scan.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. /*
  2. * Scanning implementation
  3. *
  4. * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
  5. * Copyright 2004, Instant802 Networks, Inc.
  6. * Copyright 2005, Devicescape Software, Inc.
  7. * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  8. * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. */
  14. /* TODO:
  15. * figure out how to avoid that the "current BSS" expires
  16. * clean up IBSS code (in MLME), see why it adds a BSS to the list
  17. * use cfg80211's BSS handling (depends on IBSS TODO above)
  18. * order BSS list by RSSI(?) ("quality of AP")
  19. * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
  20. * SSID)
  21. */
  22. #include <linux/wireless.h>
  23. #include <linux/if_arp.h>
  24. #include <linux/rtnetlink.h>
  25. #include <net/mac80211.h>
  26. #include <net/iw_handler.h>
  27. #include "ieee80211_i.h"
  28. #include "mesh.h"
  29. #define IEEE80211_PROBE_DELAY (HZ / 33)
  30. #define IEEE80211_CHANNEL_TIME (HZ / 33)
  31. #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
  32. void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
  33. {
  34. spin_lock_init(&local->bss_lock);
  35. INIT_LIST_HEAD(&local->bss_list);
  36. }
  37. void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
  38. {
  39. struct ieee80211_bss *bss, *tmp;
  40. list_for_each_entry_safe(bss, tmp, &local->bss_list, list)
  41. ieee80211_rx_bss_put(local, bss);
  42. }
  43. struct ieee80211_bss *
  44. ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
  45. u8 *ssid, u8 ssid_len)
  46. {
  47. struct ieee80211_bss *bss;
  48. spin_lock_bh(&local->bss_lock);
  49. bss = local->bss_hash[STA_HASH(bssid)];
  50. while (bss) {
  51. if (!bss_mesh_cfg(bss) &&
  52. !memcmp(bss->bssid, bssid, ETH_ALEN) &&
  53. bss->freq == freq &&
  54. bss->ssid_len == ssid_len &&
  55. (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
  56. atomic_inc(&bss->users);
  57. break;
  58. }
  59. bss = bss->hnext;
  60. }
  61. spin_unlock_bh(&local->bss_lock);
  62. return bss;
  63. }
  64. /* Caller must hold local->bss_lock */
  65. static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
  66. struct ieee80211_bss *bss)
  67. {
  68. u8 hash_idx;
  69. if (bss_mesh_cfg(bss))
  70. hash_idx = mesh_id_hash(bss_mesh_id(bss),
  71. bss_mesh_id_len(bss));
  72. else
  73. hash_idx = STA_HASH(bss->bssid);
  74. bss->hnext = local->bss_hash[hash_idx];
  75. local->bss_hash[hash_idx] = bss;
  76. }
  77. /* Caller must hold local->bss_lock */
  78. static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
  79. struct ieee80211_bss *bss)
  80. {
  81. struct ieee80211_bss *b, *prev = NULL;
  82. b = local->bss_hash[STA_HASH(bss->bssid)];
  83. while (b) {
  84. if (b == bss) {
  85. if (!prev)
  86. local->bss_hash[STA_HASH(bss->bssid)] =
  87. bss->hnext;
  88. else
  89. prev->hnext = bss->hnext;
  90. break;
  91. }
  92. prev = b;
  93. b = b->hnext;
  94. }
  95. }
  96. struct ieee80211_bss *
  97. ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
  98. u8 *ssid, u8 ssid_len)
  99. {
  100. struct ieee80211_bss *bss;
  101. bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
  102. if (!bss)
  103. return NULL;
  104. atomic_set(&bss->users, 2);
  105. memcpy(bss->bssid, bssid, ETH_ALEN);
  106. bss->freq = freq;
  107. if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
  108. memcpy(bss->ssid, ssid, ssid_len);
  109. bss->ssid_len = ssid_len;
  110. }
  111. spin_lock_bh(&local->bss_lock);
  112. /* TODO: order by RSSI? */
  113. list_add_tail(&bss->list, &local->bss_list);
  114. __ieee80211_rx_bss_hash_add(local, bss);
  115. spin_unlock_bh(&local->bss_lock);
  116. return bss;
  117. }
  118. #ifdef CONFIG_MAC80211_MESH
  119. static struct ieee80211_bss *
  120. ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
  121. u8 *mesh_cfg, int freq)
  122. {
  123. struct ieee80211_bss *bss;
  124. spin_lock_bh(&local->bss_lock);
  125. bss = local->bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
  126. while (bss) {
  127. if (bss_mesh_cfg(bss) &&
  128. !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
  129. bss->freq == freq &&
  130. mesh_id_len == bss->mesh_id_len &&
  131. (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
  132. mesh_id_len))) {
  133. atomic_inc(&bss->users);
  134. break;
  135. }
  136. bss = bss->hnext;
  137. }
  138. spin_unlock_bh(&local->bss_lock);
  139. return bss;
  140. }
  141. static struct ieee80211_bss *
  142. ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
  143. u8 *mesh_cfg, int mesh_config_len, int freq)
  144. {
  145. struct ieee80211_bss *bss;
  146. if (mesh_config_len != IEEE80211_MESH_CONFIG_LEN)
  147. return NULL;
  148. bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
  149. if (!bss)
  150. return NULL;
  151. bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
  152. if (!bss->mesh_cfg) {
  153. kfree(bss);
  154. return NULL;
  155. }
  156. if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
  157. bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
  158. if (!bss->mesh_id) {
  159. kfree(bss->mesh_cfg);
  160. kfree(bss);
  161. return NULL;
  162. }
  163. memcpy(bss->mesh_id, mesh_id, mesh_id_len);
  164. }
  165. atomic_set(&bss->users, 2);
  166. memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
  167. bss->mesh_id_len = mesh_id_len;
  168. bss->freq = freq;
  169. spin_lock_bh(&local->bss_lock);
  170. /* TODO: order by RSSI? */
  171. list_add_tail(&bss->list, &local->bss_list);
  172. __ieee80211_rx_bss_hash_add(local, bss);
  173. spin_unlock_bh(&local->bss_lock);
  174. return bss;
  175. }
  176. #endif
  177. static void ieee80211_rx_bss_free(struct ieee80211_bss *bss)
  178. {
  179. kfree(bss->ies);
  180. kfree(bss_mesh_id(bss));
  181. kfree(bss_mesh_cfg(bss));
  182. kfree(bss);
  183. }
  184. void ieee80211_rx_bss_put(struct ieee80211_local *local,
  185. struct ieee80211_bss *bss)
  186. {
  187. local_bh_disable();
  188. if (!atomic_dec_and_lock(&bss->users, &local->bss_lock)) {
  189. local_bh_enable();
  190. return;
  191. }
  192. __ieee80211_rx_bss_hash_del(local, bss);
  193. list_del(&bss->list);
  194. spin_unlock_bh(&local->bss_lock);
  195. ieee80211_rx_bss_free(bss);
  196. }
  197. struct ieee80211_bss *
  198. ieee80211_bss_info_update(struct ieee80211_local *local,
  199. struct ieee80211_rx_status *rx_status,
  200. struct ieee80211_mgmt *mgmt,
  201. size_t len,
  202. struct ieee802_11_elems *elems,
  203. struct ieee80211_channel *channel,
  204. bool beacon)
  205. {
  206. struct ieee80211_bss *bss;
  207. int clen, freq = channel->center_freq;
  208. enum cfg80211_signal_type sigtype = CFG80211_SIGNAL_TYPE_NONE;
  209. s32 signal = 0;
  210. if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
  211. sigtype = CFG80211_SIGNAL_TYPE_MBM;
  212. signal = rx_status->signal * 100;
  213. } else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) {
  214. sigtype = CFG80211_SIGNAL_TYPE_UNSPEC;
  215. signal = (rx_status->signal * 100) / local->hw.max_signal;
  216. }
  217. cfg80211_put_bss(
  218. cfg80211_inform_bss_frame(local->hw.wiphy, channel,
  219. mgmt, len, signal, sigtype,
  220. GFP_ATOMIC));
  221. #ifdef CONFIG_MAC80211_MESH
  222. if (elems->mesh_config)
  223. bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id,
  224. elems->mesh_id_len, elems->mesh_config, freq);
  225. else
  226. #endif
  227. bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq,
  228. elems->ssid, elems->ssid_len);
  229. if (!bss) {
  230. #ifdef CONFIG_MAC80211_MESH
  231. if (elems->mesh_config)
  232. bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
  233. elems->mesh_id_len, elems->mesh_config,
  234. elems->mesh_config_len, freq);
  235. else
  236. #endif
  237. bss = ieee80211_rx_bss_add(local, mgmt->bssid, freq,
  238. elems->ssid, elems->ssid_len);
  239. if (!bss)
  240. return NULL;
  241. } else {
  242. #if 0
  243. /* TODO: order by RSSI? */
  244. spin_lock_bh(&local->bss_lock);
  245. list_move_tail(&bss->list, &local->bss_list);
  246. spin_unlock_bh(&local->bss_lock);
  247. #endif
  248. }
  249. /* save the ERP value so that it is available at association time */
  250. if (elems->erp_info && elems->erp_info_len >= 1) {
  251. bss->erp_value = elems->erp_info[0];
  252. bss->has_erp_value = 1;
  253. }
  254. bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
  255. bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
  256. if (elems->tim) {
  257. struct ieee80211_tim_ie *tim_ie =
  258. (struct ieee80211_tim_ie *)elems->tim;
  259. bss->dtim_period = tim_ie->dtim_period;
  260. }
  261. /* set default value for buggy APs */
  262. if (!elems->tim || bss->dtim_period == 0)
  263. bss->dtim_period = 1;
  264. bss->supp_rates_len = 0;
  265. if (elems->supp_rates) {
  266. clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
  267. if (clen > elems->supp_rates_len)
  268. clen = elems->supp_rates_len;
  269. memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
  270. clen);
  271. bss->supp_rates_len += clen;
  272. }
  273. if (elems->ext_supp_rates) {
  274. clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
  275. if (clen > elems->ext_supp_rates_len)
  276. clen = elems->ext_supp_rates_len;
  277. memcpy(&bss->supp_rates[bss->supp_rates_len],
  278. elems->ext_supp_rates, clen);
  279. bss->supp_rates_len += clen;
  280. }
  281. bss->band = rx_status->band;
  282. bss->timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
  283. bss->last_update = jiffies;
  284. bss->signal = rx_status->signal;
  285. bss->noise = rx_status->noise;
  286. bss->qual = rx_status->qual;
  287. bss->wmm_used = elems->wmm_param || elems->wmm_info;
  288. if (!beacon)
  289. bss->last_probe_resp = jiffies;
  290. /*
  291. * For probe responses, or if we don't have any information yet,
  292. * use the IEs from the beacon.
  293. */
  294. if (!bss->ies || !beacon) {
  295. if (bss->ies == NULL || bss->ies_len < elems->total_len) {
  296. kfree(bss->ies);
  297. bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
  298. }
  299. if (bss->ies) {
  300. memcpy(bss->ies, elems->ie_start, elems->total_len);
  301. bss->ies_len = elems->total_len;
  302. } else
  303. bss->ies_len = 0;
  304. }
  305. return bss;
  306. }
  307. void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid,
  308. int freq, u8 *ssid, u8 ssid_len)
  309. {
  310. struct ieee80211_bss *bss;
  311. struct ieee80211_local *local = sdata->local;
  312. bss = ieee80211_rx_bss_get(local, bssid, freq, ssid, ssid_len);
  313. if (bss) {
  314. atomic_dec(&bss->users);
  315. ieee80211_rx_bss_put(local, bss);
  316. }
  317. }
  318. ieee80211_rx_result
  319. ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
  320. struct ieee80211_rx_status *rx_status)
  321. {
  322. struct ieee80211_mgmt *mgmt;
  323. struct ieee80211_bss *bss;
  324. u8 *elements;
  325. struct ieee80211_channel *channel;
  326. size_t baselen;
  327. int freq;
  328. __le16 fc;
  329. bool presp, beacon = false;
  330. struct ieee802_11_elems elems;
  331. if (skb->len < 2)
  332. return RX_DROP_UNUSABLE;
  333. mgmt = (struct ieee80211_mgmt *) skb->data;
  334. fc = mgmt->frame_control;
  335. if (ieee80211_is_ctl(fc))
  336. return RX_CONTINUE;
  337. if (skb->len < 24)
  338. return RX_DROP_MONITOR;
  339. presp = ieee80211_is_probe_resp(fc);
  340. if (presp) {
  341. /* ignore ProbeResp to foreign address */
  342. if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
  343. return RX_DROP_MONITOR;
  344. presp = true;
  345. elements = mgmt->u.probe_resp.variable;
  346. baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
  347. } else {
  348. beacon = ieee80211_is_beacon(fc);
  349. baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
  350. elements = mgmt->u.beacon.variable;
  351. }
  352. if (!presp && !beacon)
  353. return RX_CONTINUE;
  354. if (baselen > skb->len)
  355. return RX_DROP_MONITOR;
  356. ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
  357. if (elems.ds_params && elems.ds_params_len == 1)
  358. freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
  359. else
  360. freq = rx_status->freq;
  361. channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
  362. if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
  363. return RX_DROP_MONITOR;
  364. bss = ieee80211_bss_info_update(sdata->local, rx_status,
  365. mgmt, skb->len, &elems,
  366. channel, beacon);
  367. if (bss)
  368. ieee80211_rx_bss_put(sdata->local, bss);
  369. dev_kfree_skb(skb);
  370. return RX_QUEUED;
  371. }
  372. void ieee80211_send_nullfunc(struct ieee80211_local *local,
  373. struct ieee80211_sub_if_data *sdata,
  374. int powersave)
  375. {
  376. struct sk_buff *skb;
  377. struct ieee80211_hdr *nullfunc;
  378. __le16 fc;
  379. skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
  380. if (!skb) {
  381. printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
  382. "frame\n", sdata->dev->name);
  383. return;
  384. }
  385. skb_reserve(skb, local->hw.extra_tx_headroom);
  386. nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
  387. memset(nullfunc, 0, 24);
  388. fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
  389. IEEE80211_FCTL_TODS);
  390. if (powersave)
  391. fc |= cpu_to_le16(IEEE80211_FCTL_PM);
  392. nullfunc->frame_control = fc;
  393. memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
  394. memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
  395. memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
  396. ieee80211_tx_skb(sdata, skb, 0);
  397. }
  398. void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
  399. {
  400. struct ieee80211_local *local = hw_to_local(hw);
  401. struct ieee80211_sub_if_data *sdata;
  402. if (WARN_ON(!local->hw_scanning && !local->sw_scanning))
  403. return;
  404. if (WARN_ON(!local->scan_req))
  405. return;
  406. if (local->scan_req != &local->int_scan_req)
  407. cfg80211_scan_done(local->scan_req, aborted);
  408. local->scan_req = NULL;
  409. local->last_scan_completed = jiffies;
  410. if (local->hw_scanning) {
  411. local->hw_scanning = false;
  412. /*
  413. * Somebody might have requested channel change during scan
  414. * that we won't have acted upon, try now. ieee80211_hw_config
  415. * will set the flag based on actual changes.
  416. */
  417. ieee80211_hw_config(local, 0);
  418. goto done;
  419. }
  420. local->sw_scanning = false;
  421. ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
  422. netif_tx_lock_bh(local->mdev);
  423. netif_addr_lock(local->mdev);
  424. local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
  425. local->ops->configure_filter(local_to_hw(local),
  426. FIF_BCN_PRBRESP_PROMISC,
  427. &local->filter_flags,
  428. local->mdev->mc_count,
  429. local->mdev->mc_list);
  430. netif_addr_unlock(local->mdev);
  431. netif_tx_unlock_bh(local->mdev);
  432. mutex_lock(&local->iflist_mtx);
  433. list_for_each_entry(sdata, &local->interfaces, list) {
  434. if (!netif_running(sdata->dev))
  435. continue;
  436. /* Tell AP we're back */
  437. if (sdata->vif.type == NL80211_IFTYPE_STATION) {
  438. if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
  439. ieee80211_send_nullfunc(local, sdata, 0);
  440. netif_tx_wake_all_queues(sdata->dev);
  441. }
  442. } else
  443. netif_tx_wake_all_queues(sdata->dev);
  444. /* re-enable beaconing */
  445. if (sdata->vif.type == NL80211_IFTYPE_AP ||
  446. sdata->vif.type == NL80211_IFTYPE_ADHOC ||
  447. sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
  448. ieee80211_if_config(sdata,
  449. IEEE80211_IFCC_BEACON_ENABLED);
  450. }
  451. mutex_unlock(&local->iflist_mtx);
  452. done:
  453. ieee80211_mlme_notify_scan_completed(local);
  454. ieee80211_mesh_notify_scan_completed(local);
  455. }
  456. EXPORT_SYMBOL(ieee80211_scan_completed);
  457. void ieee80211_scan_work(struct work_struct *work)
  458. {
  459. struct ieee80211_local *local =
  460. container_of(work, struct ieee80211_local, scan_work.work);
  461. struct ieee80211_sub_if_data *sdata = local->scan_sdata;
  462. struct ieee80211_channel *chan;
  463. int skip, i;
  464. unsigned long next_delay = 0;
  465. /*
  466. * Avoid re-scheduling when the sdata is going away.
  467. */
  468. if (!netif_running(sdata->dev))
  469. return;
  470. switch (local->scan_state) {
  471. case SCAN_SET_CHANNEL:
  472. /* if no more bands/channels left, complete scan */
  473. if (local->scan_channel_idx >= local->scan_req->n_channels) {
  474. ieee80211_scan_completed(local_to_hw(local), false);
  475. return;
  476. }
  477. skip = 0;
  478. chan = local->scan_req->channels[local->scan_channel_idx];
  479. if (chan->flags & IEEE80211_CHAN_DISABLED ||
  480. (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
  481. chan->flags & IEEE80211_CHAN_NO_IBSS))
  482. skip = 1;
  483. if (!skip) {
  484. local->scan_channel = chan;
  485. if (ieee80211_hw_config(local,
  486. IEEE80211_CONF_CHANGE_CHANNEL))
  487. skip = 1;
  488. }
  489. /* advance state machine to next channel/band */
  490. local->scan_channel_idx++;
  491. if (skip)
  492. break;
  493. next_delay = IEEE80211_PROBE_DELAY +
  494. usecs_to_jiffies(local->hw.channel_change_time);
  495. local->scan_state = SCAN_SEND_PROBE;
  496. break;
  497. case SCAN_SEND_PROBE:
  498. next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
  499. local->scan_state = SCAN_SET_CHANNEL;
  500. if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
  501. !local->scan_req->n_ssids)
  502. break;
  503. for (i = 0; i < local->scan_req->n_ssids; i++)
  504. ieee80211_send_probe_req(
  505. sdata, NULL,
  506. local->scan_req->ssids[i].ssid,
  507. local->scan_req->ssids[i].ssid_len);
  508. next_delay = IEEE80211_CHANNEL_TIME;
  509. break;
  510. }
  511. queue_delayed_work(local->hw.workqueue, &local->scan_work,
  512. next_delay);
  513. }
  514. int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
  515. struct cfg80211_scan_request *req)
  516. {
  517. struct ieee80211_local *local = scan_sdata->local;
  518. struct ieee80211_sub_if_data *sdata;
  519. if (!req)
  520. return -EINVAL;
  521. if (local->scan_req && local->scan_req != req)
  522. return -EBUSY;
  523. local->scan_req = req;
  524. /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
  525. * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
  526. * BSSID: MACAddress
  527. * SSID
  528. * ScanType: ACTIVE, PASSIVE
  529. * ProbeDelay: delay (in microseconds) to be used prior to transmitting
  530. * a Probe frame during active scanning
  531. * ChannelList
  532. * MinChannelTime (>= ProbeDelay), in TU
  533. * MaxChannelTime: (>= MinChannelTime), in TU
  534. */
  535. /* MLME-SCAN.confirm
  536. * BSSDescriptionSet
  537. * ResultCode: SUCCESS, INVALID_PARAMETERS
  538. */
  539. if (local->sw_scanning || local->hw_scanning) {
  540. if (local->scan_sdata == scan_sdata)
  541. return 0;
  542. return -EBUSY;
  543. }
  544. if (local->ops->hw_scan) {
  545. int rc;
  546. local->hw_scanning = true;
  547. rc = local->ops->hw_scan(local_to_hw(local), req);
  548. if (rc) {
  549. local->hw_scanning = false;
  550. return rc;
  551. }
  552. local->scan_sdata = scan_sdata;
  553. return 0;
  554. }
  555. local->sw_scanning = true;
  556. mutex_lock(&local->iflist_mtx);
  557. list_for_each_entry(sdata, &local->interfaces, list) {
  558. if (!netif_running(sdata->dev))
  559. continue;
  560. /* disable beaconing */
  561. if (sdata->vif.type == NL80211_IFTYPE_AP ||
  562. sdata->vif.type == NL80211_IFTYPE_ADHOC ||
  563. sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
  564. ieee80211_if_config(sdata,
  565. IEEE80211_IFCC_BEACON_ENABLED);
  566. if (sdata->vif.type == NL80211_IFTYPE_STATION) {
  567. if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
  568. netif_tx_stop_all_queues(sdata->dev);
  569. ieee80211_send_nullfunc(local, sdata, 1);
  570. }
  571. } else
  572. netif_tx_stop_all_queues(sdata->dev);
  573. }
  574. mutex_unlock(&local->iflist_mtx);
  575. local->scan_state = SCAN_SET_CHANNEL;
  576. local->scan_channel_idx = 0;
  577. local->scan_sdata = scan_sdata;
  578. local->scan_req = req;
  579. netif_addr_lock_bh(local->mdev);
  580. local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
  581. local->ops->configure_filter(local_to_hw(local),
  582. FIF_BCN_PRBRESP_PROMISC,
  583. &local->filter_flags,
  584. local->mdev->mc_count,
  585. local->mdev->mc_list);
  586. netif_addr_unlock_bh(local->mdev);
  587. /* TODO: start scan as soon as all nullfunc frames are ACKed */
  588. queue_delayed_work(local->hw.workqueue, &local->scan_work,
  589. IEEE80211_CHANNEL_TIME);
  590. return 0;
  591. }
  592. int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
  593. struct cfg80211_scan_request *req)
  594. {
  595. struct ieee80211_local *local = sdata->local;
  596. struct ieee80211_if_sta *ifsta;
  597. if (!req)
  598. return -EINVAL;
  599. if (local->scan_req && local->scan_req != req)
  600. return -EBUSY;
  601. local->scan_req = req;
  602. if (sdata->vif.type != NL80211_IFTYPE_STATION)
  603. return ieee80211_start_scan(sdata, req);
  604. /*
  605. * STA has a state machine that might need to defer scanning
  606. * while it's trying to associate/authenticate, therefore we
  607. * queue it up to the state machine in that case.
  608. */
  609. if (local->sw_scanning || local->hw_scanning) {
  610. if (local->scan_sdata == sdata)
  611. return 0;
  612. return -EBUSY;
  613. }
  614. ifsta = &sdata->u.sta;
  615. set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
  616. queue_work(local->hw.workqueue, &ifsta->work);
  617. return 0;
  618. }