Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1886 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3155 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
1886 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  R6040 driver for KolibriOS                                     ;;
7
;;                                                                 ;;
8
;;  based on R6040.c from linux                                    ;;
9
;;                                                                 ;;
10
;;    Written by Asper (asper.85@mail.ru)                          ;;
11
;;            and hidnplayr (hidnplayr@gmail.com)                  ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
18
format MS COFF
19
 
2852 hidnplayr 20
        API_VERSION             =   0x01000100
21
        DRIVER_VERSION          =   5
1886 hidnplayr 22
 
2852 hidnplayr 23
        MAX_DEVICES             =   16
1886 hidnplayr 24
 
2852 hidnplayr 25
        DEBUG                   =   1
26
        __DEBUG__               =   1
27
        __DEBUG_LEVEL__         =   2
1886 hidnplayr 28
 
2852 hidnplayr 29
        W_MAX_TIMEOUT           =   0x0FFF      ; max time out delay time
1893 hidnplayr 30
 
2852 hidnplayr 31
        TX_TIMEOUT              =   6000        ; Time before concluding the transmitter is hung, in ms
1893 hidnplayr 32
 
2852 hidnplayr 33
        TX_RING_SIZE            =   4           ; RING sizes must be a power of 2
34
        RX_RING_SIZE            =   4
1886 hidnplayr 35
 
2852 hidnplayr 36
        RX_BUF_LEN_IDX          =   3           ; 0==8K, 1==16K, 2==32K, 3==64K
1886 hidnplayr 37
 
1893 hidnplayr 38
; Threshold is bytes transferred to chip before transmission starts.
39
 
2852 hidnplayr 40
        TX_FIFO_THRESH          =   256         ; In bytes, rounded down to 32 byte units.
1893 hidnplayr 41
 
42
; The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024.
43
 
2852 hidnplayr 44
        RX_FIFO_THRESH          =   4           ; Rx buffer level before first PCI xfer.
45
        RX_DMA_BURST            =   4           ; Maximum PCI burst, '4' is 256 bytes
46
        TX_DMA_BURST            =   4
1893 hidnplayr 47
 
48
 
49
 
1886 hidnplayr 50
include 'proc32.inc'
51
include 'imports.inc'
52
include 'fdo.inc'
53
include 'netdrv.inc'
54
 
55
public START
56
public service_proc
57
public version
58
 
1893 hidnplayr 59
; Operational parameters that usually are not changed.
1886 hidnplayr 60
 
2852 hidnplayr 61
PHY1_ADDR       =   1       ;For MAC1
62
PHY2_ADDR       =   3       ;For MAC2
63
PHY_MODE        =   0x3100  ;PHY CHIP Register 0
64
PHY_CAP         =   0x01E1  ;PHY CHIP Register 4
1886 hidnplayr 65
 
66
;**************************************************************************
67
; RDC R6040 Register Definitions
68
;**************************************************************************
2852 hidnplayr 69
MCR0            =   0x00    ;Control register 0
70
MCR1            =   0x01    ;Control register 1
71
MAC_RST         =   0x0001  ;Reset the MAC
72
MBCR            =   0x08    ;Bus control
73
MT_ICR          =   0x0C    ;TX interrupt control
74
MR_ICR          =   0x10    ;RX interrupt control
75
MTPR            =   0x14    ;TX poll command register
76
MR_BSR          =   0x18    ;RX buffer size
77
MR_DCR          =   0x1A    ;RX descriptor control
78
MLSR            =   0x1C    ;Last status
79
MMDIO           =   0x20    ;MDIO control register
80
MDIO_WRITE      =   0x4000  ;MDIO write
81
MDIO_READ       =   0x2000  ;MDIO read
82
MMRD            =   0x24    ;MDIO read data register
83
MMWD            =   0x28    ;MDIO write data register
84
MTD_SA0         =   0x2C    ;TX descriptor start address 0
85
MTD_SA1         =   0x30    ;TX descriptor start address 1
86
MRD_SA0         =   0x34    ;RX descriptor start address 0
87
MRD_SA1         =   0x38    ;RX descriptor start address 1
88
MISR            =   0x3C    ;Status register
89
MIER            =   0x40    ;INT enable register
90
MSK_INT         =   0x0000  ;Mask off interrupts
91
RX_FINISH       =   0x0001  ;RX finished
92
RX_NO_DESC      =   0x0002  ;No RX descriptor available
93
RX_FIFO_FULL    =   0x0004  ;RX FIFO full
94
RX_EARLY        =   0x0008  ;RX early
95
TX_FINISH       =   0x0010  ;TX finished
96
TX_EARLY        =   0x0080  ;TX early
97
EVENT_OVRFL     =   0x0100  ;Event counter overflow
98
LINK_CHANGED    =   0x0200  ;PHY link changed
99
ME_CISR         =   0x44    ;Event counter INT status
100
ME_CIER         =   0x48    ;Event counter INT enable
101
MR_CNT          =   0x50    ;Successfully received packet counter
102
ME_CNT0         =   0x52    ;Event counter 0
103
ME_CNT1         =   0x54    ;Event counter 1
104
ME_CNT2         =   0x56    ;Event counter 2
105
ME_CNT3         =   0x58    ;Event counter 3
106
MT_CNT          =   0x5A    ;Successfully transmit packet counter
107
ME_CNT4         =   0x5C    ;Event counter 4
108
MP_CNT          =   0x5E    ;Pause frame counter register
109
MAR0            =   0x60    ;Hash table 0
110
MAR1            =   0x62    ;Hash table 1
111
MAR2            =   0x64    ;Hash table 2
112
MAR3            =   0x66    ;Hash table 3
113
MID_0L          =   0x68    ;Multicast address MID0 Low
114
MID_0M          =   0x6A    ;Multicast address MID0 Medium
115
MID_0H          =   0x6C    ;Multicast address MID0 High
116
MID_1L          =   0x70    ;MID1 Low
117
MID_1M          =   0x72    ;MID1 Medium
118
MID_1H          =   0x74    ;MID1 High
119
MID_2L          =   0x78    ;MID2 Low
120
MID_2M          =   0x7A    ;MID2 Medium
121
MID_2H          =   0x7C    ;MID2 High
122
MID_3L          =   0x80    ;MID3 Low
123
MID_3M          =   0x82    ;MID3 Medium
124
MID_3H          =   0x84    ;MID3 High
125
PHY_CC          =   0x88    ;PHY status change configuration register
126
PHY_ST          =   0x8A    ;PHY status register
127
MAC_SM          =   0xAC    ;MAC status machine
128
MAC_ID          =   0xBE    ;Identifier register
1893 hidnplayr 129
 
2852 hidnplayr 130
MAX_BUF_SIZE    =   0x600   ;1536
1886 hidnplayr 131
 
2852 hidnplayr 132
MBCR_DEFAULT    =   0x012A  ;MAC Bus Control Register
133
MCAST_MAX       =   3       ;Max number multicast addresses to filter
1886 hidnplayr 134
 
135
;Descriptor status
2852 hidnplayr 136
DSC_OWNER_MAC   =   0x8000  ;MAC is the owner of this descriptor
137
DSC_RX_OK       =   0x4000  ;RX was successfull
138
DSC_RX_ERR      =   0x0800  ;RX PHY error
139
DSC_RX_ERR_DRI  =   0x0400  ;RX dribble packet
140
DSC_RX_ERR_BUF  =   0x0200  ;RX length exceeds buffer size
141
DSC_RX_ERR_LONG =   0x0100  ;RX length > maximum packet length
142
DSC_RX_ERR_RUNT =   0x0080  ;RX packet length < 64 byte
143
DSC_RX_ERR_CRC  =   0x0040  ;RX CRC error
144
DSC_RX_BCAST    =   0x0020  ;RX broadcast (no error)
145
DSC_RX_MCAST    =   0x0010  ;RX multicast (no error)
146
DSC_RX_MCH_HIT  =   0x0008  ;RX multicast hit in hash table (no error)
147
DSC_RX_MIDH_HIT =   0x0004  ;RX MID table hit (no error)
148
DSC_RX_IDX_MID_MASK  =   3  ;RX mask for the index of matched MIDx
1886 hidnplayr 149
 
150
;PHY settings
2852 hidnplayr 151
ICPLUS_PHY_ID   =   0x0243
1886 hidnplayr 152
 
2852 hidnplayr 153
RX_INTS         =   RX_FIFO_FULL or RX_NO_DESC or RX_FINISH
154
TX_INTS         =   TX_FINISH
155
INT_MASK        =   RX_INTS or TX_INTS
1886 hidnplayr 156
 
2852 hidnplayr 157
RX_BUF_LEN      equ (8192 << RX_BUF_LEN_IDX)    ; Size of the in-memory receive ring.
1886 hidnplayr 158
 
2852 hidnplayr 159
IO_SIZE         =   256     ; RDC MAC I/O Size
160
MAX_MAC         =   2       ; MAX RDC MAC
1893 hidnplayr 161
 
162
 
1886 hidnplayr 163
virtual at 0
164
x_head:
2852 hidnplayr 165
  .status         dw ?   ;0-1
166
  .len            dw ?   ;2-3
167
  .buf            dd ?   ;4-7
168
  .ndesc          dd ?   ;8-B
169
  .rev1           dd ?   ;C-F
170
  .vbufp          dd ?   ;10-13
171
  .vndescp        dd ?   ;14-17
172
  .skb_ptr        dd ?   ;18-1B
173
  .rev2           dd ?   ;1C-1F
1886 hidnplayr 174
  .sizeof:
175
end virtual
176
 
177
 
178
virtual at ebx
179
 
2852 hidnplayr 180
        device:
1886 hidnplayr 181
 
2852 hidnplayr 182
        ETH_DEVICE
1886 hidnplayr 183
 
2852 hidnplayr 184
        .io_addr        dd ?
1886 hidnplayr 185
 
2852 hidnplayr 186
        .cur_rx         dw ?
187
        .cur_tx         dw ?
188
        .last_tx        dw ?
189
        .phy_addr       dw ?
190
        .phy_mode       dw ?
191
        .mcr0           dw ?
192
        .mcr1           dw ?
193
        .switch_sig     dw ?
1886 hidnplayr 194
 
3205 hidnplayr 195
        .pci_bus        dd ?
196
        .pci_dev        dd ?
2852 hidnplayr 197
        .irq_line       db ?
1886 hidnplayr 198
 
3205 hidnplayr 199
        rb 3            ; dword alignment
1886 hidnplayr 200
 
2852 hidnplayr 201
        .tx_ring:       rb (((x_head.sizeof*TX_RING_SIZE)+32) and 0xfffffff0)
202
        .rx_ring:       rb (((x_head.sizeof*RX_RING_SIZE)+32) and 0xfffffff0)
1886 hidnplayr 203
 
2852 hidnplayr 204
        .size = $ - device
1886 hidnplayr 205
 
206
end virtual
207
 
208
 
209
 
210
section '.flat' code readable align 16
211
 
212
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213
;;                        ;;
214
;; proc START             ;;
215
;;                        ;;
216
;; (standard driver proc) ;;
217
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
218
 
219
align 4
220
proc START stdcall, state:dword
221
 
2852 hidnplayr 222
        cmp [state], 1
223
        jne .exit
1886 hidnplayr 224
 
225
  .entry:
226
 
3155 hidnplayr 227
        DEBUGF  2,"Loading %s driver\n", my_service
2852 hidnplayr 228
        stdcall RegService, my_service, service_proc
229
        ret
1886 hidnplayr 230
 
231
  .fail:
232
  .exit:
2852 hidnplayr 233
        xor eax, eax
234
        ret
1886 hidnplayr 235
 
236
endp
237
 
238
 
239
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240
;;                        ;;
241
;; proc SERVICE_PROC      ;;
242
;;                        ;;
243
;; (standard driver proc) ;;
244
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
245
 
246
align 4
247
proc service_proc stdcall, ioctl:dword
248
 
2852 hidnplayr 249
        mov     edx, [ioctl]
250
        mov     eax, [IOCTL.io_code]
1886 hidnplayr 251
 
252
;------------------------------------------------------
253
 
2852 hidnplayr 254
        cmp     eax, 0 ;SRV_GETVERSION
255
        jne     @F
1886 hidnplayr 256
 
2852 hidnplayr 257
        cmp     [IOCTL.out_size], 4
3155 hidnplayr 258
        jb      .fail
2852 hidnplayr 259
        mov     eax, [IOCTL.output]
260
        mov     [eax], dword API_VERSION
1886 hidnplayr 261
 
2852 hidnplayr 262
        xor     eax, eax
263
        ret
1886 hidnplayr 264
 
265
;------------------------------------------------------
266
  @@:
2852 hidnplayr 267
        cmp     eax, 1 ;SRV_HOOK
268
        jne     .fail
1886 hidnplayr 269
 
2852 hidnplayr 270
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
3155 hidnplayr 271
        jb      .fail
1886 hidnplayr 272
 
2852 hidnplayr 273
        mov     eax, [IOCTL.input]
274
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
275
        jne     .fail                                   ; other types arent supported for this card yet
1886 hidnplayr 276
 
277
; check if the device is already listed
278
 
2852 hidnplayr 279
        mov     esi, device_list
280
        mov     ecx, [devices]
281
        test    ecx, ecx
282
        jz      .firstdevice
1886 hidnplayr 283
 
284
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
2852 hidnplayr 285
        mov     ax , [eax+1]                            ;
1886 hidnplayr 286
  .nextdevice:
2852 hidnplayr 287
        mov     ebx, [esi]
3205 hidnplayr 288
        cmp     al, byte[device.pci_bus]
289
        jne     @f
290
        cmp     ah, byte[device.pci_dev]
2852 hidnplayr 291
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
3205 hidnplayr 292
       @@:
2852 hidnplayr 293
        add     esi, 4
294
        loop    .nextdevice
1886 hidnplayr 295
 
296
 
297
; This device doesnt have its own eth_device structure yet, lets create one
298
  .firstdevice:
2852 hidnplayr 299
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
3155 hidnplayr 300
        jae     .fail
1886 hidnplayr 301
 
2852 hidnplayr 302
        allocate_and_clear ebx, device.size, .fail      ; Allocate the buffer for device structure
1886 hidnplayr 303
 
304
; Fill in the direct call addresses into the struct
305
 
2852 hidnplayr 306
        mov     [device.reset], reset
307
        mov     [device.transmit], transmit
308
        mov     [device.unload], unload
309
        mov     [device.name], my_service
1886 hidnplayr 310
 
311
; save the pci bus and device numbers
312
 
2852 hidnplayr 313
        mov     eax, [IOCTL.input]
3205 hidnplayr 314
        movzx   ecx, byte[eax+1]
315
        mov     [device.pci_bus], ecx
316
        movzx   ecx, byte[eax+2]
317
        mov     [device.pci_dev], ecx
1886 hidnplayr 318
 
319
; Now, it's time to find the base io addres of the PCI device
320
 
3205 hidnplayr 321
        PCI_find_io
1886 hidnplayr 322
 
323
; We've found the io address, find IRQ now
324
 
3205 hidnplayr 325
        PCI_find_irq
1886 hidnplayr 326
 
2852 hidnplayr 327
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
328
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4
1886 hidnplayr 329
 
330
; Ok, the eth_device structure is ready, let's probe the device
2852 hidnplayr 331
        cli
1886 hidnplayr 332
 
2852 hidnplayr 333
        call    probe                                                   ; this function will output in eax
334
        test    eax, eax
335
        jnz     .err_sti                                                ; If an error occured, exit
1886 hidnplayr 336
 
2852 hidnplayr 337
        mov     eax, [devices]                                          ; Add the device structure to our device list
338
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
339
        inc     [devices]                                               ;
1886 hidnplayr 340
 
2852 hidnplayr 341
        mov     [device.type], NET_TYPE_ETH
342
        call    NetRegDev
343
        sti
1886 hidnplayr 344
 
2852 hidnplayr 345
        cmp     eax, -1
346
        je      .destroy
1886 hidnplayr 347
 
2852 hidnplayr 348
        ret
1886 hidnplayr 349
 
350
; If the device was already loaded, find the device number and return it in eax
351
 
352
  .find_devicenum:
2852 hidnplayr 353
        DEBUGF  1,"Trying to find device number of already registered device\n"
354
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
355
                                                                        ; into a device number in edi
356
        mov     eax, edi                                                ; Application wants it in eax instead
357
        DEBUGF  1,"Kernel says: %u\n", eax
358
        ret
1886 hidnplayr 359
 
360
; If an error occured, remove all allocated data and exit (returning -1 in eax)
361
 
362
  .destroy:
2852 hidnplayr 363
        ; todo: reset device into virgin state
1886 hidnplayr 364
 
365
  .err_sti:
2852 hidnplayr 366
        sti
1886 hidnplayr 367
 
368
  .err:
2852 hidnplayr 369
        stdcall KernelFree, ebx
1886 hidnplayr 370
 
371
  .fail:
2852 hidnplayr 372
        or      eax, -1
373
        ret
1886 hidnplayr 374
 
375
;------------------------------------------------------
376
endp
377
 
378
 
379
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
380
;;                                                                        ;;
381
;;        Actual Hardware dependent code starts here                      ;;
382
;;                                                                        ;;
383
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
384
 
385
 
1893 hidnplayr 386
macro mdio_write reg, val {
2852 hidnplayr 387
        stdcall phy_read, [device.io_addr], [device.phy_addr], reg
1886 hidnplayr 388
}
389
 
1893 hidnplayr 390
macro mdio_write reg, val {
2852 hidnplayr 391
        stdcall phy_write, [device.io_addr], [devce.phy_addr], reg, val
1886 hidnplayr 392
}
393
 
394
 
395
align 4
396
unload:
2852 hidnplayr 397
        ; TODO: (in this particular order)
398
        ;
399
        ; - Stop the device
400
        ; - Detach int handler
401
        ; - Remove device from local list (RTL8139_LIST)
402
        ; - call unregister function in kernel
403
        ; - Remove all allocated structures and buffers the card used
1886 hidnplayr 404
 
2852 hidnplayr 405
        or      eax,-1
1886 hidnplayr 406
 
407
ret
408
 
409
 
410
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
411
;;
412
;;  probe: enables the device (if it really is RTL8139)
413
;;
414
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
415
 
416
align 4
417
probe:
2852 hidnplayr 418
        DEBUGF  2,"Probing R6040 device\n"
1886 hidnplayr 419
 
3205 hidnplayr 420
        PCI_make_bus_master
1886 hidnplayr 421
 
2852 hidnplayr 422
        ; If PHY status change register is still set to zero
423
        ; it means the bootloader didn't initialize it
1886 hidnplayr 424
 
2852 hidnplayr 425
        set_io  0
426
        set_io  PHY_CC
427
        in      ax, dx
428
        test    ax, ax
429
        jnz     @f
430
        mov     ax, 0x9F07
431
        out     dx, ax
1886 hidnplayr 432
     @@:
433
 
2852 hidnplayr 434
        call    read_mac
1886 hidnplayr 435
 
2852 hidnplayr 436
        ; Some bootloaders/BIOSes do not initialize MAC address, warn about that
437
        and     eax, 0xFF
438
        or      eax, dword [device.mac]
439
        test    eax, eax
440
        jnz     @f
441
        DEBUGF  2, "ERROR: MAC address not initialized!\n"
1886 hidnplayr 442
 
443
     @@:
2852 hidnplayr 444
        ; Init RDC private data
445
        mov     [device.mcr0], 0x1002
446
        ;mov     [private.phy_addr], 1 ; Asper: Only one network card is supported now.
447
        mov     [device.switch_sig], 0
1886 hidnplayr 448
 
2852 hidnplayr 449
        ; Check the vendor ID on the PHY, if 0xFFFF assume none attached
450
        stdcall phy_read, 1, 2
451
        cmp     ax, 0xFFFF
452
        jne     @f
453
        DEBUGF  2, "Failed to detect an attached PHY\n" ;, generating random"
454
        mov     eax, -1
455
        ret
1886 hidnplayr 456
     @@:
457
 
2852 hidnplayr 458
        ; Set MAC address
459
        call    init_mac_regs
1886 hidnplayr 460
 
2852 hidnplayr 461
        ; Initialize and alloc RX/TX buffers
462
        call    init_txbufs
463
        call    init_rxbufs
1886 hidnplayr 464
 
2852 hidnplayr 465
        ; Read the PHY ID
466
        mov     [device.phy_mode], 0x8000
467
        stdcall phy_read, 0, 2
468
        mov     [device.switch_sig], ax
469
        cmp     ax, ICPLUS_PHY_ID
470
        jne     @f
471
        stdcall phy_write, 29, 31, 0x175C ; Enable registers
472
        jmp     .phy_readen
1886 hidnplayr 473
      @@:
474
 
2852 hidnplayr 475
        ; PHY Mode Check
476
        movzx   eax, [device.phy_addr]
477
        stdcall phy_write, eax, 4, PHY_CAP
478
        stdcall phy_write, eax, 0, PHY_MODE
1886 hidnplayr 479
 
1893 hidnplayr 480
      if PHY_MODE = 0x3100
2852 hidnplayr 481
        call    phy_mode_chk
482
        mov     [device.phy_mode], ax
483
        jmp     .phy_readen
1893 hidnplayr 484
      end if
1886 hidnplayr 485
 
1893 hidnplayr 486
      if not (PHY_MODE and 0x0100)
2852 hidnplayr 487
        mov     [device.phy_mode], 0
1893 hidnplayr 488
      end if
489
 
1886 hidnplayr 490
      .phy_readen:
491
 
2852 hidnplayr 492
        ; Set duplex mode
493
        mov     ax, [device.phy_mode]
494
        or      [device.mcr0], ax
1886 hidnplayr 495
 
2852 hidnplayr 496
        ; improve performance (by RDC guys)
497
        stdcall phy_read, 30, 17
498
        or      ax, 0x4000
499
        stdcall phy_write, 30, 17, eax
1886 hidnplayr 500
 
2852 hidnplayr 501
        stdcall phy_read, 30, 17
502
        and     ax, not 0x2000
503
        stdcall phy_write, 30, 17, eax
1886 hidnplayr 504
 
2852 hidnplayr 505
        stdcall phy_write, 0, 19, 0x0000
506
        stdcall phy_write, 0, 30, 0x01F0
1886 hidnplayr 507
 
2852 hidnplayr 508
        ; Initialize all Mac registers
509
        call    init_mac_regs
1886 hidnplayr 510
 
511
 
512
 
513
align 4
514
reset:
515
 
2852 hidnplayr 516
        DEBUGF  2,"Resetting R6040\n"
1886 hidnplayr 517
 
2852 hidnplayr 518
        ; Mask off Interrupt
519
        xor     ax, ax
520
        set_io  0
521
        set_io  MIER
522
        out     dx, ax
1886 hidnplayr 523
 
524
 
525
; attach int handler
526
 
2852 hidnplayr 527
        movzx   eax, [device.irq_line]
528
        DEBUGF  2,"Attaching int handler to irq %x\n", eax:1
529
        stdcall AttachIntHandler, eax, int_handler, dword 0
530
        test    eax, eax
531
        jnz     @f
532
        DEBUGF  2,"\nCould not attach int handler!\n"
1886 hidnplayr 533
;        or      eax, -1
534
;        ret
535
       @@:
536
 
537
 
2852 hidnplayr 538
        ;Reset RDC MAC
539
        mov     eax, MAC_RST
540
        set_io  0
541
        set_io  MCR1
542
        out     dx, ax
1886 hidnplayr 543
 
2852 hidnplayr 544
        mov     ecx, 2048 ;limit
1886 hidnplayr 545
  .read:
2852 hidnplayr 546
        in      ax, dx
547
        test    ax, 0x1
548
        jnz      @f
549
        dec     ecx
550
        test    ecx, ecx
551
        jnz     .read
1886 hidnplayr 552
  @@:
2852 hidnplayr 553
        ;Reset internal state machine
554
        mov     ax,  2
555
        set_io  MAC_SM
556
        out     dx, ax
1886 hidnplayr 557
 
2852 hidnplayr 558
        xor     ax, ax
559
        out     dx, ax
1886 hidnplayr 560
 
2852 hidnplayr 561
        mov     esi, 5
562
        stdcall Sleep
1886 hidnplayr 563
 
2852 hidnplayr 564
        ;MAC Bus Control Register
565
        mov     ax, MBCR_DEFAULT
566
        set_io  0
567
        set_io  MBCR
568
        out     dx, ax
1886 hidnplayr 569
 
2852 hidnplayr 570
        ;Buffer Size Register
571
        mov     ax, MAX_BUF_SIZE
572
        set_io  MR_BSR
573
        out     dx, ax
1886 hidnplayr 574
 
2852 hidnplayr 575
        ;Write TX ring start address
576
        lea     eax, [device.tx_ring]
577
        GetRealAddr
578
        set_io  MTD_SA0
579
        out     dx, ax
580
        shr     eax, 16
581
        set_io  MTD_SA1
582
        out     dx, ax
1886 hidnplayr 583
 
2852 hidnplayr 584
        ;Write RX ring start address
585
        lea     eax, [device.rx_ring]
586
        GetRealAddr
587
        set_io  MRD_SA0
588
        out     dx, ax
589
        shr     eax, 16
590
        set_io  MRD_SA1
591
        out     dx, ax
1886 hidnplayr 592
 
2852 hidnplayr 593
        ;Set interrupt waiting time and packet numbers
594
        xor     ax, ax
595
        set_io  MT_ICR
596
        out     dx, ax
1886 hidnplayr 597
 
2852 hidnplayr 598
        ;Enable interrupts
599
        mov     ax, INT_MASK
600
        set_io  MIER
601
        out     dx, ax
1886 hidnplayr 602
 
2852 hidnplayr 603
        ;Enable TX and RX
604
        mov     ax, [device.mcr0]
605
        or      ax, 0x0002
606
        set_io  0
607
        out     dx, ax
1886 hidnplayr 608
 
2852 hidnplayr 609
        ;Let TX poll the descriptors
610
        ;we may got called by tx_timeout which has left
611
        ;some unset tx buffers
612
        xor     ax, ax
613
        inc     ax
614
        set_io  0
615
        set_io  MTPR
616
        out     dx, ax
1886 hidnplayr 617
 
618
; Set the mtu, kernel will be able to send now
2852 hidnplayr 619
        mov     [device.mtu], 1514
1886 hidnplayr 620
 
3346 hidnplayr 621
; Set link state to unknown
622
        mov     [device.state], ETH_LINK_UNKOWN
623
 
2852 hidnplayr 624
        DEBUGF  1,"Reset ok\n"
625
        xor     eax, eax
626
        ret
1886 hidnplayr 627
 
628
 
629
 
630
align 4
631
init_txbufs:
632
 
2852 hidnplayr 633
        DEBUGF  1,"Init TxBufs\n"
1886 hidnplayr 634
 
2852 hidnplayr 635
        lea     esi, [device.tx_ring]
636
        lea     eax, [device.tx_ring + x_head.sizeof]
637
        GetRealAddr
638
        mov     ecx, TX_RING_SIZE
1886 hidnplayr 639
 
640
    .next_desc:
2852 hidnplayr 641
        mov     [esi + x_head.ndesc], eax
642
        mov     [esi + x_head.skb_ptr], 0
643
        mov     [esi + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 644
 
2852 hidnplayr 645
        add     eax, x_head.sizeof
646
        add     esi, x_head.sizeof
1886 hidnplayr 647
 
2852 hidnplayr 648
        dec     ecx
649
        jnz     .next_desc
1886 hidnplayr 650
 
2852 hidnplayr 651
        lea     eax, [device.tx_ring]
652
        GetRealAddr
653
        mov     [device.tx_ring + x_head.sizeof*(TX_RING_SIZE - 1) + x_head.ndesc], eax
1886 hidnplayr 654
 
2852 hidnplayr 655
        ret
1886 hidnplayr 656
 
657
 
658
 
659
align 4
660
init_rxbufs:
661
 
2852 hidnplayr 662
        DEBUGF  1,"Init RxBufs\n"
1886 hidnplayr 663
 
2852 hidnplayr 664
        lea     esi, [device.rx_ring]
665
        lea     eax, [device.rx_ring + x_head.sizeof]
666
        GetRealAddr
667
        mov     edx, eax
668
        mov     ecx, RX_RING_SIZE
1886 hidnplayr 669
 
670
    .next_desc:
2852 hidnplayr 671
         mov     [esi + x_head.ndesc], edx
1886 hidnplayr 672
 
2852 hidnplayr 673
        push    esi ecx
674
        stdcall KernelAlloc, MAX_BUF_SIZE
675
        pop     ecx esi
1886 hidnplayr 676
 
2852 hidnplayr 677
        mov     [esi + x_head.skb_ptr], eax
678
        GetRealAddr
679
        mov     [esi + x_head.buf], eax
680
        mov     [esi + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 681
 
2852 hidnplayr 682
        add     edx, x_head.sizeof
683
        add     esi, x_head.sizeof
1886 hidnplayr 684
 
2852 hidnplayr 685
        dec     ecx
686
        jnz     .next_desc
1886 hidnplayr 687
 
2852 hidnplayr 688
        ; complete the ring by linking the last to the first
1886 hidnplayr 689
 
2852 hidnplayr 690
        lea     eax, [device.rx_ring]
691
        GetRealAddr
692
        mov     [device.rx_ring + x_head.sizeof*(RX_RING_SIZE - 1) + x_head.ndesc], eax
1886 hidnplayr 693
 
2852 hidnplayr 694
        ret
1886 hidnplayr 695
 
696
 
697
 
698
align 4
699
phy_mode_chk:
700
 
2852 hidnplayr 701
        DEBUGF  1,"Checking PHY mode\n"
1886 hidnplayr 702
 
2852 hidnplayr 703
        ; PHY Link Status Check
704
        movzx   eax, [device.phy_addr]
705
        stdcall phy_read, eax, 1
706
        test    eax, 0x4
707
        jz      .ret_0x8000
1886 hidnplayr 708
 
2852 hidnplayr 709
        ; PHY Chip Auto-Negotiation Status
710
        movzx   eax, [device.phy_addr]
711
        stdcall phy_read, eax, 1
712
        test    eax, 0x0020
713
        jnz     .auto_nego
1886 hidnplayr 714
 
2852 hidnplayr 715
        ; Force Mode
716
        movzx   eax, [device.phy_addr]
717
        stdcall phy_read, eax, 0
718
        test    eax, 0x100
719
        jnz     .ret_0x8000
1886 hidnplayr 720
 
721
  .auto_nego:
2852 hidnplayr 722
        ; Auto Negotiation Mode
723
        movzx   eax, [device.phy_addr]
724
        stdcall phy_read, eax, 5
725
        mov     ecx, eax
726
        movzx   eax, [device.phy_addr]
727
        stdcall phy_read, eax, 4
728
        and     eax, ecx
729
        test    eax, 0x140
730
        jnz     .ret_0x8000
1886 hidnplayr 731
 
2852 hidnplayr 732
        xor     eax, eax
733
        ret
1886 hidnplayr 734
 
735
  .ret_0x8000:
2852 hidnplayr 736
        mov     eax, 0x8000
737
        ret
1886 hidnplayr 738
 
739
 
740
 
741
 
742
 
743
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
744
;;                                         ;;
745
;; Transmit                                ;;
746
;;                                         ;;
747
;; In: buffer pointer in [esp+4]           ;;
748
;;     size of buffer in [esp+8]           ;;
749
;;     pointer to device structure in ebx  ;;
750
;;                                         ;;
751
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
752
align 4
753
transmit:
2852 hidnplayr 754
        DEBUGF  2,"\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
755
        mov     eax, [esp+4]
756
        DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
757
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
758
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
759
        [eax+13]:2,[eax+12]:2
1886 hidnplayr 760
 
2852 hidnplayr 761
        cmp     dword [esp+8], 1514
3155 hidnplayr 762
        ja      .fail
2852 hidnplayr 763
        cmp     dword [esp+8], 60
3155 hidnplayr 764
        jb      .fail
1886 hidnplayr 765
 
2852 hidnplayr 766
        movzx   edi, [device.cur_tx]
767
        shl     edi, 5
768
        add     edi, ebx
769
        add     edi, device.tx_ring - ebx
1886 hidnplayr 770
 
2852 hidnplayr 771
        DEBUGF  2,"TX buffer status: 0x%x\n", [edi + x_head.status]:4
1886 hidnplayr 772
 
2852 hidnplayr 773
        test    [edi + x_head.status], DSC_OWNER_MAC    ; check if buffer is available
774
        jnz     .wait_to_send
1886 hidnplayr 775
 
776
  .do_send:
777
 
2852 hidnplayr 778
        DEBUGF  2,"Sending now\n"
1893 hidnplayr 779
 
2852 hidnplayr 780
        mov     eax, [esp+4]
781
        mov     [edi + x_head.skb_ptr], eax
782
        GetRealAddr
783
        mov     [edi + x_head.buf], eax
784
        mov     ecx, [esp+8]
785
        mov     [edi + x_head.len], cx
786
        mov     [edi + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 787
 
2852 hidnplayr 788
        ; Trigger the MAC to check the TX descriptor
789
        mov     ax, 0x01
790
        set_io  0
791
        set_io  MTPR
792
        out     dx, ax
1886 hidnplayr 793
 
2852 hidnplayr 794
        inc     [device.cur_tx]
795
        and     [device.cur_tx], TX_RING_SIZE - 1
796
        xor     eax, eax
1886 hidnplayr 797
 
2865 hidnplayr 798
; Update stats
799
        inc     [device.packets_tx]
800
        mov     eax, [esp+8]
801
        add     dword [device.bytes_tx], eax
802
        adc     dword [device.bytes_tx + 4], 0
803
 
2852 hidnplayr 804
        ret     8
1886 hidnplayr 805
 
806
  .wait_to_send:
807
 
2852 hidnplayr 808
        DEBUGF  2,"Waiting for TX buffer\n"
1886 hidnplayr 809
 
2852 hidnplayr 810
        call    GetTimerTicks           ; returns in eax
811
        lea     edx, [eax + 100]
1893 hidnplayr 812
     .l2:
2852 hidnplayr 813
        test    [edi + x_head.status], DSC_OWNER_MAC
814
        jz      .do_send
815
        mov     esi, 10
816
        call    Sleep
817
        call    GetTimerTicks
818
        cmp     edx, eax
3155 hidnplayr 819
        jb      .l2
1893 hidnplayr 820
 
2852 hidnplayr 821
        DEBUGF  1,"Send timeout\n"
822
        xor     eax, eax
823
        dec     eax
1886 hidnplayr 824
  .fail:
2852 hidnplayr 825
        DEBUGF  1,"Send failed\n"
826
        ret     8
1886 hidnplayr 827
 
828
 
829
 
830
 
831
 
832
;;;;;;;;;;;;;;;;;;;;;;;
833
;;                   ;;
834
;; Interrupt handler ;;
835
;;                   ;;
836
;;;;;;;;;;;;;;;;;;;;;;;
2935 hidnplayr 837
 
1886 hidnplayr 838
align 4
839
int_handler:
840
 
2935 hidnplayr 841
        DEBUGF  1,"\n%s int\n", my_service
1886 hidnplayr 842
 
843
; Find pointer of device wich made IRQ occur
844
 
2852 hidnplayr 845
        mov     ecx, [devices]
846
        test    ecx, ecx
2935 hidnplayr 847
        jz      .nothing
848
        mov     esi, device_list
1886 hidnplayr 849
  .nextdevice:
2935 hidnplayr 850
        mov     ebx, [esi]
1886 hidnplayr 851
 
2852 hidnplayr 852
        set_io  0
853
        set_io  MISR
854
        in      ax, dx
2935 hidnplayr 855
        out     dx, ax                  ; send it back to ACK
856
        test    ax, ax
2852 hidnplayr 857
        jnz     .got_it
2935 hidnplayr 858
  .continue:
2852 hidnplayr 859
        add     esi, 4
860
        dec     ecx
861
        jnz     .nextdevice
2935 hidnplayr 862
  .nothing:                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
2852 hidnplayr 863
        ret
1886 hidnplayr 864
 
865
; At this point, test for all possible reasons, and handle accordingly
866
 
867
  .got_it:
2935 hidnplayr 868
 
869
        DEBUGF  1,"Device: %x Status: %x ", ebx, ax
870
 
2852 hidnplayr 871
        push ax
1886 hidnplayr 872
 
2852 hidnplayr 873
        test    word [esp], RX_FINISH
874
        jz      .no_RX
1886 hidnplayr 875
 
2852 hidnplayr 876
        push    ebx
1886 hidnplayr 877
  .more_RX:
2852 hidnplayr 878
        pop     ebx
1886 hidnplayr 879
 
2852 hidnplayr 880
        ; Find the current RX descriptor
1886 hidnplayr 881
 
2852 hidnplayr 882
        movzx   edx, [device.cur_rx]
883
        shl     edx, 5
884
        lea     edx, [device.rx_ring + edx]
1886 hidnplayr 885
 
2852 hidnplayr 886
        ; Check the descriptor status
1886 hidnplayr 887
 
2852 hidnplayr 888
        mov     cx, [edx + x_head.status]
889
        test    cx, DSC_OWNER_MAC
890
        jnz     .no_RX
1886 hidnplayr 891
 
2852 hidnplayr 892
        DEBUGF  2,"packet status=0x%x\n", cx
1886 hidnplayr 893
 
2852 hidnplayr 894
        test    cx, DSC_RX_ERR          ; Global error status set
895
        jnz     .no_RX
1886 hidnplayr 896
 
2852 hidnplayr 897
        ; Packet successfully received
1886 hidnplayr 898
 
2852 hidnplayr 899
        movzx   ecx, [edx + x_head.len]
900
        and     ecx, 0xFFF
901
        sub     ecx, 4                  ; Do not count the CRC
1886 hidnplayr 902
 
2865 hidnplayr 903
; Update stats
904
        add     dword [device.bytes_rx], ecx
905
        adc     dword [device.bytes_rx + 4], 0
906
        inc     dword [device.packets_rx]
907
 
2852 hidnplayr 908
        ; Push packet size and pointer, kernel will need it..
1886 hidnplayr 909
 
2852 hidnplayr 910
        push    ebx
911
        push    .more_RX
1886 hidnplayr 912
 
2852 hidnplayr 913
        push    ecx
914
        push    [edx + x_head.skb_ptr]
1886 hidnplayr 915
 
2852 hidnplayr 916
        DEBUGF  2,"packet ptr=0x%x\n", [edx + x_head.skb_ptr]
1886 hidnplayr 917
 
2852 hidnplayr 918
        ; reset the RX descriptor
1886 hidnplayr 919
 
2852 hidnplayr 920
        push    edx
921
        stdcall KernelAlloc, MAX_BUF_SIZE
922
        pop     edx
923
        mov     [edx + x_head.skb_ptr], eax
924
        GetRealAddr
925
        mov     [edx + x_head.buf], eax
926
        mov     [edx + x_head.status], DSC_OWNER_MAC
1886 hidnplayr 927
 
2852 hidnplayr 928
        ; Use next descriptor next time
1886 hidnplayr 929
 
2852 hidnplayr 930
        inc     [device.cur_rx]
931
        and     [device.cur_rx], RX_RING_SIZE - 1
1886 hidnplayr 932
 
2852 hidnplayr 933
        ; At last, send packet to kernel
1886 hidnplayr 934
 
2981 hidnplayr 935
        jmp     Eth_input
1886 hidnplayr 936
 
1889 hidnplayr 937
 
1886 hidnplayr 938
  .no_RX:
939
 
2852 hidnplayr 940
        test    word [esp], TX_FINISH
941
        jz      .no_TX
1886 hidnplayr 942
 
1889 hidnplayr 943
      .loop_tx:
2852 hidnplayr 944
        movzx   edi, [device.last_tx]
945
        shl     edi, 5
946
        lea     edi, [device.tx_ring + edi]
1886 hidnplayr 947
 
2852 hidnplayr 948
        test    [edi + x_head.status], DSC_OWNER_MAC
949
        jnz     .no_TX
1889 hidnplayr 950
 
2852 hidnplayr 951
        cmp     [edi + x_head.skb_ptr], 0
952
        je      .no_TX
1889 hidnplayr 953
 
2852 hidnplayr 954
        DEBUGF  2,"Freeing buffer 0x%x\n", [edi + x_head.skb_ptr]
1889 hidnplayr 955
 
2852 hidnplayr 956
        push    [edi + x_head.skb_ptr]
957
        mov     [edi + x_head.skb_ptr], 0
958
        call    KernelFree
1889 hidnplayr 959
 
2852 hidnplayr 960
        inc     [device.last_tx]
961
        and     [device.last_tx], TX_RING_SIZE - 1
1893 hidnplayr 962
 
2852 hidnplayr 963
        jmp     .loop_tx
1889 hidnplayr 964
 
965
  .no_TX:
2852 hidnplayr 966
        pop     ax
967
        ret
1886 hidnplayr 968
 
969
 
970
 
971
 
972
align 4
973
init_mac_regs:
974
 
2852 hidnplayr 975
        DEBUGF  2,"initializing MAC regs\n"
1886 hidnplayr 976
 
2852 hidnplayr 977
        ; MAC operation register
978
        mov     ax, 1
979
        set_io  0
980
        set_io  MCR1
981
        out     dx, ax
982
        ; Reset MAC
983
        mov     ax, 2
984
        set_io  MAC_SM
985
        out     dx, ax
986
        ; Reset internal state machine
987
        xor     ax, ax
988
        out     dx, ax
989
        mov     esi, 5
990
        stdcall Sleep
1886 hidnplayr 991
 
2852 hidnplayr 992
        call    read_mac
1886 hidnplayr 993
 
2852 hidnplayr 994
        ret
1886 hidnplayr 995
 
996
 
997
 
998
 
999
; Read a word data from PHY Chip
1000
 
1001
align 4
1002
proc  phy_read stdcall, phy_addr:dword, reg:dword
1003
 
2852 hidnplayr 1004
        DEBUGF  2,"PHY read, addr=0x%x reg=0x%x\n", [phy_addr]:8, [reg]:8
1886 hidnplayr 1005
 
2852 hidnplayr 1006
        mov     eax, [phy_addr]
1007
        shl     eax, 8
1008
        add     eax, [reg]
1009
        add     eax, MDIO_READ
1010
        set_io  0
1011
        set_io  MMDIO
1012
        out     dx, ax
1886 hidnplayr 1013
 
2852 hidnplayr 1014
        ;Wait for the read bit to be cleared.
1015
        mov     ecx, 2048 ;limit
1886 hidnplayr 1016
  .read:
2852 hidnplayr 1017
        in      ax, dx
1018
        test    ax, MDIO_READ
1019
        jz      @f
1020
        dec     ecx
1021
        jnz     .read
1886 hidnplayr 1022
  @@:
1023
 
2852 hidnplayr 1024
        set_io  MMRD
1025
        in      ax, dx
1026
        and     eax, 0xFFFF
1886 hidnplayr 1027
 
2852 hidnplayr 1028
        DEBUGF  2,"PHY read, val=0x%x\n", eax:4
1886 hidnplayr 1029
 
2852 hidnplayr 1030
        ret
1886 hidnplayr 1031
 
1032
endp
1033
 
1034
 
1035
 
1036
 
1037
; Write a word data to PHY Chip
1038
 
1039
align 4
1040
proc  phy_write stdcall, phy_addr:dword, reg:dword, val:dword
1041
 
2852 hidnplayr 1042
        DEBUGF  2,"PHY write, addr=0x%x reg=0x%x val=0x%x\n", [phy_addr]:8, [reg]:8, [val]:8
1886 hidnplayr 1043
 
2852 hidnplayr 1044
        mov     eax, [val]
1045
        set_io  0
1046
        set_io  MMWD
1047
        out     dx, ax
1886 hidnplayr 1048
 
2852 hidnplayr 1049
        ;Write the command to the MDIO bus
1886 hidnplayr 1050
 
2852 hidnplayr 1051
        mov     eax, [phy_addr]
1052
        shl     eax, 8
1053
        add     eax, [reg]
1054
        add     eax, MDIO_WRITE
1055
        set_io  MMDIO
1056
        out     dx, ax
1886 hidnplayr 1057
 
2852 hidnplayr 1058
        ;Wait for the write bit to be cleared.
1059
        mov     ecx, 2048 ;limit
1886 hidnplayr 1060
  .write:
2852 hidnplayr 1061
        in      ax, dx
1062
        test    ax, MDIO_WRITE
1063
        jz      @f
1064
        dec     ecx
1065
        jnz     .write
1886 hidnplayr 1066
  @@:
1067
 
2852 hidnplayr 1068
        DEBUGF  2,"PHY write ok\n"
1886 hidnplayr 1069
 
2852 hidnplayr 1070
        ret
1886 hidnplayr 1071
endp
1072
 
1073
 
1074
 
1075
align 4
1076
read_mac:
1077
 
2852 hidnplayr 1078
        DEBUGF  2,"Reading MAC: "
1886 hidnplayr 1079
 
2852 hidnplayr 1080
        mov     cx, 3
1081
        lea     edi, [device.mac]
1082
        set_io  0
1083
        set_io  MID_0L
1886 hidnplayr 1084
     .mac:
2852 hidnplayr 1085
        in      ax, dx
1086
        stosw
1087
        inc     dx
1088
        inc     dx
1089
        dec     cx
1090
        jnz     .mac
1886 hidnplayr 1091
 
2852 hidnplayr 1092
        DEBUGF  2,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2, [edi-5]:2, [edi-4]:2, [edi-3]:2, [edi-2]:2, [edi-1]:2
1886 hidnplayr 1093
 
2852 hidnplayr 1094
        ret
1886 hidnplayr 1095
 
1096
 
1097
 
1098
 
1099
; End of code
1100
 
1101
section '.data' data readable writable align 16 ; place all uninitialized data place here
2852 hidnplayr 1102
align 4                                         ; Place all initialised data here
1886 hidnplayr 1103
 
2852 hidnplayr 1104
devices         dd 0
1105
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
1106
my_service      db 'R6040',0                    ; max 16 chars include zero
1886 hidnplayr 1107
 
2852 hidnplayr 1108
include_debug_strings                           ; All data wich FDO uses will be included here
1886 hidnplayr 1109
 
2852 hidnplayr 1110
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
1886 hidnplayr 1111