diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2014-08-28 06:58:16 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2014-09-02 03:28:36 -0400 |
commit | 1933747f5c29d38936cb53f35b4d8070f1cbefe2 (patch) | |
tree | 39b67d321cb4556a4a3acd6108b55a2557b3e100 | |
parent | 2139627172429baee9d62696c6923ce5dc7052bc (diff) |
ath10k: fix monitor start/stop sequences
Fix some cases where monitor start failure left
the driver in a confused state.
This also makes the monitor code simpler.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 121 |
2 files changed, 49 insertions, 73 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 4ef476099225..797741d762be 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -472,7 +472,6 @@ struct ath10k { | |||
472 | struct cfg80211_chan_def chandef; | 472 | struct cfg80211_chan_def chandef; |
473 | 473 | ||
474 | int free_vdev_map; | 474 | int free_vdev_map; |
475 | bool promisc; | ||
476 | bool monitor; | 475 | bool monitor; |
477 | int monitor_vdev_id; | 476 | int monitor_vdev_id; |
478 | bool monitor_started; | 477 | bool monitor_started; |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 4e30e577b3ed..8d793f31bbd8 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -493,19 +493,6 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) | |||
493 | return 0; | 493 | return 0; |
494 | } | 494 | } |
495 | 495 | ||
496 | static bool ath10k_monitor_is_enabled(struct ath10k *ar) | ||
497 | { | ||
498 | lockdep_assert_held(&ar->conf_mutex); | ||
499 | |||
500 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
501 | "mac monitor refs: promisc %d monitor %d cac %d\n", | ||
502 | ar->promisc, ar->monitor, | ||
503 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)); | ||
504 | |||
505 | return ar->promisc || ar->monitor || | ||
506 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | ||
507 | } | ||
508 | |||
509 | static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) | 496 | static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) |
510 | { | 497 | { |
511 | struct cfg80211_chan_def *chandef = &ar->chandef; | 498 | struct cfg80211_chan_def *chandef = &ar->chandef; |
@@ -649,16 +636,6 @@ static int ath10k_monitor_start(struct ath10k *ar) | |||
649 | 636 | ||
650 | lockdep_assert_held(&ar->conf_mutex); | 637 | lockdep_assert_held(&ar->conf_mutex); |
651 | 638 | ||
652 | if (!ath10k_monitor_is_enabled(ar)) { | ||
653 | ath10k_warn(ar, "trying to start monitor with no references\n"); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | if (ar->monitor_started) { | ||
658 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor already started\n"); | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | ret = ath10k_monitor_vdev_create(ar); | 639 | ret = ath10k_monitor_vdev_create(ar); |
663 | if (ret) { | 640 | if (ret) { |
664 | ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret); | 641 | ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret); |
@@ -678,34 +655,51 @@ static int ath10k_monitor_start(struct ath10k *ar) | |||
678 | return 0; | 655 | return 0; |
679 | } | 656 | } |
680 | 657 | ||
681 | static void ath10k_monitor_stop(struct ath10k *ar) | 658 | static int ath10k_monitor_stop(struct ath10k *ar) |
682 | { | 659 | { |
683 | int ret; | 660 | int ret; |
684 | 661 | ||
685 | lockdep_assert_held(&ar->conf_mutex); | 662 | lockdep_assert_held(&ar->conf_mutex); |
686 | 663 | ||
687 | if (ath10k_monitor_is_enabled(ar)) { | ||
688 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
689 | "mac monitor will be stopped later\n"); | ||
690 | return; | ||
691 | } | ||
692 | |||
693 | if (!ar->monitor_started) { | ||
694 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
695 | "mac monitor probably failed to start earlier\n"); | ||
696 | return; | ||
697 | } | ||
698 | |||
699 | ret = ath10k_monitor_vdev_stop(ar); | 664 | ret = ath10k_monitor_vdev_stop(ar); |
700 | if (ret) | 665 | if (ret) { |
701 | ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret); | 666 | ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret); |
667 | return ret; | ||
668 | } | ||
702 | 669 | ||
703 | ret = ath10k_monitor_vdev_delete(ar); | 670 | ret = ath10k_monitor_vdev_delete(ar); |
704 | if (ret) | 671 | if (ret) { |
705 | ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret); | 672 | ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret); |
673 | return ret; | ||
674 | } | ||
706 | 675 | ||
707 | ar->monitor_started = false; | 676 | ar->monitor_started = false; |
708 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n"); | 677 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n"); |
678 | |||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | static int ath10k_monitor_recalc(struct ath10k *ar) | ||
683 | { | ||
684 | bool should_start; | ||
685 | |||
686 | lockdep_assert_held(&ar->conf_mutex); | ||
687 | |||
688 | should_start = ar->monitor || | ||
689 | ar->filter_flags & FIF_PROMISC_IN_BSS || | ||
690 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | ||
691 | |||
692 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
693 | "mac monitor recalc started? %d should? %d\n", | ||
694 | ar->monitor_started, should_start); | ||
695 | |||
696 | if (should_start == ar->monitor_started) | ||
697 | return 0; | ||
698 | |||
699 | if (should_start) | ||
700 | return ath10k_monitor_start(ar); | ||
701 | else | ||
702 | return ath10k_monitor_stop(ar); | ||
709 | } | 703 | } |
710 | 704 | ||
711 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) | 705 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) |
@@ -736,7 +730,7 @@ static int ath10k_start_cac(struct ath10k *ar) | |||
736 | 730 | ||
737 | set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 731 | set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
738 | 732 | ||
739 | ret = ath10k_monitor_start(ar); | 733 | ret = ath10k_monitor_recalc(ar); |
740 | if (ret) { | 734 | if (ret) { |
741 | ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret); | 735 | ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret); |
742 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 736 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
@@ -2369,12 +2363,14 @@ void ath10k_halt(struct ath10k *ar) | |||
2369 | 2363 | ||
2370 | lockdep_assert_held(&ar->conf_mutex); | 2364 | lockdep_assert_held(&ar->conf_mutex); |
2371 | 2365 | ||
2372 | if (ath10k_monitor_is_enabled(ar)) { | 2366 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
2373 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 2367 | ar->filter_flags = 0; |
2374 | ar->promisc = false; | 2368 | ar->monitor = false; |
2375 | ar->monitor = false; | 2369 | |
2370 | if (ar->monitor_started) | ||
2376 | ath10k_monitor_stop(ar); | 2371 | ath10k_monitor_stop(ar); |
2377 | } | 2372 | |
2373 | ar->monitor_started = false; | ||
2378 | 2374 | ||
2379 | ath10k_scan_finish(ar); | 2375 | ath10k_scan_finish(ar); |
2380 | ath10k_peer_cleanup_all(ar); | 2376 | ath10k_peer_cleanup_all(ar); |
@@ -2629,7 +2625,7 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2629 | /* First stop monitor interface. Some FW versions crash if there's a | 2625 | /* First stop monitor interface. Some FW versions crash if there's a |
2630 | * lone monitor interface. */ | 2626 | * lone monitor interface. */ |
2631 | if (ar->monitor_started) | 2627 | if (ar->monitor_started) |
2632 | ath10k_monitor_vdev_stop(ar); | 2628 | ath10k_monitor_stop(ar); |
2633 | 2629 | ||
2634 | list_for_each_entry(arvif, &ar->arvifs, list) { | 2630 | list_for_each_entry(arvif, &ar->arvifs, list) { |
2635 | if (!arvif->is_started) | 2631 | if (!arvif->is_started) |
@@ -2677,8 +2673,7 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2677 | } | 2673 | } |
2678 | } | 2674 | } |
2679 | 2675 | ||
2680 | if (ath10k_monitor_is_enabled(ar)) | 2676 | ath10k_monitor_recalc(ar); |
2681 | ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); | ||
2682 | } | 2677 | } |
2683 | 2678 | ||
2684 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | 2679 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) |
@@ -2733,19 +2728,10 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
2733 | ath10k_config_ps(ar); | 2728 | ath10k_config_ps(ar); |
2734 | 2729 | ||
2735 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 2730 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
2736 | if (conf->flags & IEEE80211_CONF_MONITOR && !ar->monitor) { | 2731 | ar->monitor = conf->flags & IEEE80211_CONF_MONITOR; |
2737 | ar->monitor = true; | 2732 | ret = ath10k_monitor_recalc(ar); |
2738 | ret = ath10k_monitor_start(ar); | 2733 | if (ret) |
2739 | if (ret) { | 2734 | ath10k_warn(ar, "failed to recalc monitor: %d\n", ret); |
2740 | ath10k_warn(ar, "failed to start monitor (config): %d\n", | ||
2741 | ret); | ||
2742 | ar->monitor = false; | ||
2743 | } | ||
2744 | } else if (!(conf->flags & IEEE80211_CONF_MONITOR) && | ||
2745 | ar->monitor) { | ||
2746 | ar->monitor = false; | ||
2747 | ath10k_monitor_stop(ar); | ||
2748 | } | ||
2749 | } | 2735 | } |
2750 | 2736 | ||
2751 | mutex_unlock(&ar->conf_mutex); | 2737 | mutex_unlock(&ar->conf_mutex); |
@@ -3009,18 +2995,9 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw, | |||
3009 | *total_flags &= SUPPORTED_FILTERS; | 2995 | *total_flags &= SUPPORTED_FILTERS; |
3010 | ar->filter_flags = *total_flags; | 2996 | ar->filter_flags = *total_flags; |
3011 | 2997 | ||
3012 | if (ar->filter_flags & FIF_PROMISC_IN_BSS && !ar->promisc) { | 2998 | ret = ath10k_monitor_recalc(ar); |
3013 | ar->promisc = true; | 2999 | if (ret) |
3014 | ret = ath10k_monitor_start(ar); | 3000 | ath10k_warn(ar, "failed to recalc montior: %d\n", ret); |
3015 | if (ret) { | ||
3016 | ath10k_warn(ar, "failed to start monitor (promisc): %d\n", | ||
3017 | ret); | ||
3018 | ar->promisc = false; | ||
3019 | } | ||
3020 | } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && ar->promisc) { | ||
3021 | ar->promisc = false; | ||
3022 | ath10k_monitor_stop(ar); | ||
3023 | } | ||
3024 | 3001 | ||
3025 | mutex_unlock(&ar->conf_mutex); | 3002 | mutex_unlock(&ar->conf_mutex); |
3026 | } | 3003 | } |