// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2009-2012  Realtek Corporation.*/

#include "wifi.h"
#include "cam.h"

#include <linux/moduleparam.h>
#include <linux/vmalloc.h>

#ifdef CONFIG_RTLWIFI_DEBUG
void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level,
		    const char *fmt, ...)
{
	if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
		     level <= rtlpriv->cfg->mod_params->debug_level)) {
		struct va_format vaf;
		va_list args;

		va_start(args, fmt);

		vaf.fmt = fmt;
		vaf.va = &args;

		pr_info(":<%lx> %pV", in_interrupt(), &vaf);

		va_end(args);
	}
}
EXPORT_SYMBOL_GPL(_rtl_dbg_trace);

void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
		    const char *fmt, ...)
{
	if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
		     level <= rtlpriv->cfg->mod_params->debug_level)) {
		struct va_format vaf;
		va_list args;

		va_start(args, fmt);

		vaf.fmt = fmt;
		vaf.va = &args;

		pr_info("%pV", &vaf);

		va_end(args);
	}
}
EXPORT_SYMBOL_GPL(_rtl_dbg_print);

void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
			 const char *titlestring,
			 const void *hexdata, int hexdatalen)
{
	if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) &&
		     ((level) <= rtlpriv->cfg->mod_params->debug_level))) {
		pr_info("In process \"%s\" (pid %i): %s\n",
			current->comm, current->pid, titlestring);
		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
				     hexdata, hexdatalen);
	}
}
EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);

struct rtl_debugfs_priv {
	struct rtl_priv *rtlpriv;
	int (*cb_read)(struct seq_file *m, void *v);
	ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
			    size_t count, loff_t *loff);
	u32 cb_data;
};

static struct dentry *debugfs_topdir;

static int rtl_debug_get_common(struct seq_file *m, void *v)
{
	struct rtl_debugfs_priv *debugfs_priv = m->private;

	return debugfs_priv->cb_read(m, v);
}

static int dl_debug_open_common(struct inode *inode, struct file *file)
{
	return single_open(file, rtl_debug_get_common, inode->i_private);
}

static const struct file_operations file_ops_common = {
	.open = dl_debug_open_common,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

static int rtl_debug_get_mac_page(struct seq_file *m, void *v)
{
	struct rtl_debugfs_priv *debugfs_priv = m->private;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
	u32 page = debugfs_priv->cb_data;
	int i, n;
	int max = 0xff;

	for (n = 0; n <= max; ) {
		seq_printf(m, "\n%8.8x  ", n + page);
		for (i = 0; i < 4 && n <= max; i++, n += 4)
			seq_printf(m, "%8.8x    ",
				   rtl_read_dword(rtlpriv, (page | n)));
	}
	seq_puts(m, "\n");
	return 0;
}

#define RTL_DEBUG_IMPL_MAC_SERIES(page, addr)			\
static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = {	\
	.cb_read = rtl_debug_get_mac_page,			\
	.cb_data = addr,					\
}

RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);

static int rtl_debug_get_bb_page(struct seq_file *m, void *v)
{
	struct rtl_debugfs_priv *debugfs_priv = m->private;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
	struct ieee80211_hw *hw = rtlpriv->hw;
	u32 page = debugfs_priv->cb_data;
	int i, n;
	int max = 0xff;

	for (n = 0; n <= max; ) {
		seq_printf(m, "\n%8.8x  ", n + page);
		for (i = 0; i < 4 && n <= max; i++, n += 4)
			seq_printf(m, "%8.8x    ",
				   rtl_get_bbreg(hw, (page | n), 0xffffffff));
	}
	seq_puts(m, "\n");
	return 0;
}

#define RTL_DEBUG_IMPL_BB_SERIES(page, addr)			\
static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = {	\
	.cb_read = rtl_debug_get_bb_page,			\
	.cb_data = addr,					\
}

RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00);
RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00);
RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00);
RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00);
RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00);
RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00);
RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00);
RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00);
RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00);
RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00);
RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00);
RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00);

static int rtl_debug_get_reg_rf(struct seq_file *m, void *v)
{
	struct rtl_debugfs_priv *debugfs_priv = m->private;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
	struct ieee80211_hw *hw = rtlpriv->hw;
	enum radio_path rfpath = debugfs_priv->cb_data;
	int i, n;
	int max = 0x40;

	if (IS_HARDWARE_TYPE_8822B(rtlpriv))
		max = 0xff;

	seq_printf(m, "\nPATH(%d)", rfpath);

	for (n = 0; n <= max; ) {
		seq_printf(m, "\n%8.8x  ", n);
		for (i = 0; i < 4 && n <= max; n += 1, i++)
			seq_printf(m, "%8.8x    ",
				   rtl_get_rfreg(hw, rfpath, n, 0xffffffff));
	}
	seq_puts(m, "\n");
	return 0;
}

#define RTL_DEBUG_IMPL_RF_SERIES(page, addr)			\
static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = {	\
	.cb_read = rtl_debug_get_reg_rf,			\
	.cb_data = addr,					\
}

RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A);
RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B);

static int rtl_debug_get_cam_register(struct seq_file *m, void *v)
{
	struct rtl_debugfs_priv *debugfs_priv = m->private;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
	int start = debugfs_priv->cb_data;
	u32 target_cmd = 0;
	u32 target_val = 0;
	u8 entry_i = 0;
	u32 ulstatus;
	int i = 100, j = 0;
	int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11);

	/* This dump the current register page */
	seq_printf(m,
		   "\n#################### SECURITY CAM (%d-%d) ##################\n",
		   start, end - 1);

	for (j = start; j < end; j++) {
		seq_printf(m, "\nD:  %2x > ", j);
		for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
			/* polling bit, and No Write enable, and address  */
			target_cmd = entry_i + CAM_CONTENT_COUNT * j;
			target_cmd = target_cmd | BIT(31);

			/* Check polling bit is clear */
			while ((i--) >= 0) {
				ulstatus =
				    rtl_read_dword(rtlpriv,
						   rtlpriv->cfg->maps[RWCAM]);
				if (ulstatus & BIT(31))
					continue;
				else
					break;
			}

			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
					target_cmd);
			target_val = rtl_read_dword(rtlpriv,
						    rtlpriv->cfg->maps[RCAMO]);
			seq_printf(m, "%8.8x ", target_val);
		}
	}
	seq_puts(m, "\n");
	return 0;
}

#define RTL_DEBUG_IMPL_CAM_SERIES(page, addr)			\
static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = {	\
	.cb_read = rtl_debug_get_cam_register,			\
	.cb_data = addr,					\
}

RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
RTL_DEBUG_IMPL_CAM_SERIES(3, 22);

static int rtl_debug_get_btcoex(struct seq_file *m, void *v)
{
	struct rtl_debugfs_priv *debugfs_priv = m->private;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;

	if (rtlpriv->cfg->ops->get_btc_status())
		rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv,
								     m);

	seq_puts(m, "\n");

	return 0;
}

static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
	.cb_read = rtl_debug_get_btcoex,
	.cb_data = 0,
};

static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
					 const char __user *buffer,
					 size_t count, loff_t *loff)
{
	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
	char tmp[32 + 1];
	int tmp_len;
	u32 addr, val, len;
	int num;

	if (count < 3)
		return -EFAULT;

	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);

	if (copy_from_user(tmp, buffer, tmp_len))
		return -EFAULT;

	tmp[tmp_len] = '\0';

	/* write BB/MAC register */
	num = sscanf(tmp, "%x %x %x", &addr, &val, &len);

	if (num !=  3)
		return -EINVAL;

	switch (len) {
	case 1:
		rtl_write_byte(rtlpriv, addr, (u8)val);
		break;
	case 2:
		rtl_write_word(rtlpriv, addr, (u16)val);
		break;
	case 4:
		rtl_write_dword(rtlpriv, addr, val);
		break;
	default:
		/*printk("error write length=%d", len);*/
		break;
	}

	return count;
}

static struct rtl_debugfs_priv rtl_debug_priv_write_reg = {
	.cb_write = rtl_debugfs_set_write_reg,
};

static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
					 const char __user *buffer,
					 size_t count, loff_t *loff)
{
	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
	struct ieee80211_hw *hw = rtlpriv->hw;
	char tmp[32 + 1];
	int tmp_len;
	u8 h2c_len, h2c_data_packed[8];
	int h2c_data[8];	/* idx 0: cmd */
	int i;

	if (count < 3)
		return -EFAULT;

	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);

	if (copy_from_user(tmp, buffer, tmp_len))
		return -EFAULT;

	tmp[tmp_len] = '\0';

	h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X",
			 &h2c_data[0], &h2c_data[1],
			 &h2c_data[2], &h2c_data[3],
			 &h2c_data[4], &h2c_data[5],
			 &h2c_data[6], &h2c_data[7]);

	if (h2c_len == 0)
		return -EINVAL;

	for (i = 0; i < h2c_len; i++)
		h2c_data_packed[i] = (u8)h2c_data[i];

	rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0],
					h2c_len - 1,
					&h2c_data_packed[1]);

	return count;
}

static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = {
	.cb_write = rtl_debugfs_set_write_h2c,
};

static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
					   const char __user *buffer,
					    size_t count, loff_t *loff)
{
	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
	struct ieee80211_hw *hw = rtlpriv->hw;
	char tmp[32 + 1];
	int tmp_len;
	int num;
	int path;
	u32 addr, bitmask, data;

	if (count < 3)
		return -EFAULT;

	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);

	if (copy_from_user(tmp, buffer, tmp_len))
		return -EFAULT;

	tmp[tmp_len] = '\0';

	num = sscanf(tmp, "%X %X %X %X",
		     &path, &addr, &bitmask, &data);

	if (num != 4) {
		rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
			"Format is <path> <addr> <mask> <data>\n");
		return -EINVAL;
	}

	rtl_set_rfreg(hw, path, addr, bitmask, data);

	return count;
}

static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = {
	.cb_write = rtl_debugfs_set_write_rfreg,
};

static int rtl_debugfs_close(struct inode *inode, struct file *filp)
{
	return 0;
}

static ssize_t rtl_debugfs_common_write(struct file *filp,
					const char __user *buffer,
					size_t count, loff_t *loff)
{
	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;

	return debugfs_priv->cb_write(filp, buffer, count, loff);
}

static const struct file_operations file_ops_common_write = {
	.owner = THIS_MODULE,
	.write = rtl_debugfs_common_write,
	.open = simple_open,
	.release = rtl_debugfs_close,
};

#define RTL_DEBUGFS_ADD_CORE(name, mode, fopname)			   \
	do {								   \
		rtl_debug_priv_ ##name.rtlpriv = rtlpriv;		   \
		debugfs_create_file(#name, mode, parent,		   \
				    &rtl_debug_priv_ ##name,		   \
				    &file_ops_ ##fopname);		   \
	} while (0)

#define RTL_DEBUGFS_ADD(name)						   \
		RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
#define RTL_DEBUGFS_ADD_W(name)						   \
		RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)

void rtl_debug_add_one(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
	struct dentry *parent;

	snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr);

	rtlpriv->dbg.debugfs_dir =
		debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir);

	parent = rtlpriv->dbg.debugfs_dir;

	RTL_DEBUGFS_ADD(mac_0);
	RTL_DEBUGFS_ADD(mac_1);
	RTL_DEBUGFS_ADD(mac_2);
	RTL_DEBUGFS_ADD(mac_3);
	RTL_DEBUGFS_ADD(mac_4);
	RTL_DEBUGFS_ADD(mac_5);
	RTL_DEBUGFS_ADD(mac_6);
	RTL_DEBUGFS_ADD(mac_7);
	RTL_DEBUGFS_ADD(bb_8);
	RTL_DEBUGFS_ADD(bb_9);
	RTL_DEBUGFS_ADD(bb_a);
	RTL_DEBUGFS_ADD(bb_b);
	RTL_DEBUGFS_ADD(bb_c);
	RTL_DEBUGFS_ADD(bb_d);
	RTL_DEBUGFS_ADD(bb_e);
	RTL_DEBUGFS_ADD(bb_f);
	RTL_DEBUGFS_ADD(mac_10);
	RTL_DEBUGFS_ADD(mac_11);
	RTL_DEBUGFS_ADD(mac_12);
	RTL_DEBUGFS_ADD(mac_13);
	RTL_DEBUGFS_ADD(mac_14);
	RTL_DEBUGFS_ADD(mac_15);
	RTL_DEBUGFS_ADD(mac_16);
	RTL_DEBUGFS_ADD(mac_17);
	RTL_DEBUGFS_ADD(bb_18);
	RTL_DEBUGFS_ADD(bb_19);
	RTL_DEBUGFS_ADD(bb_1a);
	RTL_DEBUGFS_ADD(bb_1b);
	RTL_DEBUGFS_ADD(bb_1c);
	RTL_DEBUGFS_ADD(bb_1d);
	RTL_DEBUGFS_ADD(bb_1e);
	RTL_DEBUGFS_ADD(bb_1f);
	RTL_DEBUGFS_ADD(rf_a);
	RTL_DEBUGFS_ADD(rf_b);

	RTL_DEBUGFS_ADD(cam_1);
	RTL_DEBUGFS_ADD(cam_2);
	RTL_DEBUGFS_ADD(cam_3);

	RTL_DEBUGFS_ADD(btcoex);

	RTL_DEBUGFS_ADD_W(write_reg);
	RTL_DEBUGFS_ADD_W(write_h2c);
	RTL_DEBUGFS_ADD_W(write_rfreg);
}
EXPORT_SYMBOL_GPL(rtl_debug_add_one);

void rtl_debug_remove_one(struct ieee80211_hw *hw)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir);
	rtlpriv->dbg.debugfs_dir = NULL;
}
EXPORT_SYMBOL_GPL(rtl_debug_remove_one);

void rtl_debugfs_add_topdir(void)
{
	debugfs_topdir = debugfs_create_dir("rtlwifi", NULL);
}

void rtl_debugfs_remove_topdir(void)
{
	debugfs_remove_recursive(debugfs_topdir);
}

#endif
