Skip to content

Commit

Permalink
wifi: mt76: mt7915: rework tx packets counting when WED is active
Browse files Browse the repository at this point in the history
PPDU TxS can only report MPDU count whereas mac80211 requires MSDU scale
(NL80211_STA_INFO_TX_PACKETS), so switch to get MSDU counts from WA
statistic.

Note that mt7915 WA firmware only counts tx_packet for WED path, so driver
needs to take care of host path additionally.

Fixes: 43eaa3689507 ("wifi: mt76: add PPDU based TxS support for WED device")
Co-developed-by: Ryder Lee <[email protected]>
Signed-off-by: Ryder Lee <[email protected]>
Signed-off-by: Peter Chiu <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
  • Loading branch information
Peter Chiu authored and nbd168 committed Jun 22, 2023
1 parent d2a77a9 commit f76b102
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion mt76.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ struct mt76_sta_stats {
u64 tx_mcs[16]; /* mcs idx */
u64 tx_bytes;
/* WED TX */
u32 tx_packets;
u32 tx_packets; /* unit: MSDU */
u32 tx_retries;
u32 tx_failed;
/* WED RX */
Expand Down
9 changes: 5 additions & 4 deletions mt76_connac_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,

/* counting non-offloading skbs */
wcid->stats.tx_bytes += skb->len;
wcid->stats.tx_packets++;
/* mt7915 WA only counts WED path */
if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed))
wcid->stats.tx_packets++;
}

val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
Expand Down Expand Up @@ -606,12 +608,11 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
txs = le32_to_cpu(txs_data[0]);

/* PPDU based reporting */
if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
if (mtk_wed_device_active(&dev->mmio.wed) &&
FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) {
stats->tx_bytes +=
le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) -
le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE);
stats->tx_packets +=
le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT);
stats->tx_failed +=
le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT);
stats->tx_retries +=
Expand Down
1 change: 1 addition & 0 deletions mt76_connac_mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ enum {
MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
MCU_EXT_EVENT_RDD_REPORT = 0x3a,
MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
MCU_EXT_EVENT_WA_TX_STAT = 0x74,
MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
MCU_EXT_EVENT_MURU_CTRL = 0x9f,
};
Expand Down
6 changes: 4 additions & 2 deletions mt7915/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,8 +1042,10 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
sinfo->tx_bytes = msta->wcid.stats.tx_bytes;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);

sinfo->tx_packets = msta->wcid.stats.tx_packets;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) {
sinfo->tx_packets = msta->wcid.stats.tx_packets;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
}

if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {
sinfo->rx_bytes = msta->wcid.stats.rx_bytes;
Expand Down
74 changes: 67 additions & 7 deletions mt7915/mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
}

rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
if (seq != rxd->seq)
if (seq != rxd->seq &&
!(rxd->eid == MCU_CMD_EXT_CID &&
rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
return -EAGAIN;

if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
Expand Down Expand Up @@ -398,12 +400,14 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
struct mt76_connac2_mcu_rxd *rxd;

rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
!rxd->seq)
if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY ||
!rxd->seq) &&
!(rxd->eid == MCU_CMD_EXT_CID &&
rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT))
mt7915_mcu_rx_unsolicited_event(dev, skb);
else
mt76_mcu_rx_event(&dev->mt76, skb);
Expand Down Expand Up @@ -3736,6 +3740,62 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
&req, sizeof(req), true);
}

int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx)
{
struct {
__le32 cmd;
__le32 num;
__le32 __rsv;
__le16 wlan_idx;
} req = {
.cmd = cpu_to_le32(0x15),
.num = cpu_to_le32(1),
.wlan_idx = cpu_to_le16(wlan_idx),
};
struct mt7915_mcu_wa_tx_stat {
__le16 wlan_idx;
u8 __rsv[2];

/* tx_bytes is deprecated since WA byte counter uses u32,
* which easily leads to overflow.
*/
__le32 tx_bytes;
__le32 tx_packets;
} *res;
struct mt76_wcid *wcid;
struct sk_buff *skb;
int ret;

ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY),
&req, sizeof(req), true, &skb);
if (ret)
return ret;

if (!is_mt7915(&dev->mt76))
skb_pull(skb, 4);

res = (struct mt7915_mcu_wa_tx_stat *)skb->data;

if (le16_to_cpu(res->wlan_idx) != wlan_idx) {
ret = -EINVAL;
goto out;
}

rcu_read_lock();

wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);
if (wcid)
wcid->stats.tx_packets += le32_to_cpu(res->tx_packets);
else
ret = -EINVAL;

rcu_read_unlock();
out:
dev_kfree_skb(skb);

return ret;
}

int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
{
struct {
Expand Down
1 change: 1 addition & 0 deletions mt7915/mt7915.h
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct rate_info *rate);
int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy,
struct cfg80211_chan_def *chandef);
int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid);
int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set);
int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
Expand Down

0 comments on commit f76b102

Please sign in to comment.