diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2015-02-02 07:51:08 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-02-06 01:39:12 -0500 |
commit | a28815db67a8a27afb4a17d30103e47c6e9e036f (patch) | |
tree | a625f156b9222bac8a8f4b4c83142462c663ef81 /drivers/net/wireless/ath/ath9k | |
parent | 6d4beca3775222884e1ee9d48ef586c438c3dfa1 (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.c | 48 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/reg_wow.h | 34 |
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 | ||
274 | struct ath9k_hw_wow { | 274 | struct 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 */ |