1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 5 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 6 */ 7 8 #include <linux/vmalloc.h> 9 10 #include "debugfs_sta.h" 11 #include "core.h" 12 #include "peer.h" 13 #include "debug.h" 14 #include "dp_tx.h" 15 #include "debugfs_htt_stats.h" 16 17 void ath11k_debugfs_sta_add_tx_stats(struct ath11k_sta *arsta, 18 struct ath11k_per_peer_tx_stats *peer_stats, 19 u8 legacy_rate_idx) 20 { 21 struct rate_info *txrate = &arsta->txrate; 22 struct ath11k_htt_tx_stats *tx_stats; 23 int gi, mcs, bw, nss; 24 25 if (!arsta->tx_stats) 26 return; 27 28 tx_stats = arsta->tx_stats; 29 gi = FIELD_GET(RATE_INFO_FLAGS_SHORT_GI, arsta->txrate.flags); 30 mcs = txrate->mcs; 31 bw = ath11k_mac_mac80211_bw_to_ath11k_bw(txrate->bw); 32 nss = txrate->nss - 1; 33 34 #define STATS_OP_FMT(name) tx_stats->stats[ATH11K_STATS_TYPE_##name] 35 36 if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) { 37 STATS_OP_FMT(SUCC).he[0][mcs] += peer_stats->succ_bytes; 38 STATS_OP_FMT(SUCC).he[1][mcs] += peer_stats->succ_pkts; 39 STATS_OP_FMT(FAIL).he[0][mcs] += peer_stats->failed_bytes; 40 STATS_OP_FMT(FAIL).he[1][mcs] += peer_stats->failed_pkts; 41 STATS_OP_FMT(RETRY).he[0][mcs] += peer_stats->retry_bytes; 42 STATS_OP_FMT(RETRY).he[1][mcs] += peer_stats->retry_pkts; 43 } else if (txrate->flags & RATE_INFO_FLAGS_VHT_MCS) { 44 STATS_OP_FMT(SUCC).vht[0][mcs] += peer_stats->succ_bytes; 45 STATS_OP_FMT(SUCC).vht[1][mcs] += peer_stats->succ_pkts; 46 STATS_OP_FMT(FAIL).vht[0][mcs] += peer_stats->failed_bytes; 47 STATS_OP_FMT(FAIL).vht[1][mcs] += peer_stats->failed_pkts; 48 STATS_OP_FMT(RETRY).vht[0][mcs] += peer_stats->retry_bytes; 49 STATS_OP_FMT(RETRY).vht[1][mcs] += peer_stats->retry_pkts; 50 } else if (txrate->flags & RATE_INFO_FLAGS_MCS) { 51 STATS_OP_FMT(SUCC).ht[0][mcs] += peer_stats->succ_bytes; 52 STATS_OP_FMT(SUCC).ht[1][mcs] += peer_stats->succ_pkts; 53 STATS_OP_FMT(FAIL).ht[0][mcs] += peer_stats->failed_bytes; 54 STATS_OP_FMT(FAIL).ht[1][mcs] += peer_stats->failed_pkts; 55 STATS_OP_FMT(RETRY).ht[0][mcs] += peer_stats->retry_bytes; 56 STATS_OP_FMT(RETRY).ht[1][mcs] += peer_stats->retry_pkts; 57 } else { 58 mcs = legacy_rate_idx; 59 60 STATS_OP_FMT(SUCC).legacy[0][mcs] += peer_stats->succ_bytes; 61 STATS_OP_FMT(SUCC).legacy[1][mcs] += peer_stats->succ_pkts; 62 STATS_OP_FMT(FAIL).legacy[0][mcs] += peer_stats->failed_bytes; 63 STATS_OP_FMT(FAIL).legacy[1][mcs] += peer_stats->failed_pkts; 64 STATS_OP_FMT(RETRY).legacy[0][mcs] += peer_stats->retry_bytes; 65 STATS_OP_FMT(RETRY).legacy[1][mcs] += peer_stats->retry_pkts; 66 } 67 68 if (peer_stats->is_ampdu) { 69 tx_stats->ba_fails += peer_stats->ba_fails; 70 71 if (txrate->flags & RATE_INFO_FLAGS_HE_MCS) { 72 STATS_OP_FMT(AMPDU).he[0][mcs] += 73 peer_stats->succ_bytes + peer_stats->retry_bytes; 74 STATS_OP_FMT(AMPDU).he[1][mcs] += 75 peer_stats->succ_pkts + peer_stats->retry_pkts; 76 } else if (txrate->flags & RATE_INFO_FLAGS_MCS) { 77 STATS_OP_FMT(AMPDU).ht[0][mcs] += 78 peer_stats->succ_bytes + peer_stats->retry_bytes; 79 STATS_OP_FMT(AMPDU).ht[1][mcs] += 80 peer_stats->succ_pkts + peer_stats->retry_pkts; 81 } else { 82 STATS_OP_FMT(AMPDU).vht[0][mcs] += 83 peer_stats->succ_bytes + peer_stats->retry_bytes; 84 STATS_OP_FMT(AMPDU).vht[1][mcs] += 85 peer_stats->succ_pkts + peer_stats->retry_pkts; 86 } 87 STATS_OP_FMT(AMPDU).bw[0][bw] += 88 peer_stats->succ_bytes + peer_stats->retry_bytes; 89 STATS_OP_FMT(AMPDU).nss[0][nss] += 90 peer_stats->succ_bytes + peer_stats->retry_bytes; 91 STATS_OP_FMT(AMPDU).gi[0][gi] += 92 peer_stats->succ_bytes + peer_stats->retry_bytes; 93 STATS_OP_FMT(AMPDU).bw[1][bw] += 94 peer_stats->succ_pkts + peer_stats->retry_pkts; 95 STATS_OP_FMT(AMPDU).nss[1][nss] += 96 peer_stats->succ_pkts + peer_stats->retry_pkts; 97 STATS_OP_FMT(AMPDU).gi[1][gi] += 98 peer_stats->succ_pkts + peer_stats->retry_pkts; 99 } else { 100 tx_stats->ack_fails += peer_stats->ba_fails; 101 } 102 103 STATS_OP_FMT(SUCC).bw[0][bw] += peer_stats->succ_bytes; 104 STATS_OP_FMT(SUCC).nss[0][nss] += peer_stats->succ_bytes; 105 STATS_OP_FMT(SUCC).gi[0][gi] += peer_stats->succ_bytes; 106 107 STATS_OP_FMT(SUCC).bw[1][bw] += peer_stats->succ_pkts; 108 STATS_OP_FMT(SUCC).nss[1][nss] += peer_stats->succ_pkts; 109 STATS_OP_FMT(SUCC).gi[1][gi] += peer_stats->succ_pkts; 110 111 STATS_OP_FMT(FAIL).bw[0][bw] += peer_stats->failed_bytes; 112 STATS_OP_FMT(FAIL).nss[0][nss] += peer_stats->failed_bytes; 113 STATS_OP_FMT(FAIL).gi[0][gi] += peer_stats->failed_bytes; 114 115 STATS_OP_FMT(FAIL).bw[1][bw] += peer_stats->failed_pkts; 116 STATS_OP_FMT(FAIL).nss[1][nss] += peer_stats->failed_pkts; 117 STATS_OP_FMT(FAIL).gi[1][gi] += peer_stats->failed_pkts; 118 119 STATS_OP_FMT(RETRY).bw[0][bw] += peer_stats->retry_bytes; 120 STATS_OP_FMT(RETRY).nss[0][nss] += peer_stats->retry_bytes; 121 STATS_OP_FMT(RETRY).gi[0][gi] += peer_stats->retry_bytes; 122 123 STATS_OP_FMT(RETRY).bw[1][bw] += peer_stats->retry_pkts; 124 STATS_OP_FMT(RETRY).nss[1][nss] += peer_stats->retry_pkts; 125 STATS_OP_FMT(RETRY).gi[1][gi] += peer_stats->retry_pkts; 126 127 tx_stats->tx_duration += peer_stats->duration; 128 } 129 130 void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar, 131 struct hal_tx_status *ts) 132 { 133 ath11k_dp_tx_update_txcompl(ar, ts); 134 } 135 136 static ssize_t ath11k_dbg_sta_dump_tx_stats(struct file *file, 137 char __user *user_buf, 138 size_t count, loff_t *ppos) 139 { 140 struct ieee80211_sta *sta = file->private_data; 141 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 142 struct ath11k *ar = arsta->arvif->ar; 143 struct ath11k_htt_data_stats *stats; 144 static const char *str_name[ATH11K_STATS_TYPE_MAX] = {"succ", "fail", 145 "retry", "ampdu"}; 146 static const char *str[ATH11K_COUNTER_TYPE_MAX] = {"bytes", "packets"}; 147 int len = 0, i, j, k, retval = 0; 148 const int size = 2 * 4096; 149 char *buf; 150 151 if (!arsta->tx_stats) 152 return -ENOENT; 153 154 buf = kzalloc(size, GFP_KERNEL); 155 if (!buf) 156 return -ENOMEM; 157 158 mutex_lock(&ar->conf_mutex); 159 160 spin_lock_bh(&ar->data_lock); 161 for (k = 0; k < ATH11K_STATS_TYPE_MAX; k++) { 162 for (j = 0; j < ATH11K_COUNTER_TYPE_MAX; j++) { 163 stats = &arsta->tx_stats->stats[k]; 164 len += scnprintf(buf + len, size - len, "%s_%s\n", 165 str_name[k], 166 str[j]); 167 len += scnprintf(buf + len, size - len, 168 " HE MCS %s\n", 169 str[j]); 170 for (i = 0; i < ATH11K_HE_MCS_NUM; i++) 171 len += scnprintf(buf + len, size - len, 172 " %llu ", 173 stats->he[j][i]); 174 len += scnprintf(buf + len, size - len, "\n"); 175 len += scnprintf(buf + len, size - len, 176 " VHT MCS %s\n", 177 str[j]); 178 for (i = 0; i < ATH11K_VHT_MCS_NUM; i++) 179 len += scnprintf(buf + len, size - len, 180 " %llu ", 181 stats->vht[j][i]); 182 len += scnprintf(buf + len, size - len, "\n"); 183 len += scnprintf(buf + len, size - len, " HT MCS %s\n", 184 str[j]); 185 for (i = 0; i < ATH11K_HT_MCS_NUM; i++) 186 len += scnprintf(buf + len, size - len, 187 " %llu ", stats->ht[j][i]); 188 len += scnprintf(buf + len, size - len, "\n"); 189 len += scnprintf(buf + len, size - len, 190 " BW %s (20,40,80,160 MHz)\n", str[j]); 191 len += scnprintf(buf + len, size - len, 192 " %llu %llu %llu %llu\n", 193 stats->bw[j][0], stats->bw[j][1], 194 stats->bw[j][2], stats->bw[j][3]); 195 len += scnprintf(buf + len, size - len, 196 " NSS %s (1x1,2x2,3x3,4x4)\n", str[j]); 197 len += scnprintf(buf + len, size - len, 198 " %llu %llu %llu %llu\n", 199 stats->nss[j][0], stats->nss[j][1], 200 stats->nss[j][2], stats->nss[j][3]); 201 len += scnprintf(buf + len, size - len, 202 " GI %s (0.4us,0.8us,1.6us,3.2us)\n", 203 str[j]); 204 len += scnprintf(buf + len, size - len, 205 " %llu %llu %llu %llu\n", 206 stats->gi[j][0], stats->gi[j][1], 207 stats->gi[j][2], stats->gi[j][3]); 208 len += scnprintf(buf + len, size - len, 209 " legacy rate %s (1,2 ... Mbps)\n ", 210 str[j]); 211 for (i = 0; i < ATH11K_LEGACY_NUM; i++) 212 len += scnprintf(buf + len, size - len, "%llu ", 213 stats->legacy[j][i]); 214 len += scnprintf(buf + len, size - len, "\n"); 215 } 216 } 217 218 len += scnprintf(buf + len, size - len, 219 "\nTX duration\n %llu usecs\n", 220 arsta->tx_stats->tx_duration); 221 len += scnprintf(buf + len, size - len, 222 "BA fails\n %llu\n", arsta->tx_stats->ba_fails); 223 len += scnprintf(buf + len, size - len, 224 "ack fails\n %llu\n", arsta->tx_stats->ack_fails); 225 spin_unlock_bh(&ar->data_lock); 226 227 if (len > size) 228 len = size; 229 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 230 kfree(buf); 231 232 mutex_unlock(&ar->conf_mutex); 233 return retval; 234 } 235 236 static const struct file_operations fops_tx_stats = { 237 .read = ath11k_dbg_sta_dump_tx_stats, 238 .open = simple_open, 239 .owner = THIS_MODULE, 240 .llseek = default_llseek, 241 }; 242 243 static ssize_t ath11k_dbg_sta_dump_rx_stats(struct file *file, 244 char __user *user_buf, 245 size_t count, loff_t *ppos) 246 { 247 struct ieee80211_sta *sta = file->private_data; 248 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 249 struct ath11k *ar = arsta->arvif->ar; 250 struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; 251 int len = 0, i, retval = 0; 252 const int size = 4096; 253 char *buf; 254 255 if (!rx_stats) 256 return -ENOENT; 257 258 buf = kzalloc(size, GFP_KERNEL); 259 if (!buf) 260 return -ENOMEM; 261 262 mutex_lock(&ar->conf_mutex); 263 spin_lock_bh(&ar->ab->base_lock); 264 265 len += scnprintf(buf + len, size - len, "RX peer stats:\n"); 266 len += scnprintf(buf + len, size - len, "Num of MSDUs: %llu\n", 267 rx_stats->num_msdu); 268 len += scnprintf(buf + len, size - len, "Num of MSDUs with TCP L4: %llu\n", 269 rx_stats->tcp_msdu_count); 270 len += scnprintf(buf + len, size - len, "Num of MSDUs with UDP L4: %llu\n", 271 rx_stats->udp_msdu_count); 272 len += scnprintf(buf + len, size - len, "Num of MSDUs part of AMPDU: %llu\n", 273 rx_stats->ampdu_msdu_count); 274 len += scnprintf(buf + len, size - len, "Num of MSDUs not part of AMPDU: %llu\n", 275 rx_stats->non_ampdu_msdu_count); 276 len += scnprintf(buf + len, size - len, "Num of MSDUs using STBC: %llu\n", 277 rx_stats->stbc_count); 278 len += scnprintf(buf + len, size - len, "Num of MSDUs beamformed: %llu\n", 279 rx_stats->beamformed_count); 280 len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS ok: %llu\n", 281 rx_stats->num_mpdu_fcs_ok); 282 len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS error: %llu\n", 283 rx_stats->num_mpdu_fcs_err); 284 len += scnprintf(buf + len, size - len, 285 "GI: 0.8us %llu 0.4us %llu 1.6us %llu 3.2us %llu\n", 286 rx_stats->gi_count[0], rx_stats->gi_count[1], 287 rx_stats->gi_count[2], rx_stats->gi_count[3]); 288 len += scnprintf(buf + len, size - len, 289 "BW: 20Mhz %llu 40Mhz %llu 80Mhz %llu 160Mhz %llu\n", 290 rx_stats->bw_count[0], rx_stats->bw_count[1], 291 rx_stats->bw_count[2], rx_stats->bw_count[3]); 292 len += scnprintf(buf + len, size - len, "BCC %llu LDPC %llu\n", 293 rx_stats->coding_count[0], rx_stats->coding_count[1]); 294 len += scnprintf(buf + len, size - len, 295 "preamble: 11A %llu 11B %llu 11N %llu 11AC %llu 11AX %llu\n", 296 rx_stats->pream_cnt[0], rx_stats->pream_cnt[1], 297 rx_stats->pream_cnt[2], rx_stats->pream_cnt[3], 298 rx_stats->pream_cnt[4]); 299 len += scnprintf(buf + len, size - len, 300 "reception type: SU %llu MU_MIMO %llu MU_OFDMA %llu MU_OFDMA_MIMO %llu\n", 301 rx_stats->reception_type[0], rx_stats->reception_type[1], 302 rx_stats->reception_type[2], rx_stats->reception_type[3]); 303 len += scnprintf(buf + len, size - len, "TID(0-15) Legacy TID(16):"); 304 for (i = 0; i <= IEEE80211_NUM_TIDS; i++) 305 len += scnprintf(buf + len, size - len, "%llu ", rx_stats->tid_count[i]); 306 len += scnprintf(buf + len, size - len, "\nMCS(0-11) Legacy MCS(12):"); 307 for (i = 0; i < HAL_RX_MAX_MCS + 1; i++) 308 len += scnprintf(buf + len, size - len, "%llu ", rx_stats->mcs_count[i]); 309 len += scnprintf(buf + len, size - len, "\nNSS(1-8):"); 310 for (i = 0; i < HAL_RX_MAX_NSS; i++) 311 len += scnprintf(buf + len, size - len, "%llu ", rx_stats->nss_count[i]); 312 len += scnprintf(buf + len, size - len, "\nRX Duration:%llu ", 313 rx_stats->rx_duration); 314 len += scnprintf(buf + len, size - len, 315 "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", 316 rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0], 317 rx_stats->ru_alloc_cnt[1], rx_stats->ru_alloc_cnt[2], 318 rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4], 319 rx_stats->ru_alloc_cnt[5]); 320 321 len += scnprintf(buf + len, size - len, "\n"); 322 323 spin_unlock_bh(&ar->ab->base_lock); 324 325 if (len > size) 326 len = size; 327 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 328 kfree(buf); 329 330 mutex_unlock(&ar->conf_mutex); 331 return retval; 332 } 333 334 static const struct file_operations fops_rx_stats = { 335 .read = ath11k_dbg_sta_dump_rx_stats, 336 .open = simple_open, 337 .owner = THIS_MODULE, 338 .llseek = default_llseek, 339 }; 340 341 static int 342 ath11k_dbg_sta_open_htt_peer_stats(struct inode *inode, struct file *file) 343 { 344 struct ieee80211_sta *sta = inode->i_private; 345 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 346 struct ath11k *ar = arsta->arvif->ar; 347 struct debug_htt_stats_req *stats_req; 348 int type = ar->debug.htt_stats.type; 349 int ret; 350 351 if ((type != ATH11K_DBG_HTT_EXT_STATS_PEER_INFO && 352 type != ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS) || 353 type == ATH11K_DBG_HTT_EXT_STATS_RESET) 354 return -EPERM; 355 356 stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE); 357 if (!stats_req) 358 return -ENOMEM; 359 360 mutex_lock(&ar->conf_mutex); 361 ar->debug.htt_stats.stats_req = stats_req; 362 stats_req->type = type; 363 memcpy(stats_req->peer_addr, sta->addr, ETH_ALEN); 364 ret = ath11k_debugfs_htt_stats_req(ar); 365 mutex_unlock(&ar->conf_mutex); 366 if (ret < 0) 367 goto out; 368 369 file->private_data = stats_req; 370 return 0; 371 out: 372 vfree(stats_req); 373 ar->debug.htt_stats.stats_req = NULL; 374 return ret; 375 } 376 377 static int 378 ath11k_dbg_sta_release_htt_peer_stats(struct inode *inode, struct file *file) 379 { 380 struct ieee80211_sta *sta = inode->i_private; 381 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 382 struct ath11k *ar = arsta->arvif->ar; 383 384 mutex_lock(&ar->conf_mutex); 385 vfree(file->private_data); 386 ar->debug.htt_stats.stats_req = NULL; 387 mutex_unlock(&ar->conf_mutex); 388 389 return 0; 390 } 391 392 static ssize_t ath11k_dbg_sta_read_htt_peer_stats(struct file *file, 393 char __user *user_buf, 394 size_t count, loff_t *ppos) 395 { 396 struct debug_htt_stats_req *stats_req = file->private_data; 397 char *buf; 398 u32 length = 0; 399 400 buf = stats_req->buf; 401 length = min_t(u32, stats_req->buf_len, ATH11K_HTT_STATS_BUF_SIZE); 402 return simple_read_from_buffer(user_buf, count, ppos, buf, length); 403 } 404 405 static const struct file_operations fops_htt_peer_stats = { 406 .open = ath11k_dbg_sta_open_htt_peer_stats, 407 .release = ath11k_dbg_sta_release_htt_peer_stats, 408 .read = ath11k_dbg_sta_read_htt_peer_stats, 409 .owner = THIS_MODULE, 410 .llseek = default_llseek, 411 }; 412 413 static ssize_t ath11k_dbg_sta_write_peer_pktlog(struct file *file, 414 const char __user *buf, 415 size_t count, loff_t *ppos) 416 { 417 struct ieee80211_sta *sta = file->private_data; 418 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 419 struct ath11k *ar = arsta->arvif->ar; 420 int ret, enable; 421 422 mutex_lock(&ar->conf_mutex); 423 424 if (ar->state != ATH11K_STATE_ON) { 425 ret = -ENETDOWN; 426 goto out; 427 } 428 429 ret = kstrtoint_from_user(buf, count, 0, &enable); 430 if (ret) 431 goto out; 432 433 ar->debug.pktlog_peer_valid = enable; 434 memcpy(ar->debug.pktlog_peer_addr, sta->addr, ETH_ALEN); 435 436 /* Send peer based pktlog enable/disable */ 437 ret = ath11k_wmi_pdev_peer_pktlog_filter(ar, sta->addr, enable); 438 if (ret) { 439 ath11k_warn(ar->ab, "failed to set peer pktlog filter %pM: %d\n", 440 sta->addr, ret); 441 goto out; 442 } 443 444 ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "peer pktlog filter set to %d\n", 445 enable); 446 ret = count; 447 448 out: 449 mutex_unlock(&ar->conf_mutex); 450 return ret; 451 } 452 453 static ssize_t ath11k_dbg_sta_read_peer_pktlog(struct file *file, 454 char __user *ubuf, 455 size_t count, loff_t *ppos) 456 { 457 struct ieee80211_sta *sta = file->private_data; 458 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 459 struct ath11k *ar = arsta->arvif->ar; 460 char buf[32] = {}; 461 int len; 462 463 mutex_lock(&ar->conf_mutex); 464 len = scnprintf(buf, sizeof(buf), "%08x %pM\n", 465 ar->debug.pktlog_peer_valid, 466 ar->debug.pktlog_peer_addr); 467 mutex_unlock(&ar->conf_mutex); 468 469 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 470 } 471 472 static const struct file_operations fops_peer_pktlog = { 473 .write = ath11k_dbg_sta_write_peer_pktlog, 474 .read = ath11k_dbg_sta_read_peer_pktlog, 475 .open = simple_open, 476 .owner = THIS_MODULE, 477 .llseek = default_llseek, 478 }; 479 480 static ssize_t ath11k_dbg_sta_write_delba(struct file *file, 481 const char __user *user_buf, 482 size_t count, loff_t *ppos) 483 { 484 struct ieee80211_sta *sta = file->private_data; 485 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 486 struct ath11k *ar = arsta->arvif->ar; 487 u32 tid, initiator, reason; 488 int ret; 489 char buf[64] = {}; 490 491 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, 492 user_buf, count); 493 if (ret <= 0) 494 return ret; 495 496 ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason); 497 if (ret != 3) 498 return -EINVAL; 499 500 /* Valid TID values are 0 through 15 */ 501 if (tid > HAL_DESC_REO_NON_QOS_TID - 1) 502 return -EINVAL; 503 504 mutex_lock(&ar->conf_mutex); 505 if (ar->state != ATH11K_STATE_ON || 506 arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) { 507 ret = count; 508 goto out; 509 } 510 511 ret = ath11k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr, 512 tid, initiator, reason); 513 if (ret) { 514 ath11k_warn(ar->ab, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n", 515 arsta->arvif->vdev_id, sta->addr, tid, initiator, 516 reason); 517 } 518 ret = count; 519 out: 520 mutex_unlock(&ar->conf_mutex); 521 return ret; 522 } 523 524 static const struct file_operations fops_delba = { 525 .write = ath11k_dbg_sta_write_delba, 526 .open = simple_open, 527 .owner = THIS_MODULE, 528 .llseek = default_llseek, 529 }; 530 531 static ssize_t ath11k_dbg_sta_write_addba_resp(struct file *file, 532 const char __user *user_buf, 533 size_t count, loff_t *ppos) 534 { 535 struct ieee80211_sta *sta = file->private_data; 536 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 537 struct ath11k *ar = arsta->arvif->ar; 538 u32 tid, status; 539 int ret; 540 char buf[64] = {}; 541 542 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, 543 user_buf, count); 544 if (ret <= 0) 545 return ret; 546 547 ret = sscanf(buf, "%u %u", &tid, &status); 548 if (ret != 2) 549 return -EINVAL; 550 551 /* Valid TID values are 0 through 15 */ 552 if (tid > HAL_DESC_REO_NON_QOS_TID - 1) 553 return -EINVAL; 554 555 mutex_lock(&ar->conf_mutex); 556 if (ar->state != ATH11K_STATE_ON || 557 arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) { 558 ret = count; 559 goto out; 560 } 561 562 ret = ath11k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr, 563 tid, status); 564 if (ret) { 565 ath11k_warn(ar->ab, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n", 566 arsta->arvif->vdev_id, sta->addr, tid, status); 567 } 568 ret = count; 569 out: 570 mutex_unlock(&ar->conf_mutex); 571 return ret; 572 } 573 574 static const struct file_operations fops_addba_resp = { 575 .write = ath11k_dbg_sta_write_addba_resp, 576 .open = simple_open, 577 .owner = THIS_MODULE, 578 .llseek = default_llseek, 579 }; 580 581 static ssize_t ath11k_dbg_sta_write_addba(struct file *file, 582 const char __user *user_buf, 583 size_t count, loff_t *ppos) 584 { 585 struct ieee80211_sta *sta = file->private_data; 586 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 587 struct ath11k *ar = arsta->arvif->ar; 588 u32 tid, buf_size; 589 int ret; 590 char buf[64] = {}; 591 592 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, 593 user_buf, count); 594 if (ret <= 0) 595 return ret; 596 597 ret = sscanf(buf, "%u %u", &tid, &buf_size); 598 if (ret != 2) 599 return -EINVAL; 600 601 /* Valid TID values are 0 through 15 */ 602 if (tid > HAL_DESC_REO_NON_QOS_TID - 1) 603 return -EINVAL; 604 605 mutex_lock(&ar->conf_mutex); 606 if (ar->state != ATH11K_STATE_ON || 607 arsta->aggr_mode != ATH11K_DBG_AGGR_MODE_MANUAL) { 608 ret = count; 609 goto out; 610 } 611 612 ret = ath11k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr, 613 tid, buf_size); 614 if (ret) { 615 ath11k_warn(ar->ab, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n", 616 arsta->arvif->vdev_id, sta->addr, tid, buf_size); 617 } 618 619 ret = count; 620 out: 621 mutex_unlock(&ar->conf_mutex); 622 return ret; 623 } 624 625 static const struct file_operations fops_addba = { 626 .write = ath11k_dbg_sta_write_addba, 627 .open = simple_open, 628 .owner = THIS_MODULE, 629 .llseek = default_llseek, 630 }; 631 632 static ssize_t ath11k_dbg_sta_read_aggr_mode(struct file *file, 633 char __user *user_buf, 634 size_t count, loff_t *ppos) 635 { 636 struct ieee80211_sta *sta = file->private_data; 637 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 638 struct ath11k *ar = arsta->arvif->ar; 639 char buf[64]; 640 int len = 0; 641 642 mutex_lock(&ar->conf_mutex); 643 len = scnprintf(buf, sizeof(buf) - len, 644 "aggregation mode: %s\n\n%s\n%s\n", 645 (arsta->aggr_mode == ATH11K_DBG_AGGR_MODE_AUTO) ? 646 "auto" : "manual", "auto = 0", "manual = 1"); 647 mutex_unlock(&ar->conf_mutex); 648 649 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 650 } 651 652 static ssize_t ath11k_dbg_sta_write_aggr_mode(struct file *file, 653 const char __user *user_buf, 654 size_t count, loff_t *ppos) 655 { 656 struct ieee80211_sta *sta = file->private_data; 657 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 658 struct ath11k *ar = arsta->arvif->ar; 659 u32 aggr_mode; 660 int ret; 661 662 if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode)) 663 return -EINVAL; 664 665 if (aggr_mode >= ATH11K_DBG_AGGR_MODE_MAX) 666 return -EINVAL; 667 668 mutex_lock(&ar->conf_mutex); 669 if (ar->state != ATH11K_STATE_ON || 670 aggr_mode == arsta->aggr_mode) { 671 ret = count; 672 goto out; 673 } 674 675 ret = ath11k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr); 676 if (ret) { 677 ath11k_warn(ar->ab, "failed to clear addba session ret: %d\n", 678 ret); 679 goto out; 680 } 681 682 arsta->aggr_mode = aggr_mode; 683 out: 684 mutex_unlock(&ar->conf_mutex); 685 return ret; 686 } 687 688 static const struct file_operations fops_aggr_mode = { 689 .read = ath11k_dbg_sta_read_aggr_mode, 690 .write = ath11k_dbg_sta_write_aggr_mode, 691 .open = simple_open, 692 .owner = THIS_MODULE, 693 .llseek = default_llseek, 694 }; 695 696 static ssize_t 697 ath11k_write_htt_peer_stats_reset(struct file *file, 698 const char __user *user_buf, 699 size_t count, loff_t *ppos) 700 { 701 struct ieee80211_sta *sta = file->private_data; 702 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 703 struct ath11k *ar = arsta->arvif->ar; 704 struct htt_ext_stats_cfg_params cfg_params = {}; 705 int ret; 706 u8 type; 707 708 ret = kstrtou8_from_user(user_buf, count, 0, &type); 709 if (ret) 710 return ret; 711 712 if (!type) 713 return ret; 714 715 mutex_lock(&ar->conf_mutex); 716 cfg_params.cfg0 = HTT_STAT_PEER_INFO_MAC_ADDR; 717 cfg_params.cfg0 |= FIELD_PREP(GENMASK(15, 1), 718 HTT_PEER_STATS_REQ_MODE_FLUSH_TQM); 719 720 cfg_params.cfg1 = HTT_STAT_DEFAULT_PEER_REQ_TYPE; 721 722 cfg_params.cfg2 |= FIELD_PREP(GENMASK(7, 0), sta->addr[0]); 723 cfg_params.cfg2 |= FIELD_PREP(GENMASK(15, 8), sta->addr[1]); 724 cfg_params.cfg2 |= FIELD_PREP(GENMASK(23, 16), sta->addr[2]); 725 cfg_params.cfg2 |= FIELD_PREP(GENMASK(31, 24), sta->addr[3]); 726 727 cfg_params.cfg3 |= FIELD_PREP(GENMASK(7, 0), sta->addr[4]); 728 cfg_params.cfg3 |= FIELD_PREP(GENMASK(15, 8), sta->addr[5]); 729 730 cfg_params.cfg3 |= ATH11K_HTT_PEER_STATS_RESET; 731 732 ret = ath11k_dp_tx_htt_h2t_ext_stats_req(ar, 733 ATH11K_DBG_HTT_EXT_STATS_PEER_INFO, 734 &cfg_params, 735 0ULL); 736 if (ret) { 737 ath11k_warn(ar->ab, "failed to send htt peer stats request: %d\n", ret); 738 mutex_unlock(&ar->conf_mutex); 739 return ret; 740 } 741 742 mutex_unlock(&ar->conf_mutex); 743 744 ret = count; 745 746 return ret; 747 } 748 749 static const struct file_operations fops_htt_peer_stats_reset = { 750 .write = ath11k_write_htt_peer_stats_reset, 751 .open = simple_open, 752 .owner = THIS_MODULE, 753 .llseek = default_llseek, 754 }; 755 756 static ssize_t ath11k_dbg_sta_read_peer_ps_state(struct file *file, 757 char __user *user_buf, 758 size_t count, loff_t *ppos) 759 { 760 struct ieee80211_sta *sta = file->private_data; 761 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 762 struct ath11k *ar = arsta->arvif->ar; 763 char buf[20]; 764 int len; 765 766 spin_lock_bh(&ar->data_lock); 767 768 len = scnprintf(buf, sizeof(buf), "%d\n", arsta->peer_ps_state); 769 770 spin_unlock_bh(&ar->data_lock); 771 772 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 773 } 774 775 static const struct file_operations fops_peer_ps_state = { 776 .open = simple_open, 777 .read = ath11k_dbg_sta_read_peer_ps_state, 778 .owner = THIS_MODULE, 779 .llseek = default_llseek, 780 }; 781 782 static ssize_t ath11k_dbg_sta_read_current_ps_duration(struct file *file, 783 char __user *user_buf, 784 size_t count, 785 loff_t *ppos) 786 { 787 struct ieee80211_sta *sta = file->private_data; 788 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 789 struct ath11k *ar = arsta->arvif->ar; 790 u64 time_since_station_in_power_save; 791 char buf[20]; 792 int len; 793 794 spin_lock_bh(&ar->data_lock); 795 796 if (arsta->peer_ps_state == WMI_PEER_PS_STATE_ON && 797 arsta->peer_current_ps_valid) 798 time_since_station_in_power_save = jiffies_to_msecs(jiffies 799 - arsta->ps_start_jiffies); 800 else 801 time_since_station_in_power_save = 0; 802 803 len = scnprintf(buf, sizeof(buf), "%llu\n", 804 time_since_station_in_power_save); 805 spin_unlock_bh(&ar->data_lock); 806 807 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 808 } 809 810 static const struct file_operations fops_current_ps_duration = { 811 .open = simple_open, 812 .read = ath11k_dbg_sta_read_current_ps_duration, 813 .owner = THIS_MODULE, 814 .llseek = default_llseek, 815 }; 816 817 static ssize_t ath11k_dbg_sta_read_total_ps_duration(struct file *file, 818 char __user *user_buf, 819 size_t count, loff_t *ppos) 820 { 821 struct ieee80211_sta *sta = file->private_data; 822 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); 823 struct ath11k *ar = arsta->arvif->ar; 824 char buf[20]; 825 u64 power_save_duration; 826 int len; 827 828 spin_lock_bh(&ar->data_lock); 829 830 if (arsta->peer_ps_state == WMI_PEER_PS_STATE_ON && 831 arsta->peer_current_ps_valid) 832 power_save_duration = jiffies_to_msecs(jiffies 833 - arsta->ps_start_jiffies) 834 + arsta->ps_total_duration; 835 else 836 power_save_duration = arsta->ps_total_duration; 837 838 len = scnprintf(buf, sizeof(buf), "%llu\n", power_save_duration); 839 840 spin_unlock_bh(&ar->data_lock); 841 842 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 843 } 844 845 static const struct file_operations fops_total_ps_duration = { 846 .open = simple_open, 847 .read = ath11k_dbg_sta_read_total_ps_duration, 848 .owner = THIS_MODULE, 849 .llseek = default_llseek, 850 }; 851 852 void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 853 struct ieee80211_sta *sta, struct dentry *dir) 854 { 855 struct ath11k *ar = hw->priv; 856 857 if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) 858 debugfs_create_file("tx_stats", 0400, dir, sta, 859 &fops_tx_stats); 860 if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) 861 debugfs_create_file("rx_stats", 0400, dir, sta, 862 &fops_rx_stats); 863 864 debugfs_create_file("htt_peer_stats", 0400, dir, sta, 865 &fops_htt_peer_stats); 866 867 debugfs_create_file("peer_pktlog", 0644, dir, sta, 868 &fops_peer_pktlog); 869 870 debugfs_create_file("aggr_mode", 0644, dir, sta, &fops_aggr_mode); 871 debugfs_create_file("addba", 0200, dir, sta, &fops_addba); 872 debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp); 873 debugfs_create_file("delba", 0200, dir, sta, &fops_delba); 874 875 if (test_bit(WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET, 876 ar->ab->wmi_ab.svc_map)) 877 debugfs_create_file("htt_peer_stats_reset", 0600, dir, sta, 878 &fops_htt_peer_stats_reset); 879 880 debugfs_create_file("peer_ps_state", 0400, dir, sta, 881 &fops_peer_ps_state); 882 883 if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT, 884 ar->ab->wmi_ab.svc_map)) { 885 debugfs_create_file("current_ps_duration", 0440, dir, sta, 886 &fops_current_ps_duration); 887 debugfs_create_file("total_ps_duration", 0440, dir, sta, 888 &fops_total_ps_duration); 889 } 890 } 891