| From b99c942620576c63baffd687090febea5ab2973d Mon Sep 17 00:00:00 2001 |
| From: mtk23510 <rudra.shahi@mediatek.com> |
| Date: Wed, 26 Apr 2023 20:08:10 +0800 |
| Subject: [PATCH 1009/1015] wifi: mt76: mt7996: Beacon protection feature added |
| |
| Signed-off-by: mtk23510 <rudra.shahi@mediatek.com> |
| Change-Id: I0149a65f71d844fc395c2827a54f9360492d181e |
| --- |
| mt76_connac_mcu.h | 16 +++++++++ |
| mt7996/main.c | 4 +++ |
| mt7996/mcu.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ |
| mt7996/mcu.h | 11 ++++++ |
| mt7996/mt7996.h | 2 ++ |
| 5 files changed, 119 insertions(+) |
| |
| diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| index 42246fb9..a53fa138 100644 |
| --- a/mt76_connac_mcu.h |
| +++ b/mt76_connac_mcu.h |
| @@ -415,6 +415,14 @@ struct sta_rec_he_6g_capa { |
| u8 rsv[2]; |
| } __packed; |
| |
| +struct sta_rec_pn_info { |
| + __le16 tag; |
| + __le16 len; |
| + u8 pn[6]; |
| + u8 tsc_type; |
| + u8 rsv; |
| +} __packed; |
| + |
| struct sec_key { |
| u8 cipher_id; |
| u8 cipher_len; |
| @@ -767,6 +775,7 @@ struct wtbl_raw { |
| sizeof(struct sta_rec_sec) + \ |
| sizeof(struct sta_rec_ra_fixed) + \ |
| sizeof(struct sta_rec_he_6g_capa) + \ |
| + sizeof(struct sta_rec_pn_info) + \ |
| sizeof(struct tlv) + \ |
| MT76_CONNAC_WTBL_UPDATE_MAX_SIZE) |
| |
| @@ -796,6 +805,7 @@ enum { |
| STA_REC_HE_6G = 0x17, |
| STA_REC_HE_V2 = 0x19, |
| STA_REC_EHT = 0x22, |
| + STA_REC_PN_INFO = 0x26, |
| STA_REC_HDRT = 0x28, |
| STA_REC_HDR_TRANS = 0x2B, |
| STA_REC_MAX_NUM |
| @@ -1077,6 +1087,11 @@ enum mcu_cipher_type { |
| MCU_CIPHER_GCMP_256, |
| MCU_CIPHER_WAPI, |
| MCU_CIPHER_BIP_CMAC_128, |
| + MCU_CIPHER_BIP_CMAC_256, |
| + MCU_CIPHER_BCN_PROT_CMAC_128, |
| + MCU_CIPHER_BCN_PROT_CMAC_256, |
| + MCU_CIPHER_BCN_PROT_GMAC_128, |
| + MCU_CIPHER_BCN_PROT_GMAC_256, |
| }; |
| |
| enum { |
| @@ -1295,6 +1310,7 @@ enum { |
| UNI_BSS_INFO_RATE = 11, |
| UNI_BSS_INFO_QBSS = 15, |
| UNI_BSS_INFO_SEC = 16, |
| + UNI_BSS_INFO_BCN_PROT = 17, |
| UNI_BSS_INFO_TXCMD = 18, |
| UNI_BSS_INFO_UAPSD = 19, |
| UNI_BSS_INFO_PS = 21, |
| diff --git a/mt7996/main.c b/mt7996/main.c |
| index d40d3047..d3d10fab 100644 |
| --- a/mt7996/main.c |
| +++ b/mt7996/main.c |
| @@ -400,6 +400,10 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| } |
| |
| mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| + |
| + if (key->keyidx == 6 || key->keyidx == 7) |
| + mt7996_mcu_bcn_prot_enable(dev, vif, key); |
| + |
| err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip, |
| key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE), |
| &msta->wcid, cmd); |
| diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| index 6add77da..53d2fc73 100644 |
| --- a/mt7996/mcu.c |
| +++ b/mt7996/mcu.c |
| @@ -2133,6 +2133,92 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true); |
| } |
| |
| +static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| + u8 *pn) |
| +{ |
| +#define TSC_TYPE_BIGTK_PN 2 |
| + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + struct sta_rec_pn_info *pn_info; |
| + struct sk_buff *skb, *rskb; |
| + struct tlv *tlv; |
| + int ret; |
| + |
| + skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid); |
| + if (IS_ERR(skb)) |
| + return PTR_ERR(skb); |
| + |
| + tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info)); |
| + pn_info = (struct sta_rec_pn_info *)tlv; |
| + |
| + pn_info->tsc_type = TSC_TYPE_BIGTK_PN; |
| + ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb, |
| + MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE), true, &rskb); |
| + if (ret) |
| + return ret; |
| + |
| + skb_pull(rskb, 4); |
| + |
| + pn_info = (struct sta_rec_pn_info *)rskb->data; |
| + if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO) |
| + memcpy(pn, pn_info->pn, 6); |
| + |
| + dev_kfree_skb(rskb); |
| + return 0; |
| +} |
| + |
| +int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| + struct ieee80211_key_conf *key) |
| +{ |
| +#define WPA_BIGTK_MAX_LEN 32 |
| + int len = sizeof(struct bss_req_hdr) + sizeof(struct mt7996_mcu_bcn_prot_tlv); |
| + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| + int ret; |
| + struct mt7996_mcu_bcn_prot_tlv *bcn_prot; |
| + struct sk_buff *skb; |
| + struct tlv *tlv; |
| + u8 pn[6] = {0}; |
| + |
| + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len); |
| + if (IS_ERR(skb)) |
| + return PTR_ERR(skb); |
| + |
| + tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT, |
| + sizeof(*bcn_prot)); |
| + |
| + bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv; |
| + |
| + ret = mt7996_mcu_get_pn(dev, vif, pn); |
| + if (ret) { |
| + dev_kfree_skb(skb); |
| + return ret; |
| + } |
| + |
| + switch(key->cipher){ |
| + case WLAN_CIPHER_SUITE_AES_CMAC: |
| + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128; |
| + break; |
| + case WLAN_CIPHER_SUITE_BIP_GMAC_128: |
| + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128; |
| + break; |
| + case WLAN_CIPHER_SUITE_BIP_GMAC_256: |
| + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256; |
| + break; |
| + case WLAN_CIPHER_SUITE_BIP_CMAC_256: |
| + default: |
| + dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n"); |
| + dev_kfree_skb(skb); |
| + return -EOPNOTSUPP; |
| + } |
| + |
| + pn[0]++; |
| + memcpy(bcn_prot->pn, pn, 6); |
| + bcn_prot->enable = 1; |
| + memcpy(bcn_prot->key, key->key, WPA_BIGTK_MAX_LEN); |
| + bcn_prot->key_id = key->keyidx; |
| + |
| + return mt76_mcu_skb_send_msg(&dev->mt76, skb, |
| + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); |
| +} |
| int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, |
| struct ieee80211_vif *vif, bool enable) |
| { |
| diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| index baffbcd7..f32ac153 100644 |
| --- a/mt7996/mcu.h |
| +++ b/mt7996/mcu.h |
| @@ -262,6 +262,17 @@ struct bss_rate_tlv { |
| u8 __rsv2[9]; |
| } __packed; |
| |
| +struct mt7996_mcu_bcn_prot_tlv { |
| + __le16 tag; |
| + __le16 len; |
| + u8 pn[6]; |
| + u8 enable; |
| + u8 cipher_id; |
| + u8 key[32]; |
| + u8 key_id; |
| + u8 __rsv[3]; |
| +} __packed; |
| + |
| struct bss_ra_tlv { |
| __le16 tag; |
| __le16 len; |
| diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| index c16bc8b4..94b62211 100644 |
| --- a/mt7996/mt7996.h |
| +++ b/mt7996/mt7996.h |
| @@ -710,6 +710,8 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| struct mt76_connac_sta_key_conf *sta_key_conf, |
| struct ieee80211_key_conf *key, int mcu_cmd, |
| struct mt76_wcid *wcid, enum set_key_cmd cmd); |
| +int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| + struct ieee80211_key_conf *key); |
| int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, |
| struct ieee80211_vif *vif, |
| struct ieee80211_sta *sta); |
| -- |
| 2.39.2 |
| |