Subversion Repositories Kolibri OS

Rev

Rev 5363 | 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
; Reset the xcvr interface and turn on heartbeat.
598
        cmp     [ebx + device.id], DC21041
599
        jne     @f
5046 hidnplayr 600
        set_io  [ebx + device.io_addr], 0
5180 hidnplayr 601
        set_io  [ebx + device.io_addr], CSR13
602
        xor     eax, eax
603
        out     dx, eax
604
        set_io  [ebx + device.io_addr], CSR14
605
        dec     eax
606
        out     dx, eax
607
        set_io  [ebx + device.io_addr], CSR15
608
        inc     eax
609
        mov     al, 8
610
        out     dx, eax
611
        set_io  [ebx + device.io_addr], CSR6
612
        in      eax, dx
613
        or      ax, CSR6_ST
614
        out     dx, eax
615
        set_io  [ebx + device.io_addr], CSR13
616
        xor     eax, eax
617
        mov     ax, 0xEF05
618
        out     dx, eax
619
        jmp     .reset_done
620
  @@:
621
        cmp     [ebx + device.id], DC21040
622
        jne     @f
623
        set_io  [ebx + device.io_addr], 0
624
        set_io  [ebx + device.io_addr], CSR13
625
        xor     eax, eax
626
        out     dx, eax
627
        mov     al, 4
628
        out     dx, eax
629
        jmp     .reset_done
630
  @@:
631
        cmp     [ebx + device.id], DC21140
632
        jne     @f
633
        set_io  [ebx + device.io_addr], 0
634
        set_io  [ebx + device.io_addr], CSR12
635
        mov     eax, 0x100
636
        out     dx, eax
637
        jmp     .reset_done
638
  @@:
639
        cmp     [ebx + device.id], DC21142
640
        jne     @f
641
        ; if tp->mii_cnt
642
        set_io  [ebx + device.io_addr], 0
643
        set_io  [ebx + device.io_addr], CSR6
644
        mov     eax, 0x82020000
645
        out     dx, eax
646
        set_io  [ebx + device.io_addr], CSR13
647
        xor     eax, eax
648
        out     dx, eax
649
        set_io  [ebx + device.io_addr], CSR14
650
        out     dx, eax
651
        set_io  [ebx + device.io_addr], CSR6
652
        mov     eax, 0x820E0000
653
        out     dx, eax
654
        jmp     .reset_done
655
        ;;;; TODO
656
  @@:
657
        cmp     [ebx + device.id], LC82C168
658
        jne     @f
659
        ; TODO
660
  @@:
661
        cmp     [ebx + device.id], MX98713
662
        jne     @f
663
        ; TODO
664
  @@:
665
 
666
  .reset_done:
667
 
668
 
669
; OPEN
670
 
671
; Reset chip
672
        set_io  [ebx + device.io_addr], 0
5046 hidnplayr 673
        set_io  [ebx + device.io_addr], CSR0
5180 hidnplayr 674
        mov     eax, CSR0_RESET
3545 hidnplayr 675
        out     dx, eax
676
 
677
; wait at least 50 PCI cycles
5180 hidnplayr 678
        mov     esi, 100
5046 hidnplayr 679
        invoke  Sleep
3545 hidnplayr 680
 
681
;-----------------------------------
682
; Read mac from eeprom to driver ram
683
 
684
        call    read_mac_eeprom
685
 
686
;--------------------------------
687
; insert irq handler on given irq
688
 
5046 hidnplayr 689
        movzx   eax, [ebx + device.irq_line]
3545 hidnplayr 690
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
5046 hidnplayr 691
        invoke  AttachIntHandler, eax, int_handler, ebx
3545 hidnplayr 692
        test    eax, eax
693
        jnz     @f
4334 hidnplayr 694
        DEBUGF  2,"Could not attach int handler!\n"
5046 hidnplayr 695
        or      eax, -1
696
        ret
3545 hidnplayr 697
  @@:
698
 
5180 hidnplayr 699
;----------------
700
; Set cache modes
701
 
5046 hidnplayr 702
        set_io  [ebx + device.io_addr], 0
5180 hidnplayr 703
        set_io  [ebx + device.io_addr], CSR0
704
        mov     eax, 0x01A00000 or 0x4800 ; CSR0_DEFAULT
705
        out     dx, eax
3545 hidnplayr 706
 
5180 hidnplayr 707
        ; wait at least 50 PCI cycles
708
        mov     esi, 100
709
        invoke  Sleep
710
 
711
;---------------------------
712
; Initialize RX and TX rings
713
 
3545 hidnplayr 714
        call    init_ring
5180 hidnplayr 715
        test    eax, eax
716
        jnz     .err
3545 hidnplayr 717
 
5180 hidnplayr 718
;-------------------
719
; Set receive filter
720
 
721
        call    create_setup_frame
722
 
3545 hidnplayr 723
;--------------------------------------------
724
; setup CSR3 & CSR4 (pointers to descriptors)
725
 
5180 hidnplayr 726
        lea     eax, [ebx + device.rx_ring]
727
        invoke  GetPhysAddr
728
        DEBUGF  1,"RX descriptor base address: %x\n", eax
5046 hidnplayr 729
        set_io  [ebx + device.io_addr], 0
730
        set_io  [ebx + device.io_addr], CSR3
3545 hidnplayr 731
        out     dx, eax
732
 
5180 hidnplayr 733
        lea     eax, [ebx + device.tx_ring]
5046 hidnplayr 734
        invoke  GetPhysAddr
3545 hidnplayr 735
        DEBUGF  1,"TX descriptor base address: %x\n", eax
5180 hidnplayr 736
        set_io  [ebx + device.io_addr], CSR4
3545 hidnplayr 737
        out     dx, eax
738
 
5180 hidnplayr 739
; Select media
740
        push    [ebx + device.if_port]
741
        pop     [ebx + device.saved_if_port]
742
        cmp     [ebx + device.if_port], 0
743
        jne     @f
744
        push    [ebx + device.default_port]
745
        pop     [ebx + device.if_port]
746
  @@:
747
        cmp     [ebx + device.id], DC21041
748
        jne     @f
749
        cmp     [ebx + device.if_port], 4
750
        jbe     @f
751
        ; invalid port, select inital TP, autosense, autonegotiate
752
        mov     [ebx + device.if_port], 4                               ; CHECKME
753
  @@:
3545 hidnplayr 754
 
5180 hidnplayr 755
; Allow selecting a default media
756
        cmp     [ebx + device.mtable], 0
757
        je      .media_picked
3545 hidnplayr 758
 
5180 hidnplayr 759
        cmp     [ebx + device.if_port], 0
760
        je      @f
761
        ;; TODO
762
        jmp     .media_picked
763
  @@:
3545 hidnplayr 764
 
5180 hidnplayr 765
  .media_picked:
766
        mov     [ebx + device.csr6], 0
767
 
768
        cmp     [ebx + device.id], DC21142
769
        jne     @f
770
        cmp     [ebx + device.if_port], 0
771
        jne     @f
772
        ;; TODO
773
        mov     [ebx + device.csr6], 0x82420200
774
        mov     [ebx + device.if_port], 11
5046 hidnplayr 775
        set_io  [ebx + device.io_addr], 0
5180 hidnplayr 776
        set_io  [ebx + device.io_addr], CSR14
777
        mov     eax, 0x0003FFF
778
        out     dx, eax
779
        set_io  [ebx + device.io_addr], CSR15
780
        xor     eax, eax
781
        mov     al, 8
782
        out     dx, eax
783
        set_io  [ebx + device.io_addr], CSR13
784
        mov     al, 1
785
        out     dx, eax
786
        set_io  [ebx + device.io_addr], CSR12
787
        mov     ax, 0x1301
788
        out     dx, eax
3545 hidnplayr 789
 
5180 hidnplayr 790
  @@:
791
        cmp     [ebx + device.id], LC82C168
792
        jne     @f
793
        ;; TODO
794
  @@:
795
        cmp     [ebx + device.id], MX98713
796
        jne     @f
3545 hidnplayr 797
 
5180 hidnplayr 798
  @@:
799
;; wait a bit
800
;        mov     esi, 500
801
;        invoke  Sleep
3545 hidnplayr 802
 
5180 hidnplayr 803
; else:
804
        xor     eax, eax
805
        inc     eax
806
        call    select_media
3545 hidnplayr 807
 
5180 hidnplayr 808
; Start the chip's tx to process setup frame
809
        set_io  [ebx + device.io_addr], 0
810
        set_io  [ebx + device.io_addr], CSR6
811
        mov     eax, [ebx + device.csr6]
812
        out     dx, eax
813
        or      ax, CSR6_ST
814
        out     dx, eax
3545 hidnplayr 815
 
5180 hidnplayr 816
; Enable interrupts by setting the interrupt mask.
817
        set_io  [ebx + device.io_addr], CSR5
818
        mov     eax, [ebx + device.csr7]
819
        DEBUGF  1, "Setting CSR7 to 0x%x\n", eax
820
        out     dx, eax
821
        set_io  [ebx + device.io_addr], CSR7
822
        out     dx, eax
3545 hidnplayr 823
 
5180 hidnplayr 824
; Enable receiver
825
        set_io  [ebx + device.io_addr], CSR6
826
        mov     eax, [ebx + device.csr6]
827
        or      eax, 0x2002 + CSR6_RA
828
        out     dx, eax
3545 hidnplayr 829
 
5180 hidnplayr 830
; RX poll demand
831
        set_io  [ebx + device.io_addr], CSR2
3545 hidnplayr 832
        xor     eax, eax
5180 hidnplayr 833
        out     dx, eax
3545 hidnplayr 834
 
835
; Set the mtu, kernel will be able to send now
5046 hidnplayr 836
        mov     [ebx + device.mtu], 1514
3545 hidnplayr 837
 
838
; Set link state to unknown
5046 hidnplayr 839
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
3545 hidnplayr 840
 
5180 hidnplayr 841
        DEBUGF  1,"Reset completed\n"
842
;        xor     eax, eax
843
        ret
3545 hidnplayr 844
 
5180 hidnplayr 845
  .err:
846
        DEBUGF  2,"Reset failed\n"
847
        or      eax, -1
3545 hidnplayr 848
        ret
849
 
850
 
851
 
852
align 4
853
init_ring:
854
 
5180 hidnplayr 855
        DEBUGF  1,"Init ring\n"
3545 hidnplayr 856
 
5180 hidnplayr 857
;---------------------
858
; Setup RX descriptors
859
 
860
        lea     eax, [ebx + device.rx_ring]
5046 hidnplayr 861
        invoke  GetPhysAddr
3545 hidnplayr 862
        mov     edx, eax
863
        push    eax
5180 hidnplayr 864
        lea     edi, [ebx + device.rx_ring]
865
        mov     ecx, RX_RING_SIZE
3545 hidnplayr 866
  .loop_rx_des:
5180 hidnplayr 867
        DEBUGF  1,"RX descriptor 0x%x\n", edi
868
        add     edx, sizeof.desc
869
        mov     [edi + desc.status], DES0_OWN
5522 hidnplayr 870
        mov     [edi + desc.length], 1514
5180 hidnplayr 871
        push    edx edi ecx
5522 hidnplayr 872
        invoke  NetAlloc, 1514+NET_BUFF.data
5180 hidnplayr 873
        pop     ecx edi edx
874
        test    eax, eax
875
        jz      .out_of_mem
876
        mov     [edi + RX_RING_SIZE*sizeof.desc], eax
5522 hidnplayr 877
        push    edx
5180 hidnplayr 878
        invoke  GetPhysAddr
5522 hidnplayr 879
        add     eax, NET_BUFF.data
880
        pop     edx
5180 hidnplayr 881
        mov     [edi + desc.buffer1], eax
882
        mov     [edi + desc.buffer2], edx
883
        add     edi, sizeof.desc
3545 hidnplayr 884
        dec     ecx
885
        jnz     .loop_rx_des
5522 hidnplayr 886
 
3545 hidnplayr 887
; set last descriptor as LAST
5180 hidnplayr 888
        or      [edi - sizeof.desc + desc.length], RDES1_RER           ; EndOfRing
889
        pop     [edi - sizeof.desc + desc.buffer2]                     ; point it to the first descriptor
3545 hidnplayr 890
 
891
;---------------------
892
; Setup TX descriptors
893
 
5180 hidnplayr 894
        lea     eax, [ebx + device.tx_ring]
5046 hidnplayr 895
        invoke  GetPhysAddr
3545 hidnplayr 896
        mov     edx, eax
897
        push    eax
5180 hidnplayr 898
        lea     edi, [ebx + device.tx_ring]
899
        mov     ecx, TX_RING_SIZE
3545 hidnplayr 900
  .loop_tx_des:
5180 hidnplayr 901
        DEBUGF  1,"TX descriptor 0x%x\n", edi
902
        add     edx, sizeof.desc
903
        mov     [edi + desc.status], 0                                  ; owned by driver
904
        mov     [edi + desc.length], 0
905
        mov     [edi + desc.buffer1], 0
906
        mov     [edi + desc.buffer2], edx                               ; pointer to next descr
907
        add     edi, sizeof.desc
3545 hidnplayr 908
        dec     ecx
909
        jnz     .loop_tx_des
910
; set last descriptor as LAST
5180 hidnplayr 911
        or      [edi - sizeof.desc + desc.length], TDES1_TER            ; EndOfRing
912
        pop     [edi - sizeof.desc + desc.buffer2]                      ; point it to the first descriptor
3545 hidnplayr 913
 
914
;------------------
915
; Reset descriptors
916
 
5180 hidnplayr 917
        xor     eax, eax
918
        mov     [ebx + device.cur_tx], eax
919
        mov     [ebx + device.last_tx], eax
920
        mov     [ebx + device.cur_rx], eax
3545 hidnplayr 921
 
5522 hidnplayr 922
;        xor     eax, eax
3545 hidnplayr 923
        ret
924
 
5180 hidnplayr 925
  .out_of_mem:
926
        DEBUGF  2, "Out of memory!\n"
927
        pop     eax
928
        or      eax, -1
929
        ret
3545 hidnplayr 930
 
5180 hidnplayr 931
 
932
; IN: eax = startup
3545 hidnplayr 933
align 4
5180 hidnplayr 934
select_media:
935
 
936
        DEBUGF  1, "Selecting media\n"
937
 
938
        cmp     [ebx + device.mtable], 0
939
        je      .no_mtable
940
        DEBUGF  1, "Device has a media table\n"
941
 
942
 
943
; default:
944
        mov     eax, 0x020E0000
945
        jmp     .update_csr6
946
 
947
  .no_mtable:
948
        DEBUGF  1, "Device has no media table\n"
949
 
950
        cmp     [ebx + device.id], DC21041
951
        jne     .not_41
952
        DEBUGF  1, "DC21041\n"
953
 
954
        set_io  [ebx + device.io_addr], 0
955
        set_io  [ebx + device.io_addr], CSR13
956
        xor     eax, eax
957
        out     dx, eax         ; reset serial interface
958
        set_io  [ebx + device.io_addr], CSR14
959
        mov     eax, 0x7F3F     ;0x7F3F     ;0x7F3D     ; 10T-FD
960
        out     dx, eax
961
        set_io  [ebx + device.io_addr], CSR15
962
        mov     eax, 0x0008     ;0x0008     ;0x0008     ; 10T-FD
963
        out     dx, eax
964
        set_io  [ebx + device.io_addr], CSR13
965
        mov     eax, 0xEF05     ;0xEF01     ;0xEF09     ; 10T-FD
966
        out     dx, eax
967
        mov     eax, 0x80020000
968
        jmp     .update_csr6
969
  .not_41:
970
        cmp     [ebx + device.id], LC82C168
971
        jne     .not_LC
972
        DEBUGF  1, "LC82C168\n"
973
 
974
        ;; TODO
975
 
976
        mov     eax, 0x812C0000
977
        jmp     .update_csr6
978
  .not_LC:
979
        cmp     [ebx + device.id], DC21040
980
        jne     .not_40
981
        DEBUGF  1, "DC21040\n"
982
 
983
        set_io  [ebx + device.io_addr], 0
984
        set_io  [ebx + device.io_addr], CSR11
985
        mov     eax, FULL_DUPLEX_MAGIC
986
        out     dx, eax
987
        ; reset serial interface
988
        set_io  [ebx + device.io_addr], CSR13
989
        xor     eax, eax
990
        out     dx, eax
991
 
992
        set_io  [ebx + device.io_addr], CSR13
993
        xor     eax, eax
994
        cmp     [ebx + device.if_port], 0
995
        je      @f
996
        mov     al, 0xc
997
        out     dx, eax
998
        mov     eax, 0x01860000
999
        jmp     .update_csr6
1000
  @@:
1001
        mov     al, 4
1002
        out     dx, eax
1003
        mov     eax, 0x00420000
1004
        jmp     .update_csr6
1005
 
1006
  .not_40:
1007
        DEBUGF  1, "Unkown chip with no media table\n"
1008
 
1009
        cmp     [ebx + device.default_port], 0
1010
        jne     .not_0
1011
        cmp     [ebx + device.mii_cnt], 0
1012
        je      @f
1013
        mov     [ebx + device.if_port], 11
1014
        jmp     .not_0
1015
  @@:
1016
        mov     [ebx + device.if_port], 3
1017
  .not_0:
1018
        mov     eax, 0x020E0000 ;;;;;
1019
 
1020
  .update_csr6:
1021
        and     [ebx + device.csr6], 0xfdff
1022
        or      ax, 0x0200                     ;; FULL DUPLEX
1023
        or      [ebx + device.csr6], eax
1024
        DEBUGF  1, "new CSR6: 0x%x\n", [ebx + device.csr6]
1025
 
1026
        ret
1027
 
1028
 
1029
align 4
3545 hidnplayr 1030
start_link:
1031
 
3639 hidnplayr 1032
        DEBUGF  1,"Starting link\n"
1033
 
3545 hidnplayr 1034
        ; TODO: write working code here
1035
 
1036
        ret
1037
 
1038
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1039
;;                                         ;;
1040
;; Send setup packet                       ;;
1041
;;                                         ;;
1042
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1043
 
1044
align 4
5180 hidnplayr 1045
create_setup_frame:
3545 hidnplayr 1046
 
5180 hidnplayr 1047
        DEBUGF  1,"Creating setup packet\n"
3545 hidnplayr 1048
 
5522 hidnplayr 1049
        invoke  NetAlloc, 192 + NET_BUFF.data
5180 hidnplayr 1050
        test    eax, eax
1051
        jz      .err
5522 hidnplayr 1052
        mov     [eax + NET_BUFF.device], ebx
1053
        mov     [eax + NET_BUFF.length], 192
3545 hidnplayr 1054
 
5180 hidnplayr 1055
        push    eax
3545 hidnplayr 1056
 
5522 hidnplayr 1057
        lea     edi, [eax + NET_BUFF.data]
5180 hidnplayr 1058
        xor     eax, eax
1059
        dec     ax
1060
        stosd
1061
        stosd
1062
        stosd
3545 hidnplayr 1063
 
5180 hidnplayr 1064
        mov     ecx, 15
1065
  .loop:
5046 hidnplayr 1066
        lea     esi, [ebx + device.mac]
5180 hidnplayr 1067
        lodsw
1068
        stosd
3545 hidnplayr 1069
        dec     ecx
1070
        jnz     .loop
1071
 
5180 hidnplayr 1072
        pop     eax
3545 hidnplayr 1073
 
1074
; setup descriptor
5180 hidnplayr 1075
        lea     edi, [ebx + device.tx_ring]
1076
        DEBUGF  1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi
1077
        mov     [edi + TX_RING_SIZE*sizeof.desc], eax
1078
        invoke  GetPhysAddr
5522 hidnplayr 1079
        add     eax, NET_BUFF.data
5180 hidnplayr 1080
        mov     [edi + desc.buffer1], eax
5522 hidnplayr 1081
        mov     [edi + desc.length], TDES1_SET or 192       ; size must be EXACTLY 192 bytes + TDES1_IC
5180 hidnplayr 1082
        mov     [edi + desc.status], DES0_OWN
1083
        DEBUGF  1, "descriptor 0x%x\n", edi
3545 hidnplayr 1084
 
1085
; go to next descriptor
5180 hidnplayr 1086
        inc     [ebx + device.cur_tx]
5522 hidnplayr 1087
        and     [ebx + device.cur_tx], TX_RING_SIZE-1
3545 hidnplayr 1088
 
5522 hidnplayr 1089
        xor     eax, eax
5180 hidnplayr 1090
        ret
3545 hidnplayr 1091
 
5180 hidnplayr 1092
  .err:
1093
        DEBUGF  2, "Out of memory!\n"
5522 hidnplayr 1094
        or      eax, -1
3545 hidnplayr 1095
        ret
1096
 
1097
 
1098
 
1099
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1100
;;                                         ;;
1101
;; Transmit                                ;;
1102
;;                                         ;;
5522 hidnplayr 1103
;; In:  ebx = pointer to device structure  ;;
1104
;; Out: eax = 0 on success                 ;;
3545 hidnplayr 1105
;;                                         ;;
1106
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1107
 
5522 hidnplayr 1108
proc transmit stdcall bufferptr
3545 hidnplayr 1109
 
5046 hidnplayr 1110
        pushf
1111
        cli
1112
 
5522 hidnplayr 1113
        mov     esi, [bufferptr]
1114
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
1115
        lea     eax, [esi + NET_BUFF.data]
3545 hidnplayr 1116
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1117
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1118
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1119
        [eax+13]:2,[eax+12]:2
1120
 
5522 hidnplayr 1121
        cmp     [esi + NET_BUFF.length], 1514
3545 hidnplayr 1122
        ja      .fail
5522 hidnplayr 1123
        cmp     [esi + NET_BUFF.length], 60
1124
        jb      .fail
3545 hidnplayr 1125
 
5180 hidnplayr 1126
        mov     eax, [ebx + device.cur_tx]
1127
        mov     edx, sizeof.desc
3545 hidnplayr 1128
        mul     edx
5522 hidnplayr 1129
        lea     edi, [ebx + device.tx_ring + eax]
1130
        test    [edi + desc.status], DES0_OWN
5180 hidnplayr 1131
        jnz     .fail
3545 hidnplayr 1132
 
5180 hidnplayr 1133
        mov     eax, [bufferptr]
5522 hidnplayr 1134
        mov     [edi + TX_RING_SIZE*sizeof.desc], eax
1135
        add     eax, [eax + NET_BUFF.offset]
5180 hidnplayr 1136
        invoke  GetPhysAddr
5522 hidnplayr 1137
        mov     [edi + desc.buffer1], eax
5180 hidnplayr 1138
 
3545 hidnplayr 1139
; set packet size
5522 hidnplayr 1140
        mov     eax, [edi + desc.length]
5180 hidnplayr 1141
        and     eax, TDES1_TER                          ; preserve 'End of Ring' bit
5522 hidnplayr 1142
        or      eax, [esi + NET_BUFF.length]            ; set size
5180 hidnplayr 1143
        or      eax, TDES1_FS or TDES1_LS or TDES1_IC   ; first descr, last descr, interrupt on complete
5522 hidnplayr 1144
        mov     [edi + desc.length], eax
3545 hidnplayr 1145
 
5180 hidnplayr 1146
; set descriptor status
5522 hidnplayr 1147
        mov     [edi + desc.status], DES0_OWN            ; say it is now owned by the 21x4x
3545 hidnplayr 1148
 
5180 hidnplayr 1149
; Check if transmitter is running
5046 hidnplayr 1150
        set_io  [ebx + device.io_addr], 0
1151
        set_io  [ebx + device.io_addr], CSR6
3545 hidnplayr 1152
        in      eax, dx
5180 hidnplayr 1153
        test    eax, CSR6_ST                            ; if NOT started, start now
3545 hidnplayr 1154
        jnz     .already_started
1155
        or      eax, CSR6_ST
5180 hidnplayr 1156
        DEBUGF  1,"(Re) starting TX\n"
3545 hidnplayr 1157
        jmp     .do_it
1158
  .already_started:
5180 hidnplayr 1159
 
1160
; Trigger immediate transmit demand
5046 hidnplayr 1161
        set_io  [ebx + device.io_addr], CSR1
5180 hidnplayr 1162
        xor     eax, eax
3545 hidnplayr 1163
  .do_it:
5180 hidnplayr 1164
        out     dx, eax
3545 hidnplayr 1165
 
1166
; Update stats
5046 hidnplayr 1167
        inc     [ebx + device.packets_tx]
5522 hidnplayr 1168
        mov     ecx, [esi + NET_BUFF.length]
1169
        add     dword [ebx + device.bytes_tx], ecx
5046 hidnplayr 1170
        adc     dword [ebx + device.bytes_tx + 4], 0
3545 hidnplayr 1171
 
1172
; go to next descriptor
5180 hidnplayr 1173
        inc     [ebx + device.cur_tx]
1174
        and     [ebx + device.cur_tx], TX_RING_SIZE-1
3545 hidnplayr 1175
 
5180 hidnplayr 1176
        DEBUGF  1,"Transmit ok\n"
5046 hidnplayr 1177
        popf
3545 hidnplayr 1178
        xor     eax, eax
5046 hidnplayr 1179
        ret
3545 hidnplayr 1180
 
1181
  .fail:
5522 hidnplayr 1182
        DEBUGF  1,"Transmit failed\n"
1183
        invoke  NetFree, [bufferptr]
5046 hidnplayr 1184
        popf
3545 hidnplayr 1185
        or      eax, -1
5046 hidnplayr 1186
        ret
3545 hidnplayr 1187
 
5046 hidnplayr 1188
endp
3545 hidnplayr 1189
 
1190
;;;;;;;;;;;;;;;;;;;;;;;
1191
;;                   ;;
1192
;; Interrupt handler ;;
1193
;;                   ;;
1194
;;;;;;;;;;;;;;;;;;;;;;;
1195
 
1196
align 4
1197
int_handler:
1198
 
1199
        push    ebx esi edi
1200
 
5180 hidnplayr 1201
        DEBUGF  1,"INT\n"
3545 hidnplayr 1202
 
1203
; find pointer of device wich made IRQ occur
1204
 
1205
        mov     ecx, [devices]
1206
        test    ecx, ecx
1207
        jz      .nothing
1208
        mov     esi, device_list
1209
  .nextdevice:
1210
        mov     ebx, [esi]
1211
 
5046 hidnplayr 1212
        set_io  [ebx + device.io_addr], 0
1213
        set_io  [ebx + device.io_addr], CSR5
5180 hidnplayr 1214
        in      eax, dx
1215
        and     eax, 0x0001ffff
1216
        out     dx, eax                                 ; send it back to ACK
3545 hidnplayr 1217
        jnz     .got_it
1218
  .continue:
1219
        add     esi, 4
1220
        dec     ecx
1221
        jnz     .nextdevice
1222
  .nothing:
1223
        pop     edi esi ebx
1224
        xor     eax, eax
1225
 
1226
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1227
 
1228
  .got_it:
5180 hidnplayr 1229
        DEBUGF  1,"Device: %x CSR5: %x\n", ebx, eax
3545 hidnplayr 1230
 
1231
;----------------------------------
1232
; TX ok?
1233
 
5180 hidnplayr 1234
        test    eax, CSR5_TI
3545 hidnplayr 1235
        jz      .not_tx
1236
 
5180 hidnplayr 1237
        push    eax esi ecx
1238
        DEBUGF  1,"TX ok!\n"
1239
      .loop_tx:
5184 hidnplayr 1240
        ; get last descriptor
5180 hidnplayr 1241
        mov     eax, [ebx + device.last_tx]
1242
        mov     edx, sizeof.desc
3545 hidnplayr 1243
        mul     edx
5180 hidnplayr 1244
        lea     eax, [ebx + device.tx_ring + eax]
3545 hidnplayr 1245
 
5180 hidnplayr 1246
        DEBUGF  1,"descriptor 0x%x\n", eax
1247
        test    [eax + desc.status], DES0_OWN           ; owned by the card?
3545 hidnplayr 1248
        jnz     .end_tx
5180 hidnplayr 1249
        cmp     [eax + desc.buffer1], 0                 ; empty descriptor?
1250
        je      .end_tx
3545 hidnplayr 1251
 
5180 hidnplayr 1252
        mov     [eax + desc.buffer1], 0
5522 hidnplayr 1253
        DEBUGF  1, "Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc]
1254
        invoke  NetFree, [eax + TX_RING_SIZE*sizeof.desc]
3545 hidnplayr 1255
 
5184 hidnplayr 1256
        ; advance to next descriptor
5180 hidnplayr 1257
        inc     [ebx + device.last_tx]
1258
        and     [ebx + device.last_tx], TX_RING_SIZE-1
3545 hidnplayr 1259
 
1260
        jmp     .loop_tx
5180 hidnplayr 1261
  .end_tx:
1262
        pop     ecx esi eax
1263
  .not_tx:
3545 hidnplayr 1264
 
1265
;----------------------------------
1266
; RX irq
5180 hidnplayr 1267
        test    eax, CSR5_RI
3545 hidnplayr 1268
        jz      .not_rx
5180 hidnplayr 1269
        push    eax esi ecx
3545 hidnplayr 1270
 
1271
        DEBUGF 1,"RX ok!\n"
1272
 
1273
        push    ebx
1274
  .rx_loop:
1275
        pop     ebx
1276
 
5522 hidnplayr 1277
        ; get current descriptor
5180 hidnplayr 1278
        mov     eax, [ebx + device.cur_rx]
1279
        mov     edx, sizeof.desc
3545 hidnplayr 1280
        mul     edx
5180 hidnplayr 1281
        lea     edi, [ebx + device.rx_ring + eax]
3545 hidnplayr 1282
 
5522 hidnplayr 1283
        ; now check status
5180 hidnplayr 1284
        mov     eax, [edi + desc.status]
3545 hidnplayr 1285
 
1286
        test    eax, DES0_OWN
1287
        jnz     .end_rx                                 ; current desc is busy, nothing to do
1288
        test    eax, RDES0_FS
1289
        jz      .end_rx                                 ; current desc is NOT first packet, ERROR!
1290
        test    eax, RDES0_LS                           ; if not last desc of packet, error for now
1291
        jz      .end_rx
1292
        test    eax, RDES0_ES
1293
        jnz     .end_rx
1294
 
5184 hidnplayr 1295
; Calculate length
5180 hidnplayr 1296
        mov     ecx, [edi + desc.status]
3545 hidnplayr 1297
        shr     ecx, RDES0_FL_SH
1298
        and     ecx, RDES0_FL_MASK
5184 hidnplayr 1299
        sub     ecx, 4                                  ; throw away the CRC
1300
        DEBUGF  1,"got %u bytes\n", ecx
3545 hidnplayr 1301
 
5522 hidnplayr 1302
; Push arguments for EthInput (and some more...)
3545 hidnplayr 1303
        push    ebx
5184 hidnplayr 1304
        push    .rx_loop                                ; return addr
5522 hidnplayr 1305
        mov     eax, dword[edi + RX_RING_SIZE*sizeof.desc]
1306
        push    eax
1307
        mov     [eax + NET_BUFF.length], ecx
1308
        mov     [eax + NET_BUFF.device], ebx
1309
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
3545 hidnplayr 1310
 
1311
; update statistics
5046 hidnplayr 1312
        inc     [ebx + device.packets_rx]
5180 hidnplayr 1313
        add     dword[ebx + device.bytes_rx], ecx
1314
        adc     dword[ebx + device.bytes_rx + 4], 0
3545 hidnplayr 1315
 
5184 hidnplayr 1316
; Allocate new descriptor
1317
        push    edi ebx
5522 hidnplayr 1318
        invoke  NetAlloc, 1514 + NET_BUFF.data          ; Allocate a buffer to put packet into
5184 hidnplayr 1319
        pop     ebx edi
5522 hidnplayr 1320
        jz      .fail
5184 hidnplayr 1321
        mov     [edi + RX_RING_SIZE*sizeof.desc], eax
1322
        invoke  GetPhysAddr
5522 hidnplayr 1323
        add     eax, NET_BUFF.data
5184 hidnplayr 1324
        mov     [edi + desc.buffer1], eax
1325
        mov     [edi + desc.status], DES0_OWN           ; mark descriptor as being free
3545 hidnplayr 1326
 
5184 hidnplayr 1327
; Move to next rx desc
5180 hidnplayr 1328
        inc     [ebx + device.cur_rx]                   ; next descriptor
1329
        and     [ebx + device.cur_rx], RX_RING_SIZE-1
3545 hidnplayr 1330
 
5522 hidnplayr 1331
        jmp     [EthInput]
3545 hidnplayr 1332
  .end_rx:
5522 hidnplayr 1333
  .fail:
1334
        pop     ecx esi eax
3545 hidnplayr 1335
  .not_rx:
1336
 
1337
        pop     edi esi ebx
1338
        ret
1339
 
1340
 
1341
 
1342
align 4
1343
write_mac:      ; in: mac pushed onto stack (as 3 words)
1344
 
5180 hidnplayr 1345
        DEBUGF  1,"Writing MAC\n"
3545 hidnplayr 1346
 
1347
; write data into driver cache
1348
        mov     esi, esp
5046 hidnplayr 1349
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1350
        movsd
1351
        movsw
1352
        add     esp, 6
1353
 
5180 hidnplayr 1354
;; send setup packet (only if driver is started)
1355
;;        call    Create_Setup_Packet
3545 hidnplayr 1356
 
1357
align 4
1358
read_mac_eeprom:
1359
 
5180 hidnplayr 1360
        DEBUGF  1,"Reading MAC from eeprom\n"
3545 hidnplayr 1361
 
5046 hidnplayr 1362
        lea     edi, [ebx + device.mac]
3545 hidnplayr 1363
        mov     esi, 20/2               ; read words, start address is 20
1364
     .loop:
1365
        push    esi edi
1366
        call    SROM_Read_Word
1367
        pop     edi esi
1368
        stosw
1369
        inc     esi
1370
        cmp     esi, 26/2
1371
        jb      .loop
1372
 
5180 hidnplayr 1373
        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 1374
 
1375
        ret
1376
 
1377
 
1378
align 4
1379
SROM_GetWidth:  ; should be 6 or 8 according to some manuals (returns in ecx)
1380
 
5180 hidnplayr 1381
;        DEBUGF 1,"SROM_GetWidth\n"
3545 hidnplayr 1382
 
1383
        call    SROM_Idle
1384
        call    SROM_EnterAccessMode
1385
 
5046 hidnplayr 1386
;        set_io  [ebx + device.io_addr], 0
1387
;        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1388
 
1389
        ; send 110b
1390
 
1391
        in      eax, dx
1392
        or      eax, CSR9_SROM_DI
1393
        call    SROM_out
1394
 
1395
        in      eax, dx
1396
        or      eax, CSR9_SROM_DI
1397
        call    SROM_out
1398
 
1399
        in      eax, dx
1400
        and     eax, not (CSR9_SROM_DI)
1401
        call    SROM_out
1402
 
1403
        mov     ecx,1
1404
  .loop2:
1405
        Bit_Set CSR9_SROM_CK
1406
        SROM_Delay
1407
 
1408
        in      eax, dx
1409
        and     eax, CSR9_SROM_DO
1410
        jnz     .not_zero
1411
 
1412
        Bit_Clear CSR9_SROM_CK
1413
        SROM_Delay
1414
        jmp     .end_loop2
1415
  .not_zero:
1416
 
1417
        Bit_Clear CSR9_SROM_CK
1418
        SROM_Delay
1419
 
1420
        inc     ecx
1421
        cmp     ecx, 12
1422
        jbe     .loop2
1423
  .end_loop2:
1424
 
5180 hidnplayr 1425
        DEBUGF  1,"SROM width=%u\n", ecx
3545 hidnplayr 1426
 
1427
        call    SROM_Idle
1428
        call    SROM_EnterAccessMode
1429
        call    SROM_Idle
1430
 
1431
        ret
1432
 
1433
 
1434
align 4
1435
SROM_out:
1436
 
1437
        out     dx, eax
1438
        SROM_Delay
1439
        Bit_Set CSR9_SROM_CK
1440
        SROM_Delay
1441
        Bit_Clear CSR9_SROM_CK
1442
        SROM_Delay
1443
 
1444
        ret
1445
 
1446
 
1447
 
1448
align 4
1449
SROM_EnterAccessMode:
1450
 
5180 hidnplayr 1451
;        DEBUGF 1,"SROM_EnterAccessMode\n"
3545 hidnplayr 1452
 
5046 hidnplayr 1453
        set_io  [ebx + device.io_addr], 0
1454
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1455
        mov     eax, CSR9_SR
1456
        out     dx, eax
1457
        SROM_Delay
1458
 
1459
        Bit_Set CSR9_RD
1460
        SROM_Delay
1461
 
1462
        Bit_Clear CSR9_SROM_CK
1463
        SROM_Delay
1464
 
1465
        Bit_Set CSR9_SROM_CS
1466
        SROM_Delay
1467
 
1468
        ret
1469
 
1470
 
1471
 
1472
align 4
1473
SROM_Idle:
1474
 
5180 hidnplayr 1475
;        DEBUGF 1,"SROM_Idle\n"
3545 hidnplayr 1476
 
1477
        call    SROM_EnterAccessMode
1478
 
5046 hidnplayr 1479
;        set_io  [ebx + device.io_addr], 0
1480
;        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1481
 
1482
        mov     ecx, 25
1483
     .loop_clk:
1484
 
1485
        Bit_Clear CSR9_SROM_CK
1486
        SROM_Delay
1487
        Bit_Set CSR9_SROM_CK
1488
        SROM_Delay
1489
 
1490
        dec     ecx
1491
        jnz     .loop_clk
1492
 
1493
 
1494
        Bit_Clear CSR9_SROM_CK
1495
        SROM_Delay
1496
        Bit_Clear CSR9_SROM_CS
1497
        SROM_Delay
1498
 
1499
        xor     eax, eax
1500
        out     dx, eax
1501
 
1502
        ret
1503
 
1504
 
1505
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1506
;;                                                                      ;;
1507
;; Read serial EEprom word                                              ;;
1508
;;                                                                      ;;
1509
;; In: esi = read address                                               ;;
1510
;; OUT: ax = data word                                                  ;;
1511
;;                                                                      ;;
1512
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1513
align 4
1514
SROM_Read_Word:
1515
 
5180 hidnplayr 1516
;        DEBUGF 1,"SROM_Read_word at: %x\n", esi
3545 hidnplayr 1517
 
5046 hidnplayr 1518
        set_io  [ebx + device.io_addr], 0
1519
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1520
 
1521
; enter access mode
1522
        mov     eax, CSR9_SR + CSR9_RD
1523
        out     dx , eax
1524
        or      eax, CSR9_SROM_CS
1525
        out     dx , eax
1526
 
1527
        ; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
1528
 
1529
; send read command "110b" + address to read from
1530
        and     esi, 111111b
1531
        or      esi, 110b shl 6
1532
 
1533
        mov     ecx, 1 shl 9
1534
  .loop_cmd:
1535
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1536
        test    esi, ecx
1537
        jz      @f
1538
        or      eax, CSR9_SROM_DI
1539
       @@:
1540
        out     dx , eax
1541
        SROM_Delay
1542
        or      eax, CSR9_SROM_CK
1543
        out     dx , eax
1544
        SROM_Delay
1545
 
1546
        shr     ecx, 1
1547
        jnz     .loop_cmd
1548
 
1549
; read data from SROM
1550
 
1551
        xor     esi, esi
1552
        mov     ecx, 17 ;;; TODO: figure out why 17, not 16
1553
  .loop_read:
1554
 
1555
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
1556
        out     dx , eax
1557
        SROM_Delay
1558
 
1559
        in      eax, dx
1560
        and     eax, CSR9_SROM_DO
1561
        shr     eax, 3
1562
        shl     esi, 1
1563
        or      esi, eax
1564
 
1565
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1566
        out     dx , eax
1567
        SROM_Delay
1568
 
1569
        dec     ecx
1570
        jnz     .loop_read
1571
 
1572
        mov     eax, esi
1573
 
5180 hidnplayr 1574
;        DEBUGF 1,"%x\n", ax
3545 hidnplayr 1575
 
1576
        ret
1577
 
1578
 
1579
 
1580
;*********************************************************************
1581
;* Media Descriptor Code                                             *
1582
;*********************************************************************
1583
 
1584
; MII transceiver control section.
1585
; Read and write the MII registers using software-generated serial
1586
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1587
; for details.
1588
 
1589
; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
1590
; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
1591
; "overclocking" issues or future 66Mhz PCI.
1592
 
1593
; Read and write the MII registers using software-generated serial
1594
; MDIO protocol.  It is just different enough from the EEPROM protocol
1595
; to not share code.  The maxium data clock rate is 2.5 Mhz.
1596
 
5180 hidnplayr 1597
MDIO_SHIFT_CLK          = 0x10000
1598
MDIO_DATA_WRITE0        = 0x00000
1599
MDIO_DATA_WRITE1        = 0x20000
1600
MDIO_ENB                = 0x00000       ; Ignore the 0x02000 databook setting.
1601
MDIO_ENB_IN             = 0x40000
1602
MDIO_DATA_READ          = 0x80000
3545 hidnplayr 1603
 
1604
; MII transceiver control section.
1605
; Read and write the MII registers using software-generated serial
1606
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1607
; for details.
1608
 
1609
align 4
1610
mdio_read:      ; phy_id:edx, location:esi
1611
 
5180 hidnplayr 1612
        DEBUGF  1,"mdio read, phy=%x, location=%x\n", edx, esi
3545 hidnplayr 1613
 
1614
        shl     edx, 5
1615
        or      esi, edx
1616
        or      esi, 0xf6 shl 10
1617
 
5046 hidnplayr 1618
        set_io  [ebx + device.io_addr], 0
1619
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1620
 
1621
;    if (tp->chip_id == LC82C168) {
1622
;        int i = 1000;
1623
;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
1624
;        inl(ioaddr + 0xA0);
1625
;        inl(ioaddr + 0xA0);
1626
;        while (--i > 0)
1627
;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
1628
;                return retval & 0xffff;
1629
;        return 0xffff;
1630
;    }
1631
;
1632
;    if (tp->chip_id == COMET) {
1633
;        if (phy_id == 1) {
1634
;            if (location < 7)
1635
;                return inl(ioaddr + 0xB4 + (location<<2));
1636
;            else if (location == 17)
1637
;                return inl(ioaddr + 0xD0);
1638
;            else if (location >= 29 && location <= 31)
1639
;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
1640
;        }
1641
;        return 0xffff;
1642
;    }
1643
 
1644
; Establish sync by sending at least 32 logic ones.
1645
 
1646
        mov     ecx, 32
1647
  .loop:
1648
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1649
        out     dx, eax
1650
        MDIO_Delay
1651
 
1652
        or      eax, MDIO_SHIFT_CLK
1653
        out     dx, eax
1654
        MDIO_Delay
1655
 
1656
        dec     ecx
1657
        jnz     .loop
1658
 
1659
 
1660
; Shift the read command bits out.
1661
 
1662
        mov     ecx, 1 shl 15
1663
  .loop2:
1664
        mov     eax, MDIO_ENB
1665
        test    esi, ecx
1666
        jz      @f
1667
        or      eax, MDIO_DATA_WRITE1
1668
       @@:
1669
        out     dx, eax
1670
        MDIO_Delay
1671
 
1672
        or      eax, MDIO_SHIFT_CLK
1673
        out     dx, eax
1674
        MDIO_Delay
1675
 
1676
        shr     ecx, 1
1677
        jnz     .loop2
1678
 
1679
 
1680
; Read the two transition, 16 data, and wire-idle bits.
1681
 
1682
        xor     esi, esi
1683
        mov     ecx, 19
1684
  .loop3:
1685
        mov     eax, MDIO_ENB_IN
1686
        out     dx, eax
1687
        MDIO_Delay
1688
 
1689
        shl     esi, 1
1690
        in      eax, dx
1691
        test    eax, MDIO_DATA_READ
1692
        jz      @f
1693
        inc     esi
1694
       @@:
1695
 
1696
        mov     eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
1697
        out     dx, eax
1698
        MDIO_Delay
1699
 
1700
        dec     ecx
1701
        jnz     .loop3
1702
 
1703
        shr     esi, 1
1704
        movzx   eax, si
1705
 
5180 hidnplayr 1706
        DEBUGF  1,"data=%x\n", ax
3545 hidnplayr 1707
 
1708
        ret
1709
 
1710
 
1711
 
1712
 
1713
align 4
1714
mdio_write:     ;int phy_id: edx, int location: edi, int value: ax)
1715
 
1716
        DEBUGF  1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
1717
 
1718
        shl     edi, 18
1719
        or      edi, 0x5002 shl 16
1720
        shl     edx, 23
1721
        or      edi, edx
1722
        mov     di, ax
1723
 
5046 hidnplayr 1724
        set_io  [ebx + device.io_addr], 0
1725
        set_io  [ebx + device.io_addr], CSR9
3545 hidnplayr 1726
 
1727
;    if (tp->chip_id == LC82C168) {
1728
;        int i = 1000;
1729
;        outl(cmd, ioaddr + 0xA0);
1730
;        do
1731
;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
1732
;                break;
1733
;        while (--i > 0);
1734
;        return;
1735
;    }
1736
 
1737
;    if (tp->chip_id == COMET) {
1738
;        if (phy_id != 1)
1739
;            return;
1740
;        if (location < 7)
1741
;            outl(value, ioaddr + 0xB4 + (location<<2));
1742
;        else if (location == 17)
1743
;            outl(value, ioaddr + 0xD0);
1744
;        else if (location >= 29 && location <= 31)
1745
;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
1746
;        return;
1747
;    }
1748
 
1749
 
1750
; Establish sync by sending at least 32 logic ones.
1751
 
1752
        mov     ecx, 32
1753
  .loop:
1754
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1755
        out     dx, eax
1756
        MDIO_Delay
1757
 
1758
        or      eax, MDIO_SHIFT_CLK
1759
        out     dx, eax
1760
        MDIO_Delay
1761
 
1762
        dec     ecx
1763
        jnz     .loop
1764
 
1765
 
1766
; Shift the command bits out.
1767
 
1768
        mov     ecx, 1 shl 31
1769
  .loop2:
1770
        mov     eax, MDIO_ENB
1771
        test    edi, ecx
1772
        jz      @f
1773
        or      eax, MDIO_DATA_WRITE1
1774
       @@:
1775
        out     dx, eax
1776
        MDIO_Delay
1777
 
1778
        or      eax, MDIO_SHIFT_CLK
1779
        out     dx, eax
1780
        MDIO_Delay
1781
 
1782
        shr     ecx, 1
1783
        jnz     .loop2
1784
 
1785
 
1786
; Clear out extra bits.
1787
 
1788
        mov     ecx, 2
1789
  .loop3:
1790
        mov     eax, MDIO_ENB
1791
        out     dx, eax
1792
        MDIO_Delay
1793
 
1794
        or      eax, MDIO_SHIFT_CLK
1795
        out     dx, eax
1796
        MDIO_Delay
1797
 
1798
        dec     ecx
1799
        jnz     .loop3
1800
 
1801
        ret
1802
 
1803
 
5180 hidnplayr 1804
 
1805
 
1806
 
1807
 
3545 hidnplayr 1808
; End of code
1809
 
5046 hidnplayr 1810
data fixups
1811
end data
1812
 
1813
include '../peimport.inc'
1814
 
3545 hidnplayr 1815
my_service    db 'DEC21X4X',0                    ; max 16 chars include zero
1816
 
5180 hidnplayr 1817
chiplist:
1818
;   PCI id's , chip ,IO size, CSR7      , name  ,  flags
1819
dd 0x00021011, DC21040,  128, 0x0001ebef, sz_040,  0
1820
dd 0x00141011, DC21041,  128, 0x0001ebef, sz_041,  FLAG_HAS_MEDIA_TABLE
1821
dd 0x00091011, DC21140,  128, 0x0001ebef, sz_140,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
1822
dd 0x00191011, DC21143,  128, 0x0001ebef, sz_143,  FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_ALWAYS_CHECK_MII or FLAG_HAS_ACPI
1823
dd 0x000211AD, LC82C168, 256, 0x0801fbff, sz_lite, FLAG_HAS_MII
1824
dd 0x051210D9, MX98713,  128, 0x0001ebef, sz_m512, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE
1825
dd 0x053110D9, MX98715,  256, 0x0001ebef, sz_m513, FLAG_HAS_MEDIA_TABLE
1826
dd 0x1400125B, MX98725,  128, 0x0001fbff, sz_asix, FLAG_HAS_MII or FLAG_HAS_MEDIA_TABLE or FLAG_CSR12_IN_SROM
1827
dd 0
1828
 
1829
sz_040  db "Digital DC21040 Tulip", 0
1830
sz_041  db "Digital DC21041 Tulip", 0
1831
sz_140  db "Digital DS21140 Tulip", 0
1832
sz_143  db "Digital DS21143 Tulip", 0
1833
sz_lite db "Lite-On 82c168 PNIC", 0
1834
sz_m512 db "Macronix 98713 PMAC", 0
1835
sz_m513 db "Macronix 987x5 PMAC", 0
1836
sz_asix db "ASIX AX88140", 0
1837
 
3545 hidnplayr 1838
include_debug_strings                           ; All data wich FDO uses will be included here
1839
 
5046 hidnplayr 1840
align 4
1841
devices         dd 0
5180 hidnplayr 1842
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling