Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   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}