Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2009-2012  Realtek Corporation.*/
0003 
0004 #include "wifi.h"
0005 #include "cam.h"
0006 
0007 #include <linux/moduleparam.h>
0008 #include <linux/vmalloc.h>
0009 
0010 #ifdef CONFIG_RTLWIFI_DEBUG
0011 void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
0012             const char *fmt, ...)
0013 {
0014     if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
0015              level <= rtlpriv->cfg->mod_params->debug_level)) {
0016         struct va_format vaf;
0017         va_list args;
0018 
0019         va_start(args, fmt);
0020 
0021         vaf.fmt = fmt;
0022         vaf.va = &args;
0023 
0024         pr_info("%pV", &vaf);
0025 
0026         va_end(args);
0027     }
0028 }
0029 EXPORT_SYMBOL_GPL(_rtl_dbg_print);
0030 
0031 void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
0032              const char *titlestring,
0033              const void *hexdata, int hexdatalen)
0034 {
0035     if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) &&
0036              ((level) <= rtlpriv->cfg->mod_params->debug_level))) {
0037         pr_info("In process \"%s\" (pid %i): %s\n",
0038             current->comm, current->pid, titlestring);
0039         print_hex_dump_bytes("", DUMP_PREFIX_NONE,
0040                      hexdata, hexdatalen);
0041     }
0042 }
0043 EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
0044 
0045 struct rtl_debugfs_priv {
0046     struct rtl_priv *rtlpriv;
0047     int (*cb_read)(struct seq_file *m, void *v);
0048     ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
0049                 size_t count, loff_t *loff);
0050     u32 cb_data;
0051 };
0052 
0053 static struct dentry *debugfs_topdir;
0054 
0055 static int rtl_debug_get_common(struct seq_file *m, void *v)
0056 {
0057     struct rtl_debugfs_priv *debugfs_priv = m->private;
0058 
0059     return debugfs_priv->cb_read(m, v);
0060 }
0061 
0062 static int dl_debug_open_common(struct inode *inode, struct file *file)
0063 {
0064     return single_open(file, rtl_debug_get_common, inode->i_private);
0065 }
0066 
0067 static const struct file_operations file_ops_common = {
0068     .open = dl_debug_open_common,
0069     .read = seq_read,
0070     .llseek = seq_lseek,
0071     .release = single_release,
0072 };
0073 
0074 static int rtl_debug_get_mac_page(struct seq_file *m, void *v)
0075 {
0076     struct rtl_debugfs_priv *debugfs_priv = m->private;
0077     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0078     u32 page = debugfs_priv->cb_data;
0079     int i, n;
0080     int max = 0xff;
0081 
0082     for (n = 0; n <= max; ) {
0083         seq_printf(m, "\n%8.8x  ", n + page);
0084         for (i = 0; i < 4 && n <= max; i++, n += 4)
0085             seq_printf(m, "%8.8x    ",
0086                    rtl_read_dword(rtlpriv, (page | n)));
0087     }
0088     seq_puts(m, "\n");
0089     return 0;
0090 }
0091 
0092 #define RTL_DEBUG_IMPL_MAC_SERIES(page, addr)           \
0093 static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = {   \
0094     .cb_read = rtl_debug_get_mac_page,          \
0095     .cb_data = addr,                    \
0096 }
0097 
0098 RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
0099 RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
0100 RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
0101 RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
0102 RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
0103 RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
0104 RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
0105 RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
0106 RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
0107 RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
0108 RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
0109 RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
0110 RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
0111 RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
0112 RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
0113 RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
0114 
0115 static int rtl_debug_get_bb_page(struct seq_file *m, void *v)
0116 {
0117     struct rtl_debugfs_priv *debugfs_priv = m->private;
0118     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0119     struct ieee80211_hw *hw = rtlpriv->hw;
0120     u32 page = debugfs_priv->cb_data;
0121     int i, n;
0122     int max = 0xff;
0123 
0124     for (n = 0; n <= max; ) {
0125         seq_printf(m, "\n%8.8x  ", n + page);
0126         for (i = 0; i < 4 && n <= max; i++, n += 4)
0127             seq_printf(m, "%8.8x    ",
0128                    rtl_get_bbreg(hw, (page | n), 0xffffffff));
0129     }
0130     seq_puts(m, "\n");
0131     return 0;
0132 }
0133 
0134 #define RTL_DEBUG_IMPL_BB_SERIES(page, addr)            \
0135 static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = {    \
0136     .cb_read = rtl_debug_get_bb_page,           \
0137     .cb_data = addr,                    \
0138 }
0139 
0140 RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
0141 RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
0142 RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00);
0143 RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00);
0144 RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00);
0145 RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00);
0146 RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00);
0147 RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00);
0148 RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
0149 RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
0150 RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00);
0151 RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00);
0152 RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00);
0153 RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00);
0154 RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00);
0155 RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00);
0156 
0157 static int rtl_debug_get_reg_rf(struct seq_file *m, void *v)
0158 {
0159     struct rtl_debugfs_priv *debugfs_priv = m->private;
0160     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0161     struct ieee80211_hw *hw = rtlpriv->hw;
0162     enum radio_path rfpath = debugfs_priv->cb_data;
0163     int i, n;
0164     int max = 0x40;
0165 
0166     if (IS_HARDWARE_TYPE_8822B(rtlpriv))
0167         max = 0xff;
0168 
0169     seq_printf(m, "\nPATH(%d)", rfpath);
0170 
0171     for (n = 0; n <= max; ) {
0172         seq_printf(m, "\n%8.8x  ", n);
0173         for (i = 0; i < 4 && n <= max; n += 1, i++)
0174             seq_printf(m, "%8.8x    ",
0175                    rtl_get_rfreg(hw, rfpath, n, 0xffffffff));
0176     }
0177     seq_puts(m, "\n");
0178     return 0;
0179 }
0180 
0181 #define RTL_DEBUG_IMPL_RF_SERIES(page, addr)            \
0182 static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = {    \
0183     .cb_read = rtl_debug_get_reg_rf,            \
0184     .cb_data = addr,                    \
0185 }
0186 
0187 RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A);
0188 RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B);
0189 
0190 static int rtl_debug_get_cam_register(struct seq_file *m, void *v)
0191 {
0192     struct rtl_debugfs_priv *debugfs_priv = m->private;
0193     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0194     int start = debugfs_priv->cb_data;
0195     u32 target_cmd = 0;
0196     u32 target_val = 0;
0197     u8 entry_i = 0;
0198     u32 ulstatus;
0199     int i = 100, j = 0;
0200     int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11);
0201 
0202     /* This dump the current register page */
0203     seq_printf(m,
0204            "\n#################### SECURITY CAM (%d-%d) ##################\n",
0205            start, end - 1);
0206 
0207     for (j = start; j < end; j++) {
0208         seq_printf(m, "\nD:  %2x > ", j);
0209         for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
0210             /* polling bit, and No Write enable, and address  */
0211             target_cmd = entry_i + CAM_CONTENT_COUNT * j;
0212             target_cmd = target_cmd | BIT(31);
0213 
0214             /* Check polling bit is clear */
0215             while ((i--) >= 0) {
0216                 ulstatus =
0217                     rtl_read_dword(rtlpriv,
0218                            rtlpriv->cfg->maps[RWCAM]);
0219                 if (ulstatus & BIT(31))
0220                     continue;
0221                 else
0222                     break;
0223             }
0224 
0225             rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
0226                     target_cmd);
0227             target_val = rtl_read_dword(rtlpriv,
0228                             rtlpriv->cfg->maps[RCAMO]);
0229             seq_printf(m, "%8.8x ", target_val);
0230         }
0231     }
0232     seq_puts(m, "\n");
0233     return 0;
0234 }
0235 
0236 #define RTL_DEBUG_IMPL_CAM_SERIES(page, addr)           \
0237 static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = {   \
0238     .cb_read = rtl_debug_get_cam_register,          \
0239     .cb_data = addr,                    \
0240 }
0241 
0242 RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
0243 RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
0244 RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
0245 
0246 static int rtl_debug_get_btcoex(struct seq_file *m, void *v)
0247 {
0248     struct rtl_debugfs_priv *debugfs_priv = m->private;
0249     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0250 
0251     if (rtlpriv->cfg->ops->get_btc_status())
0252         rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv,
0253                                      m);
0254 
0255     seq_puts(m, "\n");
0256 
0257     return 0;
0258 }
0259 
0260 static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
0261     .cb_read = rtl_debug_get_btcoex,
0262     .cb_data = 0,
0263 };
0264 
0265 static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
0266                      const char __user *buffer,
0267                      size_t count, loff_t *loff)
0268 {
0269     struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
0270     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0271     char tmp[32 + 1];
0272     int tmp_len;
0273     u32 addr, val, len;
0274     int num;
0275 
0276     if (count < 3)
0277         return -EFAULT;
0278 
0279     tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
0280 
0281     if (!buffer || copy_from_user(tmp, buffer, tmp_len))
0282         return count;
0283 
0284     tmp[tmp_len] = '\0';
0285 
0286     /* write BB/MAC register */
0287     num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
0288 
0289     if (num !=  3)
0290         return count;
0291 
0292     switch (len) {
0293     case 1:
0294         rtl_write_byte(rtlpriv, addr, (u8)val);
0295         break;
0296     case 2:
0297         rtl_write_word(rtlpriv, addr, (u16)val);
0298         break;
0299     case 4:
0300         rtl_write_dword(rtlpriv, addr, val);
0301         break;
0302     default:
0303         /*printk("error write length=%d", len);*/
0304         break;
0305     }
0306 
0307     return count;
0308 }
0309 
0310 static struct rtl_debugfs_priv rtl_debug_priv_write_reg = {
0311     .cb_write = rtl_debugfs_set_write_reg,
0312 };
0313 
0314 static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
0315                      const char __user *buffer,
0316                      size_t count, loff_t *loff)
0317 {
0318     struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
0319     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0320     struct ieee80211_hw *hw = rtlpriv->hw;
0321     char tmp[32 + 1];
0322     int tmp_len;
0323     u8 h2c_len, h2c_data_packed[8];
0324     int h2c_data[8];    /* idx 0: cmd */
0325     int i;
0326 
0327     if (count < 3)
0328         return -EFAULT;
0329 
0330     tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
0331 
0332     if (copy_from_user(tmp, buffer, tmp_len))
0333         return -EFAULT;
0334 
0335     tmp[tmp_len] = '\0';
0336 
0337     h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X",
0338              &h2c_data[0], &h2c_data[1],
0339              &h2c_data[2], &h2c_data[3],
0340              &h2c_data[4], &h2c_data[5],
0341              &h2c_data[6], &h2c_data[7]);
0342 
0343     if (h2c_len == 0)
0344         return -EINVAL;
0345 
0346     for (i = 0; i < h2c_len; i++)
0347         h2c_data_packed[i] = (u8)h2c_data[i];
0348 
0349     rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0],
0350                     h2c_len - 1,
0351                     &h2c_data_packed[1]);
0352 
0353     return count;
0354 }
0355 
0356 static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = {
0357     .cb_write = rtl_debugfs_set_write_h2c,
0358 };
0359 
0360 static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
0361                        const char __user *buffer,
0362                         size_t count, loff_t *loff)
0363 {
0364     struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
0365     struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
0366     struct ieee80211_hw *hw = rtlpriv->hw;
0367     char tmp[32 + 1];
0368     int tmp_len;
0369     int num;
0370     int path;
0371     u32 addr, bitmask, data;
0372 
0373     if (count < 3)
0374         return -EFAULT;
0375 
0376     tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
0377 
0378     if (!buffer || copy_from_user(tmp, buffer, tmp_len))
0379         return count;
0380 
0381     tmp[tmp_len] = '\0';
0382 
0383     num = sscanf(tmp, "%X %X %X %X",
0384              &path, &addr, &bitmask, &data);
0385 
0386     if (num != 4) {
0387         rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
0388             "Format is <path> <addr> <mask> <data>\n");
0389         return count;
0390     }
0391 
0392     rtl_set_rfreg(hw, path, addr, bitmask, data);
0393 
0394     return count;
0395 }
0396 
0397 static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = {
0398     .cb_write = rtl_debugfs_set_write_rfreg,
0399 };
0400 
0401 static int rtl_debugfs_close(struct inode *inode, struct file *filp)
0402 {
0403     return 0;
0404 }
0405 
0406 static ssize_t rtl_debugfs_common_write(struct file *filp,
0407                     const char __user *buffer,
0408                     size_t count, loff_t *loff)
0409 {
0410     struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
0411 
0412     return debugfs_priv->cb_write(filp, buffer, count, loff);
0413 }
0414 
0415 static const struct file_operations file_ops_common_write = {
0416     .owner = THIS_MODULE,
0417     .write = rtl_debugfs_common_write,
0418     .open = simple_open,
0419     .release = rtl_debugfs_close,
0420 };
0421 
0422 #define RTL_DEBUGFS_ADD_CORE(name, mode, fopname)              \
0423     do {                                   \
0424         rtl_debug_priv_ ##name.rtlpriv = rtlpriv;          \
0425         debugfs_create_file(#name, mode, parent,           \
0426                     &rtl_debug_priv_ ##name,           \
0427                     &file_ops_ ##fopname);         \
0428     } while (0)
0429 
0430 #define RTL_DEBUGFS_ADD(name)                          \
0431         RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
0432 #define RTL_DEBUGFS_ADD_W(name)                        \
0433         RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)
0434 
0435 void rtl_debug_add_one(struct ieee80211_hw *hw)
0436 {
0437     struct rtl_priv *rtlpriv = rtl_priv(hw);
0438     struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
0439     struct dentry *parent;
0440 
0441     snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr);
0442 
0443     rtlpriv->dbg.debugfs_dir =
0444         debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir);
0445 
0446     parent = rtlpriv->dbg.debugfs_dir;
0447 
0448     RTL_DEBUGFS_ADD(mac_0);
0449     RTL_DEBUGFS_ADD(mac_1);
0450     RTL_DEBUGFS_ADD(mac_2);
0451     RTL_DEBUGFS_ADD(mac_3);
0452     RTL_DEBUGFS_ADD(mac_4);
0453     RTL_DEBUGFS_ADD(mac_5);
0454     RTL_DEBUGFS_ADD(mac_6);
0455     RTL_DEBUGFS_ADD(mac_7);
0456     RTL_DEBUGFS_ADD(bb_8);
0457     RTL_DEBUGFS_ADD(bb_9);
0458     RTL_DEBUGFS_ADD(bb_a);
0459     RTL_DEBUGFS_ADD(bb_b);
0460     RTL_DEBUGFS_ADD(bb_c);
0461     RTL_DEBUGFS_ADD(bb_d);
0462     RTL_DEBUGFS_ADD(bb_e);
0463     RTL_DEBUGFS_ADD(bb_f);
0464     RTL_DEBUGFS_ADD(mac_10);
0465     RTL_DEBUGFS_ADD(mac_11);
0466     RTL_DEBUGFS_ADD(mac_12);
0467     RTL_DEBUGFS_ADD(mac_13);
0468     RTL_DEBUGFS_ADD(mac_14);
0469     RTL_DEBUGFS_ADD(mac_15);
0470     RTL_DEBUGFS_ADD(mac_16);
0471     RTL_DEBUGFS_ADD(mac_17);
0472     RTL_DEBUGFS_ADD(bb_18);
0473     RTL_DEBUGFS_ADD(bb_19);
0474     RTL_DEBUGFS_ADD(bb_1a);
0475     RTL_DEBUGFS_ADD(bb_1b);
0476     RTL_DEBUGFS_ADD(bb_1c);
0477     RTL_DEBUGFS_ADD(bb_1d);
0478     RTL_DEBUGFS_ADD(bb_1e);
0479     RTL_DEBUGFS_ADD(bb_1f);
0480     RTL_DEBUGFS_ADD(rf_a);
0481     RTL_DEBUGFS_ADD(rf_b);
0482 
0483     RTL_DEBUGFS_ADD(cam_1);
0484     RTL_DEBUGFS_ADD(cam_2);
0485     RTL_DEBUGFS_ADD(cam_3);
0486 
0487     RTL_DEBUGFS_ADD(btcoex);
0488 
0489     RTL_DEBUGFS_ADD_W(write_reg);
0490     RTL_DEBUGFS_ADD_W(write_h2c);
0491     RTL_DEBUGFS_ADD_W(write_rfreg);
0492 }
0493 EXPORT_SYMBOL_GPL(rtl_debug_add_one);
0494 
0495 void rtl_debug_remove_one(struct ieee80211_hw *hw)
0496 {
0497     struct rtl_priv *rtlpriv = rtl_priv(hw);
0498 
0499     debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir);
0500     rtlpriv->dbg.debugfs_dir = NULL;
0501 }
0502 EXPORT_SYMBOL_GPL(rtl_debug_remove_one);
0503 
0504 void rtl_debugfs_add_topdir(void)
0505 {
0506     debugfs_topdir = debugfs_create_dir("rtlwifi", NULL);
0507 }
0508 
0509 void rtl_debugfs_remove_topdir(void)
0510 {
0511     debugfs_remove_recursive(debugfs_topdir);
0512 }
0513 
0514 #endif