wifi: mt76: mt7996: rework radar HWRDD idx

The definition of MT_RX_SEL (for rdd_rx_sel) is mixed with the
definition of HWRDD idx.
For example, MT_RX_SEL2 is for background HWRDD idx, not an
option of rdd_rx_sel.
Additionally, HWRDD idx does not exactly map to band idx for
Connac 3 chips. So, add mt7996_get_rdd_idx as a helper function.

Finally, remove some parts of the code inherited from the legacy chips.
For instance,
1. rdd_state is used for single-band-dual-HWRDD chips (for 80+80),
especially the 76xx series.
2. rdd_rx_sel is also used for single-band-dual-HWRDD chips
rx_sel = 0 => RDD0 for WF0, RDD1 for WF2
rx_sel = 1 => RDD0 for WF1, RDD1 for WF3

Chip Variants              | 5G rdd idx     | Background rdd idx
---------------------------|----------------|-------------------
MT7996 (except 205/255)    | 1              | 2
MT7992                     | 1              | 2
MT7990                     | 1              | 2

Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
Reviewed-by: Money Wang <money.wang@mediatek.com>
Link: https://patch.msgid.link/20250320015926.3948672-1-StanleyYP.Wang@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
StanleyYP Wang 2025-03-20 09:59:26 +08:00 committed by Felix Fietkau
parent 758e0cc3a4
commit 1529e335f9
5 changed files with 75 additions and 69 deletions

View File

@ -222,18 +222,27 @@ static const struct file_operations mt7996_sys_recovery_ops = {
static int static int
mt7996_radar_trigger(void *data, u64 val) mt7996_radar_trigger(void *data, u64 val)
{ {
#define RADAR_MAIN_CHAIN 1
#define RADAR_BACKGROUND 2
struct mt7996_dev *dev = data; struct mt7996_dev *dev = data;
struct mt7996_phy *phy = mt7996_band_phy(dev, NL80211_BAND_5GHZ);
int rdd_idx;
if (val > MT_RX_SEL2) if (!phy || !val || val > RADAR_BACKGROUND)
return -EINVAL; return -EINVAL;
if (val == MT_RX_SEL2 && !dev->rdd2_phy) { if (val == RADAR_BACKGROUND && !dev->rdd2_phy) {
dev_err(dev->mt76.dev, "Background radar is not enabled\n"); dev_err(dev->mt76.dev, "Background radar is not enabled\n");
return -EINVAL; return -EINVAL;
} }
return mt7996_mcu_rdd_cmd(dev, RDD_RADAR_EMULATE, rdd_idx = mt7996_get_rdd_idx(phy, val == RADAR_BACKGROUND);
val, 0, 0); if (rdd_idx < 0) {
dev_err(dev->mt76.dev, "No RDD found\n");
return -EINVAL;
}
return mt7996_mcu_rdd_cmd(dev, RDD_RADAR_EMULATE, rdd_idx, 0);
} }
DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL, DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL,

View File

@ -2441,16 +2441,15 @@ void mt7996_mac_work(struct work_struct *work)
static void mt7996_dfs_stop_radar_detector(struct mt7996_phy *phy) static void mt7996_dfs_stop_radar_detector(struct mt7996_phy *phy)
{ {
struct mt7996_dev *dev = phy->dev; struct mt7996_dev *dev = phy->dev;
int rdd_idx = mt7996_get_rdd_idx(phy, false);
if (phy->rdd_state & BIT(0)) if (rdd_idx < 0)
mt7996_mcu_rdd_cmd(dev, RDD_STOP, 0, return;
MT_RX_SEL0, 0);
if (phy->rdd_state & BIT(1)) mt7996_mcu_rdd_cmd(dev, RDD_STOP, rdd_idx, 0);
mt7996_mcu_rdd_cmd(dev, RDD_STOP, 1,
MT_RX_SEL0, 0);
} }
static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int chain) static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int rdd_idx)
{ {
int err, region; int err, region;
@ -2467,44 +2466,30 @@ static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int chain)
break; break;
} }
err = mt7996_mcu_rdd_cmd(dev, RDD_START, chain, err = mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
MT_RX_SEL0, region);
if (err < 0) if (err < 0)
return err; return err;
return mt7996_mcu_rdd_cmd(dev, RDD_DET_MODE, chain, return mt7996_mcu_rdd_cmd(dev, RDD_DET_MODE, rdd_idx, 1);
MT_RX_SEL0, 1);
} }
static int mt7996_dfs_start_radar_detector(struct mt7996_phy *phy) static int mt7996_dfs_start_radar_detector(struct mt7996_phy *phy)
{ {
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
struct mt7996_dev *dev = phy->dev; struct mt7996_dev *dev = phy->dev;
u8 band_idx = phy->mt76->band_idx; int err, rdd_idx;
int err;
rdd_idx = mt7996_get_rdd_idx(phy, false);
if (rdd_idx < 0)
return -EINVAL;
/* start CAC */ /* start CAC */
err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_START, band_idx, err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_START, rdd_idx, 0);
MT_RX_SEL0, 0);
if (err < 0) if (err < 0)
return err; return err;
err = mt7996_dfs_start_rdd(dev, band_idx); err = mt7996_dfs_start_rdd(dev, rdd_idx);
if (err < 0)
return err;
phy->rdd_state |= BIT(band_idx); return err;
if (chandef->width == NL80211_CHAN_WIDTH_160 ||
chandef->width == NL80211_CHAN_WIDTH_80P80) {
err = mt7996_dfs_start_rdd(dev, 1);
if (err < 0)
return err;
phy->rdd_state |= BIT(1);
}
return 0;
} }
static int static int
@ -2545,12 +2530,12 @@ int mt7996_dfs_init_radar_detector(struct mt7996_phy *phy)
{ {
struct mt7996_dev *dev = phy->dev; struct mt7996_dev *dev = phy->dev;
enum mt76_dfs_state dfs_state, prev_state; enum mt76_dfs_state dfs_state, prev_state;
int err; int err, rdd_idx = mt7996_get_rdd_idx(phy, false);
prev_state = phy->mt76->dfs_state; prev_state = phy->mt76->dfs_state;
dfs_state = mt76_phy_dfs_state(phy->mt76); dfs_state = mt76_phy_dfs_state(phy->mt76);
if (prev_state == dfs_state) if (prev_state == dfs_state || rdd_idx < 0)
return 0; return 0;
if (prev_state == MT_DFS_STATE_UNKNOWN) if (prev_state == MT_DFS_STATE_UNKNOWN)
@ -2574,8 +2559,7 @@ int mt7996_dfs_init_radar_detector(struct mt7996_phy *phy)
if (dfs_state == MT_DFS_STATE_CAC) if (dfs_state == MT_DFS_STATE_CAC)
return 0; return 0;
err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_END, err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_END, rdd_idx, 0);
phy->mt76->band_idx, MT_RX_SEL0, 0);
if (err < 0) { if (err < 0) {
phy->mt76->dfs_state = MT_DFS_STATE_UNKNOWN; phy->mt76->dfs_state = MT_DFS_STATE_UNKNOWN;
return err; return err;
@ -2585,8 +2569,7 @@ int mt7996_dfs_init_radar_detector(struct mt7996_phy *phy)
return 0; return 0;
stop: stop:
err = mt7996_mcu_rdd_cmd(dev, RDD_NORMAL_START, err = mt7996_mcu_rdd_cmd(dev, RDD_NORMAL_START, rdd_idx, 0);
phy->mt76->band_idx, MT_RX_SEL0, 0);
if (err < 0) if (err < 0)
return err; return err;

View File

@ -380,21 +380,27 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
r = (struct mt7996_mcu_rdd_report *)skb->data; r = (struct mt7996_mcu_rdd_report *)skb->data;
if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys)) switch (r->rdd_idx) {
return; case MT_RDD_IDX_BAND2:
mphy = dev->mt76.phys[MT_BAND2];
if (r->band_idx == MT_RX_SEL2 && !dev->rdd2_phy) break;
return; case MT_RDD_IDX_BAND1:
mphy = dev->mt76.phys[MT_BAND1];
if (r->band_idx == MT_RX_SEL2) break;
case MT_RDD_IDX_BACKGROUND:
if (!dev->rdd2_phy)
return;
mphy = dev->rdd2_phy->mt76; mphy = dev->rdd2_phy->mt76;
else break;
mphy = dev->mt76.phys[r->band_idx]; default:
dev_err(dev->mt76.dev, "Unknown RDD idx %d\n", r->rdd_idx);
return;
}
if (!mphy) if (!mphy)
return; return;
if (r->band_idx == MT_RX_SEL2) if (r->rdd_idx == MT_RDD_IDX_BACKGROUND)
cfg80211_background_radar_event(mphy->hw->wiphy, cfg80211_background_radar_event(mphy->hw->wiphy,
&dev->rdd2_chandef, &dev->rdd2_chandef,
GFP_ATOMIC); GFP_ATOMIC);
@ -3557,11 +3563,10 @@ int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
struct cfg80211_chan_def *chandef) struct cfg80211_chan_def *chandef)
{ {
struct mt7996_dev *dev = phy->dev; struct mt7996_dev *dev = phy->dev;
int err, region; int err, region, rdd_idx = mt7996_get_rdd_idx(phy, true);
if (!chandef) { /* disable offchain */ if (!chandef) { /* disable offchain */
err = mt7996_mcu_rdd_cmd(dev, RDD_STOP, MT_RX_SEL2, err = mt7996_mcu_rdd_cmd(dev, RDD_STOP, rdd_idx, 0);
0, 0);
if (err) if (err)
return err; return err;
@ -3587,8 +3592,7 @@ int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
break; break;
} }
return mt7996_mcu_rdd_cmd(dev, RDD_START, MT_RX_SEL2, return mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
0, region);
} }
int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag) int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
@ -4455,8 +4459,7 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable)
&req, sizeof(req), true); &req, sizeof(req), true);
} }
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index, int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val)
u8 rx_sel, u8 val)
{ {
struct { struct {
u8 _rsv[4]; u8 _rsv[4];
@ -4473,8 +4476,7 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
.tag = cpu_to_le16(UNI_RDD_CTRL_PARM), .tag = cpu_to_le16(UNI_RDD_CTRL_PARM),
.len = cpu_to_le16(sizeof(req) - 4), .len = cpu_to_le16(sizeof(req) - 4),
.ctrl = cmd, .ctrl = cmd,
.rdd_idx = index, .rdd_idx = rdd_idx,
.rdd_rx_sel = rx_sel,
.val = val, .val = val,
}; };

View File

@ -69,7 +69,7 @@ struct mt7996_mcu_rdd_report {
__le16 tag; __le16 tag;
__le16 len; __le16 len;
u8 band_idx; u8 rdd_idx;
u8 long_detected; u8 long_detected;
u8 constant_prf_detected; u8 constant_prf_detected;
u8 staggered_prf_detected; u8 staggered_prf_detected;

View File

@ -302,8 +302,6 @@ struct mt7996_phy {
s16 coverage_class; s16 coverage_class;
u8 slottime; u8 slottime;
u8 rdd_state;
u16 beacon_rate; u16 beacon_rate;
u32 rx_ampdu_ts; u32 rx_ampdu_ts;
@ -426,10 +424,10 @@ enum {
__MT_WFDMA_MAX, __MT_WFDMA_MAX,
}; };
enum { enum rdd_idx {
MT_RX_SEL0, MT_RDD_IDX_BAND2, /* RDD idx for band idx 2 */
MT_RX_SEL1, MT_RDD_IDX_BAND1, /* RDD idx for band idx 1 */
MT_RX_SEL2, /* monitor chain */ MT_RDD_IDX_BACKGROUND, /* RDD idx for background chain */
}; };
enum mt7996_rdd_cmd { enum mt7996_rdd_cmd {
@ -448,6 +446,21 @@ enum mt7996_rdd_cmd {
RDD_IRQ_OFF, RDD_IRQ_OFF,
}; };
static inline int
mt7996_get_rdd_idx(struct mt7996_phy *phy, bool is_background)
{
if (!phy->mt76->cap.has_5ghz)
return -1;
if (is_background)
return MT_RDD_IDX_BACKGROUND;
if (phy->mt76->band_idx == MT_BAND2)
return MT_RDD_IDX_BAND2;
return MT_RDD_IDX_BAND1;
}
static inline struct mt7996_dev * static inline struct mt7996_dev *
mt7996_hw_dev(struct ieee80211_hw *hw) mt7996_hw_dev(struct ieee80211_hw *hw)
{ {
@ -640,8 +653,7 @@ int mt7996_mcu_get_temperature(struct mt7996_phy *phy);
int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state); int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable); int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable);
int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy); int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index, int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val);
u8 rx_sel, u8 val);
int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy, int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
struct cfg80211_chan_def *chandef); struct cfg80211_chan_def *chandef);
int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx, int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,