From: JB Tsai <jb.tsai@mediatek.com>
To: <nbd@nbd.name>, <lorenzo@kernel.org>
Cc: <linux-wireless@vger.kernel.org>,
<linux-mediatek@lists.infradead.org>, <Sean.Wang@mediatek.com>,
<James-LY.Huang@mediatek.com>, <jb.tsai@mediatek.com>,
james-ly huang <james-ly.huang@mediatek.com>
Subject: [PATCH 5/9] wifi: mt76: mt7925: describe the real chandef in ROC requests
Date: Wed, 4 Nov 2026 17:23:40 +0800 [thread overview]
Message-ID: <20261104092344.1932406-5-jb.tsai@mediatek.com> (raw)
In-Reply-To: <20261104092344.1932406-1-jb.tsai@mediatek.com>
From: james-ly huang <james-ly.huang@mediatek.com>
Resolve the full chandef behind the bare channel (mt7925_mcu_roc_chandef):
for a BSS-bound request the BSS's own chanctx already describes that
channel; everything else (off-channel dwell) keeps the 20 MHz NOHT
description, which is what a listen dwell actually uses. Program bw /
center_chan / center_chan2 accordingly, and derive sco from the
primary 40 MHz block instead of comparing against the center channel.
Map the nl80211 channel width to the fw ENUM_CHANNEL_WIDTH_T encoding
via mt7925_chandef_to_cw() and the new MT7925_CW_* enum (the fw casts
roc.bw straight to that enum, so CMD_CBW_* values must not be used).
Signed-off-by: james-ly huang <james-ly.huang@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7925/mcu.c | 88 +++++++++++++++++--
.../wireless/mediatek/mt76/mt7925/mt7925.h | 13 +++
2 files changed, 92 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index 2ce403000765..056f7e2f284e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -1593,11 +1593,57 @@ int mt7925_mcu_set_mlo_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf
&req, sizeof(req), true);
}
+/* Resolve the full chandef behind a bare ieee80211_channel.
+ *
+ * The CNM channel-privilege request carries bw / center_chan / center_chan2 /
+ * sco, and for a BSS-bound request they must match the BSS's own channel.
+ * mt7925 only has a bare channel at this point, but for a BSS-bound
+ * request (JOIN) the BSS's own chanctx already describes exactly that
+ * channel, so use it.
+ *
+ * Everything else - an off-channel dwell (ROC / OFFCHNL_TX), or a request for a
+ * channel that is not the one this BSS is parked on - keeps the previous 20 MHz
+ * NOHT description, which is what a listen dwell actually uses anyway.
+ */
+static void
+mt7925_mcu_roc_chandef(struct mt792x_bss_conf *mconf,
+ struct ieee80211_channel *chan,
+ enum mt7925_roc_req type,
+ struct cfg80211_chan_def *chandef)
+{
+ if (type == MT7925_ROC_REQ_JOIN &&
+ mconf->mt76.ctx && mconf->mt76.ctx->def.chan == chan) {
+ *chandef = mconf->mt76.ctx->def;
+ return;
+ }
+
+ cfg80211_chandef_create(chandef, chan, NL80211_CHAN_NO_HT);
+}
+
+static u8 mt7925_chandef_to_cw(const struct cfg80211_chan_def *chandef)
+{
+ static const u8 width_to_cw[] = {
+ [NL80211_CHAN_WIDTH_20_NOHT] = MT7925_CW_20_40MHZ,
+ [NL80211_CHAN_WIDTH_20] = MT7925_CW_20_40MHZ,
+ [NL80211_CHAN_WIDTH_40] = MT7925_CW_20_40MHZ,
+ [NL80211_CHAN_WIDTH_80] = MT7925_CW_80MHZ,
+ [NL80211_CHAN_WIDTH_160] = MT7925_CW_160MHZ,
+ [NL80211_CHAN_WIDTH_80P80] = MT7925_CW_80P80MHZ,
+ [NL80211_CHAN_WIDTH_5] = MT7925_CW_5MHZ,
+ [NL80211_CHAN_WIDTH_10] = MT7925_CW_10MHZ,
+ [NL80211_CHAN_WIDTH_320] = MT7925_CW_320MHZ,
+ };
+
+ if (chandef->width >= ARRAY_SIZE(width_to_cw))
+ return 0;
+
+ return width_to_cw[chandef->width];
+}
+
int mt7925_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf,
struct ieee80211_channel *chan, int duration,
enum mt7925_roc_req type, u8 token_id)
{
- int center_ch = ieee80211_frequency_to_channel(chan->center_freq);
struct mt792x_dev *dev = phy->dev;
struct {
struct {
@@ -1613,18 +1659,42 @@ int mt7925_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf,
.maxinterval = cpu_to_le32(duration),
.bss_idx = mconf->mt76.idx,
.control_channel = chan->hw_value,
- .bw = CMD_CBW_20MHZ,
- .bw_from_ap = CMD_CBW_20MHZ,
- .center_chan = center_ch,
- .center_chan_from_ap = center_ch,
.dbdcband = 0xff, /* auto */
},
};
+ struct cfg80211_chan_def chandef;
+ int center_ch, pri40_freq;
+ u8 bw;
+
+ mt7925_mcu_roc_chandef(mconf, chan, type, &chandef);
+ center_ch = ieee80211_frequency_to_channel(chandef.center_freq1);
+ bw = mt7925_chandef_to_cw(&chandef);
+
+ /* Describe the REAL chandef, not a 20 MHz stub: CNM uses bw / center_chan
+ * to pick the band and to decide whether the request can share an existing
+ * SCC.
+ */
+ req.roc.bw = bw;
+ req.roc.bw_from_ap = bw;
+ req.roc.center_chan = center_ch;
+ req.roc.center_chan_from_ap = center_ch;
- if (chan->hw_value < center_ch)
- req.roc.sco = 1; /* SCA */
- else if (chan->hw_value > center_ch)
- req.roc.sco = 3; /* SCB */
+ if (chandef.center_freq2) {
+ u8 center_ch2 = ieee80211_frequency_to_channel(chandef.center_freq2);
+
+ req.roc.center_chan2 = center_ch2;
+ req.roc.center_chan2_from_ap = center_ch2;
+ }
+
+ /* Secondary channel offset of the PRIMARY 40 MHz block.
+ * sco: 0 = SCN, 1 = SCA (secondary above), 3 = SCB (secondary below).
+ */
+ if (nl80211_chan_width_to_mhz(chandef.width) >= 40) {
+ pri40_freq = cfg80211_chandef_primary(&chandef,
+ NL80211_CHAN_WIDTH_40, NULL);
+ if (pri40_freq > 0)
+ req.roc.sco = chan->center_freq < pri40_freq ? 1 : 3;
+ }
switch (chan->band) {
case NL80211_BAND_6GHZ:
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
index 636efe038392..36cbeaedb7b2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
@@ -60,6 +60,19 @@ enum {
UNI_ROC_NUM
};
+/* firmware channel width encoding (FW ENUM_CHANNEL_WIDTH_T), differs from
+ * CMD_CBW_*
+ */
+enum mt7925_fw_chan_width {
+ MT7925_CW_20_40MHZ,
+ MT7925_CW_80MHZ,
+ MT7925_CW_160MHZ,
+ MT7925_CW_80P80MHZ,
+ MT7925_CW_5MHZ,
+ MT7925_CW_10MHZ,
+ MT7925_CW_320MHZ,
+};
+
enum mt7925_roc_req {
MT7925_ROC_REQ_JOIN,
MT7925_ROC_REQ_ROC,
--
2.45.2
next prev parent reply other threads:[~2026-11-04 9:24 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 9:23 [PATCH 1/9] wifi: mt76: mt7925: drop P2P mgmt frames received on foreign channel JB Tsai
2026-11-04 9:23 ` [PATCH 2/9] wifi: mt76: mt7925: bound P2P off-channel mgmt TX lifetime JB Tsai
2026-11-04 9:23 ` [PATCH 3/9] wifi: mt76: mt7925: give every P2P interface a BMC wcid of its own JB Tsai
2026-11-04 9:23 ` [PATCH 4/9] wifi: mt76: mt7925: harden the ROC channel-grant handshake JB Tsai
2026-11-04 9:23 ` JB Tsai [this message]
2026-11-04 9:23 ` [PATCH 6/9] wifi: mt76: mt7925: request the channel before programming a GO BSS JB Tsai
2026-11-04 9:23 ` [PATCH 7/9] wifi: mt76: mt7925: inject the deauth for an aging-timeout SAP event JB Tsai
2026-11-06 0:34 ` kernel test robot
2026-11-04 9:23 ` [PATCH 8/9] wifi: mt76: mt7925: track BSS absence and drop stale GO probe responses JB Tsai
2026-11-04 9:23 ` [PATCH 9/9] wifi: mt76: mt7925: send the common scan IEs and size the request JB Tsai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261104092344.1932406-5-jb.tsai@mediatek.com \
--to=jb.tsai@mediatek.com \
--cc=James-LY.Huang@mediatek.com \
--cc=Sean.Wang@mediatek.com \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
--cc=lorenzo@kernel.org \
--cc=nbd@nbd.name \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox