blob: 7ddc56f9a277a5bd98a95d37ddf7e495ed376399 [file] [log] [blame]
developer692ed9b2023-06-19 12:03:50 +08001From b99c942620576c63baffd687090febea5ab2973d Mon Sep 17 00:00:00 2001
2From: mtk23510 <rudra.shahi@mediatek.com>
3Date: Wed, 26 Apr 2023 20:08:10 +0800
4Subject: [PATCH 1009/1015] wifi: mt76: mt7996: Beacon protection feature added
5
6Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
7Change-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
16diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
17index 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,
71diff --git a/mt7996/main.c b/mt7996/main.c
72index 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);
86diff --git a/mt7996/mcu.c b/mt7996/mcu.c
87index 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 {
183diff --git a/mt7996/mcu.h b/mt7996/mcu.h
184index 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;
205diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
206index 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--
2192.39.2
220