1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license.  When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
9 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
10 * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 * General Public License for more details.
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called COPYING.
23 *
24 * Contact Information:
25 *  Intel Linux Wireless <linuxwifi@intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 * BSD LICENSE
29 *
30 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
31 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
32 * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 *
39 *  * Redistributions of source code must retain the above copyright
40 *    notice, this list of conditions and the following disclaimer.
41 *  * Redistributions in binary form must reproduce the above copyright
42 *    notice, this list of conditions and the following disclaimer in
43 *    the documentation and/or other materials provided with the
44 *    distribution.
45 *  * Neither the name Intel Corporation nor the names of its
46 *    contributors may be used to endorse or promote products derived
47 *    from this software without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
52 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
53 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
54 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
55 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
57 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
59 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 *
61 *****************************************************************************/
62#include <linux/vmalloc.h>
63#include <linux/ieee80211.h>
64#include <linux/netdevice.h>
65
66#include "mvm.h"
67#include "sta.h"
68#include "iwl-io.h"
69#include "debugfs.h"
70#include "iwl-modparams.h"
71#include "fw/error-dump.h"
72
73static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file,
74					  char __user *user_buf,
75					  size_t count, loff_t *ppos)
76{
77	struct iwl_mvm *mvm = file->private_data;
78	char buf[16];
79	int pos, budget;
80
81	if (!iwl_mvm_is_ctdp_supported(mvm))
82		return -EOPNOTSUPP;
83
84	if (!iwl_mvm_firmware_running(mvm) ||
85	    mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
86		return -EIO;
87
88	mutex_lock(&mvm->mutex);
89	budget = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_REPORT, 0);
90	mutex_unlock(&mvm->mutex);
91
92	if (budget < 0)
93		return budget;
94
95	pos = scnprintf(buf, sizeof(buf), "%d\n", budget);
96
97	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
98}
99
100static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
101					 size_t count, loff_t *ppos)
102{
103	int ret;
104
105	if (!iwl_mvm_is_ctdp_supported(mvm))
106		return -EOPNOTSUPP;
107
108	if (!iwl_mvm_firmware_running(mvm) ||
109	    mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
110		return -EIO;
111
112	mutex_lock(&mvm->mutex);
113	ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_STOP, 0);
114	mutex_unlock(&mvm->mutex);
115
116	return ret ?: count;
117}
118
119static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf,
120					    size_t count, loff_t *ppos)
121{
122	if (!iwl_mvm_firmware_running(mvm) ||
123	    mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
124		return -EIO;
125
126	iwl_mvm_enter_ctkill(mvm);
127
128	return count;
129}
130
131static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
132					size_t count, loff_t *ppos)
133{
134	int ret;
135	u32 flush_arg;
136
137	if (!iwl_mvm_firmware_running(mvm) ||
138	    mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
139		return -EIO;
140
141	if (kstrtou32(buf, 0, &flush_arg))
142		return -EINVAL;
143
144	if (iwl_mvm_has_new_tx_api(mvm)) {
145		IWL_DEBUG_TX_QUEUES(mvm,
146				    "FLUSHING all tids queues on sta_id = %d\n",
147				    flush_arg);
148		mutex_lock(&mvm->mutex);
149		ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFFFF, 0)
150			? : count;
151		mutex_unlock(&mvm->mutex);
152		return ret;
153	}
154
155	IWL_DEBUG_TX_QUEUES(mvm, "FLUSHING queues mask to flush = 0x%x\n",
156			    flush_arg);
157
158	mutex_lock(&mvm->mutex);
159	ret =  iwl_mvm_flush_tx_path(mvm, flush_arg, 0) ? : count;
160	mutex_unlock(&mvm->mutex);
161
162	return ret;
163}
164
165static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
166					 size_t count, loff_t *ppos)
167{
168	struct iwl_mvm_sta *mvmsta;
169	int sta_id, drain, ret;
170
171	if (!iwl_mvm_firmware_running(mvm) ||
172	    mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
173		return -EIO;
174
175	if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
176		return -EINVAL;
177	if (sta_id < 0 || sta_id >= mvm->fw->ucode_capa.num_stations)
178		return -EINVAL;
179	if (drain < 0 || drain > 1)
180		return -EINVAL;
181
182	mutex_lock(&mvm->mutex);
183
184	mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
185
186	if (!mvmsta)
187		ret = -ENOENT;
188	else
189		ret = iwl_mvm_drain_sta(mvm, mvmsta, drain) ? : count;
190
191	mutex_unlock(&mvm->mutex);
192
193	return ret;
194}
195
196static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
197				   size_t count, loff_t *ppos)
198{
199	struct iwl_mvm *mvm = file->private_data;
200	const struct fw_img *img;
201	unsigned int ofs, len;
202	size_t ret;
203	u8 *ptr;
204
205	if (!iwl_mvm_firmware_running(mvm))
206		return -EINVAL;
207
208	/* default is to dump the entire data segment */
209	img = &mvm->fw->img[mvm->fwrt.cur_fw_img];
210	ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
211	len = img->sec[IWL_UCODE_SECTION_DATA].len;
212
213	if (mvm->dbgfs_sram_len) {
214		ofs = mvm->dbgfs_sram_offset;
215		len = mvm->dbgfs_sram_len;
216	}
217
218	ptr = kzalloc(len, GFP_KERNEL);
219	if (!ptr)
220		return -ENOMEM;
221
222	iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
223
224	ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len);
225
226	kfree(ptr);
227
228	return ret;
229}
230
231static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
232				    size_t count, loff_t *ppos)
233{
234	const struct fw_img *img;
235	u32 offset, len;
236	u32 img_offset, img_len;
237
238	if (!iwl_mvm_firmware_running(mvm))
239		return -EINVAL;
240
241	img = &mvm->fw->img[mvm->fwrt.cur_fw_img];
242	img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset;
243	img_len = img->sec[IWL_UCODE_SECTION_DATA].len;
244
245	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
246		if ((offset & 0x3) || (len & 0x3))
247			return -EINVAL;
248
249		if (offset + len > img_offset + img_len)
250			return -EINVAL;
251
252		mvm->dbgfs_sram_offset = offset;
253		mvm->dbgfs_sram_len = len;
254	} else {
255		mvm->dbgfs_sram_offset = 0;
256		mvm->dbgfs_sram_len = 0;
257	}
258
259	return count;
260}
261
262static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file,
263						  char __user *user_buf,
264						  size_t count, loff_t *ppos)
265{
266	struct iwl_mvm *mvm = file->private_data;
267	char buf[16];
268	int pos;
269
270	if (!mvm->temperature_test)
271		pos = scnprintf(buf , sizeof(buf), "disabled\n");
272	else
273		pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature);
274
275	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
276}
277
278/*
279 * Set NIC Temperature
280 * Cause the driver to ignore the actual NIC temperature reported by the FW
281 * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
282 * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
283 * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
284 */
285static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
286						   char *buf, size_t count,
287						   loff_t *ppos)
288{
289	int temperature;
290
291	if (!iwl_mvm_firmware_running(mvm) && !mvm->temperature_test)
292		return -EIO;
293
294	if (kstrtoint(buf, 10, &temperature))
295		return -EINVAL;
296	/* not a legal temperature */
297	if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX &&
298	     temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) ||
299	    temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN)
300		return -EINVAL;
301
302	mutex_lock(&mvm->mutex);
303	if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) {
304		if (!mvm->temperature_test)
305			goto out;
306
307		mvm->temperature_test = false;
308		/* Since we can't read the temp while awake, just set
309		 * it to zero until we get the next RX stats from the
310		 * firmware.
311		 */
312		mvm->temperature = 0;
313	} else {
314		mvm->temperature_test = true;
315		mvm->temperature = temperature;
316	}
317	IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n",
318		       mvm->temperature_test ? "En" : "Dis" ,
319		       mvm->temperature);
320	/* handle the temperature change */
321	iwl_mvm_tt_handler(mvm);
322
323out:
324	mutex_unlock(&mvm->mutex);
325
326	return count;
327}
328
329static ssize_t iwl_dbgfs_nic_temp_read(struct file *file,
330				       char __user *user_buf,
331				       size_t count, loff_t *ppos)
332{
333	struct iwl_mvm *mvm = file->private_data;
334	char buf[16];
335	int pos, ret;
336	s32 temp;
337
338	if (!iwl_mvm_firmware_running(mvm))
339		return -EIO;
340
341	mutex_lock(&mvm->mutex);
342	ret = iwl_mvm_get_temp(mvm, &temp);
343	mutex_unlock(&mvm->mutex);
344
345	if (ret)
346		return -EIO;
347
348	pos = scnprintf(buf , sizeof(buf), "%d\n", temp);
349
350	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
351}
352
353#ifdef CONFIG_ACPI
354static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file,
355					      char __user *user_buf,
356					      size_t count, loff_t *ppos)
357{
358	struct iwl_mvm *mvm = file->private_data;
359	char buf[256];
360	int pos = 0;
361	int bufsz = sizeof(buf);
362	int tbl_idx;
363	u8 *value;
364
365	if (!iwl_mvm_firmware_running(mvm))
366		return -EIO;
367
368	mutex_lock(&mvm->mutex);
369	tbl_idx = iwl_mvm_get_sar_geo_profile(mvm);
370	if (tbl_idx < 0) {
371		mutex_unlock(&mvm->mutex);
372		return tbl_idx;
373	}
374
375	if (!tbl_idx) {
376		pos = scnprintf(buf, bufsz,
377				"SAR geographic profile disabled\n");
378	} else {
379		value = &mvm->fwrt.geo_profiles[tbl_idx - 1].values[0];
380
381		pos += scnprintf(buf + pos, bufsz - pos,
382				 "Use geographic profile %d\n", tbl_idx);
383		pos += scnprintf(buf + pos, bufsz - pos,
384				 "2.4GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n",
385				 value[1], value[2], value[0]);
386		pos += scnprintf(buf + pos, bufsz - pos,
387				 "5.2GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n",
388				 value[4], value[5], value[3]);
389	}
390	mutex_unlock(&mvm->mutex);
391
392	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
393}
394#endif
395
396static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
397				       size_t count, loff_t *ppos)
398{
399	struct iwl_mvm *mvm = file->private_data;
400	struct ieee80211_sta *sta;
401	char buf[400];
402	int i, pos = 0, bufsz = sizeof(buf);
403
404	mutex_lock(&mvm->mutex);
405
406	for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
407		pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i);
408		sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
409						lockdep_is_held(&mvm->mutex));
410		if (!sta)
411			pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
412		else if (IS_ERR(sta))
413			pos += scnprintf(buf + pos, bufsz - pos, "%ld\n",
414					 PTR_ERR(sta));
415		else
416			pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
417					 sta->addr);
418	}
419
420	mutex_unlock(&mvm->mutex);
421
422	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
423}
424
425static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf,
426				      size_t count, loff_t *ppos)
427{
428	struct ieee80211_sta *sta = file->private_data;
429	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
430	struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw;
431	struct iwl_mvm *mvm = lq_sta->pers.drv;
432	static const size_t bufsz = 2048;
433	char *buff;
434	int desc = 0;
435	ssize_t ret;
436
437	buff = kmalloc(bufsz, GFP_KERNEL);
438	if (!buff)
439		return -ENOMEM;
440
441	mutex_lock(&mvm->mutex);
442
443	desc += scnprintf(buff + desc, bufsz - desc, "sta_id %d\n",
444			  lq_sta->pers.sta_id);
445	desc += scnprintf(buff + desc, bufsz - desc,
446			  "fixed rate 0x%X\n",
447			  lq_sta->pers.dbg_fixed_rate);
448	desc += scnprintf(buff + desc, bufsz - desc,
449			  "A-MPDU size limit %d\n",
450			  lq_sta->pers.dbg_agg_frame_count_lim);
451	desc += scnprintf(buff + desc, bufsz - desc,
452			  "valid_tx_ant %s%s%s\n",
453		(iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
454		(iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
455		(iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
456	desc += scnprintf(buff + desc, bufsz - desc,
457			  "last tx rate=0x%X ",
458			  lq_sta->last_rate_n_flags);
459
460	desc += rs_pretty_print_rate(buff + desc, bufsz - desc,
461				     lq_sta->last_rate_n_flags);
462	if (desc < bufsz - 1)
463		buff[desc++] = '\n';
464	mutex_unlock(&mvm->mutex);
465
466	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
467	kfree(buff);
468	return ret;
469}
470
471static ssize_t iwl_dbgfs_amsdu_len_write(struct ieee80211_sta *sta,
472					 char *buf, size_t count,
473					 loff_t *ppos)
474{
475	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
476	int i;
477	u16 amsdu_len;
478
479	if (kstrtou16(buf, 0, &amsdu_len))
480		return -EINVAL;
481
482	/* only change from debug set <-> debug unset */
483	if ((amsdu_len && mvmsta->orig_amsdu_len) ||
484	    (!!amsdu_len && mvmsta->orig_amsdu_len))
485		return -EBUSY;
486
487	if (amsdu_len) {
488		mvmsta->orig_amsdu_len = sta->max_amsdu_len;
489		sta->max_amsdu_len = amsdu_len;
490		for (i = 0; i < ARRAY_SIZE(sta->max_tid_amsdu_len); i++)
491			sta->max_tid_amsdu_len[i] = amsdu_len;
492	} else {
493		sta->max_amsdu_len = mvmsta->orig_amsdu_len;
494		mvmsta->orig_amsdu_len = 0;
495	}
496	return count;
497}
498
499static ssize_t iwl_dbgfs_amsdu_len_read(struct file *file,
500					char __user *user_buf,
501					size_t count, loff_t *ppos)
502{
503	struct ieee80211_sta *sta = file->private_data;
504	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
505
506	char buf[32];
507	int pos;
508
509	pos = scnprintf(buf, sizeof(buf), "current %d ", sta->max_amsdu_len);
510	pos += scnprintf(buf + pos, sizeof(buf) - pos, "stored %d\n",
511			 mvmsta->orig_amsdu_len);
512
513	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
514}
515
516static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
517						char __user *user_buf,
518						size_t count, loff_t *ppos)
519{
520	struct iwl_mvm *mvm = file->private_data;
521	char buf[64];
522	int bufsz = sizeof(buf);
523	int pos = 0;
524
525	pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n",
526			 mvm->disable_power_off);
527	pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n",
528			 mvm->disable_power_off_d3);
529
530	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
531}
532
533static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
534						 size_t count, loff_t *ppos)
535{
536	int ret, val;
537
538	if (!iwl_mvm_firmware_running(mvm))
539		return -EIO;
540
541	if (!strncmp("disable_power_off_d0=", buf, 21)) {
542		if (sscanf(buf + 21, "%d", &val) != 1)
543			return -EINVAL;
544		mvm->disable_power_off = val;
545	} else if (!strncmp("disable_power_off_d3=", buf, 21)) {
546		if (sscanf(buf + 21, "%d", &val) != 1)
547			return -EINVAL;
548		mvm->disable_power_off_d3 = val;
549	} else {
550		return -EINVAL;
551	}
552
553	mutex_lock(&mvm->mutex);
554	ret = iwl_mvm_power_update_device(mvm);
555	mutex_unlock(&mvm->mutex);
556
557	return ret ?: count;
558}
559
560static
561int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
562			   int pos, int bufsz)
563{
564	pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
565
566	BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
567	BT_MBOX_PRINT(0, LE_PROF1, false);
568	BT_MBOX_PRINT(0, LE_PROF2, false);
569	BT_MBOX_PRINT(0, LE_PROF_OTHER, false);
570	BT_MBOX_PRINT(0, CHL_SEQ_N, false);
571	BT_MBOX_PRINT(0, INBAND_S, false);
572	BT_MBOX_PRINT(0, LE_MIN_RSSI, false);
573	BT_MBOX_PRINT(0, LE_SCAN, false);
574	BT_MBOX_PRINT(0, LE_ADV, false);
575	BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false);
576	BT_MBOX_PRINT(0, OPEN_CON_1, true);
577
578	pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n");
579
580	BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false);
581	BT_MBOX_PRINT(1, IP_SR, false);
582	BT_MBOX_PRINT(1, LE_MSTR, false);
583	BT_MBOX_PRINT(1, AGGR_TRFC_LD, false);
584	BT_MBOX_PRINT(1, MSG_TYPE, false);
585	BT_MBOX_PRINT(1, SSN, true);
586
587	pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n");
588
589	BT_MBOX_PRINT(2, SNIFF_ACT, false);
590	BT_MBOX_PRINT(2, PAG, false);
591	BT_MBOX_PRINT(2, INQUIRY, false);
592	BT_MBOX_PRINT(2, CONN, false);
593	BT_MBOX_PRINT(2, SNIFF_INTERVAL, false);
594	BT_MBOX_PRINT(2, DISC, false);
595	BT_MBOX_PRINT(2, SCO_TX_ACT, false);
596	BT_MBOX_PRINT(2, SCO_RX_ACT, false);
597	BT_MBOX_PRINT(2, ESCO_RE_TX, false);
598	BT_MBOX_PRINT(2, SCO_DURATION, true);
599
600	pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n");
601
602	BT_MBOX_PRINT(3, SCO_STATE, false);
603	BT_MBOX_PRINT(3, SNIFF_STATE, false);
604	BT_MBOX_PRINT(3, A2DP_STATE, false);
605	BT_MBOX_PRINT(3, A2DP_SRC, false);
606	BT_MBOX_PRINT(3, ACL_STATE, false);
607	BT_MBOX_PRINT(3, MSTR_STATE, false);
608	BT_MBOX_PRINT(3, OBX_STATE, false);
609	BT_MBOX_PRINT(3, OPEN_CON_2, false);
610	BT_MBOX_PRINT(3, TRAFFIC_LOAD, false);
611	BT_MBOX_PRINT(3, CHL_SEQN_LSB, false);
612	BT_MBOX_PRINT(3, INBAND_P, false);
613	BT_MBOX_PRINT(3, MSG_TYPE_2, false);
614	BT_MBOX_PRINT(3, SSN_2, false);
615	BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
616
617	return pos;
618}
619
620static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
621				       size_t count, loff_t *ppos)
622{
623	struct iwl_mvm *mvm = file->private_data;
624	struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
625	char *buf;
626	int ret, pos = 0, bufsz = sizeof(char) * 1024;
627
628	buf = kmalloc(bufsz, GFP_KERNEL);
629	if (!buf)
630		return -ENOMEM;
631
632	mutex_lock(&mvm->mutex);
633
634	pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz);
635
636	pos += scnprintf(buf + pos, bufsz - pos, "bt_ci_compliance = %d\n",
637			 notif->bt_ci_compliance);
638	pos += scnprintf(buf + pos, bufsz - pos, "primary_ch_lut = %d\n",
639			 le32_to_cpu(notif->primary_ch_lut));
640	pos += scnprintf(buf + pos, bufsz - pos, "secondary_ch_lut = %d\n",
641			 le32_to_cpu(notif->secondary_ch_lut));
642	pos += scnprintf(buf + pos,
643			 bufsz - pos, "bt_activity_grading = %d\n",
644			 le32_to_cpu(notif->bt_activity_grading));
645	pos += scnprintf(buf + pos, bufsz - pos, "bt_rrc = %d\n",
646			 notif->rrc_status & 0xF);
647	pos += scnprintf(buf + pos, bufsz - pos, "bt_ttc = %d\n",
648			 notif->ttc_status & 0xF);
649
650	pos += scnprintf(buf + pos, bufsz - pos, "sync_sco = %d\n",
651			 IWL_MVM_BT_COEX_SYNC2SCO);
652	pos += scnprintf(buf + pos, bufsz - pos, "mplut = %d\n",
653			 IWL_MVM_BT_COEX_MPLUT);
654
655	mutex_unlock(&mvm->mutex);
656
657	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
658	kfree(buf);
659
660	return ret;
661}
662#undef BT_MBOX_PRINT
663
664static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
665				     size_t count, loff_t *ppos)
666{
667	struct iwl_mvm *mvm = file->private_data;
668	struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
669	char buf[256];
670	int bufsz = sizeof(buf);
671	int pos = 0;
672
673	mutex_lock(&mvm->mutex);
674
675	pos += scnprintf(buf + pos, bufsz - pos, "Channel inhibition CMD\n");
676	pos += scnprintf(buf + pos, bufsz - pos,
677			 "\tPrimary Channel Bitmap 0x%016llx\n",
678			 le64_to_cpu(cmd->bt_primary_ci));
679	pos += scnprintf(buf + pos, bufsz - pos,
680			 "\tSecondary Channel Bitmap 0x%016llx\n",
681			 le64_to_cpu(cmd->bt_secondary_ci));
682
683	mutex_unlock(&mvm->mutex);
684
685	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
686}
687
688static ssize_t
689iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf,
690			   size_t count, loff_t *ppos)
691{
692	u32 bt_tx_prio;
693
694	if (sscanf(buf, "%u", &bt_tx_prio) != 1)
695		return -EINVAL;
696	if (bt_tx_prio > 4)
697		return -EINVAL;
698
699	mvm->bt_tx_prio = bt_tx_prio;
700
701	return count;
702}
703
704static ssize_t
705iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf,
706			     size_t count, loff_t *ppos)
707{
708	static const char * const modes_str[BT_FORCE_ANT_MAX] = {
709		[BT_FORCE_ANT_DIS] = "dis",
710		[BT_FORCE_ANT_AUTO] = "auto",
711		[BT_FORCE_ANT_BT] = "bt",
712		[BT_FORCE_ANT_WIFI] = "wifi",
713	};
714	int ret, bt_force_ant_mode;
715
716	ret = match_string(modes_str, ARRAY_SIZE(modes_str), buf);
717	if (ret < 0)
718		return ret;
719
720	bt_force_ant_mode = ret;
721	ret = 0;
722	mutex_lock(&mvm->mutex);
723	if (mvm->bt_force_ant_mode == bt_force_ant_mode)
724		goto out;
725
726	mvm->bt_force_ant_mode = bt_force_ant_mode;
727	IWL_DEBUG_COEX(mvm, "Force mode: %s\n",
728		       modes_str[mvm->bt_force_ant_mode]);
729
730	if (iwl_mvm_firmware_running(mvm))
731		ret = iwl_mvm_send_bt_init_conf(mvm);
732	else
733		ret = 0;
734
735out:
736	mutex_unlock(&mvm->mutex);
737	return ret ?: count;
738}
739
740static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf,
741				     size_t count, loff_t *ppos)
742{
743	struct iwl_mvm *mvm = file->private_data;
744	char *buff, *pos, *endpos;
745	static const size_t bufsz = 1024;
746	int ret;
747
748	buff = kmalloc(bufsz, GFP_KERNEL);
749	if (!buff)
750		return -ENOMEM;
751
752	pos = buff;
753	endpos = pos + bufsz;
754
755	pos += scnprintf(pos, endpos - pos, "FW prefix: %s\n",
756			 mvm->trans->cfg->fw_name_pre);
757	pos += scnprintf(pos, endpos - pos, "FW: %s\n",
758			 mvm->fwrt.fw->human_readable);
759	pos += scnprintf(pos, endpos - pos, "Device: %s\n",
760			 mvm->fwrt.trans->name);
761	pos += scnprintf(pos, endpos - pos, "Bus: %s\n",
762			 mvm->fwrt.dev->bus->name);
763
764	ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
765	kfree(buff);
766
767	return ret;
768}
769
770#define PRINT_STATS_LE32(_struct, _memb)				\
771			 pos += scnprintf(buf + pos, bufsz - pos,	\
772					  fmt_table, #_memb,		\
773					  le32_to_cpu(_struct->_memb))
774
775static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
776					  char __user *user_buf, size_t count,
777					  loff_t *ppos)
778{
779	struct iwl_mvm *mvm = file->private_data;
780	static const char *fmt_table = "\t%-30s %10u\n";
781	static const char *fmt_header = "%-32s\n";
782	int pos = 0;
783	char *buf;
784	int ret;
785	size_t bufsz;
786
787	if (iwl_mvm_has_new_rx_stats_api(mvm))
788		bufsz = ((sizeof(struct mvm_statistics_rx) /
789			  sizeof(__le32)) * 43) + (4 * 33) + 1;
790	else
791		/* 43 = size of each data line; 33 = size of each header */
792		bufsz = ((sizeof(struct mvm_statistics_rx_v3) /
793			  sizeof(__le32)) * 43) + (4 * 33) + 1;
794
795	buf = kzalloc(bufsz, GFP_KERNEL);
796	if (!buf)
797		return -ENOMEM;
798
799	mutex_lock(&mvm->mutex);
800
801	if (iwl_mvm_firmware_running(mvm))
802		iwl_mvm_request_statistics(mvm, false);
803
804	pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
805			 "Statistics_Rx - OFDM");
806	if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
807		struct mvm_statistics_rx_phy_v2 *ofdm = &mvm->rx_stats_v3.ofdm;
808
809		PRINT_STATS_LE32(ofdm, ina_cnt);
810		PRINT_STATS_LE32(ofdm, fina_cnt);
811		PRINT_STATS_LE32(ofdm, plcp_err);
812		PRINT_STATS_LE32(ofdm, crc32_err);
813		PRINT_STATS_LE32(ofdm, overrun_err);
814		PRINT_STATS_LE32(ofdm, early_overrun_err);
815		PRINT_STATS_LE32(ofdm, crc32_good);
816		PRINT_STATS_LE32(ofdm, false_alarm_cnt);
817		PRINT_STATS_LE32(ofdm, fina_sync_err_cnt);
818		PRINT_STATS_LE32(ofdm, sfd_timeout);
819		PRINT_STATS_LE32(ofdm, fina_timeout);
820		PRINT_STATS_LE32(ofdm, unresponded_rts);
821		PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
822		PRINT_STATS_LE32(ofdm, sent_ack_cnt);
823		PRINT_STATS_LE32(ofdm, sent_cts_cnt);
824		PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
825		PRINT_STATS_LE32(ofdm, dsp_self_kill);
826		PRINT_STATS_LE32(ofdm, mh_format_err);
827		PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum);
828		PRINT_STATS_LE32(ofdm, reserved);
829	} else {
830		struct mvm_statistics_rx_phy *ofdm = &mvm->rx_stats.ofdm;
831
832		PRINT_STATS_LE32(ofdm, unresponded_rts);
833		PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
834		PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
835		PRINT_STATS_LE32(ofdm, dsp_self_kill);
836		PRINT_STATS_LE32(ofdm, reserved);
837	}
838
839	pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
840			 "Statistics_Rx - CCK");
841	if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
842		struct mvm_statistics_rx_phy_v2 *cck = &mvm->rx_stats_v3.cck;
843
844		PRINT_STATS_LE32(cck, ina_cnt);
845		PRINT_STATS_LE32(cck, fina_cnt);
846		PRINT_STATS_LE32(cck, plcp_err);
847		PRINT_STATS_LE32(cck, crc32_err);
848		PRINT_STATS_LE32(cck, overrun_err);
849		PRINT_STATS_LE32(cck, early_overrun_err);
850		PRINT_STATS_LE32(cck, crc32_good);
851		PRINT_STATS_LE32(cck, false_alarm_cnt);
852		PRINT_STATS_LE32(cck, fina_sync_err_cnt);
853		PRINT_STATS_LE32(cck, sfd_timeout);
854		PRINT_STATS_LE32(cck, fina_timeout);
855		PRINT_STATS_LE32(cck, unresponded_rts);
856		PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
857		PRINT_STATS_LE32(cck, sent_ack_cnt);
858		PRINT_STATS_LE32(cck, sent_cts_cnt);
859		PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
860		PRINT_STATS_LE32(cck, dsp_self_kill);
861		PRINT_STATS_LE32(cck, mh_format_err);
862		PRINT_STATS_LE32(cck, re_acq_main_rssi_sum);
863		PRINT_STATS_LE32(cck, reserved);
864	} else {
865		struct mvm_statistics_rx_phy *cck = &mvm->rx_stats.cck;
866
867		PRINT_STATS_LE32(cck, unresponded_rts);
868		PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
869		PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
870		PRINT_STATS_LE32(cck, dsp_self_kill);
871		PRINT_STATS_LE32(cck, reserved);
872	}
873
874	pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
875			 "Statistics_Rx - GENERAL");
876	if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
877		struct mvm_statistics_rx_non_phy_v3 *general =
878			&mvm->rx_stats_v3.general;
879
880		PRINT_STATS_LE32(general, bogus_cts);
881		PRINT_STATS_LE32(general, bogus_ack);
882		PRINT_STATS_LE32(general, non_bssid_frames);
883		PRINT_STATS_LE32(general, filtered_frames);
884		PRINT_STATS_LE32(general, non_channel_beacons);
885		PRINT_STATS_LE32(general, channel_beacons);
886		PRINT_STATS_LE32(general, num_missed_bcon);
887		PRINT_STATS_LE32(general, adc_rx_saturation_time);
888		PRINT_STATS_LE32(general, ina_detection_search_time);
889		PRINT_STATS_LE32(general, beacon_silence_rssi_a);
890		PRINT_STATS_LE32(general, beacon_silence_rssi_b);
891		PRINT_STATS_LE32(general, beacon_silence_rssi_c);
892		PRINT_STATS_LE32(general, interference_data_flag);
893		PRINT_STATS_LE32(general, channel_load);
894		PRINT_STATS_LE32(general, dsp_false_alarms);
895		PRINT_STATS_LE32(general, beacon_rssi_a);
896		PRINT_STATS_LE32(general, beacon_rssi_b);
897		PRINT_STATS_LE32(general, beacon_rssi_c);
898		PRINT_STATS_LE32(general, beacon_energy_a);
899		PRINT_STATS_LE32(general, beacon_energy_b);
900		PRINT_STATS_LE32(general, beacon_energy_c);
901		PRINT_STATS_LE32(general, num_bt_kills);
902		PRINT_STATS_LE32(general, mac_id);
903		PRINT_STATS_LE32(general, directed_data_mpdu);
904	} else {
905		struct mvm_statistics_rx_non_phy *general =
906			&mvm->rx_stats.general;
907
908		PRINT_STATS_LE32(general, bogus_cts);
909		PRINT_STATS_LE32(general, bogus_ack);
910		PRINT_STATS_LE32(general, non_channel_beacons);
911		PRINT_STATS_LE32(general, channel_beacons);
912		PRINT_STATS_LE32(general, num_missed_bcon);
913		PRINT_STATS_LE32(general, adc_rx_saturation_time);
914		PRINT_STATS_LE32(general, ina_detection_search_time);
915		PRINT_STATS_LE32(general, beacon_silence_rssi_a);
916		PRINT_STATS_LE32(general, beacon_silence_rssi_b);
917		PRINT_STATS_LE32(general, beacon_silence_rssi_c);
918		PRINT_STATS_LE32(general, interference_data_flag);
919		PRINT_STATS_LE32(general, channel_load);
920		PRINT_STATS_LE32(general, beacon_rssi_a);
921		PRINT_STATS_LE32(general, beacon_rssi_b);
922		PRINT_STATS_LE32(general, beacon_rssi_c);
923		PRINT_STATS_LE32(general, beacon_energy_a);
924		PRINT_STATS_LE32(general, beacon_energy_b);
925		PRINT_STATS_LE32(general, beacon_energy_c);
926		PRINT_STATS_LE32(general, num_bt_kills);
927		PRINT_STATS_LE32(general, mac_id);
928	}
929
930	pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
931			 "Statistics_Rx - HT");
932	if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
933		struct mvm_statistics_rx_ht_phy_v1 *ht =
934			&mvm->rx_stats_v3.ofdm_ht;
935
936		PRINT_STATS_LE32(ht, plcp_err);
937		PRINT_STATS_LE32(ht, overrun_err);
938		PRINT_STATS_LE32(ht, early_overrun_err);
939		PRINT_STATS_LE32(ht, crc32_good);
940		PRINT_STATS_LE32(ht, crc32_err);
941		PRINT_STATS_LE32(ht, mh_format_err);
942		PRINT_STATS_LE32(ht, agg_crc32_good);
943		PRINT_STATS_LE32(ht, agg_mpdu_cnt);
944		PRINT_STATS_LE32(ht, agg_cnt);
945		PRINT_STATS_LE32(ht, unsupport_mcs);
946	} else {
947		struct mvm_statistics_rx_ht_phy *ht =
948			&mvm->rx_stats.ofdm_ht;
949
950		PRINT_STATS_LE32(ht, mh_format_err);
951		PRINT_STATS_LE32(ht, agg_mpdu_cnt);
952		PRINT_STATS_LE32(ht, agg_cnt);
953		PRINT_STATS_LE32(ht, unsupport_mcs);
954	}
955
956	mutex_unlock(&mvm->mutex);
957
958	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
959	kfree(buf);
960
961	return ret;
962}
963#undef PRINT_STAT_LE32
964
965static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
966					  char __user *user_buf, size_t count,
967					  loff_t *ppos,
968					  struct iwl_mvm_frame_stats *stats)
969{
970	char *buff, *pos, *endpos;
971	int idx, i;
972	int ret;
973	static const size_t bufsz = 1024;
974
975	buff = kmalloc(bufsz, GFP_KERNEL);
976	if (!buff)
977		return -ENOMEM;
978
979	spin_lock_bh(&mvm->drv_stats_lock);
980
981	pos = buff;
982	endpos = pos + bufsz;
983
984	pos += scnprintf(pos, endpos - pos,
985			 "Legacy/HT/VHT\t:\t%d/%d/%d\n",
986			 stats->legacy_frames,
987			 stats->ht_frames,
988			 stats->vht_frames);
989	pos += scnprintf(pos, endpos - pos, "20/40/80\t:\t%d/%d/%d\n",
990			 stats->bw_20_frames,
991			 stats->bw_40_frames,
992			 stats->bw_80_frames);
993	pos += scnprintf(pos, endpos - pos, "NGI/SGI\t\t:\t%d/%d\n",
994			 stats->ngi_frames,
995			 stats->sgi_frames);
996	pos += scnprintf(pos, endpos - pos, "SISO/MIMO2\t:\t%d/%d\n",
997			 stats->siso_frames,
998			 stats->mimo2_frames);
999	pos += scnprintf(pos, endpos - pos, "FAIL/SCSS\t:\t%d/%d\n",
1000			 stats->fail_frames,
1001			 stats->success_frames);
1002	pos += scnprintf(pos, endpos - pos, "MPDUs agg\t:\t%d\n",
1003			 stats->agg_frames);
1004	pos += scnprintf(pos, endpos - pos, "A-MPDUs\t\t:\t%d\n",
1005			 stats->ampdu_count);
1006	pos += scnprintf(pos, endpos - pos, "Avg MPDUs/A-MPDU:\t%d\n",
1007			 stats->ampdu_count > 0 ?
1008			 (stats->agg_frames / stats->ampdu_count) : 0);
1009
1010	pos += scnprintf(pos, endpos - pos, "Last Rates\n");
1011
1012	idx = stats->last_frame_idx - 1;
1013	for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) {
1014		idx = (idx + 1) % ARRAY_SIZE(stats->last_rates);
1015		if (stats->last_rates[idx] == 0)
1016			continue;
1017		pos += scnprintf(pos, endpos - pos, "Rate[%d]: ",
1018				 (int)(ARRAY_SIZE(stats->last_rates) - i));
1019		pos += rs_pretty_print_rate(pos, endpos - pos,
1020					    stats->last_rates[idx]);
1021		if (pos < endpos - 1)
1022			*pos++ = '\n';
1023	}
1024	spin_unlock_bh(&mvm->drv_stats_lock);
1025
1026	ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
1027	kfree(buff);
1028
1029	return ret;
1030}
1031
1032static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file,
1033					   char __user *user_buf, size_t count,
1034					   loff_t *ppos)
1035{
1036	struct iwl_mvm *mvm = file->private_data;
1037
1038	return iwl_dbgfs_frame_stats_read(mvm, user_buf, count, ppos,
1039					  &mvm->drv_rx_stats);
1040}
1041
1042static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
1043					  size_t count, loff_t *ppos)
1044{
1045	int __maybe_unused ret;
1046
1047	if (!iwl_mvm_firmware_running(mvm))
1048		return -EIO;
1049
1050	mutex_lock(&mvm->mutex);
1051
1052	/* allow one more restart that we're provoking here */
1053	if (mvm->fw_restart >= 0)
1054		mvm->fw_restart++;
1055
1056	/* take the return value to make compiler happy - it will fail anyway */
1057	ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, 0, 0, NULL);
1058
1059	mutex_unlock(&mvm->mutex);
1060
1061	return count;
1062}
1063
1064static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
1065				      size_t count, loff_t *ppos)
1066{
1067	if (!iwl_mvm_firmware_running(mvm))
1068		return -EIO;
1069
1070	iwl_force_nmi(mvm->trans);
1071
1072	return count;
1073}
1074
1075static ssize_t
1076iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
1077				char __user *user_buf,
1078				size_t count, loff_t *ppos)
1079{
1080	struct iwl_mvm *mvm = file->private_data;
1081	int pos = 0;
1082	char buf[32];
1083	const size_t bufsz = sizeof(buf);
1084
1085	/* print which antennas were set for the scan command by the user */
1086	pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: ");
1087	if (mvm->scan_rx_ant & ANT_A)
1088		pos += scnprintf(buf + pos, bufsz - pos, "A");
1089	if (mvm->scan_rx_ant & ANT_B)
1090		pos += scnprintf(buf + pos, bufsz - pos, "B");
1091	if (mvm->scan_rx_ant & ANT_C)
1092		pos += scnprintf(buf + pos, bufsz - pos, "C");
1093	pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant);
1094
1095	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1096}
1097
1098static ssize_t
1099iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
1100				 size_t count, loff_t *ppos)
1101{
1102	u8 scan_rx_ant;
1103
1104	if (!iwl_mvm_firmware_running(mvm))
1105		return -EIO;
1106
1107	if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
1108		return -EINVAL;
1109	if (scan_rx_ant > ANT_ABC)
1110		return -EINVAL;
1111	if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm)))
1112		return -EINVAL;
1113
1114	if (mvm->scan_rx_ant != scan_rx_ant) {
1115		mvm->scan_rx_ant = scan_rx_ant;
1116		if (fw_has_capa(&mvm->fw->ucode_capa,
1117				IWL_UCODE_TLV_CAPA_UMAC_SCAN))
1118			iwl_mvm_config_scan(mvm);
1119	}
1120
1121	return count;
1122}
1123
1124static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm,
1125					       char *buf, size_t count,
1126					       loff_t *ppos)
1127{
1128	struct iwl_rss_config_cmd cmd = {
1129		.flags = cpu_to_le32(IWL_RSS_ENABLE),
1130		.hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
1131			     IWL_RSS_HASH_TYPE_IPV4_UDP |
1132			     IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
1133			     IWL_RSS_HASH_TYPE_IPV6_TCP |
1134			     IWL_RSS_HASH_TYPE_IPV6_UDP |
1135			     IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
1136	};
1137	int ret, i, num_repeats, nbytes = count / 2;
1138
1139	ret = hex2bin(cmd.indirection_table, buf, nbytes);
1140	if (ret)
1141		return ret;
1142
1143	/*
1144	 * The input is the redirection table, partial or full.
1145	 * Repeat the pattern if needed.
1146	 * For example, input of 01020F will be repeated 42 times,
1147	 * indirecting RSS hash results to queues 1, 2, 15 (skipping
1148	 * queues 3 - 14).
1149	 */
1150	num_repeats = ARRAY_SIZE(cmd.indirection_table) / nbytes;
1151	for (i = 1; i < num_repeats; i++)
1152		memcpy(&cmd.indirection_table[i * nbytes],
1153		       cmd.indirection_table, nbytes);
1154	/* handle cut in the middle pattern for the last places */
1155	memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table,
1156	       ARRAY_SIZE(cmd.indirection_table) % nbytes);
1157
1158	netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));
1159
1160	mutex_lock(&mvm->mutex);
1161	if (iwl_mvm_firmware_running(mvm))
1162		ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0,
1163					   sizeof(cmd), &cmd);
1164	else
1165		ret = 0;
1166	mutex_unlock(&mvm->mutex);
1167
1168	return ret ?: count;
1169}
1170
1171static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
1172					     char *buf, size_t count,
1173					     loff_t *ppos)
1174{
1175	struct iwl_rx_cmd_buffer rxb = {
1176		._rx_page_order = 0,
1177		.truesize = 0, /* not used */
1178		._offset = 0,
1179	};
1180	struct iwl_rx_packet *pkt;
1181	struct iwl_rx_mpdu_desc *desc;
1182	int bin_len = count / 2;
1183	int ret = -EINVAL;
1184	size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >=
1185				    IWL_DEVICE_FAMILY_AX210) ?
1186		sizeof(struct iwl_rx_mpdu_desc) :
1187		IWL_RX_DESC_SIZE_V1;
1188
1189	if (!iwl_mvm_firmware_running(mvm))
1190		return -EIO;
1191
1192	/* supporting only 9000 descriptor */
1193	if (!mvm->trans->trans_cfg->mq_rx_supported)
1194		return -ENOTSUPP;
1195
1196	rxb._page = alloc_pages(GFP_ATOMIC, 0);
1197	if (!rxb._page)
1198		return -ENOMEM;
1199	pkt = rxb_addr(&rxb);
1200
1201	ret = hex2bin(page_address(rxb._page), buf, bin_len);
1202	if (ret)
1203		goto out;
1204
1205	/* avoid invalid memory access */
1206	if (bin_len < sizeof(*pkt) + mpdu_cmd_hdr_size)
1207		goto out;
1208
1209	/* check this is RX packet */
1210	if (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd) !=
1211	    WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD))
1212		goto out;
1213
1214	/* check the length in metadata matches actual received length */
1215	desc = (void *)pkt->data;
1216	if (le16_to_cpu(desc->mpdu_len) !=
1217	    (bin_len - mpdu_cmd_hdr_size - sizeof(*pkt)))
1218		goto out;
1219
1220	local_bh_disable();
1221	iwl_mvm_rx_mpdu_mq(mvm, NULL, &rxb, 0);
1222	local_bh_enable();
1223	ret = 0;
1224
1225out:
1226	iwl_free_rxb(&rxb);
1227
1228	return ret ?: count;
1229}
1230
1231static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
1232{
1233	struct ieee80211_vif *vif;
1234	struct iwl_mvm_vif *mvmvif;
1235	struct sk_buff *beacon;
1236	struct ieee80211_tx_info *info;
1237	struct iwl_mac_beacon_cmd beacon_cmd = {};
1238	u8 rate;
1239	u16 flags;
1240	int i;
1241
1242	len /= 2;
1243
1244	/* Element len should be represented by u8 */
1245	if (len >= U8_MAX)
1246		return -EINVAL;
1247
1248	if (!iwl_mvm_firmware_running(mvm))
1249		return -EIO;
1250
1251	if (!iwl_mvm_has_new_tx_api(mvm) &&
1252	    !fw_has_api(&mvm->fw->ucode_capa,
1253			IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
1254		return -EINVAL;
1255
1256	rcu_read_lock();
1257
1258	for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
1259		vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, true);
1260		if (!vif)
1261			continue;
1262
1263		if (vif->type == NL80211_IFTYPE_AP)
1264			break;
1265	}
1266
1267	if (i == NUM_MAC_INDEX_DRIVER || !vif)
1268		goto out_err;
1269
1270	mvm->hw->extra_beacon_tailroom = len;
1271
1272	beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
1273	if (!beacon)
1274		goto out_err;
1275
1276	if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) {
1277		dev_kfree_skb(beacon);
1278		goto out_err;
1279	}
1280
1281	mvm->beacon_inject_active = true;
1282
1283	mvmvif = iwl_mvm_vif_from_mac80211(vif);
1284	info = IEEE80211_SKB_CB(beacon);
1285	rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
1286	flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
1287
1288	if (rate == IWL_FIRST_CCK_RATE)
1289		flags |= IWL_MAC_BEACON_CCK;
1290
1291	beacon_cmd.flags = cpu_to_le16(flags);
1292	beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
1293	beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
1294
1295	iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
1296				 &beacon_cmd.tim_size,
1297				 beacon->data, beacon->len);
1298
1299	mutex_lock(&mvm->mutex);
1300	iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd,
1301					 sizeof(beacon_cmd));
1302	mutex_unlock(&mvm->mutex);
1303
1304	dev_kfree_skb(beacon);
1305
1306	rcu_read_unlock();
1307	return 0;
1308
1309out_err:
1310	rcu_read_unlock();
1311	return -EINVAL;
1312}
1313
1314static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm,
1315						char *buf, size_t count,
1316						loff_t *ppos)
1317{
1318	int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count);
1319
1320	mvm->hw->extra_beacon_tailroom = 0;
1321	return ret ?: count;
1322}
1323
1324static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm,
1325							char *buf,
1326							size_t count,
1327							loff_t *ppos)
1328{
1329	int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0);
1330
1331	mvm->hw->extra_beacon_tailroom = 0;
1332	mvm->beacon_inject_active = false;
1333	return ret ?: count;
1334}
1335
1336static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
1337					  char __user *user_buf,
1338					  size_t count, loff_t *ppos)
1339{
1340	struct iwl_mvm *mvm = file->private_data;
1341	int conf;
1342	char buf[8];
1343	const size_t bufsz = sizeof(buf);
1344	int pos = 0;
1345
1346	mutex_lock(&mvm->mutex);
1347	conf = mvm->fwrt.dump.conf;
1348	mutex_unlock(&mvm->mutex);
1349
1350	pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf);
1351
1352	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1353}
1354
1355static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
1356					   char *buf, size_t count,
1357					   loff_t *ppos)
1358{
1359	unsigned int conf_id;
1360	int ret;
1361
1362	if (!iwl_mvm_firmware_running(mvm))
1363		return -EIO;
1364
1365	ret = kstrtouint(buf, 0, &conf_id);
1366	if (ret)
1367		return ret;
1368
1369	if (WARN_ON(conf_id >= FW_DBG_CONF_MAX))
1370		return -EINVAL;
1371
1372	mutex_lock(&mvm->mutex);
1373	ret = iwl_fw_start_dbg_conf(&mvm->fwrt, conf_id);
1374	mutex_unlock(&mvm->mutex);
1375
1376	return ret ?: count;
1377}
1378
1379static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
1380					      char *buf, size_t count,
1381					      loff_t *ppos)
1382{
1383	if (count == 0)
1384		return 0;
1385
1386	iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER,
1387			       NULL);
1388
1389	iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
1390			   (count - 1), NULL);
1391
1392	return count;
1393}
1394
1395#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
1396#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1397static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
1398					    char __user *user_buf,
1399					    size_t count, loff_t *ppos)
1400{
1401	struct iwl_mvm *mvm = file->private_data;
1402	struct iwl_bcast_filter_cmd cmd;
1403	const struct iwl_fw_bcast_filter *filter;
1404	char *buf;
1405	int bufsz = 1024;
1406	int i, j, pos = 0;
1407	ssize_t ret;
1408
1409	buf = kzalloc(bufsz, GFP_KERNEL);
1410	if (!buf)
1411		return -ENOMEM;
1412
1413	mutex_lock(&mvm->mutex);
1414	if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
1415		ADD_TEXT("None\n");
1416		mutex_unlock(&mvm->mutex);
1417		goto out;
1418	}
1419	mutex_unlock(&mvm->mutex);
1420
1421	for (i = 0; cmd.filters[i].attrs[0].mask; i++) {
1422		filter = &cmd.filters[i];
1423
1424		ADD_TEXT("Filter [%d]:\n", i);
1425		ADD_TEXT("\tDiscard=%d\n", filter->discard);
1426		ADD_TEXT("\tFrame Type: %s\n",
1427			 filter->frame_type ? "IPv4" : "Generic");
1428
1429		for (j = 0; j < ARRAY_SIZE(filter->attrs); j++) {
1430			const struct iwl_fw_bcast_filter_attr *attr;
1431
1432			attr = &filter->attrs[j];
1433			if (!attr->mask)
1434				break;
1435
1436			ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n",
1437				 j, attr->offset,
1438				 attr->offset_type ? "IP End" :
1439						     "Payload Start",
1440				 be32_to_cpu(attr->mask),
1441				 be32_to_cpu(attr->val),
1442				 le16_to_cpu(attr->reserved1));
1443		}
1444	}
1445out:
1446	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1447	kfree(buf);
1448	return ret;
1449}
1450
1451static ssize_t iwl_dbgfs_bcast_filters_write(struct iwl_mvm *mvm, char *buf,
1452					     size_t count, loff_t *ppos)
1453{
1454	int pos, next_pos;
1455	struct iwl_fw_bcast_filter filter = {};
1456	struct iwl_bcast_filter_cmd cmd;
1457	u32 filter_id, attr_id, mask, value;
1458	int err = 0;
1459
1460	if (sscanf(buf, "%d %hhi %hhi %n", &filter_id, &filter.discard,
1461		   &filter.frame_type, &pos) != 3)
1462		return -EINVAL;
1463
1464	if (filter_id >= ARRAY_SIZE(mvm->dbgfs_bcast_filtering.cmd.filters) ||
1465	    filter.frame_type > BCAST_FILTER_FRAME_TYPE_IPV4)
1466		return -EINVAL;
1467
1468	for (attr_id = 0; attr_id < ARRAY_SIZE(filter.attrs);
1469	     attr_id++) {
1470		struct iwl_fw_bcast_filter_attr *attr =
1471				&filter.attrs[attr_id];
1472
1473		if (pos >= count)
1474			break;
1475
1476		if (sscanf(&buf[pos], "%hhi %hhi %i %i %n",
1477			   &attr->offset, &attr->offset_type,
1478			   &mask, &value, &next_pos) != 4)
1479			return -EINVAL;
1480
1481		attr->mask = cpu_to_be32(mask);
1482		attr->val = cpu_to_be32(value);
1483		if (mask)
1484			filter.num_attrs++;
1485
1486		pos += next_pos;
1487	}
1488
1489	mutex_lock(&mvm->mutex);
1490	memcpy(&mvm->dbgfs_bcast_filtering.cmd.filters[filter_id],
1491	       &filter, sizeof(filter));
1492
1493	/* send updated bcast filtering configuration */
1494	if (iwl_mvm_firmware_running(mvm) &&
1495	    mvm->dbgfs_bcast_filtering.override &&
1496	    iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1497		err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
1498					   sizeof(cmd), &cmd);
1499	mutex_unlock(&mvm->mutex);
1500
1501	return err ?: count;
1502}
1503
1504static ssize_t iwl_dbgfs_bcast_filters_macs_read(struct file *file,
1505						 char __user *user_buf,
1506						 size_t count, loff_t *ppos)
1507{
1508	struct iwl_mvm *mvm = file->private_data;
1509	struct iwl_bcast_filter_cmd cmd;
1510	char *buf;
1511	int bufsz = 1024;
1512	int i, pos = 0;
1513	ssize_t ret;
1514
1515	buf = kzalloc(bufsz, GFP_KERNEL);
1516	if (!buf)
1517		return -ENOMEM;
1518
1519	mutex_lock(&mvm->mutex);
1520	if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
1521		ADD_TEXT("None\n");
1522		mutex_unlock(&mvm->mutex);
1523		goto out;
1524	}
1525	mutex_unlock(&mvm->mutex);
1526
1527	for (i = 0; i < ARRAY_SIZE(cmd.macs); i++) {
1528		const struct iwl_fw_bcast_mac *mac = &cmd.macs[i];
1529
1530		ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n",
1531			 i, mac->default_discard, mac->attached_filters);
1532	}
1533out:
1534	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1535	kfree(buf);
1536	return ret;
1537}
1538
1539static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
1540						  char *buf, size_t count,
1541						  loff_t *ppos)
1542{
1543	struct iwl_bcast_filter_cmd cmd;
1544	struct iwl_fw_bcast_mac mac = {};
1545	u32 mac_id, attached_filters;
1546	int err = 0;
1547
1548	if (!mvm->bcast_filters)
1549		return -ENOENT;
1550
1551	if (sscanf(buf, "%d %hhi %i", &mac_id, &mac.default_discard,
1552		   &attached_filters) != 3)
1553		return -EINVAL;
1554
1555	if (mac_id >= ARRAY_SIZE(cmd.macs) ||
1556	    mac.default_discard > 1 ||
1557	    attached_filters >= BIT(ARRAY_SIZE(cmd.filters)))
1558		return -EINVAL;
1559
1560	mac.attached_filters = cpu_to_le16(attached_filters);
1561
1562	mutex_lock(&mvm->mutex);
1563	memcpy(&mvm->dbgfs_bcast_filtering.cmd.macs[mac_id],
1564	       &mac, sizeof(mac));
1565
1566	/* send updated bcast filtering configuration */
1567	if (iwl_mvm_firmware_running(mvm) &&
1568	    mvm->dbgfs_bcast_filtering.override &&
1569	    iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1570		err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
1571					   sizeof(cmd), &cmd);
1572	mutex_unlock(&mvm->mutex);
1573
1574	return err ?: count;
1575}
1576#endif
1577
1578#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1579	_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1580#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1581	_MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1582#define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do {	\
1583		debugfs_create_file(alias, mode, parent, mvm,		\
1584				    &iwl_dbgfs_##name##_ops);		\
1585	} while (0)
1586#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
1587	MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
1588
1589#define MVM_DEBUGFS_WRITE_STA_FILE_OPS(name, bufsz) \
1590	_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1591#define MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(name, bufsz) \
1592	_MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
1593
1594#define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do {	\
1595		debugfs_create_file(alias, mode, parent, sta,		\
1596				    &iwl_dbgfs_##name##_ops);		\
1597	} while (0)
1598#define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \
1599	MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode)
1600
1601static ssize_t
1602iwl_dbgfs_prph_reg_read(struct file *file,
1603			char __user *user_buf,
1604			size_t count, loff_t *ppos)
1605{
1606	struct iwl_mvm *mvm = file->private_data;
1607	int pos = 0;
1608	char buf[32];
1609	const size_t bufsz = sizeof(buf);
1610
1611	if (!mvm->dbgfs_prph_reg_addr)
1612		return -EINVAL;
1613
1614	pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
1615		mvm->dbgfs_prph_reg_addr,
1616		iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
1617
1618	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1619}
1620
1621static ssize_t
1622iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
1623			 size_t count, loff_t *ppos)
1624{
1625	u8 args;
1626	u32 value;
1627
1628	args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
1629	/* if we only want to set the reg address - nothing more to do */
1630	if (args == 1)
1631		goto out;
1632
1633	/* otherwise, make sure we have both address and value */
1634	if (args != 2)
1635		return -EINVAL;
1636
1637	iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
1638
1639out:
1640	return count;
1641}
1642
1643static ssize_t
1644iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf,
1645			      size_t count, loff_t *ppos)
1646{
1647	int ret;
1648
1649	if (!iwl_mvm_firmware_running(mvm))
1650		return -EIO;
1651
1652	mutex_lock(&mvm->mutex);
1653	ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
1654	mutex_unlock(&mvm->mutex);
1655
1656	return ret ?: count;
1657}
1658
1659struct iwl_mvm_sniffer_apply {
1660	struct iwl_mvm *mvm;
1661	u8 *bssid;
1662	u16 aid;
1663};
1664
1665static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data,
1666				  struct iwl_rx_packet *pkt, void *data)
1667{
1668	struct iwl_mvm_sniffer_apply *apply = data;
1669
1670	apply->mvm->cur_aid = cpu_to_le16(apply->aid);
1671	memcpy(apply->mvm->cur_bssid, apply->bssid,
1672	       sizeof(apply->mvm->cur_bssid));
1673
1674	return true;
1675}
1676
1677static ssize_t
1678iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
1679				  size_t count, loff_t *ppos)
1680{
1681	struct iwl_notification_wait wait;
1682	struct iwl_he_monitor_cmd he_mon_cmd = {};
1683	struct iwl_mvm_sniffer_apply apply = {
1684		.mvm = mvm,
1685	};
1686	u16 wait_cmds[] = {
1687		iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD, DATA_PATH_GROUP, 0),
1688	};
1689	u32 aid;
1690	int ret;
1691
1692	if (!iwl_mvm_firmware_running(mvm))
1693		return -EIO;
1694
1695	ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid,
1696		     &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1],
1697		     &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3],
1698		     &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]);
1699	if (ret != 7)
1700		return -EINVAL;
1701
1702	he_mon_cmd.aid = cpu_to_le16(aid);
1703
1704	apply.aid = aid;
1705	apply.bssid = (void *)he_mon_cmd.bssid;
1706
1707	mutex_lock(&mvm->mutex);
1708
1709	/*
1710	 * Use the notification waiter to get our function triggered
1711	 * in sequence with other RX. This ensures that frames we get
1712	 * on the RX queue _before_ the new configuration is applied
1713	 * still have mvm->cur_aid pointing to the old AID, and that
1714	 * frames on the RX queue _after_ the firmware processed the
1715	 * new configuration (and sent the response, synchronously)
1716	 * get mvm->cur_aid correctly set to the new AID.
1717	 */
1718	iwl_init_notification_wait(&mvm->notif_wait, &wait,
1719				   wait_cmds, ARRAY_SIZE(wait_cmds),
1720				   iwl_mvm_sniffer_apply, &apply);
1721
1722	ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD,
1723						   DATA_PATH_GROUP, 0), 0,
1724				   sizeof(he_mon_cmd), &he_mon_cmd);
1725
1726	/* no need to really wait, we already did anyway */
1727	iwl_remove_notification(&mvm->notif_wait, &wait);
1728
1729	mutex_unlock(&mvm->mutex);
1730
1731	return ret ?: count;
1732}
1733
1734static ssize_t
1735iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf,
1736				 size_t count, loff_t *ppos)
1737{
1738	struct iwl_mvm *mvm = file->private_data;
1739	u8 buf[32];
1740	int len;
1741
1742	len = scnprintf(buf, sizeof(buf),
1743			"%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1744			le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0],
1745			mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3],
1746			mvm->cur_bssid[4], mvm->cur_bssid[5]);
1747
1748	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1749}
1750
1751static ssize_t
1752iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
1753				  size_t count, loff_t *ppos)
1754{
1755	struct iwl_mvm *mvm = file->private_data;
1756	u8 buf[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM * ETH_ALEN * 3 + 1];
1757	unsigned int pos = 0;
1758	size_t bufsz = sizeof(buf);
1759	int i;
1760
1761	mutex_lock(&mvm->mutex);
1762
1763	for (i = 0; i < IWL_MVM_UAPSD_NOAGG_LIST_LEN; i++)
1764		pos += scnprintf(buf + pos, bufsz - pos, "%pM\n",
1765				 mvm->uapsd_noagg_bssids[i].addr);
1766
1767	mutex_unlock(&mvm->mutex);
1768
1769	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1770}
1771
1772static ssize_t
1773iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm,
1774			   char *buf, size_t count, loff_t *ppos)
1775{
1776	int ret;
1777	struct iwl_ltr_config_cmd ltr_config = {0};
1778
1779	if (!iwl_mvm_firmware_running(mvm))
1780		return -EIO;
1781
1782	if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x",
1783		   &ltr_config.flags,
1784		   &ltr_config.static_long,
1785		   &ltr_config.static_short,
1786		   &ltr_config.ltr_cfg_values[0],
1787		   &ltr_config.ltr_cfg_values[1],
1788		   &ltr_config.ltr_cfg_values[2],
1789		   &ltr_config.ltr_cfg_values[3]) != 7) {
1790		return -EINVAL;
1791	}
1792
1793	mutex_lock(&mvm->mutex);
1794	ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config),
1795				   &ltr_config);
1796	mutex_unlock(&mvm->mutex);
1797
1798	if (ret)
1799		IWL_ERR(mvm, "failed to send ltr configuration cmd\n");
1800
1801	return ret ?: count;
1802}
1803
1804MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
1805
1806/* Device wide debugfs entries */
1807MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget);
1808MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8);
1809MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8);
1810MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1811MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
1812MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8);
1813MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1814MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
1815MVM_DEBUGFS_READ_FILE_OPS(nic_temp);
1816MVM_DEBUGFS_READ_FILE_OPS(stations);
1817MVM_DEBUGFS_READ_FILE_OPS(rs_data);
1818MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1819MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
1820MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
1821MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1822MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
1823MVM_DEBUGFS_READ_FILE_OPS(fw_ver);
1824MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1825MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
1826MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
1827MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
1828MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1829MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
1830MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
1831MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
1832			   (IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
1833MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512);
1834MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512);
1835MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);
1836
1837MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);
1838
1839#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1840MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
1841MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
1842#endif
1843
1844#ifdef CONFIG_ACPI
1845MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
1846#endif
1847
1848MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16);
1849
1850MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
1851
1852MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512);
1853
1854static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
1855				  size_t count, loff_t *ppos)
1856{
1857	struct iwl_mvm *mvm = file->private_data;
1858	struct iwl_dbg_mem_access_cmd cmd = {};
1859	struct iwl_dbg_mem_access_rsp *rsp;
1860	struct iwl_host_cmd hcmd = {
1861		.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
1862		.data = { &cmd, },
1863		.len = { sizeof(cmd) },
1864	};
1865	size_t delta;
1866	ssize_t ret, len;
1867
1868	if (!iwl_mvm_firmware_running(mvm))
1869		return -EIO;
1870
1871	hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR,
1872			     DEBUG_GROUP, 0);
1873	cmd.op = cpu_to_le32(DEBUG_MEM_OP_READ);
1874
1875	/* Take care of alignment of both the position and the length */
1876	delta = *ppos & 0x3;
1877	cmd.addr = cpu_to_le32(*ppos - delta);
1878	cmd.len = cpu_to_le32(min(ALIGN(count + delta, 4) / 4,
1879				  (size_t)DEBUG_MEM_MAX_SIZE_DWORDS));
1880
1881	mutex_lock(&mvm->mutex);
1882	ret = iwl_mvm_send_cmd(mvm, &hcmd);
1883	mutex_unlock(&mvm->mutex);
1884
1885	if (ret < 0)
1886		return ret;
1887
1888	if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
1889		ret = -EIO;
1890		goto out;
1891	}
1892
1893	rsp = (void *)hcmd.resp_pkt->data;
1894	if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) {
1895		ret = -ENXIO;
1896		goto out;
1897	}
1898
1899	len = min((size_t)le32_to_cpu(rsp->len) << 2,
1900		  iwl_rx_packet_payload_len(hcmd.resp_pkt) - sizeof(*rsp));
1901	len = min(len - delta, count);
1902	if (len < 0) {
1903		ret = -EFAULT;
1904		goto out;
1905	}
1906
1907	ret = len - copy_to_user(user_buf, (void *)rsp->data + delta, len);
1908	*ppos += ret;
1909
1910out:
1911	iwl_free_resp(&hcmd);
1912	return ret;
1913}
1914
1915static ssize_t iwl_dbgfs_mem_write(struct file *file,
1916				   const char __user *user_buf, size_t count,
1917				   loff_t *ppos)
1918{
1919	struct iwl_mvm *mvm = file->private_data;
1920	struct iwl_dbg_mem_access_cmd *cmd;
1921	struct iwl_dbg_mem_access_rsp *rsp;
1922	struct iwl_host_cmd hcmd = {};
1923	size_t cmd_size;
1924	size_t data_size;
1925	u32 op, len;
1926	ssize_t ret;
1927
1928	if (!iwl_mvm_firmware_running(mvm))
1929		return -EIO;
1930
1931	hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR,
1932			     DEBUG_GROUP, 0);
1933
1934	if (*ppos & 0x3 || count < 4) {
1935		op = DEBUG_MEM_OP_WRITE_BYTES;
1936		len = min(count, (size_t)(4 - (*ppos & 0x3)));
1937		data_size = len;
1938	} else {
1939		op = DEBUG_MEM_OP_WRITE;
1940		len = min(count >> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS);
1941		data_size = len << 2;
1942	}
1943
1944	cmd_size = sizeof(*cmd) + ALIGN(data_size, 4);
1945	cmd = kzalloc(cmd_size, GFP_KERNEL);
1946	if (!cmd)
1947		return -ENOMEM;
1948
1949	cmd->op = cpu_to_le32(op);
1950	cmd->len = cpu_to_le32(len);
1951	cmd->addr = cpu_to_le32(*ppos);
1952	if (copy_from_user((void *)cmd->data, user_buf, data_size)) {
1953		kfree(cmd);
1954		return -EFAULT;
1955	}
1956
1957	hcmd.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
1958	hcmd.data[0] = (void *)cmd;
1959	hcmd.len[0] = cmd_size;
1960
1961	mutex_lock(&mvm->mutex);
1962	ret = iwl_mvm_send_cmd(mvm, &hcmd);
1963	mutex_unlock(&mvm->mutex);
1964
1965	kfree(cmd);
1966
1967	if (ret < 0)
1968		return ret;
1969
1970	if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) {
1971		ret = -EIO;
1972		goto out;
1973	}
1974
1975	rsp = (void *)hcmd.resp_pkt->data;
1976	if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) {
1977		ret = -ENXIO;
1978		goto out;
1979	}
1980
1981	ret = data_size;
1982	*ppos += ret;
1983
1984out:
1985	iwl_free_resp(&hcmd);
1986	return ret;
1987}
1988
1989static const struct file_operations iwl_dbgfs_mem_ops = {
1990	.read = iwl_dbgfs_mem_read,
1991	.write = iwl_dbgfs_mem_write,
1992	.open = simple_open,
1993	.llseek = default_llseek,
1994};
1995
1996void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
1997			     struct ieee80211_vif *vif,
1998			     struct ieee80211_sta *sta,
1999			     struct dentry *dir)
2000{
2001	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2002
2003	if (iwl_mvm_has_tlc_offload(mvm)) {
2004		MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, 0400);
2005	}
2006	MVM_DEBUGFS_ADD_STA_FILE(amsdu_len, dir, 0600);
2007}
2008
2009void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
2010{
2011	struct dentry *bcast_dir __maybe_unused;
2012	char buf[100];
2013
2014	spin_lock_init(&mvm->drv_stats_lock);
2015
2016	mvm->debugfs_dir = dbgfs_dir;
2017
2018	MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200);
2019	MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, 0200);
2020	MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600);
2021	MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600);
2022	MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, 0400);
2023	MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, 0400);
2024	MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, 0200);
2025	MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, 0200);
2026	MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, 0400);
2027	MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, 0400);
2028	MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, 0400);
2029	MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600);
2030	MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400);
2031	MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400);
2032	MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, 0400);
2033	MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, 0200);
2034	MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, 0200);
2035	MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, 0200);
2036	MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200);
2037	MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600);
2038	MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
2039	MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
2040	MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
2041	MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
2042	MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200);
2043	MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200);
2044	MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200);
2045	MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200);
2046#ifdef CONFIG_ACPI
2047	MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400);
2048#endif
2049	MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
2050
2051	if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
2052		MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200);
2053
2054	debugfs_create_bool("enable_scan_iteration_notif", 0600,
2055			    mvm->debugfs_dir, &mvm->scan_iter_notif_enabled);
2056	debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir,
2057			    &mvm->drop_bcn_ap_mode);
2058
2059	MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR);
2060
2061#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
2062	if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
2063		bcast_dir = debugfs_create_dir("bcast_filtering",
2064					       mvm->debugfs_dir);
2065
2066		debugfs_create_bool("override", 0600, bcast_dir,
2067				    &mvm->dbgfs_bcast_filtering.override);
2068
2069		MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters,
2070					   bcast_dir, 0600);
2071		MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs,
2072					   bcast_dir, 0600);
2073	}
2074#endif
2075
2076#ifdef CONFIG_PM_SLEEP
2077	MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
2078	debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
2079			    &mvm->d3_wake_sysassert);
2080	debugfs_create_u32("last_netdetect_scans", 0400, mvm->debugfs_dir,
2081			   &mvm->last_netdetect_scans);
2082#endif
2083
2084	debugfs_create_u8("ps_disabled", 0400, mvm->debugfs_dir,
2085			  &mvm->ps_disabled);
2086	debugfs_create_blob("nvm_hw", 0400, mvm->debugfs_dir,
2087			    &mvm->nvm_hw_blob);
2088	debugfs_create_blob("nvm_sw", 0400, mvm->debugfs_dir,
2089			    &mvm->nvm_sw_blob);
2090	debugfs_create_blob("nvm_calib", 0400, mvm->debugfs_dir,
2091			    &mvm->nvm_calib_blob);
2092	debugfs_create_blob("nvm_prod", 0400, mvm->debugfs_dir,
2093			    &mvm->nvm_prod_blob);
2094	debugfs_create_blob("nvm_phy_sku", 0400, mvm->debugfs_dir,
2095			    &mvm->nvm_phy_sku_blob);
2096	debugfs_create_blob("nvm_reg", S_IRUSR,
2097			    mvm->debugfs_dir, &mvm->nvm_reg_blob);
2098
2099	debugfs_create_file("mem", 0600, dbgfs_dir, mvm, &iwl_dbgfs_mem_ops);
2100
2101	/*
2102	 * Create a symlink with mac80211. It will be removed when mac80211
2103	 * exists (before the opmode exists which removes the target.)
2104	 */
2105	snprintf(buf, 100, "../../%pd2", dbgfs_dir->d_parent);
2106	debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf);
2107}
2108