diff options
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r-- | net/wireless/scan.c | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index fbf6f33ae4d0..73a441d237b5 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -93,6 +93,69 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) | |||
93 | } | 93 | } |
94 | EXPORT_SYMBOL(cfg80211_scan_done); | 94 | EXPORT_SYMBOL(cfg80211_scan_done); |
95 | 95 | ||
96 | void __cfg80211_sched_scan_results(struct work_struct *wk) | ||
97 | { | ||
98 | struct cfg80211_registered_device *rdev; | ||
99 | |||
100 | rdev = container_of(wk, struct cfg80211_registered_device, | ||
101 | sched_scan_results_wk); | ||
102 | |||
103 | cfg80211_lock_rdev(rdev); | ||
104 | |||
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); | ||
109 | |||
110 | cfg80211_unlock_rdev(rdev); | ||
111 | } | ||
112 | |||
113 | void cfg80211_sched_scan_results(struct wiphy *wiphy) | ||
114 | { | ||
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); | ||
119 | } | ||
120 | EXPORT_SYMBOL(cfg80211_sched_scan_results); | ||
121 | |||
122 | void cfg80211_sched_scan_stopped(struct wiphy *wiphy) | ||
123 | { | ||
124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
125 | |||
126 | cfg80211_lock_rdev(rdev); | ||
127 | __cfg80211_stop_sched_scan(rdev, true); | ||
128 | cfg80211_unlock_rdev(rdev); | ||
129 | } | ||
130 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); | ||
131 | |||
132 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | ||
133 | bool driver_initiated) | ||
134 | { | ||
135 | int err; | ||
136 | struct net_device *dev; | ||
137 | |||
138 | ASSERT_RDEV_LOCK(rdev); | ||
139 | |||
140 | if (!rdev->sched_scan_req) | ||
141 | return 0; | ||
142 | |||
143 | dev = rdev->sched_scan_req->dev; | ||
144 | |||
145 | if (!driver_initiated) { | ||
146 | err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev); | ||
147 | if (err) | ||
148 | return err; | ||
149 | } | ||
150 | |||
151 | nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED); | ||
152 | |||
153 | kfree(rdev->sched_scan_req); | ||
154 | rdev->sched_scan_req = NULL; | ||
155 | |||
156 | return err; | ||
157 | } | ||
158 | |||
96 | static void bss_release(struct kref *ref) | 159 | static void bss_release(struct kref *ref) |
97 | { | 160 | { |
98 | struct cfg80211_internal_bss *bss; | 161 | struct cfg80211_internal_bss *bss; |
@@ -210,7 +273,7 @@ static bool is_mesh(struct cfg80211_bss *a, | |||
210 | { | 273 | { |
211 | const u8 *ie; | 274 | const u8 *ie; |
212 | 275 | ||
213 | if (!is_zero_ether_addr(a->bssid)) | 276 | if (!WLAN_CAPABILITY_IS_MBSS(a->capability)) |
214 | return false; | 277 | return false; |
215 | 278 | ||
216 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, | 279 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, |
@@ -248,11 +311,7 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
248 | if (a->channel != b->channel) | 311 | if (a->channel != b->channel) |
249 | return b->channel->center_freq - a->channel->center_freq; | 312 | return b->channel->center_freq - a->channel->center_freq; |
250 | 313 | ||
251 | r = memcmp(a->bssid, b->bssid, ETH_ALEN); | 314 | if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) { |
252 | if (r) | ||
253 | return r; | ||
254 | |||
255 | if (is_zero_ether_addr(a->bssid)) { | ||
256 | r = cmp_ies(WLAN_EID_MESH_ID, | 315 | r = cmp_ies(WLAN_EID_MESH_ID, |
257 | a->information_elements, | 316 | a->information_elements, |
258 | a->len_information_elements, | 317 | a->len_information_elements, |
@@ -267,6 +326,10 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
267 | b->len_information_elements); | 326 | b->len_information_elements); |
268 | } | 327 | } |
269 | 328 | ||
329 | r = memcmp(a->bssid, b->bssid, ETH_ALEN); | ||
330 | if (r) | ||
331 | return r; | ||
332 | |||
270 | return cmp_ies(WLAN_EID_SSID, | 333 | return cmp_ies(WLAN_EID_SSID, |
271 | a->information_elements, | 334 | a->information_elements, |
272 | a->len_information_elements, | 335 | a->len_information_elements, |
@@ -407,7 +470,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
407 | 470 | ||
408 | res->ts = jiffies; | 471 | res->ts = jiffies; |
409 | 472 | ||
410 | if (is_zero_ether_addr(res->pub.bssid)) { | 473 | if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) { |
411 | /* must be mesh, verify */ | 474 | /* must be mesh, verify */ |
412 | meshid = cfg80211_find_ie(WLAN_EID_MESH_ID, | 475 | meshid = cfg80211_find_ie(WLAN_EID_MESH_ID, |
413 | res->pub.information_elements, | 476 | res->pub.information_elements, |