cam.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2. /* Copyright(c) 2019-2020 Realtek Corporation
  3. */
  4. #include "cam.h"
  5. #include "debug.h"
  6. #include "fw.h"
  7. #include "mac.h"
  8. static struct sk_buff *
  9. rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev,
  10. struct rtw89_sec_cam_entry *sec_cam,
  11. bool ext_key)
  12. {
  13. struct sk_buff *skb;
  14. u32 cmd_len = H2C_SEC_CAM_LEN;
  15. u32 key32[4];
  16. u8 *cmd;
  17. int i, j;
  18. skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, cmd_len);
  19. if (!skb)
  20. return NULL;
  21. skb_put_zero(skb, cmd_len);
  22. for (i = 0; i < 4; i++) {
  23. j = i * 4;
  24. j += ext_key ? 16 : 0;
  25. key32[i] = FIELD_PREP(GENMASK(7, 0), sec_cam->key[j + 0]) |
  26. FIELD_PREP(GENMASK(15, 8), sec_cam->key[j + 1]) |
  27. FIELD_PREP(GENMASK(23, 16), sec_cam->key[j + 2]) |
  28. FIELD_PREP(GENMASK(31, 24), sec_cam->key[j + 3]);
  29. }
  30. cmd = skb->data;
  31. RTW89_SET_FWCMD_SEC_IDX(cmd, sec_cam->sec_cam_idx + (ext_key ? 1 : 0));
  32. RTW89_SET_FWCMD_SEC_OFFSET(cmd, sec_cam->offset);
  33. RTW89_SET_FWCMD_SEC_LEN(cmd, sec_cam->len);
  34. RTW89_SET_FWCMD_SEC_TYPE(cmd, sec_cam->type);
  35. RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, ext_key);
  36. RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, sec_cam->spp_mode);
  37. RTW89_SET_FWCMD_SEC_KEY0(cmd, key32[0]);
  38. RTW89_SET_FWCMD_SEC_KEY1(cmd, key32[1]);
  39. RTW89_SET_FWCMD_SEC_KEY2(cmd, key32[2]);
  40. RTW89_SET_FWCMD_SEC_KEY3(cmd, key32[3]);
  41. return skb;
  42. }
  43. static int rtw89_cam_send_sec_key_cmd(struct rtw89_dev *rtwdev,
  44. struct rtw89_sec_cam_entry *sec_cam)
  45. {
  46. struct sk_buff *skb, *ext_skb;
  47. int ret;
  48. skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, false);
  49. if (!skb) {
  50. rtw89_err(rtwdev, "failed to get sec key command\n");
  51. return -ENOMEM;
  52. }
  53. rtw89_h2c_pkt_set_hdr(rtwdev, skb,
  54. FWCMD_TYPE_H2C,
  55. H2C_CAT_MAC,
  56. H2C_CL_MAC_SEC_CAM,
  57. H2C_FUNC_MAC_SEC_UPD, 1, 0,
  58. H2C_SEC_CAM_LEN);
  59. ret = rtw89_h2c_tx(rtwdev, skb, false);
  60. if (ret) {
  61. rtw89_err(rtwdev, "failed to send sec key h2c: %d\n", ret);
  62. dev_kfree_skb(skb);
  63. return ret;
  64. }
  65. if (!sec_cam->ext_key)
  66. return 0;
  67. ext_skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, true);
  68. if (!ext_skb) {
  69. rtw89_err(rtwdev, "failed to get ext sec key command\n");
  70. return -ENOMEM;
  71. }
  72. rtw89_h2c_pkt_set_hdr(rtwdev, ext_skb,
  73. FWCMD_TYPE_H2C,
  74. H2C_CAT_MAC,
  75. H2C_CL_MAC_SEC_CAM,
  76. H2C_FUNC_MAC_SEC_UPD,
  77. 1, 0, H2C_SEC_CAM_LEN);
  78. ret = rtw89_h2c_tx(rtwdev, ext_skb, false);
  79. if (ret) {
  80. rtw89_err(rtwdev, "failed to send ext sec key h2c: %d\n", ret);
  81. dev_kfree_skb(ext_skb);
  82. return ret;
  83. }
  84. return 0;
  85. }
  86. static int rtw89_cam_get_avail_sec_cam(struct rtw89_dev *rtwdev,
  87. u8 *sec_cam_idx, bool ext_key)
  88. {
  89. const struct rtw89_chip_info *chip = rtwdev->chip;
  90. struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
  91. u8 sec_cam_num = chip->scam_num;
  92. u8 idx = 0;
  93. if (!ext_key) {
  94. idx = find_first_zero_bit(cam_info->sec_cam_map, sec_cam_num);
  95. if (idx >= sec_cam_num)
  96. return -EBUSY;
  97. set_bit(idx, cam_info->sec_cam_map);
  98. *sec_cam_idx = idx;
  99. return 0;
  100. }
  101. again:
  102. idx = find_next_zero_bit(cam_info->sec_cam_map, sec_cam_num, idx);
  103. if (idx >= sec_cam_num - 1)
  104. return -EBUSY;
  105. /* ext keys need two cam entries for 256-bit key */
  106. if (test_bit(idx + 1, cam_info->sec_cam_map)) {
  107. idx++;
  108. goto again;
  109. }
  110. set_bit(idx, cam_info->sec_cam_map);
  111. set_bit(idx + 1, cam_info->sec_cam_map);
  112. *sec_cam_idx = idx;
  113. return 0;
  114. }
  115. static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
  116. struct rtw89_sec_cam_entry *sec_cam,
  117. struct ieee80211_key_conf *key,
  118. u8 *key_idx)
  119. {
  120. u8 idx;
  121. /* RTW89_ADDR_CAM_SEC_NONE : not enabled
  122. * RTW89_ADDR_CAM_SEC_ALL_UNI : 0 - 6 unicast
  123. * RTW89_ADDR_CAM_SEC_NORMAL : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP
  124. * RTW89_ADDR_CAM_SEC_4GROUP : 0 - 1 unicast, 2 - 5 group, 6 BIP
  125. */
  126. switch (addr_cam->sec_ent_mode) {
  127. case RTW89_ADDR_CAM_SEC_NONE:
  128. return -EINVAL;
  129. case RTW89_ADDR_CAM_SEC_ALL_UNI:
  130. if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
  131. return -EINVAL;
  132. idx = find_first_zero_bit(addr_cam->sec_cam_map,
  133. RTW89_SEC_CAM_IN_ADDR_CAM);
  134. if (idx >= RTW89_SEC_CAM_IN_ADDR_CAM)
  135. return -EBUSY;
  136. *key_idx = idx;
  137. break;
  138. case RTW89_ADDR_CAM_SEC_NORMAL:
  139. if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
  140. idx = find_next_zero_bit(addr_cam->sec_cam_map,
  141. RTW89_SEC_CAM_IN_ADDR_CAM, 5);
  142. if (idx > 6)
  143. return -EBUSY;
  144. *key_idx = idx;
  145. break;
  146. }
  147. if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
  148. idx = find_next_zero_bit(addr_cam->sec_cam_map,
  149. RTW89_SEC_CAM_IN_ADDR_CAM, 0);
  150. if (idx > 1)
  151. return -EBUSY;
  152. *key_idx = idx;
  153. break;
  154. }
  155. /* Group keys */
  156. idx = find_next_zero_bit(addr_cam->sec_cam_map,
  157. RTW89_SEC_CAM_IN_ADDR_CAM, 2);
  158. if (idx > 4)
  159. return -EBUSY;
  160. *key_idx = idx;
  161. break;
  162. case RTW89_ADDR_CAM_SEC_4GROUP:
  163. if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
  164. if (test_bit(6, addr_cam->sec_cam_map))
  165. return -EINVAL;
  166. *key_idx = 6;
  167. break;
  168. }
  169. if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
  170. idx = find_next_zero_bit(addr_cam->sec_cam_map,
  171. RTW89_SEC_CAM_IN_ADDR_CAM, 0);
  172. if (idx > 1)
  173. return -EBUSY;
  174. *key_idx = idx;
  175. break;
  176. }
  177. /* Group keys */
  178. idx = find_next_zero_bit(addr_cam->sec_cam_map,
  179. RTW89_SEC_CAM_IN_ADDR_CAM, 2);
  180. if (idx > 5)
  181. return -EBUSY;
  182. *key_idx = idx;
  183. break;
  184. }
  185. return 0;
  186. }
  187. static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
  188. struct ieee80211_vif *vif,
  189. struct ieee80211_sta *sta,
  190. struct ieee80211_key_conf *key,
  191. struct rtw89_sec_cam_entry *sec_cam)
  192. {
  193. struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
  194. struct rtw89_vif *rtwvif;
  195. struct rtw89_addr_cam_entry *addr_cam;
  196. u8 key_idx = 0;
  197. int ret;
  198. if (!vif) {
  199. rtw89_err(rtwdev, "No iface for adding sec cam\n");
  200. return -EINVAL;
  201. }
  202. rtwvif = (struct rtw89_vif *)vif->drv_priv;
  203. addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
  204. ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx);
  205. if (ret) {
  206. rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n",
  207. addr_cam->sec_ent_mode, sec_cam->type);
  208. return ret;
  209. }
  210. key->hw_key_idx = key_idx;
  211. addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
  212. addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
  213. addr_cam->sec_entries[key_idx] = sec_cam;
  214. set_bit(key_idx, addr_cam->sec_cam_map);
  215. ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
  216. if (ret) {
  217. rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
  218. ret);
  219. return ret;
  220. }
  221. ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
  222. if (ret) {
  223. rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
  224. ret);
  225. clear_bit(key_idx, addr_cam->sec_cam_map);
  226. addr_cam->sec_entries[key_idx] = NULL;
  227. return ret;
  228. }
  229. return 0;
  230. }
  231. static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
  232. struct ieee80211_vif *vif,
  233. struct ieee80211_sta *sta,
  234. struct ieee80211_key_conf *key,
  235. u8 hw_key_type, bool ext_key)
  236. {
  237. struct rtw89_sec_cam_entry *sec_cam = NULL;
  238. struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
  239. u8 sec_cam_idx;
  240. int ret;
  241. /* maximum key length 256-bit */
  242. if (key->keylen > 32) {
  243. rtw89_err(rtwdev, "invalid sec key length %d\n", key->keylen);
  244. return -EINVAL;
  245. }
  246. ret = rtw89_cam_get_avail_sec_cam(rtwdev, &sec_cam_idx, ext_key);
  247. if (ret) {
  248. rtw89_warn(rtwdev, "no available sec cam: %d ext: %d\n",
  249. ret, ext_key);
  250. return ret;
  251. }
  252. sec_cam = kzalloc(sizeof(*sec_cam), GFP_KERNEL);
  253. if (!sec_cam) {
  254. ret = -ENOMEM;
  255. goto err_release_cam;
  256. }
  257. sec_cam->sec_cam_idx = sec_cam_idx;
  258. sec_cam->type = hw_key_type;
  259. sec_cam->len = RTW89_SEC_CAM_LEN;
  260. sec_cam->ext_key = ext_key;
  261. memcpy(sec_cam->key, key->key, key->keylen);
  262. ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam);
  263. if (ret) {
  264. rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret);
  265. goto err_release_cam;
  266. }
  267. /* associate with addr cam */
  268. ret = rtw89_cam_attach_sec_cam(rtwdev, vif, sta, key, sec_cam);
  269. if (ret) {
  270. rtw89_err(rtwdev, "failed to attach sec cam: %d\n", ret);
  271. goto err_release_cam;
  272. }
  273. return 0;
  274. err_release_cam:
  275. kfree(sec_cam);
  276. clear_bit(sec_cam_idx, cam_info->sec_cam_map);
  277. if (ext_key)
  278. clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
  279. return ret;
  280. }
  281. int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
  282. struct ieee80211_vif *vif,
  283. struct ieee80211_sta *sta,
  284. struct ieee80211_key_conf *key)
  285. {
  286. const struct rtw89_chip_info *chip = rtwdev->chip;
  287. u8 hw_key_type;
  288. bool ext_key = false;
  289. int ret;
  290. switch (key->cipher) {
  291. case WLAN_CIPHER_SUITE_WEP40:
  292. hw_key_type = RTW89_SEC_KEY_TYPE_WEP40;
  293. break;
  294. case WLAN_CIPHER_SUITE_WEP104:
  295. hw_key_type = RTW89_SEC_KEY_TYPE_WEP104;
  296. break;
  297. case WLAN_CIPHER_SUITE_CCMP:
  298. hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128;
  299. key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
  300. break;
  301. case WLAN_CIPHER_SUITE_CCMP_256:
  302. hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256;
  303. key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
  304. ext_key = true;
  305. break;
  306. case WLAN_CIPHER_SUITE_GCMP:
  307. hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128;
  308. key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
  309. break;
  310. case WLAN_CIPHER_SUITE_GCMP_256:
  311. hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256;
  312. key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
  313. ext_key = true;
  314. break;
  315. default:
  316. return -EOPNOTSUPP;
  317. }
  318. if (!chip->hw_sec_hdr)
  319. key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
  320. ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type,
  321. ext_key);
  322. if (ret) {
  323. rtw89_err(rtwdev, "failed to install key type %d ext %d: %d\n",
  324. hw_key_type, ext_key, ret);
  325. return ret;
  326. }
  327. return 0;
  328. }
  329. int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
  330. struct ieee80211_vif *vif,
  331. struct ieee80211_sta *sta,
  332. struct ieee80211_key_conf *key,
  333. bool inform_fw)
  334. {
  335. struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
  336. struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
  337. struct rtw89_vif *rtwvif;
  338. struct rtw89_addr_cam_entry *addr_cam;
  339. struct rtw89_sec_cam_entry *sec_cam;
  340. u8 key_idx = key->hw_key_idx;
  341. u8 sec_cam_idx;
  342. int ret = 0;
  343. if (!vif) {
  344. rtw89_err(rtwdev, "No iface for deleting sec cam\n");
  345. return -EINVAL;
  346. }
  347. rtwvif = (struct rtw89_vif *)vif->drv_priv;
  348. addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
  349. sec_cam = addr_cam->sec_entries[key_idx];
  350. if (!sec_cam)
  351. return -EINVAL;
  352. /* detach sec cam from addr cam */
  353. clear_bit(key_idx, addr_cam->sec_cam_map);
  354. addr_cam->sec_entries[key_idx] = NULL;
  355. if (inform_fw) {
  356. ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
  357. if (ret)
  358. rtw89_err(rtwdev, "failed to update dctl cam del key: %d\n", ret);
  359. ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
  360. if (ret)
  361. rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
  362. }
  363. /* clear valid bit in addr cam will disable sec cam,
  364. * so we don't need to send H2C command again
  365. */
  366. sec_cam_idx = sec_cam->sec_cam_idx;
  367. clear_bit(sec_cam_idx, cam_info->sec_cam_map);
  368. if (sec_cam->ext_key)
  369. clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
  370. kfree(sec_cam);
  371. return ret;
  372. }
  373. static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw,
  374. struct ieee80211_vif *vif,
  375. struct ieee80211_sta *sta,
  376. struct ieee80211_key_conf *key,
  377. void *data)
  378. {
  379. struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
  380. rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false);
  381. }
  382. void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
  383. struct rtw89_addr_cam_entry *addr_cam)
  384. {
  385. struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
  386. addr_cam->valid = false;
  387. clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map);
  388. }
  389. void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
  390. struct rtw89_bssid_cam_entry *bssid_cam)
  391. {
  392. struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
  393. bssid_cam->valid = false;
  394. clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
  395. }
  396. void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
  397. {
  398. struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
  399. struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
  400. rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
  401. rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam);
  402. }
  403. void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev)
  404. {
  405. rcu_read_lock();
  406. ieee80211_iter_keys_rcu(rtwdev->hw, NULL, rtw89_cam_reset_key_iter, rtwdev);
  407. rcu_read_unlock();
  408. }
  409. static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev,
  410. u8 *addr_cam_idx)
  411. {
  412. const struct rtw89_chip_info *chip = rtwdev->chip;
  413. struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
  414. u8 addr_cam_num = chip->acam_num;
  415. u8 idx;
  416. idx = find_first_zero_bit(cam_info->addr_cam_map, addr_cam_num);
  417. if (idx >= addr_cam_num)
  418. return -EBUSY;
  419. set_bit(idx, cam_info->addr_cam_map);
  420. *addr_cam_idx = idx;
  421. return 0;
  422. }
  423. int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
  424. struct rtw89_addr_cam_entry *addr_cam,
  425. const struct rtw89_bssid_cam_entry *bssid_cam)
  426. {
  427. u8 addr_cam_idx;
  428. int i;
  429. int ret;
  430. if (unlikely(addr_cam->valid)) {
  431. rtw89_debug(rtwdev, RTW89_DBG_FW,
  432. "addr cam is already valid; skip init\n");
  433. return 0;
  434. }
  435. ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx);
  436. if (ret) {
  437. rtw89_err(rtwdev, "failed to get available addr cam\n");
  438. return ret;
  439. }
  440. addr_cam->addr_cam_idx = addr_cam_idx;
  441. addr_cam->len = ADDR_CAM_ENT_SIZE;
  442. addr_cam->offset = 0;
  443. addr_cam->valid = true;
  444. addr_cam->addr_mask = 0;
  445. addr_cam->mask_sel = RTW89_NO_MSK;
  446. addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
  447. bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
  448. for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
  449. addr_cam->sec_ent_keyid[i] = 0;
  450. addr_cam->sec_ent[i] = 0;
  451. }
  452. /* associate addr cam with bssid cam */
  453. addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx;
  454. return 0;
  455. }
  456. static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
  457. u8 *bssid_cam_idx)
  458. {
  459. const struct rtw89_chip_info *chip = rtwdev->chip;
  460. struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
  461. u8 bssid_cam_num = chip->bcam_num;
  462. u8 idx;
  463. idx = find_first_zero_bit(cam_info->bssid_cam_map, bssid_cam_num);
  464. if (idx >= bssid_cam_num)
  465. return -EBUSY;
  466. set_bit(idx, cam_info->bssid_cam_map);
  467. *bssid_cam_idx = idx;
  468. return 0;
  469. }
  470. int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
  471. struct rtw89_vif *rtwvif,
  472. struct rtw89_bssid_cam_entry *bssid_cam,
  473. const u8 *bssid)
  474. {
  475. u8 bssid_cam_idx;
  476. int ret;
  477. if (unlikely(bssid_cam->valid)) {
  478. rtw89_debug(rtwdev, RTW89_DBG_FW,
  479. "bssid cam is already valid; skip init\n");
  480. return 0;
  481. }
  482. ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx);
  483. if (ret) {
  484. rtw89_err(rtwdev, "failed to get available bssid cam\n");
  485. return ret;
  486. }
  487. bssid_cam->bssid_cam_idx = bssid_cam_idx;
  488. bssid_cam->phy_idx = rtwvif->phy_idx;
  489. bssid_cam->len = BSSID_CAM_ENT_SIZE;
  490. bssid_cam->offset = 0;
  491. bssid_cam->valid = true;
  492. ether_addr_copy(bssid_cam->bssid, bssid);
  493. return 0;
  494. }
  495. void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
  496. {
  497. struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
  498. ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
  499. }
  500. int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
  501. {
  502. struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
  503. struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
  504. int ret;
  505. ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, rtwvif->bssid);
  506. if (ret) {
  507. rtw89_err(rtwdev, "failed to init bssid cam\n");
  508. return ret;
  509. }
  510. ret = rtw89_cam_init_addr_cam(rtwdev, addr_cam, bssid_cam);
  511. if (ret) {
  512. rtw89_err(rtwdev, "failed to init addr cam\n");
  513. return ret;
  514. }
  515. return 0;
  516. }
  517. int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
  518. struct rtw89_vif *rtwvif,
  519. struct rtw89_sta *rtwsta, u8 *cmd)
  520. {
  521. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
  522. struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
  523. #endif
  524. struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
  525. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
  526. u8 bss_color = vif->bss_conf.he_bss_color.color;
  527. #else
  528. u8 bss_color = 0;
  529. #endif
  530. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
  531. u8 bss_mask;
  532. if (vif->bss_conf.nontransmitted)
  533. bss_mask = RTW89_BSSID_MATCH_5_BYTES;
  534. else
  535. bss_mask = RTW89_BSSID_MATCH_ALL;
  536. #endif
  537. FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
  538. FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
  539. FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
  540. FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid);
  541. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
  542. FWCMD_SET_ADDR_BSSID_MASK(cmd, bss_mask);
  543. #endif
  544. FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx);
  545. FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color);
  546. FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]);
  547. FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]);
  548. FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]);
  549. FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]);
  550. FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]);
  551. FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]);
  552. return 0;
  553. }
  554. static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
  555. {
  556. u8 hash = 0;
  557. u8 i;
  558. for (i = start; i < ETH_ALEN; i++)
  559. hash ^= addr[i];
  560. return hash;
  561. }
  562. void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
  563. struct rtw89_vif *rtwvif,
  564. struct rtw89_sta *rtwsta,
  565. const u8 *scan_mac_addr,
  566. u8 *cmd)
  567. {
  568. struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
  569. struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
  570. struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
  571. const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
  572. u8 sma_hash, tma_hash, addr_msk_start;
  573. u8 sma_start = 0;
  574. u8 tma_start = 0;
  575. u8 *tma = sta ? sta->addr : rtwvif->bssid;
  576. if (addr_cam->addr_mask != 0) {
  577. addr_msk_start = __ffs(addr_cam->addr_mask);
  578. if (addr_cam->mask_sel == RTW89_SMA)
  579. sma_start = addr_msk_start;
  580. else if (addr_cam->mask_sel == RTW89_TMA)
  581. tma_start = addr_msk_start;
  582. }
  583. sma_hash = rtw89_cam_addr_hash(sma_start, sma);
  584. tma_hash = rtw89_cam_addr_hash(tma_start, tma);
  585. FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx);
  586. FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset);
  587. FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
  588. FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
  589. FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
  590. FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
  591. FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
  592. FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
  593. FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
  594. FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
  595. FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
  596. FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash);
  597. FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx);
  598. FWCMD_SET_ADDR_SMA0(cmd, sma[0]);
  599. FWCMD_SET_ADDR_SMA1(cmd, sma[1]);
  600. FWCMD_SET_ADDR_SMA2(cmd, sma[2]);
  601. FWCMD_SET_ADDR_SMA3(cmd, sma[3]);
  602. FWCMD_SET_ADDR_SMA4(cmd, sma[4]);
  603. FWCMD_SET_ADDR_SMA5(cmd, sma[5]);
  604. FWCMD_SET_ADDR_TMA0(cmd, tma[0]);
  605. FWCMD_SET_ADDR_TMA1(cmd, tma[1]);
  606. FWCMD_SET_ADDR_TMA2(cmd, tma[2]);
  607. FWCMD_SET_ADDR_TMA3(cmd, tma[3]);
  608. FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
  609. FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
  610. FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
  611. FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
  612. FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
  613. FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
  614. FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
  615. FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
  616. FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
  617. if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
  618. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
  619. FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
  620. #else
  621. FWCMD_SET_ADDR_AID12(cmd, vif->bss_conf.aid & 0xfff);
  622. #endif
  623. else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
  624. FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
  625. FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
  626. FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
  627. FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
  628. FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
  629. FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
  630. FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
  631. FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]);
  632. FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]);
  633. FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]);
  634. FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]);
  635. FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]);
  636. FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]);
  637. FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff);
  638. FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]);
  639. FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]);
  640. FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]);
  641. FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]);
  642. FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
  643. FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
  644. FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
  645. }
  646. void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
  647. struct rtw89_vif *rtwvif,
  648. struct rtw89_sta *rtwsta,
  649. u8 *cmd)
  650. {
  651. struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
  652. SET_DCTL_MACID_V1(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
  653. SET_DCTL_OPERATION_V1(cmd, 1);
  654. SET_DCTL_SEC_ENT0_KEYID_V1(cmd, addr_cam->sec_ent_keyid[0]);
  655. SET_DCTL_SEC_ENT1_KEYID_V1(cmd, addr_cam->sec_ent_keyid[1]);
  656. SET_DCTL_SEC_ENT2_KEYID_V1(cmd, addr_cam->sec_ent_keyid[2]);
  657. SET_DCTL_SEC_ENT3_KEYID_V1(cmd, addr_cam->sec_ent_keyid[3]);
  658. SET_DCTL_SEC_ENT4_KEYID_V1(cmd, addr_cam->sec_ent_keyid[4]);
  659. SET_DCTL_SEC_ENT5_KEYID_V1(cmd, addr_cam->sec_ent_keyid[5]);
  660. SET_DCTL_SEC_ENT6_KEYID_V1(cmd, addr_cam->sec_ent_keyid[6]);
  661. SET_DCTL_SEC_ENT_VALID_V1(cmd, addr_cam->sec_cam_map[0] & 0xff);
  662. SET_DCTL_SEC_ENT0_V1(cmd, addr_cam->sec_ent[0]);
  663. SET_DCTL_SEC_ENT1_V1(cmd, addr_cam->sec_ent[1]);
  664. SET_DCTL_SEC_ENT2_V1(cmd, addr_cam->sec_ent[2]);
  665. SET_DCTL_SEC_ENT3_V1(cmd, addr_cam->sec_ent[3]);
  666. SET_DCTL_SEC_ENT4_V1(cmd, addr_cam->sec_ent[4]);
  667. SET_DCTL_SEC_ENT5_V1(cmd, addr_cam->sec_ent[5]);
  668. SET_DCTL_SEC_ENT6_V1(cmd, addr_cam->sec_ent[6]);
  669. }