summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2011-03-05 03:12:50 +0000
committernp <np@FreeBSD.org>2011-03-05 03:12:50 +0000
commit502623636ed34e71b7792762788aa01a619e041e (patch)
tree435a71136a997ee6c02602071ce6e519b12b4351
parentd5be9ba7135a42f20129b0574b3d7afa729d2756 (diff)
downloadFreeBSD-src-502623636ed34e71b7792762788aa01a619e041e.zip
FreeBSD-src-502623636ed34e71b7792762788aa01a619e041e.tar.gz
Upgrade the firmware on the card automatically if a better version is
available. Downgrade only for a major version mismatch. MFC after: 1 week
-rw-r--r--sys/dev/cxgbe/common/common.h4
-rw-r--r--sys/dev/cxgbe/t4_main.c71
2 files changed, 58 insertions, 17 deletions
diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h
index 13b2baa..4a7203c 100644
--- a/sys/dev/cxgbe/common/common.h
+++ b/sys/dev/cxgbe/common/common.h
@@ -53,8 +53,8 @@ enum {
};
#define FW_VERSION_MAJOR 1
-#define FW_VERSION_MINOR 2
-#define FW_VERSION_MICRO 65
+#define FW_VERSION_MINOR 3
+#define FW_VERSION_MICRO 0
struct port_stats {
u64 tx_octets; /* total # of octets in good frames */
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 996600b..b5b1c65 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -1256,28 +1256,69 @@ prep_firmware(struct adapter *sc)
/* Check firmware version and install a different one if necessary */
rc = t4_check_fw_version(sc);
if (rc != 0 || force_firmware_install) {
+ uint32_t v = 0;
fw = firmware_get(T4_FWNAME);
- if (fw == NULL) {
- device_printf(sc->dev,
- "Could not find firmware image %s\n", T4_FWNAME);
- return (ENOENT);
+ if (fw != NULL) {
+ const struct fw_hdr *hdr = (const void *)fw->data;
+
+ v = ntohl(hdr->fw_ver);
+
+ /*
+ * The firmware module will not be used if it isn't the
+ * same major version as what the driver was compiled
+ * with. This check trumps force_firmware_install.
+ */
+ if (G_FW_HDR_FW_VER_MAJOR(v) != FW_VERSION_MAJOR) {
+ device_printf(sc->dev,
+ "Found firmware image but version %d "
+ "can not be used with this driver (%d)\n",
+ G_FW_HDR_FW_VER_MAJOR(v), FW_VERSION_MAJOR);
+
+ firmware_put(fw, FIRMWARE_UNLOAD);
+ fw = NULL;
+ }
}
- device_printf(sc->dev,
- "installing firmware %d.%d.%d on card.\n",
- FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
- rc = -t4_load_fw(sc, fw->data, fw->datasize);
- if (rc != 0) {
+ if (fw == NULL && (rc < 0 || force_firmware_install)) {
+ device_printf(sc->dev, "No usable firmware. "
+ "card has %d.%d.%d, driver compiled with %d.%d.%d, "
+ "force_firmware_install%s set",
+ G_FW_HDR_FW_VER_MAJOR(sc->params.fw_vers),
+ G_FW_HDR_FW_VER_MINOR(sc->params.fw_vers),
+ G_FW_HDR_FW_VER_MICRO(sc->params.fw_vers),
+ FW_VERSION_MAJOR, FW_VERSION_MINOR,
+ FW_VERSION_MICRO,
+ force_firmware_install ? "" : " not");
+ return (EAGAIN);
+ }
+
+ /*
+ * Always upgrade, even for minor/micro/build mismatches.
+ * Downgrade only for a major version mismatch or if
+ * force_firmware_install was specified.
+ */
+ if (fw != NULL && (rc < 0 || force_firmware_install ||
+ v > sc->params.fw_vers)) {
device_printf(sc->dev,
- "failed to install firmware: %d\n", rc);
- return (rc);
- } else {
- t4_get_fw_version(sc, &sc->params.fw_vers);
- t4_get_tp_version(sc, &sc->params.tp_vers);
+ "installing firmware %d.%d.%d.%d on card.\n",
+ G_FW_HDR_FW_VER_MAJOR(v), G_FW_HDR_FW_VER_MINOR(v),
+ G_FW_HDR_FW_VER_MICRO(v), G_FW_HDR_FW_VER_BUILD(v));
+
+ rc = -t4_load_fw(sc, fw->data, fw->datasize);
+ if (rc != 0) {
+ device_printf(sc->dev,
+ "failed to install firmware: %d\n", rc);
+ firmware_put(fw, FIRMWARE_UNLOAD);
+ return (rc);
+ } else {
+ /* refresh */
+ (void) t4_check_fw_version(sc);
+ }
}
- firmware_put(fw, FIRMWARE_UNLOAD);
+ if (fw != NULL)
+ firmware_put(fw, FIRMWARE_UNLOAD);
}
/* Contact firmware, request master */
OpenPOWER on IntegriCloud