Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sujith Manoharan and committed by
Kalle Valo
a28815db 6d4beca3

+56 -27
+21 -27
drivers/net/wireless/ath/ath9k/ar9003_wow.c
··· 100 100 if (pattern_count >= ah->wow.max_patterns) 101 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 108 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) { 107 109 memcpy(&pattern_val, user_pattern, 4); 108 110 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i), ··· 112 110 user_pattern += 4; 113 111 } 114 112 115 - /* set the registers for mask */ 116 113 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) { 117 114 memcpy(&mask_val, user_mask, 4); 118 115 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val); 119 116 user_mask += 4; 120 117 } 121 118 122 - /* set the pattern length to be matched 123 - * 124 - * AR_WOW_LENGTH1_REG1 125 - * bit 31:24 pattern 0 length 126 - * bit 23:16 pattern 1 length 127 - * bit 15:8 pattern 2 length 128 - * bit 7:0 pattern 3 length 129 - * 130 - * AR_WOW_LENGTH1_REG2 131 - * bit 31:24 pattern 4 length 132 - * bit 23:16 pattern 5 length 133 - * bit 15:8 pattern 6 length 134 - * bit 7:0 pattern 7 length 135 - * 136 - * the below logic writes out the new 137 - * pattern length for the corresponding 138 - * pattern_count, while masking out the 139 - * other fields 140 - */ 141 - 142 - ah->wow.wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 119 + if (pattern_count < MAX_NUM_PATTERN_LEGACY) 120 + ah->wow.wow_event_mask |= 121 + BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 122 + else 123 + ah->wow.wow_event_mask2 |= 124 + BIT((pattern_count - 8) + AR_WOW_PAT_FOUND_SHIFT); 143 125 144 126 if (pattern_count < 4) { 145 - /* Pattern 0-3 uses AR_WOW_LENGTH1 register */ 146 127 set = (pattern_len & AR_WOW_LENGTH_MAX) << 147 128 AR_WOW_LEN1_SHIFT(pattern_count); 148 129 clr = AR_WOW_LENGTH1_MASK(pattern_count); 149 130 REG_RMW(ah, AR_WOW_LENGTH1, set, clr); 150 - } else { 151 - /* Pattern 4-7 uses AR_WOW_LENGTH2 register */ 131 + } else if (pattern_count < 8) { 152 132 set = (pattern_len & AR_WOW_LENGTH_MAX) << 153 133 AR_WOW_LEN2_SHIFT(pattern_count); 154 134 clr = AR_WOW_LENGTH2_MASK(pattern_count); 155 135 REG_RMW(ah, AR_WOW_LENGTH2, set, clr); 136 + } else if (pattern_count < 12) { 137 + set = (pattern_len & AR_WOW_LENGTH_MAX) << 138 + AR_WOW_LEN3_SHIFT(pattern_count); 139 + clr = AR_WOW_LENGTH3_MASK(pattern_count); 140 + REG_RMW(ah, AR_WOW_LENGTH3, set, clr); 141 + } else if (pattern_count < MAX_NUM_PATTERN) { 142 + set = (pattern_len & AR_WOW_LENGTH_MAX) << 143 + AR_WOW_LEN4_SHIFT(pattern_count); 144 + clr = AR_WOW_LENGTH4_MASK(pattern_count); 145 + REG_RMW(ah, AR_WOW_LENGTH4, set, clr); 156 146 } 157 147 158 148 return 0;
+1
drivers/net/wireless/ath/ath9k/hw.h
··· 273 273 274 274 struct ath9k_hw_wow { 275 275 u32 wow_event_mask; 276 + u32 wow_event_mask2; 276 277 u8 max_patterns; 277 278 }; 278 279
+34
drivers/net/wireless/ath/ath9k/reg_wow.h
··· 25 25 #define AR_WOW_KEEP_ALIVE 0x827c 26 26 #define AR_WOW_KEEP_ALIVE_DELAY 0x8288 27 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 54 #define AR_WOW_LENGTH1 0x8360 29 55 #define AR_WOW_LENGTH2 0X8364 56 + #define AR_WOW_LENGTH3 0X8380 57 + #define AR_WOW_LENGTH4 0X8384 58 + 30 59 #define AR_WOW_PATTERN_MATCH_LT_256B 0x8368 60 + #define AR_MAC_PCU_WOW4 0x8370 31 61 32 62 #define AR_SW_WOW_CONTROL 0x20018 33 63 #define AR_SW_WOW_ENABLE 0x1 ··· 119 89 #define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i)) 120 90 #define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3) 121 91 #define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i)) 92 + #define AR_WOW_LEN3_SHIFT(_i) ((0xb - ((_i) & 0xb)) << 0x3) 93 + #define AR_WOW_LENGTH3_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN3_SHIFT(_i)) 94 + #define AR_WOW_LEN4_SHIFT(_i) ((0xf - ((_i) & 0xf)) << 0x3) 95 + #define AR_WOW_LENGTH4_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN4_SHIFT(_i)) 122 96 123 97 #endif /* REG_WOW_H */