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) {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to