developer | b85e875 | 2023-09-25 14:16:05 +0800 | [diff] [blame^] | 1 | From fe8bcf023b97cb281774611d95745bd2b1c14d9c 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 1013/1024] wifi: mt76: mt7996: Beacon protection feature added |
| 5 | |
| 6 | Signed-off-by: mtk23510 <rudra.shahi@mediatek.com> |
| 7 | Signed-off-by: Allen.Ye <allen.ye@mediatek.com> |
| 8 | --- |
| 9 | mt76_connac_mcu.h | 24 ++++++++ |
| 10 | mt7996/main.c | 14 +++-- |
| 11 | mt7996/mcu.c | 138 +++++++++++++++++++++++++++++++++------------- |
| 12 | mt7996/mcu.h | 17 ++++++ |
| 13 | mt7996/mt7996.h | 3 +- |
| 14 | 5 files changed, 153 insertions(+), 43 deletions(-) |
| 15 | |
| 16 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| 17 | index 196b4921d..21cae4bf4 100644 |
| 18 | --- a/mt76_connac_mcu.h |
| 19 | +++ b/mt76_connac_mcu.h |
| 20 | @@ -416,6 +416,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 | @@ -768,6 +776,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 | @@ -798,6 +807,7 @@ enum { |
| 44 | STA_REC_HE_V2 = 0x19, |
| 45 | STA_REC_MLD = 0x20, |
| 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 | @@ -1091,6 +1101,13 @@ 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 | + MCU_CIPHER_BIP_GMAC_128, |
| 61 | + MCU_CIPHER_BIP_GMAC_256, |
| 62 | }; |
| 63 | |
| 64 | enum { |
| 65 | @@ -1316,6 +1333,7 @@ enum { |
| 66 | UNI_BSS_INFO_RATE = 11, |
| 67 | UNI_BSS_INFO_QBSS = 15, |
| 68 | UNI_BSS_INFO_SEC = 16, |
| 69 | + UNI_BSS_INFO_BCN_PROT = 17, |
| 70 | UNI_BSS_INFO_TXCMD = 18, |
| 71 | UNI_BSS_INFO_UAPSD = 19, |
| 72 | UNI_BSS_INFO_PS = 21, |
| 73 | @@ -1776,6 +1794,12 @@ mt76_connac_mcu_get_cipher(int cipher) |
| 74 | return MCU_CIPHER_GCMP; |
| 75 | case WLAN_CIPHER_SUITE_GCMP_256: |
| 76 | return MCU_CIPHER_GCMP_256; |
| 77 | + case WLAN_CIPHER_SUITE_BIP_GMAC_128: |
| 78 | + return MCU_CIPHER_BIP_GMAC_128; |
| 79 | + case WLAN_CIPHER_SUITE_BIP_GMAC_256: |
| 80 | + return MCU_CIPHER_BIP_GMAC_256; |
| 81 | + case WLAN_CIPHER_SUITE_BIP_CMAC_256: |
| 82 | + return MCU_CIPHER_BIP_CMAC_256; |
| 83 | case WLAN_CIPHER_SUITE_SMS4: |
| 84 | return MCU_CIPHER_WAPI; |
| 85 | default: |
| 86 | diff --git a/mt7996/main.c b/mt7996/main.c |
| 87 | index f2e2de850..d8c8a5fac 100644 |
| 88 | --- a/mt7996/main.c |
| 89 | +++ b/mt7996/main.c |
| 90 | @@ -368,8 +368,10 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| 91 | /* fall back to sw encryption for unsupported ciphers */ |
| 92 | switch (key->cipher) { |
| 93 | case WLAN_CIPHER_SUITE_AES_CMAC: |
| 94 | - wcid_keyidx = &wcid->hw_key_idx2; |
| 95 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE; |
| 96 | + case WLAN_CIPHER_SUITE_BIP_GMAC_128: |
| 97 | + case WLAN_CIPHER_SUITE_BIP_GMAC_256: |
| 98 | + wcid_keyidx = &wcid->hw_key_idx2; |
| 99 | break; |
| 100 | case WLAN_CIPHER_SUITE_TKIP: |
| 101 | case WLAN_CIPHER_SUITE_CCMP: |
| 102 | @@ -400,9 +402,13 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
| 103 | } |
| 104 | |
| 105 | mt76_wcid_key_setup(&dev->mt76, wcid, key); |
| 106 | - err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip, |
| 107 | - key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE), |
| 108 | - &msta->wcid, cmd); |
| 109 | + |
| 110 | + if (key->keyidx == 6 || key->keyidx == 7) |
| 111 | + err = mt7996_mcu_bcn_prot_enable(dev, vif, key); |
| 112 | + else |
| 113 | + err = mt7996_mcu_add_key(&dev->mt76, vif, key, |
| 114 | + MCU_WMWA_UNI_CMD(STA_REC_UPDATE), |
| 115 | + &msta->wcid, cmd); |
| 116 | out: |
| 117 | mutex_unlock(&dev->mt76.mutex); |
| 118 | |
| 119 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| 120 | index 802b21685..22417e410 100644 |
| 121 | --- a/mt7996/mcu.c |
| 122 | +++ b/mt7996/mcu.c |
| 123 | @@ -2155,7 +2155,6 @@ out: |
| 124 | |
| 125 | static int |
| 126 | mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid, |
| 127 | - struct mt76_connac_sta_key_conf *sta_key_conf, |
| 128 | struct sk_buff *skb, |
| 129 | struct ieee80211_key_conf *key, |
| 130 | enum set_key_cmd cmd) |
| 131 | @@ -2176,43 +2175,22 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid, |
| 132 | return -EOPNOTSUPP; |
| 133 | |
| 134 | sec_key = &sec->key[0]; |
| 135 | + sec_key->wlan_idx = cpu_to_le16(wcid->idx); |
| 136 | + sec_key->mgmt_prot = 0; |
| 137 | + sec_key->cipher_id = cipher; |
| 138 | sec_key->cipher_len = sizeof(*sec_key); |
| 139 | - |
| 140 | - if (cipher == MCU_CIPHER_BIP_CMAC_128) { |
| 141 | - sec_key->wlan_idx = cpu_to_le16(wcid->idx); |
| 142 | - sec_key->cipher_id = MCU_CIPHER_AES_CCMP; |
| 143 | - sec_key->key_id = sta_key_conf->keyidx; |
| 144 | - sec_key->key_len = 16; |
| 145 | - memcpy(sec_key->key, sta_key_conf->key, 16); |
| 146 | - |
| 147 | - sec_key = &sec->key[1]; |
| 148 | - sec_key->wlan_idx = cpu_to_le16(wcid->idx); |
| 149 | - sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128; |
| 150 | - sec_key->cipher_len = sizeof(*sec_key); |
| 151 | - sec_key->key_len = 16; |
| 152 | - memcpy(sec_key->key, key->key, 16); |
| 153 | - sec->n_cipher = 2; |
| 154 | - } else { |
| 155 | - sec_key->wlan_idx = cpu_to_le16(wcid->idx); |
| 156 | - sec_key->cipher_id = cipher; |
| 157 | - sec_key->key_id = key->keyidx; |
| 158 | - sec_key->key_len = key->keylen; |
| 159 | - memcpy(sec_key->key, key->key, key->keylen); |
| 160 | - |
| 161 | - if (cipher == MCU_CIPHER_TKIP) { |
| 162 | - /* Rx/Tx MIC keys are swapped */ |
| 163 | - memcpy(sec_key->key + 16, key->key + 24, 8); |
| 164 | - memcpy(sec_key->key + 24, key->key + 16, 8); |
| 165 | - } |
| 166 | - |
| 167 | - /* store key_conf for BIP batch update */ |
| 168 | - if (cipher == MCU_CIPHER_AES_CCMP) { |
| 169 | - memcpy(sta_key_conf->key, key->key, key->keylen); |
| 170 | - sta_key_conf->keyidx = key->keyidx; |
| 171 | - } |
| 172 | - |
| 173 | - sec->n_cipher = 1; |
| 174 | + sec_key->key_id = key->keyidx; |
| 175 | + sec_key->key_len = key->keylen; |
| 176 | + sec_key->need_resp = 0; |
| 177 | + memcpy(sec_key->key, key->key, key->keylen); |
| 178 | + |
| 179 | + if (cipher == MCU_CIPHER_TKIP) { |
| 180 | + /* Rx/Tx MIC keys are swapped */ |
| 181 | + memcpy(sec_key->key + 16, key->key + 24, 8); |
| 182 | + memcpy(sec_key->key + 24, key->key + 16, 8); |
| 183 | } |
| 184 | + |
| 185 | + sec->n_cipher = 1; |
| 186 | } else { |
| 187 | sec->n_cipher = 0; |
| 188 | } |
| 189 | @@ -2221,7 +2199,6 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid, |
| 190 | } |
| 191 | |
| 192 | int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| 193 | - struct mt76_connac_sta_key_conf *sta_key_conf, |
| 194 | struct ieee80211_key_conf *key, int mcu_cmd, |
| 195 | struct mt76_wcid *wcid, enum set_key_cmd cmd) |
| 196 | { |
| 197 | @@ -2234,13 +2211,98 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| 198 | if (IS_ERR(skb)) |
| 199 | return PTR_ERR(skb); |
| 200 | |
| 201 | - ret = mt7996_mcu_sta_key_tlv(wcid, sta_key_conf, skb, key, cmd); |
| 202 | + ret = mt7996_mcu_sta_key_tlv(wcid, skb, key, cmd); |
| 203 | if (ret) |
| 204 | return ret; |
| 205 | |
| 206 | return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true); |
| 207 | } |
| 208 | |
| 209 | +static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| 210 | + u8 *pn) |
| 211 | +{ |
| 212 | +#define TSC_TYPE_BIGTK_PN 2 |
| 213 | + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 214 | + struct sta_rec_pn_info *pn_info; |
| 215 | + struct sk_buff *skb, *rskb; |
| 216 | + struct tlv *tlv; |
| 217 | + int ret; |
| 218 | + |
| 219 | + skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid); |
| 220 | + if (IS_ERR(skb)) |
| 221 | + return PTR_ERR(skb); |
| 222 | + |
| 223 | + tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info)); |
| 224 | + pn_info = (struct sta_rec_pn_info *)tlv; |
| 225 | + |
| 226 | + pn_info->tsc_type = TSC_TYPE_BIGTK_PN; |
| 227 | + ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb, |
| 228 | + MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE), true, &rskb); |
| 229 | + if (ret) |
| 230 | + return ret; |
| 231 | + |
| 232 | + skb_pull(rskb, 4); |
| 233 | + |
| 234 | + pn_info = (struct sta_rec_pn_info *)rskb->data; |
| 235 | + if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO) |
| 236 | + memcpy(pn, pn_info->pn, 6); |
| 237 | + |
| 238 | + dev_kfree_skb(rskb); |
| 239 | + return 0; |
| 240 | +} |
| 241 | + |
| 242 | +int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| 243 | + struct ieee80211_key_conf *key) |
| 244 | +{ |
| 245 | + int len = sizeof(struct bss_req_hdr) + sizeof(struct mt7996_mcu_bcn_prot_tlv); |
| 246 | + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 247 | + int ret; |
| 248 | + struct mt7996_mcu_bcn_prot_tlv *bcn_prot; |
| 249 | + struct sk_buff *skb; |
| 250 | + struct tlv *tlv; |
| 251 | + u8 pn[6] = {0}; |
| 252 | + |
| 253 | + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len); |
| 254 | + if (IS_ERR(skb)) |
| 255 | + return PTR_ERR(skb); |
| 256 | + |
| 257 | + tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT, |
| 258 | + sizeof(*bcn_prot)); |
| 259 | + |
| 260 | + bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv; |
| 261 | + |
| 262 | + ret = mt7996_mcu_get_pn(dev, vif, pn); |
| 263 | + if (ret) { |
| 264 | + dev_kfree_skb(skb); |
| 265 | + return ret; |
| 266 | + } |
| 267 | + |
| 268 | + switch (key->cipher) { |
| 269 | + case WLAN_CIPHER_SUITE_AES_CMAC: |
| 270 | + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128; |
| 271 | + break; |
| 272 | + case WLAN_CIPHER_SUITE_BIP_GMAC_128: |
| 273 | + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128; |
| 274 | + break; |
| 275 | + case WLAN_CIPHER_SUITE_BIP_GMAC_256: |
| 276 | + bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256; |
| 277 | + break; |
| 278 | + case WLAN_CIPHER_SUITE_BIP_CMAC_256: |
| 279 | + default: |
| 280 | + dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n"); |
| 281 | + dev_kfree_skb(skb); |
| 282 | + return -EOPNOTSUPP; |
| 283 | + } |
| 284 | + |
| 285 | + pn[0]++; |
| 286 | + memcpy(bcn_prot->pn, pn, 6); |
| 287 | + bcn_prot->enable = BP_SW_MODE; |
| 288 | + memcpy(bcn_prot->key, key->key, WLAN_MAX_KEY_LEN); |
| 289 | + bcn_prot->key_id = key->keyidx; |
| 290 | + |
| 291 | + return mt76_mcu_skb_send_msg(&dev->mt76, skb, |
| 292 | + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); |
| 293 | +} |
| 294 | int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, |
| 295 | struct ieee80211_vif *vif, bool enable) |
| 296 | { |
| 297 | diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| 298 | index 1d7748771..512d8543b 100644 |
| 299 | --- a/mt7996/mcu.h |
| 300 | +++ b/mt7996/mcu.h |
| 301 | @@ -313,6 +313,23 @@ struct bss_rate_tlv { |
| 302 | u8 __rsv2[9]; |
| 303 | } __packed; |
| 304 | |
| 305 | +enum { |
| 306 | + BP_DISABLE, |
| 307 | + BP_SW_MODE, |
| 308 | + BP_HW_MODE, |
| 309 | +}; |
| 310 | + |
| 311 | +struct mt7996_mcu_bcn_prot_tlv { |
| 312 | + __le16 tag; |
| 313 | + __le16 len; |
| 314 | + u8 pn[6]; |
| 315 | + u8 enable; |
| 316 | + u8 cipher_id; |
| 317 | + u8 key[WLAN_MAX_KEY_LEN]; |
| 318 | + u8 key_id; |
| 319 | + u8 __rsv[3]; |
| 320 | +} __packed; |
| 321 | + |
| 322 | struct bss_ra_tlv { |
| 323 | __le16 tag; |
| 324 | __le16 len; |
| 325 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| 326 | index 99d4659f1..b75523ff4 100644 |
| 327 | --- a/mt7996/mt7996.h |
| 328 | +++ b/mt7996/mt7996.h |
| 329 | @@ -654,9 +654,10 @@ int mt7996_init_debugfs(struct mt7996_phy *phy); |
| 330 | void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len); |
| 331 | bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len); |
| 332 | int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| 333 | - struct mt76_connac_sta_key_conf *sta_key_conf, |
| 334 | struct ieee80211_key_conf *key, int mcu_cmd, |
| 335 | struct mt76_wcid *wcid, enum set_key_cmd cmd); |
| 336 | +int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif, |
| 337 | + struct ieee80211_key_conf *key); |
| 338 | int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, |
| 339 | struct ieee80211_vif *vif, |
| 340 | struct ieee80211_sta *sta); |
| 341 | -- |
| 342 | 2.39.2 |
| 343 | |