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