451748fa8fff850970189c90eaecbce44ef7f18f
[linux-2.6-microblaze.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  */
5
6 #include <linux/module.h>
7 #include <linux/slab.h>
8 #include <linux/remoteproc.h>
9 #include <linux/firmware.h>
10 #include <linux/of.h>
11 #include "core.h"
12 #include "dp_tx.h"
13 #include "dp_rx.h"
14 #include "debug.h"
15 #include "hif.h"
16
17 unsigned int ath11k_debug_mask;
18 EXPORT_SYMBOL(ath11k_debug_mask);
19 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
20 MODULE_PARM_DESC(debug_mask, "Debugging mask");
21
22 static unsigned int ath11k_crypto_mode;
23 module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
24 MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
25
26 /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
27 unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
28 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
29 MODULE_PARM_DESC(frame_mode,
30                  "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
31
32 static const struct ath11k_hw_params ath11k_hw_params[] = {
33         {
34                 .hw_rev = ATH11K_HW_IPQ8074,
35                 .name = "ipq8074 hw2.0",
36                 .fw = {
37                         .dir = "IPQ8074/hw2.0",
38                         .board_size = 256 * 1024,
39                         .cal_size = 256 * 1024,
40                 },
41                 .max_radios = 3,
42                 .bdf_addr = 0x4B0C0000,
43                 .hw_ops = &ipq8074_ops,
44                 .ring_mask = &ath11k_hw_ring_mask_ipq8074,
45                 .internal_sleep_clock = false,
46                 .regs = &ipq8074_regs,
47                 .host_ce_config = ath11k_host_ce_config_ipq8074,
48                 .ce_count = 12,
49                 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
50                 .target_ce_count = 11,
51                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
52                 .svc_to_ce_map_len = 21,
53                 .single_pdev_only = false,
54                 .rxdma1_enable = true,
55                 .num_rxmda_per_pdev = 1,
56                 .rx_mac_buf_ring = false,
57                 .vdev_start_delay = false,
58                 .htt_peer_map_v2 = true,
59                 .tcl_0_only = false,
60                 .spectral_fft_sz = 2,
61
62                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
63                                         BIT(NL80211_IFTYPE_AP) |
64                                         BIT(NL80211_IFTYPE_MESH_POINT),
65                 .supports_monitor = true,
66                 .supports_shadow_regs = false,
67                 .idle_ps = false,
68                 .cold_boot_calib = true,
69         },
70         {
71                 .hw_rev = ATH11K_HW_IPQ6018_HW10,
72                 .name = "ipq6018 hw1.0",
73                 .fw = {
74                         .dir = "IPQ6018/hw1.0",
75                         .board_size = 256 * 1024,
76                         .cal_size = 256 * 1024,
77                 },
78                 .max_radios = 2,
79                 .bdf_addr = 0x4ABC0000,
80                 .hw_ops = &ipq6018_ops,
81                 .ring_mask = &ath11k_hw_ring_mask_ipq8074,
82                 .internal_sleep_clock = false,
83                 .regs = &ipq8074_regs,
84                 .host_ce_config = ath11k_host_ce_config_ipq8074,
85                 .ce_count = 12,
86                 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
87                 .target_ce_count = 11,
88                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
89                 .svc_to_ce_map_len = 19,
90                 .single_pdev_only = false,
91                 .rxdma1_enable = true,
92                 .num_rxmda_per_pdev = 1,
93                 .rx_mac_buf_ring = false,
94                 .vdev_start_delay = false,
95                 .htt_peer_map_v2 = true,
96                 .tcl_0_only = false,
97                 .spectral_fft_sz = 4,
98
99                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
100                                         BIT(NL80211_IFTYPE_AP) |
101                                         BIT(NL80211_IFTYPE_MESH_POINT),
102                 .supports_monitor = true,
103                 .supports_shadow_regs = false,
104                 .idle_ps = false,
105                 .cold_boot_calib = true,
106         },
107         {
108                 .name = "qca6390 hw2.0",
109                 .hw_rev = ATH11K_HW_QCA6390_HW20,
110                 .fw = {
111                         .dir = "QCA6390/hw2.0",
112                         .board_size = 256 * 1024,
113                         .cal_size = 256 * 1024,
114                 },
115                 .max_radios = 3,
116                 .bdf_addr = 0x4B0C0000,
117                 .hw_ops = &qca6390_ops,
118                 .ring_mask = &ath11k_hw_ring_mask_qca6390,
119                 .internal_sleep_clock = true,
120                 .regs = &qca6390_regs,
121                 .host_ce_config = ath11k_host_ce_config_qca6390,
122                 .ce_count = 9,
123                 .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
124                 .target_ce_count = 9,
125                 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
126                 .svc_to_ce_map_len = 14,
127                 .single_pdev_only = true,
128                 .rxdma1_enable = false,
129                 .num_rxmda_per_pdev = 2,
130                 .rx_mac_buf_ring = true,
131                 .vdev_start_delay = true,
132                 .htt_peer_map_v2 = false,
133                 .tcl_0_only = true,
134                 .spectral_fft_sz = 0,
135
136                 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
137                                         BIT(NL80211_IFTYPE_AP),
138                 .supports_monitor = false,
139                 .supports_shadow_regs = true,
140                 .idle_ps = true,
141                 .cold_boot_calib = false,
142         },
143 };
144
145 int ath11k_core_check_dt(struct ath11k_base *ab)
146 {
147         size_t max_len = sizeof(ab->qmi.target.bdf_ext);
148         const char *variant = NULL;
149         struct device_node *node;
150
151         node = ab->dev->of_node;
152         if (!node)
153                 return -ENOENT;
154
155         of_property_read_string(node, "qcom,ath11k-calibration-variant",
156                                 &variant);
157         if (!variant)
158                 return -ENODATA;
159
160         if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
161                 ath11k_dbg(ab, ATH11K_DBG_BOOT,
162                            "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
163                             variant);
164
165         return 0;
166 }
167
168 static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
169                                          size_t name_len)
170 {
171         /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
172         char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
173
174         if (ab->qmi.target.bdf_ext[0] != '\0')
175                 scnprintf(variant, sizeof(variant), ",variant=%s",
176                           ab->qmi.target.bdf_ext);
177
178         scnprintf(name, name_len,
179                   "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
180                   ath11k_bus_str(ab->hif.bus),
181                   ab->qmi.target.chip_id,
182                   ab->qmi.target.board_id, variant);
183
184         ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
185
186         return 0;
187 }
188
189 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
190                                                     const char *file)
191 {
192         const struct firmware *fw;
193         char path[100];
194         int ret;
195
196         if (file == NULL)
197                 return ERR_PTR(-ENOENT);
198
199         ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
200
201         ret = firmware_request_nowarn(&fw, path, ab->dev);
202         if (ret)
203                 return ERR_PTR(ret);
204
205         ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
206                    path, fw->size);
207
208         return fw;
209 }
210
211 void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
212 {
213         if (!IS_ERR(bd->fw))
214                 release_firmware(bd->fw);
215
216         memset(bd, 0, sizeof(*bd));
217 }
218
219 static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
220                                          struct ath11k_board_data *bd,
221                                          const void *buf, size_t buf_len,
222                                          const char *boardname,
223                                          int bd_ie_type)
224 {
225         const struct ath11k_fw_ie *hdr;
226         bool name_match_found;
227         int ret, board_ie_id;
228         size_t board_ie_len;
229         const void *board_ie_data;
230
231         name_match_found = false;
232
233         /* go through ATH11K_BD_IE_BOARD_ elements */
234         while (buf_len > sizeof(struct ath11k_fw_ie)) {
235                 hdr = buf;
236                 board_ie_id = le32_to_cpu(hdr->id);
237                 board_ie_len = le32_to_cpu(hdr->len);
238                 board_ie_data = hdr->data;
239
240                 buf_len -= sizeof(*hdr);
241                 buf += sizeof(*hdr);
242
243                 if (buf_len < ALIGN(board_ie_len, 4)) {
244                         ath11k_err(ab, "invalid ATH11K_BD_IE_BOARD length: %zu < %zu\n",
245                                    buf_len, ALIGN(board_ie_len, 4));
246                         ret = -EINVAL;
247                         goto out;
248                 }
249
250                 switch (board_ie_id) {
251                 case ATH11K_BD_IE_BOARD_NAME:
252                         ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
253                                         board_ie_data, board_ie_len);
254
255                         if (board_ie_len != strlen(boardname))
256                                 break;
257
258                         ret = memcmp(board_ie_data, boardname, strlen(boardname));
259                         if (ret)
260                                 break;
261
262                         name_match_found = true;
263                         ath11k_dbg(ab, ATH11K_DBG_BOOT,
264                                    "boot found match for name '%s'",
265                                    boardname);
266                         break;
267                 case ATH11K_BD_IE_BOARD_DATA:
268                         if (!name_match_found)
269                                 /* no match found */
270                                 break;
271
272                         ath11k_dbg(ab, ATH11K_DBG_BOOT,
273                                    "boot found board data for '%s'", boardname);
274
275                         bd->data = board_ie_data;
276                         bd->len = board_ie_len;
277
278                         ret = 0;
279                         goto out;
280                 default:
281                         ath11k_warn(ab, "unknown ATH11K_BD_IE_BOARD found: %d\n",
282                                     board_ie_id);
283                         break;
284                 }
285
286                 /* jump over the padding */
287                 board_ie_len = ALIGN(board_ie_len, 4);
288
289                 buf_len -= board_ie_len;
290                 buf += board_ie_len;
291         }
292
293         /* no match found */
294         ret = -ENOENT;
295
296 out:
297         return ret;
298 }
299
300 static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
301                                               struct ath11k_board_data *bd,
302                                               const char *boardname)
303 {
304         size_t len, magic_len;
305         const u8 *data;
306         char *filename, filepath[100];
307         size_t ie_len;
308         struct ath11k_fw_ie *hdr;
309         int ret, ie_id;
310
311         filename = ATH11K_BOARD_API2_FILE;
312
313         if (!bd->fw)
314                 bd->fw = ath11k_core_firmware_request(ab, filename);
315
316         if (IS_ERR(bd->fw))
317                 return PTR_ERR(bd->fw);
318
319         data = bd->fw->data;
320         len = bd->fw->size;
321
322         ath11k_core_create_firmware_path(ab, filename,
323                                          filepath, sizeof(filepath));
324
325         /* magic has extra null byte padded */
326         magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
327         if (len < magic_len) {
328                 ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
329                            filepath, len);
330                 ret = -EINVAL;
331                 goto err;
332         }
333
334         if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
335                 ath11k_err(ab, "found invalid board magic\n");
336                 ret = -EINVAL;
337                 goto err;
338         }
339
340         /* magic is padded to 4 bytes */
341         magic_len = ALIGN(magic_len, 4);
342         if (len < magic_len) {
343                 ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
344                            filepath, len);
345                 ret = -EINVAL;
346                 goto err;
347         }
348
349         data += magic_len;
350         len -= magic_len;
351
352         while (len > sizeof(struct ath11k_fw_ie)) {
353                 hdr = (struct ath11k_fw_ie *)data;
354                 ie_id = le32_to_cpu(hdr->id);
355                 ie_len = le32_to_cpu(hdr->len);
356
357                 len -= sizeof(*hdr);
358                 data = hdr->data;
359
360                 if (len < ALIGN(ie_len, 4)) {
361                         ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
362                                    ie_id, ie_len, len);
363                         return -EINVAL;
364                 }
365
366                 switch (ie_id) {
367                 case ATH11K_BD_IE_BOARD:
368                         ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
369                                                             ie_len,
370                                                             boardname,
371                                                             ATH11K_BD_IE_BOARD);
372                         if (ret == -ENOENT)
373                                 /* no match found, continue */
374                                 break;
375                         else if (ret)
376                                 /* there was an error, bail out */
377                                 goto err;
378                         /* either found or error, so stop searching */
379                         goto out;
380                 }
381
382                 /* jump over the padding */
383                 ie_len = ALIGN(ie_len, 4);
384
385                 len -= ie_len;
386                 data += ie_len;
387         }
388
389 out:
390         if (!bd->data || !bd->len) {
391                 ath11k_err(ab,
392                            "failed to fetch board data for %s from %s\n",
393                            boardname, filepath);
394                 ret = -ENODATA;
395                 goto err;
396         }
397
398         return 0;
399
400 err:
401         ath11k_core_free_bdf(ab, bd);
402         return ret;
403 }
404
405 static int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
406                                               struct ath11k_board_data *bd)
407 {
408         bd->fw = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_BOARD_FILE);
409         if (IS_ERR(bd->fw))
410                 return PTR_ERR(bd->fw);
411
412         bd->data = bd->fw->data;
413         bd->len = bd->fw->size;
414
415         return 0;
416 }
417
418 #define BOARD_NAME_SIZE 100
419 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
420 {
421         char boardname[BOARD_NAME_SIZE];
422         int ret;
423
424         ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
425         if (ret) {
426                 ath11k_err(ab, "failed to create board name: %d", ret);
427                 return ret;
428         }
429
430         ab->bd_api = 2;
431         ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname);
432         if (!ret)
433                 goto success;
434
435         ab->bd_api = 1;
436         ret = ath11k_core_fetch_board_data_api_1(ab, bd);
437         if (ret) {
438                 ath11k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n",
439                            ab->hw_params.fw.dir);
440                 return ret;
441         }
442
443 success:
444         ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
445         return 0;
446 }
447
448 static void ath11k_core_stop(struct ath11k_base *ab)
449 {
450         if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
451                 ath11k_qmi_firmware_stop(ab);
452
453         ath11k_hif_stop(ab);
454         ath11k_wmi_detach(ab);
455         ath11k_dp_pdev_reo_cleanup(ab);
456
457         /* De-Init of components as needed */
458 }
459
460 static int ath11k_core_soc_create(struct ath11k_base *ab)
461 {
462         int ret;
463
464         ret = ath11k_qmi_init_service(ab);
465         if (ret) {
466                 ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
467                 return ret;
468         }
469
470         ret = ath11k_debugfs_soc_create(ab);
471         if (ret) {
472                 ath11k_err(ab, "failed to create ath11k debugfs\n");
473                 goto err_qmi_deinit;
474         }
475
476         ret = ath11k_hif_power_up(ab);
477         if (ret) {
478                 ath11k_err(ab, "failed to power up :%d\n", ret);
479                 goto err_debugfs_reg;
480         }
481
482         return 0;
483
484 err_debugfs_reg:
485         ath11k_debugfs_soc_destroy(ab);
486 err_qmi_deinit:
487         ath11k_qmi_deinit_service(ab);
488         return ret;
489 }
490
491 static void ath11k_core_soc_destroy(struct ath11k_base *ab)
492 {
493         ath11k_debugfs_soc_destroy(ab);
494         ath11k_dp_free(ab);
495         ath11k_reg_free(ab);
496         ath11k_qmi_deinit_service(ab);
497 }
498
499 static int ath11k_core_pdev_create(struct ath11k_base *ab)
500 {
501         int ret;
502
503         ret = ath11k_debugfs_pdev_create(ab);
504         if (ret) {
505                 ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
506                 return ret;
507         }
508
509         ret = ath11k_mac_register(ab);
510         if (ret) {
511                 ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
512                 goto err_pdev_debug;
513         }
514
515         ret = ath11k_dp_pdev_alloc(ab);
516         if (ret) {
517                 ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
518                 goto err_mac_unregister;
519         }
520
521         ret = ath11k_thermal_register(ab);
522         if (ret) {
523                 ath11k_err(ab, "could not register thermal device: %d\n",
524                            ret);
525                 goto err_dp_pdev_free;
526         }
527
528         ret = ath11k_spectral_init(ab);
529         if (ret) {
530                 ath11k_err(ab, "failed to init spectral %d\n", ret);
531                 goto err_thermal_unregister;
532         }
533
534         return 0;
535
536 err_thermal_unregister:
537         ath11k_thermal_unregister(ab);
538 err_dp_pdev_free:
539         ath11k_dp_pdev_free(ab);
540 err_mac_unregister:
541         ath11k_mac_unregister(ab);
542 err_pdev_debug:
543         ath11k_debugfs_pdev_destroy(ab);
544
545         return ret;
546 }
547
548 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
549 {
550         ath11k_spectral_deinit(ab);
551         ath11k_thermal_unregister(ab);
552         ath11k_mac_unregister(ab);
553         ath11k_hif_irq_disable(ab);
554         ath11k_dp_pdev_free(ab);
555         ath11k_debugfs_pdev_destroy(ab);
556 }
557
558 static int ath11k_core_start(struct ath11k_base *ab,
559                              enum ath11k_firmware_mode mode)
560 {
561         int ret;
562
563         ret = ath11k_qmi_firmware_start(ab, mode);
564         if (ret) {
565                 ath11k_err(ab, "failed to attach wmi: %d\n", ret);
566                 return ret;
567         }
568
569         ret = ath11k_wmi_attach(ab);
570         if (ret) {
571                 ath11k_err(ab, "failed to attach wmi: %d\n", ret);
572                 goto err_firmware_stop;
573         }
574
575         ret = ath11k_htc_init(ab);
576         if (ret) {
577                 ath11k_err(ab, "failed to init htc: %d\n", ret);
578                 goto err_wmi_detach;
579         }
580
581         ret = ath11k_hif_start(ab);
582         if (ret) {
583                 ath11k_err(ab, "failed to start HIF: %d\n", ret);
584                 goto err_wmi_detach;
585         }
586
587         ret = ath11k_htc_wait_target(&ab->htc);
588         if (ret) {
589                 ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
590                 goto err_hif_stop;
591         }
592
593         ret = ath11k_dp_htt_connect(&ab->dp);
594         if (ret) {
595                 ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
596                 goto err_hif_stop;
597         }
598
599         ret = ath11k_wmi_connect(ab);
600         if (ret) {
601                 ath11k_err(ab, "failed to connect wmi: %d\n", ret);
602                 goto err_hif_stop;
603         }
604
605         ret = ath11k_htc_start(&ab->htc);
606         if (ret) {
607                 ath11k_err(ab, "failed to start HTC: %d\n", ret);
608                 goto err_hif_stop;
609         }
610
611         ret = ath11k_wmi_wait_for_service_ready(ab);
612         if (ret) {
613                 ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
614                            ret);
615                 goto err_hif_stop;
616         }
617
618         ret = ath11k_mac_allocate(ab);
619         if (ret) {
620                 ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
621                            ret);
622                 goto err_hif_stop;
623         }
624
625         ath11k_dp_pdev_pre_alloc(ab);
626
627         ret = ath11k_dp_pdev_reo_setup(ab);
628         if (ret) {
629                 ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
630                 goto err_mac_destroy;
631         }
632
633         ret = ath11k_wmi_cmd_init(ab);
634         if (ret) {
635                 ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
636                 goto err_reo_cleanup;
637         }
638
639         ret = ath11k_wmi_wait_for_unified_ready(ab);
640         if (ret) {
641                 ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
642                            ret);
643                 goto err_reo_cleanup;
644         }
645
646         /* put hardware to DBS mode */
647         if (ab->hw_params.single_pdev_only) {
648                 ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
649                 if (ret) {
650                         ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
651                         goto err_hif_stop;
652                 }
653         }
654
655         ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
656         if (ret) {
657                 ath11k_err(ab, "failed to send htt version request message: %d\n",
658                            ret);
659                 goto err_reo_cleanup;
660         }
661
662         return 0;
663
664 err_reo_cleanup:
665         ath11k_dp_pdev_reo_cleanup(ab);
666 err_mac_destroy:
667         ath11k_mac_destroy(ab);
668 err_hif_stop:
669         ath11k_hif_stop(ab);
670 err_wmi_detach:
671         ath11k_wmi_detach(ab);
672 err_firmware_stop:
673         ath11k_qmi_firmware_stop(ab);
674
675         return ret;
676 }
677
678 int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
679 {
680         int ret;
681
682         ret = ath11k_ce_init_pipes(ab);
683         if (ret) {
684                 ath11k_err(ab, "failed to initialize CE: %d\n", ret);
685                 return ret;
686         }
687
688         ret = ath11k_dp_alloc(ab);
689         if (ret) {
690                 ath11k_err(ab, "failed to init DP: %d\n", ret);
691                 return ret;
692         }
693
694         switch (ath11k_crypto_mode) {
695         case ATH11K_CRYPT_MODE_SW:
696                 set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
697                 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
698                 break;
699         case ATH11K_CRYPT_MODE_HW:
700                 clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
701                 clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
702                 break;
703         default:
704                 ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
705                 return -EINVAL;
706         }
707
708         if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
709                 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
710
711         mutex_lock(&ab->core_lock);
712         ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL);
713         if (ret) {
714                 ath11k_err(ab, "failed to start core: %d\n", ret);
715                 goto err_dp_free;
716         }
717
718         ret = ath11k_core_pdev_create(ab);
719         if (ret) {
720                 ath11k_err(ab, "failed to create pdev core: %d\n", ret);
721                 goto err_core_stop;
722         }
723         ath11k_hif_irq_enable(ab);
724         mutex_unlock(&ab->core_lock);
725
726         return 0;
727
728 err_core_stop:
729         ath11k_core_stop(ab);
730         ath11k_mac_destroy(ab);
731 err_dp_free:
732         ath11k_dp_free(ab);
733         mutex_unlock(&ab->core_lock);
734         return ret;
735 }
736
737 static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
738 {
739         int ret;
740
741         mutex_lock(&ab->core_lock);
742         ath11k_thermal_unregister(ab);
743         ath11k_hif_irq_disable(ab);
744         ath11k_dp_pdev_free(ab);
745         ath11k_spectral_deinit(ab);
746         ath11k_hif_stop(ab);
747         ath11k_wmi_detach(ab);
748         ath11k_dp_pdev_reo_cleanup(ab);
749         mutex_unlock(&ab->core_lock);
750
751         ath11k_dp_free(ab);
752         ath11k_hal_srng_deinit(ab);
753
754         ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
755
756         ret = ath11k_hal_srng_init(ab);
757         if (ret)
758                 return ret;
759
760         clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
761
762         ret = ath11k_core_qmi_firmware_ready(ab);
763         if (ret)
764                 goto err_hal_srng_deinit;
765
766         clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
767
768         return 0;
769
770 err_hal_srng_deinit:
771         ath11k_hal_srng_deinit(ab);
772         return ret;
773 }
774
775 void ath11k_core_halt(struct ath11k *ar)
776 {
777         struct ath11k_base *ab = ar->ab;
778
779         lockdep_assert_held(&ar->conf_mutex);
780
781         ar->num_created_vdevs = 0;
782         ar->allocated_vdev_map = 0;
783
784         ath11k_mac_scan_finish(ar);
785         ath11k_mac_peer_cleanup_all(ar);
786         cancel_delayed_work_sync(&ar->scan.timeout);
787         cancel_work_sync(&ar->regd_update_work);
788
789         rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
790         synchronize_rcu();
791         INIT_LIST_HEAD(&ar->arvifs);
792         idr_init(&ar->txmgmt_idr);
793 }
794
795 static void ath11k_core_restart(struct work_struct *work)
796 {
797         struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
798         struct ath11k *ar;
799         struct ath11k_pdev *pdev;
800         int i, ret = 0;
801
802         spin_lock_bh(&ab->base_lock);
803         ab->stats.fw_crash_counter++;
804         spin_unlock_bh(&ab->base_lock);
805
806         for (i = 0; i < ab->num_radios; i++) {
807                 pdev = &ab->pdevs[i];
808                 ar = pdev->ar;
809                 if (!ar || ar->state == ATH11K_STATE_OFF)
810                         continue;
811
812                 ieee80211_stop_queues(ar->hw);
813                 ath11k_mac_drain_tx(ar);
814                 complete(&ar->scan.started);
815                 complete(&ar->scan.completed);
816                 complete(&ar->peer_assoc_done);
817                 complete(&ar->peer_delete_done);
818                 complete(&ar->install_key_done);
819                 complete(&ar->vdev_setup_done);
820                 complete(&ar->vdev_delete_done);
821                 complete(&ar->bss_survey_done);
822                 complete(&ar->thermal.wmi_sync);
823
824                 wake_up(&ar->dp.tx_empty_waitq);
825                 idr_for_each(&ar->txmgmt_idr,
826                              ath11k_mac_tx_mgmt_pending_free, ar);
827                 idr_destroy(&ar->txmgmt_idr);
828         }
829
830         wake_up(&ab->wmi_ab.tx_credits_wq);
831         wake_up(&ab->peer_mapping_wq);
832
833         ret = ath11k_core_reconfigure_on_crash(ab);
834         if (ret) {
835                 ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
836                 return;
837         }
838
839         for (i = 0; i < ab->num_radios; i++) {
840                 pdev = &ab->pdevs[i];
841                 ar = pdev->ar;
842                 if (!ar || ar->state == ATH11K_STATE_OFF)
843                         continue;
844
845                 mutex_lock(&ar->conf_mutex);
846
847                 switch (ar->state) {
848                 case ATH11K_STATE_ON:
849                         ar->state = ATH11K_STATE_RESTARTING;
850                         ath11k_core_halt(ar);
851                         ieee80211_restart_hw(ar->hw);
852                         break;
853                 case ATH11K_STATE_OFF:
854                         ath11k_warn(ab,
855                                     "cannot restart radio %d that hasn't been started\n",
856                                     i);
857                         break;
858                 case ATH11K_STATE_RESTARTING:
859                         break;
860                 case ATH11K_STATE_RESTARTED:
861                         ar->state = ATH11K_STATE_WEDGED;
862                         fallthrough;
863                 case ATH11K_STATE_WEDGED:
864                         ath11k_warn(ab,
865                                     "device is wedged, will not restart radio %d\n", i);
866                         break;
867                 }
868                 mutex_unlock(&ar->conf_mutex);
869         }
870         complete(&ab->driver_recovery);
871 }
872
873 static int ath11k_init_hw_params(struct ath11k_base *ab)
874 {
875         const struct ath11k_hw_params *hw_params = NULL;
876         int i;
877
878         for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
879                 hw_params = &ath11k_hw_params[i];
880
881                 if (hw_params->hw_rev == ab->hw_rev)
882                         break;
883         }
884
885         if (i == ARRAY_SIZE(ath11k_hw_params)) {
886                 ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
887                 return -EINVAL;
888         }
889
890         ab->hw_params = *hw_params;
891
892         ath11k_dbg(ab, ATH11K_DBG_BOOT, "Hardware name %s\n", ab->hw_params.name);
893
894         return 0;
895 }
896
897 int ath11k_core_pre_init(struct ath11k_base *ab)
898 {
899         int ret;
900
901         ret = ath11k_init_hw_params(ab);
902         if (ret) {
903                 ath11k_err(ab, "failed to get hw params: %d\n", ret);
904                 return ret;
905         }
906
907         return 0;
908 }
909 EXPORT_SYMBOL(ath11k_core_pre_init);
910
911 int ath11k_core_init(struct ath11k_base *ab)
912 {
913         int ret;
914
915         ret = ath11k_core_soc_create(ab);
916         if (ret) {
917                 ath11k_err(ab, "failed to create soc core: %d\n", ret);
918                 return ret;
919         }
920
921         return 0;
922 }
923 EXPORT_SYMBOL(ath11k_core_init);
924
925 void ath11k_core_deinit(struct ath11k_base *ab)
926 {
927         mutex_lock(&ab->core_lock);
928
929         ath11k_core_pdev_destroy(ab);
930         ath11k_core_stop(ab);
931
932         mutex_unlock(&ab->core_lock);
933
934         ath11k_hif_power_down(ab);
935         ath11k_mac_destroy(ab);
936         ath11k_core_soc_destroy(ab);
937 }
938 EXPORT_SYMBOL(ath11k_core_deinit);
939
940 void ath11k_core_free(struct ath11k_base *ab)
941 {
942         kfree(ab);
943 }
944 EXPORT_SYMBOL(ath11k_core_free);
945
946 struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
947                                       enum ath11k_bus bus,
948                                       const struct ath11k_bus_params *bus_params)
949 {
950         struct ath11k_base *ab;
951
952         ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
953         if (!ab)
954                 return NULL;
955
956         init_completion(&ab->driver_recovery);
957
958         ab->workqueue = create_singlethread_workqueue("ath11k_wq");
959         if (!ab->workqueue)
960                 goto err_sc_free;
961
962         mutex_init(&ab->core_lock);
963         spin_lock_init(&ab->base_lock);
964
965         INIT_LIST_HEAD(&ab->peers);
966         init_waitqueue_head(&ab->peer_mapping_wq);
967         init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
968         init_waitqueue_head(&ab->qmi.cold_boot_waitq);
969         INIT_WORK(&ab->restart_work, ath11k_core_restart);
970         timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
971         init_completion(&ab->htc_suspend);
972         init_completion(&ab->wow.wakeup_completed);
973
974         ab->dev = dev;
975         ab->bus_params = *bus_params;
976         ab->hif.bus = bus;
977
978         return ab;
979
980 err_sc_free:
981         kfree(ab);
982         return NULL;
983 }
984 EXPORT_SYMBOL(ath11k_core_alloc);
985
986 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
987 MODULE_LICENSE("Dual BSD/GPL");