You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
6.1 KiB
222 lines
6.1 KiB
From 2e1781ef47a927e6cdce729f70b3a5732eaedf32 Mon Sep 17 00:00:00 2001
|
|
From: Igor Russkikh <irusskik@redhat.com>
|
|
Date: Fri, 6 Nov 2020 18:36:58 -0500
|
|
Subject: [PATCH 041/139] [netdrv] net: atlantic: refactoring pm logic
|
|
|
|
Message-id: <1604687916-15087-42-git-send-email-irusskik@redhat.com>
|
|
Patchwork-id: 338466
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.4 BZ 1857861 041/139] net: atlantic: refactoring pm logic
|
|
Bugzilla: 1857861
|
|
RH-Acked-by: David Arcari <darcari@redhat.com>
|
|
RH-Acked-by: John Linville <linville@redhat.com>
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
Bugzilla: http://bugzilla.redhat.com/1857861
|
|
|
|
commit 8aaa112a57c1d725c92dfad32c0694bd21b374d0
|
|
Author: Nikita Danilov <ndanilov@marvell.com>
|
|
Date: Thu Nov 7 22:41:52 2019 +0000
|
|
|
|
net: atlantic: refactoring pm logic
|
|
|
|
We now implement .driver.pm callbacks, these
|
|
allows driver to work correctly in hibernate
|
|
usecases, especially when used in conjunction with
|
|
WOL feature.
|
|
|
|
Before that driver only reacted to legacy .suspend/.resume
|
|
callbacks, that was a limitation in some cases.
|
|
|
|
Signed-off-by: Nikita Danilov <ndanilov@marvell.com>
|
|
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
|
Signed-off-by: Igor Russkikh <irusskik@redhat.com>
|
|
|
|
Cc: David Arcari <darcari@redhat.com>
|
|
Cc: Igor Russkikh <irusskik@redhat.com>
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
---
|
|
drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 38 ----------
|
|
drivers/net/ethernet/aquantia/atlantic/aq_nic.h | 1 -
|
|
.../net/ethernet/aquantia/atlantic/aq_pci_func.c | 87 +++++++++++++++++++---
|
|
3 files changed, 78 insertions(+), 48 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
index 75faf288a2fc..d5764228cea5 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
@@ -1057,44 +1057,6 @@ void aq_nic_free_vectors(struct aq_nic_s *self)
|
|
err_exit:;
|
|
}
|
|
|
|
-int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg)
|
|
-{
|
|
- int err = 0;
|
|
-
|
|
- if (!netif_running(self->ndev)) {
|
|
- err = 0;
|
|
- goto out;
|
|
- }
|
|
- rtnl_lock();
|
|
- if (pm_msg->event & PM_EVENT_SLEEP || pm_msg->event & PM_EVENT_FREEZE) {
|
|
- self->power_state = AQ_HW_POWER_STATE_D3;
|
|
- netif_device_detach(self->ndev);
|
|
- netif_tx_stop_all_queues(self->ndev);
|
|
-
|
|
- err = aq_nic_stop(self);
|
|
- if (err < 0)
|
|
- goto err_exit;
|
|
-
|
|
- aq_nic_deinit(self, !self->aq_hw->aq_nic_cfg->wol);
|
|
- } else {
|
|
- err = aq_nic_init(self);
|
|
- if (err < 0)
|
|
- goto err_exit;
|
|
-
|
|
- err = aq_nic_start(self);
|
|
- if (err < 0)
|
|
- goto err_exit;
|
|
-
|
|
- netif_device_attach(self->ndev);
|
|
- netif_tx_start_all_queues(self->ndev);
|
|
- }
|
|
-
|
|
-err_exit:
|
|
- rtnl_unlock();
|
|
-out:
|
|
- return err;
|
|
-}
|
|
-
|
|
void aq_nic_shutdown(struct aq_nic_s *self)
|
|
{
|
|
int err = 0;
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
|
|
index 8c23ad4ddf38..ab3176dfc209 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
|
|
@@ -157,7 +157,6 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
|
|
const struct ethtool_link_ksettings *cmd);
|
|
struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
|
|
u32 aq_nic_get_fw_version(struct aq_nic_s *self);
|
|
-int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg);
|
|
int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
|
|
void aq_nic_shutdown(struct aq_nic_s *self);
|
|
u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type);
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
|
|
index e82c96b50373..3169951fe6ab 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
|
|
@@ -347,29 +347,98 @@ static void aq_pci_shutdown(struct pci_dev *pdev)
|
|
}
|
|
}
|
|
|
|
-static int aq_pci_suspend(struct pci_dev *pdev, pm_message_t pm_msg)
|
|
+static int aq_suspend_common(struct device *dev, bool deep)
|
|
{
|
|
- struct aq_nic_s *self = pci_get_drvdata(pdev);
|
|
+ struct aq_nic_s *nic = pci_get_drvdata(to_pci_dev(dev));
|
|
+
|
|
+ rtnl_lock();
|
|
+
|
|
+ nic->power_state = AQ_HW_POWER_STATE_D3;
|
|
+ netif_device_detach(nic->ndev);
|
|
+ netif_tx_stop_all_queues(nic->ndev);
|
|
|
|
- return aq_nic_change_pm_state(self, &pm_msg);
|
|
+ aq_nic_stop(nic);
|
|
+
|
|
+ if (deep) {
|
|
+ aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol);
|
|
+ aq_nic_set_power(nic);
|
|
+ }
|
|
+
|
|
+ rtnl_unlock();
|
|
+
|
|
+ return 0;
|
|
}
|
|
|
|
-static int aq_pci_resume(struct pci_dev *pdev)
|
|
+static int atl_resume_common(struct device *dev, bool deep)
|
|
{
|
|
- struct aq_nic_s *self = pci_get_drvdata(pdev);
|
|
- pm_message_t pm_msg = PMSG_RESTORE;
|
|
+ struct pci_dev *pdev = to_pci_dev(dev);
|
|
+ struct aq_nic_s *nic;
|
|
+ int ret;
|
|
+
|
|
+ nic = pci_get_drvdata(pdev);
|
|
+
|
|
+ rtnl_lock();
|
|
+
|
|
+ pci_set_power_state(pdev, PCI_D0);
|
|
+ pci_restore_state(pdev);
|
|
+
|
|
+ if (deep) {
|
|
+ ret = aq_nic_init(nic);
|
|
+ if (ret)
|
|
+ goto err_exit;
|
|
+ }
|
|
+
|
|
+ ret = aq_nic_start(nic);
|
|
+ if (ret)
|
|
+ goto err_exit;
|
|
+
|
|
+ netif_device_attach(nic->ndev);
|
|
+ netif_tx_start_all_queues(nic->ndev);
|
|
|
|
- return aq_nic_change_pm_state(self, &pm_msg);
|
|
+err_exit:
|
|
+ rtnl_unlock();
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int aq_pm_freeze(struct device *dev)
|
|
+{
|
|
+ return aq_suspend_common(dev, false);
|
|
}
|
|
|
|
+static int aq_pm_suspend_poweroff(struct device *dev)
|
|
+{
|
|
+ return aq_suspend_common(dev, true);
|
|
+}
|
|
+
|
|
+static int aq_pm_thaw(struct device *dev)
|
|
+{
|
|
+ return atl_resume_common(dev, false);
|
|
+}
|
|
+
|
|
+static int aq_pm_resume_restore(struct device *dev)
|
|
+{
|
|
+ return atl_resume_common(dev, true);
|
|
+}
|
|
+
|
|
+const struct dev_pm_ops aq_pm_ops = {
|
|
+ .suspend = aq_pm_suspend_poweroff,
|
|
+ .poweroff = aq_pm_suspend_poweroff,
|
|
+ .freeze = aq_pm_freeze,
|
|
+ .resume = aq_pm_resume_restore,
|
|
+ .restore = aq_pm_resume_restore,
|
|
+ .thaw = aq_pm_thaw,
|
|
+};
|
|
+
|
|
static struct pci_driver aq_pci_ops = {
|
|
.name = AQ_CFG_DRV_NAME,
|
|
.id_table = aq_pci_tbl,
|
|
.probe = aq_pci_probe,
|
|
.remove = aq_pci_remove,
|
|
- .suspend = aq_pci_suspend,
|
|
- .resume = aq_pci_resume,
|
|
.shutdown = aq_pci_shutdown,
|
|
+#ifdef CONFIG_PM
|
|
+ .driver.pm = &aq_pm_ops,
|
|
+#endif
|
|
};
|
|
|
|
int aq_pci_func_register_driver(void)
|
|
--
|
|
2.13.6
|
|
|