aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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 805b0394850e..a31314fdb053 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 357137f08632..7c286662d26a 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 8847b2113978..064981345c84 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 7b761de77b0a..0f6bb9b2e642 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 ef4d5079a7ed..4ef4dd934254 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 d1834aa7edf0..71a5f31cd7cc 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 bc5dfe2978f0..e741128842bb 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 23b89c2e71da..20499b764430 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 a1a5c1b23096..0edba8a6419b 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 57763c013ca9..6988335328e8 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 c02f06901f8c..897efacb96eb 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 7fe68f8dd210..e84534c4d956 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 4472761fc591..b49819ca2cd6 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 }