diff options
author | Don Fry <brazilnut@us.ibm.com> | 2006-08-22 13:22:37 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-08-24 00:40:03 -0400 |
commit | 8d91626636ed9ce8b742edb52ae48f2faefd5864 (patch) | |
tree | d6270c4b398f356081b4f078cf32e21bafd23f7e | |
parent | 9a469abe9c6bab3ce237ee433541931bbd827faf (diff) |
[PATCH] pcnet32: break in 2.6.18-rc1 identified
A change I made for 2.6.17 and another for 2.6.18 do not work on older
pcnet32 chips which I do not have access to. If the chip is a 79C970 or
79C965, do not try and suspend or check the link status.
I have tested with a 79C970A, 79C971, 79C972, 79C973, 79C975, 79C976,
and 79C978.
Signed-off-by: Don Fry <brazilnut@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/pcnet32.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 4daafe303358..d50bcb89dd28 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -202,6 +202,8 @@ static int homepna[MAX_UNITS]; | |||
202 | #define CSR15 15 | 202 | #define CSR15 15 |
203 | #define PCNET32_MC_FILTER 8 | 203 | #define PCNET32_MC_FILTER 8 |
204 | 204 | ||
205 | #define PCNET32_79C970A 0x2621 | ||
206 | |||
205 | /* The PCNET32 Rx and Tx ring descriptors. */ | 207 | /* The PCNET32 Rx and Tx ring descriptors. */ |
206 | struct pcnet32_rx_head { | 208 | struct pcnet32_rx_head { |
207 | u32 base; | 209 | u32 base; |
@@ -289,6 +291,7 @@ struct pcnet32_private { | |||
289 | 291 | ||
290 | /* each bit indicates an available PHY */ | 292 | /* each bit indicates an available PHY */ |
291 | u32 phymask; | 293 | u32 phymask; |
294 | unsigned short chip_version; /* which variant this is */ | ||
292 | }; | 295 | }; |
293 | 296 | ||
294 | static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); | 297 | static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *); |
@@ -724,9 +727,11 @@ static u32 pcnet32_get_link(struct net_device *dev) | |||
724 | spin_lock_irqsave(&lp->lock, flags); | 727 | spin_lock_irqsave(&lp->lock, flags); |
725 | if (lp->mii) { | 728 | if (lp->mii) { |
726 | r = mii_link_ok(&lp->mii_if); | 729 | r = mii_link_ok(&lp->mii_if); |
727 | } else { | 730 | } else if (lp->chip_version >= PCNET32_79C970A) { |
728 | ulong ioaddr = dev->base_addr; /* card base I/O address */ | 731 | ulong ioaddr = dev->base_addr; /* card base I/O address */ |
729 | r = (lp->a.read_bcr(ioaddr, 4) != 0xc0); | 732 | r = (lp->a.read_bcr(ioaddr, 4) != 0xc0); |
733 | } else { /* can not detect link on really old chips */ | ||
734 | r = 1; | ||
730 | } | 735 | } |
731 | spin_unlock_irqrestore(&lp->lock, flags); | 736 | spin_unlock_irqrestore(&lp->lock, flags); |
732 | 737 | ||
@@ -1091,6 +1096,10 @@ static int pcnet32_suspend(struct net_device *dev, unsigned long *flags, | |||
1091 | ulong ioaddr = dev->base_addr; | 1096 | ulong ioaddr = dev->base_addr; |
1092 | int ticks; | 1097 | int ticks; |
1093 | 1098 | ||
1099 | /* really old chips have to be stopped. */ | ||
1100 | if (lp->chip_version < PCNET32_79C970A) | ||
1101 | return 0; | ||
1102 | |||
1094 | /* set SUSPEND (SPND) - CSR5 bit 0 */ | 1103 | /* set SUSPEND (SPND) - CSR5 bit 0 */ |
1095 | csr5 = a->read_csr(ioaddr, CSR5); | 1104 | csr5 = a->read_csr(ioaddr, CSR5); |
1096 | a->write_csr(ioaddr, CSR5, csr5 | CSR5_SUSPEND); | 1105 | a->write_csr(ioaddr, CSR5, csr5 | CSR5_SUSPEND); |
@@ -1529,6 +1538,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1529 | lp->mii_if.reg_num_mask = 0x1f; | 1538 | lp->mii_if.reg_num_mask = 0x1f; |
1530 | lp->dxsuflo = dxsuflo; | 1539 | lp->dxsuflo = dxsuflo; |
1531 | lp->mii = mii; | 1540 | lp->mii = mii; |
1541 | lp->chip_version = chip_version; | ||
1532 | lp->msg_enable = pcnet32_debug; | 1542 | lp->msg_enable = pcnet32_debug; |
1533 | if ((cards_found >= MAX_UNITS) | 1543 | if ((cards_found >= MAX_UNITS) |
1534 | || (options[cards_found] > sizeof(options_mapping))) | 1544 | || (options[cards_found] > sizeof(options_mapping))) |
@@ -1839,10 +1849,7 @@ static int pcnet32_open(struct net_device *dev) | |||
1839 | val |= 2; | 1849 | val |= 2; |
1840 | } else if (lp->options & PCNET32_PORT_ASEL) { | 1850 | } else if (lp->options & PCNET32_PORT_ASEL) { |
1841 | /* workaround of xSeries250, turn on for 79C975 only */ | 1851 | /* workaround of xSeries250, turn on for 79C975 only */ |
1842 | i = ((lp->a.read_csr(ioaddr, 88) | | 1852 | if (lp->chip_version == 0x2627) |
1843 | (lp->a. | ||
1844 | read_csr(ioaddr, 89) << 16)) >> 12) & 0xffff; | ||
1845 | if (i == 0x2627) | ||
1846 | val |= 3; | 1853 | val |= 3; |
1847 | } | 1854 | } |
1848 | lp->a.write_bcr(ioaddr, 9, val); | 1855 | lp->a.write_bcr(ioaddr, 9, val); |
@@ -1986,9 +1993,11 @@ static int pcnet32_open(struct net_device *dev) | |||
1986 | 1993 | ||
1987 | netif_start_queue(dev); | 1994 | netif_start_queue(dev); |
1988 | 1995 | ||
1989 | /* Print the link status and start the watchdog */ | 1996 | if (lp->chip_version >= PCNET32_79C970A) { |
1990 | pcnet32_check_media(dev, 1); | 1997 | /* Print the link status and start the watchdog */ |
1991 | mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); | 1998 | pcnet32_check_media(dev, 1); |
1999 | mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); | ||
2000 | } | ||
1992 | 2001 | ||
1993 | i = 0; | 2002 | i = 0; |
1994 | while (i++ < 100) | 2003 | while (i++ < 100) |