if (ret)
IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
+ if (iwl_mvm_is_lar_supported(mvm) && iwl_mvm_init_fw_regd(mvm))
+ IWL_ERR(mvm, "Failed to initialize D3 LAR information\n");
+
return 0;
}
/* query SRAM first in case we want event logging */
iwl_mvm_read_d3_sram(mvm);
+ /*
+ * Query the current location and source from the D3 firmware so we
+ * can play it back when we re-intiailize the D0 firmware
+ */
+ iwl_mvm_update_changed_regdom(mvm);
+
if (mvm->net_detect) {
iwl_mvm_query_netdetect_reasons(mvm, vif);
/* has unlocked the mutex, so skip that */
* Contains the new channel control profile map, if changed, and the new MCC
* (mobile country code).
* The new MCC may be different than what was requested in MCC_UPDATE_CMD.
- * @status: 0 for success, 1 no change in channel profile, 2 invalid input.
+ * @status: see &enum iwl_mcc_update_status
* @mcc: the new applied MCC
* @cap: capabilities for all channels which matches the MCC
* @source_id: the MCC source, see iwl_mcc_source
struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
const char *alpha2,
- enum iwl_mcc_source src_id)
+ enum iwl_mcc_source src_id,
+ bool *changed)
{
struct ieee80211_regdomain *regd = NULL;
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
goto out;
}
+ if (changed)
+ *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE);
+
regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
__le32_to_cpu(resp->n_channels),
resp->channels,
return regd;
}
-struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm)
+void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm)
+{
+ bool changed;
+ struct ieee80211_regdomain *regd;
+
+ if (!iwl_mvm_is_lar_supported(mvm))
+ return;
+
+ regd = iwl_mvm_get_current_regdomain(mvm, &changed);
+ if (!IS_ERR_OR_NULL(regd)) {
+ /* only update the regulatory core if changed */
+ if (changed)
+ regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
+
+ kfree(regd);
+ }
+}
+
+struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm,
+ bool *changed)
{
return iwl_mvm_get_regdomain(mvm->hw->wiphy, "ZZ",
iwl_mvm_is_wifi_mcc_supported(mvm) ?
MCC_SOURCE_GET_CURRENT :
- MCC_SOURCE_OLD_FW);
+ MCC_SOURCE_OLD_FW, changed);
}
int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm)
used_src = mvm->mcc_src;
if (iwl_mvm_is_wifi_mcc_supported(mvm)) {
/* Notify the firmware we support wifi location updates */
- regd = iwl_mvm_get_current_regdomain(mvm);
+ regd = iwl_mvm_get_current_regdomain(mvm, NULL);
if (!IS_ERR_OR_NULL(regd))
kfree(regd);
}
/* Now set our last stored MCC and source */
- regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src);
+ regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src, NULL);
if (IS_ERR_OR_NULL(regd))
return -EIO;
struct iwl_device_cmd *cmd);
struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
const char *alpha2,
- enum iwl_mcc_source src_id);
-struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm);
+ enum iwl_mcc_source src_id,
+ bool *changed);
+struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm,
+ bool *changed);
int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm);
+void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm);
/* smart fifo */
int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
IWL_DEBUG_LAR(mvm,
"MCC response status: 0x%x. new MCC: 0x%x ('%c%c') change: %d n_chans: %d\n",
status, mcc, mcc >> 8, mcc & 0xff,
- !!(status == MCC_RESP_SAME_CHAN_PROFILE), n_channels);
+ !!(status == MCC_RESP_NEW_CHAN_PROFILE), n_channels);
resp_len = sizeof(*mcc_resp) + n_channels * sizeof(__le32);
resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
*/
mvm->lar_regdom_set = false;
- regd = iwl_mvm_get_current_regdomain(mvm);
+ regd = iwl_mvm_get_current_regdomain(mvm, NULL);
if (IS_ERR_OR_NULL(regd))
return -EIO;
!iwl_mvm_get_bios_mcc(mvm, mcc)) {
kfree(regd);
regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc,
- MCC_SOURCE_BIOS);
+ MCC_SOURCE_BIOS, NULL);
if (IS_ERR_OR_NULL(regd))
return -EIO;
}
IWL_DEBUG_LAR(mvm,
"RX: received chub update mcc cmd (mcc '%s' src %d)\n",
mcc, src);
- regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc, src);
+ regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc, src, NULL);
if (IS_ERR_OR_NULL(regd))
return 0;
iwl_free_resp(&get_status_cmd);
out:
iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
+
+ /* the FW might have updated the regdomain */
+ iwl_mvm_update_changed_regdom(mvm);
+
iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK);
mutex_unlock(&mvm->mutex);
}