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) {
_______________________________________________
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