add acenic request_firmware patch
hmm nr of disabled drivers goes down, thanks to upstream effort. svn path=/dists/trunk/linux-2.6/; revision=11643
This commit is contained in:
parent
53296f1314
commit
3306f1917d
|
@ -40,6 +40,7 @@ linux-2.6 (2.6.26~rc6-1~experimental.1) UNRELEASED; urgency=low
|
|||
* 486: enable OLPC support thanks Andres Salomon for merge.
|
||||
Kconfig variable patch by Robert Millan (closes: #485063).
|
||||
* Add request_firmware patch for ip2.
|
||||
* Add request_firmware patch for acenic. (closes: #284221)
|
||||
|
||||
[ Martin Michlmayr ]
|
||||
* [arm/orion5x] Update the config to reflect upstream renaming this
|
||||
|
|
|
@ -0,0 +1,296 @@
|
|||
Subject: [PATCH] firmware: convert acenic driver to request_firmware()
|
||||
From: David Woodhouse <dwmw2@infradead.org>
|
||||
To: Jes Sorensen <jes@trained-monkey.org>
|
||||
Cc: netdev@vger.kernel.org, jaswinder@infradead.org
|
||||
|
||||
Again with help from Jaswinder Singh.
|
||||
|
||||
Omitting the large part of the patch which actually moves the firmware
|
||||
around, since you'll need to pull from the git tree to get the preceding
|
||||
patches if you want to test it anyway.
|
||||
|
||||
We store the firmware in little-endian form now, and thus use
|
||||
__raw_writel() to write it to the device, to avoid byteswapping by
|
||||
writel(). I've revamped that loop in ace_copy() a little bit so it could
|
||||
probably do with being tested.
|
||||
|
||||
I've dropped the information about SBSS and BSS sections of the firmware
|
||||
-- we were clearing the whole of the device's memory in advance anyway,
|
||||
so clearing the BSS sections for a _second_ time seems pointless. And
|
||||
since the text,rodata,data sections were (almost) contiguous, we now
|
||||
just load those as a single blob rather than keeping them separate.
|
||||
|
||||
Although it probably isn't necessary, we do preserve the ability to
|
||||
change the load and start addresses from 0x4000, by putting them into a
|
||||
header at the beginning of the firmware blob, along with the version
|
||||
number.
|
||||
|
||||
[ ported to debian -maks ]
|
||||
|
||||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
|
||||
index f80c839..7677680 100644
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -1912,8 +1912,8 @@ if NETDEV_1000
|
||||
|
||||
config ACENIC
|
||||
tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
|
||||
- depends on BROKEN
|
||||
depends on PCI
|
||||
+ select FW_LOADER
|
||||
---help---
|
||||
Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
|
||||
GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
|
||||
@@ -1945,6 +1946,23 @@ config ACENIC_OMIT_TIGON_I
|
||||
|
||||
The safe and default value for this is N.
|
||||
|
||||
+config ACENIC_TG1_FIRMWARE
|
||||
+ bool "Include firmware for old Tigon I based AceNICs"
|
||||
+ depends on ACENIC && !ACENIC_OMIT_TIGON_I
|
||||
+ ---help---
|
||||
+ This includes firmware for the original Alteon AceNIC and 3Com 3C985
|
||||
+ (non B version) in the kernel image.
|
||||
+ Say 'N' and let it get loaded from userspace on demand
|
||||
+
|
||||
+config ACENIC_TG2_FIRMWARE
|
||||
+ bool "Include firmware for Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit"
|
||||
+ depends on ACENIC
|
||||
+ ---help---
|
||||
+ This includes firmware for later Alteon AceNIC, 3Com 3C985B,
|
||||
+ NetGear GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit
|
||||
+ Ethernet adapter.
|
||||
+ Say 'N' and let it get loaded from userspace on demand
|
||||
+
|
||||
config DL2K
|
||||
tristate "DL2000/TC902x-based Gigabit Ethernet support"
|
||||
depends on PCI
|
||||
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
|
||||
index 6c19265..1e42734 100644
|
||||
--- a/drivers/net/acenic.c
|
||||
+++ b/drivers/net/acenic.c
|
||||
@@ -67,6 +67,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/sockios.h>
|
||||
+#include <linux/firmware.h>
|
||||
|
||||
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
||||
#include <linux/if_vlan.h>
|
||||
@@ -187,8 +188,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
|
||||
#define MAX_RODATA_LEN 8*1024
|
||||
#define MAX_DATA_LEN 2*1024
|
||||
|
||||
-#include "acenic_firmware.h"
|
||||
-
|
||||
#ifndef tigon2FwReleaseLocal
|
||||
#define tigon2FwReleaseLocal 0
|
||||
#endif
|
||||
@@ -418,6 +417,8 @@ static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
|
||||
MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
|
||||
+MODULE_FIRMWARE("acenic_tg1.bin");
|
||||
+MODULE_FIRMWARE("acenic_tg2.bin");
|
||||
|
||||
module_param_array_named(link, link_state, int, NULL, 0);
|
||||
module_param_array(trace, int, NULL, 0);
|
||||
@@ -939,8 +940,8 @@ static int __devinit ace_init(struct net_device *dev)
|
||||
case 4:
|
||||
case 5:
|
||||
printk(KERN_INFO " Tigon I (Rev. %i), Firmware: %i.%i.%i, ",
|
||||
- tig_ver, tigonFwReleaseMajor, tigonFwReleaseMinor,
|
||||
- tigonFwReleaseFix);
|
||||
+ tig_ver, ap->firmware_major, ap->firmware_minor,
|
||||
+ ap->firmware_fix);
|
||||
writel(0, ®s->LocalCtrl);
|
||||
ap->version = 1;
|
||||
ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES;
|
||||
@@ -948,8 +949,8 @@ static int __devinit ace_init(struct net_device *dev)
|
||||
#endif
|
||||
case 6:
|
||||
printk(KERN_INFO " Tigon II (Rev. %i), Firmware: %i.%i.%i, ",
|
||||
- tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor,
|
||||
- tigon2FwReleaseFix);
|
||||
+ tig_ver, ap->firmware_major, ap->firmware_minor,
|
||||
+ ap->firmware_fix);
|
||||
writel(readl(®s->CpuBCtrl) | CPU_HALT, ®s->CpuBCtrl);
|
||||
readl(®s->CpuBCtrl); /* PCI write posting */
|
||||
/*
|
||||
@@ -1201,7 +1202,9 @@ static int __devinit ace_init(struct net_device *dev)
|
||||
memset(ap->info, 0, sizeof(struct ace_info));
|
||||
memset(ap->skb, 0, sizeof(struct ace_skb));
|
||||
|
||||
- ace_load_firmware(dev);
|
||||
+ if (ace_load_firmware(dev))
|
||||
+ goto init_error;
|
||||
+
|
||||
ap->fw_running = 0;
|
||||
|
||||
tmp_ptr = ap->info_dma;
|
||||
@@ -1437,10 +1440,7 @@ static int __devinit ace_init(struct net_device *dev)
|
||||
if (ap->version >= 2)
|
||||
writel(tmp, ®s->TuneFastLink);
|
||||
|
||||
- if (ACE_IS_TIGON_I(ap))
|
||||
- writel(tigonFwStartAddr, ®s->Pc);
|
||||
- if (ap->version == 2)
|
||||
- writel(tigon2FwStartAddr, ®s->Pc);
|
||||
+ writel(ap->firmware_start, ®s->Pc);
|
||||
|
||||
writel(0, ®s->Mb0Lo);
|
||||
|
||||
@@ -2763,8 +2763,8 @@ static void ace_get_drvinfo(struct net_device *dev,
|
||||
|
||||
strlcpy(info->driver, "acenic", sizeof(info->driver));
|
||||
snprintf(info->version, sizeof(info->version), "%i.%i.%i",
|
||||
- tigonFwReleaseMajor, tigonFwReleaseMinor,
|
||||
- tigonFwReleaseFix);
|
||||
+ ap->firmware_major, ap->firmware_minor,
|
||||
+ ap->firmware_fix);
|
||||
|
||||
if (ap->pdev)
|
||||
strlcpy(info->bus_info, pci_name(ap->pdev),
|
||||
@@ -2871,11 +2871,10 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev)
|
||||
}
|
||||
|
||||
|
||||
-static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src,
|
||||
- u32 dest, int size)
|
||||
+static void __devinit ace_copy(struct ace_regs __iomem *regs, const __le32 *src,
|
||||
+ u32 dest, int size)
|
||||
{
|
||||
void __iomem *tdest;
|
||||
- u32 *wsrc;
|
||||
short tsize, i;
|
||||
|
||||
if (size <= 0)
|
||||
@@ -2887,20 +2886,15 @@ static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src,
|
||||
tdest = (void __iomem *) ®s->Window +
|
||||
(dest & (ACE_WINDOW_SIZE - 1));
|
||||
writel(dest & ~(ACE_WINDOW_SIZE - 1), ®s->WinBase);
|
||||
- /*
|
||||
- * This requires byte swapping on big endian, however
|
||||
- * writel does that for us
|
||||
- */
|
||||
- wsrc = src;
|
||||
for (i = 0; i < (tsize / 4); i++) {
|
||||
- writel(wsrc[i], tdest + i*4);
|
||||
+ /* Firmware is stored as little-endian */
|
||||
+ __raw_writel(*src, tdest);
|
||||
+ src++;
|
||||
+ tdest += 4;
|
||||
+ dest += 4;
|
||||
+ size -= 4;
|
||||
}
|
||||
- dest += tsize;
|
||||
- src += tsize;
|
||||
- size -= tsize;
|
||||
}
|
||||
-
|
||||
- return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2939,8 +2933,13 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz
|
||||
*/
|
||||
static int __devinit ace_load_firmware(struct net_device *dev)
|
||||
{
|
||||
+ const struct firmware *fw;
|
||||
+ const char *fw_name = "acenic_tg2.bin";
|
||||
struct ace_private *ap = netdev_priv(dev);
|
||||
struct ace_regs __iomem *regs = ap->regs;
|
||||
+ const __le32 *fw_data;
|
||||
+ u32 load_addr;
|
||||
+ int ret;
|
||||
|
||||
if (!(readl(®s->CpuCtrl) & CPU_HALTED)) {
|
||||
printk(KERN_ERR "%s: trying to download firmware while the "
|
||||
@@ -2948,28 +2947,52 @@ static int __devinit ace_load_firmware(struct net_device *dev)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
+ if (ACE_IS_TIGON_I(ap))
|
||||
+ fw_name = "acenic_tg1.bin";
|
||||
+
|
||||
+ ret = request_firmware(&fw, fw_name, &ap->pdev->dev);
|
||||
+ if (ret) {
|
||||
+ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
|
||||
+ ap->name, fw_name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ fw_data = (void *)fw->data;
|
||||
+
|
||||
+ /* Firmware blob starts with version numbers, followed by
|
||||
+ load and start address. Remainder is the blob to be loaded
|
||||
+ contiguously from load address. We don't bother to represent
|
||||
+ the BSS/SBSS sections any more, since we were clearing the
|
||||
+ whole thing anyway. */
|
||||
+ ap->firmware_major = fw->data[0];
|
||||
+ ap->firmware_minor = fw->data[1];
|
||||
+ ap->firmware_fix = fw->data[2];
|
||||
+
|
||||
+ ap->firmware_start = le32_to_cpu(fw_data[1]);
|
||||
+ if (ap->firmware_start < 0x4000 || ap->firmware_start >= 0x80000) {
|
||||
+ printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n",
|
||||
+ ap->name, ap->firmware_start, fw_name);
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ load_addr = le32_to_cpu(fw_data[2]);
|
||||
+ if (load_addr < 0x4000 || load_addr >= 0x80000) {
|
||||
+ printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n",
|
||||
+ ap->name, load_addr, fw_name);
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
- * Do not try to clear more than 512KB or we end up seeing
|
||||
- * funny things on NICs with only 512KB SRAM
|
||||
+ * Do not try to clear more than 512KiB or we end up seeing
|
||||
+ * funny things on NICs with only 512KiB SRAM
|
||||
*/
|
||||
ace_clear(regs, 0x2000, 0x80000-0x2000);
|
||||
- if (ACE_IS_TIGON_I(ap)) {
|
||||
- ace_copy(regs, tigonFwText, tigonFwTextAddr, tigonFwTextLen);
|
||||
- ace_copy(regs, tigonFwData, tigonFwDataAddr, tigonFwDataLen);
|
||||
- ace_copy(regs, tigonFwRodata, tigonFwRodataAddr,
|
||||
- tigonFwRodataLen);
|
||||
- ace_clear(regs, tigonFwBssAddr, tigonFwBssLen);
|
||||
- ace_clear(regs, tigonFwSbssAddr, tigonFwSbssLen);
|
||||
- }else if (ap->version == 2) {
|
||||
- ace_clear(regs, tigon2FwBssAddr, tigon2FwBssLen);
|
||||
- ace_clear(regs, tigon2FwSbssAddr, tigon2FwSbssLen);
|
||||
- ace_copy(regs, tigon2FwText, tigon2FwTextAddr,tigon2FwTextLen);
|
||||
- ace_copy(regs, tigon2FwRodata, tigon2FwRodataAddr,
|
||||
- tigon2FwRodataLen);
|
||||
- ace_copy(regs, tigon2FwData, tigon2FwDataAddr,tigon2FwDataLen);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ ace_copy(regs, &fw_data[3], load_addr, fw->size-12);
|
||||
+ out:
|
||||
+ release_firmware(fw);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h
|
||||
index 60ed183..cf7e80e 100644
|
||||
--- a/drivers/net/acenic.h
|
||||
+++ b/drivers/net/acenic.h
|
||||
@@ -695,6 +695,10 @@ struct ace_private
|
||||
#endif
|
||||
struct net_device_stats stats;
|
||||
int pci_using_dac;
|
||||
+ u8 firmware_major;
|
||||
+ u8 firmware_minor;
|
||||
+ u8 firmware_fix;
|
||||
+ u32 firmware_start;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#+ debian/dfsg/drivers-net-bnx2-request_firmware-1.patch
|
||||
+ features/all/drivers-usb-serial-keyspan-request_firmware.patch
|
||||
+ features/all/drivers-char-ip2-request_firmware.patch
|
||||
+ features/all/drivers-net-acenic-firmwar_request.patch
|
||||
+ features/all/export-gfs2-locking-symbols.patch
|
||||
+ features/all/export-unionfs-symbols.patch
|
||||
|
||||
|
|
Loading…
Reference in New Issue