blob: d710df80e4905d4c412b21534e54b7fe6420f60c [file] [log] [blame]
developer3797e1e2022-05-23 17:13:14 +08001From 3b12e37a1c903b7f30c1515b6eec481c206abb4e Mon Sep 17 00:00:00 2001
2From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
3Date: Mon, 25 Apr 2022 15:31:02 +0800
4Subject: [PATCH] mt76: mt7915: add support for 6G in-band discovery
5
6Add offloading FILS discovery and unsolicited broadcast probe response support.
7
8Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
9Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
10---
11 mt7915/init.c | 2 +
12 mt7915/mac.c | 17 +++--
13 mt7915/main.c | 8 +-
14 mt7915/mcu.c | 75 ++++++++++++++++++-
15 mt7915/mcu.h | 15 +++-
16 mt7915/mt7915.h | 4 +-
17 6 files changed, 107 insertions(+), 14 deletions(-)
18
19diff --git a/mt7915/init.c b/mt7915/init.c
20index 70baad756dd0..d123ecb9fb0c 100644
21--- a/mt7915/init.c
22+++ b/mt7915/init.c
23@@ -351,6 +351,8 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
24 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
25 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
26 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
27+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);
28+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);
29
30 if (!mdev->dev->of_node ||
31 !of_property_read_bool(mdev->dev->of_node,
32diff --git a/mt7915/mac.c b/mt7915/mac.c
33index e353e8c44d6c..de7bf137c234 100644
34--- a/mt7915/mac.c
35+++ b/mt7915/mac.c
36@@ -1177,7 +1177,7 @@ mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
37
38 void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
39 struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
40- struct ieee80211_key_conf *key, bool beacon)
41+ struct ieee80211_key_conf *key, u32 changed)
42 {
43 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
44 struct ieee80211_vif *vif = info->control.vif;
45@@ -1188,6 +1188,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
46 bool mcast = false;
47 u16 tx_count = 15;
48 u32 val;
49+ bool beacon = !!(changed & (BSS_CHANGED_BEACON |
50+ BSS_CHANGED_BEACON_ENABLED));
51+ bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
52+ BSS_CHANGED_FILS_DISCOVERY));
53
54 if (vif) {
55 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
56@@ -1200,7 +1204,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
57 if (ext_phy && dev->mt76.phy2)
58 mphy = dev->mt76.phy2;
59
60- if (beacon) {
61+ if (inband_disc) {
62+ p_fmt = MT_TX_TYPE_FW;
63+ q_idx = MT_LMAC_ALTX0;
64+ } else if (beacon) {
65 p_fmt = MT_TX_TYPE_FW;
66 q_idx = MT_LMAC_BCN0;
67 } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
68@@ -1308,8 +1315,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
69 return id;
70
71 pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
72- mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key,
73- false);
74+ mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, 0);
75
76 txp = (struct mt7915_txp *)(txwi + MT_TXD_SIZE);
77 for (i = 0; i < nbuf; i++) {
78@@ -1919,7 +1925,8 @@ mt7915_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif)
79 case NL80211_IFTYPE_MESH_POINT:
80 case NL80211_IFTYPE_ADHOC:
81 case NL80211_IFTYPE_AP:
82- mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon);
83+ mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon,
84+ BSS_CHANGED_BEACON_ENABLED);
85 break;
86 default:
87 break;
88diff --git a/mt7915/main.c b/mt7915/main.c
89index 5177b19f9154..c2c615931782 100644
90--- a/mt7915/main.c
91+++ b/mt7915/main.c
92@@ -622,8 +622,10 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
93 mt7915_update_bss_color(hw, vif, &info->he_bss_color);
94
95 if (changed & (BSS_CHANGED_BEACON |
96- BSS_CHANGED_BEACON_ENABLED))
97- mt7915_mcu_add_beacon(hw, vif, info->enable_beacon);
98+ BSS_CHANGED_BEACON_ENABLED |
99+ BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
100+ BSS_CHANGED_FILS_DISCOVERY))
101+ mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);
102
103 mutex_unlock(&dev->mt76.mutex);
104 }
105@@ -636,7 +638,7 @@ mt7915_channel_switch_beacon(struct ieee80211_hw *hw,
106 struct mt7915_dev *dev = mt7915_hw_dev(hw);
107
108 mutex_lock(&dev->mt76.mutex);
109- mt7915_mcu_add_beacon(hw, vif, true);
110+ mt7915_mcu_add_beacon(hw, vif, true, BSS_CHANGED_BEACON);
111 mutex_unlock(&dev->mt76.mutex);
112 }
113
114diff --git a/mt7915/mcu.c b/mt7915/mcu.c
115index 2a07a5d2a439..87e44c69d72b 100644
116--- a/mt7915/mcu.c
117+++ b/mt7915/mcu.c
118@@ -1892,6 +1892,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
119 u8 *buf;
120 int len = sizeof(*cont) + MT_TXD_SIZE + skb->len;
121
122+ len = (len & 0x3) ? ((len | 0x3) + 1) : len;
123 tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_CONTENT,
124 len, &bcn->sub_ntlv, &bcn->len);
125
126@@ -1910,7 +1911,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
127
128 buf = (u8 *)tlv + sizeof(*cont);
129 mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
130- true);
131+ BSS_CHANGED_BEACON);
132 memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
133 }
134
135@@ -1992,8 +1993,71 @@ mt7915_mcu_beacon_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif,
136 }
137 }
138
139-int mt7915_mcu_add_beacon(struct ieee80211_hw *hw,
140- struct ieee80211_vif *vif, int en)
141+static void
142+mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
143+ struct sk_buff *rskb, struct bss_info_bcn *bcn,
144+ u32 changed)
145+{
146+#define OFFLOAD_TX_MODE_SU BIT(0)
147+#define OFFLOAD_TX_MODE_MU BIT(1)
148+ struct ieee80211_hw *hw = mt76_hw(dev);
149+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
150+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
151+ struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
152+ enum nl80211_band band = chandef->chan->band;
153+ struct mt76_wcid *wcid = &dev->mt76.global_wcid;
154+ struct bss_info_inband_discovery *discov;
155+ struct ieee80211_tx_info *info;
156+ struct sk_buff *skb = NULL;
157+ struct tlv *tlv;
158+ bool ext_phy = phy != &dev->phy;
159+ u8 *buf, interval;
160+ int len;
161+
162+ if (changed & BSS_CHANGED_FILS_DISCOVERY &&
163+ vif->bss_conf.fils_discovery.max_interval) {
164+ interval = vif->bss_conf.fils_discovery.max_interval;
165+ skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
166+ } else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
167+ vif->bss_conf.unsol_bcast_probe_resp_interval) {
168+ interval = vif->bss_conf.unsol_bcast_probe_resp_interval;
169+ skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
170+ }
171+
172+ if (!skb)
173+ return;
174+
175+ info = IEEE80211_SKB_CB(skb);
176+ info->control.vif = vif;
177+ info->band = band;
178+
179+ if (ext_phy)
180+ info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY;
181+
182+ len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
183+ len = (len & 0x3) ? ((len | 0x3) + 1) : len;
184+
185+ tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_DISCOV,
186+ len, &bcn->sub_ntlv, &bcn->len);
187+ discov = (struct bss_info_inband_discovery *)tlv;
188+ discov->tx_mode = OFFLOAD_TX_MODE_SU;
189+ /* 0: UNSOL PROBE RESP, 1: FILS DISCOV */
190+ discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
191+ discov->tx_interval = interval;
192+ discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
193+ discov->enable = true;
194+
195+ buf = (u8 *)tlv + sizeof(*discov);
196+
197+ mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
198+ changed);
199+ memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
200+
201+ dev_kfree_skb(skb);
202+}
203+
204+int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
205+ int en, u32 changed)
206 {
207 #define MAX_BEACON_SIZE 512
208 struct mt7915_dev *dev = mt7915_hw_dev(hw);
209@@ -2044,6 +2108,11 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw,
210 mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
211 dev_kfree_skb(skb);
212
213+ if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ||
214+ changed & BSS_CHANGED_FILS_DISCOVERY)
215+ mt7915_mcu_beacon_inband_discov(dev, vif, rskb,
216+ bcn, changed);
217+
218 out:
219 return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
220 MCU_EXT_CMD(BSS_INFO_UPDATE), true);
221diff --git a/mt7915/mcu.h b/mt7915/mcu.h
222index 064d33e33738..e1d576701fdf 100644
223--- a/mt7915/mcu.h
224+++ b/mt7915/mcu.h
225@@ -404,11 +404,23 @@ struct bss_info_bcn_cont {
226 __le16 pkt_len;
227 } __packed __aligned(4);
228
229+struct bss_info_inband_discovery {
230+ __le16 tag;
231+ __le16 len;
232+ u8 tx_type;
233+ u8 tx_mode;
234+ u8 tx_interval;
235+ u8 enable;
236+ __le16 rsv;
237+ __le16 prob_rsp_len;
238+} __packed __aligned(4);
239+
240 enum {
241 BSS_INFO_BCN_CSA,
242 BSS_INFO_BCN_BCC,
243 BSS_INFO_BCN_MBSSID,
244 BSS_INFO_BCN_CONTENT,
245+ BSS_INFO_BCN_DISCOV,
246 BSS_INFO_BCN_MAX
247 };
248
249@@ -476,6 +488,7 @@ enum {
250 #define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \
251 sizeof(struct bss_info_bcn_cntdwn) + \
252 sizeof(struct bss_info_bcn_mbss) + \
253- sizeof(struct bss_info_bcn_cont))
254+ sizeof(struct bss_info_bcn_cont) + \
255+ sizeof(struct bss_info_inband_discovery))
256
257 #endif
258diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
259index 6c590eff14f1..03431012b2ff 100644
260--- a/mt7915/mt7915.h
261+++ b/mt7915/mt7915.h
262@@ -464,7 +464,7 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,
263 int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
264 struct cfg80211_he_bss_color *he_bss_color);
265 int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
266- int enable);
267+ int enable, u32 changed);
268 int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
269 bool enable);
270 int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
271@@ -551,7 +551,7 @@ void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy);
272 void mt7915_mac_enable_nf(struct mt7915_dev *dev, bool ext_phy);
273 void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
274 struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
275- struct ieee80211_key_conf *key, bool beacon);
276+ struct ieee80211_key_conf *key, u32 changed);
277 void mt7915_mac_set_timing(struct mt7915_phy *phy);
278 int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
279 struct ieee80211_sta *sta);
280--
2812.18.0
282