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