diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-05-30 13:43:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-30 13:43:31 -0400 |
commit | 8f1e5d31cf92b037506d5222fc713f27b5d46718 (patch) | |
tree | 2532bcbfeb4bb146cde3a90427067a0529d32447 | |
parent | 57afc62e9422954329adecdb8251cc232e9fe308 (diff) | |
parent | 08b8aa0931830cc4b96b47f884fe623aef5c4b84 (diff) |
Merge branch 'for-linville' of git://github.com/kvalo/ath
-rw-r--r-- | drivers/net/wireless/ath/ath10k/bmi.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/ce.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/ce.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.c | 277 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htc.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt_rx.c | 92 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt_tx.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 212 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/pci.c | 103 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 9 |
15 files changed, 534 insertions, 305 deletions
diff --git a/drivers/net/wireless/ath/ath10k/bmi.h b/drivers/net/wireless/ath/ath10k/bmi.h index 3a9bdf51c96a..111ab701465c 100644 --- a/drivers/net/wireless/ath/ath10k/bmi.h +++ b/drivers/net/wireless/ath/ath10k/bmi.h | |||
@@ -201,7 +201,8 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address, | |||
201 | \ | 201 | \ |
202 | addr = host_interest_item_address(HI_ITEM(item)); \ | 202 | addr = host_interest_item_address(HI_ITEM(item)); \ |
203 | ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \ | 203 | ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \ |
204 | *val = __le32_to_cpu(tmp); \ | 204 | if (!ret) \ |
205 | *val = __le32_to_cpu(tmp); \ | ||
205 | ret; \ | 206 | ret; \ |
206 | }) | 207 | }) |
207 | 208 | ||
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 1e4cad8632b5..d185dc0cd12b 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c | |||
@@ -329,6 +329,33 @@ exit: | |||
329 | return ret; | 329 | return ret; |
330 | } | 330 | } |
331 | 331 | ||
332 | void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe) | ||
333 | { | ||
334 | struct ath10k *ar = pipe->ar; | ||
335 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
336 | struct ath10k_ce_ring *src_ring = pipe->src_ring; | ||
337 | u32 ctrl_addr = pipe->ctrl_addr; | ||
338 | |||
339 | lockdep_assert_held(&ar_pci->ce_lock); | ||
340 | |||
341 | /* | ||
342 | * This function must be called only if there is an incomplete | ||
343 | * scatter-gather transfer (before index register is updated) | ||
344 | * that needs to be cleaned up. | ||
345 | */ | ||
346 | if (WARN_ON_ONCE(src_ring->write_index == src_ring->sw_index)) | ||
347 | return; | ||
348 | |||
349 | if (WARN_ON_ONCE(src_ring->write_index == | ||
350 | ath10k_ce_src_ring_write_index_get(ar, ctrl_addr))) | ||
351 | return; | ||
352 | |||
353 | src_ring->write_index--; | ||
354 | src_ring->write_index &= src_ring->nentries_mask; | ||
355 | |||
356 | src_ring->per_transfer_context[src_ring->write_index] = NULL; | ||
357 | } | ||
358 | |||
332 | int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, | 359 | int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, |
333 | void *per_transfer_context, | 360 | void *per_transfer_context, |
334 | u32 buffer, | 361 | u32 buffer, |
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index fd0bc3561e42..7a5a36fc59c1 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h | |||
@@ -160,6 +160,8 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, | |||
160 | unsigned int transfer_id, | 160 | unsigned int transfer_id, |
161 | unsigned int flags); | 161 | unsigned int flags); |
162 | 162 | ||
163 | void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe); | ||
164 | |||
163 | void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, | 165 | void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, |
164 | void (*send_cb)(struct ath10k_ce_pipe *), | 166 | void (*send_cb)(struct ath10k_ce_pipe *), |
165 | int disable_interrupts); | 167 | int disable_interrupts); |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 75b3dfbd6509..82017f56e661 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -58,36 +58,6 @@ static void ath10k_send_suspend_complete(struct ath10k *ar) | |||
58 | complete(&ar->target_suspend); | 58 | complete(&ar->target_suspend); |
59 | } | 59 | } |
60 | 60 | ||
61 | static int ath10k_init_connect_htc(struct ath10k *ar) | ||
62 | { | ||
63 | int status; | ||
64 | |||
65 | status = ath10k_wmi_connect_htc_service(ar); | ||
66 | if (status) | ||
67 | goto conn_fail; | ||
68 | |||
69 | /* Start HTC */ | ||
70 | status = ath10k_htc_start(&ar->htc); | ||
71 | if (status) | ||
72 | goto conn_fail; | ||
73 | |||
74 | /* Wait for WMI event to be ready */ | ||
75 | status = ath10k_wmi_wait_for_service_ready(ar); | ||
76 | if (status <= 0) { | ||
77 | ath10k_warn("wmi service ready event not received"); | ||
78 | status = -ETIMEDOUT; | ||
79 | goto timeout; | ||
80 | } | ||
81 | |||
82 | ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n"); | ||
83 | return 0; | ||
84 | |||
85 | timeout: | ||
86 | ath10k_htc_stop(&ar->htc); | ||
87 | conn_fail: | ||
88 | return status; | ||
89 | } | ||
90 | |||
91 | static int ath10k_init_configure_target(struct ath10k *ar) | 61 | static int ath10k_init_configure_target(struct ath10k *ar) |
92 | { | 62 | { |
93 | u32 param_host; | 63 | u32 param_host; |
@@ -681,7 +651,8 @@ static void ath10k_core_restart(struct work_struct *work) | |||
681 | switch (ar->state) { | 651 | switch (ar->state) { |
682 | case ATH10K_STATE_ON: | 652 | case ATH10K_STATE_ON: |
683 | ar->state = ATH10K_STATE_RESTARTING; | 653 | ar->state = ATH10K_STATE_RESTARTING; |
684 | ath10k_halt(ar); | 654 | del_timer_sync(&ar->scan.timeout); |
655 | ath10k_reset_scan((unsigned long)ar); | ||
685 | ieee80211_restart_hw(ar->hw); | 656 | ieee80211_restart_hw(ar->hw); |
686 | break; | 657 | break; |
687 | case ATH10K_STATE_OFF: | 658 | case ATH10K_STATE_OFF: |
@@ -690,6 +661,8 @@ static void ath10k_core_restart(struct work_struct *work) | |||
690 | ath10k_warn("cannot restart a device that hasn't been started\n"); | 661 | ath10k_warn("cannot restart a device that hasn't been started\n"); |
691 | break; | 662 | break; |
692 | case ATH10K_STATE_RESTARTING: | 663 | case ATH10K_STATE_RESTARTING: |
664 | /* hw restart might be requested from multiple places */ | ||
665 | break; | ||
693 | case ATH10K_STATE_RESTARTED: | 666 | case ATH10K_STATE_RESTARTED: |
694 | ar->state = ATH10K_STATE_WEDGED; | 667 | ar->state = ATH10K_STATE_WEDGED; |
695 | /* fall through */ | 668 | /* fall through */ |
@@ -701,70 +674,6 @@ static void ath10k_core_restart(struct work_struct *work) | |||
701 | mutex_unlock(&ar->conf_mutex); | 674 | mutex_unlock(&ar->conf_mutex); |
702 | } | 675 | } |
703 | 676 | ||
704 | struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | ||
705 | const struct ath10k_hif_ops *hif_ops) | ||
706 | { | ||
707 | struct ath10k *ar; | ||
708 | |||
709 | ar = ath10k_mac_create(); | ||
710 | if (!ar) | ||
711 | return NULL; | ||
712 | |||
713 | ar->ath_common.priv = ar; | ||
714 | ar->ath_common.hw = ar->hw; | ||
715 | |||
716 | ar->p2p = !!ath10k_p2p; | ||
717 | ar->dev = dev; | ||
718 | |||
719 | ar->hif.priv = hif_priv; | ||
720 | ar->hif.ops = hif_ops; | ||
721 | |||
722 | init_completion(&ar->scan.started); | ||
723 | init_completion(&ar->scan.completed); | ||
724 | init_completion(&ar->scan.on_channel); | ||
725 | init_completion(&ar->target_suspend); | ||
726 | |||
727 | init_completion(&ar->install_key_done); | ||
728 | init_completion(&ar->vdev_setup_done); | ||
729 | |||
730 | setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); | ||
731 | |||
732 | ar->workqueue = create_singlethread_workqueue("ath10k_wq"); | ||
733 | if (!ar->workqueue) | ||
734 | goto err_wq; | ||
735 | |||
736 | mutex_init(&ar->conf_mutex); | ||
737 | spin_lock_init(&ar->data_lock); | ||
738 | |||
739 | INIT_LIST_HEAD(&ar->peers); | ||
740 | init_waitqueue_head(&ar->peer_mapping_wq); | ||
741 | |||
742 | init_completion(&ar->offchan_tx_completed); | ||
743 | INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); | ||
744 | skb_queue_head_init(&ar->offchan_tx_queue); | ||
745 | |||
746 | INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); | ||
747 | skb_queue_head_init(&ar->wmi_mgmt_tx_queue); | ||
748 | |||
749 | INIT_WORK(&ar->restart_work, ath10k_core_restart); | ||
750 | |||
751 | return ar; | ||
752 | |||
753 | err_wq: | ||
754 | ath10k_mac_destroy(ar); | ||
755 | return NULL; | ||
756 | } | ||
757 | EXPORT_SYMBOL(ath10k_core_create); | ||
758 | |||
759 | void ath10k_core_destroy(struct ath10k *ar) | ||
760 | { | ||
761 | flush_workqueue(ar->workqueue); | ||
762 | destroy_workqueue(ar->workqueue); | ||
763 | |||
764 | ath10k_mac_destroy(ar); | ||
765 | } | ||
766 | EXPORT_SYMBOL(ath10k_core_destroy); | ||
767 | |||
768 | int ath10k_core_start(struct ath10k *ar) | 677 | int ath10k_core_start(struct ath10k *ar) |
769 | { | 678 | { |
770 | int status; | 679 | int status; |
@@ -805,10 +714,28 @@ int ath10k_core_start(struct ath10k *ar) | |||
805 | goto err; | 714 | goto err; |
806 | } | 715 | } |
807 | 716 | ||
717 | status = ath10k_htt_init(ar); | ||
718 | if (status) { | ||
719 | ath10k_err("failed to init htt: %d\n", status); | ||
720 | goto err_wmi_detach; | ||
721 | } | ||
722 | |||
723 | status = ath10k_htt_tx_alloc(&ar->htt); | ||
724 | if (status) { | ||
725 | ath10k_err("failed to alloc htt tx: %d\n", status); | ||
726 | goto err_wmi_detach; | ||
727 | } | ||
728 | |||
729 | status = ath10k_htt_rx_alloc(&ar->htt); | ||
730 | if (status) { | ||
731 | ath10k_err("failed to alloc htt rx: %d\n", status); | ||
732 | goto err_htt_tx_detach; | ||
733 | } | ||
734 | |||
808 | status = ath10k_hif_start(ar); | 735 | status = ath10k_hif_start(ar); |
809 | if (status) { | 736 | if (status) { |
810 | ath10k_err("could not start HIF: %d\n", status); | 737 | ath10k_err("could not start HIF: %d\n", status); |
811 | goto err_wmi_detach; | 738 | goto err_htt_rx_detach; |
812 | } | 739 | } |
813 | 740 | ||
814 | status = ath10k_htc_wait_target(&ar->htc); | 741 | status = ath10k_htc_wait_target(&ar->htc); |
@@ -817,15 +744,30 @@ int ath10k_core_start(struct ath10k *ar) | |||
817 | goto err_hif_stop; | 744 | goto err_hif_stop; |
818 | } | 745 | } |
819 | 746 | ||
820 | status = ath10k_htt_attach(ar); | 747 | status = ath10k_htt_connect(&ar->htt); |
821 | if (status) { | 748 | if (status) { |
822 | ath10k_err("could not attach htt (%d)\n", status); | 749 | ath10k_err("failed to connect htt (%d)\n", status); |
823 | goto err_hif_stop; | 750 | goto err_hif_stop; |
824 | } | 751 | } |
825 | 752 | ||
826 | status = ath10k_init_connect_htc(ar); | 753 | status = ath10k_wmi_connect(ar); |
827 | if (status) | 754 | if (status) { |
828 | goto err_htt_detach; | 755 | ath10k_err("could not connect wmi: %d\n", status); |
756 | goto err_hif_stop; | ||
757 | } | ||
758 | |||
759 | status = ath10k_htc_start(&ar->htc); | ||
760 | if (status) { | ||
761 | ath10k_err("failed to start htc: %d\n", status); | ||
762 | goto err_hif_stop; | ||
763 | } | ||
764 | |||
765 | status = ath10k_wmi_wait_for_service_ready(ar); | ||
766 | if (status <= 0) { | ||
767 | ath10k_warn("wmi service ready event not received"); | ||
768 | status = -ETIMEDOUT; | ||
769 | goto err_htc_stop; | ||
770 | } | ||
829 | 771 | ||
830 | ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n", | 772 | ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n", |
831 | ar->hw->wiphy->fw_version); | 773 | ar->hw->wiphy->fw_version); |
@@ -833,23 +775,25 @@ int ath10k_core_start(struct ath10k *ar) | |||
833 | status = ath10k_wmi_cmd_init(ar); | 775 | status = ath10k_wmi_cmd_init(ar); |
834 | if (status) { | 776 | if (status) { |
835 | ath10k_err("could not send WMI init command (%d)\n", status); | 777 | ath10k_err("could not send WMI init command (%d)\n", status); |
836 | goto err_disconnect_htc; | 778 | goto err_htc_stop; |
837 | } | 779 | } |
838 | 780 | ||
839 | status = ath10k_wmi_wait_for_unified_ready(ar); | 781 | status = ath10k_wmi_wait_for_unified_ready(ar); |
840 | if (status <= 0) { | 782 | if (status <= 0) { |
841 | ath10k_err("wmi unified ready event not received\n"); | 783 | ath10k_err("wmi unified ready event not received\n"); |
842 | status = -ETIMEDOUT; | 784 | status = -ETIMEDOUT; |
843 | goto err_disconnect_htc; | 785 | goto err_htc_stop; |
844 | } | 786 | } |
845 | 787 | ||
846 | status = ath10k_htt_attach_target(&ar->htt); | 788 | status = ath10k_htt_setup(&ar->htt); |
847 | if (status) | 789 | if (status) { |
848 | goto err_disconnect_htc; | 790 | ath10k_err("failed to setup htt: %d\n", status); |
791 | goto err_htc_stop; | ||
792 | } | ||
849 | 793 | ||
850 | status = ath10k_debug_start(ar); | 794 | status = ath10k_debug_start(ar); |
851 | if (status) | 795 | if (status) |
852 | goto err_disconnect_htc; | 796 | goto err_htc_stop; |
853 | 797 | ||
854 | ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; | 798 | ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; |
855 | INIT_LIST_HEAD(&ar->arvifs); | 799 | INIT_LIST_HEAD(&ar->arvifs); |
@@ -868,12 +812,14 @@ int ath10k_core_start(struct ath10k *ar) | |||
868 | 812 | ||
869 | return 0; | 813 | return 0; |
870 | 814 | ||
871 | err_disconnect_htc: | 815 | err_htc_stop: |
872 | ath10k_htc_stop(&ar->htc); | 816 | ath10k_htc_stop(&ar->htc); |
873 | err_htt_detach: | ||
874 | ath10k_htt_detach(&ar->htt); | ||
875 | err_hif_stop: | 817 | err_hif_stop: |
876 | ath10k_hif_stop(ar); | 818 | ath10k_hif_stop(ar); |
819 | err_htt_rx_detach: | ||
820 | ath10k_htt_rx_free(&ar->htt); | ||
821 | err_htt_tx_detach: | ||
822 | ath10k_htt_tx_free(&ar->htt); | ||
877 | err_wmi_detach: | 823 | err_wmi_detach: |
878 | ath10k_wmi_detach(ar); | 824 | ath10k_wmi_detach(ar); |
879 | err: | 825 | err: |
@@ -913,7 +859,9 @@ void ath10k_core_stop(struct ath10k *ar) | |||
913 | 859 | ||
914 | ath10k_debug_stop(ar); | 860 | ath10k_debug_stop(ar); |
915 | ath10k_htc_stop(&ar->htc); | 861 | ath10k_htc_stop(&ar->htc); |
916 | ath10k_htt_detach(&ar->htt); | 862 | ath10k_hif_stop(ar); |
863 | ath10k_htt_tx_free(&ar->htt); | ||
864 | ath10k_htt_rx_free(&ar->htt); | ||
917 | ath10k_wmi_detach(ar); | 865 | ath10k_wmi_detach(ar); |
918 | } | 866 | } |
919 | EXPORT_SYMBOL(ath10k_core_stop); | 867 | EXPORT_SYMBOL(ath10k_core_stop); |
@@ -1005,22 +953,15 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) | |||
1005 | return 0; | 953 | return 0; |
1006 | } | 954 | } |
1007 | 955 | ||
1008 | int ath10k_core_register(struct ath10k *ar, u32 chip_id) | 956 | static void ath10k_core_register_work(struct work_struct *work) |
1009 | { | 957 | { |
958 | struct ath10k *ar = container_of(work, struct ath10k, register_work); | ||
1010 | int status; | 959 | int status; |
1011 | 960 | ||
1012 | ar->chip_id = chip_id; | ||
1013 | |||
1014 | status = ath10k_core_check_chip_id(ar); | ||
1015 | if (status) { | ||
1016 | ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); | ||
1017 | return status; | ||
1018 | } | ||
1019 | |||
1020 | status = ath10k_core_probe_fw(ar); | 961 | status = ath10k_core_probe_fw(ar); |
1021 | if (status) { | 962 | if (status) { |
1022 | ath10k_err("could not probe fw (%d)\n", status); | 963 | ath10k_err("could not probe fw (%d)\n", status); |
1023 | return status; | 964 | goto err; |
1024 | } | 965 | } |
1025 | 966 | ||
1026 | status = ath10k_mac_register(ar); | 967 | status = ath10k_mac_register(ar); |
@@ -1035,18 +976,43 @@ int ath10k_core_register(struct ath10k *ar, u32 chip_id) | |||
1035 | goto err_unregister_mac; | 976 | goto err_unregister_mac; |
1036 | } | 977 | } |
1037 | 978 | ||
1038 | return 0; | 979 | set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); |
980 | return; | ||
1039 | 981 | ||
1040 | err_unregister_mac: | 982 | err_unregister_mac: |
1041 | ath10k_mac_unregister(ar); | 983 | ath10k_mac_unregister(ar); |
1042 | err_release_fw: | 984 | err_release_fw: |
1043 | ath10k_core_free_firmware_files(ar); | 985 | ath10k_core_free_firmware_files(ar); |
1044 | return status; | 986 | err: |
987 | device_release_driver(ar->dev); | ||
988 | return; | ||
989 | } | ||
990 | |||
991 | int ath10k_core_register(struct ath10k *ar, u32 chip_id) | ||
992 | { | ||
993 | int status; | ||
994 | |||
995 | ar->chip_id = chip_id; | ||
996 | |||
997 | status = ath10k_core_check_chip_id(ar); | ||
998 | if (status) { | ||
999 | ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); | ||
1000 | return status; | ||
1001 | } | ||
1002 | |||
1003 | queue_work(ar->workqueue, &ar->register_work); | ||
1004 | |||
1005 | return 0; | ||
1045 | } | 1006 | } |
1046 | EXPORT_SYMBOL(ath10k_core_register); | 1007 | EXPORT_SYMBOL(ath10k_core_register); |
1047 | 1008 | ||
1048 | void ath10k_core_unregister(struct ath10k *ar) | 1009 | void ath10k_core_unregister(struct ath10k *ar) |
1049 | { | 1010 | { |
1011 | cancel_work_sync(&ar->register_work); | ||
1012 | |||
1013 | if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) | ||
1014 | return; | ||
1015 | |||
1050 | /* We must unregister from mac80211 before we stop HTC and HIF. | 1016 | /* We must unregister from mac80211 before we stop HTC and HIF. |
1051 | * Otherwise we will fail to submit commands to FW and mac80211 will be | 1017 | * Otherwise we will fail to submit commands to FW and mac80211 will be |
1052 | * unhappy about callback failures. */ | 1018 | * unhappy about callback failures. */ |
@@ -1058,6 +1024,71 @@ void ath10k_core_unregister(struct ath10k *ar) | |||
1058 | } | 1024 | } |
1059 | EXPORT_SYMBOL(ath10k_core_unregister); | 1025 | EXPORT_SYMBOL(ath10k_core_unregister); |
1060 | 1026 | ||
1027 | struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, | ||
1028 | const struct ath10k_hif_ops *hif_ops) | ||
1029 | { | ||
1030 | struct ath10k *ar; | ||
1031 | |||
1032 | ar = ath10k_mac_create(); | ||
1033 | if (!ar) | ||
1034 | return NULL; | ||
1035 | |||
1036 | ar->ath_common.priv = ar; | ||
1037 | ar->ath_common.hw = ar->hw; | ||
1038 | |||
1039 | ar->p2p = !!ath10k_p2p; | ||
1040 | ar->dev = dev; | ||
1041 | |||
1042 | ar->hif.priv = hif_priv; | ||
1043 | ar->hif.ops = hif_ops; | ||
1044 | |||
1045 | init_completion(&ar->scan.started); | ||
1046 | init_completion(&ar->scan.completed); | ||
1047 | init_completion(&ar->scan.on_channel); | ||
1048 | init_completion(&ar->target_suspend); | ||
1049 | |||
1050 | init_completion(&ar->install_key_done); | ||
1051 | init_completion(&ar->vdev_setup_done); | ||
1052 | |||
1053 | setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); | ||
1054 | |||
1055 | ar->workqueue = create_singlethread_workqueue("ath10k_wq"); | ||
1056 | if (!ar->workqueue) | ||
1057 | goto err_wq; | ||
1058 | |||
1059 | mutex_init(&ar->conf_mutex); | ||
1060 | spin_lock_init(&ar->data_lock); | ||
1061 | |||
1062 | INIT_LIST_HEAD(&ar->peers); | ||
1063 | init_waitqueue_head(&ar->peer_mapping_wq); | ||
1064 | |||
1065 | init_completion(&ar->offchan_tx_completed); | ||
1066 | INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); | ||
1067 | skb_queue_head_init(&ar->offchan_tx_queue); | ||
1068 | |||
1069 | INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); | ||
1070 | skb_queue_head_init(&ar->wmi_mgmt_tx_queue); | ||
1071 | |||
1072 | INIT_WORK(&ar->register_work, ath10k_core_register_work); | ||
1073 | INIT_WORK(&ar->restart_work, ath10k_core_restart); | ||
1074 | |||
1075 | return ar; | ||
1076 | |||
1077 | err_wq: | ||
1078 | ath10k_mac_destroy(ar); | ||
1079 | return NULL; | ||
1080 | } | ||
1081 | EXPORT_SYMBOL(ath10k_core_create); | ||
1082 | |||
1083 | void ath10k_core_destroy(struct ath10k *ar) | ||
1084 | { | ||
1085 | flush_workqueue(ar->workqueue); | ||
1086 | destroy_workqueue(ar->workqueue); | ||
1087 | |||
1088 | ath10k_mac_destroy(ar); | ||
1089 | } | ||
1090 | EXPORT_SYMBOL(ath10k_core_destroy); | ||
1091 | |||
1061 | MODULE_AUTHOR("Qualcomm Atheros"); | 1092 | MODULE_AUTHOR("Qualcomm Atheros"); |
1062 | MODULE_DESCRIPTION("Core module for QCA988X PCIe devices."); | 1093 | MODULE_DESCRIPTION("Core module for QCA988X PCIe devices."); |
1063 | MODULE_LICENSE("Dual BSD/GPL"); | 1094 | MODULE_LICENSE("Dual BSD/GPL"); |
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 2c1dfd719146..68ceef61933d 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -335,6 +335,7 @@ enum ath10k_dev_flags { | |||
335 | /* Indicates that ath10k device is during CAC phase of DFS */ | 335 | /* Indicates that ath10k device is during CAC phase of DFS */ |
336 | ATH10K_CAC_RUNNING, | 336 | ATH10K_CAC_RUNNING, |
337 | ATH10K_FLAG_FIRST_BOOT_DONE, | 337 | ATH10K_FLAG_FIRST_BOOT_DONE, |
338 | ATH10K_FLAG_CORE_REGISTERED, | ||
338 | }; | 339 | }; |
339 | 340 | ||
340 | struct ath10k { | 341 | struct ath10k { |
@@ -440,6 +441,12 @@ struct ath10k { | |||
440 | bool radar_enabled; | 441 | bool radar_enabled; |
441 | int num_started_vdevs; | 442 | int num_started_vdevs; |
442 | 443 | ||
444 | /* Protected by conf-mutex */ | ||
445 | u8 supp_tx_chainmask; | ||
446 | u8 supp_rx_chainmask; | ||
447 | u8 cfg_tx_chainmask; | ||
448 | u8 cfg_rx_chainmask; | ||
449 | |||
443 | struct wmi_pdev_set_wmm_params_arg wmm_params; | 450 | struct wmi_pdev_set_wmm_params_arg wmm_params; |
444 | struct completion install_key_done; | 451 | struct completion install_key_done; |
445 | 452 | ||
@@ -470,6 +477,7 @@ struct ath10k { | |||
470 | 477 | ||
471 | enum ath10k_state state; | 478 | enum ath10k_state state; |
472 | 479 | ||
480 | struct work_struct register_work; | ||
473 | struct work_struct restart_work; | 481 | struct work_struct restart_work; |
474 | 482 | ||
475 | /* cycle count is reported twice for each visited channel during scan. | 483 | /* cycle count is reported twice for each visited channel during scan. |
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c index 5b58dbb17416..e493db4b4a41 100644 --- a/drivers/net/wireless/ath/ath10k/htc.c +++ b/drivers/net/wireless/ath/ath10k/htc.c | |||
@@ -830,17 +830,11 @@ int ath10k_htc_start(struct ath10k_htc *htc) | |||
830 | return 0; | 830 | return 0; |
831 | } | 831 | } |
832 | 832 | ||
833 | /* | ||
834 | * stop HTC communications, i.e. stop interrupt reception, and flush all | ||
835 | * queued buffers | ||
836 | */ | ||
837 | void ath10k_htc_stop(struct ath10k_htc *htc) | 833 | void ath10k_htc_stop(struct ath10k_htc *htc) |
838 | { | 834 | { |
839 | spin_lock_bh(&htc->tx_lock); | 835 | spin_lock_bh(&htc->tx_lock); |
840 | htc->stopped = true; | 836 | htc->stopped = true; |
841 | spin_unlock_bh(&htc->tx_lock); | 837 | spin_unlock_bh(&htc->tx_lock); |
842 | |||
843 | ath10k_hif_stop(htc->ar); | ||
844 | } | 838 | } |
845 | 839 | ||
846 | /* registered target arrival callback from the HIF layer */ | 840 | /* registered target arrival callback from the HIF layer */ |
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 69697af59ce0..19c12cc8d663 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "core.h" | 22 | #include "core.h" |
23 | #include "debug.h" | 23 | #include "debug.h" |
24 | 24 | ||
25 | static int ath10k_htt_htc_attach(struct ath10k_htt *htt) | 25 | int ath10k_htt_connect(struct ath10k_htt *htt) |
26 | { | 26 | { |
27 | struct ath10k_htc_svc_conn_req conn_req; | 27 | struct ath10k_htc_svc_conn_req conn_req; |
28 | struct ath10k_htc_svc_conn_resp conn_resp; | 28 | struct ath10k_htc_svc_conn_resp conn_resp; |
@@ -48,39 +48,14 @@ static int ath10k_htt_htc_attach(struct ath10k_htt *htt) | |||
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
50 | 50 | ||
51 | int ath10k_htt_attach(struct ath10k *ar) | 51 | int ath10k_htt_init(struct ath10k *ar) |
52 | { | 52 | { |
53 | struct ath10k_htt *htt = &ar->htt; | 53 | struct ath10k_htt *htt = &ar->htt; |
54 | int ret; | ||
55 | 54 | ||
56 | htt->ar = ar; | 55 | htt->ar = ar; |
57 | htt->max_throughput_mbps = 800; | 56 | htt->max_throughput_mbps = 800; |
58 | 57 | ||
59 | /* | 58 | /* |
60 | * Connect to HTC service. | ||
61 | * This has to be done before calling ath10k_htt_rx_attach, | ||
62 | * since ath10k_htt_rx_attach involves sending a rx ring configure | ||
63 | * message to the target. | ||
64 | */ | ||
65 | ret = ath10k_htt_htc_attach(htt); | ||
66 | if (ret) { | ||
67 | ath10k_err("could not attach htt htc (%d)\n", ret); | ||
68 | goto err_htc_attach; | ||
69 | } | ||
70 | |||
71 | ret = ath10k_htt_tx_attach(htt); | ||
72 | if (ret) { | ||
73 | ath10k_err("could not attach htt tx (%d)\n", ret); | ||
74 | goto err_htc_attach; | ||
75 | } | ||
76 | |||
77 | ret = ath10k_htt_rx_attach(htt); | ||
78 | if (ret) { | ||
79 | ath10k_err("could not attach htt rx (%d)\n", ret); | ||
80 | goto err_rx_attach; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Prefetch enough data to satisfy target | 59 | * Prefetch enough data to satisfy target |
85 | * classification engine. | 60 | * classification engine. |
86 | * This is for LL chips. HL chips will probably | 61 | * This is for LL chips. HL chips will probably |
@@ -93,11 +68,6 @@ int ath10k_htt_attach(struct ath10k *ar) | |||
93 | 2; /* ip4 dscp or ip6 priority */ | 68 | 2; /* ip4 dscp or ip6 priority */ |
94 | 69 | ||
95 | return 0; | 70 | return 0; |
96 | |||
97 | err_rx_attach: | ||
98 | ath10k_htt_tx_detach(htt); | ||
99 | err_htc_attach: | ||
100 | return ret; | ||
101 | } | 71 | } |
102 | 72 | ||
103 | #define HTT_TARGET_VERSION_TIMEOUT_HZ (3*HZ) | 73 | #define HTT_TARGET_VERSION_TIMEOUT_HZ (3*HZ) |
@@ -117,7 +87,7 @@ static int ath10k_htt_verify_version(struct ath10k_htt *htt) | |||
117 | return 0; | 87 | return 0; |
118 | } | 88 | } |
119 | 89 | ||
120 | int ath10k_htt_attach_target(struct ath10k_htt *htt) | 90 | int ath10k_htt_setup(struct ath10k_htt *htt) |
121 | { | 91 | { |
122 | int status; | 92 | int status; |
123 | 93 | ||
@@ -140,9 +110,3 @@ int ath10k_htt_attach_target(struct ath10k_htt *htt) | |||
140 | 110 | ||
141 | return ath10k_htt_send_rx_ring_cfg_ll(htt); | 111 | return ath10k_htt_send_rx_ring_cfg_ll(htt); |
142 | } | 112 | } |
143 | |||
144 | void ath10k_htt_detach(struct ath10k_htt *htt) | ||
145 | { | ||
146 | ath10k_htt_rx_detach(htt); | ||
147 | ath10k_htt_tx_detach(htt); | ||
148 | } | ||
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 645a563e3fb9..9a263462c793 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h | |||
@@ -1328,14 +1328,16 @@ struct htt_rx_desc { | |||
1328 | #define HTT_LOG2_MAX_CACHE_LINE_SIZE 7 /* 2^7 = 128 */ | 1328 | #define HTT_LOG2_MAX_CACHE_LINE_SIZE 7 /* 2^7 = 128 */ |
1329 | #define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1) | 1329 | #define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1) |
1330 | 1330 | ||
1331 | int ath10k_htt_attach(struct ath10k *ar); | 1331 | int ath10k_htt_connect(struct ath10k_htt *htt); |
1332 | int ath10k_htt_attach_target(struct ath10k_htt *htt); | 1332 | int ath10k_htt_init(struct ath10k *ar); |
1333 | void ath10k_htt_detach(struct ath10k_htt *htt); | 1333 | int ath10k_htt_setup(struct ath10k_htt *htt); |
1334 | 1334 | ||
1335 | int ath10k_htt_tx_attach(struct ath10k_htt *htt); | 1335 | int ath10k_htt_tx_alloc(struct ath10k_htt *htt); |
1336 | void ath10k_htt_tx_detach(struct ath10k_htt *htt); | 1336 | void ath10k_htt_tx_free(struct ath10k_htt *htt); |
1337 | int ath10k_htt_rx_attach(struct ath10k_htt *htt); | 1337 | |
1338 | void ath10k_htt_rx_detach(struct ath10k_htt *htt); | 1338 | int ath10k_htt_rx_alloc(struct ath10k_htt *htt); |
1339 | void ath10k_htt_rx_free(struct ath10k_htt *htt); | ||
1340 | |||
1339 | void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb); | 1341 | void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb); |
1340 | void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); | 1342 | void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); |
1341 | int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); | 1343 | int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index f85a3cf6da31..6c102b1312ff 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -225,10 +225,26 @@ static void ath10k_htt_rx_ring_refill_retry(unsigned long arg) | |||
225 | ath10k_htt_rx_msdu_buff_replenish(htt); | 225 | ath10k_htt_rx_msdu_buff_replenish(htt); |
226 | } | 226 | } |
227 | 227 | ||
228 | void ath10k_htt_rx_detach(struct ath10k_htt *htt) | 228 | static void ath10k_htt_rx_ring_clean_up(struct ath10k_htt *htt) |
229 | { | 229 | { |
230 | int sw_rd_idx = htt->rx_ring.sw_rd_idx.msdu_payld; | 230 | struct sk_buff *skb; |
231 | int i; | ||
232 | |||
233 | for (i = 0; i < htt->rx_ring.size; i++) { | ||
234 | skb = htt->rx_ring.netbufs_ring[i]; | ||
235 | if (!skb) | ||
236 | continue; | ||
237 | |||
238 | dma_unmap_single(htt->ar->dev, ATH10K_SKB_CB(skb)->paddr, | ||
239 | skb->len + skb_tailroom(skb), | ||
240 | DMA_FROM_DEVICE); | ||
241 | dev_kfree_skb_any(skb); | ||
242 | htt->rx_ring.netbufs_ring[i] = NULL; | ||
243 | } | ||
244 | } | ||
231 | 245 | ||
246 | void ath10k_htt_rx_free(struct ath10k_htt *htt) | ||
247 | { | ||
232 | del_timer_sync(&htt->rx_ring.refill_retry_timer); | 248 | del_timer_sync(&htt->rx_ring.refill_retry_timer); |
233 | tasklet_kill(&htt->rx_replenish_task); | 249 | tasklet_kill(&htt->rx_replenish_task); |
234 | tasklet_kill(&htt->txrx_compl_task); | 250 | tasklet_kill(&htt->txrx_compl_task); |
@@ -236,18 +252,7 @@ void ath10k_htt_rx_detach(struct ath10k_htt *htt) | |||
236 | skb_queue_purge(&htt->tx_compl_q); | 252 | skb_queue_purge(&htt->tx_compl_q); |
237 | skb_queue_purge(&htt->rx_compl_q); | 253 | skb_queue_purge(&htt->rx_compl_q); |
238 | 254 | ||
239 | while (sw_rd_idx != __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr))) { | 255 | ath10k_htt_rx_ring_clean_up(htt); |
240 | struct sk_buff *skb = | ||
241 | htt->rx_ring.netbufs_ring[sw_rd_idx]; | ||
242 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); | ||
243 | |||
244 | dma_unmap_single(htt->ar->dev, cb->paddr, | ||
245 | skb->len + skb_tailroom(skb), | ||
246 | DMA_FROM_DEVICE); | ||
247 | dev_kfree_skb_any(htt->rx_ring.netbufs_ring[sw_rd_idx]); | ||
248 | sw_rd_idx++; | ||
249 | sw_rd_idx &= htt->rx_ring.size_mask; | ||
250 | } | ||
251 | 256 | ||
252 | dma_free_coherent(htt->ar->dev, | 257 | dma_free_coherent(htt->ar->dev, |
253 | (htt->rx_ring.size * | 258 | (htt->rx_ring.size * |
@@ -277,6 +282,7 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) | |||
277 | 282 | ||
278 | idx = htt->rx_ring.sw_rd_idx.msdu_payld; | 283 | idx = htt->rx_ring.sw_rd_idx.msdu_payld; |
279 | msdu = htt->rx_ring.netbufs_ring[idx]; | 284 | msdu = htt->rx_ring.netbufs_ring[idx]; |
285 | htt->rx_ring.netbufs_ring[idx] = NULL; | ||
280 | 286 | ||
281 | idx++; | 287 | idx++; |
282 | idx &= htt->rx_ring.size_mask; | 288 | idx &= htt->rx_ring.size_mask; |
@@ -306,6 +312,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
306 | int msdu_len, msdu_chaining = 0; | 312 | int msdu_len, msdu_chaining = 0; |
307 | struct sk_buff *msdu; | 313 | struct sk_buff *msdu; |
308 | struct htt_rx_desc *rx_desc; | 314 | struct htt_rx_desc *rx_desc; |
315 | bool corrupted = false; | ||
309 | 316 | ||
310 | lockdep_assert_held(&htt->rx_ring.lock); | 317 | lockdep_assert_held(&htt->rx_ring.lock); |
311 | 318 | ||
@@ -399,7 +406,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
399 | msdu_len = MS(__le32_to_cpu(rx_desc->msdu_start.info0), | 406 | msdu_len = MS(__le32_to_cpu(rx_desc->msdu_start.info0), |
400 | RX_MSDU_START_INFO0_MSDU_LENGTH); | 407 | RX_MSDU_START_INFO0_MSDU_LENGTH); |
401 | msdu_chained = rx_desc->frag_info.ring2_more_count; | 408 | msdu_chained = rx_desc->frag_info.ring2_more_count; |
402 | msdu_chaining = msdu_chained; | ||
403 | 409 | ||
404 | if (msdu_len_invalid) | 410 | if (msdu_len_invalid) |
405 | msdu_len = 0; | 411 | msdu_len = 0; |
@@ -427,11 +433,15 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
427 | 433 | ||
428 | msdu->next = next; | 434 | msdu->next = next; |
429 | msdu = next; | 435 | msdu = next; |
436 | msdu_chaining = 1; | ||
430 | } | 437 | } |
431 | 438 | ||
432 | last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & | 439 | last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & |
433 | RX_MSDU_END_INFO0_LAST_MSDU; | 440 | RX_MSDU_END_INFO0_LAST_MSDU; |
434 | 441 | ||
442 | if (msdu_chaining && !last_msdu) | ||
443 | corrupted = true; | ||
444 | |||
435 | if (last_msdu) { | 445 | if (last_msdu) { |
436 | msdu->next = NULL; | 446 | msdu->next = NULL; |
437 | break; | 447 | break; |
@@ -447,6 +457,20 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
447 | msdu_chaining = -1; | 457 | msdu_chaining = -1; |
448 | 458 | ||
449 | /* | 459 | /* |
460 | * Apparently FW sometimes reports weird chained MSDU sequences with | ||
461 | * more than one rx descriptor. This seems like a bug but needs more | ||
462 | * analyzing. For the time being fix it by dropping such sequences to | ||
463 | * avoid blowing up the host system. | ||
464 | */ | ||
465 | if (corrupted) { | ||
466 | ath10k_warn("failed to pop chained msdus, dropping\n"); | ||
467 | ath10k_htt_rx_free_msdu_chain(*head_msdu); | ||
468 | *head_msdu = NULL; | ||
469 | *tail_msdu = NULL; | ||
470 | msdu_chaining = -EINVAL; | ||
471 | } | ||
472 | |||
473 | /* | ||
450 | * Don't refill the ring yet. | 474 | * Don't refill the ring yet. |
451 | * | 475 | * |
452 | * First, the elements popped here are still in use - it is not | 476 | * First, the elements popped here are still in use - it is not |
@@ -468,7 +492,7 @@ static void ath10k_htt_rx_replenish_task(unsigned long ptr) | |||
468 | ath10k_htt_rx_msdu_buff_replenish(htt); | 492 | ath10k_htt_rx_msdu_buff_replenish(htt); |
469 | } | 493 | } |
470 | 494 | ||
471 | int ath10k_htt_rx_attach(struct ath10k_htt *htt) | 495 | int ath10k_htt_rx_alloc(struct ath10k_htt *htt) |
472 | { | 496 | { |
473 | dma_addr_t paddr; | 497 | dma_addr_t paddr; |
474 | void *vaddr; | 498 | void *vaddr; |
@@ -494,7 +518,7 @@ int ath10k_htt_rx_attach(struct ath10k_htt *htt) | |||
494 | htt->rx_ring.fill_level = ath10k_htt_rx_ring_fill_level(htt); | 518 | htt->rx_ring.fill_level = ath10k_htt_rx_ring_fill_level(htt); |
495 | 519 | ||
496 | htt->rx_ring.netbufs_ring = | 520 | htt->rx_ring.netbufs_ring = |
497 | kmalloc(htt->rx_ring.size * sizeof(struct sk_buff *), | 521 | kzalloc(htt->rx_ring.size * sizeof(struct sk_buff *), |
498 | GFP_KERNEL); | 522 | GFP_KERNEL); |
499 | if (!htt->rx_ring.netbufs_ring) | 523 | if (!htt->rx_ring.netbufs_ring) |
500 | goto err_netbuf; | 524 | goto err_netbuf; |
@@ -754,17 +778,30 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar, | |||
754 | static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt, | 778 | static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt, |
755 | struct ieee80211_rx_status *rx_status, | 779 | struct ieee80211_rx_status *rx_status, |
756 | struct sk_buff *skb, | 780 | struct sk_buff *skb, |
757 | enum htt_rx_mpdu_encrypt_type enctype) | 781 | enum htt_rx_mpdu_encrypt_type enctype, |
782 | enum rx_msdu_decap_format fmt, | ||
783 | bool dot11frag) | ||
758 | { | 784 | { |
759 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 785 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
760 | 786 | ||
787 | rx_status->flag &= ~(RX_FLAG_DECRYPTED | | ||
788 | RX_FLAG_IV_STRIPPED | | ||
789 | RX_FLAG_MMIC_STRIPPED); | ||
761 | 790 | ||
762 | if (enctype == HTT_RX_MPDU_ENCRYPT_NONE) { | 791 | if (enctype == HTT_RX_MPDU_ENCRYPT_NONE) |
763 | rx_status->flag &= ~(RX_FLAG_DECRYPTED | | 792 | return; |
764 | RX_FLAG_IV_STRIPPED | | 793 | |
765 | RX_FLAG_MMIC_STRIPPED); | 794 | /* |
795 | * There's no explicit rx descriptor flag to indicate whether a given | ||
796 | * frame has been decrypted or not. We're forced to use the decap | ||
797 | * format as an implicit indication. However fragmentation rx is always | ||
798 | * raw and it probably never reports undecrypted raws. | ||
799 | * | ||
800 | * This makes sure sniffed frames are reported as-is without stripping | ||
801 | * the protected flag. | ||
802 | */ | ||
803 | if (fmt == RX_MSDU_DECAP_RAW && !dot11frag) | ||
766 | return; | 804 | return; |
767 | } | ||
768 | 805 | ||
769 | rx_status->flag |= RX_FLAG_DECRYPTED | | 806 | rx_status->flag |= RX_FLAG_DECRYPTED | |
770 | RX_FLAG_IV_STRIPPED | | 807 | RX_FLAG_IV_STRIPPED | |
@@ -918,7 +955,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
918 | } | 955 | } |
919 | 956 | ||
920 | skb_in = skb; | 957 | skb_in = skb; |
921 | ath10k_htt_rx_h_protected(htt, rx_status, skb_in, enctype); | 958 | ath10k_htt_rx_h_protected(htt, rx_status, skb_in, enctype, fmt, |
959 | false); | ||
922 | skb = skb->next; | 960 | skb = skb->next; |
923 | skb_in->next = NULL; | 961 | skb_in->next = NULL; |
924 | 962 | ||
@@ -1000,7 +1038,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, | |||
1000 | break; | 1038 | break; |
1001 | } | 1039 | } |
1002 | 1040 | ||
1003 | ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype); | 1041 | ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype, fmt, false); |
1004 | 1042 | ||
1005 | ath10k_process_rx(htt->ar, rx_status, skb); | 1043 | ath10k_process_rx(htt->ar, rx_status, skb); |
1006 | } | 1044 | } |
@@ -1288,6 +1326,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1288 | } | 1326 | } |
1289 | 1327 | ||
1290 | /* FIXME: implement signal strength */ | 1328 | /* FIXME: implement signal strength */ |
1329 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; | ||
1291 | 1330 | ||
1292 | hdr = (struct ieee80211_hdr *)msdu_head->data; | 1331 | hdr = (struct ieee80211_hdr *)msdu_head->data; |
1293 | rxd = (void *)msdu_head->data - sizeof(*rxd); | 1332 | rxd = (void *)msdu_head->data - sizeof(*rxd); |
@@ -1306,7 +1345,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1306 | 1345 | ||
1307 | enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), | 1346 | enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), |
1308 | RX_MPDU_START_INFO0_ENCRYPT_TYPE); | 1347 | RX_MPDU_START_INFO0_ENCRYPT_TYPE); |
1309 | ath10k_htt_rx_h_protected(htt, rx_status, msdu_head, enctype); | 1348 | ath10k_htt_rx_h_protected(htt, rx_status, msdu_head, enctype, fmt, |
1349 | true); | ||
1310 | msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head); | 1350 | msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head); |
1311 | 1351 | ||
1312 | if (tkip_mic_err) | 1352 | if (tkip_mic_err) |
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 7a3e2e40dd5c..7064354d1f4f 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c | |||
@@ -83,7 +83,7 @@ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id) | |||
83 | __clear_bit(msdu_id, htt->used_msdu_ids); | 83 | __clear_bit(msdu_id, htt->used_msdu_ids); |
84 | } | 84 | } |
85 | 85 | ||
86 | int ath10k_htt_tx_attach(struct ath10k_htt *htt) | 86 | int ath10k_htt_tx_alloc(struct ath10k_htt *htt) |
87 | { | 87 | { |
88 | spin_lock_init(&htt->tx_lock); | 88 | spin_lock_init(&htt->tx_lock); |
89 | init_waitqueue_head(&htt->empty_tx_wq); | 89 | init_waitqueue_head(&htt->empty_tx_wq); |
@@ -120,7 +120,7 @@ int ath10k_htt_tx_attach(struct ath10k_htt *htt) | |||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt) | 123 | static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt) |
124 | { | 124 | { |
125 | struct htt_tx_done tx_done = {0}; | 125 | struct htt_tx_done tx_done = {0}; |
126 | int msdu_id; | 126 | int msdu_id; |
@@ -141,9 +141,9 @@ static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt) | |||
141 | spin_unlock_bh(&htt->tx_lock); | 141 | spin_unlock_bh(&htt->tx_lock); |
142 | } | 142 | } |
143 | 143 | ||
144 | void ath10k_htt_tx_detach(struct ath10k_htt *htt) | 144 | void ath10k_htt_tx_free(struct ath10k_htt *htt) |
145 | { | 145 | { |
146 | ath10k_htt_tx_cleanup_pending(htt); | 146 | ath10k_htt_tx_free_pending(htt); |
147 | kfree(htt->pending_tx); | 147 | kfree(htt->pending_tx); |
148 | kfree(htt->used_msdu_ids); | 148 | kfree(htt->used_msdu_ids); |
149 | dma_pool_destroy(htt->tx_pool); | 149 | dma_pool_destroy(htt->tx_pool); |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 7026f021ccbb..a21080028c54 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -54,7 +54,10 @@ static int ath10k_send_key(struct ath10k_vif *arvif, | |||
54 | switch (key->cipher) { | 54 | switch (key->cipher) { |
55 | case WLAN_CIPHER_SUITE_CCMP: | 55 | case WLAN_CIPHER_SUITE_CCMP: |
56 | arg.key_cipher = WMI_CIPHER_AES_CCM; | 56 | arg.key_cipher = WMI_CIPHER_AES_CCM; |
57 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; | 57 | if (arvif->vdev_type == WMI_VDEV_TYPE_AP) |
58 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; | ||
59 | else | ||
60 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; | ||
58 | break; | 61 | break; |
59 | case WLAN_CIPHER_SUITE_TKIP: | 62 | case WLAN_CIPHER_SUITE_TKIP: |
60 | arg.key_cipher = WMI_CIPHER_TKIP; | 63 | arg.key_cipher = WMI_CIPHER_TKIP; |
@@ -1888,8 +1891,13 @@ static void ath10k_tx_wep_key_work(struct work_struct *work) | |||
1888 | wep_key_work); | 1891 | wep_key_work); |
1889 | int ret, keyidx = arvif->def_wep_key_newidx; | 1892 | int ret, keyidx = arvif->def_wep_key_newidx; |
1890 | 1893 | ||
1894 | mutex_lock(&arvif->ar->conf_mutex); | ||
1895 | |||
1896 | if (arvif->ar->state != ATH10K_STATE_ON) | ||
1897 | goto unlock; | ||
1898 | |||
1891 | if (arvif->def_wep_key_idx == keyidx) | 1899 | if (arvif->def_wep_key_idx == keyidx) |
1892 | return; | 1900 | goto unlock; |
1893 | 1901 | ||
1894 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", | 1902 | ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", |
1895 | arvif->vdev_id, keyidx); | 1903 | arvif->vdev_id, keyidx); |
@@ -1902,10 +1910,13 @@ static void ath10k_tx_wep_key_work(struct work_struct *work) | |||
1902 | ath10k_warn("failed to update wep key index for vdev %d: %d\n", | 1910 | ath10k_warn("failed to update wep key index for vdev %d: %d\n", |
1903 | arvif->vdev_id, | 1911 | arvif->vdev_id, |
1904 | ret); | 1912 | ret); |
1905 | return; | 1913 | goto unlock; |
1906 | } | 1914 | } |
1907 | 1915 | ||
1908 | arvif->def_wep_key_idx = keyidx; | 1916 | arvif->def_wep_key_idx = keyidx; |
1917 | |||
1918 | unlock: | ||
1919 | mutex_unlock(&arvif->ar->conf_mutex); | ||
1909 | } | 1920 | } |
1910 | 1921 | ||
1911 | static void ath10k_tx_h_update_wep_key(struct sk_buff *skb) | 1922 | static void ath10k_tx_h_update_wep_key(struct sk_buff *skb) |
@@ -2286,9 +2297,19 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
2286 | ath10k_tx_htt(ar, skb); | 2297 | ath10k_tx_htt(ar, skb); |
2287 | } | 2298 | } |
2288 | 2299 | ||
2289 | /* | 2300 | /* Must not be called with conf_mutex held as workers can use that also. */ |
2290 | * Initialize various parameters with default vaules. | 2301 | static void ath10k_drain_tx(struct ath10k *ar) |
2291 | */ | 2302 | { |
2303 | /* make sure rcu-protected mac80211 tx path itself is drained */ | ||
2304 | synchronize_net(); | ||
2305 | |||
2306 | ath10k_offchan_tx_purge(ar); | ||
2307 | ath10k_mgmt_over_wmi_tx_purge(ar); | ||
2308 | |||
2309 | cancel_work_sync(&ar->offchan_tx_work); | ||
2310 | cancel_work_sync(&ar->wmi_mgmt_tx_work); | ||
2311 | } | ||
2312 | |||
2292 | void ath10k_halt(struct ath10k *ar) | 2313 | void ath10k_halt(struct ath10k *ar) |
2293 | { | 2314 | { |
2294 | struct ath10k_vif *arvif; | 2315 | struct ath10k_vif *arvif; |
@@ -2303,19 +2324,12 @@ void ath10k_halt(struct ath10k *ar) | |||
2303 | } | 2324 | } |
2304 | 2325 | ||
2305 | del_timer_sync(&ar->scan.timeout); | 2326 | del_timer_sync(&ar->scan.timeout); |
2306 | ath10k_offchan_tx_purge(ar); | 2327 | ath10k_reset_scan((unsigned long)ar); |
2307 | ath10k_mgmt_over_wmi_tx_purge(ar); | ||
2308 | ath10k_peer_cleanup_all(ar); | 2328 | ath10k_peer_cleanup_all(ar); |
2309 | ath10k_core_stop(ar); | 2329 | ath10k_core_stop(ar); |
2310 | ath10k_hif_power_down(ar); | 2330 | ath10k_hif_power_down(ar); |
2311 | 2331 | ||
2312 | spin_lock_bh(&ar->data_lock); | 2332 | spin_lock_bh(&ar->data_lock); |
2313 | if (ar->scan.in_progress) { | ||
2314 | del_timer(&ar->scan.timeout); | ||
2315 | ar->scan.in_progress = false; | ||
2316 | ieee80211_scan_completed(ar->hw, true); | ||
2317 | } | ||
2318 | |||
2319 | list_for_each_entry(arvif, &ar->arvifs, list) { | 2333 | list_for_each_entry(arvif, &ar->arvifs, list) { |
2320 | if (!arvif->beacon) | 2334 | if (!arvif->beacon) |
2321 | continue; | 2335 | continue; |
@@ -2329,46 +2343,125 @@ void ath10k_halt(struct ath10k *ar) | |||
2329 | spin_unlock_bh(&ar->data_lock); | 2343 | spin_unlock_bh(&ar->data_lock); |
2330 | } | 2344 | } |
2331 | 2345 | ||
2346 | static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) | ||
2347 | { | ||
2348 | struct ath10k *ar = hw->priv; | ||
2349 | |||
2350 | mutex_lock(&ar->conf_mutex); | ||
2351 | |||
2352 | if (ar->cfg_tx_chainmask) { | ||
2353 | *tx_ant = ar->cfg_tx_chainmask; | ||
2354 | *rx_ant = ar->cfg_rx_chainmask; | ||
2355 | } else { | ||
2356 | *tx_ant = ar->supp_tx_chainmask; | ||
2357 | *rx_ant = ar->supp_rx_chainmask; | ||
2358 | } | ||
2359 | |||
2360 | mutex_unlock(&ar->conf_mutex); | ||
2361 | |||
2362 | return 0; | ||
2363 | } | ||
2364 | |||
2365 | static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) | ||
2366 | { | ||
2367 | int ret; | ||
2368 | |||
2369 | lockdep_assert_held(&ar->conf_mutex); | ||
2370 | |||
2371 | ar->cfg_tx_chainmask = tx_ant; | ||
2372 | ar->cfg_rx_chainmask = rx_ant; | ||
2373 | |||
2374 | if ((ar->state != ATH10K_STATE_ON) && | ||
2375 | (ar->state != ATH10K_STATE_RESTARTED)) | ||
2376 | return 0; | ||
2377 | |||
2378 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask, | ||
2379 | tx_ant); | ||
2380 | if (ret) { | ||
2381 | ath10k_warn("failed to set tx-chainmask: %d, req 0x%x\n", | ||
2382 | ret, tx_ant); | ||
2383 | return ret; | ||
2384 | } | ||
2385 | |||
2386 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask, | ||
2387 | rx_ant); | ||
2388 | if (ret) { | ||
2389 | ath10k_warn("failed to set rx-chainmask: %d, req 0x%x\n", | ||
2390 | ret, rx_ant); | ||
2391 | return ret; | ||
2392 | } | ||
2393 | |||
2394 | return 0; | ||
2395 | } | ||
2396 | |||
2397 | static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) | ||
2398 | { | ||
2399 | struct ath10k *ar = hw->priv; | ||
2400 | int ret; | ||
2401 | |||
2402 | mutex_lock(&ar->conf_mutex); | ||
2403 | ret = __ath10k_set_antenna(ar, tx_ant, rx_ant); | ||
2404 | mutex_unlock(&ar->conf_mutex); | ||
2405 | return ret; | ||
2406 | } | ||
2407 | |||
2332 | static int ath10k_start(struct ieee80211_hw *hw) | 2408 | static int ath10k_start(struct ieee80211_hw *hw) |
2333 | { | 2409 | { |
2334 | struct ath10k *ar = hw->priv; | 2410 | struct ath10k *ar = hw->priv; |
2335 | int ret = 0; | 2411 | int ret = 0; |
2336 | 2412 | ||
2413 | /* | ||
2414 | * This makes sense only when restarting hw. It is harmless to call | ||
2415 | * uncoditionally. This is necessary to make sure no HTT/WMI tx | ||
2416 | * commands will be submitted while restarting. | ||
2417 | */ | ||
2418 | ath10k_drain_tx(ar); | ||
2419 | |||
2337 | mutex_lock(&ar->conf_mutex); | 2420 | mutex_lock(&ar->conf_mutex); |
2338 | 2421 | ||
2339 | if (ar->state != ATH10K_STATE_OFF && | 2422 | switch (ar->state) { |
2340 | ar->state != ATH10K_STATE_RESTARTING) { | 2423 | case ATH10K_STATE_OFF: |
2424 | ar->state = ATH10K_STATE_ON; | ||
2425 | break; | ||
2426 | case ATH10K_STATE_RESTARTING: | ||
2427 | ath10k_halt(ar); | ||
2428 | ar->state = ATH10K_STATE_RESTARTED; | ||
2429 | break; | ||
2430 | case ATH10K_STATE_ON: | ||
2431 | case ATH10K_STATE_RESTARTED: | ||
2432 | case ATH10K_STATE_WEDGED: | ||
2433 | WARN_ON(1); | ||
2341 | ret = -EINVAL; | 2434 | ret = -EINVAL; |
2342 | goto exit; | 2435 | goto err; |
2343 | } | 2436 | } |
2344 | 2437 | ||
2345 | ret = ath10k_hif_power_up(ar); | 2438 | ret = ath10k_hif_power_up(ar); |
2346 | if (ret) { | 2439 | if (ret) { |
2347 | ath10k_err("Could not init hif: %d\n", ret); | 2440 | ath10k_err("Could not init hif: %d\n", ret); |
2348 | ar->state = ATH10K_STATE_OFF; | 2441 | goto err_off; |
2349 | goto exit; | ||
2350 | } | 2442 | } |
2351 | 2443 | ||
2352 | ret = ath10k_core_start(ar); | 2444 | ret = ath10k_core_start(ar); |
2353 | if (ret) { | 2445 | if (ret) { |
2354 | ath10k_err("Could not init core: %d\n", ret); | 2446 | ath10k_err("Could not init core: %d\n", ret); |
2355 | ath10k_hif_power_down(ar); | 2447 | goto err_power_down; |
2356 | ar->state = ATH10K_STATE_OFF; | ||
2357 | goto exit; | ||
2358 | } | 2448 | } |
2359 | 2449 | ||
2360 | if (ar->state == ATH10K_STATE_OFF) | ||
2361 | ar->state = ATH10K_STATE_ON; | ||
2362 | else if (ar->state == ATH10K_STATE_RESTARTING) | ||
2363 | ar->state = ATH10K_STATE_RESTARTED; | ||
2364 | |||
2365 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1); | 2450 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1); |
2366 | if (ret) | 2451 | if (ret) { |
2367 | ath10k_warn("failed to enable PMF QOS: %d\n", ret); | 2452 | ath10k_warn("failed to enable PMF QOS: %d\n", ret); |
2453 | goto err_core_stop; | ||
2454 | } | ||
2368 | 2455 | ||
2369 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1); | 2456 | ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1); |
2370 | if (ret) | 2457 | if (ret) { |
2371 | ath10k_warn("failed to enable dynamic BW: %d\n", ret); | 2458 | ath10k_warn("failed to enable dynamic BW: %d\n", ret); |
2459 | goto err_core_stop; | ||
2460 | } | ||
2461 | |||
2462 | if (ar->cfg_tx_chainmask) | ||
2463 | __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, | ||
2464 | ar->cfg_rx_chainmask); | ||
2372 | 2465 | ||
2373 | /* | 2466 | /* |
2374 | * By default FW set ARP frames ac to voice (6). In that case ARP | 2467 | * By default FW set ARP frames ac to voice (6). In that case ARP |
@@ -2384,14 +2477,25 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
2384 | if (ret) { | 2477 | if (ret) { |
2385 | ath10k_warn("failed to set arp ac override parameter: %d\n", | 2478 | ath10k_warn("failed to set arp ac override parameter: %d\n", |
2386 | ret); | 2479 | ret); |
2387 | goto exit; | 2480 | goto err_core_stop; |
2388 | } | 2481 | } |
2389 | 2482 | ||
2390 | ar->num_started_vdevs = 0; | 2483 | ar->num_started_vdevs = 0; |
2391 | ath10k_regd_update(ar); | 2484 | ath10k_regd_update(ar); |
2392 | ret = 0; | ||
2393 | 2485 | ||
2394 | exit: | 2486 | mutex_unlock(&ar->conf_mutex); |
2487 | return 0; | ||
2488 | |||
2489 | err_core_stop: | ||
2490 | ath10k_core_stop(ar); | ||
2491 | |||
2492 | err_power_down: | ||
2493 | ath10k_hif_power_down(ar); | ||
2494 | |||
2495 | err_off: | ||
2496 | ar->state = ATH10K_STATE_OFF; | ||
2497 | |||
2498 | err: | ||
2395 | mutex_unlock(&ar->conf_mutex); | 2499 | mutex_unlock(&ar->conf_mutex); |
2396 | return ret; | 2500 | return ret; |
2397 | } | 2501 | } |
@@ -2400,19 +2504,15 @@ static void ath10k_stop(struct ieee80211_hw *hw) | |||
2400 | { | 2504 | { |
2401 | struct ath10k *ar = hw->priv; | 2505 | struct ath10k *ar = hw->priv; |
2402 | 2506 | ||
2507 | ath10k_drain_tx(ar); | ||
2508 | |||
2403 | mutex_lock(&ar->conf_mutex); | 2509 | mutex_lock(&ar->conf_mutex); |
2404 | if (ar->state == ATH10K_STATE_ON || | 2510 | if (ar->state != ATH10K_STATE_OFF) { |
2405 | ar->state == ATH10K_STATE_RESTARTED || | ||
2406 | ar->state == ATH10K_STATE_WEDGED) | ||
2407 | ath10k_halt(ar); | 2511 | ath10k_halt(ar); |
2408 | 2512 | ar->state = ATH10K_STATE_OFF; | |
2409 | ar->state = ATH10K_STATE_OFF; | 2513 | } |
2410 | mutex_unlock(&ar->conf_mutex); | 2514 | mutex_unlock(&ar->conf_mutex); |
2411 | 2515 | ||
2412 | ath10k_mgmt_over_wmi_tx_purge(ar); | ||
2413 | |||
2414 | cancel_work_sync(&ar->offchan_tx_work); | ||
2415 | cancel_work_sync(&ar->wmi_mgmt_tx_work); | ||
2416 | cancel_work_sync(&ar->restart_work); | 2516 | cancel_work_sync(&ar->restart_work); |
2417 | } | 2517 | } |
2418 | 2518 | ||
@@ -2925,7 +3025,12 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
2925 | arvif->u.ap.hidden_ssid = info->hidden_ssid; | 3025 | arvif->u.ap.hidden_ssid = info->hidden_ssid; |
2926 | } | 3026 | } |
2927 | 3027 | ||
2928 | if (changed & BSS_CHANGED_BSSID) { | 3028 | /* |
3029 | * Firmware manages AP self-peer internally so make sure to not create | ||
3030 | * it in driver. Otherwise AP self-peer deletion may timeout later. | ||
3031 | */ | ||
3032 | if (changed & BSS_CHANGED_BSSID && | ||
3033 | vif->type != NL80211_IFTYPE_AP) { | ||
2929 | if (!is_zero_ether_addr(info->bssid)) { | 3034 | if (!is_zero_ether_addr(info->bssid)) { |
2930 | ath10k_dbg(ATH10K_DBG_MAC, | 3035 | ath10k_dbg(ATH10K_DBG_MAC, |
2931 | "mac vdev %d create peer %pM\n", | 3036 | "mac vdev %d create peer %pM\n", |
@@ -4142,14 +4247,6 @@ static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw, | |||
4142 | fixed_nss, force_sgi); | 4247 | fixed_nss, force_sgi); |
4143 | } | 4248 | } |
4144 | 4249 | ||
4145 | static void ath10k_channel_switch_beacon(struct ieee80211_hw *hw, | ||
4146 | struct ieee80211_vif *vif, | ||
4147 | struct cfg80211_chan_def *chandef) | ||
4148 | { | ||
4149 | /* there's no need to do anything here. vif->csa_active is enough */ | ||
4150 | return; | ||
4151 | } | ||
4152 | |||
4153 | static void ath10k_sta_rc_update(struct ieee80211_hw *hw, | 4250 | static void ath10k_sta_rc_update(struct ieee80211_hw *hw, |
4154 | struct ieee80211_vif *vif, | 4251 | struct ieee80211_vif *vif, |
4155 | struct ieee80211_sta *sta, | 4252 | struct ieee80211_sta *sta, |
@@ -4253,10 +4350,11 @@ static const struct ieee80211_ops ath10k_ops = { | |||
4253 | .set_frag_threshold = ath10k_set_frag_threshold, | 4350 | .set_frag_threshold = ath10k_set_frag_threshold, |
4254 | .flush = ath10k_flush, | 4351 | .flush = ath10k_flush, |
4255 | .tx_last_beacon = ath10k_tx_last_beacon, | 4352 | .tx_last_beacon = ath10k_tx_last_beacon, |
4353 | .set_antenna = ath10k_set_antenna, | ||
4354 | .get_antenna = ath10k_get_antenna, | ||
4256 | .restart_complete = ath10k_restart_complete, | 4355 | .restart_complete = ath10k_restart_complete, |
4257 | .get_survey = ath10k_get_survey, | 4356 | .get_survey = ath10k_get_survey, |
4258 | .set_bitrate_mask = ath10k_set_bitrate_mask, | 4357 | .set_bitrate_mask = ath10k_set_bitrate_mask, |
4259 | .channel_switch_beacon = ath10k_channel_switch_beacon, | ||
4260 | .sta_rc_update = ath10k_sta_rc_update, | 4358 | .sta_rc_update = ath10k_sta_rc_update, |
4261 | .get_tsf = ath10k_get_tsf, | 4359 | .get_tsf = ath10k_get_tsf, |
4262 | #ifdef CONFIG_PM | 4360 | #ifdef CONFIG_PM |
@@ -4602,6 +4700,18 @@ int ath10k_mac_register(struct ath10k *ar) | |||
4602 | BIT(NL80211_IFTYPE_ADHOC) | | 4700 | BIT(NL80211_IFTYPE_ADHOC) | |
4603 | BIT(NL80211_IFTYPE_AP); | 4701 | BIT(NL80211_IFTYPE_AP); |
4604 | 4702 | ||
4703 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { | ||
4704 | /* TODO: Have to deal with 2x2 chips if/when the come out. */ | ||
4705 | ar->supp_tx_chainmask = TARGET_10X_TX_CHAIN_MASK; | ||
4706 | ar->supp_rx_chainmask = TARGET_10X_RX_CHAIN_MASK; | ||
4707 | } else { | ||
4708 | ar->supp_tx_chainmask = TARGET_TX_CHAIN_MASK; | ||
4709 | ar->supp_rx_chainmask = TARGET_RX_CHAIN_MASK; | ||
4710 | } | ||
4711 | |||
4712 | ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask; | ||
4713 | ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask; | ||
4714 | |||
4605 | if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) | 4715 | if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) |
4606 | ar->hw->wiphy->interface_modes |= | 4716 | ar->hw->wiphy->interface_modes |= |
4607 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | 4717 | BIT(NL80211_IFTYPE_P2P_CLIENT) | |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 66b1f3017f2b..d0004d59c97e 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -59,6 +59,7 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)"); | |||
59 | 59 | ||
60 | /* how long wait to wait for target to initialise, in ms */ | 60 | /* how long wait to wait for target to initialise, in ms */ |
61 | #define ATH10K_PCI_TARGET_WAIT 3000 | 61 | #define ATH10K_PCI_TARGET_WAIT 3000 |
62 | #define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3 | ||
62 | 63 | ||
63 | #define QCA988X_2_0_DEVICE_ID (0x003c) | 64 | #define QCA988X_2_0_DEVICE_ID (0x003c) |
64 | 65 | ||
@@ -761,17 +762,21 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, | |||
761 | struct ath10k_pci_pipe *pci_pipe = &ar_pci->pipe_info[pipe_id]; | 762 | struct ath10k_pci_pipe *pci_pipe = &ar_pci->pipe_info[pipe_id]; |
762 | struct ath10k_ce_pipe *ce_pipe = pci_pipe->ce_hdl; | 763 | struct ath10k_ce_pipe *ce_pipe = pci_pipe->ce_hdl; |
763 | struct ath10k_ce_ring *src_ring = ce_pipe->src_ring; | 764 | struct ath10k_ce_ring *src_ring = ce_pipe->src_ring; |
764 | unsigned int nentries_mask = src_ring->nentries_mask; | 765 | unsigned int nentries_mask; |
765 | unsigned int sw_index = src_ring->sw_index; | 766 | unsigned int sw_index; |
766 | unsigned int write_index = src_ring->write_index; | 767 | unsigned int write_index; |
767 | int err, i; | 768 | int err, i = 0; |
768 | 769 | ||
769 | spin_lock_bh(&ar_pci->ce_lock); | 770 | spin_lock_bh(&ar_pci->ce_lock); |
770 | 771 | ||
772 | nentries_mask = src_ring->nentries_mask; | ||
773 | sw_index = src_ring->sw_index; | ||
774 | write_index = src_ring->write_index; | ||
775 | |||
771 | if (unlikely(CE_RING_DELTA(nentries_mask, | 776 | if (unlikely(CE_RING_DELTA(nentries_mask, |
772 | write_index, sw_index - 1) < n_items)) { | 777 | write_index, sw_index - 1) < n_items)) { |
773 | err = -ENOBUFS; | 778 | err = -ENOBUFS; |
774 | goto unlock; | 779 | goto err; |
775 | } | 780 | } |
776 | 781 | ||
777 | for (i = 0; i < n_items - 1; i++) { | 782 | for (i = 0; i < n_items - 1; i++) { |
@@ -788,7 +793,7 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, | |||
788 | items[i].transfer_id, | 793 | items[i].transfer_id, |
789 | CE_SEND_FLAG_GATHER); | 794 | CE_SEND_FLAG_GATHER); |
790 | if (err) | 795 | if (err) |
791 | goto unlock; | 796 | goto err; |
792 | } | 797 | } |
793 | 798 | ||
794 | /* `i` is equal to `n_items -1` after for() */ | 799 | /* `i` is equal to `n_items -1` after for() */ |
@@ -806,10 +811,15 @@ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, | |||
806 | items[i].transfer_id, | 811 | items[i].transfer_id, |
807 | 0); | 812 | 0); |
808 | if (err) | 813 | if (err) |
809 | goto unlock; | 814 | goto err; |
815 | |||
816 | spin_unlock_bh(&ar_pci->ce_lock); | ||
817 | return 0; | ||
818 | |||
819 | err: | ||
820 | for (; i > 0; i--) | ||
821 | __ath10k_ce_send_revert(ce_pipe); | ||
810 | 822 | ||
811 | err = 0; | ||
812 | unlock: | ||
813 | spin_unlock_bh(&ar_pci->ce_lock); | 823 | spin_unlock_bh(&ar_pci->ce_lock); |
814 | return err; | 824 | return err; |
815 | } | 825 | } |
@@ -1271,6 +1281,9 @@ static void ath10k_pci_hif_stop(struct ath10k *ar) | |||
1271 | 1281 | ||
1272 | ath10k_dbg(ATH10K_DBG_BOOT, "boot hif stop\n"); | 1282 | ath10k_dbg(ATH10K_DBG_BOOT, "boot hif stop\n"); |
1273 | 1283 | ||
1284 | if (WARN_ON(!ar_pci->started)) | ||
1285 | return; | ||
1286 | |||
1274 | ret = ath10k_ce_disable_interrupts(ar); | 1287 | ret = ath10k_ce_disable_interrupts(ar); |
1275 | if (ret) | 1288 | if (ret) |
1276 | ath10k_warn("failed to disable CE interrupts: %d\n", ret); | 1289 | ath10k_warn("failed to disable CE interrupts: %d\n", ret); |
@@ -1802,6 +1815,26 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar) | |||
1802 | ath10k_pci_sleep(ar); | 1815 | ath10k_pci_sleep(ar); |
1803 | } | 1816 | } |
1804 | 1817 | ||
1818 | /* this function effectively clears target memory controller assert line */ | ||
1819 | static void ath10k_pci_warm_reset_si0(struct ath10k *ar) | ||
1820 | { | ||
1821 | u32 val; | ||
1822 | |||
1823 | val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); | ||
1824 | ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS, | ||
1825 | val | SOC_RESET_CONTROL_SI0_RST_MASK); | ||
1826 | val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); | ||
1827 | |||
1828 | msleep(10); | ||
1829 | |||
1830 | val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); | ||
1831 | ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS, | ||
1832 | val & ~SOC_RESET_CONTROL_SI0_RST_MASK); | ||
1833 | val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); | ||
1834 | |||
1835 | msleep(10); | ||
1836 | } | ||
1837 | |||
1805 | static int ath10k_pci_warm_reset(struct ath10k *ar) | 1838 | static int ath10k_pci_warm_reset(struct ath10k *ar) |
1806 | { | 1839 | { |
1807 | int ret = 0; | 1840 | int ret = 0; |
@@ -1860,6 +1893,8 @@ static int ath10k_pci_warm_reset(struct ath10k *ar) | |||
1860 | SOC_RESET_CONTROL_ADDRESS); | 1893 | SOC_RESET_CONTROL_ADDRESS); |
1861 | msleep(10); | 1894 | msleep(10); |
1862 | 1895 | ||
1896 | ath10k_pci_warm_reset_si0(ar); | ||
1897 | |||
1863 | /* debug */ | 1898 | /* debug */ |
1864 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + | 1899 | val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + |
1865 | PCIE_INTR_CAUSE_ADDRESS); | 1900 | PCIE_INTR_CAUSE_ADDRESS); |
@@ -1988,6 +2023,28 @@ err: | |||
1988 | return ret; | 2023 | return ret; |
1989 | } | 2024 | } |
1990 | 2025 | ||
2026 | static int ath10k_pci_hif_power_up_warm(struct ath10k *ar) | ||
2027 | { | ||
2028 | int i, ret; | ||
2029 | |||
2030 | /* | ||
2031 | * Sometime warm reset succeeds after retries. | ||
2032 | * | ||
2033 | * FIXME: It might be possible to tune ath10k_pci_warm_reset() to work | ||
2034 | * at first try. | ||
2035 | */ | ||
2036 | for (i = 0; i < ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS; i++) { | ||
2037 | ret = __ath10k_pci_hif_power_up(ar, false); | ||
2038 | if (ret == 0) | ||
2039 | break; | ||
2040 | |||
2041 | ath10k_warn("failed to warm reset (attempt %d out of %d): %d\n", | ||
2042 | i + 1, ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS, ret); | ||
2043 | } | ||
2044 | |||
2045 | return ret; | ||
2046 | } | ||
2047 | |||
1991 | static int ath10k_pci_hif_power_up(struct ath10k *ar) | 2048 | static int ath10k_pci_hif_power_up(struct ath10k *ar) |
1992 | { | 2049 | { |
1993 | int ret; | 2050 | int ret; |
@@ -1999,10 +2056,10 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) | |||
1999 | * preferred (and safer) way to perform a device reset is through a | 2056 | * preferred (and safer) way to perform a device reset is through a |
2000 | * warm reset. | 2057 | * warm reset. |
2001 | * | 2058 | * |
2002 | * Warm reset doesn't always work though (notably after a firmware | 2059 | * Warm reset doesn't always work though so fall back to cold reset may |
2003 | * crash) so fall back to cold reset if necessary. | 2060 | * be necessary. |
2004 | */ | 2061 | */ |
2005 | ret = __ath10k_pci_hif_power_up(ar, false); | 2062 | ret = ath10k_pci_hif_power_up_warm(ar); |
2006 | if (ret) { | 2063 | if (ret) { |
2007 | ath10k_warn("failed to power up target using warm reset: %d\n", | 2064 | ath10k_warn("failed to power up target using warm reset: %d\n", |
2008 | ret); | 2065 | ret); |
@@ -2196,10 +2253,7 @@ static void ath10k_pci_early_irq_tasklet(unsigned long data) | |||
2196 | if (fw_ind & FW_IND_EVENT_PENDING) { | 2253 | if (fw_ind & FW_IND_EVENT_PENDING) { |
2197 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, | 2254 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, |
2198 | fw_ind & ~FW_IND_EVENT_PENDING); | 2255 | fw_ind & ~FW_IND_EVENT_PENDING); |
2199 | 2256 | ath10k_pci_hif_dump_area(ar); | |
2200 | /* Some structures are unavailable during early boot or at | ||
2201 | * driver teardown so just print that the device has crashed. */ | ||
2202 | ath10k_warn("device crashed - no diagnostics available\n"); | ||
2203 | } | 2257 | } |
2204 | 2258 | ||
2205 | ath10k_pci_sleep(ar); | 2259 | ath10k_pci_sleep(ar); |
@@ -2476,6 +2530,9 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) | |||
2476 | 2530 | ||
2477 | if (val & FW_IND_EVENT_PENDING) { | 2531 | if (val & FW_IND_EVENT_PENDING) { |
2478 | ath10k_warn("device has crashed during init\n"); | 2532 | ath10k_warn("device has crashed during init\n"); |
2533 | ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, | ||
2534 | val & ~FW_IND_EVENT_PENDING); | ||
2535 | ath10k_pci_hif_dump_area(ar); | ||
2479 | ret = -ECOMM; | 2536 | ret = -ECOMM; |
2480 | goto out; | 2537 | goto out; |
2481 | } | 2538 | } |
@@ -2602,18 +2659,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev, | |||
2602 | 2659 | ||
2603 | pci_set_drvdata(pdev, ar); | 2660 | pci_set_drvdata(pdev, ar); |
2604 | 2661 | ||
2605 | /* | ||
2606 | * Without any knowledge of the Host, the Target may have been reset or | ||
2607 | * power cycled and its Config Space may no longer reflect the PCI | ||
2608 | * address space that was assigned earlier by the PCI infrastructure. | ||
2609 | * Refresh it now. | ||
2610 | */ | ||
2611 | ret = pci_assign_resource(pdev, BAR_NUM); | ||
2612 | if (ret) { | ||
2613 | ath10k_err("failed to assign PCI space: %d\n", ret); | ||
2614 | goto err_ar; | ||
2615 | } | ||
2616 | |||
2617 | ret = pci_enable_device(pdev); | 2662 | ret = pci_enable_device(pdev); |
2618 | if (ret) { | 2663 | if (ret) { |
2619 | ath10k_err("failed to enable PCI device: %d\n", ret); | 2664 | ath10k_err("failed to enable PCI device: %d\n", ret); |
@@ -2725,8 +2770,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev) | |||
2725 | if (!ar_pci) | 2770 | if (!ar_pci) |
2726 | return; | 2771 | return; |
2727 | 2772 | ||
2728 | tasklet_kill(&ar_pci->msi_fw_err); | ||
2729 | |||
2730 | ath10k_core_unregister(ar); | 2773 | ath10k_core_unregister(ar); |
2731 | ath10k_pci_free_ce(ar); | 2774 | ath10k_pci_free_ce(ar); |
2732 | 2775 | ||
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 72cc4f20d102..4b7782a529ac 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -639,6 +639,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
639 | struct sk_buff *wmi_skb; | 639 | struct sk_buff *wmi_skb; |
640 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 640 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
641 | int len; | 641 | int len; |
642 | u32 buf_len = skb->len; | ||
642 | u16 fc; | 643 | u16 fc; |
643 | 644 | ||
644 | hdr = (struct ieee80211_hdr *)skb->data; | 645 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -648,6 +649,15 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
648 | return -EINVAL; | 649 | return -EINVAL; |
649 | 650 | ||
650 | len = sizeof(cmd->hdr) + skb->len; | 651 | len = sizeof(cmd->hdr) + skb->len; |
652 | |||
653 | if ((ieee80211_is_action(hdr->frame_control) || | ||
654 | ieee80211_is_deauth(hdr->frame_control) || | ||
655 | ieee80211_is_disassoc(hdr->frame_control)) && | ||
656 | ieee80211_has_protected(hdr->frame_control)) { | ||
657 | len += IEEE80211_CCMP_MIC_LEN; | ||
658 | buf_len += IEEE80211_CCMP_MIC_LEN; | ||
659 | } | ||
660 | |||
651 | len = round_up(len, 4); | 661 | len = round_up(len, 4); |
652 | 662 | ||
653 | wmi_skb = ath10k_wmi_alloc_skb(len); | 663 | wmi_skb = ath10k_wmi_alloc_skb(len); |
@@ -659,7 +669,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
659 | cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); | 669 | cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); |
660 | cmd->hdr.tx_rate = 0; | 670 | cmd->hdr.tx_rate = 0; |
661 | cmd->hdr.tx_power = 0; | 671 | cmd->hdr.tx_power = 0; |
662 | cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len)); | 672 | cmd->hdr.buf_len = __cpu_to_le32(buf_len); |
663 | 673 | ||
664 | memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); | 674 | memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); |
665 | memcpy(cmd->buf, skb->data, skb->len); | 675 | memcpy(cmd->buf, skb->data, skb->len); |
@@ -957,10 +967,16 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
957 | * frames with Protected Bit set. */ | 967 | * frames with Protected Bit set. */ |
958 | if (ieee80211_has_protected(hdr->frame_control) && | 968 | if (ieee80211_has_protected(hdr->frame_control) && |
959 | !ieee80211_is_auth(hdr->frame_control)) { | 969 | !ieee80211_is_auth(hdr->frame_control)) { |
960 | status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED | | 970 | status->flag |= RX_FLAG_DECRYPTED; |
961 | RX_FLAG_MMIC_STRIPPED; | 971 | |
962 | hdr->frame_control = __cpu_to_le16(fc & | 972 | if (!ieee80211_is_action(hdr->frame_control) && |
973 | !ieee80211_is_deauth(hdr->frame_control) && | ||
974 | !ieee80211_is_disassoc(hdr->frame_control)) { | ||
975 | status->flag |= RX_FLAG_IV_STRIPPED | | ||
976 | RX_FLAG_MMIC_STRIPPED; | ||
977 | hdr->frame_control = __cpu_to_le16(fc & | ||
963 | ~IEEE80211_FCTL_PROTECTED); | 978 | ~IEEE80211_FCTL_PROTECTED); |
979 | } | ||
964 | } | 980 | } |
965 | 981 | ||
966 | ath10k_dbg(ATH10K_DBG_MGMT, | 982 | ath10k_dbg(ATH10K_DBG_MGMT, |
@@ -2359,7 +2375,7 @@ void ath10k_wmi_detach(struct ath10k *ar) | |||
2359 | ar->wmi.num_mem_chunks = 0; | 2375 | ar->wmi.num_mem_chunks = 0; |
2360 | } | 2376 | } |
2361 | 2377 | ||
2362 | int ath10k_wmi_connect_htc_service(struct ath10k *ar) | 2378 | int ath10k_wmi_connect(struct ath10k *ar) |
2363 | { | 2379 | { |
2364 | int status; | 2380 | int status; |
2365 | struct ath10k_htc_svc_conn_req conn_req; | 2381 | struct ath10k_htc_svc_conn_req conn_req; |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index ae838221af65..89ef3b3749eb 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -2323,9 +2323,9 @@ struct wmi_pdev_param_map { | |||
2323 | #define WMI_PDEV_PARAM_UNSUPPORTED 0 | 2323 | #define WMI_PDEV_PARAM_UNSUPPORTED 0 |
2324 | 2324 | ||
2325 | enum wmi_pdev_param { | 2325 | enum wmi_pdev_param { |
2326 | /* TX chian mask */ | 2326 | /* TX chain mask */ |
2327 | WMI_PDEV_PARAM_TX_CHAIN_MASK = 0x1, | 2327 | WMI_PDEV_PARAM_TX_CHAIN_MASK = 0x1, |
2328 | /* RX chian mask */ | 2328 | /* RX chain mask */ |
2329 | WMI_PDEV_PARAM_RX_CHAIN_MASK, | 2329 | WMI_PDEV_PARAM_RX_CHAIN_MASK, |
2330 | /* TX power limit for 2G Radio */ | 2330 | /* TX power limit for 2G Radio */ |
2331 | WMI_PDEV_PARAM_TXPOWER_LIMIT2G, | 2331 | WMI_PDEV_PARAM_TXPOWER_LIMIT2G, |
@@ -4259,7 +4259,7 @@ void ath10k_wmi_detach(struct ath10k *ar); | |||
4259 | int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); | 4259 | int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); |
4260 | int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); | 4260 | int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); |
4261 | 4261 | ||
4262 | int ath10k_wmi_connect_htc_service(struct ath10k *ar); | 4262 | int ath10k_wmi_connect(struct ath10k *ar); |
4263 | int ath10k_wmi_pdev_set_channel(struct ath10k *ar, | 4263 | int ath10k_wmi_pdev_set_channel(struct ath10k *ar, |
4264 | const struct wmi_channel_arg *); | 4264 | const struct wmi_channel_arg *); |
4265 | int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); | 4265 | int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 40791dbf4616..62ac95d6bb9d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -2230,14 +2230,6 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
2230 | clear_bit(ATH_OP_SCANNING, &common->op_flags); | 2230 | clear_bit(ATH_OP_SCANNING, &common->op_flags); |
2231 | } | 2231 | } |
2232 | 2232 | ||
2233 | static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw, | ||
2234 | struct ieee80211_vif *vif, | ||
2235 | struct cfg80211_chan_def *chandef) | ||
2236 | { | ||
2237 | /* depend on vif->csa_active only */ | ||
2238 | return; | ||
2239 | } | ||
2240 | |||
2241 | struct ieee80211_ops ath9k_ops = { | 2233 | struct ieee80211_ops ath9k_ops = { |
2242 | .tx = ath9k_tx, | 2234 | .tx = ath9k_tx, |
2243 | .start = ath9k_start, | 2235 | .start = ath9k_start, |
@@ -2285,5 +2277,4 @@ struct ieee80211_ops ath9k_ops = { | |||
2285 | #endif | 2277 | #endif |
2286 | .sw_scan_start = ath9k_sw_scan_start, | 2278 | .sw_scan_start = ath9k_sw_scan_start, |
2287 | .sw_scan_complete = ath9k_sw_scan_complete, | 2279 | .sw_scan_complete = ath9k_sw_scan_complete, |
2288 | .channel_switch_beacon = ath9k_channel_switch_beacon, | ||
2289 | }; | 2280 | }; |