aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-05-18 03:15:24 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-05-22 03:58:49 -0400
commit67af9811539be83dbdc0739215d29af23c870405 (patch)
tree737b3e00be1c18e1c21c34eed17606d3839c5ed5
parent4d3df547e836f9a75b8de2b788449823c8db1d6a (diff)
cfg80211: allow RSSI compensation
Channels in 2.4GHz band overlap, this means that if we send a probe request on channel 1 and then move to channel 2, we will hear the probe response on channel 2. In this case, the RSSI will be lower than if we had heard it on the channel on which it was sent (1 in this case). The firmware / low level driver can parse the channel in the DS IE or HT IE and compensate the RSSI so that it will still have a valid value even if we heard the frame on an adjacent channel. This can be done up to a certain offset. Add this offset as a configuration for the low level driver. A low level driver that can compensate the low RSSI in this case should assign the maximal offset for which the RSSI value is still valid. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h7
-rw-r--r--net/wireless/scan.c12
2 files changed, 15 insertions, 4 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a75fabd18502..920ec8c1ce54 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2961,6 +2961,12 @@ struct wiphy_vendor_command {
2961 * and probe responses. This value should be set if the driver 2961 * and probe responses. This value should be set if the driver
2962 * wishes to limit the number of csa counters. Default (0) means 2962 * wishes to limit the number of csa counters. Default (0) means
2963 * infinite. 2963 * infinite.
2964 * @max_adj_channel_rssi_comp: max offset of between the channel on which the
2965 * frame was sent and the channel on which the frame was heard for which
2966 * the reported rssi is still valid. If a driver is able to compensate the
2967 * low rssi when a frame is heard on different channel, then it should set
2968 * this variable to the maximal offset for which it can compensate.
2969 * This value should be set in MHz.
2964 */ 2970 */
2965struct wiphy { 2971struct wiphy {
2966 /* assign these fields before you register the wiphy */ 2972 /* assign these fields before you register the wiphy */
@@ -3079,6 +3085,7 @@ struct wiphy {
3079 u16 max_ap_assoc_sta; 3085 u16 max_ap_assoc_sta;
3080 3086
3081 u8 max_num_csa_counters; 3087 u8 max_num_csa_counters;
3088 u8 max_adj_channel_rssi_comp;
3082 3089
3083 char priv[0] __aligned(NETDEV_ALIGN); 3090 char priv[0] __aligned(NETDEV_ALIGN);
3084}; 3091};
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 0f5da18cc619..77c56eef0574 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -883,6 +883,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
883 struct cfg80211_bss_ies *ies; 883 struct cfg80211_bss_ies *ies;
884 struct ieee80211_channel *channel; 884 struct ieee80211_channel *channel;
885 struct cfg80211_internal_bss tmp = {}, *res; 885 struct cfg80211_internal_bss tmp = {}, *res;
886 bool signal_valid;
886 887
887 if (WARN_ON(!wiphy)) 888 if (WARN_ON(!wiphy))
888 return NULL; 889 return NULL;
@@ -919,8 +920,9 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
919 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 920 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
920 rcu_assign_pointer(tmp.pub.ies, ies); 921 rcu_assign_pointer(tmp.pub.ies, ies);
921 922
922 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, 923 signal_valid = abs(rx_channel->center_freq - channel->center_freq) <=
923 rx_channel == channel); 924 wiphy->max_adj_channel_rssi_comp;
925 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
924 if (!res) 926 if (!res)
925 return NULL; 927 return NULL;
926 928
@@ -944,6 +946,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
944 struct cfg80211_internal_bss tmp = {}, *res; 946 struct cfg80211_internal_bss tmp = {}, *res;
945 struct cfg80211_bss_ies *ies; 947 struct cfg80211_bss_ies *ies;
946 struct ieee80211_channel *channel; 948 struct ieee80211_channel *channel;
949 bool signal_valid;
947 size_t ielen = len - offsetof(struct ieee80211_mgmt, 950 size_t ielen = len - offsetof(struct ieee80211_mgmt,
948 u.probe_resp.variable); 951 u.probe_resp.variable);
949 952
@@ -991,8 +994,9 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
991 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 994 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
992 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 995 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
993 996
994 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, 997 signal_valid = abs(rx_channel->center_freq - channel->center_freq) <=
995 rx_channel == channel); 998 wiphy->max_adj_channel_rssi_comp;
999 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
996 if (!res) 1000 if (!res)
997 return NULL; 1001 return NULL;
998 1002