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 |