blob: 600210d11b8bbbaa14a209af489eb643a7b68bae [file] [log] [blame]
developer7b18d4c2021-12-09 15:24:27 +08001diff --git a/package/kernel/mt76/patches/1005-mt76-zero-wait-dfs.patch b/package/kernel/mt76/patches/1005-mt76-zero-wait-dfs.patch
2new file mode 100644
3index 0000000..68883e4
4--- /dev/null
5+++ b/package/kernel/mt76/patches/1005-mt76-zero-wait-dfs.patch
6@@ -0,0 +1,369 @@
7+diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c
8+index 3a0ec43..2ce6973 100644
9+--- a/mt7915/debugfs.c
10++++ b/mt7915/debugfs.c
11+@@ -75,12 +75,62 @@ mt7915_radar_trigger(void *data, u64 val)
12+ {
13+ struct mt7915_dev *dev = data;
14+
15+- return mt7915_mcu_rdd_cmd(dev, RDD_RADAR_EMULATE, 1, 0, 0);
16++ if (val > MT_RX_SEL2)
17++ return -EINVAL;
18++
19++ return mt7915_mcu_rdd_cmd(dev, RDD_RADAR_EMULATE, val, 0, 0);
20+ }
21+
22+ DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL,
23+ mt7915_radar_trigger, "%lld\n");
24+
25++static int
26++mt7915_rdd_monitor(struct seq_file *s, void *data)
27++{
28++ struct mt7915_dev *dev = dev_get_drvdata(s->private);
29++ struct cfg80211_chan_def *chandef = &dev->rdd2_chandef;
30++ const char *bw;
31++ int ret = 0;
32++
33++ mutex_lock(&dev->mt76.mutex);
34++
35++ if (!cfg80211_chandef_valid(chandef)) {
36++ ret = -EINVAL;
37++ goto out;
38++ }
39++
40++ if (!dev->rdd2_phy) {
41++ seq_printf(s, "not running\n");
42++ goto out;
43++ }
44++
45++ switch (chandef->width) {
46++ case NL80211_CHAN_WIDTH_40:
47++ bw = "40";
48++ break;
49++ case NL80211_CHAN_WIDTH_80:
50++ bw = "80";
51++ break;
52++ case NL80211_CHAN_WIDTH_160:
53++ bw = "160";
54++ break;
55++ case NL80211_CHAN_WIDTH_80P80:
56++ bw = "80P80";
57++ break;
58++ default:
59++ bw = "20";
60++ break;
61++ }
62++
63++ seq_printf(s, "channel %d (%d MHz) width %s MHz center1: %d MHz\n",
64++ chandef->chan->hw_value, chandef->chan->center_freq,
65++ bw, chandef->center_freq1);
66++out:
67++ mutex_unlock(&dev->mt76.mutex);
68++
69++ return ret;
70++}
71++
72+ static int
73+ mt7915_fw_debug_wm_set(void *data, u64 val)
74+ {
75+@@ -552,6 +602,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
76+ &dev->hw_pattern);
77+ debugfs_create_file("radar_trigger", 0200, dir, dev,
78+ &fops_radar_trigger);
79++ debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir,
80++ mt7915_rdd_monitor);
81+ }
82+
83+ #ifdef MTK_DEBUG
84+diff --git a/mt7915/init.c b/mt7915/init.c
85+index e32cefc..6767702 100644
86+--- a/mt7915/init.c
87++++ b/mt7915/init.c
88+@@ -294,6 +294,9 @@ mt7915_regd_notifier(struct wiphy *wiphy,
89+ memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
90+ dev->mt76.region = request->dfs_region;
91+
92++ if (dev->mt76.region == NL80211_DFS_UNSET)
93++ mt7915_mcu_rdd_offchan_enable(phy, NULL);
94++
95+ mt7915_init_txpower(dev, &mphy->sband_2g.sband);
96+ mt7915_init_txpower(dev, &mphy->sband_5g.sband);
97+
98+@@ -307,6 +310,7 @@ static void
99+ mt7915_init_wiphy(struct ieee80211_hw *hw)
100+ {
101+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
102++ struct mt76_dev *mdev = &phy->dev->mt76;
103+ struct wiphy *wiphy = hw->wiphy;
104+
105+ hw->queues = 4;
106+@@ -334,6 +338,12 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
107+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
108+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
109+
110++ if (!mdev->dev->of_node ||
111++ !of_property_read_bool(mdev->dev->of_node,
112++ "mediatek,disable-radar-offchan"))
113++ wiphy_ext_feature_set(wiphy,
114++ NL80211_EXT_FEATURE_RADAR_OFFCHAN);
115++
116+ ieee80211_hw_set(hw, HAS_RATE_CONTROL);
117+ ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
118+ ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
119+diff --git a/mt7915/main.c b/mt7915/main.c
120+index 31efe2c..c9dba1f 100644
121+--- a/mt7915/main.c
122++++ b/mt7915/main.c
123+@@ -1312,6 +1312,55 @@ mt7915_twt_teardown_request(struct ieee80211_hw *hw,
124+ mutex_unlock(&dev->mt76.mutex);
125+ }
126+
127++static int
128++mt7915_set_radar_offchan(struct ieee80211_hw *hw,
129++ struct cfg80211_chan_def *chandef)
130++{
131++ struct mt7915_phy *phy = mt7915_hw_phy(hw);
132++ struct mt7915_dev *dev = phy->dev;
133++ int ret = -EINVAL;
134++ bool running;
135++
136++ mutex_lock(&dev->mt76.mutex);
137++
138++ if (dev->mt76.region == NL80211_DFS_UNSET)
139++ goto out;
140++
141++ if (dev->rdd2_phy && dev->rdd2_phy != phy) {
142++ /* rdd2 is already locked */
143++ ret = -EBUSY;
144++ goto out;
145++ }
146++
147++ /* rdd2 already configured on a radar channel */
148++ running = dev->rdd2_phy &&
149++ cfg80211_chandef_valid(&dev->rdd2_chandef) &&
150++ !!(dev->rdd2_chandef.chan->flags & IEEE80211_CHAN_RADAR);
151++
152++ if (!chandef || running ||
153++ !(chandef->chan->flags & IEEE80211_CHAN_RADAR)) {
154++ ret = mt7915_mcu_rdd_offchan_enable(phy, NULL);
155++ if (ret)
156++ goto out;
157++
158++ if (!running)
159++ goto update_phy;
160++ }
161++
162++ ret = mt7915_mcu_rdd_offchan_enable(phy, chandef);
163++ if (ret)
164++ goto out;
165++
166++update_phy:
167++ dev->rdd2_phy = chandef ? phy : NULL;
168++ if (chandef)
169++ dev->rdd2_chandef = *chandef;
170++out:
171++ mutex_unlock(&dev->mt76.mutex);
172++
173++ return ret;
174++}
175++
176+ const struct ieee80211_ops mt7915_ops = {
177+ .tx = mt7915_tx,
178+ .start = mt7915_start,
179+@@ -1357,4 +1406,5 @@ const struct ieee80211_ops mt7915_ops = {
180+ #ifdef CONFIG_MAC80211_DEBUGFS
181+ .sta_add_debugfs = mt7915_sta_add_debugfs,
182+ #endif
183++ .set_radar_offchan = mt7915_set_radar_offchan,
184+ };
185+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
186+index a5fb821..b361f68 100644
187+--- a/mt7915/mcu.c
188++++ b/mt7915/mcu.c
189+@@ -487,7 +487,12 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
190+ if (r->band_idx && dev->mt76.phy2)
191+ mphy = dev->mt76.phy2;
192+
193+- ieee80211_radar_detected(mphy->hw);
194++ if (r->band_idx == MT_RX_SEL2)
195++ cfg80211_offchan_radar_event(mphy->hw->wiphy,
196++ &dev->rdd2_chandef,
197++ GFP_ATOMIC);
198++ else
199++ ieee80211_radar_detected(mphy->hw);
200+ dev->hw_pattern++;
201+ }
202+
203+@@ -3409,6 +3414,97 @@ int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
204+ sizeof(req), true);
205+ }
206+
207++static int
208++mt7915_mcu_offchan_chain_ctrl(struct mt7915_phy *phy,
209++ struct cfg80211_chan_def *chandef,
210++ int cmd)
211++{
212++ struct mt7915_dev *dev = phy->dev;
213++ struct mt76_phy *mphy = phy->mt76;
214++ struct ieee80211_channel *chan = mphy->chandef.chan;
215++ int freq = mphy->chandef.center_freq1;
216++ struct mt7915_mcu_offchan_chain_ctrl req = {
217++ .monitor_scan_type = 2, /* simple rx */
218++ };
219++
220++ if (!chandef && cmd != CH_SWITCH_BACKGROUND_SCAN_STOP)
221++ return -EINVAL;
222++
223++ if (!cfg80211_chandef_valid(&mphy->chandef))
224++ return -EINVAL;
225++
226++ switch (cmd) {
227++ case CH_SWITCH_BACKGROUND_SCAN_START: {
228++ req.chan = chan->hw_value;
229++ req.central_chan = ieee80211_frequency_to_channel(freq);
230++ req.bw = mt7915_mcu_chan_bw(&mphy->chandef);
231++ req.monitor_chan = chandef->chan->hw_value;
232++ req.monitor_central_chan =
233++ ieee80211_frequency_to_channel(chandef->center_freq1);
234++ req.monitor_bw = mt7915_mcu_chan_bw(chandef);
235++ req.band_idx = phy != &dev->phy;
236++ req.scan_mode = 1;
237++ break;
238++ }
239++ case CH_SWITCH_BACKGROUND_SCAN_RUNNING:
240++ req.monitor_chan = chandef->chan->hw_value;
241++ req.monitor_central_chan =
242++ ieee80211_frequency_to_channel(chandef->center_freq1);
243++ req.band_idx = phy != &dev->phy;
244++ req.scan_mode = 2;
245++ break;
246++ case CH_SWITCH_BACKGROUND_SCAN_STOP:
247++ req.chan = chan->hw_value;
248++ req.central_chan = ieee80211_frequency_to_channel(freq);
249++ req.bw = mt7915_mcu_chan_bw(&mphy->chandef);
250++ req.tx_stream = hweight8(mphy->antenna_mask);
251++ req.rx_stream = mphy->antenna_mask;
252++ break;
253++ default:
254++ return -EINVAL;
255++ }
256++ req.band = chandef ? chandef->chan->band == NL80211_BAND_5GHZ : 1;
257++
258++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(OFFCH_SCAN_CTRL),
259++ &req, sizeof(req), false);
260++}
261++
262++int mt7915_mcu_rdd_offchan_enable(struct mt7915_phy *phy,
263++ struct cfg80211_chan_def *chandef)
264++{
265++ struct mt7915_dev *dev = phy->dev;
266++ int err, region;
267++
268++ if (!chandef) { /* disable offchain */
269++ err = mt7915_mcu_rdd_cmd(dev, RDD_STOP, MT_RX_SEL2, 0, 0);
270++ if (err)
271++ return err;
272++
273++ return mt7915_mcu_offchan_chain_ctrl(phy, NULL,
274++ CH_SWITCH_BACKGROUND_SCAN_STOP);
275++ }
276++
277++ err = mt7915_mcu_offchan_chain_ctrl(phy, chandef,
278++ CH_SWITCH_BACKGROUND_SCAN_START);
279++ if (err)
280++ return err;
281++
282++ switch (dev->mt76.region) {
283++ case NL80211_DFS_ETSI:
284++ region = 0;
285++ break;
286++ case NL80211_DFS_JP:
287++ region = 2;
288++ break;
289++ case NL80211_DFS_FCC:
290++ default:
291++ region = 1;
292++ break;
293++ }
294++
295++ return mt7915_mcu_rdd_cmd(dev, RDD_START, MT_RX_SEL2, 0, region);
296++}
297++
298+ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
299+ {
300+ struct mt7915_dev *dev = phy->dev;
301+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
302+index 2f856ae..64bea9a 100644
303+--- a/mt7915/mcu.h
304++++ b/mt7915/mcu.h
305+@@ -153,6 +153,29 @@ struct mt7915_mcu_rdd_report {
306+ } hw_pulse[32];
307+ } __packed;
308+
309++struct mt7915_mcu_offchan_chain_ctrl {
310++ u8 chan; /* primary channel */
311++ u8 central_chan; /* central channel */
312++ u8 bw;
313++ u8 tx_stream;
314++ u8 rx_stream;
315++
316++ u8 monitor_chan; /* monitor channel */
317++ u8 monitor_central_chan;/* monitor central channel */
318++ u8 monitor_bw;
319++ u8 monitor_tx_stream;
320++ u8 monitor_rx_stream;
321++
322++ u8 scan_mode; /* 0: ScanStop
323++ * 1: ScanStart
324++ * 2: ScanRunning
325++ */
326++ u8 band_idx; /* DBDC */
327++ u8 monitor_scan_type;
328++ u8 band; /* 0: 2.4GHz, 1: 5GHz */
329++ u8 rsv[2];
330++} __packed;
331++
332+ struct mt7915_mcu_eeprom {
333+ u8 buffer_mode;
334+ u8 format;
335+@@ -286,6 +309,7 @@ enum {
336+ MCU_EXT_CMD_SCS_CTRL = 0x82,
337+ MCU_EXT_CMD_TWT_AGRT_UPDATE = 0x94,
338+ MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
339++ MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a,
340+ MCU_EXT_CMD_SET_RDD_TH = 0x9d,
341+ MCU_EXT_CMD_MURU_CTRL = 0x9f,
342+ MCU_EXT_CMD_SET_SPR = 0xa8,
343+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
344+index 27dcd3f..f3449eb 100644
345+--- a/mt7915/mt7915.h
346++++ b/mt7915/mt7915.h
347+@@ -298,6 +298,10 @@ struct mt7915_dev {
348+ struct tasklet_struct irq_tasklet;
349+ struct mt7915_phy phy;
350+
351++ /* monitor rx chain configured channel */
352++ struct cfg80211_chan_def rdd2_chandef;
353++ struct mt7915_phy *rdd2_phy;
354++
355+ u16 chainmask;
356+ u32 hif_idx;
357+
358+@@ -379,6 +383,7 @@ enum {
359+ enum {
360+ MT_RX_SEL0,
361+ MT_RX_SEL1,
362++ MT_RX_SEL2, /* monitor chain */
363+ };
364+
365+ enum mt7915_rdd_cmd {
366+@@ -516,6 +521,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
367+ struct ieee80211_sta *sta, struct rate_info *rate);
368+ int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev, enum mt7915_rdd_cmd cmd,
369+ u8 index, u8 rx_sel, u8 val);
370++int mt7915_mcu_rdd_offchan_enable(struct mt7915_phy *phy,
371++ struct cfg80211_chan_def *chandef);
372+ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
373+ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
374+ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
375+