Skip to content

Commit

Permalink
iwlagn: move isr_statistics to transport layer
Browse files Browse the repository at this point in the history
It is accessed by the transport layer only, hence the move.
The debugfs handlers that accessed it moved to the transport layer too.
The rx_handlers part of it stayed in the upper layer and a special debugfs
has been added for it

Also add missing includes to iwl-commands.h.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Emmanuel Grumbach authored and John W. Linville committed Aug 29, 2011
1 parent e4ef84d commit 1f7b617
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 83 deletions.
3 changes: 3 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
#ifndef __iwl_commands_h__
#define __iwl_commands_h__

#include <linux/etherdevice.h>
#include <linux/ieee80211.h>

struct iwl_priv;

/* uCode version contains 4 values: Major/Minor/API/Serial */
Expand Down
5 changes: 0 additions & 5 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1121,11 +1121,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
&statistics_cmd);
}

void iwl_clear_isr_stats(struct iwl_priv *priv)
{
memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
}

int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,6 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
}
#endif

void iwl_clear_isr_stats(struct iwl_priv *priv);

/*****************************************************
* GEOS
******************************************************/
Expand Down
54 changes: 10 additions & 44 deletions drivers/net/wireless/iwlwifi/iwl-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,11 +556,12 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}

static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
static ssize_t iwl_dbgfs_rx_handlers_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos) {

struct iwl_priv *priv = file->private_data;

int pos = 0;
int cnt = 0;
char *buf;
Expand All @@ -573,61 +574,25 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
return -ENOMEM;
}

pos += scnprintf(buf + pos, bufsz - pos,
"Interrupt Statistics Report:\n");

pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
priv->isr_stats.hw);
pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
priv->isr_stats.sw);
if (priv->isr_stats.sw || priv->isr_stats.hw) {
pos += scnprintf(buf + pos, bufsz - pos,
"\tLast Restarting Code: 0x%X\n",
priv->isr_stats.err_code);
}
#ifdef CONFIG_IWLWIFI_DEBUG
pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
priv->isr_stats.sch);
pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
priv->isr_stats.alive);
#endif
pos += scnprintf(buf + pos, bufsz - pos,
"HW RF KILL switch toggled:\t %u\n",
priv->isr_stats.rfkill);

pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
priv->isr_stats.ctkill);

pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
priv->isr_stats.wakeup);

pos += scnprintf(buf + pos, bufsz - pos,
"Rx command responses:\t\t %u\n",
priv->isr_stats.rx);
for (cnt = 0; cnt < REPLY_MAX; cnt++) {
if (priv->isr_stats.rx_handlers[cnt] > 0)
if (priv->rx_handlers_stats[cnt] > 0)
pos += scnprintf(buf + pos, bufsz - pos,
"\tRx handler[%36s]:\t\t %u\n",
get_cmd_string(cnt),
priv->isr_stats.rx_handlers[cnt]);
priv->rx_handlers_stats[cnt]);
}

pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
priv->isr_stats.tx);

pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
priv->isr_stats.unhandled);

ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
}

static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
static ssize_t iwl_dbgfs_rx_handlers_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;
u32 reset_flag;
Expand All @@ -639,7 +604,8 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
if (sscanf(buf, "%x", &reset_flag) != 1)
return -EFAULT;
if (reset_flag == 0)
iwl_clear_isr_stats(priv);
memset(&priv->rx_handlers_stats[0], 0,
sizeof(priv->rx_handlers_stats));

return count;
}
Expand Down Expand Up @@ -834,7 +800,7 @@ DEBUGFS_READ_FILE_OPS(nvm);
DEBUGFS_READ_FILE_OPS(stations);
DEBUGFS_READ_FILE_OPS(channels);
DEBUGFS_READ_FILE_OPS(status);
DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
DEBUGFS_READ_WRITE_FILE_OPS(rx_handlers);
DEBUGFS_READ_FILE_OPS(qos);
DEBUGFS_READ_FILE_OPS(thermal_throttling);
DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
Expand Down Expand Up @@ -2471,7 +2437,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_handlers, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
Expand Down
23 changes: 3 additions & 20 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -810,22 +810,6 @@ enum iwl_pa_type {
IWL_PA_INTERNAL = 1,
};

/* interrupt statistics */
struct isr_statistics {
u32 hw;
u32 sw;
u32 err_code;
u32 sch;
u32 alive;
u32 rfkill;
u32 ctkill;
u32 wakeup;
u32 rx;
u32 rx_handlers[REPLY_MAX];
u32 tx;
u32 unhandled;
};

/* reply_tx_statistics (for _agn devices) */
struct reply_tx_error_statistics {
u32 pp_delay;
Expand Down Expand Up @@ -1155,6 +1139,9 @@ struct iwl_priv {
/* jiffies when last recovery from statistics was performed */
unsigned long rx_statistics_jiffies;

/*counters */
u32 rx_handlers_stats[REPLY_MAX];

/* force reset */
struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];

Expand Down Expand Up @@ -1258,10 +1245,6 @@ struct iwl_priv {
struct traffic_stats tx_stats;
struct traffic_stats rx_stats;

/* counts interrupts */
/* TODO: move to the transport layer */
struct isr_statistics isr_stats;

struct iwl_power_mgr power_data;
struct iwl_tt_mgmt thermal_throttle;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
* handle those that need handling via function in
* rx_handlers table. See iwl_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
priv->rx_handlers_stats[pkt->hdr.cmd]++;
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
} else {
/* No handling needed */
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,24 @@
/*This file includes the declaration that are internal to the
* trans_pcie layer */

/**
* struct isr_statistics - interrupt statistics
*
*/
struct isr_statistics {
u32 hw;
u32 sw;
u32 err_code;
u32 sch;
u32 alive;
u32 rfkill;
u32 ctkill;
u32 wakeup;
u32 rx;
u32 tx;
u32 unhandled;
};

/**
* struct iwl_rx_queue - Rx queue
* @bd: driver's pointer to buffer of receive buffer descriptors (rbd)
Expand Down Expand Up @@ -88,6 +106,7 @@ struct iwl_trans_pcie {
u32 inta;
bool use_ict;
struct tasklet_struct irq_tasklet;
struct isr_statistics isr_stats;

u32 inta_mask;
};
Expand Down
27 changes: 16 additions & 11 deletions drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
{
u32 base;
struct iwl_error_event_table table;
struct iwl_trans *trans = trans(priv);
struct iwl_trans_pcie *trans_pcie =
IWL_TRANS_GET_PCIE_TRANS(trans);

base = priv->device_pointers.error_event_table;
if (priv->ucode_type == IWL_UCODE_INIT) {
Expand Down Expand Up @@ -596,7 +599,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
priv->shrd->status, table.valid);
}

priv->isr_stats.err_code = table.error_id;
trans_pcie->isr_stats.err_code = table.error_id;

trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low,
table.data1, table.data2, table.line,
Expand Down Expand Up @@ -905,6 +908,8 @@ void iwl_irq_tasklet(struct iwl_trans *trans)

struct iwl_trans_pcie *trans_pcie =
IWL_TRANS_GET_PCIE_TRANS(trans);
struct isr_statistics *isr_stats = &trans_pcie->isr_stats;


spin_lock_irqsave(&trans->shrd->lock, flags);

Expand Down Expand Up @@ -945,7 +950,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(trans);

priv(trans)->isr_stats.hw++;
isr_stats->hw++;
iwl_irq_handle_error(priv(trans));

handled |= CSR_INT_BIT_HW_ERR;
Expand All @@ -959,13 +964,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
if (inta & CSR_INT_BIT_SCD) {
IWL_DEBUG_ISR(trans, "Scheduler finished to transmit "
"the frame/frames.\n");
priv(trans)->isr_stats.sch++;
isr_stats->sch++;
}

/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(trans, "Alive interrupt\n");
priv(trans)->isr_stats.alive++;
isr_stats->alive++;
}
}
#endif
Expand All @@ -982,7 +987,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
hw_rf_kill ? "disable radio" : "enable radio");

priv(trans)->isr_stats.rfkill++;
isr_stats->rfkill++;

/* driver only loads ucode once setting the interface up.
* the driver allows loading the ucode even if the radio
Expand All @@ -1006,15 +1011,15 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
/* Chip got too hot and stopped itself */
if (inta & CSR_INT_BIT_CT_KILL) {
IWL_ERR(trans, "Microcode CT kill error detected.\n");
priv(trans)->isr_stats.ctkill++;
isr_stats->ctkill++;
handled |= CSR_INT_BIT_CT_KILL;
}

/* Error detected by uCode */
if (inta & CSR_INT_BIT_SW_ERR) {
IWL_ERR(trans, "Microcode SW error detected. "
" Restarting 0x%X.\n", inta);
priv(trans)->isr_stats.sw++;
isr_stats->sw++;
iwl_irq_handle_error(priv(trans));
handled |= CSR_INT_BIT_SW_ERR;
}
Expand All @@ -1027,7 +1032,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
iwl_txq_update_write_ptr(priv(trans),
&priv(trans)->txq[i]);

priv(trans)->isr_stats.wakeup++;
isr_stats->wakeup++;

handled |= CSR_INT_BIT_WAKEUP;
}
Expand Down Expand Up @@ -1075,14 +1080,14 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
iwl_write8(priv(trans), CSR_INT_PERIODIC_REG,
CSR_INT_PERIODIC_ENA);

priv(trans)->isr_stats.rx++;
isr_stats->rx++;
}

/* This "Tx" DMA channel is used only for loading uCode */
if (inta & CSR_INT_BIT_FH_TX) {
iwl_write32(priv(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
IWL_DEBUG_ISR(trans, "uCode load interrupt\n");
priv(trans)->isr_stats.tx++;
isr_stats->tx++;
handled |= CSR_INT_BIT_FH_TX;
/* Wake up uCode load routine, now that load is complete */
priv(trans)->ucode_write_complete = 1;
Expand All @@ -1091,7 +1096,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)

if (inta & ~handled) {
IWL_ERR(trans, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
priv(trans)->isr_stats.unhandled++;
isr_stats->unhandled++;
}

if (inta & ~(trans_pcie->inta_mask)) {
Expand Down
Loading

0 comments on commit 1f7b617

Please sign in to comment.