wifi: mt76: mt7996: rework radar HWRDD idx
authorStanleyYP Wang <StanleyYP.Wang@mediatek.com>
Thu, 20 Mar 2025 01:59:26 +0000 (09:59 +0800)
committerFelix Fietkau <nbd@nbd.name>
Wed, 21 May 2025 12:49:38 +0000 (14:49 +0200)
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>
drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

index 4a28db17a2874078489e08ac8a038a51834b33a0..0ab827f52fd7d5a745f34ca512c6a44e6a2b103d 100644 (file)
@@ -222,18 +222,27 @@ static const struct file_operations mt7996_sys_recovery_ops = {
 static int
 mt7996_radar_trigger(void *data, u64 val)
 {
+#define RADAR_MAIN_CHAIN       1
+#define RADAR_BACKGROUND       2
        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;
 
-       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");
                return -EINVAL;
        }
 
-       return mt7996_mcu_rdd_cmd(dev, RDD_RADAR_EMULATE,
-                                 val, 0, 0);
+       rdd_idx = mt7996_get_rdd_idx(phy, val == RADAR_BACKGROUND);
+       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,
index ab9ab48878180058456985db74934e54341e73fa..8c35236624266d28823fdf6539d7ba71bb9d6897 100644 (file)
@@ -2441,16 +2441,15 @@ void mt7996_mac_work(struct work_struct *work)
 static void mt7996_dfs_stop_radar_detector(struct mt7996_phy *phy)
 {
        struct mt7996_dev *dev = phy->dev;
+       int rdd_idx = mt7996_get_rdd_idx(phy, false);
 
-       if (phy->rdd_state & BIT(0))
-               mt7996_mcu_rdd_cmd(dev, RDD_STOP, 0,
-                                  MT_RX_SEL0, 0);
-       if (phy->rdd_state & BIT(1))
-               mt7996_mcu_rdd_cmd(dev, RDD_STOP, 1,
-                                  MT_RX_SEL0, 0);
+       if (rdd_idx < 0)
+               return;
+
+       mt7996_mcu_rdd_cmd(dev, RDD_STOP, rdd_idx, 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;
 
@@ -2467,44 +2466,30 @@ static int mt7996_dfs_start_rdd(struct mt7996_dev *dev, int chain)
                break;
        }
 
-       err = mt7996_mcu_rdd_cmd(dev, RDD_START, chain,
-                                MT_RX_SEL0, region);
+       err = mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
        if (err < 0)
                return err;
 
-       return mt7996_mcu_rdd_cmd(dev, RDD_DET_MODE, chain,
-                                MT_RX_SEL0, 1);
+       return mt7996_mcu_rdd_cmd(dev, RDD_DET_MODE, rdd_idx, 1);
 }
 
 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;
-       u8 band_idx = phy->mt76->band_idx;
-       int err;
+       int err, rdd_idx;
 
-       /* start CAC */
-       err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_START, band_idx,
-                                MT_RX_SEL0, 0);
-       if (err < 0)
-               return err;
+       rdd_idx = mt7996_get_rdd_idx(phy, false);
+       if (rdd_idx < 0)
+               return -EINVAL;
 
-       err = mt7996_dfs_start_rdd(dev, band_idx);
+       /* start CAC */
+       err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_START, rdd_idx, 0);
        if (err < 0)
                return err;
 
-       phy->rdd_state |= BIT(band_idx);
-
-       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;
+       err = mt7996_dfs_start_rdd(dev, rdd_idx);
 
-               phy->rdd_state |= BIT(1);
-       }
-
-       return 0;
+       return err;
 }
 
 static int
@@ -2545,12 +2530,12 @@ int mt7996_dfs_init_radar_detector(struct mt7996_phy *phy)
 {
        struct mt7996_dev *dev = phy->dev;
        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;
        dfs_state = mt76_phy_dfs_state(phy->mt76);
 
-       if (prev_state == dfs_state)
+       if (prev_state == dfs_state || rdd_idx < 0)
                return 0;
 
        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)
                return 0;
 
-       err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_END,
-                                phy->mt76->band_idx, MT_RX_SEL0, 0);
+       err = mt7996_mcu_rdd_cmd(dev, RDD_CAC_END, rdd_idx, 0);
        if (err < 0) {
                phy->mt76->dfs_state = MT_DFS_STATE_UNKNOWN;
                return err;
@@ -2585,8 +2569,7 @@ int mt7996_dfs_init_radar_detector(struct mt7996_phy *phy)
        return 0;
 
 stop:
-       err = mt7996_mcu_rdd_cmd(dev, RDD_NORMAL_START,
-                                phy->mt76->band_idx, MT_RX_SEL0, 0);
+       err = mt7996_mcu_rdd_cmd(dev, RDD_NORMAL_START, rdd_idx, 0);
        if (err < 0)
                return err;
 
index a99e290faf1fc5fe5e2779afb0694bd2b56024a6..fdc517873fa62e2e7e0029a582e394697d7e1d7a 100644 (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;
 
-       if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
-               return;
-
-       if (r->band_idx == MT_RX_SEL2 && !dev->rdd2_phy)
-               return;
-
-       if (r->band_idx == MT_RX_SEL2)
+       switch (r->rdd_idx) {
+       case MT_RDD_IDX_BAND2:
+               mphy = dev->mt76.phys[MT_BAND2];
+               break;
+       case MT_RDD_IDX_BAND1:
+               mphy = dev->mt76.phys[MT_BAND1];
+               break;
+       case MT_RDD_IDX_BACKGROUND:
+               if (!dev->rdd2_phy)
+                       return;
                mphy = dev->rdd2_phy->mt76;
-       else
-               mphy = dev->mt76.phys[r->band_idx];
+               break;
+       default:
+               dev_err(dev->mt76.dev, "Unknown RDD idx %d\n", r->rdd_idx);
+               return;
+       }
 
        if (!mphy)
                return;
 
-       if (r->band_idx == MT_RX_SEL2)
+       if (r->rdd_idx == MT_RDD_IDX_BACKGROUND)
                cfg80211_background_radar_event(mphy->hw->wiphy,
                                                &dev->rdd2_chandef,
                                                GFP_ATOMIC);
@@ -3557,11 +3563,10 @@ int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
                                     struct cfg80211_chan_def *chandef)
 {
        struct mt7996_dev *dev = phy->dev;
-       int err, region;
+       int err, region, rdd_idx = mt7996_get_rdd_idx(phy, true);
 
        if (!chandef) { /* disable offchain */
-               err = mt7996_mcu_rdd_cmd(dev, RDD_STOP, MT_RX_SEL2,
-                                        0, 0);
+               err = mt7996_mcu_rdd_cmd(dev, RDD_STOP, rdd_idx, 0);
                if (err)
                        return err;
 
@@ -3587,8 +3592,7 @@ int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
                break;
        }
 
-       return mt7996_mcu_rdd_cmd(dev, RDD_START, MT_RX_SEL2,
-                                 0, region);
+       return mt7996_mcu_rdd_cmd(dev, RDD_START, rdd_idx, region);
 }
 
 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);
 }
 
-int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
-                      u8 rx_sel, u8 val)
+int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val)
 {
        struct {
                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),
                .len = cpu_to_le16(sizeof(req) - 4),
                .ctrl = cmd,
-               .rdd_idx = index,
-               .rdd_rx_sel = rx_sel,
+               .rdd_idx = rdd_idx,
                .val = val,
        };
 
index 8ef7d4baee906582c8db8645cbfdb8364b68ee22..fd660e913b8262cb90952c4643bd1ef38ec888d6 100644 (file)
@@ -69,7 +69,7 @@ struct mt7996_mcu_rdd_report {
        __le16 tag;
        __le16 len;
 
-       u8 band_idx;
+       u8 rdd_idx;
        u8 long_detected;
        u8 constant_prf_detected;
        u8 staggered_prf_detected;
index a45cd3ff61a013bb66d9c7a7f33189b6caf98c27..7c334e319547483c103ef821bfe9162166610603 100644 (file)
@@ -302,8 +302,6 @@ struct mt7996_phy {
        s16 coverage_class;
        u8 slottime;
 
-       u8 rdd_state;
-
        u16 beacon_rate;
 
        u32 rx_ampdu_ts;
@@ -426,10 +424,10 @@ enum {
        __MT_WFDMA_MAX,
 };
 
-enum {
-       MT_RX_SEL0,
-       MT_RX_SEL1,
-       MT_RX_SEL2, /* monitor chain */
+enum rdd_idx {
+       MT_RDD_IDX_BAND2,       /* RDD idx for band idx 2 */
+       MT_RDD_IDX_BAND1,       /* RDD idx for band idx 1 */
+       MT_RDD_IDX_BACKGROUND,  /* RDD idx for background chain */
 };
 
 enum mt7996_rdd_cmd {
@@ -448,6 +446,21 @@ enum mt7996_rdd_cmd {
        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 *
 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_protect(struct mt7996_phy *phy, bool enable);
 int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
-int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
-                      u8 rx_sel, u8 val);
+int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 rdd_idx, u8 val);
 int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
                                     struct cfg80211_chan_def *chandef);
 int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,