wifi: rtw89: add support for HW encryption in unicast management frames

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
This commit is contained in:
Kuan-Chung Chen 2024-07-31 15:05:05 +08:00 committed by Ping-Ke Shih
parent 7dd5d2514a
commit 50961f8861
10 changed files with 40 additions and 15 deletions

View 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:

View 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)

View 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;

View 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;

View 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,

View 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,

View 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,

View 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,

View 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,

View 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,