Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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