diff options
author | Andrei Otcheretianski <andrei.otcheretianski@intel.com> | 2014-06-05 09:40:36 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-07-07 14:41:19 -0400 |
commit | 664322fa43b7a52a9e8be9a3874c024412c24a50 (patch) | |
tree | 35a7da90749129b0b0d432e15f163b0e25bebb47 /drivers/net/wireless/iwlwifi/mvm | |
parent | fe887665a87b4c45be21253c4a6904ad1334be85 (diff) |
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/mvm')
-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, | |||
1206 | { | 1206 | { |
1207 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1207 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1208 | struct iwl_mvm_tx_resp *beacon_notify_hdr; | 1208 | struct iwl_mvm_tx_resp *beacon_notify_hdr; |
1209 | struct ieee80211_vif *csa_vif; | ||
1209 | u64 tsf; | 1210 | u64 tsf; |
1210 | 1211 | ||
1211 | lockdep_assert_held(&mvm->mutex); | 1212 | lockdep_assert_held(&mvm->mutex); |
@@ -1231,13 +1232,15 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, | |||
1231 | mvm->ap_last_beacon_gp2, | 1232 | mvm->ap_last_beacon_gp2, |
1232 | le32_to_cpu(beacon_notify_hdr->initial_rate)); | 1233 | le32_to_cpu(beacon_notify_hdr->initial_rate)); |
1233 | 1234 | ||
1234 | if (unlikely(mvm->csa_vif && mvm->csa_vif->csa_active)) { | 1235 | csa_vif = rcu_dereference_protected(mvm->csa_vif, |
1235 | if (!ieee80211_csa_is_complete(mvm->csa_vif)) { | 1236 | lockdep_is_held(&mvm->mutex)); |
1236 | ieee80211_csa_update_counter(mvm->csa_vif); | 1237 | if (unlikely(csa_vif && csa_vif->csa_active)) { |
1237 | iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm->csa_vif); | 1238 | if (!ieee80211_csa_is_complete(csa_vif)) { |
1239 | ieee80211_csa_update_counter(csa_vif); | ||
1240 | iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif); | ||
1238 | } else { | 1241 | } else { |
1239 | ieee80211_csa_finish(mvm->csa_vif); | 1242 | ieee80211_csa_finish(csa_vif); |
1240 | mvm->csa_vif = NULL; | 1243 | RCU_INIT_POINTER(mvm->csa_vif, NULL); |
1241 | } | 1244 | } |
1242 | } | 1245 | } |
1243 | 1246 | ||
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, | |||
1607 | 1607 | ||
1608 | mutex_lock(&mvm->mutex); | 1608 | mutex_lock(&mvm->mutex); |
1609 | 1609 | ||
1610 | /* Handle AP stop while in CSA */ | ||
1611 | if (rcu_access_pointer(mvm->csa_vif) == vif) | ||
1612 | RCU_INIT_POINTER(mvm->csa_vif, NULL); | ||
1613 | |||
1610 | mvmvif->ap_ibss_active = false; | 1614 | mvmvif->ap_ibss_active = false; |
1611 | mvm->ap_last_beacon_gp2 = 0; | 1615 | mvm->ap_last_beacon_gp2 = 0; |
1612 | 1616 | ||
@@ -2664,15 +2668,19 @@ static void iwl_mvm_channel_switch_beacon(struct ieee80211_hw *hw, | |||
2664 | struct cfg80211_chan_def *chandef) | 2668 | struct cfg80211_chan_def *chandef) |
2665 | { | 2669 | { |
2666 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 2670 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
2671 | struct ieee80211_vif *csa_vif; | ||
2667 | 2672 | ||
2668 | mutex_lock(&mvm->mutex); | 2673 | mutex_lock(&mvm->mutex); |
2669 | if (WARN(mvm->csa_vif && mvm->csa_vif->csa_active, | 2674 | |
2675 | csa_vif = rcu_dereference_protected(mvm->csa_vif, | ||
2676 | lockdep_is_held(&mvm->mutex)); | ||
2677 | if (WARN(csa_vif && csa_vif->csa_active, | ||
2670 | "Another CSA is already in progress")) | 2678 | "Another CSA is already in progress")) |
2671 | goto out_unlock; | 2679 | goto out_unlock; |
2672 | 2680 | ||
2673 | IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n", | 2681 | IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n", |
2674 | chandef->center_freq1); | 2682 | chandef->center_freq1); |
2675 | mvm->csa_vif = vif; | 2683 | rcu_assign_pointer(mvm->csa_vif, vif); |
2676 | 2684 | ||
2677 | out_unlock: | 2685 | out_unlock: |
2678 | mutex_unlock(&mvm->mutex); | 2686 | 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 { | |||
658 | /* Indicate if device power save is allowed */ | 658 | /* Indicate if device power save is allowed */ |
659 | bool ps_disabled; | 659 | bool ps_disabled; |
660 | 660 | ||
661 | struct ieee80211_vif *csa_vif; | 661 | struct ieee80211_vif __rcu *csa_vif; |
662 | 662 | ||
663 | /* system time of last beacon (for AP/GO interface) */ | 663 | /* system time of last beacon (for AP/GO interface) */ |
664 | u32 ap_last_beacon_gp2; | 664 | u32 ap_last_beacon_gp2; |