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