xref: /freebsd/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_keycache.c (revision 7661de35d15f582ab33e3bd6b8d909601557e436)
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include "opt_ah.h"
18 
19 #include "ah.h"
20 #include "ah_internal.h"
21 
22 #include "ar9300/ar9300.h"
23 #include "ar9300/ar9300reg.h"
24 
25 /*
26  * Note: The key cache hardware requires that each double-word
27  * pair be written in even/odd order (since the destination is
28  * a 64-bit register).  Don't reorder the writes in this code
29  * w/o considering this!
30  */
31 #define KEY_XOR         0xaa
32 
33 #define IS_MIC_ENABLED(ah) \
34     (AH9300(ah)->ah_sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
35 
36 /*
37  * This isn't the keytable type; this is actually something separate
38  * for the TX descriptor.
39  */
40 static const int keyType[] = {
41 	1,	/* HAL_CIPHER_WEP */
42 	0,	/* HAL_CIPHER_AES_OCB */
43 	2,	/* HAL_CIPHER_AES_CCM */
44 	0,	/* HAL_CIPHER_CKIP */
45 	3,	/* HAL_CIPHER_TKIP */
46 	0	/* HAL_CIPHER_CLR */
47 };
48 
49 /*
50  * Return the size of the hardware key cache.
51  */
52 u_int32_t
53 ar9300_get_key_cache_size(struct ath_hal *ah)
54 {
55     return AH_PRIVATE(ah)->ah_caps.halKeyCacheSize;
56 }
57 
58 /*
59  * Return AH_TRUE if the specific key cache entry is valid.
60  */
61 HAL_BOOL
62 ar9300_is_key_cache_entry_valid(struct ath_hal *ah, u_int16_t entry)
63 {
64     if (entry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
65         u_int32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry));
66         if (val & AR_KEYTABLE_VALID) {
67             return AH_TRUE;
68         }
69     }
70     return AH_FALSE;
71 }
72 
73 /*
74  * Clear the specified key cache entry and any associated MIC entry.
75  */
76 HAL_BOOL
77 ar9300_reset_key_cache_entry(struct ath_hal *ah, u_int16_t entry)
78 {
79     u_int32_t key_type;
80     struct ath_hal_9300 *ahp = AH9300(ah);
81 
82     if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
83         HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
84             "%s: entry %u out of range\n", __func__, entry);
85         return AH_FALSE;
86     }
87 
88     ahp->ah_keytype[entry] = keyType[HAL_CIPHER_CLR];
89 
90     key_type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry));
91 
92     /* XXX why not clear key type/valid bit first? */
93     OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
94     OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
95     OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
96     OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
97     OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
98     OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
99     OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
100     OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
101     if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
102         u_int16_t micentry = entry + 64;  /* MIC goes at slot+64 */
103 
104         HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize);
105         OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
106         OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
107         OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
108         OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
109         /* NB: key type and MAC are known to be ok */
110     }
111 
112     if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) {
113         return AH_TRUE;
114     }
115 
116     if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL)
117         == HAL_OK) {
118         if (key_type == AR_KEYTABLE_TYPE_TKIP    ||
119             key_type == AR_KEYTABLE_TYPE_40      ||
120             key_type == AR_KEYTABLE_TYPE_104     ||
121             key_type == AR_KEYTABLE_TYPE_128) {
122             /* SW WAR for Bug 31602 */
123             if (--ahp->ah_rifs_sec_cnt == 0) {
124                 HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
125                     "%s: Count = %d, enabling RIFS\n",
126                     __func__, ahp->ah_rifs_sec_cnt);
127                 ar9300_set_rifs_delay(ah, AH_TRUE);
128             }
129         }
130     }
131     return AH_TRUE;
132 }
133 
134 /*
135  * Sets the mac part of the specified key cache entry (and any
136  * associated MIC entry) and mark them valid.
137  */
138 HAL_BOOL
139 ar9300_set_key_cache_entry_mac(
140     struct ath_hal *ah,
141     u_int16_t entry,
142     const u_int8_t *mac)
143 {
144     u_int32_t mac_hi, mac_lo;
145     u_int32_t unicast_addr = AR_KEYTABLE_VALID;
146 
147     if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
148         HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
149             "%s: entry %u out of range\n", __func__, entry);
150         return AH_FALSE;
151     }
152     /*
153      * Set MAC address -- shifted right by 1.  mac_lo is
154      * the 4 MSBs, and mac_hi is the 2 LSBs.
155      */
156     if (mac != AH_NULL) {
157         /*
158          *  If upper layers have requested mcast MACaddr lookup, then
159          *  signify this to the hw by setting the (poorly named) valid_bit
160          *  to 0.  Yes, really 0. The hardware specs, pcu_registers.txt, is
161          *  has incorrectly named valid_bit. It should be called "Unicast".
162          *  When the Key Cache entry is to decrypt Unicast frames, this bit
163          *  should be '1'; for multicast and broadcast frames, this bit is '0'.
164          */
165         if (mac[0] & 0x01) {
166             unicast_addr = 0;    /* Not an unicast address */
167         }
168 
169         mac_hi = (mac[5] << 8)  |  mac[4];
170         mac_lo = (mac[3] << 24) | (mac[2] << 16)
171               | (mac[1] << 8)  |  mac[0];
172         mac_lo >>= 1; /* Note that the bit 0 is shifted out. This bit is used to
173                       * indicate that this is a multicast key cache. */
174         mac_lo |= (mac_hi & 1) << 31; /* carry */
175         mac_hi >>= 1;
176     } else {
177         mac_lo = mac_hi = 0;
178     }
179     OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), mac_lo);
180     OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), mac_hi | unicast_addr);
181     return AH_TRUE;
182 }
183 
184 /*
185  * Sets the contents of the specified key cache entry
186  * and any associated MIC entry.
187  */
188 HAL_BOOL
189 ar9300_set_key_cache_entry(struct ath_hal *ah, u_int16_t entry,
190                        const HAL_KEYVAL *k, const u_int8_t *mac,
191                        int xor_key)
192 {
193     const HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
194     u_int32_t key0, key1, key2, key3, key4;
195     u_int32_t key_type;
196     u_int32_t xor_mask = xor_key ?
197         (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0;
198     struct ath_hal_9300 *ahp = AH9300(ah);
199     u_int32_t pwrmgt, pwrmgt_mic, uapsd_cfg, psta = 0;
200     int is_proxysta_key = k->kv_type & HAL_KEY_PROXY_STA_MASK;
201 
202 
203     if (entry >= p_cap->halKeyCacheSize) {
204         HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
205             "%s: entry %u out of range\n", __func__, entry);
206         return AH_FALSE;
207     }
208     HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n",
209         __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
210         is_proxysta_key);
211 
212     switch (k->kv_type & AH_KEYTYPE_MASK) {
213     case HAL_CIPHER_AES_OCB:
214         key_type = AR_KEYTABLE_TYPE_AES;
215         break;
216     case HAL_CIPHER_AES_CCM:
217         if (!p_cap->halCipherAesCcmSupport) {
218             HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: AES-CCM not supported by "
219                 "mac rev 0x%x\n",
220                 __func__, AH_PRIVATE(ah)->ah_macRev);
221             return AH_FALSE;
222         }
223         key_type = AR_KEYTABLE_TYPE_CCM;
224         break;
225     case HAL_CIPHER_TKIP:
226         key_type = AR_KEYTABLE_TYPE_TKIP;
227         if (IS_MIC_ENABLED(ah) && entry + 64 >= p_cap->halKeyCacheSize) {
228             HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
229                 "%s: entry %u inappropriate for TKIP\n",
230                 __func__, entry);
231             return AH_FALSE;
232         }
233         break;
234     case HAL_CIPHER_WEP:
235         if (k->kv_len < 40 / NBBY) {
236             HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: WEP key length %u too small\n",
237                 __func__, k->kv_len);
238             return AH_FALSE;
239         }
240         if (k->kv_len <= 40 / NBBY) {
241             key_type = AR_KEYTABLE_TYPE_40;
242         } else if (k->kv_len <= 104 / NBBY) {
243             key_type = AR_KEYTABLE_TYPE_104;
244         } else {
245             key_type = AR_KEYTABLE_TYPE_128;
246         }
247         break;
248     case HAL_CIPHER_CLR:
249         key_type = AR_KEYTABLE_TYPE_CLR;
250         break;
251     default:
252         HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: cipher %u not supported\n",
253             __func__, k->kv_type);
254         return AH_FALSE;
255     }
256 
257     key0 =  LE_READ_4(k->kv_val +  0) ^ xor_mask;
258     key1 = (LE_READ_2(k->kv_val +  4) ^ xor_mask) & 0xffff;
259     key2 =  LE_READ_4(k->kv_val +  6) ^ xor_mask;
260     key3 = (LE_READ_2(k->kv_val + 10) ^ xor_mask) & 0xffff;
261     key4 =  LE_READ_4(k->kv_val + 12) ^ xor_mask;
262     if (k->kv_len <= 104 / NBBY) {
263         key4 &= 0xff;
264     }
265 
266     /* Extract the UAPSD AC bits and shift it appropriately */
267     uapsd_cfg = k->kv_apsd;
268     uapsd_cfg = (u_int32_t) SM(uapsd_cfg, AR_KEYTABLE_UAPSD);
269 
270     /* Need to preserve the power management bit used by MAC */
271     pwrmgt = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEYTABLE_PWRMGT;
272 
273     if (is_proxysta_key) {
274         u_int8_t bcast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
275         if (!mac || OS_MEMCMP(mac, bcast_mac, 6)) {
276             psta = AR_KEYTABLE_DIR_ACK_BIT;
277         }
278     }
279     /*
280      * Note: key cache hardware requires that each double-word
281      * pair be written in even/odd order (since the destination is
282      * a 64-bit register).  Don't reorder these writes w/o
283      * considering this!
284      */
285     if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
286         u_int16_t micentry = entry + 64;  /* MIC goes at slot+64 */
287 
288         /* Need to preserve the power management bit used by MAC */
289         pwrmgt_mic =
290             OS_REG_READ(ah, AR_KEYTABLE_TYPE(micentry)) & AR_KEYTABLE_PWRMGT;
291 
292         /*
293          * Invalidate the encrypt/decrypt key until the MIC
294          * key is installed so pending rx frames will fail
295          * with decrypt errors rather than a MIC error.
296          */
297         OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
298         OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
299         OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
300         OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
301         OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
302         OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry),
303             key_type | pwrmgt | uapsd_cfg | psta);
304         ar9300_set_key_cache_entry_mac(ah, entry, mac);
305 
306         /*
307          * since the AR_MISC_MODE register was written with the contents of
308          * ah_misc_mode (if any) in ar9300_attach, just check ah_misc_mode and
309          * save a pci read per key set.
310          */
311         if (ahp->ah_misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
312             u_int32_t mic0, mic1, mic2, mic3, mic4;
313             /*
314              * both RX and TX mic values can be combined into
315              * one cache slot entry.
316              * 8*N + 800         31:0    RX Michael key 0
317              * 8*N + 804         15:0    TX Michael key 0 [31:16]
318              * 8*N + 808         31:0    RX Michael key 1
319              * 8*N + 80C         15:0    TX Michael key 0 [15:0]
320              * 8*N + 810         31:0    TX Michael key 1
321              * 8*N + 814         15:0    reserved
322              * 8*N + 818         31:0    reserved
323              * 8*N + 81C         14:0    reserved
324              *                   15      key valid == 0
325              */
326             /* RX mic */
327             mic0 = LE_READ_4(k->kv_mic + 0);
328             mic2 = LE_READ_4(k->kv_mic + 4);
329             /* TX mic */
330             mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff;
331             mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff;
332             mic4 = LE_READ_4(k->kv_txmic + 4);
333             OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
334             OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
335             OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
336             OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
337             OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
338             OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
339                          AR_KEYTABLE_TYPE_CLR | pwrmgt_mic | uapsd_cfg);
340 
341         } else {
342             u_int32_t mic0, mic2;
343 
344             mic0 = LE_READ_4(k->kv_mic + 0);
345             mic2 = LE_READ_4(k->kv_mic + 4);
346             OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
347             OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
348             OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
349             OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
350             OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
351             OS_REG_WRITE(ah,
352                 AR_KEYTABLE_TYPE(micentry | pwrmgt_mic | uapsd_cfg),
353                 AR_KEYTABLE_TYPE_CLR);
354         }
355         /* NB: MIC key is not marked valid and has no MAC address */
356         OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
357         OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
358 
359         /* correct intentionally corrupted key */
360         OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
361         OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
362     } else {
363         OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
364         OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
365         OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
366         OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
367         OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
368         OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry),
369             key_type | pwrmgt | uapsd_cfg | psta);
370 
371         /*
372         ath_hal_printf(ah, "%s[%d] mac %s proxy %d\n",
373             __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
374             is_proxysta_key);
375          */
376 
377         ar9300_set_key_cache_entry_mac(ah, entry, mac);
378     }
379 
380     ahp->ah_keytype[entry] = keyType[k->kv_type];
381     HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: entry=%d, k->kv_type=%d,"
382       "keyType=%d\n", __func__, entry, k->kv_type, keyType[k->kv_type]);
383 
384 
385     if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) {
386         return AH_TRUE;
387     }
388 
389     if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL)
390         == HAL_OK) {
391         if (key_type == AR_KEYTABLE_TYPE_TKIP    ||
392             key_type == AR_KEYTABLE_TYPE_40      ||
393             key_type == AR_KEYTABLE_TYPE_104     ||
394             key_type == AR_KEYTABLE_TYPE_128) {
395             /* SW WAR for Bug 31602 */
396             ahp->ah_rifs_sec_cnt++;
397             HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
398                 "%s: Count = %d, disabling RIFS\n",
399                 __func__, ahp->ah_rifs_sec_cnt);
400             ar9300_set_rifs_delay(ah, AH_FALSE);
401         }
402     }
403     HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n",
404         __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
405         is_proxysta_key);
406 
407     return AH_TRUE;
408 }
409 
410 /*
411  * Enable the Keysearch for every subframe of an aggregate
412  */
413 void
414 ar9300_enable_keysearch_always(struct ath_hal *ah, int enable)
415 {
416     u_int32_t val;
417 
418     if (!ah) {
419         return;
420     }
421     val = OS_REG_READ(ah, AR_PCU_MISC);
422     if (enable) {
423         val |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
424     } else {
425         val &= ~AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
426     }
427     OS_REG_WRITE(ah, AR_PCU_MISC, val);
428 }
429 void ar9300_dump_keycache(struct ath_hal *ah, int n, u_int32_t *entry)
430 {
431 #define AH_KEY_REG_SIZE	8
432     int i;
433 
434     for (i = 0; i < AH_KEY_REG_SIZE; i++) {
435         entry[i] = OS_REG_READ(ah, AR_KEYTABLE_KEY0(n) + i * 4);
436     }
437 #undef AH_KEY_REG_SIZE
438 }
439