Subversion Repositories Kolibri OS

Rev

Rev 3205 | 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.get_MAC], read_mac
413
        mov     [device.set_MAC], write_mac
414
        mov     [device.unload], unload
415
        mov     [device.name], my_service
1502 hidnplayr 416
 
417
; save the pci bus and device numbers
418
 
2544 hidnplayr 419
        mov     eax, [IOCTL.input]
3205 hidnplayr 420
        movzx   ecx, byte[eax+1]
421
        mov     [device.pci_bus], ecx
422
        movzx   ecx, byte[eax+2]
423
        mov     [device.pci_dev], ecx
1502 hidnplayr 424
 
425
; Now, it's time to find the base io addres of the PCI device
426
 
3205 hidnplayr 427
        PCI_find_io
1502 hidnplayr 428
 
429
; We've found the io address, find IRQ now
430
 
3205 hidnplayr 431
        PCI_find_irq
1502 hidnplayr 432
 
2544 hidnplayr 433
        DEBUGF  2,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
434
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:8
1502 hidnplayr 435
 
2544 hidnplayr 436
        allocate_and_clear [device.rx_p_des], RX_DES_COUNT*(DES.size+RX_BUFF_SIZE), .err
437
        allocate_and_clear [device.tx_p_des], TX_DES_COUNT*(DES.size+TX_BUFF_SIZE), .err
1502 hidnplayr 438
 
439
; Ok, the eth_device structure is ready, let's probe the device
440
; Because initialization fires IRQ, IRQ handler must be aware of this device
2544 hidnplayr 441
        mov     eax, [devices]                                          ; Add the device structure to our device list
442
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
443
        inc     [devices]                                               ;
1502 hidnplayr 444
 
2544 hidnplayr 445
        call    probe                                                   ; this function will output in eax
446
        test    eax, eax
447
        jnz     .err2                                                   ; If an error occured, exit
1502 hidnplayr 448
 
1514 hidnplayr 449
 
2544 hidnplayr 450
        mov     [device.type], NET_TYPE_ETH
451
        call    NetRegDev
1514 hidnplayr 452
 
2544 hidnplayr 453
        cmp     eax, -1
454
        je      .destroy
1502 hidnplayr 455
 
2544 hidnplayr 456
        ret
1502 hidnplayr 457
 
458
; If the device was already loaded, find the device number and return it in eax
459
 
460
  .find_devicenum:
2544 hidnplayr 461
        DEBUGF  2,"Trying to find device number of already registered device\n"
462
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
463
                                                                        ; into a device number in edi
464
        mov     eax, edi                                                ; Application wants it in eax instead
465
        DEBUGF  2,"Kernel says: %u\n", eax
466
        ret
1502 hidnplayr 467
 
468
; If an error occured, remove all allocated data and exit (returning -1 in eax)
469
 
470
  .destroy:
2544 hidnplayr 471
        ; todo: reset device into virgin state
1502 hidnplayr 472
 
473
  .err2:
2544 hidnplayr 474
        dec     [devices]
1502 hidnplayr 475
  .err:
2544 hidnplayr 476
        DEBUGF  2,"removing device structure\n"
477
        stdcall KernelFree, [device.rx_p_des]
478
        stdcall KernelFree, [device.tx_p_des]
479
        stdcall KernelFree, ebx
1502 hidnplayr 480
 
481
 
482
  .fail:
2544 hidnplayr 483
        or      eax, -1
484
        ret
1502 hidnplayr 485
 
486
;------------------------------------------------------
487
endp
488
 
489
 
490
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
491
;;                                                                        ;;
492
;;        Actual Hardware dependent code starts here                      ;;
493
;;                                                                        ;;
494
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
495
 
496
 
497
 
498
align 4
499
unload:
2544 hidnplayr 500
        ; TODO: (in this particular order)
501
        ;
502
        ; - Stop the device
503
        ; - Detach int handler
504
        ; - Remove device from local list (RTL8139_LIST)
505
        ; - call unregister function in kernel
506
        ; - Remove all allocated structures and buffers the card used
1502 hidnplayr 507
 
2544 hidnplayr 508
        or      eax,-1
1502 hidnplayr 509
 
510
ret
511
 
512
 
513
macro status {
2544 hidnplayr 514
        set_io  CSR5
515
        in      eax, dx
516
        DEBUGF  1,"CSR5: %x\n", eax
1502 hidnplayr 517
}
518
 
519
 
520
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
521
;;                                         ;;
522
;; Probe                                   ;;
523
;;                                         ;;
524
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
525
 
526
align 4
527
probe:
528
 
2544 hidnplayr 529
        DEBUGF  2,"Probing dec21x4x device: "
1502 hidnplayr 530
 
3205 hidnplayr 531
        PCI_make_bus_master
1502 hidnplayr 532
 
3205 hidnplayr 533
        stdcall PciRead32, [device.pci_bus], [device.pci_dev], 0                                ; get device/vendor id
2544 hidnplayr 534
        DEBUGF  1,"Vendor id: 0x%x\n", ax
1502 hidnplayr 535
 
2923 hidnplayr 536
        cmp     ax, 0x1011
3231 hidnplayr 537
        je      .dec
538
        cmp     ax, 0x1317
539
        je      .admtek
540
        jmp     .notfound
541
 
542
  .dec:
2544 hidnplayr 543
        shr     eax, 16
544
        DEBUGF  1,"Vendor ok!, device id: 0x%x\n", ax                 ; TODO: use another method to detect chip!
1502 hidnplayr 545
 
2923 hidnplayr 546
        cmp     ax, 0x0009
2544 hidnplayr 547
        je      .supported_device
1502 hidnplayr 548
 
2923 hidnplayr 549
        cmp     ax, 0x0019
2544 hidnplayr 550
        je      .supported_device2
1502 hidnplayr 551
 
3231 hidnplayr 552
  .admtek:
553
        shr     eax, 16
554
        DEBUGF  1,"Vendor ok!, device id: 0x%x\n", ax
555
 
556
        cmp     ax, 0x0985
557
        je      .supported_device
558
 
1502 hidnplayr 559
  .notfound:
2544 hidnplayr 560
        DEBUGF  1,"Device not supported!\n"
561
        or      eax, -1
562
        ret
1502 hidnplayr 563
 
564
  .supported_device2:
565
 
2544 hidnplayr 566
        ; wake up the 21143
1502 hidnplayr 567
 
2544 hidnplayr 568
        xor     eax, eax
3205 hidnplayr 569
        stdcall PciWrite32, [device.pci_bus], [device.pci_dev], 0x40, eax
1502 hidnplayr 570
 
571
 
572
  .supported_device:
2544 hidnplayr 573
        call    SROM_GetWidth           ; TODO: use this value returned in ecx
574
                                        ; in the read_word routine!
1502 hidnplayr 575
 
576
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
577
;;                                         ;;
578
;; Reset                                   ;;
579
;;                                         ;;
580
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
581
 
582
align 4
583
reset:
584
 
2544 hidnplayr 585
        DEBUGF  2,"Resetting dec21x4x\n"
1502 hidnplayr 586
 
587
;-----------------------------------------------------------
588
; board software reset - if fails, dont do nothing else
589
 
2544 hidnplayr 590
        set_io  0
591
        status
592
        set_io  CSR0
593
        mov     eax, CSR0_RESET
3201 hidnplayr 594
        out     dx, eax
1502 hidnplayr 595
 
596
; wait at least 50 PCI cycles
2544 hidnplayr 597
        mov     esi, 1000
598
        call    Sleep
1502 hidnplayr 599
 
600
;-----------
601
; setup CSR0
602
 
2544 hidnplayr 603
        set_io  0
604
        status
605
        set_io  CSR0
606
        mov     eax, CSR0_DEFAULT
3201 hidnplayr 607
        out     dx, eax
1502 hidnplayr 608
 
609
 
610
; wait at least 50 PCI cycles
2544 hidnplayr 611
        mov     esi, 1000
612
        call    Sleep
1502 hidnplayr 613
 
614
;-----------------------------------
615
; Read mac from eeprom to driver ram
616
 
2544 hidnplayr 617
        call    read_mac_eeprom
1502 hidnplayr 618
 
619
;--------------------------------
620
; insert irq handler on given irq
621
 
2544 hidnplayr 622
        movzx   eax, [device.irq_line]
623
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
624
        stdcall AttachIntHandler, eax, int_handler, dword 0
625
        test    eax, eax
626
        jnz     @f
627
        DEBUGF  1,"\nCould not attach int handler!\n"
1502 hidnplayr 628
;        or      eax, -1
629
;        ret
630
  @@:
631
 
2544 hidnplayr 632
        set_io  0
633
        status
1502 hidnplayr 634
 
3201 hidnplayr 635
        call    init_ring
1502 hidnplayr 636
 
637
;--------------------------------------------
638
; setup CSR3 & CSR4 (pointers to descriptors)
639
 
2544 hidnplayr 640
        set_io  0
641
        status
642
        set_io  CSR3
643
        mov     eax, [device.rx_p_des]
3201 hidnplayr 644
        GetRealAddr
2544 hidnplayr 645
        DEBUGF  1,"RX descriptor base address: %x\n", eax
3201 hidnplayr 646
        out     dx, eax
1502 hidnplayr 647
 
2544 hidnplayr 648
        set_io  CSR4
649
        mov     eax, [device.tx_p_des]
3201 hidnplayr 650
        GetRealAddr
2544 hidnplayr 651
        DEBUGF  1,"TX descriptor base address: %x\n", eax
3201 hidnplayr 652
        out     dx, eax
1502 hidnplayr 653
 
654
;-------------------------------------------------------
655
; setup interrupt mask register -expect IRQs from now on
656
 
2544 hidnplayr 657
        status
658
        DEBUGF  1,"Enabling interrupts\n"
659
        set_io  CSR7
660
        mov     eax, CSR7_DEFAULT
3201 hidnplayr 661
        out     dx, eax
2544 hidnplayr 662
        status
1502 hidnplayr 663
 
664
;----------
665
; enable RX
666
 
2544 hidnplayr 667
        set_io  0
668
        status
669
        DEBUGF  1,"Enable RX\n"
1502 hidnplayr 670
 
2544 hidnplayr 671
        set_io  CSR6
672
        Bit_Set CSR6_SR; or CSR6_PR or CSR6_ST
673
        DEBUGF  1,"CSR6: %x\n", eax
1502 hidnplayr 674
 
2544 hidnplayr 675
        status
1502 hidnplayr 676
 
2544 hidnplayr 677
        call    start_link
1502 hidnplayr 678
 
679
; wait a bit
2544 hidnplayr 680
        mov     esi, 3000
681
        call    Sleep
1502 hidnplayr 682
 
683
;----------------------------------------------------
684
; send setup packet to notify the board about the MAC
685
 
2544 hidnplayr 686
        call    Send_Setup_Packet
1502 hidnplayr 687
 
2544 hidnplayr 688
        xor     eax, eax
1503 hidnplayr 689
; clear packet/byte counters
1502 hidnplayr 690
 
2544 hidnplayr 691
        lea     edi, [device.bytes_tx]
692
        mov     ecx, 6
693
        rep     stosd
1503 hidnplayr 694
 
1519 hidnplayr 695
; Set the mtu, kernel will be able to send now
2544 hidnplayr 696
        mov     [device.mtu], 1514
1519 hidnplayr 697
 
2544 hidnplayr 698
        DEBUGF  1,"Reset done\n"
1502 hidnplayr 699
 
2544 hidnplayr 700
        ret
1502 hidnplayr 701
 
1503 hidnplayr 702
 
3201 hidnplayr 703
 
1503 hidnplayr 704
align 4
3201 hidnplayr 705
init_ring:
706
 
707
;------------------------------------------
708
; Setup RX descriptors (use chained method)
709
 
710
        mov     eax, [device.rx_p_des]
711
        GetRealAddr
712
        mov     edx, eax
713
        push    eax
714
        lea     esi, [eax + RX_DES_COUNT*(DES.size)]    ; jump over RX descriptors
715
        mov     eax, [device.rx_p_des]
716
        add     eax, RX_DES_COUNT*(DES.size)            ; jump over RX descriptors
717
        mov     edi, [device.rx_p_des]
718
        mov     ecx, RX_DES_COUNT
719
  .loop_rx_des:
720
        add     edx, DES.size
721
        mov     [edi + DES.status], DES0_OWN            ; hardware owns buffer
722
        mov     [edi + DES.length], 1984 + RDES1_RCH    ; only size of first buffer, chained buffers
723
        mov     [edi + DES.buffer1], esi                ; hw buffer address
724
        mov     [edi + DES.buffer2], edx                ; pointer to next descriptor
725
        mov     [edi + DES.virtaddr], eax               ; virtual buffer address
726
        DEBUGF  1,"RX desc: buff addr: %x, next desc: %x, real buff addr: %x, real descr addr: %x \n", esi, edx, eax, edi
727
 
728
        add     esi, RX_BUFF_SIZE
729
        add     eax, RX_BUFF_SIZE
730
        add     edi, DES.size
731
        dec     ecx
732
        jnz     .loop_rx_des
733
 
734
; set last descriptor as LAST
735
        sub     edi, DES.size
736
        or      [edi + DES.length], RDES1_RER           ; EndOfRing
737
        pop     [edi + DES.buffer2]                     ; point it to the first descriptor
738
 
739
;---------------------
740
; Setup TX descriptors
741
 
742
        mov     eax, [device.tx_p_des]
743
        GetRealAddr
744
        mov     edx, eax
745
        push    eax
746
        lea     esi, [eax + TX_DES_COUNT*(DES.size)]    ; jump over TX descriptors
747
        mov     eax, [device.tx_p_des]
748
        add     eax, TX_DES_COUNT*(DES.size)            ; jump over TX descriptors
749
        mov     edi, [device.tx_p_des]
750
        mov     ecx, TX_DES_COUNT
751
  .loop_tx_des:
752
        add     edx, DES.size
753
        mov     [edi + DES.status], 0                   ; owned by driver
754
        mov     [edi + DES.length], TDES1_TCH           ; chained method
755
        mov     [edi + DES.buffer1], esi                ; pointer to buffer
756
        mov     [edi + DES.buffer2], edx                ; pointer to next descr
757
        mov     [edi + DES.virtaddr], eax
758
        DEBUGF  1,"TX desc: buff addr: %x, next desc: %x, virt buff addr: %x, virt descr addr: %x \n", esi, edx, eax, edi
759
 
760
        add     esi, TX_BUFF_SIZE
761
        add     eax, TX_BUFF_SIZE
762
        add     edi, DES.size
763
        dec     ecx
764
        jnz     .loop_tx_des
765
 
766
; set last descriptor as LAST
767
        sub     edi, DES.size
768
        or      [edi + DES.length], TDES1_TER           ; EndOfRing
769
        pop     [edi + DES.buffer2]                     ; point it to the first descriptor
770
 
771
;------------------
772
; Reset descriptors
773
 
774
        mov     [device.tx_wr_des], 0
775
        mov     [device.tx_rd_des], 0
776
        mov     [device.rx_crt_des], 0
777
        mov     [device.tx_free_des], TX_DES_COUNT
778
 
779
        ret
780
 
781
 
782
align 4
1503 hidnplayr 783
start_link:
784
 
2544 hidnplayr 785
        ; TODO: write working code here
1503 hidnplayr 786
 
2544 hidnplayr 787
        ret
1503 hidnplayr 788
 
1502 hidnplayr 789
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
790
;;                                         ;;
791
;; Send setup packet                       ;;
792
;;                                         ;;
793
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
794
 
795
align 4
796
Send_Setup_Packet:
797
 
2544 hidnplayr 798
        DEBUGF  1,"Sending setup packet\n"
1502 hidnplayr 799
 
800
; if no descriptors available, out
2544 hidnplayr 801
        mov     ecx, 1000
1502 hidnplayr 802
@@loop_wait_desc:
2544 hidnplayr 803
        cmp     [device.tx_free_des], 0
804
        jne     @f
1502 hidnplayr 805
 
2544 hidnplayr 806
        dec     ecx
807
        jnz     @@loop_wait_desc
1502 hidnplayr 808
 
2544 hidnplayr 809
        mov     eax, -1
810
        ret
1502 hidnplayr 811
      @@:
812
 
813
; go to current send descriptor
2544 hidnplayr 814
        mov     edi, [device.tx_p_des]
815
        mov     eax, [device.tx_wr_des]
816
        DEBUGF  1,"Got free descriptor: %u (%x)", eax, edi
817
        mov     edx, DES.size
818
        mul     edx
819
        add     edi, eax
820
        DEBUGF  1,"=>%x\n",  edi
1502 hidnplayr 821
 
822
; if NOT sending FIRST setup packet, must set current descriptor to 0 size for both buffers,
823
;  and go to next descriptor for real setup packet...            ;; TODO: check if 2 descriptors are available
824
 
825
;       cmp     [device.tx_packets], 0
3201 hidnplayr 826
;       je      .first
1502 hidnplayr 827
;
828
;       and     [edi+DES.des1], 0
829
;       mov     [edi+DES.des0], DES0_OWN
830
;
831
; go to next descriptor
832
;        inc     [device.tx_wr_des]
833
;        and     [device.tx_wr_des], TX_DES_COUNT-1
834
;
835
; dec free descriptors count
836
;        cmp     [device.tx_free_des], 0
837
;        jz      @f
838
;        dec     [device.tx_free_des]
839
;       @@:
840
;
841
;       ; recompute pointer to current descriptor
842
;       mov     edi, [device.tx_p_des]
843
;       mov     eax, [device.tx_wr_des]
844
;       mov     edx, DES.size
845
;       mul     edx
846
;       add     edi, eax
847
 
3201 hidnplayr 848
  .first:
1502 hidnplayr 849
 
2544 hidnplayr 850
        push    edi
1502 hidnplayr 851
; copy setup packet to current descriptor
3201 hidnplayr 852
        mov     edi, [edi + DES.virtaddr]
853
; copy the address once
2544 hidnplayr 854
        lea     esi, [device.mac]
855
        DEBUGF  1,"copying packet to %x from %x\n", edi, esi
856
        mov     ecx, 3  ; mac is 6 bytes thus 3 words
3201 hidnplayr 857
  .loop:
2544 hidnplayr 858
        DEBUGF  1,"%x ", [esi]:4
859
        movsw
3201 hidnplayr 860
        inc     edi
861
        inc     edi
2544 hidnplayr 862
        dec     ecx
863
        jnz     .loop
1502 hidnplayr 864
 
2544 hidnplayr 865
        DEBUGF  1,"\n"
1502 hidnplayr 866
 
867
; copy 15 times the broadcast address
2544 hidnplayr 868
        mov     ecx, 3*15
869
        mov     eax, 0xffffffff
870
        rep     stosd
1502 hidnplayr 871
 
2544 hidnplayr 872
        pop     edi
1502 hidnplayr 873
 
874
; setup descriptor
2544 hidnplayr 875
        DEBUGF  1,"setting up descriptor\n"
3201 hidnplayr 876
        mov     [edi + DES.length], TDES1_IC + TDES1_SET + TDES1_TCH + 192        ; size must be EXACTLY 192 bytes
877
        mov     [edi + DES.status], DES0_OWN
1502 hidnplayr 878
 
3201 hidnplayr 879
        DEBUGF  1,"status: %x\n", [edi + DES.status]:8
880
        DEBUGF  1,"length: %x\n", [edi + DES.length]:8
881
        DEBUGF  1,"buffer1: %x\n", [edi + DES.buffer1]:8
882
        DEBUGF  1,"buffer2: %x\n", [edi + DES.buffer2]:8
1502 hidnplayr 883
 
884
; go to next descriptor
2544 hidnplayr 885
        inc     [device.tx_wr_des]
886
        and     [device.tx_wr_des], TX_DES_COUNT-1
1502 hidnplayr 887
 
888
; dec free descriptors count
2544 hidnplayr 889
        cmp     [device.tx_free_des], 0
890
        jz      @f
891
        dec     [device.tx_free_des]
1502 hidnplayr 892
       @@:
893
 
894
; start tx
2544 hidnplayr 895
        set_io  0
896
        status
897
        set_io  CSR6
898
        in      eax, dx
899
        test    eax, CSR6_ST            ; if NOT started, start now
900
        jnz     .already_started
901
        or      eax, CSR6_ST
902
        DEBUGF  1,"Starting TX\n"
903
        jmp     .do_it
1502 hidnplayr 904
  .already_started:
2544 hidnplayr 905
                                        ; if already started, issue a Transmit Poll command
906
        set_io  CSR1
3201 hidnplayr 907
        xor     eax, eax
2544 hidnplayr 908
        DEBUGF  1,"Issuing transmit poll command\n"
1502 hidnplayr 909
  .do_it:
3201 hidnplayr 910
        out     dx, eax
2544 hidnplayr 911
        status
1502 hidnplayr 912
 
2544 hidnplayr 913
        DEBUGF  1,"Sending setup packet, completed!\n"
1502 hidnplayr 914
 
2544 hidnplayr 915
        ret
1502 hidnplayr 916
 
917
 
918
 
919
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
920
;;                                         ;;
921
;; Transmit                                ;;
922
;;                                         ;;
923
;; In: buffer pointer in [esp+4]           ;;
924
;;     size of buffer in [esp+8]           ;;
925
;;     pointer to device structure in ebx  ;;
926
;;                                         ;;
927
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
928
 
929
align 4
930
transmit:
931
 
2544 hidnplayr 932
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8]
933
        mov     eax, [esp+4]
934
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
935
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
936
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
937
        [eax+13]:2,[eax+12]:2
1502 hidnplayr 938
 
2544 hidnplayr 939
        cmp     dword [esp+8], MAX_ETH_FRAME_SIZE
940
        ja      .fail
1502 hidnplayr 941
 
2544 hidnplayr 942
        cmp     [device.tx_free_des], 0
943
        je      .fail
1502 hidnplayr 944
 
945
;--------------------------
946
; copy packet to crt buffer
2544 hidnplayr 947
 
948
        mov     eax, [device.tx_wr_des]
949
        mov     edx, DES.size
950
        mul     edx
951
        add     eax, [device.tx_p_des]
3201 hidnplayr 952
        mov     edi, [eax + DES.virtaddr]                 ; pointer to buffer
2544 hidnplayr 953
        mov     esi, [esp+4]
954
        mov     ecx, [esp+8]
955
        DEBUGF  1,"copying %u bytes from %x to %x\n", ecx, esi, edi
956
        rep     movsb
1502 hidnplayr 957
 
958
; set packet size
3201 hidnplayr 959
        mov     ecx, [eax+DES.length]
2544 hidnplayr 960
        and     ecx, TDES1_TER                          ; preserve 'End of Ring' bit
961
        or      ecx, [esp+8]                            ; set size
962
        or      ecx, TDES1_FS or TDES1_LS or TDES1_IC or TDES1_TCH    ; first descr, last descr, interrupt on complete, chained modus
3201 hidnplayr 963
        mov     [eax+DES.length], ecx
1502 hidnplayr 964
 
965
; set descriptor info
3201 hidnplayr 966
        mov     [eax+DES.status], DES0_OWN                ; say it is now owned by the 21x4x
1502 hidnplayr 967
 
968
; start tx
2544 hidnplayr 969
        set_io  0
970
        status
971
        set_io  CSR6
972
        in      eax, dx
973
        test    eax, CSR6_ST            ; if NOT started, start now
974
        jnz     .already_started
975
        or      eax, CSR6_ST
976
        DEBUGF  1,"Starting TX\n"
977
        jmp     .do_it
1502 hidnplayr 978
  .already_started:
2544 hidnplayr 979
                                        ; if already started, issues a Transmit Poll command
980
        set_io  CSR1
981
        mov     eax, -1
1502 hidnplayr 982
  .do_it:
2544 hidnplayr 983
        out     dx , eax
1502 hidnplayr 984
 
1503 hidnplayr 985
; Update stats
1502 hidnplayr 986
 
2544 hidnplayr 987
        inc     [device.packets_tx]
988
        mov     eax, [esp+8]
989
        add     dword [device.bytes_tx], eax
990
        adc     dword [device.bytes_tx + 4], 0
1502 hidnplayr 991
 
992
; go to next descriptor
2544 hidnplayr 993
        inc     [device.tx_wr_des]
994
        and     [device.tx_wr_des], TX_DES_COUNT-1
1502 hidnplayr 995
 
996
; dec free descriptors count
2544 hidnplayr 997
        test    [device.tx_free_des], -1
998
        jz      .end
999
        dec     [device.tx_free_des]
1502 hidnplayr 1000
  .end:
2544 hidnplayr 1001
        status
1502 hidnplayr 1002
 
2544 hidnplayr 1003
        DEBUGF  1,"transmit ok\n"
1004
        xor     eax, eax
1005
        stdcall KernelFree, [esp+4]
1006
        ret     8
1502 hidnplayr 1007
 
1008
  .fail:
2544 hidnplayr 1009
        DEBUGF  1,"transmit failed\n"
1010
        or      eax, -1
1011
        stdcall KernelFree, [esp+4]
1012
        ret     8
1502 hidnplayr 1013
 
1014
 
1015
;;;;;;;;;;;;;;;;;;;;;;;
1016
;;                   ;;
1017
;; Interrupt handler ;;
1018
;;                   ;;
1019
;;;;;;;;;;;;;;;;;;;;;;;
1020
 
1021
align 4
1022
int_handler:
1023
 
2935 hidnplayr 1024
        DEBUGF  1,"\n%s int\n", my_service
1502 hidnplayr 1025
 
1026
; find pointer of device wich made IRQ occur
1027
 
2544 hidnplayr 1028
        mov     ecx, [devices]
1029
        test    ecx, ecx
2935 hidnplayr 1030
        jz      .nothing
2544 hidnplayr 1031
        mov     esi, device_list
1502 hidnplayr 1032
  .nextdevice:
2935 hidnplayr 1033
        mov     ebx, [esi]
1502 hidnplayr 1034
 
2544 hidnplayr 1035
        set_io  0
1036
        set_io  CSR5
1037
        in      eax, dx
2935 hidnplayr 1038
        out     dx, eax                                 ; send it back to ACK
2544 hidnplayr 1039
        test    eax, eax
1040
        jnz     .got_it
1502 hidnplayr 1041
  .continue:
2544 hidnplayr 1042
        add     esi, 4
1043
        dec     ecx
1044
        jnz     .nextdevice
2935 hidnplayr 1045
  .nothing:
2544 hidnplayr 1046
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1502 hidnplayr 1047
 
1048
  .got_it:
1049
 
2935 hidnplayr 1050
        DEBUGF  1,"Device: %x CSR5: %x ", ebx, ax
1502 hidnplayr 1051
 
1052
;----------------------------------
1053
; TX ok?
1054
 
3201 hidnplayr 1055
        test    ax, CSR5_TI
2544 hidnplayr 1056
        jz      .not_tx
1057
        push    ax esi ecx
1502 hidnplayr 1058
 
2544 hidnplayr 1059
        DEBUGF 1,"TX ok!\n"
1060
 
1061
        ; go to current descriptor
1062
        mov     edi, [device.tx_p_des]
1502 hidnplayr 1063
 
2544 hidnplayr 1064
        mov     eax, [device.tx_rd_des]
1065
        mov     edx, DES.size
1066
        mul     edx
1067
        add     edi, eax
1068
 
1502 hidnplayr 1069
      .loop_tx:
2544 hidnplayr 1070
 
1071
        ; done if all desc are free
1072
        cmp     [device.tx_free_des], TX_DES_COUNT
1073
        jz      .end_tx
1502 hidnplayr 1074
 
3201 hidnplayr 1075
        mov     eax, [edi+DES.status]
1502 hidnplayr 1076
 
2544 hidnplayr 1077
        ; we stop at first desc that is owned be NIC
1078
        test    eax, DES0_OWN
1079
        jnz     .end_tx
1502 hidnplayr 1080
 
2544 hidnplayr 1081
        ; detect is setup packet
1082
        cmp     eax, (0ffffffffh - DES0_OWN)            ; all other bits are 1
1083
        jne     .not_setup_packet
1084
        DEBUGF  1,"Setup Packet detected\n"
1502 hidnplayr 1085
      .not_setup_packet:
1086
 
2544 hidnplayr 1087
        DEBUGF  1,"packet status: %x\n", eax
1502 hidnplayr 1088
 
2544 hidnplayr 1089
        ; next descriptor
1090
        add     edi, DES.size
1091
        inc     [device.tx_rd_des]
1092
        and     [device.tx_rd_des], TX_DES_COUNT-1
1502 hidnplayr 1093
 
2544 hidnplayr 1094
        ; inc free desc
1095
        inc     [device.tx_free_des]
1096
        cmp     [device.tx_free_des], TX_DES_COUNT
3155 hidnplayr 1097
        jbe     @f
2544 hidnplayr 1098
        mov     [device.tx_free_des], TX_DES_COUNT
1502 hidnplayr 1099
       @@:
1100
 
2544 hidnplayr 1101
        jmp     .loop_tx
1502 hidnplayr 1102
      .end_tx:
2544 hidnplayr 1103
 
1104
        ;------------------------------------------------------
1105
        ; here must be called standard Ethernet Tx Irq Handler
1106
        ;------------------------------------------------------
1502 hidnplayr 1107
 
2544 hidnplayr 1108
        pop     ecx esi ax
1502 hidnplayr 1109
 
1110
;----------------------------------
1111
; RX irq
1112
  .not_tx:
3201 hidnplayr 1113
        test    ax, CSR5_RI
2544 hidnplayr 1114
        jz      .not_rx
1115
        push    ax esi ecx
1502 hidnplayr 1116
 
2544 hidnplayr 1117
        DEBUGF 1,"RX ok!\n"
3201 hidnplayr 1118
 
1119
        push    ebx
1120
  .rx_loop:
1121
        pop     ebx
1122
 
1123
        ; get current descriptor
2544 hidnplayr 1124
        mov     edi, [device.rx_p_des]
1125
        mov     eax, [device.rx_crt_des]
1126
        mov     edx, DES.size
1127
        mul     edx
1128
        add     edi, eax
1502 hidnplayr 1129
 
3201 hidnplayr 1130
        ; now check status
1131
        mov     eax, [edi + DES.status]
1132
 
2544 hidnplayr 1133
        test    eax, DES0_OWN
1134
        jnz     .end_rx                                 ; current desc is busy, nothing to do
1502 hidnplayr 1135
 
2544 hidnplayr 1136
        test    eax, RDES0_FS
1137
        jz      .end_rx                                 ; current desc is NOT first packet, ERROR!
1502 hidnplayr 1138
 
2544 hidnplayr 1139
        test    eax, RDES0_LS                           ; if not last desc of packet, error for now
1140
        jz      .end_rx
1502 hidnplayr 1141
 
2544 hidnplayr 1142
        test    eax, RDES0_ES
1143
        jnz     .end_rx
1502 hidnplayr 1144
 
3201 hidnplayr 1145
        mov     esi, [edi + DES.virtaddr]
1146
        mov     ecx, [edi + DES.status]
2544 hidnplayr 1147
        shr     ecx, RDES0_FL_SH
1148
        and     ecx, RDES0_FL_MASK
3201 hidnplayr 1149
        sub     ecx, 4                                  ; crc, we dont need it
1502 hidnplayr 1150
 
2544 hidnplayr 1151
        DEBUGF  1,"Received packet!, size=%u, addr:%x\n", ecx, esi
1502 hidnplayr 1152
 
2544 hidnplayr 1153
        push    esi edi ecx
3201 hidnplayr 1154
        stdcall KernelAlloc, ecx                        ; Allocate a buffer to put packet into
2544 hidnplayr 1155
        pop     ecx edi esi
1156
        test    eax, eax
1157
        jz      .fail
1502 hidnplayr 1158
 
3201 hidnplayr 1159
        push    ebx
1160
        push    dword .rx_loop
2544 hidnplayr 1161
        push    ecx eax
1162
        mov     edi, eax
1502 hidnplayr 1163
 
1164
; update statistics
2544 hidnplayr 1165
        inc     [device.packets_rx]
1166
        add     dword [device.bytes_rx], ecx
1167
        adc     dword [device.bytes_rx + 4], 0
1502 hidnplayr 1168
 
1169
; copy packet data
2544 hidnplayr 1170
        shr     cx , 1
1171
        jnc     .nb
1172
        movsb
1502 hidnplayr 1173
  .nb:
2544 hidnplayr 1174
        shr     cx , 1
1175
        jnc     .nw
1176
        movsw
1502 hidnplayr 1177
  .nw:
2544 hidnplayr 1178
        rep     movsd
1502 hidnplayr 1179
 
3201 hidnplayr 1180
        mov     [edi + DES.status], DES0_OWN            ; free descriptor
2544 hidnplayr 1181
 
3201 hidnplayr 1182
        inc     [device.rx_crt_des]                     ; next descriptor
2544 hidnplayr 1183
        and     [device.rx_crt_des], RX_DES_COUNT-1
1502 hidnplayr 1184
 
3201 hidnplayr 1185
        jmp     Eth_input
1502 hidnplayr 1186
 
3201 hidnplayr 1187
  .end_rx:
1188
  .fail:
2544 hidnplayr 1189
        pop     ecx esi ax
3201 hidnplayr 1190
  .not_rx:
1502 hidnplayr 1191
 
2544 hidnplayr 1192
        jmp     .continue
1502 hidnplayr 1193
 
1194
 
1195
 
1196
align 4
2544 hidnplayr 1197
write_mac:      ; in: mac pushed onto stack (as 3 words)
1502 hidnplayr 1198
 
2544 hidnplayr 1199
        DEBUGF  2,"Writing MAC: "
1502 hidnplayr 1200
 
1201
; write data into driver cache
2544 hidnplayr 1202
        mov     esi, esp
1203
        lea     edi, [device.mac]
1204
        movsd
1205
        movsw
1206
        add     esp, 6
1207
 
1502 hidnplayr 1208
; send setup packet (only if driver is started)
2544 hidnplayr 1209
        call    Send_Setup_Packet
1502 hidnplayr 1210
 
1211
align 4
1212
read_mac:
1213
 
2544 hidnplayr 1214
        DEBUGF 1,"Read_mac\n"
1502 hidnplayr 1215
 
2544 hidnplayr 1216
        ret
1502 hidnplayr 1217
 
1218
 
1219
 
1220
align 4
1221
read_mac_eeprom:
1222
 
2544 hidnplayr 1223
        DEBUGF 1,"Read_mac_eeprom\n"
1502 hidnplayr 1224
 
2544 hidnplayr 1225
        lea     edi, [device.mac]
1226
        mov     esi, 20/2               ; read words, start address is 20
1502 hidnplayr 1227
     .loop:
2544 hidnplayr 1228
        push    esi edi
1229
        call    SROM_Read_Word
1230
        pop     edi esi
1231
        stosw
1232
        inc     esi
1233
        cmp     esi, 26/2
3155 hidnplayr 1234
        jb      .loop
1502 hidnplayr 1235
 
2544 hidnplayr 1236
        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 1237
 
2544 hidnplayr 1238
        ret
1502 hidnplayr 1239
 
1240
align 4
1241
write_mac_eeprom:
1242
 
2544 hidnplayr 1243
        DEBUGF 1,"Write_mac_eeprom\n"
1502 hidnplayr 1244
 
2544 hidnplayr 1245
        ret
1502 hidnplayr 1246
 
1247
 
1248
align 4
2544 hidnplayr 1249
SROM_GetWidth:  ; should be 6 or 8 according to some manuals (returns in ecx)
1502 hidnplayr 1250
 
2544 hidnplayr 1251
        DEBUGF 1,"SROM_GetWidth\n"
1502 hidnplayr 1252
 
2544 hidnplayr 1253
        call    SROM_Idle
1254
        call    SROM_EnterAccessMode
1502 hidnplayr 1255
 
1256
;        set_io  0
1257
;        set_io  CSR9
1258
 
2544 hidnplayr 1259
        ; send 110b
1502 hidnplayr 1260
 
2544 hidnplayr 1261
        in      eax, dx
1262
        or      eax, CSR9_SROM_DI
1263
        call    SROM_out
1502 hidnplayr 1264
 
2544 hidnplayr 1265
        in      eax, dx
1266
        or      eax, CSR9_SROM_DI
1267
        call    SROM_out
1502 hidnplayr 1268
 
2544 hidnplayr 1269
        in      eax, dx
1270
        and     eax, not (CSR9_SROM_DI)
1271
        call    SROM_out
1272
 
1273
        mov     ecx,1
1502 hidnplayr 1274
  .loop2:
2544 hidnplayr 1275
        Bit_Set CSR9_SROM_CK
1276
        SROM_Delay
1277
 
1278
        in      eax, dx
1279
        and     eax, CSR9_SROM_DO
1280
        jnz     .not_zero
1502 hidnplayr 1281
 
2544 hidnplayr 1282
        Bit_Clear CSR9_SROM_CK
1283
        SROM_Delay
1284
        jmp     .end_loop2
1502 hidnplayr 1285
  .not_zero:
2544 hidnplayr 1286
 
1287
        Bit_Clear CSR9_SROM_CK
1288
        SROM_Delay
1289
 
1290
        inc     ecx
1291
        cmp     ecx, 12
3155 hidnplayr 1292
        jbe     .loop2
1502 hidnplayr 1293
  .end_loop2:
2544 hidnplayr 1294
 
1295
        DEBUGF 1,"Srom width=%u\n", ecx
1296
 
1297
        call    SROM_Idle
1298
        call    SROM_EnterAccessMode
1299
        call    SROM_Idle
1300
 
1301
        ret
1502 hidnplayr 1302
 
1303
 
1304
align 4
1305
SROM_out:
1306
 
2544 hidnplayr 1307
        out     dx, eax
1308
        SROM_Delay
1309
        Bit_Set CSR9_SROM_CK
1310
        SROM_Delay
1311
        Bit_Clear CSR9_SROM_CK
1312
        SROM_Delay
1502 hidnplayr 1313
 
2544 hidnplayr 1314
        ret
1502 hidnplayr 1315
 
1316
 
1317
 
1318
align 4
1319
SROM_EnterAccessMode:
1320
 
2544 hidnplayr 1321
        DEBUGF 1,"SROM_EnterAccessMode\n"
1502 hidnplayr 1322
 
2544 hidnplayr 1323
        set_io  0
1324
        set_io  CSR9
1325
        mov     eax, CSR9_SR
1326
        out     dx, eax
1327
        SROM_Delay
1502 hidnplayr 1328
 
2544 hidnplayr 1329
        Bit_Set CSR9_RD
1330
        SROM_Delay
1502 hidnplayr 1331
 
2544 hidnplayr 1332
        Bit_Clear CSR9_SROM_CK
1333
        SROM_Delay
1502 hidnplayr 1334
 
2544 hidnplayr 1335
        Bit_Set CSR9_SROM_CS
1336
        SROM_Delay
1337
 
1338
        ret
1502 hidnplayr 1339
 
1340
 
1341
 
1342
align 4
1343
SROM_Idle:
1344
 
2544 hidnplayr 1345
        DEBUGF 1,"SROM_Idle\n"
1502 hidnplayr 1346
 
2544 hidnplayr 1347
        call    SROM_EnterAccessMode
1348
 
1502 hidnplayr 1349
;        set_io  0
1350
;        set_io  CSR9
2544 hidnplayr 1351
 
1352
        mov     ecx, 25
1502 hidnplayr 1353
     .loop_clk:
1354
 
2544 hidnplayr 1355
        Bit_Clear CSR9_SROM_CK
1356
        SROM_Delay
1357
        Bit_Set CSR9_SROM_CK
1358
        SROM_Delay
1359
 
1360
        dec     ecx
1361
        jnz     .loop_clk
1502 hidnplayr 1362
 
2544 hidnplayr 1363
 
1364
        Bit_Clear CSR9_SROM_CK
1365
        SROM_Delay
1366
        Bit_Clear CSR9_SROM_CS
1367
        SROM_Delay
1368
 
1369
        xor     eax, eax
1370
        out     dx, eax
1371
 
1372
        ret
1502 hidnplayr 1373
 
1374
 
1375
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1376
;;                                                                      ;;
1377
;; Read serial EEprom word                                              ;;
1378
;;                                                                      ;;
1379
;; In: esi = read address                                               ;;
1380
;; OUT: ax = data word                                                  ;;
1381
;;                                                                      ;;
1382
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1383
align 4
1384
SROM_Read_Word:
1385
 
2544 hidnplayr 1386
        DEBUGF 1,"SROM_Read_word at: %x result: ", esi
1502 hidnplayr 1387
 
2544 hidnplayr 1388
        set_io  0
1389
        set_io  CSR9
1502 hidnplayr 1390
 
1391
; enter access mode
2544 hidnplayr 1392
        mov     eax, CSR9_SR + CSR9_RD
1393
        out     dx , eax
1394
        or      eax, CSR9_SROM_CS
1395
        out     dx , eax
1502 hidnplayr 1396
 
2544 hidnplayr 1397
        ; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
1398
 
1502 hidnplayr 1399
; send read command "110b" + address to read from
2544 hidnplayr 1400
        and     esi, 111111b
1401
        or      esi, 110b shl 6
1402
 
1403
        mov     ecx, 1 shl 9
1502 hidnplayr 1404
  .loop_cmd:
2544 hidnplayr 1405
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1406
        test    esi, ecx
1407
        jz      @f
1408
        or      eax, CSR9_SROM_DI
1502 hidnplayr 1409
       @@:
2544 hidnplayr 1410
        out     dx , eax
1411
        SROM_Delay
1412
        or      eax, CSR9_SROM_CK
1413
        out     dx , eax
1414
        SROM_Delay
1415
 
1416
        shr     ecx, 1
1417
        jnz     .loop_cmd
1502 hidnplayr 1418
 
1419
; read data from SROM
1420
 
2544 hidnplayr 1421
        xor     esi, esi
1422
        mov     ecx, 17 ;;; TODO: figure out why 17, not 16
1502 hidnplayr 1423
  .loop_read:
2544 hidnplayr 1424
 
1425
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
1426
        out     dx , eax
1427
        SROM_Delay
1428
 
1429
        in      eax, dx
1430
        and     eax, CSR9_SROM_DO
1431
        shr     eax, 3
1432
        shl     esi, 1
1433
        or      esi, eax
1434
 
1435
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1436
        out     dx , eax
1437
        SROM_Delay
1438
 
1439
        dec     ecx
1440
        jnz     .loop_read
1441
 
1442
        mov     eax, esi
1502 hidnplayr 1443
 
2544 hidnplayr 1444
        DEBUGF 1,"%x\n", ax
1502 hidnplayr 1445
 
2544 hidnplayr 1446
        ret
1502 hidnplayr 1447
 
1448
 
1503 hidnplayr 1449
 
1450
 
1451
 
1452
 
1453
 
1454
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1455
 
1456
 
1457
 
1458
;*********************************************************************
1459
;* Media Descriptor Code                                             *
1460
;*********************************************************************
1461
 
1462
; MII transceiver control section.
1463
; Read and write the MII registers using software-generated serial
1464
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1465
; for details.
1466
 
1467
; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
1468
; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
1469
; "overclocking" issues or future 66Mhz PCI.
1470
 
1471
; Read and write the MII registers using software-generated serial
1472
; MDIO protocol.  It is just different enough from the EEPROM protocol
1473
; to not share code.  The maxium data clock rate is 2.5 Mhz.
1474
 
2852 hidnplayr 1475
MDIO_SHIFT_CLK          =        0x10000
1476
MDIO_DATA_WRITE0        =        0x00000
1477
MDIO_DATA_WRITE1        =        0x20000
1478
MDIO_ENB                =        0x00000         ; Ignore the 0x02000 databook setting.
1479
MDIO_ENB_IN             =        0x40000
1480
MDIO_DATA_READ          =        0x80000
1503 hidnplayr 1481
 
1482
; MII transceiver control section.
1483
; Read and write the MII registers using software-generated serial
1484
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1485
; for details.
1486
 
1487
align 4
2544 hidnplayr 1488
mdio_read:      ; phy_id:edx, location:esi
1503 hidnplayr 1489
 
2544 hidnplayr 1490
        DEBUGF  1,"mdio read, phy=%x, location=%x", edx, esi
1503 hidnplayr 1491
 
2544 hidnplayr 1492
        shl     edx, 5
1493
        or      esi, edx
1494
        or      esi, 0xf6 shl 10
1503 hidnplayr 1495
 
2544 hidnplayr 1496
        set_io  0
1497
        set_io  CSR9
1503 hidnplayr 1498
 
1499
;    if (tp->chip_id == LC82C168) {
1500
;        int i = 1000;
1501
;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
1502
;        inl(ioaddr + 0xA0);
1503
;        inl(ioaddr + 0xA0);
1504
;        while (--i > 0)
1505
;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
1506
;                return retval & 0xffff;
1507
;        return 0xffff;
1508
;    }
1509
;
1510
;    if (tp->chip_id == COMET) {
1511
;        if (phy_id == 1) {
1512
;            if (location < 7)
1513
;                return inl(ioaddr + 0xB4 + (location<<2));
1514
;            else if (location == 17)
1515
;                return inl(ioaddr + 0xD0);
1516
;            else if (location >= 29 && location <= 31)
1517
;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
1518
;        }
1519
;        return 0xffff;
1520
;    }
1521
 
1522
; Establish sync by sending at least 32 logic ones.
1523
 
2544 hidnplayr 1524
        mov     ecx, 32
1503 hidnplayr 1525
  .loop:
2544 hidnplayr 1526
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1527
        out     dx, eax
1528
        MDIO_Delay
1503 hidnplayr 1529
 
2544 hidnplayr 1530
        or      eax, MDIO_SHIFT_CLK
1531
        out     dx, eax
1532
        MDIO_Delay
1503 hidnplayr 1533
 
2544 hidnplayr 1534
        dec     ecx
1535
        jnz     .loop
1503 hidnplayr 1536
 
1537
 
1538
; Shift the read command bits out.
1539
 
2544 hidnplayr 1540
        mov     ecx, 1 shl 15
1503 hidnplayr 1541
  .loop2:
2544 hidnplayr 1542
        mov     eax, MDIO_ENB
1543
        test    esi, ecx
1544
        jz      @f
1545
        or      eax, MDIO_DATA_WRITE1
1503 hidnplayr 1546
       @@:
2544 hidnplayr 1547
        out     dx, eax
1548
        MDIO_Delay
1503 hidnplayr 1549
 
2544 hidnplayr 1550
        or      eax, MDIO_SHIFT_CLK
1551
        out     dx, eax
1552
        MDIO_Delay
1503 hidnplayr 1553
 
2544 hidnplayr 1554
        shr     ecx, 1
1555
        jnz     .loop2
1503 hidnplayr 1556
 
1557
 
1558
; Read the two transition, 16 data, and wire-idle bits.
1559
 
2544 hidnplayr 1560
        xor     esi, esi
1561
        mov     ecx, 19
1503 hidnplayr 1562
  .loop3:
2544 hidnplayr 1563
        mov     eax, MDIO_ENB_IN
1564
        out     dx, eax
1565
        MDIO_Delay
1503 hidnplayr 1566
 
2544 hidnplayr 1567
        shl     esi, 1
1568
        in      eax, dx
1569
        test    eax, MDIO_DATA_READ
1570
        jz      @f
1571
        inc     esi
1503 hidnplayr 1572
       @@:
1573
 
2544 hidnplayr 1574
        mov     eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
1575
        out     dx, eax
1576
        MDIO_Delay
1503 hidnplayr 1577
 
2544 hidnplayr 1578
        dec     ecx
1579
        jnz     .loop3
1503 hidnplayr 1580
 
2544 hidnplayr 1581
        shr     esi, 1
1582
        movzx   eax, si
1503 hidnplayr 1583
 
2544 hidnplayr 1584
        DEBUGF  1,", data=%x\n", ax
1503 hidnplayr 1585
 
2544 hidnplayr 1586
        ret
1503 hidnplayr 1587
 
1588
 
1589
 
1590
 
1591
align 4
2544 hidnplayr 1592
mdio_write:     ;int phy_id: edx, int location: edi, int value: ax)
1503 hidnplayr 1593
 
2544 hidnplayr 1594
        DEBUGF  1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
1503 hidnplayr 1595
 
2544 hidnplayr 1596
        shl     edi, 18
1597
        or      edi, 0x5002 shl 16
1598
        shl     edx, 23
1599
        or      edi, edx
1600
        mov     di, ax
1503 hidnplayr 1601
 
2544 hidnplayr 1602
        set_io  0
1603
        set_io  CSR9
1503 hidnplayr 1604
 
1605
;    if (tp->chip_id == LC82C168) {
1606
;        int i = 1000;
1607
;        outl(cmd, ioaddr + 0xA0);
1608
;        do
1609
;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
1610
;                break;
1611
;        while (--i > 0);
1612
;        return;
1613
;    }
1614
 
1615
;    if (tp->chip_id == COMET) {
1616
;        if (phy_id != 1)
1617
;            return;
1618
;        if (location < 7)
1619
;            outl(value, ioaddr + 0xB4 + (location<<2));
1620
;        else if (location == 17)
1621
;            outl(value, ioaddr + 0xD0);
1622
;        else if (location >= 29 && location <= 31)
1623
;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
1624
;        return;
1625
;    }
1626
 
1627
 
1628
; Establish sync by sending at least 32 logic ones.
1629
 
2544 hidnplayr 1630
        mov     ecx, 32
1503 hidnplayr 1631
  .loop:
2544 hidnplayr 1632
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1633
        out     dx, eax
1634
        MDIO_Delay
1503 hidnplayr 1635
 
2544 hidnplayr 1636
        or      eax, MDIO_SHIFT_CLK
1637
        out     dx, eax
1638
        MDIO_Delay
1503 hidnplayr 1639
 
2544 hidnplayr 1640
        dec     ecx
1641
        jnz     .loop
1503 hidnplayr 1642
 
1643
 
1644
; Shift the command bits out.
1645
 
2544 hidnplayr 1646
        mov     ecx, 1 shl 31
1503 hidnplayr 1647
  .loop2:
2544 hidnplayr 1648
        mov     eax, MDIO_ENB
1649
        test    edi, ecx
1650
        jz      @f
1651
        or      eax, MDIO_DATA_WRITE1
1503 hidnplayr 1652
       @@:
2544 hidnplayr 1653
        out     dx, eax
1654
        MDIO_Delay
1503 hidnplayr 1655
 
2544 hidnplayr 1656
        or      eax, MDIO_SHIFT_CLK
1657
        out     dx, eax
1658
        MDIO_Delay
1503 hidnplayr 1659
 
2544 hidnplayr 1660
        shr     ecx, 1
1661
        jnz     .loop2
1503 hidnplayr 1662
 
1663
 
1664
; Clear out extra bits.
1665
 
2544 hidnplayr 1666
        mov     ecx, 2
1503 hidnplayr 1667
  .loop3:
2544 hidnplayr 1668
        mov     eax, MDIO_ENB
1669
        out     dx, eax
1670
        MDIO_Delay
1503 hidnplayr 1671
 
2544 hidnplayr 1672
        or      eax, MDIO_SHIFT_CLK
1673
        out     dx, eax
1674
        MDIO_Delay
1503 hidnplayr 1675
 
2544 hidnplayr 1676
        dec     ecx
1677
        jnz     .loop3
1503 hidnplayr 1678
 
2544 hidnplayr 1679
        ret
1503 hidnplayr 1680
 
1681
 
1502 hidnplayr 1682
; End of code
2544 hidnplayr 1683
align 4                                         ; Place all initialised data here
1502 hidnplayr 1684
 
1685
devices       dd 0
1519 hidnplayr 1686
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
2544 hidnplayr 1687
my_service    db 'DEC21X4X',0                    ; max 16 chars include zero
1502 hidnplayr 1688
 
2544 hidnplayr 1689
include_debug_strings                           ; All data wich FDO uses will be included here
1502 hidnplayr 1690
 
1691
section '.data' data readable writable align 16 ; place all uninitialized data place here
1692
 
2544 hidnplayr 1693
device_list rd MAX_DEVICES                     ; This list contains all pointers to device structures the driver is handling
1502 hidnplayr 1694
 
1695