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 * 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