2015-01-30 13:32:41

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 00/17] ath9k patches

From: Sujith Manoharan <[email protected]>

ath9k patches for -next.

Sujith Manoharan (17):
ath9k: Remove ATH9K_HW_WOW_DEVICE_CAPABLE
ath9k: Return early for error conditions
ath9k: Remove redundant device_can_wakeup() check
ath9k: Check early for multi-vif/STA conditions
ath9k: Check multi-channel context for WOW
ath9k: Fix wow init/deinit
ath9k: Check WOW triggers properly
ath9k: Remove unused BMISS processing
ath9k: Remove ath9k_hw_wow_event_to_string
ath9k: Add a debugfs file for WOW
ath9k: Simplify user pattern configuration
ath9k: Add a HW structure for WOW
ath9k: Register max WOW patterns
ath9k: Move WOW registers to reg_wow.h
ath9k: Remove incorrect register macros
ath9k: Cleanup reg_wow.h
ath9k: Fix max pattern check

drivers/net/wireless/ath/ath.h | 1 +
drivers/net/wireless/ath/ath9k/ar9003_wow.c | 38 ++---
drivers/net/wireless/ath/ath9k/ath9k.h | 13 +-
drivers/net/wireless/ath/ath9k/debug.c | 68 +++++++++
drivers/net/wireless/ath/ath9k/hw.c | 10 +-
drivers/net/wireless/ath/ath9k/hw.h | 34 ++---
drivers/net/wireless/ath/ath9k/init.c | 1 +
drivers/net/wireless/ath/ath9k/main.c | 9 --
drivers/net/wireless/ath/ath9k/pci.c | 5 +-
drivers/net/wireless/ath/ath9k/reg.h | 120 ----------------
drivers/net/wireless/ath/ath9k/reg_wow.h | 93 ++++++++++++
drivers/net/wireless/ath/ath9k/wow.c | 212 ++++++++++++----------------
12 files changed, 301 insertions(+), 303 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath9k/reg_wow.h

--
2.2.2



2015-01-30 13:32:48

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 06/17] ath9k: Fix wow init/deinit

From: Sujith Manoharan <[email protected]>

Registering the card as a wakeup source needs to
be done once, during initialization. When the WOW
configuration changes, the card's status as wakeup
source needs to be changed too and this is done
via the set_wakeup() callback. Also, make sure
the device is removed properly using ath9k_deinit_wow().

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 4 ++++
drivers/net/wireless/ath/ath9k/init.c | 1 +
drivers/net/wireless/ath/ath9k/wow.c | 22 ++++++++++++++++++----
3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index e84b576..4209d7b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -838,6 +838,7 @@ struct ath9k_wow_pattern {

#ifdef CONFIG_ATH9K_WOW
void ath9k_init_wow(struct ieee80211_hw *hw);
+void ath9k_deinit_wow(struct ieee80211_hw *hw);
int ath9k_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan);
int ath9k_resume(struct ieee80211_hw *hw);
@@ -846,6 +847,9 @@ void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
static inline void ath9k_init_wow(struct ieee80211_hw *hw)
{
}
+static inline void ath9k_deinit_wow(struct ieee80211_hw *hw)
+{
+}
static inline int ath9k_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan)
{
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 2aef14e..6c6e884 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -996,6 +996,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
ath9k_ps_restore(sc);

ath9k_deinit_debug(sc);
+ ath9k_deinit_wow(hw);
ieee80211_unregister_hw(hw);
ath_rx_cleanup(sc);
ath9k_deinit_softc(sc);
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 1b005c6..8bcbaa9 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -336,20 +336,34 @@ int ath9k_resume(struct ieee80211_hw *hw)
void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
{
struct ath_softc *sc = hw->priv;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);

mutex_lock(&sc->mutex);
- device_init_wakeup(sc->dev, 1);
device_set_wakeup_enable(sc->dev, enabled);
mutex_unlock(&sc->mutex);
+
+ ath_dbg(common, WOW, "WoW wakeup source is %s\n",
+ (enabled) ? "enabled" : "disabled");
}

void ath9k_init_wow(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;

- if ((sc->driver_data & ATH9K_PCI_WOW) && device_can_wakeup(sc->dev))
+ if (sc->driver_data & ATH9K_PCI_WOW) {
hw->wiphy->wowlan = &ath9k_wowlan_support;

- atomic_set(&sc->wow_sleep_proc_intr, -1);
- atomic_set(&sc->wow_got_bmiss_intr, -1);
+ atomic_set(&sc->wow_sleep_proc_intr, -1);
+ atomic_set(&sc->wow_got_bmiss_intr, -1);
+
+ device_init_wakeup(sc->dev, 1);
+ }
+}
+
+void ath9k_deinit_wow(struct ieee80211_hw *hw)
+{
+ struct ath_softc *sc = hw->priv;
+
+ if (sc->driver_data & ATH9K_PCI_WOW)
+ device_init_wakeup(sc->dev, 0);
}
--
2.2.2


2015-01-30 13:33:03

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 17/17] ath9k: Fix max pattern check

From: Sujith Manoharan <[email protected]>

Since the maximum number of configurable patterns
is chip-specific, use the HW capability instead
of a fixed value for checking if a free pattern
slot is available.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_wow.c | 12 +++----
drivers/net/wireless/ath/ath9k/hw.h | 17 ++++-----
drivers/net/wireless/ath/ath9k/wow.c | 53 ++++++++++++++++++++---------
3 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index 6681a7b..d2a4f6f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -89,17 +89,16 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)

}

-void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
- u8 *user_mask, int pattern_count,
- int pattern_len)
+int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
+ u8 *user_mask, int pattern_count,
+ int pattern_len)
{
int i;
u32 pattern_val, mask_val;
u32 set, clr;

- /* FIXME: should check count by querying the hardware capability */
- if (pattern_count >= MAX_NUM_PATTERN)
- return;
+ if (pattern_count >= ah->wow.max_patterns)
+ return -ENOSPC;

REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));

@@ -154,6 +153,7 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
}

+ return 0;
}
EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e1801c9..f51a28f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1152,18 +1152,19 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)


#ifdef CONFIG_ATH9K_WOW
-void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
- u8 *user_mask, int pattern_count,
- int pattern_len);
+int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
+ u8 *user_mask, int pattern_count,
+ int pattern_len);
u32 ath9k_hw_wow_wakeup(struct ath_hw *ah);
void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable);
#else
-static inline void ath9k_hw_wow_apply_pattern(struct ath_hw *ah,
- u8 *user_pattern,
- u8 *user_mask,
- int pattern_count,
- int pattern_len)
+static inline int ath9k_hw_wow_apply_pattern(struct ath_hw *ah,
+ u8 *user_pattern,
+ u8 *user_mask,
+ int pattern_count,
+ int pattern_len)
{
+ return 0;
}
static inline u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
{
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index da52b1f..5092939 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -40,12 +40,12 @@ static u8 ath9k_wow_map_triggers(struct ath_softc *sc,
return wow_triggers;
}

-static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
+static int ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
int pattern_count = 0;
- int i, byte_cnt = 0;
+ int ret, i, byte_cnt = 0;
u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
u8 dis_deauth_mask[MAX_PATTERN_SIZE];

@@ -110,8 +110,10 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
dis_deauth_mask[1] = 0x03;
dis_deauth_mask[2] = 0xc0;

- ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
- pattern_count, byte_cnt);
+ ret = ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
+ pattern_count, byte_cnt);
+ if (ret)
+ goto exit;

pattern_count++;
/*
@@ -120,18 +122,20 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
*/
dis_deauth_pattern[0] = 0xC0;

- ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
- pattern_count, byte_cnt);
+ ret = ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
+ pattern_count, byte_cnt);
+exit:
+ return ret;
}

-static void ath9k_wow_add_pattern(struct ath_softc *sc,
- struct cfg80211_wowlan *wowlan)
+static int ath9k_wow_add_pattern(struct ath_softc *sc,
+ struct cfg80211_wowlan *wowlan)
{
struct ath_hw *ah = sc->sc_ah;
struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
u8 wow_pattern[MAX_PATTERN_SIZE];
u8 wow_mask[MAX_PATTERN_SIZE];
- int mask_len;
+ int mask_len, ret = 0;
s8 i = 0;

for (i = 0; i < wowlan->n_patterns; i++) {
@@ -141,12 +145,16 @@ static void ath9k_wow_add_pattern(struct ath_softc *sc,
memcpy(wow_pattern, patterns[i].pattern, patterns[i].pattern_len);
memcpy(wow_mask, patterns[i].mask, mask_len);

- ath9k_hw_wow_apply_pattern(ah,
- wow_pattern,
- wow_mask,
- i + 2,
- patterns[i].pattern_len);
+ ret = ath9k_hw_wow_apply_pattern(ah,
+ wow_pattern,
+ wow_mask,
+ i + 2,
+ patterns[i].pattern_len);
+ if (ret)
+ break;
}
+
+ return ret;
}

int ath9k_suspend(struct ieee80211_hw *hw,
@@ -213,10 +221,21 @@ int ath9k_suspend(struct ieee80211_hw *hw,
* Enable wake up on recieving disassoc/deauth
* frame by default.
*/
- ath9k_wow_add_disassoc_deauth_pattern(sc);
+ ret = ath9k_wow_add_disassoc_deauth_pattern(sc);
+ if (ret) {
+ ath_err(common,
+ "Unable to add disassoc/deauth pattern: %d\n", ret);
+ goto fail_wow;
+ }

- if (triggers & AH_WOW_USER_PATTERN_EN)
- ath9k_wow_add_pattern(sc, wowlan);
+ if (triggers & AH_WOW_USER_PATTERN_EN) {
+ ret = ath9k_wow_add_pattern(sc, wowlan);
+ if (ret) {
+ ath_err(common,
+ "Unable to add user pattern: %d\n", ret);
+ goto fail_wow;
+ }
+ }

spin_lock_bh(&sc->sc_pcu_lock);
/*
--
2.2.2


2015-01-30 13:33:00

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 15/17] ath9k: Remove incorrect register macros

From: Sujith Manoharan <[email protected]>

These macros are applicable to pre-AR9003 chips
and the addresses are different for the AR9003
family. Since they are unused anyway, remove them.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/reg_wow.h | 5 -----
1 file changed, 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/reg_wow.h b/drivers/net/wireless/ath/ath9k/reg_wow.h
index 3dbe5db..780553a 100644
--- a/drivers/net/wireless/ath/ath9k/reg_wow.h
+++ b/drivers/net/wireless/ath/ath9k/reg_wow.h
@@ -23,14 +23,9 @@
#define AR_WOW_BCN_TIMO 0x8274
#define AR_WOW_KEEP_ALIVE_TIMO 0x8278
#define AR_WOW_KEEP_ALIVE 0x827c
-#define AR_WOW_US_SCALAR 0x8284
#define AR_WOW_KEEP_ALIVE_DELAY 0x8288
#define AR_WOW_PATTERN_MATCH 0x828c
-#define AR_WOW_PATTERN_OFF1 0x8290 /* pattern bytes 0 -> 3 */
-#define AR_WOW_PATTERN_OFF2 0x8294 /* pattern bytes 4 -> 7 */

-/* for AR9285 or later version of chips */
-#define AR_WOW_EXACT 0x829c
#define AR_WOW_LENGTH1 0x8360
#define AR_WOW_LENGTH2 0X8364
/* register to enable match for less than 256 bytes packets */
--
2.2.2


2015-01-30 13:32:49

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 07/17] ath9k: Check WOW triggers properly

From: Sujith Manoharan <[email protected]>

This patch makes sure that valid WOW triggers
are present before trying to suspend the device.
Also, introduce and use ATH_OP_WOW_ENABLED to
bypass PCI suspend and clear it in resume().

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath.h | 1 +
drivers/net/wireless/ath/ath9k/pci.c | 5 +++-
drivers/net/wireless/ath/ath9k/wow.c | 53 ++++++++++++++++--------------------
3 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index ccba4fe..1eebe2e 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -64,6 +64,7 @@ enum ath_op_flags {
ATH_OP_HW_RESET,
ATH_OP_SCANNING,
ATH_OP_MULTI_CHANNEL,
+ ATH_OP_WOW_ENABLED,
};

enum ath_bus_type {
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index cc5c681..e6fef1b 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -998,9 +998,12 @@ static int ath_pci_suspend(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);

- if (sc->wow_enabled)
+ if (test_bit(ATH_OP_WOW_ENABLED, &common->op_flags)) {
+ dev_info(&pdev->dev, "WOW is enabled, bypassing PCI suspend\n");
return 0;
+ }

/* The device has to be moved to FULLSLEEP forcibly.
* Otherwise the chip never moved to full sleep,
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 8bcbaa9..c0c564d 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -23,21 +23,21 @@ static const struct wiphy_wowlan_support ath9k_wowlan_support = {
.pattern_max_len = MAX_PATTERN_SIZE,
};

-static void ath9k_wow_map_triggers(struct ath_softc *sc,
- struct cfg80211_wowlan *wowlan,
- u32 *wow_triggers)
+static u8 ath9k_wow_map_triggers(struct ath_softc *sc,
+ struct cfg80211_wowlan *wowlan)
{
+ u8 wow_triggers = 0;
+
if (wowlan->disconnect)
- *wow_triggers |= AH_WOW_LINK_CHANGE |
- AH_WOW_BEACON_MISS;
+ wow_triggers |= AH_WOW_LINK_CHANGE |
+ AH_WOW_BEACON_MISS;
if (wowlan->magic_pkt)
- *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
+ wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;

if (wowlan->n_patterns)
- *wow_triggers |= AH_WOW_USER_PATTERN_EN;
-
- sc->wow_enabled = *wow_triggers;
+ wow_triggers |= AH_WOW_USER_PATTERN_EN;

+ return wow_triggers;
}

static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
@@ -45,7 +45,7 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
int pattern_count = 0;
- int i, byte_cnt;
+ int i, byte_cnt = 0;
u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
u8 dis_deauth_mask[MAX_PATTERN_SIZE];

@@ -80,12 +80,7 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
* | x:x:x:x:x:x -- 22 bytes
*/

- /* Create Disassociate Pattern first */
-
- byte_cnt = 0;
-
/* Fill out the mask with all FF's */
-
for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
dis_deauth_mask[i] = 0xff;

@@ -108,17 +103,13 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
byte_cnt += 6;

/* copy the bssid, its same as the source mac address */
-
memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);

/* Create Disassociate pattern mask */
-
dis_deauth_mask[0] = 0xfe;
dis_deauth_mask[1] = 0x03;
dis_deauth_mask[2] = 0xc0;

- ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
-
ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
pattern_count, byte_cnt);

@@ -131,7 +122,6 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)

ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
pattern_count, byte_cnt);
-
}

static void ath9k_wow_add_pattern(struct ath_softc *sc,
@@ -190,7 +180,7 @@ int ath9k_suspend(struct ieee80211_hw *hw,
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- u32 wow_triggers_enabled = 0;
+ u8 triggers;
int ret = 0;

ath9k_deinit_channel_context(sc);
@@ -230,14 +220,16 @@ int ath9k_suspend(struct ieee80211_hw *hw,
goto fail_wow;
}

+ triggers = ath9k_wow_map_triggers(sc, wowlan);
+ if (!triggers) {
+ ath_dbg(common, WOW, "No valid WoW triggers\n");
+ ret = 1;
+ goto fail_wow;
+ }
+
ath_cancel_work(sc);
ath_stop_ani(sc);

- ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
-
- ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
- wow_triggers_enabled);
-
ath9k_ps_wakeup(sc);

ath9k_stop_btcoex(sc);
@@ -248,7 +240,7 @@ int ath9k_suspend(struct ieee80211_hw *hw,
*/
ath9k_wow_add_disassoc_deauth_pattern(sc);

- if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
+ if (triggers & AH_WOW_USER_PATTERN_EN)
ath9k_wow_add_pattern(sc, wowlan);

spin_lock_bh(&sc->sc_pcu_lock);
@@ -273,12 +265,13 @@ int ath9k_suspend(struct ieee80211_hw *hw,
synchronize_irq(sc->irq);
tasklet_kill(&sc->intr_tq);

- ath9k_hw_wow_enable(ah, wow_triggers_enabled);
+ ath9k_hw_wow_enable(ah, triggers);

ath9k_ps_restore(sc);
- ath_dbg(common, ANY, "WoW enabled in ath9k\n");
+ ath_dbg(common, WOW, "Suspend with WoW triggers: 0x%x\n", triggers);
atomic_inc(&sc->wow_sleep_proc_intr);

+ set_bit(ATH_OP_WOW_ENABLED, &common->op_flags);
fail_wow:
mutex_unlock(&sc->mutex);
return ret;
@@ -327,6 +320,8 @@ int ath9k_resume(struct ieee80211_hw *hw)
ath_restart_work(sc);
ath9k_start_btcoex(sc);

+ clear_bit(ATH_OP_WOW_ENABLED, &common->op_flags);
+
ath9k_ps_restore(sc);
mutex_unlock(&sc->mutex);

--
2.2.2


2015-01-30 13:32:57

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 13/17] ath9k: Register max WOW patterns

From: Sujith Manoharan <[email protected]>

Since the number of patterns that can be configured in
the HW is higher for newer chips, store the chip-specific
value in ath9k_hw_wow.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 7 +++++++
drivers/net/wireless/ath/ath9k/hw.h | 4 +++-
2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8c2f9e2..60aa8d7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2548,6 +2548,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;

+#ifdef CONFIG_ATH9K_WOW
+ if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565_11_OR_LATER(ah))
+ ah->wow.max_patterns = MAX_NUM_PATTERN;
+ else
+ ah->wow.max_patterns = MAX_NUM_PATTERN_LEGACY;
+#endif
+
return 0;
}

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d36210a..e1801c9 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -204,7 +204,8 @@

#define MAX_PATTERN_SIZE 256
#define MAX_PATTERN_MASK_SIZE 32
-#define MAX_NUM_PATTERN 8
+#define MAX_NUM_PATTERN 16
+#define MAX_NUM_PATTERN_LEGACY 8
#define MAX_NUM_USER_PATTERN 6 /* deducting the disassociate and
deauthenticate packets */

@@ -272,6 +273,7 @@ enum ath9k_hw_caps {

struct ath9k_hw_wow {
u32 wow_event_mask;
+ u8 max_patterns;
};

struct ath9k_hw_capabilities {
--
2.2.2


2015-01-30 13:32:42

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 01/17] ath9k: Remove ATH9K_HW_WOW_DEVICE_CAPABLE

From: Sujith Manoharan <[email protected]>

Enabling WOW based on the chip is incorrect since
it needs to be done for specific sub-devices which
have proper platform support.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 3 ---
drivers/net/wireless/ath/ath9k/hw.h | 2 --
drivers/net/wireless/ath/ath9k/wow.c | 4 +---
3 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 82d8f32..8c2f9e2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2544,9 +2544,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->hw_caps |= ATH9K_HW_CAP_RTT;
}

- if (AR_SREV_9462(ah))
- pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
-
if (AR_SREV_9300_20_OR_LATER(ah) &&
ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 450704e..dabc94e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -248,12 +248,10 @@ enum ath9k_hw_caps {
#ifdef CONFIG_ATH9K_PCOEM
ATH9K_HW_CAP_RTT = BIT(14),
ATH9K_HW_CAP_MCI = BIT(15),
- ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(16),
ATH9K_HW_CAP_BT_ANT_DIV = BIT(17),
#else
ATH9K_HW_CAP_RTT = 0,
ATH9K_HW_CAP_MCI = 0,
- ATH9K_HW_WOW_DEVICE_CAPABLE = 0,
ATH9K_HW_CAP_BT_ANT_DIV = 0,
#endif
ATH9K_HW_CAP_DFS = BIT(18),
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 5f30e58..4ffaadd 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -352,9 +352,7 @@ void ath9k_init_wow(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;

- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
- (sc->driver_data & ATH9K_PCI_WOW) &&
- device_can_wakeup(sc->dev))
+ if ((sc->driver_data & ATH9K_PCI_WOW) && device_can_wakeup(sc->dev))
hw->wiphy->wowlan = &ath9k_wowlan_support;

atomic_set(&sc->wow_sleep_proc_intr, -1);
--
2.2.2


2015-01-30 13:32:45

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 04/17] ath9k: Check early for multi-vif/STA conditions

From: Sujith Manoharan <[email protected]>

If multiple interfaces are active or there is no
associated station interface, bail out early and
return 1 so that mac80211 can proceed with the normal
suspend routine.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/wow.c | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 272c05c..1799a1d 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -209,29 +209,21 @@ int ath9k_suspend(struct ieee80211_hw *hw,
goto fail_wow;
}

- ath_cancel_work(sc);
- ath_stop_ani(sc);
-
- /*
- * none of the sta vifs are associated
- * and we are not currently handling multivif
- * cases, for instance we have to seperately
- * configure 'keep alive frame' for each
- * STA.
- */
-
- if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
- ath_dbg(common, WOW, "None of the STA vifs are associated\n");
+ if (sc->cur_chan->nvifs > 1) {
+ ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
ret = 1;
goto fail_wow;
}

- if (sc->cur_chan->nvifs > 1) {
- ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
+ if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
+ ath_dbg(common, WOW, "None of the STA vifs are associated\n");
ret = 1;
goto fail_wow;
}

+ ath_cancel_work(sc);
+ ath_stop_ani(sc);
+
ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);

ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
--
2.2.2


2015-01-30 13:32:47

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 05/17] ath9k: Check multi-channel context for WOW

From: Sujith Manoharan <[email protected]>

If CONFIG_ATH9K_CHANNEL_CONTEXT is enabled, check whether
multiple contexts are active and if so, return 1 without
enabling WOW since we don't support it in this case.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/wow.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 1799a1d..1b005c6 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -215,6 +215,15 @@ int ath9k_suspend(struct ieee80211_hw *hw,
goto fail_wow;
}

+ if (ath9k_is_chanctx_enabled()) {
+ if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) {
+ ath_dbg(common, WOW,
+ "Multi-channel WOW is not supported\n");
+ ret = 1;
+ goto fail_wow;
+ }
+ }
+
if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
ath_dbg(common, WOW, "None of the STA vifs are associated\n");
ret = 1;
--
2.2.2


2015-01-30 13:32:44

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 03/17] ath9k: Remove redundant device_can_wakeup() check

From: Sujith Manoharan <[email protected]>

WOW capability is registered with mac80211 only when
the device has the ability to wakeup, so there is no
need to check in the suspend() routine.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/wow.c | 6 ------
1 file changed, 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 1d5cd88..272c05c 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -212,12 +212,6 @@ int ath9k_suspend(struct ieee80211_hw *hw,
ath_cancel_work(sc);
ath_stop_ani(sc);

- if (!device_can_wakeup(sc->dev)) {
- ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
- ret = 1;
- goto fail_wow;
- }
-
/*
* none of the sta vifs are associated
* and we are not currently handling multivif
--
2.2.2


2015-01-30 13:32:56

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 12/17] ath9k: Add a HW structure for WOW

From: Sujith Manoharan <[email protected]>

This can be used to hold the WOW state in
ath9k_hw.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_wow.c | 10 +++++-----
drivers/net/wireless/ath/ath9k/hw.h | 6 +++++-
2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index 3abc907..bb61417 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -137,7 +137,7 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
* other fields
*/

- ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
+ ah->wow.wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);

if (pattern_count < 4) {
/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
@@ -174,7 +174,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
* register. This mask will clean it up.
*/

- val &= ah->wow_event_mask;
+ val &= ah->wow.wow_event_mask;

if (val) {
if (val & AR_WOW_MAGIC_PAT_FOUND)
@@ -218,7 +218,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
if (ah->is_pciexpress)
ath9k_hw_configpcipowersave(ah, false);

- ah->wow_event_mask = 0;
+ ah->wow.wow_event_mask = 0;

return wow_status;
}
@@ -235,7 +235,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
* are from the 'pattern_enable' in this function and
* 'pattern_count' of ath9k_hw_wow_apply_pattern()
*/
- wow_event_mask = ah->wow_event_mask;
+ wow_event_mask = ah->wow.wow_event_mask;

/*
* Untie Power-on-Reset from the PCI-E-Reset. When we are in
@@ -402,6 +402,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);

ath9k_hw_set_powermode_wow_sleep(ah);
- ah->wow_event_mask = wow_event_mask;
+ ah->wow.wow_event_mask = wow_event_mask;
}
EXPORT_SYMBOL(ath9k_hw_wow_enable);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 22b0422..d36210a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -270,6 +270,10 @@ enum ath9k_hw_caps {
* of those types.
*/

+struct ath9k_hw_wow {
+ u32 wow_event_mask;
+};
+
struct ath9k_hw_capabilities {
u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
u16 rts_aggr_limit;
@@ -928,7 +932,7 @@ struct ath_hw {
u32 ent_mode;

#ifdef CONFIG_ATH9K_WOW
- u32 wow_event_mask;
+ struct ath9k_hw_wow wow;
#endif
bool is_clk_25mhz;
int (*get_mac_revision)(void);
--
2.2.2


2015-01-30 13:32:43

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 02/17] ath9k: Return early for error conditions

From: Sujith Manoharan <[email protected]>

Do not try to cancel work instances and ANI when
the device is not present or WOW triggers are
not configured. Bail out early and use ath_err()
for such error conditions.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/wow.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 4ffaadd..1d5cd88 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -197,21 +197,21 @@ int ath9k_suspend(struct ieee80211_hw *hw,

mutex_lock(&sc->mutex);

- ath_cancel_work(sc);
- ath_stop_ani(sc);
-
if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
- ath_dbg(common, ANY, "Device not present\n");
- ret = -EINVAL;
+ ath_err(common, "Device not present\n");
+ ret = -ENODEV;
goto fail_wow;
}

if (WARN_ON(!wowlan)) {
- ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
+ ath_err(common, "None of the WoW triggers enabled\n");
ret = -EINVAL;
goto fail_wow;
}

+ ath_cancel_work(sc);
+ ath_stop_ani(sc);
+
if (!device_can_wakeup(sc->dev)) {
ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
ret = 1;
--
2.2.2


2015-01-30 13:32:51

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 08/17] ath9k: Remove unused BMISS processing

From: Sujith Manoharan <[email protected]>

The various variables tracking bmiss interrupts
are not really used anywhere except in a debug
message. Remove them since they have no functional
purpose.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 2 --
drivers/net/wireless/ath/ath9k/main.c | 9 ---------
drivers/net/wireless/ath/ath9k/wow.c | 18 ------------------
3 files changed, 29 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 4209d7b..803a7d4 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -1043,8 +1043,6 @@ struct ath_softc {
s16 tx99_power;

#ifdef CONFIG_ATH9K_WOW
- atomic_t wow_got_bmiss_intr;
- atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
u32 wow_intr_before_sleep;
#endif
};
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 62b0bf4..9ede991 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -555,15 +555,6 @@ irqreturn_t ath_isr(int irq, void *dev)
(status & ATH9K_INT_BB_WATCHDOG))
goto chip_reset;

-#ifdef CONFIG_ATH9K_WOW
- if (status & ATH9K_INT_BMISS) {
- if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
- atomic_inc(&sc->wow_got_bmiss_intr);
- atomic_dec(&sc->wow_sleep_proc_intr);
- }
- }
-#endif
-
if (status & ATH9K_INT_SWBA)
tasklet_schedule(&sc->bcon_tasklet);

diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index c0c564d..fa60dbb 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -269,7 +269,6 @@ int ath9k_suspend(struct ieee80211_hw *hw,

ath9k_ps_restore(sc);
ath_dbg(common, WOW, "Suspend with WoW triggers: 0x%x\n", triggers);
- atomic_inc(&sc->wow_sleep_proc_intr);

set_bit(ATH_OP_WOW_ENABLED, &common->op_flags);
fail_wow:
@@ -299,19 +298,6 @@ int ath9k_resume(struct ieee80211_hw *hw)

wow_status = ath9k_hw_wow_wakeup(ah);

- if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
- /*
- * some devices may not pick beacon miss
- * as the reason they woke up so we add
- * that here for that shortcoming.
- */
- wow_status |= AH_WOW_BEACON_MISS;
- atomic_dec(&sc->wow_got_bmiss_intr);
- ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
- }
-
- atomic_dec(&sc->wow_sleep_proc_intr);
-
if (wow_status) {
ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
ath9k_hw_wow_event_to_string(wow_status), wow_status);
@@ -347,10 +333,6 @@ void ath9k_init_wow(struct ieee80211_hw *hw)

if (sc->driver_data & ATH9K_PCI_WOW) {
hw->wiphy->wowlan = &ath9k_wowlan_support;
-
- atomic_set(&sc->wow_sleep_proc_intr, -1);
- atomic_set(&sc->wow_got_bmiss_intr, -1);
-
device_init_wakeup(sc->dev, 1);
}
}
--
2.2.2


2015-01-30 13:32:52

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 09/17] ath9k: Remove ath9k_hw_wow_event_to_string

From: Sujith Manoharan <[email protected]>

Printing the value of the wakeup status is sufficient.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_wow.c | 15 ---------------
drivers/net/wireless/ath/ath9k/hw.h | 5 -----
drivers/net/wireless/ath/ath9k/wow.c | 10 +++-------
3 files changed, 3 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index 81c88dd..3abc907 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -19,21 +19,6 @@
#include "reg.h"
#include "hw-ops.h"

-const char *ath9k_hw_wow_event_to_string(u32 wow_event)
-{
- if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
- return "Magic pattern";
- if (wow_event & AH_WOW_USER_PATTERN_EN)
- return "User pattern";
- if (wow_event & AH_WOW_LINK_CHANGE)
- return "Link change";
- if (wow_event & AH_WOW_BEACON_MISS)
- return "Beacon miss";
-
- return "unknown reason";
-}
-EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
-
static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dabc94e..22b0422 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1146,17 +1146,12 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)


#ifdef CONFIG_ATH9K_WOW
-const char *ath9k_hw_wow_event_to_string(u32 wow_event);
void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
u8 *user_mask, int pattern_count,
int pattern_len);
u32 ath9k_hw_wow_wakeup(struct ath_hw *ah);
void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable);
#else
-static inline const char *ath9k_hw_wow_event_to_string(u32 wow_event)
-{
- return NULL;
-}
static inline void ath9k_hw_wow_apply_pattern(struct ath_hw *ah,
u8 *user_pattern,
u8 *user_mask,
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index fa60dbb..d4cfbc3 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -281,7 +281,7 @@ int ath9k_resume(struct ieee80211_hw *hw)
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- u32 wow_status;
+ u8 status;

mutex_lock(&sc->mutex);

@@ -296,12 +296,8 @@ int ath9k_resume(struct ieee80211_hw *hw)

spin_unlock_bh(&sc->sc_pcu_lock);

- wow_status = ath9k_hw_wow_wakeup(ah);
-
- if (wow_status) {
- ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
- ath9k_hw_wow_event_to_string(wow_status), wow_status);
- }
+ status = ath9k_hw_wow_wakeup(ah);
+ ath_dbg(common, WOW, "Resume with WoW status: 0x%x\n", status);

ath_restart_work(sc);
ath9k_start_btcoex(sc);
--
2.2.2


2015-01-30 13:32:53

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 10/17] ath9k: Add a debugfs file for WOW

From: Sujith Manoharan <[email protected]>

This can be used to force WOW for cards that
are not present in the supported PCI ID list.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/debug.c | 68 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/wow.c | 4 +-
3 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 803a7d4..20216c5 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -1044,6 +1044,7 @@ struct ath_softc {

#ifdef CONFIG_ATH9K_WOW
u32 wow_intr_before_sleep;
+ bool force_wow;
#endif
};

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index dd5d391..50a2e0a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1043,6 +1043,69 @@ static const struct file_operations fops_ackto = {
};
#endif

+#ifdef CONFIG_ATH9K_WOW
+
+static ssize_t read_file_wow(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ unsigned int len = 0, size = 32;
+ ssize_t retval;
+ char *buf;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ len += scnprintf(buf + len, size - len, "WOW: %s\n",
+ sc->force_wow ? "ENABLED" : "DISABLED");
+
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+static ssize_t write_file_wow(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ unsigned long val;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ if (val != 1)
+ return -EINVAL;
+
+ if (!sc->force_wow) {
+ sc->force_wow = true;
+ ath9k_init_wow(sc->hw);
+ }
+
+ return count;
+}
+
+static const struct file_operations fops_wow = {
+ .read = read_file_wow,
+ .write = write_file_wow,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+#endif
+
static ssize_t read_file_tpc(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1313,6 +1376,11 @@ int ath9k_init_debug(struct ath_hw *ah)
&fops_btcoex);
#endif

+#ifdef CONFIG_ATH9K_WOW
+ debugfs_create_file("wow", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_wow);
+#endif
+
#ifdef CONFIG_ATH9K_DYNACK
debugfs_create_file("ack_to", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
sc, &fops_ackto);
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index d4cfbc3..4b3b565 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -327,7 +327,7 @@ void ath9k_init_wow(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;

- if (sc->driver_data & ATH9K_PCI_WOW) {
+ if ((sc->driver_data & ATH9K_PCI_WOW) || sc->force_wow) {
hw->wiphy->wowlan = &ath9k_wowlan_support;
device_init_wakeup(sc->dev, 1);
}
@@ -337,6 +337,6 @@ void ath9k_deinit_wow(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;

- if (sc->driver_data & ATH9K_PCI_WOW)
+ if ((sc->driver_data & ATH9K_PCI_WOW) || sc->force_wow)
device_init_wakeup(sc->dev, 0);
}
--
2.2.2


2015-01-30 13:33:02

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 16/17] ath9k: Cleanup reg_wow.h

From: Sujith Manoharan <[email protected]>

* Remove unnecessary comments.
* Remove unused macros.
* Indent the macros.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/reg_wow.h | 68 +++++++-------------------------
1 file changed, 15 insertions(+), 53 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/reg_wow.h b/drivers/net/wireless/ath/ath9k/reg_wow.h
index 780553a..e6de4a3 100644
--- a/drivers/net/wireless/ath/ath9k/reg_wow.h
+++ b/drivers/net/wireless/ath/ath9k/reg_wow.h
@@ -25,10 +25,8 @@
#define AR_WOW_KEEP_ALIVE 0x827c
#define AR_WOW_KEEP_ALIVE_DELAY 0x8288
#define AR_WOW_PATTERN_MATCH 0x828c
-
#define AR_WOW_LENGTH1 0x8360
#define AR_WOW_LENGTH2 0X8364
-/* register to enable match for less than 256 bytes packets */
#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368

#define AR_SW_WOW_CONTROL 0x20018
@@ -40,7 +38,6 @@
#define AR_CLR_MAC_INTERRUPT 0x20
#define AR_CLR_KA_INTERRUPT 0x40

-/* AR_WOW_PATTERN register values */
#define AR_WOW_BACK_OFF_SHIFT(x) ((x & 0xf) << 28) /* in usecs */
#define AR_WOW_MAC_INTR_EN 0x00040000
#define AR_WOW_MAGIC_EN 0x00010000
@@ -63,69 +60,34 @@
AR_WOW_BEACON_FAIL | \
AR_WOW_KEEP_ALIVE_FAIL))

-/* AR_WOW_COUNT register values */
#define AR_WOW_AIFS_CNT(x) (x & 0xff)
#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8)
#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16)

-/* AR_WOW_BCN_EN register */
#define AR_WOW_BEACON_FAIL_EN 0x00000001
-
-/* AR_WOW_BCN_TIMO rgister */
-#define AR_WOW_BEACON_TIMO 0x40000000 /* valid if BCN_EN is set */
-
-/* AR_WOW_KEEP_ALIVE_TIMO register */
-#define AR_WOW_KEEP_ALIVE_TIMO_VALUE
+#define AR_WOW_BEACON_TIMO 0x40000000
#define AR_WOW_KEEP_ALIVE_NEVER 0xffffffff
-
-/* AR_WOW_KEEP_ALIVE register */
#define AR_WOW_KEEP_ALIVE_AUTO_DIS 0x00000001
#define AR_WOW_KEEP_ALIVE_FAIL_DIS 0x00000002
-
-/* AR_WOW_KEEP_ALIVE_DELAY register */
#define AR_WOW_KEEP_ALIVE_DELAY_VALUE 0x000003e8 /* 1 msec */
-
-
-/*
- * keep it long for beacon workaround - ensure no false alarm
- */
#define AR_WOW_BMISSTHRESHOLD 0x20
-
-/* AR_WOW_PATTERN_MATCH register */
#define AR_WOW_PAT_END_OF_PKT(x) (x & 0xf)
#define AR_WOW_PAT_OFF_MATCH(x) ((x & 0xf) << 8)
-
-/*
- * default values for Wow Configuration for backoff, aifs, slot, keep-alive
- * to be programmed into various registers.
- */
-#define AR_WOW_PAT_BACKOFF 0x00000004 /* AR_WOW_PATTERN_REG */
-#define AR_WOW_CNT_AIFS_CNT 0x00000022 /* AR_WOW_COUNT_REG */
-#define AR_WOW_CNT_SLOT_CNT 0x00000009 /* AR_WOW_COUNT_REG */
-/*
- * Keepalive count applicable for AR9280 2.0 and above.
- */
-#define AR_WOW_CNT_KA_CNT 0x00000008 /* AR_WOW_COUNT register */
-
-/* WoW - Transmit buffer for keep alive frames */
-#define AR_WOW_TRANSMIT_BUFFER 0xe000 /* E000 - EFFC */
-
-#define AR_WOW_TXBUF(i) (AR_WOW_TRANSMIT_BUFFER + ((i) << 2))
-
-#define AR_WOW_KA_DESC_WORD2 0xe000
-
-#define AR_WOW_KA_DATA_WORD0 0xe030
-
-/* WoW Transmit Buffer for patterns */
-#define AR_WOW_TB_PATTERN(i) (0xe100 + (i << 8))
-#define AR_WOW_TB_MASK(i) (0xec00 + (i << 5))
-
-/* Currently Pattern 0-7 are supported - so bit 0-7 are set */
+#define AR_WOW_PAT_BACKOFF 0x00000004
+#define AR_WOW_CNT_AIFS_CNT 0x00000022
+#define AR_WOW_CNT_SLOT_CNT 0x00000009
+#define AR_WOW_CNT_KA_CNT 0x00000008
+
+#define AR_WOW_TRANSMIT_BUFFER 0xe000
+#define AR_WOW_TXBUF(i) (AR_WOW_TRANSMIT_BUFFER + ((i) << 2))
+#define AR_WOW_KA_DESC_WORD2 0xe000
+#define AR_WOW_TB_PATTERN(i) (0xe100 + (i << 8))
+#define AR_WOW_TB_MASK(i) (0xec00 + (i << 5))
#define AR_WOW_PATTERN_SUPPORTED 0xff
#define AR_WOW_LENGTH_MAX 0xff
-#define AR_WOW_LEN1_SHIFT(_i) ((0x3 - ((_i) & 0x3)) << 0x3)
-#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i))
-#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3)
-#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i))
+#define AR_WOW_LEN1_SHIFT(_i) ((0x3 - ((_i) & 0x3)) << 0x3)
+#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i))
+#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3)
+#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i))

#endif /* REG_WOW_H */
--
2.2.2


2015-01-30 13:32:59

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 14/17] ath9k: Move WOW registers to reg_wow.h

From: Sujith Manoharan <[email protected]>

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_wow.c | 1 +
drivers/net/wireless/ath/ath9k/reg.h | 120 ------------------------
drivers/net/wireless/ath/ath9k/reg_wow.h | 136 ++++++++++++++++++++++++++++
3 files changed, 137 insertions(+), 120 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath9k/reg_wow.h

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index bb61417..6681a7b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -17,6 +17,7 @@
#include <linux/export.h>
#include "ath9k.h"
#include "reg.h"
+#include "reg_wow.h"
#include "hw-ops.h"

static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 3c0b180..b1b803d 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -2010,126 +2010,6 @@ enum {

#define AR_WOW_BEACON_TIMO_MAX 0xffffffff

-/*
- * MAC WoW Registers
- */
-
-#define AR_WOW_PATTERN 0x825C
-#define AR_WOW_COUNT 0x8260
-#define AR_WOW_BCN_EN 0x8270
-#define AR_WOW_BCN_TIMO 0x8274
-#define AR_WOW_KEEP_ALIVE_TIMO 0x8278
-#define AR_WOW_KEEP_ALIVE 0x827c
-#define AR_WOW_US_SCALAR 0x8284
-#define AR_WOW_KEEP_ALIVE_DELAY 0x8288
-#define AR_WOW_PATTERN_MATCH 0x828c
-#define AR_WOW_PATTERN_OFF1 0x8290 /* pattern bytes 0 -> 3 */
-#define AR_WOW_PATTERN_OFF2 0x8294 /* pattern bytes 4 -> 7 */
-
-/* for AR9285 or later version of chips */
-#define AR_WOW_EXACT 0x829c
-#define AR_WOW_LENGTH1 0x8360
-#define AR_WOW_LENGTH2 0X8364
-/* register to enable match for less than 256 bytes packets */
-#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368
-
-#define AR_SW_WOW_CONTROL 0x20018
-#define AR_SW_WOW_ENABLE 0x1
-#define AR_SWITCH_TO_REFCLK 0x2
-#define AR_RESET_CONTROL 0x4
-#define AR_RESET_VALUE_MASK 0x8
-#define AR_HW_WOW_DISABLE 0x10
-#define AR_CLR_MAC_INTERRUPT 0x20
-#define AR_CLR_KA_INTERRUPT 0x40
-
-/* AR_WOW_PATTERN register values */
-#define AR_WOW_BACK_OFF_SHIFT(x) ((x & 0xf) << 28) /* in usecs */
-#define AR_WOW_MAC_INTR_EN 0x00040000
-#define AR_WOW_MAGIC_EN 0x00010000
-#define AR_WOW_PATTERN_EN(x) (x & 0xff)
-#define AR_WOW_PAT_FOUND_SHIFT 8
-#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT))
-#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT)
-#define AR_WOW_MAGIC_PAT_FOUND 0x00020000
-#define AR_WOW_MAC_INTR 0x00080000
-#define AR_WOW_KEEP_ALIVE_FAIL 0x00100000
-#define AR_WOW_BEACON_FAIL 0x00200000
-
-#define AR_WOW_STATUS(x) (x & (AR_WOW_PATTERN_FOUND_MASK | \
- AR_WOW_MAGIC_PAT_FOUND | \
- AR_WOW_KEEP_ALIVE_FAIL | \
- AR_WOW_BEACON_FAIL))
-#define AR_WOW_CLEAR_EVENTS(x) (x & ~(AR_WOW_PATTERN_EN(0xff) | \
- AR_WOW_MAGIC_EN | \
- AR_WOW_MAC_INTR_EN | \
- AR_WOW_BEACON_FAIL | \
- AR_WOW_KEEP_ALIVE_FAIL))
-
-/* AR_WOW_COUNT register values */
-#define AR_WOW_AIFS_CNT(x) (x & 0xff)
-#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8)
-#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16)
-
-/* AR_WOW_BCN_EN register */
-#define AR_WOW_BEACON_FAIL_EN 0x00000001
-
-/* AR_WOW_BCN_TIMO rgister */
-#define AR_WOW_BEACON_TIMO 0x40000000 /* valid if BCN_EN is set */
-
-/* AR_WOW_KEEP_ALIVE_TIMO register */
-#define AR_WOW_KEEP_ALIVE_TIMO_VALUE
-#define AR_WOW_KEEP_ALIVE_NEVER 0xffffffff
-
-/* AR_WOW_KEEP_ALIVE register */
-#define AR_WOW_KEEP_ALIVE_AUTO_DIS 0x00000001
-#define AR_WOW_KEEP_ALIVE_FAIL_DIS 0x00000002
-
-/* AR_WOW_KEEP_ALIVE_DELAY register */
-#define AR_WOW_KEEP_ALIVE_DELAY_VALUE 0x000003e8 /* 1 msec */
-
-
-/*
- * keep it long for beacon workaround - ensure no false alarm
- */
-#define AR_WOW_BMISSTHRESHOLD 0x20
-
-/* AR_WOW_PATTERN_MATCH register */
-#define AR_WOW_PAT_END_OF_PKT(x) (x & 0xf)
-#define AR_WOW_PAT_OFF_MATCH(x) ((x & 0xf) << 8)
-
-/*
- * default values for Wow Configuration for backoff, aifs, slot, keep-alive
- * to be programmed into various registers.
- */
-#define AR_WOW_PAT_BACKOFF 0x00000004 /* AR_WOW_PATTERN_REG */
-#define AR_WOW_CNT_AIFS_CNT 0x00000022 /* AR_WOW_COUNT_REG */
-#define AR_WOW_CNT_SLOT_CNT 0x00000009 /* AR_WOW_COUNT_REG */
-/*
- * Keepalive count applicable for AR9280 2.0 and above.
- */
-#define AR_WOW_CNT_KA_CNT 0x00000008 /* AR_WOW_COUNT register */
-
-/* WoW - Transmit buffer for keep alive frames */
-#define AR_WOW_TRANSMIT_BUFFER 0xe000 /* E000 - EFFC */
-
-#define AR_WOW_TXBUF(i) (AR_WOW_TRANSMIT_BUFFER + ((i) << 2))
-
-#define AR_WOW_KA_DESC_WORD2 0xe000
-
-#define AR_WOW_KA_DATA_WORD0 0xe030
-
-/* WoW Transmit Buffer for patterns */
-#define AR_WOW_TB_PATTERN(i) (0xe100 + (i << 8))
-#define AR_WOW_TB_MASK(i) (0xec00 + (i << 5))
-
-/* Currently Pattern 0-7 are supported - so bit 0-7 are set */
-#define AR_WOW_PATTERN_SUPPORTED 0xff
-#define AR_WOW_LENGTH_MAX 0xff
-#define AR_WOW_LEN1_SHIFT(_i) ((0x3 - ((_i) & 0x3)) << 0x3)
-#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i))
-#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3)
-#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i))
-
#define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */
#define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */

diff --git a/drivers/net/wireless/ath/ath9k/reg_wow.h b/drivers/net/wireless/ath/ath9k/reg_wow.h
new file mode 100644
index 0000000..3dbe5db
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/reg_wow.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2015 Qualcomm Atheros Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef REG_WOW_H
+#define REG_WOW_H
+
+#define AR_WOW_PATTERN 0x825C
+#define AR_WOW_COUNT 0x8260
+#define AR_WOW_BCN_EN 0x8270
+#define AR_WOW_BCN_TIMO 0x8274
+#define AR_WOW_KEEP_ALIVE_TIMO 0x8278
+#define AR_WOW_KEEP_ALIVE 0x827c
+#define AR_WOW_US_SCALAR 0x8284
+#define AR_WOW_KEEP_ALIVE_DELAY 0x8288
+#define AR_WOW_PATTERN_MATCH 0x828c
+#define AR_WOW_PATTERN_OFF1 0x8290 /* pattern bytes 0 -> 3 */
+#define AR_WOW_PATTERN_OFF2 0x8294 /* pattern bytes 4 -> 7 */
+
+/* for AR9285 or later version of chips */
+#define AR_WOW_EXACT 0x829c
+#define AR_WOW_LENGTH1 0x8360
+#define AR_WOW_LENGTH2 0X8364
+/* register to enable match for less than 256 bytes packets */
+#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368
+
+#define AR_SW_WOW_CONTROL 0x20018
+#define AR_SW_WOW_ENABLE 0x1
+#define AR_SWITCH_TO_REFCLK 0x2
+#define AR_RESET_CONTROL 0x4
+#define AR_RESET_VALUE_MASK 0x8
+#define AR_HW_WOW_DISABLE 0x10
+#define AR_CLR_MAC_INTERRUPT 0x20
+#define AR_CLR_KA_INTERRUPT 0x40
+
+/* AR_WOW_PATTERN register values */
+#define AR_WOW_BACK_OFF_SHIFT(x) ((x & 0xf) << 28) /* in usecs */
+#define AR_WOW_MAC_INTR_EN 0x00040000
+#define AR_WOW_MAGIC_EN 0x00010000
+#define AR_WOW_PATTERN_EN(x) (x & 0xff)
+#define AR_WOW_PAT_FOUND_SHIFT 8
+#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT))
+#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT)
+#define AR_WOW_MAGIC_PAT_FOUND 0x00020000
+#define AR_WOW_MAC_INTR 0x00080000
+#define AR_WOW_KEEP_ALIVE_FAIL 0x00100000
+#define AR_WOW_BEACON_FAIL 0x00200000
+
+#define AR_WOW_STATUS(x) (x & (AR_WOW_PATTERN_FOUND_MASK | \
+ AR_WOW_MAGIC_PAT_FOUND | \
+ AR_WOW_KEEP_ALIVE_FAIL | \
+ AR_WOW_BEACON_FAIL))
+#define AR_WOW_CLEAR_EVENTS(x) (x & ~(AR_WOW_PATTERN_EN(0xff) | \
+ AR_WOW_MAGIC_EN | \
+ AR_WOW_MAC_INTR_EN | \
+ AR_WOW_BEACON_FAIL | \
+ AR_WOW_KEEP_ALIVE_FAIL))
+
+/* AR_WOW_COUNT register values */
+#define AR_WOW_AIFS_CNT(x) (x & 0xff)
+#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8)
+#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16)
+
+/* AR_WOW_BCN_EN register */
+#define AR_WOW_BEACON_FAIL_EN 0x00000001
+
+/* AR_WOW_BCN_TIMO rgister */
+#define AR_WOW_BEACON_TIMO 0x40000000 /* valid if BCN_EN is set */
+
+/* AR_WOW_KEEP_ALIVE_TIMO register */
+#define AR_WOW_KEEP_ALIVE_TIMO_VALUE
+#define AR_WOW_KEEP_ALIVE_NEVER 0xffffffff
+
+/* AR_WOW_KEEP_ALIVE register */
+#define AR_WOW_KEEP_ALIVE_AUTO_DIS 0x00000001
+#define AR_WOW_KEEP_ALIVE_FAIL_DIS 0x00000002
+
+/* AR_WOW_KEEP_ALIVE_DELAY register */
+#define AR_WOW_KEEP_ALIVE_DELAY_VALUE 0x000003e8 /* 1 msec */
+
+
+/*
+ * keep it long for beacon workaround - ensure no false alarm
+ */
+#define AR_WOW_BMISSTHRESHOLD 0x20
+
+/* AR_WOW_PATTERN_MATCH register */
+#define AR_WOW_PAT_END_OF_PKT(x) (x & 0xf)
+#define AR_WOW_PAT_OFF_MATCH(x) ((x & 0xf) << 8)
+
+/*
+ * default values for Wow Configuration for backoff, aifs, slot, keep-alive
+ * to be programmed into various registers.
+ */
+#define AR_WOW_PAT_BACKOFF 0x00000004 /* AR_WOW_PATTERN_REG */
+#define AR_WOW_CNT_AIFS_CNT 0x00000022 /* AR_WOW_COUNT_REG */
+#define AR_WOW_CNT_SLOT_CNT 0x00000009 /* AR_WOW_COUNT_REG */
+/*
+ * Keepalive count applicable for AR9280 2.0 and above.
+ */
+#define AR_WOW_CNT_KA_CNT 0x00000008 /* AR_WOW_COUNT register */
+
+/* WoW - Transmit buffer for keep alive frames */
+#define AR_WOW_TRANSMIT_BUFFER 0xe000 /* E000 - EFFC */
+
+#define AR_WOW_TXBUF(i) (AR_WOW_TRANSMIT_BUFFER + ((i) << 2))
+
+#define AR_WOW_KA_DESC_WORD2 0xe000
+
+#define AR_WOW_KA_DATA_WORD0 0xe030
+
+/* WoW Transmit Buffer for patterns */
+#define AR_WOW_TB_PATTERN(i) (0xe100 + (i << 8))
+#define AR_WOW_TB_MASK(i) (0xec00 + (i << 5))
+
+/* Currently Pattern 0-7 are supported - so bit 0-7 are set */
+#define AR_WOW_PATTERN_SUPPORTED 0xff
+#define AR_WOW_LENGTH_MAX 0xff
+#define AR_WOW_LEN1_SHIFT(_i) ((0x3 - ((_i) & 0x3)) << 0x3)
+#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i))
+#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3)
+#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i))
+
+#endif /* REG_WOW_H */
--
2.2.2


2015-01-30 13:32:55

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 11/17] ath9k: Simplify user pattern configuration

From: Sujith Manoharan <[email protected]>

There is no need to allocate a new structure and
free it for every user pattern, instead use local
variables.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 6 -----
drivers/net/wireless/ath/ath9k/wow.c | 49 +++++++++-------------------------
2 files changed, 12 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 20216c5..0f8e946 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -830,12 +830,6 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
/* Wake on Wireless LAN */
/************************/

-struct ath9k_wow_pattern {
- u8 pattern_bytes[MAX_PATTERN_SIZE];
- u8 mask_bytes[MAX_PATTERN_SIZE];
- u32 pattern_len;
-};
-
#ifdef CONFIG_ATH9K_WOW
void ath9k_init_wow(struct ieee80211_hw *hw);
void ath9k_deinit_wow(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 4b3b565..da52b1f 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -128,50 +128,25 @@ static void ath9k_wow_add_pattern(struct ath_softc *sc,
struct cfg80211_wowlan *wowlan)
{
struct ath_hw *ah = sc->sc_ah;
- struct ath9k_wow_pattern *wow_pattern = NULL;
struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
+ u8 wow_pattern[MAX_PATTERN_SIZE];
+ u8 wow_mask[MAX_PATTERN_SIZE];
int mask_len;
s8 i = 0;

- if (!wowlan->n_patterns)
- return;
-
- /*
- * Add the new user configured patterns
- */
for (i = 0; i < wowlan->n_patterns; i++) {
-
- wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
-
- if (!wow_pattern)
- return;
-
- /*
- * TODO: convert the generic user space pattern to
- * appropriate chip specific/802.11 pattern.
- */
-
- mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
- memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
- memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
- memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
- patterns[i].pattern_len);
- memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
- wow_pattern->pattern_len = patterns[i].pattern_len;
-
- /*
- * just need to take care of deauth and disssoc pattern,
- * make sure we don't overwrite them.
- */
-
- ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
- wow_pattern->mask_bytes,
+ mask_len = DIV_ROUND_UP(patterns[i].pattern_len, 8);
+ memset(wow_pattern, 0, MAX_PATTERN_SIZE);
+ memset(wow_mask, 0, MAX_PATTERN_SIZE);
+ memcpy(wow_pattern, patterns[i].pattern, patterns[i].pattern_len);
+ memcpy(wow_mask, patterns[i].mask, mask_len);
+
+ ath9k_hw_wow_apply_pattern(ah,
+ wow_pattern,
+ wow_mask,
i + 2,
- wow_pattern->pattern_len);
- kfree(wow_pattern);
-
+ patterns[i].pattern_len);
}
-
}

int ath9k_suspend(struct ieee80211_hw *hw,
--
2.2.2


2015-02-03 13:35:22

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 00/17] ath9k patches

Sujith Manoharan <[email protected]> writes:

> From: Sujith Manoharan <[email protected]>
>
> ath9k patches for -next.
>
> Sujith Manoharan (17):
> ath9k: Remove ATH9K_HW_WOW_DEVICE_CAPABLE
> ath9k: Return early for error conditions
> ath9k: Remove redundant device_can_wakeup() check
> ath9k: Check early for multi-vif/STA conditions
> ath9k: Check multi-channel context for WOW
> ath9k: Fix wow init/deinit
> ath9k: Check WOW triggers properly
> ath9k: Remove unused BMISS processing
> ath9k: Remove ath9k_hw_wow_event_to_string
> ath9k: Add a debugfs file for WOW
> ath9k: Simplify user pattern configuration
> ath9k: Add a HW structure for WOW
> ath9k: Register max WOW patterns
> ath9k: Move WOW registers to reg_wow.h
> ath9k: Remove incorrect register macros
> ath9k: Cleanup reg_wow.h
> ath9k: Fix max pattern check

Thanks, all 17 applied to wireless-drivers-next.git.

--
Kalle Valo