brintos

brintos / linux-shallow public Read only

0
0
Text · 12.7 KiB · 9eb26df Raw
515 lines · c
1// SPDX-License-Identifier: GPL-2.02/* 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_DEBUG11void _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				else222					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 (copy_from_user(tmp, buffer, tmp_len))282		return -EFAULT;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 -EINVAL;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 (copy_from_user(tmp, buffer, tmp_len))333		return -EFAULT;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 -EINVAL;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 (copy_from_user(tmp, buffer, tmp_len))379		return -EFAULT;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 -EINVAL;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#endif515