Subversion Repositories Kolibri OS

Rev

Rev 2935 | 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
 
2923 hidnplayr 323
        DEBUGF  2,"Loading %s driver\n", my_service
2544 hidnplayr 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
 
2923 hidnplayr 533
        cmp     ax, 0x1011
2544 hidnplayr 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
 
2923 hidnplayr 539
        cmp     ax, 0x0009
2544 hidnplayr 540
        je      .supported_device
1502 hidnplayr 541
 
2923 hidnplayr 542
        cmp     ax, 0x0019
2544 hidnplayr 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
2923 hidnplayr 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
2923 hidnplayr 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
 
2923 hidnplayr 674
        push    edx
1502 hidnplayr 675
  .loop_tx_des:
2544 hidnplayr 676
        add     edx, DES.size
2923 hidnplayr 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
2923 hidnplayr 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"
2923 hidnplayr 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
 
2923 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
 
2935 hidnplayr 1015
        DEBUGF  1,"\n%s int\n", my_service
1502 hidnplayr 1016
 
1017
; find pointer of device wich made IRQ occur
1018
 
2544 hidnplayr 1019
        mov     ecx, [devices]
1020
        test    ecx, ecx
2935 hidnplayr 1021
        jz      .nothing
2544 hidnplayr 1022
        mov     esi, device_list
1502 hidnplayr 1023
  .nextdevice:
2935 hidnplayr 1024
        mov     ebx, [esi]
1502 hidnplayr 1025
 
2544 hidnplayr 1026
        set_io  0
1027
        set_io  CSR5
1028
        in      eax, dx
2935 hidnplayr 1029
        out     dx, eax                                 ; send it back to ACK
2544 hidnplayr 1030
        test    eax, eax
1031
        jnz     .got_it
1502 hidnplayr 1032
  .continue:
2544 hidnplayr 1033
        add     esi, 4
1034
        dec     ecx
1035
        jnz     .nextdevice
2935 hidnplayr 1036
  .nothing:
2544 hidnplayr 1037
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1502 hidnplayr 1038
 
1039
  .got_it:
1040
 
2935 hidnplayr 1041
        DEBUGF  1,"Device: %x CSR5: %x ", ebx, ax
1502 hidnplayr 1042
 
1043
;----------------------------------
1044
; TX ok?
1045
 
2544 hidnplayr 1046
        test    eax, CSR5_TI
1047
        jz      .not_tx
1048
        push    ax esi ecx
1502 hidnplayr 1049
 
2544 hidnplayr 1050
        DEBUGF 1,"TX ok!\n"
1051
 
1052
        ; go to current descriptor
1053
        mov     edi, [device.tx_p_des]
1502 hidnplayr 1054
 
2544 hidnplayr 1055
        mov     eax, [device.tx_rd_des]
1056
        mov     edx, DES.size
1057
        mul     edx
1058
        add     edi, eax
1059
 
1502 hidnplayr 1060
      .loop_tx:
2544 hidnplayr 1061
 
1062
        ; done if all desc are free
1063
        cmp     [device.tx_free_des], TX_DES_COUNT
1064
        jz      .end_tx
1502 hidnplayr 1065
 
2544 hidnplayr 1066
        mov     eax, [edi+DES.DES0]
1502 hidnplayr 1067
 
2544 hidnplayr 1068
        ; we stop at first desc that is owned be NIC
1069
        test    eax, DES0_OWN
1070
        jnz     .end_tx
1502 hidnplayr 1071
 
2544 hidnplayr 1072
        ; detect is setup packet
1073
        cmp     eax, (0ffffffffh - DES0_OWN)            ; all other bits are 1
1074
        jne     .not_setup_packet
1075
        DEBUGF  1,"Setup Packet detected\n"
1502 hidnplayr 1076
      .not_setup_packet:
1077
 
2544 hidnplayr 1078
        DEBUGF  1,"packet status: %x\n", eax
1502 hidnplayr 1079
 
2544 hidnplayr 1080
        ; next descriptor
1081
        add     edi, DES.size
1082
        inc     [device.tx_rd_des]
1083
        and     [device.tx_rd_des], TX_DES_COUNT-1
1502 hidnplayr 1084
 
2544 hidnplayr 1085
        ; inc free desc
1086
        inc     [device.tx_free_des]
1087
        cmp     [device.tx_free_des], TX_DES_COUNT
1088
        jle     @f
1089
        mov     [device.tx_free_des], TX_DES_COUNT
1502 hidnplayr 1090
       @@:
1091
 
2544 hidnplayr 1092
        jmp     .loop_tx
1502 hidnplayr 1093
      .end_tx:
2544 hidnplayr 1094
 
1095
        ;------------------------------------------------------
1096
        ; here must be called standard Ethernet Tx Irq Handler
1097
        ;------------------------------------------------------
1502 hidnplayr 1098
 
2544 hidnplayr 1099
        pop     ecx esi ax
1502 hidnplayr 1100
 
1101
;----------------------------------
1102
; RX irq
1103
  .not_tx:
2544 hidnplayr 1104
        test    eax, CSR5_RI
1105
        jz      .not_rx
1106
        push    ax esi ecx
1502 hidnplayr 1107
 
2544 hidnplayr 1108
        DEBUGF 1,"RX ok!\n"
1109
 
1110
        ;go to current descriptor
1111
        mov     edi, [device.rx_p_des]
1502 hidnplayr 1112
 
2544 hidnplayr 1113
        mov     eax, [device.rx_crt_des]
1114
        mov     edx, DES.size
1115
        mul     edx
1116
        add     edi, eax
1117
 
1502 hidnplayr 1118
      .loop_rx_start_of_packet:
2544 hidnplayr 1119
        mov     eax, [edi+DES.DES0]
1502 hidnplayr 1120
 
2544 hidnplayr 1121
        test    eax, DES0_OWN
1122
        jnz     .end_rx                                 ; current desc is busy, nothing to do
1502 hidnplayr 1123
 
2544 hidnplayr 1124
        test    eax, RDES0_FS
1125
        jz      .end_rx                                 ; current desc is NOT first packet, ERROR!
1502 hidnplayr 1126
 
2544 hidnplayr 1127
        test    eax, RDES0_LS                           ; if not last desc of packet, error for now
1128
        jz      .end_rx
1502 hidnplayr 1129
 
1130
;        .IF     ZERO?
1131
;                ODS2 <"Net_Interrupt: packet > 1 descriptor, not supported yet :P">
1132
;                jmp     @@end_rx
1133
;        .ENDIF
1134
 
2544 hidnplayr 1135
        test    eax, RDES0_ES
1136
        jnz     .end_rx
1502 hidnplayr 1137
 
1138
;        .IF     !ZERO?
1139
;                ODS2 <"Net_Interrupt: RX error">
1140
;                jmp     @@end_rx
1141
;        .ENDIF
1142
 
2544 hidnplayr 1143
        mov     esi, [edi+DES.realaddr]
1144
        mov     ecx, [edi+DES.DES0]
1145
        shr     ecx, RDES0_FL_SH
1146
        and     ecx, RDES0_FL_MASK
1147
        sub     ecx, 4                                   ; crc
1502 hidnplayr 1148
 
2544 hidnplayr 1149
        DEBUGF  1,"Received packet!, size=%u, addr:%x\n", ecx, esi
1502 hidnplayr 1150
 
2544 hidnplayr 1151
        push    esi edi ecx
1152
        stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
1153
        pop     ecx edi esi
1154
        test    eax, eax
1155
        jz      .fail
1502 hidnplayr 1156
 
2544 hidnplayr 1157
        push    edi
1158
        push    dword .continue_rx
1159
        push    ecx eax
1160
        mov     edi, eax
1502 hidnplayr 1161
 
1162
; update statistics
2544 hidnplayr 1163
        inc     [device.packets_rx]
1502 hidnplayr 1164
 
2544 hidnplayr 1165
        add     dword [device.bytes_rx], ecx
1166
        adc     dword [device.bytes_rx + 4], 0
1502 hidnplayr 1167
 
1168
; copy packet data
2544 hidnplayr 1169
        shr     cx , 1
1170
        jnc     .nb
1171
        movsb
1502 hidnplayr 1172
  .nb:
2544 hidnplayr 1173
        shr     cx , 1
1174
        jnc     .nw
1175
        movsw
1502 hidnplayr 1176
  .nw:
2544 hidnplayr 1177
        rep     movsd
1502 hidnplayr 1178
 
2981 hidnplayr 1179
        jmp     Eth_input
1502 hidnplayr 1180
 
1181
    .continue_rx:
2544 hidnplayr 1182
        pop     edi
1502 hidnplayr 1183
 
2544 hidnplayr 1184
        ; free descriptor
1185
        mov     [edi+DES.DES0], DES0_OWN
1186
 
1187
        ; next descriptor
1188
        add     edi, DES.size
1502 hidnplayr 1189
 
2544 hidnplayr 1190
        inc     [device.rx_crt_des]
1191
        and     [device.rx_crt_des], RX_DES_COUNT-1
1502 hidnplayr 1192
 
2544 hidnplayr 1193
        jmp     .loop_rx_start_of_packet
1502 hidnplayr 1194
 
1195
      .end_rx:
1196
      .fail:
2544 hidnplayr 1197
        pop     ecx esi ax
1502 hidnplayr 1198
      .not_rx:
1199
 
2544 hidnplayr 1200
        jmp     .continue
1502 hidnplayr 1201
 
1202
 
1203
 
1204
align 4
2544 hidnplayr 1205
write_mac:      ; in: mac pushed onto stack (as 3 words)
1502 hidnplayr 1206
 
2544 hidnplayr 1207
        DEBUGF  2,"Writing MAC: "
1502 hidnplayr 1208
 
1209
; write data into driver cache
2544 hidnplayr 1210
        mov     esi, esp
1211
        lea     edi, [device.mac]
1212
        movsd
1213
        movsw
1214
        add     esp, 6
1215
 
1502 hidnplayr 1216
; send setup packet (only if driver is started)
2544 hidnplayr 1217
        call    Send_Setup_Packet
1502 hidnplayr 1218
 
1219
align 4
1220
read_mac:
1221
 
2544 hidnplayr 1222
        DEBUGF 1,"Read_mac\n"
1502 hidnplayr 1223
 
2544 hidnplayr 1224
        ret
1502 hidnplayr 1225
 
1226
 
1227
 
1228
align 4
1229
read_mac_eeprom:
1230
 
2544 hidnplayr 1231
        DEBUGF 1,"Read_mac_eeprom\n"
1502 hidnplayr 1232
 
2544 hidnplayr 1233
        lea     edi, [device.mac]
1234
        mov     esi, 20/2               ; read words, start address is 20
1502 hidnplayr 1235
     .loop:
2544 hidnplayr 1236
        push    esi edi
1237
        call    SROM_Read_Word
1238
        pop     edi esi
1239
        stosw
1240
        inc     esi
1241
        cmp     esi, 26/2
1242
        jl      .loop
1502 hidnplayr 1243
 
2544 hidnplayr 1244
        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 1245
 
2544 hidnplayr 1246
        ret
1502 hidnplayr 1247
 
1248
align 4
1249
write_mac_eeprom:
1250
 
2544 hidnplayr 1251
        DEBUGF 1,"Write_mac_eeprom\n"
1502 hidnplayr 1252
 
2544 hidnplayr 1253
        ret
1502 hidnplayr 1254
 
1255
 
1256
align 4
2544 hidnplayr 1257
SROM_GetWidth:  ; should be 6 or 8 according to some manuals (returns in ecx)
1502 hidnplayr 1258
 
2544 hidnplayr 1259
        DEBUGF 1,"SROM_GetWidth\n"
1502 hidnplayr 1260
 
2544 hidnplayr 1261
        call    SROM_Idle
1262
        call    SROM_EnterAccessMode
1502 hidnplayr 1263
 
1264
;        set_io  0
1265
;        set_io  CSR9
1266
 
2544 hidnplayr 1267
        ; send 110b
1502 hidnplayr 1268
 
2544 hidnplayr 1269
        in      eax, dx
1270
        or      eax, CSR9_SROM_DI
1271
        call    SROM_out
1502 hidnplayr 1272
 
2544 hidnplayr 1273
        in      eax, dx
1274
        or      eax, CSR9_SROM_DI
1275
        call    SROM_out
1502 hidnplayr 1276
 
2544 hidnplayr 1277
        in      eax, dx
1278
        and     eax, not (CSR9_SROM_DI)
1279
        call    SROM_out
1280
 
1281
        mov     ecx,1
1502 hidnplayr 1282
  .loop2:
2544 hidnplayr 1283
        Bit_Set CSR9_SROM_CK
1284
        SROM_Delay
1285
 
1286
        in      eax, dx
1287
        and     eax, CSR9_SROM_DO
1288
        jnz     .not_zero
1502 hidnplayr 1289
 
2544 hidnplayr 1290
        Bit_Clear CSR9_SROM_CK
1291
        SROM_Delay
1292
        jmp     .end_loop2
1502 hidnplayr 1293
  .not_zero:
2544 hidnplayr 1294
 
1295
        Bit_Clear CSR9_SROM_CK
1296
        SROM_Delay
1297
 
1298
        inc     ecx
1299
        cmp     ecx, 12
1300
        jle     .loop2
1502 hidnplayr 1301
  .end_loop2:
2544 hidnplayr 1302
 
1303
        DEBUGF 1,"Srom width=%u\n", ecx
1304
 
1305
        call    SROM_Idle
1306
        call    SROM_EnterAccessMode
1307
        call    SROM_Idle
1308
 
1309
        ret
1502 hidnplayr 1310
 
1311
 
1312
align 4
1313
SROM_out:
1314
 
2544 hidnplayr 1315
        out     dx, eax
1316
        SROM_Delay
1317
        Bit_Set CSR9_SROM_CK
1318
        SROM_Delay
1319
        Bit_Clear CSR9_SROM_CK
1320
        SROM_Delay
1502 hidnplayr 1321
 
2544 hidnplayr 1322
        ret
1502 hidnplayr 1323
 
1324
 
1325
 
1326
align 4
1327
SROM_EnterAccessMode:
1328
 
2544 hidnplayr 1329
        DEBUGF 1,"SROM_EnterAccessMode\n"
1502 hidnplayr 1330
 
2544 hidnplayr 1331
        set_io  0
1332
        set_io  CSR9
1333
        mov     eax, CSR9_SR
1334
        out     dx, eax
1335
        SROM_Delay
1502 hidnplayr 1336
 
2544 hidnplayr 1337
        Bit_Set CSR9_RD
1338
        SROM_Delay
1502 hidnplayr 1339
 
2544 hidnplayr 1340
        Bit_Clear CSR9_SROM_CK
1341
        SROM_Delay
1502 hidnplayr 1342
 
2544 hidnplayr 1343
        Bit_Set CSR9_SROM_CS
1344
        SROM_Delay
1345
 
1346
        ret
1502 hidnplayr 1347
 
1348
 
1349
 
1350
align 4
1351
SROM_Idle:
1352
 
2544 hidnplayr 1353
        DEBUGF 1,"SROM_Idle\n"
1502 hidnplayr 1354
 
2544 hidnplayr 1355
        call    SROM_EnterAccessMode
1356
 
1502 hidnplayr 1357
;        set_io  0
1358
;        set_io  CSR9
2544 hidnplayr 1359
 
1360
        mov     ecx, 25
1502 hidnplayr 1361
     .loop_clk:
1362
 
2544 hidnplayr 1363
        Bit_Clear CSR9_SROM_CK
1364
        SROM_Delay
1365
        Bit_Set CSR9_SROM_CK
1366
        SROM_Delay
1367
 
1368
        dec     ecx
1369
        jnz     .loop_clk
1502 hidnplayr 1370
 
2544 hidnplayr 1371
 
1372
        Bit_Clear CSR9_SROM_CK
1373
        SROM_Delay
1374
        Bit_Clear CSR9_SROM_CS
1375
        SROM_Delay
1376
 
1377
        xor     eax, eax
1378
        out     dx, eax
1379
 
1380
        ret
1502 hidnplayr 1381
 
1382
 
1383
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1384
;;                                                                      ;;
1385
;; Read serial EEprom word                                              ;;
1386
;;                                                                      ;;
1387
;; In: esi = read address                                               ;;
1388
;; OUT: ax = data word                                                  ;;
1389
;;                                                                      ;;
1390
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1391
align 4
1392
SROM_Read_Word:
1393
 
2544 hidnplayr 1394
        DEBUGF 1,"SROM_Read_word at: %x result: ", esi
1502 hidnplayr 1395
 
2544 hidnplayr 1396
        set_io  0
1397
        set_io  CSR9
1502 hidnplayr 1398
 
1399
; enter access mode
2544 hidnplayr 1400
        mov     eax, CSR9_SR + CSR9_RD
1401
        out     dx , eax
1402
        or      eax, CSR9_SROM_CS
1403
        out     dx , eax
1502 hidnplayr 1404
 
2544 hidnplayr 1405
        ; TODO: change this hard-coded 6-bit stuff to use value from srom_getwidth
1406
 
1502 hidnplayr 1407
; send read command "110b" + address to read from
2544 hidnplayr 1408
        and     esi, 111111b
1409
        or      esi, 110b shl 6
1410
 
1411
        mov     ecx, 1 shl 9
1502 hidnplayr 1412
  .loop_cmd:
2544 hidnplayr 1413
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1414
        test    esi, ecx
1415
        jz      @f
1416
        or      eax, CSR9_SROM_DI
1502 hidnplayr 1417
       @@:
2544 hidnplayr 1418
        out     dx , eax
1419
        SROM_Delay
1420
        or      eax, CSR9_SROM_CK
1421
        out     dx , eax
1422
        SROM_Delay
1423
 
1424
        shr     ecx, 1
1425
        jnz     .loop_cmd
1502 hidnplayr 1426
 
1427
; read data from SROM
1428
 
2544 hidnplayr 1429
        xor     esi, esi
1430
        mov     ecx, 17 ;;; TODO: figure out why 17, not 16
1502 hidnplayr 1431
  .loop_read:
2544 hidnplayr 1432
 
1433
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS + CSR9_SROM_CK
1434
        out     dx , eax
1435
        SROM_Delay
1436
 
1437
        in      eax, dx
1438
        and     eax, CSR9_SROM_DO
1439
        shr     eax, 3
1440
        shl     esi, 1
1441
        or      esi, eax
1442
 
1443
        mov     eax, CSR9_SR + CSR9_RD + CSR9_SROM_CS
1444
        out     dx , eax
1445
        SROM_Delay
1446
 
1447
        dec     ecx
1448
        jnz     .loop_read
1449
 
1450
        mov     eax, esi
1502 hidnplayr 1451
 
2544 hidnplayr 1452
        DEBUGF 1,"%x\n", ax
1502 hidnplayr 1453
 
2544 hidnplayr 1454
        ret
1502 hidnplayr 1455
 
1456
 
1503 hidnplayr 1457
 
1458
 
1459
 
1460
 
1461
 
1462
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1463
 
1464
 
1465
 
1466
;*********************************************************************
1467
;* Media Descriptor Code                                             *
1468
;*********************************************************************
1469
 
1470
; MII transceiver control section.
1471
; Read and write the MII registers using software-generated serial
1472
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1473
; for details.
1474
 
1475
; The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
1476
; met by back-to-back PCI I/O cycles, but we insert a delay to avoid
1477
; "overclocking" issues or future 66Mhz PCI.
1478
 
1479
; Read and write the MII registers using software-generated serial
1480
; MDIO protocol.  It is just different enough from the EEPROM protocol
1481
; to not share code.  The maxium data clock rate is 2.5 Mhz.
1482
 
2852 hidnplayr 1483
MDIO_SHIFT_CLK          =        0x10000
1484
MDIO_DATA_WRITE0        =        0x00000
1485
MDIO_DATA_WRITE1        =        0x20000
1486
MDIO_ENB                =        0x00000         ; Ignore the 0x02000 databook setting.
1487
MDIO_ENB_IN             =        0x40000
1488
MDIO_DATA_READ          =        0x80000
1503 hidnplayr 1489
 
1490
; MII transceiver control section.
1491
; Read and write the MII registers using software-generated serial
1492
; MDIO protocol.  See the MII specifications or DP83840A data sheet
1493
; for details.
1494
 
1495
align 4
2544 hidnplayr 1496
mdio_read:      ; phy_id:edx, location:esi
1503 hidnplayr 1497
 
2544 hidnplayr 1498
        DEBUGF  1,"mdio read, phy=%x, location=%x", edx, esi
1503 hidnplayr 1499
 
2544 hidnplayr 1500
        shl     edx, 5
1501
        or      esi, edx
1502
        or      esi, 0xf6 shl 10
1503 hidnplayr 1503
 
2544 hidnplayr 1504
        set_io  0
1505
        set_io  CSR9
1503 hidnplayr 1506
 
1507
;    if (tp->chip_id == LC82C168) {
1508
;        int i = 1000;
1509
;        outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
1510
;        inl(ioaddr + 0xA0);
1511
;        inl(ioaddr + 0xA0);
1512
;        while (--i > 0)
1513
;            if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
1514
;                return retval & 0xffff;
1515
;        return 0xffff;
1516
;    }
1517
;
1518
;    if (tp->chip_id == COMET) {
1519
;        if (phy_id == 1) {
1520
;            if (location < 7)
1521
;                return inl(ioaddr + 0xB4 + (location<<2));
1522
;            else if (location == 17)
1523
;                return inl(ioaddr + 0xD0);
1524
;            else if (location >= 29 && location <= 31)
1525
;                return inl(ioaddr + 0xD4 + ((location-29)<<2));
1526
;        }
1527
;        return 0xffff;
1528
;    }
1529
 
1530
; Establish sync by sending at least 32 logic ones.
1531
 
2544 hidnplayr 1532
        mov     ecx, 32
1503 hidnplayr 1533
  .loop:
2544 hidnplayr 1534
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1535
        out     dx, eax
1536
        MDIO_Delay
1503 hidnplayr 1537
 
2544 hidnplayr 1538
        or      eax, MDIO_SHIFT_CLK
1539
        out     dx, eax
1540
        MDIO_Delay
1503 hidnplayr 1541
 
2544 hidnplayr 1542
        dec     ecx
1543
        jnz     .loop
1503 hidnplayr 1544
 
1545
 
1546
; Shift the read command bits out.
1547
 
2544 hidnplayr 1548
        mov     ecx, 1 shl 15
1503 hidnplayr 1549
  .loop2:
2544 hidnplayr 1550
        mov     eax, MDIO_ENB
1551
        test    esi, ecx
1552
        jz      @f
1553
        or      eax, MDIO_DATA_WRITE1
1503 hidnplayr 1554
       @@:
2544 hidnplayr 1555
        out     dx, eax
1556
        MDIO_Delay
1503 hidnplayr 1557
 
2544 hidnplayr 1558
        or      eax, MDIO_SHIFT_CLK
1559
        out     dx, eax
1560
        MDIO_Delay
1503 hidnplayr 1561
 
2544 hidnplayr 1562
        shr     ecx, 1
1563
        jnz     .loop2
1503 hidnplayr 1564
 
1565
 
1566
; Read the two transition, 16 data, and wire-idle bits.
1567
 
2544 hidnplayr 1568
        xor     esi, esi
1569
        mov     ecx, 19
1503 hidnplayr 1570
  .loop3:
2544 hidnplayr 1571
        mov     eax, MDIO_ENB_IN
1572
        out     dx, eax
1573
        MDIO_Delay
1503 hidnplayr 1574
 
2544 hidnplayr 1575
        shl     esi, 1
1576
        in      eax, dx
1577
        test    eax, MDIO_DATA_READ
1578
        jz      @f
1579
        inc     esi
1503 hidnplayr 1580
       @@:
1581
 
2544 hidnplayr 1582
        mov     eax, MDIO_ENB_IN or MDIO_SHIFT_CLK
1583
        out     dx, eax
1584
        MDIO_Delay
1503 hidnplayr 1585
 
2544 hidnplayr 1586
        dec     ecx
1587
        jnz     .loop3
1503 hidnplayr 1588
 
2544 hidnplayr 1589
        shr     esi, 1
1590
        movzx   eax, si
1503 hidnplayr 1591
 
2544 hidnplayr 1592
        DEBUGF  1,", data=%x\n", ax
1503 hidnplayr 1593
 
2544 hidnplayr 1594
        ret
1503 hidnplayr 1595
 
1596
 
1597
 
1598
 
1599
align 4
2544 hidnplayr 1600
mdio_write:     ;int phy_id: edx, int location: edi, int value: ax)
1503 hidnplayr 1601
 
2544 hidnplayr 1602
        DEBUGF  1,"mdio write, phy=%x, location=%x, data=%x\n", edx, edi, ax
1503 hidnplayr 1603
 
2544 hidnplayr 1604
        shl     edi, 18
1605
        or      edi, 0x5002 shl 16
1606
        shl     edx, 23
1607
        or      edi, edx
1608
        mov     di, ax
1503 hidnplayr 1609
 
2544 hidnplayr 1610
        set_io  0
1611
        set_io  CSR9
1503 hidnplayr 1612
 
1613
;    if (tp->chip_id == LC82C168) {
1614
;        int i = 1000;
1615
;        outl(cmd, ioaddr + 0xA0);
1616
;        do
1617
;            if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
1618
;                break;
1619
;        while (--i > 0);
1620
;        return;
1621
;    }
1622
 
1623
;    if (tp->chip_id == COMET) {
1624
;        if (phy_id != 1)
1625
;            return;
1626
;        if (location < 7)
1627
;            outl(value, ioaddr + 0xB4 + (location<<2));
1628
;        else if (location == 17)
1629
;            outl(value, ioaddr + 0xD0);
1630
;        else if (location >= 29 && location <= 31)
1631
;            outl(value, ioaddr + 0xD4 + ((location-29)<<2));
1632
;        return;
1633
;    }
1634
 
1635
 
1636
; Establish sync by sending at least 32 logic ones.
1637
 
2544 hidnplayr 1638
        mov     ecx, 32
1503 hidnplayr 1639
  .loop:
2544 hidnplayr 1640
        mov     eax, MDIO_ENB or MDIO_DATA_WRITE1
1641
        out     dx, eax
1642
        MDIO_Delay
1503 hidnplayr 1643
 
2544 hidnplayr 1644
        or      eax, MDIO_SHIFT_CLK
1645
        out     dx, eax
1646
        MDIO_Delay
1503 hidnplayr 1647
 
2544 hidnplayr 1648
        dec     ecx
1649
        jnz     .loop
1503 hidnplayr 1650
 
1651
 
1652
; Shift the command bits out.
1653
 
2544 hidnplayr 1654
        mov     ecx, 1 shl 31
1503 hidnplayr 1655
  .loop2:
2544 hidnplayr 1656
        mov     eax, MDIO_ENB
1657
        test    edi, ecx
1658
        jz      @f
1659
        or      eax, MDIO_DATA_WRITE1
1503 hidnplayr 1660
       @@:
2544 hidnplayr 1661
        out     dx, eax
1662
        MDIO_Delay
1503 hidnplayr 1663
 
2544 hidnplayr 1664
        or      eax, MDIO_SHIFT_CLK
1665
        out     dx, eax
1666
        MDIO_Delay
1503 hidnplayr 1667
 
2544 hidnplayr 1668
        shr     ecx, 1
1669
        jnz     .loop2
1503 hidnplayr 1670
 
1671
 
1672
; Clear out extra bits.
1673
 
2544 hidnplayr 1674
        mov     ecx, 2
1503 hidnplayr 1675
  .loop3:
2544 hidnplayr 1676
        mov     eax, MDIO_ENB
1677
        out     dx, eax
1678
        MDIO_Delay
1503 hidnplayr 1679
 
2544 hidnplayr 1680
        or      eax, MDIO_SHIFT_CLK
1681
        out     dx, eax
1682
        MDIO_Delay
1503 hidnplayr 1683
 
2544 hidnplayr 1684
        dec     ecx
1685
        jnz     .loop3
1503 hidnplayr 1686
 
2544 hidnplayr 1687
        ret
1503 hidnplayr 1688
 
1689
 
1502 hidnplayr 1690
; End of code
2544 hidnplayr 1691
align 4                                         ; Place all initialised data here
1502 hidnplayr 1692
 
1693
devices       dd 0
1519 hidnplayr 1694
version       dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
2544 hidnplayr 1695
my_service    db 'DEC21X4X',0                    ; max 16 chars include zero
1502 hidnplayr 1696
 
2544 hidnplayr 1697
include_debug_strings                           ; All data wich FDO uses will be included here
1502 hidnplayr 1698
 
1699
section '.data' data readable writable align 16 ; place all uninitialized data place here
1700
 
2544 hidnplayr 1701
device_list rd MAX_DEVICES                     ; This list contains all pointers to device structures the driver is handling
1502 hidnplayr 1702
 
1703