Subversion Repositories Kolibri OS

Rev

Rev 6011 | Rev 7679 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6011 Rev 7536
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  ETHERNET.INC                                                   ;;
6
;;  ETHERNET.INC                                                   ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Ethernet network layer for KolibriOS                           ;;
8
;;  Ethernet network layer for KolibriOS                           ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
16
 
17
$Revision: 6011 $
17
$Revision: 7536 $
18
 
18
 
19
ETH_FRAME_MINIMUM       = 60
19
ETH_FRAME_MINIMUM       = 60
20
ETH_QUEUE_SIZE          = 255
20
ETH_QUEUE_SIZE          = 255
21
 
21
 
22
struct  ETH_header
22
struct  ETH_header
23
 
23
 
24
        DstMAC          dp  ?  ; destination MAC-address
24
        DstMAC          dp  ?  ; destination MAC-address
25
        SrcMAC          dp  ?  ; source MAC-address
25
        SrcMAC          dp  ?  ; source MAC-address
26
        Type            dw  ?  ; type of the upper-layer protocol
26
        Type            dw  ?  ; type of the upper-layer protocol
27
 
27
 
28
ends
28
ends
29
 
29
 
30
struct  ETH_DEVICE      NET_DEVICE
30
struct  ETH_DEVICE      NET_DEVICE
31
 
31
 
32
        mac             dp ?
32
        mac             dp ?
33
 
33
 
34
ends
34
ends
35
 
35
 
36
iglobal
36
iglobal
37
align 4
37
align 4
38
 
38
 
39
        ETH_BROADCAST   dp 0xffffffffffff
39
        ETH_BROADCAST   dp 0xffffffffffff
40
 
40
 
41
        ETH_frame_queued        dd 0    ; Number of queued frames
41
        ETH_frame_queued        dd 0    ; Number of queued frames
42
 
42
 
43
        ETH_frame_head          dd ETH_frame_head       ; Pointer to next frame in the linked list
43
        ETH_frame_head          dd ETH_frame_head       ; Pointer to next frame in the linked list
44
        ETH_frame_tail          dd ETH_frame_head       ; Pointer to last frame in the linked list
44
        ETH_frame_tail          dd ETH_frame_head       ; Pointer to last frame in the linked list
45
 
45
 
46
endg
46
endg
47
 
47
 
48
uglobal
48
uglobal
49
align 4
49
align 4
50
        ETH_input_event dd ?
50
        ETH_input_event dd ?
51
endg
51
endg
52
 
52
 
53
macro   eth_init {
53
macro   eth_init {
54
 
54
 
55
        movi    ebx, 1
55
        movi    ebx, 1
56
        mov     ecx, eth_process_input
56
        mov     ecx, eth_process_input
57
        call    new_sys_threads
57
        call    new_sys_threads
58
        test    eax, eax
58
        test    eax, eax
59
        jns     @f
59
        jns     @f
60
        DEBUGF  DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax
60
        DEBUGF  DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax
61
  @@:
61
  @@:
62
 
62
 
63
}
63
}
64
 
64
 
65
;-----------------------------------------------------------------;
65
;-----------------------------------------------------------------;
66
;                                                                 ;
66
;                                                                 ;
67
; eth_input: This function is called by ethernet drivers.         ;
67
; eth_input: This function is called by ethernet drivers.         ;
68
; Push the received ethernet packet onto the ethernet input queue.;
68
; Push the received ethernet packet onto the ethernet input queue.;
69
;                                                                 ;
69
;                                                                 ;
70
;  IN:  [esp] = Pointer to buffer                                 ;
70
;  IN:  [esp] = Pointer to buffer                                 ;
71
;                                                                 ;
71
;                                                                 ;
72
;  OUT: /                                                         ;
72
;  OUT: /                                                         ;
73
;                                                                 ;
73
;                                                                 ;
74
;-----------------------------------------------------------------;
74
;-----------------------------------------------------------------;
75
align 4
75
align 4
76
eth_input:
76
eth_input:
77
 
77
 
78
        pop     eax
78
        pop     eax
79
        pushf
79
        pushf
80
        cli
80
        cli
81
 
81
 
82
        cmp     [ETH_frame_queued], ETH_QUEUE_SIZE
82
        cmp     [ETH_frame_queued], ETH_QUEUE_SIZE
83
        jae     .full
83
        jae     .full
84
        inc     [ETH_frame_queued]
84
        inc     [ETH_frame_queued]
85
 
85
 
86
; Add frame to the end of the linked list
86
; Add frame to the end of the linked list
87
        mov     [eax + NET_BUFF.NextPtr], ETH_frame_head
87
        mov     [eax + NET_BUFF.NextPtr], ETH_frame_head
88
 
88
 
89
        mov     ebx, [ETH_frame_tail]
89
        mov     ebx, [ETH_frame_tail]
90
        mov     [eax + NET_BUFF.PrevPtr], ebx
90
        mov     [eax + NET_BUFF.PrevPtr], ebx
91
 
91
 
92
        mov     [ETH_frame_tail], eax
92
        mov     [ETH_frame_tail], eax
93
        mov     [ebx + NET_BUFF.NextPtr], eax
93
        mov     [ebx + NET_BUFF.NextPtr], eax
94
 
94
 
95
        popf
95
        popf
-
 
96
 
-
 
97
; Mark it as being an Ethernet Frame
-
 
98
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
96
 
99
 
97
; Now queue an event to process it
100
; Now queue an event to process it
98
        xor     edx, edx
101
        xor     edx, edx
99
        mov     eax, [ETH_input_event]
102
        mov     eax, [ETH_input_event]
100
        mov     ebx, [eax + EVENT.id]
103
        mov     ebx, [eax + EVENT.id]
101
        xor     esi, esi
104
        xor     esi, esi
102
        call    raise_event
105
        call    raise_event
103
 
106
 
104
        ret
107
        ret
105
 
108
 
106
  .full:
109
  .full:
107
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
110
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n"
108
        popf
111
        popf
109
        push    eax
112
        push    eax
110
        call    net_buff_free
113
        call    net_buff_free
111
        ret
114
        ret
112
 
115
 
113
 
116
 
114
 
117
 
115
;-----------------------------------------------------------------;
118
;-----------------------------------------------------------------;
116
;                                                                 ;
119
;                                                                 ;
117
; eth_process_input: Process packets from ethernet input queue.   ;
120
; eth_process_input: Process packets from ethernet input queue.   ;
118
;                                                                 ;
121
;                                                                 ;
119
;  IN:  /                                                         ;
122
;  IN:  /                                                         ;
120
;                                                                 ;
123
;                                                                 ;
121
;  OUT: /                                                         ;
124
;  OUT: /                                                         ;
122
;                                                                 ;
125
;                                                                 ;
123
;-----------------------------------------------------------------;
126
;-----------------------------------------------------------------;
124
align 4
127
align 4
125
eth_process_input:
128
eth_process_input:
126
 
129
 
127
        xor     esi, esi
130
        xor     esi, esi
128
        mov     ecx, MANUAL_DESTROY
131
        mov     ecx, MANUAL_DESTROY
129
        call    create_event
132
        call    create_event
130
        mov     [ETH_input_event], eax
133
        mov     [ETH_input_event], eax
131
        pushf
134
        pushf
132
  .wait:
135
  .wait:
133
        popf
136
        popf
134
        mov     eax, [ETH_input_event]
137
        mov     eax, [ETH_input_event]
135
        mov     ebx, [eax + EVENT.id]
138
        mov     ebx, [eax + EVENT.id]
136
        call    wait_event
139
        call    wait_event
137
 
140
 
138
  .loop:
141
  .loop:
139
        pushf
142
        pushf
140
        cli
143
        cli
141
        cmp     [ETH_frame_queued], 0
144
        cmp     [ETH_frame_queued], 0
142
        je      .wait
145
        je      .wait
143
 
146
 
144
        dec     [ETH_frame_queued]
147
        dec     [ETH_frame_queued]
145
 
148
 
146
        mov     esi, [ETH_frame_head]
149
        mov     esi, [ETH_frame_head]
147
        mov     ebx, [esi + NET_BUFF.NextPtr]
150
        mov     ebx, [esi + NET_BUFF.NextPtr]
148
 
151
 
149
        mov     [ETH_frame_head], ebx
152
        mov     [ETH_frame_head], ebx
150
        mov     [ebx + NET_BUFF.PrevPtr], ETH_frame_head
153
        mov     [ebx + NET_BUFF.PrevPtr], ETH_frame_head
151
 
154
 
152
        popf
155
        popf
153
 
156
 
154
        mov     eax, [esi + NET_BUFF.offset]
157
        mov     eax, [esi + NET_BUFF.offset]
155
        add     eax, esi
158
        add     eax, esi
156
        mov     ecx, [esi + NET_BUFF.length]
159
        mov     ecx, [esi + NET_BUFF.length]
157
        mov     ebx, [esi + NET_BUFF.device]
160
        mov     ebx, [esi + NET_BUFF.device]
158
 
161
 
159
        pushd   .loop           ; return address for protocol handler
162
        pushd   .loop           ; return address for protocol handler
160
        push    esi             ; keep pointer to NET_BUFF on stack
163
        push    esi             ; keep pointer to NET_BUFF on stack
161
 
164
 
162
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
165
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
163
        sub     ecx, sizeof.ETH_header
166
        sub     ecx, sizeof.ETH_header
164
        jb      .dump
167
        jb      .dump
165
 
168
 
166
; Set registers for protocol handlers
169
; Set registers for protocol handlers
167
        lea     edx, [eax + sizeof.ETH_header]
170
        lea     edx, [eax + sizeof.ETH_header]
168
        mov     ax, [eax + ETH_header.Type]
171
        mov     ax, [eax + ETH_header.Type]
169
 
172
 
170
; Place protocol handlers here
173
; Place protocol handlers here
171
        cmp     ax, ETHER_PROTO_IPv4
174
        cmp     ax, ETHER_PROTO_IPv4
172
        je      ipv4_input
175
        je      ipv4_input
173
 
176
 
174
        cmp     ax, ETHER_PROTO_ARP
177
        cmp     ax, ETHER_PROTO_ARP
175
        je      arp_input
178
        je      arp_input
176
 
179
 
177
;        cmp     ax, ETHER_PROTO_IPv6
180
;        cmp     ax, ETHER_PROTO_IPv6
178
;        je      ipv6_input
181
;        je      ipv6_input
179
 
182
 
180
;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
183
;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
181
;        je      pppoe_discovery_input
184
;        je      pppoe_discovery_input
182
 
185
 
183
;        cmp     ax, ETHER_PROTO_PPP_SESSION
186
;        cmp     ax, ETHER_PROTO_PPP_SESSION
184
;        je      pppoe_session_input
187
;        je      pppoe_session_input
185
 
188
 
186
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
189
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
187
 
190
 
188
  .dump:
191
  .dump:
189
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
192
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n"
190
        call    net_buff_free
193
        call    net_buff_free
191
        ret
194
        ret
192
 
195
 
193
 
196
 
194
 
197
 
195
;-----------------------------------------------------------------;
198
;-----------------------------------------------------------------;
196
;                                                                 ;
199
;                                                                 ;
197
; eth_output                                                      ;
200
; eth_output                                                      ;
198
;                                                                 ;
201
;                                                                 ;
199
;  IN:  ax = protocol                                             ;
202
;  IN:  ax = protocol                                             ;
200
;       ebx = device ptr                                          ;
203
;       ebx = device ptr                                          ;
201
;       ecx = payload size                                        ;
204
;       ecx = payload size                                        ;
202
;       edx = pointer to destination mac                          ;
205
;       edx = pointer to destination mac                          ;
203
;                                                                 ;
206
;                                                                 ;
204
;  OUT: eax = start of net frame / 0 on error                     ;
207
;  OUT: eax = start of net frame / 0 on error                     ;
205
;       ebx = device ptr                                          ;
208
;       ebx = device ptr                                          ;
206
;       ecx = payload size                                        ;
209
;       ecx = payload size                                        ;
207
;       edi = start of payload                                    ;
210
;       edi = start of payload                                    ;
208
;                                                                 ;
211
;                                                                 ;
209
;-----------------------------------------------------------------;
212
;-----------------------------------------------------------------;
210
align 4
213
align 4
211
eth_output:
214
eth_output:
212
 
215
 
213
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
216
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
214
 
217
 
215
        cmp     ecx, [ebx + ETH_DEVICE.mtu]
218
        cmp     ecx, [ebx + ETH_DEVICE.mtu]
216
        ja      .exit
219
        ja      .exit
217
 
220
 
218
        push    ecx
221
        push    ecx
219
        push    ax edx
222
        push    ax edx
220
 
223
 
221
        add     ecx, sizeof.ETH_header + NET_BUFF.data
224
        add     ecx, sizeof.ETH_header + NET_BUFF.data
222
        stdcall net_buff_alloc, ecx
225
        stdcall net_buff_alloc, ecx
223
        test    eax, eax
226
        test    eax, eax
224
        jz      .out_of_ram
227
        jz      .out_of_ram
225
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
228
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
226
        mov     [eax + NET_BUFF.device], ebx
229
        mov     [eax + NET_BUFF.device], ebx
227
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
230
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
228
        lea     edi, [eax + NET_BUFF.data]
231
        lea     edi, [eax + NET_BUFF.data]
229
 
232
 
230
        pop     esi
233
        pop     esi
231
        movsd
234
        movsd
232
        movsw
235
        movsw
233
        lea     esi, [ebx + ETH_DEVICE.mac]
236
        lea     esi, [ebx + ETH_DEVICE.mac]
234
        movsd
237
        movsd
235
        movsw
238
        movsw
236
        pop     ax
239
        pop     ax
237
        stosw
240
        stosw
238
 
241
 
239
        lea     eax, [edi - sizeof.ETH_header - NET_BUFF.data]  ; Set eax to buffer start
242
        lea     eax, [edi - sizeof.ETH_header - NET_BUFF.data]  ; Set eax to buffer start
240
        pop     ecx
243
        pop     ecx
241
 
244
 
242
        lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
245
        lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
243
        cmp     edx, ETH_FRAME_MINIMUM
246
        cmp     edx, ETH_FRAME_MINIMUM
244
        jbe     .adjust_size
247
        jbe     .adjust_size
245
  .done:
248
  .done:
246
        mov     [eax + NET_BUFF.length], edx
249
        mov     [eax + NET_BUFF.length], edx
247
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
250
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
248
        ret
251
        ret
249
 
252
 
250
  .adjust_size:
253
  .adjust_size:
251
        mov     edx, ETH_FRAME_MINIMUM
254
        mov     edx, ETH_FRAME_MINIMUM
252
        test    edx, edx                        ; clear zero flag
255
        test    edx, edx                        ; clear zero flag
253
        jmp     .done
256
        jmp     .done
254
 
257
 
255
  .out_of_ram:
258
  .out_of_ram:
256
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
259
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n"
257
        add     esp, 4+2+4
260
        add     esp, 4+2+4
258
        xor     eax, eax
261
        xor     eax, eax
259
        ret
262
        ret
260
 
263
 
261
  .exit:
264
  .exit:
262
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
265
        DEBUGF  DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n"
263
        xor     eax, eax
266
        xor     eax, eax
264
        ret
267
        ret
265
 
268
 
266
 
269
 
267
 
270
 
268
;-----------------------------------------------------------------;
271
;-----------------------------------------------------------------;
269
;                                                                 ;
272
;                                                                 ;
270
; eth_api: Part of system function 76.                            ;
273
; eth_api: Part of system function 76.                            ;
271
;                                                                 ;
274
;                                                                 ;
272
;  IN:  bl = subfunction number                                   ;
275
;  IN:  bl = subfunction number                                   ;
273
;       bh = device number                                        ;
276
;       bh = device number                                        ;
274
;       ecx, edx, .. depends on subfunction                       ;
277
;       ecx, edx, .. depends on subfunction                       ;
275
;                                                                 ;
278
;                                                                 ;
276
; OUT:  depends on subfunction                                    ;
279
; OUT:  depends on subfunction                                    ;
277
;                                                                 ;
280
;                                                                 ;
278
;-----------------------------------------------------------------;
281
;-----------------------------------------------------------------;
279
align 4
282
align 4
280
eth_api:
283
eth_api:
281
 
284
 
282
        cmp     bh, NET_DEVICES_MAX
285
        cmp     bh, NET_DEVICES_MAX
283
        ja      .error
286
        ja      .error
284
        movzx   eax, bh
287
        movzx   eax, bh
285
        mov     eax, dword [NET_DRV_LIST + 4*eax]
288
        mov     eax, dword [NET_DRV_LIST + 4*eax]
286
        cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
289
        cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
287
        jne     .error
290
        jne     .error
288
 
291
 
289
        and     ebx, 0xff
292
        and     ebx, 0xff
290
        cmp     ebx, .number
293
        cmp     ebx, .number
291
        ja      .error
294
        ja      .error
292
        jmp     dword [.table + 4*ebx]
295
        jmp     dword [.table + 4*ebx]
293
 
296
 
294
  .table:
297
  .table:
295
        dd      .read_mac       ; 0
298
        dd      .read_mac       ; 0
296
  .number = ($ - .table) / 4 - 1
299
  .number = ($ - .table) / 4 - 1
297
 
300
 
298
  .error:
301
  .error:
299
        or      eax, -1
302
        or      eax, -1
300
        ret
303
        ret
301
 
304
 
302
 
305
 
303
  .read_mac:
306
  .read_mac:
304
        movzx   ebx, word [eax + ETH_DEVICE.mac]
307
        movzx   ebx, word [eax + ETH_DEVICE.mac]
305
        mov     eax, dword [eax + ETH_DEVICE.mac + 2]
308
        mov     eax, dword [eax + ETH_DEVICE.mac + 2]
306
        mov     [esp+20+4], ebx                         ; FIXME
309
        mov     [esp+20+4], ebx                         ; FIXME
307
        ret
310
        ret