1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
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 #ifdef SPECTRAL_MODULIZED_ENABLE
42 /* Function pointer for spectral rx_ops registration function */
43 void (*wlan_lmac_if_sptrl_rx_ops)(struct wlan_lmac_if_rx_ops *rx_ops);
44
wlan_lmac_if_sptrl_set_rx_ops_register_cb(void (* handler)(struct wlan_lmac_if_rx_ops *))45 QDF_STATUS wlan_lmac_if_sptrl_set_rx_ops_register_cb(void (*handler)
46 (struct wlan_lmac_if_rx_ops *))
47 {
48 wlan_lmac_if_sptrl_rx_ops = handler;
49
50 return QDF_STATUS_SUCCESS;
51 }
52
53 qdf_export_symbol(wlan_lmac_if_sptrl_set_rx_ops_register_cb);
54
55 /**
56 * wlan_spectral_register_rx_ops() - Register spectral component RX OPS
57 * @rx_ops: lmac if receive ops
58 *
59 * Return: None
60 */
wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)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
wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)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 */
wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)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
wlan_lmac_if_iot_sim_set_rx_ops_register_cb(void (* handler)(struct wlan_lmac_if_rx_ops *))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
wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)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
wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)106 static void wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
107 {
108 }
109 #endif
110
111 #if defined(QCA_SUPPORT_SON) || defined(WLAN_FEATURE_SON)
112 /* Function pointer for son rx_ops registration function */
113 void (*wlan_lmac_if_son_rx_ops)(struct wlan_lmac_if_rx_ops *rx_ops);
114
wlan_lmac_if_son_set_rx_ops_register_cb(void (* handler)(struct wlan_lmac_if_rx_ops *))115 QDF_STATUS wlan_lmac_if_son_set_rx_ops_register_cb(void (*handler)
116 (struct wlan_lmac_if_rx_ops *))
117 {
118 wlan_lmac_if_son_rx_ops = handler;
119
120 return QDF_STATUS_SUCCESS;
121 }
122
123 qdf_export_symbol(wlan_lmac_if_son_set_rx_ops_register_cb);
124
wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)125 static void wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
126 {
127 if (wlan_lmac_if_son_rx_ops)
128 wlan_lmac_if_son_rx_ops(rx_ops);
129 else
130 qdf_info("\n***** SON MODULE NOT LOADED *****\n");
131 }
132
wlan_lmac_if_son_mod_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)133 void wlan_lmac_if_son_mod_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
134 {
135 wlan_son_register_rx_ops(rx_ops);
136 }
137 #else
wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops * rx_ops)138 static void wlan_son_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
139 {
140 }
141 #endif
142
143 /**
144 * wlan_global_lmac_if_rx_ops_register() - Global lmac_if
145 * rx handler register
146 * @rx_ops: Pointer to rx_ops structure to be populated
147 *
148 * Register lmac_if RX callabacks which will be called by DA/OL/WMA/WMI
149 *
150 * Return: QDF_STATUS_SUCCESS - in case of success
151 */
152 QDF_STATUS
wlan_global_lmac_if_rx_ops_register(struct wlan_lmac_if_rx_ops * rx_ops)153 wlan_global_lmac_if_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
154 {
155 /*
156 * Component specific public api's to be called to register
157 * respective callbacks
158 * Ex: rx_ops->fp = function;
159 */
160 if (!rx_ops) {
161 qdf_err("lmac if rx ops pointer is NULL");
162 return QDF_STATUS_E_INVAL;
163 }
164 /* Registration for UMAC components */
165 wlan_lmac_if_umac_rx_ops_register(rx_ops);
166
167 /* spectral rx_ops registration*/
168 wlan_spectral_register_rx_ops(rx_ops);
169
170 /* iot_sim rx_ops registration*/
171 wlan_iot_sim_register_rx_ops(rx_ops);
172
173 /* son rx_ops registration*/
174 wlan_son_register_rx_ops(rx_ops);
175
176 return QDF_STATUS_SUCCESS;
177 }
178
179 /**
180 * wlan_global_lmac_if_open() - global lmac_if open
181 * @psoc: psoc context
182 *
183 * Opens up lmac_if southbound layer. This function calls OL,DA and UMAC
184 * modules to register respective tx and rx callbacks.
185 *
186 * Return: QDF_STATUS
187 */
wlan_global_lmac_if_open(struct wlan_objmgr_psoc * psoc)188 QDF_STATUS wlan_global_lmac_if_open(struct wlan_objmgr_psoc *psoc)
189 {
190 WLAN_DEV_TYPE dev_type;
191
192 struct wlan_lmac_if_tx_ops *tx_ops;
193 struct wlan_lmac_if_rx_ops *rx_ops;
194
195 if (!psoc) {
196 qdf_err("psoc is NULL");
197 return QDF_STATUS_E_INVAL;
198 }
199
200 tx_ops = qdf_mem_malloc(sizeof(*tx_ops));
201 if (!tx_ops) {
202 qdf_err("tx_ops is NULL");
203 return QDF_STATUS_E_NOMEM;
204 }
205
206 rx_ops = qdf_mem_malloc(sizeof(*rx_ops));
207 if (!rx_ops) {
208 qdf_err("rx_ops is NULL");
209 qdf_mem_free(tx_ops);
210 return QDF_STATUS_E_NOMEM;
211 }
212
213 wlan_psoc_set_lmac_if_txops(psoc, tx_ops);
214 wlan_psoc_set_lmac_if_rxops(psoc, rx_ops);
215
216 dev_type = psoc->soc_nif.phy_type;
217
218 if (dev_type == WLAN_DEV_OL) {
219 wlan_global_lmac_if_tx_ops_register[dev_type]
220 (tx_ops);
221 } else {
222 /* Control should ideally not reach here */
223 qdf_print("Invalid device type");
224 qdf_mem_free(tx_ops);
225 qdf_mem_free(rx_ops);
226 return QDF_STATUS_E_INVAL;
227 }
228
229 /* Function call to register rx-ops handlers */
230 wlan_global_lmac_if_rx_ops_register(rx_ops);
231
232 target_if_wake_lock_init(psoc);
233
234 return QDF_STATUS_SUCCESS;
235 }
236 qdf_export_symbol(wlan_global_lmac_if_open);
237
238 /**
239 * wlan_global_lmac_if_close() - Close global lmac_if
240 * @psoc: psoc context
241 *
242 * Deregister lmac_if TX and RX handlers
243 *
244 * Return: QDF_STATUS_SUCCESS - in case of success
245 */
wlan_global_lmac_if_close(struct wlan_objmgr_psoc * psoc)246 QDF_STATUS wlan_global_lmac_if_close(struct wlan_objmgr_psoc *psoc)
247 {
248 struct wlan_lmac_if_tx_ops *tx_ops;
249 struct wlan_lmac_if_rx_ops *rx_ops;
250
251 if (!psoc) {
252 qdf_err("psoc is NULL");
253 return QDF_STATUS_E_INVAL;
254 }
255
256 target_if_wake_lock_deinit(psoc);
257 tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
258 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
259
260 wlan_psoc_set_lmac_if_txops(psoc, NULL);
261 wlan_psoc_set_lmac_if_rxops(psoc, NULL);
262
263 qdf_mem_free(tx_ops);
264 qdf_mem_free(rx_ops);
265
266 return QDF_STATUS_SUCCESS;
267 }
268 qdf_export_symbol(wlan_global_lmac_if_close);
269
270 /**
271 * wlan_global_lmac_if_set_txops_registration_cb() - tx
272 * registration callback assignment
273 * @dev_type: Dev type can be either Direct attach or Offload
274 * @handler: handler to be called for LMAC tx ops registration
275 *
276 * API to assign appropriate tx registration callback handler based on the
277 * device type(Offload or Direct attach)
278 *
279 * Return: QDF_STATUS_SUCCESS - in case of success
280 */
wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_TYPE dev_type,QDF_STATUS (* handler)(struct wlan_lmac_if_tx_ops *))281 QDF_STATUS wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_TYPE dev_type,
282 QDF_STATUS (*handler)(struct wlan_lmac_if_tx_ops *))
283 {
284 wlan_global_lmac_if_tx_ops_register[dev_type] = handler;
285
286 return QDF_STATUS_SUCCESS;
287 }
288 qdf_export_symbol(wlan_global_lmac_if_set_txops_registration_cb);
289