diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 169 |
1 files changed, 134 insertions, 35 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 80f848a9ee13..130760572262 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -91,7 +91,7 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf, "FLUSHING all tids queues on sta_id = %d\n", flush_arg); mutex_lock(&mvm->mutex); - ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFFFF, 0) + ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFFFF) ? : count; mutex_unlock(&mvm->mutex); return ret; @@ -101,7 +101,7 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf, flush_arg); mutex_lock(&mvm->mutex); - ret = iwl_mvm_flush_tx_path(mvm, flush_arg, 0) ? : count; + ret = iwl_mvm_flush_tx_path(mvm, flush_arg) ? : count; mutex_unlock(&mvm->mutex); return ret; @@ -712,6 +712,30 @@ static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf, return ret; } +static ssize_t iwl_dbgfs_phy_integration_ver_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + char *buf; + size_t bufsz; + int pos; + ssize_t ret; + + bufsz = mvm->fw->phy_integration_ver_len + 2; + buf = kmalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + pos = scnprintf(buf, bufsz, "%.*s\n", mvm->fw->phy_integration_ver_len, + mvm->fw->phy_integration_ver); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + + kfree(buf); + return ret; +} + #define PRINT_STATS_LE32(_struct, _memb) \ pos += scnprintf(buf + pos, bufsz - pos, \ fmt_table, #_memb, \ @@ -1117,24 +1141,22 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, char *buf, size_t count, loff_t *ppos) { + struct iwl_op_mode *opmode = container_of((void *)mvm, + struct iwl_op_mode, + op_mode_specific); struct iwl_rx_cmd_buffer rxb = { ._rx_page_order = 0, .truesize = 0, /* not used */ ._offset = 0, }; struct iwl_rx_packet *pkt; - struct iwl_rx_mpdu_desc *desc; int bin_len = count / 2; int ret = -EINVAL; - size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_AX210) ? - sizeof(struct iwl_rx_mpdu_desc) : - IWL_RX_DESC_SIZE_V1; if (!iwl_mvm_firmware_running(mvm)) return -EIO; - /* supporting only 9000 descriptor */ + /* supporting only MQ RX */ if (!mvm->trans->trans_cfg->mq_rx_supported) return -ENOTSUPP; @@ -1147,23 +1169,13 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, if (ret) goto out; - /* avoid invalid memory access */ - if (bin_len < sizeof(*pkt) + mpdu_cmd_hdr_size) - goto out; - - /* check this is RX packet */ - if (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd) != - WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD)) - goto out; - - /* check the length in metadata matches actual received length */ - desc = (void *)pkt->data; - if (le16_to_cpu(desc->mpdu_len) != - (bin_len - mpdu_cmd_hdr_size - sizeof(*pkt))) + /* avoid invalid memory access and malformed packet */ + if (bin_len < sizeof(*pkt) || + bin_len != sizeof(*pkt) + iwl_rx_packet_payload_len(pkt)) goto out; local_bh_disable(); - iwl_mvm_rx_mpdu_mq(mvm, NULL, &rxb, 0); + iwl_mvm_rx_mq(opmode, NULL, &rxb); local_bh_enable(); ret = 0; @@ -1337,6 +1349,24 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm, return count; } +static ssize_t iwl_dbgfs_dbg_time_point_write(struct iwl_mvm *mvm, + char *buf, size_t count, + loff_t *ppos) +{ + u32 timepoint; + + if (kstrtou32(buf, 0, &timepoint)) + return -EINVAL; + + if (timepoint == IWL_FW_INI_TIME_POINT_INVALID || + timepoint >= IWL_FW_INI_TIME_POINT_NUM) + return -EINVAL; + + iwl_dbg_tlv_time_point(&mvm->fwrt, timepoint, NULL); + + return count; +} + #define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__) #ifdef CONFIG_IWLWIFI_BCAST_FILTERING static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file, @@ -1746,6 +1776,69 @@ iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm, return ret ?: count; } +static ssize_t iwl_dbgfs_rfi_freq_table_write(struct iwl_mvm *mvm, char *buf, + size_t count, loff_t *ppos) +{ + int ret = 0; + u16 op_id; + + if (kstrtou16(buf, 10, &op_id)) + return -EINVAL; + + /* value zero triggers re-sending the default table to the device */ + if (!op_id) + ret = iwl_rfi_send_config_cmd(mvm, NULL); + else + ret = -EOPNOTSUPP; /* in the future a new table will be added */ + + return ret ?: count; +} + +/* The size computation is as follows: + * each number needs at most 3 characters, number of rows is the size of + * the table; So, need 5 chars for the "freq: " part and each tuple afterwards + * needs 6 characters for numbers and 5 for the punctuation around. + */ +#define IWL_RFI_BUF_SIZE (IWL_RFI_LUT_INSTALLED_SIZE *\ + (5 + IWL_RFI_LUT_ENTRY_CHANNELS_NUM * (6 + 5))) + +static ssize_t iwl_dbgfs_rfi_freq_table_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + struct iwl_rfi_freq_table_resp_cmd *resp; + u32 status; + char buf[IWL_RFI_BUF_SIZE]; + int i, j, pos = 0; + + resp = iwl_rfi_get_freq_table(mvm); + if (IS_ERR(resp)) + return PTR_ERR(resp); + + status = le32_to_cpu(resp->status); + if (status != RFI_FREQ_TABLE_OK) { + scnprintf(buf, IWL_RFI_BUF_SIZE, "status = %d\n", status); + goto out; + } + + for (i = 0; i < ARRAY_SIZE(resp->table); i++) { + pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "%d: ", + resp->table[i].freq); + + for (j = 0; j < ARRAY_SIZE(resp->table[i].channels); j++) + pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, + "(%d, %d) ", + resp->table[i].channels[j], + resp->table[i].bands[j]); + pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "\n"); + } + +out: + kfree(resp); + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); /* Device wide debugfs entries */ @@ -1766,6 +1859,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64); MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats); MVM_DEBUGFS_READ_FILE_OPS(fw_ver); +MVM_DEBUGFS_READ_FILE_OPS(phy_integration_ver); MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10); MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10); @@ -1773,6 +1867,7 @@ MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10); MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); +MVM_DEBUGFS_WRITE_FILE_OPS(dbg_time_point, 64); MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, (IWL_RSS_INDIRECTION_TABLE_SIZE * 2)); MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512); @@ -1795,6 +1890,7 @@ MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16); MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32); MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512); +MVM_DEBUGFS_READ_WRITE_FILE_OPS(rfi_freq_table, 16); static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1941,26 +2037,24 @@ void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, MVM_DEBUGFS_ADD_STA_FILE(amsdu_len, dir, 0600); } -void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) +void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm) { struct dentry *bcast_dir __maybe_unused; char buf[100]; spin_lock_init(&mvm->drv_stats_lock); - mvm->debugfs_dir = dbgfs_dir; - MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600); MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600); - MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, 0400); - MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, 0400); - MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, 0200); - MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, 0200); - MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, 0400); - MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, 0400); - MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, 0400); + MVM_DEBUGFS_ADD_FILE(nic_temp, mvm->debugfs_dir, 0400); + MVM_DEBUGFS_ADD_FILE(ctdp_budget, mvm->debugfs_dir, 0400); + MVM_DEBUGFS_ADD_FILE(stop_ctdp, mvm->debugfs_dir, 0200); + MVM_DEBUGFS_ADD_FILE(force_ctkill, mvm->debugfs_dir, 0200); + MVM_DEBUGFS_ADD_FILE(stations, mvm->debugfs_dir, 0400); + MVM_DEBUGFS_ADD_FILE(bt_notif, mvm->debugfs_dir, 0400); + MVM_DEBUGFS_ADD_FILE(bt_cmd, mvm->debugfs_dir, 0400); MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600); MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400); MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400); @@ -1978,8 +2072,12 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200); + MVM_DEBUGFS_ADD_FILE(rfi_freq_table, mvm->debugfs_dir, 0600); + + if (mvm->fw->phy_integration_ver) + MVM_DEBUGFS_ADD_FILE(phy_integration_ver, mvm->debugfs_dir, 0400); #ifdef CONFIG_ACPI - MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400); + MVM_DEBUGFS_ADD_FILE(sar_geo_profile, mvm->debugfs_dir, 0400); #endif MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600); @@ -2031,12 +2129,13 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) debugfs_create_blob("nvm_reg", S_IRUSR, mvm->debugfs_dir, &mvm->nvm_reg_blob); - debugfs_create_file("mem", 0600, dbgfs_dir, mvm, &iwl_dbgfs_mem_ops); + debugfs_create_file("mem", 0600, mvm->debugfs_dir, mvm, + &iwl_dbgfs_mem_ops); /* * Create a symlink with mac80211. It will be removed when mac80211 * exists (before the opmode exists which removes the target.) */ - snprintf(buf, 100, "../../%pd2", dbgfs_dir->d_parent); + snprintf(buf, 100, "../../%pd2", mvm->debugfs_dir->d_parent); debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf); } |