| From 82715ac71e6b94a2c2136e31f3a8e6748e33aa8c Mon Sep 17 00:00:00 2001 |
| From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> |
| Date: Wed, 3 Oct 2018 11:16:54 +0300 |
| Subject: iwlwifi: mvm: fix regulatory domain update when the firmware starts |
| |
| From: Emmanuel Grumbach <emmanuel.grumbach@intel.com> |
| |
| commit 82715ac71e6b94a2c2136e31f3a8e6748e33aa8c upstream. |
| |
| When the firmware starts, it doesn't have any regulatory |
| information, hence it uses the world wide limitations. The |
| driver can feed the firmware with previous knowledge that |
| was kept in the driver, but the firmware may still not |
| update its internal tables. |
| |
| This happens when we start a BSS interface, and then the |
| firmware can change the regulatory tables based on our |
| location and it'll use more lenient, location specific |
| rules. Then, if the firmware is shut down (when the |
| interface is brought down), and then an AP interface is |
| created, the firmware will forget the country specific |
| rules. |
| |
| The host will think that we are in a certain country that |
| may allow channels and will try to teach the firmware about |
| our location, but the firmware may still not allow to drop |
| the world wide limitations and apply country specific rules |
| because it was just re-started. |
| |
| In this case, the firmware will reply with MCC_RESP_ILLEGAL |
| to the MCC_UPDATE_CMD. In that case, iwlwifi needs to let |
| the upper layers (cfg80211 / hostapd) know that the channel |
| list they know about has been updated. |
| |
| This fixes https://bugzilla.kernel.org/show_bug.cgi?id=201105 |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> |
| Signed-off-by: Luca Coelho <luciano.coelho@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| |
| --- |
| drivers/net/wireless/iwlwifi/mvm/mac80211.c | 8 ++++++-- |
| drivers/net/wireless/iwlwifi/mvm/nvm.c | 5 ++--- |
| 2 files changed, 8 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c |
| +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c |
| @@ -322,8 +322,12 @@ struct ieee80211_regdomain *iwl_mvm_get_ |
| goto out; |
| } |
| |
| - if (changed) |
| - *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE); |
| + if (changed) { |
| + u32 status = le32_to_cpu(resp->status); |
| + |
| + *changed = (status == MCC_RESP_NEW_CHAN_PROFILE || |
| + status == MCC_RESP_ILLEGAL); |
| + } |
| |
| regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg, |
| __le32_to_cpu(resp->n_channels), |
| --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c |
| +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c |
| @@ -667,9 +667,8 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, |
| |
| n_channels = __le32_to_cpu(mcc_resp->n_channels); |
| 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_NEW_CHAN_PROFILE), n_channels); |
| + "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') n_chans: %d\n", |
| + status, mcc, mcc >> 8, mcc & 0xff, n_channels); |
| |
| resp_len = sizeof(*mcc_resp) + n_channels * sizeof(__le32); |
| resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL); |