Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: ISC
   2/*
   3 * Copyright (c) 2005-2011 Atheros Communications Inc.
   4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
   5 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/debugfs.h>
  10#include <linux/vmalloc.h>
  11#include <linux/crc32.h>
  12#include <linux/firmware.h>
  13
  14#include "core.h"
  15#include "debug.h"
  16#include "hif.h"
  17#include "wmi-ops.h"
  18
  19/* ms */
  20#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
  21
  22#define ATH10K_DEBUG_CAL_DATA_LEN 12064
  23
  24void ath10k_info(struct ath10k *ar, const char *fmt, ...)
  25{
  26	struct va_format vaf = {
  27		.fmt = fmt,
  28	};
  29	va_list args;
  30
  31	va_start(args, fmt);
  32	vaf.va = &args;
  33	dev_info(ar->dev, "%pV", &vaf);
  34	trace_ath10k_log_info(ar, &vaf);
  35	va_end(args);
  36}
  37EXPORT_SYMBOL(ath10k_info);
  38
  39void ath10k_debug_print_hwfw_info(struct ath10k *ar)
  40{
  41	const struct firmware *firmware;
  42	char fw_features[128] = {};
  43	u32 crc = 0;
  44
  45	ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features));
  46
  47	ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x",
  48		    ar->hw_params.name,
  49		    ar->target_version,
  50		    ar->bus_param.chip_id,
  51		    ar->id.subsystem_vendor, ar->id.subsystem_device);
  52
  53	ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n",
  54		    IS_ENABLED(CONFIG_ATH10K_DEBUG),
  55		    IS_ENABLED(CONFIG_ATH10K_DEBUGFS),
  56		    IS_ENABLED(CONFIG_ATH10K_TRACING),
  57		    IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED),
  58		    IS_ENABLED(CONFIG_NL80211_TESTMODE));
  59
  60	firmware = ar->normal_mode_fw.fw_file.firmware;
  61	if (firmware)
  62		crc = crc32_le(0, firmware->data, firmware->size);
  63
  64	ath10k_info(ar, "firmware ver %s api %d features %s crc32 %08x\n",
  65		    ar->hw->wiphy->fw_version,
  66		    ar->fw_api,
  67		    fw_features,
  68		    crc);
  69}
  70
  71void ath10k_debug_print_board_info(struct ath10k *ar)
  72{
  73	char boardinfo[100];
  74	const struct firmware *board;
  75	u32 crc;
  76
  77	if (ar->id.bmi_ids_valid)
  78		scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
  79			  ar->id.bmi_chip_id, ar->id.bmi_board_id);
  80	else
  81		scnprintf(boardinfo, sizeof(boardinfo), "N/A");
  82
  83	board = ar->normal_mode_fw.board;
  84	if (!IS_ERR_OR_NULL(board))
  85		crc = crc32_le(0, board->data, board->size);
  86	else
  87		crc = 0;
  88
  89	ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
  90		    ar->bd_api,
  91		    boardinfo,
  92		    crc);
  93}
  94
  95void ath10k_debug_print_boot_info(struct ath10k *ar)
  96{
  97	ath10k_info(ar, "htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d\n",
  98		    ar->htt.target_version_major,
  99		    ar->htt.target_version_minor,
 100		    ar->normal_mode_fw.fw_file.wmi_op_version,
 101		    ar->normal_mode_fw.fw_file.htt_op_version,
 102		    ath10k_cal_mode_str(ar->cal_mode),
 103		    ar->max_num_stations,
 104		    test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags),
 105		    !test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags));
 106}
 107
 108void ath10k_print_driver_info(struct ath10k *ar)
 109{
 110	ath10k_debug_print_hwfw_info(ar);
 111	ath10k_debug_print_board_info(ar);
 112	ath10k_debug_print_boot_info(ar);
 113}
 114EXPORT_SYMBOL(ath10k_print_driver_info);
 115
 116void ath10k_err(struct ath10k *ar, const char *fmt, ...)
 117{
 118	struct va_format vaf = {
 119		.fmt = fmt,
 120	};
 121	va_list args;
 122
 123	va_start(args, fmt);
 124	vaf.va = &args;
 125	dev_err(ar->dev, "%pV", &vaf);
 126	trace_ath10k_log_err(ar, &vaf);
 127	va_end(args);
 128}
 129EXPORT_SYMBOL(ath10k_err);
 130
 131void ath10k_warn(struct ath10k *ar, const char *fmt, ...)
 132{
 133	struct va_format vaf = {
 134		.fmt = fmt,
 135	};
 136	va_list args;
 137
 138	va_start(args, fmt);
 139	vaf.va = &args;
 140	dev_warn_ratelimited(ar->dev, "%pV", &vaf);
 141	trace_ath10k_log_warn(ar, &vaf);
 142
 143	va_end(args);
 144}
 145EXPORT_SYMBOL(ath10k_warn);
 146
 147#ifdef CONFIG_ATH10K_DEBUGFS
 148
 149static ssize_t ath10k_read_wmi_services(struct file *file,
 150					char __user *user_buf,
 151					size_t count, loff_t *ppos)
 152{
 153	struct ath10k *ar = file->private_data;
 154	char *buf;
 155	size_t len = 0, buf_len = 8192;
 156	const char *name;
 157	ssize_t ret_cnt;
 158	bool enabled;
 159	int i;
 160
 161	buf = kzalloc(buf_len, GFP_KERNEL);
 162	if (!buf)
 163		return -ENOMEM;
 164
 165	mutex_lock(&ar->conf_mutex);
 166
 167	spin_lock_bh(&ar->data_lock);
 168	for (i = 0; i < WMI_SERVICE_MAX; i++) {
 169		enabled = test_bit(i, ar->wmi.svc_map);
 170		name = wmi_service_name(i);
 171
 172		if (!name) {
 173			if (enabled)
 174				len += scnprintf(buf + len, buf_len - len,
 175						 "%-40s %s (bit %d)\n",
 176						 "unknown", "enabled", i);
 177
 178			continue;
 179		}
 180
 181		len += scnprintf(buf + len, buf_len - len,
 182				 "%-40s %s\n",
 183				 name, enabled ? "enabled" : "-");
 184	}
 185	spin_unlock_bh(&ar->data_lock);
 186
 187	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 188
 189	mutex_unlock(&ar->conf_mutex);
 190
 191	kfree(buf);
 192	return ret_cnt;
 193}
 194
 195static const struct file_operations fops_wmi_services = {
 196	.read = ath10k_read_wmi_services,
 197	.open = simple_open,
 198	.owner = THIS_MODULE,
 199	.llseek = default_llseek,
 200};
 201
 202static void ath10k_fw_stats_pdevs_free(struct list_head *head)
 203{
 204	struct ath10k_fw_stats_pdev *i, *tmp;
 205
 206	list_for_each_entry_safe(i, tmp, head, list) {
 207		list_del(&i->list);
 208		kfree(i);
 209	}
 210}
 211
 212static void ath10k_fw_stats_vdevs_free(struct list_head *head)
 213{
 214	struct ath10k_fw_stats_vdev *i, *tmp;
 215
 216	list_for_each_entry_safe(i, tmp, head, list) {
 217		list_del(&i->list);
 218		kfree(i);
 219	}
 220}
 221
 222static void ath10k_fw_stats_peers_free(struct list_head *head)
 223{
 224	struct ath10k_fw_stats_peer *i, *tmp;
 225
 226	list_for_each_entry_safe(i, tmp, head, list) {
 227		list_del(&i->list);
 228		kfree(i);
 229	}
 230}
 231
 232static void ath10k_fw_extd_stats_peers_free(struct list_head *head)
 233{
 234	struct ath10k_fw_extd_stats_peer *i, *tmp;
 235
 236	list_for_each_entry_safe(i, tmp, head, list) {
 237		list_del(&i->list);
 238		kfree(i);
 239	}
 240}
 241
 242static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
 243{
 244	spin_lock_bh(&ar->data_lock);
 245	ar->debug.fw_stats_done = false;
 246	ar->debug.fw_stats.extended = false;
 247	ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
 248	ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
 249	ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
 250	ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
 251	spin_unlock_bh(&ar->data_lock);
 252}
 253
 254void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
 255{
 256	struct ath10k_fw_stats stats = {};
 257	bool is_start, is_started, is_end;
 258	size_t num_peers;
 259	size_t num_vdevs;
 260	int ret;
 261
 262	INIT_LIST_HEAD(&stats.pdevs);
 263	INIT_LIST_HEAD(&stats.vdevs);
 264	INIT_LIST_HEAD(&stats.peers);
 265	INIT_LIST_HEAD(&stats.peers_extd);
 266
 267	spin_lock_bh(&ar->data_lock);
 268	ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats);
 269	if (ret) {
 270		ath10k_warn(ar, "failed to pull fw stats: %d\n", ret);
 271		goto free;
 272	}
 273
 274	/* Stat data may exceed htc-wmi buffer limit. In such case firmware
 275	 * splits the stats data and delivers it in a ping-pong fashion of
 276	 * request cmd-update event.
 277	 *
 278	 * However there is no explicit end-of-data. Instead start-of-data is
 279	 * used as an implicit one. This works as follows:
 280	 *  a) discard stat update events until one with pdev stats is
 281	 *     delivered - this skips session started at end of (b)
 282	 *  b) consume stat update events until another one with pdev stats is
 283	 *     delivered which is treated as end-of-data and is itself discarded
 284	 */
 285	if (ath10k_peer_stats_enabled(ar))
 286		ath10k_sta_update_rx_duration(ar, &stats);
 287
 288	if (ar->debug.fw_stats_done) {
 289		if (!ath10k_peer_stats_enabled(ar))
 290			ath10k_warn(ar, "received unsolicited stats update event\n");
 291
 292		goto free;
 293	}
 294
 295	num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers);
 296	num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
 297	is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
 298		    !list_empty(&stats.pdevs));
 299	is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
 300		  !list_empty(&stats.pdevs));
 301
 302	if (is_start)
 303		list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
 304
 305	if (is_end)
 306		ar->debug.fw_stats_done = true;
 307
 308	if (stats.extended)
 309		ar->debug.fw_stats.extended = true;
 310
 311	is_started = !list_empty(&ar->debug.fw_stats.pdevs);
 312
 313	if (is_started && !is_end) {
 314		if (num_peers >= ATH10K_MAX_NUM_PEER_IDS) {
 315			/* Although this is unlikely impose a sane limit to
 316			 * prevent firmware from DoS-ing the host.
 317			 */
 318			ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
 319			ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
 320			ath10k_warn(ar, "dropping fw peer stats\n");
 321			goto free;
 322		}
 323
 324		if (num_vdevs >= BITS_PER_LONG) {
 325			ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
 326			ath10k_warn(ar, "dropping fw vdev stats\n");
 327			goto free;
 328		}
 329
 330		if (!list_empty(&stats.peers))
 331			list_splice_tail_init(&stats.peers_extd,
 332					      &ar->debug.fw_stats.peers_extd);
 333
 334		list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
 335		list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
 336	}
 337
 338	complete(&ar->debug.fw_stats_complete);
 339
 340free:
 341	/* In some cases lists have been spliced and cleared. Free up
 342	 * resources if that is not the case.
 343	 */
 344	ath10k_fw_stats_pdevs_free(&stats.pdevs);
 345	ath10k_fw_stats_vdevs_free(&stats.vdevs);
 346	ath10k_fw_stats_peers_free(&stats.peers);
 347	ath10k_fw_extd_stats_peers_free(&stats.peers_extd);
 348
 349	spin_unlock_bh(&ar->data_lock);
 350}
 351
 352int ath10k_debug_fw_stats_request(struct ath10k *ar)
 353{
 354	unsigned long timeout, time_left;
 355	int ret;
 356
 357	lockdep_assert_held(&ar->conf_mutex);
 358
 359	timeout = jiffies + msecs_to_jiffies(1 * HZ);
 360
 361	ath10k_debug_fw_stats_reset(ar);
 362
 363	for (;;) {
 364		if (time_after(jiffies, timeout))
 365			return -ETIMEDOUT;
 366
 367		reinit_completion(&ar->debug.fw_stats_complete);
 368
 369		ret = ath10k_wmi_request_stats(ar, ar->fw_stats_req_mask);
 370		if (ret) {
 371			ath10k_warn(ar, "could not request stats (%d)\n", ret);
 372			return ret;
 373		}
 374
 375		time_left =
 376		wait_for_completion_timeout(&ar->debug.fw_stats_complete,
 377					    1 * HZ);
 378		if (!time_left)
 379			return -ETIMEDOUT;
 380
 381		spin_lock_bh(&ar->data_lock);
 382		if (ar->debug.fw_stats_done) {
 383			spin_unlock_bh(&ar->data_lock);
 384			break;
 385		}
 386		spin_unlock_bh(&ar->data_lock);
 387	}
 388
 389	return 0;
 390}
 391
 392static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
 393{
 394	struct ath10k *ar = inode->i_private;
 395	void *buf = NULL;
 396	int ret;
 397
 398	mutex_lock(&ar->conf_mutex);
 399
 400	if (ar->state != ATH10K_STATE_ON) {
 401		ret = -ENETDOWN;
 402		goto err_unlock;
 403	}
 404
 405	buf = vmalloc(ATH10K_FW_STATS_BUF_SIZE);
 406	if (!buf) {
 407		ret = -ENOMEM;
 408		goto err_unlock;
 409	}
 410
 411	ret = ath10k_debug_fw_stats_request(ar);
 412	if (ret) {
 413		ath10k_warn(ar, "failed to request fw stats: %d\n", ret);
 414		goto err_free;
 415	}
 416
 417	ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
 418	if (ret) {
 419		ath10k_warn(ar, "failed to fill fw stats: %d\n", ret);
 420		goto err_free;
 421	}
 422
 423	file->private_data = buf;
 424
 425	mutex_unlock(&ar->conf_mutex);
 426	return 0;
 427
 428err_free:
 429	vfree(buf);
 430
 431err_unlock:
 432	mutex_unlock(&ar->conf_mutex);
 433	return ret;
 434}
 435
 436static int ath10k_fw_stats_release(struct inode *inode, struct file *file)
 437{
 438	vfree(file->private_data);
 439
 440	return 0;
 441}
 442
 443static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf,
 444				    size_t count, loff_t *ppos)
 445{
 446	const char *buf = file->private_data;
 447	size_t len = strlen(buf);
 448
 449	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 450}
 451
 452static const struct file_operations fops_fw_stats = {
 453	.open = ath10k_fw_stats_open,
 454	.release = ath10k_fw_stats_release,
 455	.read = ath10k_fw_stats_read,
 456	.owner = THIS_MODULE,
 457	.llseek = default_llseek,
 458};
 459
 460static ssize_t ath10k_debug_fw_reset_stats_read(struct file *file,
 461						char __user *user_buf,
 462						size_t count, loff_t *ppos)
 463{
 464	struct ath10k *ar = file->private_data;
 465	int ret;
 466	size_t len = 0, buf_len = 500;
 467	char *buf;
 468
 469	buf = kmalloc(buf_len, GFP_KERNEL);
 470	if (!buf)
 471		return -ENOMEM;
 472
 473	spin_lock_bh(&ar->data_lock);
 474
 475	len += scnprintf(buf + len, buf_len - len,
 476			 "fw_crash_counter\t\t%d\n", ar->stats.fw_crash_counter);
 477	len += scnprintf(buf + len, buf_len - len,
 478			 "fw_warm_reset_counter\t\t%d\n",
 479			 ar->stats.fw_warm_reset_counter);
 480	len += scnprintf(buf + len, buf_len - len,
 481			 "fw_cold_reset_counter\t\t%d\n",
 482			 ar->stats.fw_cold_reset_counter);
 483
 484	spin_unlock_bh(&ar->data_lock);
 485
 486	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 487
 488	kfree(buf);
 489
 490	return ret;
 491}
 492
 493static const struct file_operations fops_fw_reset_stats = {
 494	.open = simple_open,
 495	.read = ath10k_debug_fw_reset_stats_read,
 496	.owner = THIS_MODULE,
 497	.llseek = default_llseek,
 498};
 499
 500/* This is a clean assert crash in firmware. */
 501static int ath10k_debug_fw_assert(struct ath10k *ar)
 502{
 503	struct wmi_vdev_install_key_cmd *cmd;
 504	struct sk_buff *skb;
 505
 506	skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16);
 507	if (!skb)
 508		return -ENOMEM;
 509
 510	cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
 511	memset(cmd, 0, sizeof(*cmd));
 512
 513	/* big enough number so that firmware asserts */
 514	cmd->vdev_id = __cpu_to_le32(0x7ffe);
 515
 516	return ath10k_wmi_cmd_send(ar, skb,
 517				   ar->wmi.cmd->vdev_install_key_cmdid);
 518}
 519
 520static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
 521					     char __user *user_buf,
 522					     size_t count, loff_t *ppos)
 523{
 524	const char buf[] =
 525		"To simulate firmware crash write one of the keywords to this file:\n"
 526		"`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n"
 527		"`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n"
 528		"`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n"
 529		"`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
 530
 531	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
 532}
 533
 534/* Simulate firmware crash:
 535 * 'soft': Call wmi command causing firmware hang. This firmware hang is
 536 * recoverable by warm firmware reset.
 537 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
 538 * vdev id. This is hard firmware crash because it is recoverable only by cold
 539 * firmware reset.
 540 */
 541static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
 542					      const char __user *user_buf,
 543					      size_t count, loff_t *ppos)
 544{
 545	struct ath10k *ar = file->private_data;
 546	char buf[32] = {0};
 547	ssize_t rc;
 548	int ret;
 549
 550	/* filter partial writes and invalid commands */
 551	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
 552		return -EINVAL;
 553
 554	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
 555	if (rc < 0)
 556		return rc;
 557
 558	/* drop the possible '\n' from the end */
 559	if (buf[*ppos - 1] == '\n')
 560		buf[*ppos - 1] = '\0';
 561
 562	mutex_lock(&ar->conf_mutex);
 563
 564	if (ar->state != ATH10K_STATE_ON &&
 565	    ar->state != ATH10K_STATE_RESTARTED) {
 566		ret = -ENETDOWN;
 567		goto exit;
 568	}
 569
 570	if (!strcmp(buf, "soft")) {
 571		ath10k_info(ar, "simulating soft firmware crash\n");
 572		ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
 573	} else if (!strcmp(buf, "hard")) {
 574		ath10k_info(ar, "simulating hard firmware crash\n");
 575		/* 0x7fff is vdev id, and it is always out of range for all
 576		 * firmware variants in order to force a firmware crash.
 577		 */
 578		ret = ath10k_wmi_vdev_set_param(ar, 0x7fff,
 579						ar->wmi.vdev_param->rts_threshold,
 580						0);
 581	} else if (!strcmp(buf, "assert")) {
 582		ath10k_info(ar, "simulating firmware assert crash\n");
 583		ret = ath10k_debug_fw_assert(ar);
 584	} else if (!strcmp(buf, "hw-restart")) {
 585		ath10k_info(ar, "user requested hw restart\n");
 586		ath10k_core_start_recovery(ar);
 587		ret = 0;
 588	} else {
 589		ret = -EINVAL;
 590		goto exit;
 591	}
 592
 593	if (ret) {
 594		ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret);
 595		goto exit;
 596	}
 597
 598	ret = count;
 599
 600exit:
 601	mutex_unlock(&ar->conf_mutex);
 602	return ret;
 603}
 604
 605static const struct file_operations fops_simulate_fw_crash = {
 606	.read = ath10k_read_simulate_fw_crash,
 607	.write = ath10k_write_simulate_fw_crash,
 608	.open = simple_open,
 609	.owner = THIS_MODULE,
 610	.llseek = default_llseek,
 611};
 612
 613static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf,
 614				   size_t count, loff_t *ppos)
 615{
 616	struct ath10k *ar = file->private_data;
 617	size_t len;
 618	char buf[50];
 619
 620	len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->bus_param.chip_id);
 621
 622	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 623}
 624
 625static const struct file_operations fops_chip_id = {
 626	.read = ath10k_read_chip_id,
 627	.open = simple_open,
 628	.owner = THIS_MODULE,
 629	.llseek = default_llseek,
 630};
 631
 632static ssize_t ath10k_reg_addr_read(struct file *file,
 633				    char __user *user_buf,
 634				    size_t count, loff_t *ppos)
 635{
 636	struct ath10k *ar = file->private_data;
 637	u8 buf[32];
 638	size_t len = 0;
 639	u32 reg_addr;
 640
 641	mutex_lock(&ar->conf_mutex);
 642	reg_addr = ar->debug.reg_addr;
 643	mutex_unlock(&ar->conf_mutex);
 644
 645	len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr);
 646
 647	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 648}
 649
 650static ssize_t ath10k_reg_addr_write(struct file *file,
 651				     const char __user *user_buf,
 652				     size_t count, loff_t *ppos)
 653{
 654	struct ath10k *ar = file->private_data;
 655	u32 reg_addr;
 656	int ret;
 657
 658	ret = kstrtou32_from_user(user_buf, count, 0, &reg_addr);
 659	if (ret)
 660		return ret;
 661
 662	if (!IS_ALIGNED(reg_addr, 4))
 663		return -EFAULT;
 664
 665	mutex_lock(&ar->conf_mutex);
 666	ar->debug.reg_addr = reg_addr;
 667	mutex_unlock(&ar->conf_mutex);
 668
 669	return count;
 670}
 671
 672static const struct file_operations fops_reg_addr = {
 673	.read = ath10k_reg_addr_read,
 674	.write = ath10k_reg_addr_write,
 675	.open = simple_open,
 676	.owner = THIS_MODULE,
 677	.llseek = default_llseek,
 678};
 679
 680static ssize_t ath10k_reg_value_read(struct file *file,
 681				     char __user *user_buf,
 682				     size_t count, loff_t *ppos)
 683{
 684	struct ath10k *ar = file->private_data;
 685	u8 buf[48];
 686	size_t len;
 687	u32 reg_addr, reg_val;
 688	int ret;
 689
 690	mutex_lock(&ar->conf_mutex);
 691
 692	if (ar->state != ATH10K_STATE_ON &&
 693	    ar->state != ATH10K_STATE_UTF) {
 694		ret = -ENETDOWN;
 695		goto exit;
 696	}
 697
 698	reg_addr = ar->debug.reg_addr;
 699
 700	reg_val = ath10k_hif_read32(ar, reg_addr);
 701	len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val);
 702
 703	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 704
 705exit:
 706	mutex_unlock(&ar->conf_mutex);
 707
 708	return ret;
 709}
 710
 711static ssize_t ath10k_reg_value_write(struct file *file,
 712				      const char __user *user_buf,
 713				      size_t count, loff_t *ppos)
 714{
 715	struct ath10k *ar = file->private_data;
 716	u32 reg_addr, reg_val;
 717	int ret;
 718
 719	mutex_lock(&ar->conf_mutex);
 720
 721	if (ar->state != ATH10K_STATE_ON &&
 722	    ar->state != ATH10K_STATE_UTF) {
 723		ret = -ENETDOWN;
 724		goto exit;
 725	}
 726
 727	reg_addr = ar->debug.reg_addr;
 728
 729	ret = kstrtou32_from_user(user_buf, count, 0, &reg_val);
 730	if (ret)
 731		goto exit;
 732
 733	ath10k_hif_write32(ar, reg_addr, reg_val);
 734
 735	ret = count;
 736
 737exit:
 738	mutex_unlock(&ar->conf_mutex);
 739
 740	return ret;
 741}
 742
 743static const struct file_operations fops_reg_value = {
 744	.read = ath10k_reg_value_read,
 745	.write = ath10k_reg_value_write,
 746	.open = simple_open,
 747	.owner = THIS_MODULE,
 748	.llseek = default_llseek,
 749};
 750
 751static ssize_t ath10k_mem_value_read(struct file *file,
 752				     char __user *user_buf,
 753				     size_t count, loff_t *ppos)
 754{
 755	struct ath10k *ar = file->private_data;
 756	u8 *buf;
 757	int ret;
 758
 759	if (*ppos < 0)
 760		return -EINVAL;
 761
 762	if (!count)
 763		return 0;
 764
 765	mutex_lock(&ar->conf_mutex);
 766
 767	buf = vmalloc(count);
 768	if (!buf) {
 769		ret = -ENOMEM;
 770		goto exit;
 771	}
 772
 773	if (ar->state != ATH10K_STATE_ON &&
 774	    ar->state != ATH10K_STATE_UTF) {
 775		ret = -ENETDOWN;
 776		goto exit;
 777	}
 778
 779	ret = ath10k_hif_diag_read(ar, *ppos, buf, count);
 780	if (ret) {
 781		ath10k_warn(ar, "failed to read address 0x%08x via diagnose window from debugfs: %d\n",
 782			    (u32)(*ppos), ret);
 783		goto exit;
 784	}
 785
 786	ret = copy_to_user(user_buf, buf, count);
 787	if (ret) {
 788		ret = -EFAULT;
 789		goto exit;
 790	}
 791
 792	count -= ret;
 793	*ppos += count;
 794	ret = count;
 795
 796exit:
 797	vfree(buf);
 798	mutex_unlock(&ar->conf_mutex);
 799
 800	return ret;
 801}
 802
 803static ssize_t ath10k_mem_value_write(struct file *file,
 804				      const char __user *user_buf,
 805				      size_t count, loff_t *ppos)
 806{
 807	struct ath10k *ar = file->private_data;
 808	u8 *buf;
 809	int ret;
 810
 811	if (*ppos < 0)
 812		return -EINVAL;
 813
 814	if (!count)
 815		return 0;
 816
 817	mutex_lock(&ar->conf_mutex);
 818
 819	buf = vmalloc(count);
 820	if (!buf) {
 821		ret = -ENOMEM;
 822		goto exit;
 823	}
 824
 825	if (ar->state != ATH10K_STATE_ON &&
 826	    ar->state != ATH10K_STATE_UTF) {
 827		ret = -ENETDOWN;
 828		goto exit;
 829	}
 830
 831	ret = copy_from_user(buf, user_buf, count);
 832	if (ret) {
 833		ret = -EFAULT;
 834		goto exit;
 835	}
 836
 837	ret = ath10k_hif_diag_write(ar, *ppos, buf, count);
 838	if (ret) {
 839		ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n",
 840			    (u32)(*ppos), ret);
 841		goto exit;
 842	}
 843
 844	*ppos += count;
 845	ret = count;
 846
 847exit:
 848	vfree(buf);
 849	mutex_unlock(&ar->conf_mutex);
 850
 851	return ret;
 852}
 853
 854static const struct file_operations fops_mem_value = {
 855	.read = ath10k_mem_value_read,
 856	.write = ath10k_mem_value_write,
 857	.open = simple_open,
 858	.owner = THIS_MODULE,
 859	.llseek = default_llseek,
 860};
 861
 862static int ath10k_debug_htt_stats_req(struct ath10k *ar)
 863{
 864	u64 cookie;
 865	int ret;
 866
 867	lockdep_assert_held(&ar->conf_mutex);
 868
 869	if (ar->debug.htt_stats_mask == 0)
 870		/* htt stats are disabled */
 871		return 0;
 872
 873	if (ar->state != ATH10K_STATE_ON)
 874		return 0;
 875
 876	cookie = get_jiffies_64();
 877
 878	ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask,
 879				       ar->debug.reset_htt_stats, cookie);
 880	if (ret) {
 881		ath10k_warn(ar, "failed to send htt stats request: %d\n", ret);
 882		return ret;
 883	}
 884
 885	queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork,
 886			   msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL));
 887
 888	return 0;
 889}
 890
 891static void ath10k_debug_htt_stats_dwork(struct work_struct *work)
 892{
 893	struct ath10k *ar = container_of(work, struct ath10k,
 894					 debug.htt_stats_dwork.work);
 895
 896	mutex_lock(&ar->conf_mutex);
 897
 898	ath10k_debug_htt_stats_req(ar);
 899
 900	mutex_unlock(&ar->conf_mutex);
 901}
 902
 903static ssize_t ath10k_read_htt_stats_mask(struct file *file,
 904					  char __user *user_buf,
 905					  size_t count, loff_t *ppos)
 906{
 907	struct ath10k *ar = file->private_data;
 908	char buf[32];
 909	size_t len;
 910
 911	len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask);
 912
 913	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 914}
 915
 916static ssize_t ath10k_write_htt_stats_mask(struct file *file,
 917					   const char __user *user_buf,
 918					   size_t count, loff_t *ppos)
 919{
 920	struct ath10k *ar = file->private_data;
 921	unsigned long mask;
 922	int ret;
 923
 924	ret = kstrtoul_from_user(user_buf, count, 0, &mask);
 925	if (ret)
 926		return ret;
 927
 928	/* max 17 bit masks (for now) */
 929	if (mask > HTT_STATS_BIT_MASK)
 930		return -E2BIG;
 931
 932	mutex_lock(&ar->conf_mutex);
 933
 934	ar->debug.htt_stats_mask = mask;
 935
 936	ret = ath10k_debug_htt_stats_req(ar);
 937	if (ret)
 938		goto out;
 939
 940	ret = count;
 941
 942out:
 943	mutex_unlock(&ar->conf_mutex);
 944
 945	return ret;
 946}
 947
 948static const struct file_operations fops_htt_stats_mask = {
 949	.read = ath10k_read_htt_stats_mask,
 950	.write = ath10k_write_htt_stats_mask,
 951	.open = simple_open,
 952	.owner = THIS_MODULE,
 953	.llseek = default_llseek,
 954};
 955
 956static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
 957					       char __user *user_buf,
 958					       size_t count, loff_t *ppos)
 959{
 960	struct ath10k *ar = file->private_data;
 961	char buf[64];
 962	u8 amsdu, ampdu;
 963	size_t len;
 964
 965	mutex_lock(&ar->conf_mutex);
 966
 967	amsdu = ar->htt.max_num_amsdu;
 968	ampdu = ar->htt.max_num_ampdu;
 969	mutex_unlock(&ar->conf_mutex);
 970
 971	len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
 972
 973	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 974}
 975
 976static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
 977						const char __user *user_buf,
 978						size_t count, loff_t *ppos)
 979{
 980	struct ath10k *ar = file->private_data;
 981	int res;
 982	char buf[64] = {0};
 983	unsigned int amsdu, ampdu;
 984
 985	res = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
 986				     user_buf, count);
 987	if (res <= 0)
 988		return res;
 989
 990	res = sscanf(buf, "%u %u", &amsdu, &ampdu);
 991
 992	if (res != 2)
 993		return -EINVAL;
 994
 995	mutex_lock(&ar->conf_mutex);
 996
 997	res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
 998	if (res)
 999		goto out;
1000
1001	res = count;
1002	ar->htt.max_num_amsdu = amsdu;
1003	ar->htt.max_num_ampdu = ampdu;
1004
1005out:
1006	mutex_unlock(&ar->conf_mutex);
1007	return res;
1008}
1009
1010static const struct file_operations fops_htt_max_amsdu_ampdu = {
1011	.read = ath10k_read_htt_max_amsdu_ampdu,
1012	.write = ath10k_write_htt_max_amsdu_ampdu,
1013	.open = simple_open,
1014	.owner = THIS_MODULE,
1015	.llseek = default_llseek,
1016};
1017
1018static ssize_t ath10k_read_fw_dbglog(struct file *file,
1019				     char __user *user_buf,
1020				     size_t count, loff_t *ppos)
1021{
1022	struct ath10k *ar = file->private_data;
1023	size_t len;
1024	char buf[96];
1025
1026	len = scnprintf(buf, sizeof(buf), "0x%16llx %u\n",
1027			ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level);
1028
1029	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1030}
1031
1032static ssize_t ath10k_write_fw_dbglog(struct file *file,
1033				      const char __user *user_buf,
1034				      size_t count, loff_t *ppos)
1035{
1036	struct ath10k *ar = file->private_data;
1037	int ret;
1038	char buf[96] = {0};
1039	unsigned int log_level;
1040	u64 mask;
1041
1042	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
1043				     user_buf, count);
1044	if (ret <= 0)
1045		return ret;
1046
1047	ret = sscanf(buf, "%llx %u", &mask, &log_level);
1048
1049	if (!ret)
1050		return -EINVAL;
1051
1052	if (ret == 1)
1053		/* default if user did not specify */
1054		log_level = ATH10K_DBGLOG_LEVEL_WARN;
1055
1056	mutex_lock(&ar->conf_mutex);
1057
1058	ar->debug.fw_dbglog_mask = mask;
1059	ar->debug.fw_dbglog_level = log_level;
1060
1061	if (ar->state == ATH10K_STATE_ON) {
1062		ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1063					    ar->debug.fw_dbglog_level);
1064		if (ret) {
1065			ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n",
1066				    ret);
1067			goto exit;
1068		}
1069	}
1070
1071	ret = count;
1072
1073exit:
1074	mutex_unlock(&ar->conf_mutex);
1075
1076	return ret;
1077}
1078
1079/* TODO:  Would be nice to always support ethtool stats, would need to
1080 * move the stats storage out of ath10k_debug, or always have ath10k_debug
1081 * struct available..
1082 */
1083
1084/* This generally cooresponds to the debugfs fw_stats file */
1085static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = {
1086	"tx_pkts_nic",
1087	"tx_bytes_nic",
1088	"rx_pkts_nic",
1089	"rx_bytes_nic",
1090	"d_noise_floor",
1091	"d_cycle_count",
1092	"d_phy_error",
1093	"d_rts_bad",
1094	"d_rts_good",
1095	"d_tx_power", /* in .5 dbM I think */
1096	"d_rx_crc_err", /* fcs_bad */
1097	"d_rx_crc_err_drop", /* frame with FCS error, dropped late in kernel */
1098	"d_no_beacon",
1099	"d_tx_mpdus_queued",
1100	"d_tx_msdu_queued",
1101	"d_tx_msdu_dropped",
1102	"d_local_enqued",
1103	"d_local_freed",
1104	"d_tx_ppdu_hw_queued",
1105	"d_tx_ppdu_reaped",
1106	"d_tx_fifo_underrun",
1107	"d_tx_ppdu_abort",
1108	"d_tx_mpdu_requeued",
1109	"d_tx_excessive_retries",
1110	"d_tx_hw_rate",
1111	"d_tx_dropped_sw_retries",
1112	"d_tx_illegal_rate",
1113	"d_tx_continuous_xretries",
1114	"d_tx_timeout",
1115	"d_tx_mpdu_txop_limit",
1116	"d_pdev_resets",
1117	"d_rx_mid_ppdu_route_change",
1118	"d_rx_status",
1119	"d_rx_extra_frags_ring0",
1120	"d_rx_extra_frags_ring1",
1121	"d_rx_extra_frags_ring2",
1122	"d_rx_extra_frags_ring3",
1123	"d_rx_msdu_htt",
1124	"d_rx_mpdu_htt",
1125	"d_rx_msdu_stack",
1126	"d_rx_mpdu_stack",
1127	"d_rx_phy_err",
1128	"d_rx_phy_err_drops",
1129	"d_rx_mpdu_errors", /* FCS, MIC, ENC */
1130	"d_fw_crash_count",
1131	"d_fw_warm_reset_count",
1132	"d_fw_cold_reset_count",
1133};
1134
1135#define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats)
1136
1137void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
1138				 struct ieee80211_vif *vif,
1139				 u32 sset, u8 *data)
1140{
1141	if (sset == ETH_SS_STATS)
1142		memcpy(data, *ath10k_gstrings_stats,
1143		       sizeof(ath10k_gstrings_stats));
1144}
1145
1146int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw,
1147				   struct ieee80211_vif *vif, int sset)
1148{
1149	if (sset == ETH_SS_STATS)
1150		return ATH10K_SSTATS_LEN;
1151
1152	return 0;
1153}
1154
1155void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
1156			       struct ieee80211_vif *vif,
1157			       struct ethtool_stats *stats, u64 *data)
1158{
1159	struct ath10k *ar = hw->priv;
1160	static const struct ath10k_fw_stats_pdev zero_stats = {};
1161	const struct ath10k_fw_stats_pdev *pdev_stats;
1162	int i = 0, ret;
1163
1164	mutex_lock(&ar->conf_mutex);
1165
1166	if (ar->state == ATH10K_STATE_ON) {
1167		ret = ath10k_debug_fw_stats_request(ar);
1168		if (ret) {
1169			/* just print a warning and try to use older results */
1170			ath10k_warn(ar,
1171				    "failed to get fw stats for ethtool: %d\n",
1172				    ret);
1173		}
1174	}
1175
1176	pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs,
1177					      struct ath10k_fw_stats_pdev,
1178					      list);
1179	if (!pdev_stats) {
1180		/* no results available so just return zeroes */
1181		pdev_stats = &zero_stats;
1182	}
1183
1184	spin_lock_bh(&ar->data_lock);
1185
1186	data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */
1187	data[i++] = 0; /* tx bytes */
1188	data[i++] = pdev_stats->htt_mpdus;
1189	data[i++] = 0; /* rx bytes */
1190	data[i++] = pdev_stats->ch_noise_floor;
1191	data[i++] = pdev_stats->cycle_count;
1192	data[i++] = pdev_stats->phy_err_count;
1193	data[i++] = pdev_stats->rts_bad;
1194	data[i++] = pdev_stats->rts_good;
1195	data[i++] = pdev_stats->chan_tx_power;
1196	data[i++] = pdev_stats->fcs_bad;
1197	data[i++] = ar->stats.rx_crc_err_drop;
1198	data[i++] = pdev_stats->no_beacons;
1199	data[i++] = pdev_stats->mpdu_enqued;
1200	data[i++] = pdev_stats->msdu_enqued;
1201	data[i++] = pdev_stats->wmm_drop;
1202	data[i++] = pdev_stats->local_enqued;
1203	data[i++] = pdev_stats->local_freed;
1204	data[i++] = pdev_stats->hw_queued;
1205	data[i++] = pdev_stats->hw_reaped;
1206	data[i++] = pdev_stats->underrun;
1207	data[i++] = pdev_stats->tx_abort;
1208	data[i++] = pdev_stats->mpdus_requeued;
1209	data[i++] = pdev_stats->tx_ko;
1210	data[i++] = pdev_stats->data_rc;
1211	data[i++] = pdev_stats->sw_retry_failure;
1212	data[i++] = pdev_stats->illgl_rate_phy_err;
1213	data[i++] = pdev_stats->pdev_cont_xretry;
1214	data[i++] = pdev_stats->pdev_tx_timeout;
1215	data[i++] = pdev_stats->txop_ovf;
1216	data[i++] = pdev_stats->pdev_resets;
1217	data[i++] = pdev_stats->mid_ppdu_route_change;
1218	data[i++] = pdev_stats->status_rcvd;
1219	data[i++] = pdev_stats->r0_frags;
1220	data[i++] = pdev_stats->r1_frags;
1221	data[i++] = pdev_stats->r2_frags;
1222	data[i++] = pdev_stats->r3_frags;
1223	data[i++] = pdev_stats->htt_msdus;
1224	data[i++] = pdev_stats->htt_mpdus;
1225	data[i++] = pdev_stats->loc_msdus;
1226	data[i++] = pdev_stats->loc_mpdus;
1227	data[i++] = pdev_stats->phy_errs;
1228	data[i++] = pdev_stats->phy_err_drop;
1229	data[i++] = pdev_stats->mpdu_errs;
1230	data[i++] = ar->stats.fw_crash_counter;
1231	data[i++] = ar->stats.fw_warm_reset_counter;
1232	data[i++] = ar->stats.fw_cold_reset_counter;
1233
1234	spin_unlock_bh(&ar->data_lock);
1235
1236	mutex_unlock(&ar->conf_mutex);
1237
1238	WARN_ON(i != ATH10K_SSTATS_LEN);
1239}
1240
1241static const struct file_operations fops_fw_dbglog = {
1242	.read = ath10k_read_fw_dbglog,
1243	.write = ath10k_write_fw_dbglog,
1244	.open = simple_open,
1245	.owner = THIS_MODULE,
1246	.llseek = default_llseek,
1247};
1248
1249static int ath10k_debug_cal_data_fetch(struct ath10k *ar)
1250{
1251	u32 hi_addr;
1252	__le32 addr;
1253	int ret;
1254
1255	lockdep_assert_held(&ar->conf_mutex);
1256
1257	if (WARN_ON(ar->hw_params.cal_data_len > ATH10K_DEBUG_CAL_DATA_LEN))
1258		return -EINVAL;
1259
1260	if (ar->hw_params.cal_data_len == 0)
1261		return -EOPNOTSUPP;
1262
1263	hi_addr = host_interest_item_address(HI_ITEM(hi_board_data));
1264
1265	ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr));
1266	if (ret) {
1267		ath10k_warn(ar, "failed to read hi_board_data address: %d\n",
1268			    ret);
1269		return ret;
1270	}
1271
1272	ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), ar->debug.cal_data,
1273				   ar->hw_params.cal_data_len);
1274	if (ret) {
1275		ath10k_warn(ar, "failed to read calibration data: %d\n", ret);
1276		return ret;
1277	}
1278
1279	return 0;
1280}
1281
1282static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
1283{
1284	struct ath10k *ar = inode->i_private;
1285
1286	mutex_lock(&ar->conf_mutex);
1287
1288	if (ar->state == ATH10K_STATE_ON ||
1289	    ar->state == ATH10K_STATE_UTF) {
1290		ath10k_debug_cal_data_fetch(ar);
1291	}
1292
1293	file->private_data = ar;
1294	mutex_unlock(&ar->conf_mutex);
1295
1296	return 0;
1297}
1298
1299static ssize_t ath10k_debug_cal_data_read(struct file *file,
1300					  char __user *user_buf,
1301					  size_t count, loff_t *ppos)
1302{
1303	struct ath10k *ar = file->private_data;
1304
1305	mutex_lock(&ar->conf_mutex);
1306
1307	count = simple_read_from_buffer(user_buf, count, ppos,
1308					ar->debug.cal_data,
1309					ar->hw_params.cal_data_len);
1310
1311	mutex_unlock(&ar->conf_mutex);
1312
1313	return count;
1314}
1315
1316static ssize_t ath10k_write_ani_enable(struct file *file,
1317				       const char __user *user_buf,
1318				       size_t count, loff_t *ppos)
1319{
1320	struct ath10k *ar = file->private_data;
1321	int ret;
1322	u8 enable;
1323
1324	if (kstrtou8_from_user(user_buf, count, 0, &enable))
1325		return -EINVAL;
1326
1327	mutex_lock(&ar->conf_mutex);
1328
1329	if (ar->ani_enabled == enable) {
1330		ret = count;
1331		goto exit;
1332	}
1333
1334	ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->ani_enable,
1335					enable);
1336	if (ret) {
1337		ath10k_warn(ar, "ani_enable failed from debugfs: %d\n", ret);
1338		goto exit;
1339	}
1340	ar->ani_enabled = enable;
1341
1342	ret = count;
1343
1344exit:
1345	mutex_unlock(&ar->conf_mutex);
1346
1347	return ret;
1348}
1349
1350static ssize_t ath10k_read_ani_enable(struct file *file, char __user *user_buf,
1351				      size_t count, loff_t *ppos)
1352{
1353	struct ath10k *ar = file->private_data;
1354	size_t len;
1355	char buf[32];
1356
1357	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ani_enabled);
1358
1359	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1360}
1361
1362static const struct file_operations fops_ani_enable = {
1363	.read = ath10k_read_ani_enable,
1364	.write = ath10k_write_ani_enable,
1365	.open = simple_open,
1366	.owner = THIS_MODULE,
1367	.llseek = default_llseek,
1368};
1369
1370static const struct file_operations fops_cal_data = {
1371	.open = ath10k_debug_cal_data_open,
1372	.read = ath10k_debug_cal_data_read,
1373	.owner = THIS_MODULE,
1374	.llseek = default_llseek,
1375};
1376
1377static ssize_t ath10k_read_nf_cal_period(struct file *file,
1378					 char __user *user_buf,
1379					 size_t count, loff_t *ppos)
1380{
1381	struct ath10k *ar = file->private_data;
1382	size_t len;
1383	char buf[32];
1384
1385	len = scnprintf(buf, sizeof(buf), "%d\n", ar->debug.nf_cal_period);
1386
1387	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1388}
1389
1390static ssize_t ath10k_write_nf_cal_period(struct file *file,
1391					  const char __user *user_buf,
1392					  size_t count, loff_t *ppos)
1393{
1394	struct ath10k *ar = file->private_data;
1395	unsigned long period;
1396	int ret;
1397
1398	ret = kstrtoul_from_user(user_buf, count, 0, &period);
1399	if (ret)
1400		return ret;
1401
1402	if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX)
1403		return -EINVAL;
1404
1405	/* there's no way to switch back to the firmware default */
1406	if (period == 0)
1407		return -EINVAL;
1408
1409	mutex_lock(&ar->conf_mutex);
1410
1411	ar->debug.nf_cal_period = period;
1412
1413	if (ar->state != ATH10K_STATE_ON) {
1414		/* firmware is not running, nothing else to do */
1415		ret = count;
1416		goto exit;
1417	}
1418
1419	ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period,
1420					ar->debug.nf_cal_period);
1421	if (ret) {
1422		ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n",
1423			    ret);
1424		goto exit;
1425	}
1426
1427	ret = count;
1428
1429exit:
1430	mutex_unlock(&ar->conf_mutex);
1431
1432	return ret;
1433}
1434
1435static const struct file_operations fops_nf_cal_period = {
1436	.read = ath10k_read_nf_cal_period,
1437	.write = ath10k_write_nf_cal_period,
1438	.open = simple_open,
1439	.owner = THIS_MODULE,
1440	.llseek = default_llseek,
1441};
1442
1443#define ATH10K_TPC_CONFIG_BUF_SIZE	(1024 * 1024)
1444
1445static int ath10k_debug_tpc_stats_request(struct ath10k *ar)
1446{
1447	int ret;
1448	unsigned long time_left;
1449
1450	lockdep_assert_held(&ar->conf_mutex);
1451
1452	reinit_completion(&ar->debug.tpc_complete);
1453
1454	ret = ath10k_wmi_pdev_get_tpc_config(ar, WMI_TPC_CONFIG_PARAM);
1455	if (ret) {
1456		ath10k_warn(ar, "failed to request tpc config: %d\n", ret);
1457		return ret;
1458	}
1459
1460	time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
1461						1 * HZ);
1462	if (time_left == 0)
1463		return -ETIMEDOUT;
1464
1465	return 0;
1466}
1467
1468void ath10k_debug_tpc_stats_process(struct ath10k *ar,
1469				    struct ath10k_tpc_stats *tpc_stats)
1470{
1471	spin_lock_bh(&ar->data_lock);
1472
1473	kfree(ar->debug.tpc_stats);
1474	ar->debug.tpc_stats = tpc_stats;
1475	complete(&ar->debug.tpc_complete);
1476
1477	spin_unlock_bh(&ar->data_lock);
1478}
1479
1480void
1481ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
1482				     struct ath10k_tpc_stats_final *tpc_stats)
1483{
1484	spin_lock_bh(&ar->data_lock);
1485
1486	kfree(ar->debug.tpc_stats_final);
1487	ar->debug.tpc_stats_final = tpc_stats;
1488	complete(&ar->debug.tpc_complete);
1489
1490	spin_unlock_bh(&ar->data_lock);
1491}
1492
1493static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
1494				   unsigned int j, char *buf, size_t *len)
1495{
1496	int i;
1497	size_t buf_len;
1498	static const char table_str[][5] = { "CDD",
1499					     "STBC",
1500					     "TXBF" };
1501	static const char pream_str[][6] = { "CCK",
1502					     "OFDM",
1503					     "HT20",
1504					     "HT40",
1505					     "VHT20",
1506					     "VHT40",
1507					     "VHT80",
1508					     "HTCUP" };
1509
1510	buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1511	*len += scnprintf(buf + *len, buf_len - *len,
1512			  "********************************\n");
1513	*len += scnprintf(buf + *len, buf_len - *len,
1514			  "******************* %s POWER TABLE ****************\n",
1515			  table_str[j]);
1516	*len += scnprintf(buf + *len, buf_len - *len,
1517			  "********************************\n");
1518	*len += scnprintf(buf + *len, buf_len - *len,
1519			  "No.  Preamble Rate_code ");
1520
1521	for (i = 0; i < tpc_stats->num_tx_chain; i++)
1522		*len += scnprintf(buf + *len, buf_len - *len,
1523				  "tpc_value%d ", i);
1524
1525	*len += scnprintf(buf + *len, buf_len - *len, "\n");
1526
1527	for (i = 0; i < tpc_stats->rate_max; i++) {
1528		*len += scnprintf(buf + *len, buf_len - *len,
1529				  "%8d %s 0x%2x %s\n", i,
1530				  pream_str[tpc_stats->tpc_table[j].pream_idx[i]],
1531				  tpc_stats->tpc_table[j].rate_code[i],
1532				  tpc_stats->tpc_table[j].tpc_value[i]);
1533	}
1534
1535	*len += scnprintf(buf + *len, buf_len - *len,
1536			  "***********************************\n");
1537}
1538
1539static void ath10k_tpc_stats_fill(struct ath10k *ar,
1540				  struct ath10k_tpc_stats *tpc_stats,
1541				  char *buf)
1542{
1543	int j;
1544	size_t len, buf_len;
1545
1546	len = 0;
1547	buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1548
1549	spin_lock_bh(&ar->data_lock);
1550
1551	if (!tpc_stats) {
1552		ath10k_warn(ar, "failed to get tpc stats\n");
1553		goto unlock;
1554	}
1555
1556	len += scnprintf(buf + len, buf_len - len, "\n");
1557	len += scnprintf(buf + len, buf_len - len,
1558			 "*************************************\n");
1559	len += scnprintf(buf + len, buf_len - len,
1560			 "TPC config for channel %4d mode %d\n",
1561			 tpc_stats->chan_freq,
1562			 tpc_stats->phy_mode);
1563	len += scnprintf(buf + len, buf_len - len,
1564			 "*************************************\n");
1565	len += scnprintf(buf + len, buf_len - len,
1566			 "CTL		=  0x%2x Reg. Domain		= %2d\n",
1567			 tpc_stats->ctl,
1568			 tpc_stats->reg_domain);
1569	len += scnprintf(buf + len, buf_len - len,
1570			 "Antenna Gain	= %2d Reg. Max Antenna Gain	=  %2d\n",
1571			 tpc_stats->twice_antenna_gain,
1572			 tpc_stats->twice_antenna_reduction);
1573	len += scnprintf(buf + len, buf_len - len,
1574			 "Power Limit	= %2d Reg. Max Power		= %2d\n",
1575			 tpc_stats->power_limit,
1576			 tpc_stats->twice_max_rd_power / 2);
1577	len += scnprintf(buf + len, buf_len - len,
1578			 "Num tx chains	= %2d Num supported rates	= %2d\n",
1579			 tpc_stats->num_tx_chain,
1580			 tpc_stats->rate_max);
1581
1582	for (j = 0; j < WMI_TPC_FLAG; j++) {
1583		switch (j) {
1584		case WMI_TPC_TABLE_TYPE_CDD:
1585			if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1586				len += scnprintf(buf + len, buf_len - len,
1587						 "CDD not supported\n");
1588				break;
1589			}
1590
1591			ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1592			break;
1593		case WMI_TPC_TABLE_TYPE_STBC:
1594			if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1595				len += scnprintf(buf + len, buf_len - len,
1596						 "STBC not supported\n");
1597				break;
1598			}
1599
1600			ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1601			break;
1602		case WMI_TPC_TABLE_TYPE_TXBF:
1603			if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1604				len += scnprintf(buf + len, buf_len - len,
1605						 "TXBF not supported\n***************************\n");
1606				break;
1607			}
1608
1609			ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1610			break;
1611		default:
1612			len += scnprintf(buf + len, buf_len - len,
1613					 "Invalid Type\n");
1614			break;
1615		}
1616	}
1617
1618unlock:
1619	spin_unlock_bh(&ar->data_lock);
1620
1621	if (len >= buf_len)
1622		buf[len - 1] = 0;
1623	else
1624		buf[len] = 0;
1625}
1626
1627static int ath10k_tpc_stats_open(struct inode *inode, struct file *file)
1628{
1629	struct ath10k *ar = inode->i_private;
1630	void *buf = NULL;
1631	int ret;
1632
1633	mutex_lock(&ar->conf_mutex);
1634
1635	if (ar->state != ATH10K_STATE_ON) {
1636		ret = -ENETDOWN;
1637		goto err_unlock;
1638	}
1639
1640	buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
1641	if (!buf) {
1642		ret = -ENOMEM;
1643		goto err_unlock;
1644	}
1645
1646	ret = ath10k_debug_tpc_stats_request(ar);
1647	if (ret) {
1648		ath10k_warn(ar, "failed to request tpc config stats: %d\n",
1649			    ret);
1650		goto err_free;
1651	}
1652
1653	ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
1654	file->private_data = buf;
1655
1656	mutex_unlock(&ar->conf_mutex);
1657	return 0;
1658
1659err_free:
1660	vfree(buf);
1661
1662err_unlock:
1663	mutex_unlock(&ar->conf_mutex);
1664	return ret;
1665}
1666
1667static int ath10k_tpc_stats_release(struct inode *inode, struct file *file)
1668{
1669	vfree(file->private_data);
1670
1671	return 0;
1672}
1673
1674static ssize_t ath10k_tpc_stats_read(struct file *file, char __user *user_buf,
1675				     size_t count, loff_t *ppos)
1676{
1677	const char *buf = file->private_data;
1678	size_t len = strlen(buf);
1679
1680	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1681}
1682
1683static const struct file_operations fops_tpc_stats = {
1684	.open = ath10k_tpc_stats_open,
1685	.release = ath10k_tpc_stats_release,
1686	.read = ath10k_tpc_stats_read,
1687	.owner = THIS_MODULE,
1688	.llseek = default_llseek,
1689};
1690
1691int ath10k_debug_start(struct ath10k *ar)
1692{
1693	int ret;
1694
1695	lockdep_assert_held(&ar->conf_mutex);
1696
1697	ret = ath10k_debug_htt_stats_req(ar);
1698	if (ret)
1699		/* continue normally anyway, this isn't serious */
1700		ath10k_warn(ar, "failed to start htt stats workqueue: %d\n",
1701			    ret);
1702
1703	if (ar->debug.fw_dbglog_mask) {
1704		ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1705					    ATH10K_DBGLOG_LEVEL_WARN);
1706		if (ret)
1707			/* not serious */
1708			ath10k_warn(ar, "failed to enable dbglog during start: %d",
1709				    ret);
1710	}
1711
1712	if (ar->pktlog_filter) {
1713		ret = ath10k_wmi_pdev_pktlog_enable(ar,
1714						    ar->pktlog_filter);
1715		if (ret)
1716			/* not serious */
1717			ath10k_warn(ar,
1718				    "failed to enable pktlog filter %x: %d\n",
1719				    ar->pktlog_filter, ret);
1720	} else {
1721		ret = ath10k_wmi_pdev_pktlog_disable(ar);
1722		if (ret)
1723			/* not serious */
1724			ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1725	}
1726
1727	if (ar->debug.nf_cal_period &&
1728	    !test_bit(ATH10K_FW_FEATURE_NON_BMI,
1729		      ar->normal_mode_fw.fw_file.fw_features)) {
1730		ret = ath10k_wmi_pdev_set_param(ar,
1731						ar->wmi.pdev_param->cal_period,
1732						ar->debug.nf_cal_period);
1733		if (ret)
1734			/* not serious */
1735			ath10k_warn(ar, "cal period cfg failed from debug start: %d\n",
1736				    ret);
1737	}
1738
1739	return ret;
1740}
1741
1742void ath10k_debug_stop(struct ath10k *ar)
1743{
1744	lockdep_assert_held(&ar->conf_mutex);
1745
1746	if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
1747		      ar->normal_mode_fw.fw_file.fw_features))
1748		ath10k_debug_cal_data_fetch(ar);
1749
1750	/* Must not use _sync to avoid deadlock, we do that in
1751	 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
1752	 * warning from del_timer().
1753	 */
1754	if (ar->debug.htt_stats_mask != 0)
1755		cancel_delayed_work(&ar->debug.htt_stats_dwork);
1756
1757	ath10k_wmi_pdev_pktlog_disable(ar);
1758}
1759
1760static ssize_t ath10k_write_simulate_radar(struct file *file,
1761					   const char __user *user_buf,
1762					   size_t count, loff_t *ppos)
1763{
1764	struct ath10k *ar = file->private_data;
1765	struct ath10k_vif *arvif;
1766
1767	/* Just check for the first vif alone, as all the vifs will be
1768	 * sharing the same channel and if the channel is disabled, all the
1769	 * vifs will share the same 'is_started' state.
1770	 */
1771	arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list);
1772	if (!arvif->is_started)
1773		return -EINVAL;
1774
1775	ieee80211_radar_detected(ar->hw);
1776
1777	return count;
1778}
1779
1780static const struct file_operations fops_simulate_radar = {
1781	.write = ath10k_write_simulate_radar,
1782	.open = simple_open,
1783	.owner = THIS_MODULE,
1784	.llseek = default_llseek,
1785};
1786
1787#define ATH10K_DFS_STAT(s, p) (\
1788	len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1789			 ar->debug.dfs_stats.p))
1790
1791#define ATH10K_DFS_POOL_STAT(s, p) (\
1792	len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1793			 ar->debug.dfs_pool_stats.p))
1794
1795static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf,
1796				     size_t count, loff_t *ppos)
1797{
1798	int retval = 0, len = 0;
1799	const int size = 8000;
1800	struct ath10k *ar = file->private_data;
1801	char *buf;
1802
1803	buf = kzalloc(size, GFP_KERNEL);
1804	if (buf == NULL)
1805		return -ENOMEM;
1806
1807	if (!ar->dfs_detector) {
1808		len += scnprintf(buf + len, size - len, "DFS not enabled\n");
1809		goto exit;
1810	}
1811
1812	ar->debug.dfs_pool_stats =
1813			ar->dfs_detector->get_stats(ar->dfs_detector);
1814
1815	len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n");
1816
1817	ATH10K_DFS_STAT("reported phy errors", phy_errors);
1818	ATH10K_DFS_STAT("pulse events reported", pulses_total);
1819	ATH10K_DFS_STAT("DFS pulses detected", pulses_detected);
1820	ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded);
1821	ATH10K_DFS_STAT("Radars detected", radar_detected);
1822
1823	len += scnprintf(buf + len, size - len, "Global Pool statistics:\n");
1824	ATH10K_DFS_POOL_STAT("Pool references", pool_reference);
1825	ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated);
1826	ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error);
1827	ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used);
1828	ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated);
1829	ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error);
1830	ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used);
1831
1832exit:
1833	if (len > size)
1834		len = size;
1835
1836	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1837	kfree(buf);
1838
1839	return retval;
1840}
1841
1842static const struct file_operations fops_dfs_stats = {
1843	.read = ath10k_read_dfs_stats,
1844	.open = simple_open,
1845	.owner = THIS_MODULE,
1846	.llseek = default_llseek,
1847};
1848
1849static ssize_t ath10k_write_pktlog_filter(struct file *file,
1850					  const char __user *ubuf,
1851					  size_t count, loff_t *ppos)
1852{
1853	struct ath10k *ar = file->private_data;
1854	u32 filter;
1855	int ret;
1856
1857	if (kstrtouint_from_user(ubuf, count, 0, &filter))
1858		return -EINVAL;
1859
1860	mutex_lock(&ar->conf_mutex);
1861
1862	if (ar->state != ATH10K_STATE_ON) {
1863		ar->pktlog_filter = filter;
1864		ret = count;
1865		goto out;
1866	}
1867
1868	if (filter == ar->pktlog_filter) {
1869		ret = count;
1870		goto out;
1871	}
1872
1873	if (filter) {
1874		ret = ath10k_wmi_pdev_pktlog_enable(ar, filter);
1875		if (ret) {
1876			ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n",
1877				    ar->pktlog_filter, ret);
1878			goto out;
1879		}
1880	} else {
1881		ret = ath10k_wmi_pdev_pktlog_disable(ar);
1882		if (ret) {
1883			ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1884			goto out;
1885		}
1886	}
1887
1888	ar->pktlog_filter = filter;
1889	ret = count;
1890
1891out:
1892	mutex_unlock(&ar->conf_mutex);
1893	return ret;
1894}
1895
1896static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf,
1897					 size_t count, loff_t *ppos)
1898{
1899	char buf[32];
1900	struct ath10k *ar = file->private_data;
1901	int len = 0;
1902
1903	mutex_lock(&ar->conf_mutex);
1904	len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
1905			ar->pktlog_filter);
1906	mutex_unlock(&ar->conf_mutex);
1907
1908	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1909}
1910
1911static const struct file_operations fops_pktlog_filter = {
1912	.read = ath10k_read_pktlog_filter,
1913	.write = ath10k_write_pktlog_filter,
1914	.open = simple_open
1915};
1916
1917static ssize_t ath10k_write_quiet_period(struct file *file,
1918					 const char __user *ubuf,
1919					 size_t count, loff_t *ppos)
1920{
1921	struct ath10k *ar = file->private_data;
1922	u32 period;
1923
1924	if (kstrtouint_from_user(ubuf, count, 0, &period))
1925		return -EINVAL;
1926
1927	if (period < ATH10K_QUIET_PERIOD_MIN) {
1928		ath10k_warn(ar, "Quiet period %u can not be lesser than 25ms\n",
1929			    period);
1930		return -EINVAL;
1931	}
1932	mutex_lock(&ar->conf_mutex);
1933	ar->thermal.quiet_period = period;
1934	ath10k_thermal_set_throttling(ar);
1935	mutex_unlock(&ar->conf_mutex);
1936
1937	return count;
1938}
1939
1940static ssize_t ath10k_read_quiet_period(struct file *file, char __user *ubuf,
1941					size_t count, loff_t *ppos)
1942{
1943	char buf[32];
1944	struct ath10k *ar = file->private_data;
1945	int len = 0;
1946
1947	mutex_lock(&ar->conf_mutex);
1948	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
1949			ar->thermal.quiet_period);
1950	mutex_unlock(&ar->conf_mutex);
1951
1952	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1953}
1954
1955static const struct file_operations fops_quiet_period = {
1956	.read = ath10k_read_quiet_period,
1957	.write = ath10k_write_quiet_period,
1958	.open = simple_open
1959};
1960
1961static ssize_t ath10k_write_btcoex(struct file *file,
1962				   const char __user *ubuf,
1963				   size_t count, loff_t *ppos)
1964{
1965	struct ath10k *ar = file->private_data;
1966	char buf[32];
1967	size_t buf_size;
1968	int ret;
1969	bool val;
1970	u32 pdev_param;
1971
1972	buf_size = min(count, (sizeof(buf) - 1));
1973	if (copy_from_user(buf, ubuf, buf_size))
1974		return -EFAULT;
1975
1976	buf[buf_size] = '\0';
1977
1978	if (strtobool(buf, &val) != 0)
1979		return -EINVAL;
1980
1981	if (!ar->coex_support)
1982		return -EOPNOTSUPP;
1983
1984	mutex_lock(&ar->conf_mutex);
1985
1986	if (ar->state != ATH10K_STATE_ON &&
1987	    ar->state != ATH10K_STATE_RESTARTED) {
1988		ret = -ENETDOWN;
1989		goto exit;
1990	}
1991
1992	if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) {
1993		ret = count;
1994		goto exit;
1995	}
1996
1997	pdev_param = ar->wmi.pdev_param->enable_btcoex;
1998	if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
1999		     ar->running_fw->fw_file.fw_features)) {
2000		ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
2001		if (ret) {
2002			ath10k_warn(ar, "failed to enable btcoex: %d\n", ret);
2003			ret = count;
2004			goto exit;
2005		}
2006	} else {
2007		ath10k_info(ar, "restarting firmware due to btcoex change");
2008		ath10k_core_start_recovery(ar);
2009	}
2010
2011	if (val)
2012		set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2013	else
2014		clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2015
2016	ret = count;
2017
2018exit:
2019	mutex_unlock(&ar->conf_mutex);
2020
2021	return ret;
2022}
2023
2024static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
2025				  size_t count, loff_t *ppos)
2026{
2027	char buf[32];
2028	struct ath10k *ar = file->private_data;
2029	int len = 0;
2030
2031	mutex_lock(&ar->conf_mutex);
2032	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2033			test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags));
2034	mutex_unlock(&ar->conf_mutex);
2035
2036	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2037}
2038
2039static const struct file_operations fops_btcoex = {
2040	.read = ath10k_read_btcoex,
2041	.write = ath10k_write_btcoex,
2042	.open = simple_open
2043};
2044
2045static ssize_t ath10k_write_enable_extd_tx_stats(struct file *file,
2046						 const char __user *ubuf,
2047						 size_t count, loff_t *ppos)
2048{
2049	struct ath10k *ar = file->private_data;
2050	u32 filter;
2051	int ret;
2052
2053	if (kstrtouint_from_user(ubuf, count, 0, &filter))
2054		return -EINVAL;
2055
2056	mutex_lock(&ar->conf_mutex);
2057
2058	if (ar->state != ATH10K_STATE_ON) {
2059		ar->debug.enable_extd_tx_stats = filter;
2060		ret = count;
2061		goto out;
2062	}
2063
2064	if (filter == ar->debug.enable_extd_tx_stats) {
2065		ret = count;
2066		goto out;
2067	}
2068
2069	ar->debug.enable_extd_tx_stats = filter;
2070	ret = count;
2071
2072out:
2073	mutex_unlock(&ar->conf_mutex);
2074	return ret;
2075}
2076
2077static ssize_t ath10k_read_enable_extd_tx_stats(struct file *file,
2078						char __user *ubuf,
2079						size_t count, loff_t *ppos)
2080
2081{
2082	char buf[32];
2083	struct ath10k *ar = file->private_data;
2084	int len = 0;
2085
2086	mutex_lock(&ar->conf_mutex);
2087	len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
2088			ar->debug.enable_extd_tx_stats);
2089	mutex_unlock(&ar->conf_mutex);
2090
2091	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2092}
2093
2094static const struct file_operations fops_enable_extd_tx_stats = {
2095	.read = ath10k_read_enable_extd_tx_stats,
2096	.write = ath10k_write_enable_extd_tx_stats,
2097	.open = simple_open
2098};
2099
2100static ssize_t ath10k_write_peer_stats(struct file *file,
2101				       const char __user *ubuf,
2102				       size_t count, loff_t *ppos)
2103{
2104	struct ath10k *ar = file->private_data;
2105	char buf[32];
2106	size_t buf_size;
2107	int ret;
2108	bool val;
2109
2110	buf_size = min(count, (sizeof(buf) - 1));
2111	if (copy_from_user(buf, ubuf, buf_size))
2112		return -EFAULT;
2113
2114	buf[buf_size] = '\0';
2115
2116	if (strtobool(buf, &val) != 0)
2117		return -EINVAL;
2118
2119	mutex_lock(&ar->conf_mutex);
2120
2121	if (ar->state != ATH10K_STATE_ON &&
2122	    ar->state != ATH10K_STATE_RESTARTED) {
2123		ret = -ENETDOWN;
2124		goto exit;
2125	}
2126
2127	if (!(test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags) ^ val)) {
2128		ret = count;
2129		goto exit;
2130	}
2131
2132	if (val)
2133		set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2134	else
2135		clear_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2136
2137	ath10k_info(ar, "restarting firmware due to Peer stats change");
2138
2139	ath10k_core_start_recovery(ar);
2140	ret = count;
2141
2142exit:
2143	mutex_unlock(&ar->conf_mutex);
2144	return ret;
2145}
2146
2147static ssize_t ath10k_read_peer_stats(struct file *file, char __user *ubuf,
2148				      size_t count, loff_t *ppos)
2149
2150{
2151	char buf[32];
2152	struct ath10k *ar = file->private_data;
2153	int len = 0;
2154
2155	mutex_lock(&ar->conf_mutex);
2156	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2157			test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags));
2158	mutex_unlock(&ar->conf_mutex);
2159
2160	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2161}
2162
2163static const struct file_operations fops_peer_stats = {
2164	.read = ath10k_read_peer_stats,
2165	.write = ath10k_write_peer_stats,
2166	.open = simple_open
2167};
2168
2169static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
2170					      char __user *user_buf,
2171					      size_t count, loff_t *ppos)
2172{
2173	struct ath10k *ar = file->private_data;
2174	size_t len = 0, buf_len = 4096;
2175	ssize_t ret_cnt;
2176	char *buf;
2177
2178	buf = kzalloc(buf_len, GFP_KERNEL);
2179	if (!buf)
2180		return -ENOMEM;
2181
2182	mutex_lock(&ar->conf_mutex);
2183
2184	len += scnprintf(buf + len, buf_len - len,
2185			 "firmware-N.bin\t\t%08x\n",
2186			 crc32_le(0, ar->normal_mode_fw.fw_file.firmware->data,
2187				  ar->normal_mode_fw.fw_file.firmware->size));
2188	len += scnprintf(buf + len, buf_len - len,
2189			 "athwlan\t\t\t%08x\n",
2190			 crc32_le(0, ar->normal_mode_fw.fw_file.firmware_data,
2191				  ar->normal_mode_fw.fw_file.firmware_len));
2192	len += scnprintf(buf + len, buf_len - len,
2193			 "otp\t\t\t%08x\n",
2194			 crc32_le(0, ar->normal_mode_fw.fw_file.otp_data,
2195				  ar->normal_mode_fw.fw_file.otp_len));
2196	len += scnprintf(buf + len, buf_len - len,
2197			 "codeswap\t\t%08x\n",
2198			 crc32_le(0, ar->normal_mode_fw.fw_file.codeswap_data,
2199				  ar->normal_mode_fw.fw_file.codeswap_len));
2200	len += scnprintf(buf + len, buf_len - len,
2201			 "board-N.bin\t\t%08x\n",
2202			 crc32_le(0, ar->normal_mode_fw.board->data,
2203				  ar->normal_mode_fw.board->size));
2204	len += scnprintf(buf + len, buf_len - len,
2205			 "board\t\t\t%08x\n",
2206			 crc32_le(0, ar->normal_mode_fw.board_data,
2207				  ar->normal_mode_fw.board_len));
2208
2209	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
2210
2211	mutex_unlock(&ar->conf_mutex);
2212
2213	kfree(buf);
2214	return ret_cnt;
2215}
2216
2217static const struct file_operations fops_fw_checksums = {
2218	.read = ath10k_debug_fw_checksums_read,
2219	.open = simple_open,
2220	.owner = THIS_MODULE,
2221	.llseek = default_llseek,
2222};
2223
2224static ssize_t ath10k_sta_tid_stats_mask_read(struct file *file,
2225					      char __user *user_buf,
2226					      size_t count, loff_t *ppos)
2227{
2228	struct ath10k *ar = file->private_data;
2229	char buf[32];
2230	size_t len;
2231
2232	len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->sta_tid_stats_mask);
2233	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2234}
2235
2236static ssize_t ath10k_sta_tid_stats_mask_write(struct file *file,
2237					       const char __user *user_buf,
2238					       size_t count, loff_t *ppos)
2239{
2240	struct ath10k *ar = file->private_data;
2241	char buf[32];
2242	ssize_t len;
2243	u32 mask;
2244
2245	len = min(count, sizeof(buf) - 1);
2246	if (copy_from_user(buf, user_buf, len))
2247		return -EFAULT;
2248
2249	buf[len] = '\0';
2250	if (kstrtoint(buf, 0, &mask))
2251		return -EINVAL;
2252
2253	ar->sta_tid_stats_mask = mask;
2254
2255	return len;
2256}
2257
2258static const struct file_operations fops_sta_tid_stats_mask = {
2259	.read = ath10k_sta_tid_stats_mask_read,
2260	.write = ath10k_sta_tid_stats_mask_write,
2261	.open = simple_open,
2262	.owner = THIS_MODULE,
2263	.llseek = default_llseek,
2264};
2265
2266static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar)
2267{
2268	int ret;
2269	unsigned long time_left;
2270
2271	lockdep_assert_held(&ar->conf_mutex);
2272
2273	reinit_completion(&ar->debug.tpc_complete);
2274
2275	ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM);
2276	if (ret) {
2277		ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret);
2278		return ret;
2279	}
2280
2281	time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
2282						1 * HZ);
2283	if (time_left == 0)
2284		return -ETIMEDOUT;
2285
2286	return 0;
2287}
2288
2289static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file)
2290{
2291	struct ath10k *ar = inode->i_private;
2292	void *buf;
2293	int ret;
2294
2295	mutex_lock(&ar->conf_mutex);
2296
2297	if (ar->state != ATH10K_STATE_ON) {
2298		ret = -ENETDOWN;
2299		goto err_unlock;
2300	}
2301
2302	buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
2303	if (!buf) {
2304		ret = -ENOMEM;
2305		goto err_unlock;
2306	}
2307
2308	ret = ath10k_debug_tpc_stats_final_request(ar);
2309	if (ret) {
2310		ath10k_warn(ar, "failed to request tpc stats final: %d\n",
2311			    ret);
2312		goto err_free;
2313	}
2314
2315	ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
2316	file->private_data = buf;
2317
2318	mutex_unlock(&ar->conf_mutex);
2319	return 0;
2320
2321err_free:
2322	vfree(buf);
2323
2324err_unlock:
2325	mutex_unlock(&ar->conf_mutex);
2326	return ret;
2327}
2328
2329static int ath10k_tpc_stats_final_release(struct inode *inode,
2330					  struct file *file)
2331{
2332	vfree(file->private_data);
2333
2334	return 0;
2335}
2336
2337static ssize_t ath10k_tpc_stats_final_read(struct file *file,
2338					   char __user *user_buf,
2339					   size_t count, loff_t *ppos)
2340{
2341	const char *buf = file->private_data;
2342	unsigned int len = strlen(buf);
2343
2344	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2345}
2346
2347static const struct file_operations fops_tpc_stats_final = {
2348	.open = ath10k_tpc_stats_final_open,
2349	.release = ath10k_tpc_stats_final_release,
2350	.read = ath10k_tpc_stats_final_read,
2351	.owner = THIS_MODULE,
2352	.llseek = default_llseek,
2353};
2354
2355static ssize_t ath10k_write_warm_hw_reset(struct file *file,
2356					  const char __user *user_buf,
2357					  size_t count, loff_t *ppos)
2358{
2359	struct ath10k *ar = file->private_data;
2360	int ret;
2361	bool val;
2362
2363	if (kstrtobool_from_user(user_buf, count, &val))
2364		return -EFAULT;
2365
2366	if (!val)
2367		return -EINVAL;
2368
2369	mutex_lock(&ar->conf_mutex);
2370
2371	if (ar->state != ATH10K_STATE_ON) {
2372		ret = -ENETDOWN;
2373		goto exit;
2374	}
2375
2376	ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pdev_reset,
2377					WMI_RST_MODE_WARM_RESET);
2378
2379	if (ret) {
2380		ath10k_warn(ar, "failed to enable warm hw reset: %d\n", ret);
2381		goto exit;
2382	}
2383
2384	ret = count;
2385
2386exit:
2387	mutex_unlock(&ar->conf_mutex);
2388	return ret;
2389}
2390
2391static const struct file_operations fops_warm_hw_reset = {
2392	.write = ath10k_write_warm_hw_reset,
2393	.open = simple_open,
2394	.owner = THIS_MODULE,
2395	.llseek = default_llseek,
2396};
2397
2398static void ath10k_peer_ps_state_disable(void *data,
2399					 struct ieee80211_sta *sta)
2400{
2401	struct ath10k *ar = data;
2402	struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
2403
2404	spin_lock_bh(&ar->data_lock);
2405	arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
2406	spin_unlock_bh(&ar->data_lock);
2407}
2408
2409static ssize_t ath10k_write_ps_state_enable(struct file *file,
2410					    const char __user *user_buf,
2411					    size_t count, loff_t *ppos)
2412{
2413	struct ath10k *ar = file->private_data;
2414	int ret;
2415	u32 param;
2416	u8 ps_state_enable;
2417
2418	if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
2419		return -EINVAL;
2420
2421	if (ps_state_enable > 1)
2422		return -EINVAL;
2423
2424	mutex_lock(&ar->conf_mutex);
2425
2426	if (ar->ps_state_enable == ps_state_enable) {
2427		ret = count;
2428		goto exit;
2429	}
2430
2431	param = ar->wmi.pdev_param->peer_sta_ps_statechg_enable;
2432	ret = ath10k_wmi_pdev_set_param(ar, param, ps_state_enable);
2433	if (ret) {
2434		ath10k_warn(ar, "failed to enable ps_state_enable: %d\n",
2435			    ret);
2436		goto exit;
2437	}
2438	ar->ps_state_enable = ps_state_enable;
2439
2440	if (!ar->ps_state_enable)
2441		ieee80211_iterate_stations_atomic(ar->hw,
2442						  ath10k_peer_ps_state_disable,
2443						  ar);
2444
2445	ret = count;
2446
2447exit:
2448	mutex_unlock(&ar->conf_mutex);
2449
2450	return ret;
2451}
2452
2453static ssize_t ath10k_read_ps_state_enable(struct file *file,
2454					   char __user *user_buf,
2455					   size_t count, loff_t *ppos)
2456{
2457	struct ath10k *ar = file->private_data;
2458	int len = 0;
2459	char buf[32];
2460
2461	mutex_lock(&ar->conf_mutex);
2462	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2463			ar->ps_state_enable);
2464	mutex_unlock(&ar->conf_mutex);
2465
2466	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2467}
2468
2469static const struct file_operations fops_ps_state_enable = {
2470	.read = ath10k_read_ps_state_enable,
2471	.write = ath10k_write_ps_state_enable,
2472	.open = simple_open,
2473	.owner = THIS_MODULE,
2474	.llseek = default_llseek,
2475};
2476
2477static ssize_t ath10k_write_reset_htt_stats(struct file *file,
2478					    const char __user *user_buf,
2479					    size_t count, loff_t *ppos)
2480{
2481	struct ath10k *ar = file->private_data;
2482	unsigned long reset;
2483	int ret;
2484
2485	ret = kstrtoul_from_user(user_buf, count, 0, &reset);
2486	if (ret)
2487		return ret;
2488
2489	if (reset == 0 || reset > 0x1ffff)
2490		return -EINVAL;
2491
2492	mutex_lock(&ar->conf_mutex);
2493
2494	ar->debug.reset_htt_stats = reset;
2495
2496	ret = ath10k_debug_htt_stats_req(ar);
2497	if (ret)
2498		goto out;
2499
2500	ar->debug.reset_htt_stats = 0;
2501	ret = count;
2502
2503out:
2504	mutex_unlock(&ar->conf_mutex);
2505	return ret;
2506}
2507
2508static const struct file_operations fops_reset_htt_stats = {
2509	.write = ath10k_write_reset_htt_stats,
2510	.owner = THIS_MODULE,
2511	.open = simple_open,
2512	.llseek = default_llseek,
2513};
2514
2515int ath10k_debug_create(struct ath10k *ar)
2516{
2517	ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
2518	if (!ar->debug.cal_data)
2519		return -ENOMEM;
2520
2521	INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
2522	INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
2523	INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
2524	INIT_LIST_HEAD(&ar->debug.fw_stats.peers_extd);
2525
2526	return 0;
2527}
2528
2529void ath10k_debug_destroy(struct ath10k *ar)
2530{
2531	vfree(ar->debug.cal_data);
2532	ar->debug.cal_data = NULL;
2533
2534	ath10k_debug_fw_stats_reset(ar);
2535
2536	kfree(ar->debug.tpc_stats);
2537	kfree(ar->debug.tpc_stats_final);
2538}
2539
2540int ath10k_debug_register(struct ath10k *ar)
2541{
2542	ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
2543						   ar->hw->wiphy->debugfsdir);
2544	if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) {
2545		if (IS_ERR(ar->debug.debugfs_phy))
2546			return PTR_ERR(ar->debug.debugfs_phy);
2547
2548		return -ENOMEM;
2549	}
2550
2551	INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
2552			  ath10k_debug_htt_stats_dwork);
2553
2554	init_completion(&ar->debug.tpc_complete);
2555	init_completion(&ar->debug.fw_stats_complete);
2556
2557	debugfs_create_file("fw_stats", 0400, ar->debug.debugfs_phy, ar,
2558			    &fops_fw_stats);
2559
2560	debugfs_create_file("fw_reset_stats", 0400, ar->debug.debugfs_phy, ar,
2561			    &fops_fw_reset_stats);
2562
2563	debugfs_create_file("wmi_services", 0400, ar->debug.debugfs_phy, ar,
2564			    &fops_wmi_services);
2565
2566	debugfs_create_file("simulate_fw_crash", 0600, ar->debug.debugfs_phy, ar,
2567			    &fops_simulate_fw_crash);
2568
2569	debugfs_create_file("reg_addr", 0600, ar->debug.debugfs_phy, ar,
2570			    &fops_reg_addr);
2571
2572	debugfs_create_file("reg_value", 0600, ar->debug.debugfs_phy, ar,
2573			    &fops_reg_value);
2574
2575	debugfs_create_file("mem_value", 0600, ar->debug.debugfs_phy, ar,
2576			    &fops_mem_value);
2577
2578	debugfs_create_file("chip_id", 0400, ar->debug.debugfs_phy, ar,
2579			    &fops_chip_id);
2580
2581	debugfs_create_file("htt_stats_mask", 0600, ar->debug.debugfs_phy, ar,
2582			    &fops_htt_stats_mask);
2583
2584	debugfs_create_file("htt_max_amsdu_ampdu", 0600, ar->debug.debugfs_phy, ar,
2585			    &fops_htt_max_amsdu_ampdu);
2586
2587	debugfs_create_file("fw_dbglog", 0600, ar->debug.debugfs_phy, ar,
2588			    &fops_fw_dbglog);
2589
2590	if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
2591		      ar->normal_mode_fw.fw_file.fw_features)) {
2592		debugfs_create_file("cal_data", 0400, ar->debug.debugfs_phy, ar,
2593				    &fops_cal_data);
2594
2595		debugfs_create_file("nf_cal_period", 0600, ar->debug.debugfs_phy, ar,
2596				    &fops_nf_cal_period);
2597	}
2598
2599	debugfs_create_file("ani_enable", 0600, ar->debug.debugfs_phy, ar,
2600			    &fops_ani_enable);
2601
2602	if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
2603		debugfs_create_file("dfs_simulate_radar", 0200, ar->debug.debugfs_phy,
2604				    ar, &fops_simulate_radar);
2605
2606		debugfs_create_bool("dfs_block_radar_events", 0200,
2607				    ar->debug.debugfs_phy,
2608				    &ar->dfs_block_radar_events);
2609
2610		debugfs_create_file("dfs_stats", 0400, ar->debug.debugfs_phy, ar,
2611				    &fops_dfs_stats);
2612	}
2613
2614	debugfs_create_file("pktlog_filter", 0644, ar->debug.debugfs_phy, ar,
2615			    &fops_pktlog_filter);
2616
2617	if (test_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map))
2618		debugfs_create_file("quiet_period", 0644, ar->debug.debugfs_phy, ar,
2619				    &fops_quiet_period);
2620
2621	debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_phy, ar,
2622			    &fops_tpc_stats);
2623
2624	if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
2625		debugfs_create_file("btcoex", 0644, ar->debug.debugfs_phy, ar,
2626				    &fops_btcoex);
2627
2628	if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
2629		debugfs_create_file("peer_stats", 0644, ar->debug.debugfs_phy, ar,
2630				    &fops_peer_stats);
2631
2632		debugfs_create_file("enable_extd_tx_stats", 0644,
2633				    ar->debug.debugfs_phy, ar,
2634				    &fops_enable_extd_tx_stats);
2635	}
2636
2637	debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar,
2638			    &fops_fw_checksums);
2639
2640	if (IS_ENABLED(CONFIG_MAC80211_DEBUGFS))
2641		debugfs_create_file("sta_tid_stats_mask", 0600,
2642				    ar->debug.debugfs_phy,
2643				    ar, &fops_sta_tid_stats_mask);
2644
2645	if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map))
2646		debugfs_create_file("tpc_stats_final", 0400,
2647				    ar->debug.debugfs_phy, ar,
2648				    &fops_tpc_stats_final);
2649
2650	if (test_bit(WMI_SERVICE_RESET_CHIP, ar->wmi.svc_map))
2651		debugfs_create_file("warm_hw_reset", 0600,
2652				    ar->debug.debugfs_phy, ar,
2653				    &fops_warm_hw_reset);
2654
2655	debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_phy, ar,
2656			    &fops_ps_state_enable);
2657
2658	debugfs_create_file("reset_htt_stats", 0200, ar->debug.debugfs_phy, ar,
2659			    &fops_reset_htt_stats);
2660
2661	return 0;
2662}
2663
2664void ath10k_debug_unregister(struct ath10k *ar)
2665{
2666	cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
2667}
2668
2669#endif /* CONFIG_ATH10K_DEBUGFS */
2670
2671#ifdef CONFIG_ATH10K_DEBUG
2672void __ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask,
2673		  const char *fmt, ...)
2674{
2675	struct va_format vaf;
2676	va_list args;
2677
2678	va_start(args, fmt);
2679
2680	vaf.fmt = fmt;
2681	vaf.va = &args;
2682
2683	if (ath10k_debug_mask & mask)
2684		dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf);
2685
2686	trace_ath10k_log_dbg(ar, mask, &vaf);
2687
2688	va_end(args);
2689}
2690EXPORT_SYMBOL(__ath10k_dbg);
2691
2692void ath10k_dbg_dump(struct ath10k *ar,
2693		     enum ath10k_debug_mask mask,
2694		     const char *msg, const char *prefix,
2695		     const void *buf, size_t len)
2696{
2697	char linebuf[256];
2698	size_t linebuflen;
2699	const void *ptr;
2700
2701	if (ath10k_debug_mask & mask) {
2702		if (msg)
2703			__ath10k_dbg(ar, mask, "%s\n", msg);
2704
2705		for (ptr = buf; (ptr - buf) < len; ptr += 16) {
2706			linebuflen = 0;
2707			linebuflen += scnprintf(linebuf + linebuflen,
2708						sizeof(linebuf) - linebuflen,
2709						"%s%08x: ",
2710						(prefix ? prefix : ""),
2711						(unsigned int)(ptr - buf));
2712			hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1,
2713					   linebuf + linebuflen,
2714					   sizeof(linebuf) - linebuflen, true);
2715			dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf);
2716		}
2717	}
2718
2719	/* tracing code doesn't like null strings :/ */
2720	trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "",
2721				  buf, len);
2722}
2723EXPORT_SYMBOL(ath10k_dbg_dump);
2724
2725#endif /* CONFIG_ATH10K_DEBUG */