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 */
40static 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 */
52u_int32_t
53ar9300_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 */
61HAL_BOOL
62ar9300_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 */
76HAL_BOOL
77ar9300_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 */
138HAL_BOOL
139ar9300_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 */
188HAL_BOOL
189ar9300_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 */
413void
414ar9300_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}
429void 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
440#if ATH_SUPPORT_KEYPLUMB_WAR
441/*
442 * Check the contents of the specified key cache entry
443 * and any associated MIC entry.
444 */
445    HAL_BOOL
446ar9300_check_key_cache_entry(struct ath_hal *ah, u_int16_t entry,
447        const HAL_KEYVAL *k, int xorKey)
448{
449    const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
450    u_int32_t key0, key1, key2, key3, key4;
451    u_int32_t keyType;
452    u_int32_t xorMask = xorKey ?
453        (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0;
454    struct ath_hal_9300 *ahp = AH9300(ah);
455
456
457    if (entry >= pCap->hal_key_cache_size) {
458        HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
459                "%s: entry %u out of range\n", __func__, entry);
460        return AH_FALSE;
461    }
462    switch (k->kv_type) {
463        case HAL_CIPHER_AES_OCB:
464            keyType = AR_KEYTABLE_TYPE_AES;
465            break;
466        case HAL_CIPHER_AES_CCM:
467            if (!pCap->hal_cipher_aes_ccm_support) {
468                HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: AES-CCM not supported by "
469                        "mac rev 0x%x\n",
470                        __func__, AH_PRIVATE(ah)->ah_macRev);
471                return AH_FALSE;
472            }
473            keyType = AR_KEYTABLE_TYPE_CCM;
474            break;
475        case HAL_CIPHER_TKIP:
476            keyType = AR_KEYTABLE_TYPE_TKIP;
477            if (IS_MIC_ENABLED(ah) && entry + 64 >= pCap->hal_key_cache_size) {
478                HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
479                        "%s: entry %u inappropriate for TKIP\n",
480                        __func__, entry);
481                return AH_FALSE;
482            }
483            break;
484        case HAL_CIPHER_WEP:
485            if (k->kv_len < 40 / NBBY) {
486                HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: WEP key length %u too small\n",
487                        __func__, k->kv_len);
488                return AH_FALSE;
489            }
490            if (k->kv_len <= 40 / NBBY) {
491                keyType = AR_KEYTABLE_TYPE_40;
492            } else if (k->kv_len <= 104 / NBBY) {
493                keyType = AR_KEYTABLE_TYPE_104;
494            } else {
495                keyType = AR_KEYTABLE_TYPE_128;
496            }
497            break;
498        case HAL_CIPHER_CLR:
499            keyType = AR_KEYTABLE_TYPE_CLR;
500            return AH_TRUE;
501        default:
502            HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: cipher %u not supported\n",
503                    __func__, k->kv_type);
504            return AH_TRUE;
505    }
506
507    key0 =  LE_READ_4(k->kv_val +  0) ^ xorMask;
508    key1 = (LE_READ_2(k->kv_val +  4) ^ xorMask) & 0xffff;
509    key2 =  LE_READ_4(k->kv_val +  6) ^ xorMask;
510    key3 = (LE_READ_2(k->kv_val + 10) ^ xorMask) & 0xffff;
511    key4 =  LE_READ_4(k->kv_val + 12) ^ xorMask;
512    if (k->kv_len <= 104 / NBBY) {
513        key4 &= 0xff;
514    }
515
516    /*
517     * Note: key cache hardware requires that each double-word
518     * pair be written in even/odd order (since the destination is
519     * a 64-bit register).  Don't reorder these writes w/o
520     * considering this!
521     */
522    if (keyType == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
523        u_int16_t micentry = entry + 64;  /* MIC goes at slot+64 */
524
525
526        /*
527         * Invalidate the encrypt/decrypt key until the MIC
528         * key is installed so pending rx frames will fail
529         * with decrypt errors rather than a MIC error.
530         */
531        if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)) == key0) &&
532                (OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)) == key1) &&
533                (OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)) == key2) &&
534                (OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)) == key3) &&
535                (OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)) == key4) &&
536                ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEY_TYPE) == (keyType & AR_KEY_TYPE)))
537        {
538
539            /*
540             * since the AR_MISC_MODE register was written with the contents of
541             * ah_miscMode (if any) in ar9300Attach, just check ah_miscMode and
542             * save a pci read per key set.
543             */
544            if (ahp->ah_misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
545                u_int32_t mic0,mic1,mic2,mic3,mic4;
546                /*
547                 * both RX and TX mic values can be combined into
548                 * one cache slot entry.
549                 * 8*N + 800         31:0    RX Michael key 0
550                 * 8*N + 804         15:0    TX Michael key 0 [31:16]
551                 * 8*N + 808         31:0    RX Michael key 1
552                 * 8*N + 80C         15:0    TX Michael key 0 [15:0]
553                 * 8*N + 810         31:0    TX Michael key 1
554                 * 8*N + 814         15:0    reserved
555                 * 8*N + 818         31:0    reserved
556                 * 8*N + 81C         14:0    reserved
557                 *                   15      key valid == 0
558                 */
559                /* RX mic */
560                mic0 = LE_READ_4(k->kv_mic + 0);
561                mic2 = LE_READ_4(k->kv_mic + 4);
562                /* TX mic */
563                mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff;
564                mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff;
565                mic4 = LE_READ_4(k->kv_txmic + 4);
566                if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(micentry)) == mic0) &&
567                        (OS_REG_READ(ah, AR_KEYTABLE_KEY1(micentry)) == mic1) &&
568                        (OS_REG_READ(ah, AR_KEYTABLE_KEY2(micentry)) == mic2) &&
569                        (OS_REG_READ(ah, AR_KEYTABLE_KEY3(micentry)) == mic3) &&
570                        (OS_REG_READ(ah, AR_KEYTABLE_KEY4(micentry)) == mic4) &&
571                        ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(micentry)) & AR_KEY_TYPE) == (AR_KEYTABLE_TYPE_CLR & AR_KEY_TYPE))) {
572                    return AH_TRUE;
573                }
574
575            } else {
576                return AH_TRUE;
577            }
578        }
579    } else {
580        if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)) == key0) &&
581                (OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)) == key1) &&
582                (OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)) == key2) &&
583                (OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)) == key3) &&
584                (OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)) == key4) &&
585                ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEY_TYPE) == (keyType & AR_KEY_TYPE))) {
586            return AH_TRUE;
587        }
588    }
589    return AH_FALSE;
590}
591#endif
592