Skip to content

Commit bc35dba

Browse files
committed
add mt76 patches which add support for 802.11p and 5/10MHz for ITS infos
1 parent e676194 commit bc35dba

3 files changed

Lines changed: 334 additions & 0 deletions
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
From: Florian Maurer <fmaurer@disroot.org>
2+
Date: Mon, 24 Aug 2026 12:05:07 +0000
3+
Subject: wifi: mt76: decode 5 and 10 MHz bandwidths in the RX rate path
4+
5+
diff --git a/package/kernel/mt76/patches/900-wifi-mt76-decode-5-and-10-MHz-bandwidths-in-rx-rate.patch b/package/kernel/mt76/patches/900-wifi-mt76-decode-5-and-10-MHz-bandwidths-in-rx-rate.patch
6+
new file mode 100644
7+
--- /dev/null
8+
+++ b/package/kernel/mt76/patches/900-wifi-mt76-decode-5-and-10-MHz-bandwidths-in-rx-rate.patch
9+
@@ -0,0 +1,122 @@
10+
+From 20ae4b84f2f6614d03d077ef76108e9841be1f25 Mon Sep 17 00:00:00 2001
11+
+From: Florian Maurer <fmaurer@disroot.org>
12+
+Date: Mon, 24 Aug 2026 12:04:23 +0000
13+
+Subject: [PATCH mt76] wifi: mt76: decode 5 and 10 MHz bandwidths in the RX
14+
+ rate path
15+
+
16+
+mt76_connac2_mac_fill_rx_rate(), mt7615_mac_fill_rx(),
17+
+mt7925_mac_fill_rx_rate(), and mt7996_mac_fill_rx_rate() translate
18+
+the frame mode field of the RX vector into status->bw, but only handle
19+
+the 20, 40, 80 and 160/320 MHz widths that standard bandwidth enums cover.
20+
+Any other value falls into the default case and returns -EINVAL.
21+
+
22+
+That error is not benign. Calling functions pass it straight up to
23+
+the RX queue processing which frees the skb without incrementing any
24+
+counter, so a frame received at an unexpected bandwidth disappears with
25+
+no trace in dmesg, in the netdev statistics or in debugfs.
26+
+
27+
+The frame mode field in the RX vector encodes half- and quarter-clocked
28+
+OFDM bandwidths right after the wide bandwidth values in the same way the
29+
+CBW field of the channel switch command does. Handle CMD_CBW_10MHZ and
30+
+CMD_CBW_5MHZ across the mt76 driver family, and warn about anything still
31+
+unrecognised instead of dropping it silently.
32+
+
33+
+Signed-off-by: Florian Maurer <fmaurer@disroot.org>
34+
+---
35+
+ mt7615/mac.c | 9 +++++++++
36+
+ mt76_connac_mac.c | 14 ++++++++++++++
37+
+ mt7925/mac.c | 9 +++++++++
38+
+ mt7996/mac.c | 9 +++++++++
39+
+ 4 files changed, 41 insertions(+)
40+
+
41+
+diff --git a/mt7615/mac.c b/mt7615/mac.c
42+
+index bd56cdb0..6127ec9d 100644
43+
+--- a/mt7615/mac.c
44+
++++ b/mt7615/mac.c
45+
+@@ -557,7 +557,16 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
46+
+ case MT_PHY_BW_160:
47+
+ status->bw = RATE_INFO_BW_160;
48+
+ break;
49+
++ case CMD_CBW_10MHZ:
50+
++ status->bw = RATE_INFO_BW_10;
51+
++ break;
52+
++ case CMD_CBW_5MHZ:
53+
++ status->bw = RATE_INFO_BW_5;
54+
++ break;
55+
+ default:
56+
++ dev_warn_ratelimited(dev->mt76.dev,
57+
++ "rx: unhandled frame mode %u in rate decode\n",
58+
++ (u8)FIELD_GET(MT_RXV1_FRAME_MODE, rxdg0));
59+
+ return -EINVAL;
60+
+ }
61+
+
62+
+diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c
63+
+index 3304b597..0451d129 100644
64+
+--- a/mt76_connac_mac.c
65+
++++ b/mt76_connac_mac.c
66+
+@@ -1119,7 +1119,21 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
67+
+ case IEEE80211_STA_RX_BW_160:
68+
+ status->bw = RATE_INFO_BW_160;
69+
+ break;
70+
++ /* The RXV frame mode field reuses the encoding of the CBW field of
71+
++ * the channel switch command, which continues past the widths
72+
++ * covered by enum ieee80211_sta_rx_bandwidth with the narrow,
73+
++ * half- and quarter-clocked OFDM bandwidths.
74+
++ */
75+
++ case CMD_CBW_10MHZ:
76+
++ status->bw = RATE_INFO_BW_10;
77+
++ break;
78+
++ case CMD_CBW_5MHZ:
79+
++ status->bw = RATE_INFO_BW_5;
80+
++ break;
81+
+ default:
82+
++ dev_warn_ratelimited(dev->dev,
83+
++ "rx: unhandled frame mode %u in rate decode\n",
84+
++ bw);
85+
+ return -EINVAL;
86+
+ }
87+
+
88+
+diff --git a/mt7925/mac.c b/mt7925/mac.c
89+
+index fa75fb58..b595866b 100644
90+
+--- a/mt7925/mac.c
91+
++++ b/mt7925/mac.c
92+
+@@ -339,7 +339,16 @@ mt7925_mac_fill_rx_rate(struct mt792x_dev *dev,
93+
+ case IEEE80211_STA_RX_BW_160:
94+
+ status->bw = RATE_INFO_BW_160;
95+
+ break;
96+
++ case CMD_CBW_10MHZ:
97+
++ status->bw = RATE_INFO_BW_10;
98+
++ break;
99+
++ case CMD_CBW_5MHZ:
100+
++ status->bw = RATE_INFO_BW_5;
101+
++ break;
102+
+ default:
103+
++ dev_warn_ratelimited(dev->mt76.dev,
104+
++ "rx: unhandled frame mode %u in rate decode\n",
105+
++ bw);
106+
+ return -EINVAL;
107+
+ }
108+
+
109+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
110+
+index 753c6987..ecb1fe6f 100644
111+
+--- a/mt7996/mac.c
112+
++++ b/mt7996/mac.c
113+
+@@ -408,7 +408,16 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
114+
+ case IEEE80211_STA_RX_BW_320 + 1:
115+
+ status->bw = RATE_INFO_BW_320;
116+
+ break;
117+
++ case CMD_CBW_10MHZ:
118+
++ status->bw = RATE_INFO_BW_10;
119+
++ break;
120+
++ case CMD_CBW_5MHZ:
121+
++ status->bw = RATE_INFO_BW_5;
122+
++ break;
123+
+ default:
124+
++ dev_warn_ratelimited(dev->mt76.dev,
125+
++ "rx: unhandled frame mode %u in rate decode\n",
126+
++ bw);
127+
+ return -EINVAL;
128+
+ }
129+
+
130+
+--
131+
+2.47.3
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
From: Florian Maurer <fmaurer@disroot.org>
2+
Date: Mon, 24 Aug 2026 12:05:07 +0000
3+
Subject: wifi: mt76: mt7915: handle narrow bandwidths in channel configuration
4+
5+
diff --git a/package/kernel/mt76/patches/901-wifi-mt76-mt7915-skip-Tx-DPD-for-narrow-bandwidths.patch b/package/kernel/mt76/patches/901-wifi-mt76-mt7915-skip-Tx-DPD-for-narrow-bandwidths.patch
6+
new file mode 100644
7+
--- /dev/null
8+
+++ b/package/kernel/mt76/patches/901-wifi-mt76-mt7915-skip-Tx-DPD-for-narrow-bandwidths.patch
9+
@@ -0,0 +1,65 @@
10+
+From 3207e18b3540c669ff5371fd3ad84265c3432ff1 Mon Sep 17 00:00:00 2001
11+
+From: Florian Maurer <fmaurer@disroot.org>
12+
+Date: Mon, 24 Aug 2026 12:04:23 +0000
13+
+Subject: [PATCH mt76] wifi: mt76: mt7915: handle narrow bandwidths in channel
14+
+ configuration
15+
+
16+
+mt7915_mcu_apply_tx_dpd() looks the current centre frequency up in a
17+
+table of pre-calibrated frequencies and returns -EINVAL when it is not
18+
+found. mt7915_set_channel() calls it early and aborts on any error, so a
19+
+missing pre-calibration entry fails the whole channel switch.
20+
+
21+
+The tables list the centre frequencies of the 20 MHz and wider channels
22+
+only. A half- or quarter-clocked channel can never match one, which
23+
+makes every attempt to tune such a channel fail on a device that has
24+
+pre-calibration data in its EEPROM. Return early and leave existing DPD
25+
+settings in place.
26+
+
27+
+Additionally, the MT7915 MCU firmware validator only accepts standard
28+
+channel bandwidths (20, 40, 80, 160 MHz) in set_chan_info and stalls if
29+
+passed narrow bandwidth codes (5/10 MHz). Fall back to CMD_CBW_20MHZ
30+
+when issuing MCU_EXT_CMD(CHANNEL_SWITCH) and MCU_EXT_CMD(SET_RX_PATH) so
31+
+the RF PLL locks to the channel center without stalling the firmware.
32+
+
33+
+Signed-off-by: Florian Maurer <fmaurer@disroot.org>
34+
+---
35+
+ mt7915/mcu.c | 17 +++++++++++++++++
36+
+ 1 file changed, 17 insertions(+)
37+
+
38+
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
39+
+index 4348c280..13c52050 100644
40+
+--- a/mt7915/mcu.c
41+
++++ b/mt7915/mcu.c
42+
+@@ -2845,6 +2845,14 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
43+
+ .channel_band = ch_band[chandef->chan->band],
44+
+ };
45+
+
46+
++ /* The MT7915 MCU firmware only accepts standard bandwidths (20, 40,
47+
++ * 80, 160 MHz) in set_chan_info. Fall back to 20 MHz for narrow
48+
++ * bandwidths so the RF PLL locks to the channel center without
49+
++ * stalling the firmware.
50+
++ */
51+
++ if (req.bw == CMD_CBW_5MHZ || req.bw == CMD_CBW_10MHZ)
52+
++ req.bw = CMD_CBW_20MHZ;
53+
++
54+
+ #ifdef CONFIG_NL80211_TESTMODE
55+
+ if (phy->mt76->test.tx_antenna_mask &&
56+
+ mt76_testmode_enabled(phy->mt76)) {
57+
+@@ -3163,6 +3171,15 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
58+
+ if (!(eep[offs] & dpd_mask))
59+
+ return 0;
60+
+
61+
++ /* The pre-calibration data is indexed by the centre frequencies of
62+
++ * the 20 MHz and wider channels only, so there is no entry to apply
63+
++ * for the half- and quarter-clocked bandwidths. Keep whatever is
64+
++ * already programmed instead of failing the channel switch.
65+
++ */
66+
++ if (chandef->width == NL80211_CHAN_WIDTH_5 ||
67+
++ chandef->width == NL80211_CHAN_WIDTH_10)
68+
++ return 0;
69+
++
70+
+ idx = mt7915_dpd_freq_idx(dev, center_freq, chandef->width);
71+
+ if (idx < 0)
72+
+ return -EINVAL;
73+
+--
74+
+2.47.3
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
From: Florian Maurer <fmaurer@disroot.org>
2+
Date: Mon, 24 Aug 2026 12:05:07 +0000
3+
Subject: wifi: mt76: add optional support for 5 and 10 MHz channels
4+
5+
diff --git a/package/kernel/mt76/patches/902-wifi-mt76-add-optional-support-for-5-and-10-MHz-chan.patch b/package/kernel/mt76/patches/902-wifi-mt76-add-optional-support-for-5-and-10-MHz-chan.patch
6+
new file mode 100644
7+
--- /dev/null
8+
+++ b/package/kernel/mt76/patches/902-wifi-mt76-add-optional-support-for-5-and-10-MHz-chan.patch
9+
@@ -0,0 +1,120 @@
10+
+From a412cf60d684eb29a85446d5a1ee91dd937f56b2 Mon Sep 17 00:00:00 2001
11+
+From: Florian Maurer <fmaurer@disroot.org>
12+
+Date: Mon, 24 Aug 2026 12:04:23 +0000
13+
+Subject: [PATCH mt76] wifi: mt76: add optional support for 5 and 10 MHz
14+
+ channels
15+
+
16+
+IEEE 802.11p / ETSI ITS-G5 uses half-clocked 10 MHz channels in the
17+
+5.9 GHz band. The connac channel switch command already carries the
18+
+narrow bandwidths through mt76_connac_chan_bw(), but cfg80211 rejects a
19+
+10 MHz chandef before it ever reaches the driver because the wiphy does
20+
+not advertise WIPHY_FLAG_SUPPORTS_5_10_MHZ, and the 5 GHz channel list
21+
+ends at channel 177.
22+
+
23+
+Add an enable_5_10mhz module parameter, off by default, that advertises
24+
+the capability and registers the ITS-G5 channel centres. The extra
25+
+channels are appended to the end of the channel table so that leaving
26+
+the parameter unset registers exactly the same channel list as before
27+
+and sets exactly the same wiphy flags as before.
28+
+
29+
+No regulatory domain permits regular operation on these channels, so
30+
+they are marked IEEE80211_CHAN_CAN_MONITOR: a monitor interface can tune
31+
+them for passive reception, while any attempt to transmit is still
32+
+refused by the regulatory code.
33+
+
34+
+Signed-off-by: Florian Maurer <fmaurer@disroot.org>
35+
+---
36+
+ mac80211.c | 43 +++++++++++++++++++++++++++++++++++++++++--
37+
+ 1 file changed, 41 insertions(+), 2 deletions(-)
38+
+
39+
+diff --git a/mac80211.c b/mac80211.c
40+
+index ff86f4f5..89afee40 100644
41+
+--- a/mac80211.c
42+
++++ b/mac80211.c
43+
+@@ -4,8 +4,14 @@
44+
+ */
45+
+ #include <linux/sched.h>
46+
+ #include <linux/of.h>
47+
++#include <linux/moduleparam.h>
48+
+ #include "mt76.h"
49+
+
50+
++static bool enable_5_10mhz;
51+
++module_param(enable_5_10mhz, bool, 0444);
52+
++MODULE_PARM_DESC(enable_5_10mhz,
53+
++ "Enable 5 and 10 MHz channel widths and expose the 5.9 GHz ITS-G5 channels for monitoring (default: off)");
54+
++
55+
+ #define CHAN2G(_idx, _freq) { \
56+
+ .band = NL80211_BAND_2GHZ, \
57+
+ .center_freq = (_freq), \
58+
+@@ -20,6 +26,18 @@
59+
+ .max_power = 30, \
60+
+ }
61+
+
62+
++/* Channels that are only ever usable for passive monitoring. They carry
63+
++ * IEEE80211_CHAN_CAN_MONITOR so that a monitor interface may tune them even
64+
++ * though no regulatory domain permits regular operation there.
65+
++ */
66+
++#define CHAN5G_MON(_idx, _freq) { \
67+
++ .band = NL80211_BAND_5GHZ, \
68+
++ .center_freq = (_freq), \
69+
++ .hw_value = (_idx), \
70+
++ .max_power = 30, \
71+
++ .flags = IEEE80211_CHAN_CAN_MONITOR, \
72+
++}
73+
++
74+
+ #define CHAN6G(_idx, _freq) { \
75+
+ .band = NL80211_BAND_6GHZ, \
76+
+ .center_freq = (_freq), \
77+
+@@ -76,8 +94,22 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
78+
+ CHAN5G(169, 5845),
79+
+ CHAN5G(173, 5865),
80+
+ CHAN5G(177, 5885),
81+
++
82+
++ /* IEEE 802.11p / ETSI ITS-G5 channels in the 5.9 GHz band. These are
83+
++ * appended after the regular channels so that they can be left out
84+
++ * simply by registering fewer of them, see mt76_init_sband_5g().
85+
++ */
86+
++ CHAN5G_MON(172, 5860),
87+
++ CHAN5G_MON(174, 5870),
88+
++ CHAN5G_MON(176, 5880),
89+
++ CHAN5G_MON(178, 5890),
90+
++ CHAN5G_MON(180, 5900),
91+
++ CHAN5G_MON(182, 5910),
92+
++ CHAN5G_MON(184, 5920),
93+
+ };
94+
+
95+
++#define MT76_N_CHANNELS_5GHZ_ITS 7
96+
++
97+
+ static const struct ieee80211_channel mt76_channels_6ghz[] = {
98+
+ /* UNII-5 */
99+
+ CHAN6G(1, 5955),
100+
+@@ -373,11 +405,15 @@ static int
101+
+ mt76_init_sband_5g(struct mt76_phy *phy, struct ieee80211_rate *rates,
102+
+ int n_rates, bool vht)
103+
+ {
104+
++ int n_chan = ARRAY_SIZE(mt76_channels_5ghz);
105+
++
106+
+ phy->hw->wiphy->bands[NL80211_BAND_5GHZ] = &phy->sband_5g.sband;
107+
+
108+
++ if (!enable_5_10mhz)
109+
++ n_chan -= MT76_N_CHANNELS_5GHZ_ITS;
110+
++
111+
+ return mt76_init_sband(phy, &phy->sband_5g, mt76_channels_5ghz,
112+
+- ARRAY_SIZE(mt76_channels_5ghz), rates,
113+
+- n_rates, true, vht);
114+
++ n_chan, rates, n_rates, true, vht);
115+
+ }
116+
+
117+
+ static int
118+
+@@ -445,6 +481,9 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
119+
+ WIPHY_FLAG_SUPPORTS_TDLS |
120+
+ WIPHY_FLAG_AP_UAPSD;
121+
+
122+
++ if (enable_5_10mhz)
123+
++ wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
124+
++
125+
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
126+
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
127+
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
128+
+--
129+
+2.47.3

0 commit comments

Comments
 (0)