svn commit: r343269 - head/sys/dev/cxgbe
Navdeep Parhar
np at FreeBSD.org
Mon Jan 21 18:42:17 UTC 2019
Author: np
Date: Mon Jan 21 18:42:16 2019
New Revision: 343269
URL: https://svnweb.freebsd.org/changeset/base/343269
Log:
cxgbe(4): Allow negative values in hw.cxgbe.fw_install and take them to
mean that the driver should taste the firmware in the KLD and use that
firmware's version for all its fw_install checks.
The driver gets firmware version information from compiled-in values by
default and this change allows custom (or older/newer) firmware modules
to be used with the stock driver.
There is no change in default behavior.
MFC after: 1 week
Sponsored by: Chelsio Communications
Modified:
head/sys/dev/cxgbe/t4_main.c
Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c Mon Jan 21 18:41:57 2019 (r343268)
+++ head/sys/dev/cxgbe/t4_main.c Mon Jan 21 18:42:16 2019 (r343269)
@@ -480,9 +480,10 @@ SYSCTL_INT(_hw_cxgbe, OID_AUTO, autoneg, CTLFLAG_RDTUN
/*
* Firmware auto-install by driver during attach (0, 1, 2 = prohibited, allowed,
- * encouraged respectively).
+ * encouraged respectively). '-n' is the same as 'n' except the firmware
+ * version used in the checks is read from the firmware bundled with the driver.
*/
-static unsigned int t4_fw_install = 1;
+static int t4_fw_install = 1;
SYSCTL_INT(_hw_cxgbe, OID_AUTO, fw_install, CTLFLAG_RDTUN, &t4_fw_install, 0,
"Firmware auto-install (0 = prohibited, 1 = allowed, 2 = encouraged)");
@@ -3491,10 +3492,15 @@ install_kld_firmware(struct adapter *sc, struct fw_h *
{
const struct firmware *cfg, *fw;
const uint32_t c = be32toh(card_fw->fw_ver);
- const uint32_t d = be32toh(drv_fw->fw_ver);
- uint32_t k;
- int rc;
+ uint32_t d, k;
+ int rc, fw_install;
+ struct fw_h bundled_fw;
+ bool load_attempted;
+ cfg = fw = NULL;
+ load_attempted = false;
+ fw_install = t4_fw_install < 0 ? -t4_fw_install : t4_fw_install;
+
if (reason != NULL)
goto install;
@@ -3508,7 +3514,23 @@ install_kld_firmware(struct adapter *sc, struct fw_h *
return (0);
}
- if (!fw_compatible(card_fw, drv_fw)) {
+ memcpy(&bundled_fw, drv_fw, sizeof(bundled_fw));
+ if (t4_fw_install < 0) {
+ rc = load_fw_module(sc, &cfg, &fw);
+ if (rc != 0 || fw == NULL) {
+ device_printf(sc->dev,
+ "failed to load firmware module: %d. cfg %p, fw %p;"
+ " will use compiled-in firmware version for"
+ "hw.cxgbe.fw_install checks.\n",
+ rc, cfg, fw);
+ } else {
+ memcpy(&bundled_fw, fw->data, sizeof(bundled_fw));
+ }
+ load_attempted = true;
+ }
+ d = be32toh(bundled_fw.fw_ver);
+
+ if (!fw_compatible(card_fw, &bundled_fw)) {
reason = "incompatible or unusable";
goto install;
}
@@ -3518,52 +3540,72 @@ install_kld_firmware(struct adapter *sc, struct fw_h *
goto install;
}
- if (t4_fw_install == 2 && d != c) {
+ if (fw_install == 2 && d != c) {
reason = "different than the version bundled with this driver";
goto install;
}
- return (0);
+ /* No reason to do anything to the firmware already on the card. */
+ rc = 0;
+ goto done;
install:
+ rc = 0;
if ((*already)++)
- return (0);
+ goto done;
- if (t4_fw_install == 0) {
+ if (fw_install == 0) {
device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, "
"but the driver is prohibited from installing a firmware "
"on the card.\n",
G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c),
G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason);
- return (0);
+ goto done;
}
- device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, "
- "installing firmware %u.%u.%u.%u on card.\n",
- G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c),
- G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason,
- G_FW_HDR_FW_VER_MAJOR(d), G_FW_HDR_FW_VER_MINOR(d),
- G_FW_HDR_FW_VER_MICRO(d), G_FW_HDR_FW_VER_BUILD(d));
-
- rc = load_fw_module(sc, &cfg, &fw);
- if (rc != 0 || fw == NULL) {
- device_printf(sc->dev,
- "failed to load firmware module: %d. cfg %p, fw %p\n", rc,
- cfg, fw);
+ /*
+ * We'll attempt to install a firmware. Load the module first (if it
+ * hasn't been loaded already).
+ */
+ if (!load_attempted) {
+ rc = load_fw_module(sc, &cfg, &fw);
+ if (rc != 0 || fw == NULL) {
+ device_printf(sc->dev,
+ "failed to load firmware module: %d. cfg %p, fw %p\n",
+ rc, cfg, fw);
+ /* carry on */
+ }
+ }
+ if (fw == NULL) {
+ device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, "
+ "but the driver cannot take corrective action because it "
+ "is unable to load the firmware module.\n",
+ G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c),
+ G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason);
rc = sc->flags & FW_OK ? 0 : ENOENT;
goto done;
}
k = be32toh(((const struct fw_hdr *)fw->data)->fw_ver);
if (k != d) {
+ MPASS(t4_fw_install > 0);
device_printf(sc->dev,
"firmware in KLD (%u.%u.%u.%u) is not what the driver was "
- "compiled with and will not be used.\n",
+ "expecting (%u.%u.%u.%u) and will not be used.\n",
G_FW_HDR_FW_VER_MAJOR(k), G_FW_HDR_FW_VER_MINOR(k),
- G_FW_HDR_FW_VER_MICRO(k), G_FW_HDR_FW_VER_BUILD(k));
+ G_FW_HDR_FW_VER_MICRO(k), G_FW_HDR_FW_VER_BUILD(k),
+ G_FW_HDR_FW_VER_MAJOR(d), G_FW_HDR_FW_VER_MINOR(d),
+ G_FW_HDR_FW_VER_MICRO(d), G_FW_HDR_FW_VER_BUILD(d));
rc = sc->flags & FW_OK ? 0 : EINVAL;
goto done;
}
+
+ device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, "
+ "installing firmware %u.%u.%u.%u on card.\n",
+ G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c),
+ G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason,
+ G_FW_HDR_FW_VER_MAJOR(d), G_FW_HDR_FW_VER_MINOR(d),
+ G_FW_HDR_FW_VER_MICRO(d), G_FW_HDR_FW_VER_BUILD(d));
rc = -t4_fw_upgrade(sc, sc->mbox, fw->data, fw->datasize, 0);
if (rc != 0) {
More information about the svn-src-all
mailing list