developer | 692ed9b | 2023-06-19 12:03:50 +0800 | [diff] [blame] | 1 | From b99c942620576c63baffd687090febea5ab2973d Mon Sep 17 00:00:00 2001 |
| 2 | From: mtk23510 <rudra.shahi@mediatek.com> |
| 3 | Date: Wed, 26 Apr 2023 20:08:10 +0800 |
| 4 | Subject: [PATCH 1009/1015] wifi: mt76: mt7996: Beacon protection feature added |
| 5 | |
| 6 | Signed-off-by: mtk23510 <rudra.shahi@mediatek.com> |
| 7 | Change-Id: I0149a65f71d844fc395c2827a54f9360492d181e |
| 8 | --- |
| 9 | mt76_connac_mcu.h | 16 +++++++++ |
| 10 | mt7996/main.c | 4 +++ |
| 11 | mt7996/mcu.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ |
| 12 | mt7996/mcu.h | 11 ++++++ |
| 13 | mt7996/mt7996.h | 2 ++ |
| 14 | 5 files changed, 119 insertions(+) |
| 15 | |
| 16 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| 17 | index 42246fb9..a53fa138 100644 |
| 18 | --- a/mt76_connac_mcu.h |
| 19 | +++ b/mt76_connac_mcu.h |
| 20 | @@ -415,6 +415,14 @@ struct sta_rec_he_6g_capa { |
| 21 | u8 rsv[2]; |
| 22 | } __packed; |
| 23 | |
| 24 | +struct sta_rec_pn_info { |
| 25 | + __le16 tag; |
| 26 | + __le16 len; |
| 27 | + u8 pn[6]; |
| 28 | + u8 tsc_type; |
| 29 | + u8 rsv; |
| 30 | +} __packed; |
| 31 | + |
| 32 | struct sec_key { |
| 33 | u8 cipher_id; |
| 34 | u8 cipher_len; |
| 35 | @@ -767,6 +775,7 @@ struct wtbl_raw { |
| 36 | sizeof(struct sta_rec_sec) + \ |
| 37 | sizeof(struct sta_rec_ra_fixed) + \ |
| 38 | sizeof(struct sta_rec_he_6g_capa) + \ |
| 39 | + sizeof(struct sta_rec_pn_info) + \ |
| 40 | sizeof(struct tlv) + \ |
| 41 | MT76_CONNAC_WTBL_UPDATE_MAX_SIZE) |
| 42 | |
| 43 | @@ -796,6 +805,7 @@ enum { |
| 44 | STA_REC_HE_6G = 0x17, |
| 45 | STA_REC_HE_V2 = 0x19, |
| 46 | STA_REC_EHT = 0x22, |
| 47 | + STA_REC_PN_INFO = 0x26, |
| 48 | STA_REC_HDRT = 0x28, |
| 49 | STA_REC_HDR_TRANS = 0x2B, |
| 50 | STA_REC_MAX_NUM |
| 51 | @@ -1077,6 +1087,11 @@ enum mcu_cipher_type { |
| 52 | MCU_CIPHER_GCMP_256, |
| 53 | MCU_CIPHER_WAPI, |
| 54 | MCU_CIPHER_BIP_CMAC_128, |
| 55 | + MCU_CIPHER_BIP_CMAC_256, |
| 56 | + MCU_CIPHER_BCN_PROT_CMAC_128, |
| 57 | + MCU_CIPHER_BCN_PROT_CMAC_256, |
| 58 | + MCU_CIPHER_BCN_PROT_GMAC_128, |
| 59 | + MCU_CIPHER_BCN_PROT_GMAC_256, |
| 60 | }; |
| 61 | |
| 62 | enum { |
| 63 | @@ -1295,6 +1310,7 @@ enum { |
| 64 | UNI_BSS_INFO_RATE = 11, |
| 65 | UNI_BSS_INFO_QBSS = 15, |
| 66 | UNI_BSS_INFO_SEC = 16, |
| 67 | + UNI_BSS_INFO_BCN_PROT = 17, |
| 68 | UNI_BSS_INFO_TXCMD = 18, |
| 69 | UNI_BSS_INFO_UAPSD = 19, |
| 70 | UNI_BSS_INFO_PS = 21, |
| 71 | diff --git a/mt7996/main.c b/mt7996/main.c |
| 72 | index d40d3047..d3d10fab 100644 |
| 73 | --- a/mt7996/main.c |
| 74 | +++ b/mt7996/main.c |
| 75 | @@ -400,6 +400,10 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| 76 | } |
| 77 | |
| 78 | mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 79 | + |
| 80 | + if (key->keyidx == 6 || key->keyidx == 7) |
| 81 | + mt7996_mcu_bcn_prot_enable(dev, vif, key); |
| 82 | + |
| 83 | err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip, |
| 84 | key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE), |
| 85 | &msta->wcid, cmd); |
| 86 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| 87 | index 6add77da..53d2fc73 100644 |
| 88 | --- a/mt7996/mcu.c |
| 89 | +++ b/mt7996/mcu.c |
| 90 | @@ -2133,6 +2133,92 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| 91 | return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true); |
| 92 | } |
| 93 | |
| 94 | +static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| 95 | + u8 *pn) |
| 96 | +{ |
| 97 | +#define TSC_TYPE_BIGTK_PN 2 |
| 98 | + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 99 | + struct sta_rec_pn_info *pn_info; |
| 100 | + struct sk_buff *skb, *rskb; |
| 101 | + struct tlv *tlv; |
| 102 | + int ret; |
| 103 | + |
| 104 | + skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid); |
| 105 | + if (IS_ERR(skb)) |
| 106 | + return PTR_ERR(skb); |
| 107 | + |
| 108 | + tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info)); |
| 109 | + pn_info = (struct sta_rec_pn_info *)tlv; |
| 110 | + |
| 111 | + pn_info->tsc_type = TSC_TYPE_BIGTK_PN; |
| 112 | + ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb, |
| 113 | + MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE), true, &rskb); |
| 114 | + if (ret) |
| 115 | + return ret; |
| 116 | + |
| 117 | + skb_pull(rskb, 4); |
| 118 | + |
| 119 | + pn_info = (struct sta_rec_pn_info *)rskb->data; |
| 120 | + if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO) |
| 121 | + memcpy(pn, pn_info->pn, 6); |
| 122 | + |
| 123 | + dev_kfree_skb(rskb); |
| 124 | + return 0; |
| 125 | +} |
| 126 | + |
| 127 | +int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| 128 | + struct ieee80211_key_conf *key) |
| 129 | +{ |
| 130 | +#define WPA_BIGTK_MAX_LEN 32 |
| 131 | + int len = sizeof(struct bss_req_hdr) + sizeof(struct mt7996_mcu_bcn_prot_tlv); |
| 132 | + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 133 | + int ret; |
| 134 | + struct mt7996_mcu_bcn_prot_tlv *bcn_prot; |
| 135 | + struct sk_buff *skb; |
| 136 | + struct tlv *tlv; |
| 137 | + u8 pn[6] = {0}; |
| 138 | + |
| 139 | + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len); |
| 140 | + if (IS_ERR(skb)) |
| 141 | + return PTR_ERR(skb); |
| 142 | + |
| 143 | + tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT, |
| 144 | + sizeof(*bcn_prot)); |
| 145 | + |
| 146 | + bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv; |
| 147 | + |
| 148 | + ret = mt7996_mcu_get_pn(dev, vif, pn); |
| 149 | + if (ret) { |
| 150 | + dev_kfree_skb(skb); |
| 151 | + return ret; |
| 152 | + } |
| 153 | + |
| 154 | + switch(key->cipher){ |
| 155 | + case WLAN_CIPHER_SUITE_AES_CMAC: |
| 156 | + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128; |
| 157 | + break; |
| 158 | + case WLAN_CIPHER_SUITE_BIP_GMAC_128: |
| 159 | + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128; |
| 160 | + break; |
| 161 | + case WLAN_CIPHER_SUITE_BIP_GMAC_256: |
| 162 | + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256; |
| 163 | + break; |
| 164 | + case WLAN_CIPHER_SUITE_BIP_CMAC_256: |
| 165 | + default: |
| 166 | + dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n"); |
| 167 | + dev_kfree_skb(skb); |
| 168 | + return -EOPNOTSUPP; |
| 169 | + } |
| 170 | + |
| 171 | + pn[0]++; |
| 172 | + memcpy(bcn_prot->pn, pn, 6); |
| 173 | + bcn_prot->enable = 1; |
| 174 | + memcpy(bcn_prot->key, key->key, WPA_BIGTK_MAX_LEN); |
| 175 | + bcn_prot->key_id = key->keyidx; |
| 176 | + |
| 177 | + return mt76_mcu_skb_send_msg(&dev->mt76, skb, |
| 178 | + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); |
| 179 | +} |
| 180 | int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, |
| 181 | struct ieee80211_vif *vif, bool enable) |
| 182 | { |
| 183 | diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| 184 | index baffbcd7..f32ac153 100644 |
| 185 | --- a/mt7996/mcu.h |
| 186 | +++ b/mt7996/mcu.h |
| 187 | @@ -262,6 +262,17 @@ struct bss_rate_tlv { |
| 188 | u8 __rsv2[9]; |
| 189 | } __packed; |
| 190 | |
| 191 | +struct mt7996_mcu_bcn_prot_tlv { |
| 192 | + __le16 tag; |
| 193 | + __le16 len; |
| 194 | + u8 pn[6]; |
| 195 | + u8 enable; |
| 196 | + u8 cipher_id; |
| 197 | + u8 key[32]; |
| 198 | + u8 key_id; |
| 199 | + u8 __rsv[3]; |
| 200 | +} __packed; |
| 201 | + |
| 202 | struct bss_ra_tlv { |
| 203 | __le16 tag; |
| 204 | __le16 len; |
| 205 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| 206 | index c16bc8b4..94b62211 100644 |
| 207 | --- a/mt7996/mt7996.h |
| 208 | +++ b/mt7996/mt7996.h |
| 209 | @@ -710,6 +710,8 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| 210 | struct mt76_connac_sta_key_conf *sta_key_conf, |
| 211 | struct ieee80211_key_conf *key, int mcu_cmd, |
| 212 | struct mt76_wcid *wcid, enum set_key_cmd cmd); |
| 213 | +int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| 214 | + struct ieee80211_key_conf *key); |
| 215 | int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, |
| 216 | struct ieee80211_vif *vif, |
| 217 | struct ieee80211_sta *sta); |
| 218 | -- |
| 219 | 2.39.2 |
| 220 | |