aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorKalle Valo <kvalo@codeaurora.org>2016-09-14 12:34:50 -0400
committerKalle Valo <kvalo@codeaurora.org>2016-09-14 12:34:50 -0400
commitaf1afc2957d63f84a37b168e56be7a7ef6b43650 (patch)
tree943688e1340b28032ec3b8c8c60e2b4be54759a5 /drivers/net/wireless/ath
parent75696fe704774039e0e2ca65be24d79739ed206d (diff)
parent95b5bf7ccca0d7ba575a7e26a7ed4146b9190071 (diff)
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.9. Major changes: ath10k * add nl80211 testmode support for 10.4 firmware * hide kernel addresses from logs using %pK format specifier * implement NAPI support * enable peer stats by default ath9k * use ieee80211_tx_status_noskb where possible wil6210 * extract firmware capabilities from the firmware file ath6kl * enable firmware crash dumps on the AR6004 ath-current is also merged to fix a conflict in ath10k.
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath10k/ahb.c12
-rw-r--r--drivers/net/wireless/ath/ath10k/bmi.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c125
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h79
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c11
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c6
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c204
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c13
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h76
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c70
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c78
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/swap.c26
-rw-r--r--drivers/net/wireless/ath/ath10k/swap.h11
-rw-r--r--drivers/net/wireless/ath/ath10k/testmode.c27
-rw-r--r--drivers/net/wireless/ath/ath10k/thermal.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h33
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c59
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c186
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h24
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c104
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c151
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c53
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.h14
-rw-r--r--drivers/net/wireless/ath/wil6210/fw_inc.c92
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c15
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c63
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c34
-rw-r--r--drivers/net/wireless/ath/wil6210/p2p.c46
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c9
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c9
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h11
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c12
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h932
46 files changed, 2123 insertions, 548 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c
index acec16b9cf49..b99ad5df383d 100644
--- a/drivers/net/wireless/ath/ath10k/ahb.c
+++ b/drivers/net/wireless/ath/ath10k/ahb.c
@@ -462,13 +462,13 @@ static void ath10k_ahb_halt_chip(struct ath10k *ar)
462static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg) 462static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg)
463{ 463{
464 struct ath10k *ar = arg; 464 struct ath10k *ar = arg;
465 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
466 465
467 if (!ath10k_pci_irq_pending(ar)) 466 if (!ath10k_pci_irq_pending(ar))
468 return IRQ_NONE; 467 return IRQ_NONE;
469 468
470 ath10k_pci_disable_and_clear_legacy_irq(ar); 469 ath10k_pci_disable_and_clear_legacy_irq(ar);
471 tasklet_schedule(&ar_pci->intr_tq); 470 ath10k_pci_irq_msi_fw_mask(ar);
471 napi_schedule(&ar->napi);
472 472
473 return IRQ_HANDLED; 473 return IRQ_HANDLED;
474} 474}
@@ -577,7 +577,7 @@ static int ath10k_ahb_resource_init(struct ath10k *ar)
577 577
578 ath10k_dbg(ar, ATH10K_DBG_BOOT, "irq: %d\n", ar_ahb->irq); 578 ath10k_dbg(ar, ATH10K_DBG_BOOT, "irq: %d\n", ar_ahb->irq);
579 579
580 ath10k_dbg(ar, ATH10K_DBG_BOOT, "mem: 0x%p mem_len: %lu gcc mem: 0x%p tcsr_mem: 0x%p\n", 580 ath10k_dbg(ar, ATH10K_DBG_BOOT, "mem: 0x%pK mem_len: %lu gcc mem: 0x%pK tcsr_mem: 0x%pK\n",
581 ar_ahb->mem, ar_ahb->mem_len, 581 ar_ahb->mem, ar_ahb->mem_len,
582 ar_ahb->gcc_mem, ar_ahb->tcsr_mem); 582 ar_ahb->gcc_mem, ar_ahb->tcsr_mem);
583 return 0; 583 return 0;
@@ -717,6 +717,9 @@ static void ath10k_ahb_hif_stop(struct ath10k *ar)
717 synchronize_irq(ar_ahb->irq); 717 synchronize_irq(ar_ahb->irq);
718 718
719 ath10k_pci_flush(ar); 719 ath10k_pci_flush(ar);
720
721 napi_synchronize(&ar->napi);
722 napi_disable(&ar->napi);
720} 723}
721 724
722static int ath10k_ahb_hif_power_up(struct ath10k *ar) 725static int ath10k_ahb_hif_power_up(struct ath10k *ar)
@@ -748,6 +751,7 @@ static int ath10k_ahb_hif_power_up(struct ath10k *ar)
748 ath10k_err(ar, "could not wake up target CPU: %d\n", ret); 751 ath10k_err(ar, "could not wake up target CPU: %d\n", ret);
749 goto err_ce_deinit; 752 goto err_ce_deinit;
750 } 753 }
754 napi_enable(&ar->napi);
751 755
752 return 0; 756 return 0;
753 757
@@ -831,7 +835,7 @@ static int ath10k_ahb_probe(struct platform_device *pdev)
831 goto err_resource_deinit; 835 goto err_resource_deinit;
832 } 836 }
833 837
834 ath10k_pci_init_irq_tasklets(ar); 838 ath10k_pci_init_napi(ar);
835 839
836 ret = ath10k_ahb_request_irq_legacy(ar); 840 ret = ath10k_ahb_request_irq_legacy(ar);
837 if (ret) 841 if (ret)
diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c
index 3d29b0875b3e..2872d347ea78 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.c
+++ b/drivers/net/wireless/ath/ath10k/bmi.c
@@ -221,7 +221,7 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
221 u32 txlen; 221 u32 txlen;
222 int ret; 222 int ret;
223 223
224 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", 224 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%pK length %d\n",
225 buffer, length); 225 buffer, length);
226 226
227 if (ar->bmi.done_sent) { 227 if (ar->bmi.done_sent) {
@@ -287,7 +287,7 @@ int ath10k_bmi_fast_download(struct ath10k *ar,
287 int ret; 287 int ret;
288 288
289 ath10k_dbg(ar, ATH10K_DBG_BMI, 289 ath10k_dbg(ar, ATH10K_DBG_BMI,
290 "bmi fast download address 0x%x buffer 0x%p length %d\n", 290 "bmi fast download address 0x%x buffer 0x%pK length %d\n",
291 address, buffer, length); 291 address, buffer, length);
292 292
293 ret = ath10k_bmi_lz_stream_start(ar, address); 293 ret = ath10k_bmi_lz_stream_start(ar, address);
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 9fb8d7472d18..65d8d714e917 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -840,7 +840,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
840 ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); 840 ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
841 841
842 ath10k_dbg(ar, ATH10K_DBG_BOOT, 842 ath10k_dbg(ar, ATH10K_DBG_BOOT,
843 "boot init ce src ring id %d entries %d base_addr %p\n", 843 "boot init ce src ring id %d entries %d base_addr %pK\n",
844 ce_id, nentries, src_ring->base_addr_owner_space); 844 ce_id, nentries, src_ring->base_addr_owner_space);
845 845
846 return 0; 846 return 0;
@@ -874,7 +874,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
874 ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); 874 ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
875 875
876 ath10k_dbg(ar, ATH10K_DBG_BOOT, 876 ath10k_dbg(ar, ATH10K_DBG_BOOT,
877 "boot ce dest ring id %d entries %d base_addr %p\n", 877 "boot ce dest ring id %d entries %d base_addr %pK\n",
878 ce_id, nentries, dest_ring->base_addr_owner_space); 878 ce_id, nentries, dest_ring->base_addr_owner_space);
879 879
880 return 0; 880 return 0;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index e88982921aa3..3a8984ba9f74 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -60,7 +60,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
60 .otp_exe_param = 0, 60 .otp_exe_param = 0,
61 .channel_counters_freq_hz = 88000, 61 .channel_counters_freq_hz = 88000,
62 .max_probe_resp_desc_thres = 0, 62 .max_probe_resp_desc_thres = 0,
63 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
64 .cal_data_len = 2116, 63 .cal_data_len = 2116,
65 .fw = { 64 .fw = {
66 .dir = QCA988X_HW_2_0_FW_DIR, 65 .dir = QCA988X_HW_2_0_FW_DIR,
@@ -68,6 +67,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
68 .board_size = QCA988X_BOARD_DATA_SZ, 67 .board_size = QCA988X_BOARD_DATA_SZ,
69 .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ, 68 .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
70 }, 69 },
70 .hw_ops = &qca988x_ops,
71 }, 71 },
72 { 72 {
73 .id = QCA9887_HW_1_0_VERSION, 73 .id = QCA9887_HW_1_0_VERSION,
@@ -79,7 +79,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
79 .otp_exe_param = 0, 79 .otp_exe_param = 0,
80 .channel_counters_freq_hz = 88000, 80 .channel_counters_freq_hz = 88000,
81 .max_probe_resp_desc_thres = 0, 81 .max_probe_resp_desc_thres = 0,
82 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
83 .cal_data_len = 2116, 82 .cal_data_len = 2116,
84 .fw = { 83 .fw = {
85 .dir = QCA9887_HW_1_0_FW_DIR, 84 .dir = QCA9887_HW_1_0_FW_DIR,
@@ -87,6 +86,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
87 .board_size = QCA9887_BOARD_DATA_SZ, 86 .board_size = QCA9887_BOARD_DATA_SZ,
88 .board_ext_size = QCA9887_BOARD_EXT_DATA_SZ, 87 .board_ext_size = QCA9887_BOARD_EXT_DATA_SZ,
89 }, 88 },
89 .hw_ops = &qca988x_ops,
90 }, 90 },
91 { 91 {
92 .id = QCA6174_HW_2_1_VERSION, 92 .id = QCA6174_HW_2_1_VERSION,
@@ -104,6 +104,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
104 .board_size = QCA6174_BOARD_DATA_SZ, 104 .board_size = QCA6174_BOARD_DATA_SZ,
105 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, 105 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
106 }, 106 },
107 .hw_ops = &qca988x_ops,
107 }, 108 },
108 { 109 {
109 .id = QCA6174_HW_2_1_VERSION, 110 .id = QCA6174_HW_2_1_VERSION,
@@ -114,7 +115,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
114 .otp_exe_param = 0, 115 .otp_exe_param = 0,
115 .channel_counters_freq_hz = 88000, 116 .channel_counters_freq_hz = 88000,
116 .max_probe_resp_desc_thres = 0, 117 .max_probe_resp_desc_thres = 0,
117 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
118 .cal_data_len = 8124, 118 .cal_data_len = 8124,
119 .fw = { 119 .fw = {
120 .dir = QCA6174_HW_2_1_FW_DIR, 120 .dir = QCA6174_HW_2_1_FW_DIR,
@@ -122,6 +122,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
122 .board_size = QCA6174_BOARD_DATA_SZ, 122 .board_size = QCA6174_BOARD_DATA_SZ,
123 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, 123 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
124 }, 124 },
125 .hw_ops = &qca988x_ops,
125 }, 126 },
126 { 127 {
127 .id = QCA6174_HW_3_0_VERSION, 128 .id = QCA6174_HW_3_0_VERSION,
@@ -132,7 +133,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
132 .otp_exe_param = 0, 133 .otp_exe_param = 0,
133 .channel_counters_freq_hz = 88000, 134 .channel_counters_freq_hz = 88000,
134 .max_probe_resp_desc_thres = 0, 135 .max_probe_resp_desc_thres = 0,
135 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
136 .cal_data_len = 8124, 136 .cal_data_len = 8124,
137 .fw = { 137 .fw = {
138 .dir = QCA6174_HW_3_0_FW_DIR, 138 .dir = QCA6174_HW_3_0_FW_DIR,
@@ -140,6 +140,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
140 .board_size = QCA6174_BOARD_DATA_SZ, 140 .board_size = QCA6174_BOARD_DATA_SZ,
141 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, 141 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
142 }, 142 },
143 .hw_ops = &qca988x_ops,
143 }, 144 },
144 { 145 {
145 .id = QCA6174_HW_3_2_VERSION, 146 .id = QCA6174_HW_3_2_VERSION,
@@ -150,7 +151,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
150 .otp_exe_param = 0, 151 .otp_exe_param = 0,
151 .channel_counters_freq_hz = 88000, 152 .channel_counters_freq_hz = 88000,
152 .max_probe_resp_desc_thres = 0, 153 .max_probe_resp_desc_thres = 0,
153 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
154 .cal_data_len = 8124, 154 .cal_data_len = 8124,
155 .fw = { 155 .fw = {
156 /* uses same binaries as hw3.0 */ 156 /* uses same binaries as hw3.0 */
@@ -159,6 +159,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
159 .board_size = QCA6174_BOARD_DATA_SZ, 159 .board_size = QCA6174_BOARD_DATA_SZ,
160 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, 160 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
161 }, 161 },
162 .hw_ops = &qca988x_ops,
162 }, 163 },
163 { 164 {
164 .id = QCA99X0_HW_2_0_DEV_VERSION, 165 .id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -171,7 +172,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
171 .cck_rate_map_rev2 = true, 172 .cck_rate_map_rev2 = true,
172 .channel_counters_freq_hz = 150000, 173 .channel_counters_freq_hz = 150000,
173 .max_probe_resp_desc_thres = 24, 174 .max_probe_resp_desc_thres = 24,
174 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
175 .tx_chain_mask = 0xf, 175 .tx_chain_mask = 0xf,
176 .rx_chain_mask = 0xf, 176 .rx_chain_mask = 0xf,
177 .max_spatial_stream = 4, 177 .max_spatial_stream = 4,
@@ -182,6 +182,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
182 .board_size = QCA99X0_BOARD_DATA_SZ, 182 .board_size = QCA99X0_BOARD_DATA_SZ,
183 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, 183 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
184 }, 184 },
185 .sw_decrypt_mcast_mgmt = true,
186 .hw_ops = &qca99x0_ops,
185 }, 187 },
186 { 188 {
187 .id = QCA9984_HW_1_0_DEV_VERSION, 189 .id = QCA9984_HW_1_0_DEV_VERSION,
@@ -194,7 +196,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
194 .cck_rate_map_rev2 = true, 196 .cck_rate_map_rev2 = true,
195 .channel_counters_freq_hz = 150000, 197 .channel_counters_freq_hz = 150000,
196 .max_probe_resp_desc_thres = 24, 198 .max_probe_resp_desc_thres = 24,
197 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
198 .tx_chain_mask = 0xf, 199 .tx_chain_mask = 0xf,
199 .rx_chain_mask = 0xf, 200 .rx_chain_mask = 0xf,
200 .max_spatial_stream = 4, 201 .max_spatial_stream = 4,
@@ -205,6 +206,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
205 .board_size = QCA99X0_BOARD_DATA_SZ, 206 .board_size = QCA99X0_BOARD_DATA_SZ,
206 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, 207 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
207 }, 208 },
209 .sw_decrypt_mcast_mgmt = true,
210 .hw_ops = &qca99x0_ops,
208 }, 211 },
209 { 212 {
210 .id = QCA9888_HW_2_0_DEV_VERSION, 213 .id = QCA9888_HW_2_0_DEV_VERSION,
@@ -216,7 +219,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
216 .continuous_frag_desc = true, 219 .continuous_frag_desc = true,
217 .channel_counters_freq_hz = 150000, 220 .channel_counters_freq_hz = 150000,
218 .max_probe_resp_desc_thres = 24, 221 .max_probe_resp_desc_thres = 24,
219 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
220 .tx_chain_mask = 3, 222 .tx_chain_mask = 3,
221 .rx_chain_mask = 3, 223 .rx_chain_mask = 3,
222 .max_spatial_stream = 2, 224 .max_spatial_stream = 2,
@@ -227,6 +229,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
227 .board_size = QCA99X0_BOARD_DATA_SZ, 229 .board_size = QCA99X0_BOARD_DATA_SZ,
228 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, 230 .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
229 }, 231 },
232 .sw_decrypt_mcast_mgmt = true,
233 .hw_ops = &qca99x0_ops,
230 }, 234 },
231 { 235 {
232 .id = QCA9377_HW_1_0_DEV_VERSION, 236 .id = QCA9377_HW_1_0_DEV_VERSION,
@@ -244,6 +248,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
244 .board_size = QCA9377_BOARD_DATA_SZ, 248 .board_size = QCA9377_BOARD_DATA_SZ,
245 .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ, 249 .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
246 }, 250 },
251 .hw_ops = &qca988x_ops,
247 }, 252 },
248 { 253 {
249 .id = QCA9377_HW_1_1_DEV_VERSION, 254 .id = QCA9377_HW_1_1_DEV_VERSION,
@@ -261,6 +266,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
261 .board_size = QCA9377_BOARD_DATA_SZ, 266 .board_size = QCA9377_BOARD_DATA_SZ,
262 .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ, 267 .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
263 }, 268 },
269 .hw_ops = &qca988x_ops,
264 }, 270 },
265 { 271 {
266 .id = QCA4019_HW_1_0_DEV_VERSION, 272 .id = QCA4019_HW_1_0_DEV_VERSION,
@@ -274,7 +280,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
274 .cck_rate_map_rev2 = true, 280 .cck_rate_map_rev2 = true,
275 .channel_counters_freq_hz = 125000, 281 .channel_counters_freq_hz = 125000,
276 .max_probe_resp_desc_thres = 24, 282 .max_probe_resp_desc_thres = 24,
277 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
278 .tx_chain_mask = 0x3, 283 .tx_chain_mask = 0x3,
279 .rx_chain_mask = 0x3, 284 .rx_chain_mask = 0x3,
280 .max_spatial_stream = 2, 285 .max_spatial_stream = 2,
@@ -285,6 +290,8 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
285 .board_size = QCA4019_BOARD_DATA_SZ, 290 .board_size = QCA4019_BOARD_DATA_SZ,
286 .board_ext_size = QCA4019_BOARD_EXT_DATA_SZ, 291 .board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,
287 }, 292 },
293 .sw_decrypt_mcast_mgmt = true,
294 .hw_ops = &qca99x0_ops,
288 }, 295 },
289}; 296};
290 297
@@ -304,6 +311,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
304 [ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp", 311 [ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
305 [ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl", 312 [ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
306 [ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param", 313 [ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",
314 [ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war",
307}; 315};
308 316
309static unsigned int ath10k_core_get_fw_feature_str(char *buf, 317static unsigned int ath10k_core_get_fw_feature_str(char *buf,
@@ -699,7 +707,7 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
699 707
700 if (!ar->running_fw->fw_file.otp_data || 708 if (!ar->running_fw->fw_file.otp_data ||
701 !ar->running_fw->fw_file.otp_len) { 709 !ar->running_fw->fw_file.otp_len) {
702 ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", 710 ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %pK otp_len %zd)!\n",
703 ar->running_fw->fw_file.otp_data, 711 ar->running_fw->fw_file.otp_data,
704 ar->running_fw->fw_file.otp_len); 712 ar->running_fw->fw_file.otp_len);
705 return 0; 713 return 0;
@@ -745,7 +753,7 @@ static int ath10k_download_fw(struct ath10k *ar)
745 data = ar->running_fw->fw_file.firmware_data; 753 data = ar->running_fw->fw_file.firmware_data;
746 data_len = ar->running_fw->fw_file.firmware_len; 754 data_len = ar->running_fw->fw_file.firmware_len;
747 755
748 ret = ath10k_swap_code_seg_configure(ar); 756 ret = ath10k_swap_code_seg_configure(ar, &ar->running_fw->fw_file);
749 if (ret) { 757 if (ret) {
750 ath10k_err(ar, "failed to configure fw code swap: %d\n", 758 ath10k_err(ar, "failed to configure fw code swap: %d\n",
751 ret); 759 ret);
@@ -753,7 +761,7 @@ static int ath10k_download_fw(struct ath10k *ar)
753 } 761 }
754 762
755 ath10k_dbg(ar, ATH10K_DBG_BOOT, 763 ath10k_dbg(ar, ATH10K_DBG_BOOT,
756 "boot uploading firmware image %p len %d\n", 764 "boot uploading firmware image %pK len %d\n",
757 data, data_len); 765 data, data_len);
758 766
759 ret = ath10k_bmi_fast_download(ar, address, data, data_len); 767 ret = ath10k_bmi_fast_download(ar, address, data, data_len);
@@ -787,7 +795,7 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar)
787 if (!IS_ERR(ar->pre_cal_file)) 795 if (!IS_ERR(ar->pre_cal_file))
788 release_firmware(ar->pre_cal_file); 796 release_firmware(ar->pre_cal_file);
789 797
790 ath10k_swap_code_seg_release(ar); 798 ath10k_swap_code_seg_release(ar, &ar->normal_mode_fw.fw_file);
791 799
792 ar->normal_mode_fw.fw_file.otp_data = NULL; 800 ar->normal_mode_fw.fw_file.otp_data = NULL;
793 ar->normal_mode_fw.fw_file.otp_len = 0; 801 ar->normal_mode_fw.fw_file.otp_len = 0;
@@ -1497,14 +1505,14 @@ static void ath10k_core_restart(struct work_struct *work)
1497 1505
1498 ieee80211_stop_queues(ar->hw); 1506 ieee80211_stop_queues(ar->hw);
1499 ath10k_drain_tx(ar); 1507 ath10k_drain_tx(ar);
1500 complete_all(&ar->scan.started); 1508 complete(&ar->scan.started);
1501 complete_all(&ar->scan.completed); 1509 complete(&ar->scan.completed);
1502 complete_all(&ar->scan.on_channel); 1510 complete(&ar->scan.on_channel);
1503 complete_all(&ar->offchan_tx_completed); 1511 complete(&ar->offchan_tx_completed);
1504 complete_all(&ar->install_key_done); 1512 complete(&ar->install_key_done);
1505 complete_all(&ar->vdev_setup_done); 1513 complete(&ar->vdev_setup_done);
1506 complete_all(&ar->thermal.wmi_sync); 1514 complete(&ar->thermal.wmi_sync);
1507 complete_all(&ar->bss_survey_done); 1515 complete(&ar->bss_survey_done);
1508 wake_up(&ar->htt.empty_tx_wq); 1516 wake_up(&ar->htt.empty_tx_wq);
1509 wake_up(&ar->wmi.tx_credits_wq); 1517 wake_up(&ar->wmi.tx_credits_wq);
1510 wake_up(&ar->peer_mapping_wq); 1518 wake_up(&ar->peer_mapping_wq);
@@ -1705,6 +1713,55 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
1705 return 0; 1713 return 0;
1706} 1714}
1707 1715
1716static int ath10k_core_reset_rx_filter(struct ath10k *ar)
1717{
1718 int ret;
1719 int vdev_id;
1720 int vdev_type;
1721 int vdev_subtype;
1722 const u8 *vdev_addr;
1723
1724 vdev_id = 0;
1725 vdev_type = WMI_VDEV_TYPE_STA;
1726 vdev_subtype = ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
1727 vdev_addr = ar->mac_addr;
1728
1729 ret = ath10k_wmi_vdev_create(ar, vdev_id, vdev_type, vdev_subtype,
1730 vdev_addr);
1731 if (ret) {
1732 ath10k_err(ar, "failed to create dummy vdev: %d\n", ret);
1733 return ret;
1734 }
1735
1736 ret = ath10k_wmi_vdev_delete(ar, vdev_id);
1737 if (ret) {
1738 ath10k_err(ar, "failed to delete dummy vdev: %d\n", ret);
1739 return ret;
1740 }
1741
1742 /* WMI and HTT may use separate HIF pipes and are not guaranteed to be
1743 * serialized properly implicitly.
1744 *
1745 * Moreover (most) WMI commands have no explicit acknowledges. It is
1746 * possible to infer it implicitly by poking firmware with echo
1747 * command - getting a reply means all preceding comments have been
1748 * (mostly) processed.
1749 *
1750 * In case of vdev create/delete this is sufficient.
1751 *
1752 * Without this it's possible to end up with a race when HTT Rx ring is
1753 * started before vdev create/delete hack is complete allowing a short
1754 * window of opportunity to receive (and Tx ACK) a bunch of frames.
1755 */
1756 ret = ath10k_wmi_barrier(ar);
1757 if (ret) {
1758 ath10k_err(ar, "failed to ping firmware: %d\n", ret);
1759 return ret;
1760 }
1761
1762 return 0;
1763}
1764
1708int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, 1765int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
1709 const struct ath10k_fw_components *fw) 1766 const struct ath10k_fw_components *fw)
1710{ 1767{
@@ -1872,6 +1929,25 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
1872 goto err_hif_stop; 1929 goto err_hif_stop;
1873 } 1930 }
1874 1931
1932 /* Some firmware revisions do not properly set up hardware rx filter
1933 * registers.
1934 *
1935 * A known example from QCA9880 and 10.2.4 is that MAC_PCU_ADDR1_MASK
1936 * is filled with 0s instead of 1s allowing HW to respond with ACKs to
1937 * any frames that matches MAC_PCU_RX_FILTER which is also
1938 * misconfigured to accept anything.
1939 *
1940 * The ADDR1 is programmed using internal firmware structure field and
1941 * can't be (easily/sanely) reached from the driver explicitly. It is
1942 * possible to implicitly make it correct by creating a dummy vdev and
1943 * then deleting it.
1944 */
1945 status = ath10k_core_reset_rx_filter(ar);
1946 if (status) {
1947 ath10k_err(ar, "failed to reset rx filter: %d\n", status);
1948 goto err_hif_stop;
1949 }
1950
1875 /* If firmware indicates Full Rx Reorder support it must be used in a 1951 /* If firmware indicates Full Rx Reorder support it must be used in a
1876 * slightly different manner. Let HTT code know. 1952 * slightly different manner. Let HTT code know.
1877 */ 1953 */
@@ -2031,7 +2107,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
2031 goto err_free_firmware_files; 2107 goto err_free_firmware_files;
2032 } 2108 }
2033 2109
2034 ret = ath10k_swap_code_seg_init(ar); 2110 ret = ath10k_swap_code_seg_init(ar, &ar->normal_mode_fw.fw_file);
2035 if (ret) { 2111 if (ret) {
2036 ath10k_err(ar, "failed to initialize code swap segment: %d\n", 2112 ath10k_err(ar, "failed to initialize code swap segment: %d\n",
2037 ret); 2113 ret);
@@ -2072,6 +2148,9 @@ static void ath10k_core_register_work(struct work_struct *work)
2072 struct ath10k *ar = container_of(work, struct ath10k, register_work); 2148 struct ath10k *ar = container_of(work, struct ath10k, register_work);
2073 int status; 2149 int status;
2074 2150
2151 /* peer stats are enabled by default */
2152 set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2153
2075 status = ath10k_core_probe_fw(ar); 2154 status = ath10k_core_probe_fw(ar);
2076 if (status) { 2155 if (status) {
2077 ath10k_err(ar, "could not probe fw (%d)\n", status); 2156 ath10k_err(ar, "could not probe fw (%d)\n", status);
@@ -2249,6 +2328,8 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
2249 INIT_WORK(&ar->register_work, ath10k_core_register_work); 2328 INIT_WORK(&ar->register_work, ath10k_core_register_work);
2250 INIT_WORK(&ar->restart_work, ath10k_core_restart); 2329 INIT_WORK(&ar->restart_work, ath10k_core_restart);
2251 2330
2331 init_dummy_netdev(&ar->napi_dev);
2332
2252 ret = ath10k_debug_create(ar); 2333 ret = ath10k_debug_create(ar);
2253 if (ret) 2334 if (ret)
2254 goto err_free_aux_wq; 2335 goto err_free_aux_wq;
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 30ae5bf81611..6ec9495bcc04 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -65,6 +65,10 @@
65#define ATH10K_KEEPALIVE_MAX_IDLE 3895 65#define ATH10K_KEEPALIVE_MAX_IDLE 3895
66#define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900 66#define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900
67 67
68/* NAPI poll budget */
69#define ATH10K_NAPI_BUDGET 64
70#define ATH10K_NAPI_QUOTA_LIMIT 60
71
68struct ath10k; 72struct ath10k;
69 73
70enum ath10k_bus { 74enum ath10k_bus {
@@ -142,6 +146,7 @@ struct ath10k_wmi {
142 enum ath10k_htc_ep_id eid; 146 enum ath10k_htc_ep_id eid;
143 struct completion service_ready; 147 struct completion service_ready;
144 struct completion unified_ready; 148 struct completion unified_ready;
149 struct completion barrier;
145 wait_queue_head_t tx_credits_wq; 150 wait_queue_head_t tx_credits_wq;
146 DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX); 151 DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX);
147 struct wmi_cmd_map *cmd; 152 struct wmi_cmd_map *cmd;
@@ -440,7 +445,7 @@ struct ath10k_debug {
440 struct completion tpc_complete; 445 struct completion tpc_complete;
441 446
442 /* protected by conf_mutex */ 447 /* protected by conf_mutex */
443 u32 fw_dbglog_mask; 448 u64 fw_dbglog_mask;
444 u32 fw_dbglog_level; 449 u32 fw_dbglog_level;
445 u32 pktlog_filter; 450 u32 pktlog_filter;
446 u32 reg_addr; 451 u32 reg_addr;
@@ -551,6 +556,13 @@ enum ath10k_fw_features {
551 */ 556 */
552 ATH10K_FW_FEATURE_BTCOEX_PARAM = 14, 557 ATH10K_FW_FEATURE_BTCOEX_PARAM = 14,
553 558
559 /* Older firmware with HTT delivers incorrect tx status for null func
560 * frames to driver, but this fixed in 10.2 and 10.4 firmware versions.
561 * Also this workaround results in reporting of incorrect null func
562 * status for 10.4. This flag is used to skip the workaround.
563 */
564 ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15,
565
554 /* keep last */ 566 /* keep last */
555 ATH10K_FW_FEATURE_COUNT, 567 ATH10K_FW_FEATURE_COUNT,
556}; 568};
@@ -663,6 +675,15 @@ struct ath10k_fw_file {
663 675
664 const void *codeswap_data; 676 const void *codeswap_data;
665 size_t codeswap_len; 677 size_t codeswap_len;
678
679 /* The original idea of struct ath10k_fw_file was that it only
680 * contains struct firmware and pointers to various parts (actual
681 * firmware binary, otp, metadata etc) of the file. This seg_info
682 * is actually created separate but as this is used similarly as
683 * the other firmware components it's more convenient to have it
684 * here.
685 */
686 struct ath10k_swap_code_seg_info *firmware_swap_code_seg_info;
666}; 687};
667 688
668struct ath10k_fw_components { 689struct ath10k_fw_components {
@@ -715,53 +736,7 @@ struct ath10k {
715 struct ath10k_htc htc; 736 struct ath10k_htc htc;
716 struct ath10k_htt htt; 737 struct ath10k_htt htt;
717 738
718 struct ath10k_hw_params { 739 struct ath10k_hw_params hw_params;
719 u32 id;
720 u16 dev_id;
721 const char *name;
722 u32 patch_load_addr;
723 int uart_pin;
724 u32 otp_exe_param;
725
726 /* Type of hw cycle counter wraparound logic, for more info
727 * refer enum ath10k_hw_cc_wraparound_type.
728 */
729 enum ath10k_hw_cc_wraparound_type cc_wraparound_type;
730
731 /* Some of chip expects fragment descriptor to be continuous
732 * memory for any TX operation. Set continuous_frag_desc flag
733 * for the hardware which have such requirement.
734 */
735 bool continuous_frag_desc;
736
737 /* CCK hardware rate table mapping for the newer chipsets
738 * like QCA99X0, QCA4019 got revised. The CCK h/w rate values
739 * are in a proper order with respect to the rate/preamble
740 */
741 bool cck_rate_map_rev2;
742
743 u32 channel_counters_freq_hz;
744
745 /* Mgmt tx descriptors threshold for limiting probe response
746 * frames.
747 */
748 u32 max_probe_resp_desc_thres;
749
750 /* The padding bytes's location is different on various chips */
751 enum ath10k_hw_4addr_pad hw_4addr_pad;
752
753 u32 tx_chain_mask;
754 u32 rx_chain_mask;
755 u32 max_spatial_stream;
756 u32 cal_data_len;
757
758 struct ath10k_hw_params_fw {
759 const char *dir;
760 const char *board;
761 size_t board_size;
762 size_t board_ext_size;
763 } fw;
764 } hw_params;
765 740
766 /* contains the firmware images used with ATH10K_FIRMWARE_MODE_NORMAL */ 741 /* contains the firmware images used with ATH10K_FIRMWARE_MODE_NORMAL */
767 struct ath10k_fw_components normal_mode_fw; 742 struct ath10k_fw_components normal_mode_fw;
@@ -775,10 +750,6 @@ struct ath10k {
775 const struct firmware *cal_file; 750 const struct firmware *cal_file;
776 751
777 struct { 752 struct {
778 struct ath10k_swap_code_seg_info *firmware_swap_code_seg_info;
779 } swap;
780
781 struct {
782 u32 vendor; 753 u32 vendor;
783 u32 device; 754 u32 device;
784 u32 subsystem_vendor; 755 u32 subsystem_vendor;
@@ -936,6 +907,10 @@ struct ath10k {
936 struct ath10k_thermal thermal; 907 struct ath10k_thermal thermal;
937 struct ath10k_wow wow; 908 struct ath10k_wow wow;
938 909
910 /* NAPI */
911 struct net_device napi_dev;
912 struct napi_struct napi;
913
939 /* must be last */ 914 /* must be last */
940 u8 drv_priv[0] __aligned(sizeof(void *)); 915 u8 drv_priv[0] __aligned(sizeof(void *));
941}; 916};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 8f0fd41dfd4b..832da6ed9f13 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -1228,9 +1228,9 @@ static ssize_t ath10k_read_fw_dbglog(struct file *file,
1228{ 1228{
1229 struct ath10k *ar = file->private_data; 1229 struct ath10k *ar = file->private_data;
1230 unsigned int len; 1230 unsigned int len;
1231 char buf[64]; 1231 char buf[96];
1232 1232
1233 len = scnprintf(buf, sizeof(buf), "0x%08x %u\n", 1233 len = scnprintf(buf, sizeof(buf), "0x%16llx %u\n",
1234 ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level); 1234 ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level);
1235 1235
1236 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1236 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -1242,15 +1242,16 @@ static ssize_t ath10k_write_fw_dbglog(struct file *file,
1242{ 1242{
1243 struct ath10k *ar = file->private_data; 1243 struct ath10k *ar = file->private_data;
1244 int ret; 1244 int ret;
1245 char buf[64]; 1245 char buf[96];
1246 unsigned int log_level, mask; 1246 unsigned int log_level;
1247 u64 mask;
1247 1248
1248 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); 1249 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
1249 1250
1250 /* make sure that buf is null terminated */ 1251 /* make sure that buf is null terminated */
1251 buf[sizeof(buf) - 1] = 0; 1252 buf[sizeof(buf) - 1] = 0;
1252 1253
1253 ret = sscanf(buf, "%x %u", &mask, &log_level); 1254 ret = sscanf(buf, "%llx %u", &mask, &log_level);
1254 1255
1255 if (!ret) 1256 if (!ret)
1256 return -EINVAL; 1257 return -EINVAL;
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 5b3c6bcf9598..175aae38c375 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -44,7 +44,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
44 skb_cb = ATH10K_SKB_CB(skb); 44 skb_cb = ATH10K_SKB_CB(skb);
45 memset(skb_cb, 0, sizeof(*skb_cb)); 45 memset(skb_cb, 0, sizeof(*skb_cb));
46 46
47 ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb); 47 ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %pK\n", __func__, skb);
48 return skb; 48 return skb;
49} 49}
50 50
@@ -62,7 +62,7 @@ static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
62{ 62{
63 struct ath10k *ar = ep->htc->ar; 63 struct ath10k *ar = ep->htc->ar;
64 64
65 ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, 65 ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
66 ep->eid, skb); 66 ep->eid, skb);
67 67
68 ath10k_htc_restore_tx_skb(ep->htc, skb); 68 ath10k_htc_restore_tx_skb(ep->htc, skb);
@@ -404,7 +404,7 @@ void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
404 goto out; 404 goto out;
405 } 405 }
406 406
407 ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n", 407 ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %pK\n",
408 eid, skb); 408 eid, skb);
409 ep->ep_ops.ep_rx_complete(ar, skb); 409 ep->ep_ops.ep_rx_complete(ar, skb);
410 410
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 430a83e142aa..98c14247021b 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1665,7 +1665,6 @@ struct ath10k_htt {
1665 1665
1666 /* This is used to group tx/rx completions separately and process them 1666 /* This is used to group tx/rx completions separately and process them
1667 * in batches to reduce cache stalls */ 1667 * in batches to reduce cache stalls */
1668 struct tasklet_struct txrx_compl_task;
1669 struct sk_buff_head rx_compl_q; 1668 struct sk_buff_head rx_compl_q;
1670 struct sk_buff_head rx_in_ord_compl_q; 1669 struct sk_buff_head rx_in_ord_compl_q;
1671 struct sk_buff_head tx_fetch_ind_q; 1670 struct sk_buff_head tx_fetch_ind_q;
@@ -1798,5 +1797,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt,
1798 struct sk_buff *msdu); 1797 struct sk_buff *msdu);
1799void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar, 1798void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
1800 struct sk_buff *skb); 1799 struct sk_buff *skb);
1800int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget);
1801 1801
1802#endif 1802#endif
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 78db5d679f19..a3785a9aa843 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -34,7 +34,6 @@
34#define HTT_RX_RING_REFILL_RESCHED_MS 5 34#define HTT_RX_RING_REFILL_RESCHED_MS 5
35 35
36static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); 36static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb);
37static void ath10k_htt_txrx_compl_task(unsigned long ptr);
38 37
39static struct sk_buff * 38static struct sk_buff *
40ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr) 39ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr)
@@ -226,7 +225,6 @@ int ath10k_htt_rx_ring_refill(struct ath10k *ar)
226void ath10k_htt_rx_free(struct ath10k_htt *htt) 225void ath10k_htt_rx_free(struct ath10k_htt *htt)
227{ 226{
228 del_timer_sync(&htt->rx_ring.refill_retry_timer); 227 del_timer_sync(&htt->rx_ring.refill_retry_timer);
229 tasklet_kill(&htt->txrx_compl_task);
230 228
231 skb_queue_purge(&htt->rx_compl_q); 229 skb_queue_purge(&htt->rx_compl_q);
232 skb_queue_purge(&htt->rx_in_ord_compl_q); 230 skb_queue_purge(&htt->rx_in_ord_compl_q);
@@ -520,9 +518,6 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
520 skb_queue_head_init(&htt->tx_fetch_ind_q); 518 skb_queue_head_init(&htt->tx_fetch_ind_q);
521 atomic_set(&htt->num_mpdus_ready, 0); 519 atomic_set(&htt->num_mpdus_ready, 0);
522 520
523 tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task,
524 (unsigned long)htt);
525
526 ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n", 521 ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n",
527 htt->rx_ring.size, htt->rx_ring.fill_level); 522 htt->rx_ring.size, htt->rx_ring.fill_level);
528 return 0; 523 return 0;
@@ -931,7 +926,7 @@ static void ath10k_process_rx(struct ath10k *ar,
931 *status = *rx_status; 926 *status = *rx_status;
932 927
933 ath10k_dbg(ar, ATH10K_DBG_DATA, 928 ath10k_dbg(ar, ATH10K_DBG_DATA,
934 "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n", 929 "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
935 skb, 930 skb,
936 skb->len, 931 skb->len,
937 ieee80211_get_SA(hdr), 932 ieee80211_get_SA(hdr),
@@ -958,7 +953,7 @@ static void ath10k_process_rx(struct ath10k *ar,
958 trace_ath10k_rx_hdr(ar, skb->data, skb->len); 953 trace_ath10k_rx_hdr(ar, skb->data, skb->len);
959 trace_ath10k_rx_payload(ar, skb->data, skb->len); 954 trace_ath10k_rx_payload(ar, skb->data, skb->len);
960 955
961 ieee80211_rx(ar->hw, skb); 956 ieee80211_rx_napi(ar->hw, NULL, skb, &ar->napi);
962} 957}
963 958
964static int ath10k_htt_rx_nwifi_hdrlen(struct ath10k *ar, 959static int ath10k_htt_rx_nwifi_hdrlen(struct ath10k *ar,
@@ -1056,9 +1051,11 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
1056 const u8 first_hdr[64]) 1051 const u8 first_hdr[64])
1057{ 1052{
1058 struct ieee80211_hdr *hdr; 1053 struct ieee80211_hdr *hdr;
1054 struct htt_rx_desc *rxd;
1059 size_t hdr_len; 1055 size_t hdr_len;
1060 u8 da[ETH_ALEN]; 1056 u8 da[ETH_ALEN];
1061 u8 sa[ETH_ALEN]; 1057 u8 sa[ETH_ALEN];
1058 int l3_pad_bytes;
1062 1059
1063 /* Delivered decapped frame: 1060 /* Delivered decapped frame:
1064 * [nwifi 802.11 header] <-- replaced with 802.11 hdr 1061 * [nwifi 802.11 header] <-- replaced with 802.11 hdr
@@ -1072,19 +1069,12 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
1072 */ 1069 */
1073 1070
1074 /* pull decapped header and copy SA & DA */ 1071 /* pull decapped header and copy SA & DA */
1075 if ((ar->hw_params.hw_4addr_pad == ATH10K_HW_4ADDR_PAD_BEFORE) && 1072 rxd = (void *)msdu->data - sizeof(*rxd);
1076 ieee80211_has_a4(((struct ieee80211_hdr *)first_hdr)->frame_control)) { 1073
1077 /* The QCA99X0 4 address mode pad 2 bytes at the 1074 l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1078 * beginning of MSDU 1075 skb_put(msdu, l3_pad_bytes);
1079 */ 1076
1080 hdr = (struct ieee80211_hdr *)(msdu->data + 2); 1077 hdr = (struct ieee80211_hdr *)(msdu->data + l3_pad_bytes);
1081 /* The skb length need be extended 2 as the 2 bytes at the tail
1082 * be excluded due to the padding
1083 */
1084 skb_put(msdu, 2);
1085 } else {
1086 hdr = (struct ieee80211_hdr *)(msdu->data);
1087 }
1088 1078
1089 hdr_len = ath10k_htt_rx_nwifi_hdrlen(ar, hdr); 1079 hdr_len = ath10k_htt_rx_nwifi_hdrlen(ar, hdr);
1090 ether_addr_copy(da, ieee80211_get_DA(hdr)); 1080 ether_addr_copy(da, ieee80211_get_DA(hdr));
@@ -1151,6 +1141,8 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
1151 void *rfc1042; 1141 void *rfc1042;
1152 u8 da[ETH_ALEN]; 1142 u8 da[ETH_ALEN];
1153 u8 sa[ETH_ALEN]; 1143 u8 sa[ETH_ALEN];
1144 int l3_pad_bytes;
1145 struct htt_rx_desc *rxd;
1154 1146
1155 /* Delivered decapped frame: 1147 /* Delivered decapped frame:
1156 * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc 1148 * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
@@ -1161,6 +1153,11 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
1161 if (WARN_ON_ONCE(!rfc1042)) 1153 if (WARN_ON_ONCE(!rfc1042))
1162 return; 1154 return;
1163 1155
1156 rxd = (void *)msdu->data - sizeof(*rxd);
1157 l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1158 skb_put(msdu, l3_pad_bytes);
1159 skb_pull(msdu, l3_pad_bytes);
1160
1164 /* pull decapped header and copy SA & DA */ 1161 /* pull decapped header and copy SA & DA */
1165 eth = (struct ethhdr *)msdu->data; 1162 eth = (struct ethhdr *)msdu->data;
1166 ether_addr_copy(da, eth->h_dest); 1163 ether_addr_copy(da, eth->h_dest);
@@ -1191,6 +1188,8 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
1191{ 1188{
1192 struct ieee80211_hdr *hdr; 1189 struct ieee80211_hdr *hdr;
1193 size_t hdr_len; 1190 size_t hdr_len;
1191 int l3_pad_bytes;
1192 struct htt_rx_desc *rxd;
1194 1193
1195 /* Delivered decapped frame: 1194 /* Delivered decapped frame:
1196 * [amsdu header] <-- replaced with 802.11 hdr 1195 * [amsdu header] <-- replaced with 802.11 hdr
@@ -1198,7 +1197,11 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
1198 * [payload] 1197 * [payload]
1199 */ 1198 */
1200 1199
1201 skb_pull(msdu, sizeof(struct amsdu_subframe_hdr)); 1200 rxd = (void *)msdu->data - sizeof(*rxd);
1201 l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1202
1203 skb_put(msdu, l3_pad_bytes);
1204 skb_pull(msdu, sizeof(struct amsdu_subframe_hdr) + l3_pad_bytes);
1202 1205
1203 hdr = (struct ieee80211_hdr *)first_hdr; 1206 hdr = (struct ieee80211_hdr *)first_hdr;
1204 hdr_len = ieee80211_hdrlen(hdr->frame_control); 1207 hdr_len = ieee80211_hdrlen(hdr->frame_control);
@@ -1525,9 +1528,9 @@ static void ath10k_htt_rx_h_filter(struct ath10k *ar,
1525static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) 1528static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
1526{ 1529{
1527 struct ath10k *ar = htt->ar; 1530 struct ath10k *ar = htt->ar;
1528 static struct ieee80211_rx_status rx_status; 1531 struct ieee80211_rx_status *rx_status = &htt->rx_status;
1529 struct sk_buff_head amsdu; 1532 struct sk_buff_head amsdu;
1530 int ret; 1533 int ret, num_msdus;
1531 1534
1532 __skb_queue_head_init(&amsdu); 1535 __skb_queue_head_init(&amsdu);
1533 1536
@@ -1549,13 +1552,14 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
1549 return ret; 1552 return ret;
1550 } 1553 }
1551 1554
1552 ath10k_htt_rx_h_ppdu(ar, &amsdu, &rx_status, 0xffff); 1555 num_msdus = skb_queue_len(&amsdu);
1556 ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
1553 ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); 1557 ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0);
1554 ath10k_htt_rx_h_filter(ar, &amsdu, &rx_status); 1558 ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
1555 ath10k_htt_rx_h_mpdu(ar, &amsdu, &rx_status); 1559 ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
1556 ath10k_htt_rx_h_deliver(ar, &amsdu, &rx_status); 1560 ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status);
1557 1561
1558 return 0; 1562 return num_msdus;
1559} 1563}
1560 1564
1561static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt, 1565static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt,
@@ -1579,15 +1583,6 @@ static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt,
1579 mpdu_count += mpdu_ranges[i].mpdu_count; 1583 mpdu_count += mpdu_ranges[i].mpdu_count;
1580 1584
1581 atomic_add(mpdu_count, &htt->num_mpdus_ready); 1585 atomic_add(mpdu_count, &htt->num_mpdus_ready);
1582
1583 tasklet_schedule(&htt->txrx_compl_task);
1584}
1585
1586static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt)
1587{
1588 atomic_inc(&htt->num_mpdus_ready);
1589
1590 tasklet_schedule(&htt->txrx_compl_task);
1591} 1586}
1592 1587
1593static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, 1588static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
@@ -1772,14 +1767,15 @@ static void ath10k_htt_rx_h_rx_offload_prot(struct ieee80211_rx_status *status,
1772 RX_FLAG_MMIC_STRIPPED; 1767 RX_FLAG_MMIC_STRIPPED;
1773} 1768}
1774 1769
1775static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar, 1770static int ath10k_htt_rx_h_rx_offload(struct ath10k *ar,
1776 struct sk_buff_head *list) 1771 struct sk_buff_head *list)
1777{ 1772{
1778 struct ath10k_htt *htt = &ar->htt; 1773 struct ath10k_htt *htt = &ar->htt;
1779 struct ieee80211_rx_status *status = &htt->rx_status; 1774 struct ieee80211_rx_status *status = &htt->rx_status;
1780 struct htt_rx_offload_msdu *rx; 1775 struct htt_rx_offload_msdu *rx;
1781 struct sk_buff *msdu; 1776 struct sk_buff *msdu;
1782 size_t offset; 1777 size_t offset;
1778 int num_msdu = 0;
1783 1779
1784 while ((msdu = __skb_dequeue(list))) { 1780 while ((msdu = __skb_dequeue(list))) {
1785 /* Offloaded frames don't have Rx descriptor. Instead they have 1781 /* Offloaded frames don't have Rx descriptor. Instead they have
@@ -1819,10 +1815,12 @@ static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar,
1819 ath10k_htt_rx_h_rx_offload_prot(status, msdu); 1815 ath10k_htt_rx_h_rx_offload_prot(status, msdu);
1820 ath10k_htt_rx_h_channel(ar, status, NULL, rx->vdev_id); 1816 ath10k_htt_rx_h_channel(ar, status, NULL, rx->vdev_id);
1821 ath10k_process_rx(ar, status, msdu); 1817 ath10k_process_rx(ar, status, msdu);
1818 num_msdu++;
1822 } 1819 }
1820 return num_msdu;
1823} 1821}
1824 1822
1825static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) 1823static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1826{ 1824{
1827 struct ath10k_htt *htt = &ar->htt; 1825 struct ath10k_htt *htt = &ar->htt;
1828 struct htt_resp *resp = (void *)skb->data; 1826 struct htt_resp *resp = (void *)skb->data;
@@ -1835,12 +1833,12 @@ static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1835 u8 tid; 1833 u8 tid;
1836 bool offload; 1834 bool offload;
1837 bool frag; 1835 bool frag;
1838 int ret; 1836 int ret, num_msdus = 0;
1839 1837
1840 lockdep_assert_held(&htt->rx_ring.lock); 1838 lockdep_assert_held(&htt->rx_ring.lock);
1841 1839
1842 if (htt->rx_confused) 1840 if (htt->rx_confused)
1843 return; 1841 return -EIO;
1844 1842
1845 skb_pull(skb, sizeof(resp->hdr)); 1843 skb_pull(skb, sizeof(resp->hdr));
1846 skb_pull(skb, sizeof(resp->rx_in_ord_ind)); 1844 skb_pull(skb, sizeof(resp->rx_in_ord_ind));
@@ -1859,7 +1857,7 @@ static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1859 1857
1860 if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) { 1858 if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) {
1861 ath10k_warn(ar, "dropping invalid in order rx indication\n"); 1859 ath10k_warn(ar, "dropping invalid in order rx indication\n");
1862 return; 1860 return -EINVAL;
1863 } 1861 }
1864 1862
1865 /* The event can deliver more than 1 A-MSDU. Each A-MSDU is later 1863 /* The event can deliver more than 1 A-MSDU. Each A-MSDU is later
@@ -1870,14 +1868,14 @@ static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1870 if (ret < 0) { 1868 if (ret < 0) {
1871 ath10k_warn(ar, "failed to pop paddr list: %d\n", ret); 1869 ath10k_warn(ar, "failed to pop paddr list: %d\n", ret);
1872 htt->rx_confused = true; 1870 htt->rx_confused = true;
1873 return; 1871 return -EIO;
1874 } 1872 }
1875 1873
1876 /* Offloaded frames are very different and need to be handled 1874 /* Offloaded frames are very different and need to be handled
1877 * separately. 1875 * separately.
1878 */ 1876 */
1879 if (offload) 1877 if (offload)
1880 ath10k_htt_rx_h_rx_offload(ar, &list); 1878 num_msdus = ath10k_htt_rx_h_rx_offload(ar, &list);
1881 1879
1882 while (!skb_queue_empty(&list)) { 1880 while (!skb_queue_empty(&list)) {
1883 __skb_queue_head_init(&amsdu); 1881 __skb_queue_head_init(&amsdu);
@@ -1890,6 +1888,7 @@ static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1890 * better to report something than nothing though. This 1888 * better to report something than nothing though. This
1891 * should still give an idea about rx rate to the user. 1889 * should still give an idea about rx rate to the user.
1892 */ 1890 */
1891 num_msdus += skb_queue_len(&amsdu);
1893 ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); 1892 ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
1894 ath10k_htt_rx_h_filter(ar, &amsdu, status); 1893 ath10k_htt_rx_h_filter(ar, &amsdu, status);
1895 ath10k_htt_rx_h_mpdu(ar, &amsdu, status); 1894 ath10k_htt_rx_h_mpdu(ar, &amsdu, status);
@@ -1902,9 +1901,10 @@ static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1902 ath10k_warn(ar, "failed to extract amsdu: %d\n", ret); 1901 ath10k_warn(ar, "failed to extract amsdu: %d\n", ret);
1903 htt->rx_confused = true; 1902 htt->rx_confused = true;
1904 __skb_queue_purge(&list); 1903 __skb_queue_purge(&list);
1905 return; 1904 return -EIO;
1906 } 1905 }
1907 } 1906 }
1907 return num_msdus;
1908} 1908}
1909 1909
1910static void ath10k_htt_rx_tx_fetch_resp_id_confirm(struct ath10k *ar, 1910static void ath10k_htt_rx_tx_fetch_resp_id_confirm(struct ath10k *ar,
@@ -2267,7 +2267,6 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2267 } 2267 }
2268 case HTT_T2H_MSG_TYPE_TX_COMPL_IND: 2268 case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
2269 ath10k_htt_rx_tx_compl_ind(htt->ar, skb); 2269 ath10k_htt_rx_tx_compl_ind(htt->ar, skb);
2270 tasklet_schedule(&htt->txrx_compl_task);
2271 break; 2270 break;
2272 case HTT_T2H_MSG_TYPE_SEC_IND: { 2271 case HTT_T2H_MSG_TYPE_SEC_IND: {
2273 struct ath10k *ar = htt->ar; 2272 struct ath10k *ar = htt->ar;
@@ -2284,7 +2283,7 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2284 case HTT_T2H_MSG_TYPE_RX_FRAG_IND: { 2283 case HTT_T2H_MSG_TYPE_RX_FRAG_IND: {
2285 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", 2284 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
2286 skb->data, skb->len); 2285 skb->data, skb->len);
2287 ath10k_htt_rx_frag_handler(htt); 2286 atomic_inc(&htt->num_mpdus_ready);
2288 break; 2287 break;
2289 } 2288 }
2290 case HTT_T2H_MSG_TYPE_TEST: 2289 case HTT_T2H_MSG_TYPE_TEST:
@@ -2320,8 +2319,7 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2320 break; 2319 break;
2321 } 2320 }
2322 case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: { 2321 case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: {
2323 skb_queue_tail(&htt->rx_in_ord_compl_q, skb); 2322 __skb_queue_tail(&htt->rx_in_ord_compl_q, skb);
2324 tasklet_schedule(&htt->txrx_compl_task);
2325 return false; 2323 return false;
2326 } 2324 }
2327 case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND: 2325 case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
@@ -2347,7 +2345,6 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2347 break; 2345 break;
2348 } 2346 }
2349 skb_queue_tail(&htt->tx_fetch_ind_q, tx_fetch_ind); 2347 skb_queue_tail(&htt->tx_fetch_ind_q, tx_fetch_ind);
2350 tasklet_schedule(&htt->txrx_compl_task);
2351 break; 2348 break;
2352 } 2349 }
2353 case HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM: 2350 case HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM:
@@ -2376,27 +2373,77 @@ void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
2376} 2373}
2377EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler); 2374EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler);
2378 2375
2379static void ath10k_htt_txrx_compl_task(unsigned long ptr) 2376int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget)
2380{ 2377{
2381 struct ath10k_htt *htt = (struct ath10k_htt *)ptr; 2378 struct ath10k_htt *htt = &ar->htt;
2382 struct ath10k *ar = htt->ar;
2383 struct htt_tx_done tx_done = {}; 2379 struct htt_tx_done tx_done = {};
2384 struct sk_buff_head rx_ind_q;
2385 struct sk_buff_head tx_ind_q; 2380 struct sk_buff_head tx_ind_q;
2386 struct sk_buff *skb; 2381 struct sk_buff *skb;
2387 unsigned long flags; 2382 unsigned long flags;
2388 int num_mpdus; 2383 int quota = 0, done, num_rx_msdus;
2384 bool resched_napi = false;
2389 2385
2390 __skb_queue_head_init(&rx_ind_q);
2391 __skb_queue_head_init(&tx_ind_q); 2386 __skb_queue_head_init(&tx_ind_q);
2392 2387
2393 spin_lock_irqsave(&htt->rx_in_ord_compl_q.lock, flags); 2388 /* Since in-ord-ind can deliver more than 1 A-MSDU in single event,
2394 skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q); 2389 * process it first to utilize full available quota.
2395 spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags); 2390 */
2391 while (quota < budget) {
2392 if (skb_queue_empty(&htt->rx_in_ord_compl_q))
2393 break;
2396 2394
2397 spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags); 2395 skb = __skb_dequeue(&htt->rx_in_ord_compl_q);
2398 skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q); 2396 if (!skb) {
2399 spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags); 2397 resched_napi = true;
2398 goto exit;
2399 }
2400
2401 spin_lock_bh(&htt->rx_ring.lock);
2402 num_rx_msdus = ath10k_htt_rx_in_ord_ind(ar, skb);
2403 spin_unlock_bh(&htt->rx_ring.lock);
2404 if (num_rx_msdus < 0) {
2405 resched_napi = true;
2406 goto exit;
2407 }
2408
2409 dev_kfree_skb_any(skb);
2410 if (num_rx_msdus > 0)
2411 quota += num_rx_msdus;
2412
2413 if ((quota > ATH10K_NAPI_QUOTA_LIMIT) &&
2414 !skb_queue_empty(&htt->rx_in_ord_compl_q)) {
2415 resched_napi = true;
2416 goto exit;
2417 }
2418 }
2419
2420 while (quota < budget) {
2421 /* no more data to receive */
2422 if (!atomic_read(&htt->num_mpdus_ready))
2423 break;
2424
2425 num_rx_msdus = ath10k_htt_rx_handle_amsdu(htt);
2426 if (num_rx_msdus < 0) {
2427 resched_napi = true;
2428 goto exit;
2429 }
2430
2431 quota += num_rx_msdus;
2432 atomic_dec(&htt->num_mpdus_ready);
2433 if ((quota > ATH10K_NAPI_QUOTA_LIMIT) &&
2434 atomic_read(&htt->num_mpdus_ready)) {
2435 resched_napi = true;
2436 goto exit;
2437 }
2438 }
2439
2440 /* From NAPI documentation:
2441 * The napi poll() function may also process TX completions, in which
2442 * case if it processes the entire TX ring then it should count that
2443 * work as the rest of the budget.
2444 */
2445 if ((quota < budget) && !kfifo_is_empty(&htt->txdone_fifo))
2446 quota = budget;
2400 2447
2401 /* kfifo_get: called only within txrx_tasklet so it's neatly serialized. 2448 /* kfifo_get: called only within txrx_tasklet so it's neatly serialized.
2402 * From kfifo_get() documentation: 2449 * From kfifo_get() documentation:
@@ -2406,27 +2453,24 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr)
2406 while (kfifo_get(&htt->txdone_fifo, &tx_done)) 2453 while (kfifo_get(&htt->txdone_fifo, &tx_done))
2407 ath10k_txrx_tx_unref(htt, &tx_done); 2454 ath10k_txrx_tx_unref(htt, &tx_done);
2408 2455
2409 while ((skb = __skb_dequeue(&tx_ind_q))) { 2456 ath10k_mac_tx_push_pending(ar);
2410 ath10k_htt_rx_tx_fetch_ind(ar, skb);
2411 dev_kfree_skb_any(skb);
2412 }
2413
2414 num_mpdus = atomic_read(&htt->num_mpdus_ready);
2415
2416 while (num_mpdus) {
2417 if (ath10k_htt_rx_handle_amsdu(htt))
2418 break;
2419 2457
2420 num_mpdus--; 2458 spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags);
2421 atomic_dec(&htt->num_mpdus_ready); 2459 skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q);
2422 } 2460 spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags);
2423 2461
2424 while ((skb = __skb_dequeue(&rx_ind_q))) { 2462 while ((skb = __skb_dequeue(&tx_ind_q))) {
2425 spin_lock_bh(&htt->rx_ring.lock); 2463 ath10k_htt_rx_tx_fetch_ind(ar, skb);
2426 ath10k_htt_rx_in_ord_ind(ar, skb);
2427 spin_unlock_bh(&htt->rx_ring.lock);
2428 dev_kfree_skb_any(skb); 2464 dev_kfree_skb_any(skb);
2429 } 2465 }
2430 2466
2467exit:
2431 ath10k_htt_rx_msdu_buff_replenish(htt); 2468 ath10k_htt_rx_msdu_buff_replenish(htt);
2469 /* In case of rx failure or more data to read, report budget
2470 * to reschedule NAPI poll
2471 */
2472 done = resched_napi ? budget : quota;
2473
2474 return done;
2432} 2475}
2476EXPORT_SYMBOL(ath10k_htt_txrx_compl_task);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 7c072b605bc7..ae5b33fe5ba8 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -390,8 +390,6 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)
390{ 390{
391 int size; 391 int size;
392 392
393 tasklet_kill(&htt->txrx_compl_task);
394
395 idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); 393 idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
396 idr_destroy(&htt->pending_tx); 394 idr_destroy(&htt->pending_tx);
397 395
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index f903d468dbe6..c2ecb9bd824a 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -219,3 +219,16 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
219 survey->time = CCNT_TO_MSEC(ar, cc); 219 survey->time = CCNT_TO_MSEC(ar, cc);
220 survey->time_busy = CCNT_TO_MSEC(ar, rcc); 220 survey->time_busy = CCNT_TO_MSEC(ar, rcc);
221} 221}
222
223const struct ath10k_hw_ops qca988x_ops = {
224};
225
226static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd)
227{
228 return MS(__le32_to_cpu(rxd->msdu_end.qca99x0.info1),
229 RX_MSDU_END_INFO1_L3_HDR_PAD);
230}
231
232const struct ath10k_hw_ops qca99x0_ops = {
233 .rx_desc_get_l3_pad_bytes = ath10k_qca99x0_rx_desc_get_l3_pad_bytes,
234};
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index e014cd732a0d..308e423d4b99 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -338,11 +338,6 @@ enum ath10k_hw_rate_rev2_cck {
338 ATH10K_HW_RATE_REV2_CCK_SP_11M, 338 ATH10K_HW_RATE_REV2_CCK_SP_11M,
339}; 339};
340 340
341enum ath10k_hw_4addr_pad {
342 ATH10K_HW_4ADDR_PAD_AFTER,
343 ATH10K_HW_4ADDR_PAD_BEFORE,
344};
345
346enum ath10k_hw_cc_wraparound_type { 341enum ath10k_hw_cc_wraparound_type {
347 ATH10K_HW_CC_WRAP_DISABLED = 0, 342 ATH10K_HW_CC_WRAP_DISABLED = 0,
348 343
@@ -363,6 +358,77 @@ enum ath10k_hw_cc_wraparound_type {
363 ATH10K_HW_CC_WRAP_SHIFTED_EACH = 2, 358 ATH10K_HW_CC_WRAP_SHIFTED_EACH = 2,
364}; 359};
365 360
361struct ath10k_hw_params {
362 u32 id;
363 u16 dev_id;
364 const char *name;
365 u32 patch_load_addr;
366 int uart_pin;
367 u32 otp_exe_param;
368
369 /* Type of hw cycle counter wraparound logic, for more info
370 * refer enum ath10k_hw_cc_wraparound_type.
371 */
372 enum ath10k_hw_cc_wraparound_type cc_wraparound_type;
373
374 /* Some of chip expects fragment descriptor to be continuous
375 * memory for any TX operation. Set continuous_frag_desc flag
376 * for the hardware which have such requirement.
377 */
378 bool continuous_frag_desc;
379
380 /* CCK hardware rate table mapping for the newer chipsets
381 * like QCA99X0, QCA4019 got revised. The CCK h/w rate values
382 * are in a proper order with respect to the rate/preamble
383 */
384 bool cck_rate_map_rev2;
385
386 u32 channel_counters_freq_hz;
387
388 /* Mgmt tx descriptors threshold for limiting probe response
389 * frames.
390 */
391 u32 max_probe_resp_desc_thres;
392
393 u32 tx_chain_mask;
394 u32 rx_chain_mask;
395 u32 max_spatial_stream;
396 u32 cal_data_len;
397
398 struct ath10k_hw_params_fw {
399 const char *dir;
400 const char *board;
401 size_t board_size;
402 size_t board_ext_size;
403 } fw;
404
405 /* qca99x0 family chips deliver broadcast/multicast management
406 * frames encrypted and expect software do decryption.
407 */
408 bool sw_decrypt_mcast_mgmt;
409
410 const struct ath10k_hw_ops *hw_ops;
411};
412
413struct htt_rx_desc;
414
415/* Defines needed for Rx descriptor abstraction */
416struct ath10k_hw_ops {
417 int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd);
418};
419
420extern const struct ath10k_hw_ops qca988x_ops;
421extern const struct ath10k_hw_ops qca99x0_ops;
422
423static inline int
424ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
425 struct htt_rx_desc *rxd)
426{
427 if (hw->hw_ops->rx_desc_get_l3_pad_bytes)
428 return hw->hw_ops->rx_desc_get_l3_pad_bytes(rxd);
429 return 0;
430}
431
366/* Target specific defines for MAIN firmware */ 432/* Target specific defines for MAIN firmware */
367#define TARGET_NUM_VDEVS 8 433#define TARGET_NUM_VDEVS 8
368#define TARGET_NUM_PEER_AST 2 434#define TARGET_NUM_PEER_AST 2
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 0bbd0a00edcc..0a44dab5a287 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -824,7 +824,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
824 */ 824 */
825 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { 825 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
826 if (ar->peer_map[i] == peer) { 826 if (ar->peer_map[i] == peer) {
827 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n", 827 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
828 peer->addr, peer, i); 828 peer->addr, peer, i);
829 ar->peer_map[i] = NULL; 829 ar->peer_map[i] = NULL;
830 } 830 }
@@ -3255,6 +3255,8 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3255 if (ar->htt.target_version_major < 3 && 3255 if (ar->htt.target_version_major < 3 &&
3256 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) && 3256 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
3257 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, 3257 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3258 ar->running_fw->fw_file.fw_features) &&
3259 !test_bit(ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR,
3258 ar->running_fw->fw_file.fw_features)) 3260 ar->running_fw->fw_file.fw_features))
3259 return ATH10K_HW_TXRX_MGMT; 3261 return ATH10K_HW_TXRX_MGMT;
3260 3262
@@ -3524,7 +3526,7 @@ static int ath10k_mac_tx(struct ath10k *ar,
3524 3526
3525 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) { 3527 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3526 if (!ath10k_mac_tx_frm_has_freq(ar)) { 3528 if (!ath10k_mac_tx_frm_has_freq(ar)) {
3527 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n", 3529 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
3528 skb); 3530 skb);
3529 3531
3530 skb_queue_tail(&ar->offchan_tx_queue, skb); 3532 skb_queue_tail(&ar->offchan_tx_queue, skb);
@@ -3586,7 +3588,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
3586 3588
3587 mutex_lock(&ar->conf_mutex); 3589 mutex_lock(&ar->conf_mutex);
3588 3590
3589 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n", 3591 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
3590 skb); 3592 skb);
3591 3593
3592 hdr = (struct ieee80211_hdr *)skb->data; 3594 hdr = (struct ieee80211_hdr *)skb->data;
@@ -3643,7 +3645,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
3643 time_left = 3645 time_left =
3644 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ); 3646 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3645 if (time_left == 0) 3647 if (time_left == 0)
3646 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n", 3648 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
3647 skb); 3649 skb);
3648 3650
3649 if (!peer && tmp_peer_created) { 3651 if (!peer && tmp_peer_created) {
@@ -3777,7 +3779,9 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3777 enum ath10k_hw_txrx_mode txmode; 3779 enum ath10k_hw_txrx_mode txmode;
3778 enum ath10k_mac_tx_path txpath; 3780 enum ath10k_mac_tx_path txpath;
3779 struct sk_buff *skb; 3781 struct sk_buff *skb;
3782 struct ieee80211_hdr *hdr;
3780 size_t skb_len; 3783 size_t skb_len;
3784 bool is_mgmt, is_presp;
3781 int ret; 3785 int ret;
3782 3786
3783 spin_lock_bh(&ar->htt.tx_lock); 3787 spin_lock_bh(&ar->htt.tx_lock);
@@ -3801,6 +3805,22 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3801 skb_len = skb->len; 3805 skb_len = skb->len;
3802 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); 3806 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3803 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); 3807 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
3808 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
3809
3810 if (is_mgmt) {
3811 hdr = (struct ieee80211_hdr *)skb->data;
3812 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3813
3814 spin_lock_bh(&ar->htt.tx_lock);
3815 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
3816
3817 if (ret) {
3818 ath10k_htt_tx_dec_pending(htt);
3819 spin_unlock_bh(&ar->htt.tx_lock);
3820 return ret;
3821 }
3822 spin_unlock_bh(&ar->htt.tx_lock);
3823 }
3804 3824
3805 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb); 3825 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3806 if (unlikely(ret)) { 3826 if (unlikely(ret)) {
@@ -3808,6 +3828,8 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3808 3828
3809 spin_lock_bh(&ar->htt.tx_lock); 3829 spin_lock_bh(&ar->htt.tx_lock);
3810 ath10k_htt_tx_dec_pending(htt); 3830 ath10k_htt_tx_dec_pending(htt);
3831 if (is_mgmt)
3832 ath10k_htt_tx_mgmt_dec_pending(htt);
3811 spin_unlock_bh(&ar->htt.tx_lock); 3833 spin_unlock_bh(&ar->htt.tx_lock);
3812 3834
3813 return ret; 3835 return ret;
@@ -3894,7 +3916,7 @@ void __ath10k_scan_finish(struct ath10k *ar)
3894 ar->scan.roc_freq = 0; 3916 ar->scan.roc_freq = 0;
3895 ath10k_offchan_tx_purge(ar); 3917 ath10k_offchan_tx_purge(ar);
3896 cancel_delayed_work(&ar->scan.timeout); 3918 cancel_delayed_work(&ar->scan.timeout);
3897 complete_all(&ar->scan.completed); 3919 complete(&ar->scan.completed);
3898 break; 3920 break;
3899 } 3921 }
3900} 3922}
@@ -4100,13 +4122,29 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4100{ 4122{
4101 struct ath10k *ar = hw->priv; 4123 struct ath10k *ar = hw->priv;
4102 struct ath10k_txq *artxq = (void *)txq->drv_priv; 4124 struct ath10k_txq *artxq = (void *)txq->drv_priv;
4125 struct ieee80211_txq *f_txq;
4126 struct ath10k_txq *f_artxq;
4127 int ret = 0;
4128 int max = 16;
4103 4129
4104 spin_lock_bh(&ar->txqs_lock); 4130 spin_lock_bh(&ar->txqs_lock);
4105 if (list_empty(&artxq->list)) 4131 if (list_empty(&artxq->list))
4106 list_add_tail(&artxq->list, &ar->txqs); 4132 list_add_tail(&artxq->list, &ar->txqs);
4133
4134 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4135 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4136 list_del_init(&f_artxq->list);
4137
4138 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
4139 ret = ath10k_mac_tx_push_txq(hw, f_txq);
4140 if (ret)
4141 break;
4142 }
4143 if (ret != -ENOENT)
4144 list_add_tail(&f_artxq->list, &ar->txqs);
4107 spin_unlock_bh(&ar->txqs_lock); 4145 spin_unlock_bh(&ar->txqs_lock);
4108 4146
4109 ath10k_mac_tx_push_pending(ar); 4147 ath10k_htt_tx_txq_update(hw, f_txq);
4110 ath10k_htt_tx_txq_update(hw, txq); 4148 ath10k_htt_tx_txq_update(hw, txq);
4111} 4149}
4112 4150
@@ -5186,7 +5224,7 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw,
5186 5224
5187 ret = ath10k_monitor_recalc(ar); 5225 ret = ath10k_monitor_recalc(ar);
5188 if (ret) 5226 if (ret)
5189 ath10k_warn(ar, "failed to recalc montior: %d\n", ret); 5227 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5190 5228
5191 mutex_unlock(&ar->conf_mutex); 5229 mutex_unlock(&ar->conf_mutex);
5192} 5230}
@@ -5984,8 +6022,8 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
5984 * Existing station deletion. 6022 * Existing station deletion.
5985 */ 6023 */
5986 ath10k_dbg(ar, ATH10K_DBG_MAC, 6024 ath10k_dbg(ar, ATH10K_DBG_MAC,
5987 "mac vdev %d peer delete %pM (sta gone)\n", 6025 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
5988 arvif->vdev_id, sta->addr); 6026 arvif->vdev_id, sta->addr, sta);
5989 6027
5990 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); 6028 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5991 if (ret) 6029 if (ret)
@@ -6001,7 +6039,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
6001 continue; 6039 continue;
6002 6040
6003 if (peer->sta == sta) { 6041 if (peer->sta == sta) {
6004 ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n", 6042 ath10k_warn(ar, "found sta peer %pM (ptr %pK id %d) entry on vdev %i after it was supposedly removed\n",
6005 sta->addr, peer, i, arvif->vdev_id); 6043 sta->addr, peer, i, arvif->vdev_id);
6006 peer->sta = NULL; 6044 peer->sta = NULL;
6007 6045
@@ -6538,7 +6576,7 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6538 goto exit; 6576 goto exit;
6539 } 6577 }
6540 6578
6541 ath10k_mac_update_bss_chan_survey(ar, survey->channel); 6579 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
6542 6580
6543 spin_lock_bh(&ar->data_lock); 6581 spin_lock_bh(&ar->data_lock);
6544 memcpy(survey, ar_survey, sizeof(*survey)); 6582 memcpy(survey, ar_survey, sizeof(*survey));
@@ -7134,7 +7172,7 @@ ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7134 struct ath10k *ar = hw->priv; 7172 struct ath10k *ar = hw->priv;
7135 7173
7136 ath10k_dbg(ar, ATH10K_DBG_MAC, 7174 ath10k_dbg(ar, ATH10K_DBG_MAC,
7137 "mac chanctx add freq %hu width %d ptr %p\n", 7175 "mac chanctx add freq %hu width %d ptr %pK\n",
7138 ctx->def.chan->center_freq, ctx->def.width, ctx); 7176 ctx->def.chan->center_freq, ctx->def.width, ctx);
7139 7177
7140 mutex_lock(&ar->conf_mutex); 7178 mutex_lock(&ar->conf_mutex);
@@ -7158,7 +7196,7 @@ ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7158 struct ath10k *ar = hw->priv; 7196 struct ath10k *ar = hw->priv;
7159 7197
7160 ath10k_dbg(ar, ATH10K_DBG_MAC, 7198 ath10k_dbg(ar, ATH10K_DBG_MAC,
7161 "mac chanctx remove freq %hu width %d ptr %p\n", 7199 "mac chanctx remove freq %hu width %d ptr %pK\n",
7162 ctx->def.chan->center_freq, ctx->def.width, ctx); 7200 ctx->def.chan->center_freq, ctx->def.width, ctx);
7163 7201
7164 mutex_lock(&ar->conf_mutex); 7202 mutex_lock(&ar->conf_mutex);
@@ -7223,7 +7261,7 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7223 mutex_lock(&ar->conf_mutex); 7261 mutex_lock(&ar->conf_mutex);
7224 7262
7225 ath10k_dbg(ar, ATH10K_DBG_MAC, 7263 ath10k_dbg(ar, ATH10K_DBG_MAC,
7226 "mac chanctx change freq %hu width %d ptr %p changed %x\n", 7264 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
7227 ctx->def.chan->center_freq, ctx->def.width, ctx, changed); 7265 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
7228 7266
7229 /* This shouldn't really happen because channel switching should use 7267 /* This shouldn't really happen because channel switching should use
@@ -7281,7 +7319,7 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7281 mutex_lock(&ar->conf_mutex); 7319 mutex_lock(&ar->conf_mutex);
7282 7320
7283 ath10k_dbg(ar, ATH10K_DBG_MAC, 7321 ath10k_dbg(ar, ATH10K_DBG_MAC,
7284 "mac chanctx assign ptr %p vdev_id %i\n", 7322 "mac chanctx assign ptr %pK vdev_id %i\n",
7285 ctx, arvif->vdev_id); 7323 ctx, arvif->vdev_id);
7286 7324
7287 if (WARN_ON(arvif->is_started)) { 7325 if (WARN_ON(arvif->is_started)) {
@@ -7342,7 +7380,7 @@ ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7342 mutex_lock(&ar->conf_mutex); 7380 mutex_lock(&ar->conf_mutex);
7343 7381
7344 ath10k_dbg(ar, ATH10K_DBG_MAC, 7382 ath10k_dbg(ar, ATH10K_DBG_MAC,
7345 "mac chanctx unassign ptr %p vdev_id %i\n", 7383 "mac chanctx unassign ptr %pK vdev_id %i\n",
7346 ctx, arvif->vdev_id); 7384 ctx, arvif->vdev_id);
7347 7385
7348 WARN_ON(!arvif->is_started); 7386 WARN_ON(!arvif->is_started);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 9a22c478dd1b..0457e315d336 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1506,12 +1506,10 @@ void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
1506 ath10k_ce_per_engine_service(ar, pipe); 1506 ath10k_ce_per_engine_service(ar, pipe);
1507} 1507}
1508 1508
1509void ath10k_pci_kill_tasklet(struct ath10k *ar) 1509static void ath10k_pci_rx_retry_sync(struct ath10k *ar)
1510{ 1510{
1511 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1511 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1512 1512
1513 tasklet_kill(&ar_pci->intr_tq);
1514
1515 del_timer_sync(&ar_pci->rx_post_retry); 1513 del_timer_sync(&ar_pci->rx_post_retry);
1516} 1514}
1517 1515
@@ -1570,7 +1568,7 @@ void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
1570 ul_pipe, dl_pipe); 1568 ul_pipe, dl_pipe);
1571} 1569}
1572 1570
1573static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar) 1571void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar)
1574{ 1572{
1575 u32 val; 1573 u32 val;
1576 1574
@@ -1693,14 +1691,12 @@ static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
1693static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe) 1691static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
1694{ 1692{
1695 struct ath10k *ar; 1693 struct ath10k *ar;
1696 struct ath10k_pci *ar_pci;
1697 struct ath10k_ce_pipe *ce_pipe; 1694 struct ath10k_ce_pipe *ce_pipe;
1698 struct ath10k_ce_ring *ce_ring; 1695 struct ath10k_ce_ring *ce_ring;
1699 struct sk_buff *skb; 1696 struct sk_buff *skb;
1700 int i; 1697 int i;
1701 1698
1702 ar = pci_pipe->hif_ce_state; 1699 ar = pci_pipe->hif_ce_state;
1703 ar_pci = ath10k_pci_priv(ar);
1704 ce_pipe = pci_pipe->ce_hdl; 1700 ce_pipe = pci_pipe->ce_hdl;
1705 ce_ring = ce_pipe->src_ring; 1701 ce_ring = ce_pipe->src_ring;
1706 1702
@@ -1753,7 +1749,7 @@ void ath10k_pci_ce_deinit(struct ath10k *ar)
1753 1749
1754void ath10k_pci_flush(struct ath10k *ar) 1750void ath10k_pci_flush(struct ath10k *ar)
1755{ 1751{
1756 ath10k_pci_kill_tasklet(ar); 1752 ath10k_pci_rx_retry_sync(ar);
1757 ath10k_pci_buffer_cleanup(ar); 1753 ath10k_pci_buffer_cleanup(ar);
1758} 1754}
1759 1755
@@ -1780,6 +1776,8 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
1780 ath10k_pci_irq_disable(ar); 1776 ath10k_pci_irq_disable(ar);
1781 ath10k_pci_irq_sync(ar); 1777 ath10k_pci_irq_sync(ar);
1782 ath10k_pci_flush(ar); 1778 ath10k_pci_flush(ar);
1779 napi_synchronize(&ar->napi);
1780 napi_disable(&ar->napi);
1783 1781
1784 spin_lock_irqsave(&ar_pci->ps_lock, flags); 1782 spin_lock_irqsave(&ar_pci->ps_lock, flags);
1785 WARN_ON(ar_pci->ps_wake_refcount > 0); 1783 WARN_ON(ar_pci->ps_wake_refcount > 0);
@@ -2533,6 +2531,7 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
2533 ath10k_err(ar, "could not wake up target CPU: %d\n", ret); 2531 ath10k_err(ar, "could not wake up target CPU: %d\n", ret);
2534 goto err_ce; 2532 goto err_ce;
2535 } 2533 }
2534 napi_enable(&ar->napi);
2536 2535
2537 return 0; 2536 return 0;
2538 2537
@@ -2725,7 +2724,7 @@ static int ath10k_pci_hif_fetch_cal_eeprom(struct ath10k *ar, void **data,
2725 return 0; 2724 return 0;
2726 2725
2727err_free: 2726err_free:
2728 kfree(data); 2727 kfree(caldata);
2729 2728
2730 return -EINVAL; 2729 return -EINVAL;
2731} 2730}
@@ -2772,35 +2771,53 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
2772 return IRQ_NONE; 2771 return IRQ_NONE;
2773 } 2772 }
2774 2773
2775 if (ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) { 2774 if ((ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) &&
2776 if (!ath10k_pci_irq_pending(ar)) 2775 !ath10k_pci_irq_pending(ar))
2777 return IRQ_NONE; 2776 return IRQ_NONE;
2778
2779 ath10k_pci_disable_and_clear_legacy_irq(ar);
2780 }
2781 2777
2782 tasklet_schedule(&ar_pci->intr_tq); 2778 ath10k_pci_disable_and_clear_legacy_irq(ar);
2779 ath10k_pci_irq_msi_fw_mask(ar);
2780 napi_schedule(&ar->napi);
2783 2781
2784 return IRQ_HANDLED; 2782 return IRQ_HANDLED;
2785} 2783}
2786 2784
2787static void ath10k_pci_tasklet(unsigned long data) 2785static int ath10k_pci_napi_poll(struct napi_struct *ctx, int budget)
2788{ 2786{
2789 struct ath10k *ar = (struct ath10k *)data; 2787 struct ath10k *ar = container_of(ctx, struct ath10k, napi);
2790 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2788 int done = 0;
2791 2789
2792 if (ath10k_pci_has_fw_crashed(ar)) { 2790 if (ath10k_pci_has_fw_crashed(ar)) {
2793 ath10k_pci_irq_disable(ar);
2794 ath10k_pci_fw_crashed_clear(ar); 2791 ath10k_pci_fw_crashed_clear(ar);
2795 ath10k_pci_fw_crashed_dump(ar); 2792 ath10k_pci_fw_crashed_dump(ar);
2796 return; 2793 napi_complete(ctx);
2794 return done;
2797 } 2795 }
2798 2796
2799 ath10k_ce_per_engine_service_any(ar); 2797 ath10k_ce_per_engine_service_any(ar);
2800 2798
2801 /* Re-enable legacy irq that was disabled in the irq handler */ 2799 done = ath10k_htt_txrx_compl_task(ar, budget);
2802 if (ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) 2800
2801 if (done < budget) {
2802 napi_complete(ctx);
2803 /* In case of MSI, it is possible that interrupts are received
2804 * while NAPI poll is inprogress. So pending interrupts that are
2805 * received after processing all copy engine pipes by NAPI poll
2806 * will not be handled again. This is causing failure to
2807 * complete boot sequence in x86 platform. So before enabling
2808 * interrupts safer to check for pending interrupts for
2809 * immediate servicing.
2810 */
2811 if (CE_INTERRUPT_SUMMARY(ar)) {
2812 napi_reschedule(ctx);
2813 goto out;
2814 }
2803 ath10k_pci_enable_legacy_irq(ar); 2815 ath10k_pci_enable_legacy_irq(ar);
2816 ath10k_pci_irq_msi_fw_unmask(ar);
2817 }
2818
2819out:
2820 return done;
2804} 2821}
2805 2822
2806static int ath10k_pci_request_irq_msi(struct ath10k *ar) 2823static int ath10k_pci_request_irq_msi(struct ath10k *ar)
@@ -2858,11 +2875,10 @@ static void ath10k_pci_free_irq(struct ath10k *ar)
2858 free_irq(ar_pci->pdev->irq, ar); 2875 free_irq(ar_pci->pdev->irq, ar);
2859} 2876}
2860 2877
2861void ath10k_pci_init_irq_tasklets(struct ath10k *ar) 2878void ath10k_pci_init_napi(struct ath10k *ar)
2862{ 2879{
2863 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2880 netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_pci_napi_poll,
2864 2881 ATH10K_NAPI_BUDGET);
2865 tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long)ar);
2866} 2882}
2867 2883
2868static int ath10k_pci_init_irq(struct ath10k *ar) 2884static int ath10k_pci_init_irq(struct ath10k *ar)
@@ -2870,7 +2886,7 @@ static int ath10k_pci_init_irq(struct ath10k *ar)
2870 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2886 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2871 int ret; 2887 int ret;
2872 2888
2873 ath10k_pci_init_irq_tasklets(ar); 2889 ath10k_pci_init_napi(ar);
2874 2890
2875 if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO) 2891 if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO)
2876 ath10k_info(ar, "limiting irq mode to: %d\n", 2892 ath10k_info(ar, "limiting irq mode to: %d\n",
@@ -3062,7 +3078,7 @@ static int ath10k_pci_claim(struct ath10k *ar)
3062 goto err_master; 3078 goto err_master;
3063 } 3079 }
3064 3080
3065 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); 3081 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot pci_mem 0x%pK\n", ar_pci->mem);
3066 return 0; 3082 return 0;
3067 3083
3068err_master: 3084err_master:
@@ -3131,7 +3147,8 @@ int ath10k_pci_setup_resource(struct ath10k *ar)
3131 3147
3132void ath10k_pci_release_resource(struct ath10k *ar) 3148void ath10k_pci_release_resource(struct ath10k *ar)
3133{ 3149{
3134 ath10k_pci_kill_tasklet(ar); 3150 ath10k_pci_rx_retry_sync(ar);
3151 netif_napi_del(&ar->napi);
3135 ath10k_pci_ce_deinit(ar); 3152 ath10k_pci_ce_deinit(ar);
3136 ath10k_pci_free_pipes(ar); 3153 ath10k_pci_free_pipes(ar);
3137} 3154}
@@ -3162,7 +3179,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
3162 pci_hard_reset = ath10k_pci_qca988x_chip_reset; 3179 pci_hard_reset = ath10k_pci_qca988x_chip_reset;
3163 break; 3180 break;
3164 case QCA9887_1_0_DEVICE_ID: 3181 case QCA9887_1_0_DEVICE_ID:
3165 dev_warn(&pdev->dev, "QCA9887 support is still experimental, there are likely bugs. You have been warned.\n");
3166 hw_rev = ATH10K_HW_QCA9887; 3182 hw_rev = ATH10K_HW_QCA9887;
3167 pci_ps = false; 3183 pci_ps = false;
3168 pci_soft_reset = ath10k_pci_warm_reset; 3184 pci_soft_reset = ath10k_pci_warm_reset;
@@ -3298,7 +3314,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
3298 3314
3299err_free_irq: 3315err_free_irq:
3300 ath10k_pci_free_irq(ar); 3316 ath10k_pci_free_irq(ar);
3301 ath10k_pci_kill_tasklet(ar); 3317 ath10k_pci_rx_retry_sync(ar);
3302 3318
3303err_deinit_irq: 3319err_deinit_irq:
3304 ath10k_pci_deinit_irq(ar); 3320 ath10k_pci_deinit_irq(ar);
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 6eca1df2ce60..9854ad56b2de 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -177,8 +177,6 @@ struct ath10k_pci {
177 /* Operating interrupt mode */ 177 /* Operating interrupt mode */
178 enum ath10k_pci_irq_mode oper_irq_mode; 178 enum ath10k_pci_irq_mode oper_irq_mode;
179 179
180 struct tasklet_struct intr_tq;
181
182 struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; 180 struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX];
183 181
184 /* Copy Engine used for Diagnostic Accesses */ 182 /* Copy Engine used for Diagnostic Accesses */
@@ -294,8 +292,7 @@ void ath10k_pci_free_pipes(struct ath10k *ar);
294void ath10k_pci_free_pipes(struct ath10k *ar); 292void ath10k_pci_free_pipes(struct ath10k *ar);
295void ath10k_pci_rx_replenish_retry(unsigned long ptr); 293void ath10k_pci_rx_replenish_retry(unsigned long ptr);
296void ath10k_pci_ce_deinit(struct ath10k *ar); 294void ath10k_pci_ce_deinit(struct ath10k *ar);
297void ath10k_pci_init_irq_tasklets(struct ath10k *ar); 295void ath10k_pci_init_napi(struct ath10k *ar);
298void ath10k_pci_kill_tasklet(struct ath10k *ar);
299int ath10k_pci_init_pipes(struct ath10k *ar); 296int ath10k_pci_init_pipes(struct ath10k *ar);
300int ath10k_pci_init_config(struct ath10k *ar); 297int ath10k_pci_init_config(struct ath10k *ar);
301void ath10k_pci_rx_post(struct ath10k *ar); 298void ath10k_pci_rx_post(struct ath10k *ar);
@@ -303,6 +300,7 @@ void ath10k_pci_flush(struct ath10k *ar);
303void ath10k_pci_enable_legacy_irq(struct ath10k *ar); 300void ath10k_pci_enable_legacy_irq(struct ath10k *ar);
304bool ath10k_pci_irq_pending(struct ath10k *ar); 301bool ath10k_pci_irq_pending(struct ath10k *ar);
305void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar); 302void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar);
303void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar);
306int ath10k_pci_wait_for_target_init(struct ath10k *ar); 304int ath10k_pci_wait_for_target_init(struct ath10k *ar);
307int ath10k_pci_setup_resource(struct ath10k *ar); 305int ath10k_pci_setup_resource(struct ath10k *ar);
308void ath10k_pci_release_resource(struct ath10k *ar); 306void ath10k_pci_release_resource(struct ath10k *ar);
diff --git a/drivers/net/wireless/ath/ath10k/swap.c b/drivers/net/wireless/ath/ath10k/swap.c
index 0c5f5863dac8..adf4592374b4 100644
--- a/drivers/net/wireless/ath/ath10k/swap.c
+++ b/drivers/net/wireless/ath/ath10k/swap.c
@@ -134,17 +134,18 @@ ath10k_swap_code_seg_alloc(struct ath10k *ar, size_t swap_bin_len)
134 return seg_info; 134 return seg_info;
135} 135}
136 136
137int ath10k_swap_code_seg_configure(struct ath10k *ar) 137int ath10k_swap_code_seg_configure(struct ath10k *ar,
138 const struct ath10k_fw_file *fw_file)
138{ 139{
139 int ret; 140 int ret;
140 struct ath10k_swap_code_seg_info *seg_info = NULL; 141 struct ath10k_swap_code_seg_info *seg_info = NULL;
141 142
142 if (!ar->swap.firmware_swap_code_seg_info) 143 if (!fw_file->firmware_swap_code_seg_info)
143 return 0; 144 return 0;
144 145
145 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot found firmware code swap binary\n"); 146 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot found firmware code swap binary\n");
146 147
147 seg_info = ar->swap.firmware_swap_code_seg_info; 148 seg_info = fw_file->firmware_swap_code_seg_info;
148 149
149 ret = ath10k_bmi_write_memory(ar, seg_info->target_addr, 150 ret = ath10k_bmi_write_memory(ar, seg_info->target_addr,
150 &seg_info->seg_hw_info, 151 &seg_info->seg_hw_info,
@@ -158,28 +159,29 @@ int ath10k_swap_code_seg_configure(struct ath10k *ar)
158 return 0; 159 return 0;
159} 160}
160 161
161void ath10k_swap_code_seg_release(struct ath10k *ar) 162void ath10k_swap_code_seg_release(struct ath10k *ar,
163 struct ath10k_fw_file *fw_file)
162{ 164{
163 ath10k_swap_code_seg_free(ar, ar->swap.firmware_swap_code_seg_info); 165 ath10k_swap_code_seg_free(ar, fw_file->firmware_swap_code_seg_info);
164 166
165 /* FIXME: these two assignments look to bein wrong place! Shouldn't 167 /* FIXME: these two assignments look to bein wrong place! Shouldn't
166 * they be in ath10k_core_free_firmware_files() like the rest? 168 * they be in ath10k_core_free_firmware_files() like the rest?
167 */ 169 */
168 ar->normal_mode_fw.fw_file.codeswap_data = NULL; 170 fw_file->codeswap_data = NULL;
169 ar->normal_mode_fw.fw_file.codeswap_len = 0; 171 fw_file->codeswap_len = 0;
170 172
171 ar->swap.firmware_swap_code_seg_info = NULL; 173 fw_file->firmware_swap_code_seg_info = NULL;
172} 174}
173 175
174int ath10k_swap_code_seg_init(struct ath10k *ar) 176int ath10k_swap_code_seg_init(struct ath10k *ar, struct ath10k_fw_file *fw_file)
175{ 177{
176 int ret; 178 int ret;
177 struct ath10k_swap_code_seg_info *seg_info; 179 struct ath10k_swap_code_seg_info *seg_info;
178 const void *codeswap_data; 180 const void *codeswap_data;
179 size_t codeswap_len; 181 size_t codeswap_len;
180 182
181 codeswap_data = ar->normal_mode_fw.fw_file.codeswap_data; 183 codeswap_data = fw_file->codeswap_data;
182 codeswap_len = ar->normal_mode_fw.fw_file.codeswap_len; 184 codeswap_len = fw_file->codeswap_len;
183 185
184 if (!codeswap_len || !codeswap_data) 186 if (!codeswap_len || !codeswap_data)
185 return 0; 187 return 0;
@@ -200,7 +202,7 @@ int ath10k_swap_code_seg_init(struct ath10k *ar)
200 return ret; 202 return ret;
201 } 203 }
202 204
203 ar->swap.firmware_swap_code_seg_info = seg_info; 205 fw_file->firmware_swap_code_seg_info = seg_info;
204 206
205 return 0; 207 return 0;
206} 208}
diff --git a/drivers/net/wireless/ath/ath10k/swap.h b/drivers/net/wireless/ath/ath10k/swap.h
index 36991c7b07a0..f5dc0476493e 100644
--- a/drivers/net/wireless/ath/ath10k/swap.h
+++ b/drivers/net/wireless/ath/ath10k/swap.h
@@ -23,6 +23,8 @@
23/* Currently only one swap segment is supported */ 23/* Currently only one swap segment is supported */
24#define ATH10K_SWAP_CODE_SEG_NUM_SUPPORTED 1 24#define ATH10K_SWAP_CODE_SEG_NUM_SUPPORTED 1
25 25
26struct ath10k_fw_file;
27
26struct ath10k_swap_code_seg_tlv { 28struct ath10k_swap_code_seg_tlv {
27 __le32 address; 29 __le32 address;
28 __le32 length; 30 __le32 length;
@@ -58,8 +60,11 @@ struct ath10k_swap_code_seg_info {
58 dma_addr_t paddr[ATH10K_SWAP_CODE_SEG_NUM_SUPPORTED]; 60 dma_addr_t paddr[ATH10K_SWAP_CODE_SEG_NUM_SUPPORTED];
59}; 61};
60 62
61int ath10k_swap_code_seg_configure(struct ath10k *ar); 63int ath10k_swap_code_seg_configure(struct ath10k *ar,
62void ath10k_swap_code_seg_release(struct ath10k *ar); 64 const struct ath10k_fw_file *fw_file);
63int ath10k_swap_code_seg_init(struct ath10k *ar); 65void ath10k_swap_code_seg_release(struct ath10k *ar,
66 struct ath10k_fw_file *fw_file);
67int ath10k_swap_code_seg_init(struct ath10k *ar,
68 struct ath10k_fw_file *fw_file);
64 69
65#endif 70#endif
diff --git a/drivers/net/wireless/ath/ath10k/testmode.c b/drivers/net/wireless/ath/ath10k/testmode.c
index 120f4234d3b0..ed85f938e3c0 100644
--- a/drivers/net/wireless/ath/ath10k/testmode.c
+++ b/drivers/net/wireless/ath/ath10k/testmode.c
@@ -23,6 +23,7 @@
23#include "wmi.h" 23#include "wmi.h"
24#include "hif.h" 24#include "hif.h"
25#include "hw.h" 25#include "hw.h"
26#include "core.h"
26 27
27#include "testmode_i.h" 28#include "testmode_i.h"
28 29
@@ -45,7 +46,7 @@ bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
45 int ret; 46 int ret;
46 47
47 ath10k_dbg(ar, ATH10K_DBG_TESTMODE, 48 ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
48 "testmode event wmi cmd_id %d skb %p skb->len %d\n", 49 "testmode event wmi cmd_id %d skb %pK skb->len %d\n",
49 cmd_id, skb, skb->len); 50 cmd_id, skb, skb->len);
50 51
51 ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", skb->data, skb->len); 52 ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", skb->data, skb->len);
@@ -240,6 +241,18 @@ static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
240 goto err; 241 goto err;
241 } 242 }
242 243
244 if (ar->testmode.utf_mode_fw.fw_file.codeswap_data &&
245 ar->testmode.utf_mode_fw.fw_file.codeswap_len) {
246 ret = ath10k_swap_code_seg_init(ar,
247 &ar->testmode.utf_mode_fw.fw_file);
248 if (ret) {
249 ath10k_warn(ar,
250 "failed to init utf code swap segment: %d\n",
251 ret);
252 goto err_release_utf_mode_fw;
253 }
254 }
255
243 spin_lock_bh(&ar->data_lock); 256 spin_lock_bh(&ar->data_lock);
244 ar->testmode.utf_monitor = true; 257 ar->testmode.utf_monitor = true;
245 spin_unlock_bh(&ar->data_lock); 258 spin_unlock_bh(&ar->data_lock);
@@ -279,6 +292,11 @@ err_power_down:
279 ath10k_hif_power_down(ar); 292 ath10k_hif_power_down(ar);
280 293
281err_release_utf_mode_fw: 294err_release_utf_mode_fw:
295 if (ar->testmode.utf_mode_fw.fw_file.codeswap_data &&
296 ar->testmode.utf_mode_fw.fw_file.codeswap_len)
297 ath10k_swap_code_seg_release(ar,
298 &ar->testmode.utf_mode_fw.fw_file);
299
282 release_firmware(ar->testmode.utf_mode_fw.fw_file.firmware); 300 release_firmware(ar->testmode.utf_mode_fw.fw_file.firmware);
283 ar->testmode.utf_mode_fw.fw_file.firmware = NULL; 301 ar->testmode.utf_mode_fw.fw_file.firmware = NULL;
284 302
@@ -301,6 +319,11 @@ static void __ath10k_tm_cmd_utf_stop(struct ath10k *ar)
301 319
302 spin_unlock_bh(&ar->data_lock); 320 spin_unlock_bh(&ar->data_lock);
303 321
322 if (ar->testmode.utf_mode_fw.fw_file.codeswap_data &&
323 ar->testmode.utf_mode_fw.fw_file.codeswap_len)
324 ath10k_swap_code_seg_release(ar,
325 &ar->testmode.utf_mode_fw.fw_file);
326
304 release_firmware(ar->testmode.utf_mode_fw.fw_file.firmware); 327 release_firmware(ar->testmode.utf_mode_fw.fw_file.firmware);
305 ar->testmode.utf_mode_fw.fw_file.firmware = NULL; 328 ar->testmode.utf_mode_fw.fw_file.firmware = NULL;
306 329
@@ -360,7 +383,7 @@ static int ath10k_tm_cmd_wmi(struct ath10k *ar, struct nlattr *tb[])
360 cmd_id = nla_get_u32(tb[ATH10K_TM_ATTR_WMI_CMDID]); 383 cmd_id = nla_get_u32(tb[ATH10K_TM_ATTR_WMI_CMDID]);
361 384
362 ath10k_dbg(ar, ATH10K_DBG_TESTMODE, 385 ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
363 "testmode cmd wmi cmd_id %d buf %p buf_len %d\n", 386 "testmode cmd wmi cmd_id %d buf %pK buf_len %d\n",
364 cmd_id, buf, buf_len); 387 cmd_id, buf, buf_len);
365 388
366 ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len); 389 ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len);
diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c
index 444b52c7e4f3..0a47269be289 100644
--- a/drivers/net/wireless/ath/ath10k/thermal.c
+++ b/drivers/net/wireless/ath/ath10k/thermal.c
@@ -192,7 +192,7 @@ int ath10k_thermal_register(struct ath10k *ar)
192 192
193 /* Avoid linking error on devm_hwmon_device_register_with_groups, I 193 /* Avoid linking error on devm_hwmon_device_register_with_groups, I
194 * guess linux/hwmon.h is missing proper stubs. */ 194 * guess linux/hwmon.h is missing proper stubs. */
195 if (!config_enabled(CONFIG_HWMON)) 195 if (!IS_REACHABLE(CONFIG_HWMON))
196 return 0; 196 return 0;
197 197
198 hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev, 198 hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev,
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index b29a86a26c13..9852c5d51139 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -44,7 +44,7 @@ static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
44 complete(&ar->offchan_tx_completed); 44 complete(&ar->offchan_tx_completed);
45 ar->offchan_tx_skb = NULL; /* just for sanity */ 45 ar->offchan_tx_skb = NULL; /* just for sanity */
46 46
47 ath10k_dbg(ar, ATH10K_DBG_HTT, "completed offchannel skb %p\n", skb); 47 ath10k_dbg(ar, ATH10K_DBG_HTT, "completed offchannel skb %pK\n", skb);
48out: 48out:
49 spin_unlock_bh(&ar->data_lock); 49 spin_unlock_bh(&ar->data_lock);
50} 50}
@@ -119,8 +119,6 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
119 ieee80211_tx_status(htt->ar->hw, msdu); 119 ieee80211_tx_status(htt->ar->hw, msdu);
120 /* we do not own the msdu anymore */ 120 /* we do not own the msdu anymore */
121 121
122 ath10k_mac_tx_push_pending(ar);
123
124 return 0; 122 return 0;
125} 123}
126 124
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 64ebd304f907..c9a8bb1186f2 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -51,6 +51,8 @@ struct wmi_ops {
51 struct wmi_roam_ev_arg *arg); 51 struct wmi_roam_ev_arg *arg);
52 int (*pull_wow_event)(struct ath10k *ar, struct sk_buff *skb, 52 int (*pull_wow_event)(struct ath10k *ar, struct sk_buff *skb,
53 struct wmi_wow_ev_arg *arg); 53 struct wmi_wow_ev_arg *arg);
54 int (*pull_echo_ev)(struct ath10k *ar, struct sk_buff *skb,
55 struct wmi_echo_ev_arg *arg);
54 enum wmi_txbf_conf (*get_txbf_conf_scheme)(struct ath10k *ar); 56 enum wmi_txbf_conf (*get_txbf_conf_scheme)(struct ath10k *ar);
55 57
56 struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt); 58 struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt);
@@ -123,7 +125,7 @@ struct wmi_ops {
123 enum wmi_force_fw_hang_type type, 125 enum wmi_force_fw_hang_type type,
124 u32 delay_ms); 126 u32 delay_ms);
125 struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb); 127 struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb);
126 struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u32 module_enable, 128 struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u64 module_enable,
127 u32 log_level); 129 u32 log_level);
128 struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter); 130 struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter);
129 struct sk_buff *(*gen_pktlog_disable)(struct ath10k *ar); 131 struct sk_buff *(*gen_pktlog_disable)(struct ath10k *ar);
@@ -194,6 +196,7 @@ struct wmi_ops {
194 struct sk_buff *(*gen_pdev_bss_chan_info_req) 196 struct sk_buff *(*gen_pdev_bss_chan_info_req)
195 (struct ath10k *ar, 197 (struct ath10k *ar,
196 enum wmi_bss_survey_req_type type); 198 enum wmi_bss_survey_req_type type);
199 struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
197}; 200};
198 201
199int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 202int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -349,6 +352,16 @@ ath10k_wmi_pull_wow_event(struct ath10k *ar, struct sk_buff *skb,
349 return ar->wmi.ops->pull_wow_event(ar, skb, arg); 352 return ar->wmi.ops->pull_wow_event(ar, skb, arg);
350} 353}
351 354
355static inline int
356ath10k_wmi_pull_echo_ev(struct ath10k *ar, struct sk_buff *skb,
357 struct wmi_echo_ev_arg *arg)
358{
359 if (!ar->wmi.ops->pull_echo_ev)
360 return -EOPNOTSUPP;
361
362 return ar->wmi.ops->pull_echo_ev(ar, skb, arg);
363}
364
352static inline enum wmi_txbf_conf 365static inline enum wmi_txbf_conf
353ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar) 366ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar)
354{ 367{
@@ -932,7 +945,7 @@ ath10k_wmi_force_fw_hang(struct ath10k *ar,
932} 945}
933 946
934static inline int 947static inline int
935ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable, u32 log_level) 948ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level)
936{ 949{
937 struct sk_buff *skb; 950 struct sk_buff *skb;
938 951
@@ -1382,4 +1395,20 @@ ath10k_wmi_pdev_bss_chan_info_request(struct ath10k *ar,
1382 wmi->cmd->pdev_bss_chan_info_request_cmdid); 1395 wmi->cmd->pdev_bss_chan_info_request_cmdid);
1383} 1396}
1384 1397
1398static inline int
1399ath10k_wmi_echo(struct ath10k *ar, u32 value)
1400{
1401 struct ath10k_wmi *wmi = &ar->wmi;
1402 struct sk_buff *skb;
1403
1404 if (!wmi->ops->gen_echo)
1405 return -EOPNOTSUPP;
1406
1407 skb = wmi->ops->gen_echo(ar, value);
1408 if (IS_ERR(skb))
1409 return PTR_ERR(skb);
1410
1411 return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid);
1412}
1413
1385#endif 1414#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index e09337ee7c96..e64f59300a7c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1223,6 +1223,33 @@ ath10k_wmi_tlv_op_pull_wow_ev(struct ath10k *ar, struct sk_buff *skb,
1223 return 0; 1223 return 0;
1224} 1224}
1225 1225
1226static int ath10k_wmi_tlv_op_pull_echo_ev(struct ath10k *ar,
1227 struct sk_buff *skb,
1228 struct wmi_echo_ev_arg *arg)
1229{
1230 const void **tb;
1231 const struct wmi_echo_event *ev;
1232 int ret;
1233
1234 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
1235 if (IS_ERR(tb)) {
1236 ret = PTR_ERR(tb);
1237 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
1238 return ret;
1239 }
1240
1241 ev = tb[WMI_TLV_TAG_STRUCT_ECHO_EVENT];
1242 if (!ev) {
1243 kfree(tb);
1244 return -EPROTO;
1245 }
1246
1247 arg->value = ev->value;
1248
1249 kfree(tb);
1250 return 0;
1251}
1252
1226static struct sk_buff * 1253static struct sk_buff *
1227ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt) 1254ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt)
1228{ 1255{
@@ -2441,7 +2468,7 @@ ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
2441} 2468}
2442 2469
2443static struct sk_buff * 2470static struct sk_buff *
2444ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable, 2471ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
2445 u32 log_level) { 2472 u32 log_level) {
2446 struct wmi_tlv_dbglog_cmd *cmd; 2473 struct wmi_tlv_dbglog_cmd *cmd;
2447 struct wmi_tlv *tlv; 2474 struct wmi_tlv *tlv;
@@ -3081,6 +3108,34 @@ ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable)
3081 return skb; 3108 return skb;
3082} 3109}
3083 3110
3111static struct sk_buff *
3112ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value)
3113{
3114 struct wmi_echo_cmd *cmd;
3115 struct wmi_tlv *tlv;
3116 struct sk_buff *skb;
3117 void *ptr;
3118 size_t len;
3119
3120 len = sizeof(*tlv) + sizeof(*cmd);
3121 skb = ath10k_wmi_alloc_skb(ar, len);
3122 if (!skb)
3123 return ERR_PTR(-ENOMEM);
3124
3125 ptr = (void *)skb->data;
3126 tlv = ptr;
3127 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ECHO_CMD);
3128 tlv->len = __cpu_to_le16(sizeof(*cmd));
3129 cmd = (void *)tlv->value;
3130 cmd->value = cpu_to_le32(value);
3131
3132 ptr += sizeof(*tlv);
3133 ptr += sizeof(*cmd);
3134
3135 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv echo value 0x%08x\n", value);
3136 return skb;
3137}
3138
3084/****************/ 3139/****************/
3085/* TLV mappings */ 3140/* TLV mappings */
3086/****************/ 3141/****************/
@@ -3429,6 +3484,7 @@ static const struct wmi_ops wmi_tlv_ops = {
3429 .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats, 3484 .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
3430 .pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev, 3485 .pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev,
3431 .pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev, 3486 .pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev,
3487 .pull_echo_ev = ath10k_wmi_tlv_op_pull_echo_ev,
3432 .get_txbf_conf_scheme = ath10k_wmi_tlv_txbf_conf_scheme, 3488 .get_txbf_conf_scheme = ath10k_wmi_tlv_txbf_conf_scheme,
3433 3489
3434 .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend, 3490 .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend,
@@ -3485,6 +3541,7 @@ static const struct wmi_ops wmi_tlv_ops = {
3485 .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, 3541 .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs,
3486 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 3542 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
3487 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, 3543 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
3544 .gen_echo = ath10k_wmi_tlv_op_gen_echo,
3488}; 3545};
3489 3546
3490static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { 3547static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index d2462886b75c..38993d72f5e6 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -29,6 +29,9 @@
29#include "p2p.h" 29#include "p2p.h"
30#include "hw.h" 30#include "hw.h"
31 31
32#define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
33#define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
34
32/* MAIN WMI cmd track */ 35/* MAIN WMI cmd track */
33static struct wmi_cmd_map wmi_cmd_map = { 36static struct wmi_cmd_map wmi_cmd_map = {
34 .init_cmdid = WMI_INIT_CMDID, 37 .init_cmdid = WMI_INIT_CMDID,
@@ -1874,7 +1877,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
1874 ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr)); 1877 ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr));
1875 memcpy(cmd->buf, msdu->data, msdu->len); 1878 memcpy(cmd->buf, msdu->data, msdu->len);
1876 1879
1877 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", 1880 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %pK len %d ftype %02x stype %02x\n",
1878 msdu, skb->len, fc & IEEE80211_FCTL_FTYPE, 1881 msdu, skb->len, fc & IEEE80211_FCTL_FTYPE,
1879 fc & IEEE80211_FCTL_STYPE); 1882 fc & IEEE80211_FCTL_STYPE);
1880 trace_ath10k_tx_hdr(ar, skb->data, skb->len); 1883 trace_ath10k_tx_hdr(ar, skb->data, skb->len);
@@ -2240,6 +2243,29 @@ static int ath10k_wmi_10_4_op_pull_mgmt_rx_ev(struct ath10k *ar,
2240 return 0; 2243 return 0;
2241} 2244}
2242 2245
2246static bool ath10k_wmi_rx_is_decrypted(struct ath10k *ar,
2247 struct ieee80211_hdr *hdr)
2248{
2249 if (!ieee80211_has_protected(hdr->frame_control))
2250 return false;
2251
2252 /* FW delivers WEP Shared Auth frame with Protected Bit set and
2253 * encrypted payload. However in case of PMF it delivers decrypted
2254 * frames with Protected Bit set.
2255 */
2256 if (ieee80211_is_auth(hdr->frame_control))
2257 return false;
2258
2259 /* qca99x0 based FW delivers broadcast or multicast management frames
2260 * (ex: group privacy action frames in mesh) as encrypted payload.
2261 */
2262 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) &&
2263 ar->hw_params.sw_decrypt_mcast_mgmt)
2264 return false;
2265
2266 return true;
2267}
2268
2243int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) 2269int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
2244{ 2270{
2245 struct wmi_mgmt_rx_ev_arg arg = {}; 2271 struct wmi_mgmt_rx_ev_arg arg = {};
@@ -2326,11 +2352,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
2326 2352
2327 ath10k_wmi_handle_wep_reauth(ar, skb, status); 2353 ath10k_wmi_handle_wep_reauth(ar, skb, status);
2328 2354
2329 /* FW delivers WEP Shared Auth frame with Protected Bit set and 2355 if (ath10k_wmi_rx_is_decrypted(ar, hdr)) {
2330 * encrypted payload. However in case of PMF it delivers decrypted
2331 * frames with Protected Bit set. */
2332 if (ieee80211_has_protected(hdr->frame_control) &&
2333 !ieee80211_is_auth(hdr->frame_control)) {
2334 status->flag |= RX_FLAG_DECRYPTED; 2356 status->flag |= RX_FLAG_DECRYPTED;
2335 2357
2336 if (!ieee80211_is_action(hdr->frame_control) && 2358 if (!ieee80211_is_action(hdr->frame_control) &&
@@ -2347,7 +2369,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
2347 ath10k_mac_handle_beacon(ar, skb); 2369 ath10k_mac_handle_beacon(ar, skb);
2348 2370
2349 ath10k_dbg(ar, ATH10K_DBG_MGMT, 2371 ath10k_dbg(ar, ATH10K_DBG_MGMT,
2350 "event mgmt rx skb %p len %d ftype %02x stype %02x\n", 2372 "event mgmt rx skb %pK len %d ftype %02x stype %02x\n",
2351 skb, skb->len, 2373 skb, skb->len,
2352 fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); 2374 fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE);
2353 2375
@@ -2495,7 +2517,21 @@ exit:
2495 2517
2496void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) 2518void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
2497{ 2519{
2498 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); 2520 struct wmi_echo_ev_arg arg = {};
2521 int ret;
2522
2523 ret = ath10k_wmi_pull_echo_ev(ar, skb, &arg);
2524 if (ret) {
2525 ath10k_warn(ar, "failed to parse echo: %d\n", ret);
2526 return;
2527 }
2528
2529 ath10k_dbg(ar, ATH10K_DBG_WMI,
2530 "wmi event echo value 0x%08x\n",
2531 le32_to_cpu(arg.value));
2532
2533 if (le32_to_cpu(arg.value) == ATH10K_WMI_BARRIER_ECHO_ID)
2534 complete(&ar->wmi.barrier);
2499} 2535}
2500 2536
2501int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) 2537int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
@@ -3527,7 +3563,6 @@ void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
3527 ath10k_warn(ar, "failed to map beacon: %d\n", 3563 ath10k_warn(ar, "failed to map beacon: %d\n",
3528 ret); 3564 ret);
3529 dev_kfree_skb_any(bcn); 3565 dev_kfree_skb_any(bcn);
3530 ret = -EIO;
3531 goto skip; 3566 goto skip;
3532 } 3567 }
3533 3568
@@ -4792,6 +4827,17 @@ static int ath10k_wmi_op_pull_roam_ev(struct ath10k *ar, struct sk_buff *skb,
4792 return 0; 4827 return 0;
4793} 4828}
4794 4829
4830static int ath10k_wmi_op_pull_echo_ev(struct ath10k *ar,
4831 struct sk_buff *skb,
4832 struct wmi_echo_ev_arg *arg)
4833{
4834 struct wmi_echo_event *ev = (void *)skb->data;
4835
4836 arg->value = ev->value;
4837
4838 return 0;
4839}
4840
4795int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) 4841int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
4796{ 4842{
4797 struct wmi_rdy_ev_arg arg = {}; 4843 struct wmi_rdy_ev_arg arg = {};
@@ -5124,6 +5170,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
5124{ 5170{
5125 struct wmi_cmd_hdr *cmd_hdr; 5171 struct wmi_cmd_hdr *cmd_hdr;
5126 enum wmi_10_2_event_id id; 5172 enum wmi_10_2_event_id id;
5173 bool consumed;
5127 5174
5128 cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 5175 cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
5129 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 5176 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -5133,6 +5180,18 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
5133 5180
5134 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 5181 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
5135 5182
5183 consumed = ath10k_tm_event_wmi(ar, id, skb);
5184
5185 /* Ready event must be handled normally also in UTF mode so that we
5186 * know the UTF firmware has booted, others we are just bypass WMI
5187 * events to testmode.
5188 */
5189 if (consumed && id != WMI_10_2_READY_EVENTID) {
5190 ath10k_dbg(ar, ATH10K_DBG_WMI,
5191 "wmi testmode consumed 0x%x\n", id);
5192 goto out;
5193 }
5194
5136 switch (id) { 5195 switch (id) {
5137 case WMI_10_2_MGMT_RX_EVENTID: 5196 case WMI_10_2_MGMT_RX_EVENTID:
5138 ath10k_wmi_event_mgmt_rx(ar, skb); 5197 ath10k_wmi_event_mgmt_rx(ar, skb);
@@ -5248,6 +5307,7 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
5248{ 5307{
5249 struct wmi_cmd_hdr *cmd_hdr; 5308 struct wmi_cmd_hdr *cmd_hdr;
5250 enum wmi_10_4_event_id id; 5309 enum wmi_10_4_event_id id;
5310 bool consumed;
5251 5311
5252 cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 5312 cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
5253 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 5313 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -5257,6 +5317,18 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
5257 5317
5258 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 5318 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
5259 5319
5320 consumed = ath10k_tm_event_wmi(ar, id, skb);
5321
5322 /* Ready event must be handled normally also in UTF mode so that we
5323 * know the UTF firmware has booted, others we are just bypass WMI
5324 * events to testmode.
5325 */
5326 if (consumed && id != WMI_10_4_READY_EVENTID) {
5327 ath10k_dbg(ar, ATH10K_DBG_WMI,
5328 "wmi testmode consumed 0x%x\n", id);
5329 goto out;
5330 }
5331
5260 switch (id) { 5332 switch (id) {
5261 case WMI_10_4_MGMT_RX_EVENTID: 5333 case WMI_10_4_MGMT_RX_EVENTID:
5262 ath10k_wmi_event_mgmt_rx(ar, skb); 5334 ath10k_wmi_event_mgmt_rx(ar, skb);
@@ -5306,6 +5378,7 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
5306 break; 5378 break;
5307 case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: 5379 case WMI_10_4_WOW_WAKEUP_HOST_EVENTID:
5308 case WMI_10_4_PEER_RATECODE_LIST_EVENTID: 5380 case WMI_10_4_PEER_RATECODE_LIST_EVENTID:
5381 case WMI_10_4_WDS_PEER_EVENTID:
5309 ath10k_dbg(ar, ATH10K_DBG_WMI, 5382 ath10k_dbg(ar, ATH10K_DBG_WMI,
5310 "received event id %d not implemented\n", id); 5383 "received event id %d not implemented\n", id);
5311 break; 5384 break;
@@ -6863,7 +6936,7 @@ ath10k_wmi_op_gen_force_fw_hang(struct ath10k *ar,
6863} 6936}
6864 6937
6865static struct sk_buff * 6938static struct sk_buff *
6866ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable, 6939ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
6867 u32 log_level) 6940 u32 log_level)
6868{ 6941{
6869 struct wmi_dbglog_cfg_cmd *cmd; 6942 struct wmi_dbglog_cfg_cmd *cmd;
@@ -6901,6 +6974,44 @@ ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable,
6901} 6974}
6902 6975
6903static struct sk_buff * 6976static struct sk_buff *
6977ath10k_wmi_10_4_op_gen_dbglog_cfg(struct ath10k *ar, u64 module_enable,
6978 u32 log_level)
6979{
6980 struct wmi_10_4_dbglog_cfg_cmd *cmd;
6981 struct sk_buff *skb;
6982 u32 cfg;
6983
6984 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
6985 if (!skb)
6986 return ERR_PTR(-ENOMEM);
6987
6988 cmd = (struct wmi_10_4_dbglog_cfg_cmd *)skb->data;
6989
6990 if (module_enable) {
6991 cfg = SM(log_level,
6992 ATH10K_DBGLOG_CFG_LOG_LVL);
6993 } else {
6994 /* set back defaults, all modules with WARN level */
6995 cfg = SM(ATH10K_DBGLOG_LEVEL_WARN,
6996 ATH10K_DBGLOG_CFG_LOG_LVL);
6997 module_enable = ~0;
6998 }
6999
7000 cmd->module_enable = __cpu_to_le64(module_enable);
7001 cmd->module_valid = __cpu_to_le64(~0);
7002 cmd->config_enable = __cpu_to_le32(cfg);
7003 cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK);
7004
7005 ath10k_dbg(ar, ATH10K_DBG_WMI,
7006 "wmi dbglog cfg modules 0x%016llx 0x%016llx config %08x %08x\n",
7007 __le64_to_cpu(cmd->module_enable),
7008 __le64_to_cpu(cmd->module_valid),
7009 __le32_to_cpu(cmd->config_enable),
7010 __le32_to_cpu(cmd->config_valid));
7011 return skb;
7012}
7013
7014static struct sk_buff *
6904ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap) 7015ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap)
6905{ 7016{
6906 struct wmi_pdev_pktlog_enable_cmd *cmd; 7017 struct wmi_pdev_pktlog_enable_cmd *cmd;
@@ -7649,6 +7760,48 @@ ath10k_wmi_10_4_ext_resource_config(struct ath10k *ar,
7649 return skb; 7760 return skb;
7650} 7761}
7651 7762
7763static struct sk_buff *
7764ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value)
7765{
7766 struct wmi_echo_cmd *cmd;
7767 struct sk_buff *skb;
7768
7769 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
7770 if (!skb)
7771 return ERR_PTR(-ENOMEM);
7772
7773 cmd = (struct wmi_echo_cmd *)skb->data;
7774 cmd->value = cpu_to_le32(value);
7775
7776 ath10k_dbg(ar, ATH10K_DBG_WMI,
7777 "wmi echo value 0x%08x\n", value);
7778 return skb;
7779}
7780
7781int
7782ath10k_wmi_barrier(struct ath10k *ar)
7783{
7784 int ret;
7785 int time_left;
7786
7787 spin_lock_bh(&ar->data_lock);
7788 reinit_completion(&ar->wmi.barrier);
7789 spin_unlock_bh(&ar->data_lock);
7790
7791 ret = ath10k_wmi_echo(ar, ATH10K_WMI_BARRIER_ECHO_ID);
7792 if (ret) {
7793 ath10k_warn(ar, "failed to submit wmi echo: %d\n", ret);
7794 return ret;
7795 }
7796
7797 time_left = wait_for_completion_timeout(&ar->wmi.barrier,
7798 ATH10K_WMI_BARRIER_TIMEOUT_HZ);
7799 if (!time_left)
7800 return -ETIMEDOUT;
7801
7802 return 0;
7803}
7804
7652static const struct wmi_ops wmi_ops = { 7805static const struct wmi_ops wmi_ops = {
7653 .rx = ath10k_wmi_op_rx, 7806 .rx = ath10k_wmi_op_rx,
7654 .map_svc = wmi_main_svc_map, 7807 .map_svc = wmi_main_svc_map,
@@ -7665,6 +7818,7 @@ static const struct wmi_ops wmi_ops = {
7665 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 7818 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
7666 .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats, 7819 .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats,
7667 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev, 7820 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
7821 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
7668 7822
7669 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 7823 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
7670 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 7824 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -7709,6 +7863,7 @@ static const struct wmi_ops wmi_ops = {
7709 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7863 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7710 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 7864 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
7711 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, 7865 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
7866 .gen_echo = ath10k_wmi_op_gen_echo,
7712 /* .gen_bcn_tmpl not implemented */ 7867 /* .gen_bcn_tmpl not implemented */
7713 /* .gen_prb_tmpl not implemented */ 7868 /* .gen_prb_tmpl not implemented */
7714 /* .gen_p2p_go_bcn_ie not implemented */ 7869 /* .gen_p2p_go_bcn_ie not implemented */
@@ -7738,6 +7893,7 @@ static const struct wmi_ops wmi_10_1_ops = {
7738 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 7893 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
7739 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 7894 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
7740 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev, 7895 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
7896 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
7741 7897
7742 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 7898 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
7743 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 7899 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -7777,6 +7933,7 @@ static const struct wmi_ops wmi_10_1_ops = {
7777 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7933 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7778 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, 7934 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
7779 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, 7935 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
7936 .gen_echo = ath10k_wmi_op_gen_echo,
7780 /* .gen_bcn_tmpl not implemented */ 7937 /* .gen_bcn_tmpl not implemented */
7781 /* .gen_prb_tmpl not implemented */ 7938 /* .gen_prb_tmpl not implemented */
7782 /* .gen_p2p_go_bcn_ie not implemented */ 7939 /* .gen_p2p_go_bcn_ie not implemented */
@@ -7796,6 +7953,7 @@ static const struct wmi_ops wmi_10_2_ops = {
7796 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, 7953 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
7797 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, 7954 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
7798 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, 7955 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
7956 .gen_echo = ath10k_wmi_op_gen_echo,
7799 7957
7800 .pull_scan = ath10k_wmi_op_pull_scan_ev, 7958 .pull_scan = ath10k_wmi_op_pull_scan_ev,
7801 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, 7959 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
@@ -7807,6 +7965,7 @@ static const struct wmi_ops wmi_10_2_ops = {
7807 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 7965 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
7808 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 7966 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
7809 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev, 7967 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
7968 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
7810 7969
7811 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 7970 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
7812 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 7971 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -7862,6 +8021,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
7862 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, 8021 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
7863 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, 8022 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
7864 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, 8023 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
8024 .gen_echo = ath10k_wmi_op_gen_echo,
7865 8025
7866 .pull_scan = ath10k_wmi_op_pull_scan_ev, 8026 .pull_scan = ath10k_wmi_op_pull_scan_ev,
7867 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, 8027 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
@@ -7873,6 +8033,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
7873 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 8033 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
7874 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 8034 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
7875 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev, 8035 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
8036 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
7876 8037
7877 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 8038 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
7878 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 8039 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -7968,7 +8129,7 @@ static const struct wmi_ops wmi_10_4_ops = {
7968 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, 8129 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
7969 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, 8130 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
7970 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, 8131 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
7971 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, 8132 .gen_dbglog_cfg = ath10k_wmi_10_4_op_gen_dbglog_cfg,
7972 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, 8133 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
7973 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, 8134 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
7974 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, 8135 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
@@ -7980,10 +8141,12 @@ static const struct wmi_ops wmi_10_4_ops = {
7980 .ext_resource_config = ath10k_wmi_10_4_ext_resource_config, 8141 .ext_resource_config = ath10k_wmi_10_4_ext_resource_config,
7981 8142
7982 /* shared with 10.2 */ 8143 /* shared with 10.2 */
8144 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
7983 .gen_request_stats = ath10k_wmi_op_gen_request_stats, 8145 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
7984 .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature, 8146 .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
7985 .get_vdev_subtype = ath10k_wmi_10_4_op_get_vdev_subtype, 8147 .get_vdev_subtype = ath10k_wmi_10_4_op_get_vdev_subtype,
7986 .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, 8148 .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
8149 .gen_echo = ath10k_wmi_op_gen_echo,
7987}; 8150};
7988 8151
7989int ath10k_wmi_attach(struct ath10k *ar) 8152int ath10k_wmi_attach(struct ath10k *ar)
@@ -8036,6 +8199,7 @@ int ath10k_wmi_attach(struct ath10k *ar)
8036 8199
8037 init_completion(&ar->wmi.service_ready); 8200 init_completion(&ar->wmi.service_ready);
8038 init_completion(&ar->wmi.unified_ready); 8201 init_completion(&ar->wmi.unified_ready);
8202 init_completion(&ar->wmi.barrier);
8039 8203
8040 INIT_WORK(&ar->svc_rdy_work, ath10k_wmi_event_service_ready_work); 8204 INIT_WORK(&ar->svc_rdy_work, ath10k_wmi_event_service_ready_work);
8041 8205
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 3ef468893b3f..48e04b92e231 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -180,6 +180,7 @@ enum wmi_service {
180 WMI_SERVICE_MESH_NON_11S, 180 WMI_SERVICE_MESH_NON_11S,
181 WMI_SERVICE_PEER_STATS, 181 WMI_SERVICE_PEER_STATS,
182 WMI_SERVICE_RESTRT_CHNL_SUPPORT, 182 WMI_SERVICE_RESTRT_CHNL_SUPPORT,
183 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
183 WMI_SERVICE_TX_MODE_PUSH_ONLY, 184 WMI_SERVICE_TX_MODE_PUSH_ONLY,
184 WMI_SERVICE_TX_MODE_PUSH_PULL, 185 WMI_SERVICE_TX_MODE_PUSH_PULL,
185 WMI_SERVICE_TX_MODE_DYNAMIC, 186 WMI_SERVICE_TX_MODE_DYNAMIC,
@@ -305,6 +306,7 @@ enum wmi_10_4_service {
305 WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT, 306 WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT,
306 WMI_10_4_SERVICE_PEER_STATS, 307 WMI_10_4_SERVICE_PEER_STATS,
307 WMI_10_4_SERVICE_MESH_11S, 308 WMI_10_4_SERVICE_MESH_11S,
309 WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
308 WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, 310 WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
309 WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, 311 WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
310 WMI_10_4_SERVICE_TX_MODE_DYNAMIC, 312 WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
@@ -402,6 +404,7 @@ static inline char *wmi_service_name(int service_id)
402 SVCSTR(WMI_SERVICE_MESH_NON_11S); 404 SVCSTR(WMI_SERVICE_MESH_NON_11S);
403 SVCSTR(WMI_SERVICE_PEER_STATS); 405 SVCSTR(WMI_SERVICE_PEER_STATS);
404 SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT); 406 SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT);
407 SVCSTR(WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT);
405 SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY); 408 SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY);
406 SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL); 409 SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL);
407 SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC); 410 SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC);
@@ -652,6 +655,8 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
652 WMI_SERVICE_PEER_STATS, len); 655 WMI_SERVICE_PEER_STATS, len);
653 SVCMAP(WMI_10_4_SERVICE_MESH_11S, 656 SVCMAP(WMI_10_4_SERVICE_MESH_11S,
654 WMI_SERVICE_MESH_11S, len); 657 WMI_SERVICE_MESH_11S, len);
658 SVCMAP(WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
659 WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, len);
655 SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY, 660 SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
656 WMI_SERVICE_TX_MODE_PUSH_ONLY, len); 661 WMI_SERVICE_TX_MODE_PUSH_ONLY, len);
657 SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_PULL, 662 SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
@@ -6169,6 +6174,20 @@ struct wmi_dbglog_cfg_cmd {
6169 __le32 config_valid; 6174 __le32 config_valid;
6170} __packed; 6175} __packed;
6171 6176
6177struct wmi_10_4_dbglog_cfg_cmd {
6178 /* bitmask to hold mod id config*/
6179 __le64 module_enable;
6180
6181 /* see ATH10K_DBGLOG_CFG_ */
6182 __le32 config_enable;
6183
6184 /* mask of module id bits to be changed */
6185 __le64 module_valid;
6186
6187 /* mask of config bits to be changed, see ATH10K_DBGLOG_CFG_ */
6188 __le32 config_valid;
6189} __packed;
6190
6172enum wmi_roam_reason { 6191enum wmi_roam_reason {
6173 WMI_ROAM_REASON_BETTER_AP = 1, 6192 WMI_ROAM_REASON_BETTER_AP = 1,
6174 WMI_ROAM_REASON_BEACON_MISS = 2, 6193 WMI_ROAM_REASON_BEACON_MISS = 2,
@@ -6296,6 +6315,10 @@ struct wmi_roam_ev_arg {
6296 __le32 rssi; 6315 __le32 rssi;
6297}; 6316};
6298 6317
6318struct wmi_echo_ev_arg {
6319 __le32 value;
6320};
6321
6299struct wmi_pdev_temperature_event { 6322struct wmi_pdev_temperature_event {
6300 /* temperature value in Celcius degree */ 6323 /* temperature value in Celcius degree */
6301 __le32 temperature; 6324 __le32 temperature;
@@ -6624,5 +6647,6 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
6624 char *buf); 6647 char *buf);
6625int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, 6648int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
6626 enum wmi_vdev_subtype subtype); 6649 enum wmi_vdev_subtype subtype);
6650int ath10k_wmi_barrier(struct ath10k *ar);
6627 6651
6628#endif /* _WMI_H_ */ 6652#endif /* _WMI_H_ */
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 72e2ec67768d..b7fe0af4cb24 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1449,14 +1449,14 @@ static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1449 return -EIO; 1449 return -EIO;
1450 1450
1451 if (test_bit(CONNECTED, &vif->flags)) { 1451 if (test_bit(CONNECTED, &vif->flags)) {
1452 ar->tx_pwr = 0; 1452 ar->tx_pwr = 255;
1453 1453
1454 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) { 1454 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1455 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n"); 1455 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1456 return -EIO; 1456 return -EIO;
1457 } 1457 }
1458 1458
1459 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0, 1459 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 255,
1460 5 * HZ); 1460 5 * HZ);
1461 1461
1462 if (signal_pending(current)) { 1462 if (signal_pending(current)) {
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index 18c070850a09..d1942537ea10 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -64,7 +64,7 @@ int ath6kl_hif_rw_comp_handler(void *context, int status)
64} 64}
65EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler); 65EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler);
66 66
67#define REG_DUMP_COUNT_AR6003 60 67#define REGISTER_DUMP_COUNT 60
68#define REGISTER_DUMP_LEN_MAX 60 68#define REGISTER_DUMP_LEN_MAX 60
69 69
70static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) 70static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
@@ -73,9 +73,6 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
73 u32 i, address, regdump_addr = 0; 73 u32 i, address, regdump_addr = 0;
74 int ret; 74 int ret;
75 75
76 if (ar->target_type != TARGET_TYPE_AR6003)
77 return;
78
79 /* the reg dump pointer is copied to the host interest area */ 76 /* the reg dump pointer is copied to the host interest area */
80 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state)); 77 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
81 address = TARG_VTOP(ar->target_type, address); 78 address = TARG_VTOP(ar->target_type, address);
@@ -95,7 +92,7 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
95 92
96 /* fetch register dump data */ 93 /* fetch register dump data */
97 ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)&regdump_val[0], 94 ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)&regdump_val[0],
98 REG_DUMP_COUNT_AR6003 * (sizeof(u32))); 95 REGISTER_DUMP_COUNT * (sizeof(u32)));
99 if (ret) { 96 if (ret) {
100 ath6kl_warn("failed to get register dump: %d\n", ret); 97 ath6kl_warn("failed to get register dump: %d\n", ret);
101 return; 98 return;
@@ -105,9 +102,9 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
105 ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version, 102 ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version,
106 ar->wiphy->fw_version); 103 ar->wiphy->fw_version);
107 104
108 BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); 105 BUILD_BUG_ON(REGISTER_DUMP_COUNT % 4);
109 106
110 for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) { 107 for (i = 0; i < REGISTER_DUMP_COUNT; i += 4) {
111 ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", 108 ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
112 i, 109 i,
113 le32_to_cpu(regdump_val[i]), 110 le32_to_cpu(regdump_val[i]),
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 1b271b99c49e..8eea8d22e72e 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -260,8 +260,8 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
260 int cur_bin; 260 int cur_bin;
261 int upper, lower, cur_vit_mask; 261 int upper, lower, cur_vit_mask;
262 int i; 262 int i;
263 int8_t mask_m[123]; 263 int8_t mask_m[123] = {0};
264 int8_t mask_p[123]; 264 int8_t mask_p[123] = {0};
265 int8_t mask_amt; 265 int8_t mask_amt;
266 int tmp_mask; 266 int tmp_mask;
267 static const int pilot_mask_reg[4] = { 267 static const int pilot_mask_reg[4] = {
@@ -274,9 +274,6 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
274 }; 274 };
275 static const int inc[4] = { 0, 100, 0, 0 }; 275 static const int inc[4] = { 0, 100, 0, 0 };
276 276
277 memset(&mask_m, 0, sizeof(int8_t) * 123);
278 memset(&mask_p, 0, sizeof(int8_t) * 123);
279
280 cur_bin = -6000; 277 cur_bin = -6000;
281 upper = bin + 100; 278 upper = bin + 100;
282 lower = bin - 100; 279 lower = bin - 100;
@@ -302,7 +299,7 @@ void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
302 upper = bin + 120; 299 upper = bin + 120;
303 lower = bin - 120; 300 lower = bin - 120;
304 301
305 for (i = 0; i < 123; i++) { 302 for (i = 0; i < ARRAY_SIZE(mask_m); i++) {
306 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { 303 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
307 /* workaround for gcc bug #37014 */ 304 /* workaround for gcc bug #37014 */
308 volatile int tmp_v = abs(cur_vit_mask - bin); 305 volatile int tmp_v = abs(cur_vit_mask - bin);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 5bd2cbaf582d..08607d7fdb56 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3252,7 +3252,8 @@ static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
3252 int i; 3252 int i;
3253 3253
3254 for (i = 0; i < mdata_size / 2; i++, data++) 3254 for (i = 0; i < mdata_size / 2; i++, data++)
3255 ath9k_hw_nvram_read(ah, i, data); 3255 if (!ath9k_hw_nvram_read(ah, i, data))
3256 return -EIO;
3256 3257
3257 return 0; 3258 return 0;
3258} 3259}
@@ -3282,7 +3283,8 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3282 if (ath9k_hw_use_flash(ah)) { 3283 if (ath9k_hw_use_flash(ah)) {
3283 u8 txrx; 3284 u8 txrx;
3284 3285
3285 ar9300_eeprom_restore_flash(ah, mptr, mdata_size); 3286 if (ar9300_eeprom_restore_flash(ah, mptr, mdata_size))
3287 return -EIO;
3286 3288
3287 /* check if eeprom contains valid data */ 3289 /* check if eeprom contains valid data */
3288 eep = (struct ar9300_eeprom *) mptr; 3290 eep = (struct ar9300_eeprom *) mptr;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 490f74d9ddf0..ddb28861e7fe 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -22,7 +22,7 @@
22 22
23#ifdef CONFIG_MAC80211_LEDS 23#ifdef CONFIG_MAC80211_LEDS
24 24
25void ath_fill_led_pin(struct ath_softc *sc) 25static void ath_fill_led_pin(struct ath_softc *sc)
26{ 26{
27 struct ath_hw *ah = sc->sc_ah; 27 struct ath_hw *ah = sc->sc_ah;
28 28
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d1d0c06d627c..14b13f07cd1f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2482,6 +2482,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2482 return -EINVAL; 2482 return -EINVAL;
2483 } 2483 }
2484 2484
2485 ath9k_gpio_cap_init(ah);
2486
2485 if (AR_SREV_9485(ah) || 2487 if (AR_SREV_9485(ah) ||
2486 AR_SREV_9285(ah) || 2488 AR_SREV_9285(ah) ||
2487 AR_SREV_9330(ah) || 2489 AR_SREV_9330(ah) ||
@@ -2531,8 +2533,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2531 else 2533 else
2532 pCap->hw_caps &= ~ATH9K_HW_CAP_HT; 2534 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
2533 2535
2534 ath9k_gpio_cap_init(ah);
2535
2536 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) 2536 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah))
2537 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX; 2537 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
2538 else 2538 else
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a394622c9022..e9f32b52fc8c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -718,9 +718,12 @@ static int ath9k_start(struct ieee80211_hw *hw)
718 if (!ath_complete_reset(sc, false)) 718 if (!ath_complete_reset(sc, false))
719 ah->reset_power_on = false; 719 ah->reset_power_on = false;
720 720
721 if (ah->led_pin >= 0) 721 if (ah->led_pin >= 0) {
722 ath9k_hw_set_gpio(ah, ah->led_pin, 722 ath9k_hw_set_gpio(ah, ah->led_pin,
723 (ah->config.led_active_high) ? 1 : 0); 723 (ah->config.led_active_high) ? 1 : 0);
724 ath9k_hw_gpio_request_out(ah, ah->led_pin, NULL,
725 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
726 }
724 727
725 /* 728 /*
726 * Reset key cache to sane defaults (all entries cleared) instead of 729 * Reset key cache to sane defaults (all entries cleared) instead of
@@ -864,9 +867,11 @@ static void ath9k_stop(struct ieee80211_hw *hw)
864 867
865 spin_lock_bh(&sc->sc_pcu_lock); 868 spin_lock_bh(&sc->sc_pcu_lock);
866 869
867 if (ah->led_pin >= 0) 870 if (ah->led_pin >= 0) {
868 ath9k_hw_set_gpio(ah, ah->led_pin, 871 ath9k_hw_set_gpio(ah, ah->led_pin,
869 (ah->config.led_active_high) ? 0 : 1); 872 (ah->config.led_active_high) ? 0 : 1);
873 ath9k_hw_gpio_request_in(ah, ah->led_pin, NULL);
874 }
870 875
871 ath_prepare_reset(sc); 876 ath_prepare_reset(sc);
872 877
@@ -919,7 +924,7 @@ static void ath9k_vif_iter_set_beacon(struct ath9k_vif_iter_data *iter_data,
919 } else { 924 } else {
920 if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP && 925 if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP &&
921 vif->type == NL80211_IFTYPE_AP) 926 vif->type == NL80211_IFTYPE_AP)
922 iter_data->primary_beacon_vif = vif; 927 iter_data->primary_beacon_vif = vif;
923 } 928 }
924 929
925 iter_data->beacons = true; 930 iter_data->beacons = true;
@@ -1154,6 +1159,7 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1154 bool changed = (iter_data.primary_sta != ctx->primary_sta); 1159 bool changed = (iter_data.primary_sta != ctx->primary_sta);
1155 1160
1156 if (iter_data.primary_sta) { 1161 if (iter_data.primary_sta) {
1162 iter_data.primary_beacon_vif = iter_data.primary_sta;
1157 iter_data.beacons = true; 1163 iter_data.beacons = true;
1158 ath9k_set_assoc_state(sc, iter_data.primary_sta, 1164 ath9k_set_assoc_state(sc, iter_data.primary_sta,
1159 changed); 1165 changed);
@@ -1563,13 +1569,13 @@ static int ath9k_sta_state(struct ieee80211_hw *hw,
1563 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1569 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1564 int ret = 0; 1570 int ret = 0;
1565 1571
1566 if (old_state == IEEE80211_STA_AUTH && 1572 if (old_state == IEEE80211_STA_NOTEXIST &&
1567 new_state == IEEE80211_STA_ASSOC) { 1573 new_state == IEEE80211_STA_NONE) {
1568 ret = ath9k_sta_add(hw, vif, sta); 1574 ret = ath9k_sta_add(hw, vif, sta);
1569 ath_dbg(common, CONFIG, 1575 ath_dbg(common, CONFIG,
1570 "Add station: %pM\n", sta->addr); 1576 "Add station: %pM\n", sta->addr);
1571 } else if (old_state == IEEE80211_STA_ASSOC && 1577 } else if (old_state == IEEE80211_STA_NONE &&
1572 new_state == IEEE80211_STA_AUTH) { 1578 new_state == IEEE80211_STA_NOTEXIST) {
1573 ret = ath9k_sta_remove(hw, vif, sta); 1579 ret = ath9k_sta_remove(hw, vif, sta);
1574 ath_dbg(common, CONFIG, 1580 ath_dbg(common, CONFIG,
1575 "Remove station: %pM\n", sta->addr); 1581 "Remove station: %pM\n", sta->addr);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 8ddd604bd00c..52bfbb988611 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -50,9 +50,11 @@ static u16 bits_per_symbol[][2] = {
50static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 50static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
51 struct ath_atx_tid *tid, struct sk_buff *skb); 51 struct ath_atx_tid *tid, struct sk_buff *skb);
52static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 52static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
53 int tx_flags, struct ath_txq *txq); 53 int tx_flags, struct ath_txq *txq,
54 struct ieee80211_sta *sta);
54static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 55static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
55 struct ath_txq *txq, struct list_head *bf_q, 56 struct ath_txq *txq, struct list_head *bf_q,
57 struct ieee80211_sta *sta,
56 struct ath_tx_status *ts, int txok); 58 struct ath_tx_status *ts, int txok);
57static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 59static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
58 struct list_head *head, bool internal); 60 struct list_head *head, bool internal);
@@ -77,6 +79,22 @@ enum {
77/* Aggregation logic */ 79/* Aggregation logic */
78/*********************/ 80/*********************/
79 81
82static void ath_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
83{
84 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
85 struct ieee80211_sta *sta = info->status.status_driver_data[0];
86
87 if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
88 ieee80211_tx_status(hw, skb);
89 return;
90 }
91
92 if (sta)
93 ieee80211_tx_status_noskb(hw, sta, info);
94
95 dev_kfree_skb(skb);
96}
97
80void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) 98void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
81 __acquires(&txq->axq_lock) 99 __acquires(&txq->axq_lock)
82{ 100{
@@ -92,6 +110,7 @@ void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
92void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) 110void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
93 __releases(&txq->axq_lock) 111 __releases(&txq->axq_lock)
94{ 112{
113 struct ieee80211_hw *hw = sc->hw;
95 struct sk_buff_head q; 114 struct sk_buff_head q;
96 struct sk_buff *skb; 115 struct sk_buff *skb;
97 116
@@ -100,7 +119,7 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
100 spin_unlock_bh(&txq->axq_lock); 119 spin_unlock_bh(&txq->axq_lock);
101 120
102 while ((skb = __skb_dequeue(&q))) 121 while ((skb = __skb_dequeue(&q)))
103 ieee80211_tx_status(sc->hw, skb); 122 ath_tx_status(hw, skb);
104} 123}
105 124
106static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq, 125static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
@@ -253,7 +272,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
253 } 272 }
254 273
255 list_add_tail(&bf->list, &bf_head); 274 list_add_tail(&bf->list, &bf_head);
256 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); 275 ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
257 } 276 }
258 277
259 if (sendbar) { 278 if (sendbar) {
@@ -318,12 +337,12 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
318 bf = fi->bf; 337 bf = fi->bf;
319 338
320 if (!bf) { 339 if (!bf) {
321 ath_tx_complete(sc, skb, ATH_TX_ERROR, txq); 340 ath_tx_complete(sc, skb, ATH_TX_ERROR, txq, NULL);
322 continue; 341 continue;
323 } 342 }
324 343
325 list_add_tail(&bf->list, &bf_head); 344 list_add_tail(&bf->list, &bf_head);
326 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); 345 ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
327 } 346 }
328} 347}
329 348
@@ -426,15 +445,14 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
426 445
427static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, 446static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
428 struct ath_buf *bf, struct list_head *bf_q, 447 struct ath_buf *bf, struct list_head *bf_q,
448 struct ieee80211_sta *sta,
449 struct ath_atx_tid *tid,
429 struct ath_tx_status *ts, int txok) 450 struct ath_tx_status *ts, int txok)
430{ 451{
431 struct ath_node *an = NULL; 452 struct ath_node *an = NULL;
432 struct sk_buff *skb; 453 struct sk_buff *skb;
433 struct ieee80211_sta *sta;
434 struct ieee80211_hw *hw = sc->hw;
435 struct ieee80211_hdr *hdr; 454 struct ieee80211_hdr *hdr;
436 struct ieee80211_tx_info *tx_info; 455 struct ieee80211_tx_info *tx_info;
437 struct ath_atx_tid *tid = NULL;
438 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; 456 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
439 struct list_head bf_head; 457 struct list_head bf_head;
440 struct sk_buff_head bf_pending; 458 struct sk_buff_head bf_pending;
@@ -460,12 +478,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
460 for (i = 0; i < ts->ts_rateindex; i++) 478 for (i = 0; i < ts->ts_rateindex; i++)
461 retries += rates[i].count; 479 retries += rates[i].count;
462 480
463 rcu_read_lock();
464
465 sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
466 if (!sta) { 481 if (!sta) {
467 rcu_read_unlock();
468
469 INIT_LIST_HEAD(&bf_head); 482 INIT_LIST_HEAD(&bf_head);
470 while (bf) { 483 while (bf) {
471 bf_next = bf->bf_next; 484 bf_next = bf->bf_next;
@@ -473,7 +486,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
473 if (!bf->bf_state.stale || bf_next != NULL) 486 if (!bf->bf_state.stale || bf_next != NULL)
474 list_move_tail(&bf->list, &bf_head); 487 list_move_tail(&bf->list, &bf_head);
475 488
476 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0); 489 ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, ts, 0);
477 490
478 bf = bf_next; 491 bf = bf_next;
479 } 492 }
@@ -481,7 +494,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
481 } 494 }
482 495
483 an = (struct ath_node *)sta->drv_priv; 496 an = (struct ath_node *)sta->drv_priv;
484 tid = ath_get_skb_tid(sc, an, skb);
485 seq_first = tid->seq_start; 497 seq_first = tid->seq_start;
486 isba = ts->ts_flags & ATH9K_TX_BA; 498 isba = ts->ts_flags & ATH9K_TX_BA;
487 499
@@ -583,7 +595,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
583 ts); 595 ts);
584 } 596 }
585 597
586 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 598 ath_tx_complete_buf(sc, bf, txq, &bf_head, sta, ts,
587 !txfail); 599 !txfail);
588 } else { 600 } else {
589 if (tx_info->flags & IEEE80211_TX_STATUS_EOSP) { 601 if (tx_info->flags & IEEE80211_TX_STATUS_EOSP) {
@@ -604,7 +616,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
604 ath_tx_update_baw(sc, tid, seqno); 616 ath_tx_update_baw(sc, tid, seqno);
605 617
606 ath_tx_complete_buf(sc, bf, txq, 618 ath_tx_complete_buf(sc, bf, txq,
607 &bf_head, ts, 0); 619 &bf_head, NULL, ts,
620 0);
608 bar_index = max_t(int, bar_index, 621 bar_index = max_t(int, bar_index,
609 ATH_BA_INDEX(seq_first, seqno)); 622 ATH_BA_INDEX(seq_first, seqno));
610 break; 623 break;
@@ -648,8 +661,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
648 ath_txq_lock(sc, txq); 661 ath_txq_lock(sc, txq);
649 } 662 }
650 663
651 rcu_read_unlock();
652
653 if (needreset) 664 if (needreset)
654 ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR); 665 ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR);
655} 666}
@@ -664,7 +675,11 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
664 struct ath_tx_status *ts, struct ath_buf *bf, 675 struct ath_tx_status *ts, struct ath_buf *bf,
665 struct list_head *bf_head) 676 struct list_head *bf_head)
666{ 677{
678 struct ieee80211_hw *hw = sc->hw;
667 struct ieee80211_tx_info *info; 679 struct ieee80211_tx_info *info;
680 struct ieee80211_sta *sta;
681 struct ieee80211_hdr *hdr;
682 struct ath_atx_tid *tid = NULL;
668 bool txok, flush; 683 bool txok, flush;
669 684
670 txok = !(ts->ts_status & ATH9K_TXERR_MASK); 685 txok = !(ts->ts_status & ATH9K_TXERR_MASK);
@@ -677,6 +692,16 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
677 692
678 ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, 693 ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc,
679 ts->ts_rateindex); 694 ts->ts_rateindex);
695
696 hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
697 sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
698 if (sta) {
699 struct ath_node *an = (struct ath_node *)sta->drv_priv;
700 tid = ath_get_skb_tid(sc, an, bf->bf_mpdu);
701 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
702 tid->clear_ps_filter = true;
703 }
704
680 if (!bf_isampdu(bf)) { 705 if (!bf_isampdu(bf)) {
681 if (!flush) { 706 if (!flush) {
682 info = IEEE80211_SKB_CB(bf->bf_mpdu); 707 info = IEEE80211_SKB_CB(bf->bf_mpdu);
@@ -685,9 +710,9 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
685 ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); 710 ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
686 ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts); 711 ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts);
687 } 712 }
688 ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); 713 ath_tx_complete_buf(sc, bf, txq, bf_head, sta, ts, txok);
689 } else 714 } else
690 ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok); 715 ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, tid, ts, txok);
691 716
692 if (!flush) 717 if (!flush)
693 ath_txq_schedule(sc, txq); 718 ath_txq_schedule(sc, txq);
@@ -923,7 +948,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
923 list_add(&bf->list, &bf_head); 948 list_add(&bf->list, &bf_head);
924 __skb_unlink(skb, *q); 949 __skb_unlink(skb, *q);
925 ath_tx_update_baw(sc, tid, seqno); 950 ath_tx_update_baw(sc, tid, seqno);
926 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); 951 ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
927 continue; 952 continue;
928 } 953 }
929 954
@@ -1832,6 +1857,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
1832 */ 1857 */
1833void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq) 1858void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq)
1834{ 1859{
1860 rcu_read_lock();
1835 ath_txq_lock(sc, txq); 1861 ath_txq_lock(sc, txq);
1836 1862
1837 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 1863 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
@@ -1850,6 +1876,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq)
1850 ath_drain_txq_list(sc, txq, &txq->axq_q); 1876 ath_drain_txq_list(sc, txq, &txq->axq_q);
1851 1877
1852 ath_txq_unlock_complete(sc, txq); 1878 ath_txq_unlock_complete(sc, txq);
1879 rcu_read_unlock();
1853} 1880}
1854 1881
1855bool ath_drain_all_txq(struct ath_softc *sc) 1882bool ath_drain_all_txq(struct ath_softc *sc)
@@ -2472,7 +2499,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2472/*****************/ 2499/*****************/
2473 2500
2474static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 2501static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
2475 int tx_flags, struct ath_txq *txq) 2502 int tx_flags, struct ath_txq *txq,
2503 struct ieee80211_sta *sta)
2476{ 2504{
2477 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 2505 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
2478 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 2506 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -2492,15 +2520,17 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
2492 tx_info->flags |= IEEE80211_TX_STAT_ACK; 2520 tx_info->flags |= IEEE80211_TX_STAT_ACK;
2493 } 2521 }
2494 2522
2495 padpos = ieee80211_hdrlen(hdr->frame_control); 2523 if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
2496 padsize = padpos & 3; 2524 padpos = ieee80211_hdrlen(hdr->frame_control);
2497 if (padsize && skb->len>padpos+padsize) { 2525 padsize = padpos & 3;
2498 /* 2526 if (padsize && skb->len>padpos+padsize) {
2499 * Remove MAC header padding before giving the frame back to 2527 /*
2500 * mac80211. 2528 * Remove MAC header padding before giving the frame back to
2501 */ 2529 * mac80211.
2502 memmove(skb->data + padsize, skb->data, padpos); 2530 */
2503 skb_pull(skb, padsize); 2531 memmove(skb->data + padsize, skb->data, padpos);
2532 skb_pull(skb, padsize);
2533 }
2504 } 2534 }
2505 2535
2506 spin_lock_irqsave(&sc->sc_pm_lock, flags); 2536 spin_lock_irqsave(&sc->sc_pm_lock, flags);
@@ -2515,12 +2545,14 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
2515 } 2545 }
2516 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 2546 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
2517 2547
2518 __skb_queue_tail(&txq->complete_q, skb);
2519 ath_txq_skb_done(sc, txq, skb); 2548 ath_txq_skb_done(sc, txq, skb);
2549 tx_info->status.status_driver_data[0] = sta;
2550 __skb_queue_tail(&txq->complete_q, skb);
2520} 2551}
2521 2552
2522static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 2553static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
2523 struct ath_txq *txq, struct list_head *bf_q, 2554 struct ath_txq *txq, struct list_head *bf_q,
2555 struct ieee80211_sta *sta,
2524 struct ath_tx_status *ts, int txok) 2556 struct ath_tx_status *ts, int txok)
2525{ 2557{
2526 struct sk_buff *skb = bf->bf_mpdu; 2558 struct sk_buff *skb = bf->bf_mpdu;
@@ -2548,7 +2580,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
2548 complete(&sc->paprd_complete); 2580 complete(&sc->paprd_complete);
2549 } else { 2581 } else {
2550 ath_debug_stat_tx(sc, bf, ts, txq, tx_flags); 2582 ath_debug_stat_tx(sc, bf, ts, txq, tx_flags);
2551 ath_tx_complete(sc, skb, tx_flags, txq); 2583 ath_tx_complete(sc, skb, tx_flags, txq, sta);
2552 } 2584 }
2553skip_tx_complete: 2585skip_tx_complete:
2554 /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't 2586 /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
@@ -2700,10 +2732,12 @@ void ath_tx_tasklet(struct ath_softc *sc)
2700 u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs; 2732 u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs;
2701 int i; 2733 int i;
2702 2734
2735 rcu_read_lock();
2703 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 2736 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2704 if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) 2737 if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
2705 ath_tx_processq(sc, &sc->tx.txq[i]); 2738 ath_tx_processq(sc, &sc->tx.txq[i]);
2706 } 2739 }
2740 rcu_read_unlock();
2707} 2741}
2708 2742
2709void ath_tx_edma_tasklet(struct ath_softc *sc) 2743void ath_tx_edma_tasklet(struct ath_softc *sc)
@@ -2717,6 +2751,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2717 struct list_head *fifo_list; 2751 struct list_head *fifo_list;
2718 int status; 2752 int status;
2719 2753
2754 rcu_read_lock();
2720 for (;;) { 2755 for (;;) {
2721 if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) 2756 if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
2722 break; 2757 break;
@@ -2787,6 +2822,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2787 ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); 2822 ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head);
2788 ath_txq_unlock_complete(sc, txq); 2823 ath_txq_unlock_complete(sc, txq);
2789 } 2824 }
2825 rcu_read_unlock();
2790} 2826}
2791 2827
2792/*****************/ 2828/*****************/
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 76842e6ca38e..99ab20334d21 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -670,6 +670,7 @@ int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd,
670 ar->readlen = outlen; 670 ar->readlen = outlen;
671 spin_unlock_bh(&ar->cmd_lock); 671 spin_unlock_bh(&ar->cmd_lock);
672 672
673 reinit_completion(&ar->cmd_wait);
673 err = __carl9170_exec_cmd(ar, &ar->cmd, false); 674 err = __carl9170_exec_cmd(ar, &ar->cmd, false);
674 675
675 if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) { 676 if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) {
@@ -778,10 +779,7 @@ void carl9170_usb_stop(struct ar9170 *ar)
778 spin_lock_bh(&ar->cmd_lock); 779 spin_lock_bh(&ar->cmd_lock);
779 ar->readlen = 0; 780 ar->readlen = 0;
780 spin_unlock_bh(&ar->cmd_lock); 781 spin_unlock_bh(&ar->cmd_lock);
781 complete_all(&ar->cmd_wait); 782 complete(&ar->cmd_wait);
782
783 /* This is required to prevent an early completion on _start */
784 reinit_completion(&ar->cmd_wait);
785 783
786 /* 784 /*
787 * Note: 785 * Note:
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index f0e1175fb76a..d117240d9a73 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -354,10 +354,13 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
354 wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n", 354 wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
355 __func__, wdev, wdev->iftype); 355 __func__, wdev, wdev->iftype);
356 356
357 mutex_lock(&wil->p2p_wdev_mutex);
357 if (wil->scan_request) { 358 if (wil->scan_request) {
358 wil_err(wil, "Already scanning\n"); 359 wil_err(wil, "Already scanning\n");
360 mutex_unlock(&wil->p2p_wdev_mutex);
359 return -EAGAIN; 361 return -EAGAIN;
360 } 362 }
363 mutex_unlock(&wil->p2p_wdev_mutex);
361 364
362 /* check we are client side */ 365 /* check we are client side */
363 switch (wdev->iftype) { 366 switch (wdev->iftype) {
@@ -760,14 +763,11 @@ static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
760 return rc; 763 return rc;
761} 764}
762 765
763static struct wil_tid_crypto_rx_single * 766static struct wil_sta_info *
764wil_find_crypto_ctx(struct wil6210_priv *wil, u8 key_index, 767wil_find_sta_by_key_usage(struct wil6210_priv *wil,
765 enum wmi_key_usage key_usage, const u8 *mac_addr) 768 enum wmi_key_usage key_usage, const u8 *mac_addr)
766{ 769{
767 int cid = -EINVAL; 770 int cid = -EINVAL;
768 int tid = 0;
769 struct wil_sta_info *s;
770 struct wil_tid_crypto_rx *c;
771 771
772 if (key_usage == WMI_KEY_USE_TX_GROUP) 772 if (key_usage == WMI_KEY_USE_TX_GROUP)
773 return NULL; /* not needed */ 773 return NULL; /* not needed */
@@ -778,18 +778,72 @@ wil_find_crypto_ctx(struct wil6210_priv *wil, u8 key_index,
778 else if (key_usage == WMI_KEY_USE_RX_GROUP) 778 else if (key_usage == WMI_KEY_USE_RX_GROUP)
779 cid = wil_find_cid_by_idx(wil, 0); 779 cid = wil_find_cid_by_idx(wil, 0);
780 if (cid < 0) { 780 if (cid < 0) {
781 wil_err(wil, "No CID for %pM %s[%d]\n", mac_addr, 781 wil_err(wil, "No CID for %pM %s\n", mac_addr,
782 key_usage_str[key_usage], key_index); 782 key_usage_str[key_usage]);
783 return ERR_PTR(cid); 783 return ERR_PTR(cid);
784 } 784 }
785 785
786 s = &wil->sta[cid]; 786 return &wil->sta[cid];
787 if (key_usage == WMI_KEY_USE_PAIRWISE) 787}
788 c = &s->tid_crypto_rx[tid]; 788
789 else 789static void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage,
790 c = &s->group_crypto_rx; 790 struct wil_sta_info *cs,
791 struct key_params *params)
792{
793 struct wil_tid_crypto_rx_single *cc;
794 int tid;
795
796 if (!cs)
797 return;
791 798
792 return &c->key_id[key_index]; 799 switch (key_usage) {
800 case WMI_KEY_USE_PAIRWISE:
801 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
802 cc = &cs->tid_crypto_rx[tid].key_id[key_index];
803 if (params->seq)
804 memcpy(cc->pn, params->seq,
805 IEEE80211_GCMP_PN_LEN);
806 else
807 memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
808 cc->key_set = true;
809 }
810 break;
811 case WMI_KEY_USE_RX_GROUP:
812 cc = &cs->group_crypto_rx.key_id[key_index];
813 if (params->seq)
814 memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN);
815 else
816 memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
817 cc->key_set = true;
818 break;
819 default:
820 break;
821 }
822}
823
824static void wil_del_rx_key(u8 key_index, enum wmi_key_usage key_usage,
825 struct wil_sta_info *cs)
826{
827 struct wil_tid_crypto_rx_single *cc;
828 int tid;
829
830 if (!cs)
831 return;
832
833 switch (key_usage) {
834 case WMI_KEY_USE_PAIRWISE:
835 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
836 cc = &cs->tid_crypto_rx[tid].key_id[key_index];
837 cc->key_set = false;
838 }
839 break;
840 case WMI_KEY_USE_RX_GROUP:
841 cc = &cs->group_crypto_rx.key_id[key_index];
842 cc->key_set = false;
843 break;
844 default:
845 break;
846 }
793} 847}
794 848
795static int wil_cfg80211_add_key(struct wiphy *wiphy, 849static int wil_cfg80211_add_key(struct wiphy *wiphy,
@@ -801,24 +855,26 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
801 int rc; 855 int rc;
802 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 856 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
803 enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise); 857 enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
804 struct wil_tid_crypto_rx_single *cc = wil_find_crypto_ctx(wil, 858 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
805 key_index, 859 mac_addr);
806 key_usage, 860
807 mac_addr); 861 if (!params) {
862 wil_err(wil, "NULL params\n");
863 return -EINVAL;
864 }
808 865
809 wil_dbg_misc(wil, "%s(%pM %s[%d] PN %*phN)\n", __func__, 866 wil_dbg_misc(wil, "%s(%pM %s[%d] PN %*phN)\n", __func__,
810 mac_addr, key_usage_str[key_usage], key_index, 867 mac_addr, key_usage_str[key_usage], key_index,
811 params->seq_len, params->seq); 868 params->seq_len, params->seq);
812 869
813 if (IS_ERR(cc)) { 870 if (IS_ERR(cs)) {
814 wil_err(wil, "Not connected, %s(%pM %s[%d] PN %*phN)\n", 871 wil_err(wil, "Not connected, %s(%pM %s[%d] PN %*phN)\n",
815 __func__, mac_addr, key_usage_str[key_usage], key_index, 872 __func__, mac_addr, key_usage_str[key_usage], key_index,
816 params->seq_len, params->seq); 873 params->seq_len, params->seq);
817 return -EINVAL; 874 return -EINVAL;
818 } 875 }
819 876
820 if (cc) 877 wil_del_rx_key(key_index, key_usage, cs);
821 cc->key_set = false;
822 878
823 if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) { 879 if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
824 wil_err(wil, 880 wil_err(wil,
@@ -831,13 +887,8 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
831 887
832 rc = wmi_add_cipher_key(wil, key_index, mac_addr, params->key_len, 888 rc = wmi_add_cipher_key(wil, key_index, mac_addr, params->key_len,
833 params->key, key_usage); 889 params->key, key_usage);
834 if ((rc == 0) && cc) { 890 if (!rc)
835 if (params->seq) 891 wil_set_crypto_rx(key_index, key_usage, cs, params);
836 memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN);
837 else
838 memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
839 cc->key_set = true;
840 }
841 892
842 return rc; 893 return rc;
843} 894}
@@ -849,20 +900,18 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
849{ 900{
850 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 901 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
851 enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise); 902 enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
852 struct wil_tid_crypto_rx_single *cc = wil_find_crypto_ctx(wil, 903 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
853 key_index, 904 mac_addr);
854 key_usage,
855 mac_addr);
856 905
857 wil_dbg_misc(wil, "%s(%pM %s[%d])\n", __func__, mac_addr, 906 wil_dbg_misc(wil, "%s(%pM %s[%d])\n", __func__, mac_addr,
858 key_usage_str[key_usage], key_index); 907 key_usage_str[key_usage], key_index);
859 908
860 if (IS_ERR(cc)) 909 if (IS_ERR(cs))
861 wil_info(wil, "Not connected, %s(%pM %s[%d])\n", __func__, 910 wil_info(wil, "Not connected, %s(%pM %s[%d])\n", __func__,
862 mac_addr, key_usage_str[key_usage], key_index); 911 mac_addr, key_usage_str[key_usage], key_index);
863 912
864 if (!IS_ERR_OR_NULL(cc)) 913 if (!IS_ERR_OR_NULL(cs))
865 cc->key_set = false; 914 wil_del_rx_key(key_index, key_usage, cs);
866 915
867 return wmi_del_cipher_key(wil, key_index, mac_addr, key_usage); 916 return wmi_del_cipher_key(wil, key_index, mac_addr, key_usage);
868} 917}
@@ -1363,23 +1412,16 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
1363 struct wireless_dev *wdev) 1412 struct wireless_dev *wdev)
1364{ 1413{
1365 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1414 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1366 u8 started; 1415 struct wil_p2p_info *p2p = &wil->p2p;
1416
1417 if (!p2p->p2p_dev_started)
1418 return;
1367 1419
1368 wil_dbg_misc(wil, "%s: entered\n", __func__); 1420 wil_dbg_misc(wil, "%s: entered\n", __func__);
1369 mutex_lock(&wil->mutex); 1421 mutex_lock(&wil->mutex);
1370 started = wil_p2p_stop_discovery(wil); 1422 wil_p2p_stop_radio_operations(wil);
1371 if (started && wil->scan_request) { 1423 p2p->p2p_dev_started = 0;
1372 struct cfg80211_scan_info info = {
1373 .aborted = true,
1374 };
1375
1376 cfg80211_scan_done(wil->scan_request, &info);
1377 wil->scan_request = NULL;
1378 wil->radio_wdev = wil->wdev;
1379 }
1380 mutex_unlock(&wil->mutex); 1424 mutex_unlock(&wil->mutex);
1381
1382 wil->p2p.p2p_dev_started = 0;
1383} 1425}
1384 1426
1385static struct cfg80211_ops wil_cfg80211_ops = { 1427static struct cfg80211_ops wil_cfg80211_ops = {
@@ -1464,14 +1506,8 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev)
1464 set_wiphy_dev(wdev->wiphy, dev); 1506 set_wiphy_dev(wdev->wiphy, dev);
1465 wil_wiphy_init(wdev->wiphy); 1507 wil_wiphy_init(wdev->wiphy);
1466 1508
1467 rc = wiphy_register(wdev->wiphy);
1468 if (rc < 0)
1469 goto out_failed_reg;
1470
1471 return wdev; 1509 return wdev;
1472 1510
1473out_failed_reg:
1474 wiphy_free(wdev->wiphy);
1475out: 1511out:
1476 kfree(wdev); 1512 kfree(wdev);
1477 1513
@@ -1487,7 +1523,6 @@ void wil_wdev_free(struct wil6210_priv *wil)
1487 if (!wdev) 1523 if (!wdev)
1488 return; 1524 return;
1489 1525
1490 wiphy_unregister(wdev->wiphy);
1491 wiphy_free(wdev->wiphy); 1526 wiphy_free(wdev->wiphy);
1492 kfree(wdev); 1527 kfree(wdev);
1493} 1528}
@@ -1498,11 +1533,11 @@ void wil_p2p_wdev_free(struct wil6210_priv *wil)
1498 1533
1499 mutex_lock(&wil->p2p_wdev_mutex); 1534 mutex_lock(&wil->p2p_wdev_mutex);
1500 p2p_wdev = wil->p2p_wdev; 1535 p2p_wdev = wil->p2p_wdev;
1536 wil->p2p_wdev = NULL;
1537 wil->radio_wdev = wil_to_wdev(wil);
1538 mutex_unlock(&wil->p2p_wdev_mutex);
1501 if (p2p_wdev) { 1539 if (p2p_wdev) {
1502 wil->p2p_wdev = NULL;
1503 wil->radio_wdev = wil_to_wdev(wil);
1504 cfg80211_unregister_wdev(p2p_wdev); 1540 cfg80211_unregister_wdev(p2p_wdev);
1505 kfree(p2p_wdev); 1541 kfree(p2p_wdev);
1506 } 1542 }
1507 mutex_unlock(&wil->p2p_wdev_mutex);
1508} 1543}
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index a8098b406cc0..5e4058a4037b 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1553,6 +1553,56 @@ static const struct file_operations fops_led_blink_time = {
1553 .open = simple_open, 1553 .open = simple_open,
1554}; 1554};
1555 1555
1556/*---------FW capabilities------------*/
1557static int wil_fw_capabilities_debugfs_show(struct seq_file *s, void *data)
1558{
1559 struct wil6210_priv *wil = s->private;
1560
1561 seq_printf(s, "fw_capabilities : %*pb\n", WMI_FW_CAPABILITY_MAX,
1562 wil->fw_capabilities);
1563
1564 return 0;
1565}
1566
1567static int wil_fw_capabilities_seq_open(struct inode *inode, struct file *file)
1568{
1569 return single_open(file, wil_fw_capabilities_debugfs_show,
1570 inode->i_private);
1571}
1572
1573static const struct file_operations fops_fw_capabilities = {
1574 .open = wil_fw_capabilities_seq_open,
1575 .release = single_release,
1576 .read = seq_read,
1577 .llseek = seq_lseek,
1578};
1579
1580/*---------FW version------------*/
1581static int wil_fw_version_debugfs_show(struct seq_file *s, void *data)
1582{
1583 struct wil6210_priv *wil = s->private;
1584
1585 if (wil->fw_version[0])
1586 seq_printf(s, "%s\n", wil->fw_version);
1587 else
1588 seq_puts(s, "N/A\n");
1589
1590 return 0;
1591}
1592
1593static int wil_fw_version_seq_open(struct inode *inode, struct file *file)
1594{
1595 return single_open(file, wil_fw_version_debugfs_show,
1596 inode->i_private);
1597}
1598
1599static const struct file_operations fops_fw_version = {
1600 .open = wil_fw_version_seq_open,
1601 .release = single_release,
1602 .read = seq_read,
1603 .llseek = seq_lseek,
1604};
1605
1556/*----------------*/ 1606/*----------------*/
1557static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil, 1607static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
1558 struct dentry *dbg) 1608 struct dentry *dbg)
@@ -1603,6 +1653,8 @@ static const struct {
1603 {"recovery", S_IRUGO | S_IWUSR, &fops_recovery}, 1653 {"recovery", S_IRUGO | S_IWUSR, &fops_recovery},
1604 {"led_cfg", S_IRUGO | S_IWUSR, &fops_led_cfg}, 1654 {"led_cfg", S_IRUGO | S_IWUSR, &fops_led_cfg},
1605 {"led_blink_time", S_IRUGO | S_IWUSR, &fops_led_blink_time}, 1655 {"led_blink_time", S_IRUGO | S_IWUSR, &fops_led_blink_time},
1656 {"fw_capabilities", S_IRUGO, &fops_fw_capabilities},
1657 {"fw_version", S_IRUGO, &fops_fw_version},
1606}; 1658};
1607 1659
1608static void wil6210_debugfs_init_files(struct wil6210_priv *wil, 1660static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
@@ -1643,7 +1695,6 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
1643static const struct dbg_off dbg_wil_off[] = { 1695static const struct dbg_off dbg_wil_off[] = {
1644 WIL_FIELD(privacy, S_IRUGO, doff_u32), 1696 WIL_FIELD(privacy, S_IRUGO, doff_u32),
1645 WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong), 1697 WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong),
1646 WIL_FIELD(fw_version, S_IRUGO, doff_u32),
1647 WIL_FIELD(hw_version, S_IRUGO, doff_x32), 1698 WIL_FIELD(hw_version, S_IRUGO, doff_x32),
1648 WIL_FIELD(recovery_count, S_IRUGO, doff_u32), 1699 WIL_FIELD(recovery_count, S_IRUGO, doff_u32),
1649 WIL_FIELD(ap_isolate, S_IRUGO, doff_u32), 1700 WIL_FIELD(ap_isolate, S_IRUGO, doff_u32),
diff --git a/drivers/net/wireless/ath/wil6210/fw.h b/drivers/net/wireless/ath/wil6210/fw.h
index 7a2c6c129ad5..2f2b910501ba 100644
--- a/drivers/net/wireless/ath/wil6210/fw.h
+++ b/drivers/net/wireless/ath/wil6210/fw.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014,2016 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -58,6 +58,15 @@ struct wil_fw_record_comment { /* type == wil_fw_type_comment */
58 u8 data[0]; /* free-form data [data_size], see above */ 58 u8 data[0]; /* free-form data [data_size], see above */
59} __packed; 59} __packed;
60 60
61/* FW capabilities encoded inside a comment record */
62#define WIL_FW_CAPABILITIES_MAGIC (0xabcddcba)
63struct wil_fw_record_capabilities { /* type == wil_fw_type_comment */
64 /* identifies capabilities record */
65 __le32 magic;
66 /* capabilities (variable size), see enum wmi_fw_capability */
67 u8 capabilities[0];
68};
69
61/* perform action 70/* perform action
62 * data_size = @head.size - offsetof(struct wil_fw_record_action, data) 71 * data_size = @head.size - offsetof(struct wil_fw_record_action, data)
63 */ 72 */
@@ -93,6 +102,9 @@ struct wil_fw_record_verify { /* type == wil_fw_verify */
93/* file header 102/* file header
94 * First record of every file 103 * First record of every file
95 */ 104 */
105/* the FW version prefix in the comment */
106#define WIL_FW_VERSION_PREFIX "FW version: "
107#define WIL_FW_VERSION_PREFIX_LEN (sizeof(WIL_FW_VERSION_PREFIX) - 1)
96struct wil_fw_record_file_header { 108struct wil_fw_record_file_header {
97 __le32 signature ; /* Wilocity signature */ 109 __le32 signature ; /* Wilocity signature */
98 __le32 reserved; 110 __le32 reserved;
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
index d30657ee7e83..8f40eb301924 100644
--- a/drivers/net/wireless/ath/wil6210/fw_inc.c
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -118,6 +118,12 @@ static int wil_fw_verify(struct wil6210_priv *wil, const u8 *data, size_t size)
118 return (int)dlen; 118 return (int)dlen;
119} 119}
120 120
121static int fw_ignore_section(struct wil6210_priv *wil, const void *data,
122 size_t size)
123{
124 return 0;
125}
126
121static int fw_handle_comment(struct wil6210_priv *wil, const void *data, 127static int fw_handle_comment(struct wil6210_priv *wil, const void *data,
122 size_t size) 128 size_t size)
123{ 129{
@@ -126,6 +132,27 @@ static int fw_handle_comment(struct wil6210_priv *wil, const void *data,
126 return 0; 132 return 0;
127} 133}
128 134
135static int
136fw_handle_capabilities(struct wil6210_priv *wil, const void *data,
137 size_t size)
138{
139 const struct wil_fw_record_capabilities *rec = data;
140 size_t capa_size;
141
142 if (size < sizeof(*rec) ||
143 le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC)
144 return 0;
145
146 capa_size = size - offsetof(struct wil_fw_record_capabilities,
147 capabilities);
148 bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX);
149 memcpy(wil->fw_capabilities, rec->capabilities,
150 min(sizeof(wil->fw_capabilities), capa_size));
151 wil_hex_dump_fw("CAPA", DUMP_PREFIX_OFFSET, 16, 1,
152 rec->capabilities, capa_size, false);
153 return 0;
154}
155
129static int fw_handle_data(struct wil6210_priv *wil, const void *data, 156static int fw_handle_data(struct wil6210_priv *wil, const void *data,
130 size_t size) 157 size_t size)
131{ 158{
@@ -196,6 +223,13 @@ static int fw_handle_file_header(struct wil6210_priv *wil, const void *data,
196 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, d->comment, 223 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, d->comment,
197 sizeof(d->comment), true); 224 sizeof(d->comment), true);
198 225
226 if (!memcmp(d->comment, WIL_FW_VERSION_PREFIX,
227 WIL_FW_VERSION_PREFIX_LEN))
228 memcpy(wil->fw_version,
229 d->comment + WIL_FW_VERSION_PREFIX_LEN,
230 min(sizeof(d->comment) - WIL_FW_VERSION_PREFIX_LEN,
231 sizeof(wil->fw_version) - 1));
232
199 return 0; 233 return 0;
200} 234}
201 235
@@ -383,42 +417,51 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data,
383 417
384static const struct { 418static const struct {
385 int type; 419 int type;
386 int (*handler)(struct wil6210_priv *wil, const void *data, size_t size); 420 int (*load_handler)(struct wil6210_priv *wil, const void *data,
421 size_t size);
422 int (*parse_handler)(struct wil6210_priv *wil, const void *data,
423 size_t size);
387} wil_fw_handlers[] = { 424} wil_fw_handlers[] = {
388 {wil_fw_type_comment, fw_handle_comment}, 425 {wil_fw_type_comment, fw_handle_comment, fw_handle_capabilities},
389 {wil_fw_type_data, fw_handle_data}, 426 {wil_fw_type_data, fw_handle_data, fw_ignore_section},
390 {wil_fw_type_fill, fw_handle_fill}, 427 {wil_fw_type_fill, fw_handle_fill, fw_ignore_section},
391 /* wil_fw_type_action */ 428 /* wil_fw_type_action */
392 /* wil_fw_type_verify */ 429 /* wil_fw_type_verify */
393 {wil_fw_type_file_header, fw_handle_file_header}, 430 {wil_fw_type_file_header, fw_handle_file_header,
394 {wil_fw_type_direct_write, fw_handle_direct_write}, 431 fw_handle_file_header},
395 {wil_fw_type_gateway_data, fw_handle_gateway_data}, 432 {wil_fw_type_direct_write, fw_handle_direct_write, fw_ignore_section},
396 {wil_fw_type_gateway_data4, fw_handle_gateway_data4}, 433 {wil_fw_type_gateway_data, fw_handle_gateway_data, fw_ignore_section},
434 {wil_fw_type_gateway_data4, fw_handle_gateway_data4,
435 fw_ignore_section},
397}; 436};
398 437
399static int wil_fw_handle_record(struct wil6210_priv *wil, int type, 438static int wil_fw_handle_record(struct wil6210_priv *wil, int type,
400 const void *data, size_t size) 439 const void *data, size_t size, bool load)
401{ 440{
402 int i; 441 int i;
403 442
404 for (i = 0; i < ARRAY_SIZE(wil_fw_handlers); i++) { 443 for (i = 0; i < ARRAY_SIZE(wil_fw_handlers); i++)
405 if (wil_fw_handlers[i].type == type) 444 if (wil_fw_handlers[i].type == type)
406 return wil_fw_handlers[i].handler(wil, data, size); 445 return load ?
407 } 446 wil_fw_handlers[i].load_handler(
447 wil, data, size) :
448 wil_fw_handlers[i].parse_handler(
449 wil, data, size);
408 450
409 wil_err_fw(wil, "unknown record type: %d\n", type); 451 wil_err_fw(wil, "unknown record type: %d\n", type);
410 return -EINVAL; 452 return -EINVAL;
411} 453}
412 454
413/** 455/**
414 * wil_fw_load - load FW into device 456 * wil_fw_process - process section from FW file
415 * 457 * if load is true: Load the FW and uCode code and data to the
416 * Load the FW and uCode code and data to the corresponding device 458 * corresponding device memory regions,
417 * memory regions 459 * otherwise only parse and look for capabilities
418 * 460 *
419 * Return error code 461 * Return error code
420 */ 462 */
421static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size) 463static int wil_fw_process(struct wil6210_priv *wil, const void *data,
464 size_t size, bool load)
422{ 465{
423 int rc = 0; 466 int rc = 0;
424 const struct wil_fw_record_head *hdr; 467 const struct wil_fw_record_head *hdr;
@@ -437,7 +480,7 @@ static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size)
437 return -EINVAL; 480 return -EINVAL;
438 } 481 }
439 rc = wil_fw_handle_record(wil, le16_to_cpu(hdr->type), 482 rc = wil_fw_handle_record(wil, le16_to_cpu(hdr->type),
440 &hdr[1], hdr_sz); 483 &hdr[1], hdr_sz, load);
441 if (rc) 484 if (rc)
442 return rc; 485 return rc;
443 } 486 }
@@ -456,13 +499,16 @@ static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size)
456} 499}
457 500
458/** 501/**
459 * wil_request_firmware - Request firmware and load to device 502 * wil_request_firmware - Request firmware
460 * 503 *
461 * Request firmware image from the file and load it to device 504 * Request firmware image from the file
505 * If load is true, load firmware to device, otherwise
506 * only parse and extract capabilities
462 * 507 *
463 * Return error code 508 * Return error code
464 */ 509 */
465int wil_request_firmware(struct wil6210_priv *wil, const char *name) 510int wil_request_firmware(struct wil6210_priv *wil, const char *name,
511 bool load)
466{ 512{
467 int rc, rc1; 513 int rc, rc1;
468 const struct firmware *fw; 514 const struct firmware *fw;
@@ -482,7 +528,7 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name)
482 rc = rc1; 528 rc = rc1;
483 goto out; 529 goto out;
484 } 530 }
485 rc = wil_fw_load(wil, d, rc1); 531 rc = wil_fw_process(wil, d, rc1, load);
486 if (rc < 0) 532 if (rc < 0)
487 goto out; 533 goto out;
488 } 534 }
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 011e7412dcc0..64046e0bd0a2 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 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 5 * purpose with or without fee is hereby granted, provided that the above
@@ -101,7 +101,7 @@ static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp)
101 mask_halp ? WIL6210_IRQ_DISABLE : WIL6210_IRQ_DISABLE_NO_HALP); 101 mask_halp ? WIL6210_IRQ_DISABLE : WIL6210_IRQ_DISABLE_NO_HALP);
102} 102}
103 103
104static void wil6210_mask_halp(struct wil6210_priv *wil) 104void wil6210_mask_halp(struct wil6210_priv *wil)
105{ 105{
106 wil_dbg_irq(wil, "%s()\n", __func__); 106 wil_dbg_irq(wil, "%s()\n", __func__);
107 107
@@ -503,6 +503,13 @@ static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause)
503 offsetof(struct RGF_ICR, ICR)); 503 offsetof(struct RGF_ICR, ICR));
504 u32 imv_misc = wil_r(wil, RGF_DMA_EP_MISC_ICR + 504 u32 imv_misc = wil_r(wil, RGF_DMA_EP_MISC_ICR +
505 offsetof(struct RGF_ICR, IMV)); 505 offsetof(struct RGF_ICR, IMV));
506
507 /* HALP interrupt can be unmasked when misc interrupts are
508 * masked
509 */
510 if (icr_misc & BIT_DMA_EP_MISC_ICR_HALP)
511 return 0;
512
506 wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n" 513 wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n"
507 "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 514 "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n"
508 "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 515 "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n"
@@ -592,7 +599,7 @@ void wil6210_clear_irq(struct wil6210_priv *wil)
592 599
593void wil6210_set_halp(struct wil6210_priv *wil) 600void wil6210_set_halp(struct wil6210_priv *wil)
594{ 601{
595 wil_dbg_misc(wil, "%s()\n", __func__); 602 wil_dbg_irq(wil, "%s()\n", __func__);
596 603
597 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS), 604 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS),
598 BIT_DMA_EP_MISC_ICR_HALP); 605 BIT_DMA_EP_MISC_ICR_HALP);
@@ -600,7 +607,7 @@ void wil6210_set_halp(struct wil6210_priv *wil)
600 607
601void wil6210_clear_halp(struct wil6210_priv *wil) 608void wil6210_clear_halp(struct wil6210_priv *wil)
602{ 609{
603 wil_dbg_misc(wil, "%s()\n", __func__); 610 wil_dbg_irq(wil, "%s()\n", __func__);
604 611
605 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR), 612 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR),
606 BIT_DMA_EP_MISC_ICR_HALP); 613 BIT_DMA_EP_MISC_ICR_HALP);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 4bc92e54984a..e7130b54d1d8 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -232,6 +232,9 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
232 struct net_device *ndev = wil_to_ndev(wil); 232 struct net_device *ndev = wil_to_ndev(wil);
233 struct wireless_dev *wdev = wil->wdev; 233 struct wireless_dev *wdev = wil->wdev;
234 234
235 if (unlikely(!ndev))
236 return;
237
235 might_sleep(); 238 might_sleep();
236 wil_info(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid, 239 wil_info(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid,
237 reason_code, from_event ? "+" : "-"); 240 reason_code, from_event ? "+" : "-");
@@ -849,6 +852,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
849 bitmap_zero(wil->status, wil_status_last); 852 bitmap_zero(wil->status, wil_status_last);
850 mutex_unlock(&wil->wmi_mutex); 853 mutex_unlock(&wil->wmi_mutex);
851 854
855 mutex_lock(&wil->p2p_wdev_mutex);
852 if (wil->scan_request) { 856 if (wil->scan_request) {
853 struct cfg80211_scan_info info = { 857 struct cfg80211_scan_info info = {
854 .aborted = true, 858 .aborted = true,
@@ -860,6 +864,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
860 cfg80211_scan_done(wil->scan_request, &info); 864 cfg80211_scan_done(wil->scan_request, &info);
861 wil->scan_request = NULL; 865 wil->scan_request = NULL;
862 } 866 }
867 mutex_unlock(&wil->p2p_wdev_mutex);
863 868
864 wil_mask_irq(wil); 869 wil_mask_irq(wil);
865 870
@@ -888,11 +893,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
888 WIL_FW2_NAME); 893 WIL_FW2_NAME);
889 894
890 wil_halt_cpu(wil); 895 wil_halt_cpu(wil);
896 memset(wil->fw_version, 0, sizeof(wil->fw_version));
891 /* Loading f/w from the file */ 897 /* Loading f/w from the file */
892 rc = wil_request_firmware(wil, WIL_FW_NAME); 898 rc = wil_request_firmware(wil, WIL_FW_NAME, true);
893 if (rc) 899 if (rc)
894 return rc; 900 return rc;
895 rc = wil_request_firmware(wil, WIL_FW2_NAME); 901 rc = wil_request_firmware(wil, WIL_FW2_NAME, true);
896 if (rc) 902 if (rc)
897 return rc; 903 return rc;
898 904
@@ -1035,10 +1041,10 @@ int wil_up(struct wil6210_priv *wil)
1035 1041
1036int __wil_down(struct wil6210_priv *wil) 1042int __wil_down(struct wil6210_priv *wil)
1037{ 1043{
1038 int rc;
1039
1040 WARN_ON(!mutex_is_locked(&wil->mutex)); 1044 WARN_ON(!mutex_is_locked(&wil->mutex));
1041 1045
1046 set_bit(wil_status_resetting, wil->status);
1047
1042 if (wil->platform_ops.bus_request) 1048 if (wil->platform_ops.bus_request)
1043 wil->platform_ops.bus_request(wil->platform_handle, 0); 1049 wil->platform_ops.bus_request(wil->platform_handle, 0);
1044 1050
@@ -1050,8 +1056,9 @@ int __wil_down(struct wil6210_priv *wil)
1050 } 1056 }
1051 wil_enable_irq(wil); 1057 wil_enable_irq(wil);
1052 1058
1053 (void)wil_p2p_stop_discovery(wil); 1059 wil_p2p_stop_radio_operations(wil);
1054 1060
1061 mutex_lock(&wil->p2p_wdev_mutex);
1055 if (wil->scan_request) { 1062 if (wil->scan_request) {
1056 struct cfg80211_scan_info info = { 1063 struct cfg80211_scan_info info = {
1057 .aborted = true, 1064 .aborted = true,
@@ -1063,18 +1070,7 @@ int __wil_down(struct wil6210_priv *wil)
1063 cfg80211_scan_done(wil->scan_request, &info); 1070 cfg80211_scan_done(wil->scan_request, &info);
1064 wil->scan_request = NULL; 1071 wil->scan_request = NULL;
1065 } 1072 }
1066 1073 mutex_unlock(&wil->p2p_wdev_mutex);
1067 if (test_bit(wil_status_fwconnected, wil->status) ||
1068 test_bit(wil_status_fwconnecting, wil->status)) {
1069
1070 mutex_unlock(&wil->mutex);
1071 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
1072 WMI_DISCONNECT_EVENTID, NULL, 0,
1073 WIL6210_DISCONNECT_TO_MS);
1074 mutex_lock(&wil->mutex);
1075 if (rc)
1076 wil_err(wil, "timeout waiting for disconnect\n");
1077 }
1078 1074
1079 wil_reset(wil, false); 1075 wil_reset(wil, false);
1080 1076
@@ -1118,23 +1114,26 @@ void wil_halp_vote(struct wil6210_priv *wil)
1118 1114
1119 mutex_lock(&wil->halp.lock); 1115 mutex_lock(&wil->halp.lock);
1120 1116
1121 wil_dbg_misc(wil, "%s: start, HALP ref_cnt (%d)\n", __func__, 1117 wil_dbg_irq(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
1122 wil->halp.ref_cnt); 1118 wil->halp.ref_cnt);
1123 1119
1124 if (++wil->halp.ref_cnt == 1) { 1120 if (++wil->halp.ref_cnt == 1) {
1125 wil6210_set_halp(wil); 1121 wil6210_set_halp(wil);
1126 rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies); 1122 rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
1127 if (!rc) 1123 if (!rc) {
1128 wil_err(wil, "%s: HALP vote timed out\n", __func__); 1124 wil_err(wil, "%s: HALP vote timed out\n", __func__);
1129 else 1125 /* Mask HALP as done in case the interrupt is raised */
1130 wil_dbg_misc(wil, 1126 wil6210_mask_halp(wil);
1131 "%s: HALP vote completed after %d ms\n", 1127 } else {
1132 __func__, 1128 wil_dbg_irq(wil,
1133 jiffies_to_msecs(to_jiffies - rc)); 1129 "%s: HALP vote completed after %d ms\n",
1130 __func__,
1131 jiffies_to_msecs(to_jiffies - rc));
1132 }
1134 } 1133 }
1135 1134
1136 wil_dbg_misc(wil, "%s: end, HALP ref_cnt (%d)\n", __func__, 1135 wil_dbg_irq(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
1137 wil->halp.ref_cnt); 1136 wil->halp.ref_cnt);
1138 1137
1139 mutex_unlock(&wil->halp.lock); 1138 mutex_unlock(&wil->halp.lock);
1140} 1139}
@@ -1145,16 +1144,16 @@ void wil_halp_unvote(struct wil6210_priv *wil)
1145 1144
1146 mutex_lock(&wil->halp.lock); 1145 mutex_lock(&wil->halp.lock);
1147 1146
1148 wil_dbg_misc(wil, "%s: start, HALP ref_cnt (%d)\n", __func__, 1147 wil_dbg_irq(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
1149 wil->halp.ref_cnt); 1148 wil->halp.ref_cnt);
1150 1149
1151 if (--wil->halp.ref_cnt == 0) { 1150 if (--wil->halp.ref_cnt == 0) {
1152 wil6210_clear_halp(wil); 1151 wil6210_clear_halp(wil);
1153 wil_dbg_misc(wil, "%s: HALP unvote\n", __func__); 1152 wil_dbg_irq(wil, "%s: HALP unvote\n", __func__);
1154 } 1153 }
1155 1154
1156 wil_dbg_misc(wil, "%s: end, HALP ref_cnt (%d)\n", __func__, 1155 wil_dbg_irq(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
1157 wil->halp.ref_cnt); 1156 wil->halp.ref_cnt);
1158 1157
1159 mutex_unlock(&wil->halp.lock); 1158 mutex_unlock(&wil->halp.lock);
1160} 1159}
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 098409753d5b..61de5e9f8ef0 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -179,13 +179,6 @@ void *wil_if_alloc(struct device *dev)
179 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 179 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
180 wdev->netdev = ndev; 180 wdev->netdev = ndev;
181 181
182 netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
183 WIL6210_NAPI_BUDGET);
184 netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
185 WIL6210_NAPI_BUDGET);
186
187 netif_tx_stop_all_queues(ndev);
188
189 return wil; 182 return wil;
190 183
191 out_priv: 184 out_priv:
@@ -216,25 +209,48 @@ void wil_if_free(struct wil6210_priv *wil)
216 209
217int wil_if_add(struct wil6210_priv *wil) 210int wil_if_add(struct wil6210_priv *wil)
218{ 211{
212 struct wireless_dev *wdev = wil_to_wdev(wil);
213 struct wiphy *wiphy = wdev->wiphy;
219 struct net_device *ndev = wil_to_ndev(wil); 214 struct net_device *ndev = wil_to_ndev(wil);
220 int rc; 215 int rc;
221 216
222 wil_dbg_misc(wil, "%s()\n", __func__); 217 wil_dbg_misc(wil, "entered");
218
219 strlcpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version));
220
221 rc = wiphy_register(wiphy);
222 if (rc < 0) {
223 wil_err(wil, "failed to register wiphy, err %d\n", rc);
224 return rc;
225 }
226
227 netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
228 WIL6210_NAPI_BUDGET);
229 netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
230 WIL6210_NAPI_BUDGET);
231
232 netif_tx_stop_all_queues(ndev);
223 233
224 rc = register_netdev(ndev); 234 rc = register_netdev(ndev);
225 if (rc < 0) { 235 if (rc < 0) {
226 dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); 236 dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc);
227 return rc; 237 goto out_wiphy;
228 } 238 }
229 239
230 return 0; 240 return 0;
241
242out_wiphy:
243 wiphy_unregister(wdev->wiphy);
244 return rc;
231} 245}
232 246
233void wil_if_remove(struct wil6210_priv *wil) 247void wil_if_remove(struct wil6210_priv *wil)
234{ 248{
235 struct net_device *ndev = wil_to_ndev(wil); 249 struct net_device *ndev = wil_to_ndev(wil);
250 struct wireless_dev *wdev = wil_to_wdev(wil);
236 251
237 wil_dbg_misc(wil, "%s()\n", __func__); 252 wil_dbg_misc(wil, "%s()\n", __func__);
238 253
239 unregister_netdev(ndev); 254 unregister_netdev(ndev);
255 wiphy_unregister(wdev->wiphy);
240} 256}
diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c
index e0f8aa0ebfac..4087785d3090 100644
--- a/drivers/net/wireless/ath/wil6210/p2p.c
+++ b/drivers/net/wireless/ath/wil6210/p2p.c
@@ -263,3 +263,49 @@ void wil_p2p_search_expired(struct work_struct *work)
263 mutex_unlock(&wil->p2p_wdev_mutex); 263 mutex_unlock(&wil->p2p_wdev_mutex);
264 } 264 }
265} 265}
266
267void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
268{
269 struct wil_p2p_info *p2p = &wil->p2p;
270 struct cfg80211_scan_info info = {
271 .aborted = true,
272 };
273
274 lockdep_assert_held(&wil->mutex);
275
276 mutex_lock(&wil->p2p_wdev_mutex);
277
278 if (wil->radio_wdev != wil->p2p_wdev)
279 goto out;
280
281 if (!p2p->discovery_started) {
282 /* Regular scan on the p2p device */
283 if (wil->scan_request &&
284 wil->scan_request->wdev == wil->p2p_wdev) {
285 cfg80211_scan_done(wil->scan_request, &info);
286 wil->scan_request = NULL;
287 }
288 goto out;
289 }
290
291 /* Search or listen on p2p device */
292 mutex_unlock(&wil->p2p_wdev_mutex);
293 wil_p2p_stop_discovery(wil);
294 mutex_lock(&wil->p2p_wdev_mutex);
295
296 if (wil->scan_request) {
297 /* search */
298 cfg80211_scan_done(wil->scan_request, &info);
299 wil->scan_request = NULL;
300 } else {
301 /* listen */
302 cfg80211_remain_on_channel_expired(wil->radio_wdev,
303 p2p->cookie,
304 &p2p->listen_chan,
305 GFP_KERNEL);
306 }
307
308out:
309 wil->radio_wdev = wil->wdev;
310 mutex_unlock(&wil->p2p_wdev_mutex);
311}
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 7b5c4222bc33..44746ca0d2e6 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -20,6 +20,7 @@
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/suspend.h> 21#include <linux/suspend.h>
22#include "wil6210.h" 22#include "wil6210.h"
23#include <linux/rtnetlink.h>
23 24
24static bool use_msi = true; 25static bool use_msi = true;
25module_param(use_msi, bool, S_IRUGO); 26module_param(use_msi, bool, S_IRUGO);
@@ -38,6 +39,7 @@ void wil_set_capabilities(struct wil6210_priv *wil)
38 u32 rev_id = wil_r(wil, RGF_USER_JTAG_DEV_ID); 39 u32 rev_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
39 40
40 bitmap_zero(wil->hw_capabilities, hw_capability_last); 41 bitmap_zero(wil->hw_capabilities, hw_capability_last);
42 bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX);
41 43
42 switch (rev_id) { 44 switch (rev_id) {
43 case JTAG_DEV_ID_SPARROW_B0: 45 case JTAG_DEV_ID_SPARROW_B0:
@@ -51,6 +53,9 @@ void wil_set_capabilities(struct wil6210_priv *wil)
51 } 53 }
52 54
53 wil_info(wil, "Board hardware is %s\n", wil->hw_name); 55 wil_info(wil, "Board hardware is %s\n", wil->hw_name);
56
57 /* extract FW capabilities from file without loading the FW */
58 wil_request_firmware(wil, WIL_FW_NAME, false);
54} 59}
55 60
56void wil_disable_irq(struct wil6210_priv *wil) 61void wil_disable_irq(struct wil6210_priv *wil)
@@ -293,6 +298,9 @@ static void wil_pcie_remove(struct pci_dev *pdev)
293#endif /* CONFIG_PM */ 298#endif /* CONFIG_PM */
294 299
295 wil6210_debugfs_remove(wil); 300 wil6210_debugfs_remove(wil);
301 rtnl_lock();
302 wil_p2p_wdev_free(wil);
303 rtnl_unlock();
296 wil_if_remove(wil); 304 wil_if_remove(wil);
297 wil_if_pcie_disable(wil); 305 wil_if_pcie_disable(wil);
298 pci_iounmap(pdev, csr); 306 pci_iounmap(pdev, csr);
@@ -300,7 +308,6 @@ static void wil_pcie_remove(struct pci_dev *pdev)
300 pci_disable_device(pdev); 308 pci_disable_device(pdev);
301 if (wil->platform_ops.uninit) 309 if (wil->platform_ops.uninit)
302 wil->platform_ops.uninit(wil->platform_handle); 310 wil->platform_ops.uninit(wil->platform_handle);
303 wil_p2p_wdev_free(wil);
304 wil_if_free(wil); 311 wil_if_free(wil);
305} 312}
306 313
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index f2f6a404d3d1..4c38520d4dd2 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -873,9 +873,12 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
873 rc = -EINVAL; 873 rc = -EINVAL;
874 goto out_free; 874 goto out_free;
875 } 875 }
876 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
877 876
877 spin_lock_bh(&txdata->lock);
878 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
878 txdata->enabled = 1; 879 txdata->enabled = 1;
880 spin_unlock_bh(&txdata->lock);
881
879 if (txdata->dot1x_open && (agg_wsize >= 0)) 882 if (txdata->dot1x_open && (agg_wsize >= 0))
880 wil_addba_tx_request(wil, id, agg_wsize); 883 wil_addba_tx_request(wil, id, agg_wsize);
881 884
@@ -950,9 +953,11 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
950 rc = -EINVAL; 953 rc = -EINVAL;
951 goto out_free; 954 goto out_free;
952 } 955 }
953 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
954 956
957 spin_lock_bh(&txdata->lock);
958 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
955 txdata->enabled = 1; 959 txdata->enabled = 1;
960 spin_unlock_bh(&txdata->lock);
956 961
957 return 0; 962 return 0;
958 out_free: 963 out_free:
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index ecab4af90602..a949cd62bc4e 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -17,6 +17,7 @@
17#ifndef __WIL6210_H__ 17#ifndef __WIL6210_H__
18#define __WIL6210_H__ 18#define __WIL6210_H__
19 19
20#include <linux/etherdevice.h>
20#include <linux/netdevice.h> 21#include <linux/netdevice.h>
21#include <linux/wireless.h> 22#include <linux/wireless.h>
22#include <net/cfg80211.h> 23#include <net/cfg80211.h>
@@ -576,10 +577,11 @@ struct wil6210_priv {
576 struct wireless_dev *wdev; 577 struct wireless_dev *wdev;
577 void __iomem *csr; 578 void __iomem *csr;
578 DECLARE_BITMAP(status, wil_status_last); 579 DECLARE_BITMAP(status, wil_status_last);
579 u32 fw_version; 580 u8 fw_version[ETHTOOL_FWVERS_LEN];
580 u32 hw_version; 581 u32 hw_version;
581 const char *hw_name; 582 const char *hw_name;
582 DECLARE_BITMAP(hw_capabilities, hw_capability_last); 583 DECLARE_BITMAP(hw_capabilities, hw_capability_last);
584 DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX);
583 u8 n_mids; /* number of additional MIDs as reported by FW */ 585 u8 n_mids; /* number of additional MIDs as reported by FW */
584 u32 recovery_count; /* num of FW recovery attempts in a short time */ 586 u32 recovery_count; /* num of FW recovery attempts in a short time */
585 u32 recovery_state; /* FW recovery state machine */ 587 u32 recovery_state; /* FW recovery state machine */
@@ -657,7 +659,7 @@ struct wil6210_priv {
657 659
658 /* P2P_DEVICE vif */ 660 /* P2P_DEVICE vif */
659 struct wireless_dev *p2p_wdev; 661 struct wireless_dev *p2p_wdev;
660 struct mutex p2p_wdev_mutex; /* protect @p2p_wdev */ 662 struct mutex p2p_wdev_mutex; /* protect @p2p_wdev and @scan_request */
661 struct wireless_dev *radio_wdev; 663 struct wireless_dev *radio_wdev;
662 664
663 /* High Access Latency Policy voting */ 665 /* High Access Latency Policy voting */
@@ -828,6 +830,7 @@ void wil_unmask_irq(struct wil6210_priv *wil);
828void wil_configure_interrupt_moderation(struct wil6210_priv *wil); 830void wil_configure_interrupt_moderation(struct wil6210_priv *wil);
829void wil_disable_irq(struct wil6210_priv *wil); 831void wil_disable_irq(struct wil6210_priv *wil);
830void wil_enable_irq(struct wil6210_priv *wil); 832void wil_enable_irq(struct wil6210_priv *wil);
833void wil6210_mask_halp(struct wil6210_priv *wil);
831 834
832/* P2P */ 835/* P2P */
833bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); 836bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request);
@@ -840,6 +843,7 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil);
840int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie); 843int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie);
841void wil_p2p_listen_expired(struct work_struct *work); 844void wil_p2p_listen_expired(struct work_struct *work);
842void wil_p2p_search_expired(struct work_struct *work); 845void wil_p2p_search_expired(struct work_struct *work);
846void wil_p2p_stop_radio_operations(struct wil6210_priv *wil);
843 847
844/* WMI for P2P */ 848/* WMI for P2P */
845int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi); 849int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi);
@@ -893,7 +897,8 @@ void wil6210_unmask_irq_rx(struct wil6210_priv *wil);
893int wil_iftype_nl2wmi(enum nl80211_iftype type); 897int wil_iftype_nl2wmi(enum nl80211_iftype type);
894 898
895int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd); 899int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd);
896int wil_request_firmware(struct wil6210_priv *wil, const char *name); 900int wil_request_firmware(struct wil6210_priv *wil, const char *name,
901 bool load);
897 902
898int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime); 903int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
899int wil_suspend(struct wil6210_priv *wil, bool is_runtime); 904int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 4d92541913c0..fae4f1285d08 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -312,14 +312,14 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
312 struct wireless_dev *wdev = wil->wdev; 312 struct wireless_dev *wdev = wil->wdev;
313 struct wmi_ready_event *evt = d; 313 struct wmi_ready_event *evt = d;
314 314
315 wil->fw_version = le32_to_cpu(evt->sw_version);
316 wil->n_mids = evt->numof_additional_mids; 315 wil->n_mids = evt->numof_additional_mids;
317 316
318 wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version, 317 wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n",
318 wil->fw_version, le32_to_cpu(evt->sw_version),
319 evt->mac, wil->n_mids); 319 evt->mac, wil->n_mids);
320 /* ignore MAC address, we already have it from the boot loader */ 320 /* ignore MAC address, we already have it from the boot loader */
321 snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version), 321 strlcpy(wdev->wiphy->fw_version, wil->fw_version,
322 "%d", wil->fw_version); 322 sizeof(wdev->wiphy->fw_version));
323 323
324 wil_set_recovery_state(wil, fw_recovery_idle); 324 wil_set_recovery_state(wil, fw_recovery_idle);
325 set_bit(wil_status_fwready, wil->status); 325 set_bit(wil_status_fwready, wil->status);
@@ -424,6 +424,7 @@ static void wmi_evt_tx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
424static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, 424static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
425 void *d, int len) 425 void *d, int len)
426{ 426{
427 mutex_lock(&wil->p2p_wdev_mutex);
427 if (wil->scan_request) { 428 if (wil->scan_request) {
428 struct wmi_scan_complete_event *data = d; 429 struct wmi_scan_complete_event *data = d;
429 struct cfg80211_scan_info info = { 430 struct cfg80211_scan_info info = {
@@ -435,14 +436,13 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
435 wil->scan_request, info.aborted); 436 wil->scan_request, info.aborted);
436 437
437 del_timer_sync(&wil->scan_timer); 438 del_timer_sync(&wil->scan_timer);
438 mutex_lock(&wil->p2p_wdev_mutex);
439 cfg80211_scan_done(wil->scan_request, &info); 439 cfg80211_scan_done(wil->scan_request, &info);
440 wil->radio_wdev = wil->wdev; 440 wil->radio_wdev = wil->wdev;
441 mutex_unlock(&wil->p2p_wdev_mutex);
442 wil->scan_request = NULL; 441 wil->scan_request = NULL;
443 } else { 442 } else {
444 wil_err(wil, "SCAN_COMPLETE while not scanning\n"); 443 wil_err(wil, "SCAN_COMPLETE while not scanning\n");
445 } 444 }
445 mutex_unlock(&wil->p2p_wdev_mutex);
446} 446}
447 447
448static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) 448static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 685fe0ddea26..f430e8a80603 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -46,6 +46,16 @@ enum wmi_mid {
46 MID_BROADCAST = 0xFF, 46 MID_BROADCAST = 0xFF,
47}; 47};
48 48
49/* FW capability IDs
50 * Each ID maps to a bit in a 32-bit bitmask value provided by the FW to
51 * the host
52 */
53enum wmi_fw_capability {
54 WMI_FW_CAPABILITY_FTM = 0,
55 WMI_FW_CAPABILITY_PS_CONFIG = 1,
56 WMI_FW_CAPABILITY_MAX,
57};
58
49/* WMI_CMD_HDR */ 59/* WMI_CMD_HDR */
50struct wmi_cmd_hdr { 60struct wmi_cmd_hdr {
51 u8 mid; 61 u8 mid;
@@ -120,6 +130,8 @@ enum wmi_command_id {
120 WMI_BF_SM_MGMT_CMDID = 0x838, 130 WMI_BF_SM_MGMT_CMDID = 0x838,
121 WMI_BF_RXSS_MGMT_CMDID = 0x839, 131 WMI_BF_RXSS_MGMT_CMDID = 0x839,
122 WMI_BF_TRIG_CMDID = 0x83A, 132 WMI_BF_TRIG_CMDID = 0x83A,
133 WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842,
134 WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843,
123 WMI_SET_SECTORS_CMDID = 0x849, 135 WMI_SET_SECTORS_CMDID = 0x849,
124 WMI_MAINTAIN_PAUSE_CMDID = 0x850, 136 WMI_MAINTAIN_PAUSE_CMDID = 0x850,
125 WMI_MAINTAIN_RESUME_CMDID = 0x851, 137 WMI_MAINTAIN_RESUME_CMDID = 0x851,
@@ -134,10 +146,15 @@ enum wmi_command_id {
134 WMI_BF_CTRL_CMDID = 0x862, 146 WMI_BF_CTRL_CMDID = 0x862,
135 WMI_NOTIFY_REQ_CMDID = 0x863, 147 WMI_NOTIFY_REQ_CMDID = 0x863,
136 WMI_GET_STATUS_CMDID = 0x864, 148 WMI_GET_STATUS_CMDID = 0x864,
149 WMI_GET_RF_STATUS_CMDID = 0x866,
150 WMI_GET_BASEBAND_TYPE_CMDID = 0x867,
137 WMI_UNIT_TEST_CMDID = 0x900, 151 WMI_UNIT_TEST_CMDID = 0x900,
138 WMI_HICCUP_CMDID = 0x901, 152 WMI_HICCUP_CMDID = 0x901,
139 WMI_FLASH_READ_CMDID = 0x902, 153 WMI_FLASH_READ_CMDID = 0x902,
140 WMI_FLASH_WRITE_CMDID = 0x903, 154 WMI_FLASH_WRITE_CMDID = 0x903,
155 /* Power management */
156 WMI_TRAFFIC_DEFERRAL_CMDID = 0x904,
157 WMI_TRAFFIC_RESUME_CMDID = 0x905,
141 /* P2P */ 158 /* P2P */
142 WMI_P2P_CFG_CMDID = 0x910, 159 WMI_P2P_CFG_CMDID = 0x910,
143 WMI_PORT_ALLOCATE_CMDID = 0x911, 160 WMI_PORT_ALLOCATE_CMDID = 0x911,
@@ -150,6 +167,26 @@ enum wmi_command_id {
150 WMI_PCP_START_CMDID = 0x918, 167 WMI_PCP_START_CMDID = 0x918,
151 WMI_PCP_STOP_CMDID = 0x919, 168 WMI_PCP_STOP_CMDID = 0x919,
152 WMI_GET_PCP_FACTOR_CMDID = 0x91B, 169 WMI_GET_PCP_FACTOR_CMDID = 0x91B,
170 /* Power Save Configuration Commands */
171 WMI_PS_DEV_PROFILE_CFG_CMDID = 0x91C,
172 /* Not supported yet */
173 WMI_PS_DEV_CFG_CMDID = 0x91D,
174 /* Not supported yet */
175 WMI_PS_DEV_CFG_READ_CMDID = 0x91E,
176 /* Per MAC Power Save Configuration commands
177 * Not supported yet
178 */
179 WMI_PS_MID_CFG_CMDID = 0x91F,
180 /* Not supported yet */
181 WMI_PS_MID_CFG_READ_CMDID = 0x920,
182 WMI_RS_CFG_CMDID = 0x921,
183 WMI_GET_DETAILED_RS_RES_CMDID = 0x922,
184 WMI_AOA_MEAS_CMDID = 0x923,
185 WMI_TOF_SESSION_START_CMDID = 0x991,
186 WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
187 WMI_TOF_SET_LCR_CMDID = 0x993,
188 WMI_TOF_SET_LCI_CMDID = 0x994,
189 WMI_TOF_CHANNEL_INFO_CMDID = 0x995,
153 WMI_SET_MAC_ADDRESS_CMDID = 0xF003, 190 WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
154 WMI_ABORT_SCAN_CMDID = 0xF007, 191 WMI_ABORT_SCAN_CMDID = 0xF007,
155 WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041, 192 WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
@@ -291,9 +328,8 @@ enum wmi_scan_type {
291/* WMI_START_SCAN_CMDID */ 328/* WMI_START_SCAN_CMDID */
292struct wmi_start_scan_cmd { 329struct wmi_start_scan_cmd {
293 u8 direct_scan_mac_addr[WMI_MAC_LEN]; 330 u8 direct_scan_mac_addr[WMI_MAC_LEN];
294 /* DMG Beacon frame is transmitted during active scanning */ 331 /* run scan with discovery beacon. Relevant for ACTIVE scan only. */
295 u8 discovery_mode; 332 u8 discovery_mode;
296 /* reserved */
297 u8 reserved; 333 u8 reserved;
298 /* Max duration in the home channel(ms) */ 334 /* Max duration in the home channel(ms) */
299 __le32 dwell_time; 335 __le32 dwell_time;
@@ -453,6 +489,12 @@ struct wmi_port_delete_cmd {
453 u8 reserved[3]; 489 u8 reserved[3];
454} __packed; 490} __packed;
455 491
492/* WMI_TRAFFIC_DEFERRAL_CMDID */
493struct wmi_traffic_deferral_cmd {
494 /* Bit vector: bit[0] - wake on Unicast, bit[1] - wake on Broadcast */
495 u8 wakeup_trigger;
496} __packed;
497
456/* WMI_P2P_CFG_CMDID */ 498/* WMI_P2P_CFG_CMDID */
457enum wmi_discovery_mode { 499enum wmi_discovery_mode {
458 WMI_DISCOVERY_MODE_NON_OFFLOAD = 0x00, 500 WMI_DISCOVERY_MODE_NON_OFFLOAD = 0x00,
@@ -818,85 +860,193 @@ struct wmi_pmc_cmd {
818 __le64 mem_base; 860 __le64 mem_base;
819} __packed; 861} __packed;
820 862
863enum wmi_aoa_meas_type {
864 WMI_AOA_PHASE_MEAS = 0x00,
865 WMI_AOA_PHASE_AMP_MEAS = 0x01,
866};
867
868/* WMI_AOA_MEAS_CMDID */
869struct wmi_aoa_meas_cmd {
870 u8 mac_addr[WMI_MAC_LEN];
871 /* channels IDs:
872 * 0 - 58320 MHz
873 * 1 - 60480 MHz
874 * 2 - 62640 MHz
875 */
876 u8 channel;
877 /* enum wmi_aoa_meas_type */
878 u8 aoa_meas_type;
879 __le32 meas_rf_mask;
880} __packed;
881
882enum wmi_tof_burst_duration {
883 WMI_TOF_BURST_DURATION_250_USEC = 2,
884 WMI_TOF_BURST_DURATION_500_USEC = 3,
885 WMI_TOF_BURST_DURATION_1_MSEC = 4,
886 WMI_TOF_BURST_DURATION_2_MSEC = 5,
887 WMI_TOF_BURST_DURATION_4_MSEC = 6,
888 WMI_TOF_BURST_DURATION_8_MSEC = 7,
889 WMI_TOF_BURST_DURATION_16_MSEC = 8,
890 WMI_TOF_BURST_DURATION_32_MSEC = 9,
891 WMI_TOF_BURST_DURATION_64_MSEC = 10,
892 WMI_TOF_BURST_DURATION_128_MSEC = 11,
893 WMI_TOF_BURST_DURATION_NO_PREFERENCES = 15,
894};
895
896enum wmi_tof_session_start_flags {
897 WMI_TOF_SESSION_START_FLAG_SECURED = 0x1,
898 WMI_TOF_SESSION_START_FLAG_ASAP = 0x2,
899 WMI_TOF_SESSION_START_FLAG_LCI_REQ = 0x4,
900 WMI_TOF_SESSION_START_FLAG_LCR_REQ = 0x8,
901};
902
903/* WMI_TOF_SESSION_START_CMDID */
904struct wmi_ftm_dest_info {
905 u8 channel;
906 /* wmi_tof_session_start_flags_e */
907 u8 flags;
908 u8 initial_token;
909 u8 num_of_ftm_per_burst;
910 u8 num_of_bursts_exp;
911 /* wmi_tof_burst_duration_e */
912 u8 burst_duration;
913 /* Burst Period indicate interval between two consecutive burst
914 * instances, in units of 100 ms
915 */
916 __le16 burst_period;
917 u8 dst_mac[WMI_MAC_LEN];
918 __le16 reserved;
919} __packed;
920
921/* WMI_TOF_SESSION_START_CMDID */
922struct wmi_tof_session_start_cmd {
923 __le32 session_id;
924 u8 num_of_aoa_measures;
925 u8 aoa_type;
926 __le16 num_of_dest;
927 u8 reserved[4];
928 struct wmi_ftm_dest_info ftm_dest_info[0];
929} __packed;
930
931enum wmi_tof_channel_info_report_type {
932 WMI_TOF_CHANNEL_INFO_TYPE_CIR = 0x1,
933 WMI_TOF_CHANNEL_INFO_TYPE_RSSI = 0x2,
934 WMI_TOF_CHANNEL_INFO_TYPE_SNR = 0x4,
935 WMI_TOF_CHANNEL_INFO_TYPE_DEBUG_DATA = 0x8,
936 WMI_TOF_CHANNEL_INFO_TYPE_VENDOR_SPECIFIC = 0x10,
937};
938
939/* WMI_TOF_CHANNEL_INFO_CMDID */
940struct wmi_tof_channel_info_cmd {
941 /* wmi_tof_channel_info_report_type_e */
942 __le32 channel_info_report_request;
943} __packed;
944
821/* WMI Events 945/* WMI Events
822 * List of Events (target to host) 946 * List of Events (target to host)
823 */ 947 */
824enum wmi_event_id { 948enum wmi_event_id {
825 WMI_READY_EVENTID = 0x1001, 949 WMI_READY_EVENTID = 0x1001,
826 WMI_CONNECT_EVENTID = 0x1002, 950 WMI_CONNECT_EVENTID = 0x1002,
827 WMI_DISCONNECT_EVENTID = 0x1003, 951 WMI_DISCONNECT_EVENTID = 0x1003,
828 WMI_SCAN_COMPLETE_EVENTID = 0x100A, 952 WMI_SCAN_COMPLETE_EVENTID = 0x100A,
829 WMI_REPORT_STATISTICS_EVENTID = 0x100B, 953 WMI_REPORT_STATISTICS_EVENTID = 0x100B,
830 WMI_RD_MEM_RSP_EVENTID = 0x1800, 954 WMI_RD_MEM_RSP_EVENTID = 0x1800,
831 WMI_FW_READY_EVENTID = 0x1801, 955 WMI_FW_READY_EVENTID = 0x1801,
832 WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x200, 956 WMI_EXIT_FAST_MEM_ACC_MODE_EVENTID = 0x200,
833 WMI_ECHO_RSP_EVENTID = 0x1803, 957 WMI_ECHO_RSP_EVENTID = 0x1803,
834 WMI_FS_TUNE_DONE_EVENTID = 0x180A, 958 WMI_FS_TUNE_DONE_EVENTID = 0x180A,
835 WMI_CORR_MEASURE_EVENTID = 0x180B, 959 WMI_CORR_MEASURE_EVENTID = 0x180B,
836 WMI_READ_RSSI_EVENTID = 0x180C, 960 WMI_READ_RSSI_EVENTID = 0x180C,
837 WMI_TEMP_SENSE_DONE_EVENTID = 0x180E, 961 WMI_TEMP_SENSE_DONE_EVENTID = 0x180E,
838 WMI_DC_CALIB_DONE_EVENTID = 0x180F, 962 WMI_DC_CALIB_DONE_EVENTID = 0x180F,
839 WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811, 963 WMI_IQ_TX_CALIB_DONE_EVENTID = 0x1811,
840 WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812, 964 WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812,
841 WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815, 965 WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815,
842 WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816, 966 WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816,
843 WMI_MARLON_R_READ_DONE_EVENTID = 0x1818, 967 WMI_MARLON_R_READ_DONE_EVENTID = 0x1818,
844 WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819, 968 WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819,
845 WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181A, 969 WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181A,
846 WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181D, 970 WMI_SILENT_RSSI_CALIB_DONE_EVENTID = 0x181D,
847 WMI_RF_RX_TEST_DONE_EVENTID = 0x181E, 971 WMI_RF_RX_TEST_DONE_EVENTID = 0x181E,
848 WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820, 972 WMI_CFG_RX_CHAIN_DONE_EVENTID = 0x1820,
849 WMI_VRING_CFG_DONE_EVENTID = 0x1821, 973 WMI_VRING_CFG_DONE_EVENTID = 0x1821,
850 WMI_BA_STATUS_EVENTID = 0x1823, 974 WMI_BA_STATUS_EVENTID = 0x1823,
851 WMI_RCP_ADDBA_REQ_EVENTID = 0x1824, 975 WMI_RCP_ADDBA_REQ_EVENTID = 0x1824,
852 WMI_RCP_ADDBA_RESP_SENT_EVENTID = 0x1825, 976 WMI_RCP_ADDBA_RESP_SENT_EVENTID = 0x1825,
853 WMI_DELBA_EVENTID = 0x1826, 977 WMI_DELBA_EVENTID = 0x1826,
854 WMI_GET_SSID_EVENTID = 0x1828, 978 WMI_GET_SSID_EVENTID = 0x1828,
855 WMI_GET_PCP_CHANNEL_EVENTID = 0x182A, 979 WMI_GET_PCP_CHANNEL_EVENTID = 0x182A,
856 WMI_SW_TX_COMPLETE_EVENTID = 0x182B, 980 WMI_SW_TX_COMPLETE_EVENTID = 0x182B,
857 WMI_READ_MAC_RXQ_EVENTID = 0x1830, 981 WMI_READ_MAC_RXQ_EVENTID = 0x1830,
858 WMI_READ_MAC_TXQ_EVENTID = 0x1831, 982 WMI_READ_MAC_TXQ_EVENTID = 0x1831,
859 WMI_WRITE_MAC_RXQ_EVENTID = 0x1832, 983 WMI_WRITE_MAC_RXQ_EVENTID = 0x1832,
860 WMI_WRITE_MAC_TXQ_EVENTID = 0x1833, 984 WMI_WRITE_MAC_TXQ_EVENTID = 0x1833,
861 WMI_WRITE_MAC_XQ_FIELD_EVENTID = 0x1834, 985 WMI_WRITE_MAC_XQ_FIELD_EVENTID = 0x1834,
862 WMI_BEAMFORMING_MGMT_DONE_EVENTID = 0x1836, 986 WMI_BEAMFORMING_MGMT_DONE_EVENTID = 0x1836,
863 WMI_BF_TXSS_MGMT_DONE_EVENTID = 0x1837, 987 WMI_BF_TXSS_MGMT_DONE_EVENTID = 0x1837,
864 WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839, 988 WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839,
865 WMI_RS_MGMT_DONE_EVENTID = 0x1852, 989 WMI_RS_MGMT_DONE_EVENTID = 0x1852,
866 WMI_RF_MGMT_STATUS_EVENTID = 0x1853, 990 WMI_RF_MGMT_STATUS_EVENTID = 0x1853,
867 WMI_THERMAL_THROTTLING_STATUS_EVENTID = 0x1855, 991 WMI_THERMAL_THROTTLING_STATUS_EVENTID = 0x1855,
868 WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838, 992 WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
869 WMI_RX_MGMT_PACKET_EVENTID = 0x1840, 993 WMI_RX_MGMT_PACKET_EVENTID = 0x1840,
870 WMI_TX_MGMT_PACKET_EVENTID = 0x1841, 994 WMI_TX_MGMT_PACKET_EVENTID = 0x1841,
871 WMI_OTP_READ_RESULT_EVENTID = 0x1856, 995 WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID = 0x1842,
872 WMI_LED_CFG_DONE_EVENTID = 0x1858, 996 WMI_LINK_MAINTAIN_CFG_READ_DONE_EVENTID = 0x1843,
997 WMI_OTP_READ_RESULT_EVENTID = 0x1856,
998 WMI_LED_CFG_DONE_EVENTID = 0x1858,
873 /* Performance monitoring events */ 999 /* Performance monitoring events */
874 WMI_DATA_PORT_OPEN_EVENTID = 0x1860, 1000 WMI_DATA_PORT_OPEN_EVENTID = 0x1860,
875 WMI_WBE_LINK_DOWN_EVENTID = 0x1861, 1001 WMI_WBE_LINK_DOWN_EVENTID = 0x1861,
876 WMI_BF_CTRL_DONE_EVENTID = 0x1862, 1002 WMI_BF_CTRL_DONE_EVENTID = 0x1862,
877 WMI_NOTIFY_REQ_DONE_EVENTID = 0x1863, 1003 WMI_NOTIFY_REQ_DONE_EVENTID = 0x1863,
878 WMI_GET_STATUS_DONE_EVENTID = 0x1864, 1004 WMI_GET_STATUS_DONE_EVENTID = 0x1864,
879 WMI_VRING_EN_EVENTID = 0x1865, 1005 WMI_VRING_EN_EVENTID = 0x1865,
880 WMI_UNIT_TEST_EVENTID = 0x1900, 1006 WMI_GET_RF_STATUS_EVENTID = 0x1866,
881 WMI_FLASH_READ_DONE_EVENTID = 0x1902, 1007 WMI_GET_BASEBAND_TYPE_EVENTID = 0x1867,
882 WMI_FLASH_WRITE_DONE_EVENTID = 0x1903, 1008 WMI_UNIT_TEST_EVENTID = 0x1900,
1009 WMI_FLASH_READ_DONE_EVENTID = 0x1902,
1010 WMI_FLASH_WRITE_DONE_EVENTID = 0x1903,
1011 /* Power management */
1012 WMI_TRAFFIC_DEFERRAL_EVENTID = 0x1904,
1013 WMI_TRAFFIC_RESUME_EVENTID = 0x1905,
883 /* P2P */ 1014 /* P2P */
884 WMI_P2P_CFG_DONE_EVENTID = 0x1910, 1015 WMI_P2P_CFG_DONE_EVENTID = 0x1910,
885 WMI_PORT_ALLOCATED_EVENTID = 0x1911, 1016 WMI_PORT_ALLOCATED_EVENTID = 0x1911,
886 WMI_PORT_DELETED_EVENTID = 0x1912, 1017 WMI_PORT_DELETED_EVENTID = 0x1912,
887 WMI_LISTEN_STARTED_EVENTID = 0x1914, 1018 WMI_LISTEN_STARTED_EVENTID = 0x1914,
888 WMI_SEARCH_STARTED_EVENTID = 0x1915, 1019 WMI_SEARCH_STARTED_EVENTID = 0x1915,
889 WMI_DISCOVERY_STARTED_EVENTID = 0x1916, 1020 WMI_DISCOVERY_STARTED_EVENTID = 0x1916,
890 WMI_DISCOVERY_STOPPED_EVENTID = 0x1917, 1021 WMI_DISCOVERY_STOPPED_EVENTID = 0x1917,
891 WMI_PCP_STARTED_EVENTID = 0x1918, 1022 WMI_PCP_STARTED_EVENTID = 0x1918,
892 WMI_PCP_STOPPED_EVENTID = 0x1919, 1023 WMI_PCP_STOPPED_EVENTID = 0x1919,
893 WMI_PCP_FACTOR_EVENTID = 0x191A, 1024 WMI_PCP_FACTOR_EVENTID = 0x191A,
894 WMI_SET_CHANNEL_EVENTID = 0x9000, 1025 /* Power Save Configuration Events */
895 WMI_ASSOC_REQ_EVENTID = 0x9001, 1026 WMI_PS_DEV_PROFILE_CFG_EVENTID = 0x191C,
896 WMI_EAPOL_RX_EVENTID = 0x9002, 1027 /* Not supported yet */
897 WMI_MAC_ADDR_RESP_EVENTID = 0x9003, 1028 WMI_PS_DEV_CFG_EVENTID = 0x191D,
898 WMI_FW_VER_EVENTID = 0x9004, 1029 /* Not supported yet */
899 WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENTID = 0x9005, 1030 WMI_PS_DEV_CFG_READ_EVENTID = 0x191E,
1031 /* Not supported yet */
1032 WMI_PS_MID_CFG_EVENTID = 0x191F,
1033 /* Not supported yet */
1034 WMI_PS_MID_CFG_READ_EVENTID = 0x1920,
1035 WMI_RS_CFG_DONE_EVENTID = 0x1921,
1036 WMI_GET_DETAILED_RS_RES_EVENTID = 0x1922,
1037 WMI_AOA_MEAS_EVENTID = 0x1923,
1038 WMI_TOF_SESSION_END_EVENTID = 0x1991,
1039 WMI_TOF_GET_CAPABILITIES_EVENTID = 0x1992,
1040 WMI_TOF_SET_LCR_EVENTID = 0x1993,
1041 WMI_TOF_SET_LCI_EVENTID = 0x1994,
1042 WMI_TOF_FTM_PER_DEST_RES_EVENTID = 0x1995,
1043 WMI_TOF_CHANNEL_INFO_EVENTID = 0x1996,
1044 WMI_SET_CHANNEL_EVENTID = 0x9000,
1045 WMI_ASSOC_REQ_EVENTID = 0x9001,
1046 WMI_EAPOL_RX_EVENTID = 0x9002,
1047 WMI_MAC_ADDR_RESP_EVENTID = 0x9003,
1048 WMI_FW_VER_EVENTID = 0x9004,
1049 WMI_ACS_PASSIVE_SCAN_COMPLETE_EVENTID = 0x9005,
900}; 1050};
901 1051
902/* Events data structures */ 1052/* Events data structures */
@@ -943,10 +1093,85 @@ struct wmi_get_status_done_event {
943 1093
944/* WMI_FW_VER_EVENTID */ 1094/* WMI_FW_VER_EVENTID */
945struct wmi_fw_ver_event { 1095struct wmi_fw_ver_event {
946 u8 major; 1096 /* FW image version */
947 u8 minor; 1097 __le32 fw_major;
948 __le16 subminor; 1098 __le32 fw_minor;
949 __le16 build; 1099 __le32 fw_subminor;
1100 __le32 fw_build;
1101 /* FW image build time stamp */
1102 __le32 hour;
1103 __le32 minute;
1104 __le32 second;
1105 __le32 day;
1106 __le32 month;
1107 __le32 year;
1108 /* Boot Loader image version */
1109 __le32 bl_major;
1110 __le32 bl_minor;
1111 __le32 bl_subminor;
1112 __le32 bl_build;
1113 /* The number of entries in the FW capabilies array */
1114 u8 fw_capabilities_len;
1115 u8 reserved[3];
1116 /* FW capabilities info
1117 * Must be the last member of the struct
1118 */
1119 __le32 fw_capabilities[0];
1120} __packed;
1121
1122/* WMI_GET_RF_STATUS_EVENTID */
1123enum rf_type {
1124 RF_UNKNOWN = 0x00,
1125 RF_MARLON = 0x01,
1126 RF_SPARROW = 0x02,
1127};
1128
1129/* WMI_GET_RF_STATUS_EVENTID */
1130enum board_file_rf_type {
1131 BF_RF_MARLON = 0x00,
1132 BF_RF_SPARROW = 0x01,
1133};
1134
1135/* WMI_GET_RF_STATUS_EVENTID */
1136enum rf_status {
1137 RF_OK = 0x00,
1138 RF_NO_COMM = 0x01,
1139 RF_WRONG_BOARD_FILE = 0x02,
1140};
1141
1142/* WMI_GET_RF_STATUS_EVENTID */
1143struct wmi_get_rf_status_event {
1144 /* enum rf_type */
1145 __le32 rf_type;
1146 /* attached RFs bit vector */
1147 __le32 attached_rf_vector;
1148 /* enabled RFs bit vector */
1149 __le32 enabled_rf_vector;
1150 /* enum rf_status, refers to enabled RFs */
1151 u8 rf_status[32];
1152 /* enum board file RF type */
1153 __le32 board_file_rf_type;
1154 /* board file platform type */
1155 __le32 board_file_platform_type;
1156 /* board file version */
1157 __le32 board_file_version;
1158 __le32 reserved[2];
1159} __packed;
1160
1161/* WMI_GET_BASEBAND_TYPE_EVENTID */
1162enum baseband_type {
1163 BASEBAND_UNKNOWN = 0x00,
1164 BASEBAND_SPARROW_M_A0 = 0x03,
1165 BASEBAND_SPARROW_M_A1 = 0x04,
1166 BASEBAND_SPARROW_M_B0 = 0x05,
1167 BASEBAND_SPARROW_M_C0 = 0x06,
1168 BASEBAND_SPARROW_M_D0 = 0x07,
1169};
1170
1171/* WMI_GET_BASEBAND_TYPE_EVENTID */
1172struct wmi_get_baseband_type_event {
1173 /* enum baseband_type */
1174 __le32 baseband_type;
950} __packed; 1175} __packed;
951 1176
952/* WMI_MAC_ADDR_RESP_EVENTID */ 1177/* WMI_MAC_ADDR_RESP_EVENTID */
@@ -1410,4 +1635,553 @@ struct wmi_led_cfg_done_event {
1410 __le32 status; 1635 __le32 status;
1411} __packed; 1636} __packed;
1412 1637
1638#define WMI_NUM_MCS (13)
1639
1640/* Rate search parameters configuration per connection */
1641struct wmi_rs_cfg {
1642 /* The maximal allowed PER for each MCS
1643 * MCS will be considered as failed if PER during RS is higher
1644 */
1645 u8 per_threshold[WMI_NUM_MCS];
1646 /* Number of MPDUs for each MCS
1647 * this is the minimal statistic required to make an educated
1648 * decision
1649 */
1650 u8 min_frame_cnt[WMI_NUM_MCS];
1651 /* stop threshold [0-100] */
1652 u8 stop_th;
1653 /* MCS1 stop threshold [0-100] */
1654 u8 mcs1_fail_th;
1655 u8 max_back_failure_th;
1656 /* Debug feature for disabling internal RS trigger (which is
1657 * currently triggered by BF Done)
1658 */
1659 u8 dbg_disable_internal_trigger;
1660 __le32 back_failure_mask;
1661 __le32 mcs_en_vec;
1662} __packed;
1663
1664/* WMI_RS_CFG_CMDID */
1665struct wmi_rs_cfg_cmd {
1666 /* connection id */
1667 u8 cid;
1668 /* enable or disable rate search */
1669 u8 rs_enable;
1670 /* rate search configuration */
1671 struct wmi_rs_cfg rs_cfg;
1672} __packed;
1673
1674/* WMI_RS_CFG_DONE_EVENTID */
1675struct wmi_rs_cfg_done_event {
1676 u8 cid;
1677 /* enum wmi_fw_status */
1678 u8 status;
1679 u8 reserved[2];
1680} __packed;
1681
1682/* WMI_GET_DETAILED_RS_RES_CMDID */
1683struct wmi_get_detailed_rs_res_cmd {
1684 /* connection id */
1685 u8 cid;
1686 u8 reserved[3];
1687} __packed;
1688
1689/* RS results status */
1690enum wmi_rs_results_status {
1691 WMI_RS_RES_VALID = 0x00,
1692 WMI_RS_RES_INVALID = 0x01,
1693};
1694
1695/* Rate search results */
1696struct wmi_rs_results {
1697 /* number of sent MPDUs */
1698 u8 num_of_tx_pkt[WMI_NUM_MCS];
1699 /* number of non-acked MPDUs */
1700 u8 num_of_non_acked_pkt[WMI_NUM_MCS];
1701 /* RS timestamp */
1702 __le32 tsf;
1703 /* RS selected MCS */
1704 u8 mcs;
1705} __packed;
1706
1707/* WMI_GET_DETAILED_RS_RES_EVENTID */
1708struct wmi_get_detailed_rs_res_event {
1709 u8 cid;
1710 /* enum wmi_rs_results_status */
1711 u8 status;
1712 /* detailed rs results */
1713 struct wmi_rs_results rs_results;
1714 u8 reserved[3];
1715} __packed;
1716
1717/* broadcast connection ID */
1718#define WMI_LINK_MAINTAIN_CFG_CID_BROADCAST (0xFFFFFFFF)
1719
1720/* Types wmi_link_maintain_cfg presets for WMI_LINK_MAINTAIN_CFG_WRITE_CMD */
1721enum wmi_link_maintain_cfg_type {
1722 /* AP/PCP default normal (non-FST) configuration settings */
1723 WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_AP = 0x00,
1724 /* AP/PCP default FST configuration settings */
1725 WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_AP = 0x01,
1726 /* STA default normal (non-FST) configuration settings */
1727 WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_STA = 0x02,
1728 /* STA default FST configuration settings */
1729 WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_STA = 0x03,
1730 /* custom configuration settings */
1731 WMI_LINK_MAINTAIN_CFG_TYPE_CUSTOM = 0x04,
1732 /* number of defined configuration types */
1733 WMI_LINK_MAINTAIN_CFG_TYPES_NUM = 0x05,
1734};
1735
1736/* Response status codes for WMI_LINK_MAINTAIN_CFG_WRITE/READ commands */
1737enum wmi_link_maintain_cfg_response_status {
1738 /* WMI_LINK_MAINTAIN_CFG_WRITE/READ command successfully accomplished
1739 */
1740 WMI_LINK_MAINTAIN_CFG_RESPONSE_STATUS_OK = 0x00,
1741 /* ERROR due to bad argument in WMI_LINK_MAINTAIN_CFG_WRITE/READ
1742 * command request
1743 */
1744 WMI_LINK_MAINTAIN_CFG_RESPONSE_STATUS_BAD_ARGUMENT = 0x01,
1745};
1746
1747/* Link Loss and Keep Alive configuration */
1748struct wmi_link_maintain_cfg {
1749 /* link_loss_enable_detectors_vec */
1750 __le32 link_loss_enable_detectors_vec;
1751 /* detectors check period usec */
1752 __le32 check_link_loss_period_usec;
1753 /* max allowed tx ageing */
1754 __le32 tx_ageing_threshold_usec;
1755 /* keep alive period for high SNR */
1756 __le32 keep_alive_period_usec_high_snr;
1757 /* keep alive period for low SNR */
1758 __le32 keep_alive_period_usec_low_snr;
1759 /* lower snr limit for keep alive period update */
1760 __le32 keep_alive_snr_threshold_low_db;
1761 /* upper snr limit for keep alive period update */
1762 __le32 keep_alive_snr_threshold_high_db;
1763 /* num of successive bad bcons causing link-loss */
1764 __le32 bad_beacons_num_threshold;
1765 /* SNR limit for bad_beacons_detector */
1766 __le32 bad_beacons_snr_threshold_db;
1767} __packed;
1768
1769/* WMI_LINK_MAINTAIN_CFG_WRITE_CMDID */
1770struct wmi_link_maintain_cfg_write_cmd {
1771 /* enum wmi_link_maintain_cfg_type_e - type of requested default
1772 * configuration to be applied
1773 */
1774 __le32 cfg_type;
1775 /* requested connection ID or WMI_LINK_MAINTAIN_CFG_CID_BROADCAST */
1776 __le32 cid;
1777 /* custom configuration settings to be applied (relevant only if
1778 * cfg_type==WMI_LINK_MAINTAIN_CFG_TYPE_CUSTOM)
1779 */
1780 struct wmi_link_maintain_cfg lm_cfg;
1781} __packed;
1782
1783/* WMI_LINK_MAINTAIN_CFG_READ_CMDID */
1784struct wmi_link_maintain_cfg_read_cmd {
1785 /* connection ID which configuration settings are requested */
1786 __le32 cid;
1787} __packed;
1788
1789/* WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID */
1790struct wmi_link_maintain_cfg_write_done_event {
1791 /* requested connection ID */
1792 __le32 cid;
1793 /* wmi_link_maintain_cfg_response_status_e - write status */
1794 __le32 status;
1795} __packed;
1796
1797/* \WMI_LINK_MAINTAIN_CFG_READ_DONE_EVENT */
1798struct wmi_link_maintain_cfg_read_done_event {
1799 /* requested connection ID */
1800 __le32 cid;
1801 /* wmi_link_maintain_cfg_response_status_e - read status */
1802 __le32 status;
1803 /* Retrieved configuration settings */
1804 struct wmi_link_maintain_cfg lm_cfg;
1805} __packed;
1806
1807enum wmi_traffic_deferral_status {
1808 WMI_TRAFFIC_DEFERRAL_APPROVED = 0x0,
1809 WMI_TRAFFIC_DEFERRAL_REJECTED = 0x1,
1810};
1811
1812/* WMI_TRAFFIC_DEFERRAL_EVENTID */
1813struct wmi_traffic_deferral_event {
1814 /* enum wmi_traffic_deferral_status_e */
1815 u8 status;
1816} __packed;
1817
1818enum wmi_traffic_resume_status {
1819 WMI_TRAFFIC_RESUME_SUCCESS = 0x0,
1820 WMI_TRAFFIC_RESUME_FAILED = 0x1,
1821};
1822
1823/* WMI_TRAFFIC_RESUME_EVENTID */
1824struct wmi_traffic_resume_event {
1825 /* enum wmi_traffic_resume_status_e */
1826 u8 status;
1827} __packed;
1828
1829/* Power Save command completion status codes */
1830enum wmi_ps_cfg_cmd_status {
1831 WMI_PS_CFG_CMD_STATUS_SUCCESS = 0x00,
1832 WMI_PS_CFG_CMD_STATUS_BAD_PARAM = 0x01,
1833 /* other error */
1834 WMI_PS_CFG_CMD_STATUS_ERROR = 0x02,
1835};
1836
1837/* Device Power Save Profiles */
1838enum wmi_ps_profile_type {
1839 WMI_PS_PROFILE_TYPE_DEFAULT = 0x00,
1840 WMI_PS_PROFILE_TYPE_PS_DISABLED = 0x01,
1841 WMI_PS_PROFILE_TYPE_MAX_PS = 0x02,
1842 WMI_PS_PROFILE_TYPE_LOW_LATENCY_PS = 0x03,
1843};
1844
1845/* WMI_PS_DEV_PROFILE_CFG_CMDID
1846 *
1847 * Power save profile to be used by the device
1848 *
1849 * Returned event:
1850 * - WMI_PS_DEV_PROFILE_CFG_EVENTID
1851 */
1852struct wmi_ps_dev_profile_cfg_cmd {
1853 /* wmi_ps_profile_type_e */
1854 u8 ps_profile;
1855 u8 reserved[3];
1856} __packed;
1857
1858/* WMI_PS_DEV_PROFILE_CFG_EVENTID */
1859struct wmi_ps_dev_profile_cfg_event {
1860 /* wmi_ps_cfg_cmd_status_e */
1861 __le32 status;
1862} __packed;
1863
1864enum wmi_ps_level {
1865 WMI_PS_LEVEL_DEEP_SLEEP = 0x00,
1866 WMI_PS_LEVEL_SHALLOW_SLEEP = 0x01,
1867 /* awake = all PS mechanisms are disabled */
1868 WMI_PS_LEVEL_AWAKE = 0x02,
1869};
1870
1871enum wmi_ps_deep_sleep_clk_level {
1872 /* 33k */
1873 WMI_PS_DEEP_SLEEP_CLK_LEVEL_RTC = 0x00,
1874 /* 10k */
1875 WMI_PS_DEEP_SLEEP_CLK_LEVEL_OSC = 0x01,
1876 /* @RTC Low latency */
1877 WMI_PS_DEEP_SLEEP_CLK_LEVEL_RTC_LT = 0x02,
1878 WMI_PS_DEEP_SLEEP_CLK_LEVEL_XTAL = 0x03,
1879 WMI_PS_DEEP_SLEEP_CLK_LEVEL_SYSCLK = 0x04,
1880 /* Not Applicable */
1881 WMI_PS_DEEP_SLEEP_CLK_LEVEL_N_A = 0xFF,
1882};
1883
1884/* Response by the FW to a D3 entry request */
1885enum wmi_ps_d3_resp_policy {
1886 WMI_PS_D3_RESP_POLICY_DEFAULT = 0x00,
1887 /* debug -D3 req is always denied */
1888 WMI_PS_D3_RESP_POLICY_DENIED = 0x01,
1889 /* debug -D3 req is always approved */
1890 WMI_PS_D3_RESP_POLICY_APPROVED = 0x02,
1891};
1892
1893/* Device common power save configurations */
1894struct wmi_ps_dev_cfg {
1895 /* lowest level of PS allowed while unassociated, enum wmi_ps_level_e
1896 */
1897 u8 ps_unassoc_min_level;
1898 /* lowest deep sleep clock level while nonassoc, enum
1899 * wmi_ps_deep_sleep_clk_level_e
1900 */
1901 u8 ps_unassoc_deep_sleep_min_level;
1902 /* lowest level of PS allowed while associated, enum wmi_ps_level_e */
1903 u8 ps_assoc_min_level;
1904 /* lowest deep sleep clock level while assoc, enum
1905 * wmi_ps_deep_sleep_clk_level_e
1906 */
1907 u8 ps_assoc_deep_sleep_min_level;
1908 /* enum wmi_ps_deep_sleep_clk_level_e */
1909 u8 ps_assoc_low_latency_ds_min_level;
1910 /* enum wmi_ps_d3_resp_policy_e */
1911 u8 ps_D3_response_policy;
1912 /* BOOL */
1913 u8 ps_D3_pm_pme_enabled;
1914 /* BOOL */
1915 u8 ps_halp_enable;
1916 u8 ps_deep_sleep_enter_thresh_msec;
1917 /* BOOL */
1918 u8 ps_voltage_scaling_en;
1919} __packed;
1920
1921/* WMI_PS_DEV_CFG_CMDID
1922 *
1923 * Configure common Power Save parameters of the device and all MIDs.
1924 *
1925 * Returned event:
1926 * - WMI_PS_DEV_CFG_EVENTID
1927 */
1928struct wmi_ps_dev_cfg_cmd {
1929 /* Device Power Save configuration to be applied */
1930 struct wmi_ps_dev_cfg ps_dev_cfg;
1931 /* alignment to 32b */
1932 u8 reserved[2];
1933} __packed;
1934
1935/* WMI_PS_DEV_CFG_EVENTID */
1936struct wmi_ps_dev_cfg_event {
1937 /* wmi_ps_cfg_cmd_status_e */
1938 __le32 status;
1939} __packed;
1940
1941/* WMI_PS_DEV_CFG_READ_CMDID
1942 *
1943 * request to retrieve device Power Save configuration
1944 * (WMI_PS_DEV_CFG_CMD params)
1945 *
1946 * Returned event:
1947 * - WMI_PS_DEV_CFG_READ_EVENTID
1948 */
1949struct wmi_ps_dev_cfg_read_cmd {
1950 __le32 reserved;
1951} __packed;
1952
1953/* WMI_PS_DEV_CFG_READ_EVENTID */
1954struct wmi_ps_dev_cfg_read_event {
1955 /* wmi_ps_cfg_cmd_status_e */
1956 __le32 status;
1957 /* Retrieved device Power Save configuration (WMI_PS_DEV_CFG_CMD
1958 * params)
1959 */
1960 struct wmi_ps_dev_cfg dev_ps_cfg;
1961 /* alignment to 32b */
1962 u8 reserved[2];
1963} __packed;
1964
1965/* Per Mac Power Save configurations */
1966struct wmi_ps_mid_cfg {
1967 /* Low power RX in BTI is enabled, BOOL */
1968 u8 beacon_lprx_enable;
1969 /* Sync to sector ID enabled, BOOL */
1970 u8 beacon_sync_to_sectorId_enable;
1971 /* Low power RX in DTI is enabled, BOOL */
1972 u8 frame_exchange_lprx_enable;
1973 /* Sleep Cycle while in scheduled PS, 1-31 */
1974 u8 scheduled_sleep_cycle_pow2;
1975 /* Stay Awake for k BIs every (sleep_cycle - k) BIs, 1-31 */
1976 u8 scheduled_num_of_awake_bis;
1977 u8 am_to_traffic_load_thresh_mbp;
1978 u8 traffic_to_am_load_thresh_mbps;
1979 u8 traffic_to_am_num_of_no_traffic_bis;
1980 /* BOOL */
1981 u8 continuous_traffic_psm;
1982 __le16 no_traffic_to_min_usec;
1983 __le16 no_traffic_to_max_usec;
1984 __le16 snoozing_sleep_interval_milisec;
1985 u8 max_no_data_awake_events;
1986 /* Trigger WEB after k failed beacons */
1987 u8 num_of_failed_beacons_rx_to_trigger_web;
1988 /* Trigger BF after k failed beacons */
1989 u8 num_of_failed_beacons_rx_to_trigger_bf;
1990 /* Trigger SOB after k successful beacons */
1991 u8 num_of_successful_beacons_rx_to_trigger_sob;
1992} __packed;
1993
1994/* WMI_PS_MID_CFG_CMDID
1995 *
1996 * Configure Power Save parameters of a specific MID.
1997 * These parameters are relevant for the specific BSS this MID belongs to.
1998 *
1999 * Returned event:
2000 * - WMI_PS_MID_CFG_EVENTID
2001 */
2002struct wmi_ps_mid_cfg_cmd {
2003 /* MAC ID */
2004 u8 mid;
2005 /* mid PS configuration to be applied */
2006 struct wmi_ps_mid_cfg ps_mid_cfg;
2007} __packed;
2008
2009/* WMI_PS_MID_CFG_EVENTID */
2010struct wmi_ps_mid_cfg_event {
2011 /* MAC ID */
2012 u8 mid;
2013 /* alignment to 32b */
2014 u8 reserved[3];
2015 /* wmi_ps_cfg_cmd_status_e */
2016 __le32 status;
2017} __packed;
2018
2019/* WMI_PS_MID_CFG_READ_CMDID
2020 *
2021 * request to retrieve Power Save configuration of mid
2022 * (WMI_PS_MID_CFG_CMD params)
2023 *
2024 * Returned event:
2025 * - WMI_PS_MID_CFG_READ_EVENTID
2026 */
2027struct wmi_ps_mid_cfg_read_cmd {
2028 /* MAC ID */
2029 u8 mid;
2030 /* alignment to 32b */
2031 u8 reserved[3];
2032} __packed;
2033
2034/* WMI_PS_MID_CFG_READ_EVENTID */
2035struct wmi_ps_mid_cfg_read_event {
2036 /* MAC ID */
2037 u8 mid;
2038 /* Retrieved MID Power Save configuration(WMI_PS_MID_CFG_CMD params) */
2039 struct wmi_ps_mid_cfg mid_ps_cfg;
2040 /* wmi_ps_cfg_cmd_status_e */
2041 __le32 status;
2042} __packed;
2043
2044#define WMI_AOA_MAX_DATA_SIZE (128)
2045
2046enum wmi_aoa_meas_status {
2047 WMI_AOA_MEAS_SUCCESS = 0x00,
2048 WMI_AOA_MEAS_PEER_INCAPABLE = 0x01,
2049 WMI_AOA_MEAS_FAILURE = 0x02,
2050};
2051
2052/* WMI_AOA_MEAS_EVENTID */
2053struct wmi_aoa_meas_event {
2054 u8 mac_addr[WMI_MAC_LEN];
2055 /* channels IDs:
2056 * 0 - 58320 MHz
2057 * 1 - 60480 MHz
2058 * 2 - 62640 MHz
2059 */
2060 u8 channel;
2061 /* enum wmi_aoa_meas_type */
2062 u8 aoa_meas_type;
2063 /* Measurments are from RFs, defined by the mask */
2064 __le32 meas_rf_mask;
2065 /* enum wmi_aoa_meas_status */
2066 u8 meas_status;
2067 u8 reserved;
2068 /* Length of meas_data in bytes */
2069 __le16 length;
2070 u8 meas_data[WMI_AOA_MAX_DATA_SIZE];
2071} __packed;
2072
2073/* WMI_TOF_GET_CAPABILITIES_EVENTID */
2074struct wmi_tof_get_capabilities_event {
2075 u8 ftm_capability;
2076 /* maximum supported number of destination to start TOF */
2077 u8 max_num_of_dest;
2078 /* maximum supported number of measurements per burst */
2079 u8 max_num_of_meas_per_burst;
2080 u8 reserved;
2081 /* maximum supported multi bursts */
2082 __le16 max_multi_bursts_sessions;
2083 /* maximum supported FTM burst duration , wmi_tof_burst_duration_e */
2084 __le16 max_ftm_burst_duration;
2085 /* AOA supported types */
2086 __le32 aoa_supported_types;
2087} __packed;
2088
2089enum wmi_tof_session_end_status {
2090 WMI_TOF_SESSION_END_NO_ERROR = 0x00,
2091 WMI_TOF_SESSION_END_FAIL = 0x01,
2092 WMI_TOF_SESSION_END_PARAMS_ERROR = 0x02,
2093 WMI_TOF_SESSION_END_ABORTED = 0x03,
2094};
2095
2096/* WMI_TOF_SESSION_END_EVENTID */
2097struct wmi_tof_session_end_event {
2098 /* FTM session ID */
2099 __le32 session_id;
2100 /* wmi_tof_session_end_status_e */
2101 u8 status;
2102 u8 reserved[3];
2103} __packed;
2104
2105/* Responder FTM Results */
2106struct wmi_responder_ftm_res {
2107 u8 t1[6];
2108 u8 t2[6];
2109 u8 t3[6];
2110 u8 t4[6];
2111 __le16 tod_err;
2112 __le16 toa_err;
2113 __le16 tod_err_initiator;
2114 __le16 toa_err_initiator;
2115} __packed;
2116
2117enum wmi_tof_ftm_per_dest_res_status {
2118 WMI_PER_DEST_RES_NO_ERROR = 0x00,
2119 WMI_PER_DEST_RES_TX_RX_FAIL = 0x01,
2120 WMI_PER_DEST_RES_PARAM_DONT_MATCH = 0x02,
2121};
2122
2123enum wmi_tof_ftm_per_dest_res_flags {
2124 WMI_PER_DEST_RES_REQ_START = 0x01,
2125 WMI_PER_DEST_RES_BURST_REPORT_END = 0x02,
2126 WMI_PER_DEST_RES_REQ_END = 0x04,
2127 WMI_PER_DEST_RES_PARAM_UPDATE = 0x08,
2128};
2129
2130/* WMI_TOF_FTM_PER_DEST_RES_EVENTID */
2131struct wmi_tof_ftm_per_dest_res_event {
2132 /* FTM session ID */
2133 __le32 session_id;
2134 /* destination MAC address */
2135 u8 dst_mac[WMI_MAC_LEN];
2136 /* wmi_tof_ftm_per_dest_res_flags_e */
2137 u8 flags;
2138 /* wmi_tof_ftm_per_dest_res_status_e */
2139 u8 status;
2140 /* responder ASAP */
2141 u8 responder_asap;
2142 /* responder number of FTM per burst */
2143 u8 responder_num_ftm_per_burst;
2144 /* responder number of FTM burst exponent */
2145 u8 responder_num_ftm_bursts_exp;
2146 /* responder burst duration ,wmi_tof_burst_duration_e */
2147 u8 responder_burst_duration;
2148 /* responder burst period, indicate interval between two consecutive
2149 * burst instances, in units of 100 ms
2150 */
2151 __le16 responder_burst_period;
2152 /* receive burst counter */
2153 __le16 bursts_cnt;
2154 /* tsf of responder start burst */
2155 __le32 tsf_sync;
2156 /* actual received ftm per burst */
2157 u8 actual_ftm_per_burst;
2158 u8 reserved0[7];
2159 struct wmi_responder_ftm_res responder_ftm_res[0];
2160} __packed;
2161
2162enum wmi_tof_channel_info_type {
2163 WMI_TOF_CHANNEL_INFO_AOA = 0x00,
2164 WMI_TOF_CHANNEL_INFO_LCI = 0x01,
2165 WMI_TOF_CHANNEL_INFO_LCR = 0x02,
2166 WMI_TOF_CHANNEL_INFO_VENDOR_SPECIFIC = 0x03,
2167 WMI_TOF_CHANNEL_INFO_CIR = 0x04,
2168 WMI_TOF_CHANNEL_INFO_RSSI = 0x05,
2169 WMI_TOF_CHANNEL_INFO_SNR = 0x06,
2170 WMI_TOF_CHANNEL_INFO_DEBUG = 0x07,
2171};
2172
2173/* WMI_TOF_CHANNEL_INFO_EVENTID */
2174struct wmi_tof_channel_info_event {
2175 /* FTM session ID */
2176 __le32 session_id;
2177 /* destination MAC address */
2178 u8 dst_mac[WMI_MAC_LEN];
2179 /* wmi_tof_channel_info_type_e */
2180 u8 type;
2181 /* data report length */
2182 u8 len;
2183 /* data report payload */
2184 u8 report[0];
2185} __packed;
2186
1413#endif /* __WILOCITY_WMI_H__ */ 2187#endif /* __WILOCITY_WMI_H__ */