1 /*
2  * Copyright (c) 2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: target_if_cfr_adrastea.c
22  *
23  * Target interface of CFR for Adrastea implementation
24  *
25  */
26 
27 #include <cdp_txrx_ctrl.h>
28 #include <qdf_nbuf.h>
29 #include "target_if_cfr.h"
30 #include "init_deinit_lmac.h"
31 #include <wlan_objmgr_psoc_obj.h>
32 #include "wlan_cfr_utils_api.h"
33 #include "target_if_cfr_adrastea.h"
34 #include "cfg_ucfg_api.h"
35 #include "cfr_cfg.h"
36 #include <target_if.h>
37 
38 #ifdef WLAN_CFR_ADRASTEA
cfr_adrastea_init_pdev(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)39 QDF_STATUS cfr_adrastea_init_pdev(struct wlan_objmgr_psoc *psoc,
40 				  struct wlan_objmgr_pdev *pdev)
41 {
42 	struct pdev_cfr *cfr_pdev;
43 	struct psoc_cfr *cfr_psoc;
44 	struct wmi_unified *wmi_handle = NULL;
45 	struct target_psoc_info *tgt_hdl;
46 	struct tgt_info *info;
47 	bool cfr_capable;
48 	int num_mem_chunks, idx;
49 	u32 *read_index;
50 
51 	if (!psoc || !pdev) {
52 		cfr_err("null pdev or psoc");
53 		return QDF_STATUS_E_FAILURE;
54 	}
55 
56 	cfr_pdev = wlan_objmgr_pdev_get_comp_private_obj(
57 					pdev, WLAN_UMAC_COMP_CFR);
58 	if (!cfr_pdev) {
59 		cfr_err("null pdev cfr");
60 		return QDF_STATUS_E_FAILURE;
61 	}
62 
63 	cfr_psoc = wlan_objmgr_psoc_get_comp_private_obj(
64 					psoc, WLAN_UMAC_COMP_CFR);
65 
66 	if (!cfr_psoc) {
67 		cfr_err("null psoc cfr");
68 		return QDF_STATUS_E_FAILURE;
69 	}
70 
71 	if (wlan_cfr_is_feature_disabled(pdev)) {
72 		cfr_pdev->is_cfr_capable = 0;
73 		cfr_psoc->is_cfr_capable = 0;
74 		cfr_info("cfr disabled");
75 		return QDF_STATUS_SUCCESS;
76 	}
77 
78 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
79 	if (!wmi_handle) {
80 		cfr_err("null wmi handle");
81 		return QDF_STATUS_E_FAILURE;
82 	}
83 
84 	cfr_capable = wmi_service_enabled(wmi_handle,
85 					  wmi_service_cfr_capture_support);
86 	cfr_pdev->is_cfr_capable = cfr_capable;
87 	cfr_psoc->is_cfr_capable = cfr_capable;
88 	cfr_pdev->chip_type = CFR_CAPTURE_RADIO_ADRASTEA;
89 	cfr_pdev->cfr_max_sta_count = MAX_CFR_ENABLED_CLIENTS;
90 	cfr_pdev->subbuf_size = STREAMFS_MAX_SUBBUF_ADRASTEA;
91 	cfr_pdev->num_subbufs = STREAMFS_NUM_BUF_SUBBUF_ADRASTEA;
92 	cfr_pdev->pdev_obj = pdev;
93 	cfr_psoc->psoc_obj = psoc;
94 
95 	if (!cfr_capable) {
96 		cfr_err("FW doesn't support CFR");
97 		return QDF_STATUS_SUCCESS;
98 	}
99 
100 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
101 
102 	info = &(tgt_hdl->info);
103 	num_mem_chunks = info->num_mem_chunks;
104 
105 	/*
106 	 * Copy the host mem chunk info allocated during init
107 	 * for CFR capture in cfr pdev
108 	 */
109 	for (idx = 0; idx < num_mem_chunks; idx++) {
110 		if (info->mem_chunks[idx].req_id ==
111 					CFR_CAPTURE_HOST_MEM_REQ_ID) {
112 			cfr_pdev->cfr_mem_chunk.vaddr =
113 						info->mem_chunks[idx].vaddr;
114 			cfr_pdev->cfr_mem_chunk.paddr =
115 						info->mem_chunks[idx].paddr;
116 			cfr_pdev->cfr_mem_chunk.req_id =
117 						info->mem_chunks[idx].req_id;
118 			cfr_pdev->cfr_mem_chunk.len = info->mem_chunks[idx].len;
119 
120 			/* Initialize the read index with default value */
121 			read_index = (u32 *)info->mem_chunks[idx].vaddr;
122 			(*read_index) = CFR_HOST_MEM_READ_INDEX_DEFAULT;
123 			break;
124 		}
125 	}
126 
127 	if (idx == num_mem_chunks) {
128 		cfr_err("Host mem chunks for CFR req id not allocated\n");
129 		cfr_pdev->is_cfr_capable = 0;
130 		cfr_psoc->is_cfr_capable = 0;
131 		return QDF_STATUS_SUCCESS;
132 	}
133 
134 	return QDF_STATUS_SUCCESS;
135 }
136 
cfr_adrastea_deinit_pdev(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)137 QDF_STATUS cfr_adrastea_deinit_pdev(struct wlan_objmgr_psoc *psoc,
138 				    struct wlan_objmgr_pdev *pdev)
139 {
140 	struct pdev_cfr *pcfr;
141 
142 	if (!psoc || !pdev) {
143 		cfr_err("null pdev or psoc");
144 		return QDF_STATUS_E_FAILURE;
145 	}
146 
147 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
148 					pdev, WLAN_UMAC_COMP_CFR);
149 	if (!pcfr) {
150 		cfr_err("null pdev cfr");
151 		return QDF_STATUS_E_FAILURE;
152 	}
153 
154 	if (!pcfr->is_cfr_capable) {
155 		cfr_info("cfr disabled or FW not support");
156 		return QDF_STATUS_SUCCESS;
157 	}
158 
159 	qdf_mem_zero(&pcfr->cfr_mem_chunk,
160 		     sizeof(struct cfr_wmi_host_mem_chunk));
161 
162 	return QDF_STATUS_SUCCESS;
163 }
164 #endif
165