1 /** @file mlan_shim.c
2 *
3 * @brief This file provides APIs to MOAL module
4 *
5 * Copyright 2008-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 /**
12 * @mainpage MLAN Driver
13 *
14 * @section overview_sec Overview
15 *
16 * The MLAN is an OS independent WLAN driver for NXP 802.11
17 * embedded chipset.
18 */
19
20 /********************************************************
21 Change log:
22 10/13/2008: initial version
23 ********************************************************/
24 #include <mlan_api.h>
25
26 /* Additional WMSDK header files */
27 #include <wmerrno.h>
28 #include <osa.h>
29
30 /* Always keep this include at the end of all include files */
31 #include <mlan_remap_mem_operations.h>
32 /********************************************************
33 Local Variables
34 ********************************************************/
35
36 /********************************************************
37 Global Variables
38 ********************************************************/
39 #ifdef STA_SUPPORT
40 static mlan_operations mlan_sta_ops = {
41 /* cmd handler */
42 wlan_ops_sta_prepare_cmd,
43 /* rx handler */
44 wlan_ops_process_rx_packet,
45 /* BSS role: STA */
46 MLAN_BSS_ROLE_STA,
47 };
48 #endif
49 #ifdef UAP_SUPPORT
50 static mlan_operations mlan_uap_ops = {
51 /* cmd handler */
52 wlan_ops_uap_prepare_cmd,
53 /* rx handler */
54 wlan_ops_process_rx_packet,
55 /* BSS role: uAP */
56 MLAN_BSS_ROLE_UAP,
57 };
58 #endif
59
60 /** mlan function table */
61 static mlan_operations *mlan_ops[] = {
62 #ifdef STA_SUPPORT
63 &mlan_sta_ops,
64 #endif
65 #ifdef UAP_SUPPORT
66 &mlan_uap_ops,
67 #endif
68 MNULL,
69 };
70 #if defined(RW610)
71 extern bus_operations imu_ops;
72 #endif
73 /** Global moal_assert callback */
74 t_void (*assert_callback)(IN t_void *pmoal_handle, IN t_u32 cond) = MNULL;
75 #ifdef DEBUG_LEVEL1
76 #ifdef DEBUG_LEVEL2
77 #define DEFAULT_DEBUG_MASK (0xffffffffU)
78 #else
79 #define DEFAULT_DEBUG_MASK (MMSG | MFATAL | MERROR)
80 #endif
81
82 /** Global moal_print callback */
83 t_void (*print_callback)(IN t_void *pmoal_handle, IN t_u32 level, IN t_s8 *pformat, IN...) = MNULL;
84
85 /** Global moal_get_system_time callback */
86 mlan_status (*get_sys_time_callback)(IN t_void *pmoal_handle, OUT t_u32 *psec, OUT t_u32 *pusec) = MNULL;
87
88 /** Global driver debug mit masks */
89 t_u32 drvdbg = DEFAULT_DEBUG_MASK;
90 #endif
91
92 /********************************************************
93 Local Functions
94 *******************************************************/
95
96 /********************************************************
97 Global Functions
98 ********************************************************/
99
100 /**
101 * @brief This function registers MOAL to MLAN module.
102 *
103 * @param pmdevice A pointer to a mlan_device structure
104 * allocated in MOAL
105 * @param ppmlan_adapter A pointer to a t_void pointer to store
106 * mlan_adapter structure pointer as the context
107 *
108 * @return MLAN_STATUS_SUCCESS
109 * The registration succeeded.
110 * MLAN_STATUS_FAILURE
111 * The registration failed.
112 *
113 * mlan_status mlan_register (
114 * IN pmlan_device pmdevice,
115 * OUT t_void **ppmlan_adapter
116 * );
117 *
118 * Comments
119 * MOAL constructs mlan_device data structure to pass moal_handle and
120 * mlan_callback table to MLAN. MLAN returns mlan_adapter pointer to
121 * the ppmlan_adapter buffer provided by MOAL.
122 * Headers:
123 * declared in mlan_decl.h
124 * See Also
125 * mlan_unregister
126 */
mlan_register(IN pmlan_device pmdevice,OUT t_void ** ppmlan_adapter)127 mlan_status mlan_register(IN pmlan_device pmdevice, OUT t_void **ppmlan_adapter)
128 {
129 mlan_status ret = MLAN_STATUS_SUCCESS;
130 pmlan_adapter pmadapter = MNULL;
131 pmlan_callbacks pcb = MNULL;
132 t_u8 i = 0;
133 t_u32 j = 0;
134
135 MASSERT(pmdevice);
136 MASSERT(ppmlan_adapter);
137 /* MASSERT(pmdevice->callbacks.moal_print); */
138 #ifdef DEBUG_LEVEL1
139 print_callback = pmdevice->callbacks.moal_print;
140 get_sys_time_callback = pmdevice->callbacks.moal_get_system_time;
141 #endif
142 /* assert_callback = pmdevice->callbacks.moal_assert; */
143
144 ENTER();
145
146 MASSERT(pmdevice->callbacks.moal_malloc);
147 /* MASSERT(pmdevice->callbacks.moal_memset); */
148 /* MASSERT(pmdevice->callbacks.moal_memmove); */
149
150 /* Allocate memory for adapter structure */
151 #if !CONFIG_MEM_POOLS
152 if ((pmdevice->callbacks.moal_malloc(/* pmdevice->pmoal_handle */ NULL, sizeof(mlan_adapter), MLAN_MEM_DEF,
153 (t_u8 **)(void **)&pmadapter) != MLAN_STATUS_SUCCESS) ||
154 (pmadapter == MNULL))
155 {
156 ret = MLAN_STATUS_FAILURE;
157 goto exit_register;
158 }
159 #else
160 pmadapter = OSA_MemoryPoolAllocate(pmAdapterMemoryPool);
161 if (pmadapter == MNULL)
162 {
163 ret = MLAN_STATUS_FAILURE;
164 goto exit_register;
165 }
166 #endif
167
168 (void)__memset(pmadapter, pmadapter, 0, sizeof(mlan_adapter));
169
170 pcb = &pmadapter->callbacks;
171
172 /* Save callback functions */
173 (void)__memmove(pmadapter->pmoal_handle, pcb, &pmdevice->callbacks, sizeof(mlan_callbacks));
174
175 pmadapter->priv_num = 0;
176 for (i = 0; i < MLAN_MAX_BSS_NUM; i++)
177 {
178 pmadapter->priv[i] = MNULL;
179 if (pmdevice->bss_attr[i].active == MTRUE)
180 {
181 /* For valid bss_attr, allocate memory for private structure */
182 #if !CONFIG_MEM_POOLS
183 if ((pcb->moal_malloc(pmadapter->pmoal_handle, sizeof(mlan_private), MLAN_MEM_DEF,
184 (t_u8 **)(void **)&pmadapter->priv[i]) != MLAN_STATUS_SUCCESS) ||
185 (pmadapter->priv[i] == MNULL))
186 {
187 ret = MLAN_STATUS_FAILURE;
188 goto error;
189 }
190 #else
191 pmadapter->priv[i] = OSA_MemoryPoolAllocate(pmPrivateMemoryPool);
192 if (pmadapter->priv[i] == MNULL)
193 {
194 ret = MLAN_STATUS_FAILURE;
195 goto error;
196 }
197 #endif
198 pmadapter->priv_num++;
199 (void)__memset(pmadapter, pmadapter->priv[i], 0, sizeof(mlan_private));
200
201 pmadapter->priv[i]->adapter = pmadapter;
202
203 /* Save bss_type, frame_type & bss_priority */
204 pmadapter->priv[i]->bss_type = pmdevice->bss_attr[i].bss_type;
205 pmadapter->priv[i]->frame_type = (t_u8)pmdevice->bss_attr[i].frame_type;
206 pmadapter->priv[i]->bss_priority = (t_u8)pmdevice->bss_attr[i].bss_priority;
207 if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_STA)
208 {
209 pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA;
210 pmadapter->priv[i]->bss_mode = MLAN_BSS_MODE_INFRA;
211 }
212 else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_UAP)
213 {
214 pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_UAP;
215 pmadapter->priv[i]->bss_mode = MLAN_BSS_MODE_AUTO;
216 }
217 #ifdef WIFI_DIRECT_SUPPORT
218 else if (pmdevice->bss_attr[i].bss_type == MLAN_BSS_TYPE_WIFIDIRECT)
219 {
220 pmadapter->priv[i]->bss_role = MLAN_BSS_ROLE_STA;
221 }
222 #endif
223 else
224 {
225 /*Do Nothing*/
226 }
227 /* Save bss_index and bss_num */
228 pmadapter->priv[i]->bss_index = i;
229 pmadapter->priv[i]->bss_num = (t_u8)pmdevice->bss_attr[i].bss_num;
230
231 /* init function table */
232 for (j = 0; mlan_ops[j] != MNULL; j++)
233 {
234 if (mlan_ops[j]->bss_role == GET_BSS_ROLE(pmadapter->priv[i]))
235 {
236 (void)__memcpy(pmadapter, &pmadapter->priv[i]->ops, mlan_ops[j], sizeof(mlan_operations));
237 }
238 }
239 }
240 }
241
242 #if defined(RW610)
243 (void)__memcpy(pmadapter, &pmadapter->bus_ops, &imu_ops, sizeof(bus_operations));
244 #endif
245
246 /* Initialize lock variables */
247 if (wlan_init_lock_list(pmadapter) != MLAN_STATUS_SUCCESS)
248 {
249 ret = MLAN_STATUS_FAILURE;
250 goto error;
251 }
252
253 /* Allocate memory for member of adapter structure */
254 if (wlan_allocate_adapter(pmadapter) != MLAN_STATUS_SUCCESS)
255 {
256 ret = MLAN_STATUS_FAILURE;
257 goto error;
258 }
259
260 /* Return pointer of mlan_adapter to MOAL */
261 *ppmlan_adapter = pmadapter;
262
263 goto exit_register;
264
265 error:
266 PRINTM(MINFO, "Leave mlan_register with error\n");
267
268 for (i = 0; i < MLAN_MAX_BSS_NUM; i++)
269 {
270 if (pmadapter->priv[i])
271 #if !CONFIG_MEM_POOLS
272 pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter->priv[i]);
273 #else
274 OSA_MemoryPoolFree(pmPrivateMemoryPool, pmadapter->priv[i]);
275 #endif
276 }
277 #if !CONFIG_MEM_POOLS
278 (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter);
279 #else
280 OSA_MemoryPoolFree(pmAdapterMemoryPool, pmadapter);
281 #endif
282
283 exit_register:
284 LEAVE();
285 return ret;
286 }
287
288 /**
289 * @brief This function unregisters MOAL from MLAN module.
290 *
291 * @param pmlan_adapter A pointer to a mlan_device structure
292 * allocated in MOAL
293 *
294 * @return MLAN_STATUS_SUCCESS
295 * The deregistration succeeded.
296 */
mlan_unregister(IN t_void * pmlan_adapter)297 MLAN_API mlan_status mlan_unregister(IN t_void *pmlan_adapter)
298 {
299 mlan_status ret = MLAN_STATUS_SUCCESS;
300 mlan_adapter *pmadapter = (mlan_adapter *)pmlan_adapter;
301 pmlan_callbacks pcb;
302 t_s32 i = 0;
303
304 MASSERT(pmlan_adapter);
305
306 ENTER();
307
308 pcb = &pmadapter->callbacks;
309
310 wlan_free_adapter(pmadapter);
311
312 /* Free private structures */
313 for (i = 0; i < MIN(pmadapter->priv_num, MLAN_MAX_BSS_NUM); i++)
314 {
315 if (pmadapter->priv[i] != MNULL)
316 {
317 wlan_delete_station_list(pmadapter->priv[i]);
318 (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter->priv[i]);
319 pmadapter->priv[i] = MNULL;
320 }
321 }
322
323 /* Free mlan_adapter */
324 (void)pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter);
325
326 LEAVE();
327 return ret;
328 }
329
330 /**
331 * @brief This function initializes the firmware
332 *
333 * @param pmlan_adapter A pointer to a t_void pointer to store
334 * mlan_adapter structure pointer
335 *
336 * @return MLAN_STATUS_SUCCESS
337 * The firmware initialization succeeded.
338 * MLAN_STATUS_PENDING
339 * The firmware initialization is pending.
340 * MLAN_STATUS_FAILURE
341 * The firmware initialization failed.
342 */
mlan_init_fw(IN t_void * pmlan_adapter)343 mlan_status mlan_init_fw(IN t_void *pmlan_adapter)
344 {
345 mlan_status ret = MLAN_STATUS_SUCCESS;
346 mlan_adapter *pmadapter = (mlan_adapter *)pmlan_adapter;
347
348 ENTER();
349 MASSERT(pmlan_adapter);
350
351 /* pmadapter->hw_status = WlanHardwareStatusInitializing; */
352
353 /* Initialize firmware, may return PENDING */
354 ret = wlan_init_fw(pmadapter);
355 PRINTM(MINFO, "wlan_init_fw returned ret=0x%x\n", ret);
356
357 LEAVE();
358 return ret;
359 }
360