wifi: rtw89: wow: add GTK rekey feature related H2C commands
authorChih-Kang Chang <gary.chang@realtek.com>
Thu, 2 May 2024 02:25:01 +0000 (10:25 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Sat, 4 May 2024 00:03:50 +0000 (08:03 +0800)
Add PTK TRX IV, GTK RX IV, key encryption algorithm to H2C command to
enable GTK rekey feature.

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-9-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/cam.c
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/wow.c

index 9581cd108298fd750495cc18223123dba5b57257..67f13e4c3d159302d64cc19b3cc57681bd89cdc7 100644 (file)
@@ -756,6 +756,8 @@ void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
                                         struct rtw89_h2c_dctlinfo_ud_v1 *h2c)
 {
        struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
+       struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+       u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
 
        h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
                                   DCTLINFO_V1_C0_MACID) |
@@ -808,6 +810,23 @@ void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
                              DCTLINFO_V1_W6_SEC_ENT4 |
                              DCTLINFO_V1_W6_SEC_ENT5 |
                              DCTLINFO_V1_W6_SEC_ENT6);
+
+       if (rtw_wow->ptk_alg) {
+               h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8,
+                                          DCTLINFO_V1_W0_AES_IV_L);
+               h2c->m0 = cpu_to_le32(DCTLINFO_V1_W0_AES_IV_L);
+
+               h2c->w1 = le32_encode_bits(ptk_tx_iv[4]       |
+                                          ptk_tx_iv[5] << 8  |
+                                          ptk_tx_iv[6] << 16 |
+                                          ptk_tx_iv[7] << 24,
+                                          DCTLINFO_V1_W1_AES_IV_H);
+               h2c->m1 = cpu_to_le32(DCTLINFO_V1_W1_AES_IV_H);
+
+               h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx,
+                                           DCTLINFO_V1_W4_SEC_KEY_ID);
+               h2c->m4 |= cpu_to_le32(DCTLINFO_V1_W4_SEC_KEY_ID);
+       }
 }
 
 void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
@@ -816,6 +835,8 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
                                         struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
 {
        struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
+       struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+       u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
 
        h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
                                   DCTLINFO_V2_C0_MACID) |
@@ -869,4 +890,21 @@ void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
                                   DCTLINFO_V2_W7_SEC_ENT6_V1);
        h2c->m7 = cpu_to_le32(DCTLINFO_V2_W7_SEC_ENT5_V1 |
                              DCTLINFO_V2_W7_SEC_ENT6_V1);
+
+       if (rtw_wow->ptk_alg) {
+               h2c->w0 = le32_encode_bits(ptk_tx_iv[0] | ptk_tx_iv[1] << 8,
+                                          DCTLINFO_V2_W0_AES_IV_L);
+               h2c->m0 = cpu_to_le32(DCTLINFO_V2_W0_AES_IV_L);
+
+               h2c->w1 = le32_encode_bits(ptk_tx_iv[4] |
+                                          ptk_tx_iv[5] << 8 |
+                                          ptk_tx_iv[6] << 16 |
+                                          ptk_tx_iv[7] << 24,
+                                          DCTLINFO_V2_W1_AES_IV_H);
+               h2c->m1 = cpu_to_le32(DCTLINFO_V2_W1_AES_IV_H);
+
+               h2c->w4 |= le32_encode_bits(rtw_wow->ptk_keyidx,
+                                           DCTLINFO_V2_W4_SEC_KEY_ID);
+               h2c->m4 |= cpu_to_le32(DCTLINFO_V2_W4_SEC_KEY_ID);
+       }
 }
index a7ae5f85d57dc2c5fdaae615e5028823747c4a7b..f47bdede6c628abda312da0bca1ad6d4a5154bea 100644 (file)
@@ -6404,6 +6404,7 @@ fail:
 int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
                            bool enable)
 {
+       struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
        struct rtw89_h2c_wow_global *h2c;
        u8 macid = rtwvif->mac_id;
        u32 len = sizeof(*h2c);
@@ -6420,7 +6421,12 @@ int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
        h2c = (struct rtw89_h2c_wow_global *)skb->data;
 
        h2c->w0 = le32_encode_bits(enable, RTW89_H2C_WOW_GLOBAL_W0_ENABLE) |
-                 le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID);
+                 le32_encode_bits(macid, RTW89_H2C_WOW_GLOBAL_W0_MAC_ID) |
+                 le32_encode_bits(rtw_wow->ptk_alg,
+                                  RTW89_H2C_WOW_GLOBAL_W0_PAIRWISE_SEC_ALGO) |
+                 le32_encode_bits(rtw_wow->gtk_alg,
+                                  RTW89_H2C_WOW_GLOBAL_W0_GROUP_SEC_ALGO);
+       h2c->key_info = rtw_wow->key_info;
 
        rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
                              H2C_CAT_MAC,
index 185e24626691c787d4011e230869c1905d2bd8c4..3fb352f65e6705548e0d16ce5476a69ec2b5dd8f 100644 (file)
@@ -845,6 +845,12 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
                goto out;
        }
 
+       ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, true);
+       if (ret) {
+               rtw89_err(rtwdev, "wow: failed to enable GTK offload\n");
+               goto out;
+       }
+
        ret = rtw89_wow_cfg_wake(rtwdev, true);
        if (ret) {
                rtw89_err(rtwdev, "wow: failed to config wake\n");
@@ -881,6 +887,12 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
                goto out;
        }
 
+       ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, false);
+       if (ret) {
+               rtw89_err(rtwdev, "wow: failed to disable GTK offload\n");
+               goto out;
+       }
+
        rtw89_fw_release_general_pkt_list(rtwdev, true);
 
        ret = rtw89_wow_cfg_wake(rtwdev, false);