diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2013-07-03 15:48:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-07-03 19:35:49 -0400 |
commit | bc2bebe8de8ed4ba6482c9cc370b0dd72ffe8cd2 (patch) | |
tree | 926f3dffa87c7de6f8f88eaeebe79e81042ecabf /drivers/net/ethernet/atheros | |
parent | 0c1072ae0242fbdffd9a0bba36e7a7033d287f9c (diff) |
alx: remove WoL support
Unfortunately, WoL is broken and the system will immediately
resume after suspending, and I can't seem to figure out why.
Remove WoL support until the issue can be found.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros')
-rw-r--r-- | drivers/net/ethernet/atheros/alx/ethtool.c | 36 | ||||
-rw-r--r-- | drivers/net/ethernet/atheros/alx/hw.c | 155 | ||||
-rw-r--r-- | drivers/net/ethernet/atheros/alx/hw.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/atheros/alx/main.c | 142 |
4 files changed, 15 insertions, 323 deletions
diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c index 926100626d60..45b36507abc1 100644 --- a/drivers/net/ethernet/atheros/alx/ethtool.c +++ b/drivers/net/ethernet/atheros/alx/ethtool.c | |||
@@ -201,40 +201,6 @@ static void alx_set_msglevel(struct net_device *netdev, u32 data) | |||
201 | alx->msg_enable = data; | 201 | alx->msg_enable = data; |
202 | } | 202 | } |
203 | 203 | ||
204 | static void alx_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | ||
205 | { | ||
206 | struct alx_priv *alx = netdev_priv(netdev); | ||
207 | struct alx_hw *hw = &alx->hw; | ||
208 | |||
209 | wol->supported = WAKE_MAGIC | WAKE_PHY; | ||
210 | wol->wolopts = 0; | ||
211 | |||
212 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC) | ||
213 | wol->wolopts |= WAKE_MAGIC; | ||
214 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) | ||
215 | wol->wolopts |= WAKE_PHY; | ||
216 | } | ||
217 | |||
218 | static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | ||
219 | { | ||
220 | struct alx_priv *alx = netdev_priv(netdev); | ||
221 | struct alx_hw *hw = &alx->hw; | ||
222 | |||
223 | if (wol->wolopts & ~(WAKE_MAGIC | WAKE_PHY)) | ||
224 | return -EOPNOTSUPP; | ||
225 | |||
226 | hw->sleep_ctrl = 0; | ||
227 | |||
228 | if (wol->wolopts & WAKE_MAGIC) | ||
229 | hw->sleep_ctrl |= ALX_SLEEP_WOL_MAGIC; | ||
230 | if (wol->wolopts & WAKE_PHY) | ||
231 | hw->sleep_ctrl |= ALX_SLEEP_WOL_PHY; | ||
232 | |||
233 | device_set_wakeup_enable(&alx->hw.pdev->dev, hw->sleep_ctrl); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | const struct ethtool_ops alx_ethtool_ops = { | 204 | const struct ethtool_ops alx_ethtool_ops = { |
239 | .get_settings = alx_get_settings, | 205 | .get_settings = alx_get_settings, |
240 | .set_settings = alx_set_settings, | 206 | .set_settings = alx_set_settings, |
@@ -242,7 +208,5 @@ const struct ethtool_ops alx_ethtool_ops = { | |||
242 | .set_pauseparam = alx_set_pauseparam, | 208 | .set_pauseparam = alx_set_pauseparam, |
243 | .get_msglevel = alx_get_msglevel, | 209 | .get_msglevel = alx_get_msglevel, |
244 | .set_msglevel = alx_set_msglevel, | 210 | .set_msglevel = alx_set_msglevel, |
245 | .get_wol = alx_get_wol, | ||
246 | .set_wol = alx_set_wol, | ||
247 | .get_link = ethtool_op_get_link, | 211 | .get_link = ethtool_op_get_link, |
248 | }; | 212 | }; |
diff --git a/drivers/net/ethernet/atheros/alx/hw.c b/drivers/net/ethernet/atheros/alx/hw.c index ea99e5d8743f..1e8c24a3cb4e 100644 --- a/drivers/net/ethernet/atheros/alx/hw.c +++ b/drivers/net/ethernet/atheros/alx/hw.c | |||
@@ -332,16 +332,6 @@ void alx_set_macaddr(struct alx_hw *hw, const u8 *addr) | |||
332 | alx_write_mem32(hw, ALX_STAD1, val); | 332 | alx_write_mem32(hw, ALX_STAD1, val); |
333 | } | 333 | } |
334 | 334 | ||
335 | static void alx_enable_osc(struct alx_hw *hw) | ||
336 | { | ||
337 | u32 val; | ||
338 | |||
339 | /* rising edge */ | ||
340 | val = alx_read_mem32(hw, ALX_MISC); | ||
341 | alx_write_mem32(hw, ALX_MISC, val & ~ALX_MISC_INTNLOSC_OPEN); | ||
342 | alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN); | ||
343 | } | ||
344 | |||
345 | static void alx_reset_osc(struct alx_hw *hw, u8 rev) | 335 | static void alx_reset_osc(struct alx_hw *hw, u8 rev) |
346 | { | 336 | { |
347 | u32 val, val2; | 337 | u32 val, val2; |
@@ -858,66 +848,6 @@ void alx_post_phy_link(struct alx_hw *hw) | |||
858 | } | 848 | } |
859 | } | 849 | } |
860 | 850 | ||
861 | |||
862 | /* NOTE: | ||
863 | * 1. phy link must be established before calling this function | ||
864 | * 2. wol option (pattern,magic,link,etc.) is configed before call it. | ||
865 | */ | ||
866 | int alx_pre_suspend(struct alx_hw *hw, int speed, u8 duplex) | ||
867 | { | ||
868 | u32 master, mac, phy, val; | ||
869 | int err = 0; | ||
870 | |||
871 | master = alx_read_mem32(hw, ALX_MASTER); | ||
872 | master &= ~ALX_MASTER_PCLKSEL_SRDS; | ||
873 | mac = hw->rx_ctrl; | ||
874 | /* 10/100 half */ | ||
875 | ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, ALX_MAC_CTRL_SPEED_10_100); | ||
876 | mac &= ~(ALX_MAC_CTRL_FULLD | ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_TX_EN); | ||
877 | |||
878 | phy = alx_read_mem32(hw, ALX_PHY_CTRL); | ||
879 | phy &= ~(ALX_PHY_CTRL_DSPRST_OUT | ALX_PHY_CTRL_CLS); | ||
880 | phy |= ALX_PHY_CTRL_RST_ANALOG | ALX_PHY_CTRL_HIB_PULSE | | ||
881 | ALX_PHY_CTRL_HIB_EN; | ||
882 | |||
883 | /* without any activity */ | ||
884 | if (!(hw->sleep_ctrl & ALX_SLEEP_ACTIVE)) { | ||
885 | err = alx_write_phy_reg(hw, ALX_MII_IER, 0); | ||
886 | if (err) | ||
887 | return err; | ||
888 | phy |= ALX_PHY_CTRL_IDDQ | ALX_PHY_CTRL_POWER_DOWN; | ||
889 | } else { | ||
890 | if (hw->sleep_ctrl & (ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_CIFS)) | ||
891 | mac |= ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_BRD_EN; | ||
892 | if (hw->sleep_ctrl & ALX_SLEEP_CIFS) | ||
893 | mac |= ALX_MAC_CTRL_TX_EN; | ||
894 | if (duplex == DUPLEX_FULL) | ||
895 | mac |= ALX_MAC_CTRL_FULLD; | ||
896 | if (speed == SPEED_1000) | ||
897 | ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, | ||
898 | ALX_MAC_CTRL_SPEED_1000); | ||
899 | phy |= ALX_PHY_CTRL_DSPRST_OUT; | ||
900 | err = alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, | ||
901 | ALX_MIIEXT_S3DIG10, | ||
902 | ALX_MIIEXT_S3DIG10_SL); | ||
903 | if (err) | ||
904 | return err; | ||
905 | } | ||
906 | |||
907 | alx_enable_osc(hw); | ||
908 | hw->rx_ctrl = mac; | ||
909 | alx_write_mem32(hw, ALX_MASTER, master); | ||
910 | alx_write_mem32(hw, ALX_MAC_CTRL, mac); | ||
911 | alx_write_mem32(hw, ALX_PHY_CTRL, phy); | ||
912 | |||
913 | /* set val of PDLL D3PLLOFF */ | ||
914 | val = alx_read_mem32(hw, ALX_PDLL_TRNS1); | ||
915 | val |= ALX_PDLL_TRNS1_D3PLLOFF_EN; | ||
916 | alx_write_mem32(hw, ALX_PDLL_TRNS1, val); | ||
917 | |||
918 | return 0; | ||
919 | } | ||
920 | |||
921 | bool alx_phy_configured(struct alx_hw *hw) | 851 | bool alx_phy_configured(struct alx_hw *hw) |
922 | { | 852 | { |
923 | u32 cfg, hw_cfg; | 853 | u32 cfg, hw_cfg; |
@@ -990,26 +920,6 @@ int alx_clear_phy_intr(struct alx_hw *hw) | |||
990 | return alx_read_phy_reg(hw, ALX_MII_ISR, &isr); | 920 | return alx_read_phy_reg(hw, ALX_MII_ISR, &isr); |
991 | } | 921 | } |
992 | 922 | ||
993 | int alx_config_wol(struct alx_hw *hw) | ||
994 | { | ||
995 | u32 wol = 0; | ||
996 | int err = 0; | ||
997 | |||
998 | /* turn on magic packet event */ | ||
999 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC) | ||
1000 | wol |= ALX_WOL0_MAGIC_EN | ALX_WOL0_PME_MAGIC_EN; | ||
1001 | |||
1002 | /* turn on link up event */ | ||
1003 | if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) { | ||
1004 | wol |= ALX_WOL0_LINK_EN | ALX_WOL0_PME_LINK; | ||
1005 | /* only link up can wake up */ | ||
1006 | err = alx_write_phy_reg(hw, ALX_MII_IER, ALX_IER_LINK_UP); | ||
1007 | } | ||
1008 | alx_write_mem32(hw, ALX_WOL0, wol); | ||
1009 | |||
1010 | return err; | ||
1011 | } | ||
1012 | |||
1013 | void alx_disable_rss(struct alx_hw *hw) | 923 | void alx_disable_rss(struct alx_hw *hw) |
1014 | { | 924 | { |
1015 | u32 ctrl = alx_read_mem32(hw, ALX_RXQ0); | 925 | u32 ctrl = alx_read_mem32(hw, ALX_RXQ0); |
@@ -1121,71 +1031,6 @@ void alx_configure_basic(struct alx_hw *hw) | |||
1121 | alx_write_mem32(hw, ALX_WRR, val); | 1031 | alx_write_mem32(hw, ALX_WRR, val); |
1122 | } | 1032 | } |
1123 | 1033 | ||
1124 | int alx_select_powersaving_speed(struct alx_hw *hw, int *speed, u8 *duplex) | ||
1125 | { | ||
1126 | int i, err; | ||
1127 | u16 lpa; | ||
1128 | |||
1129 | err = alx_read_phy_link(hw); | ||
1130 | if (err) | ||
1131 | return err; | ||
1132 | |||
1133 | if (hw->link_speed == SPEED_UNKNOWN) { | ||
1134 | *speed = SPEED_UNKNOWN; | ||
1135 | *duplex = DUPLEX_UNKNOWN; | ||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1139 | err = alx_read_phy_reg(hw, MII_LPA, &lpa); | ||
1140 | if (err) | ||
1141 | return err; | ||
1142 | |||
1143 | if (!(lpa & LPA_LPACK)) { | ||
1144 | *speed = hw->link_speed; | ||
1145 | return 0; | ||
1146 | } | ||
1147 | |||
1148 | if (lpa & LPA_10FULL) { | ||
1149 | *speed = SPEED_10; | ||
1150 | *duplex = DUPLEX_FULL; | ||
1151 | } else if (lpa & LPA_10HALF) { | ||
1152 | *speed = SPEED_10; | ||
1153 | *duplex = DUPLEX_HALF; | ||
1154 | } else if (lpa & LPA_100FULL) { | ||
1155 | *speed = SPEED_100; | ||
1156 | *duplex = DUPLEX_FULL; | ||
1157 | } else { | ||
1158 | *speed = SPEED_100; | ||
1159 | *duplex = DUPLEX_HALF; | ||
1160 | } | ||
1161 | |||
1162 | if (*speed == hw->link_speed && *duplex == hw->duplex) | ||
1163 | return 0; | ||
1164 | err = alx_write_phy_reg(hw, ALX_MII_IER, 0); | ||
1165 | if (err) | ||
1166 | return err; | ||
1167 | err = alx_setup_speed_duplex(hw, alx_speed_to_ethadv(*speed, *duplex) | | ||
1168 | ADVERTISED_Autoneg, ALX_FC_ANEG | | ||
1169 | ALX_FC_RX | ALX_FC_TX); | ||
1170 | if (err) | ||
1171 | return err; | ||
1172 | |||
1173 | /* wait for linkup */ | ||
1174 | for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) { | ||
1175 | msleep(100); | ||
1176 | |||
1177 | err = alx_read_phy_link(hw); | ||
1178 | if (err < 0) | ||
1179 | return err; | ||
1180 | if (hw->link_speed != SPEED_UNKNOWN) | ||
1181 | break; | ||
1182 | } | ||
1183 | if (i == ALX_MAX_SETUP_LNK_CYCLE) | ||
1184 | return -ETIMEDOUT; | ||
1185 | |||
1186 | return 0; | ||
1187 | } | ||
1188 | |||
1189 | bool alx_get_phy_info(struct alx_hw *hw) | 1034 | bool alx_get_phy_info(struct alx_hw *hw) |
1190 | { | 1035 | { |
1191 | u16 devs1, devs2; | 1036 | u16 devs1, devs2; |
diff --git a/drivers/net/ethernet/atheros/alx/hw.h b/drivers/net/ethernet/atheros/alx/hw.h index a60e35c1c1b5..96f3b4381e17 100644 --- a/drivers/net/ethernet/atheros/alx/hw.h +++ b/drivers/net/ethernet/atheros/alx/hw.h | |||
@@ -418,8 +418,6 @@ struct alx_hw { | |||
418 | u8 flowctrl; | 418 | u8 flowctrl; |
419 | u32 adv_cfg; | 419 | u32 adv_cfg; |
420 | 420 | ||
421 | u32 sleep_ctrl; | ||
422 | |||
423 | spinlock_t mdio_lock; | 421 | spinlock_t mdio_lock; |
424 | struct mdio_if_info mdio; | 422 | struct mdio_if_info mdio; |
425 | u16 phy_id[2]; | 423 | u16 phy_id[2]; |
@@ -479,14 +477,12 @@ void alx_reset_pcie(struct alx_hw *hw); | |||
479 | void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en); | 477 | void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en); |
480 | int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl); | 478 | int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl); |
481 | void alx_post_phy_link(struct alx_hw *hw); | 479 | void alx_post_phy_link(struct alx_hw *hw); |
482 | int alx_pre_suspend(struct alx_hw *hw, int speed, u8 duplex); | ||
483 | int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data); | 480 | int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data); |
484 | int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data); | 481 | int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data); |
485 | int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata); | 482 | int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata); |
486 | int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data); | 483 | int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data); |
487 | int alx_read_phy_link(struct alx_hw *hw); | 484 | int alx_read_phy_link(struct alx_hw *hw); |
488 | int alx_clear_phy_intr(struct alx_hw *hw); | 485 | int alx_clear_phy_intr(struct alx_hw *hw); |
489 | int alx_config_wol(struct alx_hw *hw); | ||
490 | void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc); | 486 | void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc); |
491 | void alx_start_mac(struct alx_hw *hw); | 487 | void alx_start_mac(struct alx_hw *hw); |
492 | int alx_reset_mac(struct alx_hw *hw); | 488 | int alx_reset_mac(struct alx_hw *hw); |
@@ -494,7 +490,6 @@ void alx_set_macaddr(struct alx_hw *hw, const u8 *addr); | |||
494 | bool alx_phy_configured(struct alx_hw *hw); | 490 | bool alx_phy_configured(struct alx_hw *hw); |
495 | void alx_configure_basic(struct alx_hw *hw); | 491 | void alx_configure_basic(struct alx_hw *hw); |
496 | void alx_disable_rss(struct alx_hw *hw); | 492 | void alx_disable_rss(struct alx_hw *hw); |
497 | int alx_select_powersaving_speed(struct alx_hw *hw, int *speed, u8 *duplex); | ||
498 | bool alx_get_phy_info(struct alx_hw *hw); | 493 | bool alx_get_phy_info(struct alx_hw *hw); |
499 | 494 | ||
500 | static inline u32 alx_speed_to_ethadv(int speed, u8 duplex) | 495 | static inline u32 alx_speed_to_ethadv(int speed, u8 duplex) |
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 148b4b976474..0e0b242a9dd4 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
@@ -706,7 +706,6 @@ static int alx_init_sw(struct alx_priv *alx) | |||
706 | alx->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8); | 706 | alx->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8); |
707 | alx->tx_ringsz = 256; | 707 | alx->tx_ringsz = 256; |
708 | alx->rx_ringsz = 512; | 708 | alx->rx_ringsz = 512; |
709 | hw->sleep_ctrl = ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_WOL_PHY; | ||
710 | hw->imt = 200; | 709 | hw->imt = 200; |
711 | alx->int_mask = ALX_ISR_MISC; | 710 | alx->int_mask = ALX_ISR_MISC; |
712 | hw->dma_chnl = hw->max_dma_chnl; | 711 | hw->dma_chnl = hw->max_dma_chnl; |
@@ -961,66 +960,6 @@ static int alx_stop(struct net_device *netdev) | |||
961 | return 0; | 960 | return 0; |
962 | } | 961 | } |
963 | 962 | ||
964 | static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en) | ||
965 | { | ||
966 | struct alx_priv *alx = pci_get_drvdata(pdev); | ||
967 | struct net_device *netdev = alx->dev; | ||
968 | struct alx_hw *hw = &alx->hw; | ||
969 | int err, speed; | ||
970 | u8 duplex; | ||
971 | |||
972 | netif_device_detach(netdev); | ||
973 | |||
974 | if (netif_running(netdev)) | ||
975 | __alx_stop(alx); | ||
976 | |||
977 | #ifdef CONFIG_PM_SLEEP | ||
978 | err = pci_save_state(pdev); | ||
979 | if (err) | ||
980 | return err; | ||
981 | #endif | ||
982 | |||
983 | err = alx_select_powersaving_speed(hw, &speed, &duplex); | ||
984 | if (err) | ||
985 | return err; | ||
986 | err = alx_clear_phy_intr(hw); | ||
987 | if (err) | ||
988 | return err; | ||
989 | err = alx_pre_suspend(hw, speed, duplex); | ||
990 | if (err) | ||
991 | return err; | ||
992 | err = alx_config_wol(hw); | ||
993 | if (err) | ||
994 | return err; | ||
995 | |||
996 | *wol_en = false; | ||
997 | if (hw->sleep_ctrl & ALX_SLEEP_ACTIVE) { | ||
998 | netif_info(alx, wol, netdev, | ||
999 | "wol: ctrl=%X, speed=%X\n", | ||
1000 | hw->sleep_ctrl, speed); | ||
1001 | device_set_wakeup_enable(&pdev->dev, true); | ||
1002 | *wol_en = true; | ||
1003 | } | ||
1004 | |||
1005 | pci_disable_device(pdev); | ||
1006 | |||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | static void alx_shutdown(struct pci_dev *pdev) | ||
1011 | { | ||
1012 | int err; | ||
1013 | bool wol_en; | ||
1014 | |||
1015 | err = __alx_shutdown(pdev, &wol_en); | ||
1016 | if (!err) { | ||
1017 | pci_wake_from_d3(pdev, wol_en); | ||
1018 | pci_set_power_state(pdev, PCI_D3hot); | ||
1019 | } else { | ||
1020 | dev_err(&pdev->dev, "shutdown fail %d\n", err); | ||
1021 | } | ||
1022 | } | ||
1023 | |||
1024 | static void alx_link_check(struct work_struct *work) | 963 | static void alx_link_check(struct work_struct *work) |
1025 | { | 964 | { |
1026 | struct alx_priv *alx; | 965 | struct alx_priv *alx; |
@@ -1399,8 +1338,6 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1399 | goto out_unmap; | 1338 | goto out_unmap; |
1400 | } | 1339 | } |
1401 | 1340 | ||
1402 | device_set_wakeup_enable(&pdev->dev, hw->sleep_ctrl); | ||
1403 | |||
1404 | netdev_info(netdev, | 1341 | netdev_info(netdev, |
1405 | "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n", | 1342 | "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n", |
1406 | netdev->dev_addr); | 1343 | netdev->dev_addr); |
@@ -1445,22 +1382,12 @@ static void alx_remove(struct pci_dev *pdev) | |||
1445 | static int alx_suspend(struct device *dev) | 1382 | static int alx_suspend(struct device *dev) |
1446 | { | 1383 | { |
1447 | struct pci_dev *pdev = to_pci_dev(dev); | 1384 | struct pci_dev *pdev = to_pci_dev(dev); |
1448 | int err; | 1385 | struct alx_priv *alx = pci_get_drvdata(pdev); |
1449 | bool wol_en; | ||
1450 | |||
1451 | err = __alx_shutdown(pdev, &wol_en); | ||
1452 | if (err) { | ||
1453 | dev_err(&pdev->dev, "shutdown fail in suspend %d\n", err); | ||
1454 | return err; | ||
1455 | } | ||
1456 | |||
1457 | if (wol_en) { | ||
1458 | pci_prepare_to_sleep(pdev); | ||
1459 | } else { | ||
1460 | pci_wake_from_d3(pdev, false); | ||
1461 | pci_set_power_state(pdev, PCI_D3hot); | ||
1462 | } | ||
1463 | 1386 | ||
1387 | if (!netif_running(alx->dev)) | ||
1388 | return 0; | ||
1389 | netif_device_detach(alx->dev); | ||
1390 | __alx_stop(alx); | ||
1464 | return 0; | 1391 | return 0; |
1465 | } | 1392 | } |
1466 | 1393 | ||
@@ -1468,49 +1395,20 @@ static int alx_resume(struct device *dev) | |||
1468 | { | 1395 | { |
1469 | struct pci_dev *pdev = to_pci_dev(dev); | 1396 | struct pci_dev *pdev = to_pci_dev(dev); |
1470 | struct alx_priv *alx = pci_get_drvdata(pdev); | 1397 | struct alx_priv *alx = pci_get_drvdata(pdev); |
1471 | struct net_device *netdev = alx->dev; | ||
1472 | struct alx_hw *hw = &alx->hw; | ||
1473 | int err; | ||
1474 | |||
1475 | pci_set_power_state(pdev, PCI_D0); | ||
1476 | pci_restore_state(pdev); | ||
1477 | pci_save_state(pdev); | ||
1478 | |||
1479 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
1480 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
1481 | |||
1482 | hw->link_speed = SPEED_UNKNOWN; | ||
1483 | alx->int_mask = ALX_ISR_MISC; | ||
1484 | |||
1485 | alx_reset_pcie(hw); | ||
1486 | alx_reset_phy(hw); | ||
1487 | |||
1488 | err = alx_reset_mac(hw); | ||
1489 | if (err) { | ||
1490 | netif_err(alx, hw, alx->dev, | ||
1491 | "resume:reset_mac fail %d\n", err); | ||
1492 | return -EIO; | ||
1493 | } | ||
1494 | |||
1495 | err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl); | ||
1496 | if (err) { | ||
1497 | netif_err(alx, hw, alx->dev, | ||
1498 | "resume:setup_speed_duplex fail %d\n", err); | ||
1499 | return -EIO; | ||
1500 | } | ||
1501 | |||
1502 | if (netif_running(netdev)) { | ||
1503 | err = __alx_open(alx, true); | ||
1504 | if (err) | ||
1505 | return err; | ||
1506 | } | ||
1507 | |||
1508 | netif_device_attach(netdev); | ||
1509 | 1398 | ||
1510 | return err; | 1399 | if (!netif_running(alx->dev)) |
1400 | return 0; | ||
1401 | netif_device_attach(alx->dev); | ||
1402 | return __alx_open(alx, true); | ||
1511 | } | 1403 | } |
1404 | |||
1405 | static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume); | ||
1406 | #define ALX_PM_OPS (&alx_pm_ops) | ||
1407 | #else | ||
1408 | #define ALX_PM_OPS NULL | ||
1512 | #endif | 1409 | #endif |
1513 | 1410 | ||
1411 | |||
1514 | static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev, | 1412 | static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev, |
1515 | pci_channel_state_t state) | 1413 | pci_channel_state_t state) |
1516 | { | 1414 | { |
@@ -1553,8 +1451,6 @@ static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev) | |||
1553 | } | 1451 | } |
1554 | 1452 | ||
1555 | pci_set_master(pdev); | 1453 | pci_set_master(pdev); |
1556 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
1557 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
1558 | 1454 | ||
1559 | alx_reset_pcie(hw); | 1455 | alx_reset_pcie(hw); |
1560 | if (!alx_reset_mac(hw)) | 1456 | if (!alx_reset_mac(hw)) |
@@ -1590,13 +1486,6 @@ static const struct pci_error_handlers alx_err_handlers = { | |||
1590 | .resume = alx_pci_error_resume, | 1486 | .resume = alx_pci_error_resume, |
1591 | }; | 1487 | }; |
1592 | 1488 | ||
1593 | #ifdef CONFIG_PM_SLEEP | ||
1594 | static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume); | ||
1595 | #define ALX_PM_OPS (&alx_pm_ops) | ||
1596 | #else | ||
1597 | #define ALX_PM_OPS NULL | ||
1598 | #endif | ||
1599 | |||
1600 | static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = { | 1489 | static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = { |
1601 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8161), | 1490 | { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8161), |
1602 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, | 1491 | .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG }, |
@@ -1614,7 +1503,6 @@ static struct pci_driver alx_driver = { | |||
1614 | .id_table = alx_pci_tbl, | 1503 | .id_table = alx_pci_tbl, |
1615 | .probe = alx_probe, | 1504 | .probe = alx_probe, |
1616 | .remove = alx_remove, | 1505 | .remove = alx_remove, |
1617 | .shutdown = alx_shutdown, | ||
1618 | .err_handler = &alx_err_handlers, | 1506 | .err_handler = &alx_err_handlers, |
1619 | .driver.pm = ALX_PM_OPS, | 1507 | .driver.pm = ALX_PM_OPS, |
1620 | }; | 1508 | }; |