Subversion Repositories Kolibri OS

Rev

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

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