From: Divy Le Ray Date: Sun, 18 Mar 2007 20:10:06 +0000 (-0700) Subject: cxgb3 - Auto-load FW if mismatch detected X-Git-Tag: v2.6.21-rc5~21^2~12 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e2839627a957714808f98a802d137a7a2a1df46;p=linux-2.6 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 Signed-off-by: Jeff Garzik --- diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5ff0922e62..1b6459b218 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 eb0a4e0682..b9bcda821f 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #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 eaa7a2e89a..983ee813c7 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;