diff options
| author | Kalle Valo <kvalo@codeaurora.org> | 2016-09-14 12:34:50 -0400 |
|---|---|---|
| committer | Kalle Valo <kvalo@codeaurora.org> | 2016-09-14 12:34:50 -0400 |
| commit | af1afc2957d63f84a37b168e56be7a7ef6b43650 (patch) | |
| tree | 943688e1340b28032ec3b8c8c60e2b4be54759a5 /drivers/net/wireless/ath | |
| parent | 75696fe704774039e0e2ca65be24d79739ed206d (diff) | |
| parent | 95b5bf7ccca0d7ba575a7e26a7ed4146b9190071 (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')
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) | |||
| 462 | static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg) | 462 | static 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 | ||
| 722 | static int ath10k_ahb_hif_power_up(struct ath10k *ar) | 725 | static 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 | ||
| 309 | static unsigned int ath10k_core_get_fw_feature_str(char *buf, | 317 | static 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 | ||
| 1716 | static 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 | |||
| 1708 | int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, | 1765 | int 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 | |||
| 68 | struct ath10k; | 72 | struct ath10k; |
| 69 | 73 | ||
| 70 | enum ath10k_bus { | 74 | enum 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 | ||
| 668 | struct ath10k_fw_components { | 689 | struct 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); |
| 1799 | void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar, | 1798 | void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar, |
| 1800 | struct sk_buff *skb); | 1799 | struct sk_buff *skb); |
| 1800 | int 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 | ||
| 36 | static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); | 36 | static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); |
| 37 | static void ath10k_htt_txrx_compl_task(unsigned long ptr); | ||
| 38 | 37 | ||
| 39 | static struct sk_buff * | 38 | static struct sk_buff * |
| 40 | ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr) | 39 | ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr) |
| @@ -226,7 +225,6 @@ int ath10k_htt_rx_ring_refill(struct ath10k *ar) | |||
| 226 | void ath10k_htt_rx_free(struct ath10k_htt *htt) | 225 | void 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 | ||
| 964 | static int ath10k_htt_rx_nwifi_hdrlen(struct ath10k *ar, | 959 | static 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, | |||
| 1525 | static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) | 1528 | static 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 | ||
| 1561 | static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt, | 1565 | static 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 | |||
| 1586 | static 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 | ||
| 1593 | static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, | 1588 | static 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 | ||
| 1775 | static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar, | 1770 | static 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 | ||
| 1825 | static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) | 1823 | static 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 | ||
| 1910 | static void ath10k_htt_rx_tx_fetch_resp_id_confirm(struct ath10k *ar, | 1910 | static 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 | } |
| 2377 | EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler); | 2374 | EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler); |
| 2378 | 2375 | ||
| 2379 | static void ath10k_htt_txrx_compl_task(unsigned long ptr) | 2376 | int 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 | ||
| 2467 | exit: | ||
| 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 | } |
| 2476 | EXPORT_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 | |||
| 223 | const struct ath10k_hw_ops qca988x_ops = { | ||
| 224 | }; | ||
| 225 | |||
| 226 | static 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 | |||
| 232 | const 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 | ||
| 341 | enum ath10k_hw_4addr_pad { | ||
| 342 | ATH10K_HW_4ADDR_PAD_AFTER, | ||
| 343 | ATH10K_HW_4ADDR_PAD_BEFORE, | ||
| 344 | }; | ||
| 345 | |||
| 346 | enum ath10k_hw_cc_wraparound_type { | 341 | enum 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 | ||
| 361 | struct 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 | |||
| 413 | struct htt_rx_desc; | ||
| 414 | |||
| 415 | /* Defines needed for Rx descriptor abstraction */ | ||
| 416 | struct ath10k_hw_ops { | ||
| 417 | int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd); | ||
| 418 | }; | ||
| 419 | |||
| 420 | extern const struct ath10k_hw_ops qca988x_ops; | ||
| 421 | extern const struct ath10k_hw_ops qca99x0_ops; | ||
| 422 | |||
| 423 | static inline int | ||
| 424 | ath10k_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 | ||
| 1509 | void ath10k_pci_kill_tasklet(struct ath10k *ar) | 1509 | static 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 | ||
| 1573 | static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar) | 1571 | void 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) | |||
| 1693 | static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe) | 1691 | static 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 | ||
| 1754 | void ath10k_pci_flush(struct ath10k *ar) | 1750 | void 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 | ||
| 2727 | err_free: | 2726 | err_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 | ||
| 2787 | static void ath10k_pci_tasklet(unsigned long data) | 2785 | static 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 | |||
| 2819 | out: | ||
| 2820 | return done; | ||
| 2804 | } | 2821 | } |
| 2805 | 2822 | ||
| 2806 | static int ath10k_pci_request_irq_msi(struct ath10k *ar) | 2823 | static 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 | ||
| 2861 | void ath10k_pci_init_irq_tasklets(struct ath10k *ar) | 2878 | void 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 | ||
| 2868 | static int ath10k_pci_init_irq(struct ath10k *ar) | 2884 | static 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 | ||
| 3068 | err_master: | 3084 | err_master: |
| @@ -3131,7 +3147,8 @@ int ath10k_pci_setup_resource(struct ath10k *ar) | |||
| 3131 | 3147 | ||
| 3132 | void ath10k_pci_release_resource(struct ath10k *ar) | 3148 | void 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 | ||
| 3299 | err_free_irq: | 3315 | err_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 | ||
| 3303 | err_deinit_irq: | 3319 | err_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); | |||
| 294 | void ath10k_pci_free_pipes(struct ath10k *ar); | 292 | void ath10k_pci_free_pipes(struct ath10k *ar); |
| 295 | void ath10k_pci_rx_replenish_retry(unsigned long ptr); | 293 | void ath10k_pci_rx_replenish_retry(unsigned long ptr); |
| 296 | void ath10k_pci_ce_deinit(struct ath10k *ar); | 294 | void ath10k_pci_ce_deinit(struct ath10k *ar); |
| 297 | void ath10k_pci_init_irq_tasklets(struct ath10k *ar); | 295 | void ath10k_pci_init_napi(struct ath10k *ar); |
| 298 | void ath10k_pci_kill_tasklet(struct ath10k *ar); | ||
| 299 | int ath10k_pci_init_pipes(struct ath10k *ar); | 296 | int ath10k_pci_init_pipes(struct ath10k *ar); |
| 300 | int ath10k_pci_init_config(struct ath10k *ar); | 297 | int ath10k_pci_init_config(struct ath10k *ar); |
| 301 | void ath10k_pci_rx_post(struct ath10k *ar); | 298 | void ath10k_pci_rx_post(struct ath10k *ar); |
| @@ -303,6 +300,7 @@ void ath10k_pci_flush(struct ath10k *ar); | |||
| 303 | void ath10k_pci_enable_legacy_irq(struct ath10k *ar); | 300 | void ath10k_pci_enable_legacy_irq(struct ath10k *ar); |
| 304 | bool ath10k_pci_irq_pending(struct ath10k *ar); | 301 | bool ath10k_pci_irq_pending(struct ath10k *ar); |
| 305 | void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar); | 302 | void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar); |
| 303 | void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar); | ||
| 306 | int ath10k_pci_wait_for_target_init(struct ath10k *ar); | 304 | int ath10k_pci_wait_for_target_init(struct ath10k *ar); |
| 307 | int ath10k_pci_setup_resource(struct ath10k *ar); | 305 | int ath10k_pci_setup_resource(struct ath10k *ar); |
| 308 | void ath10k_pci_release_resource(struct ath10k *ar); | 306 | void 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 | ||
| 137 | int ath10k_swap_code_seg_configure(struct ath10k *ar) | 137 | int 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 | ||
| 161 | void ath10k_swap_code_seg_release(struct ath10k *ar) | 162 | void 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 | ||
| 174 | int ath10k_swap_code_seg_init(struct ath10k *ar) | 176 | int 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 | ||
| 26 | struct ath10k_fw_file; | ||
| 27 | |||
| 26 | struct ath10k_swap_code_seg_tlv { | 28 | struct 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 | ||
| 61 | int ath10k_swap_code_seg_configure(struct ath10k *ar); | 63 | int ath10k_swap_code_seg_configure(struct ath10k *ar, |
| 62 | void ath10k_swap_code_seg_release(struct ath10k *ar); | 64 | const struct ath10k_fw_file *fw_file); |
| 63 | int ath10k_swap_code_seg_init(struct ath10k *ar); | 65 | void ath10k_swap_code_seg_release(struct ath10k *ar, |
| 66 | struct ath10k_fw_file *fw_file); | ||
| 67 | int 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 | ||
| 281 | err_release_utf_mode_fw: | 294 | err_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); |
| 48 | out: | 48 | out: |
| 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 | ||
| 199 | int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); | 202 | int 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 | ||
| 355 | static inline int | ||
| 356 | ath10k_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 | |||
| 352 | static inline enum wmi_txbf_conf | 365 | static inline enum wmi_txbf_conf |
| 353 | ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar) | 366 | ath10k_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 | ||
| 934 | static inline int | 947 | static inline int |
| 935 | ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable, u32 log_level) | 948 | ath10k_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 | ||
| 1398 | static inline int | ||
| 1399 | ath10k_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 | ||
| 1226 | static 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 | |||
| 1226 | static struct sk_buff * | 1253 | static struct sk_buff * |
| 1227 | ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt) | 1254 | ath10k_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 | ||
| 2443 | static struct sk_buff * | 2470 | static struct sk_buff * |
| 2444 | ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable, | 2471 | ath10k_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 | ||
| 3111 | static struct sk_buff * | ||
| 3112 | ath10k_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 | ||
| 3490 | static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { | 3547 | static 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 */ |
| 33 | static struct wmi_cmd_map wmi_cmd_map = { | 36 | static 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 | ||
| 2246 | static 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 | |||
| 2243 | int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | 2269 | int 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 | ||
| 2496 | void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) | 2518 | void 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 | ||
| 2501 | int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) | 2537 | int 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 | ||
| 4830 | static 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 | |||
| 4795 | int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) | 4841 | int 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 | ||
| 6865 | static struct sk_buff * | 6938 | static struct sk_buff * |
| 6866 | ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable, | 6939 | ath10k_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 | ||
| 6903 | static struct sk_buff * | 6976 | static struct sk_buff * |
| 6977 | ath10k_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 | |||
| 7014 | static struct sk_buff * | ||
| 6904 | ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap) | 7015 | ath10k_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 | ||
| 7763 | static struct sk_buff * | ||
| 7764 | ath10k_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 | |||
| 7781 | int | ||
| 7782 | ath10k_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 | |||
| 7652 | static const struct wmi_ops wmi_ops = { | 7805 | static 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 | ||
| 7989 | int ath10k_wmi_attach(struct ath10k *ar) | 8152 | int 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 | ||
| 6177 | struct 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 | |||
| 6172 | enum wmi_roam_reason { | 6191 | enum 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 | ||
| 6318 | struct wmi_echo_ev_arg { | ||
| 6319 | __le32 value; | ||
| 6320 | }; | ||
| 6321 | |||
| 6299 | struct wmi_pdev_temperature_event { | 6322 | struct 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); |
| 6625 | int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, | 6648 | int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, |
| 6626 | enum wmi_vdev_subtype subtype); | 6649 | enum wmi_vdev_subtype subtype); |
| 6650 | int 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 | } |
| 65 | EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler); | 65 | EXPORT_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 | ||
| 70 | static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) | 70 | static 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 *)®dump_val[0], | 94 | ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)®dump_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 | ||
| 25 | void ath_fill_led_pin(struct ath_softc *sc) | 25 | static 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] = { | |||
| 50 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | 50 | static 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); |
| 52 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 52 | static 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); | ||
| 54 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 55 | static 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); |
| 57 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 59 | static 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 | ||
| 82 | static 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 | |||
| 80 | void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) | 98 | void 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) | |||
| 92 | void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) | 110 | void 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 | ||
| 106 | static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq, | 125 | static 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 | ||
| 427 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | 446 | static 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 | */ |
| 1833 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq) | 1858 | void 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 | ||
| 1855 | bool ath_drain_all_txq(struct ath_softc *sc) | 1882 | bool 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 | ||
| 2474 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 2501 | static 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 | ||
| 2522 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 2553 | static 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 | } |
| 2553 | skip_tx_complete: | 2585 | skip_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 | ||
| 2709 | void ath_tx_edma_tasklet(struct ath_softc *sc) | 2743 | void 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 | ||
| 763 | static struct wil_tid_crypto_rx_single * | 766 | static struct wil_sta_info * |
| 764 | wil_find_crypto_ctx(struct wil6210_priv *wil, u8 key_index, | 767 | wil_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 | 789 | static 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 | |||
| 824 | static 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 | ||
| 795 | static int wil_cfg80211_add_key(struct wiphy *wiphy, | 849 | static 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 | ||
| 1385 | static struct cfg80211_ops wil_cfg80211_ops = { | 1427 | static 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 | ||
| 1473 | out_failed_reg: | ||
| 1474 | wiphy_free(wdev->wiphy); | ||
| 1475 | out: | 1511 | out: |
| 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------------*/ | ||
| 1557 | static 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 | |||
| 1567 | static 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 | |||
| 1573 | static 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------------*/ | ||
| 1581 | static 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 | |||
| 1593 | static 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 | |||
| 1599 | static 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 | /*----------------*/ |
| 1557 | static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil, | 1607 | static 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 | ||
| 1608 | static void wil6210_debugfs_init_files(struct wil6210_priv *wil, | 1660 | static void wil6210_debugfs_init_files(struct wil6210_priv *wil, |
| @@ -1643,7 +1695,6 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil, | |||
| 1643 | static const struct dbg_off dbg_wil_off[] = { | 1695 | static 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) | ||
| 63 | struct 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) | ||
| 96 | struct wil_fw_record_file_header { | 108 | struct 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 | ||
| 121 | static int fw_ignore_section(struct wil6210_priv *wil, const void *data, | ||
| 122 | size_t size) | ||
| 123 | { | ||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 121 | static int fw_handle_comment(struct wil6210_priv *wil, const void *data, | 127 | static 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 | ||
| 135 | static int | ||
| 136 | fw_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 | |||
| 129 | static int fw_handle_data(struct wil6210_priv *wil, const void *data, | 156 | static 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 | ||
| 384 | static const struct { | 418 | static 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 | ||
| 399 | static int wil_fw_handle_record(struct wil6210_priv *wil, int type, | 438 | static 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 | */ |
| 421 | static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size) | 463 | static 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 | */ |
| 465 | int wil_request_firmware(struct wil6210_priv *wil, const char *name) | 510 | int 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 | ||
| 104 | static void wil6210_mask_halp(struct wil6210_priv *wil) | 104 | void 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 | ||
| 593 | void wil6210_set_halp(struct wil6210_priv *wil) | 600 | void 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 | ||
| 601 | void wil6210_clear_halp(struct wil6210_priv *wil) | 608 | void 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 | ||
| 1036 | int __wil_down(struct wil6210_priv *wil) | 1042 | int __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 | ||
| 217 | int wil_if_add(struct wil6210_priv *wil) | 210 | int 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 | |||
| 242 | out_wiphy: | ||
| 243 | wiphy_unregister(wdev->wiphy); | ||
| 244 | return rc; | ||
| 231 | } | 245 | } |
| 232 | 246 | ||
| 233 | void wil_if_remove(struct wil6210_priv *wil) | 247 | void 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 | |||
| 267 | void 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 | |||
| 308 | out: | ||
| 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 | ||
| 24 | static bool use_msi = true; | 25 | static bool use_msi = true; |
| 25 | module_param(use_msi, bool, S_IRUGO); | 26 | module_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 | ||
| 56 | void wil_disable_irq(struct wil6210_priv *wil) | 61 | void 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); | |||
| 828 | void wil_configure_interrupt_moderation(struct wil6210_priv *wil); | 830 | void wil_configure_interrupt_moderation(struct wil6210_priv *wil); |
| 829 | void wil_disable_irq(struct wil6210_priv *wil); | 831 | void wil_disable_irq(struct wil6210_priv *wil); |
| 830 | void wil_enable_irq(struct wil6210_priv *wil); | 832 | void wil_enable_irq(struct wil6210_priv *wil); |
| 833 | void wil6210_mask_halp(struct wil6210_priv *wil); | ||
| 831 | 834 | ||
| 832 | /* P2P */ | 835 | /* P2P */ |
| 833 | bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); | 836 | bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); |
| @@ -840,6 +843,7 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil); | |||
| 840 | int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie); | 843 | int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie); |
| 841 | void wil_p2p_listen_expired(struct work_struct *work); | 844 | void wil_p2p_listen_expired(struct work_struct *work); |
| 842 | void wil_p2p_search_expired(struct work_struct *work); | 845 | void wil_p2p_search_expired(struct work_struct *work); |
| 846 | void wil_p2p_stop_radio_operations(struct wil6210_priv *wil); | ||
| 843 | 847 | ||
| 844 | /* WMI for P2P */ | 848 | /* WMI for P2P */ |
| 845 | int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi); | 849 | int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi); |
| @@ -893,7 +897,8 @@ void wil6210_unmask_irq_rx(struct wil6210_priv *wil); | |||
| 893 | int wil_iftype_nl2wmi(enum nl80211_iftype type); | 897 | int wil_iftype_nl2wmi(enum nl80211_iftype type); |
| 894 | 898 | ||
| 895 | int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd); | 899 | int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd); |
| 896 | int wil_request_firmware(struct wil6210_priv *wil, const char *name); | 900 | int wil_request_firmware(struct wil6210_priv *wil, const char *name, |
| 901 | bool load); | ||
| 897 | 902 | ||
| 898 | int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime); | 903 | int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime); |
| 899 | int wil_suspend(struct wil6210_priv *wil, bool is_runtime); | 904 | int 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) | |||
| 424 | static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, | 424 | static 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 | ||
| 448 | static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) | 448 | static 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 | */ | ||
| 53 | enum 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 */ |
| 50 | struct wmi_cmd_hdr { | 60 | struct 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 */ |
| 292 | struct wmi_start_scan_cmd { | 329 | struct 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 */ | ||
| 493 | struct 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 */ |
| 457 | enum wmi_discovery_mode { | 499 | enum 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 | ||
| 863 | enum wmi_aoa_meas_type { | ||
| 864 | WMI_AOA_PHASE_MEAS = 0x00, | ||
| 865 | WMI_AOA_PHASE_AMP_MEAS = 0x01, | ||
| 866 | }; | ||
| 867 | |||
| 868 | /* WMI_AOA_MEAS_CMDID */ | ||
| 869 | struct 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 | |||
| 882 | enum 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 | |||
| 896 | enum 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 */ | ||
| 904 | struct 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 */ | ||
| 922 | struct 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 | |||
| 931 | enum 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 */ | ||
| 940 | struct 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 | */ |
| 824 | enum wmi_event_id { | 948 | enum 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 */ |
| 945 | struct wmi_fw_ver_event { | 1095 | struct 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 */ | ||
| 1123 | enum rf_type { | ||
| 1124 | RF_UNKNOWN = 0x00, | ||
| 1125 | RF_MARLON = 0x01, | ||
| 1126 | RF_SPARROW = 0x02, | ||
| 1127 | }; | ||
| 1128 | |||
| 1129 | /* WMI_GET_RF_STATUS_EVENTID */ | ||
| 1130 | enum board_file_rf_type { | ||
| 1131 | BF_RF_MARLON = 0x00, | ||
| 1132 | BF_RF_SPARROW = 0x01, | ||
| 1133 | }; | ||
| 1134 | |||
| 1135 | /* WMI_GET_RF_STATUS_EVENTID */ | ||
| 1136 | enum 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 */ | ||
| 1143 | struct 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 */ | ||
| 1162 | enum 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 */ | ||
| 1172 | struct 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 */ | ||
| 1641 | struct 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 */ | ||
| 1665 | struct 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 */ | ||
| 1675 | struct 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 */ | ||
| 1683 | struct wmi_get_detailed_rs_res_cmd { | ||
| 1684 | /* connection id */ | ||
| 1685 | u8 cid; | ||
| 1686 | u8 reserved[3]; | ||
| 1687 | } __packed; | ||
| 1688 | |||
| 1689 | /* RS results status */ | ||
| 1690 | enum wmi_rs_results_status { | ||
| 1691 | WMI_RS_RES_VALID = 0x00, | ||
| 1692 | WMI_RS_RES_INVALID = 0x01, | ||
| 1693 | }; | ||
| 1694 | |||
| 1695 | /* Rate search results */ | ||
| 1696 | struct 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 */ | ||
| 1708 | struct 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 */ | ||
| 1721 | enum 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 */ | ||
| 1737 | enum 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 */ | ||
| 1748 | struct 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 */ | ||
| 1770 | struct 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 */ | ||
| 1784 | struct 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 */ | ||
| 1790 | struct 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 */ | ||
| 1798 | struct 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 | |||
| 1807 | enum wmi_traffic_deferral_status { | ||
| 1808 | WMI_TRAFFIC_DEFERRAL_APPROVED = 0x0, | ||
| 1809 | WMI_TRAFFIC_DEFERRAL_REJECTED = 0x1, | ||
| 1810 | }; | ||
| 1811 | |||
| 1812 | /* WMI_TRAFFIC_DEFERRAL_EVENTID */ | ||
| 1813 | struct wmi_traffic_deferral_event { | ||
| 1814 | /* enum wmi_traffic_deferral_status_e */ | ||
| 1815 | u8 status; | ||
| 1816 | } __packed; | ||
| 1817 | |||
| 1818 | enum wmi_traffic_resume_status { | ||
| 1819 | WMI_TRAFFIC_RESUME_SUCCESS = 0x0, | ||
| 1820 | WMI_TRAFFIC_RESUME_FAILED = 0x1, | ||
| 1821 | }; | ||
| 1822 | |||
| 1823 | /* WMI_TRAFFIC_RESUME_EVENTID */ | ||
| 1824 | struct wmi_traffic_resume_event { | ||
| 1825 | /* enum wmi_traffic_resume_status_e */ | ||
| 1826 | u8 status; | ||
| 1827 | } __packed; | ||
| 1828 | |||
| 1829 | /* Power Save command completion status codes */ | ||
| 1830 | enum 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 */ | ||
| 1838 | enum 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 | */ | ||
| 1852 | struct 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 */ | ||
| 1859 | struct wmi_ps_dev_profile_cfg_event { | ||
| 1860 | /* wmi_ps_cfg_cmd_status_e */ | ||
| 1861 | __le32 status; | ||
| 1862 | } __packed; | ||
| 1863 | |||
| 1864 | enum 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 | |||
| 1871 | enum 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 */ | ||
| 1885 | enum 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 */ | ||
| 1894 | struct 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 | */ | ||
| 1928 | struct 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 */ | ||
| 1936 | struct 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 | */ | ||
| 1949 | struct wmi_ps_dev_cfg_read_cmd { | ||
| 1950 | __le32 reserved; | ||
| 1951 | } __packed; | ||
| 1952 | |||
| 1953 | /* WMI_PS_DEV_CFG_READ_EVENTID */ | ||
| 1954 | struct 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 */ | ||
| 1966 | struct 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 | */ | ||
| 2002 | struct 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 */ | ||
| 2010 | struct 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 | */ | ||
| 2027 | struct 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 */ | ||
| 2035 | struct 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 | |||
| 2046 | enum 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 */ | ||
| 2053 | struct 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 */ | ||
| 2074 | struct 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 | |||
| 2089 | enum 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 */ | ||
| 2097 | struct 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 */ | ||
| 2106 | struct 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 | |||
| 2117 | enum 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 | |||
| 2123 | enum 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 */ | ||
| 2131 | struct 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 | |||
| 2162 | enum 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 */ | ||
| 2174 | struct 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__ */ |
