Commit 2e283962 authored by Divy Le Ray's avatar Divy Le Ray Committed by Jeff Garzik
Browse files

cxgb3 - Auto-load FW if mismatch detected



The driver attempts to upgrade the FW if the card has the wrong version.

Signed-off-by: default avatarDivy Le Ray <divy@chelsio.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 05b97b30
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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.
+25 −0
Original line number Diff line number Diff line
@@ -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;

+3 −2
Original line number Diff line number Diff line
@@ -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;