From: Shayne Chen <shayne.chen@mediatek.com>
To: Felix Fietkau <nbd@nbd.name>
Cc: Ryder Lee <ryder.lee@mediatek.com>,
Evelyn Tsai <evelyn.tsai@mediatek.com>,
linux-wireless <linux-wireless@vger.kernel.org>,
linux-mediatek <linux-mediatek@lists.infradead.org>,
Lorenzo Bianconi <lorenzo.bianconi@redhat.com>,
Shayne Chen <shayne.chen@mediatek.com>
Subject: [PATCH v3 08/10] mt76: mt7915: implement testmode rx support
Date: Mon, 12 Oct 2020 20:54:01 +0800 [thread overview]
Message-ID: <20201012125403.8608-8-shayne.chen@mediatek.com> (raw)
In-Reply-To: <20201012125403.8608-1-shayne.chen@mediatek.com>
Support testmode rx and display rx statistic by parsing RXV packet
type, which is currently only enabled in testmode.
Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
v2: change last_snr to u8
v3: use nla_put_u8 for MT76_TM_RX_ATTR_SNR
change snr variable type to u8 in mt7915_mac_fill_rx_vector
.../net/wireless/mediatek/mt76/mt7915/dma.c | 3 +
.../net/wireless/mediatek/mt76/mt7915/mac.c | 38 ++++++++
.../net/wireless/mediatek/mt76/mt7915/mac.h | 5 +
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 1 +
.../wireless/mediatek/mt76/mt7915/mt7915.h | 7 ++
.../wireless/mediatek/mt76/mt7915/testmode.c | 97 +++++++++++++++++++
.../wireless/mediatek/mt76/mt7915/testmode.h | 30 ++++++
7 files changed, 181 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
index cfa12c4..e14814d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
@@ -61,6 +61,9 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
case PKT_TYPE_RX_EVENT:
mt7915_mcu_rx_event(dev, skb);
break;
+ case PKT_TYPE_TXRXV:
+ mt7915_mac_fill_rx_vector(dev, skb);
+ break;
case PKT_TYPE_NORMAL:
if (!mt7915_mac_fill_rx(dev, skb)) {
mt76_rx(&dev->mt76, q, skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index e03e12f..7bfdf54 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -562,6 +562,44 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
return 0;
}
+void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
+{
+#ifdef CONFIG_NL80211_TESTMODE
+ __le32 *rxd = (__le32 *)skb->data;
+ __le32 *rxv = rxd + 4;
+ u32 rcpi, ib_rssi, wb_rssi, v20, v21;
+ s32 foe;
+ u8 snr;
+ int i;
+
+ rcpi = le32_to_cpu(rxv[6]);
+ ib_rssi = le32_to_cpu(rxv[7]);
+ wb_rssi = le32_to_cpu(rxv[8]) >> 5;
+
+ for (i = 0; i < 4; i++, rcpi >>= 8, ib_rssi >>= 8, wb_rssi >>= 9) {
+ if (i == 3)
+ wb_rssi = le32_to_cpu(rxv[9]);
+
+ dev->test.last_rcpi[i] = rcpi & 0xff;
+ dev->test.last_ib_rssi[i] = ib_rssi & 0xff;
+ dev->test.last_wb_rssi[i] = wb_rssi & 0xff;
+ }
+
+ v20 = le32_to_cpu(rxv[20]);
+ v21 = le32_to_cpu(rxv[21]);
+
+ foe = FIELD_GET(MT_CRXV_FOE_LO, v20) |
+ (FIELD_GET(MT_CRXV_FOE_HI, v21) << MT_CRXV_FOE_SHIFT);
+
+ snr = FIELD_GET(MT_CRXV_SNR, v20) - 16;
+
+ dev->test.last_freq_offset = foe;
+ dev->test.last_snr = snr;
+
+ dev_kfree_skb(skb);
+#endif
+}
+
static u16
mt7915_mac_tx_rate_val(struct mt76_phy *mphy, u8 mode, u8 rate_idx,
u8 nss, u8 stbc, u8 *bw)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
index 0921b6f..d420392 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
@@ -128,6 +128,11 @@ enum rx_pkt_type {
#define MT_CRXV_HE_BEAM_CHNG BIT(13)
#define MT_CRXV_HE_DOPPLER BIT(16)
+#define MT_CRXV_SNR GENMASK(18, 13)
+#define MT_CRXV_FOE_LO GENMASK(31, 19)
+#define MT_CRXV_FOE_HI GENMASK(6, 0)
+#define MT_CRXV_FOE_SHIFT 13
+
enum tx_header_format {
MT_HDR_FORMAT_802_3,
MT_HDR_FORMAT_CMD,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 0a7e9d2..89453a6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -48,6 +48,7 @@ enum {
enum {
MCU_ATE_SET_TRX = 0x1,
+ MCU_ATE_SET_RX_FILTER = 0x3,
};
struct mt7915_mcu_rxd {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 6735915..fd7de79 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -165,6 +165,12 @@ struct mt7915_dev {
struct {
u32 *reg_backup;
+ s32 last_freq_offset;
+ u8 last_rcpi[4];
+ s8 last_ib_rssi[4];
+ s8 last_wb_rssi[4];
+ u8 last_snr;
+
u8 spe_idx;
} test;
#endif
@@ -436,6 +442,7 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
struct ieee80211_key_conf *key, bool beacon);
void mt7915_mac_set_timing(struct mt7915_phy *phy);
int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb);
+void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb);
void mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb);
int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
index 5d95766..acab268 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
@@ -113,6 +113,31 @@ mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy)
mt76_clear(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TBTT_STOP_CTRL);
}
+static int
+mt7915_tm_config_rx_filter(struct mt7915_dev *dev, bool en)
+{
+ struct mt7915_tm_cmd req = {
+ .testmode_en = 1,
+ .param_idx = MCU_ATE_SET_RX_FILTER,
+ .param.filter.report_en = en,
+ .param.filter.band = 0, /* TODO: support dbdc */
+ };
+ __le32 mask = RX_FILTER_NOT_OWN_BTIM |
+ RX_FILTER_NOT_OWN_UCAST |
+ RX_FILTER_RTS | RX_FILTER_CTS |
+ RX_FILTER_CTRL_RSV |
+ RX_FILTER_BC_MC_BSSID_A2 |
+ RX_FILTER_BC_MC_BSSID_A3 |
+ RX_FILTER_BC_MC_OMAC_A3 |
+ RX_FILTER_PROTOCOL_VERSION |
+ RX_FILTER_FCS_ERR;
+
+ req.param.filter.mask = cpu_to_le32(mask);
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req,
+ sizeof(req), false);
+}
+
static void
mt7915_tm_init(struct mt7915_dev *dev)
{
@@ -124,6 +149,7 @@ mt7915_tm_init(struct mt7915_dev *dev)
mt7915_tm_mode_ctrl(dev, en);
mt7915_tm_reg_backup_restore(dev, &dev->phy);
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TXRX, !en);
+ mt7915_tm_config_rx_filter(dev, en);
}
static void
@@ -156,6 +182,20 @@ mt7915_tm_set_tx_frames(struct mt7915_dev *dev, bool en)
info->control.vif = dev->phy.monitor_vif;
}
+static void
+mt7915_tm_set_rx_frames(struct mt7915_dev *dev, bool en)
+{
+ if (en) {
+ mutex_unlock(&dev->mt76.mutex);
+ mt7915_set_channel(&dev->phy);
+ mutex_lock(&dev->mt76.mutex);
+
+ mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH);
+ }
+
+ mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, en);
+}
+
static int
mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
{
@@ -169,12 +209,69 @@ mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
mt7915_tm_set_tx_frames(dev, false);
else if (state == MT76_TM_STATE_TX_FRAMES)
mt7915_tm_set_tx_frames(dev, true);
+ else if (prev_state == MT76_TM_STATE_RX_FRAMES)
+ mt7915_tm_set_rx_frames(dev, false);
+ else if (state == MT76_TM_STATE_RX_FRAMES)
+ mt7915_tm_set_rx_frames(dev, true);
else if (prev_state == MT76_TM_STATE_OFF || state == MT76_TM_STATE_OFF)
mt7915_tm_init(dev);
return 0;
}
+static int
+mt7915_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
+{
+ struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
+ void *rx, *rssi;
+ int i;
+
+ rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX);
+ if (!rx)
+ return -ENOMEM;
+
+ if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, dev->test.last_freq_offset))
+ return -ENOMEM;
+
+ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI);
+ if (!rssi)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(dev->test.last_rcpi); i++)
+ if (nla_put_u8(msg, i, dev->test.last_rcpi[i]))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rssi);
+
+ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI);
+ if (!rssi)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(dev->test.last_ib_rssi); i++)
+ if (nla_put_s8(msg, i, dev->test.last_ib_rssi[i]))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rssi);
+
+ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_WB_RSSI);
+ if (!rssi)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(dev->test.last_wb_rssi); i++)
+ if (nla_put_s8(msg, i, dev->test.last_wb_rssi[i]))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rssi);
+
+ if (nla_put_u8(msg, MT76_TM_RX_ATTR_SNR, dev->test.last_snr))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rx);
+
+ return 0;
+}
+
const struct mt76_testmode_ops mt7915_testmode_ops = {
.set_state = mt7915_tm_set_state,
+ .dump_stats = mt7915_tm_dump_stats,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h
index 04f4a2c..b344a64 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h
@@ -11,6 +11,15 @@ struct mt7915_tm_trx {
u8 rsv;
};
+struct mt7915_tm_rx_filter {
+ u8 promiscuous;
+ u8 report_en;
+ u8 band;
+ u8 _rsv;
+ __le32 mask;
+ u8 _rsv1[4];
+};
+
struct mt7915_tm_cmd {
u8 testmode_en;
u8 param_idx;
@@ -18,6 +27,7 @@ struct mt7915_tm_cmd {
union {
__le32 data;
struct mt7915_tm_trx trx;
+ struct mt7915_tm_rx_filter filter;
u8 test[72];
} param;
} __packed;
@@ -31,4 +41,24 @@ enum {
TM_MAC_RX_RXV,
};
+#define RX_FILTER_STBC_BCN_BC_MC BIT(0)
+#define RX_FILTER_FCS_ERR BIT(1)
+#define RX_FILTER_PROTOCOL_VERSION BIT(2)
+#define RX_FILTER_PROB_REQ BIT(3)
+#define RX_FILTER_MCAST BIT(4)
+#define RX_FILTER_BCAST BIT(5)
+#define RX_FILTER_MCAST_TABLE BIT(6)
+#define RX_FILTER_BC_MC_OMAC_A3 BIT(7)
+#define RX_FILTER_BC_MC_BSSID_A3 BIT(8)
+#define RX_FILTER_BC_MC_BSSID_A2 BIT(9)
+#define RX_FILTER_BCN_BSSID BIT(10)
+#define RX_FILTER_CTRL_RSV BIT(11)
+#define RX_FILTER_CTS BIT(12)
+#define RX_FILTER_RTS BIT(13)
+#define RX_FILTER_DUPLICATE BIT(14)
+#define RX_FILTER_NOT_OWN_BSSID BIT(15)
+#define RX_FILTER_NOT_OWN_UCAST BIT(16)
+#define RX_FILTER_NOT_OWN_BTIM BIT(17)
+#define RX_FILTER_NDPA BIT(18)
+
#endif
--
2.17.1
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
WARNING: multiple messages have this Message-ID (diff)
From: Shayne Chen <shayne.chen@mediatek.com>
To: Felix Fietkau <nbd@nbd.name>
Cc: linux-wireless <linux-wireless@vger.kernel.org>,
Lorenzo Bianconi <lorenzo.bianconi@redhat.com>,
Ryder Lee <ryder.lee@mediatek.com>,
Evelyn Tsai <evelyn.tsai@mediatek.com>,
linux-mediatek <linux-mediatek@lists.infradead.org>,
Shayne Chen <shayne.chen@mediatek.com>
Subject: [PATCH v3 08/10] mt76: mt7915: implement testmode rx support
Date: Mon, 12 Oct 2020 20:54:01 +0800 [thread overview]
Message-ID: <20201012125403.8608-8-shayne.chen@mediatek.com> (raw)
In-Reply-To: <20201012125403.8608-1-shayne.chen@mediatek.com>
Support testmode rx and display rx statistic by parsing RXV packet
type, which is currently only enabled in testmode.
Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
---
v2: change last_snr to u8
v3: use nla_put_u8 for MT76_TM_RX_ATTR_SNR
change snr variable type to u8 in mt7915_mac_fill_rx_vector
.../net/wireless/mediatek/mt76/mt7915/dma.c | 3 +
.../net/wireless/mediatek/mt76/mt7915/mac.c | 38 ++++++++
.../net/wireless/mediatek/mt76/mt7915/mac.h | 5 +
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 1 +
.../wireless/mediatek/mt76/mt7915/mt7915.h | 7 ++
.../wireless/mediatek/mt76/mt7915/testmode.c | 97 +++++++++++++++++++
.../wireless/mediatek/mt76/mt7915/testmode.h | 30 ++++++
7 files changed, 181 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
index cfa12c4..e14814d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
@@ -61,6 +61,9 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
case PKT_TYPE_RX_EVENT:
mt7915_mcu_rx_event(dev, skb);
break;
+ case PKT_TYPE_TXRXV:
+ mt7915_mac_fill_rx_vector(dev, skb);
+ break;
case PKT_TYPE_NORMAL:
if (!mt7915_mac_fill_rx(dev, skb)) {
mt76_rx(&dev->mt76, q, skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index e03e12f..7bfdf54 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -562,6 +562,44 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
return 0;
}
+void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
+{
+#ifdef CONFIG_NL80211_TESTMODE
+ __le32 *rxd = (__le32 *)skb->data;
+ __le32 *rxv = rxd + 4;
+ u32 rcpi, ib_rssi, wb_rssi, v20, v21;
+ s32 foe;
+ u8 snr;
+ int i;
+
+ rcpi = le32_to_cpu(rxv[6]);
+ ib_rssi = le32_to_cpu(rxv[7]);
+ wb_rssi = le32_to_cpu(rxv[8]) >> 5;
+
+ for (i = 0; i < 4; i++, rcpi >>= 8, ib_rssi >>= 8, wb_rssi >>= 9) {
+ if (i == 3)
+ wb_rssi = le32_to_cpu(rxv[9]);
+
+ dev->test.last_rcpi[i] = rcpi & 0xff;
+ dev->test.last_ib_rssi[i] = ib_rssi & 0xff;
+ dev->test.last_wb_rssi[i] = wb_rssi & 0xff;
+ }
+
+ v20 = le32_to_cpu(rxv[20]);
+ v21 = le32_to_cpu(rxv[21]);
+
+ foe = FIELD_GET(MT_CRXV_FOE_LO, v20) |
+ (FIELD_GET(MT_CRXV_FOE_HI, v21) << MT_CRXV_FOE_SHIFT);
+
+ snr = FIELD_GET(MT_CRXV_SNR, v20) - 16;
+
+ dev->test.last_freq_offset = foe;
+ dev->test.last_snr = snr;
+
+ dev_kfree_skb(skb);
+#endif
+}
+
static u16
mt7915_mac_tx_rate_val(struct mt76_phy *mphy, u8 mode, u8 rate_idx,
u8 nss, u8 stbc, u8 *bw)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
index 0921b6f..d420392 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
@@ -128,6 +128,11 @@ enum rx_pkt_type {
#define MT_CRXV_HE_BEAM_CHNG BIT(13)
#define MT_CRXV_HE_DOPPLER BIT(16)
+#define MT_CRXV_SNR GENMASK(18, 13)
+#define MT_CRXV_FOE_LO GENMASK(31, 19)
+#define MT_CRXV_FOE_HI GENMASK(6, 0)
+#define MT_CRXV_FOE_SHIFT 13
+
enum tx_header_format {
MT_HDR_FORMAT_802_3,
MT_HDR_FORMAT_CMD,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 0a7e9d2..89453a6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -48,6 +48,7 @@ enum {
enum {
MCU_ATE_SET_TRX = 0x1,
+ MCU_ATE_SET_RX_FILTER = 0x3,
};
struct mt7915_mcu_rxd {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 6735915..fd7de79 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -165,6 +165,12 @@ struct mt7915_dev {
struct {
u32 *reg_backup;
+ s32 last_freq_offset;
+ u8 last_rcpi[4];
+ s8 last_ib_rssi[4];
+ s8 last_wb_rssi[4];
+ u8 last_snr;
+
u8 spe_idx;
} test;
#endif
@@ -436,6 +442,7 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
struct ieee80211_key_conf *key, bool beacon);
void mt7915_mac_set_timing(struct mt7915_phy *phy);
int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb);
+void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb);
void mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb);
int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
index 5d95766..acab268 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
@@ -113,6 +113,31 @@ mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy)
mt76_clear(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TBTT_STOP_CTRL);
}
+static int
+mt7915_tm_config_rx_filter(struct mt7915_dev *dev, bool en)
+{
+ struct mt7915_tm_cmd req = {
+ .testmode_en = 1,
+ .param_idx = MCU_ATE_SET_RX_FILTER,
+ .param.filter.report_en = en,
+ .param.filter.band = 0, /* TODO: support dbdc */
+ };
+ __le32 mask = RX_FILTER_NOT_OWN_BTIM |
+ RX_FILTER_NOT_OWN_UCAST |
+ RX_FILTER_RTS | RX_FILTER_CTS |
+ RX_FILTER_CTRL_RSV |
+ RX_FILTER_BC_MC_BSSID_A2 |
+ RX_FILTER_BC_MC_BSSID_A3 |
+ RX_FILTER_BC_MC_OMAC_A3 |
+ RX_FILTER_PROTOCOL_VERSION |
+ RX_FILTER_FCS_ERR;
+
+ req.param.filter.mask = cpu_to_le32(mask);
+
+ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req,
+ sizeof(req), false);
+}
+
static void
mt7915_tm_init(struct mt7915_dev *dev)
{
@@ -124,6 +149,7 @@ mt7915_tm_init(struct mt7915_dev *dev)
mt7915_tm_mode_ctrl(dev, en);
mt7915_tm_reg_backup_restore(dev, &dev->phy);
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TXRX, !en);
+ mt7915_tm_config_rx_filter(dev, en);
}
static void
@@ -156,6 +182,20 @@ mt7915_tm_set_tx_frames(struct mt7915_dev *dev, bool en)
info->control.vif = dev->phy.monitor_vif;
}
+static void
+mt7915_tm_set_rx_frames(struct mt7915_dev *dev, bool en)
+{
+ if (en) {
+ mutex_unlock(&dev->mt76.mutex);
+ mt7915_set_channel(&dev->phy);
+ mutex_lock(&dev->mt76.mutex);
+
+ mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH);
+ }
+
+ mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, en);
+}
+
static int
mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
{
@@ -169,12 +209,69 @@ mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
mt7915_tm_set_tx_frames(dev, false);
else if (state == MT76_TM_STATE_TX_FRAMES)
mt7915_tm_set_tx_frames(dev, true);
+ else if (prev_state == MT76_TM_STATE_RX_FRAMES)
+ mt7915_tm_set_rx_frames(dev, false);
+ else if (state == MT76_TM_STATE_RX_FRAMES)
+ mt7915_tm_set_rx_frames(dev, true);
else if (prev_state == MT76_TM_STATE_OFF || state == MT76_TM_STATE_OFF)
mt7915_tm_init(dev);
return 0;
}
+static int
+mt7915_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
+{
+ struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
+ void *rx, *rssi;
+ int i;
+
+ rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX);
+ if (!rx)
+ return -ENOMEM;
+
+ if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, dev->test.last_freq_offset))
+ return -ENOMEM;
+
+ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI);
+ if (!rssi)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(dev->test.last_rcpi); i++)
+ if (nla_put_u8(msg, i, dev->test.last_rcpi[i]))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rssi);
+
+ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI);
+ if (!rssi)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(dev->test.last_ib_rssi); i++)
+ if (nla_put_s8(msg, i, dev->test.last_ib_rssi[i]))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rssi);
+
+ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_WB_RSSI);
+ if (!rssi)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(dev->test.last_wb_rssi); i++)
+ if (nla_put_s8(msg, i, dev->test.last_wb_rssi[i]))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rssi);
+
+ if (nla_put_u8(msg, MT76_TM_RX_ATTR_SNR, dev->test.last_snr))
+ return -ENOMEM;
+
+ nla_nest_end(msg, rx);
+
+ return 0;
+}
+
const struct mt76_testmode_ops mt7915_testmode_ops = {
.set_state = mt7915_tm_set_state,
+ .dump_stats = mt7915_tm_dump_stats,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h
index 04f4a2c..b344a64 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.h
@@ -11,6 +11,15 @@ struct mt7915_tm_trx {
u8 rsv;
};
+struct mt7915_tm_rx_filter {
+ u8 promiscuous;
+ u8 report_en;
+ u8 band;
+ u8 _rsv;
+ __le32 mask;
+ u8 _rsv1[4];
+};
+
struct mt7915_tm_cmd {
u8 testmode_en;
u8 param_idx;
@@ -18,6 +27,7 @@ struct mt7915_tm_cmd {
union {
__le32 data;
struct mt7915_tm_trx trx;
+ struct mt7915_tm_rx_filter filter;
u8 test[72];
} param;
} __packed;
@@ -31,4 +41,24 @@ enum {
TM_MAC_RX_RXV,
};
+#define RX_FILTER_STBC_BCN_BC_MC BIT(0)
+#define RX_FILTER_FCS_ERR BIT(1)
+#define RX_FILTER_PROTOCOL_VERSION BIT(2)
+#define RX_FILTER_PROB_REQ BIT(3)
+#define RX_FILTER_MCAST BIT(4)
+#define RX_FILTER_BCAST BIT(5)
+#define RX_FILTER_MCAST_TABLE BIT(6)
+#define RX_FILTER_BC_MC_OMAC_A3 BIT(7)
+#define RX_FILTER_BC_MC_BSSID_A3 BIT(8)
+#define RX_FILTER_BC_MC_BSSID_A2 BIT(9)
+#define RX_FILTER_BCN_BSSID BIT(10)
+#define RX_FILTER_CTRL_RSV BIT(11)
+#define RX_FILTER_CTS BIT(12)
+#define RX_FILTER_RTS BIT(13)
+#define RX_FILTER_DUPLICATE BIT(14)
+#define RX_FILTER_NOT_OWN_BSSID BIT(15)
+#define RX_FILTER_NOT_OWN_UCAST BIT(16)
+#define RX_FILTER_NOT_OWN_BTIM BIT(17)
+#define RX_FILTER_NDPA BIT(18)
+
#endif
--
2.17.1
next prev parent reply other threads:[~2020-10-12 12:56 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-12 12:53 [PATCH v3 01/10] mt76: testmode: switch ib and wb rssi to array type for per-antenna report Shayne Chen
2020-10-12 12:53 ` Shayne Chen
2020-10-12 12:53 ` [PATCH v3 02/10] mt76: testmode: add snr attribute in rx statistics Shayne Chen
2020-10-12 12:53 ` Shayne Chen
2020-10-12 12:53 ` [PATCH v3 03/10] mt76: testmode: add tx_rate_stbc parameter Shayne Chen
2020-10-12 12:53 ` Shayne Chen
2020-10-12 12:53 ` [PATCH v3 04/10] mt76: testmode: add support for LTF and GI combinations for HE mode Shayne Chen
2020-10-12 12:53 ` Shayne Chen
2020-10-12 12:53 ` [PATCH v3 05/10] mt76: mt7915: fix tx rate related fields in tx descriptor Shayne Chen
2020-10-12 12:53 ` Shayne Chen
2020-10-12 12:53 ` [PATCH v3 06/10] mt76: testmode: add support for HE rate modes Shayne Chen
2020-10-12 12:53 ` Shayne Chen
2020-10-12 12:54 ` [PATCH v3 07/10] mt76: mt7915: implement testmode tx support Shayne Chen
2020-10-12 12:54 ` Shayne Chen
2020-10-12 12:54 ` Shayne Chen [this message]
2020-10-12 12:54 ` [PATCH v3 08/10] mt76: mt7915: implement testmode rx support Shayne Chen
2020-10-14 10:23 ` Felix Fietkau
2020-10-14 10:23 ` Felix Fietkau
2020-10-12 12:54 ` [PATCH v3 09/10] mt76: mt7915: add support to set txpower in testmode Shayne Chen
2020-10-12 12:54 ` Shayne Chen
2020-10-12 12:54 ` [PATCH v3 10/10] mt76: mt7915: add support to set tx frequency offset " Shayne Chen
2020-10-12 12:54 ` Shayne Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201012125403.8608-8-shayne.chen@mediatek.com \
--to=shayne.chen@mediatek.com \
--cc=evelyn.tsai@mediatek.com \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
--cc=lorenzo.bianconi@redhat.com \
--cc=nbd@nbd.name \
--cc=ryder.lee@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.