Subversion Repositories Kolibri OS

Rev

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

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