diff options
Diffstat (limited to 'net/mac80211/scan.c')
| -rw-r--r-- | net/mac80211/scan.c | 136 |
1 files changed, 78 insertions, 58 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 74820656dc89..71500f1dddbc 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -474,13 +474,87 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
| 474 | return rc; | 474 | return rc; |
| 475 | } | 475 | } |
| 476 | 476 | ||
| 477 | static int ieee80211_scan_state_set_channel(struct ieee80211_local *local, | ||
| 478 | unsigned long *next_delay) | ||
| 479 | { | ||
| 480 | int skip; | ||
| 481 | struct ieee80211_channel *chan; | ||
| 482 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | ||
| 483 | |||
| 484 | /* if no more bands/channels left, complete scan */ | ||
| 485 | if (local->scan_channel_idx >= local->scan_req->n_channels) { | ||
| 486 | ieee80211_scan_completed(&local->hw, false); | ||
| 487 | return 1; | ||
| 488 | } | ||
| 489 | skip = 0; | ||
| 490 | chan = local->scan_req->channels[local->scan_channel_idx]; | ||
| 491 | |||
| 492 | if (chan->flags & IEEE80211_CHAN_DISABLED || | ||
| 493 | (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
| 494 | chan->flags & IEEE80211_CHAN_NO_IBSS)) | ||
| 495 | skip = 1; | ||
| 496 | |||
| 497 | if (!skip) { | ||
| 498 | local->scan_channel = chan; | ||
| 499 | if (ieee80211_hw_config(local, | ||
| 500 | IEEE80211_CONF_CHANGE_CHANNEL)) | ||
| 501 | skip = 1; | ||
| 502 | } | ||
| 503 | |||
| 504 | /* advance state machine to next channel/band */ | ||
| 505 | local->scan_channel_idx++; | ||
| 506 | |||
| 507 | if (skip) | ||
| 508 | return 0; | ||
| 509 | |||
| 510 | /* | ||
| 511 | * Probe delay is used to update the NAV, cf. 11.1.3.2.2 | ||
| 512 | * (which unfortunately doesn't say _why_ step a) is done, | ||
| 513 | * but it waits for the probe delay or until a frame is | ||
| 514 | * received - and the received frame would update the NAV). | ||
| 515 | * For now, we do not support waiting until a frame is | ||
| 516 | * received. | ||
| 517 | * | ||
| 518 | * In any case, it is not necessary for a passive scan. | ||
| 519 | */ | ||
| 520 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || | ||
| 521 | !local->scan_req->n_ssids) { | ||
| 522 | *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | ||
| 523 | return 0; | ||
| 524 | } | ||
| 525 | |||
| 526 | *next_delay = IEEE80211_PROBE_DELAY; | ||
| 527 | local->scan_state = SCAN_SEND_PROBE; | ||
| 528 | |||
| 529 | return 0; | ||
| 530 | } | ||
| 531 | |||
| 532 | static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | ||
| 533 | unsigned long *next_delay) | ||
| 534 | { | ||
| 535 | int i; | ||
| 536 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | ||
| 537 | |||
| 538 | for (i = 0; i < local->scan_req->n_ssids; i++) | ||
| 539 | ieee80211_send_probe_req( | ||
| 540 | sdata, NULL, | ||
| 541 | local->scan_req->ssids[i].ssid, | ||
| 542 | local->scan_req->ssids[i].ssid_len, | ||
| 543 | local->scan_req->ie, local->scan_req->ie_len); | ||
| 544 | |||
| 545 | /* | ||
| 546 | * After sending probe requests, wait for probe responses | ||
| 547 | * on the channel. | ||
| 548 | */ | ||
| 549 | *next_delay = IEEE80211_CHANNEL_TIME; | ||
| 550 | local->scan_state = SCAN_SET_CHANNEL; | ||
| 551 | } | ||
| 552 | |||
| 477 | void ieee80211_scan_work(struct work_struct *work) | 553 | void ieee80211_scan_work(struct work_struct *work) |
| 478 | { | 554 | { |
| 479 | struct ieee80211_local *local = | 555 | struct ieee80211_local *local = |
| 480 | container_of(work, struct ieee80211_local, scan_work.work); | 556 | container_of(work, struct ieee80211_local, scan_work.work); |
| 481 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 557 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; |
| 482 | struct ieee80211_channel *chan; | ||
| 483 | int skip, i; | ||
| 484 | unsigned long next_delay = 0; | 558 | unsigned long next_delay = 0; |
| 485 | 559 | ||
| 486 | mutex_lock(&local->scan_mtx); | 560 | mutex_lock(&local->scan_mtx); |
| @@ -515,65 +589,11 @@ void ieee80211_scan_work(struct work_struct *work) | |||
| 515 | 589 | ||
| 516 | switch (local->scan_state) { | 590 | switch (local->scan_state) { |
| 517 | case SCAN_SET_CHANNEL: | 591 | case SCAN_SET_CHANNEL: |
| 518 | /* if no more bands/channels left, complete scan */ | 592 | if (ieee80211_scan_state_set_channel(local, &next_delay)) |
| 519 | if (local->scan_channel_idx >= local->scan_req->n_channels) { | ||
| 520 | ieee80211_scan_completed(&local->hw, false); | ||
| 521 | return; | 593 | return; |
| 522 | } | ||
| 523 | skip = 0; | ||
| 524 | chan = local->scan_req->channels[local->scan_channel_idx]; | ||
| 525 | |||
| 526 | if (chan->flags & IEEE80211_CHAN_DISABLED || | ||
| 527 | (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
| 528 | chan->flags & IEEE80211_CHAN_NO_IBSS)) | ||
| 529 | skip = 1; | ||
| 530 | |||
| 531 | if (!skip) { | ||
| 532 | local->scan_channel = chan; | ||
| 533 | if (ieee80211_hw_config(local, | ||
| 534 | IEEE80211_CONF_CHANGE_CHANNEL)) | ||
| 535 | skip = 1; | ||
| 536 | } | ||
| 537 | |||
| 538 | /* advance state machine to next channel/band */ | ||
| 539 | local->scan_channel_idx++; | ||
| 540 | |||
| 541 | if (skip) | ||
| 542 | break; | ||
| 543 | |||
| 544 | /* | ||
| 545 | * Probe delay is used to update the NAV, cf. 11.1.3.2.2 | ||
| 546 | * (which unfortunately doesn't say _why_ step a) is done, | ||
| 547 | * but it waits for the probe delay or until a frame is | ||
| 548 | * received - and the received frame would update the NAV). | ||
| 549 | * For now, we do not support waiting until a frame is | ||
| 550 | * received. | ||
| 551 | * | ||
| 552 | * In any case, it is not necessary for a passive scan. | ||
| 553 | */ | ||
| 554 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || | ||
| 555 | !local->scan_req->n_ssids) { | ||
| 556 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | ||
| 557 | break; | ||
| 558 | } | ||
| 559 | |||
| 560 | next_delay = IEEE80211_PROBE_DELAY; | ||
| 561 | local->scan_state = SCAN_SEND_PROBE; | ||
| 562 | break; | 594 | break; |
| 563 | case SCAN_SEND_PROBE: | 595 | case SCAN_SEND_PROBE: |
| 564 | for (i = 0; i < local->scan_req->n_ssids; i++) | 596 | ieee80211_scan_state_send_probe(local, &next_delay); |
| 565 | ieee80211_send_probe_req( | ||
| 566 | sdata, NULL, | ||
| 567 | local->scan_req->ssids[i].ssid, | ||
| 568 | local->scan_req->ssids[i].ssid_len, | ||
| 569 | local->scan_req->ie, local->scan_req->ie_len); | ||
| 570 | |||
| 571 | /* | ||
| 572 | * After sending probe requests, wait for probe responses | ||
| 573 | * on the channel. | ||
| 574 | */ | ||
| 575 | next_delay = IEEE80211_CHANNEL_TIME; | ||
| 576 | local->scan_state = SCAN_SET_CHANNEL; | ||
| 577 | break; | 597 | break; |
| 578 | } | 598 | } |
| 579 | 599 | ||
