All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] mac80211_hwsim: fix PS debugfs file locking
@ 2015-01-09 10:49 Johannes Berg
  2015-01-09 10:49 ` [PATCH 2/2] mac80211: fix handling TIM IE when stations disconnect Johannes Berg
  0 siblings, 1 reply; 2+ messages in thread
From: Johannes Berg @ 2015-01-09 10:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: j, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

The functions called within the iterators must be called with
tasklets disabled, so use atomic iteration like the rest of
the code and disable tasklets around the whole operation.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/mac80211_hwsim.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 057a99e01637..74f4e1c18322 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -626,22 +626,22 @@ static int hwsim_fops_ps_write(void *dat, u64 val)
 	old_ps = data->ps;
 	data->ps = val;
 
+	local_bh_disable();
 	if (val == PS_MANUAL_POLL) {
-		ieee80211_iterate_active_interfaces(data->hw,
-						    IEEE80211_IFACE_ITER_NORMAL,
-						    hwsim_send_ps_poll, data);
+		ieee80211_iterate_active_interfaces_atomic(
+			data->hw, IEEE80211_IFACE_ITER_NORMAL,
+			hwsim_send_ps_poll, data);
 		data->ps_poll_pending = true;
 	} else if (old_ps == PS_DISABLED && val != PS_DISABLED) {
-		ieee80211_iterate_active_interfaces(data->hw,
-						    IEEE80211_IFACE_ITER_NORMAL,
-						    hwsim_send_nullfunc_ps,
-						    data);
+		ieee80211_iterate_active_interfaces_atomic(
+			data->hw, IEEE80211_IFACE_ITER_NORMAL,
+			hwsim_send_nullfunc_ps, data);
 	} else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
-		ieee80211_iterate_active_interfaces(data->hw,
-						    IEEE80211_IFACE_ITER_NORMAL,
-						    hwsim_send_nullfunc_no_ps,
-						    data);
+		ieee80211_iterate_active_interfaces_atomic(
+			data->hw, IEEE80211_IFACE_ITER_NORMAL,
+			hwsim_send_nullfunc_no_ps, data);
 	}
+	local_bh_enable();
 
 	return 0;
 }
-- 
2.1.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] mac80211: fix handling TIM IE when stations disconnect
  2015-01-09 10:49 [PATCH 1/2] mac80211_hwsim: fix PS debugfs file locking Johannes Berg
@ 2015-01-09 10:49 ` Johannes Berg
  0 siblings, 0 replies; 2+ messages in thread
From: Johannes Berg @ 2015-01-09 10:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: j, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

When a station disconnects with frames still pending, we clear
the TIM bit, but too late - it's only cleared when the station
is already removed from the driver, and thus the driver can get
confused (and hwsim will loudly complain.)

Fix this by clearing the TIM bit earlier, when the station has
been unlinked but not removed from the driver yet. To do this,
refactor the TIM recalculation to in that case ignore traffic
and simply assume no pending traffic - this is correct for the
disconnected station even though the frames haven't been freed
yet at that point.

This patch isn't needed for current drivers though as they don't
check the station argument to the set_tim() operation and thus
don't really run into the possible confusion.

Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/sta_info.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index dc352fcdd469..79383ef0c264 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -116,7 +116,6 @@ static void __cleanup_single_sta(struct sta_info *sta)
 		clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
 
 		atomic_dec(&ps->num_sta_ps);
-		sta_info_recalc_tim(sta);
 	}
 
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
@@ -625,7 +624,7 @@ static unsigned long ieee80211_tids_for_ac(int ac)
 	}
 }
 
-void sta_info_recalc_tim(struct sta_info *sta)
+static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending)
 {
 	struct ieee80211_local *local = sta->local;
 	struct ps_data *ps;
@@ -667,6 +666,9 @@ void sta_info_recalc_tim(struct sta_info *sta)
 	if (ignore_for_tim == BIT(IEEE80211_NUM_ACS) - 1)
 		ignore_for_tim = 0;
 
+	if (ignore_pending)
+		ignore_for_tim = BIT(IEEE80211_NUM_ACS) - 1;
+
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 		unsigned long tids;
 
@@ -695,7 +697,7 @@ void sta_info_recalc_tim(struct sta_info *sta)
 	else
 		__bss_tim_clear(ps->tim, id);
 
-	if (local->ops->set_tim) {
+	if (local->ops->set_tim && !WARN_ON(sta->dead)) {
 		local->tim_in_locked_section = true;
 		drv_set_tim(local, &sta->sta, indicate_tim);
 		local->tim_in_locked_section = false;
@@ -705,6 +707,11 @@ out_unlock:
 	spin_unlock_bh(&local->tim_lock);
 }
 
+void sta_info_recalc_tim(struct sta_info *sta)
+{
+	__sta_info_recalc_tim(sta, false);
+}
+
 static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb)
 {
 	struct ieee80211_tx_info *info;
@@ -888,6 +895,9 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
 	/* now keys can no longer be reached */
 	ieee80211_free_sta_keys(local, sta);
 
+	/* disable TIM bit - last chance to tell driver */
+	__sta_info_recalc_tim(sta, true);
+
 	sta->dead = true;
 
 	local->num_sta--;
-- 
2.1.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-01-09 10:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-09 10:49 [PATCH 1/2] mac80211_hwsim: fix PS debugfs file locking Johannes Berg
2015-01-09 10:49 ` [PATCH 2/2] mac80211: fix handling TIM IE when stations disconnect Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.