summaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches/406-ath9k-serialize-ath9k_hw_setpower-calls.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/406-ath9k-serialize-ath9k_hw_setpower-calls.patch')
-rw-r--r--package/mac80211/patches/406-ath9k-serialize-ath9k_hw_setpower-calls.patch67
1 files changed, 67 insertions, 0 deletions
diff --git a/package/mac80211/patches/406-ath9k-serialize-ath9k_hw_setpower-calls.patch b/package/mac80211/patches/406-ath9k-serialize-ath9k_hw_setpower-calls.patch
new file mode 100644
index 000000000..45ddf81e5
--- /dev/null
+++ b/package/mac80211/patches/406-ath9k-serialize-ath9k_hw_setpower-calls.patch
@@ -0,0 +1,67 @@
+From 841c7e339c4775f4cc614c92aaea82f70fcafbdb Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 21 Jun 2009 16:59:53 +0200
+Subject: [PATCH 1/3] ath9k: serialize ath9k_hw_setpower calls
+
+Because ath9k_setpower is called from various contexts, we have to
+protect it against concurrent calls.
+
+Changes-licensed-under: ISC
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
+ drivers/net/wireless/ath/ath9k/hw.c | 15 ++++++++++++++-
+ drivers/net/wireless/ath/ath9k/main.c | 1 +
+ 3 files changed, 16 insertions(+), 1 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -544,6 +544,7 @@ struct ath_softc {
+ int irq;
+ spinlock_t sc_resetlock;
+ spinlock_t sc_serial_rw;
++ spinlock_t sc_pm_lock;
+ struct mutex mutex;
+
+ u8 curbssid[ETH_ALEN];
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2738,7 +2738,8 @@ static bool ath9k_hw_set_power_awake(str
+ return true;
+ }
+
+-bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
++static bool ath9k_hw_setpower_nolock(struct ath_hw *ah,
++ enum ath9k_power_mode mode)
+ {
+ int status = true, setChip = true;
+ static const char *modes[] = {
+@@ -2772,6 +2773,18 @@ bool ath9k_hw_setpower(struct ath_hw *ah
+ return status;
+ }
+
++bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
++{
++ unsigned long flags;
++ bool ret;
++
++ spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags);
++ ret = ath9k_hw_setpower_nolock(ah, mode);
++ spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags);
++
++ return ret;
++}
++
+ /*
+ * Helper for ASPM support.
+ *
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1317,6 +1317,7 @@ static int ath_init(u16 devid, struct at
+ spin_lock_init(&sc->wiphy_lock);
+ spin_lock_init(&sc->sc_resetlock);
+ spin_lock_init(&sc->sc_serial_rw);
++ spin_lock_init(&sc->sc_pm_lock);
+ mutex_init(&sc->mutex);
+ tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
+ tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,