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