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