0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/export.h>
0019 #include <asm/unaligned.h>
0020 #include <net/mac80211.h>
0021
0022 #include "ath.h"
0023 #include "reg.h"
0024
0025 #define REG_READ (common->ops->read)
0026 #define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg)
0027 #define ENABLE_REGWRITE_BUFFER(_ah) \
0028 if (common->ops->enable_write_buffer) \
0029 common->ops->enable_write_buffer((_ah));
0030
0031 #define REGWRITE_BUFFER_FLUSH(_ah) \
0032 if (common->ops->write_flush) \
0033 common->ops->write_flush((_ah));
0034
0035
0036 #define IEEE80211_WEP_NKID 4
0037
0038
0039
0040
0041
0042 bool ath_hw_keyreset(struct ath_common *common, u16 entry)
0043 {
0044 u32 keyType;
0045 void *ah = common->ah;
0046
0047 if (entry >= common->keymax) {
0048 ath_err(common, "keyreset: keycache entry %u out of range\n",
0049 entry);
0050 return false;
0051 }
0052
0053 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
0054
0055 ENABLE_REGWRITE_BUFFER(ah);
0056
0057 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
0058 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
0059 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
0060 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
0061 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
0062 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
0063 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
0064 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
0065
0066 if (keyType == AR_KEYTABLE_TYPE_TKIP) {
0067 u16 micentry = entry + 64;
0068
0069 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
0070 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
0071 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
0072 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
0073 if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
0074 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
0075 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
0076 AR_KEYTABLE_TYPE_CLR);
0077 }
0078
0079 }
0080
0081 REGWRITE_BUFFER_FLUSH(ah);
0082
0083 return true;
0084 }
0085 EXPORT_SYMBOL(ath_hw_keyreset);
0086
0087 bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
0088 {
0089 u32 macHi, macLo;
0090 u32 unicast_flag = AR_KEYTABLE_VALID;
0091 void *ah = common->ah;
0092
0093 if (entry >= common->keymax) {
0094 ath_err(common, "keysetmac: keycache entry %u out of range\n",
0095 entry);
0096 return false;
0097 }
0098
0099 if (mac != NULL) {
0100
0101
0102
0103
0104
0105
0106
0107 if (mac[0] & 0x01)
0108 unicast_flag = 0;
0109
0110 macLo = get_unaligned_le32(mac);
0111 macHi = get_unaligned_le16(mac + 4);
0112 macLo >>= 1;
0113 macLo |= (macHi & 1) << 31;
0114 macHi >>= 1;
0115 } else {
0116 macLo = macHi = 0;
0117 }
0118 ENABLE_REGWRITE_BUFFER(ah);
0119
0120 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
0121 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
0122
0123 REGWRITE_BUFFER_FLUSH(ah);
0124
0125 return true;
0126 }
0127 EXPORT_SYMBOL(ath_hw_keysetmac);
0128
0129 static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
0130 const struct ath_keyval *k,
0131 const u8 *mac)
0132 {
0133 void *ah = common->ah;
0134 u32 key0, key1, key2, key3, key4;
0135 u32 keyType;
0136
0137 if (entry >= common->keymax) {
0138 ath_err(common, "set-entry: keycache entry %u out of range\n",
0139 entry);
0140 return false;
0141 }
0142
0143 switch (k->kv_type) {
0144 case ATH_CIPHER_AES_OCB:
0145 keyType = AR_KEYTABLE_TYPE_AES;
0146 break;
0147 case ATH_CIPHER_AES_CCM:
0148 if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
0149 ath_dbg(common, ANY,
0150 "AES-CCM not supported by this mac rev\n");
0151 return false;
0152 }
0153 keyType = AR_KEYTABLE_TYPE_CCM;
0154 break;
0155 case ATH_CIPHER_TKIP:
0156 keyType = AR_KEYTABLE_TYPE_TKIP;
0157 if (entry + 64 >= common->keymax) {
0158 ath_dbg(common, ANY,
0159 "entry %u inappropriate for TKIP\n", entry);
0160 return false;
0161 }
0162 break;
0163 case ATH_CIPHER_WEP:
0164 if (k->kv_len < WLAN_KEY_LEN_WEP40) {
0165 ath_dbg(common, ANY, "WEP key length %u too small\n",
0166 k->kv_len);
0167 return false;
0168 }
0169 if (k->kv_len <= WLAN_KEY_LEN_WEP40)
0170 keyType = AR_KEYTABLE_TYPE_40;
0171 else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
0172 keyType = AR_KEYTABLE_TYPE_104;
0173 else
0174 keyType = AR_KEYTABLE_TYPE_128;
0175 break;
0176 case ATH_CIPHER_CLR:
0177 keyType = AR_KEYTABLE_TYPE_CLR;
0178 break;
0179 default:
0180 ath_err(common, "cipher %u not supported\n", k->kv_type);
0181 return false;
0182 }
0183
0184 key0 = get_unaligned_le32(k->kv_val + 0);
0185 key1 = get_unaligned_le16(k->kv_val + 4);
0186 key2 = get_unaligned_le32(k->kv_val + 6);
0187 key3 = get_unaligned_le16(k->kv_val + 10);
0188 key4 = get_unaligned_le32(k->kv_val + 12);
0189 if (k->kv_len <= WLAN_KEY_LEN_WEP104)
0190 key4 &= 0xff;
0191
0192
0193
0194
0195
0196
0197
0198
0199 if (keyType == AR_KEYTABLE_TYPE_TKIP) {
0200 u16 micentry = entry + 64;
0201
0202
0203
0204
0205
0206
0207
0208 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
0209 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
0210
0211
0212 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
0213 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
0214
0215
0216 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
0217 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
0218
0219
0220 (void) ath_hw_keysetmac(common, entry, mac);
0221
0222 if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 u32 mic0, mic1, mic2, mic3, mic4;
0236
0237 mic0 = get_unaligned_le32(k->kv_mic + 0);
0238 mic2 = get_unaligned_le32(k->kv_mic + 4);
0239 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
0240 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
0241 mic4 = get_unaligned_le32(k->kv_txmic + 4);
0242
0243 ENABLE_REGWRITE_BUFFER(ah);
0244
0245
0246 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
0247 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
0248
0249
0250 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
0251 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
0252
0253
0254 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
0255 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
0256 AR_KEYTABLE_TYPE_CLR);
0257
0258 REGWRITE_BUFFER_FLUSH(ah);
0259
0260 } else {
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 u32 mic0, mic2;
0278
0279 mic0 = get_unaligned_le32(k->kv_mic + 0);
0280 mic2 = get_unaligned_le32(k->kv_mic + 4);
0281
0282 ENABLE_REGWRITE_BUFFER(ah);
0283
0284
0285 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
0286 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
0287
0288
0289 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
0290 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
0291
0292
0293 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
0294 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
0295 AR_KEYTABLE_TYPE_CLR);
0296
0297 REGWRITE_BUFFER_FLUSH(ah);
0298 }
0299
0300 ENABLE_REGWRITE_BUFFER(ah);
0301
0302
0303 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
0304 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
0305
0306
0307
0308
0309
0310
0311 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
0312 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
0313
0314 REGWRITE_BUFFER_FLUSH(ah);
0315 } else {
0316 ENABLE_REGWRITE_BUFFER(ah);
0317
0318
0319 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
0320 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
0321
0322
0323 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
0324 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
0325
0326
0327 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
0328 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
0329
0330 REGWRITE_BUFFER_FLUSH(ah);
0331
0332
0333 (void) ath_hw_keysetmac(common, entry, mac);
0334 }
0335
0336 return true;
0337 }
0338
0339 static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
0340 struct ath_keyval *hk, const u8 *addr,
0341 bool authenticator)
0342 {
0343 const u8 *key_rxmic;
0344 const u8 *key_txmic;
0345
0346 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
0347 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
0348
0349 if (addr == NULL) {
0350
0351
0352
0353
0354
0355 if (authenticator) {
0356 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
0357 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
0358 } else {
0359 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
0360 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
0361 }
0362 return ath_hw_set_keycache_entry(common, keyix, hk, addr);
0363 }
0364 if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
0365
0366 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
0367 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
0368 return ath_hw_set_keycache_entry(common, keyix, hk, addr);
0369 }
0370
0371
0372
0373
0374 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
0375 if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
0376
0377 ath_err(common, "Setting TX MIC Key Failed\n");
0378 return 0;
0379 }
0380
0381 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
0382
0383 return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr);
0384 }
0385
0386 static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
0387 {
0388 int i;
0389
0390 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
0391 if (test_bit(i, common->keymap) ||
0392 test_bit(i + 64, common->keymap))
0393 continue;
0394 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) &&
0395 (test_bit(i + 32, common->keymap) ||
0396 test_bit(i + 64 + 32, common->keymap)))
0397 continue;
0398
0399
0400 return i;
0401 }
0402 return -1;
0403 }
0404
0405 static int ath_reserve_key_cache_slot(struct ath_common *common,
0406 u32 cipher)
0407 {
0408 int i;
0409
0410 if (cipher == WLAN_CIPHER_SUITE_TKIP)
0411 return ath_reserve_key_cache_slot_tkip(common);
0412
0413
0414 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0415 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
0416 if (!test_bit(i, common->keymap) &&
0417 (test_bit(i + 32, common->keymap) ||
0418 test_bit(i + 64, common->keymap) ||
0419 test_bit(i + 64 + 32, common->keymap)))
0420 return i;
0421 if (!test_bit(i + 32, common->keymap) &&
0422 (test_bit(i, common->keymap) ||
0423 test_bit(i + 64, common->keymap) ||
0424 test_bit(i + 64 + 32, common->keymap)))
0425 return i + 32;
0426 if (!test_bit(i + 64, common->keymap) &&
0427 (test_bit(i , common->keymap) ||
0428 test_bit(i + 32, common->keymap) ||
0429 test_bit(i + 64 + 32, common->keymap)))
0430 return i + 64;
0431 if (!test_bit(i + 64 + 32, common->keymap) &&
0432 (test_bit(i, common->keymap) ||
0433 test_bit(i + 32, common->keymap) ||
0434 test_bit(i + 64, common->keymap)))
0435 return i + 64 + 32;
0436 }
0437 } else {
0438 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
0439 if (!test_bit(i, common->keymap) &&
0440 test_bit(i + 64, common->keymap))
0441 return i;
0442 if (test_bit(i, common->keymap) &&
0443 !test_bit(i + 64, common->keymap))
0444 return i + 64;
0445 }
0446 }
0447
0448
0449 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
0450
0451
0452
0453 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
0454 continue;
0455 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0456 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
0457 continue;
0458 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
0459 continue;
0460 }
0461
0462 if (!test_bit(i, common->keymap))
0463 return i;
0464 }
0465
0466
0467 return -1;
0468 }
0469
0470
0471
0472
0473 int ath_key_config(struct ath_common *common,
0474 struct ieee80211_vif *vif,
0475 struct ieee80211_sta *sta,
0476 struct ieee80211_key_conf *key)
0477 {
0478 struct ath_keyval hk;
0479 const u8 *mac = NULL;
0480 u8 gmac[ETH_ALEN];
0481 int ret = 0;
0482 int idx;
0483
0484 memset(&hk, 0, sizeof(hk));
0485
0486 switch (key->cipher) {
0487 case 0:
0488 hk.kv_type = ATH_CIPHER_CLR;
0489 break;
0490 case WLAN_CIPHER_SUITE_WEP40:
0491 case WLAN_CIPHER_SUITE_WEP104:
0492 hk.kv_type = ATH_CIPHER_WEP;
0493 break;
0494 case WLAN_CIPHER_SUITE_TKIP:
0495 hk.kv_type = ATH_CIPHER_TKIP;
0496 break;
0497 case WLAN_CIPHER_SUITE_CCMP:
0498 hk.kv_type = ATH_CIPHER_AES_CCM;
0499 break;
0500 default:
0501 return -EOPNOTSUPP;
0502 }
0503
0504 hk.kv_len = key->keylen;
0505 if (key->keylen)
0506 memcpy(hk.kv_val, key->key, key->keylen);
0507
0508 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
0509 switch (vif->type) {
0510 case NL80211_IFTYPE_AP:
0511 memcpy(gmac, vif->addr, ETH_ALEN);
0512 gmac[0] |= 0x01;
0513 mac = gmac;
0514 idx = ath_reserve_key_cache_slot(common, key->cipher);
0515 break;
0516 case NL80211_IFTYPE_ADHOC:
0517 if (!sta) {
0518 idx = key->keyidx;
0519 break;
0520 }
0521 memcpy(gmac, sta->addr, ETH_ALEN);
0522 gmac[0] |= 0x01;
0523 mac = gmac;
0524 idx = ath_reserve_key_cache_slot(common, key->cipher);
0525 break;
0526 default:
0527 idx = key->keyidx;
0528 break;
0529 }
0530 } else if (key->keyidx) {
0531 if (WARN_ON(!sta))
0532 return -EOPNOTSUPP;
0533 mac = sta->addr;
0534
0535 if (vif->type != NL80211_IFTYPE_AP) {
0536
0537
0538 idx = key->keyidx;
0539 } else
0540 return -EIO;
0541 } else {
0542 if (WARN_ON(!sta))
0543 return -EOPNOTSUPP;
0544 mac = sta->addr;
0545
0546 idx = ath_reserve_key_cache_slot(common, key->cipher);
0547 }
0548
0549 if (idx < 0)
0550 return -ENOSPC;
0551
0552 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
0553 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
0554 vif->type == NL80211_IFTYPE_AP);
0555 else
0556 ret = ath_hw_set_keycache_entry(common, idx, &hk, mac);
0557
0558 if (!ret)
0559 return -EIO;
0560
0561 set_bit(idx, common->keymap);
0562 if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
0563 set_bit(idx, common->ccmp_keymap);
0564
0565 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
0566 set_bit(idx + 64, common->keymap);
0567 set_bit(idx, common->tkip_keymap);
0568 set_bit(idx + 64, common->tkip_keymap);
0569 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0570 set_bit(idx + 32, common->keymap);
0571 set_bit(idx + 64 + 32, common->keymap);
0572 set_bit(idx + 32, common->tkip_keymap);
0573 set_bit(idx + 64 + 32, common->tkip_keymap);
0574 }
0575 }
0576
0577 return idx;
0578 }
0579 EXPORT_SYMBOL(ath_key_config);
0580
0581
0582
0583
0584 void ath_key_delete(struct ath_common *common, u8 hw_key_idx)
0585 {
0586
0587
0588
0589
0590
0591 if (test_bit(hw_key_idx, common->ccmp_keymap) ||
0592 test_bit(hw_key_idx, common->tkip_keymap))
0593 ath_hw_keysetmac(common, hw_key_idx, NULL);
0594 else
0595 ath_hw_keyreset(common, hw_key_idx);
0596 if (hw_key_idx < IEEE80211_WEP_NKID)
0597 return;
0598
0599 clear_bit(hw_key_idx, common->keymap);
0600 clear_bit(hw_key_idx, common->ccmp_keymap);
0601 if (!test_bit(hw_key_idx, common->tkip_keymap))
0602 return;
0603
0604 clear_bit(hw_key_idx + 64, common->keymap);
0605
0606 clear_bit(hw_key_idx, common->tkip_keymap);
0607 clear_bit(hw_key_idx + 64, common->tkip_keymap);
0608
0609 if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
0610 ath_hw_keyreset(common, hw_key_idx + 32);
0611 clear_bit(hw_key_idx + 32, common->keymap);
0612 clear_bit(hw_key_idx + 64 + 32, common->keymap);
0613
0614 clear_bit(hw_key_idx + 32, common->tkip_keymap);
0615 clear_bit(hw_key_idx + 64 + 32, common->tkip_keymap);
0616 }
0617 }
0618 EXPORT_SYMBOL(ath_key_delete);