iwlagn: move isr_statistics to transport layer
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Fri, 26 Aug 2011 06:10:59 +0000 (23:10 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 29 Aug 2011 19:25:34 +0000 (15:25 -0400)
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>
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h
drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans.c

index 0016c61..86b9748 100644 (file)
@@ -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 */
index 88fc396..347cbec 100644 (file)
@@ -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)
 {
index aa62118..110ffae 100644 (file)
@@ -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
 ******************************************************/
index fa070de..787dae5 100644 (file)
@@ -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;
@@ -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;
@@ -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;
 }
@@ -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);
@@ -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);
index 40a01c0..f3852ed 100644 (file)
@@ -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;
@@ -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];
 
@@ -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;
 
index a5e4dda..d7c7c93 100644 (file)
@@ -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 */
index 4694c46..f60b26f 100644 (file)
 /*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)
@@ -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;
 };
index aa7ced4..b1635ee 100644 (file)
@@ -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) {
@@ -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,
@@ -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);
 
@@ -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;
@@ -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
@@ -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
@@ -1006,7 +1011,7 @@ 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;
        }
 
@@ -1014,7 +1019,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        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;
        }
@@ -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;
        }
@@ -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;
@@ -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)) {
index 5926cac..63a3101 100644 (file)
@@ -1496,8 +1496,95 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
        return count;
 }
 
+static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
+                                       char __user *user_buf,
+                                       size_t count, loff_t *ppos) {
+
+       struct iwl_trans *trans = file->private_data;
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
+
+       int pos = 0;
+       char *buf;
+       int bufsz = 24 * 64; /* 24 items * 64 char per item */
+       ssize_t ret;
+
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf) {
+               IWL_ERR(trans, "Can not allocate Buffer\n");
+               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",
+               isr_stats->hw);
+       pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
+               isr_stats->sw);
+       if (isr_stats->sw || isr_stats->hw) {
+               pos += scnprintf(buf + pos, bufsz - pos,
+                       "\tLast Restarting Code:  0x%X\n",
+                       isr_stats->err_code);
+       }
+#ifdef CONFIG_IWLWIFI_DEBUG
+       pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
+               isr_stats->sch);
+       pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
+               isr_stats->alive);
+#endif
+       pos += scnprintf(buf + pos, bufsz - pos,
+               "HW RF KILL switch toggled:\t %u\n", isr_stats->rfkill);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
+               isr_stats->ctkill);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
+               isr_stats->wakeup);
+
+       pos += scnprintf(buf + pos, bufsz - pos,
+               "Rx command responses:\t\t %u\n", isr_stats->rx);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
+               isr_stats->tx);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
+               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,
+                                        const char __user *user_buf,
+                                        size_t count, loff_t *ppos)
+{
+       struct iwl_trans *trans = file->private_data;
+       struct iwl_trans_pcie *trans_pcie =
+               IWL_TRANS_GET_PCIE_TRANS(trans);
+       struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
+
+       char buf[8];
+       int buf_size;
+       u32 reset_flag;
+
+       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, "%x", &reset_flag) != 1)
+               return -EFAULT;
+       if (reset_flag == 0)
+               memset(isr_stats, 0, sizeof(*isr_stats));
+
+       return count;
+}
+
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
 DEBUGFS_READ_WRITE_FILE_OPS(log_event);
+DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 DEBUGFS_READ_FILE_OPS(rx_queue);
 DEBUGFS_READ_FILE_OPS(tx_queue);
 
@@ -1512,6 +1599,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
        DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR);
        DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR);
        DEBUGFS_ADD_FILE(log_event, dir, S_IWUSR | S_IRUSR);
+       DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
        return 0;
 }
 #else