Subversion Repositories Kolibri OS

Rev

Rev 1185 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1196 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2009. 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
 
17
$Revision: 983 $
18
 
19
MAX_ETH_DEVICES 	equ MAX_NET_DEVICES
20
ETH_QUEUE_SIZE		equ 16
21
 
22
struct	ETH_FRAME
23
	.DstMAC 	dp  ?  ; destination MAC-address [6 bytes]
24
	.SrcMAC 	dp  ?  ; source MAC-address [6 bytes]
25
	.Type		dw  ?  ; type of the upper-layer protocol [2 bytes]
26
	.Data:		       ; data [46-1500 bytes]
27
ends
28
 
29
struct	ETH_DEVICE
30
	.unload 	dd ?
31
	.reset		dd ?
32
	.transmit	dd ?
33
	.set_MAC	dd ?
34
	.get_MAC	dd ?
35
	.set_mode	dd ?
36
	.get_mode	dd ?
37
 
38
	.bytes_tx	dq ?
39
	.bytes_rx	dq ?
40
	.packets_tx	dd ?
41
	.packets_rx	dd ?
42
	.mode		dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
43
	.name		dd ?
44
	.mac		dp ?
45
ends			      ; the rest of the device struct depends on the type of device
46
 
47
 
48
align 4
1196 hidnplayr 49
iglobal
50
 
51
	ETH_BROADCAST	dp  0xffffffffffff
52
endg
53
 
54
align 4
1159 hidnplayr 55
uglobal
56
 
57
	ETH_RUNNING	dd  ?
58
	ETH_DRV_LIST	rd  MAX_ETH_DEVICES
59
	ETH_IN_QUEUE	rd  3*ETH_QUEUE_SIZE+3
60
	ETH_OUT_QUEUE	rd  3*ETH_QUEUE_SIZE+3
61
endg
62
 
63
 
64
;-----------------------------------------------
65
;
66
; ETH_init
67
;
68
;  This function resets all ethernet variables
69
;
70
;  IN:  /
71
;  OUT: /
72
;
73
;-----------------------------------------------
74
 
75
align 4
76
ETH_init:
77
 
78
	xor	eax, eax
79
	mov	edi, ETH_RUNNING
80
	mov	ecx, (1+MAX_ETH_DEVICES)
81
	rep	stosd
82
 
1174 hidnplayr 83
	mov	dword [ETH_IN_QUEUE], ETH_QUEUE_SIZE
1159 hidnplayr 84
	mov	dword [ETH_IN_QUEUE+4], ETH_IN_QUEUE + queue.data
85
	mov	dword [ETH_IN_QUEUE+8], ETH_IN_QUEUE + queue.data
86
 
1174 hidnplayr 87
	mov	dword [ETH_OUT_QUEUE], ETH_QUEUE_SIZE
1159 hidnplayr 88
	mov	dword [ETH_OUT_QUEUE+4], ETH_OUT_QUEUE + queue.data
89
	mov	dword [ETH_OUT_QUEUE+8], ETH_OUT_QUEUE + queue.data
90
 
91
	ret
92
 
93
 
94
;---------------------------------------------------------
95
;
96
; ETH_Add_Device:
97
;
98
;  This function is called by ethernet drivers,
99
;  to register each running ethernet device to the kernel
100
;
101
;  IN:  Pointer to device structure in ebx
102
;  OUT: Device num in eax, -1 on error
103
;
104
;---------------------------------------------------------
105
 
106
align 4
107
ETH_Add_Device:
108
 
1185 hidnplayr 109
	DEBUGF	1,"ETH_Add_Device: %x ", ebx
1174 hidnplayr 110
 
111
	mov	eax, [ETH_RUNNING]
112
	cmp	eax, MAX_ETH_DEVICES
1159 hidnplayr 113
	jge	.error
114
 
1174 hidnplayr 115
	test	eax, eax
116
	jnz	.notfirst
117
	mov	dword [ETH_IN_QUEUE], eax
118
	mov	dword [ETH_OUT_QUEUE], eax
119
      .notfirst:
120
 
1159 hidnplayr 121
	mov	eax, ebx
122
	mov	ecx, MAX_ETH_DEVICES	  ; We need to check whole list because a device may be removed without re-organizing list
123
	mov	edi, ETH_DRV_LIST
124
 
125
	cld
126
	repne	scasd			  ; See if device is already in the list
127
	jz	.error
128
 
129
	xor	eax, eax
130
	mov	ecx, MAX_ETH_DEVICES
131
	mov	edi, ETH_DRV_LIST
132
 
133
	repne	scasd			  ; Find empty spot in the list
134
	jnz	.error
135
 
136
	sub	edi, 4
137
	mov	[edi], ebx		  ; add device to list
138
 
139
	sub	edi, ETH_DRV_LIST	  ; edi = 4*device num       Calculate device number in eax
140
	mov	eax, edi		  ; edx = 4*device num
141
	shr	eax, 2
142
 
143
	inc	[ETH_RUNNING]		  ; Indicate that one more ethernet device is up and running
1174 hidnplayr 144
 
1159 hidnplayr 145
	DEBUGF	1,"- succes: %u\n",eax
146
	ret
147
 
148
       .error:
149
	or	eax, -1
150
	DEBUGF	1,"- fail\n"
151
 
152
	ret
153
 
154
 
155
 
156
 
157
;--------------------------------
158
;
159
; ETH_Remove_Device:
160
;
161
;  This function is called by ethernet drivers,
162
;  to unregister ethernet devices from the kernel
163
;
164
;  IN:  Pointer to device structure in ebx
165
;  OUT: eax: -1 on error
166
;
167
;--------------------------------
168
 
169
align 4
170
ETH_Remove_Device:
171
 
172
	cmp	[ETH_RUNNING], 0
173
	je	.error
174
 
175
	mov	eax, ebx
176
	mov	ecx, MAX_ETH_DEVICES
177
	mov	edi, ETH_DRV_LIST
178
 
179
	repne	scasd
180
	jnz	.error
181
 
182
	xor	eax, eax
183
	mov	dword [edi-4], eax
184
 
185
	dec	[ETH_RUNNING]
1174 hidnplayr 186
	jnz	.notlast
1159 hidnplayr 187
 
1174 hidnplayr 188
	mov	dword [ETH_IN_QUEUE], ETH_QUEUE_SIZE
189
	mov	dword [ETH_OUT_QUEUE], ETH_QUEUE_SIZE
190
 
191
       .notlast:
192
 
1159 hidnplayr 193
	ret
194
 
195
       .error:
196
	or	eax, -1
197
 
198
	ret
199
 
200
 
201
 
202
;-------------------------------------------------------------
203
;
204
; ETH_Receiver:
205
;
206
;  This function is called by ethernet drivers,
207
;  It pushes the received ethernet packets onto the eth_in_queue
208
;
209
;  IN:  Pointer to buffer in [esp], size of buffer in [esp-4], pointer to eth_device in ebx
210
;  OUT: /
211
;
212
;-------------------------------------------------------------
213
 
214
align 4
215
ETH_Receiver:
216
	DEBUGF	1,"ETH_Receiver \n"
217
 
218
	add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome
219
 
220
  .gohome:
221
	ret
222
 
223
 
224
 
225
 
226
 
227
;-------------------------------------------------------------
228
;
229
; ETH_Handler:
230
;
231
;  Handles all queued eth packets (called from kernel's main_loop)
232
;
233
;  IN:  /
234
;  OUT: /
235
;
236
;-------------------------------------------------------------
237
 
238
align 4
1196 hidnplayr 239
ETH_handler:
1159 hidnplayr 240
 
241
	get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome
242
 
243
	DEBUGF	1,"ETH_Handler - size: %u\n", ecx
244
	cmp	ecx, 60    ; check packet length
245
	jl	.dump
246
	sub	ecx, ETH_FRAME.Data
247
 
248
	lea	edx, [eax + ETH_FRAME.Data]
249
	mov	ax , [eax + ETH_FRAME.Type]
250
 
251
	cmp	ax, ETHER_IPv4
1196 hidnplayr 252
	je	IPv4_handler
1159 hidnplayr 253
 
254
	cmp	ax, ETHER_ARP
1196 hidnplayr 255
	je	ARP_handler
1159 hidnplayr 256
 
257
	DEBUGF	1,"Unknown ethernet packet type %x\n", ax
258
 
259
  .dump:
260
	DEBUGF	1,"Dumping packet\n"
261
	call	kernel_free
262
	add	esp, 4
263
 
264
  .gohome:
265
	ret				; return 1. to get more from queue / 2. to caller
266
 
267
 
268
 
269
;-----------------------------------------------------------------
270
;
271
; ETH_Sender:
272
;
273
;  This function sends an ethernet packet to the correct driver.
274
;
275
;  IN:  Pointer to buffer in [esp]
276
;       size of buffer in [esp+4]
277
;       pointer to device struct in ebx
278
;  OUT: /
279
;
280
;-----------------------------------------------------------------
281
 
282
align 4
283
ETH_Sender:
284
	DEBUGF	1,"ETH_Sender \n"
285
 
286
	add_to_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, .gohome
287
 
288
  .gohome:
289
	ret
290
 
291
 
292
align 4
293
ETH_send_queued:
294
 
295
	get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, .gohome
296
 
297
	call	ETH_struc2dev		 ; convert struct ptr to device num (this way we know if driver is still mounted)
298
	cmp	edi, -1
299
	je	.fail
300
 
301
	DEBUGF 1,"ETH_Sender - device: %u\n", edi
302
 
303
	jmp	[ebx+ETH_DEVICE.transmit]
304
 
305
     .fail:
306
	call	kernel_free
307
	add	esp, 4 ; pop (balance stack)
308
	DEBUGF 1,"ETH_Sender - fail\n"
309
     .gohome:
310
	ret
311
 
312
;---------------------------------------------------------------------------
313
;
314
; ETH_struc2dev
315
;
316
; IN: pointer to device struct in ebx
317
;
318
; OUT: edi is -1 on error, device number otherwise
319
;
320
;---------------------------------------------------------------------------
321
 
322
align 4
323
ETH_struc2dev:
324
	push	eax ecx
325
 
326
	mov	eax, ebx
327
	mov	ecx, MAX_ETH_DEVICES
328
	mov	edi, ETH_DRV_LIST
329
 
330
	repne	scasd
331
	jnz	.error
332
 
333
	sub	edi, ETH_DRV_LIST+4
334
	shr	edi, 2
335
 
336
	pop	ecx eax
337
	ret
338
  .error:
339
	or	edi, -1
340
	pop	ecx eax
341
 
342
	ret
343
 
344
 
345
;---------------------------------------------------------------------------
346
;
347
; ETH_create_Packet
348
;
349
; IN: pointer to source mac in eax
350
;     pointer to destination mac in ebx
351
;     packet size in ecx
352
;     device number in edx
353
;     protocol in di
354
;
355
; OUT: edi is -1 on error, pointer to buffer otherwise                    ;; TODO: XCHG EDX AND EBX output parameters
356
;      eax points to buffer start
357
;      ebx is size of complete buffer
358
;      ecx is unchanged (packet size of embedded data)
359
;      edx is pointer to device structure
360
;      esi points to procedure wich needs to be called to send packet
361
;
362
;---------------------------------------------------------------------------
363
 
364
align 4
365
ETH_create_Packet:
366
 
367
	DEBUGF 1,"Creating Ethernet Packet:\n"
368
 
369
	cmp	ecx, 60-ETH_FRAME.Data
370
	jl	.exit
371
	cmp	ecx, 1514-ETH_FRAME.Data
372
	jg	.exit
373
 
374
	push	ecx di eax ebx edx
375
 
376
	add	ecx, ETH_FRAME.Data
377
	push	ecx
378
	push	ecx
379
	call	kernel_alloc
380
	test	eax, eax
381
	jz	.pop_exit
382
 
383
	pop	ecx
384
	pop	edx
385
 
386
	mov	edi, eax
387
	pop	esi
388
	movsd
389
	movsw
390
	pop	esi
391
	movsd
392
	movsw
393
	pop	ax
394
	stosw
395
 
396
	lea	eax, [edi - ETH_FRAME.Data]  ; Set eax to buffer start
397
	mov	ebx, ecx		     ; Set ebx to complete buffer size
398
	pop	ecx
399
	mov	esi, ETH_Sender
400
 
1196 hidnplayr 401
	xor	edx, edx			;;;; TODO: Fixme
1159 hidnplayr 402
	mov	edx, [ETH_DRV_LIST + edx]
403
 
404
	DEBUGF 1,"done: %x size:%u device:%x\n", eax, ebx, edx
405
	ret
406
 
407
  .pop_exit:
408
	add	esp, 18
409
  .exit:
410
	or	edi, -1
411
	ret
412
 
413
 
414
 
415
 
416
;---------------------------------------------------------------------------
417
;
418
; ETH_API
419
;
420
; This function is called by system function 75
421
;
422
; IN:  subfunction number in bl
423
;      device number in bh
424
;      ecx, edx, .. depends on subfunction
425
;
426
; OUT:
427
;
428
;---------------------------------------------------------------------------
429
 
430
align 4
431
ETH_API:
432
 
433
	movzx	eax, bh
434
	shl	eax, 2
435
 
436
	test	bl, bl
437
	jz	.packets_tx	; 0
438
	dec	bl
439
	jz	.packets_rx	; 1
440
	dec	bl
441
	jz	.bytes_tx	; 2
442
	dec	bl
443
	jz	.bytes_rx	; 3
444
	dec	bl
445
	jz	.read_mac	; 4
446
	dec	bl
447
	jz	.write_mac	; 5
448
	dec	bl
449
	jz	.in_queue	; 6
450
	dec	bl
451
	jz	.out_queue	; 7
452
 
453
.error:
454
	mov	eax, -1
455
	ret
456
 
457
.packets_tx:
458
	add	eax, ETH_DRV_LIST
1171 hidnplayr 459
	mov	eax, dword [eax]
460
	mov	eax, dword [eax + ETH_DEVICE.packets_tx]
461
 
1159 hidnplayr 462
	ret
463
 
464
.packets_rx:
465
	add	eax, ETH_DRV_LIST
1171 hidnplayr 466
	mov	eax, dword [eax]
467
	mov	eax, dword [eax + ETH_DEVICE.packets_rx]
1159 hidnplayr 468
	ret
469
 
470
.bytes_tx:
471
	add	eax, ETH_DRV_LIST
1171 hidnplayr 472
	mov	eax, dword [eax]
1159 hidnplayr 473
	mov	eax, dword [eax + ETH_DEVICE.bytes_tx + 4]
1174 hidnplayr 474
	mov	eax, dword [eax + ETH_DEVICE.bytes_tx]
475
	mov	[esp+20+4], ebx 			; TODO: fix this ugly code
1159 hidnplayr 476
	ret
477
 
478
.bytes_rx:
479
	add	eax, ETH_DRV_LIST
1171 hidnplayr 480
	mov	eax, dword [eax]
1174 hidnplayr 481
	mov	ebx, dword [eax + ETH_DEVICE.bytes_rx + 4]
482
	mov	eax, dword [eax + ETH_DEVICE.bytes_rx]
483
	mov	[esp+20+4], ebx 			; TODO: fix this ugly code
1159 hidnplayr 484
	ret
485
 
1174 hidnplayr 486
 
1159 hidnplayr 487
.read_mac:
488
	add	eax, ETH_DRV_LIST
489
	mov	eax, [eax]
490
;        push    eax
491
;        call    dword [eax + ETH_DEVICE.get_MAC]
492
;        pop     eax
493
	movzx	ebx, word [eax + ETH_DEVICE.mac]
494
	mov	eax, dword [eax + ETH_DEVICE.mac + 2]
1171 hidnplayr 495
	mov	[esp+20+4], ebx 			; TODO: fix this ugly code
1159 hidnplayr 496
	ret
497
 
498
.write_mac:
499
	push	ecx
500
	push	dx
501
	add	eax, ETH_DRV_LIST
502
	mov	eax, [eax]
503
	mov	eax, dword [eax + ETH_DEVICE.set_MAC]
504
	call	eax
505
	ret
506
 
507
.in_queue:
508
	add	eax, ETH_IN_QUEUE
509
	mov	eax, [eax + queue.size]
510
	ret
511
 
512
.out_queue:
513
	add	eax, ETH_OUT_QUEUE
514
	mov	eax, [eax + queue.size]
515
	ret