developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame^] | 1 | From 63501a3e941097581dcee61a0149ee5bc944c579 Mon Sep 17 00:00:00 2001 |
| 2 | From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com> |
| 3 | Date: Wed, 28 Jun 2023 08:10:25 +0800 |
| 4 | Subject: [PATCH 18/98] wifi: mt76: mt7996: Add mcu commands for getting sta tx |
| 5 | statistic |
| 6 | |
| 7 | Per peer Tx/Rx statistic can only be obtained by querying WM when WED is |
| 8 | on. This patch switches to periodic event reporting in the case of WED |
| 9 | being enabled. |
| 10 | --- |
| 11 | mt76_connac_mcu.h | 15 +++++++++++ |
| 12 | mt7996/mac.c | 5 ++++ |
| 13 | mt7996/main.c | 15 +++++++++++ |
| 14 | mt7996/mcu.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ |
| 15 | mt7996/mcu.h | 26 ++++++++++++++++++ |
| 16 | mt7996/mt7996.h | 1 + |
| 17 | 6 files changed, 130 insertions(+) |
| 18 | |
| 19 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| 20 | index 90c08d2..e9dd9aa 100644 |
| 21 | --- a/mt76_connac_mcu.h |
| 22 | +++ b/mt76_connac_mcu.h |
| 23 | @@ -1023,6 +1023,8 @@ enum { |
| 24 | MCU_UNI_EVENT_TX_DONE = 0x2d, |
| 25 | MCU_UNI_EVENT_THERMAL = 0x35, |
| 26 | MCU_UNI_EVENT_NIC_CAPAB = 0x43, |
| 27 | + MCU_UNI_EVENT_PER_STA_INFO = 0x6d, |
| 28 | + MCU_UNI_EVENT_ALL_STA_INFO = 0x6e, |
| 29 | }; |
| 30 | |
| 31 | #define MCU_UNI_CMD_EVENT BIT(1) |
| 32 | @@ -1242,6 +1244,8 @@ enum { |
| 33 | MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40, |
| 34 | MCU_UNI_CMD_RRO = 0x57, |
| 35 | MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58, |
| 36 | + MCU_UNI_CMD_PER_STA_INFO = 0x6d, |
| 37 | + MCU_UNI_CMD_ALL_STA_INFO = 0x6e, |
| 38 | MCU_UNI_CMD_ASSERT_DUMP = 0x6f, |
| 39 | }; |
| 40 | |
| 41 | @@ -1322,6 +1326,17 @@ enum { |
| 42 | UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT, |
| 43 | }; |
| 44 | |
| 45 | +enum UNI_ALL_STA_INFO_TAG { |
| 46 | + UNI_ALL_STA_TX_RATE, |
| 47 | + UNI_ALL_STA_TX_STAT, |
| 48 | + UNI_ALL_STA_TXRX_ADM_STAT, |
| 49 | + UNI_ALL_STA_TXRX_AIR_TIME, |
| 50 | + UNI_ALL_STA_DATA_TX_RETRY_COUNT, |
| 51 | + UNI_ALL_STA_GI_MODE, |
| 52 | + UNI_ALL_STA_TXRX_MSDU_COUNT, |
| 53 | + UNI_ALL_STA_MAX_NUM |
| 54 | +}; |
| 55 | + |
| 56 | enum { |
| 57 | MT_NIC_CAP_TX_RESOURCE, |
| 58 | MT_NIC_CAP_TX_EFUSE_ADDR, |
| 59 | diff --git a/mt7996/mac.c b/mt7996/mac.c |
| 60 | index bdc90a0..4828f10 100644 |
| 61 | --- a/mt7996/mac.c |
| 62 | +++ b/mt7996/mac.c |
| 63 | @@ -2272,6 +2272,11 @@ void mt7996_mac_work(struct work_struct *work) |
| 64 | mphy->mac_work_count = 0; |
| 65 | |
| 66 | mt7996_mac_update_stats(phy); |
| 67 | + |
| 68 | + if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) { |
| 69 | + mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT); |
| 70 | + mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT); |
| 71 | + }; |
| 72 | } |
| 73 | |
| 74 | mutex_unlock(&mphy->dev->mutex); |
| 75 | diff --git a/mt7996/main.c b/mt7996/main.c |
| 76 | index f152e76..e9e1fd9 100644 |
| 77 | --- a/mt7996/main.c |
| 78 | +++ b/mt7996/main.c |
| 79 | @@ -977,6 +977,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw, |
| 80 | struct ieee80211_sta *sta, |
| 81 | struct station_info *sinfo) |
| 82 | { |
| 83 | + struct mt7996_phy *phy = mt7996_hw_phy(hw); |
| 84 | struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; |
| 85 | struct rate_info *txrate = &msta->wcid.rate; |
| 86 | |
| 87 | @@ -1008,6 +1009,20 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw, |
| 88 | |
| 89 | sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal); |
| 90 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); |
| 91 | + |
| 92 | + if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) { |
| 93 | + sinfo->tx_bytes = msta->wcid.stats.tx_bytes; |
| 94 | + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); |
| 95 | + |
| 96 | + sinfo->rx_bytes = msta->wcid.stats.rx_bytes; |
| 97 | + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); |
| 98 | + |
| 99 | + sinfo->tx_packets = msta->wcid.stats.tx_packets; |
| 100 | + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); |
| 101 | + |
| 102 | + sinfo->rx_packets = msta->wcid.stats.rx_packets; |
| 103 | + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); |
| 104 | + } |
| 105 | } |
| 106 | |
| 107 | static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta) |
| 108 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| 109 | index 2c611e7..652a600 100644 |
| 110 | --- a/mt7996/mcu.c |
| 111 | +++ b/mt7996/mcu.c |
| 112 | @@ -477,6 +477,54 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb) |
| 113 | phy->throttle_state = n->duty_percent; |
| 114 | } |
| 115 | |
| 116 | +static void |
| 117 | +mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb) |
| 118 | +{ |
| 119 | + struct mt7996_mcu_all_sta_info_event *res; |
| 120 | + u16 i; |
| 121 | + |
| 122 | + skb_pull(skb, sizeof(struct mt7996_mcu_rxd)); |
| 123 | + |
| 124 | + res = (struct mt7996_mcu_all_sta_info_event *)skb->data; |
| 125 | + |
| 126 | + for (i = 0; i < le16_to_cpu(res->sta_num); i++) { |
| 127 | + u8 ac; |
| 128 | + u16 wlan_idx; |
| 129 | + struct mt76_wcid *wcid; |
| 130 | + |
| 131 | + switch (le16_to_cpu(res->tag)) { |
| 132 | + case UNI_ALL_STA_TXRX_ADM_STAT: |
| 133 | + wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx); |
| 134 | + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); |
| 135 | + |
| 136 | + if (!wcid) |
| 137 | + break; |
| 138 | + |
| 139 | + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 140 | + wcid->stats.tx_bytes += |
| 141 | + le32_to_cpu(res->adm_stat[i].tx_bytes[ac]); |
| 142 | + wcid->stats.rx_bytes += |
| 143 | + le32_to_cpu(res->adm_stat[i].rx_bytes[ac]); |
| 144 | + } |
| 145 | + break; |
| 146 | + case UNI_ALL_STA_TXRX_MSDU_COUNT: |
| 147 | + wlan_idx = le16_to_cpu(res->msdu_cnt[i].wlan_idx); |
| 148 | + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); |
| 149 | + |
| 150 | + if (!wcid) |
| 151 | + break; |
| 152 | + |
| 153 | + wcid->stats.tx_packets += |
| 154 | + le32_to_cpu(res->msdu_cnt[i].tx_msdu_cnt); |
| 155 | + wcid->stats.rx_packets += |
| 156 | + le32_to_cpu(res->msdu_cnt[i].rx_msdu_cnt); |
| 157 | + break; |
| 158 | + default: |
| 159 | + break; |
| 160 | + } |
| 161 | + } |
| 162 | +} |
| 163 | + |
| 164 | static void |
| 165 | mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb) |
| 166 | { |
| 167 | @@ -524,6 +572,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb) |
| 168 | case MCU_UNI_EVENT_THERMAL: |
| 169 | mt7996_mcu_rx_thermal_notify(dev, skb); |
| 170 | break; |
| 171 | + case MCU_UNI_EVENT_ALL_STA_INFO: |
| 172 | + mt7996_mcu_rx_all_sta_info_event(dev, skb); |
| 173 | + break; |
| 174 | default: |
| 175 | break; |
| 176 | } |
| 177 | @@ -4192,3 +4243,20 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val) |
| 178 | return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req, |
| 179 | sizeof(req), true); |
| 180 | } |
| 181 | + |
| 182 | +int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag) |
| 183 | +{ |
| 184 | + struct mt7996_dev *dev = phy->dev; |
| 185 | + struct { |
| 186 | + u8 _rsv[4]; |
| 187 | + |
| 188 | + __le16 tag; |
| 189 | + __le16 len; |
| 190 | + } __packed req = { |
| 191 | + .tag = cpu_to_le16(tag), |
| 192 | + .len = cpu_to_le16(sizeof(req) - 4), |
| 193 | + }; |
| 194 | + |
| 195 | + return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO), |
| 196 | + &req, sizeof(req), false); |
| 197 | +} |
| 198 | diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| 199 | index 05785cb..97151d1 100644 |
| 200 | --- a/mt7996/mcu.h |
| 201 | +++ b/mt7996/mcu.h |
| 202 | @@ -191,6 +191,32 @@ struct mt7996_mcu_thermal_notify { |
| 203 | u8 __rsv2[4]; |
| 204 | } __packed; |
| 205 | |
| 206 | +struct mt7996_mcu_all_sta_info_event { |
| 207 | + u8 rsv[4]; |
| 208 | + __le16 tag; |
| 209 | + __le16 len; |
| 210 | + u8 more; |
| 211 | + u8 rsv2; |
| 212 | + __le16 sta_num; |
| 213 | + u8 rsv3[2]; |
| 214 | + |
| 215 | + union { |
| 216 | + struct { |
| 217 | + __le16 wlan_idx; |
| 218 | + u8 rsv[2]; |
| 219 | + __le32 tx_bytes[IEEE80211_NUM_ACS]; |
| 220 | + __le32 rx_bytes[IEEE80211_NUM_ACS]; |
| 221 | + } adm_stat[0]; |
| 222 | + |
| 223 | + struct { |
| 224 | + __le16 wlan_idx; |
| 225 | + u8 rsv[2]; |
| 226 | + __le32 tx_msdu_cnt; |
| 227 | + __le32 rx_msdu_cnt; |
| 228 | + } msdu_cnt[0]; |
| 229 | + }; |
| 230 | +} __packed; |
| 231 | + |
| 232 | enum mt7996_chan_mib_offs { |
| 233 | UNI_MIB_OBSS_AIRTIME = 26, |
| 234 | UNI_MIB_NON_WIFI_TIME = 27, |
| 235 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| 236 | index 0bb20a9..420d113 100644 |
| 237 | --- a/mt7996/mt7996.h |
| 238 | +++ b/mt7996/mt7996.h |
| 239 | @@ -494,6 +494,7 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level); |
| 240 | int mt7996_mcu_trigger_assert(struct mt7996_dev *dev); |
| 241 | void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb); |
| 242 | void mt7996_mcu_exit(struct mt7996_dev *dev); |
| 243 | +int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag); |
| 244 | |
| 245 | static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev) |
| 246 | { |
| 247 | -- |
| 248 | 2.18.0 |
| 249 | |