diff options
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt_rx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 226 |
3 files changed, 135 insertions, 98 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 8edd6da3c8e7..33029767a412 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -428,9 +428,10 @@ struct ath10k { | |||
428 | struct cfg80211_chan_def chandef; | 428 | struct cfg80211_chan_def chandef; |
429 | 429 | ||
430 | int free_vdev_map; | 430 | int free_vdev_map; |
431 | bool promisc; | ||
432 | bool monitor; | ||
431 | int monitor_vdev_id; | 433 | int monitor_vdev_id; |
432 | bool monitor_enabled; | 434 | bool monitor_started; |
433 | bool monitor_present; | ||
434 | unsigned int filter_flags; | 435 | unsigned int filter_flags; |
435 | unsigned long dev_flags; | 436 | unsigned long dev_flags; |
436 | u32 dfs_block_radar_events; | 437 | u32 dfs_block_radar_events; |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index f7ecc108ef80..f85a3cf6da31 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -1120,7 +1120,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, | |||
1120 | if (status != HTT_RX_IND_MPDU_STATUS_OK && | 1120 | if (status != HTT_RX_IND_MPDU_STATUS_OK && |
1121 | status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && | 1121 | status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && |
1122 | status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER && | 1122 | status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER && |
1123 | !htt->ar->monitor_enabled) { | 1123 | !htt->ar->monitor_started) { |
1124 | ath10k_dbg(ATH10K_DBG_HTT, | 1124 | ath10k_dbg(ATH10K_DBG_HTT, |
1125 | "htt rx ignoring frame w/ status %d\n", | 1125 | "htt rx ignoring frame w/ status %d\n", |
1126 | status); | 1126 | status); |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 58ec5a7dfb34..d3607caee1da 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -574,7 +574,20 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) | |||
574 | return ret; | 574 | return ret; |
575 | } | 575 | } |
576 | 576 | ||
577 | static int ath10k_monitor_start(struct ath10k *ar, int vdev_id) | 577 | static bool ath10k_monitor_is_enabled(struct ath10k *ar) |
578 | { | ||
579 | lockdep_assert_held(&ar->conf_mutex); | ||
580 | |||
581 | ath10k_dbg(ATH10K_DBG_MAC, | ||
582 | "mac monitor refs: promisc %d monitor %d cac %d\n", | ||
583 | ar->promisc, ar->monitor, | ||
584 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)); | ||
585 | |||
586 | return ar->promisc || ar->monitor || | ||
587 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | ||
588 | } | ||
589 | |||
590 | static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) | ||
578 | { | 591 | { |
579 | struct cfg80211_chan_def *chandef = &ar->chandef; | 592 | struct cfg80211_chan_def *chandef = &ar->chandef; |
580 | struct ieee80211_channel *channel = chandef->chan; | 593 | struct ieee80211_channel *channel = chandef->chan; |
@@ -583,11 +596,6 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id) | |||
583 | 596 | ||
584 | lockdep_assert_held(&ar->conf_mutex); | 597 | lockdep_assert_held(&ar->conf_mutex); |
585 | 598 | ||
586 | if (!ar->monitor_present) { | ||
587 | ath10k_warn("mac monitor stop -- monitor is not present\n"); | ||
588 | return -EINVAL; | ||
589 | } | ||
590 | |||
591 | arg.vdev_id = vdev_id; | 599 | arg.vdev_id = vdev_id; |
592 | arg.channel.freq = channel->center_freq; | 600 | arg.channel.freq = channel->center_freq; |
593 | arg.channel.band_center_freq1 = chandef->center_freq1; | 601 | arg.channel.band_center_freq1 = chandef->center_freq1; |
@@ -605,14 +613,14 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id) | |||
605 | 613 | ||
606 | ret = ath10k_wmi_vdev_start(ar, &arg); | 614 | ret = ath10k_wmi_vdev_start(ar, &arg); |
607 | if (ret) { | 615 | if (ret) { |
608 | ath10k_warn("failed to start Monitor vdev %i: %d\n", | 616 | ath10k_warn("failed to request monitor vdev %i start: %d\n", |
609 | vdev_id, ret); | 617 | vdev_id, ret); |
610 | return ret; | 618 | return ret; |
611 | } | 619 | } |
612 | 620 | ||
613 | ret = ath10k_vdev_setup_sync(ar); | 621 | ret = ath10k_vdev_setup_sync(ar); |
614 | if (ret) { | 622 | if (ret) { |
615 | ath10k_warn("failed to syncronise setup for monitor vdev %i: %d\n", | 623 | ath10k_warn("failed to synchronize setup for monitor vdev %i: %d\n", |
616 | vdev_id, ret); | 624 | vdev_id, ret); |
617 | return ret; | 625 | return ret; |
618 | } | 626 | } |
@@ -625,8 +633,9 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id) | |||
625 | } | 633 | } |
626 | 634 | ||
627 | ar->monitor_vdev_id = vdev_id; | 635 | ar->monitor_vdev_id = vdev_id; |
628 | ar->monitor_enabled = true; | ||
629 | 636 | ||
637 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i started\n", | ||
638 | ar->monitor_vdev_id); | ||
630 | return 0; | 639 | return 0; |
631 | 640 | ||
632 | vdev_stop: | 641 | vdev_stop: |
@@ -638,22 +647,12 @@ vdev_stop: | |||
638 | return ret; | 647 | return ret; |
639 | } | 648 | } |
640 | 649 | ||
641 | static int ath10k_monitor_stop(struct ath10k *ar) | 650 | static int ath10k_monitor_vdev_stop(struct ath10k *ar) |
642 | { | 651 | { |
643 | int ret = 0; | 652 | int ret = 0; |
644 | 653 | ||
645 | lockdep_assert_held(&ar->conf_mutex); | 654 | lockdep_assert_held(&ar->conf_mutex); |
646 | 655 | ||
647 | if (!ar->monitor_present) { | ||
648 | ath10k_warn("mac monitor stop -- monitor is not present\n"); | ||
649 | return -EINVAL; | ||
650 | } | ||
651 | |||
652 | if (!ar->monitor_enabled) { | ||
653 | ath10k_warn("mac monitor stop -- monitor is not enabled\n"); | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | |||
657 | ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id); | 656 | ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id); |
658 | if (ret) | 657 | if (ret) |
659 | ath10k_warn("failed to put down monitor vdev %i: %d\n", | 658 | ath10k_warn("failed to put down monitor vdev %i: %d\n", |
@@ -661,7 +660,7 @@ static int ath10k_monitor_stop(struct ath10k *ar) | |||
661 | 660 | ||
662 | ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); | 661 | ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); |
663 | if (ret) | 662 | if (ret) |
664 | ath10k_warn("failed to stop monitor vdev %i: %d\n", | 663 | ath10k_warn("failed to to request monitor vdev %i stop: %d\n", |
665 | ar->monitor_vdev_id, ret); | 664 | ar->monitor_vdev_id, ret); |
666 | 665 | ||
667 | ret = ath10k_vdev_setup_sync(ar); | 666 | ret = ath10k_vdev_setup_sync(ar); |
@@ -669,24 +668,20 @@ static int ath10k_monitor_stop(struct ath10k *ar) | |||
669 | ath10k_warn("failed to synchronise monitor vdev %i: %d\n", | 668 | ath10k_warn("failed to synchronise monitor vdev %i: %d\n", |
670 | ar->monitor_vdev_id, ret); | 669 | ar->monitor_vdev_id, ret); |
671 | 670 | ||
672 | ar->monitor_enabled = false; | 671 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", |
672 | ar->monitor_vdev_id); | ||
673 | return ret; | 673 | return ret; |
674 | } | 674 | } |
675 | 675 | ||
676 | static int ath10k_monitor_create(struct ath10k *ar) | 676 | static int ath10k_monitor_vdev_create(struct ath10k *ar) |
677 | { | 677 | { |
678 | int bit, ret = 0; | 678 | int bit, ret = 0; |
679 | 679 | ||
680 | lockdep_assert_held(&ar->conf_mutex); | 680 | lockdep_assert_held(&ar->conf_mutex); |
681 | 681 | ||
682 | if (ar->monitor_present) { | ||
683 | ath10k_warn("monitor mode already enabled\n"); | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | bit = ffs(ar->free_vdev_map); | 682 | bit = ffs(ar->free_vdev_map); |
688 | if (bit == 0) { | 683 | if (bit == 0) { |
689 | ath10k_warn("no free vdev slots\n"); | 684 | ath10k_warn("failed to find free vdev id for monitor vdev\n"); |
690 | return -ENOMEM; | 685 | return -ENOMEM; |
691 | } | 686 | } |
692 | 687 | ||
@@ -697,7 +692,7 @@ static int ath10k_monitor_create(struct ath10k *ar) | |||
697 | WMI_VDEV_TYPE_MONITOR, | 692 | WMI_VDEV_TYPE_MONITOR, |
698 | 0, ar->mac_addr); | 693 | 0, ar->mac_addr); |
699 | if (ret) { | 694 | if (ret) { |
700 | ath10k_warn("failed to create WMI monitor vdev %i: %d\n", | 695 | ath10k_warn("failed to request monitor vdev %i creation: %d\n", |
701 | ar->monitor_vdev_id, ret); | 696 | ar->monitor_vdev_id, ret); |
702 | goto vdev_fail; | 697 | goto vdev_fail; |
703 | } | 698 | } |
@@ -705,7 +700,6 @@ static int ath10k_monitor_create(struct ath10k *ar) | |||
705 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n", | 700 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n", |
706 | ar->monitor_vdev_id); | 701 | ar->monitor_vdev_id); |
707 | 702 | ||
708 | ar->monitor_present = true; | ||
709 | return 0; | 703 | return 0; |
710 | 704 | ||
711 | vdev_fail: | 705 | vdev_fail: |
@@ -716,30 +710,91 @@ vdev_fail: | |||
716 | return ret; | 710 | return ret; |
717 | } | 711 | } |
718 | 712 | ||
719 | static int ath10k_monitor_destroy(struct ath10k *ar) | 713 | static int ath10k_monitor_vdev_delete(struct ath10k *ar) |
720 | { | 714 | { |
721 | int ret = 0; | 715 | int ret = 0; |
722 | 716 | ||
723 | lockdep_assert_held(&ar->conf_mutex); | 717 | lockdep_assert_held(&ar->conf_mutex); |
724 | 718 | ||
725 | if (!ar->monitor_present) | ||
726 | return 0; | ||
727 | |||
728 | ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id); | 719 | ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id); |
729 | if (ret) { | 720 | if (ret) { |
730 | ath10k_warn("failed to delete WMI vdev %i: %d\n", | 721 | ath10k_warn("failed to request wmi monitor vdev %i removal: %d\n", |
731 | ar->monitor_vdev_id, ret); | 722 | ar->monitor_vdev_id, ret); |
732 | return ret; | 723 | return ret; |
733 | } | 724 | } |
734 | 725 | ||
735 | ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); | 726 | ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); |
736 | ar->monitor_present = false; | ||
737 | 727 | ||
738 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", | 728 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", |
739 | ar->monitor_vdev_id); | 729 | ar->monitor_vdev_id); |
740 | return ret; | 730 | return ret; |
741 | } | 731 | } |
742 | 732 | ||
733 | static int ath10k_monitor_start(struct ath10k *ar) | ||
734 | { | ||
735 | int ret; | ||
736 | |||
737 | lockdep_assert_held(&ar->conf_mutex); | ||
738 | |||
739 | if (!ath10k_monitor_is_enabled(ar)) { | ||
740 | ath10k_warn("trying to start monitor with no references\n"); | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | if (ar->monitor_started) { | ||
745 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor already started\n"); | ||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | ret = ath10k_monitor_vdev_create(ar); | ||
750 | if (ret) { | ||
751 | ath10k_warn("failed to create monitor vdev: %d\n", ret); | ||
752 | return ret; | ||
753 | } | ||
754 | |||
755 | ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); | ||
756 | if (ret) { | ||
757 | ath10k_warn("failed to start monitor vdev: %d\n", ret); | ||
758 | ath10k_monitor_vdev_delete(ar); | ||
759 | return ret; | ||
760 | } | ||
761 | |||
762 | ar->monitor_started = true; | ||
763 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor started\n"); | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | static void ath10k_monitor_stop(struct ath10k *ar) | ||
769 | { | ||
770 | int ret; | ||
771 | |||
772 | lockdep_assert_held(&ar->conf_mutex); | ||
773 | |||
774 | if (ath10k_monitor_is_enabled(ar)) { | ||
775 | ath10k_dbg(ATH10K_DBG_MAC, | ||
776 | "mac monitor will be stopped later\n"); | ||
777 | return; | ||
778 | } | ||
779 | |||
780 | if (!ar->monitor_started) { | ||
781 | ath10k_dbg(ATH10K_DBG_MAC, | ||
782 | "mac monitor probably failed to start earlier\n"); | ||
783 | return; | ||
784 | } | ||
785 | |||
786 | ret = ath10k_monitor_vdev_stop(ar); | ||
787 | if (ret) | ||
788 | ath10k_warn("failed to stop monitor vdev: %d\n", ret); | ||
789 | |||
790 | ret = ath10k_monitor_vdev_delete(ar); | ||
791 | if (ret) | ||
792 | ath10k_warn("failed to delete monitor vdev: %d\n", ret); | ||
793 | |||
794 | ar->monitor_started = false; | ||
795 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor stopped\n"); | ||
796 | } | ||
797 | |||
743 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) | 798 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) |
744 | { | 799 | { |
745 | struct ath10k *ar = arvif->ar; | 800 | struct ath10k *ar = arvif->ar; |
@@ -768,19 +823,13 @@ static int ath10k_start_cac(struct ath10k *ar) | |||
768 | 823 | ||
769 | set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 824 | set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
770 | 825 | ||
771 | ret = ath10k_monitor_create(ar); | 826 | ret = ath10k_monitor_start(ar); |
772 | if (ret) { | 827 | if (ret) { |
828 | ath10k_warn("failed to start monitor (cac): %d\n", ret); | ||
773 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 829 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
774 | return ret; | 830 | return ret; |
775 | } | 831 | } |
776 | 832 | ||
777 | ret = ath10k_monitor_start(ar, ar->monitor_vdev_id); | ||
778 | if (ret) { | ||
779 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | ||
780 | ath10k_monitor_destroy(ar); | ||
781 | return ret; | ||
782 | } | ||
783 | |||
784 | ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n", | 833 | ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n", |
785 | ar->monitor_vdev_id); | 834 | ar->monitor_vdev_id); |
786 | 835 | ||
@@ -795,9 +844,8 @@ static int ath10k_stop_cac(struct ath10k *ar) | |||
795 | if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) | 844 | if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) |
796 | return 0; | 845 | return 0; |
797 | 846 | ||
798 | ath10k_monitor_stop(ar); | ||
799 | ath10k_monitor_destroy(ar); | ||
800 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 847 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
848 | ath10k_monitor_stop(ar); | ||
801 | 849 | ||
802 | ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n"); | 850 | ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n"); |
803 | 851 | ||
@@ -1828,7 +1876,7 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, | |||
1828 | if (info->control.vif) | 1876 | if (info->control.vif) |
1829 | return ath10k_vif_to_arvif(info->control.vif)->vdev_id; | 1877 | return ath10k_vif_to_arvif(info->control.vif)->vdev_id; |
1830 | 1878 | ||
1831 | if (ar->monitor_enabled) | 1879 | if (ar->monitor_started) |
1832 | return ar->monitor_vdev_id; | 1880 | return ar->monitor_vdev_id; |
1833 | 1881 | ||
1834 | ath10k_warn("failed to resolve vdev id\n"); | 1882 | ath10k_warn("failed to resolve vdev id\n"); |
@@ -2266,7 +2314,13 @@ void ath10k_halt(struct ath10k *ar) | |||
2266 | { | 2314 | { |
2267 | lockdep_assert_held(&ar->conf_mutex); | 2315 | lockdep_assert_held(&ar->conf_mutex); |
2268 | 2316 | ||
2269 | ath10k_stop_cac(ar); | 2317 | if (ath10k_monitor_is_enabled(ar)) { |
2318 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | ||
2319 | ar->promisc = false; | ||
2320 | ar->monitor = false; | ||
2321 | ath10k_monitor_stop(ar); | ||
2322 | } | ||
2323 | |||
2270 | del_timer_sync(&ar->scan.timeout); | 2324 | del_timer_sync(&ar->scan.timeout); |
2271 | ath10k_offchan_tx_purge(ar); | 2325 | ath10k_offchan_tx_purge(ar); |
2272 | ath10k_mgmt_over_wmi_tx_purge(ar); | 2326 | ath10k_mgmt_over_wmi_tx_purge(ar); |
@@ -2413,7 +2467,6 @@ static const char *chandef_get_width(enum nl80211_chan_width width) | |||
2413 | static void ath10k_config_chan(struct ath10k *ar) | 2467 | static void ath10k_config_chan(struct ath10k *ar) |
2414 | { | 2468 | { |
2415 | struct ath10k_vif *arvif; | 2469 | struct ath10k_vif *arvif; |
2416 | bool monitor_was_enabled; | ||
2417 | int ret; | 2470 | int ret; |
2418 | 2471 | ||
2419 | lockdep_assert_held(&ar->conf_mutex); | 2472 | lockdep_assert_held(&ar->conf_mutex); |
@@ -2427,10 +2480,8 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2427 | 2480 | ||
2428 | /* First stop monitor interface. Some FW versions crash if there's a | 2481 | /* First stop monitor interface. Some FW versions crash if there's a |
2429 | * lone monitor interface. */ | 2482 | * lone monitor interface. */ |
2430 | monitor_was_enabled = ar->monitor_enabled; | 2483 | if (ar->monitor_started) |
2431 | 2484 | ath10k_monitor_vdev_stop(ar); | |
2432 | if (ar->monitor_enabled) | ||
2433 | ath10k_monitor_stop(ar); | ||
2434 | 2485 | ||
2435 | list_for_each_entry(arvif, &ar->arvifs, list) { | 2486 | list_for_each_entry(arvif, &ar->arvifs, list) { |
2436 | if (!arvif->is_started) | 2487 | if (!arvif->is_started) |
@@ -2475,8 +2526,8 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2475 | } | 2526 | } |
2476 | } | 2527 | } |
2477 | 2528 | ||
2478 | if (monitor_was_enabled) | 2529 | if (ath10k_monitor_is_enabled(ar)) |
2479 | ath10k_monitor_start(ar, ar->monitor_vdev_id); | 2530 | ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); |
2480 | } | 2531 | } |
2481 | 2532 | ||
2482 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | 2533 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) |
@@ -2529,10 +2580,19 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
2529 | ath10k_config_ps(ar); | 2580 | ath10k_config_ps(ar); |
2530 | 2581 | ||
2531 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 2582 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
2532 | if (conf->flags & IEEE80211_CONF_MONITOR) | 2583 | if (conf->flags & IEEE80211_CONF_MONITOR && !ar->monitor) { |
2533 | ret = ath10k_monitor_create(ar); | 2584 | ar->monitor = true; |
2534 | else | 2585 | ret = ath10k_monitor_start(ar); |
2535 | ret = ath10k_monitor_destroy(ar); | 2586 | if (ret) { |
2587 | ath10k_warn("failed to start monitor (config): %d\n", | ||
2588 | ret); | ||
2589 | ar->monitor = false; | ||
2590 | } | ||
2591 | } else if (!(conf->flags & IEEE80211_CONF_MONITOR) && | ||
2592 | ar->monitor) { | ||
2593 | ar->monitor = false; | ||
2594 | ath10k_monitor_stop(ar); | ||
2595 | } | ||
2536 | } | 2596 | } |
2537 | 2597 | ||
2538 | mutex_unlock(&ar->conf_mutex); | 2598 | mutex_unlock(&ar->conf_mutex); |
@@ -2567,12 +2627,6 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2567 | INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); | 2627 | INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); |
2568 | INIT_LIST_HEAD(&arvif->list); | 2628 | INIT_LIST_HEAD(&arvif->list); |
2569 | 2629 | ||
2570 | if ((vif->type == NL80211_IFTYPE_MONITOR) && ar->monitor_present) { | ||
2571 | ath10k_warn("only one monitor interface allowed\n"); | ||
2572 | ret = -EBUSY; | ||
2573 | goto err; | ||
2574 | } | ||
2575 | |||
2576 | bit = ffs(ar->free_vdev_map); | 2630 | bit = ffs(ar->free_vdev_map); |
2577 | if (bit == 0) { | 2631 | if (bit == 0) { |
2578 | ret = -EBUSY; | 2632 | ret = -EBUSY; |
@@ -2704,9 +2758,6 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
2704 | goto err_peer_delete; | 2758 | goto err_peer_delete; |
2705 | } | 2759 | } |
2706 | 2760 | ||
2707 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) | ||
2708 | ar->monitor_present = true; | ||
2709 | |||
2710 | mutex_unlock(&ar->conf_mutex); | 2761 | mutex_unlock(&ar->conf_mutex); |
2711 | return 0; | 2762 | return 0; |
2712 | 2763 | ||
@@ -2763,9 +2814,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, | |||
2763 | ath10k_warn("failed to delete WMI vdev %i: %d\n", | 2814 | ath10k_warn("failed to delete WMI vdev %i: %d\n", |
2764 | arvif->vdev_id, ret); | 2815 | arvif->vdev_id, ret); |
2765 | 2816 | ||
2766 | if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) | ||
2767 | ar->monitor_present = false; | ||
2768 | |||
2769 | ath10k_peer_cleanup(ar, arvif->vdev_id); | 2817 | ath10k_peer_cleanup(ar, arvif->vdev_id); |
2770 | 2818 | ||
2771 | mutex_unlock(&ar->conf_mutex); | 2819 | mutex_unlock(&ar->conf_mutex); |
@@ -2798,28 +2846,17 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw, | |||
2798 | *total_flags &= SUPPORTED_FILTERS; | 2846 | *total_flags &= SUPPORTED_FILTERS; |
2799 | ar->filter_flags = *total_flags; | 2847 | ar->filter_flags = *total_flags; |
2800 | 2848 | ||
2801 | /* Monitor must not be started if it wasn't created first. | 2849 | if (ar->filter_flags & FIF_PROMISC_IN_BSS && !ar->promisc) { |
2802 | * Promiscuous mode may be started on a non-monitor interface - in | 2850 | ar->promisc = true; |
2803 | * such case the monitor vdev is not created so starting the | 2851 | ret = ath10k_monitor_start(ar); |
2804 | * monitor makes no sense. Since ath10k uses no special RX filters | 2852 | if (ret) { |
2805 | * (only BSS filter in STA mode) there's no need for any special | 2853 | ath10k_warn("failed to start monitor (promisc): %d\n", |
2806 | * action here. */ | 2854 | ret); |
2807 | if ((ar->filter_flags & FIF_PROMISC_IN_BSS) && | 2855 | ar->promisc = false; |
2808 | !ar->monitor_enabled && ar->monitor_present) { | 2856 | } |
2809 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d start\n", | 2857 | } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && ar->promisc) { |
2810 | ar->monitor_vdev_id); | 2858 | ar->promisc = false; |
2811 | 2859 | ath10k_monitor_stop(ar); | |
2812 | ret = ath10k_monitor_start(ar, ar->monitor_vdev_id); | ||
2813 | if (ret) | ||
2814 | ath10k_warn("failed to start monitor mode: %d\n", ret); | ||
2815 | } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && | ||
2816 | ar->monitor_enabled && ar->monitor_present) { | ||
2817 | ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d stop\n", | ||
2818 | ar->monitor_vdev_id); | ||
2819 | |||
2820 | ret = ath10k_monitor_stop(ar); | ||
2821 | if (ret) | ||
2822 | ath10k_warn("failed to stop monitor mode: %d\n", ret); | ||
2823 | } | 2860 | } |
2824 | 2861 | ||
2825 | mutex_unlock(&ar->conf_mutex); | 2862 | mutex_unlock(&ar->conf_mutex); |
@@ -4579,7 +4616,6 @@ int ath10k_mac_register(struct ath10k *ar) | |||
4579 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 4616 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
4580 | IEEE80211_HW_HAS_RATE_CONTROL | | 4617 | IEEE80211_HW_HAS_RATE_CONTROL | |
4581 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | | 4618 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | |
4582 | IEEE80211_HW_WANT_MONITOR_VIF | | ||
4583 | IEEE80211_HW_AP_LINK_PS | | 4619 | IEEE80211_HW_AP_LINK_PS | |
4584 | IEEE80211_HW_SPECTRUM_MGMT; | 4620 | IEEE80211_HW_SPECTRUM_MGMT; |
4585 | 4621 | ||