xref: /wlan-dirver/qca-wifi-host-cmn/target_if/init_deinit/src/service_ready_util.c (revision 1397a33f48ea6455be40871470b286e535820eb8)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 /**
19  * DOC: service_ready_util.c
20  *
21  * Public APIs implementation source file for accessing (ext)service ready
22  * data from psoc object
23  */
24 #include "service_ready_util.h"
25 #include <wlan_reg_ucfg_api.h>
26 #include <target_type.h>
27 #include <qdf_module.h>
28 
29 QDF_STATUS init_deinit_chainmask_table_alloc(
30 		struct wlan_psoc_host_service_ext_param *ser_ext_par)
31 {
32 	int i;
33 	uint32_t alloc_size;
34 	QDF_STATUS status = QDF_STATUS_SUCCESS;
35 
36 	if (ser_ext_par->num_chainmask_tables == 0)
37 		return QDF_STATUS_E_NOSUPPORT;
38 
39 	for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) {
40 		if (ser_ext_par->chainmask_table[i].num_valid_chainmasks >
41 		    (UINT_MAX / sizeof(
42 		     struct wlan_psoc_host_chainmask_capabilities))) {
43 			target_if_err("invalid valid chanmask num %d",
44 				      ser_ext_par->chainmask_table[i].
45 				      num_valid_chainmasks);
46 			status = QDF_STATUS_E_FAILURE;
47 			break;
48 		}
49 		alloc_size =
50 			(sizeof(struct wlan_psoc_host_chainmask_capabilities) *
51 			 ser_ext_par->chainmask_table[i].num_valid_chainmasks);
52 
53 		ser_ext_par->chainmask_table[i].cap_list =
54 			qdf_mem_alloc_outline(NULL, alloc_size);
55 		if (!ser_ext_par->chainmask_table[i].cap_list) {
56 			init_deinit_chainmask_table_free(ser_ext_par);
57 			status = QDF_STATUS_E_NOMEM;
58 			break;
59 		}
60 	}
61 
62 	return status;
63 }
64 
65 qdf_export_symbol(init_deinit_chainmask_table_alloc);
66 
67 QDF_STATUS init_deinit_chainmask_table_free(
68 		struct wlan_psoc_host_service_ext_param *ser_ext_par)
69 {
70 	struct wlan_psoc_host_chainmask_table *table;
71 	int i;
72 
73 	for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) {
74 		table =  &(ser_ext_par->chainmask_table[i]);
75 		if (table->cap_list) {
76 			qdf_mem_free(table->cap_list);
77 			table->cap_list = NULL;
78 		}
79 	}
80 
81 	return QDF_STATUS_SUCCESS;
82 }
83 
84 qdf_export_symbol(init_deinit_chainmask_table_free);
85 
86 int init_deinit_populate_service_bitmap(void *wmi_handle, uint8_t *event,
87 				      uint32_t *service_bitmap)
88 {
89 	QDF_STATUS status;
90 
91 	status = wmi_save_service_bitmap(wmi_handle, event, service_bitmap);
92 	if (QDF_IS_STATUS_ERROR(status)) {
93 		target_if_err("failed to parse service bitmap");
94 		return qdf_status_to_os_return(status);
95 	}
96 
97 	return 0;
98 }
99 
100 int init_deinit_populate_fw_version_cmd(void *wmi_handle, uint8_t *event)
101 {
102 	QDF_STATUS status;
103 
104 	status = wmi_unified_save_fw_version_cmd(wmi_handle, event);
105 	if (QDF_IS_STATUS_ERROR(status))
106 		target_if_err("failed to save fw version");
107 
108 	return 0;
109 }
110 
111 int init_deinit_populate_target_cap(void *wmi_handle, uint8_t *event,
112 			       struct wlan_psoc_target_capability_info *cap)
113 {
114 	QDF_STATUS status;
115 
116 	status = wmi_get_target_cap_from_service_ready(wmi_handle, event, cap);
117 	if (QDF_IS_STATUS_ERROR(status)) {
118 		target_if_err("failed to parse target cap");
119 		return qdf_status_to_os_return(status);
120 	}
121 
122 	return 0;
123 }
124 
125 int init_deinit_populate_service_ready_ext_param(void *handle, uint8_t *evt,
126 			struct wlan_psoc_host_service_ext_param *param)
127 {
128 	QDF_STATUS status;
129 
130 	status = wmi_extract_service_ready_ext(handle, evt, param);
131 	if (QDF_IS_STATUS_ERROR(status)) {
132 		target_if_err("failed to parse wmi service ready ext param");
133 		return qdf_status_to_os_return(status);
134 	}
135 
136 	return 0;
137 }
138 
139 int init_deinit_populate_chainmask_tables(void *handle, uint8_t *evt,
140 		struct wlan_psoc_host_chainmask_table *param)
141 {
142 	QDF_STATUS status;
143 
144 	status = wmi_extract_chainmask_tables(handle, evt, param);
145 	if (QDF_IS_STATUS_ERROR(status)) {
146 		target_if_err("failed to parse wmi service ready ext param");
147 		return qdf_status_to_os_return(status);
148 	}
149 
150 	return 0;
151 }
152 
153 int init_deinit_populate_mac_phy_capability(void *handle, uint8_t *evt,
154 	struct wlan_psoc_host_hw_mode_caps *hw_cap, struct tgt_info *info)
155 {
156 	QDF_STATUS status;
157 	uint32_t hw_mode_id;
158 	uint32_t phy_bit_map;
159 	uint8_t mac_phy_id;
160 
161 	hw_mode_id = hw_cap->hw_mode_id;
162 	phy_bit_map = hw_cap->phy_id_map;
163 	target_if_debug("hw_mode_id %d phy_bit_map 0x%x",
164 			hw_mode_id, phy_bit_map);
165 
166 	mac_phy_id = 0;
167 	while (phy_bit_map) {
168 		if (info->total_mac_phy_cnt >= PSOC_MAX_MAC_PHY_CAP) {
169 			target_if_err("total mac phy exceeds max limit %d",
170 				      info->total_mac_phy_cnt);
171 			return -EINVAL;
172 		}
173 
174 		status = wmi_extract_mac_phy_cap_service_ready_ext(handle,
175 				evt, hw_mode_id, mac_phy_id,
176 				&(info->mac_phy_cap[info->total_mac_phy_cnt]));
177 		if (QDF_IS_STATUS_ERROR(status)) {
178 			target_if_err("failed to parse mac phy capability");
179 			return qdf_status_to_os_return(status);
180 		}
181 		info->mac_phy_cap[info->total_mac_phy_cnt].hw_mode_config_type
182 					= hw_cap->hw_mode_config_type;
183 		info->total_mac_phy_cnt++;
184 		phy_bit_map &= (phy_bit_map - 1);
185 		mac_phy_id++;
186 	}
187 	target_if_debug("total_mac_phy_cnt %d", info->total_mac_phy_cnt);
188 
189 	return 0;
190 }
191 
192 static int get_hw_mode(void *handle, uint8_t *evt, uint8_t hw_idx,
193 			struct wlan_psoc_host_hw_mode_caps *cap)
194 {
195 	QDF_STATUS status;
196 
197 	status = wmi_extract_hw_mode_cap_service_ready_ext(handle, evt,
198 					hw_idx, cap);
199 	if (QDF_IS_STATUS_ERROR(status)) {
200 		target_if_err("failed to parse hw mode capability");
201 		return qdf_status_to_os_return(status);
202 	}
203 
204 	return 0;
205 }
206 
207 static int get_sar_version(void *handle, uint8_t *evt,
208 			   struct wlan_psoc_host_service_ext_param *ext_param)
209 {
210 	QDF_STATUS status;
211 
212 	status = wmi_extract_sar_cap_service_ready_ext(handle, evt, ext_param);
213 	if (QDF_IS_STATUS_ERROR(status)) {
214 		target_if_err("failed to parse sar capability");
215 		return qdf_status_to_os_return(status);
216 	}
217 
218 	return 0;
219 }
220 
221 static bool new_hw_mode_preferred(uint32_t current_hw_mode,
222 				  uint32_t new_hw_mode)
223 {
224 	uint8_t hw_mode_id_precedence[WMI_HOST_HW_MODE_MAX + 1] = { 5, 1, 4,
225 								    3, 0, 2,
226 								    6 };
227 
228 	if (current_hw_mode > WMI_HOST_HW_MODE_MAX ||
229 	    new_hw_mode > WMI_HOST_HW_MODE_MAX)
230 		return false;
231 
232 	/* Above precedence is defined by low to high, lower the value
233 	 * higher the precedence
234 	 */
235 	if (hw_mode_id_precedence[current_hw_mode] >
236 	    hw_mode_id_precedence[new_hw_mode])
237 		return true;
238 
239 	return false;
240 }
241 
242 /**
243  * select_preferred_mode() - Select preferred hw mode based on current mode.
244  * @tgt_hdl: target_psoc_info object
245  * @hw_mode_caps: HW mode caps of new mode id that needs to checked for
246  *                selection.
247  * @current_mode: Current mode.
248  *
249  * API to select preferred hw mode based on the current config.
250  * Based on host config for preferred mode, final mode selected as follows-
251  * 1) If preferred_mode == WMI_HOST_HW_MODE_DETECT, Then select mode from FW
252  *    supported modes such that it is a super set of all modes FW advertises.
253  *    For e.g., If FW supports DBS(2 radio) and DBS_SBS(3 radio)- Choose DBS_SBS
254  * 2) If preferred_mode == WMI_HOST_HW_MODE_MAX, Then do not select any mode
255  *    from FW advertised modes. Host needs to maintain all modes supported in FW
256  *    and can switch dynamically.
257  * 3) Else, A valid preferred_mode is set, Hence check if this is part of FW
258  *    supported modes. If it is found, then use it to bring up the device.
259  *
260  * Return: selected_mode based on the above criteria.
261  */
262 static uint32_t
263 select_preferred_hw_mode(struct target_psoc_info *tgt_hdl,
264 			 struct wlan_psoc_host_hw_mode_caps *hw_mode_caps,
265 			 uint32_t current_mode)
266 {
267 	uint32_t preferred_mode, selected_mode = current_mode;
268 	struct tgt_info *info;
269 
270 	info = &tgt_hdl->info;
271 	preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl);
272 	if (preferred_mode == WMI_HOST_HW_MODE_DETECT) {
273 		uint32_t new_mode = hw_mode_caps->hw_mode_id;
274 
275 		/* Choose hw_mode_id based on precedence */
276 		if (new_hw_mode_preferred(selected_mode, new_mode)) {
277 			selected_mode = new_mode;
278 			qdf_mem_copy(&info->hw_mode_cap, hw_mode_caps,
279 				     sizeof(info->hw_mode_cap));
280 		}
281 	} else if ((preferred_mode != WMI_HOST_HW_MODE_MAX) &&
282 		   (preferred_mode == hw_mode_caps->hw_mode_id)) {
283 		selected_mode = preferred_mode;
284 		qdf_mem_copy(&info->hw_mode_cap, hw_mode_caps,
285 			     sizeof(info->hw_mode_cap));
286 	}
287 
288 	return selected_mode;
289 }
290 
291 int init_deinit_populate_hw_mode_capability(void *wmi_handle,
292 		uint8_t *event, struct target_psoc_info *tgt_hdl)
293 {
294 	QDF_STATUS status = QDF_STATUS_SUCCESS;
295 	uint8_t hw_idx;
296 	uint32_t num_hw_modes;
297 	struct wlan_psoc_host_hw_mode_caps hw_mode_caps[PSOC_MAX_HW_MODE];
298 	uint32_t preferred_mode, selected_mode = WMI_HOST_HW_MODE_MAX;
299 	struct tgt_info *info;
300 
301 	info = &tgt_hdl->info;
302 	num_hw_modes = info->service_ext_param.num_hw_modes;
303 	if (num_hw_modes > PSOC_MAX_HW_MODE) {
304 		target_if_err("invalid num_hw_modes %d", num_hw_modes);
305 		return -EINVAL;
306 	}
307 	target_if_debug("num_hw_modes %d", num_hw_modes);
308 
309 	qdf_mem_zero(&hw_mode_caps, sizeof(hw_mode_caps));
310 	info->hw_modes.num_modes = 0;
311 	info->hw_mode_cap.hw_mode_id = WMI_HOST_HW_MODE_MAX;
312 
313 	preferred_mode = target_psoc_get_preferred_hw_mode(tgt_hdl);
314 	for (hw_idx = 0; hw_idx < num_hw_modes; hw_idx++) {
315 		status = get_hw_mode(wmi_handle, event, hw_idx,
316 						&hw_mode_caps[hw_idx]);
317 		if (status)
318 			goto return_exit;
319 
320 		if (hw_idx < WMI_HOST_HW_MODE_MAX) {
321 			info->hw_modes.hw_mode_ids[hw_idx] =
322 				hw_mode_caps[hw_idx].hw_mode_id;
323 			info->hw_modes.num_modes++;
324 		}
325 
326 		status = init_deinit_populate_mac_phy_capability(wmi_handle,
327 				event, &hw_mode_caps[hw_idx], info);
328 		if (status)
329 			goto return_exit;
330 
331 		selected_mode = select_preferred_hw_mode(tgt_hdl,
332 							 &hw_mode_caps[hw_idx],
333 							 selected_mode);
334 	}
335 
336 	if (preferred_mode == WMI_HOST_HW_MODE_DETECT) {
337 		target_if_info("Preferred mode is not set, use mode id %d\n",
338 			       selected_mode);
339 		target_psoc_set_preferred_hw_mode(tgt_hdl, selected_mode);
340 	}
341 
342 	status = get_sar_version(wmi_handle, event, &info->service_ext_param);
343 	target_if_debug("sar version %d", info->service_ext_param.sar_version);
344 
345 return_exit:
346 	return qdf_status_to_os_return(status);
347 }
348 
349 int init_deinit_populate_dbr_ring_cap(struct wlan_objmgr_psoc *psoc,
350 			void *handle, uint8_t *event, struct tgt_info *info)
351 
352 {
353 	uint8_t cap_idx;
354 	uint32_t num_dbr_ring_caps;
355 	QDF_STATUS status = QDF_STATUS_SUCCESS;
356 
357 	num_dbr_ring_caps = info->service_ext_param.num_dbr_ring_caps;
358 
359 	target_if_debug("Num DMA Capabilities = %d", num_dbr_ring_caps);
360 
361 	if (!num_dbr_ring_caps)
362 		return 0;
363 
364 	info->dbr_ring_cap = qdf_mem_malloc(
365 				sizeof(struct wlan_psoc_host_dbr_ring_caps) *
366 				num_dbr_ring_caps);
367 
368 	if (!info->dbr_ring_cap) {
369 		target_if_err("Mem alloc for DMA cap failed");
370 		return -EINVAL;
371 	}
372 
373 	for (cap_idx = 0; cap_idx < num_dbr_ring_caps; cap_idx++) {
374 		status = wmi_extract_dbr_ring_cap_service_ready_ext(handle,
375 				event, cap_idx,
376 				&(info->dbr_ring_cap[cap_idx]));
377 		if (QDF_IS_STATUS_ERROR(status)) {
378 			target_if_err("Extraction of DMA cap failed");
379 			goto free_and_return;
380 		}
381 	}
382 
383 	return 0;
384 
385 free_and_return:
386 	qdf_mem_free(info->dbr_ring_cap);
387 	info->dbr_ring_cap = NULL;
388 
389 	return qdf_status_to_os_return(status);
390 }
391 
392 QDF_STATUS init_deinit_dbr_ring_cap_free(
393 		struct target_psoc_info *tgt_psoc_info)
394 {
395 	QDF_STATUS status = QDF_STATUS_SUCCESS;
396 
397 	if (tgt_psoc_info->info.dbr_ring_cap) {
398 		qdf_mem_free(tgt_psoc_info->info.dbr_ring_cap);
399 		tgt_psoc_info->info.dbr_ring_cap = NULL;
400 	}
401 
402 	return status;
403 }
404 qdf_export_symbol(init_deinit_dbr_ring_cap_free);
405 
406 int init_deinit_populate_phy_reg_cap(struct wlan_objmgr_psoc *psoc,
407 				void *handle, uint8_t *event,
408 				struct tgt_info *info, bool service_ready)
409 {
410 	uint8_t reg_idx;
411 	uint32_t num_phy_reg_cap;
412 	QDF_STATUS status = QDF_STATUS_SUCCESS;
413 	struct wlan_psoc_hal_reg_capability cap;
414 	struct wlan_psoc_host_hal_reg_capabilities_ext
415 				reg_cap[PSOC_MAX_PHY_REG_CAP] = {{0} };
416 
417 	if (service_ready) {
418 		status = wmi_extract_hal_reg_cap(handle, event, &cap);
419 		if (QDF_IS_STATUS_ERROR(status)) {
420 			target_if_err("failed to parse hal reg cap");
421 			return qdf_status_to_os_return(status);
422 		}
423 		info->service_ext_param.num_phy = 1;
424 		num_phy_reg_cap = 1;
425 		reg_cap[0].phy_id = 0;
426 		qdf_mem_copy(&(reg_cap[0].eeprom_reg_domain), &cap,
427 			     sizeof(struct wlan_psoc_hal_reg_capability));
428 		target_if_debug("FW wireless modes 0x%x",
429 				reg_cap[0].wireless_modes);
430 	} else {
431 		num_phy_reg_cap = info->service_ext_param.num_phy;
432 		if (num_phy_reg_cap > PSOC_MAX_PHY_REG_CAP) {
433 			target_if_err("Invalid num_phy_reg_cap %d",
434 				      num_phy_reg_cap);
435 			return -EINVAL;
436 		}
437 		target_if_debug("num_phy_reg_cap %d", num_phy_reg_cap);
438 
439 		for (reg_idx = 0; reg_idx < num_phy_reg_cap; reg_idx++) {
440 			status = wmi_extract_reg_cap_service_ready_ext(handle,
441 					event, reg_idx, &(reg_cap[reg_idx]));
442 			if (QDF_IS_STATUS_ERROR(status)) {
443 				target_if_err("failed to parse reg cap");
444 				return qdf_status_to_os_return(status);
445 			}
446 		}
447 	}
448 
449 	status = ucfg_reg_set_hal_reg_cap(psoc, reg_cap, num_phy_reg_cap);
450 
451 	return qdf_status_to_os_return(status);
452 }
453 
454 static bool init_deinit_regdmn_160mhz_support(
455 		struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
456 {
457 	return ((hal_cap->wireless_modes &
458 		WMI_HOST_REGDMN_MODE_11AC_VHT160) != 0);
459 }
460 
461 static bool init_deinit_regdmn_80p80mhz_support(
462 		struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
463 {
464 	return ((hal_cap->wireless_modes &
465 			WMI_HOST_REGDMN_MODE_11AC_VHT80_80) != 0);
466 }
467 
468 static bool init_deinit_vht_160mhz_is_supported(uint32_t vhtcap)
469 {
470 	return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_160) != 0);
471 }
472 
473 static bool init_deinit_vht_80p80mhz_is_supported(uint32_t vhtcap)
474 {
475 	return ((vhtcap & WLAN_VHTCAP_SUP_CHAN_WIDTH_80_160) != 0);
476 }
477 
478 static bool init_deinit_vht_160mhz_shortgi_is_supported(uint32_t vhtcap)
479 {
480 	return ((vhtcap & WLAN_VHTCAP_SHORTGI_160) != 0);
481 }
482 
483 QDF_STATUS init_deinit_validate_160_80p80_fw_caps(
484 		 struct wlan_objmgr_psoc *psoc,
485 		 struct target_psoc_info *tgt_hdl)
486 {
487 	bool wireless_mode_160mhz = false;
488 	bool wireless_mode_80p80mhz = false;
489 	bool vhtcap_160mhz = false;
490 	bool vhtcap_80p80_160mhz = false;
491 	bool vhtcap_160mhz_sgi = false;
492 	bool valid = false;
493 	struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap;
494 	struct common_wmi_handle *wmi_handle;
495 
496 	if (!tgt_hdl) {
497 		target_if_err(
498 		"target_psoc_info is null in validate 160n80p80 cap check");
499 		return QDF_STATUS_E_INVAL;
500 	}
501 
502 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
503 
504 	if ((tgt_hdl->info.target_type == TARGET_TYPE_QCA8074) ||
505 	    (tgt_hdl->info.target_type == TARGET_TYPE_QCA8074V2) ||
506 	    (tgt_hdl->info.target_type == TARGET_TYPE_QCA6018) ||
507 	    (tgt_hdl->info.target_type == TARGET_TYPE_QCA6290)) {
508 		/**
509 		 * Return true for now. This is not available in
510 		 * qca8074 fw yet
511 		 */
512 		return QDF_STATUS_SUCCESS;
513 	}
514 
515 	reg_cap = ucfg_reg_get_hal_reg_cap(psoc);
516 	if (reg_cap == NULL) {
517 		target_if_err("reg cap is NULL");
518 		return QDF_STATUS_E_FAILURE;
519 	}
520 
521 	/* NOTE: Host driver gets vht capability and supported channel
522 	 * width / channel frequency range from FW/HALPHY and obeys it.
523 	 * Host driver is unaware of any physical filters or any other
524 	 * hardware factors that can impact these capabilities.
525 	 * These need to be correctly determined by firmware.
526 	 */
527 
528 	/*This table lists all valid and invalid combinations
529 	 * WMODE160 WMODE80_80  VHTCAP_160 VHTCAP_80+80_160  IsCombinationvalid?
530 	 *      0         0           0              0                 YES
531 	 *      0         0           0              1                 NO
532 	 *      0         0           1              0                 NO
533 	 *      0         0           1              1                 NO
534 	 *      0         1           0              0                 NO
535 	 *      0         1           0              1                 NO
536 	 *      0         1           1              0                 NO
537 	 *      0         1           1              1                 NO
538 	 *      1         0           0              0                 NO
539 	 *      1         0           0              1                 NO
540 	 *      1         0           1              0                 YES
541 	 *      1         0           1              1                 NO
542 	 *      1         1           0              0                 NO
543 	 *      1         1           0              1                 YES
544 	 *      1         1           1              0                 NO
545 	 *      1         1           1              1                 NO
546 	 */
547 
548 	/* NOTE: Last row in above table is invalid because value corresponding
549 	 * to both VHTCAP_160 and VHTCAP_80+80_160 being set is reserved as per
550 	 * 802.11ac. Only one of them can be set at a time.
551 	 */
552 
553 	wireless_mode_160mhz = init_deinit_regdmn_160mhz_support(reg_cap);
554 	wireless_mode_80p80mhz = init_deinit_regdmn_80p80mhz_support(reg_cap);
555 	vhtcap_160mhz = init_deinit_vht_160mhz_is_supported(
556 				tgt_hdl->info.target_caps.vht_cap_info);
557 	vhtcap_80p80_160mhz = init_deinit_vht_80p80mhz_is_supported(
558 				tgt_hdl->info.target_caps.vht_cap_info);
559 	vhtcap_160mhz_sgi = init_deinit_vht_160mhz_shortgi_is_supported(
560 				tgt_hdl->info.target_caps.vht_cap_info);
561 
562 	if (!(wireless_mode_160mhz || wireless_mode_80p80mhz ||
563 	      vhtcap_160mhz || vhtcap_80p80_160mhz)) {
564 		valid = QDF_STATUS_SUCCESS;
565 	} else if (wireless_mode_160mhz && !wireless_mode_80p80mhz &&
566 		   vhtcap_160mhz && !vhtcap_80p80_160mhz) {
567 		valid = QDF_STATUS_SUCCESS;
568 	} else if (wireless_mode_160mhz && wireless_mode_80p80mhz &&
569 		   !vhtcap_160mhz && vhtcap_160mhz_sgi) {
570 		valid = QDF_STATUS_SUCCESS;
571 	}
572 
573 	if (valid == QDF_STATUS_SUCCESS) {
574 		/*
575 		 * Ensure short GI for 160 MHz is enabled
576 		 * only if 160/80+80 is supported.
577 		 */
578 		if (vhtcap_160mhz_sgi &&
579 		    !(vhtcap_160mhz || vhtcap_80p80_160mhz)) {
580 			valid = QDF_STATUS_E_FAILURE;
581 		}
582 	}
583 
584 	/* Invalid config specified by FW */
585 	if (valid != QDF_STATUS_SUCCESS) {
586 		target_if_err("Invalid 160/80+80 MHz config specified by FW. Take care of it first");
587 		target_if_err("wireless_mode_160mhz: %d, wireless_mode_80p80mhz: %d",
588 			      wireless_mode_160mhz, wireless_mode_80p80mhz);
589 		target_if_err("vhtcap_160mhz: %d, vhtcap_80p80_160mhz: %d,vhtcap_160mhz_sgi: %d",
590 			      vhtcap_160mhz, vhtcap_80p80_160mhz,
591 			      vhtcap_160mhz_sgi);
592 	}
593 	return valid;
594 }
595 
596 void init_deinit_chainmask_config(
597 		 struct wlan_objmgr_psoc *psoc,
598 		 struct target_psoc_info *tgt_hdl)
599 {
600 	tgt_hdl->info.wlan_res_cfg.tx_chain_mask =
601 		((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1);
602 	tgt_hdl->info.wlan_res_cfg.rx_chain_mask =
603 		((1 << tgt_hdl->info.target_caps.num_rf_chains) - 1);
604 }
605 
606 QDF_STATUS init_deinit_is_service_ext_msg(
607 		 struct wlan_objmgr_psoc *psoc,
608 		 struct target_psoc_info *tgt_hdl)
609 {
610 	struct common_wmi_handle *wmi_handle;
611 
612 	if (!tgt_hdl) {
613 		target_if_err(
614 			"psoc target_psoc_info is null in service ext msg");
615 		return QDF_STATUS_E_INVAL;
616 	}
617 
618 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
619 
620 	if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg))
621 		return QDF_STATUS_SUCCESS;
622 	else
623 		return QDF_STATUS_E_FAILURE;
624 }
625 
626 bool init_deinit_is_preferred_hw_mode_supported(
627 		 struct wlan_objmgr_psoc *psoc,
628 		 struct target_psoc_info *tgt_hdl)
629 {
630 	uint16_t i;
631 	struct tgt_info *info;
632 
633 	if (!tgt_hdl) {
634 		target_if_err(
635 			"psoc target_psoc_info is null in service ext msg");
636 		return FALSE;
637 	}
638 
639 	info = &tgt_hdl->info;
640 
641 	if (info->preferred_hw_mode == WMI_HOST_HW_MODE_MAX)
642 		return TRUE;
643 
644 	for (i = 0; i < target_psoc_get_total_mac_phy_cnt(tgt_hdl); i++) {
645 		if (info->mac_phy_cap[i].hw_mode_id == info->preferred_hw_mode)
646 			return TRUE;
647 	}
648 
649 	return FALSE;
650 }
651 
652 void init_deinit_wakeup_host_wait(
653 		 struct wlan_objmgr_psoc *psoc,
654 		 struct target_psoc_info *tgt_hdl)
655 {
656 	if (!tgt_hdl) {
657 		target_if_err("psoc target_psoc_info is null in target ready");
658 		return;
659 	}
660 	qdf_event_set(&tgt_hdl->info.event);
661 }
662