ar9300_keycache.c revision 250003
1250003Sadrian/*
2250003Sadrian * Copyright (c) 2013 Qualcomm Atheros, Inc.
3250003Sadrian *
4250003Sadrian * Permission to use, copy, modify, and/or distribute this software for any
5250003Sadrian * purpose with or without fee is hereby granted, provided that the above
6250003Sadrian * copyright notice and this permission notice appear in all copies.
7250003Sadrian *
8250003Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9250003Sadrian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10250003Sadrian * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11250003Sadrian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12250003Sadrian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13250003Sadrian * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14250003Sadrian * PERFORMANCE OF THIS SOFTWARE.
15250003Sadrian */
16250003Sadrian
17250003Sadrian#include "opt_ah.h"
18250003Sadrian
19250003Sadrian#ifdef AH_SUPPORT_AR9300
20250003Sadrian
21250003Sadrian#include "ah.h"
22250003Sadrian#include "ah_internal.h"
23250003Sadrian
24250003Sadrian#include "ar9300/ar9300.h"
25250003Sadrian#include "ar9300/ar9300reg.h"
26250003Sadrian
27250003Sadrian/*
28250003Sadrian * Note: The key cache hardware requires that each double-word
29250003Sadrian * pair be written in even/odd order (since the destination is
30250003Sadrian * a 64-bit register).  Don't reorder the writes in this code
31250003Sadrian * w/o considering this!
32250003Sadrian */
33250003Sadrian#define KEY_XOR         0xaa
34250003Sadrian
35250003Sadrian#define IS_MIC_ENABLED(ah) \
36250003Sadrian    (AH9300(ah)->ah_sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
37250003Sadrian
38250003Sadrian/*
39250003Sadrian * Return the size of the hardware key cache.
40250003Sadrian */
41250003Sadrianu_int32_t
42250003Sadrianar9300_get_key_cache_size(struct ath_hal *ah)
43250003Sadrian{
44250003Sadrian    return AH_PRIVATE(ah)->ah_caps.hal_key_cache_size;
45250003Sadrian}
46250003Sadrian
47250003Sadrian/*
48250003Sadrian * Return AH_TRUE if the specific key cache entry is valid.
49250003Sadrian */
50250003SadrianHAL_BOOL
51250003Sadrianar9300_is_key_cache_entry_valid(struct ath_hal *ah, u_int16_t entry)
52250003Sadrian{
53250003Sadrian    if (entry < AH_PRIVATE(ah)->ah_caps.hal_key_cache_size) {
54250003Sadrian        u_int32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry));
55250003Sadrian        if (val & AR_KEYTABLE_VALID) {
56250003Sadrian            return AH_TRUE;
57250003Sadrian        }
58250003Sadrian    }
59250003Sadrian    return AH_FALSE;
60250003Sadrian}
61250003Sadrian
62250003Sadrian/*
63250003Sadrian * Clear the specified key cache entry and any associated MIC entry.
64250003Sadrian */
65250003SadrianHAL_BOOL
66250003Sadrianar9300_reset_key_cache_entry(struct ath_hal *ah, u_int16_t entry)
67250003Sadrian{
68250003Sadrian    u_int32_t key_type;
69250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
70250003Sadrian
71250003Sadrian    if (entry >= AH_PRIVATE(ah)->ah_caps.hal_key_cache_size) {
72250003Sadrian        HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
73250003Sadrian            "%s: entry %u out of range\n", __func__, entry);
74250003Sadrian        return AH_FALSE;
75250003Sadrian    }
76250003Sadrian    key_type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry));
77250003Sadrian
78250003Sadrian    /* XXX why not clear key type/valid bit first? */
79250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
80250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
81250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
82250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
83250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
84250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
85250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
86250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
87250003Sadrian    if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
88250003Sadrian        u_int16_t micentry = entry + 64;  /* MIC goes at slot+64 */
89250003Sadrian
90250003Sadrian        HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.hal_key_cache_size);
91250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
92250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
93250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
94250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
95250003Sadrian        /* NB: key type and MAC are known to be ok */
96250003Sadrian    }
97250003Sadrian
98250003Sadrian    if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) {
99250003Sadrian        return AH_TRUE;
100250003Sadrian    }
101250003Sadrian
102250003Sadrian    if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL)
103250003Sadrian        == HAL_OK) {
104250003Sadrian        if (key_type == AR_KEYTABLE_TYPE_TKIP    ||
105250003Sadrian            key_type == AR_KEYTABLE_TYPE_40      ||
106250003Sadrian            key_type == AR_KEYTABLE_TYPE_104     ||
107250003Sadrian            key_type == AR_KEYTABLE_TYPE_128) {
108250003Sadrian            /* SW WAR for Bug 31602 */
109250003Sadrian            if (--ahp->ah_rifs_sec_cnt == 0) {
110250003Sadrian                HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
111250003Sadrian                    "%s: Count = %d, enabling RIFS\n",
112250003Sadrian                    __func__, ahp->ah_rifs_sec_cnt);
113250003Sadrian                ar9300_set_rifs_delay(ah, AH_TRUE);
114250003Sadrian            }
115250003Sadrian        }
116250003Sadrian    }
117250003Sadrian    return AH_TRUE;
118250003Sadrian}
119250003Sadrian
120250003Sadrian/*
121250003Sadrian * Sets the mac part of the specified key cache entry (and any
122250003Sadrian * associated MIC entry) and mark them valid.
123250003Sadrian */
124250003SadrianHAL_BOOL
125250003Sadrianar9300_set_key_cache_entry_mac(
126250003Sadrian    struct ath_hal *ah,
127250003Sadrian    u_int16_t entry,
128250003Sadrian    const u_int8_t *mac)
129250003Sadrian{
130250003Sadrian    u_int32_t mac_hi, mac_lo;
131250003Sadrian    u_int32_t unicast_addr = AR_KEYTABLE_VALID;
132250003Sadrian
133250003Sadrian    if (entry >= AH_PRIVATE(ah)->ah_caps.hal_key_cache_size) {
134250003Sadrian        HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
135250003Sadrian            "%s: entry %u out of range\n", __func__, entry);
136250003Sadrian        return AH_FALSE;
137250003Sadrian    }
138250003Sadrian    /*
139250003Sadrian     * Set MAC address -- shifted right by 1.  mac_lo is
140250003Sadrian     * the 4 MSBs, and mac_hi is the 2 LSBs.
141250003Sadrian     */
142250003Sadrian    if (mac != AH_NULL) {
143250003Sadrian        /*
144250003Sadrian         *  If upper layers have requested mcast MACaddr lookup, then
145250003Sadrian         *  signify this to the hw by setting the (poorly named) valid_bit
146250003Sadrian         *  to 0.  Yes, really 0. The hardware specs, pcu_registers.txt, is
147250003Sadrian         *  has incorrectly named valid_bit. It should be called "Unicast".
148250003Sadrian         *  When the Key Cache entry is to decrypt Unicast frames, this bit
149250003Sadrian         *  should be '1'; for multicast and broadcast frames, this bit is '0'.
150250003Sadrian         */
151250003Sadrian        if (mac[0] & 0x01) {
152250003Sadrian            unicast_addr = 0;    /* Not an unicast address */
153250003Sadrian        }
154250003Sadrian
155250003Sadrian        mac_hi = (mac[5] << 8)  |  mac[4];
156250003Sadrian        mac_lo = (mac[3] << 24) | (mac[2] << 16)
157250003Sadrian              | (mac[1] << 8)  |  mac[0];
158250003Sadrian        mac_lo >>= 1; /* Note that the bit 0 is shifted out. This bit is used to
159250003Sadrian                      * indicate that this is a multicast key cache. */
160250003Sadrian        mac_lo |= (mac_hi & 1) << 31; /* carry */
161250003Sadrian        mac_hi >>= 1;
162250003Sadrian    } else {
163250003Sadrian        mac_lo = mac_hi = 0;
164250003Sadrian    }
165250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), mac_lo);
166250003Sadrian    OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), mac_hi | unicast_addr);
167250003Sadrian    return AH_TRUE;
168250003Sadrian}
169250003Sadrian
170250003Sadrian/*
171250003Sadrian * Sets the contents of the specified key cache entry
172250003Sadrian * and any associated MIC entry.
173250003Sadrian */
174250003SadrianHAL_BOOL
175250003Sadrianar9300_set_key_cache_entry(struct ath_hal *ah, u_int16_t entry,
176250003Sadrian                       const HAL_KEYVAL *k, const u_int8_t *mac,
177250003Sadrian                       int xor_key)
178250003Sadrian{
179250003Sadrian    const HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
180250003Sadrian    u_int32_t key0, key1, key2, key3, key4;
181250003Sadrian    u_int32_t key_type;
182250003Sadrian    u_int32_t xor_mask = xor_key ?
183250003Sadrian        (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0;
184250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
185250003Sadrian    u_int32_t pwrmgt, pwrmgt_mic, uapsd_cfg, psta = 0;
186250003Sadrian    int is_proxysta_key = k->kv_type & HAL_KEY_PROXY_STA_MASK;
187250003Sadrian
188250003Sadrian
189250003Sadrian    if (entry >= p_cap->hal_key_cache_size) {
190250003Sadrian        HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
191250003Sadrian            "%s: entry %u out of range\n", __func__, entry);
192250003Sadrian        return AH_FALSE;
193250003Sadrian    }
194250003Sadrian    HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n",
195250003Sadrian        __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
196250003Sadrian        is_proxysta_key);
197250003Sadrian
198250003Sadrian    switch (k->kv_type & AH_KEYTYPE_MASK) {
199250003Sadrian    case HAL_CIPHER_AES_OCB:
200250003Sadrian        key_type = AR_KEYTABLE_TYPE_AES;
201250003Sadrian        break;
202250003Sadrian    case HAL_CIPHER_AES_CCM:
203250003Sadrian        if (!p_cap->hal_cipher_aes_ccm_support) {
204250003Sadrian            HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: AES-CCM not supported by "
205250003Sadrian                "mac rev 0x%x\n",
206250003Sadrian                __func__, AH_PRIVATE(ah)->ah_macRev);
207250003Sadrian            return AH_FALSE;
208250003Sadrian        }
209250003Sadrian        key_type = AR_KEYTABLE_TYPE_CCM;
210250003Sadrian        break;
211250003Sadrian    case HAL_CIPHER_TKIP:
212250003Sadrian        key_type = AR_KEYTABLE_TYPE_TKIP;
213250003Sadrian        if (IS_MIC_ENABLED(ah) && entry + 64 >= p_cap->hal_key_cache_size) {
214250003Sadrian            HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
215250003Sadrian                "%s: entry %u inappropriate for TKIP\n",
216250003Sadrian                __func__, entry);
217250003Sadrian            return AH_FALSE;
218250003Sadrian        }
219250003Sadrian        break;
220250003Sadrian    case HAL_CIPHER_WEP:
221250003Sadrian        if (k->kv_len < 40 / NBBY) {
222250003Sadrian            HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: WEP key length %u too small\n",
223250003Sadrian                __func__, k->kv_len);
224250003Sadrian            return AH_FALSE;
225250003Sadrian        }
226250003Sadrian        if (k->kv_len <= 40 / NBBY) {
227250003Sadrian            key_type = AR_KEYTABLE_TYPE_40;
228250003Sadrian        } else if (k->kv_len <= 104 / NBBY) {
229250003Sadrian            key_type = AR_KEYTABLE_TYPE_104;
230250003Sadrian        } else {
231250003Sadrian            key_type = AR_KEYTABLE_TYPE_128;
232250003Sadrian        }
233250003Sadrian        break;
234250003Sadrian    case HAL_CIPHER_CLR:
235250003Sadrian        key_type = AR_KEYTABLE_TYPE_CLR;
236250003Sadrian        break;
237250003Sadrian    default:
238250003Sadrian        HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: cipher %u not supported\n",
239250003Sadrian            __func__, k->kv_type);
240250003Sadrian        return AH_FALSE;
241250003Sadrian    }
242250003Sadrian
243250003Sadrian    key0 =  LE_READ_4(k->kv_val +  0) ^ xor_mask;
244250003Sadrian    key1 = (LE_READ_2(k->kv_val +  4) ^ xor_mask) & 0xffff;
245250003Sadrian    key2 =  LE_READ_4(k->kv_val +  6) ^ xor_mask;
246250003Sadrian    key3 = (LE_READ_2(k->kv_val + 10) ^ xor_mask) & 0xffff;
247250003Sadrian    key4 =  LE_READ_4(k->kv_val + 12) ^ xor_mask;
248250003Sadrian    if (k->kv_len <= 104 / NBBY) {
249250003Sadrian        key4 &= 0xff;
250250003Sadrian    }
251250003Sadrian
252250003Sadrian    /* Extract the UAPSD AC bits and shift it appropriately */
253250003Sadrian    uapsd_cfg = k->kv_apsd;
254250003Sadrian    uapsd_cfg = (u_int32_t) SM(uapsd_cfg, AR_KEYTABLE_UAPSD);
255250003Sadrian
256250003Sadrian    /* Need to preserve the power management bit used by MAC */
257250003Sadrian    pwrmgt = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEYTABLE_PWRMGT;
258250003Sadrian
259250003Sadrian    if (is_proxysta_key) {
260250003Sadrian        u_int8_t bcast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
261250003Sadrian        if (!mac || adf_os_mem_cmp(mac, bcast_mac, 6)) {
262250003Sadrian            psta = AR_KEYTABLE_DIR_ACK_BIT;
263250003Sadrian        }
264250003Sadrian    }
265250003Sadrian    /*
266250003Sadrian     * Note: key cache hardware requires that each double-word
267250003Sadrian     * pair be written in even/odd order (since the destination is
268250003Sadrian     * a 64-bit register).  Don't reorder these writes w/o
269250003Sadrian     * considering this!
270250003Sadrian     */
271250003Sadrian    if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
272250003Sadrian        u_int16_t micentry = entry + 64;  /* MIC goes at slot+64 */
273250003Sadrian
274250003Sadrian        /* Need to preserve the power management bit used by MAC */
275250003Sadrian        pwrmgt_mic =
276250003Sadrian            OS_REG_READ(ah, AR_KEYTABLE_TYPE(micentry)) & AR_KEYTABLE_PWRMGT;
277250003Sadrian
278250003Sadrian        /*
279250003Sadrian         * Invalidate the encrypt/decrypt key until the MIC
280250003Sadrian         * key is installed so pending rx frames will fail
281250003Sadrian         * with decrypt errors rather than a MIC error.
282250003Sadrian         */
283250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
284250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
285250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
286250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
287250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
288250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry),
289250003Sadrian            key_type | pwrmgt | uapsd_cfg | psta);
290250003Sadrian        ar9300_set_key_cache_entry_mac(ah, entry, mac);
291250003Sadrian
292250003Sadrian        /*
293250003Sadrian         * since the AR_MISC_MODE register was written with the contents of
294250003Sadrian         * ah_misc_mode (if any) in ar9300_attach, just check ah_misc_mode and
295250003Sadrian         * save a pci read per key set.
296250003Sadrian         */
297250003Sadrian        if (ahp->ah_misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
298250003Sadrian            u_int32_t mic0, mic1, mic2, mic3, mic4;
299250003Sadrian            /*
300250003Sadrian             * both RX and TX mic values can be combined into
301250003Sadrian             * one cache slot entry.
302250003Sadrian             * 8*N + 800         31:0    RX Michael key 0
303250003Sadrian             * 8*N + 804         15:0    TX Michael key 0 [31:16]
304250003Sadrian             * 8*N + 808         31:0    RX Michael key 1
305250003Sadrian             * 8*N + 80C         15:0    TX Michael key 0 [15:0]
306250003Sadrian             * 8*N + 810         31:0    TX Michael key 1
307250003Sadrian             * 8*N + 814         15:0    reserved
308250003Sadrian             * 8*N + 818         31:0    reserved
309250003Sadrian             * 8*N + 81C         14:0    reserved
310250003Sadrian             *                   15      key valid == 0
311250003Sadrian             */
312250003Sadrian            /* RX mic */
313250003Sadrian            mic0 = LE_READ_4(k->kv_mic + 0);
314250003Sadrian            mic2 = LE_READ_4(k->kv_mic + 4);
315250003Sadrian            /* TX mic */
316250003Sadrian            mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff;
317250003Sadrian            mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff;
318250003Sadrian            mic4 = LE_READ_4(k->kv_txmic + 4);
319250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
320250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
321250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
322250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
323250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
324250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
325250003Sadrian                         AR_KEYTABLE_TYPE_CLR | pwrmgt_mic | uapsd_cfg);
326250003Sadrian
327250003Sadrian        } else {
328250003Sadrian            u_int32_t mic0, mic2;
329250003Sadrian
330250003Sadrian            mic0 = LE_READ_4(k->kv_mic + 0);
331250003Sadrian            mic2 = LE_READ_4(k->kv_mic + 4);
332250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
333250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
334250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
335250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
336250003Sadrian            OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
337250003Sadrian            OS_REG_WRITE(ah,
338250003Sadrian                AR_KEYTABLE_TYPE(micentry | pwrmgt_mic | uapsd_cfg),
339250003Sadrian                AR_KEYTABLE_TYPE_CLR);
340250003Sadrian        }
341250003Sadrian        /* NB: MIC key is not marked valid and has no MAC address */
342250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
343250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
344250003Sadrian
345250003Sadrian        /* correct intentionally corrupted key */
346250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
347250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
348250003Sadrian    } else {
349250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
350250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
351250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
352250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
353250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
354250003Sadrian        OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry),
355250003Sadrian            key_type | pwrmgt | uapsd_cfg | psta);
356250003Sadrian
357250003Sadrian        /*
358250003Sadrian        ath_hal_printf(ah, "%s[%d] mac %s proxy %d\n",
359250003Sadrian            __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
360250003Sadrian            is_proxysta_key);
361250003Sadrian         */
362250003Sadrian
363250003Sadrian        ar9300_set_key_cache_entry_mac(ah, entry, mac);
364250003Sadrian    }
365250003Sadrian
366250003Sadrian    if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) {
367250003Sadrian        return AH_TRUE;
368250003Sadrian    }
369250003Sadrian
370250003Sadrian    if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL)
371250003Sadrian        == HAL_OK) {
372250003Sadrian        if (key_type == AR_KEYTABLE_TYPE_TKIP    ||
373250003Sadrian            key_type == AR_KEYTABLE_TYPE_40      ||
374250003Sadrian            key_type == AR_KEYTABLE_TYPE_104     ||
375250003Sadrian            key_type == AR_KEYTABLE_TYPE_128) {
376250003Sadrian            /* SW WAR for Bug 31602 */
377250003Sadrian            ahp->ah_rifs_sec_cnt++;
378250003Sadrian            HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
379250003Sadrian                "%s: Count = %d, disabling RIFS\n",
380250003Sadrian                __func__, ahp->ah_rifs_sec_cnt);
381250003Sadrian            ar9300_set_rifs_delay(ah, AH_FALSE);
382250003Sadrian        }
383250003Sadrian    }
384250003Sadrian    HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s[%d] mac %s proxy %d\n",
385250003Sadrian        __func__, __LINE__, mac ? ath_hal_ether_sprintf(mac) : "null",
386250003Sadrian        is_proxysta_key);
387250003Sadrian
388250003Sadrian    return AH_TRUE;
389250003Sadrian}
390250003Sadrian
391250003Sadrian/*
392250003Sadrian * Enable the Keysearch for every subframe of an aggregate
393250003Sadrian */
394250003Sadrianvoid
395250003Sadrianar9300_enable_keysearch_always(struct ath_hal *ah, int enable)
396250003Sadrian{
397250003Sadrian    u_int32_t val;
398250003Sadrian
399250003Sadrian    if (!ah) {
400250003Sadrian        return;
401250003Sadrian    }
402250003Sadrian    val = OS_REG_READ(ah, AR_PCU_MISC);
403250003Sadrian    if (enable) {
404250003Sadrian        val |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
405250003Sadrian    } else {
406250003Sadrian        val &= ~AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
407250003Sadrian    }
408250003Sadrian    OS_REG_WRITE(ah, AR_PCU_MISC, val);
409250003Sadrian}
410250003Sadrianvoid ar9300_dump_keycache(struct ath_hal *ah, int n, u_int32_t *entry)
411250003Sadrian{
412250003Sadrian#define AH_KEY_REG_SIZE	8
413250003Sadrian    int i;
414250003Sadrian
415250003Sadrian    for (i = 0; i < AH_KEY_REG_SIZE; i++) {
416250003Sadrian        entry[i] = OS_REG_READ(ah, AR_KEYTABLE_KEY0(n) + i * 4);
417250003Sadrian    }
418250003Sadrian#undef AH_KEY_REG_SIZE
419250003Sadrian}
420250003Sadrian
421250003Sadrian#endif /* AH_SUPPORT_AR9300 */
422