xref: /wlan-driver/qca-wifi-host-cmn/target_if/ftm/src/target_if_ftm.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  *
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: offload lmac interface APIs definitions for FTM
22*5113495bSYour Name  */
23*5113495bSYour Name 
24*5113495bSYour Name #include <qdf_status.h>
25*5113495bSYour Name #include <target_if_ftm.h>
26*5113495bSYour Name #include <wmi_unified_priv.h>
27*5113495bSYour Name #include <wlan_objmgr_psoc_obj.h>
28*5113495bSYour Name #include <target_if.h>
29*5113495bSYour Name #include <wlan_lmac_if_def.h>
30*5113495bSYour Name #include <wlan_ftm_ucfg_api.h>
31*5113495bSYour Name 
32*5113495bSYour Name static inline struct wlan_lmac_if_ftm_rx_ops *
target_if_ftm_get_rx_ops(struct wlan_objmgr_psoc * psoc)33*5113495bSYour Name target_if_ftm_get_rx_ops(struct wlan_objmgr_psoc *psoc)
34*5113495bSYour Name {
35*5113495bSYour Name 	struct wlan_lmac_if_rx_ops *rx_ops;
36*5113495bSYour Name 
37*5113495bSYour Name 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
38*5113495bSYour Name 	if (!rx_ops) {
39*5113495bSYour Name 		ftm_err("rx_ops is NULL");
40*5113495bSYour Name 		return NULL;
41*5113495bSYour Name 	}
42*5113495bSYour Name 
43*5113495bSYour Name 	return &rx_ops->ftm_rx_ops;
44*5113495bSYour Name }
45*5113495bSYour Name 
46*5113495bSYour Name static int
target_if_ftm_process_utf_event(ol_scn_t sc,uint8_t * event_buf,uint32_t len)47*5113495bSYour Name target_if_ftm_process_utf_event(ol_scn_t sc, uint8_t *event_buf, uint32_t len)
48*5113495bSYour Name {
49*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
50*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
51*5113495bSYour Name 	struct wmi_host_pdev_utf_event event;
52*5113495bSYour Name 	struct wlan_lmac_if_ftm_rx_ops *ftm_rx_ops;
53*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
54*5113495bSYour Name 	uint32_t pdev_id;
55*5113495bSYour Name 	struct wmi_unified *wmi_handle;
56*5113495bSYour Name 
57*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(sc);
58*5113495bSYour Name 	if (!psoc) {
59*5113495bSYour Name 		ftm_err("null psoc");
60*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
61*5113495bSYour Name 	}
62*5113495bSYour Name 
63*5113495bSYour Name 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_FTM_ID);
64*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
65*5113495bSYour Name 		ftm_err("unable to get psoc reference");
66*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
67*5113495bSYour Name 	}
68*5113495bSYour Name 
69*5113495bSYour Name 	event.datalen = len;
70*5113495bSYour Name 
71*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
72*5113495bSYour Name 	if (!wmi_handle) {
73*5113495bSYour Name 		ftm_err("Invalid WMI handle");
74*5113495bSYour Name 		wlan_objmgr_psoc_release_ref(psoc, WLAN_FTM_ID);
75*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
76*5113495bSYour Name 	}
77*5113495bSYour Name 
78*5113495bSYour Name 	if (wmi_extract_pdev_utf_event(wmi_handle, event_buf, &event)
79*5113495bSYour Name 	    != QDF_STATUS_SUCCESS) {
80*5113495bSYour Name 		ftm_err("Extracting utf event failed");
81*5113495bSYour Name 		wlan_objmgr_psoc_release_ref(psoc, WLAN_FTM_ID);
82*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
83*5113495bSYour Name 	}
84*5113495bSYour Name 
85*5113495bSYour Name 	pdev_id = event.pdev_id;
86*5113495bSYour Name 	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_FTM_ID);
87*5113495bSYour Name 	if (!pdev) {
88*5113495bSYour Name 		pdev_id = TGT_WMI_PDEV_ID_SOC;
89*5113495bSYour Name 		ftm_debug("Can't find pdev by pdev_id %d, try soc_id",
90*5113495bSYour Name 			  event.pdev_id);
91*5113495bSYour Name 		pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_FTM_ID);
92*5113495bSYour Name 		if (!pdev) {
93*5113495bSYour Name 			ftm_err("null pdev");
94*5113495bSYour Name 			wlan_objmgr_psoc_release_ref(psoc, WLAN_FTM_ID);
95*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
96*5113495bSYour Name 		}
97*5113495bSYour Name 	}
98*5113495bSYour Name 
99*5113495bSYour Name 	ftm_rx_ops = target_if_ftm_get_rx_ops(psoc);
100*5113495bSYour Name 	if (!ftm_rx_ops) {
101*5113495bSYour Name 		ftm_err("ftm_rx_ops is NULL");
102*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
103*5113495bSYour Name 	}
104*5113495bSYour Name 	if (ftm_rx_ops->ftm_ev_handler) {
105*5113495bSYour Name 		status = ftm_rx_ops->ftm_ev_handler(pdev,
106*5113495bSYour Name 				event.data, event.datalen);
107*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status))
108*5113495bSYour Name 			status = QDF_STATUS_E_INVAL;
109*5113495bSYour Name 	} else {
110*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
111*5113495bSYour Name 	}
112*5113495bSYour Name 
113*5113495bSYour Name 	wlan_objmgr_pdev_release_ref(pdev, WLAN_FTM_ID);
114*5113495bSYour Name 	wlan_objmgr_psoc_release_ref(psoc, WLAN_FTM_ID);
115*5113495bSYour Name 
116*5113495bSYour Name 	return status;
117*5113495bSYour Name }
118*5113495bSYour Name 
target_if_ftm_cmd_send(struct wlan_objmgr_pdev * pdev,uint8_t * buf,uint32_t len,uint8_t pdev_id)119*5113495bSYour Name QDF_STATUS target_if_ftm_cmd_send(struct wlan_objmgr_pdev *pdev,
120*5113495bSYour Name 				  uint8_t *buf, uint32_t len,
121*5113495bSYour Name 				  uint8_t pdev_id)
122*5113495bSYour Name {
123*5113495bSYour Name 	QDF_STATUS ret;
124*5113495bSYour Name 	wmi_unified_t handle;
125*5113495bSYour Name 	struct pdev_utf_params param;
126*5113495bSYour Name 
127*5113495bSYour Name 	if (!pdev) {
128*5113495bSYour Name 		target_if_err("null pdev");
129*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
130*5113495bSYour Name 	}
131*5113495bSYour Name 
132*5113495bSYour Name 	handle = get_wmi_unified_hdl_from_pdev(pdev);
133*5113495bSYour Name 	if (!handle) {
134*5113495bSYour Name 		target_if_err("null handle");
135*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
136*5113495bSYour Name 	}
137*5113495bSYour Name 	param.utf_payload = buf;
138*5113495bSYour Name 	param.len = len;
139*5113495bSYour Name 
140*5113495bSYour Name 	ret = wmi_unified_pdev_utf_cmd_send(handle, &param, pdev_id);
141*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
142*5113495bSYour Name 		ftm_err("wmi utf cmd send failed, ret: %d", ret);
143*5113495bSYour Name 
144*5113495bSYour Name 	return ret;
145*5113495bSYour Name }
146*5113495bSYour Name 
target_if_ftm_attach(struct wlan_objmgr_psoc * psoc)147*5113495bSYour Name QDF_STATUS target_if_ftm_attach(struct wlan_objmgr_psoc *psoc)
148*5113495bSYour Name {
149*5113495bSYour Name 	QDF_STATUS ret;
150*5113495bSYour Name 	wmi_unified_t handle;
151*5113495bSYour Name 
152*5113495bSYour Name 	if (!psoc) {
153*5113495bSYour Name 		target_if_err("null psoc");
154*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
155*5113495bSYour Name 	}
156*5113495bSYour Name 
157*5113495bSYour Name 	handle = get_wmi_unified_hdl_from_psoc(psoc);
158*5113495bSYour Name 	if (!handle) {
159*5113495bSYour Name 		target_if_err("null handle");
160*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
161*5113495bSYour Name 	}
162*5113495bSYour Name 	ret = wmi_unified_register_event_handler(handle,
163*5113495bSYour Name 			wmi_pdev_utf_event_id,
164*5113495bSYour Name 			target_if_ftm_process_utf_event,
165*5113495bSYour Name 			WMI_RX_UMAC_CTX);
166*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
167*5113495bSYour Name 		ftm_err("wmi event registration failed, ret: %d", ret);
168*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
169*5113495bSYour Name 	}
170*5113495bSYour Name 
171*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
172*5113495bSYour Name }
173*5113495bSYour Name 
target_if_ftm_detach(struct wlan_objmgr_psoc * psoc)174*5113495bSYour Name QDF_STATUS target_if_ftm_detach(struct wlan_objmgr_psoc *psoc)
175*5113495bSYour Name 
176*5113495bSYour Name {
177*5113495bSYour Name 	int ret;
178*5113495bSYour Name 	wmi_unified_t handle;
179*5113495bSYour Name 
180*5113495bSYour Name 	if (!psoc) {
181*5113495bSYour Name 		target_if_err("null psoc");
182*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
183*5113495bSYour Name 	}
184*5113495bSYour Name 
185*5113495bSYour Name 	handle = get_wmi_unified_hdl_from_psoc(psoc);
186*5113495bSYour Name 	if (!handle) {
187*5113495bSYour Name 		target_if_err("null handle");
188*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
189*5113495bSYour Name 	}
190*5113495bSYour Name 	ret = wmi_unified_unregister_event_handler(handle,
191*5113495bSYour Name 						   wmi_pdev_utf_event_id);
192*5113495bSYour Name 
193*5113495bSYour Name 	if (ret) {
194*5113495bSYour Name 		ftm_err("wmi event deregistration failed, ret: %d", ret);
195*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
196*5113495bSYour Name 	}
197*5113495bSYour Name 
198*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
199*5113495bSYour Name }
200*5113495bSYour Name 
target_if_ftm_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)201*5113495bSYour Name QDF_STATUS target_if_ftm_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
202*5113495bSYour Name {
203*5113495bSYour Name 	struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
204*5113495bSYour Name 
205*5113495bSYour Name 	if (!tx_ops) {
206*5113495bSYour Name 		ftm_err("invalid tx_ops");
207*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
208*5113495bSYour Name 	}
209*5113495bSYour Name 
210*5113495bSYour Name 	ftm_tx_ops = &tx_ops->ftm_tx_ops;
211*5113495bSYour Name 	ftm_tx_ops->ftm_attach = target_if_ftm_attach;
212*5113495bSYour Name 	ftm_tx_ops->ftm_detach = target_if_ftm_detach;
213*5113495bSYour Name 	ftm_tx_ops->ftm_cmd_send = target_if_ftm_cmd_send;
214*5113495bSYour Name 
215*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
216*5113495bSYour Name }
217