diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-29 13:48:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-29 13:48:48 -0400 |
commit | e389f9aec689209724105ae80a6c91fd2e747bc9 (patch) | |
tree | 3cc88a3e785e4f2ffeaa9dad0da695cfa437d4fe /drivers/net/tulip | |
parent | f73b0a08eae0e28c50db5dd5ab8245546918bfb6 (diff) | |
parent | b4cf205846463a0a23a917bb18ad833bc9a8c0bb (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.c | 118 | ||||
-rw-r--r-- | drivers/net/tulip/interrupt.c | 4 | ||||
-rw-r--r-- | drivers/net/tulip/media.c | 40 | ||||
-rw-r--r-- | drivers/net/tulip/tulip.h | 9 | ||||
-rw-r--r-- | drivers/net/tulip/tulip_core.c | 6 | ||||
-rw-r--r-- | drivers/net/tulip/winbond-840.c | 2 |
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 | ||
1068 | static void netdev_get_drvinfo(struct net_device *dev, | 1072 | /* |
1073 | * Ethtool interace | ||
1074 | */ | ||
1075 | |||
1076 | static 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 | ||
1090 | static 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 | |||
1103 | static 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 | |||
1082 | static const struct ethtool_ops netdev_ethtool_ops = { | 1114 | static 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[] = { | |||
2050 | MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl); | 2084 | MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl); |
2051 | 2085 | ||
2052 | 2086 | ||
2087 | #ifdef CONFIG_PM | ||
2088 | static 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 | |||
2129 | static 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 | |||
2053 | static struct pci_driver dmfe_driver = { | 2159 | static 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 | ||
2060 | MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw"); | 2168 | MODULE_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 | ||
50 | int tulip_mdio_read(struct net_device *dev, int phy_id, int location) | 52 | int 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. */ |
133 | enum status_bits { | 133 | enum 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 | ||