]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/net/wireless/ath/ath11k/core.c
ath11k: htc: implement suspend handling
[mirror_ubuntu-hirsute-kernel.git] / drivers / net / wireless / ath / ath11k / core.c
CommitLineData
d5c65159
KV
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>
14f43c5f 10#include <linux/of.h>
d5c65159
KV
11#include "core.h"
12#include "dp_tx.h"
9c57d7e3 13#include "dp_rx.h"
d5c65159 14#include "debug.h"
31858805 15#include "hif.h"
d5c65159
KV
16
17unsigned int ath11k_debug_mask;
6e0355af 18EXPORT_SYMBOL(ath11k_debug_mask);
d5c65159
KV
19module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
20MODULE_PARM_DESC(debug_mask, "Debugging mask");
21
aa2092a9
VN
22static unsigned int ath11k_crypto_mode;
23module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
24MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
25
26/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
27unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
28module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
29MODULE_PARM_DESC(frame_mode,
30 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
31
d3318abf
AK
32static const struct ath11k_hw_params ath11k_hw_params[] = {
33 {
34 .hw_rev = ATH11K_HW_IPQ8074,
35 .name = "ipq8074 hw2.0",
36 .fw = {
34d9fc80 37 .dir = "IPQ8074/hw2.0",
b3a18338
KV
38 .board_size = 256 * 1024,
39 .cal_size = 256 * 1024,
d3318abf 40 },
b1cc29e9 41 .max_radios = 3,
3b94ae4c 42 .bdf_addr = 0x4B0C0000,
d547ca4c 43 .hw_ops = &ipq8074_ops,
34d5a3a8 44 .ring_mask = &ath11k_hw_ring_mask_ipq8074,
727fae14 45 .internal_sleep_clock = false,
6976433c 46 .regs = &ipq8074_regs,
e3396b8b
CH
47 .host_ce_config = ath11k_host_ce_config_ipq8074,
48 .ce_count = 12,
967c1d11
AK
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,
5f859bc0 53 .single_pdev_only = false,
7f6fc1eb 54 .rxdma1_enable = true,
4152e420
CH
55 .num_rxmda_per_pdev = 1,
56 .rx_mac_buf_ring = false,
e7495035 57 .vdev_start_delay = false,
a6275302 58 .htt_peer_map_v2 = true,
065f5f68 59 .tcl_0_only = false,
5cca5fa1 60 .spectral_fft_sz = 2,
2626c269
KV
61
62 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
63 BIT(NL80211_IFTYPE_AP) |
64 BIT(NL80211_IFTYPE_MESH_POINT),
3f6e6c32 65 .supports_monitor = true,
e838c14a 66 .supports_shadow_regs = false,
c83c500b 67 .idle_ps = false,
02f9d3c1 68 .cold_boot_calib = true,
d5c65159 69 },
b129699a
AK
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,
b129699a
AK
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,
5cca5fa1 97 .spectral_fft_sz = 4,
2626c269
KV
98
99 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
100 BIT(NL80211_IFTYPE_AP) |
101 BIT(NL80211_IFTYPE_MESH_POINT),
3f6e6c32 102 .supports_monitor = true,
e838c14a 103 .supports_shadow_regs = false,
c83c500b 104 .idle_ps = false,
02f9d3c1 105 .cold_boot_calib = true,
b129699a 106 },
9de2ad43
CH
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,
d4ecb90b 118 .ring_mask = &ath11k_hw_ring_mask_qca6390,
727fae14 119 .internal_sleep_clock = true,
6976433c 120 .regs = &qca6390_regs,
e3396b8b
CH
121 .host_ce_config = ath11k_host_ce_config_qca6390,
122 .ce_count = 9,
967c1d11
AK
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,
5f859bc0 127 .single_pdev_only = true,
7f6fc1eb 128 .rxdma1_enable = false,
4152e420
CH
129 .num_rxmda_per_pdev = 2,
130 .rx_mac_buf_ring = true,
e7495035 131 .vdev_start_delay = true,
a6275302 132 .htt_peer_map_v2 = false,
065f5f68 133 .tcl_0_only = true,
5cca5fa1 134 .spectral_fft_sz = 0,
2626c269
KV
135
136 .interface_modes = BIT(NL80211_IFTYPE_STATION) |
137 BIT(NL80211_IFTYPE_AP),
3f6e6c32 138 .supports_monitor = false,
e838c14a 139 .supports_shadow_regs = true,
c83c500b 140 .idle_ps = true,
02f9d3c1 141 .cold_boot_calib = false,
9de2ad43 142 },
d5c65159
KV
143};
144
14f43c5f
SE
145int 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
d5c65159
KV
168static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
169 size_t name_len)
170{
14f43c5f
SE
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
d5c65159 178 scnprintf(name, name_len,
14f43c5f 179 "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
6eb6ea51 180 ath11k_bus_str(ab->hif.bus),
d5c65159 181 ab->qmi.target.chip_id,
14f43c5f 182 ab->qmi.target.board_id, variant);
d5c65159
KV
183
184 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
185
186 return 0;
187}
188
7b57b2dd 189const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
7b57b2dd 190 const char *file)
d5c65159 191{
d5c65159 192 const struct firmware *fw;
34d9fc80 193 char path[100];
d5c65159
KV
194 int ret;
195
196 if (file == NULL)
197 return ERR_PTR(-ENOENT);
198
34d9fc80 199 ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
d5c65159 200
34d9fc80 201 ret = firmware_request_nowarn(&fw, path, ab->dev);
d5c65159
KV
202 if (ret)
203 return ERR_PTR(ret);
7b57b2dd
KV
204
205 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
34d9fc80 206 path, fw->size);
d5c65159
KV
207
208 return fw;
209}
210
211void 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
219static 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
296out:
297 return ret;
298}
299
300static 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;
31d78a3d 306 char *filename, filepath[100];
d5c65159
KV
307 size_t ie_len;
308 struct ath11k_fw_ie *hdr;
309 int ret, ie_id;
310
31d78a3d
KV
311 filename = ATH11K_BOARD_API2_FILE;
312
d5c65159 313 if (!bd->fw)
34d9fc80
KV
314 bd->fw = ath11k_core_firmware_request(ab, filename);
315
d5c65159
KV
316 if (IS_ERR(bd->fw))
317 return PTR_ERR(bd->fw);
318
319 data = bd->fw->data;
320 len = bd->fw->size;
321
31d78a3d
KV
322 ath11k_core_create_firmware_path(ab, filename,
323 filepath, sizeof(filepath));
324
d5c65159
KV
325 /* magic has extra null byte padded */
326 magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
327 if (len < magic_len) {
31d78a3d
KV
328 ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
329 filepath, len);
d5c65159
KV
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) {
31d78a3d
KV
343 ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
344 filepath, len);
d5c65159
KV
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
389out:
390 if (!bd->data || !bd->len) {
391 ath11k_err(ab,
31d78a3d
KV
392 "failed to fetch board data for %s from %s\n",
393 boardname, filepath);
d5c65159
KV
394 ret = -ENODATA;
395 goto err;
396 }
397
398 return 0;
399
400err:
401 ath11k_core_free_bdf(ab, bd);
402 return ret;
403}
404
405static int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
406 struct ath11k_board_data *bd)
407{
34d9fc80 408 bd->fw = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_BOARD_FILE);
d5c65159
KV
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
419int 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
443success:
444 ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
445 return 0;
446}
447
448static 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);
e838c14a 452
31858805 453 ath11k_hif_stop(ab);
d5c65159 454 ath11k_wmi_detach(ab);
9c57d7e3 455 ath11k_dp_pdev_reo_cleanup(ab);
d5c65159
KV
456
457 /* De-Init of components as needed */
458}
459
460static 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
cb4e57db 470 ret = ath11k_debugfs_soc_create(ab);
d5c65159
KV
471 if (ret) {
472 ath11k_err(ab, "failed to create ath11k debugfs\n");
473 goto err_qmi_deinit;
474 }
475
31858805 476 ret = ath11k_hif_power_up(ab);
d5c65159
KV
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
484err_debugfs_reg:
cb4e57db 485 ath11k_debugfs_soc_destroy(ab);
d5c65159
KV
486err_qmi_deinit:
487 ath11k_qmi_deinit_service(ab);
488 return ret;
489}
490
491static void ath11k_core_soc_destroy(struct ath11k_base *ab)
492{
cb4e57db 493 ath11k_debugfs_soc_destroy(ab);
d5c65159
KV
494 ath11k_dp_free(ab);
495 ath11k_reg_free(ab);
496 ath11k_qmi_deinit_service(ab);
497}
498
499static int ath11k_core_pdev_create(struct ath11k_base *ab)
500{
501 int ret;
502
cb4e57db 503 ret = ath11k_debugfs_pdev_create(ab);
d5c65159
KV
504 if (ret) {
505 ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
506 return ret;
507 }
508
0366f426 509 ret = ath11k_mac_register(ab);
d5c65159 510 if (ret) {
0366f426 511 ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
d5c65159
KV
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);
0366f426 518 goto err_mac_unregister;
d5c65159
KV
519 }
520
2a63bbca
PKC
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
9d11b7bf
KP
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
d5c65159
KV
534 return 0;
535
9d11b7bf
KP
536err_thermal_unregister:
537 ath11k_thermal_unregister(ab);
2a63bbca
PKC
538err_dp_pdev_free:
539 ath11k_dp_pdev_free(ab);
0366f426
VT
540err_mac_unregister:
541 ath11k_mac_unregister(ab);
d5c65159 542err_pdev_debug:
cb4e57db 543 ath11k_debugfs_pdev_destroy(ab);
d5c65159
KV
544
545 return ret;
546}
547
548static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
549{
9d11b7bf 550 ath11k_spectral_deinit(ab);
2a63bbca 551 ath11k_thermal_unregister(ab);
d5c65159 552 ath11k_mac_unregister(ab);
31858805 553 ath11k_hif_irq_disable(ab);
d5c65159 554 ath11k_dp_pdev_free(ab);
cb4e57db 555 ath11k_debugfs_pdev_destroy(ab);
d5c65159
KV
556}
557
558static 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
31858805 581 ret = ath11k_hif_start(ab);
d5c65159
KV
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
0366f426
VT
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
9c57d7e3
VT
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
d5c65159
KV
633 ret = ath11k_wmi_cmd_init(ab);
634 if (ret) {
635 ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
9c57d7e3 636 goto err_reo_cleanup;
d5c65159
KV
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);
9c57d7e3 643 goto err_reo_cleanup;
d5c65159
KV
644 }
645
43ed15e1
CH
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
d5c65159
KV
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);
9c57d7e3 659 goto err_reo_cleanup;
d5c65159
KV
660 }
661
662 return 0;
663
9c57d7e3
VT
664err_reo_cleanup:
665 ath11k_dp_pdev_reo_cleanup(ab);
0366f426
VT
666err_mac_destroy:
667 ath11k_mac_destroy(ab);
d5c65159 668err_hif_stop:
31858805 669 ath11k_hif_stop(ab);
d5c65159
KV
670err_wmi_detach:
671 ath11k_wmi_detach(ab);
672err_firmware_stop:
673 ath11k_qmi_firmware_stop(ab);
674
675 return ret;
676}
677
678int 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
aa2092a9
VN
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
d5c65159
KV
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 }
31858805 723 ath11k_hif_irq_enable(ab);
d5c65159
KV
724 mutex_unlock(&ab->core_lock);
725
726 return 0;
727
728err_core_stop:
729 ath11k_core_stop(ab);
0366f426 730 ath11k_mac_destroy(ab);
d5c65159
KV
731err_dp_free:
732 ath11k_dp_free(ab);
ba479239 733 mutex_unlock(&ab->core_lock);
d5c65159
KV
734 return ret;
735}
736
737static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
738{
739 int ret;
740
741 mutex_lock(&ab->core_lock);
2a63bbca 742 ath11k_thermal_unregister(ab);
31858805 743 ath11k_hif_irq_disable(ab);
d5c65159 744 ath11k_dp_pdev_free(ab);
9d11b7bf 745 ath11k_spectral_deinit(ab);
31858805 746 ath11k_hif_stop(ab);
d5c65159 747 ath11k_wmi_detach(ab);
9c57d7e3 748 ath11k_dp_pdev_reo_cleanup(ab);
d5c65159
KV
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
770err_hal_srng_deinit:
771 ath11k_hal_srng_deinit(ab);
772 return ret;
773}
774
775void 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;
79c080db 782 ar->allocated_vdev_map = 0;
d5c65159
KV
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
795static 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);
690ace20 817 complete(&ar->peer_delete_done);
d5c65159
KV
818 complete(&ar->install_key_done);
819 complete(&ar->vdev_setup_done);
3cbbdfbe 820 complete(&ar->vdev_delete_done);
d5c65159 821 complete(&ar->bss_survey_done);
a41d1034 822 complete(&ar->thermal.wmi_sync);
d5c65159
KV
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
6bc9d6f7 830 wake_up(&ab->wmi_ab.tx_credits_wq);
d5c65159
KV
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;
0b294aeb 862 fallthrough;
d5c65159
KV
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
d3318abf
AK
873static 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
b8246f88
KV
897int 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}
909EXPORT_SYMBOL(ath11k_core_pre_init);
910
1ff8ed78
GS
911int ath11k_core_init(struct ath11k_base *ab)
912{
913 int ret;
914
d5c65159
KV
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}
7f4beda2 923EXPORT_SYMBOL(ath11k_core_init);
d5c65159
KV
924
925void 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
31858805 934 ath11k_hif_power_down(ab);
d5c65159
KV
935 ath11k_mac_destroy(ab);
936 ath11k_core_soc_destroy(ab);
937}
6e0355af 938EXPORT_SYMBOL(ath11k_core_deinit);
d5c65159
KV
939
940void ath11k_core_free(struct ath11k_base *ab)
941{
942 kfree(ab);
943}
6e0355af 944EXPORT_SYMBOL(ath11k_core_free);
d5c65159 945
630ad41c 946struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
1ff8ed78
GS
947 enum ath11k_bus bus,
948 const struct ath11k_bus_params *bus_params)
d5c65159
KV
949{
950 struct ath11k_base *ab;
951
630ad41c 952 ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
d5c65159
KV
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);
6bc9d6f7 967 init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
02f9d3c1 968 init_waitqueue_head(&ab->qmi.cold_boot_waitq);
d5c65159
KV
969 INIT_WORK(&ab->restart_work, ath11k_core_restart);
970 timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
8733d835
CH
971 init_completion(&ab->htc_suspend);
972
d5c65159 973 ab->dev = dev;
1ff8ed78 974 ab->bus_params = *bus_params;
6eb6ea51 975 ab->hif.bus = bus;
d5c65159
KV
976
977 return ab;
978
979err_sc_free:
980 kfree(ab);
981 return NULL;
982}
6e0355af
GS
983EXPORT_SYMBOL(ath11k_core_alloc);
984
985MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
986MODULE_LICENSE("Dual BSD/GPL");