Subversion Repositories Kolibri OS

Rev

Rev 8910 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                  ;;
8897 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved.     ;;
3545 hidnplayr 4
;; Distributed under terms of the GNU General Public License        ;;
5
;;                                                                  ;;
6
;;  AMD PCnet driver for KolibriOS                                  ;;
7
;;                                                                  ;;
8
;;  By hidnplayr & clevermouse                                      ;;
9
;;                                                                  ;;
10
;;  Based on the PCnet32 driver for MenuetOS, by Jarek Pelczar      ;;
11
;;                                                                  ;;
12
;;          GNU GENERAL PUBLIC LICENSE                              ;;
13
;;             Version 2, June 1991                                 ;;
14
;;                                                                  ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
4532 hidnplayr 17
format PE DLL native
18
entry START
3545 hidnplayr 19
 
4532 hidnplayr 20
        CURRENT_API             = 0x0200
21
        COMPATIBLE_API          = 0x0100
22
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
3545 hidnplayr 23
 
8897 hidnplayr 24
; configureable area
4532 hidnplayr 25
 
8897 hidnplayr 26
        MAX_DEVICES             = 16    ; Maximum number of devices this driver may handle
3545 hidnplayr 27
 
8897 hidnplayr 28
        __DEBUG__               = 1     ; 1 = on, 0 = off
29
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
3545 hidnplayr 30
 
8897 hidnplayr 31
        TX_RING_SIZE            = 32    ; Number of packets in send ring buffer
32
        RX_RING_SIZE            = 32    ; Number of packets in receive ring buffer
33
 
34
; end configureable area
35
 
4532 hidnplayr 36
section '.flat' readable writable executable
37
 
4467 hidnplayr 38
include '../struct.inc'
39
include '../macros.inc'
3545 hidnplayr 40
include '../proc32.inc'
41
include '../fdo.inc'
5074 hidnplayr 42
include '../netdrv.inc'
3545 hidnplayr 43
 
8897 hidnplayr 44
if (bsr TX_RING_SIZE)>(bsf TX_RING_SIZE)
45
  display 'TX_RING_SIZE must be a power of two'
46
  err
47
end if
3545 hidnplayr 48
 
8897 hidnplayr 49
if (bsr RX_RING_SIZE)>(bsf RX_RING_SIZE)
50
  display 'RX_RING_SIZE must be a power of two'
51
  err
52
end if
53
 
3545 hidnplayr 54
        PORT_AUI                = 0x00
55
        PORT_10BT               = 0x01
56
        PORT_GPSI               = 0x02
57
        PORT_MII                = 0x03
58
        PORT_PORTSEL            = 0x03
59
        PORT_ASEL               = 0x04
60
        PORT_100                = 0x40
61
        PORT_FD                 = 0x80
62
 
63
        DMA_MASK                = 0xffffffff
64
 
8897 hidnplayr 65
        TX_RING_LEN_BITS        = ((bsf TX_RING_SIZE) shl 12)
66
        RX_RING_LEN_BITS        = ((bsf RX_RING_SIZE) shl 4)
3545 hidnplayr 67
 
68
        PKT_BUF_SZ              = 1544
69
 
70
        WIO_RDP                 = 0x10
71
        WIO_RAP                 = 0x12
72
        WIO_RESET               = 0x14
73
        WIO_BDP                 = 0x16
74
 
75
        DWIO_RDP                = 0x10
76
        DWIO_RAP                = 0x14
77
        DWIO_RESET              = 0x18
78
        DWIO_BDP                = 0x1C
79
 
80
; CSR registers
81
 
82
        CSR_CSR                 = 0x00
83
        CSR_IAB0                = 0x01
84
        CSR_IAB1                = 0x02
85
        CSR_IMR                 = 0x03
86
        CSR_TFEAT               = 0x04
87
        CSR_EXTCTL1             = 0x05
88
        CSR_DTBLLEN             = 0x06
89
        CSR_EXTCTL2             = 0x07
90
        CSR_MAR0                = 0x08
91
        CSR_MAR1                = 0x09
92
        CSR_MAR2                = 0x0A
93
        CSR_MAR3                = 0x0B
94
        CSR_PAR0                = 0x0C
95
        CSR_PAR1                = 0x0D
96
        CSR_PAR2                = 0x0E
97
        CSR_MODE                = 0x0F
98
        CSR_RXADDR0             = 0x18
99
        CSR_RXADDR1             = 0x19
100
        CSR_TXADDR0             = 0x1E
101
        CSR_TXADDR1             = 0x1F
102
        CSR_TXPOLL              = 0x2F
103
        CSR_RXPOLL              = 0x31
104
        CSR_RXRINGLEN           = 0x4C
105
        CSR_TXRINGLEN           = 0x4E
106
        CSR_DMACTL              = 0x50
107
        CSR_BUSTIMER            = 0x52
108
        CSR_MEMERRTIMEO         = 0x64
109
        CSR_ONNOWMISC           = 0x74
110
        CSR_ADVFEAT             = 0x7A
111
        CSR_MACCFG              = 0x7D
112
        CSR_CHIPID0             = 0x58
113
        CSR_CHIPID1             = 0x59
114
 
115
; Control and Status Register (CSR0)
116
 
5004 hidnplayr 117
        CSR_INIT                = 0x0001 ;1 shl 0
118
        CSR_START               = 0x0002 ;1 shl 1
119
        CSR_STOP                = 0x0004 ;1 shl 2
120
        CSR_TX                  = 0x0008 ;1 shl 3
121
        CSR_TXON                = 0x0010 ;1 shl 4
122
        CSR_RXON                = 0x0020 ;1 shl 5
123
        CSR_INTEN               = 0x0040 ;1 shl 6
124
        CSR_INTR                = 0x0080 ;1 shl 7
125
        CSR_IDONE               = 0x0100 ;1 shl 8
126
        CSR_TINT                = 0x0200 ;1 shl 9
127
        CSR_RINT                = 0x0400 ;1 shl 10
128
        CSR_MERR                = 0x0800 ;1 shl 11
129
        CSR_MISS                = 0x1000 ;1 shl 12
130
        CSR_CERR                = 0x2000 ;1 shl 13
3545 hidnplayr 131
 
132
; Interrupt masks and deferral control (CSR3)
133
 
134
        IMR_BSWAP               = 0x0004
135
        IMR_ENMBA               = 0x0008  ; enable modified backoff alg
136
        IMR_DXMT2PD             = 0x0010
137
        IMR_LAPPEN              = 0x0020  ; lookahead packet processing enb
138
        IMR_DXSUFLO             = 0x0040  ; disable TX stop on underflow
139
        IMR_IDONE               = 0x0100
140
        IMR_TINT                = 0x0200
141
        IMR_RINT                = 0x0400
142
        IMR_MERR                = 0x0800
143
        IMR_MISS                = 0x1000
144
 
5004 hidnplayr 145
        ; Masked interrupts will be disabled.
146
        IMR                     = 0 ;IMR_IDONE ;or IMR_TINT or IMR_RINT or IMR_MERR or IMR_MISS
3545 hidnplayr 147
 
148
; Test and features control (CSR4)
149
 
150
        TFEAT_TXSTRTMASK        = 0x0004
151
        TFEAT_TXSTRT            = 0x0008
152
        TFEAT_RXCCOFLOWM        = 0x0010  ; Rx collision counter oflow
153
        TFEAT_RXCCOFLOW         = 0x0020
154
        TFEAT_UINT              = 0x0040
155
        TFEAT_UINTREQ           = 0x0080
156
        TFEAT_MISSOFLOWM        = 0x0100
157
        TFEAT_MISSOFLOW         = 0x0200
158
        TFEAT_STRIP_FCS         = 0x0400
159
        TFEAT_PAD_TX            = 0x0800
160
        TFEAT_TXDPOLL           = 0x1000
161
        TFEAT_DMAPLUS           = 0x4000
162
 
163
; Extended control and interrupt 1 (CSR5)
164
 
165
        EXTCTL1_SPND            = 0x0001  ; suspend
166
        EXTCTL1_MPMODE          = 0x0002  ; magic packet mode
167
        EXTCTL1_MPENB           = 0x0004  ; magic packet enable
168
        EXTCTL1_MPINTEN         = 0x0008  ; magic packet interrupt enable
169
        EXTCTL1_MPINT           = 0x0010  ; magic packet interrupt
170
        EXTCTL1_MPPLBA          = 0x0020  ; magic packet phys. logical bcast
171
        EXTCTL1_EXDEFEN         = 0x0040  ; excessive deferral interrupt enb.
172
        EXTCTL1_EXDEF           = 0x0080  ; excessive deferral interrupt
173
        EXTCTL1_SINTEN          = 0x0400  ; system interrupt enable
174
        EXTCTL1_SINT            = 0x0800  ; system interrupt
175
        EXTCTL1_LTINTEN         = 0x4000  ; last TX interrupt enb
176
        EXTCTL1_TXOKINTD        = 0x8000  ; TX OK interrupt disable
177
 
178
; RX/TX descriptor len (CSR6)
179
 
180
        DTBLLEN_RLEN            = 0x0F00
181
        DTBLLEN_TLEN            = 0xF000
182
 
183
; Extended control and interrupt 2 (CSR7)
184
 
185
        EXTCTL2_MIIPDTINTE      = 0x0001
186
        EXTCTL2_MIIPDTINT       = 0x0002
187
        EXTCTL2_MCCIINTE        = 0x0004
188
        EXTCTL2_MCCIINT         = 0x0008
189
        EXTCTL2_MCCINTE         = 0x0010
190
        EXTCTL2_MCCINT          = 0x0020
191
        EXTCTL2_MAPINTE         = 0x0040
192
        EXTCTL2_MAPINT          = 0x0080
193
        EXTCTL2_MREINTE         = 0x0100
194
        EXTCTL2_MREINT          = 0x0200
195
        EXTCTL2_STINTE          = 0x0400
196
        EXTCTL2_STINT           = 0x0800
197
        EXTCTL2_RXDPOLL         = 0x1000
198
        EXTCTL2_RDMD            = 0x2000
199
        EXTCTL2_RXFRTG          = 0x4000
200
        EXTCTL2_FASTSPNDE       = 0x8000
201
 
202
; Mode (CSR15)
203
 
204
        MODE_RXD                = 0x0001  ; RX disable
205
        MODE_TXD                = 0x0002  ; TX disable
206
        MODE_LOOP               = 0x0004  ; loopback enable
207
        MODE_TXCRCD             = 0x0008
208
        MODE_FORCECOLL          = 0x0010
209
        MODE_RETRYD             = 0x0020
210
        MODE_INTLOOP            = 0x0040
211
        MODE_PORTSEL            = 0x0180
212
        MODE_RXVPAD             = 0x2000
213
        MODE_RXNOBROAD          = 0x4000
214
        MODE_PROMISC            = 0x8000
215
 
216
; BCR (Bus Control Registers)
217
 
218
        BCR_MMRA                = 0x00    ; Master Mode Read Active
219
        BCR_MMW                 = 0x01    ; Master Mode Write Active
220
        BCR_MISCCFG             = 0x02
221
        BCR_LED0                = 0x04
222
        BCR_LED1                = 0x05
223
        BCR_LED2                = 0x06
224
        BCR_LED3                = 0x07
225
        BCR_DUPLEX              = 0x09
226
        BCR_BUSCTL              = 0x12
227
        BCR_EECTL               = 0x13
228
        BCR_SSTYLE              = 0x14
229
        BCR_PCILAT              = 0x16
230
        BCR_PCISUBVENID         = 0x17
231
        BCR_PCISUBSYSID         = 0x18
232
        BCR_SRAMSIZE            = 0x19
233
        BCR_SRAMBOUND           = 0x1A
234
        BCR_SRAMCTL             = 0x1B
235
        BCR_MIICTL              = 0x20
236
        BCR_MIIADDR             = 0x21
237
        BCR_MIIDATA             = 0x22
238
        BCR_PCIVENID            = 0x23
239
        BCR_PCIPCAP             = 0x24
240
        BCR_DATA0               = 0x25
241
        BCR_DATA1               = 0x26
242
        BCR_DATA2               = 0x27
243
        BCR_DATA3               = 0x28
244
        BCR_DATA4               = 0x29
245
        BCR_DATA5               = 0x2A
246
        BCR_DATA6               = 0x2B
247
        BCR_DATA7               = 0x2C
248
        BCR_ONNOWPAT0           = 0x2D
249
        BCR_ONNOWPAT1           = 0x2E
250
        BCR_ONNOWPAT2           = 0x2F
251
        BCR_PHYSEL              = 0x31
252
 
253
; RX status register
254
 
255
        RXSTAT_BPE              = 0x0080        ; bus parity error
256
        RXSTAT_ENP              = 0x0100        ; end of packet
257
        RXSTAT_STP              = 0x0200        ; start of packet
258
        RXSTAT_BUFF             = 0x0400        ; buffer error
259
        RXSTAT_CRC              = 0x0800        ; CRC error
260
        RXSTAT_OFLOW            = 0x1000        ; rx overrun
261
        RXSTAT_FRAM             = 0x2000        ; framing error
262
        RXSTAT_ERR              = 0x4000        ; error summary
263
        RXSTAT_OWN              = 0x8000
264
 
265
; TX status register
266
 
267
        TXSTAT_TRC              = 0x0000000F    ; transmit retries
268
        TXSTAT_RTRY             = 0x04000000    ; retry
269
        TXSTAT_LCAR             = 0x08000000    ; lost carrier
270
        TXSTAT_LCOL             = 0x10000000    ; late collision
271
        TXSTAT_EXDEF            = 0x20000000    ; excessive deferrals
272
        TXSTAT_UFLOW            = 0x40000000    ; transmit underrun
273
        TXSTAT_BUFF             = 0x80000000    ; buffer error
274
 
275
        TXCTL_OWN               = 0x8000
276
        TXCTL_ERR               = 0x4000        ; error summary
277
        TXCTL_ADD_FCS           = 0x2000        ; add FCS to pkt
278
        TXCTL_MORE_LTINT        = 0x1000
279
        TXCTL_ONE               = 0x0800
280
        TXCTL_DEF               = 0x0400
281
        TXCTL_STP               = 0x0200
282
        TXCTL_ENP               = 0x0100
283
        TXCTL_BPE               = 0x0080
284
 
285
        TXCTL_MBO               = 0x0000F000
286
        TXCTL_BUFSZ             = 0x00000FFF
287
 
288
        MAX_PHYS                = 32
289
 
290
 
8897 hidnplayr 291
; Pcnet configuration structure
292
struct  pcnet_init_block
3545 hidnplayr 293
 
4532 hidnplayr 294
        mode            dw ?
295
        tlen_rlen       dw ?
296
        phys_addr       dp ?
297
        reserved        dw ?
298
        filter          dq ?
299
        rx_ring_phys    dd ?
300
        tx_ring_phys    dd ?
8897 hidnplayr 301
ends
3545 hidnplayr 302
 
8897 hidnplayr 303
 
304
struct  device          ETH_DEVICE
305
 
4532 hidnplayr 306
        rb 0x100-($ and 0xff)   ; align 256
8897 hidnplayr 307
        init_block      pcnet_init_block
3545 hidnplayr 308
 
8897 hidnplayr 309
        rb 0x100-($ and 0xff)   ; align 256
4532 hidnplayr 310
        rx_ring         rb RX_RING_SIZE * sizeof.descriptor
3545 hidnplayr 311
 
4532 hidnplayr 312
        rb 0x100-($ and 0xff)   ; align 256
313
        tx_ring         rb TX_RING_SIZE * sizeof.descriptor
3545 hidnplayr 314
 
8897 hidnplayr 315
        cur_rx          dd ?
316
        cur_tx          dd ?
317
        last_tx         dd ?
318
 
4532 hidnplayr 319
        options         dd ?
320
        full_duplex     db ?
321
        chip_version    dw ?
322
        mii             db ?
323
        ltint           db ?
324
        dxsuflo         db ?
325
        fset            db ?
326
        fdx             db ?
3545 hidnplayr 327
 
4532 hidnplayr 328
        io_addr         dd ?
329
        irq_line        db ?
330
        pci_bus         dd ?
331
        pci_dev         dd ?
3545 hidnplayr 332
 
4532 hidnplayr 333
        phy             dw ?
3545 hidnplayr 334
 
8910 hidnplayr 335
        link_timer      dd ?
336
 
8897 hidnplayr 337
        rb 0x100-($ and 0xff)   ; align 256
338
 
4532 hidnplayr 339
        read_csr        dd ?
340
        write_csr       dd ?
341
        read_bcr        dd ?
342
        write_bcr       dd ?
343
        read_rap        dd ?
344
        write_rap       dd ?
345
        sw_reset        dd ?
3545 hidnplayr 346
 
4532 hidnplayr 347
ends
3545 hidnplayr 348
 
4532 hidnplayr 349
struct  descriptor
3545 hidnplayr 350
 
4532 hidnplayr 351
        base            dd ?
352
        length          dw ?
353
        status          dw ?
354
        msg_length      dw ?
355
        misc            dw ?
356
        virtual         dd ?
3545 hidnplayr 357
 
4532 hidnplayr 358
ends
3545 hidnplayr 359
 
360
 
361
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
362
;;                        ;;
363
;; proc START             ;;
364
;;                        ;;
365
;; (standard driver proc) ;;
366
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
367
 
4532 hidnplayr 368
proc START c, reason:dword, cmdline:dword
3545 hidnplayr 369
 
4532 hidnplayr 370
        cmp     [reason], DRV_ENTRY
371
        jne     .fail
3545 hidnplayr 372
 
4532 hidnplayr 373
        DEBUGF  2,"Loading driver\n"
374
        invoke  RegService, my_service, service_proc
3545 hidnplayr 375
        ret
376
 
377
  .fail:
378
        xor eax, eax
379
        ret
380
 
381
endp
382
 
383
 
384
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
385
;;                        ;;
386
;; proc SERVICE_PROC      ;;
387
;;                        ;;
388
;; (standard driver proc) ;;
389
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
390
 
391
align 4
392
proc service_proc stdcall, ioctl:dword
393
 
394
        mov     edx, [ioctl]
4470 hidnplayr 395
        mov     eax, [edx + IOCTL.io_code]
3545 hidnplayr 396
 
397
;------------------------------------------------------
398
 
399
        cmp     eax, 0 ;SRV_GETVERSION
400
        jne     @F
401
 
4470 hidnplayr 402
        cmp     [edx + IOCTL.out_size], 4
3545 hidnplayr 403
        jb      .fail
4470 hidnplayr 404
        mov     eax, [edx + IOCTL.output]
3545 hidnplayr 405
        mov     [eax], dword API_VERSION
406
 
407
        xor     eax, eax
408
        ret
409
 
410
;------------------------------------------------------
411
  @@:
412
        cmp     eax, 1 ;SRV_HOOK
413
        jne     .fail
414
 
4532 hidnplayr 415
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
3545 hidnplayr 416
        jb      .fail
417
 
4470 hidnplayr 418
        mov     eax, [edx + IOCTL.input]
4532 hidnplayr 419
        cmp     byte[eax], 1                            ; 1 means device number and bus number (pci) are given
3545 hidnplayr 420
        jne     .fail                                   ; other types arent supported for this card yet
421
 
422
; check if the device is already listed
423
 
424
        mov     ecx, [devices]
425
        test    ecx, ecx
426
        jz      .firstdevice
427
 
428
        mov     esi, device_list
4470 hidnplayr 429
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
430
        mov     ax, [eax+1]                             ;
3545 hidnplayr 431
  .nextdevice:
432
        mov     ebx, [esi]
4532 hidnplayr 433
        cmp     al, byte[ebx + device.pci_bus]
3545 hidnplayr 434
        jne     @f
4532 hidnplayr 435
        cmp     ah, byte[ebx + device.pci_dev]
3545 hidnplayr 436
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
437
       @@:
438
        add     esi, 4
439
        loop    .nextdevice
440
 
441
; This device doesnt have its own eth_device structure yet, lets create one
442
 
443
  .firstdevice:
444
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
445
        jae     .fail
446
 
4532 hidnplayr 447
        allocate_and_clear ebx, sizeof.device, .fail
3545 hidnplayr 448
 
449
; Fill in the direct call addresses into the struct
450
 
4532 hidnplayr 451
        mov     [ebx + device.reset], reset
452
        mov     [ebx + device.transmit], transmit
453
        mov     [ebx + device.unload], unload
454
        mov     [ebx + device.name], my_service
3545 hidnplayr 455
 
456
; save the pci bus and device numbers
457
 
4470 hidnplayr 458
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 459
        movzx   ecx, byte[eax+1]
4532 hidnplayr 460
        mov     [ebx + device.pci_bus], ecx
3545 hidnplayr 461
        movzx   ecx, byte[eax+2]
4532 hidnplayr 462
        mov     [ebx + device.pci_dev], ecx
3545 hidnplayr 463
 
464
; Now, it's time to find the base io addres of the PCI device
465
 
4532 hidnplayr 466
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
467
        mov     [ebx + device.io_addr], eax
3545 hidnplayr 468
 
469
; We've found the io address, find IRQ now
470
 
4532 hidnplayr 471
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
472
        mov     [ebx + device.irq_line], al
3545 hidnplayr 473
 
474
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
4532 hidnplayr 475
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
3545 hidnplayr 476
 
477
; Ok, the eth_device structure is ready, let's probe the device
478
; Because initialization fires IRQ, IRQ handler must be aware of this device
479
        mov     eax, [devices]                                          ; Add the device structure to our device list
480
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
481
        inc     [devices]                                               ;
482
 
483
        call    probe                                                   ; this function will output in eax
484
        test    eax, eax
485
        jnz     .destroy                                                ; If an error occured, exit
486
 
4532 hidnplayr 487
        mov     [ebx + device.type], NET_TYPE_ETH
488
        invoke  NetRegDev
3545 hidnplayr 489
        cmp     eax, -1
490
        je      .destroy
491
 
492
        ret
493
 
494
; If the device was already loaded, find the device number and return it in eax
495
 
496
  .find_devicenum:
497
        DEBUGF  1,"Trying to find device number of already registered device\n"
4532 hidnplayr 498
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
3545 hidnplayr 499
                                                                        ; into a device number in edi
500
        mov     eax, edi                                                ; Application wants it in eax instead
501
        DEBUGF  1,"Kernel says: %u\n", eax
502
        ret
503
 
504
; If an error occured, remove all allocated data and exit (returning -1 in eax)
505
 
506
  .destroy:
507
        ; todo: reset device into virgin state
5522 hidnplayr 508
        add     eax, NET_BUFF.data
3545 hidnplayr 509
        dec     [devices]
510
  .err:
3855 hidnplayr 511
        DEBUGF  2,"Error, removing all data !\n"
4532 hidnplayr 512
        invoke  KernelFree, ebx
3545 hidnplayr 513
 
514
  .fail:
515
        or      eax, -1
516
        ret
517
 
518
;------------------------------------------------------
519
endp
520
 
521
 
522
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
523
;;                                                                        ;;
524
;;        Actual Hardware dependent code starts here                      ;;
525
;;                                                                        ;;
526
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
527
 
528
align 4
529
unload:
8910 hidnplayr 530
 
531
        cmp     [ebx + device.link_timer], 0
532
        je      @f
533
        invoke  CancelTimerHS, [ebx + device.link_timer]
534
  @@:
535
 
3545 hidnplayr 536
        ; TODO: (in this particular order)
537
        ;
538
        ; - Stop the device
539
        ; - Detach int handler
4532 hidnplayr 540
        ; - Remove device from local list (device_list)
3545 hidnplayr 541
        ; - call unregister function in kernel
542
        ; - Remove all allocated structures and buffers the card used
543
 
5522 hidnplayr 544
        or      eax, -1
545
        ret
3545 hidnplayr 546
 
547
 
548
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
549
;;
550
;;  probe: enables the device (if it really is a PCnet device)
551
;;
552
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
553
 
554
align 4
555
probe:
556
 
4532 hidnplayr 557
        mov     edx, [ebx + device.io_addr]
3545 hidnplayr 558
 
559
        call    wio_reset
560
 
561
        xor     ecx, ecx
562
        call    wio_read_csr
563
        cmp     eax, 4
564
        jne     .try_dwio
565
 
566
        ; Try Word I/O
567
        mov     ax, 88
568
        add     edx, WIO_RAP
569
        out     dx, ax
570
        nop
571
        nop
572
        in      ax, dx
573
        sub     edx, WIO_RAP
574
        cmp     ax, 88
575
        jne     .try_dwio
576
 
577
        call    switch_to_wio
578
 
579
        jmp     .L1
580
 
581
  .try_dwio:
582
        call    dwio_reset
583
 
584
        xor     ecx, ecx
585
        call    dwio_read_csr
586
        cmp     eax, 4
587
        jne     .no_dev
588
 
589
        ; Try Dword I/O
590
        add     edx, DWIO_RAP
591
        mov     eax, 88
592
        out     dx, eax
593
        nop
594
        nop
595
        in      eax, dx
596
        sub     edx, DWIO_RAP
597
        and     eax, 0xffff
598
        cmp     eax, 88
599
        jne     .no_dev
600
 
601
        call    switch_to_dwio
602
 
603
        jmp     .L1
604
 
605
  .no_dev:
4532 hidnplayr 606
        DEBUGF  2,"device not found!\n"
3545 hidnplayr 607
        mov     eax, 1
608
        ret
609
 
610
  .L1:
611
        mov     ecx, CSR_CHIPID0
4532 hidnplayr 612
        call    [ebx + device.read_csr]
3545 hidnplayr 613
 
614
        mov     esi, eax
615
        shr     esi, 12
616
 
617
        and     ax, 0xfff
618
        cmp     ax, 3
619
        jne     .no_dev
620
 
621
        mov     ecx, CSR_CHIPID1
4532 hidnplayr 622
        call    [ebx + device.read_csr]
3545 hidnplayr 623
        shl     eax, 4
624
        or      eax, esi
4532 hidnplayr 625
        mov     [ebx + device.chip_version], ax
3545 hidnplayr 626
 
4532 hidnplayr 627
        mov     [ebx + device.fdx], 0
628
        mov     [ebx + device.mii], 0
629
        mov     [ebx + device.fset], 0
630
        mov     [ebx + device.dxsuflo], 0
631
        mov     [ebx + device.ltint], 0
3545 hidnplayr 632
 
633
        cmp     ax, 0x2420
634
        je      .L2
635
        cmp     ax, 0x2430
636
        je      .L2
637
 
4532 hidnplayr 638
        mov     [ebx + device.fdx], 1
3545 hidnplayr 639
 
640
        cmp     ax, 0x2621
641
        je      .L4
642
        cmp     ax, 0x2623
643
        je      .L5
644
        cmp     ax, 0x2624
645
        je      .L6
646
        cmp     ax, 0x2625
647
        je      .L7
648
        cmp     ax, 0x2626
649
        je      .L8
650
        cmp     ax, 0x2627
651
        je      .L9
652
 
5065 hidnplayr 653
        DEBUGF  2,"Invalid chip rev\n"
3545 hidnplayr 654
        jmp     .no_dev
655
  .L2:
4532 hidnplayr 656
        mov     [ebx + device.name], device_l2
3545 hidnplayr 657
        jmp     .L10
658
  .L4:
4532 hidnplayr 659
        mov     [ebx + device.name], device_l4
660
;        mov     [ebx + device.fdx], 1
3545 hidnplayr 661
        jmp     .L10
662
  .L5:
4532 hidnplayr 663
        mov     [ebx + device.name], device_l5
664
;        mov     [ebx + device.fdx], 1
665
        mov     [ebx + device.mii], 1
666
        mov     [ebx + device.fset], 1
667
        mov     [ebx + device.ltint], 1
3545 hidnplayr 668
        jmp     .L10
669
  .L6:
4532 hidnplayr 670
        mov     [ebx + device.name], device_l6
671
;        mov     [ebx + device.fdx], 1
672
        mov     [ebx + device.mii], 1
673
        mov     [ebx + device.fset], 1
3545 hidnplayr 674
        jmp     .L10
675
  .L7:
4532 hidnplayr 676
        mov     [ebx + device.name], device_l7
677
;        mov     [ebx + device.fdx], 1
678
        mov     [ebx + device.mii], 1
3545 hidnplayr 679
        jmp     .L10
680
  .L8:
4532 hidnplayr 681
        mov     [ebx + device.name], device_l8
682
;        mov     [ebx + device.fdx], 1
3545 hidnplayr 683
        mov     ecx, CSR_RXPOLL
4532 hidnplayr 684
        call    dword [ebx + device.read_bcr]
685
        call    dword [ebx + device.write_bcr]
3545 hidnplayr 686
        jmp     .L10
687
  .L9:
4532 hidnplayr 688
        mov     [ebx + device.name], device_l9
689
;        mov     [ebx + device.fdx], 1
690
        mov     [ebx + device.mii], 1
3545 hidnplayr 691
  .L10:
4532 hidnplayr 692
        DEBUGF  1,"device name: %s\n", [ebx + device.name]
3545 hidnplayr 693
 
4532 hidnplayr 694
        cmp     [ebx + device.fset], 1
3545 hidnplayr 695
        jne     .L11
696
        mov     ecx, BCR_BUSCTL
4532 hidnplayr 697
        call    [ebx + device.read_bcr]
3545 hidnplayr 698
        or      eax, 0x800
4532 hidnplayr 699
        call    [ebx + device.write_bcr]
3545 hidnplayr 700
 
701
        mov     ecx, CSR_DMACTL
5617 hidnplayr 702
;        call    [ebx + device.read_csr]
3545 hidnplayr 703
        mov     eax, 0xc00
4532 hidnplayr 704
        call    [ebx + device.write_csr]
3545 hidnplayr 705
 
4532 hidnplayr 706
        mov     [ebx + device.dxsuflo],1
707
        mov     [ebx + device.ltint],1
3545 hidnplayr 708
  .L11:
709
 
4532 hidnplayr 710
; Make the device a bus master
711
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
712
        or      al, PCI_CMD_MASTER
713
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
3545 hidnplayr 714
 
4532 hidnplayr 715
        mov     [ebx + device.options], PORT_ASEL
8897 hidnplayr 716
        mov     [ebx + device.init_block.mode], MODE_RXD + MODE_TXD     ; disable receive and transmit
717
        mov     [ebx + device.init_block.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
3545 hidnplayr 718
 
8897 hidnplayr 719
        mov     dword[ebx + device.init_block.filter], 0
720
        mov     dword[ebx + device.init_block.filter+4], 0
3545 hidnplayr 721
 
722
align 4
723
reset:
724
 
8910 hidnplayr 725
; Stop link check timer if it was already running
726
        cmp     [ebx + device.link_timer], 0
727
        je      @f
728
        invoke  CancelTimerHS, [ebx + device.link_timer]
729
  @@:
730
 
3545 hidnplayr 731
; attach int handler
732
 
4532 hidnplayr 733
        movzx   eax, [ebx + device.irq_line]
3545 hidnplayr 734
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
4532 hidnplayr 735
        invoke  AttachIntHandler, eax, int_handler, ebx
3545 hidnplayr 736
        test    eax, eax
737
        jnz     @f
3855 hidnplayr 738
        DEBUGF  2,"Could not attach int handler!\n"
4532 hidnplayr 739
        or      eax, -1
740
        ret
3545 hidnplayr 741
  @@:
742
 
4532 hidnplayr 743
        mov     edx, [ebx + device.io_addr]
744
        call    [ebx + device.sw_reset]
3545 hidnplayr 745
 
746
        ; Switch pcnet32 to 32bit mode
747
        mov     ecx, BCR_SSTYLE
748
        mov     eax, 2
4532 hidnplayr 749
        call    [ebx + device.write_bcr]
3545 hidnplayr 750
 
751
        ; set/reset autoselect bit
752
        mov     ecx, BCR_MISCCFG
4532 hidnplayr 753
        call    [ebx + device.read_bcr]
3545 hidnplayr 754
        and     eax, not 2
4532 hidnplayr 755
        test    [ebx + device.options], PORT_ASEL
3545 hidnplayr 756
        jz      @f
757
        or      eax, 2
758
  @@:
4532 hidnplayr 759
        call    [ebx + device.write_bcr]
3545 hidnplayr 760
 
761
        ; Handle full duplex setting
4532 hidnplayr 762
        cmp     byte [ebx + device.full_duplex], 0
3545 hidnplayr 763
        je      .duplex_ok
764
        mov     ecx, BCR_DUPLEX
4532 hidnplayr 765
        call    [ebx + device.read_bcr]
3545 hidnplayr 766
        and     eax, not 3
4532 hidnplayr 767
        test    [ebx + device.options], PORT_FD
3545 hidnplayr 768
        jz      @f
769
        or      eax, 1
4532 hidnplayr 770
        cmp     [ebx + device.options], PORT_FD or PORT_AUI
3545 hidnplayr 771
        jne     .set_duplex
772
        or      eax, 2
773
        jmp     .set_duplex
774
  @@:
4532 hidnplayr 775
        test    [ebx + device.options], PORT_ASEL
3545 hidnplayr 776
        jz      .set_duplex
4532 hidnplayr 777
        cmp     [ebx + device.chip_version], 0x2627
3545 hidnplayr 778
        jne     .set_duplex
779
        or      eax, 3
780
  .set_duplex:
781
        mov     ecx, BCR_DUPLEX
4532 hidnplayr 782
        call    [ebx + device.write_bcr]
3545 hidnplayr 783
  .duplex_ok:
784
 
785
        ; set/reset GPSI bit in test register
786
        mov     ecx, 124
4532 hidnplayr 787
        call    [ebx + device.read_csr]
788
        mov     ecx, [ebx + device.options]
3545 hidnplayr 789
        and     ecx, PORT_PORTSEL
790
        cmp     ecx, PORT_GPSI
791
        jne     @f
792
        or      eax, 0x10
793
  @@:
4532 hidnplayr 794
        call    [ebx + device.write_csr]
795
        cmp     [ebx + device.mii], 0
3545 hidnplayr 796
        je      .L6
4532 hidnplayr 797
        test    [ebx + device.options], PORT_ASEL
3545 hidnplayr 798
        jnz     .L6
799
        mov     ecx, BCR_MIICTL
4532 hidnplayr 800
        call    [ebx + device.read_bcr]
3545 hidnplayr 801
        and     eax, not 0x38
4532 hidnplayr 802
        test    [ebx + device.options], PORT_FD
3545 hidnplayr 803
        jz      @f
804
        or      eax, 0x10
805
  @@:
4532 hidnplayr 806
        test    [ebx + device.options], PORT_100
3545 hidnplayr 807
        jz      @f
808
        or      eax, 0x08
809
  @@:
4532 hidnplayr 810
        call    [ebx + device.write_bcr]
3545 hidnplayr 811
        jmp     .L9
812
  .L6:
4532 hidnplayr 813
        test    [ebx + device.options], PORT_ASEL
3545 hidnplayr 814
        jz      .L9
815
        mov     ecx, BCR_MIICTL
3855 hidnplayr 816
        DEBUGF  1,"ASEL, enable auto-negotiation\n"
4532 hidnplayr 817
        call    [ebx + device.read_bcr]
3545 hidnplayr 818
        and     eax, not 0x98
819
        or      eax, 0x20
4532 hidnplayr 820
        call    [ebx + device.write_bcr]
3545 hidnplayr 821
  .L9:
4532 hidnplayr 822
        cmp     [ebx + device.ltint], 0
3545 hidnplayr 823
        je      @f
824
        mov     ecx, 5
4532 hidnplayr 825
        call    [ebx + device.read_csr]
3545 hidnplayr 826
        or      eax, (1 shl 14)
4532 hidnplayr 827
        call    [ebx + device.write_csr]
3545 hidnplayr 828
  @@:
4532 hidnplayr 829
        mov     eax, [ebx + device.options]
3545 hidnplayr 830
        and     eax, PORT_PORTSEL
831
        shl     eax, 7
8897 hidnplayr 832
        mov     [ebx + device.init_block.mode], ax
833
        mov     dword [ebx + device.init_block.filter], -1
834
        mov     dword [ebx + device.init_block.filter+4], -1
3545 hidnplayr 835
 
836
 
837
 
838
;-----------------------------
839
 
4532 hidnplayr 840
        test    [ebx + device.mii], 1
3545 hidnplayr 841
        jz      .no_mii
842
 
4532 hidnplayr 843
        mov     [ebx + device.phy], 0
3545 hidnplayr 844
 
845
  .mii_loop:
846
        mov     ecx, MII_PHYSID1
847
        call    mdio_read
848
        cmp     ax, 0xffff
849
        je      .next
850
 
8910 hidnplayr 851
        DEBUGF  1, "PHY ID1: 0x%x\n", ax
3545 hidnplayr 852
 
853
        mov     ecx, MII_PHYSID2
854
        call    mdio_read
855
        cmp     ax, 0xffff
856
        je      .next
857
 
8910 hidnplayr 858
        DEBUGF  1, "PHY ID2: 0x%x\n", ax
3545 hidnplayr 859
 
860
        jmp     .got_phy
861
 
4532 hidnplayr 862
        cmp     [ebx + device.phy], 31
3545 hidnplayr 863
        jne     .next
4532 hidnplayr 864
        mov     ax, [ebx + device.chip_version]
3545 hidnplayr 865
        inc     ax
866
        and     ax, 0xfffe
867
        cmp     ax, 0x2624              ; 79c971 & 79c972 have phantom phy at id 31
868
        je      .got_phy
869
 
870
  .next:
4532 hidnplayr 871
        inc     [ebx + device.phy]
872
        cmp     [ebx + device.phy], MAX_PHYS
3545 hidnplayr 873
        jb      .mii_loop
874
 
3855 hidnplayr 875
        DEBUGF  2, "No PHY found!\n"
3545 hidnplayr 876
        or      eax, -1
877
        ret
878
 
879
  .got_phy:
4532 hidnplayr 880
        DEBUGF  1, "Found PHY at 0x%x\n", [ebx + device.phy]:4
3545 hidnplayr 881
 
882
  .no_mii:
883
 
884
;-----------------------------------------------
885
 
886
        call    read_mac
887
 
4532 hidnplayr 888
        lea     esi, [ebx + device.mac]
8897 hidnplayr 889
        lea     edi, [ebx + device.init_block.phys_addr]
3545 hidnplayr 890
        movsd
891
        movsw
892
 
893
        call    init_ring
5522 hidnplayr 894
        test    eax, eax
895
        jnz     .fail
3545 hidnplayr 896
 
8897 hidnplayr 897
        mov     edx, [ebx + device.io_addr]     ; init ring destroys edx
3545 hidnplayr 898
 
8897 hidnplayr 899
        lea     eax, [ebx + device.init_block]
4532 hidnplayr 900
        invoke  GetPhysAddr
3545 hidnplayr 901
        push    eax
902
        and     eax, 0xffff
8897 hidnplayr 903
        mov     ecx, CSR_IAB0
4532 hidnplayr 904
        call    [ebx + device.write_csr]
3545 hidnplayr 905
        pop     eax
906
        shr     eax, 16
8897 hidnplayr 907
        mov     ecx, CSR_IAB1
4532 hidnplayr 908
        call    [ebx + device.write_csr]
3545 hidnplayr 909
 
8897 hidnplayr 910
        mov     ecx, CSR_TFEAT
911
        mov     eax, 0x0915                     ; Auto TX PAD ?
4532 hidnplayr 912
        call    [ebx + device.write_csr]
3545 hidnplayr 913
 
914
; Set the interrupt mask
915
        mov     ecx, CSR_IMR
916
        mov     eax, IMR
4532 hidnplayr 917
        call    [ebx + device.write_csr]
3545 hidnplayr 918
 
919
; Initialise the device
920
        xor     ecx, ecx
921
        mov     eax, CSR_INIT
4532 hidnplayr 922
        call    [ebx + device.write_csr]
3545 hidnplayr 923
 
924
        mov     esi, 100
925
;        xor     ecx, ecx
926
  @@:
4532 hidnplayr 927
        call    [ebx + device.read_csr]
3545 hidnplayr 928
        test    ax, CSR_IDONE
929
        jnz     @f
930
 
931
        dec     esi
932
        jnz     @r
3855 hidnplayr 933
        DEBUGF  2,"Initialize timeout!\n"
3545 hidnplayr 934
  @@:
935
 
936
; Start the device and enable interrupts
937
        xor     ecx, ecx
938
        mov     eax, CSR_START + CSR_INTEN
4532 hidnplayr 939
        call    [ebx + device.write_csr]
3545 hidnplayr 940
 
8910 hidnplayr 941
; Set the MTU
4532 hidnplayr 942
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 943
 
4580 hidnplayr 944
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
8910 hidnplayr 945
; Start media check timer
946
        cmp     [ebx + device.mii], 0
947
        je      @f
948
        mov     [ebx + device.state], ETH_LINK_DOWN
949
        invoke  TimerHS, 0, 50, check_media_mii, ebx
950
        mov     [ebx + device.link_timer], eax
951
  @@:
3545 hidnplayr 952
 
3855 hidnplayr 953
        DEBUGF  1,"reset complete\n"
3545 hidnplayr 954
        xor     eax, eax
5522 hidnplayr 955
  .fail:
3545 hidnplayr 956
        ret
957
 
958
 
959
align 4
960
init_ring:
961
 
3855 hidnplayr 962
        DEBUGF  1,"init ring\n"
3545 hidnplayr 963
 
4532 hidnplayr 964
        lea     edi, [ebx + device.rx_ring]
3545 hidnplayr 965
        mov     eax, edi
4532 hidnplayr 966
        invoke  GetPhysAddr
8897 hidnplayr 967
        mov     [ebx + device.init_block.rx_ring_phys], eax
3545 hidnplayr 968
        mov     ecx, RX_RING_SIZE
969
  .rx_init:
970
        push    ecx
5522 hidnplayr 971
        invoke  NetAlloc, PKT_BUF_SZ+NET_BUFF.data
3545 hidnplayr 972
        pop     ecx
5522 hidnplayr 973
        test    eax, eax
974
        jz      .out_of_mem
3545 hidnplayr 975
        mov     [edi + descriptor.virtual], eax
4532 hidnplayr 976
        invoke  GetPhysAddr
5522 hidnplayr 977
        add     eax, NET_BUFF.data
3545 hidnplayr 978
        mov     [edi + descriptor.base], eax
979
        mov     [edi + descriptor.length], - PKT_BUF_SZ
8897 hidnplayr 980
        mov     dword[edi + descriptor.msg_length], 0    ; also clears misc field
3545 hidnplayr 981
        mov     [edi + descriptor.status], RXSTAT_OWN
4532 hidnplayr 982
        add     edi, sizeof.descriptor
3545 hidnplayr 983
        dec     ecx
984
        jnz     .rx_init
985
 
4532 hidnplayr 986
        lea     edi, [ebx + device.tx_ring]
3545 hidnplayr 987
        mov     eax, edi
4532 hidnplayr 988
        invoke  GetPhysAddr
8897 hidnplayr 989
        mov     [ebx + device.init_block.tx_ring_phys], eax
3545 hidnplayr 990
        mov     ecx, TX_RING_SIZE
991
  .tx_init:
992
        mov     [edi + descriptor.status], 0
4532 hidnplayr 993
        add     edi, sizeof.descriptor
3545 hidnplayr 994
        dec     ecx
995
        jnz     .tx_init
996
 
8897 hidnplayr 997
        mov     [ebx + device.init_block.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
3545 hidnplayr 998
 
4532 hidnplayr 999
        mov     [ebx + device.cur_tx], 0
1000
        mov     [ebx + device.last_tx], 0
1001
        mov     [ebx + device.cur_rx], 0
3545 hidnplayr 1002
 
5522 hidnplayr 1003
        xor     eax, eax
3545 hidnplayr 1004
        ret
1005
 
5522 hidnplayr 1006
  .out_of_mem:
1007
        DEBUGF  2,"Out of memory!\n"
3545 hidnplayr 1008
 
5522 hidnplayr 1009
        or      eax, -1
1010
        ret
3545 hidnplayr 1011
 
1012
 
5522 hidnplayr 1013
 
1014
 
3545 hidnplayr 1015
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1016
;;                                         ;;
1017
;; Transmit                                ;;
1018
;;                                         ;;
4532 hidnplayr 1019
;; In: pointer to device structure in ebx  ;;
3545 hidnplayr 1020
;;                                         ;;
1021
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1022
 
5522 hidnplayr 1023
proc transmit stdcall bufferptr
4532 hidnplayr 1024
 
8910 hidnplayr 1025
        spin_lock_irqsave
4532 hidnplayr 1026
 
5522 hidnplayr 1027
        mov     esi, [bufferptr]
1028
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
1029
        lea     eax, [esi + NET_BUFF.data]
3545 hidnplayr 1030
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1031
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1032
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1033
        [eax+13]:2,[eax+12]:2
1034
 
5522 hidnplayr 1035
        cmp     [esi + NET_BUFF.length], 1514
8898 hidnplayr 1036
        ja      .error
5522 hidnplayr 1037
        cmp     [esi + NET_BUFF.length], 60
8898 hidnplayr 1038
        jb      .error
3545 hidnplayr 1039
 
1040
; check descriptor
4532 hidnplayr 1041
        lea     edi, [ebx + device.tx_ring]
8897 hidnplayr 1042
        mov     ecx, [ebx + device.cur_tx]
5522 hidnplayr 1043
        shl     ecx, 4
1044
        add     edi, ecx
3545 hidnplayr 1045
 
1046
        test    [edi + descriptor.status], TXCTL_OWN
8898 hidnplayr 1047
        jnz     .overrun
3545 hidnplayr 1048
; descriptor is free, use it
5522 hidnplayr 1049
        mov     [edi + descriptor.virtual], esi
1050
        mov     eax, esi
1051
        add     eax, [eax + NET_BUFF.offset]
4532 hidnplayr 1052
        invoke  GetPhysAddr
3545 hidnplayr 1053
        mov     [edi + descriptor.base], eax
1054
; set length
5522 hidnplayr 1055
        mov     eax, [esi + NET_BUFF.length]
3545 hidnplayr 1056
        neg     eax
1057
        mov     [edi + descriptor.length], ax
1058
; put to transfer queue
1059
        mov     [edi + descriptor.status], TXCTL_OWN + TXCTL_STP + TXCTL_ENP
1060
 
1061
; trigger an immediate send
4532 hidnplayr 1062
        mov     edx, [ebx + device.io_addr]
3545 hidnplayr 1063
        xor     ecx, ecx                        ; CSR0
4532 hidnplayr 1064
        call    [ebx + device.read_csr]
3545 hidnplayr 1065
        or      eax, CSR_TX
4532 hidnplayr 1066
        call    [ebx + device.write_csr]
3545 hidnplayr 1067
 
8897 hidnplayr 1068
; get next descriptor
4532 hidnplayr 1069
        inc     [ebx + device.cur_tx]
1070
        and     [ebx + device.cur_tx], TX_RING_SIZE - 1
3545 hidnplayr 1071
 
1072
; Update stats
4532 hidnplayr 1073
        inc     [ebx + device.packets_tx]
5522 hidnplayr 1074
        mov     eax, [esi + NET_BUFF.length]
4532 hidnplayr 1075
        add     dword[ebx + device.bytes_tx], eax
1076
        adc     dword[ebx + device.bytes_tx + 4], 0
3545 hidnplayr 1077
 
8910 hidnplayr 1078
        spin_unlock_irqrestore
3545 hidnplayr 1079
        xor     eax, eax
4532 hidnplayr 1080
        ret
3545 hidnplayr 1081
 
8898 hidnplayr 1082
  .error:
1083
        DEBUGF  2, "TX packet error\n"
1084
        inc     [ebx + device.packets_tx_err]
5522 hidnplayr 1085
        invoke  NetFree, [bufferptr]
8898 hidnplayr 1086
 
8910 hidnplayr 1087
        spin_unlock_irqrestore
3545 hidnplayr 1088
        or      eax, -1
4532 hidnplayr 1089
        ret
3545 hidnplayr 1090
 
8898 hidnplayr 1091
  .overrun:
1092
        DEBUGF  2, "TX overrun\n"
1093
        inc     [ebx + device.packets_tx_ovr]
1094
        invoke  NetFree, [bufferptr]
1095
 
8910 hidnplayr 1096
        spin_unlock_irqrestore
8898 hidnplayr 1097
        or      eax, -1
1098
        ret
1099
 
4532 hidnplayr 1100
endp
3545 hidnplayr 1101
 
1102
 
1103
;;;;;;;;;;;;;;;;;;;;;;;
1104
;;                   ;;
1105
;; Interrupt handler ;;
1106
;;                   ;;
1107
;;;;;;;;;;;;;;;;;;;;;;;
1108
 
1109
align 4
1110
int_handler:
1111
 
1112
        push    ebx esi edi
1113
 
3855 hidnplayr 1114
        DEBUGF  1,"INT\n"
3545 hidnplayr 1115
 
1116
; find pointer of device wich made IRQ occur
1117
 
1118
        mov     ecx, [devices]
1119
        test    ecx, ecx
1120
        jz      .nothing
1121
        mov     esi, device_list
1122
  .nextdevice:
1123
        mov     ebx, [esi]
4532 hidnplayr 1124
        mov     edx, [ebx + device.io_addr]
3545 hidnplayr 1125
        push    ecx
1126
        xor     ecx, ecx                        ; CSR0
4532 hidnplayr 1127
        call    [ebx + device.read_csr]         ; get IRQ reason
1128
        call    [ebx + device.write_csr]        ; write it back to ACK
3545 hidnplayr 1129
        pop     ecx
5617 hidnplayr 1130
        test    ax, CSR_RINT or CSR_TINT
3545 hidnplayr 1131
        jnz     .got_it
1132
  .continue:
1133
        add     esi, 4
1134
        dec     ecx
1135
        jnz     .nextdevice
1136
  .nothing:
1137
        pop     edi esi ebx
1138
        xor     eax, eax
1139
 
1140
        ret
1141
 
1142
  .got_it:
5065 hidnplayr 1143
        DEBUGF  1,"Device: %x status: %x\n", ebx, eax:4
3545 hidnplayr 1144
 
1145
        push    ax
1146
        test    ax, CSR_RINT
1147
        jz      .not_receive
1148
 
1149
        push    ebx
1150
  .rx_loop:
1151
        pop     ebx
8898 hidnplayr 1152
        push    ebx
8897 hidnplayr 1153
        mov     eax, [ebx + device.cur_rx]
3545 hidnplayr 1154
        shl     eax, 4
4532 hidnplayr 1155
        lea     edi, [ebx + device.rx_ring]
3545 hidnplayr 1156
        add     edi, eax                        ; edi now points to current rx ring entry
1157
 
1158
        mov     ax, [edi + descriptor.status]
1159
        DEBUGF  1,"RX packet status: %x\n", eax:4
1160
 
1161
        test    ax, RXSTAT_OWN                  ; If this bit is set, the controller OWN's the packet, if not, we do
8898 hidnplayr 1162
        jnz     .rx_done
1163
; Both Start of packet and End of packet bits should be set, we dont support multi frame packets
3545 hidnplayr 1164
        test    ax, RXSTAT_ENP
8898 hidnplayr 1165
        jz      .rx_drop
3545 hidnplayr 1166
        test    ax, RXSTAT_STP
8898 hidnplayr 1167
        jz      .rx_drop
3545 hidnplayr 1168
 
1169
        movzx   ecx, [edi + descriptor.msg_length]      ; get packet length in ecx
4532 hidnplayr 1170
        sub     ecx, 4                                  ; We dont need the CRC
1171
        DEBUGF  1,"Got %u bytes\n", ecx
3545 hidnplayr 1172
 
1173
; Set pointers for ETH_input
1174
        push    .rx_loop                                ; return address
5522 hidnplayr 1175
        mov     eax, [edi + descriptor.virtual]
1176
        push    eax                                     ; packet address
1177
        mov     [eax + NET_BUFF.length], ecx
1178
        mov     [eax + NET_BUFF.device], ebx
1179
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
3545 hidnplayr 1180
 
1181
; Update stats
4532 hidnplayr 1182
        add     dword[ebx + device.bytes_rx], ecx
1183
        adc     dword[ebx + device.bytes_rx + 4], 0
1184
        inc     [ebx + device.packets_rx]
3545 hidnplayr 1185
 
1186
; now allocate a new buffer
5522 hidnplayr 1187
        invoke  NetAlloc, PKT_BUF_SZ+NET_BUFF.data      ; Allocate a buffer for the next packet
1188
        test    eax, eax
8898 hidnplayr 1189
        jz      .rx_overrun
3545 hidnplayr 1190
        mov     [edi + descriptor.virtual], eax         ; set virtual address
4532 hidnplayr 1191
        invoke  GetPhysAddr
5522 hidnplayr 1192
        add     eax, NET_BUFF.data
4532 hidnplayr 1193
        mov     [edi + descriptor.base], eax            ; and physical address
3545 hidnplayr 1194
        mov     [edi + descriptor.status], RXSTAT_OWN   ; give it back to PCnet controller
1195
 
4532 hidnplayr 1196
        inc     [ebx + device.cur_rx]                   ; set next receive descriptor
1197
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
3545 hidnplayr 1198
 
5522 hidnplayr 1199
        jmp     [EthInput]
3545 hidnplayr 1200
 
8898 hidnplayr 1201
  .rx_overrun:
1202
        add     esp, 4+4
1203
        DEBUGF  2,"RX FIFO overrun\n"
1204
        inc     [ebx + device.packets_rx_ovr]
1205
        jmp     .rx_next
5522 hidnplayr 1206
 
8898 hidnplayr 1207
  .rx_drop:
1208
        DEBUGF  2,"Dropping incoming packet\n"
1209
        inc     [ebx + device.packets_rx_drop]
1210
 
1211
  .rx_next:
1212
        mov     [edi + descriptor.status], RXSTAT_OWN   ; give it back to PCnet controller
1213
 
5522 hidnplayr 1214
        inc     [ebx + device.cur_rx]                   ; set next receive descriptor
1215
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
8898 hidnplayr 1216
        jmp     .rx_loop
5522 hidnplayr 1217
 
8898 hidnplayr 1218
  .rx_done:
1219
        pop     ebx
5522 hidnplayr 1220
 
3545 hidnplayr 1221
  .not_receive:
1222
        pop     ax
1223
 
1224
        test    ax, CSR_TINT
1225
        jz      .not_transmit
1226
 
1227
  .tx_loop:
4532 hidnplayr 1228
        lea     edi, [ebx + device.tx_ring]
8897 hidnplayr 1229
        mov     eax, [ebx + device.last_tx]
3545 hidnplayr 1230
        shl     eax, 4
1231
        add     edi, eax
1232
 
1233
        test    [edi + descriptor.status], TXCTL_OWN
1234
        jnz     .not_transmit
1235
 
1236
        mov     eax, [edi + descriptor.virtual]
1237
        test    eax, eax
1238
        jz      .not_transmit
1239
 
1240
        mov     [edi + descriptor.virtual], 0
1241
 
1242
        DEBUGF  1,"Removing packet %x from memory\n", eax
1243
 
5522 hidnplayr 1244
        invoke  NetFree, eax
3545 hidnplayr 1245
 
4532 hidnplayr 1246
        inc     [ebx + device.last_tx]
1247
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
3545 hidnplayr 1248
        jmp     .tx_loop
1249
 
1250
  .not_transmit:
1251
        pop     edi esi ebx
1252
        xor     eax, eax
1253
        inc     eax
1254
 
1255
        ret
1256
 
1257
 
1258
 
1259
 
1260
;;;;;;;;;;;;;;;;;;;;;;;
1261
;;                   ;;
1262
;; Write MAC address ;;
1263
;;                   ;;
1264
;;;;;;;;;;;;;;;;;;;;;;;
1265
 
1266
align 4
1267
write_mac:      ; in: mac pushed onto stack (as 3 words)
1268
 
4532 hidnplayr 1269
        DEBUGF  1,"Writing MAC: %x-%x-%x-%x-%x-%x\n",\
1270
        [esp+0]:2,[esp+1]:2,[esp+2]:2,[esp+3]:2,[esp+4]:2,[esp+5]:2
3545 hidnplayr 1271
 
4532 hidnplayr 1272
        mov     edx, [ebx + device.io_addr]
3545 hidnplayr 1273
        add     dx, 2
1274
        xor     eax, eax
1275
 
1276
        mov     ecx, CSR_PAR0
1277
       @@:
1278
        pop     ax
4532 hidnplayr 1279
        call    [ebx + device.write_csr]
3545 hidnplayr 1280
        inc     ecx
1281
        cmp     ecx, CSR_PAR2
1282
        jb      @r
1283
 
1284
; Notice this procedure does not ret, but continues to read_mac instead.
1285
 
1286
;;;;;;;;;;;;;;;;;;;;;;
1287
;;                  ;;
1288
;; Read MAC address ;;
1289
;;                  ;;
1290
;;;;;;;;;;;;;;;;;;;;;;
1291
align 4
1292
read_mac:
4532 hidnplayr 1293
        DEBUGF  1,"Reading MAC\n"
3545 hidnplayr 1294
 
4532 hidnplayr 1295
        mov     edx, [ebx + device.io_addr]
1296
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1297
        in      ax, dx
4532 hidnplayr 1298
        stosw
3545 hidnplayr 1299
 
4532 hidnplayr 1300
        inc     dx
1301
        inc     dx
1302
        in      ax, dx
1303
        stosw
3545 hidnplayr 1304
 
4532 hidnplayr 1305
        inc     dx
1306
        inc     dx
1307
        in      ax, dx
3545 hidnplayr 1308
        stosw
1309
 
4532 hidnplayr 1310
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1311
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,\
1312
        [ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
1313
 
3545 hidnplayr 1314
        ret
1315
 
1316
align 4
1317
switch_to_wio:
1318
 
1319
        DEBUGF  1,"Switching to 16-bit mode\n"
1320
 
4532 hidnplayr 1321
        mov     [ebx + device.read_csr], wio_read_csr
1322
        mov     [ebx + device.write_csr], wio_write_csr
1323
        mov     [ebx + device.read_bcr], wio_read_bcr
1324
        mov     [ebx + device.write_bcr], wio_write_bcr
1325
        mov     [ebx + device.read_rap], wio_read_rap
1326
        mov     [ebx + device.write_rap], wio_write_rap
1327
        mov     [ebx + device.sw_reset], wio_reset
3545 hidnplayr 1328
 
1329
        ret
1330
 
1331
align 4
1332
switch_to_dwio:
1333
 
1334
        DEBUGF  1,"Switching to 32-bit mode\n"
1335
 
4532 hidnplayr 1336
        mov     [ebx + device.read_csr], dwio_read_csr
1337
        mov     [ebx + device.write_csr], dwio_write_csr
1338
        mov     [ebx + device.read_bcr], dwio_read_bcr
1339
        mov     [ebx + device.write_bcr], dwio_write_bcr
1340
        mov     [ebx + device.read_rap], dwio_read_rap
1341
        mov     [ebx + device.write_rap], dwio_write_rap
1342
        mov     [ebx + device.sw_reset], dwio_reset
3545 hidnplayr 1343
 
1344
        ret
1345
 
1346
 
1347
; ecx - index
1348
; return:
1349
; eax - data
1350
align 4
1351
wio_read_csr:
1352
 
1353
        add     edx, WIO_RAP
1354
        mov     ax, cx
1355
        out     dx, ax
1356
        add     edx, WIO_RDP - WIO_RAP
1357
        in      ax, dx
1358
        and     eax, 0xffff
1359
        sub     edx, WIO_RDP
1360
 
1361
        ret
1362
 
1363
 
1364
; eax - data
1365
; ecx - index
1366
align 4
1367
wio_write_csr:
1368
 
1369
        add     edx, WIO_RAP
1370
        xchg    eax, ecx
1371
        out     dx, ax
1372
        xchg    eax, ecx
1373
        add     edx, WIO_RDP - WIO_RAP
1374
        out     dx, ax
1375
        sub     edx, WIO_RDP
1376
 
1377
        ret
1378
 
1379
 
1380
; ecx - index
1381
; return:
1382
; eax - data
1383
align 4
1384
wio_read_bcr:
1385
 
1386
        add     edx, WIO_RAP
1387
        mov     ax, cx
1388
        out     dx, ax
1389
        add     edx, WIO_BDP - WIO_RAP
1390
        in      ax, dx
1391
        and     eax, 0xffff
1392
        sub     edx, WIO_BDP
1393
 
1394
        ret
1395
 
1396
 
1397
; eax - data
1398
; ecx - index
1399
align 4
1400
wio_write_bcr:
1401
 
1402
        add     edx, WIO_RAP
1403
        xchg    eax, ecx
1404
        out     dx, ax
1405
        xchg    eax, ecx
1406
        add     edx, WIO_BDP - WIO_RAP
1407
        out     dx, ax
1408
        sub     edx, WIO_BDP
1409
 
1410
        ret
1411
 
1412
align 4
1413
wio_read_rap:
1414
 
1415
        add     edx, WIO_RAP
1416
        in      ax, dx
1417
        and     eax, 0xffff
1418
        sub     edx, WIO_RAP
1419
 
1420
        ret
1421
 
1422
; eax - val
1423
align 4
1424
wio_write_rap:
1425
 
1426
        add     edx, WIO_RAP
1427
        out     dx, ax
1428
        sub     edx, WIO_RAP
1429
 
1430
        ret
1431
 
1432
align 4
1433
wio_reset:
1434
 
1435
        push    eax
1436
        add     edx, WIO_RESET
1437
        in      ax, dx
1438
        pop     eax
1439
        sub     edx, WIO_RESET
1440
 
1441
        ret
1442
 
1443
 
1444
 
1445
; ecx - index
1446
; return:
1447
; eax - data
1448
align 4
1449
dwio_read_csr:
1450
 
1451
        add     edx, DWIO_RAP
1452
        mov     eax, ecx
1453
        out     dx, eax
1454
        add     edx, DWIO_RDP - DWIO_RAP
1455
        in      eax, dx
1456
        and     eax, 0xffff
1457
        sub     edx, DWIO_RDP
1458
 
1459
        ret
1460
 
1461
 
1462
; ecx - index
1463
; eax - data
1464
align 4
1465
dwio_write_csr:
1466
 
1467
        add     edx, DWIO_RAP
1468
        xchg    eax, ecx
1469
        out     dx, eax
1470
        add     edx, DWIO_RDP - DWIO_RAP
1471
        xchg    eax, ecx
1472
        out     dx, eax
1473
        sub     edx, DWIO_RDP
1474
 
1475
        ret
1476
 
1477
; ecx - index
1478
; return:
1479
; eax - data
1480
align 4
1481
dwio_read_bcr:
1482
 
1483
        add     edx, DWIO_RAP
1484
        mov     eax, ecx
1485
        out     dx, eax
1486
        add     edx, DWIO_BDP - DWIO_RAP
1487
        in      eax, dx
1488
        and     eax, 0xffff
1489
        sub     edx, DWIO_BDP
1490
 
1491
        ret
1492
 
1493
 
1494
; ecx - index
1495
; eax - data
1496
align 4
1497
dwio_write_bcr:
1498
 
1499
        add     edx, DWIO_RAP
1500
        xchg    eax, ecx
1501
        out     dx, eax
1502
        add     edx, DWIO_BDP - DWIO_RAP
1503
        xchg    eax, ecx
1504
        out     dx, eax
1505
        sub     edx, DWIO_BDP
1506
 
1507
        ret
1508
 
1509
align 4
1510
dwio_read_rap:
1511
 
1512
        add     edx, DWIO_RAP
1513
        in      eax, dx
1514
        and     eax, 0xffff
1515
        sub     edx, DWIO_RAP
1516
 
1517
        ret
1518
 
1519
 
1520
; eax - val
1521
align 4
1522
dwio_write_rap:
1523
 
1524
        add     edx, DWIO_RAP
1525
        out     dx, eax
1526
        sub     edx, DWIO_RAP
1527
 
1528
        ret
1529
 
1530
align 4
1531
dwio_reset:
1532
 
1533
        push    eax
1534
        add     edx, DWIO_RESET
1535
        in      eax, dx
1536
        pop     eax
1537
        sub     edx, DWIO_RESET
1538
 
1539
        ret
1540
 
1541
 
1542
align 4
1543
mdio_read:
1544
 
1545
        and     ecx, 0x1f
4532 hidnplayr 1546
        mov     ax, [ebx + device.phy]
3545 hidnplayr 1547
        and     ax, 0x1f
1548
        shl     ax, 5
1549
        or      ax, cx
1550
 
1551
        mov     ecx, BCR_MIIADDR
4532 hidnplayr 1552
        call    [ebx + device.write_bcr]
3545 hidnplayr 1553
 
1554
        mov     ecx, BCR_MIIDATA
4532 hidnplayr 1555
        call    [ebx + device.read_bcr]
3545 hidnplayr 1556
 
1557
        ret
1558
 
1559
 
1560
align 4
1561
mdio_write:
1562
 
1563
        push    eax
1564
        and     ecx, 0x1f
4532 hidnplayr 1565
        mov     ax, [ebx + device.phy]
3545 hidnplayr 1566
        and     ax, 0x1f
1567
        shl     ax, 5
1568
        or      ax, cx
1569
 
1570
        mov     ecx, BCR_MIIADDR
4532 hidnplayr 1571
        call    [ebx + device.write_bcr]
3545 hidnplayr 1572
 
1573
        pop     eax
1574
        mov     ecx, BCR_MIIDATA
4532 hidnplayr 1575
        call    [ebx + device.write_bcr]
3545 hidnplayr 1576
 
1577
        ret
1578
 
1579
 
1580
 
1581
 
8910 hidnplayr 1582
proc check_media_mii stdcall dev:dword
3545 hidnplayr 1583
 
8910 hidnplayr 1584
        spin_lock_irqsave
3545 hidnplayr 1585
 
8910 hidnplayr 1586
        mov     ebx, [dev]
1587
        mov     edx, [ebx + device.io_addr]
3545 hidnplayr 1588
 
8910 hidnplayr 1589
        mov     ecx, MII_BMSR
1590
        call    mdio_read
1591
 
1592
        mov     ecx, MII_BMSR
1593
        call    mdio_read
1594
 
1595
        mov     ecx, eax
1596
        and     eax, BMSR_LSTATUS
1597
        shr     eax, 2
1598
        cmp     eax, [ebx + device.state]
1599
        jne     .changed
1600
 
1601
        spin_unlock_irqrestore
3545 hidnplayr 1602
        ret
1603
 
8910 hidnplayr 1604
  .changed:
1605
        test    eax, eax
1606
        jz      .update
3545 hidnplayr 1607
 
8910 hidnplayr 1608
        test    ecx, BMSR_ANEGCOMPLETE
1609
        jz      .update
3545 hidnplayr 1610
 
8910 hidnplayr 1611
        mov     ecx, MII_ADVERTISE
1612
        call    mdio_read
1613
        mov     esi, eax
1614
 
1615
        mov     ecx, MII_LPA
1616
        call    mdio_read
1617
        and     eax, esi
1618
 
1619
        test    eax, LPA_100FULL
1620
        jz      @f
9149 hidnplayr 1621
        mov     eax, ETH_LINK_SPEED_100M or ETH_LINK_FULL_DUPLEX
8910 hidnplayr 1622
        jmp     .update
1623
  @@:
1624
 
1625
        test    eax, LPA_100HALF
1626
        jz      @f
9149 hidnplayr 1627
        mov     eax, ETH_LINK_SPEED_100M
8910 hidnplayr 1628
        jmp     .update
1629
  @@:
1630
 
1631
        test    eax, LPA_10FULL
1632
        jz      @f
9149 hidnplayr 1633
        mov     eax, ETH_LINK_SPEED_10M or ETH_LINK_FULL_DUPLEX
8910 hidnplayr 1634
        jmp     .update
1635
  @@:
1636
 
1637
        test    eax, LPA_10HALF
1638
        jz      @f
9149 hidnplayr 1639
        mov     eax, ETH_LINK_SPEED_10M
8910 hidnplayr 1640
        jmp     .update
1641
  @@:
1642
 
1643
        mov     eax, ETH_LINK_UNKNOWN
1644
 
1645
  .update:
1646
        mov     [ebx + device.state], eax
1647
        invoke  NetLinkChanged
1648
 
1649
 
1650
        spin_unlock_irqrestore
1651
        ret
1652
 
1653
 
1654
endp
1655
 
1656
 
3545 hidnplayr 1657
; End of code
1658
 
1659
 
4532 hidnplayr 1660
data fixups
1661
end data
3545 hidnplayr 1662
 
4532 hidnplayr 1663
include '../peimport.inc'
1664
 
4629 hidnplayr 1665
my_service    db 'PCNET32',0            ; max 16 chars include zero
4532 hidnplayr 1666
 
3545 hidnplayr 1667
device_l2     db "PCnet/PCI 79C970",0
1668
device_l4     db "PCnet/PCI II 79C970A",0
1669
device_l5     db "PCnet/FAST 79C971",0
1670
device_l6     db "PCnet/FAST+ 79C972",0
1671
device_l7     db "PCnet/FAST III 79C973",0
1672
device_l8     db "PCnet/Home 79C978",0
1673
device_l9     db "PCnet/FAST III 79C975",0
1674
 
1675
options_mapping:
1676
dd PORT_ASEL                            ; 0 Auto-select
1677
dd PORT_AUI                             ; 1 BNC/AUI
1678
dd PORT_AUI                             ; 2 AUI/BNC
1679
dd PORT_ASEL                            ; 3 not supported
1680
dd PORT_10BT or PORT_FD                 ; 4 10baseT-FD
1681
dd PORT_ASEL                            ; 5 not supported
1682
dd PORT_ASEL                            ; 6 not supported
1683
dd PORT_ASEL                            ; 7 not supported
1684
dd PORT_ASEL                            ; 8 not supported
1685
dd PORT_MII                             ; 9 MII 10baseT
1686
dd PORT_MII or PORT_FD                  ; 10 MII 10baseT-FD
1687
dd PORT_MII                             ; 11 MII (autosel)
1688
dd PORT_10BT                            ; 12 10BaseT
1689
dd PORT_MII or PORT_100                 ; 13 MII 100BaseTx
1690
dd PORT_MII or PORT_100 or PORT_FD      ; 14 MII 100BaseTx-FD
1691
dd PORT_ASEL                            ; 15 not supported
1692
 
1693
include_debug_strings                                   ; All data wich FDO uses will be included here
1694
 
1695
 
4532 hidnplayr 1696
align 4
1697
devices     dd 0
3545 hidnplayr 1698
device_list rd MAX_DEVICES                              ; This list contains all pointers to device structures the driver is handling