svn commit: r346954 - stable/11/sys/dev/cxgbe

Navdeep Parhar np at FreeBSD.org
Tue Apr 30 08:17:12 UTC 2019


Author: np
Date: Tue Apr 30 08:17:11 2019
New Revision: 346954
URL: https://svnweb.freebsd.org/changeset/base/346954

Log:
  MFC r343269, r346567
  
  r343269:
  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.
  
  Sponsored by:	Chelsio Communications
  
  r346567:
  cxgbe(4): Make sure bundled_fw is always initialized before use.
  
  This fixes a bug that prevented the driver from auto-flashing the
  firmware when it didn't see one on the card.  This feature was
  introduced in r321390 and this bug was introduced in r343269.
  
  Reported by:	gallatin@
  Sponsored by:	Chelsio Communications

Modified:
  stable/11/sys/dev/cxgbe/t4_main.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/cxgbe/t4_main.c
==============================================================================
--- stable/11/sys/dev/cxgbe/t4_main.c	Tue Apr 30 08:09:32 2019	(r346953)
+++ stable/11/sys/dev/cxgbe/t4_main.c	Tue Apr 30 08:17:11 2019	(r346954)
@@ -477,9 +477,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)");
 
@@ -3448,10 +3449,31 @@ 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;
+
+	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 (reason != NULL)
 		goto install;
 
@@ -3462,10 +3484,11 @@ install_kld_firmware(struct adapter *sc, struct fw_h *
 			goto install;
 		}
 
-		return (0);
+		rc = 0;
+		goto done;
 	}
 
-	if (!fw_compatible(card_fw, drv_fw)) {
+	if (!fw_compatible(card_fw, &bundled_fw)) {
 		reason = "incompatible or unusable";
 		goto install;
 	}
@@ -3475,52 +3498,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