Linux Audio

Check our new training course

Loading...
v6.8
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/*
   3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
   4 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
   5 */
   6
   7#include <linux/vmalloc.h>
   8
   9#include "debugfs.h"
  10
  11#include "core.h"
  12#include "debug.h"
  13#include "wmi.h"
  14#include "hal_rx.h"
  15#include "dp_tx.h"
  16#include "debugfs_htt_stats.h"
  17#include "peer.h"
  18#include "hif.h"
  19
  20static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
  21	"REO2SW1_RING",
  22	"REO2SW2_RING",
  23	"REO2SW3_RING",
  24	"REO2SW4_RING",
  25	"WBM2REO_LINK_RING",
  26	"REO2TCL_RING",
  27	"REO2FW_RING",
  28	"RELEASE_RING",
  29	"PPE_RELEASE_RING",
  30	"TCL2TQM_RING",
  31	"TQM_RELEASE_RING",
  32	"REO_RELEASE_RING",
  33	"WBM2SW0_RELEASE_RING",
  34	"WBM2SW1_RELEASE_RING",
  35	"WBM2SW2_RELEASE_RING",
  36	"WBM2SW3_RELEASE_RING",
  37	"REO_CMD_RING",
  38	"REO_STATUS_RING",
  39};
  40
  41static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
  42	"FW2RXDMA_BUF_RING",
  43	"FW2RXDMA_STATUS_RING",
  44	"FW2RXDMA_LINK_RING",
  45	"SW2RXDMA_BUF_RING",
  46	"WBM2RXDMA_LINK_RING",
  47	"RXDMA2FW_RING",
  48	"RXDMA2SW_RING",
  49	"RXDMA2RELEASE_RING",
  50	"RXDMA2REO_RING",
  51	"MONITOR_STATUS_RING",
  52	"MONITOR_BUF_RING",
  53	"MONITOR_DESC_RING",
  54	"MONITOR_DEST_RING",
  55};
  56
  57void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
  58				     enum wmi_direct_buffer_module id,
  59				     enum ath11k_dbg_dbr_event event,
  60				     struct hal_srng *srng)
  61{
  62	struct ath11k_debug_dbr *dbr_debug;
  63	struct ath11k_dbg_dbr_data *dbr_data;
  64	struct ath11k_dbg_dbr_entry *entry;
  65
  66	if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX)
  67		return;
  68
  69	dbr_debug = ar->debug.dbr_debug[id];
  70	if (!dbr_debug)
  71		return;
  72
  73	if (!dbr_debug->dbr_debug_enabled)
  74		return;
  75
  76	dbr_data = &dbr_debug->dbr_dbg_data;
  77
  78	spin_lock_bh(&dbr_data->lock);
  79
  80	if (dbr_data->entries) {
  81		entry = &dbr_data->entries[dbr_data->dbr_debug_idx];
  82		entry->hp = srng->u.src_ring.hp;
  83		entry->tp = *srng->u.src_ring.tp_addr;
  84		entry->timestamp = jiffies;
  85		entry->event = event;
  86
  87		dbr_data->dbr_debug_idx++;
  88		if (dbr_data->dbr_debug_idx ==
  89		    dbr_data->num_ring_debug_entries)
  90			dbr_data->dbr_debug_idx = 0;
  91	}
  92
  93	spin_unlock_bh(&dbr_data->lock);
  94}
  95
  96static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
  97{
  98	spin_lock_bh(&ar->data_lock);
  99	ar->fw_stats_done = false;
 100	ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
 101	ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
 102	spin_unlock_bh(&ar->data_lock);
 103}
 104
 105void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
 106{
 107	struct ath11k_base *ab = ar->ab;
 108	struct ath11k_pdev *pdev;
 109	bool is_end;
 110	static unsigned int num_vdev, num_bcn;
 111	size_t total_vdevs_started = 0;
 112	int i;
 113
 114	/* WMI_REQUEST_PDEV_STAT request has been already processed */
 115
 116	if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
 117		ar->fw_stats_done = true;
 118		return;
 119	}
 120
 121	if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
 122		if (list_empty(&stats->vdevs)) {
 123			ath11k_warn(ab, "empty vdev stats");
 124			return;
 125		}
 126		/* FW sends all the active VDEV stats irrespective of PDEV,
 127		 * hence limit until the count of all VDEVs started
 128		 */
 129		for (i = 0; i < ab->num_radios; i++) {
 130			pdev = rcu_dereference(ab->pdevs_active[i]);
 131			if (pdev && pdev->ar)
 132				total_vdevs_started += ar->num_started_vdevs;
 133		}
 134
 135		is_end = ((++num_vdev) == total_vdevs_started);
 136
 137		list_splice_tail_init(&stats->vdevs,
 138				      &ar->fw_stats.vdevs);
 139
 140		if (is_end) {
 141			ar->fw_stats_done = true;
 142			num_vdev = 0;
 143		}
 144		return;
 145	}
 146
 147	if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
 148		if (list_empty(&stats->bcn)) {
 149			ath11k_warn(ab, "empty bcn stats");
 150			return;
 151		}
 152		/* Mark end until we reached the count of all started VDEVs
 153		 * within the PDEV
 154		 */
 155		is_end = ((++num_bcn) == ar->num_started_vdevs);
 156
 157		list_splice_tail_init(&stats->bcn,
 158				      &ar->fw_stats.bcn);
 159
 160		if (is_end) {
 161			ar->fw_stats_done = true;
 162			num_bcn = 0;
 163		}
 164	}
 165}
 166
 167static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
 168					   struct stats_request_params *req_param)
 169{
 170	struct ath11k_base *ab = ar->ab;
 171	unsigned long timeout, time_left;
 172	int ret;
 173
 174	lockdep_assert_held(&ar->conf_mutex);
 175
 176	/* FW stats can get split when exceeding the stats data buffer limit.
 177	 * In that case, since there is no end marking for the back-to-back
 178	 * received 'update stats' event, we keep a 3 seconds timeout in case,
 179	 * fw_stats_done is not marked yet
 180	 */
 181	timeout = jiffies + msecs_to_jiffies(3 * 1000);
 182
 183	ath11k_debugfs_fw_stats_reset(ar);
 184
 185	reinit_completion(&ar->fw_stats_complete);
 186
 187	ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
 188
 189	if (ret) {
 190		ath11k_warn(ab, "could not request fw stats (%d)\n",
 191			    ret);
 192		return ret;
 193	}
 194
 195	time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
 196
 197	if (!time_left)
 198		return -ETIMEDOUT;
 199
 200	for (;;) {
 201		if (time_after(jiffies, timeout))
 202			break;
 203
 204		spin_lock_bh(&ar->data_lock);
 205		if (ar->fw_stats_done) {
 206			spin_unlock_bh(&ar->data_lock);
 207			break;
 208		}
 209		spin_unlock_bh(&ar->data_lock);
 210	}
 211	return 0;
 212}
 213
 214int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
 215				u32 vdev_id, u32 stats_id)
 216{
 217	struct ath11k_base *ab = ar->ab;
 218	struct stats_request_params req_param;
 219	int ret;
 220
 221	mutex_lock(&ar->conf_mutex);
 222
 223	if (ar->state != ATH11K_STATE_ON) {
 224		ret = -ENETDOWN;
 225		goto err_unlock;
 226	}
 227
 228	req_param.pdev_id = pdev_id;
 229	req_param.vdev_id = vdev_id;
 230	req_param.stats_id = stats_id;
 231
 232	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 233	if (ret)
 234		ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
 235
 236	ath11k_dbg(ab, ATH11K_DBG_WMI,
 237		   "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
 238		   pdev_id, vdev_id, stats_id);
 239
 240err_unlock:
 241	mutex_unlock(&ar->conf_mutex);
 242
 243	return ret;
 244}
 245
 246static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
 247{
 248	struct ath11k *ar = inode->i_private;
 249	struct ath11k_base *ab = ar->ab;
 250	struct stats_request_params req_param;
 251	void *buf = NULL;
 252	int ret;
 253
 254	mutex_lock(&ar->conf_mutex);
 255
 256	if (ar->state != ATH11K_STATE_ON) {
 257		ret = -ENETDOWN;
 258		goto err_unlock;
 259	}
 260
 261	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
 262	if (!buf) {
 263		ret = -ENOMEM;
 264		goto err_unlock;
 265	}
 266
 267	req_param.pdev_id = ar->pdev->pdev_id;
 268	req_param.vdev_id = 0;
 269	req_param.stats_id = WMI_REQUEST_PDEV_STAT;
 270
 271	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 272	if (ret) {
 273		ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
 274		goto err_free;
 275	}
 276
 277	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 278
 279	file->private_data = buf;
 280
 281	mutex_unlock(&ar->conf_mutex);
 282	return 0;
 283
 284err_free:
 285	vfree(buf);
 286
 287err_unlock:
 288	mutex_unlock(&ar->conf_mutex);
 289	return ret;
 290}
 291
 292static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
 293{
 294	vfree(file->private_data);
 295
 296	return 0;
 297}
 298
 299static ssize_t ath11k_read_pdev_stats(struct file *file,
 300				      char __user *user_buf,
 301				      size_t count, loff_t *ppos)
 302{
 303	const char *buf = file->private_data;
 304	size_t len = strlen(buf);
 305
 306	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 307}
 308
 309static const struct file_operations fops_pdev_stats = {
 310	.open = ath11k_open_pdev_stats,
 311	.release = ath11k_release_pdev_stats,
 312	.read = ath11k_read_pdev_stats,
 313	.owner = THIS_MODULE,
 314	.llseek = default_llseek,
 315};
 316
 317static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
 318{
 319	struct ath11k *ar = inode->i_private;
 320	struct stats_request_params req_param;
 321	void *buf = NULL;
 322	int ret;
 323
 324	mutex_lock(&ar->conf_mutex);
 325
 326	if (ar->state != ATH11K_STATE_ON) {
 327		ret = -ENETDOWN;
 328		goto err_unlock;
 329	}
 330
 331	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
 332	if (!buf) {
 333		ret = -ENOMEM;
 334		goto err_unlock;
 335	}
 336
 337	req_param.pdev_id = ar->pdev->pdev_id;
 338	/* VDEV stats is always sent for all active VDEVs from FW */
 339	req_param.vdev_id = 0;
 340	req_param.stats_id = WMI_REQUEST_VDEV_STAT;
 341
 342	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 343	if (ret) {
 344		ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
 345		goto err_free;
 346	}
 347
 348	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 349
 350	file->private_data = buf;
 351
 352	mutex_unlock(&ar->conf_mutex);
 353	return 0;
 354
 355err_free:
 356	vfree(buf);
 357
 358err_unlock:
 359	mutex_unlock(&ar->conf_mutex);
 360	return ret;
 361}
 362
 363static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
 364{
 365	vfree(file->private_data);
 366
 367	return 0;
 368}
 369
 370static ssize_t ath11k_read_vdev_stats(struct file *file,
 371				      char __user *user_buf,
 372				      size_t count, loff_t *ppos)
 373{
 374	const char *buf = file->private_data;
 375	size_t len = strlen(buf);
 376
 377	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 378}
 379
 380static const struct file_operations fops_vdev_stats = {
 381	.open = ath11k_open_vdev_stats,
 382	.release = ath11k_release_vdev_stats,
 383	.read = ath11k_read_vdev_stats,
 384	.owner = THIS_MODULE,
 385	.llseek = default_llseek,
 386};
 387
 388static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
 389{
 390	struct ath11k *ar = inode->i_private;
 391	struct ath11k_vif *arvif;
 392	struct stats_request_params req_param;
 393	void *buf = NULL;
 394	int ret;
 395
 396	mutex_lock(&ar->conf_mutex);
 397
 398	if (ar->state != ATH11K_STATE_ON) {
 399		ret = -ENETDOWN;
 400		goto err_unlock;
 401	}
 402
 403	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
 404	if (!buf) {
 405		ret = -ENOMEM;
 406		goto err_unlock;
 407	}
 408
 409	req_param.stats_id = WMI_REQUEST_BCN_STAT;
 410	req_param.pdev_id = ar->pdev->pdev_id;
 411
 412	/* loop all active VDEVs for bcn stats */
 413	list_for_each_entry(arvif, &ar->arvifs, list) {
 414		if (!arvif->is_up)
 415			continue;
 416
 417		req_param.vdev_id = arvif->vdev_id;
 418		ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 419		if (ret) {
 420			ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
 421			goto err_free;
 422		}
 423	}
 424
 425	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 426
 427	/* since beacon stats request is looped for all active VDEVs, saved fw
 428	 * stats is not freed for each request until done for all active VDEVs
 429	 */
 430	spin_lock_bh(&ar->data_lock);
 431	ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
 432	spin_unlock_bh(&ar->data_lock);
 433
 434	file->private_data = buf;
 435
 436	mutex_unlock(&ar->conf_mutex);
 437	return 0;
 438
 439err_free:
 440	vfree(buf);
 441
 442err_unlock:
 443	mutex_unlock(&ar->conf_mutex);
 444	return ret;
 445}
 446
 447static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
 448{
 449	vfree(file->private_data);
 450
 451	return 0;
 452}
 453
 454static ssize_t ath11k_read_bcn_stats(struct file *file,
 455				     char __user *user_buf,
 456				     size_t count, loff_t *ppos)
 457{
 458	const char *buf = file->private_data;
 459	size_t len = strlen(buf);
 460
 461	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 462}
 463
 464static const struct file_operations fops_bcn_stats = {
 465	.open = ath11k_open_bcn_stats,
 466	.release = ath11k_release_bcn_stats,
 467	.read = ath11k_read_bcn_stats,
 468	.owner = THIS_MODULE,
 469	.llseek = default_llseek,
 470};
 471
 472static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
 473					     char __user *user_buf,
 474					     size_t count, loff_t *ppos)
 475{
 476	const char buf[] =
 477		"To simulate firmware crash write one of the keywords to this file:\n"
 478		"`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
 479		"`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
 480
 481	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
 482}
 483
 484/* Simulate firmware crash:
 485 * 'soft': Call wmi command causing firmware hang. This firmware hang is
 486 * recoverable by warm firmware reset.
 487 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
 488 * vdev id. This is hard firmware crash because it is recoverable only by cold
 489 * firmware reset.
 490 */
 491static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
 492					      const char __user *user_buf,
 493					      size_t count, loff_t *ppos)
 494{
 495	struct ath11k_base *ab = file->private_data;
 496	struct ath11k_pdev *pdev;
 497	struct ath11k *ar = ab->pdevs[0].ar;
 498	char buf[32] = {0};
 499	ssize_t rc;
 500	int i, ret, radioup = 0;
 501
 502	for (i = 0; i < ab->num_radios; i++) {
 503		pdev = &ab->pdevs[i];
 504		ar = pdev->ar;
 505		if (ar && ar->state == ATH11K_STATE_ON) {
 506			radioup = 1;
 507			break;
 508		}
 509	}
 510	/* filter partial writes and invalid commands */
 511	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
 512		return -EINVAL;
 513
 514	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
 515	if (rc < 0)
 516		return rc;
 517
 518	/* drop the possible '\n' from the end */
 519	if (buf[*ppos - 1] == '\n')
 520		buf[*ppos - 1] = '\0';
 521
 522	if (radioup == 0) {
 523		ret = -ENETDOWN;
 524		goto exit;
 525	}
 526
 527	if (!strcmp(buf, "assert")) {
 528		ath11k_info(ab, "simulating firmware assert crash\n");
 529		ret = ath11k_wmi_force_fw_hang_cmd(ar,
 530						   ATH11K_WMI_FW_HANG_ASSERT_TYPE,
 531						   ATH11K_WMI_FW_HANG_DELAY);
 532	} else if (!strcmp(buf, "hw-restart")) {
 533		ath11k_info(ab, "user requested hw restart\n");
 534		queue_work(ab->workqueue_aux, &ab->reset_work);
 535		ret = 0;
 536	} else {
 537		ret = -EINVAL;
 538		goto exit;
 539	}
 540
 541	if (ret) {
 542		ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
 543		goto exit;
 544	}
 545
 546	ret = count;
 547
 548exit:
 549	return ret;
 550}
 551
 552static const struct file_operations fops_simulate_fw_crash = {
 553	.read = ath11k_read_simulate_fw_crash,
 554	.write = ath11k_write_simulate_fw_crash,
 555	.open = simple_open,
 556	.owner = THIS_MODULE,
 557	.llseek = default_llseek,
 558};
 559
 560static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
 561						 const char __user *ubuf,
 562						 size_t count, loff_t *ppos)
 563{
 564	struct ath11k *ar = file->private_data;
 565	u32 filter;
 566	int ret;
 567
 568	if (kstrtouint_from_user(ubuf, count, 0, &filter))
 569		return -EINVAL;
 570
 571	mutex_lock(&ar->conf_mutex);
 572
 573	if (ar->state != ATH11K_STATE_ON) {
 574		ret = -ENETDOWN;
 575		goto out;
 576	}
 577
 578	if (filter == ar->debug.extd_tx_stats) {
 579		ret = count;
 580		goto out;
 581	}
 582
 583	ar->debug.extd_tx_stats = filter;
 584	ret = count;
 585
 586out:
 587	mutex_unlock(&ar->conf_mutex);
 588	return ret;
 589}
 590
 591static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
 592						char __user *ubuf,
 593						size_t count, loff_t *ppos)
 594
 595{
 596	char buf[32] = {0};
 597	struct ath11k *ar = file->private_data;
 598	int len = 0;
 599
 600	mutex_lock(&ar->conf_mutex);
 601	len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
 602			ar->debug.extd_tx_stats);
 603	mutex_unlock(&ar->conf_mutex);
 604
 605	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
 606}
 607
 608static const struct file_operations fops_extd_tx_stats = {
 609	.read = ath11k_read_enable_extd_tx_stats,
 610	.write = ath11k_write_enable_extd_tx_stats,
 611	.open = simple_open
 612};
 613
 614static ssize_t ath11k_write_extd_rx_stats(struct file *file,
 615					  const char __user *ubuf,
 616					  size_t count, loff_t *ppos)
 617{
 618	struct ath11k *ar = file->private_data;
 619	struct ath11k_base *ab = ar->ab;
 620	struct htt_rx_ring_tlv_filter tlv_filter = {0};
 621	u32 enable, rx_filter = 0, ring_id;
 622	int i;
 623	int ret;
 624
 625	if (kstrtouint_from_user(ubuf, count, 0, &enable))
 626		return -EINVAL;
 627
 628	mutex_lock(&ar->conf_mutex);
 629
 630	if (ar->state != ATH11K_STATE_ON) {
 631		ret = -ENETDOWN;
 632		goto exit;
 633	}
 634
 635	if (enable > 1) {
 636		ret = -EINVAL;
 637		goto exit;
 638	}
 639
 640	if (enable == ar->debug.extd_rx_stats) {
 641		ret = count;
 642		goto exit;
 643	}
 644
 645	if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
 646		ar->debug.extd_rx_stats = enable;
 647		ret = count;
 648		goto exit;
 649	}
 650
 651	if (enable) {
 652		rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
 653		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
 654		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
 655		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
 656		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
 657		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
 658
 659		tlv_filter.rx_filter = rx_filter;
 660		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
 661		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
 662		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
 663		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
 664			HTT_RX_FP_DATA_FILTER_FLASG3;
 665	} else {
 666		tlv_filter = ath11k_mac_mon_status_filter_default;
 667	}
 668
 669	ar->debug.rx_filter = tlv_filter.rx_filter;
 670
 671	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
 672		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 673		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
 674						       HAL_RXDMA_MONITOR_STATUS,
 675						       DP_RX_BUFFER_SIZE, &tlv_filter);
 676
 677		if (ret) {
 678			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
 679			goto exit;
 680		}
 681	}
 682
 683	ar->debug.extd_rx_stats = enable;
 684	ret = count;
 685exit:
 686	mutex_unlock(&ar->conf_mutex);
 687	return ret;
 688}
 689
 690static ssize_t ath11k_read_extd_rx_stats(struct file *file,
 691					 char __user *ubuf,
 692					 size_t count, loff_t *ppos)
 693{
 694	struct ath11k *ar = file->private_data;
 695	char buf[32];
 696	int len = 0;
 697
 698	mutex_lock(&ar->conf_mutex);
 699	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
 700			ar->debug.extd_rx_stats);
 701	mutex_unlock(&ar->conf_mutex);
 702
 703	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
 704}
 705
 706static const struct file_operations fops_extd_rx_stats = {
 707	.read = ath11k_read_extd_rx_stats,
 708	.write = ath11k_write_extd_rx_stats,
 709	.open = simple_open,
 710};
 711
 712static int ath11k_fill_bp_stats(struct ath11k_base *ab,
 713				struct ath11k_bp_stats *bp_stats,
 714				char *buf, int len, int size)
 715{
 716	lockdep_assert_held(&ab->base_lock);
 717
 718	len += scnprintf(buf + len, size - len, "count: %u\n",
 719			 bp_stats->count);
 720	len += scnprintf(buf + len, size - len, "hp: %u\n",
 721			 bp_stats->hp);
 722	len += scnprintf(buf + len, size - len, "tp: %u\n",
 723			 bp_stats->tp);
 724	len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
 725			 jiffies_to_msecs(jiffies - bp_stats->jiffies));
 726	return len;
 727}
 728
 729static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
 730						     char *buf, int size)
 731{
 732	struct ath11k_bp_stats *bp_stats;
 733	bool stats_rxd = false;
 734	u8 i, pdev_idx;
 735	int len = 0;
 736
 737	len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
 738	len += scnprintf(buf + len, size - len, "==================\n");
 739
 740	spin_lock_bh(&ab->base_lock);
 741	for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
 742		bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
 743
 744		if (!bp_stats->count)
 745			continue;
 746
 747		len += scnprintf(buf + len, size - len, "Ring: %s\n",
 748				 htt_bp_umac_ring[i]);
 749		len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
 750		stats_rxd = true;
 751	}
 752
 753	for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
 754		for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
 755			bp_stats =
 756				&ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
 757
 758			if (!bp_stats->count)
 759				continue;
 760
 761			len += scnprintf(buf + len, size - len, "Ring: %s\n",
 762					 htt_bp_lmac_ring[i]);
 763			len += scnprintf(buf + len, size - len, "pdev: %d\n",
 764					 pdev_idx);
 765			len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
 766			stats_rxd = true;
 767		}
 768	}
 769	spin_unlock_bh(&ab->base_lock);
 770
 771	if (!stats_rxd)
 772		len += scnprintf(buf + len, size - len,
 773				 "No Ring Backpressure stats received\n\n");
 774
 775	return len;
 776}
 777
 778static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
 779						char __user *user_buf,
 780						size_t count, loff_t *ppos)
 781{
 782	struct ath11k_base *ab = file->private_data;
 783	struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
 784	int len = 0, i, retval;
 785	const int size = 4096;
 786	static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
 787			"Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
 788			"Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
 789			"AMSDU parse", "SA timeout", "DA timeout",
 790			"Flow timeout", "Flush req"};
 791	static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
 792			"Desc addr zero", "Desc inval", "AMPDU in non BA",
 793			"Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
 794			"Frame OOR", "BAR OOR", "No BA session",
 795			"Frame SN equal SSN", "PN check fail", "2k err",
 796			"PN err", "Desc blocked"};
 797
 798	char *buf;
 799
 800	buf = kzalloc(size, GFP_KERNEL);
 801	if (!buf)
 802		return -ENOMEM;
 803
 804	len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
 805	len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
 806			 soc_stats->err_ring_pkts);
 807	len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
 808			 soc_stats->invalid_rbm);
 809	len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
 810	for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
 811		len += scnprintf(buf + len, size - len, "%s: %u\n",
 812				 rxdma_err[i], soc_stats->rxdma_error[i]);
 813
 814	len += scnprintf(buf + len, size - len, "\nREO errors:\n");
 815	for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
 816		len += scnprintf(buf + len, size - len, "%s: %u\n",
 817				 reo_err[i], soc_stats->reo_error[i]);
 818
 819	len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
 820	len += scnprintf(buf + len, size - len,
 821			 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
 822			 soc_stats->hal_reo_error[0],
 823			 soc_stats->hal_reo_error[1],
 824			 soc_stats->hal_reo_error[2],
 825			 soc_stats->hal_reo_error[3]);
 826
 827	len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
 828	len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
 829
 830	for (i = 0; i < ab->hw_params.max_tx_ring; i++)
 831		len += scnprintf(buf + len, size - len, "ring%d: %u\n",
 832				 i, soc_stats->tx_err.desc_na[i]);
 833
 834	len += scnprintf(buf + len, size - len,
 835			 "\nMisc Transmit Failures: %d\n",
 836			 atomic_read(&soc_stats->tx_err.misc_fail));
 837
 838	len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
 839
 840	if (len > size)
 841		len = size;
 842	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 843	kfree(buf);
 844
 845	return retval;
 846}
 847
 848static const struct file_operations fops_soc_dp_stats = {
 849	.read = ath11k_debugfs_dump_soc_dp_stats,
 850	.open = simple_open,
 851	.owner = THIS_MODULE,
 852	.llseek = default_llseek,
 853};
 854
 855static ssize_t ath11k_write_fw_dbglog(struct file *file,
 856				      const char __user *user_buf,
 857				      size_t count, loff_t *ppos)
 858{
 859	struct ath11k *ar = file->private_data;
 860	char buf[128] = {0};
 861	struct ath11k_fw_dbglog dbglog;
 862	unsigned int param, mod_id_index, is_end;
 863	u64 value;
 864	int ret, num;
 865
 866	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
 867				     user_buf, count);
 868	if (ret <= 0)
 869		return ret;
 870
 871	num = sscanf(buf, "%u %llx %u %u", &param, &value, &mod_id_index, &is_end);
 872
 873	if (num < 2)
 874		return -EINVAL;
 875
 876	mutex_lock(&ar->conf_mutex);
 877	if (param == WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP ||
 878	    param == WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP) {
 879		if (num != 4 || mod_id_index > (MAX_MODULE_ID_BITMAP_WORDS - 1)) {
 880			ret = -EINVAL;
 881			goto out;
 882		}
 883		ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value);
 884		if (!is_end) {
 885			ret = count;
 886			goto out;
 887		}
 888	} else {
 889		if (num != 2) {
 890			ret = -EINVAL;
 891			goto out;
 892		}
 893	}
 894
 895	dbglog.param = param;
 896	dbglog.value = lower_32_bits(value);
 897	ret = ath11k_wmi_fw_dbglog_cfg(ar, ar->debug.module_id_bitmap, &dbglog);
 898	if (ret) {
 899		ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n",
 900			    ret);
 901		goto out;
 902	}
 903
 904	ret = count;
 905
 906out:
 907	mutex_unlock(&ar->conf_mutex);
 908	return ret;
 909}
 910
 911static const struct file_operations fops_fw_dbglog = {
 912	.write = ath11k_write_fw_dbglog,
 913	.open = simple_open,
 914	.owner = THIS_MODULE,
 915	.llseek = default_llseek,
 916};
 917
 918static int ath11k_open_sram_dump(struct inode *inode, struct file *file)
 919{
 920	struct ath11k_base *ab = inode->i_private;
 921	u8 *buf;
 922	u32 start, end;
 923	int ret;
 924
 925	start = ab->hw_params.sram_dump.start;
 926	end = ab->hw_params.sram_dump.end;
 927
 928	buf = vmalloc(end - start + 1);
 929	if (!buf)
 930		return -ENOMEM;
 931
 932	ret = ath11k_hif_read(ab, buf, start, end);
 933	if (ret) {
 934		ath11k_warn(ab, "failed to dump sram: %d\n", ret);
 935		vfree(buf);
 936		return ret;
 937	}
 938
 939	file->private_data = buf;
 940	return 0;
 941}
 942
 943static ssize_t ath11k_read_sram_dump(struct file *file,
 944				     char __user *user_buf,
 945				     size_t count, loff_t *ppos)
 946{
 947	struct ath11k_base *ab = file->f_inode->i_private;
 948	const char *buf = file->private_data;
 949	int len;
 950	u32 start, end;
 951
 952	start = ab->hw_params.sram_dump.start;
 953	end = ab->hw_params.sram_dump.end;
 954	len = end - start + 1;
 955
 956	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 957}
 958
 959static int ath11k_release_sram_dump(struct inode *inode, struct file *file)
 960{
 961	vfree(file->private_data);
 962	file->private_data = NULL;
 963
 964	return 0;
 965}
 966
 967static const struct file_operations fops_sram_dump = {
 968	.open = ath11k_open_sram_dump,
 969	.read = ath11k_read_sram_dump,
 970	.release = ath11k_release_sram_dump,
 971	.owner = THIS_MODULE,
 972	.llseek = default_llseek,
 973};
 974
 975int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
 976{
 977	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
 978		return 0;
 979
 
 
 
 
 980	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
 981			    &fops_simulate_fw_crash);
 982
 983	debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
 984			    &fops_soc_dp_stats);
 985
 986	if (ab->hw_params.sram_dump.start != 0)
 987		debugfs_create_file("sram", 0400, ab->debugfs_soc, ab,
 988				    &fops_sram_dump);
 989
 990	return 0;
 991}
 992
 993void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
 994{
 995	debugfs_remove_recursive(ab->debugfs_soc);
 996	ab->debugfs_soc = NULL;
 997}
 998
 999int ath11k_debugfs_soc_create(struct ath11k_base *ab)
1000{
1001	struct dentry *root;
1002	bool dput_needed;
1003	char name[64];
1004	int ret;
1005
1006	root = debugfs_lookup("ath11k", NULL);
1007	if (!root) {
1008		root = debugfs_create_dir("ath11k", NULL);
1009		if (IS_ERR_OR_NULL(root))
1010			return PTR_ERR(root);
1011
1012		dput_needed = false;
1013	} else {
1014		/* a dentry from lookup() needs dput() after we don't use it */
1015		dput_needed = true;
1016	}
1017
1018	scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
1019		  dev_name(ab->dev));
1020
1021	ab->debugfs_soc = debugfs_create_dir(name, root);
1022	if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
1023		ret = PTR_ERR(ab->debugfs_soc);
1024		goto out;
1025	}
1026
1027	ret = 0;
1028
1029out:
1030	if (dput_needed)
1031		dput(root);
1032
1033	return ret;
1034}
1035
1036void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
1037{
1038	debugfs_remove_recursive(ab->debugfs_soc);
1039	ab->debugfs_soc = NULL;
1040
1041	/* We are not removing ath11k directory on purpose, even if it
1042	 * would be empty. This simplifies the directory handling and it's
1043	 * a minor cosmetic issue to leave an empty ath11k directory to
1044	 * debugfs.
1045	 */
1046}
1047EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
1048
1049void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
1050{
1051	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1052							ar->debug.debugfs_pdev);
1053
1054	ar->fw_stats.debugfs_fwstats = fwstats_dir;
1055
1056	/* all stats debugfs files created are under "fw_stats" directory
1057	 * created per PDEV
1058	 */
1059	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1060			    &fops_pdev_stats);
1061	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1062			    &fops_vdev_stats);
1063	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1064			    &fops_bcn_stats);
1065}
1066
1067static ssize_t ath11k_write_pktlog_filter(struct file *file,
1068					  const char __user *ubuf,
1069					  size_t count, loff_t *ppos)
1070{
1071	struct ath11k *ar = file->private_data;
1072	struct ath11k_base *ab = ar->ab;
1073	struct htt_rx_ring_tlv_filter tlv_filter = {0};
1074	u32 rx_filter = 0, ring_id, filter, mode;
1075	u8 buf[128] = {0};
1076	int i, ret, rx_buf_sz = 0;
1077	ssize_t rc;
1078
1079	mutex_lock(&ar->conf_mutex);
1080	if (ar->state != ATH11K_STATE_ON) {
1081		ret = -ENETDOWN;
1082		goto out;
1083	}
1084
1085	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1086	if (rc < 0) {
1087		ret = rc;
1088		goto out;
1089	}
1090	buf[rc] = '\0';
1091
1092	ret = sscanf(buf, "0x%x %u", &filter, &mode);
1093	if (ret != 2) {
1094		ret = -EINVAL;
1095		goto out;
1096	}
1097
1098	if (filter) {
1099		ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
1100		if (ret) {
1101			ath11k_warn(ar->ab,
1102				    "failed to enable pktlog filter %x: %d\n",
1103				    ar->debug.pktlog_filter, ret);
1104			goto out;
1105		}
1106	} else {
1107		ret = ath11k_wmi_pdev_pktlog_disable(ar);
1108		if (ret) {
1109			ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
1110			goto out;
1111		}
1112	}
1113
1114	/* Clear rx filter set for monitor mode and rx status */
1115	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1116		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1117		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
1118						       HAL_RXDMA_MONITOR_STATUS,
1119						       rx_buf_sz, &tlv_filter);
1120		if (ret) {
1121			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
1122			goto out;
1123		}
1124	}
1125#define HTT_RX_FILTER_TLV_LITE_MODE \
1126			(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
1127			HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
1128			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
1129			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
1130			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
1131			HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
1132
1133	if (mode == ATH11K_PKTLOG_MODE_FULL) {
1134		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
1135			    HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
1136			    HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
1137			    HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
1138			    HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
1139			    HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
1140		rx_buf_sz = DP_RX_BUFFER_SIZE;
1141	} else if (mode == ATH11K_PKTLOG_MODE_LITE) {
1142		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1143							  HTT_PPDU_STATS_TAG_PKTLOG);
1144		if (ret) {
1145			ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
1146			goto out;
1147		}
1148
1149		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
1150		rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
1151	} else {
1152		rx_buf_sz = DP_RX_BUFFER_SIZE;
1153		tlv_filter = ath11k_mac_mon_status_filter_default;
1154		rx_filter = tlv_filter.rx_filter;
1155
1156		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1157							  HTT_PPDU_STATS_TAG_DEFAULT);
1158		if (ret) {
1159			ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
1160				   ret);
1161			goto out;
1162		}
1163	}
1164
1165	tlv_filter.rx_filter = rx_filter;
1166	if (rx_filter) {
1167		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
1168		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
1169		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
1170		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1171					       HTT_RX_FP_DATA_FILTER_FLASG3;
1172	}
1173
1174	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1175		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1176		ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1177						       ar->dp.mac_id + i,
1178						       HAL_RXDMA_MONITOR_STATUS,
1179						       rx_buf_sz, &tlv_filter);
1180
1181		if (ret) {
1182			ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1183			goto out;
1184		}
1185	}
1186
1187	ath11k_info(ab, "pktlog mode %s\n",
1188		    ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1189
1190	ar->debug.pktlog_filter = filter;
1191	ar->debug.pktlog_mode = mode;
1192	ret = count;
1193
1194out:
1195	mutex_unlock(&ar->conf_mutex);
1196	return ret;
1197}
1198
1199static ssize_t ath11k_read_pktlog_filter(struct file *file,
1200					 char __user *ubuf,
1201					 size_t count, loff_t *ppos)
1202
1203{
1204	char buf[32] = {0};
1205	struct ath11k *ar = file->private_data;
1206	int len = 0;
1207
1208	mutex_lock(&ar->conf_mutex);
1209	len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1210			ar->debug.pktlog_filter,
1211			ar->debug.pktlog_mode);
1212	mutex_unlock(&ar->conf_mutex);
1213
1214	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1215}
1216
1217static const struct file_operations fops_pktlog_filter = {
1218	.read = ath11k_read_pktlog_filter,
1219	.write = ath11k_write_pktlog_filter,
1220	.open = simple_open
1221};
1222
1223static ssize_t ath11k_write_simulate_radar(struct file *file,
1224					   const char __user *user_buf,
1225					   size_t count, loff_t *ppos)
1226{
1227	struct ath11k *ar = file->private_data;
1228	int ret;
1229
1230	ret = ath11k_wmi_simulate_radar(ar);
1231	if (ret)
1232		return ret;
1233
1234	return count;
1235}
1236
1237static const struct file_operations fops_simulate_radar = {
1238	.write = ath11k_write_simulate_radar,
1239	.open = simple_open
1240};
1241
1242static ssize_t ath11k_debug_dump_dbr_entries(struct file *file,
1243					     char __user *user_buf,
1244					     size_t count, loff_t *ppos)
1245{
1246	struct ath11k_dbg_dbr_data *dbr_dbg_data = file->private_data;
1247	static const char * const event_id_to_string[] = {"empty", "Rx", "Replenish"};
1248	int size = ATH11K_DEBUG_DBR_ENTRIES_MAX * 100;
1249	char *buf;
1250	int i, ret;
1251	int len = 0;
1252
1253	buf = kzalloc(size, GFP_KERNEL);
1254	if (!buf)
1255		return -ENOMEM;
1256
1257	len += scnprintf(buf + len, size - len,
1258			 "-----------------------------------------\n");
1259	len += scnprintf(buf + len, size - len,
1260			 "| idx |  hp  |  tp  | timestamp |  event |\n");
1261	len += scnprintf(buf + len, size - len,
1262			 "-----------------------------------------\n");
1263
1264	spin_lock_bh(&dbr_dbg_data->lock);
1265
1266	for (i = 0; i < dbr_dbg_data->num_ring_debug_entries; i++) {
1267		len += scnprintf(buf + len, size - len,
1268				 "|%4u|%8u|%8u|%11llu|%8s|\n", i,
1269				 dbr_dbg_data->entries[i].hp,
1270				 dbr_dbg_data->entries[i].tp,
1271				 dbr_dbg_data->entries[i].timestamp,
1272				 event_id_to_string[dbr_dbg_data->entries[i].event]);
1273	}
1274
1275	spin_unlock_bh(&dbr_dbg_data->lock);
1276
1277	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1278	kfree(buf);
1279
1280	return ret;
1281}
1282
1283static const struct file_operations fops_debug_dump_dbr_entries = {
1284	.read = ath11k_debug_dump_dbr_entries,
1285	.open = simple_open,
1286	.owner = THIS_MODULE,
1287	.llseek = default_llseek,
1288};
1289
1290static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id)
1291{
1292	struct ath11k_debug_dbr *dbr_debug;
1293	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1294
1295	if (!ar->debug.dbr_debug[dbr_id])
1296		return;
1297
1298	dbr_debug = ar->debug.dbr_debug[dbr_id];
1299	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1300
1301	debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1302	kfree(dbr_dbg_data->entries);
1303	kfree(dbr_debug);
1304	ar->debug.dbr_debug[dbr_id] = NULL;
1305}
1306
1307static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id)
1308{
1309	struct ath11k_debug_dbr *dbr_debug;
1310	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1311	static const char * const dbr_id_to_str[] = {"spectral", "CFR"};
1312
1313	if (ar->debug.dbr_debug[dbr_id])
1314		return 0;
1315
1316	ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug),
1317					      GFP_KERNEL);
1318
1319	if (!ar->debug.dbr_debug[dbr_id])
1320		return -ENOMEM;
1321
1322	dbr_debug = ar->debug.dbr_debug[dbr_id];
1323	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1324
1325	if (dbr_debug->dbr_debugfs)
1326		return 0;
1327
1328	dbr_debug->dbr_debugfs = debugfs_create_dir(dbr_id_to_str[dbr_id],
1329						    ar->debug.debugfs_pdev);
1330	if (IS_ERR_OR_NULL(dbr_debug->dbr_debugfs)) {
1331		if (IS_ERR(dbr_debug->dbr_debugfs))
1332			return PTR_ERR(dbr_debug->dbr_debugfs);
1333		return -ENOMEM;
1334	}
1335
1336	dbr_debug->dbr_debug_enabled = true;
1337	dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX;
1338	dbr_dbg_data->dbr_debug_idx = 0;
1339	dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX,
1340					sizeof(struct ath11k_dbg_dbr_entry),
1341					GFP_KERNEL);
1342	if (!dbr_dbg_data->entries)
1343		return -ENOMEM;
1344
1345	spin_lock_init(&dbr_dbg_data->lock);
1346
1347	debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs,
1348			    dbr_dbg_data, &fops_debug_dump_dbr_entries);
1349
1350	return 0;
1351}
1352
1353static ssize_t ath11k_debugfs_write_enable_dbr_dbg(struct file *file,
1354						   const char __user *ubuf,
1355						   size_t count, loff_t *ppos)
1356{
1357	struct ath11k *ar = file->private_data;
1358	char buf[32] = {0};
1359	u32 dbr_id, enable;
1360	int ret;
1361
1362	mutex_lock(&ar->conf_mutex);
1363
1364	if (ar->state != ATH11K_STATE_ON) {
1365		ret = -ENETDOWN;
1366		goto out;
1367	}
1368
1369	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1370	if (ret < 0)
1371		goto out;
1372
1373	buf[ret] = '\0';
1374	ret = sscanf(buf, "%u %u", &dbr_id, &enable);
1375	if (ret != 2 || dbr_id > 1 || enable > 1) {
1376		ret = -EINVAL;
1377		ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
1378		goto out;
1379	}
1380
1381	if (enable) {
1382		ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id);
1383		if (ret) {
1384			ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n",
1385				    ret);
1386			goto out;
1387		}
1388	} else {
1389		ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id);
1390	}
1391
1392	ret = count;
1393out:
1394	mutex_unlock(&ar->conf_mutex);
1395	return ret;
1396}
1397
1398static const struct file_operations fops_dbr_debug = {
1399	.write = ath11k_debugfs_write_enable_dbr_dbg,
1400	.open = simple_open,
1401	.owner = THIS_MODULE,
1402	.llseek = default_llseek,
1403};
1404
1405static ssize_t ath11k_write_ps_timekeeper_enable(struct file *file,
1406						 const char __user *user_buf,
1407						 size_t count, loff_t *ppos)
1408{
1409	struct ath11k *ar = file->private_data;
1410	ssize_t ret;
1411	u8 ps_timekeeper_enable;
1412
1413	if (kstrtou8_from_user(user_buf, count, 0, &ps_timekeeper_enable))
1414		return -EINVAL;
1415
1416	mutex_lock(&ar->conf_mutex);
1417
1418	if (ar->state != ATH11K_STATE_ON) {
1419		ret = -ENETDOWN;
1420		goto exit;
1421	}
1422
1423	if (!ar->ps_state_enable) {
1424		ret = -EINVAL;
1425		goto exit;
1426	}
1427
1428	ar->ps_timekeeper_enable = !!ps_timekeeper_enable;
1429	ret = count;
1430exit:
1431	mutex_unlock(&ar->conf_mutex);
1432
1433	return ret;
1434}
1435
1436static ssize_t ath11k_read_ps_timekeeper_enable(struct file *file,
1437						char __user *user_buf,
1438						size_t count, loff_t *ppos)
1439{
1440	struct ath11k *ar = file->private_data;
1441	char buf[32];
1442	int len;
1443
1444	mutex_lock(&ar->conf_mutex);
1445	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_timekeeper_enable);
1446	mutex_unlock(&ar->conf_mutex);
1447
1448	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1449}
1450
1451static const struct file_operations fops_ps_timekeeper_enable = {
1452	.read = ath11k_read_ps_timekeeper_enable,
1453	.write = ath11k_write_ps_timekeeper_enable,
1454	.open = simple_open,
1455	.owner = THIS_MODULE,
1456	.llseek = default_llseek,
1457};
1458
1459static void ath11k_reset_peer_ps_duration(void *data,
1460					  struct ieee80211_sta *sta)
1461{
1462	struct ath11k *ar = data;
1463	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
1464
1465	spin_lock_bh(&ar->data_lock);
1466	arsta->ps_total_duration = 0;
1467	spin_unlock_bh(&ar->data_lock);
1468}
1469
1470static ssize_t ath11k_write_reset_ps_duration(struct file *file,
1471					      const  char __user *user_buf,
1472					      size_t count, loff_t *ppos)
1473{
1474	struct ath11k *ar = file->private_data;
1475	int ret;
1476	u8 reset_ps_duration;
1477
1478	if (kstrtou8_from_user(user_buf, count, 0, &reset_ps_duration))
1479		return -EINVAL;
1480
1481	mutex_lock(&ar->conf_mutex);
1482
1483	if (ar->state != ATH11K_STATE_ON) {
1484		ret = -ENETDOWN;
1485		goto exit;
1486	}
1487
1488	if (!ar->ps_state_enable) {
1489		ret = -EINVAL;
1490		goto exit;
1491	}
1492
1493	ieee80211_iterate_stations_atomic(ar->hw,
1494					  ath11k_reset_peer_ps_duration,
1495					  ar);
1496
1497	ret = count;
1498exit:
1499	mutex_unlock(&ar->conf_mutex);
1500	return ret;
1501}
1502
1503static const struct file_operations fops_reset_ps_duration = {
1504	.write = ath11k_write_reset_ps_duration,
1505	.open = simple_open,
1506	.owner = THIS_MODULE,
1507	.llseek = default_llseek,
1508};
1509
1510static void ath11k_peer_ps_state_disable(void *data,
1511					 struct ieee80211_sta *sta)
1512{
1513	struct ath11k *ar = data;
1514	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
1515
1516	spin_lock_bh(&ar->data_lock);
1517	arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
1518	arsta->ps_start_time = 0;
1519	arsta->ps_total_duration = 0;
1520	spin_unlock_bh(&ar->data_lock);
1521}
1522
1523static ssize_t ath11k_write_ps_state_enable(struct file *file,
1524					    const char __user *user_buf,
1525					    size_t count, loff_t *ppos)
1526{
1527	struct ath11k *ar = file->private_data;
1528	struct ath11k_pdev *pdev = ar->pdev;
1529	int ret;
1530	u32 param;
1531	u8 ps_state_enable;
1532
1533	if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
1534		return -EINVAL;
1535
1536	mutex_lock(&ar->conf_mutex);
1537
1538	ps_state_enable = !!ps_state_enable;
1539
1540	if (ar->ps_state_enable == ps_state_enable) {
1541		ret = count;
1542		goto exit;
1543	}
1544
1545	param = WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
1546	ret = ath11k_wmi_pdev_set_param(ar, param, ps_state_enable, pdev->pdev_id);
1547	if (ret) {
1548		ath11k_warn(ar->ab, "failed to enable ps_state_enable: %d\n",
1549			    ret);
1550		goto exit;
1551	}
1552	ar->ps_state_enable = ps_state_enable;
1553
1554	if (!ar->ps_state_enable) {
1555		ar->ps_timekeeper_enable = false;
1556		ieee80211_iterate_stations_atomic(ar->hw,
1557						  ath11k_peer_ps_state_disable,
1558						  ar);
1559	}
1560
1561	ret = count;
1562
1563exit:
1564	mutex_unlock(&ar->conf_mutex);
1565
1566	return ret;
1567}
1568
1569static ssize_t ath11k_read_ps_state_enable(struct file *file,
1570					   char __user *user_buf,
1571					   size_t count, loff_t *ppos)
1572{
1573	struct ath11k *ar = file->private_data;
1574	char buf[32];
1575	int len;
1576
1577	mutex_lock(&ar->conf_mutex);
1578	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_state_enable);
1579	mutex_unlock(&ar->conf_mutex);
1580
1581	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1582}
1583
1584static const struct file_operations fops_ps_state_enable = {
1585	.read = ath11k_read_ps_state_enable,
1586	.write = ath11k_write_ps_state_enable,
1587	.open = simple_open,
1588	.owner = THIS_MODULE,
1589	.llseek = default_llseek,
1590};
1591
1592int ath11k_debugfs_register(struct ath11k *ar)
1593{
1594	struct ath11k_base *ab = ar->ab;
1595	char pdev_name[10];
1596	char buf[100] = {0};
1597
1598	snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx);
1599
1600	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1601	if (IS_ERR(ar->debug.debugfs_pdev))
1602		return PTR_ERR(ar->debug.debugfs_pdev);
1603
1604	/* Create a symlink under ieee80211/phy* */
1605	snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1606	debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1607
1608	ath11k_debugfs_htt_stats_init(ar);
1609
1610	ath11k_debugfs_fw_stats_init(ar);
1611
1612	debugfs_create_file("ext_tx_stats", 0644,
1613			    ar->debug.debugfs_pdev, ar,
1614			    &fops_extd_tx_stats);
1615	debugfs_create_file("ext_rx_stats", 0644,
1616			    ar->debug.debugfs_pdev, ar,
1617			    &fops_extd_rx_stats);
1618	debugfs_create_file("pktlog_filter", 0644,
1619			    ar->debug.debugfs_pdev, ar,
1620			    &fops_pktlog_filter);
1621	debugfs_create_file("fw_dbglog_config", 0600,
1622			    ar->debug.debugfs_pdev, ar,
1623			    &fops_fw_dbglog);
1624
1625	if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1626		debugfs_create_file("dfs_simulate_radar", 0200,
1627				    ar->debug.debugfs_pdev, ar,
1628				    &fops_simulate_radar);
1629		debugfs_create_bool("dfs_block_radar_events", 0200,
1630				    ar->debug.debugfs_pdev,
1631				    &ar->dfs_block_radar_events);
1632	}
1633
1634	if (ab->hw_params.dbr_debug_support)
1635		debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev,
1636				    ar, &fops_dbr_debug);
1637
1638	debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar,
1639			    &fops_ps_state_enable);
1640
1641	if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT,
1642		     ar->ab->wmi_ab.svc_map)) {
1643		debugfs_create_file("ps_timekeeper_enable", 0600,
1644				    ar->debug.debugfs_pdev, ar,
1645				    &fops_ps_timekeeper_enable);
1646
1647		debugfs_create_file("reset_ps_duration", 0200,
1648				    ar->debug.debugfs_pdev, ar,
1649				    &fops_reset_ps_duration);
1650	}
1651
1652	return 0;
1653}
1654
1655void ath11k_debugfs_unregister(struct ath11k *ar)
1656{
1657	struct ath11k_debug_dbr *dbr_debug;
1658	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1659	int i;
1660
1661	for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) {
1662		dbr_debug = ar->debug.dbr_debug[i];
1663		if (!dbr_debug)
1664			continue;
1665
1666		dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1667		kfree(dbr_dbg_data->entries);
1668		debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1669		kfree(dbr_debug);
1670		ar->debug.dbr_debug[i] = NULL;
1671	}
1672}
1673
1674static ssize_t ath11k_write_twt_add_dialog(struct file *file,
1675					   const char __user *ubuf,
1676					   size_t count, loff_t *ppos)
1677{
1678	struct ath11k_vif *arvif = file->private_data;
1679	struct wmi_twt_add_dialog_params params = { 0 };
1680	struct wmi_twt_enable_params twt_params = {0};
1681	struct ath11k *ar = arvif->ar;
1682	u8 buf[128] = {0};
1683	int ret;
1684
1685	if (ar->twt_enabled == 0) {
1686		ath11k_err(ar->ab, "twt support is not enabled\n");
1687		return -EOPNOTSUPP;
1688	}
1689
1690	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1691	if (ret < 0)
1692		return ret;
1693
1694	buf[ret] = '\0';
1695	ret = sscanf(buf,
1696		     "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
1697		     &params.peer_macaddr[0],
1698		     &params.peer_macaddr[1],
1699		     &params.peer_macaddr[2],
1700		     &params.peer_macaddr[3],
1701		     &params.peer_macaddr[4],
1702		     &params.peer_macaddr[5],
1703		     &params.dialog_id,
1704		     &params.wake_intvl_us,
1705		     &params.wake_intvl_mantis,
1706		     &params.wake_dura_us,
1707		     &params.sp_offset_us,
1708		     &params.twt_cmd,
1709		     &params.flag_bcast,
1710		     &params.flag_trigger,
1711		     &params.flag_flow_type,
1712		     &params.flag_protection);
1713	if (ret != 16)
1714		return -EINVAL;
1715
1716	/* In the case of station vif, TWT is entirely handled by
1717	 * the firmware based on the input parameters in the TWT enable
1718	 * WMI command that is sent to the target during assoc.
1719	 * For manually testing the TWT feature, we need to first disable
1720	 * TWT and send enable command again with TWT input parameter
1721	 * sta_cong_timer_ms set to 0.
1722	 */
1723	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1724		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1725
1726		ath11k_wmi_fill_default_twt_params(&twt_params);
1727		twt_params.sta_cong_timer_ms = 0;
1728
1729		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1730	}
1731
1732	params.vdev_id = arvif->vdev_id;
1733
1734	ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, &params);
1735	if (ret)
1736		goto err_twt_add_dialog;
1737
1738	return count;
1739
1740err_twt_add_dialog:
1741	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1742		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1743		ath11k_wmi_fill_default_twt_params(&twt_params);
1744		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1745	}
1746
1747	return ret;
1748}
1749
1750static ssize_t ath11k_write_twt_del_dialog(struct file *file,
1751					   const char __user *ubuf,
1752					   size_t count, loff_t *ppos)
1753{
1754	struct ath11k_vif *arvif = file->private_data;
1755	struct wmi_twt_del_dialog_params params = { 0 };
1756	struct wmi_twt_enable_params twt_params = {0};
1757	struct ath11k *ar = arvif->ar;
1758	u8 buf[64] = {0};
1759	int ret;
1760
1761	if (ar->twt_enabled == 0) {
1762		ath11k_err(ar->ab, "twt support is not enabled\n");
1763		return -EOPNOTSUPP;
1764	}
1765
1766	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1767	if (ret < 0)
1768		return ret;
1769
1770	buf[ret] = '\0';
1771	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1772		     &params.peer_macaddr[0],
1773		     &params.peer_macaddr[1],
1774		     &params.peer_macaddr[2],
1775		     &params.peer_macaddr[3],
1776		     &params.peer_macaddr[4],
1777		     &params.peer_macaddr[5],
1778		     &params.dialog_id);
1779	if (ret != 7)
1780		return -EINVAL;
1781
1782	params.vdev_id = arvif->vdev_id;
1783
1784	ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, &params);
1785	if (ret)
1786		return ret;
1787
1788	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1789		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1790		ath11k_wmi_fill_default_twt_params(&twt_params);
1791		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1792	}
1793
1794	return count;
1795}
1796
1797static ssize_t ath11k_write_twt_pause_dialog(struct file *file,
1798					     const char __user *ubuf,
1799					     size_t count, loff_t *ppos)
1800{
1801	struct ath11k_vif *arvif = file->private_data;
1802	struct wmi_twt_pause_dialog_params params = { 0 };
1803	u8 buf[64] = {0};
1804	int ret;
1805
1806	if (arvif->ar->twt_enabled == 0) {
1807		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1808		return -EOPNOTSUPP;
1809	}
1810
1811	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1812	if (ret < 0)
1813		return ret;
1814
1815	buf[ret] = '\0';
1816	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1817		     &params.peer_macaddr[0],
1818		     &params.peer_macaddr[1],
1819		     &params.peer_macaddr[2],
1820		     &params.peer_macaddr[3],
1821		     &params.peer_macaddr[4],
1822		     &params.peer_macaddr[5],
1823		     &params.dialog_id);
1824	if (ret != 7)
1825		return -EINVAL;
1826
1827	params.vdev_id = arvif->vdev_id;
1828
1829	ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, &params);
1830	if (ret)
1831		return ret;
1832
1833	return count;
1834}
1835
1836static ssize_t ath11k_write_twt_resume_dialog(struct file *file,
1837					      const char __user *ubuf,
1838					      size_t count, loff_t *ppos)
1839{
1840	struct ath11k_vif *arvif = file->private_data;
1841	struct wmi_twt_resume_dialog_params params = { 0 };
1842	u8 buf[64] = {0};
1843	int ret;
1844
1845	if (arvif->ar->twt_enabled == 0) {
1846		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1847		return -EOPNOTSUPP;
1848	}
1849
1850	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1851	if (ret < 0)
1852		return ret;
1853
1854	buf[ret] = '\0';
1855	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
1856		     &params.peer_macaddr[0],
1857		     &params.peer_macaddr[1],
1858		     &params.peer_macaddr[2],
1859		     &params.peer_macaddr[3],
1860		     &params.peer_macaddr[4],
1861		     &params.peer_macaddr[5],
1862		     &params.dialog_id,
1863		     &params.sp_offset_us,
1864		     &params.next_twt_size);
1865	if (ret != 9)
1866		return -EINVAL;
1867
1868	params.vdev_id = arvif->vdev_id;
1869
1870	ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, &params);
1871	if (ret)
1872		return ret;
1873
1874	return count;
1875}
1876
1877static const struct file_operations ath11k_fops_twt_add_dialog = {
1878	.write = ath11k_write_twt_add_dialog,
1879	.open = simple_open
1880};
1881
1882static const struct file_operations ath11k_fops_twt_del_dialog = {
1883	.write = ath11k_write_twt_del_dialog,
1884	.open = simple_open
1885};
1886
1887static const struct file_operations ath11k_fops_twt_pause_dialog = {
1888	.write = ath11k_write_twt_pause_dialog,
1889	.open = simple_open
1890};
1891
1892static const struct file_operations ath11k_fops_twt_resume_dialog = {
1893	.write = ath11k_write_twt_resume_dialog,
1894	.open = simple_open
1895};
1896
1897void ath11k_debugfs_op_vif_add(struct ieee80211_hw *hw,
1898			       struct ieee80211_vif *vif)
1899{
1900	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
1901	struct ath11k_base *ab = arvif->ar->ab;
1902	struct dentry *debugfs_twt;
1903
1904	if (arvif->vif->type != NL80211_IFTYPE_AP &&
1905	    !(arvif->vif->type == NL80211_IFTYPE_STATION &&
1906	      test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map)))
1907		return;
1908
1909	debugfs_twt = debugfs_create_dir("twt",
1910					 arvif->vif->debugfs_dir);
1911	debugfs_create_file("add_dialog", 0200, debugfs_twt,
1912			    arvif, &ath11k_fops_twt_add_dialog);
1913
1914	debugfs_create_file("del_dialog", 0200, debugfs_twt,
1915			    arvif, &ath11k_fops_twt_del_dialog);
1916
1917	debugfs_create_file("pause_dialog", 0200, debugfs_twt,
1918			    arvif, &ath11k_fops_twt_pause_dialog);
1919
1920	debugfs_create_file("resume_dialog", 0200, debugfs_twt,
1921			    arvif, &ath11k_fops_twt_resume_dialog);
1922}
1923
v6.2
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/*
   3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
 
   4 */
   5
   6#include <linux/vmalloc.h>
   7
   8#include "debugfs.h"
   9
  10#include "core.h"
  11#include "debug.h"
  12#include "wmi.h"
  13#include "hal_rx.h"
  14#include "dp_tx.h"
  15#include "debugfs_htt_stats.h"
  16#include "peer.h"
  17#include "hif.h"
  18
  19static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
  20	"REO2SW1_RING",
  21	"REO2SW2_RING",
  22	"REO2SW3_RING",
  23	"REO2SW4_RING",
  24	"WBM2REO_LINK_RING",
  25	"REO2TCL_RING",
  26	"REO2FW_RING",
  27	"RELEASE_RING",
  28	"PPE_RELEASE_RING",
  29	"TCL2TQM_RING",
  30	"TQM_RELEASE_RING",
  31	"REO_RELEASE_RING",
  32	"WBM2SW0_RELEASE_RING",
  33	"WBM2SW1_RELEASE_RING",
  34	"WBM2SW2_RELEASE_RING",
  35	"WBM2SW3_RELEASE_RING",
  36	"REO_CMD_RING",
  37	"REO_STATUS_RING",
  38};
  39
  40static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
  41	"FW2RXDMA_BUF_RING",
  42	"FW2RXDMA_STATUS_RING",
  43	"FW2RXDMA_LINK_RING",
  44	"SW2RXDMA_BUF_RING",
  45	"WBM2RXDMA_LINK_RING",
  46	"RXDMA2FW_RING",
  47	"RXDMA2SW_RING",
  48	"RXDMA2RELEASE_RING",
  49	"RXDMA2REO_RING",
  50	"MONITOR_STATUS_RING",
  51	"MONITOR_BUF_RING",
  52	"MONITOR_DESC_RING",
  53	"MONITOR_DEST_RING",
  54};
  55
  56void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
  57				     enum wmi_direct_buffer_module id,
  58				     enum ath11k_dbg_dbr_event event,
  59				     struct hal_srng *srng)
  60{
  61	struct ath11k_debug_dbr *dbr_debug;
  62	struct ath11k_dbg_dbr_data *dbr_data;
  63	struct ath11k_dbg_dbr_entry *entry;
  64
  65	if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX)
  66		return;
  67
  68	dbr_debug = ar->debug.dbr_debug[id];
  69	if (!dbr_debug)
  70		return;
  71
  72	if (!dbr_debug->dbr_debug_enabled)
  73		return;
  74
  75	dbr_data = &dbr_debug->dbr_dbg_data;
  76
  77	spin_lock_bh(&dbr_data->lock);
  78
  79	if (dbr_data->entries) {
  80		entry = &dbr_data->entries[dbr_data->dbr_debug_idx];
  81		entry->hp = srng->u.src_ring.hp;
  82		entry->tp = *srng->u.src_ring.tp_addr;
  83		entry->timestamp = jiffies;
  84		entry->event = event;
  85
  86		dbr_data->dbr_debug_idx++;
  87		if (dbr_data->dbr_debug_idx ==
  88		    dbr_data->num_ring_debug_entries)
  89			dbr_data->dbr_debug_idx = 0;
  90	}
  91
  92	spin_unlock_bh(&dbr_data->lock);
  93}
  94
  95static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
  96{
  97	spin_lock_bh(&ar->data_lock);
  98	ar->fw_stats_done = false;
  99	ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
 100	ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
 101	spin_unlock_bh(&ar->data_lock);
 102}
 103
 104void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
 105{
 106	struct ath11k_base *ab = ar->ab;
 107	struct ath11k_pdev *pdev;
 108	bool is_end;
 109	static unsigned int num_vdev, num_bcn;
 110	size_t total_vdevs_started = 0;
 111	int i;
 112
 113	/* WMI_REQUEST_PDEV_STAT request has been already processed */
 114
 115	if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
 116		ar->fw_stats_done = true;
 117		return;
 118	}
 119
 120	if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
 121		if (list_empty(&stats->vdevs)) {
 122			ath11k_warn(ab, "empty vdev stats");
 123			return;
 124		}
 125		/* FW sends all the active VDEV stats irrespective of PDEV,
 126		 * hence limit until the count of all VDEVs started
 127		 */
 128		for (i = 0; i < ab->num_radios; i++) {
 129			pdev = rcu_dereference(ab->pdevs_active[i]);
 130			if (pdev && pdev->ar)
 131				total_vdevs_started += ar->num_started_vdevs;
 132		}
 133
 134		is_end = ((++num_vdev) == total_vdevs_started);
 135
 136		list_splice_tail_init(&stats->vdevs,
 137				      &ar->fw_stats.vdevs);
 138
 139		if (is_end) {
 140			ar->fw_stats_done = true;
 141			num_vdev = 0;
 142		}
 143		return;
 144	}
 145
 146	if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
 147		if (list_empty(&stats->bcn)) {
 148			ath11k_warn(ab, "empty bcn stats");
 149			return;
 150		}
 151		/* Mark end until we reached the count of all started VDEVs
 152		 * within the PDEV
 153		 */
 154		is_end = ((++num_bcn) == ar->num_started_vdevs);
 155
 156		list_splice_tail_init(&stats->bcn,
 157				      &ar->fw_stats.bcn);
 158
 159		if (is_end) {
 160			ar->fw_stats_done = true;
 161			num_bcn = 0;
 162		}
 163	}
 164}
 165
 166static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
 167					   struct stats_request_params *req_param)
 168{
 169	struct ath11k_base *ab = ar->ab;
 170	unsigned long timeout, time_left;
 171	int ret;
 172
 173	lockdep_assert_held(&ar->conf_mutex);
 174
 175	/* FW stats can get split when exceeding the stats data buffer limit.
 176	 * In that case, since there is no end marking for the back-to-back
 177	 * received 'update stats' event, we keep a 3 seconds timeout in case,
 178	 * fw_stats_done is not marked yet
 179	 */
 180	timeout = jiffies + msecs_to_jiffies(3 * 1000);
 181
 182	ath11k_debugfs_fw_stats_reset(ar);
 183
 184	reinit_completion(&ar->fw_stats_complete);
 185
 186	ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
 187
 188	if (ret) {
 189		ath11k_warn(ab, "could not request fw stats (%d)\n",
 190			    ret);
 191		return ret;
 192	}
 193
 194	time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
 195
 196	if (!time_left)
 197		return -ETIMEDOUT;
 198
 199	for (;;) {
 200		if (time_after(jiffies, timeout))
 201			break;
 202
 203		spin_lock_bh(&ar->data_lock);
 204		if (ar->fw_stats_done) {
 205			spin_unlock_bh(&ar->data_lock);
 206			break;
 207		}
 208		spin_unlock_bh(&ar->data_lock);
 209	}
 210	return 0;
 211}
 212
 213int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
 214				u32 vdev_id, u32 stats_id)
 215{
 216	struct ath11k_base *ab = ar->ab;
 217	struct stats_request_params req_param;
 218	int ret;
 219
 220	mutex_lock(&ar->conf_mutex);
 221
 222	if (ar->state != ATH11K_STATE_ON) {
 223		ret = -ENETDOWN;
 224		goto err_unlock;
 225	}
 226
 227	req_param.pdev_id = pdev_id;
 228	req_param.vdev_id = vdev_id;
 229	req_param.stats_id = stats_id;
 230
 231	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 232	if (ret)
 233		ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
 234
 235	ath11k_dbg(ab, ATH11K_DBG_WMI,
 236		   "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
 237		   pdev_id, vdev_id, stats_id);
 238
 239err_unlock:
 240	mutex_unlock(&ar->conf_mutex);
 241
 242	return ret;
 243}
 244
 245static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
 246{
 247	struct ath11k *ar = inode->i_private;
 248	struct ath11k_base *ab = ar->ab;
 249	struct stats_request_params req_param;
 250	void *buf = NULL;
 251	int ret;
 252
 253	mutex_lock(&ar->conf_mutex);
 254
 255	if (ar->state != ATH11K_STATE_ON) {
 256		ret = -ENETDOWN;
 257		goto err_unlock;
 258	}
 259
 260	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
 261	if (!buf) {
 262		ret = -ENOMEM;
 263		goto err_unlock;
 264	}
 265
 266	req_param.pdev_id = ar->pdev->pdev_id;
 267	req_param.vdev_id = 0;
 268	req_param.stats_id = WMI_REQUEST_PDEV_STAT;
 269
 270	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 271	if (ret) {
 272		ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
 273		goto err_free;
 274	}
 275
 276	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 277
 278	file->private_data = buf;
 279
 280	mutex_unlock(&ar->conf_mutex);
 281	return 0;
 282
 283err_free:
 284	vfree(buf);
 285
 286err_unlock:
 287	mutex_unlock(&ar->conf_mutex);
 288	return ret;
 289}
 290
 291static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
 292{
 293	vfree(file->private_data);
 294
 295	return 0;
 296}
 297
 298static ssize_t ath11k_read_pdev_stats(struct file *file,
 299				      char __user *user_buf,
 300				      size_t count, loff_t *ppos)
 301{
 302	const char *buf = file->private_data;
 303	size_t len = strlen(buf);
 304
 305	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 306}
 307
 308static const struct file_operations fops_pdev_stats = {
 309	.open = ath11k_open_pdev_stats,
 310	.release = ath11k_release_pdev_stats,
 311	.read = ath11k_read_pdev_stats,
 312	.owner = THIS_MODULE,
 313	.llseek = default_llseek,
 314};
 315
 316static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
 317{
 318	struct ath11k *ar = inode->i_private;
 319	struct stats_request_params req_param;
 320	void *buf = NULL;
 321	int ret;
 322
 323	mutex_lock(&ar->conf_mutex);
 324
 325	if (ar->state != ATH11K_STATE_ON) {
 326		ret = -ENETDOWN;
 327		goto err_unlock;
 328	}
 329
 330	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
 331	if (!buf) {
 332		ret = -ENOMEM;
 333		goto err_unlock;
 334	}
 335
 336	req_param.pdev_id = ar->pdev->pdev_id;
 337	/* VDEV stats is always sent for all active VDEVs from FW */
 338	req_param.vdev_id = 0;
 339	req_param.stats_id = WMI_REQUEST_VDEV_STAT;
 340
 341	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 342	if (ret) {
 343		ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
 344		goto err_free;
 345	}
 346
 347	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 348
 349	file->private_data = buf;
 350
 351	mutex_unlock(&ar->conf_mutex);
 352	return 0;
 353
 354err_free:
 355	vfree(buf);
 356
 357err_unlock:
 358	mutex_unlock(&ar->conf_mutex);
 359	return ret;
 360}
 361
 362static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
 363{
 364	vfree(file->private_data);
 365
 366	return 0;
 367}
 368
 369static ssize_t ath11k_read_vdev_stats(struct file *file,
 370				      char __user *user_buf,
 371				      size_t count, loff_t *ppos)
 372{
 373	const char *buf = file->private_data;
 374	size_t len = strlen(buf);
 375
 376	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 377}
 378
 379static const struct file_operations fops_vdev_stats = {
 380	.open = ath11k_open_vdev_stats,
 381	.release = ath11k_release_vdev_stats,
 382	.read = ath11k_read_vdev_stats,
 383	.owner = THIS_MODULE,
 384	.llseek = default_llseek,
 385};
 386
 387static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
 388{
 389	struct ath11k *ar = inode->i_private;
 390	struct ath11k_vif *arvif;
 391	struct stats_request_params req_param;
 392	void *buf = NULL;
 393	int ret;
 394
 395	mutex_lock(&ar->conf_mutex);
 396
 397	if (ar->state != ATH11K_STATE_ON) {
 398		ret = -ENETDOWN;
 399		goto err_unlock;
 400	}
 401
 402	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
 403	if (!buf) {
 404		ret = -ENOMEM;
 405		goto err_unlock;
 406	}
 407
 408	req_param.stats_id = WMI_REQUEST_BCN_STAT;
 409	req_param.pdev_id = ar->pdev->pdev_id;
 410
 411	/* loop all active VDEVs for bcn stats */
 412	list_for_each_entry(arvif, &ar->arvifs, list) {
 413		if (!arvif->is_up)
 414			continue;
 415
 416		req_param.vdev_id = arvif->vdev_id;
 417		ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
 418		if (ret) {
 419			ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
 420			goto err_free;
 421		}
 422	}
 423
 424	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
 425
 426	/* since beacon stats request is looped for all active VDEVs, saved fw
 427	 * stats is not freed for each request until done for all active VDEVs
 428	 */
 429	spin_lock_bh(&ar->data_lock);
 430	ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
 431	spin_unlock_bh(&ar->data_lock);
 432
 433	file->private_data = buf;
 434
 435	mutex_unlock(&ar->conf_mutex);
 436	return 0;
 437
 438err_free:
 439	vfree(buf);
 440
 441err_unlock:
 442	mutex_unlock(&ar->conf_mutex);
 443	return ret;
 444}
 445
 446static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
 447{
 448	vfree(file->private_data);
 449
 450	return 0;
 451}
 452
 453static ssize_t ath11k_read_bcn_stats(struct file *file,
 454				     char __user *user_buf,
 455				     size_t count, loff_t *ppos)
 456{
 457	const char *buf = file->private_data;
 458	size_t len = strlen(buf);
 459
 460	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 461}
 462
 463static const struct file_operations fops_bcn_stats = {
 464	.open = ath11k_open_bcn_stats,
 465	.release = ath11k_release_bcn_stats,
 466	.read = ath11k_read_bcn_stats,
 467	.owner = THIS_MODULE,
 468	.llseek = default_llseek,
 469};
 470
 471static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
 472					     char __user *user_buf,
 473					     size_t count, loff_t *ppos)
 474{
 475	const char buf[] =
 476		"To simulate firmware crash write one of the keywords to this file:\n"
 477		"`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
 478		"`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
 479
 480	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
 481}
 482
 483/* Simulate firmware crash:
 484 * 'soft': Call wmi command causing firmware hang. This firmware hang is
 485 * recoverable by warm firmware reset.
 486 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
 487 * vdev id. This is hard firmware crash because it is recoverable only by cold
 488 * firmware reset.
 489 */
 490static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
 491					      const char __user *user_buf,
 492					      size_t count, loff_t *ppos)
 493{
 494	struct ath11k_base *ab = file->private_data;
 495	struct ath11k_pdev *pdev;
 496	struct ath11k *ar = ab->pdevs[0].ar;
 497	char buf[32] = {0};
 498	ssize_t rc;
 499	int i, ret, radioup = 0;
 500
 501	for (i = 0; i < ab->num_radios; i++) {
 502		pdev = &ab->pdevs[i];
 503		ar = pdev->ar;
 504		if (ar && ar->state == ATH11K_STATE_ON) {
 505			radioup = 1;
 506			break;
 507		}
 508	}
 509	/* filter partial writes and invalid commands */
 510	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
 511		return -EINVAL;
 512
 513	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
 514	if (rc < 0)
 515		return rc;
 516
 517	/* drop the possible '\n' from the end */
 518	if (buf[*ppos - 1] == '\n')
 519		buf[*ppos - 1] = '\0';
 520
 521	if (radioup == 0) {
 522		ret = -ENETDOWN;
 523		goto exit;
 524	}
 525
 526	if (!strcmp(buf, "assert")) {
 527		ath11k_info(ab, "simulating firmware assert crash\n");
 528		ret = ath11k_wmi_force_fw_hang_cmd(ar,
 529						   ATH11K_WMI_FW_HANG_ASSERT_TYPE,
 530						   ATH11K_WMI_FW_HANG_DELAY);
 531	} else if (!strcmp(buf, "hw-restart")) {
 532		ath11k_info(ab, "user requested hw restart\n");
 533		queue_work(ab->workqueue_aux, &ab->reset_work);
 534		ret = 0;
 535	} else {
 536		ret = -EINVAL;
 537		goto exit;
 538	}
 539
 540	if (ret) {
 541		ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
 542		goto exit;
 543	}
 544
 545	ret = count;
 546
 547exit:
 548	return ret;
 549}
 550
 551static const struct file_operations fops_simulate_fw_crash = {
 552	.read = ath11k_read_simulate_fw_crash,
 553	.write = ath11k_write_simulate_fw_crash,
 554	.open = simple_open,
 555	.owner = THIS_MODULE,
 556	.llseek = default_llseek,
 557};
 558
 559static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
 560						 const char __user *ubuf,
 561						 size_t count, loff_t *ppos)
 562{
 563	struct ath11k *ar = file->private_data;
 564	u32 filter;
 565	int ret;
 566
 567	if (kstrtouint_from_user(ubuf, count, 0, &filter))
 568		return -EINVAL;
 569
 570	mutex_lock(&ar->conf_mutex);
 571
 572	if (ar->state != ATH11K_STATE_ON) {
 573		ret = -ENETDOWN;
 574		goto out;
 575	}
 576
 577	if (filter == ar->debug.extd_tx_stats) {
 578		ret = count;
 579		goto out;
 580	}
 581
 582	ar->debug.extd_tx_stats = filter;
 583	ret = count;
 584
 585out:
 586	mutex_unlock(&ar->conf_mutex);
 587	return ret;
 588}
 589
 590static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
 591						char __user *ubuf,
 592						size_t count, loff_t *ppos)
 593
 594{
 595	char buf[32] = {0};
 596	struct ath11k *ar = file->private_data;
 597	int len = 0;
 598
 599	mutex_lock(&ar->conf_mutex);
 600	len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
 601			ar->debug.extd_tx_stats);
 602	mutex_unlock(&ar->conf_mutex);
 603
 604	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
 605}
 606
 607static const struct file_operations fops_extd_tx_stats = {
 608	.read = ath11k_read_enable_extd_tx_stats,
 609	.write = ath11k_write_enable_extd_tx_stats,
 610	.open = simple_open
 611};
 612
 613static ssize_t ath11k_write_extd_rx_stats(struct file *file,
 614					  const char __user *ubuf,
 615					  size_t count, loff_t *ppos)
 616{
 617	struct ath11k *ar = file->private_data;
 618	struct ath11k_base *ab = ar->ab;
 619	struct htt_rx_ring_tlv_filter tlv_filter = {0};
 620	u32 enable, rx_filter = 0, ring_id;
 621	int i;
 622	int ret;
 623
 624	if (kstrtouint_from_user(ubuf, count, 0, &enable))
 625		return -EINVAL;
 626
 627	mutex_lock(&ar->conf_mutex);
 628
 629	if (ar->state != ATH11K_STATE_ON) {
 630		ret = -ENETDOWN;
 631		goto exit;
 632	}
 633
 634	if (enable > 1) {
 635		ret = -EINVAL;
 636		goto exit;
 637	}
 638
 639	if (enable == ar->debug.extd_rx_stats) {
 640		ret = count;
 641		goto exit;
 642	}
 643
 644	if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
 645		ar->debug.extd_rx_stats = enable;
 646		ret = count;
 647		goto exit;
 648	}
 649
 650	if (enable) {
 651		rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
 652		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
 653		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
 654		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
 655		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
 656		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
 657
 658		tlv_filter.rx_filter = rx_filter;
 659		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
 660		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
 661		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
 662		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
 663			HTT_RX_FP_DATA_FILTER_FLASG3;
 664	} else {
 665		tlv_filter = ath11k_mac_mon_status_filter_default;
 666	}
 667
 668	ar->debug.rx_filter = tlv_filter.rx_filter;
 669
 670	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
 671		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 672		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
 673						       HAL_RXDMA_MONITOR_STATUS,
 674						       DP_RX_BUFFER_SIZE, &tlv_filter);
 675
 676		if (ret) {
 677			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
 678			goto exit;
 679		}
 680	}
 681
 682	ar->debug.extd_rx_stats = enable;
 683	ret = count;
 684exit:
 685	mutex_unlock(&ar->conf_mutex);
 686	return ret;
 687}
 688
 689static ssize_t ath11k_read_extd_rx_stats(struct file *file,
 690					 char __user *ubuf,
 691					 size_t count, loff_t *ppos)
 692{
 693	struct ath11k *ar = file->private_data;
 694	char buf[32];
 695	int len = 0;
 696
 697	mutex_lock(&ar->conf_mutex);
 698	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
 699			ar->debug.extd_rx_stats);
 700	mutex_unlock(&ar->conf_mutex);
 701
 702	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
 703}
 704
 705static const struct file_operations fops_extd_rx_stats = {
 706	.read = ath11k_read_extd_rx_stats,
 707	.write = ath11k_write_extd_rx_stats,
 708	.open = simple_open,
 709};
 710
 711static int ath11k_fill_bp_stats(struct ath11k_base *ab,
 712				struct ath11k_bp_stats *bp_stats,
 713				char *buf, int len, int size)
 714{
 715	lockdep_assert_held(&ab->base_lock);
 716
 717	len += scnprintf(buf + len, size - len, "count: %u\n",
 718			 bp_stats->count);
 719	len += scnprintf(buf + len, size - len, "hp: %u\n",
 720			 bp_stats->hp);
 721	len += scnprintf(buf + len, size - len, "tp: %u\n",
 722			 bp_stats->tp);
 723	len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
 724			 jiffies_to_msecs(jiffies - bp_stats->jiffies));
 725	return len;
 726}
 727
 728static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
 729						     char *buf, int size)
 730{
 731	struct ath11k_bp_stats *bp_stats;
 732	bool stats_rxd = false;
 733	u8 i, pdev_idx;
 734	int len = 0;
 735
 736	len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
 737	len += scnprintf(buf + len, size - len, "==================\n");
 738
 739	spin_lock_bh(&ab->base_lock);
 740	for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
 741		bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
 742
 743		if (!bp_stats->count)
 744			continue;
 745
 746		len += scnprintf(buf + len, size - len, "Ring: %s\n",
 747				 htt_bp_umac_ring[i]);
 748		len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
 749		stats_rxd = true;
 750	}
 751
 752	for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
 753		for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
 754			bp_stats =
 755				&ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
 756
 757			if (!bp_stats->count)
 758				continue;
 759
 760			len += scnprintf(buf + len, size - len, "Ring: %s\n",
 761					 htt_bp_lmac_ring[i]);
 762			len += scnprintf(buf + len, size - len, "pdev: %d\n",
 763					 pdev_idx);
 764			len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
 765			stats_rxd = true;
 766		}
 767	}
 768	spin_unlock_bh(&ab->base_lock);
 769
 770	if (!stats_rxd)
 771		len += scnprintf(buf + len, size - len,
 772				 "No Ring Backpressure stats received\n\n");
 773
 774	return len;
 775}
 776
 777static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
 778						char __user *user_buf,
 779						size_t count, loff_t *ppos)
 780{
 781	struct ath11k_base *ab = file->private_data;
 782	struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
 783	int len = 0, i, retval;
 784	const int size = 4096;
 785	static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
 786			"Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
 787			"Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
 788			"AMSDU parse", "SA timeout", "DA timeout",
 789			"Flow timeout", "Flush req"};
 790	static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
 791			"Desc addr zero", "Desc inval", "AMPDU in non BA",
 792			"Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
 793			"Frame OOR", "BAR OOR", "No BA session",
 794			"Frame SN equal SSN", "PN check fail", "2k err",
 795			"PN err", "Desc blocked"};
 796
 797	char *buf;
 798
 799	buf = kzalloc(size, GFP_KERNEL);
 800	if (!buf)
 801		return -ENOMEM;
 802
 803	len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
 804	len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
 805			 soc_stats->err_ring_pkts);
 806	len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
 807			 soc_stats->invalid_rbm);
 808	len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
 809	for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
 810		len += scnprintf(buf + len, size - len, "%s: %u\n",
 811				 rxdma_err[i], soc_stats->rxdma_error[i]);
 812
 813	len += scnprintf(buf + len, size - len, "\nREO errors:\n");
 814	for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
 815		len += scnprintf(buf + len, size - len, "%s: %u\n",
 816				 reo_err[i], soc_stats->reo_error[i]);
 817
 818	len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
 819	len += scnprintf(buf + len, size - len,
 820			 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
 821			 soc_stats->hal_reo_error[0],
 822			 soc_stats->hal_reo_error[1],
 823			 soc_stats->hal_reo_error[2],
 824			 soc_stats->hal_reo_error[3]);
 825
 826	len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
 827	len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
 828
 829	for (i = 0; i < ab->hw_params.max_tx_ring; i++)
 830		len += scnprintf(buf + len, size - len, "ring%d: %u\n",
 831				 i, soc_stats->tx_err.desc_na[i]);
 832
 833	len += scnprintf(buf + len, size - len,
 834			 "\nMisc Transmit Failures: %d\n",
 835			 atomic_read(&soc_stats->tx_err.misc_fail));
 836
 837	len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
 838
 839	if (len > size)
 840		len = size;
 841	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
 842	kfree(buf);
 843
 844	return retval;
 845}
 846
 847static const struct file_operations fops_soc_dp_stats = {
 848	.read = ath11k_debugfs_dump_soc_dp_stats,
 849	.open = simple_open,
 850	.owner = THIS_MODULE,
 851	.llseek = default_llseek,
 852};
 853
 854static ssize_t ath11k_write_fw_dbglog(struct file *file,
 855				      const char __user *user_buf,
 856				      size_t count, loff_t *ppos)
 857{
 858	struct ath11k *ar = file->private_data;
 859	char buf[128] = {0};
 860	struct ath11k_fw_dbglog dbglog;
 861	unsigned int param, mod_id_index, is_end;
 862	u64 value;
 863	int ret, num;
 864
 865	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
 866				     user_buf, count);
 867	if (ret <= 0)
 868		return ret;
 869
 870	num = sscanf(buf, "%u %llx %u %u", &param, &value, &mod_id_index, &is_end);
 871
 872	if (num < 2)
 873		return -EINVAL;
 874
 875	mutex_lock(&ar->conf_mutex);
 876	if (param == WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP ||
 877	    param == WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP) {
 878		if (num != 4 || mod_id_index > (MAX_MODULE_ID_BITMAP_WORDS - 1)) {
 879			ret = -EINVAL;
 880			goto out;
 881		}
 882		ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value);
 883		if (!is_end) {
 884			ret = count;
 885			goto out;
 886		}
 887	} else {
 888		if (num != 2) {
 889			ret = -EINVAL;
 890			goto out;
 891		}
 892	}
 893
 894	dbglog.param = param;
 895	dbglog.value = lower_32_bits(value);
 896	ret = ath11k_wmi_fw_dbglog_cfg(ar, ar->debug.module_id_bitmap, &dbglog);
 897	if (ret) {
 898		ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n",
 899			    ret);
 900		goto out;
 901	}
 902
 903	ret = count;
 904
 905out:
 906	mutex_unlock(&ar->conf_mutex);
 907	return ret;
 908}
 909
 910static const struct file_operations fops_fw_dbglog = {
 911	.write = ath11k_write_fw_dbglog,
 912	.open = simple_open,
 913	.owner = THIS_MODULE,
 914	.llseek = default_llseek,
 915};
 916
 917static int ath11k_open_sram_dump(struct inode *inode, struct file *file)
 918{
 919	struct ath11k_base *ab = inode->i_private;
 920	u8 *buf;
 921	u32 start, end;
 922	int ret;
 923
 924	start = ab->hw_params.sram_dump.start;
 925	end = ab->hw_params.sram_dump.end;
 926
 927	buf = vmalloc(end - start + 1);
 928	if (!buf)
 929		return -ENOMEM;
 930
 931	ret = ath11k_hif_read(ab, buf, start, end);
 932	if (ret) {
 933		ath11k_warn(ab, "failed to dump sram: %d\n", ret);
 934		vfree(buf);
 935		return ret;
 936	}
 937
 938	file->private_data = buf;
 939	return 0;
 940}
 941
 942static ssize_t ath11k_read_sram_dump(struct file *file,
 943				     char __user *user_buf,
 944				     size_t count, loff_t *ppos)
 945{
 946	struct ath11k_base *ab = file->f_inode->i_private;
 947	const char *buf = file->private_data;
 948	int len;
 949	u32 start, end;
 950
 951	start = ab->hw_params.sram_dump.start;
 952	end = ab->hw_params.sram_dump.end;
 953	len = end - start + 1;
 954
 955	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 956}
 957
 958static int ath11k_release_sram_dump(struct inode *inode, struct file *file)
 959{
 960	vfree(file->private_data);
 961	file->private_data = NULL;
 962
 963	return 0;
 964}
 965
 966static const struct file_operations fops_sram_dump = {
 967	.open = ath11k_open_sram_dump,
 968	.read = ath11k_read_sram_dump,
 969	.release = ath11k_release_sram_dump,
 970	.owner = THIS_MODULE,
 971	.llseek = default_llseek,
 972};
 973
 974int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
 975{
 976	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
 977		return 0;
 978
 979	ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
 980	if (IS_ERR(ab->debugfs_soc))
 981		return PTR_ERR(ab->debugfs_soc);
 982
 983	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
 984			    &fops_simulate_fw_crash);
 985
 986	debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
 987			    &fops_soc_dp_stats);
 988
 989	if (ab->hw_params.sram_dump.start != 0)
 990		debugfs_create_file("sram", 0400, ab->debugfs_soc, ab,
 991				    &fops_sram_dump);
 992
 993	return 0;
 994}
 995
 996void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
 997{
 998	debugfs_remove_recursive(ab->debugfs_soc);
 999	ab->debugfs_soc = NULL;
1000}
1001
1002int ath11k_debugfs_soc_create(struct ath11k_base *ab)
1003{
1004	ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1005
1006	return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
 
 
 
 
1007}
1008
1009void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
1010{
1011	debugfs_remove_recursive(ab->debugfs_ath11k);
1012	ab->debugfs_ath11k = NULL;
 
 
 
 
 
 
1013}
1014EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
1015
1016void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
1017{
1018	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1019							ar->debug.debugfs_pdev);
1020
1021	ar->fw_stats.debugfs_fwstats = fwstats_dir;
1022
1023	/* all stats debugfs files created are under "fw_stats" directory
1024	 * created per PDEV
1025	 */
1026	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1027			    &fops_pdev_stats);
1028	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1029			    &fops_vdev_stats);
1030	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1031			    &fops_bcn_stats);
1032}
1033
1034static ssize_t ath11k_write_pktlog_filter(struct file *file,
1035					  const char __user *ubuf,
1036					  size_t count, loff_t *ppos)
1037{
1038	struct ath11k *ar = file->private_data;
1039	struct ath11k_base *ab = ar->ab;
1040	struct htt_rx_ring_tlv_filter tlv_filter = {0};
1041	u32 rx_filter = 0, ring_id, filter, mode;
1042	u8 buf[128] = {0};
1043	int i, ret, rx_buf_sz = 0;
1044	ssize_t rc;
1045
1046	mutex_lock(&ar->conf_mutex);
1047	if (ar->state != ATH11K_STATE_ON) {
1048		ret = -ENETDOWN;
1049		goto out;
1050	}
1051
1052	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1053	if (rc < 0) {
1054		ret = rc;
1055		goto out;
1056	}
1057	buf[rc] = '\0';
1058
1059	ret = sscanf(buf, "0x%x %u", &filter, &mode);
1060	if (ret != 2) {
1061		ret = -EINVAL;
1062		goto out;
1063	}
1064
1065	if (filter) {
1066		ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
1067		if (ret) {
1068			ath11k_warn(ar->ab,
1069				    "failed to enable pktlog filter %x: %d\n",
1070				    ar->debug.pktlog_filter, ret);
1071			goto out;
1072		}
1073	} else {
1074		ret = ath11k_wmi_pdev_pktlog_disable(ar);
1075		if (ret) {
1076			ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
1077			goto out;
1078		}
1079	}
1080
1081	/* Clear rx filter set for monitor mode and rx status */
1082	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1083		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1084		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
1085						       HAL_RXDMA_MONITOR_STATUS,
1086						       rx_buf_sz, &tlv_filter);
1087		if (ret) {
1088			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
1089			goto out;
1090		}
1091	}
1092#define HTT_RX_FILTER_TLV_LITE_MODE \
1093			(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
1094			HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
1095			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
1096			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
1097			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
1098			HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
1099
1100	if (mode == ATH11K_PKTLOG_MODE_FULL) {
1101		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
1102			    HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
1103			    HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
1104			    HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
1105			    HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
1106			    HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
1107		rx_buf_sz = DP_RX_BUFFER_SIZE;
1108	} else if (mode == ATH11K_PKTLOG_MODE_LITE) {
1109		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1110							  HTT_PPDU_STATS_TAG_PKTLOG);
1111		if (ret) {
1112			ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
1113			goto out;
1114		}
1115
1116		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
1117		rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
1118	} else {
1119		rx_buf_sz = DP_RX_BUFFER_SIZE;
1120		tlv_filter = ath11k_mac_mon_status_filter_default;
1121		rx_filter = tlv_filter.rx_filter;
1122
1123		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1124							  HTT_PPDU_STATS_TAG_DEFAULT);
1125		if (ret) {
1126			ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
1127				   ret);
1128			goto out;
1129		}
1130	}
1131
1132	tlv_filter.rx_filter = rx_filter;
1133	if (rx_filter) {
1134		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
1135		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
1136		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
1137		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1138					       HTT_RX_FP_DATA_FILTER_FLASG3;
1139	}
1140
1141	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1142		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1143		ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1144						       ar->dp.mac_id + i,
1145						       HAL_RXDMA_MONITOR_STATUS,
1146						       rx_buf_sz, &tlv_filter);
1147
1148		if (ret) {
1149			ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1150			goto out;
1151		}
1152	}
1153
1154	ath11k_info(ab, "pktlog mode %s\n",
1155		    ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1156
1157	ar->debug.pktlog_filter = filter;
1158	ar->debug.pktlog_mode = mode;
1159	ret = count;
1160
1161out:
1162	mutex_unlock(&ar->conf_mutex);
1163	return ret;
1164}
1165
1166static ssize_t ath11k_read_pktlog_filter(struct file *file,
1167					 char __user *ubuf,
1168					 size_t count, loff_t *ppos)
1169
1170{
1171	char buf[32] = {0};
1172	struct ath11k *ar = file->private_data;
1173	int len = 0;
1174
1175	mutex_lock(&ar->conf_mutex);
1176	len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1177			ar->debug.pktlog_filter,
1178			ar->debug.pktlog_mode);
1179	mutex_unlock(&ar->conf_mutex);
1180
1181	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1182}
1183
1184static const struct file_operations fops_pktlog_filter = {
1185	.read = ath11k_read_pktlog_filter,
1186	.write = ath11k_write_pktlog_filter,
1187	.open = simple_open
1188};
1189
1190static ssize_t ath11k_write_simulate_radar(struct file *file,
1191					   const char __user *user_buf,
1192					   size_t count, loff_t *ppos)
1193{
1194	struct ath11k *ar = file->private_data;
1195	int ret;
1196
1197	ret = ath11k_wmi_simulate_radar(ar);
1198	if (ret)
1199		return ret;
1200
1201	return count;
1202}
1203
1204static const struct file_operations fops_simulate_radar = {
1205	.write = ath11k_write_simulate_radar,
1206	.open = simple_open
1207};
1208
1209static ssize_t ath11k_debug_dump_dbr_entries(struct file *file,
1210					     char __user *user_buf,
1211					     size_t count, loff_t *ppos)
1212{
1213	struct ath11k_dbg_dbr_data *dbr_dbg_data = file->private_data;
1214	static const char * const event_id_to_string[] = {"empty", "Rx", "Replenish"};
1215	int size = ATH11K_DEBUG_DBR_ENTRIES_MAX * 100;
1216	char *buf;
1217	int i, ret;
1218	int len = 0;
1219
1220	buf = kzalloc(size, GFP_KERNEL);
1221	if (!buf)
1222		return -ENOMEM;
1223
1224	len += scnprintf(buf + len, size - len,
1225			 "-----------------------------------------\n");
1226	len += scnprintf(buf + len, size - len,
1227			 "| idx |  hp  |  tp  | timestamp |  event |\n");
1228	len += scnprintf(buf + len, size - len,
1229			 "-----------------------------------------\n");
1230
1231	spin_lock_bh(&dbr_dbg_data->lock);
1232
1233	for (i = 0; i < dbr_dbg_data->num_ring_debug_entries; i++) {
1234		len += scnprintf(buf + len, size - len,
1235				 "|%4u|%8u|%8u|%11llu|%8s|\n", i,
1236				 dbr_dbg_data->entries[i].hp,
1237				 dbr_dbg_data->entries[i].tp,
1238				 dbr_dbg_data->entries[i].timestamp,
1239				 event_id_to_string[dbr_dbg_data->entries[i].event]);
1240	}
1241
1242	spin_unlock_bh(&dbr_dbg_data->lock);
1243
1244	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1245	kfree(buf);
1246
1247	return ret;
1248}
1249
1250static const struct file_operations fops_debug_dump_dbr_entries = {
1251	.read = ath11k_debug_dump_dbr_entries,
1252	.open = simple_open,
1253	.owner = THIS_MODULE,
1254	.llseek = default_llseek,
1255};
1256
1257static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id)
1258{
1259	struct ath11k_debug_dbr *dbr_debug;
1260	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1261
1262	if (!ar->debug.dbr_debug[dbr_id])
1263		return;
1264
1265	dbr_debug = ar->debug.dbr_debug[dbr_id];
1266	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1267
1268	debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1269	kfree(dbr_dbg_data->entries);
1270	kfree(dbr_debug);
1271	ar->debug.dbr_debug[dbr_id] = NULL;
1272}
1273
1274static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id)
1275{
1276	struct ath11k_debug_dbr *dbr_debug;
1277	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1278	static const char * const dbr_id_to_str[] = {"spectral", "CFR"};
1279
1280	if (ar->debug.dbr_debug[dbr_id])
1281		return 0;
1282
1283	ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug),
1284					      GFP_KERNEL);
1285
1286	if (!ar->debug.dbr_debug[dbr_id])
1287		return -ENOMEM;
1288
1289	dbr_debug = ar->debug.dbr_debug[dbr_id];
1290	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1291
1292	if (dbr_debug->dbr_debugfs)
1293		return 0;
1294
1295	dbr_debug->dbr_debugfs = debugfs_create_dir(dbr_id_to_str[dbr_id],
1296						    ar->debug.debugfs_pdev);
1297	if (IS_ERR_OR_NULL(dbr_debug->dbr_debugfs)) {
1298		if (IS_ERR(dbr_debug->dbr_debugfs))
1299			return PTR_ERR(dbr_debug->dbr_debugfs);
1300		return -ENOMEM;
1301	}
1302
1303	dbr_debug->dbr_debug_enabled = true;
1304	dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX;
1305	dbr_dbg_data->dbr_debug_idx = 0;
1306	dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX,
1307					sizeof(struct ath11k_dbg_dbr_entry),
1308					GFP_KERNEL);
1309	if (!dbr_dbg_data->entries)
1310		return -ENOMEM;
1311
1312	spin_lock_init(&dbr_dbg_data->lock);
1313
1314	debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs,
1315			    dbr_dbg_data, &fops_debug_dump_dbr_entries);
1316
1317	return 0;
1318}
1319
1320static ssize_t ath11k_debugfs_write_enable_dbr_dbg(struct file *file,
1321						   const char __user *ubuf,
1322						   size_t count, loff_t *ppos)
1323{
1324	struct ath11k *ar = file->private_data;
1325	char buf[32] = {0};
1326	u32 dbr_id, enable;
1327	int ret;
1328
1329	mutex_lock(&ar->conf_mutex);
1330
1331	if (ar->state != ATH11K_STATE_ON) {
1332		ret = -ENETDOWN;
1333		goto out;
1334	}
1335
1336	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1337	if (ret < 0)
1338		goto out;
1339
1340	buf[ret] = '\0';
1341	ret = sscanf(buf, "%u %u", &dbr_id, &enable);
1342	if (ret != 2 || dbr_id > 1 || enable > 1) {
1343		ret = -EINVAL;
1344		ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
1345		goto out;
1346	}
1347
1348	if (enable) {
1349		ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id);
1350		if (ret) {
1351			ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n",
1352				    ret);
1353			goto out;
1354		}
1355	} else {
1356		ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id);
1357	}
1358
1359	ret = count;
1360out:
1361	mutex_unlock(&ar->conf_mutex);
1362	return ret;
1363}
1364
1365static const struct file_operations fops_dbr_debug = {
1366	.write = ath11k_debugfs_write_enable_dbr_dbg,
1367	.open = simple_open,
1368	.owner = THIS_MODULE,
1369	.llseek = default_llseek,
1370};
1371
1372static ssize_t ath11k_write_ps_timekeeper_enable(struct file *file,
1373						 const char __user *user_buf,
1374						 size_t count, loff_t *ppos)
1375{
1376	struct ath11k *ar = file->private_data;
1377	ssize_t ret;
1378	u8 ps_timekeeper_enable;
1379
1380	if (kstrtou8_from_user(user_buf, count, 0, &ps_timekeeper_enable))
1381		return -EINVAL;
1382
1383	mutex_lock(&ar->conf_mutex);
1384
1385	if (ar->state != ATH11K_STATE_ON) {
1386		ret = -ENETDOWN;
1387		goto exit;
1388	}
1389
1390	if (!ar->ps_state_enable) {
1391		ret = -EINVAL;
1392		goto exit;
1393	}
1394
1395	ar->ps_timekeeper_enable = !!ps_timekeeper_enable;
1396	ret = count;
1397exit:
1398	mutex_unlock(&ar->conf_mutex);
1399
1400	return ret;
1401}
1402
1403static ssize_t ath11k_read_ps_timekeeper_enable(struct file *file,
1404						char __user *user_buf,
1405						size_t count, loff_t *ppos)
1406{
1407	struct ath11k *ar = file->private_data;
1408	char buf[32];
1409	int len;
1410
1411	mutex_lock(&ar->conf_mutex);
1412	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_timekeeper_enable);
1413	mutex_unlock(&ar->conf_mutex);
1414
1415	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1416}
1417
1418static const struct file_operations fops_ps_timekeeper_enable = {
1419	.read = ath11k_read_ps_timekeeper_enable,
1420	.write = ath11k_write_ps_timekeeper_enable,
1421	.open = simple_open,
1422	.owner = THIS_MODULE,
1423	.llseek = default_llseek,
1424};
1425
1426static void ath11k_reset_peer_ps_duration(void *data,
1427					  struct ieee80211_sta *sta)
1428{
1429	struct ath11k *ar = data;
1430	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
1431
1432	spin_lock_bh(&ar->data_lock);
1433	arsta->ps_total_duration = 0;
1434	spin_unlock_bh(&ar->data_lock);
1435}
1436
1437static ssize_t ath11k_write_reset_ps_duration(struct file *file,
1438					      const  char __user *user_buf,
1439					      size_t count, loff_t *ppos)
1440{
1441	struct ath11k *ar = file->private_data;
1442	int ret;
1443	u8 reset_ps_duration;
1444
1445	if (kstrtou8_from_user(user_buf, count, 0, &reset_ps_duration))
1446		return -EINVAL;
1447
1448	mutex_lock(&ar->conf_mutex);
1449
1450	if (ar->state != ATH11K_STATE_ON) {
1451		ret = -ENETDOWN;
1452		goto exit;
1453	}
1454
1455	if (!ar->ps_state_enable) {
1456		ret = -EINVAL;
1457		goto exit;
1458	}
1459
1460	ieee80211_iterate_stations_atomic(ar->hw,
1461					  ath11k_reset_peer_ps_duration,
1462					  ar);
1463
1464	ret = count;
1465exit:
1466	mutex_unlock(&ar->conf_mutex);
1467	return ret;
1468}
1469
1470static const struct file_operations fops_reset_ps_duration = {
1471	.write = ath11k_write_reset_ps_duration,
1472	.open = simple_open,
1473	.owner = THIS_MODULE,
1474	.llseek = default_llseek,
1475};
1476
1477static void ath11k_peer_ps_state_disable(void *data,
1478					 struct ieee80211_sta *sta)
1479{
1480	struct ath11k *ar = data;
1481	struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
1482
1483	spin_lock_bh(&ar->data_lock);
1484	arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
1485	arsta->ps_start_time = 0;
1486	arsta->ps_total_duration = 0;
1487	spin_unlock_bh(&ar->data_lock);
1488}
1489
1490static ssize_t ath11k_write_ps_state_enable(struct file *file,
1491					    const char __user *user_buf,
1492					    size_t count, loff_t *ppos)
1493{
1494	struct ath11k *ar = file->private_data;
1495	struct ath11k_pdev *pdev = ar->pdev;
1496	int ret;
1497	u32 param;
1498	u8 ps_state_enable;
1499
1500	if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
1501		return -EINVAL;
1502
1503	mutex_lock(&ar->conf_mutex);
1504
1505	ps_state_enable = !!ps_state_enable;
1506
1507	if (ar->ps_state_enable == ps_state_enable) {
1508		ret = count;
1509		goto exit;
1510	}
1511
1512	param = WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
1513	ret = ath11k_wmi_pdev_set_param(ar, param, ps_state_enable, pdev->pdev_id);
1514	if (ret) {
1515		ath11k_warn(ar->ab, "failed to enable ps_state_enable: %d\n",
1516			    ret);
1517		goto exit;
1518	}
1519	ar->ps_state_enable = ps_state_enable;
1520
1521	if (!ar->ps_state_enable) {
1522		ar->ps_timekeeper_enable = false;
1523		ieee80211_iterate_stations_atomic(ar->hw,
1524						  ath11k_peer_ps_state_disable,
1525						  ar);
1526	}
1527
1528	ret = count;
1529
1530exit:
1531	mutex_unlock(&ar->conf_mutex);
1532
1533	return ret;
1534}
1535
1536static ssize_t ath11k_read_ps_state_enable(struct file *file,
1537					   char __user *user_buf,
1538					   size_t count, loff_t *ppos)
1539{
1540	struct ath11k *ar = file->private_data;
1541	char buf[32];
1542	int len;
1543
1544	mutex_lock(&ar->conf_mutex);
1545	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_state_enable);
1546	mutex_unlock(&ar->conf_mutex);
1547
1548	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1549}
1550
1551static const struct file_operations fops_ps_state_enable = {
1552	.read = ath11k_read_ps_state_enable,
1553	.write = ath11k_write_ps_state_enable,
1554	.open = simple_open,
1555	.owner = THIS_MODULE,
1556	.llseek = default_llseek,
1557};
1558
1559int ath11k_debugfs_register(struct ath11k *ar)
1560{
1561	struct ath11k_base *ab = ar->ab;
1562	char pdev_name[5];
1563	char buf[100] = {0};
1564
1565	snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1566
1567	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1568	if (IS_ERR(ar->debug.debugfs_pdev))
1569		return PTR_ERR(ar->debug.debugfs_pdev);
1570
1571	/* Create a symlink under ieee80211/phy* */
1572	snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1573	debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1574
1575	ath11k_debugfs_htt_stats_init(ar);
1576
1577	ath11k_debugfs_fw_stats_init(ar);
1578
1579	debugfs_create_file("ext_tx_stats", 0644,
1580			    ar->debug.debugfs_pdev, ar,
1581			    &fops_extd_tx_stats);
1582	debugfs_create_file("ext_rx_stats", 0644,
1583			    ar->debug.debugfs_pdev, ar,
1584			    &fops_extd_rx_stats);
1585	debugfs_create_file("pktlog_filter", 0644,
1586			    ar->debug.debugfs_pdev, ar,
1587			    &fops_pktlog_filter);
1588	debugfs_create_file("fw_dbglog_config", 0600,
1589			    ar->debug.debugfs_pdev, ar,
1590			    &fops_fw_dbglog);
1591
1592	if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1593		debugfs_create_file("dfs_simulate_radar", 0200,
1594				    ar->debug.debugfs_pdev, ar,
1595				    &fops_simulate_radar);
1596		debugfs_create_bool("dfs_block_radar_events", 0200,
1597				    ar->debug.debugfs_pdev,
1598				    &ar->dfs_block_radar_events);
1599	}
1600
1601	if (ab->hw_params.dbr_debug_support)
1602		debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev,
1603				    ar, &fops_dbr_debug);
1604
1605	debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar,
1606			    &fops_ps_state_enable);
1607
1608	if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT,
1609		     ar->ab->wmi_ab.svc_map)) {
1610		debugfs_create_file("ps_timekeeper_enable", 0600,
1611				    ar->debug.debugfs_pdev, ar,
1612				    &fops_ps_timekeeper_enable);
1613
1614		debugfs_create_file("reset_ps_duration", 0200,
1615				    ar->debug.debugfs_pdev, ar,
1616				    &fops_reset_ps_duration);
1617	}
1618
1619	return 0;
1620}
1621
1622void ath11k_debugfs_unregister(struct ath11k *ar)
1623{
1624	struct ath11k_debug_dbr *dbr_debug;
1625	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1626	int i;
1627
1628	for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) {
1629		dbr_debug = ar->debug.dbr_debug[i];
1630		if (!dbr_debug)
1631			continue;
1632
1633		dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1634		kfree(dbr_dbg_data->entries);
1635		debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1636		kfree(dbr_debug);
1637		ar->debug.dbr_debug[i] = NULL;
1638	}
1639}
1640
1641static ssize_t ath11k_write_twt_add_dialog(struct file *file,
1642					   const char __user *ubuf,
1643					   size_t count, loff_t *ppos)
1644{
1645	struct ath11k_vif *arvif = file->private_data;
1646	struct wmi_twt_add_dialog_params params = { 0 };
1647	struct wmi_twt_enable_params twt_params = {0};
1648	struct ath11k *ar = arvif->ar;
1649	u8 buf[128] = {0};
1650	int ret;
1651
1652	if (ar->twt_enabled == 0) {
1653		ath11k_err(ar->ab, "twt support is not enabled\n");
1654		return -EOPNOTSUPP;
1655	}
1656
1657	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1658	if (ret < 0)
1659		return ret;
1660
1661	buf[ret] = '\0';
1662	ret = sscanf(buf,
1663		     "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
1664		     &params.peer_macaddr[0],
1665		     &params.peer_macaddr[1],
1666		     &params.peer_macaddr[2],
1667		     &params.peer_macaddr[3],
1668		     &params.peer_macaddr[4],
1669		     &params.peer_macaddr[5],
1670		     &params.dialog_id,
1671		     &params.wake_intvl_us,
1672		     &params.wake_intvl_mantis,
1673		     &params.wake_dura_us,
1674		     &params.sp_offset_us,
1675		     &params.twt_cmd,
1676		     &params.flag_bcast,
1677		     &params.flag_trigger,
1678		     &params.flag_flow_type,
1679		     &params.flag_protection);
1680	if (ret != 16)
1681		return -EINVAL;
1682
1683	/* In the case of station vif, TWT is entirely handled by
1684	 * the firmware based on the input parameters in the TWT enable
1685	 * WMI command that is sent to the target during assoc.
1686	 * For manually testing the TWT feature, we need to first disable
1687	 * TWT and send enable command again with TWT input parameter
1688	 * sta_cong_timer_ms set to 0.
1689	 */
1690	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1691		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1692
1693		ath11k_wmi_fill_default_twt_params(&twt_params);
1694		twt_params.sta_cong_timer_ms = 0;
1695
1696		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1697	}
1698
1699	params.vdev_id = arvif->vdev_id;
1700
1701	ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, &params);
1702	if (ret)
1703		goto err_twt_add_dialog;
1704
1705	return count;
1706
1707err_twt_add_dialog:
1708	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1709		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1710		ath11k_wmi_fill_default_twt_params(&twt_params);
1711		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1712	}
1713
1714	return ret;
1715}
1716
1717static ssize_t ath11k_write_twt_del_dialog(struct file *file,
1718					   const char __user *ubuf,
1719					   size_t count, loff_t *ppos)
1720{
1721	struct ath11k_vif *arvif = file->private_data;
1722	struct wmi_twt_del_dialog_params params = { 0 };
1723	struct wmi_twt_enable_params twt_params = {0};
1724	struct ath11k *ar = arvif->ar;
1725	u8 buf[64] = {0};
1726	int ret;
1727
1728	if (ar->twt_enabled == 0) {
1729		ath11k_err(ar->ab, "twt support is not enabled\n");
1730		return -EOPNOTSUPP;
1731	}
1732
1733	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1734	if (ret < 0)
1735		return ret;
1736
1737	buf[ret] = '\0';
1738	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1739		     &params.peer_macaddr[0],
1740		     &params.peer_macaddr[1],
1741		     &params.peer_macaddr[2],
1742		     &params.peer_macaddr[3],
1743		     &params.peer_macaddr[4],
1744		     &params.peer_macaddr[5],
1745		     &params.dialog_id);
1746	if (ret != 7)
1747		return -EINVAL;
1748
1749	params.vdev_id = arvif->vdev_id;
1750
1751	ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, &params);
1752	if (ret)
1753		return ret;
1754
1755	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1756		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1757		ath11k_wmi_fill_default_twt_params(&twt_params);
1758		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1759	}
1760
1761	return count;
1762}
1763
1764static ssize_t ath11k_write_twt_pause_dialog(struct file *file,
1765					     const char __user *ubuf,
1766					     size_t count, loff_t *ppos)
1767{
1768	struct ath11k_vif *arvif = file->private_data;
1769	struct wmi_twt_pause_dialog_params params = { 0 };
1770	u8 buf[64] = {0};
1771	int ret;
1772
1773	if (arvif->ar->twt_enabled == 0) {
1774		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1775		return -EOPNOTSUPP;
1776	}
1777
1778	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1779	if (ret < 0)
1780		return ret;
1781
1782	buf[ret] = '\0';
1783	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1784		     &params.peer_macaddr[0],
1785		     &params.peer_macaddr[1],
1786		     &params.peer_macaddr[2],
1787		     &params.peer_macaddr[3],
1788		     &params.peer_macaddr[4],
1789		     &params.peer_macaddr[5],
1790		     &params.dialog_id);
1791	if (ret != 7)
1792		return -EINVAL;
1793
1794	params.vdev_id = arvif->vdev_id;
1795
1796	ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, &params);
1797	if (ret)
1798		return ret;
1799
1800	return count;
1801}
1802
1803static ssize_t ath11k_write_twt_resume_dialog(struct file *file,
1804					      const char __user *ubuf,
1805					      size_t count, loff_t *ppos)
1806{
1807	struct ath11k_vif *arvif = file->private_data;
1808	struct wmi_twt_resume_dialog_params params = { 0 };
1809	u8 buf[64] = {0};
1810	int ret;
1811
1812	if (arvif->ar->twt_enabled == 0) {
1813		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1814		return -EOPNOTSUPP;
1815	}
1816
1817	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1818	if (ret < 0)
1819		return ret;
1820
1821	buf[ret] = '\0';
1822	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
1823		     &params.peer_macaddr[0],
1824		     &params.peer_macaddr[1],
1825		     &params.peer_macaddr[2],
1826		     &params.peer_macaddr[3],
1827		     &params.peer_macaddr[4],
1828		     &params.peer_macaddr[5],
1829		     &params.dialog_id,
1830		     &params.sp_offset_us,
1831		     &params.next_twt_size);
1832	if (ret != 9)
1833		return -EINVAL;
1834
1835	params.vdev_id = arvif->vdev_id;
1836
1837	ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, &params);
1838	if (ret)
1839		return ret;
1840
1841	return count;
1842}
1843
1844static const struct file_operations ath11k_fops_twt_add_dialog = {
1845	.write = ath11k_write_twt_add_dialog,
1846	.open = simple_open
1847};
1848
1849static const struct file_operations ath11k_fops_twt_del_dialog = {
1850	.write = ath11k_write_twt_del_dialog,
1851	.open = simple_open
1852};
1853
1854static const struct file_operations ath11k_fops_twt_pause_dialog = {
1855	.write = ath11k_write_twt_pause_dialog,
1856	.open = simple_open
1857};
1858
1859static const struct file_operations ath11k_fops_twt_resume_dialog = {
1860	.write = ath11k_write_twt_resume_dialog,
1861	.open = simple_open
1862};
1863
1864void ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
 
1865{
 
1866	struct ath11k_base *ab = arvif->ar->ab;
 
1867
1868	if (arvif->vif->type != NL80211_IFTYPE_AP &&
1869	    !(arvif->vif->type == NL80211_IFTYPE_STATION &&
1870	      test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map)))
1871		return;
1872
1873	arvif->debugfs_twt = debugfs_create_dir("twt",
1874						arvif->vif->debugfs_dir);
1875	debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt,
1876			    arvif, &ath11k_fops_twt_add_dialog);
1877
1878	debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt,
1879			    arvif, &ath11k_fops_twt_del_dialog);
1880
1881	debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt,
1882			    arvif, &ath11k_fops_twt_pause_dialog);
1883
1884	debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt,
1885			    arvif, &ath11k_fops_twt_resume_dialog);
1886}
1887
1888void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif)
1889{
1890	if (!arvif->debugfs_twt)
1891		return;
1892
1893	debugfs_remove_recursive(arvif->debugfs_twt);
1894	arvif->debugfs_twt = NULL;
1895}