Subversion Repositories Kolibri OS

Rev

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

Rev 4998 Rev 5074
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2014. 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
;;  FORCEDETH.INC                                                  ;;
6
;;  FORCEDETH.INC                                                  ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Ethernet driver for Kolibri OS                                 ;;
8
;;  Ethernet driver for Kolibri OS                                 ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;  Driver for chips of NVIDIA nForce2                             ;;
10
;;  Driver for chips of NVIDIA nForce2                             ;;
11
;;  References:                                                    ;;
11
;;  References:                                                    ;;
12
;;    forcedeth.c - linux driver (etherboot project)               ;;
12
;;    forcedeth.c - linux driver (etherboot project)               ;;
13
;;    ethernet driver template by Mike Hibbett                     ;;
13
;;    ethernet driver template by Mike Hibbett                     ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;  The copyright statement is                                     ;;
15
;;  The copyright statement is                                     ;;
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;          GNU GENERAL PUBLIC LICENSE                             ;;
17
;;          GNU GENERAL PUBLIC LICENSE                             ;;
18
;;             Version 2, June 1991                                ;;
18
;;             Version 2, June 1991                                ;;
19
;;                                                                 ;;
19
;;                                                                 ;;
20
;;  Copyright 2008 shurf,                                          ;;
20
;;  Copyright 2008 shurf,                                          ;;
21
;;   cit.utc@gmail.com                                             ;;
21
;;   cit.utc@gmail.com                                             ;;
22
;;                                                                 ;;
22
;;                                                                 ;;
23
;;  See file COPYING for details                                   ;;
23
;;  See file COPYING for details                                   ;;
24
;;                                                                 ;;
24
;;                                                                 ;;
25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26
 
26
 
27
 
27
 
28
format PE DLL native
28
format PE DLL native
29
entry START
29
entry START
30
 
30
 
31
        CURRENT_API             = 0x0200
31
        CURRENT_API             = 0x0200
32
        COMPATIBLE_API          = 0x0100
32
        COMPATIBLE_API          = 0x0100
33
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
33
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
34
 
34
 
35
        MAX_DEVICES             = 16
35
        MAX_DEVICES             = 16
36
 
36
 
37
        RBLEN                   = 0     ; Receive buffer size: 0=4K 1=8k 2=16k 3=32k 4=64k
37
        RBLEN                   = 0     ; Receive buffer size: 0=4K 1=8k 2=16k 3=32k 4=64k
38
                                        ; FIXME: option 1 and 2 will not allocate buffer correctly causing data loss!
38
                                        ; FIXME: option 1 and 2 will not allocate buffer correctly causing data loss!
39
 
39
 
40
        DEBUG                   = 1
40
        DEBUG                   = 1
41
        __DEBUG__               = 1
41
        __DEBUG__               = 1
42
        __DEBUG_LEVEL__         = 2
42
        __DEBUG_LEVEL__         = 2
43
 
43
 
44
        RX_RING                 = 4
44
        RX_RING                 = 4
45
        TX_RING                 = 4
45
        TX_RING                 = 4
46
 
46
 
47
section '.flat' readable writable executable
47
section '.flat' readable writable executable
48
 
48
 
49
include '../proc32.inc'
49
include '../proc32.inc'
50
include '../struct.inc'
50
include '../struct.inc'
51
include '../macros.inc'
51
include '../macros.inc'
52
include '../fdo.inc'
52
include '../fdo.inc'
53
include '../netdrv_pe.inc'
53
include '../netdrv.inc'
54
 
54
 
55
;**************************************************************************
55
;**************************************************************************
56
; forcedeth Register Definitions
56
; forcedeth Register Definitions
57
;**************************************************************************
57
;**************************************************************************
58
 
58
 
59
PCI_DEVICE_ID_NVIDIA_NVENET_1   = 0x01c3
59
PCI_DEVICE_ID_NVIDIA_NVENET_1   = 0x01c3
60
PCI_DEVICE_ID_NVIDIA_NVENET_2   = 0x0066
60
PCI_DEVICE_ID_NVIDIA_NVENET_2   = 0x0066
61
PCI_DEVICE_ID_NVIDIA_NVENET_4   = 0x0086
61
PCI_DEVICE_ID_NVIDIA_NVENET_4   = 0x0086
62
PCI_DEVICE_ID_NVIDIA_NVENET_5   = 0x008c
62
PCI_DEVICE_ID_NVIDIA_NVENET_5   = 0x008c
63
PCI_DEVICE_ID_NVIDIA_NVENET_3   = 0x00d6
63
PCI_DEVICE_ID_NVIDIA_NVENET_3   = 0x00d6
64
PCI_DEVICE_ID_NVIDIA_NVENET_7   = 0x00df
64
PCI_DEVICE_ID_NVIDIA_NVENET_7   = 0x00df
65
PCI_DEVICE_ID_NVIDIA_NVENET_6   = 0x00e6
65
PCI_DEVICE_ID_NVIDIA_NVENET_6   = 0x00e6
66
PCI_DEVICE_ID_NVIDIA_NVENET_8   = 0x0056
66
PCI_DEVICE_ID_NVIDIA_NVENET_8   = 0x0056
67
PCI_DEVICE_ID_NVIDIA_NVENET_9   = 0x0057
67
PCI_DEVICE_ID_NVIDIA_NVENET_9   = 0x0057
68
PCI_DEVICE_ID_NVIDIA_NVENET_10  = 0x0037
68
PCI_DEVICE_ID_NVIDIA_NVENET_10  = 0x0037
69
PCI_DEVICE_ID_NVIDIA_NVENET_11  = 0x0038
69
PCI_DEVICE_ID_NVIDIA_NVENET_11  = 0x0038
70
PCI_DEVICE_ID_NVIDIA_NVENET_12  = 0x0268
70
PCI_DEVICE_ID_NVIDIA_NVENET_12  = 0x0268
71
PCI_DEVICE_ID_NVIDIA_NVENET_13  = 0x0269
71
PCI_DEVICE_ID_NVIDIA_NVENET_13  = 0x0269
72
PCI_DEVICE_ID_NVIDIA_NVENET_14  = 0x0372
72
PCI_DEVICE_ID_NVIDIA_NVENET_14  = 0x0372
73
PCI_DEVICE_ID_NVIDIA_NVENET_15  = 0x0373
73
PCI_DEVICE_ID_NVIDIA_NVENET_15  = 0x0373
74
 
74
 
75
UNKSETUP1_VAL             = 0x16070f
75
UNKSETUP1_VAL             = 0x16070f
76
UNKSETUP2_VAL             = 0x16
76
UNKSETUP2_VAL             = 0x16
77
UNKSETUP3_VAL1            = 0x200010
77
UNKSETUP3_VAL1            = 0x200010
78
UNKSETUP4_VAL             = 8
78
UNKSETUP4_VAL             = 8
79
UNKSETUP5_BIT31           = (1 shl 31)
79
UNKSETUP5_BIT31           = (1 shl 31)
80
UNKSETUP6_VAL             = 3
80
UNKSETUP6_VAL             = 3
81
 
81
 
82
TXRXCTL_RXCHECK           = 0x0400
82
TXRXCTL_RXCHECK           = 0x0400
83
MIISTAT_ERROR             = 0x0001
83
MIISTAT_ERROR             = 0x0001
84
MIISTAT_MASK              = 0x000f
84
MIISTAT_MASK              = 0x000f
85
MIISTAT_MASK2             = 0x000f
85
MIISTAT_MASK2             = 0x000f
86
MIICTL_INUSE              = 0x08000
86
MIICTL_INUSE              = 0x08000
87
MIICTL_WRITE              = 0x00400
87
MIICTL_WRITE              = 0x00400
88
MIICTL_ADDRSHIFT          = 5
88
MIICTL_ADDRSHIFT          = 5
89
 
89
 
90
MIISPEED_BIT8             = (1 shl 8)
90
MIISPEED_BIT8             = (1 shl 8)
91
MIIDELAY                  = 5
91
MIIDELAY                  = 5
92
 
92
 
93
IRQ_RX_ERROR              = 0x0001
93
IRQ_RX_ERROR              = 0x0001
94
IRQ_RX                    = 0x0002
94
IRQ_RX                    = 0x0002
95
IRQ_RX_NOBUF              = 0x0004
95
IRQ_RX_NOBUF              = 0x0004
96
IRQ_TX_ERROR              = 0x0008
96
IRQ_TX_ERROR              = 0x0008
97
IRQ_TX_OK                 = 0x0010
97
IRQ_TX_OK                 = 0x0010
98
IRQ_TIMER                 = 0x0020
98
IRQ_TIMER                 = 0x0020
99
IRQ_LINK                  = 0x0040
99
IRQ_LINK                  = 0x0040
100
IRQ_RX_FORCED             = 0x0080
100
IRQ_RX_FORCED             = 0x0080
101
IRQ_TX_FORCED             = 0x0100
101
IRQ_TX_FORCED             = 0x0100
102
IRQ_RECOVER_ERROR         = 0x8200                                           ;
102
IRQ_RECOVER_ERROR         = 0x8200                                           ;
103
IRQMASK_WANTED_2          = IRQ_TX_FORCED + IRQ_LINK + IRQ_RX_ERROR + IRQ_RX + IRQ_TX_OK + IRQ_TX_ERROR
103
IRQMASK_WANTED_2          = IRQ_TX_FORCED + IRQ_LINK + IRQ_RX_ERROR + IRQ_RX + IRQ_TX_OK + IRQ_TX_ERROR
104
 
104
 
105
IRQ_RX_ALL                = IRQ_RX_ERROR or IRQ_RX or IRQ_RX_NOBUF or IRQ_RX_FORCED
105
IRQ_RX_ALL                = IRQ_RX_ERROR or IRQ_RX or IRQ_RX_NOBUF or IRQ_RX_FORCED
106
IRQ_TX_ALL                = IRQ_TX_ERROR or IRQ_TX_OK or IRQ_TX_FORCED
106
IRQ_TX_ALL                = IRQ_TX_ERROR or IRQ_TX_OK or IRQ_TX_FORCED
107
IRQ_OTHER                 = IRQ_LINK or IRQ_TIMER or IRQ_RECOVER_ERROR
107
IRQ_OTHER                 = IRQ_LINK or IRQ_TIMER or IRQ_RECOVER_ERROR
108
 
108
 
109
IRQSTAT_MASK              = 0x1ff
109
IRQSTAT_MASK              = 0x1ff
110
 
110
 
111
TXRXCTL_KICK              = 0x0001
111
TXRXCTL_KICK              = 0x0001
112
TXRXCTL_BIT1              = 0x0002
112
TXRXCTL_BIT1              = 0x0002
113
TXRXCTL_BIT2              = 0x0004
113
TXRXCTL_BIT2              = 0x0004
114
TXRXCTL_IDLE              = 0x0008
114
TXRXCTL_IDLE              = 0x0008
115
TXRXCTL_RESET             = 0x0010
115
TXRXCTL_RESET             = 0x0010
116
TXRXCTL_RXCHECK           = 0x0400
116
TXRXCTL_RXCHECK           = 0x0400
117
 
117
 
118
MCASTADDRA_FORCE          = 0x01
118
MCASTADDRA_FORCE          = 0x01
119
 
119
 
120
MAC_RESET_ASSERT          = 0x0F3
120
MAC_RESET_ASSERT          = 0x0F3
121
 
121
 
122
MISC1_HD                  = 0x02
122
MISC1_HD                  = 0x02
123
MISC1_FORCE               = 0x3b0f3c
123
MISC1_FORCE               = 0x3b0f3c
124
 
124
 
125
PFF_ALWAYS                = 0x7F0008
125
PFF_ALWAYS                = 0x7F0008
126
PFF_PROMISC               = 0x80
126
PFF_PROMISC               = 0x80
127
PFF_MYADDR                = 0x20
127
PFF_MYADDR                = 0x20
128
 
128
 
129
OFFLOAD_HOMEPHY           = 0x601
129
OFFLOAD_HOMEPHY           = 0x601
130
OFFLOAD_NORMAL            = 4096 shl RBLEN
130
OFFLOAD_NORMAL            = 4096 shl RBLEN
131
 
131
 
132
RNDSEED_MASK              = 0x00ff
132
RNDSEED_MASK              = 0x00ff
133
RNDSEED_FORCE             = 0x7f00
133
RNDSEED_FORCE             = 0x7f00
134
RNDSEED_FORCE2            = 0x2d00
134
RNDSEED_FORCE2            = 0x2d00
135
RNDSEED_FORCE3            = 0x7400
135
RNDSEED_FORCE3            = 0x7400
136
 
136
 
137
; POLL_DEFAULT is the interval length of the timer source on the nic
137
; POLL_DEFAULT is the interval length of the timer source on the nic
138
; POLL_DEFAULT=97 would result in an interval length of 1 ms
138
; POLL_DEFAULT=97 would result in an interval length of 1 ms
139
POLL_DEFAULT              = 970
139
POLL_DEFAULT              = 970
140
 
140
 
141
ADAPTCTL_START            = 0x02
141
ADAPTCTL_START            = 0x02
142
ADAPTCTL_LINKUP           = 0x04
142
ADAPTCTL_LINKUP           = 0x04
143
ADAPTCTL_PHYVALID         = 0x40000
143
ADAPTCTL_PHYVALID         = 0x40000
144
ADAPTCTL_RUNNING          = 0x100000
144
ADAPTCTL_RUNNING          = 0x100000
145
ADAPTCTL_PHYSHIFT         = 24
145
ADAPTCTL_PHYSHIFT         = 24
146
 
146
 
147
WAKEUPFLAGS_VAL           = 0x7770
147
WAKEUPFLAGS_VAL           = 0x7770
148
 
148
 
149
POWERSTATE_POWEREDUP      = 0x8000
149
POWERSTATE_POWEREDUP      = 0x8000
150
POWERSTATE_VALID          = 0x0100
150
POWERSTATE_VALID          = 0x0100
151
POWERSTATE_MASK           = 0x0003
151
POWERSTATE_MASK           = 0x0003
152
POWERSTATE_D0             = 0x0000
152
POWERSTATE_D0             = 0x0000
153
POWERSTATE_D1             = 0x0001
153
POWERSTATE_D1             = 0x0001
154
POWERSTATE_D2             = 0x0002
154
POWERSTATE_D2             = 0x0002
155
POWERSTATE_D3             = 0x0003
155
POWERSTATE_D3             = 0x0003
156
 
156
 
157
POWERSTATE2_POWERUP_MASK  = 0x0F11
157
POWERSTATE2_POWERUP_MASK  = 0x0F11
158
POWERSTATE2_POWERUP_REV_A3= 0x0001
158
POWERSTATE2_POWERUP_REV_A3= 0x0001
159
 
159
 
160
RCVCTL_START              = 0x01
160
RCVCTL_START              = 0x01
161
RCVSTAT_BUSY              = 0x01
161
RCVSTAT_BUSY              = 0x01
162
 
162
 
163
XMITCTL_START             = 0x01
163
XMITCTL_START             = 0x01
164
 
164
 
165
LINKSPEED_FORCE           = 0x10000
165
LINKSPEED_FORCE           = 0x10000
166
LINKSPEED_10              = 1000
166
LINKSPEED_10              = 1000
167
LINKSPEED_100             = 100
167
LINKSPEED_100             = 100
168
LINKSPEED_1000            = 50
168
LINKSPEED_1000            = 50
169
 
169
 
170
RINGSZ_TXSHIFT            = 0
170
RINGSZ_TXSHIFT            = 0
171
RINGSZ_RXSHIFT            = 16
171
RINGSZ_RXSHIFT            = 16
172
 
172
 
173
LPA_1000FULL                    = 0x0800
173
LPA_1000FULL                    = 0x0800
174
 
174
 
175
; Link partner ability register.
175
; Link partner ability register.
176
LPA_SLCT                        = 0x001f  ; Same as advertise selector
176
LPA_SLCT                        = 0x001f  ; Same as advertise selector
177
LPA_10HALF                      = 0x0020  ; Can do 10mbps half-duplex
177
LPA_10HALF                      = 0x0020  ; Can do 10mbps half-duplex
178
LPA_10FULL                      = 0x0040  ; Can do 10mbps full-duplex
178
LPA_10FULL                      = 0x0040  ; Can do 10mbps full-duplex
179
LPA_100HALF                     = 0x0080  ; Can do 100mbps half-duplex
179
LPA_100HALF                     = 0x0080  ; Can do 100mbps half-duplex
180
LPA_100FULL                     = 0x0100  ; Can do 100mbps full-duplex
180
LPA_100FULL                     = 0x0100  ; Can do 100mbps full-duplex
181
LPA_100BASE4                    = 0x0200  ; Can do 100mbps 4k packets
181
LPA_100BASE4                    = 0x0200  ; Can do 100mbps 4k packets
182
LPA_RESV                        = 0x1c00  ; Unused...
182
LPA_RESV                        = 0x1c00  ; Unused...
183
LPA_RFAULT                      = 0x2000  ; Link partner faulted
183
LPA_RFAULT                      = 0x2000  ; Link partner faulted
184
LPA_LPACK                       = 0x4000  ; Link partner acked us
184
LPA_LPACK                       = 0x4000  ; Link partner acked us
185
LPA_NPAGE                       = 0x8000  ; Next page bit
185
LPA_NPAGE                       = 0x8000  ; Next page bit
186
 
186
 
187
MII_READ                        = (-1)
187
MII_READ                        = (-1)
188
MII_PHYSID1                     = 0x02    ; PHYS ID 1
188
MII_PHYSID1                     = 0x02    ; PHYS ID 1
189
MII_PHYSID2                     = 0x03    ; PHYS ID 2
189
MII_PHYSID2                     = 0x03    ; PHYS ID 2
190
MII_BMCR                        = 0x00    ; Basic mode control register
190
MII_BMCR                        = 0x00    ; Basic mode control register
191
MII_BMSR                        = 0x01    ; Basic mode status register
191
MII_BMSR                        = 0x01    ; Basic mode status register
192
MII_ADVERTISE                   = 0x04    ; Advertisement control reg
192
MII_ADVERTISE                   = 0x04    ; Advertisement control reg
193
MII_LPA                         = 0x05    ; Link partner ability reg
193
MII_LPA                         = 0x05    ; Link partner ability reg
194
MII_SREVISION                   = 0x16    ; Silicon revision
194
MII_SREVISION                   = 0x16    ; Silicon revision
195
MII_RESV1                       = 0x17    ; Reserved...
195
MII_RESV1                       = 0x17    ; Reserved...
196
MII_NCONFIG                     = 0x1c    ; Network interface config
196
MII_NCONFIG                     = 0x1c    ; Network interface config
197
 
197
 
198
; PHY defines
198
; PHY defines
199
PHY_OUI_MARVELL                 = 0x5043
199
PHY_OUI_MARVELL                 = 0x5043
200
PHY_OUI_CICADA                  = 0x03f1
200
PHY_OUI_CICADA                  = 0x03f1
201
PHYID1_OUI_MASK                 = 0x03ff
201
PHYID1_OUI_MASK                 = 0x03ff
202
PHYID1_OUI_SHFT                 = 6
202
PHYID1_OUI_SHFT                 = 6
203
PHYID2_OUI_MASK                 = 0xfc00
203
PHYID2_OUI_MASK                 = 0xfc00
204
PHYID2_OUI_SHFT                 = 10
204
PHYID2_OUI_SHFT                 = 10
205
PHY_INIT1                       = 0x0f000
205
PHY_INIT1                       = 0x0f000
206
PHY_INIT2                       = 0x0e00
206
PHY_INIT2                       = 0x0e00
207
PHY_INIT3                       = 0x01000
207
PHY_INIT3                       = 0x01000
208
PHY_INIT4                       = 0x0200
208
PHY_INIT4                       = 0x0200
209
PHY_INIT5                       = 0x0004
209
PHY_INIT5                       = 0x0004
210
PHY_INIT6                       = 0x02000
210
PHY_INIT6                       = 0x02000
211
PHY_GIGABIT                     = 0x0100
211
PHY_GIGABIT                     = 0x0100
212
 
212
 
213
PHY_TIMEOUT                     = 0x1
213
PHY_TIMEOUT                     = 0x1
214
PHY_ERROR                       = 0x2
214
PHY_ERROR                       = 0x2
215
 
215
 
216
PHY_100                         = 0x1
216
PHY_100                         = 0x1
217
PHY_1000                        = 0x2
217
PHY_1000                        = 0x2
218
PHY_HALF                        = 0x100
218
PHY_HALF                        = 0x100
219
 
219
 
220
PHY_RGMII                       = 0x10000000
220
PHY_RGMII                       = 0x10000000
221
 
221
 
222
; desc_ver values:
222
; desc_ver values:
223
; This field has two purposes:
223
; This field has two purposes:
224
; - Newer nics uses a different ring layout. The layout is selected by
224
; - Newer nics uses a different ring layout. The layout is selected by
225
;   comparing np->desc_ver with DESC_VER_xy.
225
;   comparing np->desc_ver with DESC_VER_xy.
226
; - It contains bits that are forced on when writing to TxRxControl.
226
; - It contains bits that are forced on when writing to TxRxControl.
227
DESC_VER_1                      = 0x0
227
DESC_VER_1                      = 0x0
228
DESC_VER_2                      = (0x02100 or TXRXCTL_RXCHECK)
228
DESC_VER_2                      = (0x02100 or TXRXCTL_RXCHECK)
229
 
229
 
230
NV_TX_LASTPACKET                = (1 shl 16)
230
NV_TX_LASTPACKET                = (1 shl 16)
231
NV_TX_RETRYERROR                = (1 shl 19)
231
NV_TX_RETRYERROR                = (1 shl 19)
232
NV_TX_LASTPACKET1               = (1 shl 24)
232
NV_TX_LASTPACKET1               = (1 shl 24)
233
NV_TX_DEFERRED                  = (1 shl 26)
233
NV_TX_DEFERRED                  = (1 shl 26)
234
NV_TX_CARRIERLOST               = (1 shl 27)
234
NV_TX_CARRIERLOST               = (1 shl 27)
235
NV_TX_LATECOLLISION             = (1 shl 28)
235
NV_TX_LATECOLLISION             = (1 shl 28)
236
NV_TX_UNDERFLOW                 = (1 shl 29)
236
NV_TX_UNDERFLOW                 = (1 shl 29)
237
NV_TX_ERROR                     = (1 shl 30)
237
NV_TX_ERROR                     = (1 shl 30)
238
NV_TX_VALID                     = (1 shl 31)
238
NV_TX_VALID                     = (1 shl 31)
239
 
239
 
240
NV_TX2_LASTPACKET               = (1 shl 29)
240
NV_TX2_LASTPACKET               = (1 shl 29)
241
NV_TX2_RETRYERROR               = (1 shl 18)
241
NV_TX2_RETRYERROR               = (1 shl 18)
242
NV_TX2_LASTPACKET1              = (1 shl 23)
242
NV_TX2_LASTPACKET1              = (1 shl 23)
243
NV_TX2_DEFERRED                 = (1 shl 25)
243
NV_TX2_DEFERRED                 = (1 shl 25)
244
NV_TX2_CARRIERLOST              = (1 shl 26)
244
NV_TX2_CARRIERLOST              = (1 shl 26)
245
NV_TX2_LATECOLLISION            = (1 shl 27)
245
NV_TX2_LATECOLLISION            = (1 shl 27)
246
NV_TX2_UNDERFLOW                = (1 shl 28)
246
NV_TX2_UNDERFLOW                = (1 shl 28)
247
; error and valid are the same for both
247
; error and valid are the same for both
248
NV_TX2_ERROR                    = (1 shl 30)
248
NV_TX2_ERROR                    = (1 shl 30)
249
NV_TX2_VALID                    = (1 shl 31)
249
NV_TX2_VALID                    = (1 shl 31)
250
 
250
 
251
NV_RX_DESCRIPTORVALID           = (1 shl 16)
251
NV_RX_DESCRIPTORVALID           = (1 shl 16)
252
NV_RX_AVAIL                     = (1 shl 31)
252
NV_RX_AVAIL                     = (1 shl 31)
253
 
253
 
254
NV_RX2_DESCRIPTORVALID          = (1 shl 29)
254
NV_RX2_DESCRIPTORVALID          = (1 shl 29)
255
 
255
 
256
FLAG_MASK_V1                    = 0xffff0000
256
FLAG_MASK_V1                    = 0xffff0000
257
FLAG_MASK_V2                    = 0xffffc000
257
FLAG_MASK_V2                    = 0xffffc000
258
LEN_MASK_V1                     = (0xffffffff xor FLAG_MASK_V1)
258
LEN_MASK_V1                     = (0xffffffff xor FLAG_MASK_V1)
259
LEN_MASK_V2                     = (0xffffffff xor FLAG_MASK_V2)
259
LEN_MASK_V2                     = (0xffffffff xor FLAG_MASK_V2)
260
 
260
 
261
; Miscelaneous hardware related defines:
261
; Miscelaneous hardware related defines:
262
NV_PCI_REGSZ_VER1               = 0x270
262
NV_PCI_REGSZ_VER1               = 0x270
263
NV_PCI_REGSZ_VER2               = 0x604
263
NV_PCI_REGSZ_VER2               = 0x604
264
; various timeout delays: all in usec
264
; various timeout delays: all in usec
265
NV_TXRX_RESET_DELAY             = 4
265
NV_TXRX_RESET_DELAY             = 4
266
NV_TXSTOP_DELAY1                = 10
266
NV_TXSTOP_DELAY1                = 10
267
NV_TXSTOP_DELAY1MAX             = 500000
267
NV_TXSTOP_DELAY1MAX             = 500000
268
NV_TXSTOP_DELAY2                = 100
268
NV_TXSTOP_DELAY2                = 100
269
NV_RXSTOP_DELAY1                = 10
269
NV_RXSTOP_DELAY1                = 10
270
NV_RXSTOP_DELAY1MAX             = 500000
270
NV_RXSTOP_DELAY1MAX             = 500000
271
NV_RXSTOP_DELAY2                = 100
271
NV_RXSTOP_DELAY2                = 100
272
NV_SETUP5_DELAY                 = 5
272
NV_SETUP5_DELAY                 = 5
273
NV_SETUP5_DELAYMAX              = 50000
273
NV_SETUP5_DELAYMAX              = 50000
274
NV_POWERUP_DELAY                = 5
274
NV_POWERUP_DELAY                = 5
275
NV_POWERUP_DELAYMAX             = 5000
275
NV_POWERUP_DELAYMAX             = 5000
276
NV_MIIBUSY_DELAY                = 50
276
NV_MIIBUSY_DELAY                = 50
277
NV_MIIPHY_DELAY                 = 10
277
NV_MIIPHY_DELAY                 = 10
278
NV_MIIPHY_DELAYMAX              = 10000
278
NV_MIIPHY_DELAYMAX              = 10000
279
NV_MAC_RESET_DELAY              = 64
279
NV_MAC_RESET_DELAY              = 64
280
NV_WAKEUPPATTERNS               = 5
280
NV_WAKEUPPATTERNS               = 5
281
NV_WAKEUPMASKENTRIES            = 4
281
NV_WAKEUPMASKENTRIES            = 4
282
 
282
 
283
; Advertisement control register.
283
; Advertisement control register.
284
ADVERTISE_SLCT                  = 0x001f  ; Selector bits
284
ADVERTISE_SLCT                  = 0x001f  ; Selector bits
285
ADVERTISE_CSMA                  = 0x0001  ; Only selector supported
285
ADVERTISE_CSMA                  = 0x0001  ; Only selector supported
286
ADVERTISE_10HALF                = 0x0020  ; Try for 10mbps half-duplex
286
ADVERTISE_10HALF                = 0x0020  ; Try for 10mbps half-duplex
287
ADVERTISE_10FULL                = 0x0040  ; Try for 10mbps full-duplex
287
ADVERTISE_10FULL                = 0x0040  ; Try for 10mbps full-duplex
288
ADVERTISE_100HALF               = 0x0080  ; Try for 100mbps half-duplex
288
ADVERTISE_100HALF               = 0x0080  ; Try for 100mbps half-duplex
289
ADVERTISE_100FULL               = 0x0100  ; Try for 100mbps full-duplex
289
ADVERTISE_100FULL               = 0x0100  ; Try for 100mbps full-duplex
290
ADVERTISE_100BASE4              = 0x0200  ; Try for 100mbps 4k packets
290
ADVERTISE_100BASE4              = 0x0200  ; Try for 100mbps 4k packets
291
ADVERTISE_RESV                  = 0x1c00  ; Unused...
291
ADVERTISE_RESV                  = 0x1c00  ; Unused...
292
ADVERTISE_RFAULT                = 0x2000  ; Say we can detect faults
292
ADVERTISE_RFAULT                = 0x2000  ; Say we can detect faults
293
ADVERTISE_LPACK                 = 0x4000  ; Ack link partners response
293
ADVERTISE_LPACK                 = 0x4000  ; Ack link partners response
294
ADVERTISE_NPAGE                 = 0x8000  ; Next page bit
294
ADVERTISE_NPAGE                 = 0x8000  ; Next page bit
295
 
295
 
296
ADVERTISE_FULL                  = (ADVERTISE_100FULL or ADVERTISE_10FULL or ADVERTISE_CSMA)
296
ADVERTISE_FULL                  = (ADVERTISE_100FULL or ADVERTISE_10FULL or ADVERTISE_CSMA)
297
ADVERTISE_ALL                   = (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL)
297
ADVERTISE_ALL                   = (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL)
298
 
298
 
299
MII_1000BT_CR                   = 0x09
299
MII_1000BT_CR                   = 0x09
300
MII_1000BT_SR                   = 0x0a
300
MII_1000BT_SR                   = 0x0a
301
ADVERTISE_1000FULL              = 0x0200
301
ADVERTISE_1000FULL              = 0x0200
302
ADVERTISE_1000HALF              = 0x0100
302
ADVERTISE_1000HALF              = 0x0100
303
 
303
 
304
BMCR_ANRESTART                  = 0x0200  ; Auto negotiation restart
304
BMCR_ANRESTART                  = 0x0200  ; Auto negotiation restart
305
BMCR_ANENABLE                   = 0x1000  ; Enable auto negotiation
305
BMCR_ANENABLE                   = 0x1000  ; Enable auto negotiation
306
BMCR_SPEED100                   = 0x2000  ; Select 100Mbps
306
BMCR_SPEED100                   = 0x2000  ; Select 100Mbps
307
BMCR_LOOPBACK                   = 0x4000  ; TXD loopback bits
307
BMCR_LOOPBACK                   = 0x4000  ; TXD loopback bits
308
BMCR_RESET                      = 0x8000  ; Reset the DP83840
308
BMCR_RESET                      = 0x8000  ; Reset the DP83840
309
 
309
 
310
; Basic mode status register.
310
; Basic mode status register.
311
BMSR_ERCAP                      = 0x0001  ; Ext-reg capability
311
BMSR_ERCAP                      = 0x0001  ; Ext-reg capability
312
BMSR_JCD                        = 0x0002  ; Jabber detected
312
BMSR_JCD                        = 0x0002  ; Jabber detected
313
BMSR_LSTATUS                    = 0x0004  ; Link status
313
BMSR_LSTATUS                    = 0x0004  ; Link status
314
BMSR_ANEGCAPABLE                = 0x0008  ; Able to do auto-negotiation
314
BMSR_ANEGCAPABLE                = 0x0008  ; Able to do auto-negotiation
315
BMSR_RFAULT                     = 0x0010  ; Remote fault detected
315
BMSR_RFAULT                     = 0x0010  ; Remote fault detected
316
BMSR_ANEGCOMPLETE               = 0x0020  ; Auto-negotiation complete
316
BMSR_ANEGCOMPLETE               = 0x0020  ; Auto-negotiation complete
317
BMSR_RESV                       = 0x07c0  ; Unused...
317
BMSR_RESV                       = 0x07c0  ; Unused...
318
BMSR_10HALF                     = 0x0800  ; Can do 10mbps, half-duplex
318
BMSR_10HALF                     = 0x0800  ; Can do 10mbps, half-duplex
319
BMSR_10FULL                     = 0x1000  ; Can do 10mbps, full-duplex
319
BMSR_10FULL                     = 0x1000  ; Can do 10mbps, full-duplex
320
BMSR_100HALF                    = 0x2000  ; Can do 100mbps, half-duplex
320
BMSR_100HALF                    = 0x2000  ; Can do 100mbps, half-duplex
321
BMSR_100FULL                    = 0x4000  ; Can do 100mbps, full-duplex
321
BMSR_100FULL                    = 0x4000  ; Can do 100mbps, full-duplex
322
BMSR_100BASE4                   = 0x8000  ; Can do 100mbps, 4k packets
322
BMSR_100BASE4                   = 0x8000  ; Can do 100mbps, 4k packets
323
 
323
 
324
struct  TxDesc
324
struct  TxDesc
325
        PacketBuffer            dd ?
325
        PacketBuffer            dd ?
326
        FlagLen                 dd ?
326
        FlagLen                 dd ?
327
ends
327
ends
328
 
328
 
329
struct  RxDesc
329
struct  RxDesc
330
        PacketBuffer            dd ?
330
        PacketBuffer            dd ?
331
        FlagLen                 dd ?
331
        FlagLen                 dd ?
332
ends
332
ends
333
 
333
 
334
struct  device                  ETH_DEVICE
334
struct  device                  ETH_DEVICE
335
 
335
 
336
        pci_bus                 dd ?
336
        pci_bus                 dd ?
337
        pci_dev                 dd ?
337
        pci_dev                 dd ?
338
 
338
 
339
        mmio_addr               dd ?
339
        mmio_addr               dd ?
340
        vendor_id               dw ?
340
        vendor_id               dw ?
341
        device_id               dw ?
341
        device_id               dw ?
342
        txflags                 dd ?
342
        txflags                 dd ?
343
        desc_ver                dd ?
343
        desc_ver                dd ?
344
        irqmask                 dd ?
344
        irqmask                 dd ?
345
        wolenabled              dd ?
345
        wolenabled              dd ?
346
        in_shutdown             dd ?
346
        in_shutdown             dd ?
347
        cur_rx                  dd ?
347
        cur_rx                  dd ?
348
        cur_tx                  dd ?
348
        cur_tx                  dd ?
349
        last_tx                 dd ?
349
        last_tx                 dd ?
350
        phyaddr                 dd ?
350
        phyaddr                 dd ?
351
        phy_oui                 dd ?
351
        phy_oui                 dd ?
352
        gigabit                 dd ?
352
        gigabit                 dd ?
353
        needs_mac_reset         dd ?
353
        needs_mac_reset         dd ?
354
        linkspeed               dd ?
354
        linkspeed               dd ?
355
        duplex                  dd ?
355
        duplex                  dd ?
356
        nocable                 dd ?
356
        nocable                 dd ?
357
 
357
 
358
                                rb 0x100 - ($ and 0xff)
358
                                rb 0x100 - ($ and 0xff)
359
        tx_ring                 rd (TX_RING * sizeof.TxDesc) /4*2
359
        tx_ring                 rd (TX_RING * sizeof.TxDesc) /4*2
360
 
360
 
361
                                rb 0x100 - ($ and 0xff)
361
                                rb 0x100 - ($ and 0xff)
362
        rx_ring                 rd (RX_RING * sizeof.RxDesc) /4*2
362
        rx_ring                 rd (RX_RING * sizeof.RxDesc) /4*2
363
 
363
 
364
ends
364
ends
365
 
365
 
366
 
366
 
367
 
367
 
368
virtual at edi
368
virtual at edi
369
        IrqStatus               dd ?
369
        IrqStatus               dd ?
370
        IrqMask                 dd ?
370
        IrqMask                 dd ?
371
        UnknownSetupReg6        dd ?
371
        UnknownSetupReg6        dd ?
372
        PollingInterval         dd ?
372
        PollingInterval         dd ?
373
end virtual
373
end virtual
374
 
374
 
375
virtual at edi + 0x3c
375
virtual at edi + 0x3c
376
        MacReset                dd ?
376
        MacReset                dd ?
377
end virtual
377
end virtual
378
 
378
 
379
virtual at edi + 0x80
379
virtual at edi + 0x80
380
        Misc1                   dd ?
380
        Misc1                   dd ?
381
        TransmitterControl      dd ?
381
        TransmitterControl      dd ?
382
        TransmitterStatus       dd ?
382
        TransmitterStatus       dd ?
383
        PacketFilterFlags       dd ?
383
        PacketFilterFlags       dd ?
384
        OffloadConfig           dd ?
384
        OffloadConfig           dd ?
385
        ReceiverControl         dd ?
385
        ReceiverControl         dd ?
386
        ReceiverStatus          dd ?
386
        ReceiverStatus          dd ?
387
        RandomSeed              dd ?
387
        RandomSeed              dd ?
388
        UnknownSetupReg1        dd ?
388
        UnknownSetupReg1        dd ?
389
        UnknownSetupReg2        dd ?
389
        UnknownSetupReg2        dd ?
390
        MacAddrA                dd ?
390
        MacAddrA                dd ?
391
        MacAddrB                dd ?
391
        MacAddrB                dd ?
392
        MulticastAddrA          dd ?
392
        MulticastAddrA          dd ?
393
        MulticastAddrB          dd ?
393
        MulticastAddrB          dd ?
394
        MulticastMaskA          dd ?
394
        MulticastMaskA          dd ?
395
        MulticastMaskB          dd ?
395
        MulticastMaskB          dd ?
396
        PhyInterface            dd ?
396
        PhyInterface            dd ?
397
end virtual
397
end virtual
398
 
398
 
399
virtual at edi + 0x100
399
virtual at edi + 0x100
400
        TxRingPhysAddr          dd ?
400
        TxRingPhysAddr          dd ?
401
        RxRingPhysAddr          dd ?
401
        RxRingPhysAddr          dd ?
402
        RingSizes               dd ?
402
        RingSizes               dd ?
403
        UnknownTransmitterReg   dd ?
403
        UnknownTransmitterReg   dd ?
404
        LinkSpeed               dd ?
404
        LinkSpeed               dd ?
405
end virtual
405
end virtual
406
 
406
 
407
virtual at edi + 0x130
407
virtual at edi + 0x130
408
        UnknownSetupReg5        dd ?
408
        UnknownSetupReg5        dd ?
409
end virtual
409
end virtual
410
 
410
 
411
virtual at edi + 0x13c
411
virtual at edi + 0x13c
412
        UnknownSetupReg3        dd ?
412
        UnknownSetupReg3        dd ?
413
end virtual
413
end virtual
414
 
414
 
415
virtual at edi + 0x144
415
virtual at edi + 0x144
416
        TxRxControl             dd ?
416
        TxRxControl             dd ?
417
end virtual
417
end virtual
418
 
418
 
419
virtual at edi + 0x180
419
virtual at edi + 0x180
420
        MIIStatus               dd ?
420
        MIIStatus               dd ?
421
        UnknownSetupReg4        dd ?
421
        UnknownSetupReg4        dd ?
422
        AdapterControl          dd ?
422
        AdapterControl          dd ?
423
        MIISpeed                dd ?
423
        MIISpeed                dd ?
424
        MIIControl              dd ?
424
        MIIControl              dd ?
425
        MIIData                 dd ?
425
        MIIData                 dd ?
426
end virtual
426
end virtual
427
 
427
 
428
virtual at edi + 0x200
428
virtual at edi + 0x200
429
        WakeUpFlags             dd ?
429
        WakeUpFlags             dd ?
430
end virtual
430
end virtual
431
 
431
 
432
virtual at edi + 0x26c
432
virtual at edi + 0x26c
433
        PowerState              dd ?
433
        PowerState              dd ?
434
end virtual
434
end virtual
435
 
435
 
436
virtual at edi + 0x600
436
virtual at edi + 0x600
437
        PowerState2             dd ?
437
        PowerState2             dd ?
438
end virtual
438
end virtual
439
 
439
 
440
 
440
 
441
 
441
 
442
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
442
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
443
;;                        ;;
443
;;                        ;;
444
;; proc START             ;;
444
;; proc START             ;;
445
;;                        ;;
445
;;                        ;;
446
;; (standard driver proc) ;;
446
;; (standard driver proc) ;;
447
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
447
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448
 
448
 
449
proc START c, reason:dword, cmdline:dword
449
proc START c, reason:dword, cmdline:dword
450
 
450
 
451
        cmp     [reason], DRV_ENTRY
451
        cmp     [reason], DRV_ENTRY
452
        jne     .fail
452
        jne     .fail
453
 
453
 
454
        DEBUGF  2,"Loading driver\n"
454
        DEBUGF  2,"Loading driver\n"
455
        invoke  RegService, my_service, service_proc
455
        invoke  RegService, my_service, service_proc
456
        ret
456
        ret
457
 
457
 
458
  .fail:
458
  .fail:
459
        xor     eax, eax
459
        xor     eax, eax
460
        ret
460
        ret
461
 
461
 
462
endp
462
endp
463
 
463
 
464
 
464
 
465
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
465
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
466
;;                        ;;
466
;;                        ;;
467
;; proc SERVICE_PROC      ;;
467
;; proc SERVICE_PROC      ;;
468
;;                        ;;
468
;;                        ;;
469
;; (standard driver proc) ;;
469
;; (standard driver proc) ;;
470
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
470
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
471
 
471
 
472
proc service_proc stdcall, ioctl:dword
472
proc service_proc stdcall, ioctl:dword
473
 
473
 
474
        mov     edx, [ioctl]
474
        mov     edx, [ioctl]
475
        mov     eax, [edx + IOCTL.io_code]
475
        mov     eax, [edx + IOCTL.io_code]
476
 
476
 
477
;------------------------------------------------------
477
;------------------------------------------------------
478
 
478
 
479
        cmp     eax, 0 ;SRV_GETVERSION
479
        cmp     eax, 0 ;SRV_GETVERSION
480
        jne     @F
480
        jne     @F
481
 
481
 
482
        cmp     [edx + IOCTL.out_size], 4
482
        cmp     [edx + IOCTL.out_size], 4
483
        jb      .fail
483
        jb      .fail
484
        mov     eax, [edx + IOCTL.output]
484
        mov     eax, [edx + IOCTL.output]
485
        mov     [eax], dword API_VERSION
485
        mov     [eax], dword API_VERSION
486
 
486
 
487
        xor     eax, eax
487
        xor     eax, eax
488
        ret
488
        ret
489
 
489
 
490
;------------------------------------------------------
490
;------------------------------------------------------
491
  @@:
491
  @@:
492
        cmp     eax, 1 ;SRV_HOOK
492
        cmp     eax, 1 ;SRV_HOOK
493
        jne     .fail
493
        jne     .fail
494
 
494
 
495
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
495
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
496
        jb      .fail
496
        jb      .fail
497
 
497
 
498
        mov     eax, [edx + IOCTL.input]
498
        mov     eax, [edx + IOCTL.input]
499
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
499
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
500
        jne     .fail                                   ; other types arent supported for this card yet
500
        jne     .fail                                   ; other types arent supported for this card yet
501
 
501
 
502
; check if the device is already listed
502
; check if the device is already listed
503
 
503
 
504
        mov     esi, device_list
504
        mov     esi, device_list
505
        mov     ecx, [devices]
505
        mov     ecx, [devices]
506
        test    ecx, ecx
506
        test    ecx, ecx
507
        jz      .firstdevice
507
        jz      .firstdevice
508
 
508
 
509
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
509
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
510
        mov     ax, [eax+1]
510
        mov     ax, [eax+1]
511
  .nextdevice:
511
  .nextdevice:
512
        mov     ebx, [esi]
512
        mov     ebx, [esi]
513
        cmp     al, byte [ebx + device.pci_bus]               ; compare with pci and device num in device list (notice the usage of word instead of byte)
513
        cmp     al, byte [ebx + device.pci_bus]               ; compare with pci and device num in device list (notice the usage of word instead of byte)
514
        jne     @f
514
        jne     @f
515
        cmp     ah, byte [ebx + device.pci_dev]
515
        cmp     ah, byte [ebx + device.pci_dev]
516
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
516
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
517
  @@:
517
  @@:
518
        add     esi, 4
518
        add     esi, 4
519
        loop    .nextdevice
519
        loop    .nextdevice
520
 
520
 
521
 
521
 
522
; This device doesnt have its own eth_device structure yet, lets create one
522
; This device doesnt have its own eth_device structure yet, lets create one
523
  .firstdevice:
523
  .firstdevice:
524
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
524
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
525
        jae     .fail
525
        jae     .fail
526
 
526
 
527
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
527
        allocate_and_clear ebx, sizeof.device, .fail      ; Allocate the buffer for device structure
528
 
528
 
529
; Fill in the direct call addresses into the struct
529
; Fill in the direct call addresses into the struct
530
 
530
 
531
        mov     [ebx + device.reset], reset
531
        mov     [ebx + device.reset], reset
532
        mov     [ebx + device.transmit], transmit
532
        mov     [ebx + device.transmit], transmit
533
        mov     [ebx + device.unload], .fail
533
        mov     [ebx + device.unload], .fail
534
        mov     [ebx + device.name], my_service
534
        mov     [ebx + device.name], my_service
535
 
535
 
536
; save the pci bus and device numbers
536
; save the pci bus and device numbers
537
 
537
 
538
        mov     eax, [edx + IOCTL.input]
538
        mov     eax, [edx + IOCTL.input]
539
        movzx   ecx, byte [eax+1]
539
        movzx   ecx, byte [eax+1]
540
        mov     [ebx + device.pci_bus], ecx
540
        mov     [ebx + device.pci_bus], ecx
541
        movzx   ecx, byte [eax+2]
541
        movzx   ecx, byte [eax+2]
542
        mov     [ebx + device.pci_dev], ecx
542
        mov     [ebx + device.pci_dev], ecx
543
 
543
 
544
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x\n", [ebx + device.pci_dev], [ebx + device.pci_bus]
544
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x\n", [ebx + device.pci_dev], [ebx + device.pci_bus]
545
 
545
 
546
; Ok, the eth_device structure is ready, let's probe the device
546
; Ok, the eth_device structure is ready, let's probe the device
547
        call    probe                                                   ; this function will output in eax
547
        call    probe                                                   ; this function will output in eax
548
        test    eax, eax
548
        test    eax, eax
549
        jnz     .err                                                    ; If an error occured, exit
549
        jnz     .err                                                    ; If an error occured, exit
550
 
550
 
551
        mov     eax, [devices]                                          ; Add the device structure to our device list
551
        mov     eax, [devices]                                          ; Add the device structure to our device list
552
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
552
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
553
        inc     [devices]                                               ;
553
        inc     [devices]                                               ;
554
 
554
 
555
        mov     [ebx + device.type], NET_TYPE_ETH
555
        mov     [ebx + device.type], NET_TYPE_ETH
556
        invoke  NetRegDev
556
        invoke  NetRegDev
557
 
557
 
558
        cmp     eax, -1
558
        cmp     eax, -1
559
        je      .destroy
559
        je      .destroy
560
 
560
 
561
        ret
561
        ret
562
 
562
 
563
; If the device was already loaded, find the device number and return it in eax
563
; If the device was already loaded, find the device number and return it in eax
564
 
564
 
565
  .find_devicenum:
565
  .find_devicenum:
566
        DEBUGF  1,"Trying to find device number of already registered device\n"
566
        DEBUGF  1,"Trying to find device number of already registered device\n"
567
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
567
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
568
                                                                        ; into a device number in edi
568
                                                                        ; into a device number in edi
569
        mov     eax, edi                                                ; Application wants it in eax instead
569
        mov     eax, edi                                                ; Application wants it in eax instead
570
        DEBUGF  1,"Kernel says: %u\n", eax
570
        DEBUGF  1,"Kernel says: %u\n", eax
571
        ret
571
        ret
572
 
572
 
573
; If an error occured, remove all allocated data and exit (returning -1 in eax)
573
; If an error occured, remove all allocated data and exit (returning -1 in eax)
574
 
574
 
575
  .destroy:
575
  .destroy:
576
        ; todo: reset device into virgin state
576
        ; todo: reset device into virgin state
577
 
577
 
578
  .err:
578
  .err:
579
        invoke  KernelFree, ebx
579
        invoke  KernelFree, ebx
580
  .fail:
580
  .fail:
581
 
581
 
582
        ret
582
        ret
583
 
583
 
584
;------------------------------------------------------
584
;------------------------------------------------------
585
endp
585
endp
586
 
586
 
587
 
587
 
588
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
588
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
589
;;                                                                        ;;
589
;;                                                                        ;;
590
;;        Actual Hardware dependent code starts here                      ;;
590
;;        Actual Hardware dependent code starts here                      ;;
591
;;                                                                        ;;
591
;;                                                                        ;;
592
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
592
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
593
 
593
 
594
 
594
 
595
 
595
 
596
 
596
 
597
;***************************************************************************
597
;***************************************************************************
598
;   Function
598
;   Function
599
;      probe
599
;      probe
600
;   Description
600
;   Description
601
;      Searches for an ethernet card, enables it and clears the rx buffer
601
;      Searches for an ethernet card, enables it and clears the rx buffer
602
;
602
;
603
;***************************************************************************
603
;***************************************************************************
604
align 4
604
align 4
605
probe:
605
probe:
606
 
606
 
607
        DEBUGF  1,"probe\n"
607
        DEBUGF  1,"probe\n"
608
 
608
 
609
        mov     [ebx + device.needs_mac_reset], 0
609
        mov     [ebx + device.needs_mac_reset], 0
610
 
610
 
611
; Make the device a bus master and enable response in I/O space
611
; Make the device a bus master and enable response in I/O space
612
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
612
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
613
        or      al, PCI_CMD_MASTER + PCI_CMD_PIO ; + PCI_CMD_MMIO
613
        or      al, PCI_CMD_MASTER + PCI_CMD_PIO ; + PCI_CMD_MMIO
614
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
614
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
615
 
615
 
616
; Adjust PCI latency to be at least 32
616
; Adjust PCI latency to be at least 32
617
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency
617
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency
618
        cmp     al, 32
618
        cmp     al, 32
619
        jae     @f
619
        jae     @f
620
        mov     al, 32
620
        mov     al, 32
621
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
621
        invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
622
  @@:
622
  @@:
623
 
623
 
624
; Now, it's time to find the base mmio addres of the PCI device
624
; Now, it's time to find the base mmio addres of the PCI device
625
        stdcall PCI_find_mmio32, [ebx + device.pci_bus], [ebx + device.pci_dev] ; returns in eax
625
        stdcall PCI_find_mmio32, [ebx + device.pci_bus], [ebx + device.pci_dev] ; returns in eax
626
        DEBUGF 1,"mmio_addr= 0x%x\n", eax
626
        DEBUGF 1,"mmio_addr= 0x%x\n", eax
627
 
627
 
628
; Create virtual mapping of the physical memory
628
; Create virtual mapping of the physical memory
629
        invoke  MapIoMem, eax, 10000h, PG_SW + PG_NOCACHE
629
        invoke  MapIoMem, eax, 10000h, PG_SW + PG_NOCACHE
630
        test    eax, eax
630
        test    eax, eax
631
        jz      fail
631
        jz      fail
632
        mov     [ebx + device.mmio_addr], eax
632
        mov     [ebx + device.mmio_addr], eax
633
        DEBUGF 1,"mapped mmio_addr= 0x%x\n", eax
633
        DEBUGF 1,"mapped mmio_addr= 0x%x\n", eax
634
 
634
 
635
; Read PCI vendor/device ID
635
; Read PCI vendor/device ID
636
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.vendor_id
636
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.vendor_id
637
        mov     dword[ebx + device.vendor_id], eax
637
        mov     dword[ebx + device.vendor_id], eax
638
        DEBUGF 1,"vendor = 0x%x\n", [ebx + device.vendor_id]:4
638
        DEBUGF 1,"vendor = 0x%x\n", [ebx + device.vendor_id]:4
639
        DEBUGF 1,"device = 0x%x\n", [ebx + device.device_id]:4
639
        DEBUGF 1,"device = 0x%x\n", [ebx + device.device_id]:4
640
 
640
 
641
;-------------------------------------
641
;-------------------------------------
642
; handle different descriptor versions
642
; handle different descriptor versions
643
        mov     [ebx + device.desc_ver], DESC_VER_1
643
        mov     [ebx + device.desc_ver], DESC_VER_1
644
        mov     ax, [ebx + device.device_id]
644
        mov     ax, [ebx + device.device_id]
645
        cmp     ax, PCI_DEVICE_ID_NVIDIA_NVENET_1
645
        cmp     ax, PCI_DEVICE_ID_NVIDIA_NVENET_1
646
        je      .ver1
646
        je      .ver1
647
        cmp     ax, PCI_DEVICE_ID_NVIDIA_NVENET_2
647
        cmp     ax, PCI_DEVICE_ID_NVIDIA_NVENET_2
648
        je      .ver1
648
        je      .ver1
649
        cmp     ax, PCI_DEVICE_ID_NVIDIA_NVENET_3
649
        cmp     ax, PCI_DEVICE_ID_NVIDIA_NVENET_3
650
        je      .ver1
650
        je      .ver1
651
        mov     [ebx + device.desc_ver], DESC_VER_2
651
        mov     [ebx + device.desc_ver], DESC_VER_2
652
  .ver1:
652
  .ver1:
653
 
653
 
654
        call    read_mac
654
        call    read_mac
655
 
655
 
656
        ; disable WOL
656
        ; disable WOL
657
        mov     [WakeUpFlags], 0
657
        mov     [WakeUpFlags], 0
658
        mov     [ebx + device.wolenabled], 0
658
        mov     [ebx + device.wolenabled], 0
659
        
659
        
660
        mov     [ebx + device.txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID)
660
        mov     [ebx + device.txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID)
661
        cmp     [ebx + device.desc_ver], DESC_VER_1
661
        cmp     [ebx + device.desc_ver], DESC_VER_1
662
        jne     @f
662
        jne     @f
663
        mov     [ebx + device.txflags], (NV_TX_LASTPACKET or NV_TX_VALID)
663
        mov     [ebx + device.txflags], (NV_TX_LASTPACKET or NV_TX_VALID)
664
      @@:
664
      @@:
665
 
665
 
666
; BEGIN of switch (pci->dev_id)
666
; BEGIN of switch (pci->dev_id)
667
 
667
 
668
        cmp     [ebx + device.device_id], 0x01C3
668
        cmp     [ebx + device.device_id], 0x01C3
669
        jne     .not_0x01c3
669
        jne     .not_0x01c3
670
        ; nforce
670
        ; nforce
671
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER)         ;;; Was 0
671
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER)         ;;; Was 0
672
        jmp     .find_phy
672
        jmp     .find_phy
673
  .not_0x01c3:
673
  .not_0x01c3:
674
 
674
 
675
        cmp     [ebx + device.device_id], 0x0066
675
        cmp     [ebx + device.device_id], 0x0066
676
        je      @f
676
        je      @f
677
        cmp     [ebx + device.device_id], 0x00D6
677
        cmp     [ebx + device.device_id], 0x00D6
678
        jne     .not_0x0066
678
        jne     .not_0x0066
679
  @@:
679
  @@:
680
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER)         ;;;; was 0
680
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER)         ;;;; was 0
681
        cmp     [ebx + device.desc_ver], DESC_VER_1
681
        cmp     [ebx + device.desc_ver], DESC_VER_1
682
        jne     @f
682
        jne     @f
683
        or      [ebx + device.txflags], NV_TX_LASTPACKET1
683
        or      [ebx + device.txflags], NV_TX_LASTPACKET1
684
        jmp     .find_phy
684
        jmp     .find_phy
685
  @@:
685
  @@:
686
        or      [ebx + device.txflags], NV_TX2_LASTPACKET1
686
        or      [ebx + device.txflags], NV_TX2_LASTPACKET1
687
        jmp     .find_phy
687
        jmp     .find_phy
688
  .not_0x0066:
688
  .not_0x0066:
689
 
689
 
690
        cmp     [ebx + device.device_id], 0x0086
690
        cmp     [ebx + device.device_id], 0x0086
691
        je      @f
691
        je      @f
692
        cmp     [ebx + device.device_id], 0x008c
692
        cmp     [ebx + device.device_id], 0x008c
693
        je      @f
693
        je      @f
694
        cmp     [ebx + device.device_id], 0x00e6
694
        cmp     [ebx + device.device_id], 0x00e6
695
        je      @f
695
        je      @f
696
        cmp     [ebx + device.device_id], 0x00df
696
        cmp     [ebx + device.device_id], 0x00df
697
        je      @f
697
        je      @f
698
        cmp     [ebx + device.device_id], 0x0056
698
        cmp     [ebx + device.device_id], 0x0056
699
        je      @f
699
        je      @f
700
        cmp     [ebx + device.device_id], 0x0057
700
        cmp     [ebx + device.device_id], 0x0057
701
        je      @f
701
        je      @f
702
        cmp     [ebx + device.device_id], 0x0037
702
        cmp     [ebx + device.device_id], 0x0037
703
        je      @f
703
        je      @f
704
        cmp     [ebx + device.device_id], 0x0038
704
        cmp     [ebx + device.device_id], 0x0038
705
        jne     .not_0x0086
705
        jne     .not_0x0086
706
 
706
 
707
      @@:
707
      @@:
708
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER) ;;; was 0
708
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER) ;;; was 0
709
 
709
 
710
        cmp     [ebx + device.desc_ver], DESC_VER_1
710
        cmp     [ebx + device.desc_ver], DESC_VER_1
711
        jne     @f
711
        jne     @f
712
        or      [ebx + device.txflags], NV_TX_LASTPACKET1
712
        or      [ebx + device.txflags], NV_TX_LASTPACKET1
713
        jmp     .find_phy
713
        jmp     .find_phy
714
       @@:
714
       @@:
715
        or      [ebx + device.txflags], NV_TX2_LASTPACKET1
715
        or      [ebx + device.txflags], NV_TX2_LASTPACKET1
716
        jmp     .find_phy
716
        jmp     .find_phy
717
  .not_0x0086:
717
  .not_0x0086:
718
 
718
 
719
;       cmp     word [device_id], 0x0268
719
;       cmp     word [device_id], 0x0268
720
;       je      @f
720
;       je      @f
721
;       cmp     word [device_id], 0x0269
721
;       cmp     word [device_id], 0x0269
722
;       je      @f
722
;       je      @f
723
;       cmp     word [device_id], 0x0372
723
;       cmp     word [device_id], 0x0372
724
;       je      @f
724
;       je      @f
725
;       cmp     word [device_id], 0x0373
725
;       cmp     word [device_id], 0x0373
726
;       je      @f
726
;       je      @f
727
;       jmp     .default_switch
727
;       jmp     .default_switch
728
;@@:
728
;@@:
729
        cmp     [ebx + device.device_id], 0x0268
729
        cmp     [ebx + device.device_id], 0x0268
730
        jb      .undefined
730
        jb      .undefined
731
 
731
 
732
; Get device revision
732
; Get device revision
733
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.revision_id
733
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.revision_id
734
        mov     edi, [ebx + device.mmio_addr]   ;;;;;
734
        mov     edi, [ebx + device.mmio_addr]   ;;;;;
735
 
735
 
736
; take phy and nic out of low power mode
736
; take phy and nic out of low power mode
737
        mov     ecx, [PowerState2]
737
        mov     ecx, [PowerState2]
738
        and     ecx, not POWERSTATE2_POWERUP_MASK
738
        and     ecx, not POWERSTATE2_POWERUP_MASK
739
        cmp     [ebx + device.device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12
739
        cmp     [ebx + device.device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12
740
        je      @f
740
        je      @f
741
        cmp     [ebx + device.device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13
741
        cmp     [ebx + device.device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13
742
        jne     .set_powerstate
742
        jne     .set_powerstate
743
  @@:
743
  @@:
744
        cmp     al, 0xA3
744
        cmp     al, 0xA3
745
        jb      .set_powerstate
745
        jb      .set_powerstate
746
        or      ecx, POWERSTATE2_POWERUP_REV_A3
746
        or      ecx, POWERSTATE2_POWERUP_REV_A3
747
  .set_powerstate:
747
  .set_powerstate:
748
        mov     [PowerState2], ecx
748
        mov     [PowerState2], ecx
749
 
749
 
750
        ; DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ
750
        ; DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ
751
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER)         ; was 0
751
        mov     [ebx + device.irqmask], (IRQMASK_WANTED_2 or IRQ_TIMER)         ; was 0
752
        
752
        
753
        mov     [ebx + device.needs_mac_reset], 1
753
        mov     [ebx + device.needs_mac_reset], 1
754
        cmp     [ebx + device.desc_ver], DESC_VER_1
754
        cmp     [ebx + device.desc_ver], DESC_VER_1
755
        jne     @f
755
        jne     @f
756
        or      [ebx + device.txflags], NV_TX_LASTPACKET1
756
        or      [ebx + device.txflags], NV_TX_LASTPACKET1
757
        jmp     .find_phy
757
        jmp     .find_phy
758
 
758
 
759
       @@:
759
       @@:
760
        cmp     [ebx + device.desc_ver], DESC_VER_2
760
        cmp     [ebx + device.desc_ver], DESC_VER_2
761
        jne     .undefined
761
        jne     .undefined
762
        or      [ebx + device.txflags], NV_TX2_LASTPACKET1
762
        or      [ebx + device.txflags], NV_TX2_LASTPACKET1
763
        jmp     .find_phy
763
        jmp     .find_phy
764
 
764
 
765
  .undefined:
765
  .undefined:
766
        DEBUGF  2,"Your card was undefined in this driver.\n"
766
        DEBUGF  2,"Your card was undefined in this driver.\n"
767
        or      eax, -1
767
        or      eax, -1
768
        ret
768
        ret
769
 
769
 
770
; Find a suitable phy
770
; Find a suitable phy
771
; Start with address 1 to 31, then do 0, then fail
771
; Start with address 1 to 31, then do 0, then fail
772
 
772
 
773
  .find_phy:
773
  .find_phy:
774
        xor     edx, edx
774
        xor     edx, edx
775
  .phy_loop:
775
  .phy_loop:
776
        inc     edx
776
        inc     edx
777
        and     edx, 0x1f       ; phyaddr = i & 0x1f
777
        and     edx, 0x1f       ; phyaddr = i & 0x1f
778
        mov     eax, MII_PHYSID1
778
        mov     eax, MII_PHYSID1
779
        mov     ecx, MII_READ
779
        mov     ecx, MII_READ
780
        call    mii_rw          ; EDX - addr, EAX - miireg, ECX - value
780
        call    mii_rw          ; EDX - addr, EAX - miireg, ECX - value
781
 
781
 
782
        cmp     eax, 0x0000ffff
782
        cmp     eax, 0x0000ffff
783
        je      .try_next
783
        je      .try_next
784
        test    eax, 0x80000000
784
        test    eax, 0x80000000
785
        jnz     .try_next
785
        jnz     .try_next
786
        mov     esi, eax
786
        mov     esi, eax
787
 
787
 
788
        mov     eax, MII_PHYSID2
788
        mov     eax, MII_PHYSID2
789
        mov     ecx, MII_READ
789
        mov     ecx, MII_READ
790
        call    mii_rw
790
        call    mii_rw
791
 
791
 
792
        cmp     eax, 0x0000ffff
792
        cmp     eax, 0x0000ffff
793
        je      .try_next
793
        je      .try_next
794
        test    eax, 0x80000000
794
        test    eax, 0x80000000
795
        jnz     .try_next
795
        jnz     .try_next
796
        jmp     .got_it
796
        jmp     .got_it
797
 
797
 
798
  .try_next:
798
  .try_next:
799
        test    edx, edx
799
        test    edx, edx
800
        jnz     .phy_loop
800
        jnz     .phy_loop
801
 
801
 
802
        ; PHY in isolate mode? No phy attached and user wants to test loopback?
802
        ; PHY in isolate mode? No phy attached and user wants to test loopback?
803
        ; Very odd, but can be correct.
803
        ; Very odd, but can be correct.
804
        
804
        
805
        DEBUGF  2,"Could not find a valid PHY.\n"
805
        DEBUGF  2,"Could not find a valid PHY.\n"
806
        jmp     .no_phy
806
        jmp     .no_phy
807
 
807
 
808
  .got_it:
808
  .got_it:
809
        and     esi, PHYID1_OUI_MASK
809
        and     esi, PHYID1_OUI_MASK
810
        shl     esi, PHYID1_OUI_SHFT
810
        shl     esi, PHYID1_OUI_SHFT
811
        and     eax, PHYID2_OUI_MASK
811
        and     eax, PHYID2_OUI_MASK
812
        shr     eax, PHYID2_OUI_SHFT
812
        shr     eax, PHYID2_OUI_SHFT
813
        or      eax, esi
813
        or      eax, esi
814
 
814
 
815
        mov     [ebx + device.phyaddr], edx
815
        mov     [ebx + device.phyaddr], edx
816
        mov     [ebx + device.phy_oui], eax
816
        mov     [ebx + device.phy_oui], eax
817
 
817
 
818
        DEBUGF 1,"Found PHY with OUI:0x%x at address:0x%x\n", eax, edx
818
        DEBUGF 1,"Found PHY with OUI:0x%x at address:0x%x\n", eax, edx
819
 
819
 
820
        call    phy_init
820
        call    phy_init
821
 
821
 
822
  .no_phy:
822
  .no_phy:
823
 
823
 
824
        cmp     [ebx + device.needs_mac_reset], 0
824
        cmp     [ebx + device.needs_mac_reset], 0
825
        je      @f
825
        je      @f
826
        call    mac_reset
826
        call    mac_reset
827
  @@:
827
  @@:
828
        
828
        
829
;***************************************************************************
829
;***************************************************************************
830
;   Function
830
;   Function
831
;      reset
831
;      reset
832
;   Description
832
;   Description
833
;      Place the chip (ie, the ethernet card) into a virgin state
833
;      Place the chip (ie, the ethernet card) into a virgin state
834
;      No inputs
834
;      No inputs
835
;      All registers destroyed
835
;      All registers destroyed
836
;
836
;
837
;***************************************************************************
837
;***************************************************************************
838
reset:
838
reset:
839
 
839
 
840
        DEBUGF  1,"Resetting\n"
840
        DEBUGF  1,"Resetting\n"
841
 
841
 
842
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
842
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
843
        movzx   eax, al
843
        movzx   eax, al
844
        invoke  AttachIntHandler, eax, int_handler, ebx
844
        invoke  AttachIntHandler, eax, int_handler, ebx
845
        test    eax, eax
845
        test    eax, eax
846
        jnz     @f
846
        jnz     @f
847
        DEBUGF  2,"Could not attach int handler!\n"
847
        DEBUGF  2,"Could not attach int handler!\n"
848
        or      eax, -1
848
        or      eax, -1
849
        ret
849
        ret
850
       @@:
850
       @@:
851
 
851
 
852
; erase previous misconfiguration
852
; erase previous misconfiguration
853
 
853
 
854
        mov     edi, [ebx + device.mmio_addr]
854
        mov     edi, [ebx + device.mmio_addr]
855
        mov     [MulticastAddrA], MCASTADDRA_FORCE
855
        mov     [MulticastAddrA], MCASTADDRA_FORCE
856
        mov     [MulticastAddrB], 0
856
        mov     [MulticastAddrB], 0
857
        mov     [MulticastMaskA], 0
857
        mov     [MulticastMaskA], 0
858
        mov     [MulticastMaskB], 0
858
        mov     [MulticastMaskB], 0
859
        mov     [PacketFilterFlags], 0
859
        mov     [PacketFilterFlags], 0
860
        mov     [TransmitterControl], 0
860
        mov     [TransmitterControl], 0
861
        mov     [ReceiverControl], 0
861
        mov     [ReceiverControl], 0
862
        mov     [AdapterControl], 0
862
        mov     [AdapterControl], 0
863
 
863
 
864
; initialize descriptor rings
864
; initialize descriptor rings
865
 
865
 
866
        call    init_ring
866
        call    init_ring
867
 
867
 
868
        mov     [LinkSpeed], 0
868
        mov     [LinkSpeed], 0
869
        mov     [UnknownTransmitterReg], 0
869
        mov     [UnknownTransmitterReg], 0
870
 
870
 
871
        call    txrx_reset
871
        call    txrx_reset
872
 
872
 
873
        mov     [UnknownSetupReg6], 0
873
        mov     [UnknownSetupReg6], 0
874
        mov     [ebx + device.in_shutdown], 0
874
        mov     [ebx + device.in_shutdown], 0
875
 
875
 
876
; give hw rings
876
; give hw rings
877
 
877
 
878
        lea     eax, [ebx + device.rx_ring]
878
        lea     eax, [ebx + device.rx_ring]
879
        invoke  GetPhysAddr
879
        invoke  GetPhysAddr
880
        mov     [RxRingPhysAddr], eax
880
        mov     [RxRingPhysAddr], eax
881
 
881
 
882
        lea     eax, [ebx + device.tx_ring]
882
        lea     eax, [ebx + device.tx_ring]
883
        invoke  GetPhysAddr
883
        invoke  GetPhysAddr
884
        mov     [TxRingPhysAddr], eax
884
        mov     [TxRingPhysAddr], eax
885
 
885
 
886
        mov     [RingSizes], (((RX_RING - 1) shl RINGSZ_RXSHIFT) + ((TX_RING - 1) shl RINGSZ_TXSHIFT))
886
        mov     [RingSizes], (((RX_RING - 1) shl RINGSZ_RXSHIFT) + ((TX_RING - 1) shl RINGSZ_TXSHIFT))
887
 
887
 
888
;
888
;
889
 
889
 
890
        mov     [ebx + device.linkspeed], (LINKSPEED_FORCE or LINKSPEED_10)
890
        mov     [ebx + device.linkspeed], (LINKSPEED_FORCE or LINKSPEED_10)
891
        mov     [ebx + device.duplex], 0
891
        mov     [ebx + device.duplex], 0
892
        mov     [LinkSpeed], (LINKSPEED_FORCE or LINKSPEED_10)
892
        mov     [LinkSpeed], (LINKSPEED_FORCE or LINKSPEED_10)
893
        mov     [UnknownSetupReg3], UNKSETUP3_VAL1
893
        mov     [UnknownSetupReg3], UNKSETUP3_VAL1
894
 
894
 
895
        mov     eax, [ebx + device.desc_ver]
895
        mov     eax, [ebx + device.desc_ver]
896
        mov     [TxRxControl], eax
896
        mov     [TxRxControl], eax
897
        call    pci_push
897
        call    pci_push
898
        or      eax, TXRXCTL_BIT1
898
        or      eax, TXRXCTL_BIT1
899
        mov     [TxRxControl], eax
899
        mov     [TxRxControl], eax
900
 
900
 
901
        stdcall reg_delay, UnknownSetupReg5-edi, UNKSETUP5_BIT31, UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, 0
901
        stdcall reg_delay, UnknownSetupReg5-edi, UNKSETUP5_BIT31, UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, 0
902
 
902
 
903
        mov     [UnknownSetupReg4], 0
903
        mov     [UnknownSetupReg4], 0
904
        mov     [MIIStatus], MIISTAT_MASK2
904
        mov     [MIIStatus], MIISTAT_MASK2
905
 
905
 
906
;
906
;
907
        
907
        
908
        mov     [Misc1], (MISC1_FORCE or MISC1_HD)
908
        mov     [Misc1], (MISC1_FORCE or MISC1_HD)
909
 
909
 
910
        mov     eax, [TransmitterStatus]
910
        mov     eax, [TransmitterStatus]
911
        mov     [TransmitterStatus], eax
911
        mov     [TransmitterStatus], eax
912
 
912
 
913
        mov     [PacketFilterFlags], PFF_ALWAYS
913
        mov     [PacketFilterFlags], PFF_ALWAYS
914
 
914
 
915
        mov     [OffloadConfig], OFFLOAD_NORMAL
915
        mov     [OffloadConfig], OFFLOAD_NORMAL
916
 
916
 
917
        mov     eax, [ReceiverStatus]
917
        mov     eax, [ReceiverStatus]
918
        mov     [ReceiverStatus], eax
918
        mov     [ReceiverStatus], eax
919
 
919
 
920
; set random seed
920
; set random seed
921
        push    ebx
921
        push    ebx
922
        invoke  GetTimerTicks   ; bad idea, driver is started at system startup in 90% of cases..
922
        invoke  GetTimerTicks   ; bad idea, driver is started at system startup in 90% of cases..
923
        pop     ebx
923
        pop     ebx
924
 
924
 
925
        mov     edi, [ebx + device.mmio_addr]
925
        mov     edi, [ebx + device.mmio_addr]
926
 
926
 
927
        and     eax, RNDSEED_MASK
927
        and     eax, RNDSEED_MASK
928
        or      eax, RNDSEED_FORCE
928
        or      eax, RNDSEED_FORCE
929
        mov     [RandomSeed], eax
929
        mov     [RandomSeed], eax
930
 
930
 
931
        mov     [UnknownSetupReg1], UNKSETUP1_VAL
931
        mov     [UnknownSetupReg1], UNKSETUP1_VAL
932
        mov     [UnknownSetupReg2], UNKSETUP2_VAL
932
        mov     [UnknownSetupReg2], UNKSETUP2_VAL
933
        mov     [PollingInterval], POLL_DEFAULT
933
        mov     [PollingInterval], POLL_DEFAULT
934
        mov     [UnknownSetupReg6], UNKSETUP6_VAL
934
        mov     [UnknownSetupReg6], UNKSETUP6_VAL
935
 
935
 
936
        mov     eax, [ebx + device.phyaddr]
936
        mov     eax, [ebx + device.phyaddr]
937
        shl     eax, ADAPTCTL_PHYSHIFT
937
        shl     eax, ADAPTCTL_PHYSHIFT
938
        or      eax, (ADAPTCTL_PHYVALID or ADAPTCTL_RUNNING)
938
        or      eax, (ADAPTCTL_PHYVALID or ADAPTCTL_RUNNING)
939
        mov     [AdapterControl], eax
939
        mov     [AdapterControl], eax
940
 
940
 
941
        mov     [MIISpeed], (MIISPEED_BIT8 or MIIDELAY)
941
        mov     [MIISpeed], (MIISPEED_BIT8 or MIIDELAY)
942
        mov     [UnknownSetupReg4], UNKSETUP4_VAL
942
        mov     [UnknownSetupReg4], UNKSETUP4_VAL
943
        mov     [WakeUpFlags], WAKEUPFLAGS_VAL
943
        mov     [WakeUpFlags], WAKEUPFLAGS_VAL
944
        
944
        
945
        or      [PowerState], POWERSTATE_POWEREDUP
945
        or      [PowerState], POWERSTATE_POWEREDUP
946
        call    pci_push
946
        call    pci_push
947
 
947
 
948
        mov     esi, 10
948
        mov     esi, 10
949
        invoke  Sleep
949
        invoke  Sleep
950
 
950
 
951
        or      [PowerState], POWERSTATE_VALID
951
        or      [PowerState], POWERSTATE_VALID
952
        mov     [IrqMask], 0
952
        mov     [IrqMask], 0
953
 
953
 
954
;;;     ; ??? Mask RX interrupts
954
;;;     ; ??? Mask RX interrupts
955
        mov      [IrqMask], IRQ_RX_ALL + IRQ_TX_ALL
955
        mov      [IrqMask], IRQ_RX_ALL + IRQ_TX_ALL
956
;;;     ; ??? Mask TX interrupts
956
;;;     ; ??? Mask TX interrupts
957
;;;     mov      [IrqMask], IRQ_TX_ALL
957
;;;     mov      [IrqMask], IRQ_TX_ALL
958
;;;     ; ??? Mask OTHER interrupts
958
;;;     ; ??? Mask OTHER interrupts
959
;;;     mov      [IrqMask], IRQ_OTHER_ALL
959
;;;     mov      [IrqMask], IRQ_OTHER_ALL
960
        call    pci_push
960
        call    pci_push
961
 
961
 
962
        mov     [MIIStatus], MIISTAT_MASK2
962
        mov     [MIIStatus], MIISTAT_MASK2
963
        mov     [IrqStatus], IRQSTAT_MASK
963
        mov     [IrqStatus], IRQSTAT_MASK
964
        call    pci_push
964
        call    pci_push
965
 
965
 
966
        mov     [MulticastAddrA], MCASTADDRA_FORCE
966
        mov     [MulticastAddrA], MCASTADDRA_FORCE
967
        mov     [MulticastAddrB], 0
967
        mov     [MulticastAddrB], 0
968
        mov     [MulticastMaskA], 0
968
        mov     [MulticastMaskA], 0
969
        mov     [MulticastMaskB], 0
969
        mov     [MulticastMaskB], 0
970
 
970
 
971
        mov     [PacketFilterFlags], (PFF_ALWAYS or PFF_MYADDR)
971
        mov     [PacketFilterFlags], (PFF_ALWAYS or PFF_MYADDR)
972
 
972
 
973
        call    set_multicast
973
        call    set_multicast
974
        
974
        
975
        ; One manual link speed update: Interrupts are enabled, future link
975
        ; One manual link speed update: Interrupts are enabled, future link
976
        ; speed changes cause interrupts and are handled by nv_link_irq().
976
        ; speed changes cause interrupts and are handled by nv_link_irq().
977
 
977
 
978
        mov     eax, [MIIStatus]
978
        mov     eax, [MIIStatus]
979
        mov     [MIIStatus], MIISTAT_MASK
979
        mov     [MIIStatus], MIISTAT_MASK
980
        DEBUGF  1,"startup: got 0x%x\n", eax
980
        DEBUGF  1,"startup: got 0x%x\n", eax
981
 
981
 
982
        call    update_linkspeed
982
        call    update_linkspeed
983
 
983
 
984
        mov     [TransmitterControl], XMITCTL_START       ; start TX
984
        mov     [TransmitterControl], XMITCTL_START       ; start TX
985
        call    pci_push
985
        call    pci_push
986
 
986
 
987
        mov     [ebx + device.nocable], 0
987
        mov     [ebx + device.nocable], 0
988
        test    eax, eax
988
        test    eax, eax
989
        jnz     .return
989
        jnz     .return
990
        DEBUGF  1,"no link during initialization.\n"
990
        DEBUGF  1,"no link during initialization.\n"
991
        mov     [ebx + device.nocable], 1
991
        mov     [ebx + device.nocable], 1
992
 
992
 
993
  .return:
993
  .return:
994
        xor     eax, eax        ; Indicate that we have successfully reset the card
994
        xor     eax, eax        ; Indicate that we have successfully reset the card
995
        mov     [ebx + device.mtu], 1514 ;;; FIXME
995
        mov     [ebx + device.mtu], 1514 ;;; FIXME
996
        ret
996
        ret
997
 
997
 
998
 
998
 
999
fail:
999
fail:
1000
        or      eax, -1
1000
        or      eax, -1
1001
        ret
1001
        ret
1002
 
1002
 
1003
;--------------------------------------------------------
1003
;--------------------------------------------------------
1004
;
1004
;
1005
; MII_RW
1005
; MII_RW
1006
;
1006
;
1007
; read/write a register on the PHY.
1007
; read/write a register on the PHY.
1008
; Caller must guarantee serialization
1008
; Caller must guarantee serialization
1009
; Input:  EAX - miireg, EDX - phy addr, ECX - value to write (or -1 to read)
1009
; Input:  EAX - miireg, EDX - phy addr, ECX - value to write (or -1 to read)
1010
; Output: EAX - retval (lower 16 bits)
1010
; Output: EAX - retval (lower 16 bits)
1011
;
1011
;
1012
;--------------------------------------------------------
1012
;--------------------------------------------------------
1013
 
1013
 
1014
mii_rw:
1014
mii_rw:
1015
 
1015
 
1016
        DEBUGF  1,"mii_rw: 0x%x to reg %d at PHY %d\n", ecx, eax, edx
1016
        DEBUGF  1,"mii_rw: 0x%x to reg %d at PHY %d\n", ecx, eax, edx
1017
 
1017
 
1018
        push    edx
1018
        push    edx
1019
 
1019
 
1020
        mov     edi, [ebx + device.mmio_addr]
1020
        mov     edi, [ebx + device.mmio_addr]
1021
 
1021
 
1022
; Check if MII interface is busy
1022
; Check if MII interface is busy
1023
        mov     [MIIStatus], MIISTAT_MASK
1023
        mov     [MIIStatus], MIISTAT_MASK
1024
       @@:
1024
       @@:
1025
        test    [MIIControl], MIICTL_INUSE
1025
        test    [MIIControl], MIICTL_INUSE
1026
        jz      @f
1026
        jz      @f
1027
        mov     [MIIControl], MIICTL_INUSE
1027
        mov     [MIIControl], MIICTL_INUSE
1028
 
1028
 
1029
        DEBUGF  1,"mii_rw: in use!\n"
1029
        DEBUGF  1,"mii_rw: in use!\n"
1030
        pusha
1030
        pusha
1031
        mov     esi, NV_MIIBUSY_DELAY
1031
        mov     esi, NV_MIIBUSY_DELAY
1032
        invoke  Sleep
1032
        invoke  Sleep
1033
        popa
1033
        popa
1034
        jmp     @r
1034
        jmp     @r
1035
       @@:
1035
       @@:
1036
 
1036
 
1037
; Set the address we want to access
1037
; Set the address we want to access
1038
        shl     edx, MIICTL_ADDRSHIFT
1038
        shl     edx, MIICTL_ADDRSHIFT
1039
        or      edx, eax
1039
        or      edx, eax
1040
 
1040
 
1041
        ; When writing, write the data first.
1041
        ; When writing, write the data first.
1042
        cmp     ecx, MII_READ
1042
        cmp     ecx, MII_READ
1043
        je      @f
1043
        je      @f
1044
        mov     [MIIData], ecx
1044
        mov     [MIIData], ecx
1045
        or      edx, MIICTL_WRITE
1045
        or      edx, MIICTL_WRITE
1046
       @@:
1046
       @@:
1047
 
1047
 
1048
        mov     [MIIControl], edx
1048
        mov     [MIIControl], edx
1049
 
1049
 
1050
; Wait for read/write to complete
1050
; Wait for read/write to complete
1051
        stdcall reg_delay, MIIControl-edi, MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, 0
1051
        stdcall reg_delay, MIIControl-edi, MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, 0
1052
 
1052
 
1053
        test    eax, eax
1053
        test    eax, eax
1054
        jz      @f
1054
        jz      @f
1055
        DEBUGF  1,"mii_rw timed out.\n"
1055
        DEBUGF  1,"mii_rw timed out.\n"
1056
        or      eax, -1
1056
        or      eax, -1
1057
        jmp     .return
1057
        jmp     .return
1058
 
1058
 
1059
       @@:
1059
       @@:
1060
        cmp     ecx, MII_READ
1060
        cmp     ecx, MII_READ
1061
        je      .read
1061
        je      .read
1062
; it was a write operation - fewer failures are detectable
1062
; it was a write operation - fewer failures are detectable
1063
        DEBUGF  1,"mii_rw write: ok\n"
1063
        DEBUGF  1,"mii_rw write: ok\n"
1064
        xor     eax, eax
1064
        xor     eax, eax
1065
        jmp     .return
1065
        jmp     .return
1066
 
1066
 
1067
  .read:
1067
  .read:
1068
        mov     eax, [MIIStatus]
1068
        mov     eax, [MIIStatus]
1069
        test    eax, MIISTAT_ERROR
1069
        test    eax, MIISTAT_ERROR
1070
        jz      @f
1070
        jz      @f
1071
        DEBUGF  1,"mii read: failed.\n"
1071
        DEBUGF  1,"mii read: failed.\n"
1072
        or      eax, -1
1072
        or      eax, -1
1073
        jmp     .return
1073
        jmp     .return
1074
 
1074
 
1075
       @@:
1075
       @@:
1076
        mov     eax, [MIIData]
1076
        mov     eax, [MIIData]
1077
        DEBUGF  1,"mii read: 0x%x.\n", eax
1077
        DEBUGF  1,"mii read: 0x%x.\n", eax
1078
 
1078
 
1079
  .return:
1079
  .return:
1080
        pop     edx
1080
        pop     edx
1081
        ret
1081
        ret
1082
 
1082
 
1083
 
1083
 
1084
 
1084
 
1085
 
1085
 
1086
 
1086
 
1087
; Input:  offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword
1087
; Input:  offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword
1088
; Output: EAX - 0|1
1088
; Output: EAX - 0|1
1089
 
1089
 
1090
proc    reg_delay, offset:dword, mask:dword, target:dword, delay:dword, delaymax:dword, msg:dword
1090
proc    reg_delay, offset:dword, mask:dword, target:dword, delay:dword, delaymax:dword, msg:dword
1091
 
1091
 
1092
;        DEBUGF  1,"reg_delay\n"
1092
;        DEBUGF  1,"reg_delay\n"
1093
 
1093
 
1094
        push    esi
1094
        push    esi
1095
        call    pci_push
1095
        call    pci_push
1096
 
1096
 
1097
  .loop:
1097
  .loop:
1098
        mov     esi, [delay]
1098
        mov     esi, [delay]
1099
        invoke  Sleep
1099
        invoke  Sleep
1100
        mov     eax, [delaymax]
1100
        mov     eax, [delaymax]
1101
        sub     eax, [delay]
1101
        sub     eax, [delay]
1102
        mov     [delaymax], eax
1102
        mov     [delaymax], eax
1103
 
1103
 
1104
        cmp     eax, 0
1104
        cmp     eax, 0
1105
        jl      .fail
1105
        jl      .fail
1106
 
1106
 
1107
        mov     eax, [offset]
1107
        mov     eax, [offset]
1108
        mov     eax, [edi + eax]
1108
        mov     eax, [edi + eax]
1109
        and     eax, [mask]
1109
        and     eax, [mask]
1110
        cmp     eax, [target]
1110
        cmp     eax, [target]
1111
        jne     .loop
1111
        jne     .loop
1112
 
1112
 
1113
        pop     esi
1113
        pop     esi
1114
        xor     eax, eax
1114
        xor     eax, eax
1115
        ret
1115
        ret
1116
 
1116
 
1117
  .fail:
1117
  .fail:
1118
        pop     esi
1118
        pop     esi
1119
        xor     eax, eax
1119
        xor     eax, eax
1120
        inc     eax
1120
        inc     eax
1121
        ret
1121
        ret
1122
 
1122
 
1123
endp
1123
endp
1124
 
1124
 
1125
 
1125
 
1126
 
1126
 
1127
 
1127
 
1128
 
1128
 
1129
; Input:  none
1129
; Input:  none
1130
; Output: EAX - result (0 = OK, other = error)
1130
; Output: EAX - result (0 = OK, other = error)
1131
phy_init:
1131
phy_init:
1132
 
1132
 
1133
        push    ebx ecx
1133
        push    ebx ecx
1134
        
1134
        
1135
        ; set advertise register
1135
        ; set advertise register
1136
        mov     edx, [ebx + device.phyaddr]
1136
        mov     edx, [ebx + device.phyaddr]
1137
        mov     eax, MII_ADVERTISE
1137
        mov     eax, MII_ADVERTISE
1138
        mov     ecx, MII_READ
1138
        mov     ecx, MII_READ
1139
        call    mii_rw
1139
        call    mii_rw
1140
 
1140
 
1141
        or      eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400)
1141
        or      eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400)
1142
 
1142
 
1143
        mov     ecx, eax
1143
        mov     ecx, eax
1144
        mov     eax, MII_ADVERTISE
1144
        mov     eax, MII_ADVERTISE
1145
        call    mii_rw
1145
        call    mii_rw
1146
 
1146
 
1147
        test    eax, eax
1147
        test    eax, eax
1148
        jz      @f
1148
        jz      @f
1149
 
1149
 
1150
        DEBUGF  2,"phy write to advertise failed.\n"
1150
        DEBUGF  2,"phy write to advertise failed.\n"
1151
 
1151
 
1152
        mov     eax, PHY_ERROR
1152
        mov     eax, PHY_ERROR
1153
        jmp     .return
1153
        jmp     .return
1154
       @@:
1154
       @@:
1155
 
1155
 
1156
        ; get phy interface type
1156
        ; get phy interface type
1157
        mov     edi, [ebx + device.mmio_addr]
1157
        mov     edi, [ebx + device.mmio_addr]
1158
        mov     eax, [PhyInterface]
1158
        mov     eax, [PhyInterface]
1159
        DEBUGF  1,"phy interface type = 0x%x\n", eax:8
1159
        DEBUGF  1,"phy interface type = 0x%x\n", eax:8
1160
 
1160
 
1161
        ; see if gigabit phy
1161
        ; see if gigabit phy
1162
        mov     eax, MII_BMSR
1162
        mov     eax, MII_BMSR
1163
        mov     ecx, MII_READ
1163
        mov     ecx, MII_READ
1164
        call    mii_rw
1164
        call    mii_rw
1165
        
1165
        
1166
        test    eax, PHY_GIGABIT
1166
        test    eax, PHY_GIGABIT
1167
        jnz     .gigabit
1167
        jnz     .gigabit
1168
        mov     [ebx + device.gigabit], 0
1168
        mov     [ebx + device.gigabit], 0
1169
        jmp     .next_if
1169
        jmp     .next_if
1170
 
1170
 
1171
  .gigabit:
1171
  .gigabit:
1172
        mov     [ebx + device.gigabit], PHY_GIGABIT
1172
        mov     [ebx + device.gigabit], PHY_GIGABIT
1173
 
1173
 
1174
        mov     eax, MII_1000BT_CR
1174
        mov     eax, MII_1000BT_CR
1175
        mov     ecx, MII_READ
1175
        mov     ecx, MII_READ
1176
        call    mii_rw
1176
        call    mii_rw
1177
        
1177
        
1178
        and     eax, (not ADVERTISE_1000HALF)
1178
        and     eax, (not ADVERTISE_1000HALF)
1179
 
1179
 
1180
        test    [PhyInterface], PHY_RGMII
1180
        test    [PhyInterface], PHY_RGMII
1181
        jz      @f
1181
        jz      @f
1182
        or      eax, ADVERTISE_1000FULL
1182
        or      eax, ADVERTISE_1000FULL
1183
        jmp     .next
1183
        jmp     .next
1184
       @@:
1184
       @@:
1185
 
1185
 
1186
        and     eax, (not ADVERTISE_1000FULL)
1186
        and     eax, (not ADVERTISE_1000FULL)
1187
 
1187
 
1188
  .next:
1188
  .next:
1189
        mov     ecx, eax
1189
        mov     ecx, eax
1190
        mov     eax, MII_1000BT_CR
1190
        mov     eax, MII_1000BT_CR
1191
        call    mii_rw
1191
        call    mii_rw
1192
 
1192
 
1193
        test    eax, eax
1193
        test    eax, eax
1194
        jz      .next_if
1194
        jz      .next_if
1195
 
1195
 
1196
        DEBUGF  2,"phy init failed.\n"
1196
        DEBUGF  2,"phy init failed.\n"
1197
 
1197
 
1198
        mov     eax, PHY_ERROR
1198
        mov     eax, PHY_ERROR
1199
        jmp     .return
1199
        jmp     .return
1200
 
1200
 
1201
  .next_if:
1201
  .next_if:
1202
 
1202
 
1203
        call    phy_reset
1203
        call    phy_reset
1204
        test    eax, eax
1204
        test    eax, eax
1205
        jz      @f
1205
        jz      @f
1206
 
1206
 
1207
        DEBUGF  2,"phy reset failed.\n"
1207
        DEBUGF  2,"phy reset failed.\n"
1208
 
1208
 
1209
        mov     eax, PHY_ERROR
1209
        mov     eax, PHY_ERROR
1210
        jmp     .return
1210
        jmp     .return
1211
       @@:
1211
       @@:
1212
 
1212
 
1213
        ; phy vendor specific configuration
1213
        ; phy vendor specific configuration
1214
        cmp     [ebx + device.phy_oui], PHY_OUI_CICADA
1214
        cmp     [ebx + device.phy_oui], PHY_OUI_CICADA
1215
        jne     .next_if2
1215
        jne     .next_if2
1216
        test    [PhyInterface], PHY_RGMII
1216
        test    [PhyInterface], PHY_RGMII
1217
        jz      .next_if2
1217
        jz      .next_if2
1218
 
1218
 
1219
        mov     eax, MII_RESV1
1219
        mov     eax, MII_RESV1
1220
        mov     ecx, MII_READ
1220
        mov     ecx, MII_READ
1221
        call    mii_rw
1221
        call    mii_rw
1222
 
1222
 
1223
        and     eax, (not (PHY_INIT1 or PHY_INIT2))
1223
        and     eax, (not (PHY_INIT1 or PHY_INIT2))
1224
        or      eax, (PHY_INIT3 or PHY_INIT4)
1224
        or      eax, (PHY_INIT3 or PHY_INIT4)
1225
        mov     ecx, eax
1225
        mov     ecx, eax
1226
        mov     eax, MII_RESV1
1226
        mov     eax, MII_RESV1
1227
        call    mii_rw
1227
        call    mii_rw
1228
 
1228
 
1229
        test    eax, eax
1229
        test    eax, eax
1230
        jz      @f
1230
        jz      @f
1231
 
1231
 
1232
        DEBUGF  2,"phy init failed.\n"
1232
        DEBUGF  2,"phy init failed.\n"
1233
 
1233
 
1234
        mov     eax, PHY_ERROR
1234
        mov     eax, PHY_ERROR
1235
        jmp     .return
1235
        jmp     .return
1236
       @@:
1236
       @@:
1237
 
1237
 
1238
        mov     eax, MII_NCONFIG
1238
        mov     eax, MII_NCONFIG
1239
        mov     ecx, MII_READ
1239
        mov     ecx, MII_READ
1240
        call    mii_rw
1240
        call    mii_rw
1241
 
1241
 
1242
        or      eax, PHY_INIT5
1242
        or      eax, PHY_INIT5
1243
        mov     ecx, eax
1243
        mov     ecx, eax
1244
        mov     eax, MII_NCONFIG
1244
        mov     eax, MII_NCONFIG
1245
        call    mii_rw
1245
        call    mii_rw
1246
        test    eax, eax
1246
        test    eax, eax
1247
        jz      .next_if2
1247
        jz      .next_if2
1248
 
1248
 
1249
        DEBUGF  2,"phy init failed.\n"
1249
        DEBUGF  2,"phy init failed.\n"
1250
 
1250
 
1251
        mov     eax, PHY_ERROR
1251
        mov     eax, PHY_ERROR
1252
        jmp     .return
1252
        jmp     .return
1253
 
1253
 
1254
 
1254
 
1255
 
1255
 
1256
  .next_if2:
1256
  .next_if2:
1257
 
1257
 
1258
        cmp     [ebx + device.phy_oui], PHY_OUI_CICADA
1258
        cmp     [ebx + device.phy_oui], PHY_OUI_CICADA
1259
        jne     .restart
1259
        jne     .restart
1260
        
1260
        
1261
        mov     eax, MII_SREVISION
1261
        mov     eax, MII_SREVISION
1262
        mov     ecx, MII_READ
1262
        mov     ecx, MII_READ
1263
        call    mii_rw
1263
        call    mii_rw
1264
        
1264
        
1265
        or      eax, PHY_INIT6
1265
        or      eax, PHY_INIT6
1266
        mov     ecx, eax
1266
        mov     ecx, eax
1267
        mov     eax, MII_SREVISION
1267
        mov     eax, MII_SREVISION
1268
        call    mii_rw
1268
        call    mii_rw
1269
        test    eax, eax
1269
        test    eax, eax
1270
        jz      .restart
1270
        jz      .restart
1271
 
1271
 
1272
        DEBUGF  2,"phy init failed.\n"
1272
        DEBUGF  2,"phy init failed.\n"
1273
 
1273
 
1274
        jmp     .return
1274
        jmp     .return
1275
 
1275
 
1276
  .restart:
1276
  .restart:
1277
        ; restart auto negotiation
1277
        ; restart auto negotiation
1278
 
1278
 
1279
        mov     eax, MII_BMCR
1279
        mov     eax, MII_BMCR
1280
        mov     ecx, MII_READ
1280
        mov     ecx, MII_READ
1281
        call    mii_rw
1281
        call    mii_rw
1282
 
1282
 
1283
        or      eax, (BMCR_ANRESTART or BMCR_ANENABLE)
1283
        or      eax, (BMCR_ANRESTART or BMCR_ANENABLE)
1284
        mov     ecx, eax
1284
        mov     ecx, eax
1285
        mov     eax, MII_BMCR
1285
        mov     eax, MII_BMCR
1286
        call    mii_rw
1286
        call    mii_rw
1287
        test    eax, eax
1287
        test    eax, eax
1288
        jz      .ok
1288
        jz      .ok
1289
 
1289
 
1290
        mov     eax, PHY_ERROR
1290
        mov     eax, PHY_ERROR
1291
        jmp     .return
1291
        jmp     .return
1292
 
1292
 
1293
  .ok:
1293
  .ok:
1294
        xor     eax, eax
1294
        xor     eax, eax
1295
  .return:
1295
  .return:
1296
        pop     ecx ebx
1296
        pop     ecx ebx
1297
 
1297
 
1298
        ret
1298
        ret
1299
 
1299
 
1300
 
1300
 
1301
; Input:  none
1301
; Input:  none
1302
; Output: EAX - result (0 = OK, other = error)
1302
; Output: EAX - result (0 = OK, other = error)
1303
phy_reset:
1303
phy_reset:
1304
 
1304
 
1305
        DEBUGF  1,"phy_reset\n"
1305
        DEBUGF  1,"phy_reset\n"
1306
 
1306
 
1307
        push    ebx ecx edx
1307
        push    ebx ecx edx
1308
 
1308
 
1309
        mov     edx, [ebx + device.phyaddr]
1309
        mov     edx, [ebx + device.phyaddr]
1310
        mov     eax, MII_BMCR
1310
        mov     eax, MII_BMCR
1311
        mov     ecx, MII_READ
1311
        mov     ecx, MII_READ
1312
        call    mii_rw
1312
        call    mii_rw
1313
 
1313
 
1314
        or      eax, BMCR_RESET
1314
        or      eax, BMCR_RESET
1315
        push    eax
1315
        push    eax
1316
        mov     ecx, eax
1316
        mov     ecx, eax
1317
        mov     eax, MII_BMCR
1317
        mov     eax, MII_BMCR
1318
        call    mii_rw
1318
        call    mii_rw
1319
 
1319
 
1320
        test    eax, eax
1320
        test    eax, eax
1321
        jz      @f
1321
        jz      @f
1322
 
1322
 
1323
        pop     eax
1323
        pop     eax
1324
        mov     eax, 0xffffffff
1324
        mov     eax, 0xffffffff
1325
        jmp     .return
1325
        jmp     .return
1326
       @@:
1326
       @@:
1327
 
1327
 
1328
        pop     eax
1328
        pop     eax
1329
 
1329
 
1330
        mov     esi, 500
1330
        mov     esi, 500
1331
        invoke  Sleep
1331
        invoke  Sleep
1332
 
1332
 
1333
        ; must wait till reset is deasserted
1333
        ; must wait till reset is deasserted
1334
        mov     esi, 100        ; FIXME: 100 tries seem excessive
1334
        mov     esi, 100        ; FIXME: 100 tries seem excessive
1335
  .while_loop:
1335
  .while_loop:
1336
        test    eax, BMCR_RESET
1336
        test    eax, BMCR_RESET
1337
        jz      .while_loop_exit
1337
        jz      .while_loop_exit
1338
 
1338
 
1339
        push    esi
1339
        push    esi
1340
        mov     esi, 10
1340
        mov     esi, 10
1341
        invoke  Sleep
1341
        invoke  Sleep
1342
        pop     esi
1342
        pop     esi
1343
 
1343
 
1344
        mov     eax, MII_BMCR
1344
        mov     eax, MII_BMCR
1345
        mov     ecx, MII_READ
1345
        mov     ecx, MII_READ
1346
        call    mii_rw
1346
        call    mii_rw
1347
 
1347
 
1348
        dec     esi
1348
        dec     esi
1349
        jnz     .while_loop
1349
        jnz     .while_loop
1350
 
1350
 
1351
        mov     eax, 0xffffffff
1351
        mov     eax, 0xffffffff
1352
        jmp     .return
1352
        jmp     .return
1353
 
1353
 
1354
  .while_loop_exit:
1354
  .while_loop_exit:
1355
        xor     eax, eax
1355
        xor     eax, eax
1356
  .return:
1356
  .return:
1357
        pop     edx ecx ebx
1357
        pop     edx ecx ebx
1358
 
1358
 
1359
        ret
1359
        ret
1360
 
1360
 
1361
 
1361
 
1362
align 4
1362
align 4
1363
pci_push:
1363
pci_push:
1364
 
1364
 
1365
        push    eax
1365
        push    eax
1366
        mov     eax, [edi]
1366
        mov     eax, [edi]
1367
        pop     eax
1367
        pop     eax
1368
 
1368
 
1369
        ret
1369
        ret
1370
 
1370
 
1371
 
1371
 
1372
 
1372
 
1373
 
1373
 
1374
align 4
1374
align 4
1375
mac_reset:
1375
mac_reset:
1376
 
1376
 
1377
        push    esi edi
1377
        push    esi edi
1378
 
1378
 
1379
        DEBUGF  1,"mac_reset.\n"
1379
        DEBUGF  1,"mac_reset.\n"
1380
 
1380
 
1381
        mov     edi, [ebx + device.mmio_addr]
1381
        mov     edi, [ebx + device.mmio_addr]
1382
        mov     eax, [ebx + device.desc_ver]
1382
        mov     eax, [ebx + device.desc_ver]
1383
        or      eax, (TXRXCTL_BIT2 or TXRXCTL_RESET)
1383
        or      eax, (TXRXCTL_BIT2 or TXRXCTL_RESET)
1384
        mov     [TxRxControl], eax
1384
        mov     [TxRxControl], eax
1385
        call    pci_push
1385
        call    pci_push
1386
 
1386
 
1387
        mov     [MacReset], MAC_RESET_ASSERT
1387
        mov     [MacReset], MAC_RESET_ASSERT
1388
        call    pci_push
1388
        call    pci_push
1389
 
1389
 
1390
        mov     esi, NV_MAC_RESET_DELAY
1390
        mov     esi, NV_MAC_RESET_DELAY
1391
        invoke  Sleep
1391
        invoke  Sleep
1392
 
1392
 
1393
        mov     [MacReset], 0
1393
        mov     [MacReset], 0
1394
        call    pci_push
1394
        call    pci_push
1395
 
1395
 
1396
        mov     esi, NV_MAC_RESET_DELAY
1396
        mov     esi, NV_MAC_RESET_DELAY
1397
        invoke  Sleep
1397
        invoke  Sleep
1398
 
1398
 
1399
        mov     eax, [ebx + device.desc_ver]
1399
        mov     eax, [ebx + device.desc_ver]
1400
        or      eax, TXRXCTL_BIT2
1400
        or      eax, TXRXCTL_BIT2
1401
        mov     [TxRxControl], eax
1401
        mov     [TxRxControl], eax
1402
        call    pci_push
1402
        call    pci_push
1403
 
1403
 
1404
        pop     edi esi
1404
        pop     edi esi
1405
 
1405
 
1406
        ret
1406
        ret
1407
 
1407
 
1408
 
1408
 
1409
 
1409
 
1410
align 4
1410
align 4
1411
init_ring:
1411
init_ring:
1412
 
1412
 
1413
        DEBUGF  1,"init rings\n"
1413
        DEBUGF  1,"init rings\n"
1414
        push    eax esi ecx
1414
        push    eax esi ecx
1415
 
1415
 
1416
        mov     [ebx + device.cur_tx], 0
1416
        mov     [ebx + device.cur_tx], 0
1417
        mov     [ebx + device.last_tx], 0
1417
        mov     [ebx + device.last_tx], 0
1418
 
1418
 
1419
        mov     ecx, TX_RING
1419
        mov     ecx, TX_RING
1420
        lea     esi, [ebx + device.tx_ring]
1420
        lea     esi, [ebx + device.tx_ring]
1421
  .tx_loop:
1421
  .tx_loop:
1422
        mov     [esi + TxDesc.FlagLen], 0
1422
        mov     [esi + TxDesc.FlagLen], 0
1423
        mov     [esi + TxDesc.PacketBuffer], 0
1423
        mov     [esi + TxDesc.PacketBuffer], 0
1424
        add     esi, sizeof.TxDesc
1424
        add     esi, sizeof.TxDesc
1425
        dec     ecx
1425
        dec     ecx
1426
        jnz     .tx_loop
1426
        jnz     .tx_loop
1427
 
1427
 
1428
 
1428
 
1429
        mov     [ebx + device.cur_rx], 0
1429
        mov     [ebx + device.cur_rx], 0
1430
 
1430
 
1431
        mov     ecx, RX_RING
1431
        mov     ecx, RX_RING
1432
        lea     esi, [ebx + device.rx_ring]
1432
        lea     esi, [ebx + device.rx_ring]
1433
  .rx_loop:
1433
  .rx_loop:
1434
        push    ecx esi
1434
        push    ecx esi
1435
        invoke  KernelAlloc, 4096 shl RBLEN             ; push/pop esi not needed, but just in case...
1435
        invoke  KernelAlloc, 4096 shl RBLEN             ; push/pop esi not needed, but just in case...
1436
        pop     esi
1436
        pop     esi
1437
        mov     [esi + RX_RING*sizeof.RxDesc], eax
1437
        mov     [esi + RX_RING*sizeof.RxDesc], eax
1438
        invoke  GetPhysAddr
1438
        invoke  GetPhysAddr
1439
        mov     [esi + RxDesc.PacketBuffer], eax
1439
        mov     [esi + RxDesc.PacketBuffer], eax
1440
        mov     [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL)
1440
        mov     [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL)
1441
        add     esi, sizeof.RxDesc
1441
        add     esi, sizeof.RxDesc
1442
        pop     ecx
1442
        pop     ecx
1443
        dec     ecx
1443
        dec     ecx
1444
        jnz     .rx_loop
1444
        jnz     .rx_loop
1445
        
1445
        
1446
        pop     ecx esi eax
1446
        pop     ecx esi eax
1447
 
1447
 
1448
        ret
1448
        ret
1449
 
1449
 
1450
 
1450
 
1451
 
1451
 
1452
 
1452
 
1453
 
1453
 
1454
; Input:  none
1454
; Input:  none
1455
; Output: none
1455
; Output: none
1456
align 4
1456
align 4
1457
txrx_reset:
1457
txrx_reset:
1458
 
1458
 
1459
        push    eax esi
1459
        push    eax esi
1460
 
1460
 
1461
        DEBUGF  1,"txrx_reset\n"
1461
        DEBUGF  1,"txrx_reset\n"
1462
 
1462
 
1463
        mov     edi, [ebx + device.mmio_addr]
1463
        mov     edi, [ebx + device.mmio_addr]
1464
        mov     eax, [ebx + device.desc_ver]
1464
        mov     eax, [ebx + device.desc_ver]
1465
        or      eax, (TXRXCTL_BIT2 or TXRXCTL_RESET)
1465
        or      eax, (TXRXCTL_BIT2 or TXRXCTL_RESET)
1466
        mov     [TxRxControl], eax
1466
        mov     [TxRxControl], eax
1467
        call    pci_push
1467
        call    pci_push
1468
 
1468
 
1469
        mov     esi, NV_TXRX_RESET_DELAY
1469
        mov     esi, NV_TXRX_RESET_DELAY
1470
        invoke  Sleep
1470
        invoke  Sleep
1471
 
1471
 
1472
        mov     eax, [ebx + device.desc_ver]
1472
        mov     eax, [ebx + device.desc_ver]
1473
        or      eax, TXRXCTL_BIT2
1473
        or      eax, TXRXCTL_BIT2
1474
        mov     [TxRxControl], eax
1474
        mov     [TxRxControl], eax
1475
        call    pci_push
1475
        call    pci_push
1476
 
1476
 
1477
        pop     esi eax
1477
        pop     esi eax
1478
 
1478
 
1479
        ret
1479
        ret
1480
 
1480
 
1481
 
1481
 
1482
 
1482
 
1483
 
1483
 
1484
 
1484
 
1485
; Input:  none
1485
; Input:  none
1486
; Output: none
1486
; Output: none
1487
set_multicast:
1487
set_multicast:
1488
 
1488
 
1489
        ; u32 addr[2];
1489
        ; u32 addr[2];
1490
        ; u32 mask[2];
1490
        ; u32 mask[2];
1491
        ; u32 pff;
1491
        ; u32 pff;
1492
        ; u32 alwaysOff[2];
1492
        ; u32 alwaysOff[2];
1493
        ; u32 alwaysOn[2];
1493
        ; u32 alwaysOn[2];
1494
        ;
1494
        ;
1495
        ; memset(addr, 0, sizeof(addr));
1495
        ; memset(addr, 0, sizeof(addr));
1496
        ; memset(mask, 0, sizeof(mask));
1496
        ; memset(mask, 0, sizeof(mask));
1497
        ;
1497
        ;
1498
        ; pff = PFF_MYADDR;
1498
        ; pff = PFF_MYADDR;
1499
        ;
1499
        ;
1500
        ; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
1500
        ; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
1501
        ;
1501
        ;
1502
        ; addr[0] = alwaysOn[0];
1502
        ; addr[0] = alwaysOn[0];
1503
        ; addr[1] = alwaysOn[1];
1503
        ; addr[1] = alwaysOn[1];
1504
        ; mask[0] = alwaysOn[0] | alwaysOff[0];
1504
        ; mask[0] = alwaysOn[0] | alwaysOff[0];
1505
        ; mask[1] = alwaysOn[1] | alwaysOff[1];
1505
        ; mask[1] = alwaysOn[1] | alwaysOff[1];
1506
        ;
1506
        ;
1507
        ; addr[0] |= MCASTADDRA_FORCE;
1507
        ; addr[0] |= MCASTADDRA_FORCE;
1508
        ; pff |= PFF_ALWAYS;
1508
        ; pff |= PFF_ALWAYS;
1509
 
1509
 
1510
        call    stop_rx
1510
        call    stop_rx
1511
 
1511
 
1512
        mov     edi, [ebx + device.mmio_addr]
1512
        mov     edi, [ebx + device.mmio_addr]
1513
        mov     [MulticastAddrA], MCASTADDRA_FORCE
1513
        mov     [MulticastAddrA], MCASTADDRA_FORCE
1514
 
1514
 
1515
        mov     [MulticastAddrB], 0
1515
        mov     [MulticastAddrB], 0
1516
        mov     [MulticastMaskA], 0
1516
        mov     [MulticastMaskA], 0
1517
        mov     [MulticastMaskB], 0
1517
        mov     [MulticastMaskB], 0
1518
        mov     [PacketFilterFlags], (PFF_MYADDR or PFF_ALWAYS)
1518
        mov     [PacketFilterFlags], (PFF_MYADDR or PFF_ALWAYS)
1519
 
1519
 
1520
        call    start_rx
1520
        call    start_rx
1521
 
1521
 
1522
        ret
1522
        ret
1523
 
1523
 
1524
 
1524
 
1525
 
1525
 
1526
 
1526
 
1527
 
1527
 
1528
; Input:  none
1528
; Input:  none
1529
; Output: none
1529
; Output: none
1530
start_rx:
1530
start_rx:
1531
 
1531
 
1532
        push    edi
1532
        push    edi
1533
 
1533
 
1534
        DEBUGF  1,"start_rx\n"
1534
        DEBUGF  1,"start_rx\n"
1535
 
1535
 
1536
        ; Already running? Stop it.
1536
        ; Already running? Stop it.
1537
        mov     edi, [ebx + device.mmio_addr]
1537
        mov     edi, [ebx + device.mmio_addr]
1538
        mov     eax, [ReceiverControl]
1538
        mov     eax, [ReceiverControl]
1539
        test    eax, RCVCTL_START
1539
        test    eax, RCVCTL_START
1540
        jz      @f
1540
        jz      @f
1541
        mov     [ReceiverControl], 0
1541
        mov     [ReceiverControl], 0
1542
        call    pci_push
1542
        call    pci_push
1543
       @@:
1543
       @@:
1544
 
1544
 
1545
        mov     eax, [ebx + device.linkspeed]
1545
        mov     eax, [ebx + device.linkspeed]
1546
        mov     [LinkSpeed], eax
1546
        mov     [LinkSpeed], eax
1547
        call    pci_push
1547
        call    pci_push
1548
 
1548
 
1549
        mov     [ReceiverControl], RCVCTL_START
1549
        mov     [ReceiverControl], RCVCTL_START
1550
        call    pci_push
1550
        call    pci_push
1551
 
1551
 
1552
        pop     edi
1552
        pop     edi
1553
 
1553
 
1554
        ret
1554
        ret
1555
 
1555
 
1556
 
1556
 
1557
 
1557
 
1558
 
1558
 
1559
; Input:  none
1559
; Input:  none
1560
; Output: none
1560
; Output: none
1561
stop_rx:
1561
stop_rx:
1562
 
1562
 
1563
        push    esi edi
1563
        push    esi edi
1564
 
1564
 
1565
        DEBUGF  1,"stop_rx.\n"
1565
        DEBUGF  1,"stop_rx.\n"
1566
 
1566
 
1567
        mov     edi, [ebx + device.mmio_addr]
1567
        mov     edi, [ebx + device.mmio_addr]
1568
        mov     [ReceiverControl], 0
1568
        mov     [ReceiverControl], 0
1569
 
1569
 
1570
        push    ebx edx edi
1570
        push    ebx edx edi
1571
        stdcall reg_delay, ReceiverStatus-edi, RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, 0
1571
        stdcall reg_delay, ReceiverStatus-edi, RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, 0
1572
        pop     edi edx ebx
1572
        pop     edi edx ebx
1573
 
1573
 
1574
        mov     esi, NV_RXSTOP_DELAY2
1574
        mov     esi, NV_RXSTOP_DELAY2
1575
        invoke  Sleep
1575
        invoke  Sleep
1576
 
1576
 
1577
        mov     [LinkSpeed], 0
1577
        mov     [LinkSpeed], 0
1578
 
1578
 
1579
        pop     edi esi
1579
        pop     edi esi
1580
 
1580
 
1581
        ret
1581
        ret
1582
 
1582
 
1583
 
1583
 
1584
 
1584
 
1585
 
1585
 
1586
; Input:  none
1586
; Input:  none
1587
; Output: EAX
1587
; Output: EAX
1588
update_linkspeed:
1588
update_linkspeed:
1589
 
1589
 
1590
        DEBUGF  1,"update linkspeed\n"
1590
        DEBUGF  1,"update linkspeed\n"
1591
 
1591
 
1592
; BMSR_LSTATUS is latched, read it twice: we want the current value.
1592
; BMSR_LSTATUS is latched, read it twice: we want the current value.
1593
        
1593
        
1594
        mov     edx, [ebx + device.phyaddr]
1594
        mov     edx, [ebx + device.phyaddr]
1595
        mov     eax, MII_BMSR
1595
        mov     eax, MII_BMSR
1596
        mov     ecx, MII_READ
1596
        mov     ecx, MII_READ
1597
        call    mii_rw
1597
        call    mii_rw
1598
 
1598
 
1599
        mov     eax, MII_BMSR
1599
        mov     eax, MII_BMSR
1600
        mov     ecx, MII_READ
1600
        mov     ecx, MII_READ
1601
        call    mii_rw
1601
        call    mii_rw
1602
        
1602
        
1603
        test    ax, BMSR_LSTATUS               ; Link up?
1603
        test    ax, BMSR_LSTATUS               ; Link up?
1604
        jz      .no_link
1604
        jz      .no_link
1605
 
1605
 
1606
        DEBUGF  1,"link is up\n"
1606
        DEBUGF  1,"link is up\n"
1607
 
1607
 
1608
        test    ax, BMSR_ANEGCOMPLETE          ; still in autonegotiation?
1608
        test    ax, BMSR_ANEGCOMPLETE          ; still in autonegotiation?
1609
        jz      .10mbit_hd
1609
        jz      .10mbit_hd
1610
 
1610
 
1611
        DEBUGF  1,"autonegotiation is complete\n"
1611
        DEBUGF  1,"autonegotiation is complete\n"
1612
 
1612
 
1613
        cmp     [ebx + device.gigabit], PHY_GIGABIT
1613
        cmp     [ebx + device.gigabit], PHY_GIGABIT
1614
        jne     .no_gigabit
1614
        jne     .no_gigabit
1615
 
1615
 
1616
        ;mov     edx, [ebx + device.phyaddr]
1616
        ;mov     edx, [ebx + device.phyaddr]
1617
        mov     eax, MII_1000BT_CR
1617
        mov     eax, MII_1000BT_CR
1618
        mov     ecx, MII_READ
1618
        mov     ecx, MII_READ
1619
        call    mii_rw
1619
        call    mii_rw
1620
        push    eax
1620
        push    eax
1621
 
1621
 
1622
        ;mov     edx, [ebx + device.phyaddr]
1622
        ;mov     edx, [ebx + device.phyaddr]
1623
        mov     eax, MII_1000BT_SR
1623
        mov     eax, MII_1000BT_SR
1624
        mov     ecx, MII_READ
1624
        mov     ecx, MII_READ
1625
        call    mii_rw
1625
        call    mii_rw
1626
        pop     ecx
1626
        pop     ecx
1627
 
1627
 
1628
        test    eax, LPA_1000FULL
1628
        test    eax, LPA_1000FULL
1629
        jz      .no_gigabit
1629
        jz      .no_gigabit
1630
        test    ecx, ADVERTISE_1000FULL
1630
        test    ecx, ADVERTISE_1000FULL
1631
        jz      .no_gigabit
1631
        jz      .no_gigabit
1632
 
1632
 
1633
        DEBUGF  1,"update_linkspeed: GBit ethernet detected.\n"
1633
        DEBUGF  1,"update_linkspeed: GBit ethernet detected.\n"
1634
        mov     [ebx + device.state], ETH_LINK_1G
1634
        mov     [ebx + device.state], ETH_LINK_1G
1635
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_1000)
1635
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_1000)
1636
        xor     eax, eax
1636
        xor     eax, eax
1637
        inc     eax
1637
        inc     eax
1638
        jmp     set_speed
1638
        jmp     set_speed
1639
  .no_gigabit:
1639
  .no_gigabit:
1640
 
1640
 
1641
        ;mov     edx, [ebx + device.phyaddr]
1641
        ;mov     edx, [ebx + device.phyaddr]
1642
        mov     eax, MII_ADVERTISE
1642
        mov     eax, MII_ADVERTISE
1643
        mov     ecx, MII_READ
1643
        mov     ecx, MII_READ
1644
        call    mii_rw        ; adv = eax
1644
        call    mii_rw        ; adv = eax
1645
        push    eax
1645
        push    eax
1646
 
1646
 
1647
        ;mov     edx, [ebx + device.phyaddr]
1647
        ;mov     edx, [ebx + device.phyaddr]
1648
        mov     eax, MII_LPA
1648
        mov     eax, MII_LPA
1649
        mov     ecx, MII_READ
1649
        mov     ecx, MII_READ
1650
        call    mii_rw        ; lpa = eax
1650
        call    mii_rw        ; lpa = eax
1651
        pop     ecx
1651
        pop     ecx
1652
 
1652
 
1653
        DEBUGF  1,"PHY advertises 0x%x, lpa 0x%x\n", cx, ax
1653
        DEBUGF  1,"PHY advertises 0x%x, lpa 0x%x\n", cx, ax
1654
        and     eax, ecx                ; FIXME: handle parallel detection properly, handle gigabit ethernet
1654
        and     eax, ecx                ; FIXME: handle parallel detection properly, handle gigabit ethernet
1655
 
1655
 
1656
        test    eax, LPA_100FULL
1656
        test    eax, LPA_100FULL
1657
        jz      @f
1657
        jz      @f
1658
        DEBUGF  1,"update_linkspeed: 100 mbit full duplex\n"
1658
        DEBUGF  1,"update_linkspeed: 100 mbit full duplex\n"
1659
        mov     [ebx + device.state], ETH_LINK_100M + ETH_LINK_FD
1659
        mov     [ebx + device.state], ETH_LINK_100M + ETH_LINK_FD
1660
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_100)
1660
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_100)
1661
        xor     eax, eax
1661
        xor     eax, eax
1662
        inc     eax
1662
        inc     eax
1663
        jmp     set_speed
1663
        jmp     set_speed
1664
       @@:
1664
       @@:
1665
 
1665
 
1666
        test    eax, LPA_100HALF
1666
        test    eax, LPA_100HALF
1667
        jz      @f
1667
        jz      @f
1668
        DEBUGF  1,"update_linkspeed: 100 mbit half duplex\n"
1668
        DEBUGF  1,"update_linkspeed: 100 mbit half duplex\n"
1669
        mov     [ebx + device.state], ETH_LINK_100M
1669
        mov     [ebx + device.state], ETH_LINK_100M
1670
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_100)
1670
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_100)
1671
        xor     eax, eax
1671
        xor     eax, eax
1672
        jmp     set_speed
1672
        jmp     set_speed
1673
       @@:
1673
       @@:
1674
 
1674
 
1675
        test    eax, LPA_10FULL
1675
        test    eax, LPA_10FULL
1676
        jz      @f
1676
        jz      @f
1677
        DEBUGF  1,"update_linkspeed: 10 mbit full duplex\n"
1677
        DEBUGF  1,"update_linkspeed: 10 mbit full duplex\n"
1678
        mov     [ebx + device.state], ETH_LINK_10M + ETH_LINK_FD
1678
        mov     [ebx + device.state], ETH_LINK_10M + ETH_LINK_FD
1679
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_10)
1679
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_10)
1680
        xor     eax, eax
1680
        xor     eax, eax
1681
        inc     eax
1681
        inc     eax
1682
        jmp     set_speed
1682
        jmp     set_speed
1683
       @@:
1683
       @@:
1684
 
1684
 
1685
  .10mbit_hd:
1685
  .10mbit_hd:
1686
        DEBUGF  1,"update_linkspeed: 10 mbit half duplex\n"
1686
        DEBUGF  1,"update_linkspeed: 10 mbit half duplex\n"
1687
        mov     [ebx + device.state], ETH_LINK_10M
1687
        mov     [ebx + device.state], ETH_LINK_10M
1688
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_10)
1688
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_10)
1689
        xor     eax, eax
1689
        xor     eax, eax
1690
        jmp     set_speed
1690
        jmp     set_speed
1691
 
1691
 
1692
  .no_link:
1692
  .no_link:
1693
        DEBUGF  1,"update_linkspeed: link is down\n"
1693
        DEBUGF  1,"update_linkspeed: link is down\n"
1694
        mov     [ebx + device.state], ETH_LINK_DOWN
1694
        mov     [ebx + device.state], ETH_LINK_DOWN
1695
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_10)
1695
        mov     ecx, (LINKSPEED_FORCE or LINKSPEED_10)
1696
        xor     eax, eax
1696
        xor     eax, eax
1697
        jmp     set_speed
1697
        jmp     set_speed
1698
 
1698
 
1699
 
1699
 
1700
align 4
1700
align 4
1701
set_speed:
1701
set_speed:
1702
 
1702
 
1703
        cmp     eax, [ebx + device.duplex]
1703
        cmp     eax, [ebx + device.duplex]
1704
        jne     .update
1704
        jne     .update
1705
        cmp     ecx, [ebx + device.linkspeed]
1705
        cmp     ecx, [ebx + device.linkspeed]
1706
        jne     .update
1706
        jne     .update
1707
 
1707
 
1708
        ret
1708
        ret
1709
 
1709
 
1710
  .update:
1710
  .update:
1711
        DEBUGF  1,"update_linkspeed: changing link to 0x%x/XD.\n", ecx
1711
        DEBUGF  1,"update_linkspeed: changing link to 0x%x/XD.\n", ecx
1712
        
1712
        
1713
        mov     [ebx + device.duplex], eax
1713
        mov     [ebx + device.duplex], eax
1714
        mov     [ebx + device.linkspeed], ecx
1714
        mov     [ebx + device.linkspeed], ecx
1715
        
1715
        
1716
        cmp     [ebx + device.gigabit], PHY_GIGABIT
1716
        cmp     [ebx + device.gigabit], PHY_GIGABIT
1717
        jne     .no_gigabit
1717
        jne     .no_gigabit
1718
 
1718
 
1719
        mov     edi, [ebx + device.mmio_addr]
1719
        mov     edi, [ebx + device.mmio_addr]
1720
        mov     eax, [RandomSeed]
1720
        mov     eax, [RandomSeed]
1721
 
1721
 
1722
        and     eax, not (0x3FF00)
1722
        and     eax, not (0x3FF00)
1723
        mov     ecx, eax                ; phyreg = ecx
1723
        mov     ecx, eax                ; phyreg = ecx
1724
 
1724
 
1725
        mov     eax, [ebx + device.linkspeed]
1725
        mov     eax, [ebx + device.linkspeed]
1726
        and     eax, 0xFFF
1726
        and     eax, 0xFFF
1727
        cmp     eax, LINKSPEED_10
1727
        cmp     eax, LINKSPEED_10
1728
        jne     @f
1728
        jne     @f
1729
        or      ecx, RNDSEED_FORCE3
1729
        or      ecx, RNDSEED_FORCE3
1730
        jmp     .end_if4
1730
        jmp     .end_if4
1731
       @@:
1731
       @@:
1732
 
1732
 
1733
        cmp     eax, LINKSPEED_100
1733
        cmp     eax, LINKSPEED_100
1734
        jne     @f
1734
        jne     @f
1735
        or      ecx, RNDSEED_FORCE2
1735
        or      ecx, RNDSEED_FORCE2
1736
        jmp     .end_if4
1736
        jmp     .end_if4
1737
       @@:
1737
       @@:
1738
 
1738
 
1739
        cmp     eax, LINKSPEED_1000
1739
        cmp     eax, LINKSPEED_1000
1740
        jne     .end_if4
1740
        jne     .end_if4
1741
        or      ecx, RNDSEED_FORCE
1741
        or      ecx, RNDSEED_FORCE
1742
  .end_if4:
1742
  .end_if4:
1743
        mov     [RandomSeed], ecx
1743
        mov     [RandomSeed], ecx
1744
  .no_gigabit:
1744
  .no_gigabit:
1745
 
1745
 
1746
        mov     ecx, [PhyInterface]
1746
        mov     ecx, [PhyInterface]
1747
        and     ecx, not (PHY_HALF or PHY_100 or PHY_1000)
1747
        and     ecx, not (PHY_HALF or PHY_100 or PHY_1000)
1748
 
1748
 
1749
        cmp     [ebx + device.duplex], 0
1749
        cmp     [ebx + device.duplex], 0
1750
        jne     @f
1750
        jne     @f
1751
        or      ecx, PHY_HALF
1751
        or      ecx, PHY_HALF
1752
       @@:
1752
       @@:
1753
 
1753
 
1754
        mov     eax, [ebx + device.linkspeed]
1754
        mov     eax, [ebx + device.linkspeed]
1755
        and     eax, 0xFFF
1755
        and     eax, 0xFFF
1756
        cmp     eax, LINKSPEED_100
1756
        cmp     eax, LINKSPEED_100
1757
        jne     @f
1757
        jne     @f
1758
        or      ecx, PHY_100
1758
        or      ecx, PHY_100
1759
        jmp     .end_if5
1759
        jmp     .end_if5
1760
       @@:
1760
       @@:
1761
 
1761
 
1762
        cmp     eax, LINKSPEED_1000
1762
        cmp     eax, LINKSPEED_1000
1763
        jne     .end_if5
1763
        jne     .end_if5
1764
        or      ecx, PHY_1000
1764
        or      ecx, PHY_1000
1765
 
1765
 
1766
  .end_if5:
1766
  .end_if5:
1767
        mov     [PhyInterface], ecx
1767
        mov     [PhyInterface], ecx
1768
                
1768
                
1769
        cmp     [ebx + device.duplex], 0
1769
        cmp     [ebx + device.duplex], 0
1770
        je      @f
1770
        je      @f
1771
        xor     ecx, ecx
1771
        xor     ecx, ecx
1772
        jmp     .next
1772
        jmp     .next
1773
       @@:
1773
       @@:
1774
 
1774
 
1775
        mov     ecx, MISC1_HD
1775
        mov     ecx, MISC1_HD
1776
  .next:
1776
  .next:
1777
        or      ecx, MISC1_FORCE
1777
        or      ecx, MISC1_FORCE
1778
        mov     [Misc1], ecx
1778
        mov     [Misc1], ecx
1779
 
1779
 
1780
        call    pci_push
1780
        call    pci_push
1781
 
1781
 
1782
        mov     eax, [ebx + device.linkspeed]
1782
        mov     eax, [ebx + device.linkspeed]
1783
        mov     [LinkSpeed], eax
1783
        mov     [LinkSpeed], eax
1784
 
1784
 
1785
        call    pci_push
1785
        call    pci_push
1786
 
1786
 
1787
        ret
1787
        ret
1788
 
1788
 
1789
 
1789
 
1790
 
1790
 
1791
 
1791
 
1792
 
1792
 
1793
 
1793
 
1794
align 4
1794
align 4
1795
read_mac:
1795
read_mac:
1796
 
1796
 
1797
        mov     edi, [ebx + device.mmio_addr]
1797
        mov     edi, [ebx + device.mmio_addr]
1798
        mov     eax, [MacAddrA]
1798
        mov     eax, [MacAddrA]
1799
        mov     ecx, [MacAddrB]
1799
        mov     ecx, [MacAddrB]
1800
 
1800
 
1801
        mov     dword [ebx + device.mac], eax
1801
        mov     dword [ebx + device.mac], eax
1802
        mov     word [ebx + device.mac + 4], cx
1802
        mov     word [ebx + device.mac + 4], cx
1803
 
1803
 
1804
        cmp     [ebx + device.device_id], 0x03E5
1804
        cmp     [ebx + device.device_id], 0x03E5
1805
        jae     @f
1805
        jae     @f
1806
        bswap   eax
1806
        bswap   eax
1807
        xchg    cl, ch
1807
        xchg    cl, ch
1808
        mov     dword [ebx + device.mac + 2], eax
1808
        mov     dword [ebx + device.mac + 2], eax
1809
        mov     word [ebx + device.mac], cx
1809
        mov     word [ebx + device.mac], cx
1810
       @@:
1810
       @@:
1811
 
1811
 
1812
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n", \
1812
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n", \
1813
        [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
1813
        [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
1814
 
1814
 
1815
        ret
1815
        ret
1816
 
1816
 
1817
 
1817
 
1818
 
1818
 
1819
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1819
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1820
;;                                         ;;
1820
;;                                         ;;
1821
;; Transmit                                ;;
1821
;; Transmit                                ;;
1822
;;                                         ;;
1822
;;                                         ;;
1823
;; In: buffer pointer in [esp+4]           ;;
1823
;; In: buffer pointer in [esp+4]           ;;
1824
;;     size of buffer in [esp+8]           ;;
1824
;;     size of buffer in [esp+8]           ;;
1825
;;     pointer to device structure in ebx  ;;
1825
;;     pointer to device structure in ebx  ;;
1826
;;                                         ;;
1826
;;                                         ;;
1827
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1827
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1828
 
1828
 
1829
proc transmit stdcall bufferptr, buffersize
1829
proc transmit stdcall bufferptr, buffersize
1830
 
1830
 
1831
        pushf
1831
        pushf
1832
        cli
1832
        cli
1833
 
1833
 
1834
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1834
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
1835
        mov     eax, [bufferptr]
1835
        mov     eax, [bufferptr]
1836
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1836
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
1837
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1837
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
1838
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1838
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
1839
        [eax+13]:2,[eax+12]:2
1839
        [eax+13]:2,[eax+12]:2
1840
 
1840
 
1841
        cmp     [buffersize], 1514
1841
        cmp     [buffersize], 1514
1842
        ja      .fail
1842
        ja      .fail
1843
        cmp     [buffersize], 60
1843
        cmp     [buffersize], 60
1844
        jb      .fail
1844
        jb      .fail
1845
 
1845
 
1846
; get the descriptor address
1846
; get the descriptor address
1847
        mov     eax, [ebx + device.cur_tx]
1847
        mov     eax, [ebx + device.cur_tx]
1848
        shl     eax, 3                                  ; TX descriptor is 8 bytes.
1848
        shl     eax, 3                                  ; TX descriptor is 8 bytes.
1849
        lea     esi, [ebx + device.tx_ring + eax]
1849
        lea     esi, [ebx + device.tx_ring + eax]
1850
 
1850
 
1851
        mov     eax, [bufferptr]
1851
        mov     eax, [bufferptr]
1852
        mov     [esi + TX_RING*sizeof.TxDesc], eax
1852
        mov     [esi + TX_RING*sizeof.TxDesc], eax
1853
        invoke  GetPhysAddr                             ; Does not change esi/ebx :)
1853
        invoke  GetPhysAddr                             ; Does not change esi/ebx :)
1854
        mov     [esi + TxDesc.PacketBuffer], eax
1854
        mov     [esi + TxDesc.PacketBuffer], eax
1855
 
1855
 
1856
        mov     eax, [buffersize]
1856
        mov     eax, [buffersize]
1857
        or      eax, [ebx + device.txflags]
1857
        or      eax, [ebx + device.txflags]
1858
        mov     [esi + TxDesc.FlagLen], eax
1858
        mov     [esi + TxDesc.FlagLen], eax
1859
 
1859
 
1860
        mov     edi, [ebx + device.mmio_addr]
1860
        mov     edi, [ebx + device.mmio_addr]
1861
        mov     eax, [ebx + device.desc_ver]
1861
        mov     eax, [ebx + device.desc_ver]
1862
        or      eax, TXRXCTL_KICK
1862
        or      eax, TXRXCTL_KICK
1863
        mov     [TxRxControl], eax
1863
        mov     [TxRxControl], eax
1864
 
1864
 
1865
        call    pci_push
1865
        call    pci_push
1866
 
1866
 
1867
        inc     [ebx + device.cur_tx]
1867
        inc     [ebx + device.cur_tx]
1868
        and     [ebx + device.cur_tx], (TX_RING-1)
1868
        and     [ebx + device.cur_tx], (TX_RING-1)
1869
 
1869
 
1870
; Update stats
1870
; Update stats
1871
        inc     [ebx + device.packets_tx]
1871
        inc     [ebx + device.packets_tx]
1872
        mov     eax, [buffersize]
1872
        mov     eax, [buffersize]
1873
        add     dword[ebx + device.bytes_tx], eax
1873
        add     dword[ebx + device.bytes_tx], eax
1874
        adc     dword[ebx + device.bytes_tx + 4], 0
1874
        adc     dword[ebx + device.bytes_tx + 4], 0
1875
 
1875
 
1876
        xor     eax, eax
1876
        xor     eax, eax
1877
        popf
1877
        popf
1878
        ret
1878
        ret
1879
 
1879
 
1880
  .fail:
1880
  .fail:
1881
        DEBUGF  2,"Send failed\n"
1881
        DEBUGF  2,"Send failed\n"
1882
        invoke  KernelFree, [bufferptr]
1882
        invoke  KernelFree, [bufferptr]
1883
        popf
1883
        popf
1884
        or      eax, -1
1884
        or      eax, -1
1885
        ret
1885
        ret
1886
 
1886
 
1887
endp
1887
endp
1888
 
1888
 
1889
 
1889
 
1890
 
1890
 
1891
 
1891
 
1892
 
1892
 
1893
 
1893
 
1894
; Interrupt handler
1894
; Interrupt handler
1895
align 4
1895
align 4
1896
int_handler:
1896
int_handler:
1897
 
1897
 
1898
        push    ebx esi edi
1898
        push    ebx esi edi
1899
 
1899
 
1900
        DEBUGF  1,"INT\n"
1900
        DEBUGF  1,"INT\n"
1901
 
1901
 
1902
;-------------------------------------------
1902
;-------------------------------------------
1903
; Find pointer of device wich made IRQ occur
1903
; Find pointer of device wich made IRQ occur
1904
 
1904
 
1905
        mov     esi, device_list
1905
        mov     esi, device_list
1906
        mov     ecx, [devices]
1906
        mov     ecx, [devices]
1907
        test    ecx, ecx
1907
        test    ecx, ecx
1908
        jz      .fail
1908
        jz      .fail
1909
  .nextdevice:
1909
  .nextdevice:
1910
        mov     ebx, dword [esi]
1910
        mov     ebx, dword [esi]
1911
        add     esi, 4
1911
        add     esi, 4
1912
 
1912
 
1913
        mov     edi, [ebx + device.mmio_addr]
1913
        mov     edi, [ebx + device.mmio_addr]
1914
        mov     eax, [IrqStatus]
1914
        mov     eax, [IrqStatus]
1915
        test    eax, eax
1915
        test    eax, eax
1916
        jnz     .got_it
1916
        jnz     .got_it
1917
        dec     ecx
1917
        dec     ecx
1918
        jnz     .nextdevice
1918
        jnz     .nextdevice
1919
  .nothing:
1919
  .nothing:
1920
        pop     edi esi ebx
1920
        pop     edi esi ebx
1921
        xor     eax, eax
1921
        xor     eax, eax
1922
 
1922
 
1923
        ret
1923
        ret
1924
 
1924
 
1925
  .got_it:
1925
  .got_it:
1926
        mov     [IrqStatus], eax
1926
        mov     [IrqStatus], eax
1927
        DEBUGF  1,"IrqStatus = %x\n", eax
1927
        DEBUGF  1,"IrqStatus = %x\n", eax
1928
 
1928
 
1929
        test    eax, IRQ_RX ;+ IRQ_TIMER ;;;;
1929
        test    eax, IRQ_RX ;+ IRQ_TIMER ;;;;
1930
        jz      .no_rx
1930
        jz      .no_rx
1931
 
1931
 
1932
        push    ebx
1932
        push    ebx
1933
  .more_rx:
1933
  .more_rx:
1934
        pop     ebx
1934
        pop     ebx
1935
        mov     eax, [ebx + device.cur_rx]
1935
        mov     eax, [ebx + device.cur_rx]
1936
        mov     cx, sizeof.RxDesc
1936
        mov     cx, sizeof.RxDesc
1937
        mul     cx
1937
        mul     cx
1938
        lea     esi, [ebx + device.rx_ring + eax]
1938
        lea     esi, [ebx + device.rx_ring + eax]
1939
        mov     eax, [esi + RxDesc.FlagLen]
1939
        mov     eax, [esi + RxDesc.FlagLen]
1940
 
1940
 
1941
        test    eax, NV_RX_AVAIL        ; still owned by hardware
1941
        test    eax, NV_RX_AVAIL        ; still owned by hardware
1942
        jnz     .no_rx
1942
        jnz     .no_rx
1943
 
1943
 
1944
        cmp     [ebx + device.desc_ver], DESC_VER_1
1944
        cmp     [ebx + device.desc_ver], DESC_VER_1
1945
        jne     @f
1945
        jne     @f
1946
        test    eax, NV_RX_DESCRIPTORVALID
1946
        test    eax, NV_RX_DESCRIPTORVALID
1947
        jz      .no_rx
1947
        jz      .no_rx
1948
        jmp     .next
1948
        jmp     .next
1949
  @@:
1949
  @@:
1950
        test    eax, NV_RX2_DESCRIPTORVALID
1950
        test    eax, NV_RX2_DESCRIPTORVALID
1951
        jz      .no_rx
1951
        jz      .no_rx
1952
 
1952
 
1953
  .next:
1953
  .next:
1954
        cmp     dword[ebx + device.desc_ver], DESC_VER_1
1954
        cmp     dword[ebx + device.desc_ver], DESC_VER_1
1955
        jne     @f
1955
        jne     @f
1956
        and     eax, LEN_MASK_V1
1956
        and     eax, LEN_MASK_V1
1957
        jmp     .next2
1957
        jmp     .next2
1958
   @@:
1958
   @@:
1959
        and     eax, LEN_MASK_V2
1959
        and     eax, LEN_MASK_V2
1960
 
1960
 
1961
  .next2:
1961
  .next2:
1962
        DEBUGF  1,"Received %u bytes\n", eax
1962
        DEBUGF  1,"Received %u bytes\n", eax
1963
 
1963
 
1964
        ; Update stats
1964
        ; Update stats
1965
        add     dword[ebx + device.bytes_rx], eax
1965
        add     dword[ebx + device.bytes_rx], eax
1966
        adc     dword[ebx + device.bytes_rx + 4], 0
1966
        adc     dword[ebx + device.bytes_rx + 4], 0
1967
        inc     dword[ebx + device.packets_rx]
1967
        inc     dword[ebx + device.packets_rx]
1968
 
1968
 
1969
        ; Prepare to give packet to kernel
1969
        ; Prepare to give packet to kernel
1970
        push    ebx
1970
        push    ebx
1971
        push    .more_rx
1971
        push    .more_rx
1972
 
1972
 
1973
        push    eax
1973
        push    eax
1974
        push    dword[esi + RX_RING*sizeof.RxDesc]
1974
        push    dword[esi + RX_RING*sizeof.RxDesc]
1975
        DEBUGF  1,"packet ptr=0x%x\n", [esi + RX_RING*sizeof.RxDesc]
1975
        DEBUGF  1,"packet ptr=0x%x\n", [esi + RX_RING*sizeof.RxDesc]
1976
 
1976
 
1977
        ; Allocate new buffer for this descriptor
1977
        ; Allocate new buffer for this descriptor
1978
        invoke  KernelAlloc, 4096 shl RBLEN
1978
        invoke  KernelAlloc, 4096 shl RBLEN
1979
        mov     [esi + RX_RING*sizeof.RxDesc], eax
1979
        mov     [esi + RX_RING*sizeof.RxDesc], eax
1980
        invoke  GetPhysAddr
1980
        invoke  GetPhysAddr
1981
        mov     [esi + RxDesc.PacketBuffer], eax
1981
        mov     [esi + RxDesc.PacketBuffer], eax
1982
        mov     [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL)
1982
        mov     [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL)
1983
 
1983
 
1984
        ; update current RX descriptor
1984
        ; update current RX descriptor
1985
        inc     [ebx + device.cur_rx]
1985
        inc     [ebx + device.cur_rx]
1986
        and     [ebx + device.cur_rx], (RX_RING-1)
1986
        and     [ebx + device.cur_rx], (RX_RING-1)
1987
 
1987
 
1988
        jmp     [Eth_input]
1988
        jmp     [Eth_input]
1989
 
1989
 
1990
  .no_rx:
1990
  .no_rx:
1991
        test    eax, IRQ_RX_ERROR
1991
        test    eax, IRQ_RX_ERROR
1992
        jz      .no_rx_err
1992
        jz      .no_rx_err
1993
 
1993
 
1994
        push    eax
1994
        push    eax
1995
        DEBUGF  2,"RX error!\n"
1995
        DEBUGF  2,"RX error!\n"
1996
 
1996
 
1997
        mov     eax, [ebx + device.cur_rx]
1997
        mov     eax, [ebx + device.cur_rx]
1998
        mov     cx, sizeof.RxDesc
1998
        mov     cx, sizeof.RxDesc
1999
        mul     cx
1999
        mul     cx
2000
        lea     esi, [ebx + device.rx_ring + eax]
2000
        lea     esi, [ebx + device.rx_ring + eax]
2001
        mov     eax, [esi + RxDesc.FlagLen]
2001
        mov     eax, [esi + RxDesc.FlagLen]
2002
 
2002
 
2003
        DEBUGF  1,"Flaglen=%x\n", eax
2003
        DEBUGF  1,"Flaglen=%x\n", eax
2004
 
2004
 
2005
        ; TODO: allocate new buff ?
2005
        ; TODO: allocate new buff ?
2006
        pop     eax
2006
        pop     eax
2007
 
2007
 
2008
  .no_rx_err:
2008
  .no_rx_err:
2009
        test    eax, IRQ_TX_ERROR
2009
        test    eax, IRQ_TX_ERROR
2010
        jz      .no_tx_err
2010
        jz      .no_tx_err
2011
 
2011
 
2012
        DEBUGF  2,"TX error!\n"
2012
        DEBUGF  2,"TX error!\n"
2013
        ; TODO
2013
        ; TODO
2014
 
2014
 
2015
  .no_tx_err:
2015
  .no_tx_err:
2016
        test    eax, IRQ_LINK
2016
        test    eax, IRQ_LINK
2017
        jz      .no_link
2017
        jz      .no_link
2018
 
2018
 
2019
        push    eax
2019
        push    eax
2020
        call    update_linkspeed
2020
        call    update_linkspeed
2021
        pop     eax
2021
        pop     eax
2022
 
2022
 
2023
  .no_link:
2023
  .no_link:
2024
        test    eax, IRQ_TX_OK
2024
        test    eax, IRQ_TX_OK
2025
        jz      .no_tx
2025
        jz      .no_tx
2026
 
2026
 
2027
        DEBUGF  1, "TX completed\n"
2027
        DEBUGF  1, "TX completed\n"
2028
      .loop_tx:
2028
      .loop_tx:
2029
        mov     esi, [ebx + device.last_tx]
2029
        mov     esi, [ebx + device.last_tx]
2030
        shl     esi, 3                                  ; TX descriptor is 8 bytes.
2030
        shl     esi, 3                                  ; TX descriptor is 8 bytes.
2031
        lea     esi, [ebx + device.tx_ring + esi]
2031
        lea     esi, [ebx + device.tx_ring + esi]
2032
 
2032
 
2033
        DEBUGF  1,"Flaglen = 0x%x\n", [esi + TxDesc.FlagLen]
2033
        DEBUGF  1,"Flaglen = 0x%x\n", [esi + TxDesc.FlagLen]
2034
        test    [esi + TxDesc.FlagLen], NV_TX_VALID
2034
        test    [esi + TxDesc.FlagLen], NV_TX_VALID
2035
        jnz     .no_tx
2035
        jnz     .no_tx
2036
        cmp     dword[esi + TX_RING*sizeof.TxDesc], 0
2036
        cmp     dword[esi + TX_RING*sizeof.TxDesc], 0
2037
        je      .no_tx
2037
        je      .no_tx
2038
 
2038
 
2039
        DEBUGF  1,"Freeing buffer 0x%x\n", [esi + TX_RING*sizeof.TxDesc]:8
2039
        DEBUGF  1,"Freeing buffer 0x%x\n", [esi + TX_RING*sizeof.TxDesc]:8
2040
        push    dword[esi + TX_RING*sizeof.TxDesc]
2040
        push    dword[esi + TX_RING*sizeof.TxDesc]
2041
        mov     dword[esi + TX_RING*sizeof.TxDesc], 0
2041
        mov     dword[esi + TX_RING*sizeof.TxDesc], 0
2042
        invoke  KernelFree
2042
        invoke  KernelFree
2043
 
2043
 
2044
        inc     [ebx + device.last_tx]
2044
        inc     [ebx + device.last_tx]
2045
        and     [ebx + device.last_tx], TX_RING - 1
2045
        and     [ebx + device.last_tx], TX_RING - 1
2046
 
2046
 
2047
        jmp     .loop_tx
2047
        jmp     .loop_tx
2048
 
2048
 
2049
  .no_tx:
2049
  .no_tx:
2050
  .fail:
2050
  .fail:
2051
        pop     edi esi ebx
2051
        pop     edi esi ebx
2052
        xor     eax, eax
2052
        xor     eax, eax
2053
        inc     eax
2053
        inc     eax
2054
 
2054
 
2055
        ret
2055
        ret
2056
 
2056
 
2057
 
2057
 
2058
; End of code
2058
; End of code
2059
 
2059
 
2060
data fixups
2060
data fixups
2061
end data
2061
end data
2062
 
2062
 
2063
include '../peimport.inc'
2063
include '../peimport.inc'
2064
 
2064
 
2065
my_service      db 'FORCEDETH',0                ; max 16 chars include zero
2065
my_service      db 'FORCEDETH',0                ; max 16 chars include zero
2066
 
2066
 
2067
include_debug_strings
2067
include_debug_strings
2068
 
2068
 
2069
align 4
2069
align 4
2070
devices         dd 0
2070
devices         dd 0
2071
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
2071
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling