Jarek Kamiński <ja...@vilo.eu.org> :
[...]
> The last 2.6.36 I've tried was 2.6.36-1~experimental.1, I've then
> passsed and returned to 2.6.32 for unrelated problems. I think it wasn't
> affected, but I can re-check it and/or test later 2.6.36 versions if it
> may help.

The patch below against 2.6.37-git + davem's pending fixes (see
http://marc.info/?l=linux-netdev&m=129448910825754) should help.

Can you give it a try ?

r8169: keep firmware in memory.

The firmware agent is not available during resume.

It will help with http://bugs.debian.org/609538 but it will not avoid
the 60 seconds delay when there is no firmware.

Signed-off-by: Francois Romieu <rom...@fr.zoreil.com>
Cc: Hayes <hayesw...@realtek.com>
Cc: Ben Hutchings <b...@debian.org>
---
 drivers/net/r8169.c |   43 +++++++++++++++++++++++++++++++------------
 1 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index dd758cd..7e2f01c 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -554,6 +554,8 @@ struct rtl8169_private {
        struct mii_if_info mii;
        struct rtl8169_counters counters;
        u32 saved_wolopts;
+
+       const struct firmware *fw;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <net...@vger.kernel.org>");
@@ -1668,6 +1670,29 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const 
struct firmware *fw)
        }
 }
 
+static void rtl_release_firmware(struct rtl8169_private *tp)
+{
+       release_firmware(tp->fw);
+       tp->fw = NULL;
+}
+
+static int rtl_apply_firmware(struct rtl8169_private *tp, const char *fw_name)
+{
+       const struct firmware **fw = &tp->fw;
+       int rc = !*fw;
+
+       if (rc) {
+               rc = request_firmware(fw, fw_name, &tp->pci_dev->dev);
+               if (rc < 0)
+                       goto out;
+       }
+
+       /* TODO: release firmware once rtl_phy_write_fw signals failures. */
+       rtl_phy_write_fw(tp, *fw);
+out:
+       return rc;
+}
+
 static void rtl8169s_hw_phy_config(struct rtl8169_private *tp)
 {
        static const struct phy_reg phy_reg_init[] = {
@@ -2041,7 +2066,6 @@ static void rtl8168d_1_hw_phy_config(struct 
rtl8169_private *tp)
                { 0x0d, 0xf880 }
        };
        void __iomem *ioaddr = tp->mmio_addr;
-       const struct firmware *fw;
 
        rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
 
@@ -2105,11 +2129,8 @@ static void rtl8168d_1_hw_phy_config(struct 
rtl8169_private *tp)
 
        rtl_writephy(tp, 0x1f, 0x0005);
        rtl_writephy(tp, 0x05, 0x001b);
-       if (rtl_readphy(tp, 0x06) == 0xbf00 &&
-           request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) {
-               rtl_phy_write_fw(tp, fw);
-               release_firmware(fw);
-       } else {
+       if ((rtl_readphy(tp, 0x06) != 0xbf00) ||
+           (rtl_apply_firmware(tp, FIRMWARE_8168D_1) < 0)) {
                netif_warn(tp, probe, tp->dev, "unable to apply firmware 
patch\n");
        }
 
@@ -2159,7 +2180,6 @@ static void rtl8168d_2_hw_phy_config(struct 
rtl8169_private *tp)
                { 0x0d, 0xf880 }
        };
        void __iomem *ioaddr = tp->mmio_addr;
-       const struct firmware *fw;
 
        rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
 
@@ -2214,11 +2234,8 @@ static void rtl8168d_2_hw_phy_config(struct 
rtl8169_private *tp)
 
        rtl_writephy(tp, 0x1f, 0x0005);
        rtl_writephy(tp, 0x05, 0x001b);
-       if (rtl_readphy(tp, 0x06) == 0xb300 &&
-           request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) {
-               rtl_phy_write_fw(tp, fw);
-               release_firmware(fw);
-       } else {
+       if ((rtl_readphy(tp, 0x06) != 0xb300) ||
+           (rtl_apply_firmware(tp, FIRMWARE_8168D_2) < 0)) {
                netif_warn(tp, probe, tp->dev, "unable to apply firmware 
patch\n");
        }
 
@@ -4662,6 +4679,8 @@ static int rtl8169_close(struct net_device *dev)
        tp->TxDescArray = NULL;
        tp->RxDescArray = NULL;
 
+       rtl_release_firmware(tp);
+
        pm_runtime_put_sync(&pdev->dev);
 
        return 0;
-- 
1.7.3.4




--
To UNSUBSCRIBE, email to debian-kernel-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: 
http://lists.debian.org/20110111132524.ga2...@electric-eye.fr.zoreil.com

Reply via email to