aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2015-02-02 07:51:08 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-02-06 01:39:12 -0500
commita28815db67a8a27afb4a17d30103e47c6e9e036f (patch)
treea625f156b9222bac8a8f4b4c83142462c663ef81 /drivers/net/wireless/ath/ath9k
parent6d4beca3775222884e1ee9d48ef586c438c3dfa1 (diff)
ath9k: Add support for more WOW patterns
Newer chips like WB222, WB335 support more than 8 user-configurable patterns. This patch adds support for it by setting up the correct HW registers. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_wow.c48
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/reg_wow.h34
3 files changed, 56 insertions, 27 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index d2a4f6f49045..4b53d0b4d113 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -100,9 +100,11 @@ int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
100 if (pattern_count >= ah->wow.max_patterns) 100 if (pattern_count >= ah->wow.max_patterns)
101 return -ENOSPC; 101 return -ENOSPC;
102 102
103 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count)); 103 if (pattern_count < MAX_NUM_PATTERN_LEGACY)
104 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
105 else
106 REG_SET_BIT(ah, AR_MAC_PCU_WOW4, BIT(pattern_count - 8));
104 107
105 /* set the registers for pattern */
106 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) { 108 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
107 memcpy(&pattern_val, user_pattern, 4); 109 memcpy(&pattern_val, user_pattern, 4);
108 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i), 110 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
@@ -110,47 +112,39 @@ int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
110 user_pattern += 4; 112 user_pattern += 4;
111 } 113 }
112 114
113 /* set the registers for mask */
114 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) { 115 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
115 memcpy(&mask_val, user_mask, 4); 116 memcpy(&mask_val, user_mask, 4);
116 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val); 117 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
117 user_mask += 4; 118 user_mask += 4;
118 } 119 }
119 120
120 /* set the pattern length to be matched 121 if (pattern_count < MAX_NUM_PATTERN_LEGACY)
121 * 122 ah->wow.wow_event_mask |=
122 * AR_WOW_LENGTH1_REG1 123 BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
123 * bit 31:24 pattern 0 length 124 else
124 * bit 23:16 pattern 1 length 125 ah->wow.wow_event_mask2 |=
125 * bit 15:8 pattern 2 length 126 BIT((pattern_count - 8) + AR_WOW_PAT_FOUND_SHIFT);
126 * bit 7:0 pattern 3 length
127 *
128 * AR_WOW_LENGTH1_REG2
129 * bit 31:24 pattern 4 length
130 * bit 23:16 pattern 5 length
131 * bit 15:8 pattern 6 length
132 * bit 7:0 pattern 7 length
133 *
134 * the below logic writes out the new
135 * pattern length for the corresponding
136 * pattern_count, while masking out the
137 * other fields
138 */
139
140 ah->wow.wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
141 127
142 if (pattern_count < 4) { 128 if (pattern_count < 4) {
143 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
144 set = (pattern_len & AR_WOW_LENGTH_MAX) << 129 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
145 AR_WOW_LEN1_SHIFT(pattern_count); 130 AR_WOW_LEN1_SHIFT(pattern_count);
146 clr = AR_WOW_LENGTH1_MASK(pattern_count); 131 clr = AR_WOW_LENGTH1_MASK(pattern_count);
147 REG_RMW(ah, AR_WOW_LENGTH1, set, clr); 132 REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
148 } else { 133 } else if (pattern_count < 8) {
149 /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
150 set = (pattern_len & AR_WOW_LENGTH_MAX) << 134 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
151 AR_WOW_LEN2_SHIFT(pattern_count); 135 AR_WOW_LEN2_SHIFT(pattern_count);
152 clr = AR_WOW_LENGTH2_MASK(pattern_count); 136 clr = AR_WOW_LENGTH2_MASK(pattern_count);
153 REG_RMW(ah, AR_WOW_LENGTH2, set, clr); 137 REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
138 } else if (pattern_count < 12) {
139 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
140 AR_WOW_LEN3_SHIFT(pattern_count);
141 clr = AR_WOW_LENGTH3_MASK(pattern_count);
142 REG_RMW(ah, AR_WOW_LENGTH3, set, clr);
143 } else if (pattern_count < MAX_NUM_PATTERN) {
144 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
145 AR_WOW_LEN4_SHIFT(pattern_count);
146 clr = AR_WOW_LENGTH4_MASK(pattern_count);
147 REG_RMW(ah, AR_WOW_LENGTH4, set, clr);
154 } 148 }
155 149
156 return 0; 150 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f51a28f0740e..c8b3d8f608a2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -273,6 +273,7 @@ enum ath9k_hw_caps {
273 273
274struct ath9k_hw_wow { 274struct ath9k_hw_wow {
275 u32 wow_event_mask; 275 u32 wow_event_mask;
276 u32 wow_event_mask2;
276 u8 max_patterns; 277 u8 max_patterns;
277}; 278};
278 279
diff --git a/drivers/net/wireless/ath/ath9k/reg_wow.h b/drivers/net/wireless/ath/ath9k/reg_wow.h
index e6de4a375182..83f27f9be7aa 100644
--- a/drivers/net/wireless/ath/ath9k/reg_wow.h
+++ b/drivers/net/wireless/ath/ath9k/reg_wow.h
@@ -25,9 +25,39 @@
25#define AR_WOW_KEEP_ALIVE 0x827c 25#define AR_WOW_KEEP_ALIVE 0x827c
26#define AR_WOW_KEEP_ALIVE_DELAY 0x8288 26#define AR_WOW_KEEP_ALIVE_DELAY 0x8288
27#define AR_WOW_PATTERN_MATCH 0x828c 27#define AR_WOW_PATTERN_MATCH 0x828c
28
29/*
30 * AR_WOW_LENGTH1
31 * bit 31:24 pattern 0 length
32 * bit 23:16 pattern 1 length
33 * bit 15:8 pattern 2 length
34 * bit 7:0 pattern 3 length
35 *
36 * AR_WOW_LENGTH2
37 * bit 31:24 pattern 4 length
38 * bit 23:16 pattern 5 length
39 * bit 15:8 pattern 6 length
40 * bit 7:0 pattern 7 length
41 *
42 * AR_WOW_LENGTH3
43 * bit 31:24 pattern 8 length
44 * bit 23:16 pattern 9 length
45 * bit 15:8 pattern 10 length
46 * bit 7:0 pattern 11 length
47 *
48 * AR_WOW_LENGTH4
49 * bit 31:24 pattern 12 length
50 * bit 23:16 pattern 13 length
51 * bit 15:8 pattern 14 length
52 * bit 7:0 pattern 15 length
53 */
28#define AR_WOW_LENGTH1 0x8360 54#define AR_WOW_LENGTH1 0x8360
29#define AR_WOW_LENGTH2 0X8364 55#define AR_WOW_LENGTH2 0X8364
56#define AR_WOW_LENGTH3 0X8380
57#define AR_WOW_LENGTH4 0X8384
58
30#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368 59#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368
60#define AR_MAC_PCU_WOW4 0x8370
31 61
32#define AR_SW_WOW_CONTROL 0x20018 62#define AR_SW_WOW_CONTROL 0x20018
33#define AR_SW_WOW_ENABLE 0x1 63#define AR_SW_WOW_ENABLE 0x1
@@ -89,5 +119,9 @@
89#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i)) 119#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i))
90#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3) 120#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3)
91#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i)) 121#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i))
122#define AR_WOW_LEN3_SHIFT(_i) ((0xb - ((_i) & 0xb)) << 0x3)
123#define AR_WOW_LENGTH3_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN3_SHIFT(_i))
124#define AR_WOW_LEN4_SHIFT(_i) ((0xf - ((_i) & 0xf)) << 0x3)
125#define AR_WOW_LENGTH4_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN4_SHIFT(_i))
92 126
93#endif /* REG_WOW_H */ 127#endif /* REG_WOW_H */