1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 */ 6 7 #include "core.h" 8 #include "dp_tx.h" 9 #include "debug.h" 10 #include "debugfs.h" 11 #include "debugfs_htt_stats.h" 12 13 static ssize_t ath12k_write_simulate_radar(struct file *file, 14 const char __user *user_buf, 15 size_t count, loff_t *ppos) 16 { 17 struct ath12k *ar = file->private_data; 18 int ret; 19 20 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy); 21 ret = ath12k_wmi_simulate_radar(ar); 22 if (ret) 23 goto exit; 24 25 ret = count; 26 exit: 27 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy); 28 return ret; 29 } 30 31 static const struct file_operations fops_simulate_radar = { 32 .write = ath12k_write_simulate_radar, 33 .open = simple_open 34 }; 35 36 static ssize_t ath12k_read_simulate_fw_crash(struct file *file, 37 char __user *user_buf, 38 size_t count, loff_t *ppos) 39 { 40 const char buf[] = 41 "To simulate firmware crash write one of the keywords to this file:\n" 42 "`assert` - send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"; 43 44 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 45 } 46 47 static ssize_t 48 ath12k_write_simulate_fw_crash(struct file *file, 49 const char __user *user_buf, 50 size_t count, loff_t *ppos) 51 { 52 struct ath12k_base *ab = file->private_data; 53 struct ath12k_pdev *pdev; 54 struct ath12k *ar = NULL; 55 char buf[32] = {}; 56 int i, ret; 57 ssize_t rc; 58 59 /* filter partial writes and invalid commands */ 60 if (*ppos != 0 || count >= sizeof(buf) || count == 0) 61 return -EINVAL; 62 63 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 64 if (rc < 0) 65 return rc; 66 67 /* drop the possible '\n' from the end */ 68 if (buf[*ppos - 1] == '\n') 69 buf[*ppos - 1] = '\0'; 70 71 for (i = 0; i < ab->num_radios; i++) { 72 pdev = &ab->pdevs[i]; 73 ar = pdev->ar; 74 if (ar) 75 break; 76 } 77 78 if (!ar) 79 return -ENETDOWN; 80 81 if (!strcmp(buf, "assert")) { 82 ath12k_info(ab, "simulating firmware assert crash\n"); 83 ret = ath12k_wmi_force_fw_hang_cmd(ar, 84 ATH12K_WMI_FW_HANG_ASSERT_TYPE, 85 ATH12K_WMI_FW_HANG_DELAY); 86 } else { 87 return -EINVAL; 88 } 89 90 if (ret) { 91 ath12k_warn(ab, "failed to simulate firmware crash: %d\n", ret); 92 return ret; 93 } 94 95 return count; 96 } 97 98 static const struct file_operations fops_simulate_fw_crash = { 99 .read = ath12k_read_simulate_fw_crash, 100 .write = ath12k_write_simulate_fw_crash, 101 .open = simple_open, 102 .owner = THIS_MODULE, 103 .llseek = default_llseek, 104 }; 105 106 static ssize_t ath12k_write_tpc_stats_type(struct file *file, 107 const char __user *user_buf, 108 size_t count, loff_t *ppos) 109 { 110 struct ath12k *ar = file->private_data; 111 u8 type; 112 int ret; 113 114 ret = kstrtou8_from_user(user_buf, count, 0, &type); 115 if (ret) 116 return ret; 117 118 if (type >= WMI_HALPHY_PDEV_TX_STATS_MAX) 119 return -EINVAL; 120 121 spin_lock_bh(&ar->data_lock); 122 ar->debug.tpc_stats_type = type; 123 spin_unlock_bh(&ar->data_lock); 124 125 return count; 126 } 127 128 static int ath12k_debug_tpc_stats_request(struct ath12k *ar) 129 { 130 enum wmi_halphy_ctrl_path_stats_id tpc_stats_sub_id; 131 struct ath12k_base *ab = ar->ab; 132 int ret; 133 134 lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); 135 136 reinit_completion(&ar->debug.tpc_complete); 137 138 spin_lock_bh(&ar->data_lock); 139 ar->debug.tpc_request = true; 140 tpc_stats_sub_id = ar->debug.tpc_stats_type; 141 spin_unlock_bh(&ar->data_lock); 142 143 ret = ath12k_wmi_send_tpc_stats_request(ar, tpc_stats_sub_id); 144 if (ret) { 145 ath12k_warn(ab, "failed to request pdev tpc stats: %d\n", ret); 146 spin_lock_bh(&ar->data_lock); 147 ar->debug.tpc_request = false; 148 spin_unlock_bh(&ar->data_lock); 149 return ret; 150 } 151 152 return 0; 153 } 154 155 static int ath12k_get_tpc_ctl_mode_idx(struct wmi_tpc_stats_arg *tpc_stats, 156 enum wmi_tpc_pream_bw pream_bw, int *mode_idx) 157 { 158 u32 chan_freq = le32_to_cpu(tpc_stats->tpc_config.chan_freq); 159 u8 band; 160 161 band = ((chan_freq > ATH12K_MIN_6GHZ_FREQ) ? NL80211_BAND_6GHZ : 162 ((chan_freq > ATH12K_MIN_5GHZ_FREQ) ? NL80211_BAND_5GHZ : 163 NL80211_BAND_2GHZ)); 164 165 if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) { 166 switch (pream_bw) { 167 case WMI_TPC_PREAM_HT20: 168 case WMI_TPC_PREAM_VHT20: 169 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT_VHT20_5GHZ_6GHZ; 170 break; 171 case WMI_TPC_PREAM_HE20: 172 case WMI_TPC_PREAM_EHT20: 173 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT20_5GHZ_6GHZ; 174 break; 175 case WMI_TPC_PREAM_HT40: 176 case WMI_TPC_PREAM_VHT40: 177 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT_VHT40_5GHZ_6GHZ; 178 break; 179 case WMI_TPC_PREAM_HE40: 180 case WMI_TPC_PREAM_EHT40: 181 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT40_5GHZ_6GHZ; 182 break; 183 case WMI_TPC_PREAM_VHT80: 184 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_VHT80_5GHZ_6GHZ; 185 break; 186 case WMI_TPC_PREAM_EHT60: 187 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT80_SU_PUNC20; 188 break; 189 case WMI_TPC_PREAM_HE80: 190 case WMI_TPC_PREAM_EHT80: 191 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT80_5GHZ_6GHZ; 192 break; 193 case WMI_TPC_PREAM_VHT160: 194 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_VHT160_5GHZ_6GHZ; 195 break; 196 case WMI_TPC_PREAM_EHT120: 197 case WMI_TPC_PREAM_EHT140: 198 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT160_SU_PUNC20; 199 break; 200 case WMI_TPC_PREAM_HE160: 201 case WMI_TPC_PREAM_EHT160: 202 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT160_5GHZ_6GHZ; 203 break; 204 case WMI_TPC_PREAM_EHT200: 205 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC120; 206 break; 207 case WMI_TPC_PREAM_EHT240: 208 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC80; 209 break; 210 case WMI_TPC_PREAM_EHT280: 211 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC40; 212 break; 213 case WMI_TPC_PREAM_EHT320: 214 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT320_5GHZ_6GHZ; 215 break; 216 default: 217 /* for 5GHZ and 6GHZ, default case will be for OFDM */ 218 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_LEGACY_5GHZ_6GHZ; 219 break; 220 } 221 } else { 222 switch (pream_bw) { 223 case WMI_TPC_PREAM_OFDM: 224 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_LEGACY_2GHZ; 225 break; 226 case WMI_TPC_PREAM_HT20: 227 case WMI_TPC_PREAM_VHT20: 228 case WMI_TPC_PREAM_HE20: 229 case WMI_TPC_PREAM_EHT20: 230 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT20_2GHZ; 231 break; 232 case WMI_TPC_PREAM_HT40: 233 case WMI_TPC_PREAM_VHT40: 234 case WMI_TPC_PREAM_HE40: 235 case WMI_TPC_PREAM_EHT40: 236 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT40_2GHZ; 237 break; 238 default: 239 /* for 2GHZ, default case will be CCK */ 240 *mode_idx = ATH12K_TPC_STATS_CTL_MODE_CCK_2GHZ; 241 break; 242 } 243 } 244 245 return 0; 246 } 247 248 static s16 ath12k_tpc_get_rate(struct ath12k *ar, 249 struct wmi_tpc_stats_arg *tpc_stats, 250 u32 rate_idx, u32 num_chains, u32 rate_code, 251 enum wmi_tpc_pream_bw pream_bw, 252 enum wmi_halphy_ctrl_path_stats_id type, 253 u32 eht_rate_idx) 254 { 255 u32 tot_nss, tot_modes, txbf_on_off, index_offset1, index_offset2, index_offset3; 256 u8 chain_idx, stm_idx, num_streams; 257 bool is_mu, txbf_enabled = 0; 258 s8 rates_ctl_min, tpc_ctl; 259 s16 rates, tpc, reg_pwr; 260 u16 rate1, rate2; 261 int mode, ret; 262 263 num_streams = 1 + ATH12K_HW_NSS(rate_code); 264 chain_idx = num_chains - 1; 265 stm_idx = num_streams - 1; 266 mode = -1; 267 268 ret = ath12k_get_tpc_ctl_mode_idx(tpc_stats, pream_bw, &mode); 269 if (ret) { 270 ath12k_warn(ar->ab, "Invalid mode index received\n"); 271 tpc = TPC_INVAL; 272 goto out; 273 } 274 275 if (num_chains < num_streams) { 276 tpc = TPC_INVAL; 277 goto out; 278 } 279 280 if (le32_to_cpu(tpc_stats->tpc_config.num_tx_chain) <= 1) { 281 tpc = TPC_INVAL; 282 goto out; 283 } 284 285 if (type == WMI_HALPHY_PDEV_TX_SUTXBF_STATS || 286 type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS) 287 txbf_enabled = 1; 288 289 if (type == WMI_HALPHY_PDEV_TX_MU_STATS || 290 type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS) { 291 is_mu = true; 292 } else { 293 is_mu = false; 294 } 295 296 /* Below is the min calculation of ctl array, rates array and 297 * regulator power table. tpc is minimum of all 3 298 */ 299 if (pream_bw >= WMI_TPC_PREAM_EHT20 && pream_bw <= WMI_TPC_PREAM_EHT320) { 300 rate2 = tpc_stats->rates_array2.rate_array[eht_rate_idx]; 301 if (is_mu) 302 rates = u32_get_bits(rate2, ATH12K_TPC_RATE_ARRAY_MU); 303 else 304 rates = u32_get_bits(rate2, ATH12K_TPC_RATE_ARRAY_SU); 305 } else { 306 rate1 = tpc_stats->rates_array1.rate_array[rate_idx]; 307 if (is_mu) 308 rates = u32_get_bits(rate1, ATH12K_TPC_RATE_ARRAY_MU); 309 else 310 rates = u32_get_bits(rate1, ATH12K_TPC_RATE_ARRAY_SU); 311 } 312 313 if (tpc_stats->tlvs_rcvd & WMI_TPC_CTL_PWR_ARRAY) { 314 tot_nss = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d1); 315 tot_modes = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d2); 316 txbf_on_off = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d3); 317 index_offset1 = txbf_on_off * tot_modes * tot_nss; 318 index_offset2 = tot_modes * tot_nss; 319 index_offset3 = tot_nss; 320 321 tpc_ctl = *(tpc_stats->ctl_array.ctl_pwr_table + 322 chain_idx * index_offset1 + txbf_enabled * index_offset2 323 + mode * index_offset3 + stm_idx); 324 } else { 325 tpc_ctl = TPC_MAX; 326 ath12k_warn(ar->ab, 327 "ctl array for tpc stats not received from fw\n"); 328 } 329 330 rates_ctl_min = min_t(s16, rates, tpc_ctl); 331 332 reg_pwr = tpc_stats->max_reg_allowed_power.reg_pwr_array[chain_idx]; 333 334 if (reg_pwr < 0) 335 reg_pwr = TPC_INVAL; 336 337 tpc = min_t(s16, rates_ctl_min, reg_pwr); 338 339 /* MODULATION_LIMIT is the maximum power limit,tpc should not exceed 340 * modulation limit even if min tpc of all three array is greater 341 * modulation limit 342 */ 343 tpc = min_t(s16, tpc, MODULATION_LIMIT); 344 345 out: 346 return tpc; 347 } 348 349 static u16 ath12k_get_ratecode(u16 pream_idx, u16 nss, u16 mcs_rate) 350 { 351 u16 mode_type = ~0; 352 353 /* Below assignments are just for printing purpose only */ 354 switch (pream_idx) { 355 case WMI_TPC_PREAM_CCK: 356 mode_type = WMI_RATE_PREAMBLE_CCK; 357 break; 358 case WMI_TPC_PREAM_OFDM: 359 mode_type = WMI_RATE_PREAMBLE_OFDM; 360 break; 361 case WMI_TPC_PREAM_HT20: 362 case WMI_TPC_PREAM_HT40: 363 mode_type = WMI_RATE_PREAMBLE_HT; 364 break; 365 case WMI_TPC_PREAM_VHT20: 366 case WMI_TPC_PREAM_VHT40: 367 case WMI_TPC_PREAM_VHT80: 368 case WMI_TPC_PREAM_VHT160: 369 mode_type = WMI_RATE_PREAMBLE_VHT; 370 break; 371 case WMI_TPC_PREAM_HE20: 372 case WMI_TPC_PREAM_HE40: 373 case WMI_TPC_PREAM_HE80: 374 case WMI_TPC_PREAM_HE160: 375 mode_type = WMI_RATE_PREAMBLE_HE; 376 break; 377 case WMI_TPC_PREAM_EHT20: 378 case WMI_TPC_PREAM_EHT40: 379 case WMI_TPC_PREAM_EHT60: 380 case WMI_TPC_PREAM_EHT80: 381 case WMI_TPC_PREAM_EHT120: 382 case WMI_TPC_PREAM_EHT140: 383 case WMI_TPC_PREAM_EHT160: 384 case WMI_TPC_PREAM_EHT200: 385 case WMI_TPC_PREAM_EHT240: 386 case WMI_TPC_PREAM_EHT280: 387 case WMI_TPC_PREAM_EHT320: 388 mode_type = WMI_RATE_PREAMBLE_EHT; 389 if (mcs_rate == 0 || mcs_rate == 1) 390 mcs_rate += 14; 391 else 392 mcs_rate -= 2; 393 break; 394 default: 395 return mode_type; 396 } 397 return ((mode_type << 8) | ((nss & 0x7) << 5) | (mcs_rate & 0x1F)); 398 } 399 400 static bool ath12k_he_supports_extra_mcs(struct ath12k *ar, int freq) 401 { 402 struct ath12k_pdev_cap *cap = &ar->pdev->cap; 403 struct ath12k_band_cap *cap_band; 404 bool extra_mcs_supported; 405 406 if (freq <= ATH12K_2GHZ_MAX_FREQUENCY) 407 cap_band = &cap->band[NL80211_BAND_2GHZ]; 408 else if (freq <= ATH12K_5GHZ_MAX_FREQUENCY) 409 cap_band = &cap->band[NL80211_BAND_5GHZ]; 410 else 411 cap_band = &cap->band[NL80211_BAND_6GHZ]; 412 413 extra_mcs_supported = u32_get_bits(cap_band->he_cap_info[1], 414 HE_EXTRA_MCS_SUPPORT); 415 return extra_mcs_supported; 416 } 417 418 static int ath12k_tpc_fill_pream(struct ath12k *ar, char *buf, int buf_len, int len, 419 enum wmi_tpc_pream_bw pream_bw, u32 max_rix, 420 int max_nss, int max_rates, int pream_type, 421 enum wmi_halphy_ctrl_path_stats_id tpc_type, 422 int rate_idx, int eht_rate_idx) 423 { 424 struct wmi_tpc_stats_arg *tpc_stats = ar->debug.tpc_stats; 425 int nss, rates, chains; 426 u8 active_tx_chains; 427 u16 rate_code; 428 s16 tpc; 429 430 static const char *const pream_str[] = { 431 [WMI_TPC_PREAM_CCK] = "CCK", 432 [WMI_TPC_PREAM_OFDM] = "OFDM", 433 [WMI_TPC_PREAM_HT20] = "HT20", 434 [WMI_TPC_PREAM_HT40] = "HT40", 435 [WMI_TPC_PREAM_VHT20] = "VHT20", 436 [WMI_TPC_PREAM_VHT40] = "VHT40", 437 [WMI_TPC_PREAM_VHT80] = "VHT80", 438 [WMI_TPC_PREAM_VHT160] = "VHT160", 439 [WMI_TPC_PREAM_HE20] = "HE20", 440 [WMI_TPC_PREAM_HE40] = "HE40", 441 [WMI_TPC_PREAM_HE80] = "HE80", 442 [WMI_TPC_PREAM_HE160] = "HE160", 443 [WMI_TPC_PREAM_EHT20] = "EHT20", 444 [WMI_TPC_PREAM_EHT40] = "EHT40", 445 [WMI_TPC_PREAM_EHT60] = "EHT60", 446 [WMI_TPC_PREAM_EHT80] = "EHT80", 447 [WMI_TPC_PREAM_EHT120] = "EHT120", 448 [WMI_TPC_PREAM_EHT140] = "EHT140", 449 [WMI_TPC_PREAM_EHT160] = "EHT160", 450 [WMI_TPC_PREAM_EHT200] = "EHT200", 451 [WMI_TPC_PREAM_EHT240] = "EHT240", 452 [WMI_TPC_PREAM_EHT280] = "EHT280", 453 [WMI_TPC_PREAM_EHT320] = "EHT320"}; 454 455 active_tx_chains = ar->num_tx_chains; 456 457 for (nss = 0; nss < max_nss; nss++) { 458 for (rates = 0; rates < max_rates; rates++, rate_idx++, max_rix++) { 459 /* FW send extra MCS(10&11) for VHT and HE rates, 460 * this is not used. Hence skipping it here 461 */ 462 if (pream_type == WMI_RATE_PREAMBLE_VHT && 463 rates > ATH12K_VHT_MCS_MAX) 464 continue; 465 466 if (pream_type == WMI_RATE_PREAMBLE_HE && 467 rates > ATH12K_HE_MCS_MAX) 468 continue; 469 470 if (pream_type == WMI_RATE_PREAMBLE_EHT && 471 rates > ATH12K_EHT_MCS_MAX) 472 continue; 473 474 rate_code = ath12k_get_ratecode(pream_bw, nss, rates); 475 len += scnprintf(buf + len, buf_len - len, 476 "%d\t %s\t 0x%03x\t", max_rix, 477 pream_str[pream_bw], rate_code); 478 479 for (chains = 0; chains < active_tx_chains; chains++) { 480 if (nss > chains) { 481 len += scnprintf(buf + len, 482 buf_len - len, 483 "\t%s", "NA"); 484 } else { 485 tpc = ath12k_tpc_get_rate(ar, tpc_stats, 486 rate_idx, chains + 1, 487 rate_code, pream_bw, 488 tpc_type, 489 eht_rate_idx); 490 491 if (tpc == TPC_INVAL) { 492 len += scnprintf(buf + len, 493 buf_len - len, "\tNA"); 494 } else { 495 len += scnprintf(buf + len, 496 buf_len - len, "\t%d", 497 tpc); 498 } 499 } 500 } 501 len += scnprintf(buf + len, buf_len - len, "\n"); 502 503 if (pream_type == WMI_RATE_PREAMBLE_EHT) 504 /*For fetching the next eht rates pwr from rates array2*/ 505 ++eht_rate_idx; 506 } 507 } 508 509 return len; 510 } 511 512 static int ath12k_tpc_stats_print(struct ath12k *ar, 513 struct wmi_tpc_stats_arg *tpc_stats, 514 char *buf, size_t len, 515 enum wmi_halphy_ctrl_path_stats_id type) 516 { 517 u32 eht_idx = 0, pream_idx = 0, rate_pream_idx = 0, total_rates = 0, max_rix = 0; 518 u32 chan_freq, num_tx_chain, caps, i, j = 1; 519 size_t buf_len = ATH12K_TPC_STATS_BUF_SIZE; 520 u8 nss, active_tx_chains; 521 bool he_ext_mcs; 522 static const char *const type_str[WMI_HALPHY_PDEV_TX_STATS_MAX] = { 523 [WMI_HALPHY_PDEV_TX_SU_STATS] = "SU", 524 [WMI_HALPHY_PDEV_TX_SUTXBF_STATS] = "SU WITH TXBF", 525 [WMI_HALPHY_PDEV_TX_MU_STATS] = "MU", 526 [WMI_HALPHY_PDEV_TX_MUTXBF_STATS] = "MU WITH TXBF"}; 527 528 u8 max_rates[WMI_TPC_PREAM_MAX] = { 529 [WMI_TPC_PREAM_CCK] = ATH12K_CCK_RATES, 530 [WMI_TPC_PREAM_OFDM] = ATH12K_OFDM_RATES, 531 [WMI_TPC_PREAM_HT20] = ATH12K_HT_RATES, 532 [WMI_TPC_PREAM_HT40] = ATH12K_HT_RATES, 533 [WMI_TPC_PREAM_VHT20] = ATH12K_VHT_RATES, 534 [WMI_TPC_PREAM_VHT40] = ATH12K_VHT_RATES, 535 [WMI_TPC_PREAM_VHT80] = ATH12K_VHT_RATES, 536 [WMI_TPC_PREAM_VHT160] = ATH12K_VHT_RATES, 537 [WMI_TPC_PREAM_HE20] = ATH12K_HE_RATES, 538 [WMI_TPC_PREAM_HE40] = ATH12K_HE_RATES, 539 [WMI_TPC_PREAM_HE80] = ATH12K_HE_RATES, 540 [WMI_TPC_PREAM_HE160] = ATH12K_HE_RATES, 541 [WMI_TPC_PREAM_EHT20] = ATH12K_EHT_RATES, 542 [WMI_TPC_PREAM_EHT40] = ATH12K_EHT_RATES, 543 [WMI_TPC_PREAM_EHT60] = ATH12K_EHT_RATES, 544 [WMI_TPC_PREAM_EHT80] = ATH12K_EHT_RATES, 545 [WMI_TPC_PREAM_EHT120] = ATH12K_EHT_RATES, 546 [WMI_TPC_PREAM_EHT140] = ATH12K_EHT_RATES, 547 [WMI_TPC_PREAM_EHT160] = ATH12K_EHT_RATES, 548 [WMI_TPC_PREAM_EHT200] = ATH12K_EHT_RATES, 549 [WMI_TPC_PREAM_EHT240] = ATH12K_EHT_RATES, 550 [WMI_TPC_PREAM_EHT280] = ATH12K_EHT_RATES, 551 [WMI_TPC_PREAM_EHT320] = ATH12K_EHT_RATES}; 552 static const u8 max_nss[WMI_TPC_PREAM_MAX] = { 553 [WMI_TPC_PREAM_CCK] = ATH12K_NSS_1, 554 [WMI_TPC_PREAM_OFDM] = ATH12K_NSS_1, 555 [WMI_TPC_PREAM_HT20] = ATH12K_NSS_4, 556 [WMI_TPC_PREAM_HT40] = ATH12K_NSS_4, 557 [WMI_TPC_PREAM_VHT20] = ATH12K_NSS_8, 558 [WMI_TPC_PREAM_VHT40] = ATH12K_NSS_8, 559 [WMI_TPC_PREAM_VHT80] = ATH12K_NSS_8, 560 [WMI_TPC_PREAM_VHT160] = ATH12K_NSS_4, 561 [WMI_TPC_PREAM_HE20] = ATH12K_NSS_8, 562 [WMI_TPC_PREAM_HE40] = ATH12K_NSS_8, 563 [WMI_TPC_PREAM_HE80] = ATH12K_NSS_8, 564 [WMI_TPC_PREAM_HE160] = ATH12K_NSS_4, 565 [WMI_TPC_PREAM_EHT20] = ATH12K_NSS_4, 566 [WMI_TPC_PREAM_EHT40] = ATH12K_NSS_4, 567 [WMI_TPC_PREAM_EHT60] = ATH12K_NSS_4, 568 [WMI_TPC_PREAM_EHT80] = ATH12K_NSS_4, 569 [WMI_TPC_PREAM_EHT120] = ATH12K_NSS_4, 570 [WMI_TPC_PREAM_EHT140] = ATH12K_NSS_4, 571 [WMI_TPC_PREAM_EHT160] = ATH12K_NSS_4, 572 [WMI_TPC_PREAM_EHT200] = ATH12K_NSS_4, 573 [WMI_TPC_PREAM_EHT240] = ATH12K_NSS_4, 574 [WMI_TPC_PREAM_EHT280] = ATH12K_NSS_4, 575 [WMI_TPC_PREAM_EHT320] = ATH12K_NSS_4}; 576 577 u16 rate_idx[WMI_TPC_PREAM_MAX] = {}, eht_rate_idx[WMI_TPC_PREAM_MAX] = {}; 578 static const u8 pream_type[WMI_TPC_PREAM_MAX] = { 579 [WMI_TPC_PREAM_CCK] = WMI_RATE_PREAMBLE_CCK, 580 [WMI_TPC_PREAM_OFDM] = WMI_RATE_PREAMBLE_OFDM, 581 [WMI_TPC_PREAM_HT20] = WMI_RATE_PREAMBLE_HT, 582 [WMI_TPC_PREAM_HT40] = WMI_RATE_PREAMBLE_HT, 583 [WMI_TPC_PREAM_VHT20] = WMI_RATE_PREAMBLE_VHT, 584 [WMI_TPC_PREAM_VHT40] = WMI_RATE_PREAMBLE_VHT, 585 [WMI_TPC_PREAM_VHT80] = WMI_RATE_PREAMBLE_VHT, 586 [WMI_TPC_PREAM_VHT160] = WMI_RATE_PREAMBLE_VHT, 587 [WMI_TPC_PREAM_HE20] = WMI_RATE_PREAMBLE_HE, 588 [WMI_TPC_PREAM_HE40] = WMI_RATE_PREAMBLE_HE, 589 [WMI_TPC_PREAM_HE80] = WMI_RATE_PREAMBLE_HE, 590 [WMI_TPC_PREAM_HE160] = WMI_RATE_PREAMBLE_HE, 591 [WMI_TPC_PREAM_EHT20] = WMI_RATE_PREAMBLE_EHT, 592 [WMI_TPC_PREAM_EHT40] = WMI_RATE_PREAMBLE_EHT, 593 [WMI_TPC_PREAM_EHT60] = WMI_RATE_PREAMBLE_EHT, 594 [WMI_TPC_PREAM_EHT80] = WMI_RATE_PREAMBLE_EHT, 595 [WMI_TPC_PREAM_EHT120] = WMI_RATE_PREAMBLE_EHT, 596 [WMI_TPC_PREAM_EHT140] = WMI_RATE_PREAMBLE_EHT, 597 [WMI_TPC_PREAM_EHT160] = WMI_RATE_PREAMBLE_EHT, 598 [WMI_TPC_PREAM_EHT200] = WMI_RATE_PREAMBLE_EHT, 599 [WMI_TPC_PREAM_EHT240] = WMI_RATE_PREAMBLE_EHT, 600 [WMI_TPC_PREAM_EHT280] = WMI_RATE_PREAMBLE_EHT, 601 [WMI_TPC_PREAM_EHT320] = WMI_RATE_PREAMBLE_EHT}; 602 603 chan_freq = le32_to_cpu(tpc_stats->tpc_config.chan_freq); 604 num_tx_chain = le32_to_cpu(tpc_stats->tpc_config.num_tx_chain); 605 caps = le32_to_cpu(tpc_stats->tpc_config.caps); 606 607 active_tx_chains = ar->num_tx_chains; 608 he_ext_mcs = ath12k_he_supports_extra_mcs(ar, chan_freq); 609 610 /* mcs 12&13 is sent by FW for certain HWs in rate array, skipping it as 611 * it is not supported 612 */ 613 if (he_ext_mcs) { 614 for (i = WMI_TPC_PREAM_HE20; i <= WMI_TPC_PREAM_HE160; ++i) 615 max_rates[i] = ATH12K_HE_RATES; 616 } 617 618 if (type == WMI_HALPHY_PDEV_TX_MU_STATS || 619 type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS) { 620 pream_idx = WMI_TPC_PREAM_VHT20; 621 622 for (i = WMI_TPC_PREAM_CCK; i <= WMI_TPC_PREAM_HT40; ++i) 623 max_rix += max_nss[i] * max_rates[i]; 624 } 625 /* Enumerate all the rate indices */ 626 for (i = rate_pream_idx + 1; i < WMI_TPC_PREAM_MAX; i++) { 627 nss = (max_nss[i - 1] < num_tx_chain ? 628 max_nss[i - 1] : num_tx_chain); 629 630 rate_idx[i] = rate_idx[i - 1] + max_rates[i - 1] * nss; 631 632 if (pream_type[i] == WMI_RATE_PREAMBLE_EHT) { 633 eht_rate_idx[j] = eht_rate_idx[j - 1] + max_rates[i] * nss; 634 ++j; 635 } 636 } 637 638 for (i = 0; i < WMI_TPC_PREAM_MAX; i++) { 639 nss = (max_nss[i] < num_tx_chain ? 640 max_nss[i] : num_tx_chain); 641 total_rates += max_rates[i] * nss; 642 } 643 644 len += scnprintf(buf + len, buf_len - len, 645 "No.of rates-%d\n", total_rates); 646 647 len += scnprintf(buf + len, buf_len - len, 648 "**************** %s ****************\n", 649 type_str[type]); 650 len += scnprintf(buf + len, buf_len - len, 651 "\t\t\t\tTPC values for Active chains\n"); 652 len += scnprintf(buf + len, buf_len - len, 653 "Rate idx Preamble Rate code"); 654 655 for (i = 1; i <= active_tx_chains; ++i) { 656 len += scnprintf(buf + len, buf_len - len, 657 "\t%d-Chain", i); 658 } 659 660 len += scnprintf(buf + len, buf_len - len, "\n"); 661 for (i = pream_idx; i < WMI_TPC_PREAM_MAX; i++) { 662 if (chan_freq <= 2483) { 663 if (i == WMI_TPC_PREAM_VHT80 || 664 i == WMI_TPC_PREAM_VHT160 || 665 i == WMI_TPC_PREAM_HE80 || 666 i == WMI_TPC_PREAM_HE160 || 667 (i >= WMI_TPC_PREAM_EHT60 && 668 i <= WMI_TPC_PREAM_EHT320)) { 669 max_rix += max_nss[i] * max_rates[i]; 670 continue; 671 } 672 } else { 673 if (i == WMI_TPC_PREAM_CCK) { 674 max_rix += max_rates[i]; 675 continue; 676 } 677 } 678 679 nss = (max_nss[i] < ar->num_tx_chains ? max_nss[i] : ar->num_tx_chains); 680 681 if (!(caps & 682 (1 << ATH12K_TPC_STATS_SUPPORT_BE_PUNC))) { 683 if (i == WMI_TPC_PREAM_EHT60 || i == WMI_TPC_PREAM_EHT120 || 684 i == WMI_TPC_PREAM_EHT140 || i == WMI_TPC_PREAM_EHT200 || 685 i == WMI_TPC_PREAM_EHT240 || i == WMI_TPC_PREAM_EHT280) { 686 max_rix += max_nss[i] * max_rates[i]; 687 continue; 688 } 689 } 690 691 len = ath12k_tpc_fill_pream(ar, buf, buf_len, len, i, max_rix, nss, 692 max_rates[i], pream_type[i], 693 type, rate_idx[i], eht_rate_idx[eht_idx]); 694 695 if (pream_type[i] == WMI_RATE_PREAMBLE_EHT) 696 /*For fetch the next index eht rates from rates array2*/ 697 ++eht_idx; 698 699 max_rix += max_nss[i] * max_rates[i]; 700 } 701 return len; 702 } 703 704 static void ath12k_tpc_stats_fill(struct ath12k *ar, 705 struct wmi_tpc_stats_arg *tpc_stats, 706 char *buf) 707 { 708 size_t buf_len = ATH12K_TPC_STATS_BUF_SIZE; 709 struct wmi_tpc_config_params *tpc; 710 size_t len = 0; 711 712 if (!tpc_stats) { 713 ath12k_warn(ar->ab, "failed to find tpc stats\n"); 714 return; 715 } 716 717 spin_lock_bh(&ar->data_lock); 718 719 tpc = &tpc_stats->tpc_config; 720 len += scnprintf(buf + len, buf_len - len, "\n"); 721 len += scnprintf(buf + len, buf_len - len, 722 "*************** TPC config **************\n"); 723 len += scnprintf(buf + len, buf_len - len, 724 "* powers are in 0.25 dBm steps\n"); 725 len += scnprintf(buf + len, buf_len - len, 726 "reg domain-%d\t\tchan freq-%d\n", 727 tpc->reg_domain, tpc->chan_freq); 728 len += scnprintf(buf + len, buf_len - len, 729 "power limit-%d\t\tmax reg-domain Power-%d\n", 730 le32_to_cpu(tpc->twice_max_reg_power) / 2, tpc->power_limit); 731 len += scnprintf(buf + len, buf_len - len, 732 "No.of tx chain-%d\t", 733 ar->num_tx_chains); 734 735 ath12k_tpc_stats_print(ar, tpc_stats, buf, len, 736 ar->debug.tpc_stats_type); 737 738 spin_unlock_bh(&ar->data_lock); 739 } 740 741 static int ath12k_open_tpc_stats(struct inode *inode, struct file *file) 742 { 743 struct ath12k *ar = inode->i_private; 744 struct ath12k_hw *ah = ath12k_ar_to_ah(ar); 745 int ret; 746 747 guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy); 748 749 if (ah->state != ATH12K_HW_STATE_ON) { 750 ath12k_warn(ar->ab, "Interface not up\n"); 751 return -ENETDOWN; 752 } 753 754 void *buf __free(kfree) = kzalloc(ATH12K_TPC_STATS_BUF_SIZE, GFP_KERNEL); 755 if (!buf) 756 return -ENOMEM; 757 758 ret = ath12k_debug_tpc_stats_request(ar); 759 if (ret) { 760 ath12k_warn(ar->ab, "failed to request tpc stats: %d\n", 761 ret); 762 return ret; 763 } 764 765 if (!wait_for_completion_timeout(&ar->debug.tpc_complete, TPC_STATS_WAIT_TIME)) { 766 spin_lock_bh(&ar->data_lock); 767 ath12k_wmi_free_tpc_stats_mem(ar); 768 ar->debug.tpc_request = false; 769 spin_unlock_bh(&ar->data_lock); 770 return -ETIMEDOUT; 771 } 772 773 ath12k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf); 774 file->private_data = no_free_ptr(buf); 775 776 spin_lock_bh(&ar->data_lock); 777 ath12k_wmi_free_tpc_stats_mem(ar); 778 spin_unlock_bh(&ar->data_lock); 779 780 return 0; 781 } 782 783 static ssize_t ath12k_read_tpc_stats(struct file *file, 784 char __user *user_buf, 785 size_t count, loff_t *ppos) 786 { 787 const char *buf = file->private_data; 788 size_t len = strlen(buf); 789 790 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 791 } 792 793 static int ath12k_release_tpc_stats(struct inode *inode, 794 struct file *file) 795 { 796 kfree(file->private_data); 797 return 0; 798 } 799 800 static const struct file_operations fops_tpc_stats = { 801 .open = ath12k_open_tpc_stats, 802 .release = ath12k_release_tpc_stats, 803 .read = ath12k_read_tpc_stats, 804 .owner = THIS_MODULE, 805 .llseek = default_llseek, 806 }; 807 808 static const struct file_operations fops_tpc_stats_type = { 809 .write = ath12k_write_tpc_stats_type, 810 .open = simple_open, 811 .llseek = default_llseek, 812 }; 813 814 static ssize_t ath12k_write_extd_rx_stats(struct file *file, 815 const char __user *ubuf, 816 size_t count, loff_t *ppos) 817 { 818 struct ath12k *ar = file->private_data; 819 struct htt_rx_ring_tlv_filter tlv_filter = {}; 820 u32 ring_id, rx_filter = 0; 821 bool enable; 822 int ret, i; 823 824 if (kstrtobool_from_user(ubuf, count, &enable)) 825 return -EINVAL; 826 827 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy); 828 829 if (!ar->ab->hw_params->rxdma1_enable) { 830 ret = count; 831 goto exit; 832 } 833 834 if (ar->ah->state != ATH12K_HW_STATE_ON) { 835 ret = -ENETDOWN; 836 goto exit; 837 } 838 839 if (enable == ar->debug.extd_rx_stats) { 840 ret = count; 841 goto exit; 842 } 843 844 if (enable) { 845 rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START; 846 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START; 847 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END; 848 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS; 849 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT; 850 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE; 851 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO; 852 853 tlv_filter.rx_filter = rx_filter; 854 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0; 855 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1; 856 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2; 857 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 | 858 HTT_RX_FP_DATA_FILTER_FLASG3; 859 } else { 860 tlv_filter = ath12k_mac_mon_status_filter_default; 861 } 862 863 ar->debug.rx_filter = tlv_filter.rx_filter; 864 865 for (i = 0; i < ar->ab->hw_params->num_rxdma_per_pdev; i++) { 866 ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id; 867 ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id + i, 868 HAL_RXDMA_MONITOR_DST, 869 DP_RXDMA_REFILL_RING_SIZE, 870 &tlv_filter); 871 if (ret) { 872 ath12k_warn(ar->ab, "failed to set rx filter for monitor status ring\n"); 873 goto exit; 874 } 875 } 876 877 ar->debug.extd_rx_stats = !!enable; 878 ret = count; 879 exit: 880 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy); 881 return ret; 882 } 883 884 static ssize_t ath12k_read_extd_rx_stats(struct file *file, 885 char __user *ubuf, 886 size_t count, loff_t *ppos) 887 { 888 struct ath12k *ar = file->private_data; 889 char buf[32]; 890 int len = 0; 891 892 wiphy_lock(ath12k_ar_to_hw(ar)->wiphy); 893 len = scnprintf(buf, sizeof(buf) - len, "%d\n", 894 ar->debug.extd_rx_stats); 895 wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy); 896 897 return simple_read_from_buffer(ubuf, count, ppos, buf, len); 898 } 899 900 static const struct file_operations fops_extd_rx_stats = { 901 .read = ath12k_read_extd_rx_stats, 902 .write = ath12k_write_extd_rx_stats, 903 .open = simple_open, 904 }; 905 906 static int ath12k_open_link_stats(struct inode *inode, struct file *file) 907 { 908 struct ath12k_vif *ahvif = inode->i_private; 909 size_t len = 0, buf_len = (PAGE_SIZE * 2); 910 struct ath12k_link_stats linkstat; 911 struct ath12k_link_vif *arvif; 912 unsigned long links_map; 913 struct wiphy *wiphy; 914 int link_id, i; 915 char *buf; 916 917 if (!ahvif) 918 return -EINVAL; 919 920 buf = kzalloc(buf_len, GFP_KERNEL); 921 if (!buf) 922 return -ENOMEM; 923 924 wiphy = ahvif->ah->hw->wiphy; 925 wiphy_lock(wiphy); 926 927 links_map = ahvif->links_map; 928 for_each_set_bit(link_id, &links_map, 929 IEEE80211_MLD_MAX_NUM_LINKS) { 930 arvif = rcu_dereference_protected(ahvif->link[link_id], 931 lockdep_is_held(&wiphy->mtx)); 932 933 spin_lock_bh(&arvif->link_stats_lock); 934 linkstat = arvif->link_stats; 935 spin_unlock_bh(&arvif->link_stats_lock); 936 937 len += scnprintf(buf + len, buf_len - len, 938 "link[%d] Tx Unicast Frames Enqueued = %d\n", 939 link_id, linkstat.tx_enqueued); 940 len += scnprintf(buf + len, buf_len - len, 941 "link[%d] Tx Broadcast Frames Enqueued = %d\n", 942 link_id, linkstat.tx_bcast_mcast); 943 len += scnprintf(buf + len, buf_len - len, 944 "link[%d] Tx Frames Completed = %d\n", 945 link_id, linkstat.tx_completed); 946 len += scnprintf(buf + len, buf_len - len, 947 "link[%d] Tx Frames Dropped = %d\n", 948 link_id, linkstat.tx_dropped); 949 950 len += scnprintf(buf + len, buf_len - len, 951 "link[%d] Tx Frame descriptor Encap Type = ", 952 link_id); 953 954 len += scnprintf(buf + len, buf_len - len, 955 " raw:%d", 956 linkstat.tx_encap_type[0]); 957 958 len += scnprintf(buf + len, buf_len - len, 959 " native_wifi:%d", 960 linkstat.tx_encap_type[1]); 961 962 len += scnprintf(buf + len, buf_len - len, 963 " ethernet:%d", 964 linkstat.tx_encap_type[2]); 965 966 len += scnprintf(buf + len, buf_len - len, 967 "\nlink[%d] Tx Frame descriptor Encrypt Type = ", 968 link_id); 969 970 for (i = 0; i < DP_ENCRYPT_TYPE_MAX; i++) { 971 len += scnprintf(buf + len, buf_len - len, 972 " %d:%d", i, 973 linkstat.tx_encrypt_type[i]); 974 } 975 len += scnprintf(buf + len, buf_len - len, 976 "\nlink[%d] Tx Frame descriptor Type = buffer:%d extension:%d\n", 977 link_id, linkstat.tx_desc_type[0], 978 linkstat.tx_desc_type[1]); 979 980 len += scnprintf(buf + len, buf_len - len, 981 "------------------------------------------------------\n"); 982 } 983 984 wiphy_unlock(wiphy); 985 986 file->private_data = buf; 987 988 return 0; 989 } 990 991 static int ath12k_release_link_stats(struct inode *inode, struct file *file) 992 { 993 kfree(file->private_data); 994 return 0; 995 } 996 997 static ssize_t ath12k_read_link_stats(struct file *file, 998 char __user *user_buf, 999 size_t count, loff_t *ppos) 1000 { 1001 const char *buf = file->private_data; 1002 size_t len = strlen(buf); 1003 1004 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1005 } 1006 1007 static const struct file_operations ath12k_fops_link_stats = { 1008 .open = ath12k_open_link_stats, 1009 .release = ath12k_release_link_stats, 1010 .read = ath12k_read_link_stats, 1011 .owner = THIS_MODULE, 1012 .llseek = default_llseek, 1013 }; 1014 1015 void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw, 1016 struct ieee80211_vif *vif) 1017 { 1018 struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); 1019 1020 debugfs_create_file("link_stats", 0400, vif->debugfs_dir, ahvif, 1021 &ath12k_fops_link_stats); 1022 } 1023 EXPORT_SYMBOL(ath12k_debugfs_op_vif_add); 1024 1025 static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file, 1026 char __user *user_buf, 1027 size_t count, loff_t *ppos) 1028 { 1029 struct ath12k_base *ab = file->private_data; 1030 struct ath12k_dp *dp = ath12k_ab_to_dp(ab); 1031 struct ath12k_device_dp_stats *device_stats = &dp->device_stats; 1032 int len = 0, i, j, ret; 1033 struct ath12k *ar; 1034 const int size = 4096; 1035 static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = { 1036 [HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR] = "Overflow", 1037 [HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR] = "MPDU len", 1038 [HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR] = "FCS", 1039 [HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR] = "Decrypt", 1040 [HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR] = "TKIP MIC", 1041 [HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR] = "Unencrypt", 1042 [HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR] = "MSDU len", 1043 [HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR] = "MSDU limit", 1044 [HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR] = "WiFi parse", 1045 [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR] = "AMSDU parse", 1046 [HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR] = "SA timeout", 1047 [HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR] = "DA timeout", 1048 [HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR] = "Flow timeout", 1049 [HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR] = "Flush req", 1050 [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR] = "AMSDU frag", 1051 [HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR] = "Multicast echo", 1052 [HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR] = "AMSDU mismatch", 1053 [HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR] = "Unauth WDS", 1054 [HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR] = "AMSDU or WDS"}; 1055 1056 static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = { 1057 [HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO] = "Desc addr zero", 1058 [HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID] = "Desc inval", 1059 [HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA] = "AMPDU in non BA", 1060 [HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE] = "Non BA dup", 1061 [HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE] = "BA dup", 1062 [HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP] = "Frame 2k jump", 1063 [HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP] = "BAR 2k jump", 1064 [HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR] = "Frame OOR", 1065 [HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR] = "BAR OOR", 1066 [HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION] = "No BA session", 1067 [HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN] = "Frame SN equal SSN", 1068 [HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED] = "PN check fail", 1069 [HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET] = "2k err", 1070 [HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = "PN err", 1071 [HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = "Desc blocked"}; 1072 1073 static const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = { 1074 [HAL_WBM_REL_SRC_MODULE_TQM] = "TQM", 1075 [HAL_WBM_REL_SRC_MODULE_RXDMA] = "Rxdma", 1076 [HAL_WBM_REL_SRC_MODULE_REO] = "Reo", 1077 [HAL_WBM_REL_SRC_MODULE_FW] = "FW", 1078 [HAL_WBM_REL_SRC_MODULE_SW] = "SW"}; 1079 1080 char *buf __free(kfree) = kzalloc(size, GFP_KERNEL); 1081 1082 if (!buf) 1083 return -ENOMEM; 1084 1085 len += scnprintf(buf + len, size - len, "DEVICE RX STATS:\n\n"); 1086 len += scnprintf(buf + len, size - len, "err ring pkts: %u\n", 1087 device_stats->err_ring_pkts); 1088 len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n", 1089 device_stats->invalid_rbm); 1090 len += scnprintf(buf + len, size - len, "RXDMA errors:\n"); 1091 1092 for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++) 1093 len += scnprintf(buf + len, size - len, "%s: %u\n", 1094 rxdma_err[i], device_stats->rxdma_error[i]); 1095 1096 len += scnprintf(buf + len, size - len, "\nREO errors:\n"); 1097 1098 for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++) 1099 len += scnprintf(buf + len, size - len, "%s: %u\n", 1100 reo_err[i], device_stats->reo_error[i]); 1101 1102 len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n"); 1103 1104 for (i = 0; i < DP_REO_DST_RING_MAX; i++) 1105 len += scnprintf(buf + len, size - len, 1106 "ring%d: %u\n", i, 1107 device_stats->hal_reo_error[i]); 1108 1109 len += scnprintf(buf + len, size - len, "\nDEVICE TX STATS:\n"); 1110 len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n"); 1111 1112 for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) 1113 len += scnprintf(buf + len, size - len, "ring%d: %u\n", 1114 i, device_stats->tx_err.desc_na[i]); 1115 1116 len += scnprintf(buf + len, size - len, 1117 "\nMisc Transmit Failures: %d\n", 1118 atomic_read(&device_stats->tx_err.misc_fail)); 1119 1120 len += scnprintf(buf + len, size - len, "\ntx_wbm_rel_source:"); 1121 1122 for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) 1123 len += scnprintf(buf + len, size - len, " %d:%u", 1124 i, device_stats->tx_wbm_rel_source[i]); 1125 1126 len += scnprintf(buf + len, size - len, "\n"); 1127 1128 len += scnprintf(buf + len, size - len, "\ntqm_rel_reason:"); 1129 1130 for (i = 0; i < MAX_TQM_RELEASE_REASON; i++) 1131 len += scnprintf(buf + len, size - len, " %d:%u", 1132 i, device_stats->tqm_rel_reason[i]); 1133 1134 len += scnprintf(buf + len, size - len, "\n"); 1135 1136 len += scnprintf(buf + len, size - len, "\nfw_tx_status:"); 1137 1138 for (i = 0; i < MAX_FW_TX_STATUS; i++) 1139 len += scnprintf(buf + len, size - len, " %d:%u", 1140 i, device_stats->fw_tx_status[i]); 1141 1142 len += scnprintf(buf + len, size - len, "\n"); 1143 1144 len += scnprintf(buf + len, size - len, "\ntx_enqueued:"); 1145 1146 for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) 1147 len += scnprintf(buf + len, size - len, " %d:%u", i, 1148 device_stats->tx_enqueued[i]); 1149 1150 len += scnprintf(buf + len, size - len, "\n"); 1151 1152 len += scnprintf(buf + len, size - len, "\ntx_completed:"); 1153 1154 for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) 1155 len += scnprintf(buf + len, size - len, " %d:%u", 1156 i, device_stats->tx_completed[i]); 1157 1158 len += scnprintf(buf + len, size - len, "\n"); 1159 1160 rcu_read_lock(); 1161 for (i = 0; i < ab->num_radios; i++) { 1162 ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i)); 1163 if (ar) { 1164 len += scnprintf(buf + len, size - len, 1165 "\nradio%d tx_pending: %u\n", i, 1166 atomic_read(&ar->dp.num_tx_pending)); 1167 } 1168 } 1169 rcu_read_unlock(); 1170 1171 len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n"); 1172 1173 for (i = 0; i < DP_REO_DST_RING_MAX; i++) { 1174 len += scnprintf(buf + len, size - len, "Ring%d:", i + 1); 1175 1176 for (j = 0; j < ATH12K_MAX_DEVICES; j++) { 1177 len += scnprintf(buf + len, size - len, 1178 "\t%d:%u", j, 1179 device_stats->reo_rx[i][j]); 1180 } 1181 1182 len += scnprintf(buf + len, size - len, "\n"); 1183 } 1184 1185 len += scnprintf(buf + len, size - len, "\nREO excep MSDU buf type:%u\n", 1186 device_stats->reo_excep_msdu_buf_type); 1187 1188 len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n"); 1189 1190 for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) { 1191 len += scnprintf(buf + len, size - len, "%s:", wbm_rel_src[i]); 1192 1193 for (j = 0; j < ATH12K_MAX_DEVICES; j++) { 1194 len += scnprintf(buf + len, 1195 size - len, 1196 "\t%d:%u", j, 1197 device_stats->rx_wbm_rel_source[i][j]); 1198 } 1199 1200 len += scnprintf(buf + len, size - len, "\n"); 1201 } 1202 1203 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1204 1205 return ret; 1206 } 1207 1208 static const struct file_operations fops_device_dp_stats = { 1209 .read = ath12k_debugfs_dump_device_dp_stats, 1210 .open = simple_open, 1211 .owner = THIS_MODULE, 1212 .llseek = default_llseek, 1213 }; 1214 1215 void ath12k_debugfs_pdev_create(struct ath12k_base *ab) 1216 { 1217 debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab, 1218 &fops_simulate_fw_crash); 1219 1220 debugfs_create_file("device_dp_stats", 0400, ab->debugfs_soc, ab, 1221 &fops_device_dp_stats); 1222 } 1223 1224 void ath12k_debugfs_soc_create(struct ath12k_base *ab) 1225 { 1226 bool dput_needed; 1227 char soc_name[64] = {}; 1228 struct dentry *debugfs_ath12k; 1229 1230 debugfs_ath12k = debugfs_lookup("ath12k", NULL); 1231 if (debugfs_ath12k) { 1232 /* a dentry from lookup() needs dput() after we don't use it */ 1233 dput_needed = true; 1234 } else { 1235 debugfs_ath12k = debugfs_create_dir("ath12k", NULL); 1236 if (IS_ERR_OR_NULL(debugfs_ath12k)) 1237 return; 1238 dput_needed = false; 1239 } 1240 1241 scnprintf(soc_name, sizeof(soc_name), "%s-%s", ath12k_bus_str(ab->hif.bus), 1242 dev_name(ab->dev)); 1243 1244 ab->debugfs_soc = debugfs_create_dir(soc_name, debugfs_ath12k); 1245 1246 if (dput_needed) 1247 dput(debugfs_ath12k); 1248 } 1249 1250 void ath12k_debugfs_soc_destroy(struct ath12k_base *ab) 1251 { 1252 debugfs_remove_recursive(ab->debugfs_soc); 1253 ab->debugfs_soc = NULL; 1254 /* We are not removing ath12k directory on purpose, even if it 1255 * would be empty. This simplifies the directory handling and it's 1256 * a minor cosmetic issue to leave an empty ath12k directory to 1257 * debugfs. 1258 */ 1259 } 1260 1261 static int ath12k_open_vdev_stats(struct inode *inode, struct file *file) 1262 { 1263 struct ath12k *ar = inode->i_private; 1264 struct ath12k_fw_stats_req_params param; 1265 struct ath12k_hw *ah = ath12k_ar_to_ah(ar); 1266 int ret; 1267 1268 guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy); 1269 1270 if (!ah) 1271 return -ENETDOWN; 1272 1273 if (ah->state != ATH12K_HW_STATE_ON) 1274 return -ENETDOWN; 1275 1276 void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC); 1277 if (!buf) 1278 return -ENOMEM; 1279 1280 param.pdev_id = ath12k_mac_get_target_pdev_id(ar); 1281 /* VDEV stats is always sent for all active VDEVs from FW */ 1282 param.vdev_id = 0; 1283 param.stats_id = WMI_REQUEST_VDEV_STAT; 1284 1285 ret = ath12k_mac_get_fw_stats(ar, ¶m); 1286 if (ret) { 1287 ath12k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret); 1288 return ret; 1289 } 1290 1291 ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id, 1292 buf); 1293 ath12k_fw_stats_reset(ar); 1294 1295 file->private_data = no_free_ptr(buf); 1296 1297 return 0; 1298 } 1299 1300 static int ath12k_release_vdev_stats(struct inode *inode, struct file *file) 1301 { 1302 kfree(file->private_data); 1303 1304 return 0; 1305 } 1306 1307 static ssize_t ath12k_read_vdev_stats(struct file *file, 1308 char __user *user_buf, 1309 size_t count, loff_t *ppos) 1310 { 1311 const char *buf = file->private_data; 1312 size_t len = strlen(buf); 1313 1314 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1315 } 1316 1317 static const struct file_operations fops_vdev_stats = { 1318 .open = ath12k_open_vdev_stats, 1319 .release = ath12k_release_vdev_stats, 1320 .read = ath12k_read_vdev_stats, 1321 .owner = THIS_MODULE, 1322 .llseek = default_llseek, 1323 }; 1324 1325 static int ath12k_open_bcn_stats(struct inode *inode, struct file *file) 1326 { 1327 struct ath12k *ar = inode->i_private; 1328 struct ath12k_link_vif *arvif; 1329 struct ath12k_fw_stats_req_params param; 1330 struct ath12k_hw *ah = ath12k_ar_to_ah(ar); 1331 int ret; 1332 1333 guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy); 1334 1335 if (ah && ah->state != ATH12K_HW_STATE_ON) 1336 return -ENETDOWN; 1337 1338 void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC); 1339 if (!buf) 1340 return -ENOMEM; 1341 1342 param.pdev_id = ath12k_mac_get_target_pdev_id(ar); 1343 param.stats_id = WMI_REQUEST_BCN_STAT; 1344 1345 /* loop all active VDEVs for bcn stats */ 1346 list_for_each_entry(arvif, &ar->arvifs, list) { 1347 if (!arvif->is_up) 1348 continue; 1349 1350 param.vdev_id = arvif->vdev_id; 1351 ret = ath12k_mac_get_fw_stats(ar, ¶m); 1352 if (ret) { 1353 ath12k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret); 1354 return ret; 1355 } 1356 } 1357 1358 ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id, 1359 buf); 1360 ath12k_fw_stats_reset(ar); 1361 1362 file->private_data = no_free_ptr(buf); 1363 1364 return 0; 1365 } 1366 1367 static int ath12k_release_bcn_stats(struct inode *inode, struct file *file) 1368 { 1369 kfree(file->private_data); 1370 1371 return 0; 1372 } 1373 1374 static ssize_t ath12k_read_bcn_stats(struct file *file, 1375 char __user *user_buf, 1376 size_t count, loff_t *ppos) 1377 { 1378 const char *buf = file->private_data; 1379 size_t len = strlen(buf); 1380 1381 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1382 } 1383 1384 static const struct file_operations fops_bcn_stats = { 1385 .open = ath12k_open_bcn_stats, 1386 .release = ath12k_release_bcn_stats, 1387 .read = ath12k_read_bcn_stats, 1388 .owner = THIS_MODULE, 1389 .llseek = default_llseek, 1390 }; 1391 1392 static int ath12k_open_pdev_stats(struct inode *inode, struct file *file) 1393 { 1394 struct ath12k *ar = inode->i_private; 1395 struct ath12k_hw *ah = ath12k_ar_to_ah(ar); 1396 struct ath12k_base *ab = ar->ab; 1397 struct ath12k_fw_stats_req_params param; 1398 int ret; 1399 1400 guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy); 1401 1402 if (ah && ah->state != ATH12K_HW_STATE_ON) 1403 return -ENETDOWN; 1404 1405 void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC); 1406 if (!buf) 1407 return -ENOMEM; 1408 1409 param.pdev_id = ath12k_mac_get_target_pdev_id(ar); 1410 param.vdev_id = 0; 1411 param.stats_id = WMI_REQUEST_PDEV_STAT; 1412 1413 ret = ath12k_mac_get_fw_stats(ar, ¶m); 1414 if (ret) { 1415 ath12k_warn(ab, "failed to request fw pdev stats: %d\n", ret); 1416 return ret; 1417 } 1418 1419 ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id, 1420 buf); 1421 ath12k_fw_stats_reset(ar); 1422 1423 file->private_data = no_free_ptr(buf); 1424 1425 return 0; 1426 } 1427 1428 static int ath12k_release_pdev_stats(struct inode *inode, struct file *file) 1429 { 1430 kfree(file->private_data); 1431 1432 return 0; 1433 } 1434 1435 static ssize_t ath12k_read_pdev_stats(struct file *file, 1436 char __user *user_buf, 1437 size_t count, loff_t *ppos) 1438 { 1439 const char *buf = file->private_data; 1440 size_t len = strlen(buf); 1441 1442 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1443 } 1444 1445 static const struct file_operations fops_pdev_stats = { 1446 .open = ath12k_open_pdev_stats, 1447 .release = ath12k_release_pdev_stats, 1448 .read = ath12k_read_pdev_stats, 1449 .owner = THIS_MODULE, 1450 .llseek = default_llseek, 1451 }; 1452 1453 static 1454 void ath12k_debugfs_fw_stats_register(struct ath12k *ar) 1455 { 1456 struct dentry *fwstats_dir = debugfs_create_dir("fw_stats", 1457 ar->debug.debugfs_pdev); 1458 1459 /* all stats debugfs files created are under "fw_stats" directory 1460 * created per PDEV 1461 */ 1462 debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar, 1463 &fops_vdev_stats); 1464 debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar, 1465 &fops_bcn_stats); 1466 debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar, 1467 &fops_pdev_stats); 1468 1469 ath12k_fw_stats_init(ar); 1470 } 1471 1472 void ath12k_debugfs_register(struct ath12k *ar) 1473 { 1474 struct ath12k_base *ab = ar->ab; 1475 struct ieee80211_hw *hw = ar->ah->hw; 1476 char pdev_name[5]; 1477 char buf[100] = {}; 1478 1479 scnprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx); 1480 1481 ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); 1482 1483 /* Create a symlink under ieee80211/phy* */ 1484 scnprintf(buf, sizeof(buf), "../../ath12k/%pd2", ar->debug.debugfs_pdev); 1485 ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k", 1486 hw->wiphy->debugfsdir, 1487 buf); 1488 1489 if (ar->mac.sbands[NL80211_BAND_5GHZ].channels) { 1490 debugfs_create_file("dfs_simulate_radar", 0200, 1491 ar->debug.debugfs_pdev, ar, 1492 &fops_simulate_radar); 1493 } 1494 1495 debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_pdev, ar, 1496 &fops_tpc_stats); 1497 debugfs_create_file("tpc_stats_type", 0200, ar->debug.debugfs_pdev, 1498 ar, &fops_tpc_stats_type); 1499 init_completion(&ar->debug.tpc_complete); 1500 1501 ath12k_debugfs_htt_stats_register(ar); 1502 ath12k_debugfs_fw_stats_register(ar); 1503 1504 debugfs_create_file("ext_rx_stats", 0644, 1505 ar->debug.debugfs_pdev, ar, 1506 &fops_extd_rx_stats); 1507 } 1508 1509 void ath12k_debugfs_unregister(struct ath12k *ar) 1510 { 1511 if (!ar->debug.debugfs_pdev) 1512 return; 1513 1514 /* Remove symlink under ieee80211/phy* */ 1515 debugfs_remove(ar->debug.debugfs_pdev_symlink); 1516 debugfs_remove_recursive(ar->debug.debugfs_pdev); 1517 ar->debug.debugfs_pdev_symlink = NULL; 1518 ar->debug.debugfs_pdev = NULL; 1519 } 1520