wifi: mac80211: Fix permissions for valid_links debugfs entry
[platform/kernel/linux-starfive.git] / net / wireless / scan.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * cfg80211 scan result handling
4  *
5  * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
6  * Copyright 2013-2014  Intel Mobile Communications GmbH
7  * Copyright 2016       Intel Deutschland GmbH
8  * Copyright (C) 2018-2023 Intel Corporation
9  */
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <linux/netdevice.h>
14 #include <linux/wireless.h>
15 #include <linux/nl80211.h>
16 #include <linux/etherdevice.h>
17 #include <linux/crc32.h>
18 #include <linux/bitfield.h>
19 #include <net/arp.h>
20 #include <net/cfg80211.h>
21 #include <net/cfg80211-wext.h>
22 #include <net/iw_handler.h>
23 #include "core.h"
24 #include "nl80211.h"
25 #include "wext-compat.h"
26 #include "rdev-ops.h"
27
28 /**
29  * DOC: BSS tree/list structure
30  *
31  * At the top level, the BSS list is kept in both a list in each
32  * registered device (@bss_list) as well as an RB-tree for faster
33  * lookup. In the RB-tree, entries can be looked up using their
34  * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
35  * for other BSSes.
36  *
37  * Due to the possibility of hidden SSIDs, there's a second level
38  * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
39  * The hidden_list connects all BSSes belonging to a single AP
40  * that has a hidden SSID, and connects beacon and probe response
41  * entries. For a probe response entry for a hidden SSID, the
42  * hidden_beacon_bss pointer points to the BSS struct holding the
43  * beacon's information.
44  *
45  * Reference counting is done for all these references except for
46  * the hidden_list, so that a beacon BSS struct that is otherwise
47  * not referenced has one reference for being on the bss_list and
48  * one for each probe response entry that points to it using the
49  * hidden_beacon_bss pointer. When a BSS struct that has such a
50  * pointer is get/put, the refcount update is also propagated to
51  * the referenced struct, this ensure that it cannot get removed
52  * while somebody is using the probe response version.
53  *
54  * Note that the hidden_beacon_bss pointer never changes, due to
55  * the reference counting. Therefore, no locking is needed for
56  * it.
57  *
58  * Also note that the hidden_beacon_bss pointer is only relevant
59  * if the driver uses something other than the IEs, e.g. private
60  * data stored in the BSS struct, since the beacon IEs are
61  * also linked into the probe response struct.
62  */
63
64 /*
65  * Limit the number of BSS entries stored in mac80211. Each one is
66  * a bit over 4k at most, so this limits to roughly 4-5M of memory.
67  * If somebody wants to really attack this though, they'd likely
68  * use small beacons, and only one type of frame, limiting each of
69  * the entries to a much smaller size (in order to generate more
70  * entries in total, so overhead is bigger.)
71  */
72 static int bss_entries_limit = 1000;
73 module_param(bss_entries_limit, int, 0644);
74 MODULE_PARM_DESC(bss_entries_limit,
75                  "limit to number of scan BSS entries (per wiphy, default 1000)");
76
77 #define IEEE80211_SCAN_RESULT_EXPIRE    (30 * HZ)
78
79 /**
80  * struct cfg80211_colocated_ap - colocated AP information
81  *
82  * @list: linked list to all colocated aPS
83  * @bssid: BSSID of the reported AP
84  * @ssid: SSID of the reported AP
85  * @ssid_len: length of the ssid
86  * @center_freq: frequency the reported AP is on
87  * @unsolicited_probe: the reported AP is part of an ESS, where all the APs
88  *      that operate in the same channel as the reported AP and that might be
89  *      detected by a STA receiving this frame, are transmitting unsolicited
90  *      Probe Response frames every 20 TUs
91  * @oct_recommended: OCT is recommended to exchange MMPDUs with the reported AP
92  * @same_ssid: the reported AP has the same SSID as the reporting AP
93  * @multi_bss: the reported AP is part of a multiple BSSID set
94  * @transmitted_bssid: the reported AP is the transmitting BSSID
95  * @colocated_ess: all the APs that share the same ESS as the reported AP are
96  *      colocated and can be discovered via legacy bands.
97  * @short_ssid_valid: short_ssid is valid and can be used
98  * @short_ssid: the short SSID for this SSID
99  */
100 struct cfg80211_colocated_ap {
101         struct list_head list;
102         u8 bssid[ETH_ALEN];
103         u8 ssid[IEEE80211_MAX_SSID_LEN];
104         size_t ssid_len;
105         u32 short_ssid;
106         u32 center_freq;
107         u8 unsolicited_probe:1,
108            oct_recommended:1,
109            same_ssid:1,
110            multi_bss:1,
111            transmitted_bssid:1,
112            colocated_ess:1,
113            short_ssid_valid:1;
114 };
115
116 static void bss_free(struct cfg80211_internal_bss *bss)
117 {
118         struct cfg80211_bss_ies *ies;
119
120         if (WARN_ON(atomic_read(&bss->hold)))
121                 return;
122
123         ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
124         if (ies && !bss->pub.hidden_beacon_bss)
125                 kfree_rcu(ies, rcu_head);
126         ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
127         if (ies)
128                 kfree_rcu(ies, rcu_head);
129
130         /*
131          * This happens when the module is removed, it doesn't
132          * really matter any more save for completeness
133          */
134         if (!list_empty(&bss->hidden_list))
135                 list_del(&bss->hidden_list);
136
137         kfree(bss);
138 }
139
140 static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
141                                struct cfg80211_internal_bss *bss)
142 {
143         lockdep_assert_held(&rdev->bss_lock);
144
145         bss->refcount++;
146
147         if (bss->pub.hidden_beacon_bss)
148                 bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
149
150         if (bss->pub.transmitted_bss)
151                 bss_from_pub(bss->pub.transmitted_bss)->refcount++;
152 }
153
154 static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
155                                struct cfg80211_internal_bss *bss)
156 {
157         lockdep_assert_held(&rdev->bss_lock);
158
159         if (bss->pub.hidden_beacon_bss) {
160                 struct cfg80211_internal_bss *hbss;
161                 hbss = container_of(bss->pub.hidden_beacon_bss,
162                                     struct cfg80211_internal_bss,
163                                     pub);
164                 hbss->refcount--;
165                 if (hbss->refcount == 0)
166                         bss_free(hbss);
167         }
168
169         if (bss->pub.transmitted_bss) {
170                 struct cfg80211_internal_bss *tbss;
171
172                 tbss = container_of(bss->pub.transmitted_bss,
173                                     struct cfg80211_internal_bss,
174                                     pub);
175                 tbss->refcount--;
176                 if (tbss->refcount == 0)
177                         bss_free(tbss);
178         }
179
180         bss->refcount--;
181         if (bss->refcount == 0)
182                 bss_free(bss);
183 }
184
185 static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
186                                   struct cfg80211_internal_bss *bss)
187 {
188         lockdep_assert_held(&rdev->bss_lock);
189
190         if (!list_empty(&bss->hidden_list)) {
191                 /*
192                  * don't remove the beacon entry if it has
193                  * probe responses associated with it
194                  */
195                 if (!bss->pub.hidden_beacon_bss)
196                         return false;
197                 /*
198                  * if it's a probe response entry break its
199                  * link to the other entries in the group
200                  */
201                 list_del_init(&bss->hidden_list);
202         }
203
204         list_del_init(&bss->list);
205         list_del_init(&bss->pub.nontrans_list);
206         rb_erase(&bss->rbn, &rdev->bss_tree);
207         rdev->bss_entries--;
208         WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
209                   "rdev bss entries[%d]/list[empty:%d] corruption\n",
210                   rdev->bss_entries, list_empty(&rdev->bss_list));
211         bss_ref_put(rdev, bss);
212         return true;
213 }
214
215 bool cfg80211_is_element_inherited(const struct element *elem,
216                                    const struct element *non_inherit_elem)
217 {
218         u8 id_len, ext_id_len, i, loop_len, id;
219         const u8 *list;
220
221         if (elem->id == WLAN_EID_MULTIPLE_BSSID)
222                 return false;
223
224         if (!non_inherit_elem || non_inherit_elem->datalen < 2)
225                 return true;
226
227         /*
228          * non inheritance element format is:
229          * ext ID (56) | IDs list len | list | extension IDs list len | list
230          * Both lists are optional. Both lengths are mandatory.
231          * This means valid length is:
232          * elem_len = 1 (extension ID) + 2 (list len fields) + list lengths
233          */
234         id_len = non_inherit_elem->data[1];
235         if (non_inherit_elem->datalen < 3 + id_len)
236                 return true;
237
238         ext_id_len = non_inherit_elem->data[2 + id_len];
239         if (non_inherit_elem->datalen < 3 + id_len + ext_id_len)
240                 return true;
241
242         if (elem->id == WLAN_EID_EXTENSION) {
243                 if (!ext_id_len)
244                         return true;
245                 loop_len = ext_id_len;
246                 list = &non_inherit_elem->data[3 + id_len];
247                 id = elem->data[0];
248         } else {
249                 if (!id_len)
250                         return true;
251                 loop_len = id_len;
252                 list = &non_inherit_elem->data[2];
253                 id = elem->id;
254         }
255
256         for (i = 0; i < loop_len; i++) {
257                 if (list[i] == id)
258                         return false;
259         }
260
261         return true;
262 }
263 EXPORT_SYMBOL(cfg80211_is_element_inherited);
264
265 static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
266                                   const u8 *subelement, size_t subie_len,
267                                   u8 *new_ie, gfp_t gfp)
268 {
269         u8 *pos, *tmp;
270         const u8 *tmp_old, *tmp_new;
271         const struct element *non_inherit_elem;
272         u8 *sub_copy;
273
274         /* copy subelement as we need to change its content to
275          * mark an ie after it is processed.
276          */
277         sub_copy = kmemdup(subelement, subie_len, gfp);
278         if (!sub_copy)
279                 return 0;
280
281         pos = &new_ie[0];
282
283         /* set new ssid */
284         tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
285         if (tmp_new) {
286                 memcpy(pos, tmp_new, tmp_new[1] + 2);
287                 pos += (tmp_new[1] + 2);
288         }
289
290         /* get non inheritance list if exists */
291         non_inherit_elem =
292                 cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
293                                        sub_copy, subie_len);
294
295         /* go through IEs in ie (skip SSID) and subelement,
296          * merge them into new_ie
297          */
298         tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
299         tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
300
301         while (tmp_old + 2 - ie <= ielen &&
302                tmp_old + tmp_old[1] + 2 - ie <= ielen) {
303                 if (tmp_old[0] == 0) {
304                         tmp_old++;
305                         continue;
306                 }
307
308                 if (tmp_old[0] == WLAN_EID_EXTENSION)
309                         tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy,
310                                                          subie_len);
311                 else
312                         tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy,
313                                                      subie_len);
314
315                 if (!tmp) {
316                         const struct element *old_elem = (void *)tmp_old;
317
318                         /* ie in old ie but not in subelement */
319                         if (cfg80211_is_element_inherited(old_elem,
320                                                           non_inherit_elem)) {
321                                 memcpy(pos, tmp_old, tmp_old[1] + 2);
322                                 pos += tmp_old[1] + 2;
323                         }
324                 } else {
325                         /* ie in transmitting ie also in subelement,
326                          * copy from subelement and flag the ie in subelement
327                          * as copied (by setting eid field to WLAN_EID_SSID,
328                          * which is skipped anyway).
329                          * For vendor ie, compare OUI + type + subType to
330                          * determine if they are the same ie.
331                          */
332                         if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
333                                 if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
334                                     !memcmp(tmp_old + 2, tmp + 2, 5)) {
335                                         /* same vendor ie, copy from
336                                          * subelement
337                                          */
338                                         memcpy(pos, tmp, tmp[1] + 2);
339                                         pos += tmp[1] + 2;
340                                         tmp[0] = WLAN_EID_SSID;
341                                 } else {
342                                         memcpy(pos, tmp_old, tmp_old[1] + 2);
343                                         pos += tmp_old[1] + 2;
344                                 }
345                         } else {
346                                 /* copy ie from subelement into new ie */
347                                 memcpy(pos, tmp, tmp[1] + 2);
348                                 pos += tmp[1] + 2;
349                                 tmp[0] = WLAN_EID_SSID;
350                         }
351                 }
352
353                 if (tmp_old + tmp_old[1] + 2 - ie == ielen)
354                         break;
355
356                 tmp_old += tmp_old[1] + 2;
357         }
358
359         /* go through subelement again to check if there is any ie not
360          * copied to new ie, skip ssid, capability, bssid-index ie
361          */
362         tmp_new = sub_copy;
363         while (tmp_new + 2 - sub_copy <= subie_len &&
364                tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
365                 if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
366                       tmp_new[0] == WLAN_EID_SSID)) {
367                         memcpy(pos, tmp_new, tmp_new[1] + 2);
368                         pos += tmp_new[1] + 2;
369                 }
370                 if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len)
371                         break;
372                 tmp_new += tmp_new[1] + 2;
373         }
374
375         kfree(sub_copy);
376         return pos - new_ie;
377 }
378
379 static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
380                    const u8 *ssid, size_t ssid_len)
381 {
382         const struct cfg80211_bss_ies *ies;
383         const struct element *ssid_elem;
384
385         if (bssid && !ether_addr_equal(a->bssid, bssid))
386                 return false;
387
388         if (!ssid)
389                 return true;
390
391         ies = rcu_access_pointer(a->ies);
392         if (!ies)
393                 return false;
394         ssid_elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
395         if (!ssid_elem)
396                 return false;
397         if (ssid_elem->datalen != ssid_len)
398                 return false;
399         return memcmp(ssid_elem->data, ssid, ssid_len) == 0;
400 }
401
402 static int
403 cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
404                            struct cfg80211_bss *nontrans_bss)
405 {
406         const struct element *ssid_elem;
407         struct cfg80211_bss *bss = NULL;
408
409         rcu_read_lock();
410         ssid_elem = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID);
411         if (!ssid_elem) {
412                 rcu_read_unlock();
413                 return -EINVAL;
414         }
415
416         /* check if nontrans_bss is in the list */
417         list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) {
418                 if (is_bss(bss, nontrans_bss->bssid, ssid_elem->data,
419                            ssid_elem->datalen)) {
420                         rcu_read_unlock();
421                         return 0;
422                 }
423         }
424
425         rcu_read_unlock();
426
427         /*
428          * This is a bit weird - it's not on the list, but already on another
429          * one! The only way that could happen is if there's some BSSID/SSID
430          * shared by multiple APs in their multi-BSSID profiles, potentially
431          * with hidden SSID mixed in ... ignore it.
432          */
433         if (!list_empty(&nontrans_bss->nontrans_list))
434                 return -EINVAL;
435
436         /* add to the list */
437         list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
438         return 0;
439 }
440
441 static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev,
442                                   unsigned long expire_time)
443 {
444         struct cfg80211_internal_bss *bss, *tmp;
445         bool expired = false;
446
447         lockdep_assert_held(&rdev->bss_lock);
448
449         list_for_each_entry_safe(bss, tmp, &rdev->bss_list, list) {
450                 if (atomic_read(&bss->hold))
451                         continue;
452                 if (!time_after(expire_time, bss->ts))
453                         continue;
454
455                 if (__cfg80211_unlink_bss(rdev, bss))
456                         expired = true;
457         }
458
459         if (expired)
460                 rdev->bss_generation++;
461 }
462
463 static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
464 {
465         struct cfg80211_internal_bss *bss, *oldest = NULL;
466         bool ret;
467
468         lockdep_assert_held(&rdev->bss_lock);
469
470         list_for_each_entry(bss, &rdev->bss_list, list) {
471                 if (atomic_read(&bss->hold))
472                         continue;
473
474                 if (!list_empty(&bss->hidden_list) &&
475                     !bss->pub.hidden_beacon_bss)
476                         continue;
477
478                 if (oldest && time_before(oldest->ts, bss->ts))
479                         continue;
480                 oldest = bss;
481         }
482
483         if (WARN_ON(!oldest))
484                 return false;
485
486         /*
487          * The callers make sure to increase rdev->bss_generation if anything
488          * gets removed (and a new entry added), so there's no need to also do
489          * it here.
490          */
491
492         ret = __cfg80211_unlink_bss(rdev, oldest);
493         WARN_ON(!ret);
494         return ret;
495 }
496
497 static u8 cfg80211_parse_bss_param(u8 data,
498                                    struct cfg80211_colocated_ap *coloc_ap)
499 {
500         coloc_ap->oct_recommended =
501                 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_OCT_RECOMMENDED);
502         coloc_ap->same_ssid =
503                 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_SAME_SSID);
504         coloc_ap->multi_bss =
505                 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID);
506         coloc_ap->transmitted_bssid =
507                 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID);
508         coloc_ap->unsolicited_probe =
509                 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE);
510         coloc_ap->colocated_ess =
511                 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS);
512
513         return u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_AP);
514 }
515
516 static int cfg80211_calc_short_ssid(const struct cfg80211_bss_ies *ies,
517                                     const struct element **elem, u32 *s_ssid)
518 {
519
520         *elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
521         if (!*elem || (*elem)->datalen > IEEE80211_MAX_SSID_LEN)
522                 return -EINVAL;
523
524         *s_ssid = ~crc32_le(~0, (*elem)->data, (*elem)->datalen);
525         return 0;
526 }
527
528 static void cfg80211_free_coloc_ap_list(struct list_head *coloc_ap_list)
529 {
530         struct cfg80211_colocated_ap *ap, *tmp_ap;
531
532         list_for_each_entry_safe(ap, tmp_ap, coloc_ap_list, list) {
533                 list_del(&ap->list);
534                 kfree(ap);
535         }
536 }
537
538 static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
539                                   const u8 *pos, u8 length,
540                                   const struct element *ssid_elem,
541                                   int s_ssid_tmp)
542 {
543         /* skip the TBTT offset */
544         pos++;
545
546         /* ignore entries with invalid BSSID */
547         if (!is_valid_ether_addr(pos))
548                 return -EINVAL;
549
550         memcpy(entry->bssid, pos, ETH_ALEN);
551         pos += ETH_ALEN;
552
553         if (length >= IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM) {
554                 memcpy(&entry->short_ssid, pos,
555                        sizeof(entry->short_ssid));
556                 entry->short_ssid_valid = true;
557                 pos += 4;
558         }
559
560         /* skip non colocated APs */
561         if (!cfg80211_parse_bss_param(*pos, entry))
562                 return -EINVAL;
563         pos++;
564
565         if (length == IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM) {
566                 /*
567                  * no information about the short ssid. Consider the entry valid
568                  * for now. It would later be dropped in case there are explicit
569                  * SSIDs that need to be matched
570                  */
571                 if (!entry->same_ssid)
572                         return 0;
573         }
574
575         if (entry->same_ssid) {
576                 entry->short_ssid = s_ssid_tmp;
577                 entry->short_ssid_valid = true;
578
579                 /*
580                  * This is safe because we validate datalen in
581                  * cfg80211_parse_colocated_ap(), before calling this
582                  * function.
583                  */
584                 memcpy(&entry->ssid, &ssid_elem->data,
585                        ssid_elem->datalen);
586                 entry->ssid_len = ssid_elem->datalen;
587         }
588         return 0;
589 }
590
591 static int cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies,
592                                        struct list_head *list)
593 {
594         struct ieee80211_neighbor_ap_info *ap_info;
595         const struct element *elem, *ssid_elem;
596         const u8 *pos, *end;
597         u32 s_ssid_tmp;
598         int n_coloc = 0, ret;
599         LIST_HEAD(ap_list);
600
601         elem = cfg80211_find_elem(WLAN_EID_REDUCED_NEIGHBOR_REPORT, ies->data,
602                                   ies->len);
603         if (!elem)
604                 return 0;
605
606         pos = elem->data;
607         end = pos + elem->datalen;
608
609         ret = cfg80211_calc_short_ssid(ies, &ssid_elem, &s_ssid_tmp);
610         if (ret)
611                 return ret;
612
613         /* RNR IE may contain more than one NEIGHBOR_AP_INFO */
614         while (pos + sizeof(*ap_info) <= end) {
615                 enum nl80211_band band;
616                 int freq;
617                 u8 length, i, count;
618
619                 ap_info = (void *)pos;
620                 count = u8_get_bits(ap_info->tbtt_info_hdr,
621                                     IEEE80211_AP_INFO_TBTT_HDR_COUNT) + 1;
622                 length = ap_info->tbtt_info_len;
623
624                 pos += sizeof(*ap_info);
625
626                 if (!ieee80211_operating_class_to_band(ap_info->op_class,
627                                                        &band))
628                         break;
629
630                 freq = ieee80211_channel_to_frequency(ap_info->channel, band);
631
632                 if (end - pos < count * length)
633                         break;
634
635                 /*
636                  * TBTT info must include bss param + BSSID +
637                  * (short SSID or same_ssid bit to be set).
638                  * ignore other options, and move to the
639                  * next AP info
640                  */
641                 if (band != NL80211_BAND_6GHZ ||
642                     (length != IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM &&
643                      length < IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM)) {
644                         pos += count * length;
645                         continue;
646                 }
647
648                 for (i = 0; i < count; i++) {
649                         struct cfg80211_colocated_ap *entry;
650
651                         entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN,
652                                         GFP_ATOMIC);
653
654                         if (!entry)
655                                 break;
656
657                         entry->center_freq = freq;
658
659                         if (!cfg80211_parse_ap_info(entry, pos, length,
660                                                     ssid_elem, s_ssid_tmp)) {
661                                 n_coloc++;
662                                 list_add_tail(&entry->list, &ap_list);
663                         } else {
664                                 kfree(entry);
665                         }
666
667                         pos += length;
668                 }
669         }
670
671         if (pos != end) {
672                 cfg80211_free_coloc_ap_list(&ap_list);
673                 return 0;
674         }
675
676         list_splice_tail(&ap_list, list);
677         return n_coloc;
678 }
679
680 static  void cfg80211_scan_req_add_chan(struct cfg80211_scan_request *request,
681                                         struct ieee80211_channel *chan,
682                                         bool add_to_6ghz)
683 {
684         int i;
685         u32 n_channels = request->n_channels;
686         struct cfg80211_scan_6ghz_params *params =
687                 &request->scan_6ghz_params[request->n_6ghz_params];
688
689         for (i = 0; i < n_channels; i++) {
690                 if (request->channels[i] == chan) {
691                         if (add_to_6ghz)
692                                 params->channel_idx = i;
693                         return;
694                 }
695         }
696
697         request->channels[n_channels] = chan;
698         if (add_to_6ghz)
699                 request->scan_6ghz_params[request->n_6ghz_params].channel_idx =
700                         n_channels;
701
702         request->n_channels++;
703 }
704
705 static bool cfg80211_find_ssid_match(struct cfg80211_colocated_ap *ap,
706                                      struct cfg80211_scan_request *request)
707 {
708         int i;
709         u32 s_ssid;
710
711         for (i = 0; i < request->n_ssids; i++) {
712                 /* wildcard ssid in the scan request */
713                 if (!request->ssids[i].ssid_len) {
714                         if (ap->multi_bss && !ap->transmitted_bssid)
715                                 continue;
716
717                         return true;
718                 }
719
720                 if (ap->ssid_len &&
721                     ap->ssid_len == request->ssids[i].ssid_len) {
722                         if (!memcmp(request->ssids[i].ssid, ap->ssid,
723                                     ap->ssid_len))
724                                 return true;
725                 } else if (ap->short_ssid_valid) {
726                         s_ssid = ~crc32_le(~0, request->ssids[i].ssid,
727                                            request->ssids[i].ssid_len);
728
729                         if (ap->short_ssid == s_ssid)
730                                 return true;
731                 }
732         }
733
734         return false;
735 }
736
737 static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
738 {
739         u8 i;
740         struct cfg80211_colocated_ap *ap;
741         int n_channels, count = 0, err;
742         struct cfg80211_scan_request *request, *rdev_req = rdev->scan_req;
743         LIST_HEAD(coloc_ap_list);
744         bool need_scan_psc = true;
745         const struct ieee80211_sband_iftype_data *iftd;
746
747         rdev_req->scan_6ghz = true;
748
749         if (!rdev->wiphy.bands[NL80211_BAND_6GHZ])
750                 return -EOPNOTSUPP;
751
752         iftd = ieee80211_get_sband_iftype_data(rdev->wiphy.bands[NL80211_BAND_6GHZ],
753                                                rdev_req->wdev->iftype);
754         if (!iftd || !iftd->he_cap.has_he)
755                 return -EOPNOTSUPP;
756
757         n_channels = rdev->wiphy.bands[NL80211_BAND_6GHZ]->n_channels;
758
759         if (rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) {
760                 struct cfg80211_internal_bss *intbss;
761
762                 spin_lock_bh(&rdev->bss_lock);
763                 list_for_each_entry(intbss, &rdev->bss_list, list) {
764                         struct cfg80211_bss *res = &intbss->pub;
765                         const struct cfg80211_bss_ies *ies;
766
767                         ies = rcu_access_pointer(res->ies);
768                         count += cfg80211_parse_colocated_ap(ies,
769                                                              &coloc_ap_list);
770                 }
771                 spin_unlock_bh(&rdev->bss_lock);
772         }
773
774         request = kzalloc(struct_size(request, channels, n_channels) +
775                           sizeof(*request->scan_6ghz_params) * count +
776                           sizeof(*request->ssids) * rdev_req->n_ssids,
777                           GFP_KERNEL);
778         if (!request) {
779                 cfg80211_free_coloc_ap_list(&coloc_ap_list);
780                 return -ENOMEM;
781         }
782
783         *request = *rdev_req;
784         request->n_channels = 0;
785         request->scan_6ghz_params =
786                 (void *)&request->channels[n_channels];
787
788         /*
789          * PSC channels should not be scanned in case of direct scan with 1 SSID
790          * and at least one of the reported co-located APs with same SSID
791          * indicating that all APs in the same ESS are co-located
792          */
793         if (count && request->n_ssids == 1 && request->ssids[0].ssid_len) {
794                 list_for_each_entry(ap, &coloc_ap_list, list) {
795                         if (ap->colocated_ess &&
796                             cfg80211_find_ssid_match(ap, request)) {
797                                 need_scan_psc = false;
798                                 break;
799                         }
800                 }
801         }
802
803         /*
804          * add to the scan request the channels that need to be scanned
805          * regardless of the collocated APs (PSC channels or all channels
806          * in case that NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set)
807          */
808         for (i = 0; i < rdev_req->n_channels; i++) {
809                 if (rdev_req->channels[i]->band == NL80211_BAND_6GHZ &&
810                     ((need_scan_psc &&
811                       cfg80211_channel_is_psc(rdev_req->channels[i])) ||
812                      !(rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))) {
813                         cfg80211_scan_req_add_chan(request,
814                                                    rdev_req->channels[i],
815                                                    false);
816                 }
817         }
818
819         if (!(rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))
820                 goto skip;
821
822         list_for_each_entry(ap, &coloc_ap_list, list) {
823                 bool found = false;
824                 struct cfg80211_scan_6ghz_params *scan_6ghz_params =
825                         &request->scan_6ghz_params[request->n_6ghz_params];
826                 struct ieee80211_channel *chan =
827                         ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
828
829                 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
830                         continue;
831
832                 for (i = 0; i < rdev_req->n_channels; i++) {
833                         if (rdev_req->channels[i] == chan)
834                                 found = true;
835                 }
836
837                 if (!found)
838                         continue;
839
840                 if (request->n_ssids > 0 &&
841                     !cfg80211_find_ssid_match(ap, request))
842                         continue;
843
844                 if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid)
845                         continue;
846
847                 cfg80211_scan_req_add_chan(request, chan, true);
848                 memcpy(scan_6ghz_params->bssid, ap->bssid, ETH_ALEN);
849                 scan_6ghz_params->short_ssid = ap->short_ssid;
850                 scan_6ghz_params->short_ssid_valid = ap->short_ssid_valid;
851                 scan_6ghz_params->unsolicited_probe = ap->unsolicited_probe;
852
853                 /*
854                  * If a PSC channel is added to the scan and 'need_scan_psc' is
855                  * set to false, then all the APs that the scan logic is
856                  * interested with on the channel are collocated and thus there
857                  * is no need to perform the initial PSC channel listen.
858                  */
859                 if (cfg80211_channel_is_psc(chan) && !need_scan_psc)
860                         scan_6ghz_params->psc_no_listen = true;
861
862                 request->n_6ghz_params++;
863         }
864
865 skip:
866         cfg80211_free_coloc_ap_list(&coloc_ap_list);
867
868         if (request->n_channels) {
869                 struct cfg80211_scan_request *old = rdev->int_scan_req;
870                 rdev->int_scan_req = request;
871
872                 /*
873                  * Add the ssids from the parent scan request to the new scan
874                  * request, so the driver would be able to use them in its
875                  * probe requests to discover hidden APs on PSC channels.
876                  */
877                 request->ssids = (void *)&request->channels[request->n_channels];
878                 request->n_ssids = rdev_req->n_ssids;
879                 memcpy(request->ssids, rdev_req->ssids, sizeof(*request->ssids) *
880                        request->n_ssids);
881
882                 /*
883                  * If this scan follows a previous scan, save the scan start
884                  * info from the first part of the scan
885                  */
886                 if (old)
887                         rdev->int_scan_req->info = old->info;
888
889                 err = rdev_scan(rdev, request);
890                 if (err) {
891                         rdev->int_scan_req = old;
892                         kfree(request);
893                 } else {
894                         kfree(old);
895                 }
896
897                 return err;
898         }
899
900         kfree(request);
901         return -EINVAL;
902 }
903
904 int cfg80211_scan(struct cfg80211_registered_device *rdev)
905 {
906         struct cfg80211_scan_request *request;
907         struct cfg80211_scan_request *rdev_req = rdev->scan_req;
908         u32 n_channels = 0, idx, i;
909
910         if (!(rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ))
911                 return rdev_scan(rdev, rdev_req);
912
913         for (i = 0; i < rdev_req->n_channels; i++) {
914                 if (rdev_req->channels[i]->band != NL80211_BAND_6GHZ)
915                         n_channels++;
916         }
917
918         if (!n_channels)
919                 return cfg80211_scan_6ghz(rdev);
920
921         request = kzalloc(struct_size(request, channels, n_channels),
922                           GFP_KERNEL);
923         if (!request)
924                 return -ENOMEM;
925
926         *request = *rdev_req;
927         request->n_channels = n_channels;
928
929         for (i = idx = 0; i < rdev_req->n_channels; i++) {
930                 if (rdev_req->channels[i]->band != NL80211_BAND_6GHZ)
931                         request->channels[idx++] = rdev_req->channels[i];
932         }
933
934         rdev_req->scan_6ghz = false;
935         rdev->int_scan_req = request;
936         return rdev_scan(rdev, request);
937 }
938
939 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
940                            bool send_message)
941 {
942         struct cfg80211_scan_request *request, *rdev_req;
943         struct wireless_dev *wdev;
944         struct sk_buff *msg;
945 #ifdef CONFIG_CFG80211_WEXT
946         union iwreq_data wrqu;
947 #endif
948
949         lockdep_assert_held(&rdev->wiphy.mtx);
950
951         if (rdev->scan_msg) {
952                 nl80211_send_scan_msg(rdev, rdev->scan_msg);
953                 rdev->scan_msg = NULL;
954                 return;
955         }
956
957         rdev_req = rdev->scan_req;
958         if (!rdev_req)
959                 return;
960
961         wdev = rdev_req->wdev;
962         request = rdev->int_scan_req ? rdev->int_scan_req : rdev_req;
963
964         if (wdev_running(wdev) &&
965             (rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ) &&
966             !rdev_req->scan_6ghz && !request->info.aborted &&
967             !cfg80211_scan_6ghz(rdev))
968                 return;
969
970         /*
971          * This must be before sending the other events!
972          * Otherwise, wpa_supplicant gets completely confused with
973          * wext events.
974          */
975         if (wdev->netdev)
976                 cfg80211_sme_scan_done(wdev->netdev);
977
978         if (!request->info.aborted &&
979             request->flags & NL80211_SCAN_FLAG_FLUSH) {
980                 /* flush entries from previous scans */
981                 spin_lock_bh(&rdev->bss_lock);
982                 __cfg80211_bss_expire(rdev, request->scan_start);
983                 spin_unlock_bh(&rdev->bss_lock);
984         }
985
986         msg = nl80211_build_scan_msg(rdev, wdev, request->info.aborted);
987
988 #ifdef CONFIG_CFG80211_WEXT
989         if (wdev->netdev && !request->info.aborted) {
990                 memset(&wrqu, 0, sizeof(wrqu));
991
992                 wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
993         }
994 #endif
995
996         dev_put(wdev->netdev);
997
998         kfree(rdev->int_scan_req);
999         rdev->int_scan_req = NULL;
1000
1001         kfree(rdev->scan_req);
1002         rdev->scan_req = NULL;
1003
1004         if (!send_message)
1005                 rdev->scan_msg = msg;
1006         else
1007                 nl80211_send_scan_msg(rdev, msg);
1008 }
1009
1010 void __cfg80211_scan_done(struct work_struct *wk)
1011 {
1012         struct cfg80211_registered_device *rdev;
1013
1014         rdev = container_of(wk, struct cfg80211_registered_device,
1015                             scan_done_wk);
1016
1017         wiphy_lock(&rdev->wiphy);
1018         ___cfg80211_scan_done(rdev, true);
1019         wiphy_unlock(&rdev->wiphy);
1020 }
1021
1022 void cfg80211_scan_done(struct cfg80211_scan_request *request,
1023                         struct cfg80211_scan_info *info)
1024 {
1025         struct cfg80211_scan_info old_info = request->info;
1026
1027         trace_cfg80211_scan_done(request, info);
1028         WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req &&
1029                 request != wiphy_to_rdev(request->wiphy)->int_scan_req);
1030
1031         request->info = *info;
1032
1033         /*
1034          * In case the scan is split, the scan_start_tsf and tsf_bssid should
1035          * be of the first part. In such a case old_info.scan_start_tsf should
1036          * be non zero.
1037          */
1038         if (request->scan_6ghz && old_info.scan_start_tsf) {
1039                 request->info.scan_start_tsf = old_info.scan_start_tsf;
1040                 memcpy(request->info.tsf_bssid, old_info.tsf_bssid,
1041                        sizeof(request->info.tsf_bssid));
1042         }
1043
1044         request->notified = true;
1045         queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk);
1046 }
1047 EXPORT_SYMBOL(cfg80211_scan_done);
1048
1049 void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
1050                                  struct cfg80211_sched_scan_request *req)
1051 {
1052         lockdep_assert_held(&rdev->wiphy.mtx);
1053
1054         list_add_rcu(&req->list, &rdev->sched_scan_req_list);
1055 }
1056
1057 static void cfg80211_del_sched_scan_req(struct cfg80211_registered_device *rdev,
1058                                         struct cfg80211_sched_scan_request *req)
1059 {
1060         lockdep_assert_held(&rdev->wiphy.mtx);
1061
1062         list_del_rcu(&req->list);
1063         kfree_rcu(req, rcu_head);
1064 }
1065
1066 static struct cfg80211_sched_scan_request *
1067 cfg80211_find_sched_scan_req(struct cfg80211_registered_device *rdev, u64 reqid)
1068 {
1069         struct cfg80211_sched_scan_request *pos;
1070
1071         list_for_each_entry_rcu(pos, &rdev->sched_scan_req_list, list,
1072                                 lockdep_is_held(&rdev->wiphy.mtx)) {
1073                 if (pos->reqid == reqid)
1074                         return pos;
1075         }
1076         return NULL;
1077 }
1078
1079 /*
1080  * Determines if a scheduled scan request can be handled. When a legacy
1081  * scheduled scan is running no other scheduled scan is allowed regardless
1082  * whether the request is for legacy or multi-support scan. When a multi-support
1083  * scheduled scan is running a request for legacy scan is not allowed. In this
1084  * case a request for multi-support scan can be handled if resources are
1085  * available, ie. struct wiphy::max_sched_scan_reqs limit is not yet reached.
1086  */
1087 int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
1088                                      bool want_multi)
1089 {
1090         struct cfg80211_sched_scan_request *pos;
1091         int i = 0;
1092
1093         list_for_each_entry(pos, &rdev->sched_scan_req_list, list) {
1094                 /* request id zero means legacy in progress */
1095                 if (!i && !pos->reqid)
1096                         return -EINPROGRESS;
1097                 i++;
1098         }
1099
1100         if (i) {
1101                 /* no legacy allowed when multi request(s) are active */
1102                 if (!want_multi)
1103                         return -EINPROGRESS;
1104
1105                 /* resource limit reached */
1106                 if (i == rdev->wiphy.max_sched_scan_reqs)
1107                         return -ENOSPC;
1108         }
1109         return 0;
1110 }
1111
1112 void cfg80211_sched_scan_results_wk(struct work_struct *work)
1113 {
1114         struct cfg80211_registered_device *rdev;
1115         struct cfg80211_sched_scan_request *req, *tmp;
1116
1117         rdev = container_of(work, struct cfg80211_registered_device,
1118                            sched_scan_res_wk);
1119
1120         wiphy_lock(&rdev->wiphy);
1121         list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
1122                 if (req->report_results) {
1123                         req->report_results = false;
1124                         if (req->flags & NL80211_SCAN_FLAG_FLUSH) {
1125                                 /* flush entries from previous scans */
1126                                 spin_lock_bh(&rdev->bss_lock);
1127                                 __cfg80211_bss_expire(rdev, req->scan_start);
1128                                 spin_unlock_bh(&rdev->bss_lock);
1129                                 req->scan_start = jiffies;
1130                         }
1131                         nl80211_send_sched_scan(req,
1132                                                 NL80211_CMD_SCHED_SCAN_RESULTS);
1133                 }
1134         }
1135         wiphy_unlock(&rdev->wiphy);
1136 }
1137
1138 void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid)
1139 {
1140         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1141         struct cfg80211_sched_scan_request *request;
1142
1143         trace_cfg80211_sched_scan_results(wiphy, reqid);
1144         /* ignore if we're not scanning */
1145
1146         rcu_read_lock();
1147         request = cfg80211_find_sched_scan_req(rdev, reqid);
1148         if (request) {
1149                 request->report_results = true;
1150                 queue_work(cfg80211_wq, &rdev->sched_scan_res_wk);
1151         }
1152         rcu_read_unlock();
1153 }
1154 EXPORT_SYMBOL(cfg80211_sched_scan_results);
1155
1156 void cfg80211_sched_scan_stopped_locked(struct wiphy *wiphy, u64 reqid)
1157 {
1158         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1159
1160         lockdep_assert_held(&wiphy->mtx);
1161
1162         trace_cfg80211_sched_scan_stopped(wiphy, reqid);
1163
1164         __cfg80211_stop_sched_scan(rdev, reqid, true);
1165 }
1166 EXPORT_SYMBOL(cfg80211_sched_scan_stopped_locked);
1167
1168 void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid)
1169 {
1170         wiphy_lock(wiphy);
1171         cfg80211_sched_scan_stopped_locked(wiphy, reqid);
1172         wiphy_unlock(wiphy);
1173 }
1174 EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
1175
1176 int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
1177                                  struct cfg80211_sched_scan_request *req,
1178                                  bool driver_initiated)
1179 {
1180         lockdep_assert_held(&rdev->wiphy.mtx);
1181
1182         if (!driver_initiated) {
1183                 int err = rdev_sched_scan_stop(rdev, req->dev, req->reqid);
1184                 if (err)
1185                         return err;
1186         }
1187
1188         nl80211_send_sched_scan(req, NL80211_CMD_SCHED_SCAN_STOPPED);
1189
1190         cfg80211_del_sched_scan_req(rdev, req);
1191
1192         return 0;
1193 }
1194
1195 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
1196                                u64 reqid, bool driver_initiated)
1197 {
1198         struct cfg80211_sched_scan_request *sched_scan_req;
1199
1200         lockdep_assert_held(&rdev->wiphy.mtx);
1201
1202         sched_scan_req = cfg80211_find_sched_scan_req(rdev, reqid);
1203         if (!sched_scan_req)
1204                 return -ENOENT;
1205
1206         return cfg80211_stop_sched_scan_req(rdev, sched_scan_req,
1207                                             driver_initiated);
1208 }
1209
1210 void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
1211                       unsigned long age_secs)
1212 {
1213         struct cfg80211_internal_bss *bss;
1214         unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
1215
1216         spin_lock_bh(&rdev->bss_lock);
1217         list_for_each_entry(bss, &rdev->bss_list, list)
1218                 bss->ts -= age_jiffies;
1219         spin_unlock_bh(&rdev->bss_lock);
1220 }
1221
1222 void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
1223 {
1224         __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
1225 }
1226
1227 void cfg80211_bss_flush(struct wiphy *wiphy)
1228 {
1229         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1230
1231         spin_lock_bh(&rdev->bss_lock);
1232         __cfg80211_bss_expire(rdev, jiffies);
1233         spin_unlock_bh(&rdev->bss_lock);
1234 }
1235 EXPORT_SYMBOL(cfg80211_bss_flush);
1236
1237 const struct element *
1238 cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
1239                          const u8 *match, unsigned int match_len,
1240                          unsigned int match_offset)
1241 {
1242         const struct element *elem;
1243
1244         for_each_element_id(elem, eid, ies, len) {
1245                 if (elem->datalen >= match_offset + match_len &&
1246                     !memcmp(elem->data + match_offset, match, match_len))
1247                         return elem;
1248         }
1249
1250         return NULL;
1251 }
1252 EXPORT_SYMBOL(cfg80211_find_elem_match);
1253
1254 const struct element *cfg80211_find_vendor_elem(unsigned int oui, int oui_type,
1255                                                 const u8 *ies,
1256                                                 unsigned int len)
1257 {
1258         const struct element *elem;
1259         u8 match[] = { oui >> 16, oui >> 8, oui, oui_type };
1260         int match_len = (oui_type < 0) ? 3 : sizeof(match);
1261
1262         if (WARN_ON(oui_type > 0xff))
1263                 return NULL;
1264
1265         elem = cfg80211_find_elem_match(WLAN_EID_VENDOR_SPECIFIC, ies, len,
1266                                         match, match_len, 0);
1267
1268         if (!elem || elem->datalen < 4)
1269                 return NULL;
1270
1271         return elem;
1272 }
1273 EXPORT_SYMBOL(cfg80211_find_vendor_elem);
1274
1275 /**
1276  * enum bss_compare_mode - BSS compare mode
1277  * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find)
1278  * @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
1279  * @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
1280  */
1281 enum bss_compare_mode {
1282         BSS_CMP_REGULAR,
1283         BSS_CMP_HIDE_ZLEN,
1284         BSS_CMP_HIDE_NUL,
1285 };
1286
1287 static int cmp_bss(struct cfg80211_bss *a,
1288                    struct cfg80211_bss *b,
1289                    enum bss_compare_mode mode)
1290 {
1291         const struct cfg80211_bss_ies *a_ies, *b_ies;
1292         const u8 *ie1 = NULL;
1293         const u8 *ie2 = NULL;
1294         int i, r;
1295
1296         if (a->channel != b->channel)
1297                 return b->channel->center_freq - a->channel->center_freq;
1298
1299         a_ies = rcu_access_pointer(a->ies);
1300         if (!a_ies)
1301                 return -1;
1302         b_ies = rcu_access_pointer(b->ies);
1303         if (!b_ies)
1304                 return 1;
1305
1306         if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
1307                 ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
1308                                        a_ies->data, a_ies->len);
1309         if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
1310                 ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
1311                                        b_ies->data, b_ies->len);
1312         if (ie1 && ie2) {
1313                 int mesh_id_cmp;
1314
1315                 if (ie1[1] == ie2[1])
1316                         mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1317                 else
1318                         mesh_id_cmp = ie2[1] - ie1[1];
1319
1320                 ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
1321                                        a_ies->data, a_ies->len);
1322                 ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
1323                                        b_ies->data, b_ies->len);
1324                 if (ie1 && ie2) {
1325                         if (mesh_id_cmp)
1326                                 return mesh_id_cmp;
1327                         if (ie1[1] != ie2[1])
1328                                 return ie2[1] - ie1[1];
1329                         return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1330                 }
1331         }
1332
1333         r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
1334         if (r)
1335                 return r;
1336
1337         ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
1338         ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
1339
1340         if (!ie1 && !ie2)
1341                 return 0;
1342
1343         /*
1344          * Note that with "hide_ssid", the function returns a match if
1345          * the already-present BSS ("b") is a hidden SSID beacon for
1346          * the new BSS ("a").
1347          */
1348
1349         /* sort missing IE before (left of) present IE */
1350         if (!ie1)
1351                 return -1;
1352         if (!ie2)
1353                 return 1;
1354
1355         switch (mode) {
1356         case BSS_CMP_HIDE_ZLEN:
1357                 /*
1358                  * In ZLEN mode we assume the BSS entry we're
1359                  * looking for has a zero-length SSID. So if
1360                  * the one we're looking at right now has that,
1361                  * return 0. Otherwise, return the difference
1362                  * in length, but since we're looking for the
1363                  * 0-length it's really equivalent to returning
1364                  * the length of the one we're looking at.
1365                  *
1366                  * No content comparison is needed as we assume
1367                  * the content length is zero.
1368                  */
1369                 return ie2[1];
1370         case BSS_CMP_REGULAR:
1371         default:
1372                 /* sort by length first, then by contents */
1373                 if (ie1[1] != ie2[1])
1374                         return ie2[1] - ie1[1];
1375                 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1376         case BSS_CMP_HIDE_NUL:
1377                 if (ie1[1] != ie2[1])
1378                         return ie2[1] - ie1[1];
1379                 /* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
1380                 for (i = 0; i < ie2[1]; i++)
1381                         if (ie2[i + 2])
1382                                 return -1;
1383                 return 0;
1384         }
1385 }
1386
1387 static bool cfg80211_bss_type_match(u16 capability,
1388                                     enum nl80211_band band,
1389                                     enum ieee80211_bss_type bss_type)
1390 {
1391         bool ret = true;
1392         u16 mask, val;
1393
1394         if (bss_type == IEEE80211_BSS_TYPE_ANY)
1395                 return ret;
1396
1397         if (band == NL80211_BAND_60GHZ) {
1398                 mask = WLAN_CAPABILITY_DMG_TYPE_MASK;
1399                 switch (bss_type) {
1400                 case IEEE80211_BSS_TYPE_ESS:
1401                         val = WLAN_CAPABILITY_DMG_TYPE_AP;
1402                         break;
1403                 case IEEE80211_BSS_TYPE_PBSS:
1404                         val = WLAN_CAPABILITY_DMG_TYPE_PBSS;
1405                         break;
1406                 case IEEE80211_BSS_TYPE_IBSS:
1407                         val = WLAN_CAPABILITY_DMG_TYPE_IBSS;
1408                         break;
1409                 default:
1410                         return false;
1411                 }
1412         } else {
1413                 mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS;
1414                 switch (bss_type) {
1415                 case IEEE80211_BSS_TYPE_ESS:
1416                         val = WLAN_CAPABILITY_ESS;
1417                         break;
1418                 case IEEE80211_BSS_TYPE_IBSS:
1419                         val = WLAN_CAPABILITY_IBSS;
1420                         break;
1421                 case IEEE80211_BSS_TYPE_MBSS:
1422                         val = 0;
1423                         break;
1424                 default:
1425                         return false;
1426                 }
1427         }
1428
1429         ret = ((capability & mask) == val);
1430         return ret;
1431 }
1432
1433 /* Returned bss is reference counted and must be cleaned up appropriately. */
1434 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
1435                                       struct ieee80211_channel *channel,
1436                                       const u8 *bssid,
1437                                       const u8 *ssid, size_t ssid_len,
1438                                       enum ieee80211_bss_type bss_type,
1439                                       enum ieee80211_privacy privacy)
1440 {
1441         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1442         struct cfg80211_internal_bss *bss, *res = NULL;
1443         unsigned long now = jiffies;
1444         int bss_privacy;
1445
1446         trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type,
1447                                privacy);
1448
1449         spin_lock_bh(&rdev->bss_lock);
1450
1451         list_for_each_entry(bss, &rdev->bss_list, list) {
1452                 if (!cfg80211_bss_type_match(bss->pub.capability,
1453                                              bss->pub.channel->band, bss_type))
1454                         continue;
1455
1456                 bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY);
1457                 if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) ||
1458                     (privacy == IEEE80211_PRIVACY_OFF && bss_privacy))
1459                         continue;
1460                 if (channel && bss->pub.channel != channel)
1461                         continue;
1462                 if (!is_valid_ether_addr(bss->pub.bssid))
1463                         continue;
1464                 /* Don't get expired BSS structs */
1465                 if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
1466                     !atomic_read(&bss->hold))
1467                         continue;
1468                 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
1469                         res = bss;
1470                         bss_ref_get(rdev, res);
1471                         break;
1472                 }
1473         }
1474
1475         spin_unlock_bh(&rdev->bss_lock);
1476         if (!res)
1477                 return NULL;
1478         trace_cfg80211_return_bss(&res->pub);
1479         return &res->pub;
1480 }
1481 EXPORT_SYMBOL(cfg80211_get_bss);
1482
1483 static void rb_insert_bss(struct cfg80211_registered_device *rdev,
1484                           struct cfg80211_internal_bss *bss)
1485 {
1486         struct rb_node **p = &rdev->bss_tree.rb_node;
1487         struct rb_node *parent = NULL;
1488         struct cfg80211_internal_bss *tbss;
1489         int cmp;
1490
1491         while (*p) {
1492                 parent = *p;
1493                 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
1494
1495                 cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);
1496
1497                 if (WARN_ON(!cmp)) {
1498                         /* will sort of leak this BSS */
1499                         return;
1500                 }
1501
1502                 if (cmp < 0)
1503                         p = &(*p)->rb_left;
1504                 else
1505                         p = &(*p)->rb_right;
1506         }
1507
1508         rb_link_node(&bss->rbn, parent, p);
1509         rb_insert_color(&bss->rbn, &rdev->bss_tree);
1510 }
1511
1512 static struct cfg80211_internal_bss *
1513 rb_find_bss(struct cfg80211_registered_device *rdev,
1514             struct cfg80211_internal_bss *res,
1515             enum bss_compare_mode mode)
1516 {
1517         struct rb_node *n = rdev->bss_tree.rb_node;
1518         struct cfg80211_internal_bss *bss;
1519         int r;
1520
1521         while (n) {
1522                 bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
1523                 r = cmp_bss(&res->pub, &bss->pub, mode);
1524
1525                 if (r == 0)
1526                         return bss;
1527                 else if (r < 0)
1528                         n = n->rb_left;
1529                 else
1530                         n = n->rb_right;
1531         }
1532
1533         return NULL;
1534 }
1535
1536 static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
1537                                    struct cfg80211_internal_bss *new)
1538 {
1539         const struct cfg80211_bss_ies *ies;
1540         struct cfg80211_internal_bss *bss;
1541         const u8 *ie;
1542         int i, ssidlen;
1543         u8 fold = 0;
1544         u32 n_entries = 0;
1545
1546         ies = rcu_access_pointer(new->pub.beacon_ies);
1547         if (WARN_ON(!ies))
1548                 return false;
1549
1550         ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1551         if (!ie) {
1552                 /* nothing to do */
1553                 return true;
1554         }
1555
1556         ssidlen = ie[1];
1557         for (i = 0; i < ssidlen; i++)
1558                 fold |= ie[2 + i];
1559
1560         if (fold) {
1561                 /* not a hidden SSID */
1562                 return true;
1563         }
1564
1565         /* This is the bad part ... */
1566
1567         list_for_each_entry(bss, &rdev->bss_list, list) {
1568                 /*
1569                  * we're iterating all the entries anyway, so take the
1570                  * opportunity to validate the list length accounting
1571                  */
1572                 n_entries++;
1573
1574                 if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
1575                         continue;
1576                 if (bss->pub.channel != new->pub.channel)
1577                         continue;
1578                 if (bss->pub.scan_width != new->pub.scan_width)
1579                         continue;
1580                 if (rcu_access_pointer(bss->pub.beacon_ies))
1581                         continue;
1582                 ies = rcu_access_pointer(bss->pub.ies);
1583                 if (!ies)
1584                         continue;
1585                 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1586                 if (!ie)
1587                         continue;
1588                 if (ssidlen && ie[1] != ssidlen)
1589                         continue;
1590                 if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
1591                         continue;
1592                 if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
1593                         list_del(&bss->hidden_list);
1594                 /* combine them */
1595                 list_add(&bss->hidden_list, &new->hidden_list);
1596                 bss->pub.hidden_beacon_bss = &new->pub;
1597                 new->refcount += bss->refcount;
1598                 rcu_assign_pointer(bss->pub.beacon_ies,
1599                                    new->pub.beacon_ies);
1600         }
1601
1602         WARN_ONCE(n_entries != rdev->bss_entries,
1603                   "rdev bss entries[%d]/list[len:%d] corruption\n",
1604                   rdev->bss_entries, n_entries);
1605
1606         return true;
1607 }
1608
1609 struct cfg80211_non_tx_bss {
1610         struct cfg80211_bss *tx_bss;
1611         u8 max_bssid_indicator;
1612         u8 bssid_index;
1613 };
1614
1615 static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
1616                                          const struct cfg80211_bss_ies *new_ies,
1617                                          const struct cfg80211_bss_ies *old_ies)
1618 {
1619         struct cfg80211_internal_bss *bss;
1620
1621         /* Assign beacon IEs to all sub entries */
1622         list_for_each_entry(bss, &known->hidden_list, hidden_list) {
1623                 const struct cfg80211_bss_ies *ies;
1624
1625                 ies = rcu_access_pointer(bss->pub.beacon_ies);
1626                 WARN_ON(ies != old_ies);
1627
1628                 rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
1629         }
1630 }
1631
1632 static bool
1633 cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
1634                           struct cfg80211_internal_bss *known,
1635                           struct cfg80211_internal_bss *new,
1636                           bool signal_valid)
1637 {
1638         lockdep_assert_held(&rdev->bss_lock);
1639
1640         /* Update IEs */
1641         if (rcu_access_pointer(new->pub.proberesp_ies)) {
1642                 const struct cfg80211_bss_ies *old;
1643
1644                 old = rcu_access_pointer(known->pub.proberesp_ies);
1645
1646                 rcu_assign_pointer(known->pub.proberesp_ies,
1647                                    new->pub.proberesp_ies);
1648                 /* Override possible earlier Beacon frame IEs */
1649                 rcu_assign_pointer(known->pub.ies,
1650                                    new->pub.proberesp_ies);
1651                 if (old)
1652                         kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1653         } else if (rcu_access_pointer(new->pub.beacon_ies)) {
1654                 const struct cfg80211_bss_ies *old;
1655
1656                 if (known->pub.hidden_beacon_bss &&
1657                     !list_empty(&known->hidden_list)) {
1658                         const struct cfg80211_bss_ies *f;
1659
1660                         /* The known BSS struct is one of the probe
1661                          * response members of a group, but we're
1662                          * receiving a beacon (beacon_ies in the new
1663                          * bss is used). This can only mean that the
1664                          * AP changed its beacon from not having an
1665                          * SSID to showing it, which is confusing so
1666                          * drop this information.
1667                          */
1668
1669                         f = rcu_access_pointer(new->pub.beacon_ies);
1670                         kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
1671                         return false;
1672                 }
1673
1674                 old = rcu_access_pointer(known->pub.beacon_ies);
1675
1676                 rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
1677
1678                 /* Override IEs if they were from a beacon before */
1679                 if (old == rcu_access_pointer(known->pub.ies))
1680                         rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
1681
1682                 cfg80211_update_hidden_bsses(known,
1683                                              rcu_access_pointer(new->pub.beacon_ies),
1684                                              old);
1685
1686                 if (old)
1687                         kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1688         }
1689
1690         known->pub.beacon_interval = new->pub.beacon_interval;
1691
1692         /* don't update the signal if beacon was heard on
1693          * adjacent channel.
1694          */
1695         if (signal_valid)
1696                 known->pub.signal = new->pub.signal;
1697         known->pub.capability = new->pub.capability;
1698         known->ts = new->ts;
1699         known->ts_boottime = new->ts_boottime;
1700         known->parent_tsf = new->parent_tsf;
1701         known->pub.chains = new->pub.chains;
1702         memcpy(known->pub.chain_signal, new->pub.chain_signal,
1703                IEEE80211_MAX_CHAINS);
1704         ether_addr_copy(known->parent_bssid, new->parent_bssid);
1705         known->pub.max_bssid_indicator = new->pub.max_bssid_indicator;
1706         known->pub.bssid_index = new->pub.bssid_index;
1707
1708         return true;
1709 }
1710
1711 /* Returned bss is reference counted and must be cleaned up appropriately. */
1712 struct cfg80211_internal_bss *
1713 cfg80211_bss_update(struct cfg80211_registered_device *rdev,
1714                     struct cfg80211_internal_bss *tmp,
1715                     bool signal_valid, unsigned long ts)
1716 {
1717         struct cfg80211_internal_bss *found = NULL;
1718
1719         if (WARN_ON(!tmp->pub.channel))
1720                 return NULL;
1721
1722         tmp->ts = ts;
1723
1724         spin_lock_bh(&rdev->bss_lock);
1725
1726         if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) {
1727                 spin_unlock_bh(&rdev->bss_lock);
1728                 return NULL;
1729         }
1730
1731         found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
1732
1733         if (found) {
1734                 if (!cfg80211_update_known_bss(rdev, found, tmp, signal_valid))
1735                         goto drop;
1736         } else {
1737                 struct cfg80211_internal_bss *new;
1738                 struct cfg80211_internal_bss *hidden;
1739                 struct cfg80211_bss_ies *ies;
1740
1741                 /*
1742                  * create a copy -- the "res" variable that is passed in
1743                  * is allocated on the stack since it's not needed in the
1744                  * more common case of an update
1745                  */
1746                 new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size,
1747                               GFP_ATOMIC);
1748                 if (!new) {
1749                         ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
1750                         if (ies)
1751                                 kfree_rcu(ies, rcu_head);
1752                         ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
1753                         if (ies)
1754                                 kfree_rcu(ies, rcu_head);
1755                         goto drop;
1756                 }
1757                 memcpy(new, tmp, sizeof(*new));
1758                 new->refcount = 1;
1759                 INIT_LIST_HEAD(&new->hidden_list);
1760                 INIT_LIST_HEAD(&new->pub.nontrans_list);
1761                 /* we'll set this later if it was non-NULL */
1762                 new->pub.transmitted_bss = NULL;
1763
1764                 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
1765                         hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
1766                         if (!hidden)
1767                                 hidden = rb_find_bss(rdev, tmp,
1768                                                      BSS_CMP_HIDE_NUL);
1769                         if (hidden) {
1770                                 new->pub.hidden_beacon_bss = &hidden->pub;
1771                                 list_add(&new->hidden_list,
1772                                          &hidden->hidden_list);
1773                                 hidden->refcount++;
1774                                 rcu_assign_pointer(new->pub.beacon_ies,
1775                                                    hidden->pub.beacon_ies);
1776                         }
1777                 } else {
1778                         /*
1779                          * Ok so we found a beacon, and don't have an entry. If
1780                          * it's a beacon with hidden SSID, we might be in for an
1781                          * expensive search for any probe responses that should
1782                          * be grouped with this beacon for updates ...
1783                          */
1784                         if (!cfg80211_combine_bsses(rdev, new)) {
1785                                 bss_ref_put(rdev, new);
1786                                 goto drop;
1787                         }
1788                 }
1789
1790                 if (rdev->bss_entries >= bss_entries_limit &&
1791                     !cfg80211_bss_expire_oldest(rdev)) {
1792                         bss_ref_put(rdev, new);
1793                         goto drop;
1794                 }
1795
1796                 /* This must be before the call to bss_ref_get */
1797                 if (tmp->pub.transmitted_bss) {
1798                         struct cfg80211_internal_bss *pbss =
1799                                 container_of(tmp->pub.transmitted_bss,
1800                                              struct cfg80211_internal_bss,
1801                                              pub);
1802
1803                         new->pub.transmitted_bss = tmp->pub.transmitted_bss;
1804                         bss_ref_get(rdev, pbss);
1805                 }
1806
1807                 list_add_tail(&new->list, &rdev->bss_list);
1808                 rdev->bss_entries++;
1809                 rb_insert_bss(rdev, new);
1810                 found = new;
1811         }
1812
1813         rdev->bss_generation++;
1814         bss_ref_get(rdev, found);
1815         spin_unlock_bh(&rdev->bss_lock);
1816
1817         return found;
1818  drop:
1819         spin_unlock_bh(&rdev->bss_lock);
1820         return NULL;
1821 }
1822
1823 int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
1824                                     enum nl80211_band band,
1825                                     enum cfg80211_bss_frame_type ftype)
1826 {
1827         const struct element *tmp;
1828
1829         if (band == NL80211_BAND_6GHZ) {
1830                 struct ieee80211_he_operation *he_oper;
1831
1832                 tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie,
1833                                              ielen);
1834                 if (tmp && tmp->datalen >= sizeof(*he_oper) &&
1835                     tmp->datalen >= ieee80211_he_oper_size(&tmp->data[1])) {
1836                         const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
1837
1838                         he_oper = (void *)&tmp->data[1];
1839
1840                         he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
1841                         if (!he_6ghz_oper)
1842                                 return -1;
1843
1844                         if (ftype != CFG80211_BSS_FTYPE_BEACON ||
1845                             he_6ghz_oper->control & IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON)
1846                                 return he_6ghz_oper->primary;
1847                 }
1848         } else if (band == NL80211_BAND_S1GHZ) {
1849                 tmp = cfg80211_find_elem(WLAN_EID_S1G_OPERATION, ie, ielen);
1850                 if (tmp && tmp->datalen >= sizeof(struct ieee80211_s1g_oper_ie)) {
1851                         struct ieee80211_s1g_oper_ie *s1gop = (void *)tmp->data;
1852
1853                         return s1gop->oper_ch;
1854                 }
1855         } else {
1856                 tmp = cfg80211_find_elem(WLAN_EID_DS_PARAMS, ie, ielen);
1857                 if (tmp && tmp->datalen == 1)
1858                         return tmp->data[0];
1859
1860                 tmp = cfg80211_find_elem(WLAN_EID_HT_OPERATION, ie, ielen);
1861                 if (tmp &&
1862                     tmp->datalen >= sizeof(struct ieee80211_ht_operation)) {
1863                         struct ieee80211_ht_operation *htop = (void *)tmp->data;
1864
1865                         return htop->primary_chan;
1866                 }
1867         }
1868
1869         return -1;
1870 }
1871 EXPORT_SYMBOL(cfg80211_get_ies_channel_number);
1872
1873 /*
1874  * Update RX channel information based on the available frame payload
1875  * information. This is mainly for the 2.4 GHz band where frames can be received
1876  * from neighboring channels and the Beacon frames use the DSSS Parameter Set
1877  * element to indicate the current (transmitting) channel, but this might also
1878  * be needed on other bands if RX frequency does not match with the actual
1879  * operating channel of a BSS, or if the AP reports a different primary channel.
1880  */
1881 static struct ieee80211_channel *
1882 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
1883                          struct ieee80211_channel *channel,
1884                          enum nl80211_bss_scan_width scan_width,
1885                          enum cfg80211_bss_frame_type ftype)
1886 {
1887         u32 freq;
1888         int channel_number;
1889         struct ieee80211_channel *alt_channel;
1890
1891         channel_number = cfg80211_get_ies_channel_number(ie, ielen,
1892                                                          channel->band, ftype);
1893
1894         if (channel_number < 0) {
1895                 /* No channel information in frame payload */
1896                 return channel;
1897         }
1898
1899         freq = ieee80211_channel_to_freq_khz(channel_number, channel->band);
1900
1901         /*
1902          * In 6GHz, duplicated beacon indication is relevant for
1903          * beacons only.
1904          */
1905         if (channel->band == NL80211_BAND_6GHZ &&
1906             (freq == channel->center_freq ||
1907              abs(freq - channel->center_freq) > 80))
1908                 return channel;
1909
1910         alt_channel = ieee80211_get_channel_khz(wiphy, freq);
1911         if (!alt_channel) {
1912                 if (channel->band == NL80211_BAND_2GHZ) {
1913                         /*
1914                          * Better not allow unexpected channels when that could
1915                          * be going beyond the 1-11 range (e.g., discovering
1916                          * BSS on channel 12 when radio is configured for
1917                          * channel 11.
1918                          */
1919                         return NULL;
1920                 }
1921
1922                 /* No match for the payload channel number - ignore it */
1923                 return channel;
1924         }
1925
1926         if (scan_width == NL80211_BSS_CHAN_WIDTH_10 ||
1927             scan_width == NL80211_BSS_CHAN_WIDTH_5) {
1928                 /*
1929                  * Ignore channel number in 5 and 10 MHz channels where there
1930                  * may not be an n:1 or 1:n mapping between frequencies and
1931                  * channel numbers.
1932                  */
1933                 return channel;
1934         }
1935
1936         /*
1937          * Use the channel determined through the payload channel number
1938          * instead of the RX channel reported by the driver.
1939          */
1940         if (alt_channel->flags & IEEE80211_CHAN_DISABLED)
1941                 return NULL;
1942         return alt_channel;
1943 }
1944
1945 /* Returned bss is reference counted and must be cleaned up appropriately. */
1946 static struct cfg80211_bss *
1947 cfg80211_inform_single_bss_data(struct wiphy *wiphy,
1948                                 struct cfg80211_inform_bss *data,
1949                                 enum cfg80211_bss_frame_type ftype,
1950                                 const u8 *bssid, u64 tsf, u16 capability,
1951                                 u16 beacon_interval, const u8 *ie, size_t ielen,
1952                                 struct cfg80211_non_tx_bss *non_tx_data,
1953                                 gfp_t gfp)
1954 {
1955         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1956         struct cfg80211_bss_ies *ies;
1957         struct ieee80211_channel *channel;
1958         struct cfg80211_internal_bss tmp = {}, *res;
1959         int bss_type;
1960         bool signal_valid;
1961         unsigned long ts;
1962
1963         if (WARN_ON(!wiphy))
1964                 return NULL;
1965
1966         if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
1967                     (data->signal < 0 || data->signal > 100)))
1968                 return NULL;
1969
1970         channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan,
1971                                            data->scan_width, ftype);
1972         if (!channel)
1973                 return NULL;
1974
1975         memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
1976         tmp.pub.channel = channel;
1977         tmp.pub.scan_width = data->scan_width;
1978         tmp.pub.signal = data->signal;
1979         tmp.pub.beacon_interval = beacon_interval;
1980         tmp.pub.capability = capability;
1981         tmp.ts_boottime = data->boottime_ns;
1982         tmp.parent_tsf = data->parent_tsf;
1983         ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
1984
1985         if (non_tx_data) {
1986                 tmp.pub.transmitted_bss = non_tx_data->tx_bss;
1987                 ts = bss_from_pub(non_tx_data->tx_bss)->ts;
1988                 tmp.pub.bssid_index = non_tx_data->bssid_index;
1989                 tmp.pub.max_bssid_indicator = non_tx_data->max_bssid_indicator;
1990         } else {
1991                 ts = jiffies;
1992         }
1993
1994         /*
1995          * If we do not know here whether the IEs are from a Beacon or Probe
1996          * Response frame, we need to pick one of the options and only use it
1997          * with the driver that does not provide the full Beacon/Probe Response
1998          * frame. Use Beacon frame pointer to avoid indicating that this should
1999          * override the IEs pointer should we have received an earlier
2000          * indication of Probe Response data.
2001          */
2002         ies = kzalloc(sizeof(*ies) + ielen, gfp);
2003         if (!ies)
2004                 return NULL;
2005         ies->len = ielen;
2006         ies->tsf = tsf;
2007         ies->from_beacon = false;
2008         memcpy(ies->data, ie, ielen);
2009
2010         switch (ftype) {
2011         case CFG80211_BSS_FTYPE_BEACON:
2012                 ies->from_beacon = true;
2013                 fallthrough;
2014         case CFG80211_BSS_FTYPE_UNKNOWN:
2015                 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
2016                 break;
2017         case CFG80211_BSS_FTYPE_PRESP:
2018                 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
2019                 break;
2020         }
2021         rcu_assign_pointer(tmp.pub.ies, ies);
2022
2023         signal_valid = data->chan == channel;
2024         res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid, ts);
2025         if (!res)
2026                 return NULL;
2027
2028         if (channel->band == NL80211_BAND_60GHZ) {
2029                 bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
2030                 if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
2031                     bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
2032                         regulatory_hint_found_beacon(wiphy, channel, gfp);
2033         } else {
2034                 if (res->pub.capability & WLAN_CAPABILITY_ESS)
2035                         regulatory_hint_found_beacon(wiphy, channel, gfp);
2036         }
2037
2038         if (non_tx_data) {
2039                 /* this is a nontransmitting bss, we need to add it to
2040                  * transmitting bss' list if it is not there
2041                  */
2042                 spin_lock_bh(&rdev->bss_lock);
2043                 if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
2044                                                &res->pub)) {
2045                         if (__cfg80211_unlink_bss(rdev, res)) {
2046                                 rdev->bss_generation++;
2047                                 res = NULL;
2048                         }
2049                 }
2050                 spin_unlock_bh(&rdev->bss_lock);
2051
2052                 if (!res)
2053                         return NULL;
2054         }
2055
2056         trace_cfg80211_return_bss(&res->pub);
2057         /* cfg80211_bss_update gives us a referenced result */
2058         return &res->pub;
2059 }
2060
2061 static const struct element
2062 *cfg80211_get_profile_continuation(const u8 *ie, size_t ielen,
2063                                    const struct element *mbssid_elem,
2064                                    const struct element *sub_elem)
2065 {
2066         const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen;
2067         const struct element *next_mbssid;
2068         const struct element *next_sub;
2069
2070         next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
2071                                          mbssid_end,
2072                                          ielen - (mbssid_end - ie));
2073
2074         /*
2075          * If it is not the last subelement in current MBSSID IE or there isn't
2076          * a next MBSSID IE - profile is complete.
2077         */
2078         if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) ||
2079             !next_mbssid)
2080                 return NULL;
2081
2082         /* For any length error, just return NULL */
2083
2084         if (next_mbssid->datalen < 4)
2085                 return NULL;
2086
2087         next_sub = (void *)&next_mbssid->data[1];
2088
2089         if (next_mbssid->data + next_mbssid->datalen <
2090             next_sub->data + next_sub->datalen)
2091                 return NULL;
2092
2093         if (next_sub->id != 0 || next_sub->datalen < 2)
2094                 return NULL;
2095
2096         /*
2097          * Check if the first element in the next sub element is a start
2098          * of a new profile
2099          */
2100         return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ?
2101                NULL : next_mbssid;
2102 }
2103
2104 size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
2105                               const struct element *mbssid_elem,
2106                               const struct element *sub_elem,
2107                               u8 *merged_ie, size_t max_copy_len)
2108 {
2109         size_t copied_len = sub_elem->datalen;
2110         const struct element *next_mbssid;
2111
2112         if (sub_elem->datalen > max_copy_len)
2113                 return 0;
2114
2115         memcpy(merged_ie, sub_elem->data, sub_elem->datalen);
2116
2117         while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen,
2118                                                                 mbssid_elem,
2119                                                                 sub_elem))) {
2120                 const struct element *next_sub = (void *)&next_mbssid->data[1];
2121
2122                 if (copied_len + next_sub->datalen > max_copy_len)
2123                         break;
2124                 memcpy(merged_ie + copied_len, next_sub->data,
2125                        next_sub->datalen);
2126                 copied_len += next_sub->datalen;
2127         }
2128
2129         return copied_len;
2130 }
2131 EXPORT_SYMBOL(cfg80211_merge_profile);
2132
2133 static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
2134                                        struct cfg80211_inform_bss *data,
2135                                        enum cfg80211_bss_frame_type ftype,
2136                                        const u8 *bssid, u64 tsf,
2137                                        u16 beacon_interval, const u8 *ie,
2138                                        size_t ielen,
2139                                        struct cfg80211_non_tx_bss *non_tx_data,
2140                                        gfp_t gfp)
2141 {
2142         const u8 *mbssid_index_ie;
2143         const struct element *elem, *sub;
2144         size_t new_ie_len;
2145         u8 new_bssid[ETH_ALEN];
2146         u8 *new_ie, *profile;
2147         u64 seen_indices = 0;
2148         u16 capability;
2149         struct cfg80211_bss *bss;
2150
2151         if (!non_tx_data)
2152                 return;
2153         if (!cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
2154                 return;
2155         if (!wiphy->support_mbssid)
2156                 return;
2157         if (wiphy->support_only_he_mbssid &&
2158             !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
2159                 return;
2160
2161         new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
2162         if (!new_ie)
2163                 return;
2164
2165         profile = kmalloc(ielen, gfp);
2166         if (!profile)
2167                 goto out;
2168
2169         for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
2170                 if (elem->datalen < 4)
2171                         continue;
2172                 if (elem->data[0] < 1 || (int)elem->data[0] > 8)
2173                         continue;
2174                 for_each_element(sub, elem->data + 1, elem->datalen - 1) {
2175                         u8 profile_len;
2176
2177                         if (sub->id != 0 || sub->datalen < 4) {
2178                                 /* not a valid BSS profile */
2179                                 continue;
2180                         }
2181
2182                         if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
2183                             sub->data[1] != 2) {
2184                                 /* The first element within the Nontransmitted
2185                                  * BSSID Profile is not the Nontransmitted
2186                                  * BSSID Capability element.
2187                                  */
2188                                 continue;
2189                         }
2190
2191                         memset(profile, 0, ielen);
2192                         profile_len = cfg80211_merge_profile(ie, ielen,
2193                                                              elem,
2194                                                              sub,
2195                                                              profile,
2196                                                              ielen);
2197
2198                         /* found a Nontransmitted BSSID Profile */
2199                         mbssid_index_ie = cfg80211_find_ie
2200                                 (WLAN_EID_MULTI_BSSID_IDX,
2201                                  profile, profile_len);
2202                         if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
2203                             mbssid_index_ie[2] == 0 ||
2204                             mbssid_index_ie[2] > 46) {
2205                                 /* No valid Multiple BSSID-Index element */
2206                                 continue;
2207                         }
2208
2209                         if (seen_indices & BIT_ULL(mbssid_index_ie[2]))
2210                                 /* We don't support legacy split of a profile */
2211                                 net_dbg_ratelimited("Partial info for BSSID index %d\n",
2212                                                     mbssid_index_ie[2]);
2213
2214                         seen_indices |= BIT_ULL(mbssid_index_ie[2]);
2215
2216                         non_tx_data->bssid_index = mbssid_index_ie[2];
2217                         non_tx_data->max_bssid_indicator = elem->data[0];
2218
2219                         cfg80211_gen_new_bssid(bssid,
2220                                                non_tx_data->max_bssid_indicator,
2221                                                non_tx_data->bssid_index,
2222                                                new_bssid);
2223                         memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
2224                         new_ie_len = cfg80211_gen_new_ie(ie, ielen,
2225                                                          profile,
2226                                                          profile_len, new_ie,
2227                                                          gfp);
2228                         if (!new_ie_len)
2229                                 continue;
2230
2231                         capability = get_unaligned_le16(profile + 2);
2232                         bss = cfg80211_inform_single_bss_data(wiphy, data,
2233                                                               ftype,
2234                                                               new_bssid, tsf,
2235                                                               capability,
2236                                                               beacon_interval,
2237                                                               new_ie,
2238                                                               new_ie_len,
2239                                                               non_tx_data,
2240                                                               gfp);
2241                         if (!bss)
2242                                 break;
2243                         cfg80211_put_bss(wiphy, bss);
2244                 }
2245         }
2246
2247 out:
2248         kfree(new_ie);
2249         kfree(profile);
2250 }
2251
2252 struct cfg80211_bss *
2253 cfg80211_inform_bss_data(struct wiphy *wiphy,
2254                          struct cfg80211_inform_bss *data,
2255                          enum cfg80211_bss_frame_type ftype,
2256                          const u8 *bssid, u64 tsf, u16 capability,
2257                          u16 beacon_interval, const u8 *ie, size_t ielen,
2258                          gfp_t gfp)
2259 {
2260         struct cfg80211_bss *res;
2261         struct cfg80211_non_tx_bss non_tx_data;
2262
2263         res = cfg80211_inform_single_bss_data(wiphy, data, ftype, bssid, tsf,
2264                                               capability, beacon_interval, ie,
2265                                               ielen, NULL, gfp);
2266         if (!res)
2267                 return NULL;
2268         non_tx_data.tx_bss = res;
2269         cfg80211_parse_mbssid_data(wiphy, data, ftype, bssid, tsf,
2270                                    beacon_interval, ie, ielen, &non_tx_data,
2271                                    gfp);
2272         return res;
2273 }
2274 EXPORT_SYMBOL(cfg80211_inform_bss_data);
2275
2276 static void
2277 cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy,
2278                                  struct cfg80211_inform_bss *data,
2279                                  struct ieee80211_mgmt *mgmt, size_t len,
2280                                  struct cfg80211_non_tx_bss *non_tx_data,
2281                                  gfp_t gfp)
2282 {
2283         enum cfg80211_bss_frame_type ftype;
2284         const u8 *ie = mgmt->u.probe_resp.variable;
2285         size_t ielen = len - offsetof(struct ieee80211_mgmt,
2286                                       u.probe_resp.variable);
2287
2288         ftype = ieee80211_is_beacon(mgmt->frame_control) ?
2289                 CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP;
2290
2291         cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid,
2292                                    le64_to_cpu(mgmt->u.probe_resp.timestamp),
2293                                    le16_to_cpu(mgmt->u.probe_resp.beacon_int),
2294                                    ie, ielen, non_tx_data, gfp);
2295 }
2296
2297 static void
2298 cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
2299                                    struct cfg80211_bss *nontrans_bss,
2300                                    struct ieee80211_mgmt *mgmt, size_t len)
2301 {
2302         u8 *ie, *new_ie, *pos;
2303         const struct element *nontrans_ssid;
2304         const u8 *trans_ssid, *mbssid;
2305         size_t ielen = len - offsetof(struct ieee80211_mgmt,
2306                                       u.probe_resp.variable);
2307         size_t new_ie_len;
2308         struct cfg80211_bss_ies *new_ies;
2309         const struct cfg80211_bss_ies *old;
2310         size_t cpy_len;
2311
2312         lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);
2313
2314         ie = mgmt->u.probe_resp.variable;
2315
2316         new_ie_len = ielen;
2317         trans_ssid = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
2318         if (!trans_ssid)
2319                 return;
2320         new_ie_len -= trans_ssid[1];
2321         mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen);
2322         /*
2323          * It's not valid to have the MBSSID element before SSID
2324          * ignore if that happens - the code below assumes it is
2325          * after (while copying things inbetween).
2326          */
2327         if (!mbssid || mbssid < trans_ssid)
2328                 return;
2329         new_ie_len -= mbssid[1];
2330
2331         nontrans_ssid = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID);
2332         if (!nontrans_ssid)
2333                 return;
2334
2335         new_ie_len += nontrans_ssid->datalen;
2336
2337         /* generate new ie for nontrans BSS
2338          * 1. replace SSID with nontrans BSS' SSID
2339          * 2. skip MBSSID IE
2340          */
2341         new_ie = kzalloc(new_ie_len, GFP_ATOMIC);
2342         if (!new_ie)
2343                 return;
2344
2345         new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, GFP_ATOMIC);
2346         if (!new_ies)
2347                 goto out_free;
2348
2349         pos = new_ie;
2350
2351         /* copy the nontransmitted SSID */
2352         cpy_len = nontrans_ssid->datalen + 2;
2353         memcpy(pos, nontrans_ssid, cpy_len);
2354         pos += cpy_len;
2355         /* copy the IEs between SSID and MBSSID */
2356         cpy_len = trans_ssid[1] + 2;
2357         memcpy(pos, (trans_ssid + cpy_len), (mbssid - (trans_ssid + cpy_len)));
2358         pos += (mbssid - (trans_ssid + cpy_len));
2359         /* copy the IEs after MBSSID */
2360         cpy_len = mbssid[1] + 2;
2361         memcpy(pos, mbssid + cpy_len, ((ie + ielen) - (mbssid + cpy_len)));
2362
2363         /* update ie */
2364         new_ies->len = new_ie_len;
2365         new_ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
2366         new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
2367         memcpy(new_ies->data, new_ie, new_ie_len);
2368         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2369                 old = rcu_access_pointer(nontrans_bss->proberesp_ies);
2370                 rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies);
2371                 rcu_assign_pointer(nontrans_bss->ies, new_ies);
2372                 if (old)
2373                         kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
2374         } else {
2375                 old = rcu_access_pointer(nontrans_bss->beacon_ies);
2376                 rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
2377                 cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss),
2378                                              new_ies, old);
2379                 rcu_assign_pointer(nontrans_bss->ies, new_ies);
2380                 if (old)
2381                         kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
2382         }
2383
2384 out_free:
2385         kfree(new_ie);
2386 }
2387
2388 /* cfg80211_inform_bss_width_frame helper */
2389 static struct cfg80211_bss *
2390 cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
2391                                       struct cfg80211_inform_bss *data,
2392                                       struct ieee80211_mgmt *mgmt, size_t len,
2393                                       gfp_t gfp)
2394 {
2395         struct cfg80211_internal_bss tmp = {}, *res;
2396         struct cfg80211_bss_ies *ies;
2397         struct ieee80211_channel *channel;
2398         bool signal_valid;
2399         struct ieee80211_ext *ext = NULL;
2400         u8 *bssid, *variable;
2401         u16 capability, beacon_int;
2402         size_t ielen, min_hdr_len = offsetof(struct ieee80211_mgmt,
2403                                              u.probe_resp.variable);
2404         int bss_type;
2405         enum cfg80211_bss_frame_type ftype;
2406
2407         BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
2408                         offsetof(struct ieee80211_mgmt, u.beacon.variable));
2409
2410         trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len);
2411
2412         if (WARN_ON(!mgmt))
2413                 return NULL;
2414
2415         if (WARN_ON(!wiphy))
2416                 return NULL;
2417
2418         if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
2419                     (data->signal < 0 || data->signal > 100)))
2420                 return NULL;
2421
2422         if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
2423                 ext = (void *) mgmt;
2424                 min_hdr_len = offsetof(struct ieee80211_ext, u.s1g_beacon);
2425                 if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
2426                         min_hdr_len = offsetof(struct ieee80211_ext,
2427                                                u.s1g_short_beacon.variable);
2428         }
2429
2430         if (WARN_ON(len < min_hdr_len))
2431                 return NULL;
2432
2433         ielen = len - min_hdr_len;
2434         variable = mgmt->u.probe_resp.variable;
2435         if (ext) {
2436                 if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
2437                         variable = ext->u.s1g_short_beacon.variable;
2438                 else
2439                         variable = ext->u.s1g_beacon.variable;
2440         }
2441
2442         if (ieee80211_is_beacon(mgmt->frame_control))
2443                 ftype = CFG80211_BSS_FTYPE_BEACON;
2444         else if (ieee80211_is_probe_resp(mgmt->frame_control))
2445                 ftype = CFG80211_BSS_FTYPE_PRESP;
2446         else
2447                 ftype = CFG80211_BSS_FTYPE_UNKNOWN;
2448
2449         channel = cfg80211_get_bss_channel(wiphy, variable,
2450                                            ielen, data->chan, data->scan_width,
2451                                            ftype);
2452         if (!channel)
2453                 return NULL;
2454
2455         if (ext) {
2456                 const struct ieee80211_s1g_bcn_compat_ie *compat;
2457                 const struct element *elem;
2458
2459                 elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT,
2460                                           variable, ielen);
2461                 if (!elem)
2462                         return NULL;
2463                 if (elem->datalen < sizeof(*compat))
2464                         return NULL;
2465                 compat = (void *)elem->data;
2466                 bssid = ext->u.s1g_beacon.sa;
2467                 capability = le16_to_cpu(compat->compat_info);
2468                 beacon_int = le16_to_cpu(compat->beacon_int);
2469         } else {
2470                 bssid = mgmt->bssid;
2471                 beacon_int = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
2472                 capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
2473         }
2474
2475         ies = kzalloc(sizeof(*ies) + ielen, gfp);
2476         if (!ies)
2477                 return NULL;
2478         ies->len = ielen;
2479         ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
2480         ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control) ||
2481                            ieee80211_is_s1g_beacon(mgmt->frame_control);
2482         memcpy(ies->data, variable, ielen);
2483
2484         if (ieee80211_is_probe_resp(mgmt->frame_control))
2485                 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
2486         else
2487                 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
2488         rcu_assign_pointer(tmp.pub.ies, ies);
2489
2490         memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
2491         tmp.pub.beacon_interval = beacon_int;
2492         tmp.pub.capability = capability;
2493         tmp.pub.channel = channel;
2494         tmp.pub.scan_width = data->scan_width;
2495         tmp.pub.signal = data->signal;
2496         tmp.ts_boottime = data->boottime_ns;
2497         tmp.parent_tsf = data->parent_tsf;
2498         tmp.pub.chains = data->chains;
2499         memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
2500         ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
2501
2502         signal_valid = data->chan == channel;
2503         res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
2504                                   jiffies);
2505         if (!res)
2506                 return NULL;
2507
2508         if (channel->band == NL80211_BAND_60GHZ) {
2509                 bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
2510                 if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
2511                     bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
2512                         regulatory_hint_found_beacon(wiphy, channel, gfp);
2513         } else {
2514                 if (res->pub.capability & WLAN_CAPABILITY_ESS)
2515                         regulatory_hint_found_beacon(wiphy, channel, gfp);
2516         }
2517
2518         trace_cfg80211_return_bss(&res->pub);
2519         /* cfg80211_bss_update gives us a referenced result */
2520         return &res->pub;
2521 }
2522
2523 struct cfg80211_bss *
2524 cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
2525                                struct cfg80211_inform_bss *data,
2526                                struct ieee80211_mgmt *mgmt, size_t len,
2527                                gfp_t gfp)
2528 {
2529         struct cfg80211_bss *res, *tmp_bss;
2530         const u8 *ie = mgmt->u.probe_resp.variable;
2531         const struct cfg80211_bss_ies *ies1, *ies2;
2532         size_t ielen = len - offsetof(struct ieee80211_mgmt,
2533                                       u.probe_resp.variable);
2534         struct cfg80211_non_tx_bss non_tx_data = {};
2535
2536         res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
2537                                                     len, gfp);
2538
2539         /* don't do any further MBSSID handling for S1G */
2540         if (ieee80211_is_s1g_beacon(mgmt->frame_control))
2541                 return res;
2542
2543         if (!res || !wiphy->support_mbssid ||
2544             !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
2545                 return res;
2546         if (wiphy->support_only_he_mbssid &&
2547             !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
2548                 return res;
2549
2550         non_tx_data.tx_bss = res;
2551         /* process each non-transmitting bss */
2552         cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len,
2553                                          &non_tx_data, gfp);
2554
2555         spin_lock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
2556
2557         /* check if the res has other nontransmitting bss which is not
2558          * in MBSSID IE
2559          */
2560         ies1 = rcu_access_pointer(res->ies);
2561
2562         /* go through nontrans_list, if the timestamp of the BSS is
2563          * earlier than the timestamp of the transmitting BSS then
2564          * update it
2565          */
2566         list_for_each_entry(tmp_bss, &res->nontrans_list,
2567                             nontrans_list) {
2568                 ies2 = rcu_access_pointer(tmp_bss->ies);
2569                 if (ies2->tsf < ies1->tsf)
2570                         cfg80211_update_notlisted_nontrans(wiphy, tmp_bss,
2571                                                            mgmt, len);
2572         }
2573         spin_unlock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
2574
2575         return res;
2576 }
2577 EXPORT_SYMBOL(cfg80211_inform_bss_frame_data);
2578
2579 void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
2580 {
2581         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2582         struct cfg80211_internal_bss *bss;
2583
2584         if (!pub)
2585                 return;
2586
2587         bss = container_of(pub, struct cfg80211_internal_bss, pub);
2588
2589         spin_lock_bh(&rdev->bss_lock);
2590         bss_ref_get(rdev, bss);
2591         spin_unlock_bh(&rdev->bss_lock);
2592 }
2593 EXPORT_SYMBOL(cfg80211_ref_bss);
2594
2595 void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
2596 {
2597         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2598         struct cfg80211_internal_bss *bss;
2599
2600         if (!pub)
2601                 return;
2602
2603         bss = container_of(pub, struct cfg80211_internal_bss, pub);
2604
2605         spin_lock_bh(&rdev->bss_lock);
2606         bss_ref_put(rdev, bss);
2607         spin_unlock_bh(&rdev->bss_lock);
2608 }
2609 EXPORT_SYMBOL(cfg80211_put_bss);
2610
2611 void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
2612 {
2613         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2614         struct cfg80211_internal_bss *bss, *tmp1;
2615         struct cfg80211_bss *nontrans_bss, *tmp;
2616
2617         if (WARN_ON(!pub))
2618                 return;
2619
2620         bss = container_of(pub, struct cfg80211_internal_bss, pub);
2621
2622         spin_lock_bh(&rdev->bss_lock);
2623         if (list_empty(&bss->list))
2624                 goto out;
2625
2626         list_for_each_entry_safe(nontrans_bss, tmp,
2627                                  &pub->nontrans_list,
2628                                  nontrans_list) {
2629                 tmp1 = container_of(nontrans_bss,
2630                                     struct cfg80211_internal_bss, pub);
2631                 if (__cfg80211_unlink_bss(rdev, tmp1))
2632                         rdev->bss_generation++;
2633         }
2634
2635         if (__cfg80211_unlink_bss(rdev, bss))
2636                 rdev->bss_generation++;
2637 out:
2638         spin_unlock_bh(&rdev->bss_lock);
2639 }
2640 EXPORT_SYMBOL(cfg80211_unlink_bss);
2641
2642 void cfg80211_bss_iter(struct wiphy *wiphy,
2643                        struct cfg80211_chan_def *chandef,
2644                        void (*iter)(struct wiphy *wiphy,
2645                                     struct cfg80211_bss *bss,
2646                                     void *data),
2647                        void *iter_data)
2648 {
2649         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2650         struct cfg80211_internal_bss *bss;
2651
2652         spin_lock_bh(&rdev->bss_lock);
2653
2654         list_for_each_entry(bss, &rdev->bss_list, list) {
2655                 if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel,
2656                                                      false))
2657                         iter(wiphy, &bss->pub, iter_data);
2658         }
2659
2660         spin_unlock_bh(&rdev->bss_lock);
2661 }
2662 EXPORT_SYMBOL(cfg80211_bss_iter);
2663
2664 void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
2665                                      unsigned int link_id,
2666                                      struct ieee80211_channel *chan)
2667 {
2668         struct wiphy *wiphy = wdev->wiphy;
2669         struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2670         struct cfg80211_internal_bss *cbss = wdev->links[link_id].client.current_bss;
2671         struct cfg80211_internal_bss *new = NULL;
2672         struct cfg80211_internal_bss *bss;
2673         struct cfg80211_bss *nontrans_bss;
2674         struct cfg80211_bss *tmp;
2675
2676         spin_lock_bh(&rdev->bss_lock);
2677
2678         /*
2679          * Some APs use CSA also for bandwidth changes, i.e., without actually
2680          * changing the control channel, so no need to update in such a case.
2681          */
2682         if (cbss->pub.channel == chan)
2683                 goto done;
2684
2685         /* use transmitting bss */
2686         if (cbss->pub.transmitted_bss)
2687                 cbss = container_of(cbss->pub.transmitted_bss,
2688                                     struct cfg80211_internal_bss,
2689                                     pub);
2690
2691         cbss->pub.channel = chan;
2692
2693         list_for_each_entry(bss, &rdev->bss_list, list) {
2694                 if (!cfg80211_bss_type_match(bss->pub.capability,
2695                                              bss->pub.channel->band,
2696                                              wdev->conn_bss_type))
2697                         continue;
2698
2699                 if (bss == cbss)
2700                         continue;
2701
2702                 if (!cmp_bss(&bss->pub, &cbss->pub, BSS_CMP_REGULAR)) {
2703                         new = bss;
2704                         break;
2705                 }
2706         }
2707
2708         if (new) {
2709                 /* to save time, update IEs for transmitting bss only */
2710                 if (cfg80211_update_known_bss(rdev, cbss, new, false)) {
2711                         new->pub.proberesp_ies = NULL;
2712                         new->pub.beacon_ies = NULL;
2713                 }
2714
2715                 list_for_each_entry_safe(nontrans_bss, tmp,
2716                                          &new->pub.nontrans_list,
2717                                          nontrans_list) {
2718                         bss = container_of(nontrans_bss,
2719                                            struct cfg80211_internal_bss, pub);
2720                         if (__cfg80211_unlink_bss(rdev, bss))
2721                                 rdev->bss_generation++;
2722                 }
2723
2724                 WARN_ON(atomic_read(&new->hold));
2725                 if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new)))
2726                         rdev->bss_generation++;
2727         }
2728
2729         rb_erase(&cbss->rbn, &rdev->bss_tree);
2730         rb_insert_bss(rdev, cbss);
2731         rdev->bss_generation++;
2732
2733         list_for_each_entry_safe(nontrans_bss, tmp,
2734                                  &cbss->pub.nontrans_list,
2735                                  nontrans_list) {
2736                 bss = container_of(nontrans_bss,
2737                                    struct cfg80211_internal_bss, pub);
2738                 bss->pub.channel = chan;
2739                 rb_erase(&bss->rbn, &rdev->bss_tree);
2740                 rb_insert_bss(rdev, bss);
2741                 rdev->bss_generation++;
2742         }
2743
2744 done:
2745         spin_unlock_bh(&rdev->bss_lock);
2746 }
2747
2748 #ifdef CONFIG_CFG80211_WEXT
2749 static struct cfg80211_registered_device *
2750 cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
2751 {
2752         struct cfg80211_registered_device *rdev;
2753         struct net_device *dev;
2754
2755         ASSERT_RTNL();
2756
2757         dev = dev_get_by_index(net, ifindex);
2758         if (!dev)
2759                 return ERR_PTR(-ENODEV);
2760         if (dev->ieee80211_ptr)
2761                 rdev = wiphy_to_rdev(dev->ieee80211_ptr->wiphy);
2762         else
2763                 rdev = ERR_PTR(-ENODEV);
2764         dev_put(dev);
2765         return rdev;
2766 }
2767
2768 int cfg80211_wext_siwscan(struct net_device *dev,
2769                           struct iw_request_info *info,
2770                           union iwreq_data *wrqu, char *extra)
2771 {
2772         struct cfg80211_registered_device *rdev;
2773         struct wiphy *wiphy;
2774         struct iw_scan_req *wreq = NULL;
2775         struct cfg80211_scan_request *creq;
2776         int i, err, n_channels = 0;
2777         enum nl80211_band band;
2778
2779         if (!netif_running(dev))
2780                 return -ENETDOWN;
2781
2782         if (wrqu->data.length == sizeof(struct iw_scan_req))
2783                 wreq = (struct iw_scan_req *)extra;
2784
2785         rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
2786
2787         if (IS_ERR(rdev))
2788                 return PTR_ERR(rdev);
2789
2790         if (rdev->scan_req || rdev->scan_msg)
2791                 return -EBUSY;
2792
2793         wiphy = &rdev->wiphy;
2794
2795         /* Determine number of channels, needed to allocate creq */
2796         if (wreq && wreq->num_channels)
2797                 n_channels = wreq->num_channels;
2798         else
2799                 n_channels = ieee80211_get_num_supported_channels(wiphy);
2800
2801         creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
2802                        n_channels * sizeof(void *),
2803                        GFP_ATOMIC);
2804         if (!creq)
2805                 return -ENOMEM;
2806
2807         creq->wiphy = wiphy;
2808         creq->wdev = dev->ieee80211_ptr;
2809         /* SSIDs come after channels */
2810         creq->ssids = (void *)&creq->channels[n_channels];
2811         creq->n_channels = n_channels;
2812         creq->n_ssids = 1;
2813         creq->scan_start = jiffies;
2814
2815         /* translate "Scan on frequencies" request */
2816         i = 0;
2817         for (band = 0; band < NUM_NL80211_BANDS; band++) {
2818                 int j;
2819
2820                 if (!wiphy->bands[band])
2821                         continue;
2822
2823                 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
2824                         /* ignore disabled channels */
2825                         if (wiphy->bands[band]->channels[j].flags &
2826                                                 IEEE80211_CHAN_DISABLED)
2827                                 continue;
2828
2829                         /* If we have a wireless request structure and the
2830                          * wireless request specifies frequencies, then search
2831                          * for the matching hardware channel.
2832                          */
2833                         if (wreq && wreq->num_channels) {
2834                                 int k;
2835                                 int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
2836                                 for (k = 0; k < wreq->num_channels; k++) {
2837                                         struct iw_freq *freq =
2838                                                 &wreq->channel_list[k];
2839                                         int wext_freq =
2840                                                 cfg80211_wext_freq(freq);
2841
2842                                         if (wext_freq == wiphy_freq)
2843                                                 goto wext_freq_found;
2844                                 }
2845                                 goto wext_freq_not_found;
2846                         }
2847
2848                 wext_freq_found:
2849                         creq->channels[i] = &wiphy->bands[band]->channels[j];
2850                         i++;
2851                 wext_freq_not_found: ;
2852                 }
2853         }
2854         /* No channels found? */
2855         if (!i) {
2856                 err = -EINVAL;
2857                 goto out;
2858         }
2859
2860         /* Set real number of channels specified in creq->channels[] */
2861         creq->n_channels = i;
2862
2863         /* translate "Scan for SSID" request */
2864         if (wreq) {
2865                 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
2866                         if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
2867                                 err = -EINVAL;
2868                                 goto out;
2869                         }
2870                         memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
2871                         creq->ssids[0].ssid_len = wreq->essid_len;
2872                 }
2873                 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
2874                         creq->n_ssids = 0;
2875         }
2876
2877         for (i = 0; i < NUM_NL80211_BANDS; i++)
2878                 if (wiphy->bands[i])
2879                         creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
2880
2881         eth_broadcast_addr(creq->bssid);
2882
2883         wiphy_lock(&rdev->wiphy);
2884
2885         rdev->scan_req = creq;
2886         err = rdev_scan(rdev, creq);
2887         if (err) {
2888                 rdev->scan_req = NULL;
2889                 /* creq will be freed below */
2890         } else {
2891                 nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
2892                 /* creq now owned by driver */
2893                 creq = NULL;
2894                 dev_hold(dev);
2895         }
2896         wiphy_unlock(&rdev->wiphy);
2897  out:
2898         kfree(creq);
2899         return err;
2900 }
2901 EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan);
2902
2903 static char *ieee80211_scan_add_ies(struct iw_request_info *info,
2904                                     const struct cfg80211_bss_ies *ies,
2905                                     char *current_ev, char *end_buf)
2906 {
2907         const u8 *pos, *end, *next;
2908         struct iw_event iwe;
2909
2910         if (!ies)
2911                 return current_ev;
2912
2913         /*
2914          * If needed, fragment the IEs buffer (at IE boundaries) into short
2915          * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
2916          */
2917         pos = ies->data;
2918         end = pos + ies->len;
2919
2920         while (end - pos > IW_GENERIC_IE_MAX) {
2921                 next = pos + 2 + pos[1];
2922                 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
2923                         next = next + 2 + next[1];
2924
2925                 memset(&iwe, 0, sizeof(iwe));
2926                 iwe.cmd = IWEVGENIE;
2927                 iwe.u.data.length = next - pos;
2928                 current_ev = iwe_stream_add_point_check(info, current_ev,
2929                                                         end_buf, &iwe,
2930                                                         (void *)pos);
2931                 if (IS_ERR(current_ev))
2932                         return current_ev;
2933                 pos = next;
2934         }
2935
2936         if (end > pos) {
2937                 memset(&iwe, 0, sizeof(iwe));
2938                 iwe.cmd = IWEVGENIE;
2939                 iwe.u.data.length = end - pos;
2940                 current_ev = iwe_stream_add_point_check(info, current_ev,
2941                                                         end_buf, &iwe,
2942                                                         (void *)pos);
2943                 if (IS_ERR(current_ev))
2944                         return current_ev;
2945         }
2946
2947         return current_ev;
2948 }
2949
2950 static char *
2951 ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
2952               struct cfg80211_internal_bss *bss, char *current_ev,
2953               char *end_buf)
2954 {
2955         const struct cfg80211_bss_ies *ies;
2956         struct iw_event iwe;
2957         const u8 *ie;
2958         u8 buf[50];
2959         u8 *cfg, *p, *tmp;
2960         int rem, i, sig;
2961         bool ismesh = false;
2962
2963         memset(&iwe, 0, sizeof(iwe));
2964         iwe.cmd = SIOCGIWAP;
2965         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2966         memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
2967         current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2968                                                 IW_EV_ADDR_LEN);
2969         if (IS_ERR(current_ev))
2970                 return current_ev;
2971
2972         memset(&iwe, 0, sizeof(iwe));
2973         iwe.cmd = SIOCGIWFREQ;
2974         iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
2975         iwe.u.freq.e = 0;
2976         current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2977                                                 IW_EV_FREQ_LEN);
2978         if (IS_ERR(current_ev))
2979                 return current_ev;
2980
2981         memset(&iwe, 0, sizeof(iwe));
2982         iwe.cmd = SIOCGIWFREQ;
2983         iwe.u.freq.m = bss->pub.channel->center_freq;
2984         iwe.u.freq.e = 6;
2985         current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2986                                                 IW_EV_FREQ_LEN);
2987         if (IS_ERR(current_ev))
2988                 return current_ev;
2989
2990         if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
2991                 memset(&iwe, 0, sizeof(iwe));
2992                 iwe.cmd = IWEVQUAL;
2993                 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
2994                                      IW_QUAL_NOISE_INVALID |
2995                                      IW_QUAL_QUAL_UPDATED;
2996                 switch (wiphy->signal_type) {
2997                 case CFG80211_SIGNAL_TYPE_MBM:
2998                         sig = bss->pub.signal / 100;
2999                         iwe.u.qual.level = sig;
3000                         iwe.u.qual.updated |= IW_QUAL_DBM;
3001                         if (sig < -110)         /* rather bad */
3002                                 sig = -110;
3003                         else if (sig > -40)     /* perfect */
3004                                 sig = -40;
3005                         /* will give a range of 0 .. 70 */
3006                         iwe.u.qual.qual = sig + 110;
3007                         break;
3008                 case CFG80211_SIGNAL_TYPE_UNSPEC:
3009                         iwe.u.qual.level = bss->pub.signal;
3010                         /* will give range 0 .. 100 */
3011                         iwe.u.qual.qual = bss->pub.signal;
3012                         break;
3013                 default:
3014                         /* not reached */
3015                         break;
3016                 }
3017                 current_ev = iwe_stream_add_event_check(info, current_ev,
3018                                                         end_buf, &iwe,
3019                                                         IW_EV_QUAL_LEN);
3020                 if (IS_ERR(current_ev))
3021                         return current_ev;
3022         }
3023
3024         memset(&iwe, 0, sizeof(iwe));
3025         iwe.cmd = SIOCGIWENCODE;
3026         if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
3027                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
3028         else
3029                 iwe.u.data.flags = IW_ENCODE_DISABLED;
3030         iwe.u.data.length = 0;
3031         current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
3032                                                 &iwe, "");
3033         if (IS_ERR(current_ev))
3034                 return current_ev;
3035
3036         rcu_read_lock();
3037         ies = rcu_dereference(bss->pub.ies);
3038         rem = ies->len;
3039         ie = ies->data;
3040
3041         while (rem >= 2) {
3042                 /* invalid data */
3043                 if (ie[1] > rem - 2)
3044                         break;
3045
3046                 switch (ie[0]) {
3047                 case WLAN_EID_SSID:
3048                         memset(&iwe, 0, sizeof(iwe));
3049                         iwe.cmd = SIOCGIWESSID;
3050                         iwe.u.data.length = ie[1];
3051                         iwe.u.data.flags = 1;
3052                         current_ev = iwe_stream_add_point_check(info,
3053                                                                 current_ev,
3054                                                                 end_buf, &iwe,
3055                                                                 (u8 *)ie + 2);
3056                         if (IS_ERR(current_ev))
3057                                 goto unlock;
3058                         break;
3059                 case WLAN_EID_MESH_ID:
3060                         memset(&iwe, 0, sizeof(iwe));
3061                         iwe.cmd = SIOCGIWESSID;
3062                         iwe.u.data.length = ie[1];
3063                         iwe.u.data.flags = 1;
3064                         current_ev = iwe_stream_add_point_check(info,
3065                                                                 current_ev,
3066                                                                 end_buf, &iwe,
3067                                                                 (u8 *)ie + 2);
3068                         if (IS_ERR(current_ev))
3069                                 goto unlock;
3070                         break;
3071                 case WLAN_EID_MESH_CONFIG:
3072                         ismesh = true;
3073                         if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
3074                                 break;
3075                         cfg = (u8 *)ie + 2;
3076                         memset(&iwe, 0, sizeof(iwe));
3077                         iwe.cmd = IWEVCUSTOM;
3078                         sprintf(buf, "Mesh Network Path Selection Protocol ID: "
3079                                 "0x%02X", cfg[0]);
3080                         iwe.u.data.length = strlen(buf);
3081                         current_ev = iwe_stream_add_point_check(info,
3082                                                                 current_ev,
3083                                                                 end_buf,
3084                                                                 &iwe, buf);
3085                         if (IS_ERR(current_ev))
3086                                 goto unlock;
3087                         sprintf(buf, "Path Selection Metric ID: 0x%02X",
3088                                 cfg[1]);
3089                         iwe.u.data.length = strlen(buf);
3090                         current_ev = iwe_stream_add_point_check(info,
3091                                                                 current_ev,
3092                                                                 end_buf,
3093                                                                 &iwe, buf);
3094                         if (IS_ERR(current_ev))
3095                                 goto unlock;
3096                         sprintf(buf, "Congestion Control Mode ID: 0x%02X",
3097                                 cfg[2]);
3098                         iwe.u.data.length = strlen(buf);
3099                         current_ev = iwe_stream_add_point_check(info,
3100                                                                 current_ev,
3101                                                                 end_buf,
3102                                                                 &iwe, buf);
3103                         if (IS_ERR(current_ev))
3104                                 goto unlock;
3105                         sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
3106                         iwe.u.data.length = strlen(buf);
3107                         current_ev = iwe_stream_add_point_check(info,
3108                                                                 current_ev,
3109                                                                 end_buf,
3110                                                                 &iwe, buf);
3111                         if (IS_ERR(current_ev))
3112                                 goto unlock;
3113                         sprintf(buf, "Authentication ID: 0x%02X", cfg[4]);
3114                         iwe.u.data.length = strlen(buf);
3115                         current_ev = iwe_stream_add_point_check(info,
3116                                                                 current_ev,
3117                                                                 end_buf,
3118                                                                 &iwe, buf);
3119                         if (IS_ERR(current_ev))
3120                                 goto unlock;
3121                         sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
3122                         iwe.u.data.length = strlen(buf);
3123                         current_ev = iwe_stream_add_point_check(info,
3124                                                                 current_ev,
3125                                                                 end_buf,
3126                                                                 &iwe, buf);
3127                         if (IS_ERR(current_ev))
3128                                 goto unlock;
3129                         sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
3130                         iwe.u.data.length = strlen(buf);
3131                         current_ev = iwe_stream_add_point_check(info,
3132                                                                 current_ev,
3133                                                                 end_buf,
3134                                                                 &iwe, buf);
3135                         if (IS_ERR(current_ev))
3136                                 goto unlock;
3137                         break;
3138                 case WLAN_EID_SUPP_RATES:
3139                 case WLAN_EID_EXT_SUPP_RATES:
3140                         /* display all supported rates in readable format */
3141                         p = current_ev + iwe_stream_lcp_len(info);
3142
3143                         memset(&iwe, 0, sizeof(iwe));
3144                         iwe.cmd = SIOCGIWRATE;
3145                         /* Those two flags are ignored... */
3146                         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
3147
3148                         for (i = 0; i < ie[1]; i++) {
3149                                 iwe.u.bitrate.value =
3150                                         ((ie[i + 2] & 0x7f) * 500000);
3151                                 tmp = p;
3152                                 p = iwe_stream_add_value(info, current_ev, p,
3153                                                          end_buf, &iwe,
3154                                                          IW_EV_PARAM_LEN);
3155                                 if (p == tmp) {
3156                                         current_ev = ERR_PTR(-E2BIG);
3157                                         goto unlock;
3158                                 }
3159                         }
3160                         current_ev = p;
3161                         break;
3162                 }
3163                 rem -= ie[1] + 2;
3164                 ie += ie[1] + 2;
3165         }
3166
3167         if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
3168             ismesh) {
3169                 memset(&iwe, 0, sizeof(iwe));
3170                 iwe.cmd = SIOCGIWMODE;
3171                 if (ismesh)
3172                         iwe.u.mode = IW_MODE_MESH;
3173                 else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
3174                         iwe.u.mode = IW_MODE_MASTER;
3175                 else
3176                         iwe.u.mode = IW_MODE_ADHOC;
3177                 current_ev = iwe_stream_add_event_check(info, current_ev,
3178                                                         end_buf, &iwe,
3179                                                         IW_EV_UINT_LEN);
3180                 if (IS_ERR(current_ev))
3181                         goto unlock;
3182         }
3183
3184         memset(&iwe, 0, sizeof(iwe));
3185         iwe.cmd = IWEVCUSTOM;
3186         sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
3187         iwe.u.data.length = strlen(buf);
3188         current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
3189                                                 &iwe, buf);
3190         if (IS_ERR(current_ev))
3191                 goto unlock;
3192         memset(&iwe, 0, sizeof(iwe));
3193         iwe.cmd = IWEVCUSTOM;
3194         sprintf(buf, " Last beacon: %ums ago",
3195                 elapsed_jiffies_msecs(bss->ts));
3196         iwe.u.data.length = strlen(buf);
3197         current_ev = iwe_stream_add_point_check(info, current_ev,
3198                                                 end_buf, &iwe, buf);
3199         if (IS_ERR(current_ev))
3200                 goto unlock;
3201
3202         current_ev = ieee80211_scan_add_ies(info, ies, current_ev, end_buf);
3203
3204  unlock:
3205         rcu_read_unlock();
3206         return current_ev;
3207 }
3208
3209
3210 static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
3211                                   struct iw_request_info *info,
3212                                   char *buf, size_t len)
3213 {
3214         char *current_ev = buf;
3215         char *end_buf = buf + len;
3216         struct cfg80211_internal_bss *bss;
3217         int err = 0;
3218
3219         spin_lock_bh(&rdev->bss_lock);
3220         cfg80211_bss_expire(rdev);
3221
3222         list_for_each_entry(bss, &rdev->bss_list, list) {
3223                 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
3224                         err = -E2BIG;
3225                         break;
3226                 }
3227                 current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
3228                                            current_ev, end_buf);
3229                 if (IS_ERR(current_ev)) {
3230                         err = PTR_ERR(current_ev);
3231                         break;
3232                 }
3233         }
3234         spin_unlock_bh(&rdev->bss_lock);
3235
3236         if (err)
3237                 return err;
3238         return current_ev - buf;
3239 }
3240
3241
3242 int cfg80211_wext_giwscan(struct net_device *dev,
3243                           struct iw_request_info *info,
3244                           struct iw_point *data, char *extra)
3245 {
3246         struct cfg80211_registered_device *rdev;
3247         int res;
3248
3249         if (!netif_running(dev))
3250                 return -ENETDOWN;
3251
3252         rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
3253
3254         if (IS_ERR(rdev))
3255                 return PTR_ERR(rdev);
3256
3257         if (rdev->scan_req || rdev->scan_msg)
3258                 return -EAGAIN;
3259
3260         res = ieee80211_scan_results(rdev, info, extra, data->length);
3261         data->length = 0;
3262         if (res >= 0) {
3263                 data->length = res;
3264                 res = 0;
3265         }
3266
3267         return res;
3268 }
3269 EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan);
3270 #endif