Subversion Repositories Kolibri OS

Rev

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

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