aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-03-20 20:48:03 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 20:48:03 -0500
commitbc1c756741b065cfebf850e4164c0e2aae9d527f (patch)
treee462b85564a66b0c4f41e0d9f1ccde7c98ba00a9 /drivers
parent4e3a7aaa28db952392814f889dfbd25672266d29 (diff)
[TG3]: Support shutdown WoL.
Support WoL during shutdown by calling tg3_set_power_state(tp, PCI_D3hot) during tg3_close(). Change the power state parameter to pci_power_t type and use constants defined in pci.h. Certain ethtool operations cannot be performed after tg3_close() because the device will go to low power state. Add return -EAGAIN in such cases where appropriate. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tg3.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 7deebd74223e..01fed17d076f 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1042,9 +1042,11 @@ static void tg3_frob_aux_power(struct tg3 *tp)
1042 struct net_device *dev_peer; 1042 struct net_device *dev_peer;
1043 1043
1044 dev_peer = pci_get_drvdata(tp->pdev_peer); 1044 dev_peer = pci_get_drvdata(tp->pdev_peer);
1045 /* remove_one() may have been run on the peer. */
1045 if (!dev_peer) 1046 if (!dev_peer)
1046 BUG(); 1047 tp_peer = tp;
1047 tp_peer = netdev_priv(dev_peer); 1048 else
1049 tp_peer = netdev_priv(dev_peer);
1048 } 1050 }
1049 1051
1050 if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || 1052 if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
@@ -1135,7 +1137,7 @@ static int tg3_halt_cpu(struct tg3 *, u32);
1135static int tg3_nvram_lock(struct tg3 *); 1137static int tg3_nvram_lock(struct tg3 *);
1136static void tg3_nvram_unlock(struct tg3 *); 1138static void tg3_nvram_unlock(struct tg3 *);
1137 1139
1138static int tg3_set_power_state(struct tg3 *tp, int state) 1140static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
1139{ 1141{
1140 u32 misc_host_ctrl; 1142 u32 misc_host_ctrl;
1141 u16 power_control, power_caps; 1143 u16 power_control, power_caps;
@@ -1154,7 +1156,7 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
1154 power_control |= PCI_PM_CTRL_PME_STATUS; 1156 power_control |= PCI_PM_CTRL_PME_STATUS;
1155 power_control &= ~(PCI_PM_CTRL_STATE_MASK); 1157 power_control &= ~(PCI_PM_CTRL_STATE_MASK);
1156 switch (state) { 1158 switch (state) {
1157 case 0: 1159 case PCI_D0:
1158 power_control |= 0; 1160 power_control |= 0;
1159 pci_write_config_word(tp->pdev, 1161 pci_write_config_word(tp->pdev,
1160 pm + PCI_PM_CTRL, 1162 pm + PCI_PM_CTRL,
@@ -1167,15 +1169,15 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
1167 1169
1168 return 0; 1170 return 0;
1169 1171
1170 case 1: 1172 case PCI_D1:
1171 power_control |= 1; 1173 power_control |= 1;
1172 break; 1174 break;
1173 1175
1174 case 2: 1176 case PCI_D2:
1175 power_control |= 2; 1177 power_control |= 2;
1176 break; 1178 break;
1177 1179
1178 case 3: 1180 case PCI_D3hot:
1179 power_control |= 3; 1181 power_control |= 3;
1180 break; 1182 break;
1181 1183
@@ -6206,7 +6208,7 @@ static int tg3_init_hw(struct tg3 *tp)
6206 int err; 6208 int err;
6207 6209
6208 /* Force the chip into D0. */ 6210 /* Force the chip into D0. */
6209 err = tg3_set_power_state(tp, 0); 6211 err = tg3_set_power_state(tp, PCI_D0);
6210 if (err) 6212 if (err)
6211 goto out; 6213 goto out;
6212 6214
@@ -6493,6 +6495,10 @@ static int tg3_open(struct net_device *dev)
6493 6495
6494 tg3_full_lock(tp, 0); 6496 tg3_full_lock(tp, 0);
6495 6497
6498 err = tg3_set_power_state(tp, PCI_D0);
6499 if (err)
6500 return err;
6501
6496 tg3_disable_ints(tp); 6502 tg3_disable_ints(tp);
6497 tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; 6503 tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
6498 6504
@@ -6872,7 +6878,6 @@ static int tg3_close(struct net_device *dev)
6872 tp->tg3_flags &= 6878 tp->tg3_flags &=
6873 ~(TG3_FLAG_INIT_COMPLETE | 6879 ~(TG3_FLAG_INIT_COMPLETE |
6874 TG3_FLAG_GOT_SERDES_FLOWCTL); 6880 TG3_FLAG_GOT_SERDES_FLOWCTL);
6875 netif_carrier_off(tp->dev);
6876 6881
6877 tg3_full_unlock(tp); 6882 tg3_full_unlock(tp);
6878 6883
@@ -6889,6 +6894,10 @@ static int tg3_close(struct net_device *dev)
6889 6894
6890 tg3_free_consistent(tp); 6895 tg3_free_consistent(tp);
6891 6896
6897 tg3_set_power_state(tp, PCI_D3hot);
6898
6899 netif_carrier_off(tp->dev);
6900
6892 return 0; 6901 return 0;
6893} 6902}
6894 6903
@@ -7207,6 +7216,9 @@ static void tg3_get_regs(struct net_device *dev,
7207 7216
7208 memset(p, 0, TG3_REGDUMP_LEN); 7217 memset(p, 0, TG3_REGDUMP_LEN);
7209 7218
7219 if (tp->link_config.phy_is_low_power)
7220 return;
7221
7210 tg3_full_lock(tp, 0); 7222 tg3_full_lock(tp, 0);
7211 7223
7212#define __GET_REG32(reg) (*(p)++ = tr32(reg)) 7224#define __GET_REG32(reg) (*(p)++ = tr32(reg))
@@ -7281,6 +7293,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
7281 u8 *pd; 7293 u8 *pd;
7282 u32 i, offset, len, val, b_offset, b_count; 7294 u32 i, offset, len, val, b_offset, b_count;
7283 7295
7296 if (tp->link_config.phy_is_low_power)
7297 return -EAGAIN;
7298
7284 offset = eeprom->offset; 7299 offset = eeprom->offset;
7285 len = eeprom->len; 7300 len = eeprom->len;
7286 eeprom->len = 0; 7301 eeprom->len = 0;
@@ -7342,6 +7357,9 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
7342 u32 offset, len, b_offset, odd_len, start, end; 7357 u32 offset, len, b_offset, odd_len, start, end;
7343 u8 *buf; 7358 u8 *buf;
7344 7359
7360 if (tp->link_config.phy_is_low_power)
7361 return -EAGAIN;
7362
7345 if (eeprom->magic != TG3_EEPROM_MAGIC) 7363 if (eeprom->magic != TG3_EEPROM_MAGIC)
7346 return -EINVAL; 7364 return -EINVAL;
7347 7365
@@ -8262,6 +8280,9 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
8262{ 8280{
8263 struct tg3 *tp = netdev_priv(dev); 8281 struct tg3 *tp = netdev_priv(dev);
8264 8282
8283 if (tp->link_config.phy_is_low_power)
8284 tg3_set_power_state(tp, PCI_D0);
8285
8265 memset(data, 0, sizeof(u64) * TG3_NUM_TEST); 8286 memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
8266 8287
8267 if (tg3_test_nvram(tp) != 0) { 8288 if (tg3_test_nvram(tp) != 0) {
@@ -8319,6 +8340,9 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
8319 8340
8320 tg3_full_unlock(tp); 8341 tg3_full_unlock(tp);
8321 } 8342 }
8343 if (tp->link_config.phy_is_low_power)
8344 tg3_set_power_state(tp, PCI_D3hot);
8345
8322} 8346}
8323 8347
8324static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 8348static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -8338,6 +8362,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
8338 if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) 8362 if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
8339 break; /* We have no PHY */ 8363 break; /* We have no PHY */
8340 8364
8365 if (tp->link_config.phy_is_low_power)
8366 return -EAGAIN;
8367
8341 spin_lock_bh(&tp->lock); 8368 spin_lock_bh(&tp->lock);
8342 err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval); 8369 err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
8343 spin_unlock_bh(&tp->lock); 8370 spin_unlock_bh(&tp->lock);
@@ -8354,6 +8381,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
8354 if (!capable(CAP_NET_ADMIN)) 8381 if (!capable(CAP_NET_ADMIN))
8355 return -EPERM; 8382 return -EPERM;
8356 8383
8384 if (tp->link_config.phy_is_low_power)
8385 return -EAGAIN;
8386
8357 spin_lock_bh(&tp->lock); 8387 spin_lock_bh(&tp->lock);
8358 err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in); 8388 err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
8359 spin_unlock_bh(&tp->lock); 8389 spin_unlock_bh(&tp->lock);
@@ -9805,7 +9835,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
9805 tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; 9835 tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
9806 9836
9807 /* Force the chip into D0. */ 9837 /* Force the chip into D0. */
9808 err = tg3_set_power_state(tp, 0); 9838 err = tg3_set_power_state(tp, PCI_D0);
9809 if (err) { 9839 if (err) {
9810 printk(KERN_ERR PFX "(%s) transition to D0 failed\n", 9840 printk(KERN_ERR PFX "(%s) transition to D0 failed\n",
9811 pci_name(tp->pdev)); 9841 pci_name(tp->pdev));
@@ -11078,7 +11108,7 @@ static int tg3_resume(struct pci_dev *pdev)
11078 11108
11079 pci_restore_state(tp->pdev); 11109 pci_restore_state(tp->pdev);
11080 11110
11081 err = tg3_set_power_state(tp, 0); 11111 err = tg3_set_power_state(tp, PCI_D0);
11082 if (err) 11112 if (err)
11083 return err; 11113 return err;
11084 11114