Search Linux Wireless

[PATCH 4/5] mac80211: fix idle change notifications upon device stop

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Drivers that depend on tuning their devices to disable the radio
completely and properly through mac80211' idle state change
were being left with the radio turned on once a device interface
is stopped, the reason is that we first were checking for the open
count prior to issuing any further config changes. For some devices
this could mean breaking suspend and resume completely as they were
under the impression that the idle state change to idle would be
issued either during or after the stop callback. Fix this by
allowing state changes through upon the device stop.

This fixes suspend and resume on ath9k and likely a few other
drivers.

Cc: stable@xxxxxxxxxx
Cc: Paul Stewart <pstew@xxxxxxxxxx>
Cc: Amod Bodas <amod.bodas@xxxxxxxxxxx>
Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx>
Signed-off-by: Luis R. Rodriguez <lrodriguez@xxxxxxxxxxx>
---
 net/mac80211/ieee80211_i.h |    9 ++++++++-
 net/mac80211/iface.c       |    9 ++-------
 net/mac80211/main.c        |    4 ++--
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 72499fe..ae32349 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1023,8 +1023,15 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
 	       is_broadcast_ether_addr(raddr);
 }
 
+int __ieee80211_hw_config(struct ieee80211_local *local,
+			  u32 changed, bool nocheck);
+
+static inline int ieee80211_hw_config(struct ieee80211_local *local,
+				      u32 changed)
+{
+	return __ieee80211_hw_config(local, changed, false);
+}
 
-int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
 void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 				      u32 changed);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index f0f11bb..36b7000 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -530,20 +530,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 
 	ieee80211_recalc_ps(local, -1);
 
+	__ieee80211_hw_config(local, hw_reconf_flags, true);
+
 	if (local->open_count == 0) {
 		if (local->ops->napi_poll)
 			napi_disable(&local->napi);
 		ieee80211_clear_tx_pending(local);
 		ieee80211_stop_device(local);
-
-		/* no reconfiguring after stop! */
-		hw_reconf_flags = 0;
 	}
 
-	/* do after stop to avoid reconfiguring when we stop anyway */
-	if (hw_reconf_flags)
-		ieee80211_hw_config(local, hw_reconf_flags);
-
 	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
 		skb_queue_walk_safe(&local->pending[i], skb, tmp) {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 2de6976..45d6f21 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -96,7 +96,7 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
 	ieee80211_configure_filter(local);
 }
 
-int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
+int __ieee80211_hw_config(struct ieee80211_local *local, u32 changed, bool nocheck)
 {
 	struct ieee80211_channel *chan, *scan_chan;
 	int ret = 0;
@@ -159,7 +159,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 		local->hw.conf.power_level = power;
 	}
 
-	if (changed && local->open_count) {
+	if (changed && (nocheck || local->open_count)) {
 		ret = drv_config(local, changed);
 		/*
 		 * Goal:
-- 
1.7.3.2.90.gd4c43

--
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


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux