cxgb4: Force uninitialized state if FW_ON_ADAPTER is < FW_VERSION and we're the MASTER_PF
authorJay Hernandez <jay@chelsio.com>
Thu, 30 May 2013 03:24:14 +0000 (03:24 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 1 Jun 2013 00:25:43 +0000 (17:25 -0700)
Forcing uninitialized state allows us to upgrade and reinitialize the adapter.

FW_VERSION_T4 = 1.4.0.0
FW_VERSION_T5 = 0.0.0.0
At this point driver supports above and greater than above version of firmware.
If it doesn't find the required firmware version than it forces the adapter to
be reinitialized as shown below.

1) If FW_ON_ADAPTER < FW_VERSION and we're the MASTER_PF force uninitialized
   state and a FW upgrade if available.

       - If FW_ON_ADAPTER < /lib/firmware/cxgb4/t*fw.bin we will update the
         adapters FW.
       - If FW_ON_ADAPTER >= /lib/firmware/cxgb4/t*fw.bin don't upgrade FW.
       - If upgrade_fw() fails force reinitialization of the adapter anyways,
         it might still work.

   Either way forcing the uninitialized state allows cxgb4 reinitialize FW.

2) If FW_ON_ADAPTER >= FW_VERSION driver follows normal path.

Signed-off-by: Jay Hernandez <jay@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c

index 681804b30a3fef09678b76b40b3cae54ebaa80d1..2aafb809e067b7a204a3fb1a92412756d9ceb78f 100644 (file)
@@ -51,7 +51,7 @@
 #include "t4_hw.h"
 
 #define FW_VERSION_MAJOR 1
-#define FW_VERSION_MINOR 1
+#define FW_VERSION_MINOR 4
 #define FW_VERSION_MICRO 0
 
 #define FW_VERSION_MAJOR_T5 0
index 3cd397d60434fe93b3005d2c329621a171bea24f..5a3256b083f23f7e69d8013c4ca1ac0585ec33c4 100644 (file)
@@ -4842,8 +4842,17 @@ static int adap_init0(struct adapter *adap)
         * is excessively mismatched relative to the driver.)
         */
        ret = t4_check_fw_version(adap);
+
+       /* The error code -EFAULT is returned by t4_check_fw_version() if
+        * firmware on adapter < supported firmware. If firmware on adapter
+        * is too old (not supported by driver) and we're the MASTER_PF set
+        * adapter state to DEV_STATE_UNINIT to force firmware upgrade
+        * and reinitialization.
+        */
+       if ((adap->flags & MASTER_PF) && ret == -EFAULT)
+               state = DEV_STATE_UNINIT;
        if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) {
-               if (ret == -EINVAL || ret > 0) {
+               if (ret == -EINVAL || ret == -EFAULT || ret > 0) {
                        if (upgrade_fw(adap) >= 0) {
                                /*
                                 * Note that the chip was reset as part of the
@@ -4852,7 +4861,21 @@ static int adap_init0(struct adapter *adap)
                                 */
                                reset = 0;
                                ret = t4_check_fw_version(adap);
-                       }
+                       } else
+                               if (ret == -EFAULT) {
+                                       /*
+                                        * Firmware is old but still might
+                                        * work if we force reinitialization
+                                        * of the adapter. Ignoring FW upgrade
+                                        * failure.
+                                        */
+                                       dev_warn(adap->pdev_dev,
+                                                "Ignoring firmware upgrade "
+                                                "failure, and forcing driver "
+                                                "to reinitialize the "
+                                                "adapter.\n");
+                                       ret = 0;
+                               }
                }
                if (ret < 0)
                        return ret;
index d02d4e8c4417cf7d78a70586f6c532ef8355a76a..bff89a437b760c9d8f2630531e67bbd577629a79 100644 (file)
@@ -938,6 +938,15 @@ int t4_check_fw_version(struct adapter *adapter)
        memcpy(adapter->params.api_vers, api_vers,
               sizeof(adapter->params.api_vers));
 
+       if (major < exp_major || (major == exp_major && minor < exp_minor) ||
+           (major == exp_major && minor == exp_minor && micro < exp_micro)) {
+               dev_err(adapter->pdev_dev,
+                       "Card has firmware version %u.%u.%u, minimum "
+                       "supported firmware is %u.%u.%u.\n", major, minor,
+                       micro, exp_major, exp_minor, exp_micro);
+               return -EFAULT;
+       }
+
        if (major != exp_major) {            /* major mismatch - fail */
                dev_err(adapter->pdev_dev,
                        "card FW has major version %u, driver wants %u\n",