612efaeabcf4a36443c992edffe66371071d95f4
[platform/kernel/linux-starfive.git] / drivers / net / wireless / ath / ath11k / core.c
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/remoteproc.h>
10 #include <linux/firmware.h>
11 #include <linux/of.h>
12 #include "core.h"
13 #include "dp_tx.h"
14 #include "dp_rx.h"
15 #include "debug.h"
16 #include "hif.h"
17 #include "wow.h"
18
19 unsigned int ath11k_debug_mask;
20 EXPORT_SYMBOL(ath11k_debug_mask);
21 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
22 MODULE_PARM_DESC(debug_mask, "Debugging mask");
23
24 static unsigned int ath11k_crypto_mode;
25 module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
26 MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
27
28 /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
29 unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
30 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
31 MODULE_PARM_DESC(frame_mode,
32                  "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
33
34 static const struct ath11k_hw_params ath11k_hw_params[] = {
35         {
36                 .hw_rev = ATH11K_HW_IPQ8074,
37                 .name = "ipq8074 hw2.0",
38                 .fw = {
39                         .dir = "IPQ8074/hw2.0",
40                         .board_size = 256 * 1024,
41                         .cal_offset = 128 * 1024,
42                 },
43                 .max_radios = 3,
44                 .bdf_addr = 0x4B0C0000,
45                 .hw_ops = &ipq8074_ops,
46                 .ring_mask = &ath11k_hw_ring_mask_ipq8074,
47                 .internal_sleep_clock = false,
48                 .regs = &ipq8074_regs,
49                 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
50                 .host_ce_config = ath11k_host_ce_config_ipq8074,
51                 .ce_count = 12,
52                 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
53                 .target_ce_count = 11,
54                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
55                 .svc_to_ce_map_len = 21,
56                 .rfkill_pin = 0,
57                 .rfkill_cfg = 0,
58                 .rfkill_on_level = 0,
59                 .single_pdev_only = false,
60                 .rxdma1_enable = true,
61                 .num_rxmda_per_pdev = 1,
62                 .rx_mac_buf_ring = false,
63                 .vdev_start_delay = false,
64                 .htt_peer_map_v2 = true,
65
66                 .spectral = {
67                         .fft_sz = 2,
68                         /* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes.
69                          * so added pad size as 2 bytes to compensate the BIN size
70                          */
71                         .fft_pad_sz = 2,
72                         .summary_pad_sz = 0,
73                         .fft_hdr_len = 16,
74                         .max_fft_bins = 512,
75                 },
76
77                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
78                                         BIT(NL80211_IFTYPE_AP) |
79                                         BIT(NL80211_IFTYPE_MESH_POINT),
80                 .supports_monitor = true,
81                 .full_monitor_mode = false,
82                 .supports_shadow_regs = false,
83                 .idle_ps = false,
84                 .supports_sta_ps = false,
85                 .cold_boot_calib = true,
86                 .fw_mem_mode = 0,
87                 .num_vdevs = 16 + 1,
88                 .num_peers = 512,
89                 .supports_suspend = false,
90                 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
91                 .supports_regdb = false,
92                 .fix_l1ss = true,
93                 .credit_flow = false,
94                 .max_tx_ring = DP_TCL_NUM_RING_MAX,
95                 .hal_params = &ath11k_hw_hal_params_ipq8074,
96                 .supports_dynamic_smps_6ghz = false,
97                 .alloc_cacheable_memory = true,
98                 .wakeup_mhi = false,
99                 .supports_rssi_stats = false,
100                 .fw_wmi_diag_event = false,
101                 .current_cc_support = false,
102                 .dbr_debug_support = true,
103         },
104         {
105                 .hw_rev = ATH11K_HW_IPQ6018_HW10,
106                 .name = "ipq6018 hw1.0",
107                 .fw = {
108                         .dir = "IPQ6018/hw1.0",
109                         .board_size = 256 * 1024,
110                         .cal_offset = 128 * 1024,
111                 },
112                 .max_radios = 2,
113                 .bdf_addr = 0x4ABC0000,
114                 .hw_ops = &ipq6018_ops,
115                 .ring_mask = &ath11k_hw_ring_mask_ipq8074,
116                 .internal_sleep_clock = false,
117                 .regs = &ipq8074_regs,
118                 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
119                 .host_ce_config = ath11k_host_ce_config_ipq8074,
120                 .ce_count = 12,
121                 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
122                 .target_ce_count = 11,
123                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
124                 .svc_to_ce_map_len = 19,
125                 .rfkill_pin = 0,
126                 .rfkill_cfg = 0,
127                 .rfkill_on_level = 0,
128                 .single_pdev_only = false,
129                 .rxdma1_enable = true,
130                 .num_rxmda_per_pdev = 1,
131                 .rx_mac_buf_ring = false,
132                 .vdev_start_delay = false,
133                 .htt_peer_map_v2 = true,
134
135                 .spectral = {
136                         .fft_sz = 4,
137                         .fft_pad_sz = 0,
138                         .summary_pad_sz = 0,
139                         .fft_hdr_len = 16,
140                         .max_fft_bins = 512,
141                 },
142
143                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
144                                         BIT(NL80211_IFTYPE_AP) |
145                                         BIT(NL80211_IFTYPE_MESH_POINT),
146                 .supports_monitor = true,
147                 .full_monitor_mode = false,
148                 .supports_shadow_regs = false,
149                 .idle_ps = false,
150                 .supports_sta_ps = false,
151                 .cold_boot_calib = true,
152                 .fw_mem_mode = 0,
153                 .num_vdevs = 16 + 1,
154                 .num_peers = 512,
155                 .supports_suspend = false,
156                 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
157                 .supports_regdb = false,
158                 .fix_l1ss = true,
159                 .credit_flow = false,
160                 .max_tx_ring = DP_TCL_NUM_RING_MAX,
161                 .hal_params = &ath11k_hw_hal_params_ipq8074,
162                 .supports_dynamic_smps_6ghz = false,
163                 .alloc_cacheable_memory = true,
164                 .wakeup_mhi = false,
165                 .supports_rssi_stats = false,
166                 .fw_wmi_diag_event = false,
167                 .current_cc_support = false,
168                 .dbr_debug_support = true,
169         },
170         {
171                 .name = "qca6390 hw2.0",
172                 .hw_rev = ATH11K_HW_QCA6390_HW20,
173                 .fw = {
174                         .dir = "QCA6390/hw2.0",
175                         .board_size = 256 * 1024,
176                         .cal_offset = 128 * 1024,
177                 },
178                 .max_radios = 3,
179                 .bdf_addr = 0x4B0C0000,
180                 .hw_ops = &qca6390_ops,
181                 .ring_mask = &ath11k_hw_ring_mask_qca6390,
182                 .internal_sleep_clock = true,
183                 .regs = &qca6390_regs,
184                 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
185                 .host_ce_config = ath11k_host_ce_config_qca6390,
186                 .ce_count = 9,
187                 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
188                 .target_ce_count = 9,
189                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
190                 .svc_to_ce_map_len = 14,
191                 .rfkill_pin = 48,
192                 .rfkill_cfg = 0,
193                 .rfkill_on_level = 1,
194                 .single_pdev_only = true,
195                 .rxdma1_enable = false,
196                 .num_rxmda_per_pdev = 2,
197                 .rx_mac_buf_ring = true,
198                 .vdev_start_delay = true,
199                 .htt_peer_map_v2 = false,
200
201                 .spectral = {
202                         .fft_sz = 0,
203                         .fft_pad_sz = 0,
204                         .summary_pad_sz = 0,
205                         .fft_hdr_len = 0,
206                         .max_fft_bins = 0,
207                 },
208
209                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
210                                         BIT(NL80211_IFTYPE_AP),
211                 .supports_monitor = false,
212                 .full_monitor_mode = false,
213                 .supports_shadow_regs = true,
214                 .idle_ps = true,
215                 .supports_sta_ps = true,
216                 .cold_boot_calib = false,
217                 .fw_mem_mode = 0,
218                 .num_vdevs = 16 + 1,
219                 .num_peers = 512,
220                 .supports_suspend = true,
221                 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
222                 .supports_regdb = false,
223                 .fix_l1ss = true,
224                 .credit_flow = true,
225                 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
226                 .hal_params = &ath11k_hw_hal_params_qca6390,
227                 .supports_dynamic_smps_6ghz = false,
228                 .alloc_cacheable_memory = false,
229                 .wakeup_mhi = true,
230                 .supports_rssi_stats = true,
231                 .fw_wmi_diag_event = true,
232                 .current_cc_support = true,
233                 .dbr_debug_support = false,
234         },
235         {
236                 .name = "qcn9074 hw1.0",
237                 .hw_rev = ATH11K_HW_QCN9074_HW10,
238                 .fw = {
239                         .dir = "QCN9074/hw1.0",
240                         .board_size = 256 * 1024,
241                         .cal_offset = 128 * 1024,
242                 },
243                 .max_radios = 1,
244                 .single_pdev_only = false,
245                 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
246                 .hw_ops = &qcn9074_ops,
247                 .ring_mask = &ath11k_hw_ring_mask_qcn9074,
248                 .internal_sleep_clock = false,
249                 .regs = &qcn9074_regs,
250                 .host_ce_config = ath11k_host_ce_config_qcn9074,
251                 .ce_count = 6,
252                 .target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
253                 .target_ce_count = 9,
254                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
255                 .svc_to_ce_map_len = 18,
256                 .rfkill_pin = 0,
257                 .rfkill_cfg = 0,
258                 .rfkill_on_level = 0,
259                 .rxdma1_enable = true,
260                 .num_rxmda_per_pdev = 1,
261                 .rx_mac_buf_ring = false,
262                 .vdev_start_delay = false,
263                 .htt_peer_map_v2 = true,
264
265                 .spectral = {
266                         .fft_sz = 2,
267                         .fft_pad_sz = 0,
268                         .summary_pad_sz = 16,
269                         .fft_hdr_len = 24,
270                         .max_fft_bins = 1024,
271                 },
272
273                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
274                                         BIT(NL80211_IFTYPE_AP) |
275                                         BIT(NL80211_IFTYPE_MESH_POINT),
276                 .supports_monitor = true,
277                 .full_monitor_mode = true,
278                 .supports_shadow_regs = false,
279                 .idle_ps = false,
280                 .supports_sta_ps = false,
281                 .cold_boot_calib = false,
282                 .fw_mem_mode = 2,
283                 .num_vdevs = 8,
284                 .num_peers = 128,
285                 .supports_suspend = false,
286                 .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
287                 .supports_regdb = false,
288                 .fix_l1ss = true,
289                 .credit_flow = false,
290                 .max_tx_ring = DP_TCL_NUM_RING_MAX,
291                 .hal_params = &ath11k_hw_hal_params_ipq8074,
292                 .supports_dynamic_smps_6ghz = true,
293                 .alloc_cacheable_memory = true,
294                 .wakeup_mhi = false,
295                 .supports_rssi_stats = false,
296                 .fw_wmi_diag_event = false,
297                 .current_cc_support = false,
298                 .dbr_debug_support = true,
299         },
300         {
301                 .name = "wcn6855 hw2.0",
302                 .hw_rev = ATH11K_HW_WCN6855_HW20,
303                 .fw = {
304                         .dir = "WCN6855/hw2.0",
305                         .board_size = 256 * 1024,
306                         .cal_offset = 128 * 1024,
307                 },
308                 .max_radios = 3,
309                 .bdf_addr = 0x4B0C0000,
310                 .hw_ops = &wcn6855_ops,
311                 .ring_mask = &ath11k_hw_ring_mask_qca6390,
312                 .internal_sleep_clock = true,
313                 .regs = &wcn6855_regs,
314                 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
315                 .host_ce_config = ath11k_host_ce_config_qca6390,
316                 .ce_count = 9,
317                 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
318                 .target_ce_count = 9,
319                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
320                 .svc_to_ce_map_len = 14,
321                 .rfkill_pin = 0,
322                 .rfkill_cfg = 0,
323                 .rfkill_on_level = 0,
324                 .single_pdev_only = true,
325                 .rxdma1_enable = false,
326                 .num_rxmda_per_pdev = 2,
327                 .rx_mac_buf_ring = true,
328                 .vdev_start_delay = true,
329                 .htt_peer_map_v2 = false,
330
331                 .spectral = {
332                         .fft_sz = 0,
333                         .fft_pad_sz = 0,
334                         .summary_pad_sz = 0,
335                         .fft_hdr_len = 0,
336                         .max_fft_bins = 0,
337                 },
338
339                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
340                                         BIT(NL80211_IFTYPE_AP),
341                 .supports_monitor = false,
342                 .full_monitor_mode = false,
343                 .supports_shadow_regs = true,
344                 .idle_ps = true,
345                 .supports_sta_ps = true,
346                 .cold_boot_calib = false,
347                 .fw_mem_mode = 0,
348                 .num_vdevs = 16 + 1,
349                 .num_peers = 512,
350                 .supports_suspend = true,
351                 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
352                 .supports_regdb = true,
353                 .fix_l1ss = false,
354                 .credit_flow = true,
355                 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
356                 .hal_params = &ath11k_hw_hal_params_qca6390,
357                 .supports_dynamic_smps_6ghz = false,
358                 .alloc_cacheable_memory = false,
359                 .wakeup_mhi = true,
360                 .supports_rssi_stats = true,
361                 .fw_wmi_diag_event = true,
362                 .current_cc_support = true,
363                 .dbr_debug_support = false,
364         },
365         {
366                 .name = "wcn6855 hw2.1",
367                 .hw_rev = ATH11K_HW_WCN6855_HW21,
368                 .fw = {
369                         .dir = "WCN6855/hw2.1",
370                         .board_size = 256 * 1024,
371                         .cal_offset = 128 * 1024,
372                 },
373                 .max_radios = 3,
374                 .bdf_addr = 0x4B0C0000,
375                 .hw_ops = &wcn6855_ops,
376                 .ring_mask = &ath11k_hw_ring_mask_qca6390,
377                 .internal_sleep_clock = true,
378                 .regs = &wcn6855_regs,
379                 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
380                 .host_ce_config = ath11k_host_ce_config_qca6390,
381                 .ce_count = 9,
382                 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
383                 .target_ce_count = 9,
384                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
385                 .svc_to_ce_map_len = 14,
386                 .rfkill_pin = 0,
387                 .rfkill_cfg = 0,
388                 .rfkill_on_level = 0,
389                 .single_pdev_only = true,
390                 .rxdma1_enable = false,
391                 .num_rxmda_per_pdev = 2,
392                 .rx_mac_buf_ring = true,
393                 .vdev_start_delay = true,
394                 .htt_peer_map_v2 = false,
395
396                 .spectral = {
397                         .fft_sz = 0,
398                         .fft_pad_sz = 0,
399                         .summary_pad_sz = 0,
400                         .fft_hdr_len = 0,
401                         .max_fft_bins = 0,
402                 },
403
404                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
405                                         BIT(NL80211_IFTYPE_AP),
406                 .supports_monitor = false,
407                 .supports_shadow_regs = true,
408                 .idle_ps = true,
409                 .supports_sta_ps = true,
410                 .cold_boot_calib = false,
411                 .fw_mem_mode = 0,
412                 .num_vdevs = 16 + 1,
413                 .num_peers = 512,
414                 .supports_suspend = true,
415                 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
416                 .supports_regdb = true,
417                 .fix_l1ss = false,
418                 .credit_flow = true,
419                 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
420                 .hal_params = &ath11k_hw_hal_params_qca6390,
421                 .supports_dynamic_smps_6ghz = false,
422                 .alloc_cacheable_memory = false,
423                 .wakeup_mhi = true,
424                 .supports_rssi_stats = true,
425                 .fw_wmi_diag_event = true,
426                 .current_cc_support = true,
427                 .dbr_debug_support = false,
428         },
429 };
430
431 static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab)
432 {
433         WARN_ON(!ab->hw_params.single_pdev_only);
434
435         return &ab->pdevs[0];
436 }
437
438 int ath11k_core_suspend(struct ath11k_base *ab)
439 {
440         int ret;
441         struct ath11k_pdev *pdev;
442         struct ath11k *ar;
443
444         if (!ab->hw_params.supports_suspend)
445                 return -EOPNOTSUPP;
446
447         /* so far single_pdev_only chips have supports_suspend as true
448          * and only the first pdev is valid.
449          */
450         pdev = ath11k_core_get_single_pdev(ab);
451         ar = pdev->ar;
452         if (!ar || ar->state != ATH11K_STATE_OFF)
453                 return 0;
454
455         /* TODO: there can frames in queues so for now add delay as a hack.
456          * Need to implement to handle and remove this delay.
457          */
458         msleep(500);
459
460         ret = ath11k_dp_rx_pktlog_stop(ab, true);
461         if (ret) {
462                 ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
463                             ret);
464                 return ret;
465         }
466
467         ret = ath11k_mac_wait_tx_complete(ar);
468         if (ret) {
469                 ath11k_warn(ab, "failed to wait tx complete: %d\n", ret);
470                 return ret;
471         }
472
473         ret = ath11k_wow_enable(ab);
474         if (ret) {
475                 ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
476                 return ret;
477         }
478
479         ret = ath11k_dp_rx_pktlog_stop(ab, false);
480         if (ret) {
481                 ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
482                             ret);
483                 return ret;
484         }
485
486         ath11k_ce_stop_shadow_timers(ab);
487         ath11k_dp_stop_shadow_timers(ab);
488
489         ath11k_hif_irq_disable(ab);
490         ath11k_hif_ce_irq_disable(ab);
491
492         ret = ath11k_hif_suspend(ab);
493         if (ret) {
494                 ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
495                 return ret;
496         }
497
498         return 0;
499 }
500 EXPORT_SYMBOL(ath11k_core_suspend);
501
502 int ath11k_core_resume(struct ath11k_base *ab)
503 {
504         int ret;
505         struct ath11k_pdev *pdev;
506         struct ath11k *ar;
507
508         if (!ab->hw_params.supports_suspend)
509                 return -EOPNOTSUPP;
510
511         /* so far signle_pdev_only chips have supports_suspend as true
512          * and only the first pdev is valid.
513          */
514         pdev = ath11k_core_get_single_pdev(ab);
515         ar = pdev->ar;
516         if (!ar || ar->state != ATH11K_STATE_OFF)
517                 return 0;
518
519         ret = ath11k_hif_resume(ab);
520         if (ret) {
521                 ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
522                 return ret;
523         }
524
525         ath11k_hif_ce_irq_enable(ab);
526         ath11k_hif_irq_enable(ab);
527
528         ret = ath11k_dp_rx_pktlog_start(ab);
529         if (ret) {
530                 ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
531                             ret);
532                 return ret;
533         }
534
535         ret = ath11k_wow_wakeup(ab);
536         if (ret) {
537                 ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
538                 return ret;
539         }
540
541         return 0;
542 }
543 EXPORT_SYMBOL(ath11k_core_resume);
544
545 int ath11k_core_check_dt(struct ath11k_base *ab)
546 {
547         size_t max_len = sizeof(ab->qmi.target.bdf_ext);
548         const char *variant = NULL;
549         struct device_node *node;
550
551         node = ab->dev->of_node;
552         if (!node)
553                 return -ENOENT;
554
555         of_property_read_string(node, "qcom,ath11k-calibration-variant",
556                                 &variant);
557         if (!variant)
558                 return -ENODATA;
559
560         if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
561                 ath11k_dbg(ab, ATH11K_DBG_BOOT,
562                            "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
563                             variant);
564
565         return 0;
566 }
567
568 static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
569                                          size_t name_len)
570 {
571         /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
572         char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
573
574         if (ab->qmi.target.bdf_ext[0] != '\0')
575                 scnprintf(variant, sizeof(variant), ",variant=%s",
576                           ab->qmi.target.bdf_ext);
577
578         switch (ab->id.bdf_search) {
579         case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
580                 scnprintf(name, name_len,
581                           "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
582                           ath11k_bus_str(ab->hif.bus),
583                           ab->id.vendor, ab->id.device,
584                           ab->id.subsystem_vendor,
585                           ab->id.subsystem_device,
586                           ab->qmi.target.chip_id,
587                           ab->qmi.target.board_id,
588                           variant);
589                 break;
590         default:
591                 scnprintf(name, name_len,
592                           "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
593                           ath11k_bus_str(ab->hif.bus),
594                           ab->qmi.target.chip_id,
595                           ab->qmi.target.board_id, variant);
596                 break;
597         }
598
599         ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
600
601         return 0;
602 }
603
604 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
605                                                     const char *file)
606 {
607         const struct firmware *fw;
608         char path[100];
609         int ret;
610
611         if (file == NULL)
612                 return ERR_PTR(-ENOENT);
613
614         ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
615
616         ret = firmware_request_nowarn(&fw, path, ab->dev);
617         if (ret)
618                 return ERR_PTR(ret);
619
620         ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
621                    path, fw->size);
622
623         return fw;
624 }
625
626 void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
627 {
628         if (!IS_ERR(bd->fw))
629                 release_firmware(bd->fw);
630
631         memset(bd, 0, sizeof(*bd));
632 }
633
634 static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
635                                          struct ath11k_board_data *bd,
636                                          const void *buf, size_t buf_len,
637                                          const char *boardname,
638                                          int bd_ie_type)
639 {
640         const struct ath11k_fw_ie *hdr;
641         bool name_match_found;
642         int ret, board_ie_id;
643         size_t board_ie_len;
644         const void *board_ie_data;
645
646         name_match_found = false;
647
648         /* go through ATH11K_BD_IE_BOARD_ elements */
649         while (buf_len > sizeof(struct ath11k_fw_ie)) {
650                 hdr = buf;
651                 board_ie_id = le32_to_cpu(hdr->id);
652                 board_ie_len = le32_to_cpu(hdr->len);
653                 board_ie_data = hdr->data;
654
655                 buf_len -= sizeof(*hdr);
656                 buf += sizeof(*hdr);
657
658                 if (buf_len < ALIGN(board_ie_len, 4)) {
659                         ath11k_err(ab, "invalid ATH11K_BD_IE_BOARD length: %zu < %zu\n",
660                                    buf_len, ALIGN(board_ie_len, 4));
661                         ret = -EINVAL;
662                         goto out;
663                 }
664
665                 switch (board_ie_id) {
666                 case ATH11K_BD_IE_BOARD_NAME:
667                         ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
668                                         board_ie_data, board_ie_len);
669
670                         if (board_ie_len != strlen(boardname))
671                                 break;
672
673                         ret = memcmp(board_ie_data, boardname, strlen(boardname));
674                         if (ret)
675                                 break;
676
677                         name_match_found = true;
678                         ath11k_dbg(ab, ATH11K_DBG_BOOT,
679                                    "boot found match for name '%s'",
680                                    boardname);
681                         break;
682                 case ATH11K_BD_IE_BOARD_DATA:
683                         if (!name_match_found)
684                                 /* no match found */
685                                 break;
686
687                         ath11k_dbg(ab, ATH11K_DBG_BOOT,
688                                    "boot found board data for '%s'", boardname);
689
690                         bd->data = board_ie_data;
691                         bd->len = board_ie_len;
692
693                         ret = 0;
694                         goto out;
695                 default:
696                         ath11k_warn(ab, "unknown ATH11K_BD_IE_BOARD found: %d\n",
697                                     board_ie_id);
698                         break;
699                 }
700
701                 /* jump over the padding */
702                 board_ie_len = ALIGN(board_ie_len, 4);
703
704                 buf_len -= board_ie_len;
705                 buf += board_ie_len;
706         }
707
708         /* no match found */
709         ret = -ENOENT;
710
711 out:
712         return ret;
713 }
714
715 static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
716                                               struct ath11k_board_data *bd,
717                                               const char *boardname)
718 {
719         size_t len, magic_len;
720         const u8 *data;
721         char *filename, filepath[100];
722         size_t ie_len;
723         struct ath11k_fw_ie *hdr;
724         int ret, ie_id;
725
726         filename = ATH11K_BOARD_API2_FILE;
727
728         if (!bd->fw)
729                 bd->fw = ath11k_core_firmware_request(ab, filename);
730
731         if (IS_ERR(bd->fw))
732                 return PTR_ERR(bd->fw);
733
734         data = bd->fw->data;
735         len = bd->fw->size;
736
737         ath11k_core_create_firmware_path(ab, filename,
738                                          filepath, sizeof(filepath));
739
740         /* magic has extra null byte padded */
741         magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
742         if (len < magic_len) {
743                 ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
744                            filepath, len);
745                 ret = -EINVAL;
746                 goto err;
747         }
748
749         if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
750                 ath11k_err(ab, "found invalid board magic\n");
751                 ret = -EINVAL;
752                 goto err;
753         }
754
755         /* magic is padded to 4 bytes */
756         magic_len = ALIGN(magic_len, 4);
757         if (len < magic_len) {
758                 ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
759                            filepath, len);
760                 ret = -EINVAL;
761                 goto err;
762         }
763
764         data += magic_len;
765         len -= magic_len;
766
767         while (len > sizeof(struct ath11k_fw_ie)) {
768                 hdr = (struct ath11k_fw_ie *)data;
769                 ie_id = le32_to_cpu(hdr->id);
770                 ie_len = le32_to_cpu(hdr->len);
771
772                 len -= sizeof(*hdr);
773                 data = hdr->data;
774
775                 if (len < ALIGN(ie_len, 4)) {
776                         ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
777                                    ie_id, ie_len, len);
778                         ret = -EINVAL;
779                         goto err;
780                 }
781
782                 switch (ie_id) {
783                 case ATH11K_BD_IE_BOARD:
784                         ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
785                                                             ie_len,
786                                                             boardname,
787                                                             ATH11K_BD_IE_BOARD);
788                         if (ret == -ENOENT)
789                                 /* no match found, continue */
790                                 break;
791                         else if (ret)
792                                 /* there was an error, bail out */
793                                 goto err;
794                         /* either found or error, so stop searching */
795                         goto out;
796                 }
797
798                 /* jump over the padding */
799                 ie_len = ALIGN(ie_len, 4);
800
801                 len -= ie_len;
802                 data += ie_len;
803         }
804
805 out:
806         if (!bd->data || !bd->len) {
807                 ath11k_err(ab,
808                            "failed to fetch board data for %s from %s\n",
809                            boardname, filepath);
810                 ret = -ENODATA;
811                 goto err;
812         }
813
814         return 0;
815
816 err:
817         ath11k_core_free_bdf(ab, bd);
818         return ret;
819 }
820
821 int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
822                                        struct ath11k_board_data *bd,
823                                        const char *name)
824 {
825         bd->fw = ath11k_core_firmware_request(ab, name);
826
827         if (IS_ERR(bd->fw))
828                 return PTR_ERR(bd->fw);
829
830         bd->data = bd->fw->data;
831         bd->len = bd->fw->size;
832
833         return 0;
834 }
835
836 #define BOARD_NAME_SIZE 200
837 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
838 {
839         char boardname[BOARD_NAME_SIZE];
840         int ret;
841
842         ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
843         if (ret) {
844                 ath11k_err(ab, "failed to create board name: %d", ret);
845                 return ret;
846         }
847
848         ab->bd_api = 2;
849         ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname);
850         if (!ret)
851                 goto success;
852
853         ab->bd_api = 1;
854         ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
855         if (ret) {
856                 ath11k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n",
857                            ab->hw_params.fw.dir);
858                 return ret;
859         }
860
861 success:
862         ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
863         return 0;
864 }
865
866 int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
867 {
868         int ret;
869
870         ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME);
871         if (ret)
872                 ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
873                            ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir);
874
875         return ret;
876 }
877
878 static void ath11k_core_stop(struct ath11k_base *ab)
879 {
880         if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
881                 ath11k_qmi_firmware_stop(ab);
882
883         ath11k_hif_stop(ab);
884         ath11k_wmi_detach(ab);
885         ath11k_dp_pdev_reo_cleanup(ab);
886
887         /* De-Init of components as needed */
888 }
889
890 static int ath11k_core_soc_create(struct ath11k_base *ab)
891 {
892         int ret;
893
894         ret = ath11k_qmi_init_service(ab);
895         if (ret) {
896                 ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
897                 return ret;
898         }
899
900         ret = ath11k_debugfs_soc_create(ab);
901         if (ret) {
902                 ath11k_err(ab, "failed to create ath11k debugfs\n");
903                 goto err_qmi_deinit;
904         }
905
906         ret = ath11k_hif_power_up(ab);
907         if (ret) {
908                 ath11k_err(ab, "failed to power up :%d\n", ret);
909                 goto err_debugfs_reg;
910         }
911
912         return 0;
913
914 err_debugfs_reg:
915         ath11k_debugfs_soc_destroy(ab);
916 err_qmi_deinit:
917         ath11k_qmi_deinit_service(ab);
918         return ret;
919 }
920
921 static void ath11k_core_soc_destroy(struct ath11k_base *ab)
922 {
923         ath11k_debugfs_soc_destroy(ab);
924         ath11k_dp_free(ab);
925         ath11k_reg_free(ab);
926         ath11k_qmi_deinit_service(ab);
927 }
928
929 static int ath11k_core_pdev_create(struct ath11k_base *ab)
930 {
931         int ret;
932
933         ret = ath11k_debugfs_pdev_create(ab);
934         if (ret) {
935                 ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
936                 return ret;
937         }
938
939         ret = ath11k_mac_register(ab);
940         if (ret) {
941                 ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
942                 goto err_pdev_debug;
943         }
944
945         ret = ath11k_dp_pdev_alloc(ab);
946         if (ret) {
947                 ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
948                 goto err_mac_unregister;
949         }
950
951         ret = ath11k_thermal_register(ab);
952         if (ret) {
953                 ath11k_err(ab, "could not register thermal device: %d\n",
954                            ret);
955                 goto err_dp_pdev_free;
956         }
957
958         ret = ath11k_spectral_init(ab);
959         if (ret) {
960                 ath11k_err(ab, "failed to init spectral %d\n", ret);
961                 goto err_thermal_unregister;
962         }
963
964         return 0;
965
966 err_thermal_unregister:
967         ath11k_thermal_unregister(ab);
968 err_dp_pdev_free:
969         ath11k_dp_pdev_free(ab);
970 err_mac_unregister:
971         ath11k_mac_unregister(ab);
972 err_pdev_debug:
973         ath11k_debugfs_pdev_destroy(ab);
974
975         return ret;
976 }
977
978 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
979 {
980         ath11k_spectral_deinit(ab);
981         ath11k_thermal_unregister(ab);
982         ath11k_mac_unregister(ab);
983         ath11k_hif_irq_disable(ab);
984         ath11k_dp_pdev_free(ab);
985         ath11k_debugfs_pdev_destroy(ab);
986 }
987
988 static int ath11k_core_start(struct ath11k_base *ab,
989                              enum ath11k_firmware_mode mode)
990 {
991         int ret;
992
993         ret = ath11k_qmi_firmware_start(ab, mode);
994         if (ret) {
995                 ath11k_err(ab, "failed to attach wmi: %d\n", ret);
996                 return ret;
997         }
998
999         ret = ath11k_wmi_attach(ab);
1000         if (ret) {
1001                 ath11k_err(ab, "failed to attach wmi: %d\n", ret);
1002                 goto err_firmware_stop;
1003         }
1004
1005         ret = ath11k_htc_init(ab);
1006         if (ret) {
1007                 ath11k_err(ab, "failed to init htc: %d\n", ret);
1008                 goto err_wmi_detach;
1009         }
1010
1011         ret = ath11k_hif_start(ab);
1012         if (ret) {
1013                 ath11k_err(ab, "failed to start HIF: %d\n", ret);
1014                 goto err_wmi_detach;
1015         }
1016
1017         ret = ath11k_htc_wait_target(&ab->htc);
1018         if (ret) {
1019                 ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
1020                 goto err_hif_stop;
1021         }
1022
1023         ret = ath11k_dp_htt_connect(&ab->dp);
1024         if (ret) {
1025                 ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
1026                 goto err_hif_stop;
1027         }
1028
1029         ret = ath11k_wmi_connect(ab);
1030         if (ret) {
1031                 ath11k_err(ab, "failed to connect wmi: %d\n", ret);
1032                 goto err_hif_stop;
1033         }
1034
1035         ret = ath11k_htc_start(&ab->htc);
1036         if (ret) {
1037                 ath11k_err(ab, "failed to start HTC: %d\n", ret);
1038                 goto err_hif_stop;
1039         }
1040
1041         ret = ath11k_wmi_wait_for_service_ready(ab);
1042         if (ret) {
1043                 ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
1044                            ret);
1045                 goto err_hif_stop;
1046         }
1047
1048         ret = ath11k_mac_allocate(ab);
1049         if (ret) {
1050                 ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
1051                            ret);
1052                 goto err_hif_stop;
1053         }
1054
1055         ath11k_dp_pdev_pre_alloc(ab);
1056
1057         ret = ath11k_dp_pdev_reo_setup(ab);
1058         if (ret) {
1059                 ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
1060                 goto err_mac_destroy;
1061         }
1062
1063         ret = ath11k_wmi_cmd_init(ab);
1064         if (ret) {
1065                 ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
1066                 goto err_reo_cleanup;
1067         }
1068
1069         ret = ath11k_wmi_wait_for_unified_ready(ab);
1070         if (ret) {
1071                 ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
1072                            ret);
1073                 goto err_reo_cleanup;
1074         }
1075
1076         /* put hardware to DBS mode */
1077         if (ab->hw_params.single_pdev_only) {
1078                 ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
1079                 if (ret) {
1080                         ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
1081                         goto err_hif_stop;
1082                 }
1083         }
1084
1085         ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
1086         if (ret) {
1087                 ath11k_err(ab, "failed to send htt version request message: %d\n",
1088                            ret);
1089                 goto err_reo_cleanup;
1090         }
1091
1092         return 0;
1093
1094 err_reo_cleanup:
1095         ath11k_dp_pdev_reo_cleanup(ab);
1096 err_mac_destroy:
1097         ath11k_mac_destroy(ab);
1098 err_hif_stop:
1099         ath11k_hif_stop(ab);
1100 err_wmi_detach:
1101         ath11k_wmi_detach(ab);
1102 err_firmware_stop:
1103         ath11k_qmi_firmware_stop(ab);
1104
1105         return ret;
1106 }
1107
1108 static int ath11k_core_rfkill_config(struct ath11k_base *ab)
1109 {
1110         struct ath11k *ar;
1111         int ret = 0, i;
1112
1113         if (!(ab->target_caps.sys_cap_info & WMI_SYS_CAP_INFO_RFKILL))
1114                 return 0;
1115
1116         for (i = 0; i < ab->num_radios; i++) {
1117                 ar = ab->pdevs[i].ar;
1118
1119                 ret = ath11k_mac_rfkill_config(ar);
1120                 if (ret && ret != -EOPNOTSUPP) {
1121                         ath11k_warn(ab, "failed to configure rfkill: %d", ret);
1122                         return ret;
1123                 }
1124         }
1125
1126         return ret;
1127 }
1128
1129 int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
1130 {
1131         int ret;
1132
1133         ret = ath11k_ce_init_pipes(ab);
1134         if (ret) {
1135                 ath11k_err(ab, "failed to initialize CE: %d\n", ret);
1136                 return ret;
1137         }
1138
1139         ret = ath11k_dp_alloc(ab);
1140         if (ret) {
1141                 ath11k_err(ab, "failed to init DP: %d\n", ret);
1142                 return ret;
1143         }
1144
1145         switch (ath11k_crypto_mode) {
1146         case ATH11K_CRYPT_MODE_SW:
1147                 set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1148                 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1149                 break;
1150         case ATH11K_CRYPT_MODE_HW:
1151                 clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1152                 clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1153                 break;
1154         default:
1155                 ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
1156                 return -EINVAL;
1157         }
1158
1159         if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
1160                 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1161
1162         mutex_lock(&ab->core_lock);
1163         ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL);
1164         if (ret) {
1165                 ath11k_err(ab, "failed to start core: %d\n", ret);
1166                 goto err_dp_free;
1167         }
1168
1169         ret = ath11k_core_pdev_create(ab);
1170         if (ret) {
1171                 ath11k_err(ab, "failed to create pdev core: %d\n", ret);
1172                 goto err_core_stop;
1173         }
1174         ath11k_hif_irq_enable(ab);
1175
1176         ret = ath11k_core_rfkill_config(ab);
1177         if (ret && ret != -EOPNOTSUPP) {
1178                 ath11k_err(ab, "failed to config rfkill: %d\n", ret);
1179                 goto err_core_stop;
1180         }
1181
1182         mutex_unlock(&ab->core_lock);
1183
1184         return 0;
1185
1186 err_core_stop:
1187         ath11k_core_stop(ab);
1188         ath11k_mac_destroy(ab);
1189 err_dp_free:
1190         ath11k_dp_free(ab);
1191         mutex_unlock(&ab->core_lock);
1192         return ret;
1193 }
1194
1195 static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
1196 {
1197         int ret;
1198
1199         mutex_lock(&ab->core_lock);
1200         ath11k_thermal_unregister(ab);
1201         ath11k_hif_irq_disable(ab);
1202         ath11k_dp_pdev_free(ab);
1203         ath11k_spectral_deinit(ab);
1204         ath11k_hif_stop(ab);
1205         ath11k_wmi_detach(ab);
1206         ath11k_dp_pdev_reo_cleanup(ab);
1207         mutex_unlock(&ab->core_lock);
1208
1209         ath11k_dp_free(ab);
1210         ath11k_hal_srng_deinit(ab);
1211
1212         ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;
1213
1214         ret = ath11k_hal_srng_init(ab);
1215         if (ret)
1216                 return ret;
1217
1218         clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
1219
1220         ret = ath11k_core_qmi_firmware_ready(ab);
1221         if (ret)
1222                 goto err_hal_srng_deinit;
1223
1224         clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
1225
1226         return 0;
1227
1228 err_hal_srng_deinit:
1229         ath11k_hal_srng_deinit(ab);
1230         return ret;
1231 }
1232
1233 void ath11k_core_halt(struct ath11k *ar)
1234 {
1235         struct ath11k_base *ab = ar->ab;
1236
1237         lockdep_assert_held(&ar->conf_mutex);
1238
1239         ar->num_created_vdevs = 0;
1240         ar->allocated_vdev_map = 0;
1241
1242         ath11k_mac_scan_finish(ar);
1243         ath11k_mac_peer_cleanup_all(ar);
1244         cancel_delayed_work_sync(&ar->scan.timeout);
1245         cancel_work_sync(&ar->regd_update_work);
1246         cancel_work_sync(&ab->update_11d_work);
1247         cancel_work_sync(&ab->rfkill_work);
1248
1249         rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
1250         synchronize_rcu();
1251         INIT_LIST_HEAD(&ar->arvifs);
1252         idr_init(&ar->txmgmt_idr);
1253 }
1254
1255 static void ath11k_rfkill_work(struct work_struct *work)
1256 {
1257         struct ath11k_base *ab = container_of(work, struct ath11k_base, rfkill_work);
1258         struct ath11k *ar;
1259         bool rfkill_radio_on;
1260         int i;
1261
1262         spin_lock_bh(&ab->base_lock);
1263         rfkill_radio_on = ab->rfkill_radio_on;
1264         spin_unlock_bh(&ab->base_lock);
1265
1266         for (i = 0; i < ab->num_radios; i++) {
1267                 ar = ab->pdevs[i].ar;
1268                 if (!ar)
1269                         continue;
1270
1271                 /* notify cfg80211 radio state change */
1272                 ath11k_mac_rfkill_enable_radio(ar, rfkill_radio_on);
1273                 wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on);
1274         }
1275 }
1276
1277 static void ath11k_update_11d(struct work_struct *work)
1278 {
1279         struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
1280         struct ath11k *ar;
1281         struct ath11k_pdev *pdev;
1282         struct wmi_set_current_country_params set_current_param = {};
1283         int ret, i;
1284
1285         spin_lock_bh(&ab->base_lock);
1286         memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
1287         spin_unlock_bh(&ab->base_lock);
1288
1289         ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
1290                    set_current_param.alpha2[0],
1291                    set_current_param.alpha2[1]);
1292
1293         for (i = 0; i < ab->num_radios; i++) {
1294                 pdev = &ab->pdevs[i];
1295                 ar = pdev->ar;
1296
1297                 ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
1298                 if (ret)
1299                         ath11k_warn(ar->ab,
1300                                     "pdev id %d failed set current country code: %d\n",
1301                                     i, ret);
1302         }
1303 }
1304
1305 static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
1306 {
1307         struct ath11k *ar;
1308         struct ath11k_pdev *pdev;
1309         int i;
1310
1311         spin_lock_bh(&ab->base_lock);
1312         ab->stats.fw_crash_counter++;
1313         spin_unlock_bh(&ab->base_lock);
1314
1315         for (i = 0; i < ab->num_radios; i++) {
1316                 pdev = &ab->pdevs[i];
1317                 ar = pdev->ar;
1318                 if (!ar || ar->state == ATH11K_STATE_OFF)
1319                         continue;
1320
1321                 ieee80211_stop_queues(ar->hw);
1322                 ath11k_mac_drain_tx(ar);
1323                 complete(&ar->scan.started);
1324                 complete(&ar->scan.completed);
1325                 complete(&ar->peer_assoc_done);
1326                 complete(&ar->peer_delete_done);
1327                 complete(&ar->install_key_done);
1328                 complete(&ar->vdev_setup_done);
1329                 complete(&ar->vdev_delete_done);
1330                 complete(&ar->bss_survey_done);
1331                 complete(&ar->thermal.wmi_sync);
1332
1333                 wake_up(&ar->dp.tx_empty_waitq);
1334                 idr_for_each(&ar->txmgmt_idr,
1335                              ath11k_mac_tx_mgmt_pending_free, ar);
1336                 idr_destroy(&ar->txmgmt_idr);
1337                 wake_up(&ar->txmgmt_empty_waitq);
1338         }
1339
1340         wake_up(&ab->wmi_ab.tx_credits_wq);
1341         wake_up(&ab->peer_mapping_wq);
1342 }
1343
1344 static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
1345 {
1346         struct ath11k *ar;
1347         struct ath11k_pdev *pdev;
1348         int i;
1349
1350         for (i = 0; i < ab->num_radios; i++) {
1351                 pdev = &ab->pdevs[i];
1352                 ar = pdev->ar;
1353                 if (!ar || ar->state == ATH11K_STATE_OFF)
1354                         continue;
1355
1356                 mutex_lock(&ar->conf_mutex);
1357
1358                 switch (ar->state) {
1359                 case ATH11K_STATE_ON:
1360                         ar->state = ATH11K_STATE_RESTARTING;
1361                         ath11k_core_halt(ar);
1362                         ieee80211_restart_hw(ar->hw);
1363                         break;
1364                 case ATH11K_STATE_OFF:
1365                         ath11k_warn(ab,
1366                                     "cannot restart radio %d that hasn't been started\n",
1367                                     i);
1368                         break;
1369                 case ATH11K_STATE_RESTARTING:
1370                         break;
1371                 case ATH11K_STATE_RESTARTED:
1372                         ar->state = ATH11K_STATE_WEDGED;
1373                         fallthrough;
1374                 case ATH11K_STATE_WEDGED:
1375                         ath11k_warn(ab,
1376                                     "device is wedged, will not restart radio %d\n", i);
1377                         break;
1378                 }
1379                 mutex_unlock(&ar->conf_mutex);
1380         }
1381         complete(&ab->driver_recovery);
1382 }
1383
1384 static void ath11k_core_restart(struct work_struct *work)
1385 {
1386         struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
1387         int ret;
1388
1389         if (!ab->is_reset)
1390                 ath11k_core_pre_reconfigure_recovery(ab);
1391
1392         ret = ath11k_core_reconfigure_on_crash(ab);
1393         if (ret) {
1394                 ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
1395                 return;
1396         }
1397
1398         if (ab->is_reset)
1399                 complete_all(&ab->reconfigure_complete);
1400
1401         if (!ab->is_reset)
1402                 ath11k_core_post_reconfigure_recovery(ab);
1403 }
1404
1405 static void ath11k_core_reset(struct work_struct *work)
1406 {
1407         struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work);
1408         int reset_count, fail_cont_count;
1409         long time_left;
1410
1411         if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) {
1412                 ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags);
1413                 return;
1414         }
1415
1416         /* Sometimes the recovery will fail and then the next all recovery fail,
1417          * this is to avoid infinite recovery since it can not recovery success.
1418          */
1419         fail_cont_count = atomic_read(&ab->fail_cont_count);
1420
1421         if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FINAL)
1422                 return;
1423
1424         if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FIRST &&
1425             time_before(jiffies, ab->reset_fail_timeout))
1426                 return;
1427
1428         reset_count = atomic_inc_return(&ab->reset_count);
1429
1430         if (reset_count > 1) {
1431                 /* Sometimes it happened another reset worker before the previous one
1432                  * completed, then the second reset worker will destroy the previous one,
1433                  * thus below is to avoid that.
1434                  */
1435                 ath11k_warn(ab, "already reseting count %d\n", reset_count);
1436
1437                 reinit_completion(&ab->reset_complete);
1438                 time_left = wait_for_completion_timeout(&ab->reset_complete,
1439                                                         ATH11K_RESET_TIMEOUT_HZ);
1440
1441                 if (time_left) {
1442                         ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n");
1443                         atomic_dec(&ab->reset_count);
1444                         return;
1445                 }
1446
1447                 ab->reset_fail_timeout = jiffies + ATH11K_RESET_FAIL_TIMEOUT_HZ;
1448                 /* Record the continuous recovery fail count when recovery failed*/
1449                 atomic_inc(&ab->fail_cont_count);
1450         }
1451
1452         ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset starting\n");
1453
1454         ab->is_reset = true;
1455         atomic_set(&ab->recovery_count, 0);
1456         reinit_completion(&ab->recovery_start);
1457         atomic_set(&ab->recovery_start_count, 0);
1458
1459         ath11k_core_pre_reconfigure_recovery(ab);
1460
1461         reinit_completion(&ab->reconfigure_complete);
1462         ath11k_core_post_reconfigure_recovery(ab);
1463
1464         ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n");
1465
1466         time_left = wait_for_completion_timeout(&ab->recovery_start,
1467                                                 ATH11K_RECOVER_START_TIMEOUT_HZ);
1468
1469         ath11k_hif_power_down(ab);
1470         ath11k_qmi_free_resource(ab);
1471         ath11k_hif_power_up(ab);
1472
1473         ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n");
1474 }
1475
1476 static int ath11k_init_hw_params(struct ath11k_base *ab)
1477 {
1478         const struct ath11k_hw_params *hw_params = NULL;
1479         int i;
1480
1481         for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
1482                 hw_params = &ath11k_hw_params[i];
1483
1484                 if (hw_params->hw_rev == ab->hw_rev)
1485                         break;
1486         }
1487
1488         if (i == ARRAY_SIZE(ath11k_hw_params)) {
1489                 ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
1490                 return -EINVAL;
1491         }
1492
1493         ab->hw_params = *hw_params;
1494
1495         ath11k_info(ab, "%s\n", ab->hw_params.name);
1496
1497         return 0;
1498 }
1499
1500 int ath11k_core_pre_init(struct ath11k_base *ab)
1501 {
1502         int ret;
1503
1504         ret = ath11k_init_hw_params(ab);
1505         if (ret) {
1506                 ath11k_err(ab, "failed to get hw params: %d\n", ret);
1507                 return ret;
1508         }
1509
1510         return 0;
1511 }
1512 EXPORT_SYMBOL(ath11k_core_pre_init);
1513
1514 int ath11k_core_init(struct ath11k_base *ab)
1515 {
1516         int ret;
1517
1518         ret = ath11k_core_soc_create(ab);
1519         if (ret) {
1520                 ath11k_err(ab, "failed to create soc core: %d\n", ret);
1521                 return ret;
1522         }
1523
1524         return 0;
1525 }
1526 EXPORT_SYMBOL(ath11k_core_init);
1527
1528 void ath11k_core_deinit(struct ath11k_base *ab)
1529 {
1530         mutex_lock(&ab->core_lock);
1531
1532         ath11k_core_pdev_destroy(ab);
1533         ath11k_core_stop(ab);
1534
1535         mutex_unlock(&ab->core_lock);
1536
1537         ath11k_hif_power_down(ab);
1538         ath11k_mac_destroy(ab);
1539         ath11k_core_soc_destroy(ab);
1540 }
1541 EXPORT_SYMBOL(ath11k_core_deinit);
1542
1543 void ath11k_core_free(struct ath11k_base *ab)
1544 {
1545         destroy_workqueue(ab->workqueue_aux);
1546         destroy_workqueue(ab->workqueue);
1547
1548         kfree(ab);
1549 }
1550 EXPORT_SYMBOL(ath11k_core_free);
1551
1552 struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
1553                                       enum ath11k_bus bus,
1554                                       const struct ath11k_bus_params *bus_params)
1555 {
1556         struct ath11k_base *ab;
1557
1558         ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
1559         if (!ab)
1560                 return NULL;
1561
1562         init_completion(&ab->driver_recovery);
1563
1564         ab->workqueue = create_singlethread_workqueue("ath11k_wq");
1565         if (!ab->workqueue)
1566                 goto err_sc_free;
1567
1568         ab->workqueue_aux = create_singlethread_workqueue("ath11k_aux_wq");
1569         if (!ab->workqueue_aux)
1570                 goto err_free_wq;
1571
1572         mutex_init(&ab->core_lock);
1573         spin_lock_init(&ab->base_lock);
1574         mutex_init(&ab->vdev_id_11d_lock);
1575         init_completion(&ab->reset_complete);
1576         init_completion(&ab->reconfigure_complete);
1577         init_completion(&ab->recovery_start);
1578
1579         INIT_LIST_HEAD(&ab->peers);
1580         init_waitqueue_head(&ab->peer_mapping_wq);
1581         init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
1582         init_waitqueue_head(&ab->qmi.cold_boot_waitq);
1583         INIT_WORK(&ab->restart_work, ath11k_core_restart);
1584         INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
1585         INIT_WORK(&ab->rfkill_work, ath11k_rfkill_work);
1586         INIT_WORK(&ab->reset_work, ath11k_core_reset);
1587         timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
1588         init_completion(&ab->htc_suspend);
1589         init_completion(&ab->wow.wakeup_completed);
1590
1591         ab->dev = dev;
1592         ab->bus_params = *bus_params;
1593         ab->hif.bus = bus;
1594
1595         return ab;
1596
1597 err_free_wq:
1598         destroy_workqueue(ab->workqueue);
1599 err_sc_free:
1600         kfree(ab);
1601         return NULL;
1602 }
1603 EXPORT_SYMBOL(ath11k_core_alloc);
1604
1605 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
1606 MODULE_LICENSE("Dual BSD/GPL");