iwlwifi: mvm: don't use SAR Geo if basic SAR is not used
authorLuca Coelho <luciano.coelho@intel.com>
Wed, 17 Oct 2018 05:35:15 +0000 (08:35 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 15 Nov 2018 21:50:59 +0000 (23:50 +0200)
We can't use SAR Geo if basic SAR is not enabled, since the SAR Geo
tables define offsets in relation to the basic SAR table in use.

To fix this, make iwl_mvm_sar_init() return one in case WRDS is not
available, so we can skip reading WGDS entirely.

Fixes: a6bff3cb19b7 ("iwlwifi: mvm: add GEO_TX_POWER_LIMIT cmd for geographic tx power table")
Cc: stable@vger.kernel.org # 4.12+
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/fw.c

index 899f4a6..2ba8904 100644 (file)
@@ -928,6 +928,11 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)
        return -ENOENT;
 }
 
+static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
+{
+       return -ENOENT;
+}
+
 static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
 {
        return 0;
@@ -954,8 +959,11 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
                IWL_DEBUG_RADIO(mvm,
                                "WRDS SAR BIOS table invalid or unavailable. (%d)\n",
                                ret);
-               /* if not available, don't fail and don't bother with EWRD */
-               return 0;
+               /*
+                * If not available, don't fail and don't bother with EWRD.
+                * Return 1 to tell that we can't use WGDS either.
+                */
+               return 1;
        }
 
        ret = iwl_mvm_sar_get_ewrd_table(mvm);
@@ -968,9 +976,13 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
        /* choose profile 1 (WRDS) as default for both chains */
        ret = iwl_mvm_sar_select_profile(mvm, 1, 1);
 
-       /* if we don't have profile 0 from BIOS, just skip it */
+       /*
+        * If we don't have profile 0 from BIOS, just skip it.  This
+        * means that SAR Geo will not be enabled either, even if we
+        * have other valid profiles.
+        */
        if (ret == -ENOENT)
-               return 0;
+               return 1;
 
        return ret;
 }
@@ -1168,11 +1180,19 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
                iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
 
        ret = iwl_mvm_sar_init(mvm);
-       if (ret)
-               goto error;
+       if (ret == 0) {
+               ret = iwl_mvm_sar_geo_init(mvm);
+       } else if (ret > 0 && !iwl_mvm_sar_get_wgds_table(mvm)) {
+               /*
+                * If basic SAR is not available, we check for WGDS,
+                * which should *not* be available either.  If it is
+                * available, issue an error, because we can't use SAR
+                * Geo without basic SAR.
+                */
+               IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n");
+       }
 
-       ret = iwl_mvm_sar_geo_init(mvm);
-       if (ret)
+       if (ret < 0)
                goto error;
 
        iwl_mvm_leds_sync(mvm);