diff options
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r-- | net/wireless/scan.c | 79 |
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 | } |
2002 | EXPORT_SYMBOL(cfg80211_bss_iter); | 2002 | EXPORT_SYMBOL(cfg80211_bss_iter); |
2003 | 2003 | ||
2004 | void 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 | |||
2079 | done: | ||
2080 | spin_unlock_bh(&rdev->bss_lock); | ||
2081 | } | ||
2082 | |||
2004 | #ifdef CONFIG_CFG80211_WEXT | 2083 | #ifdef CONFIG_CFG80211_WEXT |
2005 | static struct cfg80211_registered_device * | 2084 | static struct cfg80211_registered_device * |
2006 | cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) | 2085 | cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) |