diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/rx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rx.c | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index e4930d5027d2..6fd7fae30c0a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c | |||
@@ -124,24 +124,15 @@ 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 | /* | 127 | static void iwl_mvm_calc_rssi(struct iwl_mvm *mvm, |
128 | * iwl_mvm_calc_rssi - calculate the rssi in dBm | 128 | struct iwl_rx_phy_info *phy_info, |
129 | * @phy_info: the phy information for the coming packet | 129 | struct ieee80211_rx_status *rx_status) |
130 | */ | ||
131 | static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, | ||
132 | struct iwl_rx_phy_info *phy_info) | ||
133 | { | 130 | { |
134 | int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm; | 131 | int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm; |
135 | int rssi_all_band_a, rssi_all_band_b; | 132 | int rssi_all_band_a, rssi_all_band_b; |
136 | u32 agc_a, agc_b, max_agc; | 133 | u32 agc_a, agc_b, max_agc; |
137 | u32 val; | 134 | u32 val; |
138 | 135 | ||
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]); | 136 | 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; | 137 | 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; | 138 | agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; |
@@ -166,7 +157,45 @@ static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, | |||
166 | IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", | 157 | IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", |
167 | rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); | 158 | rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); |
168 | 159 | ||
169 | return max_rssi_dbm; | 160 | rx_status->signal = max_rssi_dbm; |
161 | rx_status->chains = (le16_to_cpu(phy_info->phy_flags) & | ||
162 | RX_RES_PHY_FLAGS_ANTENNA) | ||
163 | >> RX_RES_PHY_FLAGS_ANTENNA_POS; | ||
164 | rx_status->chain_signal[0] = rssi_a_dbm; | ||
165 | rx_status->chain_signal[1] = rssi_b_dbm; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * iwl_mvm_get_signal_strength - use new rx PHY INFO API | ||
170 | */ | ||
171 | static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, | ||
172 | struct iwl_rx_phy_info *phy_info, | ||
173 | struct ieee80211_rx_status *rx_status) | ||
174 | { | ||
175 | int energy_a, energy_b, energy_c, max_energy; | ||
176 | u32 val; | ||
177 | |||
178 | val = | ||
179 | le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_ENERGY_ANT_ABC_IDX]); | ||
180 | energy_a = -((val & IWL_RX_INFO_ENERGY_ANT_A_MSK) >> | ||
181 | IWL_RX_INFO_ENERGY_ANT_A_POS); | ||
182 | energy_b = -((val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >> | ||
183 | IWL_RX_INFO_ENERGY_ANT_B_POS); | ||
184 | energy_c = -((val & IWL_RX_INFO_ENERGY_ANT_C_MSK) >> | ||
185 | IWL_RX_INFO_ENERGY_ANT_C_POS); | ||
186 | max_energy = max(energy_a, energy_b); | ||
187 | max_energy = max(max_energy, energy_c); | ||
188 | |||
189 | IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n", | ||
190 | energy_a, energy_b, energy_c, max_energy); | ||
191 | |||
192 | rx_status->signal = max_energy; | ||
193 | rx_status->chains = (le16_to_cpu(phy_info->phy_flags) & | ||
194 | RX_RES_PHY_FLAGS_ANTENNA) | ||
195 | >> RX_RES_PHY_FLAGS_ANTENNA_POS; | ||
196 | rx_status->chain_signal[0] = energy_a; | ||
197 | rx_status->chain_signal[1] = energy_b; | ||
198 | rx_status->chain_signal[2] = energy_c; | ||
170 | } | 199 | } |
171 | 200 | ||
172 | /* | 201 | /* |
@@ -289,29 +318,14 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
289 | */ | 318 | */ |
290 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ | 319 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ |
291 | 320 | ||
292 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | 321 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_RX_ENERGY_API) |
293 | rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info); | 322 | iwl_mvm_get_signal_strength(mvm, phy_info, &rx_status); |
323 | else | ||
324 | iwl_mvm_calc_rssi(mvm, phy_info, &rx_status); | ||
294 | 325 | ||
295 | IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal, | 326 | IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal, |
296 | (unsigned long long)rx_status.mactime); | 327 | (unsigned long long)rx_status.mactime); |
297 | 328 | ||
298 | /* | ||
299 | * "antenna number" | ||
300 | * | ||
301 | * It seems that the antenna field in the phy flags value | ||
302 | * is actually a bit field. This is undefined by radiotap, | ||
303 | * it wants an actual antenna number but I always get "7" | ||
304 | * for most legacy frames I receive indicating that the | ||
305 | * same frame was received on all three RX chains. | ||
306 | * | ||
307 | * I think this field should be removed in favor of a | ||
308 | * new 802.11n radiotap field "RX chains" that is defined | ||
309 | * as a bitmask. | ||
310 | */ | ||
311 | rx_status.antenna = (le16_to_cpu(phy_info->phy_flags) & | ||
312 | RX_RES_PHY_FLAGS_ANTENNA) | ||
313 | >> RX_RES_PHY_FLAGS_ANTENNA_POS; | ||
314 | |||
315 | /* set the preamble flag if appropriate */ | 329 | /* set the preamble flag if appropriate */ |
316 | if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE)) | 330 | if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE)) |
317 | rx_status.flag |= RX_FLAG_SHORTPRE; | 331 | rx_status.flag |= RX_FLAG_SHORTPRE; |