Subversion Repositories Kolibri OS

Rev

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

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