Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1196 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                  ;;
1519 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.     ;;
1196 hidnplayr 4
;; Distributed under terms of the GNU General Public License        ;;
5
;;                                                                  ;;
1564 hidnplayr 6
;;  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
 
1564 hidnplayr 17
; $Revision: 2387 $
18
 
1196 hidnplayr 19
format MS COFF
20
 
2387 hidnplayr 21
        API_VERSION             equ 0x01000100
1196 hidnplayr 22
 
2387 hidnplayr 23
        DEBUG                   equ 1
24
        __DEBUG__               equ 1
25
        __DEBUG_LEVEL__         equ 1
1196 hidnplayr 26
 
2387 hidnplayr 27
        MAX_DEVICES equ 4
28
        MAX_ETH_FRAME_SIZE equ 1514
1196 hidnplayr 29
 
30
include 'proc32.inc'
31
include 'imports.inc'
32
include 'fdo.inc'
1492 hidnplayr 33
include 'netdrv.inc'
1196 hidnplayr 34
 
1564 hidnplayr 35
 
1196 hidnplayr 36
public START
37
public service_proc
38
public version
39
 
40
 
1492 hidnplayr 41
virtual at ebx
1196 hidnplayr 42
 
2387 hidnplayr 43
        device:
1196 hidnplayr 44
 
2387 hidnplayr 45
        ETH_DEVICE
1492 hidnplayr 46
 
1564 hidnplayr 47
; device specific
1196 hidnplayr 48
 
1564 hidnplayr 49
      .private:
2387 hidnplayr 50
      .mode_            dw ?
51
      .tlen_rlen        dw ?
52
      .phys_addr        dp ?
53
      .reserved         dw ?
54
      .filter           dq ?
55
      .rx_ring_phys     dd ?
56
      .tx_ring_phys     dd ?
1196 hidnplayr 57
 
2387 hidnplayr 58
      .cur_rx           db ?
59
      .cur_tx           db ?
60
      .dirty_rx         dd ?
61
      .dirty_tx         dd ?
62
      .tx_full          db ?
63
      .options          dd ?
64
      .full_duplex      db ?
65
      .chip_version     dd ?
66
      .mii              db ?
67
      .ltint            db ?
68
      .dxsuflo          db ?
69
      .fset             db ?
70
      .fdx              db ?
1492 hidnplayr 71
 
2387 hidnplayr 72
      .rx_buffer        dd ?
73
      .tx_buffer        dd ?
1492 hidnplayr 74
 
2387 hidnplayr 75
      .io_addr          dd ?
76
      .irq_line         db ?
77
      .pci_bus          db ?
78
      .pci_dev          db ?
1541 hidnplayr 79
 
80
 
2387 hidnplayr 81
      .access_read_csr          dd ?
82
      .access_write_csr         dd ?
83
      .access_read_bcr          dd ?
84
      .access_write_bcr         dd ?
85
      .access_read_rap          dd ?
86
      .access_write_rap         dd ?
87
      .access_reset             dd ?
1196 hidnplayr 88
 
2387 hidnplayr 89
      device_size       = $ - device
1196 hidnplayr 90
 
91
end virtual
92
 
1564 hidnplayr 93
struc buf_head {
2387 hidnplayr 94
        .base           dd ?
95
        .length         dw ?
96
        .status         dw ?
97
        .msg_length     dw ?
98
        .misc           dw ?
99
        .reserved       dd ?
1196 hidnplayr 100
 
2387 hidnplayr 101
        .size:
1196 hidnplayr 102
}
103
 
104
virtual at 0
1564 hidnplayr 105
 buf_head buf_head
1196 hidnplayr 106
end virtual
107
 
2387 hidnplayr 108
        PCNET_PORT_AUI                equ 0x00
109
        PCNET_PORT_10BT               equ 0x01
110
        PCNET_PORT_GPSI               equ 0x02
111
        PCNET_PORT_MII                equ 0x03
112
        PCNET_PORT_PORTSEL            equ 0x03
113
        PCNET_PORT_ASEL               equ 0x04
114
        PCNET_PORT_100                equ 0x40
115
        PCNET_PORT_FD                 equ 0x80
1196 hidnplayr 116
 
2387 hidnplayr 117
        PCNET_DMA_MASK                equ 0xffffffff
1196 hidnplayr 118
 
2387 hidnplayr 119
        PCNET_LOG_TX_BUFFERS          equ 2
120
        PCNET_LOG_RX_BUFFERS          equ 2
1196 hidnplayr 121
 
2387 hidnplayr 122
        PCNET_TX_RING_SIZE            equ 4
123
        PCNET_TX_RING_MOD_MASK        equ (PCNET_TX_RING_SIZE-1)
124
        PCNET_TX_RING_LEN_BITS        equ (PCNET_LOG_TX_BUFFERS shl 12)
1196 hidnplayr 125
 
2387 hidnplayr 126
        PCNET_RX_RING_SIZE            equ 4
127
        PCNET_RX_RING_MOD_MASK        equ (PCNET_RX_RING_SIZE-1)
128
        PCNET_RX_RING_LEN_BITS        equ (PCNET_LOG_RX_BUFFERS shl 4)
1196 hidnplayr 129
 
2387 hidnplayr 130
        PCNET_PKT_BUF_SZ              equ 1544
131
        PCNET_PKT_BUF_SZ_NEG          equ 0xf9f8
1196 hidnplayr 132
 
2387 hidnplayr 133
        PCNET_WIO_RDP                 equ 0x10
134
        PCNET_WIO_RAP                 equ 0x12
135
        PCNET_WIO_RESET               equ 0x14
136
        PCNET_WIO_BDP                 equ 0x16
137
        PCNET_DWIO_RDP                equ 0x10
138
        PCNET_DWIO_RAP                equ 0x14
139
        PCNET_DWIO_RESET              equ 0x18
140
        PCNET_DWIO_BDP                equ 0x1C
141
        PCNET_TOTAL_SIZE              equ 0x20
1564 hidnplayr 142
 
1196 hidnplayr 143
; CSR registers
144
 
2387 hidnplayr 145
        PCNET_CSR_CSR                 equ 0x00
146
        PCNET_CSR_IAB0                equ 0x01
147
        PCNET_CSR_IAB1                equ 0x02
148
        PCNET_CSR_IMR                 equ 0x03
149
        PCNET_CSR_TFEAT               equ 0x04
150
        PCNET_CSR_EXTCTL1             equ 0x05
151
        PCNET_CSR_DTBLLEN             equ 0x06
152
        PCNET_CSR_EXTCTL2             equ 0x07
153
        PCNET_CSR_MAR0                equ 0x08
154
        PCNET_CSR_MAR1                equ 0x09
155
        PCNET_CSR_MAR2                equ 0x0A
156
        PCNET_CSR_MAR3                equ 0x0B
157
        PCNET_CSR_PAR0                equ 0x0C
158
        PCNET_CSR_PAR1                equ 0x0D
159
        PCNET_CSR_PAR2                equ 0x0E
160
        PCNET_CSR_MODE                equ 0x0F
161
        PCNET_CSR_RXADDR0             equ 0x18
162
        PCNET_CSR_RXADDR1             equ 0x19
163
        PCNET_CSR_TXADDR0             equ 0x1E
164
        PCNET_CSR_TXADDR1             equ 0x1F
165
        PCNET_CSR_TXPOLL              equ 0x2F
166
        PCNET_CSR_RXPOLL              equ 0x31
167
        PCNET_CSR_RXRINGLEN           equ 0x4C
168
        PCNET_CSR_TXRINGLEN           equ 0x4E
169
        PCNET_CSR_DMACTL              equ 0x50
170
        PCNET_CSR_BUSTIMER            equ 0x52
171
        PCNET_CSR_MEMERRTIMEO         equ 0x64
172
        PCNET_CSR_ONNOWMISC           equ 0x74
173
        PCNET_CSR_ADVFEAT             equ 0x7A
174
        PCNET_CSR_MACCFG              equ 0x7D
175
        PCNET_CSR_CHIPID0             equ 0x58
176
        PCNET_CSR_CHIPID1             equ 0x59
1196 hidnplayr 177
 
178
; Control and Status Register (CSR0)
179
 
2387 hidnplayr 180
        PCNET_CSR_INIT                equ 1 shl 0
181
        PCNET_CSR_START               equ 1 shl 1
182
        PCNET_CSR_STOP                equ 1 shl 2
183
        PCNET_CSR_TX                  equ 1 shl 3
184
        PCNET_CSR_TXON                equ 1 shl 4
185
        PCNET_CSR_RXON                equ 1 shl 5
186
        PCNET_CSR_INTEN               equ 1 shl 6
187
        PCNET_CSR_INTR                equ 1 shl 7
188
        PCNET_CSR_IDONE               equ 1 shl 8
189
        PCNET_CSR_TINT                equ 1 shl 9
190
        PCNET_CSR_RINT                equ 1 shl 10
191
        PCNET_CSR_MERR                equ 1 shl 11
192
        PCNET_CSR_MISS                equ 1 shl 12
193
        PCNET_CSR_CERR                equ 1 shl 13
1196 hidnplayr 194
 
195
; Interrupt masks and deferral control (CSR3)
196
 
2387 hidnplayr 197
        PCNET_IMR_BSWAP               equ 0x0004
198
        PCNET_IMR_ENMBA               equ 0x0008  ; enable modified backoff alg
199
        PCNET_IMR_DXMT2PD             equ 0x0010
200
        PCNET_IMR_LAPPEN              equ 0x0020  ; lookahead packet processing enb
201
        PCNET_IMR_DXSUFLO             equ 0x0040  ; disable TX stop on underflow
202
        PCNET_IMR_IDONE               equ 0x0100
203
        PCNET_IMR_TINT                equ 0x0200
204
        PCNET_IMR_RINT                equ 0x0400
205
        PCNET_IMR_MERR                equ 0x0800
206
        PCNET_IMR_MISS                equ 0x1000
1196 hidnplayr 207
 
2387 hidnplayr 208
        PCNET_IMR                     equ PCNET_IMR_TINT+PCNET_IMR_RINT+PCNET_IMR_IDONE+PCNET_IMR_MERR+PCNET_IMR_MISS
1196 hidnplayr 209
 
210
; Test and features control (CSR4)
211
 
2387 hidnplayr 212
        PCNET_TFEAT_TXSTRTMASK        equ 0x0004
213
        PCNET_TFEAT_TXSTRT            equ 0x0008
214
        PCNET_TFEAT_RXCCOFLOWM        equ 0x0010  ; Rx collision counter oflow
215
        PCNET_TFEAT_RXCCOFLOW         equ 0x0020
216
        PCNET_TFEAT_UINT              equ 0x0040
217
        PCNET_TFEAT_UINTREQ           equ 0x0080
218
        PCNET_TFEAT_MISSOFLOWM        equ 0x0100
219
        PCNET_TFEAT_MISSOFLOW         equ 0x0200
220
        PCNET_TFEAT_STRIP_FCS         equ 0x0400
221
        PCNET_TFEAT_PAD_TX            equ 0x0800
222
        PCNET_TFEAT_TXDPOLL           equ 0x1000
223
        PCNET_TFEAT_DMAPLUS           equ 0x4000
1196 hidnplayr 224
 
225
; Extended control and interrupt 1 (CSR5)
226
 
2387 hidnplayr 227
        PCNET_EXTCTL1_SPND            equ 0x0001  ; suspend
228
        PCNET_EXTCTL1_MPMODE          equ 0x0002  ; magic packet mode
229
        PCNET_EXTCTL1_MPENB           equ 0x0004  ; magic packet enable
230
        PCNET_EXTCTL1_MPINTEN         equ 0x0008  ; magic packet interrupt enable
231
        PCNET_EXTCTL1_MPINT           equ 0x0010  ; magic packet interrupt
232
        PCNET_EXTCTL1_MPPLBA          equ 0x0020  ; magic packet phys. logical bcast
233
        PCNET_EXTCTL1_EXDEFEN         equ 0x0040  ; excessive deferral interrupt enb.
234
        PCNET_EXTCTL1_EXDEF           equ 0x0080  ; excessive deferral interrupt
235
        PCNET_EXTCTL1_SINTEN          equ 0x0400  ; system interrupt enable
236
        PCNET_EXTCTL1_SINT            equ 0x0800  ; system interrupt
237
        PCNET_EXTCTL1_LTINTEN         equ 0x4000  ; last TX interrupt enb
238
        PCNET_EXTCTL1_TXOKINTD        equ 0x8000  ; TX OK interrupt disable
1196 hidnplayr 239
 
240
; RX/TX descriptor len (CSR6)
241
 
2387 hidnplayr 242
        PCNET_DTBLLEN_RLEN            equ 0x0F00
243
        PCNET_DTBLLEN_TLEN            equ 0xF000
1196 hidnplayr 244
 
245
; Extended control and interrupt 2 (CSR7)
246
 
2387 hidnplayr 247
        PCNET_EXTCTL2_MIIPDTINTE      equ 0x0001
248
        PCNET_EXTCTL2_MIIPDTINT       equ 0x0002
249
        PCNET_EXTCTL2_MCCIINTE        equ 0x0004
250
        PCNET_EXTCTL2_MCCIINT         equ 0x0008
251
        PCNET_EXTCTL2_MCCINTE         equ 0x0010
252
        PCNET_EXTCTL2_MCCINT          equ 0x0020
253
        PCNET_EXTCTL2_MAPINTE         equ 0x0040
254
        PCNET_EXTCTL2_MAPINT          equ 0x0080
255
        PCNET_EXTCTL2_MREINTE         equ 0x0100
256
        PCNET_EXTCTL2_MREINT          equ 0x0200
257
        PCNET_EXTCTL2_STINTE          equ 0x0400
258
        PCNET_EXTCTL2_STINT           equ 0x0800
259
        PCNET_EXTCTL2_RXDPOLL         equ 0x1000
260
        PCNET_EXTCTL2_RDMD            equ 0x2000
261
        PCNET_EXTCTL2_RXFRTG          equ 0x4000
262
        PCNET_EXTCTL2_FASTSPNDE       equ 0x8000
1196 hidnplayr 263
 
264
; Mode (CSR15)
265
 
2387 hidnplayr 266
        PCNET_MODE_RXD                equ 0x0001  ; RX disable
267
        PCNET_MODE_TXD                equ 0x0002  ; TX disable
268
        PCNET_MODE_LOOP               equ 0x0004  ; loopback enable
269
        PCNET_MODE_TXCRCD             equ 0x0008
270
        PCNET_MODE_FORCECOLL          equ 0x0010
271
        PCNET_MODE_RETRYD             equ 0x0020
272
        PCNET_MODE_INTLOOP            equ 0x0040
273
        PCNET_MODE_PORTSEL            equ 0x0180
274
        PCNET_MODE_RXVPAD             equ 0x2000
275
        PCNET_MODE_RXNOBROAD          equ 0x4000
276
        PCNET_MODE_PROMISC            equ 0x8000
1196 hidnplayr 277
 
278
; BCR (Bus Control Registers)
279
 
2387 hidnplayr 280
        PCNET_BCR_MMRA                equ 0x00    ; Master Mode Read Active
281
        PCNET_BCR_MMW                 equ 0x01    ; Master Mode Write Active
282
        PCNET_BCR_MISCCFG             equ 0x02
283
        PCNET_BCR_LED0                equ 0x04
284
        PCNET_BCR_LED1                equ 0x05
285
        PCNET_BCR_LED2                equ 0x06
286
        PCNET_BCR_LED3                equ 0x07
287
        PCNET_BCR_DUPLEX              equ 0x09
288
        PCNET_BCR_BUSCTL              equ 0x12
289
        PCNET_BCR_EECTL               equ 0x13
290
        PCNET_BCR_SSTYLE              equ 0x14
291
        PCNET_BCR_PCILAT              equ 0x16
292
        PCNET_BCR_PCISUBVENID         equ 0x17
293
        PCNET_BCR_PCISUBSYSID         equ 0x18
294
        PCNET_BCR_SRAMSIZE            equ 0x19
295
        PCNET_BCR_SRAMBOUND           equ 0x1A
296
        PCNET_BCR_SRAMCTL             equ 0x1B
297
        PCNET_BCR_MIICTL              equ 0x20
298
        PCNET_BCR_MIIADDR             equ 0x21
299
        PCNET_BCR_MIIDATA             equ 0x22
300
        PCNET_BCR_PCIVENID            equ 0x23
301
        PCNET_BCR_PCIPCAP             equ 0x24
302
        PCNET_BCR_DATA0               equ 0x25
303
        PCNET_BCR_DATA1               equ 0x26
304
        PCNET_BCR_DATA2               equ 0x27
305
        PCNET_BCR_DATA3               equ 0x28
306
        PCNET_BCR_DATA4               equ 0x29
307
        PCNET_BCR_DATA5               equ 0x2A
308
        PCNET_BCR_DATA6               equ 0x2B
309
        PCNET_BCR_DATA7               equ 0x2C
310
        PCNET_BCR_ONNOWPAT0           equ 0x2D
311
        PCNET_BCR_ONNOWPAT1           equ 0x2E
312
        PCNET_BCR_ONNOWPAT2           equ 0x2F
313
        PCNET_BCR_PHYSEL              equ 0x31
1196 hidnplayr 314
 
315
; RX status register
316
 
2387 hidnplayr 317
        PCNET_RXSTAT_BPE              equ 0x0080  ; bus parity error
318
        PCNET_RXSTAT_ENP              equ 0x0100  ; end of packet
319
        PCNET_RXSTAT_STP              equ 0x0200  ; start of packet
320
        PCNET_RXSTAT_BUFF             equ 0x0400  ; buffer error
321
        PCNET_RXSTAT_CRC              equ 0x0800  ; CRC error
322
        PCNET_RXSTAT_OFLOW            equ 0x1000  ; rx overrun
323
        PCNET_RXSTAT_FRAM             equ 0x2000  ; framing error
324
        PCNET_RXSTAT_ERR              equ 0x4000  ; error summary
325
        PCNET_RXSTAT_OWN              equ 0x8000
1196 hidnplayr 326
 
327
; TX status register
328
 
2387 hidnplayr 329
        PCNET_TXSTAT_TRC              equ 0x0000000F      ; transmit retries
330
        PCNET_TXSTAT_RTRY             equ 0x04000000      ; retry
331
        PCNET_TXSTAT_LCAR             equ 0x08000000      ; lost carrier
332
        PCNET_TXSTAT_LCOL             equ 0x10000000      ; late collision
333
        PCNET_TXSTAT_EXDEF            equ 0x20000000      ; excessive deferrals
334
        PCNET_TXSTAT_UFLOW            equ 0x40000000      ; transmit underrun
335
        PCNET_TXSTAT_BUFF             equ 0x80000000      ; buffer error
1196 hidnplayr 336
 
2387 hidnplayr 337
        PCNET_TXCTL_OWN               equ 0x80000000
338
        PCNET_TXCTL_ERR               equ 0x40000000      ; error summary
339
        PCNET_TXCTL_ADD_FCS           equ 0x20000000      ; add FCS to pkt
340
        PCNET_TXCTL_MORE_LTINT        equ 0x10000000
341
        PCNET_TXCTL_ONE               equ 0x08000000
342
        PCNET_TXCTL_DEF               equ 0x04000000
343
        PCNET_TXCTL_STP               equ 0x02000000
344
        PCNET_TXCTL_ENP               equ 0x01000000
345
        PCNET_TXCTL_BPE               equ 0x00800000
346
        PCNET_TXCTL_MBO               equ 0x0000F000
347
        PCNET_TXCTL_BUFSZ             equ 0x00000FFF
1196 hidnplayr 348
 
349
 
350
 
1564 hidnplayr 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
 
2387 hidnplayr 368
        DEBUGF 1,"Loading PCnet driver\n"
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
399
        jl      .fail
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
 
2387 hidnplayr 411
        cmp     [IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
412
        jl      .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]
429
        cmp     ax , word [device.pci_bus]              ; compare with pci and device num in device list (notice the usage of word instead of byte)
430
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
431
        add     esi, 4
432
        loop    .nextdevice
1196 hidnplayr 433
 
434
; This device doesnt have its own eth_device structure yet, lets create one
435
 
436
  .firstdevice:
2387 hidnplayr 437
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
438
        jge     .fail
1196 hidnplayr 439
 
2387 hidnplayr 440
        allocate_and_clear ebx, device_size, .fail
1196 hidnplayr 441
 
442
; Fill in the direct call addresses into the struct
443
 
2387 hidnplayr 444
        mov     [device.reset], reset
445
        mov     [device.transmit], transmit
446
        mov     [device.get_MAC], read_mac
447
        mov     [device.set_MAC], write_mac
448
        mov     [device.unload], unload
449
        mov     [device.name], my_service
1196 hidnplayr 450
 
451
; save the pci bus and device numbers
452
 
2387 hidnplayr 453
        mov     eax, [IOCTL.input]
454
        mov     cl , [eax+1]
455
        mov     [device.pci_bus], cl
456
        mov     cl , [eax+2]
457
        mov     [device.pci_dev], cl
1196 hidnplayr 458
 
459
; Now, it's time to find the base io addres of the PCI device
460
 
2387 hidnplayr 461
        find_io [device.pci_bus], [device.pci_dev], [device.io_addr]
1196 hidnplayr 462
 
463
; We've found the io address, find IRQ now
464
 
2387 hidnplayr 465
        find_irq [device.pci_bus], [device.pci_dev], [device.irq_line]
1196 hidnplayr 466
 
2387 hidnplayr 467
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
468
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1196 hidnplayr 469
 
2387 hidnplayr 470
        allocate_and_clear [device.tx_buffer], PCNET_RX_RING_SIZE * (PCNET_PKT_BUF_SZ + buf_head.size), .err
471
        allocate_and_clear [device.rx_buffer], PCNET_TX_RING_SIZE * (PCNET_PKT_BUF_SZ + buf_head.size), .err
1196 hidnplayr 472
 
473
; Ok, the eth_device structure is ready, let's probe the device
1201 clevermous 474
; Because initialization fires IRQ, IRQ handler must be aware of this device
2387 hidnplayr 475
        mov     eax, [devices]                                        ; Add the device structure to our device list
476
        mov     [device_list+4*eax], ebx                                 ; (IRQ handler uses this list to find device)
477
        inc     [devices]                                             ;
1196 hidnplayr 478
 
2387 hidnplayr 479
        call    probe                                                   ; this function will output in eax
480
        test    eax, eax
481
        jnz     .destroy                                                        ; If an error occured, exit
1196 hidnplayr 482
 
2387 hidnplayr 483
        mov     [device.type], NET_TYPE_ETH
484
        call    NetRegDev
485
        cmp     eax, -1
486
        je      .destroy
1196 hidnplayr 487
 
2387 hidnplayr 488
        ret
1196 hidnplayr 489
 
490
; If the device was already loaded, find the device number and return it in eax
491
 
492
  .find_devicenum:
2387 hidnplayr 493
        DEBUGF  1,"Trying to find device number of already registered device\n"
494
        mov     ebx, eax
495
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
496
                                                                        ; into a device number in edi
497
        mov     eax, edi                                                ; Application wants it in eax instead
498
        DEBUGF  1,"Kernel says: %u\n", eax
499
        ret
1196 hidnplayr 500
 
501
; If an error occured, remove all allocated data and exit (returning -1 in eax)
502
 
503
  .destroy:
2387 hidnplayr 504
        ; todo: reset device into virgin state
1564 hidnplayr 505
 
2387 hidnplayr 506
        dec     [devices]
1196 hidnplayr 507
  .err:
2387 hidnplayr 508
        DEBUGF  1,"Error, removing all data !\n"
509
        stdcall KernelFree, [device.rx_buffer]
510
        stdcall KernelFree, [device.tx_buffer]
511
        stdcall KernelFree, ebx
1196 hidnplayr 512
 
513
  .fail:
2387 hidnplayr 514
        or      eax, -1
515
        ret
1196 hidnplayr 516
 
517
;------------------------------------------------------
518
endp
519
 
520
 
521
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
522
;;                                                                        ;;
523
;;        Actual Hardware dependent code starts here                      ;;
524
;;                                                                        ;;
525
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
526
 
527
align 4
528
unload:
2387 hidnplayr 529
        ; TODO: (in this particular order)
530
        ;
531
        ; - Stop the device
532
        ; - Detach int handler
533
        ; - Remove device from local list (RTL8139_LIST)
534
        ; - call unregister function in kernel
535
        ; - Remove all allocated structures and buffers the card used
1196 hidnplayr 536
 
2387 hidnplayr 537
        or      eax,-1
1196 hidnplayr 538
 
539
ret
540
 
541
 
542
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
543
;;
544
;;  probe: enables the device (if it really is a PCnet device)
545
;;
546
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
547
 
548
align 4
549
probe:
2387 hidnplayr 550
        mov     edx, [device.io_addr]
1196 hidnplayr 551
 
2387 hidnplayr 552
        call    wio_reset
1196 hidnplayr 553
 
2387 hidnplayr 554
        xor     ecx, ecx
555
        call    wio_read_csr
556
        cmp     eax, 4
557
        jne     .try_dwio
1196 hidnplayr 558
 
2387 hidnplayr 559
        ; Try Word I/O
560
        mov     ax , 88
561
        add     edx, PCNET_WIO_RAP
562
        out     dx , ax
563
        nop
564
        nop
565
        in      ax , dx
566
        sub     edx, PCNET_WIO_RAP
567
        cmp     ax , 88
568
        jne     .try_dwio
1196 hidnplayr 569
 
2387 hidnplayr 570
        call    switch_to_wio
1196 hidnplayr 571
 
2387 hidnplayr 572
        jmp     .L1
1196 hidnplayr 573
 
574
  .try_dwio:
2387 hidnplayr 575
        call    dwio_reset
1196 hidnplayr 576
 
2387 hidnplayr 577
        xor     ecx, ecx
578
        call    dwio_read_csr
579
        cmp     eax, 4
580
        jne     .no_dev
1196 hidnplayr 581
 
2387 hidnplayr 582
        ; Try Dword I/O
583
        add     edx, PCNET_DWIO_RAP
584
        mov     eax, 88
585
        out     dx , eax
586
        nop
587
        nop
588
        in      eax, dx
589
        sub     edx, PCNET_DWIO_RAP
590
        and     eax, 0xffff
591
        cmp     eax, 88
592
        jne     .no_dev
1196 hidnplayr 593
 
2387 hidnplayr 594
        call    switch_to_dwio
1196 hidnplayr 595
 
2387 hidnplayr 596
        jmp     .L1
1196 hidnplayr 597
 
598
  .no_dev:
2387 hidnplayr 599
        DEBUGF 1,"PCnet device not found!\n"
600
        mov     eax, 1
601
        ret
1564 hidnplayr 602
  .L1:
1541 hidnplayr 603
 
2387 hidnplayr 604
        mov     ecx, PCNET_CSR_CHIPID0
605
        call    [device.access_read_csr]
606
        mov     esi, eax
1196 hidnplayr 607
 
2387 hidnplayr 608
        mov     ecx, PCNET_CSR_CHIPID1
609
        call    [device.access_read_csr]
610
        shl     eax, 16
611
        or      eax, esi
1196 hidnplayr 612
 
2387 hidnplayr 613
        mov     ecx, eax
614
        and     ecx, 0xfff
615
        cmp     ecx, 3
616
        jne     .no_dev
1196 hidnplayr 617
 
2387 hidnplayr 618
        shr     eax, 12
619
        and     eax, 0xffff
620
        mov     [device.chip_version], eax
1196 hidnplayr 621
 
2387 hidnplayr 622
        DEBUGF 1,"chip version ok\n"
623
        mov     [device.fdx], 0
624
        mov     [device.mii], 0
625
        mov     [device.fset], 0
626
        mov     [device.dxsuflo], 0
627
        mov     [device.ltint], 0
1196 hidnplayr 628
 
2387 hidnplayr 629
        cmp     eax, 0x2420
630
        je      .L2
631
        cmp     eax, 0x2430
632
        je      .L2
1196 hidnplayr 633
 
2387 hidnplayr 634
        mov     [device.fdx], 1
1196 hidnplayr 635
 
2387 hidnplayr 636
        cmp     eax, 0x2621
637
        je      .L4
638
        cmp     eax, 0x2623
639
        je      .L5
640
        cmp     eax, 0x2624
641
        je      .L6
642
        cmp     eax, 0x2625
643
        je      .L7
644
        cmp     eax, 0x2626
645
        je      .L8
646
        cmp     eax, 0x2627
647
        je      .L9
1196 hidnplayr 648
 
2387 hidnplayr 649
        DEBUGF 1,"Invalid chip rev\n"
650
        jmp     .no_dev
1196 hidnplayr 651
  .L2:
2387 hidnplayr 652
        mov     [device.name], device_l2
653
        jmp     .L10
1196 hidnplayr 654
  .L4:
2387 hidnplayr 655
        mov     [device.name], device_l4
1492 hidnplayr 656
;        mov     [device.fdx], 1
2387 hidnplayr 657
        jmp     .L10
1196 hidnplayr 658
  .L5:
2387 hidnplayr 659
        mov     [device.name], device_l5
1492 hidnplayr 660
;        mov     [device.fdx], 1
2387 hidnplayr 661
        mov     [device.mii], 1
662
        mov     [device.fset], 1
663
        mov     [device.ltint], 1
664
        jmp     .L10
1196 hidnplayr 665
  .L6:
2387 hidnplayr 666
        mov     [device.name], device_l6
1492 hidnplayr 667
;        mov     [device.fdx], 1
2387 hidnplayr 668
        mov     [device.mii], 1
669
        mov     [device.fset], 1
670
        jmp     .L10
1196 hidnplayr 671
  .L7:
2387 hidnplayr 672
        mov     [device.name], device_l7
1492 hidnplayr 673
;        mov     [device.fdx], 1
2387 hidnplayr 674
        mov     [device.mii], 1
675
        jmp     .L10
1196 hidnplayr 676
  .L8:
2387 hidnplayr 677
        mov     [device.name], device_l8
1492 hidnplayr 678
;        mov     [device.fdx], 1
2387 hidnplayr 679
        mov     ecx, PCNET_CSR_RXPOLL
680
        call    dword [device.access_read_bcr]
681
        call    dword [device.access_write_bcr]
682
        jmp     .L10
1196 hidnplayr 683
  .L9:
2387 hidnplayr 684
        mov     [device.name], device_l9
1492 hidnplayr 685
;        mov     [device.fdx], 1
2387 hidnplayr 686
        mov     [device.mii], 1
1196 hidnplayr 687
  .L10:
2387 hidnplayr 688
        DEBUGF 1,"device name: %s\n",[device.name]
1196 hidnplayr 689
 
2387 hidnplayr 690
        cmp     [device.fset], 1
691
        jne     .L11
692
        mov     ecx, PCNET_BCR_BUSCTL
693
        call    [device.access_read_bcr]
694
        or      eax, 0x800
695
        call    [device.access_write_bcr]
1196 hidnplayr 696
 
2387 hidnplayr 697
        mov     ecx, PCNET_CSR_DMACTL
698
        call    [device.access_read_csr]
1564 hidnplayr 699
;        and     eax, 0xc00
700
;        or      eax, 0xc00
2387 hidnplayr 701
        mov     eax, 0xc00
702
        call    [device.access_write_csr]
1196 hidnplayr 703
 
2387 hidnplayr 704
        mov     [device.dxsuflo],1
705
        mov     [device.ltint],1
1196 hidnplayr 706
  .L11:
707
 
2387 hidnplayr 708
        make_bus_master [device.pci_bus], [device.pci_dev]
1564 hidnplayr 709
 
2387 hidnplayr 710
        mov     eax, PCNET_PORT_ASEL
711
        mov     [device.options], eax
712
        mov     [device.mode_], word 0x0003
713
        mov     [device.tlen_rlen], word (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
1196 hidnplayr 714
 
2387 hidnplayr 715
        mov     dword [device.filter], 0
716
        mov     dword [device.filter+4], 0
1196 hidnplayr 717
 
2387 hidnplayr 718
        mov     eax, PCNET_IMR
719
        mov     ecx, PCNET_CSR_IMR                      ; Write interrupt mask
720
        call    [device.access_write_csr]
1196 hidnplayr 721
 
1492 hidnplayr 722
align 4
1196 hidnplayr 723
reset:
724
 
725
; attach int handler
726
 
2387 hidnplayr 727
        movzx   eax, [device.irq_line]
728
        DEBUGF  1,"Attaching int handler to irq %x\n",eax:1
729
        stdcall AttachIntHandler, eax, int_handler, dword 0
730
        test    eax, eax
731
        jnz     @f
732
        DEBUGF  1,"\nCould not attach int handler!\n"
1196 hidnplayr 733
;        or      eax, -1
734
;        ret
735
  @@:
736
 
2387 hidnplayr 737
        mov     edx, [device.io_addr]
738
        call    [device.access_reset]
1492 hidnplayr 739
 
2387 hidnplayr 740
        ; Switch pcnet32 to 32bit mode
741
        mov     ecx, PCNET_BCR_SSTYLE
742
        mov     eax, 2
743
        call    [device.access_write_bcr]
1492 hidnplayr 744
 
2387 hidnplayr 745
        ; set/reset autoselect bit
746
        mov     ecx, PCNET_BCR_MISCCFG
747
        call    [device.access_read_bcr]
748
        and     eax,not 2
749
        test    [device.options], PCNET_PORT_ASEL
750
        jz      .L1
751
        or      eax, 2
1196 hidnplayr 752
  .L1:
2387 hidnplayr 753
        call    [device.access_write_bcr]
1196 hidnplayr 754
 
755
 
2387 hidnplayr 756
        ; Handle full duplex setting
757
        cmp     byte [device.full_duplex], 0
758
        je      .L2
759
        mov     ecx, PCNET_BCR_DUPLEX
760
        call    [device.access_read_bcr]
761
        and     eax, not 3
762
        test    [device.options], PCNET_PORT_FD
763
        jz      .L3
764
        or      eax, 1
765
        cmp     [device.options], PCNET_PORT_FD or PCNET_PORT_AUI
766
        jne     .L4
767
        or      eax, 2
768
        jmp     .L4
1196 hidnplayr 769
  .L3:
2387 hidnplayr 770
        test    [device.options], PCNET_PORT_ASEL
771
        jz      .L4
772
        cmp     [device.chip_version], 0x2627
773
        jne     .L4
774
        or      eax, 3
1196 hidnplayr 775
  .L4:
2387 hidnplayr 776
        mov     ecx, PCNET_BCR_DUPLEX
777
        call    [device.access_write_bcr]
1196 hidnplayr 778
  .L2:
779
 
780
 
2387 hidnplayr 781
        ; set/reset GPSI bit in test register
782
        mov     ecx, 124
783
        call    [device.access_read_csr]
784
        mov     ecx, [device.options]
785
        and     ecx, PCNET_PORT_PORTSEL
786
        cmp     ecx, PCNET_PORT_GPSI
787
        jne     .L5
788
        or      eax, 0x10
1196 hidnplayr 789
  .L5:
2387 hidnplayr 790
        call    [device.access_write_csr]
791
        cmp     [device.mii], 0
792
        je      .L6
793
        test    [device.options], PCNET_PORT_ASEL
794
        jnz     .L6
795
        mov     ecx, PCNET_BCR_MIICTL
796
        call    [device.access_read_bcr]
797
        and     eax,not 0x38
798
        test    [device.options], PCNET_PORT_FD
799
        jz      .L7
800
        or      eax, 0x10
1196 hidnplayr 801
  .L7:
2387 hidnplayr 802
        test    [device.options], PCNET_PORT_100
803
        jz      .L8
804
        or      eax, 0x08
1196 hidnplayr 805
  .L8:
2387 hidnplayr 806
        call    [device.access_write_bcr]
807
        jmp     .L9
1196 hidnplayr 808
.L6:
2387 hidnplayr 809
        test    [device.options], PCNET_PORT_ASEL
810
        jz      .L9
811
        mov     ecx, PCNET_BCR_MIICTL
812
        DEBUGF 1,"ASEL, enable auto-negotiation\n"
813
        call    [device.access_read_bcr]
814
        and     eax, not 0x98
815
        or      eax, 0x20
816
        call    [device.access_write_bcr]
1196 hidnplayr 817
.L9:
2387 hidnplayr 818
        cmp     [device.ltint],0
819
        je      .L10
820
        mov     ecx,5
821
        call    [device.access_read_csr]
822
        or      eax,(1 shl 14)
823
        call    [device.access_write_csr]
1196 hidnplayr 824
.L10:
2387 hidnplayr 825
        mov     eax,[device.options]
826
        and     eax,PCNET_PORT_PORTSEL
827
        shl     eax,7
828
        mov     [device.mode_],ax
829
        mov     dword [device.filter], -1
830
        mov     dword [device.filter+4], -1
1196 hidnplayr 831
 
2387 hidnplayr 832
        call    read_mac
1196 hidnplayr 833
 
2387 hidnplayr 834
        lea     esi, [device.mac]
835
        lea     edi, [device.phys_addr]
836
        movsd
837
        movsw
1201 clevermous 838
 
2387 hidnplayr 839
        call    init_ring
1564 hidnplayr 840
 
2387 hidnplayr 841
        lea     eax, [device.private]
842
        GetRealAddr
1564 hidnplayr 843
 
2387 hidnplayr 844
        push    eax
845
        and     eax, 0xffff
846
        mov     ecx, 1
847
        call    [device.access_write_csr]
848
        pop     eax
849
        shr     eax,16
850
        mov     ecx,2
851
        call    [device.access_write_csr]
1196 hidnplayr 852
 
2387 hidnplayr 853
        mov     ecx,4
854
        mov     eax,0x0915
855
        call    [device.access_write_csr]
1196 hidnplayr 856
 
2387 hidnplayr 857
        mov     ecx,0
858
        mov     eax,1
859
        call    [device.access_write_csr]
1196 hidnplayr 860
 
2387 hidnplayr 861
        mov     [device.tx_full],0
862
        mov     [device.cur_rx],0
863
        mov     [device.cur_tx],0
864
        mov     [device.dirty_rx],0
865
        mov     [device.dirty_tx],0
1196 hidnplayr 866
 
2387 hidnplayr 867
        mov     ecx,100
1196 hidnplayr 868
.L11:
2387 hidnplayr 869
        push    ecx
870
        xor     ecx,ecx
871
        call    [device.access_read_csr]
872
        pop     ecx
873
        test    ax,0x100
874
        jnz     .L12
875
        loop    .L11
1196 hidnplayr 876
.L12:
877
 
2387 hidnplayr 878
        DEBUGF 1,"hardware reset\n"
879
        xor     ecx, ecx
880
        mov     eax, 0x0002
881
        call    [device.access_write_csr]
1196 hidnplayr 882
 
2387 hidnplayr 883
        xor     ecx, ecx
884
        call    [device.access_read_csr]
1196 hidnplayr 885
 
2387 hidnplayr 886
        xor     ecx, ecx
887
        mov     eax, PCNET_CSR_INTEN or PCNET_CSR_START
888
        call    [device.access_write_csr]
1196 hidnplayr 889
 
1564 hidnplayr 890
; Set the mtu, kernel will be able to send now
2387 hidnplayr 891
        mov     [device.mtu], 1514
1564 hidnplayr 892
 
2387 hidnplayr 893
        DEBUGF 1,"PCNET reset complete\n"
894
        xor     eax, eax
895
        ret
1492 hidnplayr 896
 
1519 hidnplayr 897
 
1564 hidnplayr 898
align 4
899
init_ring:
900
 
2387 hidnplayr 901
        mov     ecx, PCNET_RX_RING_SIZE
902
        mov     edi, [device.rx_buffer]
903
        mov     eax, edi
904
        GetRealAddr
905
        mov     [device.rx_ring_phys], eax
906
        add     eax, PCNET_RX_RING_SIZE * buf_head.size
1564 hidnplayr 907
  .rx_init:
2387 hidnplayr 908
        mov     [edi + buf_head.base], eax
909
        mov     [edi + buf_head.length], PCNET_PKT_BUF_SZ_NEG
910
        mov     [edi + buf_head.status], 0x8000
911
        and     dword [edi + buf_head.msg_length], 0
912
        and     dword [edi + buf_head.reserved], 0
913
        add     eax, PCNET_PKT_BUF_SZ
914
        add     edi, buf_head.size
915
        loop    .rx_init
1564 hidnplayr 916
 
2387 hidnplayr 917
        mov     ecx, PCNET_TX_RING_SIZE
918
        mov     edi, [device.tx_buffer]
919
        mov     eax, edi
920
        GetRealAddr
921
        mov     [device.tx_ring_phys], eax
922
        add     eax, PCNET_TX_RING_SIZE * buf_head.size
1564 hidnplayr 923
  .tx_init:
2387 hidnplayr 924
        mov     [edi + buf_head.base], eax
925
        and     dword [edi + buf_head.length], 0
926
        and     dword [edi + buf_head.msg_length], 0
927
        and     dword [edi + buf_head.reserved], 0
928
        add     eax, PCNET_PKT_BUF_SZ
929
        add     edi, buf_head.size
930
        loop    .tx_init
1564 hidnplayr 931
 
2387 hidnplayr 932
        mov     [device.tlen_rlen], (PCNET_TX_RING_LEN_BITS or PCNET_RX_RING_LEN_BITS)
1564 hidnplayr 933
 
2387 hidnplayr 934
        ret
1196 hidnplayr 935
 
936
 
937
 
938
 
939
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
940
;;                                         ;;
941
;; Transmit                                ;;
942
;;                                         ;;
1263 clevermous 943
;; In: buffer pointer in [esp+4]           ;;
1254 hidnplayr 944
;;     size of buffer in [esp+8]           ;;
1196 hidnplayr 945
;;     pointer to device structure in ebx  ;;
946
;;                                         ;;
947
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
948
 
949
align 4
950
transmit:
2387 hidnplayr 951
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
952
        mov     eax, [esp+4]
953
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
954
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
955
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
956
        [eax+13]:2,[eax+12]:2
1196 hidnplayr 957
 
2387 hidnplayr 958
        cmp     dword [esp+8], 1514
959
        jg      .nospace                        ; packet is too long
960
        cmp     dword [esp+8], 60
961
        jl      .nospace                        ; packet is too short
1196 hidnplayr 962
 
963
; check descriptor
2387 hidnplayr 964
        movzx   eax, [device.cur_tx]
965
        imul    edi, eax, PCNET_PKT_BUF_SZ
966
        shl     eax, 4
967
        add     eax, [device.tx_buffer]
968
        add     edi, [device.tx_buffer]
969
        add     edi, PCNET_TX_RING_SIZE * buf_head.size
1541 hidnplayr 970
 
2387 hidnplayr 971
        test    byte [eax + buf_head.status + 1], 80h
972
        jnz     .nospace
1201 clevermous 973
; descriptor is free, copy data
2387 hidnplayr 974
        mov     esi, [esp+4]
975
        mov     ecx, [esp+8]
976
        mov     edx, ecx
977
        shr     ecx, 2
978
        and     edx, 3
979
        rep     movsd
980
        mov     ecx, edx
981
        rep     movsb
1201 clevermous 982
; set length
2387 hidnplayr 983
        mov     ecx, [esp+8]
984
        neg     ecx
985
        mov     [eax + buf_head.length], cx
1201 clevermous 986
; put to transfer queue
2387 hidnplayr 987
        mov     [eax + buf_head.status], 0x8300
1196 hidnplayr 988
 
989
; trigger an immediate send
2387 hidnplayr 990
        xor     ecx, ecx         ; CSR0
991
        call    [device.access_read_csr]
992
        or      eax, PCNET_CSR_TX
993
        call    [device.access_write_csr]
1196 hidnplayr 994
 
995
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
2387 hidnplayr 996
        inc     [device.cur_tx]
997
        and     [device.cur_tx], 3
998
        DEBUGF  2," - Packet Sent! "
1196 hidnplayr 999
 
1000
.finish:
2387 hidnplayr 1001
        DEBUGF  2," - Done!\n"
1002
        stdcall KernelFree, [esp+4]
1003
        xor     eax, eax
1004
        ret     8
1196 hidnplayr 1005
 
1201 clevermous 1006
.nospace:
2387 hidnplayr 1007
        DEBUGF  1, 'ERROR: no free transmit descriptors\n'
1008
        stdcall KernelFree, [esp+4]
1009
        or      eax, -1
1010
        ret     8
1196 hidnplayr 1011
 
1012
 
1013
 
1014
;;;;;;;;;;;;;;;;;;;;;;;
1015
;;                   ;;
1016
;; Interrupt handler ;;
1017
;;                   ;;
1018
;;;;;;;;;;;;;;;;;;;;;;;
1019
 
1020
align 4
1021
int_handler:
1022
 
1564 hidnplayr 1023
;       DEBUGF  1,"IRQ %x ",eax:2                   ; no, you cant replace 'eax:2' with 'al', this must be a bug in FDO
1196 hidnplayr 1024
 
1025
; find pointer of device wich made IRQ occur
1026
 
2387 hidnplayr 1027
        mov     esi, device_list
1028
        mov     ecx, [devices]
1029
        test    ecx, ecx
1030
        jz      .abort
1196 hidnplayr 1031
  .nextdevice:
2387 hidnplayr 1032
        mov     ebx, dword [esi]
1033
        mov     edx, [device.io_addr]     ; get IRQ reason
1196 hidnplayr 1034
 
2387 hidnplayr 1035
        push    ecx
1036
        xor     ecx, ecx ; CSR0
1037
        call    [device.access_read_csr]
1038
        pop     ecx
1196 hidnplayr 1039
 
2387 hidnplayr 1040
        test    al , al
1041
        js      .got_it
1196 hidnplayr 1042
 
2387 hidnplayr 1043
        add     esi, 4
1044
        loop    .nextdevice
1196 hidnplayr 1045
 
2387 hidnplayr 1046
        ret                                         ; If no device was found, abort (The irq was probably for a device, not registered to this driver
1196 hidnplayr 1047
 
1048
  .got_it:
1049
;-------------------------------------------------------
1201 clevermous 1050
; Possible reasons:
1051
; initialization done - ignore
1052
; transmit done - ignore
1053
; packet received - handle
1054
; Clear ALL IRQ reasons.
1055
; N.B. One who wants to handle more than one reason must be ready
1056
; to two or more reasons in one IRQ.
2387 hidnplayr 1057
        xor     ecx, ecx
1058
        call    [device.access_write_csr]
1196 hidnplayr 1059
; Received packet ok?
1060
 
2387 hidnplayr 1061
        test    ax, PCNET_CSR_RINT
1062
        jz      @f
1196 hidnplayr 1063
 
1564 hidnplayr 1064
.receiver_test_loop:
2387 hidnplayr 1065
        movzx   eax, [device.cur_rx]
1564 hidnplayr 1066
;        and     eax, PCNET_RX_RING_MOD_MASK
2387 hidnplayr 1067
        mov     edi, eax
1196 hidnplayr 1068
 
2387 hidnplayr 1069
        imul    esi, eax, PCNET_PKT_BUF_SZ      ;
1070
        add     esi, [device.rx_buffer]         ; esi now points to rx buffer
1071
        add     esi, PCNET_RX_RING_SIZE * buf_head.size
1196 hidnplayr 1072
 
2387 hidnplayr 1073
        shl     edi, 4                          ; desc * 16 (16 is size of one ring entry)
1074
        add     edi, [device.rx_buffer]     ; edi now points to current rx ring entry
1196 hidnplayr 1075
 
2387 hidnplayr 1076
        mov     cx , [edi + buf_head.status]
1196 hidnplayr 1077
 
2387 hidnplayr 1078
        test    cx , PCNET_RXSTAT_OWN           ; If this bit is set, the controller OWN's the packet, if not, we do
1079
        jnz     .abort
1196 hidnplayr 1080
 
2387 hidnplayr 1081
        test    cx , PCNET_RXSTAT_ENP
1082
        jz      .abort
1196 hidnplayr 1083
 
2387 hidnplayr 1084
        test    cx , PCNET_RXSTAT_STP
1085
        jz      .abort
1196 hidnplayr 1086
 
2387 hidnplayr 1087
        movzx   ecx, [edi + buf_head.msg_length]        ; get packet length in ecx
1088
        sub     ecx, 4                          ;
1196 hidnplayr 1089
 
2387 hidnplayr 1090
        push    ecx
1091
        stdcall KernelAlloc, ecx                ; Allocate a buffer to put packet into
1092
        pop     ecx
1093
        test    eax, eax                        ; Test if we allocated succesfully
1094
        jz      .abort                          ;
1196 hidnplayr 1095
 
2387 hidnplayr 1096
        push    .receiver_test_loop             ;
1097
        push    ecx                             ; for eth_receiver
1098
        push    eax                             ;
1196 hidnplayr 1099
 
2387 hidnplayr 1100
        xchg    edi, eax
1101
        push    ecx
1102
        shr     ecx, 2
1103
        cld
1104
        rep     movsd
1105
        pop     ecx
1106
        and     ecx, 3
1107
        rep     movsb
1196 hidnplayr 1108
 
1564 hidnplayr 1109
;       mov     word [eax + buf_head.length], PCNET_PKT_BUF_SZ_NEG
2387 hidnplayr 1110
        mov     word [eax + buf_head.status], PCNET_RXSTAT_OWN      ; Set OWN bit back to 1 (controller may write to tx-buffer again now)
1196 hidnplayr 1111
 
2387 hidnplayr 1112
        inc     [device.cur_rx]           ; update descriptor
1113
        and     [device.cur_rx], 3        ;
1196 hidnplayr 1114
 
2387 hidnplayr 1115
        jmp     EthReceiver                     ; Send the copied packet to kernel
1196 hidnplayr 1116
 
1117
  .abort:
1118
 
1541 hidnplayr 1119
  @@:
1120
 
2387 hidnplayr 1121
        ret
1196 hidnplayr 1122
 
1123
 
1124
 
1125
 
1126
;;;;;;;;;;;;;;;;;;;;;;;
1127
;;                   ;;
1128
;; Write MAC address ;;
1129
;;                   ;;
1130
;;;;;;;;;;;;;;;;;;;;;;;
1131
 
1132
align 4
2387 hidnplayr 1133
write_mac:      ; in: mac pushed onto stack (as 3 words)
1196 hidnplayr 1134
 
2387 hidnplayr 1135
        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 1136
 
2387 hidnplayr 1137
        mov     edx, [device.io_addr]
1138
        add     dx, 2
1139
        xor     eax, eax
1564 hidnplayr 1140
 
2387 hidnplayr 1141
        mov     ecx, PCNET_CSR_PAR0
1196 hidnplayr 1142
       @@:
2387 hidnplayr 1143
        pop     ax
1144
        call    [device.access_write_csr]
1145
        DEBUGF  1,"."
1146
        inc     ecx
1147
        cmp     ecx, PCNET_CSR_PAR2
1148
        jl      @r
1196 hidnplayr 1149
 
2387 hidnplayr 1150
        DEBUGF  1,"\n"
1196 hidnplayr 1151
 
1152
; Notice this procedure does not ret, but continues to read_mac instead.
1153
 
1154
;;;;;;;;;;;;;;;;;;;;;;
1155
;;                  ;;
1156
;; Read MAC address ;;
1157
;;                  ;;
1158
;;;;;;;;;;;;;;;;;;;;;;
1564 hidnplayr 1159
align 4
1492 hidnplayr 1160
read_mac:
2387 hidnplayr 1161
        DEBUGF  1,"Reading MAC"
1196 hidnplayr 1162
 
2387 hidnplayr 1163
        mov     edx, [device.io_addr]
1164
        add     dx, 6
1196 hidnplayr 1165
       @@:
2387 hidnplayr 1166
        dec     dx
1167
        dec     dx
1168
        in      ax, dx
1169
        push    ax
1170
        DEBUGF  1,"."
1171
        cmp     edx, [device.io_addr]
1172
        jg      @r
1196 hidnplayr 1173
 
2387 hidnplayr 1174
        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 1175
 
2387 hidnplayr 1176
        lea     edi, [device.mac]
1177
        pop     ax
1178
        stosw
1179
        pop     ax
1180
        stosw
1181
        pop     ax
1182
        stosw
1196 hidnplayr 1183
 
2387 hidnplayr 1184
        ret
1196 hidnplayr 1185
 
1564 hidnplayr 1186
align 4
1196 hidnplayr 1187
switch_to_wio:
1188
 
2387 hidnplayr 1189
        DEBUGF  1,"Switching to 16-bit mode\n"
1564 hidnplayr 1190
 
2387 hidnplayr 1191
        mov     [device.access_read_csr], wio_read_csr
1192
        mov     [device.access_write_csr], wio_write_csr
1193
        mov     [device.access_read_bcr], wio_read_bcr
1194
        mov     [device.access_write_bcr], wio_write_bcr
1195
        mov     [device.access_read_rap], wio_read_rap
1196
        mov     [device.access_write_rap], wio_write_rap
1197
        mov     [device.access_reset], wio_reset
1196 hidnplayr 1198
 
2387 hidnplayr 1199
        ret
1196 hidnplayr 1200
 
1564 hidnplayr 1201
align 4
1196 hidnplayr 1202
switch_to_dwio:
1203
 
2387 hidnplayr 1204
        DEBUGF  1,"Switching to 32-bit mode\n"
1564 hidnplayr 1205
 
2387 hidnplayr 1206
        mov     [device.access_read_csr], dwio_read_csr
1207
        mov     [device.access_write_csr], dwio_write_csr
1208
        mov     [device.access_read_bcr], dwio_read_bcr
1209
        mov     [device.access_write_bcr], dwio_write_bcr
1210
        mov     [device.access_read_rap], dwio_read_rap
1211
        mov     [device.access_write_rap], dwio_write_rap
1212
        mov     [device.access_reset], dwio_reset
1196 hidnplayr 1213
 
2387 hidnplayr 1214
        ret
1196 hidnplayr 1215
 
1216
 
1217
; ecx - index
1218
; return:
1219
; eax - data
1564 hidnplayr 1220
align 4
1196 hidnplayr 1221
wio_read_csr:
1222
 
2387 hidnplayr 1223
        add     edx, PCNET_WIO_RAP
1224
        mov     ax , cx
1225
        out     dx , ax
1226
        add     edx, PCNET_WIO_RDP - PCNET_WIO_RAP
1227
        in      ax , dx
1228
        and     eax, 0xffff
1229
        sub     edx, PCNET_WIO_RDP
1196 hidnplayr 1230
 
2387 hidnplayr 1231
        ret
1196 hidnplayr 1232
 
1233
 
1234
; eax - data
1235
; ecx - index
1564 hidnplayr 1236
align 4
1196 hidnplayr 1237
wio_write_csr:
1238
 
2387 hidnplayr 1239
        add     edx, PCNET_WIO_RAP
1240
        xchg    eax, ecx
1241
        out     dx , ax
1242
        xchg    eax, ecx
1243
        add     edx, PCNET_WIO_RDP - PCNET_WIO_RAP
1244
        out     dx , ax
1245
        sub     edx, PCNET_WIO_RDP
1196 hidnplayr 1246
 
2387 hidnplayr 1247
        ret
1196 hidnplayr 1248
 
1249
 
1250
; ecx - index
1251
; return:
1252
; eax - data
1564 hidnplayr 1253
align 4
1196 hidnplayr 1254
wio_read_bcr:
1255
 
2387 hidnplayr 1256
        add     edx, PCNET_WIO_RAP
1257
        mov     ax , cx
1258
        out     dx , ax
1259
        add     edx, PCNET_WIO_BDP - PCNET_WIO_RAP
1260
        in      ax , dx
1261
        and     eax, 0xffff
1262
        sub     edx, PCNET_WIO_BDP
1196 hidnplayr 1263
 
2387 hidnplayr 1264
        ret
1196 hidnplayr 1265
 
1266
 
1267
; eax - data
1268
; ecx - index
1564 hidnplayr 1269
align 4
1196 hidnplayr 1270
wio_write_bcr:
1271
 
2387 hidnplayr 1272
        add     edx, PCNET_WIO_RAP
1273
        xchg    eax, ecx
1274
        out     dx , ax
1275
        xchg    eax, ecx
1276
        add     edx, PCNET_WIO_BDP - PCNET_WIO_RAP
1277
        out     dx , ax
1278
        sub     edx, PCNET_WIO_BDP
1196 hidnplayr 1279
 
2387 hidnplayr 1280
        ret
1196 hidnplayr 1281
 
1564 hidnplayr 1282
align 4
1196 hidnplayr 1283
wio_read_rap:
1284
 
2387 hidnplayr 1285
        add     edx, PCNET_WIO_RAP
1286
        in      ax , dx
1287
        and     eax, 0xffff
1288
        sub     edx, PCNET_WIO_RAP
1196 hidnplayr 1289
 
2387 hidnplayr 1290
        ret
1196 hidnplayr 1291
 
1292
; eax - val
1564 hidnplayr 1293
align 4
1196 hidnplayr 1294
wio_write_rap:
1295
 
2387 hidnplayr 1296
        add     edx, PCNET_WIO_RAP
1297
        out     dx , ax
1298
        sub     edx, PCNET_WIO_RAP
1196 hidnplayr 1299
 
2387 hidnplayr 1300
        ret
1196 hidnplayr 1301
 
1564 hidnplayr 1302
align 4
1196 hidnplayr 1303
wio_reset:
1304
 
2387 hidnplayr 1305
        push    eax
1306
        add     edx, PCNET_WIO_RESET
1307
        in      ax , dx
1308
        pop     eax
1309
        sub     edx, PCNET_WIO_RESET
1196 hidnplayr 1310
 
2387 hidnplayr 1311
        ret
1196 hidnplayr 1312
 
1313
 
1564 hidnplayr 1314
 
1196 hidnplayr 1315
; ecx - index
1316
; return:
1317
; eax - data
1564 hidnplayr 1318
align 4
1196 hidnplayr 1319
dwio_read_csr:
1320
 
2387 hidnplayr 1321
        add     edx, PCNET_DWIO_RAP
1322
        mov     eax, ecx
1323
        out     dx , eax
1324
        add     edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
1325
        in      eax, dx
1326
        and     eax, 0xffff
1327
        sub     edx, PCNET_DWIO_RDP
1196 hidnplayr 1328
 
2387 hidnplayr 1329
        ret
1196 hidnplayr 1330
 
1331
 
1332
; ecx - index
1333
; eax - data
1564 hidnplayr 1334
align 4
1196 hidnplayr 1335
dwio_write_csr:
1336
 
2387 hidnplayr 1337
        add     edx, PCNET_DWIO_RAP
1338
        xchg    eax, ecx
1339
        out     dx , eax
1340
        add     edx, PCNET_DWIO_RDP - PCNET_DWIO_RAP
1341
        xchg    eax, ecx
1342
        out     dx , eax
1343
        sub     edx, PCNET_DWIO_RDP
1196 hidnplayr 1344
 
2387 hidnplayr 1345
        ret
1196 hidnplayr 1346
 
1347
; ecx - index
1348
; return:
1349
; eax - data
1564 hidnplayr 1350
align 4
1196 hidnplayr 1351
dwio_read_bcr:
1352
 
2387 hidnplayr 1353
        add     edx, PCNET_DWIO_RAP
1354
        mov     eax, ecx
1355
        out     dx , eax
1356
        add     edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
1357
        in      eax, dx
1358
        and     eax, 0xffff
1359
        sub     edx, PCNET_DWIO_BDP
1196 hidnplayr 1360
 
2387 hidnplayr 1361
        ret
1196 hidnplayr 1362
 
1363
 
1364
; ecx - index
1365
; eax - data
1564 hidnplayr 1366
align 4
1196 hidnplayr 1367
dwio_write_bcr:
1368
 
2387 hidnplayr 1369
        add     edx, PCNET_DWIO_RAP
1370
        xchg    eax, ecx
1371
        out     dx , eax
1372
        add     edx, PCNET_DWIO_BDP - PCNET_DWIO_RAP
1373
        xchg    eax, ecx
1374
        out     dx , eax
1375
        sub     edx, PCNET_DWIO_BDP
1196 hidnplayr 1376
 
2387 hidnplayr 1377
        ret
1196 hidnplayr 1378
 
1564 hidnplayr 1379
align 4
1196 hidnplayr 1380
dwio_read_rap:
1381
 
2387 hidnplayr 1382
        add     edx, PCNET_DWIO_RAP
1383
        in      eax, dx
1384
        and     eax, 0xffff
1385
        sub     edx, PCNET_DWIO_RAP
1196 hidnplayr 1386
 
2387 hidnplayr 1387
        ret
1196 hidnplayr 1388
 
1389
 
1390
; eax - val
1564 hidnplayr 1391
align 4
1196 hidnplayr 1392
dwio_write_rap:
1393
 
2387 hidnplayr 1394
        add     edx, PCNET_DWIO_RAP
1395
        out     dx , eax
1396
        sub     edx, PCNET_DWIO_RAP
1196 hidnplayr 1397
 
2387 hidnplayr 1398
        ret
1196 hidnplayr 1399
 
1564 hidnplayr 1400
align 4
1196 hidnplayr 1401
dwio_reset:
1402
 
2387 hidnplayr 1403
        push    eax
1404
        add     edx, PCNET_DWIO_RESET
1405
        in      eax, dx
1406
        pop     eax
1407
        sub     edx, PCNET_DWIO_RESET
1196 hidnplayr 1408
 
2387 hidnplayr 1409
        ret
1196 hidnplayr 1410
 
1411
 
1412
 
1413
; End of code
1414
 
2387 hidnplayr 1415
align 4                                       ; Place all initialised data here
1196 hidnplayr 1416
 
1564 hidnplayr 1417
devices     dd 0
1418
version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
2387 hidnplayr 1419
my_service    db 'PCnet',0                    ; max 16 chars include zero
1564 hidnplayr 1420
 
1196 hidnplayr 1421
device_l2     db "PCnet/PCI 79C970",0
1422
device_l4     db "PCnet/PCI II 79C970A",0
1423
device_l5     db "PCnet/FAST 79C971",0
1424
device_l6     db "PCnet/FAST+ 79C972",0
1425
device_l7     db "PCnet/FAST III 79C973",0
1426
device_l8     db "PCnet/Home 79C978",0
1427
device_l9     db "PCnet/FAST III 79C975",0
1428
 
1429
options_mapping:
2387 hidnplayr 1430
dd PCNET_PORT_ASEL                                      ;  0 Auto-select
1431
dd PCNET_PORT_AUI                                       ;  1 BNC/AUI
1432
dd PCNET_PORT_AUI                                       ;  2 AUI/BNC
1433
dd PCNET_PORT_ASEL                                      ;  3 not supported
1434
dd PCNET_PORT_10BT or PCNET_PORT_FD                     ;  4 10baseT-FD
1435
dd PCNET_PORT_ASEL                                      ;  5 not supported
1436
dd PCNET_PORT_ASEL                                      ;  6 not supported
1437
dd PCNET_PORT_ASEL                                      ;  7 not supported
1438
dd PCNET_PORT_ASEL                                      ;  8 not supported
1439
dd PCNET_PORT_MII                                       ;  9 MII 10baseT
1440
dd PCNET_PORT_MII or PCNET_PORT_FD                      ; 10 MII 10baseT-FD
1441
dd PCNET_PORT_MII                                       ; 11 MII (autosel)
1442
dd PCNET_PORT_10BT                                      ; 12 10BaseT
1443
dd PCNET_PORT_MII or PCNET_PORT_100                     ; 13 MII 100BaseTx
1444
dd PCNET_PORT_MII or PCNET_PORT_100 or PCNET_PORT_FD    ; 14 MII 100BaseTx-FD
1445
dd PCNET_PORT_ASEL                                      ; 15 not supported
1196 hidnplayr 1446
 
2387 hidnplayr 1447
include_debug_strings                                   ; All data wich FDO uses will be included here
1196 hidnplayr 1448
 
2387 hidnplayr 1449
section '.data' data readable writable align 16         ; place all uninitialized data place here
1196 hidnplayr 1450
 
2387 hidnplayr 1451
device_list rd MAX_DEVICES                                 ; This list contains all pointers to device structures the driver is handling