Subversion Repositories Kolibri OS

Rev

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