Subversion Repositories Kolibri OS

Rev

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