Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
7809 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
9146 hidnplayr 3
;; Copyright (C) KolibriOS team 2018-2021. All rights reserved.    ;;
7809 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  AR81XX driver for KolibriOS                                    ;;
7
;;                                                                 ;;
8
;;  based on alx driver from TI-OpenLink                           ;;
9
;;                                                                 ;;
7827 hidnplayr 10
;;  Written by hidnplayr (hidnplayr@gmail.com)                     ;;
7809 hidnplayr 11
;;                                                                 ;;
7827 hidnplayr 12
;;  Thanks to: floppy121 for kindly providing me with the hardware ;;
13
;;              that made the development of this driver possible. ;;
14
;;                                                                 ;;
7809 hidnplayr 15
;;          GNU GENERAL PUBLIC LICENSE                             ;;
16
;;             Version 2, June 1991                                ;;
17
;;                                                                 ;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
 
20
format PE DLL native
21
entry START
22
 
23
        CURRENT_API             = 0x0200
24
        COMPATIBLE_API          = 0x0100
25
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
26
 
9146 hidnplayr 27
; configureable area
7809 hidnplayr 28
 
9146 hidnplayr 29
        MAX_DEVICES             = 16    ; Maximum number of devices this driver may handle
7809 hidnplayr 30
 
9146 hidnplayr 31
        __DEBUG__               = 1     ; 1 = on, 0 = off
32
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
7809 hidnplayr 33
 
9146 hidnplayr 34
        TX_RING_SIZE            = 128   ; Number of packets in send ring buffer
35
        RX_RING_SIZE            = 128   ; Number of packets in receive ring buffer
36
 
7809 hidnplayr 37
        RX_BUFFER_SIZE          = 1536
38
 
39
        SMB_TIMER               = 400
9146 hidnplayr 40
        IMT                     = 200                   ; IRQ Modulo Timer
41
        ITH_TPD                 = TX_RING_SIZE / 3      ; Interrupt Threshold TPD
7809 hidnplayr 42
 
9146 hidnplayr 43
; end configureable area
44
 
7809 hidnplayr 45
section '.flat' readable writable executable
46
 
47
include '../proc32.inc'
48
include '../struct.inc'
49
include '../macros.inc'
50
include '../fdo.inc'
51
include '../netdrv.inc'
52
 
53
include 'ar81xx.inc'
54
 
9146 hidnplayr 55
if (bsr TX_RING_SIZE)>(bsf TX_RING_SIZE)
56
  display 'TX_RING_SIZE must be a power of two'
57
  err
58
end if
59
 
60
if (bsr RX_RING_SIZE)>(bsf RX_RING_SIZE)
61
  display 'RX_RING_SIZE must be a power of two'
62
  err
63
end if
64
 
7809 hidnplayr 65
; Transmit Packet Descriptor
66
struct alx_tpd
67
        length          dw ?
68
        vlan_tag        dw ?
69
        word1           dd ?
70
        addr_l          dd ?
71
        addr_h          dd ?
72
ends
73
 
74
; Receive Return Descriptor
75
struct alx_rrd
76
        word0           dd ?    ; IP payload cksum + number of RFDs + start index of RFD-ring
77
        rss_hash        dd ?
78
        word2           dd ?    ; VLAN tag + Protocol ID + RSS Q num + RSS Hash algorithm
79
        word3           dd ?    ; Packet length + status
80
ends
81
 
82
; Receive Free Descriptor
83
struct alx_rfd
84
        addr_l          dd ?
85
        addr_h          dd ?
86
ends
87
 
88
struct  device          ETH_DEVICE
89
 
90
        io_addr         dd ?
91
        pci_bus         dd ?
92
        pci_dev         dd ?
7827 hidnplayr 93
        pci_vid         dw ?    ; Vendor ID
94
        pci_did         dw ?    ; Device ID
7809 hidnplayr 95
        irq_line        dd ?
96
        pci_rev         dd ?
97
        chip_rev        dd ?
98
        mmio_addr       dd ?
99
 
100
        max_dma_chnl    dd ?
101
 
102
        int_mask        dd ?
103
        rx_ctrl         dd ?
104
 
105
        rxq_read_idx            dd ?
106
        rxq_write_idx           dd ?
107
;        rxq_rrd_read_idx        dd ?
108
        txq_read_idx            dd ?
109
        txq_write_idx           dd ?
110
 
111
        rb 0x100 - ($ and 0xff) ; align 256
112
        tpd_ring        rb ((TX_RING_SIZE*sizeof.alx_tpd+16) and 0xfffffff0)
113
        rrd_ring        rb ((RX_RING_SIZE*sizeof.alx_rrd+16) and 0xfffffff0)
114
        rfd_ring        rb ((RX_RING_SIZE*sizeof.alx_rfd+16) and 0xfffffff0)
115
        tpd_ring_virt   rd TX_RING_SIZE
116
        rfd_ring_virt   rd RX_RING_SIZE
117
 
118
ends
119
 
120
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
121
;;                        ;;
122
;; proc START             ;;
123
;;                        ;;
124
;; (standard driver proc) ;;
125
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
126
 
127
proc START c, reason:dword, cmdline:dword
128
 
129
        cmp     [reason], DRV_ENTRY
130
        jne     .fail
131
 
132
        DEBUGF  2,"Loading driver\n"
133
        invoke  RegService, my_service, service_proc
134
        ret
135
 
136
  .fail:
137
        xor     eax, eax
138
        ret
139
 
140
endp
141
 
142
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
143
;;                        ;;
144
;; proc SERVICE_PROC      ;;
145
;;                        ;;
146
;; (standard driver proc) ;;
147
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
148
 
149
proc service_proc stdcall, ioctl:dword
150
 
151
        mov     edx, [ioctl]
152
        mov     eax, [edx + IOCTL.io_code]
153
 
154
;------------------------------------------------------
155
 
156
        cmp     eax, 0 ;SRV_GETVERSION
157
        jne     @F
158
 
159
        cmp     [edx + IOCTL.out_size], 4
160
        jb      .fail
161
        mov     eax, [edx + IOCTL.output]
162
        mov     [eax], dword API_VERSION
163
 
164
        xor     eax, eax
165
        ret
166
 
167
;------------------------------------------------------
168
  @@:
169
        cmp     eax, 1 ;SRV_HOOK
170
        jne     .fail
171
 
172
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
173
        jb      .fail
174
 
175
        mov     eax, [edx + IOCTL.input]
176
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
177
        jne     .fail                                   ; other types arent supported for this card yet
178
 
179
; check if the device is already listed
180
 
181
        mov     esi, device_list
182
        mov     ecx, [devices]
183
        test    ecx, ecx
184
        jz      .firstdevice
185
 
186
;        mov     eax, [edx + IOCTL.input]               ; get the pci bus and device numbers
187
        mov     ax , [eax+1]                            ;
188
  .nextdevice:
189
        mov     ebx, [esi]
190
        cmp     al, byte[ebx + device.pci_bus]
191
        jne     @f
192
        cmp     ah, byte[ebx + device.pci_dev]
193
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
194
       @@:
195
        add     esi, 4
196
        loop    .nextdevice
197
 
198
; This device doesnt have its own eth_device structure yet, lets create one
199
  .firstdevice:
200
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
201
        jae     .fail
202
 
203
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
204
 
205
; Fill in the direct call addresses into the struct
206
 
207
        mov     [ebx + device.reset], reset
208
        mov     [ebx + device.transmit], transmit
209
        mov     [ebx + device.unload], unload
210
        mov     [ebx + device.name], my_service
211
 
212
; save the pci bus and device numbers
213
 
214
        mov     eax, [edx + IOCTL.input]
215
        movzx   ecx, byte[eax+1]
216
        mov     [ebx + device.pci_bus], ecx
217
        movzx   ecx, byte[eax+2]
218
        mov     [ebx + device.pci_dev], ecx
219
 
220
; Now, it's time to find the base mmio addres of the PCI device
221
 
222
        stdcall PCI_find_mmio, [ebx + device.pci_bus], [ebx + device.pci_dev] ; returns in eax
223
        test    eax, eax
224
        jz      .destroy
225
 
226
; Create virtual mapping of the physical memory
227
 
228
        invoke  MapIoMem, eax, 10000h, PG_SW+PG_NOCACHE
229
        mov     [ebx + device.mmio_addr], eax
230
 
231
; We've found the mmio address, find IRQ now
232
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
233
        and     eax, 0xff
234
        mov     [ebx + device.irq_line], eax
235
 
236
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
237
        [ebx + device.pci_dev]:1, [ebx + device.pci_bus]:1, [ebx + device.irq_line]:1, [ebx + device.mmio_addr]:8
238
 
239
; Ok, the eth_device structure is ready, let's probe the device
240
 
241
        mov     eax, [devices]                                          ; Add the device structure to our device list
242
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
243
        inc     [devices]                                               ;
244
 
245
        call    probe                                                   ; this function will output in eax
246
        test    eax, eax
247
        jnz     .err2
248
 
249
        DEBUGF  2,"Initialised OK\n"
250
 
251
        mov     [ebx + device.type], NET_TYPE_ETH
252
        invoke  NetRegDev
253
 
254
        cmp     eax, -1
255
        je      .destroy
256
 
257
        ret
258
 
259
; If the device was already loaded, find the device number and return it in eax
260
 
261
  .find_devicenum:
262
        DEBUGF  2,"Trying to find device number of already registered device\n"
263
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
264
                                                                        ; into a device number in edi
265
        mov     eax, edi                                                ; Application wants it in eax instead
266
        DEBUGF  2,"Kernel says: %u\n", eax
267
        ret
268
 
269
; If an error occured, remove all allocated data and exit (returning -1 in eax)
270
 
271
  .destroy:
272
        ; todo: reset device into virgin state
273
 
274
  .err2:
275
        dec     [devices]
276
  .err:
277
        invoke  KernelFree, ebx
278
  .fail:
279
        DEBUGF  2, "Failed to load\n"
280
        or      eax, -1
281
        ret
282
 
283
;------------------------------------------------------
284
endp
285
 
286
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
287
;;                                                                        ;;
288
;;        Actual Hardware dependent code starts here                      ;;
289
;;                                                                        ;;
290
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
291
 
292
align 4
293
unload:
294
        ; TODO: (in this particular order)
295
        ;
296
        ; - Stop the device
297
        ; - Detach int handler
298
        ; - Remove device from local list (device_list)
299
        ; - call unregister function in kernel
300
        ; - Remove all allocated structures and buffers the card used
301
 
302
        or      eax, -1
303
        ret
304
 
305
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
306
;;
307
;;  probe: enables the device (if it really is AR81XX)
308
;;
309
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
310
 
311
align 4
312
probe:
313
        DEBUGF  1,"Probing\n"
314
 
315
; Make the device a bus master
9146 hidnplayr 316
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.command
7809 hidnplayr 317
        or      al, PCI_CMD_MASTER + PCI_CMD_MMIO + PCI_CMD_PIO
318
        and     ax, not(PCI_CMD_INTX_DISABLE)
9146 hidnplayr 319
        invoke  PciWrite16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.command, eax
7809 hidnplayr 320
 
9146 hidnplayr 321
; get device ID
322
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.device_id
7827 hidnplayr 323
        mov     [ebx + device.pci_did], ax
324
 
325
        mov     esi, chiplist
326
  .loop:
327
        cmp     word[esi+2], ax
328
        je      .got_it
329
        add     esi, 8
330
        cmp     esi, chiplist + 6*8
331
        jbe     .loop
332
        DEBUGF  2, "Unknown chip: 0x%x, continuing anyway\n", ax
333
        jmp     .done
334
  .got_it:
335
        mov     eax, dword[esi+4]
336
        mov     [ebx + device.name], eax
337
        DEBUGF  1, "Chip type = %s\n", eax
338
  .done:
339
 
9146 hidnplayr 340
; get revision ID
341
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.revision_id
7809 hidnplayr 342
        and     eax, 0xff
9146 hidnplayr 343
        DEBUGF  1,"PCI Revision: %u\n", eax
7809 hidnplayr 344
        mov     [ebx + device.pci_rev], eax
345
        shr     al, ALX_PCI_REVID_SHIFT
346
        mov     [ebx + device.chip_rev], eax
9146 hidnplayr 347
        DEBUGF  1,"ALX Revision: %u\n", eax
7809 hidnplayr 348
 
9146 hidnplayr 349
        stdcall alx_reset_pcie
7809 hidnplayr 350
 
351
        mov     ecx, (ALX_PMCTRL_L0S_EN or ALX_PMCTRL_L1_EN or ALX_PMCTRL_ASPM_FCEN)
9146 hidnplayr 352
        stdcall alx_enable_aspm
7809 hidnplayr 353
 
9146 hidnplayr 354
        stdcall alx_reset_phy
7809 hidnplayr 355
 
9146 hidnplayr 356
        stdcall alx_reset_mac
7809 hidnplayr 357
 
9146 hidnplayr 358
; Setup link to put it in a known good starting state
359
        stdcall alx_write_phy_reg, ALX_MII_DBG_ADDR, 0
7809 hidnplayr 360
 
9146 hidnplayr 361
        mov     esi, [ebx + device.mmio_addr]
362
        mov     eax, dword[esi + ALX_DRV]
363
 
364
        stdcall alx_write_phy_reg, MII_ADVERTISE, ADVERTISE_CSMA or ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or ADVERTISE_PAUSE_CAP
365
 
366
        xor     eax, eax
367
        test    [ebx + device.pci_did], 1       ;;; FIXME: is gigabit device?
368
        jz      @f
369
        mov     eax, ADVERTISE_1000XFULL
370
  @@:
371
        stdcall alx_write_phy_reg, MII_CTRL1000, eax
372
 
373
        stdcall alx_write_phy_reg, MII_BMCR, BMCR_RESET or BMCR_ANENABLE or BMCR_ANRESTART
374
 
375
        stdcall alx_get_perm_macaddr
376
 
7809 hidnplayr 377
align 4
378
reset:
379
 
380
        DEBUGF  1,"Resetting\n"
381
 
382
; alx init_sw
383
 
9146 hidnplayr 384
        stdcall alx_identify_hw
7809 hidnplayr 385
 
386
        mov     [ebx + device.int_mask], ALX_ISR_MISC
387
        mov     [ebx + device.rx_ctrl], ALX_MAC_CTRL_WOLSPED_SWEN or ALX_MAC_CTRL_MHASH_ALG_HI5B or ALX_MAC_CTRL_BRD_EN or ALX_MAC_CTRL_PCRCE or ALX_MAC_CTRL_CRCE or ALX_MAC_CTRL_RXFC_EN or ALX_MAC_CTRL_TXFC_EN or (7 shl ALX_MAC_CTRL_PRMBLEN_SHIFT)
388
 
9146 hidnplayr 389
        stdcall alx_alloc_rings
7809 hidnplayr 390
 
9146 hidnplayr 391
        stdcall alx_configure
7809 hidnplayr 392
 
9146 hidnplayr 393
        stdcall alx_request_irq
7809 hidnplayr 394
 
395
; attach interrupt handler
396
 
397
        mov     eax, [ebx + device.irq_line]
398
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
399
        invoke  AttachIntHandler, eax, int_handler, ebx
400
        test    eax, eax
401
        jnz     @f
402
        DEBUGF  2,"Could not attach int handler!\n"
403
        or      eax, -1
404
        ret
405
  @@:
406
 
407
; Clear old interrupts
408
        mov     edi, [ebx + device.mmio_addr]
409
        mov     eax, not ALX_ISR_DIS
410
        mov     [edi + ALX_ISR], eax
411
 
9146 hidnplayr 412
        stdcall alx_irq_enable
7809 hidnplayr 413
 
9146 hidnplayr 414
; Set the MTU, kernel will be able to send now
7809 hidnplayr 415
        mov     [ebx + device.mtu], 1514
416
 
9146 hidnplayr 417
        stdcall alx_check_link
7809 hidnplayr 418
 
419
        DEBUGF  1,"Reset ok\n"
420
        xor     eax, eax
421
        ret
422
 
423
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
424
;;                                         ;;
425
;; Transmit                                ;;
426
;;                                         ;;
427
;; In: pointer to device structure in ebx  ;;
9146 hidnplayr 428
;; Out: eax = 0 on success                 ;;
7809 hidnplayr 429
;;                                         ;;
430
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9146 hidnplayr 431
align 16
7809 hidnplayr 432
proc transmit stdcall bufferptr
433
 
9146 hidnplayr 434
        spin_lock_irqsave
7809 hidnplayr 435
 
436
        mov     esi, [bufferptr]
437
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
438
        lea     eax, [esi + NET_BUFF.data]
439
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
440
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
441
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
442
        [eax+13]:2,[eax+12]:2
443
 
444
        cmp     [esi + NET_BUFF.length], 1514
9146 hidnplayr 445
        ja      .error
7809 hidnplayr 446
        cmp     [esi + NET_BUFF.length], 60
9146 hidnplayr 447
        jb      .error
7809 hidnplayr 448
 
449
; Program the descriptor
450
        mov     edi, [ebx + device.txq_write_idx]
451
        DEBUGF  1, "Using TPD: %u\n", edi
9146 hidnplayr 452
        cmp     dword[ebx + device.tpd_ring_virt + edi*4], 0
453
        jne     .overrun
7809 hidnplayr 454
        mov     dword[ebx + device.tpd_ring_virt + edi*4], esi
455
        shl     edi, 4
456
        lea     edi, [ebx + device.tpd_ring + edi]
457
        mov     eax, esi
458
        add     eax, [esi + NET_BUFF.offset]
459
        invoke  GetPhysAddr
460
        mov     [edi + alx_tpd.addr_l], eax
461
        mov     [edi + alx_tpd.addr_h], 0
462
 
463
        mov     ecx, [esi + NET_BUFF.length]
464
        mov     [edi + alx_tpd.length], cx
465
 
466
        mov     [edi + alx_tpd.word1], 1 shl TPD_EOP_SHIFT
467
 
468
; Update Producer Index
469
        mov     eax, [ebx + device.txq_write_idx]
470
        inc     eax
471
        and     eax, TX_RING_SIZE - 1
472
        mov     [ebx + device.txq_write_idx], eax
473
 
474
        mov     edi, [ebx + device.mmio_addr]
475
        mov     word[edi + ALX_TPD_PRI0_PIDX], ax
476
 
477
; Update stats
478
        inc     [ebx + device.packets_tx]
479
        mov     eax, [esi + NET_BUFF.length]
480
        add     dword[ebx + device.bytes_tx], eax
481
        adc     dword[ebx + device.bytes_tx + 4], 0
482
 
9147 hidnplayr 483
        spin_unlock_irqrestore
7809 hidnplayr 484
        xor     eax, eax
485
        ret
486
 
9146 hidnplayr 487
  .error:
488
        DEBUGF  2, "TX packet error\n"
489
        inc     [ebx + device.packets_tx_err]
7809 hidnplayr 490
        invoke  NetFree, [bufferptr]
9146 hidnplayr 491
 
492
        spin_unlock_irqrestore
7809 hidnplayr 493
        or      eax, -1
494
        ret
495
 
9146 hidnplayr 496
  .overrun:
497
        DEBUGF  2, "TX overrun\n"
498
        inc     [ebx + device.packets_tx_ovr]
499
        invoke  NetFree, [bufferptr]
7809 hidnplayr 500
 
9146 hidnplayr 501
        spin_unlock_irqrestore
502
        or      eax, -1
503
        ret
7809 hidnplayr 504
 
9146 hidnplayr 505
endp
7809 hidnplayr 506
 
507
;;;;;;;;;;;;;;;;;;;;;;;
508
;;                   ;;
509
;; Interrupt handler ;;
510
;;                   ;;
511
;;;;;;;;;;;;;;;;;;;;;;;
9146 hidnplayr 512
align 16
7809 hidnplayr 513
int_handler:
514
 
515
        push    ebx esi edi
516
 
9146 hidnplayr 517
        mov     ebx, [esp+4*4]
518
        DEBUGF  1,"INT for 0x%x\n", ebx
7809 hidnplayr 519
 
9146 hidnplayr 520
; TODO? if we are paranoid, we can check that the value from ebx is present in the current device_list
7809 hidnplayr 521
 
522
        mov     edi, [ebx + device.mmio_addr]
523
        mov     eax, [edi + ALX_ISR]
524
        test    eax, eax
9146 hidnplayr 525
        jz      .nothing
7809 hidnplayr 526
 
527
        or      eax, ALX_ISR_DIS
528
        mov     [edi + ALX_ISR], eax    ; ACK interrupt
9146 hidnplayr 529
        DEBUGF  1,"Status: %x\n", eax
7809 hidnplayr 530
 
531
        test    eax, ALX_ISR_TX_Q0
532
        jz      .no_tx
533
        DEBUGF  1,"TX interrupt\n"
534
        pusha
9146 hidnplayr 535
        stdcall alx_clean_tx_irq
7809 hidnplayr 536
        popa
537
  .no_tx:
538
 
539
        test    eax, ALX_ISR_RX_Q0
540
        jz      .no_rx
541
        DEBUGF  1,"RX interrupt\n"
542
        pusha
9146 hidnplayr 543
        stdcall alx_clean_rx_irq
7809 hidnplayr 544
        popa
545
 
546
  .no_rx:
547
        test    eax, ALX_ISR_PHY
548
        jz      .no_phy
549
        DEBUGF  1,"PHY interrupt\n"
550
        pusha
551
; TODO: queue link check and disable this interrupt cause meanwhile??
9146 hidnplayr 552
        stdcall alx_check_link
7809 hidnplayr 553
        popa
554
 
555
  .no_phy:
556
        mov     dword[edi + ALX_ISR], 0
557
        pop     edi esi ebx
9146 hidnplayr 558
        xor     eax, eax
559
        inc     eax
560
 
7809 hidnplayr 561
        ret
562
 
9146 hidnplayr 563
  .nothing:
564
        pop     edi esi ebx
565
        xor     eax, eax
7809 hidnplayr 566
 
9146 hidnplayr 567
        ret
7809 hidnplayr 568
 
9146 hidnplayr 569
proc alx_identify_hw stdcall
570
 
571
        cmp     [ebx + device.pci_did], ALX_DEV_ID_AR8131
572
        je      .alc
573
 
7809 hidnplayr 574
        cmp     [ebx + device.chip_rev], ALX_REV_C0
575
        ja      .einval
576
 
577
        mov     [ebx + device.max_dma_chnl], 2
578
        cmp     [ebx + device.chip_rev], ALX_REV_B0
9146 hidnplayr 579
        jb      @f
7809 hidnplayr 580
        mov     [ebx + device.max_dma_chnl], 4
581
  @@:
582
        xor     eax, eax
583
        ret
584
 
585
  .einval:
7827 hidnplayr 586
        DEBUGF  1, "Invalid revision 0x%x\n", [ebx + device.chip_rev]
587
 
7809 hidnplayr 588
        xor     eax, eax
589
        dec     eax
590
        ret
591
 
9146 hidnplayr 592
  .alc:
593
        mov     [ebx + device.max_dma_chnl], 2
594
        xor     eax, eax
595
        ret
7809 hidnplayr 596
 
9146 hidnplayr 597
endp
7809 hidnplayr 598
 
9146 hidnplayr 599
proc udelay stdcall microseconds
7809 hidnplayr 600
 
9146 hidnplayr 601
; FIXME
602
 
603
        push    esi ecx edx
604
        xor     esi, esi
605
        inc     esi
606
        invoke  Sleep
607
        pop     edx ecx esi
608
 
609
        ret
610
 
611
endp
612
 
613
proc alx_reset_pcie stdcall
614
 
615
        DEBUGF  1,"alx_reset_pcie\n"
616
 
617
; Make the device a bus master
618
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
619
        or      al, PCI_CMD_MASTER or PCI_CMD_MMIO or PCI_CMD_PIO
620
        and     ax, not(PCI_CMD_INTX_DISABLE)
621
        invoke  PciWrite16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
622
 
623
; Clear any powersaving setting
624
        invoke  PciWrite16, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x44, 0x0000        ;; FIXME
625
 
626
; Mask some pcie error bits
627
        mov     esi, [ebx + device.mmio_addr]
628
        mov     eax, [esi + ALX_UE_SVRT]
629
        and     eax, not(ALX_UE_SVRT_DLPROTERR or ALX_UE_SVRT_FCPROTERR)
630
        mov     [esi + ALX_UE_SVRT], eax
631
 
632
; pclk
633
        mov     eax, [esi + ALX_MASTER]
634
        or      eax, ALX_MASTER_WAKEN_25M
635
        and     eax, not (ALX_MASTER_PCLKSEL_SRDS)
636
        cmp     [ebx + device.chip_rev], ALX_REV_A1
637
        ja      @f
638
        test    [ebx + device.pci_rev], ALX_PCI_REVID_WITH_CR
639
        jz      @f
640
        or      eax, ALX_MASTER_PCLKSEL_SRDS
641
  @@:
642
        mov     [esi + ALX_MASTER], eax
643
 
644
        xor     eax, eax
645
        ret
646
 
647
endp
648
 
649
proc alx_clean_tx_irq stdcall
650
 
7809 hidnplayr 651
        mov     eax, [ebx + device.txq_read_idx]
652
        movzx   ecx, word[edi + ALX_TPD_PRI0_CIDX]
653
 
654
  .loop:
655
        cmp     eax, ecx
656
        je      .done
657
 
658
        DEBUGF  1,"Cleaning TX desc %u buffer 0x%x\n", eax, [ebx + device.tpd_ring_virt + eax*4]
659
        push    eax ecx
660
        invoke  NetFree, [ebx + device.tpd_ring_virt + eax*4]
661
        pop     ecx eax
9146 hidnplayr 662
        mov     [ebx + device.tpd_ring_virt + eax*4], 0
7809 hidnplayr 663
 
664
        inc     eax
665
        and     eax, TX_RING_SIZE-1
666
        jmp     .loop
667
  .done:
668
        mov     [ebx + device.txq_read_idx], eax
669
 
670
        ret
671
 
9146 hidnplayr 672
endp
7809 hidnplayr 673
 
9146 hidnplayr 674
proc alx_clean_rx_irq stdcall
7809 hidnplayr 675
 
676
        mov     ecx, [ebx + device.rxq_read_idx]
677
  .loop:
678
        shl     ecx, 2
679
        lea     esi, [ebx + device.rrd_ring + ecx*4]
680
        test    [esi + alx_rrd.word3], 1 shl RRD_UPDATED_SHIFT
681
        jz      .done
682
        and     [esi + alx_rrd.word3], not(1 shl RRD_UPDATED_SHIFT)
683
        DEBUGF  1,"RRD=%u updated\n", [ebx + device.rxq_read_idx]
684
 
685
        mov     eax, [esi + alx_rrd.word0]
686
        shr     eax, RRD_SI_SHIFT
687
        and     eax, RRD_SI_MASK
688
        cmp     eax, [ebx + device.rxq_read_idx]
689
;        jne     .error
690
        DEBUGF  1,"RFD=%u\n", eax
691
 
692
        mov     eax, [esi + alx_rrd.word0]
693
        shr     eax, RRD_NOR_SHIFT
694
        and     eax, RRD_NOR_MASK
695
        cmp     eax, 1
696
;        jne     .error
697
 
698
        mov     eax, [esi + alx_rrd.word3]
699
;        shr     eax, RRD_PKTLEN_SHIFT
700
        and     eax, RRD_PKTLEN_MASK
701
        sub     eax, 4                          ;;;;;
702
        mov     edx, [ebx + device.rfd_ring_virt + ecx]
703
        DEBUGF  1,"Received %u bytes in buffer 0x%x\n", eax, edx
704
 
705
        mov     [edx + NET_BUFF.length], eax
706
        mov     [edx + NET_BUFF.device], ebx
707
        mov     [edx + NET_BUFF.offset], NET_BUFF.data
708
 
709
; Update stats
710
        add     dword[ebx + device.bytes_rx], eax
711
        adc     dword[ebx + device.bytes_rx + 4], 0
712
        inc     [ebx + device.packets_rx]
713
 
714
; Allocate new descriptor
715
        push    esi ecx edx
716
        invoke  NetAlloc, RX_BUFFER_SIZE+NET_BUFF.data
717
        pop     edx ecx esi
718
        test    eax, eax
9146 hidnplayr 719
        jz      .rx_overrun
7809 hidnplayr 720
        mov     [ebx + device.rfd_ring_virt + ecx], eax
721
        add     eax, NET_BUFF.data
722
        invoke  GetPhysAddr
723
        mov     dword[ebx + device.rfd_ring + ecx*2], eax
724
 
725
        push    ecx ebx
726
        push    .retaddr
727
        push    edx
728
        jmp     [EthInput]
729
  .retaddr:
730
        pop     ebx ecx
731
 
732
        shr     ecx, 2
733
        inc     ecx
734
        and     ecx, RX_RING_SIZE-1
735
        jmp     .loop
736
 
9146 hidnplayr 737
  .rx_overrun:
738
        DEBUGF  2,"RX FIFO overrun\n"
739
        inc     [ebx + device.packets_rx_ovr]
740
        shr     ecx, 2
741
        inc     ecx
742
        and     ecx, RX_RING_SIZE-1
743
        jmp     .loop
744
 
7809 hidnplayr 745
  .done:
746
        shr     ecx, 2
747
        mov     [ebx + device.rxq_read_idx], ecx
748
 
749
; Update producer index
750
        mov     esi, [ebx + device.mmio_addr]
751
        mov     [esi + ALX_RFD_PIDX], cx
752
 
753
        ret
754
 
9146 hidnplayr 755
endp
7809 hidnplayr 756
 
9146 hidnplayr 757
; IN: ecx = additional bit flags (ALX_PMCTRL_L0S_EN, ALX_PMCTRL_L1_EN, ALX_PMCTRL_ASPM_FCEN)
758
proc alx_enable_aspm stdcall
7809 hidnplayr 759
 
760
        DEBUGF  1,"alx_enable_aspm (0x%x)\n", ecx
761
 
762
        mov     esi, [ebx + device.mmio_addr]
763
 
9146 hidnplayr 764
        cmp     [ebx + device.pci_did], ALX_DEV_ID_AR8131
765
        je      .alc_l1c
7809 hidnplayr 766
 
767
        cmp     [ebx + device.chip_rev], ALX_REV_A1
768
        ja      @f
9146 hidnplayr 769
        test    [ebx + device.pci_rev], ALX_PCI_REVID_WITH_CR
7809 hidnplayr 770
        jz      @f
9146 hidnplayr 771
        or      ecx, ALX_PMCTRL_L1_SRDS_EN or ALX_PMCTRL_L1_SRDSPLL_EN
7809 hidnplayr 772
  @@:
773
 
9146 hidnplayr 774
        mov     eax, dword[esi + ALX_PMCTRL]
775
        and     eax, not((ALX_PMCTRL_LCKDET_TIMER_MASK shl ALX_PMCTRL_LCKDET_TIMER_SHIFT) or \
776
                         (ALX_PMCTRL_L1REQ_TO_MASK shl ALX_PMCTRL_L1REQ_TO_SHIFT) or \
777
                         (ALX_PMCTRL_L1_TIMER_MASK shl ALX_PMCTRL_L1_TIMER_SHIFT) or \
778
                         ALX_PMCTRL_L1_SRDS_EN or \
779
                         ALX_PMCTRL_L1_SRDSPLL_EN or \
780
                         ALX_PMCTRL_L1_BUFSRX_EN or \
781
                         ALX_PMCTRL_SADLY_EN or \
782
                         ALX_PMCTRL_HOTRST_WTEN or \
783
                         ALX_PMCTRL_L0S_EN or \
784
                         ALX_PMCTRL_L1_EN or \
785
                         ALX_PMCTRL_ASPM_FCEN or \
786
                         ALX_PMCTRL_TXL1_AFTER_L0S or \
787
                         ALX_PMCTRL_RXL1_AFTER_L0S)
788
        or      eax, (ALX_PMCTRL_LCKDET_TIMER_DEF shl ALX_PMCTRL_LCKDET_TIMER_SHIFT) or \
789
                     (ALX_PMCTRL_RCVR_WT_1US or ALX_PMCTRL_L1_CLKSW_EN or ALX_PMCTRL_L1_SRDSRX_PWD) or \
790
                     (ALX_PMCTRL_L1REG_TO_DEF shl ALX_PMCTRL_L1REQ_TO_SHIFT) or \
791
                     (ALX_PMCTRL_L1_TIMER_16US shl ALX_PMCTRL_L1_TIMER_SHIFT)
7809 hidnplayr 792
        or      eax, ecx
793
        mov     dword[esi + ALX_PMCTRL], eax
794
 
795
        ret
796
 
9146 hidnplayr 797
  .alc_l1c:
7809 hidnplayr 798
 
9146 hidnplayr 799
        DEBUGF  1, "aspm for L1C\n"
800
 
801
        mov     esi, [ebx + device.mmio_addr]
802
        mov     eax, dword[esi + ALX_PMCTRL]
803
 
804
        and     eax, not(ALX_PMCTRL_L0S_EN or ALX_PMCTRL_L1_EN or ALX_PMCTRL_ASPM_FCEN)
805
        or      eax, (ALX_PMCTRL_LCKDET_TIMER_DEF shl ALX_PMCTRL_LCKDET_TIMER_SHIFT) ;\
806
                ;     or (0 shl ALX_PMCTRL_L1_TIMER_SHIFT)
807
 
808
        or      eax, ecx
809
 
810
;;; FIXME if(linkon)
811
 
812
        or      eax, (ALX_PMCTRL_L1_SRDS_EN or ALX_PMCTRL_L1_SRDSPLL_EN or ALX_PMCTRL_L1_BUFSRX_EN)
813
        and     eax, not(ALX_PMCTRL_L1_SRDSRX_PWD or ALX_PMCTRL_L1_CLKSW_EN or ALX_PMCTRL_L0S_EN or ALX_PMCTRL_L1_EN)
814
 
815
;;
816
 
817
        mov     dword[esi + ALX_PMCTRL], eax
818
 
819
        ret
820
 
821
endp
822
 
823
proc alx_reset_mac stdcall
824
 
7809 hidnplayr 825
        DEBUGF  1, "reset mac\n"
826
 
827
; disable all interrupts, RXQ/TXQ
828
        mov     esi, [ebx + device.mmio_addr]
829
        mov     dword[esi + ALX_MSIX_MASK], 0xffffffff
830
        mov     dword[esi + ALX_IMR], 0x0
831
        mov     dword[esi + ALX_ISR], ALX_ISR_DIS
832
 
9146 hidnplayr 833
        stdcall alx_stop_mac
7809 hidnplayr 834
 
835
; mac reset workaround
836
        mov     dword[esi + ALX_RFD_PIDX], 1
837
 
9146 hidnplayr 838
; disable l0s/l1 before MAC reset on some chips
7809 hidnplayr 839
        cmp     [ebx + device.chip_rev], ALX_REV_A1
840
        ja      @f
9146 hidnplayr 841
        test    [ebx + device.pci_rev], ALX_PCI_REVID_WITH_CR
7809 hidnplayr 842
        jz      @f
843
        mov     eax, [esi + ALX_PMCTRL]
844
        mov     edx, eax
9146 hidnplayr 845
        test    eax, ALX_PMCTRL_L1_EN or ALX_PMCTRL_L0S_EN
846
        jz      @f
7809 hidnplayr 847
        and     eax, not(ALX_PMCTRL_L1_EN or ALX_PMCTRL_L0S_EN)
848
        mov     [esi + ALX_PMCTRL], eax
849
  @@:
850
 
9146 hidnplayr 851
; reset whole MAC safely
7809 hidnplayr 852
        mov     eax, [esi + ALX_MASTER]
9146 hidnplayr 853
        or      eax, ALX_MASTER_DMA_MAC_RST or ALX_MASTER_OOB_DIS
7809 hidnplayr 854
        mov     [esi + ALX_MASTER], eax
855
 
856
; make sure it's real idle
9146 hidnplayr 857
        stdcall udelay, 10
7809 hidnplayr 858
 
9146 hidnplayr 859
        mov     ecx, ALX_DMA_MAC_RST_TO ; timeout
7809 hidnplayr 860
  .loop1:
861
        mov     eax, dword[esi + ALX_RFD_PIDX]
862
        test    eax, eax
863
        jz      @f
9146 hidnplayr 864
 
865
        stdcall udelay, 10
866
 
7809 hidnplayr 867
        dec     ecx
868
        jnz     .loop1
869
        jmp     .error
870
  @@:
9146 hidnplayr 871
 
7809 hidnplayr 872
  .loop2:
873
        mov     eax, dword[esi + ALX_MASTER]
874
        test    eax, ALX_MASTER_DMA_MAC_RST
875
        jz      @f
9146 hidnplayr 876
 
877
        stdcall udelay, 10
878
 
7809 hidnplayr 879
        dec     ecx
880
        jnz     .loop2
881
        jmp     .error
882
  @@:
883
 
884
; restore l0s/l1
885
        cmp     [ebx + device.chip_rev], ALX_REV_A1
886
        ja      @f
9146 hidnplayr 887
        test    [ebx + device.pci_rev], ALX_PCI_REVID_WITH_CR
7809 hidnplayr 888
        jz      @f
889
        or      eax, ALX_MASTER_PCLKSEL_SRDS
890
        mov     [esi + ALX_MASTER], eax
891
        mov     [esi + ALX_PMCTRL], edx
892
  @@:
893
 
9146 hidnplayr 894
        stdcall alx_reset_osc
7809 hidnplayr 895
 
896
; clear Internal OSC settings, switching OSC by hw itself, disable isolate for rev A devices
897
 
898
        mov     eax, [esi + ALX_MISC3]
899
        and     eax, not (ALX_MISC3_25M_BY_SW)
900
        or      eax, ALX_MISC3_25M_NOTO_INTNL
901
        mov     [esi + ALX_MISC3], eax
902
 
903
        mov     eax, [esi + ALX_MISC]
904
        and     eax, not (ALX_MISC_INTNLOSC_OPEN)
905
 
906
        cmp     [ebx + device.chip_rev], ALX_REV_A1
907
        ja      @f
908
        and     eax, not ALX_MISC_ISO_EN
909
  @@:
910
        mov     [esi + ALX_MISC], eax
911
 
9146 hidnplayr 912
        stdcall udelay, 20
7809 hidnplayr 913
 
914
; driver control speed/duplex, hash-alg
915
        mov     eax, [ebx + device.rx_ctrl]
916
        mov     [esi + ALX_MAC_CTRL], eax
917
 
9146 hidnplayr 918
; clk sw
7809 hidnplayr 919
        mov     eax, dword[esi + ALX_SERDES]
920
        or      eax, ALX_SERDES_MACCLK_SLWDWN or ALX_SERDES_PHYCLK_SLWDWN
921
        mov     dword[esi + ALX_SERDES], eax
922
 
923
        DEBUGF  1, "OK\n"
924
        xor     eax, eax
925
        ret
926
 
927
  .error:
928
        DEBUGF  1, "error\n"
929
        xor     eax, eax
930
        dec     eax
931
        ret
932
 
9146 hidnplayr 933
endp
7809 hidnplayr 934
 
9146 hidnplayr 935
proc alx_reset_phy stdcall
7809 hidnplayr 936
 
937
        DEBUGF  1, "Reset phy\n"
938
 
939
        mov     esi, [ebx + device.mmio_addr]
940
 
9146 hidnplayr 941
        mov     eax, dword [esi + ALX_PHY_CTRL]
942
        DEBUGF 1, "read ALX_PHY_CTRL = %x\n", eax
943
        and     eax, not (ALX_PHY_CTRL_DSPRST_OUT or ALX_PHY_CTRL_IDDQ or ALX_PHY_CTRL_GATE_25M or ALX_PHY_CTRL_POWER_DOWN or ALX_PHY_CTRL_CLS)
944
        or      eax, ALX_PHY_CTRL_RST_ANALOG
945
        or      eax, ALX_PHY_CTRL_HIB_PULSE or ALX_PHY_CTRL_HIB_EN ; assume pws is enabled
7809 hidnplayr 946
 
9146 hidnplayr 947
        DEBUGF 1, "write ALX_PHY_CTRL = %x\n", eax
948
        mov     [esi + ALX_PHY_CTRL], eax
949
 
950
        stdcall udelay, 5
951
 
952
        or      eax, ALX_PHY_CTRL_DSPRST_OUT
953
        mov     [esi + ALX_PHY_CTRL], eax
954
 
955
        stdcall udelay, 10
956
 
957
        or      eax, ALX_PHY_CTRL_DSPRST_OUT
958
        DEBUGF 1, "write ALX_PHY_CTRL = %x\n", eax
959
        mov     dword [esi + ALX_PHY_CTRL], eax
960
 
961
        stdcall udelay, 800
962
 
963
; PHY power saving & hibernate
964
        stdcall alx_write_phy_dbg, ALX_MIIDBG_LEGCYPS, ALX_LEGCYPS_DEF
965
        stdcall alx_write_phy_dbg, ALX_MIIDBG_SYSMODCTRL, ALX_SYSMODCTRL_IECHOADJ_DEF
966
        stdcall alx_write_phy_ext, ALX_MIIEXT_PCS, ALX_MIIEXT_VDRVBIAS, ALX_VDRVBIAS_DEF
967
 
968
; EEE advertisement
969
        mov     eax, [esi + ALX_LPI_CTRL]
970
        and     eax, not (ALX_LPI_CTRL_EN)
971
        mov     [esi + ALX_LPI_CTRL], eax
972
        stdcall alx_write_phy_ext, ALX_MIIEXT_ANEG, ALX_MIIEXT_LOCAL_EEEADV, 0
973
 
974
; PHY power saving
975
        stdcall alx_write_phy_dbg, ALX_MIIDBG_TST10BTCFG, ALX_TST10BTCFG_DEF
976
        stdcall alx_write_phy_dbg, ALX_MIIDBG_SRDSYSMOD, ALX_SRDSYSMOD_DEF
977
        stdcall alx_write_phy_dbg, ALX_MIIDBG_TST100BTCFG, ALX_TST100BTCFG_DEF
978
        stdcall alx_write_phy_dbg, ALX_MIIDBG_ANACTRL, ALX_ANACTRL_DEF
979
        stdcall alx_read_phy_dbg, ALX_MIIDBG_GREENCFG2
980
        and     eax, not ALX_GREENCFG2_GATE_DFSE_EN
981
        stdcall alx_write_phy_dbg, ALX_MIIDBG_GREENCFG2, eax
982
; rtl8139c, 120m issue */
983
        stdcall alx_write_phy_ext, ALX_MIIEXT_ANEG, ALX_MIIEXT_NLP78, ALX_MIIEXT_NLP78_120M_DEF
984
        stdcall alx_write_phy_ext, ALX_MIIEXT_ANEG, ALX_MIIEXT_S3DIG10, ALX_MIIEXT_S3DIG10_DEF
985
 
986
; TODO: link patch ?
987
 
988
; set PHY interrupt mask
989
        stdcall alx_read_phy_reg, ALX_MII_IER
7809 hidnplayr 990
        or      eax, ALX_IER_LINK_UP or ALX_IER_LINK_DOWN
9146 hidnplayr 991
        stdcall alx_write_phy_reg, ALX_MII_IER , eax
7809 hidnplayr 992
 
993
        DEBUGF  1, "OK\n"
994
        xor     eax, eax
995
        ret
996
 
997
  .error:
998
        DEBUGF  1, "error\n"
999
        xor     eax, eax
1000
        dec     eax
1001
        ret
1002
 
9146 hidnplayr 1003
endp
7809 hidnplayr 1004
 
9146 hidnplayr 1005
proc alx_set_macaddr stdcall
7809 hidnplayr 1006
 
9146 hidnplayr 1007
        mov     esi, [ebx + device.mmio_addr]
7809 hidnplayr 1008
 
9146 hidnplayr 1009
        mov     eax, dword[ebx + device.mac+2]
1010
        bswap   eax
1011
        mov     [esi + ALX_STAD0], eax
1012
        mov     ax, word[ebx + device.mac]
1013
        xchg    al, ah
1014
        mov     [esi + ALX_STAD1], ax
7809 hidnplayr 1015
 
9146 hidnplayr 1016
 
1017
        ret
1018
endp
1019
 
1020
proc alx_enable_osc stdcall
1021
 
7809 hidnplayr 1022
        mov     esi, [ebx + device.mmio_addr]
1023
 
9146 hidnplayr 1024
; rising edge
1025
        mov     eax, dword[esi + ALX_MISC]
1026
        and     eax, not ALX_MISC_INTNLOSC_OPEN
1027
        mov     dword[esi + ALX_MISC], eax
1028
        or      eax, ALX_MISC_INTNLOSC_OPEN
1029
        mov     dword[esi + ALX_MISC], eax
1030
 
1031
        ret
1032
 
1033
endp
1034
 
1035
proc alx_reset_osc stdcall
1036
 
1037
        mov     esi, [ebx + device.mmio_addr]
1038
 
7809 hidnplayr 1039
; clear Internal OSC settings, switching OSC by hw itself
1040
        mov     eax, dword[esi + ALX_MISC3]
1041
        and     eax, not ALX_MISC3_25M_BY_SW
1042
        or      eax, ALX_MISC3_25M_NOTO_INTNL
1043
        mov     dword[esi + ALX_MISC3], eax
1044
 
1045
; clk from chipset may be unstable 1s after de-assert of
1046
; PERST, driver need re-calibrate before enter Sleep for WoL
1047
        mov     eax, dword[esi + ALX_MISC]
1048
        cmp     [ebx + device.chip_rev], ALX_REV_B0
9146 hidnplayr 1049
        jb      .rev_A
7809 hidnplayr 1050
 
1051
; restore over current protection def-val, this val could be reset by MAC-RST
1052
        and     eax, not (ALX_MISC_PSW_OCP_MASK shl ALX_MISC_PSW_OCP_SHIFT)
1053
        or      eax, ALX_MISC_PSW_OCP_DEF shl ALX_MISC_PSW_OCP_SHIFT
1054
; a 0->1 change will update the internal val of osc
1055
        and     eax, not ALX_MISC_INTNLOSC_OPEN
1056
        mov     dword[esi + ALX_MISC], eax
1057
        or      eax, ALX_MISC_INTNLOSC_OPEN
1058
        mov     dword[esi + ALX_MISC], eax
1059
 
1060
; hw will automatically dis OSC after cab
1061
        mov     eax, dword[esi + ALX_MSIC2]
1062
        and     eax, not ALX_MSIC2_CALB_START
1063
        mov     dword[esi + ALX_MSIC2], eax
1064
        or      eax, ALX_MSIC2_CALB_START
1065
        mov     dword[esi + ALX_MSIC2], eax
1066
 
9146 hidnplayr 1067
        stdcall udelay, 20
7809 hidnplayr 1068
 
1069
        ret
1070
 
9146 hidnplayr 1071
  .rev_A:
7809 hidnplayr 1072
 
1073
;  disable isolate for rev A devices
9146 hidnplayr 1074
        and     eax, not (ALX_MISC_ISO_EN)
7809 hidnplayr 1075
        or      eax, ALX_MISC_INTNLOSC_OPEN
1076
        mov     dword[esi + ALX_MISC], eax
1077
        and     eax, not ALX_MISC_INTNLOSC_OPEN
1078
        mov     dword[esi + ALX_MISC], eax
1079
 
9146 hidnplayr 1080
        stdcall udelay, 20
7809 hidnplayr 1081
 
1082
        ret
1083
 
9146 hidnplayr 1084
endp
7809 hidnplayr 1085
 
9146 hidnplayr 1086
proc alx_read_macaddr stdcall
1087
 
7809 hidnplayr 1088
        mov     esi, [ebx + device.mmio_addr]
1089
        mov     eax, dword[esi + ALX_STAD0]
1090
        bswap   eax
1091
        mov     dword[ebx + device.mac + 2], eax
1092
        mov     ax, word[esi + ALX_STAD1]
1093
        xchg    al, ah
1094
        mov     word[ebx + device.mac], ax
1095
 
1096
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1097
        [ebx + device.mac+0]:2, [ebx + device.mac+1]:2, [ebx + device.mac+2]:2, [ebx + device.mac+3]:2, [ebx + device.mac+4]:2, [ebx + device.mac+5]:2
1098
 
1099
; check if it is a valid MAC
1100
        cmp     dword[ebx + device.mac], 0x0
1101
        jne     @f
1102
        cmp     word[ebx + device.mac + 4], 0x0
1103
        je      .invalid
1104
  @@:
1105
        cmp     dword[ebx + device.mac], 0xffffffff
1106
        jne     @f
1107
        cmp     word[ebx + device.mac + 4], 0xffff
1108
        je      .invalid
1109
  @@:
9146 hidnplayr 1110
        test    byte[ebx + device.mac + 5], 0x01        ; Multicast
1111
        jnz     .invalid
1112
  @@:
7809 hidnplayr 1113
        xor     eax, eax
1114
        ret
1115
 
1116
  .invalid:
7827 hidnplayr 1117
        DEBUGF  1, "Invalid MAC!\n"
7809 hidnplayr 1118
        xor     eax, eax
1119
        inc     eax
1120
        ret
1121
 
9146 hidnplayr 1122
endp
7809 hidnplayr 1123
 
9146 hidnplayr 1124
proc alx_get_perm_macaddr stdcall
7809 hidnplayr 1125
 
1126
; try to get it from register first
9146 hidnplayr 1127
        stdcall alx_read_macaddr
7809 hidnplayr 1128
        test    eax, eax
1129
        jz      .done
1130
 
1131
; try to load from efuse
1132
        mov     esi, [ebx + device.mmio_addr]
1133
        mov     ecx, ALX_SLD_MAX_TO
1134
  .loop1:
1135
        mov     eax, dword[esi + ALX_SLD]
1136
        test    eax, ALX_SLD_STAT or ALX_SLD_START
1137
        jz      @f
1138
 
1139
        dec     ecx
1140
        jz      .error
1141
 
1142
        push    esi ecx
1143
        xor     esi, esi
1144
        inc     esi
1145
        invoke  Sleep
1146
        pop     ecx esi
1147
        jmp     .loop1
1148
  @@:
1149
        or      eax, ALX_SLD_START
1150
        mov     dword[esi + ALX_SLD], eax
1151
 
1152
        mov     ecx, ALX_SLD_MAX_TO
1153
  .loop2:
1154
        mov     eax, dword[esi + ALX_SLD]
1155
        test    eax, ALX_SLD_START
1156
        jz      @f
1157
 
1158
        dec     ecx
1159
        jz      .error
1160
 
1161
        push    esi ecx
1162
        xor     esi, esi
1163
        inc     esi
1164
        invoke  Sleep
1165
        pop     ecx esi
1166
        jmp     .loop2
1167
  @@:
1168
 
9146 hidnplayr 1169
        stdcall alx_read_macaddr
7809 hidnplayr 1170
        test    eax, eax
1171
        jz      .done
1172
 
1173
; try to load from flash/eeprom (if present)
1174
        set_io  [ebx + device.io_addr], 0
1175
        set_io  [ebx + device.io_addr], ALX_EFLD
1176
        in      eax, dx
1177
        test    eax, ALX_EFLD_F_EXIST or ALX_EFLD_E_EXIST
1178
        jz      .error
1179
 
1180
        mov     ecx, ALX_SLD_MAX_TO
1181
  .loop3:
1182
        in      eax, dx
1183
        test    eax, ALX_EFLD_STAT or ALX_EFLD_START
1184
        jz      @f
1185
 
1186
        dec     ecx
1187
        jz      .error
1188
 
1189
        push    esi edx ecx
1190
        xor     esi, esi
1191
        inc     esi
1192
        invoke  Sleep
1193
        pop     ecx edx esi
1194
        jmp     .loop3
1195
  @@:
1196
        or      eax, ALX_EFLD_START
1197
        out     dx, eax
1198
 
1199
        mov     ecx, ALX_SLD_MAX_TO
1200
  .loop4:
1201
        in      eax, dx
1202
        test    eax, ALX_EFLD_START
1203
        jz      @f
1204
 
1205
        dec     ecx
1206
        jz      .error
1207
 
1208
        push    esi edx ecx
1209
        xor     esi, esi
1210
        inc     esi
1211
        invoke  Sleep
1212
        pop     ecx edx esi
1213
        jmp     .loop4
1214
  @@:
1215
 
9146 hidnplayr 1216
        stdcall alx_read_macaddr
7809 hidnplayr 1217
        test    eax, eax
1218
        jz      .done
1219
 
1220
  .error:
1221
        DEBUGF  1, "error obtaining MAC\n"
1222
        xor     eax, eax
1223
        dec     eax
1224
        ret
1225
 
1226
  .done:
1227
        DEBUGF  1, "MAC OK\n"
1228
        xor     eax, eax
1229
        ret
1230
 
9146 hidnplayr 1231
endp
7809 hidnplayr 1232
 
9146 hidnplayr 1233
proc alx_stop_mac stdcall
1234
 
7809 hidnplayr 1235
        DEBUGF  1,"alx_stop_mac\n"
1236
 
1237
        mov     esi, [ebx + device.mmio_addr]
1238
 
1239
        mov     eax, dword[esi + ALX_RXQ0]
1240
        and     eax, not ALX_RXQ0_EN
1241
        mov     dword[esi + ALX_RXQ0], eax
1242
 
1243
        mov     eax, dword[esi + ALX_TXQ0]
1244
        and     eax, not ALX_TXQ0_EN
1245
        mov     dword[esi + ALX_TXQ0], eax
1246
 
9146 hidnplayr 1247
        stdcall udelay, 40
7809 hidnplayr 1248
 
1249
        mov     eax, [ebx + device.rx_ctrl]
1250
        and     eax, not(ALX_MAC_CTRL_TX_EN or ALX_MAC_CTRL_RX_EN)
1251
        mov     [ebx + device.rx_ctrl], eax
1252
        mov     [esi + ALX_MAC_CTRL], eax
1253
 
1254
        mov     ecx, ALX_DMA_MAC_RST_TO
1255
  .loop:
1256
        mov     eax, [esi + ALX_MAC_STS]
1257
        test    eax, ALX_MAC_STS_IDLE
1258
        jz      .done
1259
 
9146 hidnplayr 1260
        stdcall udelay, 10
7809 hidnplayr 1261
 
1262
        dec     ecx
1263
        jnz     .loop
1264
 
1265
        DEBUGF  1,"alx_stop_mac timeout!\n"
1266
        xor     eax, eax
1267
        dec     eax
1268
        ret
1269
 
1270
  .done:
1271
        DEBUGF  1,"alx_stop_mac ok\n"
1272
        xor     eax, eax
1273
        ret
1274
 
9146 hidnplayr 1275
endp
7809 hidnplayr 1276
 
9146 hidnplayr 1277
proc alx_start_mac stdcall
7809 hidnplayr 1278
 
1279
        DEBUGF  1,"alx_start_mac\n"
1280
 
1281
        mov     esi, [ebx + device.mmio_addr]
1282
 
1283
        mov     eax, dword[esi + ALX_RXQ0]
1284
        or      eax, ALX_RXQ0_EN
1285
        mov     dword[esi + ALX_RXQ0], eax
1286
 
1287
        mov     eax, dword[esi + ALX_TXQ0]
1288
        or      eax, ALX_TXQ0_EN
1289
        mov     dword[esi + ALX_TXQ0], eax
1290
 
1291
        mov     eax, [ebx + device.rx_ctrl]
1292
        or      eax, ALX_MAC_CTRL_TX_EN or ALX_MAC_CTRL_RX_EN
1293
        and     eax, not ALX_MAC_CTRL_FULLD
9146 hidnplayr 1294
        test    [ebx + device.state], ETH_LINK_FULL_DUPLEX
1295
        jz      .no_fd
7809 hidnplayr 1296
        or      eax, ALX_MAC_CTRL_FULLD
9146 hidnplayr 1297
  .no_fd:
7809 hidnplayr 1298
        and     eax, not (ALX_MAC_CTRL_SPEED_MASK shl ALX_MAC_CTRL_SPEED_SHIFT)
9146 hidnplayr 1299
        mov     ecx, [ebx + device.state]
1300
        and     ecx, ETH_LINK_SPEED_MASK
1301
        cmp     ecx, ETH_LINK_SPEED_1G
1302
        jne      .10_100
7809 hidnplayr 1303
        or      eax, (ALX_MAC_CTRL_SPEED_1000 shl ALX_MAC_CTRL_SPEED_SHIFT)
9146 hidnplayr 1304
        jmp     .done
7809 hidnplayr 1305
 
1306
  .10_100:
1307
        or      eax, (ALX_MAC_CTRL_SPEED_10_100 shl ALX_MAC_CTRL_SPEED_SHIFT)
1308
 
9146 hidnplayr 1309
  .done:
1310
        DEBUGF  1,"mac ctrl=0x%x\n", eax
7809 hidnplayr 1311
        mov     [ebx + device.rx_ctrl], eax
1312
        mov     [esi + ALX_MAC_CTRL], eax
1313
 
1314
        ret
1315
 
9146 hidnplayr 1316
endp
7809 hidnplayr 1317
 
9146 hidnplayr 1318
proc alx_init_ring_ptrs stdcall
7809 hidnplayr 1319
 
1320
        DEBUGF  1,"alx_init_ring_ptrs\n"
1321
 
1322
        mov     esi, [ebx + device.mmio_addr]
1323
 
1324
; Receive descriptors
1325
        mov     [ebx + device.rxq_read_idx], 0
1326
        mov     [ebx + device.rxq_write_idx], 0
1327
;        mov     [ebx + device.rxq_rrd_read_idx], 0
1328
 
1329
        mov     dword[esi + ALX_RX_BASE_ADDR_HI], 0
1330
 
1331
        lea     eax, [ebx + device.rrd_ring]
1332
        invoke  GetPhysAddr
1333
        mov     dword[esi + ALX_RRD_ADDR_LO], eax
1334
        mov     dword[esi + ALX_RRD_RING_SZ], RX_RING_SIZE
1335
 
1336
        lea     eax, [ebx + device.rfd_ring]
1337
        invoke  GetPhysAddr
1338
        mov     dword[esi + ALX_RFD_ADDR_LO], eax
1339
        mov     dword[esi + ALX_RFD_RING_SZ], RX_RING_SIZE
1340
        mov     dword[esi + ALX_RFD_BUF_SZ], RX_BUFFER_SIZE
1341
 
1342
; Transmit descriptors
1343
        mov     [ebx + device.txq_read_idx], 0
1344
        mov     [ebx + device.txq_write_idx], 0
1345
 
1346
        mov     dword[esi + ALX_TX_BASE_ADDR_HI], 0
1347
 
1348
        lea     eax, [ebx + device.tpd_ring]
1349
        invoke  GetPhysAddr
1350
        mov     dword[esi + ALX_TPD_PRI0_ADDR_LO], eax
1351
        mov     dword[esi + ALX_TPD_RING_SZ], TX_RING_SIZE
1352
 
1353
; Load these pointers into the chip
1354
        mov     dword[esi + ALX_SRAM9], ALX_SRAM_LOAD_PTR
1355
 
1356
        xor     eax, eax
1357
 
1358
        ret
1359
 
9146 hidnplayr 1360
endp
7809 hidnplayr 1361
 
9146 hidnplayr 1362
proc alx_alloc_rings stdcall
7809 hidnplayr 1363
 
1364
        DEBUGF  1,"alx_alloc_rings\n"
1365
 
1366
        and     [ebx + device.int_mask], not ALX_ISR_ALL_QUEUES
1367
        or      [ebx + device.int_mask], ALX_ISR_TX_Q0 or ALX_ISR_RX_Q0
9146 hidnplayr 1368
        stdcall alx_reinit_rings
7809 hidnplayr 1369
 
1370
        ret
1371
 
9146 hidnplayr 1372
endp
7809 hidnplayr 1373
 
9146 hidnplayr 1374
proc alx_reinit_rings stdcall
7809 hidnplayr 1375
 
1376
        DEBUGF  1,"alx_reinit_rings\n"
1377
 
9146 hidnplayr 1378
        stdcall alx_free_rx_ring
1379
        stdcall alx_init_ring_ptrs
1380
        stdcall alx_refill_rx_ring
7809 hidnplayr 1381
 
1382
        ret
1383
 
9146 hidnplayr 1384
endp
7809 hidnplayr 1385
 
9146 hidnplayr 1386
proc alx_refill_rx_ring stdcall
7809 hidnplayr 1387
 
1388
        DEBUGF  1,"alx_refill_rx_ring\n"
1389
 
1390
        mov     ecx, [ebx + device.rxq_write_idx]
1391
  .loop:
1392
        cmp     dword[ebx + device.rfd_ring+ecx*sizeof.alx_rfd + alx_rfd.addr_l], 0
1393
        jne     .done
1394
 
1395
        invoke  NetAlloc, NET_BUFF.data+RX_BUFFER_SIZE
1396
        test    eax, eax
1397
        jz      .done
1398
        mov     [ebx + device.rfd_ring_virt + ecx*4], eax
1399
        add     eax, NET_BUFF.data
1400
        invoke  GetPhysAddr
1401
        mov     dword[ebx + device.rfd_ring+ecx*sizeof.alx_rfd + alx_rfd.addr_l], eax
1402
        mov     dword[ebx + device.rfd_ring+ecx*sizeof.alx_rfd + alx_rfd.addr_h], 0
1403
 
1404
        mov     eax, ecx
1405
        inc     ecx
1406
        and     ecx, RX_RING_SIZE - 1
1407
 
1408
        cmp     ecx, [ebx + device.rxq_read_idx]
1409
        jne     .loop
1410
 
1411
        mov     ecx, eax
1412
 
1413
  .done:
1414
        cmp     ecx, [ebx + device.rxq_write_idx]
1415
        je      .none
1416
 
1417
        mov     [ebx + device.rxq_write_idx], ecx
1418
        mov     esi, [ebx + device.mmio_addr]
1419
        mov     [esi + ALX_RFD_PIDX], cx
1420
 
1421
  .none:
1422
        xor     eax, eax
1423
 
1424
        ret
1425
 
9146 hidnplayr 1426
endp
7809 hidnplayr 1427
 
9146 hidnplayr 1428
proc alx_free_rx_ring stdcall
7809 hidnplayr 1429
 
1430
        DEBUGF  1,"alx_free_rx_ring\n"
1431
 
1432
        xor     ecx, ecx
1433
  .loop:
1434
        mov     eax, [ebx + device.rfd_ring_virt + ecx*4]
1435
        test    eax, eax
1436
        jz      .next
1437
 
1438
        invoke  NetFree, eax
1439
 
1440
        xor     eax, eax
1441
        mov     dword[ebx + device.rfd_ring+ecx*sizeof.alx_rfd + alx_rfd.addr_l], eax
1442
        mov     dword[ebx + device.rfd_ring+ecx*sizeof.alx_rfd + alx_rfd.addr_h], eax
1443
        mov     [ebx + device.rfd_ring_virt + ecx*4], eax
1444
 
1445
  .next:
1446
        inc     ecx
1447
        cmp     ecx, RX_RING_SIZE
1448
        jb      .loop
1449
 
1450
        ret
1451
 
9146 hidnplayr 1452
endp
7809 hidnplayr 1453
 
9146 hidnplayr 1454
proc alx_configure stdcall
7809 hidnplayr 1455
 
1456
        DEBUGF  1,"alx_configure\n"
1457
 
9146 hidnplayr 1458
        stdcall alx_configure_basic
1459
        stdcall alx_disable_rss
1460
        call    alx_set_rx_mode
7809 hidnplayr 1461
 
1462
        mov     esi, [ebx + device.mmio_addr]
1463
        mov     eax, [ebx + device.rx_ctrl]
1464
        mov     [esi + ALX_MAC_CTRL], eax
1465
 
1466
        xor     eax, eax
1467
        ret
1468
 
9146 hidnplayr 1469
endp
7809 hidnplayr 1470
 
9146 hidnplayr 1471
proc alx_irq_enable stdcall
7809 hidnplayr 1472
 
1473
        DEBUGF  1,"alx_irq_enable\n"
1474
 
1475
        mov     esi, [ebx + device.mmio_addr]
1476
        mov     dword[esi + ALX_ISR], 0
1477
        mov     eax, [ebx + device.int_mask]
1478
        mov     [esi + ALX_IMR], eax
1479
 
9146 hidnplayr 1480
        stdcall alx_post_write
7809 hidnplayr 1481
 
1482
        ret
1483
 
9146 hidnplayr 1484
endp
7809 hidnplayr 1485
 
9146 hidnplayr 1486
proc alx_irq_disable stdcall
1487
 
7809 hidnplayr 1488
        DEBUGF  1,"alx_irq_disable\n"
1489
 
1490
        mov     esi, [ebx + device.mmio_addr]
1491
        mov     dword[esi + ALX_ISR], ALX_ISR_DIS
1492
        mov     dword[esi + ALX_IMR], 0
1493
 
9146 hidnplayr 1494
        stdcall alx_post_write
7809 hidnplayr 1495
 
1496
        ret
1497
 
9146 hidnplayr 1498
endp
7809 hidnplayr 1499
 
9146 hidnplayr 1500
proc alx_post_write stdcall
7809 hidnplayr 1501
 
1502
        push    eax
1503
        mov     esi, [ebx + device.mmio_addr]
1504
        mov     eax, [esi]
1505
        pop     eax
1506
 
1507
        ret
1508
 
9146 hidnplayr 1509
endp
7809 hidnplayr 1510
 
9146 hidnplayr 1511
proc alx_configure_basic stdcall
7809 hidnplayr 1512
 
1513
        DEBUGF  1,"alx_configure_basic\n"
1514
 
1515
        mov     esi, [ebx + device.mmio_addr]
1516
 
9146 hidnplayr 1517
        stdcall alx_set_macaddr
7809 hidnplayr 1518
 
1519
        mov     dword[esi + ALX_CLK_GATE], ALX_CLK_GATE_ALL
1520
 
1521
; idle timeout to switch clk_125M
1522
        cmp     [ebx + device.chip_rev], ALX_REV_B0
1523
        jb      @f
1524
        mov     dword[esi + ALX_IDLE_DECISN_TIMER], ALX_IDLE_DECISN_TIMER_DEF
1525
  @@:
1526
 
1527
        mov     dword[esi + ALX_SMB_TIMER], SMB_TIMER * 500
1528
 
9146 hidnplayr 1529
; Interrupt moderation
7809 hidnplayr 1530
        mov     eax, [esi + ALX_MASTER]
1531
        or      eax, ALX_MASTER_IRQMOD2_EN or ALX_MASTER_IRQMOD1_EN or ALX_MASTER_SYSALVTIMER_EN
1532
        mov     [esi + ALX_MASTER], eax
1533
 
9146 hidnplayr 1534
; Set interupt moderator timer (max interupts per second)
1535
        mov     dword[esi + ALX_IRQ_MODU_TIMER], ((IMT) shl ALX_IRQ_MODU_TIMER1_SHIFT) or ((IMT / 2) shl ALX_IRQ_MODU_TIMER2_SHIFT)
7809 hidnplayr 1536
 
9146 hidnplayr 1537
; Interrupt re-trigger timeout
7809 hidnplayr 1538
        mov     dword[esi + ALX_INT_RETRIG], ALX_INT_RETRIG_TO
1539
 
1540
; tpd threshold to trig int
1541
        mov     dword[esi + ALX_TINT_TPD_THRSHLD], ITH_TPD
1542
        mov     dword[esi + ALX_TINT_TIMER], IMT
1543
 
1544
        mov     dword[esi + ALX_MTU], RX_BUFFER_SIZE + 8 ;;;;
1545
 
1546
        mov     dword[esi + ALX_TXQ1], (((RX_BUFFER_SIZE + 8 + 7) shr 3) or ALX_TXQ1_ERRLGPKT_DROP_EN)
1547
 
1548
; rxq, flow control
1549
 
1550
; TODO set ALX_RXQ2
1551
 
1552
; RXQ0
1553
        mov     eax, (ALX_RXQ0_NUM_RFD_PREF_DEF shl ALX_RXQ0_NUM_RFD_PREF_SHIFT) \
1554
                or (ALX_RXQ0_RSS_MODE_DIS shl ALX_RXQ0_RSS_MODE_SHIFT) \
1555
                or (ALX_RXQ0_IDT_TBL_SIZE_DEF shl ALX_RXQ0_IDT_TBL_SIZE_SHIFT) \
1556
                or ALX_RXQ0_RSS_HSTYP_ALL or ALX_RXQ0_RSS_HASH_EN or ALX_RXQ0_IPV6_PARSE_EN
1557
 
7827 hidnplayr 1558
        test    [ebx + device.pci_did], 1       ;;; FIXME: is gigabit device?
7809 hidnplayr 1559
        jz      @f
1560
        or      eax, ALX_RXQ0_ASPM_THRESH_100M shl ALX_RXQ0_ASPM_THRESH_SHIFT
1561
  @@:
9146 hidnplayr 1562
        mov     [esi + ALX_RXQ0], eax
7809 hidnplayr 1563
 
9146 hidnplayr 1564
; DMA
1565
        max_payload equ 2               ;;;; FIXME
7809 hidnplayr 1566
 
9146 hidnplayr 1567
        mov     eax, [esi + ALX_DMA]            ; Read and ignore?
1568
        ; Pre-B0 devices have 2 DMA channels
1569
        mov     eax, (ALX_DMA_RORDER_MODE_OUT shl ALX_DMA_RORDER_MODE_SHIFT) \
1570
                or ALX_DMA_RREQ_PRI_DATA \
1571
                or (max_payload shl ALX_DMA_RREQ_BLEN_SHIFT) \
1572
                or (ALX_DMA_WDLY_CNT_DEF shl ALX_DMA_WDLY_CNT_SHIFT ) \
1573
                or (ALX_DMA_RDLY_CNT_DEF shl ALX_DMA_RDLY_CNT_SHIFT ) \
1574
                or ((2-1) shl ALX_DMA_RCHNL_SEL_SHIFT)
7809 hidnplayr 1575
 
9146 hidnplayr 1576
        cmp     [ebx + device.chip_rev], ALX_REV_B0
1577
        jb      @f
1578
        ; B0 and newer have 4 DMA channels
1579
        mov     eax, (ALX_DMA_RORDER_MODE_OUT shl ALX_DMA_RORDER_MODE_SHIFT) \
1580
                or ALX_DMA_RREQ_PRI_DATA \
1581
                or (max_payload shl ALX_DMA_RREQ_BLEN_SHIFT) \
1582
                or (ALX_DMA_WDLY_CNT_DEF shl ALX_DMA_WDLY_CNT_SHIFT ) \
1583
                or (ALX_DMA_RDLY_CNT_DEF shl ALX_DMA_RDLY_CNT_SHIFT ) \
1584
                or ((4-1) shl ALX_DMA_RCHNL_SEL_SHIFT)
1585
  @@:
1586
        mov     [esi + ALX_DMA], eax
1587
 
7809 hidnplayr 1588
; default multi-tx-q weights
1589
        mov      eax, (ALX_WRR_PRI_RESTRICT_NONE shl ALX_WRR_PRI_SHIFT) \
1590
                 or (4 shl ALX_WRR_PRI0_SHIFT) \
1591
                 or (4 shl ALX_WRR_PRI1_SHIFT) \
1592
                 or (4 shl ALX_WRR_PRI2_SHIFT) \
1593
                 or (4 shl ALX_WRR_PRI3_SHIFT)
1594
        mov      [esi + ALX_WRR], eax
1595
 
1596
        ret
1597
 
9146 hidnplayr 1598
endp
7809 hidnplayr 1599
 
9146 hidnplayr 1600
proc alx_disable_rss stdcall
7809 hidnplayr 1601
 
1602
        DEBUGF  1,"alx_disable_rss\n"
1603
 
1604
        mov     esi, [ebx + device.mmio_addr]
1605
 
1606
        mov     eax, [esi + ALX_RXQ0]
1607
        and     eax, not (ALX_RXQ0_RSS_HASH_EN)
1608
        mov     [esi + ALX_RXQ0] , eax
1609
 
1610
        ret
1611
 
9146 hidnplayr 1612
endp
7809 hidnplayr 1613
 
9146 hidnplayr 1614
proc alx_set_rx_mode stdcall
1615
 
7809 hidnplayr 1616
        DEBUGF  1,"__alx_set_rx_mode\n"
1617
 
1618
        mov     esi, [ebx + device.mmio_addr]
1619
 
9146 hidnplayr 1620
; TODO: proper multicast
1621
 
7809 hidnplayr 1622
;        if (!(netdev->flags & IFF_ALLMULTI)) {
1623
;                netdev_for_each_mc_addr(ha, netdev)
1624
;                        alx_add_mc_addr(hw, ha->addr, mc_hash);
1625
;
1626
;                alx_write_mem32(hw, ALX_HASH_TBL0, mc_hash[0]);
1627
;                alx_write_mem32(hw, ALX_HASH_TBL1, mc_hash[1]);
1628
;        }
1629
 
1630
        mov     eax, [ebx + device.rx_ctrl]
9146 hidnplayr 1631
        or      eax, ALX_MAC_CTRL_PROMISC_EN or ALX_MAC_CTRL_MULTIALL_EN        ; FIXME: dont force promiscous mode..
7809 hidnplayr 1632
        mov     [ebx + device.rx_ctrl], eax
1633
        mov     dword[esi + ALX_MAC_CTRL], eax
1634
 
1635
        ret
1636
 
9146 hidnplayr 1637
endp
7809 hidnplayr 1638
 
9146 hidnplayr 1639
proc alx_check_link stdcall
7809 hidnplayr 1640
 
9146 hidnplayr 1641
        stdcall alx_clear_phy_intr
7809 hidnplayr 1642
 
1643
        mov     edx, [ebx + device.state]
1644
 
9146 hidnplayr 1645
        stdcall alx_get_phy_link
7809 hidnplayr 1646
        cmp     eax, 0
1647
        jl      .reset
1648
 
1649
        mov     esi, [ebx + device.mmio_addr]
1650
 
1651
        spin_lock_irqsave
1652
        or      [ebx + device.int_mask], ALX_ISR_PHY
1653
        mov     eax, [ebx + device.int_mask]
1654
        mov     [esi + ALX_IMR], eax
1655
        spin_unlock_irqrestore
1656
 
1657
        cmp     edx, [ebx + device.state]
1658
        je      .no_change
1659
 
1660
        cmp     [ebx + device.state], ETH_LINK_DOWN
1661
        je      .link_down
1662
 
9146 hidnplayr 1663
        stdcall alx_post_phy_link
7809 hidnplayr 1664
        mov     ecx, (ALX_PMCTRL_L0S_EN or ALX_PMCTRL_L1_EN or ALX_PMCTRL_ASPM_FCEN)
9146 hidnplayr 1665
        stdcall alx_enable_aspm
1666
        stdcall alx_start_mac
7809 hidnplayr 1667
 
1668
        invoke  NetLinkChanged
1669
 
1670
        ret
1671
 
1672
  .no_change:
1673
        DEBUGF  1, "link state unchanged\n"
1674
 
1675
        ret
1676
 
1677
  .link_down:
1678
; Link is now down
1679
 
9146 hidnplayr 1680
        stdcall alx_reset_mac
7809 hidnplayr 1681
        test    eax, eax
1682
        jnz     .reset
1683
 
9146 hidnplayr 1684
        stdcall alx_irq_disable
7809 hidnplayr 1685
 
1686
; MAC reset causes all HW settings to be lost, restore all
9146 hidnplayr 1687
        stdcall alx_reinit_rings
7809 hidnplayr 1688
        test    eax, eax
1689
        jnz     .reset
1690
 
9146 hidnplayr 1691
        stdcall alx_configure
7809 hidnplayr 1692
        mov     ecx, (ALX_PMCTRL_L1_EN or ALX_PMCTRL_ASPM_FCEN)
9146 hidnplayr 1693
        stdcall alx_enable_aspm
1694
        stdcall alx_post_phy_link
1695
        stdcall alx_irq_enable
7809 hidnplayr 1696
 
1697
        invoke  NetLinkChanged
1698
 
1699
        ret
1700
 
1701
  .reset:
9146 hidnplayr 1702
        DEBUGF  1, "alx_schedule_reset\n"
1703
;;;        stdcall alx_schedule_reset
7809 hidnplayr 1704
 
1705
        ret
1706
 
9146 hidnplayr 1707
endp
7809 hidnplayr 1708
 
9146 hidnplayr 1709
proc alx_post_phy_link stdcall
7809 hidnplayr 1710
 
9146 hidnplayr 1711
        DEBUGF  1, "alx_post_phy_link\n"
1712
 
7809 hidnplayr 1713
        cmp     [ebx + device.chip_rev], ALX_REV_B0
1714
        ja      .done
1715
 
1716
        cmp     [ebx + device.state], ETH_LINK_UNKNOWN
1717
        jae     @f
1718
 
9146 hidnplayr 1719
; TODO: vendor hocus-pocus to tune the PHY according the detected cable length
1720
        stdcall alx_write_phy_dbg, ALX_MIIDBG_AZ_ANADECT, ALX_AZ_ANADECT_DEF
1721
        stdcall alx_read_phy_ext, ALX_MIIEXT_AFE, ALX_MIIEXT_ANEG
1722
        and     eax, not (ALX_AFE_10BT_100M_TH)
1723
        stdcall alx_write_phy_ext, ALX_MIIEXT_AFE, ALX_MIIEXT_ANEG, eax
7809 hidnplayr 1724
 
1725
        ret
1726
  @@:
1727
 
1728
  .done:
1729
 
1730
        ret
1731
 
9146 hidnplayr 1732
endp
7809 hidnplayr 1733
 
9146 hidnplayr 1734
proc alx_clear_phy_intr stdcall
7809 hidnplayr 1735
 
9146 hidnplayr 1736
        DEBUGF  1,"alx_clear_phy_intr\n"
1737
        stdcall alx_read_phy_reg, ALX_MII_ISR
7809 hidnplayr 1738
 
1739
        ret
1740
 
9146 hidnplayr 1741
endp
7809 hidnplayr 1742
 
9146 hidnplayr 1743
proc alx_get_phy_link stdcall
7809 hidnplayr 1744
 
1745
        DEBUGF  1,"alx_get_phy_link\n"
1746
 
9146 hidnplayr 1747
        stdcall alx_read_phy_reg, MII_BMSR
1748
        stdcall alx_read_phy_reg, MII_BMSR
7809 hidnplayr 1749
 
1750
        mov     [ebx + device.state], ETH_LINK_DOWN
1751
 
1752
        test    ax, BMSR_LSTATUS
1753
        jnz     @f
1754
        DEBUGF  1,"link is down\n"
1755
        xor     eax, eax
1756
        ret
1757
  @@:
9146 hidnplayr 1758
        stdcall alx_read_phy_reg, ALX_MII_GIGA_PSSR
7809 hidnplayr 1759
        test    ax, ALX_GIGA_PSSR_SPD_DPLX_RESOLVED
1760
        jz      .wrong_speed
1761
 
1762
        DEBUGF  1,"link is up\n"
1763
 
1764
        test    ax, ALX_GIGA_PSSR_DPLX
1765
        jz      @f
9146 hidnplayr 1766
        or      [ebx + device.state], ETH_LINK_FULL_DUPLEX
7809 hidnplayr 1767
        DEBUGF  1,"full duplex\n"
1768
  @@:
1769
 
1770
        and     ax, ALX_GIGA_PSSR_SPEED
1771
        cmp     ax, ALX_GIGA_PSSR_1000MBS
1772
        jne     @f
9146 hidnplayr 1773
        or      [ebx + device.state], ETH_LINK_SPEED_1G
7809 hidnplayr 1774
        DEBUGF  1,"1 gigabit\n"
1775
        ret
1776
 
1777
  @@:
1778
        cmp     ax, ALX_GIGA_PSSR_100MBS
1779
        jne     @f
9146 hidnplayr 1780
        or      [ebx + device.state], ETH_LINK_SPEED_100M
1781
        DEBUGF  1,"100 Mbit\n"
7809 hidnplayr 1782
        ret
1783
 
1784
  @@:
1785
        cmp     ax, ALX_GIGA_PSSR_10MBS
1786
        jne     @f
9146 hidnplayr 1787
        or      [ebx + device.state], ETH_LINK_SPEED_10M
1788
        DEBUGF  1,"10 Mbit\n"
7809 hidnplayr 1789
        ret
1790
 
1791
  @@:
1792
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
1793
        DEBUGF  1,"speed unknown\n"
1794
        ret
1795
 
1796
  .wrong_speed:
1797
        DEBUGF  1,"wrong speed\n"
1798
        xor     eax, eax
1799
        dec     eax
1800
        ret
1801
 
9146 hidnplayr 1802
endp
7809 hidnplayr 1803
 
9146 hidnplayr 1804
proc alx_read_phy_reg stdcall, reg:dword
7809 hidnplayr 1805
 
9146 hidnplayr 1806
; FIXME: fixed clock
7809 hidnplayr 1807
 
9146 hidnplayr 1808
        DEBUGF  1,"alx_read_phy_reg reg=0x%x\n", [reg]:4
7809 hidnplayr 1809
 
1810
        mov     esi, [ebx + device.mmio_addr]
1811
 
1812
        mov     eax, [reg]
1813
        shl     eax, ALX_MDIO_REG_SHIFT
1814
        or      eax, ALX_MDIO_SPRES_PRMBL or (ALX_MDIO_CLK_SEL_25MD4 shl ALX_MDIO_CLK_SEL_SHIFT) or ALX_MDIO_START or ALX_MDIO_OP_READ
1815
        mov     dword[esi + ALX_MDIO], eax
1816
 
1817
        mov     ecx, ALX_MDIO_MAX_AC_TO
1818
  .loop:
1819
        mov     eax, dword[esi + ALX_MDIO]
1820
        test    eax, ALX_MDIO_BUSY
1821
        jz      .ready
1822
 
9146 hidnplayr 1823
        stdcall udelay, 10
7809 hidnplayr 1824
 
1825
        dec     ecx
1826
        jnz     .loop
1827
 
9146 hidnplayr 1828
        DEBUGF  1,"alx_read_phy_reg read timeout!\n"
7809 hidnplayr 1829
        xor     eax, eax
1830
        dec     eax
1831
        ret
1832
 
1833
  .ready:
1834
;        shr     eax, ALX_MDIO_DATA_SHIFT
1835
        and     eax, ALX_MDIO_DATA_MASK
1836
 
9146 hidnplayr 1837
        DEBUGF  1,"alx_read_phy_reg data=0x%x\n", eax:4
7809 hidnplayr 1838
 
1839
        ret
1840
 
1841
endp
1842
 
9146 hidnplayr 1843
proc  alx_read_phy_ext stdcall, dev:dword, reg:dword
7809 hidnplayr 1844
 
9146 hidnplayr 1845
; FIXME: fixed clock
7809 hidnplayr 1846
 
9146 hidnplayr 1847
        DEBUGF  1,"alx_read_phy_ext dev=0x%x reg=0x%x\n", [dev]:4, [reg]:4
7809 hidnplayr 1848
 
9146 hidnplayr 1849
        mov     esi, [ebx + device.mmio_addr]
7809 hidnplayr 1850
 
9146 hidnplayr 1851
        mov     eax, [dev]
1852
        shl     eax, ALX_MDIO_EXTN_DEVAD_SHIFT
1853
        mov     ax, word[reg]
1854
;        shl     eax, ALX_MDIO_EXTN_REG_SHIFT
1855
        mov     dword[esi + ALX_MDIO_EXTN], eax
7809 hidnplayr 1856
 
9146 hidnplayr 1857
        mov     eax, ALX_MDIO_SPRES_PRMBL or (ALX_MDIO_CLK_SEL_25MD4 shl ALX_MDIO_CLK_SEL_SHIFT) or ALX_MDIO_START or ALX_MDIO_OP_READ or ALX_MDIO_MODE_EXT
1858
        mov     dword[esi + ALX_MDIO], eax
7809 hidnplayr 1859
 
9146 hidnplayr 1860
        mov     ecx, ALX_MDIO_MAX_AC_TO
1861
  .loop:
1862
        mov     eax, dword[esi + ALX_MDIO]
1863
        test    eax, ALX_MDIO_BUSY
1864
        jz      .ready
1865
 
1866
        stdcall udelay, 10
1867
 
1868
        dec     ecx
1869
        jnz     .loop
1870
 
1871
        DEBUGF  1,"alx_read_phy_ext read timeout!\n"
1872
        xor     eax, eax
1873
        dec     eax
1874
        ret
1875
 
1876
  .ready:
1877
;        shr     eax, ALX_MDIO_DATA_SHIFT
1878
        and     eax, ALX_MDIO_DATA_MASK
1879
 
1880
        DEBUGF  1,"alx_read_phy_ext data=0x%x\n", eax:4
1881
 
1882
        ret
1883
 
1884
endp
1885
 
1886
proc  alx_write_phy_reg stdcall, reg:dword, val:dword
1887
 
1888
; FIXME: fixed clock
1889
 
1890
        DEBUGF  1,"alx_write_phy_reg reg=0x%x data=0x%x\n", [reg]:4, [val]:4
1891
 
7809 hidnplayr 1892
        mov     esi, [ebx + device.mmio_addr]
1893
 
1894
        mov     eax, [reg]
1895
        shl     eax, ALX_MDIO_REG_SHIFT
1896
        mov     ax, word[val]                   ; data must be in 16 lower bits :)
1897
        or      eax, ALX_MDIO_SPRES_PRMBL or (ALX_MDIO_CLK_SEL_25MD4 shl ALX_MDIO_CLK_SEL_SHIFT) or ALX_MDIO_START
1898
        mov     dword[esi + ALX_MDIO], eax
1899
 
1900
        mov     ecx, ALX_MDIO_MAX_AC_TO
1901
  .loop:
1902
        mov     eax, dword[esi + ALX_MDIO]
1903
        test    eax, ALX_MDIO_BUSY
1904
        jz      .ready
1905
 
9146 hidnplayr 1906
        stdcall udelay, 10
7809 hidnplayr 1907
 
1908
        dec     ecx
1909
        jnz     .loop
1910
 
9146 hidnplayr 1911
        DEBUGF  1,"alx_write_phy_reg timeout!\n"
7809 hidnplayr 1912
        xor     eax, eax
1913
        dec     eax
1914
        ret
1915
 
1916
  .ready:
9146 hidnplayr 1917
        DEBUGF  1,"alx_write_phy_reg OK\n"
7809 hidnplayr 1918
        xor     eax, eax
1919
 
1920
        ret
1921
endp
1922
 
9146 hidnplayr 1923
proc  alx_write_phy_dbg stdcall, reg:dword, val:dword
1924
 
1925
        DEBUGF  1,"alx_write_phy_dbg\n"
1926
 
1927
        stdcall alx_write_phy_reg, ALX_MII_DBG_ADDR, [reg]
1928
        test    eax, eax
1929
        jnz     @f
1930
        stdcall alx_write_phy_reg, ALX_MII_DBG_DATA, [val]
1931
 
1932
        ret
1933
  @@:
1934
        DEBUGF  1,"alx_write_phy_dbg ERROR\n"
1935
 
1936
        ret
1937
 
1938
endp
1939
 
1940
proc  alx_read_phy_dbg stdcall, reg:dword
1941
 
1942
        DEBUGF  1,"alx_read_phy_dbg\n"
1943
 
1944
        stdcall alx_write_phy_reg, ALX_MII_DBG_ADDR, [reg]
1945
        test    eax, eax
1946
        jnz     @f
1947
        stdcall alx_read_phy_reg, ALX_MII_DBG_DATA
1948
 
1949
        ret
1950
  @@:
1951
        DEBUGF  1,"alx_read_phy_dbg ERROR\n"
1952
 
1953
        ret
1954
 
1955
endp
1956
 
1957
proc  alx_write_phy_ext stdcall, dev:dword, reg:dword, val:dword
1958
 
1959
; FIXME: fixed clock
1960
 
1961
        DEBUGF  1,"alx_write_phy_ext dev=0x%x reg=0x%x, data=0x%x\n", [dev]:4, [reg]:4, [val]:4
1962
 
1963
        mov     esi, [ebx + device.mmio_addr]
1964
 
1965
        mov     eax, [dev]
1966
        shl     eax, ALX_MDIO_EXTN_DEVAD_SHIFT
1967
        mov     ax, word[reg]
1968
;        shl     eax, ALX_MDIO_EXTN_REG_SHIFT
1969
        mov     dword[esi + ALX_MDIO_EXTN], eax
1970
 
1971
        movzx   eax, word[val]                   ; data must be in 16 lower bits :)
1972
        or      eax, ALX_MDIO_SPRES_PRMBL or (ALX_MDIO_CLK_SEL_25MD4 shl ALX_MDIO_CLK_SEL_SHIFT) or ALX_MDIO_START or ALX_MDIO_MODE_EXT
1973
        mov     dword[esi + ALX_MDIO], eax
1974
 
1975
        mov     ecx, ALX_MDIO_MAX_AC_TO
1976
  .loop:
1977
        mov     eax, dword[esi + ALX_MDIO]
1978
        test    eax, ALX_MDIO_BUSY
1979
        jz      .ready
1980
 
1981
        stdcall udelay, 10
1982
 
1983
        dec     ecx
1984
        jnz     .loop
1985
 
1986
        DEBUGF  1,"alx_write_phy_ext timeout!\n"
1987
        xor     eax, eax
1988
        dec     eax
1989
        ret
1990
 
1991
  .ready:
1992
        DEBUGF  1,"alx_write_phy_ext OK\n"
1993
        xor     eax, eax
1994
 
1995
        ret
1996
endp
1997
 
7809 hidnplayr 1998
alx_request_irq:
1999
 
2000
        DEBUGF  1,"Request IRQ\n"
2001
 
2002
        mov     esi, [ebx + device.mmio_addr]
2003
 
2004
; Only legacy interrupts supported for now.
2005
        mov     dword[esi + ALX_MSI_RETRANS_TIMER], 0
2006
 
2007
        ret
2008
 
2009
; End of code
2010
 
2011
data fixups
2012
end data
2013
 
2014
include '../peimport.inc'
2015
 
2016
my_service      db 'AR81XX',0                    ; max 16 chars include zero
2017
 
7827 hidnplayr 2018
chiplist:
2019
                dd (ALX_DEV_ID_AR8131 shl 16) or ALX_VEN_ID, ar8131_sz
9150 hidnplayr 2020
                dd (ALX_DEV_ID_AR8132 shl 16) or ALX_VEN_ID, ar8132_sz
2021
                dd (ALX_DEV_ID_AR8151_1 shl 16) or ALX_VEN_ID, ar8151_1_sz
2022
                dd (ALX_DEV_ID_AR8151_2 shl 16) or ALX_VEN_ID, ar8151_2_sz
2023
                dd (ALX_DEV_ID_AR8152_1 shl 16) or ALX_VEN_ID, ar8152_1_sz
2024
                dd (ALX_DEV_ID_AR8152_2 shl 16) or ALX_VEN_ID, ar8152_2_sz
7827 hidnplayr 2025
                dd (ALX_DEV_ID_AR8161 shl 16) or ALX_VEN_ID, ar8161_sz
9150 hidnplayr 2026
                dd (ALX_DEV_ID_E2200 shl 16) or ALX_VEN_ID, e2200_sz
2027
                dd (ALX_DEV_ID_E2400 shl 16) or ALX_VEN_ID, e2400_sz
2028
                dd (ALX_DEV_ID_E2500 shl 16) or ALX_VEN_ID, e2500_sz
7827 hidnplayr 2029
                dd (ALX_DEV_ID_AR8162 shl 16) or ALX_VEN_ID, ar8162_sz
2030
                dd (ALX_DEV_ID_AR8171 shl 16) or ALX_VEN_ID, ar8171_sz
2031
                dd (ALX_DEV_ID_AR8172 shl 16) or ALX_VEN_ID, ar8172_sz
2032
                dd 0
2033
 
2034
ar8131_sz       db "AR8131", 0
9150 hidnplayr 2035
ar8132_sz       db "AR8132", 0
2036
ar8151_1_sz     db "AR8151 rev1", 0
2037
ar8151_2_sz     db "AR8151 rev2", 0
2038
ar8152_1_sz     db "AR8152 rev1", 0
2039
ar8152_2_sz     db "AR8152 rev2", 0
7827 hidnplayr 2040
ar8161_sz       db "AR8161", 0
2041
ar8162_sz       db "AR8162", 0
2042
ar8171_sz       db "QCA8171", 0
2043
ar8172_sz       db "QCA8172", 0
2044
e2200_sz        db "Killer E2200", 0
2045
e2400_sz        db "Killer E2400", 0
2046
e2500_sz        db "Killer E2500", 0
2047
 
7809 hidnplayr 2048
include_debug_strings
2049
 
2050
align 4
2051
devices         dd 0
2052
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
2053