xref: /wlan-dirver/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6490.c (revision 45a38684b07295822dc8eba39e293408f203eec8)
1 /*
2  * Copyright (c) 2020 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 /**
20  * DOC : target_if_cfr_6490.c
21  *
22  * Target interface of CFR for QCA6490 implementation
23  *
24  */
25 
26 #include <cdp_txrx_ctrl.h>
27 #include "target_if_cfr.h"
28 #include <qdf_nbuf.h>
29 #include "wlan_cfr_utils_api.h"
30 #include "target_if_cfr_6490.h"
31 #include "target_if_cfr_enh.h"
32 #include "init_deinit_lmac.h"
33 #include "cfg_ucfg_api.h"
34 #include "cfr_cfg.h"
35 
36 #ifdef WLAN_ENH_CFR_ENABLE
37 #ifdef CFR_USE_FIXED_FOLDER
38 static wdi_event_subscribe g_cfr_subscribe;
39 
40 static void target_cfr_callback(void *pdev_obj, enum WDI_EVENT event,
41 				void *data, u_int16_t peer_id,
42 				uint32_t status)
43 {
44 	struct wlan_objmgr_pdev *pdev;
45 	qdf_nbuf_t nbuf = (qdf_nbuf_t)data;
46 	qdf_nbuf_t data_clone;
47 
48 	pdev = (struct wlan_objmgr_pdev *)pdev_obj;
49 	if (qdf_unlikely((!pdev || !data))) {
50 		cfr_err("Invalid pdev %pK or data %pK for event %d",
51 			pdev, data, event);
52 		qdf_nbuf_free(nbuf);
53 		return;
54 	}
55 
56 	if (event != WDI_EVENT_RX_PPDU_DESC) {
57 		cfr_debug("event is %d", event);
58 		qdf_nbuf_free(nbuf);
59 		return;
60 	}
61 
62 	data_clone = qdf_nbuf_clone(nbuf);
63 	if (data_clone)
64 		wlan_cfr_rx_tlv_process(pdev, (void *)data_clone);
65 
66 	qdf_nbuf_free(nbuf);
67 }
68 
69 QDF_STATUS
70 target_if_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev,
71 				  bool is_subscribe)
72 {
73 	ol_txrx_soc_handle soc;
74 	struct wlan_objmgr_psoc *psoc;
75 	struct pdev_cfr *pcfr;
76 
77 	if (!pdev) {
78 		cfr_err("Null pdev");
79 		return QDF_STATUS_E_INVAL;
80 	}
81 
82 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
83 				pdev, WLAN_UMAC_COMP_CFR);
84 	if (!pcfr) {
85 		cfr_err("pcfr is NULL");
86 		return QDF_STATUS_E_INVAL;
87 	}
88 
89 	psoc = wlan_pdev_get_psoc(pdev);
90 	if (!psoc) {
91 		cfr_err("Null psoc");
92 		return QDF_STATUS_E_INVAL;
93 	}
94 
95 	soc = wlan_psoc_get_dp_handle(psoc);
96 	if (!soc) {
97 		cfr_err("Null soc");
98 		return QDF_STATUS_E_INVAL;
99 	}
100 
101 	g_cfr_subscribe.callback = target_cfr_callback;
102 	g_cfr_subscribe.context = pdev;
103 	cdp_set_cfr_rcc(soc, 0, is_subscribe);
104 	cdp_enable_mon_reap_timer(soc, 0, is_subscribe);
105 	if (is_subscribe) {
106 		if (cdp_wdi_event_sub(soc, 0, &g_cfr_subscribe,
107 				      WDI_EVENT_RX_PPDU_DESC)) {
108 			cfr_err("wdi event sub fail");
109 			return QDF_STATUS_E_FAILURE;
110 		}
111 	} else {
112 		if (cdp_wdi_event_unsub(soc, 0, &g_cfr_subscribe,
113 					WDI_EVENT_RX_PPDU_DESC)) {
114 			cfr_err("wdi event unsub fail");
115 			return QDF_STATUS_E_FAILURE;
116 		}
117 	}
118 
119 	return QDF_STATUS_SUCCESS;
120 }
121 #endif
122 #endif
123 
124 QDF_STATUS cfr_6490_init_pdev(struct wlan_objmgr_psoc *psoc,
125 			      struct wlan_objmgr_pdev *pdev)
126 {
127 	struct pdev_cfr *cfr_pdev;
128 	struct psoc_cfr *cfr_psoc;
129 	struct wmi_unified *wmi_handle = NULL;
130 	bool cfr_capable;
131 	QDF_STATUS status;
132 
133 	if (!psoc || !pdev) {
134 		cfr_err("null pdev or psoc");
135 		return QDF_STATUS_E_FAILURE;
136 	}
137 
138 	cfr_pdev = wlan_objmgr_pdev_get_comp_private_obj(
139 					pdev, WLAN_UMAC_COMP_CFR);
140 	if (!cfr_pdev) {
141 		cfr_err("null pdev cfr");
142 		return QDF_STATUS_E_FAILURE;
143 	}
144 
145 	cfr_psoc = wlan_objmgr_psoc_get_comp_private_obj(
146 					psoc, WLAN_UMAC_COMP_CFR);
147 
148 	if (!cfr_psoc) {
149 		cfr_err("null psoc cfr");
150 		return QDF_STATUS_E_FAILURE;
151 	}
152 
153 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
154 	if (!wmi_handle) {
155 		cfr_err("null wmi handle");
156 		return QDF_STATUS_E_FAILURE;
157 	}
158 
159 	if (wlan_cfr_is_feature_disabled(pdev)) {
160 		cfr_pdev->is_cfr_capable = 0;
161 		cfr_psoc->is_cfr_capable = 0;
162 		cfr_info("cfr disabled");
163 		return QDF_STATUS_SUCCESS;
164 	}
165 
166 	cfr_capable = wmi_service_enabled(wmi_handle,
167 					  wmi_service_cfr_capture_support);
168 	cfr_pdev->is_cfr_capable = cfr_capable;
169 	cfr_psoc->is_cfr_capable = cfr_capable;
170 	if (!cfr_capable) {
171 		cfr_err("FW doesn't support CFR");
172 		return QDF_STATUS_SUCCESS;
173 	}
174 
175 	status = cfr_enh_init_pdev(psoc, pdev);
176 	cfr_pdev->chip_type = CFR_CAPTURE_RADIO_HSP;
177 
178 	return status;
179 }
180 
181 QDF_STATUS cfr_6490_deinit_pdev(struct wlan_objmgr_psoc *psoc,
182 				struct wlan_objmgr_pdev *pdev)
183 {
184 	struct pdev_cfr *pcfr;
185 
186 	if (!psoc || !pdev) {
187 		cfr_err("null pdev or psoc");
188 		return QDF_STATUS_E_FAILURE;
189 	}
190 
191 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
192 					pdev, WLAN_UMAC_COMP_CFR);
193 	if (!pcfr) {
194 		cfr_err("null pdev cfr");
195 		return QDF_STATUS_E_FAILURE;
196 	}
197 
198 	if (!pcfr->is_cfr_capable) {
199 		cfr_info("cfr disabled or FW not support");
200 		return QDF_STATUS_SUCCESS;
201 	}
202 
203 	return cfr_enh_deinit_pdev(psoc, pdev);
204 }
205