Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
4467 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
;;  DEC 21x4x driver for KolibriOS                                 ;;
7
;;                                                                 ;;
8
;;  Based on dec21140.Asm from Solar OS by                         ;;
9
;;     Eugen Brasoveanu,                                           ;;
10
;;       Ontanu Bogdan Valentin                                    ;;
11
;;                                                                 ;;
12
;;  Written by hidnplayr@kolibrios.org                             ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
5046 hidnplayr 19
format PE DLL native
20
entry START
3545 hidnplayr 21
 
5046 hidnplayr 22
        CURRENT_API             = 0x0200
23
        COMPATIBLE_API          = 0x0100
24
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
3545 hidnplayr 25
 
26
        MAX_DEVICES             = 16
27
 
5180 hidnplayr 28
        TX_RING_SIZE            = 4
29
        RX_RING_SIZE            = 4
3545 hidnplayr 30
 
31
        __DEBUG__               = 1
5046 hidnplayr 32
        __DEBUG_LEVEL__         = 2     ; 1 = verbose, 2 = errors only
3545 hidnplayr 33
 
5046 hidnplayr 34
section '.flat' readable writable executable
35
 
36
include '../proc32.inc'
4467 hidnplayr 37
include '../struct.inc'
38
include '../macros.inc'
3545 hidnplayr 39
include '../fdo.inc'
5074 hidnplayr 40
include '../netdrv.inc'
3545 hidnplayr 41
 
5180 hidnplayr 42
; Capability flags used in chiplist
43
        FLAG_HAS_MII            = 1 shl 0
44
        FLAG_HAS_MEDIA_TABLE    = 1 shl 1
45
        FLAG_CSR12_IN_SROM      = 1 shl 2
46
        FLAG_ALWAYS_CHECK_MII   = 1 shl 3
47
        FLAG_HAS_ACPI           = 1 shl 4
48
 
49
; Chip id's
50
        DC21040                 = 0
51
        DC21041                 = 1
52
        DC21140                 = 2
53
        DC21142                 = 3
54
        DC21143                 = 3
55
        LC82C168                = 4
56
        MX98713                 = 5
57
        MX98715                 = 6
58
        MX98725                 = 7
59
 
3545 hidnplayr 60
;-------------------------------------------
61
; configuration registers
62
;-------------------------------------------
63
CFCS                    = 4             ; configuration and status register
64
 
65
CSR0                    = 0x00          ; Bus mode
66
CSR1                    = 0x08          ; Transmit Poll Command
67
CSR2                    = 0x10          ; Receive Poll Command
68
CSR3                    = 0x18          ; Receive list base address
69
CSR4                    = 0x20          ; Transmit list base address
70
CSR5                    = 0x28          ; Status
71
CSR6                    = 0x30          ; Operation mode
72
CSR7                    = 0x38          ; Interrupt enable
73
CSR8                    = 0x40          ; Missed frames and overflow counter
74
CSR9                    = 0x48          ; Boot ROM, serial ROM, and MII management
75
CSR10                   = 0x50          ; Boot ROM programming address
76
CSR11                   = 0x58          ; General-purpose timer
77
CSR12                   = 0x60          ; General-purpose port
78
CSR13                   = 0x68
79
CSR14                   = 0x70
80
CSR15                   = 0x78          ; Watchdog timer
81
 
82
;--------bits/commands of CSR0-------------------
83
CSR0_RESET              = 1b
84
 
85
CSR0_WIE                = 1 shl 24      ; Write and Invalidate Enable
86
CSR0_RLE                = 1 shl 23      ; PCI Read Line Enable
87
CSR0_RML                = 1 shl 21      ; PCI Read Multiple
88
 
89
CSR0_CACHEALIGN_NONE    = 00b shl 14
90
CSR0_CACHEALIGN_32      = 01b shl 14
91
CSR0_CACHEALIGN_64      = 10b shl 14
92
CSR0_CACHEALIGN_128     = 11b shl 14
93
 
94
; using values from linux driver..
95
CSR0_DEFAULT            = CSR0_WIE + CSR0_RLE + CSR0_RML + CSR0_CACHEALIGN_NONE
96
 
97
;------- CSR5 -STATUS- bits --------------------------------
5180 hidnplayr 98
CSR5_TI                 = 0x00000001    ;1 shl 0        ; Transmit interupt - frame transmition completed
99
CSR5_TPS                = 0x00000002    ;1 shl 1        ; Transmit process stopped
100
CSR5_TU                 = 0x00000004    ;1 shl 2        ; Transmit Buffer unavailable
101
CSR5_TJT                = 0x00000008    ;1 shl 3        ; Transmit Jabber Timeout (transmitter had been excessively active)
102
CSR5_LP                 = 0x00000010    ;1 shl 4        ; Link pass
103
CSR5_UNF                = 0x00000020    ;1 shl 5        ; Transmit underflow - FIFO underflow
104
CSR5_RI                 = 0x00000040    ;1 shl 6        ; Receive Interrupt
105
CSR5_RU                 = 0x00000080    ;1 shl 7        ; Receive Buffer unavailable
106
CSR5_RPS                = 0x00000100    ;1 shl 8        ; Receive Process stopped
107
CSR5_RWT                = 0x00000200    ;1 shl 9        ; Receive Watchdow Timeout
108
CSR5_ETI                = 0x00000400    ;1 shl 10       ; Early transmit Interrupt
109
CSR5_GTE                = 0x00000800    ;1 shl 11       ; General Purpose Timer Expired
110
CSR5_LF                 = 0x00001000    ;1 shl 12       ; Link Fail
111
CSR5_FBE                = 0x00002000    ;1 shl 13       ; Fatal bus error
112
CSR5_ERI                = 0x00004000    ;1 shl 14       ; Early receive Interrupt
113
CSR5_AIS                = 0x00008000    ;1 shl 15       ; Abnormal interrupt summary
114
CSR5_NIS                = 0x00010000    ;1 shl 16       ; normal interrupt summary
3545 hidnplayr 115
CSR5_RS_SH              = 17            ; Receive process state  -shift
116
CSR5_RS_MASK            = 111b          ;                        -mask
117
CSR5_TS_SH              = 20            ; Transmit process state -shift
118
CSR5_TS_MASK            = 111b          ;                        -mask
119
CSR5_EB_SH              = 23            ; Error bits             -shift
120
CSR5_EB_MASK            = 111b          ; Error bits             -mask
121
 
122
;CSR5 TS values
123
CSR5_TS_STOPPED                 = 000b
124
CSR5_TS_RUNNING_FETCHING_DESC   = 001b
125
CSR5_TS_RUNNING_WAITING_TX      = 010b
126
CSR5_TS_RUNNING_READING_BUFF    = 011b
127
CSR5_TS_RUNNING_SETUP_PCKT      = 101b
128
CSR5_TS_SUSPENDED               = 110b
129
CSR5_TS_RUNNING_CLOSING_DESC    = 111b
130
 
131
;------- CSR6 -OPERATION MODE- bits --------------------------------
132
CSR6_HP                 = 1 shl 0       ; Hash/Perfect Receive Filtering mode
133
CSR6_SR                 = 1 shl 1       ; Start/Stop receive
134
CSR6_HO                 = 1 shl 2       ; Hash only Filtering mode
135
CSR6_PB                 = 1 shl 3       ; Pass bad frames
136
CSR6_IF                 = 1 shl 4       ; Inverse filtering
137
CSR6_SB                 = 1 shl 5       ; Start/Stop backoff counter
5180 hidnplayr 138
CSR6_PR                 = 1 shl 6       ; Promiscuous mode -default after reset
3545 hidnplayr 139
CSR6_PM                 = 1 shl 7       ; Pass all multicast
140
CSR6_F                  = 1 shl 9       ; Full Duplex mode
141
CSR6_OM_SH              = 10            ; Operating Mode -shift
142
CSR6_OM_MASK            = 11b           ;                -mask
143
CSR6_FC                 = 1 shl 12      ; Force Collision Mode
144
CSR6_ST                 = 1 shl 13      ; Start/Stop Transmission Command
145
CSR6_TR_SH              = 14            ; Threshold Control      -shift
146
CSR6_TR_MASK            = 11b           ;                        -mask
147
CSR6_CA                 = 1 shl 17      ; Capture Effect Enable
148
CSR6_PS                 = 1 shl 18      ; Port select SRL / MII/SYM
149
CSR6_HBD                = 1 shl 19      ; Heartbeat Disable
150
CSR6_SF                 = 1 shl 21      ; Store and Forward -transmit full packet only
151
CSR6_TTM                = 1 shl 22      ; Transmit Threshold Mode -
152
CSR6_PCS                = 1 shl 23      ; PCS active and MII/SYM port operates in symbol mode
153
CSR6_SCR                = 1 shl 24      ; Scrambler Mode
154
CSR6_MBO                = 1 shl 25      ; Must Be One
155
CSR6_RA                 = 1 shl 30      ; Receive All
156
CSR6_SC                 = 1 shl 31      ; Special Capture Effect Enable
157
 
158
 
159
;------- CSR7 -INTERRUPT ENABLE- bits --------------------------------
160
CSR7_TI                 = 1 shl 0       ; transmit Interrupt Enable (set with CSR7<16> & CSR5<0> )
161
CSR7_TS                 = 1 shl 1       ; transmit Stopped Enable (set with CSR7<15> & CSR5<1> )
162
CSR7_TU                 = 1 shl 2       ; transmit buffer underrun Enable (set with CSR7<16> & CSR5<2> )
163
CSR7_TJ                 = 1 shl 3       ; transmit jabber timeout enable (set with CSR7<15> & CSR5<3> )
164
CSR7_UN                 = 1 shl 5       ; underflow Interrupt enable (set with CSR7<15> & CSR5<5> )
165
CSR7_RI                 = 1 shl 6       ; receive Interrupt enable (set with CSR7<16> & CSR5<5> )
166
CSR7_RU                 = 1 shl 7       ; receive buffer unavailable enable (set with CSR7<15> & CSR5<7> )
167
CSR7_RS                 = 1 shl 8       ; Receive stopped enable (set with CSR7<15> & CSR5<8> )
168
CSR7_RW                 = 1 shl 9       ; receive watchdog timeout enable (set with CSR7<15> & CSR5<9> )
169
CSR7_ETE                = 1 shl 10      ; Early transmit Interrupt enable (set with CSR7<15> & CSR5<10> )
170
CSR7_GPT                = 1 shl 11      ; general purpose timer enable (set with CSR7<15> & CSR5<11> )
171
CSR7_FBE                = 1 shl 13      ; Fatal bus error enable (set with CSR7<15> & CSR5<13> )
172
CSR7_ERE                = 1 shl 14      ; Early receive enable (set with CSR7<16> & CSR5<14> )
173
CSR7_AI                 = 1 shl 15      ; Abnormal Interrupt Summary Enable (enables CSR5<0,3,7,8,9,10,13>)
174
CSR7_NI                 = 1 shl 16      ; Normal Interrup Enable (enables CSR5<0,2,6,11,14>)
175
 
176
CSR7_DEFAULT            = CSR7_TI + CSR7_TS + CSR7_RI + CSR7_RS + CSR7_TU + CSR7_TJ + CSR7_UN + \
177
                                        CSR7_RU + CSR7_RW + CSR7_FBE + CSR7_AI + CSR7_NI
178
;common to Rx and Tx
179
DES0_OWN                = 1 shl 31              ; if set, the NIC controls the descriptor, otherwise driver 'owns' the descriptors
180
 
181
;receive
182
RDES0_ZER               = 1 shl 0               ; must be 0 if legal length :D
183
RDES0_CE                = 1 shl 1               ; CRC error, valid only on last desc (RDES0<8>=1)
184
RDES0_DB                = 1 shl 2               ; dribbling bit - not multiple of 8 bits, valid only on last desc (RDES0<8>=1)
185
RDES0_RE                = 1 shl 3               ; Report on MII error.. i dont realy know what this means :P
186
RDES0_RW                = 1 shl 4               ; received watchdog timer expiration - must set CSR5<9>, valid only on last desc (RDES0<8>=1)
187
RDES0_FT                = 1 shl 5               ; frame type: 0->IEEE802.0 (len<1500) 1-> ETHERNET frame (len>1500), valid only on last desc (RDES0<8>=1)
188
RDES0_CS                = 1 shl 6               ; Collision seen, valid only on last desc (RDES0<8>=1)
189
RDES0_TL                = 1 shl 7               ; Too long(>1518)-NOT AN ERROR, valid only on last desc (RDES0<8>=1)
190
RDES0_LS                = 1 shl 8               ; Last descriptor of current frame
191
RDES0_FS                = 1 shl 9               ; First descriptor of current frame
192
RDES0_MF                = 1 shl 10              ; Multicast frame, valid only on last desc (RDES0<8>=1)
193
RDES0_RF                = 1 shl 11              ; Runt frame, valid only on last desc (RDES0<8>=1) and id overflow
194
RDES0_DT_SERIAL         = 00b shl 12            ; Data type-Serial recv frame, valid only on last desc (RDES0<8>=1)
195
RDES0_DT_INTERNAL       = 01b shl 12            ; Data type-Internal loopback recv frame, valid only on last desc (RDES0<8>=1)
196
RDES0_DT_EXTERNAL       = 11b shl 12            ; Data type-External loopback recv frame, valid only on last desc (RDES0<8>=1)
197
RDES0_DE                = 1 shl 14              ; Descriptor error - cant own a new desc and frame doesnt fit, valid only on last desc (RDES0<8>=1)
198
RDES0_ES                = 1 shl 15              ; Error Summmary - bits 1+6+11+14, valid only on last desc (RDES0<8>=1)
199
RDES0_FL_SH             = 16                    ; Field length shift, valid only on last desc (RDES0<8>=1)
200
RDES0_FL_MASK           = 11111111111111b       ; Field length mask (+CRC), valid only on last desc (RDES0<8>=1)
201
RDES0_FF                = 1 shl 30              ; Filtering fail-frame failed address recognition test(must CSR6<30>=1), valid only on last desc (RDES0<8>=1)
202
 
203
RDES1_RBS1_MASK         = 11111111111b          ; first buffer size MASK
204
RDES1_RBS2_SH           = 11                    ; second buffer size SHIFT
205
RDES1_RBS2_MASK         = 11111111111b          ; second buffer size MASK
206
RDES1_RCH               = 1 shl 24              ; Second address chained - second address (buffer) is next desc address
207
RDES1_RER               = 1 shl 25              ; Receive End of Ring - final descriptor, NIC must return to first desc
208
 
209
;transmition
210
TDES0_DE                = 1 shl 0               ; Deffered
211
TDES0_UF                = 1 shl 1               ; Underflow error
212
TDES0_LF                = 1 shl 2               ; Link fail report (only if CSR6<23>=1)
213
TDES0_CC_SH             = 3                     ; Collision Count shift - no of collision before transmition
214
TDES0_CC_MASK           = 1111b                 ; Collision Count mask
215
TDES0_HF                = 1 shl 7               ; Heartbeat fail
216
TDES0_EC                = 1 shl 8               ; Excessive Collisions - >16 collisions
217
TDES0_LC                = 1 shl 9               ; Late collision
218
TDES0_NC                = 1 shl 10              ; No carrier
219
TDES0_LO                = 1 shl 11              ; Loss of carrier
220
TDES0_TO                = 1 shl 14              ; Transmit Jabber Timeout
221
TDES0_ES                = 1 shl 15              ; Error summary TDES0<1+8+9+10+11+14>=1
222
 
223
TDES1_TBS1_MASK         = 11111111111b          ; Buffer 1 size mask
224
TDES1_TBS2_SH           = 11                    ; Buffer 2 size shift
225
TDES1_TBS2_MASK         = 11111111111b          ; Buffer 2 size mask
226
TDES1_FT0               = 1 shl 22              ; Filtering type 0
227
TDES1_DPD               = 1 shl 23              ; Disabled padding for packets <64bytes, no padding
228
TDES1_TCH               = 1 shl 24              ; Second address chained - second buffer pointer is to next desc
229
TDES1_TER               = 1 shl 25              ; Transmit end of ring - final descriptor
230
TDES1_AC                = 1 shl 26              ; Add CRC disable -pretty obvious
231
TDES1_SET               = 1 shl 27              ; Setup packet
232
TDES1_FT1               = 1 shl 28              ; Filtering type 1
233
TDES1_FS                = 1 shl 29              ; First segment - buffer is first segment of frame
234
TDES1_LS                = 1 shl 30              ; Last segment
235
TDES1_IC                = 1 shl 31              ; Interupt on completion (CSR5<0>=1) valid when TDES1<30>=1
236
 
5180 hidnplayr 237
FULL_DUPLEX_MAGIC       = 0x6969
238
;MAX_ETH_FRAME_SIZE      = 1514
3545 hidnplayr 239
 
5046 hidnplayr 240
struct  device          ETH_DEVICE
241
 
242
        io_addr         dd ?
243
        pci_bus         dd ?
244
        pci_dev         dd ?
245
        irq_line        db ?
5180 hidnplayr 246
                        rb 3    ; alignment
5046 hidnplayr 247
 
5180 hidnplayr 248
        id              dd ?    ; identification number
249
        io_size         dd ?
250
        flags           dd ?
251
        csr6            dd ?
252
        csr7            dd ?
253
        if_port         dd ?
254
        saved_if_port   dd ?
255
        default_port    dd ?
256
        mtable          dd ?
257
        mii_cnt         dd ?
258
 
259
        cur_rx          dd ?
260
        cur_tx          dd ?    ; Tx current descriptor to write data to
261
        last_tx         dd ?    ; Tx current descriptor to read TX completion
262
 
263
        rb 0x100-($ and 0xff)   ; align 256
264
        rx_ring         rb RX_RING_SIZE*2*sizeof.desc
265
 
266
        rb 0x100-($ and 0xff)   ; align 256
267
        tx_ring         rb TX_RING_SIZE*2*sizeof.desc
268
 
5046 hidnplayr 269
ends
270
 
271
;----------- descriptor structure ---------------------
5180 hidnplayr 272
struct  desc
5046 hidnplayr 273
        status          dd ?    ; bit 31 is 'own' and rest is 'status'
274
        length          dd ?    ; control bits + bytes-count buffer 1 + bytes-count buffer 2
275
        buffer1         dd ?    ; pointer to buffer1
5180 hidnplayr 276
        buffer2         dd ?    ; pointer to buffer2
5046 hidnplayr 277
ends
278
 
3545 hidnplayr 279
;=============================================================================
280
; serial ROM operations
281
;=============================================================================
282
CSR9_SR                 = 1 shl 11        ; SROM Select
283
CSR9_RD                 = 1 shl 14        ; ROM Read Operation
284
CSR9_SROM_DO            = 1 shl 3         ; Data Out for SROM
285
CSR9_SROM_DI            = 1 shl 2         ; Data In to SROM
286
CSR9_SROM_CK            = 1 shl 1         ; clock for SROM
287
CSR9_SROM_CS            = 1 shl 0         ; chip select.. always needed
288
 
289
; assume dx is CSR9
290
macro SROM_Delay {
291
        push    eax
292
        in      eax, dx
293
        in      eax, dx
294
        in      eax, dx
295
        in      eax, dx
296
        in      eax, dx
297
        in      eax, dx
298
        in      eax, dx
299
        in      eax, dx
300
        in      eax, dx
301
        in      eax, dx
302
        pop     eax
303
}
304
 
305
; assume dx is CSR9
306
macro MDIO_Delay {
307
        push    eax
308
        in      eax, dx
309
        pop     eax
310
}
311
 
312
macro Bit_Set a_bit {
313
        in      eax, dx
314
        or      eax, a_bit
315
        out     dx , eax
316
}
317
 
318
macro Bit_Clear a_bit {
319
        in      eax, dx
320
        and     eax, not (a_bit)
321
        out     dx, eax
322
}
323
 
324
 
325
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
326
;;                        ;;
327
;; proc START             ;;
328
;;                        ;;
329
;; (standard driver proc) ;;
330
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
331
 
5046 hidnplayr 332
proc START c, reason:dword, cmdline:dword
3545 hidnplayr 333
 
5046 hidnplayr 334
        cmp     [reason], DRV_ENTRY
335
        jne     .fail
3545 hidnplayr 336
 
5046 hidnplayr 337
        DEBUGF  2,"Loading driver\n"
338
        invoke  RegService, my_service, service_proc
3545 hidnplayr 339
        ret
340
 
341
  .fail:
5046 hidnplayr 342
        xor     eax, eax
3545 hidnplayr 343
        ret
344
 
345
endp
346
 
347
 
348
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
349
;;                        ;;
350
;; proc SERVICE_PROC      ;;
351
;;                        ;;
352
;; (standard driver proc) ;;
353
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
354
 
355
align 4
356
proc service_proc stdcall, ioctl:dword
357
 
358
        mov     edx, [ioctl]
4470 hidnplayr 359
        mov     eax, [edx + IOCTL.io_code]
3545 hidnplayr 360
 
361
;------------------------------------------------------
362
 
363
        cmp     eax, 0 ;SRV_GETVERSION
364
        jne     @F
365
 
4470 hidnplayr 366
        cmp     [edx + IOCTL.out_size], 4
3545 hidnplayr 367
        jb      .fail
4470 hidnplayr 368
        mov     eax, [edx + IOCTL.output]
3545 hidnplayr 369
        mov     [eax], dword API_VERSION
370
 
371
        xor     eax, eax
372
        ret
373
 
374
;------------------------------------------------------
375
  @@:
376
        cmp     eax, 1 ;SRV_HOOK
377
        jne     .fail
378
 
5180 hidnplayr 379
        cmp     [edx + IOCTL.inp_size], 3                               ; Data input must be at least 3 bytes
3545 hidnplayr 380
        jb      .fail
381
 
4470 hidnplayr 382
        mov     eax, [edx + IOCTL.input]
5180 hidnplayr 383
        cmp     byte [eax], 1                                           ; 1 means device number and bus number (pci) are given
384
        jne     .fail                                                   ; other types arent supported for this card yet
3545 hidnplayr 385
 
386
; check if the device is already listed
387
 
388
        mov     esi, device_list
389
        mov     ecx, [devices]
390
        test    ecx, ecx
391
        jz      .firstdevice
392
 
5180 hidnplayr 393
;        mov     eax, [edx + IOCTL.input]                                ; get the pci bus and device numbers
394
        mov     ax, [eax+1]                                             ;
3545 hidnplayr 395
  .nextdevice:
396
        mov     ebx, [esi]
5046 hidnplayr 397
        cmp     al, byte[ebx + device.pci_bus]
3545 hidnplayr 398
        jne     @f
5046 hidnplayr 399
        cmp     ah, byte[ebx + device.pci_dev]
5180 hidnplayr 400
        je      .find_devicenum                                         ; Device is already loaded, let's find it's device number
3545 hidnplayr 401
       @@:
402
        add     esi, 4
403
        loop    .nextdevice
404
 
405
 
406
; This device doesnt have its own eth_device structure yet, lets create one
407
  .firstdevice:
5180 hidnplayr 408
        cmp     [devices], MAX_DEVICES                                  ; First check if the driver can handle one more card
3545 hidnplayr 409
        jae     .fail
410
 
5180 hidnplayr 411
        allocate_and_clear ebx, sizeof.device, .fail
3545 hidnplayr 412
 
413
; Fill in the direct call addresses into the struct
5046 hidnplayr 414
        mov     [ebx + device.reset], reset
415
        mov     [ebx + device.transmit], transmit
416
        mov     [ebx + device.unload], unload
417
        mov     [ebx + device.name], my_service
3545 hidnplayr 418
 
419
; save the pci bus and device numbers
4470 hidnplayr 420
        mov     eax, [edx + IOCTL.input]
3545 hidnplayr 421
        movzx   ecx, byte[eax+1]
5046 hidnplayr 422
        mov     [ebx + device.pci_bus], ecx
3545 hidnplayr 423
        movzx   ecx, byte[eax+2]
5046 hidnplayr 424
        mov     [ebx + device.pci_dev], ecx
3545 hidnplayr 425
 
426
; Now, it's time to find the base io addres of the PCI device
5046 hidnplayr 427
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
428
        mov     [ebx + device.io_addr], eax
3545 hidnplayr 429
 
430
; We've found the io address, find IRQ now
5046 hidnplayr 431
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
432
        mov     [ebx + device.irq_line], al
3545 hidnplayr 433
 
434
        DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
5046 hidnplayr 435
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
3545 hidnplayr 436
 
437
; Ok, the eth_device structure is ready, let's probe the device
438
; Because initialization fires IRQ, IRQ handler must be aware of this device
439
        mov     eax, [devices]                                          ; Add the device structure to our device list
440
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
441
        inc     [devices]                                               ;
442
 
443
        call    probe                                                   ; this function will output in eax
444
        test    eax, eax
445
        jnz     .err2                                                   ; If an error occured, exit
446
 
5046 hidnplayr 447
        mov     [ebx + device.type], NET_TYPE_ETH
448
        invoke  NetRegDev
3545 hidnplayr 449
 
450
        cmp     eax, -1
451
        je      .destroy
452
 
453
        ret
454
 
455
; If the device was already loaded, find the device number and return it in eax
456
 
457
  .find_devicenum:
458
        DEBUGF  2,"Trying to find device number of already registered device\n"
5046 hidnplayr 459
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
3545 hidnplayr 460
                                                                        ; into a device number in edi
461
        mov     eax, edi                                                ; Application wants it in eax instead
462
        DEBUGF  2,"Kernel says: %u\n", eax
463
        ret
464
 
465
; If an error occured, remove all allocated data and exit (returning -1 in eax)
466
 
467
  .destroy:
468
        ; todo: reset device into virgin state
469
 
470
  .err2:
471
        dec     [devices]
472
  .err:
473
        DEBUGF  2,"removing device structure\n"
5046 hidnplayr 474
        invoke  KernelFree, ebx
3545 hidnplayr 475
 
476
  .fail:
477
        or      eax, -1
478
        ret
479
 
480
;------------------------------------------------------
481
endp
482
 
483
 
484
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
485
;;                                                                        ;;
486
;;        Actual Hardware dependent code starts here                      ;;
487
;;                                                                        ;;
488
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
489
 
490
 
491
 
492
align 4
493
unload:
494
        ; TODO: (in this particular order)
495
        ;
496
        ; - Stop the device
497
        ; - Detach int handler
5180 hidnplayr 498
        ; - Remove device from local list
3545 hidnplayr 499
        ; - call unregister function in kernel
500
        ; - Remove all allocated structures and buffers the card used
501
 
5180 hidnplayr 502
        or      eax, -1
503
        ret
3545 hidnplayr 504
 
505
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
506
;;                                         ;;
507
;; Probe                                   ;;
508
;;                                         ;;
509
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
510
 
511
align 4
512
probe:
513
 
5180 hidnplayr 514
        DEBUGF  2,"Probing\n"
3545 hidnplayr 515
 
5180 hidnplayr 516
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0        ; get device/vendor id
517
        mov     esi, chiplist
518
  .loop:
519
        cmp     dword[esi], eax
520
        je      .got_it
521
        add     esi, 6*4
522
        cmp     dword[esi], 0
523
        jne     .loop
524
        DEBUGF  2, "Unknown chip: 0x%x aborting\n", eax
3545 hidnplayr 525
 
526
        or      eax, -1
527
        ret
528
 
5180 hidnplayr 529
  .got_it:
530
        lodsd
531
        lodsd
532
        mov     [ebx + device.id], eax
533
        lodsd
534
        mov     [ebx + device.io_size], eax
535
        lodsd
536
        mov     [ebx + device.csr7], eax
537
        lodsd
538
        mov     [ebx + device.name], eax
539
        DEBUGF  1, "Detected chip = %s\n", eax
540
        lodsd
541
        mov     [ebx + device.flags], eax
3545 hidnplayr 542
 
5180 hidnplayr 543
; PROBE1
3545 hidnplayr 544
 
5180 hidnplayr 545
        test    [ebx + device.flags], FLAG_HAS_ACPI
546
        jz      .no_acpi
547
        DEBUGF  1, "Device has ACPI capabilities, time to wake it up\n"
3545 hidnplayr 548
        xor     eax, eax
5180 hidnplayr 549
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, eax       ; wake up the 21143
550
  .no_acpi:
3545 hidnplayr 551
 
5180 hidnplayr 552
        call    SROM_GetWidth           ; TODO: use this value returned in ecx in the read_word routine!
3545 hidnplayr 553
 
554
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
555
;;                                         ;;
556
;; Reset                                   ;;
557
;;                                         ;;
558
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
559
 
560
align 4
561
reset:
562
 
5180 hidnplayr 563
        DEBUGF  2,"Reset\n"
3545 hidnplayr 564
 
5180 hidnplayr 565
; Make the device a bus master
566
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
567
        or      al, PCI_CMD_MASTER
568
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
3545 hidnplayr 569
 
5180 hidnplayr 570
; Stop TX and RX
5046 hidnplayr 571
        set_io  [ebx + device.io_addr], 0
5180 hidnplayr 572
        set_io  [ebx + device.io_addr], CSR6
573
        in      eax, dx
574
        and     eax, not (CSR6_ST or CSR6_SR)
3545 hidnplayr 575
        out     dx, eax
576
 
5180 hidnplayr 577
; Clear missed packet counter
578
        set_io  [ebx + device.io_addr], CSR8
579
        in      eax, dx
3545 hidnplayr 580
 
5180 hidnplayr 581
;; wait at least 50 PCI cycles
582
;        mov     esi, 1000
583
;        invoke  Sleep
3545 hidnplayr 584
 
5180 hidnplayr 585
        cmp     [ebx + device.id], DC21041
586
        jne     @f
587
;        set_io  [ebx + device.io_addr], 0
588
        set_io  [ebx + device.io_addr], CSR9
589
        in      eax, dx
590
        test    eax, 0x8000
591
        jz      @f
592
        DEBUGF  1, "21040 compatibility mode\n"
593
        mov     [ebx + device.id], DC21040
594
  @@:
595
 
596
 
597
;;; Find connected mii xceivers? 993-1043
598
 
599
; Reset the xcvr interface and turn on heartbeat.
600
        cmp     [ebx + device.id], DC21041
601
        jne     @f
5046 hidnplayr 602
        set_io  [ebx + device.io_addr], 0
5180 hidnplayr 603
        set_io  [ebx + device.io_addr], CSR13
604
        xor     eax, eax
605
        out     dx, eax
606
        set_io  [ebx + device.io_addr], CSR14
607
        dec     eax
608
        out     dx, eax
609
        set_io  [ebx + device.io_addr], CSR15
610
        inc     eax
611
        mov     al, 8
612
        out     dx, eax
613
        set_io  [ebx + device.io_addr], CSR6
614
        in      eax, dx
615
        or      ax, CSR6_ST
616
        out     dx, eax
617
        set_io  [ebx + device.io_addr], CSR13
618
        xor     eax, eax
619
        mov     ax, 0xEF05
620
        out     dx, eax
621
        jmp     .reset_done
622
  @@:
623
        cmp     [ebx + device.id], DC21040
624
        jne     @f
625
        set_io  [ebx + device.io_addr], 0
626
        set_io  [ebx + device.io_addr], CSR13
627
        xor     eax, eax
628
        out     dx, eax
629
        mov     al, 4
630
        out     dx, eax
631
        jmp     .reset_done
632
  @@:
633
        cmp     [ebx + device.id], DC21140
634
        jne     @f
635
        set_io  [ebx + device.io_addr], 0
636
        set_io  [ebx + device.io_addr], CSR12
637
        mov     eax, 0x100
638
        out     dx, eax
639
        jmp     .reset_done
640
  @@:
641
        cmp     [ebx + device.id], DC21142
642
        jne     @f
643
        ; if tp->mii_cnt
644
        set_io  [ebx + device.io_addr], 0
645
        set_io  [ebx + device.io_addr], CSR6
646
        mov     eax, 0x82020000
647
        out     dx, eax
648
        set_io  [ebx + device.io_addr], CSR13
649
        xor     eax, eax
650
        out     dx, eax
651
        set_io  [ebx + device.io_addr], CSR14
652
        out     dx, eax
653
        set_io  [ebx + device.io_addr], CSR6
654
        mov     eax, 0x820E0000
655
        out     dx, eax
656
        jmp     .reset_done
657
        ;;;; TODO
658
  @@:
659
        cmp     [ebx + device.id], LC82C168
660
        jne     @f
661
        ; TODO
662
  @@:
663
        cmp     [ebx + device.id], MX98713
664
        jne     @f
665
        ; TODO
666
  @@:
667
 
668
  .reset_done:
669
 
670
 
671
; OPEN
672
 
673
; Reset chip
674
        set_io  [ebx + device.io_addr], 0
5046 hidnplayr 675
        set_io  [ebx + device.io_addr], CSR0
5180 hidnplayr 676
        mov     eax, CSR0_RESET
3545 hidnplayr 677
        out     dx, eax
678
 
679
; wait at least 50 PCI cycles
5180 hidnplayr 680
        mov     esi, 100
5046 hidnplayr 681
        invoke  Sleep
3545 hidnplayr 682
 
683
;-----------------------------------
684
; Read mac from eeprom to driver ram
685
 
686
        call    read_mac_eeprom
687
 
688
;--------------------------------
689
; insert irq handler on given irq
690
 
5046 hidnplayr 691
        movzx   eax, [ebx + device.irq_line]
3545 hidnplayr 692
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
5046 hidnplayr 693
        invoke  AttachIntHandler, eax, int_handler, ebx
3545 hidnplayr 694
        test    eax, eax
695
        jnz     @f
4334 hidnplayr 696
        DEBUGF  2,"Could not attach int handler!\n"
5046 hidnplayr 697
        or      eax, -1
698
        ret
3545 hidnplayr 699
  @@:
700
 
5180 hidnplayr 701
;----------------
702
; Set cache modes
703
 
5046 hidnplayr 704
        set_io  [ebx + device.io_addr], 0
5180 hidnplayr 705
        set_io  [ebx + device.io_addr], CSR0
706
        mov     eax, 0x01A00000 or 0x4800 ; CSR0_DEFAULT
707
        out     dx, eax
3545 hidnplayr 708
 
5180 hidnplayr 709
        ; wait at least 50 PCI cycles
710
        mov     esi, 100
711
        invoke  Sleep
712
 
713
;---------------------------
714
; Initialize RX and TX rings
715
 
3545 hidnplayr 716
        call    init_ring
5180 hidnplayr 717
        test    eax, eax
718
        jnz     .err
3545 hidnplayr 719
 
5180 hidnplayr 720
;-------------------
721
; Set receive filter
722
 
723
        call    create_setup_frame
724
 
3545 hidnplayr 725
;--------------------------------------------
726
; setup CSR3 & CSR4 (pointers to descriptors)
727
 
5180 hidnplayr 728
        lea     eax, [ebx + device.rx_ring]
729
        invoke  GetPhysAddr
730
        DEBUGF  1,"RX descriptor base address: %x\n", eax
5046 hidnplayr 731
        set_io  [ebx + device.io_addr], 0
732
        set_io  [ebx + device.io_addr], CSR3
3545 hidnplayr 733
        out     dx, eax
734
 
5180 hidnplayr 735
        lea     eax, [ebx + device.tx_ring]
5046 hidnplayr 736
        invoke  GetPhysAddr
3545 hidnplayr 737
        DEBUGF  1,"TX descriptor base address: %x\n", eax
5180 hidnplayr 738
        set_io  [ebx + device.io_addr], CSR4
3545 hidnplayr 739
        out     dx, eax
740
 
5180 hidnplayr 741
; Select media
742
        push    [ebx + device.if_port]
743
        pop     [ebx + device.saved_if_port]
744
        cmp     [ebx + device.if_port], 0
745
        jne     @f
746
        push    [ebx + device.default_port]
747
        pop     [ebx + device.if_port]
748
  @@:
749
        cmp     [ebx + device.id], DC21041
750
        jne     @f
751
        cmp     [ebx + device.if_port], 4
752
        jbe     @f
753
        ; invalid port, select inital TP, autosense, autonegotiate
754
        mov     [ebx + device.if_port], 4                               ; CHECKME
755
  @@:
3545 hidnplayr 756
 
5180 hidnplayr 757
; Allow selecting a default media
758
        cmp     [ebx + device.mtable], 0
759
        je      .media_picked
3545 hidnplayr 760
 
5180 hidnplayr 761
        cmp     [ebx + device.if_port], 0
762
        je      @f
763
        ;; TODO
764
        jmp     .media_picked
765
  @@:
3545 hidnplayr 766
 
5180 hidnplayr 767
  .media_picked:
768
        mov     [ebx + device.csr6], 0
769
 
770
        cmp     [ebx + device.id], DC21142
771
        jne     @f
772
        cmp     [ebx + device.if_port], 0
773
        jne     @f
774
        ;; TODO
775
        mov     [ebx + device.csr6], 0x82420200
776
        mov     [ebx + device.if_port], 11
5046 hidnplayr 777
        set_io  [ebx + device.io_addr], 0
5180 hidnplayr 778
        set_io  [ebx + device.io_addr], CSR14
779
        mov     eax, 0x0003FFF
780
        out     dx, eax
781
        set_io  [ebx + device.io_addr], CSR15
782
        xor     eax, eax
783
        mov     al, 8
784
        out     dx, eax
785
        set_io  [ebx + device.io_addr], CSR13
786
        mov     al, 1
787
        out     dx, eax
788
        set_io  [ebx + device.io_addr], CSR12
789
        mov     ax, 0x1301
790
        out     dx, eax
3545 hidnplayr 791
 
5180 hidnplayr 792
  @@:
793
        cmp     [ebx + device.id], LC82C168
794
        jne     @f
795
        ;; TODO
796
  @@:
797
        cmp     [ebx + device.id], MX98713
798
        jne     @f
3545 hidnplayr 799
 
5180 hidnplayr 800
  @@:
801
;; wait a bit
802
;        mov     esi, 500
803
;        invoke  Sleep
3545 hidnplayr 804
 
5180 hidnplayr 805
; else:
806
        xor     eax, eax
807
        inc     eax
808
        call    select_media
3545 hidnplayr 809
 
5180 hidnplayr 810
; Start the chip's tx to process setup frame
811
        set_io  [ebx + device.io_addr], 0
812
        set_io  [ebx + device.io_addr], CSR6
813
        mov     eax, [ebx + device.csr6]
814
        out     dx, eax
815
        or      ax, CSR6_ST
816
        out     dx, eax
3545 hidnplayr 817
 
5180 hidnplayr 818
; Enable interrupts by setting the interrupt mask.
819
        set_io  [ebx + device.io_addr], CSR5
820
        mov     eax, [ebx + device.csr7]
821
        DEBUGF  1, "Setting CSR7 to 0x%x\n", eax
822
        out     dx, eax
823
        set_io  [ebx + device.io_addr], CSR7
824
        out     dx, eax
3545 hidnplayr 825
 
5180 hidnplayr 826
; Enable receiver
827
        set_io  [ebx + device.io_addr], CSR6
828
        mov     eax, [ebx + device.csr6]
829
        or      eax, 0x2002 + CSR6_RA
830
        out     dx, eax
3545 hidnplayr 831
 
5180 hidnplayr 832
; RX poll demand
833
        set_io  [ebx + device.io_addr], CSR2
3545 hidnplayr 834
        xor     eax, eax
5180 hidnplayr 835
        out     dx, eax
3545 hidnplayr 836
 
837
; Set the mtu, kernel will be able to send now
5046 hidnplayr 838
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 839
 
840
; Set link state to unknown
5046 hidnplayr 841
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
3545 hidnplayr 842
 
5180 hidnplayr 843
        DEBUGF  1,"Reset completed\n"
844
;        xor     eax, eax
845
        ret
3545 hidnplayr 846
 
5180 hidnplayr 847
  .err:
848
        DEBUGF  2,"Reset failed\n"
849
        or      eax, -1
3545 hidnplayr 850
        ret
851
 
852
 
853
 
854
align 4
855
init_ring:
856
 
5180 hidnplayr 857
        DEBUGF  1,"Init ring\n"
3545 hidnplayr 858
 
5180 hidnplayr 859
;---------------------
860
; Setup RX descriptors
861
 
862
        lea     eax, [ebx + device.rx_ring]
5046 hidnplayr 863
        invoke  GetPhysAddr
3545 hidnplayr 864
        mov     edx, eax
865
        push    eax
5180 hidnplayr 866
        lea     edi, [ebx + device.rx_ring]
867
        mov     ecx, RX_RING_SIZE
3545 hidnplayr 868
  .loop_rx_des:
5180 hidnplayr 869
        DEBUGF  1,"RX descriptor 0x%x\n", edi
870
        add     edx, sizeof.desc
871
        mov     [edi + desc.status], DES0_OWN
872
        mov     [edi + desc.length], 1536
873
        push    edx edi ecx
874
        invoke  KernelAlloc, 1536
875
        pop     ecx edi edx
876
        test    eax, eax
877
        jz      .out_of_mem
878
        mov     [edi + RX_RING_SIZE*sizeof.desc], eax
879
        invoke  GetPhysAddr
880
        mov     [edi + desc.buffer1], eax
881
        mov     [edi + desc.buffer2], edx
882
        add     edi, sizeof.desc
3545 hidnplayr 883
        dec     ecx
884
        jnz     .loop_rx_des
885
; set last descriptor as LAST
5180 hidnplayr 886
        or      [edi - sizeof.desc + desc.length], RDES1_RER           ; EndOfRing
887
        pop     [edi - sizeof.desc + desc.buffer2]                     ; point it to the first descriptor
3545 hidnplayr 888
 
889
;---------------------
890
; Setup TX descriptors
891
 
5180 hidnplayr 892
        lea     eax, [ebx + device.tx_ring]
5046 hidnplayr 893
        invoke  GetPhysAddr
3545 hidnplayr 894
        mov     edx, eax
895
        push    eax
5180 hidnplayr 896
        lea     edi, [ebx + device.tx_ring]
897
        mov     ecx, TX_RING_SIZE
3545 hidnplayr 898
  .loop_tx_des:
5180 hidnplayr 899
        DEBUGF  1,"TX descriptor 0x%x\n", edi
900
        add     edx, sizeof.desc
901
        mov     [edi + desc.status], 0                                  ; owned by driver
902
        mov     [edi + desc.length], 0
903
        mov     [edi + desc.buffer1], 0
904
        mov     [edi + desc.buffer2], edx                               ; pointer to next descr
905
        add     edi, sizeof.desc
3545 hidnplayr 906
        dec     ecx
907
        jnz     .loop_tx_des
908
; set last descriptor as LAST
5180 hidnplayr 909
        or      [edi - sizeof.desc + desc.length], TDES1_TER            ; EndOfRing
910
        pop     [edi - sizeof.desc + desc.buffer2]                      ; point it to the first descriptor
3545 hidnplayr 911
 
912
;------------------
913
; Reset descriptors
914
 
5180 hidnplayr 915
        xor     eax, eax
916
        mov     [ebx + device.cur_tx], eax
917
        mov     [ebx + device.last_tx], eax
918
        mov     [ebx + device.cur_rx], eax
3545 hidnplayr 919
 
920
        ret
921
 
5180 hidnplayr 922
  .out_of_mem:
923
        DEBUGF  2, "Out of memory!\n"
924
        pop     eax
925
        or      eax, -1
926
        ret
3545 hidnplayr 927
 
5180 hidnplayr 928
 
929
; IN: eax = startup
3545 hidnplayr 930
align 4
5180 hidnplayr 931
select_media:
932
 
933
        DEBUGF  1, "Selecting media\n"
934
 
935
        cmp     [ebx + device.mtable], 0
936
        je      .no_mtable
937
        DEBUGF  1, "Device has a media table\n"
938
 
939
 
940
; default:
941
        mov     eax, 0x020E0000
942
        jmp     .update_csr6
943
 
944
  .no_mtable:
945
        DEBUGF  1, "Device has no media table\n"
946
 
947
        cmp     [ebx + device.id], DC21041
948
        jne     .not_41
949
        DEBUGF  1, "DC21041\n"
950
 
951
        set_io  [ebx + device.io_addr], 0
952
        set_io  [ebx + device.io_addr], CSR13
953
        xor     eax, eax
954
        out     dx, eax         ; reset serial interface
955
        set_io  [ebx + device.io_addr], CSR14
956
        mov     eax, 0x7F3F     ;0x7F3F     ;0x7F3D     ; 10T-FD
957
        out     dx, eax
958
        set_io  [ebx + device.io_addr], CSR15
959
        mov     eax, 0x0008     ;0x0008     ;0x0008     ; 10T-FD
960
        out     dx, eax
961
        set_io  [ebx + device.io_addr], CSR13
962
        mov     eax, 0xEF05     ;0xEF01     ;0xEF09     ; 10T-FD
963
        out     dx, eax
964
        mov     eax, 0x80020000
965
        jmp     .update_csr6
966
  .not_41:
967
        cmp     [ebx + device.id], LC82C168
968
        jne     .not_LC
969
        DEBUGF  1, "LC82C168\n"
970
 
971
        ;; TODO
972
 
973
        mov     eax, 0x812C0000
974
        jmp     .update_csr6
975
  .not_LC:
976
        cmp     [ebx + device.id], DC21040
977
        jne     .not_40
978
        DEBUGF  1, "DC21040\n"
979
 
980
        set_io  [ebx + device.io_addr], 0
981
        set_io  [ebx + device.io_addr], CSR11
982
        mov     eax, FULL_DUPLEX_MAGIC
983
        out     dx, eax
984
        ; reset serial interface
985
        set_io  [ebx + device.io_addr], CSR13
986
        xor     eax, eax
987
        out     dx, eax
988
 
989
        set_io  [ebx + device.io_addr], CSR13
990
        xor     eax, eax
991
        cmp     [ebx + device.if_port], 0
992
        je      @f
993
        mov     al, 0xc
994
        out     dx, eax
995
        mov     eax, 0x01860000
996
        jmp     .update_csr6
997
  @@:
998
        mov     al, 4
999
        out     dx, eax
1000
        mov     eax, 0x00420000
1001
        jmp     .update_csr6
1002
 
1003
  .not_40:
1004
        DEBUGF  1, "Unkown chip with no media table\n"
1005
 
1006
        cmp     [ebx + device.default_port], 0
1007
        jne     .not_0
1008
        cmp     [ebx + device.mii_cnt], 0
1009
        je      @f
1010
        mov     [ebx + device.if_port], 11
1011
        jmp     .not_0
1012
  @@:
1013
        mov     [ebx + device.if_port], 3
1014
  .not_0:
1015
        mov     eax, 0x020E0000 ;;;;;
1016
 
1017
  .update_csr6:
1018
        and     [ebx + device.csr6], 0xfdff
1019
        or      ax, 0x0200                     ;; FULL DUPLEX
1020
        or      [ebx + device.csr6], eax
1021
        DEBUGF  1, "new CSR6: 0x%x\n", [ebx + device.csr6]
1022
 
1023
        ret
1024
 
1025
 
1026
align 4
3545 hidnplayr 1027
start_link:
1028
 
3639 hidnplayr 1029
        DEBUGF  1,"Starting link\n"
1030
 
3545 hidnplayr 1031
        ; TODO: write working code here
1032
 
1033
        ret
1034
 
1035
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1036
;;                                         ;;
1037
;; Send setup packet                       ;;
1038
;;                                         ;;
1039
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1040
 
1041
align 4
5180 hidnplayr 1042
create_setup_frame:
3545 hidnplayr 1043
 
5180 hidnplayr 1044
        DEBUGF  1,"Creating setup packet\n"
3545 hidnplayr 1045
 
5180 hidnplayr 1046
        invoke  KernelAlloc, 192
1047
        test    eax, eax
1048
        jz      .err
3545 hidnplayr 1049
 
5180 hidnplayr 1050
        push    eax
3545 hidnplayr 1051
 
5180 hidnplayr 1052
        mov     edi, eax
1053
        xor     eax, eax
1054
        dec     ax
1055
        stosd
1056
        stosd
1057
        stosd
3545 hidnplayr 1058
 
5180 hidnplayr 1059
        mov     ecx, 15
1060
  .loop:
5046 hidnplayr 1061
        lea     esi, [ebx + device.mac]
5180 hidnplayr 1062
        lodsw
1063
        stosd
3545 hidnplayr 1064
        dec     ecx
1065
        jnz     .loop
1066
 
5180 hidnplayr 1067
        pop     eax
3545 hidnplayr 1068
 
1069
; setup descriptor
5180 hidnplayr 1070
        lea     edi, [ebx + device.tx_ring]
1071
        DEBUGF  1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi
1072
        mov     [edi + TX_RING_SIZE*sizeof.desc], eax
1073
        invoke  GetPhysAddr
1074
        mov     [edi + desc.buffer1], eax
1075
        mov     [edi + desc.length], TDES1_SET + 192        ; size must be EXACTLY 192 bytes + TDES1_IC
1076
        mov     [edi + desc.status], DES0_OWN
1077
        DEBUGF  1, "descriptor 0x%x\n", edi
3545 hidnplayr 1078
 
1079
; go to next descriptor
5180 hidnplayr 1080
        inc     [ebx + device.cur_tx]
3545 hidnplayr 1081
 
5180 hidnplayr 1082
        ret
3545 hidnplayr 1083
 
5180 hidnplayr 1084
  .err:
1085
        DEBUGF  2, "Out of memory!\n"
3545 hidnplayr 1086
        ret
1087
 
1088
 
1089
 
1090
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1091
;;                                         ;;
1092
;; Transmit                                ;;
1093
;;                                         ;;
1094
;; In: buffer pointer in [esp+4]           ;;
1095
;;     size of buffer in [esp+8]           ;;
1096
;;     pointer to device structure in ebx  ;;
1097
;;                                         ;;
1098
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1099
 
5046 hidnplayr 1100
proc transmit stdcall bufferptr, buffersize
3545 hidnplayr 1101
 
5046 hidnplayr 1102
        pushf
1103
        cli
1104
 
1105
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1106
        mov     eax, [bufferptr]
3545 hidnplayr 1107
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1108
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1109
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1110
        [eax+13]:2,[eax+12]:2
1111
 
5046 hidnplayr 1112
        cmp     [buffersize], 1514
3545 hidnplayr 1113
        ja      .fail
1114
 
5180 hidnplayr 1115
        mov     eax, [ebx + device.cur_tx]
1116
        mov     edx, sizeof.desc
3545 hidnplayr 1117
        mul     edx
5180 hidnplayr 1118
        lea     esi, [ebx + device.tx_ring + eax]
1119
        test    [esi + desc.status], DES0_OWN
1120
        jnz     .fail
3545 hidnplayr 1121
 
5180 hidnplayr 1122
        DEBUGF  1, "Descriptor is free\n"
1123
 
1124
        mov     eax, [bufferptr]
1125
        mov     [esi + TX_RING_SIZE*sizeof.desc], eax
1126
        invoke  GetPhysAddr
1127
        mov     [esi + desc.buffer1], eax
1128
 
3545 hidnplayr 1129
; set packet size
5180 hidnplayr 1130
        mov     eax, [esi + desc.length]
1131
        and     eax, TDES1_TER                          ; preserve 'End of Ring' bit
1132
        or      eax, [buffersize]                       ; set size
1133
        or      eax, TDES1_FS or TDES1_LS or TDES1_IC   ; first descr, last descr, interrupt on complete
1134
        mov     [esi + desc.length], eax
3545 hidnplayr 1135
 
5180 hidnplayr 1136
; set descriptor status
1137
        mov     [esi + desc.status], DES0_OWN            ; say it is now owned by the 21x4x
3545 hidnplayr 1138
 
5180 hidnplayr 1139
; Check if transmitter is running
5046 hidnplayr 1140
        set_io  [ebx + device.io_addr], 0
1141
        set_io  [ebx + device.io_addr], CSR6
3545 hidnplayr 1142
        in      eax, dx
5180 hidnplayr 1143
        test    eax, CSR6_ST                            ; if NOT started, start now
3545 hidnplayr 1144
        jnz     .already_started
1145
        or      eax, CSR6_ST
5180 hidnplayr 1146
        DEBUGF  1,"(Re) starting TX\n"
3545 hidnplayr 1147
        jmp     .do_it
1148
  .already_started:
5180 hidnplayr 1149
 
1150
; Trigger immediate transmit demand
5046 hidnplayr 1151
        set_io  [ebx + device.io_addr], CSR1
5180 hidnplayr 1152
        xor     eax, eax
3545 hidnplayr 1153
  .do_it:
5180 hidnplayr 1154
        out     dx, eax
3545 hidnplayr 1155
 
1156
; Update stats
5046 hidnplayr 1157
        inc     [ebx + device.packets_tx]
1158
        mov     eax, [buffersize]
1159
        add     dword [ebx + device.bytes_tx], eax
1160
        adc     dword [ebx + device.bytes_tx + 4], 0
3545 hidnplayr 1161
 
1162
; go to next descriptor
5180 hidnplayr 1163
        inc     [ebx + device.cur_tx]
1164
        and     [ebx + device.cur_tx], TX_RING_SIZE-1
3545 hidnplayr 1165
 
5180 hidnplayr 1166
        DEBUGF  1,"Transmit ok\n"
5046 hidnplayr 1167
        popf
3545 hidnplayr 1168
        xor     eax, eax
5046 hidnplayr 1169
        ret
3545 hidnplayr 1170
 
1171
  .fail:
5180 hidnplayr 1172
        DEBUGF  2,"Transmit failed\n"
5046 hidnplayr 1173
        invoke  KernelFree, [bufferptr]
1174
        popf
3545 hidnplayr 1175
        or      eax, -1
5046 hidnplayr 1176
        ret
3545 hidnplayr 1177
 
5046 hidnplayr 1178
endp
3545 hidnplayr 1179
 
1180
;;;;;;;;;;;;;;;;;;;;;;;
1181
;;                   ;;
1182
;; Interrupt handler ;;
1183
;;                   ;;
1184
;;;;;;;;;;;;;;;;;;;;;;;
1185
 
1186
align 4
1187
int_handler:
1188
 
1189
        push    ebx esi edi
1190
 
5180 hidnplayr 1191
        DEBUGF  1,"INT\n"
3545 hidnplayr 1192
 
1193
; find pointer of device wich made IRQ occur
1194
 
1195
        mov     ecx, [devices]
1196
        test    ecx, ecx
1197
        jz      .nothing
1198
        mov     esi, device_list
1199
  .nextdevice:
1200
        mov     ebx, [esi]
1201
 
5046 hidnplayr 1202
        set_io  [ebx + device.io_addr], 0
1203
        set_io  [ebx + device.io_addr], CSR5
5180 hidnplayr 1204
        in      eax, dx
1205
        and     eax, 0x0001ffff
1206
        out     dx, eax                                 ; send it back to ACK
3545 hidnplayr 1207
        jnz     .got_it
1208
  .continue:
1209
        add     esi, 4
1210
        dec     ecx
1211
        jnz     .nextdevice
1212
  .nothing:
1213
        pop     edi esi ebx
1214
        xor     eax, eax
1215
 
1216
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1217
 
1218
  .got_it:
5180 hidnplayr 1219
        DEBUGF  1,"Device: %x CSR5: %x\n", ebx, eax
3545 hidnplayr 1220
 
1221
;----------------------------------
1222
; TX ok?
1223
 
5180 hidnplayr 1224
        test    eax, CSR5_TI
3545 hidnplayr 1225
        jz      .not_tx
1226
 
5180 hidnplayr 1227
        push    eax esi ecx
1228
        DEBUGF  1,"TX ok!\n"
1229
      .loop_tx:
1230
        ; go to last descriptor
1231
        mov     eax, [ebx + device.last_tx]
1232
        mov     edx, sizeof.desc
3545 hidnplayr 1233
        mul     edx
5180 hidnplayr 1234
        lea     eax, [ebx + device.tx_ring + eax]
3545 hidnplayr 1235
 
5180 hidnplayr 1236
        DEBUGF  1,"descriptor 0x%x\n", eax
1237
        test    [eax + desc.status], DES0_OWN           ; owned by the card?
3545 hidnplayr 1238
        jnz     .end_tx
5180 hidnplayr 1239
        cmp     [eax + desc.buffer1], 0                 ; empty descriptor?
1240
        je      .end_tx
3545 hidnplayr 1241
 
5180 hidnplayr 1242
        mov     [eax + desc.buffer1], 0
1243
        DEBUGF  1, "Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
1244
        invoke  KernelFree, [eax + TX_RING_SIZE*sizeof.desc]
3545 hidnplayr 1245
 
1246
        ; next descriptor
5180 hidnplayr 1247
        inc     [ebx + device.last_tx]
1248
        and     [ebx + device.last_tx], TX_RING_SIZE-1
3545 hidnplayr 1249
 
1250
        jmp     .loop_tx
5180 hidnplayr 1251
  .end_tx:
1252
        pop     ecx esi eax
1253
  .not_tx:
3545 hidnplayr 1254
 
1255
;----------------------------------
1256
; RX irq
5180 hidnplayr 1257
        test    eax, CSR5_RI
3545 hidnplayr 1258
        jz      .not_rx
5180 hidnplayr 1259
        push    eax esi ecx
3545 hidnplayr 1260
 
1261
        DEBUGF 1,"RX ok!\n"
1262
 
1263
        push    ebx
1264
  .rx_loop:
1265
        pop     ebx
1266
 
1267
        ; get current descriptor
5180 hidnplayr 1268
        mov     eax, [ebx + device.cur_rx]
1269
        mov     edx, sizeof.desc
3545 hidnplayr 1270
        mul     edx
5180 hidnplayr 1271
        lea     edi, [ebx + device.rx_ring + eax]
3545 hidnplayr 1272
 
1273
        ; now check status
5180 hidnplayr 1274
        mov     eax, [edi + desc.status]
3545 hidnplayr 1275
 
1276
        test    eax, DES0_OWN
1277
        jnz     .end_rx                                 ; current desc is busy, nothing to do
1278
        test    eax, RDES0_FS
1279
        jz      .end_rx                                 ; current desc is NOT first packet, ERROR!
1280
        test    eax, RDES0_LS                           ; if not last desc of packet, error for now
1281
        jz      .end_rx
1282
        test    eax, RDES0_ES
1283
        jnz     .end_rx
1284
 
5180 hidnplayr 1285
        mov     esi, [edi + RX_RING_SIZE*sizeof.desc]
1286
        mov     ecx, [edi + desc.status]
3545 hidnplayr 1287
        shr     ecx, RDES0_FL_SH
1288
        and     ecx, RDES0_FL_MASK
1289
        sub     ecx, 4                                  ; crc, we dont need it
1290
 
5180 hidnplayr 1291
        DEBUGF  1,"size=%u, addr:0x%x\n", ecx, esi
3545 hidnplayr 1292
 
1293
        push    esi edi ecx
5046 hidnplayr 1294
        invoke  KernelAlloc, ecx                        ; Allocate a buffer to put packet into
3545 hidnplayr 1295
        pop     ecx edi esi
1296
        test    eax, eax
1297
        jz      .fail
1298
 
1299
        push    ebx
1300
        push    dword .rx_loop
1301
        push    ecx eax
5180 hidnplayr 1302
        xchg    edi, eax
3545 hidnplayr 1303
 
1304
; update statistics
5046 hidnplayr 1305
        inc     [ebx + device.packets_rx]
5180 hidnplayr 1306
        add     dword[ebx + device.bytes_rx], ecx
1307
        adc     dword[ebx + device.bytes_rx + 4], 0
3545 hidnplayr 1308
 
1309
; copy packet data
5180 hidnplayr 1310
        shr     cx, 1
3545 hidnplayr 1311
        jnc     .nb
1312
        movsb
1313
  .nb:
5180 hidnplayr 1314
        shr     cx, 1
3545 hidnplayr 1315
        jnc     .nw
1316
        movsw
1317
  .nw:
1318
        rep     movsd
1319
 
5180 hidnplayr 1320
        mov     [eax + desc.status], DES0_OWN           ; free descriptor
3545 hidnplayr 1321
 
5180 hidnplayr 1322
        inc     [ebx + device.cur_rx]                   ; next descriptor
1323
        and     [ebx + device.cur_rx], RX_RING_SIZE-1
3545 hidnplayr 1324
 
5046 hidnplayr 1325
        jmp     [Eth_input]
3545 hidnplayr 1326
 
1327
  .end_rx:
1328
  .fail:
5180 hidnplayr 1329
        pop     ecx esi eax
3545 hidnplayr 1330
  .not_rx:
1331
 
1332
        pop     edi esi ebx
1333
        ret
1334
 
1335
 
1336
 
1337
align 4
1338
write_mac:      ; in: mac pushed onto stack (as 3 words)
1339
 
5180 hidnplayr 1340
        DEBUGF  1,"Writing MAC\n"
3545 hidnplayr 1341
 
1342
; write data into driver cache
1343
        mov     esi, esp
5046 hidnplayr 1344
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1345
        movsd
1346
        movsw
1347
        add     esp, 6
1348
 
5180 hidnplayr 1349
;; send setup packet (only if driver is started)
1350
;;        call    Create_Setup_Packet
3545 hidnplayr 1351
 
1352
align 4
1353
read_mac_eeprom:
1354
 
5180 hidnplayr 1355
        DEBUGF  1,"Reading MAC from eeprom\n"
3545 hidnplayr 1356
 
5046 hidnplayr 1357
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1358
        mov     esi, 20/2               ; read words, start address is 20
1359
     .loop:
1360
        push    esi edi
1361
        call    SROM_Read_Word
1362
        pop     edi esi
1363
        stosw
1364
        inc     esi
1365
        cmp     esi, 26/2
1366
        jb      .loop
1367
 
5180 hidnplayr 1368
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2
3545 hidnplayr 1369
 
1370
        ret
1371
 
1372
 
1373
align 4
1374
SROM_GetWidth:  ; should be 6 or 8 according to some manuals (returns in ecx)
1375
 
5180 hidnplayr 1376
;        DEBUGF 1,"SROM_GetWidth\n"
3545 hidnplayr 1377
 
1378
        call    SROM_Idle
1379
        call    SROM_EnterAccessMode
1380
 
5046 hidnplayr 1381
;        set_io  [ebx + device.io_addr], 0
1382
;        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1383
 
1384
        ; send 110b
1385
 
1386
        in      eax, dx
1387
        or      eax, CSR9_SROM_DI
1388
        call    SROM_out
1389
 
1390
        in      eax, dx
1391
        or      eax, CSR9_SROM_DI
1392
        call    SROM_out
1393
 
1394
        in      eax, dx
1395
        and     eax, not (CSR9_SROM_DI)
1396
        call    SROM_out
1397
 
1398
        mov     ecx,1
1399
  .loop2:
1400
        Bit_Set CSR9_SROM_CK
1401
        SROM_Delay
1402
 
1403
        in      eax, dx
1404
        and     eax, CSR9_SROM_DO
1405
        jnz     .not_zero
1406
 
1407
        Bit_Clear CSR9_SROM_CK
1408
        SROM_Delay
1409
        jmp     .end_loop2
1410
  .not_zero:
1411
 
1412
        Bit_Clear CSR9_SROM_CK
1413
        SROM_Delay
1414
 
1415
        inc     ecx
1416
        cmp     ecx, 12
1417
        jbe     .loop2
1418
  .end_loop2:
1419
 
5180 hidnplayr 1420
        DEBUGF  1,"SROM width=%u\n", ecx
3545 hidnplayr 1421
 
1422
        call    SROM_Idle
1423
        call    SROM_EnterAccessMode
1424
        call    SROM_Idle
1425
 
1426
        ret
1427
 
1428
 
1429
align 4
1430
SROM_out:
1431
 
1432
        out     dx, eax
1433
        SROM_Delay
1434
        Bit_Set CSR9_SROM_CK
1435
        SROM_Delay
1436
        Bit_Clear CSR9_SROM_CK
1437
        SROM_Delay
1438
 
1439
        ret
1440
 
1441
 
1442
 
1443
align 4
1444
SROM_EnterAccessMode:
1445
 
5180 hidnplayr 1446
;        DEBUGF 1,"SROM_EnterAccessMode\n"
3545 hidnplayr 1447
 
5046 hidnplayr 1448
        set_io  [ebx + device.io_addr], 0
1449
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1450
        mov     eax, CSR9_SR
1451
        out     dx, eax
1452
        SROM_Delay
1453
 
1454
        Bit_Set CSR9_RD
1455
        SROM_Delay
1456
 
1457
        Bit_Clear CSR9_SROM_CK
1458
        SROM_Delay
1459
 
1460
        Bit_Set CSR9_SROM_CS
1461
        SROM_Delay
1462
 
1463
        ret
1464
 
1465
 
1466
 
1467
align 4
1468
SROM_Idle:
1469
 
5180 hidnplayr 1470
;        DEBUGF 1,"SROM_Idle\n"
3545 hidnplayr 1471
 
1472
        call    SROM_EnterAccessMode
1473
 
5046 hidnplayr 1474
;        set_io  [ebx + device.io_addr], 0
1475
;        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1476
 
1477
        mov     ecx, 25
1478
     .loop_clk:
1479
 
1480
        Bit_Clear CSR9_SROM_CK
1481
        SROM_Delay
1482
        Bit_Set CSR9_SROM_CK
1483
        SROM_Delay
1484
 
1485
        dec     ecx
1486
        jnz     .loop_clk
1487
 
1488
 
1489
        Bit_Clear CSR9_SROM_CK
1490
        SROM_Delay
1491
        Bit_Clear CSR9_SROM_CS
1492
        SROM_Delay
1493
 
1494
        xor     eax, eax
1495
        out     dx, eax
1496
 
1497
        ret
1498
 
1499
 
1500
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1501
;;                                                                      ;;
1502
;; Read serial EEprom word                                              ;;
1503
;;                                                                      ;;
1504
;; In: esi = read address                                               ;;
1505
;; OUT: ax = data word                                                  ;;
1506
;;                                                                      ;;
1507
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1508
align 4
1509
SROM_Read_Word:
1510
 
5180 hidnplayr 1511
;        DEBUGF 1,"SROM_Read_word at: %x\n", esi
3545 hidnplayr 1512
 
5046 hidnplayr 1513
        set_io  [ebx + device.io_addr], 0
1514
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1515
 
1516
; enter access mode
1517
        mov     eax, CSR9_SR + CSR9_RD
1518
        out     dx , eax
1519
        or      eax, CSR9_SROM_CS
1520
        out     dx , eax
1521
 
1522
        ; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
1523
 
1524
; send read command "110b" + address to read from
1525
        and     esi, 111111b
1526
        or      esi, 110b shl 6
1527
 
1528
        mov     ecx, 1 shl 9
1529
  .loop_cmd:
1530
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1531
        test    esi, ecx
1532
        jz      @f
1533
        or      eax, CSR9_SROM_DI
1534
       @@:
1535
        out     dx , eax
1536
        SROM_Delay
1537
        or      eax, CSR9_SROM_CK
1538
        out     dx , eax
1539
        SROM_Delay
1540
 
1541
        shr     ecx, 1
1542
        jnz     .loop_cmd
1543
 
1544
; read data from SROM
1545
 
1546
        xor     esi, esi
1547
        mov     ecx, 17 ;;; TODO: figure out why 17, not 16
1548
  .loop_read:
1549
 
1550
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
1551
        out     dx , eax
1552
        SROM_Delay
1553
 
1554
        in      eax, dx
1555
        and     eax, CSR9_SROM_DO
1556
        shr     eax, 3
1557
        shl     esi, 1
1558
        or      esi, eax
1559
 
1560
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1561
        out     dx , eax
1562
        SROM_Delay
1563
 
1564
        dec     ecx
1565
        jnz     .loop_read
1566
 
1567
        mov     eax, esi
1568
 
5180 hidnplayr 1569
;        DEBUGF 1,"%x\n", ax
3545 hidnplayr 1570
 
1571
        ret
1572
 
1573
 
1574
 
1575
;*********************************************************************
1576
;* Media Descriptor Code                                             *
1577
;*********************************************************************
1578
 
1579
; MII transceiver control section.
1580
; Read and write the MII registers using software-generated serial
1581
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1582
; for details.
1583
 
1584
; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
1585
; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
1586
; "overclocking" issues or future 66Mhz PCI.
1587
 
1588
; Read and write the MII registers using software-generated serial
1589
; MDIO protocol.  It is just different enough from the EEPROM protocol
1590
; to not share code.  The maxium data clock rate is 2.5 Mhz.
1591
 
5180 hidnplayr 1592
MDIO_SHIFT_CLK          = 0x10000
1593
MDIO_DATA_WRITE0        = 0x00000
1594
MDIO_DATA_WRITE1        = 0x20000
1595
MDIO_ENB                = 0x00000       ; Ignore the 0x02000 databook setting.
1596
MDIO_ENB_IN             = 0x40000
1597
MDIO_DATA_READ          = 0x80000
3545 hidnplayr 1598
 
1599
; MII transceiver control section.
1600
; Read and write the MII registers using software-generated serial
1601
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1602
; for details.
1603
 
1604
align 4
1605
mdio_read:      ; phy_id:edx, location:esi
1606
 
5180 hidnplayr 1607
        DEBUGF  1,"mdio read, phy=%x, location=%x\n", edx, esi
3545 hidnplayr 1608
 
1609
        shl     edx, 5
1610
        or      esi, edx
1611
        or      esi, 0xf6 shl 10
1612
 
5046 hidnplayr 1613
        set_io  [ebx + device.io_addr], 0
1614
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1615
 
1616
;    if (tp->chip_id == LC82C168) {
1617
;        int i = 1000;
1618
;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
1619
;        inl(ioaddr + 0xA0);
1620
;        inl(ioaddr + 0xA0);
1621
;        while (--i > 0)
1622
;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
1623
;                return retval & 0xffff;
1624
;        return 0xffff;
1625
;    }
1626
;
1627
;    if (tp->chip_id == COMET) {
1628
;        if (phy_id == 1) {
1629
;            if (location < 7)
1630
;                return inl(ioaddr + 0xB4 + (location<<2));
1631
;            else if (location == 17)
1632
;                return inl(ioaddr + 0xD0);
1633
;            else if (location >= 29 && location <= 31)
1634
;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
1635
;        }
1636
;        return 0xffff;
1637
;    }
1638
 
1639
; Establish sync by sending at least 32 logic ones.
1640
 
1641
        mov     ecx, 32
1642
  .loop:
1643
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1644
        out     dx, eax
1645
        MDIO_Delay
1646
 
1647
        or      eax, MDIO_SHIFT_CLK
1648
        out     dx, eax
1649
        MDIO_Delay
1650
 
1651
        dec     ecx
1652
        jnz     .loop
1653
 
1654
 
1655
; Shift the read command bits out.
1656
 
1657
        mov     ecx, 1 shl 15
1658
  .loop2:
1659
        mov     eax, MDIO_ENB
1660
        test    esi, ecx
1661
        jz      @f
1662
        or      eax, MDIO_DATA_WRITE1
1663
       @@:
1664
        out     dx, eax
1665
        MDIO_Delay
1666
 
1667
        or      eax, MDIO_SHIFT_CLK
1668
        out     dx, eax
1669
        MDIO_Delay
1670
 
1671
        shr     ecx, 1
1672
        jnz     .loop2
1673
 
1674
 
1675
; Read the two transition, 16 data, and wire-idle bits.
1676
 
1677
        xor     esi, esi
1678
        mov     ecx, 19
1679
  .loop3:
1680
        mov     eax, MDIO_ENB_IN
1681
        out     dx, eax
1682
        MDIO_Delay
1683
 
1684
        shl     esi, 1
1685
        in      eax, dx
1686
        test    eax, MDIO_DATA_READ
1687
        jz      @f
1688
        inc     esi
1689
       @@:
1690
 
1691
        mov     eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
1692
        out     dx, eax
1693
        MDIO_Delay
1694
 
1695
        dec     ecx
1696
        jnz     .loop3
1697
 
1698
        shr     esi, 1
1699
        movzx   eax, si
1700
 
5180 hidnplayr 1701
        DEBUGF  1,"data=%x\n", ax
3545 hidnplayr 1702
 
1703
        ret
1704
 
1705
 
1706
 
1707
 
1708
align 4
1709
mdio_write:     ;int phy_id: edx, int location: edi, int value: ax)
1710
 
1711
        DEBUGF  1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
1712
 
1713
        shl     edi, 18
1714
        or      edi, 0x5002 shl 16
1715
        shl     edx, 23
1716
        or      edi, edx
1717
        mov     di, ax
1718
 
5046 hidnplayr 1719
        set_io  [ebx + device.io_addr], 0
1720
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1721
 
1722
;    if (tp->chip_id == LC82C168) {
1723
;        int i = 1000;
1724
;        outl(cmd, ioaddr + 0xA0);
1725
;        do
1726
;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
1727
;                break;
1728
;        while (--i > 0);
1729
;        return;
1730
;    }
1731
 
1732
;    if (tp->chip_id == COMET) {
1733
;        if (phy_id != 1)
1734
;            return;
1735
;        if (location < 7)
1736
;            outl(value, ioaddr + 0xB4 + (location<<2));
1737
;        else if (location == 17)
1738
;            outl(value, ioaddr + 0xD0);
1739
;        else if (location >= 29 && location <= 31)
1740
;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
1741
;        return;
1742
;    }
1743
 
1744
 
1745
; Establish sync by sending at least 32 logic ones.
1746
 
1747
        mov     ecx, 32
1748
  .loop:
1749
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1750
        out     dx, eax
1751
        MDIO_Delay
1752
 
1753
        or      eax, MDIO_SHIFT_CLK
1754
        out     dx, eax
1755
        MDIO_Delay
1756
 
1757
        dec     ecx
1758
        jnz     .loop
1759
 
1760
 
1761
; Shift the command bits out.
1762
 
1763
        mov     ecx, 1 shl 31
1764
  .loop2:
1765
        mov     eax, MDIO_ENB
1766
        test    edi, ecx
1767
        jz      @f
1768
        or      eax, MDIO_DATA_WRITE1
1769
       @@:
1770
        out     dx, eax
1771
        MDIO_Delay
1772
 
1773
        or      eax, MDIO_SHIFT_CLK
1774
        out     dx, eax
1775
        MDIO_Delay
1776
 
1777
        shr     ecx, 1
1778
        jnz     .loop2
1779
 
1780
 
1781
; Clear out extra bits.
1782
 
1783
        mov     ecx, 2
1784
  .loop3:
1785
        mov     eax, MDIO_ENB
1786
        out     dx, eax
1787
        MDIO_Delay
1788
 
1789
        or      eax, MDIO_SHIFT_CLK
1790
        out     dx, eax
1791
        MDIO_Delay
1792
 
1793
        dec     ecx
1794
        jnz     .loop3
1795
 
1796
        ret
1797
 
1798
 
5180 hidnplayr 1799
 
1800
 
1801
 
1802
 
3545 hidnplayr 1803
; End of code
1804
 
5046 hidnplayr 1805
data fixups
1806
end data
1807
 
1808
include '../peimport.inc'
1809
 
3545 hidnplayr 1810
my_service    db 'DEC21X4X',0                    ; max 16 chars include zero
1811
 
5180 hidnplayr 1812
chiplist:
1813
;   PCI id's , chip ,IO size, CSR7      , name  ,  flags
1814
dd 0x00021011, DC21040,  128, 0x0001ebef, sz_040,  0
1815
dd 0x00141011, DC21041,  128, 0x0001ebef, sz_041,  FLAG_HAS_MEDIA_TABLE
1816
dd 0x00091011, DC21140,  128, 0x0001ebef, sz_140,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
1817
dd 0x00191011, DC21143,  128, 0x0001ebef, sz_143,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_ALWAYS_CHECK_MII or FLAG_HAS_ACPI
1818
dd 0x000211AD, LC82C168, 256, 0x0801fbff, sz_lite, FLAG_HAS_MII
1819
dd 0x051210D9, MX98713,  128, 0x0001ebef, sz_m512, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE
1820
dd 0x053110D9, MX98715,  256, 0x0001ebef, sz_m513, FLAG_HAS_MEDIA_TABLE
1821
dd 0x1400125B, MX98725,  128, 0x0001fbff, sz_asix, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
1822
dd 0
1823
 
1824
sz_040  db "Digital DC21040 Tulip", 0
1825
sz_041  db "Digital DC21041 Tulip", 0
1826
sz_140  db "Digital DS21140 Tulip", 0
1827
sz_143  db "Digital DS21143 Tulip", 0
1828
sz_lite db "Lite-On 82c168 PNIC", 0
1829
sz_m512 db "Macronix 98713 PMAC", 0
1830
sz_m513 db "Macronix 987x5 PMAC", 0
1831
sz_asix db "ASIX AX88140", 0
1832
 
3545 hidnplayr 1833
include_debug_strings                           ; All data wich FDO uses will be included here
1834
 
5046 hidnplayr 1835
align 4
1836
devices         dd 0
5180 hidnplayr 1837
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling