Subversion Repositories Kolibri OS

Rev

Rev 7827 | Rev 9147 | 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