Merge tag 'perf-tools-for-v6.2-1-2022-12-16' of git://git.kernel.org/pub/scm/linux...
[linux-block.git] / net / wireless / scan.c
index da752b0cc75206e6e139682074a8f848316d02ab..790bc31cf82ea0ae401219b7abb4d8fb3b385d81 100644 (file)
@@ -158,9 +158,8 @@ static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
 
        if (bss->pub.hidden_beacon_bss) {
                struct cfg80211_internal_bss *hbss;
-               hbss = container_of(bss->pub.hidden_beacon_bss,
-                                   struct cfg80211_internal_bss,
-                                   pub);
+
+               hbss = bss_from_pub(bss->pub.hidden_beacon_bss);
                hbss->refcount--;
                if (hbss->refcount == 0)
                        bss_free(hbss);
@@ -169,9 +168,7 @@ static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
        if (bss->pub.transmitted_bss) {
                struct cfg80211_internal_bss *tbss;
 
-               tbss = container_of(bss->pub.transmitted_bss,
-                                   struct cfg80211_internal_bss,
-                                   pub);
+               tbss = bss_from_pub(bss->pub.transmitted_bss);
                tbss->refcount--;
                if (tbss->refcount == 0)
                        bss_free(tbss);
@@ -330,7 +327,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
                         * determine if they are the same ie.
                         */
                        if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
-                               if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
+                               if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
+                                   !memcmp(tmp_old + 2, tmp + 2, 5)) {
                                        /* same vendor ie, copy from
                                         * subelement
                                         */
@@ -1289,7 +1287,8 @@ static int cmp_bss(struct cfg80211_bss *a,
        int i, r;
 
        if (a->channel != b->channel)
-               return b->channel->center_freq - a->channel->center_freq;
+               return (b->channel->center_freq * 1000 + b->channel->freq_offset) -
+                      (a->channel->center_freq * 1000 + a->channel->freq_offset);
 
        a_ies = rcu_access_pointer(a->ies);
        if (!a_ies)
@@ -1790,13 +1789,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
 
                /* This must be before the call to bss_ref_get */
                if (tmp->pub.transmitted_bss) {
-                       struct cfg80211_internal_bss *pbss =
-                               container_of(tmp->pub.transmitted_bss,
-                                            struct cfg80211_internal_bss,
-                                            pub);
-
                        new->pub.transmitted_bss = tmp->pub.transmitted_bss;
-                       bss_ref_get(rdev, pbss);
+                       bss_ref_get(rdev, bss_from_pub(tmp->pub.transmitted_bss));
                }
 
                list_add_tail(&new->list, &rdev->bss_list);
@@ -2526,10 +2520,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
        const struct cfg80211_bss_ies *ies1, *ies2;
        size_t ielen = len - offsetof(struct ieee80211_mgmt,
                                      u.probe_resp.variable);
-       struct cfg80211_non_tx_bss non_tx_data;
+       struct cfg80211_non_tx_bss non_tx_data = {};
 
        res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
                                                    len, gfp);
+
+       /* don't do any further MBSSID handling for S1G */
+       if (ieee80211_is_s1g_beacon(mgmt->frame_control))
+               return res;
+
        if (!res || !wiphy->support_mbssid ||
            !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
                return res;
@@ -2569,15 +2568,12 @@ EXPORT_SYMBOL(cfg80211_inform_bss_frame_data);
 void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
-       struct cfg80211_internal_bss *bss;
 
        if (!pub)
                return;
 
-       bss = container_of(pub, struct cfg80211_internal_bss, pub);
-
        spin_lock_bh(&rdev->bss_lock);
-       bss_ref_get(rdev, bss);
+       bss_ref_get(rdev, bss_from_pub(pub));
        spin_unlock_bh(&rdev->bss_lock);
 }
 EXPORT_SYMBOL(cfg80211_ref_bss);
@@ -2585,15 +2581,12 @@ EXPORT_SYMBOL(cfg80211_ref_bss);
 void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
-       struct cfg80211_internal_bss *bss;
 
        if (!pub)
                return;
 
-       bss = container_of(pub, struct cfg80211_internal_bss, pub);
-
        spin_lock_bh(&rdev->bss_lock);
-       bss_ref_put(rdev, bss);
+       bss_ref_put(rdev, bss_from_pub(pub));
        spin_unlock_bh(&rdev->bss_lock);
 }
 EXPORT_SYMBOL(cfg80211_put_bss);
@@ -2607,7 +2600,7 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
        if (WARN_ON(!pub))
                return;
 
-       bss = container_of(pub, struct cfg80211_internal_bss, pub);
+       bss = bss_from_pub(pub);
 
        spin_lock_bh(&rdev->bss_lock);
        if (list_empty(&bss->list))
@@ -2616,8 +2609,7 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
        list_for_each_entry_safe(nontrans_bss, tmp,
                                 &pub->nontrans_list,
                                 nontrans_list) {
-               tmp1 = container_of(nontrans_bss,
-                                   struct cfg80211_internal_bss, pub);
+               tmp1 = bss_from_pub(nontrans_bss);
                if (__cfg80211_unlink_bss(rdev, tmp1))
                        rdev->bss_generation++;
        }
@@ -2674,9 +2666,7 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
 
        /* use transmitting bss */
        if (cbss->pub.transmitted_bss)
-               cbss = container_of(cbss->pub.transmitted_bss,
-                                   struct cfg80211_internal_bss,
-                                   pub);
+               cbss = bss_from_pub(cbss->pub.transmitted_bss);
 
        cbss->pub.channel = chan;
 
@@ -2705,8 +2695,7 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
                list_for_each_entry_safe(nontrans_bss, tmp,
                                         &new->pub.nontrans_list,
                                         nontrans_list) {
-                       bss = container_of(nontrans_bss,
-                                          struct cfg80211_internal_bss, pub);
+                       bss = bss_from_pub(nontrans_bss);
                        if (__cfg80211_unlink_bss(rdev, bss))
                                rdev->bss_generation++;
                }
@@ -2723,8 +2712,7 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
        list_for_each_entry_safe(nontrans_bss, tmp,
                                 &cbss->pub.nontrans_list,
                                 nontrans_list) {
-               bss = container_of(nontrans_bss,
-                                  struct cfg80211_internal_bss, pub);
+               bss = bss_from_pub(nontrans_bss);
                bss->pub.channel = chan;
                rb_erase(&bss->rbn, &rdev->bss_tree);
                rb_insert_bss(rdev, bss);
@@ -3231,8 +3219,9 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
 
 int cfg80211_wext_giwscan(struct net_device *dev,
                          struct iw_request_info *info,
-                         struct iw_point *data, char *extra)
+                         union iwreq_data *wrqu, char *extra)
 {
+       struct iw_point *data = &wrqu->data;
        struct cfg80211_registered_device *rdev;
        int res;