1
2
3
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
16unsigned int ath11k_debug_mask;
17module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
18MODULE_PARM_DESC(debug_mask, "Debugging mask");
19
20static const struct ath11k_hw_params ath11k_hw_params = {
21 .name = "ipq8074",
22 .fw = {
23 .dir = IPQ8074_FW_DIR,
24 .board_size = IPQ8074_MAX_BOARD_DATA_SZ,
25 .cal_size = IPQ8074_MAX_CAL_DATA_SZ,
26 },
27};
28
29
30u8 ath11k_core_get_hw_mac_id(struct ath11k_base *ab, int pdev_idx)
31{
32 switch (pdev_idx) {
33 case 0:
34 return 0;
35 case 1:
36 return 2;
37 case 2:
38 return 1;
39 default:
40 ath11k_warn(ab, "Invalid pdev idx %d\n", pdev_idx);
41 return ATH11K_INVALID_HW_MAC_ID;
42 }
43}
44EXPORT_SYMBOL(ath11k_core_get_hw_mac_id);
45
46static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
47 size_t name_len)
48{
49
50
51
52 scnprintf(name, name_len,
53 "bus=ahb,qmi-chip-id=%d,qmi-board-id=%d",
54 ab->qmi.target.chip_id,
55 ab->qmi.target.board_id);
56
57 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
58
59 return 0;
60}
61
62static const struct firmware *ath11k_fetch_fw_file(struct ath11k_base *ab,
63 const char *dir,
64 const char *file)
65{
66 char filename[100];
67 const struct firmware *fw;
68 int ret;
69
70 if (file == NULL)
71 return ERR_PTR(-ENOENT);
72
73 if (dir == NULL)
74 dir = ".";
75
76 snprintf(filename, sizeof(filename), "%s/%s", dir, file);
77 ret = firmware_request_nowarn(&fw, filename, ab->dev);
78 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot fw request '%s': %d\n",
79 filename, ret);
80
81 if (ret)
82 return ERR_PTR(ret);
83 ath11k_warn(ab, "Downloading BDF: %s, size: %zu\n",
84 filename, fw->size);
85
86 return fw;
87}
88
89void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
90{
91 if (!IS_ERR(bd->fw))
92 release_firmware(bd->fw);
93
94 memset(bd, 0, sizeof(*bd));
95}
96
97static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
98 struct ath11k_board_data *bd,
99 const void *buf, size_t buf_len,
100 const char *boardname,
101 int bd_ie_type)
102{
103 const struct ath11k_fw_ie *hdr;
104 bool name_match_found;
105 int ret, board_ie_id;
106 size_t board_ie_len;
107 const void *board_ie_data;
108
109 name_match_found = false;
110
111
112 while (buf_len > sizeof(struct ath11k_fw_ie)) {
113 hdr = buf;
114 board_ie_id = le32_to_cpu(hdr->id);
115 board_ie_len = le32_to_cpu(hdr->len);
116 board_ie_data = hdr->data;
117
118 buf_len -= sizeof(*hdr);
119 buf += sizeof(*hdr);
120
121 if (buf_len < ALIGN(board_ie_len, 4)) {
122 ath11k_err(ab, "invalid ATH11K_BD_IE_BOARD length: %zu < %zu\n",
123 buf_len, ALIGN(board_ie_len, 4));
124 ret = -EINVAL;
125 goto out;
126 }
127
128 switch (board_ie_id) {
129 case ATH11K_BD_IE_BOARD_NAME:
130 ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
131 board_ie_data, board_ie_len);
132
133 if (board_ie_len != strlen(boardname))
134 break;
135
136 ret = memcmp(board_ie_data, boardname, strlen(boardname));
137 if (ret)
138 break;
139
140 name_match_found = true;
141 ath11k_dbg(ab, ATH11K_DBG_BOOT,
142 "boot found match for name '%s'",
143 boardname);
144 break;
145 case ATH11K_BD_IE_BOARD_DATA:
146 if (!name_match_found)
147
148 break;
149
150 ath11k_dbg(ab, ATH11K_DBG_BOOT,
151 "boot found board data for '%s'", boardname);
152
153 bd->data = board_ie_data;
154 bd->len = board_ie_len;
155
156 ret = 0;
157 goto out;
158 default:
159 ath11k_warn(ab, "unknown ATH11K_BD_IE_BOARD found: %d\n",
160 board_ie_id);
161 break;
162 }
163
164
165 board_ie_len = ALIGN(board_ie_len, 4);
166
167 buf_len -= board_ie_len;
168 buf += board_ie_len;
169 }
170
171
172 ret = -ENOENT;
173
174out:
175 return ret;
176}
177
178static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
179 struct ath11k_board_data *bd,
180 const char *boardname)
181{
182 size_t len, magic_len;
183 const u8 *data;
184 char *filename = ATH11K_BOARD_API2_FILE;
185 size_t ie_len;
186 struct ath11k_fw_ie *hdr;
187 int ret, ie_id;
188
189 if (!bd->fw)
190 bd->fw = ath11k_fetch_fw_file(ab,
191 ab->hw_params.fw.dir,
192 filename);
193 if (IS_ERR(bd->fw))
194 return PTR_ERR(bd->fw);
195
196 data = bd->fw->data;
197 len = bd->fw->size;
198
199
200 magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
201 if (len < magic_len) {
202 ath11k_err(ab, "failed to find magic value in %s/%s, file too short: %zu\n",
203 ab->hw_params.fw.dir, filename, len);
204 ret = -EINVAL;
205 goto err;
206 }
207
208 if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
209 ath11k_err(ab, "found invalid board magic\n");
210 ret = -EINVAL;
211 goto err;
212 }
213
214
215 magic_len = ALIGN(magic_len, 4);
216 if (len < magic_len) {
217 ath11k_err(ab, "failed: %s/%s too small to contain board data, len: %zu\n",
218 ab->hw_params.fw.dir, filename, len);
219 ret = -EINVAL;
220 goto err;
221 }
222
223 data += magic_len;
224 len -= magic_len;
225
226 while (len > sizeof(struct ath11k_fw_ie)) {
227 hdr = (struct ath11k_fw_ie *)data;
228 ie_id = le32_to_cpu(hdr->id);
229 ie_len = le32_to_cpu(hdr->len);
230
231 len -= sizeof(*hdr);
232 data = hdr->data;
233
234 if (len < ALIGN(ie_len, 4)) {
235 ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
236 ie_id, ie_len, len);
237 return -EINVAL;
238 }
239
240 switch (ie_id) {
241 case ATH11K_BD_IE_BOARD:
242 ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
243 ie_len,
244 boardname,
245 ATH11K_BD_IE_BOARD);
246 if (ret == -ENOENT)
247
248 break;
249 else if (ret)
250
251 goto err;
252
253 goto out;
254 }
255
256
257 ie_len = ALIGN(ie_len, 4);
258
259 len -= ie_len;
260 data += ie_len;
261 }
262
263out:
264 if (!bd->data || !bd->len) {
265 ath11k_err(ab,
266 "failed to fetch board data for %s from %s/%s\n",
267 boardname, ab->hw_params.fw.dir, filename);
268 ret = -ENODATA;
269 goto err;
270 }
271
272 return 0;
273
274err:
275 ath11k_core_free_bdf(ab, bd);
276 return ret;
277}
278
279static int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
280 struct ath11k_board_data *bd)
281{
282 bd->fw = ath11k_fetch_fw_file(ab,
283 ab->hw_params.fw.dir,
284 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
295int 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
319success:
320 ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
321 return 0;
322}
323
324static 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
333}
334
335static 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
359err_debugfs_reg:
360 ath11k_debug_soc_destroy(ab);
361err_qmi_deinit:
362 ath11k_qmi_deinit_service(ab);
363 return ret;
364}
365
366static 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
374static 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
411err_thermal_unregister:
412 ath11k_thermal_unregister(ab);
413err_dp_pdev_free:
414 ath11k_dp_pdev_free(ab);
415err_mac_unregister:
416 ath11k_mac_unregister(ab);
417err_pdev_debug:
418 ath11k_debug_pdev_destroy(ab);
419
420 return ret;
421}
422
423static 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
433static 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
530err_reo_cleanup:
531 ath11k_dp_pdev_reo_cleanup(ab);
532err_mac_destroy:
533 ath11k_mac_destroy(ab);
534err_hif_stop:
535 ath11k_hif_stop(ab);
536err_wmi_detach:
537 ath11k_wmi_detach(ab);
538err_firmware_stop:
539 ath11k_qmi_firmware_stop(ab);
540
541 return ret;
542}
543
544int 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
577err_core_stop:
578 ath11k_core_stop(ab);
579 ath11k_mac_destroy(ab);
580err_dp_free:
581 ath11k_dp_free(ab);
582 mutex_unlock(&ab->core_lock);
583 return ret;
584}
585
586static 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
619err_hal_srng_deinit:
620 ath11k_hal_srng_deinit(ab);
621 return ret;
622}
623
624void 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
644static 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
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
720int ath11k_core_init(struct ath11k_base *ab)
721{
722 struct device *dev = ab->dev;
723 struct rproc *prproc;
724 phandle rproc_phandle;
725 int ret;
726
727 if (of_property_read_u32(dev->of_node, "qcom,rproc", &rproc_phandle)) {
728 ath11k_err(ab, "failed to get q6_rproc handle\n");
729 return -ENOENT;
730 }
731
732 prproc = rproc_get_by_phandle(rproc_phandle);
733 if (!prproc) {
734 ath11k_err(ab, "failed to get rproc\n");
735 return -EINVAL;
736 }
737 ab->tgt_rproc = prproc;
738 ab->hw_params = ath11k_hw_params;
739
740 ret = ath11k_core_soc_create(ab);
741 if (ret) {
742 ath11k_err(ab, "failed to create soc core: %d\n", ret);
743 return ret;
744 }
745
746 return 0;
747}
748
749void ath11k_core_deinit(struct ath11k_base *ab)
750{
751 mutex_lock(&ab->core_lock);
752
753 ath11k_core_pdev_destroy(ab);
754 ath11k_core_stop(ab);
755
756 mutex_unlock(&ab->core_lock);
757
758 ath11k_hif_power_down(ab);
759 ath11k_mac_destroy(ab);
760 ath11k_core_soc_destroy(ab);
761}
762
763void ath11k_core_free(struct ath11k_base *ab)
764{
765 kfree(ab);
766}
767
768struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
769 enum ath11k_bus bus)
770{
771 struct ath11k_base *ab;
772
773 ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
774 if (!ab)
775 return NULL;
776
777 init_completion(&ab->driver_recovery);
778
779 ab->workqueue = create_singlethread_workqueue("ath11k_wq");
780 if (!ab->workqueue)
781 goto err_sc_free;
782
783 mutex_init(&ab->core_lock);
784 spin_lock_init(&ab->base_lock);
785
786 INIT_LIST_HEAD(&ab->peers);
787 init_waitqueue_head(&ab->peer_mapping_wq);
788 init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
789 INIT_WORK(&ab->restart_work, ath11k_core_restart);
790 timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
791 ab->dev = dev;
792
793 return ab;
794
795err_sc_free:
796 kfree(ab);
797 return NULL;
798}
799