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 |