diff options
author | Avri Altman <avri.altman@intel.com> | 2013-07-08 18:42:17 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-07-31 05:04:49 -0400 |
commit | a2d7b870d0c99abefe7c302a92f62f0a9aced3b3 (patch) | |
tree | b4e42cca1dd927ed8160d8c31391b79489b2ec25 | |
parent | 26e05cc32d4dab8ad939fd1318bc470d737a20ca (diff) |
iwlwifi: mvm: new api to get signal strength
A new API that replaces the rx signal strength calculation via agc & rssi.
The energy is now calculated outside the driver and transferred by the fw.
Signed-off-by: Avri Altman <avri.altman@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fw.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/fw-api.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rx.c | 41 |
3 files changed, 46 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index f26f12689969..46dc38a32115 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -75,14 +75,16 @@ | |||
75 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | 75 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. |
76 | * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS | 76 | * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS |
77 | * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD | 77 | * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD |
78 | * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api | ||
78 | */ | 79 | */ |
79 | enum iwl_ucode_tlv_flag { | 80 | enum iwl_ucode_tlv_flag { |
80 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | 81 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), |
81 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | 82 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), |
82 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | 83 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), |
83 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | 84 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), |
84 | IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), | 85 | IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), |
85 | IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6), | 86 | IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6), |
87 | IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8), | ||
86 | }; | 88 | }; |
87 | 89 | ||
88 | /* The default calibrate table size if not specified by firmware file */ | 90 | /* The default calibrate table size if not specified by firmware file */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 44614f5e4485..28cab821c9f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -768,6 +768,14 @@ struct iwl_phy_context_cmd { | |||
768 | } __packed; /* PHY_CONTEXT_CMD_API_VER_1 */ | 768 | } __packed; /* PHY_CONTEXT_CMD_API_VER_1 */ |
769 | 769 | ||
770 | #define IWL_RX_INFO_PHY_CNT 8 | 770 | #define IWL_RX_INFO_PHY_CNT 8 |
771 | #define IWL_RX_INFO_ENERGY_ANT_ABC_IDX 1 | ||
772 | #define IWL_RX_INFO_ENERGY_ANT_A_MSK 0x000000ff | ||
773 | #define IWL_RX_INFO_ENERGY_ANT_B_MSK 0x0000ff00 | ||
774 | #define IWL_RX_INFO_ENERGY_ANT_C_MSK 0x00ff0000 | ||
775 | #define IWL_RX_INFO_ENERGY_ANT_A_POS 0 | ||
776 | #define IWL_RX_INFO_ENERGY_ANT_B_POS 8 | ||
777 | #define IWL_RX_INFO_ENERGY_ANT_C_POS 16 | ||
778 | |||
771 | #define IWL_RX_INFO_AGC_IDX 1 | 779 | #define IWL_RX_INFO_AGC_IDX 1 |
772 | #define IWL_RX_INFO_RSSI_AB_IDX 2 | 780 | #define IWL_RX_INFO_RSSI_AB_IDX 2 |
773 | #define IWL_OFDM_AGC_A_MSK 0x0000007f | 781 | #define IWL_OFDM_AGC_A_MSK 0x0000007f |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index e4930d5027d2..c8e4af23d04c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
@@ -124,10 +124,6 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, | |||
124 | ieee80211_rx_ni(mvm->hw, skb); | 124 | ieee80211_rx_ni(mvm->hw, skb); |
125 | } | 125 | } |
126 | 126 | ||
127 | /* | ||
128 | * iwl_mvm_calc_rssi - calculate the rssi in dBm | ||
129 | * @phy_info: the phy information for the coming packet | ||
130 | */ | ||
131 | static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, | 127 | static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, |
132 | struct iwl_rx_phy_info *phy_info) | 128 | struct iwl_rx_phy_info *phy_info) |
133 | { | 129 | { |
@@ -136,12 +132,6 @@ static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, | |||
136 | u32 agc_a, agc_b, max_agc; | 132 | u32 agc_a, agc_b, max_agc; |
137 | u32 val; | 133 | u32 val; |
138 | 134 | ||
139 | /* Find max rssi among 2 possible receivers. | ||
140 | * These values are measured by the Digital Signal Processor (DSP). | ||
141 | * They should stay fairly constant even as the signal strength varies, | ||
142 | * if the radio's Automatic Gain Control (AGC) is working right. | ||
143 | * AGC value (see below) will provide the "interesting" info. | ||
144 | */ | ||
145 | val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); | 135 | val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); |
146 | agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS; | 136 | agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS; |
147 | agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; | 137 | agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; |
@@ -170,6 +160,32 @@ static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, | |||
170 | } | 160 | } |
171 | 161 | ||
172 | /* | 162 | /* |
163 | * iwl_mvm_get_signal_strength - use new rx PHY INFO API | ||
164 | */ | ||
165 | static int iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, | ||
166 | struct iwl_rx_phy_info *phy_info) | ||
167 | { | ||
168 | int energy_a, energy_b, energy_c, max_energy; | ||
169 | u32 val; | ||
170 | |||
171 | val = | ||
172 | le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_ENERGY_ANT_ABC_IDX]); | ||
173 | energy_a = -((val & IWL_RX_INFO_ENERGY_ANT_A_MSK) >> | ||
174 | IWL_RX_INFO_ENERGY_ANT_A_POS); | ||
175 | energy_b = -((val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >> | ||
176 | IWL_RX_INFO_ENERGY_ANT_B_POS); | ||
177 | energy_c = -((val & IWL_RX_INFO_ENERGY_ANT_C_MSK) >> | ||
178 | IWL_RX_INFO_ENERGY_ANT_C_POS); | ||
179 | max_energy = max(energy_a, energy_b); | ||
180 | max_energy = max(max_energy, energy_c); | ||
181 | |||
182 | IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n", | ||
183 | energy_a, energy_b, energy_c, max_energy); | ||
184 | |||
185 | return max_energy; | ||
186 | } | ||
187 | |||
188 | /* | ||
173 | * iwl_mvm_set_mac80211_rx_flag - translate fw status to mac80211 format | 189 | * iwl_mvm_set_mac80211_rx_flag - translate fw status to mac80211 format |
174 | * @mvm: the mvm object | 190 | * @mvm: the mvm object |
175 | * @hdr: 80211 header | 191 | * @hdr: 80211 header |
@@ -290,7 +306,10 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
290 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ | 306 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ |
291 | 307 | ||
292 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | 308 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ |
293 | rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info); | 309 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_RX_ENERGY_API) |
310 | rx_status.signal = iwl_mvm_get_signal_strength(mvm, phy_info); | ||
311 | else | ||
312 | rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info); | ||
294 | 313 | ||
295 | IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal, | 314 | IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal, |
296 | (unsigned long long)rx_status.mactime); | 315 | (unsigned long long)rx_status.mactime); |