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