xref: /wlan-dirver/qca-wifi-host-cmn/global_lmac_if/src/wlan_global_lmac_if.c (revision 45a38684b07295822dc8eba39e293408f203eec8)
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 #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 /**
112  * wlan_global_lmac_if_rx_ops_register() - Global lmac_if
113  * rx handler register
114  * @rx_ops: Pointer to rx_ops structure to be populated
115  *
116  * Register lmac_if RX callabacks which will be called by DA/OL/WMA/WMI
117  *
118  * Return: QDF_STATUS_SUCCESS - in case of success
119  */
120 QDF_STATUS
121 wlan_global_lmac_if_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
122 {
123 	/*
124 	 * Component specific public api's to be called to register
125 	 * respective callbacks
126 	 * Ex: rx_ops->fp = function;
127 	 */
128 	if (!rx_ops) {
129 		qdf_err("lmac if rx ops pointer is NULL");
130 		return QDF_STATUS_E_INVAL;
131 	}
132 	/* Registeration for UMAC componets */
133 	wlan_lmac_if_umac_rx_ops_register(rx_ops);
134 
135 	/* spectral rx_ops registration*/
136 	wlan_spectral_register_rx_ops(rx_ops);
137 
138 	/* iot_sim rx_ops registration*/
139 	wlan_iot_sim_register_rx_ops(rx_ops);
140 
141 	return QDF_STATUS_SUCCESS;
142 }
143 
144 /**
145  * wlan_global_lmac_if_open() - global lmac_if open
146  * @psoc: psoc context
147  *
148  * Opens up lmac_if southbound layer. This function calls OL,DA and UMAC
149  * modules to register respective tx and rx callbacks.
150  *
151  * Return: QDF_STATUS
152  */
153 QDF_STATUS wlan_global_lmac_if_open(struct wlan_objmgr_psoc *psoc)
154 {
155 	WLAN_DEV_TYPE dev_type;
156 
157 	struct wlan_lmac_if_tx_ops *tx_ops;
158 	struct wlan_lmac_if_rx_ops *rx_ops;
159 
160 	if (!psoc) {
161 		qdf_err("psoc is NULL");
162 		return QDF_STATUS_E_INVAL;
163 	}
164 
165 	tx_ops = qdf_mem_malloc(sizeof(*tx_ops));
166 	if (!tx_ops) {
167 		qdf_err("tx_ops is NULL");
168 		return QDF_STATUS_E_NOMEM;
169 	}
170 
171 	rx_ops = qdf_mem_malloc(sizeof(*rx_ops));
172 	if (!rx_ops) {
173 		qdf_err("rx_ops is NULL");
174 		qdf_mem_free(tx_ops);
175 		return QDF_STATUS_E_NOMEM;
176 	}
177 
178 	wlan_psoc_set_lmac_if_txops(psoc, tx_ops);
179 	wlan_psoc_set_lmac_if_rxops(psoc, rx_ops);
180 
181 	dev_type = psoc->soc_nif.phy_type;
182 
183 	if (dev_type == WLAN_DEV_DA || dev_type == WLAN_DEV_OL) {
184 		wlan_global_lmac_if_tx_ops_register[dev_type]
185 					(tx_ops);
186 	} else {
187 		/* Control should ideally not reach here */
188 		qdf_print("Invalid device type");
189 		qdf_mem_free(tx_ops);
190 		qdf_mem_free(rx_ops);
191 		return QDF_STATUS_E_INVAL;
192 	}
193 
194 	/* Function call to register rx-ops handlers */
195 	wlan_global_lmac_if_rx_ops_register(rx_ops);
196 
197 	target_if_wake_lock_init(psoc);
198 
199 	return QDF_STATUS_SUCCESS;
200 }
201 qdf_export_symbol(wlan_global_lmac_if_open);
202 
203 /**
204  * wlan_global_lmac_if_close() - Close global lmac_if
205  * @psoc: psoc context
206  *
207  * Deregister lmac_if TX and RX handlers
208  *
209  * Return: QDF_STATUS_SUCCESS - in case of success
210  */
211 QDF_STATUS wlan_global_lmac_if_close(struct wlan_objmgr_psoc *psoc)
212 {
213 	struct wlan_lmac_if_tx_ops *tx_ops;
214 	struct wlan_lmac_if_rx_ops *rx_ops;
215 
216 	if (!psoc) {
217 		qdf_err("psoc is NULL");
218 		return QDF_STATUS_E_INVAL;
219 	}
220 
221 	target_if_wake_lock_deinit(psoc);
222 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
223 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
224 
225 	wlan_psoc_set_lmac_if_txops(psoc, NULL);
226 	wlan_psoc_set_lmac_if_rxops(psoc, NULL);
227 
228 	qdf_mem_free(tx_ops);
229 	qdf_mem_free(rx_ops);
230 
231 	return QDF_STATUS_SUCCESS;
232 }
233 qdf_export_symbol(wlan_global_lmac_if_close);
234 
235 /**
236  * wlan_global_lmac_if_set_txops_registration_cb() - tx
237  * registration callback assignment
238  * @dev_type: Dev type can be either Direct attach or Offload
239  * @handler: handler to be called for LMAC tx ops registration
240  *
241  * API to assign appropriate tx registration callback handler based on the
242  * device type(Offload or Direct attach)
243  *
244  * Return: QDF_STATUS_SUCCESS - in case of success
245  */
246 QDF_STATUS wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_TYPE dev_type,
247 			QDF_STATUS (*handler)(struct wlan_lmac_if_tx_ops *))
248 {
249 	wlan_global_lmac_if_tx_ops_register[dev_type] = handler;
250 
251 	return QDF_STATUS_SUCCESS;
252 }
253 qdf_export_symbol(wlan_global_lmac_if_set_txops_registration_cb);
254