Subversion Repositories Kolibri OS

Rev

Rev 9394 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9394 Rev 9395
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2021. 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: 9394 $
17
$Revision: 9395 $
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
align 4
65
align 4
66
; This function is called by ethernet drivers.
66
; This function is called by ethernet drivers.
67
; Push the received ethernet packet onto the ethernet input queue.
67
; Push the received ethernet packet onto the ethernet input queue.
68
;
68
;
69
;  Input:
69
;  Input:
70
;    [esp + 4] = Pointer to buffer
70
;    [esp] = Pointer to buffer
71
;    [esp + 8] = Return address (yes, really)
71
;    [esp + 4] = Return address (yes, really)
72
;
72
;
73
;  Example:
73
;  Example:
74
;    push .retaddr
74
;    push .retaddr
75
;    push buf_addr
75
;    push buf_addr
76
;    jmp eth_input
76
;    jmp eth_input
77
eth_input:
77
eth_input:
78
 
78
 
79
        pop     eax
79
        pop     eax
80
 
80
 
81
if defined NETWORK_SANITY_CHECKS
81
if defined NETWORK_SANITY_CHECKS
82
        cmp     eax, [net_buffs_low]
82
        cmp     eax, [net_buffs_low]
83
        jb      .assert_mbuff
83
        jb      .assert_mbuff
84
        cmp     eax, [net_buffs_high]
84
        cmp     eax, [net_buffs_high]
85
        ja      .assert_mbuff
85
        ja      .assert_mbuff
86
        test    eax, 0x7ff
86
        test    eax, 0x7ff
87
        jnz     .assert_mbuff
87
        jnz     .assert_mbuff
88
end if
88
end if
89
 
89
 
90
        spin_lock_irqsave
90
        spin_lock_irqsave
91
 
91
 
92
        cmp     [ETH_frame_queued], ETH_QUEUE_SIZE
92
        cmp     [ETH_frame_queued], ETH_QUEUE_SIZE
93
        jae     .full
93
        jae     .full
94
        inc     [ETH_frame_queued]
94
        inc     [ETH_frame_queued]
95
 
95
 
96
; Add frame to the end of the linked list
96
; Add frame to the end of the linked list
97
        mov     [eax + NET_BUFF.NextPtr], ETH_frame_head
97
        mov     [eax + NET_BUFF.NextPtr], ETH_frame_head
98
 
98
 
99
        mov     ebx, [ETH_frame_tail]
99
        mov     ebx, [ETH_frame_tail]
100
        mov     [eax + NET_BUFF.PrevPtr], ebx
100
        mov     [eax + NET_BUFF.PrevPtr], ebx
101
 
101
 
102
        mov     [ETH_frame_tail], eax
102
        mov     [ETH_frame_tail], eax
103
        mov     [ebx + NET_BUFF.NextPtr], eax
103
        mov     [ebx + NET_BUFF.NextPtr], eax
104
 
104
 
105
        spin_unlock_irqrestore
105
        spin_unlock_irqrestore
106
 
106
 
107
; Mark it as being an Ethernet Frame
107
; Mark it as being an Ethernet Frame
108
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
108
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
109
 
109
 
110
; Now queue an event to process it
110
; Now queue an event to process it
111
        xor     edx, edx
111
        xor     edx, edx
112
        mov     eax, [ETH_input_event]
112
        mov     eax, [ETH_input_event]
113
        mov     ebx, [eax + EVENT.id]
113
        mov     ebx, [eax + EVENT.id]
114
        xor     esi, esi
114
        xor     esi, esi
115
        call    raise_event
115
        call    raise_event
116
 
116
 
117
        ret
117
        ret
118
 
118
 
119
  .full:
119
  .full:
120
        mov     ebx, [eax + NET_BUFF.device]
120
        mov     ebx, [eax + NET_BUFF.device]
121
        inc     [ebx + NET_DEVICE.packets_rx_ovr]
121
        inc     [ebx + NET_DEVICE.packets_rx_ovr]
122
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
122
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH incoming queue is full, discarding packet!\n"
123
        spin_unlock_irqrestore
123
        spin_unlock_irqrestore
124
        stdcall net_buff_free, eax
124
        stdcall net_buff_free, eax
125
        ret
125
        ret
126
 
126
 
127
if defined NETWORK_SANITY_CHECKS
127
if defined NETWORK_SANITY_CHECKS
128
  .assert_mbuff:
128
  .assert_mbuff:
129
        DEBUGF  DEBUG_NETWORK_ERROR, "eth_input: invalid buffer 0x%x\n", eax
129
        DEBUGF  DEBUG_NETWORK_ERROR, "eth_input: invalid buffer 0x%x\n", eax
130
        DEBUGF  DEBUG_NETWORK_ERROR, "eth_input: caller=0x%x\n", [esp+4]
130
        DEBUGF  DEBUG_NETWORK_ERROR, "eth_input: caller=0x%x\n", [esp+4]
131
        xor     eax, eax
131
        xor     eax, eax
132
        ret
132
        ret
133
end if
133
end if
134
 
134
 
135
 
135
 
136
 
136
 
137
;-----------------------------------------------------------------;
137
;-----------------------------------------------------------------;
138
;                                                                 ;
138
;                                                                 ;
139
; eth_process_input: Process packets from ethernet input queue.   ;
139
; eth_process_input: Process packets from ethernet input queue.   ;
140
;                                                                 ;
140
;                                                                 ;
141
;  IN:  /                                                         ;
141
;  IN:  /                                                         ;
142
;                                                                 ;
142
;                                                                 ;
143
;  OUT: /                                                         ;
143
;  OUT: /                                                         ;
144
;                                                                 ;
144
;                                                                 ;
145
;-----------------------------------------------------------------;
145
;-----------------------------------------------------------------;
146
align 4
146
align 4
147
eth_process_input:
147
eth_process_input:
148
 
148
 
149
        xor     esi, esi
149
        xor     esi, esi
150
        mov     ecx, MANUAL_DESTROY
150
        mov     ecx, MANUAL_DESTROY
151
        call    create_event
151
        call    create_event
152
        mov     [ETH_input_event], eax
152
        mov     [ETH_input_event], eax
153
        pushf
153
        pushf
154
  .wait:
154
  .wait:
155
        popf
155
        popf
156
        mov     eax, [ETH_input_event]
156
        mov     eax, [ETH_input_event]
157
        mov     ebx, [eax + EVENT.id]
157
        mov     ebx, [eax + EVENT.id]
158
        call    wait_event
158
        call    wait_event
159
 
159
 
160
  .loop:
160
  .loop:
161
        pushf
161
        pushf
162
        cli
162
        cli
163
        cmp     [ETH_frame_queued], 0
163
        cmp     [ETH_frame_queued], 0
164
        je      .wait
164
        je      .wait
165
 
165
 
166
        dec     [ETH_frame_queued]
166
        dec     [ETH_frame_queued]
167
 
167
 
168
        mov     esi, [ETH_frame_head]
168
        mov     esi, [ETH_frame_head]
169
        mov     ebx, [esi + NET_BUFF.NextPtr]
169
        mov     ebx, [esi + NET_BUFF.NextPtr]
170
 
170
 
171
        mov     [ETH_frame_head], ebx
171
        mov     [ETH_frame_head], ebx
172
        mov     [ebx + NET_BUFF.PrevPtr], ETH_frame_head
172
        mov     [ebx + NET_BUFF.PrevPtr], ETH_frame_head
173
 
173
 
174
        popf
174
        popf
175
 
175
 
176
        mov     eax, [esi + NET_BUFF.offset]
176
        mov     eax, [esi + NET_BUFF.offset]
177
        add     eax, esi
177
        add     eax, esi
178
        mov     ecx, [esi + NET_BUFF.length]
178
        mov     ecx, [esi + NET_BUFF.length]
179
        mov     ebx, [esi + NET_BUFF.device]
179
        mov     ebx, [esi + NET_BUFF.device]
180
 
180
 
181
        pushd   .loop           ; return address for protocol handler
181
        pushd   .loop           ; return address for protocol handler
182
        push    esi             ; keep pointer to NET_BUFF on stack
182
        push    esi             ; keep pointer to NET_BUFF on stack
183
 
183
 
184
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
184
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx
185
        sub     ecx, sizeof.ETH_header
185
        sub     ecx, sizeof.ETH_header
186
        jb      .err
186
        jb      .err
187
 
187
 
188
; Set registers for protocol handlers
188
; Set registers for protocol handlers
189
        lea     edx, [eax + sizeof.ETH_header]
189
        lea     edx, [eax + sizeof.ETH_header]
190
        mov     ax, [eax + ETH_header.Type]
190
        mov     ax, [eax + ETH_header.Type]
191
 
191
 
192
; Place protocol handlers here
192
; Place protocol handlers here
193
        cmp     ax, ETHER_PROTO_IPv4
193
        cmp     ax, ETHER_PROTO_IPv4
194
        je      ipv4_input
194
        je      ipv4_input
195
 
195
 
196
        cmp     ax, ETHER_PROTO_ARP
196
        cmp     ax, ETHER_PROTO_ARP
197
        je      arp_input
197
        je      arp_input
198
 
198
 
199
;        cmp     ax, ETHER_PROTO_IPv6
199
;        cmp     ax, ETHER_PROTO_IPv6
200
;        je      ipv6_input
200
;        je      ipv6_input
201
 
201
 
202
;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
202
;        cmp     ax, ETHER_PROTO_PPP_DISCOVERY
203
;        je      pppoe_discovery_input
203
;        je      pppoe_discovery_input
204
 
204
 
205
;        cmp     ax, ETHER_PROTO_PPP_SESSION
205
;        cmp     ax, ETHER_PROTO_PPP_SESSION
206
;        je      pppoe_session_input
206
;        je      pppoe_session_input
207
 
207
 
208
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
208
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax
209
 
209
 
210
  .drop:
210
  .drop:
211
        mov     eax, [esp]
211
        mov     eax, [esp]
212
        mov     eax, [eax + NET_BUFF.device]
212
        mov     eax, [eax + NET_BUFF.device]
213
        inc     [eax + NET_DEVICE.packets_rx_drop]
213
        inc     [eax + NET_DEVICE.packets_rx_drop]
214
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dropping\n"
214
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: dropping\n"
215
        call    net_buff_free
215
        call    net_buff_free
216
        ret
216
        ret
217
 
217
 
218
  .err:
218
  .err:
219
        mov     eax, [esp]
219
        mov     eax, [esp]
220
        mov     eax, [eax + NET_BUFF.device]
220
        mov     eax, [eax + NET_BUFF.device]
221
        inc     [eax + NET_DEVICE.packets_rx_err]
221
        inc     [eax + NET_DEVICE.packets_rx_err]
222
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: invalid frame received\n"
222
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_input: invalid frame received\n"
223
        call    net_buff_free
223
        call    net_buff_free
224
        ret
224
        ret
225
 
225
 
226
 
226
 
227
 
227
 
228
 
228
 
229
;-----------------------------------------------------------------;
229
;-----------------------------------------------------------------;
230
;                                                                 ;
230
;                                                                 ;
231
; eth_output                                                      ;
231
; eth_output                                                      ;
232
;                                                                 ;
232
;                                                                 ;
233
;  IN:  ax = protocol                                             ;
233
;  IN:  ax = protocol                                             ;
234
;       ebx = device ptr                                          ;
234
;       ebx = device ptr                                          ;
235
;       ecx = payload size                                        ;
235
;       ecx = payload size                                        ;
236
;       edx = pointer to destination mac                          ;
236
;       edx = pointer to destination mac                          ;
237
;                                                                 ;
237
;                                                                 ;
238
;  OUT: eax = start of net frame / 0 on error                     ;
238
;  OUT: eax = start of net frame / 0 on error                     ;
239
;       ebx = device ptr                                          ;
239
;       ebx = device ptr                                          ;
240
;       ecx = payload size                                        ;
240
;       ecx = payload size                                        ;
241
;       edi = start of payload                                    ;
241
;       edi = start of payload                                    ;
242
;                                                                 ;
242
;                                                                 ;
243
;-----------------------------------------------------------------;
243
;-----------------------------------------------------------------;
244
align 4
244
align 4
245
eth_output:
245
eth_output:
246
 
246
 
247
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
247
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx
248
 
248
 
249
        cmp     ecx, [ebx + ETH_DEVICE.mtu]
249
        cmp     ecx, [ebx + ETH_DEVICE.mtu]
250
        ja      .too_large
250
        ja      .too_large
251
 
251
 
252
        push    ecx
252
        push    ecx
253
        push    ax edx
253
        push    ax edx
254
 
254
 
255
        add     ecx, sizeof.ETH_header + NET_BUFF.data
255
        add     ecx, sizeof.ETH_header + NET_BUFF.data
256
        stdcall net_buff_alloc, ecx
256
        stdcall net_buff_alloc, ecx
257
        test    eax, eax
257
        test    eax, eax
258
        jz      .out_of_ram
258
        jz      .out_of_ram
259
 
259
 
260
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
260
        mov     [eax + NET_BUFF.type], NET_BUFF_ETH
261
        mov     [eax + NET_BUFF.device], ebx
261
        mov     [eax + NET_BUFF.device], ebx
262
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
262
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
263
        lea     edi, [eax + NET_BUFF.data]
263
        lea     edi, [eax + NET_BUFF.data]
264
 
264
 
265
        pop     esi
265
        pop     esi
266
        movsd
266
        movsd
267
        movsw
267
        movsw
268
        lea     esi, [ebx + ETH_DEVICE.mac]
268
        lea     esi, [ebx + ETH_DEVICE.mac]
269
        movsd
269
        movsd
270
        movsw
270
        movsw
271
        pop     ax
271
        pop     ax
272
        stosw
272
        stosw
273
 
273
 
274
        lea     eax, [edi - sizeof.ETH_header - NET_BUFF.data]  ; Set eax to buffer start
274
        lea     eax, [edi - sizeof.ETH_header - NET_BUFF.data]  ; Set eax to buffer start
275
        pop     ecx
275
        pop     ecx
276
 
276
 
277
        lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
277
        lea     edx, [ecx + sizeof.ETH_header]  ; Set edx to complete buffer size
278
        cmp     edx, ETH_FRAME_MINIMUM
278
        cmp     edx, ETH_FRAME_MINIMUM
279
        jbe     .adjust_size
279
        jbe     .adjust_size
280
  .done:
280
  .done:
281
        mov     [eax + NET_BUFF.length], edx
281
        mov     [eax + NET_BUFF.length], edx
282
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
282
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx
283
        ret
283
        ret
284
 
284
 
285
  .adjust_size:
285
  .adjust_size:
286
        mov     edx, ETH_FRAME_MINIMUM
286
        mov     edx, ETH_FRAME_MINIMUM
287
        test    edx, edx                        ; clear zero flag
287
        test    edx, edx                        ; clear zero flag
288
        jmp     .done
288
        jmp     .done
289
 
289
 
290
  .out_of_ram:
290
  .out_of_ram:
291
        inc     [ebx + NET_DEVICE.packets_tx_drop]
291
        inc     [ebx + NET_DEVICE.packets_tx_drop]
292
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: Out of ram!\n"
292
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: Out of ram!\n"
293
        add     esp, 4+2
293
        add     esp, 4+2
294
        pop     ecx
294
        pop     ecx
295
        xor     eax, eax
295
        xor     eax, eax
296
        ret
296
        ret
297
 
297
 
298
  .too_large:
298
  .too_large:
299
        inc     [eax + NET_DEVICE.packets_tx_err]
299
        inc     [eax + NET_DEVICE.packets_tx_err]
300
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: Packet too large!\n"
300
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ETH_output: Packet too large!\n"
301
        xor     eax, eax
301
        xor     eax, eax
302
        ret
302
        ret
303
 
303
 
304
 
304
 
305
 
305
 
306
;-----------------------------------------------------------------;
306
;-----------------------------------------------------------------;
307
;                                                                 ;
307
;                                                                 ;
308
; eth_api: Part of system function 76.                            ;
308
; eth_api: Part of system function 76.                            ;
309
;                                                                 ;
309
;                                                                 ;
310
;  IN:  bl = subfunction number                                   ;
310
;  IN:  bl = subfunction number                                   ;
311
;       bh = device number                                        ;
311
;       bh = device number                                        ;
312
;       ecx, edx, .. depends on subfunction                       ;
312
;       ecx, edx, .. depends on subfunction                       ;
313
;                                                                 ;
313
;                                                                 ;
314
; OUT:  depends on subfunction                                    ;
314
; OUT:  depends on subfunction                                    ;
315
;                                                                 ;
315
;                                                                 ;
316
;-----------------------------------------------------------------;
316
;-----------------------------------------------------------------;
317
align 4
317
align 4
318
eth_api:
318
eth_api:
319
 
319
 
320
        cmp     bh, NET_DEVICES_MAX
320
        cmp     bh, NET_DEVICES_MAX
321
        ja      .error
321
        ja      .error
322
        movzx   eax, bh
322
        movzx   eax, bh
323
        mov     eax, dword [net_device_list + 4*eax]
323
        mov     eax, dword [net_device_list + 4*eax]
324
        cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
324
        cmp     [eax + NET_DEVICE.device_type], NET_DEVICE_ETH
325
        jne     .error
325
        jne     .error
326
 
326
 
327
        and     ebx, 0xff
327
        and     ebx, 0xff
328
        cmp     ebx, .number
328
        cmp     ebx, .number
329
        ja      .error
329
        ja      .error
330
        jmp     dword [.table + 4*ebx]
330
        jmp     dword [.table + 4*ebx]
331
 
331
 
332
  .table:
332
  .table:
333
        dd      .read_mac       ; 0
333
        dd      .read_mac       ; 0
334
  .number = ($ - .table) / 4 - 1
334
  .number = ($ - .table) / 4 - 1
335
 
335
 
336
  .error:
336
  .error:
337
        or      eax, -1
337
        or      eax, -1
338
        ret
338
        ret
339
 
339
 
340
 
340
 
341
  .read_mac:
341
  .read_mac:
342
        movzx   ebx, word [eax + ETH_DEVICE.mac]
342
        movzx   ebx, word [eax + ETH_DEVICE.mac]
343
        mov     eax, dword [eax + ETH_DEVICE.mac + 2]
343
        mov     eax, dword [eax + ETH_DEVICE.mac + 2]
344
        mov     [esp+20+4], ebx                         ; FIXME
344
        mov     [esp+20+4], ebx                         ; FIXME
345
        ret
345
        ret