xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlan/mlan_shim.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file mlan_shim.c
2  *
3  *  @brief This file contains APIs to MOAL module.
4  *
5  *
6  *  Copyright 2008-2021 NXP
7  *
8  *  This software file (the File) is distributed by NXP
9  *  under the terms of the GNU General Public License Version 2, June 1991
10  *  (the License).  You may use, redistribute and/or modify the File in
11  *  accordance with the terms and conditions of the License, a copy of which
12  *  is available by writing to the Free Software Foundation, Inc.,
13  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
14  *  worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
15  *
16  *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
19  *  this warranty disclaimer.
20  *
21  */
22 
23 /********************************************************
24 Change log:
25     10/13/2008: initial version
26 ********************************************************/
27 
28 #include "mlan.h"
29 #ifdef STA_SUPPORT
30 #include "mlan_join.h"
31 #endif
32 #include "mlan_util.h"
33 #include "mlan_fw.h"
34 #include "mlan_main.h"
35 #include "mlan_wmm.h"
36 #ifdef SDIO
37 #include "mlan_sdio.h"
38 #endif /* SDIO */
39 #ifdef PCIE
40 #include "mlan_pcie.h"
41 #endif /* PCIE */
42 #ifdef UAP_SUPPORT
43 #include "mlan_uap.h"
44 #endif
45 #include "mlan_11h.h"
46 #include "mlan_11n_rxreorder.h"
47 #ifdef DRV_EMBEDDED_AUTHENTICATOR
48 #include "authenticator_api.h"
49 #endif
50 
51 /********************************************************
52 			Local Variables
53 ********************************************************/
54 
55 /********************************************************
56 			Global Variables
57 ********************************************************/
58 #ifdef STA_SUPPORT
59 static mlan_operations mlan_sta_ops = {
60 	/* init cmd handler */
61 	wlan_ops_sta_init_cmd,
62 	/* ioctl handler */
63 	wlan_ops_sta_ioctl,
64 	/* cmd handler */
65 	wlan_ops_sta_prepare_cmd,
66 	/* cmdresp handler */
67 	wlan_ops_sta_process_cmdresp,
68 	/* rx handler */
69 	wlan_ops_sta_process_rx_packet,
70 	/* Event handler */
71 	wlan_ops_sta_process_event,
72 	/* txpd handler */
73 	wlan_ops_sta_process_txpd,
74 	/* BSS role: STA */
75 	MLAN_BSS_ROLE_STA,
76 };
77 #endif
78 #ifdef UAP_SUPPORT
79 static mlan_operations mlan_uap_ops = {
80 	/* init cmd handler */
81 	wlan_ops_uap_init_cmd,
82 	/* ioctl handler */
83 	wlan_ops_uap_ioctl,
84 	/* cmd handler */
85 	wlan_ops_uap_prepare_cmd,
86 	/* cmdresp handler */
87 	wlan_ops_uap_process_cmdresp,
88 	/* rx handler */
89 	wlan_ops_uap_process_rx_packet,
90 	/* Event handler */
91 	wlan_ops_uap_process_event,
92 	/* txpd handler */
93 	wlan_ops_uap_process_txpd,
94 	/* BSS role: uAP */
95 	MLAN_BSS_ROLE_UAP,
96 };
97 #endif
98 
99 /** mlan function table */
100 mlan_operations *mlan_ops[] = {
101 #ifdef STA_SUPPORT
102 	&mlan_sta_ops,
103 #endif
104 #ifdef UAP_SUPPORT
105 	&mlan_uap_ops,
106 #endif
107 	MNULL,
108 };
109 
110 /** Global moal_assert callback */
111 t_void (*assert_callback)(t_pvoid pmoal_handle, t_u32 cond) = MNULL;
112 #ifdef DEBUG_LEVEL1
113 #ifdef DEBUG_LEVEL2
114 #define DEFAULT_DEBUG_MASK (0xffffffff)
115 #else
116 #define DEFAULT_DEBUG_MASK (MMSG | MFATAL | MERROR)
117 #endif
118 
119 /** Global moal_print callback */
120 t_void (*print_callback)(t_pvoid pmoal_handle, t_u32 level, char *pformat,
121 			 IN...) = MNULL;
122 
123 /** Global moal_get_system_time callback */
124 mlan_status (*get_sys_time_callback)(t_pvoid pmoal_handle, t_pu32 psec,
125 				     t_pu32 pusec) = MNULL;
126 
127 /** Global driver debug mit masks */
128 t_u32 mlan_drvdbg = DEFAULT_DEBUG_MASK;
129 #endif
130 
131 #ifdef USB
132 extern mlan_status wlan_get_usb_device(pmlan_adapter pmadapter);
133 #endif
134 /********************************************************
135 			Local Functions
136 *******************************************************/
137 /**
138  *  @brief This function process pending ioctl
139  *
140  *  @param pmadapter  A pointer to mlan_adapter structure
141  *
142  */
wlan_process_pending_ioctl(mlan_adapter * pmadapter)143 static void wlan_process_pending_ioctl(mlan_adapter *pmadapter)
144 {
145 	pmlan_ioctl_req pioctl_buf;
146 	mlan_status status = MLAN_STATUS_SUCCESS;
147 	pmlan_callbacks pcb;
148 #if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
149 	pmlan_ds_bss bss = MNULL;
150 #endif
151 #ifdef STA_SUPPORT
152 	pmlan_ds_misc_cfg misc = MNULL;
153 #endif
154 	ENTER();
155 
156 	pcb = &pmadapter->callbacks;
157 
158 	while ((pioctl_buf = (pmlan_ioctl_req)util_dequeue_list(
159 			pmadapter->pmoal_handle, &pmadapter->ioctl_pending_q,
160 			pcb->moal_spin_lock, pcb->moal_spin_unlock))) {
161 		switch (pioctl_buf->req_id) {
162 #if defined(STA_SUPPORT) && defined(UAP_SUPPORT)
163 		case MLAN_IOCTL_BSS:
164 			bss = (mlan_ds_bss *)pioctl_buf->pbuf;
165 			if (bss->sub_command == MLAN_OID_BSS_ROLE) {
166 				PRINTM(MCMND, "Role switch ioctl: %d\n",
167 				       bss->param.bss_role);
168 				status = wlan_bss_ioctl_bss_role(pmadapter,
169 								 pioctl_buf);
170 			}
171 			break;
172 #endif
173 #ifdef STA_SUPPORT
174 		case MLAN_IOCTL_MISC_CFG:
175 			misc = (mlan_ds_misc_cfg *)pioctl_buf->pbuf;
176 			if (misc->sub_command == MLAN_OID_MISC_WARM_RESET) {
177 				PRINTM(MCMND, "Warm Reset ioctl\n");
178 				status = wlan_misc_ioctl_warm_reset(pmadapter,
179 								    pioctl_buf);
180 			}
181 			break;
182 #endif
183 		default:
184 			break;
185 		}
186 		if (status != MLAN_STATUS_PENDING)
187 			pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
188 						 pioctl_buf, status);
189 	}
190 	LEAVE();
191 }
192 /********************************************************
193 			Global Functions
194 ********************************************************/
195 
196 /**
197  *  @brief This function registers MOAL to MLAN module.
198  *
199  *  @param pmdevice        A pointer to a mlan_device structure
200  *                         allocated in MOAL
201  *  @param ppmlan_adapter  A pointer to a t_void pointer to store
202  *                         mlan_adapter structure pointer as the context
203  *
204  *  @return                MLAN_STATUS_SUCCESS
205  *                             The registration succeeded.
206  *                         MLAN_STATUS_FAILURE
207  *                             The registration failed.
208  *
209  * mlan_status mlan_register(
210  *   pmlan_device     pmdevice,
211  *   t_void           **ppmlan_adapter
212  * );
213  *
214  * Comments
215  *   MOAL constructs mlan_device data structure to pass moal_handle and
216  *   mlan_callback table to MLAN. MLAN returns mlan_adapter pointer to
217  *   the ppmlan_adapter buffer provided by MOAL.
218  * Headers:
219  *   declared in mlan_decl.h
220  * See Also
221  *   mlan_unregister
222  */
mlan_register(pmlan_device pmdevice,t_void ** ppmlan_adapter)223 mlan_status mlan_register(pmlan_device pmdevice, t_void **ppmlan_adapter)
224 {
225 	mlan_status ret = MLAN_STATUS_SUCCESS;
226 	pmlan_adapter pmadapter = MNULL;
227 	pmlan_callbacks pcb = MNULL;
228 	t_u8 i = 0;
229 	t_u32 j = 0;
230 
231 	if (!pmdevice || !ppmlan_adapter) {
232 		return MLAN_STATUS_FAILURE;
233 	}
234 	MASSERT(ppmlan_adapter);
235 	MASSERT(pmdevice->callbacks.moal_print);
236 #ifdef DEBUG_LEVEL1
237 	print_callback = pmdevice->callbacks.moal_print;
238 	get_sys_time_callback = pmdevice->callbacks.moal_get_system_time;
239 #endif
240 	assert_callback = pmdevice->callbacks.moal_assert;
241 
242 	ENTER();
243 
244 	MASSERT(pmdevice->callbacks.moal_malloc);
245 	MASSERT(pmdevice->callbacks.moal_mfree);
246 	MASSERT(pmdevice->callbacks.moal_memset);
247 	MASSERT(pmdevice->callbacks.moal_memmove);
248 	MASSERT(pmdevice->callbacks.moal_udelay);
249 	MASSERT(pmdevice->callbacks.moal_usleep_range);
250 
251 	if (!pmdevice->callbacks.moal_malloc ||
252 	    !pmdevice->callbacks.moal_mfree ||
253 	    !pmdevice->callbacks.moal_memset ||
254 	    !pmdevice->callbacks.moal_udelay ||
255 	    !pmdevice->callbacks.moal_usleep_range ||
256 	    !pmdevice->callbacks.moal_memmove) {
257 		LEAVE();
258 		return MLAN_STATUS_FAILURE;
259 	}
260 	if (pmdevice->callbacks.moal_recv_amsdu_packet)
261 		PRINTM(MMSG, "Enable moal_recv_amsdu_packet\n");
262 
263 	/* Allocate memory for adapter structure */
264 	if (pmdevice->callbacks.moal_vmalloc && pmdevice->callbacks.moal_vfree)
265 		ret = pmdevice->callbacks.moal_vmalloc(pmdevice->pmoal_handle,
266 						       sizeof(mlan_adapter),
267 						       (t_u8 **)&pmadapter);
268 	else
269 		ret = pmdevice->callbacks.moal_malloc(pmdevice->pmoal_handle,
270 						      sizeof(mlan_adapter),
271 						      MLAN_MEM_DEF,
272 						      (t_u8 **)&pmadapter);
273 	if ((ret != MLAN_STATUS_SUCCESS) || !pmadapter) {
274 		ret = MLAN_STATUS_FAILURE;
275 		goto exit_register;
276 	}
277 
278 	pmdevice->callbacks.moal_memset(pmdevice->pmoal_handle, pmadapter, 0,
279 					sizeof(mlan_adapter));
280 
281 	pcb = &pmadapter->callbacks;
282 
283 	/* Save callback functions */
284 	pmdevice->callbacks.moal_memmove(pmadapter->pmoal_handle, pcb,
285 					 &pmdevice->callbacks,
286 					 sizeof(mlan_callbacks));
287 
288 	/* Assertion for all callback functions */
289 	MASSERT(pcb->moal_get_hw_spec_complete);
290 	MASSERT(pcb->moal_init_fw_complete);
291 	MASSERT(pcb->moal_shutdown_fw_complete);
292 	MASSERT(pcb->moal_send_packet_complete);
293 	MASSERT(pcb->moal_recv_packet);
294 	MASSERT(pcb->moal_recv_event);
295 	MASSERT(pcb->moal_ioctl_complete);
296 
297 #if defined(SDIO) || defined(PCIE)
298 	if (!IS_USB(pmadapter->card_type)) {
299 		MASSERT(pcb->moal_write_reg);
300 		MASSERT(pcb->moal_read_reg);
301 		MASSERT(pcb->moal_alloc_mlan_buffer);
302 		MASSERT(pcb->moal_free_mlan_buffer);
303 	}
304 #endif
305 	MASSERT(pcb->moal_get_vdll_data);
306 	MASSERT(pcb->moal_write_data_sync);
307 	MASSERT(pcb->moal_read_data_sync);
308 	MASSERT(pcb->moal_mfree);
309 	MASSERT(pcb->moal_memcpy);
310 	MASSERT(pcb->moal_memcpy_ext);
311 	MASSERT(pcb->moal_memcmp);
312 	MASSERT(pcb->moal_get_system_time);
313 	MASSERT(pcb->moal_init_timer);
314 	MASSERT(pcb->moal_free_timer);
315 	MASSERT(pcb->moal_get_boot_ktime);
316 	MASSERT(pcb->moal_start_timer);
317 	MASSERT(pcb->moal_stop_timer);
318 	MASSERT(pcb->moal_init_lock);
319 	MASSERT(pcb->moal_free_lock);
320 	MASSERT(pcb->moal_spin_lock);
321 	MASSERT(pcb->moal_spin_unlock);
322 	MASSERT(pcb->moal_hist_data_add);
323 	MASSERT(pcb->moal_updata_peer_signal);
324 	MASSERT(pcb->moal_do_div);
325 	/* Save pmoal_handle */
326 	pmadapter->pmoal_handle = pmdevice->pmoal_handle;
327 
328 	pmadapter->feature_control = pmdevice->feature_control;
329 
330 	pmadapter->card_type = pmdevice->card_type;
331 	pmadapter->card_rev = pmdevice->card_rev;
332 	pmadapter->init_para.uap_max_sta = pmdevice->uap_max_sta;
333 	pmadapter->init_para.mcs32 = pmdevice->mcs32;
334 
335 #ifdef SDIO
336 	if (IS_SD(pmadapter->card_type)) {
337 		PRINTM(MMSG,
338 		       "Attach mlan adapter operations.card_type is 0x%x.\n",
339 		       pmdevice->card_type);
340 		memcpy_ext(pmadapter, &pmadapter->ops, &mlan_sdio_ops,
341 			   sizeof(mlan_adapter_operations),
342 			   sizeof(mlan_adapter_operations));
343 		ret = wlan_get_sdio_device(pmadapter);
344 		if (MLAN_STATUS_SUCCESS != ret) {
345 			ret = MLAN_STATUS_FAILURE;
346 			goto error;
347 		}
348 		if ((pmdevice->int_mode == INT_MODE_GPIO) &&
349 		    (pmdevice->gpio_pin == 0)) {
350 			PRINTM(MERROR,
351 			       "SDIO_GPIO_INT_CONFIG: Invalid GPIO Pin\n");
352 			ret = MLAN_STATUS_FAILURE;
353 			goto error;
354 		}
355 		pmadapter->init_para.int_mode = pmdevice->int_mode;
356 		pmadapter->init_para.gpio_pin = pmdevice->gpio_pin;
357 		/* card specific probing has been deferred until now .. */
358 		ret = wlan_sdio_probe(pmadapter);
359 		if (MLAN_STATUS_SUCCESS != ret) {
360 			ret = MLAN_STATUS_FAILURE;
361 			goto error;
362 		}
363 		pmadapter->pcard_sd->max_segs = pmdevice->max_segs;
364 		pmadapter->pcard_sd->max_seg_size = pmdevice->max_seg_size;
365 
366 		pmadapter->init_para.mpa_tx_cfg = pmdevice->mpa_tx_cfg;
367 		pmadapter->init_para.mpa_rx_cfg = pmdevice->mpa_rx_cfg;
368 		pmadapter->pcard_sd->sdio_rx_aggr_enable =
369 			pmdevice->sdio_rx_aggr_enable;
370 	}
371 #endif
372 
373 #ifdef PCIE
374 	if (IS_PCIE(pmadapter->card_type)) {
375 		MASSERT(pcb->moal_malloc_consistent);
376 		MASSERT(pcb->moal_mfree_consistent);
377 		MASSERT(pcb->moal_map_memory);
378 		MASSERT(pcb->moal_unmap_memory);
379 		PRINTM(MMSG,
380 		       "Attach mlan adapter operations.card_type is 0x%x.\n",
381 		       pmdevice->card_type);
382 		memcpy_ext(pmadapter, &pmadapter->ops, &mlan_pcie_ops,
383 			   sizeof(mlan_adapter_operations),
384 			   sizeof(mlan_adapter_operations));
385 		pmadapter->init_para.ring_size = pmdevice->ring_size;
386 		ret = wlan_get_pcie_device(pmadapter);
387 		if (MLAN_STATUS_SUCCESS != ret) {
388 			ret = MLAN_STATUS_FAILURE;
389 			goto error;
390 		}
391 	}
392 #endif
393 
394 #ifdef USB
395 	if (IS_USB(pmadapter->card_type)) {
396 		MASSERT(pcb->moal_write_data_async);
397 		MASSERT(pcb->moal_recv_complete);
398 		PRINTM(MMSG,
399 		       "Attach mlan adapter operations.card_type is 0x%x.\n",
400 		       pmdevice->card_type);
401 		memcpy_ext(pmadapter, &pmadapter->ops, &mlan_usb_ops,
402 			   sizeof(mlan_adapter_operations),
403 			   sizeof(mlan_adapter_operations));
404 		ret = wlan_get_usb_device(pmadapter);
405 		if (MLAN_STATUS_SUCCESS != ret) {
406 			ret = MLAN_STATUS_FAILURE;
407 			goto error;
408 		}
409 	}
410 #endif
411 
412 #ifdef DEBUG_LEVEL1
413 	mlan_drvdbg = pmdevice->drvdbg;
414 #endif
415 
416 #ifdef MFG_CMD_SUPPORT
417 	pmadapter->init_para.mfg_mode = pmdevice->mfg_mode;
418 #endif
419 	pmadapter->init_para.auto_ds = pmdevice->auto_ds;
420 	pmadapter->init_para.ext_scan = pmdevice->ext_scan;
421 	pmadapter->init_para.ps_mode = pmdevice->ps_mode;
422 	if (pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_2K ||
423 	    pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_4K ||
424 	    pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_12K ||
425 	    pmdevice->max_tx_buf == MLAN_TX_DATA_BUF_SIZE_8K)
426 		pmadapter->init_para.max_tx_buf = pmdevice->max_tx_buf;
427 #ifdef STA_SUPPORT
428 	pmadapter->init_para.cfg_11d = pmdevice->cfg_11d;
429 #else
430 	pmadapter->init_para.cfg_11d = 0;
431 #endif
432 	if (IS_DFS_SUPPORT(pmadapter->feature_control))
433 		pmadapter->init_para.dfs_master_radar_det_en =
434 			DFS_MASTER_RADAR_DETECT_EN;
435 	pmadapter->init_para.dfs_slave_radar_det_en = DFS_SLAVE_RADAR_DETECT_EN;
436 	pmadapter->init_para.dev_cap_mask = pmdevice->dev_cap_mask;
437 	pmadapter->init_para.indrstcfg = pmdevice->indrstcfg;
438 	pmadapter->rx_work_flag = pmdevice->rx_work;
439 	pmadapter->init_para.passive_to_active_scan =
440 		pmdevice->passive_to_active_scan;
441 	pmadapter->fixed_beacon_buffer = pmdevice->fixed_beacon_buffer;
442 
443 	pmadapter->multiple_dtim = pmdevice->multi_dtim;
444 	pmadapter->inact_tmo = pmdevice->inact_tmo;
445 	pmadapter->hs_wake_interval = pmdevice->hs_wake_interval;
446 	if (pmdevice->indication_gpio != 0xff) {
447 		pmadapter->ind_gpio = pmdevice->indication_gpio & 0x0f;
448 		pmadapter->level = (pmdevice->indication_gpio & 0xf0) >> 4;
449 		if (pmadapter->level != 0 && pmadapter->level != 1) {
450 			PRINTM(MERROR,
451 			       "Indication GPIO level is wrong and will use default value 0.\n");
452 			pmadapter->level = 0;
453 		}
454 	}
455 	pmadapter->hs_mimo_switch = pmdevice->hs_mimo_switch;
456 #ifdef USB
457 	if (IS_USB(pmadapter->card_type)) {
458 		pmadapter->tx_cmd_ep = pmdevice->tx_cmd_ep;
459 		pmadapter->rx_cmd_ep = pmdevice->rx_cmd_ep;
460 		pmadapter->tx_data_ep = pmdevice->tx_data_ep;
461 		pmadapter->rx_data_ep = pmdevice->rx_data_ep;
462 	}
463 #endif
464 	pmadapter->init_para.dfs53cfg = pmdevice->dfs53cfg;
465 	pmadapter->init_para.dfs_offload = pmdevice->dfs_offload;
466 	pmadapter->priv_num = 0;
467 	pmadapter->priv[0] = MNULL;
468 
469 	if (pcb->moal_vmalloc && pcb->moal_vfree)
470 		ret = pcb->moal_vmalloc(pmadapter->pmoal_handle,
471 					sizeof(mlan_private),
472 					(t_u8 **)&pmadapter->priv[0]);
473 	else
474 		ret = pcb->moal_malloc(pmadapter->pmoal_handle,
475 				       sizeof(mlan_private), MLAN_MEM_DEF,
476 				       (t_u8 **)&pmadapter->priv[0]);
477 	if (ret != MLAN_STATUS_SUCCESS || !pmadapter->priv[0]) {
478 		ret = MLAN_STATUS_FAILURE;
479 		goto error;
480 	}
481 
482 	pmadapter->priv_num++;
483 	memset(pmadapter, pmadapter->priv[0], 0, sizeof(mlan_private));
484 
485 	pmadapter->priv[0]->adapter = pmadapter;
486 	if (pmdevice->drv_mode & DRV_MODE_MASK) {
487 		/* Save bss_type, frame_type & bss_priority */
488 		pmadapter->priv[0]->bss_type = 0xff;
489 		pmadapter->priv[0]->frame_type = MLAN_DATA_FRAME_TYPE_ETH_II;
490 		pmadapter->priv[0]->bss_priority = 0;
491 		pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_STA;
492 
493 		/* Save bss_index and bss_num */
494 		pmadapter->priv[0]->bss_index = 0;
495 		pmadapter->priv[0]->bss_num = 0xff;
496 	} else {
497 		pmadapter->priv[0]->bss_type =
498 			(t_u8)pmdevice->bss_attr[0].bss_type;
499 		pmadapter->priv[0]->frame_type =
500 			(t_u8)pmdevice->bss_attr[0].frame_type;
501 		pmadapter->priv[0]->bss_priority =
502 			(t_u8)pmdevice->bss_attr[0].bss_priority;
503 		if (pmdevice->bss_attr[0].bss_type == MLAN_BSS_TYPE_STA)
504 			pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_STA;
505 		else if (pmdevice->bss_attr[0].bss_type == MLAN_BSS_TYPE_UAP)
506 			pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_UAP;
507 #ifdef WIFI_DIRECT_SUPPORT
508 		else if (pmdevice->bss_attr[0].bss_type ==
509 			 MLAN_BSS_TYPE_WIFIDIRECT) {
510 			pmadapter->priv[0]->bss_role = MLAN_BSS_ROLE_STA;
511 			if (pmdevice->bss_attr[0].bss_virtual)
512 				pmadapter->priv[0]->bss_virtual = MTRUE;
513 		}
514 #endif
515 		/* Save bss_index and bss_num */
516 		pmadapter->priv[0]->bss_index = 0;
517 		pmadapter->priv[0]->bss_num =
518 			(t_u8)pmdevice->bss_attr[0].bss_num;
519 	}
520 
521 	/* init function table */
522 	for (j = 0; mlan_ops[j]; j++) {
523 		if (mlan_ops[j]->bss_role == GET_BSS_ROLE(pmadapter->priv[0])) {
524 			memcpy_ext(pmadapter, &pmadapter->priv[0]->ops,
525 				   mlan_ops[j], sizeof(mlan_operations),
526 				   sizeof(mlan_operations));
527 			break;
528 		}
529 	}
530 	/** back up bss_attr table */
531 	memcpy_ext(pmadapter, pmadapter->bss_attr, pmdevice->bss_attr,
532 		   sizeof(pmadapter->bss_attr), sizeof(pmadapter->bss_attr));
533 
534 	/* Initialize lock variables */
535 	if (wlan_init_lock_list(pmadapter) != MLAN_STATUS_SUCCESS) {
536 		ret = MLAN_STATUS_FAILURE;
537 		goto error;
538 	}
539 
540 	/** init lock varible for first priv */
541 	if (wlan_init_priv_lock_list(pmadapter, 0) != MLAN_STATUS_SUCCESS) {
542 		ret = MLAN_STATUS_FAILURE;
543 		goto error;
544 	}
545 
546 	/* Allocate memory for member of adapter structure */
547 	if (wlan_allocate_adapter(pmadapter)) {
548 		ret = MLAN_STATUS_FAILURE;
549 		goto error;
550 	}
551 
552 	/* Initialize timers */
553 	if (wlan_init_timer(pmadapter) != MLAN_STATUS_SUCCESS) {
554 		ret = MLAN_STATUS_FAILURE;
555 		goto error;
556 	}
557 	/* Return pointer of mlan_adapter to MOAL */
558 	*ppmlan_adapter = pmadapter;
559 
560 	goto exit_register;
561 
562 error:
563 	PRINTM(MINFO, "Leave mlan_register with error\n");
564 	/* Free adapter structure */
565 	wlan_free_adapter(pmadapter);
566 
567 	for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
568 		if (pmadapter->priv[i]) {
569 			if (pcb->moal_vmalloc && pcb->moal_vfree)
570 				pcb->moal_vfree(pmadapter->pmoal_handle,
571 						(t_u8 *)pmadapter->priv[i]);
572 			else if (pcb->moal_mfree)
573 				pcb->moal_mfree(pmadapter->pmoal_handle,
574 						(t_u8 *)pmadapter->priv[i]);
575 		}
576 	}
577 	if (pcb->moal_vmalloc && pcb->moal_vfree)
578 		pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter);
579 	else if (pcb->moal_mfree)
580 		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter);
581 
582 exit_register:
583 	LEAVE();
584 	return ret;
585 }
586 
587 /**
588  *  @brief This function unregisters MOAL from MLAN module.
589  *
590  *  @param padapter  A pointer to a mlan_device structure
591  *                         allocated in MOAL
592  *
593  *  @return                MLAN_STATUS_SUCCESS
594  *                             The deregistration succeeded.
595  */
mlan_unregister(t_void * padapter)596 mlan_status mlan_unregister(t_void *padapter)
597 {
598 	mlan_status ret = MLAN_STATUS_SUCCESS;
599 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
600 	pmlan_callbacks pcb;
601 	t_s32 i = 0;
602 
603 	MASSERT(padapter);
604 
605 	ENTER();
606 
607 	pcb = &pmadapter->callbacks;
608 
609 	/* Free adapter structure */
610 	wlan_free_adapter(pmadapter);
611 
612 	/* Free private structures */
613 	for (i = 0; i < pmadapter->priv_num; i++) {
614 		if (pmadapter->priv[i]) {
615 			if (pcb->moal_vmalloc && pcb->moal_vfree)
616 				pcb->moal_vfree(pmadapter->pmoal_handle,
617 						(t_u8 *)pmadapter->priv[i]);
618 			else if (pcb->moal_mfree)
619 				pcb->moal_mfree(pmadapter->pmoal_handle,
620 						(t_u8 *)pmadapter->priv[i]);
621 		}
622 	}
623 
624 	/* Free mlan_adapter */
625 	if (pcb->moal_vmalloc && pcb->moal_vfree)
626 		pcb->moal_vfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter);
627 	else if (pcb->moal_mfree)
628 		pcb->moal_mfree(pmadapter->pmoal_handle, (t_u8 *)pmadapter);
629 
630 	LEAVE();
631 	return ret;
632 }
633 
634 /**
635  *  @brief This function downloads the firmware
636  *
637  *  @param padapter   A pointer to a t_void pointer to store
638  *                         mlan_adapter structure pointer
639  *  @param pmfw            A pointer to firmware image
640  *
641  *  @return                MLAN_STATUS_SUCCESS
642  *                             The firmware download succeeded.
643  *                         MLAN_STATUS_FAILURE
644  *                             The firmware download failed.
645  */
mlan_dnld_fw(t_void * padapter,pmlan_fw_image pmfw)646 mlan_status mlan_dnld_fw(t_void *padapter, pmlan_fw_image pmfw)
647 {
648 	mlan_status ret = MLAN_STATUS_FAILURE;
649 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
650 
651 	ENTER();
652 	MASSERT(padapter);
653 
654 	/* Download helper/firmware */
655 	if (pmfw) {
656 		ret = pmadapter->ops.dnld_fw(pmadapter, pmfw);
657 		if (ret != MLAN_STATUS_SUCCESS) {
658 			PRINTM(MERROR, "wlan_dnld_fw fail ret=0x%x\n", ret);
659 			LEAVE();
660 			return ret;
661 		}
662 	}
663 
664 	LEAVE();
665 	return ret;
666 }
667 
668 /**
669  *  @brief This function mask host interrupt from firmware
670  *
671  *  @param padapter   A pointer to a t_void pointer to store
672  *                         mlan_adapter structure pointer
673  *
674  *  @return                MLAN_STATUS_SUCCESS
675  *                             The firmware download succeeded.
676  *                         MLAN_STATUS_FAILURE
677  *                             The firmware download failed.
678  */
mlan_disable_host_int(t_void * padapter)679 mlan_status mlan_disable_host_int(t_void *padapter)
680 {
681 	mlan_status ret = MLAN_STATUS_FAILURE;
682 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
683 
684 	ENTER();
685 	MASSERT(padapter);
686 
687 	/* mask host interrupt from firmware */
688 	if (pmadapter->ops.disable_host_int) {
689 		ret = pmadapter->ops.disable_host_int(pmadapter);
690 		if (ret != MLAN_STATUS_SUCCESS) {
691 			PRINTM(MERROR,
692 			       "mlan_disable_host_int fail ret = 0x%x\n", ret);
693 			LEAVE();
694 			return ret;
695 		}
696 	}
697 
698 	LEAVE();
699 	return ret;
700 }
701 
702 /**
703  *  @brief This function unmask host interrupt from firmware
704  *
705  *  @param padapter   A pointer to a t_void pointer to store
706  *                         mlan_adapter structure pointer
707  *
708  *  @return                MLAN_STATUS_SUCCESS
709  *                             The firmware download succeeded.
710  *                         MLAN_STATUS_FAILURE
711  *                             The firmware download failed.
712  */
mlan_enable_host_int(t_void * padapter)713 mlan_status mlan_enable_host_int(t_void *padapter)
714 {
715 	mlan_status ret = MLAN_STATUS_FAILURE;
716 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
717 
718 	ENTER();
719 	MASSERT(padapter);
720 
721 	/* unmask host interrupt from firmware */
722 	if (pmadapter->ops.enable_host_int) {
723 		ret = pmadapter->ops.enable_host_int(pmadapter);
724 		if (ret != MLAN_STATUS_SUCCESS) {
725 			PRINTM(MERROR, "mlan_enable_host_int fail ret = 0x%x\n",
726 			       ret);
727 			LEAVE();
728 			return ret;
729 		}
730 	}
731 
732 	LEAVE();
733 	return ret;
734 }
735 
736 /**
737  *  @brief This function pass init param to MLAN
738  *
739  *  @param padapter  A pointer to a t_void pointer to store
740  *                        mlan_adapter structure pointer
741  *  @param pparam         A pointer to mlan_init_param structure
742  *
743  *  @return               MLAN_STATUS_SUCCESS
744  *
745  */
mlan_set_init_param(t_void * padapter,pmlan_init_param pparam)746 mlan_status mlan_set_init_param(t_void *padapter, pmlan_init_param pparam)
747 {
748 	mlan_status ret = MLAN_STATUS_SUCCESS;
749 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
750 
751 	ENTER();
752 	MASSERT(padapter);
753 
754 	/** Save DPD data in MLAN */
755 	if ((pparam->pdpd_data_buf) || (pparam->dpd_data_len > 0)) {
756 		pmadapter->pdpd_data = pparam->pdpd_data_buf;
757 		pmadapter->dpd_data_len = pparam->dpd_data_len;
758 	}
759 	if (pparam->ptxpwr_data_buf && (pparam->txpwr_data_len > 0)) {
760 		pmadapter->ptxpwr_data = pparam->ptxpwr_data_buf;
761 		pmadapter->txpwr_data_len = pparam->txpwr_data_len;
762 	}
763 	/** Save cal data in MLAN */
764 	if ((pparam->pcal_data_buf) && (pparam->cal_data_len > 0)) {
765 		pmadapter->pcal_data = pparam->pcal_data_buf;
766 		pmadapter->cal_data_len = pparam->cal_data_len;
767 	}
768 
769 	LEAVE();
770 	return ret;
771 }
772 
773 /**
774  *  @brief This function initializes the firmware
775  *
776  *  @param padapter   A pointer to a t_void pointer to store
777  *                         mlan_adapter structure pointer
778  *
779  *  @return                MLAN_STATUS_SUCCESS
780  *                             The firmware initialization succeeded.
781  *                         MLAN_STATUS_PENDING
782  *                             The firmware initialization is pending.
783  *                         MLAN_STATUS_FAILURE
784  *                             The firmware initialization failed.
785  */
mlan_init_fw(t_void * padapter)786 mlan_status mlan_init_fw(t_void *padapter)
787 {
788 	mlan_status ret = MLAN_STATUS_SUCCESS;
789 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
790 
791 	ENTER();
792 	MASSERT(padapter);
793 
794 	pmadapter->hw_status = WlanHardwareStatusGetHwSpec;
795 
796 	/* Initialize firmware, may return PENDING */
797 	ret = wlan_init_fw(pmadapter);
798 	PRINTM(MINFO, "wlan_init_fw returned ret=0x%x\n", ret);
799 
800 	LEAVE();
801 	return ret;
802 }
803 
804 /**
805  *  @brief Shutdown firmware
806  *
807  *  @param padapter    A pointer to mlan_adapter structure
808  *
809  *  @return     MLAN_STATUS_SUCCESS
810  *                              The firmware shutdown call succeeded.
811  *              MLAN_STATUS_PENDING
812  *                              The firmware shutdown call is pending.
813  *              MLAN_STATUS_FAILURE
814  *                              The firmware shutdown call failed.
815  */
mlan_shutdown_fw(t_void * padapter)816 mlan_status mlan_shutdown_fw(t_void *padapter)
817 {
818 	mlan_status ret = MLAN_STATUS_PENDING;
819 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
820 	pmlan_buffer pmbuf;
821 	pmlan_ioctl_req pioctl_buf;
822 	pmlan_callbacks pcb;
823 	t_s32 i = 0;
824 
825 	ENTER();
826 
827 	MASSERT(padapter);
828 	/* MLAN already shutdown */
829 	if (pmadapter->hw_status == WlanHardwareStatusNotReady) {
830 		LEAVE();
831 		return MLAN_STATUS_SUCCESS;
832 	}
833 
834 	pmadapter->hw_status = WlanHardwareStatusClosing;
835 	/* Wait for mlan_process to complete */
836 	if (pmadapter->mlan_processing) {
837 		PRINTM(MWARN, "MLAN main processing is still running\n");
838 		LEAVE();
839 		return ret;
840 	}
841 
842 	/* Shut down MLAN */
843 	PRINTM(MINFO, "Shutdown MLAN...\n");
844 
845 	/* Cancel all pending commands and complete ioctls */
846 	wlan_cancel_all_pending_cmd(pmadapter, MTRUE);
847 
848 	/* Clean up priv structures */
849 	for (i = 0; i < pmadapter->priv_num; i++) {
850 		if (pmadapter->priv[i])
851 			wlan_free_priv(pmadapter->priv[i]);
852 	}
853 
854 	pcb = &pmadapter->callbacks;
855 	/** cancel pending ioctl */
856 	while ((pioctl_buf = (pmlan_ioctl_req)util_dequeue_list(
857 			pmadapter->pmoal_handle, &pmadapter->ioctl_pending_q,
858 			pcb->moal_spin_lock, pcb->moal_spin_unlock))) {
859 		pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
860 		pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
861 					 MLAN_STATUS_FAILURE);
862 	}
863 
864 	while ((pmbuf = (pmlan_buffer)util_dequeue_list(
865 			pmadapter->pmoal_handle, &pmadapter->rx_data_queue,
866 			pcb->moal_spin_lock, pcb->moal_spin_unlock))) {
867 #ifdef USB
868 		if (IS_USB(pmadapter->card_type))
869 			pcb->moal_recv_complete(pmadapter->pmoal_handle, pmbuf,
870 						pmadapter->rx_data_ep,
871 						MLAN_STATUS_FAILURE);
872 #endif
873 #if defined(SDIO) || defined(PCIE)
874 		if (!IS_USB(pmadapter->card_type))
875 			wlan_free_mlan_buffer(pmadapter, pmbuf);
876 #endif
877 	}
878 	pmadapter->rx_pkts_queued = 0;
879 #ifdef PCIE
880 	if (IS_PCIE(pmadapter->card_type) &&
881 	    wlan_set_drv_ready_reg(pmadapter, 0)) {
882 		PRINTM(MERROR, "Failed to write driver not-ready signature\n");
883 	}
884 #endif
885 
886 	/* Notify completion */
887 	ret = wlan_shutdown_fw_complete(pmadapter);
888 
889 	LEAVE();
890 	return ret;
891 }
892 
893 /**
894  *  @brief queue main work
895  *
896  *  @param pmadapter	A pointer to mlan_adapter structure
897  *
898  *  @return			N/A
899  */
mlan_queue_main_work(mlan_adapter * pmadapter)900 static t_void mlan_queue_main_work(mlan_adapter *pmadapter)
901 {
902 	pmlan_callbacks pcb = &pmadapter->callbacks;
903 	ENTER();
904 	pcb->moal_spin_lock(pmadapter->pmoal_handle,
905 			    pmadapter->pmain_proc_lock);
906 
907 	/* Check if already processing */
908 	if (pmadapter->mlan_processing) {
909 		pmadapter->more_task_flag = MTRUE;
910 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
911 				      pmadapter->pmain_proc_lock);
912 	} else {
913 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
914 				      pmadapter->pmain_proc_lock);
915 		wlan_recv_event(wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY),
916 				MLAN_EVENT_ID_DRV_DEFER_HANDLING, MNULL);
917 	}
918 	LEAVE();
919 	return;
920 }
921 
922 /**
923  *  @brief queue rx_work
924  *
925  *  @param pmadapter	A pointer to mlan_adapter structure
926  *
927  *  @return			N/A
928  */
mlan_queue_rx_work(mlan_adapter * pmadapter)929 static t_void mlan_queue_rx_work(mlan_adapter *pmadapter)
930 {
931 	pmlan_callbacks pcb = &pmadapter->callbacks;
932 	ENTER();
933 
934 	pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock);
935 
936 	/* Check if already processing */
937 	if (pmadapter->mlan_rx_processing) {
938 		pmadapter->more_rx_task_flag = MTRUE;
939 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
940 				      pmadapter->prx_proc_lock);
941 	} else {
942 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
943 				      pmadapter->prx_proc_lock);
944 		wlan_recv_event(wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY),
945 				MLAN_EVENT_ID_DRV_DEFER_RX_WORK, MNULL);
946 	}
947 	LEAVE();
948 	return;
949 }
950 
951 /**
952  *  @brief block main process
953  *
954  *  @param pmadapter	A pointer to mlan_adapter structure
955  *  @param block            MTRUE/MFALSE
956  *
957  *  @return			N/A
958  */
mlan_block_main_process(mlan_adapter * pmadapter,t_u8 block)959 void mlan_block_main_process(mlan_adapter *pmadapter, t_u8 block)
960 {
961 	pmlan_callbacks pcb = &pmadapter->callbacks;
962 	pcb->moal_spin_lock(pmadapter->pmoal_handle,
963 			    pmadapter->pmain_proc_lock);
964 	if (!block) {
965 		pmadapter->main_lock_flag = MFALSE;
966 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
967 				      pmadapter->pmain_proc_lock);
968 	} else {
969 		pmadapter->main_lock_flag = MTRUE;
970 		if (pmadapter->mlan_processing) {
971 			pcb->moal_spin_unlock(pmadapter->pmoal_handle,
972 					      pmadapter->pmain_proc_lock);
973 			PRINTM(MEVENT, "wlan: wait main work done...\n");
974 			wlan_recv_event(
975 				wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY),
976 				MLAN_EVENT_ID_DRV_FLUSH_MAIN_WORK, MNULL);
977 		} else {
978 			pcb->moal_spin_unlock(pmadapter->pmoal_handle,
979 					      pmadapter->pmain_proc_lock);
980 		}
981 	}
982 }
983 
984 /**
985  *  @brief block rx process
986  *
987  *  @param pmadapter	A pointer to mlan_adapter structure
988  *  @param block            MTRUE/MFALSE;
989  *
990  *  @return			N/A
991  */
mlan_block_rx_process(mlan_adapter * pmadapter,t_u8 block)992 void mlan_block_rx_process(mlan_adapter *pmadapter, t_u8 block)
993 {
994 	pmlan_callbacks pcb = &pmadapter->callbacks;
995 	pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock);
996 	if (!block) {
997 		pmadapter->rx_lock_flag = MFALSE;
998 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
999 				      pmadapter->prx_proc_lock);
1000 	} else {
1001 		pmadapter->rx_lock_flag = MTRUE;
1002 		if (pmadapter->mlan_rx_processing) {
1003 			pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1004 					      pmadapter->prx_proc_lock);
1005 			PRINTM(MEVENT, "wlan: wait rx work done...\n");
1006 			wlan_recv_event(wlan_get_priv(pmadapter,
1007 						      MLAN_BSS_ROLE_ANY),
1008 					MLAN_EVENT_ID_DRV_FLUSH_RX_WORK, MNULL);
1009 		} else {
1010 			pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1011 					      pmadapter->prx_proc_lock);
1012 		}
1013 	}
1014 }
1015 
1016 /**
1017  *  @brief The receive process
1018  *
1019  *  @param padapter	A pointer to mlan_adapter structure
1020  *  @param rx_pkts              A pointer to save receive pkts number
1021  *
1022  *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1023  */
mlan_rx_process(t_void * padapter,t_u8 * rx_pkts)1024 mlan_status mlan_rx_process(t_void *padapter, t_u8 *rx_pkts)
1025 {
1026 	mlan_status ret = MLAN_STATUS_SUCCESS;
1027 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1028 	pmlan_callbacks pcb;
1029 	pmlan_buffer pmbuf;
1030 	t_u8 limit = 0;
1031 	t_u8 rx_num = 0;
1032 	t_u32 in_ts_sec, in_ts_usec;
1033 
1034 	ENTER();
1035 
1036 	MASSERT(padapter);
1037 	pcb = &pmadapter->callbacks;
1038 	pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock);
1039 	if (pmadapter->mlan_rx_processing || pmadapter->rx_lock_flag) {
1040 		pmadapter->more_rx_task_flag = MTRUE;
1041 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1042 				      pmadapter->prx_proc_lock);
1043 		goto exit_rx_proc;
1044 	} else {
1045 		pmadapter->mlan_rx_processing = MTRUE;
1046 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1047 				      pmadapter->prx_proc_lock);
1048 	}
1049 	if (rx_pkts)
1050 		limit = *rx_pkts;
1051 
1052 rx_process_start:
1053 	/* Check for Rx data */
1054 	while (MTRUE) {
1055 #ifdef DRV_EMBEDDED_AUTHENTICATOR
1056 		if (pmadapter->authenticator_priv) {
1057 			if (IsAuthenticatorEnabled(
1058 				    pmadapter->authenticator_priv->psapriv)) {
1059 				AuthenticatorKeyMgmtInit(
1060 					pmadapter->authenticator_priv->psapriv,
1061 					pmadapter->authenticator_priv
1062 						->curr_addr);
1063 				pmadapter->authenticator_priv = MNULL;
1064 			}
1065 		}
1066 #endif
1067 		if (pmadapter->flush_data) {
1068 			pmadapter->flush_data = MFALSE;
1069 			wlan_flush_rxreorder_tbl(pmadapter);
1070 		}
1071 		pmadapter->callbacks.moal_spin_lock(
1072 			pmadapter->pmoal_handle,
1073 			pmadapter->rx_data_queue.plock);
1074 		pmbuf = (pmlan_buffer)util_dequeue_list(
1075 			pmadapter->pmoal_handle, &pmadapter->rx_data_queue,
1076 			MNULL, MNULL);
1077 		if (!pmbuf) {
1078 			pmadapter->callbacks.moal_spin_unlock(
1079 				pmadapter->pmoal_handle,
1080 				pmadapter->rx_data_queue.plock);
1081 			break;
1082 		}
1083 		pmadapter->rx_pkts_queued--;
1084 		rx_num++;
1085 		pmadapter->callbacks.moal_spin_unlock(
1086 			pmadapter->pmoal_handle,
1087 			pmadapter->rx_data_queue.plock);
1088 
1089 		// rx_trace 6
1090 		if (pmadapter->tp_state_on) {
1091 			pmadapter->callbacks.moal_tp_accounting(
1092 				pmadapter->pmoal_handle, pmbuf,
1093 				6 /*RX_DROP_P2*/);
1094 			pcb->moal_get_system_time(pmadapter->pmoal_handle,
1095 						  &in_ts_sec, &in_ts_usec);
1096 			pmbuf->extra_ts_sec = in_ts_sec;
1097 			pmbuf->extra_ts_usec = in_ts_usec;
1098 		}
1099 		if (pmadapter->tp_state_drop_point == 6 /*RX_DROP_P2*/) {
1100 			pmadapter->ops.data_complete(pmadapter, pmbuf, ret);
1101 			goto rx_process_start;
1102 		}
1103 
1104 		if (pmadapter->delay_task_flag &&
1105 		    (pmadapter->rx_pkts_queued < LOW_RX_PENDING)) {
1106 			PRINTM(MEVENT, "Run\n");
1107 			pmadapter->delay_task_flag = MFALSE;
1108 			mlan_queue_main_work(pmadapter);
1109 		}
1110 		pmadapter->ops.handle_rx_packet(pmadapter, pmbuf);
1111 		if (limit && rx_num >= limit)
1112 			break;
1113 	}
1114 	if (rx_pkts)
1115 		*rx_pkts = rx_num;
1116 	pcb->moal_spin_lock(pmadapter->pmoal_handle, pmadapter->prx_proc_lock);
1117 	if (pmadapter->more_rx_task_flag) {
1118 		pmadapter->more_rx_task_flag = MFALSE;
1119 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1120 				      pmadapter->prx_proc_lock);
1121 		goto rx_process_start;
1122 	}
1123 	pmadapter->mlan_rx_processing = MFALSE;
1124 	pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1125 			      pmadapter->prx_proc_lock);
1126 exit_rx_proc:
1127 	LEAVE();
1128 	return ret;
1129 }
1130 
1131 /**
1132  *  @brief The main process
1133  *
1134  *  @param padapter	A pointer to mlan_adapter structure
1135  *
1136  *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1137  */
mlan_main_process(t_void * padapter)1138 mlan_status mlan_main_process(t_void *padapter)
1139 {
1140 	mlan_status ret = MLAN_STATUS_SUCCESS;
1141 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1142 	pmlan_callbacks pcb;
1143 
1144 	ENTER();
1145 
1146 	MASSERT(padapter);
1147 
1148 	pcb = &pmadapter->callbacks;
1149 
1150 	pcb->moal_spin_lock(pmadapter->pmoal_handle,
1151 			    pmadapter->pmain_proc_lock);
1152 
1153 	/* Check if already processing */
1154 	if (pmadapter->mlan_processing || pmadapter->main_lock_flag) {
1155 		pmadapter->more_task_flag = MTRUE;
1156 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1157 				      pmadapter->pmain_proc_lock);
1158 		goto exit_main_proc;
1159 	} else {
1160 		pmadapter->mlan_processing = MTRUE;
1161 		pmadapter->main_process_cnt++;
1162 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1163 				      pmadapter->pmain_proc_lock);
1164 	}
1165 process_start:
1166 	do {
1167 		/* Is MLAN shutting down or not ready? */
1168 		if ((pmadapter->hw_status == WlanHardwareStatusClosing) ||
1169 		    (pmadapter->hw_status == WlanHardwareStatusNotReady))
1170 			break;
1171 		if (pmadapter->pending_ioctl) {
1172 			wlan_process_pending_ioctl(pmadapter);
1173 			pmadapter->pending_ioctl = MFALSE;
1174 		}
1175 		if (pmadapter->pending_disconnect_priv) {
1176 			PRINTM(MEVENT, "Reset connect state\n");
1177 			wlan_reset_connect_state(
1178 				pmadapter->pending_disconnect_priv, MTRUE);
1179 			pmadapter->pending_disconnect_priv = MNULL;
1180 		}
1181 #if defined(SDIO) || defined(PCIE)
1182 		if (!IS_USB(pmadapter->card_type)) {
1183 			if (pmadapter->rx_pkts_queued > HIGH_RX_PENDING) {
1184 				pcb->moal_tp_accounting_rx_param(
1185 					pmadapter->pmoal_handle, 2, 0);
1186 				PRINTM(MEVENT, "Pause\n");
1187 				pmadapter->delay_task_flag = MTRUE;
1188 				mlan_queue_rx_work(pmadapter);
1189 				break;
1190 			}
1191 			/* Handle pending interrupts if any */
1192 			if (pmadapter->ireg) {
1193 				if (pmadapter->hs_activated == MTRUE)
1194 					wlan_process_hs_config(pmadapter);
1195 				pmadapter->ops.process_int_status(pmadapter);
1196 				if (pmadapter->data_received)
1197 					mlan_queue_rx_work(pmadapter);
1198 			}
1199 		}
1200 #endif
1201 
1202 		/* Need to wake up the card ? */
1203 		if ((pmadapter->ps_state == PS_STATE_SLEEP) &&
1204 		    (pmadapter->pm_wakeup_card_req &&
1205 		     !pmadapter->pm_wakeup_fw_try) &&
1206 		    (wlan_is_cmd_pending(pmadapter) ||
1207 		     !wlan_bypass_tx_list_empty(pmadapter) ||
1208 		     !wlan_wmm_lists_empty(pmadapter))) {
1209 			pmadapter->ops.wakeup_card(pmadapter, MTRUE);
1210 			pmadapter->pm_wakeup_fw_try = MTRUE;
1211 			continue;
1212 		}
1213 		if (IS_CARD_RX_RCVD(pmadapter) ||
1214 		    (!pmadapter->cmd_sent &&
1215 		     pmadapter->vdll_ctrl.pending_block)) {
1216 			pmadapter->data_received = MFALSE;
1217 			if (pmadapter->hs_activated == MTRUE) {
1218 				pmadapter->is_hs_configured = MFALSE;
1219 				wlan_host_sleep_activated_event(
1220 					wlan_get_priv(pmadapter,
1221 						      MLAN_BSS_ROLE_ANY),
1222 					MFALSE);
1223 			}
1224 			pmadapter->pm_wakeup_fw_try = MFALSE;
1225 			if (pmadapter->ps_state == PS_STATE_SLEEP)
1226 				pmadapter->ps_state = PS_STATE_AWAKE;
1227 			if (pmadapter->wakeup_fw_timer_is_set) {
1228 				pcb->moal_stop_timer(
1229 					pmadapter->pmoal_handle,
1230 					pmadapter->pwakeup_fw_timer);
1231 				pmadapter->wakeup_fw_timer_is_set = MFALSE;
1232 			}
1233 		} else {
1234 			/* We have tried to wakeup the card already */
1235 			if (pmadapter->pm_wakeup_fw_try)
1236 				break;
1237 			/* Check if we need to confirm Sleep Request received
1238 			 * previously */
1239 			if (pmadapter->ps_state == PS_STATE_PRE_SLEEP)
1240 				if (!pmadapter->cmd_sent &&
1241 				    !pmadapter->curr_cmd &&
1242 				    !pmadapter->vdll_ctrl.pending_block)
1243 					wlan_check_ps_cond(pmadapter);
1244 			if (pmadapter->ps_state != PS_STATE_AWAKE ||
1245 			    (pmadapter->tx_lock_flag == MTRUE))
1246 				break;
1247 
1248 			if (pmadapter->data_sent ||
1249 			    wlan_is_tdls_link_chan_switching(
1250 				    pmadapter->tdls_status) ||
1251 			    (wlan_bypass_tx_list_empty(pmadapter) &&
1252 			     wlan_wmm_lists_empty(pmadapter)) ||
1253 			    wlan_11h_radar_detected_tx_blocked(pmadapter)) {
1254 				if (pmadapter->cmd_sent ||
1255 				    pmadapter->curr_cmd ||
1256 				    !wlan_is_send_cmd_allowed(
1257 					    pmadapter->tdls_status) ||
1258 				    !wlan_is_cmd_pending(pmadapter)) {
1259 					break;
1260 				}
1261 			}
1262 		}
1263 
1264 		/* Check for Cmd Resp */
1265 		wlan_request_cmd_lock(pmadapter);
1266 		if (pmadapter->cmd_resp_received) {
1267 			pmadapter->cmd_resp_received = MFALSE;
1268 			wlan_release_cmd_lock(pmadapter);
1269 
1270 			wlan_process_cmdresp(pmadapter);
1271 
1272 			/* call moal back when init_fw is done */
1273 			if (pmadapter->hw_status ==
1274 			    WlanHardwareStatusInitdone) {
1275 				pmadapter->hw_status = WlanHardwareStatusReady;
1276 				wlan_init_fw_complete(pmadapter);
1277 			} else if (pmadapter->hw_status ==
1278 				   WlanHardwareStatusGetHwSpecdone) {
1279 				pmadapter->hw_status =
1280 					WlanHardwareStatusInitializing;
1281 				wlan_get_hw_spec_complete(pmadapter);
1282 			}
1283 		} else {
1284 			wlan_release_cmd_lock(pmadapter);
1285 		}
1286 
1287 		/* Check for event */
1288 		if (pmadapter->event_received) {
1289 			pmadapter->event_received = MFALSE;
1290 			wlan_process_event(pmadapter);
1291 		}
1292 
1293 		/* Check if we need to confirm Sleep Request received previously
1294 		 */
1295 		if (pmadapter->ps_state == PS_STATE_PRE_SLEEP)
1296 			if (!pmadapter->cmd_sent && !pmadapter->curr_cmd &&
1297 			    !pmadapter->vdll_ctrl.pending_block)
1298 				wlan_check_ps_cond(pmadapter);
1299 
1300 		/*
1301 		 * The ps_state may have been changed during processing of
1302 		 * Sleep Request event.
1303 		 */
1304 		if ((pmadapter->ps_state == PS_STATE_SLEEP) ||
1305 		    (pmadapter->ps_state == PS_STATE_PRE_SLEEP) ||
1306 		    (pmadapter->ps_state == PS_STATE_SLEEP_CFM) ||
1307 		    (pmadapter->tx_lock_flag == MTRUE)) {
1308 			continue;
1309 		}
1310 
1311 		/* in a case of race condition, download the VDLL block here */
1312 		if (!pmadapter->cmd_sent &&
1313 		    pmadapter->vdll_ctrl.pending_block) {
1314 			wlan_download_vdll_block(
1315 				pmadapter, pmadapter->vdll_ctrl.pending_block,
1316 				pmadapter->vdll_ctrl.pending_block_len);
1317 			pmadapter->vdll_ctrl.pending_block = MNULL;
1318 		}
1319 		if (!pmadapter->cmd_sent && !pmadapter->curr_cmd &&
1320 		    wlan_is_send_cmd_allowed(pmadapter->tdls_status)) {
1321 			if (wlan_exec_next_cmd(pmadapter) ==
1322 			    MLAN_STATUS_FAILURE) {
1323 				ret = MLAN_STATUS_FAILURE;
1324 				break;
1325 			}
1326 		}
1327 
1328 		if (!pmadapter->data_sent &&
1329 		    !wlan_11h_radar_detected_tx_blocked(pmadapter) &&
1330 		    !wlan_is_tdls_link_chan_switching(pmadapter->tdls_status) &&
1331 		    !wlan_bypass_tx_list_empty(pmadapter)) {
1332 			PRINTM(MINFO, "mlan_send_pkt(): deq(bybass_txq)\n");
1333 			wlan_process_bypass_tx(pmadapter);
1334 			if (pmadapter->hs_activated == MTRUE) {
1335 				pmadapter->is_hs_configured = MFALSE;
1336 				wlan_host_sleep_activated_event(
1337 					wlan_get_priv(pmadapter,
1338 						      MLAN_BSS_ROLE_ANY),
1339 					MFALSE);
1340 			}
1341 		}
1342 
1343 		if (!pmadapter->data_sent && !wlan_wmm_lists_empty(pmadapter) &&
1344 		    !wlan_11h_radar_detected_tx_blocked(pmadapter) &&
1345 		    !wlan_is_tdls_link_chan_switching(pmadapter->tdls_status)) {
1346 			wlan_wmm_process_tx(pmadapter);
1347 			if (pmadapter->hs_activated == MTRUE) {
1348 				pmadapter->is_hs_configured = MFALSE;
1349 				wlan_host_sleep_activated_event(
1350 					wlan_get_priv(pmadapter,
1351 						      MLAN_BSS_ROLE_ANY),
1352 					MFALSE);
1353 			}
1354 		}
1355 
1356 #ifdef STA_SUPPORT
1357 		if (pmadapter->delay_null_pkt && !pmadapter->cmd_sent &&
1358 		    !pmadapter->curr_cmd && !wlan_is_cmd_pending(pmadapter) &&
1359 		    wlan_bypass_tx_list_empty(pmadapter) &&
1360 		    wlan_wmm_lists_empty(pmadapter)) {
1361 			if (wlan_send_null_packet(
1362 				    wlan_get_priv(pmadapter, MLAN_BSS_ROLE_STA),
1363 				    MRVDRV_TxPD_POWER_MGMT_NULL_PACKET |
1364 					    MRVDRV_TxPD_POWER_MGMT_LAST_PACKET) ==
1365 			    MLAN_STATUS_SUCCESS) {
1366 				pmadapter->delay_null_pkt = MFALSE;
1367 			}
1368 			break;
1369 		}
1370 #endif
1371 
1372 	} while (MTRUE);
1373 
1374 	pcb->moal_spin_lock(pmadapter->pmoal_handle,
1375 			    pmadapter->pmain_proc_lock);
1376 	if (pmadapter->more_task_flag == MTRUE) {
1377 		pmadapter->more_task_flag = MFALSE;
1378 		pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1379 				      pmadapter->pmain_proc_lock);
1380 		goto process_start;
1381 	}
1382 	pmadapter->mlan_processing = MFALSE;
1383 	pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1384 			      pmadapter->pmain_proc_lock);
1385 
1386 exit_main_proc:
1387 	if (pmadapter->hw_status == WlanHardwareStatusClosing)
1388 		mlan_shutdown_fw(pmadapter);
1389 	LEAVE();
1390 	return ret;
1391 }
1392 
1393 /**
1394  *  @brief Function to send packet
1395  *
1396  *  @param padapter	A pointer to mlan_adapter structure
1397  *  @param pmbuf		A pointer to mlan_buffer structure
1398  *
1399  *  @return			MLAN_STATUS_PENDING
1400  */
mlan_send_packet(t_void * padapter,pmlan_buffer pmbuf)1401 mlan_status mlan_send_packet(t_void *padapter, pmlan_buffer pmbuf)
1402 {
1403 	mlan_status ret = MLAN_STATUS_PENDING;
1404 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1405 	mlan_private *pmpriv;
1406 	t_u16 eth_type = 0;
1407 	t_u8 ra[MLAN_MAC_ADDR_LENGTH];
1408 	tdlsStatus_e tdls_status;
1409 
1410 	ENTER();
1411 	MASSERT(padapter && pmbuf);
1412 
1413 	if (!padapter || !pmbuf) {
1414 		return MLAN_STATUS_FAILURE;
1415 	}
1416 
1417 	MASSERT(pmbuf->bss_index < pmadapter->priv_num);
1418 	pmbuf->flags |= MLAN_BUF_FLAG_MOAL_TX_BUF;
1419 	pmpriv = pmadapter->priv[pmbuf->bss_index];
1420 
1421 	eth_type =
1422 		mlan_ntohs(*(t_u16 *)&pmbuf->pbuf[pmbuf->data_offset +
1423 						  MLAN_ETHER_PKT_TYPE_OFFSET]);
1424 	if (((pmadapter->priv[pmbuf->bss_index]->port_ctrl_mode == MTRUE) &&
1425 	     ((eth_type == MLAN_ETHER_PKT_TYPE_EAPOL) ||
1426 	      (eth_type == MLAN_ETHER_PKT_TYPE_ARP) ||
1427 	      (eth_type == MLAN_ETHER_PKT_TYPE_WAPI))) ||
1428 	    (eth_type == MLAN_ETHER_PKT_TYPE_TDLS_ACTION) ||
1429 	    (pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA)
1430 
1431 	) {
1432 		if (eth_type == MLAN_ETHER_PKT_TYPE_TDLS_ACTION) {
1433 			memcpy_ext(pmadapter, ra,
1434 				   pmbuf->pbuf + pmbuf->data_offset,
1435 				   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
1436 			tdls_status = wlan_get_tdls_link_status(pmpriv, ra);
1437 			if (MTRUE == wlan_is_tdls_link_setup(tdls_status) ||
1438 			    !pmpriv->media_connected)
1439 				pmbuf->flags |= MLAN_BUF_FLAG_TDLS;
1440 		}
1441 		if (eth_type == MLAN_ETHER_PKT_TYPE_EAPOL) {
1442 			PRINTM_NETINTF(MMSG, pmpriv);
1443 			PRINTM(MMSG, "wlan: Send EAPOL pkt to " MACSTR "\n",
1444 			       MAC2STR(pmbuf->pbuf + pmbuf->data_offset));
1445 		}
1446 		if (pmadapter->tp_state_on)
1447 			pmadapter->callbacks.moal_tp_accounting(
1448 				pmadapter->pmoal_handle, pmbuf->pdesc, 2);
1449 		if (pmadapter->tp_state_drop_point == 2)
1450 			return 0;
1451 		else
1452 			wlan_add_buf_bypass_txqueue(pmadapter, pmbuf);
1453 	} else {
1454 		if (pmadapter->tp_state_on)
1455 			pmadapter->callbacks.moal_tp_accounting(
1456 				pmadapter->pmoal_handle, pmbuf->pdesc, 2);
1457 		if (pmadapter->tp_state_drop_point == 2)
1458 			return 0;
1459 		else
1460 			/* Transmit the packet*/
1461 			wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
1462 	}
1463 
1464 	LEAVE();
1465 	return ret;
1466 }
1467 
1468 /**
1469  *  @brief MLAN ioctl handler
1470  *
1471  *  @param adapter	A pointer to mlan_adapter structure
1472  *  @param pioctl_req	A pointer to ioctl request buffer
1473  *
1474  *  @return		MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING --success,
1475  * otherwise fail
1476  */
mlan_ioctl(t_void * adapter,pmlan_ioctl_req pioctl_req)1477 mlan_status mlan_ioctl(t_void *adapter, pmlan_ioctl_req pioctl_req)
1478 {
1479 	mlan_status ret = MLAN_STATUS_SUCCESS;
1480 	pmlan_adapter pmadapter = (pmlan_adapter)adapter;
1481 	pmlan_private pmpriv = MNULL;
1482 
1483 	ENTER();
1484 
1485 	if (pioctl_req == MNULL) {
1486 		PRINTM(MMSG, "Cancel all pending cmd!\n");
1487 		wlan_cancel_all_pending_cmd(pmadapter, MFALSE);
1488 		goto exit;
1489 	}
1490 	if (pioctl_req->action == MLAN_ACT_CANCEL) {
1491 		wlan_cancel_pending_ioctl(pmadapter, pioctl_req);
1492 		ret = MLAN_STATUS_SUCCESS;
1493 		goto exit;
1494 	}
1495 	pmpriv = pmadapter->priv[pioctl_req->bss_index];
1496 	ret = pmpriv->ops.ioctl(adapter, pioctl_req);
1497 exit:
1498 	LEAVE();
1499 	return ret;
1500 }
1501 
1502 #ifdef USB
1503 /**
1504  *  @brief Packet send completion callback
1505  *
1506  *  @param padapter	A pointer to mlan_adapter structure
1507  *  @param pmbuf		A pointer to mlan_buffer structure
1508  *  @param port			Data port
1509  *  @param status		Callback status
1510  *
1511  *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1512  */
mlan_write_data_async_complete(t_void * padapter,pmlan_buffer pmbuf,t_u32 port,mlan_status status)1513 mlan_status mlan_write_data_async_complete(t_void *padapter, pmlan_buffer pmbuf,
1514 					   t_u32 port, mlan_status status)
1515 {
1516 	mlan_status ret = MLAN_STATUS_SUCCESS;
1517 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1518 
1519 	ENTER();
1520 
1521 	if (port == pmadapter->tx_cmd_ep) {
1522 		pmadapter->cmd_sent = MFALSE;
1523 		PRINTM(MCMND, "mlan_write_data_async_complete: CMD\n");
1524 		/* pmbuf was allocated by MLAN */
1525 		wlan_free_mlan_buffer(pmadapter, pmbuf);
1526 	} else {
1527 		pmadapter->data_sent = MFALSE;
1528 		ret = wlan_write_data_complete(pmadapter, pmbuf, status);
1529 	}
1530 
1531 	LEAVE();
1532 	return ret;
1533 }
1534 
1535 /**
1536  *  @brief Packet receive handler
1537  *
1538  *  @param padapter	A pointer to mlan_adapter structure
1539  *  @param pmbuf		A pointer to mlan_buffer structure
1540  *  @param port			Data port
1541  *
1542  *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE or
1543  * MLAN_STATUS_PENDING
1544  */
mlan_recv(t_void * padapter,pmlan_buffer pmbuf,t_u32 port)1545 mlan_status mlan_recv(t_void *padapter, pmlan_buffer pmbuf, t_u32 port)
1546 {
1547 	mlan_status ret = MLAN_STATUS_PENDING;
1548 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1549 	t_u8 *pbuf;
1550 	t_u32 len, recv_type;
1551 	t_u32 event_cause;
1552 #ifdef DEBUG_LEVEL1
1553 	t_u32 sec, usec;
1554 #endif
1555 	t_u32 max_rx_data_size = MLAN_RX_DATA_BUF_SIZE;
1556 
1557 	ENTER();
1558 
1559 	MASSERT(padapter && pmbuf);
1560 
1561 	if (pmadapter->hs_activated == MTRUE)
1562 		wlan_process_hs_config(pmadapter);
1563 	pbuf = pmbuf->pbuf + pmbuf->data_offset;
1564 	len = pmbuf->data_len;
1565 
1566 	MASSERT(len >= MLAN_TYPE_LEN);
1567 	recv_type = *(t_u32 *)pbuf;
1568 	recv_type = wlan_le32_to_cpu(recv_type);
1569 	pbuf += MLAN_TYPE_LEN;
1570 	len -= MLAN_TYPE_LEN;
1571 
1572 	if (port == pmadapter->rx_cmd_ep) {
1573 		switch (recv_type) {
1574 		case MLAN_USB_TYPE_CMD:
1575 			PRINTM_GET_SYS_TIME(MCMND, &sec, &usec);
1576 			PRINTM(MCMND, "mlan_recv: CMD (%lu.%06lu)\n", sec,
1577 			       usec);
1578 			if (len > MRVDRV_SIZE_OF_CMD_BUFFER) {
1579 				pmbuf->status_code = MLAN_ERROR_CMD_RESP_FAIL;
1580 				ret = MLAN_STATUS_FAILURE;
1581 				PRINTM(MERROR, "mlan_recv: CMD too large\n");
1582 			} else if (!pmadapter->curr_cmd) {
1583 				if (pmadapter->ps_state == PS_STATE_SLEEP_CFM) {
1584 					pmbuf->data_offset += MLAN_TYPE_LEN;
1585 					pmbuf->data_len -= MLAN_TYPE_LEN;
1586 					wlan_process_sleep_confirm_resp(
1587 						pmadapter,
1588 						pmbuf->pbuf +
1589 							pmbuf->data_offset,
1590 						pmbuf->data_len);
1591 					pmbuf->flags |=
1592 						MLAN_BUF_FLAG_SLEEPCFM_RESP;
1593 					ret = MLAN_STATUS_SUCCESS;
1594 
1595 				} else {
1596 					pmbuf->status_code =
1597 						MLAN_ERROR_CMD_RESP_FAIL;
1598 					ret = MLAN_STATUS_FAILURE;
1599 				}
1600 				PRINTM(MINFO, "mlan_recv: no curr_cmd\n");
1601 			} else {
1602 				wlan_request_cmd_lock(pmadapter);
1603 				pmadapter->upld_len = len;
1604 				pmbuf->data_offset += MLAN_TYPE_LEN;
1605 				pmbuf->data_len -= MLAN_TYPE_LEN;
1606 				pmadapter->curr_cmd->respbuf = pmbuf;
1607 				pmadapter->cmd_resp_received = MTRUE;
1608 				wlan_release_cmd_lock(pmadapter);
1609 			}
1610 			break;
1611 		case MLAN_USB_TYPE_EVENT:
1612 			MASSERT(len >= sizeof(t_u32));
1613 			memmove(pmadapter, &event_cause, pbuf, sizeof(t_u32));
1614 			pmadapter->event_cause = wlan_le32_to_cpu(event_cause);
1615 			PRINTM_GET_SYS_TIME(MEVENT, &sec, &usec);
1616 			PRINTM(MEVENT, "mlan_recv: EVENT 0x%x (%lu.%06lu)\n",
1617 			       pmadapter->event_cause, sec, usec);
1618 			pbuf += sizeof(t_u32);
1619 			len -= sizeof(t_u32);
1620 			if ((len > 0) && (len < MAX_EVENT_SIZE))
1621 				memmove(pmadapter, pmadapter->event_body, pbuf,
1622 					len);
1623 			pmadapter->event_received = MTRUE;
1624 			pmadapter->pmlan_buffer_event = pmbuf;
1625 			/* remove 4 byte recv_type */
1626 			pmbuf->data_offset += MLAN_TYPE_LEN;
1627 			pmbuf->data_len -= MLAN_TYPE_LEN;
1628 			/* MOAL to call mlan_main_process for processing */
1629 			break;
1630 		default:
1631 			pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
1632 			ret = MLAN_STATUS_FAILURE;
1633 			PRINTM(MERROR, "mlan_recv: unknown recv_type 0x%x\n",
1634 			       recv_type);
1635 			break;
1636 		}
1637 	} else if (port == pmadapter->rx_data_ep) {
1638 		PRINTM_GET_SYS_TIME(MDATA, &sec, &usec);
1639 		PRINTM(MDATA, "mlan_recv: DATA (%lu.%06lu)\n", sec, usec);
1640 #if defined(USB)
1641 		if (pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl.enable) {
1642 			max_rx_data_size = pmadapter->pcard_usb->usb_rx_deaggr
1643 						   .aggr_ctrl.aggr_max;
1644 			if (pmadapter->pcard_usb->usb_rx_deaggr.aggr_ctrl
1645 				    .aggr_mode == MLAN_USB_AGGR_MODE_NUM) {
1646 				max_rx_data_size *=
1647 					MAX(MLAN_USB_MAX_PKT_SIZE,
1648 					    pmadapter->pcard_usb->usb_rx_deaggr
1649 						    .aggr_ctrl.aggr_align);
1650 				max_rx_data_size = MAX(max_rx_data_size,
1651 						       MLAN_RX_DATA_BUF_SIZE);
1652 			}
1653 		}
1654 #endif
1655 		if (len > max_rx_data_size) {
1656 			pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
1657 			ret = MLAN_STATUS_FAILURE;
1658 			PRINTM(MERROR, "mlan_recv: DATA too large\n");
1659 		} else {
1660 			pmadapter->upld_len = len;
1661 			pmadapter->callbacks.moal_get_system_time(
1662 				pmadapter->pmoal_handle, &pmbuf->in_ts_sec,
1663 				&pmbuf->in_ts_usec);
1664 			pmadapter->callbacks.moal_spin_lock(
1665 				pmadapter->pmoal_handle,
1666 				pmadapter->rx_data_queue.plock);
1667 			util_enqueue_list_tail(pmadapter->pmoal_handle,
1668 					       &pmadapter->rx_data_queue,
1669 					       (pmlan_linked_list)pmbuf, MNULL,
1670 					       MNULL);
1671 			pmadapter->rx_pkts_queued++;
1672 			pmadapter->callbacks.moal_spin_unlock(
1673 				pmadapter->pmoal_handle,
1674 				pmadapter->rx_data_queue.plock);
1675 			pmadapter->data_received = MTRUE;
1676 			mlan_queue_rx_work(pmadapter);
1677 		}
1678 	} else {
1679 		pmbuf->status_code = MLAN_ERROR_PKT_INVALID;
1680 		ret = MLAN_STATUS_FAILURE;
1681 		PRINTM(MERROR, "mlan_recv: unknown port number 0x%x\n", port);
1682 	}
1683 
1684 	LEAVE();
1685 	return ret;
1686 }
1687 #endif /* USB */
1688 
1689 /**
1690  *  @brief Packet receive completion callback handler
1691  *
1692  *  @param padapter	A pointer to mlan_adapter structure
1693  *  @param pmbuf		A pointer to mlan_buffer structure
1694  *  @param status		Callback status
1695  *
1696  *  @return			MLAN_STATUS_SUCCESS
1697  */
mlan_recv_packet_complete(t_void * padapter,pmlan_buffer pmbuf,mlan_status status)1698 mlan_status mlan_recv_packet_complete(t_void *padapter, pmlan_buffer pmbuf,
1699 				      mlan_status status)
1700 {
1701 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1702 
1703 	ENTER();
1704 	wlan_recv_packet_complete(pmadapter, pmbuf, status);
1705 	LEAVE();
1706 	return MLAN_STATUS_SUCCESS;
1707 }
1708 
1709 /**
1710  *  @brief select wmm queue
1711  *
1712  *  @param padapter	A pointer to mlan_adapter structure
1713  *  @param bss_num		BSS number
1714  *  @param tid			TID
1715  *
1716  *  @return			wmm queue priority (0 - 3)
1717  */
mlan_select_wmm_queue(t_void * padapter,t_u8 bss_num,t_u8 tid)1718 t_u8 mlan_select_wmm_queue(t_void *padapter, t_u8 bss_num, t_u8 tid)
1719 {
1720 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1721 	pmlan_private pmpriv = pmadapter->priv[bss_num];
1722 	t_u8 ret;
1723 	ENTER();
1724 	ret = wlan_wmm_select_queue(pmpriv, tid);
1725 	LEAVE();
1726 	return ret;
1727 }
1728 
1729 /**
1730  *  @brief this function handle the amsdu packet after deaggreate.
1731  *
1732  *  @param padapter	A pointer to mlan_adapter structure
1733  *  @param pmbuf    A pointer to the deaggreated buf
1734  *  @param drop	    A pointer to return the drop flag.
1735  *
1736  *  @return			N/A
1737  */
mlan_process_deaggr_pkt(t_void * padapter,pmlan_buffer pmbuf,t_u8 * drop)1738 void mlan_process_deaggr_pkt(t_void *padapter, pmlan_buffer pmbuf, t_u8 *drop)
1739 {
1740 	mlan_adapter *pmadapter = (mlan_adapter *)padapter;
1741 	mlan_private *pmpriv;
1742 	t_u16 eth_type = 0;
1743 
1744 	*drop = MFALSE;
1745 	pmpriv = pmadapter->priv[pmbuf->bss_index];
1746 	eth_type =
1747 		mlan_ntohs(*(t_u16 *)&pmbuf->pbuf[pmbuf->data_offset +
1748 						  MLAN_ETHER_PKT_TYPE_OFFSET]);
1749 	switch (eth_type) {
1750 	case MLAN_ETHER_PKT_TYPE_EAPOL:
1751 		PRINTM(MEVENT, "Recevie AMSDU EAPOL frame\n");
1752 		if (pmpriv->sec_info.ewpa_enabled) {
1753 			*drop = MTRUE;
1754 			if (MLAN_STATUS_FAILURE ==
1755 			    wlan_prepare_cmd(pmpriv,
1756 					     HostCmd_CMD_802_11_EAPOL_PKT, 0, 0,
1757 					     MNULL, pmbuf)) {
1758 				PRINTM(MERROR, "Preparing the CMD failed\n");
1759 			}
1760 			wlan_recv_event(pmpriv,
1761 					MLAN_EVENT_ID_DRV_DEFER_HANDLING,
1762 					MNULL);
1763 		}
1764 		break;
1765 	case MLAN_ETHER_PKT_TYPE_TDLS_ACTION:
1766 		PRINTM(MEVENT, "Recevie AMSDU TDLS action frame\n");
1767 		wlan_process_tdls_action_frame(pmpriv,
1768 					       pmbuf->pbuf + pmbuf->data_offset,
1769 					       pmbuf->data_len);
1770 		break;
1771 	default:
1772 		break;
1773 	}
1774 	return;
1775 }
1776 
1777 #if defined(SDIO) || defined(PCIE)
1778 /**
1779  *  @brief This function gets interrupt status.
1780  *  @param msg_id only used for PCIE
1781  */
1782 /**
1783  *  @param msg_id  A message id
1784  *  @param adapter  A pointer to mlan_adapter structure
1785  *  @return         MLAN_STATUS_FAILURE -- if the intererupt is not for us
1786  */
mlan_interrupt(t_u16 msg_id,t_void * adapter)1787 mlan_status mlan_interrupt(t_u16 msg_id, t_void *adapter)
1788 {
1789 	mlan_adapter *pmadapter = (mlan_adapter *)adapter;
1790 	mlan_status ret;
1791 
1792 	ENTER();
1793 	ret = pmadapter->ops.interrupt(msg_id, pmadapter);
1794 	LEAVE();
1795 	return ret;
1796 }
1797 #endif
1798 
1799 /**
1800  *  @brief This function wakeup firmware.
1801  *
1802  *  @param adapter  A pointer to mlan_adapter structure
1803  *  @param keep_wakeup   keep wake up flag
1804  *  @return         N/A
1805  */
mlan_pm_wakeup_card(t_void * adapter,t_u8 keep_wakeup)1806 t_void mlan_pm_wakeup_card(t_void *adapter, t_u8 keep_wakeup)
1807 {
1808 	mlan_adapter *pmadapter = (mlan_adapter *)adapter;
1809 
1810 	ENTER();
1811 	if (keep_wakeup)
1812 		pmadapter->ops.wakeup_card(pmadapter, MFALSE);
1813 	pmadapter->keep_wakeup = keep_wakeup;
1814 
1815 	LEAVE();
1816 }
1817 
1818 /**
1819  *  @brief This function check main_process status.
1820  *
1821  *  @param adapter  A pointer to mlan_adapter structure
1822  *  @return         MTRUE/MFALSE
1823  */
mlan_is_main_process_running(t_void * adapter)1824 t_u8 mlan_is_main_process_running(t_void *adapter)
1825 {
1826 	mlan_adapter *pmadapter = (mlan_adapter *)adapter;
1827 	pmlan_callbacks pcb = &pmadapter->callbacks;
1828 	t_u8 ret = MFALSE;
1829 	ENTER();
1830 	pcb->moal_spin_lock(pmadapter->pmoal_handle,
1831 			    pmadapter->pmain_proc_lock);
1832 
1833 	/* Check if already processing */
1834 	if (pmadapter->mlan_processing) {
1835 		pmadapter->more_task_flag = MTRUE;
1836 		ret = MTRUE;
1837 	}
1838 	pcb->moal_spin_unlock(pmadapter->pmoal_handle,
1839 			      pmadapter->pmain_proc_lock);
1840 	LEAVE();
1841 	return ret;
1842 }
1843 
1844 #ifdef PCIE
1845 /**
1846  *  @brief This function sets the PCIE interrupt mode.
1847  *
1848  *  @param adapter  A pointer to mlan_adapter structure
1849  *  @param int_mode PCIE interrupt type active
1850  *  @param func_num PCIE function num
1851  *  @return         N/A
1852  */
mlan_set_int_mode(t_void * adapter,t_u32 int_mode,t_u8 func_num)1853 t_void mlan_set_int_mode(t_void *adapter, t_u32 int_mode, t_u8 func_num)
1854 {
1855 	mlan_adapter *pmadapter = (mlan_adapter *)adapter;
1856 	ENTER();
1857 	pmadapter->pcard_pcie->pcie_int_mode = int_mode;
1858 	pmadapter->pcard_pcie->func_num = func_num;
1859 	LEAVE();
1860 }
1861 #endif
1862