summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/atheros/alx/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/atheros/alx/main.c')
-rw-r--r--drivers/net/ethernet/atheros/alx/main.c173
1 files changed, 32 insertions, 141 deletions
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index 418de8b13165..0e0b242a9dd4 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -706,12 +706,12 @@ static int alx_init_sw(struct alx_priv *alx)
alx->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8);
alx->tx_ringsz = 256;
alx->rx_ringsz = 512;
- hw->sleep_ctrl = ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_WOL_PHY;
hw->imt = 200;
alx->int_mask = ALX_ISR_MISC;
hw->dma_chnl = hw->max_dma_chnl;
hw->ith_tpd = alx->tx_ringsz / 3;
hw->link_speed = SPEED_UNKNOWN;
+ hw->duplex = DUPLEX_UNKNOWN;
hw->adv_cfg = ADVERTISED_Autoneg |
ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
@@ -758,6 +758,7 @@ static void alx_halt(struct alx_priv *alx)
alx_netif_stop(alx);
hw->link_speed = SPEED_UNKNOWN;
+ hw->duplex = DUPLEX_UNKNOWN;
alx_reset_mac(hw);
@@ -869,18 +870,18 @@ static void __alx_stop(struct alx_priv *alx)
alx_free_rings(alx);
}
-static const char *alx_speed_desc(u16 speed)
+static const char *alx_speed_desc(struct alx_hw *hw)
{
- switch (speed) {
- case SPEED_1000 + DUPLEX_FULL:
+ switch (alx_speed_to_ethadv(hw->link_speed, hw->duplex)) {
+ case ADVERTISED_1000baseT_Full:
return "1 Gbps Full";
- case SPEED_100 + DUPLEX_FULL:
+ case ADVERTISED_100baseT_Full:
return "100 Mbps Full";
- case SPEED_100 + DUPLEX_HALF:
+ case ADVERTISED_100baseT_Half:
return "100 Mbps Half";
- case SPEED_10 + DUPLEX_FULL:
+ case ADVERTISED_10baseT_Full:
return "10 Mbps Full";
- case SPEED_10 + DUPLEX_HALF:
+ case ADVERTISED_10baseT_Half:
return "10 Mbps Half";
default:
return "Unknown speed";
@@ -891,7 +892,8 @@ static void alx_check_link(struct alx_priv *alx)
{
struct alx_hw *hw = &alx->hw;
unsigned long flags;
- int speed, old_speed;
+ int old_speed;
+ u8 old_duplex;
int err;
/* clear PHY internal interrupt status, otherwise the main
@@ -899,7 +901,9 @@ static void alx_check_link(struct alx_priv *alx)
*/
alx_clear_phy_intr(hw);
- err = alx_get_phy_link(hw, &speed);
+ old_speed = hw->link_speed;
+ old_duplex = hw->duplex;
+ err = alx_read_phy_link(hw);
if (err < 0)
goto reset;
@@ -908,15 +912,12 @@ static void alx_check_link(struct alx_priv *alx)
alx_write_mem32(hw, ALX_IMR, alx->int_mask);
spin_unlock_irqrestore(&alx->irq_lock, flags);
- old_speed = hw->link_speed;
-
- if (old_speed == speed)
+ if (old_speed == hw->link_speed)
return;
- hw->link_speed = speed;
- if (speed != SPEED_UNKNOWN) {
+ if (hw->link_speed != SPEED_UNKNOWN) {
netif_info(alx, link, alx->dev,
- "NIC Up: %s\n", alx_speed_desc(speed));
+ "NIC Up: %s\n", alx_speed_desc(hw));
alx_post_phy_link(hw);
alx_enable_aspm(hw, true, true);
alx_start_mac(hw);
@@ -959,65 +960,6 @@ static int alx_stop(struct net_device *netdev)
return 0;
}
-static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en)
-{
- struct alx_priv *alx = pci_get_drvdata(pdev);
- struct net_device *netdev = alx->dev;
- struct alx_hw *hw = &alx->hw;
- int err, speed;
-
- netif_device_detach(netdev);
-
- if (netif_running(netdev))
- __alx_stop(alx);
-
-#ifdef CONFIG_PM_SLEEP
- err = pci_save_state(pdev);
- if (err)
- return err;
-#endif
-
- err = alx_select_powersaving_speed(hw, &speed);
- if (err)
- return err;
- err = alx_clear_phy_intr(hw);
- if (err)
- return err;
- err = alx_pre_suspend(hw, speed);
- if (err)
- return err;
- err = alx_config_wol(hw);
- if (err)
- return err;
-
- *wol_en = false;
- if (hw->sleep_ctrl & ALX_SLEEP_ACTIVE) {
- netif_info(alx, wol, netdev,
- "wol: ctrl=%X, speed=%X\n",
- hw->sleep_ctrl, speed);
- device_set_wakeup_enable(&pdev->dev, true);
- *wol_en = true;
- }
-
- pci_disable_device(pdev);
-
- return 0;
-}
-
-static void alx_shutdown(struct pci_dev *pdev)
-{
- int err;
- bool wol_en;
-
- err = __alx_shutdown(pdev, &wol_en);
- if (!err) {
- pci_wake_from_d3(pdev, wol_en);
- pci_set_power_state(pdev, PCI_D3hot);
- } else {
- dev_err(&pdev->dev, "shutdown fail %d\n", err);
- }
-}
-
static void alx_link_check(struct work_struct *work)
{
struct alx_priv *alx;
@@ -1396,8 +1338,6 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_unmap;
}
- device_set_wakeup_enable(&pdev->dev, hw->sleep_ctrl);
-
netdev_info(netdev,
"Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n",
netdev->dev_addr);
@@ -1442,22 +1382,12 @@ static void alx_remove(struct pci_dev *pdev)
static int alx_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
- int err;
- bool wol_en;
-
- err = __alx_shutdown(pdev, &wol_en);
- if (err) {
- dev_err(&pdev->dev, "shutdown fail in suspend %d\n", err);
- return err;
- }
-
- if (wol_en) {
- pci_prepare_to_sleep(pdev);
- } else {
- pci_wake_from_d3(pdev, false);
- pci_set_power_state(pdev, PCI_D3hot);
- }
+ struct alx_priv *alx = pci_get_drvdata(pdev);
+ if (!netif_running(alx->dev))
+ return 0;
+ netif_device_detach(alx->dev);
+ __alx_stop(alx);
return 0;
}
@@ -1465,49 +1395,20 @@ static int alx_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct alx_priv *alx = pci_get_drvdata(pdev);
- struct net_device *netdev = alx->dev;
- struct alx_hw *hw = &alx->hw;
- int err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_save_state(pdev);
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
- hw->link_speed = SPEED_UNKNOWN;
- alx->int_mask = ALX_ISR_MISC;
-
- alx_reset_pcie(hw);
- alx_reset_phy(hw);
-
- err = alx_reset_mac(hw);
- if (err) {
- netif_err(alx, hw, alx->dev,
- "resume:reset_mac fail %d\n", err);
- return -EIO;
- }
-
- err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl);
- if (err) {
- netif_err(alx, hw, alx->dev,
- "resume:setup_speed_duplex fail %d\n", err);
- return -EIO;
- }
-
- if (netif_running(netdev)) {
- err = __alx_open(alx, true);
- if (err)
- return err;
- }
-
- netif_device_attach(netdev);
-
- return err;
+ if (!netif_running(alx->dev))
+ return 0;
+ netif_device_attach(alx->dev);
+ return __alx_open(alx, true);
}
+
+static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
+#define ALX_PM_OPS (&alx_pm_ops)
+#else
+#define ALX_PM_OPS NULL
#endif
+
static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
@@ -1550,8 +1451,6 @@ static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev)
}
pci_set_master(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
alx_reset_pcie(hw);
if (!alx_reset_mac(hw))
@@ -1587,13 +1486,6 @@ static const struct pci_error_handlers alx_err_handlers = {
.resume = alx_pci_error_resume,
};
-#ifdef CONFIG_PM_SLEEP
-static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
-#define ALX_PM_OPS (&alx_pm_ops)
-#else
-#define ALX_PM_OPS NULL
-#endif
-
static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = {
{ PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8161),
.driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
@@ -1611,7 +1503,6 @@ static struct pci_driver alx_driver = {
.id_table = alx_pci_tbl,
.probe = alx_probe,
.remove = alx_remove,
- .shutdown = alx_shutdown,
.err_handler = &alx_err_handlers,
.driver.pm = ALX_PM_OPS,
};
OpenPOWER on IntegriCloud