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