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