xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlinux/moal_shim.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file moal_shim.c
2  *
3  * @brief This file contains the callback functions registered to MLAN
4  *
5  *
6  * Copyright 2008-2022 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/21/2008: initial version
26 ********************************************************/
27 
28 #include "moal_main.h"
29 #ifdef USB
30 #include "moal_usb.h"
31 #endif
32 #ifdef SDIO
33 #include "moal_sdio.h"
34 #endif
35 #ifdef PCIE
36 #include "moal_pcie.h"
37 #endif
38 #ifdef UAP_SUPPORT
39 #include "moal_uap.h"
40 #endif
41 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
42 #include "moal_cfg80211.h"
43 #include "moal_cfg80211_util.h"
44 #endif
45 #include <asm/div64.h>
46 
47 #if defined(PCIE) || defined(SDIO)
48 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70)
49 #ifdef IMX_SUPPORT
50 #include <linux/busfreq-imx.h>
51 #endif
52 #endif
53 
54 #include <linux/etherdevice.h>
55 
56 #endif /*defined(PCIE) || defined(SDIO)*/
57 
58 /********************************************************
59 		Local Variables
60 ********************************************************/
61 /** moal_lock */
62 typedef struct _moal_lock {
63 	/** Lock */
64 	spinlock_t lock;
65 	/** Flags */
66 	unsigned long flags;
67 } moal_lock;
68 
69 /********************************************************
70 		Global Variables
71 ********************************************************/
72 
73 extern int wifi_status;
74 
75 /********************************************************
76 		Local Functions
77 ********************************************************/
78 
79 /********************************************************
80 		Global Functions
81 ********************************************************/
82 /**
83  *  @brief Alloc a buffer
84  *
85  *  @param pmoal Pointer to the MOAL context
86  *  @param size     The size of the buffer to be allocated
87  *  @param flag     The type of the buffer to be allocated
88  *  @param ppbuf    Pointer to a buffer location to store buffer pointer
89  * allocated
90  *
91  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
92  */
moal_malloc(t_void * pmoal,t_u32 size,t_u32 flag,t_u8 ** ppbuf)93 mlan_status moal_malloc(t_void *pmoal, t_u32 size, t_u32 flag, t_u8 **ppbuf)
94 {
95 	moal_handle *handle = (moal_handle *)pmoal;
96 	gfp_t mem_flag = (in_interrupt() || in_atomic() || irqs_disabled()) ?
97 				 GFP_ATOMIC :
98 				 GFP_KERNEL;
99 
100 	if (flag & MLAN_MEM_FLAG_ATOMIC)
101 		mem_flag = GFP_ATOMIC;
102 
103 #ifdef USB
104 	if (!IS_USB(handle->card_type))
105 #endif
106 	{
107 		if (flag & MLAN_MEM_DMA)
108 			mem_flag |= GFP_DMA;
109 	}
110 	*ppbuf = kzalloc(size, mem_flag);
111 	if (*ppbuf == NULL) {
112 		PRINTM(MERROR, "%s: allocate memory (%d bytes) failed!\n",
113 		       __func__, (int)size);
114 		return MLAN_STATUS_FAILURE;
115 	}
116 	atomic_inc(&handle->malloc_count);
117 
118 	return MLAN_STATUS_SUCCESS;
119 }
120 
121 /**
122  *  @brief Free a buffer
123  *
124  *  @param pmoal Pointer to the MOAL context
125  *  @param pbuf     Pointer to the buffer to be freed
126  *
127  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
128  */
moal_mfree(t_void * pmoal,t_u8 * pbuf)129 mlan_status moal_mfree(t_void *pmoal, t_u8 *pbuf)
130 {
131 	moal_handle *handle = (moal_handle *)pmoal;
132 
133 	if (!pbuf)
134 		return MLAN_STATUS_FAILURE;
135 	kfree(pbuf);
136 	atomic_dec(&handle->malloc_count);
137 	return MLAN_STATUS_SUCCESS;
138 }
139 
140 /**
141  *  @brief Alloc a vitual-address-continuous buffer
142  *
143  *  @param pmoal Pointer to the MOAL context
144  *  @param size     The size of the buffer to be allocated
145  *  @param ppbuf    Pointer to a buffer location to store buffer pointer
146  * allocated
147  *
148  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
149  */
moal_vmalloc(t_void * pmoal,t_u32 size,t_u8 ** ppbuf)150 mlan_status moal_vmalloc(t_void *pmoal, t_u32 size, t_u8 **ppbuf)
151 {
152 	moal_handle *handle = (moal_handle *)pmoal;
153 
154 	*ppbuf = vmalloc(size);
155 	if (*ppbuf == NULL) {
156 		PRINTM(MERROR, "%s: vmalloc (%d bytes) failed!", __func__,
157 		       (int)size);
158 		return MLAN_STATUS_FAILURE;
159 	}
160 	atomic_inc(&handle->vmalloc_count);
161 
162 	return MLAN_STATUS_SUCCESS;
163 }
164 
165 /**
166  *  @brief Free a buffer allocated by vmalloc
167  *
168  *  @param pmoal Pointer to the MOAL context
169  *  @param pbuf     Pointer to the buffer to be freed
170  *
171  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
172  */
moal_vfree(t_void * pmoal,t_u8 * pbuf)173 mlan_status moal_vfree(t_void *pmoal, t_u8 *pbuf)
174 {
175 	moal_handle *handle = (moal_handle *)pmoal;
176 
177 	if (!pbuf)
178 		return MLAN_STATUS_FAILURE;
179 	vfree(pbuf);
180 	atomic_dec(&handle->vmalloc_count);
181 	return MLAN_STATUS_SUCCESS;
182 }
183 
184 #ifdef PCIE
185 /**
186  *  @brief Alloc a consistent block of memory
187  *
188  *  @param pmoal Pointer to the MOAL context
189  *  @param size         The size of the buffer to be allocated
190  *  @param ppbuf        Pointer to a buffer location to store memory allocated
191  *  @param pbuf_pa      Pointer to a buffer location to store physical address
192  * of above memory
193  *
194  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
195  */
moal_malloc_consistent(t_void * pmoal,t_u32 size,t_u8 ** ppbuf,t_pu64 pbuf_pa)196 mlan_status moal_malloc_consistent(t_void *pmoal, t_u32 size, t_u8 **ppbuf,
197 				   t_pu64 pbuf_pa)
198 {
199 	moal_handle *handle = (moal_handle *)pmoal;
200 	pcie_service_card *card = (pcie_service_card *)handle->card;
201 	dma_addr_t dma;
202 	*pbuf_pa = 0;
203 
204 	if (!card)
205 		return MLAN_STATUS_FAILURE;
206 
207 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
208 	*ppbuf = (t_u8 *)dma_alloc_coherent(&card->dev->dev, size,
209 					    (dma_addr_t *)&dma, GFP_KERNEL);
210 #else
211 	*ppbuf = (t_u8 *)pci_alloc_consistent(card->dev, size,
212 					      (dma_addr_t *)&dma);
213 #endif
214 	if (*ppbuf == NULL) {
215 		PRINTM(MERROR,
216 		       "%s: allocate consistent memory (%d bytes) failed!\n",
217 		       __func__, (int)size);
218 		return MLAN_STATUS_FAILURE;
219 	}
220 	*pbuf_pa = (t_u64)dma;
221 	atomic_inc(&handle->malloc_cons_count);
222 
223 	return MLAN_STATUS_SUCCESS;
224 }
225 
226 /**
227  *  @brief Free a consistent block of memory
228  *
229  *  @param pmoal Pointer to the MOAL context
230  *  @param size         Size of them memory to be freed
231  *  @param pbuf         Pointer to the memory to be freed
232  *  @param buf_pa       Physical address of the memory to be freed
233  *
234  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
235  */
moal_mfree_consistent(t_void * pmoal,t_u32 size,t_u8 * pbuf,t_u64 buf_pa)236 mlan_status moal_mfree_consistent(t_void *pmoal, t_u32 size, t_u8 *pbuf,
237 				  t_u64 buf_pa)
238 {
239 	moal_handle *handle = (moal_handle *)pmoal;
240 	pcie_service_card *card = handle->card;
241 
242 	if (!pbuf || !card)
243 		return MLAN_STATUS_FAILURE;
244 
245 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
246 	dma_free_coherent(&card->dev->dev, size, pbuf, buf_pa);
247 #else
248 	pci_free_consistent(card->dev, size, pbuf, buf_pa);
249 #endif
250 	atomic_dec(&handle->malloc_cons_count);
251 	return MLAN_STATUS_SUCCESS;
252 }
253 
254 /**
255  *  @brief Map a block of memory to device
256  *
257  *  @param pmoal Pointer to the MOAL context
258  *  @param pbuf         Pointer to the buffer to be mapped
259  *  @param pbuf_pa      Pointer to store the physical address of buffer
260  *  @param size         Size of the buffer to be mapped
261  *  @param flag         Flags for mapping IO
262  *
263  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
264  */
moal_map_memory(t_void * pmoal,t_u8 * pbuf,t_u64 * pbuf_pa,t_u32 size,t_u32 flag)265 mlan_status moal_map_memory(t_void *pmoal, t_u8 *pbuf, t_u64 *pbuf_pa,
266 			    t_u32 size, t_u32 flag)
267 {
268 	moal_handle *handle = (moal_handle *)pmoal;
269 	pcie_service_card *card = (pcie_service_card *)handle->card;
270 
271 	dma_addr_t dma;
272 
273 	if (!card)
274 		return MLAN_STATUS_FAILURE;
275 
276 		/* Init memory to device */
277 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
278 	dma = dma_map_single(&card->dev->dev, pbuf, size, flag);
279 	if (dma_mapping_error(&card->dev->dev, dma)) {
280 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
281 	dma = pci_map_single(card->dev, pbuf, size, flag);
282 	if (pci_dma_mapping_error(card->dev, dma)) {
283 #else
284 	dma = pci_map_single(card->dev, pbuf, size, flag);
285 	if (pci_dma_mapping_error(dma)) {
286 #endif
287 		PRINTM(MERROR, "Tx ring: failed to dma_map_single\n");
288 		return MLAN_STATUS_FAILURE;
289 	}
290 
291 	*pbuf_pa = dma;
292 	return MLAN_STATUS_SUCCESS;
293 }
294 
295 /**
296  *  @brief Unmap a block of memory from device
297  *
298  *  @param pmoal Pointer to the MOAL context
299  *  @param pbuf         Pointer to the buffer to unmap
300  *  @param buf_pa       Physical address of buffer to unmap
301  *  @param size         Size of the buffer to unmap
302  *  @param flag         Flags for mapping IO
303  *
304  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
305  */
306 mlan_status moal_unmap_memory(t_void *pmoal, t_u8 *pbuf, t_u64 buf_pa,
307 			      t_u32 size, t_u32 flag)
308 {
309 	moal_handle *handle = (moal_handle *)pmoal;
310 	pcie_service_card *card = (pcie_service_card *)handle->card;
311 
312 	if (!card)
313 		return MLAN_STATUS_FAILURE;
314 
315 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
316 	dma_unmap_single(&card->dev->dev, buf_pa, size, flag);
317 #else
318 	pci_unmap_single(card->dev, buf_pa, size, flag);
319 #endif
320 
321 	return MLAN_STATUS_SUCCESS;
322 }
323 #endif /* PCIE */
324 
325 /**
326  *  @brief Fill memory with constant byte
327  *
328  *  @param pmoal Pointer to the MOAL context
329  *  @param pmem     Pointer to the memory area
330  *  @param byte     A constant byte
331  *  @param num      Number of bytes to fill
332  *
333  *  @return         Pointer to the memory area
334  */
335 t_void *moal_memset(t_void *pmoal, t_void *pmem, t_u8 byte, t_u32 num)
336 {
337 	t_void *p = pmem;
338 
339 	if (pmem && num)
340 		p = memset(pmem, byte, num);
341 
342 	return p;
343 }
344 
345 /**
346  *  @brief Copy memory from one area to another
347  *
348  *  @param pmoal Pointer to the MOAL context
349  *  @param pdest    Pointer to the dest memory
350  *  @param psrc     Pointer to the src memory
351  *  @param num      Number of bytes to move
352  *
353  *  @return         Pointer to the dest memory
354  */
355 t_void *moal_memcpy(t_void *pmoal, t_void *pdest, const t_void *psrc, t_u32 num)
356 {
357 	t_void *p = pdest;
358 
359 	if (pdest && psrc && num)
360 		p = memcpy(pdest, psrc, num);
361 
362 	return p;
363 }
364 
365 /**
366  *  @brief Copy memory from one area to another
367  *
368  *  @param pmoal Pointer to the MOAL context
369  *  @param pdest    Pointer to the dest memory
370  *  @param psrc     Pointer to the src memory
371  *  @param num      Number of bytes to move
372  *  @param dest_size size of dest memory.
373  *
374  *  @return         Pointer to the dest memory
375  */
376 t_void *moal_memcpy_ext(t_void *pmoal, t_void *pdest, const t_void *psrc,
377 			t_u32 num, t_u32 dest_size)
378 {
379 	t_void *p = pdest;
380 	if (pdest && psrc && num && dest_size)
381 		p = memcpy(pdest, psrc, MIN(num, dest_size));
382 
383 	return p;
384 }
385 
386 /**
387  *  @brief Move memory from one area to another
388  *
389  *  @param pmoal Pointer to the MOAL context
390  *  @param pdest    Pointer to the dest memory
391  *  @param psrc     Pointer to the src memory
392  *  @param num      Number of bytes to move
393  *
394  *  @return         Pointer to the dest memory
395  */
396 t_void *moal_memmove(t_void *pmoal, t_void *pdest, const t_void *psrc,
397 		     t_u32 num)
398 {
399 	t_void *p = pdest;
400 
401 	if (pdest && psrc && num)
402 		p = memmove(pdest, psrc, num);
403 
404 	return p;
405 }
406 
407 /**
408  *  @brief Compare two memory areas
409  *
410  *  @param pmoal Pointer to the MOAL context
411  *  @param pmem1    Pointer to the first memory
412  *  @param pmem2    Pointer to the second memory
413  *  @param num      Number of bytes to compare
414  *
415  *  @return         Compare result returns by memcmp
416  */
417 t_s32 moal_memcmp(t_void *pmoal, const t_void *pmem1, const t_void *pmem2,
418 		  t_u32 num)
419 {
420 	t_s32 result;
421 
422 	result = memcmp(pmem1, pmem2, num);
423 
424 	return result;
425 }
426 
427 /**
428  *  @brief Delay function
429  *
430  *  @param pmoal Pointer to the MOAL context
431  *  @param delay  delay in micro-second
432  *
433  *  @return       N/A
434  */
435 t_void moal_udelay(t_void *pmoal, t_u32 delay)
436 {
437 	if (delay >= 1000)
438 		msleep(delay / 1000);
439 	if (delay % 1000)
440 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
441 		usleep_range(delay % 1000 - 1, delay % 1000);
442 #else
443 		udelay(delay % 1000);
444 #endif
445 }
446 
447 /**
448  *  @brief  usleep_range function
449  *
450  *  @param pmoal Pointer to the MOAL context
451  *  @param min_delay  minimal delay in micro-second
452  *  @param max_delay  delay in micro-second
453  *
454  *  @return       N/A
455  */
456 t_void moal_usleep_range(t_void *pmoal, t_u32 min_delay, t_u32 max_delay)
457 {
458 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
459 	usleep_range(min_delay, max_delay);
460 #endif
461 }
462 /**
463  *  @brief Retrieves the current system time
464  *
465  *  @param pmoal Pointer to the MOAL context
466  *  @param psec     Pointer to buf for the seconds of system time
467  *  @param pusec    Pointer to buf the micro seconds of system time
468  *
469  *  @return         MLAN_STATUS_SUCCESS
470  */
471 mlan_status moal_get_system_time(t_void *pmoal, t_u32 *psec, t_u32 *pusec)
472 {
473 	wifi_timeval t;
474 
475 	woal_get_monotonic_time(&t);
476 	*psec = t.time_sec;
477 	*pusec = t.time_usec;
478 
479 	return MLAN_STATUS_SUCCESS;
480 }
481 
482 /**
483  *  @brief Retrieves the current boot time
484  *
485  *  @param pmoal Pointer to the MOAL context
486  *  @param pnsec     Pointer to buf for the Nanoseconds of boot time
487  *
488  *  @return         MLAN_STATUS_SUCCESS
489  */
490 mlan_status moal_get_boot_ktime(t_void *pmoal, t_u64 *pnsec)
491 {
492 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
493 	ktime_t time;
494 
495 	time = ktime_get_with_offset(TK_OFFS_BOOT);
496 	*pnsec = *(t_u64 *)&(time);
497 #endif
498 	return MLAN_STATUS_SUCCESS;
499 }
500 
501 /**
502  *  @brief Initializes the timer
503  *
504  *  @param pmoal Pointer to the MOAL context
505  *  @param pptimer      Pointer to the timer
506  *  @param callback     Pointer to callback function
507  *  @param pcontext     Pointer to context
508  *
509  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
510  */
511 mlan_status moal_init_timer(t_void *pmoal, t_void **pptimer,
512 			    IN t_void (*callback)(t_void *pcontext),
513 			    t_void *pcontext)
514 {
515 	moal_drv_timer *timer = NULL;
516 	gfp_t mem_flag = (in_interrupt() || in_atomic() || irqs_disabled()) ?
517 				 GFP_ATOMIC :
518 				 GFP_KERNEL;
519 
520 	timer = kmalloc(sizeof(moal_drv_timer), mem_flag);
521 	if (timer == NULL)
522 		return MLAN_STATUS_FAILURE;
523 	woal_initialize_timer(timer, callback, pcontext);
524 	*pptimer = (t_void *)timer;
525 
526 	return MLAN_STATUS_SUCCESS;
527 }
528 
529 /**
530  *  @brief Free the timer
531  *
532  *  @param pmoal Pointer to the MOAL context
533  *  @param ptimer   Pointer to the timer
534  *
535  *  @return         MLAN_STATUS_SUCCESS
536  */
537 mlan_status moal_free_timer(t_void *pmoal, t_void *ptimer)
538 {
539 	moal_drv_timer *timer = (moal_drv_timer *)ptimer;
540 
541 	if (timer) {
542 		if ((timer->timer_is_canceled == MFALSE) &&
543 		    timer->time_period) {
544 			PRINTM(MWARN,
545 			       "mlan try to free timer without stop timer!\n");
546 			woal_cancel_timer(timer);
547 		}
548 		kfree(timer);
549 	}
550 
551 	return MLAN_STATUS_SUCCESS;
552 }
553 
554 /**
555  *  @brief Start the timer
556  *
557  *  @param pmoal Pointer to the MOAL context
558  *  @param ptimer       Pointer to the timer
559  *  @param periodic     Periodic timer
560  *  @param msec         Timer value in milliseconds
561  *
562  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
563  */
564 mlan_status moal_start_timer(t_void *pmoal, t_void *ptimer, t_u8 periodic,
565 			     t_u32 msec)
566 {
567 	if (!ptimer)
568 		return MLAN_STATUS_FAILURE;
569 
570 	((moal_drv_timer *)ptimer)->timer_is_periodic = periodic;
571 	woal_mod_timer((moal_drv_timer *)ptimer, msec);
572 
573 	return MLAN_STATUS_SUCCESS;
574 }
575 
576 /**
577  *  @brief Stop the timer
578  *
579  *  @param pmoal Pointer to the MOAL context
580  *  @param ptimer   Pointer to the timer
581  *
582  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
583  */
584 mlan_status moal_stop_timer(t_void *pmoal, t_void *ptimer)
585 {
586 	if (!ptimer)
587 		return MLAN_STATUS_FAILURE;
588 	woal_cancel_timer((moal_drv_timer *)ptimer);
589 
590 	return MLAN_STATUS_SUCCESS;
591 }
592 
593 /**
594  *  @brief Initializes the lock
595  *
596  *  @param pmoal Pointer to the MOAL context
597  *  @param pplock   Pointer to the lock
598  *
599  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
600  */
601 mlan_status moal_init_lock(t_void *pmoal, t_void **pplock)
602 {
603 	moal_handle *handle = (moal_handle *)pmoal;
604 	moal_lock *mlock = NULL;
605 
606 	mlock = kmalloc(sizeof(moal_lock), GFP_ATOMIC);
607 	if (!mlock)
608 		return MLAN_STATUS_FAILURE;
609 	spin_lock_init(&mlock->lock);
610 	*pplock = (t_void *)mlock;
611 
612 	atomic_inc(&handle->lock_count);
613 
614 	return MLAN_STATUS_SUCCESS;
615 }
616 
617 /**
618  *  @brief Free the lock
619  *
620  *  @param pmoal Pointer to the MOAL context
621  *  @param plock    Lock
622  *
623  *  @return         MLAN_STATUS_SUCCESS
624  */
625 mlan_status moal_free_lock(t_void *pmoal, t_void *plock)
626 {
627 	moal_handle *handle = (moal_handle *)pmoal;
628 	moal_lock *mlock = plock;
629 
630 	kfree(mlock);
631 	if (mlock)
632 		atomic_dec(&handle->lock_count);
633 
634 	return MLAN_STATUS_SUCCESS;
635 }
636 
637 /**
638  *  @brief Request a spin lock
639  *
640  *  @param pmoal Pointer to the MOAL context
641  *  @param plock    Pointer to the lock
642  *
643  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
644  */
645 mlan_status moal_spin_lock(t_void *pmoal, t_void *plock)
646 	__acquires(&plock->lock)
647 {
648 	moal_lock *mlock = plock;
649 	unsigned long flags = 0;
650 	spin_lock_irqsave(&mlock->lock, flags);
651 	mlock->flags = flags;
652 	return MLAN_STATUS_SUCCESS;
653 }
654 
655 /**
656  *  @brief Request a spin_unlock
657  *
658  *  @param pmoal Pointer to the MOAL context
659  *  @param plock    Pointer to the lock
660  *
661  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
662  */
663 mlan_status moal_spin_unlock(t_void *pmoal, t_void *plock)
664 	__releases(&plock->lock)
665 {
666 	moal_lock *mlock = (moal_lock *)plock;
667 	spin_unlock_irqrestore(&mlock->lock, mlock->flags);
668 	return MLAN_STATUS_SUCCESS;
669 }
670 
671 /**
672  *  @brief  This function collects AMSDU TP statistics.
673  *
674  *  @param pmoal Pointer to the MOAL context
675  *  @param amsdu_process_delay          amsdu process time
676  *  @param amsdu_copy_delay             amsdu copy time
677  *
678  *  @return         N/A
679  */
680 void moal_amsdu_tp_accounting(t_void *pmoal, t_s32 amsdu_process_delay,
681 			      t_s32 amsdu_copy_delay)
682 {
683 	moal_handle *handle = (moal_handle *)pmoal;
684 	handle->tp_acnt.rx_amsdu_delay[handle->tp_acnt.rx_amsdu_index] =
685 		amsdu_process_delay;
686 	handle->tp_acnt.rx_amsdu_copy_delay[handle->tp_acnt.rx_amsdu_index] =
687 		amsdu_copy_delay;
688 	handle->tp_acnt.rx_amsdu_index++;
689 	if (handle->tp_acnt.rx_amsdu_index >= TXRX_MAX_SAMPLE)
690 		handle->tp_acnt.rx_amsdu_index = 0;
691 }
692 
693 /**
694  *  @brief  This function collects TP statistics.
695  *
696  *  @param pmoal Pointer to the MOAL context
697  *  @param buf          pointer to the buffer of a packet
698  *  @param drop_point   Drop pointer user set
699  *
700  *  @return         N/A
701  */
702 void moal_tp_accounting(t_void *pmoal, void *buf, t_u32 drop_point)
703 {
704 	struct sk_buff *skb = NULL;
705 	moal_handle *handle = (moal_handle *)pmoal;
706 	pmlan_buffer pmbuf = (pmlan_buffer)buf;
707 	t_s32 delay;
708 	wifi_timeval t;
709 
710 	if (drop_point < MAX_TP_ACCOUNT_DROP_POINT_NUM) {
711 		if (drop_point == 4) {
712 			handle->tp_acnt.tx_bytes[drop_point] += pmbuf->data_len;
713 		} else {
714 			skb = (struct sk_buff *)buf;
715 			handle->tp_acnt.tx_bytes[drop_point] += skb->len;
716 		}
717 		handle->tp_acnt.tx_packets[drop_point]++;
718 	} else if (drop_point <= RX_DROP_P5) {
719 		t_u16 rx_len = 0;
720 		if (drop_point == RX_DROP_P1 || drop_point == RX_DROP_P2)
721 			rx_len = pmbuf->data_len -
722 				 *((t_u16 *)(pmbuf->pbuf + pmbuf->data_offset) +
723 				   2); // remove rx_pkt_offset
724 		else if (drop_point == RX_DROP_P3) // aggr pkt
725 			rx_len = pmbuf->data_len;
726 		else if (drop_point == RX_DROP_P4) { // before to kernel
727 			skb = (struct sk_buff *)buf;
728 			rx_len = skb->len;
729 		}
730 		handle->tp_acnt
731 			.rx_bytes[drop_point - MAX_TP_ACCOUNT_DROP_POINT_NUM] +=
732 			rx_len;
733 		handle->tp_acnt.rx_packets[drop_point -
734 					   MAX_TP_ACCOUNT_DROP_POINT_NUM]++;
735 	} else if (drop_point == RX_TIME_PKT) {
736 		woal_get_monotonic_time(&t);
737 		/* deque - pcie receive */
738 		delay = (t_s32)(pmbuf->extra_ts_sec - pmbuf->in_ts_sec) *
739 			1000000;
740 		delay += (t_s32)(pmbuf->extra_ts_usec - pmbuf->in_ts_usec);
741 		handle->tp_acnt.rx_delay1_driver[handle->tp_acnt.rx_index] =
742 			delay;
743 		/* before netif_rx - deque */
744 		delay = (t_s32)(pmbuf->out_ts_sec - pmbuf->extra_ts_sec) *
745 			1000000;
746 		delay += (t_s32)(pmbuf->out_ts_usec - pmbuf->extra_ts_usec);
747 		handle->tp_acnt.rx_delay2_driver[handle->tp_acnt.rx_index] =
748 			delay;
749 		/* netif_rx to netif_rx return */
750 		delay = (t_s32)(t.time_sec - pmbuf->out_ts_sec) * 1000000;
751 		delay += (t_s32)(t.time_usec - pmbuf->out_ts_usec);
752 		handle->tp_acnt.rx_delay_kernel[handle->tp_acnt.rx_index] =
753 			delay;
754 		handle->tp_acnt.rx_index++;
755 		if (handle->tp_acnt.rx_index >= TXRX_MAX_SAMPLE)
756 			handle->tp_acnt.rx_index = 0;
757 	} else if (drop_point == TX_TIME_PKT) {
758 		delay = (t_s32)(pmbuf->out_ts_sec - pmbuf->in_ts_sec) * 1000000;
759 		delay += (t_s32)(pmbuf->out_ts_usec - pmbuf->in_ts_usec);
760 		handle->tp_acnt.tx_delay_driver[handle->tp_acnt.tx_index] =
761 			delay;
762 		handle->tp_acnt.tx_index++;
763 		if (handle->tp_acnt.tx_index >= TXRX_MAX_SAMPLE)
764 			handle->tp_acnt.tx_index = 0;
765 	}
766 }
767 
768 void moal_tp_accounting_rx_param(t_void *pmoal, unsigned int type,
769 				 unsigned int rsvd1)
770 {
771 	moal_handle *phandle = (moal_handle *)pmoal;
772 	switch (type) {
773 	case 0: // Rx interrupt
774 		phandle->tp_acnt.rx_intr_cnt++;
775 		break;
776 	case 1: // rx_pkts_queued
777 		phandle->tp_acnt.rx_pending = rsvd1;
778 		break;
779 	case 2: // paused
780 		phandle->tp_acnt.rx_paused_cnt++;
781 		break;
782 	case 3: // tx interrupt count
783 		phandle->tp_acnt.tx_intr_cnt++;
784 		break;
785 	case 4: // rx amsdu count
786 		phandle->tp_acnt.rx_amsdu_cnt++;
787 		phandle->tp_acnt.rx_amsdu_pkt_cnt += rsvd1;
788 		break;
789 	case 5: // tx amsdu count
790 		phandle->tp_acnt.tx_amsdu_cnt++;
791 		phandle->tp_acnt.tx_amsdu_pkt_cnt += rsvd1;
792 		break;
793 	case 6: // rxbd rdptr full count
794 		phandle->tp_acnt.rx_rdptr_full_cnt++;
795 		break;
796 	case 7: // tx hard xmit skb realloc count
797 		phandle->tp_acnt.tx_xmit_skb_realloc_cnt++;
798 		break;
799 	case 8: // tx stop queue count
800 		phandle->tp_acnt.tx_stop_queue_cnt++;
801 		break;
802 
803 	default:
804 		break;
805 	}
806 }
807 
808 /**
809  *  @brief This function reads one block of firmware data from MOAL
810  *
811  *  @param pmoal Pointer to the MOAL context
812  *  @param offset       Offset from where the data will be copied
813  *  @param len          Length to be copied
814  *  @param pbuf         Buffer where the data will be copied
815  *
816  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
817  */
818 mlan_status moal_get_fw_data(t_void *pmoal, t_u32 offset, t_u32 len, t_u8 *pbuf)
819 {
820 	moal_handle *handle = (moal_handle *)pmoal;
821 
822 	if (!pbuf || !len || !handle->firmware)
823 		return MLAN_STATUS_FAILURE;
824 
825 	if (offset + len > handle->firmware->size)
826 		return MLAN_STATUS_FAILURE;
827 
828 	moal_memcpy_ext(handle, pbuf, handle->firmware->data + offset, len,
829 			len);
830 
831 	return MLAN_STATUS_SUCCESS;
832 }
833 
834 /**
835  *  @brief This function get vdll data from moal
836  *
837  *  @param pmoal Pointer to the MOAL context
838  *  @param len          Length to be copied
839  *  @param pbuf         Buffer where the data will be copied
840  *
841  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
842  */
843 mlan_status moal_get_vdll_data(t_void *pmoal, t_u32 len, t_u8 *pbuf)
844 {
845 	moal_handle *handle = (moal_handle *)pmoal;
846 	mlan_status status = MLAN_STATUS_FAILURE;
847 	t_u32 offset = 0;
848 	t_u8 req_fw = MFALSE;
849 
850 	if (!handle->firmware) {
851 		req_fw = MTRUE;
852 		woal_vdll_req_fw(handle);
853 	}
854 
855 	if (handle->firmware) {
856 		if (len < handle->firmware->size) {
857 			offset = handle->firmware->size - len;
858 			moal_memcpy_ext(handle, pbuf,
859 					handle->firmware->data + offset, len,
860 					len);
861 			status = MLAN_STATUS_SUCCESS;
862 		} else {
863 			PRINTM(MERROR, "Invalid VDLL length = %d, fw_len=%d\n",
864 			       len, (int)handle->firmware->size);
865 		}
866 		if (req_fw) {
867 			release_firmware(handle->firmware);
868 			handle->firmware = NULL;
869 		}
870 	}
871 	return status;
872 }
873 
874 /**
875  *  @brief This function is called when MLAN completes the initialization
876  * firmware.
877  *
878  *  @param pmoal Pointer to the MOAL context
879  *  @param status   The status code for mlan_init_fw request
880  *  @param phw      pointer to mlan_hw_info
881  *  @param ptbl     pointer to mplan_bss_tbl
882  *  @return         MLAN_STATUS_SUCCESS
883  */
884 mlan_status moal_get_hw_spec_complete(t_void *pmoal, mlan_status status,
885 				      mlan_hw_info *phw, pmlan_bss_tbl ptbl)
886 {
887 	moal_handle *handle = (moal_handle *)pmoal;
888 	int i;
889 	t_u32 drv_mode = handle->params.drv_mode;
890 
891 	ENTER();
892 	if (status == MLAN_STATUS_SUCCESS) {
893 		PRINTM(MCMND, "Get Hw Spec done, fw_cap=0x%x\n", phw->fw_cap);
894 #ifdef PCIE9098
895 		/** Special/Temporary handling to manage the driver version
896 		 * string to identify Seahawk/AW690 (skyhawk based) based on
897 		 * fw_cap_ext value set by Fw */
898 		if (phw->fw_cap_ext & MBIT(31) &&
899 		    IS_PCIE9098(handle->card_type)) {
900 			moal_memcpy_ext(handle, driver_version, CARD_PCIEAW690,
901 					strlen(CARD_PCIEAW690),
902 					strlen(driver_version));
903 			moal_memcpy_ext(handle,
904 					driver_version + strlen(INTF_CARDTYPE) +
905 						strlen(KERN_VERSION),
906 					V17, strlen(V17),
907 					strlen(driver_version) -
908 						strlen(INTF_CARDTYPE) -
909 						strlen(KERN_VERSION));
910 			moal_memcpy_ext(handle, handle->driver_version,
911 					driver_version, strlen(driver_version),
912 					MLAN_MAX_VER_STR_LEN - 1);
913 		}
914 #endif
915 		/** FW should only enable DFS on one mac */
916 		if (!(phw->fw_cap & FW_CAPINFO_ZERO_DFS))
917 			handle->params.drv_mode &= ~DRV_MODE_DFS;
918 
919 		if (!(phw->fw_cap & FW_CAPINFO_80211BGA))
920 			handle->params.drv_mode &= ~DRV_MODE_WLAN;
921 		if (!handle->params.drv_mode ||
922 		    MLAN_STATUS_SUCCESS !=
923 			    woal_update_drv_tbl(handle,
924 						handle->params.drv_mode)) {
925 			PRINTM(MERROR,
926 			       "Get_hw_spec_complete: Fail to update drv_tbl\n");
927 			LEAVE();
928 			return MLAN_STATUS_FAILURE;
929 		}
930 		memset(ptbl, 0, sizeof(mlan_bss_tbl));
931 		for (i = 0; i < handle->drv_mode.intf_num; i++) {
932 			ptbl->bss_attr[i].bss_type =
933 				handle->drv_mode.bss_attr[i].bss_type;
934 			ptbl->bss_attr[i].frame_type =
935 				handle->drv_mode.bss_attr[i].frame_type;
936 			ptbl->bss_attr[i].active =
937 				handle->drv_mode.bss_attr[i].active;
938 			ptbl->bss_attr[i].bss_priority =
939 				handle->drv_mode.bss_attr[i].bss_priority;
940 			ptbl->bss_attr[i].bss_num =
941 				handle->drv_mode.bss_attr[i].bss_num;
942 			ptbl->bss_attr[i].bss_virtual =
943 				handle->drv_mode.bss_attr[i].bss_virtual;
944 		}
945 		PRINTM(MCMND, "org_drv_mode=0x%x drv_mode=0x%x\n", drv_mode,
946 		       handle->params.drv_mode);
947 	}
948 	LEAVE();
949 	return MLAN_STATUS_SUCCESS;
950 }
951 
952 /**
953  *  @brief This function is called when MLAN completes the initialization
954  * firmware.
955  *
956  *  @param pmoal Pointer to the MOAL context
957  *  @param status   The status code for mlan_init_fw request
958  *
959  *  @return         MLAN_STATUS_SUCCESS
960  */
961 mlan_status moal_init_fw_complete(t_void *pmoal, mlan_status status)
962 {
963 	moal_handle *handle = (moal_handle *)pmoal;
964 	ENTER();
965 	if (status == MLAN_STATUS_SUCCESS)
966 		handle->hardware_status = HardwareStatusReady;
967 	handle->init_wait_q_woken = MTRUE;
968 	wake_up(&handle->init_wait_q);
969 	LEAVE();
970 	return MLAN_STATUS_SUCCESS;
971 }
972 
973 /**
974  *  @brief This function is called when MLAN shutdown firmware is completed.
975  *
976  *  @param pmoal Pointer to the MOAL context
977  *  @param status   The status code for mlan_shutdown request
978  *
979  *  @return         MLAN_STATUS_SUCCESS
980  */
981 mlan_status moal_shutdown_fw_complete(t_void *pmoal, mlan_status status)
982 {
983 	moal_handle *handle = (moal_handle *)pmoal;
984 	ENTER();
985 	handle->hardware_status = HardwareStatusNotReady;
986 	handle->init_wait_q_woken = MTRUE;
987 	wake_up_interruptible(&handle->init_wait_q);
988 	LEAVE();
989 	return MLAN_STATUS_SUCCESS;
990 }
991 
992 /**
993  *  @brief This function is called when an MLAN IOCTL is completed.
994  *
995  *  @param pmoal Pointer to the MOAL context
996  *  @param pioctl_req	pointer to structure mlan_ioctl_req
997  *  @param status   The status code for mlan_ioctl request
998  *
999  *  @return         MLAN_STATUS_SUCCESS
1000  */
1001 mlan_status moal_ioctl_complete(t_void *pmoal, pmlan_ioctl_req pioctl_req,
1002 				mlan_status status)
1003 {
1004 	moal_handle *handle = (moal_handle *)pmoal;
1005 	moal_private *priv = NULL;
1006 	wait_queue *wait;
1007 	unsigned long flags = 0;
1008 	ENTER();
1009 
1010 	if (!atomic_read(&handle->ioctl_pending))
1011 		PRINTM(MERROR, "ERR: Unexpected IOCTL completed: %p\n",
1012 		       pioctl_req);
1013 	else
1014 		atomic_dec(&handle->ioctl_pending);
1015 	priv = woal_bss_index_to_priv(handle, pioctl_req->bss_index);
1016 	if (!priv) {
1017 		PRINTM(MERROR,
1018 		       "IOCTL %p complete with NULL priv, bss_index=%d\n",
1019 		       pioctl_req, pioctl_req->bss_index);
1020 		LEAVE();
1021 		return MLAN_STATUS_SUCCESS;
1022 	}
1023 
1024 	if (status != MLAN_STATUS_SUCCESS && status != MLAN_STATUS_COMPLETE)
1025 		PRINTM(MERROR,
1026 		       "IOCTL failed: %p id=0x%x, sub_id=0x%x action=%d, status_code=0x%x\n",
1027 		       pioctl_req, pioctl_req->req_id,
1028 		       (*(t_u32 *)pioctl_req->pbuf), (int)pioctl_req->action,
1029 		       pioctl_req->status_code);
1030 	else
1031 		PRINTM(MIOCTL,
1032 		       "IOCTL completed: %p id=0x%x sub_id=0x%x, action=%d,  status=%d, status_code=0x%x\n",
1033 		       pioctl_req, pioctl_req->req_id,
1034 		       (*(t_u32 *)pioctl_req->pbuf), (int)pioctl_req->action,
1035 		       status, pioctl_req->status_code);
1036 
1037 	spin_lock_irqsave(&handle->driver_lock, flags);
1038 	wait = (wait_queue *)pioctl_req->reserved_1;
1039 	if (wait) {
1040 		wait->condition = MTRUE;
1041 		wait->status = status;
1042 		if (wait->wait_timeout) {
1043 			wake_up(&wait->wait);
1044 		} else {
1045 			if ((status != MLAN_STATUS_SUCCESS) &&
1046 			    (pioctl_req->status_code ==
1047 			     MLAN_ERROR_CMD_TIMEOUT)) {
1048 				PRINTM(MERROR, "IOCTL: command timeout\n");
1049 			} else {
1050 				wake_up_interruptible(&wait->wait);
1051 			}
1052 		}
1053 		spin_unlock_irqrestore(&handle->driver_lock, flags);
1054 	} else {
1055 		spin_unlock_irqrestore(&handle->driver_lock, flags);
1056 		if ((status == MLAN_STATUS_SUCCESS) &&
1057 		    (pioctl_req->action == MLAN_ACT_GET))
1058 			woal_process_ioctl_resp(priv, pioctl_req);
1059 		kfree(pioctl_req);
1060 	}
1061 	LEAVE();
1062 	return MLAN_STATUS_SUCCESS;
1063 }
1064 
1065 /**
1066  *  @brief This function allocates mlan_buffer.
1067  *
1068  *  @param pmoal Pointer to the MOAL context
1069  *  @param size     allocation size requested
1070  *  @param pmbuf    pointer to pointer to the allocated buffer
1071  *
1072  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1073  */
1074 mlan_status moal_alloc_mlan_buffer(t_void *pmoal, t_u32 size,
1075 				   pmlan_buffer *pmbuf)
1076 {
1077 	*pmbuf = woal_alloc_mlan_buffer((moal_handle *)pmoal, size);
1078 	if (NULL == *pmbuf)
1079 		return MLAN_STATUS_FAILURE;
1080 	return MLAN_STATUS_SUCCESS;
1081 }
1082 
1083 /**
1084  *  @brief This function frees mlan_buffer.
1085  *
1086  *  @param pmoal Pointer to the MOAL context
1087  *  @param pmbuf    pointer to buffer to be freed
1088  *
1089  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1090  */
1091 mlan_status moal_free_mlan_buffer(t_void *pmoal, pmlan_buffer pmbuf)
1092 {
1093 	if (!pmbuf)
1094 		return MLAN_STATUS_FAILURE;
1095 	woal_free_mlan_buffer((moal_handle *)pmoal, pmbuf);
1096 	return MLAN_STATUS_SUCCESS;
1097 }
1098 
1099 /**
1100  *  @brief This function is called when MLAN complete send data packet.
1101  *
1102  *  @param pmoal Pointer to the MOAL context
1103  *  @param pmbuf    Pointer to the mlan buffer structure
1104  *  @param status   The status code for mlan_send_packet request
1105  *
1106  *  @return         MLAN_STATUS_SUCCESS
1107  */
1108 mlan_status moal_send_packet_complete(t_void *pmoal, pmlan_buffer pmbuf,
1109 				      mlan_status status)
1110 {
1111 	moal_private *priv = NULL;
1112 	moal_handle *handle = (moal_handle *)pmoal;
1113 	struct sk_buff *skb = NULL;
1114 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
1115 	t_u32 index = 0;
1116 #endif
1117 
1118 	ENTER();
1119 	if (pmbuf && pmbuf->buf_type == MLAN_BUF_TYPE_RAW_DATA) {
1120 		woal_free_mlan_buffer(handle, pmbuf);
1121 		atomic_dec(&handle->tx_pending);
1122 		goto done;
1123 	}
1124 	if (pmbuf) {
1125 		priv = woal_bss_index_to_priv(pmoal, pmbuf->bss_index);
1126 		skb = (struct sk_buff *)pmbuf->pdesc;
1127 		if (priv) {
1128 			woal_set_trans_start(priv->netdev);
1129 			if (skb) {
1130 				if (status == MLAN_STATUS_SUCCESS) {
1131 					priv->stats.tx_packets++;
1132 					priv->stats.tx_bytes += skb->len;
1133 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
1134 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
1135 					woal_packet_fate_monitor(
1136 						priv, PACKET_TYPE_TX,
1137 						TX_PKT_FATE_SENT,
1138 						FRAME_TYPE_ETHERNET_II, 0, 0,
1139 						skb->data, skb->data_len);
1140 #endif
1141 #endif
1142 				} else {
1143 					priv->stats.tx_errors++;
1144 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
1145 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
1146 					woal_packet_fate_monitor(
1147 						priv, PACKET_TYPE_TX,
1148 						TX_PKT_FATE_DRV_DROP_OTHER,
1149 						FRAME_TYPE_ETHERNET_II, 0, 0,
1150 						skb->data, skb->data_len);
1151 #endif
1152 #endif
1153 				}
1154 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 29)
1155 				index = skb_get_queue_mapping(skb);
1156 				if (index < 4) {
1157 					atomic_dec(&handle->tx_pending);
1158 					if (atomic_dec_return(
1159 						    &priv->wmm_tx_pending[index]) ==
1160 					    LOW_TX_PENDING) {
1161 						struct netdev_queue *txq =
1162 							netdev_get_tx_queue(
1163 								priv->netdev,
1164 								index);
1165 						if (netif_tx_queue_stopped(
1166 							    txq)) {
1167 							netif_tx_wake_queue(
1168 								txq);
1169 							PRINTM(MINFO,
1170 							       "Wakeup Kernel Queue:%d\n",
1171 							       index);
1172 						}
1173 					}
1174 				} else {
1175 					PRINTM(MERROR,
1176 					       "Invalid queue index for skb\n");
1177 				}
1178 #else /*#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)*/
1179 				if (atomic_dec_return(&handle->tx_pending) <
1180 				    LOW_TX_PENDING) {
1181 					int i;
1182 					for (i = 0; i < handle->priv_num; i++) {
1183 #ifdef STA_SUPPORT
1184 						if ((GET_BSS_ROLE(
1185 							     handle->priv[i]) ==
1186 						     MLAN_BSS_ROLE_STA) &&
1187 						    (handle->priv[i]
1188 							     ->media_connected ||
1189 						     priv->is_adhoc_link_sensed)) {
1190 							woal_wake_queue(
1191 								handle->priv[i]
1192 									->netdev);
1193 						}
1194 #endif
1195 #ifdef UAP_SUPPORT
1196 						if ((GET_BSS_ROLE(
1197 							     handle->priv[i]) ==
1198 						     MLAN_BSS_ROLE_UAP) &&
1199 						    (handle->priv[i]
1200 							     ->media_connected)) {
1201 							woal_wake_queue(
1202 								handle->priv[i]
1203 									->netdev);
1204 						}
1205 #endif
1206 					}
1207 				}
1208 #endif /*#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)*/
1209 			}
1210 		}
1211 		if (skb)
1212 			dev_kfree_skb_any(skb);
1213 	}
1214 
1215 done:
1216 	if ((atomic_read(&handle->tx_pending) == 0) &&
1217 	    !is_zero_timeval(handle->tx_time_start)) {
1218 		woal_get_monotonic_time(&handle->tx_time_end);
1219 		handle->tx_time +=
1220 			(t_u64)(timeval_to_usec(handle->tx_time_end) -
1221 				timeval_to_usec(handle->tx_time_start));
1222 		PRINTM(MINFO,
1223 		       "%s : start_timeval=%d:%d end_timeval=%d:%d inter=%llu tx_time=%llu\n",
1224 		       __func__, handle->tx_time_start.time_sec,
1225 		       handle->tx_time_start.time_usec,
1226 		       handle->tx_time_end.time_sec,
1227 		       handle->tx_time_end.time_usec,
1228 		       (t_u64)(timeval_to_usec(handle->tx_time_end) -
1229 			       timeval_to_usec(handle->tx_time_start)),
1230 		       handle->tx_time);
1231 		handle->tx_time_start.time_sec = 0;
1232 		handle->tx_time_start.time_usec = 0;
1233 	}
1234 	LEAVE();
1235 	return MLAN_STATUS_SUCCESS;
1236 }
1237 
1238 #ifdef USB
1239 /**
1240  *  @brief This function is called when MLAN complete receiving
1241  *         data/event/command
1242  *
1243  *  @param pmoal Pointer to the MOAL context
1244  *  @param pmbuf    Pointer to the mlan buffer structure
1245  *  @param port     Port number for receive
1246  *  @param status   The status code for mlan_receive request
1247  *
1248  *  @return         MLAN_STATUS_SUCCESS
1249  */
1250 mlan_status moal_recv_complete(t_void *pmoal, pmlan_buffer pmbuf, t_u32 port,
1251 			       mlan_status status)
1252 {
1253 	moal_private *priv = NULL;
1254 	moal_handle *handle = (moal_handle *)pmoal;
1255 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1256 	ENTER();
1257 
1258 	if ((pmbuf && (pmbuf->flags & MLAN_BUF_FLAG_RX_DEAGGR)) || !pmbuf)
1259 		atomic_dec(&handle->rx_pending);
1260 
1261 	if (pmbuf) {
1262 		priv = woal_bss_index_to_priv(handle, pmbuf->bss_index);
1263 		if (priv && (pmbuf->buf_type == MLAN_BUF_TYPE_DATA) &&
1264 		    (status == MLAN_STATUS_FAILURE)) {
1265 			priv->stats.rx_dropped++;
1266 		}
1267 		/* Reuse the buffer in case of command/event */
1268 		if (port == cardp->rx_cmd_ep)
1269 			woal_submit_rx_urb(handle, port);
1270 		else {
1271 			woal_free_mlan_buffer(handle, pmbuf);
1272 			if ((atomic_read(&handle->rx_pending) <
1273 			     USB_LOW_RX_PENDING) &&
1274 			    atomic_read(&cardp->rx_data_urb_pending) <
1275 				    MVUSB_RX_DATA_URB)
1276 				woal_usb_submit_rx_data_urbs(handle);
1277 		}
1278 	} else if (port == cardp->rx_data_ep) {
1279 		if ((atomic_read(&handle->rx_pending) < USB_LOW_RX_PENDING) &&
1280 		    atomic_read(&cardp->rx_data_urb_pending) <
1281 			    MVUSB_RX_DATA_URB)
1282 			woal_usb_submit_rx_data_urbs(handle);
1283 	}
1284 	LEAVE();
1285 	return MLAN_STATUS_SUCCESS;
1286 }
1287 
1288 /**
1289  *  @brief This function write a command/data packet to card.
1290  *
1291  *  @param pmoal Pointer to the MOAL context
1292  *  @param pmbuf    Pointer to the mlan buffer structure
1293  *  @param port     Port number for sent
1294  *
1295  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE or
1296  * MLAN_STATUS_PENDING or MLAN_STATUS_RESOURCE
1297  */
1298 mlan_status moal_write_data_async(t_void *pmoal, pmlan_buffer pmbuf, t_u32 port)
1299 {
1300 	moal_handle *handle = (moal_handle *)pmoal;
1301 	mlan_status ret = MLAN_STATUS_SUCCESS;
1302 	ENTER();
1303 	if (handle->is_suspended == MTRUE) {
1304 		PRINTM(MERROR,
1305 		       "write_data_async is not allowed while suspended\n");
1306 		LEAVE();
1307 		return MLAN_STATUS_FAILURE;
1308 	}
1309 	ret = woal_write_data_async((moal_handle *)pmoal, pmbuf, (t_u8)port);
1310 	LEAVE();
1311 	return ret;
1312 }
1313 #endif /* USB */
1314 
1315 /**
1316  *  @brief This function write a command/data packet to card.
1317  *         This function blocks the call until it finishes
1318  *
1319  *  @param pmoal Pointer to the MOAL context
1320  *  @param pmbuf    Pointer to the mlan buffer structure
1321  *  @param port     Port number for sent
1322  *  @param timeout  Timeout value in milliseconds (if 0 the wait is forever)
1323  *
1324  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1325  */
1326 mlan_status moal_write_data_sync(t_void *pmoal, pmlan_buffer pmbuf, t_u32 port,
1327 				 t_u32 timeout)
1328 {
1329 	moal_handle *handle = (moal_handle *)pmoal;
1330 	return handle->ops.write_data_sync(handle, pmbuf, port, timeout);
1331 }
1332 
1333 /**
1334  *  @brief This function read data packet/event/command from card.
1335  *         This function blocks the call until it finish
1336  *
1337  *  @param pmoal Pointer to the MOAL context
1338  *  @param pmbuf    Pointer to the mlan buffer structure
1339  *  @param port     Port number for read
1340  *  @param timeout  Timeout value in milliseconds (if 0 the wait is forever)
1341  *
1342  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1343  */
1344 mlan_status moal_read_data_sync(t_void *pmoal, pmlan_buffer pmbuf, t_u32 port,
1345 				t_u32 timeout)
1346 {
1347 	moal_handle *handle = (moal_handle *)pmoal;
1348 	return handle->ops.read_data_sync(handle, pmbuf, port, timeout);
1349 }
1350 
1351 #if defined(SDIO) || defined(PCIE)
1352 /**
1353  *  @brief This function writes data into card register.
1354  *
1355  *  @param pmoal Pointer to the MOAL context
1356  *  @param reg          register offset
1357  *  @param data         value
1358  *
1359  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1360  */
1361 mlan_status moal_write_reg(t_void *pmoal, t_u32 reg, t_u32 data)
1362 {
1363 	int ret = MLAN_STATUS_FAILURE;
1364 	moal_handle *handle = (moal_handle *)pmoal;
1365 	if (handle->ops.write_reg)
1366 		ret = handle->ops.write_reg(handle, reg, data);
1367 	return ret;
1368 }
1369 
1370 /**
1371  *  @brief This function reads data from card register.
1372  *
1373  *  @param pmoal Pointer to the MOAL context
1374  *  @param reg          register offset
1375  *  @param data         value
1376  *
1377  *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1378  */
1379 mlan_status moal_read_reg(t_void *pmoal, t_u32 reg, t_u32 *data)
1380 {
1381 	int ret = MLAN_STATUS_FAILURE;
1382 	moal_handle *handle = (moal_handle *)pmoal;
1383 	if (handle->ops.read_reg)
1384 		ret = handle->ops.read_reg(handle, reg, data);
1385 	return ret;
1386 }
1387 
1388 #endif /* SDIO || PCIE */
1389 
1390 #if defined(STA_CFG80211) && defined(UAP_CFG80211)
1391 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
1392 /**
1393  *  @brief This function uploads the packet to the network stack monitor
1394  * interface
1395  *
1396  *  @param handle Pointer to the MOAL context
1397  *  @param pmbuf    Pointer to mlan_buffer
1398  *
1399  *  @return  MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING/MLAN_STATUS_FAILURE
1400  */
1401 static mlan_status moal_recv_packet_to_mon_if(moal_handle *handle,
1402 					      pmlan_buffer pmbuf)
1403 {
1404 	mlan_status status = MLAN_STATUS_SUCCESS;
1405 	struct sk_buff *skb = NULL;
1406 	struct radiotap_header *rth = NULL;
1407 	radiotap_info rt_info = {};
1408 	t_u8 format = 0;
1409 	t_u8 bw = 0;
1410 	t_u8 gi = 0;
1411 	t_u8 ldpc = 0;
1412 	t_u8 chan_num;
1413 	t_u8 band = 0;
1414 	struct ieee80211_hdr *dot11_hdr = NULL;
1415 	t_u8 *payload = NULL;
1416 	t_u32 vht_sig1 = 0;
1417 	t_u32 vht_sig2 = 0;
1418 	ENTER();
1419 	if (!pmbuf->pdesc) {
1420 		LEAVE();
1421 		return status;
1422 	}
1423 
1424 	skb = (struct sk_buff *)pmbuf->pdesc;
1425 
1426 	if ((handle->mon_if) && netif_running(handle->mon_if->mon_ndev)) {
1427 		if (handle->mon_if->radiotap_enabled) {
1428 			if (skb_headroom(skb) < sizeof(*rth)) {
1429 				PRINTM(MERROR,
1430 				       "%s No space to add Radio TAP header\n",
1431 				       __func__);
1432 				status = MLAN_STATUS_FAILURE;
1433 				handle->mon_if->stats.rx_dropped++;
1434 				goto done;
1435 			}
1436 			dot11_hdr =
1437 				(struct ieee80211_hdr *)(pmbuf->pbuf +
1438 							 pmbuf->data_offset);
1439 			moal_memcpy_ext(handle, &rt_info,
1440 					pmbuf->pbuf + pmbuf->data_offset -
1441 						sizeof(rt_info),
1442 					sizeof(rt_info), sizeof(rt_info));
1443 			ldpc = (rt_info.rate_info.rate_info & 0x20) >> 5;
1444 			format = (rt_info.rate_info.rate_info & 0x18) >> 3;
1445 			bw = (rt_info.rate_info.rate_info & 0x06) >> 1;
1446 			gi = rt_info.rate_info.rate_info & 0x01;
1447 			skb_push(skb, sizeof(*rth));
1448 			rth = (struct radiotap_header *)skb->data;
1449 			memset(skb->data, 0, sizeof(*rth));
1450 			rth->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
1451 			rth->hdr.it_pad = 0;
1452 			rth->hdr.it_len = cpu_to_le16(sizeof(*rth));
1453 			rth->hdr.it_present = cpu_to_le32(
1454 				(1 << IEEE80211_RADIOTAP_TSFT) |
1455 				(1 << IEEE80211_RADIOTAP_FLAGS) |
1456 				(1 << IEEE80211_RADIOTAP_CHANNEL) |
1457 				(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
1458 				(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
1459 				(1 << IEEE80211_RADIOTAP_ANTENNA));
1460 			/** Timstamp */
1461 			rth->body.timestamp = woal_cpu_to_le64(jiffies);
1462 			/** Flags */
1463 			rth->body.flags = (rt_info.extra_info.flags &
1464 					   ~(RADIOTAP_FLAGS_USE_SGI_HT |
1465 					     RADIOTAP_FLAGS_WITH_FRAGMENT |
1466 					     RADIOTAP_FLAGS_WEP_ENCRYPTION |
1467 					     RADIOTAP_FLAGS_FAILED_FCS_CHECK));
1468 			/** reverse fail fcs, 1 means pass FCS in FW, but means
1469 			 * fail FCS in radiotap */
1470 			rth->body.flags |= (~rt_info.extra_info.flags) &
1471 					   RADIOTAP_FLAGS_FAILED_FCS_CHECK;
1472 			if ((format == MLAN_RATE_FORMAT_HT) && (gi == 1))
1473 				rth->body.flags |= RADIOTAP_FLAGS_USE_SGI_HT;
1474 			if (ieee80211_is_mgmt(dot11_hdr->frame_control) ||
1475 			    ieee80211_is_data(dot11_hdr->frame_control)) {
1476 				if ((ieee80211_has_morefrags(
1477 					    dot11_hdr->frame_control)) ||
1478 				    (!ieee80211_is_first_frag(
1479 					    dot11_hdr->seq_ctrl))) {
1480 					rth->body.flags |=
1481 						RADIOTAP_FLAGS_WITH_FRAGMENT;
1482 				}
1483 			}
1484 			if (ieee80211_is_data(dot11_hdr->frame_control) &&
1485 			    ieee80211_has_protected(dot11_hdr->frame_control)) {
1486 				payload = (t_u8 *)dot11_hdr +
1487 					  ieee80211_hdrlen(
1488 						  dot11_hdr->frame_control);
1489 				if (!(*(payload + 3) & 0x20)) /** ExtIV bit
1490 								 shall be 0 for
1491 								 WEP frame */
1492 					rth->body.flags |=
1493 						RADIOTAP_FLAGS_WEP_ENCRYPTION;
1494 			}
1495 			/** Rate, t_u8 only apply for LG mode */
1496 			if (format == MLAN_RATE_FORMAT_LG) {
1497 				rth->hdr.it_present |= cpu_to_le32(
1498 					1 << IEEE80211_RADIOTAP_RATE);
1499 				rth->body.rate = rt_info.rate_info.bitrate;
1500 			}
1501 			/** Channel */
1502 			rth->body.channel.flags = 0;
1503 			if (rt_info.chan_num)
1504 				chan_num = rt_info.chan_num;
1505 			else
1506 				chan_num =
1507 					handle->mon_if->band_chan_cfg.channel;
1508 			band = (chan_num <= 14) ? IEEE80211_BAND_2GHZ :
1509 						  IEEE80211_BAND_5GHZ;
1510 			rth->body.channel.frequency = woal_cpu_to_le16(
1511 				ieee80211_channel_to_frequency(chan_num, band));
1512 			rth->body.channel.flags |=
1513 				woal_cpu_to_le16((band == IEEE80211_BAND_2GHZ) ?
1514 							 CHANNEL_FLAGS_2GHZ :
1515 							 CHANNEL_FLAGS_5GHZ);
1516 			if (rth->body.channel.flags &
1517 			    woal_cpu_to_le16(CHANNEL_FLAGS_2GHZ))
1518 				rth->body.channel.flags |= woal_cpu_to_le16(
1519 					CHANNEL_FLAGS_DYNAMIC_CCK_OFDM);
1520 			else
1521 				rth->body.channel.flags |=
1522 					woal_cpu_to_le16(CHANNEL_FLAGS_OFDM);
1523 			if (handle->mon_if->chandef.chan &&
1524 			    (handle->mon_if->chandef.chan->flags &
1525 			     (IEEE80211_CHAN_PASSIVE_SCAN |
1526 			      IEEE80211_CHAN_RADAR)))
1527 				rth->body.channel.flags |= woal_cpu_to_le16(
1528 					CHANNEL_FLAGS_ONLY_PASSIVSCAN_ALLOW);
1529 			/** Antenna */
1530 			rth->body.antenna_signal = -(rt_info.nf - rt_info.snr);
1531 			rth->body.antenna_noise = -rt_info.nf;
1532 			/* Convert FW antenna value to radiotap spec */
1533 			rth->body.antenna = (t_u16)rt_info.antenna >> 1;
1534 			/** MCS */
1535 			if (format == MLAN_RATE_FORMAT_HT) {
1536 				rth->hdr.it_present |= cpu_to_le32(
1537 					1 << IEEE80211_RADIOTAP_MCS);
1538 				rth->body.u.mcs.known =
1539 					rt_info.extra_info.mcs_known;
1540 				rth->body.u.mcs.flags =
1541 					rt_info.extra_info.mcs_flags;
1542 				/** MCS mcs */
1543 				rth->body.u.mcs.known |=
1544 					MCS_KNOWN_MCS_INDEX_KNOWN;
1545 				rth->body.u.mcs.mcs =
1546 					rt_info.rate_info.mcs_index;
1547 				/** MCS bw */
1548 				rth->body.u.mcs.known |= MCS_KNOWN_BANDWIDTH;
1549 				rth->body.u.mcs.flags &= ~(0x03); /** Clear,
1550 								     20MHz as
1551 								     default */
1552 				if (bw == 1)
1553 					rth->body.u.mcs.flags |= RX_BW_40;
1554 				/** MCS gi */
1555 				rth->body.u.mcs.known |=
1556 					MCS_KNOWN_GUARD_INTERVAL;
1557 				rth->body.u.mcs.flags &= ~(1 << 2);
1558 				if (gi)
1559 					rth->body.u.mcs.flags |= gi << 2;
1560 				/** MCS FEC */
1561 				rth->body.u.mcs.known |= MCS_KNOWN_FEC_TYPE;
1562 				rth->body.u.mcs.flags &= ~(1 << 4);
1563 				if (ldpc)
1564 					rth->body.u.mcs.flags |= ldpc << 4;
1565 			}
1566 			/** VHT */
1567 			if (format == MLAN_RATE_FORMAT_VHT) {
1568 				vht_sig1 = rt_info.extra_info.vht_sig1;
1569 				vht_sig2 = rt_info.extra_info.vht_sig2;
1570 				/** Present Flag */
1571 				rth->hdr.it_present |= cpu_to_le32(
1572 					1 << IEEE80211_RADIOTAP_VHT);
1573 				/** STBC */
1574 				rth->body.u.vht.known |=
1575 					woal_cpu_to_le16(VHT_KNOWN_STBC);
1576 				if (vht_sig1 & MBIT(3))
1577 					rth->body.u.vht.flags |= VHT_FLAG_STBC;
1578 				/** TXOP_PS_NA */
1579 				/** TODO: Not support now */
1580 				/** GI */
1581 				rth->body.u.vht.known |=
1582 					woal_cpu_to_le16(VHT_KNOWN_GI);
1583 				if (vht_sig2 & MBIT(0))
1584 					rth->body.u.vht.flags |= VHT_FLAG_SGI;
1585 				/** SGI NSYM DIS */
1586 				rth->body.u.vht.known |= woal_cpu_to_le16(
1587 					VHT_KNOWN_SGI_NSYM_DIS);
1588 				if (vht_sig2 & MBIT(1))
1589 					rth->body.u.vht.flags |=
1590 						VHT_FLAG_SGI_NSYM_M10_9;
1591 				/** LDPC_EXTRA_OFDM_SYM */
1592 				/** TODO: Not support now */
1593 				/** BEAMFORMED */
1594 				rth->body.u.vht.known |=
1595 					woal_cpu_to_le16(VHT_KNOWN_BEAMFORMED);
1596 				if (vht_sig2 & MBIT(8))
1597 					rth->body.u.vht.flags |=
1598 						VHT_FLAG_BEAMFORMED;
1599 				/** BANDWIDTH */
1600 				rth->body.u.vht.known |=
1601 					woal_cpu_to_le16(VHT_KNOWN_BANDWIDTH);
1602 				if (bw == 1)
1603 					rth->body.u.vht.bandwidth = RX_BW_40;
1604 				else if (bw == 2)
1605 					rth->body.u.vht.bandwidth = RX_BW_80;
1606 				/** GROUP_ID */
1607 				rth->body.u.vht.known |=
1608 					woal_cpu_to_le16(VHT_KNOWN_GROUP_ID);
1609 				rth->body.u.vht.group_id =
1610 					(vht_sig1 & (0x3F0)) >> 4;
1611 				/** PARTIAL_AID */
1612 				/** TODO: Not support now */
1613 				/** mcs_nss */
1614 				rth->body.u.vht.mcs_nss[0] = vht_sig2 & (0xF0);
1615 				/* Convert FW NSS value to radiotap spec */
1616 				rth->body.u.vht.mcs_nss[0] |=
1617 					((vht_sig1 & (0x1C00)) >> 10) + 1;
1618 				/** coding */
1619 				if (vht_sig2 & MBIT(2))
1620 					rth->body.u.vht.coding |=
1621 						VHT_CODING_LDPC_USER0;
1622 			}
1623 		}
1624 		skb_set_mac_header(skb, 0);
1625 		skb->ip_summed = CHECKSUM_UNNECESSARY;
1626 		skb->pkt_type = PACKET_OTHERHOST;
1627 		skb->protocol = htons(ETH_P_802_2);
1628 		memset(skb->cb, 0, sizeof(skb->cb));
1629 		skb->dev = handle->mon_if->mon_ndev;
1630 
1631 		handle->mon_if->stats.rx_bytes += skb->len;
1632 		handle->mon_if->stats.rx_packets++;
1633 
1634 		if (in_interrupt())
1635 			netif_rx(skb);
1636 		else
1637 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
1638 			netif_rx(skb);
1639 #else
1640 			netif_rx_ni(skb);
1641 #endif
1642 
1643 		status = MLAN_STATUS_PENDING;
1644 	}
1645 
1646 done:
1647 
1648 	LEAVE();
1649 	return status;
1650 }
1651 #endif
1652 #endif
1653 
1654 /**
1655  *  @brief This function uploads amsdu packet to the network stack
1656  *
1657  *  @param pmoal Pointer to the MOAL context
1658  *  @param pmbuf    Pointer to the mlan buffer structure
1659  *
1660  *  @return         MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE
1661  */
1662 mlan_status moal_recv_amsdu_packet(t_void *pmoal, pmlan_buffer pmbuf)
1663 {
1664 	mlan_status status = MLAN_STATUS_FAILURE;
1665 	struct sk_buff *skb = NULL;
1666 	struct sk_buff *frame = NULL;
1667 	int remaining;
1668 	const struct ethhdr *eth;
1669 	u8 dst[ETH_ALEN], src[ETH_ALEN];
1670 	moal_handle *handle = (moal_handle *)pmoal;
1671 	moal_private *priv = NULL;
1672 	struct net_device *netdev = NULL;
1673 	u8 *payload;
1674 	mlan_buffer mbuf;
1675 	t_u8 drop = 0;
1676 	t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {0xaa, 0xaa, 0x03,
1677 						      0x00, 0x00, 0x00};
1678 
1679 	wifi_timeval t1, t2;
1680 	t_s32 delay;
1681 	t_u32 in_ts_sec = 0;
1682 	t_u32 in_ts_usec = 0;
1683 
1684 	ENTER();
1685 	if (!pmbuf) {
1686 		PRINTM(MERROR, "%s: pmbuf is null\n", __func__);
1687 		goto done;
1688 	}
1689 
1690 	memset(&mbuf, 0, sizeof(mlan_buffer));
1691 	mbuf.bss_index = pmbuf->bss_index;
1692 
1693 	priv = woal_bss_index_to_priv(pmoal, pmbuf->bss_index);
1694 	if (priv == NULL) {
1695 		PRINTM(MERROR, "%s: priv is null\n", __func__);
1696 		goto done;
1697 	}
1698 	netdev = priv->netdev;
1699 	skb = (struct sk_buff *)pmbuf->pdesc;
1700 	if (!skb)
1701 		goto done;
1702 
1703 	skb_reserve(skb, pmbuf->data_offset);
1704 	if (skb_tailroom(skb) < (int)pmbuf->data_len) {
1705 		PRINTM(MERROR, "skb overflow: tail room=%d, data_len=%d\n",
1706 		       skb_tailroom(skb), pmbuf->data_len);
1707 		goto done;
1708 	}
1709 	skb_put(skb, pmbuf->data_len);
1710 
1711 	// rx_trace 8
1712 	if (handle->tp_acnt.on) {
1713 		moal_tp_accounting(pmoal, skb, RX_DROP_P4);
1714 		woal_get_monotonic_time(&t1);
1715 		in_ts_sec = t1.time_sec;
1716 		in_ts_usec = t1.time_usec;
1717 		if (pmbuf->in_ts_sec) {
1718 			pmbuf->out_ts_sec = t1.time_sec;
1719 			pmbuf->out_ts_usec = t1.time_usec;
1720 		}
1721 	}
1722 	if (handle->tp_acnt.drop_point == RX_DROP_P4) {
1723 		status = MLAN_STATUS_PENDING;
1724 		dev_kfree_skb(skb);
1725 		goto done;
1726 	}
1727 
1728 	while (skb != frame) {
1729 		__be16 len;
1730 		u8 padding;
1731 		unsigned int subframe_len;
1732 		eth = (struct ethhdr *)skb->data;
1733 		len = ntohs(eth->h_proto);
1734 		subframe_len = sizeof(struct ethhdr) + len;
1735 		remaining = skb->len;
1736 
1737 		if (subframe_len > remaining) {
1738 			PRINTM(MERROR,
1739 			       "Error in len: remaining = %d, subframe_len = %d\n",
1740 			       remaining, subframe_len);
1741 			break;
1742 		}
1743 		memcpy(dst, eth->h_dest, ETH_ALEN);
1744 		memcpy(src, eth->h_source, ETH_ALEN);
1745 
1746 		padding = (4 - subframe_len) & 0x3;
1747 
1748 		skb_pull(skb, sizeof(struct ethhdr));
1749 
1750 		if (remaining <= (subframe_len + padding)) {
1751 			frame = skb;
1752 			status = MLAN_STATUS_PENDING;
1753 		} else {
1754 			frame = skb_clone(skb, GFP_ATOMIC);
1755 			skb_trim(frame, len);
1756 			eth = (struct ethhdr *)skb_pull(skb, len + padding);
1757 			if (!eth) {
1758 				PRINTM(MERROR, "Invalid amsdu packet\n");
1759 				break;
1760 			}
1761 		}
1762 		skb_reset_network_header(frame);
1763 		frame->dev = netdev;
1764 		frame->priority = skb->priority;
1765 		payload = frame->data;
1766 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
1767 		if (ether_addr_equal(payload, rfc1042_eth_hdr)) {
1768 #else
1769 		if (!memcmp(payload, rfc1042_eth_hdr,
1770 			    sizeof(rfc1042_eth_hdr))) {
1771 #endif
1772 			/* Remove RFC1042 */
1773 			skb_pull(frame, 6);
1774 			memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
1775 			memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
1776 		} else {
1777 			memcpy(skb_push(frame, sizeof(__be16)), &len,
1778 			       sizeof(__be16));
1779 			memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
1780 			memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
1781 		}
1782 		mbuf.pbuf = frame->data;
1783 		mbuf.data_len = frame->len;
1784 		mlan_process_deaggr_pkt(handle->pmlan_adapter, &mbuf, &drop);
1785 		if (drop) {
1786 			dev_kfree_skb(frame);
1787 			continue;
1788 		}
1789 		frame->protocol = eth_type_trans(frame, netdev);
1790 		frame->ip_summed = CHECKSUM_NONE;
1791 		if (in_interrupt())
1792 			netif_rx(frame);
1793 		else {
1794 			if (atomic_read(&handle->rx_pending) >
1795 			    MAX_RX_PENDING_THRHLD)
1796 				netif_rx(frame);
1797 			else {
1798 				if (handle->params.net_rx == MTRUE) {
1799 					local_bh_disable();
1800 					netif_receive_skb(frame);
1801 					local_bh_enable();
1802 				} else {
1803 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
1804 					netif_rx(frame);
1805 #else
1806 					netif_rx_ni(frame);
1807 #endif
1808 				}
1809 			}
1810 		}
1811 	}
1812 	if (handle->tp_acnt.on) {
1813 		if (pmbuf->in_ts_sec)
1814 			moal_tp_accounting(handle, pmbuf, RX_TIME_PKT);
1815 
1816 		woal_get_monotonic_time(&t2);
1817 		delay = (t_s32)(t2.time_sec - in_ts_sec) * 1000000;
1818 		delay += (t_s32)(t2.time_usec - in_ts_usec);
1819 		moal_amsdu_tp_accounting(pmoal, delay, 0);
1820 	}
1821 done:
1822 	if (status == MLAN_STATUS_PENDING)
1823 		atomic_dec(&handle->mbufalloc_count);
1824 	LEAVE();
1825 	return status;
1826 }
1827 
1828 /**
1829  *  @brief This function uploads the packet to the network stack
1830  *
1831  *  @param pmoal Pointer to the MOAL context
1832  *  @param pmbuf    Pointer to the mlan buffer structure
1833  *
1834  *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1835  */
1836 mlan_status moal_recv_packet(t_void *pmoal, pmlan_buffer pmbuf)
1837 {
1838 	mlan_status status = MLAN_STATUS_SUCCESS;
1839 	moal_private *priv = NULL;
1840 	struct sk_buff *skb = NULL;
1841 	moal_handle *handle = (moal_handle *)pmoal;
1842 #if defined(USB) || defined(PCIE)
1843 	t_u32 max_rx_data_size = MLAN_RX_DATA_BUF_SIZE;
1844 #endif
1845 	dot11_rxcontrol rxcontrol;
1846 	t_u8 rx_info_flag = MFALSE;
1847 	int j;
1848 	struct ethhdr *ethh = NULL;
1849 	struct net_device *netdev = NULL;
1850 
1851 	ENTER();
1852 	if (pmbuf) {
1853 #ifdef USB
1854 #ifdef STA_SUPPORT
1855 		if (IS_USB(handle->card_type)) {
1856 			struct usb_card_rec *cardp =
1857 				(struct usb_card_rec *)handle->card;
1858 			if (cardp->rx_deaggr_ctrl.enable) {
1859 				max_rx_data_size =
1860 					cardp->rx_deaggr_ctrl.aggr_max;
1861 				if (cardp->rx_deaggr_ctrl.aggr_mode ==
1862 				    MLAN_USB_AGGR_MODE_NUM) {
1863 					max_rx_data_size *=
1864 						MAX(MLAN_USB_MAX_PKT_SIZE,
1865 						    cardp->rx_deaggr_ctrl
1866 							    .aggr_align);
1867 					max_rx_data_size =
1868 						MAX(max_rx_data_size,
1869 						    MLAN_RX_DATA_BUF_SIZE);
1870 				}
1871 			}
1872 		}
1873 #endif
1874 #endif
1875 
1876 		priv = woal_bss_index_to_priv(pmoal, pmbuf->bss_index);
1877 		skb = (struct sk_buff *)pmbuf->pdesc;
1878 		if (priv) {
1879 			if (skb) {
1880 				skb_reserve(skb, pmbuf->data_offset);
1881 				if (skb_tailroom(skb) < (int)pmbuf->data_len) {
1882 					PRINTM(MERROR,
1883 					       "skb overflow: tail room=%d, data_len=%d\n",
1884 					       skb_tailroom(skb),
1885 					       pmbuf->data_len);
1886 					status = MLAN_STATUS_FAILURE;
1887 					priv->stats.rx_dropped++;
1888 					goto done;
1889 				}
1890 				skb_put(skb, pmbuf->data_len);
1891 #if defined(STA_CFG80211) && defined(UAP_CFG80211)
1892 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
1893 				if (pmbuf->flags & MLAN_BUF_FLAG_NET_MONITOR) {
1894 					status = moal_recv_packet_to_mon_if(
1895 						pmoal, pmbuf);
1896 					if (status == MLAN_STATUS_PENDING)
1897 						atomic_dec(
1898 							&handle->mbufalloc_count);
1899 					goto done;
1900 				}
1901 #endif
1902 #endif
1903 				pmbuf->pdesc = NULL;
1904 				pmbuf->pbuf = NULL;
1905 				pmbuf->data_offset = pmbuf->data_len = 0;
1906 				/* pkt been submit to kernel, no need to
1907 				 * free by mlan*/
1908 				status = MLAN_STATUS_PENDING;
1909 				atomic_dec(&handle->mbufalloc_count);
1910 			} else {
1911 				PRINTM(MERROR, "%s without skb attach!!!\n",
1912 				       __func__);
1913 #if defined(STA_CFG80211) && defined(UAP_CFG80211)
1914 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
1915 				/** drop the packet without skb in
1916 				 * monitor mode */
1917 				if (pmbuf->flags & MLAN_BUF_FLAG_NET_MONITOR) {
1918 					PRINTM(MINFO,
1919 					       "%s Drop packet without skb\n",
1920 					       __func__);
1921 					status = MLAN_STATUS_FAILURE;
1922 					priv->stats.rx_dropped++;
1923 					goto done;
1924 				}
1925 #endif
1926 #endif
1927 				skb = dev_alloc_skb(pmbuf->data_len +
1928 						    MLAN_NET_IP_ALIGN);
1929 				if (!skb) {
1930 					PRINTM(MERROR, "%s fail to alloc skb\n",
1931 					       __func__);
1932 					status = MLAN_STATUS_FAILURE;
1933 					priv->stats.rx_dropped++;
1934 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
1935 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
1936 					woal_packet_fate_monitor(
1937 						priv, PACKET_TYPE_RX,
1938 						RX_PKT_FATE_DRV_DROP_NOBUFS,
1939 						FRAME_TYPE_ETHERNET_II, 0, 0,
1940 						(t_u8 *)(pmbuf->pbuf +
1941 							 pmbuf->data_offset),
1942 						pmbuf->data_len);
1943 #endif
1944 #endif
1945 					goto done;
1946 				}
1947 				skb_reserve(skb, MLAN_NET_IP_ALIGN);
1948 				moal_memcpy_ext(handle, skb->data,
1949 						(t_u8 *)(pmbuf->pbuf +
1950 							 pmbuf->data_offset),
1951 						pmbuf->data_len,
1952 						pmbuf->data_len);
1953 				skb_put(skb, pmbuf->data_len);
1954 			}
1955 			ethh = (struct ethhdr *)(skb->data);
1956 			if (ntohs(ethh->h_proto) == ETH_P_PAE)
1957 				PRINTM(MEVENT,
1958 				       "wlan: %s Rx EAPOL pkt from " MACSTR
1959 				       "\n",
1960 				       priv->netdev->name,
1961 				       MAC2STR(ethh->h_source));
1962 			if (!netdev)
1963 				netdev = priv->netdev;
1964 			skb->dev = netdev;
1965 			skb->protocol = eth_type_trans(skb, netdev);
1966 			skb->ip_summed = CHECKSUM_NONE;
1967 
1968 #if defined(USB) || defined(PCIE)
1969 			/* This is only required only in case of 11n and
1970 			 USB as we alloc if(skb_tailroom(skb) <
1971 			 pmbuf->data_len){ PRINTM(MERROR,"skb overflow:
1972 			 tail room=%d, data_len\n", skb_tailroom(skb),
1973 			 pmbuf->data_len); status = MLAN_STATUS_FAILURE;
1974 				priv->stats.rx_dropped++;
1975 				goto done;
1976 			    }
1977 			 * a buffer of 4K only if its 11N (to be able to
1978 			 receive 4K AMSDU
1979 			 * packets). In case of SD we allocate buffers
1980 			 based on the size
1981 			 * of packet and hence this is not needed.
1982 			*/
1983 			/* Modifying the truesize here as our allocation
1984 			 * for each skb is 4K but we only receive 2K
1985 			 * packets and this cause the kernel to start
1986 			 * dropping packets in case where application
1987 			 * has allocated buffer based on 2K size i.e. if
1988 			 * there a 64K packet received (in IP fragments
1989 			 * and application allocates 64K to receive this
1990 			 * packet but this packet would almost double up
1991 			 * because we allocate each 1.5K fragment in 4K
1992 			 * and pass it up. As soon as the 64K limit hits
1993 			 * kernel will start to drop rest of the
1994 			 * fragments. Currently we fail the
1995 			 * Filesndl-ht.scr script for UDP, hence this
1996 			 * fix
1997 			 */
1998 			if (!IS_SD(priv->phandle->card_type)) {
1999 				if (skb->truesize > max_rx_data_size)
2000 					skb->truesize +=
2001 						(skb->len - max_rx_data_size);
2002 			}
2003 #endif
2004 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
2005 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2006 			if (!woal_filter_packet(priv, skb->data, skb->len, 0)) {
2007 				PRINTM(MEVENT, "drop filtered packet %s\n",
2008 				       priv->netdev->name);
2009 				status = MLAN_STATUS_FAILURE;
2010 				priv->stats.rx_dropped++;
2011 				woal_packet_fate_monitor(
2012 					priv, PACKET_TYPE_RX,
2013 					RX_PKT_FATE_DRV_DROP_FILTER,
2014 					FRAME_TYPE_ETHERNET_II, 0, 0, skb->data,
2015 					skb->len);
2016 				dev_kfree_skb(skb);
2017 				goto done;
2018 			}
2019 #endif
2020 #endif
2021 			priv->stats.rx_bytes += skb->len;
2022 			priv->stats.rx_packets++;
2023 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
2024 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2025 			woal_packet_fate_monitor(priv, PACKET_TYPE_RX,
2026 						 RX_PKT_FATE_SUCCESS,
2027 						 FRAME_TYPE_ETHERNET_II, 0, 0,
2028 						 skb->data, skb->len);
2029 #endif
2030 #endif
2031 #ifdef ANDROID_KERNEL
2032 			if (handle->params.wakelock_timeout) {
2033 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
2034 				__pm_wakeup_event(
2035 					&handle->ws,
2036 					handle->params.wakelock_timeout);
2037 #else
2038 				wake_lock_timeout(
2039 					&handle->wake_lock,
2040 					msecs_to_jiffies(
2041 						handle->params
2042 							.wakelock_timeout));
2043 #endif
2044 			}
2045 #endif
2046 			if (priv->rx_protocols.protocol_num) {
2047 				for (j = 0; j < priv->rx_protocols.protocol_num;
2048 				     j++) {
2049 					if (htons((__force t_u16)
2050 							  skb->protocol) ==
2051 					    priv->rx_protocols.protocols[j])
2052 						rx_info_flag = MTRUE;
2053 				}
2054 			}
2055 			if (rx_info_flag &&
2056 			    (skb_tailroom(skb) > (int)sizeof(rxcontrol))) {
2057 				memset(&rxcontrol, 0, sizeof(dot11_rxcontrol));
2058 				rxcontrol.datarate = pmbuf->u.rx_info.data_rate;
2059 				rxcontrol.channel = pmbuf->u.rx_info.channel;
2060 				rxcontrol.antenna = pmbuf->u.rx_info.antenna;
2061 				rxcontrol.rssi = pmbuf->u.rx_info.rssi;
2062 				skb_put(skb, sizeof(dot11_rxcontrol));
2063 				memmove(skb->data + sizeof(dot11_rxcontrol),
2064 					skb->data,
2065 					skb->len - sizeof(dot11_rxcontrol));
2066 				moal_memcpy_ext(handle, skb->data, &rxcontrol,
2067 						sizeof(dot11_rxcontrol),
2068 						sizeof(dot11_rxcontrol));
2069 			}
2070 			// rx_trace 8
2071 			if (priv->phandle->tp_acnt.on) {
2072 				wifi_timeval t;
2073 				moal_tp_accounting(handle, skb, RX_DROP_P4);
2074 				if (pmbuf && pmbuf->in_ts_sec) {
2075 					woal_get_monotonic_time(&t);
2076 					pmbuf->out_ts_sec = t.time_sec;
2077 					pmbuf->out_ts_usec = t.time_usec;
2078 				}
2079 			}
2080 			if (priv->phandle->tp_acnt.drop_point == RX_DROP_P4) {
2081 				status = MLAN_STATUS_PENDING;
2082 				dev_kfree_skb(skb);
2083 			} else if (in_interrupt())
2084 				netif_rx(skb);
2085 			else {
2086 				if (atomic_read(&handle->rx_pending) >
2087 				    MAX_RX_PENDING_THRHLD)
2088 					netif_rx(skb);
2089 				else {
2090 					if (handle->params.net_rx == MTRUE) {
2091 						local_bh_disable();
2092 						netif_receive_skb(skb);
2093 						local_bh_enable();
2094 					} else {
2095 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
2096 						netif_rx(skb);
2097 #else
2098 						netif_rx_ni(skb);
2099 #endif
2100 					}
2101 				}
2102 			}
2103 			if (priv->phandle->tp_acnt.on) {
2104 				if (pmbuf && pmbuf->in_ts_sec)
2105 					moal_tp_accounting(handle, pmbuf,
2106 							   RX_TIME_PKT);
2107 			}
2108 		}
2109 	}
2110 done:
2111 	LEAVE();
2112 	return status;
2113 }
2114 
2115 #if defined(PCIE) || defined(SDIO)
2116 void woal_request_busfreq_pmqos_add(t_void *handle)
2117 {
2118 	moal_handle *pmhandle = (moal_handle *)handle;
2119 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70)
2120 #ifdef IMX_SUPPORT
2121 	if (IS_PCIE(pmhandle->card_type)) {
2122 		request_bus_freq(BUS_FREQ_HIGH);
2123 	}
2124 #endif
2125 #endif
2126 	if (moal_extflg_isset(pmhandle, EXT_PMQOS)) {
2127 #if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0)
2128 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
2129 #ifdef IMX_SUPPORT
2130 		if (!pm_qos_request_active(&pmhandle->woal_pm_qos_req))
2131 			pm_qos_add_request(&pmhandle->woal_pm_qos_req,
2132 					   PM_QOS_CPU_DMA_LATENCY, 0);
2133 		else
2134 			PRINTM(MERROR, "PM-QOS request already active\n");
2135 #endif
2136 #endif
2137 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
2138 #ifdef IMX_SUPPORT
2139 		if (!cpu_latency_qos_request_active(&pmhandle->woal_pm_qos_req))
2140 			cpu_latency_qos_add_request(&pmhandle->woal_pm_qos_req,
2141 						    0);
2142 		else
2143 			PRINTM(MERROR, "PM-QOS request already active\n");
2144 #endif
2145 #endif
2146 	}
2147 	return;
2148 }
2149 
2150 void woal_release_busfreq_pmqos_remove(t_void *handle)
2151 {
2152 	moal_handle *pmhandle = (moal_handle *)handle;
2153 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 70)
2154 #ifdef IMX_SUPPORT
2155 	if (IS_PCIE(pmhandle->card_type)) {
2156 		release_bus_freq(BUS_FREQ_HIGH);
2157 	}
2158 #endif
2159 #endif
2160 
2161 	if (moal_extflg_isset(pmhandle, EXT_PMQOS)) {
2162 #if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 6, 0)
2163 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
2164 #ifdef IMX_SUPPORT
2165 		if (pm_qos_request_active(&pmhandle->woal_pm_qos_req))
2166 			pm_qos_remove_request(&pmhandle->woal_pm_qos_req);
2167 		else
2168 			PRINTM(MERROR, "PM-QOS request already removed\n");
2169 #endif
2170 #endif
2171 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0)
2172 #ifdef IMX_SUPPORT
2173 		if (cpu_latency_qos_request_active(&pmhandle->woal_pm_qos_req))
2174 			cpu_latency_qos_remove_request(
2175 				&pmhandle->woal_pm_qos_req);
2176 		else
2177 			PRINTM(MERROR, "PM-QOS request already removed\n");
2178 #endif
2179 #endif
2180 	}
2181 	return;
2182 }
2183 #endif /*defined(PCIE) || defined(SDIO)*/
2184 
2185 /**
2186  *  @brief This function checks media_connected state for
2187  *  BSS types UAP/STA/P2P_GO/GC
2188  *
2189  *  @param pmoal Pointer to the MOAL context
2190  *
2191  */
2192 int woal_check_media_connected(t_void *pmoal)
2193 {
2194 	int i;
2195 	moal_handle *pmhandle = (moal_handle *)pmoal;
2196 	moal_private *pmpriv = NULL;
2197 	for (i = 0; i < pmhandle->priv_num; i++) {
2198 		pmpriv = pmhandle->priv[i];
2199 		if (!pmpriv)
2200 			continue;
2201 		if (pmpriv->media_connected == MTRUE) {
2202 			return MTRUE;
2203 		}
2204 	}
2205 	return MFALSE;
2206 }
2207 
2208 /**
2209  *  @brief This function checks connect and disconnect
2210  *  events for BSS types UAP/STA/P2P_GO/GC
2211  *
2212  *  @param pmoal Pointer to the MOAL context
2213  *
2214  */
2215 void moal_connection_status_check_pmqos(t_void *pmoal)
2216 {
2217 	moal_handle *pmhandle = (moal_handle *)pmoal;
2218 	if ((woal_check_media_connected(pmoal) == MTRUE)) {
2219 		if (pmhandle->request_pm == MFALSE) {
2220 			pmhandle->request_pm = MTRUE;
2221 #if defined(PCIE) || defined(SDIO)
2222 			woal_request_busfreq_pmqos_add(pmhandle);
2223 #endif
2224 		}
2225 	} else {
2226 		if (pmhandle->request_pm == MTRUE) {
2227 			pmhandle->request_pm = MFALSE;
2228 #if defined(PCIE) || defined(SDIO)
2229 			woal_release_busfreq_pmqos_remove(pmhandle);
2230 #endif
2231 		}
2232 	}
2233 }
2234 
2235 #ifdef UAP_SUPPORT
2236 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
2237 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
2238 /**
2239  * @brief   Handle RX MGMT PKT event
2240  *
2241  * @param priv          A pointer moal_private structure
2242  * @param pkt        A pointer to pkt
2243  * @param len        length of pkt
2244  *
2245  * @return          N/A
2246  */
2247 static void woal_rx_mgmt_pkt_event(moal_private *priv, t_u8 *pkt, t_u16 len)
2248 {
2249 	struct woal_event *evt;
2250 	unsigned long flags;
2251 	moal_handle *handle = priv->phandle;
2252 
2253 	evt = kzalloc(sizeof(struct woal_event), GFP_ATOMIC);
2254 	if (evt) {
2255 		evt->priv = priv;
2256 		evt->type = WOAL_EVENT_RX_MGMT_PKT;
2257 		evt->evt.event_len = len;
2258 		moal_memcpy_ext(priv->phandle, evt->evt.event_buf, pkt,
2259 				evt->evt.event_len, sizeof(evt->evt.event_buf));
2260 		INIT_LIST_HEAD(&evt->link);
2261 		spin_lock_irqsave(&handle->evt_lock, flags);
2262 		list_add_tail(&evt->link, &handle->evt_queue);
2263 		spin_unlock_irqrestore(&handle->evt_lock, flags);
2264 		queue_work(handle->evt_workqueue, &handle->evt_work);
2265 	}
2266 }
2267 #endif
2268 #endif
2269 #endif
2270 
2271 /**
2272  *  @brief This function handles event receive
2273  *
2274  *  @param pmoal Pointer to the MOAL context
2275  *  @param pmevent  Pointer to the mlan event structure
2276  *
2277  *  @return         MLAN_STATUS_SUCCESS
2278  */
2279 mlan_status moal_recv_event(t_void *pmoal, pmlan_event pmevent)
2280 {
2281 #ifdef STA_SUPPORT
2282 	int custom_len = 0;
2283 #ifdef STA_CFG80211
2284 	unsigned long flags;
2285 #endif
2286 #endif
2287 	moal_private *priv = NULL;
2288 #if defined(STA_SUPPORT) || defined(UAP_SUPPORT)
2289 	moal_private *pmpriv = NULL;
2290 #endif
2291 #if defined(STA_WEXT) || defined(UAP_WEXT)
2292 #if defined(STA_SUPPORT) || defined(UAP_WEXT)
2293 #if defined(UAP_SUPPORT) || defined(STA_WEXT)
2294 	union iwreq_data wrqu;
2295 #endif
2296 #endif
2297 #endif
2298 	mlan_ds_ps_info pm_info;
2299 	moal_handle *handle = (moal_handle *)pmoal;
2300 	moal_handle *ref_handle = NULL;
2301 
2302 #ifdef STA_CFG80211
2303 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2304 	t_u8 enable = 1;
2305 #endif
2306 	t_u8 *req_ie = NULL;
2307 	t_u16 ie_len = 0;
2308 	apinfo *pinfo = NULL, *req_tlv = NULL;
2309 	MrvlIEtypesHeader_t *tlv = NULL;
2310 	t_u16 tlv_type = 0, tlv_len = 0, tlv_buf_left = 0;
2311 #endif
2312 #ifdef STA_CFG80211
2313 	t_u8 hw_test;
2314 #endif
2315 	int cfg80211_wext;
2316 
2317 #ifdef STA_CFG80211
2318 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
2319 	struct cfg80211_roam_info *roam_info = NULL;
2320 #endif
2321 #endif
2322 	t_u16 csi_len;
2323 #ifdef STA_CFG80211
2324 	t_u8 channel_status;
2325 	moal_private *remain_priv = NULL;
2326 #endif
2327 #if defined(UAP_CFG80211) || defined(STA_CFG80211)
2328 	chan_band_info *pchan_info = NULL;
2329 #endif
2330 	t_u8 radar_detected;
2331 	t_u8 bandwidth;
2332 	t_u8 event_buf[64];
2333 	t_u8 radar_chan;
2334 #ifdef UAP_CFG80211
2335 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2336 	moal_private *cfg_priv = NULL;
2337 #endif
2338 #endif
2339 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
2340 #ifdef UAP_CFG80211
2341 	unsigned long wait_time, wait_time_ms, timeout;
2342 #endif
2343 #endif
2344 
2345 	t_u8 auto_fw_dump = MFALSE;
2346 	ENTER();
2347 	if (pmevent->event_id == MLAN_EVENT_ID_FW_DUMP_INFO) {
2348 		if (!handle->is_fw_dump_timer_set) {
2349 			PRINTM(MMSG, "FW trigger fw dump\n");
2350 			handle->is_fw_dump_timer_set = MTRUE;
2351 			woal_mod_timer(&handle->fw_dump_timer, MOAL_TIMER_5S);
2352 		}
2353 		woal_store_firmware_dump(pmoal, pmevent);
2354 		handle->driver_status = MTRUE;
2355 		wifi_status = WIFI_STATUS_FW_DUMP;
2356 		ref_handle = (moal_handle *)handle->pref_mac;
2357 		if (ref_handle)
2358 			ref_handle->driver_status = MTRUE;
2359 		goto done;
2360 	}
2361 	if ((pmevent->event_id != MLAN_EVENT_ID_DRV_DEFER_RX_WORK) &&
2362 	    (pmevent->event_id != MLAN_EVENT_ID_DRV_DEFER_HANDLING) &&
2363 	    (pmevent->event_id != MLAN_EVENT_ID_DRV_MGMT_FRAME))
2364 		PRINTM(MEVENT, "event id:0x%x\n", pmevent->event_id);
2365 #if defined(PCIE)
2366 	if (pmevent->event_id == MLAN_EVENT_ID_SSU_DUMP_FILE) {
2367 		goto done;
2368 	}
2369 #endif /* SSU_SUPPORT */
2370 	if (pmevent->event_id == MLAN_EVENT_ID_STORE_HOST_CMD_RESP) {
2371 		goto done;
2372 	}
2373 	priv = woal_bss_index_to_priv(pmoal, pmevent->bss_index);
2374 	if (priv == NULL) {
2375 		PRINTM(MERROR, "%s: priv is null\n", __func__);
2376 		goto done;
2377 	}
2378 	if (priv->netdev == NULL) {
2379 		PRINTM(MERROR, "%s: netdev is null\n", __func__);
2380 		goto done;
2381 	}
2382 
2383 	cfg80211_wext = priv->phandle->params.cfg80211_wext;
2384 #ifdef STA_CFG80211
2385 	hw_test = moal_extflg_isset(pmoal, EXT_HW_TEST);
2386 #endif
2387 	switch (pmevent->event_id) {
2388 #ifdef STA_SUPPORT
2389 	case MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED:
2390 		priv->is_adhoc_link_sensed = MTRUE;
2391 		if (!netif_carrier_ok(priv->netdev))
2392 			netif_carrier_on(priv->netdev);
2393 		woal_wake_queue(priv->netdev);
2394 #ifdef STA_WEXT
2395 		if (IS_STA_WEXT(cfg80211_wext))
2396 			woal_send_iwevcustom_event(priv,
2397 						   CUS_EVT_ADHOC_LINK_SENSED);
2398 #endif
2399 		woal_broadcast_event(priv, CUS_EVT_ADHOC_LINK_SENSED,
2400 				     strlen(CUS_EVT_ADHOC_LINK_SENSED));
2401 		break;
2402 
2403 	case MLAN_EVENT_ID_FW_ADHOC_LINK_LOST:
2404 		woal_stop_queue(priv->netdev);
2405 		if (netif_carrier_ok(priv->netdev))
2406 			netif_carrier_off(priv->netdev);
2407 		priv->is_adhoc_link_sensed = MFALSE;
2408 #ifdef STA_WEXT
2409 		if (IS_STA_WEXT(cfg80211_wext))
2410 			woal_send_iwevcustom_event(priv,
2411 						   CUS_EVT_ADHOC_LINK_LOST);
2412 #endif
2413 		woal_broadcast_event(priv, CUS_EVT_ADHOC_LINK_LOST,
2414 				     strlen(CUS_EVT_ADHOC_LINK_LOST));
2415 		break;
2416 
2417 	case MLAN_EVENT_ID_DRV_CONNECTED:
2418 #ifdef STA_WEXT
2419 		if (IS_STA_WEXT(cfg80211_wext) &&
2420 		    pmevent->event_len == ETH_ALEN) {
2421 			memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
2422 			moal_memcpy_ext(priv->phandle, wrqu.ap_addr.sa_data,
2423 					pmevent->event_buf, ETH_ALEN,
2424 					sizeof(wrqu.ap_addr.sa_data));
2425 			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2426 			wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu,
2427 					    NULL);
2428 		}
2429 #endif
2430 #ifdef STA_CFG80211
2431 		if (IS_STA_CFG80211(cfg80211_wext)) {
2432 			moal_memcpy_ext(priv->phandle, priv->cfg_bssid,
2433 					pmevent->event_buf, ETH_ALEN, ETH_ALEN);
2434 			woal_set_scan_time(priv, ACTIVE_SCAN_CHAN_TIME,
2435 					   PASSIVE_SCAN_CHAN_TIME,
2436 					   MIN_SPECIFIC_SCAN_CHAN_TIME);
2437 		}
2438 #endif
2439 		custom_len = strlen(CUS_EVT_AP_CONNECTED);
2440 		memmove(pmevent->event_buf + custom_len, pmevent->event_buf,
2441 			pmevent->event_len);
2442 		moal_memcpy_ext(priv->phandle, pmevent->event_buf,
2443 				CUS_EVT_AP_CONNECTED, custom_len, custom_len);
2444 		pmevent->event_len += custom_len;
2445 		woal_broadcast_event(priv, pmevent->event_buf,
2446 				     pmevent->event_len);
2447 		woal_update_dscp_mapping(priv);
2448 		priv->media_connected = MTRUE;
2449 		if (!netif_carrier_ok(priv->netdev))
2450 			netif_carrier_on(priv->netdev);
2451 		woal_wake_queue(priv->netdev);
2452 		moal_connection_status_check_pmqos(pmoal);
2453 		break;
2454 
2455 	case MLAN_EVENT_ID_DRV_ASSOC_SUCC_LOGGER:
2456 	case MLAN_EVENT_ID_DRV_ASSOC_FAILURE_LOGGER:
2457 	case MLAN_EVENT_ID_DRV_DISCONNECT_LOGGER:
2458 #ifdef STA_CFG80211
2459 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2460 		if (IS_STA_CFG80211(cfg80211_wext))
2461 			woal_ring_event_logger(priv, VERBOSE_RING_ID, pmevent);
2462 #endif
2463 #endif
2464 		break;
2465 
2466 	case MLAN_EVENT_ID_DRV_SCAN_REPORT:
2467 		PRINTM(MINFO, "Scan report\n");
2468 
2469 		if (priv->report_scan_result) {
2470 			priv->report_scan_result = MFALSE;
2471 #ifdef STA_CFG80211
2472 			if (IS_STA_CFG80211(cfg80211_wext)) {
2473 				if (priv->phandle->scan_request) {
2474 					PRINTM(MINFO,
2475 					       "Reporting scan results\n");
2476 					woal_inform_bss_from_scan_result(
2477 						priv, NULL, MOAL_NO_WAIT);
2478 					if (!priv->phandle->first_scan_done) {
2479 						priv->phandle->first_scan_done =
2480 							MTRUE;
2481 						woal_set_scan_time(
2482 							priv,
2483 							ACTIVE_SCAN_CHAN_TIME,
2484 							PASSIVE_SCAN_CHAN_TIME,
2485 							SPECIFIC_SCAN_CHAN_TIME);
2486 					}
2487 					spin_lock_irqsave(
2488 						&priv->phandle->scan_req_lock,
2489 						flags);
2490 					if (priv->phandle->scan_request) {
2491 						cancel_delayed_work(
2492 							&priv->phandle
2493 								 ->scan_timeout_work);
2494 						woal_cfg80211_scan_done(
2495 							priv->phandle
2496 								->scan_request,
2497 							MFALSE);
2498 						priv->phandle->scan_request =
2499 							NULL;
2500 					}
2501 					spin_unlock_irqrestore(
2502 						&priv->phandle->scan_req_lock,
2503 						flags);
2504 				}
2505 			}
2506 #endif /* STA_CFG80211 */
2507 
2508 #ifdef STA_WEXT
2509 			if (IS_STA_WEXT(cfg80211_wext)) {
2510 				memset(&wrqu, 0, sizeof(union iwreq_data));
2511 				wireless_send_event(priv->netdev, SIOCGIWSCAN,
2512 						    &wrqu, NULL);
2513 			}
2514 #endif
2515 			woal_broadcast_event(priv, (t_u8 *)&pmevent->event_id,
2516 					     sizeof(mlan_event_id));
2517 		}
2518 
2519 		if (!is_zero_timeval(priv->phandle->scan_time_start)) {
2520 			woal_get_monotonic_time(&priv->phandle->scan_time_end);
2521 			priv->phandle->scan_time += (t_u64)(
2522 				timeval_to_usec(priv->phandle->scan_time_end) -
2523 				timeval_to_usec(
2524 					priv->phandle->scan_time_start));
2525 			PRINTM(MINFO,
2526 			       "%s : start_timeval=%d:%d end_timeval=%d:%d inter=%llu scan_time=%llu\n",
2527 			       __func__,
2528 			       priv->phandle->scan_time_start.time_sec,
2529 			       priv->phandle->scan_time_start.time_usec,
2530 			       priv->phandle->scan_time_end.time_sec,
2531 			       priv->phandle->scan_time_end.time_usec,
2532 			       (t_u64)(timeval_to_usec(
2533 					       priv->phandle->scan_time_end) -
2534 				       timeval_to_usec(
2535 					       priv->phandle->scan_time_start)),
2536 			       priv->phandle->scan_time);
2537 			priv->phandle->scan_time_start.time_sec = 0;
2538 			priv->phandle->scan_time_start.time_usec = 0;
2539 		}
2540 
2541 		if (priv->phandle->scan_pending_on_block == MTRUE) {
2542 			priv->phandle->scan_pending_on_block = MFALSE;
2543 			priv->phandle->scan_priv = NULL;
2544 			MOAL_REL_SEMAPHORE(&priv->phandle->async_sem);
2545 		}
2546 		break;
2547 
2548 	case MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM:
2549 		memmove((pmevent->event_buf + strlen(CUS_EVT_OBSS_SCAN_PARAM) +
2550 			 1),
2551 			pmevent->event_buf, pmevent->event_len);
2552 		moal_memcpy_ext(priv->phandle, pmevent->event_buf,
2553 				(t_u8 *)CUS_EVT_OBSS_SCAN_PARAM,
2554 				strlen(CUS_EVT_OBSS_SCAN_PARAM),
2555 				strlen(CUS_EVT_OBSS_SCAN_PARAM));
2556 		pmevent->event_buf[strlen(CUS_EVT_OBSS_SCAN_PARAM)] = 0;
2557 		woal_broadcast_event(priv, pmevent->event_buf,
2558 				     pmevent->event_len +
2559 					     strlen(CUS_EVT_OBSS_SCAN_PARAM));
2560 
2561 #ifdef STA_WEXT
2562 		if (IS_STA_WEXT(cfg80211_wext)) {
2563 			memset(&wrqu, 0, sizeof(union iwreq_data));
2564 			wrqu.data.pointer = (t_u8 __user *)pmevent->event_buf;
2565 			wrqu.data.length = pmevent->event_len +
2566 					   strlen(CUS_EVT_OBSS_SCAN_PARAM) + 1;
2567 			wireless_send_event(priv->netdev, IWEVCUSTOM, &wrqu,
2568 					    pmevent->event_buf);
2569 		}
2570 #endif
2571 		break;
2572 	case MLAN_EVENT_ID_FW_BW_CHANGED:
2573 		memmove((pmevent->event_buf + strlen(CUS_EVT_BW_CHANGED) + 1),
2574 			pmevent->event_buf, pmevent->event_len);
2575 		moal_memcpy_ext(priv->phandle, pmevent->event_buf,
2576 				(t_u8 *)CUS_EVT_BW_CHANGED,
2577 				strlen(CUS_EVT_BW_CHANGED),
2578 				strlen(CUS_EVT_BW_CHANGED));
2579 		pmevent->event_buf[strlen(CUS_EVT_BW_CHANGED)] = 0;
2580 		woal_broadcast_event(priv, pmevent->event_buf,
2581 				     pmevent->event_len +
2582 					     strlen(CUS_EVT_BW_CHANGED));
2583 
2584 #ifdef STA_WEXT
2585 		if (IS_STA_WEXT(cfg80211_wext)) {
2586 			memset(&wrqu, 0, sizeof(union iwreq_data));
2587 			wrqu.data.pointer = (t_u8 __user *)pmevent->event_buf;
2588 			wrqu.data.length = pmevent->event_len +
2589 					   strlen(CUS_EVT_BW_CHANGED) + 1;
2590 			wireless_send_event(priv->netdev, IWEVCUSTOM, &wrqu,
2591 					    pmevent->event_buf);
2592 		}
2593 #endif
2594 		break;
2595 
2596 	case MLAN_EVENT_ID_FW_DISCONNECTED:
2597 		woal_send_disconnect_to_system(priv,
2598 					       (t_u16)*pmevent->event_buf);
2599 #ifdef STA_CFG80211
2600 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
2601 		priv->auth_flag = 0;
2602 		priv->host_mlme = MFALSE;
2603 		priv->auth_alg = 0xFFFF;
2604 #endif
2605 #endif
2606 #ifdef STA_WEXT
2607 		/* Reset wireless stats signal info */
2608 		if (IS_STA_WEXT(cfg80211_wext)) {
2609 			priv->w_stats.qual.level = 0;
2610 			priv->w_stats.qual.noise = 0;
2611 		}
2612 #endif
2613 #ifdef REASSOCIATION
2614 		if (priv->reassoc_on == MTRUE) {
2615 			if (priv->auto_assoc_priv.auto_assoc_type_on &
2616 			    (0x1 << (AUTO_ASSOC_TYPE_DRV_RECONN - 1))) {
2617 				PRINTM(MINFO,
2618 				       " auto assoc: trigger driver auto re-connect\n");
2619 				priv->auto_assoc_priv.auto_assoc_trigger_flag =
2620 					AUTO_ASSOC_TYPE_DRV_RECONN;
2621 				priv->auto_assoc_priv.drv_reconnect.status =
2622 					MTRUE;
2623 				PRINTM(MINFO, "Reassoc: trigger the timer\n");
2624 				priv->reassoc_required = MTRUE;
2625 				priv->phandle->is_reassoc_timer_set = MTRUE;
2626 				woal_mod_timer(&priv->phandle->reassoc_timer,
2627 					       REASSOC_TIMER_DEFAULT);
2628 			}
2629 		} else {
2630 			priv->rate_index = AUTO_RATE;
2631 		}
2632 #endif /* REASSOCIATION */
2633 		moal_connection_status_check_pmqos(pmoal);
2634 		break;
2635 
2636 	case MLAN_EVENT_ID_FW_MIC_ERR_UNI:
2637 #ifdef STA_WEXT
2638 		if (IS_STA_WEXT(cfg80211_wext)) {
2639 #if WIRELESS_EXT >= 18
2640 			woal_send_mic_error_event(priv,
2641 						  MLAN_EVENT_ID_FW_MIC_ERR_UNI);
2642 #else
2643 			woal_send_iwevcustom_event(priv,
2644 						   CUS_EVT_MLME_MIC_ERR_UNI);
2645 #endif
2646 		}
2647 #endif /* STA_WEXT */
2648 #ifdef STA_CFG80211
2649 		if (IS_STA_CFG80211(cfg80211_wext)) {
2650 			cfg80211_michael_mic_failure(priv->netdev,
2651 						     priv->cfg_bssid,
2652 						     NL80211_KEYTYPE_PAIRWISE,
2653 						     -1, NULL, GFP_KERNEL);
2654 		}
2655 #endif
2656 		woal_broadcast_event(priv, CUS_EVT_MLME_MIC_ERR_UNI,
2657 				     strlen(CUS_EVT_MLME_MIC_ERR_UNI));
2658 		break;
2659 	case MLAN_EVENT_ID_FW_MIC_ERR_MUL:
2660 #ifdef STA_WEXT
2661 		if (IS_STA_WEXT(cfg80211_wext)) {
2662 #if WIRELESS_EXT >= 18
2663 			woal_send_mic_error_event(priv,
2664 						  MLAN_EVENT_ID_FW_MIC_ERR_MUL);
2665 #else
2666 			woal_send_iwevcustom_event(priv,
2667 						   CUS_EVT_MLME_MIC_ERR_MUL);
2668 #endif
2669 		}
2670 #endif /* STA_WEXT */
2671 #ifdef STA_CFG80211
2672 		if (IS_STA_CFG80211(cfg80211_wext)) {
2673 			cfg80211_michael_mic_failure(priv->netdev,
2674 						     priv->cfg_bssid,
2675 						     NL80211_KEYTYPE_GROUP, -1,
2676 						     NULL, GFP_KERNEL);
2677 		}
2678 #endif
2679 		woal_broadcast_event(priv, CUS_EVT_MLME_MIC_ERR_MUL,
2680 				     strlen(CUS_EVT_MLME_MIC_ERR_MUL));
2681 		break;
2682 	case MLAN_EVENT_ID_FW_BCN_RSSI_LOW:
2683 #ifdef STA_WEXT
2684 		if (IS_STA_WEXT(cfg80211_wext))
2685 			woal_send_iwevcustom_event(priv,
2686 						   CUS_EVT_BEACON_RSSI_LOW);
2687 #endif
2688 #ifdef STA_CFG80211
2689 		if (IS_STA_CFG80211(cfg80211_wext)) {
2690 #if CFG80211_VERSION_CODE > KERNEL_VERSION(2, 6, 35)
2691 			cfg80211_cqm_rssi_notify(
2692 				priv->netdev,
2693 				NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
2694 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
2695 				*(t_s16 *)pmevent->event_buf,
2696 #endif
2697 				GFP_KERNEL);
2698 			priv->last_event |= EVENT_BCN_RSSI_LOW;
2699 #endif
2700 			if (!hw_test && priv->roaming_enabled)
2701 				woal_config_bgscan_and_rssi(priv, MTRUE);
2702 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2703 			woal_cfg80211_rssi_monitor_event(
2704 				priv, *(t_s16 *)pmevent->event_buf);
2705 #endif
2706 		}
2707 #endif
2708 		woal_broadcast_event(priv, CUS_EVT_BEACON_RSSI_LOW,
2709 				     strlen(CUS_EVT_BEACON_RSSI_LOW));
2710 		break;
2711 	case MLAN_EVENT_ID_FW_BCN_RSSI_HIGH:
2712 #ifdef STA_WEXT
2713 		if (IS_STA_WEXT(cfg80211_wext))
2714 			woal_send_iwevcustom_event(priv,
2715 						   CUS_EVT_BEACON_RSSI_HIGH);
2716 #endif
2717 #ifdef STA_CFG80211
2718 		if (IS_STA_CFG80211(cfg80211_wext)) {
2719 			if (!priv->mrvl_rssi_low) {
2720 #if CFG80211_VERSION_CODE > KERNEL_VERSION(2, 6, 35)
2721 				cfg80211_cqm_rssi_notify(
2722 					priv->netdev,
2723 					NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
2724 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
2725 					*(t_s16 *)pmevent->event_buf,
2726 #endif
2727 					GFP_KERNEL);
2728 #endif
2729 				woal_set_rssi_threshold(
2730 					priv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH,
2731 					MOAL_NO_WAIT);
2732 			}
2733 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
2734 			woal_cfg80211_rssi_monitor_event(
2735 				priv, *(t_s16 *)pmevent->event_buf);
2736 #endif
2737 		}
2738 #endif
2739 		woal_broadcast_event(priv, CUS_EVT_BEACON_RSSI_HIGH,
2740 				     strlen(CUS_EVT_BEACON_RSSI_HIGH));
2741 		break;
2742 	case MLAN_EVENT_ID_FW_BCN_SNR_LOW:
2743 #ifdef STA_WEXT
2744 		if (IS_STA_WEXT(cfg80211_wext))
2745 			woal_send_iwevcustom_event(priv,
2746 						   CUS_EVT_BEACON_SNR_LOW);
2747 #endif
2748 		woal_broadcast_event(priv, CUS_EVT_BEACON_SNR_LOW,
2749 				     strlen(CUS_EVT_BEACON_SNR_LOW));
2750 		break;
2751 	case MLAN_EVENT_ID_FW_BCN_SNR_HIGH:
2752 #ifdef STA_WEXT
2753 		if (IS_STA_WEXT(cfg80211_wext))
2754 			woal_send_iwevcustom_event(priv,
2755 						   CUS_EVT_BEACON_SNR_HIGH);
2756 #endif
2757 		woal_broadcast_event(priv, CUS_EVT_BEACON_SNR_HIGH,
2758 				     strlen(CUS_EVT_BEACON_SNR_HIGH));
2759 		break;
2760 	case MLAN_EVENT_ID_FW_MAX_FAIL:
2761 #ifdef STA_WEXT
2762 		if (IS_STA_WEXT(cfg80211_wext))
2763 			woal_send_iwevcustom_event(priv, CUS_EVT_MAX_FAIL);
2764 #endif
2765 		woal_broadcast_event(priv, CUS_EVT_MAX_FAIL,
2766 				     strlen(CUS_EVT_MAX_FAIL));
2767 		break;
2768 	case MLAN_EVENT_ID_FW_DATA_RSSI_LOW:
2769 #ifdef STA_WEXT
2770 		if (IS_STA_WEXT(cfg80211_wext))
2771 			woal_send_iwevcustom_event(priv, CUS_EVT_DATA_RSSI_LOW);
2772 #endif
2773 		woal_broadcast_event(priv, CUS_EVT_DATA_RSSI_LOW,
2774 				     strlen(CUS_EVT_DATA_RSSI_LOW));
2775 		break;
2776 	case MLAN_EVENT_ID_FW_DATA_SNR_LOW:
2777 #ifdef STA_WEXT
2778 		if (IS_STA_WEXT(cfg80211_wext))
2779 			woal_send_iwevcustom_event(priv, CUS_EVT_DATA_SNR_LOW);
2780 #endif
2781 		woal_broadcast_event(priv, CUS_EVT_DATA_SNR_LOW,
2782 				     strlen(CUS_EVT_DATA_SNR_LOW));
2783 		break;
2784 	case MLAN_EVENT_ID_FW_DATA_RSSI_HIGH:
2785 #ifdef STA_WEXT
2786 		if (IS_STA_WEXT(cfg80211_wext))
2787 			woal_send_iwevcustom_event(priv,
2788 						   CUS_EVT_DATA_RSSI_HIGH);
2789 #endif
2790 		woal_broadcast_event(priv, CUS_EVT_DATA_RSSI_HIGH,
2791 				     strlen(CUS_EVT_DATA_RSSI_HIGH));
2792 		break;
2793 	case MLAN_EVENT_ID_FW_DATA_SNR_HIGH:
2794 #ifdef STA_WEXT
2795 		if (IS_STA_WEXT(cfg80211_wext))
2796 			woal_send_iwevcustom_event(priv, CUS_EVT_DATA_SNR_HIGH);
2797 #endif
2798 		woal_broadcast_event(priv, CUS_EVT_DATA_SNR_HIGH,
2799 				     strlen(CUS_EVT_DATA_SNR_HIGH));
2800 		break;
2801 	case MLAN_EVENT_ID_FW_LINK_QUALITY:
2802 #ifdef STA_WEXT
2803 		if (IS_STA_WEXT(cfg80211_wext))
2804 			woal_send_iwevcustom_event(priv, CUS_EVT_LINK_QUALITY);
2805 #endif
2806 		woal_broadcast_event(priv, CUS_EVT_LINK_QUALITY,
2807 				     strlen(CUS_EVT_LINK_QUALITY));
2808 		break;
2809 	case MLAN_EVENT_ID_FW_PORT_RELEASE:
2810 #ifdef STA_WEXT
2811 		if (IS_STA_WEXT(cfg80211_wext))
2812 			woal_send_iwevcustom_event(priv, CUS_EVT_PORT_RELEASE);
2813 #endif
2814 		woal_broadcast_event(priv, CUS_EVT_PORT_RELEASE,
2815 				     strlen(CUS_EVT_PORT_RELEASE));
2816 		break;
2817 	case MLAN_EVENT_ID_FW_PRE_BCN_LOST:
2818 #ifdef STA_WEXT
2819 		if (IS_STA_WEXT(cfg80211_wext))
2820 			woal_send_iwevcustom_event(priv,
2821 						   CUS_EVT_PRE_BEACON_LOST);
2822 #endif
2823 #ifdef STA_CFG80211
2824 #if CFG80211_VERSION_CODE > KERNEL_VERSION(2, 6, 35)
2825 		if (IS_STA_CFG80211(cfg80211_wext)) {
2826 			struct cfg80211_bss *bss = NULL;
2827 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
2828 			bss = cfg80211_get_bss(priv->wdev->wiphy, NULL,
2829 					       priv->cfg_bssid, NULL, 0,
2830 					       IEEE80211_BSS_TYPE_ESS,
2831 					       IEEE80211_PRIVACY_ANY);
2832 
2833 #else
2834 			bss = cfg80211_get_bss(priv->wdev->wiphy, NULL,
2835 					       priv->cfg_bssid, NULL, 0,
2836 					       WLAN_CAPABILITY_ESS,
2837 					       WLAN_CAPABILITY_ESS);
2838 #endif
2839 			if (bss) {
2840 				cfg80211_unlink_bss(priv->wdev->wiphy, bss);
2841 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
2842 				cfg80211_put_bss(priv->wdev->wiphy, bss);
2843 #else
2844 				cfg80211_put_bss(bss);
2845 #endif
2846 			}
2847 			if (!hw_test && priv->roaming_enabled)
2848 				woal_config_bgscan_and_rssi(priv, MFALSE);
2849 			else {
2850 				cfg80211_cqm_rssi_notify(
2851 					priv->netdev,
2852 					NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
2853 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
2854 					0,
2855 #endif
2856 					GFP_KERNEL);
2857 			}
2858 			priv->last_event |= EVENT_PRE_BCN_LOST;
2859 		}
2860 #endif
2861 #endif
2862 		woal_broadcast_event(priv, CUS_EVT_PRE_BEACON_LOST,
2863 				     strlen(CUS_EVT_PRE_BEACON_LOST));
2864 		break;
2865 	case MLAN_EVENT_ID_FW_DEBUG_INFO:
2866 #ifdef STA_WEXT
2867 		if (IS_STA_WEXT(cfg80211_wext))
2868 			woal_send_iwevcustom_event(priv, pmevent->event_buf);
2869 #endif
2870 		memmove((pmevent->event_buf + strlen(FW_DEBUG_INFO) + 1),
2871 			pmevent->event_buf, pmevent->event_len);
2872 		moal_memcpy_ext(priv->phandle, pmevent->event_buf,
2873 				(t_u8 *)FW_DEBUG_INFO, strlen(FW_DEBUG_INFO),
2874 				strlen(FW_DEBUG_INFO));
2875 		pmevent->event_buf[strlen(FW_DEBUG_INFO)] = 0;
2876 		woal_broadcast_event(priv, pmevent->event_buf,
2877 				     pmevent->event_len +
2878 					     strlen(FW_DEBUG_INFO) + 1);
2879 		break;
2880 	case MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE:
2881 #ifdef STA_WEXT
2882 		if (IS_STA_WEXT(cfg80211_wext))
2883 			woal_send_iwevcustom_event(
2884 				priv, WMM_CONFIG_CHANGE_INDICATION);
2885 #endif
2886 		woal_broadcast_event(priv, WMM_CONFIG_CHANGE_INDICATION,
2887 				     strlen(WMM_CONFIG_CHANGE_INDICATION));
2888 		break;
2889 
2890 	case MLAN_EVENT_ID_DRV_REPORT_STRING:
2891 		PRINTM(MINFO, "Report string %s\n", pmevent->event_buf);
2892 #ifdef STA_WEXT
2893 		if (IS_STA_WEXT(cfg80211_wext))
2894 			woal_send_iwevcustom_event(priv, pmevent->event_buf);
2895 #endif
2896 		woal_broadcast_event(priv, pmevent->event_buf,
2897 				     strlen(pmevent->event_buf));
2898 		break;
2899 	case MLAN_EVENT_ID_FW_WEP_ICV_ERR:
2900 		DBG_HEXDUMP(MCMD_D, "WEP ICV error", pmevent->event_buf,
2901 			    pmevent->event_len);
2902 #ifdef STA_WEXT
2903 		if (IS_STA_WEXT(cfg80211_wext))
2904 			woal_send_iwevcustom_event(priv, CUS_EVT_WEP_ICV_ERR);
2905 #endif
2906 		woal_broadcast_event(priv, CUS_EVT_WEP_ICV_ERR,
2907 				     strlen(CUS_EVT_WEP_ICV_ERR));
2908 		break;
2909 
2910 	case MLAN_EVENT_ID_DRV_DEFER_HANDLING:
2911 		queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
2912 		break;
2913 	case MLAN_EVENT_ID_DRV_FLUSH_RX_WORK:
2914 		if (moal_extflg_isset(priv->phandle, EXT_NAPI)) {
2915 			napi_synchronize(&priv->phandle->napi_rx);
2916 			break;
2917 		}
2918 		flush_workqueue(priv->phandle->rx_workqueue);
2919 		break;
2920 	case MLAN_EVENT_ID_DRV_FLUSH_MAIN_WORK:
2921 		flush_workqueue(priv->phandle->workqueue);
2922 		break;
2923 	case MLAN_EVENT_ID_DRV_DEFER_RX_WORK:
2924 		if (moal_extflg_isset(priv->phandle, EXT_NAPI)) {
2925 			napi_schedule(&priv->phandle->napi_rx);
2926 			break;
2927 		}
2928 		queue_work(priv->phandle->rx_workqueue,
2929 			   &priv->phandle->rx_work);
2930 		break;
2931 	case MLAN_EVENT_ID_DRV_DBG_DUMP:
2932 		priv->phandle->driver_status = MTRUE;
2933 		ref_handle = (moal_handle *)priv->phandle->pref_mac;
2934 		if (ref_handle)
2935 			ref_handle->driver_status = MTRUE;
2936 #ifdef DEBUG_LEVEL1
2937 		if (drvdbg & MFW_D)
2938 			auto_fw_dump = MTRUE;
2939 #endif
2940 
2941 		woal_moal_debug_info(priv, NULL, MFALSE);
2942 		if (!auto_fw_dump && !handle->fw_dump)
2943 			woal_process_hang(priv->phandle);
2944 		wifi_status = WIFI_STATUS_WIFI_HANG;
2945 		break;
2946 	case MLAN_EVENT_ID_DRV_WIFI_STATUS:
2947 		wifi_status = *(t_u16 *)(pmevent->event_buf + sizeof(t_u32));
2948 		break;
2949 	case MLAN_EVENT_ID_FW_BG_SCAN:
2950 		if (priv->media_connected == MTRUE)
2951 			priv->bg_scan_start = MFALSE;
2952 		priv->bg_scan_reported = MTRUE;
2953 #ifdef STA_WEXT
2954 		if (IS_STA_WEXT(cfg80211_wext)) {
2955 			memset(&wrqu, 0, sizeof(union iwreq_data));
2956 			wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu,
2957 					    NULL);
2958 		}
2959 #endif
2960 #ifdef STA_CFG80211
2961 		if (IS_STA_CFG80211(cfg80211_wext)) {
2962 			priv->last_event |= EVENT_BG_SCAN_REPORT;
2963 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
2964 			if (priv->sched_scanning &&
2965 			    !priv->phandle->cfg80211_suspend) {
2966 				mlan_scan_resp scan_resp;
2967 				if (MLAN_STATUS_SUCCESS ==
2968 				    woal_get_scan_table(priv, MOAL_NO_WAIT,
2969 							&scan_resp))
2970 					PRINTM(MIOCTL,
2971 					       "Triggered mlan get bgscan result\n");
2972 			}
2973 #endif
2974 			if (!hw_test && priv->roaming_enabled
2975 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
2976 			    && !priv->phandle->cfg80211_suspend
2977 #endif
2978 			) {
2979 				priv->roaming_required = MTRUE;
2980 #ifdef ANDROID_KERNEL
2981 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
2982 				__pm_wakeup_event(&priv->phandle->ws,
2983 						  ROAMING_WAKE_LOCK_TIMEOUT);
2984 #else
2985 				wake_lock_timeout(
2986 					&priv->phandle->wake_lock,
2987 					msecs_to_jiffies(
2988 						ROAMING_WAKE_LOCK_TIMEOUT));
2989 #endif
2990 #endif
2991 #ifdef REASSOCIATION
2992 				wake_up_interruptible(
2993 					&priv->phandle->reassoc_thread.wait_q);
2994 #endif
2995 			} else {
2996 #if CFG80211_VERSION_CODE > KERNEL_VERSION(2, 6, 35)
2997 				if (priv->mrvl_rssi_low) {
2998 					cfg80211_cqm_rssi_notify(
2999 						priv->netdev,
3000 						NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
3001 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
3002 						0,
3003 #endif
3004 						GFP_KERNEL);
3005 				}
3006 #endif
3007 			}
3008 		}
3009 #endif
3010 		break;
3011 	case MLAN_EVENT_ID_FW_BG_SCAN_STOPPED:
3012 #ifdef STA_CFG80211
3013 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
3014 		if (IS_STA_CFG80211(cfg80211_wext)) {
3015 			if (priv->sched_scanning)
3016 				woal_bgscan_stop_event(priv);
3017 		}
3018 #endif
3019 #endif
3020 		break;
3021 	case MLAN_EVENT_ID_DRV_BGSCAN_RESULT:
3022 #ifdef STA_CFG80211
3023 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
3024 		if (IS_STA_CFG80211(cfg80211_wext)) {
3025 			if (priv->sched_scanning &&
3026 			    !priv->phandle->cfg80211_suspend) {
3027 				woal_inform_bss_from_scan_result(priv, NULL,
3028 								 MOAL_NO_WAIT);
3029 				PRINTM(MMSG,
3030 				       "wlan: Report sched_scan result\n");
3031 				woal_report_sched_scan_result(priv);
3032 				priv->last_event = 0;
3033 				PRINTM(MEVENT,
3034 				       "Reporting Sched_Scan results\n");
3035 			}
3036 		}
3037 #endif
3038 #endif
3039 		break;
3040 #endif /* STA_SUPPORT */
3041 
3042 	case MLAN_EVENT_ID_FW_CHANNEL_REPORT_RDY:
3043 		radar_detected = pmevent->event_buf[0];
3044 		bandwidth = pmevent->event_buf[2];
3045 #ifdef UAP_SUPPORT
3046 		if (priv->chan_rpt_req.chanNum && priv->chan_rpt_pending) {
3047 			radar_chan = pmevent->event_buf[1];
3048 			if (radar_detected) {
3049 				snprintf(event_buf, sizeof(event_buf) - 1,
3050 					 "%s %d", CUS_EVT_RADAR_DETECTED,
3051 					 radar_chan);
3052 				woal_broadcast_event(priv, event_buf,
3053 						     strlen(event_buf));
3054 			} else {
3055 				snprintf(event_buf, sizeof(event_buf) - 1,
3056 					 "%s %d", CUS_EVT_CAC_FINISHED,
3057 					 priv->chan_rpt_req.chanNum);
3058 				woal_broadcast_event(priv, event_buf,
3059 						     strlen(event_buf));
3060 			}
3061 			if (priv->bss_type == MLAN_BSS_TYPE_DFS)
3062 				woal_chan_event(priv, WOAL_EVENT_CHAN_RPT,
3063 						priv->chan_rpt_req.chanNum,
3064 						radar_detected);
3065 		}
3066 #endif
3067 
3068 #ifdef UAP_CFG80211
3069 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
3070 		if (!IS_STA_OR_UAP_CFG80211(cfg80211_wext))
3071 			break;
3072 		if (priv->chan_rpt_req.chanNum && priv->chan_rpt_pending) {
3073 			priv->chan_rpt_pending = MFALSE;
3074 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
3075 			if (priv->radar_background) {
3076 				PRINTM(MEVENT,
3077 				       "%s radar found when background CAC \n",
3078 				       radar_detected ? "" : "No");
3079 				if (radar_detected)
3080 					cfg80211_background_radar_event(
3081 						priv->phandle->wiphy,
3082 						&priv->radar_background_chan,
3083 						GFP_ATOMIC);
3084 				break;
3085 			}
3086 #endif
3087 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3088 			cfg_priv = woal_get_priv_with_wdev(priv->phandle);
3089 			if (cfg_priv) {
3090 				if (radar_detected)
3091 					woal_update_channels_dfs_state(
3092 						cfg_priv,
3093 						priv->chan_rpt_req.chanNum,
3094 						priv->chan_rpt_req.bandcfg
3095 							.chanWidth,
3096 						DFS_UNAVAILABLE);
3097 				else
3098 					woal_update_channels_dfs_state(
3099 						cfg_priv,
3100 						priv->chan_rpt_req.chanNum,
3101 						priv->chan_rpt_req.bandcfg
3102 							.chanWidth,
3103 						DFS_AVAILABLE);
3104 			}
3105 #endif
3106 			break;
3107 		}
3108 
3109 		if (priv->phandle->is_cac_timer_set) {
3110 			PRINTM(MEVENT, "%s radar found when CAC \n",
3111 			       radar_detected ? "" : "No");
3112 			moal_stop_timer(priv->phandle,
3113 					&priv->phandle->cac_timer);
3114 			priv->phandle->is_cac_timer_set = MFALSE;
3115 			if (radar_detected) {
3116 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3117 				cfg80211_cac_event(priv->netdev,
3118 						   &priv->phandle->dfs_channel,
3119 						   NL80211_RADAR_CAC_ABORTED,
3120 						   GFP_KERNEL);
3121 #else
3122 				cfg80211_cac_event(priv->netdev,
3123 						   NL80211_RADAR_CAC_ABORTED,
3124 						   GFP_KERNEL);
3125 #endif
3126 				cfg80211_radar_event(
3127 					priv->wdev->wiphy,
3128 					&priv->phandle->dfs_channel,
3129 					GFP_KERNEL);
3130 			} else {
3131 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
3132 				if (!priv->user_cac_period_msec) {
3133 					// host and device timer isn't sync,add
3134 					// delay to avoid kernel warning
3135 					// WARN_ON(!time_after_eq(jiffies,
3136 					// timeout)); mdelay(100); Using
3137 					// optimized delay
3138 					timeout =
3139 						(priv->wdev->cac_start_time +
3140 						 msecs_to_jiffies(
3141 							 priv->wdev
3142 								 ->cac_time_ms));
3143 					if (!time_after_eq(jiffies, timeout)) {
3144 						/* Exact time to make host and
3145 						 * device timer in sync */
3146 						wait_time = timeout - jiffies;
3147 						wait_time_ms =
3148 							jiffies_to_msecs(
3149 								wait_time) +
3150 							3;
3151 						PRINTM(MEVENT,
3152 						       "Waiting for %ld ms for syncing\n",
3153 						       wait_time_ms);
3154 						mdelay(wait_time_ms);
3155 					}
3156 				}
3157 #endif
3158 
3159 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3160 				cfg80211_cac_event(priv->netdev,
3161 						   &priv->phandle->dfs_channel,
3162 						   NL80211_RADAR_CAC_FINISHED,
3163 						   GFP_KERNEL);
3164 #else
3165 				cfg80211_cac_event(priv->netdev,
3166 						   NL80211_RADAR_CAC_FINISHED,
3167 						   GFP_KERNEL);
3168 #endif
3169 			}
3170 			memset(&priv->phandle->dfs_channel, 0,
3171 			       sizeof(struct cfg80211_chan_def));
3172 			priv->phandle->cac_bss_index = 0xff;
3173 		}
3174 #endif /* CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) */
3175 #endif /* UAP_CFG80211 */
3176 		break;
3177 	case MLAN_EVENT_ID_FW_RADAR_DETECTED:
3178 		radar_chan = pmevent->event_buf[0];
3179 		bandwidth = pmevent->event_buf[1];
3180 		snprintf(event_buf, sizeof(event_buf) - 1, "%s %d",
3181 			 CUS_EVT_RADAR_DETECTED, radar_chan);
3182 		woal_broadcast_event(priv, event_buf, strlen(event_buf));
3183 		PRINTM(MEVENT, "Radar detected on channel %d\n", radar_chan);
3184 
3185 #ifdef UAP_CFG80211
3186 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
3187 		if (!IS_STA_OR_UAP_CFG80211(cfg80211_wext))
3188 			break;
3189 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
3190 		if (priv->radar_background) {
3191 			cfg80211_background_radar_event(
3192 				priv->phandle->wiphy,
3193 				&priv->radar_background_chan, GFP_ATOMIC);
3194 			break;
3195 		}
3196 #endif
3197 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3198 		cfg_priv = woal_get_priv_with_wdev(priv->phandle);
3199 		if (cfg_priv)
3200 			woal_update_channels_dfs_state(cfg_priv, radar_chan,
3201 						       bandwidth,
3202 						       DFS_UNAVAILABLE);
3203 #endif
3204 #ifdef UAP_SUPPORT
3205 		if ((priv->target_chan && priv->bss_started &&
3206 		     (priv->target_chan != radar_chan)) ||
3207 		    priv->backup_chan) {
3208 			PRINTM(MEVENT, "Move to target or backup chan %d %d\n",
3209 			       priv->target_chan, priv->backup_chan);
3210 			woal_move_to_next_channel(priv);
3211 			priv->target_chan = 0;
3212 			break;
3213 		}
3214 		if (priv->bss_type == MLAN_BSS_TYPE_DFS) {
3215 			woal_chan_event(priv, WOAL_EVENT_RADAR,
3216 					priv->chan_rpt_req.chanNum, MTRUE);
3217 			break;
3218 		}
3219 #endif
3220 		if (priv->phandle->is_cac_timer_set) {
3221 			if (priv->bss_index == priv->phandle->cac_bss_index) {
3222 				PRINTM(MEVENT, "radar detected during CAC \n");
3223 				woal_cancel_timer(&priv->phandle->cac_timer);
3224 				priv->phandle->is_cac_timer_set = MFALSE;
3225 				/* downstream: cancel the unfinished CAC in
3226 				 * Firmware*/
3227 				woal_11h_cancel_chan_report_ioctl(priv,
3228 								  MOAL_NO_WAIT);
3229 				/* upstream: inform cfg80211 */
3230 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3231 				cfg80211_cac_event(priv->netdev,
3232 						   &priv->phandle->dfs_channel,
3233 						   NL80211_RADAR_CAC_ABORTED,
3234 						   GFP_KERNEL);
3235 #else
3236 				cfg80211_cac_event(priv->netdev,
3237 						   NL80211_RADAR_CAC_ABORTED,
3238 						   GFP_KERNEL);
3239 #endif
3240 				cfg80211_radar_event(
3241 					priv->wdev->wiphy,
3242 					&priv->phandle->dfs_channel,
3243 					GFP_KERNEL);
3244 
3245 				memset(&priv->phandle->dfs_channel, 0,
3246 				       sizeof(priv->phandle->dfs_channel));
3247 				priv->phandle->cac_bss_index = 0xff;
3248 			} else {
3249 				PRINTM(MERROR,
3250 				       " Radar event for incorrect inferface \n");
3251 			}
3252 		} else {
3253 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3254 			if (moal_extflg_isset(priv->phandle, EXT_DFS_OFFLOAD))
3255 				woal_cfg80211_dfs_vendor_event(
3256 					priv, event_dfs_radar_detected,
3257 					&priv->chan);
3258 			else {
3259 #endif
3260 				if (priv->uap_host_based && priv->bss_started)
3261 					cfg80211_radar_event(priv->wdev->wiphy,
3262 							     &priv->chan,
3263 							     GFP_KERNEL);
3264 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3265 			}
3266 #endif
3267 		}
3268 #endif /* CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0 */
3269 #endif /* UAP_CFG80211 */
3270 		break;
3271 	case MLAN_EVENT_ID_FW_CHANNEL_SWITCH_ANN:
3272 #ifdef STA_WEXT
3273 		if (IS_STA_WEXT(cfg80211_wext))
3274 			woal_send_iwevcustom_event(priv,
3275 						   CUS_EVT_CHANNEL_SWITCH_ANN);
3276 #endif
3277 		woal_broadcast_event(priv, CUS_EVT_CHANNEL_SWITCH_ANN,
3278 				     strlen(CUS_EVT_CHANNEL_SWITCH_ANN));
3279 		break;
3280 
3281 	case MLAN_EVENT_ID_FW_CHAN_SWITCH_COMPLETE:
3282 #if defined(UAP_CFG80211) || defined(STA_CFG80211)
3283 		pchan_info = (chan_band_info *)pmevent->event_buf;
3284 #ifdef UAP_SUPPORT
3285 		if (priv->bss_role == MLAN_BSS_ROLE_UAP) {
3286 			if (priv->uap_tx_blocked) {
3287 				if (!netif_carrier_ok(priv->netdev))
3288 					netif_carrier_on(priv->netdev);
3289 				woal_start_queue(priv->netdev);
3290 				priv->uap_tx_blocked = MFALSE;
3291 			}
3292 			priv->phandle->chsw_wait_q_woken = MTRUE;
3293 			wake_up_interruptible(&priv->phandle->chsw_wait_q);
3294 		}
3295 #endif
3296 
3297 		if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
3298 			PRINTM(MMSG,
3299 			       "CSA/ECSA: Switch to new channel %d complete!\n",
3300 			       pchan_info->channel);
3301 #ifdef UAP_CFG80211
3302 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
3303 			if (priv->csa_chan.chan &&
3304 			    (pchan_info->channel ==
3305 			     priv->csa_chan.chan->hw_value)) {
3306 				moal_memcpy_ext(
3307 					priv->phandle, &priv->chan,
3308 					&priv->csa_chan,
3309 					sizeof(struct cfg80211_chan_def),
3310 					sizeof(struct cfg80211_chan_def));
3311 			}
3312 #endif
3313 #endif
3314 			if (priv->channel == pchan_info->channel)
3315 				break;
3316 			priv->channel = pchan_info->channel;
3317 
3318 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
3319 			if (MFALSE
3320 #ifdef UAP_CFG80211
3321 			    || priv->uap_host_based
3322 #endif
3323 #ifdef STA_CFG80211
3324 			    || priv->sme_current.ssid_len
3325 #endif
3326 			) {
3327 				PRINTM(MEVENT,
3328 				       "CHAN_SWITCH: 11n=%d, chan=%d, center_chan=%d, band=%d, width=%d, 2Offset=%d\n",
3329 				       pchan_info->is_11n_enabled,
3330 				       pchan_info->channel,
3331 				       pchan_info->center_chan,
3332 				       pchan_info->bandcfg.chanBand,
3333 				       pchan_info->bandcfg.chanWidth,
3334 				       pchan_info->bandcfg.chan2Offset);
3335 				woal_channel_switch_event(priv, pchan_info);
3336 			}
3337 #endif
3338 		}
3339 #endif
3340 		break;
3341 	case MLAN_EVENT_ID_FW_STOP_TX:
3342 		woal_stop_queue(priv->netdev);
3343 		if (netif_carrier_ok(priv->netdev))
3344 			netif_carrier_off(priv->netdev);
3345 		break;
3346 	case MLAN_EVENT_ID_FW_START_TX:
3347 		if (!netif_carrier_ok(priv->netdev))
3348 			netif_carrier_on(priv->netdev);
3349 		woal_wake_queue(priv->netdev);
3350 		break;
3351 	case MLAN_EVENT_ID_FW_HS_WAKEUP:
3352 		/* simulate HSCFG_CANCEL command */
3353 		woal_cancel_hs(priv, MOAL_NO_WAIT);
3354 #ifdef STA_SUPPORT
3355 		pmpriv = woal_get_priv((moal_handle *)pmoal, MLAN_BSS_ROLE_STA);
3356 #ifdef STA_WEXT
3357 		if (IS_STA_WEXT(cfg80211_wext) && pmpriv)
3358 			woal_send_iwevcustom_event(pmpriv, CUS_EVT_HS_WAKEUP);
3359 #endif /* STA_WEXT */
3360 		if (pmpriv)
3361 			woal_broadcast_event(pmpriv, CUS_EVT_HS_WAKEUP,
3362 					     strlen(CUS_EVT_HS_WAKEUP));
3363 #endif /*STA_SUPPORT */
3364 #ifdef UAP_SUPPORT
3365 		pmpriv = woal_get_priv((moal_handle *)pmoal, MLAN_BSS_ROLE_UAP);
3366 		if (pmpriv) {
3367 			pmevent->event_id = UAP_EVENT_ID_HS_WAKEUP;
3368 			woal_broadcast_event(pmpriv, (t_u8 *)&pmevent->event_id,
3369 					     sizeof(t_u32));
3370 		}
3371 #endif /* UAP_SUPPORT */
3372 		break;
3373 	case MLAN_EVENT_ID_DRV_HS_ACTIVATED:
3374 #ifdef STA_SUPPORT
3375 		pmpriv = woal_get_priv((moal_handle *)pmoal, MLAN_BSS_ROLE_STA);
3376 #ifdef STA_WEXT
3377 		if (IS_STA_WEXT(cfg80211_wext) && pmpriv)
3378 			woal_send_iwevcustom_event(pmpriv,
3379 						   CUS_EVT_HS_ACTIVATED);
3380 #endif /* STA_WEXT */
3381 		if (pmpriv)
3382 			woal_broadcast_event(pmpriv, CUS_EVT_HS_ACTIVATED,
3383 					     strlen(CUS_EVT_HS_ACTIVATED));
3384 #endif /* STA_SUPPORT */
3385 #if defined(UAP_SUPPORT)
3386 		pmpriv = woal_get_priv((moal_handle *)pmoal, MLAN_BSS_ROLE_UAP);
3387 		if (pmpriv) {
3388 			pmevent->event_id = UAP_EVENT_ID_DRV_HS_ACTIVATED;
3389 			woal_broadcast_event(pmpriv, (t_u8 *)&pmevent->event_id,
3390 					     sizeof(t_u32));
3391 		}
3392 #endif
3393 		memset(&pm_info, 0, sizeof(mlan_ds_ps_info));
3394 		if (priv->phandle->suspend_fail == MFALSE) {
3395 			woal_get_pm_info(priv, &pm_info);
3396 			if (pm_info.is_suspend_allowed == MTRUE) {
3397 				priv->phandle->hs_activated = MTRUE;
3398 #ifdef MMC_PM_FUNC_SUSPENDED
3399 				woal_wlan_is_suspended(priv->phandle);
3400 #endif
3401 			}
3402 			priv->phandle->hs_activate_wait_q_woken = MTRUE;
3403 			wake_up(&priv->phandle->hs_activate_wait_q);
3404 		}
3405 		break;
3406 	case MLAN_EVENT_ID_DRV_HS_DEACTIVATED:
3407 #ifdef STA_SUPPORT
3408 		pmpriv = woal_get_priv((moal_handle *)pmoal, MLAN_BSS_ROLE_STA);
3409 #ifdef STA_WEXT
3410 		if (IS_STA_WEXT(cfg80211_wext) && pmpriv)
3411 			woal_send_iwevcustom_event(pmpriv,
3412 						   CUS_EVT_HS_DEACTIVATED);
3413 #endif /* STA_WEXT */
3414 		if (pmpriv)
3415 			woal_broadcast_event(pmpriv, CUS_EVT_HS_DEACTIVATED,
3416 					     strlen(CUS_EVT_HS_DEACTIVATED));
3417 #endif /* STA_SUPPORT */
3418 #if defined(UAP_SUPPORT)
3419 		pmpriv = woal_get_priv((moal_handle *)pmoal, MLAN_BSS_ROLE_UAP);
3420 		if (pmpriv) {
3421 			pmevent->event_id = UAP_EVENT_ID_DRV_HS_DEACTIVATED;
3422 			woal_broadcast_event(pmpriv, (t_u8 *)&pmevent->event_id,
3423 					     sizeof(t_u32));
3424 		}
3425 #endif
3426 		priv->phandle->hs_activated = MFALSE;
3427 		break;
3428 #ifdef UAP_SUPPORT
3429 	case MLAN_EVENT_ID_UAP_FW_BSS_START:
3430 		woal_hist_data_reset(priv);
3431 		priv->bss_started = MTRUE;
3432 		priv->skip_cac = MFALSE;
3433 		if (!netif_carrier_ok(priv->netdev))
3434 			netif_carrier_on(priv->netdev);
3435 		woal_start_queue(priv->netdev);
3436 		moal_memcpy_ext(priv->phandle, priv->current_addr,
3437 				pmevent->event_buf + 6, ETH_ALEN, ETH_ALEN);
3438 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
3439 		eth_hw_addr_set(priv->netdev, priv->current_addr);
3440 #else
3441 		moal_memcpy_ext(priv->phandle, priv->netdev->dev_addr,
3442 				priv->current_addr, ETH_ALEN, ETH_ALEN);
3443 #endif
3444 		woal_broadcast_event(priv, pmevent->event_buf,
3445 				     pmevent->event_len);
3446 #ifdef STA_SUPPORT
3447 #ifdef STA_CFG80211
3448 		pmpriv = woal_get_priv((moal_handle *)pmoal, MLAN_BSS_ROLE_STA);
3449 		if (IS_STA_CFG80211(cfg80211_wext) && pmpriv)
3450 			woal_set_scan_time(pmpriv, ACTIVE_SCAN_CHAN_TIME,
3451 					   PASSIVE_SCAN_CHAN_TIME,
3452 					   MIN_SPECIFIC_SCAN_CHAN_TIME);
3453 #endif
3454 #endif
3455 #ifdef UAP_CFG80211
3456 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
3457 		if (priv->chan_under_nop) {
3458 			PRINTM(MMSG,
3459 			       "Channel Under Nop: notify cfg80211 new channel=%d\n",
3460 			       priv->channel);
3461 #if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
3462 			cfg80211_ch_switch_notify(priv->netdev, &priv->chan, 0);
3463 #else
3464 			cfg80211_ch_switch_notify(priv->netdev, &priv->chan);
3465 #endif
3466 			priv->chan_under_nop = MFALSE;
3467 		}
3468 #endif
3469 #endif
3470 		break;
3471 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
3472 	case MLAN_EVENT_ID_DRV_UAP_CHAN_INFO:
3473 #ifdef UAP_CFG80211
3474 		if (IS_UAP_CFG80211(cfg80211_wext)) {
3475 			pchan_info = (chan_band_info *)pmevent->event_buf;
3476 			PRINTM(MEVENT,
3477 			       "UAP: 11n=%d, chan=%d, center_chan=%d, band=%d, width=%d, 2Offset=%d\n",
3478 			       pchan_info->is_11n_enabled, pchan_info->channel,
3479 			       pchan_info->center_chan,
3480 			       pchan_info->bandcfg.chanBand,
3481 			       pchan_info->bandcfg.chanWidth,
3482 			       pchan_info->bandcfg.chan2Offset);
3483 			if (priv->uap_host_based &&
3484 			    (priv->channel != pchan_info->channel))
3485 				woal_channel_switch_event(priv, pchan_info);
3486 		}
3487 #endif
3488 		break;
3489 #endif
3490 	case MLAN_EVENT_ID_UAP_FW_BSS_ACTIVE:
3491 		priv->media_connected = MTRUE;
3492 		if (!netif_carrier_ok(priv->netdev))
3493 			netif_carrier_on(priv->netdev);
3494 		woal_wake_queue(priv->netdev);
3495 		woal_broadcast_event(priv, pmevent->event_buf,
3496 				     pmevent->event_len);
3497 		moal_connection_status_check_pmqos(pmoal);
3498 		break;
3499 	case MLAN_EVENT_ID_UAP_FW_BSS_IDLE:
3500 		priv->media_connected = MFALSE;
3501 		woal_broadcast_event(priv, pmevent->event_buf,
3502 				     pmevent->event_len);
3503 		moal_connection_status_check_pmqos(pmoal);
3504 		break;
3505 	case MLAN_EVENT_ID_UAP_FW_MIC_COUNTERMEASURES: {
3506 		t_u16 status = 0;
3507 		status = *(t_u16 *)(pmevent->event_buf + 4);
3508 		if (status) {
3509 			priv->media_connected = MFALSE;
3510 			woal_stop_queue(priv->netdev);
3511 			if (netif_carrier_ok(priv->netdev))
3512 				netif_carrier_off(priv->netdev);
3513 		} else {
3514 			priv->media_connected = MTRUE;
3515 			if (!netif_carrier_ok(priv->netdev))
3516 				netif_carrier_on(priv->netdev);
3517 			woal_wake_queue(priv->netdev);
3518 		}
3519 		woal_broadcast_event(priv, pmevent->event_buf,
3520 				     pmevent->event_len);
3521 	} break;
3522 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
3523 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
3524 	case MLAN_EVENT_ID_FW_REMAIN_ON_CHAN_EXPIRED:
3525 		if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
3526 			PRINTM(MEVENT,
3527 			       "FW_REMAIN_ON_CHANNEL_EXPIRED cookie = %#llx\n",
3528 			       priv->phandle->cookie);
3529 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
3530 			if (priv->host_mlme &&
3531 			    (priv->auth_flag & HOST_MLME_AUTH_PENDING)) {
3532 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
3533 				if (priv->assoc_bss) {
3534 					PRINTM(MEVENT,
3535 					       "wlan: HostMlme auth timeout\n");
3536 					cfg80211_auth_timeout(
3537 						priv->netdev,
3538 						priv->assoc_bss->bssid);
3539 				}
3540 #endif
3541 				priv->auth_flag = 0;
3542 				priv->host_mlme = MFALSE;
3543 				priv->auth_alg = 0xFFFF;
3544 			}
3545 #endif
3546 			priv->phandle->remain_on_channel = MFALSE;
3547 			if (priv->phandle->cookie &&
3548 			    !priv->phandle->is_remain_timer_set) {
3549 				cfg80211_remain_on_channel_expired(
3550 #if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
3551 					priv->netdev,
3552 #else
3553 					priv->wdev,
3554 #endif
3555 					priv->phandle->cookie,
3556 					&priv->phandle->chan,
3557 #if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
3558 					priv->phandle->channel_type,
3559 #endif
3560 					GFP_ATOMIC);
3561 				priv->phandle->cookie = 0;
3562 			}
3563 		}
3564 		break;
3565 #endif
3566 #endif
3567 	case MLAN_EVENT_ID_UAP_FW_STA_CONNECT:
3568 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
3569 		if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
3570 			struct station_info *sinfo = NULL;
3571 			t_u8 addr[ETH_ALEN];
3572 			sinfo = kzalloc(sizeof(struct station_info),
3573 					GFP_ATOMIC);
3574 			if (sinfo) {
3575 				sinfo->filled = 0;
3576 				sinfo->generation = 0;
3577 				/* copy the station mac address */
3578 				memset(addr, 0xFF, ETH_ALEN);
3579 				moal_memcpy_ext(priv->phandle, addr,
3580 						pmevent->event_buf, ETH_ALEN,
3581 						ETH_ALEN);
3582 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
3583 				if (pmevent->event_len > ETH_ALEN) {
3584 #if CFG80211_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
3585 					/* set station info filled flag */
3586 					sinfo->filled |=
3587 						STATION_INFO_ASSOC_REQ_IES;
3588 #endif
3589 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
3590 					sinfo->pertid = NULL;
3591 #endif
3592 					/* get the assoc request ies and length
3593 					 */
3594 					sinfo->assoc_req_ies =
3595 						(const t_u8
3596 							 *)(pmevent->event_buf +
3597 							    ETH_ALEN);
3598 					sinfo->assoc_req_ies_len =
3599 						pmevent->event_len - ETH_ALEN;
3600 				}
3601 #endif /* KERNEL_VERSION */
3602 				if (priv->netdev && priv->wdev)
3603 					cfg80211_new_sta(priv->netdev,
3604 							 (t_u8 *)addr, sinfo,
3605 							 GFP_KERNEL);
3606 				kfree(sinfo);
3607 			}
3608 		}
3609 #endif /* UAP_CFG80211 */
3610 		memmove((pmevent->event_buf + strlen(CUS_EVT_STA_CONNECTED) +
3611 			 1),
3612 			pmevent->event_buf, pmevent->event_len);
3613 		moal_memcpy_ext(priv->phandle, pmevent->event_buf,
3614 				(t_u8 *)CUS_EVT_STA_CONNECTED,
3615 				strlen(CUS_EVT_STA_CONNECTED),
3616 				strlen(CUS_EVT_STA_CONNECTED));
3617 		pmevent->event_buf[strlen(CUS_EVT_STA_CONNECTED)] = 0;
3618 		woal_broadcast_event(priv, pmevent->event_buf,
3619 				     pmevent->event_len +
3620 					     strlen(CUS_EVT_STA_CONNECTED));
3621 #ifdef UAP_WEXT
3622 		if (IS_UAP_WEXT(cfg80211_wext)) {
3623 			memset(&wrqu, 0, sizeof(union iwreq_data));
3624 			wrqu.data.pointer = (t_u8 __user *)pmevent->event_buf;
3625 			if ((pmevent->event_len +
3626 			     strlen(CUS_EVT_STA_CONNECTED) + 1) > IW_CUSTOM_MAX)
3627 				wrqu.data.length =
3628 					ETH_ALEN +
3629 					strlen(CUS_EVT_STA_CONNECTED) + 1;
3630 			else
3631 				wrqu.data.length =
3632 					pmevent->event_len +
3633 					strlen(CUS_EVT_STA_CONNECTED) + 1;
3634 			wireless_send_event(priv->netdev, IWEVCUSTOM, &wrqu,
3635 					    pmevent->event_buf);
3636 		}
3637 #endif /* UAP_WEXT */
3638 		break;
3639 	case MLAN_EVENT_ID_UAP_FW_STA_DISCONNECT:
3640 #ifdef UAP_CFG80211
3641 		if (IS_UAP_CFG80211(cfg80211_wext)) {
3642 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
3643 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
3644 			/**Forward Deauth, Auth and disassoc frame to Host*/
3645 			if (moal_extflg_isset(priv->phandle, EXT_HOST_MLME)) {
3646 				t_u16 reason_code = woal_le16_to_cpu(
3647 					*(t_u16 *)pmevent->event_buf);
3648 				PRINTM(MCMND, "deauth reason code =0x%x\n",
3649 				       reason_code);
3650 				/** BIT 14 indicate deauth is initiated by FW */
3651 				if (reason_code & MBIT(14))
3652 					woal_host_mlme_disconnect(
3653 						priv, 0,
3654 						pmevent->event_buf + 2);
3655 			} else
3656 #endif
3657 				if (priv->netdev && priv->wdev)
3658 				cfg80211_del_sta(priv->netdev,
3659 						 pmevent->event_buf + 2,
3660 						 GFP_KERNEL);
3661 
3662 #endif /* KERNEL_VERSION */
3663 		}
3664 #endif /* UAP_CFG80211 */
3665 		memmove((pmevent->event_buf + strlen(CUS_EVT_STA_DISCONNECTED) +
3666 			 1),
3667 			pmevent->event_buf, pmevent->event_len);
3668 		moal_memcpy_ext(priv->phandle, pmevent->event_buf,
3669 				(t_u8 *)CUS_EVT_STA_DISCONNECTED,
3670 				strlen(CUS_EVT_STA_DISCONNECTED),
3671 				strlen(CUS_EVT_STA_DISCONNECTED));
3672 		pmevent->event_buf[strlen(CUS_EVT_STA_DISCONNECTED)] = 0;
3673 		woal_broadcast_event(priv, pmevent->event_buf,
3674 				     pmevent->event_len +
3675 					     strlen(CUS_EVT_STA_DISCONNECTED));
3676 
3677 #ifdef UAP_WEXT
3678 		if (IS_UAP_WEXT(cfg80211_wext)) {
3679 			memset(&wrqu, 0, sizeof(union iwreq_data));
3680 			wrqu.data.pointer = (t_u8 __user *)pmevent->event_buf;
3681 			wrqu.data.length = pmevent->event_len +
3682 					   strlen(CUS_EVT_STA_DISCONNECTED) + 1;
3683 			wireless_send_event(priv->netdev, IWEVCUSTOM, &wrqu,
3684 					    pmevent->event_buf);
3685 		}
3686 #endif /* UAP_WEXT */
3687 		break;
3688 	case MLAN_EVENT_ID_DRV_MGMT_FRAME:
3689 #ifdef UAP_WEXT
3690 		if (IS_UAP_WEXT(cfg80211_wext)) {
3691 			woal_broadcast_event(priv, pmevent->event_buf,
3692 					     pmevent->event_len);
3693 		}
3694 #endif /* UAP_WEXT */
3695 
3696 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
3697 		if (IS_STA_OR_UAP_CFG80211(cfg80211_wext)) {
3698 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
3699 			if (priv->netdev &&
3700 			    priv->netdev->ieee80211_ptr->wiphy->mgmt_stypes &&
3701 			    priv->mgmt_subtype_mask) {
3702 				/* frmctl + durationid + addr1 + addr2 + addr3 +
3703 				 * seqctl */
3704 #define PACKET_ADDR4_POS (2 + 2 + 6 + 6 + 6 + 2)
3705 				t_u8 *pkt;
3706 				int freq =
3707 					priv->phandle->remain_on_channel ?
3708 						priv->phandle->chan.center_freq :
3709 						woal_get_active_intf_freq(priv);
3710 				if (!freq) {
3711 					if (!priv->phandle->chan.center_freq) {
3712 						PRINTM(MINFO,
3713 						       "Skip to report mgmt packet to cfg80211\n");
3714 						break;
3715 					}
3716 					freq = priv->phandle->chan.center_freq;
3717 				}
3718 
3719 				pkt = ((t_u8 *)pmevent->event_buf +
3720 				       sizeof(pmevent->event_id));
3721 
3722 				/* move addr4 */
3723 				memmove(pkt + PACKET_ADDR4_POS,
3724 					pkt + PACKET_ADDR4_POS + ETH_ALEN,
3725 					pmevent->event_len -
3726 						sizeof(pmevent->event_id) -
3727 						PACKET_ADDR4_POS - ETH_ALEN);
3728 #ifdef WIFI_DIRECT_SUPPORT
3729 				if (ieee80211_is_action(
3730 					    ((struct ieee80211_mgmt *)pkt)
3731 						    ->frame_control))
3732 					woal_cfg80211_display_p2p_actframe(
3733 						pkt,
3734 						pmevent->event_len -
3735 							sizeof(pmevent->event_id) -
3736 							MLAN_MAC_ADDR_LENGTH,
3737 						ieee80211_get_channel(
3738 							priv->wdev->wiphy,
3739 							freq),
3740 						MFALSE);
3741 #endif
3742 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
3743 				/**Forward Deauth, Auth and disassoc frame to
3744 				 * Host*/
3745 				if (priv->host_mlme &&
3746 				    (GET_BSS_ROLE(priv) != MLAN_BSS_ROLE_UAP) &&
3747 				    (ieee80211_is_deauth(
3748 					     ((struct ieee80211_mgmt *)pkt)
3749 						     ->frame_control) ||
3750 				     ieee80211_is_auth(
3751 					     ((struct ieee80211_mgmt *)pkt)
3752 						     ->frame_control) ||
3753 				     ieee80211_is_disassoc(
3754 					     ((struct ieee80211_mgmt *)pkt)
3755 						     ->frame_control))) {
3756 					if (ieee80211_is_auth(
3757 						    ((struct ieee80211_mgmt *)
3758 							     pkt)
3759 							    ->frame_control)) {
3760 						PRINTM(MEVENT,
3761 						       "HostMlme %s: Received auth frame type = 0x%x\n",
3762 						       priv->netdev->name,
3763 						       priv->auth_alg);
3764 
3765 						if (priv->auth_flag &
3766 						    HOST_MLME_AUTH_PENDING) {
3767 							if (priv->auth_alg !=
3768 							    WLAN_AUTH_SAE) {
3769 								priv->auth_flag &=
3770 									~HOST_MLME_AUTH_PENDING;
3771 								priv->auth_flag |=
3772 									HOST_MLME_AUTH_DONE;
3773 								priv->phandle
3774 									->host_mlme_priv =
3775 									priv;
3776 								queue_work(
3777 									priv->phandle
3778 										->evt_workqueue,
3779 									&priv->phandle
3780 										 ->host_mlme_work);
3781 							}
3782 						} else {
3783 							PRINTM(MERROR,
3784 							       "HostMlme %s: Drop auth frame, auth_flag=0x%x auth_alg=0x%x\n",
3785 							       priv->netdev
3786 								       ->name,
3787 							       priv->auth_flag,
3788 							       priv->auth_alg);
3789 							break;
3790 						}
3791 					} else {
3792 						PRINTM(MEVENT,
3793 						       "HostMlme %s: Receive deauth/disassociate\n",
3794 						       priv->netdev->name);
3795 #if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || IMX_ANDROID_13)
3796 						if (!priv->wdev->connected) {
3797 #else
3798 						if (!priv->wdev->current_bss) {
3799 #endif
3800 							PRINTM(MEVENT,
3801 							       "HostMlme: Drop deauth/disassociate, current_bss = null\n");
3802 							break;
3803 						}
3804 						priv->cfg_disconnect = MTRUE;
3805 						woal_mgmt_frame_register(
3806 							priv,
3807 							IEEE80211_STYPE_DEAUTH,
3808 							MFALSE);
3809 						woal_mgmt_frame_register(
3810 							priv,
3811 							IEEE80211_STYPE_DISASSOC,
3812 							MFALSE);
3813 						woal_send_disconnect_to_system(
3814 							priv,
3815 							DEF_DEAUTH_REASON_CODE);
3816 						priv->host_mlme = MFALSE;
3817 						priv->auth_flag = 0;
3818 						priv->auth_alg = 0xFFFF;
3819 					}
3820 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
3821 					woal_rx_mgmt_pkt_event(
3822 						priv, pkt,
3823 						pmevent->event_len -
3824 							sizeof(pmevent->event_id) -
3825 							MLAN_MAC_ADDR_LENGTH);
3826 #else
3827 					if (ieee80211_is_deauth(
3828 						    ((struct ieee80211_mgmt *)
3829 							     pkt)
3830 							    ->frame_control))
3831 						cfg80211_send_deauth(
3832 							priv->netdev, pkt,
3833 							pmevent->event_len -
3834 								sizeof(pmevent->event_id) -
3835 								MLAN_MAC_ADDR_LENGTH);
3836 					else if (ieee80211_is_auth(
3837 							 ((struct ieee80211_mgmt
3838 								   *)pkt)
3839 								 ->frame_control))
3840 						cfg80211_send_rx_auth(
3841 							priv->netdev, pkt,
3842 							pmevent->event_len -
3843 								sizeof(pmevent->event_id) -
3844 								MLAN_MAC_ADDR_LENGTH);
3845 					else if (ieee80211_is_disassoc(
3846 							 ((struct ieee80211_mgmt
3847 								   *)pkt)
3848 								 ->frame_control))
3849 						cfg80211_send_disassoc(
3850 							priv->netdev, pkt,
3851 							pmevent->event_len -
3852 								sizeof(pmevent->event_id) -
3853 								MLAN_MAC_ADDR_LENGTH);
3854 
3855 #endif
3856 				} else
3857 #endif
3858 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
3859 					cfg80211_rx_mgmt(
3860 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
3861 						priv->wdev,
3862 #else
3863 						priv->netdev,
3864 #endif
3865 						freq, 0,
3866 						((const t_u8 *)
3867 							 pmevent->event_buf) +
3868 							sizeof(pmevent->event_id),
3869 						pmevent->event_len -
3870 							sizeof(pmevent->event_id) -
3871 							MLAN_MAC_ADDR_LENGTH
3872 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
3873 						,
3874 						0
3875 #endif
3876 #if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
3877 						,
3878 						GFP_ATOMIC
3879 #endif
3880 					);
3881 #else
3882 				cfg80211_rx_mgmt(
3883 					priv->netdev, freq,
3884 					((const t_u8 *)pmevent->event_buf) +
3885 						sizeof(pmevent->event_id),
3886 					pmevent->event_len -
3887 						sizeof(pmevent->event_id) -
3888 						MLAN_MAC_ADDR_LENGTH,
3889 					GFP_ATOMIC);
3890 #endif
3891 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
3892 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3893 				woal_packet_fate_monitor(
3894 					priv, PACKET_TYPE_RX,
3895 					RX_PKT_FATE_SUCCESS,
3896 					FRAME_TYPE_80211_MGMT, 0, 0,
3897 					((t_u8 *)pmevent->event_buf) +
3898 						sizeof(pmevent->event_id),
3899 					pmevent->event_len -
3900 						sizeof(pmevent->event_id) -
3901 						MLAN_MAC_ADDR_LENGTH);
3902 #endif
3903 #endif
3904 			}
3905 #endif /* KERNEL_VERSION */
3906 		}
3907 #endif /* STA_CFG80211 || UAP_CFG80211 */
3908 		break;
3909 #endif /* UAP_SUPPORT */
3910 	case MLAN_EVENT_ID_DRV_PASSTHRU:
3911 		woal_broadcast_event(priv, pmevent->event_buf,
3912 				     pmevent->event_len);
3913 		break;
3914 	case MLAN_EVENT_ID_DRV_ASSOC_FAILURE_REPORT:
3915 		PRINTM(MINFO, "Assoc result\n");
3916 
3917 		if (priv->media_connected) {
3918 			PRINTM(MINFO, "Assoc_Rpt: Media Connected\n");
3919 			if (!netif_carrier_ok(priv->netdev)) {
3920 				PRINTM(MINFO, "Assoc_Rpt: Carrier On\n");
3921 				netif_carrier_on(priv->netdev);
3922 			}
3923 			PRINTM(MINFO, "Assoc_Rpt: Queue Start\n");
3924 			woal_wake_queue(priv->netdev);
3925 		}
3926 		break;
3927 	case MLAN_EVENT_ID_DRV_MEAS_REPORT:
3928 		/* We have received measurement report, wakeup measurement wait
3929 		 * queue */
3930 		PRINTM(MINFO, "Measurement Report\n");
3931 		/* Going out of CAC checking period */
3932 		if (priv->phandle->cac_period == MTRUE) {
3933 			priv->phandle->cac_period = MFALSE;
3934 			if (priv->phandle->meas_wait_q_woken == MFALSE) {
3935 				priv->phandle->meas_wait_q_woken = MTRUE;
3936 				wake_up_interruptible(
3937 					&priv->phandle->meas_wait_q);
3938 			}
3939 
3940 			/* Execute delayed BSS START command */
3941 			if (priv->phandle->delay_bss_start == MTRUE) {
3942 				mlan_ioctl_req *req = NULL;
3943 				mlan_ds_bss *bss = NULL;
3944 
3945 				/* Clear flag */
3946 				priv->phandle->delay_bss_start = MFALSE;
3947 
3948 				PRINTM(MMSG,
3949 				       "Now CAC measure period end. Execute delayed BSS Start command.\n");
3950 
3951 				req = woal_alloc_mlan_ioctl_req(
3952 					sizeof(mlan_ds_bss));
3953 				if (!req) {
3954 					PRINTM(MERROR,
3955 					       "Failed to allocate ioctl request buffer\n");
3956 					goto done;
3957 				}
3958 				bss = (mlan_ds_bss *)req->pbuf;
3959 				req->req_id = MLAN_IOCTL_BSS;
3960 				req->action = MLAN_ACT_SET;
3961 				bss->sub_command = MLAN_OID_BSS_START;
3962 				moal_memcpy_ext(
3963 					priv->phandle, &bss->param.ssid_bssid,
3964 					&priv->phandle->delay_ssid_bssid,
3965 					sizeof(mlan_ssid_bssid),
3966 					sizeof(mlan_ssid_bssid));
3967 
3968 				if (woal_request_ioctl(priv, req,
3969 						       MOAL_NO_WAIT) !=
3970 				    MLAN_STATUS_PENDING) {
3971 					PRINTM(MERROR,
3972 					       "Delayed BSS Start operation failed!\n");
3973 					kfree(req);
3974 				}
3975 
3976 				PRINTM(MMSG, "BSS START Complete!\n");
3977 			}
3978 #ifdef UAP_SUPPORT
3979 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
3980 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
3981 			if (priv->uap_host_based &&
3982 			    moal_extflg_isset(priv->phandle, EXT_DFS_OFFLOAD))
3983 				woal_cfg80211_dfs_vendor_event(
3984 					priv, event_dfs_cac_finished,
3985 					&priv->chan);
3986 #endif
3987 #endif
3988 #endif
3989 		}
3990 		break;
3991 	case MLAN_EVENT_ID_DRV_TDLS_TEARDOWN_REQ:
3992 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
3993 #ifdef STA_CFG80211
3994 		if (IS_STA_CFG80211(cfg80211_wext)) {
3995 			tdls_tear_down_event *tdls_event =
3996 				(tdls_tear_down_event *)pmevent->event_buf;
3997 			cfg80211_tdls_oper_request(priv->netdev,
3998 						   tdls_event->peer_mac_addr,
3999 						   NL80211_TDLS_TEARDOWN,
4000 						   tdls_event->reason_code,
4001 						   GFP_KERNEL);
4002 		}
4003 #endif
4004 #endif
4005 		break;
4006 	case MLAN_EVENT_ID_FW_TX_STATUS: {
4007 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
4008 		unsigned long flag;
4009 		tx_status_event *tx_status =
4010 			(tx_status_event *)(pmevent->event_buf + 4);
4011 		struct tx_status_info *tx_info = NULL;
4012 		PRINTM(MINFO,
4013 		       "Receive Tx status: tx_token=%d, pkt_type=0x%x, status=%d tx_seq_num=%d\n",
4014 		       tx_status->tx_token_id, tx_status->packet_type,
4015 		       tx_status->status, priv->tx_seq_num);
4016 		spin_lock_irqsave(&priv->tx_stat_lock, flag);
4017 		tx_info = woal_get_tx_info(priv, tx_status->tx_token_id);
4018 		if (tx_info) {
4019 			bool ack;
4020 			struct sk_buff *skb = (struct sk_buff *)tx_info->tx_skb;
4021 			list_del(&tx_info->link);
4022 			spin_unlock_irqrestore(&priv->tx_stat_lock, flag);
4023 			if (!tx_status->status)
4024 				ack = true;
4025 			else
4026 				ack = false;
4027 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
4028 			if (priv->phandle->remain_on_channel &&
4029 			    tx_info->cancel_remain_on_channel) {
4030 				remain_priv =
4031 					priv->phandle->priv
4032 						[priv->phandle->remain_bss_index];
4033 				if (remain_priv) {
4034 					woal_cfg80211_remain_on_channel_cfg(
4035 						remain_priv, MOAL_NO_WAIT,
4036 						MTRUE, &channel_status, NULL, 0,
4037 						0);
4038 					priv->phandle->remain_on_channel =
4039 						MFALSE;
4040 				}
4041 			}
4042 #endif
4043 			PRINTM(MEVENT, "Wlan: Tx status=%d\n", ack);
4044 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
4045 			if (tx_info->tx_cookie) {
4046 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
4047 #if CFG80211_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
4048 				cfg80211_mgmt_tx_status(priv->netdev,
4049 							tx_info->tx_cookie,
4050 							skb->data, skb->len,
4051 							ack, GFP_ATOMIC);
4052 #else
4053 				cfg80211_mgmt_tx_status(priv->wdev,
4054 							tx_info->tx_cookie,
4055 							skb->data, skb->len,
4056 							ack, GFP_ATOMIC);
4057 #endif
4058 #endif
4059 			}
4060 #if defined(STA_CFG80211) || defined(UAP_CFG80211)
4061 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
4062 			woal_packet_fate_monitor(priv, PACKET_TYPE_TX,
4063 						 ack ? TX_PKT_FATE_ACKED :
4064 						       TX_PKT_FATE_SENT,
4065 						 FRAME_TYPE_80211_MGMT, 0, 0,
4066 						 skb->data, skb->len);
4067 #endif
4068 #endif
4069 #endif
4070 			dev_kfree_skb_any(skb);
4071 			kfree(tx_info);
4072 		} else {
4073 			spin_unlock_irqrestore(&priv->tx_stat_lock, flag);
4074 		}
4075 #endif
4076 	} break;
4077 	case MLAN_EVENT_ID_DRV_FT_RESPONSE:
4078 		if (priv->phandle->fw_roam_enable)
4079 			break;
4080 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
4081 #ifdef STA_CFG80211
4082 		if (IS_STA_CFG80211(cfg80211_wext)) {
4083 			struct cfg80211_ft_event_params ft_event;
4084 			if (priv->ft_pre_connect)
4085 				break;
4086 			memset(&ft_event, 0,
4087 			       sizeof(struct cfg80211_ft_event_params));
4088 			PRINTM(MMSG,
4089 			       "wlan : FT response  target AP " MACSTR "\n",
4090 			       MAC2STR((t_u8 *)pmevent->event_buf));
4091 			DBG_HEXDUMP(MDAT_D, "FT-event ", pmevent->event_buf,
4092 				    pmevent->event_len);
4093 			moal_memcpy_ext(priv->phandle, priv->target_ap_bssid,
4094 					pmevent->event_buf, ETH_ALEN, ETH_ALEN);
4095 			ft_event.target_ap = priv->target_ap_bssid;
4096 			ft_event.ies = pmevent->event_buf + ETH_ALEN;
4097 			ft_event.ies_len = pmevent->event_len - ETH_ALEN;
4098 			/*TSPEC info is needed by RIC, However the TS operation
4099 			 * is configured by mlanutl*/
4100 			/*So do not add RIC temporally*/
4101 			/*when add RIC, 1. query TS status, 2. copy tspec from
4102 			 * addts command*/
4103 			ft_event.ric_ies = NULL;
4104 			ft_event.ric_ies_len = 0;
4105 
4106 			cfg80211_ft_event(priv->netdev, &ft_event);
4107 			priv->ft_pre_connect = MTRUE;
4108 
4109 			if (priv->ft_roaming_triggered_by_driver ||
4110 			    !(priv->ft_cap & MBIT(0))) {
4111 				priv->ft_wait_condition = MTRUE;
4112 				wake_up(&priv->ft_wait_q);
4113 			}
4114 		}
4115 #endif
4116 #endif
4117 		break;
4118 	case MLAN_EVENT_ID_FW_ROAM_OFFLOAD_RESULT:
4119 #ifdef STA_CFG80211
4120 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
4121 		woal_cfg80211_vendor_event(priv, event_set_key_mgmt_offload,
4122 					   &enable, sizeof(enable));
4123 #endif
4124 		moal_memcpy_ext(priv->phandle, priv->cfg_bssid,
4125 				pmevent->event_buf, ETH_ALEN, ETH_ALEN);
4126 		tlv = (MrvlIEtypesHeader_t *)((t_u8 *)pmevent->event_buf +
4127 					      MLAN_MAC_ADDR_LENGTH);
4128 		tlv_buf_left = pmevent->event_len - MLAN_MAC_ADDR_LENGTH;
4129 		while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
4130 			tlv_type = woal_le16_to_cpu(tlv->type);
4131 			tlv_len = woal_le16_to_cpu(tlv->len);
4132 
4133 			if (tlv_buf_left <
4134 			    (tlv_len + sizeof(MrvlIEtypesHeader_t))) {
4135 				PRINTM(MERROR,
4136 				       "Error processing firmware roam success TLVs, bytes left < TLV length\n");
4137 				break;
4138 			}
4139 
4140 			switch (tlv_type) {
4141 			case TLV_TYPE_APINFO:
4142 				pinfo = (apinfo *)tlv;
4143 				break;
4144 			case TLV_TYPE_ASSOC_REQ_IE:
4145 				req_tlv = (apinfo *)tlv;
4146 				break;
4147 			default:
4148 				break;
4149 			}
4150 			tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
4151 			tlv = (MrvlIEtypesHeader_t
4152 				       *)((t_u8 *)tlv + tlv_len +
4153 					  sizeof(MrvlIEtypesHeader_t));
4154 		}
4155 		if (!pinfo) {
4156 			PRINTM(MERROR,
4157 			       "ERROR:AP info in roaming event buffer is NULL\n");
4158 			goto done;
4159 		}
4160 		if (req_tlv) {
4161 			req_ie = req_tlv->rsp_ie;
4162 			ie_len = req_tlv->header.len;
4163 		}
4164 		woal_inform_bss_from_scan_result(priv, NULL, MOAL_NO_WAIT);
4165 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
4166 		roam_info =
4167 			kzalloc(sizeof(struct cfg80211_roam_info), GFP_ATOMIC);
4168 		if (roam_info) {
4169 #if ((CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)) || IMX_ANDROID_13)
4170 			roam_info->links[0].bssid = priv->cfg_bssid;
4171 #else
4172 			roam_info->bssid = priv->cfg_bssid;
4173 #endif
4174 			roam_info->req_ie = req_ie;
4175 			roam_info->req_ie_len = ie_len;
4176 			roam_info->resp_ie = pinfo->rsp_ie;
4177 			roam_info->resp_ie_len = pinfo->header.len;
4178 			cfg80211_roamed(priv->netdev, roam_info, GFP_KERNEL);
4179 			kfree(roam_info);
4180 		}
4181 #else
4182 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
4183 		cfg80211_roamed(priv->netdev, NULL, priv->cfg_bssid, req_ie,
4184 				ie_len, pinfo->rsp_ie, pinfo->header.len,
4185 				GFP_KERNEL);
4186 #else
4187 		cfg80211_roamed(priv->netdev, priv->cfg_bssid, req_ie, ie_len,
4188 				pinfo->rsp_ie, pinfo->header.len, GFP_KERNEL);
4189 #endif
4190 #endif
4191 
4192 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
4193 		woal_roam_ap_info(priv, pmevent->event_buf, pmevent->event_len);
4194 #endif
4195 #endif
4196 		PRINTM(MMSG, "FW Roamed to bssid " MACSTR " successfully\n",
4197 		       MAC2STR(pmevent->event_buf));
4198 		break;
4199 	case MLAN_EVENT_ID_CSI:
4200 		DBG_HEXDUMP(MEVT_D, "CSI dump", pmevent->event_buf,
4201 			    pmevent->event_len);
4202 #ifdef STA_CFG80211
4203 #if CFG80211_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
4204 		if (priv->csi_enable)
4205 			woal_cfg80211_event_csi_dump(priv, pmevent->event_buf,
4206 						     pmevent->event_len);
4207 #endif
4208 #endif
4209 		/* Send Netlink event */
4210 		custom_len = strlen(CUS_EVT_CSI) + sizeof(priv->csi_seq);
4211 		csi_len = pmevent->event_len;
4212 		memmove(pmevent->event_buf + custom_len, pmevent->event_buf,
4213 			csi_len);
4214 		moal_memcpy_ext(priv->phandle, pmevent->event_buf, CUS_EVT_CSI,
4215 				strlen(CUS_EVT_CSI), strlen(CUS_EVT_CSI));
4216 		moal_memcpy_ext(priv->phandle,
4217 				pmevent->event_buf + strlen(CUS_EVT_CSI),
4218 				(t_u8 *)(&(priv->csi_seq)),
4219 				sizeof(priv->csi_seq), sizeof(priv->csi_seq));
4220 		woal_broadcast_event(priv, pmevent->event_buf,
4221 				     custom_len + csi_len);
4222 		priv->csi_seq++;
4223 		break;
4224 	default:
4225 		break;
4226 	}
4227 done:
4228 	LEAVE();
4229 	return MLAN_STATUS_SUCCESS;
4230 }
4231 
4232 /**
4233  *  @brief This function prints the debug message in mlan
4234  *
4235  *  @param pmoal Pointer to the MOAL context
4236  *  @param level    debug level
4237  *  @param pformat  point to string format buf
4238  *
4239  *  @return         N/A
4240  */
4241 __attribute__((format(printf, 3, 4))) t_void
4242 moal_print(t_void *pmoal, t_u32 level, char *pformat, IN...)
4243 {
4244 #ifdef DEBUG_LEVEL1
4245 	va_list args;
4246 
4247 	if (level & MHEX_DUMP) {
4248 		t_u8 *buf = NULL;
4249 		int len = 0;
4250 
4251 		va_start(args, pformat);
4252 		buf = (t_u8 *)va_arg(args, t_u8 *);
4253 		len = (int)va_arg(args, int);
4254 		va_end(args);
4255 
4256 #ifdef DEBUG_LEVEL2
4257 		if (level & MINFO)
4258 			HEXDUMP((char *)pformat, buf, len);
4259 		else
4260 #endif /* DEBUG_LEVEL2 */
4261 		{
4262 			if (level & MERROR)
4263 				DBG_HEXDUMP(MERROR, (char *)pformat, buf, len);
4264 			if (level & MCMD_D)
4265 				DBG_HEXDUMP(MCMD_D, (char *)pformat, buf, len);
4266 			if (level & MDAT_D)
4267 				DBG_HEXDUMP(MDAT_D, (char *)pformat, buf, len);
4268 			if (level & MIF_D)
4269 				DBG_HEXDUMP(MIF_D, (char *)pformat, buf, len);
4270 			if (level & MFW_D)
4271 				DBG_HEXDUMP(MFW_D, (char *)pformat, buf, len);
4272 			if (level & MEVT_D)
4273 				DBG_HEXDUMP(MEVT_D, (char *)pformat, buf, len);
4274 		}
4275 	} else {
4276 		if (drvdbg & level) {
4277 			va_start(args, pformat);
4278 			vprintk(pformat, args);
4279 			va_end(args);
4280 		}
4281 	}
4282 #endif /* DEBUG_LEVEL1 */
4283 }
4284 
4285 /**
4286  *  @brief This function prints the network interface name
4287  *
4288  *  @param pmoal Pointer to the MOAL context
4289  *  @param bss_index    BSS index
4290  *  @param level        debug level
4291  *
4292  *  @return            N/A
4293  */
4294 t_void moal_print_netintf(t_void *pmoal, t_u32 bss_index, t_u32 level)
4295 {
4296 #ifdef DEBUG_LEVEL1
4297 	moal_handle *phandle = (moal_handle *)pmoal;
4298 
4299 	if (phandle) {
4300 		if ((bss_index < MLAN_MAX_BSS_NUM) &&
4301 		    phandle->priv[bss_index] &&
4302 		    phandle->priv[bss_index]->netdev) {
4303 			if (drvdbg & level)
4304 				printk("%s: ",
4305 				       phandle->priv[bss_index]->netdev->name);
4306 		}
4307 	}
4308 #endif /* DEBUG_LEVEL1 */
4309 }
4310 
4311 /**
4312  *  @brief This function asserts the existence of the passed argument
4313  *
4314  *  @param pmoal     A pointer to moal_private structure
4315  *  @param cond             Condition to check
4316  *
4317  *  @return                 N/A
4318  */
4319 t_void moal_assert(t_void *pmoal, t_u32 cond)
4320 {
4321 	if (!cond) {
4322 		panic("Assert failed: Panic!");
4323 	}
4324 }
4325 
4326 /**
4327  *  @brief This function save the histogram data
4328  *
4329  *  @param pmoal     A pointer to moal_private structure
4330  *  @param bss_index        BSS index
4331  *  @param rx_rate          rx rate index
4332  *  @param snr              snr
4333  *  @param nflr             noise floor
4334  *  @param antenna          antenna
4335  *
4336  *  @return                 N/A
4337  */
4338 t_void moal_hist_data_add(t_void *pmoal, t_u32 bss_index, t_u16 rx_rate,
4339 			  t_s8 snr, t_s8 nflr, t_u8 antenna)
4340 {
4341 	moal_private *priv = NULL;
4342 	priv = woal_bss_index_to_priv(pmoal, bss_index);
4343 	if (priv && antenna >= priv->phandle->card_info->histogram_table_num)
4344 		antenna = 0;
4345 	if (priv && priv->hist_data[antenna])
4346 		woal_hist_data_add(priv, rx_rate, snr, nflr, antenna);
4347 }
4348 
4349 /**
4350  *  @brief This function update the peer signal
4351  *
4352  *  @param pmoal     A pointer to moal_private structure
4353  *  @param bss_index        BSS index
4354  *  @param peer_addr        peer address
4355  *  @param snr              snr
4356  *  @param nflr             noise floor
4357  *
4358  *  @return                 N/A
4359  */
4360 t_void moal_updata_peer_signal(t_void *pmoal, t_u32 bss_index, t_u8 *peer_addr,
4361 			       t_s8 snr, t_s8 nflr)
4362 {
4363 	moal_private *priv = NULL;
4364 	struct tdls_peer *peer = NULL;
4365 	unsigned long flags;
4366 	priv = woal_bss_index_to_priv(pmoal, bss_index);
4367 	if (priv && priv->enable_auto_tdls) {
4368 		spin_lock_irqsave(&priv->tdls_lock, flags);
4369 		list_for_each_entry (peer, &priv->tdls_list, link) {
4370 			if (!memcmp(peer->peer_addr, peer_addr, ETH_ALEN)) {
4371 				peer->rssi = nflr - snr;
4372 				peer->rssi_jiffies = jiffies;
4373 				break;
4374 			}
4375 		}
4376 		spin_unlock_irqrestore(&priv->tdls_lock, flags);
4377 	}
4378 }
4379 
4380 /**
4381  *  @brief Performs division of 64-bit num with base
4382  *  @brief do_div does two things
4383  *  @brief 1. modifies the 64-bit num in place with
4384  *  @brief the quotient, i.e., num becomes quotient
4385  *  @brief 2. do_div() returns the 32-bit reminder
4386  *
4387  *  @param num   dividend
4388  *  @param base  divisor
4389  *  @return      returns 64-bit quotient
4390  */
4391 t_u64 moal_do_div(t_u64 num, t_u32 base)
4392 {
4393 	t_u64 val = num;
4394 	do_div(val, base);
4395 	return val;
4396 }
4397 
4398 #if defined(DRV_EMBEDDED_AUTHENTICATOR) || defined(DRV_EMBEDDED_SUPPLICANT)
4399 /**
4400  *  @brief Performs wait event
4401  *
4402  *  @param pmoal   t_void
4403  *  @param bss_index      index of priv
4404  *  @return      MLAN_STATUS_SUCCESS
4405  */
4406 mlan_status moal_wait_hostcmd_complete(t_void *pmoal, t_u32 bss_index)
4407 {
4408 	mlan_status status = MLAN_STATUS_SUCCESS;
4409 	moal_handle *handle = (moal_handle *)pmoal;
4410 	moal_private *priv = woal_bss_index_to_priv(handle, bss_index);
4411 	long time_left = 0;
4412 
4413 	ENTER();
4414 
4415 	if (!priv) {
4416 		PRINTM(MERROR, "moal_wait_event: priv is null!\n");
4417 		goto done;
4418 	}
4419 
4420 	priv->hostcmd_wait_condition = MFALSE;
4421 	time_left = wait_event_timeout(priv->hostcmd_wait_q,
4422 				       priv->hostcmd_wait_condition,
4423 				       MOAL_IOCTL_TIMEOUT);
4424 
4425 	if (!time_left) {
4426 		PRINTM(MERROR, "moal_wait_event: wait timeout ");
4427 		status = MLAN_STATUS_FAILURE;
4428 	}
4429 
4430 done:
4431 	LEAVE();
4432 	return status;
4433 }
4434 
4435 /**
4436  *  @brief wake up esa wait_q
4437  *
4438  *  @param pmoal   t_void
4439  *  @param bss_index      index of priv
4440  *  @return      MLAN_STATUS_SUCCESS
4441  */
4442 mlan_status moal_notify_hostcmd_complete(t_void *pmoal, t_u32 bss_index)
4443 {
4444 	mlan_status status = MLAN_STATUS_SUCCESS;
4445 	moal_handle *handle = (moal_handle *)pmoal;
4446 	moal_private *priv = woal_bss_index_to_priv(handle, bss_index);
4447 
4448 	ENTER();
4449 
4450 	priv->hostcmd_wait_condition = MTRUE;
4451 	wake_up(&priv->hostcmd_wait_q);
4452 
4453 	LEAVE();
4454 	return status;
4455 }
4456 #endif
4457