Subversion Repositories Kolibri OS

Rev

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
;;                                                                 ;;
5363 yogev_ezra 3
;; Copyright (C) KolibriOS team 2004-2015. 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
5184 hidnplayr 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:
5184 hidnplayr 1230
        ; get last descriptor
5180 hidnplayr 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
5184 hidnplayr 1243
        DEBUGF  1,"Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
5180 hidnplayr 1244
        invoke  KernelFree, [eax + TX_RING_SIZE*sizeof.desc]
3545 hidnplayr 1245
 
5184 hidnplayr 1246
        ; advance to 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
5184 hidnplayr 1257
 
5180 hidnplayr 1258
        test    eax, CSR5_RI
3545 hidnplayr 1259
        jz      .not_rx
5180 hidnplayr 1260
        push    eax esi ecx
3545 hidnplayr 1261
 
1262
        DEBUGF 1,"RX ok!\n"
1263
 
1264
        push    ebx
1265
  .rx_loop:
1266
        pop     ebx
1267
 
5184 hidnplayr 1268
; get current descriptor
5180 hidnplayr 1269
        mov     eax, [ebx + device.cur_rx]
1270
        mov     edx, sizeof.desc
3545 hidnplayr 1271
        mul     edx
5180 hidnplayr 1272
        lea     edi, [ebx + device.rx_ring + eax]
3545 hidnplayr 1273
 
5184 hidnplayr 1274
; Check current RX descriptor status
5180 hidnplayr 1275
        mov     eax, [edi + desc.status]
3545 hidnplayr 1276
 
1277
        test    eax, DES0_OWN
1278
        jnz     .end_rx                                 ; current desc is busy, nothing to do
1279
        test    eax, RDES0_FS
1280
        jz      .end_rx                                 ; current desc is NOT first packet, ERROR!
1281
        test    eax, RDES0_LS                           ; if not last desc of packet, error for now
1282
        jz      .end_rx
1283
        test    eax, RDES0_ES
1284
        jnz     .end_rx
1285
 
5184 hidnplayr 1286
; Calculate length
5180 hidnplayr 1287
        mov     ecx, [edi + desc.status]
3545 hidnplayr 1288
        shr     ecx, RDES0_FL_SH
1289
        and     ecx, RDES0_FL_MASK
5184 hidnplayr 1290
        sub     ecx, 4                                  ; throw away the CRC
1291
        DEBUGF  1,"got %u bytes\n", ecx
3545 hidnplayr 1292
 
5184 hidnplayr 1293
; Push arguments for Eth_input (and some more...)
3545 hidnplayr 1294
        push    ebx
5184 hidnplayr 1295
        push    .rx_loop                                ; return addr
1296
        push    ecx                                     ; packet size
1297
        push    dword[edi + RX_RING_SIZE*sizeof.desc]   ; packet ptr
3545 hidnplayr 1298
 
1299
; update statistics
5046 hidnplayr 1300
        inc     [ebx + device.packets_rx]
5180 hidnplayr 1301
        add     dword[ebx + device.bytes_rx], ecx
1302
        adc     dword[ebx + device.bytes_rx + 4], 0
3545 hidnplayr 1303
 
5184 hidnplayr 1304
; Allocate new descriptor
1305
        push    edi ebx
1306
        invoke  KernelAlloc, 1536                       ; Allocate a buffer to put packet into
1307
        pop     ebx edi
1308
        mov     [edi + RX_RING_SIZE*sizeof.desc], eax
1309
        invoke  GetPhysAddr
1310
        mov     [edi + desc.buffer1], eax
1311
        mov     [edi + desc.status], DES0_OWN           ; mark descriptor as being free
3545 hidnplayr 1312
 
5184 hidnplayr 1313
; Move to next rx desc
5180 hidnplayr 1314
        inc     [ebx + device.cur_rx]                   ; next descriptor
1315
        and     [ebx + device.cur_rx], RX_RING_SIZE-1
3545 hidnplayr 1316
 
5046 hidnplayr 1317
        jmp     [Eth_input]
3545 hidnplayr 1318
  .end_rx:
1319
  .not_rx:
1320
 
1321
        pop     edi esi ebx
1322
        ret
1323
 
1324
 
1325
 
1326
align 4
1327
write_mac:      ; in: mac pushed onto stack (as 3 words)
1328
 
5180 hidnplayr 1329
        DEBUGF  1,"Writing MAC\n"
3545 hidnplayr 1330
 
1331
; write data into driver cache
1332
        mov     esi, esp
5046 hidnplayr 1333
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1334
        movsd
1335
        movsw
1336
        add     esp, 6
1337
 
5180 hidnplayr 1338
;; send setup packet (only if driver is started)
1339
;;        call    Create_Setup_Packet
3545 hidnplayr 1340
 
1341
align 4
1342
read_mac_eeprom:
1343
 
5180 hidnplayr 1344
        DEBUGF  1,"Reading MAC from eeprom\n"
3545 hidnplayr 1345
 
5046 hidnplayr 1346
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1347
        mov     esi, 20/2               ; read words, start address is 20
1348
     .loop:
1349
        push    esi edi
1350
        call    SROM_Read_Word
1351
        pop     edi esi
1352
        stosw
1353
        inc     esi
1354
        cmp     esi, 26/2
1355
        jb      .loop
1356
 
5180 hidnplayr 1357
        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 1358
 
1359
        ret
1360
 
1361
 
1362
align 4
1363
SROM_GetWidth:  ; should be 6 or 8 according to some manuals (returns in ecx)
1364
 
5180 hidnplayr 1365
;        DEBUGF 1,"SROM_GetWidth\n"
3545 hidnplayr 1366
 
1367
        call    SROM_Idle
1368
        call    SROM_EnterAccessMode
1369
 
5046 hidnplayr 1370
;        set_io  [ebx + device.io_addr], 0
1371
;        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1372
 
1373
        ; send 110b
1374
 
1375
        in      eax, dx
1376
        or      eax, CSR9_SROM_DI
1377
        call    SROM_out
1378
 
1379
        in      eax, dx
1380
        or      eax, CSR9_SROM_DI
1381
        call    SROM_out
1382
 
1383
        in      eax, dx
1384
        and     eax, not (CSR9_SROM_DI)
1385
        call    SROM_out
1386
 
1387
        mov     ecx,1
1388
  .loop2:
1389
        Bit_Set CSR9_SROM_CK
1390
        SROM_Delay
1391
 
1392
        in      eax, dx
1393
        and     eax, CSR9_SROM_DO
1394
        jnz     .not_zero
1395
 
1396
        Bit_Clear CSR9_SROM_CK
1397
        SROM_Delay
1398
        jmp     .end_loop2
1399
  .not_zero:
1400
 
1401
        Bit_Clear CSR9_SROM_CK
1402
        SROM_Delay
1403
 
1404
        inc     ecx
1405
        cmp     ecx, 12
1406
        jbe     .loop2
1407
  .end_loop2:
1408
 
5180 hidnplayr 1409
        DEBUGF  1,"SROM width=%u\n", ecx
3545 hidnplayr 1410
 
1411
        call    SROM_Idle
1412
        call    SROM_EnterAccessMode
1413
        call    SROM_Idle
1414
 
1415
        ret
1416
 
1417
 
1418
align 4
1419
SROM_out:
1420
 
1421
        out     dx, eax
1422
        SROM_Delay
1423
        Bit_Set CSR9_SROM_CK
1424
        SROM_Delay
1425
        Bit_Clear CSR9_SROM_CK
1426
        SROM_Delay
1427
 
1428
        ret
1429
 
1430
 
1431
 
1432
align 4
1433
SROM_EnterAccessMode:
1434
 
5180 hidnplayr 1435
;        DEBUGF 1,"SROM_EnterAccessMode\n"
3545 hidnplayr 1436
 
5046 hidnplayr 1437
        set_io  [ebx + device.io_addr], 0
1438
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1439
        mov     eax, CSR9_SR
1440
        out     dx, eax
1441
        SROM_Delay
1442
 
1443
        Bit_Set CSR9_RD
1444
        SROM_Delay
1445
 
1446
        Bit_Clear CSR9_SROM_CK
1447
        SROM_Delay
1448
 
1449
        Bit_Set CSR9_SROM_CS
1450
        SROM_Delay
1451
 
1452
        ret
1453
 
1454
 
1455
 
1456
align 4
1457
SROM_Idle:
1458
 
5180 hidnplayr 1459
;        DEBUGF 1,"SROM_Idle\n"
3545 hidnplayr 1460
 
1461
        call    SROM_EnterAccessMode
1462
 
5046 hidnplayr 1463
;        set_io  [ebx + device.io_addr], 0
1464
;        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1465
 
1466
        mov     ecx, 25
1467
     .loop_clk:
1468
 
1469
        Bit_Clear CSR9_SROM_CK
1470
        SROM_Delay
1471
        Bit_Set CSR9_SROM_CK
1472
        SROM_Delay
1473
 
1474
        dec     ecx
1475
        jnz     .loop_clk
1476
 
1477
 
1478
        Bit_Clear CSR9_SROM_CK
1479
        SROM_Delay
1480
        Bit_Clear CSR9_SROM_CS
1481
        SROM_Delay
1482
 
1483
        xor     eax, eax
1484
        out     dx, eax
1485
 
1486
        ret
1487
 
1488
 
1489
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1490
;;                                                                      ;;
1491
;; Read serial EEprom word                                              ;;
1492
;;                                                                      ;;
1493
;; In: esi = read address                                               ;;
1494
;; OUT: ax = data word                                                  ;;
1495
;;                                                                      ;;
1496
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1497
align 4
1498
SROM_Read_Word:
1499
 
5180 hidnplayr 1500
;        DEBUGF 1,"SROM_Read_word at: %x\n", esi
3545 hidnplayr 1501
 
5046 hidnplayr 1502
        set_io  [ebx + device.io_addr], 0
1503
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1504
 
1505
; enter access mode
1506
        mov     eax, CSR9_SR + CSR9_RD
1507
        out     dx , eax
1508
        or      eax, CSR9_SROM_CS
1509
        out     dx , eax
1510
 
1511
        ; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
1512
 
1513
; send read command "110b" + address to read from
1514
        and     esi, 111111b
1515
        or      esi, 110b shl 6
1516
 
1517
        mov     ecx, 1 shl 9
1518
  .loop_cmd:
1519
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1520
        test    esi, ecx
1521
        jz      @f
1522
        or      eax, CSR9_SROM_DI
1523
       @@:
1524
        out     dx , eax
1525
        SROM_Delay
1526
        or      eax, CSR9_SROM_CK
1527
        out     dx , eax
1528
        SROM_Delay
1529
 
1530
        shr     ecx, 1
1531
        jnz     .loop_cmd
1532
 
1533
; read data from SROM
1534
 
1535
        xor     esi, esi
1536
        mov     ecx, 17 ;;; TODO: figure out why 17, not 16
1537
  .loop_read:
1538
 
1539
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
1540
        out     dx , eax
1541
        SROM_Delay
1542
 
1543
        in      eax, dx
1544
        and     eax, CSR9_SROM_DO
1545
        shr     eax, 3
1546
        shl     esi, 1
1547
        or      esi, eax
1548
 
1549
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1550
        out     dx , eax
1551
        SROM_Delay
1552
 
1553
        dec     ecx
1554
        jnz     .loop_read
1555
 
1556
        mov     eax, esi
1557
 
5180 hidnplayr 1558
;        DEBUGF 1,"%x\n", ax
3545 hidnplayr 1559
 
1560
        ret
1561
 
1562
 
1563
 
1564
;*********************************************************************
1565
;* Media Descriptor Code                                             *
1566
;*********************************************************************
1567
 
1568
; MII transceiver control section.
1569
; Read and write the MII registers using software-generated serial
1570
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1571
; for details.
1572
 
1573
; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
1574
; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
1575
; "overclocking" issues or future 66Mhz PCI.
1576
 
1577
; Read and write the MII registers using software-generated serial
1578
; MDIO protocol.  It is just different enough from the EEPROM protocol
1579
; to not share code.  The maxium data clock rate is 2.5 Mhz.
1580
 
5180 hidnplayr 1581
MDIO_SHIFT_CLK          = 0x10000
1582
MDIO_DATA_WRITE0        = 0x00000
1583
MDIO_DATA_WRITE1        = 0x20000
1584
MDIO_ENB                = 0x00000       ; Ignore the 0x02000 databook setting.
1585
MDIO_ENB_IN             = 0x40000
1586
MDIO_DATA_READ          = 0x80000
3545 hidnplayr 1587
 
1588
; MII transceiver control section.
1589
; Read and write the MII registers using software-generated serial
1590
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1591
; for details.
1592
 
1593
align 4
1594
mdio_read:      ; phy_id:edx, location:esi
1595
 
5180 hidnplayr 1596
        DEBUGF  1,"mdio read, phy=%x, location=%x\n", edx, esi
3545 hidnplayr 1597
 
1598
        shl     edx, 5
1599
        or      esi, edx
1600
        or      esi, 0xf6 shl 10
1601
 
5046 hidnplayr 1602
        set_io  [ebx + device.io_addr], 0
1603
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1604
 
1605
;    if (tp->chip_id == LC82C168) {
1606
;        int i = 1000;
1607
;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
1608
;        inl(ioaddr + 0xA0);
1609
;        inl(ioaddr + 0xA0);
1610
;        while (--i > 0)
1611
;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
1612
;                return retval & 0xffff;
1613
;        return 0xffff;
1614
;    }
1615
;
1616
;    if (tp->chip_id == COMET) {
1617
;        if (phy_id == 1) {
1618
;            if (location < 7)
1619
;                return inl(ioaddr + 0xB4 + (location<<2));
1620
;            else if (location == 17)
1621
;                return inl(ioaddr + 0xD0);
1622
;            else if (location >= 29 && location <= 31)
1623
;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
1624
;        }
1625
;        return 0xffff;
1626
;    }
1627
 
1628
; Establish sync by sending at least 32 logic ones.
1629
 
1630
        mov     ecx, 32
1631
  .loop:
1632
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1633
        out     dx, eax
1634
        MDIO_Delay
1635
 
1636
        or      eax, MDIO_SHIFT_CLK
1637
        out     dx, eax
1638
        MDIO_Delay
1639
 
1640
        dec     ecx
1641
        jnz     .loop
1642
 
1643
 
1644
; Shift the read command bits out.
1645
 
1646
        mov     ecx, 1 shl 15
1647
  .loop2:
1648
        mov     eax, MDIO_ENB
1649
        test    esi, ecx
1650
        jz      @f
1651
        or      eax, MDIO_DATA_WRITE1
1652
       @@:
1653
        out     dx, eax
1654
        MDIO_Delay
1655
 
1656
        or      eax, MDIO_SHIFT_CLK
1657
        out     dx, eax
1658
        MDIO_Delay
1659
 
1660
        shr     ecx, 1
1661
        jnz     .loop2
1662
 
1663
 
1664
; Read the two transition, 16 data, and wire-idle bits.
1665
 
1666
        xor     esi, esi
1667
        mov     ecx, 19
1668
  .loop3:
1669
        mov     eax, MDIO_ENB_IN
1670
        out     dx, eax
1671
        MDIO_Delay
1672
 
1673
        shl     esi, 1
1674
        in      eax, dx
1675
        test    eax, MDIO_DATA_READ
1676
        jz      @f
1677
        inc     esi
1678
       @@:
1679
 
1680
        mov     eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
1681
        out     dx, eax
1682
        MDIO_Delay
1683
 
1684
        dec     ecx
1685
        jnz     .loop3
1686
 
1687
        shr     esi, 1
1688
        movzx   eax, si
1689
 
5180 hidnplayr 1690
        DEBUGF  1,"data=%x\n", ax
3545 hidnplayr 1691
 
1692
        ret
1693
 
1694
 
1695
 
1696
 
1697
align 4
1698
mdio_write:     ;int phy_id: edx, int location: edi, int value: ax)
1699
 
1700
        DEBUGF  1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
1701
 
1702
        shl     edi, 18
1703
        or      edi, 0x5002 shl 16
1704
        shl     edx, 23
1705
        or      edi, edx
1706
        mov     di, ax
1707
 
5046 hidnplayr 1708
        set_io  [ebx + device.io_addr], 0
1709
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1710
 
1711
;    if (tp->chip_id == LC82C168) {
1712
;        int i = 1000;
1713
;        outl(cmd, ioaddr + 0xA0);
1714
;        do
1715
;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
1716
;                break;
1717
;        while (--i > 0);
1718
;        return;
1719
;    }
1720
 
1721
;    if (tp->chip_id == COMET) {
1722
;        if (phy_id != 1)
1723
;            return;
1724
;        if (location < 7)
1725
;            outl(value, ioaddr + 0xB4 + (location<<2));
1726
;        else if (location == 17)
1727
;            outl(value, ioaddr + 0xD0);
1728
;        else if (location >= 29 && location <= 31)
1729
;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
1730
;        return;
1731
;    }
1732
 
1733
 
1734
; Establish sync by sending at least 32 logic ones.
1735
 
1736
        mov     ecx, 32
1737
  .loop:
1738
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1739
        out     dx, eax
1740
        MDIO_Delay
1741
 
1742
        or      eax, MDIO_SHIFT_CLK
1743
        out     dx, eax
1744
        MDIO_Delay
1745
 
1746
        dec     ecx
1747
        jnz     .loop
1748
 
1749
 
1750
; Shift the command bits out.
1751
 
1752
        mov     ecx, 1 shl 31
1753
  .loop2:
1754
        mov     eax, MDIO_ENB
1755
        test    edi, ecx
1756
        jz      @f
1757
        or      eax, MDIO_DATA_WRITE1
1758
       @@:
1759
        out     dx, eax
1760
        MDIO_Delay
1761
 
1762
        or      eax, MDIO_SHIFT_CLK
1763
        out     dx, eax
1764
        MDIO_Delay
1765
 
1766
        shr     ecx, 1
1767
        jnz     .loop2
1768
 
1769
 
1770
; Clear out extra bits.
1771
 
1772
        mov     ecx, 2
1773
  .loop3:
1774
        mov     eax, MDIO_ENB
1775
        out     dx, eax
1776
        MDIO_Delay
1777
 
1778
        or      eax, MDIO_SHIFT_CLK
1779
        out     dx, eax
1780
        MDIO_Delay
1781
 
1782
        dec     ecx
1783
        jnz     .loop3
1784
 
1785
        ret
1786
 
1787
 
5180 hidnplayr 1788
 
1789
 
1790
 
1791
 
3545 hidnplayr 1792
; End of code
1793
 
5046 hidnplayr 1794
data fixups
1795
end data
1796
 
1797
include '../peimport.inc'
1798
 
3545 hidnplayr 1799
my_service    db 'DEC21X4X',0                    ; max 16 chars include zero
1800
 
5180 hidnplayr 1801
chiplist:
1802
;   PCI id's , chip ,IO size, CSR7      , name  ,  flags
1803
dd 0x00021011, DC21040,  128, 0x0001ebef, sz_040,  0
1804
dd 0x00141011, DC21041,  128, 0x0001ebef, sz_041,  FLAG_HAS_MEDIA_TABLE
1805
dd 0x00091011, DC21140,  128, 0x0001ebef, sz_140,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
1806
dd 0x00191011, DC21143,  128, 0x0001ebef, sz_143,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_ALWAYS_CHECK_MII or FLAG_HAS_ACPI
1807
dd 0x000211AD, LC82C168, 256, 0x0801fbff, sz_lite, FLAG_HAS_MII
1808
dd 0x051210D9, MX98713,  128, 0x0001ebef, sz_m512, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE
1809
dd 0x053110D9, MX98715,  256, 0x0001ebef, sz_m513, FLAG_HAS_MEDIA_TABLE
1810
dd 0x1400125B, MX98725,  128, 0x0001fbff, sz_asix, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
1811
dd 0
1812
 
1813
sz_040  db "Digital DC21040 Tulip", 0
1814
sz_041  db "Digital DC21041 Tulip", 0
1815
sz_140  db "Digital DS21140 Tulip", 0
1816
sz_143  db "Digital DS21143 Tulip", 0
1817
sz_lite db "Lite-On 82c168 PNIC", 0
1818
sz_m512 db "Macronix 98713 PMAC", 0
1819
sz_m513 db "Macronix 987x5 PMAC", 0
1820
sz_asix db "ASIX AX88140", 0
1821
 
3545 hidnplayr 1822
include_debug_strings                           ; All data wich FDO uses will be included here
1823
 
5046 hidnplayr 1824
align 4
1825
devices         dd 0
5180 hidnplayr 1826
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling