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
This commit is contained in:
parent
b958d4b255
commit
2a857082dc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=343269
@ -480,9 +480,10 @@ SYSCTL_INT(_hw_cxgbe, OID_AUTO, autoneg, CTLFLAG_RDTUN, &t4_autoneg, 0,
|
||||
|
||||
/*
|
||||
* 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,9 +3492,14 @@ install_kld_firmware(struct adapter *sc, struct fw_h *card_fw,
|
||||
{
|
||||
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 *card_fw,
|
||||
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,25 +3540,64 @@ install_kld_firmware(struct adapter *sc, struct fw_h *card_fw,
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 "
|
||||
"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_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, "
|
||||
@ -3546,25 +3607,6 @@ install_kld_firmware(struct adapter *sc, struct fw_h *card_fw,
|
||||
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);
|
||||
rc = sc->flags & FW_OK ? 0 : ENOENT;
|
||||
goto done;
|
||||
}
|
||||
k = be32toh(((const struct fw_hdr *)fw->data)->fw_ver);
|
||||
if (k != d) {
|
||||
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",
|
||||
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));
|
||||
rc = sc->flags & FW_OK ? 0 : EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = -t4_fw_upgrade(sc, sc->mbox, fw->data, fw->datasize, 0);
|
||||
if (rc != 0) {
|
||||
device_printf(sc->dev, "failed to install firmware: %d\n", rc);
|
||||
|
Loading…
Reference in New Issue
Block a user