94
94
EXPORT_SYMBOL(cfg80211_scan_done);
96
void __cfg80211_sched_scan_results(struct work_struct *wk)
98
struct cfg80211_registered_device *rdev;
100
rdev = container_of(wk, struct cfg80211_registered_device,
101
sched_scan_results_wk);
103
mutex_lock(&rdev->sched_scan_mtx);
105
/* we don't have sched_scan_req anymore if the scan is stopping */
106
if (rdev->sched_scan_req)
107
nl80211_send_sched_scan_results(rdev,
108
rdev->sched_scan_req->dev);
110
mutex_unlock(&rdev->sched_scan_mtx);
113
void cfg80211_sched_scan_results(struct wiphy *wiphy)
115
/* ignore if we're not scanning */
116
if (wiphy_to_dev(wiphy)->sched_scan_req)
117
queue_work(cfg80211_wq,
118
&wiphy_to_dev(wiphy)->sched_scan_results_wk);
120
EXPORT_SYMBOL(cfg80211_sched_scan_results);
122
void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
124
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
126
mutex_lock(&rdev->sched_scan_mtx);
127
__cfg80211_stop_sched_scan(rdev, true);
128
mutex_unlock(&rdev->sched_scan_mtx);
130
EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
132
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
133
bool driver_initiated)
136
struct net_device *dev;
138
lockdep_assert_held(&rdev->sched_scan_mtx);
140
if (!rdev->sched_scan_req)
143
dev = rdev->sched_scan_req->dev;
145
if (!driver_initiated) {
146
err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
151
nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
153
kfree(rdev->sched_scan_req);
154
rdev->sched_scan_req = NULL;
96
159
static void bss_release(struct kref *ref)
98
161
struct cfg80211_internal_bss *bss;
126
189
/* must hold dev->bss_lock! */
190
static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
191
struct cfg80211_internal_bss *bss)
193
list_del_init(&bss->list);
194
rb_erase(&bss->rbn, &dev->bss_tree);
195
kref_put(&bss->ref, bss_release);
198
/* must hold dev->bss_lock! */
127
199
void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
129
201
struct cfg80211_internal_bss *bss, *tmp;
135
207
if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
137
list_del(&bss->list);
138
rb_erase(&bss->rbn, &dev->bss_tree);
139
kref_put(&bss->ref, bss_release);
209
__cfg80211_unlink_bss(dev, bss);
197
267
return memcmp(ssidie + 2, ssid, ssid_len) == 0;
270
static bool is_mesh_bss(struct cfg80211_bss *a)
274
if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
277
ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
278
a->information_elements,
279
a->len_information_elements);
283
ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
284
a->information_elements,
285
a->len_information_elements);
200
292
static bool is_mesh(struct cfg80211_bss *a,
201
293
const u8 *meshid, size_t meshidlen,
202
294
const u8 *meshcfg)
206
if (!is_zero_ether_addr(a->bssid))
298
if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
209
301
ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
241
333
if (a->channel != b->channel)
242
334
return b->channel->center_freq - a->channel->center_freq;
244
r = memcmp(a->bssid, b->bssid, ETH_ALEN);
248
if (is_zero_ether_addr(a->bssid)) {
336
if (is_mesh_bss(a) && is_mesh_bss(b)) {
249
337
r = cmp_ies(WLAN_EID_MESH_ID,
250
338
a->information_elements,
251
339
a->len_information_elements,
260
348
b->len_information_elements);
351
r = memcmp(a->bssid, b->bssid, ETH_ALEN);
263
355
return cmp_ies(WLAN_EID_SSID,
264
356
a->information_elements,
265
357
a->len_information_elements,
387
479
struct cfg80211_internal_bss *res)
389
481
struct cfg80211_internal_bss *found = NULL;
390
const u8 *meshid, *meshcfg;
393
484
* The reference to "res" is donated to this function.
401
492
res->ts = jiffies;
403
if (is_zero_ether_addr(res->pub.bssid)) {
404
/* must be mesh, verify */
405
meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
406
res->pub.information_elements,
407
res->pub.len_information_elements);
408
meshcfg = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
409
res->pub.information_elements,
410
res->pub.len_information_elements);
411
if (!meshid || !meshcfg ||
412
meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) {
414
kref_put(&res->ref, bss_release);
419
494
spin_lock_bh(&dev->bss_lock);
421
496
found = rb_find_bss(dev, res);
585
660
struct cfg80211_internal_bss *res;
586
661
size_t ielen = len - offsetof(struct ieee80211_mgmt,
587
662
u.probe_resp.variable);
588
size_t privsz = wiphy->bss_priv_size;
590
671
if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
591
672
(signal < 0 || signal > 100)))
594
if (WARN_ON(!mgmt || !wiphy ||
595
len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
675
if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
678
privsz = wiphy->bss_priv_size;
598
680
res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
663
745
spin_lock_bh(&dev->bss_lock);
664
746
if (!list_empty(&bss->list)) {
665
list_del_init(&bss->list);
747
__cfg80211_unlink_bss(dev, bss);
666
748
dev->bss_generation++;
667
rb_erase(&bss->rbn, &dev->bss_tree);
669
kref_put(&bss->ref, bss_release);
671
750
spin_unlock_bh(&dev->bss_lock);