From: Luciano Coelho <luciano.coelho@xxxxxxxxx> Send a channel switch failed notification to userspace when an ongoing channel swith fails. Signed-off-by: Luciano Coelho <luciano.coelho@xxxxxxxxx> --- net/mac80211/cfg.c | 30 +++++++++++++++++++++++------- net/mac80211/iface.c | 6 +++++- net/mac80211/mlme.c | 9 ++++++++- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 53a2cfe..f8958e0 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1101,9 +1101,13 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata); /* abort any running channel switch */ - sdata->vif.csa_active = false; - kfree(sdata->u.ap.next_beacon); - sdata->u.ap.next_beacon = NULL; + if (sdata->vif.csa_active) { + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); + sdata->vif.csa_active = false; + kfree(sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon = NULL; + } /* turn off carrier for this interface and dependent VLANs */ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) @@ -3030,8 +3034,11 @@ static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) sdata->radar_required = sdata->csa_radar_required; err = ieee80211_vif_change_channel(sdata, &changed); mutex_unlock(&local->mtx); - if (WARN_ON(err < 0)) + if (WARN_ON(err < 0)) { + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); return; + } if (!local->use_chanctx) { local->_oper_chandef = sdata->csa_chandef; @@ -3045,21 +3052,30 @@ static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata) kfree(sdata->u.ap.next_beacon); sdata->u.ap.next_beacon = NULL; - if (err < 0) + if (err < 0) { + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); return; + } changed |= err; break; case NL80211_IFTYPE_ADHOC: err = ieee80211_ibss_finish_csa(sdata); - if (err < 0) + if (err < 0) { + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); return; + } changed |= err; break; #ifdef CONFIG_MAC80211_MESH case NL80211_IFTYPE_MESH_POINT: err = ieee80211_mesh_finish_csa(sdata); - if (err < 0) + if (err < 0) { + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); return; + } changed |= err; break; #endif diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7fff3dc..578f6e6 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -838,7 +838,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, cancel_work_sync(&sdata->recalc_smps); sdata_lock(sdata); - sdata->vif.csa_active = false; + if (sdata->vif.csa_active) { + sdata->vif.csa_active = false; + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); + } sdata_unlock(sdata); cancel_work_sync(&sdata->csa_finalize_work); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 139005d..beff8c8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -958,6 +958,8 @@ static void ieee80211_chswitch_work(struct work_struct *work) "vif channel switch failed, disconnecting\n"); ieee80211_queue_work(&sdata->local->hw, &ifmgd->csa_connection_drop_work); + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); goto out; } @@ -2060,7 +2062,12 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, true, frame_buf); ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; - sdata->vif.csa_active = false; + + if (sdata->vif.csa_active) { + cfg80211_ch_switch_failed_notify(sdata->dev, + &sdata->csa_chandef); + sdata->vif.csa_active = false; + } ieee80211_wake_queues_by_reason(&sdata->local->hw, IEEE80211_MAX_QUEUE_MAP, IEEE80211_QUEUE_STOP_REASON_CSA); -- 1.9.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html