aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9119f5ce3677..d313c9befa23 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -2001,6 +2001,85 @@ void cfg80211_bss_iter(struct wiphy *wiphy,
2001} 2001}
2002EXPORT_SYMBOL(cfg80211_bss_iter); 2002EXPORT_SYMBOL(cfg80211_bss_iter);
2003 2003
2004void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
2005 struct ieee80211_channel *chan)
2006{
2007 struct wiphy *wiphy = wdev->wiphy;
2008 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2009 struct cfg80211_internal_bss *cbss = wdev->current_bss;
2010 struct cfg80211_internal_bss *new = NULL;
2011 struct cfg80211_internal_bss *bss;
2012 struct cfg80211_bss *nontrans_bss;
2013 struct cfg80211_bss *tmp;
2014
2015 spin_lock_bh(&rdev->bss_lock);
2016
2017 if (WARN_ON(cbss->pub.channel == chan))
2018 goto done;
2019
2020 /* use transmitting bss */
2021 if (cbss->pub.transmitted_bss)
2022 cbss = container_of(cbss->pub.transmitted_bss,
2023 struct cfg80211_internal_bss,
2024 pub);
2025
2026 cbss->pub.channel = chan;
2027
2028 list_for_each_entry(bss, &rdev->bss_list, list) {
2029 if (!cfg80211_bss_type_match(bss->pub.capability,
2030 bss->pub.channel->band,
2031 wdev->conn_bss_type))
2032 continue;
2033
2034 if (bss == cbss)
2035 continue;
2036
2037 if (!cmp_bss(&bss->pub, &cbss->pub, BSS_CMP_REGULAR)) {
2038 new = bss;
2039 break;
2040 }
2041 }
2042
2043 if (new) {
2044 /* to save time, update IEs for transmitting bss only */
2045 if (cfg80211_update_known_bss(rdev, cbss, new, false)) {
2046 new->pub.proberesp_ies = NULL;
2047 new->pub.beacon_ies = NULL;
2048 }
2049
2050 list_for_each_entry_safe(nontrans_bss, tmp,
2051 &new->pub.nontrans_list,
2052 nontrans_list) {
2053 bss = container_of(nontrans_bss,
2054 struct cfg80211_internal_bss, pub);
2055 if (__cfg80211_unlink_bss(rdev, bss))
2056 rdev->bss_generation++;
2057 }
2058
2059 WARN_ON(atomic_read(&new->hold));
2060 if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new)))
2061 rdev->bss_generation++;
2062 }
2063
2064 rb_erase(&cbss->rbn, &rdev->bss_tree);
2065 rb_insert_bss(rdev, cbss);
2066 rdev->bss_generation++;
2067
2068 list_for_each_entry_safe(nontrans_bss, tmp,
2069 &cbss->pub.nontrans_list,
2070 nontrans_list) {
2071 bss = container_of(nontrans_bss,
2072 struct cfg80211_internal_bss, pub);
2073 bss->pub.channel = chan;
2074 rb_erase(&bss->rbn, &rdev->bss_tree);
2075 rb_insert_bss(rdev, bss);
2076 rdev->bss_generation++;
2077 }
2078
2079done:
2080 spin_unlock_bh(&rdev->bss_lock);
2081}
2082
2004#ifdef CONFIG_CFG80211_WEXT 2083#ifdef CONFIG_CFG80211_WEXT
2005static struct cfg80211_registered_device * 2084static struct cfg80211_registered_device *
2006cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) 2085cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)