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 ®_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