File Index
Files and directories
Sign in
FILE

debug.c

File preview with syntax highlighting.

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