xref: /freebsd/sys/contrib/dev/athk/ath11k/core.c (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #if defined(__FreeBSD__)
8 #define	LINUXKPI_PARAM_PREFIX	ath11k_core_
9 #endif
10 
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/remoteproc.h>
14 #include <linux/firmware.h>
15 #if defined(CONFIG_OF)
16 #include <linux/of.h>
17 #endif
18 #if defined(__FreeBSD__)
19 #include <linux/delay.h>
20 #endif
21 #include "core.h"
22 #include "dp_tx.h"
23 #include "dp_rx.h"
24 #include "debug.h"
25 #include "hif.h"
26 #include "wow.h"
27 
28 unsigned int ath11k_debug_mask;
29 EXPORT_SYMBOL(ath11k_debug_mask);
30 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
31 MODULE_PARM_DESC(debug_mask, "Debugging mask");
32 
33 static unsigned int ath11k_crypto_mode;
34 module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
35 MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
36 
37 /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
38 unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
39 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
40 MODULE_PARM_DESC(frame_mode,
41 		 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
42 
43 static const struct ath11k_hw_params ath11k_hw_params[] = {
44 	{
45 		.hw_rev = ATH11K_HW_IPQ8074,
46 		.name = "ipq8074 hw2.0",
47 		.fw = {
48 			.dir = "IPQ8074/hw2.0",
49 			.board_size = 256 * 1024,
50 			.cal_offset = 128 * 1024,
51 		},
52 		.max_radios = 3,
53 		.bdf_addr = 0x4B0C0000,
54 		.hw_ops = &ipq8074_ops,
55 		.ring_mask = &ath11k_hw_ring_mask_ipq8074,
56 		.internal_sleep_clock = false,
57 		.regs = &ipq8074_regs,
58 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
59 		.host_ce_config = ath11k_host_ce_config_ipq8074,
60 		.ce_count = 12,
61 		.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
62 		.target_ce_count = 11,
63 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
64 		.svc_to_ce_map_len = 21,
65 		.rfkill_pin = 0,
66 		.rfkill_cfg = 0,
67 		.rfkill_on_level = 0,
68 		.single_pdev_only = false,
69 		.rxdma1_enable = true,
70 		.num_rxmda_per_pdev = 1,
71 		.rx_mac_buf_ring = false,
72 		.vdev_start_delay = false,
73 		.htt_peer_map_v2 = true,
74 
75 		.spectral = {
76 			.fft_sz = 2,
77 			/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes.
78 			 * so added pad size as 2 bytes to compensate the BIN size
79 			 */
80 			.fft_pad_sz = 2,
81 			.summary_pad_sz = 0,
82 			.fft_hdr_len = 16,
83 			.max_fft_bins = 512,
84 		},
85 
86 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
87 					BIT(NL80211_IFTYPE_AP) |
88 					BIT(NL80211_IFTYPE_MESH_POINT),
89 		.supports_monitor = true,
90 		.full_monitor_mode = false,
91 		.supports_shadow_regs = false,
92 		.idle_ps = false,
93 		.supports_sta_ps = false,
94 		.cold_boot_calib = true,
95 		.fw_mem_mode = 0,
96 		.num_vdevs = 16 + 1,
97 		.num_peers = 512,
98 		.supports_suspend = false,
99 		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
100 		.supports_regdb = false,
101 		.fix_l1ss = true,
102 		.credit_flow = false,
103 		.max_tx_ring = DP_TCL_NUM_RING_MAX,
104 		.hal_params = &ath11k_hw_hal_params_ipq8074,
105 		.supports_dynamic_smps_6ghz = false,
106 		.alloc_cacheable_memory = true,
107 		.wakeup_mhi = false,
108 		.supports_rssi_stats = false,
109 		.fw_wmi_diag_event = false,
110 	},
111 	{
112 		.hw_rev = ATH11K_HW_IPQ6018_HW10,
113 		.name = "ipq6018 hw1.0",
114 		.fw = {
115 			.dir = "IPQ6018/hw1.0",
116 			.board_size = 256 * 1024,
117 			.cal_offset = 128 * 1024,
118 		},
119 		.max_radios = 2,
120 		.bdf_addr = 0x4ABC0000,
121 		.hw_ops = &ipq6018_ops,
122 		.ring_mask = &ath11k_hw_ring_mask_ipq8074,
123 		.internal_sleep_clock = false,
124 		.regs = &ipq8074_regs,
125 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
126 		.host_ce_config = ath11k_host_ce_config_ipq8074,
127 		.ce_count = 12,
128 		.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
129 		.target_ce_count = 11,
130 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
131 		.svc_to_ce_map_len = 19,
132 		.rfkill_pin = 0,
133 		.rfkill_cfg = 0,
134 		.rfkill_on_level = 0,
135 		.single_pdev_only = false,
136 		.rxdma1_enable = true,
137 		.num_rxmda_per_pdev = 1,
138 		.rx_mac_buf_ring = false,
139 		.vdev_start_delay = false,
140 		.htt_peer_map_v2 = true,
141 
142 		.spectral = {
143 			.fft_sz = 4,
144 			.fft_pad_sz = 0,
145 			.summary_pad_sz = 0,
146 			.fft_hdr_len = 16,
147 			.max_fft_bins = 512,
148 		},
149 
150 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
151 					BIT(NL80211_IFTYPE_AP) |
152 					BIT(NL80211_IFTYPE_MESH_POINT),
153 		.supports_monitor = true,
154 		.full_monitor_mode = false,
155 		.supports_shadow_regs = false,
156 		.idle_ps = false,
157 		.supports_sta_ps = false,
158 		.cold_boot_calib = true,
159 		.fw_mem_mode = 0,
160 		.num_vdevs = 16 + 1,
161 		.num_peers = 512,
162 		.supports_suspend = false,
163 		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
164 		.supports_regdb = false,
165 		.fix_l1ss = true,
166 		.credit_flow = false,
167 		.max_tx_ring = DP_TCL_NUM_RING_MAX,
168 		.hal_params = &ath11k_hw_hal_params_ipq8074,
169 		.supports_dynamic_smps_6ghz = false,
170 		.alloc_cacheable_memory = true,
171 		.wakeup_mhi = false,
172 		.supports_rssi_stats = false,
173 		.fw_wmi_diag_event = false,
174 	},
175 	{
176 		.name = "qca6390 hw2.0",
177 		.hw_rev = ATH11K_HW_QCA6390_HW20,
178 		.fw = {
179 			.dir = "QCA6390/hw2.0",
180 			.board_size = 256 * 1024,
181 			.cal_offset = 128 * 1024,
182 		},
183 		.max_radios = 3,
184 		.bdf_addr = 0x4B0C0000,
185 		.hw_ops = &qca6390_ops,
186 		.ring_mask = &ath11k_hw_ring_mask_qca6390,
187 		.internal_sleep_clock = true,
188 		.regs = &qca6390_regs,
189 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
190 		.host_ce_config = ath11k_host_ce_config_qca6390,
191 		.ce_count = 9,
192 		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
193 		.target_ce_count = 9,
194 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
195 		.svc_to_ce_map_len = 14,
196 		.rfkill_pin = 48,
197 		.rfkill_cfg = 0,
198 		.rfkill_on_level = 1,
199 		.single_pdev_only = true,
200 		.rxdma1_enable = false,
201 		.num_rxmda_per_pdev = 2,
202 		.rx_mac_buf_ring = true,
203 		.vdev_start_delay = true,
204 		.htt_peer_map_v2 = false,
205 
206 		.spectral = {
207 			.fft_sz = 0,
208 			.fft_pad_sz = 0,
209 			.summary_pad_sz = 0,
210 			.fft_hdr_len = 0,
211 			.max_fft_bins = 0,
212 		},
213 
214 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
215 					BIT(NL80211_IFTYPE_AP),
216 		.supports_monitor = false,
217 		.full_monitor_mode = false,
218 		.supports_shadow_regs = true,
219 		.idle_ps = true,
220 		.supports_sta_ps = true,
221 		.cold_boot_calib = false,
222 		.fw_mem_mode = 0,
223 		.num_vdevs = 16 + 1,
224 		.num_peers = 512,
225 		.supports_suspend = true,
226 		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
227 		.supports_regdb = true,
228 		.fix_l1ss = true,
229 		.credit_flow = true,
230 		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
231 		.hal_params = &ath11k_hw_hal_params_qca6390,
232 		.supports_dynamic_smps_6ghz = false,
233 		.alloc_cacheable_memory = false,
234 		.wakeup_mhi = true,
235 		.supports_rssi_stats = true,
236 		.fw_wmi_diag_event = true,
237 	},
238 	{
239 		.name = "qcn9074 hw1.0",
240 		.hw_rev = ATH11K_HW_QCN9074_HW10,
241 		.fw = {
242 			.dir = "QCN9074/hw1.0",
243 			.board_size = 256 * 1024,
244 			.cal_offset = 128 * 1024,
245 		},
246 		.max_radios = 1,
247 		.single_pdev_only = false,
248 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
249 		.hw_ops = &qcn9074_ops,
250 		.ring_mask = &ath11k_hw_ring_mask_qcn9074,
251 		.internal_sleep_clock = false,
252 		.regs = &qcn9074_regs,
253 		.host_ce_config = ath11k_host_ce_config_qcn9074,
254 		.ce_count = 6,
255 		.target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
256 		.target_ce_count = 9,
257 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
258 		.svc_to_ce_map_len = 18,
259 		.rfkill_pin = 0,
260 		.rfkill_cfg = 0,
261 		.rfkill_on_level = 0,
262 		.rxdma1_enable = true,
263 		.num_rxmda_per_pdev = 1,
264 		.rx_mac_buf_ring = false,
265 		.vdev_start_delay = false,
266 		.htt_peer_map_v2 = true,
267 
268 		.spectral = {
269 			.fft_sz = 2,
270 			.fft_pad_sz = 0,
271 			.summary_pad_sz = 16,
272 			.fft_hdr_len = 24,
273 			.max_fft_bins = 1024,
274 		},
275 
276 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
277 					BIT(NL80211_IFTYPE_AP) |
278 					BIT(NL80211_IFTYPE_MESH_POINT),
279 		.supports_monitor = true,
280 		.full_monitor_mode = true,
281 		.supports_shadow_regs = false,
282 		.idle_ps = false,
283 		.supports_sta_ps = false,
284 		.cold_boot_calib = false,
285 		.fw_mem_mode = 2,
286 		.num_vdevs = 8,
287 		.num_peers = 128,
288 		.supports_suspend = false,
289 		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
290 		.supports_regdb = false,
291 		.fix_l1ss = true,
292 		.credit_flow = false,
293 		.max_tx_ring = DP_TCL_NUM_RING_MAX,
294 		.hal_params = &ath11k_hw_hal_params_ipq8074,
295 		.supports_dynamic_smps_6ghz = true,
296 		.alloc_cacheable_memory = true,
297 		.wakeup_mhi = false,
298 		.supports_rssi_stats = false,
299 		.fw_wmi_diag_event = false,
300 	},
301 	{
302 		.name = "wcn6855 hw2.0",
303 		.hw_rev = ATH11K_HW_WCN6855_HW20,
304 		.fw = {
305 			.dir = "WCN6855/hw2.0",
306 			.board_size = 256 * 1024,
307 			.cal_offset = 128 * 1024,
308 		},
309 		.max_radios = 3,
310 		.bdf_addr = 0x4B0C0000,
311 		.hw_ops = &wcn6855_ops,
312 		.ring_mask = &ath11k_hw_ring_mask_qca6390,
313 		.internal_sleep_clock = true,
314 		.regs = &wcn6855_regs,
315 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
316 		.host_ce_config = ath11k_host_ce_config_qca6390,
317 		.ce_count = 9,
318 		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
319 		.target_ce_count = 9,
320 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
321 		.svc_to_ce_map_len = 14,
322 		.rfkill_pin = 0,
323 		.rfkill_cfg = 0,
324 		.rfkill_on_level = 0,
325 		.single_pdev_only = true,
326 		.rxdma1_enable = false,
327 		.num_rxmda_per_pdev = 2,
328 		.rx_mac_buf_ring = true,
329 		.vdev_start_delay = true,
330 		.htt_peer_map_v2 = false,
331 
332 		.spectral = {
333 			.fft_sz = 0,
334 			.fft_pad_sz = 0,
335 			.summary_pad_sz = 0,
336 			.fft_hdr_len = 0,
337 			.max_fft_bins = 0,
338 		},
339 
340 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
341 					BIT(NL80211_IFTYPE_AP),
342 		.supports_monitor = false,
343 		.full_monitor_mode = false,
344 		.supports_shadow_regs = true,
345 		.idle_ps = true,
346 		.supports_sta_ps = true,
347 		.cold_boot_calib = false,
348 		.fw_mem_mode = 0,
349 		.num_vdevs = 16 + 1,
350 		.num_peers = 512,
351 		.supports_suspend = true,
352 		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
353 		.supports_regdb = true,
354 		.fix_l1ss = false,
355 		.credit_flow = true,
356 		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
357 		.hal_params = &ath11k_hw_hal_params_qca6390,
358 		.supports_dynamic_smps_6ghz = false,
359 		.alloc_cacheable_memory = false,
360 		.wakeup_mhi = true,
361 		.supports_rssi_stats = true,
362 		.fw_wmi_diag_event = true,
363 	},
364 	{
365 		.name = "wcn6855 hw2.1",
366 		.hw_rev = ATH11K_HW_WCN6855_HW21,
367 		.fw = {
368 			.dir = "WCN6855/hw2.1",
369 			.board_size = 256 * 1024,
370 			.cal_offset = 128 * 1024,
371 		},
372 		.max_radios = 3,
373 		.bdf_addr = 0x4B0C0000,
374 		.hw_ops = &wcn6855_ops,
375 		.ring_mask = &ath11k_hw_ring_mask_qca6390,
376 		.internal_sleep_clock = true,
377 		.regs = &wcn6855_regs,
378 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
379 		.host_ce_config = ath11k_host_ce_config_qca6390,
380 		.ce_count = 9,
381 		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
382 		.target_ce_count = 9,
383 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
384 		.svc_to_ce_map_len = 14,
385 		.rfkill_pin = 0,
386 		.rfkill_cfg = 0,
387 		.rfkill_on_level = 0,
388 		.single_pdev_only = true,
389 		.rxdma1_enable = false,
390 		.num_rxmda_per_pdev = 2,
391 		.rx_mac_buf_ring = true,
392 		.vdev_start_delay = true,
393 		.htt_peer_map_v2 = false,
394 
395 		.spectral = {
396 			.fft_sz = 0,
397 			.fft_pad_sz = 0,
398 			.summary_pad_sz = 0,
399 			.fft_hdr_len = 0,
400 			.max_fft_bins = 0,
401 		},
402 
403 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
404 					BIT(NL80211_IFTYPE_AP),
405 		.supports_monitor = false,
406 		.supports_shadow_regs = true,
407 		.idle_ps = true,
408 		.supports_sta_ps = true,
409 		.cold_boot_calib = false,
410 		.fw_mem_mode = 0,
411 		.num_vdevs = 16 + 1,
412 		.num_peers = 512,
413 		.supports_suspend = true,
414 		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
415 		.supports_regdb = true,
416 		.fix_l1ss = false,
417 		.credit_flow = true,
418 		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
419 		.hal_params = &ath11k_hw_hal_params_qca6390,
420 		.supports_dynamic_smps_6ghz = false,
421 		.alloc_cacheable_memory = false,
422 		.wakeup_mhi = true,
423 		.supports_rssi_stats = true,
424 		.fw_wmi_diag_event = true,
425 	},
426 };
427 
428 int ath11k_core_suspend(struct ath11k_base *ab)
429 {
430 	int ret;
431 
432 	if (!ab->hw_params.supports_suspend)
433 		return -EOPNOTSUPP;
434 
435 	/* TODO: there can frames in queues so for now add delay as a hack.
436 	 * Need to implement to handle and remove this delay.
437 	 */
438 	msleep(500);
439 
440 	ret = ath11k_dp_rx_pktlog_stop(ab, true);
441 	if (ret) {
442 		ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
443 			    ret);
444 		return ret;
445 	}
446 
447 	ret = ath11k_wow_enable(ab);
448 	if (ret) {
449 		ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
450 		return ret;
451 	}
452 
453 	ret = ath11k_dp_rx_pktlog_stop(ab, false);
454 	if (ret) {
455 		ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
456 			    ret);
457 		return ret;
458 	}
459 
460 	ath11k_ce_stop_shadow_timers(ab);
461 	ath11k_dp_stop_shadow_timers(ab);
462 
463 	ath11k_hif_irq_disable(ab);
464 	ath11k_hif_ce_irq_disable(ab);
465 
466 	ret = ath11k_hif_suspend(ab);
467 	if (ret) {
468 		ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
469 		return ret;
470 	}
471 
472 	return 0;
473 }
474 EXPORT_SYMBOL(ath11k_core_suspend);
475 
476 int ath11k_core_resume(struct ath11k_base *ab)
477 {
478 	int ret;
479 
480 	if (!ab->hw_params.supports_suspend)
481 		return -EOPNOTSUPP;
482 
483 	ret = ath11k_hif_resume(ab);
484 	if (ret) {
485 		ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
486 		return ret;
487 	}
488 
489 	ath11k_hif_ce_irq_enable(ab);
490 	ath11k_hif_irq_enable(ab);
491 
492 	ret = ath11k_dp_rx_pktlog_start(ab);
493 	if (ret) {
494 		ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
495 			    ret);
496 		return ret;
497 	}
498 
499 	ret = ath11k_wow_wakeup(ab);
500 	if (ret) {
501 		ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
502 		return ret;
503 	}
504 
505 	return 0;
506 }
507 EXPORT_SYMBOL(ath11k_core_resume);
508 
509 int ath11k_core_check_dt(struct ath11k_base *ab)
510 {
511 #if defined(__linux__)
512 	size_t max_len = sizeof(ab->qmi.target.bdf_ext);
513 	const char *variant = NULL;
514 	struct device_node *node;
515 
516 	node = ab->dev->of_node;
517 	if (!node)
518 		return -ENOENT;
519 
520 	of_property_read_string(node, "qcom,ath11k-calibration-variant",
521 				&variant);
522 	if (!variant)
523 		return -ENODATA;
524 
525 	if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
526 		ath11k_dbg(ab, ATH11K_DBG_BOOT,
527 			   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
528 			    variant);
529 
530 	return 0;
531 #elif defined(__FreeBSD__)
532 	return -ENOENT;
533 #endif
534 }
535 
536 static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
537 					 size_t name_len)
538 {
539 	/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
540 	char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
541 
542 	if (ab->qmi.target.bdf_ext[0] != '\0')
543 		scnprintf(variant, sizeof(variant), ",variant=%s",
544 			  ab->qmi.target.bdf_ext);
545 
546 	switch (ab->id.bdf_search) {
547 	case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
548 		scnprintf(name, name_len,
549 			  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
550 			  ath11k_bus_str(ab->hif.bus),
551 			  ab->id.vendor, ab->id.device,
552 			  ab->id.subsystem_vendor,
553 			  ab->id.subsystem_device,
554 			  ab->qmi.target.chip_id,
555 			  ab->qmi.target.board_id,
556 			  variant);
557 		break;
558 	default:
559 		scnprintf(name, name_len,
560 			  "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
561 			  ath11k_bus_str(ab->hif.bus),
562 			  ab->qmi.target.chip_id,
563 			  ab->qmi.target.board_id, variant);
564 		break;
565 	}
566 
567 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
568 
569 	return 0;
570 }
571 
572 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
573 						    const char *file)
574 {
575 	const struct firmware *fw;
576 	char path[100];
577 	int ret;
578 
579 	if (file == NULL)
580 		return ERR_PTR(-ENOENT);
581 
582 	ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
583 
584 	ret = firmware_request_nowarn(&fw, path, ab->dev);
585 	if (ret)
586 		return ERR_PTR(ret);
587 
588 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
589 		   path, fw->size);
590 
591 	return fw;
592 }
593 
594 void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
595 {
596 	if (!IS_ERR(bd->fw))
597 		release_firmware(bd->fw);
598 
599 	memset(bd, 0, sizeof(*bd));
600 }
601 
602 static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
603 					 struct ath11k_board_data *bd,
604 #if defined(__linux__)
605 					 const void *buf, size_t buf_len,
606 #elif defined(__FreeBSD__)
607 					 const u8 *buf, size_t buf_len,
608 #endif
609 					 const char *boardname,
610 					 int bd_ie_type)
611 {
612 	const struct ath11k_fw_ie *hdr;
613 	bool name_match_found;
614 	int ret, board_ie_id;
615 	size_t board_ie_len;
616 	const void *board_ie_data;
617 
618 	name_match_found = false;
619 
620 	/* go through ATH11K_BD_IE_BOARD_ elements */
621 	while (buf_len > sizeof(struct ath11k_fw_ie)) {
622 #if defined(__linux__)
623 		hdr = buf;
624 #elif defined(__FreeBSD__)
625 		hdr = (const struct ath11k_fw_ie *)buf;
626 #endif
627 		board_ie_id = le32_to_cpu(hdr->id);
628 		board_ie_len = le32_to_cpu(hdr->len);
629 		board_ie_data = hdr->data;
630 
631 		buf_len -= sizeof(*hdr);
632 		buf += sizeof(*hdr);
633 
634 		if (buf_len < ALIGN(board_ie_len, 4)) {
635 			ath11k_err(ab, "invalid ATH11K_BD_IE_BOARD length: %zu < %zu\n",
636 				   buf_len, ALIGN(board_ie_len, 4));
637 			ret = -EINVAL;
638 			goto out;
639 		}
640 
641 		switch (board_ie_id) {
642 		case ATH11K_BD_IE_BOARD_NAME:
643 			ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
644 					board_ie_data, board_ie_len);
645 
646 			if (board_ie_len != strlen(boardname))
647 				break;
648 
649 			ret = memcmp(board_ie_data, boardname, strlen(boardname));
650 			if (ret)
651 				break;
652 
653 			name_match_found = true;
654 			ath11k_dbg(ab, ATH11K_DBG_BOOT,
655 				   "boot found match for name '%s'",
656 				   boardname);
657 			break;
658 		case ATH11K_BD_IE_BOARD_DATA:
659 			if (!name_match_found)
660 				/* no match found */
661 				break;
662 
663 			ath11k_dbg(ab, ATH11K_DBG_BOOT,
664 				   "boot found board data for '%s'", boardname);
665 
666 			bd->data = board_ie_data;
667 			bd->len = board_ie_len;
668 
669 			ret = 0;
670 			goto out;
671 		default:
672 			ath11k_warn(ab, "unknown ATH11K_BD_IE_BOARD found: %d\n",
673 				    board_ie_id);
674 			break;
675 		}
676 
677 		/* jump over the padding */
678 		board_ie_len = ALIGN(board_ie_len, 4);
679 
680 		buf_len -= board_ie_len;
681 		buf += board_ie_len;
682 	}
683 
684 	/* no match found */
685 	ret = -ENOENT;
686 
687 out:
688 	return ret;
689 }
690 
691 static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
692 					      struct ath11k_board_data *bd,
693 					      const char *boardname)
694 {
695 	size_t len, magic_len;
696 	const u8 *data;
697 	char *filename, filepath[100];
698 	size_t ie_len;
699 #if defined(__linux__)
700 	struct ath11k_fw_ie *hdr;
701 #elif defined(__FreeBSD__)
702 	const struct ath11k_fw_ie *hdr;
703 #endif
704 	int ret, ie_id;
705 
706 	filename = ATH11K_BOARD_API2_FILE;
707 
708 	if (!bd->fw)
709 		bd->fw = ath11k_core_firmware_request(ab, filename);
710 
711 	if (IS_ERR(bd->fw))
712 		return PTR_ERR(bd->fw);
713 
714 	data = bd->fw->data;
715 	len = bd->fw->size;
716 
717 	ath11k_core_create_firmware_path(ab, filename,
718 					 filepath, sizeof(filepath));
719 
720 	/* magic has extra null byte padded */
721 	magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
722 	if (len < magic_len) {
723 		ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
724 			   filepath, len);
725 		ret = -EINVAL;
726 		goto err;
727 	}
728 
729 	if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
730 		ath11k_err(ab, "found invalid board magic\n");
731 		ret = -EINVAL;
732 		goto err;
733 	}
734 
735 	/* magic is padded to 4 bytes */
736 	magic_len = ALIGN(magic_len, 4);
737 	if (len < magic_len) {
738 		ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
739 			   filepath, len);
740 		ret = -EINVAL;
741 		goto err;
742 	}
743 
744 	data += magic_len;
745 	len -= magic_len;
746 
747 	while (len > sizeof(struct ath11k_fw_ie)) {
748 #if defined(__linux__)
749 		hdr = (struct ath11k_fw_ie *)data;
750 #elif defined(__FreeBSD__)
751 		hdr = (const struct ath11k_fw_ie *)data;
752 #endif
753 		ie_id = le32_to_cpu(hdr->id);
754 		ie_len = le32_to_cpu(hdr->len);
755 
756 		len -= sizeof(*hdr);
757 		data = hdr->data;
758 
759 		if (len < ALIGN(ie_len, 4)) {
760 			ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
761 				   ie_id, ie_len, len);
762 			ret = -EINVAL;
763 			goto err;
764 		}
765 
766 		switch (ie_id) {
767 		case ATH11K_BD_IE_BOARD:
768 			ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
769 							    ie_len,
770 							    boardname,
771 							    ATH11K_BD_IE_BOARD);
772 			if (ret == -ENOENT)
773 				/* no match found, continue */
774 				break;
775 			else if (ret)
776 				/* there was an error, bail out */
777 				goto err;
778 			/* either found or error, so stop searching */
779 			goto out;
780 		}
781 
782 		/* jump over the padding */
783 		ie_len = ALIGN(ie_len, 4);
784 
785 		len -= ie_len;
786 		data += ie_len;
787 	}
788 
789 out:
790 	if (!bd->data || !bd->len) {
791 		ath11k_err(ab,
792 			   "failed to fetch board data for %s from %s\n",
793 			   boardname, filepath);
794 		ret = -ENODATA;
795 		goto err;
796 	}
797 
798 	return 0;
799 
800 err:
801 	ath11k_core_free_bdf(ab, bd);
802 	return ret;
803 }
804 
805 int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
806 				       struct ath11k_board_data *bd,
807 				       const char *name)
808 {
809 	bd->fw = ath11k_core_firmware_request(ab, name);
810 
811 	if (IS_ERR(bd->fw))
812 		return PTR_ERR(bd->fw);
813 
814 	bd->data = bd->fw->data;
815 	bd->len = bd->fw->size;
816 
817 	return 0;
818 }
819 
820 #define BOARD_NAME_SIZE 200
821 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
822 {
823 	char boardname[BOARD_NAME_SIZE];
824 	int ret;
825 
826 	ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
827 	if (ret) {
828 		ath11k_err(ab, "failed to create board name: %d", ret);
829 		return ret;
830 	}
831 
832 	ab->bd_api = 2;
833 	ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname);
834 	if (!ret)
835 		goto success;
836 
837 	ab->bd_api = 1;
838 	ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
839 	if (ret) {
840 		ath11k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n",
841 			   ab->hw_params.fw.dir);
842 		return ret;
843 	}
844 
845 success:
846 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
847 	return 0;
848 }
849 
850 int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
851 {
852 	int ret;
853 
854 	ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME);
855 	if (ret)
856 		ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
857 			   ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir);
858 
859 	return ret;
860 }
861 
862 static void ath11k_core_stop(struct ath11k_base *ab)
863 {
864 	if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
865 		ath11k_qmi_firmware_stop(ab);
866 
867 	ath11k_hif_stop(ab);
868 	ath11k_wmi_detach(ab);
869 	ath11k_dp_pdev_reo_cleanup(ab);
870 
871 	/* De-Init of components as needed */
872 }
873 
874 static int ath11k_core_soc_create(struct ath11k_base *ab)
875 {
876 	int ret;
877 
878 	ret = ath11k_qmi_init_service(ab);
879 	if (ret) {
880 		ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
881 		return ret;
882 	}
883 
884 	ret = ath11k_debugfs_soc_create(ab);
885 	if (ret) {
886 		ath11k_err(ab, "failed to create ath11k debugfs\n");
887 		goto err_qmi_deinit;
888 	}
889 
890 	ret = ath11k_hif_power_up(ab);
891 	if (ret) {
892 		ath11k_err(ab, "failed to power up :%d\n", ret);
893 		goto err_debugfs_reg;
894 	}
895 
896 	return 0;
897 
898 err_debugfs_reg:
899 	ath11k_debugfs_soc_destroy(ab);
900 err_qmi_deinit:
901 	ath11k_qmi_deinit_service(ab);
902 	return ret;
903 }
904 
905 static void ath11k_core_soc_destroy(struct ath11k_base *ab)
906 {
907 	ath11k_debugfs_soc_destroy(ab);
908 	ath11k_dp_free(ab);
909 	ath11k_reg_free(ab);
910 	ath11k_qmi_deinit_service(ab);
911 }
912 
913 static int ath11k_core_pdev_create(struct ath11k_base *ab)
914 {
915 	int ret;
916 
917 	ret = ath11k_debugfs_pdev_create(ab);
918 	if (ret) {
919 		ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
920 		return ret;
921 	}
922 
923 	ret = ath11k_mac_register(ab);
924 	if (ret) {
925 		ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
926 		goto err_pdev_debug;
927 	}
928 
929 	ret = ath11k_dp_pdev_alloc(ab);
930 	if (ret) {
931 		ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
932 		goto err_mac_unregister;
933 	}
934 
935 	ret = ath11k_thermal_register(ab);
936 	if (ret) {
937 		ath11k_err(ab, "could not register thermal device: %d\n",
938 			   ret);
939 		goto err_dp_pdev_free;
940 	}
941 
942 	ret = ath11k_spectral_init(ab);
943 	if (ret) {
944 		ath11k_err(ab, "failed to init spectral %d\n", ret);
945 		goto err_thermal_unregister;
946 	}
947 
948 	return 0;
949 
950 err_thermal_unregister:
951 	ath11k_thermal_unregister(ab);
952 err_dp_pdev_free:
953 	ath11k_dp_pdev_free(ab);
954 err_mac_unregister:
955 	ath11k_mac_unregister(ab);
956 err_pdev_debug:
957 	ath11k_debugfs_pdev_destroy(ab);
958 
959 	return ret;
960 }
961 
962 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
963 {
964 	ath11k_spectral_deinit(ab);
965 	ath11k_thermal_unregister(ab);
966 	ath11k_mac_unregister(ab);
967 	ath11k_hif_irq_disable(ab);
968 	ath11k_dp_pdev_free(ab);
969 	ath11k_debugfs_pdev_destroy(ab);
970 }
971 
972 static int ath11k_core_start(struct ath11k_base *ab,
973 			     enum ath11k_firmware_mode mode)
974 {
975 	int ret;
976 
977 	ret = ath11k_qmi_firmware_start(ab, mode);
978 	if (ret) {
979 		ath11k_err(ab, "failed to attach wmi: %d\n", ret);
980 		return ret;
981 	}
982 
983 	ret = ath11k_wmi_attach(ab);
984 	if (ret) {
985 		ath11k_err(ab, "failed to attach wmi: %d\n", ret);
986 		goto err_firmware_stop;
987 	}
988 
989 	ret = ath11k_htc_init(ab);
990 	if (ret) {
991 		ath11k_err(ab, "failed to init htc: %d\n", ret);
992 		goto err_wmi_detach;
993 	}
994 
995 	ret = ath11k_hif_start(ab);
996 	if (ret) {
997 		ath11k_err(ab, "failed to start HIF: %d\n", ret);
998 		goto err_wmi_detach;
999 	}
1000 
1001 	ret = ath11k_htc_wait_target(&ab->htc);
1002 	if (ret) {
1003 		ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
1004 		goto err_hif_stop;
1005 	}
1006 
1007 	ret = ath11k_dp_htt_connect(&ab->dp);
1008 	if (ret) {
1009 		ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
1010 		goto err_hif_stop;
1011 	}
1012 
1013 	ret = ath11k_wmi_connect(ab);
1014 	if (ret) {
1015 		ath11k_err(ab, "failed to connect wmi: %d\n", ret);
1016 		goto err_hif_stop;
1017 	}
1018 
1019 	ret = ath11k_htc_start(&ab->htc);
1020 	if (ret) {
1021 		ath11k_err(ab, "failed to start HTC: %d\n", ret);
1022 		goto err_hif_stop;
1023 	}
1024 
1025 	ret = ath11k_wmi_wait_for_service_ready(ab);
1026 	if (ret) {
1027 		ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
1028 			   ret);
1029 		goto err_hif_stop;
1030 	}
1031 
1032 	ret = ath11k_mac_allocate(ab);
1033 	if (ret) {
1034 		ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
1035 			   ret);
1036 		goto err_hif_stop;
1037 	}
1038 
1039 	ath11k_dp_pdev_pre_alloc(ab);
1040 
1041 	ret = ath11k_dp_pdev_reo_setup(ab);
1042 	if (ret) {
1043 		ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
1044 		goto err_mac_destroy;
1045 	}
1046 
1047 	ret = ath11k_wmi_cmd_init(ab);
1048 	if (ret) {
1049 		ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
1050 		goto err_reo_cleanup;
1051 	}
1052 
1053 	ret = ath11k_wmi_wait_for_unified_ready(ab);
1054 	if (ret) {
1055 		ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
1056 			   ret);
1057 		goto err_reo_cleanup;
1058 	}
1059 
1060 	/* put hardware to DBS mode */
1061 	if (ab->hw_params.single_pdev_only) {
1062 		ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
1063 		if (ret) {
1064 			ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
1065 			goto err_hif_stop;
1066 		}
1067 	}
1068 
1069 	ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
1070 	if (ret) {
1071 		ath11k_err(ab, "failed to send htt version request message: %d\n",
1072 			   ret);
1073 		goto err_reo_cleanup;
1074 	}
1075 
1076 	return 0;
1077 
1078 err_reo_cleanup:
1079 	ath11k_dp_pdev_reo_cleanup(ab);
1080 err_mac_destroy:
1081 	ath11k_mac_destroy(ab);
1082 err_hif_stop:
1083 	ath11k_hif_stop(ab);
1084 err_wmi_detach:
1085 	ath11k_wmi_detach(ab);
1086 err_firmware_stop:
1087 	ath11k_qmi_firmware_stop(ab);
1088 
1089 	return ret;
1090 }
1091 
1092 static int ath11k_core_rfkill_config(struct ath11k_base *ab)
1093 {
1094 	struct ath11k *ar;
1095 	int ret = 0, i;
1096 
1097 	if (!(ab->target_caps.sys_cap_info & WMI_SYS_CAP_INFO_RFKILL))
1098 		return 0;
1099 
1100 	for (i = 0; i < ab->num_radios; i++) {
1101 		ar = ab->pdevs[i].ar;
1102 
1103 		ret = ath11k_mac_rfkill_config(ar);
1104 		if (ret && ret != -EOPNOTSUPP) {
1105 			ath11k_warn(ab, "failed to configure rfkill: %d", ret);
1106 			return ret;
1107 		}
1108 	}
1109 
1110 	return ret;
1111 }
1112 
1113 int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
1114 {
1115 	int ret;
1116 
1117 	ret = ath11k_ce_init_pipes(ab);
1118 	if (ret) {
1119 		ath11k_err(ab, "failed to initialize CE: %d\n", ret);
1120 		return ret;
1121 	}
1122 
1123 	ret = ath11k_dp_alloc(ab);
1124 	if (ret) {
1125 		ath11k_err(ab, "failed to init DP: %d\n", ret);
1126 		return ret;
1127 	}
1128 
1129 	switch (ath11k_crypto_mode) {
1130 	case ATH11K_CRYPT_MODE_SW:
1131 		set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1132 		set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1133 		break;
1134 	case ATH11K_CRYPT_MODE_HW:
1135 		clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1136 		clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1137 		break;
1138 	default:
1139 		ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
1140 		return -EINVAL;
1141 	}
1142 
1143 	if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
1144 		set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1145 
1146 	mutex_lock(&ab->core_lock);
1147 	ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL);
1148 	if (ret) {
1149 		ath11k_err(ab, "failed to start core: %d\n", ret);
1150 		goto err_dp_free;
1151 	}
1152 
1153 	ret = ath11k_core_pdev_create(ab);
1154 	if (ret) {
1155 		ath11k_err(ab, "failed to create pdev core: %d\n", ret);
1156 		goto err_core_stop;
1157 	}
1158 	ath11k_hif_irq_enable(ab);
1159 
1160 	ret = ath11k_core_rfkill_config(ab);
1161 	if (ret && ret != -EOPNOTSUPP) {
1162 		ath11k_err(ab, "failed to config rfkill: %d\n", ret);
1163 		goto err_core_stop;
1164 	}
1165 
1166 	mutex_unlock(&ab->core_lock);
1167 
1168 	return 0;
1169 
1170 err_core_stop:
1171 	ath11k_core_stop(ab);
1172 	ath11k_mac_destroy(ab);
1173 err_dp_free:
1174 	ath11k_dp_free(ab);
1175 	mutex_unlock(&ab->core_lock);
1176 	return ret;
1177 }
1178 
1179 static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
1180 {
1181 	int ret;
1182 
1183 	mutex_lock(&ab->core_lock);
1184 	ath11k_thermal_unregister(ab);
1185 	ath11k_hif_irq_disable(ab);
1186 	ath11k_dp_pdev_free(ab);
1187 	ath11k_spectral_deinit(ab);
1188 	ath11k_hif_stop(ab);
1189 	ath11k_wmi_detach(ab);
1190 	ath11k_dp_pdev_reo_cleanup(ab);
1191 	mutex_unlock(&ab->core_lock);
1192 
1193 	ath11k_dp_free(ab);
1194 	ath11k_hal_srng_deinit(ab);
1195 
1196 	ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;
1197 
1198 	ret = ath11k_hal_srng_init(ab);
1199 	if (ret)
1200 		return ret;
1201 
1202 	clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
1203 
1204 	ret = ath11k_core_qmi_firmware_ready(ab);
1205 	if (ret)
1206 		goto err_hal_srng_deinit;
1207 
1208 	clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
1209 
1210 	return 0;
1211 
1212 err_hal_srng_deinit:
1213 	ath11k_hal_srng_deinit(ab);
1214 	return ret;
1215 }
1216 
1217 void ath11k_core_halt(struct ath11k *ar)
1218 {
1219 	struct ath11k_base *ab = ar->ab;
1220 
1221 	lockdep_assert_held(&ar->conf_mutex);
1222 
1223 	ar->num_created_vdevs = 0;
1224 	ar->allocated_vdev_map = 0;
1225 
1226 	ath11k_mac_scan_finish(ar);
1227 	ath11k_mac_peer_cleanup_all(ar);
1228 	cancel_delayed_work_sync(&ar->scan.timeout);
1229 	cancel_work_sync(&ar->regd_update_work);
1230 	cancel_work_sync(&ab->update_11d_work);
1231 	cancel_work_sync(&ab->rfkill_work);
1232 
1233 	rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
1234 	synchronize_rcu();
1235 	INIT_LIST_HEAD(&ar->arvifs);
1236 	idr_init(&ar->txmgmt_idr);
1237 }
1238 
1239 static void ath11k_rfkill_work(struct work_struct *work)
1240 {
1241 	struct ath11k_base *ab = container_of(work, struct ath11k_base, rfkill_work);
1242 	struct ath11k *ar;
1243 	bool rfkill_radio_on;
1244 	int i;
1245 
1246 	spin_lock_bh(&ab->base_lock);
1247 	rfkill_radio_on = ab->rfkill_radio_on;
1248 	spin_unlock_bh(&ab->base_lock);
1249 
1250 	for (i = 0; i < ab->num_radios; i++) {
1251 		ar = ab->pdevs[i].ar;
1252 		if (!ar)
1253 			continue;
1254 
1255 		/* notify cfg80211 radio state change */
1256 		ath11k_mac_rfkill_enable_radio(ar, rfkill_radio_on);
1257 		wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on);
1258 	}
1259 }
1260 
1261 static void ath11k_update_11d(struct work_struct *work)
1262 {
1263 	struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
1264 	struct ath11k *ar;
1265 	struct ath11k_pdev *pdev;
1266 	struct wmi_set_current_country_params set_current_param = {};
1267 	int ret, i;
1268 
1269 	spin_lock_bh(&ab->base_lock);
1270 	memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
1271 	spin_unlock_bh(&ab->base_lock);
1272 
1273 	ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
1274 		   set_current_param.alpha2[0],
1275 		   set_current_param.alpha2[1]);
1276 
1277 	for (i = 0; i < ab->num_radios; i++) {
1278 		pdev = &ab->pdevs[i];
1279 		ar = pdev->ar;
1280 
1281 		ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
1282 		if (ret)
1283 			ath11k_warn(ar->ab,
1284 				    "pdev id %d failed set current country code: %d\n",
1285 				    i, ret);
1286 	}
1287 }
1288 
1289 static void ath11k_core_restart(struct work_struct *work)
1290 {
1291 	struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
1292 	struct ath11k *ar;
1293 	struct ath11k_pdev *pdev;
1294 	int i, ret = 0;
1295 
1296 	spin_lock_bh(&ab->base_lock);
1297 	ab->stats.fw_crash_counter++;
1298 	spin_unlock_bh(&ab->base_lock);
1299 
1300 	for (i = 0; i < ab->num_radios; i++) {
1301 		pdev = &ab->pdevs[i];
1302 		ar = pdev->ar;
1303 		if (!ar || ar->state == ATH11K_STATE_OFF)
1304 			continue;
1305 
1306 		ieee80211_stop_queues(ar->hw);
1307 		ath11k_mac_drain_tx(ar);
1308 		complete(&ar->scan.started);
1309 		complete(&ar->scan.completed);
1310 		complete(&ar->peer_assoc_done);
1311 		complete(&ar->peer_delete_done);
1312 		complete(&ar->install_key_done);
1313 		complete(&ar->vdev_setup_done);
1314 		complete(&ar->vdev_delete_done);
1315 		complete(&ar->bss_survey_done);
1316 		complete(&ar->thermal.wmi_sync);
1317 
1318 		wake_up(&ar->dp.tx_empty_waitq);
1319 		idr_for_each(&ar->txmgmt_idr,
1320 			     ath11k_mac_tx_mgmt_pending_free, ar);
1321 		idr_destroy(&ar->txmgmt_idr);
1322 		wake_up(&ar->txmgmt_empty_waitq);
1323 	}
1324 
1325 	wake_up(&ab->wmi_ab.tx_credits_wq);
1326 	wake_up(&ab->peer_mapping_wq);
1327 
1328 	ret = ath11k_core_reconfigure_on_crash(ab);
1329 	if (ret) {
1330 		ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
1331 		return;
1332 	}
1333 
1334 	for (i = 0; i < ab->num_radios; i++) {
1335 		pdev = &ab->pdevs[i];
1336 		ar = pdev->ar;
1337 		if (!ar || ar->state == ATH11K_STATE_OFF)
1338 			continue;
1339 
1340 		mutex_lock(&ar->conf_mutex);
1341 
1342 		switch (ar->state) {
1343 		case ATH11K_STATE_ON:
1344 			ar->state = ATH11K_STATE_RESTARTING;
1345 			ath11k_core_halt(ar);
1346 			ieee80211_restart_hw(ar->hw);
1347 			break;
1348 		case ATH11K_STATE_OFF:
1349 			ath11k_warn(ab,
1350 				    "cannot restart radio %d that hasn't been started\n",
1351 				    i);
1352 			break;
1353 		case ATH11K_STATE_RESTARTING:
1354 			break;
1355 		case ATH11K_STATE_RESTARTED:
1356 			ar->state = ATH11K_STATE_WEDGED;
1357 			fallthrough;
1358 		case ATH11K_STATE_WEDGED:
1359 			ath11k_warn(ab,
1360 				    "device is wedged, will not restart radio %d\n", i);
1361 			break;
1362 		}
1363 		mutex_unlock(&ar->conf_mutex);
1364 	}
1365 	complete(&ab->driver_recovery);
1366 }
1367 
1368 static int ath11k_init_hw_params(struct ath11k_base *ab)
1369 {
1370 	const struct ath11k_hw_params *hw_params = NULL;
1371 	int i;
1372 
1373 	for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
1374 		hw_params = &ath11k_hw_params[i];
1375 
1376 		if (hw_params->hw_rev == ab->hw_rev)
1377 			break;
1378 	}
1379 
1380 	if (i == ARRAY_SIZE(ath11k_hw_params)) {
1381 		ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
1382 		return -EINVAL;
1383 	}
1384 
1385 	ab->hw_params = *hw_params;
1386 
1387 	ath11k_info(ab, "%s\n", ab->hw_params.name);
1388 
1389 	return 0;
1390 }
1391 
1392 int ath11k_core_pre_init(struct ath11k_base *ab)
1393 {
1394 	int ret;
1395 
1396 	ret = ath11k_init_hw_params(ab);
1397 	if (ret) {
1398 		ath11k_err(ab, "failed to get hw params: %d\n", ret);
1399 		return ret;
1400 	}
1401 
1402 	return 0;
1403 }
1404 EXPORT_SYMBOL(ath11k_core_pre_init);
1405 
1406 int ath11k_core_init(struct ath11k_base *ab)
1407 {
1408 	int ret;
1409 
1410 	ret = ath11k_core_soc_create(ab);
1411 	if (ret) {
1412 		ath11k_err(ab, "failed to create soc core: %d\n", ret);
1413 		return ret;
1414 	}
1415 
1416 	return 0;
1417 }
1418 EXPORT_SYMBOL(ath11k_core_init);
1419 
1420 void ath11k_core_deinit(struct ath11k_base *ab)
1421 {
1422 	mutex_lock(&ab->core_lock);
1423 
1424 	ath11k_core_pdev_destroy(ab);
1425 	ath11k_core_stop(ab);
1426 
1427 	mutex_unlock(&ab->core_lock);
1428 
1429 	ath11k_hif_power_down(ab);
1430 	ath11k_mac_destroy(ab);
1431 	ath11k_core_soc_destroy(ab);
1432 }
1433 EXPORT_SYMBOL(ath11k_core_deinit);
1434 
1435 void ath11k_core_free(struct ath11k_base *ab)
1436 {
1437 	flush_workqueue(ab->workqueue);
1438 	destroy_workqueue(ab->workqueue);
1439 
1440 	kfree(ab);
1441 }
1442 EXPORT_SYMBOL(ath11k_core_free);
1443 
1444 struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
1445 				      enum ath11k_bus bus,
1446 				      const struct ath11k_bus_params *bus_params)
1447 {
1448 	struct ath11k_base *ab;
1449 
1450 	ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
1451 	if (!ab)
1452 		return NULL;
1453 
1454 	init_completion(&ab->driver_recovery);
1455 
1456 	ab->workqueue = create_singlethread_workqueue("ath11k_wq");
1457 	if (!ab->workqueue)
1458 		goto err_sc_free;
1459 
1460 	mutex_init(&ab->core_lock);
1461 	spin_lock_init(&ab->base_lock);
1462 	mutex_init(&ab->vdev_id_11d_lock);
1463 
1464 	INIT_LIST_HEAD(&ab->peers);
1465 	init_waitqueue_head(&ab->peer_mapping_wq);
1466 	init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
1467 	init_waitqueue_head(&ab->qmi.cold_boot_waitq);
1468 	INIT_WORK(&ab->restart_work, ath11k_core_restart);
1469 	INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
1470 	INIT_WORK(&ab->rfkill_work, ath11k_rfkill_work);
1471 	timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
1472 	init_completion(&ab->htc_suspend);
1473 	init_completion(&ab->wow.wakeup_completed);
1474 
1475 	ab->dev = dev;
1476 	ab->bus_params = *bus_params;
1477 	ab->hif.bus = bus;
1478 
1479 	return ab;
1480 
1481 err_sc_free:
1482 	kfree(ab);
1483 	return NULL;
1484 }
1485 EXPORT_SYMBOL(ath11k_core_alloc);
1486 
1487 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
1488 MODULE_LICENSE("Dual BSD/GPL");
1489