aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-04-08 02:45:47 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2014-04-08 02:55:30 -0400
commit1bbc09752d3fdbfc2f768da60f7c67f128e5bc1f (patch)
tree2afcf02b7d860f53fb9c0efbbb41a9944734c3e8 /drivers/net/wireless/ath/ath10k
parent7a8a396be406aa51124e8baae827406ae3bc59ed (diff)
ath10k: refactor monitor code
It was possible to create/delete/start/stop monitor vdev from a few places that were not exclusively protected against each other. This resulted in monitor vdev being stopped/removed by one call origin while another one was expecting it to continue running. For example if CAC was started and interface's promiscuous mode was toggled monitor vdev was removed from the driver meaning no radar would be detected. In additional a warning would be printed upon CAC completion complaining it tried to stop non-running monitor vdev. The patch simplifies monitor code by removing IEEE80211_HW_WANT_MONITOR_VIF (which wasn't really ever needed) and improves state tracking. It also unifies prints. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k')
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h5
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c226
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
577static int ath10k_monitor_start(struct ath10k *ar, int vdev_id) 577static 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
590static 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
632vdev_stop: 641vdev_stop:
@@ -638,22 +647,12 @@ vdev_stop:
638 return ret; 647 return ret;
639} 648}
640 649
641static int ath10k_monitor_stop(struct ath10k *ar) 650static 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
676static int ath10k_monitor_create(struct ath10k *ar) 676static 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
711vdev_fail: 705vdev_fail:
@@ -716,30 +710,91 @@ vdev_fail:
716 return ret; 710 return ret;
717} 711}
718 712
719static int ath10k_monitor_destroy(struct ath10k *ar) 713static 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
733static 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
768static 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
743static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) 798static 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)
2413static void ath10k_config_chan(struct ath10k *ar) 2467static 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
2482static int ath10k_config(struct ieee80211_hw *hw, u32 changed) 2533static 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