|
Line
Link Here
|
| 0 |
-- a/drivers/net/forcedeth.c 2004-11-17 13:03:34 -08:00 |
0 |
++ b/drivers/net/forcedeth.c 2004-11-17 13:03:34 -08:00 |
|
Lines 10-17
Link Here
|
| 10 |
* trademarks of NVIDIA Corporation in the United States and other |
10 |
* trademarks of NVIDIA Corporation in the United States and other |
| 11 |
* countries. |
11 |
* countries. |
| 12 |
* |
12 |
* |
| 13 |
* Copyright (C) 2003 Manfred Spraul |
13 |
* Copyright (C) 2003,4 Manfred Spraul |
| 14 |
* Copyright (C) 2004 Andrew de Quincey (wol support) |
14 |
* Copyright (C) 2004 Andrew de Quincey (wol support) |
|
|
15 |
* Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane |
| 16 |
* IRQ rate fixes, bigendian fixes, cleanups, verification) |
| 17 |
* Copyright (c) 2004 NVIDIA Corporation |
| 15 |
* |
18 |
* |
| 16 |
* This program is free software; you can redistribute it and/or modify |
19 |
* This program is free software; you can redistribute it and/or modify |
| 17 |
* it under the terms of the GNU General Public License as published by |
20 |
* it under the terms of the GNU General Public License as published by |
|
Lines 60-74
Link Here
|
| 60 |
* 0.19: 29 Nov 2003: Handle RxNoBuf, detect & handle invalid mac |
63 |
* 0.19: 29 Nov 2003: Handle RxNoBuf, detect & handle invalid mac |
| 61 |
* addresses, really stop rx if already running |
64 |
* addresses, really stop rx if already running |
| 62 |
* in nv_start_rx, clean up a bit. |
65 |
* in nv_start_rx, clean up a bit. |
| 63 |
* (C) Carl-Daniel Hailfinger |
|
|
| 64 |
* 0.20: 07 Dec 2003: alloc fixes |
66 |
* 0.20: 07 Dec 2003: alloc fixes |
| 65 |
* 0.21: 12 Jan 2004: additional alloc fix, nic polling fix. |
67 |
* 0.21: 12 Jan 2004: additional alloc fix, nic polling fix. |
| 66 |
* 0.22: 19 Jan 2004: reprogram timer to a sane rate, avoid lockup |
68 |
* 0.22: 19 Jan 2004: reprogram timer to a sane rate, avoid lockup |
| 67 |
* on close. |
69 |
* on close. |
| 68 |
* (C) Carl-Daniel Hailfinger, Manfred Spraul |
|
|
| 69 |
* 0.23: 26 Jan 2004: various small cleanups |
70 |
* 0.23: 26 Jan 2004: various small cleanups |
| 70 |
* 0.24: 27 Feb 2004: make driver even less anonymous in backtraces |
71 |
* 0.24: 27 Feb 2004: make driver even less anonymous in backtraces |
| 71 |
* 0.25: 09 Mar 2004: wol support |
72 |
* 0.25: 09 Mar 2004: wol support |
|
|
73 |
* 0.26: 03 Jun 2004: netdriver specific annotation, sparse-related fixes |
| 74 |
* 0.27: 19 Jun 2004: Gigabit support, new descriptor rings, |
| 75 |
* added CK804/MCP04 device IDs, code fixes |
| 76 |
* for registers, link status and other minor fixes. |
| 77 |
* 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe |
| 78 |
* 0.29: 31 Aug 2004: Add backup timer for link change notification. |
| 79 |
* 0.30: 25 Sep 2004: rx checksum support for nf 250 Gb. Add rx reset |
| 80 |
* into nv_close, otherwise reenabling for wol can |
| 81 |
* cause DMA to kfree'd memory. |
| 72 |
* |
82 |
* |
| 73 |
* Known bugs: |
83 |
* Known bugs: |
| 74 |
* We suspect that on some hardware no TX done interrupts are generated. |
84 |
* We suspect that on some hardware no TX done interrupts are generated. |
|
Lines 80-88
Link Here
|
| 80 |
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
90 |
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
| 81 |
* superfluous timer interrupts from the nic. |
91 |
* superfluous timer interrupts from the nic. |
| 82 |
*/ |
92 |
*/ |
| 83 |
#define FORCEDETH_VERSION "0.25" |
93 |
#define FORCEDETH_VERSION "0.30" |
|
|
94 |
#define DRV_NAME "forcedeth" |
| 84 |
|
95 |
|
| 85 |
#include <linux/module.h> |
96 |
#include <linux/module.h> |
|
|
97 |
#include <linux/moduleparam.h> |
| 86 |
#include <linux/types.h> |
98 |
#include <linux/types.h> |
| 87 |
#include <linux/pci.h> |
99 |
#include <linux/pci.h> |
| 88 |
#include <linux/interrupt.h> |
100 |
#include <linux/interrupt.h> |
|
Lines 113-128
Link Here
|
| 113 |
* Hardware access: |
125 |
* Hardware access: |
| 114 |
*/ |
126 |
*/ |
| 115 |
|
127 |
|
| 116 |
#define DEV_NEED_LASTPACKET1 0x0001 |
128 |
#define DEV_NEED_LASTPACKET1 0x0001 /* set LASTPACKET1 in tx flags */ |
| 117 |
#define DEV_IRQMASK_1 0x0002 |
129 |
#define DEV_IRQMASK_1 0x0002 /* use NVREG_IRQMASK_WANTED_1 for irq mask */ |
| 118 |
#define DEV_IRQMASK_2 0x0004 |
130 |
#define DEV_IRQMASK_2 0x0004 /* use NVREG_IRQMASK_WANTED_2 for irq mask */ |
| 119 |
#define DEV_NEED_TIMERIRQ 0x0008 |
131 |
#define DEV_NEED_TIMERIRQ 0x0008 /* set the timer irq flag in the irq mask */ |
|
|
132 |
#define DEV_NEED_LINKTIMER 0x0010 /* poll link settings. Relies on the timer irq */ |
| 120 |
|
133 |
|
| 121 |
enum { |
134 |
enum { |
| 122 |
NvRegIrqStatus = 0x000, |
135 |
NvRegIrqStatus = 0x000, |
| 123 |
#define NVREG_IRQSTAT_MIIEVENT 0x040 |
136 |
#define NVREG_IRQSTAT_MIIEVENT 0x040 |
| 124 |
#define NVREG_IRQSTAT_MASK 0x1ff |
137 |
#define NVREG_IRQSTAT_MASK 0x1ff |
| 125 |
NvRegIrqMask = 0x004, |
138 |
NvRegIrqMask = 0x004, |
|
|
139 |
#define NVREG_IRQ_RX_ERROR 0x0001 |
| 126 |
#define NVREG_IRQ_RX 0x0002 |
140 |
#define NVREG_IRQ_RX 0x0002 |
| 127 |
#define NVREG_IRQ_RX_NOBUF 0x0004 |
141 |
#define NVREG_IRQ_RX_NOBUF 0x0004 |
| 128 |
#define NVREG_IRQ_TX_ERR 0x0008 |
142 |
#define NVREG_IRQ_TX_ERR 0x0008 |
|
Lines 132-138
Link Here
|
| 132 |
#define NVREG_IRQ_TX1 0x0100 |
146 |
#define NVREG_IRQ_TX1 0x0100 |
| 133 |
#define NVREG_IRQMASK_WANTED_1 0x005f |
147 |
#define NVREG_IRQMASK_WANTED_1 0x005f |
| 134 |
#define NVREG_IRQMASK_WANTED_2 0x0147 |
148 |
#define NVREG_IRQMASK_WANTED_2 0x0147 |
| 135 |
#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) |
149 |
#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) |
| 136 |
|
150 |
|
| 137 |
NvRegUnknownSetupReg6 = 0x008, |
151 |
NvRegUnknownSetupReg6 = 0x008, |
| 138 |
#define NVREG_UNKSETUP6_VAL 3 |
152 |
#define NVREG_UNKSETUP6_VAL 3 |
|
Lines 159-165
Link Here
|
| 159 |
|
173 |
|
| 160 |
NvRegOffloadConfig = 0x90, |
174 |
NvRegOffloadConfig = 0x90, |
| 161 |
#define NVREG_OFFLOAD_HOMEPHY 0x601 |
175 |
#define NVREG_OFFLOAD_HOMEPHY 0x601 |
| 162 |
#define NVREG_OFFLOAD_NORMAL 0x5ee |
176 |
#define NVREG_OFFLOAD_NORMAL RX_NIC_BUFSIZE |
| 163 |
NvRegReceiverControl = 0x094, |
177 |
NvRegReceiverControl = 0x094, |
| 164 |
#define NVREG_RCVCTL_START 0x01 |
178 |
#define NVREG_RCVCTL_START 0x01 |
| 165 |
NvRegReceiverStatus = 0x98, |
179 |
NvRegReceiverStatus = 0x98, |
|
Lines 168-173
Link Here
|
| 168 |
NvRegRandomSeed = 0x9c, |
182 |
NvRegRandomSeed = 0x9c, |
| 169 |
#define NVREG_RNDSEED_MASK 0x00ff |
183 |
#define NVREG_RNDSEED_MASK 0x00ff |
| 170 |
#define NVREG_RNDSEED_FORCE 0x7f00 |
184 |
#define NVREG_RNDSEED_FORCE 0x7f00 |
|
|
185 |
#define NVREG_RNDSEED_FORCE2 0x2d00 |
| 186 |
#define NVREG_RNDSEED_FORCE3 0x7400 |
| 171 |
|
187 |
|
| 172 |
NvRegUnknownSetupReg1 = 0xA0, |
188 |
NvRegUnknownSetupReg1 = 0xA0, |
| 173 |
#define NVREG_UNKSETUP1_VAL 0x16070f |
189 |
#define NVREG_UNKSETUP1_VAL 0x16070f |
|
Lines 181-186
Link Here
|
| 181 |
NvRegMulticastMaskA = 0xB8, |
197 |
NvRegMulticastMaskA = 0xB8, |
| 182 |
NvRegMulticastMaskB = 0xBC, |
198 |
NvRegMulticastMaskB = 0xBC, |
| 183 |
|
199 |
|
|
|
200 |
NvRegPhyInterface = 0xC0, |
| 201 |
#define PHY_RGMII 0x10000000 |
| 202 |
|
| 184 |
NvRegTxRingPhysAddr = 0x100, |
203 |
NvRegTxRingPhysAddr = 0x100, |
| 185 |
NvRegRxRingPhysAddr = 0x104, |
204 |
NvRegRxRingPhysAddr = 0x104, |
| 186 |
NvRegRingSizes = 0x108, |
205 |
NvRegRingSizes = 0x108, |
|
Lines 189-200
Link Here
|
| 189 |
NvRegUnknownTransmitterReg = 0x10c, |
208 |
NvRegUnknownTransmitterReg = 0x10c, |
| 190 |
NvRegLinkSpeed = 0x110, |
209 |
NvRegLinkSpeed = 0x110, |
| 191 |
#define NVREG_LINKSPEED_FORCE 0x10000 |
210 |
#define NVREG_LINKSPEED_FORCE 0x10000 |
| 192 |
#define NVREG_LINKSPEED_10 10 |
211 |
#define NVREG_LINKSPEED_10 1000 |
| 193 |
#define NVREG_LINKSPEED_100 100 |
212 |
#define NVREG_LINKSPEED_100 100 |
| 194 |
#define NVREG_LINKSPEED_1000 1000 |
213 |
#define NVREG_LINKSPEED_1000 50 |
| 195 |
NvRegUnknownSetupReg5 = 0x130, |
214 |
NvRegUnknownSetupReg5 = 0x130, |
| 196 |
#define NVREG_UNKSETUP5_BIT31 (1<<31) |
215 |
#define NVREG_UNKSETUP5_BIT31 (1<<31) |
| 197 |
NvRegUnknownSetupReg3 = 0x134, |
216 |
NvRegUnknownSetupReg3 = 0x13c, |
| 198 |
#define NVREG_UNKSETUP3_VAL1 0x200010 |
217 |
#define NVREG_UNKSETUP3_VAL1 0x200010 |
| 199 |
NvRegTxRxControl = 0x144, |
218 |
NvRegTxRxControl = 0x144, |
| 200 |
#define NVREG_TXRXCTL_KICK 0x0001 |
219 |
#define NVREG_TXRXCTL_KICK 0x0001 |
|
Lines 202-207
Link Here
|
| 202 |
#define NVREG_TXRXCTL_BIT2 0x0004 |
221 |
#define NVREG_TXRXCTL_BIT2 0x0004 |
| 203 |
#define NVREG_TXRXCTL_IDLE 0x0008 |
222 |
#define NVREG_TXRXCTL_IDLE 0x0008 |
| 204 |
#define NVREG_TXRXCTL_RESET 0x0010 |
223 |
#define NVREG_TXRXCTL_RESET 0x0010 |
|
|
224 |
#define NVREG_TXRXCTL_RXCHECK 0x0400 |
| 205 |
NvRegMIIStatus = 0x180, |
225 |
NvRegMIIStatus = 0x180, |
| 206 |
#define NVREG_MIISTAT_ERROR 0x0001 |
226 |
#define NVREG_MIISTAT_ERROR 0x0001 |
| 207 |
#define NVREG_MIISTAT_LINKCHANGE 0x0008 |
227 |
#define NVREG_MIISTAT_LINKCHANGE 0x0008 |
|
Lines 213-227
Link Here
|
| 213 |
NvRegAdapterControl = 0x188, |
233 |
NvRegAdapterControl = 0x188, |
| 214 |
#define NVREG_ADAPTCTL_START 0x02 |
234 |
#define NVREG_ADAPTCTL_START 0x02 |
| 215 |
#define NVREG_ADAPTCTL_LINKUP 0x04 |
235 |
#define NVREG_ADAPTCTL_LINKUP 0x04 |
| 216 |
#define NVREG_ADAPTCTL_PHYVALID 0x4000 |
236 |
#define NVREG_ADAPTCTL_PHYVALID 0x40000 |
| 217 |
#define NVREG_ADAPTCTL_RUNNING 0x100000 |
237 |
#define NVREG_ADAPTCTL_RUNNING 0x100000 |
| 218 |
#define NVREG_ADAPTCTL_PHYSHIFT 24 |
238 |
#define NVREG_ADAPTCTL_PHYSHIFT 24 |
| 219 |
NvRegMIISpeed = 0x18c, |
239 |
NvRegMIISpeed = 0x18c, |
| 220 |
#define NVREG_MIISPEED_BIT8 (1<<8) |
240 |
#define NVREG_MIISPEED_BIT8 (1<<8) |
| 221 |
#define NVREG_MIIDELAY 5 |
241 |
#define NVREG_MIIDELAY 5 |
| 222 |
NvRegMIIControl = 0x190, |
242 |
NvRegMIIControl = 0x190, |
| 223 |
#define NVREG_MIICTL_INUSE 0x10000 |
243 |
#define NVREG_MIICTL_INUSE 0x08000 |
| 224 |
#define NVREG_MIICTL_WRITE 0x08000 |
244 |
#define NVREG_MIICTL_WRITE 0x00400 |
| 225 |
#define NVREG_MIICTL_ADDRSHIFT 5 |
245 |
#define NVREG_MIICTL_ADDRSHIFT 5 |
| 226 |
NvRegMIIData = 0x194, |
246 |
NvRegMIIData = 0x194, |
| 227 |
NvRegWakeUpFlags = 0x200, |
247 |
NvRegWakeUpFlags = 0x200, |
|
Lines 253-286
Link Here
|
| 253 |
#define NVREG_POWERSTATE_D3 0x0003 |
273 |
#define NVREG_POWERSTATE_D3 0x0003 |
| 254 |
}; |
274 |
}; |
| 255 |
|
275 |
|
|
|
276 |
/* Big endian: should work, but is untested */ |
| 256 |
struct ring_desc { |
277 |
struct ring_desc { |
| 257 |
u32 PacketBuffer; |
278 |
u32 PacketBuffer; |
| 258 |
u16 Length; |
279 |
u32 FlagLen; |
| 259 |
u16 Flags; |
|
|
| 260 |
}; |
280 |
}; |
| 261 |
|
281 |
|
| 262 |
#define NV_TX_LASTPACKET (1<<0) |
282 |
#define FLAG_MASK_V1 0xffff0000 |
| 263 |
#define NV_TX_RETRYERROR (1<<3) |
283 |
#define FLAG_MASK_V2 0xffffc000 |
| 264 |
#define NV_TX_LASTPACKET1 (1<<8) |
284 |
#define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) |
| 265 |
#define NV_TX_DEFERRED (1<<10) |
285 |
#define LEN_MASK_V2 (0xffffffff ^ FLAG_MASK_V2) |
| 266 |
#define NV_TX_CARRIERLOST (1<<11) |
286 |
|
| 267 |
#define NV_TX_LATECOLLISION (1<<12) |
287 |
#define NV_TX_LASTPACKET (1<<16) |
| 268 |
#define NV_TX_UNDERFLOW (1<<13) |
288 |
#define NV_TX_RETRYERROR (1<<19) |
| 269 |
#define NV_TX_ERROR (1<<14) |
289 |
#define NV_TX_LASTPACKET1 (1<<24) |
| 270 |
#define NV_TX_VALID (1<<15) |
290 |
#define NV_TX_DEFERRED (1<<26) |
| 271 |
|
291 |
#define NV_TX_CARRIERLOST (1<<27) |
| 272 |
#define NV_RX_DESCRIPTORVALID (1<<0) |
292 |
#define NV_TX_LATECOLLISION (1<<28) |
| 273 |
#define NV_RX_MISSEDFRAME (1<<1) |
293 |
#define NV_TX_UNDERFLOW (1<<29) |
| 274 |
#define NV_RX_SUBSTRACT1 (1<<3) |
294 |
#define NV_TX_ERROR (1<<30) |
| 275 |
#define NV_RX_ERROR1 (1<<7) |
295 |
#define NV_TX_VALID (1<<31) |
| 276 |
#define NV_RX_ERROR2 (1<<8) |
296 |
|
| 277 |
#define NV_RX_ERROR3 (1<<9) |
297 |
#define NV_TX2_LASTPACKET (1<<29) |
| 278 |
#define NV_RX_ERROR4 (1<<10) |
298 |
#define NV_TX2_RETRYERROR (1<<18) |
| 279 |
#define NV_RX_CRCERR (1<<11) |
299 |
#define NV_TX2_LASTPACKET1 (1<<23) |
| 280 |
#define NV_RX_OVERFLOW (1<<12) |
300 |
#define NV_TX2_DEFERRED (1<<25) |
| 281 |
#define NV_RX_FRAMINGERR (1<<13) |
301 |
#define NV_TX2_CARRIERLOST (1<<26) |
| 282 |
#define NV_RX_ERROR (1<<14) |
302 |
#define NV_TX2_LATECOLLISION (1<<27) |
| 283 |
#define NV_RX_AVAIL (1<<15) |
303 |
#define NV_TX2_UNDERFLOW (1<<28) |
|
|
304 |
/* error and valid are the same for both */ |
| 305 |
#define NV_TX2_ERROR (1<<30) |
| 306 |
#define NV_TX2_VALID (1<<31) |
| 307 |
|
| 308 |
#define NV_RX_DESCRIPTORVALID (1<<16) |
| 309 |
#define NV_RX_MISSEDFRAME (1<<17) |
| 310 |
#define NV_RX_SUBSTRACT1 (1<<18) |
| 311 |
#define NV_RX_ERROR1 (1<<23) |
| 312 |
#define NV_RX_ERROR2 (1<<24) |
| 313 |
#define NV_RX_ERROR3 (1<<25) |
| 314 |
#define NV_RX_ERROR4 (1<<26) |
| 315 |
#define NV_RX_CRCERR (1<<27) |
| 316 |
#define NV_RX_OVERFLOW (1<<28) |
| 317 |
#define NV_RX_FRAMINGERR (1<<29) |
| 318 |
#define NV_RX_ERROR (1<<30) |
| 319 |
#define NV_RX_AVAIL (1<<31) |
| 320 |
|
| 321 |
#define NV_RX2_CHECKSUMMASK (0x1C000000) |
| 322 |
#define NV_RX2_CHECKSUMOK1 (0x10000000) |
| 323 |
#define NV_RX2_CHECKSUMOK2 (0x14000000) |
| 324 |
#define NV_RX2_CHECKSUMOK3 (0x18000000) |
| 325 |
#define NV_RX2_DESCRIPTORVALID (1<<29) |
| 326 |
#define NV_RX2_SUBSTRACT1 (1<<25) |
| 327 |
#define NV_RX2_ERROR1 (1<<18) |
| 328 |
#define NV_RX2_ERROR2 (1<<19) |
| 329 |
#define NV_RX2_ERROR3 (1<<20) |
| 330 |
#define NV_RX2_ERROR4 (1<<21) |
| 331 |
#define NV_RX2_CRCERR (1<<22) |
| 332 |
#define NV_RX2_OVERFLOW (1<<23) |
| 333 |
#define NV_RX2_FRAMINGERR (1<<24) |
| 334 |
/* error and avail are the same for both */ |
| 335 |
#define NV_RX2_ERROR (1<<30) |
| 336 |
#define NV_RX2_AVAIL (1<<31) |
| 284 |
|
337 |
|
| 285 |
/* Miscelaneous hardware related defines: */ |
338 |
/* Miscelaneous hardware related defines: */ |
| 286 |
#define NV_PCI_REGSZ 0x270 |
339 |
#define NV_PCI_REGSZ 0x270 |
|
Lines 306-333
Link Here
|
| 306 |
|
359 |
|
| 307 |
/* General driver defaults */ |
360 |
/* General driver defaults */ |
| 308 |
#define NV_WATCHDOG_TIMEO (5*HZ) |
361 |
#define NV_WATCHDOG_TIMEO (5*HZ) |
| 309 |
#define DEFAULT_MTU 1500 /* also maximum supported, at least for now */ |
|
|
| 310 |
|
362 |
|
| 311 |
#define RX_RING 128 |
363 |
#define RX_RING 128 |
| 312 |
#define TX_RING 16 |
364 |
#define TX_RING 64 |
| 313 |
/* limited to 1 packet until we understand NV_TX_LASTPACKET */ |
365 |
/* |
| 314 |
#define TX_LIMIT_STOP 10 |
366 |
* If your nic mysteriously hangs then try to reduce the limits |
| 315 |
#define TX_LIMIT_START 5 |
367 |
* to 1/0: It might be required to set NV_TX_LASTPACKET in the |
|
|
368 |
* last valid ring entry. But this would be impossible to |
| 369 |
* implement - probably a disassembly error. |
| 370 |
*/ |
| 371 |
#define TX_LIMIT_STOP 63 |
| 372 |
#define TX_LIMIT_START 62 |
| 316 |
|
373 |
|
| 317 |
/* rx/tx mac addr + type + vlan + align + slack*/ |
374 |
/* rx/tx mac addr + type + vlan + align + slack*/ |
| 318 |
#define RX_NIC_BUFSIZE (DEFAULT_MTU + 64) |
375 |
#define RX_NIC_BUFSIZE (ETH_DATA_LEN + 64) |
| 319 |
/* even more slack */ |
376 |
/* even more slack */ |
| 320 |
#define RX_ALLOC_BUFSIZE (DEFAULT_MTU + 128) |
377 |
#define RX_ALLOC_BUFSIZE (ETH_DATA_LEN + 128) |
| 321 |
|
378 |
|
| 322 |
#define OOM_REFILL (1+HZ/20) |
379 |
#define OOM_REFILL (1+HZ/20) |
| 323 |
#define POLL_WAIT (1+HZ/100) |
380 |
#define POLL_WAIT (1+HZ/100) |
|
|
381 |
#define LINK_TIMEOUT (3*HZ) |
| 382 |
|
| 383 |
/* |
| 384 |
* desc_ver values: |
| 385 |
* This field has two purposes: |
| 386 |
* - Newer nics uses a different ring layout. The layout is selected by |
| 387 |
* comparing np->desc_ver with DESC_VER_xy. |
| 388 |
* - It contains bits that are forced on when writing to NvRegTxRxControl. |
| 389 |
*/ |
| 390 |
#define DESC_VER_1 0x0 |
| 391 |
#define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK) |
| 392 |
|
| 393 |
/* PHY defines */ |
| 394 |
#define PHY_OUI_MARVELL 0x5043 |
| 395 |
#define PHY_OUI_CICADA 0x03f1 |
| 396 |
#define PHYID1_OUI_MASK 0x03ff |
| 397 |
#define PHYID1_OUI_SHFT 6 |
| 398 |
#define PHYID2_OUI_MASK 0xfc00 |
| 399 |
#define PHYID2_OUI_SHFT 10 |
| 400 |
#define PHY_INIT1 0x0f000 |
| 401 |
#define PHY_INIT2 0x0e00 |
| 402 |
#define PHY_INIT3 0x01000 |
| 403 |
#define PHY_INIT4 0x0200 |
| 404 |
#define PHY_INIT5 0x0004 |
| 405 |
#define PHY_INIT6 0x02000 |
| 406 |
#define PHY_GIGABIT 0x0100 |
| 407 |
|
| 408 |
#define PHY_TIMEOUT 0x1 |
| 409 |
#define PHY_ERROR 0x2 |
| 410 |
|
| 411 |
#define PHY_100 0x1 |
| 412 |
#define PHY_1000 0x2 |
| 413 |
#define PHY_HALF 0x100 |
| 414 |
|
| 415 |
/* FIXME: MII defines that should be added to <linux/mii.h> */ |
| 416 |
#define MII_1000BT_CR 0x09 |
| 417 |
#define MII_1000BT_SR 0x0a |
| 418 |
#define ADVERTISE_1000FULL 0x0200 |
| 419 |
#define ADVERTISE_1000HALF 0x0100 |
| 420 |
#define LPA_1000FULL 0x0800 |
| 421 |
#define LPA_1000HALF 0x0400 |
| 422 |
|
| 324 |
|
423 |
|
| 325 |
/* |
424 |
/* |
| 326 |
* SMP locking: |
425 |
* SMP locking: |
| 327 |
* All hardware access under dev->priv->lock, except the performance |
426 |
* All hardware access under dev->priv->lock, except the performance |
| 328 |
* critical parts: |
427 |
* critical parts: |
| 329 |
* - rx is (pseudo-) lockless: it relies on the single-threading provided |
428 |
* - rx is (pseudo-) lockless: it relies on the single-threading provided |
| 330 |
* by the arch code for interrupts. |
429 |
* by the arch code for interrupts. |
| 331 |
* - tx setup is lockless: it relies on dev->xmit_lock. Actual submission |
430 |
* - tx setup is lockless: it relies on dev->xmit_lock. Actual submission |
| 332 |
* needs dev->priv->lock :-( |
431 |
* needs dev->priv->lock :-( |
| 333 |
* - set_multicast_list: preparation lockless, relies on dev->xmit_lock. |
432 |
* - set_multicast_list: preparation lockless, relies on dev->xmit_lock. |
|
Lines 345-356
Link Here
|
| 345 |
int duplex; |
444 |
int duplex; |
| 346 |
int phyaddr; |
445 |
int phyaddr; |
| 347 |
int wolenabled; |
446 |
int wolenabled; |
|
|
447 |
unsigned int phy_oui; |
| 448 |
u16 gigabit; |
| 348 |
|
449 |
|
| 349 |
/* General data: RO fields */ |
450 |
/* General data: RO fields */ |
| 350 |
dma_addr_t ring_addr; |
451 |
dma_addr_t ring_addr; |
| 351 |
struct pci_dev *pci_dev; |
452 |
struct pci_dev *pci_dev; |
| 352 |
u32 orig_mac[2]; |
453 |
u32 orig_mac[2]; |
| 353 |
u32 irqmask; |
454 |
u32 irqmask; |
|
|
455 |
u32 desc_ver; |
| 354 |
|
456 |
|
| 355 |
/* rx specific fields. |
457 |
/* rx specific fields. |
| 356 |
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock); |
458 |
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock); |
|
Lines 363-368
Link Here
|
| 363 |
struct timer_list oom_kick; |
465 |
struct timer_list oom_kick; |
| 364 |
struct timer_list nic_poll; |
466 |
struct timer_list nic_poll; |
| 365 |
|
467 |
|
|
|
468 |
/* media detection workaround. |
| 469 |
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock); |
| 470 |
*/ |
| 471 |
int need_linktimer; |
| 472 |
unsigned long link_timeout; |
| 366 |
/* |
473 |
/* |
| 367 |
* tx specific fields. |
474 |
* tx specific fields. |
| 368 |
*/ |
475 |
*/ |
|
Lines 370-376
Link Here
|
| 370 |
unsigned int next_tx, nic_tx; |
477 |
unsigned int next_tx, nic_tx; |
| 371 |
struct sk_buff *tx_skbuff[TX_RING]; |
478 |
struct sk_buff *tx_skbuff[TX_RING]; |
| 372 |
dma_addr_t tx_dma[TX_RING]; |
479 |
dma_addr_t tx_dma[TX_RING]; |
| 373 |
u16 tx_flags; |
480 |
u32 tx_flags; |
| 374 |
}; |
481 |
}; |
| 375 |
|
482 |
|
| 376 |
/* |
483 |
/* |
|
Lines 395-400
Link Here
|
| 395 |
readl(base); |
502 |
readl(base); |
| 396 |
} |
503 |
} |
| 397 |
|
504 |
|
|
|
505 |
static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v) |
| 506 |
{ |
| 507 |
return le32_to_cpu(prd->FlagLen) |
| 508 |
& ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); |
| 509 |
} |
| 510 |
|
| 398 |
static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, |
511 |
static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, |
| 399 |
int delay, int delaymax, const char *msg) |
512 |
int delay, int delaymax, const char *msg) |
| 400 |
{ |
513 |
{ |
|
Lines 421-444
Link Here
|
| 421 |
static int mii_rw(struct net_device *dev, int addr, int miireg, int value) |
534 |
static int mii_rw(struct net_device *dev, int addr, int miireg, int value) |
| 422 |
{ |
535 |
{ |
| 423 |
u8 *base = get_hwbase(dev); |
536 |
u8 *base = get_hwbase(dev); |
| 424 |
int was_running; |
|
|
| 425 |
u32 reg; |
537 |
u32 reg; |
| 426 |
int retval; |
538 |
int retval; |
| 427 |
|
539 |
|
| 428 |
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
540 |
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
| 429 |
was_running = 0; |
541 |
|
| 430 |
reg = readl(base + NvRegAdapterControl); |
|
|
| 431 |
if (reg & NVREG_ADAPTCTL_RUNNING) { |
| 432 |
was_running = 1; |
| 433 |
writel(reg & ~NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); |
| 434 |
} |
| 435 |
reg = readl(base + NvRegMIIControl); |
542 |
reg = readl(base + NvRegMIIControl); |
| 436 |
if (reg & NVREG_MIICTL_INUSE) { |
543 |
if (reg & NVREG_MIICTL_INUSE) { |
| 437 |
writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl); |
544 |
writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl); |
| 438 |
udelay(NV_MIIBUSY_DELAY); |
545 |
udelay(NV_MIIBUSY_DELAY); |
| 439 |
} |
546 |
} |
| 440 |
|
547 |
|
| 441 |
reg = NVREG_MIICTL_INUSE | (addr << NVREG_MIICTL_ADDRSHIFT) | miireg; |
548 |
reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg; |
| 442 |
if (value != MII_READ) { |
549 |
if (value != MII_READ) { |
| 443 |
writel(value, base + NvRegMIIData); |
550 |
writel(value, base + NvRegMIIData); |
| 444 |
reg |= NVREG_MIICTL_WRITE; |
551 |
reg |= NVREG_MIICTL_WRITE; |
|
Lines 460-478
Link Here
|
| 460 |
dev->name, miireg, addr); |
567 |
dev->name, miireg, addr); |
| 461 |
retval = -1; |
568 |
retval = -1; |
| 462 |
} else { |
569 |
} else { |
| 463 |
/* FIXME: why is that required? */ |
|
|
| 464 |
udelay(50); |
| 465 |
retval = readl(base + NvRegMIIData); |
570 |
retval = readl(base + NvRegMIIData); |
| 466 |
dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n", |
571 |
dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n", |
| 467 |
dev->name, miireg, addr, retval); |
572 |
dev->name, miireg, addr, retval); |
| 468 |
} |
573 |
} |
| 469 |
if (was_running) { |
574 |
|
| 470 |
reg = readl(base + NvRegAdapterControl); |
|
|
| 471 |
writel(reg | NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); |
| 472 |
} |
| 473 |
return retval; |
575 |
return retval; |
| 474 |
} |
576 |
} |
| 475 |
|
577 |
|
|
|
578 |
static void msleep(unsigned long msecs) |
| 579 |
{ |
| 580 |
set_current_state(TASK_UNINTERRUPTIBLE); |
| 581 |
schedule_timeout((HZ * msecs + 999) / 1000); |
| 582 |
} |
| 583 |
|
| 584 |
static int phy_reset(struct net_device *dev) |
| 585 |
{ |
| 586 |
struct fe_priv *np = get_nvpriv(dev); |
| 587 |
u32 miicontrol; |
| 588 |
unsigned int tries = 0; |
| 589 |
|
| 590 |
miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); |
| 591 |
miicontrol |= BMCR_RESET; |
| 592 |
if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) { |
| 593 |
return -1; |
| 594 |
} |
| 595 |
|
| 596 |
/* wait for 500ms */ |
| 597 |
msleep(500); |
| 598 |
|
| 599 |
/* must wait till reset is deasserted */ |
| 600 |
while (miicontrol & BMCR_RESET) { |
| 601 |
msleep(10); |
| 602 |
miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); |
| 603 |
/* FIXME: 100 tries seem excessive */ |
| 604 |
if (tries++ > 100) |
| 605 |
return -1; |
| 606 |
} |
| 607 |
return 0; |
| 608 |
} |
| 609 |
|
| 610 |
static int phy_init(struct net_device *dev) |
| 611 |
{ |
| 612 |
struct fe_priv *np = get_nvpriv(dev); |
| 613 |
u8 *base = get_hwbase(dev); |
| 614 |
u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg; |
| 615 |
|
| 616 |
/* set advertise register */ |
| 617 |
reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); |
| 618 |
reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|0x800|0x400); |
| 619 |
if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { |
| 620 |
printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev)); |
| 621 |
return PHY_ERROR; |
| 622 |
} |
| 623 |
|
| 624 |
/* get phy interface type */ |
| 625 |
phyinterface = readl(base + NvRegPhyInterface); |
| 626 |
|
| 627 |
/* see if gigabit phy */ |
| 628 |
mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); |
| 629 |
if (mii_status & PHY_GIGABIT) { |
| 630 |
np->gigabit = PHY_GIGABIT; |
| 631 |
mii_control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); |
| 632 |
mii_control_1000 &= ~ADVERTISE_1000HALF; |
| 633 |
if (phyinterface & PHY_RGMII) |
| 634 |
mii_control_1000 |= ADVERTISE_1000FULL; |
| 635 |
else |
| 636 |
mii_control_1000 &= ~ADVERTISE_1000FULL; |
| 637 |
|
| 638 |
if (mii_rw(dev, np->phyaddr, MII_1000BT_CR, mii_control_1000)) { |
| 639 |
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 640 |
return PHY_ERROR; |
| 641 |
} |
| 642 |
} |
| 643 |
else |
| 644 |
np->gigabit = 0; |
| 645 |
|
| 646 |
/* reset the phy */ |
| 647 |
if (phy_reset(dev)) { |
| 648 |
printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev)); |
| 649 |
return PHY_ERROR; |
| 650 |
} |
| 651 |
|
| 652 |
/* phy vendor specific configuration */ |
| 653 |
if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) { |
| 654 |
phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); |
| 655 |
phy_reserved &= ~(PHY_INIT1 | PHY_INIT2); |
| 656 |
phy_reserved |= (PHY_INIT3 | PHY_INIT4); |
| 657 |
if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) { |
| 658 |
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 659 |
return PHY_ERROR; |
| 660 |
} |
| 661 |
phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); |
| 662 |
phy_reserved |= PHY_INIT5; |
| 663 |
if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) { |
| 664 |
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 665 |
return PHY_ERROR; |
| 666 |
} |
| 667 |
} |
| 668 |
if (np->phy_oui == PHY_OUI_CICADA) { |
| 669 |
phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); |
| 670 |
phy_reserved |= PHY_INIT6; |
| 671 |
if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) { |
| 672 |
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 673 |
return PHY_ERROR; |
| 674 |
} |
| 675 |
} |
| 676 |
|
| 677 |
/* restart auto negotiation */ |
| 678 |
mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); |
| 679 |
mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); |
| 680 |
if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { |
| 681 |
return PHY_ERROR; |
| 682 |
} |
| 683 |
|
| 684 |
return 0; |
| 685 |
} |
| 686 |
|
| 476 |
static void nv_start_rx(struct net_device *dev) |
687 |
static void nv_start_rx(struct net_device *dev) |
| 477 |
{ |
688 |
{ |
| 478 |
struct fe_priv *np = get_nvpriv(dev); |
689 |
struct fe_priv *np = get_nvpriv(dev); |
|
Lines 487-492
Link Here
|
| 487 |
writel(np->linkspeed, base + NvRegLinkSpeed); |
698 |
writel(np->linkspeed, base + NvRegLinkSpeed); |
| 488 |
pci_push(base); |
699 |
pci_push(base); |
| 489 |
writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); |
700 |
writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); |
|
|
701 |
dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n", |
| 702 |
dev->name, np->duplex, np->linkspeed); |
| 490 |
pci_push(base); |
703 |
pci_push(base); |
| 491 |
} |
704 |
} |
| 492 |
|
705 |
|
|
Lines 497-504
Link Here
|
| 497 |
dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name); |
710 |
dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name); |
| 498 |
writel(0, base + NvRegReceiverControl); |
711 |
writel(0, base + NvRegReceiverControl); |
| 499 |
reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, |
712 |
reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, |
| 500 |
NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, |
713 |
NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, |
| 501 |
KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); |
714 |
KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); |
| 502 |
|
715 |
|
| 503 |
udelay(NV_RXSTOP_DELAY2); |
716 |
udelay(NV_RXSTOP_DELAY2); |
| 504 |
writel(0, base + NvRegLinkSpeed); |
717 |
writel(0, base + NvRegLinkSpeed); |
|
Lines 520-527
Link Here
|
| 520 |
dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name); |
733 |
dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name); |
| 521 |
writel(0, base + NvRegTransmitterControl); |
734 |
writel(0, base + NvRegTransmitterControl); |
| 522 |
reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, |
735 |
reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, |
| 523 |
NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, |
736 |
NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, |
| 524 |
KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); |
737 |
KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); |
| 525 |
|
738 |
|
| 526 |
udelay(NV_TXSTOP_DELAY2); |
739 |
udelay(NV_TXSTOP_DELAY2); |
| 527 |
writel(0, base + NvRegUnknownTransmitterReg); |
740 |
writel(0, base + NvRegUnknownTransmitterReg); |
|
Lines 529-541
Link Here
|
| 529 |
|
742 |
|
| 530 |
static void nv_txrx_reset(struct net_device *dev) |
743 |
static void nv_txrx_reset(struct net_device *dev) |
| 531 |
{ |
744 |
{ |
|
|
745 |
struct fe_priv *np = get_nvpriv(dev); |
| 532 |
u8 *base = get_hwbase(dev); |
746 |
u8 *base = get_hwbase(dev); |
| 533 |
|
747 |
|
| 534 |
dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name); |
748 |
dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name); |
| 535 |
writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET, base + NvRegTxRxControl); |
749 |
writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl); |
| 536 |
pci_push(base); |
750 |
pci_push(base); |
| 537 |
udelay(NV_TXRX_RESET_DELAY); |
751 |
udelay(NV_TXRX_RESET_DELAY); |
| 538 |
writel(NVREG_TXRXCTL_BIT2, base + NvRegTxRxControl); |
752 |
writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl); |
| 539 |
pci_push(base); |
753 |
pci_push(base); |
| 540 |
} |
754 |
} |
| 541 |
|
755 |
|
|
Lines 556-646
Link Here
|
| 556 |
return &np->stats; |
770 |
return &np->stats; |
| 557 |
} |
771 |
} |
| 558 |
|
772 |
|
| 559 |
static int nv_ethtool_ioctl(struct net_device *dev, void *useraddr) |
773 |
static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
| 560 |
{ |
774 |
{ |
| 561 |
struct fe_priv *np = get_nvpriv(dev); |
775 |
struct fe_priv *np = get_nvpriv(dev); |
| 562 |
u8 *base = get_hwbase(dev); |
776 |
strcpy(info->driver, "forcedeth"); |
| 563 |
u32 ethcmd; |
777 |
strcpy(info->version, FORCEDETH_VERSION); |
| 564 |
|
778 |
strcpy(info->bus_info, pci_name(np->pci_dev)); |
| 565 |
if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) |
779 |
} |
| 566 |
return -EFAULT; |
|
|
| 567 |
|
| 568 |
switch (ethcmd) { |
| 569 |
case ETHTOOL_GDRVINFO: |
| 570 |
{ |
| 571 |
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; |
| 572 |
strcpy(info.driver, "forcedeth"); |
| 573 |
strcpy(info.version, FORCEDETH_VERSION); |
| 574 |
strcpy(info.bus_info, pci_name(np->pci_dev)); |
| 575 |
if (copy_to_user(useraddr, &info, sizeof (info))) |
| 576 |
return -EFAULT; |
| 577 |
return 0; |
| 578 |
} |
| 579 |
case ETHTOOL_GLINK: |
| 580 |
{ |
| 581 |
struct ethtool_value edata = { ETHTOOL_GLINK }; |
| 582 |
|
| 583 |
edata.data = !!netif_carrier_ok(dev); |
| 584 |
|
| 585 |
if (copy_to_user(useraddr, &edata, sizeof(edata))) |
| 586 |
return -EFAULT; |
| 587 |
return 0; |
| 588 |
} |
| 589 |
case ETHTOOL_GWOL: |
| 590 |
{ |
| 591 |
struct ethtool_wolinfo wolinfo; |
| 592 |
memset(&wolinfo, 0, sizeof(wolinfo)); |
| 593 |
wolinfo.supported = WAKE_MAGIC; |
| 594 |
|
| 595 |
spin_lock_irq(&np->lock); |
| 596 |
if (np->wolenabled) |
| 597 |
wolinfo.wolopts = WAKE_MAGIC; |
| 598 |
spin_unlock_irq(&np->lock); |
| 599 |
|
| 600 |
if (copy_to_user(useraddr, &wolinfo, sizeof(wolinfo))) |
| 601 |
return -EFAULT; |
| 602 |
return 0; |
| 603 |
} |
| 604 |
case ETHTOOL_SWOL: |
| 605 |
{ |
| 606 |
struct ethtool_wolinfo wolinfo; |
| 607 |
if (copy_from_user(&wolinfo, useraddr, sizeof(wolinfo))) |
| 608 |
return -EFAULT; |
| 609 |
|
| 610 |
spin_lock_irq(&np->lock); |
| 611 |
if (wolinfo.wolopts == 0) { |
| 612 |
writel(0, base + NvRegWakeUpFlags); |
| 613 |
np->wolenabled = 0; |
| 614 |
} |
| 615 |
if (wolinfo.wolopts & WAKE_MAGIC) { |
| 616 |
writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags); |
| 617 |
np->wolenabled = 1; |
| 618 |
} |
| 619 |
spin_unlock_irq(&np->lock); |
| 620 |
return 0; |
| 621 |
} |
| 622 |
|
780 |
|
| 623 |
default: |
781 |
static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) |
| 624 |
break; |
782 |
{ |
| 625 |
} |
783 |
struct fe_priv *np = get_nvpriv(dev); |
|
|
784 |
wolinfo->supported = WAKE_MAGIC; |
| 626 |
|
785 |
|
| 627 |
return -EOPNOTSUPP; |
786 |
spin_lock_irq(&np->lock); |
|
|
787 |
if (np->wolenabled) |
| 788 |
wolinfo->wolopts = WAKE_MAGIC; |
| 789 |
spin_unlock_irq(&np->lock); |
| 628 |
} |
790 |
} |
| 629 |
/* |
791 |
|
| 630 |
* nv_ioctl: dev->do_ioctl function |
792 |
static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) |
| 631 |
* Called with rtnl_lock held. |
|
|
| 632 |
*/ |
| 633 |
static int nv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
| 634 |
{ |
793 |
{ |
| 635 |
switch(cmd) { |
794 |
struct fe_priv *np = get_nvpriv(dev); |
| 636 |
case SIOCETHTOOL: |
795 |
u8 *base = get_hwbase(dev); |
| 637 |
return nv_ethtool_ioctl(dev, (void *) rq->ifr_data); |
|
|
| 638 |
|
796 |
|
| 639 |
default: |
797 |
spin_lock_irq(&np->lock); |
| 640 |
return -EOPNOTSUPP; |
798 |
if (wolinfo->wolopts == 0) { |
|
|
799 |
writel(0, base + NvRegWakeUpFlags); |
| 800 |
np->wolenabled = 0; |
| 801 |
} |
| 802 |
if (wolinfo->wolopts & WAKE_MAGIC) { |
| 803 |
writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags); |
| 804 |
np->wolenabled = 1; |
| 641 |
} |
805 |
} |
|
|
806 |
spin_unlock_irq(&np->lock); |
| 807 |
return 0; |
| 642 |
} |
808 |
} |
| 643 |
|
809 |
|
|
|
810 |
static struct ethtool_ops ops = { |
| 811 |
.get_drvinfo = nv_get_drvinfo, |
| 812 |
.get_link = ethtool_op_get_link, |
| 813 |
.get_wol = nv_get_wol, |
| 814 |
.set_wol = nv_set_wol, |
| 815 |
}; |
| 816 |
|
| 644 |
/* |
817 |
/* |
| 645 |
* nv_alloc_rx: fill rx ring entries. |
818 |
* nv_alloc_rx: fill rx ring entries. |
| 646 |
* Return 1 if the allocations for the skbs failed and the |
819 |
* Return 1 if the allocations for the skbs failed and the |
|
Lines 650-660
Link Here
|
| 650 |
{ |
823 |
{ |
| 651 |
struct fe_priv *np = get_nvpriv(dev); |
824 |
struct fe_priv *np = get_nvpriv(dev); |
| 652 |
unsigned int refill_rx = np->refill_rx; |
825 |
unsigned int refill_rx = np->refill_rx; |
|
|
826 |
int nr; |
| 653 |
|
827 |
|
| 654 |
while (np->cur_rx != refill_rx) { |
828 |
while (np->cur_rx != refill_rx) { |
| 655 |
int nr = refill_rx % RX_RING; |
|
|
| 656 |
struct sk_buff *skb; |
829 |
struct sk_buff *skb; |
| 657 |
|
830 |
|
|
|
831 |
nr = refill_rx % RX_RING; |
| 658 |
if (np->rx_skbuff[nr] == NULL) { |
832 |
if (np->rx_skbuff[nr] == NULL) { |
| 659 |
|
833 |
|
| 660 |
skb = dev_alloc_skb(RX_ALLOC_BUFSIZE); |
834 |
skb = dev_alloc_skb(RX_ALLOC_BUFSIZE); |
|
Lines 669-678
Link Here
|
| 669 |
np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, |
843 |
np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, |
| 670 |
PCI_DMA_FROMDEVICE); |
844 |
PCI_DMA_FROMDEVICE); |
| 671 |
np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); |
845 |
np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); |
| 672 |
np->rx_ring[nr].Length = cpu_to_le16(RX_NIC_BUFSIZE); |
|
|
| 673 |
wmb(); |
846 |
wmb(); |
| 674 |
np->rx_ring[nr].Flags = cpu_to_le16(NV_RX_AVAIL); |
847 |
np->rx_ring[nr].FlagLen = cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL); |
| 675 |
dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", |
848 |
dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", |
| 676 |
dev->name, refill_rx); |
849 |
dev->name, refill_rx); |
| 677 |
refill_rx++; |
850 |
refill_rx++; |
| 678 |
} |
851 |
} |
|
Lines 703-717
Link Here
|
| 703 |
int i; |
876 |
int i; |
| 704 |
|
877 |
|
| 705 |
np->next_tx = np->nic_tx = 0; |
878 |
np->next_tx = np->nic_tx = 0; |
| 706 |
for (i = 0; i < TX_RING; i++) { |
879 |
for (i = 0; i < TX_RING; i++) |
| 707 |
np->tx_ring[i].Flags = 0; |
880 |
np->tx_ring[i].FlagLen = 0; |
| 708 |
} |
|
|
| 709 |
|
881 |
|
| 710 |
np->cur_rx = RX_RING; |
882 |
np->cur_rx = RX_RING; |
| 711 |
np->refill_rx = 0; |
883 |
np->refill_rx = 0; |
| 712 |
for (i = 0; i < RX_RING; i++) { |
884 |
for (i = 0; i < RX_RING; i++) |
| 713 |
np->rx_ring[i].Flags = 0; |
885 |
np->rx_ring[i].FlagLen = 0; |
| 714 |
} |
|
|
| 715 |
return nv_alloc_rx(dev); |
886 |
return nv_alloc_rx(dev); |
| 716 |
} |
887 |
} |
| 717 |
|
888 |
|
|
Lines 720-726
Link Here
|
| 720 |
struct fe_priv *np = get_nvpriv(dev); |
891 |
struct fe_priv *np = get_nvpriv(dev); |
| 721 |
int i; |
892 |
int i; |
| 722 |
for (i = 0; i < TX_RING; i++) { |
893 |
for (i = 0; i < TX_RING; i++) { |
| 723 |
np->tx_ring[i].Flags = 0; |
894 |
np->tx_ring[i].FlagLen = 0; |
| 724 |
if (np->tx_skbuff[i]) { |
895 |
if (np->tx_skbuff[i]) { |
| 725 |
pci_unmap_single(np->pci_dev, np->tx_dma[i], |
896 |
pci_unmap_single(np->pci_dev, np->tx_dma[i], |
| 726 |
np->tx_skbuff[i]->len, |
897 |
np->tx_skbuff[i]->len, |
|
Lines 737-743
Link Here
|
| 737 |
struct fe_priv *np = get_nvpriv(dev); |
908 |
struct fe_priv *np = get_nvpriv(dev); |
| 738 |
int i; |
909 |
int i; |
| 739 |
for (i = 0; i < RX_RING; i++) { |
910 |
for (i = 0; i < RX_RING; i++) { |
| 740 |
np->rx_ring[i].Flags = 0; |
911 |
np->rx_ring[i].FlagLen = 0; |
| 741 |
wmb(); |
912 |
wmb(); |
| 742 |
if (np->rx_skbuff[i]) { |
913 |
if (np->rx_skbuff[i]) { |
| 743 |
pci_unmap_single(np->pci_dev, np->rx_dma[i], |
914 |
pci_unmap_single(np->pci_dev, np->rx_dma[i], |
|
Lines 769-779
Link Here
|
| 769 |
PCI_DMA_TODEVICE); |
940 |
PCI_DMA_TODEVICE); |
| 770 |
|
941 |
|
| 771 |
np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); |
942 |
np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); |
| 772 |
np->tx_ring[nr].Length = cpu_to_le16(skb->len-1); |
|
|
| 773 |
|
943 |
|
| 774 |
spin_lock_irq(&np->lock); |
944 |
spin_lock_irq(&np->lock); |
| 775 |
wmb(); |
945 |
wmb(); |
| 776 |
np->tx_ring[nr].Flags = np->tx_flags; |
946 |
np->tx_ring[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); |
| 777 |
dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", |
947 |
dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", |
| 778 |
dev->name, np->next_tx); |
948 |
dev->name, np->next_tx); |
| 779 |
{ |
949 |
{ |
|
Lines 792-798
Link Here
|
| 792 |
if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP) |
962 |
if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP) |
| 793 |
netif_stop_queue(dev); |
963 |
netif_stop_queue(dev); |
| 794 |
spin_unlock_irq(&np->lock); |
964 |
spin_unlock_irq(&np->lock); |
| 795 |
writel(NVREG_TXRXCTL_KICK, get_hwbase(dev) + NvRegTxRxControl); |
965 |
writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl); |
| 796 |
pci_push(get_hwbase(dev)); |
966 |
pci_push(get_hwbase(dev)); |
| 797 |
return 0; |
967 |
return 0; |
| 798 |
} |
968 |
} |
|
Lines 805-831
Link Here
|
| 805 |
static void nv_tx_done(struct net_device *dev) |
975 |
static void nv_tx_done(struct net_device *dev) |
| 806 |
{ |
976 |
{ |
| 807 |
struct fe_priv *np = get_nvpriv(dev); |
977 |
struct fe_priv *np = get_nvpriv(dev); |
|
|
978 |
u32 Flags; |
| 979 |
int i; |
| 808 |
|
980 |
|
| 809 |
while (np->nic_tx < np->next_tx) { |
981 |
while (np->nic_tx != np->next_tx) { |
| 810 |
struct ring_desc *prd; |
982 |
i = np->nic_tx % TX_RING; |
| 811 |
int i = np->nic_tx % TX_RING; |
|
|
| 812 |
|
983 |
|
| 813 |
prd = &np->tx_ring[i]; |
984 |
Flags = le32_to_cpu(np->tx_ring[i].FlagLen); |
| 814 |
|
985 |
|
| 815 |
dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", |
986 |
dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", |
| 816 |
dev->name, np->nic_tx, prd->Flags); |
987 |
dev->name, np->nic_tx, Flags); |
| 817 |
if (prd->Flags & cpu_to_le16(NV_TX_VALID)) |
988 |
if (Flags & NV_TX_VALID) |
| 818 |
break; |
989 |
break; |
| 819 |
if (prd->Flags & cpu_to_le16(NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| |
990 |
if (np->desc_ver == DESC_VER_1) { |
| 820 |
NV_TX_UNDERFLOW|NV_TX_ERROR)) { |
991 |
if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| |
| 821 |
if (prd->Flags & cpu_to_le16(NV_TX_UNDERFLOW)) |
992 |
NV_TX_UNDERFLOW|NV_TX_ERROR)) { |
| 822 |
np->stats.tx_fifo_errors++; |
993 |
if (Flags & NV_TX_UNDERFLOW) |
| 823 |
if (prd->Flags & cpu_to_le16(NV_TX_CARRIERLOST)) |
994 |
np->stats.tx_fifo_errors++; |
| 824 |
np->stats.tx_carrier_errors++; |
995 |
if (Flags & NV_TX_CARRIERLOST) |
| 825 |
np->stats.tx_errors++; |
996 |
np->stats.tx_carrier_errors++; |
|
|
997 |
np->stats.tx_errors++; |
| 998 |
} else { |
| 999 |
np->stats.tx_packets++; |
| 1000 |
np->stats.tx_bytes += np->tx_skbuff[i]->len; |
| 1001 |
} |
| 826 |
} else { |
1002 |
} else { |
| 827 |
np->stats.tx_packets++; |
1003 |
if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION| |
| 828 |
np->stats.tx_bytes += np->tx_skbuff[i]->len; |
1004 |
NV_TX2_UNDERFLOW|NV_TX2_ERROR)) { |
|
|
1005 |
if (Flags & NV_TX2_UNDERFLOW) |
| 1006 |
np->stats.tx_fifo_errors++; |
| 1007 |
if (Flags & NV_TX2_CARRIERLOST) |
| 1008 |
np->stats.tx_carrier_errors++; |
| 1009 |
np->stats.tx_errors++; |
| 1010 |
} else { |
| 1011 |
np->stats.tx_packets++; |
| 1012 |
np->stats.tx_bytes += np->tx_skbuff[i]->len; |
| 1013 |
} |
| 829 |
} |
1014 |
} |
| 830 |
pci_unmap_single(np->pci_dev, np->tx_dma[i], |
1015 |
pci_unmap_single(np->pci_dev, np->tx_dma[i], |
| 831 |
np->tx_skbuff[i]->len, |
1016 |
np->tx_skbuff[i]->len, |
|
Lines 875-883
Link Here
|
| 875 |
static void nv_rx_process(struct net_device *dev) |
1060 |
static void nv_rx_process(struct net_device *dev) |
| 876 |
{ |
1061 |
{ |
| 877 |
struct fe_priv *np = get_nvpriv(dev); |
1062 |
struct fe_priv *np = get_nvpriv(dev); |
|
|
1063 |
u32 Flags; |
| 878 |
|
1064 |
|
| 879 |
for (;;) { |
1065 |
for (;;) { |
| 880 |
struct ring_desc *prd; |
|
|
| 881 |
struct sk_buff *skb; |
1066 |
struct sk_buff *skb; |
| 882 |
int len; |
1067 |
int len; |
| 883 |
int i; |
1068 |
int i; |
|
Lines 885-895
Link Here
|
| 885 |
break; /* we scanned the whole ring - do not continue */ |
1070 |
break; /* we scanned the whole ring - do not continue */ |
| 886 |
|
1071 |
|
| 887 |
i = np->cur_rx % RX_RING; |
1072 |
i = np->cur_rx % RX_RING; |
| 888 |
prd = &np->rx_ring[i]; |
1073 |
Flags = le32_to_cpu(np->rx_ring[i].FlagLen); |
|
|
1074 |
len = nv_descr_getlength(&np->rx_ring[i], np->desc_ver); |
| 1075 |
|
| 889 |
dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", |
1076 |
dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", |
| 890 |
dev->name, np->cur_rx, prd->Flags); |
1077 |
dev->name, np->cur_rx, Flags); |
| 891 |
|
1078 |
|
| 892 |
if (prd->Flags & cpu_to_le16(NV_RX_AVAIL)) |
1079 |
if (Flags & NV_RX_AVAIL) |
| 893 |
break; /* still owned by hardware, */ |
1080 |
break; /* still owned by hardware, */ |
| 894 |
|
1081 |
|
| 895 |
/* |
1082 |
/* |
|
Lines 903-909
Link Here
|
| 903 |
|
1090 |
|
| 904 |
{ |
1091 |
{ |
| 905 |
int j; |
1092 |
int j; |
| 906 |
dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",prd->Flags); |
1093 |
dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",Flags); |
| 907 |
for (j=0; j<64; j++) { |
1094 |
for (j=0; j<64; j++) { |
| 908 |
if ((j%16) == 0) |
1095 |
if ((j%16) == 0) |
| 909 |
dprintk("\n%03x:", j); |
1096 |
dprintk("\n%03x:", j); |
|
Lines 912-952
Link Here
|
| 912 |
dprintk("\n"); |
1099 |
dprintk("\n"); |
| 913 |
} |
1100 |
} |
| 914 |
/* look at what we actually got: */ |
1101 |
/* look at what we actually got: */ |
| 915 |
if (!(prd->Flags & cpu_to_le16(NV_RX_DESCRIPTORVALID))) |
1102 |
if (np->desc_ver == DESC_VER_1) { |
| 916 |
goto next_pkt; |
1103 |
if (!(Flags & NV_RX_DESCRIPTORVALID)) |
| 917 |
|
1104 |
goto next_pkt; |
| 918 |
|
|
|
| 919 |
len = le16_to_cpu(prd->Length); |
| 920 |
|
1105 |
|
| 921 |
if (prd->Flags & cpu_to_le16(NV_RX_MISSEDFRAME)) { |
1106 |
if (Flags & NV_RX_MISSEDFRAME) { |
| 922 |
np->stats.rx_missed_errors++; |
1107 |
np->stats.rx_missed_errors++; |
| 923 |
np->stats.rx_errors++; |
1108 |
np->stats.rx_errors++; |
| 924 |
goto next_pkt; |
1109 |
goto next_pkt; |
| 925 |
} |
1110 |
} |
| 926 |
if (prd->Flags & cpu_to_le16(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { |
1111 |
if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { |
| 927 |
np->stats.rx_errors++; |
1112 |
np->stats.rx_errors++; |
| 928 |
goto next_pkt; |
1113 |
goto next_pkt; |
| 929 |
} |
1114 |
} |
| 930 |
if (prd->Flags & cpu_to_le16(NV_RX_CRCERR)) { |
1115 |
if (Flags & NV_RX_CRCERR) { |
| 931 |
np->stats.rx_crc_errors++; |
1116 |
np->stats.rx_crc_errors++; |
| 932 |
np->stats.rx_errors++; |
1117 |
np->stats.rx_errors++; |
| 933 |
goto next_pkt; |
1118 |
goto next_pkt; |
| 934 |
} |
1119 |
} |
| 935 |
if (prd->Flags & cpu_to_le16(NV_RX_OVERFLOW)) { |
1120 |
if (Flags & NV_RX_OVERFLOW) { |
| 936 |
np->stats.rx_over_errors++; |
1121 |
np->stats.rx_over_errors++; |
| 937 |
np->stats.rx_errors++; |
1122 |
np->stats.rx_errors++; |
| 938 |
goto next_pkt; |
1123 |
goto next_pkt; |
| 939 |
} |
1124 |
} |
| 940 |
if (prd->Flags & cpu_to_le16(NV_RX_ERROR)) { |
1125 |
if (Flags & NV_RX_ERROR) { |
| 941 |
/* framing errors are soft errors, the rest is fatal. */ |
1126 |
/* framing errors are soft errors, the rest is fatal. */ |
| 942 |
if (prd->Flags & cpu_to_le16(NV_RX_FRAMINGERR)) { |
1127 |
if (Flags & NV_RX_FRAMINGERR) { |
| 943 |
if (prd->Flags & cpu_to_le16(NV_RX_SUBSTRACT1)) { |
1128 |
if (Flags & NV_RX_SUBSTRACT1) { |
| 944 |
len--; |
1129 |
len--; |
|
|
1130 |
} |
| 1131 |
} else { |
| 1132 |
np->stats.rx_errors++; |
| 1133 |
goto next_pkt; |
| 945 |
} |
1134 |
} |
| 946 |
} else { |
1135 |
} |
|
|
1136 |
} else { |
| 1137 |
if (!(Flags & NV_RX2_DESCRIPTORVALID)) |
| 1138 |
goto next_pkt; |
| 1139 |
|
| 1140 |
if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4)) { |
| 947 |
np->stats.rx_errors++; |
1141 |
np->stats.rx_errors++; |
| 948 |
goto next_pkt; |
1142 |
goto next_pkt; |
| 949 |
} |
1143 |
} |
|
|
1144 |
if (Flags & NV_RX2_CRCERR) { |
| 1145 |
np->stats.rx_crc_errors++; |
| 1146 |
np->stats.rx_errors++; |
| 1147 |
goto next_pkt; |
| 1148 |
} |
| 1149 |
if (Flags & NV_RX2_OVERFLOW) { |
| 1150 |
np->stats.rx_over_errors++; |
| 1151 |
np->stats.rx_errors++; |
| 1152 |
goto next_pkt; |
| 1153 |
} |
| 1154 |
if (Flags & NV_RX2_ERROR) { |
| 1155 |
/* framing errors are soft errors, the rest is fatal. */ |
| 1156 |
if (Flags & NV_RX2_FRAMINGERR) { |
| 1157 |
if (Flags & NV_RX2_SUBSTRACT1) { |
| 1158 |
len--; |
| 1159 |
} |
| 1160 |
} else { |
| 1161 |
np->stats.rx_errors++; |
| 1162 |
goto next_pkt; |
| 1163 |
} |
| 1164 |
} |
| 1165 |
Flags &= NV_RX2_CHECKSUMMASK; |
| 1166 |
if (Flags == NV_RX2_CHECKSUMOK1 || |
| 1167 |
Flags == NV_RX2_CHECKSUMOK2 || |
| 1168 |
Flags == NV_RX2_CHECKSUMOK3) { |
| 1169 |
dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name); |
| 1170 |
np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY; |
| 1171 |
} else { |
| 1172 |
dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name); |
| 1173 |
} |
| 950 |
} |
1174 |
} |
| 951 |
/* got a valid packet - forward it to the network core */ |
1175 |
/* got a valid packet - forward it to the network core */ |
| 952 |
skb = np->rx_skbuff[i]; |
1176 |
skb = np->rx_skbuff[i]; |
|
Lines 971-977
Link Here
|
| 971 |
*/ |
1195 |
*/ |
| 972 |
static int nv_change_mtu(struct net_device *dev, int new_mtu) |
1196 |
static int nv_change_mtu(struct net_device *dev, int new_mtu) |
| 973 |
{ |
1197 |
{ |
| 974 |
if (new_mtu > DEFAULT_MTU) |
1198 |
if (new_mtu > ETH_DATA_LEN) |
| 975 |
return -EINVAL; |
1199 |
return -EINVAL; |
| 976 |
dev->mtu = new_mtu; |
1200 |
dev->mtu = new_mtu; |
| 977 |
return 0; |
1201 |
return 0; |
|
Lines 1035-1040
Link Here
|
| 1035 |
writel(mask[0], base + NvRegMulticastMaskA); |
1259 |
writel(mask[0], base + NvRegMulticastMaskA); |
| 1036 |
writel(mask[1], base + NvRegMulticastMaskB); |
1260 |
writel(mask[1], base + NvRegMulticastMaskB); |
| 1037 |
writel(pff, base + NvRegPacketFilterFlags); |
1261 |
writel(pff, base + NvRegPacketFilterFlags); |
|
|
1262 |
dprintk(KERN_INFO "%s: reconfiguration for multicast lists.\n", |
| 1263 |
dev->name); |
| 1038 |
nv_start_rx(dev); |
1264 |
nv_start_rx(dev); |
| 1039 |
spin_unlock_irq(&np->lock); |
1265 |
spin_unlock_irq(&np->lock); |
| 1040 |
} |
1266 |
} |
|
Lines 1042-1057
Link Here
|
| 1042 |
static int nv_update_linkspeed(struct net_device *dev) |
1268 |
static int nv_update_linkspeed(struct net_device *dev) |
| 1043 |
{ |
1269 |
{ |
| 1044 |
struct fe_priv *np = get_nvpriv(dev); |
1270 |
struct fe_priv *np = get_nvpriv(dev); |
| 1045 |
int adv, lpa, newls, newdup; |
1271 |
u8 *base = get_hwbase(dev); |
|
|
1272 |
int adv, lpa; |
| 1273 |
int newls = np->linkspeed; |
| 1274 |
int newdup = np->duplex; |
| 1275 |
int mii_status; |
| 1276 |
int retval = 0; |
| 1277 |
u32 control_1000, status_1000, phyreg; |
| 1278 |
|
| 1279 |
/* BMSR_LSTATUS is latched, read it twice: |
| 1280 |
* we want the current value. |
| 1281 |
*/ |
| 1282 |
mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); |
| 1283 |
mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); |
| 1284 |
|
| 1285 |
if (!(mii_status & BMSR_LSTATUS)) { |
| 1286 |
dprintk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n", |
| 1287 |
dev->name); |
| 1288 |
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
| 1289 |
newdup = 0; |
| 1290 |
retval = 0; |
| 1291 |
goto set_speed; |
| 1292 |
} |
| 1293 |
|
| 1294 |
/* check auto negotiation is complete */ |
| 1295 |
if (!(mii_status & BMSR_ANEGCOMPLETE)) { |
| 1296 |
/* still in autonegotiation - configure nic for 10 MBit HD and wait. */ |
| 1297 |
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
| 1298 |
newdup = 0; |
| 1299 |
retval = 0; |
| 1300 |
dprintk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name); |
| 1301 |
goto set_speed; |
| 1302 |
} |
| 1303 |
|
| 1304 |
retval = 1; |
| 1305 |
if (np->gigabit == PHY_GIGABIT) { |
| 1306 |
control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); |
| 1307 |
status_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_SR, MII_READ); |
| 1308 |
|
| 1309 |
if ((control_1000 & ADVERTISE_1000FULL) && |
| 1310 |
(status_1000 & LPA_1000FULL)) { |
| 1311 |
dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n", |
| 1312 |
dev->name); |
| 1313 |
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000; |
| 1314 |
newdup = 1; |
| 1315 |
goto set_speed; |
| 1316 |
} |
| 1317 |
} |
| 1046 |
|
1318 |
|
| 1047 |
adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); |
1319 |
adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); |
| 1048 |
lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); |
1320 |
lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); |
| 1049 |
dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", |
1321 |
dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", |
| 1050 |
dev->name, adv, lpa); |
1322 |
dev->name, adv, lpa); |
| 1051 |
|
1323 |
|
| 1052 |
/* FIXME: handle parallel detection properly, handle gigabit ethernet */ |
1324 |
/* FIXME: handle parallel detection properly */ |
| 1053 |
lpa = lpa & adv; |
1325 |
lpa = lpa & adv; |
| 1054 |
if (lpa & LPA_100FULL) { |
1326 |
if (lpa & LPA_100FULL) { |
| 1055 |
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; |
1327 |
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; |
| 1056 |
newdup = 1; |
1328 |
newdup = 1; |
| 1057 |
} else if (lpa & LPA_100HALF) { |
1329 |
} else if (lpa & LPA_100HALF) { |
|
Lines 1068-1104
Link Here
|
| 1068 |
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
1340 |
newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
| 1069 |
newdup = 0; |
1341 |
newdup = 0; |
| 1070 |
} |
1342 |
} |
| 1071 |
if (np->duplex != newdup || np->linkspeed != newls) { |
|
|
| 1072 |
np->duplex = newdup; |
| 1073 |
np->linkspeed = newls; |
| 1074 |
return 1; |
| 1075 |
} |
| 1076 |
return 0; |
| 1077 |
} |
| 1078 |
|
1343 |
|
| 1079 |
static void nv_link_irq(struct net_device *dev) |
1344 |
set_speed: |
| 1080 |
{ |
1345 |
if (np->duplex == newdup && np->linkspeed == newls) |
| 1081 |
struct fe_priv *np = get_nvpriv(dev); |
1346 |
return retval; |
| 1082 |
u8 *base = get_hwbase(dev); |
1347 |
|
| 1083 |
u32 miistat; |
1348 |
dprintk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n", |
| 1084 |
int miival; |
1349 |
dev->name, np->linkspeed, np->duplex, newls, newdup); |
|
|
1350 |
|
| 1351 |
np->duplex = newdup; |
| 1352 |
np->linkspeed = newls; |
| 1353 |
|
| 1354 |
if (np->gigabit == PHY_GIGABIT) { |
| 1355 |
phyreg = readl(base + NvRegRandomSeed); |
| 1356 |
phyreg &= ~(0x3FF00); |
| 1357 |
if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) |
| 1358 |
phyreg |= NVREG_RNDSEED_FORCE3; |
| 1359 |
else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
| 1360 |
phyreg |= NVREG_RNDSEED_FORCE2; |
| 1361 |
else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
| 1362 |
phyreg |= NVREG_RNDSEED_FORCE; |
| 1363 |
writel(phyreg, base + NvRegRandomSeed); |
| 1364 |
} |
| 1365 |
|
| 1366 |
phyreg = readl(base + NvRegPhyInterface); |
| 1367 |
phyreg &= ~(PHY_HALF|PHY_100|PHY_1000); |
| 1368 |
if (np->duplex == 0) |
| 1369 |
phyreg |= PHY_HALF; |
| 1370 |
if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) |
| 1371 |
phyreg |= PHY_100; |
| 1372 |
else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) |
| 1373 |
phyreg |= PHY_1000; |
| 1374 |
writel(phyreg, base + NvRegPhyInterface); |
| 1085 |
|
1375 |
|
| 1086 |
miistat = readl(base + NvRegMIIStatus); |
1376 |
writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), |
| 1087 |
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
1377 |
base + NvRegMisc1); |
| 1088 |
printk(KERN_DEBUG "%s: link change notification, status 0x%x.\n", dev->name, miistat); |
1378 |
pci_push(base); |
|
|
1379 |
writel(np->linkspeed, base + NvRegLinkSpeed); |
| 1380 |
pci_push(base); |
| 1089 |
|
1381 |
|
| 1090 |
miival = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); |
1382 |
return retval; |
| 1091 |
if (miival & BMSR_ANEGCOMPLETE) { |
1383 |
} |
| 1092 |
nv_update_linkspeed(dev); |
|
|
| 1093 |
|
1384 |
|
|
|
1385 |
static void nv_linkchange(struct net_device *dev) |
| 1386 |
{ |
| 1387 |
if (nv_update_linkspeed(dev)) { |
| 1094 |
if (netif_carrier_ok(dev)) { |
1388 |
if (netif_carrier_ok(dev)) { |
| 1095 |
nv_stop_rx(dev); |
1389 |
nv_stop_rx(dev); |
| 1096 |
} else { |
1390 |
} else { |
| 1097 |
netif_carrier_on(dev); |
1391 |
netif_carrier_on(dev); |
| 1098 |
printk(KERN_INFO "%s: link up.\n", dev->name); |
1392 |
printk(KERN_INFO "%s: link up.\n", dev->name); |
| 1099 |
} |
1393 |
} |
| 1100 |
writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), |
|
|
| 1101 |
base + NvRegMisc1); |
| 1102 |
nv_start_rx(dev); |
1394 |
nv_start_rx(dev); |
| 1103 |
} else { |
1395 |
} else { |
| 1104 |
if (netif_carrier_ok(dev)) { |
1396 |
if (netif_carrier_ok(dev)) { |
|
Lines 1106-1116
Link Here
|
| 1106 |
printk(KERN_INFO "%s: link down.\n", dev->name); |
1398 |
printk(KERN_INFO "%s: link down.\n", dev->name); |
| 1107 |
nv_stop_rx(dev); |
1399 |
nv_stop_rx(dev); |
| 1108 |
} |
1400 |
} |
| 1109 |
writel(np->linkspeed, base + NvRegLinkSpeed); |
|
|
| 1110 |
pci_push(base); |
| 1111 |
} |
1401 |
} |
| 1112 |
} |
1402 |
} |
| 1113 |
|
1403 |
|
|
|
1404 |
static void nv_link_irq(struct net_device *dev) |
| 1405 |
{ |
| 1406 |
u8 *base = get_hwbase(dev); |
| 1407 |
u32 miistat; |
| 1408 |
|
| 1409 |
miistat = readl(base + NvRegMIIStatus); |
| 1410 |
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
| 1411 |
dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat); |
| 1412 |
|
| 1413 |
if (miistat & (NVREG_MIISTAT_LINKCHANGE)) |
| 1414 |
nv_linkchange(dev); |
| 1415 |
dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); |
| 1416 |
} |
| 1417 |
|
| 1114 |
static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) |
1418 |
static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) |
| 1115 |
{ |
1419 |
{ |
| 1116 |
struct net_device *dev = (struct net_device *) data; |
1420 |
struct net_device *dev = (struct net_device *) data; |
|
Lines 1135-1141
Link Here
|
| 1135 |
spin_unlock(&np->lock); |
1439 |
spin_unlock(&np->lock); |
| 1136 |
} |
1440 |
} |
| 1137 |
|
1441 |
|
| 1138 |
if (events & (NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) { |
1442 |
if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) { |
| 1139 |
nv_rx_process(dev); |
1443 |
nv_rx_process(dev); |
| 1140 |
if (nv_alloc_rx(dev)) { |
1444 |
if (nv_alloc_rx(dev)) { |
| 1141 |
spin_lock(&np->lock); |
1445 |
spin_lock(&np->lock); |
|
Lines 1150-1155
Link Here
|
| 1150 |
nv_link_irq(dev); |
1454 |
nv_link_irq(dev); |
| 1151 |
spin_unlock(&np->lock); |
1455 |
spin_unlock(&np->lock); |
| 1152 |
} |
1456 |
} |
|
|
1457 |
if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { |
| 1458 |
spin_lock(&np->lock); |
| 1459 |
nv_linkchange(dev); |
| 1460 |
spin_unlock(&np->lock); |
| 1461 |
np->link_timeout = jiffies + LINK_TIMEOUT; |
| 1462 |
} |
| 1153 |
if (events & (NVREG_IRQ_TX_ERR)) { |
1463 |
if (events & (NVREG_IRQ_TX_ERR)) { |
| 1154 |
dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", |
1464 |
dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", |
| 1155 |
dev->name, events); |
1465 |
dev->name, events); |
|
Lines 1157-1163
Link Here
|
| 1157 |
if (events & (NVREG_IRQ_UNKNOWN)) { |
1467 |
if (events & (NVREG_IRQ_UNKNOWN)) { |
| 1158 |
printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", |
1468 |
printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", |
| 1159 |
dev->name, events); |
1469 |
dev->name, events); |
| 1160 |
} |
1470 |
} |
| 1161 |
if (i > max_interrupt_work) { |
1471 |
if (i > max_interrupt_work) { |
| 1162 |
spin_lock(&np->lock); |
1472 |
spin_lock(&np->lock); |
| 1163 |
/* disable interrupts on the nic */ |
1473 |
/* disable interrupts on the nic */ |
|
Lines 1210-1230
Link Here
|
| 1210 |
writel(0, base + NvRegMulticastMaskA); |
1520 |
writel(0, base + NvRegMulticastMaskA); |
| 1211 |
writel(0, base + NvRegMulticastMaskB); |
1521 |
writel(0, base + NvRegMulticastMaskB); |
| 1212 |
writel(0, base + NvRegPacketFilterFlags); |
1522 |
writel(0, base + NvRegPacketFilterFlags); |
|
|
1523 |
|
| 1524 |
writel(0, base + NvRegTransmitterControl); |
| 1525 |
writel(0, base + NvRegReceiverControl); |
| 1526 |
|
| 1213 |
writel(0, base + NvRegAdapterControl); |
1527 |
writel(0, base + NvRegAdapterControl); |
|
|
1528 |
|
| 1529 |
/* 2) initialize descriptor rings */ |
| 1530 |
oom = nv_init_ring(dev); |
| 1531 |
|
| 1214 |
writel(0, base + NvRegLinkSpeed); |
1532 |
writel(0, base + NvRegLinkSpeed); |
| 1215 |
writel(0, base + NvRegUnknownTransmitterReg); |
1533 |
writel(0, base + NvRegUnknownTransmitterReg); |
| 1216 |
nv_txrx_reset(dev); |
1534 |
nv_txrx_reset(dev); |
| 1217 |
writel(0, base + NvRegUnknownSetupReg6); |
1535 |
writel(0, base + NvRegUnknownSetupReg6); |
| 1218 |
|
1536 |
|
| 1219 |
/* 2) initialize descriptor rings */ |
|
|
| 1220 |
np->in_shutdown = 0; |
1537 |
np->in_shutdown = 0; |
| 1221 |
oom = nv_init_ring(dev); |
|
|
| 1222 |
|
1538 |
|
| 1223 |
/* 3) set mac address */ |
1539 |
/* 3) set mac address */ |
| 1224 |
{ |
1540 |
{ |
| 1225 |
u32 mac[2]; |
1541 |
u32 mac[2]; |
| 1226 |
|
1542 |
|
| 1227 |
mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + |
1543 |
mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + |
| 1228 |
(dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); |
1544 |
(dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); |
| 1229 |
mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); |
1545 |
mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); |
| 1230 |
|
1546 |
|
|
Lines 1232-1284
Link Here
|
| 1232 |
writel(mac[1], base + NvRegMacAddrB); |
1548 |
writel(mac[1], base + NvRegMacAddrB); |
| 1233 |
} |
1549 |
} |
| 1234 |
|
1550 |
|
| 1235 |
/* 4) continue setup */ |
1551 |
/* 4) give hw rings */ |
|
|
1552 |
writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); |
| 1553 |
writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); |
| 1554 |
writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), |
| 1555 |
base + NvRegRingSizes); |
| 1556 |
|
| 1557 |
/* 5) continue setup */ |
| 1236 |
np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
1558 |
np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
| 1237 |
np->duplex = 0; |
1559 |
np->duplex = 0; |
|
|
1560 |
|
| 1561 |
writel(np->linkspeed, base + NvRegLinkSpeed); |
| 1238 |
writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3); |
1562 |
writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3); |
| 1239 |
writel(0, base + NvRegTxRxControl); |
1563 |
writel(np->desc_ver, base + NvRegTxRxControl); |
| 1240 |
pci_push(base); |
1564 |
pci_push(base); |
| 1241 |
writel(NVREG_TXRXCTL_BIT1, base + NvRegTxRxControl); |
1565 |
writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl); |
| 1242 |
reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, |
1566 |
reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, |
| 1243 |
NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, |
1567 |
NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, |
| 1244 |
KERN_INFO "open: SetupReg5, Bit 31 remained off\n"); |
1568 |
KERN_INFO "open: SetupReg5, Bit 31 remained off\n"); |
| 1245 |
writel(0, base + NvRegUnknownSetupReg4); |
|
|
| 1246 |
|
| 1247 |
/* 5) Find a suitable PHY */ |
| 1248 |
writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed); |
| 1249 |
for (i = 1; i < 32; i++) { |
| 1250 |
int id1, id2; |
| 1251 |
|
| 1252 |
spin_lock_irq(&np->lock); |
| 1253 |
id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ); |
| 1254 |
spin_unlock_irq(&np->lock); |
| 1255 |
if (id1 < 0 || id1 == 0xffff) |
| 1256 |
continue; |
| 1257 |
spin_lock_irq(&np->lock); |
| 1258 |
id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ); |
| 1259 |
spin_unlock_irq(&np->lock); |
| 1260 |
if (id2 < 0 || id2 == 0xffff) |
| 1261 |
continue; |
| 1262 |
dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", |
| 1263 |
dev->name, id1, id2, i); |
| 1264 |
np->phyaddr = i; |
| 1265 |
|
1569 |
|
| 1266 |
spin_lock_irq(&np->lock); |
1570 |
writel(0, base + NvRegUnknownSetupReg4); |
| 1267 |
nv_update_linkspeed(dev); |
1571 |
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); |
| 1268 |
spin_unlock_irq(&np->lock); |
1572 |
writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); |
| 1269 |
|
|
|
| 1270 |
break; |
| 1271 |
} |
| 1272 |
if (i == 32) { |
| 1273 |
printk(KERN_INFO "%s: open: failing due to lack of suitable PHY.\n", |
| 1274 |
dev->name); |
| 1275 |
ret = -EINVAL; |
| 1276 |
goto out_drain; |
| 1277 |
} |
| 1278 |
|
1573 |
|
| 1279 |
/* 6) continue setup */ |
1574 |
/* 6) continue setup */ |
| 1280 |
writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), |
1575 |
writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); |
| 1281 |
base + NvRegMisc1); |
|
|
| 1282 |
writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); |
1576 |
writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); |
| 1283 |
writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); |
1577 |
writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); |
| 1284 |
writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig); |
1578 |
writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig); |
|
Lines 1290-1306
Link Here
|
| 1290 |
writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2); |
1584 |
writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2); |
| 1291 |
writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval); |
1585 |
writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval); |
| 1292 |
writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); |
1586 |
writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); |
| 1293 |
writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID, |
1587 |
writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING, |
| 1294 |
base + NvRegAdapterControl); |
1588 |
base + NvRegAdapterControl); |
|
|
1589 |
writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed); |
| 1295 |
writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4); |
1590 |
writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4); |
| 1296 |
writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags); |
1591 |
writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags); |
| 1297 |
|
1592 |
|
| 1298 |
/* 7) start packet processing */ |
|
|
| 1299 |
writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); |
| 1300 |
writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); |
| 1301 |
writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), |
| 1302 |
base + NvRegRingSizes); |
| 1303 |
|
| 1304 |
i = readl(base + NvRegPowerState); |
1593 |
i = readl(base + NvRegPowerState); |
| 1305 |
if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) |
1594 |
if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) |
| 1306 |
writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState); |
1595 |
writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState); |
|
Lines 1308-1320
Link Here
|
| 1308 |
pci_push(base); |
1597 |
pci_push(base); |
| 1309 |
udelay(10); |
1598 |
udelay(10); |
| 1310 |
writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); |
1599 |
writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); |
| 1311 |
writel(NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); |
|
|
| 1312 |
|
| 1313 |
|
1600 |
|
| 1314 |
writel(0, base + NvRegIrqMask); |
1601 |
writel(0, base + NvRegIrqMask); |
| 1315 |
pci_push(base); |
1602 |
pci_push(base); |
| 1316 |
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); |
|
|
| 1317 |
pci_push(base); |
| 1318 |
writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); |
1603 |
writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); |
| 1319 |
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); |
1604 |
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); |
| 1320 |
pci_push(base); |
1605 |
pci_push(base); |
|
Lines 1323-1328
Link Here
|
| 1323 |
if (ret) |
1608 |
if (ret) |
| 1324 |
goto out_drain; |
1609 |
goto out_drain; |
| 1325 |
|
1610 |
|
|
|
1611 |
/* ask for interrupts */ |
| 1326 |
writel(np->irqmask, base + NvRegIrqMask); |
1612 |
writel(np->irqmask, base + NvRegIrqMask); |
| 1327 |
|
1613 |
|
| 1328 |
spin_lock_irq(&np->lock); |
1614 |
spin_lock_irq(&np->lock); |
|
Lines 1331-1348
Link Here
|
| 1331 |
writel(0, base + NvRegMulticastMaskA); |
1617 |
writel(0, base + NvRegMulticastMaskA); |
| 1332 |
writel(0, base + NvRegMulticastMaskB); |
1618 |
writel(0, base + NvRegMulticastMaskB); |
| 1333 |
writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); |
1619 |
writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); |
|
|
1620 |
/* One manual link speed update: Interrupts are enabled, future link |
| 1621 |
* speed changes cause interrupts and are handled by nv_link_irq(). |
| 1622 |
*/ |
| 1623 |
{ |
| 1624 |
u32 miistat; |
| 1625 |
miistat = readl(base + NvRegMIIStatus); |
| 1626 |
writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
| 1627 |
dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); |
| 1628 |
} |
| 1629 |
ret = nv_update_linkspeed(dev); |
| 1334 |
nv_start_rx(dev); |
1630 |
nv_start_rx(dev); |
| 1335 |
nv_start_tx(dev); |
1631 |
nv_start_tx(dev); |
| 1336 |
netif_start_queue(dev); |
1632 |
netif_start_queue(dev); |
| 1337 |
if (oom) |
1633 |
if (ret) { |
| 1338 |
mod_timer(&np->oom_kick, jiffies + OOM_REFILL); |
|
|
| 1339 |
if (mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ) & BMSR_ANEGCOMPLETE) { |
| 1340 |
netif_carrier_on(dev); |
1634 |
netif_carrier_on(dev); |
| 1341 |
} else { |
1635 |
} else { |
| 1342 |
printk("%s: no link during initialization.\n", dev->name); |
1636 |
printk("%s: no link during initialization.\n", dev->name); |
| 1343 |
netif_carrier_off(dev); |
1637 |
netif_carrier_off(dev); |
| 1344 |
} |
1638 |
} |
| 1345 |
|
1639 |
if (oom) |
|
|
1640 |
mod_timer(&np->oom_kick, jiffies + OOM_REFILL); |
| 1346 |
spin_unlock_irq(&np->lock); |
1641 |
spin_unlock_irq(&np->lock); |
| 1347 |
|
1642 |
|
| 1348 |
return 0; |
1643 |
return 0; |
|
Lines 1368-1376
Link Here
|
| 1368 |
spin_lock_irq(&np->lock); |
1663 |
spin_lock_irq(&np->lock); |
| 1369 |
nv_stop_tx(dev); |
1664 |
nv_stop_tx(dev); |
| 1370 |
nv_stop_rx(dev); |
1665 |
nv_stop_rx(dev); |
| 1371 |
base = get_hwbase(dev); |
1666 |
nv_txrx_reset(dev); |
| 1372 |
|
1667 |
|
| 1373 |
/* disable interrupts on the nic or we will lock up */ |
1668 |
/* disable interrupts on the nic or we will lock up */ |
|
|
1669 |
base = get_hwbase(dev); |
| 1374 |
writel(0, base + NvRegIrqMask); |
1670 |
writel(0, base + NvRegIrqMask); |
| 1375 |
pci_push(base); |
1671 |
pci_push(base); |
| 1376 |
dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name); |
1672 |
dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name); |
|
Lines 1424-1430
Link Here
|
| 1424 |
|
1720 |
|
| 1425 |
pci_set_master(pci_dev); |
1721 |
pci_set_master(pci_dev); |
| 1426 |
|
1722 |
|
| 1427 |
err = pci_request_regions(pci_dev, dev->name); |
1723 |
err = pci_request_regions(pci_dev, DRV_NAME); |
| 1428 |
if (err < 0) |
1724 |
if (err < 0) |
| 1429 |
goto out_disable; |
1725 |
goto out_disable; |
| 1430 |
|
1726 |
|
|
Lines 1447-1452
Link Here
|
| 1447 |
goto out_relreg; |
1743 |
goto out_relreg; |
| 1448 |
} |
1744 |
} |
| 1449 |
|
1745 |
|
|
|
1746 |
/* handle different descriptor versions */ |
| 1747 |
if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 || |
| 1748 |
pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 || |
| 1749 |
pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3) |
| 1750 |
np->desc_ver = DESC_VER_1; |
| 1751 |
else |
| 1752 |
np->desc_ver = DESC_VER_2; |
| 1753 |
|
| 1450 |
err = -ENOMEM; |
1754 |
err = -ENOMEM; |
| 1451 |
dev->base_addr = (unsigned long) ioremap(addr, NV_PCI_REGSZ); |
1755 |
dev->base_addr = (unsigned long) ioremap(addr, NV_PCI_REGSZ); |
| 1452 |
if (!dev->base_addr) |
1756 |
if (!dev->base_addr) |
|
Lines 1464-1470
Link Here
|
| 1464 |
dev->get_stats = nv_get_stats; |
1768 |
dev->get_stats = nv_get_stats; |
| 1465 |
dev->change_mtu = nv_change_mtu; |
1769 |
dev->change_mtu = nv_change_mtu; |
| 1466 |
dev->set_multicast_list = nv_set_multicast; |
1770 |
dev->set_multicast_list = nv_set_multicast; |
| 1467 |
dev->do_ioctl = nv_ioctl; |
1771 |
SET_ETHTOOL_OPS(dev, &ops); |
| 1468 |
dev->tx_timeout = nv_tx_timeout; |
1772 |
dev->tx_timeout = nv_tx_timeout; |
| 1469 |
dev->watchdog_timeo = NV_WATCHDOG_TIMEO; |
1773 |
dev->watchdog_timeo = NV_WATCHDOG_TIMEO; |
| 1470 |
|
1774 |
|
|
Lines 1506-1520
Link Here
|
| 1506 |
writel(0, base + NvRegWakeUpFlags); |
1810 |
writel(0, base + NvRegWakeUpFlags); |
| 1507 |
np->wolenabled = 0; |
1811 |
np->wolenabled = 0; |
| 1508 |
|
1812 |
|
| 1509 |
np->tx_flags = cpu_to_le16(NV_TX_LASTPACKET|NV_TX_LASTPACKET1|NV_TX_VALID); |
1813 |
if (np->desc_ver == DESC_VER_1) { |
| 1510 |
if (id->driver_data & DEV_NEED_LASTPACKET1) |
1814 |
np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; |
| 1511 |
np->tx_flags |= cpu_to_le16(NV_TX_LASTPACKET1); |
1815 |
if (id->driver_data & DEV_NEED_LASTPACKET1) |
|
|
1816 |
np->tx_flags |= NV_TX_LASTPACKET1; |
| 1817 |
} else { |
| 1818 |
np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; |
| 1819 |
if (id->driver_data & DEV_NEED_LASTPACKET1) |
| 1820 |
np->tx_flags |= NV_TX2_LASTPACKET1; |
| 1821 |
} |
| 1512 |
if (id->driver_data & DEV_IRQMASK_1) |
1822 |
if (id->driver_data & DEV_IRQMASK_1) |
| 1513 |
np->irqmask = NVREG_IRQMASK_WANTED_1; |
1823 |
np->irqmask = NVREG_IRQMASK_WANTED_1; |
| 1514 |
if (id->driver_data & DEV_IRQMASK_2) |
1824 |
if (id->driver_data & DEV_IRQMASK_2) |
| 1515 |
np->irqmask = NVREG_IRQMASK_WANTED_2; |
1825 |
np->irqmask = NVREG_IRQMASK_WANTED_2; |
| 1516 |
if (id->driver_data & DEV_NEED_TIMERIRQ) |
1826 |
if (id->driver_data & DEV_NEED_TIMERIRQ) |
| 1517 |
np->irqmask |= NVREG_IRQ_TIMER; |
1827 |
np->irqmask |= NVREG_IRQ_TIMER; |
|
|
1828 |
if (id->driver_data & DEV_NEED_LINKTIMER) { |
| 1829 |
dprintk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev)); |
| 1830 |
np->need_linktimer = 1; |
| 1831 |
np->link_timeout = jiffies + LINK_TIMEOUT; |
| 1832 |
} else { |
| 1833 |
dprintk(KERN_INFO "%s: link timer off.\n", pci_name(pci_dev)); |
| 1834 |
np->need_linktimer = 0; |
| 1835 |
} |
| 1836 |
|
| 1837 |
/* find a suitable phy */ |
| 1838 |
for (i = 1; i < 32; i++) { |
| 1839 |
int id1, id2; |
| 1840 |
|
| 1841 |
spin_lock_irq(&np->lock); |
| 1842 |
id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ); |
| 1843 |
spin_unlock_irq(&np->lock); |
| 1844 |
if (id1 < 0 || id1 == 0xffff) |
| 1845 |
continue; |
| 1846 |
spin_lock_irq(&np->lock); |
| 1847 |
id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ); |
| 1848 |
spin_unlock_irq(&np->lock); |
| 1849 |
if (id2 < 0 || id2 == 0xffff) |
| 1850 |
continue; |
| 1851 |
|
| 1852 |
id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT; |
| 1853 |
id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT; |
| 1854 |
dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", |
| 1855 |
pci_name(pci_dev), id1, id2, i); |
| 1856 |
np->phyaddr = i; |
| 1857 |
np->phy_oui = id1 | id2; |
| 1858 |
break; |
| 1859 |
} |
| 1860 |
if (i == 32) { |
| 1861 |
/* PHY in isolate mode? No phy attached and user wants to |
| 1862 |
* test loopback? Very odd, but can be correct. |
| 1863 |
*/ |
| 1864 |
printk(KERN_INFO "%s: open: Could not find a valid PHY.\n", |
| 1865 |
pci_name(pci_dev)); |
| 1866 |
} |
| 1867 |
|
| 1868 |
if (i != 32) { |
| 1869 |
/* reset it */ |
| 1870 |
phy_init(dev); |
| 1871 |
} |
| 1518 |
|
1872 |
|
| 1519 |
err = register_netdev(dev); |
1873 |
err = register_netdev(dev); |
| 1520 |
if (err) { |
1874 |
if (err) { |
|
Lines 1569-1589
Link Here
|
| 1569 |
static struct pci_device_id pci_tbl[] = { |
1923 |
static struct pci_device_id pci_tbl[] = { |
| 1570 |
{ /* nForce Ethernet Controller */ |
1924 |
{ /* nForce Ethernet Controller */ |
| 1571 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
1925 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1572 |
.device = 0x1C3, |
1926 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_1, |
| 1573 |
.subvendor = PCI_ANY_ID, |
1927 |
.subvendor = PCI_ANY_ID, |
| 1574 |
.subdevice = PCI_ANY_ID, |
1928 |
.subdevice = PCI_ANY_ID, |
| 1575 |
.driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ, |
1929 |
.driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
| 1576 |
}, |
1930 |
}, |
| 1577 |
{ /* nForce2 Ethernet Controller */ |
1931 |
{ /* nForce2 Ethernet Controller */ |
| 1578 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
1932 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1579 |
.device = 0x0066, |
1933 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_2, |
|
|
1934 |
.subvendor = PCI_ANY_ID, |
| 1935 |
.subdevice = PCI_ANY_ID, |
| 1936 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
| 1937 |
}, |
| 1938 |
{ /* nForce3 Ethernet Controller */ |
| 1939 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1940 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_3, |
| 1941 |
.subvendor = PCI_ANY_ID, |
| 1942 |
.subdevice = PCI_ANY_ID, |
| 1943 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
| 1944 |
}, |
| 1945 |
{ /* nForce3 Ethernet Controller */ |
| 1946 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1947 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_4, |
| 1580 |
.subvendor = PCI_ANY_ID, |
1948 |
.subvendor = PCI_ANY_ID, |
| 1581 |
.subdevice = PCI_ANY_ID, |
1949 |
.subdevice = PCI_ANY_ID, |
| 1582 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
1950 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
| 1583 |
}, |
1951 |
}, |
| 1584 |
{ /* nForce3 Ethernet Controller */ |
1952 |
{ /* nForce3 Ethernet Controller */ |
| 1585 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
1953 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1586 |
.device = 0x00D6, |
1954 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_5, |
|
|
1955 |
.subvendor = PCI_ANY_ID, |
| 1956 |
.subdevice = PCI_ANY_ID, |
| 1957 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
| 1958 |
}, |
| 1959 |
{ /* nForce3 Ethernet Controller */ |
| 1960 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1961 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_6, |
| 1962 |
.subvendor = PCI_ANY_ID, |
| 1963 |
.subdevice = PCI_ANY_ID, |
| 1964 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
| 1965 |
}, |
| 1966 |
{ /* nForce3 Ethernet Controller */ |
| 1967 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1968 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_7, |
| 1969 |
.subvendor = PCI_ANY_ID, |
| 1970 |
.subdevice = PCI_ANY_ID, |
| 1971 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
| 1972 |
}, |
| 1973 |
{ /* CK804 Ethernet Controller */ |
| 1974 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1975 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_8, |
| 1976 |
.subvendor = PCI_ANY_ID, |
| 1977 |
.subdevice = PCI_ANY_ID, |
| 1978 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
| 1979 |
}, |
| 1980 |
{ /* CK804 Ethernet Controller */ |
| 1981 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1982 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_9, |
| 1983 |
.subvendor = PCI_ANY_ID, |
| 1984 |
.subdevice = PCI_ANY_ID, |
| 1985 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
| 1986 |
}, |
| 1987 |
{ /* MCP04 Ethernet Controller */ |
| 1988 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1989 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_10, |
| 1990 |
.subvendor = PCI_ANY_ID, |
| 1991 |
.subdevice = PCI_ANY_ID, |
| 1992 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
| 1993 |
}, |
| 1994 |
{ /* MCP04 Ethernet Controller */ |
| 1995 |
.vendor = PCI_VENDOR_ID_NVIDIA, |
| 1996 |
.device = PCI_DEVICE_ID_NVIDIA_NVENET_11, |
| 1587 |
.subvendor = PCI_ANY_ID, |
1997 |
.subvendor = PCI_ANY_ID, |
| 1588 |
.subdevice = PCI_ANY_ID, |
1998 |
.subdevice = PCI_ANY_ID, |
| 1589 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
1999 |
.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, |
|
Lines 1610-1616
Link Here
|
| 1610 |
pci_unregister_driver(&driver); |
2020 |
pci_unregister_driver(&driver); |
| 1611 |
} |
2021 |
} |
| 1612 |
|
2022 |
|
| 1613 |
MODULE_PARM(max_interrupt_work, "i"); |
2023 |
module_param(max_interrupt_work, int, 0); |
| 1614 |
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt"); |
2024 |
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt"); |
| 1615 |
|
2025 |
|
| 1616 |
MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>"); |
2026 |
MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>"); |