The three of you reported an MSI-X-related error when the system
resumes from suspend. This has been fixed for now by disabling MSI-X
on certain chip versions. However more versions may be affected.

I checked with Realtek and they confirmed that on certain chip
versions a MSIX-related value in PCI config space is reset when
resuming from S3.

I would appreciate if you could test the following experimental patch
and whether warning "MSIX address lost, re-configuring" appears in
your dmesg output after resume from suspend.

Thanks a lot for your efforts.

Heiner

---
 drivers/net/ethernet/realtek/r8169.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c 
b/drivers/net/ethernet/realtek/r8169.c
index 0d9c38318..56b4bdff9 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -690,6 +690,8 @@ struct rtl8169_private {
        struct rtl8169_counters *counters;
        struct rtl8169_tc_offsets tc_offset;
        u32 saved_wolopts;
+       u32 saved_msix_addr_lo;
+       u32 saved_msix_addr_hi;
 
        struct rtl_fw {
                const struct firmware *fw;
@@ -6876,6 +6878,19 @@ static int rtl8169_resume(struct device *device)
 {
        struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *dev = pci_get_drvdata(pdev);
+       struct rtl8169_private *tp = netdev_priv(dev);
+       u32 val;
+
+       /* Some chip versions loose these values when resuming */
+       if (pdev->msix_enabled) {
+               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_4, &val);
+               if (!val)
+                       dev_warn(device, "MSIX address lost, re-configuring\n");
+               pci_write_config_dword(pdev, PCI_BASE_ADDRESS_4,
+                                      tp->saved_msix_addr_lo);
+               pci_write_config_dword(pdev, PCI_BASE_ADDRESS_5,
+                                      tp->saved_msix_addr_hi);
+       }
 
        if (netif_running(dev))
                __rtl8169_resume(dev);
@@ -7076,11 +7091,6 @@ static int rtl_alloc_irq(struct rtl8169_private *tp)
                RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable);
                RTL_W8(tp, Cfg9346, Cfg9346_Lock);
                flags = PCI_IRQ_LEGACY;
-       } else if (tp->mac_version == RTL_GIGA_MAC_VER_40) {
-               /* This version was reported to have issues with resume
-                * from suspend when using MSI-X
-                */
-               flags = PCI_IRQ_LEGACY | PCI_IRQ_MSI;
        } else {
                flags = PCI_IRQ_ALL_TYPES;
        }
@@ -7355,6 +7365,13 @@ static int rtl_init_one(struct pci_dev *pdev, const 
struct pci_device_id *ent)
                return rc;
        }
 
+       if (pdev->msix_enabled) {
+               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_4,
+                                     &tp->saved_msix_addr_lo);
+               pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5,
+                                     &tp->saved_msix_addr_hi);
+       }
+
        tp->saved_wolopts = __rtl8169_get_wol(tp);
 
        mutex_init(&tp->wk.mutex);
-- 
2.18.0

Reply via email to