1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 4 #include <linux/relay.h> 5 #include "mt7915.h" 6 #include "eeprom.h" 7 #include "mcu.h" 8 #include "mac.h" 9 10 #define FW_BIN_LOG_MAGIC 0x44e98caf 11 12 /** global debugfs **/ 13 14 struct hw_queue_map { 15 const char *name; 16 u8 index; 17 u8 pid; 18 u8 qid; 19 }; 20 21 static int 22 mt7915_implicit_txbf_set(void *data, u64 val) 23 { 24 struct mt7915_dev *dev = data; 25 26 /* The existing connected stations shall reconnect to apply 27 * new implicit txbf configuration. 28 */ 29 dev->ibf = !!val; 30 31 return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE); 32 } 33 34 static int 35 mt7915_implicit_txbf_get(void *data, u64 *val) 36 { 37 struct mt7915_dev *dev = data; 38 39 *val = dev->ibf; 40 41 return 0; 42 } 43 44 DEFINE_DEBUGFS_ATTRIBUTE(fops_implicit_txbf, mt7915_implicit_txbf_get, 45 mt7915_implicit_txbf_set, "%lld\n"); 46 47 /* test knob of system error recovery */ 48 static ssize_t 49 mt7915_sys_recovery_set(struct file *file, const char __user *user_buf, 50 size_t count, loff_t *ppos) 51 { 52 struct mt7915_phy *phy = file->private_data; 53 struct mt7915_dev *dev = phy->dev; 54 bool band = phy->mt76->band_idx; 55 int ret = 0; 56 u16 val; 57 58 ret = kstrtou16_from_user(user_buf, count, 0, &val); 59 if (ret) 60 return ret; 61 62 switch (val) { 63 /* 64 * 0: grab firmware current SER state. 65 * 1: trigger & enable system error L1 recovery. 66 * 2: trigger & enable system error L2 recovery. 67 * 3: trigger & enable system error L3 rx abort. 68 * 4: trigger & enable system error L3 tx abort 69 * 5: trigger & enable system error L3 tx disable. 70 * 6: trigger & enable system error L3 bf recovery. 71 * 7: trigger & enable system error full recovery. 72 * 8: trigger firmware crash. 73 */ 74 case SER_QUERY: 75 ret = mt7915_mcu_set_ser(dev, 0, 0, band); 76 break; 77 case SER_SET_RECOVER_L1: 78 case SER_SET_RECOVER_L2: 79 case SER_SET_RECOVER_L3_RX_ABORT: 80 case SER_SET_RECOVER_L3_TX_ABORT: 81 case SER_SET_RECOVER_L3_TX_DISABLE: 82 case SER_SET_RECOVER_L3_BF: 83 ret = mt7915_mcu_set_ser(dev, SER_ENABLE, BIT(val), band); 84 if (ret) 85 return ret; 86 87 ret = mt7915_mcu_set_ser(dev, SER_RECOVER, val, band); 88 break; 89 90 /* enable full chip reset */ 91 case SER_SET_RECOVER_FULL: 92 mt76_set(dev, MT_WFDMA0_MCU_HOST_INT_ENA, MT_MCU_CMD_WDT_MASK); 93 ret = mt7915_mcu_set_ser(dev, 1, 3, band); 94 if (ret) 95 return ret; 96 97 dev->recovery.state |= MT_MCU_CMD_WDT_MASK; 98 mt7915_reset(dev); 99 break; 100 101 /* WARNING: trigger firmware crash */ 102 case SER_SET_SYSTEM_ASSERT: 103 mt76_wr(dev, MT_MCU_WM_CIRQ_EINT_MASK_CLR_ADDR, BIT(18)); 104 mt76_wr(dev, MT_MCU_WM_CIRQ_EINT_SOFT_ADDR, BIT(18)); 105 break; 106 default: 107 break; 108 } 109 110 return ret ? ret : count; 111 } 112 113 static ssize_t 114 mt7915_sys_recovery_get(struct file *file, char __user *user_buf, 115 size_t count, loff_t *ppos) 116 { 117 struct mt7915_phy *phy = file->private_data; 118 struct mt7915_dev *dev = phy->dev; 119 char *buff; 120 int desc = 0; 121 ssize_t ret; 122 static const size_t bufsz = 1024; 123 124 buff = kmalloc(bufsz, GFP_KERNEL); 125 if (!buff) 126 return -ENOMEM; 127 128 /* HELP */ 129 desc += scnprintf(buff + desc, bufsz - desc, 130 "Please echo the correct value ...\n"); 131 desc += scnprintf(buff + desc, bufsz - desc, 132 "0: grab firmware transient SER state\n"); 133 desc += scnprintf(buff + desc, bufsz - desc, 134 "1: trigger system error L1 recovery\n"); 135 desc += scnprintf(buff + desc, bufsz - desc, 136 "2: trigger system error L2 recovery\n"); 137 desc += scnprintf(buff + desc, bufsz - desc, 138 "3: trigger system error L3 rx abort\n"); 139 desc += scnprintf(buff + desc, bufsz - desc, 140 "4: trigger system error L3 tx abort\n"); 141 desc += scnprintf(buff + desc, bufsz - desc, 142 "5: trigger system error L3 tx disable\n"); 143 desc += scnprintf(buff + desc, bufsz - desc, 144 "6: trigger system error L3 bf recovery\n"); 145 desc += scnprintf(buff + desc, bufsz - desc, 146 "7: trigger system error full recovery\n"); 147 desc += scnprintf(buff + desc, bufsz - desc, 148 "8: trigger firmware crash\n"); 149 150 /* SER statistics */ 151 desc += scnprintf(buff + desc, bufsz - desc, 152 "\nlet's dump firmware SER statistics...\n"); 153 desc += scnprintf(buff + desc, bufsz - desc, 154 "::E R , SER_STATUS = 0x%08x\n", 155 mt76_rr(dev, MT_SWDEF_SER_STATS)); 156 desc += scnprintf(buff + desc, bufsz - desc, 157 "::E R , SER_PLE_ERR = 0x%08x\n", 158 mt76_rr(dev, MT_SWDEF_PLE_STATS)); 159 desc += scnprintf(buff + desc, bufsz - desc, 160 "::E R , SER_PLE_ERR_1 = 0x%08x\n", 161 mt76_rr(dev, MT_SWDEF_PLE1_STATS)); 162 desc += scnprintf(buff + desc, bufsz - desc, 163 "::E R , SER_PLE_ERR_AMSDU = 0x%08x\n", 164 mt76_rr(dev, MT_SWDEF_PLE_AMSDU_STATS)); 165 desc += scnprintf(buff + desc, bufsz - desc, 166 "::E R , SER_PSE_ERR = 0x%08x\n", 167 mt76_rr(dev, MT_SWDEF_PSE_STATS)); 168 desc += scnprintf(buff + desc, bufsz - desc, 169 "::E R , SER_PSE_ERR_1 = 0x%08x\n", 170 mt76_rr(dev, MT_SWDEF_PSE1_STATS)); 171 desc += scnprintf(buff + desc, bufsz - desc, 172 "::E R , SER_LMAC_WISR6_B0 = 0x%08x\n", 173 mt76_rr(dev, MT_SWDEF_LAMC_WISR6_BN0_STATS)); 174 desc += scnprintf(buff + desc, bufsz - desc, 175 "::E R , SER_LMAC_WISR6_B1 = 0x%08x\n", 176 mt76_rr(dev, MT_SWDEF_LAMC_WISR6_BN1_STATS)); 177 desc += scnprintf(buff + desc, bufsz - desc, 178 "::E R , SER_LMAC_WISR7_B0 = 0x%08x\n", 179 mt76_rr(dev, MT_SWDEF_LAMC_WISR7_BN0_STATS)); 180 desc += scnprintf(buff + desc, bufsz - desc, 181 "::E R , SER_LMAC_WISR7_B1 = 0x%08x\n", 182 mt76_rr(dev, MT_SWDEF_LAMC_WISR7_BN1_STATS)); 183 desc += scnprintf(buff + desc, bufsz - desc, 184 "\nSYS_RESET_COUNT: WM %d, WA %d\n", 185 dev->recovery.wm_reset_count, 186 dev->recovery.wa_reset_count); 187 188 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 189 kfree(buff); 190 return ret; 191 } 192 193 static const struct file_operations mt7915_sys_recovery_ops = { 194 .write = mt7915_sys_recovery_set, 195 .read = mt7915_sys_recovery_get, 196 .open = simple_open, 197 .llseek = default_llseek, 198 }; 199 200 static int 201 mt7915_radar_trigger(void *data, u64 val) 202 { 203 #define RADAR_MAIN_CHAIN 1 204 #define RADAR_BACKGROUND 2 205 struct mt7915_phy *phy = data; 206 struct mt7915_dev *dev = phy->dev; 207 int rdd_idx; 208 209 if (!val || val > RADAR_BACKGROUND) 210 return -EINVAL; 211 212 if (val == RADAR_BACKGROUND && !dev->rdd2_phy) { 213 dev_err(dev->mt76.dev, "Background radar is not enabled\n"); 214 return -EINVAL; 215 } 216 217 rdd_idx = mt7915_get_rdd_idx(phy, val == RADAR_BACKGROUND); 218 if (rdd_idx < 0) { 219 dev_err(dev->mt76.dev, "No RDD found\n"); 220 return -EINVAL; 221 } 222 223 return mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_RADAR_EMULATE, 224 rdd_idx, 0, 0); 225 } 226 227 DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL, 228 mt7915_radar_trigger, "%lld\n"); 229 230 static int 231 mt7915_muru_debug_set(void *data, u64 val) 232 { 233 struct mt7915_dev *dev = data; 234 235 dev->muru_debug = val; 236 mt7915_mcu_muru_debug_set(dev, dev->muru_debug); 237 238 return 0; 239 } 240 241 static int 242 mt7915_muru_debug_get(void *data, u64 *val) 243 { 244 struct mt7915_dev *dev = data; 245 246 *val = dev->muru_debug; 247 248 return 0; 249 } 250 251 DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_debug, mt7915_muru_debug_get, 252 mt7915_muru_debug_set, "%lld\n"); 253 254 static int mt7915_muru_stats_show(struct seq_file *file, void *data) 255 { 256 struct mt7915_phy *phy = file->private; 257 struct mt7915_dev *dev = phy->dev; 258 static const char * const dl_non_he_type[] = { 259 "CCK", "OFDM", "HT MIX", "HT GF", 260 "VHT SU", "VHT 2MU", "VHT 3MU", "VHT 4MU" 261 }; 262 static const char * const dl_he_type[] = { 263 "HE SU", "HE EXT", "HE 2MU", "HE 3MU", "HE 4MU", 264 "HE 2RU", "HE 3RU", "HE 4RU", "HE 5-8RU", "HE 9-16RU", 265 "HE >16RU" 266 }; 267 static const char * const ul_he_type[] = { 268 "HE 2MU", "HE 3MU", "HE 4MU", "HE SU", "HE 2RU", 269 "HE 3RU", "HE 4RU", "HE 5-8RU", "HE 9-16RU", "HE >16RU" 270 }; 271 int ret, i; 272 u64 total_ppdu_cnt, sub_total_cnt; 273 274 if (!dev->muru_debug) { 275 seq_puts(file, "Please enable muru_debug first.\n"); 276 return 0; 277 } 278 279 mutex_lock(&dev->mt76.mutex); 280 281 ret = mt7915_mcu_muru_debug_get(phy); 282 if (ret) 283 goto exit; 284 285 /* Non-HE Downlink*/ 286 seq_puts(file, "[Non-HE]\nDownlink\nData Type: "); 287 288 for (i = 0; i < 5; i++) 289 seq_printf(file, "%8s | ", dl_non_he_type[i]); 290 291 seq_puts(file, "\nTotal Count:"); 292 seq_printf(file, "%8u | %8u | %8u | %8u | %8u | ", 293 phy->mib.dl_cck_cnt, 294 phy->mib.dl_ofdm_cnt, 295 phy->mib.dl_htmix_cnt, 296 phy->mib.dl_htgf_cnt, 297 phy->mib.dl_vht_su_cnt); 298 299 seq_puts(file, "\nDownlink MU-MIMO\nData Type: "); 300 301 for (i = 5; i < 8; i++) 302 seq_printf(file, "%8s | ", dl_non_he_type[i]); 303 304 seq_puts(file, "\nTotal Count:"); 305 seq_printf(file, "%8u | %8u | %8u | ", 306 phy->mib.dl_vht_2mu_cnt, 307 phy->mib.dl_vht_3mu_cnt, 308 phy->mib.dl_vht_4mu_cnt); 309 310 sub_total_cnt = (u64)phy->mib.dl_vht_2mu_cnt + 311 phy->mib.dl_vht_3mu_cnt + 312 phy->mib.dl_vht_4mu_cnt; 313 314 seq_printf(file, "\nTotal non-HE MU-MIMO DL PPDU count: %lld", 315 sub_total_cnt); 316 317 total_ppdu_cnt = sub_total_cnt + 318 phy->mib.dl_cck_cnt + 319 phy->mib.dl_ofdm_cnt + 320 phy->mib.dl_htmix_cnt + 321 phy->mib.dl_htgf_cnt + 322 phy->mib.dl_vht_su_cnt; 323 324 seq_printf(file, "\nAll non-HE DL PPDU count: %lld", total_ppdu_cnt); 325 326 /* HE Downlink */ 327 seq_puts(file, "\n\n[HE]\nDownlink\nData Type: "); 328 329 for (i = 0; i < 2; i++) 330 seq_printf(file, "%8s | ", dl_he_type[i]); 331 332 seq_puts(file, "\nTotal Count:"); 333 seq_printf(file, "%8u | %8u | ", 334 phy->mib.dl_he_su_cnt, phy->mib.dl_he_ext_su_cnt); 335 336 seq_puts(file, "\nDownlink MU-MIMO\nData Type: "); 337 338 for (i = 2; i < 5; i++) 339 seq_printf(file, "%8s | ", dl_he_type[i]); 340 341 seq_puts(file, "\nTotal Count:"); 342 seq_printf(file, "%8u | %8u | %8u | ", 343 phy->mib.dl_he_2mu_cnt, phy->mib.dl_he_3mu_cnt, 344 phy->mib.dl_he_4mu_cnt); 345 346 seq_puts(file, "\nDownlink OFDMA\nData Type: "); 347 348 for (i = 5; i < 11; i++) 349 seq_printf(file, "%8s | ", dl_he_type[i]); 350 351 seq_puts(file, "\nTotal Count:"); 352 seq_printf(file, "%8u | %8u | %8u | %8u | %9u | %8u | ", 353 phy->mib.dl_he_2ru_cnt, 354 phy->mib.dl_he_3ru_cnt, 355 phy->mib.dl_he_4ru_cnt, 356 phy->mib.dl_he_5to8ru_cnt, 357 phy->mib.dl_he_9to16ru_cnt, 358 phy->mib.dl_he_gtr16ru_cnt); 359 360 sub_total_cnt = (u64)phy->mib.dl_he_2mu_cnt + 361 phy->mib.dl_he_3mu_cnt + 362 phy->mib.dl_he_4mu_cnt; 363 total_ppdu_cnt = sub_total_cnt; 364 365 seq_printf(file, "\nTotal HE MU-MIMO DL PPDU count: %lld", 366 sub_total_cnt); 367 368 sub_total_cnt = (u64)phy->mib.dl_he_2ru_cnt + 369 phy->mib.dl_he_3ru_cnt + 370 phy->mib.dl_he_4ru_cnt + 371 phy->mib.dl_he_5to8ru_cnt + 372 phy->mib.dl_he_9to16ru_cnt + 373 phy->mib.dl_he_gtr16ru_cnt; 374 total_ppdu_cnt += sub_total_cnt; 375 376 seq_printf(file, "\nTotal HE OFDMA DL PPDU count: %lld", 377 sub_total_cnt); 378 379 total_ppdu_cnt += (u64)phy->mib.dl_he_su_cnt + 380 phy->mib.dl_he_ext_su_cnt; 381 382 seq_printf(file, "\nAll HE DL PPDU count: %lld", total_ppdu_cnt); 383 384 /* HE Uplink */ 385 seq_puts(file, "\n\nUplink"); 386 seq_puts(file, "\nTrigger-based Uplink MU-MIMO\nData Type: "); 387 388 for (i = 0; i < 3; i++) 389 seq_printf(file, "%8s | ", ul_he_type[i]); 390 391 seq_puts(file, "\nTotal Count:"); 392 seq_printf(file, "%8u | %8u | %8u | ", 393 phy->mib.ul_hetrig_2mu_cnt, 394 phy->mib.ul_hetrig_3mu_cnt, 395 phy->mib.ul_hetrig_4mu_cnt); 396 397 seq_puts(file, "\nTrigger-based Uplink OFDMA\nData Type: "); 398 399 for (i = 3; i < 10; i++) 400 seq_printf(file, "%8s | ", ul_he_type[i]); 401 402 seq_puts(file, "\nTotal Count:"); 403 seq_printf(file, "%8u | %8u | %8u | %8u | %8u | %9u | %7u | ", 404 phy->mib.ul_hetrig_su_cnt, 405 phy->mib.ul_hetrig_2ru_cnt, 406 phy->mib.ul_hetrig_3ru_cnt, 407 phy->mib.ul_hetrig_4ru_cnt, 408 phy->mib.ul_hetrig_5to8ru_cnt, 409 phy->mib.ul_hetrig_9to16ru_cnt, 410 phy->mib.ul_hetrig_gtr16ru_cnt); 411 412 sub_total_cnt = (u64)phy->mib.ul_hetrig_2mu_cnt + 413 phy->mib.ul_hetrig_3mu_cnt + 414 phy->mib.ul_hetrig_4mu_cnt; 415 total_ppdu_cnt = sub_total_cnt; 416 417 seq_printf(file, "\nTotal HE MU-MIMO UL TB PPDU count: %lld", 418 sub_total_cnt); 419 420 sub_total_cnt = (u64)phy->mib.ul_hetrig_2ru_cnt + 421 phy->mib.ul_hetrig_3ru_cnt + 422 phy->mib.ul_hetrig_4ru_cnt + 423 phy->mib.ul_hetrig_5to8ru_cnt + 424 phy->mib.ul_hetrig_9to16ru_cnt + 425 phy->mib.ul_hetrig_gtr16ru_cnt; 426 total_ppdu_cnt += sub_total_cnt; 427 428 seq_printf(file, "\nTotal HE OFDMA UL TB PPDU count: %lld", 429 sub_total_cnt); 430 431 total_ppdu_cnt += phy->mib.ul_hetrig_su_cnt; 432 433 seq_printf(file, "\nAll HE UL TB PPDU count: %lld\n", total_ppdu_cnt); 434 435 exit: 436 mutex_unlock(&dev->mt76.mutex); 437 438 return ret; 439 } 440 DEFINE_SHOW_ATTRIBUTE(mt7915_muru_stats); 441 442 static int 443 mt7915_rdd_monitor(struct seq_file *s, void *data) 444 { 445 struct mt7915_dev *dev = dev_get_drvdata(s->private); 446 struct cfg80211_chan_def *chandef = &dev->rdd2_chandef; 447 const char *bw; 448 int ret = 0; 449 450 mutex_lock(&dev->mt76.mutex); 451 452 if (!mt7915_eeprom_has_background_radar(dev)) { 453 seq_puts(s, "no background radar capability\n"); 454 goto out; 455 } 456 457 if (!cfg80211_chandef_valid(chandef)) { 458 ret = -EINVAL; 459 goto out; 460 } 461 462 if (!dev->rdd2_phy) { 463 seq_puts(s, "not running\n"); 464 goto out; 465 } 466 467 switch (chandef->width) { 468 case NL80211_CHAN_WIDTH_40: 469 bw = "40"; 470 break; 471 case NL80211_CHAN_WIDTH_80: 472 bw = "80"; 473 break; 474 case NL80211_CHAN_WIDTH_160: 475 bw = "160"; 476 break; 477 case NL80211_CHAN_WIDTH_80P80: 478 bw = "80P80"; 479 break; 480 default: 481 bw = "20"; 482 break; 483 } 484 485 seq_printf(s, "channel %d (%d MHz) width %s MHz center1: %d MHz\n", 486 chandef->chan->hw_value, chandef->chan->center_freq, 487 bw, chandef->center_freq1); 488 out: 489 mutex_unlock(&dev->mt76.mutex); 490 491 return ret; 492 } 493 494 static int 495 mt7915_fw_debug_wm_set(void *data, u64 val) 496 { 497 struct mt7915_dev *dev = data; 498 enum { 499 DEBUG_TXCMD = 62, 500 DEBUG_CMD_RPT_TX, 501 DEBUG_CMD_RPT_TRIG, 502 DEBUG_SPL, 503 DEBUG_RPT_RX, 504 } debug; 505 bool tx, rx, en; 506 int ret; 507 508 dev->fw.debug_wm = val ? MCU_FW_LOG_TO_HOST : 0; 509 510 if (dev->fw.debug_bin) 511 val = 16; 512 else 513 val = dev->fw.debug_wm; 514 515 tx = dev->fw.debug_wm || (dev->fw.debug_bin & BIT(1)); 516 rx = dev->fw.debug_wm || (dev->fw.debug_bin & BIT(2)); 517 en = dev->fw.debug_wm || (dev->fw.debug_bin & BIT(0)); 518 519 ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, val); 520 if (ret) 521 goto out; 522 523 for (debug = DEBUG_TXCMD; debug <= DEBUG_RPT_RX; debug++) { 524 if (debug == DEBUG_RPT_RX) 525 val = en && rx; 526 else 527 val = en && tx; 528 529 ret = mt7915_mcu_fw_dbg_ctrl(dev, debug, val); 530 if (ret) 531 goto out; 532 } 533 534 /* WM CPU info record control */ 535 mt76_clear(dev, MT_CPU_UTIL_CTRL, BIT(0)); 536 mt76_wr(dev, MT_DIC_CMD_REG_CMD, BIT(2) | BIT(13) | 537 (dev->fw.debug_wm ? 0 : BIT(0))); 538 mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR, BIT(5)); 539 mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR, BIT(5)); 540 541 out: 542 if (ret) 543 dev->fw.debug_wm = 0; 544 545 return ret; 546 } 547 548 static int 549 mt7915_fw_debug_wm_get(void *data, u64 *val) 550 { 551 struct mt7915_dev *dev = data; 552 553 *val = dev->fw.debug_wm; 554 555 return 0; 556 } 557 558 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wm, mt7915_fw_debug_wm_get, 559 mt7915_fw_debug_wm_set, "%lld\n"); 560 561 static int 562 mt7915_fw_debug_wa_set(void *data, u64 val) 563 { 564 struct mt7915_dev *dev = data; 565 int ret; 566 567 dev->fw.debug_wa = val ? MCU_FW_LOG_TO_HOST : 0; 568 569 ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw.debug_wa); 570 if (ret) 571 goto out; 572 573 ret = mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), 574 MCU_WA_PARAM_PDMA_RX, !!dev->fw.debug_wa, 0); 575 out: 576 if (ret) 577 dev->fw.debug_wa = 0; 578 579 return ret; 580 } 581 582 static int 583 mt7915_fw_debug_wa_get(void *data, u64 *val) 584 { 585 struct mt7915_dev *dev = data; 586 587 *val = dev->fw.debug_wa; 588 589 return 0; 590 } 591 592 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wa, mt7915_fw_debug_wa_get, 593 mt7915_fw_debug_wa_set, "%lld\n"); 594 595 static struct dentry * 596 create_buf_file_cb(const char *filename, struct dentry *parent, umode_t mode, 597 struct rchan_buf *buf, int *is_global) 598 { 599 struct dentry *f; 600 601 f = debugfs_create_file("fwlog_data", mode, parent, buf, 602 &relay_file_operations); 603 if (IS_ERR(f)) 604 return NULL; 605 606 *is_global = 1; 607 608 return f; 609 } 610 611 static int 612 remove_buf_file_cb(struct dentry *f) 613 { 614 debugfs_remove(f); 615 616 return 0; 617 } 618 619 static int 620 mt7915_fw_debug_bin_set(void *data, u64 val) 621 { 622 static struct rchan_callbacks relay_cb = { 623 .create_buf_file = create_buf_file_cb, 624 .remove_buf_file = remove_buf_file_cb, 625 }; 626 struct mt7915_dev *dev = data; 627 628 if (!dev->relay_fwlog) 629 dev->relay_fwlog = relay_open("fwlog_data", dev->debugfs_dir, 630 1500, 512, &relay_cb, NULL); 631 if (!dev->relay_fwlog) 632 return -ENOMEM; 633 634 dev->fw.debug_bin = val; 635 636 relay_reset(dev->relay_fwlog); 637 638 return mt7915_fw_debug_wm_set(dev, dev->fw.debug_wm); 639 } 640 641 static int 642 mt7915_fw_debug_bin_get(void *data, u64 *val) 643 { 644 struct mt7915_dev *dev = data; 645 646 *val = dev->fw.debug_bin; 647 648 return 0; 649 } 650 651 DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_bin, mt7915_fw_debug_bin_get, 652 mt7915_fw_debug_bin_set, "%lld\n"); 653 654 static int 655 mt7915_fw_util_wm_show(struct seq_file *file, void *data) 656 { 657 struct mt7915_dev *dev = file->private; 658 659 seq_printf(file, "Program counter: 0x%x\n", mt76_rr(dev, MT_WM_MCU_PC)); 660 661 if (dev->fw.debug_wm) { 662 seq_printf(file, "Busy: %u%% Peak busy: %u%%\n", 663 mt76_rr(dev, MT_CPU_UTIL_BUSY_PCT), 664 mt76_rr(dev, MT_CPU_UTIL_PEAK_BUSY_PCT)); 665 seq_printf(file, "Idle count: %u Peak idle count: %u\n", 666 mt76_rr(dev, MT_CPU_UTIL_IDLE_CNT), 667 mt76_rr(dev, MT_CPU_UTIL_PEAK_IDLE_CNT)); 668 } 669 670 return 0; 671 } 672 673 DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wm); 674 675 static int 676 mt7915_fw_util_wa_show(struct seq_file *file, void *data) 677 { 678 struct mt7915_dev *dev = file->private; 679 680 seq_printf(file, "Program counter: 0x%x\n", mt76_rr(dev, MT_WA_MCU_PC)); 681 682 if (dev->fw.debug_wa) 683 return mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(QUERY), 684 MCU_WA_PARAM_CPU_UTIL, 0, 0); 685 686 return 0; 687 } 688 689 DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa); 690 691 static void 692 mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, 693 struct seq_file *file) 694 { 695 struct mt7915_dev *dev = phy->dev; 696 bool ext_phy = phy != &dev->phy; 697 int bound[15], range[4], i; 698 u8 band = phy->mt76->band_idx; 699 700 /* Tx ampdu stat */ 701 for (i = 0; i < ARRAY_SIZE(range); i++) 702 range[i] = mt76_rr(dev, MT_MIB_ARNG(band, i)); 703 704 for (i = 0; i < ARRAY_SIZE(bound); i++) 705 bound[i] = MT_MIB_ARNCR_RANGE(range[i / 4], i % 4) + 1; 706 707 seq_printf(file, "\nPhy %d, Phy band %d\n", ext_phy, band); 708 709 seq_printf(file, "Length: %8d | ", bound[0]); 710 for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) 711 seq_printf(file, "%3d -%3d | ", 712 bound[i] + 1, bound[i + 1]); 713 714 seq_puts(file, "\nCount: "); 715 for (i = 0; i < ARRAY_SIZE(bound); i++) 716 seq_printf(file, "%8d | ", phy->mt76->aggr_stats[i]); 717 seq_puts(file, "\n"); 718 719 seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); 720 } 721 722 static void 723 mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s) 724 { 725 struct mt76_mib_stats *mib = &phy->mib; 726 static const char * const bw[] = { 727 "BW20", "BW40", "BW80", "BW160" 728 }; 729 730 /* Tx Beamformer monitor */ 731 seq_puts(s, "\nTx Beamformer applied PPDU counts: "); 732 733 seq_printf(s, "iBF: %d, eBF: %d\n", 734 mib->tx_bf_ibf_ppdu_cnt, 735 mib->tx_bf_ebf_ppdu_cnt); 736 737 /* Tx Beamformer Rx feedback monitor */ 738 seq_puts(s, "Tx Beamformer Rx feedback statistics: "); 739 740 seq_printf(s, "All: %d, HE: %d, VHT: %d, HT: %d, ", 741 mib->tx_bf_rx_fb_all_cnt, 742 mib->tx_bf_rx_fb_he_cnt, 743 mib->tx_bf_rx_fb_vht_cnt, 744 mib->tx_bf_rx_fb_ht_cnt); 745 746 seq_printf(s, "%s, NC: %d, NR: %d\n", 747 bw[mib->tx_bf_rx_fb_bw], 748 mib->tx_bf_rx_fb_nc_cnt, 749 mib->tx_bf_rx_fb_nr_cnt); 750 751 /* Tx Beamformee Rx NDPA & Tx feedback report */ 752 seq_printf(s, "Tx Beamformee successful feedback frames: %d\n", 753 mib->tx_bf_fb_cpl_cnt); 754 seq_printf(s, "Tx Beamformee feedback triggered counts: %d\n", 755 mib->tx_bf_fb_trig_cnt); 756 757 /* Tx SU & MU counters */ 758 seq_printf(s, "Tx multi-user Beamforming counts: %d\n", 759 mib->tx_bf_cnt); 760 seq_printf(s, "Tx multi-user MPDU counts: %d\n", mib->tx_mu_mpdu_cnt); 761 seq_printf(s, "Tx multi-user successful MPDU counts: %d\n", 762 mib->tx_mu_acked_mpdu_cnt); 763 seq_printf(s, "Tx single-user successful MPDU counts: %d\n", 764 mib->tx_su_acked_mpdu_cnt); 765 766 seq_puts(s, "\n"); 767 } 768 769 static int 770 mt7915_tx_stats_show(struct seq_file *file, void *data) 771 { 772 struct mt7915_phy *phy = file->private; 773 struct mt7915_dev *dev = phy->dev; 774 struct mt76_mib_stats *mib = &phy->mib; 775 int i; 776 777 mutex_lock(&dev->mt76.mutex); 778 779 mt7915_ampdu_stat_read_phy(phy, file); 780 mt7915_mac_update_stats(phy); 781 mt7915_txbf_stat_read_phy(phy, file); 782 783 /* Tx amsdu info */ 784 seq_puts(file, "Tx MSDU statistics:\n"); 785 for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) { 786 seq_printf(file, "AMSDU pack count of %d MSDU in TXD: %8d ", 787 i + 1, mib->tx_amsdu[i]); 788 if (mib->tx_amsdu_cnt) 789 seq_printf(file, "(%3d%%)\n", 790 mib->tx_amsdu[i] * 100 / mib->tx_amsdu_cnt); 791 else 792 seq_puts(file, "\n"); 793 } 794 795 mutex_unlock(&dev->mt76.mutex); 796 797 return 0; 798 } 799 800 DEFINE_SHOW_ATTRIBUTE(mt7915_tx_stats); 801 802 static void 803 mt7915_hw_queue_read(struct seq_file *s, u32 size, 804 const struct hw_queue_map *map) 805 { 806 struct mt7915_phy *phy = s->private; 807 struct mt7915_dev *dev = phy->dev; 808 u32 i, val; 809 810 val = mt76_rr(dev, MT_FL_Q_EMPTY); 811 for (i = 0; i < size; i++) { 812 u32 ctrl, head, tail, queued; 813 814 if (val & BIT(map[i].index)) 815 continue; 816 817 ctrl = BIT(31) | (map[i].pid << 10) | ((u32)map[i].qid << 24); 818 mt76_wr(dev, MT_FL_Q0_CTRL, ctrl); 819 820 head = mt76_get_field(dev, MT_FL_Q2_CTRL, 821 GENMASK(11, 0)); 822 tail = mt76_get_field(dev, MT_FL_Q2_CTRL, 823 GENMASK(27, 16)); 824 queued = mt76_get_field(dev, MT_FL_Q3_CTRL, 825 GENMASK(11, 0)); 826 827 seq_printf(s, "\t%s: ", map[i].name); 828 seq_printf(s, "queued:0x%03x head:0x%03x tail:0x%03x\n", 829 queued, head, tail); 830 } 831 } 832 833 static void 834 mt7915_sta_hw_queue_read(void *data, struct ieee80211_sta *sta) 835 { 836 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; 837 struct mt7915_dev *dev = msta->vif->phy->dev; 838 struct seq_file *s = data; 839 u8 ac; 840 841 for (ac = 0; ac < 4; ac++) { 842 u32 qlen, ctrl, val; 843 u32 idx = msta->wcid.idx >> 5; 844 u8 offs = msta->wcid.idx & GENMASK(4, 0); 845 846 ctrl = BIT(31) | BIT(11) | (ac << 24); 847 val = mt76_rr(dev, MT_PLE_AC_QEMPTY(ac, idx)); 848 849 if (val & BIT(offs)) 850 continue; 851 852 mt76_wr(dev, MT_FL_Q0_CTRL, ctrl | msta->wcid.idx); 853 qlen = mt76_get_field(dev, MT_FL_Q3_CTRL, 854 GENMASK(11, 0)); 855 seq_printf(s, "\tSTA %pM wcid %d: AC%d%d queued:%d\n", 856 sta->addr, msta->wcid.idx, 857 msta->vif->mt76.wmm_idx, ac, qlen); 858 } 859 } 860 861 static int 862 mt7915_hw_queues_show(struct seq_file *file, void *data) 863 { 864 struct mt7915_phy *phy = file->private; 865 struct mt7915_dev *dev = phy->dev; 866 static const struct hw_queue_map ple_queue_map[] = { 867 { "CPU_Q0", 0, 1, MT_CTX0 }, 868 { "CPU_Q1", 1, 1, MT_CTX0 + 1 }, 869 { "CPU_Q2", 2, 1, MT_CTX0 + 2 }, 870 { "CPU_Q3", 3, 1, MT_CTX0 + 3 }, 871 { "ALTX_Q0", 8, 2, MT_LMAC_ALTX0 }, 872 { "BMC_Q0", 9, 2, MT_LMAC_BMC0 }, 873 { "BCN_Q0", 10, 2, MT_LMAC_BCN0 }, 874 { "PSMP_Q0", 11, 2, MT_LMAC_PSMP0 }, 875 { "ALTX_Q1", 12, 2, MT_LMAC_ALTX0 + 4 }, 876 { "BMC_Q1", 13, 2, MT_LMAC_BMC0 + 4 }, 877 { "BCN_Q1", 14, 2, MT_LMAC_BCN0 + 4 }, 878 { "PSMP_Q1", 15, 2, MT_LMAC_PSMP0 + 4 }, 879 }; 880 static const struct hw_queue_map pse_queue_map[] = { 881 { "CPU Q0", 0, 1, MT_CTX0 }, 882 { "CPU Q1", 1, 1, MT_CTX0 + 1 }, 883 { "CPU Q2", 2, 1, MT_CTX0 + 2 }, 884 { "CPU Q3", 3, 1, MT_CTX0 + 3 }, 885 { "HIF_Q0", 8, 0, MT_HIF0 }, 886 { "HIF_Q1", 9, 0, MT_HIF0 + 1 }, 887 { "HIF_Q2", 10, 0, MT_HIF0 + 2 }, 888 { "HIF_Q3", 11, 0, MT_HIF0 + 3 }, 889 { "HIF_Q4", 12, 0, MT_HIF0 + 4 }, 890 { "HIF_Q5", 13, 0, MT_HIF0 + 5 }, 891 { "LMAC_Q", 16, 2, 0 }, 892 { "MDP_TXQ", 17, 2, 1 }, 893 { "MDP_RXQ", 18, 2, 2 }, 894 { "SEC_TXQ", 19, 2, 3 }, 895 { "SEC_RXQ", 20, 2, 4 }, 896 }; 897 u32 val, head, tail; 898 899 /* ple queue */ 900 val = mt76_rr(dev, MT_PLE_FREEPG_CNT); 901 head = mt76_get_field(dev, MT_PLE_FREEPG_HEAD_TAIL, GENMASK(11, 0)); 902 tail = mt76_get_field(dev, MT_PLE_FREEPG_HEAD_TAIL, GENMASK(27, 16)); 903 seq_puts(file, "PLE page info:\n"); 904 seq_printf(file, 905 "\tTotal free page: 0x%08x head: 0x%03x tail: 0x%03x\n", 906 val, head, tail); 907 908 val = mt76_rr(dev, MT_PLE_PG_HIF_GROUP); 909 head = mt76_get_field(dev, MT_PLE_HIF_PG_INFO, GENMASK(11, 0)); 910 tail = mt76_get_field(dev, MT_PLE_HIF_PG_INFO, GENMASK(27, 16)); 911 seq_printf(file, "\tHIF free page: 0x%03x res: 0x%03x used: 0x%03x\n", 912 val, head, tail); 913 914 seq_puts(file, "PLE non-empty queue info:\n"); 915 mt7915_hw_queue_read(file, ARRAY_SIZE(ple_queue_map), 916 &ple_queue_map[0]); 917 918 /* iterate per-sta ple queue */ 919 ieee80211_iterate_stations_atomic(phy->mt76->hw, 920 mt7915_sta_hw_queue_read, file); 921 /* pse queue */ 922 seq_puts(file, "PSE non-empty queue info:\n"); 923 mt7915_hw_queue_read(file, ARRAY_SIZE(pse_queue_map), 924 &pse_queue_map[0]); 925 926 return 0; 927 } 928 929 DEFINE_SHOW_ATTRIBUTE(mt7915_hw_queues); 930 931 static int 932 mt7915_xmit_queues_show(struct seq_file *file, void *data) 933 { 934 struct mt7915_phy *phy = file->private; 935 struct mt7915_dev *dev = phy->dev; 936 struct { 937 struct mt76_queue *q; 938 char *queue; 939 } queue_map[] = { 940 { phy->mt76->q_tx[MT_TXQ_BE], " MAIN" }, 941 { dev->mt76.q_mcu[MT_MCUQ_WM], " MCUWM" }, 942 { dev->mt76.q_mcu[MT_MCUQ_WA], " MCUWA" }, 943 { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWDL" }, 944 }; 945 int i; 946 947 seq_puts(file, " queue | hw-queued | head | tail |\n"); 948 for (i = 0; i < ARRAY_SIZE(queue_map); i++) { 949 struct mt76_queue *q = queue_map[i].q; 950 951 if (!q) 952 continue; 953 954 seq_printf(file, " %s | %9d | %9d | %9d |\n", 955 queue_map[i].queue, q->queued, q->head, 956 q->tail); 957 } 958 959 return 0; 960 } 961 962 DEFINE_SHOW_ATTRIBUTE(mt7915_xmit_queues); 963 964 #define mt7915_txpower_puts(rate) \ 965 ({ \ 966 len += scnprintf(buf + len, sz - len, "%-16s:", #rate " (TMAC)"); \ 967 for (i = 0; i < mt7915_sku_group_len[SKU_##rate]; i++, offs++) \ 968 len += scnprintf(buf + len, sz - len, " %6d", txpwr[offs]); \ 969 len += scnprintf(buf + len, sz - len, "\n"); \ 970 }) 971 972 #define mt7915_txpower_sets(rate, pwr, flag) \ 973 ({ \ 974 offs += len; \ 975 len = mt7915_sku_group_len[rate]; \ 976 if (mode == flag) { \ 977 for (i = 0; i < len; i++) \ 978 req.txpower_sku[offs + i] = pwr; \ 979 } \ 980 }) 981 982 static ssize_t 983 mt7915_rate_txpower_get(struct file *file, char __user *user_buf, 984 size_t count, loff_t *ppos) 985 { 986 struct mt7915_phy *phy = file->private_data; 987 struct mt7915_dev *dev = phy->dev; 988 s8 txpwr[MT7915_SKU_RATE_NUM]; 989 static const size_t sz = 2048; 990 u8 band = phy->mt76->band_idx; 991 int i, offs = 0, len = 0; 992 ssize_t ret; 993 char *buf; 994 u32 reg; 995 996 buf = kzalloc(sz, GFP_KERNEL); 997 if (!buf) 998 return -ENOMEM; 999 1000 ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr), TX_POWER_INFO_RATE); 1001 if (ret) 1002 goto out; 1003 1004 /* Txpower propagation path: TMAC -> TXV -> BBP */ 1005 len += scnprintf(buf + len, sz - len, 1006 "\nPhy%d Tx power table (channel %d)\n", 1007 phy != &dev->phy, phy->mt76->chandef.chan->hw_value); 1008 len += scnprintf(buf + len, sz - len, "%-16s %6s %6s %6s %6s\n", 1009 " ", "1m", "2m", "5m", "11m"); 1010 mt7915_txpower_puts(CCK); 1011 1012 len += scnprintf(buf + len, sz - len, 1013 "%-16s %6s %6s %6s %6s %6s %6s %6s %6s\n", 1014 " ", "6m", "9m", "12m", "18m", "24m", "36m", "48m", 1015 "54m"); 1016 mt7915_txpower_puts(OFDM); 1017 1018 len += scnprintf(buf + len, sz - len, 1019 "%-16s %6s %6s %6s %6s %6s %6s %6s %6s\n", 1020 " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", 1021 "mcs5", "mcs6", "mcs7"); 1022 mt7915_txpower_puts(HT_BW20); 1023 1024 len += scnprintf(buf + len, sz - len, 1025 "%-16s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", 1026 " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", 1027 "mcs6", "mcs7", "mcs32"); 1028 mt7915_txpower_puts(HT_BW40); 1029 1030 len += scnprintf(buf + len, sz - len, 1031 "%-16s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", 1032 " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", 1033 "mcs6", "mcs7", "mcs8", "mcs9", "mcs10", "mcs11"); 1034 mt7915_txpower_puts(VHT_BW20); 1035 mt7915_txpower_puts(VHT_BW40); 1036 mt7915_txpower_puts(VHT_BW80); 1037 mt7915_txpower_puts(VHT_BW160); 1038 mt7915_txpower_puts(HE_RU26); 1039 mt7915_txpower_puts(HE_RU52); 1040 mt7915_txpower_puts(HE_RU106); 1041 mt7915_txpower_puts(HE_RU242); 1042 mt7915_txpower_puts(HE_RU484); 1043 mt7915_txpower_puts(HE_RU996); 1044 mt7915_txpower_puts(HE_RU2x996); 1045 1046 reg = is_mt7915(&dev->mt76) ? MT_WF_PHY_TPC_CTRL_STAT(band) : 1047 MT_WF_PHY_TPC_CTRL_STAT_MT7916(band); 1048 1049 len += scnprintf(buf + len, sz - len, "\nTx power (bbp) : %6ld\n", 1050 mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER)); 1051 1052 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 1053 1054 out: 1055 kfree(buf); 1056 return ret; 1057 } 1058 1059 static ssize_t 1060 mt7915_rate_txpower_set(struct file *file, const char __user *user_buf, 1061 size_t count, loff_t *ppos) 1062 { 1063 int i, ret, pwr, pwr160 = 0, pwr80 = 0, pwr40 = 0, pwr20 = 0; 1064 struct mt7915_phy *phy = file->private_data; 1065 struct mt7915_dev *dev = phy->dev; 1066 struct mt76_phy *mphy = phy->mt76; 1067 struct mt7915_mcu_txpower_sku req = { 1068 .format_id = TX_POWER_LIMIT_TABLE, 1069 .band_idx = phy->mt76->band_idx, 1070 }; 1071 char buf[100]; 1072 enum mac80211_rx_encoding mode; 1073 u32 offs = 0, len = 0; 1074 1075 if (count >= sizeof(buf)) 1076 return -EINVAL; 1077 1078 if (copy_from_user(buf, user_buf, count)) 1079 return -EFAULT; 1080 1081 if (count && buf[count - 1] == '\n') 1082 buf[count - 1] = '\0'; 1083 else 1084 buf[count] = '\0'; 1085 1086 if (sscanf(buf, "%u %u %u %u %u", 1087 &mode, &pwr160, &pwr80, &pwr40, &pwr20) != 5) { 1088 dev_warn(dev->mt76.dev, 1089 "per bandwidth power limit: Mode BW160 BW80 BW40 BW20"); 1090 return -EINVAL; 1091 } 1092 1093 if (mode > RX_ENC_HE) 1094 return -EINVAL; 1095 1096 if (pwr160) 1097 pwr160 = mt76_get_power_bound(mphy, pwr160); 1098 if (pwr80) 1099 pwr80 = mt76_get_power_bound(mphy, pwr80); 1100 if (pwr40) 1101 pwr40 = mt76_get_power_bound(mphy, pwr40); 1102 if (pwr20) 1103 pwr20 = mt76_get_power_bound(mphy, pwr20); 1104 1105 if (pwr160 < 0 || pwr80 < 0 || pwr40 < 0 || pwr20 < 0) 1106 return -EINVAL; 1107 1108 mutex_lock(&dev->mt76.mutex); 1109 ret = mt7915_mcu_get_txpower_sku(phy, req.txpower_sku, 1110 sizeof(req.txpower_sku), TX_POWER_INFO_RATE); 1111 if (ret) 1112 goto out; 1113 1114 mt7915_txpower_sets(SKU_CCK, pwr20, RX_ENC_LEGACY); 1115 mt7915_txpower_sets(SKU_OFDM, pwr20, RX_ENC_LEGACY); 1116 if (mode == RX_ENC_LEGACY) 1117 goto skip; 1118 1119 mt7915_txpower_sets(SKU_HT_BW20, pwr20, RX_ENC_HT); 1120 mt7915_txpower_sets(SKU_HT_BW40, pwr40, RX_ENC_HT); 1121 if (mode == RX_ENC_HT) 1122 goto skip; 1123 1124 mt7915_txpower_sets(SKU_VHT_BW20, pwr20, RX_ENC_VHT); 1125 mt7915_txpower_sets(SKU_VHT_BW40, pwr40, RX_ENC_VHT); 1126 mt7915_txpower_sets(SKU_VHT_BW80, pwr80, RX_ENC_VHT); 1127 mt7915_txpower_sets(SKU_VHT_BW160, pwr160, RX_ENC_VHT); 1128 if (mode == RX_ENC_VHT) 1129 goto skip; 1130 1131 mt7915_txpower_sets(SKU_HE_RU26, pwr20, RX_ENC_HE + 1); 1132 mt7915_txpower_sets(SKU_HE_RU52, pwr20, RX_ENC_HE + 1); 1133 mt7915_txpower_sets(SKU_HE_RU106, pwr20, RX_ENC_HE + 1); 1134 mt7915_txpower_sets(SKU_HE_RU242, pwr20, RX_ENC_HE); 1135 mt7915_txpower_sets(SKU_HE_RU484, pwr40, RX_ENC_HE); 1136 mt7915_txpower_sets(SKU_HE_RU996, pwr80, RX_ENC_HE); 1137 mt7915_txpower_sets(SKU_HE_RU2x996, pwr160, RX_ENC_HE); 1138 skip: 1139 ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), 1140 &req, sizeof(req), true); 1141 if (ret) 1142 goto out; 1143 1144 pwr = max3(pwr80, pwr40, pwr20); 1145 mphy->txpower_cur = max3(mphy->txpower_cur, pwr160, pwr); 1146 out: 1147 mutex_unlock(&dev->mt76.mutex); 1148 1149 return ret ? ret : count; 1150 } 1151 1152 static const struct file_operations mt7915_txpower_fops = { 1153 .write = mt7915_rate_txpower_set, 1154 .read = mt7915_rate_txpower_get, 1155 .open = simple_open, 1156 .owner = THIS_MODULE, 1157 .llseek = default_llseek, 1158 }; 1159 1160 static int 1161 mt7915_path_txpower_show(struct seq_file *file) 1162 { 1163 struct mt7915_phy *phy = file->private; 1164 s8 txpower[MT7915_SKU_PATH_NUM], *buf = txpower; 1165 int ret; 1166 1167 #define PATH_POWER_SHOW(_name, _len, _skip) do { \ 1168 size_t __len = (_len); \ 1169 if (_skip) { \ 1170 buf -= 1; \ 1171 *buf = 0; \ 1172 } \ 1173 mt76_seq_puts_array(file, _name, buf, __len); \ 1174 buf += __len; \ 1175 } while (0) 1176 1177 seq_printf(file, "\n%*c", 18, ' '); 1178 seq_puts(file, "1T1S/2T1S/3T1S/4T1S/2T2S/3T2S/4T2S/3T3S/4T3S/4T4S\n"); 1179 ret = mt7915_mcu_get_txpower_sku(phy, txpower, sizeof(txpower), 1180 TX_POWER_INFO_PATH); 1181 if (ret) 1182 return ret; 1183 1184 PATH_POWER_SHOW("CCK", 4, 0); 1185 PATH_POWER_SHOW("OFDM", 4, 0); 1186 PATH_POWER_SHOW("BF-OFDM", 4, 1); 1187 1188 PATH_POWER_SHOW("HT/VHT20", 10, 0); 1189 PATH_POWER_SHOW("BF-HT/VHT20", 10, 1); 1190 PATH_POWER_SHOW("HT/VHT40", 10, 0); 1191 PATH_POWER_SHOW("BF-HT/VHT40", 10, 1); 1192 1193 PATH_POWER_SHOW("BW20/RU242", 10, 0); 1194 PATH_POWER_SHOW("BF-BW20/RU242", 10, 1); 1195 PATH_POWER_SHOW("BW40/RU484", 10, 0); 1196 PATH_POWER_SHOW("BF-BW40/RU484", 10, 1); 1197 PATH_POWER_SHOW("BW80/RU996", 10, 0); 1198 PATH_POWER_SHOW("BF-BW80/RU996", 10, 1); 1199 PATH_POWER_SHOW("BW160/RU2x996", 10, 0); 1200 PATH_POWER_SHOW("BF-BW160/RU2x996", 10, 1); 1201 PATH_POWER_SHOW("RU26", 10, 0); 1202 PATH_POWER_SHOW("BF-RU26", 10, 0); 1203 PATH_POWER_SHOW("RU52", 10, 0); 1204 PATH_POWER_SHOW("BF-RU52", 10, 0); 1205 PATH_POWER_SHOW("RU106", 10, 0); 1206 PATH_POWER_SHOW("BF-RU106", 10, 0); 1207 #undef PATH_POWER_SHOW 1208 1209 return 0; 1210 } 1211 1212 static int 1213 mt7915_txpower_path_show(struct seq_file *file, void *data) 1214 { 1215 struct mt7915_phy *phy = file->private; 1216 1217 seq_printf(file, "\nBand %d\n", phy != &phy->dev->phy); 1218 1219 return mt7915_path_txpower_show(file); 1220 } 1221 1222 DEFINE_SHOW_ATTRIBUTE(mt7915_txpower_path); 1223 1224 static int 1225 mt7915_twt_stats(struct seq_file *s, void *data) 1226 { 1227 struct mt7915_dev *dev = dev_get_drvdata(s->private); 1228 struct mt7915_twt_flow *iter; 1229 1230 rcu_read_lock(); 1231 1232 seq_puts(s, " wcid | id | flags | exp | mantissa"); 1233 seq_puts(s, " | duration | tsf |\n"); 1234 list_for_each_entry_rcu(iter, &dev->twt_list, list) 1235 seq_printf(s, 1236 "%9d | %8d | %5c%c%c%c | %8d | %8d | %8d | %14lld |\n", 1237 iter->wcid, iter->id, 1238 iter->sched ? 's' : 'u', 1239 iter->protection ? 'p' : '-', 1240 iter->trigger ? 't' : '-', 1241 iter->flowtype ? '-' : 'a', 1242 iter->exp, iter->mantissa, 1243 iter->duration, iter->tsf); 1244 1245 rcu_read_unlock(); 1246 1247 return 0; 1248 } 1249 1250 /* The index of RF registers use the generic regidx, combined with two parts: 1251 * WF selection [31:24] and offset [23:0]. 1252 */ 1253 static int 1254 mt7915_rf_regval_get(void *data, u64 *val) 1255 { 1256 struct mt7915_dev *dev = data; 1257 u32 regval; 1258 int ret; 1259 1260 ret = mt7915_mcu_rf_regval(dev, dev->mt76.debugfs_reg, ®val, false); 1261 if (ret) 1262 return ret; 1263 1264 *val = regval; 1265 1266 return 0; 1267 } 1268 1269 static int 1270 mt7915_rf_regval_set(void *data, u64 val) 1271 { 1272 struct mt7915_dev *dev = data; 1273 u32 val32 = val; 1274 1275 return mt7915_mcu_rf_regval(dev, dev->mt76.debugfs_reg, &val32, true); 1276 } 1277 1278 DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7915_rf_regval_get, 1279 mt7915_rf_regval_set, "0x%08llx\n"); 1280 1281 int mt7915_init_debugfs(struct mt7915_phy *phy) 1282 { 1283 struct mt7915_dev *dev = phy->dev; 1284 bool ext_phy = phy != &dev->phy; 1285 struct dentry *dir; 1286 1287 dir = mt76_register_debugfs_fops(phy->mt76, NULL); 1288 1289 debugfs_create_file("muru_debug", 0600, dir, dev, &fops_muru_debug); 1290 debugfs_create_file("muru_stats", 0400, dir, phy, 1291 &mt7915_muru_stats_fops); 1292 debugfs_create_file("hw-queues", 0400, dir, phy, 1293 &mt7915_hw_queues_fops); 1294 debugfs_create_file("xmit-queues", 0400, dir, phy, 1295 &mt7915_xmit_queues_fops); 1296 debugfs_create_file("tx_stats", 0400, dir, phy, &mt7915_tx_stats_fops); 1297 debugfs_create_file("sys_recovery", 0600, dir, phy, 1298 &mt7915_sys_recovery_ops); 1299 debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm); 1300 debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa); 1301 debugfs_create_file("fw_debug_bin", 0600, dir, dev, &fops_fw_debug_bin); 1302 debugfs_create_file("fw_util_wm", 0400, dir, dev, 1303 &mt7915_fw_util_wm_fops); 1304 debugfs_create_file("fw_util_wa", 0400, dir, dev, 1305 &mt7915_fw_util_wa_fops); 1306 debugfs_create_file("implicit_txbf", 0600, dir, dev, 1307 &fops_implicit_txbf); 1308 debugfs_create_file("txpower_sku", 0400, dir, phy, 1309 &mt7915_txpower_fops); 1310 debugfs_create_file("txpower_path", 0400, dir, phy, 1311 &mt7915_txpower_path_fops); 1312 debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir, 1313 mt7915_twt_stats); 1314 debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval); 1315 1316 if (!dev->dbdc_support || phy->mt76->band_idx) { 1317 debugfs_create_u32("dfs_hw_pattern", 0400, dir, 1318 &dev->hw_pattern); 1319 debugfs_create_file("radar_trigger", 0200, dir, phy, 1320 &fops_radar_trigger); 1321 debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir, 1322 mt7915_rdd_monitor); 1323 } 1324 1325 if (!ext_phy) 1326 dev->debugfs_dir = dir; 1327 1328 return 0; 1329 } 1330 1331 static void 1332 mt7915_debugfs_write_fwlog(struct mt7915_dev *dev, const void *hdr, int hdrlen, 1333 const void *data, int len) 1334 { 1335 static DEFINE_SPINLOCK(lock); 1336 unsigned long flags; 1337 void *dest; 1338 1339 spin_lock_irqsave(&lock, flags); 1340 dest = relay_reserve(dev->relay_fwlog, hdrlen + len + 4); 1341 if (dest) { 1342 *(u32 *)dest = hdrlen + len; 1343 dest += 4; 1344 1345 if (hdrlen) { 1346 memcpy(dest, hdr, hdrlen); 1347 dest += hdrlen; 1348 } 1349 1350 memcpy(dest, data, len); 1351 relay_flush(dev->relay_fwlog); 1352 } 1353 spin_unlock_irqrestore(&lock, flags); 1354 } 1355 1356 void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int len) 1357 { 1358 struct { 1359 __le32 magic; 1360 __le32 timestamp; 1361 __le16 msg_type; 1362 __le16 len; 1363 } hdr = { 1364 .magic = cpu_to_le32(FW_BIN_LOG_MAGIC), 1365 .msg_type = cpu_to_le16(PKT_TYPE_RX_FW_MONITOR), 1366 }; 1367 1368 if (!dev->relay_fwlog) 1369 return; 1370 1371 hdr.timestamp = cpu_to_le32(mt76_rr(dev, MT_LPON_FRCR(0))); 1372 hdr.len = *(__le16 *)data; 1373 mt7915_debugfs_write_fwlog(dev, &hdr, sizeof(hdr), data, len); 1374 } 1375 1376 bool mt7915_debugfs_rx_log(struct mt7915_dev *dev, const void *data, int len) 1377 { 1378 if (get_unaligned_le32(data) != FW_BIN_LOG_MAGIC) 1379 return false; 1380 1381 if (dev->relay_fwlog) 1382 mt7915_debugfs_write_fwlog(dev, NULL, 0, data, len); 1383 1384 return true; 1385 } 1386 1387 #ifdef CONFIG_MAC80211_DEBUGFS 1388 /** per-station debugfs **/ 1389 1390 static ssize_t mt7915_sta_fixed_rate_set(struct file *file, 1391 const char __user *user_buf, 1392 size_t count, loff_t *ppos) 1393 { 1394 struct ieee80211_sta *sta = file->private_data; 1395 struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; 1396 struct mt7915_dev *dev = msta->vif->phy->dev; 1397 struct ieee80211_vif *vif; 1398 struct sta_phy phy = {}; 1399 char buf[100]; 1400 int ret; 1401 u32 field; 1402 u8 i, gi, he_ltf; 1403 1404 if (count >= sizeof(buf)) 1405 return -EINVAL; 1406 1407 if (copy_from_user(buf, user_buf, count)) 1408 return -EFAULT; 1409 1410 if (count && buf[count - 1] == '\n') 1411 buf[count - 1] = '\0'; 1412 else 1413 buf[count] = '\0'; 1414 1415 /* mode - cck: 0, ofdm: 1, ht: 2, gf: 3, vht: 4, he_su: 8, he_er: 9 1416 * bw - bw20: 0, bw40: 1, bw80: 2, bw160: 3 1417 * nss - vht: 1~4, he: 1~4, others: ignore 1418 * mcs - cck: 0~4, ofdm: 0~7, ht: 0~32, vht: 0~9, he_su: 0~11, he_er: 0~2 1419 * gi - (ht/vht) lgi: 0, sgi: 1; (he) 0.8us: 0, 1.6us: 1, 3.2us: 2 1420 * ldpc - off: 0, on: 1 1421 * stbc - off: 0, on: 1 1422 * he_ltf - 1xltf: 0, 2xltf: 1, 4xltf: 2 1423 */ 1424 if (sscanf(buf, "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu", 1425 &phy.type, &phy.bw, &phy.nss, &phy.mcs, &gi, 1426 &phy.ldpc, &phy.stbc, &he_ltf) != 8) { 1427 dev_warn(dev->mt76.dev, 1428 "format: Mode BW NSS MCS (HE)GI LDPC STBC HE_LTF\n"); 1429 field = RATE_PARAM_AUTO; 1430 goto out; 1431 } 1432 1433 phy.ldpc = (phy.bw || phy.ldpc) * GENMASK(2, 0); 1434 for (i = 0; i <= phy.bw; i++) { 1435 phy.sgi |= gi << (i << sta->deflink.he_cap.has_he); 1436 phy.he_ltf |= he_ltf << (i << sta->deflink.he_cap.has_he); 1437 } 1438 field = RATE_PARAM_FIXED; 1439 1440 out: 1441 vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); 1442 ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy, field); 1443 if (ret) 1444 return -EFAULT; 1445 1446 return count; 1447 } 1448 1449 static const struct file_operations fops_fixed_rate = { 1450 .write = mt7915_sta_fixed_rate_set, 1451 .open = simple_open, 1452 .owner = THIS_MODULE, 1453 .llseek = default_llseek, 1454 }; 1455 1456 static int 1457 mt7915_queues_show(struct seq_file *s, void *data) 1458 { 1459 struct ieee80211_sta *sta = s->private; 1460 1461 mt7915_sta_hw_queue_read(s, sta); 1462 1463 return 0; 1464 } 1465 1466 DEFINE_SHOW_ATTRIBUTE(mt7915_queues); 1467 1468 void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1469 struct ieee80211_sta *sta, struct dentry *dir) 1470 { 1471 debugfs_create_file("fixed_rate", 0600, dir, sta, &fops_fixed_rate); 1472 debugfs_create_file("hw-queues", 0400, dir, sta, &mt7915_queues_fops); 1473 } 1474 1475 #endif 1476