Subversion Repositories Kolibri OS

Rev

Rev 3350 | 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
 
3350 hidnplayr 280
;
1196 hidnplayr 281
 
3350 hidnplayr 282
        MAX_PHYS                = 32
283
 
284
 
3198 hidnplayr 285
virtual at ebx
1196 hidnplayr 286
 
3198 hidnplayr 287
        device:
1196 hidnplayr 288
 
3198 hidnplayr 289
        ETH_DEVICE
1196 hidnplayr 290
 
3198 hidnplayr 291
; device specific
1196 hidnplayr 292
 
3198 hidnplayr 293
                        rb 0x100-(($ - device) and 0xff)        ;        align 256
294
        .private:
295
        .mode_          dw ?
296
        .tlen_rlen      dw ?
297
        .phys_addr      dp ?
298
        .reserved       dw ?
299
        .filter         dq ?
300
        .rx_ring_phys   dd ?
301
        .tx_ring_phys   dd ?
1196 hidnplayr 302
 
3198 hidnplayr 303
                        rb 0x100-(($ - device) and 0xff)        ;        align 256
304
        .rx_ring        rb RX_RING_SIZE * descriptor.size
1196 hidnplayr 305
 
3198 hidnplayr 306
                        rb 0x100-(($ - device) and 0xff)        ;        align 256
307
        .tx_ring        rb TX_RING_SIZE * descriptor.size
1196 hidnplayr 308
 
3198 hidnplayr 309
        .cur_rx         db ?
310
        .cur_tx         db ?
311
        .last_tx        db ?
312
        .options        dd ?
313
        .full_duplex    db ?
314
        .chip_version   dw ?
315
        .mii            db ?
316
        .ltint          db ?
317
        .dxsuflo        db ?
318
        .fset           db ?
319
        .fdx            db ?
1196 hidnplayr 320
 
3198 hidnplayr 321
        .io_addr        dd ?
322
        .irq_line       db ?
3205 hidnplayr 323
        .pci_bus        dd ?
324
        .pci_dev        dd ?
1196 hidnplayr 325
 
3350 hidnplayr 326
        .phy            dw ?
327
 
3198 hidnplayr 328
        .read_csr       dd ?
329
        .write_csr      dd ?
330
        .read_bcr       dd ?
331
        .write_bcr      dd ?
332
        .read_rap       dd ?
333
        .write_rap      dd ?
334
        .sw_reset       dd ?
1196 hidnplayr 335
 
3198 hidnplayr 336
        device_size     = $ - device
1196 hidnplayr 337
 
3198 hidnplayr 338
end virtual
1196 hidnplayr 339
 
3198 hidnplayr 340
struc   descriptor {
341
        .base           dd ?
342
        .length         dw ?
343
        .status         dw ?
344
        .msg_length     dw ?
345
        .misc           dw ?
346
        .virtual        dd ?
1196 hidnplayr 347
 
3198 hidnplayr 348
        .size:
349
}
1196 hidnplayr 350
 
3198 hidnplayr 351
virtual at 0
352
 descriptor descriptor
353
end virtual
1564 hidnplayr 354
 
3198 hidnplayr 355
 
356
 
357
 
1196 hidnplayr 358
section '.flat' code readable align 16
359
 
360
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
361
;;                        ;;
362
;; proc START             ;;
363
;;                        ;;
364
;; (standard driver proc) ;;
365
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
366
 
367
proc START stdcall, state:dword
368
 
2387 hidnplayr 369
        cmp [state], 1
370
        jne .exit
1196 hidnplayr 371
 
372
  .entry:
373
 
3155 hidnplayr 374
        DEBUGF 1,"Loading %s driver\n", my_service
2387 hidnplayr 375
        stdcall RegService, my_service, service_proc
376
        ret
1196 hidnplayr 377
 
378
  .fail:
379
  .exit:
2387 hidnplayr 380
        xor eax, eax
381
        ret
1196 hidnplayr 382
 
383
endp
384
 
385
 
386
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
387
;;                        ;;
388
;; proc SERVICE_PROC      ;;
389
;;                        ;;
390
;; (standard driver proc) ;;
391
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
392
 
393
align 4
394
proc service_proc stdcall, ioctl:dword
395
 
2387 hidnplayr 396
        mov     edx, [ioctl]
397
        mov     eax, [IOCTL.io_code]
1196 hidnplayr 398
 
399
;------------------------------------------------------
400
 
2387 hidnplayr 401
        cmp     eax, 0 ;SRV_GETVERSION
402
        jne     @F
1196 hidnplayr 403
 
2387 hidnplayr 404
        cmp     [IOCTL.out_size], 4
3155 hidnplayr 405
        jb      .fail
2387 hidnplayr 406
        mov     eax, [IOCTL.output]
407
        mov     [eax], dword API_VERSION
1196 hidnplayr 408
 
2387 hidnplayr 409
        xor     eax, eax
410
        ret
1196 hidnplayr 411
 
412
;------------------------------------------------------
413
  @@:
2387 hidnplayr 414
        cmp     eax, 1 ;SRV_HOOK
415
        jne     .fail
1196 hidnplayr 416
 
3198 hidnplayr 417
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
3155 hidnplayr 418
        jb      .fail
1196 hidnplayr 419
 
2387 hidnplayr 420
        mov     eax, [IOCTL.input]
421
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
422
        jne     .fail                                   ; other types arent supported for this card yet
1196 hidnplayr 423
 
424
; check if the device is already listed
425
 
2387 hidnplayr 426
        mov     ecx, [devices]
427
        test    ecx, ecx
428
        jz      .firstdevice
1492 hidnplayr 429
 
2387 hidnplayr 430
        mov     esi, device_list
1492 hidnplayr 431
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
2387 hidnplayr 432
        mov     ax , [eax+1]                            ;
1196 hidnplayr 433
  .nextdevice:
2387 hidnplayr 434
        mov     ebx, [esi]
3205 hidnplayr 435
        cmp     al, byte[device.pci_bus]
436
        jne     @f
437
        cmp     ah, byte[device.pci_dev]
2387 hidnplayr 438
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
3205 hidnplayr 439
       @@:
2387 hidnplayr 440
        add     esi, 4
441
        loop    .nextdevice
1196 hidnplayr 442
 
443
; This device doesnt have its own eth_device structure yet, lets create one
444
 
445
  .firstdevice:
2387 hidnplayr 446
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
3155 hidnplayr 447
        jae     .fail
1196 hidnplayr 448
 
2387 hidnplayr 449
        allocate_and_clear ebx, device_size, .fail
1196 hidnplayr 450
 
451
; Fill in the direct call addresses into the struct
452
 
2387 hidnplayr 453
        mov     [device.reset], reset
454
        mov     [device.transmit], transmit
455
        mov     [device.unload], unload
456
        mov     [device.name], my_service
1196 hidnplayr 457
 
458
; save the pci bus and device numbers
459
 
2387 hidnplayr 460
        mov     eax, [IOCTL.input]
3205 hidnplayr 461
        movzx   ecx, byte[eax+1]
462
        mov     [device.pci_bus], ecx
463
        movzx   ecx, byte[eax+2]
464
        mov     [device.pci_dev], ecx
1196 hidnplayr 465
 
466
; Now, it's time to find the base io addres of the PCI device
467
 
3205 hidnplayr 468
        PCI_find_io
1196 hidnplayr 469
 
470
; We've found the io address, find IRQ now
471
 
3205 hidnplayr 472
        PCI_find_irq
1196 hidnplayr 473
 
2387 hidnplayr 474
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
475
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1196 hidnplayr 476
 
477
; Ok, the eth_device structure is ready, let's probe the device
1201 clevermous 478
; Because initialization fires IRQ, IRQ handler must be aware of this device
3198 hidnplayr 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]                                               ;
1196 hidnplayr 482
 
2387 hidnplayr 483
        call    probe                                                   ; this function will output in eax
484
        test    eax, eax
3198 hidnplayr 485
        jnz     .destroy                                                ; If an error occured, exit
1196 hidnplayr 486
 
2387 hidnplayr 487
        mov     [device.type], NET_TYPE_ETH
488
        call    NetRegDev
489
        cmp     eax, -1
490
        je      .destroy
1196 hidnplayr 491
 
2387 hidnplayr 492
        ret
1196 hidnplayr 493
 
494
; If the device was already loaded, find the device number and return it in eax
495
 
496
  .find_devicenum:
2387 hidnplayr 497
        DEBUGF  1,"Trying to find device number of already registered device\n"
498
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
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
1196 hidnplayr 503
 
504
; If an error occured, remove all allocated data and exit (returning -1 in eax)
505
 
506
  .destroy:
2387 hidnplayr 507
        ; todo: reset device into virgin state
1564 hidnplayr 508
 
2387 hidnplayr 509
        dec     [devices]
1196 hidnplayr 510
  .err:
2387 hidnplayr 511
        DEBUGF  1,"Error, removing all data !\n"
512
        stdcall KernelFree, ebx
1196 hidnplayr 513
 
514
  .fail:
2387 hidnplayr 515
        or      eax, -1
516
        ret
1196 hidnplayr 517
 
518
;------------------------------------------------------
519
endp
520
 
521
 
522
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
523
;;                                                                        ;;
524
;;        Actual Hardware dependent code starts here                      ;;
525
;;                                                                        ;;
526
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
527
 
528
align 4
529
unload:
2387 hidnplayr 530
        ; TODO: (in this particular order)
531
        ;
532
        ; - Stop the device
533
        ; - Detach int handler
534
        ; - Remove device from local list (RTL8139_LIST)
535
        ; - call unregister function in kernel
536
        ; - Remove all allocated structures and buffers the card used
1196 hidnplayr 537
 
2387 hidnplayr 538
        or      eax,-1
1196 hidnplayr 539
 
540
ret
541
 
542
 
543
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
544
;;
545
;;  probe: enables the device (if it really is a PCnet device)
546
;;
547
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
548
 
549
align 4
550
probe:
3198 hidnplayr 551
 
2387 hidnplayr 552
        mov     edx, [device.io_addr]
1196 hidnplayr 553
 
2387 hidnplayr 554
        call    wio_reset
1196 hidnplayr 555
 
2387 hidnplayr 556
        xor     ecx, ecx
557
        call    wio_read_csr
558
        cmp     eax, 4
559
        jne     .try_dwio
1196 hidnplayr 560
 
2387 hidnplayr 561
        ; Try Word I/O
3198 hidnplayr 562
        mov     ax, 88
563
        add     edx, WIO_RAP
564
        out     dx, ax
2387 hidnplayr 565
        nop
566
        nop
3198 hidnplayr 567
        in      ax, dx
568
        sub     edx, WIO_RAP
569
        cmp     ax, 88
2387 hidnplayr 570
        jne     .try_dwio
1196 hidnplayr 571
 
2387 hidnplayr 572
        call    switch_to_wio
1196 hidnplayr 573
 
2387 hidnplayr 574
        jmp     .L1
1196 hidnplayr 575
 
576
  .try_dwio:
2387 hidnplayr 577
        call    dwio_reset
1196 hidnplayr 578
 
2387 hidnplayr 579
        xor     ecx, ecx
580
        call    dwio_read_csr
581
        cmp     eax, 4
582
        jne     .no_dev
1196 hidnplayr 583
 
2387 hidnplayr 584
        ; Try Dword I/O
3198 hidnplayr 585
        add     edx, DWIO_RAP
2387 hidnplayr 586
        mov     eax, 88
3198 hidnplayr 587
        out     dx, eax
2387 hidnplayr 588
        nop
589
        nop
590
        in      eax, dx
3198 hidnplayr 591
        sub     edx, DWIO_RAP
2387 hidnplayr 592
        and     eax, 0xffff
593
        cmp     eax, 88
594
        jne     .no_dev
1196 hidnplayr 595
 
2387 hidnplayr 596
        call    switch_to_dwio
1196 hidnplayr 597
 
2387 hidnplayr 598
        jmp     .L1
1196 hidnplayr 599
 
600
  .no_dev:
2387 hidnplayr 601
        DEBUGF 1,"PCnet device not found!\n"
602
        mov     eax, 1
603
        ret
3198 hidnplayr 604
 
1564 hidnplayr 605
  .L1:
3198 hidnplayr 606
        mov     ecx, CSR_CHIPID0
607
        call    [device.read_csr]
1541 hidnplayr 608
 
2387 hidnplayr 609
        mov     esi, eax
3198 hidnplayr 610
        shr     esi, 12
1196 hidnplayr 611
 
3198 hidnplayr 612
        and     ax, 0xfff
613
        cmp     ax, 3
2387 hidnplayr 614
        jne     .no_dev
1196 hidnplayr 615
 
3198 hidnplayr 616
        mov     ecx, CSR_CHIPID1
617
        call    [device.read_csr]
618
        shl     eax, 4
619
        or      eax, esi
620
        mov     [device.chip_version], ax
1196 hidnplayr 621
 
2387 hidnplayr 622
        mov     [device.fdx], 0
623
        mov     [device.mii], 0
624
        mov     [device.fset], 0
625
        mov     [device.dxsuflo], 0
626
        mov     [device.ltint], 0
1196 hidnplayr 627
 
3198 hidnplayr 628
        cmp     ax, 0x2420
2387 hidnplayr 629
        je      .L2
3198 hidnplayr 630
        cmp     ax, 0x2430
2387 hidnplayr 631
        je      .L2
1196 hidnplayr 632
 
2387 hidnplayr 633
        mov     [device.fdx], 1
1196 hidnplayr 634
 
3198 hidnplayr 635
        cmp     ax, 0x2621
2387 hidnplayr 636
        je      .L4
3198 hidnplayr 637
        cmp     ax, 0x2623
2387 hidnplayr 638
        je      .L5
3198 hidnplayr 639
        cmp     ax, 0x2624
2387 hidnplayr 640
        je      .L6
3198 hidnplayr 641
        cmp     ax, 0x2625
2387 hidnplayr 642
        je      .L7
3198 hidnplayr 643
        cmp     ax, 0x2626
2387 hidnplayr 644
        je      .L8
3198 hidnplayr 645
        cmp     ax, 0x2627
2387 hidnplayr 646
        je      .L9
1196 hidnplayr 647
 
2387 hidnplayr 648
        DEBUGF 1,"Invalid chip rev\n"
649
        jmp     .no_dev
1196 hidnplayr 650
  .L2:
2387 hidnplayr 651
        mov     [device.name], device_l2
652
        jmp     .L10
1196 hidnplayr 653
  .L4:
2387 hidnplayr 654
        mov     [device.name], device_l4
1492 hidnplayr 655
;        mov     [device.fdx], 1
2387 hidnplayr 656
        jmp     .L10
1196 hidnplayr 657
  .L5:
2387 hidnplayr 658
        mov     [device.name], device_l5
1492 hidnplayr 659
;        mov     [device.fdx], 1
2387 hidnplayr 660
        mov     [device.mii], 1
661
        mov     [device.fset], 1
662
        mov     [device.ltint], 1
663
        jmp     .L10
1196 hidnplayr 664
  .L6:
2387 hidnplayr 665
        mov     [device.name], device_l6
1492 hidnplayr 666
;        mov     [device.fdx], 1
2387 hidnplayr 667
        mov     [device.mii], 1
668
        mov     [device.fset], 1
669
        jmp     .L10
1196 hidnplayr 670
  .L7:
2387 hidnplayr 671
        mov     [device.name], device_l7
1492 hidnplayr 672
;        mov     [device.fdx], 1
2387 hidnplayr 673
        mov     [device.mii], 1
674
        jmp     .L10
1196 hidnplayr 675
  .L8:
2387 hidnplayr 676
        mov     [device.name], device_l8
1492 hidnplayr 677
;        mov     [device.fdx], 1
3198 hidnplayr 678
        mov     ecx, CSR_RXPOLL
679
        call    dword [device.read_bcr]
680
        call    dword [device.write_bcr]
2387 hidnplayr 681
        jmp     .L10
1196 hidnplayr 682
  .L9:
2387 hidnplayr 683
        mov     [device.name], device_l9
1492 hidnplayr 684
;        mov     [device.fdx], 1
2387 hidnplayr 685
        mov     [device.mii], 1
1196 hidnplayr 686
  .L10:
3198 hidnplayr 687
        DEBUGF 1,"device name: %s\n", [device.name]
1196 hidnplayr 688
 
2387 hidnplayr 689
        cmp     [device.fset], 1
690
        jne     .L11
3198 hidnplayr 691
        mov     ecx, BCR_BUSCTL
692
        call    [device.read_bcr]
2387 hidnplayr 693
        or      eax, 0x800
3198 hidnplayr 694
        call    [device.write_bcr]
1196 hidnplayr 695
 
3198 hidnplayr 696
        mov     ecx, CSR_DMACTL
697
        call    [device.read_csr]
1564 hidnplayr 698
;        and     eax, 0xc00
699
;        or      eax, 0xc00
2387 hidnplayr 700
        mov     eax, 0xc00
3198 hidnplayr 701
        call    [device.write_csr]
1196 hidnplayr 702
 
2387 hidnplayr 703
        mov     [device.dxsuflo],1
704
        mov     [device.ltint],1
1196 hidnplayr 705
  .L11:
706
 
3205 hidnplayr 707
        PCI_make_bus_master
1564 hidnplayr 708
 
3198 hidnplayr 709
        mov     [device.options], PORT_ASEL
710
        mov     [device.mode_], MODE_RXD + MODE_TXD     ; disable receive and transmit
711
        mov     [device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
1196 hidnplayr 712
 
2387 hidnplayr 713
        mov     dword [device.filter], 0
714
        mov     dword [device.filter+4], 0
1196 hidnplayr 715
 
1492 hidnplayr 716
align 4
1196 hidnplayr 717
reset:
718
 
719
; attach int handler
720
 
2387 hidnplayr 721
        movzx   eax, [device.irq_line]
3198 hidnplayr 722
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
2387 hidnplayr 723
        stdcall AttachIntHandler, eax, int_handler, dword 0
724
        test    eax, eax
725
        jnz     @f
726
        DEBUGF  1,"\nCould not attach int handler!\n"
1196 hidnplayr 727
;        or      eax, -1
728
;        ret
729
  @@:
730
 
2387 hidnplayr 731
        mov     edx, [device.io_addr]
1492 hidnplayr 732
 
3198 hidnplayr 733
        call    [device.sw_reset]
734
 
2387 hidnplayr 735
        ; Switch pcnet32 to 32bit mode
3198 hidnplayr 736
        mov     ecx, BCR_SSTYLE
2387 hidnplayr 737
        mov     eax, 2
3198 hidnplayr 738
        call    [device.write_bcr]
1492 hidnplayr 739
 
2387 hidnplayr 740
        ; set/reset autoselect bit
3198 hidnplayr 741
        mov     ecx, BCR_MISCCFG
742
        call    [device.read_bcr]
743
        and     eax, not 2
744
        test    [device.options], PORT_ASEL
745
        jz      @f
2387 hidnplayr 746
        or      eax, 2
3198 hidnplayr 747
  @@:
748
        call    [device.write_bcr]
1196 hidnplayr 749
 
2387 hidnplayr 750
        ; Handle full duplex setting
751
        cmp     byte [device.full_duplex], 0
3198 hidnplayr 752
        je      .duplex_ok
753
        mov     ecx, BCR_DUPLEX
754
        call    [device.read_bcr]
2387 hidnplayr 755
        and     eax, not 3
3198 hidnplayr 756
        test    [device.options], PORT_FD
757
        jz      @f
2387 hidnplayr 758
        or      eax, 1
3198 hidnplayr 759
        cmp     [device.options], PORT_FD or PORT_AUI
760
        jne     .set_duplex
2387 hidnplayr 761
        or      eax, 2
3198 hidnplayr 762
        jmp     .set_duplex
763
  @@:
764
        test    [device.options], PORT_ASEL
765
        jz      .set_duplex
2387 hidnplayr 766
        cmp     [device.chip_version], 0x2627
3198 hidnplayr 767
        jne     .set_duplex
2387 hidnplayr 768
        or      eax, 3
3198 hidnplayr 769
  .set_duplex:
770
        mov     ecx, BCR_DUPLEX
771
        call    [device.write_bcr]
772
  .duplex_ok:
1196 hidnplayr 773
 
2387 hidnplayr 774
        ; set/reset GPSI bit in test register
775
        mov     ecx, 124
3198 hidnplayr 776
        call    [device.read_csr]
2387 hidnplayr 777
        mov     ecx, [device.options]
3198 hidnplayr 778
        and     ecx, PORT_PORTSEL
779
        cmp     ecx, PORT_GPSI
780
        jne     @f
2387 hidnplayr 781
        or      eax, 0x10
3198 hidnplayr 782
  @@:
783
        call    [device.write_csr]
2387 hidnplayr 784
        cmp     [device.mii], 0
785
        je      .L6
3198 hidnplayr 786
        test    [device.options], PORT_ASEL
2387 hidnplayr 787
        jnz     .L6
3198 hidnplayr 788
        mov     ecx, BCR_MIICTL
789
        call    [device.read_bcr]
790
        and     eax, not 0x38
791
        test    [device.options], PORT_FD
792
        jz      @f
2387 hidnplayr 793
        or      eax, 0x10
3198 hidnplayr 794
  @@:
795
        test    [device.options], PORT_100
796
        jz      @f
2387 hidnplayr 797
        or      eax, 0x08
3198 hidnplayr 798
  @@:
799
        call    [device.write_bcr]
2387 hidnplayr 800
        jmp     .L9
3198 hidnplayr 801
  .L6:
802
        test    [device.options], PORT_ASEL
2387 hidnplayr 803
        jz      .L9
3198 hidnplayr 804
        mov     ecx, BCR_MIICTL
2387 hidnplayr 805
        DEBUGF 1,"ASEL, enable auto-negotiation\n"
3198 hidnplayr 806
        call    [device.read_bcr]
2387 hidnplayr 807
        and     eax, not 0x98
808
        or      eax, 0x20
3198 hidnplayr 809
        call    [device.write_bcr]
810
  .L9:
811
        cmp     [device.ltint], 0
812
        je      @f
813
        mov     ecx, 5
814
        call    [device.read_csr]
815
        or      eax, (1 shl 14)
816
        call    [device.write_csr]
817
  @@:
818
        mov     eax, [device.options]
819
        and     eax, PORT_PORTSEL
820
        shl     eax, 7
821
        mov     [device.mode_], ax
2387 hidnplayr 822
        mov     dword [device.filter], -1
823
        mov     dword [device.filter+4], -1
1196 hidnplayr 824
 
3350 hidnplayr 825
 
826
 
827
;-----------------------------
828
 
829
        test    [device.mii], 1
830
        jz      .no_mii
831
 
832
        mov     [device.phy], 0
833
 
834
  .mii_loop:
835
        mov     ecx, MII_PHYSID1
836
        call    mdio_read
837
        cmp     ax, 0xffff
838
        je      .next
839
 
840
        DEBUGF  1, "0x%x\n", ax
841
 
842
        mov     ecx, MII_PHYSID2
843
        call    mdio_read
844
        cmp     ax, 0xffff
845
        je      .next
846
 
847
        DEBUGF  1, "0x%x\n", ax
848
 
849
        jmp     .got_phy
850
 
851
        cmp     [device.phy], 31
852
        jne     .next
853
        mov     ax, [device.chip_version]
854
        inc     ax
855
        and     ax, 0xfffe
856
        cmp     ax, 0x2624              ; 79c971 & 79c972 have phantom phy at id 31
857
        je      .got_phy
858
 
859
  .next:
860
        inc     [device.phy]
861
        cmp     [device.phy], MAX_PHYS
862
        jb      .mii_loop
863
 
864
        DEBUGF  1, "No PHY found!\n"
865
 
866
        or      eax, -1
867
        ret
868
 
869
  .got_phy:
870
        DEBUGF  1, "Found PHY at 0x%x\n", [device.phy]:4
871
 
872
  .no_mii:
873
 
874
;-----------------------------------------------
875
 
2387 hidnplayr 876
        call    read_mac
1196 hidnplayr 877
 
2387 hidnplayr 878
        lea     esi, [device.mac]
879
        lea     edi, [device.phys_addr]
880
        movsd
881
        movsw
1201 clevermous 882
 
2387 hidnplayr 883
        call    init_ring
1564 hidnplayr 884
 
3198 hidnplayr 885
        mov     edx, [device.io_addr]   ; init ring destroys edx
886
 
2387 hidnplayr 887
        lea     eax, [device.private]
888
        GetRealAddr
889
        push    eax
890
        and     eax, 0xffff
891
        mov     ecx, 1
3198 hidnplayr 892
        call    [device.write_csr]
2387 hidnplayr 893
        pop     eax
3198 hidnplayr 894
        shr     eax, 16
895
        mov     ecx, 2
896
        call    [device.write_csr]
1196 hidnplayr 897
 
3198 hidnplayr 898
        mov     ecx, 4
899
        mov     eax, 0x0915
900
        call    [device.write_csr]
1196 hidnplayr 901
 
3198 hidnplayr 902
; Set the interrupt mask
903
        mov     ecx, CSR_IMR
904
        mov     eax, IMR
905
        call    [device.write_csr]
1196 hidnplayr 906
 
3198 hidnplayr 907
; Initialise the device
908
        xor     ecx, ecx
909
        mov     eax, CSR_INIT
910
        call    [device.write_csr]
1196 hidnplayr 911
 
3198 hidnplayr 912
        mov     esi, 100
913
;        xor     ecx, ecx
914
  @@:
915
        call    [device.read_csr]
916
        test    ax, CSR_IDONE
917
        jnz     @f
1196 hidnplayr 918
 
3198 hidnplayr 919
        dec     esi
920
        jnz     @r
921
        DEBUGF 1,"Initialize timeout!\n"
922
  @@:
1196 hidnplayr 923
 
3198 hidnplayr 924
; Start the device and enable interrupts
2387 hidnplayr 925
        xor     ecx, ecx
3198 hidnplayr 926
        mov     eax, CSR_START + CSR_INTEN
927
        call    [device.write_csr]
1196 hidnplayr 928
 
1564 hidnplayr 929
; Set the mtu, kernel will be able to send now
2387 hidnplayr 930
        mov     [device.mtu], 1514
1564 hidnplayr 931
 
3346 hidnplayr 932
; get link status
3347 hidnplayr 933
        mov     [device.state], ETH_LINK_UNKOWN
3346 hidnplayr 934
 
3350 hidnplayr 935
        call    check_media
936
 
3198 hidnplayr 937
        DEBUGF 1,"reset complete\n"
2387 hidnplayr 938
        xor     eax, eax
939
        ret
1492 hidnplayr 940
 
1519 hidnplayr 941
 
1564 hidnplayr 942
align 4
943
init_ring:
944
 
3198 hidnplayr 945
        DEBUGF 1,"init ring\n"
946
 
947
        lea     edi, [device.rx_ring]
2387 hidnplayr 948
        mov     eax, edi
949
        GetRealAddr
950
        mov     [device.rx_ring_phys], eax
3198 hidnplayr 951
        mov     ecx, RX_RING_SIZE
1564 hidnplayr 952
  .rx_init:
3198 hidnplayr 953
        push    ecx
954
        stdcall KernelAlloc, PKT_BUF_SZ
955
        pop     ecx
956
        mov     [edi + descriptor.virtual], eax
957
        GetRealAddr
958
        mov     [edi + descriptor.base], eax
959
        mov     [edi + descriptor.length], - PKT_BUF_SZ
960
        mov     [edi + descriptor.status], RXSTAT_OWN
961
        mov     dword [edi + descriptor.msg_length], 0    ; also clears misc field
962
        add     edi, descriptor.size
963
        dec     ecx
964
        jnz     .rx_init
1564 hidnplayr 965
 
3198 hidnplayr 966
        lea     edi, [device.tx_ring]
2387 hidnplayr 967
        mov     eax, edi
968
        GetRealAddr
969
        mov     [device.tx_ring_phys], eax
3198 hidnplayr 970
        mov     ecx, TX_RING_SIZE
1564 hidnplayr 971
  .tx_init:
3198 hidnplayr 972
        mov     [edi + descriptor.status], 0
973
        add     edi, descriptor.size
974
        dec     ecx
975
        jnz     .tx_init
1564 hidnplayr 976
 
3198 hidnplayr 977
        mov     [device.tlen_rlen], (TX_RING_LEN_BITS or RX_RING_LEN_BITS)
1564 hidnplayr 978
 
3198 hidnplayr 979
        mov     [device.cur_tx], 0
980
        mov     [device.last_tx], 0
981
        mov     [device.cur_rx], 0
982
 
2387 hidnplayr 983
        ret
1196 hidnplayr 984
 
985
 
986
 
987
 
988
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
989
;;                                         ;;
990
;; Transmit                                ;;
991
;;                                         ;;
1263 clevermous 992
;; In: buffer pointer in [esp+4]           ;;
1254 hidnplayr 993
;;     size of buffer in [esp+8]           ;;
1196 hidnplayr 994
;;     pointer to device structure in ebx  ;;
995
;;                                         ;;
996
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
997
 
998
align 4
999
transmit:
3198 hidnplayr 1000
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
2387 hidnplayr 1001
        mov     eax, [esp+4]
1002
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1003
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1004
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1005
        [eax+13]:2,[eax+12]:2
1196 hidnplayr 1006
 
2387 hidnplayr 1007
        cmp     dword [esp+8], 1514
3155 hidnplayr 1008
        ja      .nospace                        ; packet is too long
2387 hidnplayr 1009
        cmp     dword [esp+8], 60
3155 hidnplayr 1010
        jb      .nospace                        ; packet is too short
1196 hidnplayr 1011
 
1012
; check descriptor
3198 hidnplayr 1013
        lea     edi, [device.tx_ring]
2387 hidnplayr 1014
        movzx   eax, [device.cur_tx]
1015
        shl     eax, 4
3198 hidnplayr 1016
        add     edi, eax
1541 hidnplayr 1017
 
3198 hidnplayr 1018
        test    [edi + descriptor.status], TXCTL_OWN
2387 hidnplayr 1019
        jnz     .nospace
3198 hidnplayr 1020
; descriptor is free, use it
1021
        mov     eax, [esp+4]
1022
        mov     [edi + descriptor.virtual], eax
1023
        GetRealAddr
1024
        mov     [edi + descriptor.base], eax
1201 clevermous 1025
; set length
3198 hidnplayr 1026
        mov     eax, [esp+8]
1027
        neg     eax
1028
        mov     [edi + descriptor.length], ax
1201 clevermous 1029
; put to transfer queue
3198 hidnplayr 1030
        mov     [edi + descriptor.status], TXCTL_OWN + TXCTL_STP + TXCTL_ENP
1196 hidnplayr 1031
 
1032
; trigger an immediate send
3197 hidnplayr 1033
        mov     edx, [device.io_addr]
3198 hidnplayr 1034
        xor     ecx, ecx                        ; CSR0
1035
        call    [device.read_csr]
1036
        or      eax, CSR_TX
1037
        call    [device.write_csr]
1196 hidnplayr 1038
 
1039
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
2387 hidnplayr 1040
        inc     [device.cur_tx]
3198 hidnplayr 1041
        and     [device.cur_tx], TX_RING_SIZE - 1
2387 hidnplayr 1042
        DEBUGF  2," - Packet Sent! "
1196 hidnplayr 1043
 
2863 hidnplayr 1044
; Update stats
1045
        inc     [device.packets_tx]
1046
        mov     eax, [esp+8]
1047
        add     dword [device.bytes_tx], eax
1048
        adc     dword [device.bytes_tx + 4], 0
1049
 
3198 hidnplayr 1050
  .finish:
2387 hidnplayr 1051
        DEBUGF  2," - Done!\n"
1052
        xor     eax, eax
1053
        ret     8
1196 hidnplayr 1054
 
3198 hidnplayr 1055
  .nospace:
2387 hidnplayr 1056
        DEBUGF  1, 'ERROR: no free transmit descriptors\n'
1057
        stdcall KernelFree, [esp+4]
1058
        or      eax, -1
1059
        ret     8
1196 hidnplayr 1060
 
1061
 
1062
 
1063
;;;;;;;;;;;;;;;;;;;;;;;
1064
;;                   ;;
1065
;; Interrupt handler ;;
1066
;;                   ;;
1067
;;;;;;;;;;;;;;;;;;;;;;;
1068
 
1069
align 4
1070
int_handler:
1071
 
2935 hidnplayr 1072
        DEBUGF  1,"\n%s int\n", my_service
1196 hidnplayr 1073
 
1074
; find pointer of device wich made IRQ occur
1075
 
2387 hidnplayr 1076
        mov     ecx, [devices]
1077
        test    ecx, ecx
2935 hidnplayr 1078
        jz      .nothing
1079
        mov     esi, device_list
1196 hidnplayr 1080
  .nextdevice:
2935 hidnplayr 1081
        mov     ebx, [esi]
1082
 
3198 hidnplayr 1083
        mov     edx, [device.io_addr]
2387 hidnplayr 1084
        push    ecx
3198 hidnplayr 1085
        xor     ecx, ecx                        ; CSR0
1086
        call    [device.read_csr]               ; get IRQ reason
1087
        call    [device.write_csr]              ; write it back to ACK
2387 hidnplayr 1088
        pop     ecx
3198 hidnplayr 1089
        test    ax, ax
1090
        jnz     .got_it
2935 hidnplayr 1091
  .continue:
2387 hidnplayr 1092
        add     esi, 4
2935 hidnplayr 1093
        dec     ecx
1094
        jnz     .nextdevice
1095
  .nothing:
3198 hidnplayr 1096
        ret                                     ; If no device was found, abort (The int was probably for a device, not registered to this driver)
1196 hidnplayr 1097
 
1098
  .got_it:
3198 hidnplayr 1099
        DEBUGF  1,"Device: %x status: %x\n", ebx, eax:2
2935 hidnplayr 1100
 
3198 hidnplayr 1101
        push    ax
1102
        test    ax, CSR_RINT
1103
        jz      .not_receive
2935 hidnplayr 1104
 
2401 hidnplayr 1105
        push    ebx
3198 hidnplayr 1106
  .rx_loop:
2401 hidnplayr 1107
        pop     ebx
2387 hidnplayr 1108
        movzx   eax, [device.cur_rx]
3198 hidnplayr 1109
        shl     eax, 4
1110
        lea     edi, [device.rx_ring]
1111
        add     edi, eax                        ; edi now points to current rx ring entry
1196 hidnplayr 1112
 
3198 hidnplayr 1113
        mov     ax, [edi + descriptor.status]
1114
        DEBUGF  1,"RX packet status: %x\n", eax:4
1196 hidnplayr 1115
 
3198 hidnplayr 1116
        test    ax, RXSTAT_OWN                  ; If this bit is set, the controller OWN's the packet, if not, we do
1117
        jnz     .not_receive
1196 hidnplayr 1118
 
3198 hidnplayr 1119
        test    ax, RXSTAT_ENP
1120
        jz      .not_receive
1196 hidnplayr 1121
 
3198 hidnplayr 1122
        test    ax, RXSTAT_STP
1123
        jz      .not_receive
1196 hidnplayr 1124
 
3198 hidnplayr 1125
        movzx   ecx, [edi + descriptor.msg_length]      ; get packet length in ecx
1126
        sub     ecx, 4                                  ;
1196 hidnplayr 1127
 
3198 hidnplayr 1128
; Set pointers for ETH_input
1129
        push    ebx
1196 hidnplayr 1130
 
3198 hidnplayr 1131
        push    .rx_loop                                ; return address
1132
        push    ecx                                     ; packet size
1133
        push    [edi + descriptor.virtual]              ; packet address
1196 hidnplayr 1134
 
2863 hidnplayr 1135
; Update stats
1136
        add     dword [device.bytes_rx], ecx
1137
        adc     dword [device.bytes_rx + 4], 0
3198 hidnplayr 1138
        inc     [device.packets_rx]
2863 hidnplayr 1139
 
3198 hidnplayr 1140
; now allocate a new buffer
1141
        stdcall KernelAlloc, PKT_BUF_SZ                 ; Allocate a buffer for the next packet
1142
        mov     [edi + descriptor.virtual], eax         ; set virtual address
1143
        GetRealAddr
1144
        mov     [edi + descriptor.base], eax            ; and real address
1196 hidnplayr 1145
 
3198 hidnplayr 1146
;        mov     word [edi + descriptor.length], - PKT_BUF_SZ
1147
        mov     [edi + descriptor.status], RXSTAT_OWN   ; give it back to PCnet controller
1196 hidnplayr 1148
 
3198 hidnplayr 1149
        inc     [device.cur_rx]                         ; set next receive descriptor
1150
        and     [device.cur_rx], RX_RING_SIZE - 1
1196 hidnplayr 1151
 
2981 hidnplayr 1152
        jmp     Eth_input
1196 hidnplayr 1153
 
3198 hidnplayr 1154
  .not_receive:
1155
        pop     ax
1196 hidnplayr 1156
 
3198 hidnplayr 1157
        test    ax, CSR_TINT
1158
        jz      .not_transmit
1541 hidnplayr 1159
 
3198 hidnplayr 1160
  .tx_loop:
1161
        lea     edi, [device.tx_ring]
1162
        movzx   eax, [device.last_tx]
1163
        shl     eax, 4
1164
        add     edi, eax
1165
 
1166
        test    [edi + descriptor.status], TXCTL_OWN
1167
        jnz     .not_transmit
1168
 
1169
        mov     eax, [edi + descriptor.virtual]
1170
        test    eax, eax
1171
        jz      .not_transmit
1172
 
1173
        mov     [edi + descriptor.virtual], 0
1174
 
1175
        DEBUGF  1,"Removing packet %x from memory\n", eax
1176
 
1177
        stdcall KernelFree, eax
1178
 
1179
        inc     [device.last_tx]
1180
        and     [device.last_tx], TX_RING_SIZE - 1
1181
        jmp     .tx_loop
1182
 
1183
  .not_transmit:
1184
 
2387 hidnplayr 1185
        ret
1196 hidnplayr 1186
 
1187
 
1188
 
1189
 
1190
;;;;;;;;;;;;;;;;;;;;;;;
1191
;;                   ;;
1192
;; Write MAC address ;;
1193
;;                   ;;
1194
;;;;;;;;;;;;;;;;;;;;;;;
1195
 
1196
align 4
2387 hidnplayr 1197
write_mac:      ; in: mac pushed onto stack (as 3 words)
1196 hidnplayr 1198
 
2387 hidnplayr 1199
        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 1200
 
2387 hidnplayr 1201
        mov     edx, [device.io_addr]
1202
        add     dx, 2
1203
        xor     eax, eax
1564 hidnplayr 1204
 
3198 hidnplayr 1205
        mov     ecx, CSR_PAR0
1196 hidnplayr 1206
       @@:
2387 hidnplayr 1207
        pop     ax
3198 hidnplayr 1208
        call    [device.write_csr]
2387 hidnplayr 1209
        DEBUGF  1,"."
1210
        inc     ecx
3198 hidnplayr 1211
        cmp     ecx, CSR_PAR2
3155 hidnplayr 1212
        jb      @r
1196 hidnplayr 1213
 
2387 hidnplayr 1214
        DEBUGF  1,"\n"
1196 hidnplayr 1215
 
1216
; Notice this procedure does not ret, but continues to read_mac instead.
1217
 
1218
;;;;;;;;;;;;;;;;;;;;;;
1219
;;                  ;;
1220
;; Read MAC address ;;
1221
;;                  ;;
1222
;;;;;;;;;;;;;;;;;;;;;;
1564 hidnplayr 1223
align 4
1492 hidnplayr 1224
read_mac:
2387 hidnplayr 1225
        DEBUGF  1,"Reading MAC"
1196 hidnplayr 1226
 
2387 hidnplayr 1227
        mov     edx, [device.io_addr]
1228
        add     dx, 6
1196 hidnplayr 1229
       @@:
2387 hidnplayr 1230
        dec     dx
1231
        dec     dx
1232
        in      ax, dx
1233
        push    ax
1234
        DEBUGF  1,"."
1235
        cmp     edx, [device.io_addr]
3155 hidnplayr 1236
        ja      @r
1196 hidnplayr 1237
 
2387 hidnplayr 1238
        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 1239
 
2387 hidnplayr 1240
        lea     edi, [device.mac]
1241
        pop     ax
1242
        stosw
1243
        pop     ax
1244
        stosw
1245
        pop     ax
1246
        stosw
1196 hidnplayr 1247
 
2387 hidnplayr 1248
        ret
1196 hidnplayr 1249
 
1564 hidnplayr 1250
align 4
1196 hidnplayr 1251
switch_to_wio:
1252
 
2387 hidnplayr 1253
        DEBUGF  1,"Switching to 16-bit mode\n"
1564 hidnplayr 1254
 
3198 hidnplayr 1255
        mov     [device.read_csr], wio_read_csr
1256
        mov     [device.write_csr], wio_write_csr
1257
        mov     [device.read_bcr], wio_read_bcr
1258
        mov     [device.write_bcr], wio_write_bcr
1259
        mov     [device.read_rap], wio_read_rap
1260
        mov     [device.write_rap], wio_write_rap
1261
        mov     [device.sw_reset], wio_reset
1196 hidnplayr 1262
 
2387 hidnplayr 1263
        ret
1196 hidnplayr 1264
 
1564 hidnplayr 1265
align 4
1196 hidnplayr 1266
switch_to_dwio:
1267
 
2387 hidnplayr 1268
        DEBUGF  1,"Switching to 32-bit mode\n"
1564 hidnplayr 1269
 
3198 hidnplayr 1270
        mov     [device.read_csr], dwio_read_csr
1271
        mov     [device.write_csr], dwio_write_csr
1272
        mov     [device.read_bcr], dwio_read_bcr
1273
        mov     [device.write_bcr], dwio_write_bcr
1274
        mov     [device.read_rap], dwio_read_rap
1275
        mov     [device.write_rap], dwio_write_rap
1276
        mov     [device.sw_reset], dwio_reset
1196 hidnplayr 1277
 
2387 hidnplayr 1278
        ret
1196 hidnplayr 1279
 
1280
 
1281
; ecx - index
1282
; return:
1283
; eax - data
1564 hidnplayr 1284
align 4
1196 hidnplayr 1285
wio_read_csr:
1286
 
3198 hidnplayr 1287
        add     edx, WIO_RAP
1288
        mov     ax, cx
1289
        out     dx, ax
1290
        add     edx, WIO_RDP - WIO_RAP
1291
        in      ax, dx
2387 hidnplayr 1292
        and     eax, 0xffff
3198 hidnplayr 1293
        sub     edx, WIO_RDP
1196 hidnplayr 1294
 
2387 hidnplayr 1295
        ret
1196 hidnplayr 1296
 
1297
 
1298
; eax - data
1299
; ecx - index
1564 hidnplayr 1300
align 4
1196 hidnplayr 1301
wio_write_csr:
1302
 
3198 hidnplayr 1303
        add     edx, WIO_RAP
2387 hidnplayr 1304
        xchg    eax, ecx
3198 hidnplayr 1305
        out     dx, ax
2387 hidnplayr 1306
        xchg    eax, ecx
3198 hidnplayr 1307
        add     edx, WIO_RDP - WIO_RAP
1308
        out     dx, ax
1309
        sub     edx, WIO_RDP
1196 hidnplayr 1310
 
2387 hidnplayr 1311
        ret
1196 hidnplayr 1312
 
1313
 
1314
; ecx - index
1315
; return:
1316
; eax - data
1564 hidnplayr 1317
align 4
1196 hidnplayr 1318
wio_read_bcr:
1319
 
3198 hidnplayr 1320
        add     edx, WIO_RAP
1321
        mov     ax, cx
1322
        out     dx, ax
1323
        add     edx, WIO_BDP - WIO_RAP
1324
        in      ax, dx
2387 hidnplayr 1325
        and     eax, 0xffff
3198 hidnplayr 1326
        sub     edx, WIO_BDP
1196 hidnplayr 1327
 
2387 hidnplayr 1328
        ret
1196 hidnplayr 1329
 
1330
 
1331
; eax - data
1332
; ecx - index
1564 hidnplayr 1333
align 4
1196 hidnplayr 1334
wio_write_bcr:
1335
 
3198 hidnplayr 1336
        add     edx, WIO_RAP
2387 hidnplayr 1337
        xchg    eax, ecx
3198 hidnplayr 1338
        out     dx, ax
2387 hidnplayr 1339
        xchg    eax, ecx
3198 hidnplayr 1340
        add     edx, WIO_BDP - WIO_RAP
1341
        out     dx, ax
1342
        sub     edx, WIO_BDP
1196 hidnplayr 1343
 
2387 hidnplayr 1344
        ret
1196 hidnplayr 1345
 
1564 hidnplayr 1346
align 4
1196 hidnplayr 1347
wio_read_rap:
1348
 
3198 hidnplayr 1349
        add     edx, WIO_RAP
1350
        in      ax, dx
2387 hidnplayr 1351
        and     eax, 0xffff
3198 hidnplayr 1352
        sub     edx, WIO_RAP
1196 hidnplayr 1353
 
2387 hidnplayr 1354
        ret
1196 hidnplayr 1355
 
1356
; eax - val
1564 hidnplayr 1357
align 4
1196 hidnplayr 1358
wio_write_rap:
1359
 
3198 hidnplayr 1360
        add     edx, WIO_RAP
1361
        out     dx, ax
1362
        sub     edx, WIO_RAP
1196 hidnplayr 1363
 
2387 hidnplayr 1364
        ret
1196 hidnplayr 1365
 
1564 hidnplayr 1366
align 4
1196 hidnplayr 1367
wio_reset:
1368
 
2387 hidnplayr 1369
        push    eax
3198 hidnplayr 1370
        add     edx, WIO_RESET
1371
        in      ax, dx
2387 hidnplayr 1372
        pop     eax
3198 hidnplayr 1373
        sub     edx, WIO_RESET
1196 hidnplayr 1374
 
2387 hidnplayr 1375
        ret
1196 hidnplayr 1376
 
1377
 
1564 hidnplayr 1378
 
1196 hidnplayr 1379
; ecx - index
1380
; return:
1381
; eax - data
1564 hidnplayr 1382
align 4
1196 hidnplayr 1383
dwio_read_csr:
1384
 
3198 hidnplayr 1385
        add     edx, DWIO_RAP
2387 hidnplayr 1386
        mov     eax, ecx
3198 hidnplayr 1387
        out     dx, eax
1388
        add     edx, DWIO_RDP - DWIO_RAP
2387 hidnplayr 1389
        in      eax, dx
1390
        and     eax, 0xffff
3198 hidnplayr 1391
        sub     edx, DWIO_RDP
1196 hidnplayr 1392
 
2387 hidnplayr 1393
        ret
1196 hidnplayr 1394
 
1395
 
1396
; ecx - index
1397
; eax - data
1564 hidnplayr 1398
align 4
1196 hidnplayr 1399
dwio_write_csr:
1400
 
3198 hidnplayr 1401
        add     edx, DWIO_RAP
2387 hidnplayr 1402
        xchg    eax, ecx
3198 hidnplayr 1403
        out     dx, eax
1404
        add     edx, DWIO_RDP - DWIO_RAP
2387 hidnplayr 1405
        xchg    eax, ecx
3198 hidnplayr 1406
        out     dx, eax
1407
        sub     edx, DWIO_RDP
1196 hidnplayr 1408
 
2387 hidnplayr 1409
        ret
1196 hidnplayr 1410
 
1411
; ecx - index
1412
; return:
1413
; eax - data
1564 hidnplayr 1414
align 4
1196 hidnplayr 1415
dwio_read_bcr:
1416
 
3198 hidnplayr 1417
        add     edx, DWIO_RAP
2387 hidnplayr 1418
        mov     eax, ecx
3198 hidnplayr 1419
        out     dx, eax
1420
        add     edx, DWIO_BDP - DWIO_RAP
2387 hidnplayr 1421
        in      eax, dx
1422
        and     eax, 0xffff
3198 hidnplayr 1423
        sub     edx, DWIO_BDP
1196 hidnplayr 1424
 
2387 hidnplayr 1425
        ret
1196 hidnplayr 1426
 
1427
 
1428
; ecx - index
1429
; eax - data
1564 hidnplayr 1430
align 4
1196 hidnplayr 1431
dwio_write_bcr:
1432
 
3198 hidnplayr 1433
        add     edx, DWIO_RAP
2387 hidnplayr 1434
        xchg    eax, ecx
3198 hidnplayr 1435
        out     dx, eax
1436
        add     edx, DWIO_BDP - DWIO_RAP
2387 hidnplayr 1437
        xchg    eax, ecx
3198 hidnplayr 1438
        out     dx, eax
1439
        sub     edx, DWIO_BDP
1196 hidnplayr 1440
 
2387 hidnplayr 1441
        ret
1196 hidnplayr 1442
 
1564 hidnplayr 1443
align 4
1196 hidnplayr 1444
dwio_read_rap:
1445
 
3198 hidnplayr 1446
        add     edx, DWIO_RAP
2387 hidnplayr 1447
        in      eax, dx
1448
        and     eax, 0xffff
3198 hidnplayr 1449
        sub     edx, DWIO_RAP
1196 hidnplayr 1450
 
2387 hidnplayr 1451
        ret
1196 hidnplayr 1452
 
1453
 
1454
; eax - val
1564 hidnplayr 1455
align 4
1196 hidnplayr 1456
dwio_write_rap:
1457
 
3198 hidnplayr 1458
        add     edx, DWIO_RAP
1459
        out     dx, eax
1460
        sub     edx, DWIO_RAP
1196 hidnplayr 1461
 
2387 hidnplayr 1462
        ret
1196 hidnplayr 1463
 
1564 hidnplayr 1464
align 4
1196 hidnplayr 1465
dwio_reset:
1466
 
2387 hidnplayr 1467
        push    eax
3198 hidnplayr 1468
        add     edx, DWIO_RESET
2387 hidnplayr 1469
        in      eax, dx
1470
        pop     eax
3198 hidnplayr 1471
        sub     edx, DWIO_RESET
1196 hidnplayr 1472
 
2387 hidnplayr 1473
        ret
1196 hidnplayr 1474
 
1475
 
3350 hidnplayr 1476
align 4
1477
mdio_read:
1196 hidnplayr 1478
 
3350 hidnplayr 1479
        and     ecx, 0x1f
1480
        mov     ax, [device.phy]
1481
        and     ax, 0x1f
1482
        shl     ax, 5
1483
        or      ax, cx
1484
 
1485
        mov     ecx, BCR_MIIADDR
1486
        call    [device.write_bcr]
1487
 
1488
        mov     ecx, BCR_MIIDATA
1489
        call    [device.read_bcr]
1490
 
1491
        ret
1492
 
1493
 
1494
align 4
1495
mdio_write:
1496
 
1497
        push    eax
1498
        and     ecx, 0x1f
1499
        mov     ax, [device.phy]
1500
        and     ax, 0x1f
1501
        shl     ax, 5
1502
        or      ax, cx
1503
 
1504
        mov     ecx, BCR_MIIADDR
1505
        call    [device.write_bcr]
1506
 
1507
        pop     eax
1508
        mov     ecx, BCR_MIIDATA
1509
        call    [device.write_bcr]
1510
 
1511
        ret
1512
 
1513
 
1514
align 4
1515
check_media:
1516
 
1517
        DEBUGF  1, "check_media\n"
1518
 
1519
        test    [device.mii], 1
1520
        jnz      mii_link_ok
1521
 
1522
        mov     ecx, BCR_LED0
1523
        call    [device.read_bcr]
1524
        cmp     eax, 0xc0
1525
 
3351 hidnplayr 1526
        DEBUGF  1, "link status=0x%x\n", ax
3350 hidnplayr 1527
 
1528
        ret
1529
 
1530
 
1531
 
1196 hidnplayr 1532
; End of code
1533
 
2387 hidnplayr 1534
align 4                                       ; Place all initialised data here
1196 hidnplayr 1535
 
1564 hidnplayr 1536
devices     dd 0
1537
version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
2387 hidnplayr 1538
my_service    db 'PCnet',0                    ; max 16 chars include zero
1564 hidnplayr 1539
 
1196 hidnplayr 1540
device_l2     db "PCnet/PCI 79C970",0
1541
device_l4     db "PCnet/PCI II 79C970A",0
1542
device_l5     db "PCnet/FAST 79C971",0
1543
device_l6     db "PCnet/FAST+ 79C972",0
1544
device_l7     db "PCnet/FAST III 79C973",0
1545
device_l8     db "PCnet/Home 79C978",0
1546
device_l9     db "PCnet/FAST III 79C975",0
1547
 
1548
options_mapping:
3198 hidnplayr 1549
dd PORT_ASEL                            ; 0 Auto-select
1550
dd PORT_AUI                             ; 1 BNC/AUI
1551
dd PORT_AUI                             ; 2 AUI/BNC
1552
dd PORT_ASEL                            ; 3 not supported
1553
dd PORT_10BT or PORT_FD                 ; 4 10baseT-FD
1554
dd PORT_ASEL                            ; 5 not supported
1555
dd PORT_ASEL                            ; 6 not supported
1556
dd PORT_ASEL                            ; 7 not supported
1557
dd PORT_ASEL                            ; 8 not supported
1558
dd PORT_MII                             ; 9 MII 10baseT
1559
dd PORT_MII or PORT_FD                  ; 10 MII 10baseT-FD
1560
dd PORT_MII                             ; 11 MII (autosel)
1561
dd PORT_10BT                            ; 12 10BaseT
1562
dd PORT_MII or PORT_100                 ; 13 MII 100BaseTx
1563
dd PORT_MII or PORT_100 or PORT_FD      ; 14 MII 100BaseTx-FD
1564
dd PORT_ASEL                            ; 15 not supported
1196 hidnplayr 1565
 
2387 hidnplayr 1566
include_debug_strings                                   ; All data wich FDO uses will be included here
1196 hidnplayr 1567
 
2387 hidnplayr 1568
section '.data' data readable writable align 16         ; place all uninitialized data place here
1196 hidnplayr 1569
 
3198 hidnplayr 1570
device_list rd MAX_DEVICES                              ; This list contains all pointers to device structures the driver is handling