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:
Divy Le Ray 2007-03-18 13:10:06 -07:00 committed by Jeff Garzik
parent 05b97b30b0
commit 2e2839627a
3 changed files with 29 additions and 2 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;