xref: /wlan-driver/qca-wifi-host-cmn/target_if/init_deinit/src/init_cmd_api.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  * DOC: init_cmd_api.c
22*5113495bSYour Name  *
23*5113495bSYour Name  * WMI Init command prepare & send APIs
24*5113495bSYour Name  */
25*5113495bSYour Name #include <qdf_status.h>
26*5113495bSYour Name #include <qdf_types.h>
27*5113495bSYour Name #include <wlan_objmgr_psoc_obj.h>
28*5113495bSYour Name #include <wlan_objmgr_pdev_obj.h>
29*5113495bSYour Name #include <target_if.h>
30*5113495bSYour Name #include <service_ready_util.h>
31*5113495bSYour Name #include <wlan_tgt_def_config.h>
32*5113495bSYour Name #include <wlan_reg_ucfg_api.h>
33*5113495bSYour Name #include <init_cmd_api.h>
34*5113495bSYour Name #include <target_if_scan.h>
35*5113495bSYour Name #include <target_if_reg.h>
36*5113495bSYour Name #include <target_if_twt.h>
37*5113495bSYour Name #include <cdp_txrx_ctrl.h>
38*5113495bSYour Name 
39*5113495bSYour Name /**
40*5113495bSYour Name  *  init_deinit_alloc_host_mem_chunk() - allocates chunk of memory requested
41*5113495bSYour Name  *                                       by FW.
42*5113495bSYour Name  *  @psoc: PSOC object
43*5113495bSYour Name  *  @tgt_hdl: Target PSOC info
44*5113495bSYour Name  *  @req_id: request id
45*5113495bSYour Name  *  @idx: chunk id
46*5113495bSYour Name  *  @num_units: Number of units
47*5113495bSYour Name  *  @unit_len: Unit length
48*5113495bSYour Name  *  @num_unit_info: Num unit info
49*5113495bSYour Name  *
50*5113495bSYour Name  *  API to allocate host memory chunk requested by FW
51*5113495bSYour Name  *
52*5113495bSYour Name  *  Return: num_units on successful allocation
53*5113495bSYour Name  *          0 on failure
54*5113495bSYour Name  */
init_deinit_alloc_host_mem_chunk(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl,u_int32_t req_id,u_int32_t idx,u_int32_t num_units,u_int32_t unit_len,u_int32_t num_unit_info)55*5113495bSYour Name static uint32_t init_deinit_alloc_host_mem_chunk(struct wlan_objmgr_psoc *psoc,
56*5113495bSYour Name 			struct target_psoc_info *tgt_hdl,
57*5113495bSYour Name 			u_int32_t req_id, u_int32_t idx, u_int32_t num_units,
58*5113495bSYour Name 			u_int32_t unit_len, u_int32_t num_unit_info)
59*5113495bSYour Name {
60*5113495bSYour Name 	qdf_dma_addr_t paddr;
61*5113495bSYour Name 	uint32_t ichunk = 0;
62*5113495bSYour Name 	struct tgt_info *info;
63*5113495bSYour Name 	qdf_device_t qdf_dev;
64*5113495bSYour Name 
65*5113495bSYour Name 	info = (&tgt_hdl->info);
66*5113495bSYour Name 
67*5113495bSYour Name 	if (!num_units  || !unit_len)
68*5113495bSYour Name 		return 0;
69*5113495bSYour Name 
70*5113495bSYour Name 	qdf_dev = wlan_psoc_get_qdf_dev(psoc);
71*5113495bSYour Name 	if (!qdf_dev)
72*5113495bSYour Name 		return 0;
73*5113495bSYour Name 
74*5113495bSYour Name 	/*
75*5113495bSYour Name 	 * We have skip smaller chunks memory allocation for TXBF_CV and
76*5113495bSYour Name 	 * CFR_CAPTURE buffer as Firmware is expecting continuous memory
77*5113495bSYour Name 	 */
78*5113495bSYour Name 	if (!((num_unit_info & HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED) &&
79*5113495bSYour Name 	      (req_id == TXBF_CV_POOL0 || req_id == TXBF_CV_POOL1 ||
80*5113495bSYour Name 	      req_id == TXBF_CV_POOL2 ||
81*5113495bSYour Name 	      req_id == CFR_CAPTURE_HOST_MEM_REQ_ID))) {
82*5113495bSYour Name 		ichunk = ((num_units * unit_len) >>
83*5113495bSYour Name 			HOST_MEM_CHUNK_MAX_SIZE_POWER2);
84*5113495bSYour Name 		if (ichunk)
85*5113495bSYour Name 			num_units = num_units / (ichunk + 1);
86*5113495bSYour Name 	}
87*5113495bSYour Name 
88*5113495bSYour Name 	info->mem_chunks[idx].vaddr = NULL;
89*5113495bSYour Name 	/* reduce the requested allocation by half until allocation succeeds */
90*5113495bSYour Name 	while (!info->mem_chunks[idx].vaddr && num_units) {
91*5113495bSYour Name 		info->mem_chunks[idx].vaddr = qdf_mem_alloc_consistent(qdf_dev,
92*5113495bSYour Name 				qdf_dev->dev, num_units * unit_len, &paddr);
93*5113495bSYour Name 		if (!info->mem_chunks[idx].vaddr) {
94*5113495bSYour Name 			if (num_unit_info &
95*5113495bSYour Name 					HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED) {
96*5113495bSYour Name 				num_units = 0;
97*5113495bSYour Name 				target_if_err("mem chink alloc failed for %d",
98*5113495bSYour Name 					      idx);
99*5113495bSYour Name 				break;
100*5113495bSYour Name 			}
101*5113495bSYour Name 			/* reduce length by half */
102*5113495bSYour Name 			num_units = (num_units >> 1);
103*5113495bSYour Name 		} else {
104*5113495bSYour Name 			info->mem_chunks[idx].paddr = paddr;
105*5113495bSYour Name 			info->mem_chunks[idx].len = num_units*unit_len;
106*5113495bSYour Name 			info->mem_chunks[idx].req_id =  req_id;
107*5113495bSYour Name 		}
108*5113495bSYour Name 	}
109*5113495bSYour Name 	target_if_debug("req_id %d idx %d num_units %d unit_len %d",
110*5113495bSYour Name 			req_id, idx, num_units, unit_len);
111*5113495bSYour Name 
112*5113495bSYour Name 	return num_units;
113*5113495bSYour Name }
114*5113495bSYour Name 
115*5113495bSYour Name /* Host mem size units, it is used for round-off */
116*5113495bSYour Name #define HOST_MEM_SIZE_UNIT 4
117*5113495bSYour Name 
118*5113495bSYour Name /**
119*5113495bSYour Name  *  init_deinit_alloc_host_mem() - allocates amount of memory requested by FW.
120*5113495bSYour Name  *  @psoc: PSOC object
121*5113495bSYour Name  *  @tgt_hdl: Target PSOC info
122*5113495bSYour Name  *  @req_id: request id
123*5113495bSYour Name  *  @num_units: Number of units
124*5113495bSYour Name  *  @unit_len: Unit length
125*5113495bSYour Name  *  @num_unit_info: Num unit info
126*5113495bSYour Name  *
127*5113495bSYour Name  *  API to allocate host memory requested by FW
128*5113495bSYour Name  *
129*5113495bSYour Name  *  Return: QDF_STATUS_SUCCESS on successful allocation
130*5113495bSYour Name  *          QDF_STATUS_E_FAILURE on failure
131*5113495bSYour Name  */
init_deinit_alloc_host_mem(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl,u_int32_t req_id,u_int32_t num_units,u_int32_t unit_len,u_int32_t num_unit_info)132*5113495bSYour Name static QDF_STATUS init_deinit_alloc_host_mem(struct wlan_objmgr_psoc *psoc,
133*5113495bSYour Name 		struct target_psoc_info *tgt_hdl, u_int32_t req_id,
134*5113495bSYour Name 		u_int32_t num_units, u_int32_t unit_len,
135*5113495bSYour Name 		u_int32_t num_unit_info)
136*5113495bSYour Name {
137*5113495bSYour Name 	struct tgt_info *info;
138*5113495bSYour Name 	uint32_t remaining_units;
139*5113495bSYour Name 	uint32_t allocated_units = 0;
140*5113495bSYour Name 	uint32_t idx;
141*5113495bSYour Name 
142*5113495bSYour Name 	info = (&tgt_hdl->info);
143*5113495bSYour Name 	/* adjust the length to nearest multiple of unit size */
144*5113495bSYour Name 	unit_len = (unit_len + (HOST_MEM_SIZE_UNIT - 1)) &
145*5113495bSYour Name 				(~(HOST_MEM_SIZE_UNIT - 1));
146*5113495bSYour Name 	idx = info->num_mem_chunks;
147*5113495bSYour Name 	remaining_units = num_units;
148*5113495bSYour Name 
149*5113495bSYour Name 	while (remaining_units) {
150*5113495bSYour Name 		if (idx == MAX_MEM_CHUNKS) {
151*5113495bSYour Name 			target_if_err(
152*5113495bSYour Name 				"REACHED MAX CHUNK LIMIT for mem units %d",
153*5113495bSYour Name 					num_units);
154*5113495bSYour Name 			target_if_err(
155*5113495bSYour Name 			"unit len %d requested by FW, only allocated %d",
156*5113495bSYour Name 				unit_len, (num_units - remaining_units));
157*5113495bSYour Name 			info->num_mem_chunks = idx;
158*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
159*5113495bSYour Name 		}
160*5113495bSYour Name 
161*5113495bSYour Name 		if ((tgt_hdl->tif_ops) &&
162*5113495bSYour Name 		    (tgt_hdl->tif_ops->mem_mgr_alloc_chunk))
163*5113495bSYour Name 			allocated_units = tgt_hdl->tif_ops->mem_mgr_alloc_chunk(
164*5113495bSYour Name 						psoc, tgt_hdl, req_id, idx,
165*5113495bSYour Name 						remaining_units,
166*5113495bSYour Name 						unit_len, num_unit_info);
167*5113495bSYour Name 		else
168*5113495bSYour Name 			allocated_units = init_deinit_alloc_host_mem_chunk(
169*5113495bSYour Name 						psoc, tgt_hdl, req_id, idx,
170*5113495bSYour Name 						remaining_units,
171*5113495bSYour Name 						unit_len, num_unit_info);
172*5113495bSYour Name 		if (allocated_units == 0) {
173*5113495bSYour Name 			target_if_err("FAILED TO ALLOC mem unit len %d",
174*5113495bSYour Name 				      unit_len);
175*5113495bSYour Name 			target_if_err("units requested %d units allocated %d",
176*5113495bSYour Name 				      num_units, (num_units - remaining_units));
177*5113495bSYour Name 			info->num_mem_chunks = idx;
178*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
179*5113495bSYour Name 		}
180*5113495bSYour Name 		remaining_units -= allocated_units;
181*5113495bSYour Name 		++idx;
182*5113495bSYour Name 	}
183*5113495bSYour Name 	info->num_mem_chunks = idx;
184*5113495bSYour Name 
185*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
186*5113495bSYour Name }
187*5113495bSYour Name 
init_deinit_free_num_units(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl)188*5113495bSYour Name QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc,
189*5113495bSYour Name 			struct target_psoc_info *tgt_hdl)
190*5113495bSYour Name {
191*5113495bSYour Name 	struct tgt_info *info;
192*5113495bSYour Name 	qdf_device_t qdf_dev;
193*5113495bSYour Name 	uint32_t idx;
194*5113495bSYour Name 	QDF_STATUS status;
195*5113495bSYour Name 
196*5113495bSYour Name 	if (!tgt_hdl) {
197*5113495bSYour Name 		target_if_err("target_psoc_info is null");
198*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
199*5113495bSYour Name 	}
200*5113495bSYour Name 
201*5113495bSYour Name 	if ((tgt_hdl->tif_ops) &&
202*5113495bSYour Name 	    (tgt_hdl->tif_ops->mem_mgr_free_chunks)) {
203*5113495bSYour Name 		status = tgt_hdl->tif_ops->mem_mgr_free_chunks(psoc, tgt_hdl);
204*5113495bSYour Name 	} else {
205*5113495bSYour Name 		qdf_dev = wlan_psoc_get_qdf_dev(psoc);
206*5113495bSYour Name 		if (!qdf_dev) {
207*5113495bSYour Name 			target_if_err("qdf_dev is null");
208*5113495bSYour Name 			QDF_BUG(0);
209*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
210*5113495bSYour Name 		}
211*5113495bSYour Name 		info = (&tgt_hdl->info);
212*5113495bSYour Name 		for (idx = 0; idx < info->num_mem_chunks; idx++) {
213*5113495bSYour Name 			qdf_mem_free_consistent(
214*5113495bSYour Name 					qdf_dev, qdf_dev->dev,
215*5113495bSYour Name 					info->mem_chunks[idx].len,
216*5113495bSYour Name 					info->mem_chunks[idx].vaddr,
217*5113495bSYour Name 					info->mem_chunks[idx].paddr,
218*5113495bSYour Name 					qdf_get_dma_mem_context(
219*5113495bSYour Name 					(&info->mem_chunks[idx]), memctx));
220*5113495bSYour Name 
221*5113495bSYour Name 			info->mem_chunks[idx].vaddr = NULL;
222*5113495bSYour Name 			info->mem_chunks[idx].paddr = 0;
223*5113495bSYour Name 			info->mem_chunks[idx].len = 0;
224*5113495bSYour Name 		}
225*5113495bSYour Name 		info->num_mem_chunks = 0;
226*5113495bSYour Name 		status = QDF_STATUS_SUCCESS;
227*5113495bSYour Name 	}
228*5113495bSYour Name 
229*5113495bSYour Name 	return status;
230*5113495bSYour Name }
231*5113495bSYour Name 
init_deinit_handle_host_mem_req(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl,uint8_t * event)232*5113495bSYour Name QDF_STATUS init_deinit_handle_host_mem_req(
233*5113495bSYour Name 		struct wlan_objmgr_psoc *psoc,
234*5113495bSYour Name 		struct target_psoc_info *tgt_hdl, uint8_t *event)
235*5113495bSYour Name {
236*5113495bSYour Name 	uint32_t num_mem_reqs;
237*5113495bSYour Name 	host_mem_req mem_reqs;
238*5113495bSYour Name 	uint32_t i;
239*5113495bSYour Name 	uint32_t idx;
240*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
241*5113495bSYour Name 	struct wmi_unified *wmi_handle;
242*5113495bSYour Name 	struct tgt_info *info;
243*5113495bSYour Name 
244*5113495bSYour Name 	if (!tgt_hdl) {
245*5113495bSYour Name 		target_if_err("target_psoc_info is null");
246*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
247*5113495bSYour Name 	}
248*5113495bSYour Name 
249*5113495bSYour Name 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
250*5113495bSYour Name 	info = (&tgt_hdl->info);
251*5113495bSYour Name 
252*5113495bSYour Name 	num_mem_reqs = wmi_extract_num_mem_reqs_from_service_ready(
253*5113495bSYour Name 							wmi_handle, event);
254*5113495bSYour Name 	if (!num_mem_reqs)
255*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
256*5113495bSYour Name 
257*5113495bSYour Name 	if (num_mem_reqs > MAX_MEM_CHUNKS) {
258*5113495bSYour Name 		target_if_err_rl("num_mem_reqs:%u is out of bounds",
259*5113495bSYour Name 				num_mem_reqs);
260*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
261*5113495bSYour Name 	}
262*5113495bSYour Name 
263*5113495bSYour Name 	for (i = 0; i < WMI_FW_PRIORITY_MAX; i++) {
264*5113495bSYour Name 		for (idx = 0; idx < num_mem_reqs; idx++) {
265*5113495bSYour Name 			status = wmi_extract_host_mem_req_from_service_ready(
266*5113495bSYour Name 					wmi_handle, event, &mem_reqs,
267*5113495bSYour Name 					info->wlan_res_cfg.num_active_peers,
268*5113495bSYour Name 					info->wlan_res_cfg.num_peers, i, idx);
269*5113495bSYour Name 			if (mem_reqs.tgt_num_units) {
270*5113495bSYour Name 				status = init_deinit_alloc_host_mem(
271*5113495bSYour Name 						psoc,
272*5113495bSYour Name 						tgt_hdl,
273*5113495bSYour Name 						mem_reqs.req_id,
274*5113495bSYour Name 						mem_reqs.tgt_num_units,
275*5113495bSYour Name 						mem_reqs.unit_size,
276*5113495bSYour Name 						mem_reqs.num_unit_info);
277*5113495bSYour Name 				if (status == QDF_STATUS_E_FAILURE) {
278*5113495bSYour Name 					target_if_err("num_mem_chunk exceeds supp number");
279*5113495bSYour Name 				} else if (status == QDF_STATUS_E_NOMEM) {
280*5113495bSYour Name 					target_if_err("mem alloc failure");
281*5113495bSYour Name 				}
282*5113495bSYour Name 			}
283*5113495bSYour Name 
284*5113495bSYour Name 			if (status != QDF_STATUS_SUCCESS)
285*5113495bSYour Name 				return status;
286*5113495bSYour Name 		}
287*5113495bSYour Name 	}
288*5113495bSYour Name 
289*5113495bSYour Name 	return status;
290*5113495bSYour Name }
291*5113495bSYour Name 
292*5113495bSYour Name #ifdef FEATURE_NO_DBS_INTRABAND_MCC_SUPPORT
293*5113495bSYour Name /**
294*5113495bSYour Name  * is_num_band_to_mac_required() - host needs to configure MACs or not.
295*5113495bSYour Name  * @tgt_hdl: Pointer to target handle
296*5113495bSYour Name  *
297*5113495bSYour Name  * if num of mac per band is sent by host then FW will not initialize
298*5113495bSYour Name  * its data structure with its default value. Host either have to set
299*5113495bSYour Name  * these value as per current HW mode or else these variable should be
300*5113495bSYour Name  * initialized to 0.
301*5113495bSYour Name  * Ex - If host is sending default HW mode as DBS in INIT_CMDID and FW
302*5113495bSYour Name  * doesn't advertise wmi_service_dual_band_simultaneous_support then host
303*5113495bSYour Name  * must not configure MACs and FW should configure with default values.
304*5113495bSYour Name  *
305*5113495bSYour Name  * @return: true if host needs to configure MACs else false
306*5113495bSYour Name  */
is_num_band_to_mac_required(struct target_psoc_info * tgt_hdl)307*5113495bSYour Name static bool is_num_band_to_mac_required(struct target_psoc_info *tgt_hdl)
308*5113495bSYour Name {
309*5113495bSYour Name 	struct tgt_info *info;
310*5113495bSYour Name 	struct wmi_unified *wmi_handle;
311*5113495bSYour Name 
312*5113495bSYour Name 	if (!tgt_hdl)
313*5113495bSYour Name 		return true;
314*5113495bSYour Name 
315*5113495bSYour Name 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
316*5113495bSYour Name 	info = (&tgt_hdl->info);
317*5113495bSYour Name 
318*5113495bSYour Name 	if ((info->hw_modes.num_modes == 1) &&
319*5113495bSYour Name 	    (info->hw_modes.hw_mode_ids[0] == WMI_HOST_HW_MODE_DBS) &&
320*5113495bSYour Name 	    !wmi_service_enabled(wmi_handle,
321*5113495bSYour Name 				 wmi_service_dual_band_simultaneous_support))
322*5113495bSYour Name 		return false;
323*5113495bSYour Name 
324*5113495bSYour Name 	return true;
325*5113495bSYour Name }
326*5113495bSYour Name #else
is_num_band_to_mac_required(struct target_psoc_info * tgt_hdl)327*5113495bSYour Name static bool is_num_band_to_mac_required(struct target_psoc_info *tgt_hdl)
328*5113495bSYour Name {
329*5113495bSYour Name 	return true;
330*5113495bSYour Name }
331*5113495bSYour Name #endif
332*5113495bSYour Name 
init_deinit_derive_band_to_mac_param(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl,struct wmi_init_cmd_param * init_param)333*5113495bSYour Name void init_deinit_derive_band_to_mac_param(
334*5113495bSYour Name 		struct wlan_objmgr_psoc *psoc,
335*5113495bSYour Name 		struct target_psoc_info *tgt_hdl,
336*5113495bSYour Name 		struct wmi_init_cmd_param *init_param)
337*5113495bSYour Name {
338*5113495bSYour Name 	uint8_t i;
339*5113495bSYour Name 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap;
340*5113495bSYour Name 	struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap;
341*5113495bSYour Name 	struct wmi_host_pdev_band_to_mac *band_to_mac = init_param->band_to_mac;
342*5113495bSYour Name 
343*5113495bSYour Name 	if (!tgt_hdl) {
344*5113495bSYour Name 		target_if_err("target_psoc_info is null ");
345*5113495bSYour Name 		return;
346*5113495bSYour Name 	}
347*5113495bSYour Name 
348*5113495bSYour Name 	reg_cap = ucfg_reg_get_hal_reg_cap(psoc);
349*5113495bSYour Name 	if (!reg_cap) {
350*5113495bSYour Name 		target_if_err("reg cap is NULL");
351*5113495bSYour Name 		return;
352*5113495bSYour Name 	}
353*5113495bSYour Name 
354*5113495bSYour Name 	mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
355*5113495bSYour Name 	if (!mac_phy_cap) {
356*5113495bSYour Name 		target_if_err("mac_phy_cap is NULL");
357*5113495bSYour Name 		return;
358*5113495bSYour Name 	}
359*5113495bSYour Name 	if (is_num_band_to_mac_required(tgt_hdl))
360*5113495bSYour Name 		init_param->num_band_to_mac =
361*5113495bSYour Name 			target_psoc_get_num_radios(tgt_hdl);
362*5113495bSYour Name 
363*5113495bSYour Name 	for (i = 0; i < target_psoc_get_num_radios(tgt_hdl); i++) {
364*5113495bSYour Name 		if (mac_phy_cap->supported_bands ==
365*5113495bSYour Name 			(WMI_HOST_WLAN_5G_CAPABILITY |
366*5113495bSYour Name 					WMI_HOST_WLAN_2G_CAPABILITY)) {
367*5113495bSYour Name 			/*Supports both 5G and 2G. Use freq from both radios*/
368*5113495bSYour Name 			target_if_debug("Supports both 2G and 5G");
369*5113495bSYour Name 			band_to_mac[i].pdev_id = mac_phy_cap->pdev_id;
370*5113495bSYour Name 			band_to_mac[i].start_freq =
371*5113495bSYour Name 					reg_cap[i].low_2ghz_chan;
372*5113495bSYour Name 			band_to_mac[i].end_freq =
373*5113495bSYour Name 					reg_cap[i].high_5ghz_chan;
374*5113495bSYour Name 
375*5113495bSYour Name 		} else if (mac_phy_cap->supported_bands ==
376*5113495bSYour Name 				WMI_HOST_WLAN_2G_CAPABILITY) {
377*5113495bSYour Name 			reg_cap[mac_phy_cap->phy_id].low_5ghz_chan = 0;
378*5113495bSYour Name 			reg_cap[mac_phy_cap->phy_id].high_5ghz_chan = 0;
379*5113495bSYour Name 
380*5113495bSYour Name 			if (!init_param->num_band_to_mac)
381*5113495bSYour Name 				goto next_mac_phy_cap;
382*5113495bSYour Name 
383*5113495bSYour Name 			band_to_mac[i].pdev_id = mac_phy_cap->pdev_id;
384*5113495bSYour Name 			band_to_mac[i].start_freq =
385*5113495bSYour Name 					reg_cap[i].low_2ghz_chan;
386*5113495bSYour Name 			band_to_mac[i].end_freq =
387*5113495bSYour Name 					reg_cap[i].high_2ghz_chan;
388*5113495bSYour Name 			target_if_debug("2G radio - pdev_id = %d start_freq = %d end_freq= %d",
389*5113495bSYour Name 				       band_to_mac[i].pdev_id,
390*5113495bSYour Name 				       band_to_mac[i].start_freq,
391*5113495bSYour Name 				       band_to_mac[i].end_freq);
392*5113495bSYour Name 
393*5113495bSYour Name 		} else if (mac_phy_cap->supported_bands ==
394*5113495bSYour Name 					WMI_HOST_WLAN_5G_CAPABILITY) {
395*5113495bSYour Name 			reg_cap[mac_phy_cap->phy_id].low_2ghz_chan = 0;
396*5113495bSYour Name 			reg_cap[mac_phy_cap->phy_id].high_2ghz_chan = 0;
397*5113495bSYour Name 
398*5113495bSYour Name 			if (!init_param->num_band_to_mac)
399*5113495bSYour Name 				goto next_mac_phy_cap;
400*5113495bSYour Name 
401*5113495bSYour Name 			band_to_mac[i].pdev_id = mac_phy_cap->pdev_id;
402*5113495bSYour Name 			band_to_mac[i].start_freq =
403*5113495bSYour Name 						reg_cap[i].low_5ghz_chan;
404*5113495bSYour Name 			band_to_mac[i].end_freq =
405*5113495bSYour Name 						reg_cap[i].high_5ghz_chan;
406*5113495bSYour Name 
407*5113495bSYour Name 			target_if_debug("5G radio -pdev_id = %d start_freq = %d end_freq =%d\n",
408*5113495bSYour Name 				       band_to_mac[i].pdev_id,
409*5113495bSYour Name 				       band_to_mac[i].start_freq,
410*5113495bSYour Name 				       band_to_mac[i].end_freq);
411*5113495bSYour Name 		}
412*5113495bSYour Name 
413*5113495bSYour Name next_mac_phy_cap:
414*5113495bSYour Name 		mac_phy_cap++;
415*5113495bSYour Name 	}
416*5113495bSYour Name }
417*5113495bSYour Name 
418*5113495bSYour Name #if defined(CONFIG_AFC_SUPPORT)
419*5113495bSYour Name /**
420*5113495bSYour Name  * init_deinit_derive_afc_dev_type_param() - Derive AFC init deployment param
421*5113495bSYour Name  *
422*5113495bSYour Name  * @psoc: PSOC object
423*5113495bSYour Name  * @init_param: Pointer to init param
424*5113495bSYour Name  *
425*5113495bSYour Name  * Return: void
426*5113495bSYour Name  */
init_deinit_derive_afc_dev_type_param(struct wlan_objmgr_psoc * psoc,struct wmi_init_cmd_param * init_param)427*5113495bSYour Name static void init_deinit_derive_afc_dev_type_param(
428*5113495bSYour Name 		struct wlan_objmgr_psoc *psoc,
429*5113495bSYour Name 		struct wmi_init_cmd_param *init_param)
430*5113495bSYour Name {
431*5113495bSYour Name 	enum reg_afc_dev_deploy_type reg_afc_dev_type;
432*5113495bSYour Name 	target_resource_config *tgt_cfg;
433*5113495bSYour Name 	QDF_STATUS ret_val;
434*5113495bSYour Name 
435*5113495bSYour Name 	tgt_cfg = init_param->res_cfg;
436*5113495bSYour Name 
437*5113495bSYour Name 	ret_val = target_if_reg_get_afc_dev_type(psoc,
438*5113495bSYour Name 						 &reg_afc_dev_type);
439*5113495bSYour Name 
440*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret_val)) {
441*5113495bSYour Name 		target_if_err("get afc dev type failed");
442*5113495bSYour Name 		return;
443*5113495bSYour Name 	}
444*5113495bSYour Name 	tgt_cfg->afc_indoor_support = false;
445*5113495bSYour Name 	tgt_cfg->afc_outdoor_support = false;
446*5113495bSYour Name 	if (reg_afc_dev_type == AFC_DEPLOYMENT_INDOOR)
447*5113495bSYour Name 		tgt_cfg->afc_indoor_support = true;
448*5113495bSYour Name 	else if (reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR)
449*5113495bSYour Name 		tgt_cfg->afc_outdoor_support = true;
450*5113495bSYour Name }
451*5113495bSYour Name #else
init_deinit_derive_afc_dev_type_param(struct wlan_objmgr_psoc * psoc,struct wmi_init_cmd_param * init_param)452*5113495bSYour Name static inline void init_deinit_derive_afc_dev_type_param(
453*5113495bSYour Name 		struct wlan_objmgr_psoc *psoc,
454*5113495bSYour Name 		struct wmi_init_cmd_param *init_param)
455*5113495bSYour Name {
456*5113495bSYour Name }
457*5113495bSYour Name #endif
458*5113495bSYour Name 
459*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
460*5113495bSYour Name #ifdef FEATURE_WLAN_TDLS
461*5113495bSYour Name static void
init_deinit_set_tdls_mlo_vdev(struct wmi_init_cmd_param * init_param,struct wmi_unified * wmi_handle)462*5113495bSYour Name init_deinit_set_tdls_mlo_vdev(struct wmi_init_cmd_param *init_param,
463*5113495bSYour Name 			      struct wmi_unified *wmi_handle)
464*5113495bSYour Name {
465*5113495bSYour Name 	if (wmi_service_enabled(wmi_handle, wmi_service_tdls_mlo_support))
466*5113495bSYour Name 		init_param->res_cfg->num_tdls_vdevs = WLAN_UMAC_MLO_MAX_VDEVS;
467*5113495bSYour Name }
468*5113495bSYour Name #else
469*5113495bSYour Name static void
init_deinit_set_tdls_mlo_vdev(struct wmi_init_cmd_param * init_param,struct wmi_unified * wmi_handle)470*5113495bSYour Name init_deinit_set_tdls_mlo_vdev(struct wmi_init_cmd_param *init_param,
471*5113495bSYour Name 			      struct wmi_unified *wmi_handle)
472*5113495bSYour Name {}
473*5113495bSYour Name #endif
474*5113495bSYour Name #else
475*5113495bSYour Name static void
init_deinit_set_tdls_mlo_vdev(struct wmi_init_cmd_param * init_param,struct wmi_unified * wmi_handle)476*5113495bSYour Name init_deinit_set_tdls_mlo_vdev(struct wmi_init_cmd_param *init_param,
477*5113495bSYour Name 			      struct wmi_unified *wmi_handle)
478*5113495bSYour Name {}
479*5113495bSYour Name #endif
480*5113495bSYour Name 
481*5113495bSYour Name /**
482*5113495bSYour Name  * init_deinit_set_dp_rx_peer_metadata_ver() - update RX peer metadata
483*5113495bSYour Name  *                                             version to DP
484*5113495bSYour Name  * @psoc: PSOC object
485*5113495bSYour Name  * @peer_md_ver: peer metadata version value
486*5113495bSYour Name  *
487*5113495bSYour Name  * Return: None
488*5113495bSYour Name  */
489*5113495bSYour Name static void
init_deinit_set_dp_rx_peer_metadata_ver(struct wlan_objmgr_psoc * psoc,uint8_t peer_md_ver)490*5113495bSYour Name init_deinit_set_dp_rx_peer_metadata_ver(struct wlan_objmgr_psoc *psoc,
491*5113495bSYour Name 					uint8_t peer_md_ver)
492*5113495bSYour Name {
493*5113495bSYour Name 	ol_txrx_soc_handle soc;
494*5113495bSYour Name 	cdp_config_param_type val = {0};
495*5113495bSYour Name 
496*5113495bSYour Name 	val.cdp_peer_metadata_ver = peer_md_ver;
497*5113495bSYour Name 	soc = wlan_psoc_get_dp_handle(psoc);
498*5113495bSYour Name 
499*5113495bSYour Name 	cdp_txrx_set_psoc_param(soc, CDP_CFG_RX_PEER_METADATA_VER,
500*5113495bSYour Name 				val);
501*5113495bSYour Name }
502*5113495bSYour Name 
init_deinit_prepare_send_init_cmd(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl)503*5113495bSYour Name void init_deinit_prepare_send_init_cmd(
504*5113495bSYour Name 		 struct wlan_objmgr_psoc *psoc,
505*5113495bSYour Name 		 struct target_psoc_info *tgt_hdl)
506*5113495bSYour Name {
507*5113495bSYour Name 	struct wmi_init_cmd_param init_param = {0};
508*5113495bSYour Name 	struct tgt_info *info;
509*5113495bSYour Name 	struct wmi_unified *wmi_handle;
510*5113495bSYour Name 	QDF_STATUS ret_val;
511*5113495bSYour Name 	uint32_t fw_build_vers_ext;
512*5113495bSYour Name 
513*5113495bSYour Name 	if (!tgt_hdl) {
514*5113495bSYour Name 		target_if_err("target_psoc_info is null");
515*5113495bSYour Name 		return;
516*5113495bSYour Name 	}
517*5113495bSYour Name 
518*5113495bSYour Name 	wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl);
519*5113495bSYour Name 	info = (&tgt_hdl->info);
520*5113495bSYour Name 
521*5113495bSYour Name 	init_param.res_cfg = &info->wlan_res_cfg;
522*5113495bSYour Name 	init_param.num_mem_chunks = info->num_mem_chunks;
523*5113495bSYour Name 	init_param.mem_chunks = info->mem_chunks;
524*5113495bSYour Name 
525*5113495bSYour Name 	if (init_deinit_is_service_ext_msg(psoc, tgt_hdl) ==
526*5113495bSYour Name 			QDF_STATUS_SUCCESS) {
527*5113495bSYour Name 		init_param.hw_mode_id = info->preferred_hw_mode;
528*5113495bSYour Name 		/* Temp change, until FW submits support for handling this TLV
529*5113495bSYour Name 		 * For single mode, skip sending hw_mode
530*5113495bSYour Name 		 */
531*5113495bSYour Name 		if (info->preferred_hw_mode == WMI_HOST_HW_MODE_SINGLE)
532*5113495bSYour Name 			init_param.hw_mode_id = WMI_HOST_HW_MODE_MAX;
533*5113495bSYour Name 
534*5113495bSYour Name 		init_deinit_derive_band_to_mac_param(psoc, tgt_hdl,
535*5113495bSYour Name 						     &init_param);
536*5113495bSYour Name 	} else {
537*5113495bSYour Name 		ret_val = tgt_if_regulatory_modify_freq_range(psoc);
538*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(ret_val)) {
539*5113495bSYour Name 			target_if_err("Modify freq range is failed");
540*5113495bSYour Name 			return;
541*5113495bSYour Name 		}
542*5113495bSYour Name 	}
543*5113495bSYour Name 
544*5113495bSYour Name 	ret_val = target_if_alloc_pdevs(psoc, tgt_hdl);
545*5113495bSYour Name 	if (ret_val != QDF_STATUS_SUCCESS)
546*5113495bSYour Name 		return;
547*5113495bSYour Name 
548*5113495bSYour Name 	ret_val = target_if_update_pdev_tgt_info(psoc, tgt_hdl);
549*5113495bSYour Name 	if (ret_val != QDF_STATUS_SUCCESS)
550*5113495bSYour Name 		return;
551*5113495bSYour Name 
552*5113495bSYour Name 	info->wlan_res_cfg.max_ndp_sessions =
553*5113495bSYour Name 		QDF_MIN(info->wlan_res_cfg.max_ndp_sessions,
554*5113495bSYour Name 			info->service_ext2_param.max_ndp_sessions);
555*5113495bSYour Name 
556*5113495bSYour Name 	if (info->service_ext2_param.twt_ack_support_cap) {
557*5113495bSYour Name 		info->wlan_res_cfg.twt_ack_support_cap = true;
558*5113495bSYour Name 		target_if_twt_set_twt_ack_support(psoc, true);
559*5113495bSYour Name 	}
560*5113495bSYour Name 
561*5113495bSYour Name 	info->wlan_res_cfg.target_cap_flags =
562*5113495bSYour Name 		target_psoc_get_target_cap_flags(tgt_hdl);
563*5113495bSYour Name 
564*5113495bSYour Name 	target_if_debug("FW version 0x%x ", info->target_caps.fw_version);
565*5113495bSYour Name 	if (init_deinit_is_service_ext_msg(psoc, tgt_hdl) ==
566*5113495bSYour Name 							QDF_STATUS_SUCCESS) {
567*5113495bSYour Name 		fw_build_vers_ext = info->service_ext_param.fw_build_vers_ext;
568*5113495bSYour Name 		target_if_debug("fw_build_vers_ext:0x%x HDL version info:0x%0x, CRM sub ID:0x%x\n",
569*5113495bSYour Name 				fw_build_vers_ext, fw_build_vers_ext & 0x3FF,
570*5113495bSYour Name 				(fw_build_vers_ext >> 25) & 0x7F);
571*5113495bSYour Name 	} else {
572*5113495bSYour Name 		target_if_debug("0x%x\n", info->target_caps.fw_version_1);
573*5113495bSYour Name 	}
574*5113495bSYour Name 
575*5113495bSYour Name 	if (wmi_service_enabled(wmi_handle, wmi_service_ext2_msg))
576*5113495bSYour Name 		init_deinit_derive_afc_dev_type_param(psoc, &init_param);
577*5113495bSYour Name 
578*5113495bSYour Name 	if (wmi_service_enabled(wmi_handle, wmi_service_v1a_v1b_supported))
579*5113495bSYour Name 		info->wlan_res_cfg.dp_peer_meta_data_ver =
580*5113495bSYour Name 					CDP_RX_PEER_METADATA_V1_A_B;
581*5113495bSYour Name 	else
582*5113495bSYour Name 		info->wlan_res_cfg.dp_peer_meta_data_ver =
583*5113495bSYour Name 			target_psoc_get_target_dp_peer_meta_data_ver(tgt_hdl);
584*5113495bSYour Name 
585*5113495bSYour Name 	/* notify DP rx peer metadata version */
586*5113495bSYour Name 	init_deinit_set_dp_rx_peer_metadata_ver(
587*5113495bSYour Name 			psoc, info->wlan_res_cfg.dp_peer_meta_data_ver);
588*5113495bSYour Name 
589*5113495bSYour Name 	init_deinit_set_tdls_mlo_vdev(&init_param, wmi_handle);
590*5113495bSYour Name 
591*5113495bSYour Name 	target_if_ext_res_cfg_enable(psoc, tgt_hdl, NULL);
592*5113495bSYour Name 
593*5113495bSYour Name 	target_if_set_reo_shared_qref_feature(psoc, info);
594*5113495bSYour Name 
595*5113495bSYour Name 	target_if_set_num_max_mlo_link(psoc, info);
596*5113495bSYour Name 
597*5113495bSYour Name 	wmi_unified_init_cmd_send(wmi_handle, &init_param);
598*5113495bSYour Name 
599*5113495bSYour Name 	/* Set Max scans allowed */
600*5113495bSYour Name 	target_if_scan_set_max_active_scans(psoc,
601*5113495bSYour Name 					    WLAN_MAX_ACTIVE_SCANS_ALLOWED);
602*5113495bSYour Name 
603*5113495bSYour Name 	if (wmi_service_enabled(wmi_handle, wmi_service_hw_db2dbm_support))
604*5113495bSYour Name 		wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_HW_DB2DBM);
605*5113495bSYour Name }
606