aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-05-08 03:10:02 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-05-08 05:57:27 -0400
commitcf8767dd7635d2209485dc765965d33537ad66eb (patch)
tree95e582416ee448ca113807688f587e5f2f06dff1 /net/mac80211
parent771bb3ddc225d6dbbef8f22838c1287c4e3cd02b (diff)
mac80211: disconnect iface if CSA unexpectedly fails
It doesn't make much sense to leave a crippled interface running. As a side effect this will unblock tx queues with CSA reason immediately after failure instead of until after userspace requests interface to stop. This also gives userspace an opportunity to indirectly see CSA failure. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> [small code cleanup] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 0c87c8c47123..7d358037d4e9 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3090,7 +3090,7 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,
3090 return 0; 3090 return 0;
3091} 3091}
3092 3092
3093static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) 3093static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
3094{ 3094{
3095 struct ieee80211_local *local = sdata->local; 3095 struct ieee80211_local *local = sdata->local;
3096 u32 changed = 0; 3096 u32 changed = 0;
@@ -3101,8 +3101,8 @@ static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
3101 3101
3102 sdata->radar_required = sdata->csa_radar_required; 3102 sdata->radar_required = sdata->csa_radar_required;
3103 err = ieee80211_vif_change_channel(sdata, &changed); 3103 err = ieee80211_vif_change_channel(sdata, &changed);
3104 if (WARN_ON(err < 0)) 3104 if (err < 0)
3105 return; 3105 return err;
3106 3106
3107 if (!local->use_chanctx) { 3107 if (!local->use_chanctx) {
3108 local->_oper_chandef = sdata->csa_chandef; 3108 local->_oper_chandef = sdata->csa_chandef;
@@ -3113,7 +3113,7 @@ static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
3113 3113
3114 err = ieee80211_set_after_csa_beacon(sdata, &changed); 3114 err = ieee80211_set_after_csa_beacon(sdata, &changed);
3115 if (err) 3115 if (err)
3116 return; 3116 return err;
3117 3117
3118 ieee80211_bss_info_change_notify(sdata, changed); 3118 ieee80211_bss_info_change_notify(sdata, changed);
3119 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); 3119 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
@@ -3122,6 +3122,17 @@ static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
3122 ieee80211_wake_queues_by_reason(&local->hw, 3122 ieee80211_wake_queues_by_reason(&local->hw,
3123 IEEE80211_MAX_QUEUE_MAP, 3123 IEEE80211_MAX_QUEUE_MAP,
3124 IEEE80211_QUEUE_STOP_REASON_CSA); 3124 IEEE80211_QUEUE_STOP_REASON_CSA);
3125
3126 return 0;
3127}
3128
3129static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
3130{
3131 if (__ieee80211_csa_finalize(sdata)) {
3132 sdata_info(sdata, "failed to finalize CSA, disconnecting\n");
3133 cfg80211_stop_iface(sdata->local->hw.wiphy, &sdata->wdev,
3134 GFP_KERNEL);
3135 }
3125} 3136}
3126 3137
3127void ieee80211_csa_finalize_work(struct work_struct *work) 3138void ieee80211_csa_finalize_work(struct work_struct *work)