forked from Minki/linux
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
|
||||
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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user