0001
0002
0003
0004
0005 #include "cam.h"
0006 #include "debug.h"
0007 #include "fw.h"
0008 #include "mac.h"
0009
0010 static struct sk_buff *
0011 rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev,
0012 struct rtw89_sec_cam_entry *sec_cam,
0013 bool ext_key)
0014 {
0015 struct sk_buff *skb;
0016 u32 cmd_len = H2C_SEC_CAM_LEN;
0017 u32 key32[4];
0018 u8 *cmd;
0019 int i, j;
0020
0021 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, cmd_len);
0022 if (!skb)
0023 return NULL;
0024
0025 skb_put_zero(skb, cmd_len);
0026
0027 for (i = 0; i < 4; i++) {
0028 j = i * 4;
0029 j += ext_key ? 16 : 0;
0030 key32[i] = FIELD_PREP(GENMASK(7, 0), sec_cam->key[j + 0]) |
0031 FIELD_PREP(GENMASK(15, 8), sec_cam->key[j + 1]) |
0032 FIELD_PREP(GENMASK(23, 16), sec_cam->key[j + 2]) |
0033 FIELD_PREP(GENMASK(31, 24), sec_cam->key[j + 3]);
0034 }
0035
0036 cmd = skb->data;
0037 RTW89_SET_FWCMD_SEC_IDX(cmd, sec_cam->sec_cam_idx + (ext_key ? 1 : 0));
0038 RTW89_SET_FWCMD_SEC_OFFSET(cmd, sec_cam->offset);
0039 RTW89_SET_FWCMD_SEC_LEN(cmd, sec_cam->len);
0040 RTW89_SET_FWCMD_SEC_TYPE(cmd, sec_cam->type);
0041 RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, ext_key);
0042 RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, sec_cam->spp_mode);
0043 RTW89_SET_FWCMD_SEC_KEY0(cmd, key32[0]);
0044 RTW89_SET_FWCMD_SEC_KEY1(cmd, key32[1]);
0045 RTW89_SET_FWCMD_SEC_KEY2(cmd, key32[2]);
0046 RTW89_SET_FWCMD_SEC_KEY3(cmd, key32[3]);
0047
0048 return skb;
0049 }
0050
0051 static int rtw89_cam_send_sec_key_cmd(struct rtw89_dev *rtwdev,
0052 struct rtw89_sec_cam_entry *sec_cam)
0053 {
0054 struct sk_buff *skb, *ext_skb;
0055 int ret;
0056
0057 skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, false);
0058 if (!skb) {
0059 rtw89_err(rtwdev, "failed to get sec key command\n");
0060 return -ENOMEM;
0061 }
0062
0063 rtw89_h2c_pkt_set_hdr(rtwdev, skb,
0064 FWCMD_TYPE_H2C,
0065 H2C_CAT_MAC,
0066 H2C_CL_MAC_SEC_CAM,
0067 H2C_FUNC_MAC_SEC_UPD, 1, 0,
0068 H2C_SEC_CAM_LEN);
0069 ret = rtw89_h2c_tx(rtwdev, skb, false);
0070 if (ret) {
0071 rtw89_err(rtwdev, "failed to send sec key h2c: %d\n", ret);
0072 dev_kfree_skb(skb);
0073 return ret;
0074 }
0075
0076 if (!sec_cam->ext_key)
0077 return 0;
0078
0079 ext_skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, true);
0080 if (!ext_skb) {
0081 rtw89_err(rtwdev, "failed to get ext sec key command\n");
0082 return -ENOMEM;
0083 }
0084
0085 rtw89_h2c_pkt_set_hdr(rtwdev, ext_skb,
0086 FWCMD_TYPE_H2C,
0087 H2C_CAT_MAC,
0088 H2C_CL_MAC_SEC_CAM,
0089 H2C_FUNC_MAC_SEC_UPD,
0090 1, 0, H2C_SEC_CAM_LEN);
0091 ret = rtw89_h2c_tx(rtwdev, ext_skb, false);
0092 if (ret) {
0093 rtw89_err(rtwdev, "failed to send ext sec key h2c: %d\n", ret);
0094 dev_kfree_skb(ext_skb);
0095 return ret;
0096 }
0097
0098 return 0;
0099 }
0100
0101 static int rtw89_cam_get_avail_sec_cam(struct rtw89_dev *rtwdev,
0102 u8 *sec_cam_idx, bool ext_key)
0103 {
0104 const struct rtw89_chip_info *chip = rtwdev->chip;
0105 struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
0106 u8 sec_cam_num = chip->scam_num;
0107 u8 idx = 0;
0108
0109 if (!ext_key) {
0110 idx = find_first_zero_bit(cam_info->sec_cam_map, sec_cam_num);
0111 if (idx >= sec_cam_num)
0112 return -EBUSY;
0113
0114 set_bit(idx, cam_info->sec_cam_map);
0115 *sec_cam_idx = idx;
0116
0117 return 0;
0118 }
0119
0120 again:
0121 idx = find_next_zero_bit(cam_info->sec_cam_map, sec_cam_num, idx);
0122 if (idx >= sec_cam_num - 1)
0123 return -EBUSY;
0124
0125 if (test_bit(idx + 1, cam_info->sec_cam_map)) {
0126 idx++;
0127 goto again;
0128 }
0129
0130 set_bit(idx, cam_info->sec_cam_map);
0131 set_bit(idx + 1, cam_info->sec_cam_map);
0132 *sec_cam_idx = idx;
0133
0134 return 0;
0135 }
0136
0137 static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
0138 struct rtw89_sec_cam_entry *sec_cam,
0139 struct ieee80211_key_conf *key,
0140 u8 *key_idx)
0141 {
0142 u8 idx;
0143
0144
0145
0146
0147
0148
0149 switch (addr_cam->sec_ent_mode) {
0150 case RTW89_ADDR_CAM_SEC_NONE:
0151 return -EINVAL;
0152 case RTW89_ADDR_CAM_SEC_ALL_UNI:
0153 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
0154 return -EINVAL;
0155 idx = find_first_zero_bit(addr_cam->sec_cam_map,
0156 RTW89_SEC_CAM_IN_ADDR_CAM);
0157 if (idx >= RTW89_SEC_CAM_IN_ADDR_CAM)
0158 return -EBUSY;
0159 *key_idx = idx;
0160 break;
0161 case RTW89_ADDR_CAM_SEC_NORMAL:
0162 if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
0163 idx = find_next_zero_bit(addr_cam->sec_cam_map,
0164 RTW89_SEC_CAM_IN_ADDR_CAM, 5);
0165 if (idx > 6)
0166 return -EBUSY;
0167 *key_idx = idx;
0168 break;
0169 }
0170
0171 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
0172 idx = find_next_zero_bit(addr_cam->sec_cam_map,
0173 RTW89_SEC_CAM_IN_ADDR_CAM, 0);
0174 if (idx > 1)
0175 return -EBUSY;
0176 *key_idx = idx;
0177 break;
0178 }
0179
0180
0181 idx = find_next_zero_bit(addr_cam->sec_cam_map,
0182 RTW89_SEC_CAM_IN_ADDR_CAM, 2);
0183 if (idx > 4)
0184 return -EBUSY;
0185 *key_idx = idx;
0186 break;
0187 case RTW89_ADDR_CAM_SEC_4GROUP:
0188 if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
0189 if (test_bit(6, addr_cam->sec_cam_map))
0190 return -EINVAL;
0191 *key_idx = 6;
0192 break;
0193 }
0194
0195 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
0196 idx = find_next_zero_bit(addr_cam->sec_cam_map,
0197 RTW89_SEC_CAM_IN_ADDR_CAM, 0);
0198 if (idx > 1)
0199 return -EBUSY;
0200 *key_idx = idx;
0201 break;
0202 }
0203
0204
0205 idx = find_next_zero_bit(addr_cam->sec_cam_map,
0206 RTW89_SEC_CAM_IN_ADDR_CAM, 2);
0207 if (idx > 5)
0208 return -EBUSY;
0209 *key_idx = idx;
0210 break;
0211 }
0212
0213 return 0;
0214 }
0215
0216 static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
0217 struct ieee80211_vif *vif,
0218 struct ieee80211_sta *sta,
0219 struct ieee80211_key_conf *key,
0220 struct rtw89_sec_cam_entry *sec_cam)
0221 {
0222 struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
0223 struct rtw89_vif *rtwvif;
0224 struct rtw89_addr_cam_entry *addr_cam;
0225 u8 key_idx = 0;
0226 int ret;
0227
0228 if (!vif) {
0229 rtw89_err(rtwdev, "No iface for adding sec cam\n");
0230 return -EINVAL;
0231 }
0232
0233 rtwvif = (struct rtw89_vif *)vif->drv_priv;
0234 addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
0235 ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx);
0236 if (ret) {
0237 rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n",
0238 addr_cam->sec_ent_mode, sec_cam->type);
0239 return ret;
0240 }
0241
0242 key->hw_key_idx = key_idx;
0243 addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
0244 addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
0245 addr_cam->sec_entries[key_idx] = sec_cam;
0246 set_bit(key_idx, addr_cam->sec_cam_map);
0247 ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
0248 if (ret) {
0249 rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
0250 ret);
0251 return ret;
0252 }
0253 ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
0254 if (ret) {
0255 rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
0256 ret);
0257 clear_bit(key_idx, addr_cam->sec_cam_map);
0258 addr_cam->sec_entries[key_idx] = NULL;
0259 return ret;
0260 }
0261
0262 return 0;
0263 }
0264
0265 static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
0266 struct ieee80211_vif *vif,
0267 struct ieee80211_sta *sta,
0268 struct ieee80211_key_conf *key,
0269 u8 hw_key_type, bool ext_key)
0270 {
0271 struct rtw89_sec_cam_entry *sec_cam = NULL;
0272 struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
0273 u8 sec_cam_idx;
0274 int ret;
0275
0276
0277 if (key->keylen > 32) {
0278 rtw89_err(rtwdev, "invalid sec key length %d\n", key->keylen);
0279 return -EINVAL;
0280 }
0281
0282 ret = rtw89_cam_get_avail_sec_cam(rtwdev, &sec_cam_idx, ext_key);
0283 if (ret) {
0284 rtw89_warn(rtwdev, "no available sec cam: %d ext: %d\n",
0285 ret, ext_key);
0286 return ret;
0287 }
0288
0289 sec_cam = kzalloc(sizeof(*sec_cam), GFP_KERNEL);
0290 if (!sec_cam) {
0291 ret = -ENOMEM;
0292 goto err_release_cam;
0293 }
0294
0295 sec_cam->sec_cam_idx = sec_cam_idx;
0296 sec_cam->type = hw_key_type;
0297 sec_cam->len = RTW89_SEC_CAM_LEN;
0298 sec_cam->ext_key = ext_key;
0299 memcpy(sec_cam->key, key->key, key->keylen);
0300 ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam);
0301 if (ret) {
0302 rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret);
0303 goto err_release_cam;
0304 }
0305
0306
0307 ret = rtw89_cam_attach_sec_cam(rtwdev, vif, sta, key, sec_cam);
0308 if (ret) {
0309 rtw89_err(rtwdev, "failed to attach sec cam: %d\n", ret);
0310 goto err_release_cam;
0311 }
0312
0313 return 0;
0314
0315 err_release_cam:
0316 kfree(sec_cam);
0317 clear_bit(sec_cam_idx, cam_info->sec_cam_map);
0318 if (ext_key)
0319 clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
0320
0321 return ret;
0322 }
0323
0324 int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
0325 struct ieee80211_vif *vif,
0326 struct ieee80211_sta *sta,
0327 struct ieee80211_key_conf *key)
0328 {
0329 const struct rtw89_chip_info *chip = rtwdev->chip;
0330 u8 hw_key_type;
0331 bool ext_key = false;
0332 int ret;
0333
0334 switch (key->cipher) {
0335 case WLAN_CIPHER_SUITE_WEP40:
0336 hw_key_type = RTW89_SEC_KEY_TYPE_WEP40;
0337 break;
0338 case WLAN_CIPHER_SUITE_WEP104:
0339 hw_key_type = RTW89_SEC_KEY_TYPE_WEP104;
0340 break;
0341 case WLAN_CIPHER_SUITE_CCMP:
0342 hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128;
0343 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
0344 break;
0345 case WLAN_CIPHER_SUITE_CCMP_256:
0346 hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256;
0347 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
0348 ext_key = true;
0349 break;
0350 case WLAN_CIPHER_SUITE_GCMP:
0351 hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128;
0352 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
0353 break;
0354 case WLAN_CIPHER_SUITE_GCMP_256:
0355 hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256;
0356 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
0357 ext_key = true;
0358 break;
0359 default:
0360 return -EOPNOTSUPP;
0361 }
0362
0363 if (!chip->hw_sec_hdr)
0364 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0365
0366 ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type,
0367 ext_key);
0368 if (ret) {
0369 rtw89_err(rtwdev, "failed to install key type %d ext %d: %d\n",
0370 hw_key_type, ext_key, ret);
0371 return ret;
0372 }
0373
0374 return 0;
0375 }
0376
0377 int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
0378 struct ieee80211_vif *vif,
0379 struct ieee80211_sta *sta,
0380 struct ieee80211_key_conf *key,
0381 bool inform_fw)
0382 {
0383 struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
0384 struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
0385 struct rtw89_vif *rtwvif;
0386 struct rtw89_addr_cam_entry *addr_cam;
0387 struct rtw89_sec_cam_entry *sec_cam;
0388 u8 key_idx = key->hw_key_idx;
0389 u8 sec_cam_idx;
0390 int ret = 0;
0391
0392 if (!vif) {
0393 rtw89_err(rtwdev, "No iface for deleting sec cam\n");
0394 return -EINVAL;
0395 }
0396
0397 rtwvif = (struct rtw89_vif *)vif->drv_priv;
0398 addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
0399 sec_cam = addr_cam->sec_entries[key_idx];
0400 if (!sec_cam)
0401 return -EINVAL;
0402
0403
0404 clear_bit(key_idx, addr_cam->sec_cam_map);
0405 addr_cam->sec_entries[key_idx] = NULL;
0406 if (inform_fw) {
0407 ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
0408 if (ret)
0409 rtw89_err(rtwdev, "failed to update dctl cam del key: %d\n", ret);
0410 ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
0411 if (ret)
0412 rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
0413 }
0414
0415
0416
0417
0418 sec_cam_idx = sec_cam->sec_cam_idx;
0419 clear_bit(sec_cam_idx, cam_info->sec_cam_map);
0420 if (sec_cam->ext_key)
0421 clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
0422
0423 kfree(sec_cam);
0424
0425 return ret;
0426 }
0427
0428 static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw,
0429 struct ieee80211_vif *vif,
0430 struct ieee80211_sta *sta,
0431 struct ieee80211_key_conf *key,
0432 void *data)
0433 {
0434 struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
0435
0436 rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false);
0437 }
0438
0439 void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
0440 struct rtw89_addr_cam_entry *addr_cam)
0441 {
0442 struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
0443
0444 addr_cam->valid = false;
0445 clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map);
0446 }
0447
0448 void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
0449 struct rtw89_bssid_cam_entry *bssid_cam)
0450 {
0451 struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
0452
0453 bssid_cam->valid = false;
0454 clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
0455 }
0456
0457 void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
0458 {
0459 struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
0460 struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
0461
0462 rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
0463 rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam);
0464 }
0465
0466 void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev)
0467 {
0468 rcu_read_lock();
0469 ieee80211_iter_keys_rcu(rtwdev->hw, NULL, rtw89_cam_reset_key_iter, rtwdev);
0470 rcu_read_unlock();
0471 }
0472
0473 static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev,
0474 u8 *addr_cam_idx)
0475 {
0476 const struct rtw89_chip_info *chip = rtwdev->chip;
0477 struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
0478 u8 addr_cam_num = chip->acam_num;
0479 u8 idx;
0480
0481 idx = find_first_zero_bit(cam_info->addr_cam_map, addr_cam_num);
0482 if (idx >= addr_cam_num)
0483 return -EBUSY;
0484
0485 set_bit(idx, cam_info->addr_cam_map);
0486 *addr_cam_idx = idx;
0487
0488 return 0;
0489 }
0490
0491 int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
0492 struct rtw89_addr_cam_entry *addr_cam,
0493 const struct rtw89_bssid_cam_entry *bssid_cam)
0494 {
0495 u8 addr_cam_idx;
0496 int i;
0497 int ret;
0498
0499 if (unlikely(addr_cam->valid)) {
0500 rtw89_debug(rtwdev, RTW89_DBG_FW,
0501 "addr cam is already valid; skip init\n");
0502 return 0;
0503 }
0504
0505 ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx);
0506 if (ret) {
0507 rtw89_err(rtwdev, "failed to get available addr cam\n");
0508 return ret;
0509 }
0510
0511 addr_cam->addr_cam_idx = addr_cam_idx;
0512 addr_cam->len = ADDR_CAM_ENT_SIZE;
0513 addr_cam->offset = 0;
0514 addr_cam->valid = true;
0515 addr_cam->addr_mask = 0;
0516 addr_cam->mask_sel = RTW89_NO_MSK;
0517 addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
0518 bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
0519
0520 for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
0521 addr_cam->sec_ent_keyid[i] = 0;
0522 addr_cam->sec_ent[i] = 0;
0523 }
0524
0525
0526 addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx;
0527
0528 return 0;
0529 }
0530
0531 static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
0532 u8 *bssid_cam_idx)
0533 {
0534 const struct rtw89_chip_info *chip = rtwdev->chip;
0535 struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
0536 u8 bssid_cam_num = chip->bcam_num;
0537 u8 idx;
0538
0539 idx = find_first_zero_bit(cam_info->bssid_cam_map, bssid_cam_num);
0540 if (idx >= bssid_cam_num)
0541 return -EBUSY;
0542
0543 set_bit(idx, cam_info->bssid_cam_map);
0544 *bssid_cam_idx = idx;
0545
0546 return 0;
0547 }
0548
0549 int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
0550 struct rtw89_vif *rtwvif,
0551 struct rtw89_bssid_cam_entry *bssid_cam,
0552 const u8 *bssid)
0553 {
0554 u8 bssid_cam_idx;
0555 int ret;
0556
0557 if (unlikely(bssid_cam->valid)) {
0558 rtw89_debug(rtwdev, RTW89_DBG_FW,
0559 "bssid cam is already valid; skip init\n");
0560 return 0;
0561 }
0562
0563 ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx);
0564 if (ret) {
0565 rtw89_err(rtwdev, "failed to get available bssid cam\n");
0566 return ret;
0567 }
0568
0569 bssid_cam->bssid_cam_idx = bssid_cam_idx;
0570 bssid_cam->phy_idx = rtwvif->phy_idx;
0571 bssid_cam->len = BSSID_CAM_ENT_SIZE;
0572 bssid_cam->offset = 0;
0573 bssid_cam->valid = true;
0574 ether_addr_copy(bssid_cam->bssid, bssid);
0575
0576 return 0;
0577 }
0578
0579 void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
0580 {
0581 struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
0582
0583 ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
0584 }
0585
0586 int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
0587 {
0588 struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
0589 struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
0590 int ret;
0591
0592 ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, rtwvif->bssid);
0593 if (ret) {
0594 rtw89_err(rtwdev, "failed to init bssid cam\n");
0595 return ret;
0596 }
0597
0598 ret = rtw89_cam_init_addr_cam(rtwdev, addr_cam, bssid_cam);
0599 if (ret) {
0600 rtw89_err(rtwdev, "failed to init addr cam\n");
0601 return ret;
0602 }
0603
0604 return 0;
0605 }
0606
0607 int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
0608 struct rtw89_vif *rtwvif,
0609 struct rtw89_sta *rtwsta, u8 *cmd)
0610 {
0611 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
0612 struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
0613 u8 bss_color = vif->bss_conf.he_bss_color.color;
0614 u8 bss_mask;
0615
0616 if (vif->bss_conf.nontransmitted)
0617 bss_mask = RTW89_BSSID_MATCH_5_BYTES;
0618 else
0619 bss_mask = RTW89_BSSID_MATCH_ALL;
0620
0621 FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
0622 FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
0623 FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
0624 FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid);
0625 FWCMD_SET_ADDR_BSSID_MASK(cmd, bss_mask);
0626 FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx);
0627 FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color);
0628
0629 FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]);
0630 FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]);
0631 FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]);
0632 FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]);
0633 FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]);
0634 FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]);
0635
0636 return 0;
0637 }
0638
0639 static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
0640 {
0641 u8 hash = 0;
0642 u8 i;
0643
0644 for (i = start; i < ETH_ALEN; i++)
0645 hash ^= addr[i];
0646
0647 return hash;
0648 }
0649
0650 void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
0651 struct rtw89_vif *rtwvif,
0652 struct rtw89_sta *rtwsta,
0653 const u8 *scan_mac_addr,
0654 u8 *cmd)
0655 {
0656 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
0657 struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
0658 struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
0659 const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
0660 u8 sma_hash, tma_hash, addr_msk_start;
0661 u8 sma_start = 0;
0662 u8 tma_start = 0;
0663 u8 *tma = sta ? sta->addr : rtwvif->bssid;
0664
0665 if (addr_cam->addr_mask != 0) {
0666 addr_msk_start = __ffs(addr_cam->addr_mask);
0667 if (addr_cam->mask_sel == RTW89_SMA)
0668 sma_start = addr_msk_start;
0669 else if (addr_cam->mask_sel == RTW89_TMA)
0670 tma_start = addr_msk_start;
0671 }
0672 sma_hash = rtw89_cam_addr_hash(sma_start, sma);
0673 tma_hash = rtw89_cam_addr_hash(tma_start, tma);
0674
0675 FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx);
0676 FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset);
0677 FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
0678
0679 FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
0680 FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
0681 FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
0682 FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
0683 FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
0684 FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
0685 FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
0686 FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
0687 FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash);
0688
0689 FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx);
0690
0691 FWCMD_SET_ADDR_SMA0(cmd, sma[0]);
0692 FWCMD_SET_ADDR_SMA1(cmd, sma[1]);
0693 FWCMD_SET_ADDR_SMA2(cmd, sma[2]);
0694 FWCMD_SET_ADDR_SMA3(cmd, sma[3]);
0695 FWCMD_SET_ADDR_SMA4(cmd, sma[4]);
0696 FWCMD_SET_ADDR_SMA5(cmd, sma[5]);
0697
0698 FWCMD_SET_ADDR_TMA0(cmd, tma[0]);
0699 FWCMD_SET_ADDR_TMA1(cmd, tma[1]);
0700 FWCMD_SET_ADDR_TMA2(cmd, tma[2]);
0701 FWCMD_SET_ADDR_TMA3(cmd, tma[3]);
0702 FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
0703 FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
0704
0705 FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
0706 FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
0707 FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
0708 FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
0709 FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
0710 FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
0711 FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
0712 if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
0713 FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
0714 else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
0715 FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
0716 FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
0717 FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
0718 FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
0719 FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
0720 FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
0721 FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
0722 FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]);
0723 FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]);
0724 FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]);
0725 FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]);
0726 FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]);
0727 FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]);
0728
0729 FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff);
0730 FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]);
0731 FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]);
0732 FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]);
0733 FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]);
0734 FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
0735 FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
0736 FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
0737 }
0738
0739 void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
0740 struct rtw89_vif *rtwvif,
0741 struct rtw89_sta *rtwsta,
0742 u8 *cmd)
0743 {
0744 struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
0745
0746 SET_DCTL_MACID_V1(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
0747 SET_DCTL_OPERATION_V1(cmd, 1);
0748
0749 SET_DCTL_SEC_ENT0_KEYID_V1(cmd, addr_cam->sec_ent_keyid[0]);
0750 SET_DCTL_SEC_ENT1_KEYID_V1(cmd, addr_cam->sec_ent_keyid[1]);
0751 SET_DCTL_SEC_ENT2_KEYID_V1(cmd, addr_cam->sec_ent_keyid[2]);
0752 SET_DCTL_SEC_ENT3_KEYID_V1(cmd, addr_cam->sec_ent_keyid[3]);
0753 SET_DCTL_SEC_ENT4_KEYID_V1(cmd, addr_cam->sec_ent_keyid[4]);
0754 SET_DCTL_SEC_ENT5_KEYID_V1(cmd, addr_cam->sec_ent_keyid[5]);
0755 SET_DCTL_SEC_ENT6_KEYID_V1(cmd, addr_cam->sec_ent_keyid[6]);
0756
0757 SET_DCTL_SEC_ENT_VALID_V1(cmd, addr_cam->sec_cam_map[0] & 0xff);
0758 SET_DCTL_SEC_ENT0_V1(cmd, addr_cam->sec_ent[0]);
0759 SET_DCTL_SEC_ENT1_V1(cmd, addr_cam->sec_ent[1]);
0760 SET_DCTL_SEC_ENT2_V1(cmd, addr_cam->sec_ent[2]);
0761 SET_DCTL_SEC_ENT3_V1(cmd, addr_cam->sec_ent[3]);
0762 SET_DCTL_SEC_ENT4_V1(cmd, addr_cam->sec_ent[4]);
0763 SET_DCTL_SEC_ENT5_V1(cmd, addr_cam->sec_ent[5]);
0764 SET_DCTL_SEC_ENT6_V1(cmd, addr_cam->sec_ent[6]);
0765 }