wifi: rtw89: preparation for MLO including AP_LINK_PS feature, ieee80211_ops and links
Ping-Ke Shih
maintainerv3 cover wifi: rtw89: preparation for MLO including AP_LINK_PS feature, ieee80211_ops and links
Add more materials for MLO. First one is AP_LINK_PS feature. Then implement ieee80211_ops related to links. The last two are to consider link_id instead of -1.
v3:
- correct // style comment in patch 1/6
v2:
- rebase on top of tree. no other changes.
Zong-Zhe Yang (6):
wifi: rtw89: 8922a: configure AP_LINK_PS if FW supports
wifi: rtw89: register ops of can_activate_links
wifi: rtw89: implement ops of change vif/sta links
wifi: rtw89: apply MLD pairwise key to dynamically active links
wifi: rtw89: pass target link_id to ieee80211_gtk_rekey_add()
wifi: rtw89: pass target link_id to ieee80211_nullfunc_get()
drivers/net/wireless/realtek/rtw89/cam.c | 32 +- drivers/net/wireless/realtek/rtw89/cam.h | 5 + drivers/net/wireless/realtek/rtw89/core.c | 45 ++- drivers/net/wireless/realtek/rtw89/core.h | 59 ++++ drivers/net/wireless/realtek/rtw89/fw.c | 71 ++++- drivers/net/wireless/realtek/rtw89/fw.h | 19 ++ drivers/net/wireless/realtek/rtw89/mac.c | 50 ++++ drivers/net/wireless/realtek/rtw89/mac.h | 7 + drivers/net/wireless/realtek/rtw89/mac80211.c | 280 +++++++++++++++++- drivers/net/wireless/realtek/rtw89/ser.c | 1 + drivers/net/wireless/realtek/rtw89/wow.c | 5 +- 11 files changed, 560 insertions(+), 14 deletions(-)
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v3 1/6 wifi: rtw89: 8922a: configure AP_LINK_PS if FW supports
From: Zong-Zhe Yang <[email protected]>
After FW v0.35.46.0, for AP mode, RTL8922A FW supports a new FW feature, called NOTIFY_AP_INFO, to notify driver information related to AP mode. And, one function of it is to monitor PS states of remote stations. Once one of them changes, FW will send a C2H event to tell driver. With this FW feature, we can declare AP_LINK_PS.
For now, driver still needs to determine if a frame is ps-poll or U-APSD trigger. So, add the corresponding RX handling in driver, which activates only when at least one AP is running.
---
v3: correct // style comment
--- drivers/net/wireless/realtek/rtw89/core.c | 42 ++++++++++++ drivers/net/wireless/realtek/rtw89/core.h | 37 +++++++++++ drivers/net/wireless/realtek/rtw89/fw.c | 66 +++++++++++++++++++ drivers/net/wireless/realtek/rtw89/fw.h | 19 ++++++ drivers/net/wireless/realtek/rtw89/mac.c | 50 ++++++++++++++ drivers/net/wireless/realtek/rtw89/mac.h | 7 ++ drivers/net/wireless/realtek/rtw89/mac80211.c | 13 +++- drivers/net/wireless/realtek/rtw89/ser.c | 1 + 8 files changed, 234 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/core.c +42 -0
@@ -2749,6 +2749,41 @@ static void rtw89_core_flush_ppdu_rx_queue(struct rtw89_dev *rtwdev, } } +static +void rtw89_core_rx_pkt_hdl (struct rtw89_dev *rtwdev,const struct sk_buff *skb, +const struct rtw89_rx_desc_info *desc) +{ +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +struct rtw89_sta_link *rtwsta_link; +struct ieee80211_sta *sta; +struct rtw89_sta *rtwsta; +u8 macid = desc->mac_id; + +if (!refcount_read (&rtwdev->refcount_ap_info)) +return ; + +rcu_read_lock (); + + rtwsta_link =rtw89_assoc_link_rcu_dereference (rtwdev, macid); +if (!rtwsta_link) + goto out; + + rtwsta = rtwsta_link->rtwsta; +if (!test_bit (RTW89_REMOTE_STA_IN_PS , rtwsta->flags)) + goto out; + + sta =rtwsta_to_sta (rtwsta); +if (ieee80211_is_pspoll (hdr->frame_control)) +ieee80211_sta_pspoll (sta); +else if (ieee80211_has_pm (hdr->frame_control) && + (ieee80211_is_data_qos (hdr->frame_control) || +ieee80211_is_qos_nullfunc (hdr->frame_control))) +ieee80211_sta_uapsd_trigger (sta,ieee80211_get_tid (hdr)); + +out: +rcu_read_unlock (); +} +void rtw89_core_rx (struct rtw89_dev *rtwdev,struct rtw89_rx_desc_info *desc_info,struct sk_buff *skb)
@@ -2771,6 +2806,7 @@ void rtw89_core_rx(struct rtw89_dev *rtwdev, rx_status =IEEE80211_SKB_RXCB (skb);memset (rx_status,0 ,sizeof (*rx_status));rtw89_core_update_rx_status (rtwdev, desc_info, rx_status); +rtw89_core_rx_pkt_hdl (rtwdev, skb, desc_info);if (desc_info->long_rxdesc &&BIT (desc_info->frame_type) &PPDU_FILTER_BITMAP )skb_queue_tail (&ppdu_sts->rx_queue[band], skb);
@@ -3748,6 +3784,8 @@ int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev, {const struct ieee80211_vif *vif =rtwvif_link_to_vif (rtwvif_link); +rtw89_assoc_link_clr (rtwsta_link); +if (vif->type ==NL80211_IFTYPE_STATION )rtw89_fw_h2c_set_bcn_fltr_cfg (rtwdev, rtwvif_link, false);
@@ -3883,6 +3921,7 @@ int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,rtw89_fw_h2c_set_bcn_fltr_cfg (rtwdev, rtwvif_link, true); } +rtw89_assoc_link_set (rtwsta_link);return ret; }
@@ -5150,6 +5189,9 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)if (RTW89_CHK_FW_FEATURE (BEACON_FILTER , &rtwdev->fw))ieee80211_hw_set (hw,CONNECTION_MONITOR ); +if (RTW89_CHK_FW_FEATURE (NOTIFY_AP_INFO , &rtwdev->fw)) +ieee80211_hw_set (hw,AP_LINK_PS ); + hw->wiphy->interface_modes =BIT (NL80211_IFTYPE_STATION ) |BIT (NL80211_IFTYPE_AP ) | BIT(NL80211_IFTYPE_P2P_CLIENT) |
drivers/net/wireless/realtek/rtw89/core.h +37 -0
@@ -4452,6 +4452,7 @@ enum rtw89_fw_feature {RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0 ,RTW89_FW_FEATURE_RFK_RXDCK_V0 ,RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX , + RTW89_FW_FEATURE_NOTIFY_AP_INFO, }; struct rtw89_fw_suit {
@@ -5596,6 +5597,9 @@ struct rtw89_dev {struct rtw89_rfe_data *rfe_data;enum rtw89_custid custid; +struct rtw89_sta_link __rcu *assoc_link_on_macid[RTW89_MAX_MAC_ID_NUM ]; +refcount_t refcount_ap_info; +/* ensures exclusive access from mac80211 callbacks */ struct mutex mutex;struct list_head rtwvifs_list;
@@ -5730,10 +5734,18 @@ static inline bool rtw89_vif_assign_link_is_valid(struct rtw89_vif_link **rtwviffor (link_id =0 ; link_id <IEEE80211_MLD_MAX_NUM_LINKS ; link_id++) \if (rtw89_vif_assign_link_is_valid (&(rtwvif_link), rtwvif, link_id)) +enum rtw89_sta_flags { +RTW89_REMOTE_STA_IN_PS , + + NUM_OF_RTW89_STA_FLAGS, +}; +struct rtw89_sta {struct rtw89_dev *rtwdev;struct rtw89_vif *rtwvif; + DECLARE_BITMAP(flags, NUM_OF_RTW89_STA_FLAGS); +bool disassoc;struct sk_buff_head roc_queue;
@@ -5811,6 +5823,31 @@ u8 rtw89_sta_link_inst_get_index(struct rtw89_sta_link *rtwsta_link)return rtwsta_link - rtwsta->links_inst; } +static inline void rtw89_assoc_link_set (struct rtw89_sta_link *rtwsta_link) +{ +struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; +struct rtw89_dev *rtwdev = rtwsta->rtwdev; + +rcu_assign_pointer (rtwdev->assoc_link_on_macid[rtwsta_link->mac_id], + rtwsta_link); +} + +static inline void rtw89_assoc_link_clr (struct rtw89_sta_link *rtwsta_link) +{ +struct rtw89_sta *rtwsta = rtwsta_link->rtwsta; +struct rtw89_dev *rtwdev = rtwsta->rtwdev; + +rcu_assign_pointer (rtwdev->assoc_link_on_macid[rtwsta_link->mac_id], +NULL ); +synchronize_rcu (); +} + +static inline struct rtw89_sta_link * +rtw89_assoc_link_rcu_dereference (struct rtw89_dev *rtwdev,u8 macid) +{ +return rcu_dereference (rtwdev->assoc_link_on_macid[macid]); +} +static inline int rtw89_hci_tx_write (struct rtw89_dev *rtwdev,struct rtw89_core_tx_request *tx_req) {
drivers/net/wireless/realtek/rtw89/fw.c +66 -0
78 lines not on this page · raw message
drivers/net/wireless/realtek/rtw89/fw.h +19 -0
@@ -3466,6 +3466,12 @@ struct rtw89_h2c_wow_aoac {__le32 w0; } __packed; +struct rtw89_h2c_ap_info { +__le32 w0; +} __packed; + +#define RTW89_H2C_AP_INFO_W0_PWR_INT_EN BIT(0) +#define RTW89_C2H_HEADER_LEN 8struct rtw89_c2h_hdr {
@@ -3725,6 +3731,14 @@ struct rtw89_c2h_wow_aoac_report {#define RTW89_C2H_WOW_AOAC_RPT_REKEY_IDX BIT(0) +struct rtw89_c2h_pwr_int_notify { +struct rtw89_c2h_hdr hdr; +__le32 w2; +} __packed; + +#define RTW89_C2H_PWR_INT_NOTIFY_W2_MACID GENMASK(15, 0) +#define RTW89_C2H_PWR_INT_NOTIFY_W2_PWR_STATUS BIT(16) +struct rtw89_h2c_tx_duty {__le32 w0;__le32 w1;
@@ -4168,6 +4182,10 @@ enum rtw89_mrc_h2c_func { #define RTW89_MRC_WAIT_COND_REQ_TSF \ RTW89_MRC_WAIT_COND(0 /* don't care */, H2C_FUNC_MRC_REQ_TSF) +/* CLASS 36 - AP */ +#define H2C_CL_AP 0x24 +#define H2C_FUNC_AP_INFO 0x0 +#define H2C_CAT_OUTSRC 0x2#define H2C_CL_OUTSRC_RA 0x1
@@ -4697,6 +4715,7 @@ int rtw89_fw_h2c_mrc_sync(struct rtw89_dev *rtwdev, const struct rtw89_fw_mrc_sync_arg *arg);int rtw89_fw_h2c_mrc_upd_duration (struct rtw89_dev *rtwdev,const struct rtw89_fw_mrc_upd_duration_arg *arg); +int rtw89_fw_h2c_ap_info_refcount (struct rtw89_dev *rtwdev,bool en);static inline void rtw89_fw_h2c_init_ba_cam (struct rtw89_dev *rtwdev) {
drivers/net/wireless/realtek/rtw89/mac.c +50 -0
74 lines not on this page · raw message
drivers/net/wireless/realtek/rtw89/mac.h +7 -0
@@ -426,6 +426,12 @@ enum rtw89_mac_c2h_wow_func { NUM_OF_RTW89_MAC_C2H_FUNC_WOW, }; +enum rtw89_mac_c2h_ap_func { +RTW89_MAC_C2H_FUNC_PWR_INT_NOTIFY =0 , + +NUM_OF_RTW89_MAC_C2H_FUNC_AP , +}; +enum rtw89_mac_c2h_class {RTW89_MAC_C2H_CLASS_INFO =0x0 ,RTW89_MAC_C2H_CLASS_OFLD =0x1 ,
@@ -434,6 +440,7 @@ enum rtw89_mac_c2h_class {RTW89_MAC_C2H_CLASS_MCC =0x4 ,RTW89_MAC_C2H_CLASS_FWDBG =0x5 ,RTW89_MAC_C2H_CLASS_MRC =0xe , +RTW89_MAC_C2H_CLASS_AP =0x18 , RTW89_MAC_C2H_CLASS_MAX, };
drivers/net/wireless/realtek/rtw89/mac80211.c +12 -1
@@ -775,6 +775,7 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,struct rtw89_vif *rtwvif =vif_to_rtwvif (vif);struct rtw89_vif_link *rtwvif_link;const struct rtw89_chan *chan; +int ret =0 ;mutex_lock (&rtwdev->mutex);
@@ -783,6 +784,7 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,rtw89_err (rtwdev,"%s: rtwvif link (link_id %u) is not active\n" , __func__, link_conf->link_id); + ret = -ENOLINK ; goto out; }
@@ -804,12 +806,18 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,rtw89_fw_h2c_cam (rtwdev, rtwvif_link,NULL ,NULL );rtw89_chip_rfk_channel (rtwdev, rtwvif_link); +if (RTW89_CHK_FW_FEATURE (NOTIFY_AP_INFO , &rtwdev->fw)) { + ret =rtw89_fw_h2c_ap_info_refcount (rtwdev, true); +if (ret) + goto out; + } +rtw89_queue_chanctx_work (rtwdev); out:mutex_unlock (&rtwdev->mutex); -return 0 ; +return ret; } static
@@ -830,6 +838,9 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; } +if (RTW89_CHK_FW_FEATURE (NOTIFY_AP_INFO , &rtwdev->fw)) +rtw89_fw_h2c_ap_info_refcount (rtwdev, false); +rtw89_mac_stop_ap (rtwdev, rtwvif_link);rtw89_chip_h2c_assoc_cmac_tbl (rtwdev, rtwvif_link,NULL );rtw89_fw_h2c_join_info (rtwdev, rtwvif_link,NULL , true);
drivers/net/wireless/realtek/rtw89/ser.c +1 -0
@@ -365,6 +365,7 @@ static void ser_reset_mac_binding(struct rtw89_dev *rtwdev)ser_reset_vif (rtwdev, rtwvif); rtwdev->total_sta_assoc =0 ; +refcount_set (&rtwdev->refcount_ap_info,0 ); }/* hal function */
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerRe: [PATCH v3 1/6] wifi: rtw89: 8922a: configure AP_LINK_PS if FW supports
Quoted 8 lines · Ping-Ke Shih
From: Zong-Zhe Yang <[email protected]>
After FW v0.35.46.0, for AP mode, RTL8922A FW supports a new FW feature, called
NOTIFY_AP_INFO, to notify driver information related to AP mode. And, one function of it is to monitor PS states of remote stations. Once one of them changes, FW will send a C2H event to tell driver. With this FW feature, we can declareAP_LINK_PS.
Quoted 6 lines
For now, driver still needs to determine if a frame is ps-poll or U-APSD trigger. So, add the corresponding RX handling in driver, which activates only when at least one AP is running.
Signed-off-by Zong-Zhe Yang <[email protected]>Signed-off-by Ping-Ke Shih <[email protected]>
6 patch(es) applied to rtw-next branch of rtw.git, thanks.
144c6cd24b35 wifi: rtw89: 8922a: configure AP_LINK_PS if FW supports c821a8af435c wifi: rtw89: register ops of can_activate_links d2b387bdca46 wifi: rtw89: implement ops of change vif/sta links a6db83bef0f5 wifi: rtw89: apply MLD pairwise key to dynamically active links 55709b195464 wifi: rtw89: pass target link_id to ieee80211_gtk_rekey_add() f79257f5b971 wifi: rtw89: pass target link_id to ieee80211_nullfunc_get()
Ping-Ke Shih
maintainerPATCH v3 2/6 wifi: rtw89: register ops of can_activate_links
In reply to Ping-Ke ShihFrom: Zong-Zhe Yang <[email protected]>
Register mac80211 ops of can_activate_links which is required when we are ready to enable multiple active links.
--- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/mac80211.c | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+)
drivers/net/wireless/realtek/rtw89/core.h +1 -0
@@ -830,6 +830,7 @@ enum rtw89_phy_idx { };#define __RTW89_MLD_MAX_LINK_NUM 2 +#define RTW89_MLD_NON_STA_LINK_NUM 1enum rtw89_chanctx_idx {RTW89_CHANCTX_0 =0 ,
drivers/net/wireless/realtek/rtw89/mac80211.c +25 -0
@@ -1484,6 +1484,30 @@ static int rtw89_ops_set_tid_config(struct ieee80211_hw *hw,return 0 ; } +static bool rtw89_can_work_on_links (struct rtw89_dev *rtwdev, +struct ieee80211_vif *vif,u16 links) +{ +struct rtw89_vif *rtwvif =vif_to_rtwvif (vif); +u8 w =hweight16 (links); + +if (vif->type !=NL80211_IFTYPE_STATION && + w >RTW89_MLD_NON_STA_LINK_NUM ) +return false; + +return w <= rtwvif->links_inst_valid_num; +} + +static bool rtw89_ops_can_activate_links (struct ieee80211_hw *hw, +struct ieee80211_vif *vif, +u16 active_links) +{ +struct rtw89_dev *rtwdev = hw->priv; + +guard (mutex)(&rtwdev->mutex); + +return rtw89_can_work_on_links (rtwdev, vif, active_links); +} +#ifdef CONFIG_PM static int rtw89_ops_suspend (struct ieee80211_hw *hw,struct cfg80211_wowlan *wowlan)
@@ -1611,6 +1635,7 @@ const struct ieee80211_ops rtw89_ops = { .set_sar_specs = rtw89_ops_set_sar_specs, .link_sta_rc_update = rtw89_ops_sta_rc_update, .set_tid_config = rtw89_ops_set_tid_config, + .can_activate_links = rtw89_ops_can_activate_links, #ifdef CONFIG_PM .suspend = rtw89_ops_suspend, .resume = rtw89_ops_resume,
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v3 3/6 wifi: rtw89: implement ops of change vif/sta links
In reply to Ping-Ke ShihFrom: Zong-Zhe Yang <[email protected]>
To support MLO, implement change_vif_links() and change_sta_links() ops. Basically, we follow arguments to set/clear links. One special thing is that when vif is idle, i.e. no connection, link id 0 is set up by us for default uses. So, when bitmap of vif links change from 0x0 to non-zero, we clear the default one first. And when bitmap of vif links change from non-zero to 0x0, we set up a default one at the end.
--- drivers/net/wireless/realtek/rtw89/core.h | 17 ++ drivers/net/wireless/realtek/rtw89/mac80211.c | 226 +++++++++++++++++- 2 files changed, 238 insertions(+), 5 deletions(-)
drivers/net/wireless/realtek/rtw89/core.h +17 -0
@@ -5700,10 +5700,17 @@ struct rtw89_dev {u8 priv[]__aligned(sizeof(void *)) ; }; +struct rtw89_link_conf_container { +struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS ]; +}; + +#define RTW89_VIF_IDLE_LINK_ID 0 +struct rtw89_vif {struct rtw89_dev *rtwdev;struct list_head list;struct list_head mgnt_entry; +struct rtw89_link_conf_container __rcu *snap_link_confs;u8 mac_addr[ETH_ALEN ];__be32 ip_addr;
@@ -6273,9 +6280,19 @@ static inline struct ieee80211_bss_conf * __rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink) { struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); +struct rtw89_vif *rtwvif = rtwvif_link->rtwvif; +struct rtw89_link_conf_container *snap;struct ieee80211_bss_conf *bss_conf; + snap =rcu_dereference (rtwvif->snap_link_confs); +if (snap) { + bss_conf = snap->link_conf[rtwvif_link->link_id]; + goto out; + } + bss_conf =rcu_dereference (vif->link_conf[rtwvif_link->link_id]); + +out:if (unlikely (!bss_conf)) { *nolink = true;return &vif->bss_conf;
drivers/net/wireless/realtek/rtw89/mac80211.c +221 -5
264 lines not on this page · raw message
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v3 4/6 wifi: rtw89: apply MLD pairwise key to dynamically active links
In reply to Ping-Ke ShihFrom: Zong-Zhe Yang <[email protected]>
In MLD connection, a pairwise key should work on all active links. And, we take just one entry in security CAM for one pairwise key. (It means we will reuse one single entry for all links.) Originally, we already applied the security CAM entry of pairwise key to deflink's address CAM.
However, links can be activated dynamically. So now for pairwise keys, each rtw89_sta records the IDs of the security CAM entries. Then, when driver is notified that some links are active via change_sta_links(), we apply target pairwise keys to them according to the record.
--- drivers/net/wireless/realtek/rtw89/cam.c | 32 ++++++++++++++++--- drivers/net/wireless/realtek/rtw89/cam.h | 5 +++ drivers/net/wireless/realtek/rtw89/core.h | 4 +++ drivers/net/wireless/realtek/rtw89/mac80211.c | 16 ++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-)
drivers/net/wireless/realtek/rtw89/cam.c +28 -4
@@ -135,8 +135,8 @@ static int rtw89_cam_get_avail_sec_cam(struct rtw89_dev *rtwdev, }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);
drivers/net/wireless/realtek/rtw89/cam.h +5 -0
@@ -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
drivers/net/wireless/realtek/rtw89/core.h +4 -0
@@ -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 ];
drivers/net/wireless/realtek/rtw89/mac80211.c +16 -0
@@ -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 ;
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v3 5/6 wifi: rtw89: pass target link_id to ieee80211_gtk_rekey_add()
In reply to Ping-Ke ShihFrom: Zong-Zhe Yang <[email protected]>
When calling ieee80211_gtk_rekey_add(), pass the target link_id instead of always -1.
--- drivers/net/wireless/realtek/rtw89/wow.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/wow.c +4 -1
@@ -620,7 +620,10 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,* need to unlock mutex */ mutex_unlock (&rtwdev->mutex); - key =ieee80211_gtk_rekey_add (wow_vif, rekey_conf,-1 ); +if (ieee80211_vif_is_mld (wow_vif)) + key =ieee80211_gtk_rekey_add (wow_vif, rekey_conf, rtwvif_link->link_id); +else + key =ieee80211_gtk_rekey_add (wow_vif, rekey_conf,-1 );mutex_lock (&rtwdev->mutex);kfree (rekey_conf);
Signature · 1 line
2.25.1
Ping-Ke Shih
maintainerPATCH v3 6/6 wifi: rtw89: pass target link_id to ieee80211_nullfunc_get()
In reply to Ping-Ke ShihFrom: Zong-Zhe Yang <[email protected]>
When calling ieee80211_nullfunc_get(), pass the target link_id instead of always -1.
--- drivers/net/wireless/realtek/rtw89/core.c | 3 ++- drivers/net/wireless/realtek/rtw89/fw.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-)
drivers/net/wireless/realtek/rtw89/core.c +2 -1
@@ -3216,6 +3216,7 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool qos, bool ps) { struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); +int link_id =ieee80211_vif_is_mld (vif) ? rtwvif_link->link_id :-1 ;struct ieee80211_sta *sta;struct ieee80211_hdr *hdr;struct sk_buff *skb;
@@ -3231,7 +3232,7 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, goto out; } - skb =ieee80211_nullfunc_get (rtwdev->hw, vif,-1 , qos); + skb =ieee80211_nullfunc_get (rtwdev->hw, vif, link_id, qos);if (!skb) { ret = -ENOMEM ; goto out;
drivers/net/wireless/realtek/rtw89/fw.c +3 -2
@@ -2415,6 +2415,7 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, u8 *id) {struct ieee80211_vif *vif =rtwvif_link_to_vif (rtwvif_link); +int link_id =ieee80211_vif_is_mld (vif) ? rtwvif_link->link_id :-1 ;struct rtw89_pktofld_info *info;struct sk_buff *skb;int ret;
@@ -2431,10 +2432,10 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, skb =ieee80211_proberesp_get (rtwdev->hw, vif);break ;case RTW89_PKT_OFLD_TYPE_NULL_DATA : - skb =ieee80211_nullfunc_get (rtwdev->hw, vif,-1 , false); + skb =ieee80211_nullfunc_get (rtwdev->hw, vif, link_id, false);break ;case RTW89_PKT_OFLD_TYPE_QOS_NULL : - skb =ieee80211_nullfunc_get (rtwdev->hw, vif,-1 , true); + skb =ieee80211_nullfunc_get (rtwdev->hw, vif, link_id, true);break ;case RTW89_PKT_OFLD_TYPE_EAPOL_KEY : skb =rtw89_eapol_get (rtwdev, rtwvif_link);
Signature · 1 line
2.25.1