Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
425 victor 1
$Revision: 425 $
261 hidnplayr 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;                                                                    ;;
4
;;  PCNET32.INC                                                       ;;
5
;;                                                                    ;;
6
;;  Ethernet driver for Menuet OS                                     ;;
7
;;                                                                    ;;
8
;;  Version 1.0  31 July 2004                                         ;;
9
;;                                                                    ;;
10
;;  This driver is based on the PCNet32 driver from                   ;;
11
;;  the etherboot 5.0.6 project. The copyright statement is           ;;
12
;;                                                                    ;;
13
;;          GNU GENERAL PUBLIC LICENSE                                ;;
14
;;             Version 2, June 1991                                   ;;
15
;;                                                                    ;;
16
;;  remaining parts Copyright 2004 Jarek Pelczar,                     ;;
17
;;   jpelczar@interia.pl                                              ;;
18
;;                                                                    ;;
19
;;  See file COPYING for details                                      ;;
20
;;                                                                    ;;
21
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22
;macro PutStr X
23
;{
24
; local .__xyz1
25
; local .__xyz2
26
; push esi
27
; mov esi,.__xyz1
28
; call sys_msg_board_str
29
; push eax
30
; mov eax,1
31
; call delay_hs
32
; pop eax
33
; jmp .__xyz2
34
;.__xyz1:
35
; db X
36
; db 13,10,0
37
;.__xyz2:
38
; pop esi
39
;}
40
PCNET32_PORT_AUI      equ 0x00
41
PCNET32_PORT_10BT     equ 0x01
42
PCNET32_PORT_GPSI     equ 0x02
43
PCNET32_PORT_MII      equ 0x03
44
PCNET32_PORT_PORTSEL  equ 0x03
45
PCNET32_PORT_ASEL     equ 0x04
46
PCNET32_PORT_100      equ 0x40
47
PCNET32_PORT_FD       equ 0x80
48
PCNET32_DMA_MASK      equ 0xffffffff
49
PCNET32_LOG_TX_BUFFERS  equ 1
50
PCNET32_LOG_RX_BUFFERS  equ 2
51
PCNET32_TX_RING_SIZE            equ (1 shl PCNET32_LOG_TX_BUFFERS)
52
PCNET32_TX_RING_MOD_MASK        equ (PCNET32_TX_RING_SIZE-1)
53
PCNET32_TX_RING_LEN_BITS        equ 0
54
PCNET32_RX_RING_SIZE            equ (1 shl PCNET32_LOG_RX_BUFFERS)
55
PCNET32_RX_RING_MOD_MASK        equ (PCNET32_RX_RING_SIZE-1)
56
PCNET32_RX_RING_LEN_BITS        equ (PCNET32_LOG_RX_BUFFERS shl 4)
57
PCNET32_PKT_BUF_SZ              equ 1544
58
PCNET32_PKT_BUF_SZ_NEG          equ 0xf9f8
59
pcnet32_txb equ (eth_data_start)
60
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
61
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
62
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
63
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
64
pcnet32_private:
65
.mode                   dw ?
66
.tlen_rlen              dw ?
67
.phys_addr              db ?,?,?,?,?,?
68
.reserved               dw ?
69
.filter                 dd ?,?
70
.rx_ring                dd ?
71
.tx_ring                dd ?
72
.cur_rx                 dd ?
73
.cur_tx                 dd ?
74
.dirty_rx               dd ?
75
.dirty_tx               dd ?
76
.tx_full                db ?
77
.options                dd ?
78
.full_duplex            db ?
79
.chip_version           dd ?
80
.mii                    db ?
81
.ltint                  db ?
82
.dxsuflo                db ?
83
.fset                   db ?
84
.fdx                    db ?
85
end virtual
86
virtual at 0
87
pcnet32_rx_head:
88
.base           dd ?
89
.buf_length     dw ?
90
.status         dw ?
91
.msg_length     dd ?
92
.reserved       dd ?
93
end virtual
94
virtual at 0
95
pcnet32_tx_head:
96
.base           dd ?
97
.length         dw ?
98
.status         dw ?
99
.misc           dd ?
100
.reserved       dd ?
101
end virtual
102
 
103
uglobal
104
pcnet32_access:
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 ?
112
endg
113
 
114
iglobal
115
pcnet32_options_mapping:
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
120
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ;  4 10baseT-FD
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
129
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
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
132
endg
133
 
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
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
 
336
pcnet32_init_ring:
337
    mov [pcnet32_private.tx_full],0
338
    mov [pcnet32_private.cur_rx],0
339
    mov [pcnet32_private.cur_tx],0
340
    mov [pcnet32_private.dirty_rx],0
341
    mov [pcnet32_private.dirty_tx],0
342
    mov edi,pcnet32_rx_ring
343
    mov ecx,PCNET32_RX_RING_SIZE
344
    mov ebx,pcnet32_rxb
345
.rx_init:
346
    mov [edi+pcnet32_rx_head.base],ebx
347
    mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
348
    mov [edi+pcnet32_rx_head.status],word 0x8000
349
    add ebx,PCNET32_PKT_BUF_SZ
350
;    inc ebx
351
    add edi,16
352
    loop .rx_init
353
    mov edi,pcnet32_tx_ring
354
    mov ecx,PCNET32_TX_RING_SIZE
355
.tx_init:
356
    mov [edi+pcnet32_tx_head.base],dword 0
357
    mov [edi+pcnet32_tx_head.status],word 0
358
    add edi,16
359
    loop .tx_init
360
    mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
361
    mov esi,node_addr
362
    mov edi,pcnet32_private.phys_addr
363
    cld
364
    movsd
365
    movsw
366
    mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
367
    mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
368
    ret
369
pcnet32_reset:
370
    ; Reset PCNET32
371
    mov ebp,[io_addr]
372
    call dword [pcnet32_access.reset]
373
    ; set 32bit mode
374
    mov ebx,20
375
    mov eax,2
376
    call dword [pcnet32_access.write_bcr]
377
    ; set/reset autoselect bit
378
    mov ebx,2
379
    call dword [pcnet32_access.read_bcr]
380
    and eax,not 2
381
    test [pcnet32_private.options],PCNET32_PORT_ASEL
382
    jz .L1
383
    or eax,2
384
.L1:
385
    call dword [pcnet32_access.write_bcr]
386
    ; Handle full duplex setting
387
    cmp byte [pcnet32_private.full_duplex],0
388
    je .L2
389
    mov ebx,9
390
    call dword [pcnet32_access.read_bcr]
391
    and eax,not 3
392
    test [pcnet32_private.options],PCNET32_PORT_FD
393
    jz .L3
394
    or eax,1
395
    cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI
396
    jne .L4
397
    or eax,2
398
    jmp .L4
399
.L3:
400
    test [pcnet32_private.options],PCNET32_PORT_ASEL
401
    jz .L4
402
    cmp [pcnet32_private.chip_version],0x2627
403
    jne .L4
404
    or eax,3
405
.L4:
406
    mov ebx,9
407
    call dword [pcnet32_access.write_bcr]
408
.L2:
409
    ; set/reset GPSI bit
410
    mov ebx,124
411
    call dword [pcnet32_access.read_csr]
412
    mov ecx,[pcnet32_private.options]
413
    and ecx,PCNET32_PORT_PORTSEL
414
    cmp ecx,PCNET32_PORT_GPSI
415
    jne .L5
416
    or eax,0x10
417
.L5:
418
    call dword [pcnet32_access.write_csr]
419
    cmp [pcnet32_private.mii],0
420
    je .L6
421
    test [pcnet32_private.options],PCNET32_PORT_ASEL
422
    jnz .L6
423
    mov ebx,32
424
    call dword [pcnet32_access.read_bcr]
425
    and eax,not 0x38
426
    test [pcnet32_private.options],PCNET32_PORT_FD
427
    jz .L7
428
    or eax,0x10
429
.L7:
430
    test [pcnet32_private.options],PCNET32_PORT_100
431
    jz .L8
432
    or eax,0x08
433
.L8:
434
    call dword [pcnet32_access.write_bcr]
435
    jmp .L9
436
.L6:
437
    test [pcnet32_private.options],PCNET32_PORT_ASEL
438
    jz .L9
439
    mov ebx,32
440
;    PutStr "ASEL, enable auto-negotiation"
441
    call dword [pcnet32_access.read_bcr]
442
    and eax,not 0x98
443
    or eax,0x20
444
    call dword [pcnet32_access.write_bcr]
445
.L9:
446
    cmp [pcnet32_private.ltint],0
447
    je .L10
448
    mov ebx,5
449
    call dword [pcnet32_access.read_csr]
450
    or eax,(1 shl 14)
451
    call dword [pcnet32_access.write_csr]
452
.L10:
453
    mov eax,[pcnet32_private.options]
454
    and eax,PCNET32_PORT_PORTSEL
455
    shl eax,7
456
    mov [pcnet32_private.mode],ax
457
    mov [pcnet32_private.filter],dword 0xffffffff
458
    mov [pcnet32_private.filter+4],dword 0xffffffff
459
    call pcnet32_init_ring
460
    mov ebx,1
461
    mov eax,pcnet32_private
462
    and eax,0xffff
463
    call dword [pcnet32_access.write_csr]
464
    mov eax,pcnet32_private
465
    mov ebx,2
466
    shr eax,16
467
    call dword [pcnet32_access.write_csr]
468
    mov ebx,4
469
    mov eax,0x0915
470
    call dword [pcnet32_access.write_csr]
471
    mov ebx,0
472
    mov eax,1
473
    call dword [pcnet32_access.write_csr]
474
    mov ecx,100
475
.L11:
476
    xor ebx,ebx
477
    call dword [pcnet32_access.read_csr]
478
    test ax,0x100
479
    jnz .L12
480
    loop .L11
481
.L12:
482
;    PutStr "hardware reset"
483
    xor ebx,ebx
484
    mov eax,0x0002
485
    call dword [pcnet32_access.write_csr]
486
    xor ebx,ebx
487
    call dword [pcnet32_access.read_csr]
488
;    PutStr "PCNET reset complete"
489
    ret
490
pcnet32_adjust_pci_device:
491
   ;*******Get current setting************************
492
   mov     al, 2                                        ;read a word
493
   mov     bh, [pci_dev]
494
   mov     ah, [pci_bus]
495
   mov     bl, 0x04                                 ;from command Register
496
   call    pci_read_reg
497
   ;******see if its already set as bus master********
498
   mov      bx, ax
499
   and      bx,5
500
   cmp      bx,5
501
   je       pcnet32_adjust_pci_device_Latency
502
   ;******Make card a bus master*******
503
   mov      cx, ax                              ;value to write
504
   mov     bh, [pci_dev]
505
   mov     al, 2                                ;write a word
506
   or       cx,5
507
   mov     ah, [pci_bus]
508
   mov     bl, 0x04                             ;to command register
509
   call    pci_write_reg
510
   ;******Check latency setting***********
511
pcnet32_adjust_pci_device_Latency:
512
   ;*******Get current latency setting************************
513
;   mov     al, 1                                       ;read a byte
514
;   mov     bh, [pci_dev]
515
;   mov     ah, [pci_bus]
516
;   mov     bl, 0x0D                                ;from Lantency Timer Register
517
;   call    pci_read_reg
518
   ;******see if its aat least 64 clocks********
519
;   cmp      ax,64
520
;   jge      pcnet32_adjust_pci_device_Done
521
   ;******Set latency to 32 clocks*******
522
;   mov     cx, 64                              ;value to write
523
;   mov     bh, [pci_dev]
524
;   mov     al, 1                               ;write a byte
525
;   mov     ah, [pci_bus]
526
;   mov     bl, 0x0D                            ;to Lantency Timer Register
527
;   call    pci_write_reg
528
   ;******Check latency setting***********
529
pcnet32_adjust_pci_device_Done:
530
   ret
531
pcnet32_probe:
532
    mov ebp,[io_addr]
533
    call pcnet32_wio_reset
534
    xor ebx,ebx
535
    call pcnet32_wio_read_csr
536
    cmp eax,4
537
    jne .try_dwio
538
    call pcnet32_wio_check
539
    and al,al
540
    jz .try_dwio
541
;    PutStr "Using WIO"
542
    mov esi,pcnet32_wio
543
    jmp .L1
544
.try_dwio:
545
    call pcnet32_dwio_reset
546
    xor ebx,ebx
547
    call pcnet32_dwio_read_csr
548
    cmp eax,4
549
    jne .no_dev
550
    call pcnet32_dwio_check
551
    and al,al
552
    jz .no_dev
553
;    PutStr "Using DWIO"
554
    mov esi,pcnet32_dwio
555
    jmp .L1
556
.no_dev:
557
;    PutStr "PCNET32 not found"
558
    ret
559
.L1:
560
    mov edi,pcnet32_access
561
    mov ecx,7
562
    cld
563
    rep movsd
564
    mov ebx,88
565
    call dword [pcnet32_access.read_csr]
566
    mov ecx,eax
567
    mov ebx,89
568
    call dword [pcnet32_access.read_csr]
569
    shl eax,16
570
    or eax,ecx
571
    mov ecx,eax
572
    and ecx,0xfff
573
    cmp ecx,3
574
    jne .no_dev
575
    shr eax,12
576
    and eax,0xffff
577
    mov [pcnet32_private.chip_version],eax
578
;    PutStr "PCNET32 chip version OK"
579
    mov [pcnet32_private.fdx],0
580
    mov [pcnet32_private.mii],0
581
    mov [pcnet32_private.fset],0
582
    mov [pcnet32_private.dxsuflo],0
583
    mov [pcnet32_private.ltint],0
584
    mov eax,[pcnet32_private.chip_version]
585
    cmp eax,0x2420
586
    je .L2
587
    cmp eax,0x2430
588
    je .L3
589
    cmp eax,0x2621
590
    je .L4
591
    cmp eax,0x2623
592
    je .L5
593
    cmp eax,0x2624
594
    je .L6
595
    cmp eax,0x2625
596
    je .L7
597
    cmp eax,0x2626
598
    je .L8
599
    cmp eax,0x2627
600
    je .L9
601
;    PutStr "Invalid chip rev"
602
    jmp .no_dev
603
.L2:
604
;    PutStr "PCnet/PCI 79C970"
605
    jmp .L10
606
.L3:
607
;    PutStr "PCnet/PCI 79C970"
608
    jmp .L10
609
.L4:
610
;    PutStr "PCnet/PCI II 79C970A"
611
    mov [pcnet32_private.fdx],1
612
    jmp .L10
613
.L5:
614
;    PutStr "PCnet/FAST 79C971"
615
    mov [pcnet32_private.fdx],1
616
    mov [pcnet32_private.mii],1
617
    mov [pcnet32_private.fset],1
618
    mov [pcnet32_private.ltint],1
619
    jmp .L10
620
.L6:
621
;    PutStr "PCnet/FAST+ 79C972"
622
    mov [pcnet32_private.fdx],1
623
    mov [pcnet32_private.mii],1
624
    mov [pcnet32_private.fset],1
625
    jmp .L10
626
.L7:
627
;    PutStr "PCnet/FAST III 79C973"
628
    mov [pcnet32_private.fdx],1
629
    mov [pcnet32_private.mii],1
630
    jmp .L10
631
.L8:
632
;    PutStr "PCnet/Home 79C978"
633
    mov [pcnet32_private.fdx],1
634
    mov ebx,49
635
    call dword [pcnet32_access.read_bcr]
636
    call dword [pcnet32_access.write_bcr]
637
    jmp .L10
638
.L9:
639
;    PutStr "PCnet/FAST III 79C975"
640
    mov [pcnet32_private.fdx],1
641
    mov [pcnet32_private.mii],1
642
.L10:
643
    cmp [pcnet32_private.fset],1
644
    jne .L11
645
    mov ebx,18
646
    call dword [pcnet32_access.read_bcr]
647
    or eax,0x800
648
    call dword [pcnet32_access.write_bcr]
649
    mov ebx,80
650
    call dword [pcnet32_access.read_csr]
651
    and eax,0xc00
652
    or eax,0xc00
653
    call dword [pcnet32_access.write_csr]
654
    mov [pcnet32_private.dxsuflo],1
655
    mov [pcnet32_private.ltint],1
656
.L11:
657
    ; read MAC
658
    mov edi,node_addr
659
    mov edx,ebp
660
    mov ecx,6
661
.Lmac:
662
    in al,dx
663
    stosb
664
    inc edx
665
    loop .Lmac
666
;    PutStr "MAC read"
667
    call pcnet32_adjust_pci_device
668
;    PutStr "PCI done"
669
    mov eax,PCNET32_PORT_ASEL
670
    mov [pcnet32_private.options],eax
671
    mov [pcnet32_private.mode],word 0x0003
672
    mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
673
    mov esi,node_addr
674
    mov edi,pcnet32_private.phys_addr
675
    cld
676
    movsd
677
    movsw
678
    mov [pcnet32_private.filter],dword 0
679
    mov [pcnet32_private.filter+4],dword 0
680
    mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring
681
    mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
682
;    PutStr "Switching to 32"
683
    mov ebx,20
684
    mov eax,2
685
    call dword [pcnet32_access.write_bcr]
686
    mov ebx,1
687
    mov eax,(pcnet32_private and 0xffff)
688
    call dword [pcnet32_access.write_csr]
689
    mov ebx,2
690
    mov eax,(pcnet32_private shr 16) and 0xffff
691
    call dword [pcnet32_access.write_csr]
692
    mov ebx,0
693
    mov eax,1
694
    call dword [pcnet32_access.write_csr]
695
    mov esi,1
696
    call delay_ms
697
    call pcnet32_reset
698
    mov eax, [pci_data]
699
    mov [eth_status], eax
700
    ret
701
pcnet32_poll:
702
    xor eax,eax
703
    mov [eth_rx_data_len],ax
704
    mov eax,[pcnet32_private.cur_rx]
705
    and eax,PCNET32_RX_RING_MOD_MASK
706
    mov ebx,eax
707
    imul esi,eax,PCNET32_PKT_BUF_SZ
708
    add esi,pcnet32_rxb
709
    shl ebx,4
710
    add ebx,pcnet32_rx_ring
711
    mov cx,[ebx+pcnet32_rx_head.status]
712
    test cx,0x8000
713
    jnz .L1
714
    cmp ch,3
715
    jne .L1
716
;    PutStr "PCNETRX"
717
    mov ecx,[ebx+pcnet32_rx_head.msg_length]
718
    and ecx,0xfff
719
    sub ecx,4
720
    mov [eth_rx_data_len],cx
721
    push ecx
722
    shr ecx,2
723
    mov edi,Ether_buffer
724
    cld
725
    rep movsd
726
    pop ecx
727
    and ecx,3
728
    rep movsb
729
    mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
730
    or [ebx+pcnet32_rx_head.status],word 0x8000
731
    inc [pcnet32_private.cur_rx]
732
.L1:
733
    ret
734
;         Pointer to 48 bit destination address in edi
735
;         Type of packet in bx
736
;         size of packet in ecx
737
;         pointer to packet data in esi
738
pcnet32_xmit:
739
    push edi
740
    push esi
741
    push ebx
742
    push ecx
743
;    PutStr "PCNETTX"
744
    mov esi,edi
745
    mov edi,[pcnet32_private.cur_tx]
746
    imul edi,PCNET32_PKT_BUF_SZ
747
    add edi,pcnet32_txb ; edi=ptxb
748
    mov eax,edi
749
    cld         ; copy MAC
750
    movsd
751
    movsw
752
    mov esi,node_addr
753
    cld
754
    movsd
755
    movsw
756
    mov [edi],bx
757
    add edi,2
758
    mov esi,[esp+8]
759
    mov ecx,[esp]
760
    push ecx
761
    shr ecx,2
762
    cld
763
    rep movsd
764
    pop ecx
765
    and ecx,3
766
    rep movsb
767
;    mov ecx,[esp]
768
;    add ecx,14 ; ETH_HLEN
769
;    xor eax,eax
770
; pad to min length (60=ETH_ZLEN)
771
;    cmp ecx,60
772
;    jae .L1
773
;    sub ecx,60
774
;    cld
775
;    rep stosb
776
;.L1:
777
    mov edi,pcnet32_tx_ring+0   ; entry=0
778
    mov ecx,[esp]
779
    add ecx,14
780
    cmp cx,60
781
    jae .L1
782
    mov cx,60
783
.L1:
784
    neg cx
785
    mov [edi+pcnet32_tx_head.length],cx
786
    mov [edi+pcnet32_tx_head.misc],dword 0
787
    mov [edi+pcnet32_tx_head.base],eax
788
    mov [edi+pcnet32_tx_head.status],word 0x8300
789
    ; trigger an immediate send poll
790
    mov ebx,0
791
    mov eax,0x0008      ; 0x0048
792
    mov ebp,[io_addr]
793
    call dword [pcnet32_access.write_csr]
794
    mov dword [pcnet32_private.cur_tx],0
795
    ; wait for TX to complete
796
    mov ecx,[timer_ticks];[0xfdf0]
797
    add ecx,100
798
.L2:
799
    mov ax,[edi+pcnet32_tx_head.status]
800
    test ax,0x8000
801
    jz .L3
802
    cmp ecx,[timer_ticks];[0xfdf0]
803
    jb .L4
804
    mov esi,10
805
    call delay_ms
806
    jnz .L2
807
.L4:
808
;    PutStr "PCNET: Send timeout"
809
.L3:
810
    mov dword [edi+pcnet32_tx_head.base],0
811
    pop ecx
812
    pop ebx
813
    pop esi
814
    pop edi
815
    ret