r8169: Keep firmware in memory (Closes: #609538)
svn path=/dists/trunk/linux-2.6/; revision=16846
This commit is contained in:
parent
c0b4964a04
commit
3b19bfc2e8
|
@ -3,6 +3,7 @@ linux-2.6 (2.6.37-1~experimental.2) UNRELEASED; urgency=low
|
|||
[ Ben Hutchings ]
|
||||
* [arm] ixp4xx: Revert build fix, now applied upstream which resulted
|
||||
in another build failure
|
||||
* r8169: Keep firmware in memory (Closes: #609538)
|
||||
|
||||
[ Aurelien Jarno ]
|
||||
* [sh4] Export cpu_core_map to fix build failure with CONFIG_SFC=m.
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
From 73a575b628e2ae8e0393399387445eaf1dac3fb7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?fran=C3=A7ois=20romieu?= <romieu@fr.zoreil.com>
|
||||
Date: Thu, 13 Jan 2011 13:07:53 +0000
|
||||
Subject: [PATCH] r8169: keep firmware in memory.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit f1e02ed109df5f99abf942b8ccc99960cb09dd38 upstream.
|
||||
|
||||
The firmware agent is not available during resume. Loading the firmware
|
||||
during open() (see eee3a96c6368f47df8df5bd4ed1843600652b337) is not
|
||||
enough.
|
||||
|
||||
close() is run during resume through rtl8169_reset_task(), whence the
|
||||
mildly natural release of firmware in the driver removal method instead.
|
||||
|
||||
It will help with http://bugs.debian.org/609538. It will not avoid
|
||||
the 60 seconds delay when:
|
||||
- there is no firmware
|
||||
- the driver is loaded and the device is not up before a suspend/resume
|
||||
|
||||
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
|
||||
Tested-by: Jarek Kamiński <jarek@vilo.eu.org>
|
||||
Cc: Hayes <hayeswang@realtek.com>
|
||||
Cc: Ben Hutchings <benh@debian.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
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 49a6db6..a5b0271 100644
|
||||
--- a/drivers/net/r8169.c
|
||||
+++ b/drivers/net/r8169.c
|
||||
@@ -508,6 +508,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 <netdev@vger.kernel.org>");
|
||||
@@ -1458,6 +1460,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(void __iomem *ioaddr)
|
||||
{
|
||||
static const struct phy_reg phy_reg_init[] = {
|
||||
@@ -1833,7 +1858,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_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
|
||||
|
||||
@@ -1897,11 +1921,8 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
|
||||
|
||||
mdio_write(ioaddr, 0x1f, 0x0005);
|
||||
mdio_write(ioaddr, 0x05, 0x001b);
|
||||
- if (mdio_read(ioaddr, 0x06) == 0xbf00 &&
|
||||
- request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) {
|
||||
- rtl_phy_write_fw(tp, fw);
|
||||
- release_firmware(fw);
|
||||
- } else {
|
||||
+ if ((mdio_read(ioaddr, 0x06) != 0xbf00) ||
|
||||
+ (rtl_apply_firmware(tp, FIRMWARE_8168D_1) < 0)) {
|
||||
netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
|
||||
}
|
||||
|
||||
@@ -1951,7 +1972,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_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
|
||||
|
||||
@@ -2006,11 +2026,8 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
|
||||
|
||||
mdio_write(ioaddr, 0x1f, 0x0005);
|
||||
mdio_write(ioaddr, 0x05, 0x001b);
|
||||
- if (mdio_read(ioaddr, 0x06) == 0xb300 &&
|
||||
- request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) {
|
||||
- rtl_phy_write_fw(tp, fw);
|
||||
- release_firmware(fw);
|
||||
- } else {
|
||||
+ if ((mdio_read(ioaddr, 0x06) != 0xb300) ||
|
||||
+ (rtl_apply_firmware(tp, FIRMWARE_8168D_2) < 0)) {
|
||||
netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
|
||||
}
|
||||
|
||||
@@ -2706,6 +2723,8 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
|
||||
|
||||
flush_scheduled_work();
|
||||
|
||||
+ rtl_release_firmware(tp);
|
||||
+
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (pci_dev_run_wake(pdev))
|
||||
--
|
||||
1.7.2.3
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
- bugfix/arm/ixp4xx-add-missing-export.patch
|
||||
+ bugfix/sh4/sh-export-topology-core-cpumask.patch
|
||||
+ bugfix/all/r8169-keep-firmware-in-memory.patch
|
||||
|
|
Loading…
Reference in New Issue