aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-scan.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-09-13 08:46:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-09-14 16:08:03 -0400
commit3eecce527c7434dfd16517ce08b49632c8a26717 (patch)
tree7495b3970b2f34d40dc0adbfc8a5a8627a515851 /drivers/net/wireless/iwlwifi/iwl-scan.c
parentb5be3efc34294cc34e305903df6a388950e8d1f3 (diff)
iwlwifi: unify scan start checks
Rather than duplicating all the checks and even in case of errors accepting the scan request from mac80211, we can push the checks to the caller and in all error cases reject the scan request right away (rather than accepting and then saying it was aborted). Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c127
1 files changed, 74 insertions, 53 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 7727f0966d31..6bd14bc33478 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -324,19 +324,68 @@ void iwl_init_scan_params(struct iwl_priv *priv)
324} 324}
325EXPORT_SYMBOL(iwl_init_scan_params); 325EXPORT_SYMBOL(iwl_init_scan_params);
326 326
327static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif) 327static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
328 struct ieee80211_vif *vif,
329 bool internal,
330 enum nl80211_band band)
328{ 331{
332 int ret;
333
329 lockdep_assert_held(&priv->mutex); 334 lockdep_assert_held(&priv->mutex);
330 335
331 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 336 if (WARN_ON(!priv->cfg->ops->utils->request_scan))
337 return -EOPNOTSUPP;
338
339 cancel_delayed_work(&priv->scan_check);
340
341 if (!iwl_is_ready(priv)) {
342 IWL_WARN(priv, "request scan called when driver not ready.\n");
343 return -EIO;
344 }
345
346 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
347 IWL_DEBUG_INFO(priv,
348 "Multiple concurrent scan requests in parallel.\n");
349 return -EBUSY;
350 }
351
352 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
353 IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
354 return -EIO;
355 }
356
357 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
358 IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
359 return -EBUSY;
360 }
361
362 if (iwl_is_rfkill(priv)) {
363 IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
364 return -EIO;
365 }
366
367 if (!test_bit(STATUS_READY, &priv->status)) {
368 IWL_DEBUG_HC(priv, "Scan request while uninitialized.\n");
369 return -EBUSY;
370 }
371
372 IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
373 internal ? "internal short " : "");
374
332 set_bit(STATUS_SCANNING, &priv->status); 375 set_bit(STATUS_SCANNING, &priv->status);
333 priv->is_internal_short_scan = false; 376 priv->is_internal_short_scan = internal;
334 priv->scan_start = jiffies; 377 priv->scan_start = jiffies;
378 priv->scan_band = band;
335 379
336 if (WARN_ON(!priv->cfg->ops->utils->request_scan)) 380 ret = priv->cfg->ops->utils->request_scan(priv, vif);
337 return -EOPNOTSUPP; 381 if (ret) {
382 clear_bit(STATUS_SCANNING, &priv->status);
383 priv->is_internal_short_scan = false;
384 return ret;
385 }
338 386
339 priv->cfg->ops->utils->request_scan(priv, vif); 387 queue_delayed_work(priv->workqueue, &priv->scan_check,
388 IWL_SCAN_CHECK_WATCHDOG);
340 389
341 return 0; 390 return 0;
342} 391}
@@ -355,12 +404,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
355 404
356 mutex_lock(&priv->mutex); 405 mutex_lock(&priv->mutex);
357 406
358 if (!iwl_is_ready_rf(priv)) {
359 ret = -EIO;
360 IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
361 goto out_unlock;
362 }
363
364 if (test_bit(STATUS_SCANNING, &priv->status) && 407 if (test_bit(STATUS_SCANNING, &priv->status) &&
365 !priv->is_internal_short_scan) { 408 !priv->is_internal_short_scan) {
366 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); 409 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
@@ -368,14 +411,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
368 goto out_unlock; 411 goto out_unlock;
369 } 412 }
370 413
371 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
372 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
373 ret = -EAGAIN;
374 goto out_unlock;
375 }
376
377 /* mac80211 will only ask for one band at a time */ 414 /* mac80211 will only ask for one band at a time */
378 priv->scan_band = req->channels[0]->band;
379 priv->scan_request = req; 415 priv->scan_request = req;
380 priv->scan_vif = vif; 416 priv->scan_vif = vif;
381 417
@@ -386,7 +422,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
386 if (priv->is_internal_short_scan) 422 if (priv->is_internal_short_scan)
387 ret = 0; 423 ret = 0;
388 else 424 else
389 ret = iwl_scan_initiate(priv, vif); 425 ret = iwl_scan_initiate(priv, vif, false,
426 req->channels[0]->band);
390 427
391 IWL_DEBUG_MAC80211(priv, "leave\n"); 428 IWL_DEBUG_MAC80211(priv, "leave\n");
392 429
@@ -418,31 +455,13 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
418 goto unlock; 455 goto unlock;
419 } 456 }
420 457
421 if (!iwl_is_ready_rf(priv)) {
422 IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
423 goto unlock;
424 }
425
426 if (test_bit(STATUS_SCANNING, &priv->status)) { 458 if (test_bit(STATUS_SCANNING, &priv->status)) {
427 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); 459 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
428 goto unlock; 460 goto unlock;
429 } 461 }
430 462
431 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { 463 if (iwl_scan_initiate(priv, NULL, true, priv->band))
432 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); 464 IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
433 goto unlock;
434 }
435
436 priv->scan_band = priv->band;
437
438 IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
439 set_bit(STATUS_SCANNING, &priv->status);
440 priv->is_internal_short_scan = true;
441
442 if (WARN_ON(!priv->cfg->ops->utils->request_scan))
443 goto unlock;
444
445 priv->cfg->ops->utils->request_scan(priv, NULL);
446 unlock: 465 unlock:
447 mutex_unlock(&priv->mutex); 466 mutex_unlock(&priv->mutex);
448} 467}
@@ -536,7 +555,6 @@ static void iwl_bg_scan_completed(struct work_struct *work)
536 struct iwl_priv *priv = 555 struct iwl_priv *priv =
537 container_of(work, struct iwl_priv, scan_completed); 556 container_of(work, struct iwl_priv, scan_completed);
538 bool internal = false; 557 bool internal = false;
539 bool scan_completed = false;
540 struct iwl_rxon_context *ctx; 558 struct iwl_rxon_context *ctx;
541 559
542 IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); 560 IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
@@ -549,16 +567,27 @@ static void iwl_bg_scan_completed(struct work_struct *work)
549 IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); 567 IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
550 internal = true; 568 internal = true;
551 } else if (priv->scan_request) { 569 } else if (priv->scan_request) {
552 scan_completed = true;
553 priv->scan_request = NULL; 570 priv->scan_request = NULL;
554 priv->scan_vif = NULL; 571 priv->scan_vif = NULL;
572 ieee80211_scan_completed(priv->hw, false);
555 } 573 }
556 574
557 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 575 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
558 goto out; 576 goto out;
559 577
560 if (internal && priv->scan_request) 578 if (internal && priv->scan_request) {
561 iwl_scan_initiate(priv, priv->scan_vif); 579 int err = iwl_scan_initiate(priv, priv->scan_vif, false,
580 priv->scan_request->channels[0]->band);
581
582 if (err) {
583 IWL_DEBUG_SCAN(priv,
584 "failed to initiate pending scan: %d\n", err);
585 priv->scan_request = NULL;
586 priv->scan_vif = NULL;
587 ieee80211_scan_completed(priv->hw, true);
588 } else
589 goto out;
590 }
562 591
563 /* Since setting the TXPOWER may have been deferred while 592 /* Since setting the TXPOWER may have been deferred while
564 * performing the scan, fire one off */ 593 * performing the scan, fire one off */
@@ -571,19 +600,11 @@ static void iwl_bg_scan_completed(struct work_struct *work)
571 for_each_context(priv, ctx) 600 for_each_context(priv, ctx)
572 iwlcore_commit_rxon(priv, ctx); 601 iwlcore_commit_rxon(priv, ctx);
573 602
574 out:
575 if (priv->cfg->ops->hcmd->set_pan_params) 603 if (priv->cfg->ops->hcmd->set_pan_params)
576 priv->cfg->ops->hcmd->set_pan_params(priv); 604 priv->cfg->ops->hcmd->set_pan_params(priv);
577 605
606 out:
578 mutex_unlock(&priv->mutex); 607 mutex_unlock(&priv->mutex);
579
580 /*
581 * Do not hold mutex here since this will cause mac80211 to call
582 * into driver again into functions that will attempt to take
583 * mutex.
584 */
585 if (scan_completed)
586 ieee80211_scan_completed(priv->hw, false);
587} 608}
588 609
589void iwl_setup_scan_deferred_work(struct iwl_priv *priv) 610void iwl_setup_scan_deferred_work(struct iwl_priv *priv)