ice: add FW load wait
authorJan Sokolowski <jan.sokolowski@intel.com>
Thu, 13 Jul 2023 13:21:24 +0000 (15:21 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 7 Aug 2023 20:01:29 +0000 (13:01 -0700)
As some cards load FW from external sources, we have to wait
to be sure that FW is ready before setting link up.

Add check and wait for FW readiness

Signed-off-by: Jan Sokolowski <jan.sokolowski@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
drivers/net/ethernet/intel/ice/ice_main.c

index a92dc9a16035833d9f6af09f76224ae99eaae4ea..fb590b4c1053924890432291d18b87699e531d63 100644 (file)
 #define VP_MDET_TX_TCLAN_VALID_M               BIT(0)
 #define VP_MDET_TX_TDPU(_VF)                   (0x00040000 + ((_VF) * 4))
 #define VP_MDET_TX_TDPU_VALID_M                        BIT(0)
+#define GL_MNG_FWSM                            0x000B6134
+#define GL_MNG_FWSM_FW_LOADING_M               BIT(30)
 #define GLNVM_FLA                              0x000B6108
 #define GLNVM_FLA_LOCKED_M                     BIT(6)
 #define GLNVM_GENS                             0x000B6100
index 2e80d5cd9f5671e72f50bfd610a1bd479e76345b..0f04347eda39df9338dc9d6a40d026fc054deed3 100644 (file)
@@ -4520,6 +4520,31 @@ static void ice_deinit_eth(struct ice_pf *pf)
        ice_decfg_netdev(vsi);
 }
 
+/**
+ * ice_wait_for_fw - wait for full FW readiness
+ * @hw: pointer to the hardware structure
+ * @timeout: milliseconds that can elapse before timing out
+ */
+static int ice_wait_for_fw(struct ice_hw *hw, u32 timeout)
+{
+       int fw_loading;
+       u32 elapsed = 0;
+
+       while (elapsed <= timeout) {
+               fw_loading = rd32(hw, GL_MNG_FWSM) & GL_MNG_FWSM_FW_LOADING_M;
+
+               /* firmware was not yet loaded, we have to wait more */
+               if (fw_loading) {
+                       elapsed += 100;
+                       msleep(100);
+                       continue;
+               }
+               return 0;
+       }
+
+       return -ETIMEDOUT;
+}
+
 static int ice_init_dev(struct ice_pf *pf)
 {
        struct device *dev = ice_pf_to_dev(pf);
@@ -4532,6 +4557,18 @@ static int ice_init_dev(struct ice_pf *pf)
                return err;
        }
 
+       /* Some cards require longer initialization times
+        * due to necessity of loading FW from an external source.
+        * This can take even half a minute.
+        */
+       if (ice_is_pf_c827(hw)) {
+               err = ice_wait_for_fw(hw, 30000);
+               if (err) {
+                       dev_err(dev, "ice_wait_for_fw timed out");
+                       return err;
+               }
+       }
+
        ice_init_feature_support(pf);
 
        ice_request_fw(pf);