wifi: rtw89: add support for HW encryption in unicast management frames
authorKuan-Chung Chen <damon.chen@realtek.com>
Wed, 31 Jul 2024 07:05:05 +0000 (15:05 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Wed, 7 Aug 2024 03:04:59 +0000 (11:04 +0800)
Add hardware encryption support for unicast management frames for
8922AE and 8852CE. Other chips will continue to use software
encryption for unicast management frames.

Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240731070506.46100-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/cam.c
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index 4557c6e035a97488c8ed088c5776f133d6fc3685..4476fc7e53db74ab9e97eb39b119afd27cad97c1 100644 (file)
@@ -384,20 +384,24 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
                break;
        case WLAN_CIPHER_SUITE_CCMP:
                hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128;
-               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+               if (!chip->hw_mgmt_tx_encrypt)
+                       key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
                break;
        case WLAN_CIPHER_SUITE_CCMP_256:
                hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256;
-               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+               if (!chip->hw_mgmt_tx_encrypt)
+                       key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
                ext_key = true;
                break;
        case WLAN_CIPHER_SUITE_GCMP:
                hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128;
-               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+               if (!chip->hw_mgmt_tx_encrypt)
+                       key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
                break;
        case WLAN_CIPHER_SUITE_GCMP_256:
                hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256;
-               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+               if (!chip->hw_mgmt_tx_encrypt)
+                       key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
                ext_key = true;
                break;
        case WLAN_CIPHER_SUITE_AES_CMAC:
index 894b03d77a05c314db650de01e3b54fc67d0ba5b..a71c1147d3ce96b72bf71699e51dc8ded82f9d7d 100644 (file)
@@ -602,15 +602,28 @@ static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev,
        return rtwsta->mac_id;
 }
 
+static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev,
+                                        struct rtw89_tx_desc_info *desc_info,
+                                        struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr = (void *)skb->data;
+       __le16 fc = hdr->frame_control;
+
+       desc_info->hdr_llc_len = ieee80211_hdrlen(fc);
+       desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */
+}
+
 static void
 rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
                               struct rtw89_core_tx_request *tx_req)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
        struct ieee80211_vif *vif = tx_req->vif;
        struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
        struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
        const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
                                                       rtwvif->chanctx_idx);
+       struct sk_buff *skb = tx_req->skb;
        u8 qsel, ch_dma;
 
        qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : RTW89_TX_QSEL_B0_MGMT;
@@ -629,6 +642,11 @@ rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev,
        desc_info->dis_data_fb = true;
        desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req, chan);
 
+       if (chip->hw_mgmt_tx_encrypt && IEEE80211_SKB_CB(skb)->control.hw_key) {
+               rtw89_core_tx_update_sec_key(rtwdev, tx_req);
+               rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb);
+       }
+
        rtw89_debug(rtwdev, RTW89_DBG_TXRX,
                    "tx mgmt frame with rate 0x%x on channel %d (band %d, bw %d)\n",
                    desc_info->data_rate, chan->channel, chan->band_type,
@@ -862,17 +880,6 @@ rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev,
        return PACKET_MAX;
 }
 
-static void rtw89_core_tx_update_llc_hdr(struct rtw89_dev *rtwdev,
-                                        struct rtw89_tx_desc_info *desc_info,
-                                        struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr = (void *)skb->data;
-       __le16 fc = hdr->frame_control;
-
-       desc_info->hdr_llc_len = ieee80211_hdrlen(fc);
-       desc_info->hdr_llc_len >>= 1; /* in unit of 2 bytes */
-}
-
 static void
 rtw89_core_tx_wake(struct rtw89_dev *rtwdev,
                   struct rtw89_core_tx_request *tx_req)
index 7a3a31dfbab09c76f73858f7c6c8116c76cf1ec3..ecef3b154f3ef486104da8939eb40f8b8758e51e 100644 (file)
@@ -4183,6 +4183,7 @@ struct rtw89_chip_info {
        bool ul_tb_waveform_ctrl;
        bool ul_tb_pwr_diff;
        bool hw_sec_hdr;
+       bool hw_mgmt_tx_encrypt;
        u8 rf_path_num;
        u8 tx_nss;
        u8 rx_nss;
index 6c2cef134d9b689ddf10b29146ad8dd881da6748..149fb1b162394cdaf2b1956efd1eb4055d8e6bb1 100644 (file)
@@ -2032,11 +2032,16 @@ int rtw89_mac_resize_ple_rx_quota(struct rtw89_dev *rtwdev, bool wow)
 
 void rtw89_mac_hw_mgnt_sec(struct rtw89_dev *rtwdev, bool enable)
 {
+       const struct rtw89_chip_info *chip = rtwdev->chip;
        u32 msk32 = B_AX_UC_MGNT_DEC | B_AX_BMC_MGNT_DEC;
 
        if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
                return;
 
+       /* 8852C enable B_AX_UC_MGNT_DEC by default */
+       if (chip->chip_id == RTL8852C)
+               msk32 = B_AX_BMC_MGNT_DEC;
+
        if (enable)
                rtw89_write32_set(rtwdev, R_AX_SEC_ENG_CTRL, msk32);
        else
@@ -2261,6 +2266,8 @@ static int sec_eng_init_ax(struct rtw89_dev *rtwdev)
        /* init TX encryption */
        val |= (B_AX_SEC_TX_ENC | B_AX_SEC_RX_DEC);
        val |= (B_AX_MC_DEC | B_AX_BC_DEC);
+       if (chip->chip_id == RTL8852C)
+               val |= B_AX_UC_MGNT_DEC;
        if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
            chip->chip_id == RTL8851B)
                val &= ~B_AX_TX_PARTIAL_MODE;
index cfaea0193d35f08fda2ce9c5a07f55adf4c62e5d..e6463035a7af04da1261f9d8fa5da37a16f074ad 100644 (file)
@@ -2473,6 +2473,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
        .ul_tb_waveform_ctrl    = true,
        .ul_tb_pwr_diff         = false,
        .hw_sec_hdr             = false,
+       .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 1,
        .tx_nss                 = 1,
        .rx_nss                 = 1,
index ec9f7bc5c6d2b98b7ee6bd64283d5db5fb2b17ce..7ea388fa06574f9591f02f7856bec1c51d849fdc 100644 (file)
@@ -2188,6 +2188,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
        .ul_tb_waveform_ctrl    = false,
        .ul_tb_pwr_diff         = false,
        .hw_sec_hdr             = false,
+       .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 2,
        .tx_nss                 = 2,
        .rx_nss                 = 2,
index 71c166202560e43611d887c72d96e8d9db376a43..f26979b89cc9af8c42cf40816cf045c047f71561 100644 (file)
@@ -828,6 +828,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
        .ul_tb_waveform_ctrl    = true,
        .ul_tb_pwr_diff         = false,
        .hw_sec_hdr             = false,
+       .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 2,
        .tx_nss                 = 2,
        .rx_nss                 = 2,
index 9aa2106a64b762163e66b7353bd84cefd26dbb7f..fb98ef9dbc54910ac1a19eeedcb3ce50e0199e25 100644 (file)
@@ -761,6 +761,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
        .ul_tb_waveform_ctrl    = true,
        .ul_tb_pwr_diff         = false,
        .hw_sec_hdr             = false,
+       .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 2,
        .tx_nss                 = 2,
        .rx_nss                 = 2,
index e0c1cf8811a2fb4b8753dcfbff2e533986dfa8fb..d9d7b3ff338aff4bbc1ffbed8c14b965715078d5 100644 (file)
@@ -2969,6 +2969,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
        .ul_tb_waveform_ctrl    = false,
        .ul_tb_pwr_diff         = true,
        .hw_sec_hdr             = true,
+       .hw_mgmt_tx_encrypt     = true,
        .rf_path_num            = 2,
        .tx_nss                 = 2,
        .rx_nss                 = 2,
index 554b21e77e6473e7bcd4a1e346ed8c0508344750..6004a622d2448e52eeeca67204408ecca59df669 100644 (file)
@@ -2572,6 +2572,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
        .ul_tb_waveform_ctrl    = false,
        .ul_tb_pwr_diff         = false,
        .hw_sec_hdr             = true,
+       .hw_mgmt_tx_encrypt     = true,
        .rf_path_num            = 2,
        .tx_nss                 = 2,
        .rx_nss                 = 2,