#include <linux/workqueue.h>
#include <linux/proc_fs.h>
#include <linux/rtnetlink.h>
+#include <linux/firmware.h>
#include <asm/uaccess.h>
#include "common.h"
}
}
+#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
if (!(adap->flags & FULL_INIT_DONE)) {
err = t3_check_fw_version(adap);
+ if (err == -EINVAL)
+ err = upgrade_fw(adap);
if (err)
goto out;
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 */
};
/**
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;