Subversion Repositories Kolibri OS

Rev

Rev 1249 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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