1355 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2/* Copyright(c) 2018-2019 Realtek Corporation3 */4 5#include <linux/debugfs.h>6#include <linux/seq_file.h>7#include "main.h"8#include "coex.h"9#include "sec.h"10#include "fw.h"11#include "debug.h"12#include "phy.h"13#include "reg.h"14#include "ps.h"15#include "regd.h"16 17#ifdef CONFIG_RTW88_DEBUGFS18 19struct rtw_debugfs_priv {20 struct rtw_dev *rtwdev;21 int (*cb_read)(struct seq_file *m, void *v);22 ssize_t (*cb_write)(struct file *filp, const char __user *buffer,23 size_t count, loff_t *loff);24 union {25 u32 cb_data;26 u8 *buf;27 struct {28 u32 page_offset;29 u32 page_num;30 } rsvd_page;31 struct {32 u8 rf_path;33 u32 rf_addr;34 u32 rf_mask;35 };36 struct {37 u32 addr;38 u32 len;39 } read_reg;40 struct {41 u8 bit;42 } dm_cap;43 };44};45 46struct rtw_debugfs {47 struct rtw_debugfs_priv mac_0;48 struct rtw_debugfs_priv mac_1;49 struct rtw_debugfs_priv mac_2;50 struct rtw_debugfs_priv mac_3;51 struct rtw_debugfs_priv mac_4;52 struct rtw_debugfs_priv mac_5;53 struct rtw_debugfs_priv mac_6;54 struct rtw_debugfs_priv mac_7;55 struct rtw_debugfs_priv mac_10;56 struct rtw_debugfs_priv mac_11;57 struct rtw_debugfs_priv mac_12;58 struct rtw_debugfs_priv mac_13;59 struct rtw_debugfs_priv mac_14;60 struct rtw_debugfs_priv mac_15;61 struct rtw_debugfs_priv mac_16;62 struct rtw_debugfs_priv mac_17;63 struct rtw_debugfs_priv bb_8;64 struct rtw_debugfs_priv bb_9;65 struct rtw_debugfs_priv bb_a;66 struct rtw_debugfs_priv bb_b;67 struct rtw_debugfs_priv bb_c;68 struct rtw_debugfs_priv bb_d;69 struct rtw_debugfs_priv bb_e;70 struct rtw_debugfs_priv bb_f;71 struct rtw_debugfs_priv bb_18;72 struct rtw_debugfs_priv bb_19;73 struct rtw_debugfs_priv bb_1a;74 struct rtw_debugfs_priv bb_1b;75 struct rtw_debugfs_priv bb_1c;76 struct rtw_debugfs_priv bb_1d;77 struct rtw_debugfs_priv bb_1e;78 struct rtw_debugfs_priv bb_1f;79 struct rtw_debugfs_priv bb_2c;80 struct rtw_debugfs_priv bb_2d;81 struct rtw_debugfs_priv bb_40;82 struct rtw_debugfs_priv bb_41;83 struct rtw_debugfs_priv rf_dump;84 struct rtw_debugfs_priv tx_pwr_tbl;85 struct rtw_debugfs_priv write_reg;86 struct rtw_debugfs_priv h2c;87 struct rtw_debugfs_priv rf_write;88 struct rtw_debugfs_priv rf_read;89 struct rtw_debugfs_priv read_reg;90 struct rtw_debugfs_priv fix_rate;91 struct rtw_debugfs_priv dump_cam;92 struct rtw_debugfs_priv rsvd_page;93 struct rtw_debugfs_priv phy_info;94 struct rtw_debugfs_priv coex_enable;95 struct rtw_debugfs_priv coex_info;96 struct rtw_debugfs_priv edcca_enable;97 struct rtw_debugfs_priv fw_crash;98 struct rtw_debugfs_priv force_lowest_basic_rate;99 struct rtw_debugfs_priv dm_cap;100};101 102static const char * const rtw_dm_cap_strs[] = {103 [RTW_DM_CAP_NA] = "NA",104 [RTW_DM_CAP_TXGAPK] = "TXGAPK",105};106 107static int rtw_debugfs_single_show(struct seq_file *m, void *v)108{109 struct rtw_debugfs_priv *debugfs_priv = m->private;110 111 return debugfs_priv->cb_read(m, v);112}113 114static ssize_t rtw_debugfs_common_write(struct file *filp,115 const char __user *buffer,116 size_t count, loff_t *loff)117{118 struct rtw_debugfs_priv *debugfs_priv = filp->private_data;119 120 return debugfs_priv->cb_write(filp, buffer, count, loff);121}122 123static ssize_t rtw_debugfs_single_write(struct file *filp,124 const char __user *buffer,125 size_t count, loff_t *loff)126{127 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;128 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;129 130 return debugfs_priv->cb_write(filp, buffer, count, loff);131}132 133static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp)134{135 return single_open(filp, rtw_debugfs_single_show, inode->i_private);136}137 138static int rtw_debugfs_close(struct inode *inode, struct file *filp)139{140 return 0;141}142 143static const struct file_operations file_ops_single_r = {144 .owner = THIS_MODULE,145 .open = rtw_debugfs_single_open_rw,146 .read = seq_read,147 .llseek = seq_lseek,148 .release = single_release,149};150 151static const struct file_operations file_ops_single_rw = {152 .owner = THIS_MODULE,153 .open = rtw_debugfs_single_open_rw,154 .release = single_release,155 .read = seq_read,156 .llseek = seq_lseek,157 .write = rtw_debugfs_single_write,158};159 160static const struct file_operations file_ops_common_write = {161 .owner = THIS_MODULE,162 .write = rtw_debugfs_common_write,163 .open = simple_open,164 .release = rtw_debugfs_close,165};166 167static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v)168{169 struct rtw_debugfs_priv *debugfs_priv = m->private;170 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;171 u32 val, len, addr;172 173 len = debugfs_priv->read_reg.len;174 addr = debugfs_priv->read_reg.addr;175 switch (len) {176 case 1:177 val = rtw_read8(rtwdev, addr);178 seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val);179 break;180 case 2:181 val = rtw_read16(rtwdev, addr);182 seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val);183 break;184 case 4:185 val = rtw_read32(rtwdev, addr);186 seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val);187 break;188 }189 return 0;190}191 192static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)193{194 struct rtw_debugfs_priv *debugfs_priv = m->private;195 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;196 u32 val, addr, mask;197 u8 path;198 199 path = debugfs_priv->rf_path;200 addr = debugfs_priv->rf_addr;201 mask = debugfs_priv->rf_mask;202 203 mutex_lock(&rtwdev->mutex);204 val = rtw_read_rf(rtwdev, path, addr, mask);205 mutex_unlock(&rtwdev->mutex);206 207 seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",208 path, addr, mask, val);209 210 return 0;211}212 213static int rtw_debugfs_get_fix_rate(struct seq_file *m, void *v)214{215 struct rtw_debugfs_priv *debugfs_priv = m->private;216 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;217 struct rtw_dm_info *dm_info = &rtwdev->dm_info;218 u8 fix_rate = dm_info->fix_rate;219 220 if (fix_rate >= DESC_RATE_MAX) {221 seq_printf(m, "Fix rate disabled, fix_rate = %u\n", fix_rate);222 return 0;223 }224 225 seq_printf(m, "Data frames fixed at desc rate %u\n", fix_rate);226 return 0;227}228 229static int rtw_debugfs_copy_from_user(char tmp[], int size,230 const char __user *buffer, size_t count,231 int num)232{233 int tmp_len;234 235 memset(tmp, 0, size);236 237 if (count < num)238 return -EFAULT;239 240 tmp_len = (count > size - 1 ? size - 1 : count);241 242 if (copy_from_user(tmp, buffer, tmp_len))243 return -EFAULT;244 245 tmp[tmp_len] = '\0';246 247 return 0;248}249 250static ssize_t rtw_debugfs_set_read_reg(struct file *filp,251 const char __user *buffer,252 size_t count, loff_t *loff)253{254 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;255 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;256 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;257 char tmp[32 + 1];258 u32 addr, len;259 int num;260 int ret;261 262 ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);263 if (ret)264 return ret;265 266 num = sscanf(tmp, "%x %x", &addr, &len);267 268 if (num != 2)269 return -EINVAL;270 271 if (len != 1 && len != 2 && len != 4) {272 rtw_warn(rtwdev, "read reg setting wrong len\n");273 return -EINVAL;274 }275 debugfs_priv->read_reg.addr = addr;276 debugfs_priv->read_reg.len = len;277 278 return count;279}280 281static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v)282{283 struct rtw_debugfs_priv *debugfs_priv = m->private;284 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;285 u32 val, command;286 u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT;287 u32 read_cmd = RTW_SEC_CMD_POLLING;288 int i;289 290 seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data);291 seq_puts(m, "0x0 0x1 0x2 0x3 ");292 seq_puts(m, "0x4 0x5\n");293 mutex_lock(&rtwdev->mutex);294 for (i = 0; i <= 5; i++) {295 command = read_cmd | (hw_key_idx + i);296 rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);297 val = rtw_read32(rtwdev, RTW_SEC_READ_REG);298 seq_printf(m, "%8.8x", val);299 if (i < 2)300 seq_puts(m, " ");301 }302 seq_puts(m, "\n");303 mutex_unlock(&rtwdev->mutex);304 return 0;305}306 307static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)308{309 struct rtw_debugfs_priv *debugfs_priv = m->private;310 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;311 u8 page_size = rtwdev->chip->page_size;312 u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size;313 u32 offset = debugfs_priv->rsvd_page.page_offset * page_size;314 u8 *buf;315 int i;316 int ret;317 318 buf = vzalloc(buf_size);319 if (!buf)320 return -ENOMEM;321 322 ret = rtw_fw_dump_fifo(rtwdev, RTW_FW_FIFO_SEL_RSVD_PAGE, offset,323 buf_size, (u32 *)buf);324 if (ret) {325 rtw_err(rtwdev, "failed to dump rsvd page\n");326 vfree(buf);327 return ret;328 }329 330 for (i = 0 ; i < buf_size ; i += 8) {331 if (i % page_size == 0)332 seq_printf(m, "PAGE %d\n", (i + offset) / page_size);333 seq_printf(m, "%8ph\n", buf + i);334 }335 vfree(buf);336 337 return 0;338}339 340static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp,341 const char __user *buffer,342 size_t count, loff_t *loff)343{344 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;345 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;346 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;347 char tmp[32 + 1];348 u32 offset, page_num;349 int num;350 int ret;351 352 ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);353 if (ret)354 return ret;355 356 num = sscanf(tmp, "%d %d", &offset, &page_num);357 358 if (num != 2) {359 rtw_warn(rtwdev, "invalid arguments\n");360 return -EINVAL;361 }362 363 debugfs_priv->rsvd_page.page_offset = offset;364 debugfs_priv->rsvd_page.page_num = page_num;365 366 return count;367}368 369static ssize_t rtw_debugfs_set_single_input(struct file *filp,370 const char __user *buffer,371 size_t count, loff_t *loff)372{373 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;374 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;375 u32 input;376 int ret;377 378 ret = kstrtou32_from_user(buffer, count, 0, &input);379 if (ret)380 return ret;381 382 debugfs_priv->cb_data = input;383 384 return count;385}386 387static ssize_t rtw_debugfs_set_write_reg(struct file *filp,388 const char __user *buffer,389 size_t count, loff_t *loff)390{391 struct rtw_debugfs_priv *debugfs_priv = filp->private_data;392 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;393 char tmp[32 + 1];394 u32 addr, val, len;395 int num;396 int ret;397 398 ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);399 if (ret)400 return ret;401 402 /* write BB/MAC register */403 num = sscanf(tmp, "%x %x %x", &addr, &val, &len);404 405 if (num != 3)406 return -EINVAL;407 408 switch (len) {409 case 1:410 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,411 "reg write8 0x%03x: 0x%08x\n", addr, val);412 rtw_write8(rtwdev, addr, (u8)val);413 break;414 case 2:415 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,416 "reg write16 0x%03x: 0x%08x\n", addr, val);417 rtw_write16(rtwdev, addr, (u16)val);418 break;419 case 4:420 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,421 "reg write32 0x%03x: 0x%08x\n", addr, val);422 rtw_write32(rtwdev, addr, (u32)val);423 break;424 default:425 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,426 "error write length = %d\n", len);427 break;428 }429 430 return count;431}432 433static ssize_t rtw_debugfs_set_h2c(struct file *filp,434 const char __user *buffer,435 size_t count, loff_t *loff)436{437 struct rtw_debugfs_priv *debugfs_priv = filp->private_data;438 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;439 char tmp[32 + 1];440 u8 param[8];441 int num;442 int ret;443 444 ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);445 if (ret)446 return ret;447 448 num = sscanf(tmp, "%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx,%hhx",449 ¶m[0], ¶m[1], ¶m[2], ¶m[3],450 ¶m[4], ¶m[5], ¶m[6], ¶m[7]);451 if (num != 8) {452 rtw_warn(rtwdev, "invalid H2C command format for debug\n");453 return -EINVAL;454 }455 456 mutex_lock(&rtwdev->mutex);457 rtw_fw_h2c_cmd_dbg(rtwdev, param);458 mutex_unlock(&rtwdev->mutex);459 460 return count;461}462 463static ssize_t rtw_debugfs_set_rf_write(struct file *filp,464 const char __user *buffer,465 size_t count, loff_t *loff)466{467 struct rtw_debugfs_priv *debugfs_priv = filp->private_data;468 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;469 char tmp[32 + 1];470 u32 path, addr, mask, val;471 int num;472 int ret;473 474 ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4);475 if (ret)476 return ret;477 478 num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val);479 480 if (num != 4) {481 rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");482 return -EINVAL;483 }484 485 mutex_lock(&rtwdev->mutex);486 rtw_write_rf(rtwdev, path, addr, mask, val);487 mutex_unlock(&rtwdev->mutex);488 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,489 "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n",490 path, addr, mask, val);491 492 return count;493}494 495static ssize_t rtw_debugfs_set_rf_read(struct file *filp,496 const char __user *buffer,497 size_t count, loff_t *loff)498{499 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;500 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;501 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;502 char tmp[32 + 1];503 u32 path, addr, mask;504 int num;505 int ret;506 507 ret = rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);508 if (ret)509 return ret;510 511 num = sscanf(tmp, "%x %x %x", &path, &addr, &mask);512 513 if (num != 3) {514 rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");515 return -EINVAL;516 }517 518 debugfs_priv->rf_path = path;519 debugfs_priv->rf_addr = addr;520 debugfs_priv->rf_mask = mask;521 522 return count;523}524 525static ssize_t rtw_debugfs_set_fix_rate(struct file *filp,526 const char __user *buffer,527 size_t count, loff_t *loff)528{529 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;530 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;531 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;532 struct rtw_dm_info *dm_info = &rtwdev->dm_info;533 u8 fix_rate;534 int ret;535 536 ret = kstrtou8_from_user(buffer, count, 0, &fix_rate);537 if (ret)538 return ret;539 540 dm_info->fix_rate = fix_rate;541 542 return count;543}544 545static int rtw_debug_get_mac_page(struct seq_file *m, void *v)546{547 struct rtw_debugfs_priv *debugfs_priv = m->private;548 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;549 u32 page = debugfs_priv->cb_data;550 int i, n;551 int max = 0xff;552 553 rtw_read32(rtwdev, debugfs_priv->cb_data);554 for (n = 0; n <= max; ) {555 seq_printf(m, "\n%8.8x ", n + page);556 for (i = 0; i < 4 && n <= max; i++, n += 4)557 seq_printf(m, "%8.8x ",558 rtw_read32(rtwdev, (page | n)));559 }560 seq_puts(m, "\n");561 return 0;562}563 564static int rtw_debug_get_bb_page(struct seq_file *m, void *v)565{566 struct rtw_debugfs_priv *debugfs_priv = m->private;567 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;568 u32 page = debugfs_priv->cb_data;569 int i, n;570 int max = 0xff;571 572 rtw_read32(rtwdev, debugfs_priv->cb_data);573 for (n = 0; n <= max; ) {574 seq_printf(m, "\n%8.8x ", n + page);575 for (i = 0; i < 4 && n <= max; i++, n += 4)576 seq_printf(m, "%8.8x ",577 rtw_read32(rtwdev, (page | n)));578 }579 seq_puts(m, "\n");580 return 0;581}582 583static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v)584{585 struct rtw_debugfs_priv *debugfs_priv = m->private;586 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;587 u32 addr, offset, data;588 u8 path;589 590 mutex_lock(&rtwdev->mutex);591 592 for (path = 0; path < rtwdev->hal.rf_path_num; path++) {593 seq_printf(m, "RF path:%d\n", path);594 for (addr = 0; addr < 0x100; addr += 4) {595 seq_printf(m, "%8.8x ", addr);596 for (offset = 0; offset < 4; offset++) {597 data = rtw_read_rf(rtwdev, path, addr + offset,598 0xffffffff);599 seq_printf(m, "%8.8x ", data);600 }601 seq_puts(m, "\n");602 }603 seq_puts(m, "\n");604 }605 606 mutex_unlock(&rtwdev->mutex);607 608 return 0;609}610 611static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate)612{613 static const char * const614 cck_rate[] = {"1M", "2M", "5.5M", "11M"};615 u8 idx = rate - DESC_RATE1M;616 617 seq_printf(m, " CCK_%-5s", cck_rate[idx]);618}619 620static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate)621{622 static const char * const623 ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"};624 u8 idx = rate - DESC_RATE6M;625 626 seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]);627}628 629static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate)630{631 u8 mcs_n = rate - DESC_RATEMCS0;632 633 seq_printf(m, " MCS%-6u", mcs_n);634}635 636static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate)637{638 u8 idx = rate - DESC_RATEVHT1SS_MCS0;639 u8 n_ss, mcs_n;640 641 /* n spatial stream */642 n_ss = 1 + idx / 10;643 /* MCS n */644 mcs_n = idx % 10;645 seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n);646}647 648static void rtw_print_rate(struct seq_file *m, u8 rate)649{650 switch (rate) {651 case DESC_RATE1M...DESC_RATE11M:652 rtw_print_cck_rate_txt(m, rate);653 break;654 case DESC_RATE6M...DESC_RATE54M:655 rtw_print_ofdm_rate_txt(m, rate);656 break;657 case DESC_RATEMCS0...DESC_RATEMCS15:658 rtw_print_ht_rate_txt(m, rate);659 break;660 case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9:661 rtw_print_vht_rate_txt(m, rate);662 break;663 default:664 seq_printf(m, " Unknown rate=0x%x\n", rate);665 break;666 }667}668 669#define case_REGD(src) \670 case RTW_REGD_##src: return #src671 672static const char *rtw_get_regd_string(u8 regd)673{674 switch (regd) {675 case_REGD(FCC);676 case_REGD(MKK);677 case_REGD(ETSI);678 case_REGD(IC);679 case_REGD(KCC);680 case_REGD(ACMA);681 case_REGD(CHILE);682 case_REGD(UKRAINE);683 case_REGD(MEXICO);684 case_REGD(CN);685 case_REGD(WW);686 default:687 return "Unknown";688 }689}690 691static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)692{693 struct rtw_debugfs_priv *debugfs_priv = m->private;694 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;695 struct rtw_hal *hal = &rtwdev->hal;696 u8 path, rate, bw, ch, regd;697 struct rtw_power_params pwr_param = {0};698 699 mutex_lock(&rtwdev->mutex);700 bw = hal->current_band_width;701 ch = hal->current_channel;702 regd = rtw_regd_get(rtwdev);703 704 seq_printf(m, "channel: %u\n", ch);705 seq_printf(m, "bandwidth: %u\n", bw);706 seq_printf(m, "regulatory: %s\n", rtw_get_regd_string(regd));707 seq_printf(m, "%-4s %-10s %-9s %-9s (%-4s %-4s %-4s) %-4s\n",708 "path", "rate", "pwr", "base", "byr", "lmt", "sar", "rem");709 710 mutex_lock(&hal->tx_power_mutex);711 for (path = RF_PATH_A; path <= RF_PATH_B; path++) {712 /* there is no CCK rates used in 5G */713 if (hal->current_band_type == RTW_BAND_5G)714 rate = DESC_RATE6M;715 else716 rate = DESC_RATE1M;717 718 /* now, not support vht 3ss and vht 4ss*/719 for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) {720 /* now, not support ht 3ss and ht 4ss*/721 if (rate > DESC_RATEMCS15 &&722 rate < DESC_RATEVHT1SS_MCS0)723 continue;724 725 rtw_get_tx_power_params(rtwdev, path, rate, bw,726 ch, regd, &pwr_param);727 728 seq_printf(m, "%4c ", path + 'A');729 rtw_print_rate(m, rate);730 seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d) %4d\n",731 hal->tx_pwr_tbl[path][rate],732 hal->tx_pwr_tbl[path][rate],733 pwr_param.pwr_base,734 min3(pwr_param.pwr_offset,735 pwr_param.pwr_limit,736 pwr_param.pwr_sar),737 pwr_param.pwr_offset, pwr_param.pwr_limit,738 pwr_param.pwr_sar,739 pwr_param.pwr_remnant);740 }741 }742 743 mutex_unlock(&hal->tx_power_mutex);744 mutex_unlock(&rtwdev->mutex);745 746 return 0;747}748 749void rtw_debugfs_get_simple_phy_info(struct seq_file *m)750{751 struct rtw_debugfs_priv *debugfs_priv = m->private;752 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;753 struct rtw_hal *hal = &rtwdev->hal;754 struct rtw_dm_info *dm_info = &rtwdev->dm_info;755 struct rtw_traffic_stats *stats = &rtwdev->stats;756 757 seq_printf(m, "%-40s = %ddBm/ %d\n", "RSSI/ STA Channel",758 dm_info->rssi[RF_PATH_A] - 100, hal->current_channel);759 760 seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n",761 stats->tx_throughput, stats->rx_throughput);762 763 seq_puts(m, "[Tx Rate] = ");764 rtw_print_rate(m, dm_info->tx_rate);765 seq_printf(m, "(0x%x)\n", dm_info->tx_rate);766 767 seq_puts(m, "[Rx Rate] = ");768 rtw_print_rate(m, dm_info->curr_rx_rate);769 seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate);770}771 772static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v)773{774 struct rtw_debugfs_priv *debugfs_priv = m->private;775 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;776 struct rtw_dm_info *dm_info = &rtwdev->dm_info;777 struct rtw_traffic_stats *stats = &rtwdev->stats;778 struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count;779 struct rtw_efuse *efuse = &rtwdev->efuse;780 struct ewma_evm *ewma_evm = dm_info->ewma_evm;781 struct ewma_snr *ewma_snr = dm_info->ewma_snr;782 u8 ss, rate_id;783 784 seq_puts(m, "==========[Common Info]========\n");785 seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N');786 seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel);787 seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width);788 seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]);789 seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n",790 stats->tx_throughput, stats->rx_throughput);791 seq_printf(m, "1SS for TX and RX = %c\n\n", rtwdev->hal.txrx_1ss ?792 'Y' : 'N');793 794 seq_puts(m, "==========[Tx Phy Info]========\n");795 seq_puts(m, "[Tx Rate] = ");796 rtw_print_rate(m, dm_info->tx_rate);797 seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate);798 799 seq_puts(m, "==========[Rx Phy Info]========\n");800 seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt);801 seq_puts(m, "[Rx Rate] = ");802 rtw_print_rate(m, dm_info->curr_rx_rate);803 seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate);804 805 seq_puts(m, "[Rx Rate Count]:\n");806 seq_printf(m, " * CCK = {%u, %u, %u, %u}\n",807 last_cnt->num_qry_pkt[DESC_RATE1M],808 last_cnt->num_qry_pkt[DESC_RATE2M],809 last_cnt->num_qry_pkt[DESC_RATE5_5M],810 last_cnt->num_qry_pkt[DESC_RATE11M]);811 812 seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n",813 last_cnt->num_qry_pkt[DESC_RATE6M],814 last_cnt->num_qry_pkt[DESC_RATE9M],815 last_cnt->num_qry_pkt[DESC_RATE12M],816 last_cnt->num_qry_pkt[DESC_RATE18M],817 last_cnt->num_qry_pkt[DESC_RATE24M],818 last_cnt->num_qry_pkt[DESC_RATE36M],819 last_cnt->num_qry_pkt[DESC_RATE48M],820 last_cnt->num_qry_pkt[DESC_RATE54M]);821 822 for (ss = 0; ss < efuse->hw_cap.nss; ss++) {823 rate_id = DESC_RATEMCS0 + ss * 8;824 seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n",825 ss * 8, ss * 8 + 7,826 last_cnt->num_qry_pkt[rate_id],827 last_cnt->num_qry_pkt[rate_id + 1],828 last_cnt->num_qry_pkt[rate_id + 2],829 last_cnt->num_qry_pkt[rate_id + 3],830 last_cnt->num_qry_pkt[rate_id + 4],831 last_cnt->num_qry_pkt[rate_id + 5],832 last_cnt->num_qry_pkt[rate_id + 6],833 last_cnt->num_qry_pkt[rate_id + 7]);834 }835 836 for (ss = 0; ss < efuse->hw_cap.nss; ss++) {837 rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10;838 seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n",839 ss + 1,840 last_cnt->num_qry_pkt[rate_id],841 last_cnt->num_qry_pkt[rate_id + 1],842 last_cnt->num_qry_pkt[rate_id + 2],843 last_cnt->num_qry_pkt[rate_id + 3],844 last_cnt->num_qry_pkt[rate_id + 4],845 last_cnt->num_qry_pkt[rate_id + 5],846 last_cnt->num_qry_pkt[rate_id + 6],847 last_cnt->num_qry_pkt[rate_id + 7],848 last_cnt->num_qry_pkt[rate_id + 8],849 last_cnt->num_qry_pkt[rate_id + 9]);850 }851 852 seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n",853 dm_info->rssi[RF_PATH_A] - 100,854 dm_info->rssi[RF_PATH_B] - 100);855 seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n",856 dm_info->rx_evm_dbm[RF_PATH_A],857 dm_info->rx_evm_dbm[RF_PATH_B]);858 seq_printf(m, "[Rx SNR] = {%d, %d}\n",859 dm_info->rx_snr[RF_PATH_A],860 dm_info->rx_snr[RF_PATH_B]);861 seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n",862 dm_info->cfo_tail[RF_PATH_A],863 dm_info->cfo_tail[RF_PATH_B]);864 865 if (dm_info->curr_rx_rate >= DESC_RATE11M) {866 seq_puts(m, "[Rx Average Status]:\n");867 seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n",868 (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]),869 (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A]));870 seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n",871 (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]),872 (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A]));873 seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n",874 (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]),875 (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]),876 (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]),877 (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B]));878 }879 880 seq_puts(m, "[Rx Counter]:\n");881 seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n",882 dm_info->cck_cca_cnt,883 dm_info->ofdm_cca_cnt,884 dm_info->total_cca_cnt);885 seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n",886 dm_info->cck_fa_cnt,887 dm_info->ofdm_fa_cnt,888 dm_info->total_fa_cnt);889 seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n",890 dm_info->cck_ok_cnt, dm_info->cck_err_cnt);891 seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n",892 dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt);893 seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n",894 dm_info->ht_ok_cnt, dm_info->ht_err_cnt);895 seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n",896 dm_info->vht_ok_cnt, dm_info->vht_err_cnt);897 898 return 0;899}900 901static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v)902{903 struct rtw_debugfs_priv *debugfs_priv = m->private;904 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;905 906 mutex_lock(&rtwdev->mutex);907 rtw_coex_display_coex_info(rtwdev, m);908 mutex_unlock(&rtwdev->mutex);909 910 return 0;911}912 913static ssize_t rtw_debugfs_set_coex_enable(struct file *filp,914 const char __user *buffer,915 size_t count, loff_t *loff)916{917 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;918 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;919 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;920 struct rtw_coex *coex = &rtwdev->coex;921 bool enable;922 int ret;923 924 ret = kstrtobool_from_user(buffer, count, &enable);925 if (ret)926 return ret;927 928 mutex_lock(&rtwdev->mutex);929 coex->manual_control = !enable;930 mutex_unlock(&rtwdev->mutex);931 932 return count;933}934 935static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v)936{937 struct rtw_debugfs_priv *debugfs_priv = m->private;938 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;939 struct rtw_coex *coex = &rtwdev->coex;940 941 seq_printf(m, "coex mechanism %s\n",942 coex->manual_control ? "disabled" : "enabled");943 944 return 0;945}946 947static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp,948 const char __user *buffer,949 size_t count, loff_t *loff)950{951 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;952 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;953 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;954 bool input;955 int err;956 957 err = kstrtobool_from_user(buffer, count, &input);958 if (err)959 return err;960 961 rtw_edcca_enabled = input;962 rtw_phy_adaptivity_set_mode(rtwdev);963 964 return count;965}966 967static int rtw_debugfs_get_edcca_enable(struct seq_file *m, void *v)968{969 struct rtw_debugfs_priv *debugfs_priv = m->private;970 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;971 struct rtw_dm_info *dm_info = &rtwdev->dm_info;972 973 seq_printf(m, "EDCCA %s: EDCCA mode %d\n",974 rtw_edcca_enabled ? "enabled" : "disabled",975 dm_info->edcca_mode);976 return 0;977}978 979static ssize_t rtw_debugfs_set_fw_crash(struct file *filp,980 const char __user *buffer,981 size_t count, loff_t *loff)982{983 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;984 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;985 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;986 bool input;987 int ret;988 989 ret = kstrtobool_from_user(buffer, count, &input);990 if (ret)991 return ret;992 993 if (!input)994 return -EINVAL;995 996 if (test_bit(RTW_FLAG_RESTARTING, rtwdev->flags))997 return -EINPROGRESS;998 999 mutex_lock(&rtwdev->mutex);1000 rtw_leave_lps_deep(rtwdev);1001 set_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags);1002 rtw_write8(rtwdev, REG_HRCV_MSG, 1);1003 mutex_unlock(&rtwdev->mutex);1004 1005 return count;1006}1007 1008static int rtw_debugfs_get_fw_crash(struct seq_file *m, void *v)1009{1010 struct rtw_debugfs_priv *debugfs_priv = m->private;1011 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;1012 1013 seq_printf(m, "%d\n",1014 test_bit(RTW_FLAG_RESTART_TRIGGERING, rtwdev->flags) ||1015 test_bit(RTW_FLAG_RESTARTING, rtwdev->flags));1016 return 0;1017}1018 1019static ssize_t rtw_debugfs_set_force_lowest_basic_rate(struct file *filp,1020 const char __user *buffer,1021 size_t count, loff_t *loff)1022{1023 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;1024 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;1025 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;1026 bool input;1027 int err;1028 1029 err = kstrtobool_from_user(buffer, count, &input);1030 if (err)1031 return err;1032 1033 if (input)1034 set_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags);1035 else1036 clear_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags);1037 1038 return count;1039}1040 1041static int rtw_debugfs_get_force_lowest_basic_rate(struct seq_file *m, void *v)1042{1043 struct rtw_debugfs_priv *debugfs_priv = m->private;1044 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;1045 1046 seq_printf(m, "force lowest basic rate: %d\n",1047 test_bit(RTW_FLAG_FORCE_LOWEST_RATE, rtwdev->flags));1048 1049 return 0;1050}1051 1052static ssize_t rtw_debugfs_set_dm_cap(struct file *filp,1053 const char __user *buffer,1054 size_t count, loff_t *loff)1055{1056 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;1057 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;1058 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;1059 struct rtw_dm_info *dm_info = &rtwdev->dm_info;1060 int ret, bit;1061 bool en;1062 1063 ret = kstrtoint_from_user(buffer, count, 10, &bit);1064 if (ret)1065 return ret;1066 1067 en = bit > 0;1068 bit = abs(bit);1069 1070 if (bit >= RTW_DM_CAP_NUM) {1071 rtw_warn(rtwdev, "unknown DM CAP %d\n", bit);1072 return -EINVAL;1073 }1074 1075 if (en)1076 dm_info->dm_flags &= ~BIT(bit);1077 else1078 dm_info->dm_flags |= BIT(bit);1079 1080 debugfs_priv->dm_cap.bit = bit;1081 1082 return count;1083}1084 1085static void dump_gapk_status(struct rtw_dev *rtwdev, struct seq_file *m)1086{1087 struct rtw_dm_info *dm_info = &rtwdev->dm_info;1088 struct rtw_gapk_info *txgapk = &rtwdev->dm_info.gapk;1089 int i, path;1090 u32 val;1091 1092 seq_printf(m, "\n(%2d) %c%s\n\n", RTW_DM_CAP_TXGAPK,1093 dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+',1094 rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]);1095 1096 mutex_lock(&rtwdev->mutex);1097 1098 for (path = 0; path < rtwdev->hal.rf_path_num; path++) {1099 val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK);1100 seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val);1101 1102 for (i = 0; i < RF_HW_OFFSET_NUM; i++)1103 seq_printf(m, "[TXGAPK] offset %d %d\n",1104 txgapk->rf3f_fs[path][i], i);1105 seq_puts(m, "\n");1106 }1107 mutex_unlock(&rtwdev->mutex);1108}1109 1110static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v)1111{1112 struct rtw_debugfs_priv *debugfs_priv = m->private;1113 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;1114 struct rtw_dm_info *dm_info = &rtwdev->dm_info;1115 int i;1116 1117 switch (debugfs_priv->dm_cap.bit) {1118 case RTW_DM_CAP_TXGAPK:1119 dump_gapk_status(rtwdev, m);1120 break;1121 default:1122 for (i = 1; i < RTW_DM_CAP_NUM; i++) {1123 seq_printf(m, "(%2d) %c%s\n", i,1124 dm_info->dm_flags & BIT(i) ? '-' : '+',1125 rtw_dm_cap_strs[i]);1126 }1127 break;1128 }1129 debugfs_priv->dm_cap.bit = RTW_DM_CAP_NA;1130 return 0;1131}1132 1133#define rtw_debug_priv_mac(addr) \1134{ \1135 .cb_read = rtw_debug_get_mac_page, \1136 .cb_data = addr, \1137}1138 1139#define rtw_debug_priv_bb(addr) \1140{ \1141 .cb_read = rtw_debug_get_bb_page, \1142 .cb_data = addr, \1143}1144 1145#define rtw_debug_priv_get(name) \1146{ \1147 .cb_read = rtw_debugfs_get_ ##name, \1148}1149 1150#define rtw_debug_priv_set(name) \1151{ \1152 .cb_write = rtw_debugfs_set_ ##name, \1153}1154 1155#define rtw_debug_priv_set_and_get(name) \1156{ \1157 .cb_write = rtw_debugfs_set_ ##name, \1158 .cb_read = rtw_debugfs_get_ ##name, \1159}1160 1161#define rtw_debug_priv_set_single_and_get(name) \1162{ \1163 .cb_write = rtw_debugfs_set_single_input, \1164 .cb_read = rtw_debugfs_get_ ##name, \1165}1166 1167static const struct rtw_debugfs rtw_debugfs_templ = {1168 .mac_0 = rtw_debug_priv_mac(0x0000),1169 .mac_1 = rtw_debug_priv_mac(0x0100),1170 .mac_2 = rtw_debug_priv_mac(0x0200),1171 .mac_3 = rtw_debug_priv_mac(0x0300),1172 .mac_4 = rtw_debug_priv_mac(0x0400),1173 .mac_5 = rtw_debug_priv_mac(0x0500),1174 .mac_6 = rtw_debug_priv_mac(0x0600),1175 .mac_7 = rtw_debug_priv_mac(0x0700),1176 .mac_10 = rtw_debug_priv_mac(0x1000),1177 .mac_11 = rtw_debug_priv_mac(0x1100),1178 .mac_12 = rtw_debug_priv_mac(0x1200),1179 .mac_13 = rtw_debug_priv_mac(0x1300),1180 .mac_14 = rtw_debug_priv_mac(0x1400),1181 .mac_15 = rtw_debug_priv_mac(0x1500),1182 .mac_16 = rtw_debug_priv_mac(0x1600),1183 .mac_17 = rtw_debug_priv_mac(0x1700),1184 .bb_8 = rtw_debug_priv_bb(0x0800),1185 .bb_9 = rtw_debug_priv_bb(0x0900),1186 .bb_a = rtw_debug_priv_bb(0x0a00),1187 .bb_b = rtw_debug_priv_bb(0x0b00),1188 .bb_c = rtw_debug_priv_bb(0x0c00),1189 .bb_d = rtw_debug_priv_bb(0x0d00),1190 .bb_e = rtw_debug_priv_bb(0x0e00),1191 .bb_f = rtw_debug_priv_bb(0x0f00),1192 .bb_18 = rtw_debug_priv_bb(0x1800),1193 .bb_19 = rtw_debug_priv_bb(0x1900),1194 .bb_1a = rtw_debug_priv_bb(0x1a00),1195 .bb_1b = rtw_debug_priv_bb(0x1b00),1196 .bb_1c = rtw_debug_priv_bb(0x1c00),1197 .bb_1d = rtw_debug_priv_bb(0x1d00),1198 .bb_1e = rtw_debug_priv_bb(0x1e00),1199 .bb_1f = rtw_debug_priv_bb(0x1f00),1200 .bb_2c = rtw_debug_priv_bb(0x2c00),1201 .bb_2d = rtw_debug_priv_bb(0x2d00),1202 .bb_40 = rtw_debug_priv_bb(0x4000),1203 .bb_41 = rtw_debug_priv_bb(0x4100),1204 .rf_dump = rtw_debug_priv_get(rf_dump),1205 .tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl),1206 .write_reg = rtw_debug_priv_set(write_reg),1207 .h2c = rtw_debug_priv_set(h2c),1208 .rf_write = rtw_debug_priv_set(rf_write),1209 .rf_read = rtw_debug_priv_set_and_get(rf_read),1210 .read_reg = rtw_debug_priv_set_and_get(read_reg),1211 .fix_rate = rtw_debug_priv_set_and_get(fix_rate),1212 .dump_cam = rtw_debug_priv_set_single_and_get(dump_cam),1213 .rsvd_page = rtw_debug_priv_set_and_get(rsvd_page),1214 .phy_info = rtw_debug_priv_get(phy_info),1215 .coex_enable = rtw_debug_priv_set_and_get(coex_enable),1216 .coex_info = rtw_debug_priv_get(coex_info),1217 .edcca_enable = rtw_debug_priv_set_and_get(edcca_enable),1218 .fw_crash = rtw_debug_priv_set_and_get(fw_crash),1219 .force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate),1220 .dm_cap = rtw_debug_priv_set_and_get(dm_cap),1221};1222 1223#define rtw_debugfs_add_core(name, mode, fopname, parent) \1224 do { \1225 struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \1226 priv->rtwdev = rtwdev; \1227 if (IS_ERR(debugfs_create_file(#name, mode, \1228 parent, priv, \1229 &file_ops_ ##fopname))) \1230 pr_debug("Unable to initialize debugfs:%s\n", \1231 #name); \1232 } while (0)1233 1234#define rtw_debugfs_add_w(name) \1235 rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir)1236#define rtw_debugfs_add_rw(name) \1237 rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir)1238#define rtw_debugfs_add_r(name) \1239 rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)1240 1241static1242void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)1243{1244 rtw_debugfs_add_w(write_reg);1245 rtw_debugfs_add_rw(read_reg);1246 rtw_debugfs_add_w(rf_write);1247 rtw_debugfs_add_rw(rf_read);1248 rtw_debugfs_add_rw(fix_rate);1249 rtw_debugfs_add_rw(dump_cam);1250 rtw_debugfs_add_rw(rsvd_page);1251 rtw_debugfs_add_r(phy_info);1252 rtw_debugfs_add_r(coex_info);1253 rtw_debugfs_add_rw(coex_enable);1254 rtw_debugfs_add_w(h2c);1255 rtw_debugfs_add_r(rf_dump);1256 rtw_debugfs_add_r(tx_pwr_tbl);1257 rtw_debugfs_add_rw(edcca_enable);1258 rtw_debugfs_add_rw(fw_crash);1259 rtw_debugfs_add_rw(force_lowest_basic_rate);1260 rtw_debugfs_add_rw(dm_cap);1261}1262 1263static1264void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)1265{1266 rtw_debugfs_add_r(mac_0);1267 rtw_debugfs_add_r(mac_1);1268 rtw_debugfs_add_r(mac_2);1269 rtw_debugfs_add_r(mac_3);1270 rtw_debugfs_add_r(mac_4);1271 rtw_debugfs_add_r(mac_5);1272 rtw_debugfs_add_r(mac_6);1273 rtw_debugfs_add_r(mac_7);1274 rtw_debugfs_add_r(bb_8);1275 rtw_debugfs_add_r(bb_9);1276 rtw_debugfs_add_r(bb_a);1277 rtw_debugfs_add_r(bb_b);1278 rtw_debugfs_add_r(bb_c);1279 rtw_debugfs_add_r(bb_d);1280 rtw_debugfs_add_r(bb_e);1281 rtw_debugfs_add_r(bb_f);1282}1283 1284static1285void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir)1286{1287 rtw_debugfs_add_r(mac_10);1288 rtw_debugfs_add_r(mac_11);1289 rtw_debugfs_add_r(mac_12);1290 rtw_debugfs_add_r(mac_13);1291 rtw_debugfs_add_r(mac_14);1292 rtw_debugfs_add_r(mac_15);1293 rtw_debugfs_add_r(mac_16);1294 rtw_debugfs_add_r(mac_17);1295 rtw_debugfs_add_r(bb_18);1296 rtw_debugfs_add_r(bb_19);1297 rtw_debugfs_add_r(bb_1a);1298 rtw_debugfs_add_r(bb_1b);1299 rtw_debugfs_add_r(bb_1c);1300 rtw_debugfs_add_r(bb_1d);1301 rtw_debugfs_add_r(bb_1e);1302 rtw_debugfs_add_r(bb_1f);1303 if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {1304 rtw_debugfs_add_r(bb_2c);1305 rtw_debugfs_add_r(bb_2d);1306 rtw_debugfs_add_r(bb_40);1307 rtw_debugfs_add_r(bb_41);1308 }1309}1310 1311void rtw_debugfs_init(struct rtw_dev *rtwdev)1312{1313 struct dentry *debugfs_topdir;1314 1315 rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ),1316 GFP_KERNEL);1317 if (!rtwdev->debugfs)1318 return;1319 1320 debugfs_topdir = debugfs_create_dir("rtw88",1321 rtwdev->hw->wiphy->debugfsdir);1322 1323 rtw_debugfs_add_basic(rtwdev, debugfs_topdir);1324 rtw_debugfs_add_sec0(rtwdev, debugfs_topdir);1325 rtw_debugfs_add_sec1(rtwdev, debugfs_topdir);1326}1327 1328void rtw_debugfs_deinit(struct rtw_dev *rtwdev)1329{1330 kfree(rtwdev->debugfs);1331}1332#endif /* CONFIG_RTW88_DEBUGFS */1333 1334#ifdef CONFIG_RTW88_DEBUG1335 1336void rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,1337 const char *fmt, ...)1338{1339 struct va_format vaf = {1340 .fmt = fmt,1341 };1342 va_list args;1343 1344 va_start(args, fmt);1345 vaf.va = &args;1346 1347 if (rtw_debug_mask & mask)1348 dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf);1349 1350 va_end(args);1351}1352EXPORT_SYMBOL(rtw_dbg);1353 1354#endif /* CONFIG_RTW88_DEBUG */1355