ath9k: Fix max pattern check
authorSujith Manoharan <c_manoha@qca.qualcomm.com>
Fri, 30 Jan 2015 13:35:37 +0000 (19:05 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 3 Feb 2015 13:31:14 +0000 (15:31 +0200)
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 <c_manoha@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath9k/ar9003_wow.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/wow.c

index 6681a7b03cd0e85f4905801868d35b4e8c222716..d2a4f6f490457b436e654c312276b23b71014a78 100644 (file)
@@ -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);
 
index e1801c91d53857a1ea2ddc40c2eef0dbb9926cf8..f51a28f0740ebfb839a3ba497ad01c84b6c7c206 100644 (file)
@@ -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)
 {
index da52b1ffff24391faaae8d3793b134b2c7b066b9..5092939876f60128a0a57ada36a3861799d6d445 100644 (file)
@@ -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);
        /*