wifi: rtw89: wow: parsing Auth Key Management from associate request
authorChih-Kang Chang <gary.chang@realtek.com>
Thu, 2 May 2024 02:24:56 +0000 (10:24 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Fri, 3 May 2024 23:58:28 +0000 (07:58 +0800)
Need Auth Key Management(AKM) to let firmware to generate appropriate
EAPoL packet for GTK rekey. The AKM is present in the association request
RSN IE to indicate which cipher that station selected.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://msgid.link/20240502022505.28966-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/wow.c
drivers/net/wireless/realtek/rtw89/wow.h

index dda69e8d114d3872f86efb5a2cc9f03bc860e636..e0bb0028a0d44719cfbe86e9cb872ec7a5f84686 100644 (file)
@@ -18,6 +18,7 @@
 #include "ser.h"
 #include "txrx.h"
 #include "util.h"
+#include "wow.h"
 
 static bool rtw89_disable_ps_mode;
 module_param_named(disable_ps_mode, rtw89_disable_ps_mode, bool, 0644);
@@ -255,6 +256,9 @@ static void rtw89_traffic_stats_accu(struct rtw89_dev *rtwdev,
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
+       if (tx && ieee80211_is_assoc_req(hdr->frame_control))
+               rtw89_wow_parse_akm(rtwdev, skb);
+
        if (!ieee80211_is_data(hdr->frame_control))
                return;
 
index 4007377d29ba518d9e8d42b0d798ccca2b78b09f..b8683a9075ad200d559a5c20e6b7821f3b3f099b 100644 (file)
@@ -5210,6 +5210,7 @@ struct rtw89_wow_param {
        DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM);
        struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM];
        u8 pattern_cnt;
+       u8 akm;
 };
 
 struct rtw89_mcc_limit {
index ea555f29442d66c771d78fcc8501a983c5210f56..dcae75128c7127aabffb96b0a5e0db8b822ddbf5 100644 (file)
 #include "util.h"
 #include "wow.h"
 
+void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
+{
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+       struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+       const u8 *rsn, *ies = mgmt->u.assoc_req.variable;
+       struct rtw89_rsn_ie *rsn_ie;
+
+       rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len);
+       if (!rsn)
+               return;
+
+       rsn_ie = (struct rtw89_rsn_ie *)rsn;
+       rtw_wow->akm = rsn_ie->akm_cipher_suite.type;
+}
+
 static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
 {
        __rtw89_leave_ps_mode(rtwdev);
index a2f7b2e3cdb4ddec7b183fbbbe01a23d74971dd7..d9cfd2beda397832f9973669153ba1f9195fbaf1 100644 (file)
@@ -15,7 +15,31 @@ enum rtw89_wake_reason {
        RTW89_WOW_RSN_RX_NLO = 0x55,
 };
 
+struct rtw89_cipher_suite {
+       u8 oui[3];
+       u8 type;
+} __packed;
+
+struct rtw89_rsn_ie {
+       u8 tag_number;
+       u8 tag_length;
+       __le16 rsn_version;
+       struct rtw89_cipher_suite group_cipher_suite;
+       __le16 pairwise_cipher_suite_cnt;
+       struct rtw89_cipher_suite pairwise_cipher_suite;
+       __le16 akm_cipher_suite_cnt;
+       struct rtw89_cipher_suite akm_cipher_suite;
+} __packed;
+
+#ifdef CONFIG_PM
 int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan);
 int rtw89_wow_resume(struct rtw89_dev *rtwdev);
+void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb);
+#else
+static inline
+void rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb)
+{
+}
+#endif
 
 #endif