iwlwifi: mvm: report per-chain signal to mac80211
authorJohannes Berg <johannes.berg@intel.com>
Wed, 3 Jul 2013 09:55:17 +0000 (11:55 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 31 Jul 2013 09:05:04 +0000 (11:05 +0200)
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>
drivers/net/wireless/iwlwifi/mvm/rx.c

index c8e4af2..6fd7fae 100644 (file)
@@ -124,8 +124,9 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
        ieee80211_rx_ni(mvm->hw, skb);
 }
 
-static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
-                            struct iwl_rx_phy_info *phy_info)
+static void iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
+                             struct iwl_rx_phy_info *phy_info,
+                             struct ieee80211_rx_status *rx_status)
 {
        int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
        int rssi_all_band_a, rssi_all_band_b;
@@ -156,14 +157,20 @@ static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
        IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
                        rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
 
-       return max_rssi_dbm;
+       rx_status->signal = max_rssi_dbm;
+       rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
+                               RX_RES_PHY_FLAGS_ANTENNA)
+                                       >> RX_RES_PHY_FLAGS_ANTENNA_POS;
+       rx_status->chain_signal[0] = rssi_a_dbm;
+       rx_status->chain_signal[1] = rssi_b_dbm;
 }
 
 /*
  * iwl_mvm_get_signal_strength - use new rx PHY INFO API
  */
-static int iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
-                                      struct iwl_rx_phy_info *phy_info)
+static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
+                                       struct iwl_rx_phy_info *phy_info,
+                                       struct ieee80211_rx_status *rx_status)
 {
        int energy_a, energy_b, energy_c, max_energy;
        u32 val;
@@ -182,7 +189,13 @@ static int iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
        IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n",
                        energy_a, energy_b, energy_c, max_energy);
 
-       return max_energy;
+       rx_status->signal = max_energy;
+       rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
+                               RX_RES_PHY_FLAGS_ANTENNA)
+                                       >> RX_RES_PHY_FLAGS_ANTENNA_POS;
+       rx_status->chain_signal[0] = energy_a;
+       rx_status->chain_signal[1] = energy_b;
+       rx_status->chain_signal[2] = energy_c;
 }
 
 /*
@@ -305,32 +318,14 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
         */
        /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
 
-       /* Find max signal strength (dBm) among 3 antenna/receiver chains */
        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_RX_ENERGY_API)
-               rx_status.signal = iwl_mvm_get_signal_strength(mvm, phy_info);
+               iwl_mvm_get_signal_strength(mvm, phy_info, &rx_status);
        else
-               rx_status.signal = iwl_mvm_calc_rssi(mvm, phy_info);
+               iwl_mvm_calc_rssi(mvm, phy_info, &rx_status);
 
        IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal,
                              (unsigned long long)rx_status.mactime);
 
-       /*
-        * "antenna number"
-        *
-        * It seems that the antenna field in the phy flags value
-        * is actually a bit field. This is undefined by radiotap,
-        * it wants an actual antenna number but I always get "7"
-        * for most legacy frames I receive indicating that the
-        * same frame was received on all three RX chains.
-        *
-        * I think this field should be removed in favor of a
-        * new 802.11n radiotap field "RX chains" that is defined
-        * as a bitmask.
-        */
-       rx_status.antenna = (le16_to_cpu(phy_info->phy_flags) &
-                               RX_RES_PHY_FLAGS_ANTENNA)
-                               >> RX_RES_PHY_FLAGS_ANTENNA_POS;
-
        /* set the preamble flag if appropriate */
        if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE))
                rx_status.flag |= RX_FLAG_SHORTPRE;