diff options
author | Andrei Otcheretianski <andrei.otcheretianski@intel.com> | 2014-06-05 17:40:36 +0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-07-07 22:41:19 +0400 |
commit | 664322fa43b7a52a9e8be9a3874c024412c24a50 (patch) | |
tree | 35a7da90749129b0b0d432e15f163b0e25bebb47 /drivers/net/wireless/iwlwifi | |
parent | fe887665a87b4c45be21253c4a6904ad1334be85 (diff) | |
download | linux-664322fa43b7a52a9e8be9a3874c024412c24a50.tar.xz |
iwlwifi: mvm: Protect mvm->csa_vif with RCU
Currently mvm->csa_vif is protected with mvm mutex. The RCU protection
is required for "iwlwifi: mvm: Reflect GO channel switch in NoA" patch.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 |
3 files changed, 20 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 6d094721a20e..19bd696bd6f8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -1206,6 +1206,7 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_mvm_tx_resp *beacon_notify_hdr; + struct ieee80211_vif *csa_vif; u64 tsf; lockdep_assert_held(&mvm->mutex); @@ -1231,13 +1232,15 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, mvm->ap_last_beacon_gp2, le32_to_cpu(beacon_notify_hdr->initial_rate)); - if (unlikely(mvm->csa_vif && mvm->csa_vif->csa_active)) { - if (!ieee80211_csa_is_complete(mvm->csa_vif)) { - ieee80211_csa_update_counter(mvm->csa_vif); - iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm->csa_vif); + csa_vif = rcu_dereference_protected(mvm->csa_vif, + lockdep_is_held(&mvm->mutex)); + if (unlikely(csa_vif && csa_vif->csa_active)) { + if (!ieee80211_csa_is_complete(csa_vif)) { + ieee80211_csa_update_counter(csa_vif); + iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif); } else { - ieee80211_csa_finish(mvm->csa_vif); - mvm->csa_vif = NULL; + ieee80211_csa_finish(csa_vif); + RCU_INIT_POINTER(mvm->csa_vif, NULL); } } diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 78a78c02dda5..984a1e75aad0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1607,6 +1607,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + /* Handle AP stop while in CSA */ + if (rcu_access_pointer(mvm->csa_vif) == vif) + RCU_INIT_POINTER(mvm->csa_vif, NULL); + mvmvif->ap_ibss_active = false; mvm->ap_last_beacon_gp2 = 0; @@ -2664,15 +2668,19 @@ static void iwl_mvm_channel_switch_beacon(struct ieee80211_hw *hw, struct cfg80211_chan_def *chandef) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct ieee80211_vif *csa_vif; mutex_lock(&mvm->mutex); - if (WARN(mvm->csa_vif && mvm->csa_vif->csa_active, + + csa_vif = rcu_dereference_protected(mvm->csa_vif, + lockdep_is_held(&mvm->mutex)); + if (WARN(csa_vif && csa_vif->csa_active, "Another CSA is already in progress")) goto out_unlock; IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n", chandef->center_freq1); - mvm->csa_vif = vif; + rcu_assign_pointer(mvm->csa_vif, vif); out_unlock: mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index fa8fcbcceb23..5bb42af8886b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -658,7 +658,7 @@ struct iwl_mvm { /* Indicate if device power save is allowed */ bool ps_disabled; - struct ieee80211_vif *csa_vif; + struct ieee80211_vif __rcu *csa_vif; /* system time of last beacon (for AP/GO interface) */ u32 ap_last_beacon_gp2; |