diff options
author | Divy Le Ray <divy@chelsio.com> | 2007-03-18 23:10:06 +0300 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-03-23 08:48:33 +0300 |
commit | 2e2839627a957714808f98a802d137a7a2a1df46 (patch) | |
tree | 7c001eeb3a45b9f31da3862acbfc11633eea3914 | |
parent | 05b97b30b09ed245d376035cddf669532e5cca67 (diff) | |
download | linux-2e2839627a957714808f98a802d137a7a2a1df46.tar.xz |
cxgb3 - Auto-load FW if mismatch detected
The driver attempts to upgrade the FW if the card has the wrong version.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 25 | ||||
-rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 5 |
3 files changed, 29 insertions, 2 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5ff0922e628c..1b6459b218ca 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2374,6 +2374,7 @@ config CHELSIO_T1_NAPI config CHELSIO_T3 tristate "Chelsio Communications T3 10Gb Ethernet support" depends on PCI + select FW_LOADER help This driver supports Chelsio T3-based gigabit and 10Gb Ethernet adapters. diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index eb0a4e068200..b9bcda821f7c 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -42,6 +42,7 @@ #include <linux/workqueue.h> #include <linux/proc_fs.h> #include <linux/rtnetlink.h> +#include <linux/firmware.h> #include <asm/uaccess.h> #include "common.h" @@ -707,6 +708,28 @@ static void bind_qsets(struct adapter *adap) } } +#define FW_FNAME "t3fw-%d.%d.bin" + +static int upgrade_fw(struct adapter *adap) +{ + int ret; + char buf[64]; + const struct firmware *fw; + struct device *dev = &adap->pdev->dev; + + snprintf(buf, sizeof(buf), FW_FNAME, FW_VERSION_MAJOR, + FW_VERSION_MINOR); + ret = request_firmware(&fw, buf, dev); + if (ret < 0) { + dev_err(dev, "could not upgrade firmware: unable to load %s\n", + buf); + return ret; + } + ret = t3_load_fw(adap, fw->data, fw->size); + release_firmware(fw); + return ret; +} + /** * cxgb_up - enable the adapter * @adapter: adapter being enabled @@ -723,6 +746,8 @@ static int cxgb_up(struct adapter *adap) if (!(adap->flags & FULL_INIT_DONE)) { err = t3_check_fw_version(adap); + if (err == -EINVAL) + err = upgrade_fw(adap); if (err) goto out; diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index eaa7a2e89a30..983ee813c7e4 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -681,7 +681,8 @@ enum { SF_ERASE_SECTOR = 0xd8, /* erase sector */ FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */ - FW_VERS_ADDR = 0x77ffc /* flash address holding FW version */ + FW_VERS_ADDR = 0x77ffc, /* flash address holding FW version */ + FW_MIN_SIZE = 8 /* at least version and csum */ }; /** @@ -935,7 +936,7 @@ int t3_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size) const u32 *p = (const u32 *)fw_data; int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16; - if (size & 3) + if ((size & 3) || size < FW_MIN_SIZE) return -EINVAL; if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR) return -EFBIG; |