Skip to content

Commit 096b743

Browse files
StanleyYP Wanggregkh
authored andcommitted
wifi: mt76: mt7996: fix the behavior of radar detection
[ Upstream commit 45a0925 ] RDD_DET_MODE is a firmware command intended for testing and does not pause TX after radar detection, so remove it from the normal flow; instead, use the MAC_ENABLE_CTRL firmware command to resume TX after the radar-triggered channel switch completes. Fixes: 1529e33 ("wifi: mt76: mt7996: rework radar HWRDD idx") Co-developed-by: Shayne Chen <shayne.chen@mediatek.com> Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> Link: https://patch.msgid.link/20251215063728.3013365-2-shayne.chen@mediatek.com Signed-off-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d902905 commit 096b743

5 files changed

Lines changed: 68 additions & 12 deletions

File tree

drivers/net/wireless/mediatek/mt76/mt7996/mac.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2944,7 +2944,7 @@ static void mt7996_dfs_stop_radar_detector(struct mt7996_phy *phy)
29442944

29452945
static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int rdd_idx)
29462946
{
2947-
int err, region;
2947+
int region;
29482948

29492949
switch (dev->mt76.region) {
29502950
case NL80211_DFS_ETSI:
@@ -2959,11 +2959,7 @@ static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int rdd_idx)
29592959
break;
29602960
}
29612961

2962-
err = mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
2963-
if (err < 0)
2964-
return err;
2965-
2966-
return mt7996_mcu_rdd_cmd(dev, RDD_DET_MODE, rdd_idx, 1);
2962+
return mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
29672963
}
29682964

29692965
static int mt7996_dfs_start_radar_detector(struct mt7996_phy *phy)

drivers/net/wireless/mediatek/mt76/mt7996/main.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static void mt7996_stop_phy(struct mt7996_phy *phy)
7979

8080
mutex_lock(&dev->mt76.mutex);
8181

82+
mt7996_mcu_rdd_resume_tx(phy);
8283
mt7996_mcu_set_radio_en(phy, false);
8384

8485
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
@@ -933,6 +934,24 @@ mt7996_channel_switch_beacon(struct ieee80211_hw *hw,
933934
mutex_unlock(&dev->mt76.mutex);
934935
}
935936

937+
static int
938+
mt7996_post_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
939+
struct ieee80211_bss_conf *link_conf)
940+
{
941+
struct cfg80211_chan_def *chandef = &link_conf->chanreq.oper;
942+
struct mt7996_dev *dev = mt7996_hw_dev(hw);
943+
struct mt7996_phy *phy = mt7996_band_phy(dev, chandef->chan->band);
944+
int ret;
945+
946+
mutex_lock(&dev->mt76.mutex);
947+
948+
ret = mt7996_mcu_rdd_resume_tx(phy);
949+
950+
mutex_unlock(&dev->mt76.mutex);
951+
952+
return ret;
953+
}
954+
936955
static int
937956
mt7996_mac_sta_init_link(struct mt7996_dev *dev,
938957
struct ieee80211_bss_conf *link_conf,
@@ -2295,6 +2314,7 @@ const struct ieee80211_ops mt7996_ops = {
22952314
.release_buffered_frames = mt76_release_buffered_frames,
22962315
.get_txpower = mt7996_get_txpower,
22972316
.channel_switch_beacon = mt7996_channel_switch_beacon,
2317+
.post_channel_switch = mt7996_post_channel_switch,
22982318
.get_stats = mt7996_get_stats,
22992319
.get_et_sset_count = mt7996_get_et_sset_count,
23002320
.get_et_stats = mt7996_get_et_stats,

drivers/net/wireless/mediatek/mt76/mt7996/mcu.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -413,24 +413,32 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
413413
break;
414414
case MT_RDD_IDX_BACKGROUND:
415415
if (!dev->rdd2_phy)
416-
return;
416+
goto err;
417417
mphy = dev->rdd2_phy->mt76;
418418
break;
419419
default:
420-
dev_err(dev->mt76.dev, "Unknown RDD idx %d\n", r->rdd_idx);
421-
return;
420+
goto err;
422421
}
423422

424423
if (!mphy)
425-
return;
424+
goto err;
426425

427-
if (r->rdd_idx == MT_RDD_IDX_BACKGROUND)
426+
if (r->rdd_idx == MT_RDD_IDX_BACKGROUND) {
428427
cfg80211_background_radar_event(mphy->hw->wiphy,
429428
&dev->rdd2_chandef,
430429
GFP_ATOMIC);
431-
else
430+
} else {
431+
struct mt7996_phy *phy = mphy->priv;
432+
433+
phy->rdd_tx_paused = true;
432434
ieee80211_radar_detected(mphy->hw, NULL);
435+
}
433436
dev->hw_pattern++;
437+
438+
return;
439+
440+
err:
441+
dev_err(dev->mt76.dev, "Invalid RDD idx %d\n", r->rdd_idx);
434442
}
435443

436444
static void
@@ -4554,6 +4562,35 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable)
45544562
&req, sizeof(req), true);
45554563
}
45564564

4565+
int mt7996_mcu_rdd_resume_tx(struct mt7996_phy *phy)
4566+
{
4567+
struct {
4568+
u8 band_idx;
4569+
u8 _rsv[3];
4570+
4571+
__le16 tag;
4572+
__le16 len;
4573+
u8 mac_enable;
4574+
u8 _rsv2[3];
4575+
} __packed req = {
4576+
.band_idx = phy->mt76->band_idx,
4577+
.tag = cpu_to_le16(UNI_BAND_CONFIG_MAC_ENABLE_CTRL),
4578+
.len = cpu_to_le16(sizeof(req) - 4),
4579+
.mac_enable = 2,
4580+
};
4581+
int ret;
4582+
4583+
if (!phy->rdd_tx_paused)
4584+
return 0;
4585+
4586+
ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),
4587+
&req, sizeof(req), true);
4588+
if (!ret)
4589+
phy->rdd_tx_paused = false;
4590+
4591+
return ret;
4592+
}
4593+
45574594
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val)
45584595
{
45594596
struct {

drivers/net/wireless/mediatek/mt76/mt7996/mcu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,7 @@ enum {
837837
enum {
838838
UNI_BAND_CONFIG_RADIO_ENABLE,
839839
UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
840+
UNI_BAND_CONFIG_MAC_ENABLE_CTRL = 0x0c,
840841
};
841842

842843
enum {

drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ struct mt7996_phy {
376376

377377
bool has_aux_rx;
378378
bool counter_reset;
379+
bool rdd_tx_paused;
379380
};
380381

381382
struct mt7996_dev {
@@ -725,6 +726,7 @@ int mt7996_mcu_get_temperature(struct mt7996_phy *phy);
725726
int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
726727
int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
727728
int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
729+
int mt7996_mcu_rdd_resume_tx(struct mt7996_phy *phy);
728730
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val);
729731
int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
730732
struct cfg80211_chan_def *chandef);

0 commit comments

Comments
 (0)