[go: nahoru, domu]

1820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg/******************************************************************************
2820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
3820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * This file is provided under a dual BSD/GPLv2 license.  When using or
4820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * redistributing this file, you may do so under either license.
5820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
6820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * GPL LICENSE SUMMARY
7820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
851368bf792c79eb917694a4155d62f04359e3734Emmanuel Grumbach * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
98b4139dc9f2171f313fc703c08269f6f8a6f6fc4Johannes Berg * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
11820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * This program is free software; you can redistribute it and/or modify
12820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * it under the terms of version 2 of the GNU General Public License as
13820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * published by the Free Software Foundation.
14820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
15820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * This program is distributed in the hope that it will be useful, but
16820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * WITHOUT ANY WARRANTY; without even the implied warranty of
17820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * General Public License for more details.
19820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
20820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * You should have received a copy of the GNU General Public License
21820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * along with this program; if not, write to the Free Software
22820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
23820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * USA
24820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
25820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * The full GNU General Public License is included in this distribution
26820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * in the file called COPYING.
27820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
28820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * Contact Information:
29820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *  Intel Linux Wireless <ilw@linux.intel.com>
30820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
31820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
32820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * BSD LICENSE
33820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
3451368bf792c79eb917694a4155d62f04359e3734Emmanuel Grumbach * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
358b4139dc9f2171f313fc703c08269f6f8a6f6fc4Johannes Berg * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
36820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * All rights reserved.
37820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
38820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * Redistribution and use in source and binary forms, with or without
39820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * modification, are permitted provided that the following conditions
40820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * are met:
41820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
42820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *  * Redistributions of source code must retain the above copyright
43820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *    notice, this list of conditions and the following disclaimer.
44820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *  * Redistributions in binary form must reproduce the above copyright
45820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *    notice, this list of conditions and the following disclaimer in
46820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *    the documentation and/or other materials provided with the
47820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *    distribution.
48820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *  * Neither the name Intel Corporation nor the names of its
49820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *    contributors may be used to endorse or promote products derived
50820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *    from this software without specific prior written permission.
51820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
52820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
53820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
54820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
55820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
56820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
57820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
58820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
59820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
60820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
62820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *
64820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg *****************************************************************************/
65820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg#include "mvm.h"
66820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg#include "debugfs.h"
67820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
68e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondarstatic void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
69e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar				 struct ieee80211_vif *vif,
70e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar				 enum iwl_dbgfs_pm_mask param, int val)
71e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar{
72e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
73e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
74e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
75e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	dbgfs_pm->mask |= param;
76e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
77e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	switch (param) {
78e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_KEEP_ALIVE: {
79717e2390dc72e87380d6ccf62134b0ab84ee43d2Emmanuel Grumbach		int dtimper = vif->bss_conf.dtim_period ?: 1;
80e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
81e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
82e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
83e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (val * MSEC_PER_SEC < 3 * dtimper_msec)
84e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			IWL_WARN(mvm,
85e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar				 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
86e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar				 val * MSEC_PER_SEC, 3 * dtimper_msec);
87e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->keep_alive_seconds = val;
88e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
89e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	}
90e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
91e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
92e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar				val ? "enabled" : "disabled");
93e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->skip_over_dtim = val;
94e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
95e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
96e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
97e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->skip_dtim_periods = val;
98e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
99e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
100e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
101e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->rx_data_timeout = val;
102e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
103e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
104e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
105e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->tx_data_timeout = val;
106e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
107e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_LPRX_ENA:
108e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
109e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->lprx_ena = val;
110e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
111e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
112e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
113e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->lprx_rssi_threshold = val;
114e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
115e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_SNOOZE_ENABLE:
116e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "snooze_enable=%d\n", val);
117e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->snooze_ena = val;
118e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
119e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_PM_UAPSD_MISBEHAVING:
120e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val);
121e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_pm->uapsd_misbehaving = val;
122e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
12384fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller	case MVM_DEBUGFS_PM_USE_PS_POLL:
12484fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller		IWL_DEBUG_POWER(mvm, "use_ps_poll=%d\n", val);
12584fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller		dbgfs_pm->use_ps_poll = val;
12684fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller		break;
127e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	}
128e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar}
129e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
130e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondarstatic ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf,
131e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					 size_t count, loff_t *ppos)
132e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar{
133e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
134e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm *mvm = mvmvif->mvm;
135e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	enum iwl_dbgfs_pm_mask param;
136e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	int val, ret;
137e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
138e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	if (!strncmp("keep_alive=", buf, 11)) {
139e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 11, "%d", &val) != 1)
140e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
141e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_KEEP_ALIVE;
142e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("skip_over_dtim=", buf, 15)) {
143e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 15, "%d", &val) != 1)
144e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
145e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
146e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("skip_dtim_periods=", buf, 18)) {
147e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 18, "%d", &val) != 1)
148e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
149e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
150e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("rx_data_timeout=", buf, 16)) {
151e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 16, "%d", &val) != 1)
152e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
153e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
154e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("tx_data_timeout=", buf, 16)) {
155e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 16, "%d", &val) != 1)
156e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
157e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
158e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("lprx=", buf, 5)) {
159e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 5, "%d", &val) != 1)
160e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
161e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_LPRX_ENA;
162e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
163e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 20, "%d", &val) != 1)
164e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
165e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
166e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    POWER_LPRX_RSSI_THRESHOLD_MIN)
167e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
168e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
169e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("snooze_enable=", buf, 14)) {
170e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 14, "%d", &val) != 1)
171e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
172e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_SNOOZE_ENABLE;
173e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("uapsd_misbehaving=", buf, 18)) {
174e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf + 18, "%d", &val) != 1)
175e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
176e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING;
17784fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller	} else if (!strncmp("use_ps_poll=", buf, 12)) {
17884fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller		if (sscanf(buf + 12, "%d", &val) != 1)
17984fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller			return -EINVAL;
18084fd7608a0d7b9e7ce350aab278780a3e341628fEliad Peller		param = MVM_DEBUGFS_PM_USE_PS_POLL;
181e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else {
182e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		return -EINVAL;
183e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	}
184e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
185e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	mutex_lock(&mvm->mutex);
186e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	iwl_dbgfs_update_pm(mvm, vif, param, val);
187999609f1206a14039db534058b251c6d5ab39322Arik Nemtsov	ret = iwl_mvm_power_update_mac(mvm);
188e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	mutex_unlock(&mvm->mutex);
189e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
190e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	return ret ?: count;
191e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar}
192e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
193e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondarstatic ssize_t iwl_dbgfs_pm_params_read(struct file *file,
194e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					char __user *user_buf,
195e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					size_t count, loff_t *ppos)
196e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar{
197e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct ieee80211_vif *vif = file->private_data;
198e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
199e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm *mvm = mvmvif->mvm;
200e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	char buf[512];
201e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	int bufsz = sizeof(buf);
202e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	int pos;
203e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
204c1cb92fc1ecd2159b7fb148ed8d5f09d511ae030Emmanuel Grumbach	pos = iwl_mvm_power_mac_dbgfs_read(mvm, vif, buf, bufsz);
205e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
206e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
207e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar}
208e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
209820a1a50025550061b0d0ea15a760ecd183886f7Johannes Bergstatic ssize_t iwl_dbgfs_mac_params_read(struct file *file,
210820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg					 char __user *user_buf,
211820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg					 size_t count, loff_t *ppos)
212820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg{
213820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	struct ieee80211_vif *vif = file->private_data;
214820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2157f09d70436729dee9dfa7ab11fda9d384c4bdf9fJohannes Berg	struct iwl_mvm *mvm = mvmvif->mvm;
216820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	u8 ap_sta_id;
217820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	struct ieee80211_chanctx_conf *chanctx_conf;
218820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	char buf[512];
219820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	int bufsz = sizeof(buf);
220820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	int pos = 0;
221820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	int i;
222820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
223820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	mutex_lock(&mvm->mutex);
224820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
225820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	ap_sta_id = mvmvif->ap_sta_id;
226820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
2272284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	switch (ieee80211_vif_type_p2p(vif)) {
2282284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	case NL80211_IFTYPE_ADHOC:
2292284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		pos += scnprintf(buf+pos, bufsz-pos, "type: ibss\n");
2302284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		break;
2312284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	case NL80211_IFTYPE_STATION:
2322284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		pos += scnprintf(buf+pos, bufsz-pos, "type: bss\n");
2332284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		break;
2342284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	case NL80211_IFTYPE_AP:
2352284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		pos += scnprintf(buf+pos, bufsz-pos, "type: ap\n");
2362284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		break;
2372284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	case NL80211_IFTYPE_P2P_CLIENT:
2382284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		pos += scnprintf(buf+pos, bufsz-pos, "type: p2p client\n");
2392284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		break;
2402284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	case NL80211_IFTYPE_P2P_GO:
2412284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		pos += scnprintf(buf+pos, bufsz-pos, "type: p2p go\n");
2422284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		break;
2432284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	case NL80211_IFTYPE_P2P_DEVICE:
2442284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		pos += scnprintf(buf+pos, bufsz-pos, "type: p2p dev\n");
2452284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		break;
2462284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	default:
2472284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach		break;
2482284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach	}
2492284b951fbad502680a0e1ba35a8efc965d6b6ceEmmanuel Grumbach
250820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
251820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg			 mvmvif->id, mvmvif->color);
252820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
253820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg			 vif->bss_conf.bssid);
254820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
255820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
256820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		pos += scnprintf(buf+pos, bufsz-pos,
257820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
258820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 i, mvmvif->queue_params[i].txop,
259820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 mvmvif->queue_params[i].cw_min,
260820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 mvmvif->queue_params[i].cw_max,
261820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 mvmvif->queue_params[i].aifs,
262820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 mvmvif->queue_params[i].uapsd);
263820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
264820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	if (vif->type == NL80211_IFTYPE_STATION &&
265820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	    ap_sta_id != IWL_MVM_STATION_COUNT) {
266820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		struct ieee80211_sta *sta;
267820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
268820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
269820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg						lockdep_is_held(&mvm->mutex));
2701ddbbb0c83de82599b1baf14bf6bb69a774d4fc7Johannes Berg		if (!IS_ERR_OR_NULL(sta)) {
2711ddbbb0c83de82599b1baf14bf6bb69a774d4fc7Johannes Berg			struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
2721ddbbb0c83de82599b1baf14bf6bb69a774d4fc7Johannes Berg
2731ddbbb0c83de82599b1baf14bf6bb69a774d4fc7Johannes Berg			pos += scnprintf(buf+pos, bufsz-pos,
2741fa477c65a404a9e5a961efcf2acd1efc5eedd04Emmanuel Grumbach					 "ap_sta_id %d - reduced Tx power %d\n",
2751ddbbb0c83de82599b1baf14bf6bb69a774d4fc7Johannes Berg					 ap_sta_id,
2761fa477c65a404a9e5a961efcf2acd1efc5eedd04Emmanuel Grumbach					 mvm_sta->bt_reduced_txpower);
2771ddbbb0c83de82599b1baf14bf6bb69a774d4fc7Johannes Berg		}
278820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	}
279820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
280820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	rcu_read_lock();
281820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	chanctx_conf = rcu_dereference(vif->chanctx_conf);
282820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	if (chanctx_conf)
283820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		pos += scnprintf(buf+pos, bufsz-pos,
284820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 "idle rx chains %d, active rx chains: %d\n",
285820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 chanctx_conf->rx_chains_static,
286820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg				 chanctx_conf->rx_chains_dynamic);
287820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	rcu_read_unlock();
288820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
289820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	mutex_unlock(&mvm->mutex);
290820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
291820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
292820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg}
293820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
294e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondarstatic void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
295e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar				enum iwl_dbgfs_bf_mask param, int value)
296e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar{
297e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
298e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
299e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
300e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	dbgfs_bf->mask |= param;
301e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
302e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	switch (param) {
303e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_ENERGY_DELTA:
304e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_energy_delta = value;
305e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
306e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
307e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_roaming_energy_delta = value;
308e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
309e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_ROAMING_STATE:
310e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_roaming_state = value;
311e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
312e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_TEMP_THRESHOLD:
313e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_temp_threshold = value;
314e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
315e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_TEMP_FAST_FILTER:
316e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_temp_fast_filter = value;
317e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
318e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_TEMP_SLOW_FILTER:
319e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_temp_slow_filter = value;
320e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
321e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
322e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_enable_beacon_filter = value;
323e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
324e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_DEBUG_FLAG:
325e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_debug_flag = value;
326e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
327e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BF_ESCAPE_TIMER:
328e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->bf_escape_timer = value;
329e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
330e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
331e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->ba_enable_beacon_abort = value;
332e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
333e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	case MVM_DEBUGFS_BA_ESCAPE_TIMER:
334e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		dbgfs_bf->ba_escape_timer = value;
335e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		break;
336e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	}
337e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar}
338e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
339e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondarstatic ssize_t iwl_dbgfs_bf_params_write(struct ieee80211_vif *vif, char *buf,
340e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					 size_t count, loff_t *ppos)
341e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar{
342e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
343e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm *mvm = mvmvif->mvm;
344e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	enum iwl_dbgfs_bf_mask param;
345e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	int value, ret = 0;
346e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
347e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	if (!strncmp("bf_energy_delta=", buf, 16)) {
348e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+16, "%d", &value) != 1)
349e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
350e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BF_ENERGY_DELTA_MIN ||
351e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BF_ENERGY_DELTA_MAX)
352e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
353e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_ENERGY_DELTA;
354e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
355e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+24, "%d", &value) != 1)
356e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
357e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
358e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
359e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
360e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
361e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_roaming_state=", buf, 17)) {
362e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+17, "%d", &value) != 1)
363e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
364e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BF_ROAMING_STATE_MIN ||
365e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BF_ROAMING_STATE_MAX)
366e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
367e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_ROAMING_STATE;
368e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_temp_threshold=", buf, 18)) {
369e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+18, "%d", &value) != 1)
370e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
371e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BF_TEMP_THRESHOLD_MIN ||
372e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BF_TEMP_THRESHOLD_MAX)
373e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
374e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_TEMP_THRESHOLD;
375e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_temp_fast_filter=", buf, 20)) {
376e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+20, "%d", &value) != 1)
377e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
378e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BF_TEMP_FAST_FILTER_MIN ||
379e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BF_TEMP_FAST_FILTER_MAX)
380e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
381e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_TEMP_FAST_FILTER;
382e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_temp_slow_filter=", buf, 20)) {
383e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+20, "%d", &value) != 1)
384e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
385e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BF_TEMP_SLOW_FILTER_MIN ||
386e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BF_TEMP_SLOW_FILTER_MAX)
387e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
388e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_TEMP_SLOW_FILTER;
389e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
390e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+24, "%d", &value) != 1)
391e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
392e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < 0 || value > 1)
393e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
394e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
395e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_debug_flag=", buf, 14)) {
396e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+14, "%d", &value) != 1)
397e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
398e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < 0 || value > 1)
399e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
400e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_DEBUG_FLAG;
401e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("bf_escape_timer=", buf, 16)) {
402e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+16, "%d", &value) != 1)
403e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
404e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BF_ESCAPE_TIMER_MIN ||
405e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BF_ESCAPE_TIMER_MAX)
406e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
407e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
408e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("ba_escape_timer=", buf, 16)) {
409e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+16, "%d", &value) != 1)
410e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
411e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < IWL_BA_ESCAPE_TIMER_MIN ||
412e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		    value > IWL_BA_ESCAPE_TIMER_MAX)
413e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
414e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
415e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
416e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (sscanf(buf+23, "%d", &value) != 1)
417e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
418e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		if (value < 0 || value > 1)
419e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			return -EINVAL;
420e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
421e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	} else {
422e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		return -EINVAL;
423e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	}
424e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
425e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	mutex_lock(&mvm->mutex);
426e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	iwl_dbgfs_update_bf(vif, param, value);
427e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value)
428a10229271946731959b2269370d0492d88cfab23Emmanuel Grumbach		ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
429e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	else
430a10229271946731959b2269370d0492d88cfab23Emmanuel Grumbach		ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
431e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	mutex_unlock(&mvm->mutex);
432e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
433e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	return ret ?: count;
434e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar}
435e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
436e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondarstatic ssize_t iwl_dbgfs_bf_params_read(struct file *file,
437e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					char __user *user_buf,
438e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					size_t count, loff_t *ppos)
439e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar{
440e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct ieee80211_vif *vif = file->private_data;
441e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
442e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	char buf[256];
443e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	int pos = 0;
444e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	const size_t bufsz = sizeof(buf);
445e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	struct iwl_beacon_filter_cmd cmd = {
446e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		IWL_BF_CMD_CONFIG_DEFAULTS,
447e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		.bf_enable_beacon_filter =
448e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			cpu_to_le32(IWL_BF_ENABLE_BEACON_FILTER_DEFAULT),
449e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		.ba_enable_beacon_abort =
450e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			cpu_to_le32(IWL_BA_ENABLE_BEACON_ABORT_DEFAULT),
451e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	};
452e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
453e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
454e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	if (mvmvif->bf_data.bf_enabled)
455e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		cmd.bf_enable_beacon_filter = cpu_to_le32(1);
456e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	else
457e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		cmd.bf_enable_beacon_filter = 0;
458e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
459e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
460e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_energy_delta));
461e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
462e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_roaming_energy_delta));
463e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
464e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_roaming_state));
465e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_threshold = %d\n",
466e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_temp_threshold));
467e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_fast_filter = %d\n",
468e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_temp_fast_filter));
469e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_slow_filter = %d\n",
470e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_temp_slow_filter));
471e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
472e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_enable_beacon_filter));
473e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
474e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_debug_flag));
475e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
476e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.bf_escape_timer));
477e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
478e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.ba_escape_timer));
479e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
480e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar			 le32_to_cpu(cmd.ba_enable_beacon_abort));
481e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
482e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
483e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar}
484e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
485a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Bergstatic ssize_t iwl_dbgfs_low_latency_write(struct ieee80211_vif *vif, char *buf,
486a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg					   size_t count, loff_t *ppos)
487a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg{
488a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
489a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	struct iwl_mvm *mvm = mvmvif->mvm;
490a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	u8 value;
491a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	int ret;
492a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg
493a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	ret = kstrtou8(buf, 0, &value);
494a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	if (ret)
495a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg		return ret;
496a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	if (value > 1)
497a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg		return -EINVAL;
498a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg
499a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	mutex_lock(&mvm->mutex);
500a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	iwl_mvm_update_low_latency(mvm, vif, value);
501a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	mutex_unlock(&mvm->mutex);
502a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg
503a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	return count;
504a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg}
505a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg
506a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Bergstatic ssize_t iwl_dbgfs_low_latency_read(struct file *file,
507a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg					  char __user *user_buf,
508a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg					  size_t count, loff_t *ppos)
509a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg{
510a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	struct ieee80211_vif *vif = file->private_data;
511a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
512a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	char buf[3];
513a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg
514a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	buf[0] = mvmvif->low_latency ? '1' : '0';
515a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	buf[1] = '\n';
516a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	buf[2] = '\0';
517a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
518a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg}
519a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg
520e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
521e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
522e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
523e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	_MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
524820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do {		\
525820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		if (!debugfs_create_file(#name, mode, parent, vif,	\
526820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg					 &iwl_dbgfs_##name##_ops))	\
527820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg			goto err;					\
528820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	} while (0)
529820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
530820a1a50025550061b0d0ea15a760ecd183886f7Johannes BergMVM_DEBUGFS_READ_FILE_OPS(mac_params);
531e45a941deb24b956c9b5a06461810b45882c3e1cAlexander BondarMVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
532e45a941deb24b956c9b5a06461810b45882c3e1cAlexander BondarMVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
533a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes BergMVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
534820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
535820a1a50025550061b0d0ea15a760ecd183886f7Johannes Bergvoid iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
536820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg{
537820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	struct dentry *dbgfs_dir = vif->debugfs_dir;
538820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
539820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	char buf[100];
540820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
541820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	/*
542820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 * Check if debugfs directory already exist before creating it.
543820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 * This may happen when, for example, resetting hw or suspend-resume
544820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 */
545820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	if (!dbgfs_dir || mvmvif->dbgfs_dir)
546820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		return;
547820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
548820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
5497f09d70436729dee9dfa7ab11fda9d384c4bdf9fJohannes Berg	mvmvif->mvm = mvm;
550820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
551820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	if (!mvmvif->dbgfs_dir) {
552820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
553820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg			dbgfs_dir->d_name.name);
554820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		return;
555820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	}
556820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
557ad2549d8edf8f10a6330ab60bfbdaea096281a79Emmanuel Grumbach	if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
558e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	    ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
559e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	     (vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
5607303dd7f312f0d07a4bf45c62608d5233b5e8062Alexander Bondar	      mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)))
561e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
562e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					 S_IRUSR);
563e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
56432a65c3419cb618067c0f839b686b6bd3ecc1dbfEmmanuel Grumbach	MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, S_IRUSR);
565a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg	MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir,
566a21d7bcbf4c65bb7f79e16287d41040e4c7f5596Johannes Berg				 S_IRUSR | S_IWUSR);
567820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
568e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
569e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar	    mvmvif == mvm->bf_allowed_vif)
570e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar		MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
571e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar					 S_IRUSR | S_IWUSR);
572e45a941deb24b956c9b5a06461810b45882c3e1cAlexander Bondar
573820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	/*
574820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 * Create symlink for convenience pointing to interface specific
575820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 * debugfs entries for the driver. For example, under
576820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
577820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 * find
578820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
579820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	 */
580820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	snprintf(buf, 100, "../../../%s/%s/%s/%s",
581820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		 dbgfs_dir->d_parent->d_parent->d_name.name,
582820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		 dbgfs_dir->d_parent->d_name.name,
583820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		 dbgfs_dir->d_name.name,
584820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		 mvmvif->dbgfs_dir->d_name.name);
585820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
586820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
587820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg						     mvm->debugfs_dir, buf);
588820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	if (!mvmvif->dbgfs_slink)
589820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg		IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
590820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg			dbgfs_dir->d_name.name);
591820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	return;
592820a1a50025550061b0d0ea15a760ecd183886f7Johannes Bergerr:
593820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	IWL_ERR(mvm, "Can't create debugfs entity\n");
594820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg}
595820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
596820a1a50025550061b0d0ea15a760ecd183886f7Johannes Bergvoid iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
597820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg{
598820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
599820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
600820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	debugfs_remove(mvmvif->dbgfs_slink);
601820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	mvmvif->dbgfs_slink = NULL;
602820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg
603820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	debugfs_remove_recursive(mvmvif->dbgfs_dir);
604820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg	mvmvif->dbgfs_dir = NULL;
605820a1a50025550061b0d0ea15a760ecd183886f7Johannes Berg}
606