Skip to content

Commit

Permalink
mt76: mt7915: implement testmode rx support
Browse files Browse the repository at this point in the history
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>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
Shayne Chen authored and Felix Fietkau committed Dec 4, 2020
1 parent aadf095 commit 5d8a83f
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 0 deletions.
5 changes: 5 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7915/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ 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;
#ifdef CONFIG_NL80211_TESTMODE
case PKT_TYPE_TXRXV:
mt7915_mac_fill_rx_vector(dev, skb);
break;
#endif
case PKT_TYPE_NORMAL:
if (!mt7915_mac_fill_rx(dev, skb)) {
mt76_rx(&dev->mt76, q, skb);
Expand Down
38 changes: 38 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7915/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,44 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
return 0;
}

#ifdef CONFIG_NL80211_TESTMODE
void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
{
__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 void
mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy,
__le32 *txwi, struct sk_buff *skb)
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7915/mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,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
Expand Down Expand Up @@ -442,6 +448,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);
Expand Down
77 changes: 77 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ static const struct reg_band reg_backup_list[] = {
REG_BAND(TMAC_ICR0),
REG_BAND_IDX(ARB_DRNGR0, 0),
REG_BAND_IDX(ARB_DRNGR0, 1),
REG_BAND(WF_RFCR),
REG_BAND(WF_RFCR1),
};

static int
Expand Down Expand Up @@ -111,6 +113,10 @@ mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy)

mt76_wr(dev, MT_TMAC_TFCR0(ext_phy), 0);
mt76_clear(dev, MT_TMAC_TCR0(ext_phy), MT_TMAC_TCR0_TBTT_STOP_CTRL);

/* config rx filter for testmode rx */
mt76_wr(dev, MT_WF_RFCR(ext_phy), 0xcf70a);
mt76_wr(dev, MT_WF_RFCR1(ext_phy), 0);
}

static void
Expand Down Expand Up @@ -156,6 +162,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)
{
Expand All @@ -169,12 +189,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,
};

0 comments on commit 5d8a83f

Please sign in to comment.