Rev 5522 | Rev 7678 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5522 | Rev 6011 | ||
---|---|---|---|
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: 5522 $ |
17 | $Revision: 6011 $ |
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 | ;----------------------------------------------------------------- |
- | |
66 | ; |
65 | ;-----------------------------------------------------------------; |
67 | ; ETH_input |
- | |
68 | ; |
66 | ; ; |
69 | ; This function is called by ethernet drivers, |
67 | ; eth_input: This function is called by ethernet drivers. ; |
70 | ; It pushes the received ethernet packets onto the ethernet input queue |
- | |
- | 68 | ; Push the received ethernet packet onto the ethernet input queue.; |
|
71 | ; |
69 | ; ; |
72 | ; IN: [esp] = Pointer to buffer |
- | |
- | 70 | ; IN: [esp] = Pointer to buffer ; |
|
73 | ; |
71 | ; ; |
74 | ; OUT: / |
- | |
- | 72 | ; OUT: / ; |
|
75 | ; |
73 | ; ; |
76 | ;----------------------------------------------------------------- |
74 | ;-----------------------------------------------------------------; |
77 | align 4 |
75 | align 4 |
78 | ETH_input: |
76 | eth_input: |
79 | 77 | ||
80 | pop eax |
78 | pop eax |
81 | pushf |
79 | pushf |
82 | cli |
80 | cli |
83 | 81 | ||
84 | cmp [ETH_frame_queued], ETH_QUEUE_SIZE |
82 | cmp [ETH_frame_queued], ETH_QUEUE_SIZE |
85 | jae .full |
83 | jae .full |
86 | inc [ETH_frame_queued] |
84 | inc [ETH_frame_queued] |
87 | 85 | ||
88 | ; Add frame to the end of the linked list |
86 | ; Add frame to the end of the linked list |
89 | mov [eax + NET_BUFF.NextPtr], ETH_frame_head |
87 | mov [eax + NET_BUFF.NextPtr], ETH_frame_head |
90 | 88 | ||
91 | mov ebx, [ETH_frame_tail] |
89 | mov ebx, [ETH_frame_tail] |
92 | mov [eax + NET_BUFF.PrevPtr], ebx |
90 | mov [eax + NET_BUFF.PrevPtr], ebx |
93 | 91 | ||
94 | mov [ETH_frame_tail], eax |
92 | mov [ETH_frame_tail], eax |
95 | mov [ebx + NET_BUFF.NextPtr], eax |
93 | mov [ebx + NET_BUFF.NextPtr], eax |
96 | 94 | ||
97 | popf |
95 | popf |
98 | 96 | ||
99 | ; Now queue an event to process it |
97 | ; Now queue an event to process it |
100 | xor edx, edx |
98 | xor edx, edx |
101 | mov eax, [ETH_input_event] |
99 | mov eax, [ETH_input_event] |
102 | mov ebx, [eax + EVENT.id] |
100 | mov ebx, [eax + EVENT.id] |
103 | xor esi, esi |
101 | xor esi, esi |
104 | call raise_event |
102 | call raise_event |
105 | 103 | ||
106 | ret |
104 | ret |
107 | 105 | ||
108 | .full: |
106 | .full: |
109 | DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n" |
107 | DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n" |
110 | popf |
108 | popf |
111 | push eax |
109 | push eax |
112 | call NET_BUFF_free |
110 | call net_buff_free |
113 | ret |
111 | ret |
114 | 112 | ||
115 | 113 | ||
- | 114 | ||
- | 115 | ;-----------------------------------------------------------------; |
|
- | 116 | ; ; |
|
- | 117 | ; eth_process_input: Process packets from ethernet input queue. ; |
|
- | 118 | ; ; |
|
- | 119 | ; IN: / ; |
|
116 | - | ||
- | 120 | ; ; |
|
- | 121 | ; OUT: / ; |
|
- | 122 | ; ; |
|
117 | 123 | ;-----------------------------------------------------------------; |
|
118 | align 4 |
124 | align 4 |
119 | ETH_process_input: |
125 | eth_process_input: |
120 | 126 | ||
121 | xor esi, esi |
127 | xor esi, esi |
122 | mov ecx, MANUAL_DESTROY |
128 | mov ecx, MANUAL_DESTROY |
123 | call create_event |
129 | call create_event |
124 | mov [ETH_input_event], eax |
130 | mov [ETH_input_event], eax |
125 | pushf |
131 | pushf |
126 | .wait: |
132 | .wait: |
127 | popf |
133 | popf |
128 | mov eax, [ETH_input_event] |
134 | mov eax, [ETH_input_event] |
129 | mov ebx, [eax + EVENT.id] |
135 | mov ebx, [eax + EVENT.id] |
130 | call wait_event |
136 | call wait_event |
131 | 137 | ||
132 | .loop: |
138 | .loop: |
133 | pushf |
139 | pushf |
134 | cli |
140 | cli |
135 | cmp [ETH_frame_queued], 0 |
141 | cmp [ETH_frame_queued], 0 |
136 | je .wait |
142 | je .wait |
137 | 143 | ||
138 | dec [ETH_frame_queued] |
144 | dec [ETH_frame_queued] |
139 | 145 | ||
140 | mov esi, [ETH_frame_head] |
146 | mov esi, [ETH_frame_head] |
141 | mov ebx, [esi + NET_BUFF.NextPtr] |
147 | mov ebx, [esi + NET_BUFF.NextPtr] |
142 | 148 | ||
143 | mov [ETH_frame_head], ebx |
149 | mov [ETH_frame_head], ebx |
144 | mov [ebx + NET_BUFF.PrevPtr], ETH_frame_head |
150 | mov [ebx + NET_BUFF.PrevPtr], ETH_frame_head |
145 | 151 | ||
146 | popf |
152 | popf |
147 | 153 | ||
148 | mov eax, [esi + NET_BUFF.offset] |
154 | mov eax, [esi + NET_BUFF.offset] |
149 | add eax, esi |
155 | add eax, esi |
150 | mov ecx, [esi + NET_BUFF.length] |
156 | mov ecx, [esi + NET_BUFF.length] |
151 | mov ebx, [esi + NET_BUFF.device] |
157 | mov ebx, [esi + NET_BUFF.device] |
152 | 158 | ||
153 | pushd .loop ; return address for protocol handler |
159 | pushd .loop ; return address for protocol handler |
154 | push esi ; keep pointer to NET_BUFF on stack |
160 | push esi ; keep pointer to NET_BUFF on stack |
155 | 161 | ||
156 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx |
162 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx |
157 | sub ecx, sizeof.ETH_header |
163 | sub ecx, sizeof.ETH_header |
158 | jb .dump |
164 | jb .dump |
159 | 165 | ||
160 | ; Set registers for protocol handlers |
166 | ; Set registers for protocol handlers |
161 | lea edx, [eax + sizeof.ETH_header] |
167 | lea edx, [eax + sizeof.ETH_header] |
162 | mov ax, [eax + ETH_header.Type] |
168 | mov ax, [eax + ETH_header.Type] |
163 | 169 | ||
164 | ; Place protocol handlers here |
170 | ; Place protocol handlers here |
165 | cmp ax, ETHER_PROTO_IPv4 |
171 | cmp ax, ETHER_PROTO_IPv4 |
166 | je IPv4_input |
172 | je ipv4_input |
167 | 173 | ||
168 | cmp ax, ETHER_PROTO_ARP |
174 | cmp ax, ETHER_PROTO_ARP |
169 | je ARP_input |
175 | je arp_input |
170 | 176 | ||
171 | ; cmp ax, ETHER_PROTO_IPv6 |
177 | ; cmp ax, ETHER_PROTO_IPv6 |
172 | ; je IPv6_input |
178 | ; je ipv6_input |
173 | 179 | ||
174 | ; cmp ax, ETHER_PROTO_PPP_DISCOVERY |
180 | ; cmp ax, ETHER_PROTO_PPP_DISCOVERY |
175 | ; je PPPoE_discovery_input |
181 | ; je pppoe_discovery_input |
176 | 182 | ||
177 | ; cmp ax, ETHER_PROTO_PPP_SESSION |
183 | ; cmp ax, ETHER_PROTO_PPP_SESSION |
178 | ; je PPPoE_session_input |
184 | ; je pppoe_session_input |
179 | 185 | ||
180 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax |
186 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax |
181 | 187 | ||
182 | .dump: |
188 | .dump: |
183 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n" |
189 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n" |
184 | call NET_BUFF_free |
190 | call net_buff_free |
185 | ret |
191 | ret |
186 | - | ||
187 | ;----------------------------------------------------------------- |
192 | |
188 | ; |
- | |
189 | ; ETH_output |
193 | |
- | 194 | ||
- | 195 | ;-----------------------------------------------------------------; |
|
- | 196 | ; ; |
|
- | 197 | ; eth_output ; |
|
190 | ; |
198 | ; ; |
191 | ; IN: ax = protocol |
199 | ; IN: ax = protocol ; |
192 | ; ebx = device ptr |
200 | ; ebx = device ptr ; |
193 | ; ecx = payload size |
201 | ; ecx = payload size ; |
194 | ; edx = pointer to destination mac |
- | |
- | 202 | ; edx = pointer to destination mac ; |
|
195 | ; |
203 | ; ; |
196 | ; OUT: eax = start of net frame / 0 on error |
204 | ; OUT: eax = start of net frame / 0 on error ; |
197 | ; ebx = device ptr |
205 | ; ebx = device ptr ; |
198 | ; ecx = payload size |
206 | ; ecx = payload size ; |
199 | ; edi = start of payload |
- | |
- | 207 | ; edi = start of payload ; |
|
200 | ; |
208 | ; ; |
201 | ;----------------------------------------------------------------- |
209 | ;-----------------------------------------------------------------; |
202 | align 4 |
210 | align 4 |
203 | ETH_output: |
211 | eth_output: |
204 | 212 | ||
205 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx |
213 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx |
206 | 214 | ||
207 | cmp ecx, [ebx + ETH_DEVICE.mtu] |
215 | cmp ecx, [ebx + ETH_DEVICE.mtu] |
208 | ja .exit |
216 | ja .exit |
209 | 217 | ||
210 | push ecx |
218 | push ecx |
211 | push ax edx |
219 | push ax edx |
212 | 220 | ||
213 | add ecx, sizeof.ETH_header + NET_BUFF.data |
221 | add ecx, sizeof.ETH_header + NET_BUFF.data |
214 | stdcall NET_BUFF_alloc, ecx |
222 | stdcall net_buff_alloc, ecx |
215 | test eax, eax |
223 | test eax, eax |
216 | jz .out_of_ram |
224 | jz .out_of_ram |
217 | mov [eax + NET_BUFF.type], NET_BUFF_ETH |
225 | mov [eax + NET_BUFF.type], NET_BUFF_ETH |
218 | mov [eax + NET_BUFF.device], ebx |
226 | mov [eax + NET_BUFF.device], ebx |
219 | mov [eax + NET_BUFF.offset], NET_BUFF.data |
227 | mov [eax + NET_BUFF.offset], NET_BUFF.data |
220 | lea edi, [eax + NET_BUFF.data] |
228 | lea edi, [eax + NET_BUFF.data] |
221 | 229 | ||
222 | pop esi |
230 | pop esi |
223 | movsd |
231 | movsd |
224 | movsw |
232 | movsw |
225 | lea esi, [ebx + ETH_DEVICE.mac] |
233 | lea esi, [ebx + ETH_DEVICE.mac] |
226 | movsd |
234 | movsd |
227 | movsw |
235 | movsw |
228 | pop ax |
236 | pop ax |
229 | stosw |
237 | stosw |
230 | 238 | ||
231 | lea eax, [edi - sizeof.ETH_header - NET_BUFF.data] ; Set eax to buffer start |
239 | lea eax, [edi - sizeof.ETH_header - NET_BUFF.data] ; Set eax to buffer start |
232 | pop ecx |
240 | pop ecx |
233 | 241 | ||
234 | lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size |
242 | lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size |
235 | cmp edx, ETH_FRAME_MINIMUM |
243 | cmp edx, ETH_FRAME_MINIMUM |
236 | jbe .adjust_size |
244 | jbe .adjust_size |
237 | .done: |
245 | .done: |
238 | mov [eax + NET_BUFF.length], edx |
246 | mov [eax + NET_BUFF.length], edx |
239 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx |
247 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx |
240 | ret |
248 | ret |
241 | 249 | ||
242 | .adjust_size: |
250 | .adjust_size: |
243 | mov edx, ETH_FRAME_MINIMUM |
251 | mov edx, ETH_FRAME_MINIMUM |
244 | test edx, edx ; clear zero flag |
252 | test edx, edx ; clear zero flag |
245 | jmp .done |
253 | jmp .done |
246 | 254 | ||
247 | .out_of_ram: |
255 | .out_of_ram: |
248 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n" |
256 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n" |
249 | add esp, 4+2+4 |
257 | add esp, 4+2+4 |
250 | xor eax, eax |
258 | xor eax, eax |
251 | ret |
259 | ret |
252 | 260 | ||
253 | .exit: |
261 | .exit: |
254 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n" |
262 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n" |
255 | xor eax, eax |
263 | xor eax, eax |
256 | ret |
264 | ret |
257 | 265 | ||
258 | 266 | ||
259 | 267 | ||
260 | ;----------------------------------------------------------------- |
- | |
261 | ; |
- | |
262 | ; ETH_API |
- | |
- | 268 | ;-----------------------------------------------------------------; |
|
263 | ; |
269 | ; ; |
264 | ; This function is called by system function 76 |
- | |
- | 270 | ; eth_api: Part of system function 76. ; |
|
265 | ; |
271 | ; ; |
266 | ; IN: subfunction number in bl |
272 | ; IN: bl = subfunction number ; |
267 | ; device number in bh |
273 | ; bh = device number ; |
268 | ; ecx, edx, .. depends on subfunction |
- | |
- | 274 | ; ecx, edx, .. depends on subfunction ; |
|
269 | ; |
275 | ; ; |
270 | ; OUT: |
- | |
- | 276 | ; OUT: depends on subfunction ; |
|
271 | ; |
277 | ; ; |
272 | ;----------------------------------------------------------------- |
278 | ;-----------------------------------------------------------------; |
273 | align 4 |
279 | align 4 |
274 | ETH_api: |
280 | eth_api: |
275 | 281 | ||
276 | cmp bh, NET_DEVICES_MAX |
282 | cmp bh, NET_DEVICES_MAX |
277 | ja .error |
283 | ja .error |
278 | movzx eax, bh |
284 | movzx eax, bh |
279 | mov eax, dword [NET_DRV_LIST + 4*eax] |
285 | mov eax, dword [NET_DRV_LIST + 4*eax] |
280 | cmp [eax + NET_DEVICE.device_type], NET_DEVICE_ETH |
286 | cmp [eax + NET_DEVICE.device_type], NET_DEVICE_ETH |
281 | jne .error |
287 | jne .error |
282 | 288 | ||
283 | and ebx, 0xff |
289 | and ebx, 0xff |
284 | cmp ebx, .number |
290 | cmp ebx, .number |
285 | ja .error |
291 | ja .error |
286 | jmp dword [.table + 4*ebx] |
292 | jmp dword [.table + 4*ebx] |
287 | 293 | ||
288 | .table: |
294 | .table: |
289 | dd .read_mac ; 0 |
295 | dd .read_mac ; 0 |
290 | .number = ($ - .table) / 4 - 1 |
296 | .number = ($ - .table) / 4 - 1 |
291 | 297 | ||
292 | .error: |
298 | .error: |
293 | or eax, -1 |
299 | or eax, -1 |
294 | ret |
300 | ret |
295 | 301 | ||
296 | 302 | ||
297 | .read_mac: |
303 | .read_mac: |
298 | movzx ebx, word [eax + ETH_DEVICE.mac] |
304 | movzx ebx, word [eax + ETH_DEVICE.mac] |
299 | mov eax, dword [eax + ETH_DEVICE.mac + 2] |
305 | mov eax, dword [eax + ETH_DEVICE.mac + 2] |
300 | mov [esp+20+4], ebx ; FIXME |
306 | mov [esp+20+4], ebx ; FIXME |
301 | ret |
307 | ret |