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>
This commit is contained in:
parent
05b97b30b0
commit
2e2839627a
|
@ -2374,6 +2374,7 @@ config CHELSIO_T1_NAPI
|
||||||
config CHELSIO_T3
|
config CHELSIO_T3
|
||||||
tristate "Chelsio Communications T3 10Gb Ethernet support"
|
tristate "Chelsio Communications T3 10Gb Ethernet support"
|
||||||
depends on PCI
|
depends on PCI
|
||||||
|
select FW_LOADER
|
||||||
help
|
help
|
||||||
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
|
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
|
||||||
adapters.
|
adapters.
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/firmware.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
#include "common.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
|
* cxgb_up - enable the adapter
|
||||||
* @adapter: adapter being enabled
|
* @adapter: adapter being enabled
|
||||||
|
@ -723,6 +746,8 @@ static int cxgb_up(struct adapter *adap)
|
||||||
|
|
||||||
if (!(adap->flags & FULL_INIT_DONE)) {
|
if (!(adap->flags & FULL_INIT_DONE)) {
|
||||||
err = t3_check_fw_version(adap);
|
err = t3_check_fw_version(adap);
|
||||||
|
if (err == -EINVAL)
|
||||||
|
err = upgrade_fw(adap);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
@ -681,7 +681,8 @@ enum {
|
||||||
SF_ERASE_SECTOR = 0xd8, /* erase sector */
|
SF_ERASE_SECTOR = 0xd8, /* erase sector */
|
||||||
|
|
||||||
FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */
|
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;
|
const u32 *p = (const u32 *)fw_data;
|
||||||
int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
|
int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
|
||||||
|
|
||||||
if (size & 3)
|
if ((size & 3) || size < FW_MIN_SIZE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
|
if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
|
||||||
return -EFBIG;
|
return -EFBIG;
|
||||||
|
|
Loading…
Reference in a new issue