2023-04-28 20:56:33

by Ben Greear

[permalink] [raw]
Subject: [PATCH 1/6] wifi: mt76: mt7915: Support vht mu-mimo sniffer feature.

From: Ben Greear <[email protected]>

This feature allows mac80211 to update the driver with mu-mimo
group to allow the monitor port to capture MU-MIMO (VHT) frames.

The mt7915 driver implementation will only enable this feature
when there is only a monitor vdev. I was afraid that it would mess
up a sta + monitor vdev combination, for instance.

Original code from Ryder

Signed-off-by: Ben Greear <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++
.../net/wireless/mediatek/mt76/mt7915/init.c | 1 +
.../net/wireless/mediatek/mt76/mt7915/main.c | 41 +++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/regs.h | 10 +++++
4 files changed, 57 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 6b07b8fafec2..d4ae53d80d07 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -945,6 +945,11 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
return dev->rev & 0xffff;
}

+static inline int mt76_vif_count(struct mt76_dev *dev)
+{
+ return hweight_long(dev->vif_mask);
+}
+
#define mt76xx_chip(dev) mt76_chip(&((dev)->mt76))
#define mt76xx_rev(dev) mt76_rev(&((dev)->mt76))

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index ac2049f49bb3..bea75615872f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -370,6 +370,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);

if (!is_mt7915(&dev->mt76))
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 1b361199c061..7566db0cf523 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -592,6 +592,34 @@ mt7915_update_bss_color(struct ieee80211_hw *hw,
}
}

+static void
+mt7915_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info)
+{
+ struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
+ u8 i, band = phy->mt76->band_idx;
+ u32 *mu;
+
+ mu = (u32 *)info->mu_group.membership;
+ for (i = 0; i < WLAN_MEMBERSHIP_LEN / sizeof(*mu); i++) {
+ if (is_mt7916(&dev->mt76))
+ mt76_wr(dev, MT_WF_PHY_RX_GID_TAB_VLD_MT7916(band, i),
+ mu[i]);
+ else
+ mt76_wr(dev, MT_WF_PHY_RX_GID_TAB_VLD(band, i), mu[i]);
+ }
+
+ mu = (u32 *)info->mu_group.position;
+ for (i = 0; i < WLAN_USER_POSITION_LEN / sizeof(*mu); i++) {
+ if (is_mt7916(&dev->mt76))
+ mt76_wr(dev, MT_WF_PHY_RX_GID_TAB_POS_MT7916(band, i),
+ mu[i]);
+ else
+ mt76_wr(dev, MT_WF_PHY_RX_GID_TAB_POS(band, i), mu[i]);
+ }
+}
+
static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
@@ -650,6 +678,19 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
BSS_CHANGED_FILS_DISCOVERY))
mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);

+ if (changed & BSS_CHANGED_MU_GROUPS) {
+ /* Assumption is that in case of non-monitor VDEV existing, then
+ * that device should control the mu-group directly.
+ */
+ int vif_count = mt76_vif_count(&dev->mt76);
+ int max_ok = 0;
+
+ if (phy->monitor_vif)
+ max_ok = 1;
+ if (vif_count <= max_ok)
+ mt7915_update_mu_group(hw, vif, info);
+ }
+
mutex_unlock(&dev->mt76.mutex);
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index c8e478a55081..5e057cce5c9f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -1183,6 +1183,16 @@ enum offs_rev {
#define MT_WF_PHY_BASE 0x83080000
#define MT_WF_PHY(ofs) (MT_WF_PHY_BASE + (ofs))

+#define MT_WF_PHY_RX_GID_TAB_VLD(_phy, i) MT_WF_PHY(0x1054 + \
+ (i) * 4 + ((_phy) << 16))
+#define MT_WF_PHY_RX_GID_TAB_VLD_MT7916(_phy, i) MT_WF_PHY(0x1054 + \
+ (i) * 4 + ((_phy) << 20))
+
+#define MT_WF_PHY_RX_GID_TAB_POS(_phy, i) MT_WF_PHY(0x105c + \
+ (i) * 4 + ((_phy) << 16))
+#define MT_WF_PHY_RX_GID_TAB_POS_MT7916(_phy, i) MT_WF_PHY(0x105c + \
+ (i) * 4 + ((_phy) << 20))
+
#define MT_WF_PHY_RX_CTRL1(_phy) MT_WF_PHY(0x2004 + ((_phy) << 16))
#define MT_WF_PHY_RX_CTRL1_MT7916(_phy) MT_WF_PHY(0x2004 + ((_phy) << 20))
#define MT_WF_PHY_RX_CTRL1_IPI_EN GENMASK(2, 0)
--
2.40.0


2023-04-28 20:56:33

by Ben Greear

[permalink] [raw]
Subject: [PATCH 4/6] wifi: mt76: mt7915: Adjust MDP_RCFR1 in monitor mode.

From: Ben Greear <[email protected]>

Request to pass some otherwise dropped frames to host when in
monitor mode. Change initialization logic to use a better name
(but values actually set in the register during init does not change)

Signed-off-by: Ben Greear <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7915/init.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt7915/main.c | 9 +++++++++
drivers/net/wireless/mediatek/mt76/mt7915/regs.h | 6 ++++++
3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index bea75615872f..cd98a1e1e63c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -469,8 +469,8 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
MT_MDP_RCFR1_RX_DROPPED_UCAST |
MT_MDP_RCFR1_RX_DROPPED_MCAST;
set = FIELD_PREP(MT_MDP_RCFR1_MCU_RX_BYPASS, MT_MDP_TO_HIF) |
- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_TO_HIF) |
- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF);
+ FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_PFD_DROP) |
+ FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_PFD_DROP);
mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set);

mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 0x680);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index fec30cf26855..64c14fc303a2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -566,6 +566,9 @@ static void __mt7915_configure_filter(struct ieee80211_hw *hw,
u32 flags = 0;
bool is_promisc = *total_flags & FIF_CONTROL || phy->monitor_vif ||
phy->monitor_enabled;
+ u32 mdp_rcfr1_mask = MT_MDP_RCFR1_RX_DROPPED_UCAST |
+ MT_MDP_RCFR1_RX_DROPPED_MCAST;
+ u32 mdp_rcfr1_set;

#define MT76_FILTER(_flag, _hw) do { \
flags |= *total_flags & FIF_##_flag; \
@@ -610,11 +613,17 @@ static void __mt7915_configure_filter(struct ieee80211_hw *hw,
mt76_set(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
MT_WF_RMAC_TOP_TF_SNIFFER);
mt7915_check_apply_monitor_config(phy);
+
+ mdp_rcfr1_set = FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_PFD_TO_HIF) |
+ FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_PFD_TO_HIF);
} else {
mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);
mt76_clear(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
MT_WF_RMAC_TOP_TF_SNIFFER);
+ mdp_rcfr1_set = FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_PFD_DROP) |
+ FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_PFD_DROP);
}
+ mt76_rmw(dev, MT_MDP_BNRCFR1(band), mdp_rcfr1_mask, mdp_rcfr1_set);
}

static void mt7915_configure_filter(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index 252e5f1405cf..db81c9902832 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -189,6 +189,12 @@ enum offs_rev {
#define MT_MDP_RCFR1_RX_DROPPED_MCAST GENMASK(30, 29)
#define MT_MDP_TO_HIF 0
#define MT_MDP_TO_WM 1
+/* For UCDP2MH, BMCDP2MH in RCFR1 */
+#define MT_MDP_PFD_DROP 0
+#define MT_MDP_PFD_TO_MCU 1
+#define MT_MDP_PFD_TO_HIF 2
+#define MT_MDP_PFD_TO_HIF2 3
+

/* TRB: band 0(0x820e1000), band 1(0x820f1000) */
#define MT_WF_TRB_BASE(_band) ((_band) ? 0x820f1000 : 0x820e1000)
--
2.40.0

2023-04-28 20:56:33

by Ben Greear

[permalink] [raw]
Subject: [PATCH 2/6] wifi: mt76: mt7915: Move rxfilter logic into central location.

From: Ben Greear <[email protected]>

And ensure monitor mode is taken into account when calculating the
filter.

Enable RMAC_TOP_TF_SNIFFER when in promisc mode.

Signed-off-by: Ben Greear <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/main.c | 51 ++++++++++++++-----
.../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +
.../net/wireless/mediatek/mt76/mt7915/regs.h | 3 ++
3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 7566db0cf523..7ec9f45cfa15 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -8,6 +8,11 @@
#include "mt7915.h"
#include "mcu.h"

+static void __mt7915_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast);
+
static bool mt7915_dev_running(struct mt7915_dev *dev)
{
struct mt7915_phy *phy;
@@ -481,16 +486,15 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
bool enabled = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);
bool band = phy->mt76->band_idx;
+ u32 total_flags = phy->mac80211_rxfilter_flags;
+ u64 multicast = 0; /* not used by this driver currently. */

- if (!enabled)
- phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
- else
- phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
+ phy->monitor_enabled = enabled;

mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN,
enabled);
mt76_testmode_reset(phy->mt76, true);
- mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
+ __mt7915_configure_filter(hw, 0, &total_flags, multicast);
}

mutex_unlock(&dev->mt76.mutex);
@@ -512,10 +516,10 @@ mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return 0;
}

-static void mt7915_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
+static void __mt7915_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast)
{
struct mt7915_dev *dev = mt7915_hw_dev(hw);
struct mt7915_phy *phy = mt7915_hw_phy(hw);
@@ -526,6 +530,8 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR1_DROP_CFEND |
MT_WF_RFCR1_DROP_CFACK;
u32 flags = 0;
+ bool is_promisc = *total_flags & FIF_CONTROL || phy->monitor_vif ||
+ phy->monitor_enabled;

#define MT76_FILTER(_flag, _hw) do { \
flags |= *total_flags & FIF_##_flag; \
@@ -533,7 +539,7 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
phy->rxfilter |= !(flags & FIF_##_flag) * (_hw); \
} while (0)

- mutex_lock(&dev->mt76.mutex);
+ phy->mac80211_rxfilter_flags = *total_flags; /* save requested flags for later */

phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
MT_WF_RFCR_DROP_OTHER_BEACON |
@@ -547,6 +553,8 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR_DROP_UNWANTED_CTL |
MT_WF_RFCR_DROP_STBC_MULTI);

+ phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
+
MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |
MT_WF_RFCR_DROP_A3_MAC |
MT_WF_RFCR_DROP_A3_BSSID);
@@ -557,14 +565,33 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR_DROP_RTS |
MT_WF_RFCR_DROP_CTL_RSV |
MT_WF_RFCR_DROP_NDPA);
+ if (is_promisc)
+ phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;

*total_flags = flags;
mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);

- if (*total_flags & FIF_CONTROL)
+ if (is_promisc) {
mt76_clear(dev, MT_WF_RFCR1(band), ctl_flags);
- else
+ mt76_set(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
+ MT_WF_RMAC_TOP_TF_SNIFFER);
+ } else {
mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);
+ mt76_clear(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
+ MT_WF_RMAC_TOP_TF_SNIFFER);
+ }
+}
+
+static void mt7915_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ u64 multicast)
+{
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
+
+ mutex_lock(&dev->mt76.mutex);
+
+ __mt7915_configure_filter(hw, changed_flags, total_flags, multicast);

mutex_unlock(&dev->mt76.mutex);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index b3ead3530740..06f98e5cd95e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -244,6 +244,8 @@ struct mt7915_phy {
struct ieee80211_vif *monitor_vif;

struct thermal_cooling_device *cdev;
+ u32 mac80211_rxfilter_flags;
+ u8 monitor_enabled;
u8 cdev_state;
u8 throttle_state;
u32 throttle_temp[2]; /* 0: critical high, 1: maximum */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index 5e057cce5c9f..0118fdaa96b3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -566,6 +566,9 @@ enum offs_rev {
#define MT_WF_RMAC_MIB_AIRTIME4(_band) MT_WF_RMAC(_band, 0x0390)
#define MT_WF_RMAC_MIB_QOS23_BACKOFF GENMASK(31, 0)

+#define MT_WF_RMAC_TOP_TF_PARSER(_band) MT_WF_RMAC(_band, 0x0604)
+#define MT_WF_RMAC_TOP_TF_SNIFFER (BIT(10) | BIT(12))
+
/* WFDMA0 */
#define MT_WFDMA0_BASE __REG(WFDMA0_ADDR)
#define MT_WFDMA0(ofs) (MT_WFDMA0_BASE + (ofs))
--
2.40.0

2023-04-28 20:56:33

by Ben Greear

[permalink] [raw]
Subject: [PATCH 3/6] wifi: mt76: mt7915: Support setting aid when in monitor mode.

From: Ben Greear <[email protected]>

The parser expects values in hex.
Syntax: aid color uldl enables

The enables value is a set of flags to enable any/all of the
aid, color, and/or uldl (in that order).
options. For uldl, 0x1 means upload.
Example, capture aid 11:
echo "b 0 0 1" > /debug/ieee80211/phy0/mt76/he_sniffer_params

Note that you must also enable the group-5 fields in the rx-status
header for he-trig (and he-mu) to show up properly in a packet
capture.

Signed-off-by: Ben Greear <[email protected]>
---
.../wireless/mediatek/mt76/mt7915/debugfs.c | 60 +++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/main.c | 35 +++++++++++
.../wireless/mediatek/mt76/mt7915/mt7915.h | 8 +++
.../net/wireless/mediatek/mt76/mt7915/regs.h | 9 +++
4 files changed, 112 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 879884ead660..f836754103dc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -247,6 +247,64 @@ mt7915_muru_debug_get(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_debug, mt7915_muru_debug_get,
mt7915_muru_debug_set, "%lld\n");

+static ssize_t
+mt7915_he_monitor_set(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct mt7915_phy *phy = file->private_data;
+ char buf[64] = {0};
+ u32 aid, bss_color, uldl, enables;
+ int ret;
+ struct mt7915_dev *dev = phy->dev;
+
+ if (count >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(buf, user_buf, count))
+ return -EFAULT;
+
+ ret = sscanf(buf, "%x %x %x %x",
+ &aid, &bss_color, &uldl, &enables);
+ if (ret != 4)
+ return -EINVAL;
+
+ phy->monitor_cur_aid = aid;
+ phy->monitor_cur_color = bss_color;
+ phy->monitor_cur_uldl = uldl;
+ phy->monitor_cur_enables = enables;
+
+ mutex_lock(&dev->mt76.mutex);
+ mt7915_check_apply_monitor_config(phy);
+ mutex_unlock(&dev->mt76.mutex);
+
+ return count;
+}
+
+static ssize_t
+mt7915_he_monitor_get(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct mt7915_phy *phy = file->private_data;
+ u8 buf[32];
+ int len;
+
+ len = scnprintf(buf, sizeof(buf),
+ "aid: 0x%x bss-color: 0x%x uldl: 0x%x enables: 0x%x\n"
+ " ULDL: 0 is download, 1 is upload\n"
+ " Enable-bits: 1: AID 2: Color 4: ULDL\n",
+ phy->monitor_cur_aid, phy->monitor_cur_color,
+ phy->monitor_cur_uldl, phy->monitor_cur_enables);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations mt7915_he_sniffer_ops = {
+ .write = mt7915_he_monitor_set,
+ .read = mt7915_he_monitor_get,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+
static int mt7915_muru_stats_show(struct seq_file *file, void *data)
{
struct mt7915_phy *phy = file->private;
@@ -1230,6 +1288,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
debugfs_create_file("tx_stats", 0400, dir, phy, &mt7915_tx_stats_fops);
debugfs_create_file("sys_recovery", 0600, dir, phy,
&mt7915_sys_recovery_ops);
+ debugfs_create_file("he_sniffer_params", 0600, dir, phy,
+ &mt7915_he_sniffer_ops);
debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm);
debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa);
debugfs_create_file("fw_debug_bin", 0600, dir, dev, &fops_fw_debug_bin);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 7ec9f45cfa15..fec30cf26855 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -516,6 +516,40 @@ mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return 0;
}

+void mt7915_check_apply_monitor_config(struct mt7915_phy *phy)
+{
+ /* I first thought that this would not work well when combined
+ * with STA mode, but now I think it will not matter since it appears
+ * the HEMU rule 1 is only used after normal HE MU operations
+ * have happened. --Ben
+ */
+ struct mt7915_dev *dev = phy->dev;
+ u32 reg = mt76_rr(dev, MT_WF_HEMU_RULE1);
+
+ reg &= ~(MT_WF_HEMU_RULE1_AID |
+ MT_WF_HEMU_RULE1_COLOR |
+ MT_WF_HEMU_RULE1_ULDL |
+ MT_WF_HEMU_RULE1_AID_ENABLE |
+ MT_WF_HEMU_RULE1_BSS_COLOR_ENABLE |
+ MT_WF_HEMU_RULE1_ULDL_ENABLE |
+ MT_WF_HEMU_RULE1_PRIORITY);
+ reg |= phy->monitor_cur_aid;
+ reg |= (phy->monitor_cur_color << 10) & 0x3f;
+ if (phy->monitor_cur_uldl)
+ reg |= MT_WF_HEMU_RULE1_ULDL;
+ if (phy->monitor_cur_enables) {
+ if (phy->monitor_cur_enables & 0x1)
+ reg |= MT_WF_HEMU_RULE1_AID_ENABLE;
+ if (phy->monitor_cur_enables & 0x2)
+ reg |= MT_WF_HEMU_RULE1_BSS_COLOR_ENABLE;
+ if (phy->monitor_cur_enables & 0x4)
+ reg |= MT_WF_HEMU_RULE1_ULDL_ENABLE;
+ reg |= MT_WF_HEMU_RULE1_PRIORITY; /* set priority to 7 */
+ }
+
+ mt76_wr(dev, MT_WF_HEMU_RULE1, reg);
+}
+
static void __mt7915_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
@@ -575,6 +609,7 @@ static void __mt7915_configure_filter(struct ieee80211_hw *hw,
mt76_clear(dev, MT_WF_RFCR1(band), ctl_flags);
mt76_set(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
MT_WF_RMAC_TOP_TF_SNIFFER);
+ mt7915_check_apply_monitor_config(phy);
} else {
mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);
mt76_clear(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 06f98e5cd95e..084001647aaa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -242,6 +242,13 @@ struct mt7915_phy {
struct ieee80211_sband_iftype_data iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];

struct ieee80211_vif *monitor_vif;
+ u16 monitor_cur_aid; /* aid to be used in monitor mode to capture HE trigger frames */
+ /* bss-color to be used in monitor mode to capture HE trigger frames */
+ u8 monitor_cur_color;
+ /* upload/download to be used in monitor mode to capture HE trigger frames */
+ u8 monitor_cur_uldl;
+ /* Specifies which of the above are used: 0x1 is AID, 0x2 is color, 0x3 is uldl */
+ u8 monitor_cur_enables;

struct thermal_cooling_device *cdev;
u32 mac80211_rxfilter_flags;
@@ -628,6 +635,7 @@ int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enable);
int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms);
int mt7915_mcu_wed_enable_rx_stats(struct mt7915_dev *dev);
int mt7915_init_debugfs(struct mt7915_phy *phy);
+void mt7915_check_apply_monitor_config(struct mt7915_phy *phy);
void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int len);
bool mt7915_debugfs_rx_log(struct mt7915_dev *dev, const void *data, int len);
#ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index 0118fdaa96b3..252e5f1405cf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -1217,4 +1217,13 @@ enum offs_rev {
#define MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR MT_MCU_WM_CIRQ(0x108)
#define MT_MCU_WM_CIRQ_EINT_SOFT_ADDR MT_MCU_WM_CIRQ(0x118)

+#define MT_WF_HEMU_RULE1 (MT_WF_PHY_BASE + 0x10e0)
+#define MT_WF_HEMU_RULE1_AID GENMASK(10, 0)
+#define MT_WF_HEMU_RULE1_COLOR GENMASK(21, 16)
+#define MT_WF_HEMU_RULE1_ULDL (BIT(22)) /* 0 dl, 1 ul */
+#define MT_WF_HEMU_RULE1_AID_ENABLE (BIT(24))
+#define MT_WF_HEMU_RULE1_BSS_COLOR_ENABLE (BIT(25))
+#define MT_WF_HEMU_RULE1_ULDL_ENABLE (BIT(26))
+#define MT_WF_HEMU_RULE1_PRIORITY GENMASK(30, 28) /* 0 disable, 7 is highest */
+
#endif
--
2.40.0

2023-04-28 20:56:33

by Ben Greear

[permalink] [raw]
Subject: [PATCH 5/6] wifi: mt76: mt7915: Improve monitor-mode flags settings.

From: Ben Greear <[email protected]>

This enables capturing more frames, and now when the rx5 group
option is also enabled for rx-status, wireshark shows HE-TRIG
as well as HE-MU frames.

Signed-off-by: Ben Greear <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/main.c | 26 +++++++++++++++++--
.../net/wireless/mediatek/mt76/mt7915/regs.h | 16 ++++++++++++
2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 64c14fc303a2..55aed3c6d3be 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -562,6 +562,12 @@ static void __mt7915_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR1_DROP_BF_POLL |
MT_WF_RFCR1_DROP_BA |
MT_WF_RFCR1_DROP_CFEND |
+ MT_WF_RFCR1_DROP_PS_BFRPOL |
+ MT_WF_RFCR1_DROP_PS_NDPA |
+ MT_WF_RFCR1_DROP_NO2ME_TF |
+ MT_WF_RFCR1_DROP_NON_MUBAR_TF |
+ MT_WF_RFCR1_DROP_RXS_BRP |
+ MT_WF_RFCR1_DROP_TF_BFRP |
MT_WF_RFCR1_DROP_CFACK;
u32 flags = 0;
bool is_promisc = *total_flags & FIF_CONTROL || phy->monitor_vif ||
@@ -587,7 +593,9 @@ static void __mt7915_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR_DROP_BCAST |
MT_WF_RFCR_DROP_DUPLICATE |
MT_WF_RFCR_DROP_A2_BSSID |
- MT_WF_RFCR_DROP_UNWANTED_CTL |
+ MT_WF_RFCR_DROP_UNWANTED_CTL | /* 0 means drop */
+ MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT |
+ MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL |
MT_WF_RFCR_DROP_STBC_MULTI);

phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
@@ -602,8 +610,22 @@ static void __mt7915_configure_filter(struct ieee80211_hw *hw,
MT_WF_RFCR_DROP_RTS |
MT_WF_RFCR_DROP_CTL_RSV |
MT_WF_RFCR_DROP_NDPA);
- if (is_promisc)
+ if (is_promisc) {
phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
+ phy->rxfilter |= MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT;
+ if (flags & FIF_CONTROL) {
+ phy->rxfilter |= MT_WF_RFCR_DROP_UNWANTED_CTL; /* 1 means receive */
+ phy->rxfilter |= MT_WF_RFCR_SECOND_BCN_EN;
+ phy->rxfilter |= MT_WF_RFCR_RX_MGMT_FRAME_CTRL;
+ phy->rxfilter |= MT_WF_RFCR_RX_SAMEBSSIDPRORESP_CTRL;
+ phy->rxfilter |= MT_WF_RFCR_RX_DIFFBSSIDPRORESP_CTRL;
+ phy->rxfilter |= MT_WF_RFCR_RX_SAMEBSSIDBCN_CTRL;
+ phy->rxfilter |= MT_WF_RFCR_RX_SAMEBSSIDNULL_CTRL;
+ phy->rxfilter |= MT_WF_RFCR_RX_DIFFBSSIDNULL_CTRL;
+ phy->rxfilter &= ~(MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL);
+ }
+ phy->rxfilter |= MT_WF_RFCR_RX_DATA_FRAME_CTRL;
+ }

*total_flags = flags;
mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index db81c9902832..db52334204ed 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -547,6 +547,16 @@ enum offs_rev {
#define MT_WF_RFCR_DROP_OTHER_TIM BIT(19)
#define MT_WF_RFCR_DROP_NDPA BIT(20)
#define MT_WF_RFCR_DROP_UNWANTED_CTL BIT(21)
+#define MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT BIT(22)
+#define MT_WF_RFCR_SECOND_BCN_EN BIT(23)
+#define MT_WF_RFCR_RX_MGMT_FRAME_CTRL BIT(24)
+#define MT_WF_RFCR_RX_DATA_FRAME_CTRL BIT(25)
+#define MT_WF_RFCR_RX_SAMEBSSIDPRORESP_CTRL BIT(26)
+#define MT_WF_RFCR_RX_DIFFBSSIDPRORESP_CTRL BIT(27)
+#define MT_WF_RFCR_RX_SAMEBSSIDBCN_CTRL BIT(28)
+#define MT_WF_RFCR_RX_SAMEBSSIDNULL_CTRL BIT(29)
+#define MT_WF_RFCR_RX_DIFFBSSIDNULL_CTRL BIT(30)
+#define MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL BIT(31)

#define MT_WF_RFCR1(_band) MT_WF_RMAC(_band, 0x004)
#define MT_WF_RFCR1_DROP_ACK BIT(4)
@@ -554,6 +564,12 @@ enum offs_rev {
#define MT_WF_RFCR1_DROP_BA BIT(6)
#define MT_WF_RFCR1_DROP_CFEND BIT(7)
#define MT_WF_RFCR1_DROP_CFACK BIT(8)
+#define MT_WF_RFCR1_DROP_PS_BFRPOL BIT(11)
+#define MT_WF_RFCR1_DROP_PS_NDPA BIT(12)
+#define MT_WF_RFCR1_DROP_NO2ME_TF BIT(22)
+#define MT_WF_RFCR1_DROP_NON_MUBAR_TF BIT(23)
+#define MT_WF_RFCR1_DROP_RXS_BRP BIT(25)
+#define MT_WF_RFCR1_DROP_TF_BFRP BIT(30)

#define MT_WF_RMAC_RSVD0(_band) MT_WF_RMAC(_band, 0x02e0)
#define MT_WF_RMAC_RSVD0_EIFS_CLR BIT(21)
--
2.40.0

2023-04-28 20:56:53

by Ben Greear

[permalink] [raw]
Subject: [PATCH 6/6] wifi: mt76: mt7915: support enabling rx group-5 status

From: Ben Greear <[email protected]>

When enabled, this allows per-skb rx rate reporting.
Enabling this may degrade RX performance, so it remains
disabled by default.

Signed-off-by: Ben Greear <[email protected]>
---
.../wireless/mediatek/mt76/mt7915/debugfs.c | 33 +++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/init.c | 3 +-
.../net/wireless/mediatek/mt76/mt7915/main.c | 2 +-
.../wireless/mediatek/mt76/mt7915/mt7915.h | 5 +++
4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index f836754103dc..cb01f7f72d85 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -743,6 +743,38 @@ mt7915_fw_util_wa_show(struct seq_file *file, void *data)

DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa);

+static int
+mt7915_rx_group_5_enable_set(void *data, u64 val)
+{
+ struct mt7915_dev *dev = data;
+
+ mutex_lock(&dev->mt76.mutex);
+
+ dev->rx_group_5_enable = !!val;
+
+ /* Enabled if we requested enabled OR if monitor mode is enabled. */
+ mt76_rmw_field(dev, MT_DMA_DCR0(0), MT_DMA_DCR0_RXD_G5_EN,
+ dev->rx_group_5_enable);
+ mt76_testmode_reset(dev->phy.mt76, true);
+
+ mutex_unlock(&dev->mt76.mutex);
+
+ return 0;
+}
+
+static int
+mt7915_rx_group_5_enable_get(void *data, u64 *val)
+{
+ struct mt7915_dev *dev = data;
+
+ *val = dev->rx_group_5_enable;
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_rx_group_5_enable, mt7915_rx_group_5_enable_get,
+ mt7915_rx_group_5_enable_set, "%lld\n");
+
static void
mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
struct seq_file *file)
@@ -1297,6 +1329,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
&mt7915_fw_util_wm_fops);
debugfs_create_file("fw_util_wa", 0400, dir, dev,
&mt7915_fw_util_wa_fops);
+ debugfs_create_file("rx_group_5_enable", 0600, dir, dev, &fops_rx_group_5_enable);
debugfs_create_file("implicit_txbf", 0600, dir, dev,
&fops_implicit_txbf);
debugfs_create_file("txpower_sku", 0400, dir, phy,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index cd98a1e1e63c..75571566430e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -476,7 +476,8 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 0x680);

/* mt7915: disable rx rate report by default due to hw issues */
- mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN);
+ mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN,
+ dev->rx_group_5_enable);

/* clear estimated value of EIFS for Rx duration & OBSS time */
mt76_wr(dev, MT_WF_RMAC_RSVD0(band), MT_WF_RMAC_RSVD0_EIFS_CLR);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 55aed3c6d3be..dd73b12cea61 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -492,7 +492,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
phy->monitor_enabled = enabled;

mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN,
- enabled);
+ dev->rx_group_5_enable);
mt76_testmode_reset(phy->mt76, true);
__mt7915_configure_filter(hw, 0, &total_flags, multicast);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 084001647aaa..03459c6d94cd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -313,6 +313,11 @@ struct mt7915_dev {
u16 chainshift;
u32 hif_idx;

+ /* Should we enable group-5 rx descriptor logic? This may decrease RX
+ * throughput, but will give per skb rx rate information..
+ */
+ bool rx_group_5_enable;
+
struct work_struct init_work;
struct work_struct rc_work;
struct work_struct dump_work;
--
2.40.0

2023-04-28 21:19:13

by Ryder Lee

[permalink] [raw]
Subject: Re: [PATCH 1/6] wifi: mt76: mt7915: Support vht mu-mimo sniffer feature.

On Fri, 2023-04-28 at 13:49 -0700, [email protected] wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> From: Ben Greear <[email protected]>
>
> This feature allows mac80211 to update the driver with mu-mimo
> group to allow the monitor port to capture MU-MIMO (VHT) frames.
>
> The mt7915 driver implementation will only enable this feature
> when there is only a monitor vdev. I was afraid that it would mess
> up a sta + monitor vdev combination, for instance.
>
> Original code from Ryder
>
> Signed-off-by: Ben Greear <[email protected]>
> ---
> drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++
> .../net/wireless/mediatek/mt76/mt7915/init.c | 1 +
> .../net/wireless/mediatek/mt76/mt7915/main.c | 41
> +++++++++++++++++++
> .../net/wireless/mediatek/mt76/mt7915/regs.h | 10 +++++
> 4 files changed, 57 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h
> b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 6b07b8fafec2..d4ae53d80d07 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -945,6 +945,11 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
> return dev->rev & 0xffff;
> }
>
> +static inline int mt76_vif_count(struct mt76_dev *dev)
> +{
> + return hweight_long(dev->vif_mask);
> +}
> +
> #define mt76xx_chip(dev) mt76_chip(&((dev)->mt76))
> #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76))
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> index ac2049f49bb3..bea75615872f 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
> @@ -370,6 +370,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy)
> wiphy_ext_feature_set(wiphy,
> NL80211_EXT_FEATURE_FILS_DISCOVERY);
> wiphy_ext_feature_set(wiphy,
> NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
> wiphy_ext_feature_set(wiphy,
> NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
> + wiphy_ext_feature_set(wiphy,
> NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
>
> if (!is_mt7915(&dev->mt76))
> wiphy_ext_feature_set(wiphy,
> NL80211_EXT_FEATURE_STA_TX_PWR);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> index 1b361199c061..7566db0cf523 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> @@ -592,6 +592,34 @@ mt7915_update_bss_color(struct ieee80211_hw *hw,
> }
> }
>
> +static void
> +mt7915_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif
> *vif,
> + struct ieee80211_bss_conf *info)
> +{
> + struct mt7915_phy *phy = mt7915_hw_phy(hw);
> + struct mt7915_dev *dev = mt7915_hw_dev(hw);
> + u8 i, band = phy->mt76->band_idx;
> + u32 *mu;
> +
> + mu = (u32 *)info->mu_group.membership;
> + for (i = 0; i < WLAN_MEMBERSHIP_LEN / sizeof(*mu); i++) {
> + if (is_mt7916(&dev->mt76))
> + mt76_wr(dev,
> MT_WF_PHY_RX_GID_TAB_VLD_MT7916(band, i),
> + mu[i]);
> + else
> + mt76_wr(dev, MT_WF_PHY_RX_GID_TAB_VLD(band,
> i), mu[i]);
> + }
> +
> + mu = (u32 *)info->mu_group.position;
> + for (i = 0; i < WLAN_USER_POSITION_LEN / sizeof(*mu); i++) {
> + if (is_mt7916(&dev->mt76))
> + mt76_wr(dev,
> MT_WF_PHY_RX_GID_TAB_POS_MT7916(band, i),
> + mu[i]);
> + else
> + mt76_wr(dev, MT_WF_PHY_RX_GID_TAB_POS(band,
> i), mu[i]);
> + }
> +}
> +
> static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
> struct ieee80211_vif *vif,
> struct ieee80211_bss_conf *info,
> @@ -650,6 +678,19 @@ static void mt7915_bss_info_changed(struct
> ieee80211_hw *hw,
> BSS_CHANGED_FILS_DISCOVERY))
> mt7915_mcu_add_beacon(hw, vif, info->enable_beacon,
> changed);
>
> + if (changed & BSS_CHANGED_MU_GROUPS) {
> + /* Assumption is that in case of non-monitor VDEV
> existing, then
> + * that device should control the mu-group directly.
> + */
> + int vif_count = mt76_vif_count(&dev->mt76);
> + int max_ok = 0;

I don't think we need checks here as user can fully handle this with
toggling iw command - iw dev mon0 set monitor mumimo-groupid <Group ID>

Also, the Group ID mgmt frame is transmitted by the AP to assign or
change the user position of a STA, which will notify underlying driver
of changes.

> + if (phy->monitor_vif)
> + max_ok = 1;
> + if (vif_count <= max_ok)
> + mt7915_update_mu_group(hw, vif, info);
> + }
> +
> mutex_unlock(&dev->mt76.mutex);
> }
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
> b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
> index c8e478a55081..5e057cce5c9f 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
> @@ -1183,6 +1183,16 @@ enum offs_rev {
> #define MT_WF_PHY_BASE 0x83080000
> #define MT_WF_PHY(ofs) (MT_WF_PHY_BASE + (ofs))
>
> +#define MT_WF_PHY_RX_GID_TAB_VLD(_phy,
> i) MT_WF_PHY(0x1054 + \
> + (i)
> * 4 + ((_phy) << 16))
> +#define MT_WF_PHY_RX_GID_TAB_VLD_MT7916(_phy,
> i) MT_WF_PHY(0x1054 + \
> + (i)
> * 4 + ((_phy) << 20))
> +
> +#define MT_WF_PHY_RX_GID_TAB_POS(_phy,
> i) MT_WF_PHY(0x105c + \
> + (i)
> * 4 + ((_phy) << 16))
> +#define MT_WF_PHY_RX_GID_TAB_POS_MT7916(_phy,
> i) MT_WF_PHY(0x105c + \
> + (i)
> * 4 + ((_phy) << 20))
> +
> #define MT_WF_PHY_RX_CTRL1(_phy) MT_WF_PHY(0x2004 + ((_phy) <<
> 16))
> #define MT_WF_PHY_RX_CTRL1_MT7916(_phy) MT_WF_PHY(0x2004 +
> ((_phy) << 20))
> #define MT_WF_PHY_RX_CTRL1_IPI_EN GENMASK(2, 0)
> --
> 2.40.0
>

2023-04-28 21:43:52

by Ryder Lee

[permalink] [raw]
Subject: Re: [PATCH 2/6] wifi: mt76: mt7915: Move rxfilter logic into central location.

On Fri, 2023-04-28 at 13:49 -0700, [email protected] wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> From: Ben Greear <[email protected]>
>
> And ensure monitor mode is taken into account when calculating the
> filter.
>
> Enable RMAC_TOP_TF_SNIFFER when in promisc mode.
>
> Signed-off-by: Ben Greear <[email protected]>
> ---
> .../net/wireless/mediatek/mt76/mt7915/main.c | 51 ++++++++++++++---
> --
> .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +
> .../net/wireless/mediatek/mt76/mt7915/regs.h | 3 ++
> 3 files changed, 44 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> index 7566db0cf523..7ec9f45cfa15 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> @@ -8,6 +8,11 @@
> #include "mt7915.h"
> #include "mcu.h"
>
> +static void __mt7915_configure_filter(struct ieee80211_hw *hw,
> + unsigned int changed_flags,
> + unsigned int *total_flags,
> + u64 multicast);
> +
> static bool mt7915_dev_running(struct mt7915_dev *dev)
> {
> struct mt7915_phy *phy;
> @@ -481,16 +486,15 @@ static int mt7915_config(struct ieee80211_hw
> *hw, u32 changed)
> if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
> bool enabled = !!(hw->conf.flags &
> IEEE80211_CONF_MONITOR);
> bool band = phy->mt76->band_idx;
> + u32 total_flags = phy->mac80211_rxfilter_flags;
> + u64 multicast = 0; /* not used by this driver
> currently. */
>
> - if (!enabled)
> - phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
> - else
> - phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
> + phy->monitor_enabled = enabled;
>
> mt76_rmw_field(dev, MT_DMA_DCR0(band),
> MT_DMA_DCR0_RXD_G5_EN,
> enabled);
> mt76_testmode_reset(phy->mt76, true);
> - mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
> + __mt7915_configure_filter(hw, 0, &total_flags,
> multicast);
> }
>
> mutex_unlock(&dev->mt76.mutex);
> @@ -512,10 +516,10 @@ mt7915_conf_tx(struct ieee80211_hw *hw, struct
> ieee80211_vif *vif,
> return 0;
> }
>
> -static void mt7915_configure_filter(struct ieee80211_hw *hw,
> - unsigned int changed_flags,
> - unsigned int *total_flags,
> - u64 multicast)
> +static void __mt7915_configure_filter(struct ieee80211_hw *hw,
> + unsigned int changed_flags,
> + unsigned int *total_flags,
> + u64 multicast)
> {
> struct mt7915_dev *dev = mt7915_hw_dev(hw);
> struct mt7915_phy *phy = mt7915_hw_phy(hw);
> @@ -526,6 +530,8 @@ static void mt7915_configure_filter(struct
> ieee80211_hw *hw,
> MT_WF_RFCR1_DROP_CFEND |
> MT_WF_RFCR1_DROP_CFACK;
> u32 flags = 0;
> + bool is_promisc = *total_flags & FIF_CONTROL || phy-
> >monitor_vif ||
> + phy->monitor_enabled;
>
> #define MT76_FILTER(_flag, _hw) do
> { \
> flags |= *total_flags &
> FIF_##_flag; \
> @@ -533,7 +539,7 @@ static void mt7915_configure_filter(struct
> ieee80211_hw *hw,
> phy->rxfilter |= !(flags & FIF_##_flag) *
> (_hw); \
> } while (0)
>
> - mutex_lock(&dev->mt76.mutex);
> + phy->mac80211_rxfilter_flags = *total_flags; /* save
> requested flags for later */
>
> phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
> MT_WF_RFCR_DROP_OTHER_BEACON |
> @@ -547,6 +553,8 @@ static void mt7915_configure_filter(struct
> ieee80211_hw *hw,
> MT_WF_RFCR_DROP_UNWANTED_CTL |
> MT_WF_RFCR_DROP_STBC_MULTI);
>
> + phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
> +
> MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |
> MT_WF_RFCR_DROP_A3_MAC |
> MT_WF_RFCR_DROP_A3_BSSID);
> @@ -557,14 +565,33 @@ static void mt7915_configure_filter(struct
> ieee80211_hw *hw,
> MT_WF_RFCR_DROP_RTS |
> MT_WF_RFCR_DROP_CTL_RSV |
> MT_WF_RFCR_DROP_NDPA);
> + if (is_promisc)
> + phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
>
> *total_flags = flags;
> mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
>
> - if (*total_flags & FIF_CONTROL)
> + if (is_promisc) {
> mt76_clear(dev, MT_WF_RFCR1(band), ctl_flags);
> - else
> + mt76_set(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
> + MT_WF_RMAC_TOP_TF_SNIFFER);
> + } else {
> mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);
> + mt76_clear(dev, MT_WF_RMAC_TOP_TF_PARSER(band),
> + MT_WF_RMAC_TOP_TF_SNIFFER);
> + }
> +}
> +
> +static void mt7915_configure_filter(struct ieee80211_hw *hw,
> + unsigned int changed_flags,
> + unsigned int *total_flags,
> + u64 multicast)
> +{
> + struct mt7915_dev *dev = mt7915_hw_dev(hw);
> +
> + mutex_lock(&dev->mt76.mutex);
> +
> + __mt7915_configure_filter(hw, changed_flags, total_flags,
> multicast);
>
> mutex_unlock(&dev->mt76.mutex);
> }
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> index b3ead3530740..06f98e5cd95e 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> @@ -244,6 +244,8 @@ struct mt7915_phy {
> struct ieee80211_vif *monitor_vif;
>
> struct thermal_cooling_device *cdev;
> + u32 mac80211_rxfilter_flags;
> + u8 monitor_enabled;
> u8 cdev_state;
> u8 throttle_state;
> u32 throttle_temp[2]; /* 0: critical high, 1: maximum */
>
I prefer something like this so that we don't need a monitor_enabled?
if (changed & IEEE80211_CONF_CHANGE_MONITOR)
mt7915_set_monitor(phy, !!(hw->conf.flags &&
IEEE80211_CONF_MONITOR));

Ryder

2023-04-28 21:53:11

by Ryder Lee

[permalink] [raw]
Subject: Re: [PATCH 5/6] wifi: mt76: mt7915: Improve monitor-mode flags settings.

On Fri, 2023-04-28 at 13:49 -0700, [email protected] wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> From: Ben Greear <[email protected]>
>
> This enables capturing more frames, and now when the rx5 group
> option is also enabled for rx-status, wireshark shows HE-TRIG
> as well as HE-MU frames.
>
> Signed-off-by: Ben Greear <[email protected]>
> ---
> .../net/wireless/mediatek/mt76/mt7915/main.c | 26
> +++++++++++++++++--
> .../net/wireless/mediatek/mt76/mt7915/regs.h | 16 ++++++++++++
> 2 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> index 64c14fc303a2..55aed3c6d3be 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> @@ -562,6 +562,12 @@ static void __mt7915_configure_filter(struct
> ieee80211_hw *hw,
> MT_WF_RFCR1_DROP_BF_POLL |
> MT_WF_RFCR1_DROP_BA |
> MT_WF_RFCR1_DROP_CFEND |
> + MT_WF_RFCR1_DROP_PS_BFRPOL |
> + MT_WF_RFCR1_DROP_PS_NDPA |
> + MT_WF_RFCR1_DROP_NO2ME_TF |
> + MT_WF_RFCR1_DROP_NON_MUBAR_TF |
> + MT_WF_RFCR1_DROP_RXS_BRP |
> + MT_WF_RFCR1_DROP_TF_BFRP |
> MT_WF_RFCR1_DROP_CFACK;
> u32 flags = 0;
> bool is_promisc = *total_flags & FIF_CONTROL || phy-
> >monitor_vif ||
> @@ -587,7 +593,9 @@ static void __mt7915_configure_filter(struct
> ieee80211_hw *hw,
> MT_WF_RFCR_DROP_BCAST |
> MT_WF_RFCR_DROP_DUPLICATE |
> MT_WF_RFCR_DROP_A2_BSSID |
> - MT_WF_RFCR_DROP_UNWANTED_CTL |
> + MT_WF_RFCR_DROP_UNWANTED_CTL | /* 0 means
> drop */
> + MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT |
> + MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL |
> MT_WF_RFCR_DROP_STBC_MULTI);
>
> phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
> @@ -602,8 +610,22 @@ static void __mt7915_configure_filter(struct
> ieee80211_hw *hw,
> MT_WF_RFCR_DROP_RTS |
> MT_WF_RFCR_DROP_CTL_RSV |
> MT_WF_RFCR_DROP_NDPA);
> - if (is_promisc)
> + if (is_promisc) {
> phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
> + phy->rxfilter |=
> MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT;
> + if (flags & FIF_CONTROL) {
> + phy->rxfilter |=
> MT_WF_RFCR_DROP_UNWANTED_CTL; /* 1 means receive */
> + phy->rxfilter |= MT_WF_RFCR_SECOND_BCN_EN;
> + phy->rxfilter |=
> MT_WF_RFCR_RX_MGMT_FRAME_CTRL;
> + phy->rxfilter |=
> MT_WF_RFCR_RX_SAMEBSSIDPRORESP_CTRL;
> + phy->rxfilter |=
> MT_WF_RFCR_RX_DIFFBSSIDPRORESP_CTRL;
> + phy->rxfilter |=
> MT_WF_RFCR_RX_SAMEBSSIDBCN_CTRL;
> + phy->rxfilter |=
> MT_WF_RFCR_RX_SAMEBSSIDNULL_CTRL;
> + phy->rxfilter |=
> MT_WF_RFCR_RX_DIFFBSSIDNULL_CTRL;
> + phy->rxfilter &=
> ~(MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL);

FIF_CONTROL: pass control frame. However, many of these are not control
frames. I think we should move monitor dedicated misc parts to
IEEE80211_CONF_CHANGE_MONITOR mt7915_set_monitor and leave this
function as-is ... as my reply in [2/6].
> + }
> + phy->rxfilter |= MT_WF_RFCR_RX_DATA_FRAME_CTRL;

2023-04-28 22:05:14

by Ryder Lee

[permalink] [raw]
Subject: Re: [PATCH 3/6] wifi: mt76: mt7915: Support setting aid when in monitor mode.

On Fri, 2023-04-28 at 13:49 -0700, [email protected] wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> From: Ben Greear <[email protected]>
>
> The parser expects values in hex.
> Syntax: aid color uldl enables
>
> The enables value is a set of flags to enable any/all of the
> aid, color, and/or uldl (in that order).
> options. For uldl, 0x1 means upload.
> Example, capture aid 11:
> echo "b 0 0 1" > /debug/ieee80211/phy0/mt76/he_sniffer_params
>
> Note that you must also enable the group-5 fields in the rx-status
> header for he-trig (and he-mu) to show up properly in a packet
> capture.
>
> Signed-off-by: Ben Greear <[email protected]>
> ---
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> index 06f98e5cd95e..084001647aaa 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
> @@ -242,6 +242,13 @@ struct mt7915_phy {
> struct ieee80211_sband_iftype_data
> iftype[NUM_NL80211_BANDS][NUM_NL80211_IFTYPES];
>
> struct ieee80211_vif *monitor_vif;
> + u16 monitor_cur_aid; /* aid to be used in monitor mode to
> capture HE trigger frames */
> + /* bss-color to be used in monitor mode to capture HE trigger
> frames */
> + u8 monitor_cur_color;
> + /* upload/download to be used in monitor mode to capture HE
> trigger frames */
> + u8 monitor_cur_uldl;
> + /* Specifies which of the above are used: 0x1 is AID, 0x2 is
> color, 0x3 is uldl */
> + u8 monitor_cur_enables;
>
>

Just my personal taste to gather similar stuff into a struct.

struct {
u16 cur_aid;
u8 cur_uldl;
u8 cur_color
u8 cur_enabled;
} monitor;

Could you please make a change if you plan to post a v2?

Ryder

2023-04-28 22:10:25

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH 5/6] wifi: mt76: mt7915: Improve monitor-mode flags settings.

On 4/28/23 14:48, Ryder Lee wrote:
> On Fri, 2023-04-28 at 13:49 -0700, [email protected] wrote:
>> External email : Please do not click links or open attachments until
>> you have verified the sender or the content.
>>
>>
>> From: Ben Greear <[email protected]>
>>
>> This enables capturing more frames, and now when the rx5 group
>> option is also enabled for rx-status, wireshark shows HE-TRIG
>> as well as HE-MU frames.
>>
>> Signed-off-by: Ben Greear <[email protected]>
>> ---
>> .../net/wireless/mediatek/mt76/mt7915/main.c | 26
>> +++++++++++++++++--
>> .../net/wireless/mediatek/mt76/mt7915/regs.h | 16 ++++++++++++
>> 2 files changed, 40 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> index 64c14fc303a2..55aed3c6d3be 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> @@ -562,6 +562,12 @@ static void __mt7915_configure_filter(struct
>> ieee80211_hw *hw,
>> MT_WF_RFCR1_DROP_BF_POLL |
>> MT_WF_RFCR1_DROP_BA |
>> MT_WF_RFCR1_DROP_CFEND |
>> + MT_WF_RFCR1_DROP_PS_BFRPOL |
>> + MT_WF_RFCR1_DROP_PS_NDPA |
>> + MT_WF_RFCR1_DROP_NO2ME_TF |
>> + MT_WF_RFCR1_DROP_NON_MUBAR_TF |
>> + MT_WF_RFCR1_DROP_RXS_BRP |
>> + MT_WF_RFCR1_DROP_TF_BFRP |
>> MT_WF_RFCR1_DROP_CFACK;
>> u32 flags = 0;
>> bool is_promisc = *total_flags & FIF_CONTROL || phy-
>>> monitor_vif ||
>> @@ -587,7 +593,9 @@ static void __mt7915_configure_filter(struct
>> ieee80211_hw *hw,
>> MT_WF_RFCR_DROP_BCAST |
>> MT_WF_RFCR_DROP_DUPLICATE |
>> MT_WF_RFCR_DROP_A2_BSSID |
>> - MT_WF_RFCR_DROP_UNWANTED_CTL |
>> + MT_WF_RFCR_DROP_UNWANTED_CTL | /* 0 means
>> drop */
>> + MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT |
>> + MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL |
>> MT_WF_RFCR_DROP_STBC_MULTI);
>>
>> phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
>> @@ -602,8 +610,22 @@ static void __mt7915_configure_filter(struct
>> ieee80211_hw *hw,
>> MT_WF_RFCR_DROP_RTS |
>> MT_WF_RFCR_DROP_CTL_RSV |
>> MT_WF_RFCR_DROP_NDPA);
>> - if (is_promisc)
>> + if (is_promisc) {
>> phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
>> + phy->rxfilter |=
>> MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT;
>> + if (flags & FIF_CONTROL) {
>> + phy->rxfilter |=
>> MT_WF_RFCR_DROP_UNWANTED_CTL; /* 1 means receive */
>> + phy->rxfilter |= MT_WF_RFCR_SECOND_BCN_EN;
>> + phy->rxfilter |=
>> MT_WF_RFCR_RX_MGMT_FRAME_CTRL;
>> + phy->rxfilter |=
>> MT_WF_RFCR_RX_SAMEBSSIDPRORESP_CTRL;
>> + phy->rxfilter |=
>> MT_WF_RFCR_RX_DIFFBSSIDPRORESP_CTRL;
>> + phy->rxfilter |=
>> MT_WF_RFCR_RX_SAMEBSSIDBCN_CTRL;
>> + phy->rxfilter |=
>> MT_WF_RFCR_RX_SAMEBSSIDNULL_CTRL;
>> + phy->rxfilter |=
>> MT_WF_RFCR_RX_DIFFBSSIDNULL_CTRL;
>> + phy->rxfilter &=
>> ~(MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL);
>
> FIF_CONTROL: pass control frame. However, many of these are not control
> frames. I think we should move monitor dedicated misc parts to
> IEEE80211_CONF_CHANGE_MONITOR mt7915_set_monitor and leave this
> function as-is ... as my reply in [2/6].

My understanding is that the rxfilter and related phy fields should take all settings and vdevs into account.
So if monitor mode is enabled, and another sta/ap vdev exists, and someone takes any action that causes
the stack to call the set_filter() logic on the sta/vdev, then set_filter must know about the monitor port to
do the right thing. This is why mt7915_configure_filter should handle everything and be aware of
monitor port existing or not.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2023-04-29 02:46:33

by Ryder Lee

[permalink] [raw]
Subject: Re: [PATCH 5/6] wifi: mt76: mt7915: Improve monitor-mode flags settings.

On Fri, 2023-04-28 at 15:06 -0700, Ben Greear wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> On 4/28/23 14:48, Ryder Lee wrote:
> > On Fri, 2023-04-28 at 13:49 -0700, [email protected] wrote:
> > > External email : Please do not click links or open attachments
> > > until
> > > you have verified the sender or the content.
> > >
> > >
> > > From: Ben Greear <[email protected]>
> > >
> > > This enables capturing more frames, and now when the rx5 group
> > > option is also enabled for rx-status, wireshark shows HE-TRIG
> > > as well as HE-MU frames.
> > >
> > > Signed-off-by: Ben Greear <[email protected]>
> > > ---
> > > .../net/wireless/mediatek/mt76/mt7915/main.c | 26
> > > +++++++++++++++++--
> > > .../net/wireless/mediatek/mt76/mt7915/regs.h | 16 ++++++++++++
> > > 2 files changed, 40 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > index 64c14fc303a2..55aed3c6d3be 100644
> > > --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > @@ -562,6 +562,12 @@ static void __mt7915_configure_filter(struct
> > > ieee80211_hw *hw,
> > > MT_WF_RFCR1_DROP_BF_POLL |
> > > MT_WF_RFCR1_DROP_BA |
> > > MT_WF_RFCR1_DROP_CFEND |
> > > + MT_WF_RFCR1_DROP_PS_BFRPOL |
> > > + MT_WF_RFCR1_DROP_PS_NDPA |
> > > + MT_WF_RFCR1_DROP_NO2ME_TF |
> > > + MT_WF_RFCR1_DROP_NON_MUBAR_TF |
> > > + MT_WF_RFCR1_DROP_RXS_BRP |
> > > + MT_WF_RFCR1_DROP_TF_BFRP |
> > > MT_WF_RFCR1_DROP_CFACK;
> > > u32 flags = 0;
> > > bool is_promisc = *total_flags & FIF_CONTROL || phy-
> > > > monitor_vif ||
> > >
> > > @@ -587,7 +593,9 @@ static void __mt7915_configure_filter(struct
> > > ieee80211_hw *hw,
> > > MT_WF_RFCR_DROP_BCAST |
> > > MT_WF_RFCR_DROP_DUPLICATE |
> > > MT_WF_RFCR_DROP_A2_BSSID |
> > > - MT_WF_RFCR_DROP_UNWANTED_CTL |
> > > + MT_WF_RFCR_DROP_UNWANTED_CTL | /* 0
> > > means
> > > drop */
> > > + MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT
> > > |
> > > + MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL |
> > > MT_WF_RFCR_DROP_STBC_MULTI);
> > >
> > > phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
> > > @@ -602,8 +610,22 @@ static void __mt7915_configure_filter(struct
> > > ieee80211_hw *hw,
> > > MT_WF_RFCR_DROP_RTS |
> > > MT_WF_RFCR_DROP_CTL_RSV |
> > > MT_WF_RFCR_DROP_NDPA);
> > > - if (is_promisc)
> > > + if (is_promisc) {
> > > phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT;
> > > + if (flags & FIF_CONTROL) {
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_DROP_UNWANTED_CTL; /* 1 means receive */
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_SECOND_BCN_EN;
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_RX_MGMT_FRAME_CTRL;
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_RX_SAMEBSSIDPRORESP_CTRL;
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_RX_DIFFBSSIDPRORESP_CTRL;
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_RX_SAMEBSSIDBCN_CTRL;
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_RX_SAMEBSSIDNULL_CTRL;
> > > + phy->rxfilter |=
> > > MT_WF_RFCR_RX_DIFFBSSIDNULL_CTRL;
> > > + phy->rxfilter &=
> > > ~(MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL);
> >
> > FIF_CONTROL: pass control frame. However, many of these are not
> > control
> > frames. I think we should move monitor dedicated misc parts to
> > IEEE80211_CONF_CHANGE_MONITOR mt7915_set_monitor and leave this
> > function as-is ... as my reply in [2/6].
>
> My understanding is that the rxfilter and related phy fields should
> take all settings and vdevs into account.
> So if monitor mode is enabled, and another sta/ap vdev exists, and
> someone takes any action that causes
> the stack to call the set_filter() logic on the sta/vdev, then
> set_filter must know about the monitor port to
> do the right thing. This is why mt7915_configure_filter should
> handle everything and be aware of
> monitor port existing or not.
>

This depends on what we end up doing with mixed modes. IMO, monitor
mode should be in the driver's seat. Hence we set/clear phy->rxfilter
or specific registers addtionally via IEEE80211_CONF_CHANGE_MONITOR as
we alreay did for MT_WF_RFCR_DROP_OTHER_US, right?

Ryder

2023-04-29 15:01:04

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH 5/6] wifi: mt76: mt7915: Improve monitor-mode flags settings.

On 4/28/23 7:33 PM, Ryder Lee wrote:
> On Fri, 2023-04-28 at 15:06 -0700, Ben Greear wrote:
>> External email : Please do not click links or open attachments until
>> you have verified the sender or the content.
>>
>>
>> On 4/28/23 14:48, Ryder Lee wrote:
>> > On Fri, 2023-04-28 at 13:49 -0700, [email protected] wrote:
>> > > External email : Please do not click links or open attachments
>> > > until
>> > > you have verified the sender or the content.
>> > >
>> > >
>> > > From: Ben Greear <[email protected]>
>> > >
>> > > This enables capturing more frames, and now when the rx5 group
>> > > option is also enabled for rx-status, wireshark shows HE-TRIG
>> > > as well as HE-MU frames.
>> > >
>> > > Signed-off-by: Ben Greear <[email protected]>
>> > > ---
>> > > .../net/wireless/mediatek/mt76/mt7915/main.c | 26
>> > > +++++++++++++++++--
>> > > .../net/wireless/mediatek/mt76/mt7915/regs.h | 16 ++++++++++++
>> > > 2 files changed, 40 insertions(+), 2 deletions(-)
>> > >
>> > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> > > b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> > > index 64c14fc303a2..55aed3c6d3be 100644
>> > > --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> > > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
>> > > @@ -562,6 +562,12 @@ static void __mt7915_configure_filter(struct
>> > > ieee80211_hw *hw,
>> > > MT_WF_RFCR1_DROP_BF_POLL |
>> > > MT_WF_RFCR1_DROP_BA |
>> > > MT_WF_RFCR1_DROP_CFEND |
>> > > + MT_WF_RFCR1_DROP_PS_BFRPOL |
>> > > + MT_WF_RFCR1_DROP_PS_NDPA |
>> > > + MT_WF_RFCR1_DROP_NO2ME_TF |
>> > > + MT_WF_RFCR1_DROP_NON_MUBAR_TF |
>> > > + MT_WF_RFCR1_DROP_RXS_BRP |
>> > > + MT_WF_RFCR1_DROP_TF_BFRP |
>> > > MT_WF_RFCR1_DROP_CFACK;
>> > > u32 flags = 0;
>> > > bool is_promisc = *total_flags & FIF_CONTROL || phy-
>> > > > monitor_vif ||
>> > >
>> > > @@ -587,7 +593,9 @@ static void __mt7915_configure_filter(struct
>> > > ieee80211_hw *hw,
>> > > MT_WF_RFCR_DROP_BCAST |
>> > > MT_WF_RFCR_DROP_DUPLICATE |
>> > > MT_WF_RFCR_DROP_A2_BSSID |
>> > > - MT_WF_RFCR_DROP_UNWANTED_CTL |
>> > > + MT_WF_RFCR_DROP_UNWANTED_CTL | /* 0
>> > > means
>> > > drop */
>> > > + MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT
>> > > |
>> > > + MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL |
>> > > MT_WF_RFCR_DROP_STBC_MULTI);
>> > >
>> > > phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
>> > > @@ -602,8 +610,22 @@ static void __mt7915_configure_filter(struct
>> > > ieee80211_hw *hw,
>> > > MT_WF_RFCR_DROP_RTS |
>> > > MT_WF_RFCR_DROP_CTL_RSV |
>> > > MT_WF_RFCR_DROP_NDPA);
>> > > - if (is_promisc)
>> > > + if (is_promisc) {
>> > > phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT;
>> > > + if (flags & FIF_CONTROL) {
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_DROP_UNWANTED_CTL; /* 1 means receive */
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_SECOND_BCN_EN;
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_RX_MGMT_FRAME_CTRL;
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_RX_SAMEBSSIDPRORESP_CTRL;
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_RX_DIFFBSSIDPRORESP_CTRL;
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_RX_SAMEBSSIDBCN_CTRL;
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_RX_SAMEBSSIDNULL_CTRL;
>> > > + phy->rxfilter |=
>> > > MT_WF_RFCR_RX_DIFFBSSIDNULL_CTRL;
>> > > + phy->rxfilter &=
>> > > ~(MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL);
>> >
>> > FIF_CONTROL: pass control frame. However, many of these are not
>> > control
>> > frames. I think we should move monitor dedicated misc parts to
>> > IEEE80211_CONF_CHANGE_MONITOR mt7915_set_monitor and leave this
>> > function as-is ... as my reply in [2/6].
>>
>> My understanding is that the rxfilter and related phy fields should
>> take all settings and vdevs into account.
>> So if monitor mode is enabled, and another sta/ap vdev exists, and
>> someone takes any action that causes
>> the stack to call the set_filter() logic on the sta/vdev, then
>> set_filter must know about the monitor port to
>> do the right thing. This is why mt7915_configure_filter should
>> handle everything and be aware of
>> monitor port existing or not.
>>
>
> This depends on what we end up doing with mixed modes. IMO, monitor
> mode should be in the driver's seat. Hence we set/clear phy->rxfilter
> or specific registers addtionally via IEEE80211_CONF_CHANGE_MONITOR as
> we alreay did for MT_WF_RFCR_DROP_OTHER_US, right?

My patch should make monitor mode work whether or not other vdevs are active
(and causing calls to set_filter logic after monitor mode was enabled).
And it puts the somewhat tricky filter and related register logic into a single location.

If we do not pay attention to monitor-mode in the set_filter, then it
will probably break in mixed vdev mode.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com

2023-04-30 18:08:59

by Ryder Lee

[permalink] [raw]
Subject: Re: [PATCH 5/6] wifi: mt76: mt7915: Improve monitor-mode flags settings.

On Sat, 2023-04-29 at 07:42 -0700, Ben Greear wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>
>
> On 4/28/23 7:33 PM, Ryder Lee wrote:
> > On Fri, 2023-04-28 at 15:06 -0700, Ben Greear wrote:
> > > External email : Please do not click links or open attachments
> > > until
> > > you have verified the sender or the content.
> > >
> > >
> > > On 4/28/23 14:48, Ryder Lee wrote:
> > > > On Fri, 2023-04-28 at 13:49 -0700, [email protected]
> > > > wrote:
> > > > > External email : Please do not click links or open
> > > > > attachments
> > > > > until
> > > > > you have verified the sender or the content.
> > > > >
> > > > >
> > > > > From: Ben Greear <[email protected]>
> > > > >
> > > > > This enables capturing more frames, and now when the rx5
> > > > > group
> > > > > option is also enabled for rx-status, wireshark shows HE-TRIG
> > > > > as well as HE-MU frames.
> > > > >
> > > > > Signed-off-by: Ben Greear <[email protected]>
> > > > > ---
> > > > > .../net/wireless/mediatek/mt76/mt7915/main.c | 26
> > > > > +++++++++++++++++--
> > > > > .../net/wireless/mediatek/mt76/mt7915/regs.h | 16
> > > > > ++++++++++++
> > > > > 2 files changed, 40 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > > > b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > > > index 64c14fc303a2..55aed3c6d3be 100644
> > > > > --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
> > > > > @@ -562,6 +562,12 @@ static void
> > > > > __mt7915_configure_filter(struct
> > > > > ieee80211_hw *hw,
> > > > > MT_WF_RFCR1_DROP_BF_POLL |
> > > > > MT_WF_RFCR1_DROP_BA |
> > > > > MT_WF_RFCR1_DROP_CFEND |
> > > > > + MT_WF_RFCR1_DROP_PS_BFRPOL |
> > > > > + MT_WF_RFCR1_DROP_PS_NDPA |
> > > > > + MT_WF_RFCR1_DROP_NO2ME_TF |
> > > > > + MT_WF_RFCR1_DROP_NON_MUBAR_TF |
> > > > > + MT_WF_RFCR1_DROP_RXS_BRP |
> > > > > + MT_WF_RFCR1_DROP_TF_BFRP |
> > > > > MT_WF_RFCR1_DROP_CFACK;
> > > > > u32 flags = 0;
> > > > > bool is_promisc = *total_flags & FIF_CONTROL || phy-
> > > > > > monitor_vif ||
> > > > >
> > > > > @@ -587,7 +593,9 @@ static void
> > > > > __mt7915_configure_filter(struct
> > > > > ieee80211_hw *hw,
> > > > > MT_WF_RFCR_DROP_BCAST |
> > > > > MT_WF_RFCR_DROP_DUPLICATE |
> > > > > MT_WF_RFCR_DROP_A2_BSSID |
> > > > > - MT_WF_RFCR_DROP_UNWANTED_CTL |
> > > > > + MT_WF_RFCR_DROP_UNWANTED_CTL | /*
> > > > > 0
> > > > > means
> > > > > drop */
> > > > > + MT_WF_RFCR_IND_FILTER_EN_OF_31_23_
> > > > > BIT
> > > > > >
> > > > >
> > > > > + MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL
> > > > > |
> > > > > MT_WF_RFCR_DROP_STBC_MULTI);
> > > > >
> > > > > phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
> > > > > @@ -602,8 +610,22 @@ static void
> > > > > __mt7915_configure_filter(struct
> > > > > ieee80211_hw *hw,
> > > > > MT_WF_RFCR_DROP_RTS |
> > > > > MT_WF_RFCR_DROP_CTL_RSV |
> > > > > MT_WF_RFCR_DROP_NDPA);
> > > > > - if (is_promisc)
> > > > > + if (is_promisc) {
> > > > > phy->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_IND_FILTER_EN_OF_31_23_BIT;
> > > > > + if (flags & FIF_CONTROL) {
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_DROP_UNWANTED_CTL; /* 1 means receive */
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_SECOND_BCN_EN;
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_RX_MGMT_FRAME_CTRL;
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_RX_SAMEBSSIDPRORESP_CTRL;
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_RX_DIFFBSSIDPRORESP_CTRL;
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_RX_SAMEBSSIDBCN_CTRL;
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_RX_SAMEBSSIDNULL_CTRL;
> > > > > + phy->rxfilter |=
> > > > > MT_WF_RFCR_RX_DIFFBSSIDNULL_CTRL;
> > > > > + phy->rxfilter &=
> > > > > ~(MT_WF_RFCR_DROP_DIFFBSSIDMGT_CTRL);
> > > >
> > > > FIF_CONTROL: pass control frame. However, many of these are not
> > > > control
> > > > frames. I think we should move monitor dedicated misc parts to
> > > > IEEE80211_CONF_CHANGE_MONITOR mt7915_set_monitor and leave this
> > > > function as-is ... as my reply in [2/6].
> > >
> > > My understanding is that the rxfilter and related phy fields
> > > should
> > > take all settings and vdevs into account.
> > > So if monitor mode is enabled, and another sta/ap vdev exists,
> > > and
> > > someone takes any action that causes
> > > the stack to call the set_filter() logic on the sta/vdev, then
> > > set_filter must know about the monitor port to
> > > do the right thing. This is why mt7915_configure_filter should
> > > handle everything and be aware of
> > > monitor port existing or not.
> > >
> >
> > This depends on what we end up doing with mixed modes. IMO, monitor
> > mode should be in the driver's seat. Hence we set/clear phy-
> > >rxfilter
> > or specific registers addtionally via IEEE80211_CONF_CHANGE_MONITOR
> > as
> > we alreay did for MT_WF_RFCR_DROP_OTHER_US, right?
>
> My patch should make monitor mode work whether or not other vdevs are
> active
> (and causing calls to set_filter logic after monitor mode was
> enabled).
> And it puts the somewhat tricky filter and related register logic
> into a single location.
>
> If we do not pay attention to monitor-mode in the set_filter, then it
> will probably break in mixed vdev mode.
>
>
Similar to [1/6] VHT mu-mimo sniffer thing.

That's the reason why "iw monitor mode flags" exists, right? I think
users can handle this situation themselves via iw command, which is
more flexible than adding a fixed vdev check in driver. That said, user
can decide what fif_flags they want by doing so.

And we can just put extra monitor specific controls into
IEEE80211_CONF_CHANGE_MONITOR.

Ryder