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