aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tulip
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-29 13:48:48 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-29 13:48:48 -0400
commite389f9aec689209724105ae80a6c91fd2e747bc9 (patch)
tree3cc88a3e785e4f2ffeaa9dad0da695cfa437d4fe /drivers/net/tulip
parentf73b0a08eae0e28c50db5dd5ab8245546918bfb6 (diff)
parentb4cf205846463a0a23a917bb18ad833bc9a8c0bb (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (107 commits) smc911x: fix compilation breakage wjen debug is on [netdrvr] eexpress: minor corrections add NAPI support to sb1250-mac.c ixgb: ROUND_UP macro cleanup in drivers/net/ixgb e1000: ROUND_UP macro cleanup in drivers/net/e1000 Generic HDLC sparse annotations e100: Optionally use I/O mode only to access register space e100: allow bad MAC address when running with invalid eeprom csum ehea: fix for dlpar support ehea: fix for sysfs entries 3C509: Remove unnecessary include of <linux/pm_legacy.h> NetXen: Fix for vmalloc issues NetXen: Fixes for Power PC architecture NetXen: Port swap feature for multi port cards NetXen: Removal of redundant macros NetXen: Multi PCI support for Quad cards NetXen: Removal of redundant argument passing NetXen: Use multiple PCI functions [netdrvr e100] experiment with doing RX in a similar manner to eepro100 [PATCH] ieee80211: add missing global needed by IEEE80211_DEBUG_XXXX ...
Diffstat (limited to 'drivers/net/tulip')
-rw-r--r--drivers/net/tulip/dmfe.c118
-rw-r--r--drivers/net/tulip/interrupt.c4
-rw-r--r--drivers/net/tulip/media.c40
-rw-r--r--drivers/net/tulip/tulip.h9
-rw-r--r--drivers/net/tulip/tulip_core.c6
-rw-r--r--drivers/net/tulip/winbond-840.c2
6 files changed, 162 insertions, 17 deletions
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index b3a64ca98634..4ed67ff0e81e 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -55,9 +55,6 @@
55 55
56 TODO 56 TODO
57 57
58 Implement pci_driver::suspend() and pci_driver::resume()
59 power management methods.
60
61 Check on 64 bit boxes. 58 Check on 64 bit boxes.
62 Check and fix on big endian boxes. 59 Check and fix on big endian boxes.
63 60
@@ -125,6 +122,11 @@
125#define DM9801_NOISE_FLOOR 8 122#define DM9801_NOISE_FLOOR 8
126#define DM9802_NOISE_FLOOR 5 123#define DM9802_NOISE_FLOOR 5
127 124
125#define DMFE_WOL_LINKCHANGE 0x20000000
126#define DMFE_WOL_SAMPLEPACKET 0x10000000
127#define DMFE_WOL_MAGICPACKET 0x08000000
128
129
128#define DMFE_10MHF 0 130#define DMFE_10MHF 0
129#define DMFE_100MHF 1 131#define DMFE_100MHF 1
130#define DMFE_10MFD 4 132#define DMFE_10MFD 4
@@ -251,6 +253,7 @@ struct dmfe_board_info {
251 u8 wait_reset; /* Hardware failed, need to reset */ 253 u8 wait_reset; /* Hardware failed, need to reset */
252 u8 dm910x_chk_mode; /* Operating mode check */ 254 u8 dm910x_chk_mode; /* Operating mode check */
253 u8 first_in_callback; /* Flag to record state */ 255 u8 first_in_callback; /* Flag to record state */
256 u8 wol_mode; /* user WOL settings */
254 struct timer_list timer; 257 struct timer_list timer;
255 258
256 /* System defined statistic counter */ 259 /* System defined statistic counter */
@@ -431,6 +434,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
431 db->chip_id = ent->driver_data; 434 db->chip_id = ent->driver_data;
432 db->ioaddr = pci_resource_start(pdev, 0); 435 db->ioaddr = pci_resource_start(pdev, 0);
433 db->chip_revision = dev_rev; 436 db->chip_revision = dev_rev;
437 db->wol_mode = 0;
434 438
435 db->pdev = pdev; 439 db->pdev = pdev;
436 440
@@ -1065,7 +1069,11 @@ static void dmfe_set_filter_mode(struct DEVICE * dev)
1065 spin_unlock_irqrestore(&db->lock, flags); 1069 spin_unlock_irqrestore(&db->lock, flags);
1066} 1070}
1067 1071
1068static void netdev_get_drvinfo(struct net_device *dev, 1072/*
1073 * Ethtool interace
1074 */
1075
1076static void dmfe_ethtool_get_drvinfo(struct net_device *dev,
1069 struct ethtool_drvinfo *info) 1077 struct ethtool_drvinfo *info)
1070{ 1078{
1071 struct dmfe_board_info *np = netdev_priv(dev); 1079 struct dmfe_board_info *np = netdev_priv(dev);
@@ -1079,9 +1087,35 @@ static void netdev_get_drvinfo(struct net_device *dev,
1079 dev->base_addr, dev->irq); 1087 dev->base_addr, dev->irq);
1080} 1088}
1081 1089
1090static int dmfe_ethtool_set_wol(struct net_device *dev,
1091 struct ethtool_wolinfo *wolinfo)
1092{
1093 struct dmfe_board_info *db = netdev_priv(dev);
1094
1095 if (wolinfo->wolopts & (WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
1096 WAKE_ARP | WAKE_MAGICSECURE))
1097 return -EOPNOTSUPP;
1098
1099 db->wol_mode = wolinfo->wolopts;
1100 return 0;
1101}
1102
1103static void dmfe_ethtool_get_wol(struct net_device *dev,
1104 struct ethtool_wolinfo *wolinfo)
1105{
1106 struct dmfe_board_info *db = netdev_priv(dev);
1107
1108 wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
1109 wolinfo->wolopts = db->wol_mode;
1110 return;
1111}
1112
1113
1082static const struct ethtool_ops netdev_ethtool_ops = { 1114static const struct ethtool_ops netdev_ethtool_ops = {
1083 .get_drvinfo = netdev_get_drvinfo, 1115 .get_drvinfo = dmfe_ethtool_get_drvinfo,
1084 .get_link = ethtool_op_get_link, 1116 .get_link = ethtool_op_get_link,
1117 .set_wol = dmfe_ethtool_set_wol,
1118 .get_wol = dmfe_ethtool_get_wol,
1085}; 1119};
1086 1120
1087/* 1121/*
@@ -2050,11 +2084,85 @@ static struct pci_device_id dmfe_pci_tbl[] = {
2050MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl); 2084MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl);
2051 2085
2052 2086
2087#ifdef CONFIG_PM
2088static int dmfe_suspend(struct pci_dev *pci_dev, pm_message_t state)
2089{
2090 struct net_device *dev = pci_get_drvdata(pci_dev);
2091 struct dmfe_board_info *db = netdev_priv(dev);
2092 u32 tmp;
2093
2094 /* Disable upper layer interface */
2095 netif_device_detach(dev);
2096
2097 /* Disable Tx/Rx */
2098 db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);
2099 update_cr6(db->cr6_data, dev->base_addr);
2100
2101 /* Disable Interrupt */
2102 outl(0, dev->base_addr + DCR7);
2103 outl(inl (dev->base_addr + DCR5), dev->base_addr + DCR5);
2104
2105 /* Fre RX buffers */
2106 dmfe_free_rxbuffer(db);
2107
2108 /* Enable WOL */
2109 pci_read_config_dword(pci_dev, 0x40, &tmp);
2110 tmp &= ~(DMFE_WOL_LINKCHANGE|DMFE_WOL_MAGICPACKET);
2111
2112 if (db->wol_mode & WAKE_PHY)
2113 tmp |= DMFE_WOL_LINKCHANGE;
2114 if (db->wol_mode & WAKE_MAGIC)
2115 tmp |= DMFE_WOL_MAGICPACKET;
2116
2117 pci_write_config_dword(pci_dev, 0x40, tmp);
2118
2119 pci_enable_wake(pci_dev, PCI_D3hot, 1);
2120 pci_enable_wake(pci_dev, PCI_D3cold, 1);
2121
2122 /* Power down device*/
2123 pci_set_power_state(pci_dev, pci_choose_state (pci_dev,state));
2124 pci_save_state(pci_dev);
2125
2126 return 0;
2127}
2128
2129static int dmfe_resume(struct pci_dev *pci_dev)
2130{
2131 struct net_device *dev = pci_get_drvdata(pci_dev);
2132 u32 tmp;
2133
2134 pci_restore_state(pci_dev);
2135 pci_set_power_state(pci_dev, PCI_D0);
2136
2137 /* Re-initilize DM910X board */
2138 dmfe_init_dm910x(dev);
2139
2140 /* Disable WOL */
2141 pci_read_config_dword(pci_dev, 0x40, &tmp);
2142
2143 tmp &= ~(DMFE_WOL_LINKCHANGE | DMFE_WOL_MAGICPACKET);
2144 pci_write_config_dword(pci_dev, 0x40, tmp);
2145
2146 pci_enable_wake(pci_dev, PCI_D3hot, 0);
2147 pci_enable_wake(pci_dev, PCI_D3cold, 0);
2148
2149 /* Restart upper layer interface */
2150 netif_device_attach(dev);
2151
2152 return 0;
2153}
2154#else
2155#define dmfe_suspend NULL
2156#define dmfe_resume NULL
2157#endif
2158
2053static struct pci_driver dmfe_driver = { 2159static struct pci_driver dmfe_driver = {
2054 .name = "dmfe", 2160 .name = "dmfe",
2055 .id_table = dmfe_pci_tbl, 2161 .id_table = dmfe_pci_tbl,
2056 .probe = dmfe_init_one, 2162 .probe = dmfe_init_one,
2057 .remove = __devexit_p(dmfe_remove_one), 2163 .remove = __devexit_p(dmfe_remove_one),
2164 .suspend = dmfe_suspend,
2165 .resume = dmfe_resume
2058}; 2166};
2059 2167
2060MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw"); 2168MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index e86df07769a1..9b08afbd1f65 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -673,7 +673,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
673 if (tp->link_change) 673 if (tp->link_change)
674 (tp->link_change)(dev, csr5); 674 (tp->link_change)(dev, csr5);
675 } 675 }
676 if (csr5 & SytemError) { 676 if (csr5 & SystemError) {
677 int error = (csr5 >> 23) & 7; 677 int error = (csr5 >> 23) & 7;
678 /* oops, we hit a PCI error. The code produced corresponds 678 /* oops, we hit a PCI error. The code produced corresponds
679 * to the reason: 679 * to the reason:
@@ -743,7 +743,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
743 TxFIFOUnderflow | 743 TxFIFOUnderflow |
744 TxJabber | 744 TxJabber |
745 TPLnkFail | 745 TPLnkFail |
746 SytemError )) != 0); 746 SystemError )) != 0);
747#else 747#else
748 } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0); 748 } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0);
749 749
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index 20bd52b86993..b56256636543 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -44,8 +44,10 @@ static const unsigned char comet_miireg2offset[32] = {
44 44
45/* MII transceiver control section. 45/* MII transceiver control section.
46 Read and write the MII registers using software-generated serial 46 Read and write the MII registers using software-generated serial
47 MDIO protocol. See the MII specifications or DP83840A data sheet 47 MDIO protocol.
48 for details. */ 48 See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
49 or DP83840A data sheet for more details.
50 */
49 51
50int tulip_mdio_read(struct net_device *dev, int phy_id, int location) 52int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
51{ 53{
@@ -261,24 +263,56 @@ void tulip_select_media(struct net_device *dev, int startup)
261 u16 *reset_sequence = &((u16*)(p+3))[init_length]; 263 u16 *reset_sequence = &((u16*)(p+3))[init_length];
262 int reset_length = p[2 + init_length*2]; 264 int reset_length = p[2 + init_length*2];
263 misc_info = reset_sequence + reset_length; 265 misc_info = reset_sequence + reset_length;
264 if (startup) 266 if (startup) {
267 int timeout = 10; /* max 1 ms */
265 for (i = 0; i < reset_length; i++) 268 for (i = 0; i < reset_length; i++)
266 iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); 269 iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
270
271 /* flush posted writes */
272 ioread32(ioaddr + CSR15);
273
274 /* Sect 3.10.3 in DP83840A.pdf (p39) */
275 udelay(500);
276
277 /* Section 4.2 in DP83840A.pdf (p43) */
278 /* and IEEE 802.3 "22.2.4.1.1 Reset" */
279 while (timeout-- &&
280 (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
281 udelay(100);
282 }
267 for (i = 0; i < init_length; i++) 283 for (i = 0; i < init_length; i++)
268 iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); 284 iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
285
286 ioread32(ioaddr + CSR15); /* flush posted writes */
269 } else { 287 } else {
270 u8 *init_sequence = p + 2; 288 u8 *init_sequence = p + 2;
271 u8 *reset_sequence = p + 3 + init_length; 289 u8 *reset_sequence = p + 3 + init_length;
272 int reset_length = p[2 + init_length]; 290 int reset_length = p[2 + init_length];
273 misc_info = (u16*)(reset_sequence + reset_length); 291 misc_info = (u16*)(reset_sequence + reset_length);
274 if (startup) { 292 if (startup) {
293 int timeout = 10; /* max 1 ms */
275 iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12); 294 iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
276 for (i = 0; i < reset_length; i++) 295 for (i = 0; i < reset_length; i++)
277 iowrite32(reset_sequence[i], ioaddr + CSR12); 296 iowrite32(reset_sequence[i], ioaddr + CSR12);
297
298 /* flush posted writes */
299 ioread32(ioaddr + CSR12);
300
301 /* Sect 3.10.3 in DP83840A.pdf (p39) */
302 udelay(500);
303
304 /* Section 4.2 in DP83840A.pdf (p43) */
305 /* and IEEE 802.3 "22.2.4.1.1 Reset" */
306 while (timeout-- &&
307 (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
308 udelay(100);
278 } 309 }
279 for (i = 0; i < init_length; i++) 310 for (i = 0; i < init_length; i++)
280 iowrite32(init_sequence[i], ioaddr + CSR12); 311 iowrite32(init_sequence[i], ioaddr + CSR12);
312
313 ioread32(ioaddr + CSR12); /* flush posted writes */
281 } 314 }
315
282 tmp_info = get_u16(&misc_info[1]); 316 tmp_info = get_u16(&misc_info[1]);
283 if (tmp_info) 317 if (tmp_info)
284 tp->advertising[phy_num] = tmp_info | 1; 318 tp->advertising[phy_num] = tmp_info | 1;
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 25f25da76917..c840d2e67b23 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -132,7 +132,7 @@ enum pci_cfg_driver_reg {
132/* The bits in the CSR5 status registers, mostly interrupt sources. */ 132/* The bits in the CSR5 status registers, mostly interrupt sources. */
133enum status_bits { 133enum status_bits {
134 TimerInt = 0x800, 134 TimerInt = 0x800,
135 SytemError = 0x2000, 135 SystemError = 0x2000,
136 TPLnkFail = 0x1000, 136 TPLnkFail = 0x1000,
137 TPLnkPass = 0x10, 137 TPLnkPass = 0x10,
138 NormalIntr = 0x10000, 138 NormalIntr = 0x10000,
@@ -482,8 +482,11 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp)
482 udelay(10); 482 udelay(10);
483 483
484 if (!i) 484 if (!i)
485 printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n", 485 printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
486 pci_name(tp->pdev)); 486 " (CSR5 0x%x CSR6 0x%x)\n",
487 pci_name(tp->pdev),
488 ioread32(ioaddr + CSR5),
489 ioread32(ioaddr + CSR6));
487 } 490 }
488} 491}
489 492
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index e9bf526ec534..041af63f2811 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -17,11 +17,11 @@
17 17
18#define DRV_NAME "tulip" 18#define DRV_NAME "tulip"
19#ifdef CONFIG_TULIP_NAPI 19#ifdef CONFIG_TULIP_NAPI
20#define DRV_VERSION "1.1.14-NAPI" /* Keep at least for test */ 20#define DRV_VERSION "1.1.15-NAPI" /* Keep at least for test */
21#else 21#else
22#define DRV_VERSION "1.1.14" 22#define DRV_VERSION "1.1.15"
23#endif 23#endif
24#define DRV_RELDATE "May 11, 2002" 24#define DRV_RELDATE "Feb 27, 2007"
25 25
26 26
27#include <linux/module.h> 27#include <linux/module.h>
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 5b71ac78bca2..fa440706fb4a 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -1147,7 +1147,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
1147 } 1147 }
1148 1148
1149 /* Abnormal error summary/uncommon events handlers. */ 1149 /* Abnormal error summary/uncommon events handlers. */
1150 if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SytemError | 1150 if (intr_status & (AbnormalIntr | TxFIFOUnderflow | SystemError |
1151 TimerInt | TxDied)) 1151 TimerInt | TxDied))
1152 netdev_error(dev, intr_status); 1152 netdev_error(dev, intr_status);
1153 1153