Commit 6af75e4d authored by Sujith Manoharan's avatar Sujith Manoharan Committed by Kalle Valo

ath9k: Fix max pattern check

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: default avatarSujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 404033c1
...@@ -89,7 +89,7 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) ...@@ -89,7 +89,7 @@ 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, int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
u8 *user_mask, int pattern_count, u8 *user_mask, int pattern_count,
int pattern_len) int pattern_len)
{ {
...@@ -97,9 +97,8 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, ...@@ -97,9 +97,8 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
u32 pattern_val, mask_val; u32 pattern_val, mask_val;
u32 set, clr; u32 set, clr;
/* FIXME: should check count by querying the hardware capability */ if (pattern_count >= ah->wow.max_patterns)
if (pattern_count >= MAX_NUM_PATTERN) return -ENOSPC;
return;
REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count)); 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, ...@@ -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); REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
} }
return 0;
} }
EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern); EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
......
...@@ -1152,18 +1152,19 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) ...@@ -1152,18 +1152,19 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
#ifdef CONFIG_ATH9K_WOW #ifdef CONFIG_ATH9K_WOW
void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
u8 *user_mask, int pattern_count, u8 *user_mask, int pattern_count,
int pattern_len); int pattern_len);
u32 ath9k_hw_wow_wakeup(struct ath_hw *ah); u32 ath9k_hw_wow_wakeup(struct ath_hw *ah);
void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable); void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable);
#else #else
static inline void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, static inline int ath9k_hw_wow_apply_pattern(struct ath_hw *ah,
u8 *user_pattern, u8 *user_pattern,
u8 *user_mask, u8 *user_mask,
int pattern_count, int pattern_count,
int pattern_len) int pattern_len)
{ {
return 0;
} }
static inline u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) static inline u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
{ {
......
...@@ -40,12 +40,12 @@ static u8 ath9k_wow_map_triggers(struct ath_softc *sc, ...@@ -40,12 +40,12 @@ static u8 ath9k_wow_map_triggers(struct ath_softc *sc,
return wow_triggers; 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_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
int pattern_count = 0; 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_pattern[MAX_PATTERN_SIZE];
u8 dis_deauth_mask[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) ...@@ -110,8 +110,10 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
dis_deauth_mask[1] = 0x03; dis_deauth_mask[1] = 0x03;
dis_deauth_mask[2] = 0xc0; dis_deauth_mask[2] = 0xc0;
ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, ret = ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
pattern_count, byte_cnt); pattern_count, byte_cnt);
if (ret)
goto exit;
pattern_count++; pattern_count++;
/* /*
...@@ -120,18 +122,20 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc) ...@@ -120,18 +122,20 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
*/ */
dis_deauth_pattern[0] = 0xC0; dis_deauth_pattern[0] = 0xC0;
ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, ret = ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
pattern_count, byte_cnt); pattern_count, byte_cnt);
exit:
return ret;
} }
static void ath9k_wow_add_pattern(struct ath_softc *sc, static int ath9k_wow_add_pattern(struct ath_softc *sc,
struct cfg80211_wowlan *wowlan) struct cfg80211_wowlan *wowlan)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct cfg80211_pkt_pattern *patterns = wowlan->patterns; struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
u8 wow_pattern[MAX_PATTERN_SIZE]; u8 wow_pattern[MAX_PATTERN_SIZE];
u8 wow_mask[MAX_PATTERN_SIZE]; u8 wow_mask[MAX_PATTERN_SIZE];
int mask_len; int mask_len, ret = 0;
s8 i = 0; s8 i = 0;
for (i = 0; i < wowlan->n_patterns; i++) { for (i = 0; i < wowlan->n_patterns; i++) {
...@@ -141,12 +145,16 @@ static void ath9k_wow_add_pattern(struct ath_softc *sc, ...@@ -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_pattern, patterns[i].pattern, patterns[i].pattern_len);
memcpy(wow_mask, patterns[i].mask, mask_len); memcpy(wow_mask, patterns[i].mask, mask_len);
ath9k_hw_wow_apply_pattern(ah, ret = ath9k_hw_wow_apply_pattern(ah,
wow_pattern, wow_pattern,
wow_mask, wow_mask,
i + 2, i + 2,
patterns[i].pattern_len); patterns[i].pattern_len);
if (ret)
break;
} }
return ret;
} }
int ath9k_suspend(struct ieee80211_hw *hw, int ath9k_suspend(struct ieee80211_hw *hw,
...@@ -213,10 +221,21 @@ 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 * Enable wake up on recieving disassoc/deauth
* frame by default. * 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) if (triggers & AH_WOW_USER_PATTERN_EN) {
ath9k_wow_add_pattern(sc, wowlan); 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); spin_lock_bh(&sc->sc_pcu_lock);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment