Rev 5001 | Rev 5363 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5001 | Rev 5015 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2014. 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: 5001 $ |
17 | $Revision: 5015 $ |
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 | struct ETH_queue_entry |
36 | struct ETH_queue_entry |
37 | 37 | ||
38 | device dd ? |
38 | device dd ? |
39 | packet dd ? |
39 | packet dd ? |
40 | size dd ? |
40 | size dd ? |
41 | 41 | ||
42 | ends |
42 | ends |
43 | 43 | ||
44 | iglobal |
44 | iglobal |
45 | align 4 |
45 | align 4 |
46 | 46 | ||
47 | ETH_BROADCAST dp 0xffffffffffff |
47 | ETH_BROADCAST dp 0xffffffffffff |
48 | endg |
48 | endg |
49 | 49 | ||
50 | uglobal |
50 | uglobal |
51 | align 4 |
51 | align 4 |
52 | ETH_input_event dd ? |
52 | ETH_input_event dd ? |
53 | ETH_queue rd (ETH_QUEUE_SIZE*sizeof.ETH_queue_entry + sizeof.queue)/4 |
53 | ETH_queue rd (ETH_QUEUE_SIZE*sizeof.ETH_queue_entry + sizeof.queue)/4 |
54 | endg |
54 | endg |
55 | 55 | ||
56 | macro ETH_init { |
56 | macro ETH_init { |
57 | 57 | ||
58 | init_queue ETH_queue |
58 | init_queue ETH_queue |
59 | 59 | ||
60 | movi ebx, 1 |
60 | movi ebx, 1 |
61 | mov ecx, ETH_process_input |
61 | mov ecx, ETH_process_input |
62 | call new_sys_threads |
62 | call new_sys_threads |
63 | test eax, eax |
63 | test eax, eax |
64 | jns @f |
64 | jns @f |
65 | DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax |
65 | DEBUGF DEBUG_NETWORK_ERROR,'K : cannot create kernel thread for ethernet, error %d\n', eax |
66 | @@: |
66 | @@: |
67 | 67 | ||
68 | } |
68 | } |
69 | 69 | ||
70 | ;----------------------------------------------------------------- |
70 | ;----------------------------------------------------------------- |
71 | ; |
71 | ; |
72 | ; ETH_input |
72 | ; ETH_input |
73 | ; |
73 | ; |
74 | ; This function is called by ethernet drivers, |
74 | ; This function is called by ethernet drivers, |
75 | ; It pushes the received ethernet packets onto the eth_in_queue |
75 | ; It pushes the received ethernet packets onto the eth_in_queue |
76 | ; |
76 | ; |
77 | ; IN: [esp] = Pointer to buffer |
77 | ; IN: [esp] = Pointer to buffer |
78 | ; [esp+4] = size of buffer |
78 | ; [esp+4] = size of buffer |
79 | ; ebx = pointer to eth_device |
79 | ; ebx = pointer to eth_device |
80 | ; OUT: / |
80 | ; OUT: / |
81 | ; |
81 | ; |
82 | ;----------------------------------------------------------------- |
82 | ;----------------------------------------------------------------- |
83 | align 4 |
83 | align 4 |
84 | ETH_input: |
84 | ETH_input: |
85 | 85 | ||
86 | push ebx |
86 | push ebx |
87 | mov esi, esp |
87 | mov esi, esp |
88 | 88 | ||
89 | add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail |
89 | add_to_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .fail |
90 | add esp, sizeof.ETH_queue_entry |
90 | add esp, sizeof.ETH_queue_entry |
91 | 91 | ||
92 | xor edx, edx |
92 | xor edx, edx |
93 | mov eax, [ETH_input_event] |
93 | mov eax, [ETH_input_event] |
94 | mov ebx, [eax + EVENT.id] |
94 | mov ebx, [eax + EVENT.id] |
95 | xor esi, esi |
95 | xor esi, esi |
96 | call raise_event |
96 | call raise_event |
97 | 97 | ||
98 | ret |
98 | ret |
99 | 99 | ||
100 | .fail: |
100 | .fail: |
101 | DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n" |
101 | DEBUGF DEBUG_NETWORK_ERROR, "ETH incoming queue is full, discarding packet!\n" |
102 | 102 | ||
103 | pop ebx |
103 | pop ebx |
104 | call NET_packet_free |
104 | call NET_packet_free |
105 | add esp, 4 |
105 | add esp, 4 |
106 | 106 | ||
107 | ret |
107 | ret |
108 | 108 | ||
109 | 109 | ||
110 | 110 | ||
111 | 111 | ||
112 | align 4 |
112 | align 4 |
113 | ETH_process_input: |
113 | ETH_process_input: |
114 | 114 | ||
115 | xor esi, esi |
115 | xor esi, esi |
116 | mov ecx, MANUAL_DESTROY |
116 | mov ecx, MANUAL_DESTROY |
117 | call create_event |
117 | call create_event |
118 | mov [ETH_input_event], eax |
118 | mov [ETH_input_event], eax |
119 | 119 | ||
120 | .wait: |
120 | .wait: |
121 | mov eax, [ETH_input_event] |
121 | mov eax, [ETH_input_event] |
122 | mov ebx, [eax + EVENT.id] |
122 | mov ebx, [eax + EVENT.id] |
123 | call wait_event |
123 | call wait_event |
124 | 124 | ||
125 | .loop: |
125 | .loop: |
126 | get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait |
126 | get_from_queue ETH_queue, ETH_QUEUE_SIZE, sizeof.ETH_queue_entry, .wait |
127 | 127 | ||
128 | mov eax, [esi + ETH_queue_entry.packet] |
128 | mov eax, [esi + ETH_queue_entry.packet] |
129 | mov ecx, [esi + ETH_queue_entry.size] |
129 | mov ecx, [esi + ETH_queue_entry.size] |
130 | mov ebx, [esi + ETH_queue_entry.device] |
130 | mov ebx, [esi + ETH_queue_entry.device] |
131 | 131 | ||
132 | pushd .loop ; return address |
132 | pushd .loop ; return address |
133 | push ecx eax |
133 | push ecx eax |
134 | 134 | ||
135 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx |
135 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: size=%u\n", ecx |
136 | sub ecx, sizeof.ETH_header |
136 | sub ecx, sizeof.ETH_header |
137 | jb .dump |
137 | jb .dump |
138 | 138 | ||
139 | lea edx, [eax + sizeof.ETH_header] |
139 | lea edx, [eax + sizeof.ETH_header] |
140 | mov ax, [eax + ETH_header.Type] |
140 | mov ax, [eax + ETH_header.Type] |
141 | 141 | ||
142 | cmp ax, ETHER_PROTO_IPv4 |
142 | cmp ax, ETHER_PROTO_IPv4 |
143 | je IPv4_input |
143 | je IPv4_input |
144 | 144 | ||
145 | cmp ax, ETHER_PROTO_ARP |
145 | cmp ax, ETHER_PROTO_ARP |
146 | je ARP_input |
146 | je ARP_input |
147 | 147 | ||
148 | ; cmp ax, ETHER_PROTO_IPv6 |
148 | ; cmp ax, ETHER_PROTO_IPv6 |
149 | ; je IPv6_input |
149 | ; je IPv6_input |
150 | 150 | ||
151 | ; cmp ax, ETHER_PROTO_PPP_DISCOVERY |
151 | ; cmp ax, ETHER_PROTO_PPP_DISCOVERY |
152 | ; je PPPoE_discovery_input |
152 | ; je PPPoE_discovery_input |
153 | 153 | ||
154 | ; cmp ax, ETHER_PROTO_PPP_SESSION |
154 | ; cmp ax, ETHER_PROTO_PPP_SESSION |
155 | ; je PPPoE_session_input |
155 | ; je PPPoE_session_input |
156 | 156 | ||
157 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax |
157 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: Unknown packet type=%x\n", ax |
158 | 158 | ||
159 | .dump: |
159 | .dump: |
160 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n" |
160 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_input: dumping\n" |
161 | call NET_packet_free |
161 | call NET_packet_free |
162 | add esp, 4 |
162 | add esp, 4 |
163 | ret |
163 | ret |
164 | 164 | ||
165 | ;----------------------------------------------------------------- |
165 | ;----------------------------------------------------------------- |
166 | ; |
166 | ; |
167 | ; ETH_output |
167 | ; ETH_output |
168 | ; |
168 | ; |
169 | ; IN: eax = pointer to source mac |
169 | ; IN: ax = protocol |
170 | ; ebx = device ptr |
170 | ; ebx = device ptr |
171 | ; ecx = packet size |
171 | ; ecx = payload size |
172 | ; edx = pointer to destination mac |
172 | ; edx = pointer to destination mac |
173 | ; di = protocol |
- | |
174 | ; |
173 | ; |
175 | ; OUT: edi = 0 on error, pointer to buffer otherwise |
174 | ; OUT: eax = start of ethernet frame / 0 on error |
176 | ; eax = buffer start |
175 | ; ebx = device ptr |
177 | ; ebx = to device structure |
176 | ; ecx = payload size |
178 | ; ecx = unchanged (packet size of embedded data) |
177 | ; edx = ethernet frame size |
179 | ; edx = size of complete buffer |
178 | ; edi = start of ethernet payload |
180 | ; |
179 | ; |
181 | ;----------------------------------------------------------------- |
180 | ;----------------------------------------------------------------- |
182 | align 4 |
181 | align 4 |
183 | ETH_output: |
182 | ETH_output: |
184 | 183 | ||
185 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx |
184 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: size=%u device=%x\n", ecx, ebx |
186 | 185 | ||
187 | cmp ecx, [ebx + NET_DEVICE.mtu] |
186 | cmp ecx, [ebx + ETH_DEVICE.mtu] |
188 | ja .exit |
187 | ja .exit |
189 | 188 | ||
190 | push ecx |
189 | push ecx |
191 | push di eax edx |
190 | push ax edx |
192 | 191 | ||
193 | add ecx, sizeof.ETH_header |
192 | add ecx, sizeof.ETH_header |
194 | stdcall kernel_alloc, ecx |
193 | stdcall kernel_alloc, ecx |
195 | test eax, eax |
194 | test eax, eax |
196 | jz .out_of_ram |
195 | jz .out_of_ram |
197 | mov edi, eax |
196 | mov edi, eax |
198 | 197 | ||
199 | pop esi |
198 | pop esi |
200 | movsd |
199 | movsd |
201 | movsw |
200 | movsw |
202 | pop esi |
201 | lea esi, [ebx + ETH_DEVICE.mac] |
203 | movsd |
202 | movsd |
204 | movsw |
203 | movsw |
205 | pop ax |
204 | pop ax |
206 | stosw |
205 | stosw |
207 | 206 | ||
208 | lea eax, [edi - sizeof.ETH_header] ; Set eax to buffer start |
207 | lea eax, [edi - sizeof.ETH_header] ; Set eax to buffer start |
209 | pop ecx |
208 | pop ecx |
210 | lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size |
209 | lea edx, [ecx + sizeof.ETH_header] ; Set edx to complete buffer size |
211 | 210 | ||
212 | cmp edx, ETH_FRAME_MINIMUM |
211 | cmp edx, ETH_FRAME_MINIMUM |
213 | jbe .adjust_size |
212 | jbe .adjust_size |
214 | .done: |
213 | .done: |
215 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx |
214 | DEBUGF DEBUG_NETWORK_VERBOSE, "ETH_output: ptr=%x size=%u\n", eax, edx |
216 | ret |
215 | ret |
217 | 216 | ||
218 | .adjust_size: |
217 | .adjust_size: |
219 | mov edx, ETH_FRAME_MINIMUM |
218 | mov edx, ETH_FRAME_MINIMUM |
220 | test edx, edx ; clear zero flag |
219 | test edx, edx ; clear zero flag |
221 | jmp .done |
220 | jmp .done |
222 | 221 | ||
223 | .out_of_ram: |
222 | .out_of_ram: |
224 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n" |
223 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Out of ram!\n" |
225 | add esp, 4+4+2+4 |
224 | add esp, 4+2+4 |
226 | sub edi, edi |
225 | xor eax, eax |
227 | ret |
226 | ret |
228 | 227 | ||
229 | .exit: |
228 | .exit: |
230 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n" |
229 | DEBUGF DEBUG_NETWORK_ERROR, "ETH_output: Packet too large!\n" |
231 | sub edi, edi |
230 | xor eax, eax |
232 | ret |
231 | ret |
233 | 232 | ||
234 | 233 | ||
235 | 234 | ||
236 | ;----------------------------------------------------------------- |
235 | ;----------------------------------------------------------------- |
237 | ; |
236 | ; |
238 | ; ETH_API |
237 | ; ETH_API |
239 | ; |
238 | ; |
240 | ; This function is called by system function 76 |
239 | ; This function is called by system function 76 |
241 | ; |
240 | ; |
242 | ; IN: subfunction number in bl |
241 | ; IN: subfunction number in bl |
243 | ; device number in bh |
242 | ; device number in bh |
244 | ; ecx, edx, .. depends on subfunction |
243 | ; ecx, edx, .. depends on subfunction |
245 | ; |
244 | ; |
246 | ; OUT: |
245 | ; OUT: |
247 | ; |
246 | ; |
248 | ;----------------------------------------------------------------- |
247 | ;----------------------------------------------------------------- |
249 | align 4 |
248 | align 4 |
250 | ETH_api: |
249 | ETH_api: |
251 | 250 | ||
252 | cmp bh, NET_DEVICES_MAX |
251 | cmp bh, NET_DEVICES_MAX |
253 | ja .error |
252 | ja .error |
254 | movzx eax, bh |
253 | movzx eax, bh |
255 | mov eax, dword [NET_DRV_LIST + 4*eax] |
254 | mov eax, dword [NET_DRV_LIST + 4*eax] |
256 | cmp [eax + NET_DEVICE.device_type], NET_DEVICE_ETH |
255 | cmp [eax + NET_DEVICE.device_type], NET_DEVICE_ETH |
257 | jne .error |
256 | jne .error |
258 | 257 | ||
259 | and ebx, 0xff |
258 | and ebx, 0xff |
260 | cmp ebx, .number |
259 | cmp ebx, .number |
261 | ja .error |
260 | ja .error |
262 | jmp dword [.table + 4*ebx] |
261 | jmp dword [.table + 4*ebx] |
263 | 262 | ||
264 | .table: |
263 | .table: |
265 | dd .read_mac ; 0 |
264 | dd .read_mac ; 0 |
266 | .number = ($ - .table) / 4 - 1 |
265 | .number = ($ - .table) / 4 - 1 |
267 | 266 | ||
268 | .error: |
267 | .error: |
269 | or eax, -1 |
268 | or eax, -1 |
270 | ret |
269 | ret |
271 | 270 | ||
272 | 271 | ||
273 | .read_mac: |
272 | .read_mac: |
274 | movzx ebx, word [eax + ETH_DEVICE.mac] |
273 | movzx ebx, word [eax + ETH_DEVICE.mac] |
275 | mov eax, dword [eax + ETH_DEVICE.mac + 2] |
274 | mov eax, dword [eax + ETH_DEVICE.mac + 2] |
276 | mov [esp+20+4], ebx ; TODO: fix this ugly code |
275 | mov [esp+20+4], ebx ; TODO: fix this ugly code |
277 | ret |
276 | ret |