diff options
Diffstat (limited to 'sys/contrib/dev/rtw89/debug.c')
| -rw-r--r-- | sys/contrib/dev/rtw89/debug.c | 2232 | 
1 files changed, 1302 insertions, 930 deletions
| diff --git a/sys/contrib/dev/rtw89/debug.c b/sys/contrib/dev/rtw89/debug.c index f7e451b0a032..d6624c2ed379 100644 --- a/sys/contrib/dev/rtw89/debug.c +++ b/sys/contrib/dev/rtw89/debug.c @@ -17,6 +17,7 @@  #include "ps.h"  #include "reg.h"  #include "sar.h" +#include "util.h"  #if defined(__FreeBSD__)  #ifdef CONFIG_RTW89_DEBUGFS  #include <linux/debugfs.h> @@ -31,11 +32,21 @@ MODULE_PARM_DESC(debug_mask, "Debugging mask");  #endif  #ifdef CONFIG_RTW89_DEBUGFS +struct rtw89_debugfs_priv_opt { +	bool rlock:1; +	bool wlock:1; +	size_t rsize; +}; +  struct rtw89_debugfs_priv {  	struct rtw89_dev *rtwdev; -	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); +	ssize_t (*cb_read)(struct rtw89_dev *rtwdev, +			   struct rtw89_debugfs_priv *debugfs_priv, +			   char *buf, size_t bufsz); +	ssize_t (*cb_write)(struct rtw89_dev *rtwdev, +			    struct rtw89_debugfs_priv *debugfs_priv, +			    const char *buf, size_t count); +	struct rtw89_debugfs_priv_opt opt;  	union {  		u32 cb_data;  		struct { @@ -60,6 +71,8 @@ struct rtw89_debugfs_priv {  			u8 sel;  		} mac_mem;  	}; +	ssize_t rused; +	char *rbuf;  };  struct rtw89_debugfs { @@ -81,8 +94,31 @@ struct rtw89_debugfs {  	struct rtw89_debugfs_priv phy_info;  	struct rtw89_debugfs_priv stations;  	struct rtw89_debugfs_priv disable_dm; +	struct rtw89_debugfs_priv mlo_mode; +}; + +struct rtw89_debugfs_iter_data { +	char *buf; +	size_t bufsz; +	int written_sz;  }; +static void rtw89_debugfs_iter_data_setup(struct rtw89_debugfs_iter_data *iter_data, +					  char *buf, size_t bufsz) +{ +	iter_data->buf = buf; +	iter_data->bufsz = bufsz; +	iter_data->written_sz = 0; +} + +static void rtw89_debugfs_iter_data_next(struct rtw89_debugfs_iter_data *iter_data, +					 char *buf, size_t bufsz, int written_sz) +{ +	iter_data->buf = buf; +	iter_data->bufsz = bufsz; +	iter_data->written_sz += written_sz; +} +  static const u16 rtw89_rate_info_bw_to_mhz_map[] = {  	[RATE_INFO_BW_20] = 20,  	[RATE_INFO_BW_40] = 40, @@ -99,84 +135,122 @@ static u16 rtw89_rate_info_bw_to_mhz(enum rate_info_bw bw)  	return 0;  } -static int rtw89_debugfs_single_show(struct seq_file *m, void *v) +static ssize_t rtw89_debugfs_file_read_helper(struct wiphy *wiphy, struct file *file, +					      char *buf, size_t bufsz, void *data)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; +	struct rtw89_debugfs_priv *debugfs_priv = data; +	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; +	ssize_t n; -	return debugfs_priv->cb_read(m, v); +	n = debugfs_priv->cb_read(rtwdev, debugfs_priv, buf, bufsz); +	rtw89_might_trailing_ellipsis(buf, bufsz, n); + +	return n;  } -static ssize_t rtw89_debugfs_single_write(struct file *filp, -					  const char __user *buffer, -					  size_t count, loff_t *loff) +static ssize_t rtw89_debugfs_file_read(struct file *file, char __user *userbuf, +				       size_t count, loff_t *ppos)  { -	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; +	struct rtw89_debugfs_priv *debugfs_priv = file->private_data; +	struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt; +	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; +	size_t bufsz = opt->rsize ? opt->rsize : PAGE_SIZE; +	char *buf; +	ssize_t n; -	return debugfs_priv->cb_write(filp, buffer, count, loff); -} +	if (!debugfs_priv->rbuf) +		debugfs_priv->rbuf = devm_kzalloc(rtwdev->dev, bufsz, GFP_KERNEL); -static ssize_t rtw89_debugfs_seq_file_write(struct file *filp, -					    const char __user *buffer, -					    size_t count, loff_t *loff) -{ -	struct seq_file *seqpriv = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = seqpriv->private; +	buf = debugfs_priv->rbuf; +	if (!buf) +		return -ENOMEM; + +	if (*ppos) { +		n = debugfs_priv->rused; +		goto out; +	} -	return debugfs_priv->cb_write(filp, buffer, count, loff); +	if (opt->rlock) { +		n = wiphy_locked_debugfs_read(rtwdev->hw->wiphy, file, buf, bufsz, +					      userbuf, count, ppos, +					      rtw89_debugfs_file_read_helper, +					      debugfs_priv); +		debugfs_priv->rused = n; + +		return n; +	} + +	n = rtw89_debugfs_file_read_helper(rtwdev->hw->wiphy, file, buf, bufsz, +					   debugfs_priv); +	debugfs_priv->rused = n; + +out: +	return simple_read_from_buffer(userbuf, count, ppos, buf, n);  } -static int rtw89_debugfs_single_open(struct inode *inode, struct file *filp) +static ssize_t rtw89_debugfs_file_write_helper(struct wiphy *wiphy, struct file *file, +					       char *buf, size_t count, void *data)  { -	return single_open(filp, rtw89_debugfs_single_show, inode->i_private); +	struct rtw89_debugfs_priv *debugfs_priv = data; +	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; + +	return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count);  } -static int rtw89_debugfs_close(struct inode *inode, struct file *filp) +static ssize_t rtw89_debugfs_file_write(struct file *file, +					const char __user *userbuf, +					size_t count, loff_t *loff)  { -	return 0; +	struct rtw89_debugfs_priv *debugfs_priv = file->private_data; +	struct rtw89_debugfs_priv_opt *opt = &debugfs_priv->opt; +	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; +	char *buf __free(kfree) = kmalloc(count + 1, GFP_KERNEL); +	ssize_t n; + +	if (!buf) +		return -ENOMEM; + +	if (opt->wlock) { +		n = wiphy_locked_debugfs_write(rtwdev->hw->wiphy, +					       file, buf, count + 1, +					       userbuf, count, +					       rtw89_debugfs_file_write_helper, +					       debugfs_priv); +		return n; +	} + +	if (copy_from_user(buf, userbuf, count)) +		return -EFAULT; + +	buf[count] = '\0'; + +	return debugfs_priv->cb_write(rtwdev, debugfs_priv, buf, count);  } -static const struct file_operations file_ops_single_r = { -	.owner = THIS_MODULE, -	.open = rtw89_debugfs_single_open, -	.read = seq_read, -	.llseek = seq_lseek, -	.release = single_release, +static const struct debugfs_short_fops file_ops_single_r = { +	.read = rtw89_debugfs_file_read, +	.llseek = generic_file_llseek,  }; -static const struct file_operations file_ops_common_rw = { -	.owner = THIS_MODULE, -	.open = rtw89_debugfs_single_open, -	.release = single_release, -	.read = seq_read, -	.llseek = seq_lseek, -	.write = rtw89_debugfs_seq_file_write, +static const struct debugfs_short_fops file_ops_common_rw = { +	.read = rtw89_debugfs_file_read, +	.write = rtw89_debugfs_file_write, +	.llseek = generic_file_llseek,  }; -static const struct file_operations file_ops_single_w = { -	.owner = THIS_MODULE, -	.write = rtw89_debugfs_single_write, -	.open = simple_open, -	.release = rtw89_debugfs_close, +static const struct debugfs_short_fops file_ops_single_w = { +	.write = rtw89_debugfs_file_write, +	.llseek = generic_file_llseek,  };  static ssize_t -rtw89_debug_priv_read_reg_select(struct file *filp, -				 const char __user *user_buf, -				 size_t count, loff_t *loff) +rtw89_debug_priv_read_reg_select(struct rtw89_dev *rtwdev, +				 struct rtw89_debugfs_priv *debugfs_priv, +				 const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	char buf[32]; -	size_t buf_size;  	u32 addr, len;  	int num; -	buf_size = min(count, sizeof(buf) - 1); -	if (copy_from_user(buf, user_buf, buf_size)) -		return -EFAULT; - -	buf[buf_size] = '\0';  	num = sscanf(buf, "%x %x", &addr, &len);  	if (num != 2) {  		rtw89_info(rtwdev, "invalid format: <addr> <len>\n"); @@ -191,11 +265,13 @@ rtw89_debug_priv_read_reg_select(struct file *filp,  	return count;  } -static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_read_reg_get(struct rtw89_dev *rtwdev, +				      struct rtw89_debugfs_priv *debugfs_priv, +				      char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	u32 addr, end, data, k; +	char *p = buf, *end = buf + bufsz; +	u32 addr, addr_end, data, k;  	u32 len;  	len = debugfs_priv->read_reg.len; @@ -219,41 +295,34 @@ static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v)  		return -EINVAL;  	} -	seq_printf(m, "get %d bytes at 0x%08x=0x%08x\n", len, addr, data); +	p += scnprintf(p, end - p, "get %d bytes at 0x%08x=0x%08x\n", len, +		       addr, data); -	return 0; +	return p - buf;  ndata: -	end = addr + len; +	addr_end = addr + len; -	for (; addr < end; addr += 16) { -		seq_printf(m, "%08xh : ", 0x18600000 + addr); +	for (; addr < addr_end; addr += 16) { +		p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + addr);  		for (k = 0; k < 16; k += 4) {  			data = rtw89_read32(rtwdev, addr + k); -			seq_printf(m, "%08x ", data); +			p += scnprintf(p, end - p, "%08x ", data);  		} -		seq_puts(m, "\n"); +		p += scnprintf(p, end - p, "\n");  	} -	return 0; +	return p - buf;  } -static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp, -					      const char __user *user_buf, -					      size_t count, loff_t *loff) +static +ssize_t rtw89_debug_priv_write_reg_set(struct rtw89_dev *rtwdev, +				       struct rtw89_debugfs_priv *debugfs_priv, +				       const char *buf, size_t count)  { -	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	char buf[32]; -	size_t buf_size;  	u32 addr, val, len;  	int num; -	buf_size = min(count, sizeof(buf) - 1); -	if (copy_from_user(buf, user_buf, buf_size)) -		return -EFAULT; - -	buf[buf_size] = '\0';  	num = sscanf(buf, "%x %x %x", &addr, &val, &len);  	if (num !=  3) {  		rtw89_info(rtwdev, "invalid format: <addr> <val> <len>\n"); @@ -282,24 +351,14 @@ static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp,  }  static ssize_t -rtw89_debug_priv_read_rf_select(struct file *filp, -				const char __user *user_buf, -				size_t count, loff_t *loff) +rtw89_debug_priv_read_rf_select(struct rtw89_dev *rtwdev, +				struct rtw89_debugfs_priv *debugfs_priv, +				const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	char buf[32]; -	size_t buf_size;  	u32 addr, mask;  	u8 path;  	int num; -	buf_size = min(count, sizeof(buf) - 1); -	if (copy_from_user(buf, user_buf, buf_size)) -		return -EFAULT; - -	buf[buf_size] = '\0';  	num = sscanf(buf, "%hhd %x %x", &path, &addr, &mask);  	if (num != 3) {  		rtw89_info(rtwdev, "invalid format: <path> <addr> <mask>\n"); @@ -319,10 +378,12 @@ rtw89_debug_priv_read_rf_select(struct file *filp,  	return count;  } -static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_read_rf_get(struct rtw89_dev *rtwdev, +				     struct rtw89_debugfs_priv *debugfs_priv, +				     char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; +	char *p = buf, *end = buf + bufsz;  	u32 addr, data, mask;  	u8 path; @@ -332,28 +393,21 @@ static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v)  	data = rtw89_read_rf(rtwdev, path, addr, mask); -	seq_printf(m, "path %d, rf register 0x%08x=0x%08x\n", path, addr, data); +	p += scnprintf(p, end - p, "path %d, rf register 0x%08x=0x%08x\n", +		       path, addr, data); -	return 0; +	return p - buf;  } -static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp, -					     const char __user *user_buf, -					     size_t count, loff_t *loff) +static +ssize_t rtw89_debug_priv_write_rf_set(struct rtw89_dev *rtwdev, +				      struct rtw89_debugfs_priv *debugfs_priv, +				      const char *buf, size_t count)  { -	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	char buf[32]; -	size_t buf_size;  	u32 addr, val, mask;  	u8 path;  	int num; -	buf_size = min(count, sizeof(buf) - 1); -	if (copy_from_user(buf, user_buf, buf_size)) -		return -EFAULT; - -	buf[buf_size] = '\0';  	num = sscanf(buf, "%hhd %x %x %x", &path, &addr, &mask, &val);  	if (num != 4) {  		rtw89_info(rtwdev, "invalid format: <path> <addr> <mask> <val>\n"); @@ -372,29 +426,31 @@ static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp,  	return count;  } -static int rtw89_debug_priv_rf_reg_dump_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_rf_reg_dump_get(struct rtw89_dev *rtwdev, +					 struct rtw89_debugfs_priv *debugfs_priv, +					 char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	const struct rtw89_chip_info *chip = rtwdev->chip; +	char *p = buf, *end = buf + bufsz;  	u32 addr, offset, data;  	u8 path;  	for (path = 0; path < chip->rf_path_num; path++) { -		seq_printf(m, "RF path %d:\n\n", path); +		p += scnprintf(p, end - p, "RF path %d:\n\n", path);  		for (addr = 0; addr < 0x100; addr += 4) { -			seq_printf(m, "0x%08x: ", addr); +			p += scnprintf(p, end - p, "0x%08x: ", addr);  			for (offset = 0; offset < 4; offset++) {  				data = rtw89_read_rf(rtwdev, path,  						     addr + offset, RFREG_MASK); -				seq_printf(m, "0x%05x  ", data); +				p += scnprintf(p, end - p, "0x%05x  ", data);  			} -			seq_puts(m, "\n"); +			p += scnprintf(p, end - p, "\n");  		} -		seq_puts(m, "\n"); +		p += scnprintf(p, end - p, "\n");  	} -	return 0; +	return p - buf;  }  struct txpwr_ent { @@ -725,56 +781,71 @@ static const struct txpwr_map __txpwr_map_lmt_ru_be = {  };  static unsigned int -__print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent, -		  const s8 *buf, const unsigned int cur) +__print_txpwr_ent(char *buf, size_t bufsz, const struct txpwr_ent *ent, +		  const s8 *bufp, const unsigned int cur, unsigned int *ate)  { +	char *p = buf, *end = buf + bufsz;  	unsigned int cnt, i; +	unsigned int eaten;  	char *fmt;  	if (ent->nested) { -		for (cnt = 0, i = 0; i < ent->len; i++) -			cnt += __print_txpwr_ent(m, ent->ptr + i, buf, -						 cur + cnt); -		return cnt; +		for (cnt = 0, i = 0; i < ent->len; i++, cnt += eaten) +			p += __print_txpwr_ent(p, end - p, ent->ptr + i, bufp, +					       cur + cnt, &eaten); +		*ate = cnt; +		goto out;  	}  	switch (ent->len) {  	case 0: -		seq_printf(m, "\t<< %s >>\n", ent->txt); -		return 0; +		p += scnprintf(p, end - p, "\t<< %s >>\n", ent->txt); +		*ate = 0; +		goto out;  	case 2:  		fmt = "%s\t| %3d, %3d,\t\tdBm\n"; -		seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1]); -		return 2; +		p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], +			       bufp[cur + 1]); +		*ate = 2; +		goto out;  	case 4:  		fmt = "%s\t| %3d, %3d, %3d, %3d,\tdBm\n"; -		seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], -			   buf[cur + 2], buf[cur + 3]); -		return 4; +		p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], +			       bufp[cur + 1], +			       bufp[cur + 2], bufp[cur + 3]); +		*ate = 4; +		goto out;  	case 8:  		fmt = "%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n"; -		seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1], -			   buf[cur + 2], buf[cur + 3], buf[cur + 4], -			   buf[cur + 5], buf[cur + 6], buf[cur + 7]); -		return 8; +		p += scnprintf(p, end - p, fmt, ent->txt, bufp[cur], +			       bufp[cur + 1], +			       bufp[cur + 2], bufp[cur + 3], bufp[cur + 4], +			       bufp[cur + 5], bufp[cur + 6], bufp[cur + 7]); +		*ate = 8; +		goto out;  	default:  		return 0;  	} + +out: +	return p - buf;  } -static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev, -			     const struct txpwr_map *map) +static ssize_t __print_txpwr_map(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, +				 const struct txpwr_map *map)  {  	u8 fct = rtwdev->chip->txpwr_factor_mac;  	u8 path_num = rtwdev->chip->rf_path_num; +	char *p = buf, *end = buf + bufsz;  	unsigned int cur, i; +	unsigned int eaten;  	u32 max_valid_addr;  	u32 val, addr; -	s8 *buf, tmp; +	s8 *bufp, tmp;  	int ret; -	buf = vzalloc(map->addr_to - map->addr_from + 4); -	if (!buf) +	bufp = vzalloc(map->addr_to - map->addr_from + 4); +	if (!bufp)  		return -ENOMEM;  	if (path_num == 1) @@ -794,52 +865,31 @@ static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,  		for (i = 0; i < 4; i++, val >>= 8) {  			/* signed 7 bits, and reserved BIT(7) */  			tmp = sign_extend32(val, 6); -			buf[cur + i] = tmp >> fct; +			bufp[cur + i] = tmp >> fct;  		}  	} -	for (cur = 0, i = 0; i < map->size; i++) -		cur += __print_txpwr_ent(m, &map->ent[i], buf, cur); +	for (cur = 0, i = 0; i < map->size; i++, cur += eaten) +		p += __print_txpwr_ent(p, end - p, &map->ent[i], bufp, cur, &eaten); -	vfree(buf); -	return 0; +	vfree(bufp); +	return p - buf;  } -#define case_REGD(_regd) \ -	case RTW89_ ## _regd: \ -		seq_puts(m, #_regd "\n"); \ -		break - -static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev, -			 const struct rtw89_chan *chan) +static int __print_regd(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, +			const struct rtw89_chan *chan)  { +	const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; +	char *p = buf, *end = buf + bufsz;  	u8 band = chan->band_type;  	u8 regd = rtw89_regd_get(rtwdev, band); -	switch (regd) { -	default: -		seq_printf(m, "UNKNOWN: %d\n", regd); -		break; -	case_REGD(WW); -	case_REGD(ETSI); -	case_REGD(FCC); -	case_REGD(MKK); -	case_REGD(NA); -	case_REGD(IC); -	case_REGD(KCC); -	case_REGD(NCC); -	case_REGD(CHILE); -	case_REGD(ACMA); -	case_REGD(MEXICO); -	case_REGD(UKRAINE); -	case_REGD(CN); -	case_REGD(QATAR); -	case_REGD(UK); -	case_REGD(THAILAND); -	} -} +	p += scnprintf(p, end - p, "%s\n", rtw89_regd_get_string(regd)); +	p += scnprintf(p, end - p, "\t(txpwr UK follow ETSI: %s)\n", +		       str_yes_no(regulatory->txpwr_uk_follow_etsi)); -#undef case_REGD +	return p - buf; +}  struct dbgfs_txpwr_table {  	const struct txpwr_map *byr; @@ -865,96 +915,95 @@ static const struct dbgfs_txpwr_table *dbgfs_txpwr_tables[RTW89_CHIP_GEN_NUM] =  };  static -void rtw89_debug_priv_txpwr_table_get_regd(struct seq_file *m, -					   struct rtw89_dev *rtwdev, -					   const struct rtw89_chan *chan) +int rtw89_debug_priv_txpwr_table_get_regd(struct rtw89_dev *rtwdev, +					  char *buf, size_t bufsz, +					  const struct rtw89_chan *chan)  {  	const struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;  	const struct rtw89_reg_6ghz_tpe *tpe6 = ®ulatory->reg_6ghz_tpe; +	char *p = buf, *end = buf + bufsz; -	seq_printf(m, "[Chanctx] band %u, ch %u, bw %u\n", -		   chan->band_type, chan->channel, chan->band_width); +	p += scnprintf(p, end - p, "[Chanctx] band %u, ch %u, bw %u\n", +		       chan->band_type, chan->channel, chan->band_width); -	seq_puts(m, "[Regulatory] "); -	__print_regd(m, rtwdev, chan); +	p += scnprintf(p, end - p, "[Regulatory] "); +	p += __print_regd(rtwdev, p, end - p, chan);  	if (chan->band_type == RTW89_BAND_6G) { -		seq_printf(m, "[reg6_pwr_type] %u\n", regulatory->reg_6ghz_power); +		p += scnprintf(p, end - p, "[reg6_pwr_type] %u\n", +			       regulatory->reg_6ghz_power);  		if (tpe6->valid) -			seq_printf(m, "[TPE] %d dBm\n", tpe6->constraint); +			p += scnprintf(p, end - p, "[TPE] %d dBm\n", +				       tpe6->constraint);  	} + +	return p - buf;  } -static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_txpwr_table_get(struct rtw89_dev *rtwdev, +					 struct rtw89_debugfs_priv *debugfs_priv, +					 char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; +	struct rtw89_sar_parm sar_parm = {};  	const struct dbgfs_txpwr_table *tbl;  	const struct rtw89_chan *chan; -	int ret = 0; +	char *p = buf, *end = buf + bufsz; +	ssize_t n; + +	lockdep_assert_wiphy(rtwdev->hw->wiphy); -	mutex_lock(&rtwdev->mutex);  	rtw89_leave_ps_mode(rtwdev);  	chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); +	sar_parm.center_freq = chan->freq; -	rtw89_debug_priv_txpwr_table_get_regd(m, rtwdev, chan); +	p += rtw89_debug_priv_txpwr_table_get_regd(rtwdev, p, end - p, chan); -	seq_puts(m, "[SAR]\n"); -	rtw89_print_sar(m, rtwdev, chan->freq); +	p += scnprintf(p, end - p, "[SAR]\n"); +	p += rtw89_print_sar(rtwdev, p, end - p, &sar_parm); -	seq_puts(m, "[TAS]\n"); -	rtw89_print_tas(m, rtwdev); +	p += scnprintf(p, end - p, "[TAS]\n"); +	p += rtw89_print_tas(rtwdev, p, end - p); -	seq_puts(m, "[DAG]\n"); -	rtw89_print_ant_gain(m, rtwdev, chan); +	p += scnprintf(p, end - p, "[DAG]\n"); +	p += rtw89_print_ant_gain(rtwdev, p, end - p, chan);  	tbl = dbgfs_txpwr_tables[chip_gen]; -	if (!tbl) { -		ret = -EOPNOTSUPP; -		goto err; -	} - -	seq_puts(m, "\n[TX power byrate]\n"); -	ret = __print_txpwr_map(m, rtwdev, tbl->byr); -	if (ret) -		goto err; - -	seq_puts(m, "\n[TX power limit]\n"); -	ret = __print_txpwr_map(m, rtwdev, tbl->lmt); -	if (ret) -		goto err; - -	seq_puts(m, "\n[TX power limit_ru]\n"); -	ret = __print_txpwr_map(m, rtwdev, tbl->lmt_ru); -	if (ret) -		goto err; +	if (!tbl) +		return -EOPNOTSUPP; -err: -	mutex_unlock(&rtwdev->mutex); -	return ret; +	p += scnprintf(p, end - p, "\n[TX power byrate]\n"); +	n = __print_txpwr_map(rtwdev, p, end - p, tbl->byr); +	if (n < 0) +		return n; +	p += n; + +	p += scnprintf(p, end - p, "\n[TX power limit]\n"); +	n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt); +	if (n < 0) +		return n; +	p += n; + +	p += scnprintf(p, end - p, "\n[TX power limit_ru]\n"); +	n = __print_txpwr_map(rtwdev, p, end - p, tbl->lmt_ru); +	if (n < 0) +		return n; +	p += n; + +	return p - buf;  }  static ssize_t -rtw89_debug_priv_mac_reg_dump_select(struct file *filp, -				     const char __user *user_buf, -				     size_t count, loff_t *loff) +rtw89_debug_priv_mac_reg_dump_select(struct rtw89_dev *rtwdev, +				     struct rtw89_debugfs_priv *debugfs_priv, +				     const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	const struct rtw89_chip_info *chip = rtwdev->chip; -	char buf[32]; -	size_t buf_size;  	int sel;  	int ret; -	buf_size = min(count, sizeof(buf) - 1); -	if (copy_from_user(buf, user_buf, buf_size)) -		return -EFAULT; - -	buf[buf_size] = '\0';  	ret = kstrtoint(buf, 0, &sel);  	if (ret)  		return ret; @@ -978,99 +1027,91 @@ rtw89_debug_priv_mac_reg_dump_select(struct file *filp,  #define RTW89_MAC_PAGE_SIZE		0x100 -static int rtw89_debug_priv_mac_reg_dump_get(struct seq_file *m, void *v) +static +ssize_t rtw89_debug_priv_mac_reg_dump_get(struct rtw89_dev *rtwdev, +					  struct rtw89_debugfs_priv *debugfs_priv, +					  char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data; -	u32 start, end; +	char *p = buf, *end = buf + bufsz; +	u32 start, end_addr;  	u32 i, j, k, page;  	u32 val;  	switch (reg_sel) {  	case RTW89_DBG_SEL_MAC_00: -		seq_puts(m, "Debug selected MAC page 0x00\n"); +		p += scnprintf(p, end - p, "Debug selected MAC page 0x00\n");  		start = 0x000; -		end = 0x014; +		end_addr = 0x014;  		break;  	case RTW89_DBG_SEL_MAC_30: -		seq_puts(m, "Debug selected MAC page 0x30\n"); +		p += scnprintf(p, end - p, "Debug selected MAC page 0x30\n");  		start = 0x030; -		end = 0x033; +		end_addr = 0x033;  		break;  	case RTW89_DBG_SEL_MAC_40: -		seq_puts(m, "Debug selected MAC page 0x40\n"); +		p += scnprintf(p, end - p, "Debug selected MAC page 0x40\n");  		start = 0x040; -		end = 0x07f; +		end_addr = 0x07f;  		break;  	case RTW89_DBG_SEL_MAC_80: -		seq_puts(m, "Debug selected MAC page 0x80\n"); +		p += scnprintf(p, end - p, "Debug selected MAC page 0x80\n");  		start = 0x080; -		end = 0x09f; +		end_addr = 0x09f;  		break;  	case RTW89_DBG_SEL_MAC_C0: -		seq_puts(m, "Debug selected MAC page 0xc0\n"); +		p += scnprintf(p, end - p, "Debug selected MAC page 0xc0\n");  		start = 0x0c0; -		end = 0x0df; +		end_addr = 0x0df;  		break;  	case RTW89_DBG_SEL_MAC_E0: -		seq_puts(m, "Debug selected MAC page 0xe0\n"); +		p += scnprintf(p, end - p, "Debug selected MAC page 0xe0\n");  		start = 0x0e0; -		end = 0x0ff; +		end_addr = 0x0ff;  		break;  	case RTW89_DBG_SEL_BB: -		seq_puts(m, "Debug selected BB register\n"); +		p += scnprintf(p, end - p, "Debug selected BB register\n");  		start = 0x100; -		end = 0x17f; +		end_addr = 0x17f;  		break;  	case RTW89_DBG_SEL_IQK: -		seq_puts(m, "Debug selected IQK register\n"); +		p += scnprintf(p, end - p, "Debug selected IQK register\n");  		start = 0x180; -		end = 0x1bf; +		end_addr = 0x1bf;  		break;  	case RTW89_DBG_SEL_RFC: -		seq_puts(m, "Debug selected RFC register\n"); +		p += scnprintf(p, end - p, "Debug selected RFC register\n");  		start = 0x1c0; -		end = 0x1ff; +		end_addr = 0x1ff;  		break;  	default: -		seq_puts(m, "Selected invalid register page\n"); +		p += scnprintf(p, end - p, "Selected invalid register page\n");  		return -EINVAL;  	} -	for (i = start; i <= end; i++) { +	for (i = start; i <= end_addr; i++) {  		page = i << 8;  		for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) { -			seq_printf(m, "%08xh : ", 0x18600000 + j); +			p += scnprintf(p, end - p, "%08xh : ", 0x18600000 + j);  			for (k = 0; k < 4; k++) {  				val = rtw89_read32(rtwdev, j + (k << 2)); -				seq_printf(m, "%08x ", val); +				p += scnprintf(p, end - p, "%08x ", val);  			} -			seq_puts(m, "\n"); +			p += scnprintf(p, end - p, "\n");  		}  	} -	return 0; +	return p - buf;  }  static ssize_t -rtw89_debug_priv_mac_mem_dump_select(struct file *filp, -				     const char __user *user_buf, -				     size_t count, loff_t *loff) +rtw89_debug_priv_mac_mem_dump_select(struct rtw89_dev *rtwdev, +				     struct rtw89_debugfs_priv *debugfs_priv, +				     const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	char buf[32]; -	size_t buf_size;  	u32 sel, start_addr, len;  	int num; -	buf_size = min(count, sizeof(buf) - 1); -	if (copy_from_user(buf, user_buf, buf_size)) -		return -EFAULT; - -	buf[buf_size] = '\0';  	num = sscanf(buf, "%x %x %x", &sel, &start_addr, &len);  	if (num != 3) {  		rtw89_info(rtwdev, "invalid format: <sel> <start> <len>\n"); @@ -1087,51 +1128,58 @@ rtw89_debug_priv_mac_mem_dump_select(struct file *filp,  	return count;  } -static void rtw89_debug_dump_mac_mem(struct seq_file *m, -				     struct rtw89_dev *rtwdev, -				     u8 sel, u32 start_addr, u32 len) +static int rtw89_debug_dump_mac_mem(struct rtw89_dev *rtwdev, +				    char *buf, size_t bufsz, +				    u8 sel, u32 start_addr, u32 len)  {  	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;  	u32 filter_model_addr = mac->filter_model_addr;  	u32 indir_access_addr = mac->indir_access_addr; +	u32 mem_page_size = mac->mem_page_size;  	u32 base_addr, start_page, residue; -	u32 i, j, p, pages; +	char *p = buf, *end = buf + bufsz; +	u32 i, j, pp, pages;  	u32 dump_len, remain;  	u32 val;  	remain = len; -	pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1; -	start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE; -	residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE; +	pages = len / mem_page_size + 1; +	start_page = start_addr / mem_page_size; +	residue = start_addr % mem_page_size;  	base_addr = mac->mem_base_addrs[sel]; -	base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE; +	base_addr += start_page * mem_page_size; -	for (p = 0; p < pages; p++) { -		dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE); +	for (pp = 0; pp < pages; pp++) { +		dump_len = min_t(u32, remain, mem_page_size);  		rtw89_write32(rtwdev, filter_model_addr, base_addr);  		for (i = indir_access_addr + residue;  		     i < indir_access_addr + dump_len;) { -			seq_printf(m, "%08xh:", i); +			p += scnprintf(p, end - p, "%08xh:", i);  			for (j = 0;  			     j < 4 && i < indir_access_addr + dump_len;  			     j++, i += 4) {  				val = rtw89_read32(rtwdev, i); -				seq_printf(m, "  %08x", val); +				p += scnprintf(p, end - p, "  %08x", val);  				remain -= 4;  			} -			seq_puts(m, "\n"); +			p += scnprintf(p, end - p, "\n");  		} -		base_addr += MAC_MEM_DUMP_PAGE_SIZE; +		base_addr += mem_page_size;  	} + +	return p - buf;  } -static int -rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_mac_mem_dump_get(struct rtw89_dev *rtwdev, +				  struct rtw89_debugfs_priv *debugfs_priv, +				  char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; +	char *p = buf, *end = buf + bufsz;  	bool grant_read = false; +	lockdep_assert_wiphy(rtwdev->hw->wiphy); +  	if (debugfs_priv->mac_mem.sel >= RTW89_MAC_MEM_NUM)  		return -ENOENT; @@ -1148,40 +1196,28 @@ rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v)  		}  	} -	mutex_lock(&rtwdev->mutex);  	rtw89_leave_ps_mode(rtwdev);  	if (grant_read)  		rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); -	rtw89_debug_dump_mac_mem(m, rtwdev, -				 debugfs_priv->mac_mem.sel, -				 debugfs_priv->mac_mem.start, -				 debugfs_priv->mac_mem.len); +	p += rtw89_debug_dump_mac_mem(rtwdev, p, end - p, +				      debugfs_priv->mac_mem.sel, +				      debugfs_priv->mac_mem.start, +				      debugfs_priv->mac_mem.len);  	if (grant_read)  		rtw89_write32_clr(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO); -	mutex_unlock(&rtwdev->mutex); -	return 0; +	return p - buf;  }  static ssize_t -rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp, -					  const char __user *user_buf, -					  size_t count, loff_t *loff) +rtw89_debug_priv_mac_dbg_port_dump_select(struct rtw89_dev *rtwdev, +					  struct rtw89_debugfs_priv *debugfs_priv, +					  const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	char buf[32]; -	size_t buf_size;  	int sel, set;  	int num;  	bool enable; -	buf_size = min(count, sizeof(buf) - 1); -	if (copy_from_user(buf, user_buf, buf_size)) -		return -EFAULT; - -	buf[buf_size] = '\0';  	num = sscanf(buf, "%d %d", &sel, &set);  	if (num != 2) {  		rtw89_info(rtwdev, "invalid format: <sel> <set>\n"); @@ -1217,13 +1253,13 @@ rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp,  }  static int rtw89_debug_mac_dump_ss_dbg(struct rtw89_dev *rtwdev, -				       struct seq_file *m) +				       char *buf, size_t bufsz)  {  	return 0;  }  static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev, -					struct seq_file *m) +				       char *buf, size_t bufsz)  {  #define DLE_DFI_DUMP(__type, __target, __sel)				\  ({									\ @@ -1252,7 +1288,7 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,  	__data;								\  }) -#define DLE_DFI_FREE_PAGE_DUMP(__m, __type)				\ +#define DLE_DFI_FREE_PAGE_DUMP(__p, __end, __type)			\  ({									\  	u32 __freepg, __pubpg;						\  	u32 __freepg_head, __freepg_tail, __pubpg_num;			\ @@ -1262,24 +1298,25 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,  	__freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg);	\  	__freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg);	\  	__pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg);		\ -	seq_printf(__m, "[%s] freepg head: %d\n",			\ -		   #__type, __freepg_head);				\ -	seq_printf(__m, "[%s] freepg tail: %d\n",			\ -		   #__type, __freepg_tail);				\ -	seq_printf(__m, "[%s] pubpg num  : %d\n",			\ -		  #__type, __pubpg_num);				\ +	__p += scnprintf(__p, __end - __p, "[%s] freepg head: %d\n",	\ +			 #__type, __freepg_head);			\ +	__p += scnprintf(__p, __end - __p, "[%s] freepg tail: %d\n",	\ +			 #__type, __freepg_tail);			\ +	__p += scnprintf(__p, __end - __p, "[%s] pubpg num  : %d\n",	\ +			 #__type, __pubpg_num);				\  }) -#define case_QUOTA(__m, __type, __id)					\ +#define case_QUOTA(__p, __end, __type, __id)				\  	case __type##_QTAID_##__id:					\ -		val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id);	\ +		val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id); \  		rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32);	\  		use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32);	\ -		seq_printf(__m, "[%s][%s] rsv_pgnum: %d\n",		\ -			   #__type, #__id, rsv_pgnum);			\ -		seq_printf(__m, "[%s][%s] use_pgnum: %d\n",		\ -			   #__type, #__id, use_pgnum);			\ +		__p += scnprintf(__p, __end - __p, "[%s][%s] rsv_pgnum: %d\n", \ +				 #__type, #__id, rsv_pgnum);		\ +		__p += scnprintf(__p, __end - __p, "[%s][%s] use_pgnum: %d\n", \ +				 #__type, #__id, use_pgnum);		\  		break +	char *p = buf, *end = buf + bufsz;  	u32 quota_id;  	u32 val32;  	u16 rsv_pgnum, use_pgnum; @@ -1287,38 +1324,39 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,  	ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);  	if (ret) { -		seq_puts(m, "[DLE]  : DMAC not enabled\n"); -		return ret; +		p += scnprintf(p, end - p, "[DLE]  : DMAC not enabled\n"); +		goto out;  	} -	DLE_DFI_FREE_PAGE_DUMP(m, WDE); -	DLE_DFI_FREE_PAGE_DUMP(m, PLE); +	DLE_DFI_FREE_PAGE_DUMP(p, end, WDE); +	DLE_DFI_FREE_PAGE_DUMP(p, end, PLE);  	for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) {  		switch (quota_id) { -		case_QUOTA(m, WDE, HOST_IF); -		case_QUOTA(m, WDE, WLAN_CPU); -		case_QUOTA(m, WDE, DATA_CPU); -		case_QUOTA(m, WDE, PKTIN); -		case_QUOTA(m, WDE, CPUIO); +		case_QUOTA(p, end, WDE, HOST_IF); +		case_QUOTA(p, end, WDE, WLAN_CPU); +		case_QUOTA(p, end, WDE, DATA_CPU); +		case_QUOTA(p, end, WDE, PKTIN); +		case_QUOTA(p, end, WDE, CPUIO);  		}  	}  	for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) {  		switch (quota_id) { -		case_QUOTA(m, PLE, B0_TXPL); -		case_QUOTA(m, PLE, B1_TXPL); -		case_QUOTA(m, PLE, C2H); -		case_QUOTA(m, PLE, H2C); -		case_QUOTA(m, PLE, WLAN_CPU); -		case_QUOTA(m, PLE, MPDU); -		case_QUOTA(m, PLE, CMAC0_RX); -		case_QUOTA(m, PLE, CMAC1_RX); -		case_QUOTA(m, PLE, CMAC1_BBRPT); -		case_QUOTA(m, PLE, WDRLS); -		case_QUOTA(m, PLE, CPUIO); +		case_QUOTA(p, end, PLE, B0_TXPL); +		case_QUOTA(p, end, PLE, B1_TXPL); +		case_QUOTA(p, end, PLE, C2H); +		case_QUOTA(p, end, PLE, H2C); +		case_QUOTA(p, end, PLE, WLAN_CPU); +		case_QUOTA(p, end, PLE, MPDU); +		case_QUOTA(p, end, PLE, CMAC0_RX); +		case_QUOTA(p, end, PLE, CMAC1_RX); +		case_QUOTA(p, end, PLE, CMAC1_BBRPT); +		case_QUOTA(p, end, PLE, WDRLS); +		case_QUOTA(p, end, PLE, CPUIO);  		}  	} -	return 0; +out: +	return p - buf;  #undef case_QUOTA  #undef DLE_DFI_DUMP @@ -1326,73 +1364,88 @@ static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,  }  static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev, -					 struct seq_file *m) +					 char *buf, size_t bufsz)  {  	const struct rtw89_chip_info *chip = rtwdev->chip; +	char *p = buf, *end = buf + bufsz;  	u32 dmac_err;  	int i, ret;  	ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);  	if (ret) { -		seq_puts(m, "[DMAC] : DMAC not enabled\n"); -		return ret; +		p += scnprintf(p, end - p, "[DMAC] : DMAC not enabled\n"); +		goto out;  	}  	dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR); -	seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); -	seq_printf(m, "R_AX_DMAC_ERR_IMR=0x%08x\n", -		   rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR)); +	p += scnprintf(p, end - p, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err); +	p += scnprintf(p, end - p, "R_AX_DMAC_ERR_IMR=0x%08x\n", +		       rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR));  	if (dmac_err) { -		seq_printf(m, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); -		seq_printf(m, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1)); +		p += scnprintf(p, end - p, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1)); +		p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1));  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); -			seq_printf(m, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); -			seq_printf(m, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); -			seq_printf(m, "R_AX_PLE_DBGERR_STS=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS)); +			p += scnprintf(p, end - p, +				       "R_AX_PLE_ERRFLAG_MSG=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG)); +			p += scnprintf(p, end - p, +				       "R_AX_WDE_ERRFLAG_MSG=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG)); +			p += scnprintf(p, end - p, +				       "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN)); +			p += scnprintf(p, end - p, +				       "R_AX_PLE_DBGERR_STS=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS));  		}  	}  	if (dmac_err & B_AX_WDRLS_ERR_FLAG) { -		seq_printf(m, "R_AX_WDRLS_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); -		seq_printf(m, "R_AX_WDRLS_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR)); +		p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_WDRLS_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR));  		if (chip->chip_id == RTL8852C) -			seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1)); +			p += scnprintf(p, end - p, +				       "R_AX_RPQ_RXBD_IDX=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1));  		else -			seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX)); +			p += scnprintf(p, end - p, +				       "R_AX_RPQ_RXBD_IDX=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));  	}  	if (dmac_err & B_AX_WSEC_ERR_FLAG) {  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_SEC_ERR_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); -			seq_printf(m, "R_AX_SEC_ERR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); -			seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); -			seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); -			seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); -			seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); -			seq_printf(m, "R_AX_SEC_DEBUG1=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); -			seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); -			seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_ERR_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_ERR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_ENG_CTRL=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_MPDU_PROC=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_CAM_ACCESS=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_CAM_RDATA=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); +			p += scnprintf(p, end - p, "R_AX_SEC_DEBUG1=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_DEBUG1)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_TX_DEBUG=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_RX_DEBUG=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));  			rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,  					   B_AX_DBG_SEL0, 0x8B); @@ -1403,187 +1456,229 @@ static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev,  			for (i = 0; i < 0x10; i++) {  				rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL,  						   B_AX_SEC_DBG_PORT_FIELD_MASK, i); -				seq_printf(m, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", -					   i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2)); +				p += scnprintf(p, end - p, +					       "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n", +					       i, +					       rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));  			}  		} else { -			seq_printf(m, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); -			seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); -			seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); -			seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); -			seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); -			seq_printf(m, "R_AX_SEC_CAM_WDATA=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); -			seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); -			seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); -			seq_printf(m, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); -			seq_printf(m, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_ERR_IMR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_DEBUG)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_ENG_CTRL=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_MPDU_PROC=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_CAM_ACCESS=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_CAM_RDATA=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_CAM_WDATA=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_TX_DEBUG=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_RX_DEBUG=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_TRX_PKT_CNT=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT)); +			p += scnprintf(p, end - p, +				       "R_AX_SEC_TRX_BLK_CNT=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT));  		}  	}  	if (dmac_err & B_AX_MPDU_ERR_FLAG) { -		seq_printf(m, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); -		seq_printf(m, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); -		seq_printf(m, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); -		seq_printf(m, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR)); +		p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR)); +		p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR));  	}  	if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) { -		seq_printf(m, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); -		seq_printf(m, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR)); +		p += scnprintf(p, end - p, +			       "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR)); +		p += scnprintf(p, end - p, +			       "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));  	}  	if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) { -		seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); -		seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); -		seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); -		seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); +		p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); +		p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));  	}  	if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) {  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); -			seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); -			seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); -			seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR));  		} else { -			seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); -			seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1)); +			p += scnprintf(p, end - p, +				       "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1));  		}  	}  	if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) { -		seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); -		seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); -		seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); -		seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); -		seq_printf(m, "R_AX_WD_CPUQ_OP_0=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); -		seq_printf(m, "R_AX_WD_CPUQ_OP_1=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); -		seq_printf(m, "R_AX_WD_CPUQ_OP_2=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); -		seq_printf(m, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); -		seq_printf(m, "R_AX_PL_CPUQ_OP_0=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); -		seq_printf(m, "R_AX_PL_CPUQ_OP_1=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); -		seq_printf(m, "R_AX_PL_CPUQ_OP_2=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); -		seq_printf(m, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS)); +		p += scnprintf(p, end - p, "R_AX_WDE_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_WDE_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR)); +		p += scnprintf(p, end - p, "R_AX_PLE_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR)); +		p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_0=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0)); +		p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_1=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1)); +		p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_2=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2)); +		p += scnprintf(p, end - p, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS)); +		p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_0=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0)); +		p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_1=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1)); +		p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_2=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2)); +		p += scnprintf(p, end - p, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_RX_CTRL0=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RX_CTRL0)); -			seq_printf(m, "R_AX_RX_CTRL1=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RX_CTRL1)); -			seq_printf(m, "R_AX_RX_CTRL2=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RX_CTRL2)); +			p += scnprintf(p, end - p, "R_AX_RX_CTRL0=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RX_CTRL0)); +			p += scnprintf(p, end - p, "R_AX_RX_CTRL1=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RX_CTRL1)); +			p += scnprintf(p, end - p, "R_AX_RX_CTRL2=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RX_CTRL2));  		} else { -			seq_printf(m, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); -			seq_printf(m, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); -			seq_printf(m, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2)); +			p += scnprintf(p, end - p, +				       "R_AX_RXDMA_PKT_INFO_0=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0)); +			p += scnprintf(p, end - p, +				       "R_AX_RXDMA_PKT_INFO_1=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1)); +			p += scnprintf(p, end - p, +				       "R_AX_RXDMA_PKT_INFO_2=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));  		}  	}  	if (dmac_err & B_AX_PKTIN_ERR_FLAG) { -		seq_printf(m, "R_AX_PKTIN_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); -		seq_printf(m, "R_AX_PKTIN_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR)); +		p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR)); +		p += scnprintf(p, end - p, "R_AX_PKTIN_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR));  	}  	if (dmac_err & B_AX_DISPATCH_ERR_FLAG) { -		seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); -		seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); -		seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); -		seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); -		seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); -		seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR)); +		p += scnprintf(p, end - p, +			       "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR)); +		p += scnprintf(p, end - p, +			       "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR)); +		p += scnprintf(p, end - p, +			       "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR)); +		p += scnprintf(p, end - p, +			       "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR)); +		p += scnprintf(p, end - p, +			       "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR)); +		p += scnprintf(p, end - p, +			       "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));  	}  	if (dmac_err & B_AX_BBRPT_ERR_FLAG) {  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); -			seq_printf(m, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); -			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); -			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); -			seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); -			seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));  		} else { -			seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); -			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); -			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); -			seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); -			seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", -				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR)); +			p += scnprintf(p, end - p, +				       "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n", +				       rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));  		}  	}  	if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) { -		seq_printf(m, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); -		seq_printf(m, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", -			   rtw89_read32(rtwdev, R_AX_HAXI_IDCT)); +		p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK)); +		p += scnprintf(p, end - p, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n", +			       rtw89_read32(rtwdev, R_AX_HAXI_IDCT));  	} -	return 0; +out: +	return p - buf;  }  static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev, -					 struct seq_file *m, +					 char *buf, size_t bufsz,  					 enum rtw89_mac_idx band)  {  	const struct rtw89_chip_info *chip = rtwdev->chip; +	char *p = buf, *end = buf + bufsz;  	u32 offset = 0;  	u32 cmac_err;  	int ret; @@ -1591,96 +1686,127 @@ static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev,  	ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);  	if (ret) {  		if (band) -			seq_puts(m, "[CMAC] : CMAC1 not enabled\n"); +			p += scnprintf(p, end - p, +				       "[CMAC] : CMAC1 not enabled\n");  		else -			seq_puts(m, "[CMAC] : CMAC0 not enabled\n"); -		return ret; +			p += scnprintf(p, end - p, +				       "[CMAC] : CMAC0 not enabled\n"); +		goto out;  	}  	if (band)  		offset = RTW89_MAC_AX_BAND_REG_OFFSET;  	cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset); -	seq_printf(m, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, -		   rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); -	seq_printf(m, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, -		   rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); -	seq_printf(m, "R_AX_CK_EN [%d]=0x%08x\n", band, -		   rtw89_read32(rtwdev, R_AX_CK_EN + offset)); +	p += scnprintf(p, end - p, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band, +		       rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset)); +	p += scnprintf(p, end - p, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band, +		       rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset)); +	p += scnprintf(p, end - p, "R_AX_CK_EN [%d]=0x%08x\n", band, +		       rtw89_read32(rtwdev, R_AX_CK_EN + offset));  	if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) { -		seq_printf(m, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, -			   rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); -		seq_printf(m, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, -			   rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset)); +		p += scnprintf(p, end - p, +			       "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band, +			       rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset)); +		p += scnprintf(p, end - p, +			       "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band, +			       rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset));  	}  	if (cmac_err & B_AX_PTCL_TOP_ERR_IND) { -		seq_printf(m, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band, -			   rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); -		seq_printf(m, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band, -			   rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset)); +		p += scnprintf(p, end - p, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", +			       band, +			       rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset)); +		p += scnprintf(p, end - p, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", +			       band, +			       rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset));  	}  	if (cmac_err & B_AX_DMA_TOP_ERR_IND) {  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); -			seq_printf(m, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band, +				       rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", +				       band, +				       rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset));  		} else { -			seq_printf(m, "R_AX_DLE_CTRL [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_DLE_CTRL [%d]=0x%08x\n", band, +				       rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset));  		}  	}  	if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) {  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); -			seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", +				       band, +				       rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", +				       band, +				       rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));  		} else { -			seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", +				       band, +				       rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));  		}  	}  	if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) { -		seq_printf(m, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band, -			   rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); -		seq_printf(m, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band, -			   rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset)); +		p += scnprintf(p, end - p, "R_AX_TXPWR_IMR [%d]=0x%08x\n", +			       band, +			       rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset)); +		p += scnprintf(p, end - p, "R_AX_TXPWR_ISR [%d]=0x%08x\n", +			       band, +			       rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset));  	}  	if (cmac_err & B_AX_WMAC_TX_ERR_IND) {  		if (chip->chip_id == RTL8852C) { -			seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset)); -			seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", +				       band, +				       rtw89_read32(rtwdev, +						    R_AX_TRXPTCL_ERROR_INDICA + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", +				       band, +				       rtw89_read32(rtwdev, +						    R_AX_TRXPTCL_ERROR_INDICA_MASK + offset));  		} else { -			seq_printf(m, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band, -				   rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset)); +			p += scnprintf(p, end - p, +				       "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", +				       band, +				       rtw89_read32(rtwdev, +						    R_AX_TMAC_ERR_IMR_ISR + offset));  		} -		seq_printf(m, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, -			   rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset)); +		p += scnprintf(p, end - p, +			       "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band, +			       rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset));  	} -	seq_printf(m, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, -		   rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); +	p += scnprintf(p, end - p, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band, +		       rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset)); -	return 0; +out: +	return p - buf;  }  static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev, -					 struct seq_file *m) +					 char *buf, size_t bufsz)  { -	rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_0); +	char *p = buf, *end = buf + bufsz; + +	p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_0);  	if (rtwdev->dbcc_en) -		rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_1); +		p += rtw89_debug_mac_dump_cmac_err(rtwdev, p, end - p, RTW89_MAC_1); -	return 0; +	return p - buf;  }  static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = { @@ -2486,11 +2612,12 @@ static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = {  	.rd_msk = B_AX_DEBUG_ST_MASK  }; -static const struct rtw89_mac_dbg_port_info * -rtw89_debug_mac_dbg_port_sel(struct seq_file *m, -			     struct rtw89_dev *rtwdev, u32 sel) +static int +rtw89_debug_mac_dbg_port_sel(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, +			     u32 sel, const struct rtw89_mac_dbg_port_info **ppinfo)  { -	const struct rtw89_mac_dbg_port_info *info; +	const struct rtw89_mac_dbg_port_info *info = NULL; +	char *p = buf, *end = buf + bufsz;  	u32 index;  	u32 val32;  	u16 val16; @@ -2502,28 +2629,28 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG);  		val16 |= B_AX_PTCL_DBG_EN;  		rtw89_write16(rtwdev, R_AX_PTCL_DBG, val16); -		seq_puts(m, "Enable PTCL C0 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable PTCL C0 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_PTCL_C1:  		info = &dbg_port_ptcl_c1;  		val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG_C1);  		val16 |= B_AX_PTCL_DBG_EN;  		rtw89_write16(rtwdev, R_AX_PTCL_DBG_C1, val16); -		seq_puts(m, "Enable PTCL C1 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable PTCL C1 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_SCH_C0:  		info = &dbg_port_sch_c0;  		val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL);  		val32 |= B_AX_SCH_DBG_EN;  		rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL, val32); -		seq_puts(m, "Enable SCH C0 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable SCH C0 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_SCH_C1:  		info = &dbg_port_sch_c1;  		val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL_C1);  		val32 |= B_AX_SCH_DBG_EN;  		rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL_C1, val32); -		seq_puts(m, "Enable SCH C1 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable SCH C1 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_TMAC_C0:  		info = &dbg_port_tmac_c0; @@ -2540,7 +2667,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);  		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);  		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); -		seq_puts(m, "Enable TMAC C0 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable TMAC C0 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_TMAC_C1:  		info = &dbg_port_tmac_c1; @@ -2557,7 +2684,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);  		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);  		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); -		seq_puts(m, "Enable TMAC C1 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable TMAC C1 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_RMAC_C0:  		info = &dbg_port_rmac_c0; @@ -2579,7 +2706,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL,  				       B_AX_DBGSEL_TRXPTCL_MASK);  		rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL, val8); -		seq_puts(m, "Enable RMAC C0 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable RMAC C0 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_RMAC_C1:  		info = &dbg_port_rmac_c1; @@ -2601,23 +2728,23 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL,  				       B_AX_DBGSEL_TRXPTCL_MASK);  		rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val8); -		seq_puts(m, "Enable RMAC C1 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable RMAC C1 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_RMACST_C0:  		info = &dbg_port_rmacst_c0; -		seq_puts(m, "Enable RMAC state C0 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable RMAC state C0 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_RMACST_C1:  		info = &dbg_port_rmacst_c1; -		seq_puts(m, "Enable RMAC state C1 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable RMAC state C1 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_RMAC_PLCP_C0:  		info = &dbg_port_rmac_plcp_c0; -		seq_puts(m, "Enable RMAC PLCP C0 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable RMAC PLCP C0 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_RMAC_PLCP_C1:  		info = &dbg_port_rmac_plcp_c1; -		seq_puts(m, "Enable RMAC PLCP C1 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable RMAC PLCP C1 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_TRXPTCL_C0:  		info = &dbg_port_trxptcl_c0; @@ -2629,7 +2756,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);  		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);  		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); -		seq_puts(m, "Enable TRXPTCL C0 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable TRXPTCL C0 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_TRXPTCL_C1:  		info = &dbg_port_trxptcl_c1; @@ -2641,131 +2768,137 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);  		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);  		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32); -		seq_puts(m, "Enable TRXPTCL C1 dbgport.\n"); +		p += scnprintf(p, end - p, "Enable TRXPTCL C1 dbgport.\n");  		break;  	case RTW89_DBG_PORT_SEL_TX_INFOL_C0:  		info = &dbg_port_tx_infol_c0;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1, val32); -		seq_puts(m, "Enable tx infol dump.\n"); +		p += scnprintf(p, end - p, "Enable tx infol dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_TX_INFOH_C0:  		info = &dbg_port_tx_infoh_c0;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1, val32); -		seq_puts(m, "Enable tx infoh dump.\n"); +		p += scnprintf(p, end - p, "Enable tx infoh dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_TX_INFOL_C1:  		info = &dbg_port_tx_infol_c1;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); -		seq_puts(m, "Enable tx infol dump.\n"); +		p += scnprintf(p, end - p, "Enable tx infol dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_TX_INFOH_C1:  		info = &dbg_port_tx_infoh_c1;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); -		seq_puts(m, "Enable tx infoh dump.\n"); +		p += scnprintf(p, end - p, "Enable tx infoh dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_TXTF_INFOL_C0:  		info = &dbg_port_txtf_infol_c0;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1, val32); -		seq_puts(m, "Enable tx tf infol dump.\n"); +		p += scnprintf(p, end - p, "Enable tx tf infol dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_TXTF_INFOH_C0:  		info = &dbg_port_txtf_infoh_c0;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1, val32); -		seq_puts(m, "Enable tx tf infoh dump.\n"); +		p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_TXTF_INFOL_C1:  		info = &dbg_port_txtf_infol_c1;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); -		seq_puts(m, "Enable tx tf infol dump.\n"); +		p += scnprintf(p, end - p, "Enable tx tf infol dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_TXTF_INFOH_C1:  		info = &dbg_port_txtf_infoh_c1;  		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);  		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;  		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32); -		seq_puts(m, "Enable tx tf infoh dump.\n"); +		p += scnprintf(p, end - p, "Enable tx tf infoh dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG:  		info = &dbg_port_wde_bufmgn_freepg; -		seq_puts(m, "Enable wde bufmgn freepg dump.\n"); +		p += scnprintf(p, end - p, "Enable wde bufmgn freepg dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA:  		info = &dbg_port_wde_bufmgn_quota; -		seq_puts(m, "Enable wde bufmgn quota dump.\n"); +		p += scnprintf(p, end - p, "Enable wde bufmgn quota dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT:  		info = &dbg_port_wde_bufmgn_pagellt; -		seq_puts(m, "Enable wde bufmgn pagellt dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable wde bufmgn pagellt dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO:  		info = &dbg_port_wde_bufmgn_pktinfo; -		seq_puts(m, "Enable wde bufmgn pktinfo dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable wde bufmgn pktinfo dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT:  		info = &dbg_port_wde_quemgn_prepkt; -		seq_puts(m, "Enable wde quemgn prepkt dump.\n"); +		p += scnprintf(p, end - p, "Enable wde quemgn prepkt dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT:  		info = &dbg_port_wde_quemgn_nxtpkt; -		seq_puts(m, "Enable wde quemgn nxtpkt dump.\n"); +		p += scnprintf(p, end - p, "Enable wde quemgn nxtpkt dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL:  		info = &dbg_port_wde_quemgn_qlnktbl; -		seq_puts(m, "Enable wde quemgn qlnktbl dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable wde quemgn qlnktbl dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY:  		info = &dbg_port_wde_quemgn_qempty; -		seq_puts(m, "Enable wde quemgn qempty dump.\n"); +		p += scnprintf(p, end - p, "Enable wde quemgn qempty dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG:  		info = &dbg_port_ple_bufmgn_freepg; -		seq_puts(m, "Enable ple bufmgn freepg dump.\n"); +		p += scnprintf(p, end - p, "Enable ple bufmgn freepg dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA:  		info = &dbg_port_ple_bufmgn_quota; -		seq_puts(m, "Enable ple bufmgn quota dump.\n"); +		p += scnprintf(p, end - p, "Enable ple bufmgn quota dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT:  		info = &dbg_port_ple_bufmgn_pagellt; -		seq_puts(m, "Enable ple bufmgn pagellt dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable ple bufmgn pagellt dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO:  		info = &dbg_port_ple_bufmgn_pktinfo; -		seq_puts(m, "Enable ple bufmgn pktinfo dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable ple bufmgn pktinfo dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT:  		info = &dbg_port_ple_quemgn_prepkt; -		seq_puts(m, "Enable ple quemgn prepkt dump.\n"); +		p += scnprintf(p, end - p, "Enable ple quemgn prepkt dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT:  		info = &dbg_port_ple_quemgn_nxtpkt; -		seq_puts(m, "Enable ple quemgn nxtpkt dump.\n"); +		p += scnprintf(p, end - p, "Enable ple quemgn nxtpkt dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL:  		info = &dbg_port_ple_quemgn_qlnktbl; -		seq_puts(m, "Enable ple quemgn qlnktbl dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable ple quemgn qlnktbl dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY:  		info = &dbg_port_ple_quemgn_qempty; -		seq_puts(m, "Enable ple quemgn qempty dump.\n"); +		p += scnprintf(p, end - p, "Enable ple quemgn qempty dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PKTINFO:  		info = &dbg_port_pktinfo; -		seq_puts(m, "Enable pktinfo dump.\n"); +		p += scnprintf(p, end - p, "Enable pktinfo dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX0:  		rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL, @@ -2784,7 +2917,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, index); -		seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt tx%x dump.\n", index);  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX6:  		info = &dbg_port_dspt_hdt_tx6; @@ -2792,7 +2926,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 6); -		seq_puts(m, "Enable Dispatcher hdt tx6 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt tx6 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX7:  		info = &dbg_port_dspt_hdt_tx7; @@ -2800,7 +2935,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 7); -		seq_puts(m, "Enable Dispatcher hdt tx7 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt tx7 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX8:  		info = &dbg_port_dspt_hdt_tx8; @@ -2808,7 +2944,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 8); -		seq_puts(m, "Enable Dispatcher hdt tx8 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt tx8 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX9:  	case RTW89_DBG_PORT_SEL_DSPT_HDT_TXA: @@ -2820,7 +2957,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, index); -		seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt tx%x dump.\n", index);  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_TXD:  		info = &dbg_port_dspt_hdt_txD; @@ -2828,7 +2966,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 0xD); -		seq_puts(m, "Enable Dispatcher hdt txD dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt txD dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX0:  		info = &dbg_port_dspt_cdt_tx0; @@ -2836,7 +2975,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 0); -		seq_puts(m, "Enable Dispatcher cdt tx0 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt tx0 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX1:  		info = &dbg_port_dspt_cdt_tx1; @@ -2844,7 +2984,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 1); -		seq_puts(m, "Enable Dispatcher cdt tx1 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt tx1 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX3:  		info = &dbg_port_dspt_cdt_tx3; @@ -2852,7 +2993,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 3); -		seq_puts(m, "Enable Dispatcher cdt tx3 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt tx3 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX4:  		info = &dbg_port_dspt_cdt_tx4; @@ -2860,7 +3002,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 4); -		seq_puts(m, "Enable Dispatcher cdt tx4 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt tx4 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX5:  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX6: @@ -2872,7 +3015,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, index); -		seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt tx%x dump.\n", index);  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX9:  		info = &dbg_port_dspt_cdt_tx9; @@ -2880,7 +3024,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 9); -		seq_puts(m, "Enable Dispatcher cdt tx9 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt tx9 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TXA:  	case RTW89_DBG_PORT_SEL_DSPT_CDT_TXB: @@ -2891,7 +3036,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, index); -		seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt tx%x dump.\n", index);  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX0:  		info = &dbg_port_dspt_hdt_rx0; @@ -2899,7 +3045,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 0); -		seq_puts(m, "Enable Dispatcher hdt rx0 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt rx0 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX1:  	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX2: @@ -2909,7 +3056,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, index); -		seq_printf(m, "Enable Dispatcher hdt rx%x dump.\n", index); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt rx%x dump.\n", index);  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX3:  		info = &dbg_port_dspt_hdt_rx3; @@ -2917,7 +3065,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 3); -		seq_puts(m, "Enable Dispatcher hdt rx3 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt rx3 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX4:  		info = &dbg_port_dspt_hdt_rx4; @@ -2925,7 +3074,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 4); -		seq_puts(m, "Enable Dispatcher hdt rx4 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt rx4 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX5:  		info = &dbg_port_dspt_hdt_rx5; @@ -2933,7 +3083,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 5); -		seq_puts(m, "Enable Dispatcher hdt rx5 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher hdt rx5 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0:  		info = &dbg_port_dspt_cdt_rx_p0_0; @@ -2941,7 +3092,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 3);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 0); -		seq_puts(m, "Enable Dispatcher cdt rx part0 0 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt rx part0 0 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0:  	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1: @@ -2950,7 +3102,8 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 3);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 1); -		seq_puts(m, "Enable Dispatcher cdt rx part0 1 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt rx part0 1 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2:  		info = &dbg_port_dspt_cdt_rx_p0_2; @@ -2958,43 +3111,50 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  				   B_AX_DISPATCHER_INTN_SEL_MASK, 3);  		rtw89_write16_mask(rtwdev, info->sel_addr,  				   B_AX_DISPATCHER_CH_SEL_MASK, 2); -		seq_puts(m, "Enable Dispatcher cdt rx part0 2 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt rx part0 2 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1:  		info = &dbg_port_dspt_cdt_rx_p1;  		rtw89_write8_mask(rtwdev, info->sel_addr,  				  B_AX_DISPATCHER_INTN_SEL_MASK, 3); -		seq_puts(m, "Enable Dispatcher cdt rx part1 dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher cdt rx part1 dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_STF_CTRL:  		info = &dbg_port_dspt_stf_ctrl;  		rtw89_write8_mask(rtwdev, info->sel_addr,  				  B_AX_DISPATCHER_INTN_SEL_MASK, 4); -		seq_puts(m, "Enable Dispatcher stf control dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher stf control dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL:  		info = &dbg_port_dspt_addr_ctrl;  		rtw89_write8_mask(rtwdev, info->sel_addr,  				  B_AX_DISPATCHER_INTN_SEL_MASK, 5); -		seq_puts(m, "Enable Dispatcher addr control dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher addr control dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_WDE_INTF:  		info = &dbg_port_dspt_wde_intf;  		rtw89_write8_mask(rtwdev, info->sel_addr,  				  B_AX_DISPATCHER_INTN_SEL_MASK, 6); -		seq_puts(m, "Enable Dispatcher wde interface dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher wde interface dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_PLE_INTF:  		info = &dbg_port_dspt_ple_intf;  		rtw89_write8_mask(rtwdev, info->sel_addr,  				  B_AX_DISPATCHER_INTN_SEL_MASK, 7); -		seq_puts(m, "Enable Dispatcher ple interface dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher ple interface dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL:  		info = &dbg_port_dspt_flow_ctrl;  		rtw89_write8_mask(rtwdev, info->sel_addr,  				  B_AX_DISPATCHER_INTN_SEL_MASK, 8); -		seq_puts(m, "Enable Dispatcher flow control dump.\n"); +		p += scnprintf(p, end - p, +			       "Enable Dispatcher flow control dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PCIE_TXDMA:  		info = &dbg_port_pcie_txdma; @@ -3002,7 +3162,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL0);  		val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL1);  		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); -		seq_puts(m, "Enable pcie txdma dump.\n"); +		p += scnprintf(p, end - p, "Enable pcie txdma dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PCIE_RXDMA:  		info = &dbg_port_pcie_rxdma; @@ -3010,7 +3170,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL0);  		val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL1);  		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); -		seq_puts(m, "Enable pcie rxdma dump.\n"); +		p += scnprintf(p, end - p, "Enable pcie rxdma dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PCIE_CVT:  		info = &dbg_port_pcie_cvt; @@ -3018,7 +3178,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL0);  		val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL1);  		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); -		seq_puts(m, "Enable pcie cvt dump.\n"); +		p += scnprintf(p, end - p, "Enable pcie cvt dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PCIE_CXPL:  		info = &dbg_port_pcie_cxpl; @@ -3026,7 +3186,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL0);  		val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL1);  		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); -		seq_puts(m, "Enable pcie cxpl dump.\n"); +		p += scnprintf(p, end - p, "Enable pcie cxpl dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PCIE_IO:  		info = &dbg_port_pcie_io; @@ -3034,7 +3194,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL0);  		val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL1);  		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); -		seq_puts(m, "Enable pcie io dump.\n"); +		p += scnprintf(p, end - p, "Enable pcie io dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PCIE_MISC:  		info = &dbg_port_pcie_misc; @@ -3042,7 +3202,7 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL0);  		val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL1);  		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32); -		seq_puts(m, "Enable pcie misc dump.\n"); +		p += scnprintf(p, end - p, "Enable pcie misc dump.\n");  		break;  	case RTW89_DBG_PORT_SEL_PCIE_MISC2:  		info = &dbg_port_pcie_misc2; @@ -3050,14 +3210,16 @@ rtw89_debug_mac_dbg_port_sel(struct seq_file *m,  		val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL,  					 B_AX_PCIE_DBG_SEL_MASK);  		rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16); -		seq_puts(m, "Enable pcie misc2 dump.\n"); +		p += scnprintf(p, end - p, "Enable pcie misc2 dump.\n");  		break;  	default: -		seq_puts(m, "Dbg port select err\n"); -		return NULL; +		p += scnprintf(p, end - p, "Dbg port select err\n"); +		break;  	} -	return info; +	*ppinfo = info; + +	return p - buf;  }  static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel) @@ -3091,23 +3253,25 @@ static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel)  }  static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev, -					 struct seq_file *m, u32 sel) +					 char *buf, size_t bufsz, u32 sel)  { -	const struct rtw89_mac_dbg_port_info *info; -	u8 val8; -	u16 val16; +	const struct rtw89_mac_dbg_port_info *info = NULL; +	char *p = buf, *end = buf + bufsz;  	u32 val32; +	u16 val16; +	u8 val8;  	u32 i; -	info = rtw89_debug_mac_dbg_port_sel(m, rtwdev, sel); +	p += rtw89_debug_mac_dbg_port_sel(rtwdev, p, end - p, sel, &info); +  	if (!info) {  		rtw89_err(rtwdev, "failed to select debug port %d\n", sel); -		return -EINVAL; +		goto out;  	}  #define case_DBG_SEL(__sel) \  	case RTW89_DBG_PORT_SEL_##__sel: \ -		seq_puts(m, "Dump debug port " #__sel ":\n"); \ +		p += scnprintf(p, end - p, "Dump debug port " #__sel ":\n"); \  		break  	switch (sel) { @@ -3203,8 +3367,8 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,  #undef case_DBG_SEL -	seq_printf(m, "Sel addr = 0x%X\n", info->sel_addr); -	seq_printf(m, "Read addr = 0x%X\n", info->rd_addr); +	p += scnprintf(p, end - p, "Sel addr = 0x%X\n", info->sel_addr); +	p += scnprintf(p, end - p, "Read addr = 0x%X\n", info->rd_addr);  	for (i = info->srt; i <= info->end; i++) {  		switch (info->sel_byte) { @@ -3212,17 +3376,17 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,  		default:  			rtw89_write8_mask(rtwdev, info->sel_addr,  					  info->sel_msk, i); -			seq_printf(m, "0x%02X: ", i); +			p += scnprintf(p, end - p, "0x%02X: ", i);  			break;  		case 2:  			rtw89_write16_mask(rtwdev, info->sel_addr,  					   info->sel_msk, i); -			seq_printf(m, "0x%04X: ", i); +			p += scnprintf(p, end - p, "0x%04X: ", i);  			break;  		case 4:  			rtw89_write32_mask(rtwdev, info->sel_addr,  					   info->sel_msk, i); -			seq_printf(m, "0x%04X: ", i); +			p += scnprintf(p, end - p, "0x%04X: ", i);  			break;  		} @@ -3233,77 +3397,75 @@ static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,  		default:  			val8 = rtw89_read8_mask(rtwdev,  						info->rd_addr, info->rd_msk); -			seq_printf(m, "0x%02X\n", val8); +			p += scnprintf(p, end - p, "0x%02X\n", val8);  			break;  		case 2:  			val16 = rtw89_read16_mask(rtwdev,  						  info->rd_addr, info->rd_msk); -			seq_printf(m, "0x%04X\n", val16); +			p += scnprintf(p, end - p, "0x%04X\n", val16);  			break;  		case 4:  			val32 = rtw89_read32_mask(rtwdev,  						  info->rd_addr, info->rd_msk); -			seq_printf(m, "0x%08X\n", val32); +			p += scnprintf(p, end - p, "0x%08X\n", val32);  			break;  		}  	} -	return 0; +out: +	return p - buf;  }  static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev, -					 struct seq_file *m) +					 char *buf, size_t bufsz)  { +	char *p = buf, *end = buf + bufsz; +	ssize_t n;  	u32 sel; -	int ret = 0;  	for (sel = RTW89_DBG_PORT_SEL_PTCL_C0;  	     sel < RTW89_DBG_PORT_SEL_LAST; sel++) {  		if (!is_dbg_port_valid(rtwdev, sel))  			continue; -		ret = rtw89_debug_mac_dbg_port_dump(rtwdev, m, sel); -		if (ret) { +		n = rtw89_debug_mac_dbg_port_dump(rtwdev, p, end - p, sel); +		if (n < 0) {  			rtw89_err(rtwdev,  				  "failed to dump debug port %d\n", sel);  			break;  		} +		p += n;  	} -	return ret; +	return p - buf;  } -static int -rtw89_debug_priv_mac_dbg_port_dump_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_mac_dbg_port_dump_get(struct rtw89_dev *rtwdev, +				       struct rtw89_debugfs_priv *debugfs_priv, +				       char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; +	char *p = buf, *end = buf + bufsz;  	if (debugfs_priv->dbgpkg_en.ss_dbg) -		rtw89_debug_mac_dump_ss_dbg(rtwdev, m); +		p += rtw89_debug_mac_dump_ss_dbg(rtwdev, p, end - p);  	if (debugfs_priv->dbgpkg_en.dle_dbg) -		rtw89_debug_mac_dump_dle_dbg(rtwdev, m); +		p += rtw89_debug_mac_dump_dle_dbg(rtwdev, p, end - p);  	if (debugfs_priv->dbgpkg_en.dmac_dbg) -		rtw89_debug_mac_dump_dmac_dbg(rtwdev, m); +		p += rtw89_debug_mac_dump_dmac_dbg(rtwdev, p, end - p);  	if (debugfs_priv->dbgpkg_en.cmac_dbg) -		rtw89_debug_mac_dump_cmac_dbg(rtwdev, m); +		p += rtw89_debug_mac_dump_cmac_dbg(rtwdev, p, end - p);  	if (debugfs_priv->dbgpkg_en.dbg_port) -		rtw89_debug_mac_dump_dbg_port(rtwdev, m); +		p += rtw89_debug_mac_dump_dbg_port(rtwdev, p, end - p); -	return 0; +	return p - buf;  }; -static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev, -			      const char __user *user_buf, size_t count) +static u8 *rtw89_hex2bin(struct rtw89_dev *rtwdev, const char *buf, size_t count)  { -	char *buf;  	u8 *bin;  	int num;  	int err = 0; -	buf = memdup_user(user_buf, count); -	if (IS_ERR(buf)) -		return buf; -  	num = count / 2;  	bin = kmalloc(num, GFP_KERNEL);  	if (!bin) { @@ -3318,22 +3480,18 @@ static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev,  	}  out: -	kfree(buf); -  	return err ? ERR_PTR(err) : bin;  } -static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp, -					     const char __user *user_buf, -					     size_t count, loff_t *loff) +static ssize_t rtw89_debug_priv_send_h2c_set(struct rtw89_dev *rtwdev, +					     struct rtw89_debugfs_priv *debugfs_priv, +					     const char *buf, size_t count)  { -	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	u8 *h2c;  	int ret;  	u16 h2c_len = count / 2; -	h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); +	h2c = rtw89_hex2bin(rtwdev, buf, count);  	if (IS_ERR(h2c))  		return -EFAULT; @@ -3344,34 +3502,36 @@ static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp,  	return ret ? ret : count;  } -static int -rtw89_debug_priv_early_h2c_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_early_h2c_get(struct rtw89_dev *rtwdev, +			       struct rtw89_debugfs_priv *debugfs_priv, +			       char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	struct rtw89_early_h2c *early_h2c; +	char *p = buf, *end = buf + bufsz;  	int seq = 0; -	mutex_lock(&rtwdev->mutex); +	lockdep_assert_wiphy(rtwdev->hw->wiphy); +  	list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) -		seq_printf(m, "%d: %*ph\n", ++seq, early_h2c->h2c_len, early_h2c->h2c); -	mutex_unlock(&rtwdev->mutex); +		p += scnprintf(p, end - p, "%d: %*ph\n", ++seq, +			       early_h2c->h2c_len, early_h2c->h2c); -	return 0; +	return p - buf;  }  static ssize_t -rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf, -			       size_t count, loff_t *loff) +rtw89_debug_priv_early_h2c_set(struct rtw89_dev *rtwdev, +			       struct rtw89_debugfs_priv *debugfs_priv, +			       const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	struct rtw89_early_h2c *early_h2c;  	u8 *h2c;  	u16 h2c_len = count / 2; -	h2c = rtw89_hex2bin_user(rtwdev, user_buf, count); +	lockdep_assert_wiphy(rtwdev->hw->wiphy); + +	h2c = rtw89_hex2bin(rtwdev, buf, count);  	if (IS_ERR(h2c))  		return -EFAULT; @@ -3390,9 +3550,7 @@ rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf,  	early_h2c->h2c = h2c;  	early_h2c->h2c_len = h2c_len; -	mutex_lock(&rtwdev->mutex);  	list_add_tail(&early_h2c->list, &rtwdev->early_h2c_list); -	mutex_unlock(&rtwdev->mutex);  out:  	return count; @@ -3425,15 +3583,16 @@ static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev)  	return 0;  } -static int -rtw89_debug_priv_fw_crash_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_fw_crash_get(struct rtw89_dev *rtwdev, +			      struct rtw89_debugfs_priv *debugfs_priv, +			      char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; +	char *p = buf, *end = buf + bufsz; -	seq_printf(m, "%d\n", -		   test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags)); -	return 0; +	p += scnprintf(p, end - p, "%d\n", +		       test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags)); +	return p - buf;  }  enum rtw89_dbg_crash_simulation_type { @@ -3442,23 +3601,23 @@ enum rtw89_dbg_crash_simulation_type {  };  static ssize_t -rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf, -			      size_t count, loff_t *loff) +rtw89_debug_priv_fw_crash_set(struct rtw89_dev *rtwdev, +			      struct rtw89_debugfs_priv *debugfs_priv, +			      const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	int (*sim)(struct rtw89_dev *rtwdev);  	u8 crash_type;  	int ret; -	ret = kstrtou8_from_user(user_buf, count, 0, &crash_type); +	lockdep_assert_wiphy(rtwdev->hw->wiphy); + +	ret = kstrtou8(buf, 0, &crash_type);  	if (ret)  		return -EINVAL;  	switch (crash_type) {  	case RTW89_DBG_SIM_CPU_EXCEPTION: -		if (!RTW89_CHK_FW_FEATURE(CRASH_TRIGGER, &rtwdev->fw)) +		if (!RTW89_CHK_FW_FEATURE_GROUP(CRASH_TRIGGER, &rtwdev->fw))  			return -EOPNOTSUPP;  		sim = rtw89_fw_h2c_trigger_cpu_exception;  		break; @@ -3469,10 +3628,8 @@ rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf,  		return -EINVAL;  	} -	mutex_lock(&rtwdev->mutex);  	set_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags);  	ret = sim(rtwdev); -	mutex_unlock(&rtwdev->mutex);  	if (ret)  		return ret; @@ -3480,27 +3637,22 @@ rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf,  	return count;  } -static int rtw89_debug_priv_btc_info_get(struct seq_file *m, void *v) +static ssize_t rtw89_debug_priv_btc_info_get(struct rtw89_dev *rtwdev, +					     struct rtw89_debugfs_priv *debugfs_priv, +					     char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; - -	rtw89_btc_dump_info(rtwdev, m); - -	return 0; +	return rtw89_btc_dump_info(rtwdev, buf, bufsz);  } -static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp, -					       const char __user *user_buf, -					       size_t count, loff_t *loff) +static ssize_t rtw89_debug_priv_btc_manual_set(struct rtw89_dev *rtwdev, +					       struct rtw89_debugfs_priv *debugfs_priv, +					       const char *buf, size_t count)  { -	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	struct rtw89_btc *btc = &rtwdev->btc;  	const struct rtw89_btc_ver *ver = btc->ver;  	int ret; -	ret = kstrtobool_from_user(user_buf, count, &btc->manual_ctrl); +	ret = kstrtobool(buf, &btc->manual_ctrl);  	if (ret)  		return ret; @@ -3512,31 +3664,29 @@ static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp,  	return count;  } -static ssize_t rtw89_debug_priv_fw_log_manual_set(struct file *filp, -						  const char __user *user_buf, -						  size_t count, loff_t *loff) +static ssize_t rtw89_debug_priv_fw_log_manual_set(struct rtw89_dev *rtwdev, +						  struct rtw89_debugfs_priv *debugfs_priv, +						  const char *buf, size_t count)  { -	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	struct rtw89_fw_log *log = &rtwdev->fw.log;  	bool fw_log_manual; -	if (kstrtobool_from_user(user_buf, count, &fw_log_manual)) +	lockdep_assert_wiphy(rtwdev->hw->wiphy); + +	if (kstrtobool(buf, &fw_log_manual))  		goto out; -	mutex_lock(&rtwdev->mutex);  	log->enable = fw_log_manual;  	if (log->enable)  		rtw89_fw_log_prepare(rtwdev);  	rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual); -	mutex_unlock(&rtwdev->mutex);  out:  	return count;  } -static void rtw89_sta_link_info_get_iter(struct seq_file *m, -					 struct rtw89_dev *rtwdev, -					 struct rtw89_sta_link *rtwsta_link) +static int rtw89_sta_link_info_get_iter(struct rtw89_dev *rtwdev, +					char *buf, size_t bufsz, +					struct rtw89_sta_link *rtwsta_link)  {  	static const char * const he_gi_str[] = {  		[NL80211_RATE_INFO_HE_GI_0_8] = "0.8", @@ -3554,6 +3704,7 @@ static void rtw89_sta_link_info_get_iter(struct seq_file *m,  	u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;  	bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity;  	struct ieee80211_link_sta *link_sta; +	char *p = buf, *end = buf + bufsz;  	u8 evm_min, evm_max, evm_1ss;  	u16 max_rc_amsdu_len;  	u8 rssi; @@ -3567,107 +3718,136 @@ static void rtw89_sta_link_info_get_iter(struct seq_file *m,  	rcu_read_unlock(); -	seq_printf(m, "TX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id); +	p += scnprintf(p, end - p, "TX rate [%u, %u]: ", rtwsta_link->mac_id, +		       rtwsta_link->link_id);  	if (rate->flags & RATE_INFO_FLAGS_MCS) -		seq_printf(m, "HT MCS-%d%s", rate->mcs, -			   rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); +		p += scnprintf(p, end - p, "HT MCS-%d%s", rate->mcs, +			       rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");  	else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) -		seq_printf(m, "VHT %dSS MCS-%d%s", rate->nss, rate->mcs, -			   rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : ""); +		p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", rate->nss, +			       rate->mcs, +			       rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");  	else if (rate->flags & RATE_INFO_FLAGS_HE_MCS) -		seq_printf(m, "HE %dSS MCS-%d GI:%s", rate->nss, rate->mcs, -			   rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? -			   he_gi_str[rate->he_gi] : "N/A"); +		p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s", rate->nss, +			       rate->mcs, +			       rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? +			       he_gi_str[rate->he_gi] : "N/A");  	else if (rate->flags & RATE_INFO_FLAGS_EHT_MCS) -		seq_printf(m, "EHT %dSS MCS-%d GI:%s", rate->nss, rate->mcs, -			   rate->eht_gi < ARRAY_SIZE(eht_gi_str) ? -			   eht_gi_str[rate->eht_gi] : "N/A"); +		p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s", rate->nss, +			       rate->mcs, +			       rate->eht_gi < ARRAY_SIZE(eht_gi_str) ? +			       eht_gi_str[rate->eht_gi] : "N/A");  	else -		seq_printf(m, "Legacy %d", rate->legacy); -	seq_printf(m, "%s", rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : ""); -	seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw)); -	seq_printf(m, " (hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate); -	seq_printf(m, " ==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait, -		   max_rc_amsdu_len); - -	seq_printf(m, "RX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id); +		p += scnprintf(p, end - p, "Legacy %d", rate->legacy); +	p += scnprintf(p, end - p, "%s", +		       rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : ""); +	p += scnprintf(p, end - p, " BW:%u", +		       rtw89_rate_info_bw_to_mhz(rate->bw)); +	p += scnprintf(p, end - p, " (hw_rate=0x%x)", +		       rtwsta_link->ra_report.hw_rate); +	p += scnprintf(p, end - p, " ==> agg_wait=%d (%d)\n", +		       rtwsta_link->max_agg_wait, +		       max_rc_amsdu_len); + +	p += scnprintf(p, end - p, "RX rate [%u, %u]: ", rtwsta_link->mac_id, +		       rtwsta_link->link_id);  	switch (status->encoding) {  	case RX_ENC_LEGACY: -		seq_printf(m, "Legacy %d", status->rate_idx + -			   (status->band != NL80211_BAND_2GHZ ? 4 : 0)); +		p += scnprintf(p, end - p, "Legacy %d", status->rate_idx + +			       (status->band != NL80211_BAND_2GHZ ? 4 : 0));  		break;  	case RX_ENC_HT: -		seq_printf(m, "HT MCS-%d%s", status->rate_idx, -			   status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); +		p += scnprintf(p, end - p, "HT MCS-%d%s", status->rate_idx, +			       status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");  		break;  	case RX_ENC_VHT: -		seq_printf(m, "VHT %dSS MCS-%d%s", status->nss, status->rate_idx, -			   status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : ""); +		p += scnprintf(p, end - p, "VHT %dSS MCS-%d%s", status->nss, +			       status->rate_idx, +			       status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");  		break;  	case RX_ENC_HE: -		seq_printf(m, "HE %dSS MCS-%d GI:%s", status->nss, status->rate_idx, -			   status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? -			   he_gi_str[status->he_gi] : "N/A"); +		p += scnprintf(p, end - p, "HE %dSS MCS-%d GI:%s", +			       status->nss, status->rate_idx, +			       status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ? +			       he_gi_str[status->he_gi] : "N/A");  		break;  	case RX_ENC_EHT: -		seq_printf(m, "EHT %dSS MCS-%d GI:%s", status->nss, status->rate_idx, -			   status->eht.gi < ARRAY_SIZE(eht_gi_str) ? -			   eht_gi_str[status->eht.gi] : "N/A"); +		p += scnprintf(p, end - p, "EHT %dSS MCS-%d GI:%s", +			       status->nss, status->rate_idx, +			       status->eht.gi < ARRAY_SIZE(eht_gi_str) ? +			       eht_gi_str[status->eht.gi] : "N/A");  		break;  	} -	seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw)); -	seq_printf(m, " (hw_rate=0x%x)\n", rtwsta_link->rx_hw_rate); +	p += scnprintf(p, end - p, " BW:%u", +		       rtw89_rate_info_bw_to_mhz(status->bw)); +	p += scnprintf(p, end - p, " (hw_rate=0x%x)\n", +		       rtwsta_link->rx_hw_rate);  	rssi = ewma_rssi_read(&rtwsta_link->avg_rssi); -	seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [", -		   RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta_link->prev_rssi); +	p += scnprintf(p, end - p, "RSSI: %d dBm (raw=%d, prev=%d) [", +		       RTW89_RSSI_RAW_TO_DBM(rssi), rssi, +		       rtwsta_link->prev_rssi);  	for (i = 0; i < ant_num; i++) {  		rssi = ewma_rssi_read(&rtwsta_link->rssi[i]); -		seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi), -			   ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "", -			   i + 1 == ant_num ? "" : ", "); +		p += scnprintf(p, end - p, "%d%s%s", +			       RTW89_RSSI_RAW_TO_DBM(rssi), +			       ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "", +			       i + 1 == ant_num ? "" : ", ");  	} -	seq_puts(m, "]\n"); +	p += scnprintf(p, end - p, "]\n");  	evm_1ss = ewma_evm_read(&rtwsta_link->evm_1ss); -	seq_printf(m, "EVM: [%2u.%02u, ", evm_1ss >> 2, (evm_1ss & 0x3) * 25); +	p += scnprintf(p, end - p, "EVM: [%2u.%02u, ", evm_1ss >> 2, +		       (evm_1ss & 0x3) * 25);  	for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) {  		evm_min = ewma_evm_read(&rtwsta_link->evm_min[i]);  		evm_max = ewma_evm_read(&rtwsta_link->evm_max[i]); -		seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ", -			   evm_min >> 2, (evm_min & 0x3) * 25, -			   evm_max >> 2, (evm_max & 0x3) * 25); +		p += scnprintf(p, end - p, "%s(%2u.%02u, %2u.%02u)", +			       i == 0 ? "" : " ", +			       evm_min >> 2, (evm_min & 0x3) * 25, +			       evm_max >> 2, (evm_max & 0x3) * 25);  	} -	seq_puts(m, "]\t"); +	p += scnprintf(p, end - p, "]\t");  	snr = ewma_snr_read(&rtwsta_link->avg_snr); -	seq_printf(m, "SNR: %u\n", snr); +	p += scnprintf(p, end - p, "SNR: %u\n", snr); + +	return p - buf;  }  static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)  { -	struct seq_file *m = (struct seq_file *)data; +	struct rtw89_debugfs_iter_data *iter_data = +		(struct rtw89_debugfs_iter_data *)data;  	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);  	struct rtw89_dev *rtwdev = rtwsta->rtwdev;  	struct rtw89_sta_link *rtwsta_link; +	size_t bufsz = iter_data->bufsz; +	char *buf = iter_data->buf; +	char *p = buf, *end = buf + bufsz;  	unsigned int link_id;  	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) -		rtw89_sta_link_info_get_iter(m, rtwdev, rtwsta_link); +		p += rtw89_sta_link_info_get_iter(rtwdev, p, end - p, rtwsta_link); + +	rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf);  } -static void -rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat, +static int +rtw89_debug_append_rx_rate(char *buf, size_t bufsz, struct rtw89_pkt_stat *pkt_stat,  			   enum rtw89_hw_rate first_rate, int len)  { +	char *p = buf, *end = buf + bufsz;  	int i;  	for (i = 0; i < len; i++) -		seq_printf(m, "%s%u", i == 0 ? "" : ", ", -			   pkt_stat->rx_rate_cnt[first_rate + i]); +		p += scnprintf(p, end - p, "%s%u", i == 0 ? "" : ", ", +			       pkt_stat->rx_rate_cnt[first_rate + i]); + +	return p - buf;  }  #define FIRST_RATE_SAME(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_ ## rate} @@ -3692,34 +3872,40 @@ static const struct rtw89_rx_rate_cnt_info {  	{FIRST_RATE_GEV1(EHT_NSS2_MCS0), 14, 0, "EHT 2SS:"},  }; -static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v) +static ssize_t rtw89_debug_priv_phy_info_get(struct rtw89_dev *rtwdev, +					     struct rtw89_debugfs_priv *debugfs_priv, +					     char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	struct rtw89_traffic_stats *stats = &rtwdev->stats;  	struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat;  	const struct rtw89_chip_info *chip = rtwdev->chip; +	struct rtw89_debugfs_iter_data iter_data;  	const struct rtw89_rx_rate_cnt_info *info;  	struct rtw89_hal *hal = &rtwdev->hal; +	char *p = buf, *end = buf + bufsz;  	enum rtw89_hw_rate first_rate;  	u8 rssi;  	int i;  	rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi); -	seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d", -		   stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv); +	p += scnprintf(p, end - p, "TP TX: %u [%u] Mbps (lv: %d", +		       stats->tx_throughput, stats->tx_throughput_raw, +		       stats->tx_tfc_lv);  	if (hal->thermal_prot_lv) -		seq_printf(m, ", duty: %d%%", -			   100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP); -	seq_printf(m, "), RX: %u [%u] Mbps (lv: %d)\n", -		   stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv); -	seq_printf(m, "Beacon: %u (%d dBm), TF: %u\n", pkt_stat->beacon_nr, -		   RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic); -	seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len, -		   stats->rx_avg_len); - -	seq_puts(m, "RX count:\n"); +		p += scnprintf(p, end - p, ", duty: %d%%", +			       100 - hal->thermal_prot_lv * RTW89_THERMAL_PROT_STEP); +	p += scnprintf(p, end - p, "), RX: %u [%u] Mbps (lv: %d)\n", +		       stats->rx_throughput, stats->rx_throughput_raw, +		       stats->rx_tfc_lv); +	p += scnprintf(p, end - p, "Beacon: %u (%d dBm), TF: %u\n", +		       pkt_stat->beacon_nr, +		       RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic); +	p += scnprintf(p, end - p, "Avg packet length: TX=%u, RX=%u\n", +		       stats->tx_avg_len, +		       stats->rx_avg_len); + +	p += scnprintf(p, end - p, "RX count:\n");  	for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) {  		info = &rtw89_rx_rate_cnt_infos[i]; @@ -3727,189 +3913,279 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)  		if (first_rate >= RTW89_HW_RATE_NR)  			continue; -		seq_printf(m, "%10s [", info->rate_mode); -		rtw89_debug_append_rx_rate(m, pkt_stat, -					   first_rate, info->len); +		p += scnprintf(p, end - p, "%10s [", info->rate_mode); +		p += rtw89_debug_append_rx_rate(p, end - p, pkt_stat, +						first_rate, info->len);  		if (info->ext) { -			seq_puts(m, "]["); -			rtw89_debug_append_rx_rate(m, pkt_stat, -						   first_rate + info->len, info->ext); +			p += scnprintf(p, end - p, "]["); +			p += rtw89_debug_append_rx_rate(p, end - p, pkt_stat, +							first_rate + info->len, info->ext);  		} -		seq_puts(m, "]\n"); +		p += scnprintf(p, end - p, "]\n");  	} -	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, m); +	rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); +	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, &iter_data); +	p += iter_data.written_sz; -	return 0; +	return p - buf;  } -static void rtw89_dump_addr_cam(struct seq_file *m, -				struct rtw89_dev *rtwdev, -				struct rtw89_addr_cam_entry *addr_cam) +static int rtw89_dump_addr_cam(struct rtw89_dev *rtwdev, +			       char *buf, size_t bufsz, +			       struct rtw89_addr_cam_entry *addr_cam)  {  	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;  	const struct rtw89_sec_cam_entry *sec_entry; +	char *p = buf, *end = buf + bufsz;  	u8 sec_cam_idx;  	int i; -	seq_printf(m, "\taddr_cam_idx=%u\n", addr_cam->addr_cam_idx); -	seq_printf(m, "\t-> bssid_cam_idx=%u\n", addr_cam->bssid_cam_idx); -	seq_printf(m, "\tsec_cam_bitmap=%*ph\n", (int)sizeof(addr_cam->sec_cam_map), -		   addr_cam->sec_cam_map); +	p += scnprintf(p, end - p, "\taddr_cam_idx=%u\n", +		       addr_cam->addr_cam_idx); +	p += scnprintf(p, end - p, "\t-> bssid_cam_idx=%u\n", +		       addr_cam->bssid_cam_idx); +	p += scnprintf(p, end - p, "\tsec_cam_bitmap=%*ph\n", +		       (int)sizeof(addr_cam->sec_cam_map), +		       addr_cam->sec_cam_map);  	for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) {  		sec_cam_idx = addr_cam->sec_ent[i];  		sec_entry = cam_info->sec_entries[sec_cam_idx];  		if (!sec_entry)  			continue; -		seq_printf(m, "\tsec[%d]: sec_cam_idx %u", i, sec_entry->sec_cam_idx); +		p += scnprintf(p, end - p, "\tsec[%d]: sec_cam_idx %u", i, +			       sec_entry->sec_cam_idx);  		if (sec_entry->ext_key) -			seq_printf(m, ", %u", sec_entry->sec_cam_idx + 1); -		seq_puts(m, "\n"); +			p += scnprintf(p, end - p, ", %u", +				       sec_entry->sec_cam_idx + 1); +		p += scnprintf(p, end - p, "\n");  	} + +	return p - buf;  } -__printf(3, 4) -static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_list, -				   const char *fmt, ...) +__printf(4, 5) +static int rtw89_dump_pkt_offload(char *buf, size_t bufsz, struct list_head *pkt_list, +				  const char *fmt, ...)  { +	char *p = buf, *end = buf + bufsz;  	struct rtw89_pktofld_info *info;  	struct va_format vaf;  	va_list args;  	if (list_empty(pkt_list)) -		return; +		return 0;  	va_start(args, fmt);  	vaf.va = &args;  	vaf.fmt = fmt; -	seq_printf(m, "%pV", &vaf); +	p += scnprintf(p, end - p, "%pV", &vaf);  	va_end(args);  	list_for_each_entry(info, pkt_list, list) -		seq_printf(m, "%d ", info->id); +		p += scnprintf(p, end - p, "%d ", info->id); + +	p += scnprintf(p, end - p, "\n"); -	seq_puts(m, "\n"); +	return p - buf;  } -static void rtw89_vif_link_ids_get(struct seq_file *m, u8 *mac, -				   struct rtw89_dev *rtwdev, -				   struct rtw89_vif_link *rtwvif_link) +static int rtw89_vif_link_ids_get(struct rtw89_dev *rtwdev, +				  char *buf, size_t bufsz, u8 *mac, +				  struct rtw89_vif_link *rtwvif_link, +				  bool designated)  {  	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam; - -	seq_printf(m, "    [%u] %pM\n", rtwvif_link->mac_id, rtwvif_link->mac_addr); -	seq_printf(m, "\tlink_id=%u\n", rtwvif_link->link_id); -	seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx); -	rtw89_dump_addr_cam(m, rtwdev, &rtwvif_link->addr_cam); -	rtw89_dump_pkt_offload(m, &rtwvif_link->general_pkt_list, -			       "\tpkt_ofld[GENERAL]: "); +	char *p = buf, *end = buf + bufsz; + +	p += scnprintf(p, end - p, "    [%u] %pM\n", rtwvif_link->mac_id, +		       rtwvif_link->mac_addr); +	p += scnprintf(p, end - p, "\tlink_id=%u%s\n", rtwvif_link->link_id, +		       designated ? " (*)" : ""); +	p += scnprintf(p, end - p, "\tbssid_cam_idx=%u\n", +		       bssid_cam->bssid_cam_idx); +	p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwvif_link->addr_cam); +	p += rtw89_dump_pkt_offload(p, end - p, &rtwvif_link->general_pkt_list, +				    "\tpkt_ofld[GENERAL]: "); + +	return p - buf;  }  static  void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)  { -	struct seq_file *m = (struct seq_file *)data; +	struct rtw89_debugfs_iter_data *iter_data = +		(struct rtw89_debugfs_iter_data *)data;  	struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);  	struct rtw89_dev *rtwdev = rtwvif->rtwdev; +	struct rtw89_vif_link *designated_link;  	struct rtw89_vif_link *rtwvif_link; +	size_t bufsz = iter_data->bufsz; +	char *buf = iter_data->buf; +	char *p = buf, *end = buf + bufsz;  	unsigned int link_id; -	seq_printf(m, "VIF %pM\n", rtwvif->mac_addr); +	designated_link = rtw89_get_designated_link(rtwvif); + +	p += scnprintf(p, end - p, "VIF %pM\n", rtwvif->mac_addr);  	rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) -		rtw89_vif_link_ids_get(m, mac, rtwdev, rtwvif_link); +		p += rtw89_vif_link_ids_get(rtwdev, p, end - p, mac, rtwvif_link, +					    rtwvif_link == designated_link); + +	rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf);  } -static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_dev *rtwdev, -			      struct rtw89_sta_link *rtwsta_link) +static int rtw89_dump_ba_cam(struct rtw89_dev *rtwdev, +			     char *buf, size_t bufsz, +			     struct rtw89_sta_link *rtwsta_link)  {  	struct rtw89_ba_cam_entry *entry; +	char *p = buf, *end = buf + bufsz;  	bool first = true;  	list_for_each_entry(entry, &rtwsta_link->ba_cam_list, list) {  		if (first) { -			seq_puts(m, "\tba_cam "); +			p += scnprintf(p, end - p, "\tba_cam ");  			first = false;  		} else { -			seq_puts(m, ", "); +			p += scnprintf(p, end - p, ", ");  		} -		seq_printf(m, "tid[%u]=%d", entry->tid, -			   (int)(entry - rtwdev->cam_info.ba_cam_entry)); +		p += scnprintf(p, end - p, "tid[%u]=%d", entry->tid, +			       (int)(entry - rtwdev->cam_info.ba_cam_entry));  	} -	seq_puts(m, "\n"); +	p += scnprintf(p, end - p, "\n"); + +	return p - buf;  } -static void rtw89_sta_link_ids_get(struct seq_file *m, -				   struct rtw89_dev *rtwdev, -				   struct rtw89_sta_link *rtwsta_link) +static int rtw89_sta_link_ids_get(struct rtw89_dev *rtwdev, +				  char *buf, size_t bufsz, +				  struct rtw89_sta_link *rtwsta_link, +				  bool designated)  {  	struct ieee80211_link_sta *link_sta; +	char *p = buf, *end = buf + bufsz;  	rcu_read_lock();  	link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true); -	seq_printf(m, "    [%u] %pM\n", rtwsta_link->mac_id, link_sta->addr); +	p += scnprintf(p, end - p, "    [%u] %pM\n", rtwsta_link->mac_id, +		       link_sta->addr);  	rcu_read_unlock(); -	seq_printf(m, "\tlink_id=%u\n", rtwsta_link->link_id); -	rtw89_dump_addr_cam(m, rtwdev, &rtwsta_link->addr_cam); -	rtw89_dump_ba_cam(m, rtwdev, rtwsta_link); +	p += scnprintf(p, end - p, "\tlink_id=%u%s\n", rtwsta_link->link_id, +		       designated ? " (*)" : ""); +	p += rtw89_dump_addr_cam(rtwdev, p, end - p, &rtwsta_link->addr_cam); +	p += rtw89_dump_ba_cam(rtwdev, p, end - p, rtwsta_link); + +	return p - buf;  }  static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)  { -	struct seq_file *m = (struct seq_file *)data; +	struct rtw89_debugfs_iter_data *iter_data = +		(struct rtw89_debugfs_iter_data *)data;  	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);  	struct rtw89_dev *rtwdev = rtwsta->rtwdev; +	struct rtw89_sta_link *designated_link;  	struct rtw89_sta_link *rtwsta_link; +	size_t bufsz = iter_data->bufsz; +	char *buf = iter_data->buf; +	char *p = buf, *end = buf + bufsz;  	unsigned int link_id; -	seq_printf(m, "STA %pM %s\n", sta->addr, sta->tdls ? "(TDLS)" : ""); +	designated_link = rtw89_get_designated_link(rtwsta); + +	p += scnprintf(p, end - p, "STA %pM %s\n", sta->addr, +		       sta->tdls ? "(TDLS)" : "");  	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) -		rtw89_sta_link_ids_get(m, rtwdev, rtwsta_link); +		p += rtw89_sta_link_ids_get(rtwdev, p, end - p, rtwsta_link, +					    rtwsta_link == designated_link); + +	rtw89_debugfs_iter_data_next(iter_data, p, end - p, p - buf);  } -static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v) +static ssize_t rtw89_debug_priv_stations_get(struct rtw89_dev *rtwdev, +					     struct rtw89_debugfs_priv *debugfs_priv, +					     char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	struct rtw89_cam_info *cam_info = &rtwdev->cam_info; +	struct rtw89_debugfs_iter_data iter_data; +	char *p = buf, *end = buf + bufsz;  	u8 idx; -	mutex_lock(&rtwdev->mutex); - -	seq_puts(m, "map:\n"); -	seq_printf(m, "\tmac_id:    %*ph\n", (int)sizeof(rtwdev->mac_id_map), -		   rtwdev->mac_id_map); -	seq_printf(m, "\taddr_cam:  %*ph\n", (int)sizeof(cam_info->addr_cam_map), -		   cam_info->addr_cam_map); -	seq_printf(m, "\tbssid_cam: %*ph\n", (int)sizeof(cam_info->bssid_cam_map), -		   cam_info->bssid_cam_map); -	seq_printf(m, "\tsec_cam:   %*ph\n", (int)sizeof(cam_info->sec_cam_map), -		   cam_info->sec_cam_map); -	seq_printf(m, "\tba_cam:    %*ph\n", (int)sizeof(cam_info->ba_cam_map), -		   cam_info->ba_cam_map); -	seq_printf(m, "\tpkt_ofld:  %*ph\n", (int)sizeof(rtwdev->pkt_offload), -		   rtwdev->pkt_offload); +	lockdep_assert_wiphy(rtwdev->hw->wiphy); + +	p += scnprintf(p, end - p, "map:\n"); +	p += scnprintf(p, end - p, "\tmac_id:    %*ph\n", +		       (int)sizeof(rtwdev->mac_id_map), +		       rtwdev->mac_id_map); +	p += scnprintf(p, end - p, "\taddr_cam:  %*ph\n", +		       (int)sizeof(cam_info->addr_cam_map), +		       cam_info->addr_cam_map); +	p += scnprintf(p, end - p, "\tbssid_cam: %*ph\n", +		       (int)sizeof(cam_info->bssid_cam_map), +		       cam_info->bssid_cam_map); +	p += scnprintf(p, end - p, "\tsec_cam:   %*ph\n", +		       (int)sizeof(cam_info->sec_cam_map), +		       cam_info->sec_cam_map); +	p += scnprintf(p, end - p, "\tba_cam:    %*ph\n", +		       (int)sizeof(cam_info->ba_cam_map), +		       cam_info->ba_cam_map); +	p += scnprintf(p, end - p, "\tpkt_ofld:  %*ph\n", +		       (int)sizeof(rtwdev->pkt_offload), +		       rtwdev->pkt_offload);  	for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {  		if (!(rtwdev->chip->support_bands & BIT(idx)))  			continue; -		rtw89_dump_pkt_offload(m, &rtwdev->scan_info.pkt_list[idx], -				       "\t\t[SCAN %u]: ", idx); +		p += rtw89_dump_pkt_offload(p, end - p, &rtwdev->scan_info.pkt_list[idx], +					    "\t\t[SCAN %u]: ", idx);  	} +	rtw89_debugfs_iter_data_setup(&iter_data, p, end - p);  	ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, -		IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m); +		IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, &iter_data); +	p += iter_data.written_sz; + +	rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); +	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, &iter_data); +	p += iter_data.written_sz; -	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m); +	return p - buf; +} -	mutex_unlock(&rtwdev->mutex); +static void rtw89_debug_disable_dm_cfg_bmap(struct rtw89_dev *rtwdev, u32 new) +{ +	struct rtw89_hal *hal = &rtwdev->hal; +	u32 old = hal->disabled_dm_bitmap; -	return 0; +	if (new == old) +		return; + +	hal->disabled_dm_bitmap = new; + +	rtw89_debug(rtwdev, RTW89_DBG_STATE, "Disable DM: 0x%x -> 0x%x\n", old, new); +} + +static void rtw89_debug_disable_dm_set_flag(struct rtw89_dev *rtwdev, u8 flag) +{ +	struct rtw89_hal *hal = &rtwdev->hal; +	u32 cur = hal->disabled_dm_bitmap; + +	rtw89_debug_disable_dm_cfg_bmap(rtwdev, cur | BIT(flag)); +} + +static void rtw89_debug_disable_dm_clr_flag(struct rtw89_dev *rtwdev, u8 flag) +{ +	struct rtw89_hal *hal = &rtwdev->hal; +	u32 cur = hal->disabled_dm_bitmap; + +	rtw89_debug_disable_dm_cfg_bmap(rtwdev, cur & ~BIT(flag));  }  #define DM_INFO(type) {RTW89_DM_ ## type, #type} @@ -3920,92 +4196,187 @@ static const struct rtw89_disabled_dm_info {  } rtw89_disabled_dm_infos[] = {  	DM_INFO(DYNAMIC_EDCCA),  	DM_INFO(THERMAL_PROTECT), +	DM_INFO(TAS), +	DM_INFO(MLO),  }; -static int -rtw89_debug_priv_disable_dm_get(struct seq_file *m, void *v) +static ssize_t +rtw89_debug_priv_disable_dm_get(struct rtw89_dev *rtwdev, +				struct rtw89_debugfs_priv *debugfs_priv, +				char *buf, size_t bufsz)  { -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;  	const struct rtw89_disabled_dm_info *info;  	struct rtw89_hal *hal = &rtwdev->hal; +	char *p = buf, *end = buf + bufsz;  	u32 disabled;  	int i; -	seq_printf(m, "Disabled DM: 0x%x\n", hal->disabled_dm_bitmap); +	p += scnprintf(p, end - p, "Disabled DM: 0x%x\n", +		       hal->disabled_dm_bitmap);  	for (i = 0; i < ARRAY_SIZE(rtw89_disabled_dm_infos); i++) {  		info = &rtw89_disabled_dm_infos[i];  		disabled = BIT(info->type) & hal->disabled_dm_bitmap; -		seq_printf(m, "[%d] %s: %c\n", info->type, info->name, -			   disabled ? 'X' : 'O'); +		p += scnprintf(p, end - p, "[%d] %s: %c\n", info->type, +			       info->name, +			       disabled ? 'X' : 'O');  	} -	return 0; +	return p - buf;  }  static ssize_t -rtw89_debug_priv_disable_dm_set(struct file *filp, const char __user *user_buf, -				size_t count, loff_t *loff) +rtw89_debug_priv_disable_dm_set(struct rtw89_dev *rtwdev, +				struct rtw89_debugfs_priv *debugfs_priv, +				const char *buf, size_t count)  { -	struct seq_file *m = (struct seq_file *)filp->private_data; -	struct rtw89_debugfs_priv *debugfs_priv = m->private; -	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; -	struct rtw89_hal *hal = &rtwdev->hal;  	u32 conf;  	int ret; -	ret = kstrtou32_from_user(user_buf, count, 0, &conf); +	ret = kstrtou32(buf, 0, &conf);  	if (ret)  		return -EINVAL; -	hal->disabled_dm_bitmap = conf; +	rtw89_debug_disable_dm_cfg_bmap(rtwdev, conf); + +	return count; +} + +static void rtw89_debug_mlo_mode_set_mlsr(struct rtw89_dev *rtwdev, +					  unsigned int link_id) +{ +	struct ieee80211_vif *vif; +	struct rtw89_vif *rtwvif; + +	rtw89_for_each_rtwvif(rtwdev, rtwvif) { +		vif = rtwvif_to_vif(rtwvif); +		if (!ieee80211_vif_is_mld(vif)) +			continue; + +		rtw89_core_mlsr_switch(rtwdev, rtwvif, link_id); +	} +} + +static ssize_t +rtw89_debug_priv_mlo_mode_get(struct rtw89_dev *rtwdev, +			      struct rtw89_debugfs_priv *debugfs_priv, +			      char *buf, size_t bufsz) +{ +	bool mlo_dm_dis = rtwdev->hal.disabled_dm_bitmap & BIT(RTW89_DM_MLO); +	char *p = buf, *end = buf + bufsz; +	struct ieee80211_vif *vif; +	struct rtw89_vif *rtwvif; +	int count = 0; + +	p += scnprintf(p, end - p, "MLD(s) status: (MLO DM: %s)\n", +		       str_disable_enable(mlo_dm_dis)); + +	rtw89_for_each_rtwvif(rtwdev, rtwvif) { +		vif = rtwvif_to_vif(rtwvif); +		if (!ieee80211_vif_is_mld(vif)) +			continue; + +		p += scnprintf(p, end - p, +			       "\t#%u: MLO mode %x, valid 0x%x, active 0x%x\n", +			       count++, rtwvif->mlo_mode, vif->valid_links, +			       vif->active_links); +	} + +	if (count == 0) +		p += scnprintf(p, end - p, "\t(None)\n"); + +	return p - buf; +} + +static ssize_t +rtw89_debug_priv_mlo_mode_set(struct rtw89_dev *rtwdev, +			      struct rtw89_debugfs_priv *debugfs_priv, +			      const char *buf, size_t count) +{ +	u8 num, mlo_mode; +	u32 argv; + +	num = sscanf(buf, "%hhx %u", &mlo_mode, &argv); +	if (num != 2) +		return -EINVAL; + +	rtw89_debug_disable_dm_set_flag(rtwdev, RTW89_DM_MLO); + +	rtw89_debug(rtwdev, RTW89_DBG_STATE, "Set MLO mode to %x\n", mlo_mode); + +	switch (mlo_mode) { +	case RTW89_MLO_MODE_MLSR: +		rtw89_debug_mlo_mode_set_mlsr(rtwdev, argv); +		break; +	default: +		rtw89_debug(rtwdev, RTW89_DBG_STATE, "Unsupported MLO mode\n"); +		rtw89_debug_disable_dm_clr_flag(rtwdev, RTW89_DM_MLO); + +		return -EOPNOTSUPP; +	}  	return count;  } -#define rtw89_debug_priv_get(name)				\ +#define rtw89_debug_priv_get(name, opts...)			\  {								\  	.cb_read = rtw89_debug_priv_ ##name## _get,		\ +	.opt = { opts },					\  } -#define rtw89_debug_priv_set(name)				\ +#define rtw89_debug_priv_set(name, opts...)			\  {								\  	.cb_write = rtw89_debug_priv_ ##name## _set,		\ +	.opt = { opts },					\  } -#define rtw89_debug_priv_select_and_get(name)			\ +#define rtw89_debug_priv_select_and_get(name, opts...)		\  {								\  	.cb_write = rtw89_debug_priv_ ##name## _select,		\  	.cb_read = rtw89_debug_priv_ ##name## _get,		\ +	.opt = { opts },					\  } -#define rtw89_debug_priv_set_and_get(name)			\ +#define rtw89_debug_priv_set_and_get(name, opts...)		\  {								\  	.cb_write = rtw89_debug_priv_ ##name## _set,		\  	.cb_read = rtw89_debug_priv_ ##name## _get,		\ +	.opt = { opts },					\  } +#define RSIZE_8K .rsize = 0x2000 +#define RSIZE_12K .rsize = 0x3000 +#define RSIZE_16K .rsize = 0x4000 +#define RSIZE_20K .rsize = 0x5000 +#define RSIZE_32K .rsize = 0x8000 +#define RSIZE_64K .rsize = 0x10000 +#define RSIZE_128K .rsize = 0x20000 +#define RSIZE_1M .rsize = 0x100000 +#define RLOCK .rlock = 1 +#define WLOCK .wlock = 1 +#define RWLOCK RLOCK, WLOCK +  static const struct rtw89_debugfs rtw89_debugfs_templ = {  	.read_reg = rtw89_debug_priv_select_and_get(read_reg),  	.write_reg = rtw89_debug_priv_set(write_reg),  	.read_rf = rtw89_debug_priv_select_and_get(read_rf),  	.write_rf = rtw89_debug_priv_set(write_rf), -	.rf_reg_dump = rtw89_debug_priv_get(rf_reg_dump), -	.txpwr_table = rtw89_debug_priv_get(txpwr_table), -	.mac_reg_dump = rtw89_debug_priv_select_and_get(mac_reg_dump), -	.mac_mem_dump = rtw89_debug_priv_select_and_get(mac_mem_dump), -	.mac_dbg_port_dump = rtw89_debug_priv_select_and_get(mac_dbg_port_dump), +	.rf_reg_dump = rtw89_debug_priv_get(rf_reg_dump, RSIZE_8K), +	.txpwr_table = rtw89_debug_priv_get(txpwr_table, RSIZE_20K, RLOCK), +	.mac_reg_dump = rtw89_debug_priv_select_and_get(mac_reg_dump, RSIZE_128K), +	.mac_mem_dump = rtw89_debug_priv_select_and_get(mac_mem_dump, RSIZE_16K, RLOCK), +	.mac_dbg_port_dump = rtw89_debug_priv_select_and_get(mac_dbg_port_dump, RSIZE_1M),  	.send_h2c = rtw89_debug_priv_set(send_h2c), -	.early_h2c = rtw89_debug_priv_set_and_get(early_h2c), -	.fw_crash = rtw89_debug_priv_set_and_get(fw_crash), -	.btc_info = rtw89_debug_priv_get(btc_info), +	.early_h2c = rtw89_debug_priv_set_and_get(early_h2c, RWLOCK), +	.fw_crash = rtw89_debug_priv_set_and_get(fw_crash, WLOCK), +	.btc_info = rtw89_debug_priv_get(btc_info, RSIZE_12K),  	.btc_manual = rtw89_debug_priv_set(btc_manual), -	.fw_log_manual = rtw89_debug_priv_set(fw_log_manual), +	.fw_log_manual = rtw89_debug_priv_set(fw_log_manual, WLOCK),  	.phy_info = rtw89_debug_priv_get(phy_info), -	.stations = rtw89_debug_priv_get(stations), -	.disable_dm = rtw89_debug_priv_set_and_get(disable_dm), +	.stations = rtw89_debug_priv_get(stations, RLOCK), +	.disable_dm = rtw89_debug_priv_set_and_get(disable_dm, RWLOCK), +	.mlo_mode = rtw89_debug_priv_set_and_get(mlo_mode, RWLOCK),  };  #define rtw89_debugfs_add(name, mode, fopname, parent)				\ @@ -4050,6 +4421,7 @@ void rtw89_debugfs_add_sec1(struct rtw89_dev *rtwdev, struct dentry *debugfs_top  	rtw89_debugfs_add_r(phy_info);  	rtw89_debugfs_add_r(stations);  	rtw89_debugfs_add_rw(disable_dm); +	rtw89_debugfs_add_rw(mlo_mode);  }  void rtw89_debugfs_init(struct rtw89_dev *rtwdev) | 
