162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 562306a36Sopenharmony_ci * Copyright (C) 2018 Intel Corporation 662306a36Sopenharmony_ci *****************************************************************************/ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/slab.h> 962306a36Sopenharmony_ci#include <linux/kernel.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/debugfs.h> 1262306a36Sopenharmony_ci#include <linux/ieee80211.h> 1362306a36Sopenharmony_ci#include <net/mac80211.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "iwl-debug.h" 1662306a36Sopenharmony_ci#include "iwl-trans.h" 1762306a36Sopenharmony_ci#include "iwl-io.h" 1862306a36Sopenharmony_ci#include "dev.h" 1962306a36Sopenharmony_ci#include "agn.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* create and remove of files */ 2262306a36Sopenharmony_ci#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 2362306a36Sopenharmony_ci debugfs_create_file(#name, mode, parent, priv, \ 2462306a36Sopenharmony_ci &iwl_dbgfs_##name##_ops); \ 2562306a36Sopenharmony_ci} while (0) 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* file operation */ 2862306a36Sopenharmony_ci#define DEBUGFS_READ_FILE_OPS(name) \ 2962306a36Sopenharmony_cistatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 3062306a36Sopenharmony_ci .read = iwl_dbgfs_##name##_read, \ 3162306a36Sopenharmony_ci .open = simple_open, \ 3262306a36Sopenharmony_ci .llseek = generic_file_llseek, \ 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define DEBUGFS_WRITE_FILE_OPS(name) \ 3662306a36Sopenharmony_cistatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 3762306a36Sopenharmony_ci .write = iwl_dbgfs_##name##_write, \ 3862306a36Sopenharmony_ci .open = simple_open, \ 3962306a36Sopenharmony_ci .llseek = generic_file_llseek, \ 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 4462306a36Sopenharmony_cistatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 4562306a36Sopenharmony_ci .write = iwl_dbgfs_##name##_write, \ 4662306a36Sopenharmony_ci .read = iwl_dbgfs_##name##_read, \ 4762306a36Sopenharmony_ci .open = simple_open, \ 4862306a36Sopenharmony_ci .llseek = generic_file_llseek, \ 4962306a36Sopenharmony_ci}; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_sram_read(struct file *file, 5262306a36Sopenharmony_ci char __user *user_buf, 5362306a36Sopenharmony_ci size_t count, loff_t *ppos) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci u32 val = 0; 5662306a36Sopenharmony_ci char *buf; 5762306a36Sopenharmony_ci ssize_t ret; 5862306a36Sopenharmony_ci int i = 0; 5962306a36Sopenharmony_ci bool device_format = false; 6062306a36Sopenharmony_ci int offset = 0; 6162306a36Sopenharmony_ci int len = 0; 6262306a36Sopenharmony_ci int pos = 0; 6362306a36Sopenharmony_ci int sram; 6462306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 6562306a36Sopenharmony_ci const struct fw_img *img; 6662306a36Sopenharmony_ci size_t bufsz; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci if (!iwl_is_ready_rf(priv)) 6962306a36Sopenharmony_ci return -EAGAIN; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci /* default is to dump the entire data segment */ 7262306a36Sopenharmony_ci if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { 7362306a36Sopenharmony_ci priv->dbgfs_sram_offset = 0x800000; 7462306a36Sopenharmony_ci if (!priv->ucode_loaded) 7562306a36Sopenharmony_ci return -EINVAL; 7662306a36Sopenharmony_ci img = &priv->fw->img[priv->cur_ucode]; 7762306a36Sopenharmony_ci priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; 7862306a36Sopenharmony_ci } 7962306a36Sopenharmony_ci len = priv->dbgfs_sram_len; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci if (len == -4) { 8262306a36Sopenharmony_ci device_format = true; 8362306a36Sopenharmony_ci len = 4; 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci bufsz = 50 + len * 4; 8762306a36Sopenharmony_ci buf = kmalloc(bufsz, GFP_KERNEL); 8862306a36Sopenharmony_ci if (!buf) 8962306a36Sopenharmony_ci return -ENOMEM; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 9262306a36Sopenharmony_ci len); 9362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 9462306a36Sopenharmony_ci priv->dbgfs_sram_offset); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci /* adjust sram address since reads are only on even u32 boundaries */ 9762306a36Sopenharmony_ci offset = priv->dbgfs_sram_offset & 0x3; 9862306a36Sopenharmony_ci sram = priv->dbgfs_sram_offset & ~0x3; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* read the first u32 from sram */ 10162306a36Sopenharmony_ci val = iwl_trans_read_mem32(priv->trans, sram); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci for (; len; len--) { 10462306a36Sopenharmony_ci /* put the address at the start of every line */ 10562306a36Sopenharmony_ci if (i == 0) 10662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 10762306a36Sopenharmony_ci "%08X: ", sram + offset); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci if (device_format) 11062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 11162306a36Sopenharmony_ci "%02x", (val >> (8 * (3 - offset))) & 0xff); 11262306a36Sopenharmony_ci else 11362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 11462306a36Sopenharmony_ci "%02x ", (val >> (8 * offset)) & 0xff); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci /* if all bytes processed, read the next u32 from sram */ 11762306a36Sopenharmony_ci if (++offset == 4) { 11862306a36Sopenharmony_ci sram += 4; 11962306a36Sopenharmony_ci offset = 0; 12062306a36Sopenharmony_ci val = iwl_trans_read_mem32(priv->trans, sram); 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci /* put in extra spaces and split lines for human readability */ 12462306a36Sopenharmony_ci if (++i == 16) { 12562306a36Sopenharmony_ci i = 0; 12662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 12762306a36Sopenharmony_ci } else if (!(i & 7)) { 12862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, " "); 12962306a36Sopenharmony_ci } else if (!(i & 3)) { 13062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, " "); 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci if (i) 13462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 13762306a36Sopenharmony_ci kfree(buf); 13862306a36Sopenharmony_ci return ret; 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_sram_write(struct file *file, 14262306a36Sopenharmony_ci const char __user *user_buf, 14362306a36Sopenharmony_ci size_t count, loff_t *ppos) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 14662306a36Sopenharmony_ci char buf[64]; 14762306a36Sopenharmony_ci int buf_size; 14862306a36Sopenharmony_ci u32 offset, len; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 15162306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 15262306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 15362306a36Sopenharmony_ci return -EFAULT; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 15662306a36Sopenharmony_ci priv->dbgfs_sram_offset = offset; 15762306a36Sopenharmony_ci priv->dbgfs_sram_len = len; 15862306a36Sopenharmony_ci } else if (sscanf(buf, "%x", &offset) == 1) { 15962306a36Sopenharmony_ci priv->dbgfs_sram_offset = offset; 16062306a36Sopenharmony_ci priv->dbgfs_sram_len = -4; 16162306a36Sopenharmony_ci } else { 16262306a36Sopenharmony_ci priv->dbgfs_sram_offset = 0; 16362306a36Sopenharmony_ci priv->dbgfs_sram_len = 0; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci return count; 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, 17062306a36Sopenharmony_ci char __user *user_buf, 17162306a36Sopenharmony_ci size_t count, loff_t *ppos) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 17462306a36Sopenharmony_ci const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN]; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci if (!priv->wowlan_sram) 17762306a36Sopenharmony_ci return -ENODATA; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, 18062306a36Sopenharmony_ci priv->wowlan_sram, 18162306a36Sopenharmony_ci img->sec[IWL_UCODE_SECTION_DATA].len); 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 18462306a36Sopenharmony_ci size_t count, loff_t *ppos) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 18762306a36Sopenharmony_ci struct iwl_station_entry *station; 18862306a36Sopenharmony_ci struct iwl_tid_data *tid_data; 18962306a36Sopenharmony_ci char *buf; 19062306a36Sopenharmony_ci int i, j, pos = 0; 19162306a36Sopenharmony_ci ssize_t ret; 19262306a36Sopenharmony_ci /* Add 30 for initial string */ 19362306a36Sopenharmony_ci const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci buf = kmalloc(bufsz, GFP_KERNEL); 19662306a36Sopenharmony_ci if (!buf) 19762306a36Sopenharmony_ci return -ENOMEM; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 20062306a36Sopenharmony_ci priv->num_stations); 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci for (i = 0; i < IWLAGN_STATION_COUNT; i++) { 20362306a36Sopenharmony_ci station = &priv->stations[i]; 20462306a36Sopenharmony_ci if (!station->used) 20562306a36Sopenharmony_ci continue; 20662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 20762306a36Sopenharmony_ci "station %d - addr: %pM, flags: %#x\n", 20862306a36Sopenharmony_ci i, station->sta.sta.addr, 20962306a36Sopenharmony_ci station->sta.station_flags_msk); 21062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 21162306a36Sopenharmony_ci "TID seqno next_rclmd " 21262306a36Sopenharmony_ci "rate_n_flags state txq\n"); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci for (j = 0; j < IWL_MAX_TID_COUNT; j++) { 21562306a36Sopenharmony_ci tid_data = &priv->tid_data[i][j]; 21662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 21762306a36Sopenharmony_ci "%d: 0x%.4x 0x%.4x 0x%.8x " 21862306a36Sopenharmony_ci "%d %.2d", 21962306a36Sopenharmony_ci j, tid_data->seq_number, 22062306a36Sopenharmony_ci tid_data->next_reclaimed, 22162306a36Sopenharmony_ci tid_data->agg.rate_n_flags, 22262306a36Sopenharmony_ci tid_data->agg.state, 22362306a36Sopenharmony_ci tid_data->agg.txq_id); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci if (tid_data->agg.wait_for_ba) 22662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 22762306a36Sopenharmony_ci " - waitforba"); 22862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 22962306a36Sopenharmony_ci } 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 23262306a36Sopenharmony_ci } 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 23562306a36Sopenharmony_ci kfree(buf); 23662306a36Sopenharmony_ci return ret; 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_nvm_read(struct file *file, 24062306a36Sopenharmony_ci char __user *user_buf, 24162306a36Sopenharmony_ci size_t count, 24262306a36Sopenharmony_ci loff_t *ppos) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci ssize_t ret; 24562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 24662306a36Sopenharmony_ci int pos = 0, ofs = 0, buf_size = 0; 24762306a36Sopenharmony_ci const u8 *ptr; 24862306a36Sopenharmony_ci char *buf; 24962306a36Sopenharmony_ci u16 nvm_ver; 25062306a36Sopenharmony_ci size_t eeprom_len = priv->eeprom_blob_size; 25162306a36Sopenharmony_ci buf_size = 4 * eeprom_len + 256; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci if (eeprom_len % 16) 25462306a36Sopenharmony_ci return -ENODATA; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci ptr = priv->eeprom_blob; 25762306a36Sopenharmony_ci if (!ptr) 25862306a36Sopenharmony_ci return -ENOMEM; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci /* 4 characters for byte 0xYY */ 26162306a36Sopenharmony_ci buf = kzalloc(buf_size, GFP_KERNEL); 26262306a36Sopenharmony_ci if (!buf) 26362306a36Sopenharmony_ci return -ENOMEM; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci nvm_ver = priv->nvm_data->nvm_version; 26662306a36Sopenharmony_ci pos += scnprintf(buf + pos, buf_size - pos, 26762306a36Sopenharmony_ci "NVM version: 0x%x\n", nvm_ver); 26862306a36Sopenharmony_ci for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 26962306a36Sopenharmony_ci pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x %16ph\n", 27062306a36Sopenharmony_ci ofs, ptr + ofs); 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 27462306a36Sopenharmony_ci kfree(buf); 27562306a36Sopenharmony_ci return ret; 27662306a36Sopenharmony_ci} 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 27962306a36Sopenharmony_ci size_t count, loff_t *ppos) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 28262306a36Sopenharmony_ci struct ieee80211_channel *channels = NULL; 28362306a36Sopenharmony_ci const struct ieee80211_supported_band *supp_band = NULL; 28462306a36Sopenharmony_ci int pos = 0, i, bufsz = PAGE_SIZE; 28562306a36Sopenharmony_ci char *buf; 28662306a36Sopenharmony_ci ssize_t ret; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 28962306a36Sopenharmony_ci if (!buf) 29062306a36Sopenharmony_ci return -ENOMEM; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci supp_band = iwl_get_hw_mode(priv, NL80211_BAND_2GHZ); 29362306a36Sopenharmony_ci if (supp_band) { 29462306a36Sopenharmony_ci channels = supp_band->channels; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 29762306a36Sopenharmony_ci "Displaying %d channels in 2.4GHz band 802.11bg):\n", 29862306a36Sopenharmony_ci supp_band->n_channels); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci for (i = 0; i < supp_band->n_channels; i++) 30162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 30262306a36Sopenharmony_ci "%d: %ddBm: BSS%s%s, %s.\n", 30362306a36Sopenharmony_ci channels[i].hw_value, 30462306a36Sopenharmony_ci channels[i].max_power, 30562306a36Sopenharmony_ci channels[i].flags & IEEE80211_CHAN_RADAR ? 30662306a36Sopenharmony_ci " (IEEE 802.11h required)" : "", 30762306a36Sopenharmony_ci ((channels[i].flags & IEEE80211_CHAN_NO_IR) 30862306a36Sopenharmony_ci || (channels[i].flags & 30962306a36Sopenharmony_ci IEEE80211_CHAN_RADAR)) ? "" : 31062306a36Sopenharmony_ci ", IBSS", 31162306a36Sopenharmony_ci channels[i].flags & 31262306a36Sopenharmony_ci IEEE80211_CHAN_NO_IR ? 31362306a36Sopenharmony_ci "passive only" : "active/passive"); 31462306a36Sopenharmony_ci } 31562306a36Sopenharmony_ci supp_band = iwl_get_hw_mode(priv, NL80211_BAND_5GHZ); 31662306a36Sopenharmony_ci if (supp_band) { 31762306a36Sopenharmony_ci channels = supp_band->channels; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 32062306a36Sopenharmony_ci "Displaying %d channels in 5.2GHz band (802.11a)\n", 32162306a36Sopenharmony_ci supp_band->n_channels); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci for (i = 0; i < supp_band->n_channels; i++) 32462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 32562306a36Sopenharmony_ci "%d: %ddBm: BSS%s%s, %s.\n", 32662306a36Sopenharmony_ci channels[i].hw_value, 32762306a36Sopenharmony_ci channels[i].max_power, 32862306a36Sopenharmony_ci channels[i].flags & IEEE80211_CHAN_RADAR ? 32962306a36Sopenharmony_ci " (IEEE 802.11h required)" : "", 33062306a36Sopenharmony_ci ((channels[i].flags & IEEE80211_CHAN_NO_IR) 33162306a36Sopenharmony_ci || (channels[i].flags & 33262306a36Sopenharmony_ci IEEE80211_CHAN_RADAR)) ? "" : 33362306a36Sopenharmony_ci ", IBSS", 33462306a36Sopenharmony_ci channels[i].flags & 33562306a36Sopenharmony_ci IEEE80211_CHAN_NO_IR ? 33662306a36Sopenharmony_ci "passive only" : "active/passive"); 33762306a36Sopenharmony_ci } 33862306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 33962306a36Sopenharmony_ci kfree(buf); 34062306a36Sopenharmony_ci return ret; 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_status_read(struct file *file, 34462306a36Sopenharmony_ci char __user *user_buf, 34562306a36Sopenharmony_ci size_t count, loff_t *ppos) { 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 34862306a36Sopenharmony_ci char buf[512]; 34962306a36Sopenharmony_ci int pos = 0; 35062306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 35362306a36Sopenharmony_ci test_bit(STATUS_RF_KILL_HW, &priv->status)); 35462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", 35562306a36Sopenharmony_ci test_bit(STATUS_CT_KILL, &priv->status)); 35662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 35762306a36Sopenharmony_ci test_bit(STATUS_ALIVE, &priv->status)); 35862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", 35962306a36Sopenharmony_ci test_bit(STATUS_READY, &priv->status)); 36062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 36162306a36Sopenharmony_ci test_bit(STATUS_EXIT_PENDING, &priv->status)); 36262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 36362306a36Sopenharmony_ci test_bit(STATUS_STATISTICS, &priv->status)); 36462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 36562306a36Sopenharmony_ci test_bit(STATUS_SCANNING, &priv->status)); 36662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", 36762306a36Sopenharmony_ci test_bit(STATUS_SCAN_ABORTING, &priv->status)); 36862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", 36962306a36Sopenharmony_ci test_bit(STATUS_SCAN_HW, &priv->status)); 37062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", 37162306a36Sopenharmony_ci test_bit(STATUS_POWER_PMI, &priv->status)); 37262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 37362306a36Sopenharmony_ci test_bit(STATUS_FW_ERROR, &priv->status)); 37462306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 37562306a36Sopenharmony_ci} 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_rx_handlers_read(struct file *file, 37862306a36Sopenharmony_ci char __user *user_buf, 37962306a36Sopenharmony_ci size_t count, loff_t *ppos) { 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci int pos = 0; 38462306a36Sopenharmony_ci int cnt = 0; 38562306a36Sopenharmony_ci char *buf; 38662306a36Sopenharmony_ci int bufsz = 24 * 64; /* 24 items * 64 char per item */ 38762306a36Sopenharmony_ci ssize_t ret; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 39062306a36Sopenharmony_ci if (!buf) 39162306a36Sopenharmony_ci return -ENOMEM; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci for (cnt = 0; cnt < REPLY_MAX; cnt++) { 39462306a36Sopenharmony_ci if (priv->rx_handlers_stats[cnt] > 0) 39562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 39662306a36Sopenharmony_ci "\tRx handler[%36s]:\t\t %u\n", 39762306a36Sopenharmony_ci iwl_get_cmd_string(priv->trans, (u32)cnt), 39862306a36Sopenharmony_ci priv->rx_handlers_stats[cnt]); 39962306a36Sopenharmony_ci } 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 40262306a36Sopenharmony_ci kfree(buf); 40362306a36Sopenharmony_ci return ret; 40462306a36Sopenharmony_ci} 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_rx_handlers_write(struct file *file, 40762306a36Sopenharmony_ci const char __user *user_buf, 40862306a36Sopenharmony_ci size_t count, loff_t *ppos) 40962306a36Sopenharmony_ci{ 41062306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci char buf[8]; 41362306a36Sopenharmony_ci int buf_size; 41462306a36Sopenharmony_ci u32 reset_flag; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 41762306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 41862306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 41962306a36Sopenharmony_ci return -EFAULT; 42062306a36Sopenharmony_ci if (sscanf(buf, "%x", &reset_flag) != 1) 42162306a36Sopenharmony_ci return -EFAULT; 42262306a36Sopenharmony_ci if (reset_flag == 0) 42362306a36Sopenharmony_ci memset(&priv->rx_handlers_stats[0], 0, 42462306a36Sopenharmony_ci sizeof(priv->rx_handlers_stats)); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci return count; 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 43062306a36Sopenharmony_ci size_t count, loff_t *ppos) 43162306a36Sopenharmony_ci{ 43262306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 43362306a36Sopenharmony_ci struct iwl_rxon_context *ctx; 43462306a36Sopenharmony_ci int pos = 0, i; 43562306a36Sopenharmony_ci char buf[256 * NUM_IWL_RXON_CTX]; 43662306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci for_each_context(priv, ctx) { 43962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", 44062306a36Sopenharmony_ci ctx->ctxid); 44162306a36Sopenharmony_ci for (i = 0; i < AC_NUM; i++) { 44262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 44362306a36Sopenharmony_ci "\tcw_min\tcw_max\taifsn\ttxop\n"); 44462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 44562306a36Sopenharmony_ci "AC[%d]\t%u\t%u\t%u\t%u\n", i, 44662306a36Sopenharmony_ci ctx->qos_data.def_qos_parm.ac[i].cw_min, 44762306a36Sopenharmony_ci ctx->qos_data.def_qos_parm.ac[i].cw_max, 44862306a36Sopenharmony_ci ctx->qos_data.def_qos_parm.ac[i].aifsn, 44962306a36Sopenharmony_ci ctx->qos_data.def_qos_parm.ac[i].edca_txop); 45062306a36Sopenharmony_ci } 45162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 45262306a36Sopenharmony_ci } 45362306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 45462306a36Sopenharmony_ci} 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 45762306a36Sopenharmony_ci char __user *user_buf, 45862306a36Sopenharmony_ci size_t count, loff_t *ppos) 45962306a36Sopenharmony_ci{ 46062306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 46162306a36Sopenharmony_ci struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 46262306a36Sopenharmony_ci struct iwl_tt_restriction *restriction; 46362306a36Sopenharmony_ci char buf[100]; 46462306a36Sopenharmony_ci int pos = 0; 46562306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 46862306a36Sopenharmony_ci "Thermal Throttling Mode: %s\n", 46962306a36Sopenharmony_ci tt->advanced_tt ? "Advance" : "Legacy"); 47062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 47162306a36Sopenharmony_ci "Thermal Throttling State: %d\n", 47262306a36Sopenharmony_ci tt->state); 47362306a36Sopenharmony_ci if (tt->advanced_tt) { 47462306a36Sopenharmony_ci restriction = tt->restriction + tt->state; 47562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 47662306a36Sopenharmony_ci "Tx mode: %d\n", 47762306a36Sopenharmony_ci restriction->tx_stream); 47862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 47962306a36Sopenharmony_ci "Rx mode: %d\n", 48062306a36Sopenharmony_ci restriction->rx_stream); 48162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 48262306a36Sopenharmony_ci "HT mode: %d\n", 48362306a36Sopenharmony_ci restriction->is_ht); 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 48662306a36Sopenharmony_ci} 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, 48962306a36Sopenharmony_ci const char __user *user_buf, 49062306a36Sopenharmony_ci size_t count, loff_t *ppos) 49162306a36Sopenharmony_ci{ 49262306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 49362306a36Sopenharmony_ci char buf[8]; 49462306a36Sopenharmony_ci int buf_size; 49562306a36Sopenharmony_ci int ht40; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 49862306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 49962306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 50062306a36Sopenharmony_ci return -EFAULT; 50162306a36Sopenharmony_ci if (sscanf(buf, "%d", &ht40) != 1) 50262306a36Sopenharmony_ci return -EFAULT; 50362306a36Sopenharmony_ci if (!iwl_is_any_associated(priv)) 50462306a36Sopenharmony_ci priv->disable_ht40 = ht40 ? true : false; 50562306a36Sopenharmony_ci else 50662306a36Sopenharmony_ci return -EINVAL; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci return count; 50962306a36Sopenharmony_ci} 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_disable_ht40_read(struct file *file, 51262306a36Sopenharmony_ci char __user *user_buf, 51362306a36Sopenharmony_ci size_t count, loff_t *ppos) 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 51662306a36Sopenharmony_ci char buf[100]; 51762306a36Sopenharmony_ci int pos = 0; 51862306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 52162306a36Sopenharmony_ci "11n 40MHz Mode: %s\n", 52262306a36Sopenharmony_ci priv->disable_ht40 ? "Disabled" : "Enabled"); 52362306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 52462306a36Sopenharmony_ci} 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_temperature_read(struct file *file, 52762306a36Sopenharmony_ci char __user *user_buf, 52862306a36Sopenharmony_ci size_t count, loff_t *ppos) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 53162306a36Sopenharmony_ci char buf[8]; 53262306a36Sopenharmony_ci int pos = 0; 53362306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%d\n", priv->temperature); 53662306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 53762306a36Sopenharmony_ci} 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, 54162306a36Sopenharmony_ci const char __user *user_buf, 54262306a36Sopenharmony_ci size_t count, loff_t *ppos) 54362306a36Sopenharmony_ci{ 54462306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 54562306a36Sopenharmony_ci char buf[8]; 54662306a36Sopenharmony_ci int buf_size; 54762306a36Sopenharmony_ci int value; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 55062306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 55162306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 55262306a36Sopenharmony_ci return -EFAULT; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci if (sscanf(buf, "%d", &value) != 1) 55562306a36Sopenharmony_ci return -EINVAL; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci /* 55862306a36Sopenharmony_ci * Our users expect 0 to be "CAM", but 0 isn't actually 55962306a36Sopenharmony_ci * valid here. However, let's not confuse them and present 56062306a36Sopenharmony_ci * IWL_POWER_INDEX_1 as "1", not "0". 56162306a36Sopenharmony_ci */ 56262306a36Sopenharmony_ci if (value == 0) 56362306a36Sopenharmony_ci return -EINVAL; 56462306a36Sopenharmony_ci else if (value > 0) 56562306a36Sopenharmony_ci value -= 1; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) 56862306a36Sopenharmony_ci return -EINVAL; 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci if (!iwl_is_ready_rf(priv)) 57162306a36Sopenharmony_ci return -EAGAIN; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci priv->power_data.debug_sleep_level_override = value; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci mutex_lock(&priv->mutex); 57662306a36Sopenharmony_ci iwl_power_update_mode(priv, true); 57762306a36Sopenharmony_ci mutex_unlock(&priv->mutex); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci return count; 58062306a36Sopenharmony_ci} 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file, 58362306a36Sopenharmony_ci char __user *user_buf, 58462306a36Sopenharmony_ci size_t count, loff_t *ppos) 58562306a36Sopenharmony_ci{ 58662306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 58762306a36Sopenharmony_ci char buf[10]; 58862306a36Sopenharmony_ci int pos, value; 58962306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci /* see the write function */ 59262306a36Sopenharmony_ci value = priv->power_data.debug_sleep_level_override; 59362306a36Sopenharmony_ci if (value >= 0) 59462306a36Sopenharmony_ci value += 1; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci pos = scnprintf(buf, bufsz, "%d\n", value); 59762306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 59862306a36Sopenharmony_ci} 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file, 60162306a36Sopenharmony_ci char __user *user_buf, 60262306a36Sopenharmony_ci size_t count, loff_t *ppos) 60362306a36Sopenharmony_ci{ 60462306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 60562306a36Sopenharmony_ci char buf[200]; 60662306a36Sopenharmony_ci int pos = 0, i; 60762306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 60862306a36Sopenharmony_ci struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd; 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 61162306a36Sopenharmony_ci "flags: %#.2x\n", le16_to_cpu(cmd->flags)); 61262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 61362306a36Sopenharmony_ci "RX/TX timeout: %d/%d usec\n", 61462306a36Sopenharmony_ci le32_to_cpu(cmd->rx_data_timeout), 61562306a36Sopenharmony_ci le32_to_cpu(cmd->tx_data_timeout)); 61662306a36Sopenharmony_ci for (i = 0; i < IWL_POWER_VEC_SIZE; i++) 61762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 61862306a36Sopenharmony_ci "sleep_interval[%d]: %d\n", i, 61962306a36Sopenharmony_ci le32_to_cpu(cmd->sleep_interval[i])); 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 62262306a36Sopenharmony_ci} 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(sram); 62562306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(wowlan_sram); 62662306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(nvm); 62762306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(stations); 62862306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(channels); 62962306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(status); 63062306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(rx_handlers); 63162306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(qos); 63262306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(thermal_throttling); 63362306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 63462306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(temperature); 63562306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); 63662306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(current_sleep_command); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci#define fmt_value " %-30s %10u\n" 63962306a36Sopenharmony_ci#define fmt_hex " %-30s 0x%02X\n" 64062306a36Sopenharmony_ci#define fmt_table " %-30s %10u %10u %10u %10u\n" 64162306a36Sopenharmony_ci#define fmt_header "%-32s current cumulative delta max\n" 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_cistatic int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) 64462306a36Sopenharmony_ci{ 64562306a36Sopenharmony_ci int p = 0; 64662306a36Sopenharmony_ci u32 flag; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci lockdep_assert_held(&priv->statistics.lock); 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci flag = le32_to_cpu(priv->statistics.flag); 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); 65362306a36Sopenharmony_ci if (flag & UCODE_STATISTICS_CLEAR_MSK) 65462306a36Sopenharmony_ci p += scnprintf(buf + p, bufsz - p, 65562306a36Sopenharmony_ci "\tStatistics have been cleared\n"); 65662306a36Sopenharmony_ci p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", 65762306a36Sopenharmony_ci (flag & UCODE_STATISTICS_FREQUENCY_MSK) 65862306a36Sopenharmony_ci ? "2.4 GHz" : "5.2 GHz"); 65962306a36Sopenharmony_ci p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", 66062306a36Sopenharmony_ci (flag & UCODE_STATISTICS_NARROW_BAND_MSK) 66162306a36Sopenharmony_ci ? "enabled" : "disabled"); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci return p; 66462306a36Sopenharmony_ci} 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 66762306a36Sopenharmony_ci char __user *user_buf, 66862306a36Sopenharmony_ci size_t count, loff_t *ppos) 66962306a36Sopenharmony_ci{ 67062306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 67162306a36Sopenharmony_ci int pos = 0; 67262306a36Sopenharmony_ci char *buf; 67362306a36Sopenharmony_ci int bufsz = sizeof(struct statistics_rx_phy) * 40 + 67462306a36Sopenharmony_ci sizeof(struct statistics_rx_non_phy) * 40 + 67562306a36Sopenharmony_ci sizeof(struct statistics_rx_ht_phy) * 40 + 400; 67662306a36Sopenharmony_ci ssize_t ret; 67762306a36Sopenharmony_ci struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; 67862306a36Sopenharmony_ci struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; 67962306a36Sopenharmony_ci struct statistics_rx_non_phy *general, *accum_general; 68062306a36Sopenharmony_ci struct statistics_rx_non_phy *delta_general, *max_general; 68162306a36Sopenharmony_ci struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci if (!iwl_is_alive(priv)) 68462306a36Sopenharmony_ci return -EAGAIN; 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 68762306a36Sopenharmony_ci if (!buf) 68862306a36Sopenharmony_ci return -ENOMEM; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci /* 69162306a36Sopenharmony_ci * the statistic information display here is based on 69262306a36Sopenharmony_ci * the last statistics notification from uCode 69362306a36Sopenharmony_ci * might not reflect the current uCode activity 69462306a36Sopenharmony_ci */ 69562306a36Sopenharmony_ci spin_lock_bh(&priv->statistics.lock); 69662306a36Sopenharmony_ci ofdm = &priv->statistics.rx_ofdm; 69762306a36Sopenharmony_ci cck = &priv->statistics.rx_cck; 69862306a36Sopenharmony_ci general = &priv->statistics.rx_non_phy; 69962306a36Sopenharmony_ci ht = &priv->statistics.rx_ofdm_ht; 70062306a36Sopenharmony_ci accum_ofdm = &priv->accum_stats.rx_ofdm; 70162306a36Sopenharmony_ci accum_cck = &priv->accum_stats.rx_cck; 70262306a36Sopenharmony_ci accum_general = &priv->accum_stats.rx_non_phy; 70362306a36Sopenharmony_ci accum_ht = &priv->accum_stats.rx_ofdm_ht; 70462306a36Sopenharmony_ci delta_ofdm = &priv->delta_stats.rx_ofdm; 70562306a36Sopenharmony_ci delta_cck = &priv->delta_stats.rx_cck; 70662306a36Sopenharmony_ci delta_general = &priv->delta_stats.rx_non_phy; 70762306a36Sopenharmony_ci delta_ht = &priv->delta_stats.rx_ofdm_ht; 70862306a36Sopenharmony_ci max_ofdm = &priv->max_delta_stats.rx_ofdm; 70962306a36Sopenharmony_ci max_cck = &priv->max_delta_stats.rx_cck; 71062306a36Sopenharmony_ci max_general = &priv->max_delta_stats.rx_non_phy; 71162306a36Sopenharmony_ci max_ht = &priv->max_delta_stats.rx_ofdm_ht; 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci pos += iwl_statistics_flag(priv, buf, bufsz); 71462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 71562306a36Sopenharmony_ci fmt_header, "Statistics_Rx - OFDM:"); 71662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 71762306a36Sopenharmony_ci fmt_table, "ina_cnt:", 71862306a36Sopenharmony_ci le32_to_cpu(ofdm->ina_cnt), 71962306a36Sopenharmony_ci accum_ofdm->ina_cnt, 72062306a36Sopenharmony_ci delta_ofdm->ina_cnt, max_ofdm->ina_cnt); 72162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 72262306a36Sopenharmony_ci fmt_table, "fina_cnt:", 72362306a36Sopenharmony_ci le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, 72462306a36Sopenharmony_ci delta_ofdm->fina_cnt, max_ofdm->fina_cnt); 72562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 72662306a36Sopenharmony_ci fmt_table, "plcp_err:", 72762306a36Sopenharmony_ci le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, 72862306a36Sopenharmony_ci delta_ofdm->plcp_err, max_ofdm->plcp_err); 72962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 73062306a36Sopenharmony_ci fmt_table, "crc32_err:", 73162306a36Sopenharmony_ci le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, 73262306a36Sopenharmony_ci delta_ofdm->crc32_err, max_ofdm->crc32_err); 73362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 73462306a36Sopenharmony_ci fmt_table, "overrun_err:", 73562306a36Sopenharmony_ci le32_to_cpu(ofdm->overrun_err), 73662306a36Sopenharmony_ci accum_ofdm->overrun_err, delta_ofdm->overrun_err, 73762306a36Sopenharmony_ci max_ofdm->overrun_err); 73862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 73962306a36Sopenharmony_ci fmt_table, "early_overrun_err:", 74062306a36Sopenharmony_ci le32_to_cpu(ofdm->early_overrun_err), 74162306a36Sopenharmony_ci accum_ofdm->early_overrun_err, 74262306a36Sopenharmony_ci delta_ofdm->early_overrun_err, 74362306a36Sopenharmony_ci max_ofdm->early_overrun_err); 74462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 74562306a36Sopenharmony_ci fmt_table, "crc32_good:", 74662306a36Sopenharmony_ci le32_to_cpu(ofdm->crc32_good), 74762306a36Sopenharmony_ci accum_ofdm->crc32_good, delta_ofdm->crc32_good, 74862306a36Sopenharmony_ci max_ofdm->crc32_good); 74962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 75062306a36Sopenharmony_ci fmt_table, "false_alarm_cnt:", 75162306a36Sopenharmony_ci le32_to_cpu(ofdm->false_alarm_cnt), 75262306a36Sopenharmony_ci accum_ofdm->false_alarm_cnt, 75362306a36Sopenharmony_ci delta_ofdm->false_alarm_cnt, 75462306a36Sopenharmony_ci max_ofdm->false_alarm_cnt); 75562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 75662306a36Sopenharmony_ci fmt_table, "fina_sync_err_cnt:", 75762306a36Sopenharmony_ci le32_to_cpu(ofdm->fina_sync_err_cnt), 75862306a36Sopenharmony_ci accum_ofdm->fina_sync_err_cnt, 75962306a36Sopenharmony_ci delta_ofdm->fina_sync_err_cnt, 76062306a36Sopenharmony_ci max_ofdm->fina_sync_err_cnt); 76162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 76262306a36Sopenharmony_ci fmt_table, "sfd_timeout:", 76362306a36Sopenharmony_ci le32_to_cpu(ofdm->sfd_timeout), 76462306a36Sopenharmony_ci accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout, 76562306a36Sopenharmony_ci max_ofdm->sfd_timeout); 76662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 76762306a36Sopenharmony_ci fmt_table, "fina_timeout:", 76862306a36Sopenharmony_ci le32_to_cpu(ofdm->fina_timeout), 76962306a36Sopenharmony_ci accum_ofdm->fina_timeout, delta_ofdm->fina_timeout, 77062306a36Sopenharmony_ci max_ofdm->fina_timeout); 77162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 77262306a36Sopenharmony_ci fmt_table, "unresponded_rts:", 77362306a36Sopenharmony_ci le32_to_cpu(ofdm->unresponded_rts), 77462306a36Sopenharmony_ci accum_ofdm->unresponded_rts, 77562306a36Sopenharmony_ci delta_ofdm->unresponded_rts, 77662306a36Sopenharmony_ci max_ofdm->unresponded_rts); 77762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 77862306a36Sopenharmony_ci fmt_table, "rxe_frame_lmt_ovrun:", 77962306a36Sopenharmony_ci le32_to_cpu(ofdm->rxe_frame_limit_overrun), 78062306a36Sopenharmony_ci accum_ofdm->rxe_frame_limit_overrun, 78162306a36Sopenharmony_ci delta_ofdm->rxe_frame_limit_overrun, 78262306a36Sopenharmony_ci max_ofdm->rxe_frame_limit_overrun); 78362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 78462306a36Sopenharmony_ci fmt_table, "sent_ack_cnt:", 78562306a36Sopenharmony_ci le32_to_cpu(ofdm->sent_ack_cnt), 78662306a36Sopenharmony_ci accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt, 78762306a36Sopenharmony_ci max_ofdm->sent_ack_cnt); 78862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 78962306a36Sopenharmony_ci fmt_table, "sent_cts_cnt:", 79062306a36Sopenharmony_ci le32_to_cpu(ofdm->sent_cts_cnt), 79162306a36Sopenharmony_ci accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt, 79262306a36Sopenharmony_ci max_ofdm->sent_cts_cnt); 79362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 79462306a36Sopenharmony_ci fmt_table, "sent_ba_rsp_cnt:", 79562306a36Sopenharmony_ci le32_to_cpu(ofdm->sent_ba_rsp_cnt), 79662306a36Sopenharmony_ci accum_ofdm->sent_ba_rsp_cnt, 79762306a36Sopenharmony_ci delta_ofdm->sent_ba_rsp_cnt, 79862306a36Sopenharmony_ci max_ofdm->sent_ba_rsp_cnt); 79962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 80062306a36Sopenharmony_ci fmt_table, "dsp_self_kill:", 80162306a36Sopenharmony_ci le32_to_cpu(ofdm->dsp_self_kill), 80262306a36Sopenharmony_ci accum_ofdm->dsp_self_kill, 80362306a36Sopenharmony_ci delta_ofdm->dsp_self_kill, 80462306a36Sopenharmony_ci max_ofdm->dsp_self_kill); 80562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 80662306a36Sopenharmony_ci fmt_table, "mh_format_err:", 80762306a36Sopenharmony_ci le32_to_cpu(ofdm->mh_format_err), 80862306a36Sopenharmony_ci accum_ofdm->mh_format_err, 80962306a36Sopenharmony_ci delta_ofdm->mh_format_err, 81062306a36Sopenharmony_ci max_ofdm->mh_format_err); 81162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 81262306a36Sopenharmony_ci fmt_table, "re_acq_main_rssi_sum:", 81362306a36Sopenharmony_ci le32_to_cpu(ofdm->re_acq_main_rssi_sum), 81462306a36Sopenharmony_ci accum_ofdm->re_acq_main_rssi_sum, 81562306a36Sopenharmony_ci delta_ofdm->re_acq_main_rssi_sum, 81662306a36Sopenharmony_ci max_ofdm->re_acq_main_rssi_sum); 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 81962306a36Sopenharmony_ci fmt_header, "Statistics_Rx - CCK:"); 82062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 82162306a36Sopenharmony_ci fmt_table, "ina_cnt:", 82262306a36Sopenharmony_ci le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, 82362306a36Sopenharmony_ci delta_cck->ina_cnt, max_cck->ina_cnt); 82462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 82562306a36Sopenharmony_ci fmt_table, "fina_cnt:", 82662306a36Sopenharmony_ci le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, 82762306a36Sopenharmony_ci delta_cck->fina_cnt, max_cck->fina_cnt); 82862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 82962306a36Sopenharmony_ci fmt_table, "plcp_err:", 83062306a36Sopenharmony_ci le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, 83162306a36Sopenharmony_ci delta_cck->plcp_err, max_cck->plcp_err); 83262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 83362306a36Sopenharmony_ci fmt_table, "crc32_err:", 83462306a36Sopenharmony_ci le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, 83562306a36Sopenharmony_ci delta_cck->crc32_err, max_cck->crc32_err); 83662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 83762306a36Sopenharmony_ci fmt_table, "overrun_err:", 83862306a36Sopenharmony_ci le32_to_cpu(cck->overrun_err), 83962306a36Sopenharmony_ci accum_cck->overrun_err, delta_cck->overrun_err, 84062306a36Sopenharmony_ci max_cck->overrun_err); 84162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 84262306a36Sopenharmony_ci fmt_table, "early_overrun_err:", 84362306a36Sopenharmony_ci le32_to_cpu(cck->early_overrun_err), 84462306a36Sopenharmony_ci accum_cck->early_overrun_err, 84562306a36Sopenharmony_ci delta_cck->early_overrun_err, 84662306a36Sopenharmony_ci max_cck->early_overrun_err); 84762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 84862306a36Sopenharmony_ci fmt_table, "crc32_good:", 84962306a36Sopenharmony_ci le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, 85062306a36Sopenharmony_ci delta_cck->crc32_good, max_cck->crc32_good); 85162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 85262306a36Sopenharmony_ci fmt_table, "false_alarm_cnt:", 85362306a36Sopenharmony_ci le32_to_cpu(cck->false_alarm_cnt), 85462306a36Sopenharmony_ci accum_cck->false_alarm_cnt, 85562306a36Sopenharmony_ci delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); 85662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 85762306a36Sopenharmony_ci fmt_table, "fina_sync_err_cnt:", 85862306a36Sopenharmony_ci le32_to_cpu(cck->fina_sync_err_cnt), 85962306a36Sopenharmony_ci accum_cck->fina_sync_err_cnt, 86062306a36Sopenharmony_ci delta_cck->fina_sync_err_cnt, 86162306a36Sopenharmony_ci max_cck->fina_sync_err_cnt); 86262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 86362306a36Sopenharmony_ci fmt_table, "sfd_timeout:", 86462306a36Sopenharmony_ci le32_to_cpu(cck->sfd_timeout), 86562306a36Sopenharmony_ci accum_cck->sfd_timeout, delta_cck->sfd_timeout, 86662306a36Sopenharmony_ci max_cck->sfd_timeout); 86762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 86862306a36Sopenharmony_ci fmt_table, "fina_timeout:", 86962306a36Sopenharmony_ci le32_to_cpu(cck->fina_timeout), 87062306a36Sopenharmony_ci accum_cck->fina_timeout, delta_cck->fina_timeout, 87162306a36Sopenharmony_ci max_cck->fina_timeout); 87262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 87362306a36Sopenharmony_ci fmt_table, "unresponded_rts:", 87462306a36Sopenharmony_ci le32_to_cpu(cck->unresponded_rts), 87562306a36Sopenharmony_ci accum_cck->unresponded_rts, delta_cck->unresponded_rts, 87662306a36Sopenharmony_ci max_cck->unresponded_rts); 87762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 87862306a36Sopenharmony_ci fmt_table, "rxe_frame_lmt_ovrun:", 87962306a36Sopenharmony_ci le32_to_cpu(cck->rxe_frame_limit_overrun), 88062306a36Sopenharmony_ci accum_cck->rxe_frame_limit_overrun, 88162306a36Sopenharmony_ci delta_cck->rxe_frame_limit_overrun, 88262306a36Sopenharmony_ci max_cck->rxe_frame_limit_overrun); 88362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 88462306a36Sopenharmony_ci fmt_table, "sent_ack_cnt:", 88562306a36Sopenharmony_ci le32_to_cpu(cck->sent_ack_cnt), 88662306a36Sopenharmony_ci accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt, 88762306a36Sopenharmony_ci max_cck->sent_ack_cnt); 88862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 88962306a36Sopenharmony_ci fmt_table, "sent_cts_cnt:", 89062306a36Sopenharmony_ci le32_to_cpu(cck->sent_cts_cnt), 89162306a36Sopenharmony_ci accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt, 89262306a36Sopenharmony_ci max_cck->sent_cts_cnt); 89362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 89462306a36Sopenharmony_ci fmt_table, "sent_ba_rsp_cnt:", 89562306a36Sopenharmony_ci le32_to_cpu(cck->sent_ba_rsp_cnt), 89662306a36Sopenharmony_ci accum_cck->sent_ba_rsp_cnt, 89762306a36Sopenharmony_ci delta_cck->sent_ba_rsp_cnt, 89862306a36Sopenharmony_ci max_cck->sent_ba_rsp_cnt); 89962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 90062306a36Sopenharmony_ci fmt_table, "dsp_self_kill:", 90162306a36Sopenharmony_ci le32_to_cpu(cck->dsp_self_kill), 90262306a36Sopenharmony_ci accum_cck->dsp_self_kill, delta_cck->dsp_self_kill, 90362306a36Sopenharmony_ci max_cck->dsp_self_kill); 90462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 90562306a36Sopenharmony_ci fmt_table, "mh_format_err:", 90662306a36Sopenharmony_ci le32_to_cpu(cck->mh_format_err), 90762306a36Sopenharmony_ci accum_cck->mh_format_err, delta_cck->mh_format_err, 90862306a36Sopenharmony_ci max_cck->mh_format_err); 90962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 91062306a36Sopenharmony_ci fmt_table, "re_acq_main_rssi_sum:", 91162306a36Sopenharmony_ci le32_to_cpu(cck->re_acq_main_rssi_sum), 91262306a36Sopenharmony_ci accum_cck->re_acq_main_rssi_sum, 91362306a36Sopenharmony_ci delta_cck->re_acq_main_rssi_sum, 91462306a36Sopenharmony_ci max_cck->re_acq_main_rssi_sum); 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 91762306a36Sopenharmony_ci fmt_header, "Statistics_Rx - GENERAL:"); 91862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 91962306a36Sopenharmony_ci fmt_table, "bogus_cts:", 92062306a36Sopenharmony_ci le32_to_cpu(general->bogus_cts), 92162306a36Sopenharmony_ci accum_general->bogus_cts, delta_general->bogus_cts, 92262306a36Sopenharmony_ci max_general->bogus_cts); 92362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 92462306a36Sopenharmony_ci fmt_table, "bogus_ack:", 92562306a36Sopenharmony_ci le32_to_cpu(general->bogus_ack), 92662306a36Sopenharmony_ci accum_general->bogus_ack, delta_general->bogus_ack, 92762306a36Sopenharmony_ci max_general->bogus_ack); 92862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 92962306a36Sopenharmony_ci fmt_table, "non_bssid_frames:", 93062306a36Sopenharmony_ci le32_to_cpu(general->non_bssid_frames), 93162306a36Sopenharmony_ci accum_general->non_bssid_frames, 93262306a36Sopenharmony_ci delta_general->non_bssid_frames, 93362306a36Sopenharmony_ci max_general->non_bssid_frames); 93462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 93562306a36Sopenharmony_ci fmt_table, "filtered_frames:", 93662306a36Sopenharmony_ci le32_to_cpu(general->filtered_frames), 93762306a36Sopenharmony_ci accum_general->filtered_frames, 93862306a36Sopenharmony_ci delta_general->filtered_frames, 93962306a36Sopenharmony_ci max_general->filtered_frames); 94062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 94162306a36Sopenharmony_ci fmt_table, "non_channel_beacons:", 94262306a36Sopenharmony_ci le32_to_cpu(general->non_channel_beacons), 94362306a36Sopenharmony_ci accum_general->non_channel_beacons, 94462306a36Sopenharmony_ci delta_general->non_channel_beacons, 94562306a36Sopenharmony_ci max_general->non_channel_beacons); 94662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 94762306a36Sopenharmony_ci fmt_table, "channel_beacons:", 94862306a36Sopenharmony_ci le32_to_cpu(general->channel_beacons), 94962306a36Sopenharmony_ci accum_general->channel_beacons, 95062306a36Sopenharmony_ci delta_general->channel_beacons, 95162306a36Sopenharmony_ci max_general->channel_beacons); 95262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 95362306a36Sopenharmony_ci fmt_table, "num_missed_bcon:", 95462306a36Sopenharmony_ci le32_to_cpu(general->num_missed_bcon), 95562306a36Sopenharmony_ci accum_general->num_missed_bcon, 95662306a36Sopenharmony_ci delta_general->num_missed_bcon, 95762306a36Sopenharmony_ci max_general->num_missed_bcon); 95862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 95962306a36Sopenharmony_ci fmt_table, "adc_rx_saturation_time:", 96062306a36Sopenharmony_ci le32_to_cpu(general->adc_rx_saturation_time), 96162306a36Sopenharmony_ci accum_general->adc_rx_saturation_time, 96262306a36Sopenharmony_ci delta_general->adc_rx_saturation_time, 96362306a36Sopenharmony_ci max_general->adc_rx_saturation_time); 96462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 96562306a36Sopenharmony_ci fmt_table, "ina_detect_search_tm:", 96662306a36Sopenharmony_ci le32_to_cpu(general->ina_detection_search_time), 96762306a36Sopenharmony_ci accum_general->ina_detection_search_time, 96862306a36Sopenharmony_ci delta_general->ina_detection_search_time, 96962306a36Sopenharmony_ci max_general->ina_detection_search_time); 97062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 97162306a36Sopenharmony_ci fmt_table, "beacon_silence_rssi_a:", 97262306a36Sopenharmony_ci le32_to_cpu(general->beacon_silence_rssi_a), 97362306a36Sopenharmony_ci accum_general->beacon_silence_rssi_a, 97462306a36Sopenharmony_ci delta_general->beacon_silence_rssi_a, 97562306a36Sopenharmony_ci max_general->beacon_silence_rssi_a); 97662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 97762306a36Sopenharmony_ci fmt_table, "beacon_silence_rssi_b:", 97862306a36Sopenharmony_ci le32_to_cpu(general->beacon_silence_rssi_b), 97962306a36Sopenharmony_ci accum_general->beacon_silence_rssi_b, 98062306a36Sopenharmony_ci delta_general->beacon_silence_rssi_b, 98162306a36Sopenharmony_ci max_general->beacon_silence_rssi_b); 98262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 98362306a36Sopenharmony_ci fmt_table, "beacon_silence_rssi_c:", 98462306a36Sopenharmony_ci le32_to_cpu(general->beacon_silence_rssi_c), 98562306a36Sopenharmony_ci accum_general->beacon_silence_rssi_c, 98662306a36Sopenharmony_ci delta_general->beacon_silence_rssi_c, 98762306a36Sopenharmony_ci max_general->beacon_silence_rssi_c); 98862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 98962306a36Sopenharmony_ci fmt_table, "interference_data_flag:", 99062306a36Sopenharmony_ci le32_to_cpu(general->interference_data_flag), 99162306a36Sopenharmony_ci accum_general->interference_data_flag, 99262306a36Sopenharmony_ci delta_general->interference_data_flag, 99362306a36Sopenharmony_ci max_general->interference_data_flag); 99462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 99562306a36Sopenharmony_ci fmt_table, "channel_load:", 99662306a36Sopenharmony_ci le32_to_cpu(general->channel_load), 99762306a36Sopenharmony_ci accum_general->channel_load, 99862306a36Sopenharmony_ci delta_general->channel_load, 99962306a36Sopenharmony_ci max_general->channel_load); 100062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 100162306a36Sopenharmony_ci fmt_table, "dsp_false_alarms:", 100262306a36Sopenharmony_ci le32_to_cpu(general->dsp_false_alarms), 100362306a36Sopenharmony_ci accum_general->dsp_false_alarms, 100462306a36Sopenharmony_ci delta_general->dsp_false_alarms, 100562306a36Sopenharmony_ci max_general->dsp_false_alarms); 100662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 100762306a36Sopenharmony_ci fmt_table, "beacon_rssi_a:", 100862306a36Sopenharmony_ci le32_to_cpu(general->beacon_rssi_a), 100962306a36Sopenharmony_ci accum_general->beacon_rssi_a, 101062306a36Sopenharmony_ci delta_general->beacon_rssi_a, 101162306a36Sopenharmony_ci max_general->beacon_rssi_a); 101262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 101362306a36Sopenharmony_ci fmt_table, "beacon_rssi_b:", 101462306a36Sopenharmony_ci le32_to_cpu(general->beacon_rssi_b), 101562306a36Sopenharmony_ci accum_general->beacon_rssi_b, 101662306a36Sopenharmony_ci delta_general->beacon_rssi_b, 101762306a36Sopenharmony_ci max_general->beacon_rssi_b); 101862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 101962306a36Sopenharmony_ci fmt_table, "beacon_rssi_c:", 102062306a36Sopenharmony_ci le32_to_cpu(general->beacon_rssi_c), 102162306a36Sopenharmony_ci accum_general->beacon_rssi_c, 102262306a36Sopenharmony_ci delta_general->beacon_rssi_c, 102362306a36Sopenharmony_ci max_general->beacon_rssi_c); 102462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 102562306a36Sopenharmony_ci fmt_table, "beacon_energy_a:", 102662306a36Sopenharmony_ci le32_to_cpu(general->beacon_energy_a), 102762306a36Sopenharmony_ci accum_general->beacon_energy_a, 102862306a36Sopenharmony_ci delta_general->beacon_energy_a, 102962306a36Sopenharmony_ci max_general->beacon_energy_a); 103062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 103162306a36Sopenharmony_ci fmt_table, "beacon_energy_b:", 103262306a36Sopenharmony_ci le32_to_cpu(general->beacon_energy_b), 103362306a36Sopenharmony_ci accum_general->beacon_energy_b, 103462306a36Sopenharmony_ci delta_general->beacon_energy_b, 103562306a36Sopenharmony_ci max_general->beacon_energy_b); 103662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 103762306a36Sopenharmony_ci fmt_table, "beacon_energy_c:", 103862306a36Sopenharmony_ci le32_to_cpu(general->beacon_energy_c), 103962306a36Sopenharmony_ci accum_general->beacon_energy_c, 104062306a36Sopenharmony_ci delta_general->beacon_energy_c, 104162306a36Sopenharmony_ci max_general->beacon_energy_c); 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 104462306a36Sopenharmony_ci fmt_header, "Statistics_Rx - OFDM_HT:"); 104562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 104662306a36Sopenharmony_ci fmt_table, "plcp_err:", 104762306a36Sopenharmony_ci le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, 104862306a36Sopenharmony_ci delta_ht->plcp_err, max_ht->plcp_err); 104962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 105062306a36Sopenharmony_ci fmt_table, "overrun_err:", 105162306a36Sopenharmony_ci le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, 105262306a36Sopenharmony_ci delta_ht->overrun_err, max_ht->overrun_err); 105362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 105462306a36Sopenharmony_ci fmt_table, "early_overrun_err:", 105562306a36Sopenharmony_ci le32_to_cpu(ht->early_overrun_err), 105662306a36Sopenharmony_ci accum_ht->early_overrun_err, 105762306a36Sopenharmony_ci delta_ht->early_overrun_err, 105862306a36Sopenharmony_ci max_ht->early_overrun_err); 105962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 106062306a36Sopenharmony_ci fmt_table, "crc32_good:", 106162306a36Sopenharmony_ci le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, 106262306a36Sopenharmony_ci delta_ht->crc32_good, max_ht->crc32_good); 106362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 106462306a36Sopenharmony_ci fmt_table, "crc32_err:", 106562306a36Sopenharmony_ci le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, 106662306a36Sopenharmony_ci delta_ht->crc32_err, max_ht->crc32_err); 106762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 106862306a36Sopenharmony_ci fmt_table, "mh_format_err:", 106962306a36Sopenharmony_ci le32_to_cpu(ht->mh_format_err), 107062306a36Sopenharmony_ci accum_ht->mh_format_err, 107162306a36Sopenharmony_ci delta_ht->mh_format_err, max_ht->mh_format_err); 107262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 107362306a36Sopenharmony_ci fmt_table, "agg_crc32_good:", 107462306a36Sopenharmony_ci le32_to_cpu(ht->agg_crc32_good), 107562306a36Sopenharmony_ci accum_ht->agg_crc32_good, 107662306a36Sopenharmony_ci delta_ht->agg_crc32_good, max_ht->agg_crc32_good); 107762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 107862306a36Sopenharmony_ci fmt_table, "agg_mpdu_cnt:", 107962306a36Sopenharmony_ci le32_to_cpu(ht->agg_mpdu_cnt), 108062306a36Sopenharmony_ci accum_ht->agg_mpdu_cnt, 108162306a36Sopenharmony_ci delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); 108262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 108362306a36Sopenharmony_ci fmt_table, "agg_cnt:", 108462306a36Sopenharmony_ci le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, 108562306a36Sopenharmony_ci delta_ht->agg_cnt, max_ht->agg_cnt); 108662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 108762306a36Sopenharmony_ci fmt_table, "unsupport_mcs:", 108862306a36Sopenharmony_ci le32_to_cpu(ht->unsupport_mcs), 108962306a36Sopenharmony_ci accum_ht->unsupport_mcs, 109062306a36Sopenharmony_ci delta_ht->unsupport_mcs, max_ht->unsupport_mcs); 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_ci spin_unlock_bh(&priv->statistics.lock); 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 109562306a36Sopenharmony_ci kfree(buf); 109662306a36Sopenharmony_ci return ret; 109762306a36Sopenharmony_ci} 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, 110062306a36Sopenharmony_ci char __user *user_buf, 110162306a36Sopenharmony_ci size_t count, loff_t *ppos) 110262306a36Sopenharmony_ci{ 110362306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 110462306a36Sopenharmony_ci int pos = 0; 110562306a36Sopenharmony_ci char *buf; 110662306a36Sopenharmony_ci int bufsz = (sizeof(struct statistics_tx) * 48) + 250; 110762306a36Sopenharmony_ci ssize_t ret; 110862306a36Sopenharmony_ci struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ci if (!iwl_is_alive(priv)) 111162306a36Sopenharmony_ci return -EAGAIN; 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 111462306a36Sopenharmony_ci if (!buf) 111562306a36Sopenharmony_ci return -ENOMEM; 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci /* the statistic information display here is based on 111862306a36Sopenharmony_ci * the last statistics notification from uCode 111962306a36Sopenharmony_ci * might not reflect the current uCode activity 112062306a36Sopenharmony_ci */ 112162306a36Sopenharmony_ci spin_lock_bh(&priv->statistics.lock); 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci tx = &priv->statistics.tx; 112462306a36Sopenharmony_ci accum_tx = &priv->accum_stats.tx; 112562306a36Sopenharmony_ci delta_tx = &priv->delta_stats.tx; 112662306a36Sopenharmony_ci max_tx = &priv->max_delta_stats.tx; 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci pos += iwl_statistics_flag(priv, buf, bufsz); 112962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 113062306a36Sopenharmony_ci fmt_header, "Statistics_Tx:"); 113162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 113262306a36Sopenharmony_ci fmt_table, "preamble:", 113362306a36Sopenharmony_ci le32_to_cpu(tx->preamble_cnt), 113462306a36Sopenharmony_ci accum_tx->preamble_cnt, 113562306a36Sopenharmony_ci delta_tx->preamble_cnt, max_tx->preamble_cnt); 113662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 113762306a36Sopenharmony_ci fmt_table, "rx_detected_cnt:", 113862306a36Sopenharmony_ci le32_to_cpu(tx->rx_detected_cnt), 113962306a36Sopenharmony_ci accum_tx->rx_detected_cnt, 114062306a36Sopenharmony_ci delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); 114162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 114262306a36Sopenharmony_ci fmt_table, "bt_prio_defer_cnt:", 114362306a36Sopenharmony_ci le32_to_cpu(tx->bt_prio_defer_cnt), 114462306a36Sopenharmony_ci accum_tx->bt_prio_defer_cnt, 114562306a36Sopenharmony_ci delta_tx->bt_prio_defer_cnt, 114662306a36Sopenharmony_ci max_tx->bt_prio_defer_cnt); 114762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 114862306a36Sopenharmony_ci fmt_table, "bt_prio_kill_cnt:", 114962306a36Sopenharmony_ci le32_to_cpu(tx->bt_prio_kill_cnt), 115062306a36Sopenharmony_ci accum_tx->bt_prio_kill_cnt, 115162306a36Sopenharmony_ci delta_tx->bt_prio_kill_cnt, 115262306a36Sopenharmony_ci max_tx->bt_prio_kill_cnt); 115362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 115462306a36Sopenharmony_ci fmt_table, "few_bytes_cnt:", 115562306a36Sopenharmony_ci le32_to_cpu(tx->few_bytes_cnt), 115662306a36Sopenharmony_ci accum_tx->few_bytes_cnt, 115762306a36Sopenharmony_ci delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); 115862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 115962306a36Sopenharmony_ci fmt_table, "cts_timeout:", 116062306a36Sopenharmony_ci le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, 116162306a36Sopenharmony_ci delta_tx->cts_timeout, max_tx->cts_timeout); 116262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 116362306a36Sopenharmony_ci fmt_table, "ack_timeout:", 116462306a36Sopenharmony_ci le32_to_cpu(tx->ack_timeout), 116562306a36Sopenharmony_ci accum_tx->ack_timeout, 116662306a36Sopenharmony_ci delta_tx->ack_timeout, max_tx->ack_timeout); 116762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 116862306a36Sopenharmony_ci fmt_table, "expected_ack_cnt:", 116962306a36Sopenharmony_ci le32_to_cpu(tx->expected_ack_cnt), 117062306a36Sopenharmony_ci accum_tx->expected_ack_cnt, 117162306a36Sopenharmony_ci delta_tx->expected_ack_cnt, 117262306a36Sopenharmony_ci max_tx->expected_ack_cnt); 117362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 117462306a36Sopenharmony_ci fmt_table, "actual_ack_cnt:", 117562306a36Sopenharmony_ci le32_to_cpu(tx->actual_ack_cnt), 117662306a36Sopenharmony_ci accum_tx->actual_ack_cnt, 117762306a36Sopenharmony_ci delta_tx->actual_ack_cnt, 117862306a36Sopenharmony_ci max_tx->actual_ack_cnt); 117962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 118062306a36Sopenharmony_ci fmt_table, "dump_msdu_cnt:", 118162306a36Sopenharmony_ci le32_to_cpu(tx->dump_msdu_cnt), 118262306a36Sopenharmony_ci accum_tx->dump_msdu_cnt, 118362306a36Sopenharmony_ci delta_tx->dump_msdu_cnt, 118462306a36Sopenharmony_ci max_tx->dump_msdu_cnt); 118562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 118662306a36Sopenharmony_ci fmt_table, "abort_nxt_frame_mismatch:", 118762306a36Sopenharmony_ci le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), 118862306a36Sopenharmony_ci accum_tx->burst_abort_next_frame_mismatch_cnt, 118962306a36Sopenharmony_ci delta_tx->burst_abort_next_frame_mismatch_cnt, 119062306a36Sopenharmony_ci max_tx->burst_abort_next_frame_mismatch_cnt); 119162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 119262306a36Sopenharmony_ci fmt_table, "abort_missing_nxt_frame:", 119362306a36Sopenharmony_ci le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), 119462306a36Sopenharmony_ci accum_tx->burst_abort_missing_next_frame_cnt, 119562306a36Sopenharmony_ci delta_tx->burst_abort_missing_next_frame_cnt, 119662306a36Sopenharmony_ci max_tx->burst_abort_missing_next_frame_cnt); 119762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 119862306a36Sopenharmony_ci fmt_table, "cts_timeout_collision:", 119962306a36Sopenharmony_ci le32_to_cpu(tx->cts_timeout_collision), 120062306a36Sopenharmony_ci accum_tx->cts_timeout_collision, 120162306a36Sopenharmony_ci delta_tx->cts_timeout_collision, 120262306a36Sopenharmony_ci max_tx->cts_timeout_collision); 120362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 120462306a36Sopenharmony_ci fmt_table, "ack_ba_timeout_collision:", 120562306a36Sopenharmony_ci le32_to_cpu(tx->ack_or_ba_timeout_collision), 120662306a36Sopenharmony_ci accum_tx->ack_or_ba_timeout_collision, 120762306a36Sopenharmony_ci delta_tx->ack_or_ba_timeout_collision, 120862306a36Sopenharmony_ci max_tx->ack_or_ba_timeout_collision); 120962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 121062306a36Sopenharmony_ci fmt_table, "agg ba_timeout:", 121162306a36Sopenharmony_ci le32_to_cpu(tx->agg.ba_timeout), 121262306a36Sopenharmony_ci accum_tx->agg.ba_timeout, 121362306a36Sopenharmony_ci delta_tx->agg.ba_timeout, 121462306a36Sopenharmony_ci max_tx->agg.ba_timeout); 121562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 121662306a36Sopenharmony_ci fmt_table, "agg ba_resched_frames:", 121762306a36Sopenharmony_ci le32_to_cpu(tx->agg.ba_reschedule_frames), 121862306a36Sopenharmony_ci accum_tx->agg.ba_reschedule_frames, 121962306a36Sopenharmony_ci delta_tx->agg.ba_reschedule_frames, 122062306a36Sopenharmony_ci max_tx->agg.ba_reschedule_frames); 122162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 122262306a36Sopenharmony_ci fmt_table, "agg scd_query_agg_frame:", 122362306a36Sopenharmony_ci le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), 122462306a36Sopenharmony_ci accum_tx->agg.scd_query_agg_frame_cnt, 122562306a36Sopenharmony_ci delta_tx->agg.scd_query_agg_frame_cnt, 122662306a36Sopenharmony_ci max_tx->agg.scd_query_agg_frame_cnt); 122762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 122862306a36Sopenharmony_ci fmt_table, "agg scd_query_no_agg:", 122962306a36Sopenharmony_ci le32_to_cpu(tx->agg.scd_query_no_agg), 123062306a36Sopenharmony_ci accum_tx->agg.scd_query_no_agg, 123162306a36Sopenharmony_ci delta_tx->agg.scd_query_no_agg, 123262306a36Sopenharmony_ci max_tx->agg.scd_query_no_agg); 123362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 123462306a36Sopenharmony_ci fmt_table, "agg scd_query_agg:", 123562306a36Sopenharmony_ci le32_to_cpu(tx->agg.scd_query_agg), 123662306a36Sopenharmony_ci accum_tx->agg.scd_query_agg, 123762306a36Sopenharmony_ci delta_tx->agg.scd_query_agg, 123862306a36Sopenharmony_ci max_tx->agg.scd_query_agg); 123962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 124062306a36Sopenharmony_ci fmt_table, "agg scd_query_mismatch:", 124162306a36Sopenharmony_ci le32_to_cpu(tx->agg.scd_query_mismatch), 124262306a36Sopenharmony_ci accum_tx->agg.scd_query_mismatch, 124362306a36Sopenharmony_ci delta_tx->agg.scd_query_mismatch, 124462306a36Sopenharmony_ci max_tx->agg.scd_query_mismatch); 124562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 124662306a36Sopenharmony_ci fmt_table, "agg frame_not_ready:", 124762306a36Sopenharmony_ci le32_to_cpu(tx->agg.frame_not_ready), 124862306a36Sopenharmony_ci accum_tx->agg.frame_not_ready, 124962306a36Sopenharmony_ci delta_tx->agg.frame_not_ready, 125062306a36Sopenharmony_ci max_tx->agg.frame_not_ready); 125162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 125262306a36Sopenharmony_ci fmt_table, "agg underrun:", 125362306a36Sopenharmony_ci le32_to_cpu(tx->agg.underrun), 125462306a36Sopenharmony_ci accum_tx->agg.underrun, 125562306a36Sopenharmony_ci delta_tx->agg.underrun, max_tx->agg.underrun); 125662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 125762306a36Sopenharmony_ci fmt_table, "agg bt_prio_kill:", 125862306a36Sopenharmony_ci le32_to_cpu(tx->agg.bt_prio_kill), 125962306a36Sopenharmony_ci accum_tx->agg.bt_prio_kill, 126062306a36Sopenharmony_ci delta_tx->agg.bt_prio_kill, 126162306a36Sopenharmony_ci max_tx->agg.bt_prio_kill); 126262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 126362306a36Sopenharmony_ci fmt_table, "agg rx_ba_rsp_cnt:", 126462306a36Sopenharmony_ci le32_to_cpu(tx->agg.rx_ba_rsp_cnt), 126562306a36Sopenharmony_ci accum_tx->agg.rx_ba_rsp_cnt, 126662306a36Sopenharmony_ci delta_tx->agg.rx_ba_rsp_cnt, 126762306a36Sopenharmony_ci max_tx->agg.rx_ba_rsp_cnt); 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { 127062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 127162306a36Sopenharmony_ci "tx power: (1/2 dB step)\n"); 127262306a36Sopenharmony_ci if ((priv->nvm_data->valid_tx_ant & ANT_A) && 127362306a36Sopenharmony_ci tx->tx_power.ant_a) 127462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 127562306a36Sopenharmony_ci fmt_hex, "antenna A:", 127662306a36Sopenharmony_ci tx->tx_power.ant_a); 127762306a36Sopenharmony_ci if ((priv->nvm_data->valid_tx_ant & ANT_B) && 127862306a36Sopenharmony_ci tx->tx_power.ant_b) 127962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 128062306a36Sopenharmony_ci fmt_hex, "antenna B:", 128162306a36Sopenharmony_ci tx->tx_power.ant_b); 128262306a36Sopenharmony_ci if ((priv->nvm_data->valid_tx_ant & ANT_C) && 128362306a36Sopenharmony_ci tx->tx_power.ant_c) 128462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 128562306a36Sopenharmony_ci fmt_hex, "antenna C:", 128662306a36Sopenharmony_ci tx->tx_power.ant_c); 128762306a36Sopenharmony_ci } 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci spin_unlock_bh(&priv->statistics.lock); 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 129262306a36Sopenharmony_ci kfree(buf); 129362306a36Sopenharmony_ci return ret; 129462306a36Sopenharmony_ci} 129562306a36Sopenharmony_ci 129662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, 129762306a36Sopenharmony_ci char __user *user_buf, 129862306a36Sopenharmony_ci size_t count, loff_t *ppos) 129962306a36Sopenharmony_ci{ 130062306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 130162306a36Sopenharmony_ci int pos = 0; 130262306a36Sopenharmony_ci char *buf; 130362306a36Sopenharmony_ci int bufsz = sizeof(struct statistics_general) * 10 + 300; 130462306a36Sopenharmony_ci ssize_t ret; 130562306a36Sopenharmony_ci struct statistics_general_common *general, *accum_general; 130662306a36Sopenharmony_ci struct statistics_general_common *delta_general, *max_general; 130762306a36Sopenharmony_ci struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; 130862306a36Sopenharmony_ci struct statistics_div *div, *accum_div, *delta_div, *max_div; 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci if (!iwl_is_alive(priv)) 131162306a36Sopenharmony_ci return -EAGAIN; 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 131462306a36Sopenharmony_ci if (!buf) 131562306a36Sopenharmony_ci return -ENOMEM; 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci /* the statistic information display here is based on 131862306a36Sopenharmony_ci * the last statistics notification from uCode 131962306a36Sopenharmony_ci * might not reflect the current uCode activity 132062306a36Sopenharmony_ci */ 132162306a36Sopenharmony_ci 132262306a36Sopenharmony_ci spin_lock_bh(&priv->statistics.lock); 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_ci general = &priv->statistics.common; 132562306a36Sopenharmony_ci dbg = &priv->statistics.common.dbg; 132662306a36Sopenharmony_ci div = &priv->statistics.common.div; 132762306a36Sopenharmony_ci accum_general = &priv->accum_stats.common; 132862306a36Sopenharmony_ci accum_dbg = &priv->accum_stats.common.dbg; 132962306a36Sopenharmony_ci accum_div = &priv->accum_stats.common.div; 133062306a36Sopenharmony_ci delta_general = &priv->delta_stats.common; 133162306a36Sopenharmony_ci max_general = &priv->max_delta_stats.common; 133262306a36Sopenharmony_ci delta_dbg = &priv->delta_stats.common.dbg; 133362306a36Sopenharmony_ci max_dbg = &priv->max_delta_stats.common.dbg; 133462306a36Sopenharmony_ci delta_div = &priv->delta_stats.common.div; 133562306a36Sopenharmony_ci max_div = &priv->max_delta_stats.common.div; 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci pos += iwl_statistics_flag(priv, buf, bufsz); 133862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 133962306a36Sopenharmony_ci fmt_header, "Statistics_General:"); 134062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 134162306a36Sopenharmony_ci fmt_value, "temperature:", 134262306a36Sopenharmony_ci le32_to_cpu(general->temperature)); 134362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 134462306a36Sopenharmony_ci fmt_value, "temperature_m:", 134562306a36Sopenharmony_ci le32_to_cpu(general->temperature_m)); 134662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 134762306a36Sopenharmony_ci fmt_value, "ttl_timestamp:", 134862306a36Sopenharmony_ci le32_to_cpu(general->ttl_timestamp)); 134962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 135062306a36Sopenharmony_ci fmt_table, "burst_check:", 135162306a36Sopenharmony_ci le32_to_cpu(dbg->burst_check), 135262306a36Sopenharmony_ci accum_dbg->burst_check, 135362306a36Sopenharmony_ci delta_dbg->burst_check, max_dbg->burst_check); 135462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 135562306a36Sopenharmony_ci fmt_table, "burst_count:", 135662306a36Sopenharmony_ci le32_to_cpu(dbg->burst_count), 135762306a36Sopenharmony_ci accum_dbg->burst_count, 135862306a36Sopenharmony_ci delta_dbg->burst_count, max_dbg->burst_count); 135962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 136062306a36Sopenharmony_ci fmt_table, "wait_for_silence_timeout_count:", 136162306a36Sopenharmony_ci le32_to_cpu(dbg->wait_for_silence_timeout_cnt), 136262306a36Sopenharmony_ci accum_dbg->wait_for_silence_timeout_cnt, 136362306a36Sopenharmony_ci delta_dbg->wait_for_silence_timeout_cnt, 136462306a36Sopenharmony_ci max_dbg->wait_for_silence_timeout_cnt); 136562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 136662306a36Sopenharmony_ci fmt_table, "sleep_time:", 136762306a36Sopenharmony_ci le32_to_cpu(general->sleep_time), 136862306a36Sopenharmony_ci accum_general->sleep_time, 136962306a36Sopenharmony_ci delta_general->sleep_time, max_general->sleep_time); 137062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 137162306a36Sopenharmony_ci fmt_table, "slots_out:", 137262306a36Sopenharmony_ci le32_to_cpu(general->slots_out), 137362306a36Sopenharmony_ci accum_general->slots_out, 137462306a36Sopenharmony_ci delta_general->slots_out, max_general->slots_out); 137562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 137662306a36Sopenharmony_ci fmt_table, "slots_idle:", 137762306a36Sopenharmony_ci le32_to_cpu(general->slots_idle), 137862306a36Sopenharmony_ci accum_general->slots_idle, 137962306a36Sopenharmony_ci delta_general->slots_idle, max_general->slots_idle); 138062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 138162306a36Sopenharmony_ci fmt_table, "tx_on_a:", 138262306a36Sopenharmony_ci le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, 138362306a36Sopenharmony_ci delta_div->tx_on_a, max_div->tx_on_a); 138462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 138562306a36Sopenharmony_ci fmt_table, "tx_on_b:", 138662306a36Sopenharmony_ci le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, 138762306a36Sopenharmony_ci delta_div->tx_on_b, max_div->tx_on_b); 138862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 138962306a36Sopenharmony_ci fmt_table, "exec_time:", 139062306a36Sopenharmony_ci le32_to_cpu(div->exec_time), accum_div->exec_time, 139162306a36Sopenharmony_ci delta_div->exec_time, max_div->exec_time); 139262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 139362306a36Sopenharmony_ci fmt_table, "probe_time:", 139462306a36Sopenharmony_ci le32_to_cpu(div->probe_time), accum_div->probe_time, 139562306a36Sopenharmony_ci delta_div->probe_time, max_div->probe_time); 139662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 139762306a36Sopenharmony_ci fmt_table, "rx_enable_counter:", 139862306a36Sopenharmony_ci le32_to_cpu(general->rx_enable_counter), 139962306a36Sopenharmony_ci accum_general->rx_enable_counter, 140062306a36Sopenharmony_ci delta_general->rx_enable_counter, 140162306a36Sopenharmony_ci max_general->rx_enable_counter); 140262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 140362306a36Sopenharmony_ci fmt_table, "num_of_sos_states:", 140462306a36Sopenharmony_ci le32_to_cpu(general->num_of_sos_states), 140562306a36Sopenharmony_ci accum_general->num_of_sos_states, 140662306a36Sopenharmony_ci delta_general->num_of_sos_states, 140762306a36Sopenharmony_ci max_general->num_of_sos_states); 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci spin_unlock_bh(&priv->statistics.lock); 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 141262306a36Sopenharmony_ci kfree(buf); 141362306a36Sopenharmony_ci return ret; 141462306a36Sopenharmony_ci} 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, 141762306a36Sopenharmony_ci char __user *user_buf, 141862306a36Sopenharmony_ci size_t count, loff_t *ppos) 141962306a36Sopenharmony_ci{ 142062306a36Sopenharmony_ci struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 142162306a36Sopenharmony_ci int pos = 0; 142262306a36Sopenharmony_ci char *buf; 142362306a36Sopenharmony_ci int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200; 142462306a36Sopenharmony_ci ssize_t ret; 142562306a36Sopenharmony_ci struct statistics_bt_activity *bt, *accum_bt; 142662306a36Sopenharmony_ci 142762306a36Sopenharmony_ci if (!iwl_is_alive(priv)) 142862306a36Sopenharmony_ci return -EAGAIN; 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci if (!priv->bt_enable_flag) 143162306a36Sopenharmony_ci return -EINVAL; 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci /* make request to uCode to retrieve statistics information */ 143462306a36Sopenharmony_ci mutex_lock(&priv->mutex); 143562306a36Sopenharmony_ci ret = iwl_send_statistics_request(priv, 0, false); 143662306a36Sopenharmony_ci mutex_unlock(&priv->mutex); 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci if (ret) 143962306a36Sopenharmony_ci return -EAGAIN; 144062306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 144162306a36Sopenharmony_ci if (!buf) 144262306a36Sopenharmony_ci return -ENOMEM; 144362306a36Sopenharmony_ci 144462306a36Sopenharmony_ci /* 144562306a36Sopenharmony_ci * the statistic information display here is based on 144662306a36Sopenharmony_ci * the last statistics notification from uCode 144762306a36Sopenharmony_ci * might not reflect the current uCode activity 144862306a36Sopenharmony_ci */ 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_ci spin_lock_bh(&priv->statistics.lock); 145162306a36Sopenharmony_ci 145262306a36Sopenharmony_ci bt = &priv->statistics.bt_activity; 145362306a36Sopenharmony_ci accum_bt = &priv->accum_stats.bt_activity; 145462306a36Sopenharmony_ci 145562306a36Sopenharmony_ci pos += iwl_statistics_flag(priv, buf, bufsz); 145662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); 145762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 145862306a36Sopenharmony_ci "\t\t\tcurrent\t\t\taccumulative\n"); 145962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 146062306a36Sopenharmony_ci "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", 146162306a36Sopenharmony_ci le32_to_cpu(bt->hi_priority_tx_req_cnt), 146262306a36Sopenharmony_ci accum_bt->hi_priority_tx_req_cnt); 146362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 146462306a36Sopenharmony_ci "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n", 146562306a36Sopenharmony_ci le32_to_cpu(bt->hi_priority_tx_denied_cnt), 146662306a36Sopenharmony_ci accum_bt->hi_priority_tx_denied_cnt); 146762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 146862306a36Sopenharmony_ci "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", 146962306a36Sopenharmony_ci le32_to_cpu(bt->lo_priority_tx_req_cnt), 147062306a36Sopenharmony_ci accum_bt->lo_priority_tx_req_cnt); 147162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 147262306a36Sopenharmony_ci "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n", 147362306a36Sopenharmony_ci le32_to_cpu(bt->lo_priority_tx_denied_cnt), 147462306a36Sopenharmony_ci accum_bt->lo_priority_tx_denied_cnt); 147562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 147662306a36Sopenharmony_ci "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", 147762306a36Sopenharmony_ci le32_to_cpu(bt->hi_priority_rx_req_cnt), 147862306a36Sopenharmony_ci accum_bt->hi_priority_rx_req_cnt); 147962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 148062306a36Sopenharmony_ci "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n", 148162306a36Sopenharmony_ci le32_to_cpu(bt->hi_priority_rx_denied_cnt), 148262306a36Sopenharmony_ci accum_bt->hi_priority_rx_denied_cnt); 148362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 148462306a36Sopenharmony_ci "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", 148562306a36Sopenharmony_ci le32_to_cpu(bt->lo_priority_rx_req_cnt), 148662306a36Sopenharmony_ci accum_bt->lo_priority_rx_req_cnt); 148762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 148862306a36Sopenharmony_ci "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", 148962306a36Sopenharmony_ci le32_to_cpu(bt->lo_priority_rx_denied_cnt), 149062306a36Sopenharmony_ci accum_bt->lo_priority_rx_denied_cnt); 149162306a36Sopenharmony_ci 149262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 149362306a36Sopenharmony_ci "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", 149462306a36Sopenharmony_ci le32_to_cpu(priv->statistics.num_bt_kills), 149562306a36Sopenharmony_ci priv->statistics.accum_num_bt_kills); 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_ci spin_unlock_bh(&priv->statistics.lock); 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 150062306a36Sopenharmony_ci kfree(buf); 150162306a36Sopenharmony_ci return ret; 150262306a36Sopenharmony_ci} 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, 150562306a36Sopenharmony_ci char __user *user_buf, 150662306a36Sopenharmony_ci size_t count, loff_t *ppos) 150762306a36Sopenharmony_ci{ 150862306a36Sopenharmony_ci struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 150962306a36Sopenharmony_ci int pos = 0; 151062306a36Sopenharmony_ci char *buf; 151162306a36Sopenharmony_ci int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + 151262306a36Sopenharmony_ci (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; 151362306a36Sopenharmony_ci ssize_t ret; 151462306a36Sopenharmony_ci 151562306a36Sopenharmony_ci if (!iwl_is_alive(priv)) 151662306a36Sopenharmony_ci return -EAGAIN; 151762306a36Sopenharmony_ci 151862306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 151962306a36Sopenharmony_ci if (!buf) 152062306a36Sopenharmony_ci return -ENOMEM; 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n"); 152362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n", 152462306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY), 152562306a36Sopenharmony_ci priv->reply_tx_stats.pp_delay); 152662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 152762306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES), 152862306a36Sopenharmony_ci priv->reply_tx_stats.pp_few_bytes); 152962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 153062306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO), 153162306a36Sopenharmony_ci priv->reply_tx_stats.pp_bt_prio); 153262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 153362306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD), 153462306a36Sopenharmony_ci priv->reply_tx_stats.pp_quiet_period); 153562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 153662306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK), 153762306a36Sopenharmony_ci priv->reply_tx_stats.pp_calc_ttak); 153862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 153962306a36Sopenharmony_ci iwl_get_tx_fail_reason( 154062306a36Sopenharmony_ci TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY), 154162306a36Sopenharmony_ci priv->reply_tx_stats.int_crossed_retry); 154262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 154362306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT), 154462306a36Sopenharmony_ci priv->reply_tx_stats.short_limit); 154562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 154662306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT), 154762306a36Sopenharmony_ci priv->reply_tx_stats.long_limit); 154862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 154962306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN), 155062306a36Sopenharmony_ci priv->reply_tx_stats.fifo_underrun); 155162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 155262306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW), 155362306a36Sopenharmony_ci priv->reply_tx_stats.drain_flow); 155462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 155562306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH), 155662306a36Sopenharmony_ci priv->reply_tx_stats.rfkill_flush); 155762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 155862306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE), 155962306a36Sopenharmony_ci priv->reply_tx_stats.life_expire); 156062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 156162306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS), 156262306a36Sopenharmony_ci priv->reply_tx_stats.dest_ps); 156362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 156462306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED), 156562306a36Sopenharmony_ci priv->reply_tx_stats.host_abort); 156662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 156762306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY), 156862306a36Sopenharmony_ci priv->reply_tx_stats.pp_delay); 156962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 157062306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID), 157162306a36Sopenharmony_ci priv->reply_tx_stats.sta_invalid); 157262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 157362306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED), 157462306a36Sopenharmony_ci priv->reply_tx_stats.frag_drop); 157562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 157662306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE), 157762306a36Sopenharmony_ci priv->reply_tx_stats.tid_disable); 157862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 157962306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED), 158062306a36Sopenharmony_ci priv->reply_tx_stats.fifo_flush); 158162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 158262306a36Sopenharmony_ci iwl_get_tx_fail_reason( 158362306a36Sopenharmony_ci TX_STATUS_FAIL_INSUFFICIENT_CF_POLL), 158462306a36Sopenharmony_ci priv->reply_tx_stats.insuff_cf_poll); 158562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 158662306a36Sopenharmony_ci iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX), 158762306a36Sopenharmony_ci priv->reply_tx_stats.fail_hw_drop); 158862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 158962306a36Sopenharmony_ci iwl_get_tx_fail_reason( 159062306a36Sopenharmony_ci TX_STATUS_FAIL_NO_BEACON_ON_RADAR), 159162306a36Sopenharmony_ci priv->reply_tx_stats.sta_color_mismatch); 159262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", 159362306a36Sopenharmony_ci priv->reply_tx_stats.unknown); 159462306a36Sopenharmony_ci 159562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 159662306a36Sopenharmony_ci "\nStatistics_Agg_TX_Error:\n"); 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 159962306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK), 160062306a36Sopenharmony_ci priv->reply_agg_tx_stats.underrun); 160162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 160262306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK), 160362306a36Sopenharmony_ci priv->reply_agg_tx_stats.bt_prio); 160462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 160562306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK), 160662306a36Sopenharmony_ci priv->reply_agg_tx_stats.few_bytes); 160762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 160862306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK), 160962306a36Sopenharmony_ci priv->reply_agg_tx_stats.abort); 161062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 161162306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason( 161262306a36Sopenharmony_ci AGG_TX_STATE_LAST_SENT_TTL_MSK), 161362306a36Sopenharmony_ci priv->reply_agg_tx_stats.last_sent_ttl); 161462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 161562306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason( 161662306a36Sopenharmony_ci AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK), 161762306a36Sopenharmony_ci priv->reply_agg_tx_stats.last_sent_try); 161862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 161962306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason( 162062306a36Sopenharmony_ci AGG_TX_STATE_LAST_SENT_BT_KILL_MSK), 162162306a36Sopenharmony_ci priv->reply_agg_tx_stats.last_sent_bt_kill); 162262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 162362306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK), 162462306a36Sopenharmony_ci priv->reply_agg_tx_stats.scd_query); 162562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 162662306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason( 162762306a36Sopenharmony_ci AGG_TX_STATE_TEST_BAD_CRC32_MSK), 162862306a36Sopenharmony_ci priv->reply_agg_tx_stats.bad_crc32); 162962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 163062306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK), 163162306a36Sopenharmony_ci priv->reply_agg_tx_stats.response); 163262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 163362306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK), 163462306a36Sopenharmony_ci priv->reply_agg_tx_stats.dump_tx); 163562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 163662306a36Sopenharmony_ci iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK), 163762306a36Sopenharmony_ci priv->reply_agg_tx_stats.delay_tx); 163862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", 163962306a36Sopenharmony_ci priv->reply_agg_tx_stats.unknown); 164062306a36Sopenharmony_ci 164162306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 164262306a36Sopenharmony_ci kfree(buf); 164362306a36Sopenharmony_ci return ret; 164462306a36Sopenharmony_ci} 164562306a36Sopenharmony_ci 164662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_sensitivity_read(struct file *file, 164762306a36Sopenharmony_ci char __user *user_buf, 164862306a36Sopenharmony_ci size_t count, loff_t *ppos) { 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 165162306a36Sopenharmony_ci int pos = 0; 165262306a36Sopenharmony_ci int cnt = 0; 165362306a36Sopenharmony_ci char *buf; 165462306a36Sopenharmony_ci int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100; 165562306a36Sopenharmony_ci ssize_t ret; 165662306a36Sopenharmony_ci struct iwl_sensitivity_data *data; 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_ci data = &priv->sensitivity_data; 165962306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 166062306a36Sopenharmony_ci if (!buf) 166162306a36Sopenharmony_ci return -ENOMEM; 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", 166462306a36Sopenharmony_ci data->auto_corr_ofdm); 166562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 166662306a36Sopenharmony_ci "auto_corr_ofdm_mrc:\t\t %u\n", 166762306a36Sopenharmony_ci data->auto_corr_ofdm_mrc); 166862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n", 166962306a36Sopenharmony_ci data->auto_corr_ofdm_x1); 167062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 167162306a36Sopenharmony_ci "auto_corr_ofdm_mrc_x1:\t\t %u\n", 167262306a36Sopenharmony_ci data->auto_corr_ofdm_mrc_x1); 167362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n", 167462306a36Sopenharmony_ci data->auto_corr_cck); 167562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n", 167662306a36Sopenharmony_ci data->auto_corr_cck_mrc); 167762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 167862306a36Sopenharmony_ci "last_bad_plcp_cnt_ofdm:\t\t %u\n", 167962306a36Sopenharmony_ci data->last_bad_plcp_cnt_ofdm); 168062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n", 168162306a36Sopenharmony_ci data->last_fa_cnt_ofdm); 168262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 168362306a36Sopenharmony_ci "last_bad_plcp_cnt_cck:\t\t %u\n", 168462306a36Sopenharmony_ci data->last_bad_plcp_cnt_cck); 168562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n", 168662306a36Sopenharmony_ci data->last_fa_cnt_cck); 168762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n", 168862306a36Sopenharmony_ci data->nrg_curr_state); 168962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n", 169062306a36Sopenharmony_ci data->nrg_prev_state); 169162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t"); 169262306a36Sopenharmony_ci for (cnt = 0; cnt < 10; cnt++) { 169362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, " %u", 169462306a36Sopenharmony_ci data->nrg_value[cnt]); 169562306a36Sopenharmony_ci } 169662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 169762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t"); 169862306a36Sopenharmony_ci for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) { 169962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, " %u", 170062306a36Sopenharmony_ci data->nrg_silence_rssi[cnt]); 170162306a36Sopenharmony_ci } 170262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 170362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n", 170462306a36Sopenharmony_ci data->nrg_silence_ref); 170562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n", 170662306a36Sopenharmony_ci data->nrg_energy_idx); 170762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n", 170862306a36Sopenharmony_ci data->nrg_silence_idx); 170962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n", 171062306a36Sopenharmony_ci data->nrg_th_cck); 171162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 171262306a36Sopenharmony_ci "nrg_auto_corr_silence_diff:\t %u\n", 171362306a36Sopenharmony_ci data->nrg_auto_corr_silence_diff); 171462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n", 171562306a36Sopenharmony_ci data->num_in_cck_no_fa); 171662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n", 171762306a36Sopenharmony_ci data->nrg_th_ofdm); 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 172062306a36Sopenharmony_ci kfree(buf); 172162306a36Sopenharmony_ci return ret; 172262306a36Sopenharmony_ci} 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci 172562306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_chain_noise_read(struct file *file, 172662306a36Sopenharmony_ci char __user *user_buf, 172762306a36Sopenharmony_ci size_t count, loff_t *ppos) { 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 173062306a36Sopenharmony_ci int pos = 0; 173162306a36Sopenharmony_ci int cnt = 0; 173262306a36Sopenharmony_ci char *buf; 173362306a36Sopenharmony_ci int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100; 173462306a36Sopenharmony_ci ssize_t ret; 173562306a36Sopenharmony_ci struct iwl_chain_noise_data *data; 173662306a36Sopenharmony_ci 173762306a36Sopenharmony_ci data = &priv->chain_noise_data; 173862306a36Sopenharmony_ci buf = kzalloc(bufsz, GFP_KERNEL); 173962306a36Sopenharmony_ci if (!buf) 174062306a36Sopenharmony_ci return -ENOMEM; 174162306a36Sopenharmony_ci 174262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", 174362306a36Sopenharmony_ci data->active_chains); 174462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n", 174562306a36Sopenharmony_ci data->chain_noise_a); 174662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n", 174762306a36Sopenharmony_ci data->chain_noise_b); 174862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n", 174962306a36Sopenharmony_ci data->chain_noise_c); 175062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n", 175162306a36Sopenharmony_ci data->chain_signal_a); 175262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n", 175362306a36Sopenharmony_ci data->chain_signal_b); 175462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n", 175562306a36Sopenharmony_ci data->chain_signal_c); 175662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n", 175762306a36Sopenharmony_ci data->beacon_count); 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t"); 176062306a36Sopenharmony_ci for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 176162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, " %u", 176262306a36Sopenharmony_ci data->disconn_array[cnt]); 176362306a36Sopenharmony_ci } 176462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 176562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t"); 176662306a36Sopenharmony_ci for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 176762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, " %u", 176862306a36Sopenharmony_ci data->delta_gain_code[cnt]); 176962306a36Sopenharmony_ci } 177062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "\n"); 177162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n", 177262306a36Sopenharmony_ci data->radio_write); 177362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n", 177462306a36Sopenharmony_ci data->state); 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 177762306a36Sopenharmony_ci kfree(buf); 177862306a36Sopenharmony_ci return ret; 177962306a36Sopenharmony_ci} 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_power_save_status_read(struct file *file, 178262306a36Sopenharmony_ci char __user *user_buf, 178362306a36Sopenharmony_ci size_t count, loff_t *ppos) 178462306a36Sopenharmony_ci{ 178562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 178662306a36Sopenharmony_ci char buf[60]; 178762306a36Sopenharmony_ci int pos = 0; 178862306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 178962306a36Sopenharmony_ci u32 pwrsave_status; 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci pwrsave_status = iwl_read32(priv->trans, CSR_GP_CNTRL) & 179262306a36Sopenharmony_ci CSR_GP_REG_POWER_SAVE_STATUS_MSK; 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); 179562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 179662306a36Sopenharmony_ci (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : 179762306a36Sopenharmony_ci (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : 179862306a36Sopenharmony_ci (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : 179962306a36Sopenharmony_ci "error"); 180062306a36Sopenharmony_ci 180162306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 180262306a36Sopenharmony_ci} 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, 180562306a36Sopenharmony_ci const char __user *user_buf, 180662306a36Sopenharmony_ci size_t count, loff_t *ppos) 180762306a36Sopenharmony_ci{ 180862306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 180962306a36Sopenharmony_ci char buf[8]; 181062306a36Sopenharmony_ci int buf_size; 181162306a36Sopenharmony_ci int clear; 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 181462306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 181562306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 181662306a36Sopenharmony_ci return -EFAULT; 181762306a36Sopenharmony_ci if (sscanf(buf, "%d", &clear) != 1) 181862306a36Sopenharmony_ci return -EFAULT; 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_ci /* make request to uCode to retrieve statistics information */ 182162306a36Sopenharmony_ci mutex_lock(&priv->mutex); 182262306a36Sopenharmony_ci iwl_send_statistics_request(priv, 0, true); 182362306a36Sopenharmony_ci mutex_unlock(&priv->mutex); 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci return count; 182662306a36Sopenharmony_ci} 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, 182962306a36Sopenharmony_ci char __user *user_buf, 183062306a36Sopenharmony_ci size_t count, loff_t *ppos) { 183162306a36Sopenharmony_ci 183262306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 183362306a36Sopenharmony_ci int pos = 0; 183462306a36Sopenharmony_ci char buf[128]; 183562306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", 183862306a36Sopenharmony_ci priv->event_log.ucode_trace ? "On" : "Off"); 183962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", 184062306a36Sopenharmony_ci priv->event_log.non_wraps_count); 184162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", 184262306a36Sopenharmony_ci priv->event_log.wraps_once_count); 184362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", 184462306a36Sopenharmony_ci priv->event_log.wraps_more_count); 184562306a36Sopenharmony_ci 184662306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 184762306a36Sopenharmony_ci} 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, 185062306a36Sopenharmony_ci const char __user *user_buf, 185162306a36Sopenharmony_ci size_t count, loff_t *ppos) 185262306a36Sopenharmony_ci{ 185362306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 185462306a36Sopenharmony_ci char buf[8]; 185562306a36Sopenharmony_ci int buf_size; 185662306a36Sopenharmony_ci int trace; 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 185962306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 186062306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 186162306a36Sopenharmony_ci return -EFAULT; 186262306a36Sopenharmony_ci if (sscanf(buf, "%d", &trace) != 1) 186362306a36Sopenharmony_ci return -EFAULT; 186462306a36Sopenharmony_ci 186562306a36Sopenharmony_ci if (trace) { 186662306a36Sopenharmony_ci priv->event_log.ucode_trace = true; 186762306a36Sopenharmony_ci if (iwl_is_alive(priv)) { 186862306a36Sopenharmony_ci /* start collecting data now */ 186962306a36Sopenharmony_ci mod_timer(&priv->ucode_trace, jiffies); 187062306a36Sopenharmony_ci } 187162306a36Sopenharmony_ci } else { 187262306a36Sopenharmony_ci priv->event_log.ucode_trace = false; 187362306a36Sopenharmony_ci del_timer_sync(&priv->ucode_trace); 187462306a36Sopenharmony_ci } 187562306a36Sopenharmony_ci 187662306a36Sopenharmony_ci return count; 187762306a36Sopenharmony_ci} 187862306a36Sopenharmony_ci 187962306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, 188062306a36Sopenharmony_ci char __user *user_buf, 188162306a36Sopenharmony_ci size_t count, loff_t *ppos) { 188262306a36Sopenharmony_ci 188362306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 188462306a36Sopenharmony_ci int len = 0; 188562306a36Sopenharmony_ci char buf[20]; 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ci len = sprintf(buf, "0x%04X\n", 188862306a36Sopenharmony_ci le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags)); 188962306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, len); 189062306a36Sopenharmony_ci} 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, 189362306a36Sopenharmony_ci char __user *user_buf, 189462306a36Sopenharmony_ci size_t count, loff_t *ppos) { 189562306a36Sopenharmony_ci 189662306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 189762306a36Sopenharmony_ci int len = 0; 189862306a36Sopenharmony_ci char buf[20]; 189962306a36Sopenharmony_ci 190062306a36Sopenharmony_ci len = sprintf(buf, "0x%04X\n", 190162306a36Sopenharmony_ci le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags)); 190262306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, len); 190362306a36Sopenharmony_ci} 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_missed_beacon_read(struct file *file, 190662306a36Sopenharmony_ci char __user *user_buf, 190762306a36Sopenharmony_ci size_t count, loff_t *ppos) { 190862306a36Sopenharmony_ci 190962306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 191062306a36Sopenharmony_ci int pos = 0; 191162306a36Sopenharmony_ci char buf[12]; 191262306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 191362306a36Sopenharmony_ci 191462306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%d\n", 191562306a36Sopenharmony_ci priv->missed_beacon_threshold); 191662306a36Sopenharmony_ci 191762306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 191862306a36Sopenharmony_ci} 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, 192162306a36Sopenharmony_ci const char __user *user_buf, 192262306a36Sopenharmony_ci size_t count, loff_t *ppos) 192362306a36Sopenharmony_ci{ 192462306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 192562306a36Sopenharmony_ci char buf[8]; 192662306a36Sopenharmony_ci int buf_size; 192762306a36Sopenharmony_ci int missed; 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 193062306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 193162306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 193262306a36Sopenharmony_ci return -EFAULT; 193362306a36Sopenharmony_ci if (sscanf(buf, "%d", &missed) != 1) 193462306a36Sopenharmony_ci return -EINVAL; 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN || 193762306a36Sopenharmony_ci missed > IWL_MISSED_BEACON_THRESHOLD_MAX) 193862306a36Sopenharmony_ci priv->missed_beacon_threshold = 193962306a36Sopenharmony_ci IWL_MISSED_BEACON_THRESHOLD_DEF; 194062306a36Sopenharmony_ci else 194162306a36Sopenharmony_ci priv->missed_beacon_threshold = missed; 194262306a36Sopenharmony_ci 194362306a36Sopenharmony_ci return count; 194462306a36Sopenharmony_ci} 194562306a36Sopenharmony_ci 194662306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, 194762306a36Sopenharmony_ci char __user *user_buf, 194862306a36Sopenharmony_ci size_t count, loff_t *ppos) { 194962306a36Sopenharmony_ci 195062306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 195162306a36Sopenharmony_ci int pos = 0; 195262306a36Sopenharmony_ci char buf[12]; 195362306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 195462306a36Sopenharmony_ci 195562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "%u\n", 195662306a36Sopenharmony_ci priv->plcp_delta_threshold); 195762306a36Sopenharmony_ci 195862306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 195962306a36Sopenharmony_ci} 196062306a36Sopenharmony_ci 196162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, 196262306a36Sopenharmony_ci const char __user *user_buf, 196362306a36Sopenharmony_ci size_t count, loff_t *ppos) { 196462306a36Sopenharmony_ci 196562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 196662306a36Sopenharmony_ci char buf[8]; 196762306a36Sopenharmony_ci int buf_size; 196862306a36Sopenharmony_ci int plcp; 196962306a36Sopenharmony_ci 197062306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 197162306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 197262306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 197362306a36Sopenharmony_ci return -EFAULT; 197462306a36Sopenharmony_ci if (sscanf(buf, "%d", &plcp) != 1) 197562306a36Sopenharmony_ci return -EINVAL; 197662306a36Sopenharmony_ci if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || 197762306a36Sopenharmony_ci (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) 197862306a36Sopenharmony_ci priv->plcp_delta_threshold = 197962306a36Sopenharmony_ci IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; 198062306a36Sopenharmony_ci else 198162306a36Sopenharmony_ci priv->plcp_delta_threshold = plcp; 198262306a36Sopenharmony_ci return count; 198362306a36Sopenharmony_ci} 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_rf_reset_read(struct file *file, 198662306a36Sopenharmony_ci char __user *user_buf, 198762306a36Sopenharmony_ci size_t count, loff_t *ppos) 198862306a36Sopenharmony_ci{ 198962306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 199062306a36Sopenharmony_ci int pos = 0; 199162306a36Sopenharmony_ci char buf[300]; 199262306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 199362306a36Sopenharmony_ci struct iwl_rf_reset *rf_reset = &priv->rf_reset; 199462306a36Sopenharmony_ci 199562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 199662306a36Sopenharmony_ci "RF reset statistics\n"); 199762306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 199862306a36Sopenharmony_ci "\tnumber of reset request: %d\n", 199962306a36Sopenharmony_ci rf_reset->reset_request_count); 200062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 200162306a36Sopenharmony_ci "\tnumber of reset request success: %d\n", 200262306a36Sopenharmony_ci rf_reset->reset_success_count); 200362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 200462306a36Sopenharmony_ci "\tnumber of reset request reject: %d\n", 200562306a36Sopenharmony_ci rf_reset->reset_reject_count); 200662306a36Sopenharmony_ci 200762306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 200862306a36Sopenharmony_ci} 200962306a36Sopenharmony_ci 201062306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_rf_reset_write(struct file *file, 201162306a36Sopenharmony_ci const char __user *user_buf, 201262306a36Sopenharmony_ci size_t count, loff_t *ppos) { 201362306a36Sopenharmony_ci 201462306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 201562306a36Sopenharmony_ci int ret; 201662306a36Sopenharmony_ci 201762306a36Sopenharmony_ci ret = iwl_force_rf_reset(priv, true); 201862306a36Sopenharmony_ci return ret ? ret : count; 201962306a36Sopenharmony_ci} 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, 202262306a36Sopenharmony_ci const char __user *user_buf, 202362306a36Sopenharmony_ci size_t count, loff_t *ppos) { 202462306a36Sopenharmony_ci 202562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 202662306a36Sopenharmony_ci char buf[8]; 202762306a36Sopenharmony_ci int buf_size; 202862306a36Sopenharmony_ci int flush; 202962306a36Sopenharmony_ci 203062306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 203162306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 203262306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 203362306a36Sopenharmony_ci return -EFAULT; 203462306a36Sopenharmony_ci if (sscanf(buf, "%d", &flush) != 1) 203562306a36Sopenharmony_ci return -EINVAL; 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci if (iwl_is_rfkill(priv)) 203862306a36Sopenharmony_ci return -EFAULT; 203962306a36Sopenharmony_ci 204062306a36Sopenharmony_ci iwlagn_dev_txfifo_flush(priv); 204162306a36Sopenharmony_ci 204262306a36Sopenharmony_ci return count; 204362306a36Sopenharmony_ci} 204462306a36Sopenharmony_ci 204562306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, 204662306a36Sopenharmony_ci char __user *user_buf, 204762306a36Sopenharmony_ci size_t count, loff_t *ppos) { 204862306a36Sopenharmony_ci 204962306a36Sopenharmony_ci struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 205062306a36Sopenharmony_ci int pos = 0; 205162306a36Sopenharmony_ci char buf[200]; 205262306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ci if (!priv->bt_enable_flag) { 205562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n"); 205662306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 205762306a36Sopenharmony_ci } 205862306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n", 205962306a36Sopenharmony_ci priv->bt_enable_flag); 206062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n", 206162306a36Sopenharmony_ci priv->bt_full_concurrent ? "full concurrency" : "3-wire"); 206262306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " 206362306a36Sopenharmony_ci "last traffic notif: %d\n", 206462306a36Sopenharmony_ci priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load); 206562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " 206662306a36Sopenharmony_ci "kill_ack_mask: %x, kill_cts_mask: %x\n", 206762306a36Sopenharmony_ci priv->bt_ch_announce, priv->kill_ack_mask, 206862306a36Sopenharmony_ci priv->kill_cts_mask); 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: "); 207162306a36Sopenharmony_ci switch (priv->bt_traffic_load) { 207262306a36Sopenharmony_ci case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 207362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n"); 207462306a36Sopenharmony_ci break; 207562306a36Sopenharmony_ci case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: 207662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "High\n"); 207762306a36Sopenharmony_ci break; 207862306a36Sopenharmony_ci case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 207962306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "Low\n"); 208062306a36Sopenharmony_ci break; 208162306a36Sopenharmony_ci case IWL_BT_COEX_TRAFFIC_LOAD_NONE: 208262306a36Sopenharmony_ci default: 208362306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "None\n"); 208462306a36Sopenharmony_ci break; 208562306a36Sopenharmony_ci } 208662306a36Sopenharmony_ci 208762306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 208862306a36Sopenharmony_ci} 208962306a36Sopenharmony_ci 209062306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_protection_mode_read(struct file *file, 209162306a36Sopenharmony_ci char __user *user_buf, 209262306a36Sopenharmony_ci size_t count, loff_t *ppos) 209362306a36Sopenharmony_ci{ 209462306a36Sopenharmony_ci struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_ci int pos = 0; 209762306a36Sopenharmony_ci char buf[40]; 209862306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 209962306a36Sopenharmony_ci 210062306a36Sopenharmony_ci if (priv->cfg->ht_params) 210162306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 210262306a36Sopenharmony_ci "use %s for aggregation\n", 210362306a36Sopenharmony_ci (priv->hw_params.use_rts_for_aggregation) ? 210462306a36Sopenharmony_ci "rts/cts" : "cts-to-self"); 210562306a36Sopenharmony_ci else 210662306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, "N/A"); 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 210962306a36Sopenharmony_ci} 211062306a36Sopenharmony_ci 211162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_protection_mode_write(struct file *file, 211262306a36Sopenharmony_ci const char __user *user_buf, 211362306a36Sopenharmony_ci size_t count, loff_t *ppos) { 211462306a36Sopenharmony_ci 211562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 211662306a36Sopenharmony_ci char buf[8]; 211762306a36Sopenharmony_ci int buf_size; 211862306a36Sopenharmony_ci int rts; 211962306a36Sopenharmony_ci 212062306a36Sopenharmony_ci if (!priv->cfg->ht_params) 212162306a36Sopenharmony_ci return -EINVAL; 212262306a36Sopenharmony_ci 212362306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 212462306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 212562306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 212662306a36Sopenharmony_ci return -EFAULT; 212762306a36Sopenharmony_ci if (sscanf(buf, "%d", &rts) != 1) 212862306a36Sopenharmony_ci return -EINVAL; 212962306a36Sopenharmony_ci if (rts) 213062306a36Sopenharmony_ci priv->hw_params.use_rts_for_aggregation = true; 213162306a36Sopenharmony_ci else 213262306a36Sopenharmony_ci priv->hw_params.use_rts_for_aggregation = false; 213362306a36Sopenharmony_ci return count; 213462306a36Sopenharmony_ci} 213562306a36Sopenharmony_ci 213662306a36Sopenharmony_cistatic int iwl_cmd_echo_test(struct iwl_priv *priv) 213762306a36Sopenharmony_ci{ 213862306a36Sopenharmony_ci int ret; 213962306a36Sopenharmony_ci struct iwl_host_cmd cmd = { 214062306a36Sopenharmony_ci .id = REPLY_ECHO, 214162306a36Sopenharmony_ci .len = { 0 }, 214262306a36Sopenharmony_ci }; 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_ci ret = iwl_dvm_send_cmd(priv, &cmd); 214562306a36Sopenharmony_ci if (ret) 214662306a36Sopenharmony_ci IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); 214762306a36Sopenharmony_ci else 214862306a36Sopenharmony_ci IWL_DEBUG_INFO(priv, "echo testing pass\n"); 214962306a36Sopenharmony_ci return ret; 215062306a36Sopenharmony_ci} 215162306a36Sopenharmony_ci 215262306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_echo_test_write(struct file *file, 215362306a36Sopenharmony_ci const char __user *user_buf, 215462306a36Sopenharmony_ci size_t count, loff_t *ppos) 215562306a36Sopenharmony_ci{ 215662306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 215762306a36Sopenharmony_ci char buf[8]; 215862306a36Sopenharmony_ci int buf_size; 215962306a36Sopenharmony_ci 216062306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 216162306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 216262306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 216362306a36Sopenharmony_ci return -EFAULT; 216462306a36Sopenharmony_ci 216562306a36Sopenharmony_ci iwl_cmd_echo_test(priv); 216662306a36Sopenharmony_ci return count; 216762306a36Sopenharmony_ci} 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_ci#ifdef CONFIG_IWLWIFI_DEBUG 217062306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_log_event_read(struct file *file, 217162306a36Sopenharmony_ci char __user *user_buf, 217262306a36Sopenharmony_ci size_t count, loff_t *ppos) 217362306a36Sopenharmony_ci{ 217462306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 217562306a36Sopenharmony_ci char *buf = NULL; 217662306a36Sopenharmony_ci ssize_t ret; 217762306a36Sopenharmony_ci 217862306a36Sopenharmony_ci ret = iwl_dump_nic_event_log(priv, true, &buf); 217962306a36Sopenharmony_ci if (ret > 0) 218062306a36Sopenharmony_ci ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); 218162306a36Sopenharmony_ci kfree(buf); 218262306a36Sopenharmony_ci return ret; 218362306a36Sopenharmony_ci} 218462306a36Sopenharmony_ci 218562306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_log_event_write(struct file *file, 218662306a36Sopenharmony_ci const char __user *user_buf, 218762306a36Sopenharmony_ci size_t count, loff_t *ppos) 218862306a36Sopenharmony_ci{ 218962306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 219062306a36Sopenharmony_ci u32 event_log_flag; 219162306a36Sopenharmony_ci char buf[8]; 219262306a36Sopenharmony_ci int buf_size; 219362306a36Sopenharmony_ci 219462306a36Sopenharmony_ci /* check that the interface is up */ 219562306a36Sopenharmony_ci if (!iwl_is_ready(priv)) 219662306a36Sopenharmony_ci return -EAGAIN; 219762306a36Sopenharmony_ci 219862306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 219962306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 220062306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 220162306a36Sopenharmony_ci return -EFAULT; 220262306a36Sopenharmony_ci if (sscanf(buf, "%u", &event_log_flag) != 1) 220362306a36Sopenharmony_ci return -EFAULT; 220462306a36Sopenharmony_ci if (event_log_flag == 1) 220562306a36Sopenharmony_ci iwl_dump_nic_event_log(priv, true, NULL); 220662306a36Sopenharmony_ci 220762306a36Sopenharmony_ci return count; 220862306a36Sopenharmony_ci} 220962306a36Sopenharmony_ci#endif 221062306a36Sopenharmony_ci 221162306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, 221262306a36Sopenharmony_ci char __user *user_buf, 221362306a36Sopenharmony_ci size_t count, loff_t *ppos) 221462306a36Sopenharmony_ci{ 221562306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 221662306a36Sopenharmony_ci char buf[120]; 221762306a36Sopenharmony_ci int pos = 0; 221862306a36Sopenharmony_ci const size_t bufsz = sizeof(buf); 221962306a36Sopenharmony_ci 222062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 222162306a36Sopenharmony_ci "Sensitivity calibrations %s\n", 222262306a36Sopenharmony_ci (priv->calib_disabled & 222362306a36Sopenharmony_ci IWL_SENSITIVITY_CALIB_DISABLED) ? 222462306a36Sopenharmony_ci "DISABLED" : "ENABLED"); 222562306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 222662306a36Sopenharmony_ci "Chain noise calibrations %s\n", 222762306a36Sopenharmony_ci (priv->calib_disabled & 222862306a36Sopenharmony_ci IWL_CHAIN_NOISE_CALIB_DISABLED) ? 222962306a36Sopenharmony_ci "DISABLED" : "ENABLED"); 223062306a36Sopenharmony_ci pos += scnprintf(buf + pos, bufsz - pos, 223162306a36Sopenharmony_ci "Tx power calibrations %s\n", 223262306a36Sopenharmony_ci (priv->calib_disabled & 223362306a36Sopenharmony_ci IWL_TX_POWER_CALIB_DISABLED) ? 223462306a36Sopenharmony_ci "DISABLED" : "ENABLED"); 223562306a36Sopenharmony_ci 223662306a36Sopenharmony_ci return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 223762306a36Sopenharmony_ci} 223862306a36Sopenharmony_ci 223962306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_calib_disabled_write(struct file *file, 224062306a36Sopenharmony_ci const char __user *user_buf, 224162306a36Sopenharmony_ci size_t count, loff_t *ppos) 224262306a36Sopenharmony_ci{ 224362306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 224462306a36Sopenharmony_ci char buf[8]; 224562306a36Sopenharmony_ci u32 calib_disabled; 224662306a36Sopenharmony_ci int buf_size; 224762306a36Sopenharmony_ci 224862306a36Sopenharmony_ci memset(buf, 0, sizeof(buf)); 224962306a36Sopenharmony_ci buf_size = min(count, sizeof(buf) - 1); 225062306a36Sopenharmony_ci if (copy_from_user(buf, user_buf, buf_size)) 225162306a36Sopenharmony_ci return -EFAULT; 225262306a36Sopenharmony_ci if (sscanf(buf, "%x", &calib_disabled) != 1) 225362306a36Sopenharmony_ci return -EFAULT; 225462306a36Sopenharmony_ci 225562306a36Sopenharmony_ci priv->calib_disabled = calib_disabled; 225662306a36Sopenharmony_ci 225762306a36Sopenharmony_ci return count; 225862306a36Sopenharmony_ci} 225962306a36Sopenharmony_ci 226062306a36Sopenharmony_cistatic ssize_t iwl_dbgfs_fw_restart_write(struct file *file, 226162306a36Sopenharmony_ci const char __user *user_buf, 226262306a36Sopenharmony_ci size_t count, loff_t *ppos) 226362306a36Sopenharmony_ci{ 226462306a36Sopenharmony_ci struct iwl_priv *priv = file->private_data; 226562306a36Sopenharmony_ci bool fw_restart = iwlwifi_mod_params.fw_restart; 226662306a36Sopenharmony_ci int __maybe_unused ret; 226762306a36Sopenharmony_ci 226862306a36Sopenharmony_ci iwlwifi_mod_params.fw_restart = true; 226962306a36Sopenharmony_ci 227062306a36Sopenharmony_ci mutex_lock(&priv->mutex); 227162306a36Sopenharmony_ci 227262306a36Sopenharmony_ci /* take the return value to make compiler happy - it will fail anyway */ 227362306a36Sopenharmony_ci ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, 0, 0, NULL); 227462306a36Sopenharmony_ci 227562306a36Sopenharmony_ci mutex_unlock(&priv->mutex); 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_ci iwlwifi_mod_params.fw_restart = fw_restart; 227862306a36Sopenharmony_ci 227962306a36Sopenharmony_ci return count; 228062306a36Sopenharmony_ci} 228162306a36Sopenharmony_ci 228262306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(ucode_rx_stats); 228362306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(ucode_tx_stats); 228462306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(ucode_general_stats); 228562306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(sensitivity); 228662306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(chain_noise); 228762306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(power_save_status); 228862306a36Sopenharmony_ciDEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 228962306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 229062306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 229162306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); 229262306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(rf_reset); 229362306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(rxon_flags); 229462306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(rxon_filter_flags); 229562306a36Sopenharmony_ciDEBUGFS_WRITE_FILE_OPS(txfifo_flush); 229662306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(ucode_bt_stats); 229762306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(bt_traffic); 229862306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(protection_mode); 229962306a36Sopenharmony_ciDEBUGFS_READ_FILE_OPS(reply_tx_error); 230062306a36Sopenharmony_ciDEBUGFS_WRITE_FILE_OPS(echo_test); 230162306a36Sopenharmony_ciDEBUGFS_WRITE_FILE_OPS(fw_restart); 230262306a36Sopenharmony_ci#ifdef CONFIG_IWLWIFI_DEBUG 230362306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(log_event); 230462306a36Sopenharmony_ci#endif 230562306a36Sopenharmony_ciDEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); 230662306a36Sopenharmony_ci 230762306a36Sopenharmony_ci/* 230862306a36Sopenharmony_ci * Create the debugfs files and directories 230962306a36Sopenharmony_ci * 231062306a36Sopenharmony_ci */ 231162306a36Sopenharmony_civoid iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) 231262306a36Sopenharmony_ci{ 231362306a36Sopenharmony_ci struct dentry *dir_data, *dir_rf, *dir_debug; 231462306a36Sopenharmony_ci 231562306a36Sopenharmony_ci priv->debugfs_dir = dbgfs_dir; 231662306a36Sopenharmony_ci 231762306a36Sopenharmony_ci dir_data = debugfs_create_dir("data", dbgfs_dir); 231862306a36Sopenharmony_ci dir_rf = debugfs_create_dir("rf", dbgfs_dir); 231962306a36Sopenharmony_ci dir_debug = debugfs_create_dir("debug", dbgfs_dir); 232062306a36Sopenharmony_ci 232162306a36Sopenharmony_ci DEBUGFS_ADD_FILE(nvm, dir_data, 0400); 232262306a36Sopenharmony_ci DEBUGFS_ADD_FILE(sram, dir_data, 0600); 232362306a36Sopenharmony_ci DEBUGFS_ADD_FILE(wowlan_sram, dir_data, 0400); 232462306a36Sopenharmony_ci DEBUGFS_ADD_FILE(stations, dir_data, 0400); 232562306a36Sopenharmony_ci DEBUGFS_ADD_FILE(channels, dir_data, 0400); 232662306a36Sopenharmony_ci DEBUGFS_ADD_FILE(status, dir_data, 0400); 232762306a36Sopenharmony_ci DEBUGFS_ADD_FILE(rx_handlers, dir_data, 0600); 232862306a36Sopenharmony_ci DEBUGFS_ADD_FILE(qos, dir_data, 0400); 232962306a36Sopenharmony_ci DEBUGFS_ADD_FILE(sleep_level_override, dir_data, 0600); 233062306a36Sopenharmony_ci DEBUGFS_ADD_FILE(current_sleep_command, dir_data, 0400); 233162306a36Sopenharmony_ci DEBUGFS_ADD_FILE(thermal_throttling, dir_data, 0400); 233262306a36Sopenharmony_ci DEBUGFS_ADD_FILE(disable_ht40, dir_data, 0600); 233362306a36Sopenharmony_ci DEBUGFS_ADD_FILE(temperature, dir_data, 0400); 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci DEBUGFS_ADD_FILE(power_save_status, dir_debug, 0400); 233662306a36Sopenharmony_ci DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, 0200); 233762306a36Sopenharmony_ci DEBUGFS_ADD_FILE(missed_beacon, dir_debug, 0200); 233862306a36Sopenharmony_ci DEBUGFS_ADD_FILE(plcp_delta, dir_debug, 0600); 233962306a36Sopenharmony_ci DEBUGFS_ADD_FILE(rf_reset, dir_debug, 0600); 234062306a36Sopenharmony_ci DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, 0400); 234162306a36Sopenharmony_ci DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, 0400); 234262306a36Sopenharmony_ci DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, 0400); 234362306a36Sopenharmony_ci DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, 0200); 234462306a36Sopenharmony_ci DEBUGFS_ADD_FILE(protection_mode, dir_debug, 0600); 234562306a36Sopenharmony_ci DEBUGFS_ADD_FILE(sensitivity, dir_debug, 0400); 234662306a36Sopenharmony_ci DEBUGFS_ADD_FILE(chain_noise, dir_debug, 0400); 234762306a36Sopenharmony_ci DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, 0600); 234862306a36Sopenharmony_ci DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, 0400); 234962306a36Sopenharmony_ci DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, 0400); 235062306a36Sopenharmony_ci DEBUGFS_ADD_FILE(rxon_flags, dir_debug, 0200); 235162306a36Sopenharmony_ci DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, 0200); 235262306a36Sopenharmony_ci DEBUGFS_ADD_FILE(echo_test, dir_debug, 0200); 235362306a36Sopenharmony_ci DEBUGFS_ADD_FILE(fw_restart, dir_debug, 0200); 235462306a36Sopenharmony_ci#ifdef CONFIG_IWLWIFI_DEBUG 235562306a36Sopenharmony_ci DEBUGFS_ADD_FILE(log_event, dir_debug, 0600); 235662306a36Sopenharmony_ci#endif 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci if (iwl_advanced_bt_coexist(priv)) 235962306a36Sopenharmony_ci DEBUGFS_ADD_FILE(bt_traffic, dir_debug, 0400); 236062306a36Sopenharmony_ci 236162306a36Sopenharmony_ci /* Calibrations disabled/enabled status*/ 236262306a36Sopenharmony_ci DEBUGFS_ADD_FILE(calib_disabled, dir_rf, 0600); 236362306a36Sopenharmony_ci 236462306a36Sopenharmony_ci /* 236562306a36Sopenharmony_ci * Create a symlink with mac80211. This is not very robust, as it does 236662306a36Sopenharmony_ci * not remove the symlink created. The implicit assumption is that 236762306a36Sopenharmony_ci * when the opmode exits, mac80211 will also exit, and will remove 236862306a36Sopenharmony_ci * this symlink as part of its cleanup. 236962306a36Sopenharmony_ci */ 237062306a36Sopenharmony_ci if (priv->mac80211_registered) { 237162306a36Sopenharmony_ci char buf[100]; 237262306a36Sopenharmony_ci struct dentry *mac80211_dir, *dev_dir; 237362306a36Sopenharmony_ci 237462306a36Sopenharmony_ci dev_dir = dbgfs_dir->d_parent; 237562306a36Sopenharmony_ci mac80211_dir = priv->hw->wiphy->debugfsdir; 237662306a36Sopenharmony_ci 237762306a36Sopenharmony_ci snprintf(buf, 100, "../../%pd2", dev_dir); 237862306a36Sopenharmony_ci 237962306a36Sopenharmony_ci debugfs_create_symlink("iwlwifi", mac80211_dir, buf); 238062306a36Sopenharmony_ci } 238162306a36Sopenharmony_ci} 2382