developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 1 | From 5b0810ecadc01482ef25b7e063ebe69f42e39a8e Mon Sep 17 00:00:00 2001 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2 | From: Benjamin Lin <benjamin-jw.lin@mediatek.com> |
| 3 | Date: Fri, 17 Nov 2023 18:08:06 +0800 |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 4 | Subject: [PATCH 068/223] mtk: mt76: mt7996: get airtime and RSSI via MCU |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 5 | commands |
| 6 | |
| 7 | Direct access to WTBL for airtime and RSSI may cause synchronization issue with FW. |
| 8 | Moreover, frequent access to WTBL, whenever TX-Free-Done event is received, leads to heavy CPU overheads. |
| 9 | Therefore, indirect access to WTBL, through FW, with lower frequence is performed. |
| 10 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 11 | Change-Id: I978e7432603742fae9c753f055ff3087cf6b632c |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12 | Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com> |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 13 | Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com> |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 14 | --- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 15 | mt76.h | 18 +++++ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 16 | mt76_connac_mcu.h | 14 +++- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 17 | mt7996/debugfs.c | 17 +++-- |
| 18 | mt7996/mac.c | 145 +++++++------------------------------- |
| 19 | mt7996/mcu.c | 161 +++++++++++++++++++++++++++++++++++++++++-- |
| 20 | mt7996/mcu.h | 24 +++++++ |
| 21 | mt7996/mt7996.h | 26 +++++-- |
| 22 | mt7996/mtk_debugfs.c | 71 +++++++++++++++++++ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 23 | mt7996/regs.h | 2 + |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 24 | 9 files changed, 336 insertions(+), 142 deletions(-) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 25 | |
| 26 | diff --git a/mt76.h b/mt76.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 27 | index e7901e57..aad7f557 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 28 | --- a/mt76.h |
| 29 | +++ b/mt76.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 30 | @@ -336,11 +336,13 @@ struct mt76_sta_stats { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 31 | u32 tx_packets; /* unit: MSDU */ |
| 32 | u32 tx_retries; |
| 33 | u32 tx_failed; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 34 | + u64 tx_airtime; |
| 35 | /* WED RX */ |
| 36 | u64 rx_bytes; |
| 37 | u32 rx_packets; |
| 38 | u32 rx_errors; |
| 39 | u32 rx_drops; |
| 40 | + u64 rx_airtime; |
| 41 | }; |
| 42 | |
| 43 | enum mt76_wcid_flags { |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 44 | @@ -1339,6 +1341,22 @@ static inline int mt76_decr(int val, int size) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 45 | |
| 46 | u8 mt76_ac_to_hwq(u8 ac); |
| 47 | |
| 48 | +static inline u8 |
| 49 | +mt76_ac_to_tid(u8 ac) |
| 50 | +{ |
| 51 | + static const u8 ac_to_tid[] = { |
| 52 | + [IEEE80211_AC_BE] = 0, |
| 53 | + [IEEE80211_AC_BK] = 1, |
| 54 | + [IEEE80211_AC_VI] = 4, |
| 55 | + [IEEE80211_AC_VO] = 6 |
| 56 | + }; |
| 57 | + |
| 58 | + if (WARN_ON(ac >= IEEE80211_NUM_ACS)) |
| 59 | + return 0; |
| 60 | + |
| 61 | + return ac_to_tid[ac]; |
| 62 | +} |
| 63 | + |
| 64 | static inline struct ieee80211_txq * |
| 65 | mtxq_to_txq(struct mt76_txq *mtxq) |
| 66 | { |
| 67 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 68 | index db152167..adecb0ed 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 69 | --- a/mt76_connac_mcu.h |
| 70 | +++ b/mt76_connac_mcu.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 71 | @@ -1387,11 +1387,23 @@ enum { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 72 | UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT, |
| 73 | }; |
| 74 | |
| 75 | +enum UNI_PER_STA_INFO_TAG { |
| 76 | + UNI_PER_STA_RSSI, |
| 77 | + UNI_PER_STA_CONTENTION_RX_RATE, |
| 78 | + UNI_PER_STA_PER, |
| 79 | + UNI_PER_STA_SNR, |
| 80 | + UNI_PER_STA_TX_RATE, |
| 81 | + UNI_PER_STA_TX_CNT, |
| 82 | + UNI_PER_STA_TID_SN_GET, |
| 83 | + UNI_PER_STA_TID_SN_SET, |
| 84 | + UNI_PER_STA_MAX_NUM |
| 85 | +}; |
| 86 | + |
| 87 | enum UNI_ALL_STA_INFO_TAG { |
| 88 | UNI_ALL_STA_TXRX_RATE, |
| 89 | UNI_ALL_STA_TX_STAT, |
| 90 | UNI_ALL_STA_TXRX_ADM_STAT, |
| 91 | - UNI_ALL_STA_TXRX_AIR_TIME, |
| 92 | + UNI_ALL_STA_TXRX_AIRTIME, |
| 93 | UNI_ALL_STA_DATA_TX_RETRY_COUNT, |
| 94 | UNI_ALL_STA_GI_MODE, |
| 95 | UNI_ALL_STA_TXRX_MSDU_COUNT, |
| 96 | diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 97 | index 0ef8fee6..e46a0fb9 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 98 | --- a/mt7996/debugfs.c |
| 99 | +++ b/mt7996/debugfs.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 100 | @@ -979,12 +979,11 @@ mt7996_airtime_read(struct seq_file *s, void *data) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 101 | { |
| 102 | struct mt7996_dev *dev = dev_get_drvdata(s->private); |
| 103 | struct mt76_dev *mdev = &dev->mt76; |
| 104 | - struct mt7996_vow_sta_ctrl *vow; |
| 105 | + struct mt76_sta_stats *stats; |
| 106 | struct ieee80211_sta *sta; |
| 107 | struct mt7996_sta *msta; |
| 108 | struct mt76_wcid *wcid; |
| 109 | struct mt76_vif *vif; |
| 110 | - u64 airtime; |
| 111 | u16 i; |
| 112 | |
| 113 | seq_printf(s, "VoW Airtime Information:\n"); |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 114 | @@ -996,16 +995,16 @@ mt7996_airtime_read(struct seq_file *s, void *data) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 115 | |
| 116 | msta = container_of(wcid, struct mt7996_sta, wcid); |
| 117 | sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); |
| 118 | - vow = &msta->vow; |
| 119 | vif = &msta->vif->mt76; |
| 120 | + stats = &wcid->stats; |
| 121 | |
| 122 | - spin_lock_bh(&vow->lock); |
| 123 | - airtime = vow->tx_airtime; |
| 124 | - vow->tx_airtime = 0; |
| 125 | - spin_unlock_bh(&vow->lock); |
| 126 | + seq_printf(s, "%pM WCID: %hu BandIdx: %hhu OmacIdx: 0x%hhx\t" |
| 127 | + "TxAirtime: %llu\tRxAirtime: %llu\n", |
| 128 | + sta->addr, i, vif->band_idx, vif->omac_idx, |
| 129 | + stats->tx_airtime, stats->rx_airtime); |
| 130 | |
| 131 | - seq_printf(s, "%pM WCID: %hu BandIdx: %hhu OmacIdx: 0x%hhx\tTxAirtime: %llu\n", |
| 132 | - sta->addr, i, vif->band_idx, vif->omac_idx, airtime); |
| 133 | + stats->tx_airtime = 0; |
| 134 | + stats->rx_airtime = 0; |
| 135 | } |
| 136 | rcu_read_unlock(); |
| 137 | |
| 138 | diff --git a/mt7996/mac.c b/mt7996/mac.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 139 | index c72f70db..8b753148 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 140 | --- a/mt7996/mac.c |
| 141 | +++ b/mt7996/mac.c |
| 142 | @@ -12,8 +12,6 @@ |
| 143 | #include "mcu.h" |
| 144 | #include "vendor.h" |
| 145 | |
| 146 | -#define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2) |
| 147 | - |
| 148 | static const struct mt7996_dfs_radar_spec etsi_radar_specs = { |
| 149 | .pulse_th = { 110, -10, -80, 40, 5200, 128, 5200 }, |
| 150 | .radar_pattern = { |
| 151 | @@ -93,110 +91,6 @@ u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw) |
| 152 | return MT_WTBL_LMAC_OFFS(wcid, dw); |
| 153 | } |
| 154 | |
| 155 | -static void mt7996_mac_sta_poll(struct mt7996_dev *dev) |
| 156 | -{ |
| 157 | - static const u8 ac_to_tid[] = { |
| 158 | - [IEEE80211_AC_BE] = 0, |
| 159 | - [IEEE80211_AC_BK] = 1, |
| 160 | - [IEEE80211_AC_VI] = 4, |
| 161 | - [IEEE80211_AC_VO] = 6 |
| 162 | - }; |
| 163 | - struct ieee80211_sta *sta; |
| 164 | - struct mt7996_sta *msta; |
| 165 | - struct mt7996_vow_sta_ctrl *vow; |
| 166 | - u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS]; |
| 167 | - LIST_HEAD(sta_poll_list); |
| 168 | - int i; |
| 169 | - |
| 170 | - spin_lock_bh(&dev->mt76.sta_poll_lock); |
| 171 | - list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list); |
| 172 | - spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| 173 | - |
| 174 | - rcu_read_lock(); |
| 175 | - |
| 176 | - while (true) { |
| 177 | - bool clear = false; |
| 178 | - u32 addr, val; |
| 179 | - u16 idx; |
| 180 | - s8 rssi[4]; |
| 181 | - |
| 182 | - spin_lock_bh(&dev->mt76.sta_poll_lock); |
| 183 | - if (list_empty(&sta_poll_list)) { |
| 184 | - spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| 185 | - break; |
| 186 | - } |
| 187 | - msta = list_first_entry(&sta_poll_list, |
| 188 | - struct mt7996_sta, wcid.poll_list); |
| 189 | - list_del_init(&msta->wcid.poll_list); |
| 190 | - spin_unlock_bh(&dev->mt76.sta_poll_lock); |
| 191 | - |
| 192 | - idx = msta->wcid.idx; |
| 193 | - |
| 194 | - /* refresh peer's airtime reporting */ |
| 195 | - addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 20); |
| 196 | - |
| 197 | - for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 198 | - u32 tx_last = msta->airtime_ac[i]; |
| 199 | - u32 rx_last = msta->airtime_ac[i + 4]; |
| 200 | - |
| 201 | - msta->airtime_ac[i] = mt76_rr(dev, addr); |
| 202 | - msta->airtime_ac[i + 4] = mt76_rr(dev, addr + 4); |
| 203 | - |
| 204 | - tx_time[i] = msta->airtime_ac[i] - tx_last; |
| 205 | - rx_time[i] = msta->airtime_ac[i + 4] - rx_last; |
| 206 | - |
| 207 | - if ((tx_last | rx_last) & BIT(30)) |
| 208 | - clear = true; |
| 209 | - |
| 210 | - addr += 8; |
| 211 | - } |
| 212 | - |
| 213 | - if (clear) { |
| 214 | - mt7996_mac_wtbl_update(dev, idx, |
| 215 | - MT_WTBL_UPDATE_ADM_COUNT_CLEAR); |
| 216 | - memset(msta->airtime_ac, 0, sizeof(msta->airtime_ac)); |
| 217 | - } |
| 218 | - |
| 219 | - if (!msta->wcid.sta) |
| 220 | - continue; |
| 221 | - |
| 222 | - sta = container_of((void *)msta, struct ieee80211_sta, |
| 223 | - drv_priv); |
| 224 | - vow = &msta->vow; |
| 225 | - for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
| 226 | - u8 q = mt76_connac_lmac_mapping(i); |
| 227 | - u32 tx_cur = tx_time[q]; |
| 228 | - u32 rx_cur = rx_time[q]; |
| 229 | - u8 tid = ac_to_tid[i]; |
| 230 | - |
| 231 | - if (!tx_cur && !rx_cur) |
| 232 | - continue; |
| 233 | - |
| 234 | - ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur); |
| 235 | - |
| 236 | - spin_lock_bh(&vow->lock); |
| 237 | - vow->tx_airtime += tx_cur; |
| 238 | - spin_unlock_bh(&vow->lock); |
| 239 | - } |
| 240 | - |
| 241 | - /* get signal strength of resp frames (CTS/BA/ACK) */ |
| 242 | - addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34); |
| 243 | - val = mt76_rr(dev, addr); |
| 244 | - |
| 245 | - rssi[0] = to_rssi(GENMASK(7, 0), val); |
| 246 | - rssi[1] = to_rssi(GENMASK(15, 8), val); |
| 247 | - rssi[2] = to_rssi(GENMASK(23, 16), val); |
| 248 | - rssi[3] = to_rssi(GENMASK(31, 14), val); |
| 249 | - |
| 250 | - msta->ack_signal = |
| 251 | - mt76_rx_signal(msta->vif->phy->mt76->antenna_mask, rssi); |
| 252 | - |
| 253 | - ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal); |
| 254 | - } |
| 255 | - |
| 256 | - rcu_read_unlock(); |
| 257 | -} |
| 258 | - |
| 259 | void mt7996_mac_enable_rtscts(struct mt7996_dev *dev, |
| 260 | struct ieee80211_vif *vif, bool enable) |
| 261 | { |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 262 | @@ -1221,8 +1115,6 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 263 | } |
| 264 | } |
| 265 | |
| 266 | - mt7996_mac_sta_poll(dev); |
| 267 | - |
| 268 | if (wake) |
| 269 | mt76_set_tx_blocked(&dev->mt76, false); |
| 270 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 271 | @@ -2391,31 +2283,42 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 272 | |
| 273 | void mt7996_mac_work(struct work_struct *work) |
| 274 | { |
| 275 | - struct mt7996_phy *phy; |
| 276 | - struct mt76_phy *mphy; |
| 277 | - |
| 278 | - mphy = (struct mt76_phy *)container_of(work, struct mt76_phy, |
| 279 | - mac_work.work); |
| 280 | - phy = mphy->priv; |
| 281 | + struct mt76_phy *mphy = (struct mt76_phy *)container_of(work, struct mt76_phy, |
| 282 | + mac_work.work); |
| 283 | + struct mt7996_phy *phy = mphy->priv; |
| 284 | + struct mt76_dev *mdev = mphy->dev; |
| 285 | |
| 286 | - mutex_lock(&mphy->dev->mutex); |
| 287 | + mutex_lock(&mdev->mutex); |
| 288 | |
| 289 | mt76_update_survey(mphy); |
| 290 | if (++mphy->mac_work_count == 5) { |
| 291 | + int i; |
| 292 | + |
| 293 | mphy->mac_work_count = 0; |
| 294 | |
| 295 | mt7996_mac_update_stats(phy); |
| 296 | |
| 297 | - mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE); |
| 298 | - if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) { |
| 299 | - mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT); |
| 300 | - mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT); |
| 301 | + /* Update DEV-wise information only in |
| 302 | + * the MAC work of the first band running. |
| 303 | + */ |
| 304 | + for (i = MT_BAND0; i <= mphy->band_idx; ++i) { |
| 305 | + if (i == mphy->band_idx) { |
| 306 | + mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_RATE); |
| 307 | + mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_AIRTIME); |
| 308 | + mt7996_mcu_get_rssi(mdev); |
| 309 | + if (mtk_wed_device_active(&mdev->mmio.wed)) { |
| 310 | + mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_ADM_STAT); |
| 311 | + mt7996_mcu_get_all_sta_info(mdev, UNI_ALL_STA_TXRX_MSDU_COUNT); |
| 312 | + } |
| 313 | + } else if (mt7996_band_valid(phy->dev, i) && |
| 314 | + test_bit(MT76_STATE_RUNNING, &mdev->phys[i]->state)) |
| 315 | + break; |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | - mutex_unlock(&mphy->dev->mutex); |
| 320 | + mutex_unlock(&mdev->mutex); |
| 321 | |
| 322 | - mt76_tx_status_check(mphy->dev, false); |
| 323 | + mt76_tx_status_check(mdev, false); |
| 324 | |
| 325 | ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, |
| 326 | MT7996_WATCHDOG_TIME); |
| 327 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 328 | index be273181..db877d75 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 329 | --- a/mt7996/mcu.c |
| 330 | +++ b/mt7996/mcu.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 331 | @@ -568,7 +568,8 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 332 | u16 wlan_idx; |
| 333 | struct mt76_wcid *wcid; |
| 334 | struct mt76_phy *mphy; |
| 335 | - u32 tx_bytes, rx_bytes, tx_packets, rx_packets; |
| 336 | + struct ieee80211_sta *sta; |
| 337 | + u32 tx_bytes, rx_bytes, tx_airtime, rx_airtime, tx_packets, rx_packets; |
| 338 | |
| 339 | switch (le16_to_cpu(res->tag)) { |
| 340 | case UNI_ALL_STA_TXRX_RATE: |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 341 | @@ -589,7 +590,7 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 342 | break; |
| 343 | |
| 344 | mphy = mt76_dev_phy(&dev->mt76, wcid->phy_idx); |
| 345 | - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 346 | + for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) { |
| 347 | tx_bytes = le32_to_cpu(res->adm_stat[i].tx_bytes[ac]); |
| 348 | rx_bytes = le32_to_cpu(res->adm_stat[i].rx_bytes[ac]); |
| 349 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 350 | @@ -621,6 +622,24 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 351 | __mt7996_stat_to_netdev(mphy, wcid, 0, 0, |
| 352 | tx_packets, rx_packets); |
| 353 | break; |
| 354 | + case UNI_ALL_STA_TXRX_AIRTIME: |
| 355 | + wlan_idx = le16_to_cpu(res->airtime[i].wlan_idx); |
| 356 | + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); |
| 357 | + sta = wcid_to_sta(wcid); |
| 358 | + if (!sta) |
| 359 | + continue; |
| 360 | + |
| 361 | + for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ++ac) { |
| 362 | + u8 lmac_ac = mt76_connac_lmac_mapping(ac); |
| 363 | + tx_airtime = le32_to_cpu(res->airtime[i].tx[lmac_ac]); |
| 364 | + rx_airtime = le32_to_cpu(res->airtime[i].rx[lmac_ac]); |
| 365 | + |
| 366 | + wcid->stats.tx_airtime += tx_airtime; |
| 367 | + wcid->stats.rx_airtime += rx_airtime; |
| 368 | + ieee80211_sta_register_airtime(sta, mt76_ac_to_tid(ac), |
| 369 | + tx_airtime, rx_airtime); |
| 370 | + } |
| 371 | + break; |
| 372 | default: |
| 373 | break; |
| 374 | } |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 375 | @@ -2249,8 +2268,6 @@ mt7996_mcu_sta_init_vow(struct mt7996_phy *phy, struct mt7996_sta *msta) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 376 | vow->drr_quantum[IEEE80211_AC_VI] = VOW_DRR_QUANTUM_IDX1; |
| 377 | vow->drr_quantum[IEEE80211_AC_BE] = VOW_DRR_QUANTUM_IDX2; |
| 378 | vow->drr_quantum[IEEE80211_AC_BK] = VOW_DRR_QUANTUM_IDX2; |
| 379 | - vow->tx_airtime = 0; |
| 380 | - spin_lock_init(&vow->lock); |
| 381 | |
| 382 | ret = mt7996_mcu_set_vow_drr_ctrl(phy, msta, VOW_DRR_CTRL_STA_BSS_GROUP); |
| 383 | if (ret) |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 384 | @@ -4868,9 +4885,139 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 385 | sizeof(req), true); |
| 386 | } |
| 387 | |
| 388 | -int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag) |
| 389 | +int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag, |
| 390 | + u16 sta_num, u16 *sta_list) |
| 391 | +{ |
| 392 | +#define PER_STA_INFO_MAX_NUM 90 |
| 393 | + struct mt7996_mcu_per_sta_info_event *res; |
| 394 | + struct mt76_wcid *wcid; |
| 395 | + struct sk_buff *skb; |
| 396 | + u16 wlan_idx; |
| 397 | + int i, ret; |
| 398 | + struct { |
| 399 | + u8 __rsv1; |
| 400 | + u8 unsolicit; |
| 401 | + u8 __rsv2[2]; |
| 402 | + |
| 403 | + __le16 tag; |
| 404 | + __le16 len; |
| 405 | + __le16 sta_num; |
| 406 | + u8 __rsv3[2]; |
| 407 | + __le16 sta_list[PER_STA_INFO_MAX_NUM]; |
| 408 | + } __packed req = { |
| 409 | + .unsolicit = 0, |
| 410 | + .tag = cpu_to_le16(tag), |
| 411 | + .len = cpu_to_le16(sizeof(req) - 4), |
| 412 | + .sta_num = cpu_to_le16(sta_num) |
| 413 | + }; |
| 414 | + |
| 415 | + if (sta_num > PER_STA_INFO_MAX_NUM) |
| 416 | + return -EINVAL; |
| 417 | + |
| 418 | + for (i = 0; i < sta_num; ++i) |
| 419 | + req.sta_list[i] = cpu_to_le16(sta_list[i]); |
| 420 | + |
| 421 | + ret = mt76_mcu_send_and_get_msg(dev, MCU_WM_UNI_CMD(PER_STA_INFO), |
| 422 | + &req, sizeof(req), true, &skb); |
| 423 | + if (ret) |
| 424 | + return ret; |
| 425 | + |
| 426 | + res = (struct mt7996_mcu_per_sta_info_event *)skb->data; |
| 427 | + if (le16_to_cpu(res->tag) != tag) { |
| 428 | + ret = -EINVAL; |
| 429 | + goto out; |
| 430 | + } |
| 431 | + |
| 432 | + rcu_read_lock(); |
| 433 | + switch (tag) { |
| 434 | + case UNI_PER_STA_RSSI: |
| 435 | + for (i = 0; i < sta_num; ++i) { |
| 436 | + struct mt7996_sta *msta; |
| 437 | + struct mt76_phy *phy; |
| 438 | + s8 rssi[4]; |
| 439 | + u8 *rcpi; |
| 440 | + |
| 441 | + wlan_idx = le16_to_cpu(res->rssi[i].wlan_idx); |
| 442 | + wcid = rcu_dereference(dev->wcid[wlan_idx]); |
| 443 | + if (wcid) { |
| 444 | + rcpi = res->rssi[i].rcpi; |
| 445 | + rssi[0] = to_rssi(MT_PRXV_RCPI0, rcpi[0]); |
| 446 | + rssi[1] = to_rssi(MT_PRXV_RCPI0, rcpi[1]); |
| 447 | + rssi[2] = to_rssi(MT_PRXV_RCPI0, rcpi[2]); |
| 448 | + rssi[3] = to_rssi(MT_PRXV_RCPI0, rcpi[3]); |
| 449 | + |
| 450 | + msta = container_of(wcid, struct mt7996_sta, wcid); |
| 451 | + phy = msta->vif->phy->mt76; |
| 452 | + msta->ack_signal = mt76_rx_signal(phy->antenna_mask, rssi); |
| 453 | + ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal); |
| 454 | + } else { |
| 455 | + ret = -EINVAL; |
| 456 | + dev_err(dev->dev, "Failed to update RSSI for " |
| 457 | + "invalid WCID: %hu\n", wlan_idx); |
| 458 | + } |
| 459 | + } |
| 460 | + break; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 461 | + default: |
| 462 | + ret = -EINVAL; |
| 463 | + dev_err(dev->dev, "Unknown UNI_PER_STA_INFO_TAG: %d\n", tag); |
| 464 | + } |
| 465 | + rcu_read_unlock(); |
| 466 | +out: |
| 467 | + dev_kfree_skb(skb); |
| 468 | + return ret; |
| 469 | +} |
| 470 | + |
| 471 | +int mt7996_mcu_get_rssi(struct mt76_dev *dev) |
| 472 | +{ |
| 473 | + u16 sta_list[PER_STA_INFO_MAX_NUM]; |
| 474 | + LIST_HEAD(sta_poll_list); |
| 475 | + struct mt7996_sta *msta; |
| 476 | + int i, ret; |
| 477 | + bool empty = false; |
| 478 | + |
| 479 | + spin_lock_bh(&dev->sta_poll_lock); |
| 480 | + list_splice_init(&dev->sta_poll_list, &sta_poll_list); |
| 481 | + spin_unlock_bh(&dev->sta_poll_lock); |
| 482 | + |
| 483 | + while (!empty) { |
| 484 | + for (i = 0; i < PER_STA_INFO_MAX_NUM; ++i) { |
| 485 | + spin_lock_bh(&dev->sta_poll_lock); |
| 486 | + if (list_empty(&sta_poll_list)) { |
| 487 | + spin_unlock_bh(&dev->sta_poll_lock); |
| 488 | + |
| 489 | + if (i == 0) |
| 490 | + return 0; |
| 491 | + |
| 492 | + empty = true; |
| 493 | + break; |
| 494 | + } |
| 495 | + msta = list_first_entry(&sta_poll_list, |
| 496 | + struct mt7996_sta, |
| 497 | + wcid.poll_list); |
| 498 | + list_del_init(&msta->wcid.poll_list); |
| 499 | + spin_unlock_bh(&dev->sta_poll_lock); |
| 500 | + |
| 501 | + sta_list[i] = msta->wcid.idx; |
| 502 | + } |
| 503 | + |
| 504 | + ret = mt7996_mcu_get_per_sta_info(dev, UNI_PER_STA_RSSI, |
| 505 | + i, sta_list); |
| 506 | + if (ret) { |
| 507 | + /* Add STAs, whose RSSI has not been updated, |
| 508 | + * back to polling list. |
| 509 | + */ |
| 510 | + spin_lock_bh(&dev->sta_poll_lock); |
| 511 | + list_splice(&sta_poll_list, &dev->sta_poll_list); |
| 512 | + spin_unlock_bh(&dev->sta_poll_lock); |
| 513 | + break; |
| 514 | + } |
| 515 | + } |
| 516 | + |
| 517 | + return ret; |
| 518 | +} |
| 519 | + |
| 520 | +int mt7996_mcu_get_all_sta_info(struct mt76_dev *dev, u16 tag) |
| 521 | { |
| 522 | - struct mt7996_dev *dev = phy->dev; |
| 523 | struct { |
| 524 | u8 _rsv[4]; |
| 525 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 526 | @@ -4881,7 +5028,7 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 527 | .len = cpu_to_le16(sizeof(req) - 4), |
| 528 | }; |
| 529 | |
| 530 | - return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO), |
| 531 | + return mt76_mcu_send_msg(dev, MCU_WM_UNI_CMD(ALL_STA_INFO), |
| 532 | &req, sizeof(req), false); |
| 533 | } |
| 534 | |
| 535 | diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 536 | index 19572d85..5aa55e4f 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 537 | --- a/mt7996/mcu.h |
| 538 | +++ b/mt7996/mcu.h |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 539 | @@ -199,6 +199,23 @@ struct mt7996_mcu_mib { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 540 | __le64 data; |
| 541 | } __packed; |
| 542 | |
| 543 | +struct per_sta_rssi { |
| 544 | + __le16 wlan_idx; |
| 545 | + u8 __rsv[2]; |
| 546 | + u8 rcpi[4]; |
| 547 | +} __packed; |
| 548 | + |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 549 | +struct mt7996_mcu_per_sta_info_event { |
| 550 | + u8 __rsv[4]; |
| 551 | + |
| 552 | + __le16 tag; |
| 553 | + __le16 len; |
| 554 | + |
| 555 | + union { |
| 556 | + struct per_sta_rssi rssi[0]; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 557 | + }; |
| 558 | +} __packed; |
| 559 | + |
| 560 | struct all_sta_trx_rate { |
| 561 | __le16 wlan_idx; |
| 562 | u8 __rsv1[2]; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 563 | @@ -244,6 +261,13 @@ struct mt7996_mcu_all_sta_info_event { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 564 | __le32 tx_msdu_cnt; |
| 565 | __le32 rx_msdu_cnt; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 566 | } __packed, msdu_cnt); |
| 567 | + |
| 568 | + DECLARE_FLEX_ARRAY(struct { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 569 | + __le16 wlan_idx; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 570 | + u8 rsv[2]; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 571 | + __le32 tx[IEEE80211_NUM_ACS]; |
| 572 | + __le32 rx[IEEE80211_NUM_ACS]; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 573 | + } __packed, airtime); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 574 | } __packed; |
| 575 | } __packed; |
| 576 | |
| 577 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 578 | index 7d0f7dda..f6d3bd19 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 579 | --- a/mt7996/mt7996.h |
| 580 | +++ b/mt7996/mt7996.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 581 | @@ -128,6 +128,8 @@ |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 582 | #define MT7996_RRO_MSDU_PG_CR_CNT 8 |
| 583 | #define MT7996_RRO_MSDU_PG_SIZE_PER_CR 0x10000 |
| 584 | |
| 585 | +#define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2) |
| 586 | + |
| 587 | struct mt7996_vif; |
| 588 | struct mt7996_sta; |
| 589 | struct mt7996_dfs_pulse; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 590 | @@ -299,8 +301,6 @@ struct mt7996_vow_sta_ctrl { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 591 | bool paused; |
| 592 | u8 bss_grp_idx; |
| 593 | u8 drr_quantum[IEEE80211_NUM_ACS]; |
| 594 | - u64 tx_airtime; |
| 595 | - spinlock_t lock; |
| 596 | }; |
| 597 | |
| 598 | struct mt7996_sta { |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 599 | @@ -309,7 +309,6 @@ struct mt7996_sta { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 600 | struct mt7996_vif *vif; |
| 601 | |
| 602 | struct list_head rc_list; |
| 603 | - u32 airtime_ac[8]; |
| 604 | |
| 605 | int ack_signal; |
| 606 | struct ewma_avg_signal avg_ack_signal; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 607 | @@ -406,6 +405,21 @@ struct mt7996_air_monitor_ctrl { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 608 | }; |
| 609 | #endif |
| 610 | |
| 611 | +struct mt7996_rro_ba_session { |
| 612 | + u32 ack_sn :12; |
| 613 | + u32 win_sz :3; |
| 614 | + u32 bn :1; |
| 615 | + u32 last_in_sn :12; |
| 616 | + u32 bc :1; |
| 617 | + u32 bd :1; |
| 618 | + u32 sat :1; |
| 619 | + u32 cn :1; |
| 620 | + u32 within_cnt :12; |
| 621 | + u32 to_sel :3; |
| 622 | + u32 rsv :1; |
| 623 | + u32 last_in_rxtime :12; |
| 624 | +}; |
| 625 | + |
| 626 | struct mt7996_phy { |
| 627 | struct mt76_phy *mt76; |
| 628 | struct mt7996_dev *dev; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 629 | @@ -605,6 +619,7 @@ struct mt7996_dev { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 630 | u32 fw_dbg_module; |
| 631 | u8 fw_dbg_lv; |
| 632 | u32 bcn_total_cnt[__MT_MAX_BAND]; |
| 633 | + u32 sid; |
| 634 | } dbg; |
| 635 | const struct mt7996_dbg_reg_desc *dbg_reg; |
| 636 | #endif |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 637 | @@ -829,7 +844,10 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 638 | int mt7996_mcu_trigger_assert(struct mt7996_dev *dev); |
| 639 | void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb); |
| 640 | void mt7996_mcu_exit(struct mt7996_dev *dev); |
| 641 | -int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag); |
| 642 | +int mt7996_mcu_get_per_sta_info(struct mt76_dev *dev, u16 tag, |
| 643 | + u16 sta_num, u16 *sta_list); |
| 644 | +int mt7996_mcu_get_rssi(struct mt76_dev *dev); |
| 645 | +int mt7996_mcu_get_all_sta_info(struct mt76_dev *dev, u16 tag); |
| 646 | int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id); |
| 647 | int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data); |
| 648 | int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event); |
| 649 | diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 650 | index 5a140f51..4ce4ac0d 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 651 | --- a/mt7996/mtk_debugfs.c |
| 652 | +++ b/mt7996/mtk_debugfs.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 653 | @@ -3064,6 +3064,69 @@ mt7996_vow_drr_dbg(void *data, u64 val) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 654 | DEFINE_DEBUGFS_ATTRIBUTE(fops_vow_drr_dbg, NULL, |
| 655 | mt7996_vow_drr_dbg, "%lld\n"); |
| 656 | |
| 657 | +static int |
| 658 | +mt7996_rro_session_read(struct seq_file *s, void *data) |
| 659 | +{ |
| 660 | + struct mt7996_dev *dev = dev_get_drvdata(s->private); |
| 661 | + struct mt7996_rro_ba_session *tbl; |
| 662 | + u32 value[2]; |
| 663 | + |
| 664 | + mt76_wr(dev, MT_RRO_DBG_RD_CTRL, MT_RRO_DBG_RD_EXEC + |
| 665 | + (dev->dbg.sid >> 1) + 0x200); |
| 666 | + |
| 667 | + if (dev->dbg.sid & 0x1) { |
| 668 | + value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(2)); |
| 669 | + value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(3)); |
| 670 | + } else { |
| 671 | + value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(0)); |
| 672 | + value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(1)); |
| 673 | + } |
| 674 | + |
| 675 | + tbl = (struct mt7996_rro_ba_session *)&value[0]; |
| 676 | + |
| 677 | + seq_printf(s, " seid %d:\nba session table DW0:%08x DW2:%08x\n", |
| 678 | + dev->dbg.sid, value[0], value[1]); |
| 679 | + |
| 680 | + seq_printf(s, "ack_sn = 0x%x, last_in_sn = 0x%x, sat/bn/bc/bd/cn = %d/%d/%d/%d/%d\n", |
| 681 | + tbl->ack_sn, tbl->last_in_sn, tbl->sat, tbl->bn, tbl->bc, tbl->bd, tbl->cn); |
| 682 | + |
| 683 | + seq_printf(s, "within_cnt = %d, to_sel = %d, last_in_rxtime = %d\n", |
| 684 | + tbl->within_cnt, tbl->to_sel, tbl->last_in_rxtime); |
| 685 | + |
| 686 | + return 0; |
| 687 | +} |
| 688 | + |
| 689 | +static int |
| 690 | +mt7996_show_rro_mib(struct seq_file *s, void *data) |
| 691 | +{ |
| 692 | + struct mt7996_dev *dev = dev_get_drvdata(s->private); |
| 693 | + u32 reg[12]; |
| 694 | + |
| 695 | + seq_printf(s, "RRO mib Info:\n"); |
| 696 | + |
| 697 | + reg[0] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(0)); |
| 698 | + reg[1] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(1)); |
| 699 | + reg[2] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(2)); |
| 700 | + reg[3] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(3)); |
| 701 | + reg[4] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(4)); |
| 702 | + reg[5] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(5)); |
| 703 | + reg[6] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(6)); |
| 704 | + reg[7] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(7)); |
| 705 | + reg[8] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(8)); |
| 706 | + reg[9] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(9)); |
| 707 | + reg[10] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(10)); |
| 708 | + reg[11] = mt76_rr(dev, WF_RRO_TOP_STATISTIC(11)); |
| 709 | + |
| 710 | + seq_printf(s, "STEP_ONE/WITHIN/SURPASS = %x/%x/%x\n", reg[0], reg[3], reg[4]); |
| 711 | + seq_printf(s, "REPEAT/OLDPKT/BAR = %x/%x/%x\n", reg[1], reg[2], reg[5]); |
| 712 | + seq_printf(s, "SURPASS with big gap = %x\n", reg[6]); |
| 713 | + seq_printf(s, "DISCONNECT/INVALID = %x/%x\n", reg[7], reg[8]); |
| 714 | + seq_printf(s, "TO(Step one)/TO(flush all) = %x/%x\n", reg[9], reg[10]); |
| 715 | + seq_printf(s, "buf ran out = %x\n", reg[11]); |
| 716 | + |
| 717 | + return 0; |
| 718 | +} |
| 719 | + |
| 720 | int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir) |
| 721 | { |
| 722 | struct mt7996_dev *dev = phy->dev; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 723 | @@ -3162,6 +3225,14 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 724 | |
| 725 | debugfs_create_file("muru_prot_thr", 0200, dir, phy, &fops_muru_prot_thr); |
| 726 | |
| 727 | + if (dev->has_rro) { |
| 728 | + debugfs_create_u32("rro_sid", 0600, dir, &dev->dbg.sid); |
| 729 | + debugfs_create_devm_seqfile(dev->mt76.dev, "rro_sid_info", dir, |
| 730 | + mt7996_rro_session_read); |
| 731 | + debugfs_create_devm_seqfile(dev->mt76.dev, "rro_mib", dir, |
| 732 | + mt7996_show_rro_mib); |
| 733 | + } |
| 734 | + |
| 735 | return 0; |
| 736 | } |
| 737 | |
| 738 | diff --git a/mt7996/regs.h b/mt7996/regs.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 739 | index 87bf0012..96438cca 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 740 | --- a/mt7996/regs.h |
| 741 | +++ b/mt7996/regs.h |
| 742 | @@ -122,6 +122,8 @@ enum offs_rev { |
| 743 | #define MT_MCU_INT_EVENT_DMA_INIT BIT(1) |
| 744 | #define MT_MCU_INT_EVENT_RESET_DONE BIT(3) |
| 745 | |
| 746 | +#define WF_RRO_TOP_STATISTIC(_n) MT_RRO_TOP(0x180 + _n * 0x4) |
| 747 | + |
| 748 | /* PLE */ |
| 749 | #define MT_PLE_BASE 0x820c0000 |
| 750 | #define MT_PLE(ofs) (MT_PLE_BASE + (ofs)) |
| 751 | -- |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 752 | 2.45.2 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 753 | |