iwlwifi: update reply_statistics_cmd with 'clear' parameter
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 13 Nov 2009 19:56:28 +0000 (11:56 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 18 Nov 2009 22:09:04 +0000 (17:09 -0500)
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>
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-calib.c
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-debug.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c

index 6532e9e689516f6a964c90234ecadecd3e5dd442..f586e7e83131354912a35710ef6853b8f6fb6701 100644 (file)
@@ -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,
@@ -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);
@@ -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) {
index d994de7438d89063492308b4e6589f51c7eb8fda..95a57b36a7eafef9a366409d4d7391e0c77861d2 100644 (file)
@@ -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);
 
index 2857287be4fd65c729ca5e9c5d872a29617fd643..6e23a2b5cb8ac86b78ddacf93b8c2fb46d7a8ede 100644 (file)
@@ -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.
index d09e748153238ecbb78ca4a59f343a0d6a5c5f5c..1736c60c3e21d9cc3583c8f81c28731919b8852a 100644 (file)
@@ -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);
 
index 3f97036ac29b319164d98c74f529e1712fe2783d..584a376b96c5f16d1de13ed6734236f7ae7f1319 100644 (file)
@@ -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 */
@@ -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);
index 96c92eab692a431b14871a50c0fc12f1b9d2f664..25a0e73314f72597ab0bdbc437e19768aaa3d0f7 100644 (file)
@@ -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;
index 8784911fd56e634fc51477c46c18de47f8b2a556..45a5edd1b1a7e5a6d98f3806483382c75c6ed269 100644 (file)
@@ -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)
 {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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);
@@ -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
@@ -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);
@@ -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);
index 9bce2c1625e3e085b46559a59f2f2b5e005a5adb..8ccc0bb1d9ed00c0fe9391acae0aa0dff0fbfaa2 100644 (file)
@@ -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));
index 61b3b0e6ed73dfe4e162a1cf4413b73ee0bafe51..9d010a0d83afd179f7fe51adecf94e2e75a8f1e3 100644 (file)
@@ -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)
index 05f118529feaf88c2f8d26d149ccfc0ecf9ac720..93bb4d341be30d65e6a1d6e4db2b1c0a61c4dc4d 100644 (file)
@@ -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) {