Re: USB Hid Timeout and r8169 module to trust HW if present.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, Now i got it working without user meddeling at all:


From: Lauri Jakku <lja@xxxxxx>

Date: Mon, 9 Aug 2021 21:44:53 +0300
Subject: [PATCH] net:realtek:r8169 driver load fix

   net:realtek:r8169

     Problem:

       The driver seems not to work at first run for some HW's, not even
       when proper hardware is detected by it at the first probe.

     Solution:

       the driver will trust the hardware that reports valid ID and then
       make re-loading of the module as it would being reloaded manually.


Signed-off-by: Lauri Jakku <lja@xxxxxx>
---
 .../drivers/net/ethernet/realtek/r8169_main.c | 35 ++++++++++++++---
 linux-5.14-rc4/drivers/net/phy/phy_device.c   | 38 +++++++++++++++++++
 2 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/linux-5.14-rc4/drivers/net/ethernet/realtek/r8169_main.c b/linux-5.14-rc4/drivers/net/ethernet/realtek/r8169_main.c
index c7af5bc3b..d8e602527 100644
--- a/linux-5.14-rc4/drivers/net/ethernet/realtek/r8169_main.c
+++ b/linux-5.14-rc4/drivers/net/ethernet/realtek/r8169_main.c
@@ -634,6 +634,8 @@ struct rtl8169_private {
     struct rtl_fw *rtl_fw;
 
     u32 ocp_base;
+
+    int retry_probeing;
 };
 
 typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
@@ -5097,13 +5099,16 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
     tp->phydev = mdiobus_get_phy(new_bus, 0);
     if (!tp->phydev) {
         return -ENODEV;
-    } else if (!tp->phydev->drv) {
-        /* Most chip versions fail with the genphy driver.
-         * Therefore ensure that the dedicated PHY driver is loaded.
+    } else if (tp->phydev->phy_id != RTL_GIGA_MAC_NONE) {
+        /* Most chip versions fail with the genphy driver, BUT do rerport valid IW
+         * ID. Re-starting the module seem to fix the issue of non-functional driver.
          */
-        dev_err(&pdev->dev, "no dedicated PHY driver found for PHY ID 0x%08x, maybe realtek.ko needs to be added to initramfs?\n",
+        dev_err(&pdev->dev,
+            "no dedicated driver, but HW found: PHY PHY ID 0x%08x\n",
             tp->phydev->phy_id);
-        return -EUNATCH;
+
+        dev_err(&pdev->dev, "trying re-probe few times..\n");
+
     }
 
     tp->phydev->mac_managed_pm = 1;
@@ -5250,6 +5255,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
     enum mac_version chipset;
     struct net_device *dev;
     u16 xid;
+    int savederr = 0;
 
     dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp));
     if (!dev)
@@ -5261,6 +5267,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
     tp->dev = dev;
     tp->pci_dev = pdev;
     tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
+    tp->retry_probeing = 0;
     tp->eee_adv = -1;
     tp->ocp_base = OCP_STD_PHY_BASE;
 
@@ -5410,7 +5417,15 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
     pci_set_drvdata(pdev, tp);
 
-    rc = r8169_mdio_register(tp);
+    savederr = r8169_mdio_register(tp);
+
+    if (
+        (tp->retry_probeing > 0) &&
+        (savederr == -EAGAIN)
+       ) {
+        netdev_info(dev, " retry of probe requested..............");
+    }
+
     if (rc)
         return rc;
 
@@ -5435,6 +5450,14 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
     if (pci_dev_run_wake(pdev))
         pm_runtime_put_sync(&pdev->dev);
 
+    if (
+        (tp->retry_probeing > 0) &&
+        (savederr == -EAGAIN)
+       ) {
+        netdev_info(dev, " retry of probe requested..............");
+        return savederr;
+    }
+
     return 0;
 }
 
diff --git a/linux-5.14-rc4/drivers/net/phy/phy_device.c b/linux-5.14-rc4/drivers/net/phy/phy_device.c
index 5d5f9a9ee..59c6ac031 100644
--- a/linux-5.14-rc4/drivers/net/phy/phy_device.c
+++ b/linux-5.14-rc4/drivers/net/phy/phy_device.c
@@ -2980,6 +2980,9 @@ struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode)
 }
 EXPORT_SYMBOL_GPL(fwnode_get_phy_node);
 
+
+static int phy_remove(struct device *dev);
+
 /**
  * phy_probe - probe and init a PHY device
  * @dev: device to probe and init
@@ -2988,13 +2991,22 @@ EXPORT_SYMBOL_GPL(fwnode_get_phy_node);
  *   set the state to READY (the driver's init function should
  *   set it to STARTING if needed).
  */
+#define REDO_PROBE_TIMES    5
 static int phy_probe(struct device *dev)
 {
     struct phy_device *phydev = to_phy_device(dev);
     struct device_driver *drv = phydev->mdio.dev.driver;
     struct phy_driver *phydrv = to_phy_driver(drv);
+    int again = 0;
+    int savederr = 0;
+again_retry:
     int err = 0;
 
+    if (again > 0) {
+        pr_err("%s: Re-probe %d of driver.....\n",
+               phydrv->name, again);
+    }
+
     phydev->drv = phydrv;
 
     /* Disable the interrupt if the PHY doesn't support it
@@ -3013,6 +3025,17 @@ static int phy_probe(struct device *dev)
 
     if (phydev->drv->probe) {
         err = phydev->drv->probe(phydev);
+
+        /* If again requested. */
+        if (err == -EAGAIN) {
+            again++;
+            savederr = err;
+            err = 0;
+
+            pr_info("%s: EAGAIN: %d ...\n",
+                phydrv->name, again);
+        }
+
         if (err)
             goto out;
     }
@@ -3081,6 +3104,20 @@ static int phy_probe(struct device *dev)
 
     mutex_unlock(&phydev->lock);
 
+    if ((savederr == -EAGAIN) &&
+        ((again > 0) && (again < REDO_PROBE_TIMES))
+       ) {
+        pr_err("%s: Retry removal driver..\n",
+            phydrv->name);
+
+        phy_remove(dev);
+
+        pr_err("%s: Re-probe driver..\n",
+            phydrv->name);
+        savederr = 0;
+        goto again_retry;
+    }
+
     return err;
 }
 
@@ -3108,6 +3145,7 @@ static int phy_remove(struct device *dev)
     return 0;
 }
 
+
 static void phy_shutdown(struct device *dev)
 {
     struct phy_device *phydev = to_phy_device(dev);
-- 
2.17.1





[Index of Archives]     [Kernel Development]     [Kernel Announce]     [Kernel Newbies]     [Linux Networking Development]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Device Mapper]

  Powered by Linux