aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-03-19 04:55:55 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-03-19 16:29:53 -0400
commit1a1cb744de160ee70086a77afff605bbc275d291 (patch)
tree6703edcce54889b86df6c7f5b72deca0d3affd0e
parentc9c3a0604614344f7c73523176b6d0a85cba6eab (diff)
mac80211: fix suspend vs. authentication race
Since Stanislaw's patch removing the quiescing code, mac80211 had a race regarding suspend vs. authentication: as cfg80211 doesn't track authentication attempts, it can't abort them. Therefore the attempts may be kept running while suspending, which can lead to all kinds of issues, in at least some cases causing an error in iwlmvm firmware. Fix this by aborting the authentication attempt when suspending. Cc: stable@vger.kernel.org Fixes: 12e7f517029d ("mac80211: cleanup generic suspend/resume procedures") Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c26
-rw-r--r--net/mac80211/pm.c14
3 files changed, 38 insertions, 3 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8603dfb52b3a..562cedde0ada 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1391,6 +1391,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
1391void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); 1391void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
1392void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata, 1392void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
1393 __le16 fc, bool acked); 1393 __le16 fc, bool acked);
1394void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata);
1394void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); 1395void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
1395 1396
1396/* IBSS code */ 1397/* IBSS code */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5ade21eb3602..6d24e6c8f320 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3576,6 +3576,32 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
3576} 3576}
3577 3577
3578#ifdef CONFIG_PM 3578#ifdef CONFIG_PM
3579void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
3580{
3581 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3582 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3583
3584 sdata_lock(sdata);
3585
3586 if (ifmgd->auth_data) {
3587 /*
3588 * If we are trying to authenticate while suspending, cfg80211
3589 * won't know and won't actually abort those attempts, thus we
3590 * need to do that ourselves.
3591 */
3592 ieee80211_send_deauth_disassoc(sdata,
3593 ifmgd->auth_data->bss->bssid,
3594 IEEE80211_STYPE_DEAUTH,
3595 WLAN_REASON_DEAUTH_LEAVING,
3596 false, frame_buf);
3597 ieee80211_destroy_auth_data(sdata, false);
3598 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
3599 IEEE80211_DEAUTH_FRAME_LEN);
3600 }
3601
3602 sdata_unlock(sdata);
3603}
3604
3579void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) 3605void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3580{ 3606{
3581 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3607 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index af64fb8e8add..d478b880a0af 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -100,10 +100,18 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
100 100
101 /* remove all interfaces that were created in the driver */ 101 /* remove all interfaces that were created in the driver */
102 list_for_each_entry(sdata, &local->interfaces, list) { 102 list_for_each_entry(sdata, &local->interfaces, list) {
103 if (!ieee80211_sdata_running(sdata) || 103 if (!ieee80211_sdata_running(sdata))
104 sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
105 sdata->vif.type == NL80211_IFTYPE_MONITOR)
106 continue; 104 continue;
105 switch (sdata->vif.type) {
106 case NL80211_IFTYPE_AP_VLAN:
107 case NL80211_IFTYPE_MONITOR:
108 continue;
109 case NL80211_IFTYPE_STATION:
110 ieee80211_mgd_quiesce(sdata);
111 break;
112 default:
113 break;
114 }
107 115
108 drv_remove_interface(local, sdata); 116 drv_remove_interface(local, sdata);
109 } 117 }