aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-03-10 09:44:00 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-03-18 02:40:02 -0400
commit81d62d5a9c4df3f4f7b0c5f5e1158f3fc4802fda (patch)
tree810735d584c51c570e2ff4061873f167f575c766 /drivers/net/wireless/iwlwifi/mvm
parent208d271a3f5388672b3d7ec141e975abd84ab3da (diff)
iwlwifi: mvm: continue (with error) CSA on GO time event failure
If, on a GO, the CSA time event fails to be scheduled, continue the flow towards mac80211's state machine so it doesn't get stuck, but report an error later on the post switch which will cause mac80211 to tear down the operation. This ensures nothing gets stuck due to the scheduling failure. Signed-off-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/mac80211.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c16
3 files changed, 20 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 302c8cc50f25..5f26557e4197 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -3646,6 +3646,8 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
3646 3646
3647 mutex_lock(&mvm->mutex); 3647 mutex_lock(&mvm->mutex);
3648 3648
3649 mvmvif->csa_failed = false;
3650
3649 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", 3651 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n",
3650 chsw->chandef.center_freq1); 3652 chsw->chandef.center_freq1);
3651 3653
@@ -3721,6 +3723,12 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
3721 3723
3722 mutex_lock(&mvm->mutex); 3724 mutex_lock(&mvm->mutex);
3723 3725
3726 if (mvmvif->csa_failed) {
3727 mvmvif->csa_failed = false;
3728 ret = -EIO;
3729 goto out_unlock;
3730 }
3731
3724 if (vif->type == NL80211_IFTYPE_STATION) { 3732 if (vif->type == NL80211_IFTYPE_STATION) {
3725 struct iwl_mvm_sta *mvmsta; 3733 struct iwl_mvm_sta *mvmsta;
3726 3734
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 432265eb0dd7..4903dec7048a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -354,6 +354,7 @@ struct iwl_mvm_vif_bf_data {
354 * @beacon_stats: beacon statistics, containing the # of received beacons, 354 * @beacon_stats: beacon statistics, containing the # of received beacons,
355 * # of received beacons accumulated over FW restart, and the current 355 * # of received beacons accumulated over FW restart, and the current
356 * average signal of beacons retrieved from the firmware 356 * average signal of beacons retrieved from the firmware
357 * @csa_failed: CSA failed to schedule time event, report an error later
357 */ 358 */
358struct iwl_mvm_vif { 359struct iwl_mvm_vif {
359 struct iwl_mvm *mvm; 360 struct iwl_mvm *mvm;
@@ -433,6 +434,7 @@ struct iwl_mvm_vif {
433 434
434 /* Indicates that CSA countdown may be started */ 435 /* Indicates that CSA countdown may be started */
435 bool csa_countdown; 436 bool csa_countdown;
437 bool csa_failed;
436}; 438};
437 439
438static inline struct iwl_mvm_vif * 440static inline struct iwl_mvm_vif *
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 8d179ab67cc2..98c8d70c90d2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -196,19 +196,23 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm,
196 struct iwl_mvm_time_event_data *te_data, 196 struct iwl_mvm_time_event_data *te_data,
197 struct iwl_time_event_notif *notif) 197 struct iwl_time_event_notif *notif)
198{ 198{
199 if (!le32_to_cpu(notif->status)) { 199 struct ieee80211_vif *vif = te_data->vif;
200 if (te_data->vif->type == NL80211_IFTYPE_STATION) 200 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
201 ieee80211_connection_loss(te_data->vif); 201
202 if (!notif->status)
202 IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); 203 IWL_DEBUG_TE(mvm, "CSA time event failed to start\n");
203 iwl_mvm_te_clear_data(mvm, te_data);
204 return;
205 }
206 204
207 switch (te_data->vif->type) { 205 switch (te_data->vif->type) {
208 case NL80211_IFTYPE_AP: 206 case NL80211_IFTYPE_AP:
207 if (!notif->status)
208 mvmvif->csa_failed = true;
209 iwl_mvm_csa_noa_start(mvm); 209 iwl_mvm_csa_noa_start(mvm);
210 break; 210 break;
211 case NL80211_IFTYPE_STATION: 211 case NL80211_IFTYPE_STATION:
212 if (!notif->status) {
213 ieee80211_connection_loss(te_data->vif);
214 break;
215 }
212 iwl_mvm_csa_client_absent(mvm, te_data->vif); 216 iwl_mvm_csa_client_absent(mvm, te_data->vif);
213 ieee80211_chswitch_done(te_data->vif, true); 217 ieee80211_chswitch_done(te_data->vif, true);
214 break; 218 break;