Subversion Repositories Kolibri OS

Rev

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

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