Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                  ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved.     ;;
4
;; Distributed under terms of the GNU General Public License        ;;
5
;;                                                                  ;;
6
;;  PCNET32.INC                                                     ;;
7
;;                                                                  ;;
8
;;  Ethernet driver for Menuet OS                                   ;;
9
;;                                                                  ;;
781 hidnplayr 10
;;  - Version 1.0  31 July 2004:                                    ;;
11
;;      Initial release                                             ;;
431 serge 12
;;                                                                  ;;
781 hidnplayr 13
;;  - Version 1.01 29 March 2008:                                   ;;
14
;;     Adapted to work with kolibrios flat kernel                   ;;
15
;;     Debug info is updated, and now uses DEBUGF macro             ;;
16
;;     by hidnplayr@kolibrios.org                                   ;;
17
;;                                                                  ;;
431 serge 18
;;  This driver is based on the PCNet32 driver from                 ;;
19
;;  the etherboot 5.0.6 project. The copyright statement is         ;;
20
;;                                                                  ;;
21
;;          GNU GENERAL PUBLIC LICENSE                              ;;
22
;;             Version 2, June 1991                                 ;;
23
;;                                                                  ;;
24
;;  remaining parts Copyright 2004 Jarek Pelczar,                   ;;
25
;;   jpelczar@interia.pl                                            ;;
26
;;                                                                  ;;
27
;;  See file COPYING for details                                    ;;
28
;;                                                                  ;;
29
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
593 mikedld 30
 
31
$Revision: 781 $
32
 
33
 
261 hidnplayr 34
PCNET32_PORT_AUI      equ 0x00
35
PCNET32_PORT_10BT     equ 0x01
36
PCNET32_PORT_GPSI     equ 0x02
37
PCNET32_PORT_MII      equ 0x03
38
PCNET32_PORT_PORTSEL  equ 0x03
39
PCNET32_PORT_ASEL     equ 0x04
40
PCNET32_PORT_100      equ 0x40
41
PCNET32_PORT_FD       equ 0x80
42
PCNET32_DMA_MASK      equ 0xffffffff
781 hidnplayr 43
 
44
PCNET32_LOG_TX_BUFFERS	equ 1
45
PCNET32_LOG_RX_BUFFERS	equ 2
46
 
47
PCNET32_TX_RING_SIZE		equ (1 shl PCNET32_LOG_TX_BUFFERS)
48
PCNET32_TX_RING_MOD_MASK	equ (PCNET32_TX_RING_SIZE-1)
49
PCNET32_TX_RING_LEN_BITS	equ 0
50
PCNET32_RX_RING_SIZE		equ (1 shl PCNET32_LOG_RX_BUFFERS)
51
PCNET32_RX_RING_MOD_MASK	equ (PCNET32_RX_RING_SIZE-1)
52
PCNET32_RX_RING_LEN_BITS	equ (PCNET32_LOG_RX_BUFFERS shl 4)
53
PCNET32_PKT_BUF_SZ		equ 1544
54
PCNET32_PKT_BUF_SZ_NEG		equ 0xf9f8
55
 
261 hidnplayr 56
pcnet32_txb equ (eth_data_start)
57
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
58
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
59
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
781 hidnplayr 60
 
261 hidnplayr 61
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
62
pcnet32_private:
781 hidnplayr 63
.mode			dw ?
64
.tlen_rlen		dw ?
65
.phys_addr		db ?,?,?,?,?,?
66
.reserved		dw ?
67
.filter 		dd ?,?
68
.rx_ring		dd ?
69
.tx_ring		dd ?
70
.cur_rx 		dd ?
71
.cur_tx 		dd ?
72
.dirty_rx		dd ?
73
.dirty_tx		dd ?
74
.tx_full		db ?
75
.options		dd ?
76
.full_duplex		db ?
77
.chip_version		dd ?
78
.mii			db ?
79
.ltint			db ?
80
.dxsuflo		db ?
81
.fset			db ?
82
.fdx			db ?
261 hidnplayr 83
end virtual
781 hidnplayr 84
 
261 hidnplayr 85
virtual at 0
86
pcnet32_rx_head:
781 hidnplayr 87
.base		dd ?
88
.buf_length	dw ?
89
.status 	dw ?
90
.msg_length	dd ?
91
.reserved	dd ?
261 hidnplayr 92
end virtual
781 hidnplayr 93
 
261 hidnplayr 94
virtual at 0
95
pcnet32_tx_head:
781 hidnplayr 96
.base		dd ?
97
.length 	dw ?
98
.status 	dw ?
99
.misc		dd ?
100
.reserved	dd ?
261 hidnplayr 101
end virtual
102
 
103
uglobal
104
pcnet32_access:
781 hidnplayr 105
.read_csr		dd ?
106
.write_csr		dd ?
107
.read_bcr		dd ?
108
.write_bcr		dd ?
109
.read_rap		dd ?
110
.write_rap		dd ?
111
.reset			dd ?
261 hidnplayr 112
endg
113
 
114
iglobal
115
pcnet32_options_mapping:
781 hidnplayr 116
dd PCNET32_PORT_ASEL	;  0 Auto-select
117
dd PCNET32_PORT_AUI	;  1 BNC/AUI
118
dd PCNET32_PORT_AUI	;  2 AUI/BNC
119
dd PCNET32_PORT_ASEL	;  3 not supported
261 hidnplayr 120
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ;  4 10baseT-FD
781 hidnplayr 121
dd PCNET32_PORT_ASEL	;  5 not supported
122
dd PCNET32_PORT_ASEL	;  6 not supported
123
dd PCNET32_PORT_ASEL	;  7 not supported
124
dd PCNET32_PORT_ASEL	;  8 not supported
125
dd PCNET32_PORT_MII	;  9 MII 10baseT
126
dd PCNET32_PORT_MII or PCNET32_PORT_FD	; 10 MII 10baseT-FD
127
dd PCNET32_PORT_MII	; 11 MII (autosel)
128
dd PCNET32_PORT_10BT	; 12 10BaseT
261 hidnplayr 129
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
781 hidnplayr 130
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD	; 14 MII 100BaseTx-FD
131
dd PCNET32_PORT_ASEL	; 15 not supported
261 hidnplayr 132
endg
133
 
781 hidnplayr 134
PCNET32_WIO_RDP 	equ 0x10
135
PCNET32_WIO_RAP 	equ 0x12
136
PCNET32_WIO_RESET	equ 0x14
137
PCNET32_WIO_BDP 	equ 0x16
138
PCNET32_DWIO_RDP	equ 0x10
139
PCNET32_DWIO_RAP	equ 0x14
140
PCNET32_DWIO_RESET	equ 0x18
141
PCNET32_DWIO_BDP	equ 0x1C
142
PCNET32_TOTAL_SIZE	equ 0x20
261 hidnplayr 143
; ebx - index
144
; return:
145
; eax - data
146
pcnet32_wio_read_csr:
147
    push edx
148
    lea edx,[ebp+PCNET32_WIO_RAP]
149
    mov ax,bx
150
    out dx,ax
151
    lea edx,[ebp+PCNET32_WIO_RDP]
152
    in ax,dx
153
    and eax,0xffff
154
    pop edx
155
    ret
156
; eax - data
157
; ebx - index
158
pcnet32_wio_write_csr:
159
    push edx
160
    lea edx,[ebp+PCNET32_WIO_RAP]
161
    xchg eax,ebx
162
    out dx,ax
163
    xchg eax,ebx
164
    lea edx,[ebp+PCNET32_WIO_RDP]
165
    out dx,ax
166
    pop edx
167
    ret
168
; ebx - index
169
; return:
170
; eax - data
171
pcnet32_wio_read_bcr:
172
    push edx
173
    lea edx,[ebp+PCNET32_WIO_RAP]
174
    mov ax,bx
175
    out dx,ax
176
    lea edx,[ebp+PCNET32_WIO_BDP]
177
    in ax,dx
178
    and eax,0xffff
179
    pop edx
180
    ret
181
; eax - data
182
; ebx - index
183
pcnet32_wio_write_bcr:
184
    push edx
185
    lea edx,[ebp+PCNET32_WIO_RAP]
186
    xchg eax,ebx
187
    out dx,ax
188
    xchg eax,ebx
189
    lea edx,[ebp+PCNET32_WIO_BDP]
190
    out dx,ax
191
    pop edx
192
    ret
193
pcnet32_wio_read_rap:
194
    push edx
195
    lea edx,[ebp+PCNET32_WIO_RAP]
196
    in ax,dx
197
    and eax,0xffff
198
    pop edx
199
    ret
200
; eax - val
201
pcnet32_wio_write_rap:
202
    push edx
203
    lea edx,[ebp+PCNET32_WIO_RAP]
204
    out dx,ax
205
    pop edx
206
    ret
207
pcnet32_wio_reset:
208
    push edx
209
    push eax
210
    lea edx,[ebp+PCNET32_WIO_RESET]
211
    in ax,dx
212
    pop eax
213
    pop edx
214
    ret
215
pcnet32_wio_check:
216
    push edx
217
    mov ax,88
218
    lea edx,[ebp+PCNET32_WIO_RAP]
219
    out dx,ax
220
    nop
221
    nop
222
    in ax,dx
223
    cmp ax,88
224
    sete al
225
    pop edx
226
    ret
227
 
228
iglobal
229
pcnet32_wio:
230
    dd pcnet32_wio_read_csr
231
    dd pcnet32_wio_write_csr
232
    dd pcnet32_wio_read_bcr
233
    dd pcnet32_wio_write_bcr
234
    dd pcnet32_wio_read_rap
235
    dd pcnet32_wio_write_rap
236
    dd pcnet32_wio_reset
237
endg
238
 
239
; ebx - index
240
; return:
241
; eax - data
242
pcnet32_dwio_read_csr:
243
    push edx
244
    lea edx,[ebp+PCNET32_DWIO_RAP]
245
    mov ebx,eax
246
    out dx,eax
247
    lea edx,[ebp+PCNET32_DWIO_RDP]
248
    in eax,dx
249
    and eax,0xffff
250
    pop edx
251
    ret
252
; ebx - index
253
; eax - data
254
pcnet32_dwio_write_csr:
255
    push edx
256
    lea edx,[ebp+PCNET32_DWIO_RAP]
257
    xchg eax,ebx
258
    out dx,eax
259
    lea edx,[ebp+PCNET32_DWIO_RDP]
260
    xchg eax,ebx
261
    out dx,eax
262
    pop edx
263
    ret
264
; ebx - index
265
; return:
266
; eax - data
267
pcnet32_dwio_read_bcr:
268
    push edx
269
    lea edx,[ebp+PCNET32_DWIO_RAP]
270
    mov ebx,eax
271
    out dx,eax
272
    lea edx,[ebp+PCNET32_DWIO_BDP]
273
    in eax,dx
274
    and eax,0xffff
275
    pop edx
276
    ret
277
; ebx - index
278
; eax - data
279
pcnet32_dwio_write_bcr:
280
    push edx
281
    lea edx,[ebp+PCNET32_DWIO_RAP]
282
    xchg eax,ebx
283
    out dx,eax
284
    lea edx,[ebp+PCNET32_DWIO_BDP]
285
    xchg eax,ebx
286
    out dx,eax
287
    pop edx
288
    ret
289
pcnet32_dwio_read_rap:
290
    push edx
291
    lea edx,[ebp+PCNET32_DWIO_RAP]
292
    in eax,dx
293
    and eax,0xffff
294
    pop edx
295
    ret
296
; eax - val
297
pcnet32_dwio_write_rap:
298
    push edx
299
    lea edx,[ebp+PCNET32_DWIO_RAP]
300
    out dx,eax
301
    pop edx
302
    ret
303
pcnet32_dwio_reset:
304
    push edx
305
    push eax
306
    lea edx,[ebp+PCNET32_DWIO_RESET]
307
    in eax,dx
308
    pop eax
309
    pop edx
310
    ret
311
pcnet32_dwio_check:
312
    push edx
313
    lea edx,[PCNET32_DWIO_RAP]
314
    mov eax,88
315
    out dx,eax
316
    nop
317
    nop
318
    in eax,dx
319
    and eax,0xffff
320
    cmp eax,88
321
    sete al
322
    pop edx
323
    ret
324
 
325
iglobal
326
pcnet32_dwio:
327
    dd pcnet32_dwio_read_csr
328
    dd pcnet32_dwio_write_csr
329
    dd pcnet32_dwio_read_bcr
330
    dd pcnet32_dwio_write_bcr
331
    dd pcnet32_dwio_read_rap
332
    dd pcnet32_dwio_write_rap
333
    dd pcnet32_dwio_reset
334
endg
335
 
781 hidnplayr 336
 
337
 
261 hidnplayr 338
pcnet32_init_ring:
339
    mov [pcnet32_private.tx_full],0
340
    mov [pcnet32_private.cur_rx],0
341
    mov [pcnet32_private.cur_tx],0
342
    mov [pcnet32_private.dirty_rx],0
343
    mov [pcnet32_private.dirty_tx],0
344
    mov edi,pcnet32_rx_ring
345
    mov ecx,PCNET32_RX_RING_SIZE
346
    mov ebx,pcnet32_rxb
781 hidnplayr 347
    sub ebx,OS_BASE
261 hidnplayr 348
.rx_init:
349
    mov [edi+pcnet32_rx_head.base],ebx
350
    mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
351
    mov [edi+pcnet32_rx_head.status],word 0x8000
352
    add ebx,PCNET32_PKT_BUF_SZ
353
;    inc ebx
354
    add edi,16
355
    loop .rx_init
356
    mov edi,pcnet32_tx_ring
357
    mov ecx,PCNET32_TX_RING_SIZE
358
.tx_init:
359
    mov [edi+pcnet32_tx_head.base],dword 0
360
    mov [edi+pcnet32_tx_head.status],word 0
361
    add edi,16
362
    loop .tx_init
363
    mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
364
    mov esi,node_addr
365
    mov edi,pcnet32_private.phys_addr
366
    cld
367
    movsd
368
    movsw
781 hidnplayr 369
    mov eax,pcnet32_rx_ring
370
    sub eax,OS_BASE
371
    mov dword [pcnet32_private.rx_ring],eax
372
 
373
    mov eax,pcnet32_tx_ring
374
    sub eax,OS_BASE
375
    mov dword [pcnet32_private.tx_ring],eax
261 hidnplayr 376
    ret
781 hidnplayr 377
 
378
 
379
 
261 hidnplayr 380
pcnet32_reset:
381
    ; Reset PCNET32
382
    mov ebp,[io_addr]
383
    call dword [pcnet32_access.reset]
384
    ; set 32bit mode
385
    mov ebx,20
386
    mov eax,2
387
    call dword [pcnet32_access.write_bcr]
388
    ; set/reset autoselect bit
389
    mov ebx,2
390
    call dword [pcnet32_access.read_bcr]
391
    and eax,not 2
392
    test [pcnet32_private.options],PCNET32_PORT_ASEL
393
    jz .L1
394
    or eax,2
395
.L1:
396
    call dword [pcnet32_access.write_bcr]
397
    ; Handle full duplex setting
398
    cmp byte [pcnet32_private.full_duplex],0
399
    je .L2
400
    mov ebx,9
401
    call dword [pcnet32_access.read_bcr]
402
    and eax,not 3
403
    test [pcnet32_private.options],PCNET32_PORT_FD
404
    jz .L3
405
    or eax,1
406
    cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI
407
    jne .L4
408
    or eax,2
409
    jmp .L4
410
.L3:
411
    test [pcnet32_private.options],PCNET32_PORT_ASEL
412
    jz .L4
413
    cmp [pcnet32_private.chip_version],0x2627
414
    jne .L4
415
    or eax,3
416
.L4:
417
    mov ebx,9
418
    call dword [pcnet32_access.write_bcr]
419
.L2:
420
    ; set/reset GPSI bit
421
    mov ebx,124
422
    call dword [pcnet32_access.read_csr]
423
    mov ecx,[pcnet32_private.options]
424
    and ecx,PCNET32_PORT_PORTSEL
425
    cmp ecx,PCNET32_PORT_GPSI
426
    jne .L5
427
    or eax,0x10
428
.L5:
429
    call dword [pcnet32_access.write_csr]
430
    cmp [pcnet32_private.mii],0
431
    je .L6
432
    test [pcnet32_private.options],PCNET32_PORT_ASEL
433
    jnz .L6
434
    mov ebx,32
435
    call dword [pcnet32_access.read_bcr]
436
    and eax,not 0x38
437
    test [pcnet32_private.options],PCNET32_PORT_FD
438
    jz .L7
439
    or eax,0x10
440
.L7:
441
    test [pcnet32_private.options],PCNET32_PORT_100
442
    jz .L8
443
    or eax,0x08
444
.L8:
445
    call dword [pcnet32_access.write_bcr]
446
    jmp .L9
447
.L6:
448
    test [pcnet32_private.options],PCNET32_PORT_ASEL
449
    jz .L9
450
    mov ebx,32
781 hidnplayr 451
;    DEBUGF 1," K : ASEL, enable auto-negotiation\n"
261 hidnplayr 452
    call dword [pcnet32_access.read_bcr]
453
    and eax,not 0x98
454
    or eax,0x20
455
    call dword [pcnet32_access.write_bcr]
456
.L9:
457
    cmp [pcnet32_private.ltint],0
458
    je .L10
459
    mov ebx,5
460
    call dword [pcnet32_access.read_csr]
461
    or eax,(1 shl 14)
462
    call dword [pcnet32_access.write_csr]
463
.L10:
464
    mov eax,[pcnet32_private.options]
465
    and eax,PCNET32_PORT_PORTSEL
466
    shl eax,7
467
    mov [pcnet32_private.mode],ax
468
    mov [pcnet32_private.filter],dword 0xffffffff
469
    mov [pcnet32_private.filter+4],dword 0xffffffff
470
    call pcnet32_init_ring
471
    mov ebx,1
472
    mov eax,pcnet32_private
781 hidnplayr 473
    sub eax,OS_BASE
261 hidnplayr 474
    and eax,0xffff
475
    call dword [pcnet32_access.write_csr]
476
    mov eax,pcnet32_private
781 hidnplayr 477
    sub eax,OS_BASE
261 hidnplayr 478
    mov ebx,2
479
    shr eax,16
480
    call dword [pcnet32_access.write_csr]
481
    mov ebx,4
482
    mov eax,0x0915
483
    call dword [pcnet32_access.write_csr]
484
    mov ebx,0
485
    mov eax,1
486
    call dword [pcnet32_access.write_csr]
487
    mov ecx,100
488
.L11:
489
    xor ebx,ebx
490
    call dword [pcnet32_access.read_csr]
491
    test ax,0x100
492
    jnz .L12
493
    loop .L11
494
.L12:
781 hidnplayr 495
;    DEBUGF 1," K : hardware reset\n"
261 hidnplayr 496
    xor ebx,ebx
497
    mov eax,0x0002
498
    call dword [pcnet32_access.write_csr]
499
    xor ebx,ebx
500
    call dword [pcnet32_access.read_csr]
781 hidnplayr 501
;    DEBUGF 1," K : PCNET reset complete\n"
261 hidnplayr 502
    ret
781 hidnplayr 503
 
504
 
505
 
261 hidnplayr 506
pcnet32_adjust_pci_device:
507
   ;*******Get current setting************************
781 hidnplayr 508
   mov	   al, 2					;read a word
509
   mov	   bh, [pci_dev]
510
   mov	   ah, [pci_bus]
511
   mov	   bl, 0x04				    ;from command Register
261 hidnplayr 512
   call    pci_read_reg
513
   ;******see if its already set as bus master********
781 hidnplayr 514
   mov	    bx, ax
515
   and	    bx,5
516
   cmp	    bx,5
517
   je	    pcnet32_adjust_pci_device_Latency
261 hidnplayr 518
   ;******Make card a bus master*******
781 hidnplayr 519
   mov	    cx, ax				;value to write
520
   mov	   bh, [pci_dev]
521
   mov	   al, 2				;write a word
522
   or	    cx,5
523
   mov	   ah, [pci_bus]
524
   mov	   bl, 0x04				;to command register
261 hidnplayr 525
   call    pci_write_reg
526
   ;******Check latency setting***********
527
pcnet32_adjust_pci_device_Latency:
528
   ;*******Get current latency setting************************
529
;   mov     al, 1                                       ;read a byte
530
;   mov     bh, [pci_dev]
531
;   mov     ah, [pci_bus]
532
;   mov     bl, 0x0D                                ;from Lantency Timer Register
533
;   call    pci_read_reg
534
   ;******see if its aat least 64 clocks********
535
;   cmp      ax,64
536
;   jge      pcnet32_adjust_pci_device_Done
537
   ;******Set latency to 32 clocks*******
538
;   mov     cx, 64                              ;value to write
539
;   mov     bh, [pci_dev]
540
;   mov     al, 1                               ;write a byte
541
;   mov     ah, [pci_bus]
542
;   mov     bl, 0x0D                            ;to Lantency Timer Register
543
;   call    pci_write_reg
544
   ;******Check latency setting***********
545
pcnet32_adjust_pci_device_Done:
546
   ret
781 hidnplayr 547
 
548
 
549
 
550
 
261 hidnplayr 551
pcnet32_probe:
552
    mov ebp,[io_addr]
553
    call pcnet32_wio_reset
554
    xor ebx,ebx
555
    call pcnet32_wio_read_csr
556
    cmp eax,4
557
    jne .try_dwio
558
    call pcnet32_wio_check
559
    and al,al
560
    jz .try_dwio
781 hidnplayr 561
;    DEBUGF 1," K : Using WIO\n"
261 hidnplayr 562
    mov esi,pcnet32_wio
563
    jmp .L1
564
.try_dwio:
565
    call pcnet32_dwio_reset
566
    xor ebx,ebx
567
    call pcnet32_dwio_read_csr
568
    cmp eax,4
569
    jne .no_dev
570
    call pcnet32_dwio_check
571
    and al,al
572
    jz .no_dev
781 hidnplayr 573
;    DEBUGF 1," K : Using DWIO\n"
261 hidnplayr 574
    mov esi,pcnet32_dwio
575
    jmp .L1
576
.no_dev:
781 hidnplayr 577
    DEBUGF 1," K : PCNET32 not found\n"
261 hidnplayr 578
    ret
579
.L1:
580
    mov edi,pcnet32_access
581
    mov ecx,7
582
    cld
583
    rep movsd
584
    mov ebx,88
585
    call dword [pcnet32_access.read_csr]
586
    mov ecx,eax
587
    mov ebx,89
588
    call dword [pcnet32_access.read_csr]
589
    shl eax,16
590
    or eax,ecx
591
    mov ecx,eax
592
    and ecx,0xfff
593
    cmp ecx,3
594
    jne .no_dev
595
    shr eax,12
596
    and eax,0xffff
597
    mov [pcnet32_private.chip_version],eax
781 hidnplayr 598
;    DEBUGF 1," K : PCNET32 chip version OK\n"
261 hidnplayr 599
    mov [pcnet32_private.fdx],0
600
    mov [pcnet32_private.mii],0
601
    mov [pcnet32_private.fset],0
602
    mov [pcnet32_private.dxsuflo],0
603
    mov [pcnet32_private.ltint],0
604
    mov eax,[pcnet32_private.chip_version]
605
    cmp eax,0x2420
606
    je .L2
607
    cmp eax,0x2430
608
    je .L3
609
    cmp eax,0x2621
610
    je .L4
611
    cmp eax,0x2623
612
    je .L5
613
    cmp eax,0x2624
614
    je .L6
615
    cmp eax,0x2625
616
    je .L7
617
    cmp eax,0x2626
618
    je .L8
619
    cmp eax,0x2627
620
    je .L9
781 hidnplayr 621
    DEBUGF 1," K : Invalid chip rev\n"
261 hidnplayr 622
    jmp .no_dev
623
.L2:
781 hidnplayr 624
;    DEBUGF 1," K : PCnet/PCI 79C970\n"
261 hidnplayr 625
    jmp .L10
626
.L3:
781 hidnplayr 627
;    DEBUGF 1," K : PCnet/PCI 79C970\n"
261 hidnplayr 628
    jmp .L10
629
.L4:
781 hidnplayr 630
;    DEBUGF 1," K : PCnet/PCI II 79C970A\n"
261 hidnplayr 631
    mov [pcnet32_private.fdx],1
632
    jmp .L10
633
.L5:
781 hidnplayr 634
;    DEBUGF 1," K : PCnet/FAST 79C971\n"
261 hidnplayr 635
    mov [pcnet32_private.fdx],1
636
    mov [pcnet32_private.mii],1
637
    mov [pcnet32_private.fset],1
638
    mov [pcnet32_private.ltint],1
639
    jmp .L10
640
.L6:
781 hidnplayr 641
;    DEBUGF 1," K : PCnet/FAST+ 79C972\n"
261 hidnplayr 642
    mov [pcnet32_private.fdx],1
643
    mov [pcnet32_private.mii],1
644
    mov [pcnet32_private.fset],1
645
    jmp .L10
646
.L7:
781 hidnplayr 647
;    DEBUGF 1," K : PCnet/FAST III 79C973\n"
261 hidnplayr 648
    mov [pcnet32_private.fdx],1
649
    mov [pcnet32_private.mii],1
650
    jmp .L10
651
.L8:
781 hidnplayr 652
;    DEBUGF 1," K : PCnet/Home 79C978\n"
261 hidnplayr 653
    mov [pcnet32_private.fdx],1
654
    mov ebx,49
655
    call dword [pcnet32_access.read_bcr]
656
    call dword [pcnet32_access.write_bcr]
657
    jmp .L10
658
.L9:
781 hidnplayr 659
;    DEBUGF 1," K : PCnet/FAST III 79C975\n"
261 hidnplayr 660
    mov [pcnet32_private.fdx],1
661
    mov [pcnet32_private.mii],1
662
.L10:
663
    cmp [pcnet32_private.fset],1
664
    jne .L11
665
    mov ebx,18
666
    call dword [pcnet32_access.read_bcr]
667
    or eax,0x800
668
    call dword [pcnet32_access.write_bcr]
669
    mov ebx,80
670
    call dword [pcnet32_access.read_csr]
671
    and eax,0xc00
672
    or eax,0xc00
673
    call dword [pcnet32_access.write_csr]
674
    mov [pcnet32_private.dxsuflo],1
675
    mov [pcnet32_private.ltint],1
676
.L11:
677
    ; read MAC
678
    mov edi,node_addr
679
    mov edx,ebp
680
    mov ecx,6
681
.Lmac:
682
    in al,dx
683
    stosb
684
    inc edx
685
    loop .Lmac
781 hidnplayr 686
;    DEBUGF 1," K : MAC read\n"
261 hidnplayr 687
    call pcnet32_adjust_pci_device
781 hidnplayr 688
;    DEBUGF 1," K : PCI done\n"
261 hidnplayr 689
    mov eax,PCNET32_PORT_ASEL
690
    mov [pcnet32_private.options],eax
691
    mov [pcnet32_private.mode],word 0x0003
692
    mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
693
    mov esi,node_addr
694
    mov edi,pcnet32_private.phys_addr
695
    cld
696
    movsd
697
    movsw
698
    mov [pcnet32_private.filter],dword 0
699
    mov [pcnet32_private.filter+4],dword 0
781 hidnplayr 700
    mov eax,pcnet32_rx_ring
701
    sub eax,OS_BASE
702
    mov dword [pcnet32_private.rx_ring],eax
703
 
704
    mov eax,pcnet32_tx_ring
705
    sub eax,OS_BASE
706
    mov dword [pcnet32_private.tx_ring],eax
707
;    DEBUGF 1," K : Switching to 32\n"
261 hidnplayr 708
    mov ebx,20
709
    mov eax,2
710
    call dword [pcnet32_access.write_bcr]
711
    mov ebx,1
712
    mov eax,(pcnet32_private and 0xffff)
713
    call dword [pcnet32_access.write_csr]
714
    mov ebx,2
715
    mov eax,(pcnet32_private shr 16) and 0xffff
716
    call dword [pcnet32_access.write_csr]
717
    mov ebx,0
718
    mov eax,1
719
    call dword [pcnet32_access.write_csr]
720
    mov esi,1
721
    call delay_ms
722
    call pcnet32_reset
723
    mov eax, [pci_data]
724
    mov [eth_status], eax
725
    ret
781 hidnplayr 726
 
727
 
728
 
261 hidnplayr 729
pcnet32_poll:
781 hidnplayr 730
    xor ax,ax
261 hidnplayr 731
    mov [eth_rx_data_len],ax
732
    mov eax,[pcnet32_private.cur_rx]
733
    and eax,PCNET32_RX_RING_MOD_MASK
734
    mov ebx,eax
735
    imul esi,eax,PCNET32_PKT_BUF_SZ
736
    add esi,pcnet32_rxb
737
    shl ebx,4
738
    add ebx,pcnet32_rx_ring
739
    mov cx,[ebx+pcnet32_rx_head.status]
740
    test cx,0x8000
741
    jnz .L1
742
    cmp ch,3
743
    jne .L1
744
    mov ecx,[ebx+pcnet32_rx_head.msg_length]
745
    and ecx,0xfff
746
    sub ecx,4
747
    mov [eth_rx_data_len],cx
781 hidnplayr 748
;    DEBUGF 1," K : PCNETRX: %ub\n",cx
261 hidnplayr 749
    push ecx
750
    shr ecx,2
751
    mov edi,Ether_buffer
752
    cld
753
    rep movsd
754
    pop ecx
755
    and ecx,3
756
    rep movsb
757
    mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
758
    or [ebx+pcnet32_rx_head.status],word 0x8000
759
    inc [pcnet32_private.cur_rx]
760
.L1:
761
    ret
781 hidnplayr 762
 
763
 
764
 
765
 
261 hidnplayr 766
;         Pointer to 48 bit destination address in edi
767
;         Type of packet in bx
768
;         size of packet in ecx
769
;         pointer to packet data in esi
770
pcnet32_xmit:
771
    push edi
772
    push esi
773
    push ebx
774
    push ecx
781 hidnplayr 775
;    DEBUGF 1," K : PCNETTX\n"
261 hidnplayr 776
    mov esi,edi
777
    mov edi,[pcnet32_private.cur_tx]
778
    imul edi,PCNET32_PKT_BUF_SZ
779
    add edi,pcnet32_txb ; edi=ptxb
780
    mov eax,edi
781 hidnplayr 781
    cld 	; copy MAC
261 hidnplayr 782
    movsd
783
    movsw
784
    mov esi,node_addr
785
    cld
786
    movsd
787
    movsw
788
    mov [edi],bx
789
    add edi,2
790
    mov esi,[esp+8]
791
    mov ecx,[esp]
792
    push ecx
793
    shr ecx,2
794
    cld
795
    rep movsd
796
    pop ecx
797
    and ecx,3
798
    rep movsb
799
;    mov ecx,[esp]
800
;    add ecx,14 ; ETH_HLEN
801
;    xor eax,eax
802
; pad to min length (60=ETH_ZLEN)
803
;    cmp ecx,60
804
;    jae .L1
805
;    sub ecx,60
806
;    cld
807
;    rep stosb
808
;.L1:
781 hidnplayr 809
    mov edi,pcnet32_tx_ring+0	; entry=0
261 hidnplayr 810
    mov ecx,[esp]
811
    add ecx,14
812
    cmp cx,60
813
    jae .L1
814
    mov cx,60
815
.L1:
816
    neg cx
817
    mov [edi+pcnet32_tx_head.length],cx
818
    mov [edi+pcnet32_tx_head.misc],dword 0
781 hidnplayr 819
    sub eax,OS_BASE
261 hidnplayr 820
    mov [edi+pcnet32_tx_head.base],eax
821
    mov [edi+pcnet32_tx_head.status],word 0x8300
822
    ; trigger an immediate send poll
823
    mov ebx,0
781 hidnplayr 824
    mov eax,0x0008	; 0x0048
261 hidnplayr 825
    mov ebp,[io_addr]
826
    call dword [pcnet32_access.write_csr]
827
    mov dword [pcnet32_private.cur_tx],0
828
    ; wait for TX to complete
829
    mov ecx,[timer_ticks];[0xfdf0]
830
    add ecx,100
831
.L2:
832
    mov ax,[edi+pcnet32_tx_head.status]
833
    test ax,0x8000
834
    jz .L3
835
    cmp ecx,[timer_ticks];[0xfdf0]
836
    jb .L4
837
    mov esi,10
838
    call delay_ms
839
    jnz .L2
840
.L4:
781 hidnplayr 841
    DEBUGF 1," K : PCNET: Send timeout\n"
261 hidnplayr 842
.L3:
843
    mov dword [edi+pcnet32_tx_head.base],0
844
    pop ecx
845
    pop ebx
846
    pop esi
847
    pop edi
848
    ret