| /****************************************************************************** |
| * |
| * Copyright(c) 2017 Intel Deutschland GmbH |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name Intel Corporation nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| *****************************************************************************/ |
| |
| #include "fw/api/ax-softap-testmode.h" |
| #include <net/mac80211.h> |
| #include "debugfs.h" |
| #include "mvm.h" |
| |
| static ssize_t iwl_dbgfs_ax_softap_testmode_dl_basic_write(struct iwl_mvm* mvm, char* buf, |
| size_t count, loff_t* ppos) { |
| struct ax_softap_testmode_dl_basic_cmd* cmd = (struct ax_softap_testmode_dl_basic_cmd*)buf; |
| |
| int ret; |
| uint32_t status; |
| |
| if (sizeof(*cmd) != count) { |
| IWL_ERR(mvm, "Bad size for softap dl basic cmd (%zd) should be (%zd)\n", count, |
| sizeof(*cmd)); |
| return -EINVAL; |
| } |
| |
| status = 0; |
| |
| mutex_lock(&mvm->mutex); |
| ret = iwl_mvm_send_cmd_pdu_status( |
| mvm, iwl_cmd_id(AX_SOFTAP_TESTMODE_DL_BASIC, DATA_PATH_GROUP, 0), count, cmd, &status); |
| mutex_unlock(&mvm->mutex); |
| if (ret) { |
| IWL_ERR(mvm, "Failed to send softap dl basic cmd (%d)\n", ret); |
| return ret; |
| } |
| |
| if (status) { |
| IWL_ERR(mvm, "softap dl basic cmd failed (%d)\n", status); |
| return -EIO; |
| } |
| |
| return count; |
| } |
| |
| static ssize_t iwl_dbgfs_ax_softap_testmode_dl_mu_bar_write(struct iwl_mvm* mvm, char* buf, |
| size_t count, loff_t* ppos) { |
| struct ax_softap_testmode_dl_mu_bar_cmd* cmd = (struct ax_softap_testmode_dl_mu_bar_cmd*)buf; |
| |
| int ret; |
| uint32_t status; |
| |
| if (sizeof(*cmd) != count) { |
| IWL_ERR(mvm, "Bad size for softap dl mu bar cmd (%zd) should be (%zd)\n", count, |
| sizeof(*cmd)); |
| return -EINVAL; |
| } |
| |
| status = 0; |
| |
| mutex_lock(&mvm->mutex); |
| ret = iwl_mvm_send_cmd_pdu_status( |
| mvm, iwl_cmd_id(AX_SOFTAP_TESTMODE_DL_MU_BAR, DATA_PATH_GROUP, 0), count, cmd, &status); |
| mutex_unlock(&mvm->mutex); |
| if (ret) { |
| IWL_ERR(mvm, "Failed to send softap dl mu bar cmd (%d)\n", ret); |
| return ret; |
| } |
| |
| if (status) { |
| IWL_ERR(mvm, "softap dl mu bar cmd failed (%d)\n", status); |
| return -EIO; |
| } |
| |
| return count; |
| } |
| |
| static ssize_t iwl_dbgfs_ax_softap_testmode_ul_write(struct iwl_mvm* mvm, char* buf, size_t count, |
| loff_t* ppos) { |
| struct ax_softap_testmode_ul_cmd* cmd = (struct ax_softap_testmode_ul_cmd*)buf; |
| |
| int ret; |
| uint32_t status; |
| |
| if (sizeof(*cmd) != count) { |
| IWL_ERR(mvm, "Bad size for softap ul cmd (%zd) should be (%zd)\n", count, sizeof(*cmd)); |
| return -EINVAL; |
| } |
| |
| status = 0; |
| |
| mutex_lock(&mvm->mutex); |
| ret = iwl_mvm_send_cmd_pdu_status(mvm, iwl_cmd_id(AX_SOFTAP_TESTMODE_UL, DATA_PATH_GROUP, 0), |
| count, cmd, &status); |
| mutex_unlock(&mvm->mutex); |
| if (ret) { |
| IWL_ERR(mvm, "Failed to send softap ul cmd (%d)\n", ret); |
| return ret; |
| } |
| |
| if (status) { |
| IWL_ERR(mvm, "softap ul cmd failed (%d)\n", status); |
| return -EIO; |
| } |
| |
| return count; |
| } |
| |
| #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ |
| _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm) |
| #define MVM_DEBUGFS_ADD_FILE_AX_SOFTAP_TM(name, parent, mode) \ |
| do { \ |
| if (!debugfs_create_file(#name, mode, parent, mvm, &iwl_dbgfs_##name##_ops)) goto err; \ |
| } while (0) |
| |
| #define DL_BASIC_CMD_SIZE (sizeof(struct ax_softap_testmode_dl_basic_cmd) + 1) |
| #define DL_MU_BAR_CMD_SIZE (sizeof(struct ax_softap_testmode_dl_mu_bar_cmd) + 1) |
| #define UL_CMD_SIZE (sizeof(struct ax_softap_testmode_ul_cmd) + 1) |
| |
| MVM_DEBUGFS_WRITE_FILE_OPS(ax_softap_testmode_dl_basic, DL_BASIC_CMD_SIZE); |
| MVM_DEBUGFS_WRITE_FILE_OPS(ax_softap_testmode_dl_mu_bar, DL_MU_BAR_CMD_SIZE); |
| MVM_DEBUGFS_WRITE_FILE_OPS(ax_softap_testmode_ul, UL_CMD_SIZE); |
| |
| static void ax_softap_testmode_add_debugfs(struct ieee80211_hw* hw, struct ieee80211_vif* vif, |
| struct ieee80211_sta* sta, struct dentry* dir) { |
| struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw); |
| |
| MVM_DEBUGFS_ADD_FILE_AX_SOFTAP_TM(ax_softap_testmode_dl_basic, dir, S_IWUSR); |
| MVM_DEBUGFS_ADD_FILE_AX_SOFTAP_TM(ax_softap_testmode_dl_mu_bar, dir, S_IWUSR); |
| MVM_DEBUGFS_ADD_FILE_AX_SOFTAP_TM(ax_softap_testmode_ul, dir, S_IWUSR); |
| return; |
| err: |
| IWL_ERR(mvm, "Can't create debugfs entity\n"); |
| } |
| |
| void iwl_mvm_ax_softap_testmode_sta_add_debugfs(struct ieee80211_hw* hw, struct ieee80211_vif* vif, |
| struct ieee80211_sta* sta, struct dentry* dir) { |
| if (fw_has_capa(&IWL_MAC80211_GET_MVM(hw)->fw->ucode_capa, IWL_UCODE_TLV_CAPA_AX_SAP_TM_V2)) { |
| ax_softap_testmode_add_debugfs(hw, vif, sta, dir); |
| } |
| } |