Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_keycache.c
48525 views
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
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
446
ar9300_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
593