提交 79a6c9a4 编写于 作者: P Ping-Ke Shih 提交者: Kalle Valo

rtw89: support hardware generate security header

The newer chip will generate security header itself, so don't set
IEEE80211_KEY_FLAG_GENERATE_IV in this kind of chip. But, it needs to fill
key_index, PN and 802.11 header length to TX descriptor, and then hardware
uses these to generate security header.
Signed-off-by: NPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: NKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220318023214.32411-11-pkshih@realtek.com
上级 f59acdde
...@@ -320,6 +320,7 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, ...@@ -320,6 +320,7 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key) struct ieee80211_key_conf *key)
{ {
const struct rtw89_chip_info *chip = rtwdev->chip;
u8 hw_key_type; u8 hw_key_type;
bool ext_key = false; bool ext_key = false;
int ret; int ret;
...@@ -353,6 +354,7 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, ...@@ -353,6 +354,7 @@ int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (!chip->hw_sec_hdr)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type, ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type,
......
...@@ -435,6 +435,7 @@ static void ...@@ -435,6 +435,7 @@ static void
rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req) struct rtw89_core_tx_request *tx_req)
{ {
const struct rtw89_chip_info *chip = rtwdev->chip;
struct ieee80211_vif *vif = tx_req->vif; struct ieee80211_vif *vif = tx_req->vif;
struct ieee80211_sta *sta = tx_req->sta; struct ieee80211_sta *sta = tx_req->sta;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
...@@ -446,6 +447,7 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, ...@@ -446,6 +447,7 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
struct sk_buff *skb = tx_req->skb; struct sk_buff *skb = tx_req->skb;
u8 sec_type = RTW89_SEC_KEY_TYPE_NONE; u8 sec_type = RTW89_SEC_KEY_TYPE_NONE;
u64 pn64;
if (!vif) { if (!vif) {
rtw89_warn(rtwdev, "cannot set sec key without vif\n"); rtw89_warn(rtwdev, "cannot set sec key without vif\n");
...@@ -491,8 +493,21 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev, ...@@ -491,8 +493,21 @@ rtw89_core_tx_update_sec_key(struct rtw89_dev *rtwdev,
} }
desc_info->sec_en = true; desc_info->sec_en = true;
desc_info->sec_keyid = key->keyidx;
desc_info->sec_type = sec_type; desc_info->sec_type = sec_type;
desc_info->sec_cam_idx = sec_cam->sec_cam_idx; desc_info->sec_cam_idx = sec_cam->sec_cam_idx;
if (!chip->hw_sec_hdr)
return;
pn64 = atomic64_inc_return(&key->tx_pn);
desc_info->sec_seq[0] = pn64;
desc_info->sec_seq[1] = pn64 >> 8;
desc_info->sec_seq[2] = pn64 >> 16;
desc_info->sec_seq[3] = pn64 >> 24;
desc_info->sec_seq[4] = pn64 >> 32;
desc_info->sec_seq[5] = pn64 >> 40;
desc_info->wp_offset = 1; /* in unit of 8 bytes for security header */
} }
static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev, static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
...@@ -755,6 +770,17 @@ rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev, ...@@ -755,6 +770,17 @@ rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev,
return PACKET_MAX; 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 static void
rtw89_core_tx_wake(struct rtw89_dev *rtwdev, rtw89_core_tx_wake(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req) struct rtw89_core_tx_request *tx_req)
...@@ -806,6 +832,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, ...@@ -806,6 +832,7 @@ rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev,
rtw89_core_tx_update_data_info(rtwdev, tx_req); rtw89_core_tx_update_data_info(rtwdev, tx_req);
pkt_type = rtw89_core_tx_btc_spec_pkt_notify(rtwdev, tx_req); pkt_type = rtw89_core_tx_btc_spec_pkt_notify(rtwdev, tx_req);
rtw89_core_tx_update_he_qos_htc(rtwdev, tx_req, pkt_type); rtw89_core_tx_update_he_qos_htc(rtwdev, tx_req, pkt_type);
rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb);
break; break;
case RTW89_CORE_TX_TYPE_FWCMD: case RTW89_CORE_TX_TYPE_FWCMD:
rtw89_core_tx_update_h2c_info(rtwdev, tx_req); rtw89_core_tx_update_h2c_info(rtwdev, tx_req);
...@@ -912,6 +939,7 @@ static __le32 rtw89_build_txwd_body0_v1(struct rtw89_tx_desc_info *desc_info) ...@@ -912,6 +939,7 @@ static __le32 rtw89_build_txwd_body0_v1(struct rtw89_tx_desc_info *desc_info)
static __le32 rtw89_build_txwd_body1_v1(struct rtw89_tx_desc_info *desc_info) static __le32 rtw89_build_txwd_body1_v1(struct rtw89_tx_desc_info *desc_info)
{ {
u32 dword = FIELD_PREP(RTW89_TXWD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) | u32 dword = FIELD_PREP(RTW89_TXWD_BODY1_ADDR_INFO_NUM, desc_info->addr_info_nr) |
FIELD_PREP(RTW89_TXWD_BODY1_SEC_KEYID, desc_info->sec_keyid) |
FIELD_PREP(RTW89_TXWD_BODY1_SEC_TYPE, desc_info->sec_type); FIELD_PREP(RTW89_TXWD_BODY1_SEC_TYPE, desc_info->sec_type);
return cpu_to_le32(dword); return cpu_to_le32(dword);
...@@ -936,6 +964,24 @@ static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info) ...@@ -936,6 +964,24 @@ static __le32 rtw89_build_txwd_body3(struct rtw89_tx_desc_info *desc_info)
return cpu_to_le32(dword); return cpu_to_le32(dword);
} }
static __le32 rtw89_build_txwd_body4(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L0, desc_info->sec_seq[0]) |
FIELD_PREP(RTW89_TXWD_BODY4_SEC_IV_L1, desc_info->sec_seq[1]);
return cpu_to_le32(dword);
}
static __le32 rtw89_build_txwd_body5(struct rtw89_tx_desc_info *desc_info)
{
u32 dword = FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H2, desc_info->sec_seq[2]) |
FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H3, desc_info->sec_seq[3]) |
FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H4, desc_info->sec_seq[4]) |
FIELD_PREP(RTW89_TXWD_BODY5_SEC_IV_H5, desc_info->sec_seq[5]);
return cpu_to_le32(dword);
}
static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info) static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info)
{ {
u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) | u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) |
...@@ -1032,6 +1078,10 @@ void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev, ...@@ -1032,6 +1078,10 @@ void rtw89_core_fill_txdesc_v1(struct rtw89_dev *rtwdev,
txwd_body->dword1 = rtw89_build_txwd_body1_v1(desc_info); txwd_body->dword1 = rtw89_build_txwd_body1_v1(desc_info);
txwd_body->dword2 = rtw89_build_txwd_body2(desc_info); txwd_body->dword2 = rtw89_build_txwd_body2(desc_info);
txwd_body->dword3 = rtw89_build_txwd_body3(desc_info); txwd_body->dword3 = rtw89_build_txwd_body3(desc_info);
if (desc_info->sec_en) {
txwd_body->dword4 = rtw89_build_txwd_body4(desc_info);
txwd_body->dword5 = rtw89_build_txwd_body5(desc_info);
}
txwd_body->dword7 = rtw89_build_txwd_body7_v1(desc_info); txwd_body->dword7 = rtw89_build_txwd_body7_v1(desc_info);
if (!desc_info->en_wd_info) if (!desc_info->en_wd_info)
......
...@@ -733,8 +733,10 @@ struct rtw89_tx_desc_info { ...@@ -733,8 +733,10 @@ struct rtw89_tx_desc_info {
u8 ampdu_num; u8 ampdu_num;
bool sec_en; bool sec_en;
u8 addr_info_nr; u8 addr_info_nr;
u8 sec_keyid;
u8 sec_type; u8 sec_type;
u8 sec_cam_idx; u8 sec_cam_idx;
u8 sec_seq[6];
u16 data_rate; u16 data_rate;
u16 data_retry_lowest_rate; u16 data_retry_lowest_rate;
bool fw_dl; bool fw_dl;
...@@ -2302,6 +2304,7 @@ struct rtw89_chip_info { ...@@ -2302,6 +2304,7 @@ struct rtw89_chip_info {
u32 rf_base_addr[2]; u32 rf_base_addr[2];
u8 support_bands; u8 support_bands;
bool support_bw160; bool support_bw160;
bool hw_sec_hdr;
u8 rf_path_num; u8 rf_path_num;
u8 tx_nss; u8 tx_nss;
u8 rx_nss; u8 rx_nss;
......
...@@ -2066,6 +2066,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { ...@@ -2066,6 +2066,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.support_bands = BIT(NL80211_BAND_2GHZ) | .support_bands = BIT(NL80211_BAND_2GHZ) |
BIT(NL80211_BAND_5GHZ), BIT(NL80211_BAND_5GHZ),
.support_bw160 = false, .support_bw160 = false,
.hw_sec_hdr = false,
.rf_path_num = 2, .rf_path_num = 2,
.tx_nss = 2, .tx_nss = 2,
.rx_nss = 2, .rx_nss = 2,
......
...@@ -508,6 +508,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { ...@@ -508,6 +508,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.rf_base_addr = {0xe000, 0xf000}, .rf_base_addr = {0xe000, 0xf000},
.pwr_on_seq = NULL, .pwr_on_seq = NULL,
.pwr_off_seq = NULL, .pwr_off_seq = NULL,
.hw_sec_hdr = true,
.sec_ctrl_efuse_size = 4, .sec_ctrl_efuse_size = 4,
.physical_efuse_size = 1216, .physical_efuse_size = 1216,
.logical_efuse_size = 2048, .logical_efuse_size = 2048,
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
/* TX WD BODY DWORD 1 */ /* TX WD BODY DWORD 1 */
#define RTW89_TXWD_BODY1_ADDR_INFO_NUM GENMASK(31, 26) #define RTW89_TXWD_BODY1_ADDR_INFO_NUM GENMASK(31, 26)
#define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16) #define RTW89_TXWD_BODY1_PAYLOAD_ID GENMASK(31, 16)
#define RTW89_TXWD_BODY1_SEC_KEYID GENMASK(5, 4)
#define RTW89_TXWD_BODY1_SEC_TYPE GENMASK(3, 0) #define RTW89_TXWD_BODY1_SEC_TYPE GENMASK(3, 0)
/* TX WD BODY DWORD 2 */ /* TX WD BODY DWORD 2 */
...@@ -52,8 +53,14 @@ ...@@ -52,8 +53,14 @@
#define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0) #define RTW89_TXWD_BODY3_SW_SEQ GENMASK(11, 0)
/* TX WD BODY DWORD 4 */ /* TX WD BODY DWORD 4 */
#define RTW89_TXWD_BODY4_SEC_IV_L1 GENMASK(31, 24)
#define RTW89_TXWD_BODY4_SEC_IV_L0 GENMASK(23, 16)
/* TX WD BODY DWORD 5 */ /* TX WD BODY DWORD 5 */
#define RTW89_TXWD_BODY5_SEC_IV_H5 GENMASK(31, 24)
#define RTW89_TXWD_BODY5_SEC_IV_H4 GENMASK(23, 16)
#define RTW89_TXWD_BODY5_SEC_IV_H3 GENMASK(15, 8)
#define RTW89_TXWD_BODY5_SEC_IV_H2 GENMASK(7, 0)
/* TX WD BODY DWORD 6 (V1) */ /* TX WD BODY DWORD 6 (V1) */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册