Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2434 | Serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
2465 | Serge | 3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
2434 | Serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; FORCEDETH.INC ;; |
||
7 | ;; ;; |
||
8 | ;; Ethernet driver for Kolibri OS ;; |
||
9 | ;; ;; |
||
10 | ;; Version 0.1 24 June 2008 - 23 Sep 2008 ;; |
||
11 | ;; ;; |
||
12 | ;; Driver for chips of NVIDIA nForce2 ;; |
||
13 | ;; References: ;; |
||
14 | ;; forcedeth.c - linux driver (etherboot project) ;; |
||
15 | ;; ethernet driver template by Mike Hibbett ;; |
||
16 | ;; ;; |
||
17 | ;; The copyright statement is ;; |
||
18 | ;; ;; |
||
19 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
20 | ;; Version 2, June 1991 ;; |
||
21 | ;; ;; |
||
22 | ;; Copyright 2008 shurf, ;; |
||
23 | ;; cit.utc@gmail.com ;; |
||
24 | ;; ;; |
||
25 | ;; See file COPYING for details ;; |
||
26 | ;; ;; |
||
27 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
28 | |||
29 | $Revision: 2465 $ |
||
30 | |||
31 | ;******************************************************************** |
||
32 | ; Interface |
||
33 | ; forcedeth_reset |
||
34 | ; forcedeth_probe |
||
35 | ; forcedeth_poll |
||
36 | ; forcedeth_transmit |
||
37 | ; forcedeth_cable |
||
38 | ; |
||
39 | ;******************************************************************** |
||
40 | |||
41 | ;************************************************************************** |
||
42 | ; forcedeth Register Definitions |
||
43 | ;************************************************************************** |
||
44 | |||
45 | PCI_REG_COMMAND equ 0x04 ; command register |
||
46 | |||
47 | PCI_COMMAND_IO equ 0x01 ; Enable response in I/O space |
||
48 | PCI_COMMAND_MASTER equ 0x04 ; Enable bus mastering |
||
49 | PCI_LATENCY_TIMER equ 0x0d ; 8 bits |
||
50 | |||
51 | PCI_VENDOR_ID equ 0x00 ; 16 bit |
||
52 | PCI_REVISION_ID equ 0x08 ; 8 bits |
||
53 | |||
54 | PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits |
||
55 | PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits |
||
56 | PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits |
||
57 | PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits |
||
58 | PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits |
||
59 | PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits |
||
60 | |||
61 | PCI_BASE_ADDRESS_SPACE_IO equ 0x01 |
||
62 | PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) |
||
63 | PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) |
||
64 | |||
65 | PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 |
||
66 | PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address |
||
67 | PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] |
||
68 | PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address |
||
69 | |||
70 | ; NIC specific static variables go here |
||
71 | PCI_DEVICE_ID_NVIDIA_NVENET_1 equ 0x01c3 |
||
72 | PCI_DEVICE_ID_NVIDIA_NVENET_2 equ 0x0066 |
||
73 | PCI_DEVICE_ID_NVIDIA_NVENET_4 equ 0x0086 |
||
74 | PCI_DEVICE_ID_NVIDIA_NVENET_5 equ 0x008c |
||
75 | PCI_DEVICE_ID_NVIDIA_NVENET_3 equ 0x00d6 |
||
76 | PCI_DEVICE_ID_NVIDIA_NVENET_7 equ 0x00df |
||
77 | PCI_DEVICE_ID_NVIDIA_NVENET_6 equ 0x00e6 |
||
78 | PCI_DEVICE_ID_NVIDIA_NVENET_8 equ 0x0056 |
||
79 | PCI_DEVICE_ID_NVIDIA_NVENET_9 equ 0x0057 |
||
80 | PCI_DEVICE_ID_NVIDIA_NVENET_10 equ 0x0037 |
||
81 | PCI_DEVICE_ID_NVIDIA_NVENET_11 equ 0x0038 |
||
82 | PCI_DEVICE_ID_NVIDIA_NVENET_12 equ 0x0268 |
||
83 | PCI_DEVICE_ID_NVIDIA_NVENET_13 equ 0x0269 |
||
84 | PCI_DEVICE_ID_NVIDIA_NVENET_14 equ 0x0372 |
||
85 | PCI_DEVICE_ID_NVIDIA_NVENET_15 equ 0x0373 |
||
86 | |||
87 | ETH_DATA_LEN equ 1500 |
||
88 | |||
89 | ; rx/tx mac addr + type + vlan + align + slack |
||
90 | RX_NIC_BUFSIZE equ (ETH_DATA_LEN + 64) |
||
91 | ; even more slack |
||
92 | RX_ALLOC_BUFSIZE equ (ETH_DATA_LEN + 128) |
||
93 | |||
94 | NvRegIrqStatus equ 0x00 |
||
95 | NvRegIrqMask equ 0x04 |
||
96 | NvRegUnknownSetupReg6 equ 0x08 |
||
97 | NvRegPollingInterval equ 0x0c |
||
98 | NvRegMacReset equ 0x3c |
||
99 | NvRegMisc1 equ 0x80 |
||
100 | NvRegTransmitterControl equ 0x84 |
||
101 | NvRegTransmitterStatus equ 0x88 |
||
102 | NvRegPacketFilterFlags equ 0x8c |
||
103 | NvRegOffloadConfig equ 0x90 |
||
104 | NvRegReceiverControl equ 0x94 |
||
105 | NvRegReceiverStatus equ 0x98 |
||
106 | NvRegRandomSeed equ 0x9c |
||
107 | NvRegUnknownSetupReg1 equ 0xA0 |
||
108 | NvRegUnknownSetupReg2 equ 0xA4 |
||
109 | NvRegMacAddrA equ 0xA8 ; MAC address low |
||
110 | NvRegMacAddrB equ 0xAC ; MAC address high |
||
111 | NvRegMulticastAddrA equ 0xB0 |
||
112 | NvRegMulticastAddrB equ 0xB4 |
||
113 | NvRegMulticastMaskA equ 0xB8 |
||
114 | NvRegMulticastMaskB equ 0xBC |
||
115 | NvRegPhyInterface equ 0xC0 |
||
116 | NvRegTxRingPhysAddr equ 0x100 |
||
117 | NvRegRxRingPhysAddr equ 0x104 |
||
118 | NvRegRingSizes equ 0x108 |
||
119 | NvRegUnknownTransmitterReg equ 0x10c |
||
120 | NvRegLinkSpeed equ 0x110 |
||
121 | NvRegUnknownSetupReg5 equ 0x130 |
||
122 | NvRegUnknownSetupReg3 equ 0x13c |
||
123 | NvRegTxRxControl equ 0x144 |
||
124 | NvRegMIIStatus equ 0x180 |
||
125 | NvRegUnknownSetupReg4 equ 0x184 |
||
126 | NvRegAdapterControl equ 0x188 |
||
127 | NvRegMIISpeed equ 0x18c |
||
128 | NvRegMIIControl equ 0x190 |
||
129 | NvRegMIIData equ 0x194 |
||
130 | NvRegWakeUpFlags equ 0x200 |
||
131 | NvRegPowerState equ 0x26c |
||
132 | NvRegPowerState2 equ 0x600 |
||
133 | |||
134 | NVREG_UNKSETUP1_VAL equ 0x16070f |
||
135 | NVREG_UNKSETUP2_VAL equ 0x16 |
||
136 | NVREG_UNKSETUP3_VAL1 equ 0x200010 |
||
137 | NVREG_UNKSETUP4_VAL equ 8 |
||
138 | NVREG_UNKSETUP5_BIT31 equ (1 shl 31) |
||
139 | NVREG_UNKSETUP6_VAL equ 3 |
||
140 | |||
141 | NVREG_TXRXCTL_RXCHECK equ 0x0400 |
||
142 | NVREG_MIISTAT_ERROR equ 0x0001 |
||
143 | NVREG_MIISTAT_MASK equ 0x000f |
||
144 | NVREG_MIISTAT_MASK2 equ 0x000f |
||
145 | NVREG_MIICTL_INUSE equ 0x08000 |
||
146 | NVREG_MIICTL_WRITE equ 0x00400 |
||
147 | NVREG_MIICTL_ADDRSHIFT equ 5 |
||
148 | |||
149 | NVREG_MIISPEED_BIT8 equ (1 shl 8) |
||
150 | NVREG_MIIDELAY equ 5 |
||
151 | |||
152 | NVREG_IRQ_RX_ERROR equ 0x0001 |
||
153 | NVREG_IRQ_RX equ 0x0002 |
||
154 | NVREG_IRQ_RX_NOBUF equ 0x0004 |
||
155 | NVREG_IRQ_LINK equ 0x0040 |
||
156 | NVREG_IRQ_TIMER equ 0x0020 |
||
157 | NVREG_IRQMASK_WANTED_2 equ 0x0147 |
||
158 | |||
159 | NVREG_IRQ_RX_ALL equ (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF) |
||
160 | NVREG_IRQ_TX_ALL equ 0 ; ??????????? |
||
161 | NVREG_IRQ_OTHER_ALL equ (NVREG_IRQ_LINK or NVREG_IRQ_TIMER) |
||
162 | |||
163 | NVREG_IRQSTAT_MASK equ 0x1ff |
||
164 | |||
165 | NVREG_TXRXCTL_KICK equ 0x0001 |
||
166 | NVREG_TXRXCTL_BIT1 equ 0x0002 |
||
167 | NVREG_TXRXCTL_BIT2 equ 0x0004 |
||
168 | NVREG_TXRXCTL_IDLE equ 0x0008 |
||
169 | NVREG_TXRXCTL_RESET equ 0x0010 |
||
170 | NVREG_TXRXCTL_RXCHECK equ 0x0400 |
||
171 | |||
172 | NVREG_MCASTADDRA_FORCE equ 0x01 |
||
173 | |||
174 | NVREG_MAC_RESET_ASSERT equ 0x0F3 |
||
175 | |||
176 | NVREG_MISC1_HD equ 0x02 |
||
177 | NVREG_MISC1_FORCE equ 0x3b0f3c |
||
178 | |||
179 | NVREG_PFF_ALWAYS equ 0x7F0008 |
||
180 | NVREG_PFF_PROMISC equ 0x80 |
||
181 | NVREG_PFF_MYADDR equ 0x20 |
||
182 | |||
183 | NVREG_OFFLOAD_HOMEPHY equ 0x601 |
||
184 | NVREG_OFFLOAD_NORMAL equ RX_NIC_BUFSIZE |
||
185 | |||
186 | NVREG_RNDSEED_MASK equ 0x00ff |
||
187 | NVREG_RNDSEED_FORCE equ 0x7f00 |
||
188 | NVREG_RNDSEED_FORCE2 equ 0x2d00 |
||
189 | NVREG_RNDSEED_FORCE3 equ 0x7400 |
||
190 | |||
191 | ; NVREG_POLL_DEFAULT is the interval length of the timer source on the nic |
||
192 | ; NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms |
||
193 | NVREG_POLL_DEFAULT equ 970 |
||
194 | |||
195 | NVREG_ADAPTCTL_START equ 0x02 |
||
196 | NVREG_ADAPTCTL_LINKUP equ 0x04 |
||
197 | NVREG_ADAPTCTL_PHYVALID equ 0x40000 |
||
198 | NVREG_ADAPTCTL_RUNNING equ 0x100000 |
||
199 | NVREG_ADAPTCTL_PHYSHIFT equ 24 |
||
200 | |||
201 | NVREG_WAKEUPFLAGS_VAL equ 0x7770 |
||
202 | |||
203 | NVREG_POWERSTATE_POWEREDUP equ 0x8000 |
||
204 | NVREG_POWERSTATE_VALID equ 0x0100 |
||
205 | NVREG_POWERSTATE_MASK equ 0x0003 |
||
206 | NVREG_POWERSTATE_D0 equ 0x0000 |
||
207 | NVREG_POWERSTATE_D1 equ 0x0001 |
||
208 | NVREG_POWERSTATE_D2 equ 0x0002 |
||
209 | NVREG_POWERSTATE_D3 equ 0x0003 |
||
210 | |||
211 | NVREG_POWERSTATE2_POWERUP_MASK equ 0x0F11 |
||
212 | NVREG_POWERSTATE2_POWERUP_REV_A3 equ 0x0001 |
||
213 | |||
214 | NVREG_RCVCTL_START equ 0x01 |
||
215 | NVREG_RCVSTAT_BUSY equ 0x01 |
||
216 | |||
217 | NVREG_XMITCTL_START equ 0x01 |
||
218 | |||
219 | NVREG_LINKSPEED_FORCE equ 0x10000 |
||
220 | NVREG_LINKSPEED_10 equ 1000 |
||
221 | NVREG_LINKSPEED_100 equ 100 |
||
222 | NVREG_LINKSPEED_1000 equ 50 |
||
223 | |||
224 | NVREG_RINGSZ_TXSHIFT equ 0 |
||
225 | NVREG_RINGSZ_RXSHIFT equ 16 |
||
226 | |||
227 | LPA_1000FULL equ 0x0800 |
||
228 | |||
229 | ; Link partner ability register. |
||
230 | LPA_SLCT equ 0x001f ; Same as advertise selector |
||
231 | LPA_10HALF equ 0x0020 ; Can do 10mbps half-duplex |
||
232 | LPA_10FULL equ 0x0040 ; Can do 10mbps full-duplex |
||
233 | LPA_100HALF equ 0x0080 ; Can do 100mbps half-duplex |
||
234 | LPA_100FULL equ 0x0100 ; Can do 100mbps full-duplex |
||
235 | LPA_100BASE4 equ 0x0200 ; Can do 100mbps 4k packets |
||
236 | LPA_RESV equ 0x1c00 ; Unused... |
||
237 | LPA_RFAULT equ 0x2000 ; Link partner faulted |
||
238 | LPA_LPACK equ 0x4000 ; Link partner acked us |
||
239 | LPA_NPAGE equ 0x8000 ; Next page bit |
||
240 | |||
241 | MII_READ equ (-1) |
||
242 | MII_PHYSID1 equ 0x02 ; PHYS ID 1 |
||
243 | MII_PHYSID2 equ 0x03 ; PHYS ID 2 |
||
244 | MII_BMCR equ 0x00 ; Basic mode control register |
||
245 | MII_BMSR equ 0x01 ; Basic mode status register |
||
246 | MII_ADVERTISE equ 0x04 ; Advertisement control reg |
||
247 | MII_LPA equ 0x05 ; Link partner ability reg |
||
248 | MII_SREVISION equ 0x16 ; Silicon revision |
||
249 | MII_RESV1 equ 0x17 ; Reserved... |
||
250 | MII_NCONFIG equ 0x1c ; Network interface config |
||
251 | |||
252 | ; PHY defines |
||
253 | PHY_OUI_MARVELL equ 0x5043 |
||
254 | PHY_OUI_CICADA equ 0x03f1 |
||
255 | PHYID1_OUI_MASK equ 0x03ff |
||
256 | PHYID1_OUI_SHFT equ 6 |
||
257 | PHYID2_OUI_MASK equ 0xfc00 |
||
258 | PHYID2_OUI_SHFT equ 10 |
||
259 | PHY_INIT1 equ 0x0f000 |
||
260 | PHY_INIT2 equ 0x0e00 |
||
261 | PHY_INIT3 equ 0x01000 |
||
262 | PHY_INIT4 equ 0x0200 |
||
263 | PHY_INIT5 equ 0x0004 |
||
264 | PHY_INIT6 equ 0x02000 |
||
265 | PHY_GIGABIT equ 0x0100 |
||
266 | |||
267 | PHY_TIMEOUT equ 0x1 |
||
268 | PHY_ERROR equ 0x2 |
||
269 | |||
270 | PHY_100 equ 0x1 |
||
271 | PHY_1000 equ 0x2 |
||
272 | PHY_HALF equ 0x100 |
||
273 | |||
274 | PHY_RGMII equ 0x10000000 |
||
275 | |||
276 | ; desc_ver values: |
||
277 | ; This field has two purposes: |
||
278 | ; - Newer nics uses a different ring layout. The layout is selected by |
||
279 | ; comparing np->desc_ver with DESC_VER_xy. |
||
280 | ; - It contains bits that are forced on when writing to NvRegTxRxControl. |
||
281 | DESC_VER_1 equ 0x0 |
||
282 | DESC_VER_2 equ (0x02100 or NVREG_TXRXCTL_RXCHECK) |
||
283 | |||
284 | MAC_ADDR_LEN equ 6 |
||
285 | |||
286 | NV_TX_LASTPACKET equ (1 shl 16) |
||
287 | NV_TX_RETRYERROR equ (1 shl 19) |
||
288 | NV_TX_LASTPACKET1 equ (1 shl 24) |
||
289 | NV_TX_DEFERRED equ (1 shl 26) |
||
290 | NV_TX_CARRIERLOST equ (1 shl 27) |
||
291 | NV_TX_LATECOLLISION equ (1 shl 28) |
||
292 | NV_TX_UNDERFLOW equ (1 shl 29) |
||
293 | NV_TX_ERROR equ (1 shl 30) |
||
294 | NV_TX_VALID equ (1 shl 31) |
||
295 | |||
296 | NV_TX2_LASTPACKET equ (1 shl 29) |
||
297 | NV_TX2_RETRYERROR equ (1 shl 18) |
||
298 | NV_TX2_LASTPACKET1 equ (1 shl 23) |
||
299 | NV_TX2_DEFERRED equ (1 shl 25) |
||
300 | NV_TX2_CARRIERLOST equ (1 shl 26) |
||
301 | NV_TX2_LATECOLLISION equ (1 shl 27) |
||
302 | NV_TX2_UNDERFLOW equ (1 shl 28) |
||
303 | ; error and valid are the same for both |
||
304 | NV_TX2_ERROR equ (1 shl 30) |
||
305 | NV_TX2_VALID equ (1 shl 31) |
||
306 | |||
307 | NV_RX_DESCRIPTORVALID equ (1 shl 16) |
||
308 | NV_RX_AVAIL equ (1 shl 31) |
||
309 | |||
310 | NV_RX2_DESCRIPTORVALID equ (1 shl 29) |
||
311 | |||
312 | RX_RING equ 4 |
||
313 | TX_RING equ 2 |
||
314 | |||
315 | FLAG_MASK_V1 equ 0xffff0000 |
||
316 | FLAG_MASK_V2 equ 0xffffc000 |
||
317 | LEN_MASK_V1 equ (0xffffffff xor FLAG_MASK_V1) |
||
318 | LEN_MASK_V2 equ (0xffffffff xor FLAG_MASK_V2) |
||
319 | |||
320 | ; Miscelaneous hardware related defines: |
||
321 | NV_PCI_REGSZ_VER1 equ 0x270 |
||
322 | NV_PCI_REGSZ_VER2 equ 0x604 |
||
323 | ; various timeout delays: all in usec |
||
324 | NV_TXRX_RESET_DELAY equ 4 |
||
325 | NV_TXSTOP_DELAY1 equ 10 |
||
326 | NV_TXSTOP_DELAY1MAX equ 500000 |
||
327 | NV_TXSTOP_DELAY2 equ 100 |
||
328 | NV_RXSTOP_DELAY1 equ 10 |
||
329 | NV_RXSTOP_DELAY1MAX equ 500000 |
||
330 | NV_RXSTOP_DELAY2 equ 100 |
||
331 | NV_SETUP5_DELAY equ 5 |
||
332 | NV_SETUP5_DELAYMAX equ 50000 |
||
333 | NV_POWERUP_DELAY equ 5 |
||
334 | NV_POWERUP_DELAYMAX equ 5000 |
||
335 | NV_MIIBUSY_DELAY equ 50 |
||
336 | NV_MIIPHY_DELAY equ 10 |
||
337 | NV_MIIPHY_DELAYMAX equ 10000 |
||
338 | NV_MAC_RESET_DELAY equ 64 |
||
339 | NV_WAKEUPPATTERNS equ 5 |
||
340 | NV_WAKEUPMASKENTRIES equ 4 |
||
341 | |||
342 | ; Advertisement control register. |
||
343 | ADVERTISE_SLCT equ 0x001f ; Selector bits |
||
344 | ADVERTISE_CSMA equ 0x0001 ; Only selector supported |
||
345 | ADVERTISE_10HALF equ 0x0020 ; Try for 10mbps half-duplex |
||
346 | ADVERTISE_10FULL equ 0x0040 ; Try for 10mbps full-duplex |
||
347 | ADVERTISE_100HALF equ 0x0080 ; Try for 100mbps half-duplex |
||
348 | ADVERTISE_100FULL equ 0x0100 ; Try for 100mbps full-duplex |
||
349 | ADVERTISE_100BASE4 equ 0x0200 ; Try for 100mbps 4k packets |
||
350 | ADVERTISE_RESV equ 0x1c00 ; Unused... |
||
351 | ADVERTISE_RFAULT equ 0x2000 ; Say we can detect faults |
||
352 | ADVERTISE_LPACK equ 0x4000 ; Ack link partners response |
||
353 | ADVERTISE_NPAGE equ 0x8000 ; Next page bit |
||
354 | |||
355 | ADVERTISE_FULL equ (ADVERTISE_100FULL or ADVERTISE_10FULL or ADVERTISE_CSMA) |
||
356 | ADVERTISE_ALL equ (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL) |
||
357 | |||
358 | MII_1000BT_CR equ 0x09 |
||
359 | MII_1000BT_SR equ 0x0a |
||
360 | ADVERTISE_1000FULL equ 0x0200 |
||
361 | ADVERTISE_1000HALF equ 0x0100 |
||
362 | |||
363 | BMCR_ANRESTART equ 0x0200 ; Auto negotiation restart |
||
364 | BMCR_ANENABLE equ 0x1000 ; Enable auto negotiation |
||
365 | BMCR_SPEED100 equ 0x2000 ; Select 100Mbps |
||
366 | BMCR_LOOPBACK equ 0x4000 ; TXD loopback bits |
||
367 | BMCR_RESET equ 0x8000 ; Reset the DP83840 |
||
368 | |||
369 | ; Basic mode status register. |
||
370 | BMSR_ERCAP equ 0x0001 ; Ext-reg capability |
||
371 | BMSR_JCD equ 0x0002 ; Jabber detected |
||
372 | BMSR_LSTATUS equ 0x0004 ; Link status |
||
373 | BMSR_ANEGCAPABLE equ 0x0008 ; Able to do auto-negotiation |
||
374 | BMSR_RFAULT equ 0x0010 ; Remote fault detected |
||
375 | BMSR_ANEGCOMPLETE equ 0x0020 ; Auto-negotiation complete |
||
376 | BMSR_RESV equ 0x07c0 ; Unused... |
||
377 | BMSR_10HALF equ 0x0800 ; Can do 10mbps, half-duplex |
||
378 | BMSR_10FULL equ 0x1000 ; Can do 10mbps, full-duplex |
||
379 | BMSR_100HALF equ 0x2000 ; Can do 100mbps, half-duplex |
||
380 | BMSR_100FULL equ 0x4000 ; Can do 100mbps, full-duplex |
||
381 | BMSR_100BASE4 equ 0x8000 ; Can do 100mbps, 4k packets |
||
382 | |||
383 | ETH_ALEN equ 6 |
||
384 | ETH_HLEN equ (2 * ETH_ALEN + 2) |
||
385 | ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
||
386 | ; mininmum 64bytes frame length |
||
387 | |||
388 | uglobal |
||
389 | forcedeth_mmio_addr dd 0 ; memory map physical address |
||
390 | forcedeth_mmio_size dd 0 ; size of memory bar |
||
391 | forcedeth_vendor_id dw 0 ; Vendor ID |
||
392 | forcedeth_device_id dw 0 ; Device ID |
||
393 | forcedeth_orig_mac0 dd 0 ; MAC |
||
394 | forcedeth_orig_mac1 dd 0 ; MAC |
||
395 | forcedeth_mapio_addr dd 0 ; mapped IO address |
||
396 | forcedeth_txflags dd 0 ; |
||
397 | forcedeth_desc_ver dd 0 ; |
||
398 | forcedeth_irqmask dd 0 ; IRQ-mask |
||
399 | forcedeth_wolenabled dd 0 ; WOL |
||
400 | forcedeth_in_shutdown dd 0 ; |
||
401 | forcedeth_cur_rx dd 0 ; |
||
402 | forcedeth_refill_rx dd 0 ; |
||
403 | forcedeth_phyaddr dd 0 ; |
||
404 | forcedeth_phy_oui dd 0 ; |
||
405 | forcedeth_gigabit dd 0 ; |
||
406 | forcedeth_needs_mac_reset dd 0 ; |
||
407 | forcedeth_linkspeed dd 0 ; |
||
408 | forcedeth_duplex dd 0 ; |
||
409 | forcedeth_next_tx dd 0 ; next TX descriptor number |
||
410 | forcedeth_nic_tx dd 0 ; ??? d'nt used ??? |
||
411 | forcedeth_packetlen dd 0 ; |
||
412 | forcedeth_nocable dd 0 ; no cable present |
||
413 | endg |
||
414 | |||
415 | struc forcedeth_TxDesc { |
||
416 | .PacketBuffer dd ? |
||
417 | .FlagLen dd ? |
||
418 | } |
||
419 | virtual at 0 |
||
420 | forcedeth_TxDesc forcedeth_TxDesc |
||
421 | sizeof.forcedeth_TxDesc = $ - forcedeth_TxDesc |
||
422 | end virtual |
||
423 | |||
424 | struc forcedeth_RxDesc { |
||
425 | .PacketBuffer dd ? |
||
426 | .FlagLen dd ? |
||
427 | } |
||
428 | virtual at 0 |
||
429 | forcedeth_RxDesc forcedeth_RxDesc |
||
430 | sizeof.forcedeth_RxDesc = $ - forcedeth_RxDesc |
||
431 | end virtual |
||
432 | |||
433 | virtual at eth_data_start |
||
434 | ; Define the TX Descriptor |
||
435 | align 256 |
||
436 | forcedeth_tx_ring rb TX_RING * sizeof.forcedeth_TxDesc |
||
437 | ; Create a static buffer of size RX_BUF_SZ for each |
||
438 | ; TX Descriptor. All descriptors point to a |
||
439 | ; part of this buffer |
||
440 | align 256 |
||
441 | forcedeth_txb rb TX_RING * RX_NIC_BUFSIZE |
||
442 | |||
443 | ; Define the RX Descriptor |
||
444 | align 256 |
||
445 | forcedeth_rx_ring rb RX_RING * sizeof.forcedeth_RxDesc |
||
446 | ; Create a static buffer of size RX_BUF_SZ for each |
||
447 | ; RX Descriptor. All descriptors point to a |
||
448 | ; part of this buffer |
||
449 | align 256 |
||
450 | forcedeth_rxb rb RX_RING * RX_NIC_BUFSIZE |
||
451 | end virtual |
||
452 | |||
453 | |||
454 | ;*************************************************************************** |
||
455 | ; Function |
||
456 | ; forcedeth_reset |
||
457 | ; Description |
||
458 | ; Place the chip (ie, the ethernet card) into a virgin state |
||
459 | ; No inputs |
||
460 | ; All registers destroyed |
||
461 | ; |
||
462 | ;*************************************************************************** |
||
463 | forcedeth_reset: |
||
464 | |||
465 | ; 1) erase previous misconfiguration |
||
466 | ; 4.1-1: stop adapter: ignored, 4.3 seems to be overkill |
||
467 | |||
468 | ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) |
||
469 | mov edi, dword [forcedeth_mapio_addr] |
||
470 | mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
||
471 | |||
472 | ; writel(0, base + NvRegMulticastAddrB) |
||
473 | mov dword [edi+NvRegMulticastAddrB], 0 |
||
474 | |||
475 | ; writel(0, base + NvRegMulticastMaskA) |
||
476 | mov dword [edi+NvRegMulticastMaskA], 0 |
||
477 | |||
478 | ; writel(0, base + NvRegMulticastMaskB) |
||
479 | mov dword [edi+NvRegMulticastMaskB], 0 |
||
480 | |||
481 | ; writel(0, base + NvRegPacketFilterFlags) |
||
482 | mov dword [edi+NvRegPacketFilterFlags], 0 |
||
483 | |||
484 | ; writel(0, base + NvRegTransmitterControl) |
||
485 | mov dword [edi+NvRegTransmitterControl], 0 |
||
486 | |||
487 | ; writel(0, base + NvRegReceiverControl) |
||
488 | mov dword [edi+NvRegReceiverControl], 0 |
||
489 | |||
490 | ; writel(0, base + NvRegAdapterControl) |
||
491 | mov dword [edi+NvRegAdapterControl], 0 |
||
492 | |||
493 | |||
494 | ; 2) initialize descriptor rings |
||
495 | ; init_ring(nic) |
||
496 | call forcedeth_init_ring |
||
497 | |||
498 | ; writel(0, base + NvRegLinkSpeed) |
||
499 | mov dword [edi+NvRegLinkSpeed], 0 |
||
500 | |||
501 | ; writel(0, base + NvRegUnknownTransmitterReg) |
||
502 | mov dword [edi+NvRegUnknownTransmitterReg], 0 |
||
503 | |||
504 | ; txrx_reset(nic) |
||
505 | call forcedeth_txrx_reset |
||
506 | |||
507 | ; writel(0, base + NvRegUnknownSetupReg6) |
||
508 | mov dword [edi+NvRegUnknownSetupReg6], 0 |
||
509 | |||
510 | ; np->in_shutdown = 0 |
||
511 | mov dword [forcedeth_in_shutdown], 0 |
||
512 | |||
513 | |||
514 | ; 3) set mac address |
||
515 | ; writel(mac[0], base + NvRegMacAddrA) |
||
516 | mov eax, dword [forcedeth_orig_mac0] |
||
517 | mov dword [edi+NvRegMacAddrA], eax |
||
518 | |||
519 | ; writel(mac[1], base + NvRegMacAddrB) |
||
520 | mov eax, dword [forcedeth_orig_mac1] |
||
521 | mov dword [edi+NvRegMacAddrB], eax |
||
522 | |||
523 | |||
524 | ; 4) give hw rings |
||
525 | ; writel((u32) virt_to_le32desc(&rx_ring[0]), base + NvRegRxRingPhysAddr) |
||
526 | mov eax, forcedeth_rx_ring |
||
527 | |||
528 | ;DEBUGF 1," K : FORCEDETH: rx_ring at 0x%x\n", eax |
||
529 | |||
530 | sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
531 | mov dword [edi+NvRegRxRingPhysAddr], eax |
||
532 | |||
533 | ; writel((u32) virt_to_le32desc(&tx_ring[0]), base + NvRegTxRingPhysAddr) |
||
534 | mov eax, forcedeth_tx_ring |
||
535 | sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
536 | mov dword [edi+NvRegTxRingPhysAddr], eax |
||
537 | |||
538 | ; writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes) |
||
539 | mov dword [edi+NvRegRingSizes], (((RX_RING - 1) shl NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) shl NVREG_RINGSZ_TXSHIFT)) |
||
540 | |||
541 | ; 5) continue setup |
||
542 | ; np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
543 | mov dword [forcedeth_linkspeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
544 | |||
545 | ; np->duplex = 0 |
||
546 | mov dword [forcedeth_duplex], 0 |
||
547 | |||
548 | ; writel(np->linkspeed, base + NvRegLinkSpeed) |
||
549 | mov dword [edi+NvRegLinkSpeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
550 | |||
551 | ; writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3) |
||
552 | mov dword [edi+NvRegUnknownSetupReg3], NVREG_UNKSETUP3_VAL1 |
||
553 | |||
554 | ; writel(np->desc_ver, base + NvRegTxRxControl) |
||
555 | mov eax, dword [forcedeth_desc_ver] |
||
556 | mov dword [edi+NvRegTxRxControl], eax |
||
557 | |||
558 | ; pci_push(base) |
||
559 | call forcedeth_pci_push |
||
560 | |||
561 | ; writel(NVREG_TXRXCTL_BIT1 | np->desc_ver, base + NvRegTxRxControl) |
||
562 | or eax, NVREG_TXRXCTL_BIT1 |
||
563 | mov dword [edi+NvRegTxRxControl], eax |
||
564 | |||
565 | ; reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, "open: SetupReg5, Bit 31 remained off\n") |
||
566 | push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
||
567 | stdcall forcedeth_reg_delay, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, 0 |
||
568 | pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
||
569 | |||
570 | ; writel(0, base + NvRegUnknownSetupReg4) |
||
571 | mov dword [edi+NvRegUnknownSetupReg4], 0 |
||
572 | |||
573 | ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) |
||
574 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 |
||
575 | |||
576 | |||
577 | ; printf("%d-Mbs Link, %s-Duplex\n", np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100, np->duplex ? "Full" : "Half") |
||
578 | ;;;;;;;;;;; DEBUGF |
||
579 | |||
580 | ; 6) continue setup |
||
581 | |||
582 | ; writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1) |
||
583 | mov dword [edi+NvRegMisc1], (NVREG_MISC1_FORCE or NVREG_MISC1_HD) |
||
584 | |||
585 | ; writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus) |
||
586 | mov eax, dword [edi+NvRegTransmitterStatus] |
||
587 | mov dword [edi+NvRegTransmitterStatus], eax |
||
588 | |||
589 | ; writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags) |
||
590 | mov dword [edi+NvRegPacketFilterFlags], NVREG_PFF_ALWAYS |
||
591 | |||
592 | ; writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig) |
||
593 | mov dword [edi+NvRegOffloadConfig], NVREG_OFFLOAD_NORMAL |
||
594 | |||
595 | ; writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus) |
||
596 | mov eax, dword [edi+NvRegReceiverStatus] |
||
597 | mov dword [edi+NvRegReceiverStatus], eax |
||
598 | |||
599 | ; Get a random number |
||
600 | ; i = random() |
||
601 | push edi |
||
602 | stdcall sys_clock ; eax = 0x00SSMMHH (current system time) |
||
603 | pop edi |
||
604 | |||
605 | ; writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK), base + NvRegRandomSeed) |
||
606 | and eax, NVREG_RNDSEED_MASK |
||
607 | or eax, NVREG_RNDSEED_FORCE |
||
608 | mov dword [edi+NvRegRandomSeed], eax |
||
609 | |||
610 | ; writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1) |
||
611 | mov dword [edi+NvRegUnknownSetupReg1], NVREG_UNKSETUP1_VAL |
||
612 | |||
613 | ; writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2) |
||
614 | mov dword [edi+NvRegUnknownSetupReg2], NVREG_UNKSETUP2_VAL |
||
615 | |||
616 | ; writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval) |
||
617 | mov dword [edi+NvRegPollingInterval], NVREG_POLL_DEFAULT |
||
618 | |||
619 | ; writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6) |
||
620 | mov dword [edi+NvRegUnknownSetupReg6], NVREG_UNKSETUP6_VAL |
||
621 | |||
622 | ; writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT) | NVREG_ADAPTCTL_PHYVALID | NVREG_ADAPTCTL_RUNNING, |
||
623 | ; base + NvRegAdapterControl) |
||
624 | mov eax, dword [forcedeth_phyaddr] |
||
625 | shl eax, NVREG_ADAPTCTL_PHYSHIFT |
||
626 | or eax, (NVREG_ADAPTCTL_PHYVALID or NVREG_ADAPTCTL_RUNNING) |
||
627 | mov dword [edi+NvRegAdapterControl], eax |
||
628 | |||
629 | ; writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed) |
||
630 | mov dword [edi+NvRegMIISpeed], (NVREG_MIISPEED_BIT8 or NVREG_MIIDELAY) |
||
631 | |||
632 | ; writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4) |
||
633 | mov dword [edi+NvRegUnknownSetupReg4], NVREG_UNKSETUP4_VAL |
||
634 | |||
635 | ; writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags) |
||
636 | mov dword [edi+NvRegWakeUpFlags], NVREG_WAKEUPFLAGS_VAL |
||
637 | |||
638 | ; i = readl(base + NvRegPowerState) |
||
639 | mov eax, dword [edi+NvRegPowerState] |
||
640 | |||
641 | ; if ((i & NVREG_POWERSTATE_POWEREDUP) == 0) |
||
642 | test eax, NVREG_POWERSTATE_POWEREDUP |
||
643 | jnz @f |
||
644 | ; writel(NVREG_POWERSTATE_POWEREDUP | i, base + NvRegPowerState) |
||
645 | or eax, NVREG_POWERSTATE_POWEREDUP |
||
646 | mov dword [edi+NvRegPowerState], eax |
||
647 | |||
648 | @@: |
||
649 | |||
650 | ; pci_push(base) |
||
651 | call forcedeth_pci_push |
||
652 | |||
653 | ; nv_udelay(10) |
||
654 | mov esi, 10 |
||
655 | call forcedeth_nv_udelay |
||
656 | |||
657 | ; writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState) |
||
658 | mov eax, dword [edi+NvRegPowerState] |
||
659 | or eax, NVREG_POWERSTATE_VALID |
||
660 | mov dword [edi+NvRegPowerState], eax |
||
661 | |||
662 | ; ??? disable all interrupts ??? |
||
663 | ; writel(0, base + NvRegIrqMask) |
||
664 | mov dword [edi+NvRegIrqMask], 0 |
||
665 | |||
666 | ;;; ; ??? Mask RX interrupts |
||
667 | ;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_RX_ALL |
||
668 | ;;; ; ??? Mask TX interrupts |
||
669 | ;;; ;mov dword [edi+NvRegIrqMask], NVREG_IRQ_TX_ALL |
||
670 | ;;; ; ??? Mask OTHER interrupts |
||
671 | ;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_OTHER_ALL |
||
672 | |||
673 | ; pci_push(base) |
||
674 | call forcedeth_pci_push |
||
675 | |||
676 | ; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus) |
||
677 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2 |
||
678 | |||
679 | ; writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus) |
||
680 | mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK |
||
681 | |||
682 | ; pci_push(base) |
||
683 | call forcedeth_pci_push |
||
684 | |||
685 | |||
686 | ; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA) |
||
687 | mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
||
688 | |||
689 | ; writel(0, base + NvRegMulticastAddrB) |
||
690 | mov dword [edi+NvRegMulticastAddrB], 0 |
||
691 | |||
692 | ; writel(0, base + NvRegMulticastMaskA) |
||
693 | mov dword [edi+NvRegMulticastMaskA], 0 |
||
694 | |||
695 | ; writel(0, base + NvRegMulticastMaskB) |
||
696 | mov dword [edi+NvRegMulticastMaskB], 0 |
||
697 | |||
698 | ; writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags) |
||
699 | mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_ALWAYS or NVREG_PFF_MYADDR) |
||
700 | |||
701 | ; set_multicast(nic) |
||
702 | call forcedeth_set_multicast |
||
703 | |||
704 | ; One manual link speed update: Interrupts are enabled, future link |
||
705 | ; speed changes cause interrupts and are handled by nv_link_irq(). |
||
706 | |||
707 | ; miistat = readl(base + NvRegMIIStatus) |
||
708 | mov eax, dword [edi+NvRegMIIStatus] |
||
709 | |||
710 | ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
||
711 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK |
||
712 | |||
713 | ; dprintf(("startup: got 0x%hX.\n", miistat)); |
||
714 | ;;; DEBUGF 1," K : FORCEDETH: startup: got 0x%x\n", eax |
||
715 | |||
716 | |||
717 | ; ret = update_linkspeed(nic) |
||
718 | call forcedeth_update_linkspeed |
||
719 | push eax |
||
720 | |||
721 | ; start_tx(nic) |
||
722 | call forcedeth_start_tx |
||
723 | |||
724 | pop eax |
||
725 | |||
726 | ; if (ret) { |
||
727 | ; //Start Connection netif_carrier_on(dev); |
||
728 | ; } else { |
||
729 | ; printf("no link during initialization.\n"); |
||
730 | ; } |
||
731 | |||
732 | ;*** added by shurf (21.09.2008) |
||
733 | mov dword [forcedeth_nocable], 0 |
||
734 | ;*** |
||
735 | |||
736 | test eax, eax |
||
737 | jnz .return |
||
738 | DEBUGF 1," K : FORCEDETH: no link during initialization.\n" |
||
739 | |||
740 | ;*** added by shurf (21.09.2008) |
||
741 | mov dword [forcedeth_nocable], 1 |
||
742 | ;*** |
||
743 | |||
744 | .return: |
||
745 | |||
746 | ; Indicate that we have successfully reset the card |
||
747 | mov eax, dword [pci_data] |
||
748 | mov dword [eth_status], eax |
||
749 | ret |
||
750 | |||
751 | |||
752 | |||
753 | ;*************************************************************************** |
||
754 | ; Function |
||
755 | ; forcedeth_probe |
||
756 | ; Description |
||
757 | ; Searches for an ethernet card, enables it and clears the rx buffer |
||
758 | ; If a card was found, it enables the ethernet -> TCPIP link |
||
759 | ; |
||
760 | ;*************************************************************************** |
||
761 | forcedeth_probe: |
||
762 | |||
763 | ; DEBUGF 1," K : FORCEDETH: 0x%x 0x%x, 0x%x\n", [io_addr]:8,[pci_bus]:2,[pci_dev]:2 |
||
764 | |||
765 | mov dword [forcedeth_needs_mac_reset], 0 |
||
766 | |||
767 | ; BEGIN of adjust_pci_device() |
||
768 | ; read word from PCI-device |
||
769 | mov al, 1 ;;;;;;;;;;;;;;2 |
||
770 | mov bh, [pci_dev] |
||
771 | mov ah, [pci_bus] |
||
772 | mov bl, PCI_REG_COMMAND |
||
773 | call pci_read_reg |
||
774 | mov bx, ax ; new command |
||
775 | or bx, PCI_COMMAND_MASTER |
||
776 | or bx, PCI_COMMAND_IO |
||
777 | cmp bx, ax |
||
778 | je @f |
||
779 | ; Enabling PCI-device (make card as bus master) |
||
780 | DEBUGF 1," K : FORCEDETH: Updating PCI command 0x%x->0x%x\n", ax, bx |
||
781 | mov cx, bx |
||
782 | mov al, 1 ;;;;;;;;;;;;2 |
||
783 | mov bh, [pci_dev] |
||
784 | mov ah, [pci_bus] |
||
785 | mov bl, PCI_REG_COMMAND |
||
786 | call pci_write_reg |
||
787 | |||
788 | ; Check latency settings |
||
789 | @@: |
||
790 | ; Get current latency settings from Latency timer register (byte) |
||
791 | mov al, 0 ;;;;;;;;;1 |
||
792 | mov bh, [pci_dev] |
||
793 | mov ah, [pci_bus] |
||
794 | mov bl, PCI_LATENCY_TIMER |
||
795 | call pci_read_reg |
||
796 | |||
797 | ; see if its at least 32 |
||
798 | cmp al, 32 |
||
799 | jge @f |
||
800 | ; set latency to 32 |
||
801 | DEBUGF 1, "K : FORCEDETH: PCI latency timer (CFLT) is unreasonably low at %d.\n", al |
||
802 | DEBUGF 1, "K : FORCEDETH: Setting to 32 clocks.\n" |
||
803 | mov cl, 32 |
||
804 | mov al, 0 ;;;;;;;1 |
||
805 | mov bh, [pci_dev] |
||
806 | mov ah, [pci_bus] |
||
807 | mov bl, PCI_LATENCY_TIMER |
||
808 | call pci_write_reg |
||
809 | ; END of adjust_pci_device() |
||
810 | |||
811 | @@: |
||
812 | ; BEGIN of pci_bar_start (addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0)) |
||
813 | mov al, 2 ; dword |
||
814 | mov bh, [pci_dev] |
||
815 | mov ah, [pci_bus] |
||
816 | mov bl, PCI_BASE_ADDRESS_0 |
||
817 | call pci_read_reg |
||
818 | test eax, PCI_BASE_ADDRESS_SPACE_IO |
||
819 | jz @f |
||
820 | and eax, PCI_BASE_ADDRESS_IO_MASK |
||
821 | jmp .next |
||
822 | @@: |
||
823 | push eax |
||
824 | and eax, PCI_BASE_ADDRESS_MEM_TYPE_MASK |
||
825 | cmp eax, PCI_BASE_ADDRESS_MEM_TYPE_64 |
||
826 | jne .not64 |
||
827 | mov al, 2 ; dword |
||
828 | mov bh, [pci_dev] |
||
829 | mov ah, [pci_bus] |
||
830 | mov bl, PCI_BASE_ADDRESS_0 + 4 |
||
831 | call pci_read_reg |
||
832 | or eax, eax |
||
833 | jz .not64 |
||
834 | DEBUGF 1,"K : FORCEDETH: pci_bar_start: Unhandled 64bit BAR\n" |
||
835 | or eax, -1 |
||
836 | jmp .next |
||
837 | .not64: |
||
838 | pop eax |
||
839 | and eax, PCI_BASE_ADDRESS_MEM_MASK |
||
840 | .next: |
||
841 | ; END of pci_bar_start |
||
842 | ; addr = eax |
||
843 | mov dword [forcedeth_mmio_addr], eax |
||
844 | |||
845 | |||
846 | ; BEGIN of pci_bar_size (sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0)) |
||
847 | |||
848 | ; Save original bar |
||
849 | mov al, 2 ; dword |
||
850 | mov bh, [pci_dev] |
||
851 | mov ah, [pci_bus] |
||
852 | mov bl, PCI_BASE_ADDRESS_0 |
||
853 | call pci_read_reg |
||
854 | mov dword [forcedeth_tmp_start], eax |
||
855 | ; Compute which bits can be set |
||
856 | ; (ecx - value to write) |
||
857 | mov al, 2 ; dword |
||
858 | mov bh, [pci_dev] |
||
859 | mov ah, [pci_bus] |
||
860 | mov bl, PCI_BASE_ADDRESS_0 |
||
861 | mov ecx, (not 0) |
||
862 | call pci_write_reg |
||
863 | mov al, 2 ; dword |
||
864 | mov bh, [pci_dev] |
||
865 | mov ah, [pci_bus] |
||
866 | mov bl, PCI_BASE_ADDRESS_0 |
||
867 | call pci_read_reg |
||
868 | push eax |
||
869 | ; Restore the original size |
||
870 | mov al, 2 ; dword |
||
871 | mov bh, [pci_dev] |
||
872 | mov ah, [pci_bus] |
||
873 | mov bl, PCI_BASE_ADDRESS_0 |
||
874 | mov ecx, dword [forcedeth_tmp_start] |
||
875 | call pci_write_reg |
||
876 | ; Find the significant bits |
||
877 | pop eax |
||
878 | test dword [forcedeth_tmp_start], PCI_BASE_ADDRESS_SPACE_IO |
||
879 | jz @f |
||
880 | and eax, PCI_BASE_ADDRESS_IO_MASK |
||
881 | jmp .next2 |
||
882 | @@: |
||
883 | and eax, PCI_BASE_ADDRESS_MEM_MASK |
||
884 | .next2: |
||
885 | ; Find the lowest bit set |
||
886 | mov ecx, eax |
||
887 | sub eax, 1 |
||
888 | not eax |
||
889 | and ecx, eax |
||
890 | |||
891 | ; END of pci_bar_start |
||
892 | mov dword [forcedeth_mmio_size], ecx |
||
893 | |||
894 | DEBUGF 1," K : FORCEDETH: mmio_addr= 0x%x [mmio_size= 0x%x]\n", [forcedeth_mmio_addr]:8, [forcedeth_mmio_size]:8 |
||
895 | |||
896 | ; Get Vendor and Device ID |
||
897 | mov al, 2 |
||
898 | mov bh, [pci_dev] |
||
899 | mov ah, [pci_bus] |
||
900 | mov bl, PCI_VENDOR_ID |
||
901 | call pci_read_reg |
||
902 | mov word [forcedeth_vendor_id], ax |
||
903 | shr eax, 16 |
||
904 | mov word [forcedeth_device_id], ax |
||
905 | |||
906 | DEBUGF 1," K : FORCEDETH: vendor_id= 0x%x device_id= 0x%x\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 |
||
907 | |||
908 | ; handle different descriptor versions |
||
909 | mov eax, dword [forcedeth_device_id] |
||
910 | cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_1 |
||
911 | je .ver1 |
||
912 | cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_2 |
||
913 | je .ver1 |
||
914 | cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_3 |
||
915 | je .ver1 |
||
916 | mov dword [forcedeth_desc_ver], DESC_VER_2 |
||
917 | jmp @f |
||
918 | .ver1: |
||
919 | mov dword [forcedeth_desc_ver], DESC_VER_1 |
||
920 | @@: |
||
921 | ; read the mac address |
||
922 | ; map memory |
||
923 | stdcall map_io_mem, [forcedeth_mmio_addr], [forcedeth_mmio_size], (PG_SW+PG_NOCACHE) |
||
924 | test eax, eax |
||
925 | jz .fail |
||
926 | |||
927 | mov dword [forcedeth_mapio_addr], eax |
||
928 | mov edi, eax |
||
929 | mov eax, dword [edi+NvRegMacAddrA] |
||
930 | mov dword [forcedeth_orig_mac0], eax |
||
931 | mov edx, dword [edi+NvRegMacAddrB] |
||
932 | mov dword [forcedeth_orig_mac1], edx |
||
933 | |||
934 | ; save MAC-address to global variable node_addr |
||
935 | mov dword [node_addr], eax |
||
936 | mov word [node_addr+4], dx |
||
937 | |||
938 | ; reverse if desired |
||
939 | cmp word [forcedeth_device_id], 0x03E5 |
||
940 | jae .no_reverse_mac |
||
941 | mov al, byte [node_addr] |
||
942 | xchg al, byte [node_addr+5] |
||
943 | mov byte [node_addr], al |
||
944 | mov al, byte [node_addr+1] |
||
945 | xchg al, byte [node_addr+4] |
||
946 | mov byte [node_addr+4], al |
||
947 | mov al, byte [node_addr+2] |
||
948 | xchg al, byte [node_addr+3] |
||
949 | mov byte [node_addr+3], al |
||
950 | .no_reverse_mac: |
||
951 | |||
952 | ; DEBUGF 1," K : FORCEDETH: orig_mac0= 0x%x\n", [forcedeth_orig_mac0]:8 |
||
953 | ; DEBUGF 1," K : FORCEDETH: orig_mac1= 0x%x\n", [forcedeth_orig_mac1]:8 |
||
954 | DEBUGF 1," K : FORCEDETH: MAC = %x-%x-%x-%x-%x-%x\n", [node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2, |
||
955 | |||
956 | ; disable WOL |
||
957 | mov edi, dword [forcedeth_mapio_addr] |
||
958 | mov dword [edi+NvRegWakeUpFlags], 0 |
||
959 | mov dword [forcedeth_wolenabled], 0 |
||
960 | |||
961 | mov dword [forcedeth_txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID) |
||
962 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
963 | jne @f |
||
964 | mov dword [forcedeth_txflags], (NV_TX_LASTPACKET or NV_TX_VALID) |
||
965 | @@: |
||
966 | |||
967 | ; BEGIN of switch (pci->dev_id) |
||
968 | |||
969 | cmp word [forcedeth_device_id], 0x01C3 |
||
970 | jne .next_0x0066 |
||
971 | ; nforce |
||
972 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
973 | jmp .end_switch |
||
974 | |||
975 | .next_0x0066: |
||
976 | cmp word [forcedeth_device_id], 0x0066 |
||
977 | je @f |
||
978 | cmp word [forcedeth_device_id], 0x00D6 |
||
979 | je @f |
||
980 | jmp .next_0x0086 |
||
981 | @@: |
||
982 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
983 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
984 | jne @f |
||
985 | or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
||
986 | jmp .end_switch |
||
987 | @@: |
||
988 | or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
||
989 | jmp .end_switch |
||
990 | |||
991 | .next_0x0086: |
||
992 | cmp word [forcedeth_device_id], 0x0086 |
||
993 | je @f |
||
994 | cmp word [forcedeth_device_id], 0x008c |
||
995 | je @f |
||
996 | cmp word [forcedeth_device_id], 0x00e6 |
||
997 | je @f |
||
998 | cmp word [forcedeth_device_id], 0x00df |
||
999 | je @f |
||
1000 | cmp word [forcedeth_device_id], 0x0056 |
||
1001 | je @f |
||
1002 | cmp word [forcedeth_device_id], 0x0057 |
||
1003 | je @f |
||
1004 | cmp word [forcedeth_device_id], 0x0037 |
||
1005 | je @f |
||
1006 | cmp word [forcedeth_device_id], 0x0038 |
||
1007 | je @f |
||
1008 | jmp .next_0x0268 |
||
1009 | @@: |
||
1010 | ; np->irqmask = NVREG_IRQMASK_WANTED_2; |
||
1011 | ; np->irqmask |= NVREG_IRQ_TIMER; |
||
1012 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
1013 | |||
1014 | ; if (np->desc_ver == DESC_VER_1) |
||
1015 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1016 | jne @f |
||
1017 | ; np->tx_flags |= NV_TX_LASTPACKET1; |
||
1018 | or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
||
1019 | jmp .end_switch |
||
1020 | ; else |
||
1021 | @@: |
||
1022 | ; np->tx_flags |= NV_TX2_LASTPACKET1; |
||
1023 | or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
||
1024 | |||
1025 | ; break; |
||
1026 | jmp .end_switch |
||
1027 | |||
1028 | .next_0x0268: |
||
1029 | ; cmp word [forcedeth_device_id], 0x0268 |
||
1030 | ; je @f |
||
1031 | ; cmp word [forcedeth_device_id], 0x0269 |
||
1032 | ; je @f |
||
1033 | ; cmp word [forcedeth_device_id], 0x0372 |
||
1034 | ; je @f |
||
1035 | ; cmp word [forcedeth_device_id], 0x0373 |
||
1036 | ; je @f |
||
1037 | ; jmp .default_switch |
||
1038 | ;@@: |
||
1039 | cmp word [forcedeth_device_id], 0x0268 |
||
1040 | jb .default_switch |
||
1041 | ; pci_read_config_byte(pci, PCI_REVISION_ID, &revision_id); |
||
1042 | mov al, 0 ; byte |
||
1043 | mov bh, [pci_dev] |
||
1044 | mov ah, [pci_bus] |
||
1045 | mov bl, PCI_REVISION_ID |
||
1046 | call pci_read_reg |
||
1047 | mov ecx, eax ; cl = revision_id |
||
1048 | |||
1049 | ; take phy and nic out of low power mode |
||
1050 | ; powerstate = readl(base + NvRegPowerState2); |
||
1051 | mov edi, dword [forcedeth_mapio_addr] |
||
1052 | mov eax, dword [edi+NvRegPowerState2] ; eax = powerstate |
||
1053 | |||
1054 | ; powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; |
||
1055 | and eax, not NVREG_POWERSTATE2_POWERUP_MASK |
||
1056 | |||
1057 | ; if ((pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_12||pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_13)&&revision_id>=0xA3) |
||
1058 | cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12 |
||
1059 | je @f |
||
1060 | cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13 |
||
1061 | je @f |
||
1062 | jmp .end_if |
||
1063 | @@: |
||
1064 | cmp cl, 0xA3 |
||
1065 | jl .end_if |
||
1066 | ; powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; |
||
1067 | or eax, NVREG_POWERSTATE2_POWERUP_REV_A3 |
||
1068 | |||
1069 | .end_if: |
||
1070 | |||
1071 | ; writel(powerstate, base + NvRegPowerState2); |
||
1072 | mov dword [edi+NvRegPowerState2], eax |
||
1073 | |||
1074 | ; //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ |
||
1075 | ; np->irqmask = NVREG_IRQMASK_WANTED_2; |
||
1076 | ; np->irqmask |= NVREG_IRQ_TIMER; |
||
1077 | mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER) |
||
1078 | |||
1079 | ; needs_mac_reset = 1; |
||
1080 | mov dword [forcedeth_needs_mac_reset], 1 |
||
1081 | |||
1082 | ; if (np->desc_ver == DESC_VER_1) |
||
1083 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1084 | jne @f |
||
1085 | ; np->tx_flags |= NV_TX_LASTPACKET1; |
||
1086 | or dword [forcedeth_txflags], NV_TX_LASTPACKET1 |
||
1087 | jmp .end_if2 |
||
1088 | @@: |
||
1089 | ; else |
||
1090 | ; np->tx_flags |= NV_TX2_LASTPACKET1; |
||
1091 | or dword [forcedeth_txflags], NV_TX2_LASTPACKET1 |
||
1092 | |||
1093 | .end_if2: |
||
1094 | ; break; |
||
1095 | jmp .end_switch |
||
1096 | |||
1097 | .default_switch: |
||
1098 | DEBUGF 1," K : FORCEDETH: Your card was undefined in this driver.\n" |
||
1099 | DEBUGF 1," K : FORCEDETH: Review driver_data in Kolibri driver and send a patch\n" |
||
1100 | |||
1101 | .end_switch: |
||
1102 | |||
1103 | ; END of switch (pci->dev_id) |
||
1104 | |||
1105 | |||
1106 | ; Find a suitable phy |
||
1107 | mov dword [forcedeth_tmp_i], 1 |
||
1108 | .for_loop: |
||
1109 | ; for (i = 1; i <= 32; i++) |
||
1110 | ; phyaddr = i & 0x1f |
||
1111 | mov ebx, dword [forcedeth_tmp_i] |
||
1112 | and ebx, 0x1f |
||
1113 | |||
1114 | ; id1 = mii_rw(phyaddr, MII_PHYSID1, MII_READ) |
||
1115 | ;EBX - addr, EAX - miireg, ECX - value |
||
1116 | mov eax, MII_PHYSID1 |
||
1117 | mov ecx, MII_READ |
||
1118 | call forcedeth_mii_rw ; id1 = eax |
||
1119 | |||
1120 | ; if (id1 < 0 || id1 == 0xffff) |
||
1121 | cmp eax, 0xffffffff |
||
1122 | je .continue_for |
||
1123 | test eax, 0x80000000 |
||
1124 | jnz .continue_for |
||
1125 | mov dword [forcedeth_tmp_id1], eax |
||
1126 | |||
1127 | ; id2 = mii_rw(nic, phyaddr, MII_PHYSID2, MII_READ) |
||
1128 | mov eax, MII_PHYSID2 |
||
1129 | mov ecx, MII_READ |
||
1130 | call forcedeth_mii_rw ; id2 = eax |
||
1131 | |||
1132 | ; if (id2 < 0 || id2 == 0xffff) |
||
1133 | cmp eax, 0xffffffff |
||
1134 | je .continue_for |
||
1135 | test eax, 0x80000000 |
||
1136 | jnz .continue_for |
||
1137 | mov dword [forcedeth_tmp_id2], eax |
||
1138 | |||
1139 | jmp .break_for |
||
1140 | .continue_for: |
||
1141 | inc dword [forcedeth_tmp_i] |
||
1142 | cmp dword [forcedeth_tmp_i], 32 |
||
1143 | jle .for_loop |
||
1144 | jmp .end_for |
||
1145 | |||
1146 | .break_for: |
||
1147 | |||
1148 | ;;;; DEBUGF 1," K : FORCEDETH: id1=0x%x id2=0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8 |
||
1149 | |||
1150 | ; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT |
||
1151 | mov eax, dword [forcedeth_tmp_id1] |
||
1152 | and eax, PHYID1_OUI_MASK |
||
1153 | shl eax, PHYID1_OUI_SHFT |
||
1154 | mov dword [forcedeth_tmp_id1], eax |
||
1155 | |||
1156 | ; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT |
||
1157 | mov eax, dword [forcedeth_tmp_id2] |
||
1158 | and eax, PHYID2_OUI_MASK |
||
1159 | shr eax, PHYID2_OUI_SHFT |
||
1160 | mov dword [forcedeth_tmp_id2], eax |
||
1161 | |||
1162 | DEBUGF 1," K : FORCEDETH: Found PHY 0x%x:0x%x at address 0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8, ebx |
||
1163 | |||
1164 | ; np->phyaddr = phyaddr; |
||
1165 | mov dword [forcedeth_phyaddr], ebx |
||
1166 | |||
1167 | ; np->phy_oui = id1 | id2; |
||
1168 | mov eax, dword [forcedeth_tmp_id1] |
||
1169 | or eax, dword [forcedeth_tmp_id2] |
||
1170 | mov dword [forcedeth_phy_oui], eax |
||
1171 | |||
1172 | .end_for: |
||
1173 | |||
1174 | ; if (i == 33) |
||
1175 | cmp dword [forcedeth_tmp_i], 33 |
||
1176 | jne @f |
||
1177 | ; PHY in isolate mode? No phy attached and user wants to |
||
1178 | ; test loopback? Very odd, but can be correct. |
||
1179 | |||
1180 | DEBUGF 1," K : FORCEDETH: Could not find a valid PHY.\n" |
||
1181 | |||
1182 | jmp .next3 |
||
1183 | |||
1184 | @@: |
||
1185 | |||
1186 | ; if (i != 33) |
||
1187 | ; reset it |
||
1188 | call forcedeth_phy_init |
||
1189 | |||
1190 | .next3: |
||
1191 | |||
1192 | ; dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n", |
||
1193 | ; pci->name, pci->vendor, pci->dev_id, pci->name)); |
||
1194 | DEBUGF 1," K : FORCEDETH: subsystem: 0x%x:0x%x bound to forcedeth\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4 |
||
1195 | |||
1196 | |||
1197 | ; if(needs_mac_reset) mac_reset(nic); |
||
1198 | cmp dword [forcedeth_needs_mac_reset], 0 |
||
1199 | je @f |
||
1200 | call forcedeth_mac_reset |
||
1201 | |||
1202 | @@: |
||
1203 | |||
1204 | ; if(!forcedeth_reset(nic)) return 0; // no valid link |
||
1205 | call forcedeth_reset |
||
1206 | test eax, eax |
||
1207 | jnz @f |
||
1208 | mov eax, 0 |
||
1209 | jmp .return |
||
1210 | |||
1211 | @@: |
||
1212 | |||
1213 | ; point to NIC specific routines |
||
1214 | ; dev->disable = forcedeth_disable; |
||
1215 | ; nic->poll = forcedeth_poll; |
||
1216 | ; nic->transmit = forcedeth_transmit; |
||
1217 | ; nic->irq = forcedeth_irq; |
||
1218 | ;;;;;;;;;stdcall attach_int_handler, 11, forcedeth_int_handler, 0 |
||
1219 | |||
1220 | ; return 1 |
||
1221 | mov eax, 1 |
||
1222 | jmp .return |
||
1223 | |||
1224 | .fail: |
||
1225 | mov eax, 0 |
||
1226 | |||
1227 | .return: |
||
1228 | ret |
||
1229 | |||
1230 | uglobal |
||
1231 | forcedeth_tmp_start dd ? |
||
1232 | forcedeth_tmp_reg dd ? |
||
1233 | forcedeth_tmp_i dd ? |
||
1234 | forcedeth_tmp_id1 dd ? |
||
1235 | forcedeth_tmp_id2 dd ? |
||
1236 | forcedeth_tmp_phyinterface dd ? |
||
1237 | forcedeth_tmp_newls dd ? |
||
1238 | forcedeth_tmp_newdup dd ? |
||
1239 | forcedeth_tmp_retval dd ? |
||
1240 | forcedeth_tmp_control_1000 dd ? |
||
1241 | forcedeth_tmp_lpa dd ? |
||
1242 | forcedeth_tmp_adv dd ? |
||
1243 | forcedeth_tmp_len dd ? |
||
1244 | forcedeth_tmp_valid dd ? |
||
1245 | forcedeth_tmp_nr dd ? |
||
1246 | forcedeth_tmp_ptxb dd ? |
||
1247 | endg |
||
1248 | |||
1249 | ;*************************************************************************** |
||
1250 | ; Function |
||
1251 | ; forcedeth_poll |
||
1252 | ; |
||
1253 | ; Description |
||
1254 | ; Polls the ethernet card for a received packet |
||
1255 | ; Received data, if any, ends up in Ether_buffer |
||
1256 | ; |
||
1257 | ;*************************************************************************** |
||
1258 | forcedeth_poll: |
||
1259 | |||
1260 | mov word [eth_rx_data_len], 0 |
||
1261 | |||
1262 | ; ???????????????????????????? |
||
1263 | ; ??? Clear events? ??? |
||
1264 | mov edi, dword [forcedeth_mapio_addr] |
||
1265 | mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK |
||
1266 | ; ???????????????????????????? |
||
1267 | |||
1268 | .top: |
||
1269 | |||
1270 | ; i = np->cur_rx % RX_RING |
||
1271 | mov eax, dword [forcedeth_cur_rx] |
||
1272 | and eax, (RX_RING-1) |
||
1273 | mov dword [forcedeth_tmp_i], eax |
||
1274 | |||
1275 | ; Flags = le32_to_cpu(rx_ring[i].FlagLen) |
||
1276 | ; Flags = rx_ring[i].FlagLen |
||
1277 | mov cl, sizeof.forcedeth_RxDesc |
||
1278 | mul cl |
||
1279 | add eax, forcedeth_rx_ring |
||
1280 | mov ebx, eax |
||
1281 | mov eax, [ebx + forcedeth_RxDesc.FlagLen] |
||
1282 | |||
1283 | |||
1284 | ; if (Flags & NV_RX_AVAIL) |
||
1285 | test eax, NV_RX_AVAIL |
||
1286 | ; return 0; /* still owned by hardware, */ |
||
1287 | ; still owned by hardware |
||
1288 | jnz .return0 |
||
1289 | |||
1290 | ;;;;; DEBUGF 1,"poll: FlagLen = %x\n", eax |
||
1291 | |||
1292 | ; if (np->desc_ver == DESC_VER_1) { |
||
1293 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1294 | jne @f |
||
1295 | ; if (!(Flags & NV_RX_DESCRIPTORVALID)) |
||
1296 | test eax, NV_RX_DESCRIPTORVALID |
||
1297 | ; return 0; |
||
1298 | jz .return0 |
||
1299 | jmp .next |
||
1300 | ; } else { |
||
1301 | @@: |
||
1302 | ; if (!(Flags & NV_RX2_DESCRIPTORVALID)) |
||
1303 | test eax, NV_RX2_DESCRIPTORVALID |
||
1304 | ; return 0; |
||
1305 | jz .return0 |
||
1306 | ; } |
||
1307 | |||
1308 | .next: |
||
1309 | |||
1310 | ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) |
||
1311 | ; len = rx_ring[i].FlagLen & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); |
||
1312 | ; eax = FlagLen |
||
1313 | cmp dword [forcedeth_desc_ver], DESC_VER_1 |
||
1314 | jne @f |
||
1315 | and eax, LEN_MASK_V1 |
||
1316 | jmp .next2 |
||
1317 | @@: |
||
1318 | and eax, LEN_MASK_V2 |
||
1319 | |||
1320 | .next2: |
||
1321 | |||
1322 | ; mov dword [forcedeth_tmp_len], eax |
||
1323 | |||
1324 | ; valid = 1 |
||
1325 | mov dword [forcedeth_tmp_valid], 1 |
||
1326 | |||
1327 | ; got a valid packet - forward it to the network core |
||
1328 | ; nic->packetlen = len; |
||
1329 | mov dword [forcedeth_packetlen], eax |
||
1330 | ; |
||
1331 | mov word [eth_rx_data_len], ax |
||
1332 | ;;;;;;;;; DEBUGF 1,"poll: packet len = 0x%x\n", [forcedeth_packetlen] |
||
1333 | |||
1334 | |||
1335 | ; memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen); |
||
1336 | ; Copy packet to system buffer (Ether_buffer) |
||
1337 | ;???? ecx = (len-4) |
||
1338 | mov ecx, eax |
||
1339 | push ecx |
||
1340 | shr ecx, 2 |
||
1341 | |||
1342 | ; rxb + (i * RX_NIC_BUFSIZE) |
||
1343 | mov eax, dword [forcedeth_tmp_i] |
||
1344 | mov bx, RX_NIC_BUFSIZE |
||
1345 | mul bx |
||
1346 | add eax, forcedeth_rxb |
||
1347 | |||
1348 | mov esi, eax |
||
1349 | mov edi, Ether_buffer |
||
1350 | cld ; set to increment |
||
1351 | rep movsd ; mov dword from [esi++] to [edi++] |
||
1352 | pop ecx |
||
1353 | and ecx, 3 ; copy rest 1-3 bytes |
||
1354 | rep movsb |
||
1355 | |||
1356 | ; wmb(); |
||
1357 | ; ??? |
||
1358 | |||
1359 | ; np->cur_rx++; |
||
1360 | inc dword [forcedeth_cur_rx] |
||
1361 | |||
1362 | ; if (!valid) |
||
1363 | cmp dword [forcedeth_tmp_valid], 0 |
||
1364 | jne @f |
||
1365 | ; goto top; |
||
1366 | jmp .top |
||
1367 | @@: |
||
1368 | ; alloc_rx(nic); |
||
1369 | call forcedeth_alloc_rx |
||
1370 | |||
1371 | ; return 1; |
||
1372 | jmp .return1 |
||
1373 | |||
1374 | ;;;;; DEBUGF 1,"K : FORCEDETH: poll: ...\n" |
||
1375 | |||
1376 | |||
1377 | .return0: |
||
1378 | mov eax, 0 |
||
1379 | jmp .return |
||
1380 | .return1: |
||
1381 | mov eax, 1 |
||
1382 | .return: |
||
1383 | ;;push eax |
||
1384 | |||
1385 | ; ???????????????????????????????????????????????? |
||
1386 | ; ????? clear interrupt mask/status |
||
1387 | ; read IRQ status |
||
1388 | ;;mov edi, dword [forcedeth_mapio_addr] |
||
1389 | ;;mov eax, dword [edi+NvRegIrqStatus] |
||
1390 | |||
1391 | ; clear events |
||
1392 | ;;and eax, not (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF or NVREG_IRQ_LINK or NVREG_IRQ_TIMER) |
||
1393 | |||
1394 | ; write IRQ status |
||
1395 | ;;mov dword [edi+NvRegIrqStatus], eax |
||
1396 | ; ???????????????????????????????????????????????? |
||
1397 | |||
1398 | ;;pop eax |
||
1399 | ret |
||
1400 | |||
1401 | |||
1402 | ;*************************************************************************** |
||
1403 | ; Function |
||
1404 | ; forcedeth_transmit |
||
1405 | ; |
||
1406 | ; Description |
||
1407 | ; Transmits a packet of data via the ethernet card |
||
1408 | ; Pointer to 48 bit destination address in edi |
||
1409 | ; Type of packet in bx |
||
1410 | ; size of packet in ecx |
||
1411 | ; pointer to packet data in esi |
||
1412 | ; |
||
1413 | ;*************************************************************************** |
||
1414 | forcedeth_transmit: |
||
1415 | |||
1416 | ; send the packet to destination |
||
1417 | ;pusha |
||
1418 | ;DEBUGF 1,"K : FORCEDETH: transmit: packet type = 0x%x\n", ebx |
||
1419 | ;DEBUGF 1,"K : FORCEDETH: transmit: packet len = 0x%x\n", ecx |
||
1420 | ;mov eax, dword [edi] |
||
1421 | ;DEBUGF 1,"K : FORCEDETH: transmit: dest adr = 0x%x\n", eax |
||
1422 | ;mov eax, dword [edi+4] |
||
1423 | ;DEBUGF 1,"K : FORCEDETH: transmit: dest adr2 = 0x%x\n", eax |
||
1424 | ;mov eax, dword [node_addr] |
||
1425 | ;DEBUGF 1,"K : FORCEDETH: transmit: src adr = 0x%x\n", eax |
||
1426 | ;mov eax, dword [node_addr+4] |
||
1427 | ;DEBUGF 1,"K : FORCEDETH: transmit: src adr2 = 0x%x\n", eax |
||
1428 | ;popa |
||
1429 | |||
1430 | ; int nr = np->next_tx % TX_RING |
||
1431 | mov eax, dword [forcedeth_next_tx] |
||
1432 | and eax, (TX_RING-1) |
||
1433 | mov dword [forcedeth_tmp_nr], eax |
||
1434 | |||
1435 | ; point to the current txb incase multiple tx_rings are used |
||
1436 | ; ptxb = txb + (nr * RX_NIC_BUFSIZE) |
||
1437 | push ecx |
||
1438 | mov cx, RX_NIC_BUFSIZE |
||
1439 | mul cx ; AX*CX, result to DX:AX |
||
1440 | add eax, forcedeth_txb |
||
1441 | mov dword [forcedeth_tmp_ptxb], eax |
||
1442 | push esi |
||
1443 | mov esi, edi ; dst MAC |
||
1444 | mov edi, eax ; packet buffer |
||
1445 | cld ; set to increment |
||
1446 | |||
1447 | ; copy the packet to ring buffer |
||
1448 | ; memcpy(ptxb, d, ETH_ALEN); /* dst */ |
||
1449 | movsd |
||
1450 | movsw |
||
1451 | |||
1452 | ; memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ |
||
1453 | mov esi, node_addr |
||
1454 | movsd |
||
1455 | movsw |
||
1456 | |||
1457 | ; nstype = htons((u16) t); /* type */ |
||
1458 | ; memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */ |
||
1459 | mov word [edi], bx |
||
1460 | add edi, 2 |
||
1461 | |||
1462 | ; memcpy(ptxb + ETH_HLEN, p, s); |
||
1463 | pop esi |
||
1464 | pop ecx |
||
1465 | push ecx |
||
1466 | shr ecx, 2 ; count in dwords |
||
1467 | rep movsd ; copy dwords from [esi+=4] to [edi+=4] |
||
1468 | pop ecx |
||
1469 | push ecx |
||
1470 | and ecx, 3 ; copy rest 1-3 bytes |
||
1471 | rep movsb ; copy bytess from [esi++] to [edi++] |
||
1472 | |||
1473 | |||
1474 | ; s += ETH_HLEN; |
||
1475 | ; while (s < ETH_ZLEN) /* pad to min length */ |
||
1476 | ; ptxb[s++] = '\0'; |
||
1477 | ; pad to min length |
||
1478 | pop ecx |
||
1479 | add ecx, ETH_HLEN |
||
1480 | push ecx ; header length + data length |
||
1481 | cmp ecx, ETH_ZLEN |
||
1482 | jge @f |
||
1483 | mov eax, ETH_ZLEN |
||
1484 | sub eax, ecx |
||
1485 | xchg eax, ecx |
||
1486 | mov al, 0 |
||
1487 | rep stosb ; copy byte from al to [edi++] |
||
1488 | |||
1489 | @@: |
||
1490 | |||
1491 | ; tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb); |
||
1492 | mov eax, dword [forcedeth_tmp_nr] |
||
1493 | mov cl, sizeof.forcedeth_TxDesc |
||
1494 | mul cl |
||
1495 | add eax, forcedeth_tx_ring |
||
1496 | mov ebx, eax |
||
1497 | mov eax, dword [forcedeth_tmp_ptxb] |
||
1498 | sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1499 | mov [ebx + forcedeth_TxDesc.PacketBuffer], eax |
||
1500 | |||
1501 | ;DEBUGF 1,"K : FORCEDETH: transmit: PacketBuffer = 0x%x\n", eax |
||
1502 | ;DEBUGF 1,"K : FORCEDETH: transmit: txflags = 0x%x\n", [forcedeth_txflags]:8 |
||
1503 | |||
1504 | ; wmb(); |
||
1505 | ; tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags); |
||
1506 | pop eax ; header length + data length |
||
1507 | mov ecx, dword [forcedeth_txflags] |
||
1508 | or eax, ecx |
||
1509 | mov [ebx + forcedeth_TxDesc.FlagLen], eax |
||
1510 | |||
1511 | ; writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl); |
||
1512 | mov edi, dword [forcedeth_mapio_addr] |
||
1513 | mov eax, dword [forcedeth_desc_ver] |
||
1514 | or eax, NVREG_TXRXCTL_KICK |
||
1515 | mov dword [edi+NvRegTxRxControl], eax |
||
1516 | |||
1517 | ; pci_push(base); |
||
1518 | call forcedeth_pci_push |
||
1519 | |||
1520 | ; np->next_tx++ |
||
1521 | inc dword [forcedeth_next_tx]; may be need to reset? Overflow? |
||
1522 | |||
1523 | ret |
||
1524 | |||
1525 | ;*************************************************************************** |
||
1526 | ; Function |
||
1527 | ; forcedeth_cable |
||
1528 | ; |
||
1529 | ; Description |
||
1530 | ; Return AL=0, if cable is not connected |
||
1531 | ; Returm AL=1, if cable is connected |
||
1532 | ; |
||
1533 | ;*************************************************************************** |
||
1534 | forcedeth_cable: |
||
1535 | |||
1536 | mov al, 1 |
||
1537 | cmp dword [forcedeth_nocable], 1 |
||
1538 | jne .return |
||
1539 | mov al, 0 |
||
1540 | |||
1541 | .return: |
||
1542 | ret |
||
1543 | |||
1544 | ;*************************************************************************** |
||
1545 | |||
1546 | |||
1547 | ; read/write a register on the PHY. |
||
1548 | ; Caller must guarantee serialization |
||
1549 | ; Input: EAX - miireg, EBX - addr, ECX - value |
||
1550 | ; Output: EAX - retval |
||
1551 | forcedeth_mii_rw: |
||
1552 | push ebx |
||
1553 | push eax ; save miireg |
||
1554 | ; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus) |
||
1555 | mov edi, dword [forcedeth_mapio_addr] |
||
1556 | mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK |
||
1557 | |||
1558 | ; reg = readl(base + NvRegMIIControl) |
||
1559 | mov eax, dword [edi+NvRegMIIControl] |
||
1560 | test eax, NVREG_MIICTL_INUSE |
||
1561 | jz @f |
||
1562 | ; writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl) |
||
1563 | mov dword [edi+NvRegMIIControl], NVREG_MIICTL_INUSE |
||
1564 | ; nv_udelay(NV_MIIBUSY_DELAY) |
||
1565 | mov esi, NV_MIIBUSY_DELAY |
||
1566 | call forcedeth_nv_udelay |
||
1567 | @@: |
||
1568 | ; reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg |
||
1569 | pop edx ; restore miireg |
||
1570 | mov eax, ebx |
||
1571 | shl eax, NVREG_MIICTL_ADDRSHIFT |
||
1572 | or eax, edx |
||
1573 | mov dword [forcedeth_tmp_reg], eax |
||
1574 | |||
1575 | cmp ecx, MII_READ |
||
1576 | je @f |
||
1577 | ; writel(value, base + NvRegMIIData) |
||
1578 | mov dword [edi+NvRegMIIData], ecx |
||
1579 | ; reg |= NVREG_MIICTL_WRITE |
||
1580 | or dword [forcedeth_tmp_reg], NVREG_MIICTL_WRITE |
||
1581 | @@: |
||
1582 | ; writel(reg, base + NvRegMIIControl) |
||
1583 | mov eax, dword [forcedeth_tmp_reg] |
||
1584 | mov dword [edi+NvRegMIIControl], eax |
||
1585 | |||
1586 | push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
||
1587 | |||
1588 | ; reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL) |
||
1589 | stdcall forcedeth_reg_delay, NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, 0 |
||
1590 | |||
1591 | pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
||
1592 | |||
1593 | test eax, eax |
||
1594 | jz @f |
||
1595 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d timed out.\n", edx, ebx |
||
1596 | mov eax, 0xffffffff |
||
1597 | jmp .return |
||
1598 | @@: |
||
1599 | cmp ecx, MII_READ |
||
1600 | je @f |
||
1601 | ;it was a write operation - fewer failures are detectable |
||
1602 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw wrote 0x%x to reg %d at PHY %d\n", ecx, edx, ebx |
||
1603 | mov eax, 0 |
||
1604 | jmp .return |
||
1605 | @@: |
||
1606 | ; readl(base + NvRegMIIStatus) |
||
1607 | mov eax, dword [edi+NvRegMIIStatus] |
||
1608 | test eax, NVREG_MIISTAT_ERROR |
||
1609 | jz @f |
||
1610 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d failed.\n", edx, ebx |
||
1611 | mov eax, 0xffffffff |
||
1612 | jmp .return |
||
1613 | @@: |
||
1614 | ; retval = readl(base + NvRegMIIData) |
||
1615 | mov eax, dword [edi+NvRegMIIData] |
||
1616 | ;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw read from reg %d at PHY %d: 0x%x.\n", edx, ebx, eax |
||
1617 | .return: |
||
1618 | pop ebx |
||
1619 | ret |
||
1620 | |||
1621 | |||
1622 | |||
1623 | ; Input: ESI - delay |
||
1624 | ; Output: none |
||
1625 | forcedeth_nv_udelay: |
||
1626 | |||
1627 | push ebx |
||
1628 | cmp dword [forcedeth_in_shutdown], 0 |
||
1629 | jne @f |
||
1630 | call forcedeth_udelay ; delay on ESI |
||
1631 | jmp .return |
||
1632 | @@: |
||
1633 | |||
1634 | .loop: |
||
1635 | cmp esi, 0 |
||
1636 | je .return |
||
1637 | ; Don't allow an rx_ring overflow to happen |
||
1638 | ; while shutting down the NIC it will |
||
1639 | ; kill the receive function. |
||
1640 | |||
1641 | call forcedeth_drop_rx |
||
1642 | mov ebx, 3 ; sleep = 3 |
||
1643 | cmp ebx, esi ; if(sleep > delay) |
||
1644 | jle @f |
||
1645 | mov ebx, esi ; sleep = delay |
||
1646 | @@: |
||
1647 | push esi |
||
1648 | mov esi, ebx |
||
1649 | ; udelay(sleep) |
||
1650 | call forcedeth_udelay ; delay on ESI |
||
1651 | pop esi |
||
1652 | sub esi, ebx ; delay -= sleep |
||
1653 | jmp .loop |
||
1654 | |||
1655 | .return: |
||
1656 | pop ebx |
||
1657 | ret |
||
1658 | |||
1659 | |||
1660 | ; Input: none |
||
1661 | ; Output: none |
||
1662 | forcedeth_drop_rx: |
||
1663 | |||
1664 | push eax ebx ecx edi |
||
1665 | |||
1666 | ; events = readl(base + NvRegIrqStatus) |
||
1667 | mov edi, dword [forcedeth_mapio_addr] |
||
1668 | mov eax, dword [edi+NvRegIrqStatus] |
||
1669 | |||
1670 | test eax, eax |
||
1671 | jz @f |
||
1672 | ; writel(events, base + NvRegIrqStatus) |
||
1673 | mov dword [edi+NvRegIrqStatus], eax |
||
1674 | @@: |
||
1675 | ;if (!(events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF))) |
||
1676 | test eax, (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF) |
||
1677 | jz .return |
||
1678 | |||
1679 | .loop: |
||
1680 | ; i = np->cur_rx % RX_RING |
||
1681 | mov eax, dword [forcedeth_cur_rx] |
||
1682 | and eax, (RX_RING-1) |
||
1683 | ; //Flags = le32_to_cpu(rx_ring[i].FlagLen) |
||
1684 | ; Flags = rx_ring[i].FlagLen |
||
1685 | mov cl, sizeof.forcedeth_RxDesc |
||
1686 | mul cl |
||
1687 | add eax, forcedeth_rx_ring |
||
1688 | mov ebx, eax |
||
1689 | mov eax, [ebx + forcedeth_RxDesc.FlagLen] |
||
1690 | ; len = nv_descr_getlength(&rx_ring[i], np->desc_ver) |
||
1691 | ; > len = Flags & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2) |
||
1692 | ; ??? len don't used later !!! ??? |
||
1693 | ; ... |
||
1694 | test eax, NV_RX_AVAIL |
||
1695 | jnz .return ; still owned by hardware, |
||
1696 | ; wmb() |
||
1697 | ; ??? may be empty function ??? |
||
1698 | ; np->cur_rx++ |
||
1699 | inc dword [forcedeth_cur_rx] |
||
1700 | ; alloc_rx(NULL) |
||
1701 | call forcedeth_alloc_rx |
||
1702 | .return: |
||
1703 | pop edi ecx ebx eax |
||
1704 | ret |
||
1705 | |||
1706 | |||
1707 | ; Fill rx ring entries. |
||
1708 | ; Return 1 if the allocations for the skbs failed and the |
||
1709 | ; rx engine is without Available descriptors |
||
1710 | ; Input: none |
||
1711 | ; Output: none |
||
1712 | forcedeth_alloc_rx: |
||
1713 | |||
1714 | push eax ebx ecx edx |
||
1715 | ; refill_rx = np->refill_rx |
||
1716 | mov ecx, dword [forcedeth_refill_rx] |
||
1717 | .loop: |
||
1718 | cmp dword [forcedeth_cur_rx], ecx |
||
1719 | je .loop_end |
||
1720 | ; nr = refill_rx % RX_RING |
||
1721 | mov eax, ecx |
||
1722 | and eax, (RX_RING-1) ; nr |
||
1723 | ; rx_ring[nr].PacketBuffer = &rxb[nr * RX_NIC_BUFSIZE] |
||
1724 | push ecx |
||
1725 | push eax |
||
1726 | mov cl, sizeof.forcedeth_RxDesc |
||
1727 | mul cl |
||
1728 | add eax, forcedeth_rx_ring |
||
1729 | mov ebx, eax |
||
1730 | pop eax |
||
1731 | mov cx, RX_NIC_BUFSIZE |
||
1732 | mul cx |
||
1733 | pop ecx |
||
1734 | add eax, forcedeth_rxb |
||
1735 | sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1736 | mov [ebx + forcedeth_RxDesc.PacketBuffer], eax |
||
1737 | ; wmb() |
||
1738 | ; ... |
||
1739 | ; rx_ring[nr].FlagLen = RX_NIC_BUFSIZE | NV_RX_AVAIL |
||
1740 | mov [ebx + forcedeth_RxDesc.FlagLen], (RX_NIC_BUFSIZE or NV_RX_AVAIL) |
||
1741 | inc ecx |
||
1742 | jmp .loop |
||
1743 | |||
1744 | .loop_end: |
||
1745 | ; np->refill_rx = refill_rx |
||
1746 | mov [forcedeth_refill_rx], ecx |
||
1747 | .return: |
||
1748 | pop edx ecx ebx eax |
||
1749 | ret |
||
1750 | |||
1751 | |||
1752 | ; Delay in millisec |
||
1753 | ; Input: ESI - delay in ms |
||
1754 | ; Output: none |
||
1755 | forcedeth_udelay: |
||
1756 | call delay_ms |
||
1757 | ret |
||
1758 | |||
1759 | ; Input: offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword |
||
1760 | ; Output: EAX - 0|1 |
||
1761 | ;;;;proc forcedeth_reg_delay,offset:word,mask:dword,target:dword,delay:word,delaymax:word,msg:dword |
||
1762 | proc forcedeth_reg_delay,offset:dword,mask:dword,target:dword,delay:dword,delaymax:dword,msg:dword |
||
1763 | |||
1764 | push ebx esi edi |
||
1765 | ; pci_push(base) |
||
1766 | call forcedeth_pci_push |
||
1767 | .loop: |
||
1768 | ; nv_udelay(delay) |
||
1769 | mov esi, dword [delay] |
||
1770 | call forcedeth_nv_udelay ; delay in esi |
||
1771 | mov eax, dword [delaymax] |
||
1772 | sub eax, dword [delay] |
||
1773 | mov dword [delaymax], eax |
||
1774 | ; if (delaymax < 0) |
||
1775 | test dword [delaymax], 0x80000000 |
||
1776 | jz @f |
||
1777 | ; return 1 |
||
1778 | mov eax, 1 |
||
1779 | jmp .return |
||
1780 | @@: |
||
1781 | ; while ((readl(base + offset) & mask) != target) |
||
1782 | mov edi, dword [forcedeth_mapio_addr] |
||
1783 | mov ebx, dword [offset] |
||
1784 | mov eax, dword [edi+ebx] |
||
1785 | and eax, dword [mask] |
||
1786 | cmp eax, dword [target] |
||
1787 | jne .loop |
||
1788 | xor eax, eax |
||
1789 | .return: |
||
1790 | pop edi esi ebx |
||
1791 | ret |
||
1792 | endp |
||
1793 | |||
1794 | |||
1795 | ; Input: none |
||
1796 | ; Output: none |
||
1797 | forcedeth_pci_push: |
||
1798 | push eax edi |
||
1799 | ;force out pending posted writes |
||
1800 | mov edi, dword [forcedeth_mapio_addr] |
||
1801 | mov eax, dword [edi] |
||
1802 | pop edi eax |
||
1803 | ret |
||
1804 | |||
1805 | |||
1806 | ; Input: none |
||
1807 | ; Output: EAX - result (0 = OK, other = error) |
||
1808 | forcedeth_phy_init: |
||
1809 | |||
1810 | push ebx ecx |
||
1811 | |||
1812 | ; set advertise register |
||
1813 | ; reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); |
||
1814 | ; EBX - addr, EAX - miireg, ECX - value |
||
1815 | mov ebx, dword [forcedeth_phyaddr] |
||
1816 | mov eax, MII_ADVERTISE |
||
1817 | mov ecx, MII_READ |
||
1818 | call forcedeth_mii_rw ; reg = eax |
||
1819 | |||
1820 | ; reg |= |
||
1821 | ; (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF | |
||
1822 | ; ADVERTISE_100FULL | 0x800 | 0x400); |
||
1823 | or eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400) |
||
1824 | |||
1825 | ; if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg)) |
||
1826 | ; EBX - addr, EAX - miireg, ECX - value |
||
1827 | mov ecx, eax ; reg |
||
1828 | mov eax, MII_ADVERTISE |
||
1829 | call forcedeth_mii_rw ; eax -> return |
||
1830 | |||
1831 | test eax, eax |
||
1832 | jz @f |
||
1833 | ; printf("phy write to advertise failed.\n"); |
||
1834 | DEBUGF 1," K : FORCEDETH: phy write to advertise failed.\n" |
||
1835 | |||
1836 | ; return PHY_ERROR; |
||
1837 | mov eax, PHY_ERROR |
||
1838 | jmp .return |
||
1839 | @@: |
||
1840 | ; get phy interface type |
||
1841 | ; phyinterface = readl(base + NvRegPhyInterface); |
||
1842 | mov edi, dword [forcedeth_mapio_addr] |
||
1843 | mov eax, dword [edi+NvRegPhyInterface] ; phyinterface = eax |
||
1844 | mov dword [forcedeth_tmp_phyinterface], eax |
||
1845 | |||
1846 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1847 | DEBUGF 1," K : FORCEDETH: phy interface type = 0x%x\n", [forcedeth_tmp_phyinterface]:8 |
||
1848 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1849 | |||
1850 | ; see if gigabit phy |
||
1851 | ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); |
||
1852 | ; EBX - addr, EAX - miireg, ECX - value |
||
1853 | mov eax, MII_BMSR |
||
1854 | mov ecx, MII_READ |
||
1855 | call forcedeth_mii_rw ; mii_status = eax |
||
1856 | |||
1857 | ; if (mii_status & PHY_GIGABIT) |
||
1858 | test eax, PHY_GIGABIT |
||
1859 | jnz .gigabit |
||
1860 | ; np->gigabit = 0; |
||
1861 | mov dword [forcedeth_gigabit], 0 |
||
1862 | jmp .next_if |
||
1863 | |||
1864 | .gigabit: |
||
1865 | ; np->gigabit = PHY_GIGABIT; |
||
1866 | mov dword [forcedeth_gigabit], PHY_GIGABIT |
||
1867 | |||
1868 | ; mii_control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ); |
||
1869 | ; EBX - addr, EAX - miireg, ECX - value |
||
1870 | mov eax, MII_1000BT_CR |
||
1871 | mov ecx, MII_READ |
||
1872 | call forcedeth_mii_rw ; mii_control_1000 = eax |
||
1873 | |||
1874 | ; mii_control_1000 &= ~ADVERTISE_1000HALF; |
||
1875 | and eax, (not ADVERTISE_1000HALF) |
||
1876 | |||
1877 | ; if (phyinterface & PHY_RGMII) |
||
1878 | test dword [forcedeth_tmp_phyinterface], PHY_RGMII |
||
1879 | jz @f |
||
1880 | ; mii_control_1000 |= ADVERTISE_1000FULL |
||
1881 | or eax, ADVERTISE_1000FULL |
||
1882 | jmp .next |
||
1883 | @@: |
||
1884 | ; mii_control_1000 &= ~ADVERTISE_1000FULL |
||
1885 | and eax, (not ADVERTISE_1000FULL) |
||
1886 | |||
1887 | .next: |
||
1888 | ; if (mii_rw(nic, np->phyaddr, MII_1000BT_CR, mii_control_1000)) |
||
1889 | ; EBX - addr, EAX - miireg, ECX - value |
||
1890 | mov ecx, eax |
||
1891 | mov eax, MII_1000BT_CR |
||
1892 | call forcedeth_mii_rw ; eax -> return |
||
1893 | |||
1894 | test eax, eax |
||
1895 | jz .next_if |
||
1896 | |||
1897 | ; printf("phy init failed.\n"); |
||
1898 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1899 | |||
1900 | ; return PHY_ERROR; |
||
1901 | mov eax, PHY_ERROR |
||
1902 | jmp .return |
||
1903 | |||
1904 | .next_if: |
||
1905 | |||
1906 | ; reset the phy |
||
1907 | ; if (phy_reset(nic)) |
||
1908 | call forcedeth_phy_reset |
||
1909 | test eax, eax |
||
1910 | jz @f |
||
1911 | ; printf("phy reset failed\n") |
||
1912 | DEBUGF 1," K : FORCEDETH: phy reset failed.\n" |
||
1913 | ; return PHY_ERROR |
||
1914 | mov eax, PHY_ERROR |
||
1915 | jmp .return |
||
1916 | @@: |
||
1917 | |||
1918 | ; phy vendor specific configuration |
||
1919 | ; if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) |
||
1920 | cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA |
||
1921 | jne .next_if2 |
||
1922 | test dword [forcedeth_tmp_phyinterface], PHY_RGMII |
||
1923 | jz .next_if2 |
||
1924 | |||
1925 | ; phy_reserved = mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ) |
||
1926 | ; EBX - addr, EAX - miireg, ECX - value |
||
1927 | mov eax, MII_RESV1 |
||
1928 | mov ecx, MII_READ |
||
1929 | call forcedeth_mii_rw ; phy_reserved = eax |
||
1930 | |||
1931 | ; phy_reserved &= ~(PHY_INIT1 | PHY_INIT2) |
||
1932 | and eax, (not (PHY_INIT1 or PHY_INIT2)) |
||
1933 | ; phy_reserved |= (PHY_INIT3 | PHY_INIT4) |
||
1934 | or eax, (PHY_INIT3 or PHY_INIT4) |
||
1935 | |||
1936 | ; if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved)) |
||
1937 | ; EBX - addr, EAX - miireg, ECX - value |
||
1938 | mov ecx, eax |
||
1939 | mov eax, MII_RESV1 |
||
1940 | call forcedeth_mii_rw ; eax -> return |
||
1941 | test eax, eax |
||
1942 | jz @f |
||
1943 | ; printf("phy init failed.\n") |
||
1944 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1945 | ; return PHY_ERROR |
||
1946 | mov eax, PHY_ERROR |
||
1947 | jmp .return |
||
1948 | @@: |
||
1949 | ; phy_reserved = mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ); |
||
1950 | ; EBX - addr, EAX - miireg, ECX - value |
||
1951 | mov eax, MII_NCONFIG |
||
1952 | mov ecx, MII_READ |
||
1953 | call forcedeth_mii_rw ; phy_reserved = eax |
||
1954 | |||
1955 | ; phy_reserved |= PHY_INIT5 |
||
1956 | or eax, PHY_INIT5 |
||
1957 | |||
1958 | ; if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved)) |
||
1959 | ; EBX - addr, EAX - miireg, ECX - value |
||
1960 | mov ecx, eax |
||
1961 | mov eax, MII_NCONFIG |
||
1962 | call forcedeth_mii_rw ; eax -> return |
||
1963 | test eax, eax |
||
1964 | jz .next_if2 |
||
1965 | ; printf("phy init failed.\n") |
||
1966 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1967 | ; return PHY_ERROR |
||
1968 | mov eax, PHY_ERROR |
||
1969 | jmp .return |
||
1970 | |||
1971 | .next_if2: |
||
1972 | |||
1973 | ; if (np->phy_oui == PHY_OUI_CICADA) |
||
1974 | cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA |
||
1975 | jne .restart |
||
1976 | |||
1977 | ; phy_reserved = mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ) |
||
1978 | ; EBX - addr, EAX - miireg, ECX - value |
||
1979 | mov eax, MII_SREVISION |
||
1980 | mov ecx, MII_READ |
||
1981 | call forcedeth_mii_rw ; phy_reserved = eax |
||
1982 | |||
1983 | ; phy_reserved |= PHY_INIT6 |
||
1984 | or eax, PHY_INIT6 |
||
1985 | |||
1986 | ; if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved)) |
||
1987 | mov ecx, eax |
||
1988 | mov eax, MII_SREVISION |
||
1989 | call forcedeth_mii_rw ; eax -> return |
||
1990 | test eax, eax |
||
1991 | jz .restart |
||
1992 | ; printf("phy init failed.\n"); |
||
1993 | DEBUGF 1," K : FORCEDETH: phy init failed.\n" |
||
1994 | ; return PHY_ERROR; |
||
1995 | jmp .return |
||
1996 | |||
1997 | .restart: |
||
1998 | ; restart auto negotiation |
||
1999 | ; mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ) |
||
2000 | ; EBX - addr, EAX - miireg, ECX - value |
||
2001 | mov eax, MII_BMCR |
||
2002 | mov ecx, MII_READ |
||
2003 | call forcedeth_mii_rw ; mii_control = eax |
||
2004 | |||
2005 | ; mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE) |
||
2006 | or eax, (BMCR_ANRESTART or BMCR_ANENABLE) |
||
2007 | |||
2008 | ; if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control)) |
||
2009 | mov ecx, eax |
||
2010 | mov eax, MII_BMCR |
||
2011 | call forcedeth_mii_rw ; eax -> return |
||
2012 | test eax, eax |
||
2013 | jz .ok |
||
2014 | |||
2015 | ; return PHY_ERROR; |
||
2016 | mov eax, PHY_ERROR |
||
2017 | jmp .return |
||
2018 | |||
2019 | .ok: |
||
2020 | mov eax, 0 |
||
2021 | .return: |
||
2022 | pop ecx ebx |
||
2023 | ret |
||
2024 | |||
2025 | |||
2026 | ; Input: none |
||
2027 | ; Output: EAX - result (0 = OK, other = error) |
||
2028 | forcedeth_phy_reset: |
||
2029 | |||
2030 | push ebx ecx edx |
||
2031 | |||
2032 | ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); |
||
2033 | ; EBX - addr, EAX - miireg, ECX - value |
||
2034 | mov ebx, dword [forcedeth_phyaddr] |
||
2035 | mov eax, MII_BMCR |
||
2036 | mov ecx, MII_READ |
||
2037 | call forcedeth_mii_rw ; miicontrol = eax |
||
2038 | |||
2039 | ; miicontrol |= BMCR_RESET; |
||
2040 | or eax, BMCR_RESET |
||
2041 | push eax |
||
2042 | |||
2043 | ; if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol)) |
||
2044 | ; EBX - addr, EAX - miireg, ECX - value |
||
2045 | mov ecx, eax |
||
2046 | mov eax, MII_BMCR |
||
2047 | call forcedeth_mii_rw ; miicontrol = eax |
||
2048 | |||
2049 | test eax, eax |
||
2050 | jz @f |
||
2051 | pop eax |
||
2052 | mov eax, 0xffffffff |
||
2053 | jmp .return |
||
2054 | @@: |
||
2055 | pop eax |
||
2056 | |||
2057 | ; wait for 500ms |
||
2058 | ; mdelay(500) |
||
2059 | mov esi, 500 |
||
2060 | call forcedeth_udelay |
||
2061 | |||
2062 | ; must wait till reset is deasserted |
||
2063 | ; while (miicontrol & BMCR_RESET) { |
||
2064 | mov edx, 100 |
||
2065 | .while_loop: |
||
2066 | test eax, BMCR_RESET |
||
2067 | jz .while_loop_exit |
||
2068 | |||
2069 | ; mdelay(10); |
||
2070 | mov esi, 10 |
||
2071 | call forcedeth_udelay |
||
2072 | |||
2073 | ; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ); |
||
2074 | ; EBX - addr, EAX - miireg, ECX - value |
||
2075 | mov eax, MII_BMCR |
||
2076 | mov ecx, MII_READ |
||
2077 | call forcedeth_mii_rw ; miicontrol = eax |
||
2078 | |||
2079 | ; FIXME: 100 tries seem excessive |
||
2080 | ; if (tries++ > 100) |
||
2081 | dec edx |
||
2082 | jnz .while_loop |
||
2083 | ; return -1; |
||
2084 | mov eax, 0xffffffff |
||
2085 | jmp .return |
||
2086 | .while_loop_exit: |
||
2087 | ; return 0 |
||
2088 | mov eax, 0 |
||
2089 | .return: |
||
2090 | pop edx ecx ebx |
||
2091 | ret |
||
2092 | |||
2093 | ; Input: none |
||
2094 | ; Output: none |
||
2095 | forcedeth_mac_reset: |
||
2096 | push esi edi |
||
2097 | |||
2098 | ; dprintf("mac_reset\n") |
||
2099 | DEBUGF 1," K : FORCEDETH: mac_reset.\n" |
||
2100 | |||
2101 | ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) |
||
2102 | mov edi, dword [forcedeth_mapio_addr] |
||
2103 | mov eax, dword [forcedeth_desc_ver] |
||
2104 | or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) |
||
2105 | mov dword [edi+NvRegTxRxControl], eax |
||
2106 | |||
2107 | ; pci_push(base) |
||
2108 | call forcedeth_pci_push |
||
2109 | |||
2110 | ; writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset) |
||
2111 | mov dword [edi+NvRegMacReset], NVREG_MAC_RESET_ASSERT |
||
2112 | |||
2113 | ; pci_push(base) |
||
2114 | call forcedeth_pci_push |
||
2115 | |||
2116 | ; udelay(NV_MAC_RESET_DELAY) |
||
2117 | mov esi, NV_MAC_RESET_DELAY |
||
2118 | call forcedeth_nv_udelay |
||
2119 | |||
2120 | ; writel(0, base + NvRegMacReset) |
||
2121 | mov dword [edi+NvRegMacReset], 0 |
||
2122 | |||
2123 | ; pci_push(base) |
||
2124 | call forcedeth_pci_push |
||
2125 | |||
2126 | ; udelay(NV_MAC_RESET_DELAY) |
||
2127 | mov esi, NV_MAC_RESET_DELAY |
||
2128 | call forcedeth_nv_udelay |
||
2129 | |||
2130 | ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) |
||
2131 | mov eax, dword [forcedeth_desc_ver] |
||
2132 | or eax, NVREG_TXRXCTL_BIT2 |
||
2133 | mov dword [edi+NvRegTxRxControl], eax |
||
2134 | |||
2135 | ; pci_push(base) |
||
2136 | call forcedeth_pci_push |
||
2137 | |||
2138 | pop edi esi |
||
2139 | ret |
||
2140 | |||
2141 | ; Input: none |
||
2142 | ; Output: none |
||
2143 | forcedeth_init_ring: |
||
2144 | push eax ebx ecx |
||
2145 | |||
2146 | ; np->next_tx = np->nic_tx = 0 |
||
2147 | mov dword[forcedeth_next_tx], 0 |
||
2148 | mov dword[forcedeth_nic_tx], 0 |
||
2149 | |||
2150 | ; for (i = 0; i < TX_RING; i++) |
||
2151 | mov ecx, TX_RING |
||
2152 | |||
2153 | .for_loop: |
||
2154 | ; tx_ring[i].FlagLen = 0; |
||
2155 | mov eax, ecx |
||
2156 | dec eax |
||
2157 | mov bl, sizeof.forcedeth_TxDesc |
||
2158 | mul bl |
||
2159 | add eax, forcedeth_tx_ring |
||
2160 | mov ebx, eax |
||
2161 | mov dword [ebx + forcedeth_TxDesc.FlagLen], 0 |
||
2162 | loop .for_loop |
||
2163 | |||
2164 | ; np->cur_rx = RX_RING; |
||
2165 | mov dword [forcedeth_cur_rx], RX_RING |
||
2166 | ; np->refill_rx = 0; |
||
2167 | mov dword [forcedeth_refill_rx], 0 |
||
2168 | |||
2169 | ;for (i = 0; i < RX_RING; i++) |
||
2170 | mov ecx, RX_RING |
||
2171 | |||
2172 | .for_loop2: |
||
2173 | ; rx_ring[i].FlagLen = 0; |
||
2174 | mov eax, ecx |
||
2175 | dec eax |
||
2176 | mov bl, sizeof.forcedeth_RxDesc |
||
2177 | mul bl |
||
2178 | add eax, forcedeth_rx_ring |
||
2179 | mov ebx, eax |
||
2180 | mov dword [ebx + forcedeth_RxDesc.FlagLen], 0 |
||
2181 | loop .for_loop2 |
||
2182 | |||
2183 | ; alloc_rx(nic); |
||
2184 | call forcedeth_alloc_rx |
||
2185 | |||
2186 | .return: |
||
2187 | pop ecx ebx eax |
||
2188 | ret |
||
2189 | |||
2190 | ; Input: none |
||
2191 | ; Output: none |
||
2192 | forcedeth_txrx_reset: |
||
2193 | push eax esi edi |
||
2194 | |||
2195 | ; dprintf(("txrx_reset\n")) |
||
2196 | DEBUGF 1," K : FORCEDETH: txrx_reset.\n" |
||
2197 | |||
2198 | ; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl) |
||
2199 | mov edi, dword [forcedeth_mapio_addr] |
||
2200 | mov eax, dword [forcedeth_desc_ver] |
||
2201 | or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET) |
||
2202 | mov dword [edi+NvRegTxRxControl], eax |
||
2203 | |||
2204 | ; pci_push(base) |
||
2205 | call forcedeth_pci_push |
||
2206 | |||
2207 | ; nv_udelay(NV_TXRX_RESET_DELAY) |
||
2208 | mov esi, NV_TXRX_RESET_DELAY |
||
2209 | call forcedeth_nv_udelay |
||
2210 | |||
2211 | ; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl) |
||
2212 | mov eax, dword [forcedeth_desc_ver] |
||
2213 | or eax, NVREG_TXRXCTL_BIT2 |
||
2214 | mov dword [edi+NvRegTxRxControl], eax |
||
2215 | |||
2216 | ; pci_push(base) |
||
2217 | call forcedeth_pci_push |
||
2218 | |||
2219 | .return: |
||
2220 | pop edi esi eax |
||
2221 | ret |
||
2222 | |||
2223 | ; Input: none |
||
2224 | ; Output: none |
||
2225 | forcedeth_set_multicast: |
||
2226 | push edi |
||
2227 | |||
2228 | ; u32 addr[2]; |
||
2229 | ; u32 mask[2]; |
||
2230 | ; u32 pff; |
||
2231 | ; u32 alwaysOff[2]; |
||
2232 | ; u32 alwaysOn[2]; |
||
2233 | ; |
||
2234 | ; memset(addr, 0, sizeof(addr)); |
||
2235 | ; memset(mask, 0, sizeof(mask)); |
||
2236 | ; |
||
2237 | ; pff = NVREG_PFF_MYADDR; |
||
2238 | ; |
||
2239 | ; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0; |
||
2240 | ; |
||
2241 | ; addr[0] = alwaysOn[0]; |
||
2242 | ; addr[1] = alwaysOn[1]; |
||
2243 | ; mask[0] = alwaysOn[0] | alwaysOff[0]; |
||
2244 | ; mask[1] = alwaysOn[1] | alwaysOff[1]; |
||
2245 | ; |
||
2246 | ; addr[0] |= NVREG_MCASTADDRA_FORCE; |
||
2247 | ; pff |= NVREG_PFF_ALWAYS; |
||
2248 | ; stop_rx(); |
||
2249 | call forcedeth_stop_rx |
||
2250 | ; writel(addr[0], base + NvRegMulticastAddrA); |
||
2251 | mov edi, dword [forcedeth_mapio_addr] |
||
2252 | mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE |
||
2253 | ; writel(addr[1], base + NvRegMulticastAddrB); |
||
2254 | mov dword [edi+NvRegMulticastAddrB], 0 |
||
2255 | ; writel(mask[0], base + NvRegMulticastMaskA); |
||
2256 | mov dword [edi+NvRegMulticastMaskA], 0 |
||
2257 | ; writel(mask[1], base + NvRegMulticastMaskB); |
||
2258 | mov dword [edi+NvRegMulticastMaskB], 0 |
||
2259 | ; writel(pff, base + NvRegPacketFilterFlags); |
||
2260 | mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_MYADDR or NVREG_PFF_ALWAYS) |
||
2261 | ; start_rx(nic); |
||
2262 | call forcedeth_start_rx |
||
2263 | |||
2264 | .return: |
||
2265 | pop edi |
||
2266 | ret |
||
2267 | |||
2268 | ; Input: none |
||
2269 | ; Output: none |
||
2270 | forcedeth_start_rx: |
||
2271 | push edi |
||
2272 | |||
2273 | ; dprintf(("start_rx\n")) |
||
2274 | DEBUGF 1," K : FORCEDETH: start_rx.\n" |
||
2275 | |||
2276 | ; Already running? Stop it. |
||
2277 | ; if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) { |
||
2278 | mov edi, dword [forcedeth_mapio_addr] |
||
2279 | mov eax, dword [edi+NvRegReceiverControl] |
||
2280 | test eax, NVREG_RCVCTL_START |
||
2281 | jz @f |
||
2282 | ; writel(0, base + NvRegReceiverControl) |
||
2283 | mov dword [edi+NvRegReceiverControl], 0 |
||
2284 | ; pci_push(base) |
||
2285 | call forcedeth_pci_push |
||
2286 | |||
2287 | @@: |
||
2288 | |||
2289 | ; writel(np->linkspeed, base + NvRegLinkSpeed); |
||
2290 | mov eax, dword [forcedeth_linkspeed] |
||
2291 | mov dword [edi+NvRegLinkSpeed], eax |
||
2292 | ; pci_push(base); |
||
2293 | call forcedeth_pci_push |
||
2294 | ; writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); |
||
2295 | mov dword [edi+NvRegReceiverControl], NVREG_RCVCTL_START |
||
2296 | ; pci_push(base); |
||
2297 | call forcedeth_pci_push |
||
2298 | |||
2299 | .return: |
||
2300 | pop edi |
||
2301 | ret |
||
2302 | |||
2303 | ; Input: none |
||
2304 | ; Output: none |
||
2305 | forcedeth_stop_rx: |
||
2306 | push esi edi |
||
2307 | |||
2308 | ; dprintf(("stop_rx\n")) |
||
2309 | DEBUGF 1," K : FORCEDETH: stop_rx.\n" |
||
2310 | |||
2311 | ; writel(0, base + NvRegReceiverControl) |
||
2312 | mov edi, dword [forcedeth_mapio_addr] |
||
2313 | mov dword [edi+NvRegReceiverControl], 0 |
||
2314 | |||
2315 | push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;; |
||
2316 | ; reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, "stop_rx: ReceiverStatus remained busy"); |
||
2317 | stdcall forcedeth_reg_delay, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, 0 |
||
2318 | pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;; |
||
2319 | |||
2320 | |||
2321 | ; nv_udelay(NV_RXSTOP_DELAY2) |
||
2322 | mov esi, NV_RXSTOP_DELAY2 |
||
2323 | call forcedeth_nv_udelay |
||
2324 | |||
2325 | ; writel(0, base + NvRegLinkSpeed) |
||
2326 | mov dword [edi+NvRegLinkSpeed], 0 |
||
2327 | |||
2328 | .return: |
||
2329 | pop edi esi |
||
2330 | ret |
||
2331 | |||
2332 | ; Input: none |
||
2333 | ; Output: EAX |
||
2334 | forcedeth_update_linkspeed: |
||
2335 | push ebx ecx esi edi |
||
2336 | |||
2337 | ; BMSR_LSTATUS is latched, read it twice: |
||
2338 | ; we want the current value. |
||
2339 | |||
2340 | ; mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) |
||
2341 | ;EBX - addr, EAX - miireg, ECX - value |
||
2342 | mov ebx, dword [forcedeth_phyaddr] |
||
2343 | mov eax, MII_BMSR |
||
2344 | mov ecx, MII_READ |
||
2345 | call forcedeth_mii_rw |
||
2346 | |||
2347 | |||
2348 | ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) |
||
2349 | ;EBX - addr, EAX - miireg, ECX - value |
||
2350 | mov ebx, dword [forcedeth_phyaddr] |
||
2351 | mov eax, MII_BMSR |
||
2352 | mov ecx, MII_READ |
||
2353 | call forcedeth_mii_rw ; mii_status = eax |
||
2354 | |||
2355 | ; yhlu |
||
2356 | |||
2357 | ; for(i=0;i<30;i++) { |
||
2358 | mov ecx, 30 |
||
2359 | .for_loop: |
||
2360 | push ecx |
||
2361 | |||
2362 | ; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ); |
||
2363 | ;EBX - addr, EAX - miireg, ECX - value |
||
2364 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2365 | mov eax, MII_BMSR |
||
2366 | mov ecx, MII_READ |
||
2367 | call forcedeth_mii_rw ; mii_status = eax |
||
2368 | |||
2369 | ; if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break; |
||
2370 | test eax, BMSR_LSTATUS |
||
2371 | jz @f |
||
2372 | test eax, BMSR_ANEGCOMPLETE |
||
2373 | jz @f |
||
2374 | ; break |
||
2375 | pop ecx |
||
2376 | jmp .break |
||
2377 | |||
2378 | @@: |
||
2379 | |||
2380 | ; mdelay(100); |
||
2381 | push eax ; ??? |
||
2382 | mov esi, 100 |
||
2383 | call forcedeth_udelay |
||
2384 | pop eax ; ??? |
||
2385 | |||
2386 | pop ecx |
||
2387 | loop .for_loop |
||
2388 | |||
2389 | .break: |
||
2390 | |||
2391 | ; if (!(mii_status & BMSR_LSTATUS)) { |
||
2392 | test eax, BMSR_LSTATUS |
||
2393 | jnz @f |
||
2394 | |||
2395 | ; printf("no link detected by phy - falling back to 10HD.\n") |
||
2396 | DEBUGF 1," K : FORCEDETH: update_linkspeed: no link detected by phy - falling back to 10HD.\n" |
||
2397 | |||
2398 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2399 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2400 | |||
2401 | ; newdup = 0; |
||
2402 | mov dword [forcedeth_tmp_newdup], 0 |
||
2403 | ; retval = 0; |
||
2404 | mov dword [forcedeth_tmp_retval], 0 |
||
2405 | |||
2406 | ; goto set_speed; |
||
2407 | jmp .set_speed |
||
2408 | |||
2409 | @@: |
||
2410 | |||
2411 | ; check auto negotiation is complete |
||
2412 | ; if (!(mii_status & BMSR_ANEGCOMPLETE)) { |
||
2413 | test eax, BMSR_ANEGCOMPLETE |
||
2414 | jnz @f |
||
2415 | |||
2416 | ; still in autonegotiation - configure nic for 10 MBit HD and wait. |
||
2417 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2418 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2419 | |||
2420 | ; newdup = 0 |
||
2421 | mov dword [forcedeth_tmp_newdup], 0 |
||
2422 | |||
2423 | ; retval = 0 |
||
2424 | mov dword [forcedeth_tmp_retval], 0 |
||
2425 | |||
2426 | ; printf("autoneg not completed - falling back to 10HD.\n") |
||
2427 | DEBUGF 1," K : FORCEDETH: update_linkspeed: autoneg not completed - falling back to 10HD.\n" |
||
2428 | |||
2429 | ; goto set_speed |
||
2430 | jmp .set_speed |
||
2431 | |||
2432 | @@: |
||
2433 | |||
2434 | ; retval = 1 |
||
2435 | mov dword [forcedeth_tmp_retval], 1 |
||
2436 | |||
2437 | ; if (np->gigabit == PHY_GIGABIT) { |
||
2438 | cmp dword [forcedeth_gigabit], PHY_GIGABIT |
||
2439 | jne .end_if |
||
2440 | ; control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ) |
||
2441 | ;EBX - addr, EAX - miireg, ECX - value |
||
2442 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2443 | mov eax, MII_1000BT_CR |
||
2444 | mov ecx, MII_READ |
||
2445 | call forcedeth_mii_rw ; control_1000 = eax |
||
2446 | mov dword [forcedeth_tmp_control_1000], eax |
||
2447 | |||
2448 | ; status_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_SR, MII_READ) |
||
2449 | ;EBX - addr, EAX - miireg, ECX - value |
||
2450 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2451 | mov eax, MII_1000BT_SR |
||
2452 | mov ecx, MII_READ |
||
2453 | call forcedeth_mii_rw ; status_1000 = eax |
||
2454 | ;mov dword [forcedeth_tmp_status_1000], eax |
||
2455 | |||
2456 | ; if ((control_1000 & ADVERTISE_1000FULL) && |
||
2457 | ; (status_1000 & LPA_1000FULL)) { |
||
2458 | test eax, LPA_1000FULL |
||
2459 | jz .end_if |
||
2460 | test dword [forcedeth_tmp_control_1000], ADVERTISE_1000FULL |
||
2461 | jz .end_if |
||
2462 | |||
2463 | ; printf ("update_linkspeed: GBit ethernet detected.\n") |
||
2464 | DEBUGF 1," K : FORCEDETH: update_linkspeed: GBit ethernet detected.\n" |
||
2465 | |||
2466 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000 |
||
2467 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_1000) |
||
2468 | |||
2469 | ; newdup = 1 |
||
2470 | mov dword [forcedeth_tmp_newdup], 1 |
||
2471 | |||
2472 | ; goto set_speed |
||
2473 | jmp .set_speed |
||
2474 | |||
2475 | .end_if: |
||
2476 | |||
2477 | ; adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ); |
||
2478 | ;EBX - addr, EAX - miireg, ECX - value |
||
2479 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2480 | mov eax, MII_ADVERTISE |
||
2481 | mov ecx, MII_READ |
||
2482 | call forcedeth_mii_rw ; adv = eax |
||
2483 | mov dword [forcedeth_tmp_adv], eax |
||
2484 | |||
2485 | ; lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ); |
||
2486 | ;EBX - addr, EAX - miireg, ECX - value |
||
2487 | ;mov ebx, dword [forcedeth_phyaddr] |
||
2488 | mov eax, MII_LPA |
||
2489 | mov ecx, MII_READ |
||
2490 | call forcedeth_mii_rw ; lpa = eax |
||
2491 | mov dword [forcedeth_tmp_lpa], eax |
||
2492 | |||
2493 | ; dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n", adv, lpa)); |
||
2494 | DEBUGF 1," K : FORCEDETH: update_linkspeed: PHY advertises 0x%x, lpa 0x%x.\n", [forcedeth_tmp_adv]:8, [forcedeth_tmp_lpa]:8 |
||
2495 | |||
2496 | ; FIXME: handle parallel detection properly, handle gigabit ethernet |
||
2497 | ; lpa = lpa & adv |
||
2498 | mov eax, dword [forcedeth_tmp_adv] |
||
2499 | and dword [forcedeth_tmp_lpa], eax |
||
2500 | |||
2501 | mov eax, dword [forcedeth_tmp_lpa] |
||
2502 | |||
2503 | ; if (lpa & LPA_100FULL) { |
||
2504 | test eax, LPA_100FULL |
||
2505 | jz @f |
||
2506 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 |
||
2507 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) |
||
2508 | ; newdup = 1 |
||
2509 | mov dword [forcedeth_tmp_newdup], 1 |
||
2510 | jmp .set_speed |
||
2511 | @@: |
||
2512 | ; } else if (lpa & LPA_100HALF) { |
||
2513 | test eax, LPA_100HALF |
||
2514 | jz @f |
||
2515 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100 |
||
2516 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100) |
||
2517 | ; newdup = 0 |
||
2518 | mov dword [forcedeth_tmp_newdup], 0 |
||
2519 | jmp .set_speed |
||
2520 | @@: |
||
2521 | ; } else if (lpa & LPA_10FULL) { |
||
2522 | test eax, LPA_10FULL |
||
2523 | jz @f |
||
2524 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2525 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2526 | ; newdup = 1 |
||
2527 | mov dword [forcedeth_tmp_newdup], 1 |
||
2528 | jmp .set_speed |
||
2529 | @@: |
||
2530 | ; } else if (lpa & LPA_10HALF) { |
||
2531 | test eax, LPA_10HALF |
||
2532 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10; |
||
2533 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2534 | ; newdup = 0; |
||
2535 | mov dword [forcedeth_tmp_newdup], 0 |
||
2536 | jmp .set_speed |
||
2537 | @@: |
||
2538 | ; } else { |
||
2539 | ; printf("bad ability %hX - falling back to 10HD.\n", lpa) |
||
2540 | DEBUGF 1," K : FORCEDETH: update_linkspeed: bad ability 0x%x - falling back to 10HD.\n", eax |
||
2541 | |||
2542 | ; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10 |
||
2543 | mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10) |
||
2544 | ; newdup = 0 |
||
2545 | mov dword [forcedeth_tmp_newdup], 0 |
||
2546 | ; } |
||
2547 | |||
2548 | .set_speed: |
||
2549 | |||
2550 | ; if (np->duplex == newdup && np->linkspeed == newls) |
||
2551 | mov eax, dword [forcedeth_tmp_newdup] |
||
2552 | cmp eax, dword [forcedeth_duplex] |
||
2553 | jne .end_if2 |
||
2554 | mov eax, dword [forcedeth_tmp_newls] |
||
2555 | cmp eax, dword [forcedeth_linkspeed] |
||
2556 | jne .end_if2 |
||
2557 | ; return retval; |
||
2558 | jmp .return |
||
2559 | |||
2560 | .end_if2: |
||
2561 | |||
2562 | ; dprintf(("changing link setting from %d/%s to %d/%s.\n", |
||
2563 | ; np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex")) |
||
2564 | DEBUGF 1," K : FORCEDETH: update_linkspeed: changing link from %x/XD to %x/XD.\n", [forcedeth_linkspeed]:8, [forcedeth_tmp_newls]:8 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!! |
||
2565 | |||
2566 | ; np->duplex = newdup |
||
2567 | mov eax, dword [forcedeth_tmp_newdup] |
||
2568 | mov dword [forcedeth_duplex], eax |
||
2569 | |||
2570 | ; np->linkspeed = newls |
||
2571 | mov eax, [forcedeth_tmp_newls] |
||
2572 | mov dword [forcedeth_linkspeed], eax |
||
2573 | |||
2574 | ; if (np->gigabit == PHY_GIGABIT) { |
||
2575 | cmp dword [forcedeth_gigabit], PHY_GIGABIT |
||
2576 | jne .end_if3 |
||
2577 | |||
2578 | ; phyreg = readl(base + NvRegRandomSeed); |
||
2579 | mov edi, dword [forcedeth_mapio_addr] |
||
2580 | mov eax, dword [edi+NvRegRandomSeed] |
||
2581 | |||
2582 | ; phyreg &= ~(0x3FF00); |
||
2583 | and eax, not (0x3FF00) |
||
2584 | mov ecx, eax ; phyreg = ecx |
||
2585 | |||
2586 | ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) |
||
2587 | mov eax, dword [forcedeth_linkspeed] |
||
2588 | and eax, 0xFFF |
||
2589 | cmp eax, NVREG_LINKSPEED_10 |
||
2590 | jne @f |
||
2591 | ; phyreg |= NVREG_RNDSEED_FORCE3 |
||
2592 | or ecx, NVREG_RNDSEED_FORCE3 |
||
2593 | jmp .end_if4 |
||
2594 | @@: |
||
2595 | ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
||
2596 | cmp eax, NVREG_LINKSPEED_100 |
||
2597 | jne @f |
||
2598 | ; phyreg |= NVREG_RNDSEED_FORCE2 |
||
2599 | or ecx, NVREG_RNDSEED_FORCE2 |
||
2600 | jmp .end_if4 |
||
2601 | @@: |
||
2602 | ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
||
2603 | cmp eax, NVREG_LINKSPEED_1000 |
||
2604 | jne .end_if4 |
||
2605 | ; phyreg |= NVREG_RNDSEED_FORCE |
||
2606 | or ecx, NVREG_RNDSEED_FORCE |
||
2607 | .end_if4: |
||
2608 | ; writel(phyreg, base + NvRegRandomSeed) |
||
2609 | mov dword [edi+NvRegRandomSeed], ecx |
||
2610 | |||
2611 | .end_if3: |
||
2612 | |||
2613 | ; phyreg = readl(base + NvRegPhyInterface) |
||
2614 | mov ecx, dword [edi+NvRegPhyInterface] |
||
2615 | |||
2616 | ; phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000) |
||
2617 | and ecx, not (PHY_HALF or PHY_100 or PHY_1000) |
||
2618 | |||
2619 | ; if (np->duplex == 0) |
||
2620 | cmp dword [forcedeth_duplex], 0 |
||
2621 | jne @f |
||
2622 | ; phyreg |= PHY_HALF |
||
2623 | or ecx, PHY_HALF |
||
2624 | @@: |
||
2625 | ; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
||
2626 | mov eax, dword [forcedeth_linkspeed] |
||
2627 | and eax, 0xFFF |
||
2628 | cmp eax, NVREG_LINKSPEED_100 |
||
2629 | jne @f |
||
2630 | ; phyreg |= PHY_100 |
||
2631 | or ecx, PHY_100 |
||
2632 | jmp .end_if5 |
||
2633 | @@: |
||
2634 | ; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
||
2635 | cmp eax, NVREG_LINKSPEED_1000 |
||
2636 | jne .end_if5 |
||
2637 | ; phyreg |= PHY_1000 |
||
2638 | or ecx, PHY_1000 |
||
2639 | |||
2640 | .end_if5: |
||
2641 | |||
2642 | ; writel(phyreg, base + NvRegPhyInterface) |
||
2643 | mov dword [edi+NvRegPhyInterface], ecx |
||
2644 | |||
2645 | ; writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); |
||
2646 | cmp dword [forcedeth_duplex], 0 |
||
2647 | je @f |
||
2648 | mov ecx, 0 |
||
2649 | jmp .next |
||
2650 | @@: |
||
2651 | mov ecx, NVREG_MISC1_HD |
||
2652 | .next: |
||
2653 | or ecx, NVREG_MISC1_FORCE |
||
2654 | mov dword [edi+NvRegMisc1], ecx |
||
2655 | |||
2656 | ; pci_push(base) |
||
2657 | call forcedeth_pci_push |
||
2658 | |||
2659 | ; writel(np->linkspeed, base + NvRegLinkSpeed) |
||
2660 | mov eax, dword [forcedeth_linkspeed] |
||
2661 | mov dword [edi+NvRegLinkSpeed], eax |
||
2662 | |||
2663 | ; pci_push(base) |
||
2664 | call forcedeth_pci_push |
||
2665 | |||
2666 | .return: |
||
2667 | ; return retval |
||
2668 | mov eax, dword [forcedeth_tmp_retval] |
||
2669 | pop edi esi ecx ebx |
||
2670 | ret |
||
2671 | |||
2672 | |||
2673 | ; Input: none |
||
2674 | ; Output: none |
||
2675 | forcedeth_start_tx: |
||
2676 | push edi |
||
2677 | ; dprintf(("start_tx\n")) |
||
2678 | DEBUGF 1," K : FORCEDETH: start_tx.\n" |
||
2679 | |||
2680 | ; writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl) |
||
2681 | mov edi, dword [forcedeth_mapio_addr] |
||
2682 | mov dword [edi+NvRegTransmitterControl], NVREG_XMITCTL_START |
||
2683 | |||
2684 | ; pci_push(base) |
||
2685 | call forcedeth_pci_push |
||
2686 | |||
2687 | .return: |
||
2688 | pop edi |
||
2689 | ret |
||
2690 | |||
2691 | ; Interrupt handler |
||
2692 | forcedeth_int_handler: |
||
2693 | DEBUGF 1," K : FORCEDETH: interrupt handler.\n" |
||
2694 | |||
2695 | ret30;i++)>>>>><>>><>>>=>><>><>><> |
||
2696 |