aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h2
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
2677out_unlock: 2685out_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;