xref: /wlan-driver/qca-wifi-host-cmn/global_lmac_if/src/wlan_global_lmac_if.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-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 #include "qdf_mem.h"
21*5113495bSYour Name #include "qdf_module.h"
22*5113495bSYour Name #include "wlan_lmac_if_def.h"
23*5113495bSYour Name #include "wlan_lmac_if_api.h"
24*5113495bSYour Name #include "wlan_global_lmac_if_api.h"
25*5113495bSYour Name #ifdef WLAN_CONV_SPECTRAL_ENABLE
26*5113495bSYour Name #include <wlan_spectral_utils_api.h>
27*5113495bSYour Name #endif
28*5113495bSYour Name #include <target_if_psoc_wake_lock.h>
29*5113495bSYour Name 
30*5113495bSYour Name /* Function pointer to call DA/OL specific tx_ops registration function */
31*5113495bSYour Name QDF_STATUS (*wlan_global_lmac_if_tx_ops_register[MAX_DEV_TYPE])
32*5113495bSYour Name 				(struct wlan_lmac_if_tx_ops *tx_ops);
33*5113495bSYour Name 
34*5113495bSYour Name /*
35*5113495bSYour Name  * spectral scan is built as separate .ko for WIN where
36*5113495bSYour Name  * MCL it is part of wlan.ko so the registration of
37*5113495bSYour Name .* rx ops to global lmac if layer is different between WIN
38*5113495bSYour Name  * and MCL
39*5113495bSYour Name  */
40*5113495bSYour Name #ifdef WLAN_CONV_SPECTRAL_ENABLE
41*5113495bSYour Name #ifdef SPECTRAL_MODULIZED_ENABLE
42*5113495bSYour Name /* Function pointer for spectral rx_ops registration function */
43*5113495bSYour Name void (*wlan_lmac_if_sptrl_rx_ops)(struct wlan_lmac_if_rx_ops *rx_ops);
44*5113495bSYour Name 
wlan_lmac_if_sptrl_set_rx_ops_register_cb(void (* handler)(struct wlan_lmac_if_rx_ops *))45*5113495bSYour Name QDF_STATUS wlan_lmac_if_sptrl_set_rx_ops_register_cb(void (*handler)
46*5113495bSYour Name 				(struct wlan_lmac_if_rx_ops *))
47*5113495bSYour Name {
48*5113495bSYour Name 	wlan_lmac_if_sptrl_rx_ops = handler;
49*5113495bSYour Name 
50*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
51*5113495bSYour Name }
52*5113495bSYour Name 
53*5113495bSYour Name qdf_export_symbol(wlan_lmac_if_sptrl_set_rx_ops_register_cb);
54*5113495bSYour Name 
55*5113495bSYour Name /**
56*5113495bSYour Name  * wlan_spectral_register_rx_ops() - Register spectral component RX OPS
57*5113495bSYour Name  * @rx_ops: lmac if receive ops
58*5113495bSYour Name  *
59*5113495bSYour Name  * Return: None
60*5113495bSYour Name  */
wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)61*5113495bSYour Name static void wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
62*5113495bSYour Name {
63*5113495bSYour Name 	wlan_lmac_if_sptrl_rx_ops(rx_ops);
64*5113495bSYour Name }
65*5113495bSYour Name #else
wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)66*5113495bSYour Name static void wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
67*5113495bSYour Name {
68*5113495bSYour Name 	wlan_lmac_if_sptrl_register_rx_ops(rx_ops);
69*5113495bSYour Name }
70*5113495bSYour Name #endif /* SPECTRAL_MODULIZED_ENABLE */
71*5113495bSYour Name #else
72*5113495bSYour Name /**
73*5113495bSYour Name  * wlan_spectral_register_rx_ops() - Dummy api to register spectral RX OPS
74*5113495bSYour Name  * @rx_ops: lmac if receive ops
75*5113495bSYour Name  *
76*5113495bSYour Name  * Return: None
77*5113495bSYour Name  */
wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)78*5113495bSYour Name static void wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
79*5113495bSYour Name {
80*5113495bSYour Name }
81*5113495bSYour Name #endif /*WLAN_CONV_SPECTRAL_ENABLE*/
82*5113495bSYour Name 
83*5113495bSYour Name #ifdef WLAN_IOT_SIM_SUPPORT
84*5113495bSYour Name /* Function pointer for iot_sim rx_ops registration function */
85*5113495bSYour Name void (*wlan_lmac_if_iot_sim_rx_ops)(struct wlan_lmac_if_rx_ops *rx_ops);
86*5113495bSYour Name 
wlan_lmac_if_iot_sim_set_rx_ops_register_cb(void (* handler)(struct wlan_lmac_if_rx_ops *))87*5113495bSYour Name QDF_STATUS wlan_lmac_if_iot_sim_set_rx_ops_register_cb(void (*handler)
88*5113495bSYour Name 				(struct wlan_lmac_if_rx_ops *))
89*5113495bSYour Name {
90*5113495bSYour Name 	wlan_lmac_if_iot_sim_rx_ops = handler;
91*5113495bSYour Name 
92*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
93*5113495bSYour Name }
94*5113495bSYour Name 
95*5113495bSYour Name qdf_export_symbol(wlan_lmac_if_iot_sim_set_rx_ops_register_cb);
96*5113495bSYour Name 
wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)97*5113495bSYour Name static void wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
98*5113495bSYour Name {
99*5113495bSYour Name 	if (wlan_lmac_if_iot_sim_rx_ops)
100*5113495bSYour Name 		wlan_lmac_if_iot_sim_rx_ops(rx_ops);
101*5113495bSYour Name 	else
102*5113495bSYour Name 		qdf_print("\n***** IOT SIM MODULE NOT LOADED *****\n");
103*5113495bSYour Name }
104*5113495bSYour Name 
105*5113495bSYour Name #else
wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)106*5113495bSYour Name static void wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
107*5113495bSYour Name {
108*5113495bSYour Name }
109*5113495bSYour Name #endif
110*5113495bSYour Name 
111*5113495bSYour Name #if defined(QCA_SUPPORT_SON) || defined(WLAN_FEATURE_SON)
112*5113495bSYour Name /* Function pointer for son rx_ops registration function */
113*5113495bSYour Name void (*wlan_lmac_if_son_rx_ops)(struct wlan_lmac_if_rx_ops *rx_ops);
114*5113495bSYour Name 
wlan_lmac_if_son_set_rx_ops_register_cb(void (* handler)(struct wlan_lmac_if_rx_ops *))115*5113495bSYour Name QDF_STATUS wlan_lmac_if_son_set_rx_ops_register_cb(void (*handler)
116*5113495bSYour Name 				(struct wlan_lmac_if_rx_ops *))
117*5113495bSYour Name {
118*5113495bSYour Name 	wlan_lmac_if_son_rx_ops = handler;
119*5113495bSYour Name 
120*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
121*5113495bSYour Name }
122*5113495bSYour Name 
123*5113495bSYour Name qdf_export_symbol(wlan_lmac_if_son_set_rx_ops_register_cb);
124*5113495bSYour Name 
wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)125*5113495bSYour Name static void wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
126*5113495bSYour Name {
127*5113495bSYour Name 	if (wlan_lmac_if_son_rx_ops)
128*5113495bSYour Name 		wlan_lmac_if_son_rx_ops(rx_ops);
129*5113495bSYour Name 	else
130*5113495bSYour Name 		qdf_info("\n***** SON MODULE NOT LOADED *****\n");
131*5113495bSYour Name }
132*5113495bSYour Name 
wlan_lmac_if_son_mod_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)133*5113495bSYour Name void wlan_lmac_if_son_mod_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
134*5113495bSYour Name {
135*5113495bSYour Name 	wlan_son_register_rx_ops(rx_ops);
136*5113495bSYour Name }
137*5113495bSYour Name #else
wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)138*5113495bSYour Name static void wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
139*5113495bSYour Name {
140*5113495bSYour Name }
141*5113495bSYour Name #endif
142*5113495bSYour Name 
143*5113495bSYour Name /**
144*5113495bSYour Name  * wlan_global_lmac_if_rx_ops_register() - Global lmac_if
145*5113495bSYour Name  * rx handler register
146*5113495bSYour Name  * @rx_ops: Pointer to rx_ops structure to be populated
147*5113495bSYour Name  *
148*5113495bSYour Name  * Register lmac_if RX callabacks which will be called by DA/OL/WMA/WMI
149*5113495bSYour Name  *
150*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS - in case of success
151*5113495bSYour Name  */
152*5113495bSYour Name QDF_STATUS
wlan_global_lmac_if_rx_ops_register(struct wlan_lmac_if_rx_ops * rx_ops)153*5113495bSYour Name wlan_global_lmac_if_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
154*5113495bSYour Name {
155*5113495bSYour Name 	/*
156*5113495bSYour Name 	 * Component specific public api's to be called to register
157*5113495bSYour Name 	 * respective callbacks
158*5113495bSYour Name 	 * Ex: rx_ops->fp = function;
159*5113495bSYour Name 	 */
160*5113495bSYour Name 	if (!rx_ops) {
161*5113495bSYour Name 		qdf_err("lmac if rx ops pointer is NULL");
162*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
163*5113495bSYour Name 	}
164*5113495bSYour Name 	/* Registration for UMAC components */
165*5113495bSYour Name 	wlan_lmac_if_umac_rx_ops_register(rx_ops);
166*5113495bSYour Name 
167*5113495bSYour Name 	/* spectral rx_ops registration*/
168*5113495bSYour Name 	wlan_spectral_register_rx_ops(rx_ops);
169*5113495bSYour Name 
170*5113495bSYour Name 	/* iot_sim rx_ops registration*/
171*5113495bSYour Name 	wlan_iot_sim_register_rx_ops(rx_ops);
172*5113495bSYour Name 
173*5113495bSYour Name 	/* son rx_ops registration*/
174*5113495bSYour Name 	wlan_son_register_rx_ops(rx_ops);
175*5113495bSYour Name 
176*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
177*5113495bSYour Name }
178*5113495bSYour Name 
179*5113495bSYour Name /**
180*5113495bSYour Name  * wlan_global_lmac_if_open() - global lmac_if open
181*5113495bSYour Name  * @psoc: psoc context
182*5113495bSYour Name  *
183*5113495bSYour Name  * Opens up lmac_if southbound layer. This function calls OL,DA and UMAC
184*5113495bSYour Name  * modules to register respective tx and rx callbacks.
185*5113495bSYour Name  *
186*5113495bSYour Name  * Return: QDF_STATUS
187*5113495bSYour Name  */
wlan_global_lmac_if_open(struct wlan_objmgr_psoc * psoc)188*5113495bSYour Name QDF_STATUS wlan_global_lmac_if_open(struct wlan_objmgr_psoc *psoc)
189*5113495bSYour Name {
190*5113495bSYour Name 	WLAN_DEV_TYPE dev_type;
191*5113495bSYour Name 
192*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
193*5113495bSYour Name 	struct wlan_lmac_if_rx_ops *rx_ops;
194*5113495bSYour Name 
195*5113495bSYour Name 	if (!psoc) {
196*5113495bSYour Name 		qdf_err("psoc is NULL");
197*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
198*5113495bSYour Name 	}
199*5113495bSYour Name 
200*5113495bSYour Name 	tx_ops = qdf_mem_malloc(sizeof(*tx_ops));
201*5113495bSYour Name 	if (!tx_ops) {
202*5113495bSYour Name 		qdf_err("tx_ops is NULL");
203*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
204*5113495bSYour Name 	}
205*5113495bSYour Name 
206*5113495bSYour Name 	rx_ops = qdf_mem_malloc(sizeof(*rx_ops));
207*5113495bSYour Name 	if (!rx_ops) {
208*5113495bSYour Name 		qdf_err("rx_ops is NULL");
209*5113495bSYour Name 		qdf_mem_free(tx_ops);
210*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
211*5113495bSYour Name 	}
212*5113495bSYour Name 
213*5113495bSYour Name 	wlan_psoc_set_lmac_if_txops(psoc, tx_ops);
214*5113495bSYour Name 	wlan_psoc_set_lmac_if_rxops(psoc, rx_ops);
215*5113495bSYour Name 
216*5113495bSYour Name 	dev_type = psoc->soc_nif.phy_type;
217*5113495bSYour Name 
218*5113495bSYour Name 	if (dev_type == WLAN_DEV_OL) {
219*5113495bSYour Name 		wlan_global_lmac_if_tx_ops_register[dev_type]
220*5113495bSYour Name 					(tx_ops);
221*5113495bSYour Name 	} else {
222*5113495bSYour Name 		/* Control should ideally not reach here */
223*5113495bSYour Name 		qdf_print("Invalid device type");
224*5113495bSYour Name 		qdf_mem_free(tx_ops);
225*5113495bSYour Name 		qdf_mem_free(rx_ops);
226*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
227*5113495bSYour Name 	}
228*5113495bSYour Name 
229*5113495bSYour Name 	/* Function call to register rx-ops handlers */
230*5113495bSYour Name 	wlan_global_lmac_if_rx_ops_register(rx_ops);
231*5113495bSYour Name 
232*5113495bSYour Name 	target_if_wake_lock_init(psoc);
233*5113495bSYour Name 
234*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
235*5113495bSYour Name }
236*5113495bSYour Name qdf_export_symbol(wlan_global_lmac_if_open);
237*5113495bSYour Name 
238*5113495bSYour Name /**
239*5113495bSYour Name  * wlan_global_lmac_if_close() - Close global lmac_if
240*5113495bSYour Name  * @psoc: psoc context
241*5113495bSYour Name  *
242*5113495bSYour Name  * Deregister lmac_if TX and RX handlers
243*5113495bSYour Name  *
244*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS - in case of success
245*5113495bSYour Name  */
wlan_global_lmac_if_close(struct wlan_objmgr_psoc * psoc)246*5113495bSYour Name QDF_STATUS wlan_global_lmac_if_close(struct wlan_objmgr_psoc *psoc)
247*5113495bSYour Name {
248*5113495bSYour Name 	struct wlan_lmac_if_tx_ops *tx_ops;
249*5113495bSYour Name 	struct wlan_lmac_if_rx_ops *rx_ops;
250*5113495bSYour Name 
251*5113495bSYour Name 	if (!psoc) {
252*5113495bSYour Name 		qdf_err("psoc is NULL");
253*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
254*5113495bSYour Name 	}
255*5113495bSYour Name 
256*5113495bSYour Name 	target_if_wake_lock_deinit(psoc);
257*5113495bSYour Name 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
258*5113495bSYour Name 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
259*5113495bSYour Name 
260*5113495bSYour Name 	wlan_psoc_set_lmac_if_txops(psoc, NULL);
261*5113495bSYour Name 	wlan_psoc_set_lmac_if_rxops(psoc, NULL);
262*5113495bSYour Name 
263*5113495bSYour Name 	qdf_mem_free(tx_ops);
264*5113495bSYour Name 	qdf_mem_free(rx_ops);
265*5113495bSYour Name 
266*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
267*5113495bSYour Name }
268*5113495bSYour Name qdf_export_symbol(wlan_global_lmac_if_close);
269*5113495bSYour Name 
270*5113495bSYour Name /**
271*5113495bSYour Name  * wlan_global_lmac_if_set_txops_registration_cb() - tx
272*5113495bSYour Name  * registration callback assignment
273*5113495bSYour Name  * @dev_type: Dev type can be either Direct attach or Offload
274*5113495bSYour Name  * @handler: handler to be called for LMAC tx ops registration
275*5113495bSYour Name  *
276*5113495bSYour Name  * API to assign appropriate tx registration callback handler based on the
277*5113495bSYour Name  * device type(Offload or Direct attach)
278*5113495bSYour Name  *
279*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS - in case of success
280*5113495bSYour Name  */
wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_TYPE dev_type,QDF_STATUS (* handler)(struct wlan_lmac_if_tx_ops *))281*5113495bSYour Name QDF_STATUS wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_TYPE dev_type,
282*5113495bSYour Name 			QDF_STATUS (*handler)(struct wlan_lmac_if_tx_ops *))
283*5113495bSYour Name {
284*5113495bSYour Name 	wlan_global_lmac_if_tx_ops_register[dev_type] = handler;
285*5113495bSYour Name 
286*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
287*5113495bSYour Name }
288*5113495bSYour Name qdf_export_symbol(wlan_global_lmac_if_set_txops_registration_cb);
289