diff options
Diffstat (limited to 'drivers/net/wireless/ath')
65 files changed, 1808 insertions, 842 deletions
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index c63d1159db5c..ce7826009eeb 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig | |||
@@ -25,6 +25,14 @@ config ATH_DEBUG | |||
25 | Say Y, if you want to debug atheros wireless drivers. | 25 | Say Y, if you want to debug atheros wireless drivers. |
26 | Right now only ath9k makes use of this. | 26 | Right now only ath9k makes use of this. |
27 | 27 | ||
28 | config ATH_TRACEPOINTS | ||
29 | bool "Atheros wireless tracing" | ||
30 | depends on ATH_DEBUG | ||
31 | depends on EVENT_TRACING | ||
32 | ---help--- | ||
33 | This option enables tracepoints for atheros wireless drivers. | ||
34 | Currently, ath9k makes use of this facility. | ||
35 | |||
28 | config ATH_REG_DYNAMIC_USER_REG_HINTS | 36 | config ATH_REG_DYNAMIC_USER_REG_HINTS |
29 | bool "Atheros dynamic user regulatory hints" | 37 | bool "Atheros dynamic user regulatory hints" |
30 | depends on CFG80211_CERTIFICATION_ONUS | 38 | depends on CFG80211_CERTIFICATION_ONUS |
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 7d023b0f13b4..89f8d5979402 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile | |||
@@ -17,4 +17,8 @@ ath-objs := main.o \ | |||
17 | dfs_pri_detector.o | 17 | dfs_pri_detector.o |
18 | 18 | ||
19 | ath-$(CONFIG_ATH_DEBUG) += debug.o | 19 | ath-$(CONFIG_ATH_DEBUG) += debug.o |
20 | ath-$(CONFIG_ATH_TRACEPOINTS) += trace.o | ||
21 | |||
20 | ccflags-y += -D__CHECK_ENDIAN__ | 22 | ccflags-y += -D__CHECK_ENDIAN__ |
23 | |||
24 | CFLAGS_trace.o := -I$(src) | ||
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index a3b6e27d9121..e5ba6faf3281 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -268,6 +268,7 @@ enum ATH_DEBUG { | |||
268 | }; | 268 | }; |
269 | 269 | ||
270 | #define ATH_DBG_DEFAULT (ATH_DBG_FATAL) | 270 | #define ATH_DBG_DEFAULT (ATH_DBG_FATAL) |
271 | #define ATH_DBG_MAX_LEN 512 | ||
271 | 272 | ||
272 | #ifdef CONFIG_ATH_DEBUG | 273 | #ifdef CONFIG_ATH_DEBUG |
273 | 274 | ||
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index 1053bb5f2cdc..72acb822bb11 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig | |||
@@ -24,7 +24,7 @@ config ATH10K_DEBUG | |||
24 | 24 | ||
25 | config ATH10K_DEBUGFS | 25 | config ATH10K_DEBUGFS |
26 | bool "Atheros ath10k debugfs support" | 26 | bool "Atheros ath10k debugfs support" |
27 | depends on ATH10K | 27 | depends on ATH10K && DEBUG_FS |
28 | select RELAY | 28 | select RELAY |
29 | ---help--- | 29 | ---help--- |
30 | Enabled debugfs support | 30 | Enabled debugfs support |
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile index 2cfb63ca9327..8b1b1adb477a 100644 --- a/drivers/net/wireless/ath/ath10k/Makefile +++ b/drivers/net/wireless/ath/ath10k/Makefile | |||
@@ -11,6 +11,7 @@ ath10k_core-y += mac.o \ | |||
11 | bmi.o | 11 | bmi.o |
12 | 12 | ||
13 | ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o | 13 | ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o |
14 | ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o | ||
14 | ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o | 15 | ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o |
15 | 16 | ||
16 | obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o | 17 | obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o |
diff --git a/drivers/net/wireless/ath/ath10k/bmi.h b/drivers/net/wireless/ath/ath10k/bmi.h index 111ab701465c..31a990635490 100644 --- a/drivers/net/wireless/ath/ath10k/bmi.h +++ b/drivers/net/wireless/ath/ath10k/bmi.h | |||
@@ -177,7 +177,6 @@ struct bmi_target_info { | |||
177 | u32 type; | 177 | u32 type; |
178 | }; | 178 | }; |
179 | 179 | ||
180 | |||
181 | /* in msec */ | 180 | /* in msec */ |
182 | #define BMI_COMMUNICATION_TIMEOUT_HZ (1*HZ) | 181 | #define BMI_COMMUNICATION_TIMEOUT_HZ (1*HZ) |
183 | 182 | ||
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 71eef233bd01..101cadb6e4ba 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c | |||
@@ -260,7 +260,6 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar, | |||
260 | ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IS_ADDRESS, mask); | 260 | ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IS_ADDRESS, mask); |
261 | } | 261 | } |
262 | 262 | ||
263 | |||
264 | /* | 263 | /* |
265 | * Guts of ath10k_ce_send, used by both ath10k_ce_send and | 264 | * Guts of ath10k_ce_send, used by both ath10k_ce_send and |
266 | * ath10k_ce_sendlist_send. | 265 | * ath10k_ce_sendlist_send. |
@@ -385,7 +384,6 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe) | |||
385 | return delta; | 384 | return delta; |
386 | } | 385 | } |
387 | 386 | ||
388 | |||
389 | int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) | 387 | int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) |
390 | { | 388 | { |
391 | struct ath10k *ar = pipe->ar; | 389 | struct ath10k *ar = pipe->ar; |
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 82d1f23546b9..329b7340fa72 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include "hif.h" | 21 | #include "hif.h" |
22 | 22 | ||
23 | |||
24 | /* Maximum number of Copy Engine's supported */ | 23 | /* Maximum number of Copy Engine's supported */ |
25 | #define CE_COUNT_MAX 8 | 24 | #define CE_COUNT_MAX 8 |
26 | #define CE_HTT_H2T_MSG_SRC_NENTRIES 4096 | 25 | #define CE_HTT_H2T_MSG_SRC_NENTRIES 4096 |
@@ -37,7 +36,6 @@ | |||
37 | 36 | ||
38 | struct ath10k_ce_pipe; | 37 | struct ath10k_ce_pipe; |
39 | 38 | ||
40 | |||
41 | #define CE_DESC_FLAGS_GATHER (1 << 0) | 39 | #define CE_DESC_FLAGS_GATHER (1 << 0) |
42 | #define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) | 40 | #define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) |
43 | #define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC | 41 | #define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC |
@@ -189,10 +187,10 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, | |||
189 | * Pops 1 completed send buffer from Source ring. | 187 | * Pops 1 completed send buffer from Source ring. |
190 | */ | 188 | */ |
191 | int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, | 189 | int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, |
192 | void **per_transfer_contextp, | 190 | void **per_transfer_contextp, |
193 | u32 *bufferp, | 191 | u32 *bufferp, |
194 | unsigned int *nbytesp, | 192 | unsigned int *nbytesp, |
195 | unsigned int *transfer_idp); | 193 | unsigned int *transfer_idp); |
196 | 194 | ||
197 | /*==================CE Engine Initialization=======================*/ | 195 | /*==================CE Engine Initialization=======================*/ |
198 | 196 | ||
@@ -202,7 +200,7 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, | |||
202 | void (*recv_cb)(struct ath10k_ce_pipe *)); | 200 | void (*recv_cb)(struct ath10k_ce_pipe *)); |
203 | void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); | 201 | void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); |
204 | int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, | 202 | int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, |
205 | const struct ce_attr *attr); | 203 | const struct ce_attr *attr); |
206 | void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id); | 204 | void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id); |
207 | 205 | ||
208 | /*==================CE Engine Shutdown=======================*/ | 206 | /*==================CE Engine Shutdown=======================*/ |
@@ -383,7 +381,6 @@ struct ce_attr { | |||
383 | #define DST_WATERMARK_HIGH_RESET 0 | 381 | #define DST_WATERMARK_HIGH_RESET 0 |
384 | #define DST_WATERMARK_ADDRESS 0x0050 | 382 | #define DST_WATERMARK_ADDRESS 0x0050 |
385 | 383 | ||
386 | |||
387 | static inline u32 ath10k_ce_base_address(unsigned int ce_id) | 384 | static inline u32 ath10k_ce_base_address(unsigned int ce_id) |
388 | { | 385 | { |
389 | return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id; | 386 | return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id; |
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 651a6da8adf5..cee18c89d7f2 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "bmi.h" | 26 | #include "bmi.h" |
27 | #include "debug.h" | 27 | #include "debug.h" |
28 | #include "htt.h" | 28 | #include "htt.h" |
29 | #include "testmode.h" | ||
29 | 30 | ||
30 | unsigned int ath10k_debug_mask; | 31 | unsigned int ath10k_debug_mask; |
31 | static bool uart_print; | 32 | static bool uart_print; |
@@ -257,21 +258,42 @@ static int ath10k_download_and_run_otp(struct ath10k *ar) | |||
257 | return 0; | 258 | return 0; |
258 | } | 259 | } |
259 | 260 | ||
260 | static int ath10k_download_fw(struct ath10k *ar) | 261 | static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode) |
261 | { | 262 | { |
262 | u32 address; | 263 | u32 address, data_len; |
264 | const char *mode_name; | ||
265 | const void *data; | ||
263 | int ret; | 266 | int ret; |
264 | 267 | ||
265 | address = ar->hw_params.patch_load_addr; | 268 | address = ar->hw_params.patch_load_addr; |
266 | 269 | ||
267 | ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data, | 270 | switch (mode) { |
268 | ar->firmware_len); | 271 | case ATH10K_FIRMWARE_MODE_NORMAL: |
272 | data = ar->firmware_data; | ||
273 | data_len = ar->firmware_len; | ||
274 | mode_name = "normal"; | ||
275 | break; | ||
276 | case ATH10K_FIRMWARE_MODE_UTF: | ||
277 | data = ar->testmode.utf->data; | ||
278 | data_len = ar->testmode.utf->size; | ||
279 | mode_name = "utf"; | ||
280 | break; | ||
281 | default: | ||
282 | ath10k_err(ar, "unknown firmware mode: %d\n", mode); | ||
283 | return -EINVAL; | ||
284 | } | ||
285 | |||
286 | ath10k_dbg(ar, ATH10K_DBG_BOOT, | ||
287 | "boot uploading firmware image %p len %d mode %s\n", | ||
288 | data, data_len, mode_name); | ||
289 | |||
290 | ret = ath10k_bmi_fast_download(ar, address, data, data_len); | ||
269 | if (ret) { | 291 | if (ret) { |
270 | ath10k_err(ar, "could not write fw (%d)\n", ret); | 292 | ath10k_err(ar, "failed to download %s firmware: %d\n", |
271 | goto exit; | 293 | mode_name, ret); |
294 | return ret; | ||
272 | } | 295 | } |
273 | 296 | ||
274 | exit: | ||
275 | return ret; | 297 | return ret; |
276 | } | 298 | } |
277 | 299 | ||
@@ -567,7 +589,8 @@ success: | |||
567 | return 0; | 589 | return 0; |
568 | } | 590 | } |
569 | 591 | ||
570 | static int ath10k_init_download_firmware(struct ath10k *ar) | 592 | static int ath10k_init_download_firmware(struct ath10k *ar, |
593 | enum ath10k_firmware_mode mode) | ||
571 | { | 594 | { |
572 | int ret; | 595 | int ret; |
573 | 596 | ||
@@ -583,7 +606,7 @@ static int ath10k_init_download_firmware(struct ath10k *ar) | |||
583 | return ret; | 606 | return ret; |
584 | } | 607 | } |
585 | 608 | ||
586 | ret = ath10k_download_fw(ar); | 609 | ret = ath10k_download_fw(ar, mode); |
587 | if (ret) { | 610 | if (ret) { |
588 | ath10k_err(ar, "failed to download firmware: %d\n", ret); | 611 | ath10k_err(ar, "failed to download firmware: %d\n", ret); |
589 | return ret; | 612 | return ret; |
@@ -685,12 +708,15 @@ static void ath10k_core_restart(struct work_struct *work) | |||
685 | case ATH10K_STATE_WEDGED: | 708 | case ATH10K_STATE_WEDGED: |
686 | ath10k_warn(ar, "device is wedged, will not restart\n"); | 709 | ath10k_warn(ar, "device is wedged, will not restart\n"); |
687 | break; | 710 | break; |
711 | case ATH10K_STATE_UTF: | ||
712 | ath10k_warn(ar, "firmware restart in UTF mode not supported\n"); | ||
713 | break; | ||
688 | } | 714 | } |
689 | 715 | ||
690 | mutex_unlock(&ar->conf_mutex); | 716 | mutex_unlock(&ar->conf_mutex); |
691 | } | 717 | } |
692 | 718 | ||
693 | int ath10k_core_start(struct ath10k *ar) | 719 | int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) |
694 | { | 720 | { |
695 | int status; | 721 | int status; |
696 | 722 | ||
@@ -703,7 +729,7 @@ int ath10k_core_start(struct ath10k *ar) | |||
703 | goto err; | 729 | goto err; |
704 | } | 730 | } |
705 | 731 | ||
706 | status = ath10k_init_download_firmware(ar); | 732 | status = ath10k_init_download_firmware(ar, mode); |
707 | if (status) | 733 | if (status) |
708 | goto err; | 734 | goto err; |
709 | 735 | ||
@@ -760,10 +786,12 @@ int ath10k_core_start(struct ath10k *ar) | |||
760 | goto err_hif_stop; | 786 | goto err_hif_stop; |
761 | } | 787 | } |
762 | 788 | ||
763 | status = ath10k_htt_connect(&ar->htt); | 789 | if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { |
764 | if (status) { | 790 | status = ath10k_htt_connect(&ar->htt); |
765 | ath10k_err(ar, "failed to connect htt (%d)\n", status); | 791 | if (status) { |
766 | goto err_hif_stop; | 792 | ath10k_err(ar, "failed to connect htt (%d)\n", status); |
793 | goto err_hif_stop; | ||
794 | } | ||
767 | } | 795 | } |
768 | 796 | ||
769 | status = ath10k_wmi_connect(ar); | 797 | status = ath10k_wmi_connect(ar); |
@@ -778,11 +806,13 @@ int ath10k_core_start(struct ath10k *ar) | |||
778 | goto err_hif_stop; | 806 | goto err_hif_stop; |
779 | } | 807 | } |
780 | 808 | ||
781 | status = ath10k_wmi_wait_for_service_ready(ar); | 809 | if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { |
782 | if (status <= 0) { | 810 | status = ath10k_wmi_wait_for_service_ready(ar); |
783 | ath10k_warn(ar, "wmi service ready event not received"); | 811 | if (status <= 0) { |
784 | status = -ETIMEDOUT; | 812 | ath10k_warn(ar, "wmi service ready event not received"); |
785 | goto err_hif_stop; | 813 | status = -ETIMEDOUT; |
814 | goto err_hif_stop; | ||
815 | } | ||
786 | } | 816 | } |
787 | 817 | ||
788 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n", | 818 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n", |
@@ -802,10 +832,13 @@ int ath10k_core_start(struct ath10k *ar) | |||
802 | goto err_hif_stop; | 832 | goto err_hif_stop; |
803 | } | 833 | } |
804 | 834 | ||
805 | status = ath10k_htt_setup(&ar->htt); | 835 | /* we don't care about HTT in UTF mode */ |
806 | if (status) { | 836 | if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { |
807 | ath10k_err(ar, "failed to setup htt: %d\n", status); | 837 | status = ath10k_htt_setup(&ar->htt); |
808 | goto err_hif_stop; | 838 | if (status) { |
839 | ath10k_err(ar, "failed to setup htt: %d\n", status); | ||
840 | goto err_hif_stop; | ||
841 | } | ||
809 | } | 842 | } |
810 | 843 | ||
811 | status = ath10k_debug_start(ar); | 844 | status = ath10k_debug_start(ar); |
@@ -861,7 +894,8 @@ void ath10k_core_stop(struct ath10k *ar) | |||
861 | lockdep_assert_held(&ar->conf_mutex); | 894 | lockdep_assert_held(&ar->conf_mutex); |
862 | 895 | ||
863 | /* try to suspend target */ | 896 | /* try to suspend target */ |
864 | if (ar->state != ATH10K_STATE_RESTARTING) | 897 | if (ar->state != ATH10K_STATE_RESTARTING && |
898 | ar->state != ATH10K_STATE_UTF) | ||
865 | ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); | 899 | ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); |
866 | 900 | ||
867 | ath10k_debug_stop(ar); | 901 | ath10k_debug_stop(ar); |
@@ -914,7 +948,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar) | |||
914 | 948 | ||
915 | mutex_lock(&ar->conf_mutex); | 949 | mutex_lock(&ar->conf_mutex); |
916 | 950 | ||
917 | ret = ath10k_core_start(ar); | 951 | ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); |
918 | if (ret) { | 952 | if (ret) { |
919 | ath10k_err(ar, "could not init core (%d)\n", ret); | 953 | ath10k_err(ar, "could not init core (%d)\n", ret); |
920 | ath10k_core_free_firmware_files(ar); | 954 | ath10k_core_free_firmware_files(ar); |
@@ -977,7 +1011,7 @@ static void ath10k_core_register_work(struct work_struct *work) | |||
977 | goto err_release_fw; | 1011 | goto err_release_fw; |
978 | } | 1012 | } |
979 | 1013 | ||
980 | status = ath10k_debug_create(ar); | 1014 | status = ath10k_debug_register(ar); |
981 | if (status) { | 1015 | if (status) { |
982 | ath10k_err(ar, "unable to initialize debugfs\n"); | 1016 | ath10k_err(ar, "unable to initialize debugfs\n"); |
983 | goto err_unregister_mac; | 1017 | goto err_unregister_mac; |
@@ -1041,9 +1075,11 @@ void ath10k_core_unregister(struct ath10k *ar) | |||
1041 | * unhappy about callback failures. */ | 1075 | * unhappy about callback failures. */ |
1042 | ath10k_mac_unregister(ar); | 1076 | ath10k_mac_unregister(ar); |
1043 | 1077 | ||
1078 | ath10k_testmode_destroy(ar); | ||
1079 | |||
1044 | ath10k_core_free_firmware_files(ar); | 1080 | ath10k_core_free_firmware_files(ar); |
1045 | 1081 | ||
1046 | ath10k_debug_destroy(ar); | 1082 | ath10k_debug_unregister(ar); |
1047 | } | 1083 | } |
1048 | EXPORT_SYMBOL(ath10k_core_unregister); | 1084 | EXPORT_SYMBOL(ath10k_core_unregister); |
1049 | 1085 | ||
@@ -1051,6 +1087,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, | |||
1051 | const struct ath10k_hif_ops *hif_ops) | 1087 | const struct ath10k_hif_ops *hif_ops) |
1052 | { | 1088 | { |
1053 | struct ath10k *ar; | 1089 | struct ath10k *ar; |
1090 | int ret; | ||
1054 | 1091 | ||
1055 | ar = ath10k_mac_create(priv_size); | 1092 | ar = ath10k_mac_create(priv_size); |
1056 | if (!ar) | 1093 | if (!ar) |
@@ -1076,7 +1113,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, | |||
1076 | 1113 | ||
1077 | ar->workqueue = create_singlethread_workqueue("ath10k_wq"); | 1114 | ar->workqueue = create_singlethread_workqueue("ath10k_wq"); |
1078 | if (!ar->workqueue) | 1115 | if (!ar->workqueue) |
1079 | goto err_wq; | 1116 | goto err_free_mac; |
1080 | 1117 | ||
1081 | mutex_init(&ar->conf_mutex); | 1118 | mutex_init(&ar->conf_mutex); |
1082 | spin_lock_init(&ar->data_lock); | 1119 | spin_lock_init(&ar->data_lock); |
@@ -1094,10 +1131,18 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, | |||
1094 | INIT_WORK(&ar->register_work, ath10k_core_register_work); | 1131 | INIT_WORK(&ar->register_work, ath10k_core_register_work); |
1095 | INIT_WORK(&ar->restart_work, ath10k_core_restart); | 1132 | INIT_WORK(&ar->restart_work, ath10k_core_restart); |
1096 | 1133 | ||
1134 | ret = ath10k_debug_create(ar); | ||
1135 | if (ret) | ||
1136 | goto err_free_wq; | ||
1137 | |||
1097 | return ar; | 1138 | return ar; |
1098 | 1139 | ||
1099 | err_wq: | 1140 | err_free_wq: |
1141 | destroy_workqueue(ar->workqueue); | ||
1142 | |||
1143 | err_free_mac: | ||
1100 | ath10k_mac_destroy(ar); | 1144 | ath10k_mac_destroy(ar); |
1145 | |||
1101 | return NULL; | 1146 | return NULL; |
1102 | } | 1147 | } |
1103 | EXPORT_SYMBOL(ath10k_core_create); | 1148 | EXPORT_SYMBOL(ath10k_core_create); |
@@ -1107,6 +1152,7 @@ void ath10k_core_destroy(struct ath10k *ar) | |||
1107 | flush_workqueue(ar->workqueue); | 1152 | flush_workqueue(ar->workqueue); |
1108 | destroy_workqueue(ar->workqueue); | 1153 | destroy_workqueue(ar->workqueue); |
1109 | 1154 | ||
1155 | ath10k_debug_destroy(ar); | ||
1110 | ath10k_mac_destroy(ar); | 1156 | ath10k_mac_destroy(ar); |
1111 | } | 1157 | } |
1112 | EXPORT_SYMBOL(ath10k_core_destroy); | 1158 | EXPORT_SYMBOL(ath10k_core_destroy); |
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 4ef476099225..fe531ea6926c 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -293,7 +293,7 @@ struct ath10k_debug { | |||
293 | struct dentry *debugfs_phy; | 293 | struct dentry *debugfs_phy; |
294 | 294 | ||
295 | struct ath10k_target_stats target_stats; | 295 | struct ath10k_target_stats target_stats; |
296 | DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_BM_SIZE); | 296 | DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX); |
297 | 297 | ||
298 | struct completion event_stats_compl; | 298 | struct completion event_stats_compl; |
299 | 299 | ||
@@ -330,6 +330,17 @@ enum ath10k_state { | |||
330 | * prevents completion timeouts and makes the driver more responsive to | 330 | * prevents completion timeouts and makes the driver more responsive to |
331 | * userspace commands. This is also prevents recursive recovery. */ | 331 | * userspace commands. This is also prevents recursive recovery. */ |
332 | ATH10K_STATE_WEDGED, | 332 | ATH10K_STATE_WEDGED, |
333 | |||
334 | /* factory tests */ | ||
335 | ATH10K_STATE_UTF, | ||
336 | }; | ||
337 | |||
338 | enum ath10k_firmware_mode { | ||
339 | /* the default mode, standard 802.11 functionality */ | ||
340 | ATH10K_FIRMWARE_MODE_NORMAL, | ||
341 | |||
342 | /* factory tests etc */ | ||
343 | ATH10K_FIRMWARE_MODE_UTF, | ||
333 | }; | 344 | }; |
334 | 345 | ||
335 | enum ath10k_fw_features { | 346 | enum ath10k_fw_features { |
@@ -472,7 +483,6 @@ struct ath10k { | |||
472 | struct cfg80211_chan_def chandef; | 483 | struct cfg80211_chan_def chandef; |
473 | 484 | ||
474 | int free_vdev_map; | 485 | int free_vdev_map; |
475 | bool promisc; | ||
476 | bool monitor; | 486 | bool monitor; |
477 | int monitor_vdev_id; | 487 | int monitor_vdev_id; |
478 | bool monitor_started; | 488 | bool monitor_started; |
@@ -544,6 +554,15 @@ struct ath10k { | |||
544 | struct ath10k_spec_scan config; | 554 | struct ath10k_spec_scan config; |
545 | } spectral; | 555 | } spectral; |
546 | 556 | ||
557 | struct { | ||
558 | /* protected by conf_mutex */ | ||
559 | const struct firmware *utf; | ||
560 | DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT); | ||
561 | |||
562 | /* protected by data_lock */ | ||
563 | bool utf_monitor; | ||
564 | } testmode; | ||
565 | |||
547 | /* must be last */ | 566 | /* must be last */ |
548 | u8 drv_priv[0] __aligned(sizeof(void *)); | 567 | u8 drv_priv[0] __aligned(sizeof(void *)); |
549 | }; | 568 | }; |
@@ -552,7 +571,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, | |||
552 | const struct ath10k_hif_ops *hif_ops); | 571 | const struct ath10k_hif_ops *hif_ops); |
553 | void ath10k_core_destroy(struct ath10k *ar); | 572 | void ath10k_core_destroy(struct ath10k *ar); |
554 | 573 | ||
555 | int ath10k_core_start(struct ath10k *ar); | 574 | int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode); |
556 | int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt); | 575 | int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt); |
557 | void ath10k_core_stop(struct ath10k *ar); | 576 | void ath10k_core_stop(struct ath10k *ar); |
558 | int ath10k_core_register(struct ath10k *ar, u32 chip_id); | 577 | int ath10k_core_register(struct ath10k *ar, u32 chip_id); |
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index f3f0a80f8bab..3756feba3223 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c | |||
@@ -117,7 +117,7 @@ int ath10k_info(struct ath10k *ar, const char *fmt, ...) | |||
117 | va_start(args, fmt); | 117 | va_start(args, fmt); |
118 | vaf.va = &args; | 118 | vaf.va = &args; |
119 | ret = dev_info(ar->dev, "%pV", &vaf); | 119 | ret = dev_info(ar->dev, "%pV", &vaf); |
120 | trace_ath10k_log_info(&vaf); | 120 | trace_ath10k_log_info(ar, &vaf); |
121 | va_end(args); | 121 | va_end(args); |
122 | 122 | ||
123 | return ret; | 123 | return ret; |
@@ -134,11 +134,12 @@ void ath10k_print_driver_info(struct ath10k *ar) | |||
134 | ar->fw_api, | 134 | ar->fw_api, |
135 | ar->htt.target_version_major, | 135 | ar->htt.target_version_major, |
136 | ar->htt.target_version_minor); | 136 | ar->htt.target_version_minor); |
137 | ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d\n", | 137 | ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", |
138 | config_enabled(CONFIG_ATH10K_DEBUG), | 138 | config_enabled(CONFIG_ATH10K_DEBUG), |
139 | config_enabled(CONFIG_ATH10K_DEBUGFS), | 139 | config_enabled(CONFIG_ATH10K_DEBUGFS), |
140 | config_enabled(CONFIG_ATH10K_TRACING), | 140 | config_enabled(CONFIG_ATH10K_TRACING), |
141 | config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)); | 141 | config_enabled(CONFIG_ATH10K_DFS_CERTIFIED), |
142 | config_enabled(CONFIG_NL80211_TESTMODE)); | ||
142 | } | 143 | } |
143 | EXPORT_SYMBOL(ath10k_print_driver_info); | 144 | EXPORT_SYMBOL(ath10k_print_driver_info); |
144 | 145 | ||
@@ -153,7 +154,7 @@ int ath10k_err(struct ath10k *ar, const char *fmt, ...) | |||
153 | va_start(args, fmt); | 154 | va_start(args, fmt); |
154 | vaf.va = &args; | 155 | vaf.va = &args; |
155 | ret = dev_err(ar->dev, "%pV", &vaf); | 156 | ret = dev_err(ar->dev, "%pV", &vaf); |
156 | trace_ath10k_log_err(&vaf); | 157 | trace_ath10k_log_err(ar, &vaf); |
157 | va_end(args); | 158 | va_end(args); |
158 | 159 | ||
159 | return ret; | 160 | return ret; |
@@ -170,7 +171,7 @@ int ath10k_warn(struct ath10k *ar, const char *fmt, ...) | |||
170 | va_start(args, fmt); | 171 | va_start(args, fmt); |
171 | vaf.va = &args; | 172 | vaf.va = &args; |
172 | dev_warn_ratelimited(ar->dev, "%pV", &vaf); | 173 | dev_warn_ratelimited(ar->dev, "%pV", &vaf); |
173 | trace_ath10k_log_warn(&vaf); | 174 | trace_ath10k_log_warn(ar, &vaf); |
174 | 175 | ||
175 | va_end(args); | 176 | va_end(args); |
176 | 177 | ||
@@ -208,7 +209,7 @@ static ssize_t ath10k_read_wmi_services(struct file *file, | |||
208 | if (len > buf_len) | 209 | if (len > buf_len) |
209 | len = buf_len; | 210 | len = buf_len; |
210 | 211 | ||
211 | for (i = 0; i < WMI_MAX_SERVICE; i++) { | 212 | for (i = 0; i < WMI_SERVICE_MAX; i++) { |
212 | enabled = test_bit(i, ar->debug.wmi_service_bitmap); | 213 | enabled = test_bit(i, ar->debug.wmi_service_bitmap); |
213 | name = wmi_service_name(i); | 214 | name = wmi_service_name(i); |
214 | 215 | ||
@@ -564,16 +565,35 @@ static const struct file_operations fops_fw_stats = { | |||
564 | .llseek = default_llseek, | 565 | .llseek = default_llseek, |
565 | }; | 566 | }; |
566 | 567 | ||
568 | /* This is a clean assert crash in firmware. */ | ||
569 | static int ath10k_debug_fw_assert(struct ath10k *ar) | ||
570 | { | ||
571 | struct wmi_vdev_install_key_cmd *cmd; | ||
572 | struct sk_buff *skb; | ||
573 | |||
574 | skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16); | ||
575 | if (!skb) | ||
576 | return -ENOMEM; | ||
577 | |||
578 | cmd = (struct wmi_vdev_install_key_cmd *)skb->data; | ||
579 | memset(cmd, 0, sizeof(*cmd)); | ||
580 | |||
581 | /* big enough number so that firmware asserts */ | ||
582 | cmd->vdev_id = __cpu_to_le32(0x7ffe); | ||
583 | |||
584 | return ath10k_wmi_cmd_send(ar, skb, | ||
585 | ar->wmi.cmd->vdev_install_key_cmdid); | ||
586 | } | ||
587 | |||
567 | static ssize_t ath10k_read_simulate_fw_crash(struct file *file, | 588 | static ssize_t ath10k_read_simulate_fw_crash(struct file *file, |
568 | char __user *user_buf, | 589 | char __user *user_buf, |
569 | size_t count, loff_t *ppos) | 590 | size_t count, loff_t *ppos) |
570 | { | 591 | { |
571 | const char buf[] = "To simulate firmware crash write one of the" | 592 | const char buf[] = |
572 | " keywords to this file:\n `soft` - this will send" | 593 | "To simulate firmware crash write one of the keywords to this file:\n" |
573 | " WMI_FORCE_FW_HANG_ASSERT to firmware if FW" | 594 | "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n" |
574 | " supports that command.\n `hard` - this will send" | 595 | "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n" |
575 | " to firmware command with illegal parameters" | 596 | "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n"; |
576 | " causing firmware crash.\n"; | ||
577 | 597 | ||
578 | return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); | 598 | return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); |
579 | } | 599 | } |
@@ -621,7 +641,11 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file, | |||
621 | * firmware variants in order to force a firmware crash. | 641 | * firmware variants in order to force a firmware crash. |
622 | */ | 642 | */ |
623 | ret = ath10k_wmi_vdev_set_param(ar, 0x7fff, | 643 | ret = ath10k_wmi_vdev_set_param(ar, 0x7fff, |
624 | ar->wmi.vdev_param->rts_threshold, 0); | 644 | ar->wmi.vdev_param->rts_threshold, |
645 | 0); | ||
646 | } else if (!strcmp(buf, "assert")) { | ||
647 | ath10k_info(ar, "simulating firmware assert crash\n"); | ||
648 | ret = ath10k_debug_fw_assert(ar); | ||
625 | } else { | 649 | } else { |
626 | ret = -EINVAL; | 650 | ret = -EINVAL; |
627 | goto exit; | 651 | goto exit; |
@@ -840,8 +864,8 @@ static void ath10k_debug_htt_stats_dwork(struct work_struct *work) | |||
840 | } | 864 | } |
841 | 865 | ||
842 | static ssize_t ath10k_read_htt_stats_mask(struct file *file, | 866 | static ssize_t ath10k_read_htt_stats_mask(struct file *file, |
843 | char __user *user_buf, | 867 | char __user *user_buf, |
844 | size_t count, loff_t *ppos) | 868 | size_t count, loff_t *ppos) |
845 | { | 869 | { |
846 | struct ath10k *ar = file->private_data; | 870 | struct ath10k *ar = file->private_data; |
847 | char buf[32]; | 871 | char buf[32]; |
@@ -853,8 +877,8 @@ static ssize_t ath10k_read_htt_stats_mask(struct file *file, | |||
853 | } | 877 | } |
854 | 878 | ||
855 | static ssize_t ath10k_write_htt_stats_mask(struct file *file, | 879 | static ssize_t ath10k_write_htt_stats_mask(struct file *file, |
856 | const char __user *user_buf, | 880 | const char __user *user_buf, |
857 | size_t count, loff_t *ppos) | 881 | size_t count, loff_t *ppos) |
858 | { | 882 | { |
859 | struct ath10k *ar = file->private_data; | 883 | struct ath10k *ar = file->private_data; |
860 | unsigned long mask; | 884 | unsigned long mask; |
@@ -959,8 +983,8 @@ static const struct file_operations fops_htt_max_amsdu_ampdu = { | |||
959 | }; | 983 | }; |
960 | 984 | ||
961 | static ssize_t ath10k_read_fw_dbglog(struct file *file, | 985 | static ssize_t ath10k_read_fw_dbglog(struct file *file, |
962 | char __user *user_buf, | 986 | char __user *user_buf, |
963 | size_t count, loff_t *ppos) | 987 | size_t count, loff_t *ppos) |
964 | { | 988 | { |
965 | struct ath10k *ar = file->private_data; | 989 | struct ath10k *ar = file->private_data; |
966 | unsigned int len; | 990 | unsigned int len; |
@@ -1132,19 +1156,28 @@ static const struct file_operations fops_dfs_stats = { | |||
1132 | 1156 | ||
1133 | int ath10k_debug_create(struct ath10k *ar) | 1157 | int ath10k_debug_create(struct ath10k *ar) |
1134 | { | 1158 | { |
1135 | int ret; | ||
1136 | |||
1137 | ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); | 1159 | ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); |
1138 | if (!ar->debug.fw_crash_data) { | 1160 | if (!ar->debug.fw_crash_data) |
1139 | ret = -ENOMEM; | 1161 | return -ENOMEM; |
1140 | goto err; | ||
1141 | } | ||
1142 | 1162 | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | void ath10k_debug_destroy(struct ath10k *ar) | ||
1167 | { | ||
1168 | vfree(ar->debug.fw_crash_data); | ||
1169 | ar->debug.fw_crash_data = NULL; | ||
1170 | } | ||
1171 | |||
1172 | int ath10k_debug_register(struct ath10k *ar) | ||
1173 | { | ||
1143 | ar->debug.debugfs_phy = debugfs_create_dir("ath10k", | 1174 | ar->debug.debugfs_phy = debugfs_create_dir("ath10k", |
1144 | ar->hw->wiphy->debugfsdir); | 1175 | ar->hw->wiphy->debugfsdir); |
1145 | if (!ar->debug.debugfs_phy) { | 1176 | if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) { |
1146 | ret = -ENOMEM; | 1177 | if (IS_ERR(ar->debug.debugfs_phy)) |
1147 | goto err_free_fw_crash_data; | 1178 | return PTR_ERR(ar->debug.debugfs_phy); |
1179 | |||
1180 | return -ENOMEM; | ||
1148 | } | 1181 | } |
1149 | 1182 | ||
1150 | INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, | 1183 | INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, |
@@ -1192,17 +1225,10 @@ int ath10k_debug_create(struct ath10k *ar) | |||
1192 | } | 1225 | } |
1193 | 1226 | ||
1194 | return 0; | 1227 | return 0; |
1195 | |||
1196 | err_free_fw_crash_data: | ||
1197 | vfree(ar->debug.fw_crash_data); | ||
1198 | |||
1199 | err: | ||
1200 | return ret; | ||
1201 | } | 1228 | } |
1202 | 1229 | ||
1203 | void ath10k_debug_destroy(struct ath10k *ar) | 1230 | void ath10k_debug_unregister(struct ath10k *ar) |
1204 | { | 1231 | { |
1205 | vfree(ar->debug.fw_crash_data); | ||
1206 | cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); | 1232 | cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); |
1207 | } | 1233 | } |
1208 | 1234 | ||
@@ -1223,7 +1249,7 @@ void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask, | |||
1223 | if (ath10k_debug_mask & mask) | 1249 | if (ath10k_debug_mask & mask) |
1224 | dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf); | 1250 | dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf); |
1225 | 1251 | ||
1226 | trace_ath10k_log_dbg(mask, &vaf); | 1252 | trace_ath10k_log_dbg(ar, mask, &vaf); |
1227 | 1253 | ||
1228 | va_end(args); | 1254 | va_end(args); |
1229 | } | 1255 | } |
@@ -1242,7 +1268,7 @@ void ath10k_dbg_dump(struct ath10k *ar, | |||
1242 | } | 1268 | } |
1243 | 1269 | ||
1244 | /* tracing code doesn't like null strings :/ */ | 1270 | /* tracing code doesn't like null strings :/ */ |
1245 | trace_ath10k_log_dbg_dump(msg ? msg : "", prefix ? prefix : "", | 1271 | trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "", |
1246 | buf, len); | 1272 | buf, len); |
1247 | } | 1273 | } |
1248 | EXPORT_SYMBOL(ath10k_dbg_dump); | 1274 | EXPORT_SYMBOL(ath10k_dbg_dump); |
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 56746539bea2..b3774f7f492c 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h | |||
@@ -34,6 +34,7 @@ enum ath10k_debug_mask { | |||
34 | ATH10K_DBG_DATA = 0x00000200, | 34 | ATH10K_DBG_DATA = 0x00000200, |
35 | ATH10K_DBG_BMI = 0x00000400, | 35 | ATH10K_DBG_BMI = 0x00000400, |
36 | ATH10K_DBG_REGULATORY = 0x00000800, | 36 | ATH10K_DBG_REGULATORY = 0x00000800, |
37 | ATH10K_DBG_TESTMODE = 0x00001000, | ||
37 | ATH10K_DBG_ANY = 0xffffffff, | 38 | ATH10K_DBG_ANY = 0xffffffff, |
38 | }; | 39 | }; |
39 | 40 | ||
@@ -49,6 +50,8 @@ int ath10k_debug_start(struct ath10k *ar); | |||
49 | void ath10k_debug_stop(struct ath10k *ar); | 50 | void ath10k_debug_stop(struct ath10k *ar); |
50 | int ath10k_debug_create(struct ath10k *ar); | 51 | int ath10k_debug_create(struct ath10k *ar); |
51 | void ath10k_debug_destroy(struct ath10k *ar); | 52 | void ath10k_debug_destroy(struct ath10k *ar); |
53 | int ath10k_debug_register(struct ath10k *ar); | ||
54 | void ath10k_debug_unregister(struct ath10k *ar); | ||
52 | void ath10k_debug_read_service_map(struct ath10k *ar, | 55 | void ath10k_debug_read_service_map(struct ath10k *ar, |
53 | void *service_map, | 56 | void *service_map, |
54 | size_t map_size); | 57 | size_t map_size); |
@@ -80,6 +83,15 @@ static inline void ath10k_debug_destroy(struct ath10k *ar) | |||
80 | { | 83 | { |
81 | } | 84 | } |
82 | 85 | ||
86 | static inline int ath10k_debug_register(struct ath10k *ar) | ||
87 | { | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static inline void ath10k_debug_unregister(struct ath10k *ar) | ||
92 | { | ||
93 | } | ||
94 | |||
83 | static inline void ath10k_debug_read_service_map(struct ath10k *ar, | 95 | static inline void ath10k_debug_read_service_map(struct ath10k *ar, |
84 | void *service_map, | 96 | void *service_map, |
85 | size_t map_size) | 97 | size_t map_size) |
diff --git a/drivers/net/wireless/ath/ath10k/hif.h b/drivers/net/wireless/ath/ath10k/hif.h index 2ac7beacddca..62323fea27e1 100644 --- a/drivers/net/wireless/ath/ath10k/hif.h +++ b/drivers/net/wireless/ath/ath10k/hif.h | |||
@@ -91,7 +91,6 @@ struct ath10k_hif_ops { | |||
91 | int (*resume)(struct ath10k *ar); | 91 | int (*resume)(struct ath10k *ar); |
92 | }; | 92 | }; |
93 | 93 | ||
94 | |||
95 | static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id, | 94 | static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id, |
96 | struct ath10k_hif_sg_item *items, | 95 | struct ath10k_hif_sg_item *items, |
97 | int n_items) | 96 | int n_items) |
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c index fd9a251f0659..676bd4ed969b 100644 --- a/drivers/net/wireless/ath/ath10k/htc.c +++ b/drivers/net/wireless/ath/ath10k/htc.c | |||
@@ -45,10 +45,8 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar) | |||
45 | struct ath10k_skb_cb *skb_cb; | 45 | struct ath10k_skb_cb *skb_cb; |
46 | 46 | ||
47 | skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE); | 47 | skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE); |
48 | if (!skb) { | 48 | if (!skb) |
49 | ath10k_warn(ar, "Unable to allocate ctrl skb\n"); | ||
50 | return NULL; | 49 | return NULL; |
51 | } | ||
52 | 50 | ||
53 | skb_reserve(skb, 20); /* FIXME: why 20 bytes? */ | 51 | skb_reserve(skb, 20); /* FIXME: why 20 bytes? */ |
54 | WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); | 52 | WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); |
@@ -569,7 +567,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc) | |||
569 | ath10k_hif_send_complete_check(htc->ar, i, 1); | 567 | ath10k_hif_send_complete_check(htc->ar, i, 1); |
570 | 568 | ||
571 | status = wait_for_completion_timeout(&htc->ctl_resp, | 569 | status = wait_for_completion_timeout(&htc->ctl_resp, |
572 | ATH10K_HTC_WAIT_TIMEOUT_HZ); | 570 | ATH10K_HTC_WAIT_TIMEOUT_HZ); |
573 | 571 | ||
574 | if (status == 0) | 572 | if (status == 0) |
575 | status = -ETIMEDOUT; | 573 | status = -ETIMEDOUT; |
@@ -806,10 +804,8 @@ struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size) | |||
806 | struct sk_buff *skb; | 804 | struct sk_buff *skb; |
807 | 805 | ||
808 | skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr)); | 806 | skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr)); |
809 | if (!skb) { | 807 | if (!skb) |
810 | ath10k_warn(ar, "could not allocate HTC tx skb\n"); | ||
811 | return NULL; | 808 | return NULL; |
812 | } | ||
813 | 809 | ||
814 | skb_reserve(skb, sizeof(struct ath10k_htc_hdr)); | 810 | skb_reserve(skb, sizeof(struct ath10k_htc_hdr)); |
815 | 811 | ||
diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h index bf532f671189..527179c0edce 100644 --- a/drivers/net/wireless/ath/ath10k/htc.h +++ b/drivers/net/wireless/ath/ath10k/htc.h | |||
@@ -214,7 +214,6 @@ struct ath10k_htc_frame { | |||
214 | struct ath10k_htc_record trailer[0]; | 214 | struct ath10k_htc_record trailer[0]; |
215 | } __packed __aligned(4); | 215 | } __packed __aligned(4); |
216 | 216 | ||
217 | |||
218 | /*******************/ | 217 | /*******************/ |
219 | /* Host-side stuff */ | 218 | /* Host-side stuff */ |
220 | /*******************/ | 219 | /*******************/ |
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 87daae11f116..56cb4aceb383 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c | |||
@@ -101,7 +101,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt) | |||
101 | return status; | 101 | return status; |
102 | 102 | ||
103 | status = wait_for_completion_timeout(&htt->target_version_received, | 103 | status = wait_for_completion_timeout(&htt->target_version_received, |
104 | HTT_TARGET_VERSION_TIMEOUT_HZ); | 104 | HTT_TARGET_VERSION_TIMEOUT_HZ); |
105 | if (status <= 0) { | 105 | if (status <= 0) { |
106 | ath10k_warn(ar, "htt version request timed out\n"); | 106 | ath10k_warn(ar, "htt version request timed out\n"); |
107 | return -ETIMEDOUT; | 107 | return -ETIMEDOUT; |
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 6c93f3885ee5..3b44217a6c19 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h | |||
@@ -265,7 +265,6 @@ enum htt_mgmt_tx_status { | |||
265 | 265 | ||
266 | /*=== target -> host messages ===============================================*/ | 266 | /*=== target -> host messages ===============================================*/ |
267 | 267 | ||
268 | |||
269 | enum htt_t2h_msg_type { | 268 | enum htt_t2h_msg_type { |
270 | HTT_T2H_MSG_TYPE_VERSION_CONF = 0x0, | 269 | HTT_T2H_MSG_TYPE_VERSION_CONF = 0x0, |
271 | HTT_T2H_MSG_TYPE_RX_IND = 0x1, | 270 | HTT_T2H_MSG_TYPE_RX_IND = 0x1, |
@@ -1032,6 +1031,7 @@ static inline struct htt_stats_conf_item *htt_stats_conf_next_item( | |||
1032 | { | 1031 | { |
1033 | return (void *)item + sizeof(*item) + roundup(item->length, 4); | 1032 | return (void *)item + sizeof(*item) + roundup(item->length, 4); |
1034 | } | 1033 | } |
1034 | |||
1035 | /* | 1035 | /* |
1036 | * host -> target FRAG DESCRIPTOR/MSDU_EXT DESC bank | 1036 | * host -> target FRAG DESCRIPTOR/MSDU_EXT DESC bank |
1037 | * | 1037 | * |
@@ -1148,7 +1148,6 @@ struct htt_resp { | |||
1148 | }; | 1148 | }; |
1149 | } __packed; | 1149 | } __packed; |
1150 | 1150 | ||
1151 | |||
1152 | /*** host side structures follow ***/ | 1151 | /*** host side structures follow ***/ |
1153 | 1152 | ||
1154 | struct htt_tx_done { | 1153 | struct htt_tx_done { |
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 30927b1d7109..60d40a04508b 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c | |||
@@ -42,7 +42,6 @@ | |||
42 | /* when under memory pressure rx ring refill may fail and needs a retry */ | 42 | /* when under memory pressure rx ring refill may fail and needs a retry */ |
43 | #define HTT_RX_RING_REFILL_RETRY_MS 50 | 43 | #define HTT_RX_RING_REFILL_RETRY_MS 50 |
44 | 44 | ||
45 | |||
46 | static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); | 45 | static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); |
47 | static void ath10k_htt_txrx_compl_task(unsigned long ptr); | 46 | static void ath10k_htt_txrx_compl_task(unsigned long ptr); |
48 | 47 | ||
@@ -133,7 +132,7 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num) | |||
133 | dma_addr_t paddr; | 132 | dma_addr_t paddr; |
134 | int ret = 0, idx; | 133 | int ret = 0, idx; |
135 | 134 | ||
136 | idx = __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr)); | 135 | idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr); |
137 | while (num > 0) { | 136 | while (num > 0) { |
138 | skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN); | 137 | skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN); |
139 | if (!skb) { | 138 | if (!skb) { |
@@ -171,7 +170,7 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num) | |||
171 | } | 170 | } |
172 | 171 | ||
173 | fail: | 172 | fail: |
174 | *(htt->rx_ring.alloc_idx.vaddr) = __cpu_to_le32(idx); | 173 | *htt->rx_ring.alloc_idx.vaddr = __cpu_to_le32(idx); |
175 | return ret; | 174 | return ret; |
176 | } | 175 | } |
177 | 176 | ||
@@ -223,6 +222,7 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt) | |||
223 | static void ath10k_htt_rx_ring_refill_retry(unsigned long arg) | 222 | static void ath10k_htt_rx_ring_refill_retry(unsigned long arg) |
224 | { | 223 | { |
225 | struct ath10k_htt *htt = (struct ath10k_htt *)arg; | 224 | struct ath10k_htt *htt = (struct ath10k_htt *)arg; |
225 | |||
226 | ath10k_htt_rx_msdu_buff_replenish(htt); | 226 | ath10k_htt_rx_msdu_buff_replenish(htt); |
227 | } | 227 | } |
228 | 228 | ||
@@ -314,7 +314,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
314 | { | 314 | { |
315 | struct ath10k *ar = htt->ar; | 315 | struct ath10k *ar = htt->ar; |
316 | int msdu_len, msdu_chaining = 0; | 316 | int msdu_len, msdu_chaining = 0; |
317 | struct sk_buff *msdu; | 317 | struct sk_buff *msdu, *next; |
318 | struct htt_rx_desc *rx_desc; | 318 | struct htt_rx_desc *rx_desc; |
319 | 319 | ||
320 | lockdep_assert_held(&htt->rx_ring.lock); | 320 | lockdep_assert_held(&htt->rx_ring.lock); |
@@ -450,11 +450,11 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
450 | if (last_msdu) { | 450 | if (last_msdu) { |
451 | msdu->next = NULL; | 451 | msdu->next = NULL; |
452 | break; | 452 | break; |
453 | } else { | ||
454 | struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt); | ||
455 | msdu->next = next; | ||
456 | msdu = next; | ||
457 | } | 453 | } |
454 | |||
455 | next = ath10k_htt_rx_netbuf_pop(htt); | ||
456 | msdu->next = next; | ||
457 | msdu = next; | ||
458 | } | 458 | } |
459 | *tail_msdu = msdu; | 459 | *tail_msdu = msdu; |
460 | 460 | ||
@@ -480,6 +480,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | |||
480 | static void ath10k_htt_rx_replenish_task(unsigned long ptr) | 480 | static void ath10k_htt_rx_replenish_task(unsigned long ptr) |
481 | { | 481 | { |
482 | struct ath10k_htt *htt = (struct ath10k_htt *)ptr; | 482 | struct ath10k_htt *htt = (struct ath10k_htt *)ptr; |
483 | |||
483 | ath10k_htt_rx_msdu_buff_replenish(htt); | 484 | ath10k_htt_rx_msdu_buff_replenish(htt); |
484 | } | 485 | } |
485 | 486 | ||
@@ -488,6 +489,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) | |||
488 | struct ath10k *ar = htt->ar; | 489 | struct ath10k *ar = htt->ar; |
489 | dma_addr_t paddr; | 490 | dma_addr_t paddr; |
490 | void *vaddr; | 491 | void *vaddr; |
492 | size_t size; | ||
491 | struct timer_list *timer = &htt->rx_ring.refill_retry_timer; | 493 | struct timer_list *timer = &htt->rx_ring.refill_retry_timer; |
492 | 494 | ||
493 | htt->rx_ring.size = ath10k_htt_rx_ring_size(htt); | 495 | htt->rx_ring.size = ath10k_htt_rx_ring_size(htt); |
@@ -515,9 +517,9 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) | |||
515 | if (!htt->rx_ring.netbufs_ring) | 517 | if (!htt->rx_ring.netbufs_ring) |
516 | goto err_netbuf; | 518 | goto err_netbuf; |
517 | 519 | ||
518 | vaddr = dma_alloc_coherent(htt->ar->dev, | 520 | size = htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring); |
519 | (htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring)), | 521 | |
520 | &paddr, GFP_DMA); | 522 | vaddr = dma_alloc_coherent(htt->ar->dev, size, &paddr, GFP_DMA); |
521 | if (!vaddr) | 523 | if (!vaddr) |
522 | goto err_dma_ring; | 524 | goto err_dma_ring; |
523 | 525 | ||
@@ -625,19 +627,21 @@ static struct ieee80211_hdr *ath10k_htt_rx_skb_get_hdr(struct sk_buff *skb) | |||
625 | 627 | ||
626 | rxd = (void *)skb->data - sizeof(*rxd); | 628 | rxd = (void *)skb->data - sizeof(*rxd); |
627 | fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), | 629 | fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), |
628 | RX_MSDU_START_INFO1_DECAP_FORMAT); | 630 | RX_MSDU_START_INFO1_DECAP_FORMAT); |
629 | 631 | ||
630 | if (fmt == RX_MSDU_DECAP_RAW) | 632 | if (fmt == RX_MSDU_DECAP_RAW) |
631 | return (void *)skb->data; | 633 | return (void *)skb->data; |
632 | else | 634 | |
633 | return (void *)skb->data - RX_HTT_HDR_STATUS_LEN; | 635 | return (void *)skb->data - RX_HTT_HDR_STATUS_LEN; |
634 | } | 636 | } |
635 | 637 | ||
636 | /* This function only applies for first msdu in an msdu chain */ | 638 | /* This function only applies for first msdu in an msdu chain */ |
637 | static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr) | 639 | static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr) |
638 | { | 640 | { |
641 | u8 *qc; | ||
642 | |||
639 | if (ieee80211_is_data_qos(hdr->frame_control)) { | 643 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
640 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 644 | qc = ieee80211_get_qos_ctl(hdr); |
641 | if (qc[0] & 0x80) | 645 | if (qc[0] & 0x80) |
642 | return true; | 646 | return true; |
643 | } | 647 | } |
@@ -914,7 +918,7 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
914 | 918 | ||
915 | rxd = (void *)skb->data - sizeof(*rxd); | 919 | rxd = (void *)skb->data - sizeof(*rxd); |
916 | enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), | 920 | enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), |
917 | RX_MPDU_START_INFO0_ENCRYPT_TYPE); | 921 | RX_MPDU_START_INFO0_ENCRYPT_TYPE); |
918 | 922 | ||
919 | hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; | 923 | hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; |
920 | hdr_len = ieee80211_hdrlen(hdr->frame_control); | 924 | hdr_len = ieee80211_hdrlen(hdr->frame_control); |
@@ -950,8 +954,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
950 | /* pull decapped header and copy SA & DA */ | 954 | /* pull decapped header and copy SA & DA */ |
951 | hdr = (struct ieee80211_hdr *)skb->data; | 955 | hdr = (struct ieee80211_hdr *)skb->data; |
952 | hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); | 956 | hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); |
953 | memcpy(da, ieee80211_get_DA(hdr), ETH_ALEN); | 957 | ether_addr_copy(da, ieee80211_get_DA(hdr)); |
954 | memcpy(sa, ieee80211_get_SA(hdr), ETH_ALEN); | 958 | ether_addr_copy(sa, ieee80211_get_SA(hdr)); |
955 | skb_pull(skb, hdr_len); | 959 | skb_pull(skb, hdr_len); |
956 | 960 | ||
957 | /* push original 802.11 header */ | 961 | /* push original 802.11 header */ |
@@ -968,8 +972,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, | |||
968 | /* original 802.11 header has a different DA and in | 972 | /* original 802.11 header has a different DA and in |
969 | * case of 4addr it may also have different SA | 973 | * case of 4addr it may also have different SA |
970 | */ | 974 | */ |
971 | memcpy(ieee80211_get_DA(hdr), da, ETH_ALEN); | 975 | ether_addr_copy(ieee80211_get_DA(hdr), da); |
972 | memcpy(ieee80211_get_SA(hdr), sa, ETH_ALEN); | 976 | ether_addr_copy(ieee80211_get_SA(hdr), sa); |
973 | break; | 977 | break; |
974 | case RX_MSDU_DECAP_ETHERNET2_DIX: | 978 | case RX_MSDU_DECAP_ETHERNET2_DIX: |
975 | /* strip ethernet header and insert decapped 802.11 | 979 | /* strip ethernet header and insert decapped 802.11 |
@@ -1029,9 +1033,9 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, | |||
1029 | 1033 | ||
1030 | rxd = (void *)skb->data - sizeof(*rxd); | 1034 | rxd = (void *)skb->data - sizeof(*rxd); |
1031 | fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), | 1035 | fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), |
1032 | RX_MSDU_START_INFO1_DECAP_FORMAT); | 1036 | RX_MSDU_START_INFO1_DECAP_FORMAT); |
1033 | enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), | 1037 | enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), |
1034 | RX_MPDU_START_INFO0_ENCRYPT_TYPE); | 1038 | RX_MPDU_START_INFO0_ENCRYPT_TYPE); |
1035 | hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; | 1039 | hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; |
1036 | hdr_len = ieee80211_hdrlen(hdr->frame_control); | 1040 | hdr_len = ieee80211_hdrlen(hdr->frame_control); |
1037 | 1041 | ||
@@ -1332,7 +1336,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, | |||
1332 | } | 1336 | } |
1333 | 1337 | ||
1334 | static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | 1338 | static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, |
1335 | struct htt_rx_fragment_indication *frag) | 1339 | struct htt_rx_fragment_indication *frag) |
1336 | { | 1340 | { |
1337 | struct ath10k *ar = htt->ar; | 1341 | struct ath10k *ar = htt->ar; |
1338 | struct sk_buff *msdu_head, *msdu_tail; | 1342 | struct sk_buff *msdu_head, *msdu_tail; |
@@ -1378,7 +1382,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, | |||
1378 | tkip_mic_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR); | 1382 | tkip_mic_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR); |
1379 | decrypt_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR); | 1383 | decrypt_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR); |
1380 | fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), | 1384 | fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), |
1381 | RX_MSDU_START_INFO1_DECAP_FORMAT); | 1385 | RX_MSDU_START_INFO1_DECAP_FORMAT); |
1382 | 1386 | ||
1383 | if (fmt != RX_MSDU_DECAP_RAW) { | 1387 | if (fmt != RX_MSDU_DECAP_RAW) { |
1384 | ath10k_warn(ar, "we dont support non-raw fragmented rx yet\n"); | 1388 | ath10k_warn(ar, "we dont support non-raw fragmented rx yet\n"); |
@@ -1654,7 +1658,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) | |||
1654 | /* FIX THIS */ | 1658 | /* FIX THIS */ |
1655 | break; | 1659 | break; |
1656 | case HTT_T2H_MSG_TYPE_STATS_CONF: | 1660 | case HTT_T2H_MSG_TYPE_STATS_CONF: |
1657 | trace_ath10k_htt_stats(skb->data, skb->len); | 1661 | trace_ath10k_htt_stats(ar, skb->data, skb->len); |
1658 | break; | 1662 | break; |
1659 | case HTT_T2H_MSG_TYPE_TX_INSPECT_IND: | 1663 | case HTT_T2H_MSG_TYPE_TX_INSPECT_IND: |
1660 | /* Firmware can return tx frames if it's unable to fully | 1664 | /* Firmware can return tx frames if it's unable to fully |
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index eaa73aa99c20..bd87a35201d8 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c | |||
@@ -154,7 +154,6 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt) | |||
154 | kfree(htt->pending_tx); | 154 | kfree(htt->pending_tx); |
155 | kfree(htt->used_msdu_ids); | 155 | kfree(htt->used_msdu_ids); |
156 | dma_pool_destroy(htt->tx_pool); | 156 | dma_pool_destroy(htt->tx_pool); |
157 | return; | ||
158 | } | 157 | } |
159 | 158 | ||
160 | void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) | 159 | void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) |
@@ -377,7 +376,6 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) | |||
377 | int msdu_id = -1; | 376 | int msdu_id = -1; |
378 | int res; | 377 | int res; |
379 | 378 | ||
380 | |||
381 | res = ath10k_htt_tx_inc_pending(htt); | 379 | res = ath10k_htt_tx_inc_pending(htt); |
382 | if (res) | 380 | if (res) |
383 | goto err; | 381 | goto err; |
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 13568b01de9f..3cf5702c1e7e 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h | |||
@@ -36,6 +36,8 @@ | |||
36 | #define ATH10K_FW_API2_FILE "firmware-2.bin" | 36 | #define ATH10K_FW_API2_FILE "firmware-2.bin" |
37 | #define ATH10K_FW_API3_FILE "firmware-3.bin" | 37 | #define ATH10K_FW_API3_FILE "firmware-3.bin" |
38 | 38 | ||
39 | #define ATH10K_FW_UTF_FILE "utf.bin" | ||
40 | |||
39 | /* includes also the null byte */ | 41 | /* includes also the null byte */ |
40 | #define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K" | 42 | #define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K" |
41 | 43 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 1f35bd1ef563..46709301a51e 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "wmi.h" | 26 | #include "wmi.h" |
27 | #include "htt.h" | 27 | #include "htt.h" |
28 | #include "txrx.h" | 28 | #include "txrx.h" |
29 | #include "testmode.h" | ||
29 | 30 | ||
30 | /**********/ | 31 | /**********/ |
31 | /* Crypto */ | 32 | /* Crypto */ |
@@ -198,7 +199,7 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, | |||
198 | list_for_each_entry(peer, &ar->peers, list) { | 199 | list_for_each_entry(peer, &ar->peers, list) { |
199 | for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { | 200 | for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { |
200 | if (peer->keys[i] == key) { | 201 | if (peer->keys[i] == key) { |
201 | memcpy(addr, peer->addr, ETH_ALEN); | 202 | ether_addr_copy(addr, peer->addr); |
202 | peer->keys[i] = NULL; | 203 | peer->keys[i] = NULL; |
203 | break; | 204 | break; |
204 | } | 205 | } |
@@ -224,7 +225,6 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, | |||
224 | return first_errno; | 225 | return first_errno; |
225 | } | 226 | } |
226 | 227 | ||
227 | |||
228 | /*********************/ | 228 | /*********************/ |
229 | /* General utilities */ | 229 | /* General utilities */ |
230 | /*********************/ | 230 | /*********************/ |
@@ -493,19 +493,6 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) | |||
493 | return 0; | 493 | return 0; |
494 | } | 494 | } |
495 | 495 | ||
496 | static bool ath10k_monitor_is_enabled(struct ath10k *ar) | ||
497 | { | ||
498 | lockdep_assert_held(&ar->conf_mutex); | ||
499 | |||
500 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
501 | "mac monitor refs: promisc %d monitor %d cac %d\n", | ||
502 | ar->promisc, ar->monitor, | ||
503 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)); | ||
504 | |||
505 | return ar->promisc || ar->monitor || | ||
506 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | ||
507 | } | ||
508 | |||
509 | static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) | 496 | static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) |
510 | { | 497 | { |
511 | struct cfg80211_chan_def *chandef = &ar->chandef; | 498 | struct cfg80211_chan_def *chandef = &ar->chandef; |
@@ -649,16 +636,6 @@ static int ath10k_monitor_start(struct ath10k *ar) | |||
649 | 636 | ||
650 | lockdep_assert_held(&ar->conf_mutex); | 637 | lockdep_assert_held(&ar->conf_mutex); |
651 | 638 | ||
652 | if (!ath10k_monitor_is_enabled(ar)) { | ||
653 | ath10k_warn(ar, "trying to start monitor with no references\n"); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | if (ar->monitor_started) { | ||
658 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor already started\n"); | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | ret = ath10k_monitor_vdev_create(ar); | 639 | ret = ath10k_monitor_vdev_create(ar); |
663 | if (ret) { | 640 | if (ret) { |
664 | ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret); | 641 | ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret); |
@@ -678,34 +655,51 @@ static int ath10k_monitor_start(struct ath10k *ar) | |||
678 | return 0; | 655 | return 0; |
679 | } | 656 | } |
680 | 657 | ||
681 | static void ath10k_monitor_stop(struct ath10k *ar) | 658 | static int ath10k_monitor_stop(struct ath10k *ar) |
682 | { | 659 | { |
683 | int ret; | 660 | int ret; |
684 | 661 | ||
685 | lockdep_assert_held(&ar->conf_mutex); | 662 | lockdep_assert_held(&ar->conf_mutex); |
686 | 663 | ||
687 | if (ath10k_monitor_is_enabled(ar)) { | ||
688 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
689 | "mac monitor will be stopped later\n"); | ||
690 | return; | ||
691 | } | ||
692 | |||
693 | if (!ar->monitor_started) { | ||
694 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
695 | "mac monitor probably failed to start earlier\n"); | ||
696 | return; | ||
697 | } | ||
698 | |||
699 | ret = ath10k_monitor_vdev_stop(ar); | 664 | ret = ath10k_monitor_vdev_stop(ar); |
700 | if (ret) | 665 | if (ret) { |
701 | ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret); | 666 | ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret); |
667 | return ret; | ||
668 | } | ||
702 | 669 | ||
703 | ret = ath10k_monitor_vdev_delete(ar); | 670 | ret = ath10k_monitor_vdev_delete(ar); |
704 | if (ret) | 671 | if (ret) { |
705 | ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret); | 672 | ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret); |
673 | return ret; | ||
674 | } | ||
706 | 675 | ||
707 | ar->monitor_started = false; | 676 | ar->monitor_started = false; |
708 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n"); | 677 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n"); |
678 | |||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | static int ath10k_monitor_recalc(struct ath10k *ar) | ||
683 | { | ||
684 | bool should_start; | ||
685 | |||
686 | lockdep_assert_held(&ar->conf_mutex); | ||
687 | |||
688 | should_start = ar->monitor || | ||
689 | ar->filter_flags & FIF_PROMISC_IN_BSS || | ||
690 | test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | ||
691 | |||
692 | ath10k_dbg(ar, ATH10K_DBG_MAC, | ||
693 | "mac monitor recalc started? %d should? %d\n", | ||
694 | ar->monitor_started, should_start); | ||
695 | |||
696 | if (should_start == ar->monitor_started) | ||
697 | return 0; | ||
698 | |||
699 | if (should_start) | ||
700 | return ath10k_monitor_start(ar); | ||
701 | |||
702 | return ath10k_monitor_stop(ar); | ||
709 | } | 703 | } |
710 | 704 | ||
711 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) | 705 | static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) |
@@ -736,7 +730,7 @@ static int ath10k_start_cac(struct ath10k *ar) | |||
736 | 730 | ||
737 | set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 731 | set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
738 | 732 | ||
739 | ret = ath10k_monitor_start(ar); | 733 | ret = ath10k_monitor_recalc(ar); |
740 | if (ret) { | 734 | if (ret) { |
741 | ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret); | 735 | ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret); |
742 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 736 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
@@ -901,7 +895,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) | |||
901 | } | 895 | } |
902 | 896 | ||
903 | static void ath10k_control_beaconing(struct ath10k_vif *arvif, | 897 | static void ath10k_control_beaconing(struct ath10k_vif *arvif, |
904 | struct ieee80211_bss_conf *info) | 898 | struct ieee80211_bss_conf *info) |
905 | { | 899 | { |
906 | struct ath10k *ar = arvif->ar; | 900 | struct ath10k *ar = arvif->ar; |
907 | int ret = 0; | 901 | int ret = 0; |
@@ -936,7 +930,7 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif, | |||
936 | return; | 930 | return; |
937 | 931 | ||
938 | arvif->aid = 0; | 932 | arvif->aid = 0; |
939 | memcpy(arvif->bssid, info->bssid, ETH_ALEN); | 933 | ether_addr_copy(arvif->bssid, info->bssid); |
940 | 934 | ||
941 | ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, | 935 | ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, |
942 | arvif->bssid); | 936 | arvif->bssid); |
@@ -1056,7 +1050,7 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar, | |||
1056 | { | 1050 | { |
1057 | lockdep_assert_held(&ar->conf_mutex); | 1051 | lockdep_assert_held(&ar->conf_mutex); |
1058 | 1052 | ||
1059 | memcpy(arg->addr, sta->addr, ETH_ALEN); | 1053 | ether_addr_copy(arg->addr, sta->addr); |
1060 | arg->vdev_id = arvif->vdev_id; | 1054 | arg->vdev_id = arvif->vdev_id; |
1061 | arg->peer_aid = sta->aid; | 1055 | arg->peer_aid = sta->aid; |
1062 | arg->peer_flags |= WMI_PEER_AUTH; | 1056 | arg->peer_flags |= WMI_PEER_AUTH; |
@@ -1111,9 +1105,9 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar, | |||
1111 | ies = rcu_dereference(bss->ies); | 1105 | ies = rcu_dereference(bss->ies); |
1112 | 1106 | ||
1113 | wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, | 1107 | wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, |
1114 | WLAN_OUI_TYPE_MICROSOFT_WPA, | 1108 | WLAN_OUI_TYPE_MICROSOFT_WPA, |
1115 | ies->data, | 1109 | ies->data, |
1116 | ies->len); | 1110 | ies->len); |
1117 | rcu_read_unlock(); | 1111 | rcu_read_unlock(); |
1118 | cfg80211_put_bss(ar->hw->wiphy, bss); | 1112 | cfg80211_put_bss(ar->hw->wiphy, bss); |
1119 | } | 1113 | } |
@@ -1163,6 +1157,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, | |||
1163 | { | 1157 | { |
1164 | const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; | 1158 | const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; |
1165 | int i, n; | 1159 | int i, n; |
1160 | u32 stbc; | ||
1166 | 1161 | ||
1167 | lockdep_assert_held(&ar->conf_mutex); | 1162 | lockdep_assert_held(&ar->conf_mutex); |
1168 | 1163 | ||
@@ -1199,7 +1194,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, | |||
1199 | } | 1194 | } |
1200 | 1195 | ||
1201 | if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) { | 1196 | if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) { |
1202 | u32 stbc; | ||
1203 | stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC; | 1197 | stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC; |
1204 | stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT; | 1198 | stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT; |
1205 | stbc = stbc << WMI_RC_RX_STBC_FLAG_S; | 1199 | stbc = stbc << WMI_RC_RX_STBC_FLAG_S; |
@@ -1267,7 +1261,6 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar, | |||
1267 | uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN | | 1261 | uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN | |
1268 | WMI_AP_PS_UAPSD_AC0_TRIGGER_EN; | 1262 | WMI_AP_PS_UAPSD_AC0_TRIGGER_EN; |
1269 | 1263 | ||
1270 | |||
1271 | if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP) | 1264 | if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP) |
1272 | max_sp = sta->max_sp; | 1265 | max_sp = sta->max_sp; |
1273 | 1266 | ||
@@ -1296,7 +1289,8 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar, | |||
1296 | sta->listen_interval - mac80211 patch required. | 1289 | sta->listen_interval - mac80211 patch required. |
1297 | Currently use 10 seconds */ | 1290 | Currently use 10 seconds */ |
1298 | ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr, | 1291 | ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr, |
1299 | WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 10); | 1292 | WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, |
1293 | 10); | ||
1300 | if (ret) { | 1294 | if (ret) { |
1301 | ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n", | 1295 | ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n", |
1302 | arvif->vdev_id, ret); | 1296 | arvif->vdev_id, ret); |
@@ -1320,7 +1314,6 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, | |||
1320 | arg->peer_flags |= WMI_PEER_VHT; | 1314 | arg->peer_flags |= WMI_PEER_VHT; |
1321 | arg->peer_vht_caps = vht_cap->cap; | 1315 | arg->peer_vht_caps = vht_cap->cap; |
1322 | 1316 | ||
1323 | |||
1324 | ampdu_factor = (vht_cap->cap & | 1317 | ampdu_factor = (vht_cap->cap & |
1325 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >> | 1318 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >> |
1326 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; | 1319 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; |
@@ -1531,7 +1524,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, | |||
1531 | arvif->vdev_id, bss_conf->bssid, bss_conf->aid); | 1524 | arvif->vdev_id, bss_conf->bssid, bss_conf->aid); |
1532 | 1525 | ||
1533 | arvif->aid = bss_conf->aid; | 1526 | arvif->aid = bss_conf->aid; |
1534 | memcpy(arvif->bssid, bss_conf->bssid, ETH_ALEN); | 1527 | ether_addr_copy(arvif->bssid, bss_conf->bssid); |
1535 | 1528 | ||
1536 | ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); | 1529 | ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); |
1537 | if (ret) { | 1530 | if (ret) { |
@@ -1615,7 +1608,7 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, | |||
1615 | return ret; | 1608 | return ret; |
1616 | } | 1609 | } |
1617 | 1610 | ||
1618 | if (!sta->wme) { | 1611 | if (!sta->wme && !reassoc) { |
1619 | arvif->num_legacy_stations++; | 1612 | arvif->num_legacy_stations++; |
1620 | ret = ath10k_recalc_rtscts_prot(arvif); | 1613 | ret = ath10k_recalc_rtscts_prot(arvif); |
1621 | if (ret) { | 1614 | if (ret) { |
@@ -1863,11 +1856,10 @@ static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr) | |||
1863 | return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; | 1856 | return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; |
1864 | } | 1857 | } |
1865 | 1858 | ||
1866 | static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, | 1859 | static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif) |
1867 | struct ieee80211_tx_info *info) | ||
1868 | { | 1860 | { |
1869 | if (info->control.vif) | 1861 | if (vif) |
1870 | return ath10k_vif_to_arvif(info->control.vif)->vdev_id; | 1862 | return ath10k_vif_to_arvif(vif)->vdev_id; |
1871 | 1863 | ||
1872 | if (ar->monitor_started) | 1864 | if (ar->monitor_started) |
1873 | return ar->monitor_vdev_id; | 1865 | return ar->monitor_vdev_id; |
@@ -2323,7 +2315,7 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
2323 | 2315 | ||
2324 | ATH10K_SKB_CB(skb)->htt.is_offchan = false; | 2316 | ATH10K_SKB_CB(skb)->htt.is_offchan = false; |
2325 | ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr); | 2317 | ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr); |
2326 | ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, info); | 2318 | ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif); |
2327 | 2319 | ||
2328 | /* it makes no sense to process injected frames like that */ | 2320 | /* it makes no sense to process injected frames like that */ |
2329 | if (vif && vif->type != NL80211_IFTYPE_MONITOR) { | 2321 | if (vif && vif->type != NL80211_IFTYPE_MONITOR) { |
@@ -2369,12 +2361,14 @@ void ath10k_halt(struct ath10k *ar) | |||
2369 | 2361 | ||
2370 | lockdep_assert_held(&ar->conf_mutex); | 2362 | lockdep_assert_held(&ar->conf_mutex); |
2371 | 2363 | ||
2372 | if (ath10k_monitor_is_enabled(ar)) { | 2364 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); |
2373 | clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); | 2365 | ar->filter_flags = 0; |
2374 | ar->promisc = false; | 2366 | ar->monitor = false; |
2375 | ar->monitor = false; | 2367 | |
2368 | if (ar->monitor_started) | ||
2376 | ath10k_monitor_stop(ar); | 2369 | ath10k_monitor_stop(ar); |
2377 | } | 2370 | |
2371 | ar->monitor_started = false; | ||
2378 | 2372 | ||
2379 | ath10k_scan_finish(ar); | 2373 | ath10k_scan_finish(ar); |
2380 | ath10k_peer_cleanup_all(ar); | 2374 | ath10k_peer_cleanup_all(ar); |
@@ -2485,6 +2479,9 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
2485 | WARN_ON(1); | 2479 | WARN_ON(1); |
2486 | ret = -EINVAL; | 2480 | ret = -EINVAL; |
2487 | goto err; | 2481 | goto err; |
2482 | case ATH10K_STATE_UTF: | ||
2483 | ret = -EBUSY; | ||
2484 | goto err; | ||
2488 | } | 2485 | } |
2489 | 2486 | ||
2490 | ret = ath10k_hif_power_up(ar); | 2487 | ret = ath10k_hif_power_up(ar); |
@@ -2493,7 +2490,7 @@ static int ath10k_start(struct ieee80211_hw *hw) | |||
2493 | goto err_off; | 2490 | goto err_off; |
2494 | } | 2491 | } |
2495 | 2492 | ||
2496 | ret = ath10k_core_start(ar); | 2493 | ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); |
2497 | if (ret) { | 2494 | if (ret) { |
2498 | ath10k_err(ar, "Could not init core: %d\n", ret); | 2495 | ath10k_err(ar, "Could not init core: %d\n", ret); |
2499 | goto err_power_down; | 2496 | goto err_power_down; |
@@ -2629,7 +2626,7 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2629 | /* First stop monitor interface. Some FW versions crash if there's a | 2626 | /* First stop monitor interface. Some FW versions crash if there's a |
2630 | * lone monitor interface. */ | 2627 | * lone monitor interface. */ |
2631 | if (ar->monitor_started) | 2628 | if (ar->monitor_started) |
2632 | ath10k_monitor_vdev_stop(ar); | 2629 | ath10k_monitor_stop(ar); |
2633 | 2630 | ||
2634 | list_for_each_entry(arvif, &ar->arvifs, list) { | 2631 | list_for_each_entry(arvif, &ar->arvifs, list) { |
2635 | if (!arvif->is_started) | 2632 | if (!arvif->is_started) |
@@ -2677,8 +2674,7 @@ static void ath10k_config_chan(struct ath10k *ar) | |||
2677 | } | 2674 | } |
2678 | } | 2675 | } |
2679 | 2676 | ||
2680 | if (ath10k_monitor_is_enabled(ar)) | 2677 | ath10k_monitor_recalc(ar); |
2681 | ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); | ||
2682 | } | 2678 | } |
2683 | 2679 | ||
2684 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | 2680 | static int ath10k_config(struct ieee80211_hw *hw, u32 changed) |
@@ -2733,19 +2729,10 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) | |||
2733 | ath10k_config_ps(ar); | 2729 | ath10k_config_ps(ar); |
2734 | 2730 | ||
2735 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 2731 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
2736 | if (conf->flags & IEEE80211_CONF_MONITOR && !ar->monitor) { | 2732 | ar->monitor = conf->flags & IEEE80211_CONF_MONITOR; |
2737 | ar->monitor = true; | 2733 | ret = ath10k_monitor_recalc(ar); |
2738 | ret = ath10k_monitor_start(ar); | 2734 | if (ret) |
2739 | if (ret) { | 2735 | ath10k_warn(ar, "failed to recalc monitor: %d\n", ret); |
2740 | ath10k_warn(ar, "failed to start monitor (config): %d\n", | ||
2741 | ret); | ||
2742 | ar->monitor = false; | ||
2743 | } | ||
2744 | } else if (!(conf->flags & IEEE80211_CONF_MONITOR) && | ||
2745 | ar->monitor) { | ||
2746 | ar->monitor = false; | ||
2747 | ath10k_monitor_stop(ar); | ||
2748 | } | ||
2749 | } | 2736 | } |
2750 | 2737 | ||
2751 | mutex_unlock(&ar->conf_mutex); | 2738 | mutex_unlock(&ar->conf_mutex); |
@@ -3009,18 +2996,9 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw, | |||
3009 | *total_flags &= SUPPORTED_FILTERS; | 2996 | *total_flags &= SUPPORTED_FILTERS; |
3010 | ar->filter_flags = *total_flags; | 2997 | ar->filter_flags = *total_flags; |
3011 | 2998 | ||
3012 | if (ar->filter_flags & FIF_PROMISC_IN_BSS && !ar->promisc) { | 2999 | ret = ath10k_monitor_recalc(ar); |
3013 | ar->promisc = true; | 3000 | if (ret) |
3014 | ret = ath10k_monitor_start(ar); | 3001 | ath10k_warn(ar, "failed to recalc montior: %d\n", ret); |
3015 | if (ret) { | ||
3016 | ath10k_warn(ar, "failed to start monitor (promisc): %d\n", | ||
3017 | ret); | ||
3018 | ar->promisc = false; | ||
3019 | } | ||
3020 | } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && ar->promisc) { | ||
3021 | ar->promisc = false; | ||
3022 | ath10k_monitor_stop(ar); | ||
3023 | } | ||
3024 | 3002 | ||
3025 | mutex_unlock(&ar->conf_mutex); | 3003 | mutex_unlock(&ar->conf_mutex); |
3026 | } | 3004 | } |
@@ -3033,7 +3011,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3033 | struct ath10k *ar = hw->priv; | 3011 | struct ath10k *ar = hw->priv; |
3034 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 3012 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
3035 | int ret = 0; | 3013 | int ret = 0; |
3036 | u32 vdev_param, pdev_param; | 3014 | u32 vdev_param, pdev_param, slottime, preamble; |
3037 | 3015 | ||
3038 | mutex_lock(&ar->conf_mutex); | 3016 | mutex_lock(&ar->conf_mutex); |
3039 | 3017 | ||
@@ -3112,7 +3090,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3112 | * this is never erased as we it for crypto key | 3090 | * this is never erased as we it for crypto key |
3113 | * clearing; this is FW requirement | 3091 | * clearing; this is FW requirement |
3114 | */ | 3092 | */ |
3115 | memcpy(arvif->bssid, info->bssid, ETH_ALEN); | 3093 | ether_addr_copy(arvif->bssid, info->bssid); |
3116 | 3094 | ||
3117 | ath10k_dbg(ar, ATH10K_DBG_MAC, | 3095 | ath10k_dbg(ar, ATH10K_DBG_MAC, |
3118 | "mac vdev %d start %pM\n", | 3096 | "mac vdev %d start %pM\n", |
@@ -3154,7 +3132,6 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3154 | } | 3132 | } |
3155 | 3133 | ||
3156 | if (changed & BSS_CHANGED_ERP_SLOT) { | 3134 | if (changed & BSS_CHANGED_ERP_SLOT) { |
3157 | u32 slottime; | ||
3158 | if (info->use_short_slot) | 3135 | if (info->use_short_slot) |
3159 | slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */ | 3136 | slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */ |
3160 | 3137 | ||
@@ -3173,7 +3150,6 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3173 | } | 3150 | } |
3174 | 3151 | ||
3175 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 3152 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
3176 | u32 preamble; | ||
3177 | if (info->use_short_preamble) | 3153 | if (info->use_short_preamble) |
3178 | preamble = WMI_VDEV_PREAMBLE_SHORT; | 3154 | preamble = WMI_VDEV_PREAMBLE_SHORT; |
3179 | else | 3155 | else |
@@ -3192,8 +3168,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
3192 | } | 3168 | } |
3193 | 3169 | ||
3194 | if (changed & BSS_CHANGED_ASSOC) { | 3170 | if (changed & BSS_CHANGED_ASSOC) { |
3195 | if (info->assoc) | 3171 | if (info->assoc) { |
3172 | /* Workaround: Make sure monitor vdev is not running | ||
3173 | * when associating to prevent some firmware revisions | ||
3174 | * (e.g. 10.1 and 10.2) from crashing. | ||
3175 | */ | ||
3176 | if (ar->monitor_started) | ||
3177 | ath10k_monitor_stop(ar); | ||
3196 | ath10k_bss_assoc(hw, vif, info); | 3178 | ath10k_bss_assoc(hw, vif, info); |
3179 | ath10k_monitor_recalc(ar); | ||
3180 | } | ||
3197 | } | 3181 | } |
3198 | 3182 | ||
3199 | exit: | 3183 | exit: |
@@ -3580,7 +3564,7 @@ exit: | |||
3580 | } | 3564 | } |
3581 | 3565 | ||
3582 | static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif, | 3566 | static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif, |
3583 | u16 ac, bool enable) | 3567 | u16 ac, bool enable) |
3584 | { | 3568 | { |
3585 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 3569 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
3586 | u32 value = 0; | 3570 | u32 value = 0; |
@@ -4081,8 +4065,8 @@ ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask, | |||
4081 | continue; | 4065 | continue; |
4082 | else if (mask->control[band].ht_mcs[i] == 0x00) | 4066 | else if (mask->control[band].ht_mcs[i] == 0x00) |
4083 | break; | 4067 | break; |
4084 | else | 4068 | |
4085 | return false; | 4069 | return false; |
4086 | } | 4070 | } |
4087 | 4071 | ||
4088 | ht_nss = i; | 4072 | ht_nss = i; |
@@ -4093,8 +4077,8 @@ ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask, | |||
4093 | continue; | 4077 | continue; |
4094 | else if (mask->control[band].vht_mcs[i] == 0x0000) | 4078 | else if (mask->control[band].vht_mcs[i] == 0x0000) |
4095 | break; | 4079 | break; |
4096 | else | 4080 | |
4097 | return false; | 4081 | return false; |
4098 | } | 4082 | } |
4099 | 4083 | ||
4100 | vht_nss = i; | 4084 | vht_nss = i; |
@@ -4472,6 +4456,9 @@ static const struct ieee80211_ops ath10k_ops = { | |||
4472 | .sta_rc_update = ath10k_sta_rc_update, | 4456 | .sta_rc_update = ath10k_sta_rc_update, |
4473 | .get_tsf = ath10k_get_tsf, | 4457 | .get_tsf = ath10k_get_tsf, |
4474 | .ampdu_action = ath10k_ampdu_action, | 4458 | .ampdu_action = ath10k_ampdu_action, |
4459 | |||
4460 | CFG80211_TESTMODE_CMD(ath10k_tm_cmd) | ||
4461 | |||
4475 | #ifdef CONFIG_PM | 4462 | #ifdef CONFIG_PM |
4476 | .suspend = ath10k_suspend, | 4463 | .suspend = ath10k_suspend, |
4477 | .resume = ath10k_resume, | 4464 | .resume = ath10k_resume, |
@@ -4723,7 +4710,6 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar) | |||
4723 | return ht_cap; | 4710 | return ht_cap; |
4724 | } | 4711 | } |
4725 | 4712 | ||
4726 | |||
4727 | static void ath10k_get_arvif_iter(void *data, u8 *mac, | 4713 | static void ath10k_get_arvif_iter(void *data, u8 *mac, |
4728 | struct ieee80211_vif *vif) | 4714 | struct ieee80211_vif *vif) |
4729 | { | 4715 | { |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 056a35a77133..59e0ea83be50 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
@@ -64,9 +64,6 @@ static const struct pci_device_id ath10k_pci_id_table[] = { | |||
64 | {0} | 64 | {0} |
65 | }; | 65 | }; |
66 | 66 | ||
67 | static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, | ||
68 | u32 *data); | ||
69 | |||
70 | static void ath10k_pci_buffer_cleanup(struct ath10k *ar); | 67 | static void ath10k_pci_buffer_cleanup(struct ath10k *ar); |
71 | static int ath10k_pci_cold_reset(struct ath10k *ar); | 68 | static int ath10k_pci_cold_reset(struct ath10k *ar); |
72 | static int ath10k_pci_warm_reset(struct ath10k *ar); | 69 | static int ath10k_pci_warm_reset(struct ath10k *ar); |
@@ -343,8 +340,8 @@ static void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar) | |||
343 | 340 | ||
344 | /* IMPORTANT: this extra read transaction is required to | 341 | /* IMPORTANT: this extra read transaction is required to |
345 | * flush the posted write buffer. */ | 342 | * flush the posted write buffer. */ |
346 | (void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + | 343 | (void)ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + |
347 | PCIE_INTR_ENABLE_ADDRESS); | 344 | PCIE_INTR_ENABLE_ADDRESS); |
348 | } | 345 | } |
349 | 346 | ||
350 | static void ath10k_pci_enable_legacy_irq(struct ath10k *ar) | 347 | static void ath10k_pci_enable_legacy_irq(struct ath10k *ar) |
@@ -355,8 +352,8 @@ static void ath10k_pci_enable_legacy_irq(struct ath10k *ar) | |||
355 | 352 | ||
356 | /* IMPORTANT: this extra read transaction is required to | 353 | /* IMPORTANT: this extra read transaction is required to |
357 | * flush the posted write buffer. */ | 354 | * flush the posted write buffer. */ |
358 | (void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + | 355 | (void)ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + |
359 | PCIE_INTR_ENABLE_ADDRESS); | 356 | PCIE_INTR_ENABLE_ADDRESS); |
360 | } | 357 | } |
361 | 358 | ||
362 | static inline const char *ath10k_pci_get_irq_method(struct ath10k *ar) | 359 | static inline const char *ath10k_pci_get_irq_method(struct ath10k *ar) |
@@ -365,10 +362,11 @@ static inline const char *ath10k_pci_get_irq_method(struct ath10k *ar) | |||
365 | 362 | ||
366 | if (ar_pci->num_msi_intrs > 1) | 363 | if (ar_pci->num_msi_intrs > 1) |
367 | return "msi-x"; | 364 | return "msi-x"; |
368 | else if (ar_pci->num_msi_intrs == 1) | 365 | |
366 | if (ar_pci->num_msi_intrs == 1) | ||
369 | return "msi"; | 367 | return "msi"; |
370 | else | 368 | |
371 | return "legacy"; | 369 | return "legacy"; |
372 | } | 370 | } |
373 | 371 | ||
374 | static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe) | 372 | static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe) |
@@ -487,25 +485,6 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, | |||
487 | void *data_buf = NULL; | 485 | void *data_buf = NULL; |
488 | int i; | 486 | int i; |
489 | 487 | ||
490 | /* | ||
491 | * This code cannot handle reads to non-memory space. Redirect to the | ||
492 | * register read fn but preserve the multi word read capability of | ||
493 | * this fn | ||
494 | */ | ||
495 | if (address < DRAM_BASE_ADDRESS) { | ||
496 | if (!IS_ALIGNED(address, 4) || | ||
497 | !IS_ALIGNED((unsigned long)data, 4)) | ||
498 | return -EIO; | ||
499 | |||
500 | while ((nbytes >= 4) && ((ret = ath10k_pci_diag_read_access( | ||
501 | ar, address, (u32 *)data)) == 0)) { | ||
502 | nbytes -= sizeof(u32); | ||
503 | address += sizeof(u32); | ||
504 | data += sizeof(u32); | ||
505 | } | ||
506 | return ret; | ||
507 | } | ||
508 | |||
509 | ce_diag = ar_pci->ce_diag; | 488 | ce_diag = ar_pci->ce_diag; |
510 | 489 | ||
511 | /* | 490 | /* |
@@ -549,7 +528,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, | |||
549 | address); | 528 | address); |
550 | 529 | ||
551 | ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, | 530 | ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, |
552 | 0); | 531 | 0); |
553 | if (ret) | 532 | if (ret) |
554 | goto done; | 533 | goto done; |
555 | 534 | ||
@@ -569,7 +548,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, | |||
569 | goto done; | 548 | goto done; |
570 | } | 549 | } |
571 | 550 | ||
572 | if (buf != (u32) address) { | 551 | if (buf != (u32)address) { |
573 | ret = -EIO; | 552 | ret = -EIO; |
574 | goto done; | 553 | goto done; |
575 | } | 554 | } |
@@ -652,19 +631,7 @@ static int __ath10k_pci_diag_read_hi(struct ath10k *ar, void *dest, | |||
652 | } | 631 | } |
653 | 632 | ||
654 | #define ath10k_pci_diag_read_hi(ar, dest, src, len) \ | 633 | #define ath10k_pci_diag_read_hi(ar, dest, src, len) \ |
655 | __ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len); | 634 | __ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len) |
656 | |||
657 | /* Read 4-byte aligned data from Target memory or register */ | ||
658 | static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, | ||
659 | u32 *data) | ||
660 | { | ||
661 | /* Assume range doesn't cross this boundary */ | ||
662 | if (address >= DRAM_BASE_ADDRESS) | ||
663 | return ath10k_pci_diag_read32(ar, address, data); | ||
664 | |||
665 | *data = ath10k_pci_read32(ar, address); | ||
666 | return 0; | ||
667 | } | ||
668 | 635 | ||
669 | static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | 636 | static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, |
670 | const void *data, int nbytes) | 637 | const void *data, int nbytes) |
@@ -729,7 +696,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, | |||
729 | * Request CE to send caller-supplied data that | 696 | * Request CE to send caller-supplied data that |
730 | * was copied to bounce buffer to Target(!) address. | 697 | * was copied to bounce buffer to Target(!) address. |
731 | */ | 698 | */ |
732 | ret = ath10k_ce_send(ce_diag, NULL, (u32) ce_data, | 699 | ret = ath10k_ce_send(ce_diag, NULL, (u32)ce_data, |
733 | nbytes, 0, 0); | 700 | nbytes, 0, 0); |
734 | if (ret != 0) | 701 | if (ret != 0) |
735 | goto done; | 702 | goto done; |
@@ -803,18 +770,6 @@ static int ath10k_pci_diag_write32(struct ath10k *ar, u32 address, u32 value) | |||
803 | return ath10k_pci_diag_write_mem(ar, address, &val, sizeof(val)); | 770 | return ath10k_pci_diag_write_mem(ar, address, &val, sizeof(val)); |
804 | } | 771 | } |
805 | 772 | ||
806 | /* Write 4B data to Target memory or register */ | ||
807 | static int ath10k_pci_diag_write_access(struct ath10k *ar, u32 address, | ||
808 | u32 data) | ||
809 | { | ||
810 | /* Assume range doesn't cross this boundary */ | ||
811 | if (address >= DRAM_BASE_ADDRESS) | ||
812 | return ath10k_pci_diag_write32(ar, address, data); | ||
813 | |||
814 | ath10k_pci_write32(ar, address, data); | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | static bool ath10k_pci_is_awake(struct ath10k *ar) | 773 | static bool ath10k_pci_is_awake(struct ath10k *ar) |
819 | { | 774 | { |
820 | u32 val = ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS); | 775 | u32 val = ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS); |
@@ -1152,7 +1107,7 @@ static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, | |||
1152 | } | 1107 | } |
1153 | 1108 | ||
1154 | static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, | 1109 | static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, |
1155 | u8 *ul_pipe, u8 *dl_pipe) | 1110 | u8 *ul_pipe, u8 *dl_pipe) |
1156 | { | 1111 | { |
1157 | int ul_is_polled, dl_is_polled; | 1112 | int ul_is_polled, dl_is_polled; |
1158 | 1113 | ||
@@ -1172,16 +1127,8 @@ static void ath10k_pci_irq_disable(struct ath10k *ar) | |||
1172 | int i; | 1127 | int i; |
1173 | 1128 | ||
1174 | ath10k_ce_disable_interrupts(ar); | 1129 | ath10k_ce_disable_interrupts(ar); |
1175 | 1130 | ath10k_pci_disable_and_clear_legacy_irq(ar); | |
1176 | /* Regardless how many interrupts were assigned for MSI the first one | 1131 | /* FIXME: How to mask all MSI interrupts? */ |
1177 | * is always used for firmware indications (crashes). There's no way to | ||
1178 | * mask the irq in the device so call disable_irq(). Legacy (shared) | ||
1179 | * interrupts can be masked on the device though. | ||
1180 | */ | ||
1181 | if (ar_pci->num_msi_intrs > 0) | ||
1182 | disable_irq(ar_pci->pdev->irq); | ||
1183 | else | ||
1184 | ath10k_pci_disable_and_clear_legacy_irq(ar); | ||
1185 | 1132 | ||
1186 | for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) | 1133 | for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) |
1187 | synchronize_irq(ar_pci->pdev->irq + i); | 1134 | synchronize_irq(ar_pci->pdev->irq + i); |
@@ -1189,15 +1136,9 @@ static void ath10k_pci_irq_disable(struct ath10k *ar) | |||
1189 | 1136 | ||
1190 | static void ath10k_pci_irq_enable(struct ath10k *ar) | 1137 | static void ath10k_pci_irq_enable(struct ath10k *ar) |
1191 | { | 1138 | { |
1192 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
1193 | |||
1194 | ath10k_ce_enable_interrupts(ar); | 1139 | ath10k_ce_enable_interrupts(ar); |
1195 | 1140 | ath10k_pci_enable_legacy_irq(ar); | |
1196 | /* See comment in ath10k_pci_irq_disable() */ | 1141 | /* FIXME: How to unmask all MSI interrupts? */ |
1197 | if (ar_pci->num_msi_intrs > 0) | ||
1198 | enable_irq(ar_pci->pdev->irq); | ||
1199 | else | ||
1200 | ath10k_pci_enable_legacy_irq(ar); | ||
1201 | } | 1142 | } |
1202 | 1143 | ||
1203 | static int ath10k_pci_hif_start(struct ath10k *ar) | 1144 | static int ath10k_pci_hif_start(struct ath10k *ar) |
@@ -1311,14 +1252,21 @@ static void ath10k_pci_hif_stop(struct ath10k *ar) | |||
1311 | { | 1252 | { |
1312 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n"); | 1253 | ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n"); |
1313 | 1254 | ||
1314 | ath10k_pci_irq_disable(ar); | ||
1315 | ath10k_pci_flush(ar); | ||
1316 | |||
1317 | /* Most likely the device has HTT Rx ring configured. The only way to | 1255 | /* Most likely the device has HTT Rx ring configured. The only way to |
1318 | * prevent the device from accessing (and possible corrupting) host | 1256 | * prevent the device from accessing (and possible corrupting) host |
1319 | * memory is to reset the chip now. | 1257 | * memory is to reset the chip now. |
1258 | * | ||
1259 | * There's also no known way of masking MSI interrupts on the device. | ||
1260 | * For ranged MSI the CE-related interrupts can be masked. However | ||
1261 | * regardless how many MSI interrupts are assigned the first one | ||
1262 | * is always used for firmware indications (crashes) and cannot be | ||
1263 | * masked. To prevent the device from asserting the interrupt reset it | ||
1264 | * before proceeding with cleanup. | ||
1320 | */ | 1265 | */ |
1321 | ath10k_pci_warm_reset(ar); | 1266 | ath10k_pci_warm_reset(ar); |
1267 | |||
1268 | ath10k_pci_irq_disable(ar); | ||
1269 | ath10k_pci_flush(ar); | ||
1322 | } | 1270 | } |
1323 | 1271 | ||
1324 | static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, | 1272 | static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, |
@@ -1472,28 +1420,12 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe, | |||
1472 | */ | 1420 | */ |
1473 | static int ath10k_pci_wake_target_cpu(struct ath10k *ar) | 1421 | static int ath10k_pci_wake_target_cpu(struct ath10k *ar) |
1474 | { | 1422 | { |
1475 | int ret; | 1423 | u32 addr, val; |
1476 | u32 core_ctrl; | ||
1477 | |||
1478 | ret = ath10k_pci_diag_read_access(ar, SOC_CORE_BASE_ADDRESS | | ||
1479 | CORE_CTRL_ADDRESS, | ||
1480 | &core_ctrl); | ||
1481 | if (ret) { | ||
1482 | ath10k_warn(ar, "failed to read core_ctrl: %d\n", ret); | ||
1483 | return ret; | ||
1484 | } | ||
1485 | |||
1486 | /* A_INUM_FIRMWARE interrupt to Target CPU */ | ||
1487 | core_ctrl |= CORE_CTRL_CPU_INTR_MASK; | ||
1488 | 1424 | ||
1489 | ret = ath10k_pci_diag_write_access(ar, SOC_CORE_BASE_ADDRESS | | 1425 | addr = SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS; |
1490 | CORE_CTRL_ADDRESS, | 1426 | val = ath10k_pci_read32(ar, addr); |
1491 | core_ctrl); | 1427 | val |= CORE_CTRL_CPU_INTR_MASK; |
1492 | if (ret) { | 1428 | ath10k_pci_write32(ar, addr, val); |
1493 | ath10k_warn(ar, "failed to set target CPU interrupt mask: %d\n", | ||
1494 | ret); | ||
1495 | return ret; | ||
1496 | } | ||
1497 | 1429 | ||
1498 | return 0; | 1430 | return 0; |
1499 | } | 1431 | } |
@@ -1516,8 +1448,8 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1516 | host_interest_item_address(HI_ITEM(hi_interconnect_state)); | 1448 | host_interest_item_address(HI_ITEM(hi_interconnect_state)); |
1517 | 1449 | ||
1518 | /* Supply Target-side CE configuration */ | 1450 | /* Supply Target-side CE configuration */ |
1519 | ret = ath10k_pci_diag_read_access(ar, interconnect_targ_addr, | 1451 | ret = ath10k_pci_diag_read32(ar, interconnect_targ_addr, |
1520 | &pcie_state_targ_addr); | 1452 | &pcie_state_targ_addr); |
1521 | if (ret != 0) { | 1453 | if (ret != 0) { |
1522 | ath10k_err(ar, "Failed to get pcie state addr: %d\n", ret); | 1454 | ath10k_err(ar, "Failed to get pcie state addr: %d\n", ret); |
1523 | return ret; | 1455 | return ret; |
@@ -1529,10 +1461,10 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1529 | return ret; | 1461 | return ret; |
1530 | } | 1462 | } |
1531 | 1463 | ||
1532 | ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr + | 1464 | ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr + |
1533 | offsetof(struct pcie_state, | 1465 | offsetof(struct pcie_state, |
1534 | pipe_cfg_addr), | 1466 | pipe_cfg_addr)), |
1535 | &pipe_cfg_targ_addr); | 1467 | &pipe_cfg_targ_addr); |
1536 | if (ret != 0) { | 1468 | if (ret != 0) { |
1537 | ath10k_err(ar, "Failed to get pipe cfg addr: %d\n", ret); | 1469 | ath10k_err(ar, "Failed to get pipe cfg addr: %d\n", ret); |
1538 | return ret; | 1470 | return ret; |
@@ -1545,18 +1477,18 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1545 | } | 1477 | } |
1546 | 1478 | ||
1547 | ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr, | 1479 | ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr, |
1548 | target_ce_config_wlan, | 1480 | target_ce_config_wlan, |
1549 | sizeof(target_ce_config_wlan)); | 1481 | sizeof(target_ce_config_wlan)); |
1550 | 1482 | ||
1551 | if (ret != 0) { | 1483 | if (ret != 0) { |
1552 | ath10k_err(ar, "Failed to write pipe cfg: %d\n", ret); | 1484 | ath10k_err(ar, "Failed to write pipe cfg: %d\n", ret); |
1553 | return ret; | 1485 | return ret; |
1554 | } | 1486 | } |
1555 | 1487 | ||
1556 | ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr + | 1488 | ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr + |
1557 | offsetof(struct pcie_state, | 1489 | offsetof(struct pcie_state, |
1558 | svc_to_pipe_map), | 1490 | svc_to_pipe_map)), |
1559 | &svc_to_pipe_map); | 1491 | &svc_to_pipe_map); |
1560 | if (ret != 0) { | 1492 | if (ret != 0) { |
1561 | ath10k_err(ar, "Failed to get svc/pipe map: %d\n", ret); | 1493 | ath10k_err(ar, "Failed to get svc/pipe map: %d\n", ret); |
1562 | return ret; | 1494 | return ret; |
@@ -1569,17 +1501,17 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1569 | } | 1501 | } |
1570 | 1502 | ||
1571 | ret = ath10k_pci_diag_write_mem(ar, svc_to_pipe_map, | 1503 | ret = ath10k_pci_diag_write_mem(ar, svc_to_pipe_map, |
1572 | target_service_to_ce_map_wlan, | 1504 | target_service_to_ce_map_wlan, |
1573 | sizeof(target_service_to_ce_map_wlan)); | 1505 | sizeof(target_service_to_ce_map_wlan)); |
1574 | if (ret != 0) { | 1506 | if (ret != 0) { |
1575 | ath10k_err(ar, "Failed to write svc/pipe map: %d\n", ret); | 1507 | ath10k_err(ar, "Failed to write svc/pipe map: %d\n", ret); |
1576 | return ret; | 1508 | return ret; |
1577 | } | 1509 | } |
1578 | 1510 | ||
1579 | ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr + | 1511 | ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr + |
1580 | offsetof(struct pcie_state, | 1512 | offsetof(struct pcie_state, |
1581 | config_flags), | 1513 | config_flags)), |
1582 | &pcie_config_flags); | 1514 | &pcie_config_flags); |
1583 | if (ret != 0) { | 1515 | if (ret != 0) { |
1584 | ath10k_err(ar, "Failed to get pcie config_flags: %d\n", ret); | 1516 | ath10k_err(ar, "Failed to get pcie config_flags: %d\n", ret); |
1585 | return ret; | 1517 | return ret; |
@@ -1587,9 +1519,10 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1587 | 1519 | ||
1588 | pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1; | 1520 | pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1; |
1589 | 1521 | ||
1590 | ret = ath10k_pci_diag_write_access(ar, pcie_state_targ_addr + | 1522 | ret = ath10k_pci_diag_write32(ar, (pcie_state_targ_addr + |
1591 | offsetof(struct pcie_state, config_flags), | 1523 | offsetof(struct pcie_state, |
1592 | pcie_config_flags); | 1524 | config_flags)), |
1525 | pcie_config_flags); | ||
1593 | if (ret != 0) { | 1526 | if (ret != 0) { |
1594 | ath10k_err(ar, "Failed to write pcie config_flags: %d\n", ret); | 1527 | ath10k_err(ar, "Failed to write pcie config_flags: %d\n", ret); |
1595 | return ret; | 1528 | return ret; |
@@ -1598,7 +1531,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1598 | /* configure early allocation */ | 1531 | /* configure early allocation */ |
1599 | ealloc_targ_addr = host_interest_item_address(HI_ITEM(hi_early_alloc)); | 1532 | ealloc_targ_addr = host_interest_item_address(HI_ITEM(hi_early_alloc)); |
1600 | 1533 | ||
1601 | ret = ath10k_pci_diag_read_access(ar, ealloc_targ_addr, &ealloc_value); | 1534 | ret = ath10k_pci_diag_read32(ar, ealloc_targ_addr, &ealloc_value); |
1602 | if (ret != 0) { | 1535 | if (ret != 0) { |
1603 | ath10k_err(ar, "Faile to get early alloc val: %d\n", ret); | 1536 | ath10k_err(ar, "Faile to get early alloc val: %d\n", ret); |
1604 | return ret; | 1537 | return ret; |
@@ -1610,7 +1543,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1610 | ealloc_value |= ((1 << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & | 1543 | ealloc_value |= ((1 << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & |
1611 | HI_EARLY_ALLOC_IRAM_BANKS_MASK); | 1544 | HI_EARLY_ALLOC_IRAM_BANKS_MASK); |
1612 | 1545 | ||
1613 | ret = ath10k_pci_diag_write_access(ar, ealloc_targ_addr, ealloc_value); | 1546 | ret = ath10k_pci_diag_write32(ar, ealloc_targ_addr, ealloc_value); |
1614 | if (ret != 0) { | 1547 | if (ret != 0) { |
1615 | ath10k_err(ar, "Failed to set early alloc val: %d\n", ret); | 1548 | ath10k_err(ar, "Failed to set early alloc val: %d\n", ret); |
1616 | return ret; | 1549 | return ret; |
@@ -1619,7 +1552,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1619 | /* Tell Target to proceed with initialization */ | 1552 | /* Tell Target to proceed with initialization */ |
1620 | flag2_targ_addr = host_interest_item_address(HI_ITEM(hi_option_flag2)); | 1553 | flag2_targ_addr = host_interest_item_address(HI_ITEM(hi_option_flag2)); |
1621 | 1554 | ||
1622 | ret = ath10k_pci_diag_read_access(ar, flag2_targ_addr, &flag2_value); | 1555 | ret = ath10k_pci_diag_read32(ar, flag2_targ_addr, &flag2_value); |
1623 | if (ret != 0) { | 1556 | if (ret != 0) { |
1624 | ath10k_err(ar, "Failed to get option val: %d\n", ret); | 1557 | ath10k_err(ar, "Failed to get option val: %d\n", ret); |
1625 | return ret; | 1558 | return ret; |
@@ -1627,7 +1560,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) | |||
1627 | 1560 | ||
1628 | flag2_value |= HI_OPTION_EARLY_CFG_DONE; | 1561 | flag2_value |= HI_OPTION_EARLY_CFG_DONE; |
1629 | 1562 | ||
1630 | ret = ath10k_pci_diag_write_access(ar, flag2_targ_addr, flag2_value); | 1563 | ret = ath10k_pci_diag_write32(ar, flag2_targ_addr, flag2_value); |
1631 | if (ret != 0) { | 1564 | if (ret != 0) { |
1632 | ath10k_err(ar, "Failed to set option val: %d\n", ret); | 1565 | ath10k_err(ar, "Failed to set option val: %d\n", ret); |
1633 | return ret; | 1566 | return ret; |
@@ -1692,7 +1625,7 @@ static int ath10k_pci_ce_init(struct ath10k *ar) | |||
1692 | continue; | 1625 | continue; |
1693 | } | 1626 | } |
1694 | 1627 | ||
1695 | pipe_info->buf_sz = (size_t) (attr->src_sz_max); | 1628 | pipe_info->buf_sz = (size_t)(attr->src_sz_max); |
1696 | } | 1629 | } |
1697 | 1630 | ||
1698 | return 0; | 1631 | return 0; |
@@ -2228,7 +2161,7 @@ static int ath10k_pci_init_irq(struct ath10k *ar) | |||
2228 | if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO) { | 2161 | if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO) { |
2229 | ar_pci->num_msi_intrs = MSI_NUM_REQUEST; | 2162 | ar_pci->num_msi_intrs = MSI_NUM_REQUEST; |
2230 | ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs, | 2163 | ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs, |
2231 | ar_pci->num_msi_intrs); | 2164 | ar_pci->num_msi_intrs); |
2232 | if (ret > 0) | 2165 | if (ret > 0) |
2233 | return 0; | 2166 | return 0; |
2234 | 2167 | ||
@@ -2554,6 +2487,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, | |||
2554 | 2487 | ||
2555 | err_free_irq: | 2488 | err_free_irq: |
2556 | ath10k_pci_free_irq(ar); | 2489 | ath10k_pci_free_irq(ar); |
2490 | ath10k_pci_kill_tasklet(ar); | ||
2557 | 2491 | ||
2558 | err_deinit_irq: | 2492 | err_deinit_irq: |
2559 | ath10k_pci_deinit_irq(ar); | 2493 | ath10k_pci_deinit_irq(ar); |
@@ -2590,6 +2524,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) | |||
2590 | 2524 | ||
2591 | ath10k_core_unregister(ar); | 2525 | ath10k_core_unregister(ar); |
2592 | ath10k_pci_free_irq(ar); | 2526 | ath10k_pci_free_irq(ar); |
2527 | ath10k_pci_kill_tasklet(ar); | ||
2593 | ath10k_pci_deinit_irq(ar); | 2528 | ath10k_pci_deinit_irq(ar); |
2594 | ath10k_pci_ce_deinit(ar); | 2529 | ath10k_pci_ce_deinit(ar); |
2595 | ath10k_pci_free_ce(ar); | 2530 | ath10k_pci_free_ce(ar); |
diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h index 1c584c4b019c..e1ffdd57a18c 100644 --- a/drivers/net/wireless/ath/ath10k/rx_desc.h +++ b/drivers/net/wireless/ath/ath10k/rx_desc.h | |||
@@ -839,7 +839,6 @@ struct rx_ppdu_start { | |||
839 | * Reserved: HW should fill with 0, FW should ignore. | 839 | * Reserved: HW should fill with 0, FW should ignore. |
840 | */ | 840 | */ |
841 | 841 | ||
842 | |||
843 | #define RX_PPDU_END_FLAGS_PHY_ERR (1 << 0) | 842 | #define RX_PPDU_END_FLAGS_PHY_ERR (1 << 0) |
844 | #define RX_PPDU_END_FLAGS_RX_LOCATION (1 << 1) | 843 | #define RX_PPDU_END_FLAGS_RX_LOCATION (1 << 1) |
845 | #define RX_PPDU_END_FLAGS_TXBF_H_INFO (1 << 2) | 844 | #define RX_PPDU_END_FLAGS_TXBF_H_INFO (1 << 2) |
diff --git a/drivers/net/wireless/ath/ath10k/targaddrs.h b/drivers/net/wireless/ath/ath10k/targaddrs.h index be7ba1e78afe..9d0ae30f9ff1 100644 --- a/drivers/net/wireless/ath/ath10k/targaddrs.h +++ b/drivers/net/wireless/ath/ath10k/targaddrs.h | |||
@@ -284,7 +284,6 @@ Fw Mode/SubMode Mask | |||
284 | #define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00 | 284 | #define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00 |
285 | #define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8 | 285 | #define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8 |
286 | 286 | ||
287 | |||
288 | /* hi_option_flag2 options */ | 287 | /* hi_option_flag2 options */ |
289 | #define HI_OPTION_OFFLOAD_AMSDU 0x01 | 288 | #define HI_OPTION_OFFLOAD_AMSDU 0x01 |
290 | #define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */ | 289 | #define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */ |
diff --git a/drivers/net/wireless/ath/ath10k/testmode.c b/drivers/net/wireless/ath/ath10k/testmode.c new file mode 100644 index 000000000000..483db9cb8c96 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/testmode.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "testmode.h" | ||
18 | |||
19 | #include <net/netlink.h> | ||
20 | #include <linux/firmware.h> | ||
21 | |||
22 | #include "debug.h" | ||
23 | #include "wmi.h" | ||
24 | #include "hif.h" | ||
25 | #include "hw.h" | ||
26 | |||
27 | #include "testmode_i.h" | ||
28 | |||
29 | static const struct nla_policy ath10k_tm_policy[ATH10K_TM_ATTR_MAX + 1] = { | ||
30 | [ATH10K_TM_ATTR_CMD] = { .type = NLA_U32 }, | ||
31 | [ATH10K_TM_ATTR_DATA] = { .type = NLA_BINARY, | ||
32 | .len = ATH10K_TM_DATA_MAX_LEN }, | ||
33 | [ATH10K_TM_ATTR_WMI_CMDID] = { .type = NLA_U32 }, | ||
34 | [ATH10K_TM_ATTR_VERSION_MAJOR] = { .type = NLA_U32 }, | ||
35 | [ATH10K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 }, | ||
36 | }; | ||
37 | |||
38 | /* Returns true if callee consumes the skb and the skb should be discarded. | ||
39 | * Returns false if skb is not used. Does not sleep. | ||
40 | */ | ||
41 | bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb) | ||
42 | { | ||
43 | struct sk_buff *nl_skb; | ||
44 | bool consumed; | ||
45 | int ret; | ||
46 | |||
47 | ath10k_dbg(ar, ATH10K_DBG_TESTMODE, | ||
48 | "testmode event wmi cmd_id %d skb %p skb->len %d\n", | ||
49 | cmd_id, skb, skb->len); | ||
50 | |||
51 | ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", skb->data, skb->len); | ||
52 | |||
53 | spin_lock_bh(&ar->data_lock); | ||
54 | |||
55 | if (!ar->testmode.utf_monitor) { | ||
56 | consumed = false; | ||
57 | goto out; | ||
58 | } | ||
59 | |||
60 | /* Only testmode.c should be handling events from utf firmware, | ||
61 | * otherwise all sort of problems will arise as mac80211 operations | ||
62 | * are not initialised. | ||
63 | */ | ||
64 | consumed = true; | ||
65 | |||
66 | nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, | ||
67 | 2 * sizeof(u32) + skb->len, | ||
68 | GFP_ATOMIC); | ||
69 | if (!nl_skb) { | ||
70 | ath10k_warn(ar, | ||
71 | "failed to allocate skb for testmode wmi event\n"); | ||
72 | goto out; | ||
73 | } | ||
74 | |||
75 | ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI); | ||
76 | if (ret) { | ||
77 | ath10k_warn(ar, | ||
78 | "failed to to put testmode wmi event cmd attribute: %d\n", | ||
79 | ret); | ||
80 | kfree_skb(nl_skb); | ||
81 | goto out; | ||
82 | } | ||
83 | |||
84 | ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id); | ||
85 | if (ret) { | ||
86 | ath10k_warn(ar, | ||
87 | "failed to to put testmode wmi even cmd_id: %d\n", | ||
88 | ret); | ||
89 | kfree_skb(nl_skb); | ||
90 | goto out; | ||
91 | } | ||
92 | |||
93 | ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, skb->len, skb->data); | ||
94 | if (ret) { | ||
95 | ath10k_warn(ar, | ||
96 | "failed to copy skb to testmode wmi event: %d\n", | ||
97 | ret); | ||
98 | kfree_skb(nl_skb); | ||
99 | goto out; | ||
100 | } | ||
101 | |||
102 | cfg80211_testmode_event(nl_skb, GFP_ATOMIC); | ||
103 | |||
104 | out: | ||
105 | spin_unlock_bh(&ar->data_lock); | ||
106 | |||
107 | return consumed; | ||
108 | } | ||
109 | |||
110 | static int ath10k_tm_cmd_get_version(struct ath10k *ar, struct nlattr *tb[]) | ||
111 | { | ||
112 | struct sk_buff *skb; | ||
113 | int ret; | ||
114 | |||
115 | ath10k_dbg(ar, ATH10K_DBG_TESTMODE, | ||
116 | "testmode cmd get version_major %d version_minor %d\n", | ||
117 | ATH10K_TESTMODE_VERSION_MAJOR, | ||
118 | ATH10K_TESTMODE_VERSION_MINOR); | ||
119 | |||
120 | skb = cfg80211_testmode_alloc_reply_skb(ar->hw->wiphy, | ||
121 | nla_total_size(sizeof(u32))); | ||
122 | if (!skb) | ||
123 | return -ENOMEM; | ||
124 | |||
125 | ret = nla_put_u32(skb, ATH10K_TM_ATTR_VERSION_MAJOR, | ||
126 | ATH10K_TESTMODE_VERSION_MAJOR); | ||
127 | if (ret) { | ||
128 | kfree_skb(skb); | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | ret = nla_put_u32(skb, ATH10K_TM_ATTR_VERSION_MINOR, | ||
133 | ATH10K_TESTMODE_VERSION_MINOR); | ||
134 | if (ret) { | ||
135 | kfree_skb(skb); | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | return cfg80211_testmode_reply(skb); | ||
140 | } | ||
141 | |||
142 | static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[]) | ||
143 | { | ||
144 | char filename[100]; | ||
145 | int ret; | ||
146 | |||
147 | ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode cmd utf start\n"); | ||
148 | |||
149 | mutex_lock(&ar->conf_mutex); | ||
150 | |||
151 | if (ar->state == ATH10K_STATE_UTF) { | ||
152 | ret = -EALREADY; | ||
153 | goto err; | ||
154 | } | ||
155 | |||
156 | /* start utf only when the driver is not in use */ | ||
157 | if (ar->state != ATH10K_STATE_OFF) { | ||
158 | ret = -EBUSY; | ||
159 | goto err; | ||
160 | } | ||
161 | |||
162 | if (WARN_ON(ar->testmode.utf != NULL)) { | ||
163 | /* utf image is already downloaded, it shouldn't be */ | ||
164 | ret = -EEXIST; | ||
165 | goto err; | ||
166 | } | ||
167 | |||
168 | snprintf(filename, sizeof(filename), "%s/%s", | ||
169 | ar->hw_params.fw.dir, ATH10K_FW_UTF_FILE); | ||
170 | |||
171 | /* load utf firmware image */ | ||
172 | ret = request_firmware(&ar->testmode.utf, filename, ar->dev); | ||
173 | if (ret) { | ||
174 | ath10k_warn(ar, "failed to retrieve utf firmware '%s': %d\n", | ||
175 | filename, ret); | ||
176 | goto err; | ||
177 | } | ||
178 | |||
179 | spin_lock_bh(&ar->data_lock); | ||
180 | |||
181 | ar->testmode.utf_monitor = true; | ||
182 | |||
183 | spin_unlock_bh(&ar->data_lock); | ||
184 | |||
185 | BUILD_BUG_ON(sizeof(ar->fw_features) != | ||
186 | sizeof(ar->testmode.orig_fw_features)); | ||
187 | |||
188 | memcpy(ar->testmode.orig_fw_features, ar->fw_features, | ||
189 | sizeof(ar->fw_features)); | ||
190 | |||
191 | /* utf.bin firmware image does not advertise firmware features. Do | ||
192 | * an ugly hack where we force the firmware features so that wmi.c | ||
193 | * will use the correct WMI interface. | ||
194 | */ | ||
195 | memset(ar->fw_features, 0, sizeof(ar->fw_features)); | ||
196 | __set_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features); | ||
197 | |||
198 | ret = ath10k_hif_power_up(ar); | ||
199 | if (ret) { | ||
200 | ath10k_err(ar, "failed to power up hif (testmode): %d\n", ret); | ||
201 | ar->state = ATH10K_STATE_OFF; | ||
202 | goto err_fw_features; | ||
203 | } | ||
204 | |||
205 | ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_UTF); | ||
206 | if (ret) { | ||
207 | ath10k_err(ar, "failed to start core (testmode): %d\n", ret); | ||
208 | ar->state = ATH10K_STATE_OFF; | ||
209 | goto err_power_down; | ||
210 | } | ||
211 | |||
212 | ar->state = ATH10K_STATE_UTF; | ||
213 | |||
214 | ath10k_info(ar, "UTF firmware started\n"); | ||
215 | |||
216 | mutex_unlock(&ar->conf_mutex); | ||
217 | |||
218 | return 0; | ||
219 | |||
220 | err_power_down: | ||
221 | ath10k_hif_power_down(ar); | ||
222 | |||
223 | err_fw_features: | ||
224 | /* return the original firmware features */ | ||
225 | memcpy(ar->fw_features, ar->testmode.orig_fw_features, | ||
226 | sizeof(ar->fw_features)); | ||
227 | |||
228 | release_firmware(ar->testmode.utf); | ||
229 | ar->testmode.utf = NULL; | ||
230 | |||
231 | err: | ||
232 | mutex_unlock(&ar->conf_mutex); | ||
233 | |||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | static void __ath10k_tm_cmd_utf_stop(struct ath10k *ar) | ||
238 | { | ||
239 | lockdep_assert_held(&ar->conf_mutex); | ||
240 | |||
241 | ath10k_core_stop(ar); | ||
242 | ath10k_hif_power_down(ar); | ||
243 | |||
244 | spin_lock_bh(&ar->data_lock); | ||
245 | |||
246 | ar->testmode.utf_monitor = false; | ||
247 | |||
248 | spin_unlock_bh(&ar->data_lock); | ||
249 | |||
250 | /* return the original firmware features */ | ||
251 | memcpy(ar->fw_features, ar->testmode.orig_fw_features, | ||
252 | sizeof(ar->fw_features)); | ||
253 | |||
254 | release_firmware(ar->testmode.utf); | ||
255 | ar->testmode.utf = NULL; | ||
256 | |||
257 | ar->state = ATH10K_STATE_OFF; | ||
258 | } | ||
259 | |||
260 | static int ath10k_tm_cmd_utf_stop(struct ath10k *ar, struct nlattr *tb[]) | ||
261 | { | ||
262 | int ret; | ||
263 | |||
264 | ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode cmd utf stop\n"); | ||
265 | |||
266 | mutex_lock(&ar->conf_mutex); | ||
267 | |||
268 | if (ar->state != ATH10K_STATE_UTF) { | ||
269 | ret = -ENETDOWN; | ||
270 | goto out; | ||
271 | } | ||
272 | |||
273 | __ath10k_tm_cmd_utf_stop(ar); | ||
274 | |||
275 | ret = 0; | ||
276 | |||
277 | ath10k_info(ar, "UTF firmware stopped\n"); | ||
278 | |||
279 | out: | ||
280 | mutex_unlock(&ar->conf_mutex); | ||
281 | return ret; | ||
282 | } | ||
283 | |||
284 | static int ath10k_tm_cmd_wmi(struct ath10k *ar, struct nlattr *tb[]) | ||
285 | { | ||
286 | struct sk_buff *skb; | ||
287 | int ret, buf_len; | ||
288 | u32 cmd_id; | ||
289 | void *buf; | ||
290 | |||
291 | mutex_lock(&ar->conf_mutex); | ||
292 | |||
293 | if (ar->state != ATH10K_STATE_UTF) { | ||
294 | ret = -ENETDOWN; | ||
295 | goto out; | ||
296 | } | ||
297 | |||
298 | if (!tb[ATH10K_TM_ATTR_DATA]) { | ||
299 | ret = -EINVAL; | ||
300 | goto out; | ||
301 | } | ||
302 | |||
303 | if (!tb[ATH10K_TM_ATTR_WMI_CMDID]) { | ||
304 | ret = -EINVAL; | ||
305 | goto out; | ||
306 | } | ||
307 | |||
308 | buf = nla_data(tb[ATH10K_TM_ATTR_DATA]); | ||
309 | buf_len = nla_len(tb[ATH10K_TM_ATTR_DATA]); | ||
310 | cmd_id = nla_get_u32(tb[ATH10K_TM_ATTR_WMI_CMDID]); | ||
311 | |||
312 | ath10k_dbg(ar, ATH10K_DBG_TESTMODE, | ||
313 | "testmode cmd wmi cmd_id %d buf %p buf_len %d\n", | ||
314 | cmd_id, buf, buf_len); | ||
315 | |||
316 | ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len); | ||
317 | |||
318 | skb = ath10k_wmi_alloc_skb(ar, buf_len); | ||
319 | if (!skb) { | ||
320 | ret = -ENOMEM; | ||
321 | goto out; | ||
322 | } | ||
323 | |||
324 | memcpy(skb->data, buf, buf_len); | ||
325 | |||
326 | ret = ath10k_wmi_cmd_send(ar, skb, cmd_id); | ||
327 | if (ret) { | ||
328 | ath10k_warn(ar, "failed to transmit wmi command (testmode): %d\n", | ||
329 | ret); | ||
330 | goto out; | ||
331 | } | ||
332 | |||
333 | ret = 0; | ||
334 | |||
335 | out: | ||
336 | mutex_unlock(&ar->conf_mutex); | ||
337 | return ret; | ||
338 | } | ||
339 | |||
340 | int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
341 | void *data, int len) | ||
342 | { | ||
343 | struct ath10k *ar = hw->priv; | ||
344 | struct nlattr *tb[ATH10K_TM_ATTR_MAX + 1]; | ||
345 | int ret; | ||
346 | |||
347 | ret = nla_parse(tb, ATH10K_TM_ATTR_MAX, data, len, | ||
348 | ath10k_tm_policy); | ||
349 | if (ret) | ||
350 | return ret; | ||
351 | |||
352 | if (!tb[ATH10K_TM_ATTR_CMD]) | ||
353 | return -EINVAL; | ||
354 | |||
355 | switch (nla_get_u32(tb[ATH10K_TM_ATTR_CMD])) { | ||
356 | case ATH10K_TM_CMD_GET_VERSION: | ||
357 | return ath10k_tm_cmd_get_version(ar, tb); | ||
358 | case ATH10K_TM_CMD_UTF_START: | ||
359 | return ath10k_tm_cmd_utf_start(ar, tb); | ||
360 | case ATH10K_TM_CMD_UTF_STOP: | ||
361 | return ath10k_tm_cmd_utf_stop(ar, tb); | ||
362 | case ATH10K_TM_CMD_WMI: | ||
363 | return ath10k_tm_cmd_wmi(ar, tb); | ||
364 | default: | ||
365 | return -EOPNOTSUPP; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | void ath10k_testmode_destroy(struct ath10k *ar) | ||
370 | { | ||
371 | mutex_lock(&ar->conf_mutex); | ||
372 | |||
373 | if (ar->state != ATH10K_STATE_UTF) { | ||
374 | /* utf firmware is not running, nothing to do */ | ||
375 | goto out; | ||
376 | } | ||
377 | |||
378 | __ath10k_tm_cmd_utf_stop(ar); | ||
379 | |||
380 | out: | ||
381 | mutex_unlock(&ar->conf_mutex); | ||
382 | } | ||
diff --git a/drivers/net/wireless/ath/ath10k/testmode.h b/drivers/net/wireless/ath/ath10k/testmode.h new file mode 100644 index 000000000000..9cdd150815db --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/testmode.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "core.h" | ||
18 | |||
19 | #ifdef CONFIG_NL80211_TESTMODE | ||
20 | |||
21 | void ath10k_testmode_destroy(struct ath10k *ar); | ||
22 | |||
23 | bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb); | ||
24 | int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | ||
25 | void *data, int len); | ||
26 | |||
27 | #else | ||
28 | |||
29 | static inline void ath10k_testmode_destroy(struct ath10k *ar) | ||
30 | { | ||
31 | } | ||
32 | |||
33 | static inline bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, | ||
34 | struct sk_buff *skb) | ||
35 | { | ||
36 | return false; | ||
37 | } | ||
38 | |||
39 | static inline int ath10k_tm_cmd(struct ieee80211_hw *hw, | ||
40 | struct ieee80211_vif *vif, | ||
41 | void *data, int len) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath10k/testmode_i.h b/drivers/net/wireless/ath/ath10k/testmode_i.h new file mode 100644 index 000000000000..ba81bf66ce85 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/testmode_i.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | /* "API" level of the ath10k testmode interface. Bump it after every | ||
18 | * incompatible interface change. | ||
19 | */ | ||
20 | #define ATH10K_TESTMODE_VERSION_MAJOR 1 | ||
21 | |||
22 | /* Bump this after every _compatible_ interface change, for example | ||
23 | * addition of a new command or an attribute. | ||
24 | */ | ||
25 | #define ATH10K_TESTMODE_VERSION_MINOR 0 | ||
26 | |||
27 | #define ATH10K_TM_DATA_MAX_LEN 5000 | ||
28 | |||
29 | enum ath10k_tm_attr { | ||
30 | __ATH10K_TM_ATTR_INVALID = 0, | ||
31 | ATH10K_TM_ATTR_CMD = 1, | ||
32 | ATH10K_TM_ATTR_DATA = 2, | ||
33 | ATH10K_TM_ATTR_WMI_CMDID = 3, | ||
34 | ATH10K_TM_ATTR_VERSION_MAJOR = 4, | ||
35 | ATH10K_TM_ATTR_VERSION_MINOR = 5, | ||
36 | |||
37 | /* keep last */ | ||
38 | __ATH10K_TM_ATTR_AFTER_LAST, | ||
39 | ATH10K_TM_ATTR_MAX = __ATH10K_TM_ATTR_AFTER_LAST - 1, | ||
40 | }; | ||
41 | |||
42 | /* All ath10k testmode interface commands specified in | ||
43 | * ATH10K_TM_ATTR_CMD | ||
44 | */ | ||
45 | enum ath10k_tm_cmd { | ||
46 | /* Returns the supported ath10k testmode interface version in | ||
47 | * ATH10K_TM_ATTR_VERSION. Always guaranteed to work. User space | ||
48 | * uses this to verify it's using the correct version of the | ||
49 | * testmode interface | ||
50 | */ | ||
51 | ATH10K_TM_CMD_GET_VERSION = 0, | ||
52 | |||
53 | /* Boots the UTF firmware, the netdev interface must be down at the | ||
54 | * time. | ||
55 | */ | ||
56 | ATH10K_TM_CMD_UTF_START = 1, | ||
57 | |||
58 | /* Shuts down the UTF firmware and puts the driver back into OFF | ||
59 | * state. | ||
60 | */ | ||
61 | ATH10K_TM_CMD_UTF_STOP = 2, | ||
62 | |||
63 | /* The command used to transmit a WMI command to the firmware and | ||
64 | * the event to receive WMI events from the firmware. Without | ||
65 | * struct wmi_cmd_hdr header, only the WMI payload. Command id is | ||
66 | * provided with ATH10K_TM_ATTR_WMI_CMDID and payload in | ||
67 | * ATH10K_TM_ATTR_DATA. | ||
68 | */ | ||
69 | ATH10K_TM_CMD_WMI = 3, | ||
70 | }; | ||
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 4eb2ecbc06ef..574b75ab2609 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) | 18 | #if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) |
19 | 19 | ||
20 | #include <linux/tracepoint.h> | 20 | #include <linux/tracepoint.h> |
21 | #include "core.h" | ||
21 | 22 | ||
22 | #define _TRACE_H_ | 23 | #define _TRACE_H_ |
23 | 24 | ||
@@ -39,59 +40,79 @@ static inline void trace_ ## name(proto) {} | |||
39 | #define ATH10K_MSG_MAX 200 | 40 | #define ATH10K_MSG_MAX 200 |
40 | 41 | ||
41 | DECLARE_EVENT_CLASS(ath10k_log_event, | 42 | DECLARE_EVENT_CLASS(ath10k_log_event, |
42 | TP_PROTO(struct va_format *vaf), | 43 | TP_PROTO(struct ath10k *ar, struct va_format *vaf), |
43 | TP_ARGS(vaf), | 44 | TP_ARGS(ar, vaf), |
44 | TP_STRUCT__entry( | 45 | TP_STRUCT__entry( |
46 | __string(device, dev_name(ar->dev)) | ||
47 | __string(driver, dev_driver_string(ar->dev)) | ||
45 | __dynamic_array(char, msg, ATH10K_MSG_MAX) | 48 | __dynamic_array(char, msg, ATH10K_MSG_MAX) |
46 | ), | 49 | ), |
47 | TP_fast_assign( | 50 | TP_fast_assign( |
51 | __assign_str(device, dev_name(ar->dev)); | ||
52 | __assign_str(driver, dev_driver_string(ar->dev)); | ||
48 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | 53 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), |
49 | ATH10K_MSG_MAX, | 54 | ATH10K_MSG_MAX, |
50 | vaf->fmt, | 55 | vaf->fmt, |
51 | *vaf->va) >= ATH10K_MSG_MAX); | 56 | *vaf->va) >= ATH10K_MSG_MAX); |
52 | ), | 57 | ), |
53 | TP_printk("%s", __get_str(msg)) | 58 | TP_printk( |
59 | "%s %s %s", | ||
60 | __get_str(driver), | ||
61 | __get_str(device), | ||
62 | __get_str(msg) | ||
63 | ) | ||
54 | ); | 64 | ); |
55 | 65 | ||
56 | DEFINE_EVENT(ath10k_log_event, ath10k_log_err, | 66 | DEFINE_EVENT(ath10k_log_event, ath10k_log_err, |
57 | TP_PROTO(struct va_format *vaf), | 67 | TP_PROTO(struct ath10k *ar, struct va_format *vaf), |
58 | TP_ARGS(vaf) | 68 | TP_ARGS(ar, vaf) |
59 | ); | 69 | ); |
60 | 70 | ||
61 | DEFINE_EVENT(ath10k_log_event, ath10k_log_warn, | 71 | DEFINE_EVENT(ath10k_log_event, ath10k_log_warn, |
62 | TP_PROTO(struct va_format *vaf), | 72 | TP_PROTO(struct ath10k *ar, struct va_format *vaf), |
63 | TP_ARGS(vaf) | 73 | TP_ARGS(ar, vaf) |
64 | ); | 74 | ); |
65 | 75 | ||
66 | DEFINE_EVENT(ath10k_log_event, ath10k_log_info, | 76 | DEFINE_EVENT(ath10k_log_event, ath10k_log_info, |
67 | TP_PROTO(struct va_format *vaf), | 77 | TP_PROTO(struct ath10k *ar, struct va_format *vaf), |
68 | TP_ARGS(vaf) | 78 | TP_ARGS(ar, vaf) |
69 | ); | 79 | ); |
70 | 80 | ||
71 | TRACE_EVENT(ath10k_log_dbg, | 81 | TRACE_EVENT(ath10k_log_dbg, |
72 | TP_PROTO(unsigned int level, struct va_format *vaf), | 82 | TP_PROTO(struct ath10k *ar, unsigned int level, struct va_format *vaf), |
73 | TP_ARGS(level, vaf), | 83 | TP_ARGS(ar, level, vaf), |
74 | TP_STRUCT__entry( | 84 | TP_STRUCT__entry( |
85 | __string(device, dev_name(ar->dev)) | ||
86 | __string(driver, dev_driver_string(ar->dev)) | ||
75 | __field(unsigned int, level) | 87 | __field(unsigned int, level) |
76 | __dynamic_array(char, msg, ATH10K_MSG_MAX) | 88 | __dynamic_array(char, msg, ATH10K_MSG_MAX) |
77 | ), | 89 | ), |
78 | TP_fast_assign( | 90 | TP_fast_assign( |
91 | __assign_str(device, dev_name(ar->dev)); | ||
92 | __assign_str(driver, dev_driver_string(ar->dev)); | ||
79 | __entry->level = level; | 93 | __entry->level = level; |
80 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | 94 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), |
81 | ATH10K_MSG_MAX, | 95 | ATH10K_MSG_MAX, |
82 | vaf->fmt, | 96 | vaf->fmt, |
83 | *vaf->va) >= ATH10K_MSG_MAX); | 97 | *vaf->va) >= ATH10K_MSG_MAX); |
84 | ), | 98 | ), |
85 | TP_printk("%s", __get_str(msg)) | 99 | TP_printk( |
100 | "%s %s %s", | ||
101 | __get_str(driver), | ||
102 | __get_str(device), | ||
103 | __get_str(msg) | ||
104 | ) | ||
86 | ); | 105 | ); |
87 | 106 | ||
88 | TRACE_EVENT(ath10k_log_dbg_dump, | 107 | TRACE_EVENT(ath10k_log_dbg_dump, |
89 | TP_PROTO(const char *msg, const char *prefix, | 108 | TP_PROTO(struct ath10k *ar, const char *msg, const char *prefix, |
90 | const void *buf, size_t buf_len), | 109 | const void *buf, size_t buf_len), |
91 | 110 | ||
92 | TP_ARGS(msg, prefix, buf, buf_len), | 111 | TP_ARGS(ar, msg, prefix, buf, buf_len), |
93 | 112 | ||
94 | TP_STRUCT__entry( | 113 | TP_STRUCT__entry( |
114 | __string(device, dev_name(ar->dev)) | ||
115 | __string(driver, dev_driver_string(ar->dev)) | ||
95 | __string(msg, msg) | 116 | __string(msg, msg) |
96 | __string(prefix, prefix) | 117 | __string(prefix, prefix) |
97 | __field(size_t, buf_len) | 118 | __field(size_t, buf_len) |
@@ -99,6 +120,8 @@ TRACE_EVENT(ath10k_log_dbg_dump, | |||
99 | ), | 120 | ), |
100 | 121 | ||
101 | TP_fast_assign( | 122 | TP_fast_assign( |
123 | __assign_str(device, dev_name(ar->dev)); | ||
124 | __assign_str(driver, dev_driver_string(ar->dev)); | ||
102 | __assign_str(msg, msg); | 125 | __assign_str(msg, msg); |
103 | __assign_str(prefix, prefix); | 126 | __assign_str(prefix, prefix); |
104 | __entry->buf_len = buf_len; | 127 | __entry->buf_len = buf_len; |
@@ -106,16 +129,22 @@ TRACE_EVENT(ath10k_log_dbg_dump, | |||
106 | ), | 129 | ), |
107 | 130 | ||
108 | TP_printk( | 131 | TP_printk( |
109 | "%s/%s\n", __get_str(prefix), __get_str(msg) | 132 | "%s %s %s/%s\n", |
133 | __get_str(driver), | ||
134 | __get_str(device), | ||
135 | __get_str(prefix), | ||
136 | __get_str(msg) | ||
110 | ) | 137 | ) |
111 | ); | 138 | ); |
112 | 139 | ||
113 | TRACE_EVENT(ath10k_wmi_cmd, | 140 | TRACE_EVENT(ath10k_wmi_cmd, |
114 | TP_PROTO(int id, void *buf, size_t buf_len, int ret), | 141 | TP_PROTO(struct ath10k *ar, int id, void *buf, size_t buf_len, int ret), |
115 | 142 | ||
116 | TP_ARGS(id, buf, buf_len, ret), | 143 | TP_ARGS(ar, id, buf, buf_len, ret), |
117 | 144 | ||
118 | TP_STRUCT__entry( | 145 | TP_STRUCT__entry( |
146 | __string(device, dev_name(ar->dev)) | ||
147 | __string(driver, dev_driver_string(ar->dev)) | ||
119 | __field(unsigned int, id) | 148 | __field(unsigned int, id) |
120 | __field(size_t, buf_len) | 149 | __field(size_t, buf_len) |
121 | __dynamic_array(u8, buf, buf_len) | 150 | __dynamic_array(u8, buf, buf_len) |
@@ -123,6 +152,8 @@ TRACE_EVENT(ath10k_wmi_cmd, | |||
123 | ), | 152 | ), |
124 | 153 | ||
125 | TP_fast_assign( | 154 | TP_fast_assign( |
155 | __assign_str(device, dev_name(ar->dev)); | ||
156 | __assign_str(driver, dev_driver_string(ar->dev)); | ||
126 | __entry->id = id; | 157 | __entry->id = id; |
127 | __entry->buf_len = buf_len; | 158 | __entry->buf_len = buf_len; |
128 | __entry->ret = ret; | 159 | __entry->ret = ret; |
@@ -130,7 +161,9 @@ TRACE_EVENT(ath10k_wmi_cmd, | |||
130 | ), | 161 | ), |
131 | 162 | ||
132 | TP_printk( | 163 | TP_printk( |
133 | "id %d len %zu ret %d", | 164 | "%s %s id %d len %zu ret %d", |
165 | __get_str(driver), | ||
166 | __get_str(device), | ||
134 | __entry->id, | 167 | __entry->id, |
135 | __entry->buf_len, | 168 | __entry->buf_len, |
136 | __entry->ret | 169 | __entry->ret |
@@ -138,67 +171,85 @@ TRACE_EVENT(ath10k_wmi_cmd, | |||
138 | ); | 171 | ); |
139 | 172 | ||
140 | TRACE_EVENT(ath10k_wmi_event, | 173 | TRACE_EVENT(ath10k_wmi_event, |
141 | TP_PROTO(int id, void *buf, size_t buf_len), | 174 | TP_PROTO(struct ath10k *ar, int id, void *buf, size_t buf_len), |
142 | 175 | ||
143 | TP_ARGS(id, buf, buf_len), | 176 | TP_ARGS(ar, id, buf, buf_len), |
144 | 177 | ||
145 | TP_STRUCT__entry( | 178 | TP_STRUCT__entry( |
179 | __string(device, dev_name(ar->dev)) | ||
180 | __string(driver, dev_driver_string(ar->dev)) | ||
146 | __field(unsigned int, id) | 181 | __field(unsigned int, id) |
147 | __field(size_t, buf_len) | 182 | __field(size_t, buf_len) |
148 | __dynamic_array(u8, buf, buf_len) | 183 | __dynamic_array(u8, buf, buf_len) |
149 | ), | 184 | ), |
150 | 185 | ||
151 | TP_fast_assign( | 186 | TP_fast_assign( |
187 | __assign_str(device, dev_name(ar->dev)); | ||
188 | __assign_str(driver, dev_driver_string(ar->dev)); | ||
152 | __entry->id = id; | 189 | __entry->id = id; |
153 | __entry->buf_len = buf_len; | 190 | __entry->buf_len = buf_len; |
154 | memcpy(__get_dynamic_array(buf), buf, buf_len); | 191 | memcpy(__get_dynamic_array(buf), buf, buf_len); |
155 | ), | 192 | ), |
156 | 193 | ||
157 | TP_printk( | 194 | TP_printk( |
158 | "id %d len %zu", | 195 | "%s %s id %d len %zu", |
196 | __get_str(driver), | ||
197 | __get_str(device), | ||
159 | __entry->id, | 198 | __entry->id, |
160 | __entry->buf_len | 199 | __entry->buf_len |
161 | ) | 200 | ) |
162 | ); | 201 | ); |
163 | 202 | ||
164 | TRACE_EVENT(ath10k_htt_stats, | 203 | TRACE_EVENT(ath10k_htt_stats, |
165 | TP_PROTO(void *buf, size_t buf_len), | 204 | TP_PROTO(struct ath10k *ar, void *buf, size_t buf_len), |
166 | 205 | ||
167 | TP_ARGS(buf, buf_len), | 206 | TP_ARGS(ar, buf, buf_len), |
168 | 207 | ||
169 | TP_STRUCT__entry( | 208 | TP_STRUCT__entry( |
209 | __string(device, dev_name(ar->dev)) | ||
210 | __string(driver, dev_driver_string(ar->dev)) | ||
170 | __field(size_t, buf_len) | 211 | __field(size_t, buf_len) |
171 | __dynamic_array(u8, buf, buf_len) | 212 | __dynamic_array(u8, buf, buf_len) |
172 | ), | 213 | ), |
173 | 214 | ||
174 | TP_fast_assign( | 215 | TP_fast_assign( |
216 | __assign_str(device, dev_name(ar->dev)); | ||
217 | __assign_str(driver, dev_driver_string(ar->dev)); | ||
175 | __entry->buf_len = buf_len; | 218 | __entry->buf_len = buf_len; |
176 | memcpy(__get_dynamic_array(buf), buf, buf_len); | 219 | memcpy(__get_dynamic_array(buf), buf, buf_len); |
177 | ), | 220 | ), |
178 | 221 | ||
179 | TP_printk( | 222 | TP_printk( |
180 | "len %zu", | 223 | "%s %s len %zu", |
224 | __get_str(driver), | ||
225 | __get_str(device), | ||
181 | __entry->buf_len | 226 | __entry->buf_len |
182 | ) | 227 | ) |
183 | ); | 228 | ); |
184 | 229 | ||
185 | TRACE_EVENT(ath10k_wmi_dbglog, | 230 | TRACE_EVENT(ath10k_wmi_dbglog, |
186 | TP_PROTO(void *buf, size_t buf_len), | 231 | TP_PROTO(struct ath10k *ar, void *buf, size_t buf_len), |
187 | 232 | ||
188 | TP_ARGS(buf, buf_len), | 233 | TP_ARGS(ar, buf, buf_len), |
189 | 234 | ||
190 | TP_STRUCT__entry( | 235 | TP_STRUCT__entry( |
236 | __string(device, dev_name(ar->dev)) | ||
237 | __string(driver, dev_driver_string(ar->dev)) | ||
191 | __field(size_t, buf_len) | 238 | __field(size_t, buf_len) |
192 | __dynamic_array(u8, buf, buf_len) | 239 | __dynamic_array(u8, buf, buf_len) |
193 | ), | 240 | ), |
194 | 241 | ||
195 | TP_fast_assign( | 242 | TP_fast_assign( |
243 | __assign_str(device, dev_name(ar->dev)); | ||
244 | __assign_str(driver, dev_driver_string(ar->dev)); | ||
196 | __entry->buf_len = buf_len; | 245 | __entry->buf_len = buf_len; |
197 | memcpy(__get_dynamic_array(buf), buf, buf_len); | 246 | memcpy(__get_dynamic_array(buf), buf, buf_len); |
198 | ), | 247 | ), |
199 | 248 | ||
200 | TP_printk( | 249 | TP_printk( |
201 | "len %zu", | 250 | "%s %s len %zu", |
251 | __get_str(driver), | ||
252 | __get_str(device), | ||
202 | __entry->buf_len | 253 | __entry->buf_len |
203 | ) | 254 | ) |
204 | ); | 255 | ); |
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 2eeec8a63d5c..a0cbc21d0d4b 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c | |||
@@ -178,7 +178,7 @@ void ath10k_peer_map_event(struct ath10k_htt *htt, | |||
178 | goto exit; | 178 | goto exit; |
179 | 179 | ||
180 | peer->vdev_id = ev->vdev_id; | 180 | peer->vdev_id = ev->vdev_id; |
181 | memcpy(peer->addr, ev->addr, ETH_ALEN); | 181 | ether_addr_copy(peer->addr, ev->addr); |
182 | list_add(&peer->list, &ar->peers); | 182 | list_add(&peer->list, &ar->peers); |
183 | wake_up(&ar->peer_mapping_wq); | 183 | wake_up(&ar->peer_mapping_wq); |
184 | } | 184 | } |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index e500a3cc905e..2c42bd504b79 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "debug.h" | 23 | #include "debug.h" |
24 | #include "wmi.h" | 24 | #include "wmi.h" |
25 | #include "mac.h" | 25 | #include "mac.h" |
26 | #include "testmode.h" | ||
26 | 27 | ||
27 | /* MAIN WMI cmd track */ | 28 | /* MAIN WMI cmd track */ |
28 | static struct wmi_cmd_map wmi_cmd_map = { | 29 | static struct wmi_cmd_map wmi_cmd_map = { |
@@ -611,6 +612,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = { | |||
611 | int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) | 612 | int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) |
612 | { | 613 | { |
613 | int ret; | 614 | int ret; |
615 | |||
614 | ret = wait_for_completion_timeout(&ar->wmi.service_ready, | 616 | ret = wait_for_completion_timeout(&ar->wmi.service_ready, |
615 | WMI_SERVICE_READY_TIMEOUT_HZ); | 617 | WMI_SERVICE_READY_TIMEOUT_HZ); |
616 | return ret; | 618 | return ret; |
@@ -619,12 +621,13 @@ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) | |||
619 | int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) | 621 | int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) |
620 | { | 622 | { |
621 | int ret; | 623 | int ret; |
624 | |||
622 | ret = wait_for_completion_timeout(&ar->wmi.unified_ready, | 625 | ret = wait_for_completion_timeout(&ar->wmi.unified_ready, |
623 | WMI_UNIFIED_READY_TIMEOUT_HZ); | 626 | WMI_UNIFIED_READY_TIMEOUT_HZ); |
624 | return ret; | 627 | return ret; |
625 | } | 628 | } |
626 | 629 | ||
627 | static struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len) | 630 | struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len) |
628 | { | 631 | { |
629 | struct sk_buff *skb; | 632 | struct sk_buff *skb; |
630 | u32 round_len = roundup(len, 4); | 633 | u32 round_len = roundup(len, 4); |
@@ -666,7 +669,7 @@ static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, | |||
666 | 669 | ||
667 | memset(skb_cb, 0, sizeof(*skb_cb)); | 670 | memset(skb_cb, 0, sizeof(*skb_cb)); |
668 | ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); | 671 | ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); |
669 | trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len, ret); | 672 | trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len, ret); |
670 | 673 | ||
671 | if (ret) | 674 | if (ret) |
672 | goto err_pull; | 675 | goto err_pull; |
@@ -725,8 +728,7 @@ static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar) | |||
725 | wake_up(&ar->wmi.tx_credits_wq); | 728 | wake_up(&ar->wmi.tx_credits_wq); |
726 | } | 729 | } |
727 | 730 | ||
728 | static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, | 731 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id) |
729 | u32 cmd_id) | ||
730 | { | 732 | { |
731 | int ret = -EOPNOTSUPP; | 733 | int ret = -EOPNOTSUPP; |
732 | 734 | ||
@@ -792,7 +794,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
792 | cmd->hdr.tx_power = 0; | 794 | cmd->hdr.tx_power = 0; |
793 | cmd->hdr.buf_len = __cpu_to_le32(buf_len); | 795 | cmd->hdr.buf_len = __cpu_to_le32(buf_len); |
794 | 796 | ||
795 | memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); | 797 | ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr)); |
796 | memcpy(cmd->buf, skb->data, skb->len); | 798 | memcpy(cmd->buf, skb->data, skb->len); |
797 | 799 | ||
798 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", | 800 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", |
@@ -1288,7 +1290,7 @@ static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) | |||
1288 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", | 1290 | ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", |
1289 | skb->len); | 1291 | skb->len); |
1290 | 1292 | ||
1291 | trace_ath10k_wmi_dbglog(skb->data, skb->len); | 1293 | trace_ath10k_wmi_dbglog(ar, skb->data, skb->len); |
1292 | 1294 | ||
1293 | return 0; | 1295 | return 0; |
1294 | } | 1296 | } |
@@ -1384,6 +1386,8 @@ static void ath10k_wmi_update_tim(struct ath10k *ar, | |||
1384 | struct ieee80211_tim_ie *tim; | 1386 | struct ieee80211_tim_ie *tim; |
1385 | u8 *ies, *ie; | 1387 | u8 *ies, *ie; |
1386 | u8 ie_len, pvm_len; | 1388 | u8 ie_len, pvm_len; |
1389 | __le32 t; | ||
1390 | u32 v; | ||
1387 | 1391 | ||
1388 | /* if next SWBA has no tim_changed the tim_bitmap is garbage. | 1392 | /* if next SWBA has no tim_changed the tim_bitmap is garbage. |
1389 | * we must copy the bitmap upon change and reuse it later */ | 1393 | * we must copy the bitmap upon change and reuse it later */ |
@@ -1394,8 +1398,8 @@ static void ath10k_wmi_update_tim(struct ath10k *ar, | |||
1394 | sizeof(bcn_info->tim_info.tim_bitmap)); | 1398 | sizeof(bcn_info->tim_info.tim_bitmap)); |
1395 | 1399 | ||
1396 | for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { | 1400 | for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { |
1397 | __le32 t = bcn_info->tim_info.tim_bitmap[i / 4]; | 1401 | t = bcn_info->tim_info.tim_bitmap[i / 4]; |
1398 | u32 v = __le32_to_cpu(t); | 1402 | v = __le32_to_cpu(t); |
1399 | arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; | 1403 | arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; |
1400 | } | 1404 | } |
1401 | 1405 | ||
@@ -1511,7 +1515,6 @@ static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa) | |||
1511 | u8 opp_ps_info = noa->ctwindow_oppps; | 1515 | u8 opp_ps_info = noa->ctwindow_oppps; |
1512 | bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT); | 1516 | bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT); |
1513 | 1517 | ||
1514 | |||
1515 | if (!noa_descriptors && !opps_enabled) | 1518 | if (!noa_descriptors && !opps_enabled) |
1516 | return len; | 1519 | return len; |
1517 | 1520 | ||
@@ -1568,7 +1571,6 @@ cleanup: | |||
1568 | kfree(old_data); | 1571 | kfree(old_data); |
1569 | } | 1572 | } |
1570 | 1573 | ||
1571 | |||
1572 | static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) | 1574 | static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) |
1573 | { | 1575 | { |
1574 | struct wmi_host_swba_event *ev; | 1576 | struct wmi_host_swba_event *ev; |
@@ -1859,9 +1861,10 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar, | |||
1859 | } | 1861 | } |
1860 | } | 1862 | } |
1861 | 1863 | ||
1862 | static void ath10k_wmi_event_spectral_scan(struct ath10k *ar, | 1864 | static void |
1863 | struct wmi_single_phyerr_rx_event *event, | 1865 | ath10k_wmi_event_spectral_scan(struct ath10k *ar, |
1864 | u64 tsf) | 1866 | struct wmi_single_phyerr_rx_event *event, |
1867 | u64 tsf) | ||
1865 | { | 1868 | { |
1866 | int buf_len, tlv_len, res, i = 0; | 1869 | int buf_len, tlv_len, res, i = 0; |
1867 | struct phyerr_tlv *tlv; | 1870 | struct phyerr_tlv *tlv; |
@@ -1989,7 +1992,7 @@ static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) | |||
1989 | } | 1992 | } |
1990 | 1993 | ||
1991 | static void ath10k_wmi_event_profile_match(struct ath10k *ar, | 1994 | static void ath10k_wmi_event_profile_match(struct ath10k *ar, |
1992 | struct sk_buff *skb) | 1995 | struct sk_buff *skb) |
1993 | { | 1996 | { |
1994 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); | 1997 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); |
1995 | } | 1998 | } |
@@ -2040,13 +2043,13 @@ static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, | |||
2040 | } | 2043 | } |
2041 | 2044 | ||
2042 | static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, | 2045 | static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, |
2043 | struct sk_buff *skb) | 2046 | struct sk_buff *skb) |
2044 | { | 2047 | { |
2045 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); | 2048 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); |
2046 | } | 2049 | } |
2047 | 2050 | ||
2048 | static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, | 2051 | static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, |
2049 | struct sk_buff *skb) | 2052 | struct sk_buff *skb) |
2050 | { | 2053 | { |
2051 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); | 2054 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); |
2052 | } | 2055 | } |
@@ -2082,7 +2085,7 @@ static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, | |||
2082 | } | 2085 | } |
2083 | 2086 | ||
2084 | static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, | 2087 | static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, |
2085 | struct sk_buff *skb) | 2088 | struct sk_buff *skb) |
2086 | { | 2089 | { |
2087 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); | 2090 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); |
2088 | } | 2091 | } |
@@ -2106,7 +2109,7 @@ static void ath10k_wmi_event_addba_complete(struct ath10k *ar, | |||
2106 | } | 2109 | } |
2107 | 2110 | ||
2108 | static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, | 2111 | static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, |
2109 | struct sk_buff *skb) | 2112 | struct sk_buff *skb) |
2110 | { | 2113 | { |
2111 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); | 2114 | ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); |
2112 | } | 2115 | } |
@@ -2130,7 +2133,7 @@ static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, | |||
2130 | } | 2133 | } |
2131 | 2134 | ||
2132 | static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, | 2135 | static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, |
2133 | u32 num_units, u32 unit_len) | 2136 | u32 num_units, u32 unit_len) |
2134 | { | 2137 | { |
2135 | dma_addr_t paddr; | 2138 | dma_addr_t paddr; |
2136 | u32 pool_size; | 2139 | u32 pool_size; |
@@ -2164,7 +2167,7 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, | |||
2164 | struct sk_buff *skb) | 2167 | struct sk_buff *skb) |
2165 | { | 2168 | { |
2166 | struct wmi_service_ready_event *ev = (void *)skb->data; | 2169 | struct wmi_service_ready_event *ev = (void *)skb->data; |
2167 | DECLARE_BITMAP(svc_bmap, WMI_SERVICE_BM_SIZE) = {}; | 2170 | DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {}; |
2168 | 2171 | ||
2169 | if (skb->len < sizeof(*ev)) { | 2172 | if (skb->len < sizeof(*ev)) { |
2170 | ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", | 2173 | ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", |
@@ -2241,7 +2244,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, | |||
2241 | u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; | 2244 | u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; |
2242 | int ret; | 2245 | int ret; |
2243 | struct wmi_service_ready_event_10x *ev = (void *)skb->data; | 2246 | struct wmi_service_ready_event_10x *ev = (void *)skb->data; |
2244 | DECLARE_BITMAP(svc_bmap, WMI_SERVICE_BM_SIZE) = {}; | 2247 | DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {}; |
2245 | 2248 | ||
2246 | if (skb->len < sizeof(*ev)) { | 2249 | if (skb->len < sizeof(*ev)) { |
2247 | ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", | 2250 | ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n", |
@@ -2347,7 +2350,7 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2347 | if (WARN_ON(skb->len < sizeof(*ev))) | 2350 | if (WARN_ON(skb->len < sizeof(*ev))) |
2348 | return -EINVAL; | 2351 | return -EINVAL; |
2349 | 2352 | ||
2350 | memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN); | 2353 | ether_addr_copy(ar->mac_addr, ev->mac_addr.addr); |
2351 | 2354 | ||
2352 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 2355 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
2353 | "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n", | 2356 | "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n", |
@@ -2371,7 +2374,7 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2371 | if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) | 2374 | if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) |
2372 | return; | 2375 | return; |
2373 | 2376 | ||
2374 | trace_ath10k_wmi_event(id, skb->data, skb->len); | 2377 | trace_ath10k_wmi_event(ar, id, skb->data, skb->len); |
2375 | 2378 | ||
2376 | switch (id) { | 2379 | switch (id) { |
2377 | case WMI_MGMT_RX_EVENTID: | 2380 | case WMI_MGMT_RX_EVENTID: |
@@ -2480,6 +2483,7 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2480 | { | 2483 | { |
2481 | struct wmi_cmd_hdr *cmd_hdr; | 2484 | struct wmi_cmd_hdr *cmd_hdr; |
2482 | enum wmi_10x_event_id id; | 2485 | enum wmi_10x_event_id id; |
2486 | bool consumed; | ||
2483 | 2487 | ||
2484 | cmd_hdr = (struct wmi_cmd_hdr *)skb->data; | 2488 | cmd_hdr = (struct wmi_cmd_hdr *)skb->data; |
2485 | id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); | 2489 | id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); |
@@ -2487,7 +2491,19 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2487 | if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) | 2491 | if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) |
2488 | return; | 2492 | return; |
2489 | 2493 | ||
2490 | trace_ath10k_wmi_event(id, skb->data, skb->len); | 2494 | trace_ath10k_wmi_event(ar, id, skb->data, skb->len); |
2495 | |||
2496 | consumed = ath10k_tm_event_wmi(ar, id, skb); | ||
2497 | |||
2498 | /* Ready event must be handled normally also in UTF mode so that we | ||
2499 | * know the UTF firmware has booted, others we are just bypass WMI | ||
2500 | * events to testmode. | ||
2501 | */ | ||
2502 | if (consumed && id != WMI_10X_READY_EVENTID) { | ||
2503 | ath10k_dbg(ar, ATH10K_DBG_WMI, | ||
2504 | "wmi testmode consumed 0x%x\n", id); | ||
2505 | goto out; | ||
2506 | } | ||
2491 | 2507 | ||
2492 | switch (id) { | 2508 | switch (id) { |
2493 | case WMI_10X_MGMT_RX_EVENTID: | 2509 | case WMI_10X_MGMT_RX_EVENTID: |
@@ -2575,11 +2591,15 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2575 | case WMI_10X_READY_EVENTID: | 2591 | case WMI_10X_READY_EVENTID: |
2576 | ath10k_wmi_ready_event_rx(ar, skb); | 2592 | ath10k_wmi_ready_event_rx(ar, skb); |
2577 | break; | 2593 | break; |
2594 | case WMI_10X_PDEV_UTF_EVENTID: | ||
2595 | /* ignore utf events */ | ||
2596 | break; | ||
2578 | default: | 2597 | default: |
2579 | ath10k_warn(ar, "Unknown eventid: %d\n", id); | 2598 | ath10k_warn(ar, "Unknown eventid: %d\n", id); |
2580 | break; | 2599 | break; |
2581 | } | 2600 | } |
2582 | 2601 | ||
2602 | out: | ||
2583 | dev_kfree_skb(skb); | 2603 | dev_kfree_skb(skb); |
2584 | } | 2604 | } |
2585 | 2605 | ||
@@ -2594,7 +2614,7 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb) | |||
2594 | if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) | 2614 | if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) |
2595 | return; | 2615 | return; |
2596 | 2616 | ||
2597 | trace_ath10k_wmi_event(id, skb->data, skb->len); | 2617 | trace_ath10k_wmi_event(ar, id, skb->data, skb->len); |
2598 | 2618 | ||
2599 | switch (id) { | 2619 | switch (id) { |
2600 | case WMI_10_2_MGMT_RX_EVENTID: | 2620 | case WMI_10_2_MGMT_RX_EVENTID: |
@@ -3476,7 +3496,7 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, | |||
3476 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3496 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3477 | cmd->vdev_type = __cpu_to_le32(type); | 3497 | cmd->vdev_type = __cpu_to_le32(type); |
3478 | cmd->vdev_subtype = __cpu_to_le32(subtype); | 3498 | cmd->vdev_subtype = __cpu_to_le32(subtype); |
3479 | memcpy(cmd->vdev_macaddr.addr, macaddr, ETH_ALEN); | 3499 | ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); |
3480 | 3500 | ||
3481 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3501 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3482 | "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", | 3502 | "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", |
@@ -3503,9 +3523,10 @@ int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) | |||
3503 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); | 3523 | return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); |
3504 | } | 3524 | } |
3505 | 3525 | ||
3506 | static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | 3526 | static int |
3507 | const struct wmi_vdev_start_request_arg *arg, | 3527 | ath10k_wmi_vdev_start_restart(struct ath10k *ar, |
3508 | u32 cmd_id) | 3528 | const struct wmi_vdev_start_request_arg *arg, |
3529 | u32 cmd_id) | ||
3509 | { | 3530 | { |
3510 | struct wmi_vdev_start_request_cmd *cmd; | 3531 | struct wmi_vdev_start_request_cmd *cmd; |
3511 | struct sk_buff *skb; | 3532 | struct sk_buff *skb; |
@@ -3569,8 +3590,8 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | |||
3569 | cmd->chan.antenna_max = arg->channel.max_antenna_gain; | 3590 | cmd->chan.antenna_max = arg->channel.max_antenna_gain; |
3570 | 3591 | ||
3571 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3592 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3572 | "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, " | 3593 | "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n", |
3573 | "ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id, | 3594 | cmdname, arg->vdev_id, |
3574 | flags, arg->channel.freq, arg->channel.mode, | 3595 | flags, arg->channel.freq, arg->channel.mode, |
3575 | cmd->chan.flags, arg->channel.max_power); | 3596 | cmd->chan.flags, arg->channel.max_power); |
3576 | 3597 | ||
@@ -3586,7 +3607,7 @@ int ath10k_wmi_vdev_start(struct ath10k *ar, | |||
3586 | } | 3607 | } |
3587 | 3608 | ||
3588 | int ath10k_wmi_vdev_restart(struct ath10k *ar, | 3609 | int ath10k_wmi_vdev_restart(struct ath10k *ar, |
3589 | const struct wmi_vdev_start_request_arg *arg) | 3610 | const struct wmi_vdev_start_request_arg *arg) |
3590 | { | 3611 | { |
3591 | u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid; | 3612 | u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid; |
3592 | 3613 | ||
@@ -3622,7 +3643,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) | |||
3622 | cmd = (struct wmi_vdev_up_cmd *)skb->data; | 3643 | cmd = (struct wmi_vdev_up_cmd *)skb->data; |
3623 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3644 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3624 | cmd->vdev_assoc_id = __cpu_to_le32(aid); | 3645 | cmd->vdev_assoc_id = __cpu_to_le32(aid); |
3625 | memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN); | 3646 | ether_addr_copy(cmd->vdev_bssid.addr, bssid); |
3626 | 3647 | ||
3627 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3648 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3628 | "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", | 3649 | "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", |
@@ -3703,7 +3724,7 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar, | |||
3703 | cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len); | 3724 | cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len); |
3704 | 3725 | ||
3705 | if (arg->macaddr) | 3726 | if (arg->macaddr) |
3706 | memcpy(cmd->peer_macaddr.addr, arg->macaddr, ETH_ALEN); | 3727 | ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr); |
3707 | if (arg->key_data) | 3728 | if (arg->key_data) |
3708 | memcpy(cmd->key_data, arg->key_data, arg->key_len); | 3729 | memcpy(cmd->key_data, arg->key_data, arg->key_len); |
3709 | 3730 | ||
@@ -3782,7 +3803,7 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, | |||
3782 | 3803 | ||
3783 | cmd = (struct wmi_peer_create_cmd *)skb->data; | 3804 | cmd = (struct wmi_peer_create_cmd *)skb->data; |
3784 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3805 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3785 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3806 | ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); |
3786 | 3807 | ||
3787 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3808 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3788 | "wmi peer create vdev_id %d peer_addr %pM\n", | 3809 | "wmi peer create vdev_id %d peer_addr %pM\n", |
@@ -3802,7 +3823,7 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, | |||
3802 | 3823 | ||
3803 | cmd = (struct wmi_peer_delete_cmd *)skb->data; | 3824 | cmd = (struct wmi_peer_delete_cmd *)skb->data; |
3804 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3825 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3805 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3826 | ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); |
3806 | 3827 | ||
3807 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3828 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3808 | "wmi peer delete vdev_id %d peer_addr %pM\n", | 3829 | "wmi peer delete vdev_id %d peer_addr %pM\n", |
@@ -3823,7 +3844,7 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, | |||
3823 | cmd = (struct wmi_peer_flush_tids_cmd *)skb->data; | 3844 | cmd = (struct wmi_peer_flush_tids_cmd *)skb->data; |
3824 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3845 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3825 | cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); | 3846 | cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); |
3826 | memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3847 | ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); |
3827 | 3848 | ||
3828 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3849 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3829 | "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", | 3850 | "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", |
@@ -3846,7 +3867,7 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, | |||
3846 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3867 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3847 | cmd->param_id = __cpu_to_le32(param_id); | 3868 | cmd->param_id = __cpu_to_le32(param_id); |
3848 | cmd->param_value = __cpu_to_le32(param_value); | 3869 | cmd->param_value = __cpu_to_le32(param_value); |
3849 | memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); | 3870 | ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); |
3850 | 3871 | ||
3851 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3872 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3852 | "wmi vdev %d peer 0x%pM set param %d value %d\n", | 3873 | "wmi vdev %d peer 0x%pM set param %d value %d\n", |
@@ -3917,7 +3938,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, | |||
3917 | cmd->vdev_id = __cpu_to_le32(vdev_id); | 3938 | cmd->vdev_id = __cpu_to_le32(vdev_id); |
3918 | cmd->param_id = __cpu_to_le32(param_id); | 3939 | cmd->param_id = __cpu_to_le32(param_id); |
3919 | cmd->param_value = __cpu_to_le32(value); | 3940 | cmd->param_value = __cpu_to_le32(value); |
3920 | memcpy(&cmd->peer_macaddr, mac, ETH_ALEN); | 3941 | ether_addr_copy(cmd->peer_macaddr.addr, mac); |
3921 | 3942 | ||
3922 | ath10k_dbg(ar, ATH10K_DBG_WMI, | 3943 | ath10k_dbg(ar, ATH10K_DBG_WMI, |
3923 | "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", | 3944 | "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", |
@@ -4001,7 +4022,7 @@ ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf, | |||
4001 | cmd->peer_vht_caps = __cpu_to_le32(arg->peer_vht_caps); | 4022 | cmd->peer_vht_caps = __cpu_to_le32(arg->peer_vht_caps); |
4002 | cmd->peer_phymode = __cpu_to_le32(arg->peer_phymode); | 4023 | cmd->peer_phymode = __cpu_to_le32(arg->peer_phymode); |
4003 | 4024 | ||
4004 | memcpy(cmd->peer_macaddr.addr, arg->addr, ETH_ALEN); | 4025 | ether_addr_copy(cmd->peer_macaddr.addr, arg->addr); |
4005 | 4026 | ||
4006 | cmd->peer_legacy_rates.num_rates = | 4027 | cmd->peer_legacy_rates.num_rates = |
4007 | __cpu_to_le32(arg->peer_legacy_rates.num_rates); | 4028 | __cpu_to_le32(arg->peer_legacy_rates.num_rates); |
@@ -4155,7 +4176,7 @@ static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, | |||
4155 | } | 4176 | } |
4156 | 4177 | ||
4157 | int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, | 4178 | int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, |
4158 | const struct wmi_pdev_set_wmm_params_arg *arg) | 4179 | const struct wmi_pdev_set_wmm_params_arg *arg) |
4159 | { | 4180 | { |
4160 | struct wmi_pdev_set_wmm_params *cmd; | 4181 | struct wmi_pdev_set_wmm_params *cmd; |
4161 | struct sk_buff *skb; | 4182 | struct sk_buff *skb; |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index e70836586756..86f5ebccfe79 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -109,6 +109,9 @@ enum wmi_service { | |||
109 | WMI_SERVICE_BURST, | 109 | WMI_SERVICE_BURST, |
110 | WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, | 110 | WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, |
111 | WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, | 111 | WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, |
112 | |||
113 | /* keep last */ | ||
114 | WMI_SERVICE_MAX, | ||
112 | }; | 115 | }; |
113 | 116 | ||
114 | enum wmi_10x_service { | 117 | enum wmi_10x_service { |
@@ -219,8 +222,6 @@ static inline char *wmi_service_name(int service_id) | |||
219 | #undef SVCSTR | 222 | #undef SVCSTR |
220 | } | 223 | } |
221 | 224 | ||
222 | #define WMI_MAX_SERVICE 64 | ||
223 | |||
224 | #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ | 225 | #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ |
225 | (__le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ | 226 | (__le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ |
226 | BIT((svc_id)%(sizeof(u32)))) | 227 | BIT((svc_id)%(sizeof(u32)))) |
@@ -347,9 +348,6 @@ static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out) | |||
347 | 348 | ||
348 | #undef SVCMAP | 349 | #undef SVCMAP |
349 | 350 | ||
350 | #define WMI_SERVICE_BM_SIZE \ | ||
351 | ((WMI_MAX_SERVICE + sizeof(u32) - 1)/sizeof(u32)) | ||
352 | |||
353 | /* 2 word representation of MAC addr */ | 351 | /* 2 word representation of MAC addr */ |
354 | struct wmi_mac_addr { | 352 | struct wmi_mac_addr { |
355 | union { | 353 | union { |
@@ -1271,7 +1269,6 @@ enum wmi_channel_change_cause { | |||
1271 | WMI_HT_CAP_RX_STBC | \ | 1269 | WMI_HT_CAP_RX_STBC | \ |
1272 | WMI_HT_CAP_LDPC) | 1270 | WMI_HT_CAP_LDPC) |
1273 | 1271 | ||
1274 | |||
1275 | /* | 1272 | /* |
1276 | * WMI_VHT_CAP_* these maps to ieee 802.11ac vht capability information | 1273 | * WMI_VHT_CAP_* these maps to ieee 802.11ac vht capability information |
1277 | * field. The fields not defined here are not supported, or reserved. | 1274 | * field. The fields not defined here are not supported, or reserved. |
@@ -1405,7 +1402,7 @@ struct wmi_service_ready_event { | |||
1405 | __le32 phy_capability; | 1402 | __le32 phy_capability; |
1406 | /* Maximum number of frag table entries that SW will populate less 1 */ | 1403 | /* Maximum number of frag table entries that SW will populate less 1 */ |
1407 | __le32 max_frag_entry; | 1404 | __le32 max_frag_entry; |
1408 | __le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; | 1405 | __le32 wmi_service_bitmap[16]; |
1409 | __le32 num_rf_chains; | 1406 | __le32 num_rf_chains; |
1410 | /* | 1407 | /* |
1411 | * The following field is only valid for service type | 1408 | * The following field is only valid for service type |
@@ -1444,7 +1441,7 @@ struct wmi_service_ready_event_10x { | |||
1444 | 1441 | ||
1445 | /* Maximum number of frag table entries that SW will populate less 1 */ | 1442 | /* Maximum number of frag table entries that SW will populate less 1 */ |
1446 | __le32 max_frag_entry; | 1443 | __le32 max_frag_entry; |
1447 | __le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; | 1444 | __le32 wmi_service_bitmap[16]; |
1448 | __le32 num_rf_chains; | 1445 | __le32 num_rf_chains; |
1449 | 1446 | ||
1450 | /* | 1447 | /* |
@@ -1473,7 +1470,6 @@ struct wmi_service_ready_event_10x { | |||
1473 | struct wlan_host_mem_req mem_reqs[1]; | 1470 | struct wlan_host_mem_req mem_reqs[1]; |
1474 | } __packed; | 1471 | } __packed; |
1475 | 1472 | ||
1476 | |||
1477 | #define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ) | 1473 | #define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ) |
1478 | #define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ) | 1474 | #define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ) |
1479 | 1475 | ||
@@ -2127,7 +2123,6 @@ struct wmi_start_scan_cmd_10x { | |||
2127 | */ | 2123 | */ |
2128 | } __packed; | 2124 | } __packed; |
2129 | 2125 | ||
2130 | |||
2131 | struct wmi_ssid_arg { | 2126 | struct wmi_ssid_arg { |
2132 | int len; | 2127 | int len; |
2133 | const u8 *ssid; | 2128 | const u8 *ssid; |
@@ -2188,7 +2183,6 @@ struct wmi_start_scan_arg { | |||
2188 | /* WMI_SCAN_CLASS_MASK must be the same value as IEEE80211_SCAN_CLASS_MASK */ | 2183 | /* WMI_SCAN_CLASS_MASK must be the same value as IEEE80211_SCAN_CLASS_MASK */ |
2189 | #define WMI_SCAN_CLASS_MASK 0xFF000000 | 2184 | #define WMI_SCAN_CLASS_MASK 0xFF000000 |
2190 | 2185 | ||
2191 | |||
2192 | enum wmi_stop_scan_type { | 2186 | enum wmi_stop_scan_type { |
2193 | WMI_SCAN_STOP_ONE = 0x00000000, /* stop by scan_id */ | 2187 | WMI_SCAN_STOP_ONE = 0x00000000, /* stop by scan_id */ |
2194 | WMI_SCAN_STOP_VDEV_ALL = 0x01000000, /* stop by vdev_id */ | 2188 | WMI_SCAN_STOP_VDEV_ALL = 0x01000000, /* stop by vdev_id */ |
@@ -2373,7 +2367,6 @@ struct wmi_single_phyerr_rx_hdr { | |||
2373 | __le32 nf_list_1; | 2367 | __le32 nf_list_1; |
2374 | __le32 nf_list_2; | 2368 | __le32 nf_list_2; |
2375 | 2369 | ||
2376 | |||
2377 | /* Length of the frame */ | 2370 | /* Length of the frame */ |
2378 | __le32 buf_len; | 2371 | __le32 buf_len; |
2379 | } __packed; | 2372 | } __packed; |
@@ -2475,7 +2468,6 @@ struct phyerr_fft_report { | |||
2475 | #define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_MASK 0x000000FF | 2468 | #define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_MASK 0x000000FF |
2476 | #define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_LSB 0 | 2469 | #define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_LSB 0 |
2477 | 2470 | ||
2478 | |||
2479 | struct phyerr_tlv { | 2471 | struct phyerr_tlv { |
2480 | __le16 len; | 2472 | __le16 len; |
2481 | u8 tag; | 2473 | u8 tag; |
@@ -2506,7 +2498,6 @@ struct wmi_echo_cmd { | |||
2506 | __le32 value; | 2498 | __le32 value; |
2507 | } __packed; | 2499 | } __packed; |
2508 | 2500 | ||
2509 | |||
2510 | struct wmi_pdev_set_regdomain_cmd { | 2501 | struct wmi_pdev_set_regdomain_cmd { |
2511 | __le32 reg_domain; | 2502 | __le32 reg_domain; |
2512 | __le32 reg_domain_2G; | 2503 | __le32 reg_domain_2G; |
@@ -2555,7 +2546,6 @@ struct wmi_pdev_set_quiet_cmd { | |||
2555 | __le32 enabled; | 2546 | __le32 enabled; |
2556 | } __packed; | 2547 | } __packed; |
2557 | 2548 | ||
2558 | |||
2559 | /* | 2549 | /* |
2560 | * 802.11g protection mode. | 2550 | * 802.11g protection mode. |
2561 | */ | 2551 | */ |
@@ -4293,7 +4283,6 @@ struct wmi_tbtt_offset_event { | |||
4293 | __le32 tbttoffset_list[WMI_MAX_AP_VDEV]; | 4283 | __le32 tbttoffset_list[WMI_MAX_AP_VDEV]; |
4294 | } __packed; | 4284 | } __packed; |
4295 | 4285 | ||
4296 | |||
4297 | struct wmi_peer_create_cmd { | 4286 | struct wmi_peer_create_cmd { |
4298 | __le32 vdev_id; | 4287 | __le32 vdev_id; |
4299 | struct wmi_mac_addr peer_macaddr; | 4288 | struct wmi_mac_addr peer_macaddr; |
@@ -4739,6 +4728,10 @@ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); | |||
4739 | int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); | 4728 | int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); |
4740 | 4729 | ||
4741 | int ath10k_wmi_connect(struct ath10k *ar); | 4730 | int ath10k_wmi_connect(struct ath10k *ar); |
4731 | |||
4732 | struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len); | ||
4733 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); | ||
4734 | |||
4742 | int ath10k_wmi_pdev_set_channel(struct ath10k *ar, | 4735 | int ath10k_wmi_pdev_set_channel(struct ath10k *ar, |
4743 | const struct wmi_channel_arg *); | 4736 | const struct wmi_channel_arg *); |
4744 | int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); | 4737 | int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); |
@@ -4774,11 +4767,11 @@ int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, | |||
4774 | int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, | 4767 | int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, |
4775 | u32 enable); | 4768 | u32 enable); |
4776 | int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, | 4769 | int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, |
4777 | const u8 peer_addr[ETH_ALEN]); | 4770 | const u8 peer_addr[ETH_ALEN]); |
4778 | int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, | 4771 | int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, |
4779 | const u8 peer_addr[ETH_ALEN]); | 4772 | const u8 peer_addr[ETH_ALEN]); |
4780 | int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, | 4773 | int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, |
4781 | const u8 peer_addr[ETH_ALEN], u32 tid_bitmap); | 4774 | const u8 peer_addr[ETH_ALEN], u32 tid_bitmap); |
4782 | int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, | 4775 | int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, |
4783 | const u8 *peer_addr, | 4776 | const u8 *peer_addr, |
4784 | enum wmi_peer_param param_id, u32 param_value); | 4777 | enum wmi_peer_param param_id, u32 param_value); |
@@ -4795,7 +4788,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, | |||
4795 | const struct wmi_scan_chan_list_arg *arg); | 4788 | const struct wmi_scan_chan_list_arg *arg); |
4796 | int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif); | 4789 | int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif); |
4797 | int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, | 4790 | int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, |
4798 | const struct wmi_pdev_set_wmm_params_arg *arg); | 4791 | const struct wmi_pdev_set_wmm_params_arg *arg); |
4799 | int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); | 4792 | int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); |
4800 | int ath10k_wmi_force_fw_hang(struct ath10k *ar, | 4793 | int ath10k_wmi_force_fw_hang(struct ath10k *ar, |
4801 | enum wmi_force_fw_hang_type type, u32 delay_ms); | 4794 | enum wmi_force_fw_hang_type type, u32 delay_ms); |
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index c9f81a388f15..93caf8e68901 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig | |||
@@ -1,13 +1,12 @@ | |||
1 | config ATH5K | 1 | config ATH5K |
2 | tristate "Atheros 5xxx wireless cards support" | 2 | tristate "Atheros 5xxx wireless cards support" |
3 | depends on (PCI || ATHEROS_AR231X) && MAC80211 | 3 | depends on PCI && MAC80211 |
4 | select ATH_COMMON | 4 | select ATH_COMMON |
5 | select MAC80211_LEDS | 5 | select MAC80211_LEDS |
6 | select LEDS_CLASS | 6 | select LEDS_CLASS |
7 | select NEW_LEDS | 7 | select NEW_LEDS |
8 | select AVERAGE | 8 | select AVERAGE |
9 | select ATH5K_AHB if (ATHEROS_AR231X && !PCI) | 9 | select ATH5K_PCI |
10 | select ATH5K_PCI if (!ATHEROS_AR231X && PCI) | ||
11 | ---help--- | 10 | ---help--- |
12 | This module adds support for wireless adapters based on | 11 | This module adds support for wireless adapters based on |
13 | Atheros 5xxx chipset. | 12 | Atheros 5xxx chipset. |
@@ -52,16 +51,9 @@ config ATH5K_TRACER | |||
52 | 51 | ||
53 | If unsure, say N. | 52 | If unsure, say N. |
54 | 53 | ||
55 | config ATH5K_AHB | ||
56 | bool "Atheros 5xxx AHB bus support" | ||
57 | depends on (ATHEROS_AR231X && !PCI) | ||
58 | ---help--- | ||
59 | This adds support for WiSoC type chipsets of the 5xxx Atheros | ||
60 | family. | ||
61 | |||
62 | config ATH5K_PCI | 54 | config ATH5K_PCI |
63 | bool "Atheros 5xxx PCI bus support" | 55 | bool "Atheros 5xxx PCI bus support" |
64 | depends on (!ATHEROS_AR231X && PCI) | 56 | depends on PCI |
65 | ---help--- | 57 | ---help--- |
66 | This adds support for PCI type chipsets of the 5xxx Atheros | 58 | This adds support for PCI type chipsets of the 5xxx Atheros |
67 | family. | 59 | family. |
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 1b3a34f7f224..51e2d8668041 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile | |||
@@ -17,6 +17,5 @@ ath5k-y += ani.o | |||
17 | ath5k-y += sysfs.o | 17 | ath5k-y += sysfs.o |
18 | ath5k-y += mac80211-ops.o | 18 | ath5k-y += mac80211-ops.o |
19 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | 19 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o |
20 | ath5k-$(CONFIG_ATH5K_AHB) += ahb.o | ||
21 | ath5k-$(CONFIG_ATH5K_PCI) += pci.o | 20 | ath5k-$(CONFIG_ATH5K_PCI) += pci.o |
22 | obj-$(CONFIG_ATH5K) += ath5k.o | 21 | obj-$(CONFIG_ATH5K) += ath5k.o |
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c deleted file mode 100644 index 79bffe165cab..000000000000 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ /dev/null | |||
@@ -1,234 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
4 | * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> | ||
5 | * | ||
6 | * Permission to use, copy, modify, and/or distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/nl80211.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/etherdevice.h> | ||
22 | #include <linux/export.h> | ||
23 | #include <ar231x_platform.h> | ||
24 | #include "ath5k.h" | ||
25 | #include "debug.h" | ||
26 | #include "base.h" | ||
27 | #include "reg.h" | ||
28 | |||
29 | /* return bus cachesize in 4B word units */ | ||
30 | static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz) | ||
31 | { | ||
32 | *csz = L1_CACHE_BYTES >> 2; | ||
33 | } | ||
34 | |||
35 | static bool | ||
36 | ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) | ||
37 | { | ||
38 | struct ath5k_hw *ah = common->priv; | ||
39 | struct platform_device *pdev = to_platform_device(ah->dev); | ||
40 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
41 | u16 *eeprom, *eeprom_end; | ||
42 | |||
43 | eeprom = (u16 *) bcfg->radio; | ||
44 | eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ; | ||
45 | |||
46 | eeprom += off; | ||
47 | if (eeprom > eeprom_end) | ||
48 | return false; | ||
49 | |||
50 | *data = *eeprom; | ||
51 | return true; | ||
52 | } | ||
53 | |||
54 | int ath5k_hw_read_srev(struct ath5k_hw *ah) | ||
55 | { | ||
56 | struct platform_device *pdev = to_platform_device(ah->dev); | ||
57 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
58 | ah->ah_mac_srev = bcfg->devid; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
63 | { | ||
64 | struct platform_device *pdev = to_platform_device(ah->dev); | ||
65 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
66 | u8 *cfg_mac; | ||
67 | |||
68 | if (to_platform_device(ah->dev)->id == 0) | ||
69 | cfg_mac = bcfg->config->wlan0_mac; | ||
70 | else | ||
71 | cfg_mac = bcfg->config->wlan1_mac; | ||
72 | |||
73 | memcpy(mac, cfg_mac, ETH_ALEN); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static const struct ath_bus_ops ath_ahb_bus_ops = { | ||
78 | .ath_bus_type = ATH_AHB, | ||
79 | .read_cachesize = ath5k_ahb_read_cachesize, | ||
80 | .eeprom_read = ath5k_ahb_eeprom_read, | ||
81 | .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, | ||
82 | }; | ||
83 | |||
84 | /*Initialization*/ | ||
85 | static int ath_ahb_probe(struct platform_device *pdev) | ||
86 | { | ||
87 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
88 | struct ath5k_hw *ah; | ||
89 | struct ieee80211_hw *hw; | ||
90 | struct resource *res; | ||
91 | void __iomem *mem; | ||
92 | int irq; | ||
93 | int ret = 0; | ||
94 | u32 reg; | ||
95 | |||
96 | if (!dev_get_platdata(&pdev->dev)) { | ||
97 | dev_err(&pdev->dev, "no platform data specified\n"); | ||
98 | ret = -EINVAL; | ||
99 | goto err_out; | ||
100 | } | ||
101 | |||
102 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
103 | if (res == NULL) { | ||
104 | dev_err(&pdev->dev, "no memory resource found\n"); | ||
105 | ret = -ENXIO; | ||
106 | goto err_out; | ||
107 | } | ||
108 | |||
109 | mem = ioremap_nocache(res->start, resource_size(res)); | ||
110 | if (mem == NULL) { | ||
111 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
112 | ret = -ENOMEM; | ||
113 | goto err_out; | ||
114 | } | ||
115 | |||
116 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
117 | if (res == NULL) { | ||
118 | dev_err(&pdev->dev, "no IRQ resource found\n"); | ||
119 | ret = -ENXIO; | ||
120 | goto err_iounmap; | ||
121 | } | ||
122 | |||
123 | irq = res->start; | ||
124 | |||
125 | hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops); | ||
126 | if (hw == NULL) { | ||
127 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | ||
128 | ret = -ENOMEM; | ||
129 | goto err_iounmap; | ||
130 | } | ||
131 | |||
132 | ah = hw->priv; | ||
133 | ah->hw = hw; | ||
134 | ah->dev = &pdev->dev; | ||
135 | ah->iobase = mem; | ||
136 | ah->irq = irq; | ||
137 | ah->devid = bcfg->devid; | ||
138 | |||
139 | if (bcfg->devid >= AR5K_SREV_AR2315_R6) { | ||
140 | /* Enable WMAC AHB arbitration */ | ||
141 | reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
142 | reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN; | ||
143 | iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
144 | |||
145 | /* Enable global WMAC swapping */ | ||
146 | reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP); | ||
147 | reg |= AR5K_AR2315_BYTESWAP_WMAC; | ||
148 | iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); | ||
149 | } else { | ||
150 | /* Enable WMAC DMA access (assuming 5312 or 231x*/ | ||
151 | /* TODO: check other platforms */ | ||
152 | reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); | ||
153 | if (to_platform_device(ah->dev)->id == 0) | ||
154 | reg |= AR5K_AR5312_ENABLE_WLAN0; | ||
155 | else | ||
156 | reg |= AR5K_AR5312_ENABLE_WLAN1; | ||
157 | iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); | ||
158 | |||
159 | /* | ||
160 | * On a dual-band AR5312, the multiband radio is only | ||
161 | * used as pass-through. Disable 2 GHz support in the | ||
162 | * driver for it | ||
163 | */ | ||
164 | if (to_platform_device(ah->dev)->id == 0 && | ||
165 | (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) == | ||
166 | (BD_WLAN1 | BD_WLAN0)) | ||
167 | ah->ah_capabilities.cap_needs_2GHz_ovr = true; | ||
168 | else | ||
169 | ah->ah_capabilities.cap_needs_2GHz_ovr = false; | ||
170 | } | ||
171 | |||
172 | ret = ath5k_init_ah(ah, &ath_ahb_bus_ops); | ||
173 | if (ret != 0) { | ||
174 | dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); | ||
175 | ret = -ENODEV; | ||
176 | goto err_free_hw; | ||
177 | } | ||
178 | |||
179 | platform_set_drvdata(pdev, hw); | ||
180 | |||
181 | return 0; | ||
182 | |||
183 | err_free_hw: | ||
184 | ieee80211_free_hw(hw); | ||
185 | err_iounmap: | ||
186 | iounmap(mem); | ||
187 | err_out: | ||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static int ath_ahb_remove(struct platform_device *pdev) | ||
192 | { | ||
193 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
194 | struct ieee80211_hw *hw = platform_get_drvdata(pdev); | ||
195 | struct ath5k_hw *ah; | ||
196 | u32 reg; | ||
197 | |||
198 | if (!hw) | ||
199 | return 0; | ||
200 | |||
201 | ah = hw->priv; | ||
202 | |||
203 | if (bcfg->devid >= AR5K_SREV_AR2315_R6) { | ||
204 | /* Disable WMAC AHB arbitration */ | ||
205 | reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
206 | reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN; | ||
207 | iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
208 | } else { | ||
209 | /*Stop DMA access */ | ||
210 | reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); | ||
211 | if (to_platform_device(ah->dev)->id == 0) | ||
212 | reg &= ~AR5K_AR5312_ENABLE_WLAN0; | ||
213 | else | ||
214 | reg &= ~AR5K_AR5312_ENABLE_WLAN1; | ||
215 | iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); | ||
216 | } | ||
217 | |||
218 | ath5k_deinit_ah(ah); | ||
219 | iounmap(ah->iobase); | ||
220 | ieee80211_free_hw(hw); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static struct platform_driver ath_ahb_driver = { | ||
226 | .probe = ath_ahb_probe, | ||
227 | .remove = ath_ahb_remove, | ||
228 | .driver = { | ||
229 | .name = "ar231x-wmac", | ||
230 | .owner = THIS_MODULE, | ||
231 | }, | ||
232 | }; | ||
233 | |||
234 | module_platform_driver(ath_ahb_driver); | ||
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 85316bb3f8c6..ed2468220216 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1647,32 +1647,6 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah) | |||
1647 | return &(ath5k_hw_common(ah)->regulatory); | 1647 | return &(ath5k_hw_common(ah)->regulatory); |
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | #ifdef CONFIG_ATHEROS_AR231X | ||
1651 | #define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000) | ||
1652 | |||
1653 | static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) | ||
1654 | { | ||
1655 | /* On AR2315 and AR2317 the PCI clock domain registers | ||
1656 | * are outside of the WMAC register space */ | ||
1657 | if (unlikely((reg >= 0x4000) && (reg < 0x5000) && | ||
1658 | (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6))) | ||
1659 | return AR5K_AR2315_PCI_BASE + reg; | ||
1660 | |||
1661 | return ah->iobase + reg; | ||
1662 | } | ||
1663 | |||
1664 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) | ||
1665 | { | ||
1666 | return ioread32(ath5k_ahb_reg(ah, reg)); | ||
1667 | } | ||
1668 | |||
1669 | static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | ||
1670 | { | ||
1671 | iowrite32(val, ath5k_ahb_reg(ah, reg)); | ||
1672 | } | ||
1673 | |||
1674 | #else | ||
1675 | |||
1676 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) | 1650 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) |
1677 | { | 1651 | { |
1678 | return ioread32(ah->iobase + reg); | 1652 | return ioread32(ah->iobase + reg); |
@@ -1683,8 +1657,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | |||
1683 | iowrite32(val, ah->iobase + reg); | 1657 | iowrite32(val, ah->iobase + reg); |
1684 | } | 1658 | } |
1685 | 1659 | ||
1686 | #endif | ||
1687 | |||
1688 | static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah) | 1660 | static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah) |
1689 | { | 1661 | { |
1690 | return ath5k_hw_common(ah)->bus_ops->ath_bus_type; | 1662 | return ath5k_hw_common(ah)->bus_ops->ath_bus_type; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 59a87247aac4..a4a09bb8f2f3 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -99,15 +99,6 @@ static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, | |||
99 | 99 | ||
100 | /* Known SREVs */ | 100 | /* Known SREVs */ |
101 | static const struct ath5k_srev_name srev_names[] = { | 101 | static const struct ath5k_srev_name srev_names[] = { |
102 | #ifdef CONFIG_ATHEROS_AR231X | ||
103 | { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 }, | ||
104 | { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 }, | ||
105 | { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 }, | ||
106 | { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 }, | ||
107 | { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 }, | ||
108 | { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 }, | ||
109 | { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 }, | ||
110 | #else | ||
111 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, | 102 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, |
112 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, | 103 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, |
113 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, | 104 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, |
@@ -126,7 +117,6 @@ static const struct ath5k_srev_name srev_names[] = { | |||
126 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, | 117 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, |
127 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, | 118 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, |
128 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, | 119 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, |
129 | #endif | ||
130 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, | 120 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, |
131 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, | 121 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, |
132 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, | 122 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, |
@@ -142,10 +132,6 @@ static const struct ath5k_srev_name srev_names[] = { | |||
142 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, | 132 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, |
143 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, | 133 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, |
144 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, | 134 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, |
145 | #ifdef CONFIG_ATHEROS_AR231X | ||
146 | { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, | ||
147 | { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, | ||
148 | #endif | ||
149 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, | 135 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, |
150 | }; | 136 | }; |
151 | 137 | ||
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 399728618fb9..c70782e8f07b 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -66,6 +66,7 @@ | |||
66 | 66 | ||
67 | #include <linux/seq_file.h> | 67 | #include <linux/seq_file.h> |
68 | #include <linux/list.h> | 68 | #include <linux/list.h> |
69 | #include <linux/vmalloc.h> | ||
69 | #include "debug.h" | 70 | #include "debug.h" |
70 | #include "ath5k.h" | 71 | #include "ath5k.h" |
71 | #include "reg.h" | 72 | #include "reg.h" |
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 2062d1190556..0beb7e7d6075 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c | |||
@@ -163,20 +163,14 @@ int ath5k_init_leds(struct ath5k_hw *ah) | |||
163 | { | 163 | { |
164 | int ret = 0; | 164 | int ret = 0; |
165 | struct ieee80211_hw *hw = ah->hw; | 165 | struct ieee80211_hw *hw = ah->hw; |
166 | #ifndef CONFIG_ATHEROS_AR231X | ||
167 | struct pci_dev *pdev = ah->pdev; | 166 | struct pci_dev *pdev = ah->pdev; |
168 | #endif | ||
169 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; | 167 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; |
170 | const struct pci_device_id *match; | 168 | const struct pci_device_id *match; |
171 | 169 | ||
172 | if (!ah->pdev) | 170 | if (!ah->pdev) |
173 | return 0; | 171 | return 0; |
174 | 172 | ||
175 | #ifdef CONFIG_ATHEROS_AR231X | ||
176 | match = NULL; | ||
177 | #else | ||
178 | match = pci_match_id(&ath5k_led_devices[0], pdev); | 173 | match = pci_match_id(&ath5k_led_devices[0], pdev); |
179 | #endif | ||
180 | if (match) { | 174 | if (match) { |
181 | __set_bit(ATH_STAT_LEDSOFT, ah->status); | 175 | __set_bit(ATH_STAT_LEDSOFT, ah->status); |
182 | ah->led_pin = ATH_PIN(match->driver_data); | 176 | ah->led_pin = ATH_PIN(match->driver_data); |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 00fb8badbacc..b72d0be716db 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -1004,9 +1004,11 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1004 | case ATH9K_ANI_FIRSTEP_LEVEL:{ | 1004 | case ATH9K_ANI_FIRSTEP_LEVEL:{ |
1005 | u32 level = param; | 1005 | u32 level = param; |
1006 | 1006 | ||
1007 | value = level; | 1007 | value = level * 2; |
1008 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | 1008 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, |
1009 | AR_PHY_FIND_SIG_FIRSTEP, value); | 1009 | AR_PHY_FIND_SIG_FIRSTEP, value); |
1010 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, | ||
1011 | AR_PHY_FIND_SIG_FIRSTEP_LOW, value); | ||
1010 | 1012 | ||
1011 | if (level != aniState->firstepLevel) { | 1013 | if (level != aniState->firstepLevel) { |
1012 | ath_dbg(common, ANI, | 1014 | ath_dbg(common, ANI, |
@@ -1040,9 +1042,8 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1040 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, | 1042 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, |
1041 | AR_PHY_TIMING5_CYCPWR_THR1, value); | 1043 | AR_PHY_TIMING5_CYCPWR_THR1, value); |
1042 | 1044 | ||
1043 | if (IS_CHAN_HT40(ah->curchan)) | 1045 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, |
1044 | REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, | 1046 | AR_PHY_EXT_TIMING5_CYCPWR_THR1, value - 1); |
1045 | AR_PHY_EXT_TIMING5_CYCPWR_THR1, value); | ||
1046 | 1047 | ||
1047 | if (level != aniState->spurImmunityLevel) { | 1048 | if (level != aniState->spurImmunityLevel) { |
1048 | ath_dbg(common, ANI, | 1049 | ath_dbg(common, ANI, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 669cb3747208..2a93519f4bdf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -381,16 +381,27 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
381 | ts->evm1 = ads->AR_TxEVM1; | 381 | ts->evm1 = ads->AR_TxEVM1; |
382 | ts->evm2 = ads->AR_TxEVM2; | 382 | ts->evm2 = ads->AR_TxEVM2; |
383 | 383 | ||
384 | status = ACCESS_ONCE(ads->ds_ctl4); | ||
385 | ts->duration[0] = MS(status, AR_PacketDur0); | ||
386 | ts->duration[1] = MS(status, AR_PacketDur1); | ||
387 | status = ACCESS_ONCE(ads->ds_ctl5); | ||
388 | ts->duration[2] = MS(status, AR_PacketDur2); | ||
389 | ts->duration[3] = MS(status, AR_PacketDur3); | ||
390 | |||
391 | return 0; | 384 | return 0; |
392 | } | 385 | } |
393 | 386 | ||
387 | static int ar9002_hw_get_duration(struct ath_hw *ah, const void *ds, int index) | ||
388 | { | ||
389 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
390 | |||
391 | switch (index) { | ||
392 | case 0: | ||
393 | return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur0); | ||
394 | case 1: | ||
395 | return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur1); | ||
396 | case 2: | ||
397 | return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur2); | ||
398 | case 3: | ||
399 | return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur3); | ||
400 | default: | ||
401 | return -1; | ||
402 | } | ||
403 | } | ||
404 | |||
394 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | 405 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, |
395 | u32 size, u32 flags) | 406 | u32 size, u32 flags) |
396 | { | 407 | { |
@@ -413,4 +424,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) | |||
413 | ops->get_isr = ar9002_hw_get_isr; | 424 | ops->get_isr = ar9002_hw_get_isr; |
414 | ops->set_txdesc = ar9002_set_txdesc; | 425 | ops->set_txdesc = ar9002_set_txdesc; |
415 | ops->proc_txdesc = ar9002_hw_proc_txdesc; | 426 | ops->proc_txdesc = ar9002_hw_proc_txdesc; |
427 | ops->get_duration = ar9002_hw_get_duration; | ||
416 | } | 428 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index e5f7c11fa144..057b1657c428 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -355,11 +355,9 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
355 | struct ath_tx_status *ts) | 355 | struct ath_tx_status *ts) |
356 | { | 356 | { |
357 | struct ar9003_txs *ads; | 357 | struct ar9003_txs *ads; |
358 | struct ar9003_txc *adc; | ||
359 | u32 status; | 358 | u32 status; |
360 | 359 | ||
361 | ads = &ah->ts_ring[ah->ts_tail]; | 360 | ads = &ah->ts_ring[ah->ts_tail]; |
362 | adc = (struct ar9003_txc *)ads; | ||
363 | 361 | ||
364 | status = ACCESS_ONCE(ads->status8); | 362 | status = ACCESS_ONCE(ads->status8); |
365 | if ((status & AR_TxDone) == 0) | 363 | if ((status & AR_TxDone) == 0) |
@@ -428,18 +426,29 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
428 | ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); | 426 | ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); |
429 | ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); | 427 | ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); |
430 | 428 | ||
431 | status = ACCESS_ONCE(adc->ctl15); | ||
432 | ts->duration[0] = MS(status, AR_PacketDur0); | ||
433 | ts->duration[1] = MS(status, AR_PacketDur1); | ||
434 | status = ACCESS_ONCE(adc->ctl16); | ||
435 | ts->duration[2] = MS(status, AR_PacketDur2); | ||
436 | ts->duration[3] = MS(status, AR_PacketDur3); | ||
437 | |||
438 | memset(ads, 0, sizeof(*ads)); | 429 | memset(ads, 0, sizeof(*ads)); |
439 | 430 | ||
440 | return 0; | 431 | return 0; |
441 | } | 432 | } |
442 | 433 | ||
434 | static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index) | ||
435 | { | ||
436 | const struct ar9003_txc *adc = ds; | ||
437 | |||
438 | switch (index) { | ||
439 | case 0: | ||
440 | return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur0); | ||
441 | case 1: | ||
442 | return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur1); | ||
443 | case 2: | ||
444 | return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur2); | ||
445 | case 3: | ||
446 | return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur3); | ||
447 | default: | ||
448 | return 0; | ||
449 | } | ||
450 | } | ||
451 | |||
443 | void ar9003_hw_attach_mac_ops(struct ath_hw *hw) | 452 | void ar9003_hw_attach_mac_ops(struct ath_hw *hw) |
444 | { | 453 | { |
445 | struct ath_hw_ops *ops = ath9k_hw_ops(hw); | 454 | struct ath_hw_ops *ops = ath9k_hw_ops(hw); |
@@ -449,6 +458,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) | |||
449 | ops->get_isr = ar9003_hw_get_isr; | 458 | ops->get_isr = ar9003_hw_get_isr; |
450 | ops->set_txdesc = ar9003_set_txdesc; | 459 | ops->set_txdesc = ar9003_set_txdesc; |
451 | ops->proc_txdesc = ar9003_hw_proc_txdesc; | 460 | ops->proc_txdesc = ar9003_hw_proc_txdesc; |
461 | ops->get_duration = ar9003_hw_get_duration; | ||
452 | } | 462 | } |
453 | 463 | ||
454 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) | 464 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 542a8d51d3b0..697c4ae90af0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -517,6 +517,23 @@ static void ar9003_hw_spur_mitigate(struct ath_hw *ah, | |||
517 | ar9003_hw_spur_mitigate_ofdm(ah, chan); | 517 | ar9003_hw_spur_mitigate_ofdm(ah, chan); |
518 | } | 518 | } |
519 | 519 | ||
520 | static u32 ar9003_hw_compute_pll_control_soc(struct ath_hw *ah, | ||
521 | struct ath9k_channel *chan) | ||
522 | { | ||
523 | u32 pll; | ||
524 | |||
525 | pll = SM(0x5, AR_RTC_9300_SOC_PLL_REFDIV); | ||
526 | |||
527 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
528 | pll |= SM(0x1, AR_RTC_9300_SOC_PLL_CLKSEL); | ||
529 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
530 | pll |= SM(0x2, AR_RTC_9300_SOC_PLL_CLKSEL); | ||
531 | |||
532 | pll |= SM(0x2c, AR_RTC_9300_SOC_PLL_DIV_INT); | ||
533 | |||
534 | return pll; | ||
535 | } | ||
536 | |||
520 | static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah, | 537 | static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah, |
521 | struct ath9k_channel *chan) | 538 | struct ath9k_channel *chan) |
522 | { | 539 | { |
@@ -1781,7 +1798,12 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | |||
1781 | 1798 | ||
1782 | priv_ops->rf_set_freq = ar9003_hw_set_channel; | 1799 | priv_ops->rf_set_freq = ar9003_hw_set_channel; |
1783 | priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; | 1800 | priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; |
1784 | priv_ops->compute_pll_control = ar9003_hw_compute_pll_control; | 1801 | |
1802 | if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) | ||
1803 | priv_ops->compute_pll_control = ar9003_hw_compute_pll_control_soc; | ||
1804 | else | ||
1805 | priv_ops->compute_pll_control = ar9003_hw_compute_pll_control; | ||
1806 | |||
1785 | priv_ops->set_channel_regs = ar9003_hw_set_channel_regs; | 1807 | priv_ops->set_channel_regs = ar9003_hw_set_channel_regs; |
1786 | priv_ops->init_bb = ar9003_hw_init_bb; | 1808 | priv_ops->init_bb = ar9003_hw_init_bb; |
1787 | priv_ops->process_ini = ar9003_hw_process_ini; | 1809 | priv_ops->process_ini = ar9003_hw_process_ini; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 8cd116efe3ea..bfa0b1518da1 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -354,6 +354,7 @@ struct ath_chanctx { | |||
354 | bool switch_after_beacon; | 354 | bool switch_after_beacon; |
355 | 355 | ||
356 | short nvifs; | 356 | short nvifs; |
357 | short nvifs_assigned; | ||
357 | unsigned int rxfilter; | 358 | unsigned int rxfilter; |
358 | }; | 359 | }; |
359 | 360 | ||
@@ -454,7 +455,8 @@ void ath9k_p2p_bss_info_changed(struct ath_softc *sc, | |||
454 | void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | 455 | void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, |
455 | struct sk_buff *skb); | 456 | struct sk_buff *skb); |
456 | void ath9k_p2p_ps_timer(void *priv); | 457 | void ath9k_p2p_ps_timer(void *priv); |
457 | void ath9k_chanctx_wake_queues(struct ath_softc *sc); | 458 | void ath9k_chanctx_wake_queues(struct ath_softc *sc, struct ath_chanctx *ctx); |
459 | void ath9k_chanctx_stop_queues(struct ath_softc *sc, struct ath_chanctx *ctx); | ||
458 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); | 460 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); |
459 | 461 | ||
460 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, | 462 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, |
@@ -524,7 +526,12 @@ static inline void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *av | |||
524 | static inline void ath9k_p2p_ps_timer(struct ath_softc *sc) | 526 | static inline void ath9k_p2p_ps_timer(struct ath_softc *sc) |
525 | { | 527 | { |
526 | } | 528 | } |
527 | static inline void ath9k_chanctx_wake_queues(struct ath_softc *sc) | 529 | static inline void ath9k_chanctx_wake_queues(struct ath_softc *sc, |
530 | struct ath_chanctx *ctx) | ||
531 | { | ||
532 | } | ||
533 | static inline void ath9k_chanctx_stop_queues(struct ath_softc *sc, | ||
534 | struct ath_chanctx *ctx) | ||
528 | { | 535 | { |
529 | } | 536 | } |
530 | static inline void ath_chanctx_check_active(struct ath_softc *sc, | 537 | static inline void ath_chanctx_check_active(struct ath_softc *sc, |
@@ -585,6 +592,11 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
585 | struct ath_vif { | 592 | struct ath_vif { |
586 | struct list_head list; | 593 | struct list_head list; |
587 | 594 | ||
595 | /* BSS info */ | ||
596 | u8 bssid[ETH_ALEN]; | ||
597 | u16 aid; | ||
598 | bool assoc; | ||
599 | |||
588 | struct ieee80211_vif *vif; | 600 | struct ieee80211_vif *vif; |
589 | struct ath_node mcast_node; | 601 | struct ath_node mcast_node; |
590 | int av_bslot; | 602 | int av_bslot; |
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 77c99eb55834..945c89826b14 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c | |||
@@ -211,7 +211,7 @@ void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx) | |||
211 | switch (vif->type) { | 211 | switch (vif->type) { |
212 | case NL80211_IFTYPE_P2P_CLIENT: | 212 | case NL80211_IFTYPE_P2P_CLIENT: |
213 | case NL80211_IFTYPE_STATION: | 213 | case NL80211_IFTYPE_STATION: |
214 | if (vif->bss_conf.assoc) | 214 | if (avp->assoc) |
215 | active = true; | 215 | active = true; |
216 | break; | 216 | break; |
217 | default: | 217 | default: |
@@ -761,6 +761,13 @@ void ath_offchannel_next(struct ath_softc *sc) | |||
761 | 761 | ||
762 | void ath_roc_complete(struct ath_softc *sc, bool abort) | 762 | void ath_roc_complete(struct ath_softc *sc, bool abort) |
763 | { | 763 | { |
764 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
765 | |||
766 | if (abort) | ||
767 | ath_dbg(common, CHAN_CTX, "RoC aborted\n"); | ||
768 | else | ||
769 | ath_dbg(common, CHAN_CTX, "RoC expired\n"); | ||
770 | |||
764 | sc->offchannel.roc_vif = NULL; | 771 | sc->offchannel.roc_vif = NULL; |
765 | sc->offchannel.roc_chan = NULL; | 772 | sc->offchannel.roc_chan = NULL; |
766 | if (!abort) | 773 | if (!abort) |
@@ -917,7 +924,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, | |||
917 | 924 | ||
918 | switch (vif->type) { | 925 | switch (vif->type) { |
919 | case NL80211_IFTYPE_STATION: | 926 | case NL80211_IFTYPE_STATION: |
920 | if (!vif->bss_conf.assoc) | 927 | if (!avp->assoc) |
921 | return false; | 928 | return false; |
922 | 929 | ||
923 | skb = ieee80211_nullfunc_get(sc->hw, vif); | 930 | skb = ieee80211_nullfunc_get(sc->hw, vif); |
@@ -1037,9 +1044,11 @@ static void ath_offchannel_channel_change(struct ath_softc *sc) | |||
1037 | void ath_chanctx_set_next(struct ath_softc *sc, bool force) | 1044 | void ath_chanctx_set_next(struct ath_softc *sc, bool force) |
1038 | { | 1045 | { |
1039 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1046 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1047 | struct ath_chanctx *old_ctx; | ||
1040 | struct timespec ts; | 1048 | struct timespec ts; |
1041 | bool measure_time = false; | 1049 | bool measure_time = false; |
1042 | bool send_ps = false; | 1050 | bool send_ps = false; |
1051 | bool queues_stopped = false; | ||
1043 | 1052 | ||
1044 | spin_lock_bh(&sc->chan_lock); | 1053 | spin_lock_bh(&sc->chan_lock); |
1045 | if (!sc->next_chan) { | 1054 | if (!sc->next_chan) { |
@@ -1069,6 +1078,10 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force) | |||
1069 | getrawmonotonic(&ts); | 1078 | getrawmonotonic(&ts); |
1070 | measure_time = true; | 1079 | measure_time = true; |
1071 | } | 1080 | } |
1081 | |||
1082 | ath9k_chanctx_stop_queues(sc, sc->cur_chan); | ||
1083 | queues_stopped = true; | ||
1084 | |||
1072 | __ath9k_flush(sc->hw, ~0, true); | 1085 | __ath9k_flush(sc->hw, ~0, true); |
1073 | 1086 | ||
1074 | if (ath_chanctx_send_ps_frame(sc, true)) | 1087 | if (ath_chanctx_send_ps_frame(sc, true)) |
@@ -1082,6 +1095,7 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force) | |||
1082 | sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah); | 1095 | sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah); |
1083 | } | 1096 | } |
1084 | } | 1097 | } |
1098 | old_ctx = sc->cur_chan; | ||
1085 | sc->cur_chan = sc->next_chan; | 1099 | sc->cur_chan = sc->next_chan; |
1086 | sc->cur_chan->stopped = false; | 1100 | sc->cur_chan->stopped = false; |
1087 | sc->next_chan = NULL; | 1101 | sc->next_chan = NULL; |
@@ -1104,7 +1118,16 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force) | |||
1104 | if (measure_time) | 1118 | if (measure_time) |
1105 | sc->sched.channel_switch_time = | 1119 | sc->sched.channel_switch_time = |
1106 | ath9k_hw_get_tsf_offset(&ts, NULL); | 1120 | ath9k_hw_get_tsf_offset(&ts, NULL); |
1121 | /* | ||
1122 | * A reset will ensure that all queues are woken up, | ||
1123 | * so there is no need to awaken them again. | ||
1124 | */ | ||
1125 | goto out; | ||
1107 | } | 1126 | } |
1127 | |||
1128 | if (queues_stopped) | ||
1129 | ath9k_chanctx_wake_queues(sc, old_ctx); | ||
1130 | out: | ||
1108 | if (send_ps) | 1131 | if (send_ps) |
1109 | ath_chanctx_send_ps_frame(sc, false); | 1132 | ath_chanctx_send_ps_frame(sc, false); |
1110 | 1133 | ||
@@ -1170,18 +1193,37 @@ bool ath9k_is_chanctx_enabled(void) | |||
1170 | /* Queue management */ | 1193 | /* Queue management */ |
1171 | /********************/ | 1194 | /********************/ |
1172 | 1195 | ||
1173 | void ath9k_chanctx_wake_queues(struct ath_softc *sc) | 1196 | void ath9k_chanctx_stop_queues(struct ath_softc *sc, struct ath_chanctx *ctx) |
1197 | { | ||
1198 | struct ath_hw *ah = sc->sc_ah; | ||
1199 | int i; | ||
1200 | |||
1201 | if (ctx == &sc->offchannel.chan) { | ||
1202 | ieee80211_stop_queue(sc->hw, | ||
1203 | sc->hw->offchannel_tx_hw_queue); | ||
1204 | } else { | ||
1205 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | ||
1206 | ieee80211_stop_queue(sc->hw, | ||
1207 | ctx->hw_queue_base + i); | ||
1208 | } | ||
1209 | |||
1210 | if (ah->opmode == NL80211_IFTYPE_AP) | ||
1211 | ieee80211_stop_queue(sc->hw, sc->hw->queues - 2); | ||
1212 | } | ||
1213 | |||
1214 | |||
1215 | void ath9k_chanctx_wake_queues(struct ath_softc *sc, struct ath_chanctx *ctx) | ||
1174 | { | 1216 | { |
1175 | struct ath_hw *ah = sc->sc_ah; | 1217 | struct ath_hw *ah = sc->sc_ah; |
1176 | int i; | 1218 | int i; |
1177 | 1219 | ||
1178 | if (sc->cur_chan == &sc->offchannel.chan) { | 1220 | if (ctx == &sc->offchannel.chan) { |
1179 | ieee80211_wake_queue(sc->hw, | 1221 | ieee80211_wake_queue(sc->hw, |
1180 | sc->hw->offchannel_tx_hw_queue); | 1222 | sc->hw->offchannel_tx_hw_queue); |
1181 | } else { | 1223 | } else { |
1182 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | 1224 | for (i = 0; i < IEEE80211_NUM_ACS; i++) |
1183 | ieee80211_wake_queue(sc->hw, | 1225 | ieee80211_wake_queue(sc->hw, |
1184 | sc->cur_chan->hw_queue_base + i); | 1226 | ctx->hw_queue_base + i); |
1185 | } | 1227 | } |
1186 | 1228 | ||
1187 | if (ah->opmode == NL80211_IFTYPE_AP) | 1229 | if (ah->opmode == NL80211_IFTYPE_AP) |
@@ -1339,7 +1381,7 @@ void ath9k_p2p_ps_timer(void *priv) | |||
1339 | rcu_read_lock(); | 1381 | rcu_read_lock(); |
1340 | 1382 | ||
1341 | vif = avp->vif; | 1383 | vif = avp->vif; |
1342 | sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); | 1384 | sta = ieee80211_find_sta(vif, avp->bssid); |
1343 | if (!sta) | 1385 | if (!sta) |
1344 | goto out; | 1386 | goto out; |
1345 | 1387 | ||
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c index 6ae8e0bc9e1f..22b3cc4c27cd 100644 --- a/drivers/net/wireless/ath/ath9k/dynack.c +++ b/drivers/net/wireless/ath/ath9k/dynack.c | |||
@@ -202,7 +202,7 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, | |||
202 | ridx = ts->ts_rateindex; | 202 | ridx = ts->ts_rateindex; |
203 | 203 | ||
204 | da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp; | 204 | da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp; |
205 | da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration[ts->ts_rateindex]; | 205 | da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration; |
206 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1); | 206 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1); |
207 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2); | 207 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2); |
208 | 208 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index a47ea8423f1e..8e85efeaeffc 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
@@ -67,6 +67,12 @@ static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds, | |||
67 | return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts); | 67 | return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts); |
68 | } | 68 | } |
69 | 69 | ||
70 | static inline int ath9k_hw_get_duration(struct ath_hw *ah, const void *ds, | ||
71 | int index) | ||
72 | { | ||
73 | return ath9k_hw_ops(ah)->get_duration(ah, ds, index); | ||
74 | } | ||
75 | |||
70 | static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, | 76 | static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, |
71 | struct ath_hw_antcomb_conf *antconf) | 77 | struct ath_hw_antcomb_conf *antconf) |
72 | { | 78 | { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 3aed729e4d5e..8be4b1453394 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -222,31 +222,28 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
222 | { | 222 | { |
223 | u32 val; | 223 | u32 val; |
224 | 224 | ||
225 | if (ah->get_mac_revision) | ||
226 | ah->hw_version.macRev = ah->get_mac_revision(); | ||
227 | |||
225 | switch (ah->hw_version.devid) { | 228 | switch (ah->hw_version.devid) { |
226 | case AR5416_AR9100_DEVID: | 229 | case AR5416_AR9100_DEVID: |
227 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | 230 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; |
228 | break; | 231 | break; |
229 | case AR9300_DEVID_AR9330: | 232 | case AR9300_DEVID_AR9330: |
230 | ah->hw_version.macVersion = AR_SREV_VERSION_9330; | 233 | ah->hw_version.macVersion = AR_SREV_VERSION_9330; |
231 | if (ah->get_mac_revision) { | 234 | if (!ah->get_mac_revision) { |
232 | ah->hw_version.macRev = ah->get_mac_revision(); | ||
233 | } else { | ||
234 | val = REG_READ(ah, AR_SREV); | 235 | val = REG_READ(ah, AR_SREV); |
235 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | 236 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); |
236 | } | 237 | } |
237 | return; | 238 | return; |
238 | case AR9300_DEVID_AR9340: | 239 | case AR9300_DEVID_AR9340: |
239 | ah->hw_version.macVersion = AR_SREV_VERSION_9340; | 240 | ah->hw_version.macVersion = AR_SREV_VERSION_9340; |
240 | val = REG_READ(ah, AR_SREV); | ||
241 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | ||
242 | return; | 241 | return; |
243 | case AR9300_DEVID_QCA955X: | 242 | case AR9300_DEVID_QCA955X: |
244 | ah->hw_version.macVersion = AR_SREV_VERSION_9550; | 243 | ah->hw_version.macVersion = AR_SREV_VERSION_9550; |
245 | return; | 244 | return; |
246 | case AR9300_DEVID_AR953X: | 245 | case AR9300_DEVID_AR953X: |
247 | ah->hw_version.macVersion = AR_SREV_VERSION_9531; | 246 | ah->hw_version.macVersion = AR_SREV_VERSION_9531; |
248 | if (ah->get_mac_revision) | ||
249 | ah->hw_version.macRev = ah->get_mac_revision(); | ||
250 | return; | 247 | return; |
251 | } | 248 | } |
252 | 249 | ||
@@ -704,6 +701,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
704 | { | 701 | { |
705 | u32 pll; | 702 | u32 pll; |
706 | 703 | ||
704 | pll = ath9k_hw_compute_pll_control(ah, chan); | ||
705 | |||
707 | if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { | 706 | if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { |
708 | /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ | 707 | /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ |
709 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 708 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
@@ -754,7 +753,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
754 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, | 753 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, |
755 | AR_CH0_DPLL3_PHASE_SHIFT, 0x1); | 754 | AR_CH0_DPLL3_PHASE_SHIFT, 0x1); |
756 | 755 | ||
757 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | 756 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, |
757 | pll | AR_RTC_9300_PLL_BYPASS); | ||
758 | udelay(1000); | 758 | udelay(1000); |
759 | 759 | ||
760 | /* program refdiv, nint, frac to RTC register */ | 760 | /* program refdiv, nint, frac to RTC register */ |
@@ -770,7 +770,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
770 | } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) { | 770 | } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) { |
771 | u32 regval, pll2_divint, pll2_divfrac, refdiv; | 771 | u32 regval, pll2_divint, pll2_divfrac, refdiv; |
772 | 772 | ||
773 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | 773 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, |
774 | pll | AR_RTC_9300_SOC_PLL_BYPASS); | ||
774 | udelay(1000); | 775 | udelay(1000); |
775 | 776 | ||
776 | REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16); | 777 | REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16); |
@@ -843,7 +844,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
843 | udelay(1000); | 844 | udelay(1000); |
844 | } | 845 | } |
845 | 846 | ||
846 | pll = ath9k_hw_compute_pll_control(ah, chan); | ||
847 | if (AR_SREV_9565(ah)) | 847 | if (AR_SREV_9565(ah)) |
848 | pll |= 0x40000; | 848 | pll |= 0x40000; |
849 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 849 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
@@ -1192,9 +1192,12 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) | |||
1192 | 1192 | ||
1193 | switch (opmode) { | 1193 | switch (opmode) { |
1194 | case NL80211_IFTYPE_ADHOC: | 1194 | case NL80211_IFTYPE_ADHOC: |
1195 | set |= AR_STA_ID1_ADHOC; | 1195 | if (!AR_SREV_9340_13(ah)) { |
1196 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); | 1196 | set |= AR_STA_ID1_ADHOC; |
1197 | break; | 1197 | REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); |
1198 | break; | ||
1199 | } | ||
1200 | /* fall through */ | ||
1198 | case NL80211_IFTYPE_MESH_POINT: | 1201 | case NL80211_IFTYPE_MESH_POINT: |
1199 | case NL80211_IFTYPE_AP: | 1202 | case NL80211_IFTYPE_AP: |
1200 | set |= AR_STA_ID1_STA_AP; | 1203 | set |= AR_STA_ID1_STA_AP; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b9eef3362fbb..975074fc11bc 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -691,6 +691,7 @@ struct ath_hw_ops { | |||
691 | struct ath_tx_info *i); | 691 | struct ath_tx_info *i); |
692 | int (*proc_txdesc)(struct ath_hw *ah, void *ds, | 692 | int (*proc_txdesc)(struct ath_hw *ah, void *ds, |
693 | struct ath_tx_status *ts); | 693 | struct ath_tx_status *ts); |
694 | int (*get_duration)(struct ath_hw *ah, const void *ds, int index); | ||
694 | void (*antdiv_comb_conf_get)(struct ath_hw *ah, | 695 | void (*antdiv_comb_conf_get)(struct ath_hw *ah, |
695 | struct ath_hw_antcomb_conf *antconf); | 696 | struct ath_hw_antcomb_conf *antconf); |
696 | void (*antdiv_comb_conf_set)(struct ath_hw *ah, | 697 | void (*antdiv_comb_conf_set)(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index cd05a7791073..aa69ceaad0be 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -121,7 +121,7 @@ struct ath_tx_status { | |||
121 | u32 evm0; | 121 | u32 evm0; |
122 | u32 evm1; | 122 | u32 evm1; |
123 | u32 evm2; | 123 | u32 evm2; |
124 | u32 duration[4]; | 124 | u32 duration; |
125 | }; | 125 | }; |
126 | 126 | ||
127 | struct ath_rx_status { | 127 | struct ath_rx_status { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index fbf23ac61c97..205162449b72 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -60,8 +60,10 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) | |||
60 | 60 | ||
61 | spin_lock_bh(&txq->axq_lock); | 61 | spin_lock_bh(&txq->axq_lock); |
62 | 62 | ||
63 | if (txq->axq_depth) | 63 | if (txq->axq_depth) { |
64 | pending = true; | 64 | pending = true; |
65 | goto out; | ||
66 | } | ||
65 | 67 | ||
66 | if (txq->mac80211_qnum >= 0) { | 68 | if (txq->mac80211_qnum >= 0) { |
67 | struct list_head *list; | 69 | struct list_head *list; |
@@ -70,6 +72,7 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) | |||
70 | if (!list_empty(list)) | 72 | if (!list_empty(list)) |
71 | pending = true; | 73 | pending = true; |
72 | } | 74 | } |
75 | out: | ||
73 | spin_unlock_bh(&txq->axq_lock); | 76 | spin_unlock_bh(&txq->axq_lock); |
74 | return pending; | 77 | return pending; |
75 | } | 78 | } |
@@ -261,12 +264,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
261 | 264 | ||
262 | ath9k_hw_set_interrupts(ah); | 265 | ath9k_hw_set_interrupts(ah); |
263 | ath9k_hw_enable_interrupts(ah); | 266 | ath9k_hw_enable_interrupts(ah); |
264 | 267 | ieee80211_wake_queues(sc->hw); | |
265 | if (!ath9k_is_chanctx_enabled()) | ||
266 | ieee80211_wake_queues(sc->hw); | ||
267 | else | ||
268 | ath9k_chanctx_wake_queues(sc); | ||
269 | |||
270 | ath9k_p2p_ps_timer(sc); | 268 | ath9k_p2p_ps_timer(sc); |
271 | 269 | ||
272 | return true; | 270 | return true; |
@@ -898,6 +896,7 @@ static bool ath9k_uses_beacons(int type) | |||
898 | static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, | 896 | static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, |
899 | u8 *mac, struct ieee80211_vif *vif) | 897 | u8 *mac, struct ieee80211_vif *vif) |
900 | { | 898 | { |
899 | struct ath_vif *avp = (struct ath_vif *)vif->drv_priv; | ||
901 | int i; | 900 | int i; |
902 | 901 | ||
903 | if (iter_data->has_hw_macaddr) { | 902 | if (iter_data->has_hw_macaddr) { |
@@ -918,7 +917,7 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, | |||
918 | break; | 917 | break; |
919 | case NL80211_IFTYPE_STATION: | 918 | case NL80211_IFTYPE_STATION: |
920 | iter_data->nstations++; | 919 | iter_data->nstations++; |
921 | if (vif->bss_conf.assoc && !iter_data->primary_sta) | 920 | if (avp->assoc && !iter_data->primary_sta) |
922 | iter_data->primary_sta = vif; | 921 | iter_data->primary_sta = vif; |
923 | break; | 922 | break; |
924 | case NL80211_IFTYPE_ADHOC: | 923 | case NL80211_IFTYPE_ADHOC: |
@@ -939,6 +938,34 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, | |||
939 | } | 938 | } |
940 | } | 939 | } |
941 | 940 | ||
941 | static void ath9k_update_bssid_mask(struct ath_softc *sc, | ||
942 | struct ath_chanctx *ctx, | ||
943 | struct ath9k_vif_iter_data *iter_data) | ||
944 | { | ||
945 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
946 | struct ath_vif *avp; | ||
947 | int i; | ||
948 | |||
949 | if (!ath9k_is_chanctx_enabled()) | ||
950 | return; | ||
951 | |||
952 | list_for_each_entry(avp, &ctx->vifs, list) { | ||
953 | if (ctx->nvifs_assigned != 1) | ||
954 | continue; | ||
955 | |||
956 | if (!avp->vif->p2p || !iter_data->has_hw_macaddr) | ||
957 | continue; | ||
958 | |||
959 | ether_addr_copy(common->curbssid, avp->bssid); | ||
960 | |||
961 | /* perm_addr will be used as the p2p device address. */ | ||
962 | for (i = 0; i < ETH_ALEN; i++) | ||
963 | iter_data->mask[i] &= | ||
964 | ~(iter_data->hw_macaddr[i] ^ | ||
965 | sc->hw->wiphy->perm_addr[i]); | ||
966 | } | ||
967 | } | ||
968 | |||
942 | /* Called with sc->mutex held. */ | 969 | /* Called with sc->mutex held. */ |
943 | void ath9k_calculate_iter_data(struct ath_softc *sc, | 970 | void ath9k_calculate_iter_data(struct ath_softc *sc, |
944 | struct ath_chanctx *ctx, | 971 | struct ath_chanctx *ctx, |
@@ -957,19 +984,21 @@ void ath9k_calculate_iter_data(struct ath_softc *sc, | |||
957 | 984 | ||
958 | list_for_each_entry(avp, &ctx->vifs, list) | 985 | list_for_each_entry(avp, &ctx->vifs, list) |
959 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); | 986 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); |
987 | |||
988 | ath9k_update_bssid_mask(sc, ctx, iter_data); | ||
960 | } | 989 | } |
961 | 990 | ||
962 | static void ath9k_set_assoc_state(struct ath_softc *sc, | 991 | static void ath9k_set_assoc_state(struct ath_softc *sc, |
963 | struct ieee80211_vif *vif, bool changed) | 992 | struct ieee80211_vif *vif, bool changed) |
964 | { | 993 | { |
965 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 994 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
966 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 995 | struct ath_vif *avp = (struct ath_vif *)vif->drv_priv; |
967 | unsigned long flags; | 996 | unsigned long flags; |
968 | 997 | ||
969 | set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); | 998 | set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); |
970 | 999 | ||
971 | ether_addr_copy(common->curbssid, bss_conf->bssid); | 1000 | ether_addr_copy(common->curbssid, avp->bssid); |
972 | common->curaid = bss_conf->aid; | 1001 | common->curaid = avp->aid; |
973 | ath9k_hw_write_associd(sc->sc_ah); | 1002 | ath9k_hw_write_associd(sc->sc_ah); |
974 | 1003 | ||
975 | if (changed) { | 1004 | if (changed) { |
@@ -1121,6 +1150,10 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1121 | else | 1150 | else |
1122 | clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); | 1151 | clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); |
1123 | 1152 | ||
1153 | ath_dbg(common, CONFIG, | ||
1154 | "macaddr: %pM, bssid: %pM, bssidmask: %pM\n", | ||
1155 | common->macaddr, common->curbssid, common->bssidmask); | ||
1156 | |||
1124 | ath9k_ps_restore(sc); | 1157 | ath9k_ps_restore(sc); |
1125 | } | 1158 | } |
1126 | 1159 | ||
@@ -1698,6 +1731,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1698 | ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n", | 1731 | ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n", |
1699 | bss_conf->bssid, bss_conf->assoc); | 1732 | bss_conf->bssid, bss_conf->assoc); |
1700 | 1733 | ||
1734 | ether_addr_copy(avp->bssid, bss_conf->bssid); | ||
1735 | avp->aid = bss_conf->aid; | ||
1736 | avp->assoc = bss_conf->assoc; | ||
1737 | |||
1701 | ath9k_calculate_summary_state(sc, avp->chanctx); | 1738 | ath9k_calculate_summary_state(sc, avp->chanctx); |
1702 | 1739 | ||
1703 | if (ath9k_is_chanctx_enabled()) { | 1740 | if (ath9k_is_chanctx_enabled()) { |
@@ -1932,9 +1969,6 @@ static bool ath9k_has_tx_pending(struct ath_softc *sc) | |||
1932 | if (!ATH_TXQ_SETUP(sc, i)) | 1969 | if (!ATH_TXQ_SETUP(sc, i)) |
1933 | continue; | 1970 | continue; |
1934 | 1971 | ||
1935 | if (!sc->tx.txq[i].axq_depth) | ||
1936 | continue; | ||
1937 | |||
1938 | npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]); | 1972 | npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]); |
1939 | if (npend) | 1973 | if (npend) |
1940 | break; | 1974 | break; |
@@ -1960,7 +1994,6 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
1960 | struct ath_common *common = ath9k_hw_common(ah); | 1994 | struct ath_common *common = ath9k_hw_common(ah); |
1961 | int timeout = HZ / 5; /* 200 ms */ | 1995 | int timeout = HZ / 5; /* 200 ms */ |
1962 | bool drain_txq; | 1996 | bool drain_txq; |
1963 | int i; | ||
1964 | 1997 | ||
1965 | cancel_delayed_work_sync(&sc->tx_complete_work); | 1998 | cancel_delayed_work_sync(&sc->tx_complete_work); |
1966 | 1999 | ||
@@ -1988,10 +2021,6 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
1988 | ath_reset(sc); | 2021 | ath_reset(sc); |
1989 | 2022 | ||
1990 | ath9k_ps_restore(sc); | 2023 | ath9k_ps_restore(sc); |
1991 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | ||
1992 | ieee80211_wake_queue(sc->hw, | ||
1993 | sc->cur_chan->hw_queue_base + i); | ||
1994 | } | ||
1995 | } | 2024 | } |
1996 | 2025 | ||
1997 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); | 2026 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); |
@@ -2000,16 +2029,8 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) | |||
2000 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | 2029 | static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) |
2001 | { | 2030 | { |
2002 | struct ath_softc *sc = hw->priv; | 2031 | struct ath_softc *sc = hw->priv; |
2003 | int i; | ||
2004 | 2032 | ||
2005 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 2033 | return ath9k_has_tx_pending(sc); |
2006 | if (!ATH_TXQ_SETUP(sc, i)) | ||
2007 | continue; | ||
2008 | |||
2009 | if (ath9k_has_pending_frames(sc, &sc->tx.txq[i])) | ||
2010 | return true; | ||
2011 | } | ||
2012 | return false; | ||
2013 | } | 2034 | } |
2014 | 2035 | ||
2015 | static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | 2036 | static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -2351,6 +2372,7 @@ static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw, | |||
2351 | conf->def.chan->center_freq); | 2372 | conf->def.chan->center_freq); |
2352 | 2373 | ||
2353 | avp->chanctx = ctx; | 2374 | avp->chanctx = ctx; |
2375 | ctx->nvifs_assigned++; | ||
2354 | list_add_tail(&avp->list, &ctx->vifs); | 2376 | list_add_tail(&avp->list, &ctx->vifs); |
2355 | ath9k_calculate_summary_state(sc, ctx); | 2377 | ath9k_calculate_summary_state(sc, ctx); |
2356 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | 2378 | for (i = 0; i < IEEE80211_NUM_ACS; i++) |
@@ -2379,6 +2401,7 @@ static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw, | |||
2379 | conf->def.chan->center_freq); | 2401 | conf->def.chan->center_freq); |
2380 | 2402 | ||
2381 | avp->chanctx = NULL; | 2403 | avp->chanctx = NULL; |
2404 | ctx->nvifs_assigned--; | ||
2382 | list_del(&avp->list); | 2405 | list_del(&avp->list); |
2383 | ath9k_calculate_summary_state(sc, ctx); | 2406 | ath9k_calculate_summary_state(sc, ctx); |
2384 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 2407 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index a1499700bcf2..2a938f4feac5 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -903,6 +903,10 @@ | |||
903 | #define AR_SREV_9340(_ah) \ | 903 | #define AR_SREV_9340(_ah) \ |
904 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340)) | 904 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340)) |
905 | 905 | ||
906 | #define AR_SREV_9340_13(_ah) \ | ||
907 | (AR_SREV_9340((_ah)) && \ | ||
908 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9340_13)) | ||
909 | |||
906 | #define AR_SREV_9340_13_OR_LATER(_ah) \ | 910 | #define AR_SREV_9340_13_OR_LATER(_ah) \ |
907 | (AR_SREV_9340((_ah)) && \ | 911 | (AR_SREV_9340((_ah)) && \ |
908 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9340_13)) | 912 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9340_13)) |
@@ -1240,12 +1244,23 @@ enum { | |||
1240 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 | 1244 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 |
1241 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 | 1245 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 |
1242 | 1246 | ||
1247 | #define AR_RTC_9300_SOC_PLL_DIV_INT 0x0000003f | ||
1248 | #define AR_RTC_9300_SOC_PLL_DIV_INT_S 0 | ||
1249 | #define AR_RTC_9300_SOC_PLL_DIV_FRAC 0x000fffc0 | ||
1250 | #define AR_RTC_9300_SOC_PLL_DIV_FRAC_S 6 | ||
1251 | #define AR_RTC_9300_SOC_PLL_REFDIV 0x01f00000 | ||
1252 | #define AR_RTC_9300_SOC_PLL_REFDIV_S 20 | ||
1253 | #define AR_RTC_9300_SOC_PLL_CLKSEL 0x06000000 | ||
1254 | #define AR_RTC_9300_SOC_PLL_CLKSEL_S 25 | ||
1255 | #define AR_RTC_9300_SOC_PLL_BYPASS 0x08000000 | ||
1256 | |||
1243 | #define AR_RTC_9300_PLL_DIV 0x000003ff | 1257 | #define AR_RTC_9300_PLL_DIV 0x000003ff |
1244 | #define AR_RTC_9300_PLL_DIV_S 0 | 1258 | #define AR_RTC_9300_PLL_DIV_S 0 |
1245 | #define AR_RTC_9300_PLL_REFDIV 0x00003C00 | 1259 | #define AR_RTC_9300_PLL_REFDIV 0x00003C00 |
1246 | #define AR_RTC_9300_PLL_REFDIV_S 10 | 1260 | #define AR_RTC_9300_PLL_REFDIV_S 10 |
1247 | #define AR_RTC_9300_PLL_CLKSEL 0x0000C000 | 1261 | #define AR_RTC_9300_PLL_CLKSEL 0x0000C000 |
1248 | #define AR_RTC_9300_PLL_CLKSEL_S 14 | 1262 | #define AR_RTC_9300_PLL_CLKSEL_S 14 |
1263 | #define AR_RTC_9300_PLL_BYPASS 0x00010000 | ||
1249 | 1264 | ||
1250 | #define AR_RTC_9160_PLL_DIV 0x000003ff | 1265 | #define AR_RTC_9160_PLL_DIV 0x000003ff |
1251 | #define AR_RTC_9160_PLL_DIV_S 0 | 1266 | #define AR_RTC_9160_PLL_DIV_S 0 |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 93ad31be0ada..151ae49fa57e 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -158,7 +158,6 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | |||
158 | { | 158 | { |
159 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 159 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
160 | struct ath_frame_info *fi = get_frame_info(skb); | 160 | struct ath_frame_info *fi = get_frame_info(skb); |
161 | int hw_queue; | ||
162 | int q = fi->txq; | 161 | int q = fi->txq; |
163 | 162 | ||
164 | if (q < 0) | 163 | if (q < 0) |
@@ -168,10 +167,9 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, | |||
168 | if (WARN_ON(--txq->pending_frames < 0)) | 167 | if (WARN_ON(--txq->pending_frames < 0)) |
169 | txq->pending_frames = 0; | 168 | txq->pending_frames = 0; |
170 | 169 | ||
171 | hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue; | ||
172 | if (txq->stopped && | 170 | if (txq->stopped && |
173 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | 171 | txq->pending_frames < sc->tx.txq_max_pending[q]) { |
174 | ieee80211_wake_queue(sc->hw, hw_queue); | 172 | ieee80211_wake_queue(sc->hw, info->hw_queue); |
175 | txq->stopped = false; | 173 | txq->stopped = false; |
176 | } | 174 | } |
177 | } | 175 | } |
@@ -685,6 +683,8 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | |||
685 | if (bf_is_ampdu_not_probing(bf)) | 683 | if (bf_is_ampdu_not_probing(bf)) |
686 | txq->axq_ampdu_depth--; | 684 | txq->axq_ampdu_depth--; |
687 | 685 | ||
686 | ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, | ||
687 | ts->ts_rateindex); | ||
688 | if (!bf_isampdu(bf)) { | 688 | if (!bf_isampdu(bf)) { |
689 | if (!flush) { | 689 | if (!flush) { |
690 | info = IEEE80211_SKB_CB(bf->bf_mpdu); | 690 | info = IEEE80211_SKB_CB(bf->bf_mpdu); |
@@ -1841,15 +1841,17 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
1841 | if (txq->mac80211_qnum < 0) | 1841 | if (txq->mac80211_qnum < 0) |
1842 | return; | 1842 | return; |
1843 | 1843 | ||
1844 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) | ||
1845 | return; | ||
1846 | |||
1844 | spin_lock_bh(&sc->chan_lock); | 1847 | spin_lock_bh(&sc->chan_lock); |
1845 | ac_list = &sc->cur_chan->acq[txq->mac80211_qnum]; | 1848 | ac_list = &sc->cur_chan->acq[txq->mac80211_qnum]; |
1846 | spin_unlock_bh(&sc->chan_lock); | ||
1847 | 1849 | ||
1848 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags) || | 1850 | if (list_empty(ac_list)) { |
1849 | list_empty(ac_list)) | 1851 | spin_unlock_bh(&sc->chan_lock); |
1850 | return; | 1852 | return; |
1853 | } | ||
1851 | 1854 | ||
1852 | spin_lock_bh(&sc->chan_lock); | ||
1853 | rcu_read_lock(); | 1855 | rcu_read_lock(); |
1854 | 1856 | ||
1855 | last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list); | 1857 | last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list); |
@@ -2207,9 +2209,8 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2207 | struct ath_txq *txq = txctl->txq; | 2209 | struct ath_txq *txq = txctl->txq; |
2208 | struct ath_atx_tid *tid = NULL; | 2210 | struct ath_atx_tid *tid = NULL; |
2209 | struct ath_buf *bf; | 2211 | struct ath_buf *bf; |
2210 | bool queue; | 2212 | bool queue, skip_uapsd = false; |
2211 | int q, hw_queue; | 2213 | int q, ret; |
2212 | int ret; | ||
2213 | 2214 | ||
2214 | if (vif) | 2215 | if (vif) |
2215 | avp = (void *)vif->drv_priv; | 2216 | avp = (void *)vif->drv_priv; |
@@ -2228,14 +2229,13 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2228 | */ | 2229 | */ |
2229 | 2230 | ||
2230 | q = skb_get_queue_mapping(skb); | 2231 | q = skb_get_queue_mapping(skb); |
2231 | hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue; | ||
2232 | 2232 | ||
2233 | ath_txq_lock(sc, txq); | 2233 | ath_txq_lock(sc, txq); |
2234 | if (txq == sc->tx.txq_map[q]) { | 2234 | if (txq == sc->tx.txq_map[q]) { |
2235 | fi->txq = q; | 2235 | fi->txq = q; |
2236 | if (++txq->pending_frames > sc->tx.txq_max_pending[q] && | 2236 | if (++txq->pending_frames > sc->tx.txq_max_pending[q] && |
2237 | !txq->stopped) { | 2237 | !txq->stopped) { |
2238 | ieee80211_stop_queue(sc->hw, hw_queue); | 2238 | ieee80211_stop_queue(sc->hw, info->hw_queue); |
2239 | txq->stopped = true; | 2239 | txq->stopped = true; |
2240 | } | 2240 | } |
2241 | } | 2241 | } |
@@ -2250,15 +2250,14 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2250 | sc->cur_chan->stopped) && !txctl->force_channel) { | 2250 | sc->cur_chan->stopped) && !txctl->force_channel) { |
2251 | if (!txctl->an) | 2251 | if (!txctl->an) |
2252 | txctl->an = &avp->mcast_node; | 2252 | txctl->an = &avp->mcast_node; |
2253 | info->flags &= ~IEEE80211_TX_CTL_PS_RESPONSE; | ||
2254 | queue = true; | 2253 | queue = true; |
2254 | skip_uapsd = true; | ||
2255 | } | 2255 | } |
2256 | 2256 | ||
2257 | if (txctl->an && queue) | 2257 | if (txctl->an && queue) |
2258 | tid = ath_get_skb_tid(sc, txctl->an, skb); | 2258 | tid = ath_get_skb_tid(sc, txctl->an, skb); |
2259 | 2259 | ||
2260 | if (info->flags & (IEEE80211_TX_CTL_PS_RESPONSE | | 2260 | if (!skip_uapsd && (info->flags & IEEE80211_TX_CTL_PS_RESPONSE)) { |
2261 | IEEE80211_TX_CTL_TX_OFFCHAN)) { | ||
2262 | ath_txq_unlock(sc, txq); | 2261 | ath_txq_unlock(sc, txq); |
2263 | txq = sc->tx.uapsdq; | 2262 | txq = sc->tx.uapsdq; |
2264 | ath_txq_lock(sc, txq); | 2263 | ath_txq_lock(sc, txq); |
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index 8b0ac14d5c32..83f47af19280 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | 21 | ||
22 | #include "ath.h" | 22 | #include "ath.h" |
23 | #include "trace.h" | ||
23 | 24 | ||
24 | MODULE_AUTHOR("Atheros Communications"); | 25 | MODULE_AUTHOR("Atheros Communications"); |
25 | MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards."); | 26 | MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards."); |
@@ -84,6 +85,8 @@ void ath_printk(const char *level, const struct ath_common* common, | |||
84 | else | 85 | else |
85 | printk("%sath: %pV", level, &vaf); | 86 | printk("%sath: %pV", level, &vaf); |
86 | 87 | ||
88 | trace_ath_log(common->hw->wiphy, &vaf); | ||
89 | |||
87 | va_end(args); | 90 | va_end(args); |
88 | } | 91 | } |
89 | EXPORT_SYMBOL(ath_printk); | 92 | EXPORT_SYMBOL(ath_printk); |
diff --git a/drivers/net/wireless/ath/trace.c b/drivers/net/wireless/ath/trace.c new file mode 100644 index 000000000000..18fb3a071931 --- /dev/null +++ b/drivers/net/wireless/ath/trace.c | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | |||
19 | #define CREATE_TRACE_POINTS | ||
20 | #include "trace.h" | ||
diff --git a/drivers/net/wireless/ath/trace.h b/drivers/net/wireless/ath/trace.h new file mode 100644 index 000000000000..ba711644d27e --- /dev/null +++ b/drivers/net/wireless/ath/trace.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #if !defined(_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
18 | #define _TRACE_H | ||
19 | |||
20 | #include <linux/tracepoint.h> | ||
21 | #include "ath.h" | ||
22 | |||
23 | #undef TRACE_SYSTEM | ||
24 | #define TRACE_SYSTEM ath | ||
25 | |||
26 | #if !defined(CONFIG_ATH_TRACEPOINTS) | ||
27 | |||
28 | #undef TRACE_EVENT | ||
29 | #define TRACE_EVENT(name, proto, ...) static inline void trace_ ## name(proto) {} | ||
30 | |||
31 | #endif /* CONFIG_ATH_TRACEPOINTS */ | ||
32 | |||
33 | TRACE_EVENT(ath_log, | ||
34 | |||
35 | TP_PROTO(struct wiphy *wiphy, | ||
36 | struct va_format *vaf), | ||
37 | |||
38 | TP_ARGS(wiphy, vaf), | ||
39 | |||
40 | TP_STRUCT__entry( | ||
41 | __string(device, wiphy_name(wiphy)) | ||
42 | __string(driver, KBUILD_MODNAME) | ||
43 | __dynamic_array(char, msg, ATH_DBG_MAX_LEN) | ||
44 | ), | ||
45 | |||
46 | TP_fast_assign( | ||
47 | __assign_str(device, wiphy_name(wiphy)); | ||
48 | __assign_str(driver, KBUILD_MODNAME); | ||
49 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | ||
50 | ATH_DBG_MAX_LEN, | ||
51 | vaf->fmt, | ||
52 | *vaf->va) >= ATH_DBG_MAX_LEN); | ||
53 | ), | ||
54 | |||
55 | TP_printk( | ||
56 | "%s %s %s", | ||
57 | __get_str(driver), | ||
58 | __get_str(device), | ||
59 | __get_str(msg) | ||
60 | ) | ||
61 | ); | ||
62 | |||
63 | #endif /* _TRACE_H || TRACE_HEADER_MULTI_READ */ | ||
64 | |||
65 | #undef TRACE_INCLUDE_PATH | ||
66 | #define TRACE_INCLUDE_PATH . | ||
67 | #undef TRACE_INCLUDE_FILE | ||
68 | #define TRACE_INCLUDE_FILE trace | ||
69 | |||
70 | /* This part must be outside protection */ | ||
71 | #include <trace/define_trace.h> | ||
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile index a471d74ae409..8ad4b5f97e04 100644 --- a/drivers/net/wireless/ath/wil6210/Makefile +++ b/drivers/net/wireless/ath/wil6210/Makefile | |||
@@ -10,10 +10,12 @@ wil6210-y += interrupt.o | |||
10 | wil6210-y += txrx.o | 10 | wil6210-y += txrx.o |
11 | wil6210-y += debug.o | 11 | wil6210-y += debug.o |
12 | wil6210-y += rx_reorder.o | 12 | wil6210-y += rx_reorder.o |
13 | wil6210-y += ioctl.o | ||
13 | wil6210-y += fw.o | 14 | wil6210-y += fw.o |
14 | wil6210-$(CONFIG_WIL6210_TRACING) += trace.o | 15 | wil6210-$(CONFIG_WIL6210_TRACING) += trace.o |
15 | wil6210-y += wil_platform.o | 16 | wil6210-y += wil_platform.o |
16 | wil6210-$(CONFIG_WIL6210_PLATFORM_MSM) += wil_platform_msm.o | 17 | wil6210-$(CONFIG_WIL6210_PLATFORM_MSM) += wil_platform_msm.o |
18 | wil6210-y += ethtool.o | ||
17 | 19 | ||
18 | # for tracing framework to find trace.h | 20 | # for tracing framework to find trace.h |
19 | CFLAGS_trace.o := -I$(src) | 21 | CFLAGS_trace.o := -I$(src) |
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index f3a31e8c2535..d9f4b30dd343 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -728,6 +728,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, | |||
728 | wil_print_bcon_data(bcon); | 728 | wil_print_bcon_data(bcon); |
729 | } | 729 | } |
730 | 730 | ||
731 | wil_set_recovery_state(wil, fw_recovery_idle); | ||
732 | |||
731 | mutex_lock(&wil->mutex); | 733 | mutex_lock(&wil->mutex); |
732 | 734 | ||
733 | __wil_down(wil); | 735 | __wil_down(wil); |
@@ -775,6 +777,8 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, | |||
775 | 777 | ||
776 | wil_dbg_misc(wil, "%s()\n", __func__); | 778 | wil_dbg_misc(wil, "%s()\n", __func__); |
777 | 779 | ||
780 | wil_set_recovery_state(wil, fw_recovery_idle); | ||
781 | |||
778 | mutex_lock(&wil->mutex); | 782 | mutex_lock(&wil->mutex); |
779 | 783 | ||
780 | rc = wmi_pcp_stop(wil); | 784 | rc = wmi_pcp_stop(wil); |
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index eb2204e5fdd4..54a6ddc6301b 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c | |||
@@ -1041,6 +1041,71 @@ static const struct file_operations fops_info = { | |||
1041 | .llseek = seq_lseek, | 1041 | .llseek = seq_lseek, |
1042 | }; | 1042 | }; |
1043 | 1043 | ||
1044 | /*---------recovery------------*/ | ||
1045 | /* mode = [manual|auto] | ||
1046 | * state = [idle|pending|running] | ||
1047 | */ | ||
1048 | static ssize_t wil_read_file_recovery(struct file *file, char __user *user_buf, | ||
1049 | size_t count, loff_t *ppos) | ||
1050 | { | ||
1051 | struct wil6210_priv *wil = file->private_data; | ||
1052 | char buf[80]; | ||
1053 | int n; | ||
1054 | static const char * const sstate[] = {"idle", "pending", "running"}; | ||
1055 | |||
1056 | n = snprintf(buf, sizeof(buf), "mode = %s\nstate = %s\n", | ||
1057 | no_fw_recovery ? "manual" : "auto", | ||
1058 | sstate[wil->recovery_state]); | ||
1059 | |||
1060 | n = min_t(int, n, sizeof(buf)); | ||
1061 | |||
1062 | return simple_read_from_buffer(user_buf, count, ppos, | ||
1063 | buf, n); | ||
1064 | } | ||
1065 | |||
1066 | static ssize_t wil_write_file_recovery(struct file *file, | ||
1067 | const char __user *buf_, | ||
1068 | size_t count, loff_t *ppos) | ||
1069 | { | ||
1070 | struct wil6210_priv *wil = file->private_data; | ||
1071 | static const char run_command[] = "run"; | ||
1072 | char buf[sizeof(run_command) + 1]; /* to detect "runx" */ | ||
1073 | ssize_t rc; | ||
1074 | |||
1075 | if (wil->recovery_state != fw_recovery_pending) { | ||
1076 | wil_err(wil, "No recovery pending\n"); | ||
1077 | return -EINVAL; | ||
1078 | } | ||
1079 | |||
1080 | if (*ppos != 0) { | ||
1081 | wil_err(wil, "Offset [%d]\n", (int)*ppos); | ||
1082 | return -EINVAL; | ||
1083 | } | ||
1084 | |||
1085 | if (count > sizeof(buf)) { | ||
1086 | wil_err(wil, "Input too long, len = %d\n", (int)count); | ||
1087 | return -EINVAL; | ||
1088 | } | ||
1089 | |||
1090 | rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, buf_, count); | ||
1091 | if (rc < 0) | ||
1092 | return rc; | ||
1093 | |||
1094 | buf[rc] = '\0'; | ||
1095 | if (0 == strcmp(buf, run_command)) | ||
1096 | wil_set_recovery_state(wil, fw_recovery_running); | ||
1097 | else | ||
1098 | wil_err(wil, "Bad recovery command \"%s\"\n", buf); | ||
1099 | |||
1100 | return rc; | ||
1101 | } | ||
1102 | |||
1103 | static const struct file_operations fops_recovery = { | ||
1104 | .read = wil_read_file_recovery, | ||
1105 | .write = wil_write_file_recovery, | ||
1106 | .open = simple_open, | ||
1107 | }; | ||
1108 | |||
1044 | /*---------Station matrix------------*/ | 1109 | /*---------Station matrix------------*/ |
1045 | static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) | 1110 | static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) |
1046 | { | 1111 | { |
@@ -1152,6 +1217,7 @@ static const struct { | |||
1152 | {"freq", S_IRUGO, &fops_freq}, | 1217 | {"freq", S_IRUGO, &fops_freq}, |
1153 | {"link", S_IRUGO, &fops_link}, | 1218 | {"link", S_IRUGO, &fops_link}, |
1154 | {"info", S_IRUGO, &fops_info}, | 1219 | {"info", S_IRUGO, &fops_info}, |
1220 | {"recovery", S_IRUGO | S_IWUSR, &fops_recovery}, | ||
1155 | }; | 1221 | }; |
1156 | 1222 | ||
1157 | static void wil6210_debugfs_init_files(struct wil6210_priv *wil, | 1223 | static void wil6210_debugfs_init_files(struct wil6210_priv *wil, |
@@ -1194,6 +1260,7 @@ static const struct dbg_off dbg_wil_off[] = { | |||
1194 | WIL_FIELD(status, S_IRUGO | S_IWUSR, doff_ulong), | 1260 | WIL_FIELD(status, S_IRUGO | S_IWUSR, doff_ulong), |
1195 | WIL_FIELD(fw_version, S_IRUGO, doff_u32), | 1261 | WIL_FIELD(fw_version, S_IRUGO, doff_u32), |
1196 | WIL_FIELD(hw_version, S_IRUGO, doff_x32), | 1262 | WIL_FIELD(hw_version, S_IRUGO, doff_x32), |
1263 | WIL_FIELD(recovery_count, S_IRUGO, doff_u32), | ||
1197 | {}, | 1264 | {}, |
1198 | }; | 1265 | }; |
1199 | 1266 | ||
diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c new file mode 100644 index 000000000000..d686638972be --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/ethtool.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/rtnetlink.h> | ||
20 | #include <net/cfg80211.h> | ||
21 | |||
22 | #include "wil6210.h" | ||
23 | |||
24 | static int wil_ethtoolops_begin(struct net_device *ndev) | ||
25 | { | ||
26 | struct wil6210_priv *wil = ndev_to_wil(ndev); | ||
27 | |||
28 | mutex_lock(&wil->mutex); | ||
29 | |||
30 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
31 | |||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static void wil_ethtoolops_complete(struct net_device *ndev) | ||
36 | { | ||
37 | struct wil6210_priv *wil = ndev_to_wil(ndev); | ||
38 | |||
39 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
40 | |||
41 | mutex_unlock(&wil->mutex); | ||
42 | } | ||
43 | |||
44 | static int wil_ethtoolops_get_coalesce(struct net_device *ndev, | ||
45 | struct ethtool_coalesce *cp) | ||
46 | { | ||
47 | struct wil6210_priv *wil = ndev_to_wil(ndev); | ||
48 | u32 itr_en, itr_val = 0; | ||
49 | |||
50 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
51 | |||
52 | itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); | ||
53 | if (itr_en & BIT_DMA_ITR_CNT_CRL_EN) | ||
54 | itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); | ||
55 | |||
56 | cp->rx_coalesce_usecs = itr_val; | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int wil_ethtoolops_set_coalesce(struct net_device *ndev, | ||
62 | struct ethtool_coalesce *cp) | ||
63 | { | ||
64 | struct wil6210_priv *wil = ndev_to_wil(ndev); | ||
65 | |||
66 | wil_dbg_misc(wil, "%s(%d usec)\n", __func__, cp->rx_coalesce_usecs); | ||
67 | |||
68 | if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { | ||
69 | wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | /* only @rx_coalesce_usecs supported, ignore | ||
74 | * other parameters | ||
75 | */ | ||
76 | |||
77 | if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX) | ||
78 | goto out_bad; | ||
79 | |||
80 | wil->itr_trsh = cp->rx_coalesce_usecs; | ||
81 | wil_set_itr_trsh(wil); | ||
82 | |||
83 | return 0; | ||
84 | |||
85 | out_bad: | ||
86 | wil_dbg_misc(wil, "Unsupported coalescing params. Raw command:\n"); | ||
87 | print_hex_dump_debug("DBG[MISC] coal ", DUMP_PREFIX_OFFSET, 16, 4, | ||
88 | cp, sizeof(*cp), false); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | static const struct ethtool_ops wil_ethtool_ops = { | ||
93 | .begin = wil_ethtoolops_begin, | ||
94 | .complete = wil_ethtoolops_complete, | ||
95 | .get_drvinfo = cfg80211_get_drvinfo, | ||
96 | .get_coalesce = wil_ethtoolops_get_coalesce, | ||
97 | .set_coalesce = wil_ethtoolops_set_coalesce, | ||
98 | }; | ||
99 | |||
100 | void wil_set_ethtoolops(struct net_device *ndev) | ||
101 | { | ||
102 | ndev->ethtool_ops = &wil_ethtool_ops; | ||
103 | } | ||
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 7269bac111b9..90f416f239bd 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c | |||
@@ -157,17 +157,7 @@ void wil_unmask_irq(struct wil6210_priv *wil) | |||
157 | offsetof(struct RGF_ICR, ICC)); | 157 | offsetof(struct RGF_ICR, ICC)); |
158 | 158 | ||
159 | /* interrupt moderation parameters */ | 159 | /* interrupt moderation parameters */ |
160 | if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { | 160 | wil_set_itr_trsh(wil); |
161 | /* disable interrupt moderation for monitor | ||
162 | * to get better timestamp precision | ||
163 | */ | ||
164 | iowrite32(0, wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); | ||
165 | } else { | ||
166 | iowrite32(WIL6210_ITR_TRSH, | ||
167 | wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); | ||
168 | iowrite32(BIT_DMA_ITR_CNT_CRL_EN, | ||
169 | wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); | ||
170 | } | ||
171 | 161 | ||
172 | wil6210_unmask_irq_pseudo(wil); | 162 | wil6210_unmask_irq_pseudo(wil); |
173 | wil6210_unmask_irq_tx(wil); | 163 | wil6210_unmask_irq_tx(wil); |
diff --git a/drivers/net/wireless/ath/wil6210/ioctl.c b/drivers/net/wireless/ath/wil6210/ioctl.c new file mode 100644 index 000000000000..e9c0673819c6 --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/ioctl.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/uaccess.h> | ||
18 | |||
19 | #include "wil6210.h" | ||
20 | #include <uapi/linux/wil6210_uapi.h> | ||
21 | |||
22 | #define wil_hex_dump_ioctl(prefix_str, buf, len) \ | ||
23 | print_hex_dump_debug("DBG[IOC ]" prefix_str, \ | ||
24 | DUMP_PREFIX_OFFSET, 16, 1, buf, len, true) | ||
25 | #define wil_dbg_ioctl(wil, fmt, arg...) wil_dbg(wil, "DBG[IOC ]" fmt, ##arg) | ||
26 | |||
27 | static void __iomem *wil_ioc_addr(struct wil6210_priv *wil, uint32_t addr, | ||
28 | uint32_t size, enum wil_memio_op op) | ||
29 | { | ||
30 | void __iomem *a; | ||
31 | u32 off; | ||
32 | |||
33 | switch (op & wil_mmio_addr_mask) { | ||
34 | case wil_mmio_addr_linker: | ||
35 | a = wmi_buffer(wil, cpu_to_le32(addr)); | ||
36 | break; | ||
37 | case wil_mmio_addr_ahb: | ||
38 | a = wmi_addr(wil, addr); | ||
39 | break; | ||
40 | case wil_mmio_addr_bar: | ||
41 | a = wmi_addr(wil, addr + WIL6210_FW_HOST_OFF); | ||
42 | break; | ||
43 | default: | ||
44 | wil_err(wil, "Unsupported address mode, op = 0x%08x\n", op); | ||
45 | return NULL; | ||
46 | } | ||
47 | |||
48 | off = a - wil->csr; | ||
49 | if (size >= WIL6210_MEM_SIZE - off) { | ||
50 | wil_err(wil, "Requested block does not fit into memory: " | ||
51 | "off = 0x%08x size = 0x%08x\n", off, size); | ||
52 | return NULL; | ||
53 | } | ||
54 | |||
55 | return a; | ||
56 | } | ||
57 | |||
58 | static int wil_ioc_memio_dword(struct wil6210_priv *wil, void __user *data) | ||
59 | { | ||
60 | struct wil_memio io; | ||
61 | void __iomem *a; | ||
62 | bool need_copy = false; | ||
63 | |||
64 | if (copy_from_user(&io, data, sizeof(io))) | ||
65 | return -EFAULT; | ||
66 | |||
67 | wil_dbg_ioctl(wil, "IO: addr = 0x%08x val = 0x%08x op = 0x%08x\n", | ||
68 | io.addr, io.val, io.op); | ||
69 | |||
70 | a = wil_ioc_addr(wil, io.addr, sizeof(u32), io.op); | ||
71 | if (!a) { | ||
72 | wil_err(wil, "invalid address 0x%08x, op = 0x%08x\n", io.addr, | ||
73 | io.op); | ||
74 | return -EINVAL; | ||
75 | } | ||
76 | /* operation */ | ||
77 | switch (io.op & wil_mmio_op_mask) { | ||
78 | case wil_mmio_read: | ||
79 | io.val = ioread32(a); | ||
80 | need_copy = true; | ||
81 | break; | ||
82 | case wil_mmio_write: | ||
83 | iowrite32(io.val, a); | ||
84 | wmb(); /* make sure write propagated to HW */ | ||
85 | break; | ||
86 | default: | ||
87 | wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op); | ||
88 | return -EINVAL; | ||
89 | } | ||
90 | |||
91 | if (need_copy) { | ||
92 | wil_dbg_ioctl(wil, "IO done: addr = 0x%08x" | ||
93 | " val = 0x%08x op = 0x%08x\n", | ||
94 | io.addr, io.val, io.op); | ||
95 | if (copy_to_user(data, &io, sizeof(io))) | ||
96 | return -EFAULT; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int wil_ioc_memio_block(struct wil6210_priv *wil, void __user *data) | ||
103 | { | ||
104 | struct wil_memio_block io; | ||
105 | void *block; | ||
106 | void __iomem *a; | ||
107 | int rc = 0; | ||
108 | |||
109 | if (copy_from_user(&io, data, sizeof(io))) | ||
110 | return -EFAULT; | ||
111 | |||
112 | wil_dbg_ioctl(wil, "IO: addr = 0x%08x size = 0x%08x op = 0x%08x\n", | ||
113 | io.addr, io.size, io.op); | ||
114 | |||
115 | /* size */ | ||
116 | if (io.size % 4) { | ||
117 | wil_err(wil, "size is not multiple of 4: 0x%08x\n", io.size); | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | |||
121 | a = wil_ioc_addr(wil, io.addr, io.size, io.op); | ||
122 | if (!a) { | ||
123 | wil_err(wil, "invalid address 0x%08x, op = 0x%08x\n", io.addr, | ||
124 | io.op); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | |||
128 | block = kmalloc(io.size, GFP_USER); | ||
129 | if (!block) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | /* operation */ | ||
133 | switch (io.op & wil_mmio_op_mask) { | ||
134 | case wil_mmio_read: | ||
135 | wil_memcpy_fromio_32(block, a, io.size); | ||
136 | wil_hex_dump_ioctl("Read ", block, io.size); | ||
137 | if (copy_to_user(io.block, block, io.size)) { | ||
138 | rc = -EFAULT; | ||
139 | goto out_free; | ||
140 | } | ||
141 | break; | ||
142 | case wil_mmio_write: | ||
143 | if (copy_from_user(block, io.block, io.size)) { | ||
144 | rc = -EFAULT; | ||
145 | goto out_free; | ||
146 | } | ||
147 | wil_memcpy_toio_32(a, block, io.size); | ||
148 | wmb(); /* make sure write propagated to HW */ | ||
149 | wil_hex_dump_ioctl("Write ", block, io.size); | ||
150 | break; | ||
151 | default: | ||
152 | wil_err(wil, "Unsupported operation, op = 0x%08x\n", io.op); | ||
153 | rc = -EINVAL; | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | out_free: | ||
158 | kfree(block); | ||
159 | return rc; | ||
160 | } | ||
161 | |||
162 | int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd) | ||
163 | { | ||
164 | switch (cmd) { | ||
165 | case WIL_IOCTL_MEMIO: | ||
166 | return wil_ioc_memio_dword(wil, data); | ||
167 | case WIL_IOCTL_MEMIO_BLOCK: | ||
168 | return wil_ioc_memio_block(wil, data); | ||
169 | default: | ||
170 | wil_dbg_ioctl(wil, "Unsupported IOCTL 0x%04x\n", cmd); | ||
171 | return -ENOIOCTLCMD; | ||
172 | } | ||
173 | } | ||
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 21667e0c3d14..6500caf8d609 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c | |||
@@ -25,14 +25,19 @@ | |||
25 | #define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000 | 25 | #define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000 |
26 | #define WAIT_FOR_DISCONNECT_INTERVAL_MS 10 | 26 | #define WAIT_FOR_DISCONNECT_INTERVAL_MS 10 |
27 | 27 | ||
28 | static bool no_fw_recovery; | 28 | bool no_fw_recovery; |
29 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); | 29 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); |
30 | MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery"); | 30 | MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery"); |
31 | 31 | ||
32 | static bool no_fw_load = true; | 32 | static bool no_fw_load = true; |
33 | module_param(no_fw_load, bool, S_IRUGO | S_IWUSR); | 33 | module_param(no_fw_load, bool, S_IRUGO | S_IWUSR); |
34 | MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash."); | 34 | MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash."); |
35 | 35 | ||
36 | static unsigned int itr_trsh = WIL6210_ITR_TRSH_DEFAULT; | ||
37 | |||
38 | module_param(itr_trsh, uint, S_IRUGO); | ||
39 | MODULE_PARM_DESC(itr_trsh, " Interrupt moderation threshold, usecs."); | ||
40 | |||
36 | #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ | 41 | #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ |
37 | #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ | 42 | #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ |
38 | 43 | ||
@@ -186,17 +191,38 @@ static void wil_scan_timer_fn(ulong x) | |||
186 | schedule_work(&wil->fw_error_worker); | 191 | schedule_work(&wil->fw_error_worker); |
187 | } | 192 | } |
188 | 193 | ||
194 | static int wil_wait_for_recovery(struct wil6210_priv *wil) | ||
195 | { | ||
196 | if (wait_event_interruptible(wil->wq, wil->recovery_state != | ||
197 | fw_recovery_pending)) { | ||
198 | wil_err(wil, "Interrupt, canceling recovery\n"); | ||
199 | return -ERESTARTSYS; | ||
200 | } | ||
201 | if (wil->recovery_state != fw_recovery_running) { | ||
202 | wil_info(wil, "Recovery cancelled\n"); | ||
203 | return -EINTR; | ||
204 | } | ||
205 | wil_info(wil, "Proceed with recovery\n"); | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | void wil_set_recovery_state(struct wil6210_priv *wil, int state) | ||
210 | { | ||
211 | wil_dbg_misc(wil, "%s(%d -> %d)\n", __func__, | ||
212 | wil->recovery_state, state); | ||
213 | |||
214 | wil->recovery_state = state; | ||
215 | wake_up_interruptible(&wil->wq); | ||
216 | } | ||
217 | |||
189 | static void wil_fw_error_worker(struct work_struct *work) | 218 | static void wil_fw_error_worker(struct work_struct *work) |
190 | { | 219 | { |
191 | struct wil6210_priv *wil = container_of(work, | 220 | struct wil6210_priv *wil = container_of(work, struct wil6210_priv, |
192 | struct wil6210_priv, fw_error_worker); | 221 | fw_error_worker); |
193 | struct wireless_dev *wdev = wil->wdev; | 222 | struct wireless_dev *wdev = wil->wdev; |
194 | 223 | ||
195 | wil_dbg_misc(wil, "fw error worker\n"); | 224 | wil_dbg_misc(wil, "fw error worker\n"); |
196 | 225 | ||
197 | if (no_fw_recovery) | ||
198 | return; | ||
199 | |||
200 | /* increment @recovery_count if less then WIL6210_FW_RECOVERY_TO | 226 | /* increment @recovery_count if less then WIL6210_FW_RECOVERY_TO |
201 | * passed since last recovery attempt | 227 | * passed since last recovery attempt |
202 | */ | 228 | */ |
@@ -219,8 +245,13 @@ static void wil_fw_error_worker(struct work_struct *work) | |||
219 | case NL80211_IFTYPE_STATION: | 245 | case NL80211_IFTYPE_STATION: |
220 | case NL80211_IFTYPE_P2P_CLIENT: | 246 | case NL80211_IFTYPE_P2P_CLIENT: |
221 | case NL80211_IFTYPE_MONITOR: | 247 | case NL80211_IFTYPE_MONITOR: |
222 | wil_info(wil, "fw error recovery started (try %d)...\n", | 248 | wil_info(wil, "fw error recovery requested (try %d)...\n", |
223 | wil->recovery_count); | 249 | wil->recovery_count); |
250 | if (!no_fw_recovery) | ||
251 | wil->recovery_state = fw_recovery_running; | ||
252 | if (0 != wil_wait_for_recovery(wil)) | ||
253 | break; | ||
254 | |||
224 | __wil_down(wil); | 255 | __wil_down(wil); |
225 | __wil_up(wil); | 256 | __wil_up(wil); |
226 | break; | 257 | break; |
@@ -297,6 +328,7 @@ int wil_priv_init(struct wil6210_priv *wil) | |||
297 | 328 | ||
298 | INIT_LIST_HEAD(&wil->pending_wmi_ev); | 329 | INIT_LIST_HEAD(&wil->pending_wmi_ev); |
299 | spin_lock_init(&wil->wmi_ev_lock); | 330 | spin_lock_init(&wil->wmi_ev_lock); |
331 | init_waitqueue_head(&wil->wq); | ||
300 | 332 | ||
301 | wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); | 333 | wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); |
302 | if (!wil->wmi_wq) | 334 | if (!wil->wmi_wq) |
@@ -309,6 +341,7 @@ int wil_priv_init(struct wil6210_priv *wil) | |||
309 | } | 341 | } |
310 | 342 | ||
311 | wil->last_fw_recovery = jiffies; | 343 | wil->last_fw_recovery = jiffies; |
344 | wil->itr_trsh = itr_trsh; | ||
312 | 345 | ||
313 | return 0; | 346 | return 0; |
314 | } | 347 | } |
@@ -325,6 +358,7 @@ void wil_priv_deinit(struct wil6210_priv *wil) | |||
325 | { | 358 | { |
326 | wil_dbg_misc(wil, "%s()\n", __func__); | 359 | wil_dbg_misc(wil, "%s()\n", __func__); |
327 | 360 | ||
361 | wil_set_recovery_state(wil, fw_recovery_idle); | ||
328 | del_timer_sync(&wil->scan_timer); | 362 | del_timer_sync(&wil->scan_timer); |
329 | cancel_work_sync(&wil->disconnect_worker); | 363 | cancel_work_sync(&wil->disconnect_worker); |
330 | cancel_work_sync(&wil->fw_error_worker); | 364 | cancel_work_sync(&wil->fw_error_worker); |
@@ -437,6 +471,26 @@ static int wil_target_reset(struct wil6210_priv *wil) | |||
437 | return 0; | 471 | return 0; |
438 | } | 472 | } |
439 | 473 | ||
474 | /** | ||
475 | * wil_set_itr_trsh: - apply interrupt coalescing params | ||
476 | */ | ||
477 | void wil_set_itr_trsh(struct wil6210_priv *wil) | ||
478 | { | ||
479 | /* disable, use usec resolution */ | ||
480 | W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EXT_TICK); | ||
481 | |||
482 | /* disable interrupt moderation for monitor | ||
483 | * to get better timestamp precision | ||
484 | */ | ||
485 | if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) | ||
486 | return; | ||
487 | |||
488 | wil_info(wil, "set ITR_TRSH = %d usec\n", wil->itr_trsh); | ||
489 | W(RGF_DMA_ITR_CNT_TRSH, wil->itr_trsh); | ||
490 | W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EN | | ||
491 | BIT_DMA_ITR_CNT_CRL_EXT_TICK); /* start it */ | ||
492 | } | ||
493 | |||
440 | #undef R | 494 | #undef R |
441 | #undef W | 495 | #undef W |
442 | #undef S | 496 | #undef S |
@@ -547,6 +601,7 @@ int wil_reset(struct wil6210_priv *wil) | |||
547 | void wil_fw_error_recovery(struct wil6210_priv *wil) | 601 | void wil_fw_error_recovery(struct wil6210_priv *wil) |
548 | { | 602 | { |
549 | wil_dbg_misc(wil, "starting fw error recovery\n"); | 603 | wil_dbg_misc(wil, "starting fw error recovery\n"); |
604 | wil->recovery_state = fw_recovery_pending; | ||
550 | schedule_work(&wil->fw_error_worker); | 605 | schedule_work(&wil->fw_error_worker); |
551 | } | 606 | } |
552 | 607 | ||
@@ -698,6 +753,7 @@ int wil_down(struct wil6210_priv *wil) | |||
698 | 753 | ||
699 | wil_dbg_misc(wil, "%s()\n", __func__); | 754 | wil_dbg_misc(wil, "%s()\n", __func__); |
700 | 755 | ||
756 | wil_set_recovery_state(wil, fw_recovery_idle); | ||
701 | mutex_lock(&wil->mutex); | 757 | mutex_lock(&wil->mutex); |
702 | rc = __wil_down(wil); | 758 | rc = __wil_down(wil); |
703 | mutex_unlock(&wil->mutex); | 759 | mutex_unlock(&wil->mutex); |
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index 1c0c77d9a14f..239965106c05 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c | |||
@@ -52,6 +52,17 @@ static int wil_change_mtu(struct net_device *ndev, int new_mtu) | |||
52 | return 0; | 52 | return 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | static int wil_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) | ||
56 | { | ||
57 | struct wil6210_priv *wil = ndev_to_wil(ndev); | ||
58 | |||
59 | int ret = wil_ioctl(wil, ifr->ifr_data, cmd); | ||
60 | |||
61 | wil_dbg_misc(wil, "ioctl(0x%04x) -> %d\n", cmd, ret); | ||
62 | |||
63 | return ret; | ||
64 | } | ||
65 | |||
55 | static const struct net_device_ops wil_netdev_ops = { | 66 | static const struct net_device_ops wil_netdev_ops = { |
56 | .ndo_open = wil_open, | 67 | .ndo_open = wil_open, |
57 | .ndo_stop = wil_stop, | 68 | .ndo_stop = wil_stop, |
@@ -59,6 +70,7 @@ static const struct net_device_ops wil_netdev_ops = { | |||
59 | .ndo_set_mac_address = eth_mac_addr, | 70 | .ndo_set_mac_address = eth_mac_addr, |
60 | .ndo_validate_addr = eth_validate_addr, | 71 | .ndo_validate_addr = eth_validate_addr, |
61 | .ndo_change_mtu = wil_change_mtu, | 72 | .ndo_change_mtu = wil_change_mtu, |
73 | .ndo_do_ioctl = wil_do_ioctl, | ||
62 | }; | 74 | }; |
63 | 75 | ||
64 | static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget) | 76 | static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget) |
@@ -149,6 +161,7 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr) | |||
149 | } | 161 | } |
150 | 162 | ||
151 | ndev->netdev_ops = &wil_netdev_ops; | 163 | ndev->netdev_ops = &wil_netdev_ops; |
164 | wil_set_ethtoolops(ndev); | ||
152 | ndev->ieee80211_ptr = wdev; | 165 | ndev->ieee80211_ptr = wdev; |
153 | ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM | | 166 | ndev->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM | |
154 | NETIF_F_SG | NETIF_F_GRO; | 167 | NETIF_F_SG | NETIF_F_GRO; |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 41aa79327584..ce6488e42091 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/timex.h> | 23 | #include <linux/timex.h> |
24 | #include "wil_platform.h" | 24 | #include "wil_platform.h" |
25 | 25 | ||
26 | extern bool no_fw_recovery; | ||
26 | 27 | ||
27 | #define WIL_NAME "wil6210" | 28 | #define WIL_NAME "wil6210" |
28 | #define WIL_FW_NAME "wil6210.fw" | 29 | #define WIL_FW_NAME "wil6210.fw" |
@@ -52,7 +53,9 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1) | |||
52 | #define WIL6210_MAX_TX_RINGS (24) /* HW limit */ | 53 | #define WIL6210_MAX_TX_RINGS (24) /* HW limit */ |
53 | #define WIL6210_MAX_CID (8) /* HW limit */ | 54 | #define WIL6210_MAX_CID (8) /* HW limit */ |
54 | #define WIL6210_NAPI_BUDGET (16) /* arbitrary */ | 55 | #define WIL6210_NAPI_BUDGET (16) /* arbitrary */ |
55 | #define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */ | 56 | /* Max supported by wil6210 value for interrupt threshold is 5sec. */ |
57 | #define WIL6210_ITR_TRSH_MAX (5000000) | ||
58 | #define WIL6210_ITR_TRSH_DEFAULT (300) /* usec */ | ||
56 | #define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */ | 59 | #define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */ |
57 | #define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000) | 60 | #define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000) |
58 | #define WIL6210_SCAN_TO msecs_to_jiffies(10000) | 61 | #define WIL6210_SCAN_TO msecs_to_jiffies(10000) |
@@ -377,6 +380,12 @@ struct wil_sta_info { | |||
377 | unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)]; | 380 | unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)]; |
378 | }; | 381 | }; |
379 | 382 | ||
383 | enum { | ||
384 | fw_recovery_idle = 0, | ||
385 | fw_recovery_pending = 1, | ||
386 | fw_recovery_running = 2, | ||
387 | }; | ||
388 | |||
380 | struct wil6210_priv { | 389 | struct wil6210_priv { |
381 | struct pci_dev *pdev; | 390 | struct pci_dev *pdev; |
382 | int n_msi; | 391 | int n_msi; |
@@ -387,12 +396,15 @@ struct wil6210_priv { | |||
387 | u32 hw_version; | 396 | u32 hw_version; |
388 | struct wil_board *board; | 397 | struct wil_board *board; |
389 | u8 n_mids; /* number of additional MIDs as reported by FW */ | 398 | u8 n_mids; /* number of additional MIDs as reported by FW */ |
390 | int recovery_count; /* num of FW recovery attempts in a short time */ | 399 | u32 recovery_count; /* num of FW recovery attempts in a short time */ |
400 | u32 recovery_state; /* FW recovery state machine */ | ||
391 | unsigned long last_fw_recovery; /* jiffies of last fw recovery */ | 401 | unsigned long last_fw_recovery; /* jiffies of last fw recovery */ |
402 | wait_queue_head_t wq; /* for all wait_event() use */ | ||
392 | /* profile */ | 403 | /* profile */ |
393 | u32 monitor_flags; | 404 | u32 monitor_flags; |
394 | u32 secure_pcp; /* create secure PCP? */ | 405 | u32 secure_pcp; /* create secure PCP? */ |
395 | int sinfo_gen; | 406 | int sinfo_gen; |
407 | u32 itr_trsh; | ||
396 | /* cached ISR registers */ | 408 | /* cached ISR registers */ |
397 | u32 isr_misc; | 409 | u32 isr_misc; |
398 | /* mailbox related */ | 410 | /* mailbox related */ |
@@ -502,7 +514,9 @@ void wil_if_remove(struct wil6210_priv *wil); | |||
502 | int wil_priv_init(struct wil6210_priv *wil); | 514 | int wil_priv_init(struct wil6210_priv *wil); |
503 | void wil_priv_deinit(struct wil6210_priv *wil); | 515 | void wil_priv_deinit(struct wil6210_priv *wil); |
504 | int wil_reset(struct wil6210_priv *wil); | 516 | int wil_reset(struct wil6210_priv *wil); |
517 | void wil_set_itr_trsh(struct wil6210_priv *wil); | ||
505 | void wil_fw_error_recovery(struct wil6210_priv *wil); | 518 | void wil_fw_error_recovery(struct wil6210_priv *wil); |
519 | void wil_set_recovery_state(struct wil6210_priv *wil, int state); | ||
506 | void wil_link_on(struct wil6210_priv *wil); | 520 | void wil_link_on(struct wil6210_priv *wil); |
507 | void wil_link_off(struct wil6210_priv *wil); | 521 | void wil_link_off(struct wil6210_priv *wil); |
508 | int wil_up(struct wil6210_priv *wil); | 522 | int wil_up(struct wil6210_priv *wil); |
@@ -511,6 +525,7 @@ int wil_down(struct wil6210_priv *wil); | |||
511 | int __wil_down(struct wil6210_priv *wil); | 525 | int __wil_down(struct wil6210_priv *wil); |
512 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); | 526 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); |
513 | int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); | 527 | int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); |
528 | void wil_set_ethtoolops(struct net_device *ndev); | ||
514 | 529 | ||
515 | void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); | 530 | void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr); |
516 | void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); | 531 | void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); |
@@ -580,5 +595,7 @@ void wil6210_unmask_irq_rx(struct wil6210_priv *wil); | |||
580 | 595 | ||
581 | int wil_iftype_nl2wmi(enum nl80211_iftype type); | 596 | int wil_iftype_nl2wmi(enum nl80211_iftype type); |
582 | 597 | ||
598 | int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd); | ||
583 | int wil_request_firmware(struct wil6210_priv *wil, const char *name); | 599 | int wil_request_firmware(struct wil6210_priv *wil, const char *name); |
600 | |||
584 | #endif /* __WIL6210_H__ */ | 601 | #endif /* __WIL6210_H__ */ |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index bd781c7adf2a..4311df982c60 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -299,6 +299,7 @@ static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d, | |||
299 | { | 299 | { |
300 | wil_dbg_wmi(wil, "WMI: got FW ready event\n"); | 300 | wil_dbg_wmi(wil, "WMI: got FW ready event\n"); |
301 | 301 | ||
302 | wil_set_recovery_state(wil, fw_recovery_idle); | ||
302 | set_bit(wil_status_fwready, &wil->status); | 303 | set_bit(wil_status_fwready, &wil->status); |
303 | /* let the reset sequence continue */ | 304 | /* let the reset sequence continue */ |
304 | complete(&wil->wmi_ready); | 305 | complete(&wil->wmi_ready); |