File Index
Files and directories
Sign in
FILE

debugfs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/ath/ath12k/debugfs.c C
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/*
   3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
   4 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
   5 */
   6
   7#include "core.h"
   8#include "dp_tx.h"
   9#include "debug.h"
  10#include "debugfs.h"
  11#include "debugfs_htt_stats.h"
  12
  13static ssize_t ath12k_write_simulate_radar(struct file *file,
  14					   const char __user *user_buf,
  15					   size_t count, loff_t *ppos)
  16{
  17	struct ath12k *ar = file->private_data;
  18	int ret;
  19
  20	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
  21	ret = ath12k_wmi_simulate_radar(ar);
  22	if (ret)
  23		goto exit;
  24
  25	ret = count;
  26exit:
  27	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
  28	return ret;
  29}
  30
  31static const struct file_operations fops_simulate_radar = {
  32	.write = ath12k_write_simulate_radar,
  33	.open = simple_open
  34};
  35
  36static ssize_t ath12k_read_simulate_fw_crash(struct file *file,
  37					     char __user *user_buf,
  38					     size_t count, loff_t *ppos)
  39{
  40	const char buf[] =
  41		"To simulate firmware crash write one of the keywords to this file:\n"
  42		"`assert` - send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n";
  43
  44	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
  45}
  46
  47static ssize_t
  48ath12k_write_simulate_fw_crash(struct file *file,
  49			       const char __user *user_buf,
  50			       size_t count, loff_t *ppos)
  51{
  52	struct ath12k_base *ab = file->private_data;
  53	struct ath12k_pdev *pdev;
  54	struct ath12k *ar = NULL;
  55	char buf[32] = {};
  56	int i, ret;
  57	ssize_t rc;
  58
  59	/* filter partial writes and invalid commands */
  60	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
  61		return -EINVAL;
  62
  63	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
  64	if (rc < 0)
  65		return rc;
  66
  67	/* drop the possible '\n' from the end */
  68	if (buf[*ppos - 1] == '\n')
  69		buf[*ppos - 1] = '\0';
  70
  71	for (i = 0; i < ab->num_radios; i++) {
  72		pdev = &ab->pdevs[i];
  73		ar = pdev->ar;
  74		if (ar)
  75			break;
  76	}
  77
  78	if (!ar)
  79		return -ENETDOWN;
  80
  81	if (!strcmp(buf, "assert")) {
  82		ath12k_info(ab, "simulating firmware assert crash\n");
  83		ret = ath12k_wmi_force_fw_hang_cmd(ar,
  84						   ATH12K_WMI_FW_HANG_ASSERT_TYPE,
  85						   ATH12K_WMI_FW_HANG_DELAY);
  86	} else {
  87		return -EINVAL;
  88	}
  89
  90	if (ret) {
  91		ath12k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
  92		return ret;
  93	}
  94
  95	return count;
  96}
  97
  98static const struct file_operations fops_simulate_fw_crash = {
  99	.read = ath12k_read_simulate_fw_crash,
 100	.write = ath12k_write_simulate_fw_crash,
 101	.open = simple_open,
 102	.owner = THIS_MODULE,
 103	.llseek = default_llseek,
 104};
 105
 106static ssize_t ath12k_write_tpc_stats_type(struct file *file,
 107					   const char __user *user_buf,
 108					   size_t count, loff_t *ppos)
 109{
 110	struct ath12k *ar = file->private_data;
 111	u8 type;
 112	int ret;
 113
 114	ret = kstrtou8_from_user(user_buf, count, 0, &type);
 115	if (ret)
 116		return ret;
 117
 118	if (type >= WMI_HALPHY_PDEV_TX_STATS_MAX)
 119		return -EINVAL;
 120
 121	spin_lock_bh(&ar->data_lock);
 122	ar->debug.tpc_stats_type = type;
 123	spin_unlock_bh(&ar->data_lock);
 124
 125	return count;
 126}
 127
 128static int ath12k_debug_tpc_stats_request(struct ath12k *ar)
 129{
 130	enum wmi_halphy_ctrl_path_stats_id tpc_stats_sub_id;
 131	struct ath12k_base *ab = ar->ab;
 132	int ret;
 133
 134	lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 135
 136	reinit_completion(&ar->debug.tpc_complete);
 137
 138	spin_lock_bh(&ar->data_lock);
 139	ar->debug.tpc_request = true;
 140	tpc_stats_sub_id = ar->debug.tpc_stats_type;
 141	spin_unlock_bh(&ar->data_lock);
 142
 143	ret = ath12k_wmi_send_tpc_stats_request(ar, tpc_stats_sub_id);
 144	if (ret) {
 145		ath12k_warn(ab, "failed to request pdev tpc stats: %d\n", ret);
 146		spin_lock_bh(&ar->data_lock);
 147		ar->debug.tpc_request = false;
 148		spin_unlock_bh(&ar->data_lock);
 149		return ret;
 150	}
 151
 152	return 0;
 153}
 154
 155static int ath12k_get_tpc_ctl_mode_idx(struct wmi_tpc_stats_arg *tpc_stats,
 156				       enum wmi_tpc_pream_bw pream_bw, int *mode_idx)
 157{
 158	u32 chan_freq = le32_to_cpu(tpc_stats->tpc_config.chan_freq);
 159	u8 band;
 160
 161	band = ((chan_freq > ATH12K_MIN_6GHZ_FREQ) ? NL80211_BAND_6GHZ :
 162		((chan_freq > ATH12K_MIN_5GHZ_FREQ) ? NL80211_BAND_5GHZ :
 163		NL80211_BAND_2GHZ));
 164
 165	if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
 166		switch (pream_bw) {
 167		case WMI_TPC_PREAM_HT20:
 168		case WMI_TPC_PREAM_VHT20:
 169			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT_VHT20_5GHZ_6GHZ;
 170			break;
 171		case WMI_TPC_PREAM_HE20:
 172		case WMI_TPC_PREAM_EHT20:
 173			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT20_5GHZ_6GHZ;
 174			break;
 175		case WMI_TPC_PREAM_HT40:
 176		case WMI_TPC_PREAM_VHT40:
 177			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT_VHT40_5GHZ_6GHZ;
 178			break;
 179		case WMI_TPC_PREAM_HE40:
 180		case WMI_TPC_PREAM_EHT40:
 181			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT40_5GHZ_6GHZ;
 182			break;
 183		case WMI_TPC_PREAM_VHT80:
 184			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_VHT80_5GHZ_6GHZ;
 185			break;
 186		case WMI_TPC_PREAM_EHT60:
 187			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT80_SU_PUNC20;
 188			break;
 189		case WMI_TPC_PREAM_HE80:
 190		case WMI_TPC_PREAM_EHT80:
 191			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT80_5GHZ_6GHZ;
 192			break;
 193		case WMI_TPC_PREAM_VHT160:
 194			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_VHT160_5GHZ_6GHZ;
 195			break;
 196		case WMI_TPC_PREAM_EHT120:
 197		case WMI_TPC_PREAM_EHT140:
 198			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT160_SU_PUNC20;
 199			break;
 200		case WMI_TPC_PREAM_HE160:
 201		case WMI_TPC_PREAM_EHT160:
 202			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT160_5GHZ_6GHZ;
 203			break;
 204		case WMI_TPC_PREAM_EHT200:
 205			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC120;
 206			break;
 207		case WMI_TPC_PREAM_EHT240:
 208			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC80;
 209			break;
 210		case WMI_TPC_PREAM_EHT280:
 211			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_EHT320_SU_PUNC40;
 212			break;
 213		case WMI_TPC_PREAM_EHT320:
 214			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HE_EHT320_5GHZ_6GHZ;
 215			break;
 216		default:
 217			/* for 5GHZ and 6GHZ, default case will be for OFDM */
 218			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_LEGACY_5GHZ_6GHZ;
 219			break;
 220		}
 221	} else {
 222		switch (pream_bw) {
 223		case WMI_TPC_PREAM_OFDM:
 224			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_LEGACY_2GHZ;
 225			break;
 226		case WMI_TPC_PREAM_HT20:
 227		case WMI_TPC_PREAM_VHT20:
 228		case WMI_TPC_PREAM_HE20:
 229		case WMI_TPC_PREAM_EHT20:
 230			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT20_2GHZ;
 231			break;
 232		case WMI_TPC_PREAM_HT40:
 233		case WMI_TPC_PREAM_VHT40:
 234		case WMI_TPC_PREAM_HE40:
 235		case WMI_TPC_PREAM_EHT40:
 236			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_HT40_2GHZ;
 237			break;
 238		default:
 239			/* for 2GHZ, default case will be CCK */
 240			*mode_idx = ATH12K_TPC_STATS_CTL_MODE_CCK_2GHZ;
 241			break;
 242		}
 243	}
 244
 245	return 0;
 246}
 247
 248static s16 ath12k_tpc_get_rate(struct ath12k *ar,
 249			       struct wmi_tpc_stats_arg *tpc_stats,
 250			       u32 rate_idx, u32 num_chains, u32 rate_code,
 251			       enum wmi_tpc_pream_bw pream_bw,
 252			       enum wmi_halphy_ctrl_path_stats_id type,
 253			       u32 eht_rate_idx)
 254{
 255	u32 tot_nss, tot_modes, txbf_on_off, index_offset1, index_offset2, index_offset3;
 256	u8 chain_idx, stm_idx, num_streams;
 257	bool is_mu, txbf_enabled = 0;
 258	s8 rates_ctl_min, tpc_ctl;
 259	s16 rates, tpc, reg_pwr;
 260	u16 rate1, rate2;
 261	int mode, ret;
 262
 263	num_streams = 1 + ATH12K_HW_NSS(rate_code);
 264	chain_idx = num_chains - 1;
 265	stm_idx = num_streams - 1;
 266	mode = -1;
 267
 268	ret = ath12k_get_tpc_ctl_mode_idx(tpc_stats, pream_bw, &mode);
 269	if (ret) {
 270		ath12k_warn(ar->ab, "Invalid mode index received\n");
 271		tpc = TPC_INVAL;
 272		goto out;
 273	}
 274
 275	if (num_chains < num_streams) {
 276		tpc = TPC_INVAL;
 277		goto out;
 278	}
 279
 280	if (le32_to_cpu(tpc_stats->tpc_config.num_tx_chain) <= 1) {
 281		tpc = TPC_INVAL;
 282		goto out;
 283	}
 284
 285	if (type == WMI_HALPHY_PDEV_TX_SUTXBF_STATS ||
 286	    type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS)
 287		txbf_enabled = 1;
 288
 289	if (type == WMI_HALPHY_PDEV_TX_MU_STATS ||
 290	    type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS) {
 291		is_mu = true;
 292	} else {
 293		is_mu = false;
 294	}
 295
 296	/* Below is the min calculation of ctl array, rates array and
 297	 * regulator power table. tpc is minimum of all 3
 298	 */
 299	if (pream_bw >= WMI_TPC_PREAM_EHT20 && pream_bw <= WMI_TPC_PREAM_EHT320) {
 300		rate2 = tpc_stats->rates_array2.rate_array[eht_rate_idx];
 301		if (is_mu)
 302			rates = u32_get_bits(rate2, ATH12K_TPC_RATE_ARRAY_MU);
 303		else
 304			rates = u32_get_bits(rate2, ATH12K_TPC_RATE_ARRAY_SU);
 305	} else {
 306		rate1 = tpc_stats->rates_array1.rate_array[rate_idx];
 307		if (is_mu)
 308			rates = u32_get_bits(rate1, ATH12K_TPC_RATE_ARRAY_MU);
 309		else
 310			rates = u32_get_bits(rate1, ATH12K_TPC_RATE_ARRAY_SU);
 311	}
 312
 313	if (tpc_stats->tlvs_rcvd & WMI_TPC_CTL_PWR_ARRAY) {
 314		tot_nss = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d1);
 315		tot_modes = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d2);
 316		txbf_on_off = le32_to_cpu(tpc_stats->ctl_array.tpc_ctl_pwr.d3);
 317		index_offset1 = txbf_on_off * tot_modes * tot_nss;
 318		index_offset2 = tot_modes * tot_nss;
 319		index_offset3 = tot_nss;
 320
 321		tpc_ctl = *(tpc_stats->ctl_array.ctl_pwr_table +
 322			    chain_idx * index_offset1 + txbf_enabled * index_offset2
 323			    + mode * index_offset3 + stm_idx);
 324	} else {
 325		tpc_ctl = TPC_MAX;
 326		ath12k_warn(ar->ab,
 327			    "ctl array for tpc stats not received from fw\n");
 328	}
 329
 330	rates_ctl_min = min_t(s16, rates, tpc_ctl);
 331
 332	reg_pwr = tpc_stats->max_reg_allowed_power.reg_pwr_array[chain_idx];
 333
 334	if (reg_pwr < 0)
 335		reg_pwr = TPC_INVAL;
 336
 337	tpc = min_t(s16, rates_ctl_min, reg_pwr);
 338
 339	/* MODULATION_LIMIT is the maximum power limit,tpc should not exceed
 340	 * modulation limit even if min tpc of all three array is greater
 341	 * modulation limit
 342	 */
 343	tpc = min_t(s16, tpc, MODULATION_LIMIT);
 344
 345out:
 346	return tpc;
 347}
 348
 349static u16 ath12k_get_ratecode(u16 pream_idx, u16 nss, u16 mcs_rate)
 350{
 351	u16 mode_type = ~0;
 352
 353	/* Below assignments are just for printing purpose only */
 354	switch (pream_idx) {
 355	case WMI_TPC_PREAM_CCK:
 356		mode_type = WMI_RATE_PREAMBLE_CCK;
 357		break;
 358	case WMI_TPC_PREAM_OFDM:
 359		mode_type = WMI_RATE_PREAMBLE_OFDM;
 360		break;
 361	case WMI_TPC_PREAM_HT20:
 362	case WMI_TPC_PREAM_HT40:
 363		mode_type = WMI_RATE_PREAMBLE_HT;
 364		break;
 365	case WMI_TPC_PREAM_VHT20:
 366	case WMI_TPC_PREAM_VHT40:
 367	case WMI_TPC_PREAM_VHT80:
 368	case WMI_TPC_PREAM_VHT160:
 369		mode_type = WMI_RATE_PREAMBLE_VHT;
 370		break;
 371	case WMI_TPC_PREAM_HE20:
 372	case WMI_TPC_PREAM_HE40:
 373	case WMI_TPC_PREAM_HE80:
 374	case WMI_TPC_PREAM_HE160:
 375		mode_type = WMI_RATE_PREAMBLE_HE;
 376		break;
 377	case WMI_TPC_PREAM_EHT20:
 378	case WMI_TPC_PREAM_EHT40:
 379	case WMI_TPC_PREAM_EHT60:
 380	case WMI_TPC_PREAM_EHT80:
 381	case WMI_TPC_PREAM_EHT120:
 382	case WMI_TPC_PREAM_EHT140:
 383	case WMI_TPC_PREAM_EHT160:
 384	case WMI_TPC_PREAM_EHT200:
 385	case WMI_TPC_PREAM_EHT240:
 386	case WMI_TPC_PREAM_EHT280:
 387	case WMI_TPC_PREAM_EHT320:
 388		mode_type = WMI_RATE_PREAMBLE_EHT;
 389		if (mcs_rate == 0 || mcs_rate == 1)
 390			mcs_rate += 14;
 391		else
 392			mcs_rate -= 2;
 393		break;
 394	default:
 395		return mode_type;
 396	}
 397	return ((mode_type << 8) | ((nss & 0x7) << 5) | (mcs_rate & 0x1F));
 398}
 399
 400static bool ath12k_he_supports_extra_mcs(struct ath12k *ar, int freq)
 401{
 402	struct ath12k_pdev_cap *cap = &ar->pdev->cap;
 403	struct ath12k_band_cap *cap_band;
 404	bool extra_mcs_supported;
 405
 406	if (freq <= ATH12K_2GHZ_MAX_FREQUENCY)
 407		cap_band = &cap->band[NL80211_BAND_2GHZ];
 408	else if (freq <= ATH12K_5GHZ_MAX_FREQUENCY)
 409		cap_band = &cap->band[NL80211_BAND_5GHZ];
 410	else
 411		cap_band = &cap->band[NL80211_BAND_6GHZ];
 412
 413	extra_mcs_supported = u32_get_bits(cap_band->he_cap_info[1],
 414					   HE_EXTRA_MCS_SUPPORT);
 415	return extra_mcs_supported;
 416}
 417
 418static int ath12k_tpc_fill_pream(struct ath12k *ar, char *buf, int buf_len, int len,
 419				 enum wmi_tpc_pream_bw pream_bw, u32 max_rix,
 420				 int max_nss, int max_rates, int pream_type,
 421				 enum wmi_halphy_ctrl_path_stats_id tpc_type,
 422				 int rate_idx, int eht_rate_idx)
 423{
 424	struct wmi_tpc_stats_arg *tpc_stats = ar->debug.tpc_stats;
 425	int nss, rates, chains;
 426	u8 active_tx_chains;
 427	u16 rate_code;
 428	s16 tpc;
 429
 430	static const char *const pream_str[] = {
 431		[WMI_TPC_PREAM_CCK]     = "CCK",
 432		[WMI_TPC_PREAM_OFDM]    = "OFDM",
 433		[WMI_TPC_PREAM_HT20]    = "HT20",
 434		[WMI_TPC_PREAM_HT40]    = "HT40",
 435		[WMI_TPC_PREAM_VHT20]   = "VHT20",
 436		[WMI_TPC_PREAM_VHT40]   = "VHT40",
 437		[WMI_TPC_PREAM_VHT80]   = "VHT80",
 438		[WMI_TPC_PREAM_VHT160]  = "VHT160",
 439		[WMI_TPC_PREAM_HE20]    = "HE20",
 440		[WMI_TPC_PREAM_HE40]    = "HE40",
 441		[WMI_TPC_PREAM_HE80]    = "HE80",
 442		[WMI_TPC_PREAM_HE160]   = "HE160",
 443		[WMI_TPC_PREAM_EHT20]   = "EHT20",
 444		[WMI_TPC_PREAM_EHT40]   = "EHT40",
 445		[WMI_TPC_PREAM_EHT60]   = "EHT60",
 446		[WMI_TPC_PREAM_EHT80]   = "EHT80",
 447		[WMI_TPC_PREAM_EHT120]   = "EHT120",
 448		[WMI_TPC_PREAM_EHT140]   = "EHT140",
 449		[WMI_TPC_PREAM_EHT160]   = "EHT160",
 450		[WMI_TPC_PREAM_EHT200]   = "EHT200",
 451		[WMI_TPC_PREAM_EHT240]   = "EHT240",
 452		[WMI_TPC_PREAM_EHT280]   = "EHT280",
 453		[WMI_TPC_PREAM_EHT320]   = "EHT320"};
 454
 455	active_tx_chains = ar->num_tx_chains;
 456
 457	for (nss = 0; nss < max_nss; nss++) {
 458		for (rates = 0; rates < max_rates; rates++, rate_idx++, max_rix++) {
 459			/* FW send extra MCS(10&11) for VHT and HE rates,
 460			 *  this is not used. Hence skipping it here
 461			 */
 462			if (pream_type == WMI_RATE_PREAMBLE_VHT &&
 463			    rates > ATH12K_VHT_MCS_MAX)
 464				continue;
 465
 466			if (pream_type == WMI_RATE_PREAMBLE_HE &&
 467			    rates > ATH12K_HE_MCS_MAX)
 468				continue;
 469
 470			if (pream_type == WMI_RATE_PREAMBLE_EHT &&
 471			    rates > ATH12K_EHT_MCS_MAX)
 472				continue;
 473
 474			rate_code = ath12k_get_ratecode(pream_bw, nss, rates);
 475			len += scnprintf(buf + len, buf_len - len,
 476					 "%d\t %s\t 0x%03x\t", max_rix,
 477					 pream_str[pream_bw], rate_code);
 478
 479			for (chains = 0; chains < active_tx_chains; chains++) {
 480				if (nss > chains) {
 481					len += scnprintf(buf + len,
 482							 buf_len - len,
 483							 "\t%s", "NA");
 484				} else {
 485					tpc = ath12k_tpc_get_rate(ar, tpc_stats,
 486								  rate_idx, chains + 1,
 487								  rate_code, pream_bw,
 488								  tpc_type,
 489								  eht_rate_idx);
 490
 491					if (tpc == TPC_INVAL) {
 492						len += scnprintf(buf + len,
 493								 buf_len - len, "\tNA");
 494					} else {
 495						len += scnprintf(buf + len,
 496								 buf_len - len, "\t%d",
 497								 tpc);
 498					}
 499				}
 500			}
 501			len += scnprintf(buf + len, buf_len - len, "\n");
 502
 503			if (pream_type == WMI_RATE_PREAMBLE_EHT)
 504				/*For fetching the next eht rates pwr from rates array2*/
 505				++eht_rate_idx;
 506		}
 507	}
 508
 509	return len;
 510}
 511
 512static int ath12k_tpc_stats_print(struct ath12k *ar,
 513				  struct wmi_tpc_stats_arg *tpc_stats,
 514				  char *buf, size_t len,
 515				  enum wmi_halphy_ctrl_path_stats_id type)
 516{
 517	u32 eht_idx = 0, pream_idx = 0, rate_pream_idx = 0, total_rates = 0, max_rix = 0;
 518	u32 chan_freq, num_tx_chain, caps, i, j = 1;
 519	size_t buf_len = ATH12K_TPC_STATS_BUF_SIZE;
 520	u8 nss, active_tx_chains;
 521	bool he_ext_mcs;
 522	static const char *const type_str[WMI_HALPHY_PDEV_TX_STATS_MAX] = {
 523		[WMI_HALPHY_PDEV_TX_SU_STATS]		= "SU",
 524		[WMI_HALPHY_PDEV_TX_SUTXBF_STATS]	= "SU WITH TXBF",
 525		[WMI_HALPHY_PDEV_TX_MU_STATS]		= "MU",
 526		[WMI_HALPHY_PDEV_TX_MUTXBF_STATS]	= "MU WITH TXBF"};
 527
 528	u8 max_rates[WMI_TPC_PREAM_MAX] = {
 529		[WMI_TPC_PREAM_CCK]     = ATH12K_CCK_RATES,
 530		[WMI_TPC_PREAM_OFDM]    = ATH12K_OFDM_RATES,
 531		[WMI_TPC_PREAM_HT20]    = ATH12K_HT_RATES,
 532		[WMI_TPC_PREAM_HT40]    = ATH12K_HT_RATES,
 533		[WMI_TPC_PREAM_VHT20]   = ATH12K_VHT_RATES,
 534		[WMI_TPC_PREAM_VHT40]   = ATH12K_VHT_RATES,
 535		[WMI_TPC_PREAM_VHT80]   = ATH12K_VHT_RATES,
 536		[WMI_TPC_PREAM_VHT160]  = ATH12K_VHT_RATES,
 537		[WMI_TPC_PREAM_HE20]    = ATH12K_HE_RATES,
 538		[WMI_TPC_PREAM_HE40]    = ATH12K_HE_RATES,
 539		[WMI_TPC_PREAM_HE80]    = ATH12K_HE_RATES,
 540		[WMI_TPC_PREAM_HE160]   = ATH12K_HE_RATES,
 541		[WMI_TPC_PREAM_EHT20]   = ATH12K_EHT_RATES,
 542		[WMI_TPC_PREAM_EHT40]   = ATH12K_EHT_RATES,
 543		[WMI_TPC_PREAM_EHT60]   = ATH12K_EHT_RATES,
 544		[WMI_TPC_PREAM_EHT80]   = ATH12K_EHT_RATES,
 545		[WMI_TPC_PREAM_EHT120]  = ATH12K_EHT_RATES,
 546		[WMI_TPC_PREAM_EHT140]  = ATH12K_EHT_RATES,
 547		[WMI_TPC_PREAM_EHT160]  = ATH12K_EHT_RATES,
 548		[WMI_TPC_PREAM_EHT200]  = ATH12K_EHT_RATES,
 549		[WMI_TPC_PREAM_EHT240]  = ATH12K_EHT_RATES,
 550		[WMI_TPC_PREAM_EHT280]  = ATH12K_EHT_RATES,
 551		[WMI_TPC_PREAM_EHT320]  = ATH12K_EHT_RATES};
 552	static const u8 max_nss[WMI_TPC_PREAM_MAX] = {
 553		[WMI_TPC_PREAM_CCK]     = ATH12K_NSS_1,
 554		[WMI_TPC_PREAM_OFDM]    = ATH12K_NSS_1,
 555		[WMI_TPC_PREAM_HT20]    = ATH12K_NSS_4,
 556		[WMI_TPC_PREAM_HT40]    = ATH12K_NSS_4,
 557		[WMI_TPC_PREAM_VHT20]   = ATH12K_NSS_8,
 558		[WMI_TPC_PREAM_VHT40]   = ATH12K_NSS_8,
 559		[WMI_TPC_PREAM_VHT80]   = ATH12K_NSS_8,
 560		[WMI_TPC_PREAM_VHT160]  = ATH12K_NSS_4,
 561		[WMI_TPC_PREAM_HE20]    = ATH12K_NSS_8,
 562		[WMI_TPC_PREAM_HE40]    = ATH12K_NSS_8,
 563		[WMI_TPC_PREAM_HE80]    = ATH12K_NSS_8,
 564		[WMI_TPC_PREAM_HE160]   = ATH12K_NSS_4,
 565		[WMI_TPC_PREAM_EHT20]   = ATH12K_NSS_4,
 566		[WMI_TPC_PREAM_EHT40]   = ATH12K_NSS_4,
 567		[WMI_TPC_PREAM_EHT60]   = ATH12K_NSS_4,
 568		[WMI_TPC_PREAM_EHT80]   = ATH12K_NSS_4,
 569		[WMI_TPC_PREAM_EHT120]  = ATH12K_NSS_4,
 570		[WMI_TPC_PREAM_EHT140]  = ATH12K_NSS_4,
 571		[WMI_TPC_PREAM_EHT160]  = ATH12K_NSS_4,
 572		[WMI_TPC_PREAM_EHT200]  = ATH12K_NSS_4,
 573		[WMI_TPC_PREAM_EHT240]  = ATH12K_NSS_4,
 574		[WMI_TPC_PREAM_EHT280]  = ATH12K_NSS_4,
 575		[WMI_TPC_PREAM_EHT320]  = ATH12K_NSS_4};
 576
 577	u16 rate_idx[WMI_TPC_PREAM_MAX] = {}, eht_rate_idx[WMI_TPC_PREAM_MAX] = {};
 578	static const u8 pream_type[WMI_TPC_PREAM_MAX] = {
 579		[WMI_TPC_PREAM_CCK]     = WMI_RATE_PREAMBLE_CCK,
 580		[WMI_TPC_PREAM_OFDM]    = WMI_RATE_PREAMBLE_OFDM,
 581		[WMI_TPC_PREAM_HT20]    = WMI_RATE_PREAMBLE_HT,
 582		[WMI_TPC_PREAM_HT40]    = WMI_RATE_PREAMBLE_HT,
 583		[WMI_TPC_PREAM_VHT20]   = WMI_RATE_PREAMBLE_VHT,
 584		[WMI_TPC_PREAM_VHT40]   = WMI_RATE_PREAMBLE_VHT,
 585		[WMI_TPC_PREAM_VHT80]   = WMI_RATE_PREAMBLE_VHT,
 586		[WMI_TPC_PREAM_VHT160]  = WMI_RATE_PREAMBLE_VHT,
 587		[WMI_TPC_PREAM_HE20]    = WMI_RATE_PREAMBLE_HE,
 588		[WMI_TPC_PREAM_HE40]    = WMI_RATE_PREAMBLE_HE,
 589		[WMI_TPC_PREAM_HE80]    = WMI_RATE_PREAMBLE_HE,
 590		[WMI_TPC_PREAM_HE160]   = WMI_RATE_PREAMBLE_HE,
 591		[WMI_TPC_PREAM_EHT20]   = WMI_RATE_PREAMBLE_EHT,
 592		[WMI_TPC_PREAM_EHT40]   = WMI_RATE_PREAMBLE_EHT,
 593		[WMI_TPC_PREAM_EHT60]   = WMI_RATE_PREAMBLE_EHT,
 594		[WMI_TPC_PREAM_EHT80]   = WMI_RATE_PREAMBLE_EHT,
 595		[WMI_TPC_PREAM_EHT120]  = WMI_RATE_PREAMBLE_EHT,
 596		[WMI_TPC_PREAM_EHT140]  = WMI_RATE_PREAMBLE_EHT,
 597		[WMI_TPC_PREAM_EHT160]  = WMI_RATE_PREAMBLE_EHT,
 598		[WMI_TPC_PREAM_EHT200]  = WMI_RATE_PREAMBLE_EHT,
 599		[WMI_TPC_PREAM_EHT240]  = WMI_RATE_PREAMBLE_EHT,
 600		[WMI_TPC_PREAM_EHT280]  = WMI_RATE_PREAMBLE_EHT,
 601		[WMI_TPC_PREAM_EHT320]  = WMI_RATE_PREAMBLE_EHT};
 602
 603	chan_freq = le32_to_cpu(tpc_stats->tpc_config.chan_freq);
 604	num_tx_chain = le32_to_cpu(tpc_stats->tpc_config.num_tx_chain);
 605	caps = le32_to_cpu(tpc_stats->tpc_config.caps);
 606
 607	active_tx_chains = ar->num_tx_chains;
 608	he_ext_mcs = ath12k_he_supports_extra_mcs(ar, chan_freq);
 609
 610	/* mcs 12&13 is sent by FW for certain HWs in rate array, skipping it as
 611	 * it is not supported
 612	 */
 613	if (he_ext_mcs) {
 614		for (i = WMI_TPC_PREAM_HE20; i <= WMI_TPC_PREAM_HE160; ++i)
 615			max_rates[i] = ATH12K_HE_RATES;
 616	}
 617
 618	if (type == WMI_HALPHY_PDEV_TX_MU_STATS ||
 619	    type == WMI_HALPHY_PDEV_TX_MUTXBF_STATS) {
 620		pream_idx = WMI_TPC_PREAM_VHT20;
 621
 622		for (i = WMI_TPC_PREAM_CCK; i <= WMI_TPC_PREAM_HT40; ++i)
 623			max_rix += max_nss[i] * max_rates[i];
 624	}
 625	/* Enumerate all the rate indices */
 626	for (i = rate_pream_idx + 1; i < WMI_TPC_PREAM_MAX; i++) {
 627		nss = (max_nss[i - 1] < num_tx_chain ?
 628		       max_nss[i - 1] : num_tx_chain);
 629
 630		rate_idx[i] = rate_idx[i - 1] + max_rates[i - 1] * nss;
 631
 632		if (pream_type[i] == WMI_RATE_PREAMBLE_EHT) {
 633			eht_rate_idx[j] = eht_rate_idx[j - 1] + max_rates[i] * nss;
 634			++j;
 635		}
 636	}
 637
 638	for (i = 0; i < WMI_TPC_PREAM_MAX; i++) {
 639		nss = (max_nss[i] < num_tx_chain ?
 640		       max_nss[i] : num_tx_chain);
 641		total_rates += max_rates[i] * nss;
 642	}
 643
 644	len += scnprintf(buf + len, buf_len - len,
 645			 "No.of rates-%d\n", total_rates);
 646
 647	len += scnprintf(buf + len, buf_len - len,
 648			 "**************** %s ****************\n",
 649			 type_str[type]);
 650	len += scnprintf(buf + len, buf_len - len,
 651			 "\t\t\t\tTPC values for Active chains\n");
 652	len += scnprintf(buf + len, buf_len - len,
 653			 "Rate idx Preamble Rate code");
 654
 655	for (i = 1; i <= active_tx_chains; ++i) {
 656		len += scnprintf(buf + len, buf_len - len,
 657				 "\t%d-Chain", i);
 658	}
 659
 660	len += scnprintf(buf + len, buf_len - len, "\n");
 661	for (i = pream_idx; i < WMI_TPC_PREAM_MAX; i++) {
 662		if (chan_freq <= 2483) {
 663			if (i == WMI_TPC_PREAM_VHT80 ||
 664			    i == WMI_TPC_PREAM_VHT160 ||
 665			    i == WMI_TPC_PREAM_HE80 ||
 666			    i == WMI_TPC_PREAM_HE160 ||
 667			    (i >= WMI_TPC_PREAM_EHT60 &&
 668			     i <= WMI_TPC_PREAM_EHT320)) {
 669				max_rix += max_nss[i] * max_rates[i];
 670				continue;
 671			}
 672		} else {
 673			if (i == WMI_TPC_PREAM_CCK) {
 674				max_rix += max_rates[i];
 675				continue;
 676			}
 677		}
 678
 679		nss = (max_nss[i] < ar->num_tx_chains ? max_nss[i] : ar->num_tx_chains);
 680
 681		if (!(caps &
 682		    (1 << ATH12K_TPC_STATS_SUPPORT_BE_PUNC))) {
 683			if (i == WMI_TPC_PREAM_EHT60 || i == WMI_TPC_PREAM_EHT120 ||
 684			    i == WMI_TPC_PREAM_EHT140 || i == WMI_TPC_PREAM_EHT200 ||
 685			    i == WMI_TPC_PREAM_EHT240 || i == WMI_TPC_PREAM_EHT280) {
 686				max_rix += max_nss[i] * max_rates[i];
 687				continue;
 688			}
 689		}
 690
 691		len = ath12k_tpc_fill_pream(ar, buf, buf_len, len, i, max_rix, nss,
 692					    max_rates[i], pream_type[i],
 693					    type, rate_idx[i], eht_rate_idx[eht_idx]);
 694
 695		if (pream_type[i] == WMI_RATE_PREAMBLE_EHT)
 696			/*For fetch the next index eht rates from rates array2*/
 697			++eht_idx;
 698
 699		max_rix += max_nss[i] * max_rates[i];
 700	}
 701	return len;
 702}
 703
 704static void ath12k_tpc_stats_fill(struct ath12k *ar,
 705				  struct wmi_tpc_stats_arg *tpc_stats,
 706				  char *buf)
 707{
 708	size_t buf_len = ATH12K_TPC_STATS_BUF_SIZE;
 709	struct wmi_tpc_config_params *tpc;
 710	size_t len = 0;
 711
 712	if (!tpc_stats) {
 713		ath12k_warn(ar->ab, "failed to find tpc stats\n");
 714		return;
 715	}
 716
 717	spin_lock_bh(&ar->data_lock);
 718
 719	tpc = &tpc_stats->tpc_config;
 720	len += scnprintf(buf + len, buf_len - len, "\n");
 721	len += scnprintf(buf + len, buf_len - len,
 722			 "*************** TPC config **************\n");
 723	len += scnprintf(buf + len, buf_len - len,
 724			 "* powers are in 0.25 dBm steps\n");
 725	len += scnprintf(buf + len, buf_len - len,
 726			 "reg domain-%d\t\tchan freq-%d\n",
 727			 tpc->reg_domain, tpc->chan_freq);
 728	len += scnprintf(buf + len, buf_len - len,
 729			 "power limit-%d\t\tmax reg-domain Power-%d\n",
 730			 le32_to_cpu(tpc->twice_max_reg_power) / 2, tpc->power_limit);
 731	len += scnprintf(buf + len, buf_len - len,
 732			 "No.of tx chain-%d\t",
 733			 ar->num_tx_chains);
 734
 735	ath12k_tpc_stats_print(ar, tpc_stats, buf, len,
 736			       ar->debug.tpc_stats_type);
 737
 738	spin_unlock_bh(&ar->data_lock);
 739}
 740
 741static int ath12k_open_tpc_stats(struct inode *inode, struct file *file)
 742{
 743	struct ath12k *ar = inode->i_private;
 744	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
 745	int ret;
 746
 747	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
 748
 749	if (ah->state != ATH12K_HW_STATE_ON) {
 750		ath12k_warn(ar->ab, "Interface not up\n");
 751		return -ENETDOWN;
 752	}
 753
 754	void *buf __free(kfree) = kzalloc(ATH12K_TPC_STATS_BUF_SIZE, GFP_KERNEL);
 755	if (!buf)
 756		return -ENOMEM;
 757
 758	ret = ath12k_debug_tpc_stats_request(ar);
 759	if (ret) {
 760		ath12k_warn(ar->ab, "failed to request tpc stats: %d\n",
 761			    ret);
 762		return ret;
 763	}
 764
 765	if (!wait_for_completion_timeout(&ar->debug.tpc_complete, TPC_STATS_WAIT_TIME)) {
 766		spin_lock_bh(&ar->data_lock);
 767		ath12k_wmi_free_tpc_stats_mem(ar);
 768		ar->debug.tpc_request = false;
 769		spin_unlock_bh(&ar->data_lock);
 770		return -ETIMEDOUT;
 771	}
 772
 773	ath12k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
 774	file->private_data = no_free_ptr(buf);
 775
 776	spin_lock_bh(&ar->data_lock);
 777	ath12k_wmi_free_tpc_stats_mem(ar);
 778	spin_unlock_bh(&ar->data_lock);
 779
 780	return 0;
 781}
 782
 783static ssize_t ath12k_read_tpc_stats(struct file *file,
 784				     char __user *user_buf,
 785				     size_t count, loff_t *ppos)
 786{
 787	const char *buf = file->private_data;
 788	size_t len = strlen(buf);
 789
 790	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 791}
 792
 793static int ath12k_release_tpc_stats(struct inode *inode,
 794				    struct file *file)
 795{
 796	kfree(file->private_data);
 797	return 0;
 798}
 799
 800static const struct file_operations fops_tpc_stats = {
 801	.open = ath12k_open_tpc_stats,
 802	.release = ath12k_release_tpc_stats,
 803	.read = ath12k_read_tpc_stats,
 804	.owner = THIS_MODULE,
 805	.llseek = default_llseek,
 806};
 807
 808static const struct file_operations fops_tpc_stats_type = {
 809	.write = ath12k_write_tpc_stats_type,
 810	.open = simple_open,
 811	.llseek = default_llseek,
 812};
 813
 814static ssize_t ath12k_write_extd_rx_stats(struct file *file,
 815					  const char __user *ubuf,
 816					  size_t count, loff_t *ppos)
 817{
 818	struct ath12k *ar = file->private_data;
 819	struct htt_rx_ring_tlv_filter tlv_filter = {};
 820	u32 ring_id, rx_filter = 0;
 821	bool enable;
 822	int ret, i;
 823
 824	if (kstrtobool_from_user(ubuf, count, &enable))
 825		return -EINVAL;
 826
 827	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
 828
 829	if (!ar->ab->hw_params->rxdma1_enable) {
 830		ret = count;
 831		goto exit;
 832	}
 833
 834	if (ar->ah->state != ATH12K_HW_STATE_ON) {
 835		ret = -ENETDOWN;
 836		goto exit;
 837	}
 838
 839	if (enable == ar->debug.extd_rx_stats) {
 840		ret = count;
 841		goto exit;
 842	}
 843
 844	if (enable) {
 845		rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
 846		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
 847		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
 848		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
 849		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
 850		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
 851		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO;
 852
 853		tlv_filter.rx_filter = rx_filter;
 854		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
 855		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
 856		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
 857		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
 858			HTT_RX_FP_DATA_FILTER_FLASG3;
 859	} else {
 860		tlv_filter = ath12k_mac_mon_status_filter_default;
 861	}
 862
 863	ar->debug.rx_filter = tlv_filter.rx_filter;
 864
 865	for (i = 0; i < ar->ab->hw_params->num_rxdma_per_pdev; i++) {
 866		ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id;
 867		ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id + i,
 868						       HAL_RXDMA_MONITOR_DST,
 869						       DP_RXDMA_REFILL_RING_SIZE,
 870						       &tlv_filter);
 871		if (ret) {
 872			ath12k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
 873			goto exit;
 874		}
 875	}
 876
 877	ar->debug.extd_rx_stats = !!enable;
 878	ret = count;
 879exit:
 880	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
 881	return ret;
 882}
 883
 884static ssize_t ath12k_read_extd_rx_stats(struct file *file,
 885					 char __user *ubuf,
 886					 size_t count, loff_t *ppos)
 887{
 888	struct ath12k *ar = file->private_data;
 889	char buf[32];
 890	int len = 0;
 891
 892	wiphy_lock(ath12k_ar_to_hw(ar)->wiphy);
 893	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
 894			ar->debug.extd_rx_stats);
 895	wiphy_unlock(ath12k_ar_to_hw(ar)->wiphy);
 896
 897	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
 898}
 899
 900static const struct file_operations fops_extd_rx_stats = {
 901	.read = ath12k_read_extd_rx_stats,
 902	.write = ath12k_write_extd_rx_stats,
 903	.open = simple_open,
 904};
 905
 906static int ath12k_open_link_stats(struct inode *inode, struct file *file)
 907{
 908	struct ath12k_vif *ahvif = inode->i_private;
 909	size_t len = 0, buf_len = (PAGE_SIZE * 2);
 910	struct ath12k_link_stats linkstat;
 911	struct ath12k_link_vif *arvif;
 912	unsigned long links_map;
 913	struct wiphy *wiphy;
 914	int link_id, i;
 915	char *buf;
 916
 917	if (!ahvif)
 918		return -EINVAL;
 919
 920	buf = kzalloc(buf_len, GFP_KERNEL);
 921	if (!buf)
 922		return -ENOMEM;
 923
 924	wiphy = ahvif->ah->hw->wiphy;
 925	wiphy_lock(wiphy);
 926
 927	links_map = ahvif->links_map;
 928	for_each_set_bit(link_id, &links_map,
 929			 IEEE80211_MLD_MAX_NUM_LINKS) {
 930		arvif = rcu_dereference_protected(ahvif->link[link_id],
 931						  lockdep_is_held(&wiphy->mtx));
 932
 933		spin_lock_bh(&arvif->link_stats_lock);
 934		linkstat = arvif->link_stats;
 935		spin_unlock_bh(&arvif->link_stats_lock);
 936
 937		len += scnprintf(buf + len, buf_len - len,
 938				 "link[%d] Tx Unicast Frames Enqueued  = %d\n",
 939				 link_id, linkstat.tx_enqueued);
 940		len += scnprintf(buf + len, buf_len - len,
 941				 "link[%d] Tx Broadcast Frames Enqueued = %d\n",
 942				 link_id, linkstat.tx_bcast_mcast);
 943		len += scnprintf(buf + len, buf_len - len,
 944				 "link[%d] Tx Frames Completed = %d\n",
 945				 link_id, linkstat.tx_completed);
 946		len += scnprintf(buf + len, buf_len - len,
 947				 "link[%d] Tx Frames Dropped = %d\n",
 948				 link_id, linkstat.tx_dropped);
 949
 950		len += scnprintf(buf + len, buf_len - len,
 951				 "link[%d] Tx Frame descriptor Encap Type = ",
 952				 link_id);
 953
 954		len += scnprintf(buf + len, buf_len - len,
 955					 " raw:%d",
 956					 linkstat.tx_encap_type[0]);
 957
 958		len += scnprintf(buf + len, buf_len - len,
 959					 " native_wifi:%d",
 960					 linkstat.tx_encap_type[1]);
 961
 962		len += scnprintf(buf + len, buf_len - len,
 963					 " ethernet:%d",
 964					 linkstat.tx_encap_type[2]);
 965
 966		len += scnprintf(buf + len, buf_len - len,
 967				 "\nlink[%d] Tx Frame descriptor Encrypt Type = ",
 968				 link_id);
 969
 970		for (i = 0; i < HAL_ENCRYPT_TYPE_MAX; i++) {
 971			len += scnprintf(buf + len, buf_len - len,
 972					 " %d:%d", i,
 973					 linkstat.tx_encrypt_type[i]);
 974		}
 975		len += scnprintf(buf + len, buf_len - len,
 976				 "\nlink[%d] Tx Frame descriptor Type = buffer:%d extension:%d\n",
 977				 link_id, linkstat.tx_desc_type[0],
 978				 linkstat.tx_desc_type[1]);
 979
 980		len += scnprintf(buf + len, buf_len - len,
 981				"------------------------------------------------------\n");
 982	}
 983
 984	wiphy_unlock(wiphy);
 985
 986	file->private_data = buf;
 987
 988	return 0;
 989}
 990
 991static int ath12k_release_link_stats(struct inode *inode, struct file *file)
 992{
 993	kfree(file->private_data);
 994	return 0;
 995}
 996
 997static ssize_t ath12k_read_link_stats(struct file *file,
 998				      char __user *user_buf,
 999				      size_t count, loff_t *ppos)
1000{
1001	const char *buf = file->private_data;
1002	size_t len = strlen(buf);
1003
1004	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1005}
1006
1007static const struct file_operations ath12k_fops_link_stats = {
1008	.open = ath12k_open_link_stats,
1009	.release = ath12k_release_link_stats,
1010	.read = ath12k_read_link_stats,
1011	.owner = THIS_MODULE,
1012	.llseek = default_llseek,
1013};
1014
1015void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw,
1016			       struct ieee80211_vif *vif)
1017{
1018	struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
1019
1020	debugfs_create_file("link_stats", 0400, vif->debugfs_dir, ahvif,
1021			    &ath12k_fops_link_stats);
1022}
1023
1024static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
1025						   char __user *user_buf,
1026						   size_t count, loff_t *ppos)
1027{
1028	struct ath12k_base *ab = file->private_data;
1029	struct ath12k_device_dp_stats *device_stats = &ab->device_stats;
1030	int len = 0, i, j, ret;
1031	struct ath12k *ar;
1032	const int size = 4096;
1033	static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
1034		[HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR] = "Overflow",
1035		[HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR] = "MPDU len",
1036		[HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR] = "FCS",
1037		[HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR] = "Decrypt",
1038		[HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR] = "TKIP MIC",
1039		[HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR] = "Unencrypt",
1040		[HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR] = "MSDU len",
1041		[HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR] = "MSDU limit",
1042		[HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR] = "WiFi parse",
1043		[HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR] = "AMSDU parse",
1044		[HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR] = "SA timeout",
1045		[HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR] = "DA timeout",
1046		[HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR] = "Flow timeout",
1047		[HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR] = "Flush req",
1048		[HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR] = "AMSDU frag",
1049		[HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR] = "Multicast echo",
1050		[HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR] = "AMSDU mismatch",
1051		[HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR] = "Unauth WDS",
1052		[HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR] = "AMSDU or WDS"};
1053
1054	static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
1055		[HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO] = "Desc addr zero",
1056		[HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID] = "Desc inval",
1057		[HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA] =  "AMPDU in non BA",
1058		[HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE] = "Non BA dup",
1059		[HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE] = "BA dup",
1060		[HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP] = "Frame 2k jump",
1061		[HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP] = "BAR 2k jump",
1062		[HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR] = "Frame OOR",
1063		[HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR] = "BAR OOR",
1064		[HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION] = "No BA session",
1065		[HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN] = "Frame SN equal SSN",
1066		[HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED] = "PN check fail",
1067		[HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET] = "2k err",
1068		[HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = "PN err",
1069		[HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = "Desc blocked"};
1070
1071	static const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = {
1072		[HAL_WBM_REL_SRC_MODULE_TQM] = "TQM",
1073		[HAL_WBM_REL_SRC_MODULE_RXDMA] = "Rxdma",
1074		[HAL_WBM_REL_SRC_MODULE_REO] = "Reo",
1075		[HAL_WBM_REL_SRC_MODULE_FW] = "FW",
1076		[HAL_WBM_REL_SRC_MODULE_SW] = "SW"};
1077
1078	char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
1079
1080	if (!buf)
1081		return -ENOMEM;
1082
1083	len += scnprintf(buf + len, size - len, "DEVICE RX STATS:\n\n");
1084	len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
1085			 device_stats->err_ring_pkts);
1086	len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
1087			 device_stats->invalid_rbm);
1088	len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
1089
1090	for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
1091		len += scnprintf(buf + len, size - len, "%s: %u\n",
1092				 rxdma_err[i], device_stats->rxdma_error[i]);
1093
1094	len += scnprintf(buf + len, size - len, "\nREO errors:\n");
1095
1096	for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
1097		len += scnprintf(buf + len, size - len, "%s: %u\n",
1098				 reo_err[i], device_stats->reo_error[i]);
1099
1100	len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
1101
1102	for (i = 0; i < DP_REO_DST_RING_MAX; i++)
1103		len += scnprintf(buf + len, size - len,
1104				 "ring%d: %u\n", i,
1105				 device_stats->hal_reo_error[i]);
1106
1107	len += scnprintf(buf + len, size - len, "\nDEVICE TX STATS:\n");
1108	len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
1109
1110	for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
1111		len += scnprintf(buf + len, size - len, "ring%d: %u\n",
1112				 i, device_stats->tx_err.desc_na[i]);
1113
1114	len += scnprintf(buf + len, size - len,
1115			 "\nMisc Transmit Failures: %d\n",
1116			 atomic_read(&device_stats->tx_err.misc_fail));
1117
1118	len += scnprintf(buf + len, size - len, "\ntx_wbm_rel_source:");
1119
1120	for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++)
1121		len += scnprintf(buf + len, size - len, " %d:%u",
1122				 i, device_stats->tx_wbm_rel_source[i]);
1123
1124	len += scnprintf(buf + len, size - len, "\n");
1125
1126	len += scnprintf(buf + len, size - len, "\ntqm_rel_reason:");
1127
1128	for (i = 0; i < MAX_TQM_RELEASE_REASON; i++)
1129		len += scnprintf(buf + len, size - len, " %d:%u",
1130				 i, device_stats->tqm_rel_reason[i]);
1131
1132	len += scnprintf(buf + len, size - len, "\n");
1133
1134	len += scnprintf(buf + len, size - len, "\nfw_tx_status:");
1135
1136	for (i = 0; i < MAX_FW_TX_STATUS; i++)
1137		len += scnprintf(buf + len, size - len, " %d:%u",
1138				 i, device_stats->fw_tx_status[i]);
1139
1140	len += scnprintf(buf + len, size - len, "\n");
1141
1142	len += scnprintf(buf + len, size - len, "\ntx_enqueued:");
1143
1144	for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
1145		len += scnprintf(buf + len, size - len, " %d:%u", i,
1146				 device_stats->tx_enqueued[i]);
1147
1148	len += scnprintf(buf + len, size - len, "\n");
1149
1150	len += scnprintf(buf + len, size - len, "\ntx_completed:");
1151
1152	for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
1153		len += scnprintf(buf + len, size - len, " %d:%u",
1154				 i, device_stats->tx_completed[i]);
1155
1156	len += scnprintf(buf + len, size - len, "\n");
1157
1158	for (i = 0; i < ab->num_radios; i++) {
1159		ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i));
1160		if (ar) {
1161			len += scnprintf(buf + len, size - len,
1162					"\nradio%d tx_pending: %u\n", i,
1163					atomic_read(&ar->dp.num_tx_pending));
1164		}
1165	}
1166
1167	len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n");
1168
1169	for (i = 0; i < DP_REO_DST_RING_MAX; i++) {
1170		len += scnprintf(buf + len, size - len, "Ring%d:", i + 1);
1171
1172		for (j = 0; j < ATH12K_MAX_DEVICES; j++) {
1173			len += scnprintf(buf + len, size - len,
1174					"\t%d:%u", j,
1175					 device_stats->reo_rx[i][j]);
1176		}
1177
1178		len += scnprintf(buf + len, size - len, "\n");
1179	}
1180
1181	len += scnprintf(buf + len, size - len, "\nREO excep MSDU buf type:%u\n",
1182			 device_stats->reo_excep_msdu_buf_type);
1183
1184	len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n");
1185
1186	for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) {
1187		len += scnprintf(buf + len, size - len, "%s:", wbm_rel_src[i]);
1188
1189		for (j = 0; j < ATH12K_MAX_DEVICES; j++) {
1190			len += scnprintf(buf + len,
1191					 size - len,
1192					 "\t%d:%u", j,
1193					 device_stats->rx_wbm_rel_source[i][j]);
1194		}
1195
1196		len += scnprintf(buf + len, size - len, "\n");
1197	}
1198
1199	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1200
1201	return ret;
1202}
1203
1204static const struct file_operations fops_device_dp_stats = {
1205	.read = ath12k_debugfs_dump_device_dp_stats,
1206	.open = simple_open,
1207	.owner = THIS_MODULE,
1208	.llseek = default_llseek,
1209};
1210
1211void ath12k_debugfs_pdev_create(struct ath12k_base *ab)
1212{
1213	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
1214			    &fops_simulate_fw_crash);
1215
1216	debugfs_create_file("device_dp_stats", 0400, ab->debugfs_soc, ab,
1217			    &fops_device_dp_stats);
1218}
1219
1220void ath12k_debugfs_soc_create(struct ath12k_base *ab)
1221{
1222	bool dput_needed;
1223	char soc_name[64] = {};
1224	struct dentry *debugfs_ath12k;
1225
1226	debugfs_ath12k = debugfs_lookup("ath12k", NULL);
1227	if (debugfs_ath12k) {
1228		/* a dentry from lookup() needs dput() after we don't use it */
1229		dput_needed = true;
1230	} else {
1231		debugfs_ath12k = debugfs_create_dir("ath12k", NULL);
1232		if (IS_ERR_OR_NULL(debugfs_ath12k))
1233			return;
1234		dput_needed = false;
1235	}
1236
1237	scnprintf(soc_name, sizeof(soc_name), "%s-%s", ath12k_bus_str(ab->hif.bus),
1238		  dev_name(ab->dev));
1239
1240	ab->debugfs_soc = debugfs_create_dir(soc_name, debugfs_ath12k);
1241
1242	if (dput_needed)
1243		dput(debugfs_ath12k);
1244}
1245
1246void ath12k_debugfs_soc_destroy(struct ath12k_base *ab)
1247{
1248	debugfs_remove_recursive(ab->debugfs_soc);
1249	ab->debugfs_soc = NULL;
1250	/* We are not removing ath12k directory on purpose, even if it
1251	 * would be empty. This simplifies the directory handling and it's
1252	 * a minor cosmetic issue to leave an empty ath12k directory to
1253	 * debugfs.
1254	 */
1255}
1256
1257static int ath12k_open_vdev_stats(struct inode *inode, struct file *file)
1258{
1259	struct ath12k *ar = inode->i_private;
1260	struct ath12k_fw_stats_req_params param;
1261	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1262	int ret;
1263
1264	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1265
1266	if (!ah)
1267		return -ENETDOWN;
1268
1269	if (ah->state != ATH12K_HW_STATE_ON)
1270		return -ENETDOWN;
1271
1272	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1273	if (!buf)
1274		return -ENOMEM;
1275
1276	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1277	/* VDEV stats is always sent for all active VDEVs from FW */
1278	param.vdev_id = 0;
1279	param.stats_id = WMI_REQUEST_VDEV_STAT;
1280
1281	ret = ath12k_mac_get_fw_stats(ar, &param);
1282	if (ret) {
1283		ath12k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
1284		return ret;
1285	}
1286
1287	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1288				 buf);
1289	ath12k_fw_stats_reset(ar);
1290
1291	file->private_data = no_free_ptr(buf);
1292
1293	return 0;
1294}
1295
1296static int ath12k_release_vdev_stats(struct inode *inode, struct file *file)
1297{
1298	kfree(file->private_data);
1299
1300	return 0;
1301}
1302
1303static ssize_t ath12k_read_vdev_stats(struct file *file,
1304				      char __user *user_buf,
1305				      size_t count, loff_t *ppos)
1306{
1307	const char *buf = file->private_data;
1308	size_t len = strlen(buf);
1309
1310	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1311}
1312
1313static const struct file_operations fops_vdev_stats = {
1314	.open = ath12k_open_vdev_stats,
1315	.release = ath12k_release_vdev_stats,
1316	.read = ath12k_read_vdev_stats,
1317	.owner = THIS_MODULE,
1318	.llseek = default_llseek,
1319};
1320
1321static int ath12k_open_bcn_stats(struct inode *inode, struct file *file)
1322{
1323	struct ath12k *ar = inode->i_private;
1324	struct ath12k_link_vif *arvif;
1325	struct ath12k_fw_stats_req_params param;
1326	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1327	int ret;
1328
1329	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1330
1331	if (ah && ah->state != ATH12K_HW_STATE_ON)
1332		return -ENETDOWN;
1333
1334	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1335	if (!buf)
1336		return -ENOMEM;
1337
1338	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1339	param.stats_id = WMI_REQUEST_BCN_STAT;
1340
1341	/* loop all active VDEVs for bcn stats */
1342	list_for_each_entry(arvif, &ar->arvifs, list) {
1343		if (!arvif->is_up)
1344			continue;
1345
1346		param.vdev_id = arvif->vdev_id;
1347		ret = ath12k_mac_get_fw_stats(ar, &param);
1348		if (ret) {
1349			ath12k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
1350			return ret;
1351		}
1352	}
1353
1354	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1355				 buf);
1356	ath12k_fw_stats_reset(ar);
1357
1358	file->private_data = no_free_ptr(buf);
1359
1360	return 0;
1361}
1362
1363static int ath12k_release_bcn_stats(struct inode *inode, struct file *file)
1364{
1365	kfree(file->private_data);
1366
1367	return 0;
1368}
1369
1370static ssize_t ath12k_read_bcn_stats(struct file *file,
1371				     char __user *user_buf,
1372				     size_t count, loff_t *ppos)
1373{
1374	const char *buf = file->private_data;
1375	size_t len = strlen(buf);
1376
1377	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1378}
1379
1380static const struct file_operations fops_bcn_stats = {
1381	.open = ath12k_open_bcn_stats,
1382	.release = ath12k_release_bcn_stats,
1383	.read = ath12k_read_bcn_stats,
1384	.owner = THIS_MODULE,
1385	.llseek = default_llseek,
1386};
1387
1388static int ath12k_open_pdev_stats(struct inode *inode, struct file *file)
1389{
1390	struct ath12k *ar = inode->i_private;
1391	struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
1392	struct ath12k_base *ab = ar->ab;
1393	struct ath12k_fw_stats_req_params param;
1394	int ret;
1395
1396	guard(wiphy)(ath12k_ar_to_hw(ar)->wiphy);
1397
1398	if (ah && ah->state != ATH12K_HW_STATE_ON)
1399		return -ENETDOWN;
1400
1401	void *buf __free(kfree) = kzalloc(ATH12K_FW_STATS_BUF_SIZE, GFP_ATOMIC);
1402	if (!buf)
1403		return -ENOMEM;
1404
1405	param.pdev_id = ath12k_mac_get_target_pdev_id(ar);
1406	param.vdev_id = 0;
1407	param.stats_id = WMI_REQUEST_PDEV_STAT;
1408
1409	ret = ath12k_mac_get_fw_stats(ar, &param);
1410	if (ret) {
1411		ath12k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
1412		return ret;
1413	}
1414
1415	ath12k_wmi_fw_stats_dump(ar, &ar->fw_stats, param.stats_id,
1416				 buf);
1417	ath12k_fw_stats_reset(ar);
1418
1419	file->private_data = no_free_ptr(buf);
1420
1421	return 0;
1422}
1423
1424static int ath12k_release_pdev_stats(struct inode *inode, struct file *file)
1425{
1426	kfree(file->private_data);
1427
1428	return 0;
1429}
1430
1431static ssize_t ath12k_read_pdev_stats(struct file *file,
1432				      char __user *user_buf,
1433				      size_t count, loff_t *ppos)
1434{
1435	const char *buf = file->private_data;
1436	size_t len = strlen(buf);
1437
1438	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1439}
1440
1441static const struct file_operations fops_pdev_stats = {
1442	.open = ath12k_open_pdev_stats,
1443	.release = ath12k_release_pdev_stats,
1444	.read = ath12k_read_pdev_stats,
1445	.owner = THIS_MODULE,
1446	.llseek = default_llseek,
1447};
1448
1449static
1450void ath12k_debugfs_fw_stats_register(struct ath12k *ar)
1451{
1452	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1453							ar->debug.debugfs_pdev);
1454
1455	/* all stats debugfs files created are under "fw_stats" directory
1456	 * created per PDEV
1457	 */
1458	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1459			    &fops_vdev_stats);
1460	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1461			    &fops_bcn_stats);
1462	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1463			    &fops_pdev_stats);
1464
1465	ath12k_fw_stats_init(ar);
1466}
1467
1468void ath12k_debugfs_register(struct ath12k *ar)
1469{
1470	struct ath12k_base *ab = ar->ab;
1471	struct ieee80211_hw *hw = ar->ah->hw;
1472	char pdev_name[5];
1473	char buf[100] = {};
1474
1475	scnprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1476
1477	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1478
1479	/* Create a symlink under ieee80211/phy* */
1480	scnprintf(buf, sizeof(buf), "../../ath12k/%pd2", ar->debug.debugfs_pdev);
1481	ar->debug.debugfs_pdev_symlink = debugfs_create_symlink("ath12k",
1482								hw->wiphy->debugfsdir,
1483								buf);
1484
1485	if (ar->mac.sbands[NL80211_BAND_5GHZ].channels) {
1486		debugfs_create_file("dfs_simulate_radar", 0200,
1487				    ar->debug.debugfs_pdev, ar,
1488				    &fops_simulate_radar);
1489	}
1490
1491	debugfs_create_file("tpc_stats", 0400, ar->debug.debugfs_pdev, ar,
1492			    &fops_tpc_stats);
1493	debugfs_create_file("tpc_stats_type", 0200, ar->debug.debugfs_pdev,
1494			    ar, &fops_tpc_stats_type);
1495	init_completion(&ar->debug.tpc_complete);
1496
1497	ath12k_debugfs_htt_stats_register(ar);
1498	ath12k_debugfs_fw_stats_register(ar);
1499
1500	debugfs_create_file("ext_rx_stats", 0644,
1501			    ar->debug.debugfs_pdev, ar,
1502			    &fops_extd_rx_stats);
1503}
1504
1505void ath12k_debugfs_unregister(struct ath12k *ar)
1506{
1507	if (!ar->debug.debugfs_pdev)
1508		return;
1509
1510	/* Remove symlink under ieee80211/phy* */
1511	debugfs_remove(ar->debug.debugfs_pdev_symlink);
1512	debugfs_remove_recursive(ar->debug.debugfs_pdev);
1513	ar->debug.debugfs_pdev_symlink = NULL;
1514	ar->debug.debugfs_pdev = NULL;
1515}
~/ Read-only file preview.