aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-04-08 11:14:56 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-04-08 11:19:00 -0400
commit0da0e5bf1522d75d446f5124e17016628d0a149e (patch)
tree86d9c4986be873fb834b54a4d9075330743c0f03
parent703bc583cb98a24eeedd297ee59dfa12852897d1 (diff)
iwlagn: clean up & autodetect statistics
There's no need to keep both normal and BT statistics versions around all the time in memory when we only use a subset of both. So keep only the subsets that we need in memory, depending on the debug config). Also, in doing so, we can remove all the calls to iwl_bt_statistics() in the driver as we'll just access the copied statistics now. Finally, also remove this call from the one place where it might still be needed and automatically detect what kind of statistics the device is sending based on their size. This way, we don't need to keep track of which devices do what any more, which is good since this is subject to change based on the ucode version (as some ucode even for non-BT devices will in fact use BT statistics). Warn upon encountering a statistics command from the ucode that isn't known, so we will find such issues earlier in the future. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Tested-by: Don Fry <donald.h.fry@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c134
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c298
13 files changed, 243 insertions, 376 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 805b0394850..a31314fdb05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -383,7 +383,6 @@ static struct iwl_ht_params iwl2000_ht_params = {
383}; 383};
384 384
385static struct iwl_bt_params iwl2030_bt_params = { 385static struct iwl_bt_params iwl2030_bt_params = {
386 .bt_statistics = true,
387 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 386 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
388 .advanced_bt_coexist = true, 387 .advanced_bt_coexist = true,
389 .agg_time_limit = BT_AGG_THRESHOLD_DEF, 388 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 357137f0863..7c286662d26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -259,7 +259,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
259 u32 vt = 0; 259 u32 vt = 0;
260 s32 offset = iwl_temp_calib_to_offset(priv); 260 s32 offset = iwl_temp_calib_to_offset(priv);
261 261
262 vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature); 262 vt = le32_to_cpu(priv->statistics.common.temperature);
263 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; 263 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
264 /* now vt hold the temperature in Kelvin */ 264 /* now vt hold the temperature in Kelvin */
265 priv->temperature = KELVIN_TO_CELSIUS(vt); 265 priv->temperature = KELVIN_TO_CELSIUS(vt);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 8847b211397..064981345c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -489,7 +489,6 @@ static struct iwl_ht_params iwl6000_ht_params = {
489}; 489};
490 490
491static struct iwl_bt_params iwl6000_bt_params = { 491static struct iwl_bt_params iwl6000_bt_params = {
492 .bt_statistics = true,
493 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 492 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
494 .advanced_bt_coexist = true, 493 .advanced_bt_coexist = true,
495 .agg_time_limit = BT_AGG_THRESHOLD_DEF, 494 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 7b761de77b0..0f6bb9b2e64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -605,7 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
605 IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret); 605 IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
606} 606}
607 607
608void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) 608void iwl_sensitivity_calibration(struct iwl_priv *priv)
609{ 609{
610 u32 rx_enable_time; 610 u32 rx_enable_time;
611 u32 fa_cck; 611 u32 fa_cck;
@@ -631,16 +631,9 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
631 } 631 }
632 632
633 spin_lock_irqsave(&priv->lock, flags); 633 spin_lock_irqsave(&priv->lock, flags);
634 if (iwl_bt_statistics(priv)) { 634 rx_info = &priv->statistics.rx_non_phy;
635 rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> 635 ofdm = &priv->statistics.rx_ofdm;
636 rx.general.common); 636 cck = &priv->statistics.rx_cck;
637 ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
638 cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck);
639 } else {
640 rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
641 ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
642 cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
643 }
644 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { 637 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
645 IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); 638 IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
646 spin_unlock_irqrestore(&priv->lock, flags); 639 spin_unlock_irqrestore(&priv->lock, flags);
@@ -851,7 +844,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
851 * 1) Which antennas are connected. 844 * 1) Which antennas are connected.
852 * 2) Differential rx gain settings to balance the 3 receivers. 845 * 2) Differential rx gain settings to balance the 3 receivers.
853 */ 846 */
854void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) 847void iwl_chain_noise_calibration(struct iwl_priv *priv)
855{ 848{
856 struct iwl_chain_noise_data *data = NULL; 849 struct iwl_chain_noise_data *data = NULL;
857 850
@@ -896,13 +889,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
896 } 889 }
897 890
898 spin_lock_irqsave(&priv->lock, flags); 891 spin_lock_irqsave(&priv->lock, flags);
899 if (iwl_bt_statistics(priv)) { 892
900 rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> 893 rx_info = &priv->statistics.rx_non_phy;
901 rx.general.common); 894
902 } else {
903 rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
904 rx.general);
905 }
906 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { 895 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
907 IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); 896 IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
908 spin_unlock_irqrestore(&priv->lock, flags); 897 spin_unlock_irqrestore(&priv->lock, flags);
@@ -911,19 +900,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
911 900
912 rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); 901 rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
913 rxon_chnum = le16_to_cpu(ctx->staging.channel); 902 rxon_chnum = le16_to_cpu(ctx->staging.channel);
914 if (iwl_bt_statistics(priv)) { 903 stat_band24 =
915 stat_band24 = !!(((struct iwl_bt_notif_statistics *) 904 !!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
916 stat_resp)->flag & 905 stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16;
917 STATISTICS_REPLY_FLG_BAND_24G_MSK);
918 stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
919 stat_resp)->flag) >> 16;
920 } else {
921 stat_band24 = !!(((struct iwl_notif_statistics *)
922 stat_resp)->flag &
923 STATISTICS_REPLY_FLG_BAND_24G_MSK);
924 stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
925 stat_resp)->flag) >> 16;
926 }
927 906
928 /* Make sure we accumulate data for just the associated channel 907 /* Make sure we accumulate data for just the associated channel
929 * (even if scanning). */ 908 * (even if scanning). */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index ef4d5079a7e..4ef4dd93425 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -66,8 +66,8 @@
66#include "iwl-core.h" 66#include "iwl-core.h"
67#include "iwl-commands.h" 67#include "iwl-commands.h"
68 68
69void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); 69void iwl_chain_noise_calibration(struct iwl_priv *priv);
70void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp); 70void iwl_sensitivity_calibration(struct iwl_priv *priv);
71 71
72void iwl_init_sensitivity(struct iwl_priv *priv); 72void iwl_init_sensitivity(struct iwl_priv *priv);
73void iwl_reset_run_time_calib(struct iwl_priv *priv); 73void iwl_reset_run_time_calib(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index d1834aa7edf..71a5f31cd7c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -39,10 +39,7 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
39 int p = 0; 39 int p = 0;
40 u32 flag; 40 u32 flag;
41 41
42 if (iwl_bt_statistics(priv)) 42 flag = le32_to_cpu(priv->statistics.flag);
43 flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
44 else
45 flag = le32_to_cpu(priv->_agn.statistics.flag);
46 43
47 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); 44 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
48 if (flag & UCODE_STATISTICS_CLEAR_MSK) 45 if (flag & UCODE_STATISTICS_CLEAR_MSK)
@@ -88,43 +85,22 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
88 * the last statistics notification from uCode 85 * the last statistics notification from uCode
89 * might not reflect the current uCode activity 86 * might not reflect the current uCode activity
90 */ 87 */
91 if (iwl_bt_statistics(priv)) { 88 ofdm = &priv->statistics.rx_ofdm;
92 ofdm = &priv->_agn.statistics_bt.rx.ofdm; 89 cck = &priv->statistics.rx_cck;
93 cck = &priv->_agn.statistics_bt.rx.cck; 90 general = &priv->statistics.rx_non_phy;
94 general = &priv->_agn.statistics_bt.rx.general.common; 91 ht = &priv->statistics.rx_ofdm_ht;
95 ht = &priv->_agn.statistics_bt.rx.ofdm_ht; 92 accum_ofdm = &priv->accum_stats.rx_ofdm;
96 accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm; 93 accum_cck = &priv->accum_stats.rx_cck;
97 accum_cck = &priv->_agn.accum_statistics_bt.rx.cck; 94 accum_general = &priv->accum_stats.rx_non_phy;
98 accum_general = 95 accum_ht = &priv->accum_stats.rx_ofdm_ht;
99 &priv->_agn.accum_statistics_bt.rx.general.common; 96 delta_ofdm = &priv->delta_stats.rx_ofdm;
100 accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht; 97 delta_cck = &priv->delta_stats.rx_cck;
101 delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm; 98 delta_general = &priv->delta_stats.rx_non_phy;
102 delta_cck = &priv->_agn.delta_statistics_bt.rx.cck; 99 delta_ht = &priv->delta_stats.rx_ofdm_ht;
103 delta_general = 100 max_ofdm = &priv->max_delta_stats.rx_ofdm;
104 &priv->_agn.delta_statistics_bt.rx.general.common; 101 max_cck = &priv->max_delta_stats.rx_cck;
105 delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht; 102 max_general = &priv->max_delta_stats.rx_non_phy;
106 max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm; 103 max_ht = &priv->max_delta_stats.rx_ofdm_ht;
107 max_cck = &priv->_agn.max_delta_bt.rx.cck;
108 max_general = &priv->_agn.max_delta_bt.rx.general.common;
109 max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
110 } else {
111 ofdm = &priv->_agn.statistics.rx.ofdm;
112 cck = &priv->_agn.statistics.rx.cck;
113 general = &priv->_agn.statistics.rx.general;
114 ht = &priv->_agn.statistics.rx.ofdm_ht;
115 accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
116 accum_cck = &priv->_agn.accum_statistics.rx.cck;
117 accum_general = &priv->_agn.accum_statistics.rx.general;
118 accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
119 delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
120 delta_cck = &priv->_agn.delta_statistics.rx.cck;
121 delta_general = &priv->_agn.delta_statistics.rx.general;
122 delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
123 max_ofdm = &priv->_agn.max_delta.rx.ofdm;
124 max_cck = &priv->_agn.max_delta.rx.cck;
125 max_general = &priv->_agn.max_delta.rx.general;
126 max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
127 }
128 104
129 pos += iwl_statistics_flag(priv, buf, bufsz); 105 pos += iwl_statistics_flag(priv, buf, bufsz);
130 pos += scnprintf(buf + pos, bufsz - pos, 106 pos += scnprintf(buf + pos, bufsz - pos,
@@ -531,20 +507,13 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
531 } 507 }
532 508
533 /* the statistic information display here is based on 509 /* the statistic information display here is based on
534 * the last statistics notification from uCode 510 * the last statistics notification from uCode
535 * might not reflect the current uCode activity 511 * might not reflect the current uCode activity
536 */ 512 */
537 if (iwl_bt_statistics(priv)) { 513 tx = &priv->statistics.tx;
538 tx = &priv->_agn.statistics_bt.tx; 514 accum_tx = &priv->accum_stats.tx;
539 accum_tx = &priv->_agn.accum_statistics_bt.tx; 515 delta_tx = &priv->delta_stats.tx;
540 delta_tx = &priv->_agn.delta_statistics_bt.tx; 516 max_tx = &priv->max_delta_stats.tx;
541 max_tx = &priv->_agn.max_delta_bt.tx;
542 } else {
543 tx = &priv->_agn.statistics.tx;
544 accum_tx = &priv->_agn.accum_statistics.tx;
545 delta_tx = &priv->_agn.delta_statistics.tx;
546 max_tx = &priv->_agn.max_delta.tx;
547 }
548 517
549 pos += iwl_statistics_flag(priv, buf, bufsz); 518 pos += iwl_statistics_flag(priv, buf, bufsz);
550 pos += scnprintf(buf + pos, bufsz - pos, 519 pos += scnprintf(buf + pos, bufsz - pos,
@@ -731,36 +700,21 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
731 } 700 }
732 701
733 /* the statistic information display here is based on 702 /* the statistic information display here is based on
734 * the last statistics notification from uCode 703 * the last statistics notification from uCode
735 * might not reflect the current uCode activity 704 * might not reflect the current uCode activity
736 */ 705 */
737 if (iwl_bt_statistics(priv)) { 706 general = &priv->statistics.common;
738 general = &priv->_agn.statistics_bt.general.common; 707 dbg = &priv->statistics.common.dbg;
739 dbg = &priv->_agn.statistics_bt.general.common.dbg; 708 div = &priv->statistics.common.div;
740 div = &priv->_agn.statistics_bt.general.common.div; 709 accum_general = &priv->accum_stats.common;
741 accum_general = &priv->_agn.accum_statistics_bt.general.common; 710 accum_dbg = &priv->accum_stats.common.dbg;
742 accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg; 711 accum_div = &priv->accum_stats.common.div;
743 accum_div = &priv->_agn.accum_statistics_bt.general.common.div; 712 delta_general = &priv->delta_stats.common;
744 delta_general = &priv->_agn.delta_statistics_bt.general.common; 713 max_general = &priv->max_delta_stats.common;
745 max_general = &priv->_agn.max_delta_bt.general.common; 714 delta_dbg = &priv->delta_stats.common.dbg;
746 delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg; 715 max_dbg = &priv->max_delta_stats.common.dbg;
747 max_dbg = &priv->_agn.max_delta_bt.general.common.dbg; 716 delta_div = &priv->delta_stats.common.div;
748 delta_div = &priv->_agn.delta_statistics_bt.general.common.div; 717 max_div = &priv->max_delta_stats.common.div;
749 max_div = &priv->_agn.max_delta_bt.general.common.div;
750 } else {
751 general = &priv->_agn.statistics.general.common;
752 dbg = &priv->_agn.statistics.general.common.dbg;
753 div = &priv->_agn.statistics.general.common.div;
754 accum_general = &priv->_agn.accum_statistics.general.common;
755 accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
756 accum_div = &priv->_agn.accum_statistics.general.common.div;
757 delta_general = &priv->_agn.delta_statistics.general.common;
758 max_general = &priv->_agn.max_delta.general.common;
759 delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
760 max_dbg = &priv->_agn.max_delta.general.common.dbg;
761 delta_div = &priv->_agn.delta_statistics.general.common.div;
762 max_div = &priv->_agn.max_delta.general.common.div;
763 }
764 718
765 pos += iwl_statistics_flag(priv, buf, bufsz); 719 pos += iwl_statistics_flag(priv, buf, bufsz);
766 pos += scnprintf(buf + pos, bufsz - pos, 720 pos += scnprintf(buf + pos, bufsz - pos,
@@ -876,8 +830,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
876 * the last statistics notification from uCode 830 * the last statistics notification from uCode
877 * might not reflect the current uCode activity 831 * might not reflect the current uCode activity
878 */ 832 */
879 bt = &priv->_agn.statistics_bt.general.activity; 833 bt = &priv->statistics.bt_activity;
880 accum_bt = &priv->_agn.accum_statistics_bt.general.activity; 834 accum_bt = &priv->accum_stats.bt_activity;
881 835
882 pos += iwl_statistics_flag(priv, buf, bufsz); 836 pos += iwl_statistics_flag(priv, buf, bufsz);
883 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); 837 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
@@ -918,10 +872,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
918 872
919 pos += scnprintf(buf + pos, bufsz - pos, 873 pos += scnprintf(buf + pos, bufsz - pos,
920 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", 874 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
921 le32_to_cpu(priv->_agn.statistics_bt.rx. 875 le32_to_cpu(priv->statistics.num_bt_kills),
922 general.num_bt_kills), 876 priv->statistics.accum_num_bt_kills);
923 priv->_agn.accum_statistics_bt.rx.
924 general.num_bt_kills);
925 877
926 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 878 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
927 kfree(buf); 879 kfree(buf);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index bc5dfe2978f..e741128842b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -549,9 +549,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
549void iwlagn_temperature(struct iwl_priv *priv) 549void iwlagn_temperature(struct iwl_priv *priv)
550{ 550{
551 /* store temperature from correct statistics (in Celsius) */ 551 /* store temperature from correct statistics (in Celsius) */
552 priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ? 552 priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
553 priv->_agn.statistics_bt.general.common.temperature :
554 priv->_agn.statistics.general.common.temperature);
555 iwl_tt_handler(priv); 553 iwl_tt_handler(priv);
556} 554}
557 555
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 23b89c2e71d..20499b76443 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1705,10 +1705,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1705 else 1705 else
1706 priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; 1706 priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1707 1707
1708 if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS ||
1709 (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics))
1710 priv->bt_statistics = true;
1711
1712 /* Copy images into buffers for card's bus-master reads ... */ 1708 /* Copy images into buffers for card's bus-master reads ... */
1713 1709
1714 /* Runtime instructions (first block of data in file) */ 1710 /* Runtime instructions (first block of data in file) */
@@ -2626,17 +2622,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2626 } 2622 }
2627 2623
2628 if (priv->start_calib) { 2624 if (priv->start_calib) {
2629 if (iwl_bt_statistics(priv)) { 2625 iwl_chain_noise_calibration(priv);
2630 iwl_chain_noise_calibration(priv, 2626 iwl_sensitivity_calibration(priv);
2631 (void *)&priv->_agn.statistics_bt);
2632 iwl_sensitivity_calibration(priv,
2633 (void *)&priv->_agn.statistics_bt);
2634 } else {
2635 iwl_chain_noise_calibration(priv,
2636 (void *)&priv->_agn.statistics);
2637 iwl_sensitivity_calibration(priv,
2638 (void *)&priv->_agn.statistics);
2639 }
2640 } 2627 }
2641 2628
2642 mutex_unlock(&priv->mutex); 2629 mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index a1a5c1b2309..0edba8a6419 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2535,53 +2535,6 @@ struct rate_histogram {
2535 2535
2536/* statistics command response */ 2536/* statistics command response */
2537 2537
2538struct iwl39_statistics_rx_phy {
2539 __le32 ina_cnt;
2540 __le32 fina_cnt;
2541 __le32 plcp_err;
2542 __le32 crc32_err;
2543 __le32 overrun_err;
2544 __le32 early_overrun_err;
2545 __le32 crc32_good;
2546 __le32 false_alarm_cnt;
2547 __le32 fina_sync_err_cnt;
2548 __le32 sfd_timeout;
2549 __le32 fina_timeout;
2550 __le32 unresponded_rts;
2551 __le32 rxe_frame_limit_overrun;
2552 __le32 sent_ack_cnt;
2553 __le32 sent_cts_cnt;
2554} __packed;
2555
2556struct iwl39_statistics_rx_non_phy {
2557 __le32 bogus_cts; /* CTS received when not expecting CTS */
2558 __le32 bogus_ack; /* ACK received when not expecting ACK */
2559 __le32 non_bssid_frames; /* number of frames with BSSID that
2560 * doesn't belong to the STA BSSID */
2561 __le32 filtered_frames; /* count frames that were dumped in the
2562 * filtering process */
2563 __le32 non_channel_beacons; /* beacons with our bss id but not on
2564 * our serving channel */
2565} __packed;
2566
2567struct iwl39_statistics_rx {
2568 struct iwl39_statistics_rx_phy ofdm;
2569 struct iwl39_statistics_rx_phy cck;
2570 struct iwl39_statistics_rx_non_phy general;
2571} __packed;
2572
2573struct iwl39_statistics_tx {
2574 __le32 preamble_cnt;
2575 __le32 rx_detected_cnt;
2576 __le32 bt_prio_defer_cnt;
2577 __le32 bt_prio_kill_cnt;
2578 __le32 few_bytes_cnt;
2579 __le32 cts_timeout;
2580 __le32 ack_timeout;
2581 __le32 expected_ack_cnt;
2582 __le32 actual_ack_cnt;
2583} __packed;
2584
2585struct statistics_dbg { 2538struct statistics_dbg {
2586 __le32 burst_check; 2539 __le32 burst_check;
2587 __le32 burst_count; 2540 __le32 burst_count;
@@ -2589,23 +2542,6 @@ struct statistics_dbg {
2589 __le32 reserved[3]; 2542 __le32 reserved[3];
2590} __packed; 2543} __packed;
2591 2544
2592struct iwl39_statistics_div {
2593 __le32 tx_on_a;
2594 __le32 tx_on_b;
2595 __le32 exec_time;
2596 __le32 probe_time;
2597} __packed;
2598
2599struct iwl39_statistics_general {
2600 __le32 temperature;
2601 struct statistics_dbg dbg;
2602 __le32 sleep_time;
2603 __le32 slots_out;
2604 __le32 slots_idle;
2605 __le32 ttl_timestamp;
2606 struct iwl39_statistics_div div;
2607} __packed;
2608
2609struct statistics_rx_phy { 2545struct statistics_rx_phy {
2610 __le32 ina_cnt; 2546 __le32 ina_cnt;
2611 __le32 fina_cnt; 2547 __le32 fina_cnt;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 57763c013ca..6988335328e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -279,7 +279,6 @@ struct iwl_base_params {
279 * @advanced_bt_coexist: support advanced bt coexist 279 * @advanced_bt_coexist: support advanced bt coexist
280 * @bt_init_traffic_load: specify initial bt traffic load 280 * @bt_init_traffic_load: specify initial bt traffic load
281 * @bt_prio_boost: default bt priority boost value 281 * @bt_prio_boost: default bt priority boost value
282 * @bt_statistics: use BT version of statistics notification
283 * @agg_time_limit: maximum number of uSec in aggregation 282 * @agg_time_limit: maximum number of uSec in aggregation
284 * @ampdu_factor: Maximum A-MPDU length factor 283 * @ampdu_factor: Maximum A-MPDU length factor
285 * @ampdu_density: Minimum A-MPDU spacing 284 * @ampdu_density: Minimum A-MPDU spacing
@@ -289,7 +288,6 @@ struct iwl_bt_params {
289 bool advanced_bt_coexist; 288 bool advanced_bt_coexist;
290 u8 bt_init_traffic_load; 289 u8 bt_init_traffic_load;
291 u8 bt_prio_boost; 290 u8 bt_prio_boost;
292 const bool bt_statistics;
293 u16 agg_time_limit; 291 u16 agg_time_limit;
294 u8 ampdu_factor; 292 u8 ampdu_factor;
295 u8 ampdu_density; 293 u8 ampdu_density;
@@ -696,11 +694,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
696 priv->cfg->bt_params->advanced_bt_coexist; 694 priv->cfg->bt_params->advanced_bt_coexist;
697} 695}
698 696
699static inline bool iwl_bt_statistics(struct iwl_priv *priv)
700{
701 return priv->bt_statistics;
702}
703
704extern bool bt_coex_active; 697extern bool bt_coex_active;
705extern bool bt_siso_mode; 698extern bool bt_siso_mode;
706 699
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index c02f06901f8..897efacb96e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1751,8 +1751,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1751 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); 1751 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
1752 if (priv->cfg->base_params->ucode_tracing) 1752 if (priv->cfg->base_params->ucode_tracing)
1753 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); 1753 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
1754 if (iwl_bt_statistics(priv)) 1754 DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
1755 DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
1756 DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); 1755 DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
1757 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 1756 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1758 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 1757 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 7fe68f8dd21..e84534c4d95 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -543,13 +543,12 @@ enum iwl_ucode_tlv_type {
543 * enum iwl_ucode_tlv_flag - ucode API flags 543 * enum iwl_ucode_tlv_flag - ucode API flags
544 * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously 544 * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
545 * was a separate TLV but moved here to save space. 545 * was a separate TLV but moved here to save space.
546 * @IWL_UCODE_TLV_FLAGS_BTSTATS: This uCode image uses BT statistics, which 546 * @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved
547 * may be true even if the device doesn't have BT.
548 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). 547 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
549 */ 548 */
550enum iwl_ucode_tlv_flag { 549enum iwl_ucode_tlv_flag {
551 IWL_UCODE_TLV_FLAGS_PAN = BIT(0), 550 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
552 IWL_UCODE_TLV_FLAGS_BTSTATS = BIT(1), 551 IWL_UCODE_TLV_FLAGS_RESERVED_1 = BIT(1),
553 IWL_UCODE_TLV_FLAGS_MFP = BIT(2), 552 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
554}; 553};
555 554
@@ -1357,6 +1356,31 @@ struct iwl_priv {
1357 u64 timestamp; 1356 u64 timestamp;
1358 1357
1359 struct { 1358 struct {
1359 __le32 flag;
1360 struct statistics_general_common common;
1361 struct statistics_rx_non_phy rx_non_phy;
1362 struct statistics_rx_phy rx_ofdm;
1363 struct statistics_rx_ht_phy rx_ofdm_ht;
1364 struct statistics_rx_phy rx_cck;
1365 struct statistics_tx tx;
1366#ifdef CONFIG_IWLWIFI_DEBUGFS
1367 struct statistics_bt_activity bt_activity;
1368 __le32 num_bt_kills, accum_num_bt_kills;
1369#endif
1370 } statistics;
1371#ifdef CONFIG_IWLWIFI_DEBUGFS
1372 struct {
1373 struct statistics_general_common common;
1374 struct statistics_rx_non_phy rx_non_phy;
1375 struct statistics_rx_phy rx_ofdm;
1376 struct statistics_rx_ht_phy rx_ofdm_ht;
1377 struct statistics_rx_phy rx_cck;
1378 struct statistics_tx tx;
1379 struct statistics_bt_activity bt_activity;
1380 } accum_stats, delta_stats, max_delta_stats;
1381#endif
1382
1383 struct {
1360 /* INT ICT Table */ 1384 /* INT ICT Table */
1361 __le32 *ict_tbl; 1385 __le32 *ict_tbl;
1362 void *ict_tbl_vir; 1386 void *ict_tbl_vir;
@@ -1387,19 +1411,9 @@ struct iwl_priv {
1387 u8 phy_calib_chain_noise_reset_cmd; 1411 u8 phy_calib_chain_noise_reset_cmd;
1388 u8 phy_calib_chain_noise_gain_cmd; 1412 u8 phy_calib_chain_noise_gain_cmd;
1389 1413
1390 struct iwl_notif_statistics statistics;
1391 struct iwl_bt_notif_statistics statistics_bt;
1392 /* counts reply_tx error */ 1414 /* counts reply_tx error */
1393 struct reply_tx_error_statistics reply_tx_stats; 1415 struct reply_tx_error_statistics reply_tx_stats;
1394 struct reply_agg_tx_error_statistics reply_agg_tx_stats; 1416 struct reply_agg_tx_error_statistics reply_agg_tx_stats;
1395#ifdef CONFIG_IWLWIFI_DEBUGFS
1396 struct iwl_notif_statistics accum_statistics;
1397 struct iwl_notif_statistics delta_statistics;
1398 struct iwl_notif_statistics max_delta;
1399 struct iwl_bt_notif_statistics accum_statistics_bt;
1400 struct iwl_bt_notif_statistics delta_statistics_bt;
1401 struct iwl_bt_notif_statistics max_delta_bt;
1402#endif
1403 /* notification wait support */ 1417 /* notification wait support */
1404 struct list_head notif_waits; 1418 struct list_head notif_waits;
1405 spinlock_t notif_wait_lock; 1419 spinlock_t notif_wait_lock;
@@ -1424,7 +1438,6 @@ struct iwl_priv {
1424 bool bt_ch_announce; 1438 bool bt_ch_announce;
1425 bool bt_full_concurrent; 1439 bool bt_full_concurrent;
1426 bool bt_ant_couple_ok; 1440 bool bt_ant_couple_ok;
1427 bool bt_statistics;
1428 __le32 kill_ack_mask; 1441 __le32 kill_ack_mask;
1429 __le32 kill_cts_mask; 1442 __le32 kill_cts_mask;
1430 __le16 bt_valid; 1443 __le16 bt_valid;
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 4472761fc59..b49819ca2cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -390,21 +390,16 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
390 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal 390 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
391 * operation state. 391 * operation state.
392 */ 392 */
393static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) 393static bool iwl_good_ack_health(struct iwl_priv *priv,
394 struct statistics_tx *cur)
394{ 395{
395 int actual_delta, expected_delta, ba_timeout_delta; 396 int actual_delta, expected_delta, ba_timeout_delta;
396 struct statistics_tx *cur, *old; 397 struct statistics_tx *old;
397 398
398 if (priv->_agn.agg_tids_count) 399 if (priv->_agn.agg_tids_count)
399 return true; 400 return true;
400 401
401 if (iwl_bt_statistics(priv)) { 402 old = &priv->statistics.tx;
402 cur = &pkt->u.stats_bt.tx;
403 old = &priv->_agn.statistics_bt.tx;
404 } else {
405 cur = &pkt->u.stats.tx;
406 old = &priv->_agn.statistics.tx;
407 }
408 403
409 actual_delta = le32_to_cpu(cur->actual_ack_cnt) - 404 actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
410 le32_to_cpu(old->actual_ack_cnt); 405 le32_to_cpu(old->actual_ack_cnt);
@@ -430,10 +425,10 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt
430 * DEBUG is not, these will just compile out. 425 * DEBUG is not, these will just compile out.
431 */ 426 */
432 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", 427 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
433 priv->_agn.delta_statistics.tx.rx_detected_cnt); 428 priv->delta_stats.tx.rx_detected_cnt);
434 IWL_DEBUG_RADIO(priv, 429 IWL_DEBUG_RADIO(priv,
435 "ack_or_ba_timeout_collision delta %d\n", 430 "ack_or_ba_timeout_collision delta %d\n",
436 priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); 431 priv->delta_stats.tx.ack_or_ba_timeout_collision);
437#endif 432#endif
438 433
439 if (ba_timeout_delta >= BA_TIMEOUT_MAX) 434 if (ba_timeout_delta >= BA_TIMEOUT_MAX)
@@ -450,7 +445,9 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt
450 * to improve the throughput. 445 * to improve the throughput.
451 */ 446 */
452static bool iwl_good_plcp_health(struct iwl_priv *priv, 447static bool iwl_good_plcp_health(struct iwl_priv *priv,
453 struct iwl_rx_packet *pkt, unsigned int msecs) 448 struct statistics_rx_phy *cur_ofdm,
449 struct statistics_rx_ht_phy *cur_ofdm_ht,
450 unsigned int msecs)
454{ 451{
455 int delta; 452 int delta;
456 int threshold = priv->cfg->base_params->plcp_delta_threshold; 453 int threshold = priv->cfg->base_params->plcp_delta_threshold;
@@ -460,29 +457,12 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv,
460 return true; 457 return true;
461 } 458 }
462 459
463 if (iwl_bt_statistics(priv)) { 460 delta = le32_to_cpu(cur_ofdm->plcp_err) -
464 struct statistics_rx_bt *cur, *old; 461 le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) +
465 462 le32_to_cpu(cur_ofdm_ht->plcp_err) -
466 cur = &pkt->u.stats_bt.rx; 463 le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err);
467 old = &priv->_agn.statistics_bt.rx;
468
469 delta = le32_to_cpu(cur->ofdm.plcp_err) -
470 le32_to_cpu(old->ofdm.plcp_err) +
471 le32_to_cpu(cur->ofdm_ht.plcp_err) -
472 le32_to_cpu(old->ofdm_ht.plcp_err);
473 } else {
474 struct statistics_rx *cur, *old;
475
476 cur = &pkt->u.stats.rx;
477 old = &priv->_agn.statistics.rx;
478
479 delta = le32_to_cpu(cur->ofdm.plcp_err) -
480 le32_to_cpu(old->ofdm.plcp_err) +
481 le32_to_cpu(cur->ofdm_ht.plcp_err) -
482 le32_to_cpu(old->ofdm_ht.plcp_err);
483 }
484 464
485 /* Can be negative if firmware reseted statistics */ 465 /* Can be negative if firmware reset statistics */
486 if (delta <= 0) 466 if (delta <= 0)
487 return true; 467 return true;
488 468
@@ -497,44 +477,36 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv,
497} 477}
498 478
499static void iwl_recover_from_statistics(struct iwl_priv *priv, 479static void iwl_recover_from_statistics(struct iwl_priv *priv,
500 struct iwl_rx_packet *pkt) 480 struct statistics_rx_phy *cur_ofdm,
481 struct statistics_rx_ht_phy *cur_ofdm_ht,
482 struct statistics_tx *tx,
483 unsigned long stamp)
501{ 484{
502 const struct iwl_mod_params *mod_params = priv->cfg->mod_params; 485 const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
503 unsigned int msecs; 486 unsigned int msecs;
504 unsigned long stamp;
505 487
506 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 488 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
507 return; 489 return;
508 490
509 stamp = jiffies;
510 msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); 491 msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies);
511 492
512 /* Only gather statistics and update time stamp when not associated */ 493 /* Only gather statistics and update time stamp when not associated */
513 if (!iwl_is_any_associated(priv)) 494 if (!iwl_is_any_associated(priv))
514 goto out; 495 return;
515 496
516 /* Do not check/recover when do not have enough statistics data */ 497 /* Do not check/recover when do not have enough statistics data */
517 if (msecs < 99) 498 if (msecs < 99)
518 return; 499 return;
519 500
520 if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { 501 if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) {
521 IWL_ERR(priv, "low ack count detected, restart firmware\n"); 502 IWL_ERR(priv, "low ack count detected, restart firmware\n");
522 if (!iwl_force_reset(priv, IWL_FW_RESET, false)) 503 if (!iwl_force_reset(priv, IWL_FW_RESET, false))
523 return; 504 return;
524 } 505 }
525 506
526 if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs)) 507 if (mod_params->plcp_check &&
508 !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
527 iwl_force_reset(priv, IWL_RF_RESET, false); 509 iwl_force_reset(priv, IWL_RF_RESET, false);
528
529out:
530 if (iwl_bt_statistics(priv))
531 memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
532 sizeof(priv->_agn.statistics_bt));
533 else
534 memcpy(&priv->_agn.statistics, &pkt->u.stats,
535 sizeof(priv->_agn.statistics));
536
537 priv->rx_statistics_jiffies = stamp;
538} 510}
539 511
540/* Calculate noise level, based on measurements during network silence just 512/* Calculate noise level, based on measurements during network silence just
@@ -548,10 +520,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
548 int bcn_silence_a, bcn_silence_b, bcn_silence_c; 520 int bcn_silence_a, bcn_silence_b, bcn_silence_c;
549 int last_rx_noise; 521 int last_rx_noise;
550 522
551 if (iwl_bt_statistics(priv)) 523 rx_info = &priv->statistics.rx_non_phy;
552 rx_info = &(priv->_agn.statistics_bt.rx.general.common); 524
553 else
554 rx_info = &(priv->_agn.statistics.rx.general);
555 bcn_silence_a = 525 bcn_silence_a =
556 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; 526 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
557 bcn_silence_b = 527 bcn_silence_b =
@@ -583,105 +553,153 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
583 last_rx_noise); 553 last_rx_noise);
584} 554}
585 555
556#ifdef CONFIG_IWLWIFI_DEBUGFS
586/* 557/*
587 * based on the assumption of all statistics counter are in DWORD 558 * based on the assumption of all statistics counter are in DWORD
588 * FIXME: This function is for debugging, do not deal with 559 * FIXME: This function is for debugging, do not deal with
589 * the case of counters roll-over. 560 * the case of counters roll-over.
590 */ 561 */
591static void iwl_accumulative_statistics(struct iwl_priv *priv, 562static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta,
592 __le32 *stats) 563 __le32 *max_delta, __le32 *accum, int size)
593{ 564{
594#ifdef CONFIG_IWLWIFI_DEBUGFS 565 int i;
595 int i, size; 566
596 __le32 *prev_stats; 567 for (i = 0;
597 u32 *accum_stats; 568 i < size / sizeof(__le32);
598 u32 *delta, *max_delta; 569 i++, prev++, cur++, delta++, max_delta++, accum++) {
599 struct statistics_general_common *general, *accum_general; 570 if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) {
600 struct statistics_tx *tx, *accum_tx; 571 *delta = cpu_to_le32(
601 572 le32_to_cpu(*cur) - le32_to_cpu(*prev));
602 if (iwl_bt_statistics(priv)) { 573 le32_add_cpu(accum, le32_to_cpu(*delta));
603 prev_stats = (__le32 *)&priv->_agn.statistics_bt; 574 if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta))
604 accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
605 size = sizeof(struct iwl_bt_notif_statistics);
606 general = &priv->_agn.statistics_bt.general.common;
607 accum_general = &priv->_agn.accum_statistics_bt.general.common;
608 tx = &priv->_agn.statistics_bt.tx;
609 accum_tx = &priv->_agn.accum_statistics_bt.tx;
610 delta = (u32 *)&priv->_agn.delta_statistics_bt;
611 max_delta = (u32 *)&priv->_agn.max_delta_bt;
612 } else {
613 prev_stats = (__le32 *)&priv->_agn.statistics;
614 accum_stats = (u32 *)&priv->_agn.accum_statistics;
615 size = sizeof(struct iwl_notif_statistics);
616 general = &priv->_agn.statistics.general.common;
617 accum_general = &priv->_agn.accum_statistics.general.common;
618 tx = &priv->_agn.statistics.tx;
619 accum_tx = &priv->_agn.accum_statistics.tx;
620 delta = (u32 *)&priv->_agn.delta_statistics;
621 max_delta = (u32 *)&priv->_agn.max_delta;
622 }
623 for (i = sizeof(__le32); i < size;
624 i += sizeof(__le32), stats++, prev_stats++, delta++,
625 max_delta++, accum_stats++) {
626 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
627 *delta = (le32_to_cpu(*stats) -
628 le32_to_cpu(*prev_stats));
629 *accum_stats += *delta;
630 if (*delta > *max_delta)
631 *max_delta = *delta; 575 *max_delta = *delta;
632 } 576 }
633 } 577 }
578}
634 579
635 /* reset accumulative statistics for "no-counter" type statistics */ 580static void
636 accum_general->temperature = general->temperature; 581iwl_accumulative_statistics(struct iwl_priv *priv,
637 accum_general->temperature_m = general->temperature_m; 582 struct statistics_general_common *common,
638 accum_general->ttl_timestamp = general->ttl_timestamp; 583 struct statistics_rx_non_phy *rx_non_phy,
639 accum_tx->tx_power.ant_a = tx->tx_power.ant_a; 584 struct statistics_rx_phy *rx_ofdm,
640 accum_tx->tx_power.ant_b = tx->tx_power.ant_b; 585 struct statistics_rx_ht_phy *rx_ofdm_ht,
641 accum_tx->tx_power.ant_c = tx->tx_power.ant_c; 586 struct statistics_rx_phy *rx_cck,
642#endif 587 struct statistics_tx *tx,
588 struct statistics_bt_activity *bt_activity)
589{
590#define ACCUM(_name) \
591 accum_stats((__le32 *)&priv->statistics._name, \
592 (__le32 *)_name, \
593 (__le32 *)&priv->delta_stats._name, \
594 (__le32 *)&priv->max_delta_stats._name, \
595 (__le32 *)&priv->accum_stats._name, \
596 sizeof(*_name));
597
598 ACCUM(common);
599 ACCUM(rx_non_phy);
600 ACCUM(rx_ofdm);
601 ACCUM(rx_ofdm_ht);
602 ACCUM(rx_cck);
603 ACCUM(tx);
604 if (bt_activity)
605 ACCUM(bt_activity);
606#undef ACCUM
643} 607}
608#else
609static inline void
610iwl_accumulative_statistics(struct iwl_priv *priv,
611 struct statistics_general_common *common,
612 struct statistics_rx_non_phy *rx_non_phy,
613 struct statistics_rx_phy *rx_ofdm,
614 struct statistics_rx_ht_phy *rx_ofdm_ht,
615 struct statistics_rx_phy *rx_cck,
616 struct statistics_tx *tx,
617 struct statistics_bt_activity *bt_activity)
618{
619}
620#endif
644 621
645static void iwl_rx_statistics(struct iwl_priv *priv, 622static void iwl_rx_statistics(struct iwl_priv *priv,
646 struct iwl_rx_mem_buffer *rxb) 623 struct iwl_rx_mem_buffer *rxb)
647{ 624{
625 unsigned long stamp = jiffies;
648 const int reg_recalib_period = 60; 626 const int reg_recalib_period = 60;
649 int change; 627 int change;
650 struct iwl_rx_packet *pkt = rxb_addr(rxb); 628 struct iwl_rx_packet *pkt = rxb_addr(rxb);
629 u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
630 __le32 *flag;
631 struct statistics_general_common *common;
632 struct statistics_rx_non_phy *rx_non_phy;
633 struct statistics_rx_phy *rx_ofdm;
634 struct statistics_rx_ht_phy *rx_ofdm_ht;
635 struct statistics_rx_phy *rx_cck;
636 struct statistics_tx *tx;
637 struct statistics_bt_activity *bt_activity;
638
639 len -= sizeof(struct iwl_cmd_header); /* skip header */
640
641 IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
642 len);
643
644 if (len == sizeof(struct iwl_bt_notif_statistics)) {
645 struct iwl_bt_notif_statistics *stats;
646 stats = &pkt->u.stats_bt;
647 flag = &stats->flag;
648 common = &stats->general.common;
649 rx_non_phy = &stats->rx.general.common;
650 rx_ofdm = &stats->rx.ofdm;
651 rx_ofdm_ht = &stats->rx.ofdm_ht;
652 rx_cck = &stats->rx.cck;
653 tx = &stats->tx;
654 bt_activity = &stats->general.activity;
651 655
652 if (iwl_bt_statistics(priv)) { 656#ifdef CONFIG_IWLWIFI_DEBUGFS
653 IWL_DEBUG_RX(priv, 657 /* handle this exception directly */
654 "Statistics notification received (%d vs %d).\n", 658 priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills;
655 (int)sizeof(struct iwl_bt_notif_statistics), 659 le32_add_cpu(&priv->statistics.accum_num_bt_kills,
656 le32_to_cpu(pkt->len_n_flags) & 660 le32_to_cpu(stats->rx.general.num_bt_kills));
657 FH_RSCSR_FRAME_SIZE_MSK); 661#endif
658 662 } else if (len == sizeof(struct iwl_notif_statistics)) {
659 change = ((priv->_agn.statistics_bt.general.common.temperature != 663 struct iwl_notif_statistics *stats;
660 pkt->u.stats_bt.general.common.temperature) || 664 stats = &pkt->u.stats;
661 ((priv->_agn.statistics_bt.flag & 665 flag = &stats->flag;
662 STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 666 common = &stats->general.common;
663 (pkt->u.stats_bt.flag & 667 rx_non_phy = &stats->rx.general;
664 STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 668 rx_ofdm = &stats->rx.ofdm;
665 669 rx_ofdm_ht = &stats->rx.ofdm_ht;
666 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); 670 rx_cck = &stats->rx.cck;
671 tx = &stats->tx;
672 bt_activity = NULL;
667 } else { 673 } else {
668 IWL_DEBUG_RX(priv, 674 WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
669 "Statistics notification received (%d vs %d).\n", 675 len, sizeof(struct iwl_bt_notif_statistics),
670 (int)sizeof(struct iwl_notif_statistics), 676 sizeof(struct iwl_notif_statistics));
671 le32_to_cpu(pkt->len_n_flags) & 677 return;
672 FH_RSCSR_FRAME_SIZE_MSK);
673
674 change = ((priv->_agn.statistics.general.common.temperature !=
675 pkt->u.stats.general.common.temperature) ||
676 ((priv->_agn.statistics.flag &
677 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
678 (pkt->u.stats.flag &
679 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
680
681 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
682 } 678 }
683 679
684 iwl_recover_from_statistics(priv, pkt); 680 change = common->temperature != priv->statistics.common.temperature ||
681 (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
682 (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK);
683
684 iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm,
685 rx_ofdm_ht, rx_cck, tx, bt_activity);
686
687 iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp);
688
689 priv->statistics.flag = *flag;
690 memcpy(&priv->statistics.common, common, sizeof(*common));
691 memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy));
692 memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm));
693 memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht));
694 memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck));
695 memcpy(&priv->statistics.tx, tx, sizeof(*tx));
696#ifdef CONFIG_IWLWIFI_DEBUGFS
697 if (bt_activity)
698 memcpy(&priv->statistics.bt_activity, bt_activity,
699 sizeof(*bt_activity));
700#endif
701
702 priv->rx_statistics_jiffies = stamp;
685 703
686 set_bit(STATUS_STATISTICS, &priv->status); 704 set_bit(STATUS_STATISTICS, &priv->status);
687 705
@@ -708,18 +726,12 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv,
708 726
709 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 727 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
710#ifdef CONFIG_IWLWIFI_DEBUGFS 728#ifdef CONFIG_IWLWIFI_DEBUGFS
711 memset(&priv->_agn.accum_statistics, 0, 729 memset(&priv->accum_stats, 0,
712 sizeof(struct iwl_notif_statistics)); 730 sizeof(priv->accum_stats));
713 memset(&priv->_agn.delta_statistics, 0, 731 memset(&priv->delta_stats, 0,
714 sizeof(struct iwl_notif_statistics)); 732 sizeof(priv->delta_stats));
715 memset(&priv->_agn.max_delta, 0, 733 memset(&priv->max_delta_stats, 0,
716 sizeof(struct iwl_notif_statistics)); 734 sizeof(priv->max_delta_stats));
717 memset(&priv->_agn.accum_statistics_bt, 0,
718 sizeof(struct iwl_bt_notif_statistics));
719 memset(&priv->_agn.delta_statistics_bt, 0,
720 sizeof(struct iwl_bt_notif_statistics));
721 memset(&priv->_agn.max_delta_bt, 0,
722 sizeof(struct iwl_bt_notif_statistics));
723#endif 735#endif
724 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 736 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
725 } 737 }