aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-07-03 05:55:17 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-07-31 05:05:04 -0400
commit226eb8cd22b6cddccd6e109a8400427ea6fed080 (patch)
tree43ffdb24f89be7266a93095a14e23092545414db
parent291aa7c4a4c01ef925b366174fc05ff2a757fad0 (diff)
iwlwifi: mvm: report per-chain signal to mac80211
Instead of reporting the maximum signal strength and the antenna bitmap in the antenna field (which is really just for radiotap and defined differently), report the signal strength values per chain and set the chain bitmap. Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c47
1 files changed, 21 insertions, 26 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index c8e4af23d04c..6fd7fae30c0a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -124,8 +124,9 @@ 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
127static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, 127static void iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
128 struct iwl_rx_phy_info *phy_info) 128 struct iwl_rx_phy_info *phy_info,
129 struct ieee80211_rx_status *rx_status)
129{ 130{
130 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;
131 int rssi_all_band_a, rssi_all_band_b; 132 int rssi_all_band_a, rssi_all_band_b;
@@ -156,14 +157,20 @@ static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
156 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",
157 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);
158 159
159 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;
160} 166}
161 167
162/* 168/*
163 * iwl_mvm_get_signal_strength - use new rx PHY INFO API 169 * iwl_mvm_get_signal_strength - use new rx PHY INFO API
164 */ 170 */
165static int iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, 171static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
166 struct iwl_rx_phy_info *phy_info) 172 struct iwl_rx_phy_info *phy_info,
173 struct ieee80211_rx_status *rx_status)
167{ 174{
168 int energy_a, energy_b, energy_c, max_energy; 175 int energy_a, energy_b, energy_c, max_energy;
169 u32 val; 176 u32 val;
@@ -182,7 +189,13 @@ static int iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
182 IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n", 189 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); 190 energy_a, energy_b, energy_c, max_energy);
184 191
185 return max_energy; 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;
186} 199}
187 200
188/* 201/*
@@ -305,32 +318,14 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
305 */ 318 */
306 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ 319 /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
307 320
308 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
309 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_RX_ENERGY_API) 321 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); 322 iwl_mvm_get_signal_strength(mvm, phy_info, &rx_status);
311 else 323 else
312 rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info); 324 iwl_mvm_calc_rssi(mvm, phy_info, &rx_status);
313 325
314 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,
315 (unsigned long long)rx_status.mactime); 327 (unsigned long long)rx_status.mactime);
316 328
317 /*
318 * "antenna number"
319 *
320 * It seems that the antenna field in the phy flags value
321 * is actually a bit field. This is undefined by radiotap,
322 * it wants an actual antenna number but I always get "7"
323 * for most legacy frames I receive indicating that the
324 * same frame was received on all three RX chains.
325 *
326 * I think this field should be removed in favor of a
327 * new 802.11n radiotap field "RX chains" that is defined
328 * as a bitmask.
329 */
330 rx_status.antenna = (le16_to_cpu(phy_info->phy_flags) &
331 RX_RES_PHY_FLAGS_ANTENNA)
332 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
333
334 /* set the preamble flag if appropriate */ 329 /* set the preamble flag if appropriate */
335 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))
336 rx_status.flag |= RX_FLAG_SHORTPRE; 331 rx_status.flag |= RX_FLAG_SHORTPRE;