aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-07-14 11:08:57 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-07-23 11:41:18 -0400
commit7980fba54ec42f7c206b2bb469baeb3a0a2e8a93 (patch)
treea51924951f40f302009dd9ae9869a09d9303d61c /drivers
parentaf8ee0553b4ce077319190cde680d74ad18ddfad (diff)
iwlagn: Add support for bluetooth statistics notification
WiFi/BT combo devices has different statistics notification structure, adding the support here to make sure the structure align correctly. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c134
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c167
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
7 files changed, 271 insertions, 119 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 90033e8752bb..c4c5691032a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -605,8 +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, 608void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
609 struct iwl_notif_statistics *resp)
610{ 609{
611 u32 rx_enable_time; 610 u32 rx_enable_time;
612 u32 fa_cck; 611 u32 fa_cck;
@@ -616,8 +615,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
616 u32 norm_fa_ofdm; 615 u32 norm_fa_ofdm;
617 u32 norm_fa_cck; 616 u32 norm_fa_cck;
618 struct iwl_sensitivity_data *data = NULL; 617 struct iwl_sensitivity_data *data = NULL;
619 struct statistics_rx_non_phy *rx_info = &(resp->rx.general); 618 struct statistics_rx_non_phy *rx_info;
620 struct statistics_rx *statistics = &(resp->rx); 619 struct statistics_rx_phy *ofdm, *cck;
621 unsigned long flags; 620 unsigned long flags;
622 struct statistics_general_data statis; 621 struct statistics_general_data statis;
623 622
@@ -632,6 +631,16 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
632 } 631 }
633 632
634 spin_lock_irqsave(&priv->lock, flags); 633 spin_lock_irqsave(&priv->lock, flags);
634 if (priv->cfg->bt_statistics) {
635 rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
636 rx.general.common);
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 }
635 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { 644 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
636 IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); 645 IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
637 spin_unlock_irqrestore(&priv->lock, flags); 646 spin_unlock_irqrestore(&priv->lock, flags);
@@ -640,23 +649,23 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
640 649
641 /* Extract Statistics: */ 650 /* Extract Statistics: */
642 rx_enable_time = le32_to_cpu(rx_info->channel_load); 651 rx_enable_time = le32_to_cpu(rx_info->channel_load);
643 fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt); 652 fa_cck = le32_to_cpu(cck->false_alarm_cnt);
644 fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt); 653 fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt);
645 bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err); 654 bad_plcp_cck = le32_to_cpu(cck->plcp_err);
646 bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err); 655 bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err);
647 656
648 statis.beacon_silence_rssi_a = 657 statis.beacon_silence_rssi_a =
649 le32_to_cpu(statistics->general.beacon_silence_rssi_a); 658 le32_to_cpu(rx_info->beacon_silence_rssi_a);
650 statis.beacon_silence_rssi_b = 659 statis.beacon_silence_rssi_b =
651 le32_to_cpu(statistics->general.beacon_silence_rssi_b); 660 le32_to_cpu(rx_info->beacon_silence_rssi_b);
652 statis.beacon_silence_rssi_c = 661 statis.beacon_silence_rssi_c =
653 le32_to_cpu(statistics->general.beacon_silence_rssi_c); 662 le32_to_cpu(rx_info->beacon_silence_rssi_c);
654 statis.beacon_energy_a = 663 statis.beacon_energy_a =
655 le32_to_cpu(statistics->general.beacon_energy_a); 664 le32_to_cpu(rx_info->beacon_energy_a);
656 statis.beacon_energy_b = 665 statis.beacon_energy_b =
657 le32_to_cpu(statistics->general.beacon_energy_b); 666 le32_to_cpu(rx_info->beacon_energy_b);
658 statis.beacon_energy_c = 667 statis.beacon_energy_c =
659 le32_to_cpu(statistics->general.beacon_energy_c); 668 le32_to_cpu(rx_info->beacon_energy_c);
660 669
661 spin_unlock_irqrestore(&priv->lock, flags); 670 spin_unlock_irqrestore(&priv->lock, flags);
662 671
@@ -728,8 +737,7 @@ static inline u8 find_first_chain(u8 mask)
728 * 1) Which antennas are connected. 737 * 1) Which antennas are connected.
729 * 2) Differential rx gain settings to balance the 3 receivers. 738 * 2) Differential rx gain settings to balance the 3 receivers.
730 */ 739 */
731void iwl_chain_noise_calibration(struct iwl_priv *priv, 740void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
732 struct iwl_notif_statistics *stat_resp)
733{ 741{
734 struct iwl_chain_noise_data *data = NULL; 742 struct iwl_chain_noise_data *data = NULL;
735 743
@@ -753,7 +761,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
753 u32 active_chains = 0; 761 u32 active_chains = 0;
754 u8 num_tx_chains; 762 u8 num_tx_chains;
755 unsigned long flags; 763 unsigned long flags;
756 struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general); 764 struct statistics_rx_non_phy *rx_info;
757 u8 first_chain; 765 u8 first_chain;
758 766
759 if (priv->disable_chain_noise_cal) 767 if (priv->disable_chain_noise_cal)
@@ -772,6 +780,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
772 } 780 }
773 781
774 spin_lock_irqsave(&priv->lock, flags); 782 spin_lock_irqsave(&priv->lock, flags);
783 if (priv->cfg->bt_statistics) {
784 rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
785 rx.general.common);
786 } else {
787 rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
788 rx.general);
789 }
775 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { 790 if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
776 IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); 791 IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
777 spin_unlock_irqrestore(&priv->lock, flags); 792 spin_unlock_irqrestore(&priv->lock, flags);
@@ -780,8 +795,19 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
780 795
781 rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK); 796 rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
782 rxon_chnum = le16_to_cpu(priv->staging_rxon.channel); 797 rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
783 stat_band24 = !!(stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); 798 if (priv->cfg->bt_statistics) {
784 stat_chnum = le32_to_cpu(stat_resp->flag) >> 16; 799 stat_band24 = !!(((struct iwl_bt_notif_statistics *)
800 stat_resp)->flag &
801 STATISTICS_REPLY_FLG_BAND_24G_MSK);
802 stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
803 stat_resp)->flag) >> 16;
804 } else {
805 stat_band24 = !!(((struct iwl_notif_statistics *)
806 stat_resp)->flag &
807 STATISTICS_REPLY_FLG_BAND_24G_MSK);
808 stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
809 stat_resp)->flag) >> 16;
810 }
785 811
786 /* Make sure we accumulate data for just the associated channel 812 /* Make sure we accumulate data for just the associated channel
787 * (even if scanning). */ 813 * (even if scanning). */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index 11dd1f736bed..19d1e5e86261 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -31,21 +31,24 @@
31static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) 31static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
32{ 32{
33 int p = 0; 33 int p = 0;
34 u32 flag;
34 35
35 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", 36 if (priv->cfg->bt_statistics)
36 le32_to_cpu(priv->_agn.statistics.flag)); 37 flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
37 if (le32_to_cpu(priv->_agn.statistics.flag) & 38 else
38 UCODE_STATISTICS_CLEAR_MSK) 39 flag = le32_to_cpu(priv->_agn.statistics.flag);
40
41 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
42 if (flag & UCODE_STATISTICS_CLEAR_MSK)
39 p += scnprintf(buf + p, bufsz - p, 43 p += scnprintf(buf + p, bufsz - p,
40 "\tStatistics have been cleared\n"); 44 "\tStatistics have been cleared\n");
41 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", 45 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
42 (le32_to_cpu(priv->_agn.statistics.flag) & 46 (flag & UCODE_STATISTICS_FREQUENCY_MSK)
43 UCODE_STATISTICS_FREQUENCY_MSK) 47 ? "2.4 GHz" : "5.2 GHz");
44 ? "2.4 GHz" : "5.2 GHz");
45 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", 48 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
46 (le32_to_cpu(priv->_agn.statistics.flag) & 49 (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
47 UCODE_STATISTICS_NARROW_BAND_MSK) 50 ? "enabled" : "disabled");
48 ? "enabled" : "disabled"); 51
49 return p; 52 return p;
50} 53}
51 54
@@ -79,22 +82,43 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
79 * the last statistics notification from uCode 82 * the last statistics notification from uCode
80 * might not reflect the current uCode activity 83 * might not reflect the current uCode activity
81 */ 84 */
82 ofdm = &priv->_agn.statistics.rx.ofdm; 85 if (priv->cfg->bt_statistics) {
83 cck = &priv->_agn.statistics.rx.cck; 86 ofdm = &priv->_agn.statistics_bt.rx.ofdm;
84 general = &priv->_agn.statistics.rx.general; 87 cck = &priv->_agn.statistics_bt.rx.cck;
85 ht = &priv->_agn.statistics.rx.ofdm_ht; 88 general = &priv->_agn.statistics_bt.rx.general.common;
86 accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm; 89 ht = &priv->_agn.statistics_bt.rx.ofdm_ht;
87 accum_cck = &priv->_agn.accum_statistics.rx.cck; 90 accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm;
88 accum_general = &priv->_agn.accum_statistics.rx.general; 91 accum_cck = &priv->_agn.accum_statistics_bt.rx.cck;
89 accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht; 92 accum_general =
90 delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm; 93 &priv->_agn.accum_statistics_bt.rx.general.common;
91 delta_cck = &priv->_agn.delta_statistics.rx.cck; 94 accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht;
92 delta_general = &priv->_agn.delta_statistics.rx.general; 95 delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm;
93 delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht; 96 delta_cck = &priv->_agn.delta_statistics_bt.rx.cck;
94 max_ofdm = &priv->_agn.max_delta.rx.ofdm; 97 delta_general =
95 max_cck = &priv->_agn.max_delta.rx.cck; 98 &priv->_agn.delta_statistics_bt.rx.general.common;
96 max_general = &priv->_agn.max_delta.rx.general; 99 delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht;
97 max_ht = &priv->_agn.max_delta.rx.ofdm_ht; 100 max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm;
101 max_cck = &priv->_agn.max_delta_bt.rx.cck;
102 max_general = &priv->_agn.max_delta_bt.rx.general.common;
103 max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
104 } else {
105 ofdm = &priv->_agn.statistics.rx.ofdm;
106 cck = &priv->_agn.statistics.rx.cck;
107 general = &priv->_agn.statistics.rx.general;
108 ht = &priv->_agn.statistics.rx.ofdm_ht;
109 accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
110 accum_cck = &priv->_agn.accum_statistics.rx.cck;
111 accum_general = &priv->_agn.accum_statistics.rx.general;
112 accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
113 delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
114 delta_cck = &priv->_agn.delta_statistics.rx.cck;
115 delta_general = &priv->_agn.delta_statistics.rx.general;
116 delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
117 max_ofdm = &priv->_agn.max_delta.rx.ofdm;
118 max_cck = &priv->_agn.max_delta.rx.cck;
119 max_general = &priv->_agn.max_delta.rx.general;
120 max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
121 }
98 122
99 pos += iwl_statistics_flag(priv, buf, bufsz); 123 pos += iwl_statistics_flag(priv, buf, bufsz);
100 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 124 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
@@ -560,10 +584,18 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
560 * the last statistics notification from uCode 584 * the last statistics notification from uCode
561 * might not reflect the current uCode activity 585 * might not reflect the current uCode activity
562 */ 586 */
563 tx = &priv->_agn.statistics.tx; 587 if (priv->cfg->bt_statistics) {
564 accum_tx = &priv->_agn.accum_statistics.tx; 588 tx = &priv->_agn.statistics_bt.tx;
565 delta_tx = &priv->_agn.delta_statistics.tx; 589 accum_tx = &priv->_agn.accum_statistics_bt.tx;
566 max_tx = &priv->_agn.max_delta.tx; 590 delta_tx = &priv->_agn.delta_statistics_bt.tx;
591 max_tx = &priv->_agn.max_delta_bt.tx;
592 } else {
593 tx = &priv->_agn.statistics.tx;
594 accum_tx = &priv->_agn.accum_statistics.tx;
595 delta_tx = &priv->_agn.delta_statistics.tx;
596 max_tx = &priv->_agn.max_delta.tx;
597 }
598
567 pos += iwl_statistics_flag(priv, buf, bufsz); 599 pos += iwl_statistics_flag(priv, buf, bufsz);
568 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 600 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
569 "acumulative delta max\n", 601 "acumulative delta max\n",
@@ -777,18 +809,34 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
777 * the last statistics notification from uCode 809 * the last statistics notification from uCode
778 * might not reflect the current uCode activity 810 * might not reflect the current uCode activity
779 */ 811 */
780 general = &priv->_agn.statistics.general.common; 812 if (priv->cfg->bt_statistics) {
781 dbg = &priv->_agn.statistics.general.common.dbg; 813 general = &priv->_agn.statistics_bt.general.common;
782 div = &priv->_agn.statistics.general.common.div; 814 dbg = &priv->_agn.statistics_bt.general.common.dbg;
783 accum_general = &priv->_agn.accum_statistics.general.common; 815 div = &priv->_agn.statistics_bt.general.common.div;
784 delta_general = &priv->_agn.delta_statistics.general.common; 816 accum_general = &priv->_agn.accum_statistics_bt.general.common;
785 max_general = &priv->_agn.max_delta.general.common; 817 accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg;
786 accum_dbg = &priv->_agn.accum_statistics.general.common.dbg; 818 accum_div = &priv->_agn.accum_statistics_bt.general.common.div;
787 delta_dbg = &priv->_agn.delta_statistics.general.common.dbg; 819 delta_general = &priv->_agn.delta_statistics_bt.general.common;
788 max_dbg = &priv->_agn.max_delta.general.common.dbg; 820 max_general = &priv->_agn.max_delta_bt.general.common;
789 accum_div = &priv->_agn.accum_statistics.general.common.div; 821 delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg;
790 delta_div = &priv->_agn.delta_statistics.general.common.div; 822 max_dbg = &priv->_agn.max_delta_bt.general.common.dbg;
791 max_div = &priv->_agn.max_delta.general.common.div; 823 delta_div = &priv->_agn.delta_statistics_bt.general.common.div;
824 max_div = &priv->_agn.max_delta_bt.general.common.div;
825 } else {
826 general = &priv->_agn.statistics.general.common;
827 dbg = &priv->_agn.statistics.general.common.dbg;
828 div = &priv->_agn.statistics.general.common.div;
829 accum_general = &priv->_agn.accum_statistics.general.common;
830 accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
831 accum_div = &priv->_agn.accum_statistics.general.common.div;
832 delta_general = &priv->_agn.delta_statistics.general.common;
833 max_general = &priv->_agn.max_delta.general.common;
834 delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
835 max_dbg = &priv->_agn.max_delta.general.common.dbg;
836 delta_div = &priv->_agn.delta_statistics.general.common.div;
837 max_div = &priv->_agn.max_delta.general.common.div;
838 }
839
792 pos += iwl_statistics_flag(priv, buf, bufsz); 840 pos += iwl_statistics_flag(priv, buf, bufsz);
793 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 841 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
794 "acumulative delta max\n", 842 "acumulative delta max\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 249b77bbf638..9490eced1198 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -67,17 +67,22 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
67 * exactly when to expect beacons, therefore only when we're associated. */ 67 * exactly when to expect beacons, therefore only when we're associated. */
68static void iwl_rx_calc_noise(struct iwl_priv *priv) 68static void iwl_rx_calc_noise(struct iwl_priv *priv)
69{ 69{
70 struct statistics_rx_non_phy *rx_info 70 struct statistics_rx_non_phy *rx_info;
71 = &(priv->_agn.statistics.rx.general);
72 int num_active_rx = 0; 71 int num_active_rx = 0;
73 int total_silence = 0; 72 int total_silence = 0;
74 int bcn_silence_a = 73 int bcn_silence_a, bcn_silence_b, bcn_silence_c;
74 int last_rx_noise;
75
76 if (priv->cfg->bt_statistics)
77 rx_info = &(priv->_agn.statistics_bt.rx.general.common);
78 else
79 rx_info = &(priv->_agn.statistics.rx.general);
80 bcn_silence_a =
75 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; 81 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
76 int bcn_silence_b = 82 bcn_silence_b =
77 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; 83 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
78 int bcn_silence_c = 84 bcn_silence_c =
79 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; 85 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
80 int last_rx_noise;
81 86
82 if (bcn_silence_a) { 87 if (bcn_silence_a) {
83 total_silence += bcn_silence_a; 88 total_silence += bcn_silence_a;
@@ -112,17 +117,35 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
112static void iwl_accumulative_statistics(struct iwl_priv *priv, 117static void iwl_accumulative_statistics(struct iwl_priv *priv,
113 __le32 *stats) 118 __le32 *stats)
114{ 119{
115 int i; 120 int i, size;
116 __le32 *prev_stats; 121 __le32 *prev_stats;
117 u32 *accum_stats; 122 u32 *accum_stats;
118 u32 *delta, *max_delta; 123 u32 *delta, *max_delta;
124 struct statistics_general_common *general, *accum_general;
125 struct statistics_tx *tx, *accum_tx;
119 126
120 prev_stats = (__le32 *)&priv->_agn.statistics; 127 if (priv->cfg->bt_statistics) {
121 accum_stats = (u32 *)&priv->_agn.accum_statistics; 128 prev_stats = (__le32 *)&priv->_agn.statistics_bt;
122 delta = (u32 *)&priv->_agn.delta_statistics; 129 accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
123 max_delta = (u32 *)&priv->_agn.max_delta; 130 size = sizeof(struct iwl_bt_notif_statistics);
124 131 general = &priv->_agn.statistics_bt.general.common;
125 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 132 accum_general = &priv->_agn.accum_statistics_bt.general.common;
133 tx = &priv->_agn.statistics_bt.tx;
134 accum_tx = &priv->_agn.accum_statistics_bt.tx;
135 delta = (u32 *)&priv->_agn.delta_statistics_bt;
136 max_delta = (u32 *)&priv->_agn.max_delta_bt;
137 } else {
138 prev_stats = (__le32 *)&priv->_agn.statistics;
139 accum_stats = (u32 *)&priv->_agn.accum_statistics;
140 size = sizeof(struct iwl_notif_statistics);
141 general = &priv->_agn.statistics.general.common;
142 accum_general = &priv->_agn.accum_statistics.general.common;
143 tx = &priv->_agn.statistics.tx;
144 accum_tx = &priv->_agn.accum_statistics.tx;
145 delta = (u32 *)&priv->_agn.delta_statistics;
146 max_delta = (u32 *)&priv->_agn.max_delta;
147 }
148 for (i = sizeof(__le32); i < size;
126 i += sizeof(__le32), stats++, prev_stats++, delta++, 149 i += sizeof(__le32), stats++, prev_stats++, delta++,
127 max_delta++, accum_stats++) { 150 max_delta++, accum_stats++) {
128 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { 151 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
@@ -135,18 +158,12 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
135 } 158 }
136 159
137 /* reset accumulative statistics for "no-counter" type statistics */ 160 /* reset accumulative statistics for "no-counter" type statistics */
138 priv->_agn.accum_statistics.general.common.temperature = 161 accum_general->temperature = general->temperature;
139 priv->_agn.statistics.general.common.temperature; 162 accum_general->temperature_m = general->temperature_m;
140 priv->_agn.accum_statistics.general.common.temperature_m = 163 accum_general->ttl_timestamp = general->ttl_timestamp;
141 priv->_agn.statistics.general.common.temperature_m; 164 accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
142 priv->_agn.accum_statistics.general.common.ttl_timestamp = 165 accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
143 priv->_agn.statistics.general.common.ttl_timestamp; 166 accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
144 priv->_agn.accum_statistics.tx.tx_power.ant_a =
145 priv->_agn.statistics.tx.tx_power.ant_a;
146 priv->_agn.accum_statistics.tx.tx_power.ant_b =
147 priv->_agn.statistics.tx.tx_power.ant_b;
148 priv->_agn.accum_statistics.tx.tx_power.ant_c =
149 priv->_agn.statistics.tx.tx_power.ant_c;
150} 167}
151#endif 168#endif
152 169
@@ -185,11 +202,30 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
185 * by zero. 202 * by zero.
186 */ 203 */
187 if (plcp_msec) { 204 if (plcp_msec) {
188 combined_plcp_delta = 205 struct statistics_rx_phy *ofdm;
189 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - 206 struct statistics_rx_ht_phy *ofdm_ht;
190 le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) + 207
191 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - 208 if (priv->cfg->bt_statistics) {
192 le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err)); 209 ofdm = &pkt->u.stats_bt.rx.ofdm;
210 ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
211 combined_plcp_delta =
212 (le32_to_cpu(ofdm->plcp_err) -
213 le32_to_cpu(priv->_agn.statistics_bt.
214 rx.ofdm.plcp_err)) +
215 (le32_to_cpu(ofdm_ht->plcp_err) -
216 le32_to_cpu(priv->_agn.statistics_bt.
217 rx.ofdm_ht.plcp_err));
218 } else {
219 ofdm = &pkt->u.stats.rx.ofdm;
220 ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
221 combined_plcp_delta =
222 (le32_to_cpu(ofdm->plcp_err) -
223 le32_to_cpu(priv->_agn.statistics.
224 rx.ofdm.plcp_err)) +
225 (le32_to_cpu(ofdm_ht->plcp_err) -
226 le32_to_cpu(priv->_agn.statistics.
227 rx.ofdm_ht.plcp_err));
228 }
193 229
194 if ((combined_plcp_delta > 0) && 230 if ((combined_plcp_delta > 0) &&
195 ((combined_plcp_delta * 100) / plcp_msec) > 231 ((combined_plcp_delta * 100) / plcp_msec) >
@@ -206,15 +242,14 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
206 * plcp_msec 242 * plcp_msec
207 */ 243 */
208 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " 244 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
209 "%u, %u, %u, %u, %d, %u mSecs\n", 245 "%u, %u, %u, %u, %d, %u mSecs\n",
210 priv->cfg->plcp_delta_threshold, 246 priv->cfg->plcp_delta_threshold,
211 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), 247 le32_to_cpu(ofdm->plcp_err),
212 le32_to_cpu( 248 le32_to_cpu(ofdm->plcp_err),
213 priv->_agn.statistics.rx.ofdm.plcp_err), 249 le32_to_cpu(ofdm_ht->plcp_err),
214 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), 250 le32_to_cpu(ofdm_ht->plcp_err),
215 le32_to_cpu( 251 combined_plcp_delta, plcp_msec);
216 priv->_agn.statistics.rx.ofdm_ht.plcp_err), 252
217 combined_plcp_delta, plcp_msec);
218 rc = false; 253 rc = false;
219 } 254 }
220 } 255 }
@@ -227,24 +262,50 @@ void iwl_rx_statistics(struct iwl_priv *priv,
227 int change; 262 int change;
228 struct iwl_rx_packet *pkt = rxb_addr(rxb); 263 struct iwl_rx_packet *pkt = rxb_addr(rxb);
229 264
265 if (priv->cfg->bt_statistics) {
266 IWL_DEBUG_RX(priv,
267 "Statistics notification received (%d vs %d).\n",
268 (int)sizeof(struct iwl_bt_notif_statistics),
269 le32_to_cpu(pkt->len_n_flags) &
270 FH_RSCSR_FRAME_SIZE_MSK);
230 271
231 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 272 change = ((priv->_agn.statistics_bt.general.common.temperature !=
232 (int)sizeof(priv->_agn.statistics), 273 pkt->u.stats_bt.general.common.temperature) ||
233 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 274 ((priv->_agn.statistics_bt.flag &
275 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
276 (pkt->u.stats_bt.flag &
277 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
278#ifdef CONFIG_IWLWIFI_DEBUGFS
279 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
280#endif
234 281
235 change = ((priv->_agn.statistics.general.common.temperature != 282 } else {
236 pkt->u.stats.general.common.temperature) || 283 IWL_DEBUG_RX(priv,
237 ((priv->_agn.statistics.flag & 284 "Statistics notification received (%d vs %d).\n",
238 STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 285 (int)sizeof(struct iwl_notif_statistics),
239 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 286 le32_to_cpu(pkt->len_n_flags) &
287 FH_RSCSR_FRAME_SIZE_MSK);
240 288
289 change = ((priv->_agn.statistics.general.common.temperature !=
290 pkt->u.stats.general.common.temperature) ||
291 ((priv->_agn.statistics.flag &
292 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
293 (pkt->u.stats.flag &
294 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
241#ifdef CONFIG_IWLWIFI_DEBUGFS 295#ifdef CONFIG_IWLWIFI_DEBUGFS
242 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 296 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
243#endif 297#endif
298
299 }
300
244 iwl_recover_from_statistics(priv, pkt); 301 iwl_recover_from_statistics(priv, pkt);
245 302
246 memcpy(&priv->_agn.statistics, &pkt->u.stats, 303 if (priv->cfg->bt_statistics)
247 sizeof(priv->_agn.statistics)); 304 memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
305 sizeof(priv->_agn.statistics_bt));
306 else
307 memcpy(&priv->_agn.statistics, &pkt->u.stats,
308 sizeof(priv->_agn.statistics));
248 309
249 set_bit(STATUS_STATISTICS, &priv->status); 310 set_bit(STATUS_STATISTICS, &priv->status);
250 311
@@ -277,6 +338,12 @@ void iwl_reply_statistics(struct iwl_priv *priv,
277 sizeof(struct iwl_notif_statistics)); 338 sizeof(struct iwl_notif_statistics));
278 memset(&priv->_agn.max_delta, 0, 339 memset(&priv->_agn.max_delta, 0,
279 sizeof(struct iwl_notif_statistics)); 340 sizeof(struct iwl_notif_statistics));
341 memset(&priv->_agn.accum_statistics_bt, 0,
342 sizeof(struct iwl_bt_notif_statistics));
343 memset(&priv->_agn.delta_statistics_bt, 0,
344 sizeof(struct iwl_bt_notif_statistics));
345 memset(&priv->_agn.max_delta_bt, 0,
346 sizeof(struct iwl_bt_notif_statistics));
280#endif 347#endif
281 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 348 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
282 } 349 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 7391c63fb024..33a8f13ffe0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3008,9 +3008,17 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
3008 } 3008 }
3009 3009
3010 if (priv->start_calib) { 3010 if (priv->start_calib) {
3011 iwl_chain_noise_calibration(priv, &priv->_agn.statistics); 3011 if (priv->cfg->bt_statistics) {
3012 3012 iwl_chain_noise_calibration(priv,
3013 iwl_sensitivity_calibration(priv, &priv->_agn.statistics); 3013 (void *)&priv->_agn.statistics_bt);
3014 iwl_sensitivity_calibration(priv,
3015 (void *)&priv->_agn.statistics_bt);
3016 } else {
3017 iwl_chain_noise_calibration(priv,
3018 (void *)&priv->_agn.statistics);
3019 iwl_sensitivity_calibration(priv,
3020 (void *)&priv->_agn.statistics);
3021 }
3014 } 3022 }
3015 3023
3016 mutex_unlock(&priv->mutex); 3024 mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index 2b7b1df83ba0..ba9523fbb300 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -66,10 +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, 69void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
70 struct iwl_notif_statistics *stat_resp); 70void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
71void iwl_sensitivity_calibration(struct iwl_priv *priv,
72 struct iwl_notif_statistics *resp);
73 71
74void iwl_init_sensitivity(struct iwl_priv *priv); 72void iwl_init_sensitivity(struct iwl_priv *priv);
75void 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-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 4be90637b568..04b2e2987f1e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3988,6 +3988,7 @@ struct iwl_rx_packet {
3988 struct iwl_sleep_notification sleep_notif; 3988 struct iwl_sleep_notification sleep_notif;
3989 struct iwl_spectrum_resp spectrum; 3989 struct iwl_spectrum_resp spectrum;
3990 struct iwl_notif_statistics stats; 3990 struct iwl_notif_statistics stats;
3991 struct iwl_bt_notif_statistics stats_bt;
3991 struct iwl_compressed_ba_resp compressed_ba; 3992 struct iwl_compressed_ba_resp compressed_ba;
3992 struct iwl_missed_beacon_notif missed_beacon; 3993 struct iwl_missed_beacon_notif missed_beacon;
3993 struct iwl_coex_medium_notification coex_medium_notif; 3994 struct iwl_coex_medium_notification coex_medium_notif;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index dff1b17d5ea8..297f8d1f5cb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1322,10 +1322,14 @@ struct iwl_priv {
1322 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; 1322 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1323 1323
1324 struct iwl_notif_statistics statistics; 1324 struct iwl_notif_statistics statistics;
1325 struct iwl_bt_notif_statistics statistics_bt;
1325#ifdef CONFIG_IWLWIFI_DEBUGFS 1326#ifdef CONFIG_IWLWIFI_DEBUGFS
1326 struct iwl_notif_statistics accum_statistics; 1327 struct iwl_notif_statistics accum_statistics;
1327 struct iwl_notif_statistics delta_statistics; 1328 struct iwl_notif_statistics delta_statistics;
1328 struct iwl_notif_statistics max_delta; 1329 struct iwl_notif_statistics max_delta;
1330 struct iwl_bt_notif_statistics accum_statistics_bt;
1331 struct iwl_bt_notif_statistics delta_statistics_bt;
1332 struct iwl_bt_notif_statistics max_delta_bt;
1329#endif 1333#endif
1330 } _agn; 1334 } _agn;
1331#endif 1335#endif