debug.c (13071B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright(c) 2009-2012 Realtek Corporation.*/ 3 4#include "wifi.h" 5#include "cam.h" 6 7#include <linux/moduleparam.h> 8#include <linux/vmalloc.h> 9 10#ifdef CONFIG_RTLWIFI_DEBUG 11void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level, 12 const char *fmt, ...) 13{ 14 if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) && 15 level <= rtlpriv->cfg->mod_params->debug_level)) { 16 struct va_format vaf; 17 va_list args; 18 19 va_start(args, fmt); 20 21 vaf.fmt = fmt; 22 vaf.va = &args; 23 24 pr_info("%pV", &vaf); 25 26 va_end(args); 27 } 28} 29EXPORT_SYMBOL_GPL(_rtl_dbg_print); 30 31void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level, 32 const char *titlestring, 33 const void *hexdata, int hexdatalen) 34{ 35 if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) && 36 ((level) <= rtlpriv->cfg->mod_params->debug_level))) { 37 pr_info("In process \"%s\" (pid %i): %s\n", 38 current->comm, current->pid, titlestring); 39 print_hex_dump_bytes("", DUMP_PREFIX_NONE, 40 hexdata, hexdatalen); 41 } 42} 43EXPORT_SYMBOL_GPL(_rtl_dbg_print_data); 44 45struct rtl_debugfs_priv { 46 struct rtl_priv *rtlpriv; 47 int (*cb_read)(struct seq_file *m, void *v); 48 ssize_t (*cb_write)(struct file *filp, const char __user *buffer, 49 size_t count, loff_t *loff); 50 u32 cb_data; 51}; 52 53static struct dentry *debugfs_topdir; 54 55static int rtl_debug_get_common(struct seq_file *m, void *v) 56{ 57 struct rtl_debugfs_priv *debugfs_priv = m->private; 58 59 return debugfs_priv->cb_read(m, v); 60} 61 62static int dl_debug_open_common(struct inode *inode, struct file *file) 63{ 64 return single_open(file, rtl_debug_get_common, inode->i_private); 65} 66 67static const struct file_operations file_ops_common = { 68 .open = dl_debug_open_common, 69 .read = seq_read, 70 .llseek = seq_lseek, 71 .release = single_release, 72}; 73 74static int rtl_debug_get_mac_page(struct seq_file *m, void *v) 75{ 76 struct rtl_debugfs_priv *debugfs_priv = m->private; 77 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 78 u32 page = debugfs_priv->cb_data; 79 int i, n; 80 int max = 0xff; 81 82 for (n = 0; n <= max; ) { 83 seq_printf(m, "\n%8.8x ", n + page); 84 for (i = 0; i < 4 && n <= max; i++, n += 4) 85 seq_printf(m, "%8.8x ", 86 rtl_read_dword(rtlpriv, (page | n))); 87 } 88 seq_puts(m, "\n"); 89 return 0; 90} 91 92#define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \ 93static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \ 94 .cb_read = rtl_debug_get_mac_page, \ 95 .cb_data = addr, \ 96} 97 98RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000); 99RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100); 100RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200); 101RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300); 102RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400); 103RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500); 104RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600); 105RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700); 106RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000); 107RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100); 108RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200); 109RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300); 110RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400); 111RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500); 112RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600); 113RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700); 114 115static int rtl_debug_get_bb_page(struct seq_file *m, void *v) 116{ 117 struct rtl_debugfs_priv *debugfs_priv = m->private; 118 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 119 struct ieee80211_hw *hw = rtlpriv->hw; 120 u32 page = debugfs_priv->cb_data; 121 int i, n; 122 int max = 0xff; 123 124 for (n = 0; n <= max; ) { 125 seq_printf(m, "\n%8.8x ", n + page); 126 for (i = 0; i < 4 && n <= max; i++, n += 4) 127 seq_printf(m, "%8.8x ", 128 rtl_get_bbreg(hw, (page | n), 0xffffffff)); 129 } 130 seq_puts(m, "\n"); 131 return 0; 132} 133 134#define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \ 135static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \ 136 .cb_read = rtl_debug_get_bb_page, \ 137 .cb_data = addr, \ 138} 139 140RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800); 141RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900); 142RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00); 143RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00); 144RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00); 145RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00); 146RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00); 147RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00); 148RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800); 149RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900); 150RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00); 151RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00); 152RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00); 153RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00); 154RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00); 155RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00); 156 157static int rtl_debug_get_reg_rf(struct seq_file *m, void *v) 158{ 159 struct rtl_debugfs_priv *debugfs_priv = m->private; 160 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 161 struct ieee80211_hw *hw = rtlpriv->hw; 162 enum radio_path rfpath = debugfs_priv->cb_data; 163 int i, n; 164 int max = 0x40; 165 166 if (IS_HARDWARE_TYPE_8822B(rtlpriv)) 167 max = 0xff; 168 169 seq_printf(m, "\nPATH(%d)", rfpath); 170 171 for (n = 0; n <= max; ) { 172 seq_printf(m, "\n%8.8x ", n); 173 for (i = 0; i < 4 && n <= max; n += 1, i++) 174 seq_printf(m, "%8.8x ", 175 rtl_get_rfreg(hw, rfpath, n, 0xffffffff)); 176 } 177 seq_puts(m, "\n"); 178 return 0; 179} 180 181#define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \ 182static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \ 183 .cb_read = rtl_debug_get_reg_rf, \ 184 .cb_data = addr, \ 185} 186 187RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A); 188RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B); 189 190static int rtl_debug_get_cam_register(struct seq_file *m, void *v) 191{ 192 struct rtl_debugfs_priv *debugfs_priv = m->private; 193 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 194 int start = debugfs_priv->cb_data; 195 u32 target_cmd = 0; 196 u32 target_val = 0; 197 u8 entry_i = 0; 198 u32 ulstatus; 199 int i = 100, j = 0; 200 int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11); 201 202 /* This dump the current register page */ 203 seq_printf(m, 204 "\n#################### SECURITY CAM (%d-%d) ##################\n", 205 start, end - 1); 206 207 for (j = start; j < end; j++) { 208 seq_printf(m, "\nD: %2x > ", j); 209 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { 210 /* polling bit, and No Write enable, and address */ 211 target_cmd = entry_i + CAM_CONTENT_COUNT * j; 212 target_cmd = target_cmd | BIT(31); 213 214 /* Check polling bit is clear */ 215 while ((i--) >= 0) { 216 ulstatus = 217 rtl_read_dword(rtlpriv, 218 rtlpriv->cfg->maps[RWCAM]); 219 if (ulstatus & BIT(31)) 220 continue; 221 else 222 break; 223 } 224 225 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], 226 target_cmd); 227 target_val = rtl_read_dword(rtlpriv, 228 rtlpriv->cfg->maps[RCAMO]); 229 seq_printf(m, "%8.8x ", target_val); 230 } 231 } 232 seq_puts(m, "\n"); 233 return 0; 234} 235 236#define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \ 237static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \ 238 .cb_read = rtl_debug_get_cam_register, \ 239 .cb_data = addr, \ 240} 241 242RTL_DEBUG_IMPL_CAM_SERIES(1, 0); 243RTL_DEBUG_IMPL_CAM_SERIES(2, 11); 244RTL_DEBUG_IMPL_CAM_SERIES(3, 22); 245 246static int rtl_debug_get_btcoex(struct seq_file *m, void *v) 247{ 248 struct rtl_debugfs_priv *debugfs_priv = m->private; 249 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 250 251 if (rtlpriv->cfg->ops->get_btc_status()) 252 rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv, 253 m); 254 255 seq_puts(m, "\n"); 256 257 return 0; 258} 259 260static struct rtl_debugfs_priv rtl_debug_priv_btcoex = { 261 .cb_read = rtl_debug_get_btcoex, 262 .cb_data = 0, 263}; 264 265static ssize_t rtl_debugfs_set_write_reg(struct file *filp, 266 const char __user *buffer, 267 size_t count, loff_t *loff) 268{ 269 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 270 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 271 char tmp[32 + 1]; 272 int tmp_len; 273 u32 addr, val, len; 274 int num; 275 276 if (count < 3) 277 return -EFAULT; 278 279 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); 280 281 if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 282 return count; 283 284 tmp[tmp_len] = '\0'; 285 286 /* write BB/MAC register */ 287 num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 288 289 if (num != 3) 290 return count; 291 292 switch (len) { 293 case 1: 294 rtl_write_byte(rtlpriv, addr, (u8)val); 295 break; 296 case 2: 297 rtl_write_word(rtlpriv, addr, (u16)val); 298 break; 299 case 4: 300 rtl_write_dword(rtlpriv, addr, val); 301 break; 302 default: 303 /*printk("error write length=%d", len);*/ 304 break; 305 } 306 307 return count; 308} 309 310static struct rtl_debugfs_priv rtl_debug_priv_write_reg = { 311 .cb_write = rtl_debugfs_set_write_reg, 312}; 313 314static ssize_t rtl_debugfs_set_write_h2c(struct file *filp, 315 const char __user *buffer, 316 size_t count, loff_t *loff) 317{ 318 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 319 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 320 struct ieee80211_hw *hw = rtlpriv->hw; 321 char tmp[32 + 1]; 322 int tmp_len; 323 u8 h2c_len, h2c_data_packed[8]; 324 int h2c_data[8]; /* idx 0: cmd */ 325 int i; 326 327 if (count < 3) 328 return -EFAULT; 329 330 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); 331 332 if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 333 return count; 334 335 tmp[tmp_len] = '\0'; 336 337 h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X", 338 &h2c_data[0], &h2c_data[1], 339 &h2c_data[2], &h2c_data[3], 340 &h2c_data[4], &h2c_data[5], 341 &h2c_data[6], &h2c_data[7]); 342 343 if (h2c_len <= 0) 344 return count; 345 346 for (i = 0; i < h2c_len; i++) 347 h2c_data_packed[i] = (u8)h2c_data[i]; 348 349 rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0], 350 h2c_len - 1, 351 &h2c_data_packed[1]); 352 353 return count; 354} 355 356static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = { 357 .cb_write = rtl_debugfs_set_write_h2c, 358}; 359 360static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, 361 const char __user *buffer, 362 size_t count, loff_t *loff) 363{ 364 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 365 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 366 struct ieee80211_hw *hw = rtlpriv->hw; 367 char tmp[32 + 1]; 368 int tmp_len; 369 int num; 370 int path; 371 u32 addr, bitmask, data; 372 373 if (count < 3) 374 return -EFAULT; 375 376 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); 377 378 if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 379 return count; 380 381 tmp[tmp_len] = '\0'; 382 383 num = sscanf(tmp, "%X %X %X %X", 384 &path, &addr, &bitmask, &data); 385 386 if (num != 4) { 387 rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, 388 "Format is <path> <addr> <mask> <data>\n"); 389 return count; 390 } 391 392 rtl_set_rfreg(hw, path, addr, bitmask, data); 393 394 return count; 395} 396 397static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = { 398 .cb_write = rtl_debugfs_set_write_rfreg, 399}; 400 401static int rtl_debugfs_close(struct inode *inode, struct file *filp) 402{ 403 return 0; 404} 405 406static ssize_t rtl_debugfs_common_write(struct file *filp, 407 const char __user *buffer, 408 size_t count, loff_t *loff) 409{ 410 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 411 412 return debugfs_priv->cb_write(filp, buffer, count, loff); 413} 414 415static const struct file_operations file_ops_common_write = { 416 .owner = THIS_MODULE, 417 .write = rtl_debugfs_common_write, 418 .open = simple_open, 419 .release = rtl_debugfs_close, 420}; 421 422#define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \ 423 do { \ 424 rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \ 425 debugfs_create_file(#name, mode, parent, \ 426 &rtl_debug_priv_ ##name, \ 427 &file_ops_ ##fopname); \ 428 } while (0) 429 430#define RTL_DEBUGFS_ADD(name) \ 431 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common) 432#define RTL_DEBUGFS_ADD_W(name) \ 433 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write) 434 435void rtl_debug_add_one(struct ieee80211_hw *hw) 436{ 437 struct rtl_priv *rtlpriv = rtl_priv(hw); 438 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 439 struct dentry *parent; 440 441 snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr); 442 443 rtlpriv->dbg.debugfs_dir = 444 debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir); 445 446 parent = rtlpriv->dbg.debugfs_dir; 447 448 RTL_DEBUGFS_ADD(mac_0); 449 RTL_DEBUGFS_ADD(mac_1); 450 RTL_DEBUGFS_ADD(mac_2); 451 RTL_DEBUGFS_ADD(mac_3); 452 RTL_DEBUGFS_ADD(mac_4); 453 RTL_DEBUGFS_ADD(mac_5); 454 RTL_DEBUGFS_ADD(mac_6); 455 RTL_DEBUGFS_ADD(mac_7); 456 RTL_DEBUGFS_ADD(bb_8); 457 RTL_DEBUGFS_ADD(bb_9); 458 RTL_DEBUGFS_ADD(bb_a); 459 RTL_DEBUGFS_ADD(bb_b); 460 RTL_DEBUGFS_ADD(bb_c); 461 RTL_DEBUGFS_ADD(bb_d); 462 RTL_DEBUGFS_ADD(bb_e); 463 RTL_DEBUGFS_ADD(bb_f); 464 RTL_DEBUGFS_ADD(mac_10); 465 RTL_DEBUGFS_ADD(mac_11); 466 RTL_DEBUGFS_ADD(mac_12); 467 RTL_DEBUGFS_ADD(mac_13); 468 RTL_DEBUGFS_ADD(mac_14); 469 RTL_DEBUGFS_ADD(mac_15); 470 RTL_DEBUGFS_ADD(mac_16); 471 RTL_DEBUGFS_ADD(mac_17); 472 RTL_DEBUGFS_ADD(bb_18); 473 RTL_DEBUGFS_ADD(bb_19); 474 RTL_DEBUGFS_ADD(bb_1a); 475 RTL_DEBUGFS_ADD(bb_1b); 476 RTL_DEBUGFS_ADD(bb_1c); 477 RTL_DEBUGFS_ADD(bb_1d); 478 RTL_DEBUGFS_ADD(bb_1e); 479 RTL_DEBUGFS_ADD(bb_1f); 480 RTL_DEBUGFS_ADD(rf_a); 481 RTL_DEBUGFS_ADD(rf_b); 482 483 RTL_DEBUGFS_ADD(cam_1); 484 RTL_DEBUGFS_ADD(cam_2); 485 RTL_DEBUGFS_ADD(cam_3); 486 487 RTL_DEBUGFS_ADD(btcoex); 488 489 RTL_DEBUGFS_ADD_W(write_reg); 490 RTL_DEBUGFS_ADD_W(write_h2c); 491 RTL_DEBUGFS_ADD_W(write_rfreg); 492} 493EXPORT_SYMBOL_GPL(rtl_debug_add_one); 494 495void rtl_debug_remove_one(struct ieee80211_hw *hw) 496{ 497 struct rtl_priv *rtlpriv = rtl_priv(hw); 498 499 debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir); 500 rtlpriv->dbg.debugfs_dir = NULL; 501} 502EXPORT_SYMBOL_GPL(rtl_debug_remove_one); 503 504void rtl_debugfs_add_topdir(void) 505{ 506 debugfs_topdir = debugfs_create_dir("rtlwifi", NULL); 507} 508 509void rtl_debugfs_remove_topdir(void) 510{ 511 debugfs_remove_recursive(debugfs_topdir); 512} 513 514#endif