diff options
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/cam.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/cam.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/core.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/mac80211.c | 16 |
4 files changed, 53 insertions, 4 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 8ef59994c0db..8fa1e6c1ce13 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -135,8 +135,8 @@ again: } static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam, - struct rtw89_sec_cam_entry *sec_cam, - struct ieee80211_key_conf *key, + const struct rtw89_sec_cam_entry *sec_cam, + const struct ieee80211_key_conf *key, u8 *key_idx) { u8 idx; @@ -246,8 +246,8 @@ static int __rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link, - struct ieee80211_key_conf *key, - struct rtw89_sec_cam_entry *sec_cam) + const struct ieee80211_key_conf *key, + const struct rtw89_sec_cam_entry *sec_cam) { struct rtw89_addr_cam_entry *addr_cam; u8 key_idx = 0; @@ -286,6 +286,22 @@ static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, return 0; } +int rtw89_cam_attach_link_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + u8 sec_cam_idx) +{ + struct rtw89_cam_info *cam_info = &rtwdev->cam_info; + const struct rtw89_sec_cam_entry *sec_cam; + + sec_cam = cam_info->sec_entries[sec_cam_idx]; + if (!sec_cam) + return -ENOENT; + + return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link, rtwsta_link, + sec_cam->key_conf, sec_cam); +} + static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -306,6 +322,9 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev, rtwvif = vif_to_rtwvif(vif); + if (rtwsta) + clear_bit(sec_cam->sec_cam_idx, rtwsta->pairwise_sec_cam_map); + rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) { rtwsta_link = rtwsta ? rtwsta->links[link_id] : NULL; if (rtwsta && !rtwsta_link) @@ -369,6 +388,8 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev, return ret; } + set_bit(sec_cam->sec_cam_idx, rtwsta->pairwise_sec_cam_map); + return 0; } @@ -410,6 +431,9 @@ static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev, sec_cam->len = RTW89_SEC_CAM_LEN; sec_cam->ext_key = ext_key; memcpy(sec_cam->key, key->key, key->keylen); + + sec_cam->key_conf = key; + ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam); if (ret) { rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret); diff --git a/drivers/net/wireless/realtek/rtw89/cam.h b/drivers/net/wireless/realtek/rtw89/cam.h index 3134ebf08825..8fd2d776408e 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.h +++ b/drivers/net/wireless/realtek/rtw89/cam.h @@ -578,4 +578,9 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev, void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev); +int rtw89_cam_attach_link_sec_cam(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link, + struct rtw89_sta_link *rtwsta_link, + u8 sec_cam_idx); + #endif diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index bcfefd7fa01e..409cbdc6b92a 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3359,6 +3359,8 @@ struct rtw89_sec_cam_entry { u8 spp_mode : 1; /* 256 bits */ u8 key[32]; + + struct ieee80211_key_conf *key_conf; }; struct rtw89_sta_link { @@ -5761,6 +5763,8 @@ struct rtw89_sta { struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS]; DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS); + DECLARE_BITMAP(pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM); + u8 links_inst_valid_num; DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM); struct rtw89_sta_link *links[IEEE80211_MLD_MAX_NUM_LINKS]; diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index a4e47ef22b9b..bf7a674bce28 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -509,6 +509,7 @@ static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev, rtw89_core_txq_init(rtwdev, sta->txq[i]); skb_queue_head_init(&rtwsta->roc_queue); + bitmap_zero(rtwsta->pairwise_sec_cam_map, RTW89_MAX_SEC_CAM_NUM); rtwsta_link = rtw89_sta_set_link(rtwsta, sta->deflink.link_id); if (!rtwsta_link) { @@ -1656,6 +1657,7 @@ static int __rtw89_ops_set_sta_links(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link; struct rtw89_sta_link *rtwsta_link; unsigned int link_id; + u8 sec_cam_idx; int ret; for_each_set_bit(link_id, &set_links, IEEE80211_MLD_MAX_NUM_LINKS) { @@ -1682,6 +1684,20 @@ static int __rtw89_ops_set_sta_links(struct rtw89_dev *rtwdev, } __rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link); + + for_each_set_bit(sec_cam_idx, rtwsta->pairwise_sec_cam_map, + RTW89_MAX_SEC_CAM_NUM) { + ret = rtw89_cam_attach_link_sec_cam(rtwdev, + rtwvif_link, + rtwsta_link, + sec_cam_idx); + if (ret) { + rtw89_err(rtwdev, + "%s: failed to apply pairwise key (link id %u)\n", + __func__, link_id); + return ret; + } + } } return 0; |