Subversion Repositories Kolibri OS

Rev

Rev 5074 | Rev 5522 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5074 Rev 5363
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2010-2014. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  rhine.asm                                                      ;;
6
;;  rhine.asm                                                      ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Ethernet driver for Kolibri OS                                 ;;
8
;;  Ethernet driver for Kolibri OS                                 ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;  This driver is based on the via-rhine driver from              ;;
10
;;  This driver is based on the via-rhine driver from              ;;
11
;;  the etherboot 5.0.6 project. The copyright statement is        ;;
11
;;  the etherboot 5.0.6 project. The copyright statement is        ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
15
;;                                                                 ;;
16
;;    Rewritten in flat assembler by Asper (asper.85@mail.ru)      ;;
16
;;    Rewritten in flat assembler by Asper (asper.85@mail.ru)      ;;
17
;;            and hidnplayr (hidnplayr@gmail.com)                  ;;
17
;;            and hidnplayr (hidnplayr@gmail.com)                  ;;
18
;;                                                                 ;;
18
;;                                                                 ;;
19
;;  See file COPYING for details                                   ;;
19
;;  See file COPYING for details                                   ;;
20
;;                                                                 ;;
20
;;                                                                 ;;
21
;;                                                                 ;;
21
;;                                                                 ;;
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
23
 
23
 
24
format PE DLL native
24
format PE DLL native
25
entry START
25
entry START
26
 
26
 
27
        CURRENT_API             = 0x0200
27
        CURRENT_API             = 0x0200
28
        COMPATIBLE_API          = 0x0100
28
        COMPATIBLE_API          = 0x0100
29
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
29
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
30
 
30
 
31
        MAX_DEVICES             = 16
31
        MAX_DEVICES             = 16
32
 
32
 
33
        __DEBUG__               = 1
33
        __DEBUG__               = 1
34
        __DEBUG_LEVEL__         = 2     ; 1 = all, 2 = errors only
34
        __DEBUG_LEVEL__         = 2     ; 1 = all, 2 = errors only
35
 
35
 
36
        TX_RING_SIZE            = 4
36
        TX_RING_SIZE            = 4
37
        RX_RING_SIZE            = 4
37
        RX_RING_SIZE            = 4
38
 
38
 
39
        ; max time out delay time
39
        ; max time out delay time
40
        W_MAX_TIMEOUT           = 0x0FFF
40
        W_MAX_TIMEOUT           = 0x0FFF
41
 
41
 
42
        ; Size of the in-memory receive ring.
42
        ; Size of the in-memory receive ring.
43
        RX_BUF_LEN_IDX          = 3     ; 0==8K, 1==16K, 2==32K, 3==64K
43
        RX_BUF_LEN_IDX          = 3     ; 0==8K, 1==16K, 2==32K, 3==64K
44
 
44
 
45
        ; PCI Tuning Parameters
45
        ; PCI Tuning Parameters
46
        ; Threshold is bytes transferred to chip before transmission starts.
46
        ; Threshold is bytes transferred to chip before transmission starts.
47
        TX_FIFO_THRESH          = 256   ; In bytes, rounded down to 32 byte units.
47
        TX_FIFO_THRESH          = 256   ; In bytes, rounded down to 32 byte units.
48
 
48
 
49
        ; The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024.
49
        ; The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024.
50
        RX_FIFO_THRESH          = 4     ; Rx buffer level before first PCI transfer.
50
        RX_FIFO_THRESH          = 4     ; Rx buffer level before first PCI transfer.
51
        RX_DMA_BURST            = 4     ; Maximum PCI burst, '4' is 256 bytes
51
        RX_DMA_BURST            = 4     ; Maximum PCI burst, '4' is 256 bytes
52
        TX_DMA_BURST            = 4
52
        TX_DMA_BURST            = 4
53
 
53
 
54
 
54
 
55
section '.flat' readable writable executable
55
section '.flat' readable writable executable
56
 
56
 
57
include '../proc32.inc'
57
include '../proc32.inc'
58
include '../struct.inc'
58
include '../struct.inc'
59
include '../macros.inc'
59
include '../macros.inc'
60
include '../fdo.inc'
60
include '../fdo.inc'
61
include '../netdrv.inc'
61
include '../netdrv.inc'
62
 
62
 
63
 
63
 
64
;**************************************************************************
64
;**************************************************************************
65
; VIA Rhine Register Definitions
65
; VIA Rhine Register Definitions
66
;**************************************************************************
66
;**************************************************************************
67
byPAR0                          = 0x00
67
byPAR0                          = 0x00
68
byRCR                           = 0x06
68
byRCR                           = 0x06
69
byTCR                           = 0x07
69
byTCR                           = 0x07
70
byCR0                           = 0x08
70
byCR0                           = 0x08
71
byCR1                           = 0x09
71
byCR1                           = 0x09
72
byISR0                          = 0x0c
72
byISR0                          = 0x0c
73
byISR1                          = 0x0d
73
byISR1                          = 0x0d
74
byIMR0                          = 0x0e
74
byIMR0                          = 0x0e
75
byIMR1                          = 0x0f
75
byIMR1                          = 0x0f
76
byMAR0                          = 0x10
76
byMAR0                          = 0x10
77
byMAR1                          = 0x11
77
byMAR1                          = 0x11
78
byMAR2                          = 0x12
78
byMAR2                          = 0x12
79
byMAR3                          = 0x13
79
byMAR3                          = 0x13
80
byMAR4                          = 0x14
80
byMAR4                          = 0x14
81
byMAR5                          = 0x15
81
byMAR5                          = 0x15
82
byMAR6                          = 0x16
82
byMAR6                          = 0x16
83
byMAR7                          = 0x17
83
byMAR7                          = 0x17
84
dwCurrentRxDescAddr             = 0x18
84
dwCurrentRxDescAddr             = 0x18
85
dwCurrentTxDescAddr             = 0x1c
85
dwCurrentTxDescAddr             = 0x1c
86
dwCurrentRDSE0                  = 0x20
86
dwCurrentRDSE0                  = 0x20
87
dwCurrentRDSE1                  = 0x24
87
dwCurrentRDSE1                  = 0x24
88
dwCurrentRDSE2                  = 0x28
88
dwCurrentRDSE2                  = 0x28
89
dwCurrentRDSE3                  = 0x2c
89
dwCurrentRDSE3                  = 0x2c
90
dwNextRDSE0                     = 0x30
90
dwNextRDSE0                     = 0x30
91
dwNextRDSE1                     = 0x34
91
dwNextRDSE1                     = 0x34
92
dwNextRDSE2                     = 0x38
92
dwNextRDSE2                     = 0x38
93
dwNextRDSE3                     = 0x3c
93
dwNextRDSE3                     = 0x3c
94
dwCurrentTDSE0                  = 0x40
94
dwCurrentTDSE0                  = 0x40
95
dwCurrentTDSE1                  = 0x44
95
dwCurrentTDSE1                  = 0x44
96
dwCurrentTDSE2                  = 0x48
96
dwCurrentTDSE2                  = 0x48
97
dwCurrentTDSE3                  = 0x4c
97
dwCurrentTDSE3                  = 0x4c
98
dwNextTDSE0                     = 0x50
98
dwNextTDSE0                     = 0x50
99
dwNextTDSE1                     = 0x54
99
dwNextTDSE1                     = 0x54
100
dwNextTDSE2                     = 0x58
100
dwNextTDSE2                     = 0x58
101
dwNextTDSE3                     = 0x5c
101
dwNextTDSE3                     = 0x5c
102
dwCurrRxDMAPtr                  = 0x60
102
dwCurrRxDMAPtr                  = 0x60
103
dwCurrTxDMAPtr                  = 0x64
103
dwCurrTxDMAPtr                  = 0x64
104
byMPHY                          = 0x6c
104
byMPHY                          = 0x6c
105
byMIISR                         = 0x6d
105
byMIISR                         = 0x6d
106
byBCR0                          = 0x6e
106
byBCR0                          = 0x6e
107
byBCR1                          = 0x6f
107
byBCR1                          = 0x6f
108
byMIICR                         = 0x70
108
byMIICR                         = 0x70
109
byMIIAD                         = 0x71
109
byMIIAD                         = 0x71
110
wMIIDATA                        = 0x72
110
wMIIDATA                        = 0x72
111
byEECSR                         = 0x74
111
byEECSR                         = 0x74
112
byTEST                          = 0x75
112
byTEST                          = 0x75
113
byGPIO                          = 0x76
113
byGPIO                          = 0x76
114
byCFGA                          = 0x78
114
byCFGA                          = 0x78
115
byCFGB                          = 0x79
115
byCFGB                          = 0x79
116
byCFGC                          = 0x7a
116
byCFGC                          = 0x7a
117
byCFGD                          = 0x7b
117
byCFGD                          = 0x7b
118
wTallyCntMPA                    = 0x7c
118
wTallyCntMPA                    = 0x7c
119
wTallyCntCRC                    = 0x7d
119
wTallyCntCRC                    = 0x7d
120
bySTICKHW                       = 0x83
120
bySTICKHW                       = 0x83
121
byWOLcrClr                      = 0xA4
121
byWOLcrClr                      = 0xA4
122
byWOLcgClr                      = 0xA7
122
byWOLcgClr                      = 0xA7
123
byPwrcsrClr                     = 0xAC
123
byPwrcsrClr                     = 0xAC
124
 
124
 
125
;---------------------  Exioaddr Definitions -------------------------
125
;---------------------  Exioaddr Definitions -------------------------
126
 
126
 
127
; Bits in the RCR register
127
; Bits in the RCR register
128
RCR_RRFT2               = 0x80
128
RCR_RRFT2               = 0x80
129
RCR_RRFT1               = 0x40
129
RCR_RRFT1               = 0x40
130
RCR_RRFT0               = 0x20
130
RCR_RRFT0               = 0x20
131
RCR_PROM                = 0x10
131
RCR_PROM                = 0x10
132
RCR_AB                  = 0x08
132
RCR_AB                  = 0x08
133
RCR_AM                  = 0x04
133
RCR_AM                  = 0x04
134
RCR_AR                  = 0x02
134
RCR_AR                  = 0x02
135
RCR_SEP                 = 0x01
135
RCR_SEP                 = 0x01
136
; Bits in the TCR register
136
; Bits in the TCR register
137
TCR_RTSF                = 0x80
137
TCR_RTSF                = 0x80
138
TCR_RTFT1               = 0x40
138
TCR_RTFT1               = 0x40
139
TCR_RTFT0               = 0x20
139
TCR_RTFT0               = 0x20
140
TCR_OFSET               = 0x08
140
TCR_OFSET               = 0x08
141
TCR_LB1                 = 0x04    ; loopback[1]
141
TCR_LB1                 = 0x04    ; loopback[1]
142
TCR_LB0                 = 0x02    ; loopback[0]
142
TCR_LB0                 = 0x02    ; loopback[0]
143
; Bits in the CR0 register
143
; Bits in the CR0 register
144
CR0_RDMD                = 0x40    ; rx descriptor polling demand
144
CR0_RDMD                = 0x40    ; rx descriptor polling demand
145
CR0_TDMD                = 0x20    ; tx descriptor polling demand
145
CR0_TDMD                = 0x20    ; tx descriptor polling demand
146
CR0_TXON                = 0x10
146
CR0_TXON                = 0x10
147
CR0_RXON                = 0x08
147
CR0_RXON                = 0x08
148
CR0_STOP                = 0x04    ; stop NIC, default = 1
148
CR0_STOP                = 0x04    ; stop NIC, default = 1
149
CR0_STRT                = 0x02    ; start NIC
149
CR0_STRT                = 0x02    ; start NIC
150
CR0_INIT                = 0x01    ; start init process
150
CR0_INIT                = 0x01    ; start init process
151
; Bits in the CR1 register
151
; Bits in the CR1 register
152
CR1_SFRST               = 0x80    ; software reset
152
CR1_SFRST               = 0x80    ; software reset
153
CR1_RDMD1               = 0x40    ; RDMD1
153
CR1_RDMD1               = 0x40    ; RDMD1
154
CR1_TDMD1               = 0x20    ; TDMD1
154
CR1_TDMD1               = 0x20    ; TDMD1
155
CR1_KEYPAG              = 0x10    ; turn on par/key
155
CR1_KEYPAG              = 0x10    ; turn on par/key
156
CR1_DPOLL               = 0x08    ; disable rx/tx auto polling
156
CR1_DPOLL               = 0x08    ; disable rx/tx auto polling
157
CR1_FDX                 = 0x04    ; full duplex mode
157
CR1_FDX                 = 0x04    ; full duplex mode
158
CR1_ETEN                = 0x02    ; early tx mode
158
CR1_ETEN                = 0x02    ; early tx mode
159
CR1_EREN                = 0x01    ; early rx mode
159
CR1_EREN                = 0x01    ; early rx mode
160
; Bits in the CR register
160
; Bits in the CR register
161
CR_RDMD                 = 0x0040  ; rx descriptor polling demand
161
CR_RDMD                 = 0x0040  ; rx descriptor polling demand
162
CR_TDMD                 = 0x0020  ; tx descriptor polling demand
162
CR_TDMD                 = 0x0020  ; tx descriptor polling demand
163
CR_TXON                 = 0x0010
163
CR_TXON                 = 0x0010
164
CR_RXON                 = 0x0008
164
CR_RXON                 = 0x0008
165
CR_STOP                 = 0x0004  ; stop NIC, default = 1
165
CR_STOP                 = 0x0004  ; stop NIC, default = 1
166
CR_STRT                 = 0x0002  ; start NIC
166
CR_STRT                 = 0x0002  ; start NIC
167
CR_INIT                 = 0x0001  ; start init process
167
CR_INIT                 = 0x0001  ; start init process
168
CR_SFRST                = 0x8000  ; software reset
168
CR_SFRST                = 0x8000  ; software reset
169
CR_RDMD1                = 0x4000  ; RDMD1
169
CR_RDMD1                = 0x4000  ; RDMD1
170
CR_TDMD1                = 0x2000  ; TDMD1
170
CR_TDMD1                = 0x2000  ; TDMD1
171
CR_KEYPAG               = 0x1000  ; turn on par/key
171
CR_KEYPAG               = 0x1000  ; turn on par/key
172
CR_DPOLL                = 0x0800  ; disable rx/tx auto polling
172
CR_DPOLL                = 0x0800  ; disable rx/tx auto polling
173
CR_FDX                  = 0x0400  ; full duplex mode
173
CR_FDX                  = 0x0400  ; full duplex mode
174
CR_ETEN                 = 0x0200  ; early tx mode
174
CR_ETEN                 = 0x0200  ; early tx mode
175
CR_EREN                 = 0x0100  ; early rx mode
175
CR_EREN                 = 0x0100  ; early rx mode
176
; Bits in the IMR0 register
176
; Bits in the IMR0 register
177
IMR0_CNTM               = 0x80
177
IMR0_CNTM               = 0x80
178
IMR0_BEM                = 0x40
178
IMR0_BEM                = 0x40
179
IMR0_RUM                = 0x20
179
IMR0_RUM                = 0x20
180
IMR0_TUM                = 0x10
180
IMR0_TUM                = 0x10
181
IMR0_TXEM               = 0x08
181
IMR0_TXEM               = 0x08
182
IMR0_RXEM               = 0x04
182
IMR0_RXEM               = 0x04
183
IMR0_PTXM               = 0x02
183
IMR0_PTXM               = 0x02
184
IMR0_PRXM               = 0x01
184
IMR0_PRXM               = 0x01
185
; define imrshadow
185
; define imrshadow
186
IMRShadow               = 0x5AFF
186
IMRShadow               = 0x5AFF
187
; Bits in the IMR1 register
187
; Bits in the IMR1 register
188
IMR1_INITM              = 0x80
188
IMR1_INITM              = 0x80
189
IMR1_SRCM               = 0x40
189
IMR1_SRCM               = 0x40
190
IMR1_NBFM               = 0x10
190
IMR1_NBFM               = 0x10
191
IMR1_PRAIM              = 0x08
191
IMR1_PRAIM              = 0x08
192
IMR1_RES0M              = 0x04
192
IMR1_RES0M              = 0x04
193
IMR1_ETM                = 0x02
193
IMR1_ETM                = 0x02
194
IMR1_ERM                = 0x01
194
IMR1_ERM                = 0x01
195
; Bits in the ISR register
195
; Bits in the ISR register
196
ISR_INITI               = 0x8000
196
ISR_INITI               = 0x8000
197
ISR_SRCI                = 0x4000
197
ISR_SRCI                = 0x4000
198
ISR_ABTI                = 0x2000
198
ISR_ABTI                = 0x2000
199
ISR_NORBF               = 0x1000
199
ISR_NORBF               = 0x1000
200
ISR_PKTRA               = 0x0800
200
ISR_PKTRA               = 0x0800
201
ISR_RES0                = 0x0400
201
ISR_RES0                = 0x0400
202
ISR_ETI                 = 0x0200
202
ISR_ETI                 = 0x0200
203
ISR_ERI                 = 0x0100
203
ISR_ERI                 = 0x0100
204
ISR_CNT                 = 0x0080
204
ISR_CNT                 = 0x0080
205
ISR_BE                  = 0x0040
205
ISR_BE                  = 0x0040
206
ISR_RU                  = 0x0020
206
ISR_RU                  = 0x0020
207
ISR_TU                  = 0x0010
207
ISR_TU                  = 0x0010
208
ISR_TXE                 = 0x0008
208
ISR_TXE                 = 0x0008
209
ISR_RXE                 = 0x0004
209
ISR_RXE                 = 0x0004
210
ISR_PTX                 = 0x0002
210
ISR_PTX                 = 0x0002
211
ISR_PRX                 = 0x0001
211
ISR_PRX                 = 0x0001
212
; Bits in the ISR0 register
212
; Bits in the ISR0 register
213
ISR0_CNT                = 0x80
213
ISR0_CNT                = 0x80
214
ISR0_BE                 = 0x40
214
ISR0_BE                 = 0x40
215
ISR0_RU                 = 0x20
215
ISR0_RU                 = 0x20
216
ISR0_TU                 = 0x10
216
ISR0_TU                 = 0x10
217
ISR0_TXE                = 0x08
217
ISR0_TXE                = 0x08
218
ISR0_RXE                = 0x04
218
ISR0_RXE                = 0x04
219
ISR0_PTX                = 0x02
219
ISR0_PTX                = 0x02
220
ISR0_PRX                = 0x01
220
ISR0_PRX                = 0x01
221
; Bits in the ISR1 register
221
; Bits in the ISR1 register
222
ISR1_INITI              = 0x80
222
ISR1_INITI              = 0x80
223
ISR1_SRCI               = 0x40
223
ISR1_SRCI               = 0x40
224
ISR1_NORBF              = 0x10
224
ISR1_NORBF              = 0x10
225
ISR1_PKTRA              = 0x08
225
ISR1_PKTRA              = 0x08
226
ISR1_ETI                = 0x02
226
ISR1_ETI                = 0x02
227
ISR1_ERI                = 0x01
227
ISR1_ERI                = 0x01
228
; ISR ABNORMAL CONDITION
228
; ISR ABNORMAL CONDITION
229
ISR_ABNORMAL            = ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
229
ISR_ABNORMAL            = ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
230
; Bits in the MIISR register
230
; Bits in the MIISR register
231
MIISR_MIIERR            = 0x08
231
MIISR_MIIERR            = 0x08
232
MIISR_MRERR             = 0x04
232
MIISR_MRERR             = 0x04
233
MIISR_LNKFL             = 0x02
233
MIISR_LNKFL             = 0x02
234
MIISR_SPEED             = 0x01
234
MIISR_SPEED             = 0x01
235
; Bits in the MIICR register
235
; Bits in the MIICR register
236
MIICR_MAUTO             = 0x80
236
MIICR_MAUTO             = 0x80
237
MIICR_RCMD              = 0x40
237
MIICR_RCMD              = 0x40
238
MIICR_WCMD              = 0x20
238
MIICR_WCMD              = 0x20
239
MIICR_MDPM              = 0x10
239
MIICR_MDPM              = 0x10
240
MIICR_MOUT              = 0x08
240
MIICR_MOUT              = 0x08
241
MIICR_MDO               = 0x04
241
MIICR_MDO               = 0x04
242
MIICR_MDI               = 0x02
242
MIICR_MDI               = 0x02
243
MIICR_MDC               = 0x01
243
MIICR_MDC               = 0x01
244
; Bits in the EECSR register
244
; Bits in the EECSR register
245
EECSR_EEPR              = 0x80    ; eeprom programmed status, 73h means programmed
245
EECSR_EEPR              = 0x80    ; eeprom programmed status, 73h means programmed
246
EECSR_EMBP              = 0x40    ; eeprom embedded programming
246
EECSR_EMBP              = 0x40    ; eeprom embedded programming
247
EECSR_AUTOLD            = 0x20    ; eeprom content reload
247
EECSR_AUTOLD            = 0x20    ; eeprom content reload
248
EECSR_DPM               = 0x10    ; eeprom direct programming
248
EECSR_DPM               = 0x10    ; eeprom direct programming
249
EECSR_CS                = 0x08    ; eeprom CS pin
249
EECSR_CS                = 0x08    ; eeprom CS pin
250
EECSR_SK                = 0x04    ; eeprom SK pin
250
EECSR_SK                = 0x04    ; eeprom SK pin
251
EECSR_DI                = 0x02    ; eeprom DI pin
251
EECSR_DI                = 0x02    ; eeprom DI pin
252
EECSR_DO                = 0x01    ; eeprom DO pin
252
EECSR_DO                = 0x01    ; eeprom DO pin
253
; Bits in the BCR0 register
253
; Bits in the BCR0 register
254
BCR0_CRFT2              = 0x20
254
BCR0_CRFT2              = 0x20
255
BCR0_CRFT1              = 0x10
255
BCR0_CRFT1              = 0x10
256
BCR0_CRFT0              = 0x08
256
BCR0_CRFT0              = 0x08
257
BCR0_DMAL2              = 0x04
257
BCR0_DMAL2              = 0x04
258
BCR0_DMAL1              = 0x02
258
BCR0_DMAL1              = 0x02
259
BCR0_DMAL0              = 0x01
259
BCR0_DMAL0              = 0x01
260
; Bits in the BCR1 register
260
; Bits in the BCR1 register
261
BCR1_CTSF               = 0x20
261
BCR1_CTSF               = 0x20
262
BCR1_CTFT1              = 0x10
262
BCR1_CTFT1              = 0x10
263
BCR1_CTFT0              = 0x08
263
BCR1_CTFT0              = 0x08
264
BCR1_POT2               = 0x04
264
BCR1_POT2               = 0x04
265
BCR1_POT1               = 0x02
265
BCR1_POT1               = 0x02
266
BCR1_POT0               = 0x01
266
BCR1_POT0               = 0x01
267
; Bits in the CFGA register
267
; Bits in the CFGA register
268
CFGA_EELOAD             = 0x80    ; enable eeprom embedded and direct programming
268
CFGA_EELOAD             = 0x80    ; enable eeprom embedded and direct programming
269
CFGA_JUMPER             = 0x40
269
CFGA_JUMPER             = 0x40
270
CFGA_MTGPIO             = 0x08
270
CFGA_MTGPIO             = 0x08
271
CFGA_T10EN              = 0x02
271
CFGA_T10EN              = 0x02
272
CFGA_AUTO               = 0x01
272
CFGA_AUTO               = 0x01
273
; Bits in the CFGB register
273
; Bits in the CFGB register
274
CFGB_PD                 = 0x80
274
CFGB_PD                 = 0x80
275
CFGB_POLEN              = 0x02
275
CFGB_POLEN              = 0x02
276
CFGB_LNKEN              = 0x01
276
CFGB_LNKEN              = 0x01
277
; Bits in the CFGC register
277
; Bits in the CFGC register
278
CFGC_M10TIO             = 0x80
278
CFGC_M10TIO             = 0x80
279
CFGC_M10POL             = 0x40
279
CFGC_M10POL             = 0x40
280
CFGC_PHY1               = 0x20
280
CFGC_PHY1               = 0x20
281
CFGC_PHY0               = 0x10
281
CFGC_PHY0               = 0x10
282
CFGC_BTSEL              = 0x08
282
CFGC_BTSEL              = 0x08
283
CFGC_BPS2               = 0x04    ; bootrom select[2]
283
CFGC_BPS2               = 0x04    ; bootrom select[2]
284
CFGC_BPS1               = 0x02    ; bootrom select[1]
284
CFGC_BPS1               = 0x02    ; bootrom select[1]
285
CFGC_BPS0               = 0x01    ; bootrom select[0]
285
CFGC_BPS0               = 0x01    ; bootrom select[0]
286
; Bits in the CFGD register
286
; Bits in the CFGD register
287
CFGD_GPIOEN             = 0x80
287
CFGD_GPIOEN             = 0x80
288
CFGD_DIAG               = 0x40
288
CFGD_DIAG               = 0x40
289
CFGD_MAGIC              = 0x10
289
CFGD_MAGIC              = 0x10
290
CFGD_RANDOM             = 0x08
290
CFGD_RANDOM             = 0x08
291
CFGD_CFDX               = 0x04
291
CFGD_CFDX               = 0x04
292
CFGD_CEREN              = 0x02
292
CFGD_CEREN              = 0x02
293
CFGD_CETEN              = 0x01
293
CFGD_CETEN              = 0x01
294
; Bits in RSR
294
; Bits in RSR
295
RSR_RERR                = 0x00000001
295
RSR_RERR                = 0x00000001
296
RSR_CRC                 = 0x00000002
296
RSR_CRC                 = 0x00000002
297
RSR_FAE                 = 0x00000004
297
RSR_FAE                 = 0x00000004
298
RSR_FOV                 = 0x00000008
298
RSR_FOV                 = 0x00000008
299
RSR_LONG                = 0x00000010
299
RSR_LONG                = 0x00000010
300
RSR_RUNT                = 0x00000020
300
RSR_RUNT                = 0x00000020
301
RSR_SERR                = 0x00000040
301
RSR_SERR                = 0x00000040
302
RSR_BUFF                = 0x00000080
302
RSR_BUFF                = 0x00000080
303
RSR_EDP                 = 0x00000100
303
RSR_EDP                 = 0x00000100
304
RSR_STP                 = 0x00000200
304
RSR_STP                 = 0x00000200
305
RSR_CHN                 = 0x00000400
305
RSR_CHN                 = 0x00000400
306
RSR_PHY                 = 0x00000800
306
RSR_PHY                 = 0x00000800
307
RSR_BAR                 = 0x00001000
307
RSR_BAR                 = 0x00001000
308
RSR_MAR                 = 0x00002000
308
RSR_MAR                 = 0x00002000
309
RSR_RXOK                = 0x00008000
309
RSR_RXOK                = 0x00008000
310
RSR_ABNORMAL            = RSR_RERR+RSR_LONG+RSR_RUNT
310
RSR_ABNORMAL            = RSR_RERR+RSR_LONG+RSR_RUNT
311
; Bits in TSR
311
; Bits in TSR
312
TSR_NCR0                = 0x00000001
312
TSR_NCR0                = 0x00000001
313
TSR_NCR1                = 0x00000002
313
TSR_NCR1                = 0x00000002
314
TSR_NCR2                = 0x00000004
314
TSR_NCR2                = 0x00000004
315
TSR_NCR3                = 0x00000008
315
TSR_NCR3                = 0x00000008
316
TSR_COLS                = 0x00000010
316
TSR_COLS                = 0x00000010
317
TSR_CDH                 = 0x00000080
317
TSR_CDH                 = 0x00000080
318
TSR_ABT                 = 0x00000100
318
TSR_ABT                 = 0x00000100
319
TSR_OWC                 = 0x00000200
319
TSR_OWC                 = 0x00000200
320
TSR_CRS                 = 0x00000400
320
TSR_CRS                 = 0x00000400
321
TSR_UDF                 = 0x00000800
321
TSR_UDF                 = 0x00000800
322
TSR_TBUFF               = 0x00001000
322
TSR_TBUFF               = 0x00001000
323
TSR_SERR                = 0x00002000
323
TSR_SERR                = 0x00002000
324
TSR_JAB                 = 0x00004000
324
TSR_JAB                 = 0x00004000
325
TSR_TERR                = 0x00008000
325
TSR_TERR                = 0x00008000
326
TSR_ABNORMAL            = TSR_TERR+TSR_OWC+TSR_ABT+TSR_JAB+TSR_CRS
326
TSR_ABNORMAL            = TSR_TERR+TSR_OWC+TSR_ABT+TSR_JAB+TSR_CRS
327
TSR_OWN_BIT             = 0x80000000
327
TSR_OWN_BIT             = 0x80000000
328
 
328
 
329
CB_DELAY_LOOP_WAIT      = 10      ; 10ms
329
CB_DELAY_LOOP_WAIT      = 10      ; 10ms
330
; enabled mask value of irq
330
; enabled mask value of irq
331
W_IMR_MASK_VALUE        = 0x1BFF  ; initial value of IMR
331
W_IMR_MASK_VALUE        = 0x1BFF  ; initial value of IMR
332
 
332
 
333
; Ethernet address filter type
333
; Ethernet address filter type
334
PKT_TYPE_DIRECTED       = 0x0001  ; obsolete, directed address is always accepted
334
PKT_TYPE_DIRECTED       = 0x0001  ; obsolete, directed address is always accepted
335
PKT_TYPE_MULTICAST      = 0x0002
335
PKT_TYPE_MULTICAST      = 0x0002
336
PKT_TYPE_ALL_MULTICAST  = 0x0004
336
PKT_TYPE_ALL_MULTICAST  = 0x0004
337
PKT_TYPE_BROADCAST      = 0x0008
337
PKT_TYPE_BROADCAST      = 0x0008
338
PKT_TYPE_PROMISCUOUS    = 0x0020
338
PKT_TYPE_PROMISCUOUS    = 0x0020
339
PKT_TYPE_LONG           = 0x2000
339
PKT_TYPE_LONG           = 0x2000
340
PKT_TYPE_RUNT           = 0x4000
340
PKT_TYPE_RUNT           = 0x4000
341
PKT_TYPE_ERROR          = 0x8000  ; accept error packets, e.g. CRC error
341
PKT_TYPE_ERROR          = 0x8000  ; accept error packets, e.g. CRC error
342
 
342
 
343
; Loopback mode
343
; Loopback mode
344
 
344
 
345
NIC_LB_NONE             = 0x00
345
NIC_LB_NONE             = 0x00
346
NIC_LB_INTERNAL         = 0x01
346
NIC_LB_INTERNAL         = 0x01
347
NIC_LB_PHY              = 0x02    ; MII or Internal-10BaseT loopback
347
NIC_LB_PHY              = 0x02    ; MII or Internal-10BaseT loopback
348
 
348
 
349
PKT_BUF_SZ              = 1536    ; Size of each temporary Rx buffer.
349
PKT_BUF_SZ              = 1536    ; Size of each temporary Rx buffer.
350
 
350
 
351
PCI_REG_MODE3           = 0x53
351
PCI_REG_MODE3           = 0x53
352
MODE3_MIION             = 0x04    ; in PCI_REG_MOD3 OF PCI space
352
MODE3_MIION             = 0x04    ; in PCI_REG_MOD3 OF PCI space
353
 
353
 
354
; VIA Rhine revisions
354
; VIA Rhine revisions
355
VT86C100A       = 0x00
355
VT86C100A       = 0x00
356
VTunknown0      = 0x20
356
VTunknown0      = 0x20
357
VT6102          = 0x40
357
VT6102          = 0x40
358
VT8231          = 0x50 ; Integrated MAC
358
VT8231          = 0x50 ; Integrated MAC
359
VT8233          = 0x60 ; Integrated MAC
359
VT8233          = 0x60 ; Integrated MAC
360
VT8235          = 0x74 ; Integrated MAC
360
VT8235          = 0x74 ; Integrated MAC
361
VT8237          = 0x78 ; Integrated MAC
361
VT8237          = 0x78 ; Integrated MAC
362
VTunknown1      = 0x7C
362
VTunknown1      = 0x7C
363
VT6105          = 0x80
363
VT6105          = 0x80
364
VT6105_B0       = 0x83
364
VT6105_B0       = 0x83
365
VT6105L         = 0x8A
365
VT6105L         = 0x8A
366
VT6107          = 0x8C
366
VT6107          = 0x8C
367
VTunknown2      = 0x8E
367
VTunknown2      = 0x8E
368
VT6105M         = 0x90
368
VT6105M         = 0x90
369
 
369
 
370
; Rx status bits
370
; Rx status bits
371
RX_SBITS_RERR                   = 1 shl 0
371
RX_SBITS_RERR                   = 1 shl 0
372
RX_SBITS_CRC_ERROR              = 1 shl 1
372
RX_SBITS_CRC_ERROR              = 1 shl 1
373
RX_SBITS_FAE                    = 1 shl 2
373
RX_SBITS_FAE                    = 1 shl 2
374
RX_SBITS_FOV                    = 1 shl 3
374
RX_SBITS_FOV                    = 1 shl 3
375
RX_SBITS_TOOLONG                = 1 shl 4
375
RX_SBITS_TOOLONG                = 1 shl 4
376
RX_SBITS_RUNT                   = 1 shl 5
376
RX_SBITS_RUNT                   = 1 shl 5
377
RX_SBITS_SERR                   = 1 shl 6
377
RX_SBITS_SERR                   = 1 shl 6
378
RX_SBITS_BUFF                   = 1 shl 7
378
RX_SBITS_BUFF                   = 1 shl 7
379
RX_SBITS_EDP                    = 1 shl 8
379
RX_SBITS_EDP                    = 1 shl 8
380
RX_SBITS_STP                    = 1 shl 9
380
RX_SBITS_STP                    = 1 shl 9
381
RX_SBITS_CHN                    = 1 shl 10
381
RX_SBITS_CHN                    = 1 shl 10
382
RX_SBITS_PHY                    = 1 shl 11
382
RX_SBITS_PHY                    = 1 shl 11
383
RX_SBITS_BAR                    = 1 shl 12
383
RX_SBITS_BAR                    = 1 shl 12
384
RX_SBITS_MAR                    = 1 shl 13
384
RX_SBITS_MAR                    = 1 shl 13
385
RX_SBITS_RESERVED_1             = 1 shl 14
385
RX_SBITS_RESERVED_1             = 1 shl 14
386
RX_SBITS_RXOK                   = 1 shl 15
386
RX_SBITS_RXOK                   = 1 shl 15
387
RX_SBITS_FRAME_LENGTH           = 0x7FF shl 16
387
RX_SBITS_FRAME_LENGTH           = 0x7FF shl 16
388
RX_SBITS_RESERVED_2             = 0xF shl 27
388
RX_SBITS_RESERVED_2             = 0xF shl 27
389
RX_SBITS_OWN_BIT                = 1 shl 31
389
RX_SBITS_OWN_BIT                = 1 shl 31
390
 
390
 
391
; Rx control bits
391
; Rx control bits
392
RX_CBITS_RX_BUF_SIZE            = 0x7FF
392
RX_CBITS_RX_BUF_SIZE            = 0x7FF
393
RX_CBITS_EXTEND_RX_BUF_SIZE     = 0xF shl 11
393
RX_CBITS_EXTEND_RX_BUF_SIZE     = 0xF shl 11
394
RX_CBITS_RESERVED_1             = 0x1FFFF shl 15
394
RX_CBITS_RESERVED_1             = 0x1FFFF shl 15
395
 
395
 
396
; Tx status bits
396
; Tx status bits
397
TX_SBITS_NCR0                   = 1 shl 0
397
TX_SBITS_NCR0                   = 1 shl 0
398
TX_SBITS_NCR1                   = 1 shl 1
398
TX_SBITS_NCR1                   = 1 shl 1
399
TX_SBITS_NCR2                   = 1 shl 2
399
TX_SBITS_NCR2                   = 1 shl 2
400
TX_SBITS_NCR3                   = 1 shl 3
400
TX_SBITS_NCR3                   = 1 shl 3
401
TX_SBITS_COLS                   = 1 shl 4
401
TX_SBITS_COLS                   = 1 shl 4
402
TX_SBITS_RESERVED_1             = 1 shl 5
402
TX_SBITS_RESERVED_1             = 1 shl 5
403
TX_SBITS_CDH                    = 1 shl 7
403
TX_SBITS_CDH                    = 1 shl 7
404
TX_SBITS_ABT                    = 1 shl 8
404
TX_SBITS_ABT                    = 1 shl 8
405
TX_SBITS_OWC                    = 1 shl 9
405
TX_SBITS_OWC                    = 1 shl 9
406
TX_SBITS_CRS                    = 1 shl 10
406
TX_SBITS_CRS                    = 1 shl 10
407
TX_SBITS_UDF                    = 1 shl 11
407
TX_SBITS_UDF                    = 1 shl 11
408
TX_SBITS_TBUFF                  = 1 shl 12
408
TX_SBITS_TBUFF                  = 1 shl 12
409
TX_SBITS_SERR                   = 1 shl 13
409
TX_SBITS_SERR                   = 1 shl 13
410
TX_SBITS_JAB                    = 1 shl 14
410
TX_SBITS_JAB                    = 1 shl 14
411
TX_SBITS_TERR                   = 1 shl 15
411
TX_SBITS_TERR                   = 1 shl 15
412
TX_SBITS_RESERVED_2             = 0x7FFF shl 16
412
TX_SBITS_RESERVED_2             = 0x7FFF shl 16
413
TX_SBITS_OWN_BIT                = 1 shl 31
413
TX_SBITS_OWN_BIT                = 1 shl 31
414
 
414
 
415
; Tx control bits
415
; Tx control bits
416
TX_CBITS_TX_BUF_SIZE            = 0x7FF
416
TX_CBITS_TX_BUF_SIZE            = 0x7FF
417
TX_CBITS_EXTEND_TX_BUF_SIZE     = 0xF shl 11
417
TX_CBITS_EXTEND_TX_BUF_SIZE     = 0xF shl 11
418
TX_CBITS_CHN                    = 1 shl 15
418
TX_CBITS_CHN                    = 1 shl 15
419
TX_CBITS_CRC                    = 1 shl 16
419
TX_CBITS_CRC                    = 1 shl 16
420
TX_CBITS_RESERVED_1             = 0xF shl 17
420
TX_CBITS_RESERVED_1             = 0xF shl 17
421
TX_CBITS_STP                    = 1 shl 21
421
TX_CBITS_STP                    = 1 shl 21
422
TX_CBITS_EDP                    = 1 shl 22
422
TX_CBITS_EDP                    = 1 shl 22
423
TX_CBITS_IC                     = 1 shl 23
423
TX_CBITS_IC                     = 1 shl 23
424
TX_CBITS_RESERVED_2             = 0xFF shl 24
424
TX_CBITS_RESERVED_2             = 0xFF shl 24
425
 
425
 
426
 
426
 
427
 
427
 
428
; Offsets to the device registers.
428
; Offsets to the device registers.
429
        StationAddr             = 0x00
429
        StationAddr             = 0x00
430
        RxConfig                = 0x06
430
        RxConfig                = 0x06
431
        TxConfig                = 0x07
431
        TxConfig                = 0x07
432
        ChipCmd                 = 0x08
432
        ChipCmd                 = 0x08
433
        IntrStatus              = 0x0C
433
        IntrStatus              = 0x0C
434
        IntrEnable              = 0x0E
434
        IntrEnable              = 0x0E
435
        MulticastFilter0        = 0x10
435
        MulticastFilter0        = 0x10
436
        MulticastFilter1        = 0x14
436
        MulticastFilter1        = 0x14
437
        RxRingPtr               = 0x18
437
        RxRingPtr               = 0x18
438
        TxRingPtr               = 0x1C
438
        TxRingPtr               = 0x1C
439
        GFIFOTest               = 0x54
439
        GFIFOTest               = 0x54
440
        MIIPhyAddr              = 0x6C
440
        MIIPhyAddr              = 0x6C
441
        MIIStatus               = 0x6D
441
        MIIStatus               = 0x6D
442
        PCIBusConfig            = 0x6E
442
        PCIBusConfig            = 0x6E
443
        MIICmd                  = 0x70
443
        MIICmd                  = 0x70
444
        MIIRegAddr              = 0x71
444
        MIIRegAddr              = 0x71
445
        MIIData                 = 0x72
445
        MIIData                 = 0x72
446
        MACRegEEcsr             = 0x74
446
        MACRegEEcsr             = 0x74
447
        ConfigA                 = 0x78
447
        ConfigA                 = 0x78
448
        ConfigB                 = 0x79
448
        ConfigB                 = 0x79
449
        ConfigC                 = 0x7A
449
        ConfigC                 = 0x7A
450
        ConfigD                 = 0x7B
450
        ConfigD                 = 0x7B
451
        RxMissed                = 0x7C
451
        RxMissed                = 0x7C
452
        RxCRCErrs               = 0x7E
452
        RxCRCErrs               = 0x7E
453
        MiscCmd                 = 0x81
453
        MiscCmd                 = 0x81
454
        StickyHW                = 0x83
454
        StickyHW                = 0x83
455
        IntrStatus2             = 0x84
455
        IntrStatus2             = 0x84
456
        WOLcrClr                = 0xA4
456
        WOLcrClr                = 0xA4
457
        WOLcgClr                = 0xA7
457
        WOLcgClr                = 0xA7
458
        PwrcsrClr               = 0xAC
458
        PwrcsrClr               = 0xAC
459
 
459
 
460
; Bits in the interrupt status/mask registers.
460
; Bits in the interrupt status/mask registers.
461
        IntrRxDone              = 0x0001
461
        IntrRxDone              = 0x0001
462
        IntrRxErr               = 0x0004
462
        IntrRxErr               = 0x0004
463
        IntrRxEmpty             = 0x0020
463
        IntrRxEmpty             = 0x0020
464
        IntrTxDone              = 0x0002
464
        IntrTxDone              = 0x0002
465
        IntrTxError             = 0x0008
465
        IntrTxError             = 0x0008
466
        IntrTxUnderrun          = 0x0010
466
        IntrTxUnderrun          = 0x0010
467
        IntrPCIErr              = 0x0040
467
        IntrPCIErr              = 0x0040
468
        IntrStatsMax            = 0x0080
468
        IntrStatsMax            = 0x0080
469
        IntrRxEarly             = 0x0100
469
        IntrRxEarly             = 0x0100
470
        IntrRxOverflow          = 0x0400
470
        IntrRxOverflow          = 0x0400
471
        IntrRxDropped           = 0x0800
471
        IntrRxDropped           = 0x0800
472
        IntrRxNoBuf             = 0x1000
472
        IntrRxNoBuf             = 0x1000
473
        IntrTxAborted           = 0x2000
473
        IntrTxAborted           = 0x2000
474
        IntrLinkChange          = 0x4000
474
        IntrLinkChange          = 0x4000
475
        IntrRxWakeUp            = 0x8000
475
        IntrRxWakeUp            = 0x8000
476
        IntrNormalSummary       = 0x0003
476
        IntrNormalSummary       = 0x0003
477
        IntrAbnormalSummary     = 0xC260
477
        IntrAbnormalSummary     = 0xC260
478
        IntrTxDescRace          = 0x080000        ; mapped from IntrStatus2
478
        IntrTxDescRace          = 0x080000        ; mapped from IntrStatus2
479
        IntrTxErrSummary        = 0x082218
479
        IntrTxErrSummary        = 0x082218
480
 
480
 
481
        DEFAULT_INTR            = (IntrRxDone or IntrRxErr or IntrRxEmpty or IntrRxOverflow or IntrRxDropped or IntrRxNoBuf)
481
        DEFAULT_INTR            = (IntrRxDone or IntrRxErr or IntrRxEmpty or IntrRxOverflow or IntrRxDropped or IntrRxNoBuf)
482
        RX_BUF_LEN              = (8192 shl RX_BUF_LEN_IDX)
482
        RX_BUF_LEN              = (8192 shl RX_BUF_LEN_IDX)
483
 
483
 
484
struct  rx_head
484
struct  rx_head
485
        status          dd ?
485
        status          dd ?
486
        control         dd ?
486
        control         dd ?
487
        buff_addr       dd ?    ; address
487
        buff_addr       dd ?    ; address
488
        next_desc       dd ?    ;
488
        next_desc       dd ?    ;
489
 
489
 
490
        buff_addr_virt  dd ?
490
        buff_addr_virt  dd ?
491
                        rd 3    ; alignment
491
                        rd 3    ; alignment
492
ends
492
ends
493
 
493
 
494
struct  tx_head
494
struct  tx_head
495
        status          dd ?
495
        status          dd ?
496
        control         dd ?
496
        control         dd ?
497
        buff_addr       dd ?    ; address
497
        buff_addr       dd ?    ; address
498
        next_desc       dd ?    ;
498
        next_desc       dd ?    ;
499
 
499
 
500
        buff_addr_virt  dd ?
500
        buff_addr_virt  dd ?
501
                        rd 3    ; alignment
501
                        rd 3    ; alignment
502
ends
502
ends
503
 
503
 
504
struct  device          ETH_DEVICE
504
struct  device          ETH_DEVICE
505
 
505
 
506
        io_addr         dd ?
506
        io_addr         dd ?
507
        pci_dev         dd ?
507
        pci_dev         dd ?
508
        pci_bus         dd ?
508
        pci_bus         dd ?
509
        revision        db ?
509
        revision        db ?
510
        irq_line        db ?
510
        irq_line        db ?
511
        chip_id         dw ?
511
        chip_id         dw ?
512
 
512
 
513
        cur_rx          dw ?
513
        cur_rx          dw ?
514
        cur_tx          dw ?
514
        cur_tx          dw ?
515
        last_tx         dw ?
515
        last_tx         dw ?
516
 
516
 
517
        rb 0x100 - ($ and 0xff) ; align 256
517
        rb 0x100 - ($ and 0xff) ; align 256
518
        tx_ring         rb sizeof.tx_head*TX_RING_SIZE
518
        tx_ring         rb sizeof.tx_head*TX_RING_SIZE
519
 
519
 
520
        rb 0x100 - ($ and 0xff) ; align 256
520
        rb 0x100 - ($ and 0xff) ; align 256
521
        rx_ring         rb sizeof.rx_head*RX_RING_SIZE
521
        rx_ring         rb sizeof.rx_head*RX_RING_SIZE
522
 
522
 
523
ends
523
ends
524
 
524
 
525
 
525
 
526
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
526
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
527
;;                        ;;
527
;;                        ;;
528
;; proc START             ;;
528
;; proc START             ;;
529
;;                        ;;
529
;;                        ;;
530
;; (standard driver proc) ;;
530
;; (standard driver proc) ;;
531
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
531
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
532
 
532
 
533
proc START c, reason:dword, cmdline:dword
533
proc START c, reason:dword, cmdline:dword
534
 
534
 
535
        cmp     [reason], DRV_ENTRY
535
        cmp     [reason], DRV_ENTRY
536
        jne     .fail
536
        jne     .fail
537
 
537
 
538
        DEBUGF  1,"Loading driver\n"
538
        DEBUGF  1,"Loading driver\n"
539
        invoke  RegService, my_service, service_proc
539
        invoke  RegService, my_service, service_proc
540
        ret
540
        ret
541
 
541
 
542
  .fail:
542
  .fail:
543
        xor     eax, eax
543
        xor     eax, eax
544
        ret
544
        ret
545
 
545
 
546
endp
546
endp
547
 
547
 
548
 
548
 
549
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
549
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
550
;;                        ;;
550
;;                        ;;
551
;; proc SERVICE_PROC      ;;
551
;; proc SERVICE_PROC      ;;
552
;;                        ;;
552
;;                        ;;
553
;; (standard driver proc) ;;
553
;; (standard driver proc) ;;
554
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
554
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
555
 
555
 
556
proc service_proc stdcall, ioctl:dword
556
proc service_proc stdcall, ioctl:dword
557
 
557
 
558
        mov     edx, [ioctl]
558
        mov     edx, [ioctl]
559
        mov     eax, [edx + IOCTL.io_code]
559
        mov     eax, [edx + IOCTL.io_code]
560
 
560
 
561
;------------------------------------------------------
561
;------------------------------------------------------
562
 
562
 
563
        cmp     eax, 0 ;SRV_GETVERSION
563
        cmp     eax, 0 ;SRV_GETVERSION
564
        jne     @F
564
        jne     @F
565
 
565
 
566
        cmp     [edx + IOCTL.out_size], 4
566
        cmp     [edx + IOCTL.out_size], 4
567
        jb      .fail
567
        jb      .fail
568
        mov     eax, [edx + IOCTL.output]
568
        mov     eax, [edx + IOCTL.output]
569
        mov     [eax], dword API_VERSION
569
        mov     [eax], dword API_VERSION
570
 
570
 
571
        xor     eax, eax
571
        xor     eax, eax
572
        ret
572
        ret
573
 
573
 
574
;------------------------------------------------------
574
;------------------------------------------------------
575
  @@:
575
  @@:
576
        cmp     eax, 1 ;SRV_HOOK
576
        cmp     eax, 1 ;SRV_HOOK
577
        jne     .fail
577
        jne     .fail
578
 
578
 
579
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
579
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
580
        jb      .fail
580
        jb      .fail
581
 
581
 
582
        mov     eax, [edx + IOCTL.input]
582
        mov     eax, [edx + IOCTL.input]
583
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
583
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
584
        jne     .fail                                   ; other types aren't supported for this card yet
584
        jne     .fail                                   ; other types aren't supported for this card yet
585
 
585
 
586
; check if the device is already listed
586
; check if the device is already listed
587
 
587
 
588
        mov     esi, device_list
588
        mov     esi, device_list
589
        mov     ecx, [devices]
589
        mov     ecx, [devices]
590
        test    ecx, ecx
590
        test    ecx, ecx
591
        jz      .firstdevice
591
        jz      .firstdevice
592
 
592
 
593
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
593
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
594
        mov     ax, [eax+1]                             ;
594
        mov     ax, [eax+1]                             ;
595
  .nextdevice:
595
  .nextdevice:
596
        mov     ebx, [esi]
596
        mov     ebx, [esi]
597
        cmp     al, byte[ebx + device.pci_bus]
597
        cmp     al, byte[ebx + device.pci_bus]
598
        jne     @f
598
        jne     @f
599
        cmp     ah, byte[ebx + device.pci_dev]
599
        cmp     ah, byte[ebx + device.pci_dev]
600
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
600
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
601
       @@:
601
       @@:
602
        add     esi, 4
602
        add     esi, 4
603
        loop    .nextdevice
603
        loop    .nextdevice
604
 
604
 
605
 
605
 
606
; This device doesn't have its own eth_device structure yet, lets create one
606
; This device doesn't have its own eth_device structure yet, lets create one
607
  .firstdevice:
607
  .firstdevice:
608
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
608
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
609
        jae     .fail
609
        jae     .fail
610
 
610
 
611
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
611
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
612
 
612
 
613
; Fill in the direct call addresses into the struct
613
; Fill in the direct call addresses into the struct
614
 
614
 
615
        mov     [ebx + device.reset], reset
615
        mov     [ebx + device.reset], reset
616
        mov     [ebx + device.transmit], transmit
616
        mov     [ebx + device.transmit], transmit
617
        mov     [ebx + device.unload], unload
617
        mov     [ebx + device.unload], unload
618
        mov     [ebx + device.name], my_service
618
        mov     [ebx + device.name], my_service
619
 
619
 
620
; save the pci bus and device numbers
620
; save the pci bus and device numbers
621
 
621
 
622
        mov     eax, [edx + IOCTL.input]
622
        mov     eax, [edx + IOCTL.input]
623
        movzx   ecx, byte[eax+1]
623
        movzx   ecx, byte[eax+1]
624
        mov     [ebx + device.pci_bus], ecx
624
        mov     [ebx + device.pci_bus], ecx
625
        movzx   ecx, byte[eax+2]
625
        movzx   ecx, byte[eax+2]
626
        mov     [ebx + device.pci_dev], ecx
626
        mov     [ebx + device.pci_dev], ecx
627
 
627
 
628
; Now, it's time to find the base io address of the PCI device
628
; Now, it's time to find the base io address of the PCI device
629
 
629
 
630
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
630
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
631
        mov     [ebx + device.io_addr], eax
631
        mov     [ebx + device.io_addr], eax
632
 
632
 
633
; We've found the io address, find IRQ now
633
; We've found the io address, find IRQ now
634
 
634
 
635
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
635
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
636
        mov     [ebx + device.irq_line], al
636
        mov     [ebx + device.irq_line], al
637
 
637
 
638
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
638
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
639
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
639
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4
640
 
640
 
641
; Ok, the eth_device structure is ready, let's probe the device
641
; Ok, the eth_device structure is ready, let's probe the device
642
        call    probe                                                   ; this function will output in eax
642
        call    probe                                                   ; this function will output in eax
643
        test    eax, eax
643
        test    eax, eax
644
        jnz     .err                                                    ; If an error occurred, exit
644
        jnz     .err                                                    ; If an error occurred, exit
645
 
645
 
646
        mov     eax, [devices]                                          ; Add the device structure to our device list
646
        mov     eax, [devices]                                          ; Add the device structure to our device list
647
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
647
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
648
        inc     [devices]                                               ;
648
        inc     [devices]                                               ;
649
 
649
 
650
        mov     [ebx + device.type], NET_TYPE_ETH
650
        mov     [ebx + device.type], NET_TYPE_ETH
651
        invoke  NetRegDev
651
        invoke  NetRegDev
652
 
652
 
653
        cmp     eax, -1
653
        cmp     eax, -1
654
        je      .destroy
654
        je      .destroy
655
 
655
 
656
        ret
656
        ret
657
 
657
 
658
; If the device was already loaded, find the device number and return it in eax
658
; If the device was already loaded, find the device number and return it in eax
659
 
659
 
660
  .find_devicenum:
660
  .find_devicenum:
661
        DEBUGF  1,"Trying to find device number of already registered device\n"
661
        DEBUGF  1,"Trying to find device number of already registered device\n"
662
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
662
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
663
                                                                        ; into a device number in edi
663
                                                                        ; into a device number in edi
664
        mov     eax, edi                                                ; Application wants it in eax instead
664
        mov     eax, edi                                                ; Application wants it in eax instead
665
        DEBUGF  1,"Kernel says: %u\n", eax
665
        DEBUGF  1,"Kernel says: %u\n", eax
666
        ret
666
        ret
667
 
667
 
668
; If an error occurred, remove all allocated data and exit (returning -1 in eax)
668
; If an error occurred, remove all allocated data and exit (returning -1 in eax)
669
 
669
 
670
  .destroy:
670
  .destroy:
671
        ; todo: reset device into virgin state
671
        ; todo: reset device into virgin state
672
 
672
 
673
  .err:
673
  .err:
674
        invoke  KernelFree, ebx
674
        invoke  KernelFree, ebx
675
 
675
 
676
  .fail:
676
  .fail:
677
        or      eax, -1
677
        or      eax, -1
678
        ret
678
        ret
679
 
679
 
680
;------------------------------------------------------
680
;------------------------------------------------------
681
endp
681
endp
682
 
682
 
683
 
683
 
684
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
684
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
685
;;                                                                        ;;
685
;;                                                                        ;;
686
;;        Actual Hardware dependent code starts here                      ;;
686
;;        Actual Hardware dependent code starts here                      ;;
687
;;                                                                        ;;
687
;;                                                                        ;;
688
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
688
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
689
 
689
 
690
 
690
 
691
;-------
691
;-------
692
;
692
;
693
; PROBE
693
; PROBE
694
;
694
;
695
;-------
695
;-------
696
probe:
696
probe:
697
 
697
 
698
        DEBUGF  1, "Probing\n"
698
        DEBUGF  1, "Probing\n"
699
 
699
 
700
 
700
 
701
; Make the device a bus master
701
; Make the device a bus master
702
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
702
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
703
        or      al, PCI_CMD_MASTER
703
        or      al, PCI_CMD_MASTER
704
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
704
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
705
 
705
 
706
; get device id
706
; get device id
707
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.device_id
707
        invoke  PciRead16, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.device_id
708
        mov     [ebx + device.chip_id], ax
708
        mov     [ebx + device.chip_id], ax
709
 
709
 
710
        mov     esi, chiplist
710
        mov     esi, chiplist
711
  .loop:
711
  .loop:
712
        cmp     word[esi+2], ax
712
        cmp     word[esi+2], ax
713
        je      .got_it
713
        je      .got_it
714
        add     esi, 8
714
        add     esi, 8
715
        cmp     esi, chiplist + 6*8
715
        cmp     esi, chiplist + 6*8
716
        jbe     .loop
716
        jbe     .loop
717
        DEBUGF  2, "Unknown chip: 0x%x, continuing anyway\n", ax
717
        DEBUGF  2, "Unknown chip: 0x%x, continuing anyway\n", ax
718
        jmp     .done
718
        jmp     .done
719
  .got_it:
719
  .got_it:
720
        mov     eax, dword[esi+4]
720
        mov     eax, dword[esi+4]
721
        mov     [ebx + device.name], eax
721
        mov     [ebx + device.name], eax
722
        DEBUGF  1, "Chip type = %s\n", eax
722
        DEBUGF  1, "Chip type = %s\n", eax
723
  .done:
723
  .done:
724
 
724
 
725
; get revision id.
725
; get revision id.
726
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.revision_id
726
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.revision_id
727
        mov     [ebx + device.revision], al
727
        mov     [ebx + device.revision], al
728
 
728
 
729
        movzx   eax, [ebx + device.revision]
729
        movzx   eax, [ebx + device.revision]
730
        DEBUGF  1, "Card revision = 0x%x\n", eax
730
        DEBUGF  1, "Card revision = 0x%x\n", eax
731
 
731
 
732
; D-Link provided reset code (with comment additions)
732
; D-Link provided reset code (with comment additions)
733
        cmp     al, 0x40
733
        cmp     al, 0x40
734
        jb      .below_x40
734
        jb      .below_x40
735
 
735
 
736
        mov     ax, [ebx + device.chip_id]
736
        mov     ax, [ebx + device.chip_id]
737
        DEBUGF  1, "Enabling Sticky Bit Workaround for Chip_id: 0x%x\n", ax
737
        DEBUGF  1, "Enabling Sticky Bit Workaround for Chip_id: 0x%x\n", ax
738
 
738
 
739
        ; clear sticky bit before reset & read ethernet address
739
        ; clear sticky bit before reset & read ethernet address
740
        set_io  [ebx + device.io_addr], 0
740
        set_io  [ebx + device.io_addr], 0
741
        set_io  [ebx + device.io_addr], bySTICKHW
741
        set_io  [ebx + device.io_addr], bySTICKHW
742
        in      al, dx
742
        in      al, dx
743
        and     al, 0xFC
743
        and     al, 0xFC
744
        out     dx, al
744
        out     dx, al
745
 
745
 
746
        ; (bits written are cleared?)
746
        ; (bits written are cleared?)
747
        ; disable force PME-enable
747
        ; disable force PME-enable
748
        set_io  [ebx + device.io_addr], byWOLcgClr
748
        set_io  [ebx + device.io_addr], byWOLcgClr
749
        mov     al, 0x80
749
        mov     al, 0x80
750
        out     dx, al
750
        out     dx, al
751
 
751
 
752
        ; disable power-event config bit
752
        ; disable power-event config bit
753
        mov     al, 0xFF
753
        mov     al, 0xFF
754
        out     dx, al
754
        out     dx, al
755
 
755
 
756
        ; clear power status (undocumented in vt6102 docs?)
756
        ; clear power status (undocumented in vt6102 docs?)
757
        set_io  [ebx + device.io_addr], byPwrcsrClr
757
        set_io  [ebx + device.io_addr], byPwrcsrClr
758
        out     dx, al
758
        out     dx, al
759
 
759
 
760
  .below_x40:
760
  .below_x40:
761
 
761
 
762
; Reset the chip to erase previous misconfiguration.
762
; Reset the chip to erase previous misconfiguration.
763
        set_io  [ebx + device.io_addr], 0
763
        set_io  [ebx + device.io_addr], 0
764
        set_io  [ebx + device.io_addr], byCR0
764
        set_io  [ebx + device.io_addr], byCR0
765
        mov     ax, CR_SFRST
765
        mov     ax, CR_SFRST
766
        out     dx, ax
766
        out     dx, ax
767
 
767
 
768
; if vt3043 delay after reset
768
; if vt3043 delay after reset
769
        cmp     [ebx + device.revision], 0x40
769
        cmp     [ebx + device.revision], 0x40
770
        jae     @f
770
        jae     @f
771
        mov     esi, 200 ; 2000ms
771
        mov     esi, 200 ; 2000ms
772
        invoke  Sleep
772
        invoke  Sleep
773
   @@:
773
   @@:
774
 
774
 
775
; polling till software reset complete
775
; polling till software reset complete
776
        mov     ecx, W_MAX_TIMEOUT
776
        mov     ecx, W_MAX_TIMEOUT
777
   .poll_again:
777
   .poll_again:
778
        in      ax, dx
778
        in      ax, dx
779
        test    ax, CR_SFRST
779
        test    ax, CR_SFRST
780
        jz      @f
780
        jz      @f
781
        loop    .poll_again
781
        loop    .poll_again
782
        DEBUGF  1, "Soft reset timeout!\n"
782
        DEBUGF  1, "Soft reset timeout!\n"
783
   @@:
783
   @@:
784
 
784
 
785
; issue AUTOLoad in EECSR to reload eeprom
785
; issue AUTOLoad in EECSR to reload eeprom
786
        set_io  [ebx + device.io_addr], byEECSR
786
        set_io  [ebx + device.io_addr], byEECSR
787
        mov     al, 0x20
787
        mov     al, 0x20
788
        out     dx, al
788
        out     dx, al
789
 
789
 
790
; if vt3065 delay after reset
790
; if vt3065 delay after reset
791
        cmp     [ebx + device.revision], 0x40
791
        cmp     [ebx + device.revision], 0x40
792
        jb      .not_vt3065
792
        jb      .not_vt3065
793
 
793
 
794
        ; delay 10ms to let MAC stable
794
        ; delay 10ms to let MAC stable
795
        mov     esi, 1 ; 10ms
795
        mov     esi, 1 ; 10ms
796
        invoke  Sleep
796
        invoke  Sleep
797
 
797
 
798
        ; for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
798
        ; for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
799
        ; turned on.  it makes MAC receive magic packet
799
        ; turned on.  it makes MAC receive magic packet
800
        ; automatically. So, we turn it off. (D-Link)
800
        ; automatically. So, we turn it off. (D-Link)
801
 
801
 
802
        set_io  [ebx + device.io_addr], byCFGA
802
        set_io  [ebx + device.io_addr], byCFGA
803
        in      al, dx
803
        in      al, dx
804
        and     al, 0xFE
804
        and     al, 0xFE
805
        out     dx, al
805
        out     dx, al
806
 
806
 
807
        ; turn on bit2 in PCI configuration register 0x53 , only for 3065
807
        ; turn on bit2 in PCI configuration register 0x53 , only for 3065
808
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_REG_MODE3
808
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_REG_MODE3
809
        or      al, MODE3_MIION
809
        or      al, MODE3_MIION
810
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_REG_MODE3, eax
810
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_REG_MODE3, eax
811
  .not_vt3065:
811
  .not_vt3065:
812
 
812
 
813
; back off algorithm, disable the right-most 4-bit off CFGD
813
; back off algorithm, disable the right-most 4-bit off CFGD
814
        set_io  [ebx + device.io_addr], 0
814
        set_io  [ebx + device.io_addr], 0
815
        set_io  [ebx + device.io_addr], byCFGD
815
        set_io  [ebx + device.io_addr], byCFGD
816
        in      al, dx
816
        in      al, dx
817
        and     al, not (CFGD_RANDOM or CFGD_CFDX or CFGD_CEREN or CFGD_CETEN)
817
        and     al, not (CFGD_RANDOM or CFGD_CFDX or CFGD_CEREN or CFGD_CETEN)
818
        out     dx, al
818
        out     dx, al
819
 
819
 
820
; reload eeprom
820
; reload eeprom
821
        call    reload_eeprom
821
        call    reload_eeprom
822
 
822
 
823
; read MAC
823
; read MAC
824
        call    read_mac
824
        call    read_mac
825
 
825
 
826
; restart MII auto-negotiation
826
; restart MII auto-negotiation
827
        stdcall WriteMII, 0, 1 shl 9, 1
827
        stdcall WriteMII, 0, 1 shl 9, 1
828
 
828
 
829
        DEBUGF  1, "Analyzing Media type, this may take several seconds"
829
        DEBUGF  1, "Analyzing Media type, this may take several seconds"
830
 
830
 
831
        mov     ecx, 5
831
        mov     ecx, 5
832
     .read_again:
832
     .read_again:
833
        mov     esi, 1
833
        mov     esi, 1
834
        invoke  Sleep
834
        invoke  Sleep
835
 
835
 
836
        stdcall ReadMII, 1
836
        stdcall ReadMII, 1
837
        test    eax, 0x0020
837
        test    eax, 0x0020
838
        jnz     .read_done
838
        jnz     .read_done
839
        loop    .read_again
839
        loop    .read_again
840
        DEBUGF  1, "timeout!\n"
840
        DEBUGF  1, "timeout!\n"
841
     .read_done:
841
     .read_done:
842
        DEBUGF  1, "OK\n"
842
        DEBUGF  1, "OK\n"
843
 
843
 
844
if 0
844
if 0
845
 
845
 
846
        set_io  [ebx + device.io_addr], 0
846
        set_io  [ebx + device.io_addr], 0
847
        set_io  [ebx + device.io_addr], 0x6C
847
        set_io  [ebx + device.io_addr], 0x6C
848
        in      al, dx
848
        in      al, dx
849
        and     eax, 0xFF
849
        and     eax, 0xFF
850
        DEBUGF  1, "MII : Address %x\n", ax
850
        DEBUGF  1, "MII : Address %x\n", ax
851
 
851
 
852
        stdcall ReadMII, 1
852
        stdcall ReadMII, 1
853
        DEBUGF  1, "status 0x%x\n", ax
853
        DEBUGF  1, "status 0x%x\n", ax
854
 
854
 
855
        stdcall ReadMII, 4
855
        stdcall ReadMII, 4
856
        DEBUGF  1, "advertising 0x%x\n", ax
856
        DEBUGF  1, "advertising 0x%x\n", ax
857
 
857
 
858
        stdcall ReadMII, 5
858
        stdcall ReadMII, 5
859
        DEBUGF  1, "link 0x%x\n", ax
859
        DEBUGF  1, "link 0x%x\n", ax
860
 
860
 
861
end if
861
end if
862
 
862
 
863
; query MII to know LineSpeed, duplex mode
863
; query MII to know LineSpeed, duplex mode
864
        set_io  [ebx + device.io_addr], 0
864
        set_io  [ebx + device.io_addr], 0
865
        set_io  [ebx + device.io_addr], MIIStatus
865
        set_io  [ebx + device.io_addr], MIIStatus
866
        in      al, dx
866
        in      al, dx
867
        test    al, MIISR_SPEED
867
        test    al, MIISR_SPEED
868
        jz      .100mbps
868
        jz      .100mbps
869
        DEBUGF  1, "Linespeed=10Mbs\n"
869
        DEBUGF  1, "Linespeed=10Mbs\n"
870
        jmp     @f
870
        jmp     @f
871
 
871
 
872
    .100mbps:
872
    .100mbps:
873
        DEBUGF  1, "Linespeed=100Mbs\n"
873
        DEBUGF  1, "Linespeed=100Mbs\n"
874
    @@:
874
    @@:
875
 
875
 
876
        call    QueryAuto
876
        call    QueryAuto
877
 
877
 
878
        test    eax, 1
878
        test    eax, 1
879
        jz      .halfduplex
879
        jz      .halfduplex
880
 
880
 
881
        DEBUGF  1, "Fullduplex\n"
881
        DEBUGF  1, "Fullduplex\n"
882
        set_io  [ebx + device.io_addr], 0
882
        set_io  [ebx + device.io_addr], 0
883
        set_io  [ebx + device.io_addr], byCR0
883
        set_io  [ebx + device.io_addr], byCR0
884
        mov     ax, CR_FDX
884
        mov     ax, CR_FDX
885
        out     dx, ax
885
        out     dx, ax
886
        jmp     @f
886
        jmp     @f
887
 
887
 
888
    .halfduplex:
888
    .halfduplex:
889
        DEBUGF  1, "Halfduplex\n"
889
        DEBUGF  1, "Halfduplex\n"
890
    @@:
890
    @@:
891
 
891
 
892
; set MII 10 FULL ON, only apply in vt3043
892
; set MII 10 FULL ON, only apply in vt3043
893
        cmp     [ebx + device.chip_id], 0x3043
893
        cmp     [ebx + device.chip_id], 0x3043
894
        jne     @f
894
        jne     @f
895
        stdcall WriteMII, 0x17, 1 shl 1, 1
895
        stdcall WriteMII, 0x17, 1 shl 1, 1
896
    @@:
896
    @@:
897
 
897
 
898
; turn on MII link change
898
; turn on MII link change
899
        set_io  [ebx + device.io_addr], 0
899
        set_io  [ebx + device.io_addr], 0
900
        set_io  [ebx + device.io_addr], byMIICR
900
        set_io  [ebx + device.io_addr], byMIICR
901
        in      al, dx
901
        in      al, dx
902
        and     al, 0x7F
902
        and     al, 0x7F
903
        out     dx, al
903
        out     dx, al
904
        push    eax
904
        push    eax
905
 
905
 
906
        call    MIIDelay
906
        call    MIIDelay
907
 
907
 
908
        set_io  [ebx + device.io_addr], byMIIAD
908
        set_io  [ebx + device.io_addr], byMIIAD
909
        mov     al, 0x41
909
        mov     al, 0x41
910
        out     dx, al
910
        out     dx, al
911
 
911
 
912
        call    MIIDelay
912
        call    MIIDelay
913
 
913
 
914
        pop     eax
914
        pop     eax
915
        or      al, 0x80
915
        or      al, 0x80
916
        set_io  [ebx + device.io_addr], byMIICR
916
        set_io  [ebx + device.io_addr], byMIICR
917
        out     dx, al
917
        out     dx, al
918
 
918
 
919
;**************************************************************************;
919
;**************************************************************************;
920
;* ETH_RESET - Reset adapter                                              *;
920
;* ETH_RESET - Reset adapter                                              *;
921
;**************************************************************************;
921
;**************************************************************************;
922
 
922
 
923
reset:
923
reset:
924
 
924
 
925
        DEBUGF  1, "reset\n"
925
        DEBUGF  1, "reset\n"
926
 
926
 
927
; attach int handler
927
; attach int handler
928
        movzx   eax, [ebx + device.irq_line]
928
        movzx   eax, [ebx + device.irq_line]
929
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
929
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
930
        invoke  AttachIntHandler, eax, int_handler, ebx
930
        invoke  AttachIntHandler, eax, int_handler, ebx
931
        test    eax, eax
931
        test    eax, eax
932
        jnz     @f
932
        jnz     @f
933
        DEBUGF  2,"Could not attach int handler!\n"
933
        DEBUGF  2,"Could not attach int handler!\n"
934
        or      eax, -1
934
        or      eax, -1
935
        ret
935
        ret
936
       @@:
936
       @@:
937
 
937
 
938
; Soft reset the chip.
938
; Soft reset the chip.
939
        set_io  [ebx + device.io_addr], 0
939
        set_io  [ebx + device.io_addr], 0
940
        set_io  [ebx + device.io_addr], byCR0
940
        set_io  [ebx + device.io_addr], byCR0
941
        mov     ax, CR_SFRST
941
        mov     ax, CR_SFRST
942
        out     dx, ax
942
        out     dx, ax
943
 
943
 
944
        call    MIIDelay
944
        call    MIIDelay
945
 
945
 
946
; Initialize rings
946
; Initialize rings
947
        call    init_ring
947
        call    init_ring
948
 
948
 
949
; Set Multicast
949
; Set Multicast
950
        call    set_rx_mode
950
        call    set_rx_mode
951
 
951
 
952
; set TCR RCR threshold to store and forward
952
; set TCR RCR threshold to store and forward
953
        set_io  [ebx + device.io_addr], 0
953
        set_io  [ebx + device.io_addr], 0
954
        set_io  [ebx + device.io_addr], byBCR0
954
        set_io  [ebx + device.io_addr], byBCR0
955
        mov     al, 0x3E
955
        mov     al, 0x3E
956
        out     dx, al
956
        out     dx, al
957
 
957
 
958
        set_io  [ebx + device.io_addr], byBCR1
958
        set_io  [ebx + device.io_addr], byBCR1
959
        mov     al, 0x38
959
        mov     al, 0x38
960
        out     dx, al
960
        out     dx, al
961
 
961
 
962
        set_io  [ebx + device.io_addr], byRCR
962
        set_io  [ebx + device.io_addr], byRCR
963
        mov     al, 0x2C
963
        mov     al, 0x2C
964
        out     dx, al
964
        out     dx, al
965
 
965
 
966
        set_io  [ebx + device.io_addr], byTCR
966
        set_io  [ebx + device.io_addr], byTCR
967
        mov     al, 0x60
967
        mov     al, 0x60
968
        out     dx, al
968
        out     dx, al
969
 
969
 
970
; Set Fulldupex
970
; Set Fulldupex
971
 
971
 
972
        call    QueryAuto
972
        call    QueryAuto
973
        test    eax, eax        ; full duplex?
973
        test    eax, eax        ; full duplex?
974
        jz      @f
974
        jz      @f
975
 
975
 
976
        set_io  [ebx + device.io_addr], 0
976
        set_io  [ebx + device.io_addr], 0
977
        set_io  [ebx + device.io_addr], byCFGD
977
        set_io  [ebx + device.io_addr], byCFGD
978
        mov     al, CFGD_CFDX
978
        mov     al, CFGD_CFDX
979
        out     dx, al
979
        out     dx, al
980
 
980
 
981
        set_io  [ebx + device.io_addr], byCR0
981
        set_io  [ebx + device.io_addr], byCR0
982
        mov     ax, CR_FDX
982
        mov     ax, CR_FDX
983
        out     dx, ax
983
        out     dx, ax
984
    @@:
984
    @@:
985
 
985
 
986
; ENABLE interrupts
986
; ENABLE interrupts
987
        set_io  [ebx + device.io_addr], 0
987
        set_io  [ebx + device.io_addr], 0
988
        set_io  [ebx + device.io_addr], byIMR0
988
        set_io  [ebx + device.io_addr], byIMR0
989
        mov     ax, DEFAULT_INTR
989
        mov     ax, DEFAULT_INTR
990
        out     dx, ax
990
        out     dx, ax
991
 
991
 
992
; KICK NIC to WORK
992
; KICK NIC to WORK
993
 
993
 
994
        set_io  [ebx + device.io_addr], byCR0
994
        set_io  [ebx + device.io_addr], byCR0
995
        in      ax, dx
995
        in      ax, dx
996
        and     ax, not CR_STOP
996
        and     ax, not CR_STOP
997
        or      ax, CR_STRT or CR_TXON or CR_RXON or CR_DPOLL
997
        or      ax, CR_STRT or CR_TXON or CR_RXON or CR_DPOLL
998
        out     dx, ax
998
        out     dx, ax
999
 
999
 
1000
; Set the mtu, kernel will be able to send now
1000
; Set the mtu, kernel will be able to send now
1001
        mov     [ebx + device.mtu], 1514
1001
        mov     [ebx + device.mtu], 1514
1002
 
1002
 
1003
; Set link state to unknown
1003
; Set link state to unknown
1004
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
1004
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
1005
 
1005
 
1006
; say reset was successful
1006
; say reset was successful
1007
        xor     eax, eax
1007
        xor     eax, eax
1008
        ret
1008
        ret
1009
 
1009
 
1010
 
1010
 
1011
 
1011
 
1012
align 4
1012
align 4
1013
unload:
1013
unload:
1014
 
1014
 
1015
        call    reset
1015
        call    reset
1016
        push    eax edx
1016
        push    eax edx
1017
        DEBUGF  1, "rhine disable\n"
1017
        DEBUGF  1, "rhine disable\n"
1018
 
1018
 
1019
        ; Switch to loopback mode to avoid hardware races.
1019
        ; Switch to loopback mode to avoid hardware races.
1020
        set_io  [ebx + device.io_addr], 0
1020
        set_io  [ebx + device.io_addr], 0
1021
        set_io  [ebx + device.io_addr], byTCR
1021
        set_io  [ebx + device.io_addr], byTCR
1022
        mov     al, 0x61
1022
        mov     al, 0x61
1023
        out     dx, al
1023
        out     dx, al
1024
 
1024
 
1025
        ; Stop the chip's Tx and Rx processes.
1025
        ; Stop the chip's Tx and Rx processes.
1026
        set_io  [ebx + device.io_addr], byCR0
1026
        set_io  [ebx + device.io_addr], byCR0
1027
        mov     ax, CR_STOP
1027
        mov     ax, CR_STOP
1028
        out     dx, ax
1028
        out     dx, ax
1029
        pop     edx eax
1029
        pop     edx eax
1030
 
1030
 
1031
        ret
1031
        ret
1032
 
1032
 
1033
 
1033
 
1034
 
1034
 
1035
 
1035
 
1036
align 4
1036
align 4
1037
reload_eeprom:
1037
reload_eeprom:
1038
 
1038
 
1039
        DEBUGF  1, "Reload eeprom\n"
1039
        DEBUGF  1, "Reload eeprom\n"
1040
 
1040
 
1041
        set_io  [ebx + device.io_addr], 0
1041
        set_io  [ebx + device.io_addr], 0
1042
        set_io  [ebx + device.io_addr], byEECSR
1042
        set_io  [ebx + device.io_addr], byEECSR
1043
        mov     al, 0x20
1043
        mov     al, 0x20
1044
        out     dx, al
1044
        out     dx, al
1045
        ; Typically 2 cycles to reload.
1045
        ; Typically 2 cycles to reload.
1046
        mov     ecx, 150
1046
        mov     ecx, 150
1047
  .reload:
1047
  .reload:
1048
        in      al, dx
1048
        in      al, dx
1049
        test    al, 0x20
1049
        test    al, 0x20
1050
        jz      @f
1050
        jz      @f
1051
        loop    .reload
1051
        loop    .reload
1052
        DEBUGF  2, "Reload eeprom: timeout!\n"
1052
        DEBUGF  2, "Reload eeprom: timeout!\n"
1053
  @@:
1053
  @@:
1054
 
1054
 
1055
        ret
1055
        ret
1056
 
1056
 
1057
 
1057
 
1058
 
1058
 
1059
; Initialize the Rx and Tx rings, along with various 'dev' bits.
1059
; Initialize the Rx and Tx rings, along with various 'dev' bits.
1060
align 4
1060
align 4
1061
init_ring:
1061
init_ring:
1062
 
1062
 
1063
        DEBUGF  1, "Init ring\n"
1063
        DEBUGF  1, "Init ring\n"
1064
 
1064
 
1065
        lea     edi, [ebx + device.rx_ring]
1065
        lea     edi, [ebx + device.rx_ring]
1066
        mov     eax, edi
1066
        mov     eax, edi
1067
        invoke  GetPhysAddr
1067
        invoke  GetPhysAddr
1068
        mov     esi, eax
1068
        mov     esi, eax
1069
        push    esi
1069
        push    esi
1070
        mov     ecx, RX_RING_SIZE
1070
        mov     ecx, RX_RING_SIZE
1071
   .rx_init:
1071
   .rx_init:
1072
        add     esi, sizeof.rx_head
1072
        add     esi, sizeof.rx_head
1073
        mov     [edi + rx_head.status], RX_SBITS_OWN_BIT
1073
        mov     [edi + rx_head.status], RX_SBITS_OWN_BIT
1074
        mov     [edi + rx_head.control], PKT_BUF_SZ
1074
        mov     [edi + rx_head.control], PKT_BUF_SZ
1075
        push    ecx
1075
        push    ecx
1076
        invoke  KernelAlloc, PKT_BUF_SZ
1076
        invoke  KernelAlloc, PKT_BUF_SZ
1077
        pop     ecx
1077
        pop     ecx
1078
        mov     [edi + rx_head.buff_addr_virt], eax
1078
        mov     [edi + rx_head.buff_addr_virt], eax
1079
        invoke  GetPhysAddr
1079
        invoke  GetPhysAddr
1080
        mov     [edi + rx_head.buff_addr], eax                        ; buffer ptr
1080
        mov     [edi + rx_head.buff_addr], eax                        ; buffer ptr
1081
        mov     [edi + rx_head.next_desc], esi                        ; next head
1081
        mov     [edi + rx_head.next_desc], esi                        ; next head
1082
        add     edi, sizeof.rx_head
1082
        add     edi, sizeof.rx_head
1083
        dec     ecx
1083
        dec     ecx
1084
        jnz     .rx_init
1084
        jnz     .rx_init
1085
        pop     [edi - sizeof.rx_head + rx_head.next_desc]            ; Mark the last entry as wrapping the ring.
1085
        pop     [edi - sizeof.rx_head + rx_head.next_desc]            ; Mark the last entry as wrapping the ring.
1086
 
1086
 
1087
 
1087
 
1088
        lea     edi, [ebx + device.tx_ring]
1088
        lea     edi, [ebx + device.tx_ring]
1089
        mov     eax, edi
1089
        mov     eax, edi
1090
        invoke  GetPhysAddr
1090
        invoke  GetPhysAddr
1091
        mov     esi, eax
1091
        mov     esi, eax
1092
        push    esi
1092
        push    esi
1093
        mov     ecx, TX_RING_SIZE
1093
        mov     ecx, TX_RING_SIZE
1094
   .tx_init:
1094
   .tx_init:
1095
        add     esi, sizeof.tx_head
1095
        add     esi, sizeof.tx_head
1096
        mov     [edi + tx_head.status], 0
1096
        mov     [edi + tx_head.status], 0
1097
        mov     [edi + tx_head.control], 0x00E08000
1097
        mov     [edi + tx_head.control], 0x00E08000
1098
        mov     [edi + tx_head.buff_addr], 0
1098
        mov     [edi + tx_head.buff_addr], 0
1099
        mov     [edi + tx_head.next_desc], esi
1099
        mov     [edi + tx_head.next_desc], esi
1100
        mov     [edi + tx_head.buff_addr_virt], 0
1100
        mov     [edi + tx_head.buff_addr_virt], 0
1101
        add     edi, sizeof.tx_head
1101
        add     edi, sizeof.tx_head
1102
        dec     ecx
1102
        dec     ecx
1103
        jnz     .tx_init
1103
        jnz     .tx_init
1104
        pop     [edi - sizeof.tx_head + tx_head.next_desc]              ; Mark the last entry as wrapping the ring.
1104
        pop     [edi - sizeof.tx_head + tx_head.next_desc]              ; Mark the last entry as wrapping the ring.
1105
 
1105
 
1106
; write Descriptors to MAC
1106
; write Descriptors to MAC
1107
        lea     eax, [ebx + device.rx_ring]
1107
        lea     eax, [ebx + device.rx_ring]
1108
        invoke  GetPhysAddr
1108
        invoke  GetPhysAddr
1109
        set_io  [ebx + device.io_addr], 0
1109
        set_io  [ebx + device.io_addr], 0
1110
        set_io  [ebx + device.io_addr], dwCurrentRxDescAddr
1110
        set_io  [ebx + device.io_addr], dwCurrentRxDescAddr
1111
        out     dx, eax
1111
        out     dx, eax
1112
 
1112
 
1113
        lea     eax, [ebx + device.tx_ring]
1113
        lea     eax, [ebx + device.tx_ring]
1114
        invoke  GetPhysAddr
1114
        invoke  GetPhysAddr
1115
        set_io  [ebx + device.io_addr], dwCurrentTxDescAddr
1115
        set_io  [ebx + device.io_addr], dwCurrentTxDescAddr
1116
        out     dx, eax
1116
        out     dx, eax
1117
 
1117
 
1118
        xor     eax, eax
1118
        xor     eax, eax
1119
        mov     [ebx + device.cur_rx], ax
1119
        mov     [ebx + device.cur_rx], ax
1120
        mov     [ebx + device.cur_tx], ax
1120
        mov     [ebx + device.cur_tx], ax
1121
        mov     [ebx + device.last_tx], ax
1121
        mov     [ebx + device.last_tx], ax
1122
 
1122
 
1123
        ret
1123
        ret
1124
 
1124
 
1125
 
1125
 
1126
align 4
1126
align 4
1127
QueryAuto:
1127
QueryAuto:
1128
 
1128
 
1129
        DEBUGF  1, "Query Auto\n"
1129
        DEBUGF  1, "Query Auto\n"
1130
 
1130
 
1131
        push    ecx
1131
        push    ecx
1132
        stdcall ReadMII, 0x04   ; advertised
1132
        stdcall ReadMII, 0x04   ; advertised
1133
        mov     ecx, eax
1133
        mov     ecx, eax
1134
        stdcall ReadMII, 0x05
1134
        stdcall ReadMII, 0x05
1135
        and     ecx, eax
1135
        and     ecx, eax
1136
 
1136
 
1137
        xor     eax, eax
1137
        xor     eax, eax
1138
        test    ecx, 0x100
1138
        test    ecx, 0x100
1139
        jnz     .one
1139
        jnz     .one
1140
 
1140
 
1141
        and     ecx, 0x1C0
1141
        and     ecx, 0x1C0
1142
        cmp     ecx, 0x40
1142
        cmp     ecx, 0x40
1143
        jne     .zero
1143
        jne     .zero
1144
   .one:
1144
   .one:
1145
        inc     eax
1145
        inc     eax
1146
        DEBUGF  1, "AutoNego OK!\n"
1146
        DEBUGF  1, "AutoNego OK!\n"
1147
   .zero:
1147
   .zero:
1148
        pop     ecx
1148
        pop     ecx
1149
 
1149
 
1150
        ret
1150
        ret
1151
 
1151
 
1152
 
1152
 
1153
proc    ReadMII stdcall, byMIIIndex:dword
1153
proc    ReadMII stdcall, byMIIIndex:dword
1154
 
1154
 
1155
;        DEBUGF  1, "ReadMII Index=%x\n", [byMIIIndex]
1155
;        DEBUGF  1, "ReadMII Index=%x\n", [byMIIIndex]
1156
 
1156
 
1157
        push    esi ebx ecx edx
1157
        push    esi ebx ecx edx
1158
 
1158
 
1159
        set_io  [ebx + device.io_addr], 0
1159
        set_io  [ebx + device.io_addr], 0
1160
        set_io  [ebx + device.io_addr], byMIIAD
1160
        set_io  [ebx + device.io_addr], byMIIAD
1161
        in      al, dx
1161
        in      al, dx
1162
        mov     bl, al
1162
        mov     bl, al
1163
 
1163
 
1164
        set_io  [ebx + device.io_addr], byMIICR
1164
        set_io  [ebx + device.io_addr], byMIICR
1165
        in      al, dx
1165
        in      al, dx
1166
        mov     bh, al
1166
        mov     bh, al
1167
        and     al, 0x7F
1167
        and     al, 0x7F
1168
        out     dx, al
1168
        out     dx, al
1169
 
1169
 
1170
        call    MIIDelay
1170
        call    MIIDelay
1171
 
1171
 
1172
        mov     al, byte [byMIIIndex]
1172
        mov     al, byte [byMIIIndex]
1173
        set_io  [ebx + device.io_addr], byMIIAD
1173
        set_io  [ebx + device.io_addr], byMIIAD
1174
        out     dx, al
1174
        out     dx, al
1175
 
1175
 
1176
        call    MIIDelay
1176
        call    MIIDelay
1177
 
1177
 
1178
        set_io  [ebx + device.io_addr], byMIICR
1178
        set_io  [ebx + device.io_addr], byMIICR
1179
        in      al, dx
1179
        in      al, dx
1180
        or      al, 0x40
1180
        or      al, 0x40
1181
        out     dx, al
1181
        out     dx, al
1182
 
1182
 
1183
        mov     ecx, 200
1183
        mov     ecx, 200
1184
  .read_again:
1184
  .read_again:
1185
        in      al, dx
1185
        in      al, dx
1186
        test    al, 0x40
1186
        test    al, 0x40
1187
        jz      @f
1187
        jz      @f
1188
 
1188
 
1189
        mov     esi, 10
1189
        mov     esi, 10
1190
        invoke  Sleep
1190
        invoke  Sleep
1191
        dec     ecx
1191
        dec     ecx
1192
        jnz     .read_again
1192
        jnz     .read_again
1193
        DEBUGF  2, "ReadMII: timeout!\n"
1193
        DEBUGF  2, "ReadMII: timeout!\n"
1194
  @@:
1194
  @@:
1195
 
1195
 
1196
        call    MIIDelay
1196
        call    MIIDelay
1197
 
1197
 
1198
        set_io  [ebx + device.io_addr], byMIIAD
1198
        set_io  [ebx + device.io_addr], byMIIAD
1199
        in      ax, dx
1199
        in      ax, dx
1200
 
1200
 
1201
        push    eax
1201
        push    eax
1202
        mov     ax, bx
1202
        mov     ax, bx
1203
        set_io  [ebx + device.io_addr], byMIIAD
1203
        set_io  [ebx + device.io_addr], byMIIAD
1204
        out     dx, al
1204
        out     dx, al
1205
 
1205
 
1206
        shr     ax, 8
1206
        shr     ax, 8
1207
        set_io  [ebx + device.io_addr], byMIICR
1207
        set_io  [ebx + device.io_addr], byMIICR
1208
        out     dx, al
1208
        out     dx, al
1209
 
1209
 
1210
        call    MIIDelay
1210
        call    MIIDelay
1211
 
1211
 
1212
        pop     eax
1212
        pop     eax
1213
        and     eax, 0xFFFF
1213
        and     eax, 0xFFFF
1214
        rol     ax, 8
1214
        rol     ax, 8
1215
 
1215
 
1216
        pop     edx ecx ebx esi
1216
        pop     edx ecx ebx esi
1217
        ret
1217
        ret
1218
endp
1218
endp
1219
 
1219
 
1220
 
1220
 
1221
 
1221
 
1222
proc    WriteMII stdcall, byMIISetByte:dword, byMIISetBit:dword, byMIIOP:dword
1222
proc    WriteMII stdcall, byMIISetByte:dword, byMIISetBit:dword, byMIIOP:dword
1223
 
1223
 
1224
;        DEBUGF  1, "WriteMII SetByte=%x SetBit=%x OP=%x\n", [byMIISetByte], [byMIISetBit], [byMIIOP]
1224
;        DEBUGF  1, "WriteMII SetByte=%x SetBit=%x OP=%x\n", [byMIISetByte], [byMIISetBit], [byMIIOP]
1225
 
1225
 
1226
        push    ebx eax ecx edx
1226
        push    ebx eax ecx edx
1227
 
1227
 
1228
        set_io  [ebx + device.io_addr], 0
1228
        set_io  [ebx + device.io_addr], 0
1229
        set_io  [ebx + device.io_addr], byMIIAD
1229
        set_io  [ebx + device.io_addr], byMIIAD
1230
        in      al, dx
1230
        in      al, dx
1231
        mov     bl, al
1231
        mov     bl, al
1232
 
1232
 
1233
        set_io  [ebx + device.io_addr], byMIICR
1233
        set_io  [ebx + device.io_addr], byMIICR
1234
        in      al, dx
1234
        in      al, dx
1235
        mov     bh, al
1235
        mov     bh, al
1236
        and     al, 0x7F
1236
        and     al, 0x7F
1237
        out     dx, al
1237
        out     dx, al
1238
 
1238
 
1239
        call    MIIDelay
1239
        call    MIIDelay
1240
 
1240
 
1241
        mov     al, byte [byMIISetByte]
1241
        mov     al, byte [byMIISetByte]
1242
        set_io  [ebx + device.io_addr], byMIIAD
1242
        set_io  [ebx + device.io_addr], byMIIAD
1243
        out     dx, al
1243
        out     dx, al
1244
 
1244
 
1245
        call    MIIDelay
1245
        call    MIIDelay
1246
 
1246
 
1247
        set_io  [ebx + device.io_addr], byMIICR
1247
        set_io  [ebx + device.io_addr], byMIICR
1248
        in      al, dx
1248
        in      al, dx
1249
        or      al, 0x40
1249
        or      al, 0x40
1250
        out     dx, al
1250
        out     dx, al
1251
 
1251
 
1252
        mov     ecx, 200
1252
        mov     ecx, 200
1253
  .read_again0:
1253
  .read_again0:
1254
        in      al, dx
1254
        in      al, dx
1255
        test    al, 0x40
1255
        test    al, 0x40
1256
        jz      .done
1256
        jz      .done
1257
 
1257
 
1258
        mov     esi, 10
1258
        mov     esi, 10
1259
        invoke  Sleep
1259
        invoke  Sleep
1260
        dec     ecx
1260
        dec     ecx
1261
        jnz     .read_again0
1261
        jnz     .read_again0
1262
        DEBUGF  2, "WriteMII: timeout (1)\n"
1262
        DEBUGF  2, "WriteMII: timeout (1)\n"
1263
  .done:
1263
  .done:
1264
 
1264
 
1265
        call    MIIDelay
1265
        call    MIIDelay
1266
 
1266
 
1267
        set_io  [ebx + device.io_addr], wMIIDATA
1267
        set_io  [ebx + device.io_addr], wMIIDATA
1268
        in      ax, dx
1268
        in      ax, dx
1269
 
1269
 
1270
        mov     ecx, [byMIISetBit]
1270
        mov     ecx, [byMIISetBit]
1271
        rol     cx, 8
1271
        rol     cx, 8
1272
 
1272
 
1273
        cmp     byte [byMIIOP], 0
1273
        cmp     byte [byMIIOP], 0
1274
        jne     @f
1274
        jne     @f
1275
        not     ecx
1275
        not     ecx
1276
        and     ax, cx
1276
        and     ax, cx
1277
        jmp     .end_mascarad
1277
        jmp     .end_mascarad
1278
     @@:
1278
     @@:
1279
        or      ax, cx
1279
        or      ax, cx
1280
     .end_mascarad:
1280
     .end_mascarad:
1281
 
1281
 
1282
        set_io  [ebx + device.io_addr], wMIIDATA
1282
        set_io  [ebx + device.io_addr], wMIIDATA
1283
        out     dx, ax
1283
        out     dx, ax
1284
 
1284
 
1285
        call    MIIDelay
1285
        call    MIIDelay
1286
 
1286
 
1287
        set_io  [ebx + device.io_addr], byMIICR
1287
        set_io  [ebx + device.io_addr], byMIICR
1288
        in      al, dx
1288
        in      al, dx
1289
        or      al, 0x20
1289
        or      al, 0x20
1290
        out     dx, al
1290
        out     dx, al
1291
 
1291
 
1292
        mov     ecx, 200
1292
        mov     ecx, 200
1293
    .read_again1:
1293
    .read_again1:
1294
        in      al, dx
1294
        in      al, dx
1295
        test    al, 0x20
1295
        test    al, 0x20
1296
        jz      @f
1296
        jz      @f
1297
 
1297
 
1298
        mov     esi, 10
1298
        mov     esi, 10
1299
        invoke  Sleep
1299
        invoke  Sleep
1300
        dec     ecx
1300
        dec     ecx
1301
        jnz     .read_again1
1301
        jnz     .read_again1
1302
        DEBUGF  2, "WriteMII timeout (2)\n"
1302
        DEBUGF  2, "WriteMII timeout (2)\n"
1303
    @@:
1303
    @@:
1304
 
1304
 
1305
        call    MIIDelay
1305
        call    MIIDelay
1306
 
1306
 
1307
        mov     ax, bx
1307
        mov     ax, bx
1308
        and     al, 0x7F
1308
        and     al, 0x7F
1309
        set_io  [ebx + device.io_addr], byMIIAD
1309
        set_io  [ebx + device.io_addr], byMIIAD
1310
        out     dx, al
1310
        out     dx, al
1311
 
1311
 
1312
        shr     ax, 8
1312
        shr     ax, 8
1313
        set_io  [ebx + device.io_addr], byMIICR
1313
        set_io  [ebx + device.io_addr], byMIICR
1314
        out     dx, al
1314
        out     dx, al
1315
 
1315
 
1316
        call    MIIDelay
1316
        call    MIIDelay
1317
 
1317
 
1318
        pop     edx ecx eax ebx
1318
        pop     edx ecx eax ebx
1319
        ret
1319
        ret
1320
endp
1320
endp
1321
 
1321
 
1322
 
1322
 
1323
align 4
1323
align 4
1324
MIIDelay:
1324
MIIDelay:
1325
 
1325
 
1326
        mov     ecx, 0x7FFF
1326
        mov     ecx, 0x7FFF
1327
    @@:
1327
    @@:
1328
        in      al, 0x61
1328
        in      al, 0x61
1329
        in      al, 0x61
1329
        in      al, 0x61
1330
        in      al, 0x61
1330
        in      al, 0x61
1331
        in      al, 0x61
1331
        in      al, 0x61
1332
        loop    @b
1332
        loop    @b
1333
 
1333
 
1334
        ret
1334
        ret
1335
 
1335
 
1336
 
1336
 
1337
align 4
1337
align 4
1338
set_rx_mode:
1338
set_rx_mode:
1339
 
1339
 
1340
        DEBUGF  1, "Set RX mode\n"
1340
        DEBUGF  1, "Set RX mode\n"
1341
 
1341
 
1342
        ; ! IFF_PROMISC
1342
        ; ! IFF_PROMISC
1343
        mov     eax, 0xffffffff
1343
        mov     eax, 0xffffffff
1344
        set_io  [ebx + device.io_addr], 0
1344
        set_io  [ebx + device.io_addr], 0
1345
        set_io  [ebx + device.io_addr], byMAR0
1345
        set_io  [ebx + device.io_addr], byMAR0
1346
        out     dx, eax
1346
        out     dx, eax
1347
 
1347
 
1348
        set_io  [ebx + device.io_addr], byMAR4
1348
        set_io  [ebx + device.io_addr], byMAR4
1349
        out     dx, eax
1349
        out     dx, eax
1350
 
1350
 
1351
        set_io  [ebx + device.io_addr], byRCR
1351
        set_io  [ebx + device.io_addr], byRCR
1352
        mov     al, 0x6C                ;rx_mode = 0x0C;
1352
        mov     al, 0x6C                ;rx_mode = 0x0C;
1353
        out     dx, al          ;outb(0x60 /* thresh */ | rx_mode, byRCR );
1353
        out     dx, al          ;outb(0x60 /* thresh */ | rx_mode, byRCR );
1354
 
1354
 
1355
        ret
1355
        ret
1356
 
1356
 
1357
 
1357
 
1358
 
1358
 
1359
 
1359
 
1360
 
1360
 
1361
; Beware of PCI posted writes
1361
; Beware of PCI posted writes
1362
macro IOSYNC
1362
macro IOSYNC
1363
{
1363
{
1364
        set_io  [ebx + device.io_addr], StationAddr
1364
        set_io  [ebx + device.io_addr], StationAddr
1365
        in      al, dx
1365
        in      al, dx
1366
}
1366
}
1367
 
1367
 
1368
 
1368
 
1369
 
1369
 
1370
align 4
1370
align 4
1371
read_mac:
1371
read_mac:
1372
 
1372
 
1373
        lea     edi, [ebx + device.mac]
1373
        lea     edi, [ebx + device.mac]
1374
        set_io  [ebx + device.io_addr], 0
1374
        set_io  [ebx + device.io_addr], 0
1375
        set_io  [ebx + device.io_addr], byPAR0
1375
        set_io  [ebx + device.io_addr], byPAR0
1376
        mov     ecx, 6
1376
        mov     ecx, 6
1377
  .next:
1377
  .next:
1378
        in      al, dx
1378
        in      al, dx
1379
        stosb
1379
        stosb
1380
        inc     edx
1380
        inc     edx
1381
        dec     ecx
1381
        dec     ecx
1382
        jnz     .next
1382
        jnz     .next
1383
 
1383
 
1384
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n", \
1384
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n", \
1385
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
1385
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
1386
 
1386
 
1387
 
1387
 
1388
        ret
1388
        ret
1389
 
1389
 
1390
 
1390
 
1391
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1391
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1392
;;                                         ;;
1392
;;                                         ;;
1393
;; Transmit                                ;;
1393
;; Transmit                                ;;
1394
;;                                         ;;
1394
;;                                         ;;
1395
;; In: buffer pointer in [esp+4]           ;;
1395
;; In: buffer pointer in [esp+4]           ;;
1396
;;     size of buffer in [esp+8]           ;;
1396
;;     size of buffer in [esp+8]           ;;
1397
;;     pointer to device structure in ebx  ;;
1397
;;     pointer to device structure in ebx  ;;
1398
;;                                         ;;
1398
;;                                         ;;
1399
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1399
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1400
align 4
1400
align 4
1401
proc transmit stdcall bufferptr, buffersize
1401
proc transmit stdcall bufferptr, buffersize
1402
 
1402
 
1403
        pushf
1403
        pushf
1404
        cli
1404
        cli
1405
 
1405
 
1406
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1406
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1407
        mov     eax, [bufferptr]
1407
        mov     eax, [bufferptr]
1408
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1408
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1409
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1409
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1410
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1410
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1411
        [eax+13]:2,[eax+12]:2
1411
        [eax+13]:2,[eax+12]:2
1412
 
1412
 
1413
        cmp     [buffersize], 1514
1413
        cmp     [buffersize], 1514
1414
        ja      .fail
1414
        ja      .fail
1415
        cmp     [buffersize], 60
1415
        cmp     [buffersize], 60
1416
        jb      .fail
1416
        jb      .fail
1417
 
1417
 
1418
        movzx   eax, [ebx + device.cur_tx]
1418
        movzx   eax, [ebx + device.cur_tx]
1419
        mov     ecx, sizeof.tx_head
1419
        mov     ecx, sizeof.tx_head
1420
        mul     ecx
1420
        mul     ecx
1421
        lea     edi, [ebx + device.tx_ring]
1421
        lea     edi, [ebx + device.tx_ring]
1422
        add     edi, eax
1422
        add     edi, eax
1423
 
1423
 
1424
        cmp     [edi + tx_head.buff_addr_virt], 0
1424
        cmp     [edi + tx_head.buff_addr_virt], 0
1425
        jne     .fail
1425
        jne     .fail
1426
 
1426
 
1427
        mov     eax, [bufferptr]
1427
        mov     eax, [bufferptr]
1428
        mov     [edi + tx_head.buff_addr_virt], eax
1428
        mov     [edi + tx_head.buff_addr_virt], eax
1429
        invoke  GetPhysAddr
1429
        invoke  GetPhysAddr
1430
        mov     [edi + tx_head.buff_addr], eax
1430
        mov     [edi + tx_head.buff_addr], eax
1431
        mov     ecx, [buffersize]
1431
        mov     ecx, [buffersize]
1432
        and     ecx, TX_CBITS_TX_BUF_SIZE
1432
        and     ecx, TX_CBITS_TX_BUF_SIZE
1433
        or      ecx,  0x00E08000
1433
        or      ecx,  0x00E08000
1434
        mov     [edi + tx_head.control], ecx
1434
        mov     [edi + tx_head.control], ecx
1435
        or      [edi + tx_head.status], TX_SBITS_OWN_BIT
1435
        or      [edi + tx_head.status], TX_SBITS_OWN_BIT
1436
 
1436
 
1437
        set_io  [ebx + device.io_addr], 0
1437
        set_io  [ebx + device.io_addr], 0
1438
        set_io  [ebx + device.io_addr], byCR1
1438
        set_io  [ebx + device.io_addr], byCR1
1439
        in      al, dx
1439
        in      al, dx
1440
        or      al, CR1_TDMD1
1440
        or      al, CR1_TDMD1
1441
        out     dx, al
1441
        out     dx, al
1442
 
1442
 
1443
        inc     [ebx + device.cur_tx]
1443
        inc     [ebx + device.cur_tx]
1444
        and     [ebx + device.cur_tx], TX_RING_SIZE-1
1444
        and     [ebx + device.cur_tx], TX_RING_SIZE-1
1445
 
1445
 
1446
        ;outw(IMRShadow,byIMR0); ;
1446
        ;outw(IMRShadow,byIMR0); ;
1447
 
1447
 
1448
; Update stats
1448
; Update stats
1449
        inc     [ebx + device.packets_tx]
1449
        inc     [ebx + device.packets_tx]
1450
        mov     ecx, [buffersize]
1450
        mov     ecx, [buffersize]
1451
        add     dword [ebx + device.bytes_tx], ecx
1451
        add     dword [ebx + device.bytes_tx], ecx
1452
        adc     dword [ebx + device.bytes_tx + 4], 0
1452
        adc     dword [ebx + device.bytes_tx + 4], 0
1453
 
1453
 
1454
        DEBUGF  1,"Transmit OK\n"
1454
        DEBUGF  1,"Transmit OK\n"
1455
        popf
1455
        popf
1456
        xor     eax, eax
1456
        xor     eax, eax
1457
        ret
1457
        ret
1458
 
1458
 
1459
  .fail:
1459
  .fail:
1460
        DEBUGF  2,"Transmit failed\n"
1460
        DEBUGF  2,"Transmit failed\n"
1461
        invoke  KernelFree, [bufferptr]
1461
        invoke  KernelFree, [bufferptr]
1462
        popf
1462
        popf
1463
        or      eax, -1
1463
        or      eax, -1
1464
        ret
1464
        ret
1465
 
1465
 
1466
endp
1466
endp
1467
 
1467
 
1468
 
1468
 
1469
 
1469
 
1470
;;;;;;;;;;;;;;;;;;;;;;;
1470
;;;;;;;;;;;;;;;;;;;;;;;
1471
;;                   ;;
1471
;;                   ;;
1472
;; Interrupt handler ;;
1472
;; Interrupt handler ;;
1473
;;                   ;;
1473
;;                   ;;
1474
;;;;;;;;;;;;;;;;;;;;;;;
1474
;;;;;;;;;;;;;;;;;;;;;;;
1475
 
1475
 
1476
align 4
1476
align 4
1477
int_handler:
1477
int_handler:
1478
 
1478
 
1479
        push    ebx esi edi
1479
        push    ebx esi edi
1480
 
1480
 
1481
        DEBUGF  1,"INT\n"
1481
        DEBUGF  1,"INT\n"
1482
 
1482
 
1483
; Find pointer of device which made IRQ occur
1483
; Find pointer of device which made IRQ occur
1484
 
1484
 
1485
        mov     ecx, [devices]
1485
        mov     ecx, [devices]
1486
        test    ecx, ecx
1486
        test    ecx, ecx
1487
        jz      .nothing
1487
        jz      .nothing
1488
        mov     esi, device_list
1488
        mov     esi, device_list
1489
  .nextdevice:
1489
  .nextdevice:
1490
        mov     ebx, [esi]
1490
        mov     ebx, [esi]
1491
 
1491
 
1492
        set_io  [ebx + device.io_addr], 0
1492
        set_io  [ebx + device.io_addr], 0
1493
        set_io  [ebx + device.io_addr], IntrStatus
1493
        set_io  [ebx + device.io_addr], IntrStatus
1494
        in      ax, dx
1494
        in      ax, dx
1495
        out     dx, ax                  ; send it back to ACK
1495
        out     dx, ax                  ; send it back to ACK
1496
        test    ax, ax
1496
        test    ax, ax
1497
        jnz     .got_it
1497
        jnz     .got_it
1498
  .continue:
1498
  .continue:
1499
        add     esi, 4
1499
        add     esi, 4
1500
        dec     ecx
1500
        dec     ecx
1501
        jnz     .nextdevice
1501
        jnz     .nextdevice
1502
  .nothing:
1502
  .nothing:
1503
        pop     edi esi ebx
1503
        pop     edi esi ebx
1504
        xor     eax, eax
1504
        xor     eax, eax
1505
 
1505
 
1506
        ret                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1506
        ret                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1507
 
1507
 
1508
 
1508
 
1509
 
1509
 
1510
  .got_it:
1510
  .got_it:
1511
 
1511
 
1512
        DEBUGF  1, "status=0x%x\n", ax
1512
        DEBUGF  1, "status=0x%x\n", ax
1513
 
1513
 
1514
        push    ax
1514
        push    ax
1515
 
1515
 
1516
        test    ax, IntrRxDone
1516
        test    ax, IntrRxDone
1517
        jz      .not_RX
1517
        jz      .not_RX
1518
 
1518
 
1519
        push    ebx
1519
        push    ebx
1520
  .more_RX:
1520
  .more_RX:
1521
        pop     ebx
1521
        pop     ebx
1522
 
1522
 
1523
; Get the current descriptor pointer
1523
; Get the current descriptor pointer
1524
 
1524
 
1525
        movzx   eax, [ebx + device.cur_rx]
1525
        movzx   eax, [ebx + device.cur_rx]
1526
        mov     ecx, sizeof.rx_head
1526
        mov     ecx, sizeof.rx_head
1527
        mul     ecx
1527
        mul     ecx
1528
        lea     edi, [ebx + device.rx_ring]
1528
        lea     edi, [ebx + device.rx_ring]
1529
        add     edi, eax
1529
        add     edi, eax
1530
 
1530
 
1531
; Check it's status
1531
; Check it's status
1532
 
1532
 
1533
        test    [edi + rx_head.status], RX_SBITS_OWN_BIT
1533
        test    [edi + rx_head.status], RX_SBITS_OWN_BIT
1534
        jnz     .not_bit_own
1534
        jnz     .not_bit_own
1535
 
1535
 
1536
        DEBUGF  1, "Packet status = 0x%x\n", [edi + rx_head.status]
1536
        DEBUGF  1, "Packet status = 0x%x\n", [edi + rx_head.status]
1537
 
1537
 
1538
; TODO: check error bits
1538
; TODO: check error bits
1539
 
1539
 
1540
; get length
1540
; get length
1541
 
1541
 
1542
        mov     ecx, [edi + rx_head.status]
1542
        mov     ecx, [edi + rx_head.status]
1543
        and     ecx, RX_SBITS_FRAME_LENGTH
1543
        and     ecx, RX_SBITS_FRAME_LENGTH
1544
        shr     ecx, 16
1544
        shr     ecx, 16
1545
        sub     ecx, 4  ; We dont want CRC
1545
        sub     ecx, 4  ; We dont want CRC
1546
 
1546
 
1547
; Update stats
1547
; Update stats
1548
 
1548
 
1549
        add     dword [ebx + device.bytes_rx], ecx
1549
        add     dword [ebx + device.bytes_rx], ecx
1550
        adc     dword [ebx + device.bytes_rx + 4], 0
1550
        adc     dword [ebx + device.bytes_rx + 4], 0
1551
        inc     [ebx + device.packets_rx]
1551
        inc     [ebx + device.packets_rx]
1552
 
1552
 
1553
; Push packet size and pointer, kernel will need it..
1553
; Push packet size and pointer, kernel will need it..
1554
 
1554
 
1555
        push    ebx
1555
        push    ebx
1556
        push    .more_RX        ; return ptr
1556
        push    .more_RX        ; return ptr
1557
 
1557
 
1558
        push    ecx             ; full packet size
1558
        push    ecx             ; full packet size
1559
        push    [edi + rx_head.buff_addr_virt]
1559
        push    [edi + rx_head.buff_addr_virt]
1560
 
1560
 
1561
; reset the RX descriptor
1561
; reset the RX descriptor
1562
 
1562
 
1563
        push    edi
1563
        push    edi
1564
        invoke  KernelAlloc, PKT_BUF_SZ
1564
        invoke  KernelAlloc, PKT_BUF_SZ
1565
        pop     edi
1565
        pop     edi
1566
        mov     [edi + rx_head.buff_addr_virt], eax
1566
        mov     [edi + rx_head.buff_addr_virt], eax
1567
        invoke  GetPhysAddr
1567
        invoke  GetPhysAddr
1568
        mov     [edi + rx_head.buff_addr], eax
1568
        mov     [edi + rx_head.buff_addr], eax
1569
        mov     [edi + rx_head.status], RX_SBITS_OWN_BIT
1569
        mov     [edi + rx_head.status], RX_SBITS_OWN_BIT
1570
 
1570
 
1571
; Use next descriptor next time
1571
; Use next descriptor next time
1572
 
1572
 
1573
        inc     [ebx + device.cur_rx]
1573
        inc     [ebx + device.cur_rx]
1574
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
1574
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
1575
 
1575
 
1576
; At last, send packet to kernel
1576
; At last, send packet to kernel
1577
 
1577
 
1578
        jmp     [Eth_input]
1578
        jmp     [Eth_input]
1579
 
1579
 
1580
  .not_bit_own:
1580
  .not_bit_own:
1581
  .not_RX:
1581
  .not_RX:
1582
 
1582
 
1583
        pop     ax
1583
        pop     ax
1584
 
1584
 
1585
        test    ax, IntrTxDone
1585
        test    ax, IntrTxDone
1586
        jz      .not_TX
1586
        jz      .not_TX
1587
 
1587
 
1588
      .loop_tx:
1588
      .loop_tx:
1589
        movzx   eax, [ebx + device.last_tx]
1589
        movzx   eax, [ebx + device.last_tx]
1590
        mov     ecx, sizeof.tx_head
1590
        mov     ecx, sizeof.tx_head
1591
        mul     ecx
1591
        mul     ecx
1592
        lea     edi, [ebx + device.tx_ring]
1592
        lea     edi, [ebx + device.tx_ring]
1593
        add     edi, eax
1593
        add     edi, eax
1594
 
1594
 
1595
        test    [edi + tx_head.status], TX_SBITS_OWN_BIT
1595
        test    [edi + tx_head.status], TX_SBITS_OWN_BIT
1596
        jnz     .not_TX
1596
        jnz     .not_TX
1597
 
1597
 
1598
        cmp     [edi + tx_head.buff_addr_virt], 0
1598
        cmp     [edi + tx_head.buff_addr_virt], 0
1599
        je      .not_TX
1599
        je      .not_TX
1600
 
1600
 
1601
        DEBUGF  1,"Freeing buffer 0x%x\n", [edi + tx_head.buff_addr_virt]
1601
        DEBUGF  1,"Freeing buffer 0x%x\n", [edi + tx_head.buff_addr_virt]
1602
 
1602
 
1603
        push    [edi + tx_head.buff_addr_virt]
1603
        push    [edi + tx_head.buff_addr_virt]
1604
        mov     [edi + tx_head.buff_addr_virt], 0
1604
        mov     [edi + tx_head.buff_addr_virt], 0
1605
        invoke  KernelFree
1605
        invoke  KernelFree
1606
 
1606
 
1607
        inc     [ebx + device.last_tx]
1607
        inc     [ebx + device.last_tx]
1608
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
1608
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
1609
 
1609
 
1610
        jmp     .loop_tx
1610
        jmp     .loop_tx
1611
 
1611
 
1612
  .not_TX:
1612
  .not_TX:
1613
 
1613
 
1614
        ; On Rhine-II, Bit 3 indicates Tx descriptor write-back race.
1614
        ; On Rhine-II, Bit 3 indicates Tx descriptor write-back race.
1615
if 0
1615
if 0
1616
        cmp     [ebx + device.chip_id], 0x3065 ;if (tp->chip_id == 0x3065)
1616
        cmp     [ebx + device.chip_id], 0x3065 ;if (tp->chip_id == 0x3065)
1617
        jne     @f
1617
        jne     @f
1618
        push    ax
1618
        push    ax
1619
        xor     eax, eax
1619
        xor     eax, eax
1620
        set_io  [ebx + device.io_addr], IntrStatus2
1620
        set_io  [ebx + device.io_addr], IntrStatus2
1621
        in      al, dx ;  intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
1621
        in      al, dx ;  intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
1622
        shl     eax, 16
1622
        shl     eax, 16
1623
        pop     ax
1623
        pop     ax
1624
    @@:
1624
    @@:
1625
end if
1625
end if
1626
 
1626
 
1627
if 0
1627
if 0
1628
 
1628
 
1629
        ; Acknowledge all of the current interrupt sources ASAP.
1629
        ; Acknowledge all of the current interrupt sources ASAP.
1630
        xor     ecx, ecx
1630
        xor     ecx, ecx
1631
        test    eax, IntrTxDescRace
1631
        test    eax, IntrTxDescRace
1632
        jz      @f
1632
        jz      @f
1633
        set_io  [ebx + device.io_addr], 0
1633
        set_io  [ebx + device.io_addr], 0
1634
        set_io  [ebx + device.io_addr], IntrStatus2
1634
        set_io  [ebx + device.io_addr], IntrStatus2
1635
        push    ax
1635
        push    ax
1636
        mov     al, 0x08
1636
        mov     al, 0x08
1637
        out     dx, al
1637
        out     dx, al
1638
        pop     ax
1638
        pop     ax
1639
    @@:
1639
    @@:
1640
        set_io  [ebx + device.io_addr], 0
1640
        set_io  [ebx + device.io_addr], 0
1641
        set_io  [ebx + device.io_addr], IntrStatus
1641
        set_io  [ebx + device.io_addr], IntrStatus
1642
        out     dx, ax
1642
        out     dx, ax
1643
        IOSYNC
1643
        IOSYNC
1644
 
1644
 
1645
end if
1645
end if
1646
 
1646
 
1647
        pop     edi esi ebx
1647
        pop     edi esi ebx
1648
        xor     eax, eax
1648
        xor     eax, eax
1649
        inc     eax
1649
        inc     eax
1650
 
1650
 
1651
        ret
1651
        ret
1652
 
1652
 
1653
 
1653
 
1654
 
1654
 
1655
 
1655
 
1656
 
1656
 
1657
; End of code
1657
; End of code
1658
 
1658
 
1659
data fixups
1659
data fixups
1660
end data
1660
end data
1661
 
1661
 
1662
include '../peimport.inc'
1662
include '../peimport.inc'
1663
 
1663
 
1664
my_service      db 'RHINE',0                    ; max 16 chars including zero
1664
my_service      db 'RHINE',0                    ; max 16 chars including zero
1665
 
1665
 
1666
chiplist:
1666
chiplist:
1667
                dd 0x30431106, rhine_3043;, RHINE_IOTYPE, RHINE_I_IOSIZE, CanHaveMII or ReqTxAlign or HasV1TxStat
1667
                dd 0x30431106, rhine_3043;, RHINE_IOTYPE, RHINE_I_IOSIZE, CanHaveMII or ReqTxAlign or HasV1TxStat
1668
                dd 0x61001106, rhine_6100;, RHINE_IOTYPE, RHINE_I_IOSIZE, CanHaveMII or ReqTxAlign or HasV1TxStat
1668
                dd 0x61001106, rhine_6100;, RHINE_IOTYPE, RHINE_I_IOSIZE, CanHaveMII or ReqTxAlign or HasV1TxStat
1669
                dd 0x30651106, rhine_6102;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1669
                dd 0x30651106, rhine_6102;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1670
                dd 0x31061106, rhine_6105;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1670
                dd 0x31061106, rhine_6105;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1671
; Duplicate entry, with 'M' features enabled.
1671
; Duplicate entry, with 'M' features enabled.
1672
;                dd 0x31061106, rhine_6105;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL or HasIPChecksum or HasVLAN
1672
;                dd 0x31061106, rhine_6105;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL or HasIPChecksum or HasVLAN
1673
                dd 0x30531106, rhine_3053;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1673
                dd 0x30531106, rhine_3053;, RHINE_IOTYPE, RHINEII_IOSIZE, CanHaveMII or HasWOL
1674
                dd 0
1674
                dd 0
1675
 
1675
 
1676
rhine_3043      db "VIA VT3043 Rhine", 0
1676
rhine_3043      db "VIA VT3043 Rhine", 0
1677
rhine_6100      db "VIA VT86C100A Rhine", 0
1677
rhine_6100      db "VIA VT86C100A Rhine", 0
1678
rhine_6102      db "VIA VT6102 Rhine-II", 0
1678
rhine_6102      db "VIA VT6102 Rhine-II", 0
1679
rhine_6105      db "VIA VT6105LOM Rhine-III (3106)", 0
1679
rhine_6105      db "VIA VT6105LOM Rhine-III (3106)", 0
1680
rhine_3053      db "VIA VT6105M Rhine-III (3053 prototype)", 0
1680
rhine_3053      db "VIA VT6105M Rhine-III (3053 prototype)", 0
1681
 
1681
 
1682
include_debug_strings                           ; All data which FDO uses will be included here
1682
include_debug_strings                           ; All data which FDO uses will be included here
1683
 
1683
 
1684
align 4
1684
align 4
1685
devices         dd 0
1685
devices         dd 0
1686
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
1686
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling