Rev 1473 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1159 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
1514 | hidnplayr | 3 | ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
1159 | hidnplayr | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; ETHERNET.INC ;; |
||
7 | ;; ;; |
||
8 | ;; Ethernet network layer for KolibriOS ;; |
||
9 | ;; ;; |
||
10 | ;; Written by hidnplayr@kolibrios.org ;; |
||
11 | ;; ;; |
||
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
13 | ;; Version 2, June 1991 ;; |
||
14 | ;; ;; |
||
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
16 | |||
1206 | hidnplayr | 17 | $Revision: 1514 $ |
1159 | hidnplayr | 18 | |
19 | ETH_QUEUE_SIZE equ 16 |
||
20 | |||
21 | struct ETH_FRAME |
||
1514 | hidnplayr | 22 | .DstMAC dp ? ; destination MAC-address |
23 | .SrcMAC dp ? ; source MAC-address |
||
24 | .Type dw ? ; type of the upper-layer protocol |
||
25 | .Data: ; data (46-1500 bytes for a normal packet) |
||
1159 | hidnplayr | 26 | ends |
27 | |||
1514 | hidnplayr | 28 | virtual at NET_DEVICE.end |
29 | |||
30 | ETH_DEVICE: |
||
1159 | hidnplayr | 31 | .unload dd ? |
32 | .reset dd ? |
||
33 | .transmit dd ? |
||
34 | .set_MAC dd ? |
||
35 | .get_MAC dd ? |
||
36 | .set_mode dd ? |
||
37 | .get_mode dd ? |
||
38 | |||
39 | .bytes_tx dq ? |
||
40 | .bytes_rx dq ? |
||
41 | .packets_tx dd ? |
||
42 | .packets_rx dd ? |
||
1514 | hidnplayr | 43 | .mode dd ? |
1159 | hidnplayr | 44 | .name dd ? |
45 | .mac dp ? |
||
46 | |||
1514 | hidnplayr | 47 | end virtual |
1159 | hidnplayr | 48 | |
49 | align 4 |
||
1196 | hidnplayr | 50 | iglobal |
51 | |||
52 | ETH_BROADCAST dp 0xffffffffffff |
||
53 | endg |
||
54 | |||
55 | align 4 |
||
1159 | hidnplayr | 56 | uglobal |
57 | ETH_RUNNING dd ? |
||
58 | endg |
||
59 | |||
60 | |||
1257 | hidnplayr | 61 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 62 | ; |
63 | ; ETH_init |
||
64 | ; |
||
65 | ; This function resets all ethernet variables |
||
66 | ; |
||
67 | ; IN: / |
||
68 | ; OUT: / |
||
69 | ; |
||
1257 | hidnplayr | 70 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 71 | align 4 |
72 | ETH_init: |
||
73 | |||
1514 | hidnplayr | 74 | mov [ETH_RUNNING], 0 |
1159 | hidnplayr | 75 | |
76 | ret |
||
77 | |||
78 | |||
1257 | hidnplayr | 79 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 80 | ; |
81 | ; ETH_Receiver: |
||
82 | ; |
||
83 | ; This function is called by ethernet drivers, |
||
84 | ; It pushes the received ethernet packets onto the eth_in_queue |
||
85 | ; |
||
1514 | hidnplayr | 86 | ; IN: [esp] = Pointer to buffer |
1257 | hidnplayr | 87 | ; [esp-4] = size of buffer |
1514 | hidnplayr | 88 | ; ebx = pointer to eth_device |
1159 | hidnplayr | 89 | ; OUT: / |
90 | ; |
||
1257 | hidnplayr | 91 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 92 | align 4 |
1249 | hidnplayr | 93 | ETH_receiver: |
1473 | hidnplayr | 94 | mov eax, [esp] |
95 | mov ecx, [esp+4] |
||
1249 | hidnplayr | 96 | |
1159 | hidnplayr | 97 | DEBUGF 1,"ETH_Handler - size: %u\n", ecx |
98 | cmp ecx, 60 ; check packet length |
||
99 | jl .dump |
||
100 | sub ecx, ETH_FRAME.Data |
||
101 | |||
102 | lea edx, [eax + ETH_FRAME.Data] |
||
103 | mov ax , [eax + ETH_FRAME.Type] |
||
104 | |||
105 | cmp ax, ETHER_IPv4 |
||
1196 | hidnplayr | 106 | je IPv4_handler |
1159 | hidnplayr | 107 | |
108 | cmp ax, ETHER_ARP |
||
1196 | hidnplayr | 109 | je ARP_handler |
1159 | hidnplayr | 110 | |
1473 | hidnplayr | 111 | DEBUGF 2,"Unknown ethernet packet type %x\n", ax |
1159 | hidnplayr | 112 | |
113 | .dump: |
||
1473 | hidnplayr | 114 | DEBUGF 2,"ETH_Handler - dumping\n" |
1159 | hidnplayr | 115 | call kernel_free |
116 | add esp, 4 |
||
1249 | hidnplayr | 117 | ret |
1159 | hidnplayr | 118 | |
1249 | hidnplayr | 119 | ;----------------------------------------------------------------- |
120 | ; |
||
1257 | hidnplayr | 121 | ; ETH_create_packet |
1159 | hidnplayr | 122 | ; |
1514 | hidnplayr | 123 | ; IN: eax = pointer to source mac |
124 | ; ebx = pointer to destination mac |
||
125 | ; ecx = packet size |
||
126 | ; edx = device number |
||
127 | ; di = protocol |
||
1159 | hidnplayr | 128 | ; |
1514 | hidnplayr | 129 | ; OUT: edi = 0 on error, pointer to buffer otherwise |
130 | ; eax = buffer start |
||
131 | ; ebx = to device structure |
||
132 | ; ecx = unchanged (packet size of embedded data) |
||
133 | ; edx = size of complete buffer |
||
1159 | hidnplayr | 134 | ; |
1257 | hidnplayr | 135 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 136 | align 4 |
1249 | hidnplayr | 137 | ETH_create_packet: |
1159 | hidnplayr | 138 | |
1473 | hidnplayr | 139 | DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx |
1159 | hidnplayr | 140 | |
1514 | hidnplayr | 141 | cmp ecx, 1500 ;;; |
1159 | hidnplayr | 142 | jg .exit |
143 | |||
144 | push ecx di eax ebx edx |
||
145 | |||
146 | add ecx, ETH_FRAME.Data |
||
147 | push ecx |
||
148 | push ecx |
||
149 | call kernel_alloc |
||
1514 | hidnplayr | 150 | mov edi, eax |
151 | test edi, edi |
||
1159 | hidnplayr | 152 | jz .pop_exit |
153 | |||
154 | pop ecx |
||
155 | pop edx |
||
156 | |||
157 | pop esi |
||
158 | movsd |
||
159 | movsw |
||
160 | pop esi |
||
161 | movsd |
||
162 | movsw |
||
163 | pop ax |
||
164 | stosw |
||
165 | |||
166 | lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start |
||
1206 | hidnplayr | 167 | mov edx, ecx ; Set ebx to complete buffer size |
1159 | hidnplayr | 168 | pop ecx |
169 | |||
1206 | hidnplayr | 170 | xor ebx, ebx ;;;; TODO: Fixme |
1514 | hidnplayr | 171 | mov ebx, [NET_DRV_LIST + ebx] |
1159 | hidnplayr | 172 | |
1206 | hidnplayr | 173 | cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes |
174 | jg .continue |
||
175 | mov edx, 46 + ETH_FRAME.Data |
||
176 | .continue: |
||
177 | |||
1473 | hidnplayr | 178 | DEBUGF 1,"done: %x size:%u device:%x\n", eax, edx, ebx |
1159 | hidnplayr | 179 | ret |
180 | |||
181 | .pop_exit: |
||
1473 | hidnplayr | 182 | DEBUGF 2,"Out of ram space!!\n" |
1159 | hidnplayr | 183 | add esp, 18 |
1514 | hidnplayr | 184 | and edi, 0 |
1206 | hidnplayr | 185 | ret |
186 | |||
1159 | hidnplayr | 187 | .exit: |
1473 | hidnplayr | 188 | DEBUGF 2,"Packet too large!\n" |
1514 | hidnplayr | 189 | and edi, 0 |
1159 | hidnplayr | 190 | ret |
191 | |||
192 | |||
193 | |||
1257 | hidnplayr | 194 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 195 | ; |
196 | ; ETH_API |
||
197 | ; |
||
198 | ; This function is called by system function 75 |
||
199 | ; |
||
200 | ; IN: subfunction number in bl |
||
201 | ; device number in bh |
||
202 | ; ecx, edx, .. depends on subfunction |
||
203 | ; |
||
204 | ; OUT: |
||
205 | ; |
||
1257 | hidnplayr | 206 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 207 | align 4 |
208 | ETH_API: |
||
209 | |||
1514 | hidnplayr | 210 | cmp bh, MAX_NET_DEVICES |
211 | jg .error |
||
1159 | hidnplayr | 212 | movzx eax, bh |
213 | shl eax, 2 |
||
214 | |||
1514 | hidnplayr | 215 | cmp bl, 7 |
216 | jz .out_queue |
||
217 | cmp bl, 6 |
||
218 | jz .in_queue |
||
219 | |||
220 | mov eax, dword [NET_DRV_LIST + eax] |
||
221 | cmp [eax + NET_DEVICE.type], NET_TYPE_ETH |
||
222 | jne .error |
||
223 | |||
1159 | hidnplayr | 224 | test bl, bl |
225 | jz .packets_tx ; 0 |
||
226 | dec bl |
||
227 | jz .packets_rx ; 1 |
||
228 | dec bl |
||
229 | jz .bytes_tx ; 2 |
||
230 | dec bl |
||
231 | jz .bytes_rx ; 3 |
||
232 | dec bl |
||
233 | jz .read_mac ; 4 |
||
234 | dec bl |
||
235 | jz .write_mac ; 5 |
||
236 | |||
1514 | hidnplayr | 237 | .error: |
238 | DEBUGF 2,"Device is not ethernet type\n" |
||
239 | or eax, -1 |
||
1159 | hidnplayr | 240 | ret |
241 | |||
242 | .packets_tx: |
||
1171 | hidnplayr | 243 | mov eax, dword [eax + ETH_DEVICE.packets_tx] |
244 | |||
1159 | hidnplayr | 245 | ret |
246 | |||
247 | .packets_rx: |
||
1171 | hidnplayr | 248 | mov eax, dword [eax + ETH_DEVICE.packets_rx] |
1159 | hidnplayr | 249 | ret |
250 | |||
251 | .bytes_tx: |
||
1241 | clevermous | 252 | mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4] |
1174 | hidnplayr | 253 | mov eax, dword [eax + ETH_DEVICE.bytes_tx] |
254 | mov [esp+20+4], ebx ; TODO: fix this ugly code |
||
1159 | hidnplayr | 255 | ret |
256 | |||
257 | .bytes_rx: |
||
1174 | hidnplayr | 258 | mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4] |
259 | mov eax, dword [eax + ETH_DEVICE.bytes_rx] |
||
260 | mov [esp+20+4], ebx ; TODO: fix this ugly code |
||
1159 | hidnplayr | 261 | ret |
262 | |||
1174 | hidnplayr | 263 | |
1159 | hidnplayr | 264 | .read_mac: |
265 | movzx ebx, word [eax + ETH_DEVICE.mac] |
||
266 | mov eax, dword [eax + ETH_DEVICE.mac + 2] |
||
1171 | hidnplayr | 267 | mov [esp+20+4], ebx ; TODO: fix this ugly code |
1159 | hidnplayr | 268 | ret |
269 | |||
270 | .write_mac: |
||
271 | push ecx |
||
272 | push dx |
||
1514 | hidnplayr | 273 | mov eax, [eax + ETH_DEVICE.set_MAC] |
1159 | hidnplayr | 274 | call eax |
275 | ret |
||
276 | |||
277 | .in_queue: |
||
1514 | hidnplayr | 278 | if ETH_QUEUE |
1159 | hidnplayr | 279 | add eax, ETH_IN_QUEUE |
280 | mov eax, [eax + queue.size] |
||
1514 | hidnplayr | 281 | else |
282 | or eax, -1 |
||
283 | end if |
||
1159 | hidnplayr | 284 | ret |
285 | |||
286 | .out_queue: |
||
1514 | hidnplayr | 287 | if ETH_QUEUE |
1159 | hidnplayr | 288 | add eax, ETH_OUT_QUEUE |
289 | mov eax, [eax + queue.size] |
||
1514 | hidnplayr | 290 | else |
291 | or eax, -1 |
||
292 | end if |
||
1159 | hidnplayr | 293 | ret |