aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2009-11-13 14:56:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:04 -0500
commitef8d5529b015d4c5db7fad1adfc91edfd5abad56 (patch)
tree401d2477ce3ad9d87be8f696a470b08894856307 /drivers
parent7d2ed110a80991849a2824a6dc3c063ffca9dbe4 (diff)
iwlwifi: update reply_statistics_cmd with 'clear' parameter
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
10 files changed, 77 insertions, 23 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 6532e9e68951..f586e7e83131 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -612,7 +612,7 @@ static void iwl_bg_statistics_periodic(unsigned long data)
612 if (!iwl_is_ready_rf(priv)) 612 if (!iwl_is_ready_rf(priv))
613 return; 613 return;
614 614
615 iwl_send_statistics_request(priv, CMD_ASYNC); 615 iwl_send_statistics_request(priv, CMD_ASYNC, false);
616} 616}
617 617
618static void iwl_rx_beacon_notif(struct iwl_priv *priv, 618static void iwl_rx_beacon_notif(struct iwl_priv *priv,
@@ -729,7 +729,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
729 * statistics request from the host as well as for the periodic 729 * statistics request from the host as well as for the periodic
730 * statistics notifications (after received beacons) from the uCode. 730 * statistics notifications (after received beacons) from the uCode.
731 */ 731 */
732 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics; 732 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics;
733 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 733 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
734 734
735 iwl_setup_spectrum_handlers(priv); 735 iwl_setup_spectrum_handlers(priv);
@@ -2892,7 +2892,7 @@ static ssize_t show_statistics(struct device *d,
2892 return -EAGAIN; 2892 return -EAGAIN;
2893 2893
2894 mutex_lock(&priv->mutex); 2894 mutex_lock(&priv->mutex);
2895 rc = iwl_send_statistics_request(priv, 0); 2895 rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
2896 mutex_unlock(&priv->mutex); 2896 mutex_unlock(&priv->mutex);
2897 2897
2898 if (rc) { 2898 if (rc) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index d994de7438d8..95a57b36a7ea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -900,7 +900,7 @@ void iwl_reset_run_time_calib(struct iwl_priv *priv)
900 900
901 /* Ask for statistics now, the uCode will send notification 901 /* Ask for statistics now, the uCode will send notification
902 * periodically after association */ 902 * periodically after association */
903 iwl_send_statistics_request(priv, CMD_ASYNC); 903 iwl_send_statistics_request(priv, CMD_ASYNC, true);
904} 904}
905EXPORT_SYMBOL(iwl_reset_run_time_calib); 905EXPORT_SYMBOL(iwl_reset_run_time_calib);
906 906
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 2857287be4fd..6e23a2b5cb8a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3071,6 +3071,10 @@ struct statistics_general {
3071 __le32 reserved3; 3071 __le32 reserved3;
3072} __attribute__ ((packed)); 3072} __attribute__ ((packed));
3073 3073
3074#define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0)
3075#define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1)
3076#define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2)
3077
3074/* 3078/*
3075 * REPLY_STATISTICS_CMD = 0x9c, 3079 * REPLY_STATISTICS_CMD = 0x9c,
3076 * 3945 and 4965 identical. 3080 * 3945 and 4965 identical.
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d09e74815323..1736c60c3e21 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1990,16 +1990,21 @@ int iwl_send_bt_config(struct iwl_priv *priv)
1990} 1990}
1991EXPORT_SYMBOL(iwl_send_bt_config); 1991EXPORT_SYMBOL(iwl_send_bt_config);
1992 1992
1993int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) 1993int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
1994{ 1994{
1995 u32 stat_flags = 0; 1995 struct iwl_statistics_cmd statistics_cmd = {
1996 struct iwl_host_cmd cmd = { 1996 .configuration_flags =
1997 .id = REPLY_STATISTICS_CMD, 1997 clear ? IWL_STATS_CONF_CLEAR_STATS : 0,
1998 .flags = flags,
1999 .len = sizeof(stat_flags),
2000 .data = (u8 *) &stat_flags,
2001 }; 1998 };
2002 return iwl_send_cmd(priv, &cmd); 1999
2000 if (flags & CMD_ASYNC)
2001 return iwl_send_cmd_pdu_async(priv, REPLY_STATISTICS_CMD,
2002 sizeof(struct iwl_statistics_cmd),
2003 &statistics_cmd, NULL);
2004 else
2005 return iwl_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
2006 sizeof(struct iwl_statistics_cmd),
2007 &statistics_cmd);
2003} 2008}
2004EXPORT_SYMBOL(iwl_send_statistics_request); 2009EXPORT_SYMBOL(iwl_send_statistics_request);
2005 2010
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 3f97036ac29b..584a376b96c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -425,6 +425,8 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
425 struct iwl_rx_mem_buffer *rxb); 425 struct iwl_rx_mem_buffer *rxb);
426void iwl_rx_statistics(struct iwl_priv *priv, 426void iwl_rx_statistics(struct iwl_priv *priv,
427 struct iwl_rx_mem_buffer *rxb); 427 struct iwl_rx_mem_buffer *rxb);
428void iwl_reply_statistics(struct iwl_priv *priv,
429 struct iwl_rx_mem_buffer *rxb);
428void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); 430void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
429 431
430/* TX helpers */ 432/* TX helpers */
@@ -669,7 +671,8 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
669 671
670extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); 672extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
671extern int iwl_send_bt_config(struct iwl_priv *priv); 673extern int iwl_send_bt_config(struct iwl_priv *priv);
672extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); 674extern int iwl_send_statistics_request(struct iwl_priv *priv,
675 u8 flags, bool clear);
673extern int iwl_verify_ucode(struct iwl_priv *priv); 676extern int iwl_verify_ucode(struct iwl_priv *priv);
674extern int iwl_send_lq_cmd(struct iwl_priv *priv, 677extern int iwl_send_lq_cmd(struct iwl_priv *priv,
675 struct iwl_link_quality_cmd *lq, u8 flags); 678 struct iwl_link_quality_cmd *lq, u8 flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 96c92eab692a..25a0e73314f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -107,6 +107,7 @@ struct iwl_debugfs {
107 struct dentry *file_chain_noise; 107 struct dentry *file_chain_noise;
108 struct dentry *file_tx_power; 108 struct dentry *file_tx_power;
109 struct dentry *file_power_save_status; 109 struct dentry *file_power_save_status;
110 struct dentry *file_clear_statistics;
110 } dbgfs_debug_files; 111 } dbgfs_debug_files;
111 u32 sram_offset; 112 u32 sram_offset;
112 u32 sram_len; 113 u32 sram_len;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 8784911fd56e..45a5edd1b1a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1042,10 +1042,6 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1042 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1042 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1043} 1043}
1044 1044
1045#define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0)
1046#define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1)
1047#define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2)
1048
1049static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, 1045static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1050 int bufsz) 1046 int bufsz)
1051{ 1047{
@@ -1092,7 +1088,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1092 1088
1093 /* make request to uCode to retrieve statistics information */ 1089 /* make request to uCode to retrieve statistics information */
1094 mutex_lock(&priv->mutex); 1090 mutex_lock(&priv->mutex);
1095 ret = iwl_send_statistics_request(priv, 0); 1091 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1096 mutex_unlock(&priv->mutex); 1092 mutex_unlock(&priv->mutex);
1097 1093
1098 if (ret) { 1094 if (ret) {
@@ -1398,7 +1394,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1398 1394
1399 /* make request to uCode to retrieve statistics information */ 1395 /* make request to uCode to retrieve statistics information */
1400 mutex_lock(&priv->mutex); 1396 mutex_lock(&priv->mutex);
1401 ret = iwl_send_statistics_request(priv, 0); 1397 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1402 mutex_unlock(&priv->mutex); 1398 mutex_unlock(&priv->mutex);
1403 1399
1404 if (ret) { 1400 if (ret) {
@@ -1542,7 +1538,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1542 1538
1543 /* make request to uCode to retrieve statistics information */ 1539 /* make request to uCode to retrieve statistics information */
1544 mutex_lock(&priv->mutex); 1540 mutex_lock(&priv->mutex);
1545 ret = iwl_send_statistics_request(priv, 0); 1541 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1546 mutex_unlock(&priv->mutex); 1542 mutex_unlock(&priv->mutex);
1547 1543
1548 if (ret) { 1544 if (ret) {
@@ -1770,7 +1766,7 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1770 else { 1766 else {
1771 /* make request to uCode to retrieve statistics information */ 1767 /* make request to uCode to retrieve statistics information */
1772 mutex_lock(&priv->mutex); 1768 mutex_lock(&priv->mutex);
1773 ret = iwl_send_statistics_request(priv, 0); 1769 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1774 mutex_unlock(&priv->mutex); 1770 mutex_unlock(&priv->mutex);
1775 1771
1776 if (ret) { 1772 if (ret) {
@@ -1828,6 +1824,30 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1828 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1824 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1829} 1825}
1830 1826
1827static ssize_t iwl_dbgfs_clear_statistics_write(struct file *file,
1828 const char __user *user_buf,
1829 size_t count, loff_t *ppos)
1830{
1831 struct iwl_priv *priv = file->private_data;
1832 char buf[8];
1833 int buf_size;
1834 int clear;
1835
1836 memset(buf, 0, sizeof(buf));
1837 buf_size = min(count, sizeof(buf) - 1);
1838 if (copy_from_user(buf, user_buf, buf_size))
1839 return -EFAULT;
1840 if (sscanf(buf, "%d", &clear) != 1)
1841 return -EFAULT;
1842
1843 /* make request to uCode to retrieve statistics information */
1844 mutex_lock(&priv->mutex);
1845 iwl_send_statistics_request(priv, CMD_SYNC, true);
1846 mutex_unlock(&priv->mutex);
1847
1848 return count;
1849}
1850
1831DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics); 1851DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics);
1832DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics); 1852DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics);
1833DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1853DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1840,6 +1860,7 @@ DEBUGFS_READ_FILE_OPS(sensitivity);
1840DEBUGFS_READ_FILE_OPS(chain_noise); 1860DEBUGFS_READ_FILE_OPS(chain_noise);
1841DEBUGFS_READ_FILE_OPS(tx_power); 1861DEBUGFS_READ_FILE_OPS(tx_power);
1842DEBUGFS_READ_FILE_OPS(power_save_status); 1862DEBUGFS_READ_FILE_OPS(power_save_status);
1863DEBUGFS_WRITE_FILE_OPS(clear_statistics);
1843 1864
1844/* 1865/*
1845 * Create the debugfs files and directories 1866 * Create the debugfs files and directories
@@ -1888,6 +1909,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1888 DEBUGFS_ADD_FILE(tx_queue, debug); 1909 DEBUGFS_ADD_FILE(tx_queue, debug);
1889 DEBUGFS_ADD_FILE(tx_power, debug); 1910 DEBUGFS_ADD_FILE(tx_power, debug);
1890 DEBUGFS_ADD_FILE(power_save_status, debug); 1911 DEBUGFS_ADD_FILE(power_save_status, debug);
1912 DEBUGFS_ADD_FILE(clear_statistics, debug);
1891 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 1913 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1892 DEBUGFS_ADD_FILE(ucode_rx_stats, debug); 1914 DEBUGFS_ADD_FILE(ucode_rx_stats, debug);
1893 DEBUGFS_ADD_FILE(ucode_tx_stats, debug); 1915 DEBUGFS_ADD_FILE(ucode_tx_stats, debug);
@@ -1941,6 +1963,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
1941 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue); 1963 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
1942 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power); 1964 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
1943 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status); 1965 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
1966 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_clear_statistics);
1944 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 1967 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1945 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 1968 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1946 file_ucode_rx_stats); 1969 file_ucode_rx_stats);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 9bce2c1625e3..8ccc0bb1d9ed 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -506,7 +506,7 @@ static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
506{ 506{
507 IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); 507 IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n");
508 /* make request to retrieve statistics information */ 508 /* make request to retrieve statistics information */
509 iwl_send_statistics_request(priv, 0); 509 iwl_send_statistics_request(priv, CMD_SYNC, false);
510 /* Reschedule the ct_kill wait timer */ 510 /* Reschedule the ct_kill wait timer */
511 mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm, 511 mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
512 jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION)); 512 jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION));
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 61b3b0e6ed73..9d010a0d83af 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -635,6 +635,24 @@ void iwl_rx_statistics(struct iwl_priv *priv,
635} 635}
636EXPORT_SYMBOL(iwl_rx_statistics); 636EXPORT_SYMBOL(iwl_rx_statistics);
637 637
638void iwl_reply_statistics(struct iwl_priv *priv,
639 struct iwl_rx_mem_buffer *rxb)
640{
641 struct iwl_rx_packet *pkt = rxb_addr(rxb);
642
643 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
644 memset(&priv->statistics, 0,
645 sizeof(struct iwl_notif_statistics));
646#ifdef CONFIG_IWLWIFI_DEBUG
647 memset(&priv->accum_statistics, 0,
648 sizeof(struct iwl_notif_statistics));
649#endif
650 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
651 }
652 iwl_rx_statistics(priv, rxb);
653}
654EXPORT_SYMBOL(iwl_reply_statistics);
655
638#define PERFECT_RSSI (-20) /* dBm */ 656#define PERFECT_RSSI (-20) /* dBm */
639#define WORST_RSSI (-95) /* dBm */ 657#define WORST_RSSI (-95) /* dBm */
640#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) 658#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 05f118529fea..93bb4d341be3 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3649,7 +3649,7 @@ static ssize_t show_statistics(struct device *d,
3649 return -EAGAIN; 3649 return -EAGAIN;
3650 3650
3651 mutex_lock(&priv->mutex); 3651 mutex_lock(&priv->mutex);
3652 rc = iwl_send_statistics_request(priv, 0); 3652 rc = iwl_send_statistics_request(priv, CMD_SYNC, false);
3653 mutex_unlock(&priv->mutex); 3653 mutex_unlock(&priv->mutex);
3654 3654
3655 if (rc) { 3655 if (rc) {