aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/forcedeth.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 69ef117674ef..26fc00a9ff83 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -109,6 +109,7 @@
109 * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup. 109 * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup.
110 * 0.55: 22 Mar 2006: Add flow control (pause frame). 110 * 0.55: 22 Mar 2006: Add flow control (pause frame).
111 * 0.56: 22 Mar 2006: Additional ethtool config and moduleparam support. 111 * 0.56: 22 Mar 2006: Additional ethtool config and moduleparam support.
112 * 0.57: 14 May 2006: Mac address set in probe/remove and order corrections.
112 * 113 *
113 * Known bugs: 114 * Known bugs:
114 * We suspect that on some hardware no TX done interrupts are generated. 115 * We suspect that on some hardware no TX done interrupts are generated.
@@ -120,7 +121,7 @@
120 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 121 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
121 * superfluous timer interrupts from the nic. 122 * superfluous timer interrupts from the nic.
122 */ 123 */
123#define FORCEDETH_VERSION "0.56" 124#define FORCEDETH_VERSION "0.57"
124#define DRV_NAME "forcedeth" 125#define DRV_NAME "forcedeth"
125 126
126#include <linux/module.h> 127#include <linux/module.h>
@@ -262,7 +263,8 @@ enum {
262 NvRegRingSizes = 0x108, 263 NvRegRingSizes = 0x108,
263#define NVREG_RINGSZ_TXSHIFT 0 264#define NVREG_RINGSZ_TXSHIFT 0
264#define NVREG_RINGSZ_RXSHIFT 16 265#define NVREG_RINGSZ_RXSHIFT 16
265 NvRegUnknownTransmitterReg = 0x10c, 266 NvRegTransmitPoll = 0x10c,
267#define NVREG_TRANSMITPOLL_MAC_ADDR_REV 0x00008000
266 NvRegLinkSpeed = 0x110, 268 NvRegLinkSpeed = 0x110,
267#define NVREG_LINKSPEED_FORCE 0x10000 269#define NVREG_LINKSPEED_FORCE 0x10000
268#define NVREG_LINKSPEED_10 1000 270#define NVREG_LINKSPEED_10 1000
@@ -1178,7 +1180,7 @@ static void nv_stop_tx(struct net_device *dev)
1178 KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); 1180 KERN_INFO "nv_stop_tx: TransmitterStatus remained busy");
1179 1181
1180 udelay(NV_TXSTOP_DELAY2); 1182 udelay(NV_TXSTOP_DELAY2);
1181 writel(0, base + NvRegUnknownTransmitterReg); 1183 writel(readl(base + NvRegTransmitPoll) & NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
1182} 1184}
1183 1185
1184static void nv_txrx_reset(struct net_device *dev) 1186static void nv_txrx_reset(struct net_device *dev)
@@ -3917,7 +3919,7 @@ static int nv_open(struct net_device *dev)
3917 oom = nv_init_ring(dev); 3919 oom = nv_init_ring(dev);
3918 3920
3919 writel(0, base + NvRegLinkSpeed); 3921 writel(0, base + NvRegLinkSpeed);
3920 writel(0, base + NvRegUnknownTransmitterReg); 3922 writel(readl(base + NvRegTransmitPoll) & NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
3921 nv_txrx_reset(dev); 3923 nv_txrx_reset(dev);
3922 writel(0, base + NvRegUnknownSetupReg6); 3924 writel(0, base + NvRegUnknownSetupReg6);
3923 3925
@@ -4082,7 +4084,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
4082 unsigned long addr; 4084 unsigned long addr;
4083 u8 __iomem *base; 4085 u8 __iomem *base;
4084 int err, i; 4086 int err, i;
4085 u32 powerstate; 4087 u32 powerstate, txreg;
4086 4088
4087 dev = alloc_etherdev(sizeof(struct fe_priv)); 4089 dev = alloc_etherdev(sizeof(struct fe_priv));
4088 err = -ENOMEM; 4090 err = -ENOMEM;
@@ -4269,12 +4271,30 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
4269 np->orig_mac[0] = readl(base + NvRegMacAddrA); 4271 np->orig_mac[0] = readl(base + NvRegMacAddrA);
4270 np->orig_mac[1] = readl(base + NvRegMacAddrB); 4272 np->orig_mac[1] = readl(base + NvRegMacAddrB);
4271 4273
4272 dev->dev_addr[0] = (np->orig_mac[1] >> 8) & 0xff; 4274 /* check the workaround bit for correct mac address order */
4273 dev->dev_addr[1] = (np->orig_mac[1] >> 0) & 0xff; 4275 txreg = readl(base + NvRegTransmitPoll);
4274 dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff; 4276 if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
4275 dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff; 4277 /* mac address is already in correct order */
4276 dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff; 4278 dev->dev_addr[0] = (np->orig_mac[0] >> 0) & 0xff;
4277 dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff; 4279 dev->dev_addr[1] = (np->orig_mac[0] >> 8) & 0xff;
4280 dev->dev_addr[2] = (np->orig_mac[0] >> 16) & 0xff;
4281 dev->dev_addr[3] = (np->orig_mac[0] >> 24) & 0xff;
4282 dev->dev_addr[4] = (np->orig_mac[1] >> 0) & 0xff;
4283 dev->dev_addr[5] = (np->orig_mac[1] >> 8) & 0xff;
4284 } else {
4285 /* need to reverse mac address to correct order */
4286 dev->dev_addr[0] = (np->orig_mac[1] >> 8) & 0xff;
4287 dev->dev_addr[1] = (np->orig_mac[1] >> 0) & 0xff;
4288 dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
4289 dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
4290 dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
4291 dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
4292 /* set permanent address to be correct aswell */
4293 np->orig_mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) +
4294 (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
4295 np->orig_mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8);
4296 writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
4297 }
4278 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); 4298 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
4279 4299
4280 if (!is_valid_ether_addr(dev->perm_addr)) { 4300 if (!is_valid_ether_addr(dev->perm_addr)) {