* cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame
  *
  * @wiphy: the wiphy reporting the BSS
- * @channel: The channel the frame was received on
+ * @rx_channel: The channel the frame was received on
  * @scan_width: width of the control channel
  * @mgmt: the management frame (probe response or beacon)
  * @len: length of the management frame
  */
 struct cfg80211_bss * __must_check
 cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
-                               struct ieee80211_channel *channel,
+                               struct ieee80211_channel *rx_channel,
                                enum nl80211_bss_scan_width scan_width,
                                struct ieee80211_mgmt *mgmt, size_t len,
                                s32 signal, gfp_t gfp);
 
 static inline struct cfg80211_bss * __must_check
 cfg80211_inform_bss_frame(struct wiphy *wiphy,
-                         struct ieee80211_channel *channel,
+                         struct ieee80211_channel *rx_channel,
                          struct ieee80211_mgmt *mgmt, size_t len,
                          s32 signal, gfp_t gfp)
 {
-       return cfg80211_inform_bss_width_frame(wiphy, channel,
+       return cfg80211_inform_bss_width_frame(wiphy, rx_channel,
                                               NL80211_BSS_CHAN_WIDTH_20,
                                               mgmt, len, signal, gfp);
 }
  * cfg80211_inform_bss - inform cfg80211 of a new BSS
  *
  * @wiphy: the wiphy reporting the BSS
- * @channel: The channel the frame was received on
+ * @rx_channel: The channel the frame was received on
  * @scan_width: width of the control channel
  * @bssid: the BSSID of the BSS
  * @tsf: the TSF sent by the peer in the beacon/probe response (or 0)
  */
 struct cfg80211_bss * __must_check
 cfg80211_inform_bss_width(struct wiphy *wiphy,
-                         struct ieee80211_channel *channel,
+                         struct ieee80211_channel *rx_channel,
                          enum nl80211_bss_scan_width scan_width,
                          const u8 *bssid, u64 tsf, u16 capability,
                          u16 beacon_interval, const u8 *ie, size_t ielen,
 
 static inline struct cfg80211_bss * __must_check
 cfg80211_inform_bss(struct wiphy *wiphy,
-                   struct ieee80211_channel *channel,
+                   struct ieee80211_channel *rx_channel,
                    const u8 *bssid, u64 tsf, u16 capability,
                    u16 beacon_interval, const u8 *ie, size_t ielen,
                    s32 signal, gfp_t gfp)
 {
-       return cfg80211_inform_bss_width(wiphy, channel,
+       return cfg80211_inform_bss_width(wiphy, rx_channel,
                                         NL80211_BSS_CHAN_WIDTH_20,
                                         bssid, tsf, capability,
                                         beacon_interval, ie, ielen, signal,
 
                                  struct ieee802_11_elems *elems)
 {
        struct ieee80211_local *local = sdata->local;
-       int freq;
        struct cfg80211_bss *cbss;
        struct ieee80211_bss *bss;
        struct sta_info *sta;
        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
        bool rates_updated = false;
 
-       if (elems->ds_params)
-               freq = ieee80211_channel_to_frequency(elems->ds_params[0],
-                                                     band);
-       else
-               freq = rx_status->freq;
-
-       channel = ieee80211_get_channel(local->hw.wiphy, freq);
-
-       if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
+       channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
+       if (!channel)
                return;
 
        if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
 
                                  struct ieee802_11_elems *elems)
 {
        struct ieee80211_local *local = sdata->local;
-       int freq;
        struct ieee80211_bss *bss;
        struct ieee80211_channel *channel;
 
        sdata_assert_lock(sdata);
 
-       if (elems->ds_params)
-               freq = ieee80211_channel_to_frequency(elems->ds_params[0],
-                                                     rx_status->band);
-       else
-               freq = rx_status->freq;
-
-       channel = ieee80211_get_channel(local->hw.wiphy, freq);
-
-       if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
+       channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
+       if (!channel)
                return;
 
        bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
 
 /* Returned bss is reference counted and must be cleaned up appropriately. */
 static struct cfg80211_internal_bss *
 cfg80211_bss_update(struct cfg80211_registered_device *dev,
-                   struct cfg80211_internal_bss *tmp)
+                   struct cfg80211_internal_bss *tmp,
+                   bool signal_valid)
 {
        struct cfg80211_internal_bss *found = NULL;
 
                }
 
                found->pub.beacon_interval = tmp->pub.beacon_interval;
-               found->pub.signal = tmp->pub.signal;
+               /*
+                * don't update the signal if beacon was heard on
+                * adjacent channel.
+                */
+               if (signal_valid)
+                       found->pub.signal = tmp->pub.signal;
                found->pub.capability = tmp->pub.capability;
                found->ts = tmp->ts;
        } else {
 /* Returned bss is reference counted and must be cleaned up appropriately. */
 struct cfg80211_bss*
 cfg80211_inform_bss_width(struct wiphy *wiphy,
-                         struct ieee80211_channel *channel,
+                         struct ieee80211_channel *rx_channel,
                          enum nl80211_bss_scan_width scan_width,
                          const u8 *bssid, u64 tsf, u16 capability,
                          u16 beacon_interval, const u8 *ie, size_t ielen,
                          s32 signal, gfp_t gfp)
 {
        struct cfg80211_bss_ies *ies;
+       struct ieee80211_channel *channel;
        struct cfg80211_internal_bss tmp = {}, *res;
 
        if (WARN_ON(!wiphy))
                        (signal < 0 || signal > 100)))
                return NULL;
 
-       channel = cfg80211_get_bss_channel(wiphy, ie, ielen, channel);
+       channel = cfg80211_get_bss_channel(wiphy, ie, ielen, rx_channel);
        if (!channel)
                return NULL;
 
        rcu_assign_pointer(tmp.pub.beacon_ies, ies);
        rcu_assign_pointer(tmp.pub.ies, ies);
 
-       res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
+       res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
+                                 rx_channel == channel);
        if (!res)
                return NULL;
 
 /* Returned bss is reference counted and must be cleaned up appropriately. */
 struct cfg80211_bss *
 cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
-                               struct ieee80211_channel *channel,
+                               struct ieee80211_channel *rx_channel,
                                enum nl80211_bss_scan_width scan_width,
                                struct ieee80211_mgmt *mgmt, size_t len,
                                s32 signal, gfp_t gfp)
 {
        struct cfg80211_internal_bss tmp = {}, *res;
        struct cfg80211_bss_ies *ies;
+       struct ieee80211_channel *channel;
        size_t ielen = len - offsetof(struct ieee80211_mgmt,
                                      u.probe_resp.variable);
 
        BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
                        offsetof(struct ieee80211_mgmt, u.beacon.variable));
 
-       trace_cfg80211_inform_bss_width_frame(wiphy, channel, scan_width, mgmt,
+       trace_cfg80211_inform_bss_width_frame(wiphy, rx_channel, scan_width, mgmt,
                                              len, signal);
 
        if (WARN_ON(!mgmt))
                return NULL;
 
        channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
-                                          ielen, channel);
+                                          ielen, rx_channel);
        if (!channel)
                return NULL;
 
        tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
        tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
 
-       res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
+       res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
+                                 rx_channel == channel);
        if (!res)
                return NULL;