Skip to content

Commit

Permalink
iwlwifi: update reply_statistics_cmd with 'clear' parameter
Browse files Browse the repository at this point in the history
When issue REPLY_STATISTICS_CMD to uCode, two possible flag
can be set in the configuration flags

bit 0: Clear statistics
       0: Do not clear Statistics counters
       1: Clear to zero Statistics counters

Allow "clear" parameter to be set from the caller.

Add debugfs file to clear the statistics counters to help monitor and
debug the uCode behavior.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Wey-Yi Guy authored and John W. Linville committed Nov 18, 2009
1 parent 7d2ed11 commit ef8d552
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 23 deletions.
6 changes: 3 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ static void iwl_bg_statistics_periodic(unsigned long data)
if (!iwl_is_ready_rf(priv))
return;

iwl_send_statistics_request(priv, CMD_ASYNC);
iwl_send_statistics_request(priv, CMD_ASYNC, false);
}

static void iwl_rx_beacon_notif(struct iwl_priv *priv,
Expand Down Expand Up @@ -729,7 +729,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
* statistics request from the host as well as for the periodic
* statistics notifications (after received beacons) from the uCode.
*/
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;

iwl_setup_spectrum_handlers(priv);
Expand Down Expand Up @@ -2892,7 +2892,7 @@ static ssize_t show_statistics(struct device *d,
return -EAGAIN;

mutex_lock(&priv->mutex);
rc = iwl_send_statistics_request(priv, 0);
rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
mutex_unlock(&priv->mutex);

if (rc) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-calib.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ void iwl_reset_run_time_calib(struct iwl_priv *priv)

/* Ask for statistics now, the uCode will send notification
* periodically after association */
iwl_send_statistics_request(priv, CMD_ASYNC);
iwl_send_statistics_request(priv, CMD_ASYNC, true);
}
EXPORT_SYMBOL(iwl_reset_run_time_calib);

4 changes: 4 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -3071,6 +3071,10 @@ struct statistics_general {
__le32 reserved3;
} __attribute__ ((packed));

#define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0)
#define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1)
#define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2)

/*
* REPLY_STATISTICS_CMD = 0x9c,
* 3945 and 4965 identical.
Expand Down
21 changes: 13 additions & 8 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1990,16 +1990,21 @@ int iwl_send_bt_config(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_send_bt_config);

int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
{
u32 stat_flags = 0;
struct iwl_host_cmd cmd = {
.id = REPLY_STATISTICS_CMD,
.flags = flags,
.len = sizeof(stat_flags),
.data = (u8 *) &stat_flags,
struct iwl_statistics_cmd statistics_cmd = {
.configuration_flags =
clear ? IWL_STATS_CONF_CLEAR_STATS : 0,
};
return iwl_send_cmd(priv, &cmd);

if (flags & CMD_ASYNC)
return iwl_send_cmd_pdu_async(priv, REPLY_STATISTICS_CMD,
sizeof(struct iwl_statistics_cmd),
&statistics_cmd, NULL);
else
return iwl_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
sizeof(struct iwl_statistics_cmd),
&statistics_cmd);
}
EXPORT_SYMBOL(iwl_send_statistics_request);

Expand Down
5 changes: 4 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);

/* TX helpers */
Expand Down Expand Up @@ -669,7 +671,8 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)

extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
extern int iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_send_statistics_request(struct iwl_priv *priv,
u8 flags, bool clear);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern int iwl_send_lq_cmd(struct iwl_priv *priv,
struct iwl_link_quality_cmd *lq, u8 flags);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ struct iwl_debugfs {
struct dentry *file_chain_noise;
struct dentry *file_tx_power;
struct dentry *file_power_save_status;
struct dentry *file_clear_statistics;
} dbgfs_debug_files;
u32 sram_offset;
u32 sram_len;
Expand Down
39 changes: 31 additions & 8 deletions drivers/net/wireless/iwlwifi/iwl-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,10 +1042,6 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}

#define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0)
#define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1)
#define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2)

static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
int bufsz)
{
Expand Down Expand Up @@ -1092,7 +1088,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,

/* make request to uCode to retrieve statistics information */
mutex_lock(&priv->mutex);
ret = iwl_send_statistics_request(priv, 0);
ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
mutex_unlock(&priv->mutex);

if (ret) {
Expand Down Expand Up @@ -1398,7 +1394,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,

/* make request to uCode to retrieve statistics information */
mutex_lock(&priv->mutex);
ret = iwl_send_statistics_request(priv, 0);
ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
mutex_unlock(&priv->mutex);

if (ret) {
Expand Down Expand Up @@ -1542,7 +1538,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,

/* make request to uCode to retrieve statistics information */
mutex_lock(&priv->mutex);
ret = iwl_send_statistics_request(priv, 0);
ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
mutex_unlock(&priv->mutex);

if (ret) {
Expand Down Expand Up @@ -1770,7 +1766,7 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
else {
/* make request to uCode to retrieve statistics information */
mutex_lock(&priv->mutex);
ret = iwl_send_statistics_request(priv, 0);
ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
mutex_unlock(&priv->mutex);

if (ret) {
Expand Down Expand Up @@ -1828,6 +1824,30 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}

static ssize_t iwl_dbgfs_clear_statistics_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
char buf[8];
int buf_size;
int clear;

memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%d", &clear) != 1)
return -EFAULT;

/* make request to uCode to retrieve statistics information */
mutex_lock(&priv->mutex);
iwl_send_statistics_request(priv, CMD_SYNC, true);
mutex_unlock(&priv->mutex);

return count;
}

DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
Expand All @@ -1840,6 +1860,7 @@ DEBUGFS_READ_FILE_OPS(sensitivity);
DEBUGFS_READ_FILE_OPS(chain_noise);
DEBUGFS_READ_FILE_OPS(tx_power);
DEBUGFS_READ_FILE_OPS(power_save_status);
DEBUGFS_WRITE_FILE_OPS(clear_statistics);

/*
* Create the debugfs files and directories
Expand Down Expand Up @@ -1888,6 +1909,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(tx_queue, debug);
DEBUGFS_ADD_FILE(tx_power, debug);
DEBUGFS_ADD_FILE(power_save_status, debug);
DEBUGFS_ADD_FILE(clear_statistics, debug);
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
DEBUGFS_ADD_FILE(ucode_rx_stats, debug);
DEBUGFS_ADD_FILE(ucode_tx_stats, debug);
Expand Down Expand Up @@ -1941,6 +1963,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_clear_statistics);
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
file_ucode_rx_stats);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-power.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
{
IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
/* make request to retrieve statistics information */
iwl_send_statistics_request(priv, 0);
iwl_send_statistics_request(priv, CMD_SYNC, false);
/* Reschedule the ct_kill wait timer */
mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
Expand Down
18 changes: 18 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,24 @@ void iwl_rx_statistics(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_rx_statistics);

void iwl_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);

if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
memset(&priv->statistics, 0,
sizeof(struct iwl_notif_statistics));
#ifdef CONFIG_IWLWIFI_DEBUG
memset(&priv->accum_statistics, 0,
sizeof(struct iwl_notif_statistics));
#endif
IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
}
iwl_rx_statistics(priv, rxb);
}
EXPORT_SYMBOL(iwl_reply_statistics);

#define PERFECT_RSSI (-20) /* dBm */
#define WORST_RSSI (-95) /* dBm */
#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -3649,7 +3649,7 @@ static ssize_t show_statistics(struct device *d,
return -EAGAIN;

mutex_lock(&priv->mutex);
rc = iwl_send_statistics_request(priv, 0);
rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
mutex_unlock(&priv->mutex);

if (rc) {
Expand Down

0 comments on commit ef8d552

Please sign in to comment.