1 /** @file wifi.c
2  *
3  *  @brief  This file provides WiFi Core API
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 #include <mlan_api.h>
12 
13 #include <stdio.h>
14 #include <string.h>
15 #include <wifi.h>
16 #include <osa.h>
17 
18 #include "wifi-internal.h"
19 #include <wm_net.h>
20 #if defined(RW610)
21 #include "wifi-imu.h"
22 #else
23 #include <mlan_sdio_api.h>
24 #include "wifi-sdio.h"
25 #include "mlan_sdio.h"
26 #include "sdio.h"
27 #include "firmware_dnld.h"
28 
29 #endif
30 #ifdef RW610
31 #include "fsl_adapter_rfimu.h"
32 #endif
33 
34 /* Always keep this include at the end of all include files */
35 #include <mlan_remap_mem_operations.h>
36 
37 #if CONFIG_HEAP_DEBUG
38 OSA_SEMAPHORE_HANDLE_DEFINE(os_mem_stat_sem);
39 
40 t_u32 valid_item_cnt = 0;
41 wifi_os_mem_info wifi_os_mem_stat[OS_MEM_STAT_TABLE_SIZE];
42 #endif
43 
44 #if CONFIG_CSI
45 #define MAX_CSI_LOCAL_BUF        80
46 #define CSI_LOCAL_BUF_ENTRY_SIZE 768
47 t_u8 csi_local_buff[MAX_CSI_LOCAL_BUF][CSI_LOCAL_BUF_ENTRY_SIZE] = {
48     0,
49 };
50 
51 csi_local_buff_statu csi_buff_stat = {0, 0, 0};
52 
53 int csi_event_cnt        = 0;
54 t_u64 csi_event_data_len = 0;
55 #endif
56 
57 #if CONFIG_ECSA
58 extern wifi_ecsa_status_control ecsa_status_control;
59 #endif
60 
61 #if !CONFIG_WIFI_CORE_STACK_SIZE
62 #define CONFIG_WIFI_CORE_STACK_SIZE (2048)
63 #endif
64 
65 #define MAX_MCAST_LEN (MLAN_MAX_MULTICAST_LIST_SIZE * MLAN_MAC_ADDR_LENGTH)
66 #if CONFIG_WiFi_878x
67 #define MAX_WAIT_TIME 20
68 #else
69 #define MAX_WAIT_TIME 3000
70 #endif
71 
72 #ifndef USB_SUPPORT_ENABLE
73 #define _T(x) x
74 #endif
75 
76 #if CONFIG_WMM
77 #define BOARD_DATA_BUFFER_ALIGN_SIZE 32
78 
79 SDK_ALIGN(uint8_t outbuf_arr[MAX_WMM_BUF_NUM][OUTBUF_WMM_LEN], BOARD_DATA_BUFFER_ALIGN_SIZE);
80 #endif
81 
82 #if CONFIG_TXPD_RXPD_V3
83 #define RXPD_CHAN_MASK 0x3FE0
84 #endif
85 
86 /* Global variable wm_rand_seed */
87 uint32_t wm_rand_seed = -1;
88 
89 #if CONFIG_WMM
90 OSA_SEMAPHORE_HANDLE_DEFINE(txbuf_sem);
91 #endif
92 
93 #if CONFIG_STA_AMPDU_TX
94 bool sta_ampdu_tx_enable         = true;
95 t_u8 sta_ampdu_tx_enable_per_tid = 0xFF;
96 #endif
97 
98 #if CONFIG_STA_AMPDU_RX
99 bool sta_ampdu_rx_enable         = true;
100 t_u8 sta_ampdu_rx_enable_per_tid = 0xFF;
101 #endif
102 
103 #if CONFIG_UAP_AMPDU_TX
104 bool uap_ampdu_tx_enable         = true;
105 t_u8 uap_ampdu_tx_enable_per_tid = 0xFF;
106 #endif
107 
108 #if CONFIG_UAP_AMPDU_RX
109 bool uap_ampdu_rx_enable         = true;
110 t_u8 uap_ampdu_rx_enable_per_tid = 0xFF;
111 #endif
112 
113 /* tx status: 0-RUNNING, 1-BLOCK */
114 t_u8 wifi_tx_status = WIFI_DATA_RUNNING;
115 /* tx data count blocked */
116 t_u8 wifi_tx_block_cnt = 0;
117 /* rx status: 0-RUNNING, 1-BLOCK */
118 t_u8 wifi_rx_status = WIFI_DATA_RUNNING;
119 /* rx data count blocked */
120 t_u8 wifi_rx_block_cnt = 0;
121 
122 int retry_attempts;
123 wm_wifi_t wm_wifi;
124 static bool xfer_pending;
125 static bool scan_thread_in_process = false;
126 
127 #if CONFIG_HOST_SLEEP
128 OSA_SEMAPHORE_HANDLE_DEFINE(wakelock);
129 int wakeup_by = 0;
130 #endif
131 #if CONFIG_WIFI_RECOVERY
132 bool wifi_recovery_enable = false;
133 t_u16 wifi_recovery_cnt   = 0;
134 #endif
135 bool wifi_shutdown_enable = false;
136 
137 typedef enum __mlan_status
138 {
139     MLAN_STATUS_FW_DNLD_SKIP = 1,
140     MLAN_CARD_NOT_DETECTED   = 3,
141     MLAN_STATUS_FW_DNLD_FAILED,
142     MLAN_STATUS_FW_NOT_DETECTED,
143     MLAN_STATUS_FW_NOT_READY,
144 #if CONFIG_XZ_DECOMPRESSION
145     MLAN_STATUS_FW_XZ_FAILED,
146 #endif /* CONFIG_XZ_DECOMPRESSION */
147     MLAN_CARD_CMD_TIMEOUT
148 } __mlan_status;
149 #ifndef RW610
150 
151 static void wifi_core_task(osa_task_param_t arg);
152 
153 /* OSA_TASKS: name, priority, instances, stackSz, useFloat */
154 static OSA_TASK_DEFINE(wifi_core_task, OSA_PRIORITY_HIGH, 1, CONFIG_WIFI_CORE_STACK_SIZE, 0);
155 
156 #endif
157 
158 #if !CONFIG_WIFI_SCAN_STACK_SIZE
159 #define CONFIG_WIFI_SCAN_STACK_SIZE (2048)
160 #endif
161 
162 static void wifi_scan_task(osa_task_param_t arg);
163 
164 /* OSA_TASKS: name, priority, instances, stackSz, useFloat */
165 static OSA_TASK_DEFINE(wifi_scan_task, OSA_PRIORITY_NORMAL, 1, CONFIG_WIFI_SCAN_STACK_SIZE, 0);
166 
167 #if !CONFIG_WIFI_DRIVER_STACK_SIZE
168 #define CONFIG_WIFI_DRIVER_STACK_SIZE (2048)
169 #endif
170 
171 static void wifi_drv_task(osa_task_param_t arg);
172 
173 /* OSA_TASKS: name, priority, instances, stackSz, useFloat */
174 static OSA_TASK_DEFINE(wifi_drv_task, OSA_PRIORITY_HIGH, 1, CONFIG_WIFI_DRIVER_STACK_SIZE, 0);
175 
176 #if CONFIG_WMM
177 
178 #if !CONFIG_WIFI_DRV_TX_STACK_SIZE
179 #define CONFIG_WIFI_DRV_TX_STACK_SIZE (2048)
180 #endif
181 
182 static void wifi_drv_tx_task(osa_task_param_t arg);
183 
184 /* OSA_TASKS: name, priority, instances, stackSz, useFloat */
185 #ifdef RW610
186 static OSA_TASK_DEFINE(wifi_drv_tx_task, OSA_PRIORITY_ABOVE_NORMAL, 1, CONFIG_WIFI_DRV_TX_STACK_SIZE, 0);
187 #else
188 static OSA_TASK_DEFINE(wifi_drv_tx_task, OSA_PRIORITY_HIGH, 1, CONFIG_WIFI_DRV_TX_STACK_SIZE, 0);
189 #endif
190 #endif
191 
192 #if !CONFIG_WIFI_POWERSAVE_STACK_SIZE
193 #define CONFIG_WIFI_POWERSAVE_STACK_SIZE (1024)
194 #endif
195 
196 static void wifi_powersave_task(osa_task_param_t arg);
197 
198 /* OSA_TASKS: name, priority, instances, stackSz, useFloat */
199 static OSA_TASK_DEFINE(wifi_powersave_task, OSA_PRIORITY_NORMAL, 1, CONFIG_WIFI_POWERSAVE_STACK_SIZE, 0);
200 
201 int wifi_set_mac_multicast_addr(const char *mlist, t_u32 num_of_addr);
202 int wrapper_get_wpa_ie_in_assoc(uint8_t *wpa_ie);
203 
204 #if CONFIG_HOST_SLEEP
wakelock_get(void)205 int wakelock_get(void)
206 {
207     int ret = WM_SUCCESS;
208 #if CONFIG_POWER_MANAGER
209     ret = OSA_SemaphorePost((osa_semaphore_handle_t)wakelock);
210     if (ret != WM_SUCCESS)
211         wifi_e("Failed to get wakelock");
212 #endif
213     return ret;
214 }
215 
wakelock_put(void)216 int wakelock_put(void)
217 {
218     int ret = WM_SUCCESS;
219 #if CONFIG_POWER_MANAGER
220     ret = OSA_SemaphoreWait((osa_semaphore_handle_t)wakelock, 0);
221     if (ret != WM_SUCCESS)
222         wifi_e("Failed to put wakelock");
223 #endif
224     return ret;
225 }
226 
wakelock_isheld(void)227 int wakelock_isheld(void)
228 {
229 #if CONFIG_POWER_MANAGER
230     return OSA_SemaphoreGetCount((osa_semaphore_handle_t)wakelock);
231 #else
232     return 1;
233 #endif
234 }
235 #endif
236 extern void process_pkt_hdrs(void *pbuf, t_u32 payloadlen, t_u8 interface, t_u8 tid, t_u32 tx_control);
237 
wifi_get_last_cmd_sent_ms(void)238 unsigned wifi_get_last_cmd_sent_ms(void)
239 {
240     return wm_wifi.last_sent_cmd_msec;
241 }
242 
wifi_get_value1(void)243 uint32_t wifi_get_value1(void)
244 {
245     return wifi_get_device_value1();
246 }
247 
248 /* Wake up Wi-Fi card */
wifi_wake_up_card(uint32_t * resp)249 void wifi_wake_up_card(uint32_t *resp)
250 {
251 #if CONFIG_WIFI_PS_DEBUG
252     wcmdr_d("Wakeup device...");
253 #endif
254 
255 #ifndef RW610
256     (void)sdio_drv_creg_write(0x0, 1, 0x02, resp);
257 #else
258     imu_wakeup_card();
259 #endif
260 }
261 
262 /* When Wi-Fi card is in IEEE PS and sleeping
263  * CMD or Data cannot be transmited.
264  * The card must be woken up.
265  * So data or command trasnfer is temporarily kept
266  * in pending state. This function returns value
267  * of pending flag true/false.
268  */
wifi_get_xfer_pending(void)269 bool wifi_get_xfer_pending(void)
270 {
271     return xfer_pending;
272 }
273 /*
274  * This function sets the flag value
275  */
wifi_set_xfer_pending(bool xfer_val)276 void wifi_set_xfer_pending(bool xfer_val)
277 {
278     xfer_pending = xfer_val;
279 }
280 
wifi_update_last_cmd_sent_ms(void)281 void wifi_update_last_cmd_sent_ms(void)
282 {
283     wm_wifi.last_sent_cmd_msec = OSA_TimeGetMsec();
284 }
285 
wifi_get_command_resp_sem(unsigned long wait)286 static int wifi_get_command_resp_sem(unsigned long wait)
287 {
288     return OSA_SemaphoreWait((osa_semaphore_handle_t)wm_wifi.command_resp_sem, wait);
289 }
290 
wifi_put_command_resp_sem(void)291 int wifi_put_command_resp_sem(void)
292 {
293     return OSA_SemaphorePost((osa_semaphore_handle_t)wm_wifi.command_resp_sem);
294 }
295 
296 #define WL_ID_WIFI_CMD "wifi_cmd"
297 
wifi_get_command_lock(void)298 int wifi_get_command_lock(void)
299 {
300     osa_status_t status;
301 
302 #if CONFIG_HOST_SLEEP
303     wakelock_get();
304 #endif
305     status = OSA_MutexLock((osa_mutex_handle_t)wm_wifi.command_lock, osaWaitForever_c);
306 
307     if (status != KOSA_StatusSuccess)
308     {
309         return -WM_FAIL;
310     }
311 
312     return WM_SUCCESS;
313 }
314 
wifi_put_command_lock(void)315 int wifi_put_command_lock(void)
316 {
317     osa_status_t status;
318 
319 #if CONFIG_HOST_SLEEP
320     wakelock_put();
321 #endif
322     status = OSA_MutexUnlock((osa_mutex_handle_t)wm_wifi.command_lock);
323 
324     if (status != KOSA_StatusSuccess)
325     {
326         return -WM_FAIL;
327     }
328 
329     return WM_SUCCESS;
330 }
331 
wifi_get_mcastf_lock(void)332 static int wifi_get_mcastf_lock(void)
333 {
334     osa_status_t status;
335 
336     status = OSA_MutexLock((osa_mutex_handle_t)wm_wifi.mcastf_mutex, osaWaitForever_c);
337 
338     if (status != KOSA_StatusSuccess)
339     {
340         return -WM_FAIL;
341     }
342 
343     return WM_SUCCESS;
344 }
345 
wifi_put_mcastf_lock(void)346 static int wifi_put_mcastf_lock(void)
347 {
348     osa_status_t status;
349 
350     status = OSA_MutexUnlock((osa_mutex_handle_t)wm_wifi.mcastf_mutex);
351 
352     if (status != KOSA_StatusSuccess)
353     {
354         return -WM_FAIL;
355     }
356 
357     return WM_SUCCESS;
358 }
359 
360 #if CONFIG_WIFI_FW_DEBUG
361 
wifi_register_fw_dump_cb(int (* wifi_usb_mount_cb)(),int (* wifi_usb_file_open_cb)(char * test_file_name),int (* wifi_usb_file_write_cb)(uint8_t * data,size_t data_len),int (* wifi_usb_file_close_cb)())362 void wifi_register_fw_dump_cb(int (*wifi_usb_mount_cb)(),
363                               int (*wifi_usb_file_open_cb)(char *test_file_name),
364                               int (*wifi_usb_file_write_cb)(uint8_t *data, size_t data_len),
365                               int (*wifi_usb_file_close_cb)())
366 {
367     wm_wifi.wifi_usb_mount_cb      = wifi_usb_mount_cb;
368     wm_wifi.wifi_usb_file_open_cb  = wifi_usb_file_open_cb;
369     wm_wifi.wifi_usb_file_write_cb = wifi_usb_file_write_cb;
370     wm_wifi.wifi_usb_file_close_cb = wifi_usb_file_close_cb;
371 }
372 
373 #ifdef SD8801
374 
375 #define DEBUG_HOST_READY     0xEE
376 #define DEBUG_FW_DONE        0xFF
377 #define DEBUG_MEMDUMP_FINISH 0xFE
378 #define SDIO_SCRATCH_REG     0x60
379 #define DEBUG_ITCM_DONE      0xaa
380 #define DEBUG_DTCM_DONE      0xbb
381 #define DEBUG_SQRAM_DONE     0xcc
382 
383 #define DEBUG_DUMP_CTRL_REG  0x63
384 #define DEBUG_DUMP_FIRST_REG 0x62
385 #define DEBUG_DUMP_START_REG 0x64
386 #define DEBUG_DUMP_END_REG   0x6a
387 #define ITCM_SIZE            0x60000
388 
389 #define SQRAM_SIZE 0x33500
390 
391 #define DTCM_SIZE 0x14000
392 
393 char itcm_dump_file_name[]  = _T("1:/itcm.bin");
394 char dtcm_dump_file_name[]  = _T("1:/dtcm.bin");
395 char sqram_dump_file_name[] = _T("1:/sqram.bin");
396 
397 /**
398  *  @brief This function dump firmware memory to file
399  *
400  *  @return         N/A
401  */
wifi_dump_firmware_info()402 void wifi_dump_firmware_info()
403 {
404     int ret = 0;
405     unsigned int reg, reg_start, reg_end;
406     t_u8 ctrl_data = 0;
407     int tries;
408     t_u8 data[8], i;
409     uint32_t resp;
410     if (wm_wifi.wifi_usb_file_open_cb != NULL)
411     {
412         ret = wm_wifi.wifi_usb_file_open_cb(itcm_dump_file_name);
413         if (ret != WM_SUCCESS)
414         {
415             wifi_e("File opening failed");
416             goto done;
417         }
418     }
419     else
420     {
421         wifi_e("File open callback is not registered");
422         goto done;
423     }
424     reg_start = DEBUG_DUMP_START_REG;
425     reg_end   = DEBUG_DUMP_END_REG;
426     do
427     {
428         ret = sdio_drv_creg_write(DEBUG_DUMP_CTRL_REG, 1, DEBUG_HOST_READY, &resp);
429         if (!ret)
430         {
431             wifi_e("SDIO Write ERR");
432             goto done;
433         }
434 
435         for (tries = 0; tries < MAX_POLL_TRIES; tries++)
436         {
437             ret = sdio_drv_creg_read(DEBUG_DUMP_CTRL_REG, 1, &resp);
438             if (!ret)
439             {
440                 wifi_e("SDIO READ ERR");
441                 goto done;
442             }
443             ctrl_data = resp & 0xff;
444 
445             if ((ctrl_data == DEBUG_FW_DONE) || (ctrl_data == DEBUG_ITCM_DONE) || (ctrl_data == DEBUG_DTCM_DONE) ||
446                 (ctrl_data == DEBUG_SQRAM_DONE))
447                 break;
448             if (ctrl_data != DEBUG_HOST_READY)
449             {
450                 ret = sdio_drv_creg_write(DEBUG_DUMP_CTRL_REG, 1, DEBUG_HOST_READY, &resp);
451                 if (!ret)
452                 {
453                     wifi_e("SDIO Write ERR");
454                     goto done;
455                 }
456             }
457             OSA_TimeDelay(10);
458         }
459         if (ctrl_data == DEBUG_HOST_READY)
460         {
461             wifi_e("Fail to pull ctrl_data");
462             goto done;
463         }
464         reg = DEBUG_DUMP_FIRST_REG;
465         ret = sdio_drv_creg_read(reg, 1, &resp);
466         if (!ret)
467         {
468             wifi_e("SDIO READ ERR");
469             goto done;
470         }
471 
472         i = 0;
473         for (reg = reg_start; reg <= reg_end; reg++)
474         {
475             ret = sdio_drv_creg_read(reg, 1, &resp);
476             if (!ret)
477             {
478                 wifi_e("SDIO READ ERR");
479                 goto done;
480             }
481             data[i++] = resp & 0xff;
482         }
483 
484         dump_hex(data, sizeof(data));
485 
486         if (wm_wifi.wifi_usb_file_write_cb != NULL)
487         {
488             ret = wm_wifi.wifi_usb_file_write_cb(data, sizeof(data));
489             if (ret != WM_SUCCESS)
490             {
491                 wifi_e("File writing failed");
492                 goto done;
493             }
494         }
495         else
496         {
497             wifi_e("File write callback is not registered");
498             goto done;
499         }
500         switch (ctrl_data)
501         {
502             case DEBUG_ITCM_DONE:
503                 if (wm_wifi.wifi_usb_file_close_cb != NULL)
504                 {
505                     ret = wm_wifi.wifi_usb_file_close_cb();
506                     if (ret != WM_SUCCESS)
507                     {
508                         wifi_e("File closing failed");
509                         goto done;
510                     }
511                 }
512                 else
513                 {
514                     wifi_e("File close callback is not registered");
515                     goto done;
516                 }
517                 if (wm_wifi.wifi_usb_file_open_cb != NULL)
518                 {
519                     ret = wm_wifi.wifi_usb_file_open_cb(dtcm_dump_file_name);
520                     if (ret != WM_SUCCESS)
521                     {
522                         wifi_e("File opening failed");
523                         goto done;
524                     }
525                 }
526                 else
527                 {
528                     wifi_e("USB open callback is not registered");
529                     goto done;
530                 }
531                 break;
532             case DEBUG_DTCM_DONE:
533                 if (wm_wifi.wifi_usb_file_close_cb != NULL)
534                 {
535                     ret = wm_wifi.wifi_usb_file_close_cb();
536                     if (ret != WM_SUCCESS)
537                     {
538                         wifi_e("File closing failed");
539                         goto done;
540                     }
541                 }
542                 else
543                 {
544                     wifi_e("File close callback is not registered");
545                     goto done;
546                 }
547                 if (wm_wifi.wifi_usb_file_open_cb != NULL)
548                 {
549                     ret = wm_wifi.wifi_usb_file_open_cb(sqram_dump_file_name);
550                     if (ret != WM_SUCCESS)
551                     {
552                         wifi_e("File opening failed");
553                         goto done;
554                     }
555                 }
556                 else
557                 {
558                     wifi_e("USB open cb is not registered");
559                     goto done;
560                 }
561                 break;
562             case DEBUG_SQRAM_DONE:
563                 if (wm_wifi.wifi_usb_file_close_cb != NULL)
564                 {
565                     ret = wm_wifi.wifi_usb_file_close_cb();
566                     if (ret != WM_SUCCESS)
567                     {
568                         wifi_e("File closing failed");
569                         goto done;
570                     }
571                     wifi_d("End output!");
572                 }
573                 else
574                 {
575                     wifi_e("File close callback is not registered");
576                     goto done;
577                 }
578                 break;
579             default:
580                 wifi_d("Unexpected wifi debug \n");
581                 break;
582         }
583     } while (ctrl_data != DEBUG_SQRAM_DONE);
584 
585     wifi_d("The output ITCM/DTCM/SQRAM have been saved to files successfully!");
586     /* end dump fw memory */
587 done:
588 
589     while (1)
590         ;
591 }
592 
593 #ifndef RW610
594 /**
595  *  @brief This function reads and displays SDIO registers for debugging
596  *
597  *  @return         N/A
598  */
wifi_sdio_reg_dbg()599 void wifi_sdio_reg_dbg()
600 {
601     int ret = 0;
602     t_u8 loop, index = 0, func, data;
603     unsigned int reg, reg_start, reg_end;
604     unsigned int scratch_reg = SDIO_SCRATCH_REG;
605     unsigned int reg_table[] = {0x28, 0x30, 0x34, 0x38, 0x3c};
606     char buf[256], *ptr;
607     uint32_t resp;
608 
609     for (loop = 0; loop < 5; loop++)
610     {
611         (void)memset(buf, 0, sizeof(buf));
612         ptr = buf;
613         if (loop == 0)
614         {
615             /* Read the registers of SDIO function0 */
616             func      = loop;
617             reg_start = 0;
618             reg_end   = 9;
619         }
620         else if (loop == 1)
621         {
622             /* Read the registers of SDIO function1 */
623             func      = loop;
624             reg_start = 4;
625             reg_end   = 9;
626         }
627         else if (loop == 2)
628         {
629             /* Read specific registers of SDIO function1 */
630             index     = 0;
631             func      = 1;
632             reg_start = reg_table[index++];
633             reg_end   = reg_table[ARRAY_SIZE(reg_table) - 1];
634         }
635         else
636         {
637             /* Read the scratch registers of SDIO function1 */
638             if (loop == 4)
639                 OSA_TimeDelay(1);
640             func      = 1;
641             reg_start = scratch_reg;
642             reg_end   = scratch_reg + 10;
643         }
644         if (loop != 2)
645             ptr += sprintf(ptr, "SDIO Func%d (%#x-%#x): ", func, reg_start, reg_end);
646         else
647             ptr += sprintf(ptr, "SDIO Func%d: ", func);
648         for (reg = reg_start; reg <= reg_end;)
649         {
650 #ifndef RW610
651             ret = sdio_drv_creg_read(reg, func, &resp);
652 #endif
653             data = resp & 0xff;
654             if (loop == 2)
655                 ptr += sprintf(ptr, "(%#x) ", reg);
656             if (!ret)
657                 ptr += sprintf(ptr, "%02x ", data);
658             else
659             {
660                 ptr += sprintf(ptr, "ERR");
661                 break;
662             }
663             if (loop == 2 && reg < reg_end)
664                 reg = reg_table[index++];
665             else
666                 reg++;
667         }
668         wifi_d("%s", buf);
669     }
670 }
671 #endif
672 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || \
673     defined(SD9177) || defined(RW610_SERIES)
674 
675 #define DEBUG_HOST_READY     0xCC
676 #define DEBUG_FW_DONE        0xFF
677 #define DEBUG_MEMDUMP_FINISH 0xFE
678 
679 #define DEBUG_DUMP_CTRL_REG    0xF9
680 #define DEBUG_DUMP_START_REG   0xF1
681 #define DEBUG_DUMP_END_REG     0xF8
682 #define SDIO_SCRATCH_REG       0xE8
683 #define DEBUG_DUMP_SCRATCH_REG (void *)0x41382488
684 
685 char fw_dump_file_name[] = _T("1:/fw_dump.bin");
686 
687 typedef enum
688 {
689     DUMP_TYPE_ITCM        = 0,
690     DUMP_TYPE_DTCM        = 1,
691     DUMP_TYPE_SQRAM       = 2,
692     DUMP_TYPE_APU_REGS    = 3,
693     DUMP_TYPE_CIU_REGS    = 4,
694     DUMP_TYPE_ICU_REGS    = 5,
695     DUMP_TYPE_MAC_REGS    = 6,
696     DUMP_TYPE_EXTEND_7    = 7,
697     DUMP_TYPE_EXTEND_8    = 8,
698     DUMP_TYPE_EXTEND_9    = 9,
699     DUMP_TYPE_EXTEND_10   = 10,
700     DUMP_TYPE_EXTEND_11   = 11,
701     DUMP_TYPE_EXTEND_12   = 12,
702     DUMP_TYPE_EXTEND_13   = 13,
703     DUMP_TYPE_EXTEND_LAST = 14
704 } dumped_mem_type;
705 
706 #define MAX_NAME_LEN      8
707 #define MAX_FULL_NAME_LEN 32
708 
709 typedef struct
710 {
711     t_u8 mem_name[MAX_NAME_LEN];
712     t_u8 *mem_Ptr;
713     struct file *pfile_mem;
714     t_u8 done_flag;
715     t_u8 type;
716 } memory_type_mapping;
717 
718 memory_type_mapping mem_type_mapping_tbl = {"DUMP", NULL, NULL, 0xDD};
719 
720 typedef enum
721 {
722     RDWR_STATUS_SUCCESS = 0,
723     RDWR_STATUS_FAILURE = 1,
724     RDWR_STATUS_DONE    = 2
725 } rdwr_status;
726 
727 /**
728  *  @brief This function read/write firmware via cmd52
729  *
730  *  @param doneflag  A flag
731  *
732  *  @return         MLAN_STATUS_SUCCESS
733  */
wifi_cmd52_rdwr_firmware(t_u8 doneflag)734 rdwr_status wifi_cmd52_rdwr_firmware(t_u8 doneflag)
735 {
736     int ret                = 0;
737     int tries              = 0;
738     t_u8 ctrl_data         = 0;
739     t_u8 dbg_dump_ctrl_reg = 0;
740     t_u8 debug_host_ready  = 0;
741     uint32_t resp;
742 
743     dbg_dump_ctrl_reg = DEBUG_DUMP_CTRL_REG;
744     debug_host_ready  = DEBUG_HOST_READY;
745 
746     ret = sdio_drv_creg_write(dbg_dump_ctrl_reg, 1, debug_host_ready, &resp);
747     if (!ret)
748     {
749         wifi_e("SDIO Write ERR");
750         return RDWR_STATUS_FAILURE;
751     }
752     for (tries = 0; tries < MAX_POLL_TRIES; tries++)
753     {
754         ret = sdio_drv_creg_read(dbg_dump_ctrl_reg, 1, &resp);
755         if (!ret)
756         {
757             wifi_e("SDIO READ ERR");
758             return RDWR_STATUS_FAILURE;
759         }
760         ctrl_data = resp & 0xff;
761         if (ctrl_data == DEBUG_FW_DONE)
762             break;
763         if (doneflag && ctrl_data == doneflag)
764             return RDWR_STATUS_DONE;
765         if (ctrl_data != debug_host_ready)
766         {
767             ret = sdio_drv_creg_write(dbg_dump_ctrl_reg, 1, debug_host_ready, &resp);
768             if (!ret)
769             {
770                 wifi_e("SDIO Write ERR");
771                 return RDWR_STATUS_FAILURE;
772             }
773         }
774         OSA_TimeDelay(1);
775     }
776     if (ctrl_data == debug_host_ready)
777     {
778         wifi_e("Fail to pull ctrl_data");
779         return RDWR_STATUS_FAILURE;
780     }
781 
782     return RDWR_STATUS_SUCCESS;
783 }
784 
785 /**
786  *  @brief This function dump firmware memory to file
787  *
788  *  @return         N/A
789  */
wifi_dump_firmware_info()790 void wifi_dump_firmware_info()
791 {
792     int ret   = 0;
793     int tries = 0;
794     unsigned int reg, reg_start, reg_end;
795     t_u8 start_flag = 0;
796     t_u8 doneflag   = 0;
797     rdwr_status stat;
798     t_u8 dbg_dump_start_reg                    = 0;
799     t_u8 dbg_dump_end_reg                      = 0;
800     memory_type_mapping *pmem_type_mapping_tbl = &mem_type_mapping_tbl;
801     t_u8 data[8], i;
802     uint32_t resp;
803 
804     dbg_dump_start_reg = DEBUG_DUMP_START_REG;
805     dbg_dump_end_reg   = DEBUG_DUMP_END_REG;
806 
807     /* read the number of the memories which will dump */
808     if (RDWR_STATUS_FAILURE == wifi_cmd52_rdwr_firmware(doneflag))
809         goto done;
810 
811     /** check the reg which indicate dump starting */
812     for (reg = dbg_dump_start_reg; reg <= dbg_dump_end_reg; reg++)
813     {
814         for (tries = 0; tries < MAX_POLL_TRIES; tries++)
815         {
816             ret = sdio_drv_creg_read(reg, 1, &resp);
817             if (!ret)
818             {
819                 wifi_e("SDIO READ ERR");
820                 goto done;
821             }
822             start_flag = resp & 0xff;
823             /** 0 means dump starting*/
824             if (start_flag == 0)
825                 break;
826             OSA_TimeDelay(1);
827         }
828         if (tries == MAX_POLL_TRIES)
829         {
830             wifi_d("FW not ready to dump");
831             goto done;
832         }
833     }
834     if (wm_wifi.wifi_usb_file_open_cb != NULL)
835     {
836         ret = wm_wifi.wifi_usb_file_open_cb(fw_dump_file_name);
837         if (ret != WM_SUCCESS)
838         {
839             wifi_e("File opening failed");
840             goto done;
841         }
842     }
843     else
844     {
845         wifi_e("File open callback is not registered");
846         goto done;
847     }
848 
849     doneflag = pmem_type_mapping_tbl->done_flag;
850     do
851     {
852         stat = wifi_cmd52_rdwr_firmware(doneflag);
853         if (RDWR_STATUS_FAILURE == stat)
854             goto done;
855 
856         reg_start = dbg_dump_start_reg;
857         reg_end   = dbg_dump_end_reg;
858         i         = 0;
859         for (reg = reg_start; reg <= reg_end; reg++)
860         {
861             ret = sdio_drv_creg_read(reg, 1, &resp);
862             if (!ret)
863             {
864                 wifi_e("SDIO READ ERR");
865                 goto done;
866             }
867             data[i++] = (resp & 0xff);
868         }
869         if (wm_wifi.wifi_usb_file_write_cb != NULL)
870         {
871             ret = wm_wifi.wifi_usb_file_write_cb(data, sizeof(data));
872             if (ret != WM_SUCCESS)
873             {
874                 wifi_e("File writing failed");
875                 goto done;
876             }
877         }
878         else
879         {
880             wifi_e("File write callback is not registered");
881             goto done;
882         }
883 
884         if (RDWR_STATUS_DONE == stat)
885         {
886             if (wm_wifi.wifi_usb_file_close_cb != NULL)
887             {
888                 ret = wm_wifi.wifi_usb_file_close_cb();
889                 if (ret != WM_SUCCESS)
890                 {
891                     wifi_e("File closing failed");
892                     goto done;
893                 }
894             }
895             else
896             {
897                 wifi_e("File close callback is not registered");
898                 goto done;
899             }
900             break;
901         }
902     } while (1);
903 
904     /* end dump fw memory */
905 done:
906     while (1)
907         ;
908 }
909 
910 #ifndef RW610
911 /**
912  *  @brief This function reads and displays SDIO registers for debugging
913  *
914  *  @return         N/A
915  */
wifi_sdio_reg_dbg()916 void wifi_sdio_reg_dbg()
917 {
918     int ret = 0;
919     t_u8 loop, index = 0, func, data;
920     unsigned int reg, reg_start, reg_end;
921     unsigned int scratch_reg = SDIO_SCRATCH_REG;
922     unsigned int reg_table[] = {0x08, 0x58, 0x5C, 0x5D, 0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x68, 0x69, 0x6a};
923     char buf[256], *ptr;
924     uint32_t resp;
925 
926     for (loop = 0; loop < 5; loop++)
927     {
928         (void)memset(buf, 0, sizeof(buf));
929         ptr = buf;
930         if (loop == 0)
931         {
932             /* Read the registers of SDIO function0 */
933             func      = loop;
934             reg_start = 0;
935             reg_end   = 9;
936         }
937         else if (loop == 1)
938         {
939             /* Read the registers of SDIO function1 */
940             func      = loop;
941             reg_start = 0x10;
942             reg_end   = 0x17;
943         }
944         else if (loop == 2)
945         {
946             /* Read specific registers of SDIO function1 */
947             index     = 0;
948             func      = 1;
949             reg_start = reg_table[index++];
950             reg_end   = reg_table[ARRAY_SIZE(reg_table) - 1];
951         }
952         else
953         {
954             /* Read the scratch registers of SDIO function1 */
955             if (loop == 4)
956                 OSA_TimeDelay(1);
957             func      = 1;
958             reg_start = scratch_reg;
959             reg_end   = scratch_reg + 10;
960         }
961         if (loop != 2)
962             ptr += sprintf(ptr, "SDIO Func%d (%#x-%#x): ", func, reg_start, reg_end);
963         else
964             ptr += sprintf(ptr, "SDIO Func%d: ", func);
965         for (reg = reg_start; reg <= reg_end;)
966         {
967             ret  = sdio_drv_creg_read(reg, func, &resp);
968             data = resp & 0xff;
969             if (loop == 2)
970                 ptr += sprintf(ptr, "(%#x) ", reg);
971             if (ret)
972                 ptr += sprintf(ptr, "%02x ", data);
973             else
974             {
975                 ptr += sprintf(ptr, "ERR");
976                 break;
977             }
978             if (loop == 2 && reg < reg_end)
979                 reg = reg_table[index++];
980             else
981                 reg++;
982         }
983         wifi_d("%s", buf);
984     }
985 }
986 #endif
987 
988 #elif defined(RW610)
989 /**
990  *  @brief This function dump firmware memory to file
991  *
992  *  @return         N/A
993  */
wifi_dump_firmware_info()994 void wifi_dump_firmware_info()
995 {
996     /*Dummy for RW610 */
997 }
998 
999 #endif
1000 #endif
1001 
1002 #if CONFIG_FW_VDLL
wifi_wait_for_vdllcmdresp(void * cmd_resp_priv)1003 int wifi_wait_for_vdllcmdresp(void *cmd_resp_priv)
1004 {
1005     int ret                 = WM_SUCCESS;
1006     HostCmd_DS_COMMAND *cmd = wifi_get_vdllcommand_buffer();
1007 #ifndef RW610
1008     t_u32 buf_len = MLAN_SDIO_BLOCK_SIZE;
1009     t_u32 tx_blocks;
1010 #endif
1011 
1012 #ifndef RW610
1013 #if (CONFIG_WIFI_CMD_RESP_DEBUG) && (CONFIG_FW_VDLL_DEBUG)
1014 
1015     wcmdr_d("VDLL CMD --- : 0x%x Size: %d Seq: %x", cmd->command, cmd->size, cmd->seq_num);
1016 #endif /* CONFIG_ENABLE_WARNING_LOGS || CONFIG_WIFI_CMD_RESP_DEBUG*/
1017 #endif
1018     if (cmd->size > WIFI_FW_CMDBUF_SIZE)
1019     {
1020         /*
1021          * This is a error added to be flagged during
1022          * development cycle. It is not expected to
1023          * occur in production. The legacy code below
1024          * only sents out MLAN_SDIO_BLOCK_SIZE or 2 *
1025          * MLAN_SDIO_BLOCK_SIZE sized packet. If ever
1026          * in future greater packet size generated then
1027          * this error will help to localize the problem.
1028          */
1029         wifi_e("cmd size greater than WIFI_FW_CMDBUF_SIZE\r\n");
1030         return -WM_FAIL;
1031     }
1032 
1033 #ifndef RW610
1034     tx_blocks = ((t_u32)cmd->size + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
1035 #endif
1036 
1037 #if defined(RW610)
1038     (void)wifi_send_cmdbuffer();
1039 #else
1040     (void)wifi_send_vdllcmdbuffer(tx_blocks, buf_len);
1041 #endif
1042 
1043     return ret;
1044 }
1045 #endif
1046 
1047 #if (CONFIG_WIFI_IND_DNLD)
1048 static int wifi_reinit(uint8_t fw_reload);
1049 t_u8 wifi_rx_block_cnt;
1050 t_u8 wifi_tx_block_cnt;
1051 
wlan_process_hang(uint8_t fw_reload)1052 void wlan_process_hang(uint8_t fw_reload)
1053 {
1054     int i, ret = WM_SUCCESS;
1055 
1056     if (mlan_adap->in_reset == true)
1057     {
1058         wifi_d("Already in process hanging");
1059         return;
1060     }
1061 
1062     wifi_d("Start to process hanging");
1063 
1064 #if CONFIG_WIFI_IND_RESET
1065     if (fw_reload == FW_RELOAD_NO_EMULATION)
1066     {
1067         (void)wifi_ind_reset_lock();
1068     }
1069 #endif
1070 
1071     /* Block TX data */
1072     wifi_set_tx_status(WIFI_DATA_BLOCK);
1073     /* Block RX data */
1074     wifi_set_rx_status(WIFI_DATA_BLOCK);
1075 
1076     if (is_split_scan_complete() == false)
1077     {
1078         wifi_user_scan_config_cleanup();
1079         (void)wifi_event_completion(WIFI_EVENT_SCAN_RESULT, WIFI_EVENT_REASON_FAILURE, NULL);
1080     }
1081 
1082     mlan_adap->in_reset = true;
1083     for (i = 0; i < (int)(MIN(MLAN_MAX_BSS_NUM, mlan_adap->priv_num)); i++)
1084     {
1085         if (mlan_adap->priv[i]->media_connected == MTRUE)
1086         {
1087             mlan_adap->priv[i]->media_connected = MFALSE;
1088 
1089             if (mlan_adap->priv[i]->bss_type == MLAN_BSS_TYPE_STA)
1090             {
1091             }
1092             else if (mlan_adap->priv[i]->bss_type == MLAN_BSS_TYPE_UAP)
1093             {
1094                 mlan_adap->priv[i]->uap_bss_started = MFALSE;
1095             }
1096         }
1097 
1098         if (mlan_adap->priv[i])
1099         {
1100             wlan_clean_txrx(mlan_adap->priv[i]);
1101         }
1102     }
1103 
1104     (void)wifi_event_completion(WIFI_EVENT_FW_HANG, WIFI_EVENT_REASON_SUCCESS, NULL);
1105 
1106     ret = wifi_reinit(fw_reload);
1107 
1108     if (ret != WM_SUCCESS)
1109     {
1110         ASSERT(0);
1111     }
1112 
1113     /* Unblock TX data */
1114     wifi_set_tx_status(WIFI_DATA_RUNNING);
1115     /* Unblock RX data */
1116     wifi_set_rx_status(WIFI_DATA_RUNNING);
1117     mlan_adap->in_reset = false;
1118     wifi_tx_block_cnt   = 0;
1119     wifi_rx_block_cnt   = 0;
1120 
1121 #if CONFIG_WIFI_IND_RESET
1122     wifi_ind_reset_stop();
1123 #endif
1124 
1125     (void)wifi_event_completion(WIFI_EVENT_FW_RESET, WIFI_EVENT_REASON_SUCCESS, NULL);
1126 
1127 #if CONFIG_WIFI_IND_RESET
1128     wifi_ind_reset_unlock();
1129 #endif
1130 }
1131 #endif
1132 
wifi_wait_for_cmdresp(void * cmd_resp_priv)1133 int wifi_wait_for_cmdresp(void *cmd_resp_priv)
1134 {
1135     int ret;
1136     HostCmd_DS_COMMAND *cmd = wifi_get_command_buffer();
1137 #ifndef RW610
1138     t_u32 buf_len = MLAN_SDIO_BLOCK_SIZE;
1139     t_u32 tx_blocks;
1140 #endif
1141     mlan_private *pmpriv    = (mlan_private *)mlan_adap->priv[0];
1142     mlan_adapter *pmadapter = pmpriv->adapter;
1143 
1144 #ifndef RW610
1145 #if (CONFIG_ENABLE_WARNING_LOGS) || (CONFIG_WIFI_CMD_RESP_DEBUG)
1146 
1147 #if !CONFIG_WIFI_PS_DEBUG
1148     if (cmd->command != HostCmd_CMD_802_11_PS_MODE_ENH)
1149     {
1150         wcmdr_d("CMD --- : 0x%x Size: %d Seq: %d", cmd->command, cmd->size, cmd->seq_num);
1151     }
1152 #else
1153     wcmdr_d("CMD --- : 0x%x Size: %d Seq: %d", cmd->command, cmd->size, cmd->seq_num);
1154 #endif
1155 
1156 #endif /* CONFIG_ENABLE_WARNING_LOGS || CONFIG_WIFI_CMD_RESP_DEBUG*/
1157 #endif
1158 
1159 #if CONFIG_WIFI_IND_RESET
1160     /* IR is in progress so any CMD coming during progress should be ignored */
1161     if (wifi_ind_reset_in_progress() == true)
1162     {
1163         (void)wifi_put_command_lock();
1164         return WM_SUCCESS;
1165     }
1166 #endif
1167 
1168 #if CONFIG_FW_VDLL
1169     while (pmadapter->vdll_in_progress == MTRUE)
1170     {
1171         OSA_TimeDelay(50);
1172     }
1173 #endif
1174 
1175     if (cmd->size > WIFI_FW_CMDBUF_SIZE)
1176     {
1177         /*
1178          * This is a error added to be flagged during
1179          * development cycle. It is not expected to
1180          * occur in production. The legacy code below
1181          * only sents out MLAN_SDIO_BLOCK_SIZE or 2 *
1182          * MLAN_SDIO_BLOCK_SIZE sized packet. If ever
1183          * in future greater packet size generated then
1184          * this error will help to localize the problem.
1185          */
1186         wifi_e("cmd size greater than WIFI_FW_CMDBUF_SIZE\r\n");
1187 #if CONFIG_WIFI_IND_RESET
1188         wifi_ind_reset_unlock();
1189 #endif
1190         (void)wifi_put_command_lock();
1191         return -WM_FAIL;
1192     }
1193 
1194 #if CONFIG_WIFI_RECOVERY
1195     if (wifi_recovery_enable)
1196     {
1197         wifi_w("Recovery in progress. command 0x%x skipped", cmd->command);
1198 #if CONFIG_WIFI_IND_RESET
1199         wifi_ind_reset_unlock();
1200 #endif
1201         wifi_put_command_lock();
1202         return -WM_FAIL;
1203     }
1204 #endif
1205     if (wifi_shutdown_enable)
1206     {
1207         wifi_w("FW shutdown in progress. command 0x%x skipped", cmd->command);
1208 #if CONFIG_WIFI_IND_RESET
1209         wifi_ind_reset_unlock();
1210 #endif
1211         wifi_put_command_lock();
1212         return -WM_FAIL;
1213     }
1214 
1215 #ifndef RW610
1216     tx_blocks = ((t_u32)cmd->size + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
1217 #endif
1218 
1219 #if !CONFIG_UART_WIFI_BRIDGE
1220     ret = OSA_RWLockReadLock(&sleep_rwlock, MAX_WAIT_TIME);
1221     if (ret != WM_SUCCESS)
1222     {
1223 #if CONFIG_WIFI_PS_DEBUG
1224         wifi_e("Failed to wakeup card");
1225 #endif
1226 #if CONFIG_WIFI_IND_RESET
1227         wifi_ind_reset_unlock();
1228 #endif
1229         // wakelock_put(WL_ID_LL_OUTPUT);
1230         (void)wifi_put_command_lock();
1231 #if CONFIG_WIFI_RECOVERY
1232         wifi_recovery_enable = true;
1233         return -WM_FAIL;
1234 #else
1235         assert(0);
1236 #endif
1237     }
1238 #endif
1239 #if CONFIG_WMM_UAPSD
1240     /*
1241      * No PS handshake between driver and FW for the uapsd case,
1242      * CMD should not wakeup FW, needs to wait to send till receiving PS_AWAKE Event from FW.
1243      */
1244     OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1245 #endif
1246     /*
1247      * This is the private pointer. Only the command response handler
1248      * function knows what it means or where it points to. It can be
1249      * NULL.
1250      */
1251     wm_wifi.cmd_resp_priv = cmd_resp_priv;
1252 #if defined(RW610)
1253     (void)wifi_send_cmdbuffer();
1254 #else
1255     (void)wifi_send_cmdbuffer(tx_blocks, buf_len);
1256 #endif
1257 #if !CONFIG_UART_WIFI_BRIDGE
1258     /* put the sleep_rwlock after send command but not wait for the command response,
1259      * for sleep confirm command, sleep confirm response(in wifi_process_ps_enh_response())
1260      * would try to get the sleep_rwlock until get it,
1261      * so here put the sleep_rwlock as early as possible.
1262      */
1263     (void)OSA_RWLockReadUnlock(&sleep_rwlock);
1264 #endif
1265 
1266     pmadapter->cmd_sent = MTRUE;
1267 
1268     /* Wait max 20 sec for the command response */
1269     ret = wifi_get_command_resp_sem(WIFI_COMMAND_RESPONSE_WAIT_MS);
1270     if (ret != WM_SUCCESS)
1271     {
1272         pmadapter->cmd_sent = MFALSE;
1273 #if CONFIG_ENABLE_WARNING_LOGS
1274         t_u32 outbuf_len = 0;
1275         HostCmd_DS_COMMAND *tmo_cmd =
1276             (HostCmd_DS_COMMAND *)((t_u8 *)wifi_get_outbuf((uint32_t *)(&outbuf_len)) + INTF_HEADER_LEN);
1277         wifi_w("Command response timed out. command 0x%x, len %d, seqno 0x%x", tmo_cmd->command, tmo_cmd->size,
1278                tmo_cmd->seq_num);
1279 #endif /* CONFIG_ENABLE_WARNING_LOGS */
1280 #if CONFIG_WIFI_FW_DEBUG
1281 #ifndef RW610
1282         wifi_sdio_reg_dbg();
1283         if (wm_wifi.wifi_usb_mount_cb != NULL)
1284         {
1285             ret = wm_wifi.wifi_usb_mount_cb();
1286             if (ret == WM_SUCCESS)
1287                 wifi_dump_firmware_info();
1288             else
1289             {
1290                 wifi_e("USB mounting failed");
1291             }
1292         }
1293         else
1294             wifi_e("USB mount callback is not registered");
1295 #else
1296         wifi_dump_firmware_info();
1297 #endif
1298 #endif
1299 #if CONFIG_WIFI_RECOVERY
1300         wifi_recovery_enable = true;
1301 #else
1302         /* assert as command flow cannot work anymore */
1303 #if (CONFIG_WIFI_IND_DNLD)
1304         wlan_process_hang(FW_RELOAD_SDIO_INBAND_RESET);
1305 #else
1306         ASSERT(0);
1307 #endif
1308 #endif
1309     }
1310 
1311     if (cmd->command == HostCmd_CMD_FUNC_SHUTDOWN)
1312     {
1313         wifi_shutdown_enable = true;
1314     }
1315 
1316     wm_wifi.cmd_resp_priv = NULL;
1317 #if CONFIG_WMM_UAPSD
1318     OSA_SemaphorePost((osa_semaphore_handle_t)uapsd_sem);
1319 #endif
1320     wifi_set_xfer_pending(false);
1321 #if CONFIG_WIFI_IND_RESET
1322     wifi_ind_reset_unlock();
1323 #endif
1324     (void)wifi_put_command_lock();
1325     return ret;
1326 }
1327 
1328 #if CONFIG_P2P
wifi_wfd_event(bool peer_event,bool action_frame,void * data)1329 void wifi_wfd_event(bool peer_event, bool action_frame, void *data)
1330 {
1331     struct wifi_wfd_event event;
1332 
1333     if (wm_wifi.wfd_event_queue)
1334     {
1335         event.peer_event   = peer_event;
1336         event.action_frame = action_frame;
1337         event.data         = data;
1338         (void)OSA_MsgQPut((osa_msgq_handle_t)wm_wifi.wfd_event_queue, &event);
1339     }
1340 }
1341 #endif
1342 
wifi_event_completion(enum wifi_event event,enum wifi_event_reason result,void * data)1343 int wifi_event_completion(enum wifi_event event, enum wifi_event_reason result, void *data)
1344 {
1345     struct wifi_message msg;
1346     if (wm_wifi.wlc_mgr_event_queue == MNULL)
1347     {
1348         wifi_e("wlc_mgr_event_queue has not been created, event %d", event);
1349         return -WM_FAIL;
1350     }
1351 
1352     msg.data   = data;
1353     msg.reason = result;
1354     msg.event  = (uint16_t)event;
1355     if (OSA_MsgQPut((osa_msgq_handle_t)wm_wifi.wlc_mgr_event_queue, &msg) != KOSA_StatusSuccess)
1356     {
1357         wifi_e("Failed to send response on Queue, event %d", event);
1358         return -WM_FAIL;
1359     }
1360     return WM_SUCCESS;
1361 }
1362 
cmp_mac_addr(uint8_t * mac_addr1,uint8_t * mac_addr2)1363 static int cmp_mac_addr(uint8_t *mac_addr1, uint8_t *mac_addr2)
1364 {
1365     int i = 0;
1366 
1367     if ((mac_addr1 == MNULL) || (mac_addr2 == MNULL))
1368     {
1369         return 1;
1370     }
1371 
1372     for (i = 0; i < MLAN_MAC_ADDR_LENGTH; i++)
1373     {
1374         if (mac_addr1[i] != mac_addr2[i])
1375         {
1376             return 1;
1377         }
1378     }
1379     return 0;
1380 }
1381 
add_mcast_ip(uint8_t * mac_addr)1382 static int add_mcast_ip(uint8_t *mac_addr)
1383 {
1384     mcast_filter *node_t, *new_node;
1385     (void)wifi_get_mcastf_lock();
1386     node_t = wm_wifi.start_list;
1387     if (wm_wifi.start_list == NULL)
1388     {
1389 #if !CONFIG_MEM_POOLS
1390         new_node = OSA_MemoryAllocate(sizeof(mcast_filter));
1391 #else
1392         new_node = (mcast_filter *)OSA_MemoryPoolAllocate(buf_32_MemoryPool);
1393 #endif
1394         if (new_node == NULL)
1395         {
1396             (void)wifi_put_mcastf_lock();
1397             return -WM_FAIL;
1398         }
1399         (void)memcpy((void *)new_node->mac_addr, (const void *)mac_addr, MLAN_MAC_ADDR_LENGTH);
1400         new_node->next     = NULL;
1401         wm_wifi.start_list = new_node;
1402         (void)wifi_put_mcastf_lock();
1403         return WM_SUCCESS;
1404     }
1405     while (node_t->next != NULL && cmp_mac_addr(node_t->mac_addr, mac_addr))
1406     {
1407         node_t = node_t->next;
1408     }
1409 
1410     if (!cmp_mac_addr(node_t->mac_addr, mac_addr))
1411     {
1412         (void)wifi_put_mcastf_lock();
1413         return -WM_E_EXIST;
1414     }
1415 #if !CONFIG_MEM_POOLS
1416     new_node = OSA_MemoryAllocate(sizeof(mcast_filter));
1417 #else
1418     new_node = (mcast_filter *)OSA_MemoryPoolAllocate(buf_32_MemoryPool);
1419 #endif
1420     if (new_node == NULL)
1421     {
1422         (void)wifi_put_mcastf_lock();
1423         return -WM_FAIL;
1424     }
1425     (void)memcpy((void *)new_node->mac_addr, (const void *)mac_addr, MLAN_MAC_ADDR_LENGTH);
1426     new_node->next = NULL;
1427     node_t->next   = new_node;
1428     (void)wifi_put_mcastf_lock();
1429     return WM_SUCCESS;
1430 }
1431 
remove_mcast_ip(uint8_t * mac_addr)1432 static int remove_mcast_ip(uint8_t *mac_addr)
1433 {
1434     mcast_filter *curr_node, *prev_node;
1435     (void)wifi_get_mcastf_lock();
1436     curr_node = wm_wifi.start_list->next;
1437     prev_node = wm_wifi.start_list;
1438     if (wm_wifi.start_list == NULL)
1439     {
1440         (void)wifi_put_mcastf_lock();
1441         return -WM_FAIL;
1442     }
1443     if (curr_node == NULL && cmp_mac_addr(prev_node->mac_addr, mac_addr))
1444     {
1445 #if !CONFIG_MEM_POOLS
1446         OSA_MemoryFree(prev_node);
1447 #else
1448         OSA_MemoryPoolFree(buf_32_MemoryPool, prev_node);
1449 #endif
1450         wm_wifi.start_list = NULL;
1451         (void)wifi_put_mcastf_lock();
1452         return WM_SUCCESS;
1453     }
1454     /* If search element is at first location */
1455     if (!cmp_mac_addr(prev_node->mac_addr, mac_addr))
1456     {
1457         wm_wifi.start_list = prev_node->next;
1458 #if !CONFIG_MEM_POOLS
1459         OSA_MemoryFree(prev_node);
1460 #else
1461         OSA_MemoryPoolFree(buf_32_MemoryPool, prev_node);
1462 #endif
1463         (void)wifi_put_mcastf_lock();
1464         return WM_SUCCESS;
1465     }
1466     /* Find node in linked list */
1467     while (cmp_mac_addr(curr_node->mac_addr, mac_addr) && curr_node->next != NULL)
1468     {
1469         prev_node = curr_node;
1470         curr_node = curr_node->next;
1471     }
1472     if (!cmp_mac_addr(curr_node->mac_addr, mac_addr))
1473     {
1474         prev_node->next = curr_node->next;
1475 #if !CONFIG_MEM_POOLS
1476         OSA_MemoryFree(curr_node);
1477 #else
1478         OSA_MemoryPoolFree(buf_32_MemoryPool, curr_node);
1479 #endif
1480         (void)wifi_put_mcastf_lock();
1481         return WM_SUCCESS;
1482     }
1483     (void)wifi_put_mcastf_lock();
1484     return -WM_FAIL;
1485 }
1486 
make_filter_list(char * mlist,int maxlen)1487 static int make_filter_list(char *mlist, int maxlen)
1488 {
1489     mcast_filter *node_t;
1490     int maddr_cnt = 0;
1491     (void)wifi_get_mcastf_lock();
1492     node_t = wm_wifi.start_list;
1493     while (node_t != NULL)
1494     {
1495         (void)memcpy((void *)mlist, (const void *)node_t->mac_addr, MLAN_MAC_ADDR_LENGTH);
1496         node_t = (struct mcast_filter *)node_t->next;
1497         mlist  = mlist + MLAN_MAC_ADDR_LENGTH;
1498         maddr_cnt++;
1499         if (maddr_cnt > (maxlen / 6U))
1500         {
1501             break;
1502         }
1503     }
1504     (void)wifi_put_mcastf_lock();
1505     return maddr_cnt;
1506 }
1507 
wifi_get_ipv4_multicast_mac(uint32_t ipaddr,uint8_t * mac_addr)1508 void wifi_get_ipv4_multicast_mac(uint32_t ipaddr, uint8_t *mac_addr)
1509 {
1510     int i = 0, j = 0;
1511     uint32_t mac_addr_r = 0x01005E;
1512     ipaddr              = ipaddr & 0x7FFFFFU;
1513     /* Generate Multicast Mapped Mac Address for IPv4
1514      * To get Multicast Mapped MAC address,
1515      * To calculate 6 byte Multicast-Mapped MAC Address.
1516      * 1) Fill higher 24-bits with IANA Multicast OUI (01-00-5E)
1517      * 2) Set 24th bit as Zero
1518      * 3) Fill lower 23-bits with from IP address (ignoring higher
1519      * 9bits).
1520      */
1521     for (i = 2; i >= 0; i--)
1522     {
1523         mac_addr[j] = (uint8_t)((char)(mac_addr_r >> 8 * i) & 0xFF);
1524         j++;
1525     }
1526 
1527     for (i = 2; i >= 0; i--)
1528     {
1529         mac_addr[j] = (uint8_t)((char)(ipaddr >> 8 * i) & 0xFF);
1530         j++;
1531     }
1532 }
1533 
1534 #if CONFIG_IPV6
wifi_get_ipv6_multicast_mac(uint32_t ipaddr,uint8_t * mac_addr)1535 void wifi_get_ipv6_multicast_mac(uint32_t ipaddr, uint8_t *mac_addr)
1536 {
1537     int i = 0, j = 0;
1538     uint32_t mac_addr_r = 0x3333;
1539     /* Generate Multicast Mapped Mac Address for IPv6
1540      * To get Multicast Mapped MAC address,
1541      * To calculate 6 byte Multicast-Mapped MAC Address.
1542      * 1) Fill higher 16-bits with IANA Multicast OUI (33-33)
1543      * 2) Fill lower 24-bits with from IP address
1544      */
1545     for (i = 1; i >= 0; i--)
1546     {
1547         mac_addr[j] = (char)(mac_addr_r >> 8 * i) & 0xFF;
1548         j++;
1549     }
1550 
1551     for (i = 3; i >= 0; i--)
1552     {
1553         mac_addr[j] = (char)(ipaddr >> 8 * i) & 0xFF;
1554         j++;
1555     }
1556 }
1557 #endif /* CONFIG_IPV6 */
1558 
wifi_add_mcast_filter(uint8_t * mac_addr)1559 int wifi_add_mcast_filter(uint8_t *mac_addr)
1560 {
1561     char mlist[MAX_MCAST_LEN] = {0};
1562     int len, ret;
1563     /* If MAC address is 00:11:22:33:44:55,
1564      * then pass mac_addr array in following format:
1565      * mac_addr[0] = 00
1566      * mac_addr[1] = 11
1567      * mac_addr[2] = 22
1568      * mac_addr[3] = 33
1569      * mac_addr[4] = 44
1570      * mac_addr[5] = 55
1571      */
1572 
1573     (void)memset(&mlist, 0x00, MAX_MCAST_LEN);
1574     ret = add_mcast_ip(mac_addr);
1575     if (ret != WM_SUCCESS)
1576     {
1577         return ret;
1578     }
1579     len = make_filter_list(mlist, (int)MAX_MCAST_LEN);
1580     return wifi_set_mac_multicast_addr(mlist, (t_u32)len);
1581 }
1582 
wifi_remove_mcast_filter(uint8_t * mac_addr)1583 int wifi_remove_mcast_filter(uint8_t *mac_addr)
1584 {
1585     char mlist[MAX_MCAST_LEN];
1586     int len, ret;
1587     /* If MAC address is 00:11:22:33:44:55,
1588      * then pass mac_addr array in following format:
1589      * mac_addr[0] = 00
1590      * mac_addr[1] = 11
1591      * mac_addr[2] = 22
1592      * mac_addr[3] = 33
1593      * mac_addr[4] = 44
1594      * mac_addr[5] = 55
1595      */
1596 
1597     (void)memset(&mlist, 0x00, MAX_MCAST_LEN);
1598     ret = remove_mcast_ip(mac_addr);
1599     if (ret != WM_SUCCESS)
1600     {
1601         return ret;
1602     }
1603     len = make_filter_list(mlist, (int)MAX_MCAST_LEN);
1604     ret = wifi_set_mac_multicast_addr(mlist, (uint32_t)len);
1605     return ret;
1606 }
1607 
wifi_remove_all_mcast_filter(uint8_t need_lock)1608 void wifi_remove_all_mcast_filter(uint8_t need_lock)
1609 {
1610     mcast_filter *node = NULL;
1611 
1612     if (wm_wifi.start_list == NULL)
1613         return;
1614 
1615     if (need_lock)
1616         wifi_get_mcastf_lock();
1617 
1618     while (wm_wifi.start_list)
1619     {
1620         node               = wm_wifi.start_list;
1621         wm_wifi.start_list = node->next;
1622 #if !CONFIG_MEM_POOLS
1623         OSA_MemoryFree(node);
1624 #else
1625         OSA_MemoryPoolFree(buf_32_MemoryPool, node);
1626 #endif
1627     }
1628 
1629     if (need_lock)
1630         wifi_put_mcastf_lock();
1631 }
1632 
1633 static struct wifi_scan_result2 common_desc;
wifi_get_scan_result(unsigned int index,struct wifi_scan_result2 ** desc)1634 int wifi_get_scan_result(unsigned int index, struct wifi_scan_result2 **desc)
1635 {
1636     (void)memset(&common_desc, 0x00, sizeof(struct wifi_scan_result2));
1637     int rv =
1638         wrapper_bssdesc_first_set((int)index, common_desc.bssid, &common_desc.is_ibss_bit_set, &common_desc.ssid_len,
1639                                   common_desc.ssid, &common_desc.Channel, &common_desc.RSSI, &common_desc.beacon_period,
1640                                   &common_desc.dtim_period, &common_desc.WPA_WPA2_WEP, &common_desc.wpa_mcstCipher,
1641                                   &common_desc.wpa_ucstCipher, &common_desc.rsn_mcstCipher, &common_desc.rsn_ucstCipher,
1642                                   &common_desc.ap_mfpc, &common_desc.ap_mfpr, &common_desc.ap_pwe);
1643     if (rv != WM_SUCCESS)
1644     {
1645         wifi_e("wifi_get_scan_result failed");
1646         return rv;
1647     }
1648 
1649     /* Country info not populated */
1650     rv = wrapper_bssdesc_second_set((int)index, &common_desc.phtcap_ie_present, &common_desc.phtinfo_ie_present,
1651 #if CONFIG_11AC
1652                                     &common_desc.pvhtcap_ie_present,
1653 #endif
1654 #if CONFIG_11AX
1655                                     &common_desc.phecap_ie_present,
1656 #endif
1657                                     &common_desc.wmm_ie_present, &common_desc.band, &common_desc.wps_IE_exist,
1658                                     &common_desc.wps_session, &common_desc.wpa2_entp_IE_exist,
1659 #if CONFIG_11R
1660                                     &common_desc.mdid,
1661 #endif
1662 #if CONFIG_11K
1663                                     &common_desc.neighbor_report_supported,
1664 #endif
1665 #if CONFIG_11V
1666                                     &common_desc.bss_transition_supported,
1667 #endif
1668                                     &common_desc.trans_mode, common_desc.trans_bssid, &common_desc.trans_ssid_len,
1669                                     common_desc.trans_ssid
1670 #if CONFIG_DRIVER_MBO
1671                                     ,
1672                                     &common_desc.mbo_assoc_disallowed
1673 #endif
1674     );
1675 
1676     if (rv != WM_SUCCESS)
1677     {
1678         wifi_e("wifi_get_scan_result failed");
1679         return rv;
1680     }
1681 
1682     *desc = &common_desc;
1683 
1684     return WM_SUCCESS;
1685 }
1686 
wifi_register_event_queue(osa_msgq_handle_t event_queue)1687 int wifi_register_event_queue(osa_msgq_handle_t event_queue)
1688 {
1689     if (event_queue == MNULL)
1690     {
1691         return -WM_E_INVAL;
1692     }
1693 
1694     if (wm_wifi.wlc_mgr_event_queue != NULL)
1695     {
1696         return -WM_FAIL;
1697     }
1698 
1699     wm_wifi.wlc_mgr_event_queue = event_queue;
1700     return WM_SUCCESS;
1701 }
1702 
wifi_unregister_event_queue(osa_msgq_handle_t event_queue)1703 int wifi_unregister_event_queue(osa_msgq_handle_t event_queue)
1704 {
1705     if ((wm_wifi.wlc_mgr_event_queue == MNULL) || wm_wifi.wlc_mgr_event_queue != event_queue)
1706     {
1707         return -WM_FAIL;
1708     }
1709 
1710     wm_wifi.wlc_mgr_event_queue = NULL;
1711     return WM_SUCCESS;
1712 }
1713 
1714 #if CONFIG_P2P
wifi_register_wfd_event_queue(osa_msgq_handle_t event_queue)1715 int wifi_register_wfd_event_queue(osa_msgq_handle_t event_queue)
1716 {
1717     if (wm_wifi.wfd_event_queue)
1718         return -WM_FAIL;
1719 
1720     wm_wifi.wfd_event_queue = event_queue;
1721     return WM_SUCCESS;
1722 }
1723 
wifi_unregister_wfd_event_queue(osa_msgq_handle_t event_queue)1724 int wifi_unregister_wfd_event_queue(osa_msgq_handle_t event_queue)
1725 {
1726     if (!wm_wifi.wfd_event_queue || wm_wifi.wfd_event_queue != event_queue)
1727         return -WM_FAIL;
1728 
1729     wm_wifi.wfd_event_queue = NULL;
1730     return WM_SUCCESS;
1731 }
1732 #endif
1733 
wifi_get_wpa_ie_in_assoc(uint8_t * wpa_ie)1734 int wifi_get_wpa_ie_in_assoc(uint8_t *wpa_ie)
1735 {
1736     return wrapper_get_wpa_ie_in_assoc(wpa_ie);
1737 }
1738 
1739 #define WL_ID_WIFI_MAIN_LOOP "wifi_drv_task"
1740 
wifi_drv_task(void * argv)1741 static void wifi_drv_task(void *argv)
1742 {
1743     osa_status_t status;
1744     struct bus_message msg;
1745 
1746     (void)memset((void *)&msg, 0, sizeof(struct bus_message));
1747 
1748     /* Main Loop */
1749     while (true)
1750     {
1751         status = OSA_MsgQGet((osa_msgq_handle_t)wm_wifi.io_events, &msg, osaWaitForever_c);
1752         if (status == KOSA_StatusSuccess)
1753         {
1754             // wakelock_get(WL_ID_WIFI_MAIN_LOOP);
1755 
1756             if (msg.event == MLAN_TYPE_EVENT)
1757             {
1758                 (void)wifi_handle_fw_event(&msg);
1759                 /*
1760                  * Free the buffer after the event is
1761                  * handled.
1762                  */
1763                 if (msg.data != NULL)
1764                 {
1765                     wifi_free_eventbuf(msg.data);
1766                 }
1767             }
1768             else if (msg.event == MLAN_TYPE_CMD)
1769             {
1770                 (void)wifi_process_cmd_response((HostCmd_DS_COMMAND *)(void *)((uint8_t *)msg.data + INTF_HEADER_LEN));
1771                 wifi_update_last_cmd_sent_ms();
1772                 (void)wifi_put_command_resp_sem();
1773             }
1774             else
1775             { /* Do Nothing */
1776             }
1777 
1778             // wakelock_put(WL_ID_WIFI_MAIN_LOOP);
1779         }
1780     }
1781 }
1782 
1783 #ifndef RW610
1784 #define WL_ID_WIFI_CORE_INPUT "wifi_core_task"
1785 /**
1786  * This function should be called when a packet is ready to be read
1787  * from the interface.
1788  */
wifi_core_task(void * argv)1789 static void wifi_core_task(void *argv)
1790 {
1791     OSA_SR_ALLOC();
1792     for (;;)
1793     {
1794         OSA_ENTER_CRITICAL();
1795 
1796         /* Allow interrupt handler to deliver us a packet */
1797         g_txrx_flag = true;
1798         //		SDIOC_IntMask(SDIOC_INT_CDINT, UNMASK);
1799         //		SDIOC_IntSigMask(SDIOC_INT_CDINT, UNMASK);
1800 #ifndef RW610
1801         sdio_enable_interrupt();
1802 #endif
1803 
1804         OSA_EXIT_CRITICAL();
1805 
1806         (void)OSA_TaskNotifyGet(osaWaitForever_c);
1807 
1808         // wakelock_get(WL_ID_WIFI_CORE_INPUT);
1809 
1810 #if defined(RW610)
1811         (void)wifi_imu_lock();
1812 #else
1813         /* Protect the SDIO from other parallel activities */
1814         (void)wifi_sdio_lock();
1815 
1816         (void)wlan_process_int_status(mlan_adap);
1817 #endif
1818 
1819 #if defined(RW610)
1820         wifi_imu_unlock();
1821 #else
1822         wifi_sdio_unlock();
1823 #endif
1824         // wakelock_put(WL_ID_WIFI_CORE_INPUT);
1825     } /* for ;; */
1826 }
1827 #endif
wifi_user_scan_config_cleanup(void)1828 void wifi_user_scan_config_cleanup(void)
1829 {
1830     if (wm_wifi.g_user_scan_cfg != NULL)
1831     {
1832 #if !CONFIG_MEM_POOLS
1833         OSA_MemoryFree((void *)wm_wifi.g_user_scan_cfg);
1834 #else
1835         OSA_MemoryPoolFree(buf_512_MemoryPool, wm_wifi.g_user_scan_cfg);
1836 #endif
1837         wm_wifi.g_user_scan_cfg = NULL;
1838     }
1839 }
1840 
wifi_scan_stop(void)1841 void wifi_scan_stop(void)
1842 {
1843     wm_wifi.scan_stop = true;
1844     while (scan_thread_in_process)
1845     {
1846         /* wait for scan task done */
1847         OSA_TimeDelay(1000);
1848     }
1849     wm_wifi.scan_stop = false;
1850 }
1851 
1852 /**
1853  * This function should be called when scan command is ready
1854  *
1855  */
wifi_scan_task(void * argv)1856 static void wifi_scan_task(void *argv)
1857 {
1858     mlan_status rv;
1859     for (;;)
1860     {
1861         (void)OSA_TaskNotifyGet(osaWaitForever_c);
1862         if (wm_wifi.scan_stop == true)
1863         {
1864             wm_wifi.scan_stop = false;
1865             wifi_user_scan_config_cleanup();
1866             break;
1867         }
1868 
1869         scan_thread_in_process = true;
1870         if (wm_wifi.g_user_scan_cfg != NULL)
1871         {
1872 #if CONFIG_WPA_SUPP
1873             (void)wifi_event_completion(WIFI_EVENT_SCAN_START, WIFI_EVENT_REASON_SUCCESS, NULL);
1874 #endif
1875             rv = wlan_scan_networks((mlan_private *)mlan_adap->priv[0], NULL, wm_wifi.g_user_scan_cfg);
1876             if (rv != MLAN_STATUS_SUCCESS)
1877             {
1878                 wifi_user_scan_config_cleanup();
1879                 (void)wifi_event_completion(WIFI_EVENT_SCAN_RESULT, WIFI_EVENT_REASON_FAILURE, NULL);
1880             }
1881         }
1882         scan_thread_in_process = false;
1883     } /* for ;; */
1884     while (true)
1885     {
1886         OSA_TimeDelay(60000);
1887     }
1888 }
1889 
wifi_powersave_task(void * data)1890 static void wifi_powersave_task(void *data)
1891 {
1892     osa_status_t status;
1893     struct wifi_message msg;
1894 
1895     while (1)
1896     {
1897         status = OSA_MsgQGet((osa_msgq_handle_t)wm_wifi.powersave_queue, &msg, osaWaitForever_c);
1898         if (status == KOSA_StatusSuccess)
1899         {
1900             switch (msg.event)
1901             {
1902                 case WIFI_EVENT_SLEEP:
1903                     wifi_event_completion(WIFI_EVENT_SLEEP, WIFI_EVENT_REASON_SUCCESS, NULL);
1904                     break;
1905                 default:
1906                     wifi_w("got unknown message: %d", msg.event);
1907                     break;
1908             }
1909         }
1910     }
1911 }
1912 
1913 #if CONFIG_FW_VDLL
1914 /**
1915  *  @brief This function flushes all data
1916  *
1917  *  @param context      Reorder context pointer
1918  *
1919  *  @return 	   	    N/A
1920  */
wlan_vdll_complete(osa_timer_arg_t tmr_handle)1921 static t_void wlan_vdll_complete(osa_timer_arg_t tmr_handle)
1922 {
1923     mlan_adap->vdll_in_progress = MFALSE;
1924 }
1925 #endif
1926 
1927 static void wifi_core_deinit(void);
1928 static int wifi_low_level_input(const uint8_t interface, const uint8_t *buffer, const uint16_t len);
1929 
wifi_core_init(void)1930 static int wifi_core_init(void)
1931 {
1932     osa_status_t status;
1933     int ret;
1934 
1935     if (wm_wifi.wifi_core_init_done != 0U)
1936     {
1937         return WM_SUCCESS;
1938     }
1939 
1940     status = OSA_MutexCreate((osa_mutex_handle_t)wm_wifi.command_lock);
1941     if (status != KOSA_StatusSuccess)
1942     {
1943         wifi_e("Create command_lock failed");
1944         goto fail;
1945     }
1946 
1947     status = OSA_EventCreate((osa_event_handle_t)wm_wifi.wifi_event_Handle, 1);
1948     if (status != KOSA_StatusSuccess)
1949     {
1950         wifi_e("Create event handle failed");
1951         goto fail;
1952     }
1953 
1954     status = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)wm_wifi.command_resp_sem);
1955     if (status != KOSA_StatusSuccess)
1956     {
1957         wifi_e("Create command resp sem failed");
1958         goto fail;
1959     }
1960     OSA_SemaphorePost((osa_semaphore_handle_t)wm_wifi.command_resp_sem);
1961     status = OSA_MutexCreate((osa_mutex_handle_t)wm_wifi.mcastf_mutex);
1962     if (status != KOSA_StatusSuccess)
1963     {
1964         wifi_e("Create mcastf mutex failed");
1965         goto fail;
1966     }
1967     /*
1968      * Take the cmd resp lock immediately so that we can later block on
1969      * it.
1970      */
1971     (void)wifi_get_command_resp_sem(osaWaitForever_c);
1972 
1973     status = OSA_MsgQCreate((osa_msgq_handle_t)wm_wifi.io_events, MAX_EVENTS, sizeof(struct bus_message));
1974     if (status != KOSA_StatusSuccess)
1975     {
1976         wifi_e("Create io events queue failed");
1977         goto fail;
1978     }
1979 
1980     ret = bus_register_event_queue((osa_msgq_handle_t)wm_wifi.io_events);
1981     if (ret != WM_SUCCESS)
1982     {
1983         wifi_e("Register io events queue failed");
1984         goto fail;
1985     }
1986 
1987     status = OSA_TaskCreate((osa_task_handle_t)wm_wifi.wifi_drv_task_Handle, OSA_TASK(wifi_drv_task), NULL);
1988     if (status != KOSA_StatusSuccess)
1989     {
1990         wifi_e("Create wifi driver thread failed");
1991         goto fail;
1992     }
1993 
1994     ret = bus_register_data_input_function(&wifi_low_level_input);
1995     if (ret != WM_SUCCESS)
1996     {
1997         wifi_e("Register wifi low level input failed");
1998         goto fail;
1999     }
2000 
2001     status = OSA_TaskCreate((osa_task_handle_t)wm_wifi.wifi_scan_task_Handle, OSA_TASK(wifi_scan_task), NULL);
2002     if (status != KOSA_StatusSuccess)
2003     {
2004         wifi_e("Create wifi scan thread failed");
2005         goto fail;
2006     }
2007 #ifndef RW610
2008     status = OSA_TaskCreate((osa_task_handle_t)wm_wifi.wifi_core_task_Handle, OSA_TASK(wifi_core_task), NULL);
2009     if (status != KOSA_StatusSuccess)
2010     {
2011         wifi_e("Create stack dispatcher thread failed");
2012         goto fail;
2013     }
2014 #endif
2015 
2016     wm_wifi.wifi_core_init_done = 1;
2017 
2018 #if CONFIG_WMM
2019     ret = wifi_wmm_buf_pool_init(&outbuf_arr[0][0]);
2020     if (ret != WM_SUCCESS)
2021     {
2022         wifi_e("Unable to init wmm buffer pool");
2023         goto fail;
2024     }
2025 
2026     ret = wifi_bypass_txq_init();
2027     if (ret != WM_SUCCESS)
2028     {
2029         wifi_e("Init bypass txq failed\r\n");
2030         goto fail;
2031     }
2032 
2033     status = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)txbuf_sem);
2034     if (status != KOSA_StatusSuccess)
2035     {
2036         wifi_e("Create txbuf sem failed");
2037         return ret;
2038     }
2039 
2040     /* Semaphore to protect wmm data parameters */
2041     status = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)wm_wifi.tx_data_sem);
2042     if (status != KOSA_StatusSuccess)
2043     {
2044         PRINTF("Create tx data sem failed");
2045         goto fail;
2046     }
2047     OSA_SemaphorePost((osa_semaphore_handle_t)wm_wifi.tx_data_sem);
2048     status = OSA_MsgQCreate((osa_msgq_handle_t)wm_wifi.tx_data, MAX_EVENTS, sizeof(struct bus_message));
2049     if (status != KOSA_StatusSuccess)
2050     {
2051         wifi_e("Create tx_data queue failed");
2052         goto fail;
2053     }
2054 
2055     status = OSA_TaskCreate((osa_task_handle_t)wm_wifi.wifi_drv_tx_task_Handle, OSA_TASK(wifi_drv_tx_task), NULL);
2056     if (status != KOSA_StatusSuccess)
2057     {
2058         PRINTF("Create tx data thread failed");
2059         goto fail;
2060     }
2061 #endif
2062 
2063     status = OSA_MsgQCreate((osa_msgq_handle_t)wm_wifi.powersave_queue, MAX_EVENTS, sizeof(struct bus_message));
2064     if (status != KOSA_StatusSuccess)
2065     {
2066         PRINTF("Create power save queue failed");
2067         goto fail;
2068     }
2069 
2070     status = OSA_TaskCreate((osa_task_handle_t)wm_wifi.wifi_powersave_task_Handle, OSA_TASK(wifi_powersave_task), NULL);
2071     if (status != KOSA_StatusSuccess)
2072     {
2073         PRINTF("Create power save thread failed");
2074         goto fail;
2075     }
2076 
2077 #if CONFIG_CSI
2078     /* Semaphore to protect data parameters */
2079     status = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem);
2080     if (status != KOSA_StatusSuccess)
2081     {
2082         PRINTF("Create usb data sem failed");
2083         goto fail;
2084     }
2085     OSA_SemaphorePost((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem);
2086 #endif
2087 
2088 #if CONFIG_ECSA
2089     /* Semaphore to wait ECSA complete */
2090     status = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)ecsa_status_control.ecsa_sem);
2091     if (status != KOSA_StatusSuccess)
2092     {
2093         PRINTF("Create ecsa sem failed");
2094         goto fail;
2095     }
2096 #endif
2097 
2098 #if CONFIG_FW_VDLL
2099     (void)mlan_adap->callbacks.moal_init_timer(mlan_adap->pmoal_handle, &mlan_adap->vdll_timer, wlan_vdll_complete,
2100                                                NULL);
2101 #endif
2102 
2103     wm_wifi.wifi_core_init_done = 1;
2104 
2105 #if defined(SD8801) || defined(RW610)
2106     wifi_uap_set_bandwidth(BANDWIDTH_20MHZ);
2107 #else
2108     wifi_uap_set_bandwidth(BANDWIDTH_40MHZ);
2109 #endif
2110 
2111     return WM_SUCCESS;
2112 
2113 fail:
2114 
2115     wifi_core_deinit();
2116 
2117     return -WM_FAIL;
2118 }
2119 
wifi_core_deinit(void)2120 static void wifi_core_deinit(void)
2121 {
2122     int i = 0;
2123 
2124     mlan_adap->in_reset = true;
2125     for (i = 0; i < (int)(MIN(MLAN_MAX_BSS_NUM, mlan_adap->priv_num)); i++)
2126     {
2127         if (mlan_adap->priv[i])
2128         {
2129             wlan_clean_txrx(mlan_adap->priv[i]);
2130             (void)OSA_MutexDestroy((osa_mutex_handle_t)mlan_adap->priv[i]->tx_ba_stream_tbl_lock);
2131             (void)OSA_SemaphoreDestroy((osa_semaphore_handle_t)mlan_adap->priv[i]->rx_reorder_tbl_lock);
2132 #if CONFIG_WMM
2133             wlan_ralist_deinit_enh(mlan_adap->priv[i]);
2134 #endif
2135         }
2136     }
2137 
2138     wm_wifi.wifi_core_init_done = 0;
2139 
2140     bus_deregister_event_queue();
2141     bus_deregister_data_input_funtion();
2142 
2143     (void)OSA_MsgQDestroy((osa_msgq_handle_t)wm_wifi.io_events);
2144 
2145     (void)OSA_MsgQDestroy((osa_msgq_handle_t)wm_wifi.powersave_queue);
2146 
2147 #if CONFIG_WMM
2148     (void)OSA_MsgQDestroy((osa_msgq_handle_t)wm_wifi.tx_data);
2149     wifi_wmm_buf_pool_deinit();
2150     wifi_bypass_txq_deinit();
2151 
2152     (void)OSA_SemaphoreDestroy((osa_semaphore_handle_t)txbuf_sem);
2153 #endif
2154 
2155     wifi_remove_all_mcast_filter(0);
2156 
2157     (void)OSA_MutexDestroy((osa_mutex_handle_t)wm_wifi.mcastf_mutex);
2158     (void)OSA_SemaphoreDestroy((osa_semaphore_handle_t)wm_wifi.command_resp_sem);
2159 
2160 #if CONFIG_WMM
2161     (void)OSA_SemaphoreDestroy((osa_semaphore_handle_t)wm_wifi.tx_data_sem);
2162 #endif
2163     (void)OSA_MutexDestroy((osa_mutex_handle_t)wm_wifi.command_lock);
2164     (void)OSA_EventDestroy((osa_event_handle_t)wm_wifi.wifi_event_Handle);
2165 #ifndef RW610
2166     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_drv_task_Handle);
2167     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_core_task_Handle);
2168     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_scan_task_Handle);
2169     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_powersave_task_Handle);
2170 #if CONFIG_WMM
2171     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_drv_tx_task_Handle);
2172 #endif
2173 #else
2174     wm_wifi.cmd_resp_priv   = NULL;
2175     wm_wifi.cmd_resp_ioctl  = NULL;
2176     wm_wifi.cmd_resp_status = 0;
2177     memset(&wm_wifi, 0x00, sizeof(wm_wifi));
2178 #endif
2179 #if CONFIG_CSI
2180     (void)OSA_SemaphoreDestroy((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem);
2181 #endif
2182 #if CONFIG_ECSA
2183     (void)OSA_SemaphoreDestroy((osa_semaphore_handle_t)ecsa_status_control.ecsa_sem);
2184 #endif
2185 #if CONFIG_FW_VDLL
2186     (void)mlan_adap->callbacks.moal_stop_timer(mlan_adap->pmoal_handle, mlan_adap->vdll_timer);
2187     (void)mlan_adap->callbacks.moal_free_timer(mlan_adap->pmoal_handle, &mlan_adap->vdll_timer);
2188 #endif
2189 }
2190 
wifi_init(const uint8_t * fw_start_addr,const size_t size)2191 int wifi_init(const uint8_t *fw_start_addr, const size_t size)
2192 {
2193     int ret = WM_SUCCESS;
2194     if (wm_wifi.wifi_init_done != 0U)
2195     {
2196         return WM_SUCCESS;
2197     }
2198 
2199     (void)memset(&wm_wifi, 0, sizeof(wm_wifi_t));
2200 
2201     wm_wifi.fw_start_addr = fw_start_addr;
2202     wm_wifi.size          = size;
2203 
2204 #if defined(RW610)
2205     ret = (int)imu_wifi_init(WLAN_TYPE_NORMAL, fw_start_addr, size);
2206 #else
2207     ret = (int)sd_wifi_init(WLAN_TYPE_NORMAL, fw_start_addr, size);
2208 #endif
2209     if (ret != WM_SUCCESS)
2210     {
2211 #if defined(RW610)
2212         wifi_e("imu_wifi_init failed. status code %d", ret);
2213 #else
2214         wifi_e("sd_wifi_init failed. status code %d", ret);
2215 #endif
2216         switch (ret)
2217         {
2218             case MLAN_CARD_CMD_TIMEOUT:
2219             case MLAN_CARD_NOT_DETECTED:
2220                 ret = -WIFI_ERROR_CARD_NOT_DETECTED;
2221                 break;
2222             case MLAN_STATUS_FW_DNLD_FAILED:
2223                 ret = -WIFI_ERROR_FW_DNLD_FAILED;
2224                 break;
2225             case MLAN_STATUS_FW_NOT_DETECTED:
2226                 ret = -WIFI_ERROR_FW_NOT_DETECTED;
2227                 break;
2228 #if CONFIG_XZ_DECOMPRESSION
2229             case MLAN_STATUS_FW_XZ_FAILED:
2230                 ret = -WIFI_ERROR_FW_XZ_FAILED;
2231                 break;
2232 #endif /* CONFIG_XZ_DECOMPRESSION */
2233             case MLAN_STATUS_FW_NOT_READY:
2234                 ret = -WIFI_ERROR_FW_NOT_READY;
2235                 break;
2236             default:
2237                 PRINTM(MINFO, "Unexpected MLAN FW Status \n");
2238                 break;
2239         }
2240         return ret;
2241     }
2242 
2243     ret = wifi_core_init();
2244     if (ret != WM_SUCCESS)
2245     {
2246         wifi_e("wifi_core_init failed. status code %d", ret);
2247         return ret;
2248     }
2249 
2250 #ifndef RW610
2251     ret = (int)sd_wifi_post_init(WLAN_TYPE_NORMAL);
2252     if (ret != WM_SUCCESS)
2253     {
2254         wifi_e("sd_wifi_post_init failed. status code %d", ret);
2255         return ret;
2256     }
2257 #endif
2258     if (ret == WM_SUCCESS)
2259     {
2260         wm_wifi.wifi_init_done = 1;
2261     }
2262 
2263     return ret;
2264 }
2265 
2266 #if (CONFIG_WIFI_IND_DNLD)
wifi_reinit(uint8_t fw_reload)2267 static int wifi_reinit(uint8_t fw_reload)
2268 {
2269     int ret = WM_SUCCESS;
2270 
2271     ret = (int)sd_wifi_reinit(WLAN_TYPE_NORMAL, wm_wifi.fw_start_addr, wm_wifi.size, fw_reload);
2272     if (ret != WM_SUCCESS)
2273     {
2274         if (ret != MLAN_STATUS_FW_DNLD_SKIP)
2275         {
2276             wifi_e("sd_wifi_reinit failed. status code %d", ret);
2277         }
2278         switch (ret)
2279         {
2280             case MLAN_CARD_CMD_TIMEOUT:
2281             case MLAN_CARD_NOT_DETECTED:
2282                 ret = -WIFI_ERROR_CARD_NOT_DETECTED;
2283                 break;
2284             case MLAN_STATUS_FW_DNLD_FAILED:
2285                 ret = -WIFI_ERROR_FW_DNLD_FAILED;
2286                 break;
2287             case MLAN_STATUS_FW_NOT_DETECTED:
2288                 ret = -WIFI_ERROR_FW_NOT_DETECTED;
2289                 break;
2290 #if CONFIG_XZ_DECOMPRESSION
2291             case MLAN_STATUS_FW_XZ_FAILED:
2292                 ret = -WIFI_ERROR_FW_XZ_FAILED;
2293                 break;
2294 #endif /* CONFIG_XZ_DECOMPRESSION */
2295             case MLAN_STATUS_FW_NOT_READY:
2296                 ret = -WIFI_ERROR_FW_NOT_READY;
2297                 break;
2298             case MLAN_STATUS_FW_DNLD_SKIP:
2299                 ret = WM_SUCCESS;
2300                 break;
2301             default:
2302                 PRINTM(MINFO, "Unexpected MLAN FW Status \n");
2303                 ret = -WM_FAIL;
2304                 break;
2305         }
2306     }
2307 #ifndef RW610
2308     else
2309     {
2310         ret = (int)sd_wifi_post_init(WLAN_TYPE_NORMAL);
2311         if (ret != WM_SUCCESS)
2312         {
2313             wifi_e("sd_wifi_post_init failed. status code %d", ret);
2314             return ret;
2315         }
2316     }
2317 #endif
2318 
2319     return ret;
2320 }
2321 #endif
2322 
2323 #ifndef RW610
wifi_init_fcc(const uint8_t * fw_start_addr,const size_t size)2324 int wifi_init_fcc(const uint8_t *fw_start_addr, const size_t size)
2325 {
2326     if (wm_wifi.wifi_init_done != 0U)
2327     {
2328         return WM_SUCCESS;
2329     }
2330 
2331     int ret = (int)sd_wifi_init(WLAN_TYPE_FCC_CERTIFICATION, fw_start_addr, size);
2332     if (ret != 0)
2333     {
2334         wifi_e("sd_wifi_init failed. status code %d", ret);
2335         switch (ret)
2336         {
2337             case MLAN_CARD_CMD_TIMEOUT:
2338             case MLAN_CARD_NOT_DETECTED:
2339                 ret = -WIFI_ERROR_CARD_NOT_DETECTED;
2340                 break;
2341             case MLAN_STATUS_FW_DNLD_FAILED:
2342                 ret = -WIFI_ERROR_FW_DNLD_FAILED;
2343                 break;
2344             case MLAN_STATUS_FW_NOT_DETECTED:
2345                 ret = -WIFI_ERROR_FW_NOT_DETECTED;
2346                 break;
2347 #if CONFIG_XZ_DECOMPRESSION
2348             case MLAN_STATUS_FW_XZ_FAILED:
2349                 ret = -WIFI_ERROR_FW_XZ_FAILED;
2350                 break;
2351 #endif /* CONFIG_XZ_DECOMPRESSION */
2352             case MLAN_STATUS_FW_NOT_READY:
2353                 ret = -WIFI_ERROR_FW_NOT_READY;
2354                 break;
2355             default:
2356                 wifi_d("sd_wifi_init unexpected MLAN Status %d", ret);
2357                 break;
2358         }
2359         return ret;
2360     }
2361 
2362     ret = wifi_core_init();
2363     if (ret != 0)
2364     {
2365         wifi_e("wifi_core_init failed. status code %d", ret);
2366     }
2367 
2368     if (ret == WM_SUCCESS)
2369     {
2370         wm_wifi.wifi_init_done = 1;
2371     }
2372 #ifndef RW610
2373     ret = (int)sd_wifi_post_init(WLAN_TYPE_FCC_CERTIFICATION);
2374     if (ret != WM_SUCCESS)
2375     {
2376         wifi_e("sd_wifi_post_init failed. status code %d", ret);
2377         return ret;
2378     }
2379 #endif
2380 
2381     return ret;
2382 }
2383 #endif
2384 
wifi_deinit(void)2385 void wifi_deinit(void)
2386 {
2387     if (wm_wifi.wifi_init_done == 0U)
2388     {
2389         return;
2390     }
2391 
2392     wm_wifi.wifi_init_done = 0;
2393 
2394     wifi_core_deinit();
2395 #if defined(RW610)
2396     imu_wifi_deinit();
2397 #else
2398     sd_wifi_deinit();
2399 #endif
2400 }
2401 
2402 #ifdef RW610
wifi_fw_is_hang(void)2403 bool wifi_fw_is_hang(void)
2404 {
2405     if (mlan_adap && mlan_adap->bus_ops.fw_is_hang)
2406         return mlan_adap->bus_ops.fw_is_hang();
2407     return false;
2408 }
2409 
wifi_destroy_wifidriver_tasks(void)2410 void wifi_destroy_wifidriver_tasks(void)
2411 {
2412 #if CONFIG_WMM
2413     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_drv_tx_task_Handle);
2414 #endif
2415     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_drv_task_Handle);
2416 #ifndef RW610
2417     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_core_task_Handle);
2418 #endif
2419     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_scan_task_Handle);
2420     (void)OSA_TaskDestroy((osa_task_handle_t)wm_wifi.wifi_powersave_task_Handle);
2421 
2422     imu_uninstall_callback();
2423 }
2424 #endif
wifi_set_tx_status(t_u8 status)2425 void wifi_set_tx_status(t_u8 status)
2426 {
2427     wifi_tx_status = status;
2428 }
2429 
wifi_set_rx_status(t_u8 status)2430 void wifi_set_rx_status(t_u8 status)
2431 {
2432     wifi_rx_status = status;
2433 }
2434 
wifi_set_packet_retry_count(const int count)2435 void wifi_set_packet_retry_count(const int count)
2436 {
2437     retry_attempts = count;
2438 }
2439 
2440 #if CONFIG_STA_AMPDU_TX
wifi_sta_ampdu_tx_enable(void)2441 void wifi_sta_ampdu_tx_enable(void)
2442 {
2443     sta_ampdu_tx_enable = true;
2444 }
2445 
wifi_sta_ampdu_tx_disable(void)2446 void wifi_sta_ampdu_tx_disable(void)
2447 {
2448     sta_ampdu_tx_enable = false;
2449 }
2450 
wifi_sta_ampdu_tx_enable_per_tid(t_u8 tid)2451 void wifi_sta_ampdu_tx_enable_per_tid(t_u8 tid)
2452 {
2453     sta_ampdu_tx_enable_per_tid = tid;
2454 }
2455 
wifi_sta_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)2456 t_u8 wifi_sta_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)
2457 {
2458     if ((sta_ampdu_tx_enable_per_tid >> tid) & 0x01)
2459         return MTRUE;
2460     else
2461         return MFALSE;
2462 }
2463 #else
wifi_sta_ampdu_tx_enable(void)2464 void wifi_sta_ampdu_tx_enable(void)
2465 {
2466 }
2467 
wifi_sta_ampdu_tx_disable(void)2468 void wifi_sta_ampdu_tx_disable(void)
2469 {
2470 }
wifi_sta_ampdu_tx_enable_per_tid(t_u8 tid)2471 void wifi_sta_ampdu_tx_enable_per_tid(t_u8 tid)
2472 {
2473 }
2474 
wifi_sta_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)2475 t_u8 wifi_sta_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)
2476 {
2477     return MTRUE;
2478 }
2479 #endif /* CONFIG_STA_AMPDU_TX */
2480 
2481 #if CONFIG_STA_AMPDU_RX
wifi_sta_ampdu_rx_enable(void)2482 void wifi_sta_ampdu_rx_enable(void)
2483 {
2484     sta_ampdu_rx_enable = true;
2485 }
2486 
wifi_sta_ampdu_rx_disable(void)2487 void wifi_sta_ampdu_rx_disable(void)
2488 {
2489     sta_ampdu_rx_enable = false;
2490 }
2491 
wifi_sta_ampdu_rx_enable_per_tid(t_u8 tid)2492 void wifi_sta_ampdu_rx_enable_per_tid(t_u8 tid)
2493 {
2494     sta_ampdu_rx_enable_per_tid = tid;
2495 }
2496 
wifi_sta_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)2497 t_u8 wifi_sta_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)
2498 {
2499     if ((sta_ampdu_rx_enable_per_tid >> tid) & 0x01)
2500         return MTRUE;
2501     else
2502         return MFALSE;
2503 }
2504 #else
wifi_sta_ampdu_rx_enable(void)2505 void wifi_sta_ampdu_rx_enable(void)
2506 {
2507 }
2508 
wifi_sta_ampdu_rx_disable(void)2509 void wifi_sta_ampdu_rx_disable(void)
2510 {
2511 }
wifi_sta_ampdu_rx_enable_per_tid(t_u8 tid)2512 void wifi_sta_ampdu_rx_enable_per_tid(t_u8 tid)
2513 {
2514 }
2515 
wifi_sta_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)2516 t_u8 wifi_sta_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)
2517 {
2518     return MTRUE;
2519 }
2520 #endif /* CONFIG_STA_AMPDU_RX */
2521 
2522 #if CONFIG_UAP_AMPDU_TX
wifi_uap_ampdu_tx_enable(void)2523 void wifi_uap_ampdu_tx_enable(void)
2524 {
2525     uap_ampdu_tx_enable = true;
2526 }
2527 
wifi_uap_ampdu_tx_disable(void)2528 void wifi_uap_ampdu_tx_disable(void)
2529 {
2530     uap_ampdu_tx_enable = false;
2531 }
2532 
wifi_uap_ampdu_tx_enable_per_tid(t_u8 tid)2533 void wifi_uap_ampdu_tx_enable_per_tid(t_u8 tid)
2534 {
2535     uap_ampdu_tx_enable_per_tid = tid;
2536 }
2537 
wifi_uap_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)2538 t_u8 wifi_uap_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)
2539 {
2540     if ((uap_ampdu_tx_enable_per_tid >> tid) & 0x01)
2541         return MTRUE;
2542     else
2543         return MFALSE;
2544 }
2545 #else
wifi_uap_ampdu_tx_enable(void)2546 void wifi_uap_ampdu_tx_enable(void)
2547 {
2548 }
2549 
wifi_uap_ampdu_tx_disable(void)2550 void wifi_uap_ampdu_tx_disable(void)
2551 {
2552 }
wifi_uap_ampdu_tx_enable_per_tid(t_u8 tid)2553 void wifi_uap_ampdu_tx_enable_per_tid(t_u8 tid)
2554 {
2555 }
2556 
wifi_uap_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)2557 t_u8 wifi_uap_ampdu_tx_enable_per_tid_is_allowed(t_u8 tid)
2558 {
2559     return MTRUE;
2560 }
2561 #endif /* CONFIG_STA_AMPDU_TX */
2562 
2563 #if CONFIG_UAP_AMPDU_RX
wifi_uap_ampdu_rx_enable(void)2564 void wifi_uap_ampdu_rx_enable(void)
2565 {
2566     uap_ampdu_rx_enable = true;
2567 }
2568 
wifi_uap_ampdu_rx_disable(void)2569 void wifi_uap_ampdu_rx_disable(void)
2570 {
2571     uap_ampdu_rx_enable = false;
2572 }
2573 
wifi_uap_ampdu_rx_enable_per_tid(t_u8 tid)2574 void wifi_uap_ampdu_rx_enable_per_tid(t_u8 tid)
2575 {
2576     uap_ampdu_rx_enable_per_tid = tid;
2577 }
2578 
wifi_uap_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)2579 t_u8 wifi_uap_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)
2580 {
2581     if ((uap_ampdu_rx_enable_per_tid >> tid) & 0x01)
2582         return MTRUE;
2583     else
2584         return MFALSE;
2585 }
2586 #else
wifi_uap_ampdu_rx_enable(void)2587 void wifi_uap_ampdu_rx_enable(void)
2588 {
2589 }
2590 
wifi_uap_ampdu_rx_disable(void)2591 void wifi_uap_ampdu_rx_disable(void)
2592 {
2593 }
wifi_uap_ampdu_rx_enable_per_tid(t_u8 tid)2594 void wifi_uap_ampdu_rx_enable_per_tid(t_u8 tid)
2595 {
2596 }
2597 
wifi_uap_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)2598 t_u8 wifi_uap_ampdu_rx_enable_per_tid_is_allowed(t_u8 tid)
2599 {
2600     return MTRUE;
2601 }
2602 #endif /* CONFIG_STA_AMPDU_RX */
2603 
2604 #if ((FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER) && FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER > 0U)
wifi_register_get_rxbuf_desc_callback(void * (* wifi_get_rxbuf_desc)(t_u16 rx_len))2605 int wifi_register_get_rxbuf_desc_callback(void *(*wifi_get_rxbuf_desc)(t_u16 rx_len))
2606 {
2607     if (wm_wifi.wifi_get_rxbuf_desc != NULL)
2608     {
2609         return -WM_FAIL;
2610     }
2611 
2612     wm_wifi.wifi_get_rxbuf_desc = wifi_get_rxbuf_desc;
2613 
2614     return WM_SUCCESS;
2615 }
2616 
wifi_deregister_get_rxbuf_desc_callback(void)2617 void wifi_deregister_get_rxbuf_desc_callback(void)
2618 {
2619     wm_wifi.wifi_get_rxbuf_desc = NULL;
2620 }
2621 #endif
2622 
2623 #if !CONFIG_WIFI_RX_REORDER
wifi_register_data_input_callback(void (* data_input_callback)(const uint8_t interface,const uint8_t * buffer,const uint16_t len))2624 int wifi_register_data_input_callback(void (*data_input_callback)(const uint8_t interface,
2625                                                                   const uint8_t *buffer,
2626                                                                   const uint16_t len))
2627 {
2628 #if CONFIG_HEAP_DEBUG
2629     static bool mem_stat_sem_init = 0;
2630     int ret;
2631 #endif
2632     if (wm_wifi.data_input_callback != NULL)
2633     {
2634         return -WM_FAIL;
2635     }
2636 
2637     wm_wifi.data_input_callback = data_input_callback;
2638 
2639 #if CONFIG_HEAP_DEBUG
2640     /* Semaphore to protect os mem stat */
2641     if (!mem_stat_sem_init)
2642     {
2643         ret = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)os_mem_stat_sem);
2644         if (ret != WM_SUCCESS)
2645         {
2646             PRINTF("Create os mem stat sem failed");
2647             return -WM_FAIL;
2648         }
2649         OSA_SemaphorePost((osa_semaphore_handle_t)os_mem_stat_sem);
2650         mem_stat_sem_init = 1;
2651     }
2652 #endif
2653 
2654     return WM_SUCCESS;
2655 }
2656 
wifi_deregister_data_input_callback(void)2657 void wifi_deregister_data_input_callback(void)
2658 {
2659     wm_wifi.data_input_callback = NULL;
2660 }
2661 #else
wifi_register_gen_pbuf_from_data2_callback(void * (* gen_pbuf_from_data2)(t_u8 * payload,t_u16 datalen,void ** p_payload))2662 int wifi_register_gen_pbuf_from_data2_callback(void *(*gen_pbuf_from_data2)(t_u8 *payload,
2663                                                                             t_u16 datalen,
2664                                                                             void **p_payload))
2665 {
2666 #if CONFIG_HEAP_DEBUG
2667     static bool mem_stat_sem_init = 0;
2668     int ret;
2669 #endif
2670     if (wm_wifi.gen_pbuf_from_data2 != NULL)
2671     {
2672         return -WM_FAIL;
2673     }
2674 
2675     wm_wifi.gen_pbuf_from_data2 = gen_pbuf_from_data2;
2676 
2677 #if CONFIG_HEAP_DEBUG
2678     /* Semaphore to protect os mem stat */
2679     if (!mem_stat_sem_init)
2680     {
2681         ret = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)os_mem_stat_sem);
2682         if (ret != WM_SUCCESS)
2683         {
2684             PRINTF("Create os mem stat sem failed");
2685             return -WM_FAIL;
2686         }
2687         OSA_SemaphorePost((osa_semaphore_handle_t)os_mem_stat_sem);
2688         mem_stat_sem_init = 1;
2689     }
2690 #endif
2691 
2692     return WM_SUCCESS;
2693 }
2694 
wifi_deregister_gen_pbuf_from_data2_callback(void)2695 void wifi_deregister_gen_pbuf_from_data2_callback(void)
2696 {
2697     wm_wifi.gen_pbuf_from_data2 = NULL;
2698 }
2699 #endif
2700 
wifi_register_amsdu_data_input_callback(void (* amsdu_data_input_callback)(uint8_t interface,uint8_t * buffer,uint16_t len))2701 int wifi_register_amsdu_data_input_callback(void (*amsdu_data_input_callback)(uint8_t interface,
2702                                                                               uint8_t *buffer,
2703                                                                               uint16_t len))
2704 {
2705     if (wm_wifi.amsdu_data_input_callback != NULL)
2706     {
2707         return -WM_FAIL;
2708     }
2709 
2710     wm_wifi.amsdu_data_input_callback = amsdu_data_input_callback;
2711 
2712     return WM_SUCCESS;
2713 }
2714 
wifi_deregister_amsdu_data_input_callback(void)2715 void wifi_deregister_amsdu_data_input_callback(void)
2716 {
2717     wm_wifi.amsdu_data_input_callback = NULL;
2718 }
2719 
wifi_register_deliver_packet_above_callback(void (* deliver_packet_above_callback)(void * rxpd,uint8_t interface,void * lwip_pbuf))2720 int wifi_register_deliver_packet_above_callback(void (*deliver_packet_above_callback)(void *rxpd,
2721                                                                                       uint8_t interface,
2722                                                                                       void *lwip_pbuf))
2723 {
2724     if (wm_wifi.deliver_packet_above_callback != NULL)
2725     {
2726         return -WM_FAIL;
2727     }
2728 
2729     wm_wifi.deliver_packet_above_callback = deliver_packet_above_callback;
2730 
2731     return WM_SUCCESS;
2732 }
2733 
wifi_deregister_deliver_packet_above_callback(void)2734 void wifi_deregister_deliver_packet_above_callback(void)
2735 {
2736     wm_wifi.deliver_packet_above_callback = NULL;
2737 }
2738 
wifi_register_wrapper_net_is_ip_or_ipv6_callback(bool (* wrapper_net_is_ip_or_ipv6_callback)(const t_u8 * buffer))2739 int wifi_register_wrapper_net_is_ip_or_ipv6_callback(bool (*wrapper_net_is_ip_or_ipv6_callback)(const t_u8 *buffer))
2740 {
2741     if (wm_wifi.wrapper_net_is_ip_or_ipv6_callback != NULL)
2742     {
2743         return -WM_FAIL;
2744     }
2745 
2746     wm_wifi.wrapper_net_is_ip_or_ipv6_callback = wrapper_net_is_ip_or_ipv6_callback;
2747 
2748     return WM_SUCCESS;
2749 }
2750 
wifi_deregister_wrapper_net_is_ip_or_ipv6_callback(void)2751 void wifi_deregister_wrapper_net_is_ip_or_ipv6_callback(void)
2752 {
2753     wm_wifi.wrapper_net_is_ip_or_ipv6_callback = NULL;
2754 }
2755 
2756 #if CONFIG_WPA_SUPP
2757 
wpa_supp_handle_link_lost(mlan_private * priv)2758 void wpa_supp_handle_link_lost(mlan_private *priv)
2759 {
2760     t_u8 broadcast_addr[ETH_ALEN]      = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2761     nxp_wifi_event_mlme_t *deauth_resp = &wm_wifi.mgmt_resp;
2762     IEEE80211_MGMT *mgmt               = (IEEE80211_MGMT *)deauth_resp->frame.frame;
2763 
2764     if (priv->bss_role == MLAN_BSS_ROLE_STA)
2765     {
2766         memset(mgmt, 0, sizeof(IEEE80211_MGMT));
2767 
2768         mgmt->frame_control            = SUBTYPE_DEAUTH;
2769         mgmt->duration                 = 0;
2770         mgmt->seq_ctrl                 = 0;
2771         mgmt->u.deauth_req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
2772 
2773         memcpy((void *)mgmt->da, broadcast_addr, MLAN_MAC_ADDR_LENGTH);
2774         memcpy((void *)mgmt->sa, priv->curr_bss_params.bss_descriptor.mac_address, MLAN_MAC_ADDR_LENGTH);
2775         memcpy((void *)mgmt->bssid, priv->curr_bss_params.bss_descriptor.mac_address, MLAN_MAC_ADDR_LENGTH);
2776 
2777         deauth_resp->frame.frame_len = 26;
2778 
2779         priv->curr_bss_params.host_mlme = 0;
2780         priv->auth_flag                 = 0;
2781 
2782         if (wm_wifi.supp_if_callbk_fns->deauth_callbk_fn)
2783         {
2784             wm_wifi.supp_if_callbk_fns->deauth_callbk_fn(wm_wifi.if_priv, deauth_resp, deauth_resp->frame.frame_len);
2785         }
2786     }
2787 }
2788 
2789 /**
2790  *   @brief This function processes the 802.11 mgmt Frame
2791  *
2792  *   @param priv            A pointer to mlan_private
2793  *
2794  *   @param payload         A pointer to the received buffer
2795  *   @param payload_len     Length of the received buffer
2796  *   @param prx_pd          A pointer to RxPD
2797  *
2798  *   @return                MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
2799  */
wlan_process_802dot11_mgmt_pkt2(mlan_private * priv,t_u8 * payload,t_u32 payload_len,RxPD * prx_pd)2800 static mlan_status wlan_process_802dot11_mgmt_pkt2(mlan_private *priv, t_u8 *payload, t_u32 payload_len, RxPD *prx_pd)
2801 {
2802     // pmlan_adapter pmadapter = priv->adapter;
2803     // pmlan_callbacks pcb = &pmadapter->callbacks;
2804     mlan_status ret                   = MLAN_STATUS_SUCCESS;
2805     wlan_802_11_header *pieee_pkt_hdr = MNULL;
2806     t_u16 sub_type                    = 0;
2807     // t_u8 *event_buf = MNULL;
2808     // mlan_event *pevent = MNULL;
2809     t_u8 unicast     = 0;
2810     t_u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2811 #if defined(ENABLE_802_11R) || defined(UAP_HOST_MLME)
2812 #if CONFIG_WIFI_EXTRA_DEBUG
2813     IEEE80211_MGMT *mgmt = MNULL;
2814 #endif
2815 #endif
2816 #if CONFIG_RX_CHAN_INFO
2817 #if CONFIG_TXPD_RXPD_V3
2818     t_u8 band_config = (prx_pd->rx_info & 0x3); /* Bit[1:0] 0: HALCHANBAND_BG, 1:HALCHANBAND_A, 2: HALCHANBAND_6E */
2819     t_u8 chan_num    = (prx_pd->rx_info & RXPD_CHAN_MASK) >>
2820                     5; /* Bit[13: 5] Non zero channel number on which this packet is received */
2821 #else
2822     t_u8 band_config = prx_pd->band_config;
2823     t_u8 chan_num    = prx_pd->chan_num;
2824 #endif
2825 #endif
2826     t_u8 category    = 0;
2827     t_u8 action_code = 0;
2828 #ifdef DOT1AS_SUPPORT
2829     struct timestamps tstamps;
2830 #endif
2831 #ifdef UAP_HOST_MLME
2832 #ifdef UAP_SUPPORT
2833     // t_u8 *sta_addr = NULL;
2834     // sta_node *sta_ptr = MNULL;
2835     // MrvlIETypes_MgmtFrameSet_t *tlv;
2836     // pmlan_buffer pmbuf;
2837 #endif
2838 #endif
2839 
2840     ENTER();
2841 #if 0
2842 /* rx buffer read from data path, nothing with MAX_EVENT_SIZE */
2843     if (payload_len > (MAX_EVENT_SIZE - sizeof(mlan_event)))
2844     {
2845         wifi_d("Dropping large mgmt frame,len =%d", payload_len);
2846         LEAVE();
2847         return ret;
2848     }
2849 #endif
2850     /* Check  packet type-subtype and compare with mgmt_passthru_mask
2851      * If event is needed to host, just eventify it */
2852     pieee_pkt_hdr = (wlan_802_11_header *)payload;
2853     sub_type      = IEEE80211_GET_FC_MGMT_FRAME_SUBTYPE(pieee_pkt_hdr->frm_ctl);
2854     if (((1 << sub_type) & priv->mgmt_frame_passthru_mask) == 0)
2855     {
2856         wifi_d("Dropping mgmt frame for subtype %d snr=%d.", sub_type, prx_pd->snr);
2857         LEAVE();
2858         return ret;
2859     }
2860     switch (sub_type)
2861     {
2862         case SUBTYPE_ASSOC_REQUEST:
2863         case SUBTYPE_REASSOC_REQUEST:
2864 #ifdef UAP_HOST_MLME
2865 #ifdef UAP_SUPPORT
2866             if (priv->uap_host_based)
2867             {
2868                 if (!memcmp(pieee_pkt_hdr->addr3, priv->curr_addr, MLAN_MAC_ADDR_LENGTH))
2869                 {
2870                     wifi_d("wlan: HostMlme MICRO_AP_STA_ASSOC " MACSTR "", MAC2STR(pieee_pkt_hdr->addr2));
2871 
2872 #if 0
2873                     sta_addr = OSA_MemoryAllocate(MLAN_MAC_ADDR_LENGTH);
2874                     if (sta_addr == MNULL)
2875                     {
2876                         wifi_w("No mem. Cannot process MAC address from assoc");
2877                         LEAVE();
2878                         return ret;
2879                     }
2880 
2881                     (void)memcpy((void *)sta_addr, (const void *)pieee_pkt_hdr->addr2, MLAN_MAC_ADDR_LENGTH);
2882                     if (wifi_event_completion(WIFI_EVENT_UAP_CLIENT_ASSOC, WIFI_EVENT_REASON_SUCCESS, sta_addr) !=
2883                         WM_SUCCESS)
2884                     {
2885                         /* If fail to send message on queue, free allocated memory ! */
2886                         OSA_MemoryFree((void *)sta_addr);
2887                     }
2888 
2889                     mgmt    = (IEEE80211_MGMT *)payload;
2890                     sta_ptr = wlan_add_station_entry(priv, pieee_pkt_hdr->addr2);
2891                     if (sta_ptr)
2892                     {
2893                         sta_ptr->capability = wlan_le16_to_cpu(mgmt->u.assoc_req.capab_info);
2894                         pmbuf               = wlan_alloc_mlan_buffer(pmadapter, payload_len, 0, MTRUE);
2895                         if (pmbuf)
2896                         {
2897                             wifi_d("check sta capability");
2898                             pmbuf->data_len = ASSOC_EVENT_FIX_SIZE;
2899                             tlv = (MrvlIETypes_MgmtFrameSet_t *)(pmbuf->pbuf + pmbuf->data_offset + pmbuf->data_len);
2900                             tlv->type = wlan_cpu_to_le16(TLV_TYPE_MGMT_FRAME);
2901                             tlv->len  = sizeof(IEEEtypes_FrameCtl_t);
2902                             __memcpy(pmadapter, (t_u8 *)&tlv->frame_control, &pieee_pkt_hdr->frm_ctl,
2903                                      sizeof(IEEEtypes_FrameCtl_t));
2904                             pmbuf->data_len += sizeof(MrvlIETypes_MgmtFrameSet_t);
2905                             __memcpy(pmadapter, pmbuf->pbuf + pmbuf->data_offset + pmbuf->data_len,
2906                                      payload + sizeof(wlan_802_11_header), payload_len - sizeof(wlan_802_11_header));
2907                             pmbuf->data_len += payload_len - sizeof(wlan_802_11_header);
2908                             tlv->len += payload_len - sizeof(wlan_802_11_header);
2909                             tlv->len = wlan_cpu_to_le16(tlv->len);
2910                             DBG_HEXDUMP(MCMD_D, "assoc_req", pmbuf->pbuf + pmbuf->data_offset, pmbuf->data_len);
2911                             wlan_check_sta_capability(priv, pmbuf, sta_ptr);
2912                             wlan_free_mlan_buffer(pmadapter, pmbuf);
2913 
2914                             OSA_MemoryFree(pmbuf);
2915                         }
2916                     }
2917 #endif
2918                 }
2919                 else
2920                 {
2921                     wifi_d("wlan: Drop MICRO_AP_STA_ASSOC " MACSTR " from unknown BSSID " MACSTR "\r\n",
2922                            MAC2STR(pieee_pkt_hdr->addr2), MAC2STR(pieee_pkt_hdr->addr3));
2923                 }
2924             }
2925             unicast = MTRUE;
2926             break;
2927 #endif
2928 #endif
2929         case SUBTYPE_AUTH:
2930             unicast = MTRUE;
2931             wifi_d("wlan: HostMlme Auth received from " MACSTR "\r\n", MAC2STR(pieee_pkt_hdr->addr2));
2932 
2933             if (priv->bss_role == MLAN_BSS_ROLE_STA)
2934             {
2935 #if CONFIG_HOST_MLME
2936                 if (priv->curr_bss_params.host_mlme)
2937                 {
2938                     if (priv->auth_flag & HOST_MLME_AUTH_PENDING)
2939                     {
2940                         if (priv->auth_alg != WLAN_AUTH_SAE)
2941                         {
2942                             priv->auth_flag &= ~HOST_MLME_AUTH_PENDING;
2943                             priv->auth_flag |= HOST_MLME_AUTH_DONE;
2944                         }
2945                     }
2946                 }
2947 #endif
2948             }
2949             break;
2950         case SUBTYPE_PROBE_RESP:
2951             unicast = MTRUE;
2952             break;
2953         case SUBTYPE_DISASSOC:
2954         case SUBTYPE_DEAUTH:
2955             if (memcmp(pieee_pkt_hdr->addr1, broadcast, MLAN_MAC_ADDR_LENGTH))
2956                 unicast = MTRUE;
2957 #ifdef UAP_HOST_MLME
2958 #ifdef UAP_SUPPORT
2959             if (priv->uap_host_based)
2960             {
2961                 if (!memcmp(pieee_pkt_hdr->addr3, priv->curr_addr, MLAN_MAC_ADDR_LENGTH))
2962                 {
2963 #if CONFIG_WIFI_EXTRA_DEBUG
2964                     mgmt = (IEEE80211_MGMT *)payload;
2965 #endif
2966 
2967                     wifi_d("wlan: HostMlme Deauth Receive from " MACSTR " reason code: %d\r\n",
2968                            MAC2STR(pieee_pkt_hdr->addr2), mgmt->u.deauth_req.reason_code);
2969 
2970 #if 0
2971                     sta_addr = OSA_MemoryAllocate(MLAN_MAC_ADDR_LENGTH);
2972                     if (sta_addr == MNULL)
2973                     {
2974                         wifi_w("No mem. Cannot process MAC address from deauth");
2975                         LEAVE();
2976                         return ret;
2977                     }
2978 
2979                     (void)memcpy((void *)sta_addr, (const void *)pieee_pkt_hdr->addr2, MLAN_MAC_ADDR_LENGTH);
2980                     if (wifi_event_completion(WIFI_EVENT_UAP_CLIENT_DEAUTH, WIFI_EVENT_REASON_SUCCESS, sta_addr) !=
2981                         WM_SUCCESS)
2982                     {
2983                         /* If fail to send message on queue, free allocated memory ! */
2984                         OSA_MemoryFree((void *)sta_addr);
2985                     }
2986 #endif
2987                 }
2988                 else
2989                 {
2990                     LEAVE();
2991                     return ret;
2992                 }
2993             }
2994 #endif
2995 #endif
2996             if (priv->bss_role == MLAN_BSS_ROLE_STA)
2997             {
2998 #if CONFIG_HOST_MLME
2999 
3000                 t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = {0};
3001                 if ((memcmp(pieee_pkt_hdr->addr3, (t_u8 *)priv->curr_bss_params.bss_descriptor.mac_address,
3002                            MLAN_MAC_ADDR_LENGTH) &&
3003                     memcmp(zero_mac, (t_u8 *)priv->curr_bss_params.bss_descriptor.mac_address,
3004                            MLAN_MAC_ADDR_LENGTH)) ||
3005                     memcmp(pieee_pkt_hdr->addr3, (t_u8 *)priv->curr_bss_params.attemp_bssid,
3006                            MLAN_MAC_ADDR_LENGTH))
3007                 {
3008                     wifi_d("Dropping Deauth frame from other bssid: type=%d " MACSTR "\r\n", sub_type,
3009                            MAC2STR(pieee_pkt_hdr->addr3));
3010                     LEAVE();
3011                     return ret;
3012                 }
3013                 wifi_d("wlan: HostMlme Disconnected: sub_type=%d\n", sub_type);
3014 #if 0
3015 				pmadapter->pending_disconnect_priv = priv;
3016 				wlan_recv_event(
3017 					priv, MLAN_EVENT_ID_DRV_DEFER_HANDLING,
3018 					MNULL);
3019 #endif
3020 #endif
3021             }
3022             break;
3023         case SUBTYPE_ACTION:
3024             category    = *(payload + sizeof(wlan_802_11_header));
3025             action_code = *(payload + sizeof(wlan_802_11_header) + 1);
3026             /*wpa_supplicant only deals with those action frame below*/
3027             if (category != IEEE_MGMT_ACTION_CATEGORY_WMM_TSPEC && category != IEEE_MGMT_ACTION_CATEGORY_FST &&
3028                 category != IEEE_MGMT_ACTION_CATEGORY_PUBLIC && category != IEEE_MGMT_ACTION_CATEGORY_RADIO_RSRC &&
3029                 category != IEEE_MGMT_ACTION_CATEGORY_PROTECTED_DUAL && category != IEEE_MGMT_ACTION_CATEGORY_QOS &&
3030                 category != IEEE_MGMT_ACTION_CATEGORY_FAST_BSS_TRANS &&
3031                 category != IEEE_MGMT_ACTION_CATEGORY_SA_QUERY && category != IEEE_MGMT_ACTION_CATEGORY_AV_STREAMING &&
3032                 category != IEEE_MGMT_ACTION_CATEGORY_WNM)
3033             {
3034                 wifi_d("Drop action frame: category = %d, action_code=%d", category, action_code);
3035                 LEAVE();
3036                 return ret;
3037             }
3038             if (category == IEEE_MGMT_ACTION_CATEGORY_BLOCK_ACK)
3039             {
3040                 wifi_d("Drop BLOCK ACK action frame: action_code=%d", action_code);
3041                 LEAVE();
3042                 return ret;
3043             }
3044             if ((category == IEEE_MGMT_ACTION_CATEGORY_PUBLIC) &&
3045                 (action_code == BSS_20_40_COEX || action_code == FILS_DISCOVERY))
3046             {
3047                 wifi_d("Drop unneed public action frame %d", action_code);
3048                 LEAVE();
3049                 return ret;
3050             }
3051 #ifdef HOST_TDLS_SUPPORT
3052             if ((category == CATEGORY_PUBLIC) && (action_code == TDLS_DISCOVERY_RESPONSE))
3053             {
3054                 pcb->moal_updata_peer_signal(pmadapter->pmoal_handle, priv->bss_index, pieee_pkt_hdr->addr2,
3055                                              prx_pd->snr, prx_pd->nf);
3056                 PRINTM(MINFO, "Rx: TDLS discovery response, nf=%d, snr=%d\n", prx_pd->nf, prx_pd->snr);
3057             }
3058 #endif
3059 #ifdef DOT1AS_SUPPORT
3060             if ((category == IEEE_MGMT_ACTION_CATEGORY_UNPROTECT_WNM) && (action_code == 0x1))
3061             {
3062 #if CONFIG_TXPD_RXPD_V3
3063                 prx_pd->toa_tod_tstamps = wlan_le64_to_cpu(prx_pd->toa_tod_tstamps);
3064                 tstamps.t3              = prx_pd->toa_tod_tstamps >> 32;
3065                 tstamps.t2              = (t_u32)prx_pd->toa_tod_tstamps;
3066 #else
3067                 prx_pd->Tsf = wlan_le64_to_cpu(prx_pd->Tsf);
3068                 tstamps.t3  = prx_pd->Tsf >> 32;
3069                 tstamps.t2  = (t_u32)prx_pd->Tsf;
3070 #endif
3071                 tstamps.t2_err       = 0;
3072                 tstamps.t3_err       = 0;
3073                 tstamps.ingress_time = pcb->moal_do_div(pmadapter->host_bbu_clk_delta, 10);
3074                 tstamps.ingress_time += tstamps.t2; // t2, t3 is 10ns
3075                                                     // and delta is in 1
3076                                                     // ns unit;
3077                 PRINTM(MINFO, "T2: %d, T3: %d, ingress: %lu\n", tstamps.t2, tstamps.t3, tstamps.ingress_time);
3078             }
3079 #endif
3080             if (memcmp(pieee_pkt_hdr->addr1, broadcast, MLAN_MAC_ADDR_LENGTH))
3081                 unicast = MTRUE;
3082             break;
3083         default:
3084             break;
3085     }
3086     if (unicast == MTRUE)
3087     {
3088         if (memcmp(pieee_pkt_hdr->addr1, priv->curr_addr, MLAN_MAC_ADDR_LENGTH))
3089         {
3090             wifi_d("Dropping mgmt frame for others: type=%d " MACSTR "\r\n", sub_type, MAC2STR(pieee_pkt_hdr->addr1));
3091             LEAVE();
3092             return ret;
3093         }
3094     }
3095 
3096 #if 0
3097 	/* Allocate memory for event buffer */
3098 	ret = pcb->moal_malloc(pmadapter->pmoal_handle, MAX_EVENT_SIZE,
3099 			       MLAN_MEM_DEF, &event_buf);
3100 	if ((ret != MLAN_STATUS_SUCCESS) || !event_buf) {
3101 		PRINTM(MERROR, "Could not allocate buffer for event buf\n");
3102 		LEAVE();
3103 		return MLAN_STATUS_FAILURE;
3104 	}
3105 	pevent = (pmlan_event)event_buf;
3106 	pevent->bss_index = priv->bss_index;
3107 #ifdef ENABLE_802_11R
3108 	mgmt = (IEEE80211_MGMT *)payload;
3109 	if (
3110 		priv->bss_role == MLAN_BSS_ROLE_STA &&
3111 #if CONFIG_HOST_MLME
3112 		!priv->curr_bss_params.host_mlme &&
3113 #endif
3114 		sub_type == SUBTYPE_ACTION &&
3115 		mgmt->u.ft_resp.category == FT_CATEGORY &&
3116 		mgmt->u.ft_resp.action == FT_ACTION_RESPONSE &&
3117 		mgmt->u.ft_resp.status_code == 0) {
3118 		PRINTM(MCMND, "FT Action response received\n");
3119 #define FT_ACTION_HEAD_LEN (24 + 6 + 16)
3120 		pevent->event_id = MLAN_EVENT_ID_DRV_FT_RESPONSE;
3121 		pevent->event_len =
3122 			payload_len + MLAN_MAC_ADDR_LENGTH - FT_ACTION_HEAD_LEN;
3123 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
3124 			   &mgmt->u.ft_resp.target_ap_addr,
3125 			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
3126 		memcpy_ext(pmadapter,
3127 			   (t_u8 *)(pevent->event_buf + MLAN_MAC_ADDR_LENGTH),
3128 			   payload + FT_ACTION_HEAD_LEN,
3129 			   payload_len - FT_ACTION_HEAD_LEN,
3130 			   pevent->event_len - MLAN_MAC_ADDR_LENGTH);
3131 	} else if (
3132 		priv->bss_role == MLAN_BSS_ROLE_STA &&
3133 #if CONFIG_HOST_MLME
3134 		!priv->curr_bss_params.host_mlme &&
3135 #endif
3136 		sub_type == SUBTYPE_AUTH &&
3137 		mgmt->u.auth.auth_alg == MLAN_AUTH_MODE_FT &&
3138 		mgmt->u.auth.auth_transaction == 2 &&
3139 		mgmt->u.auth.status_code == 0) {
3140 		PRINTM(MCMND, "FT auth response received \n");
3141 #define AUTH_PACKET_LEN (24 + 6 + 6)
3142 		pevent->event_id = MLAN_EVENT_ID_DRV_FT_RESPONSE;
3143 		pevent->event_len =
3144 			payload_len + MLAN_MAC_ADDR_LENGTH - AUTH_PACKET_LEN;
3145 		memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf, mgmt->sa,
3146 			   MLAN_MAC_ADDR_LENGTH, MLAN_MAC_ADDR_LENGTH);
3147 		memcpy_ext(pmadapter,
3148 			   (t_u8 *)(pevent->event_buf + MLAN_MAC_ADDR_LENGTH),
3149 			   payload + AUTH_PACKET_LEN,
3150 			   payload_len - AUTH_PACKET_LEN,
3151 			   pevent->event_len - MLAN_MAC_ADDR_LENGTH);
3152 	} else {
3153 #endif
3154 		pevent->event_id = MLAN_EVENT_ID_DRV_MGMT_FRAME;
3155 		pevent->event_len = payload_len + sizeof(pevent->event_id);
3156 #if CONFIG_RX_CHAN_INFO
3157 		pevent->event_buf[0] = band_config;
3158 		pevent->event_buf[1] = chan_num;
3159 #else
3160 	memcpy_ext(pmadapter, (t_u8 *)pevent->event_buf,
3161 		   (t_u8 *)&pevent->event_id, sizeof(pevent->event_id),
3162 		   pevent->event_len);
3163 #endif
3164 		memcpy_ext(
3165 			pmadapter,
3166 			(t_u8 *)(pevent->event_buf + sizeof(pevent->event_id)),
3167 			payload, payload_len, payload_len);
3168 #ifdef DOT1AS_SUPPORT
3169 		// Append timestamp info at the end of event
3170 		if ((category == IEEE_MGMT_ACTION_CATEGORY_UNPROTECT_WNM) &&
3171 		    (action_code == 0x1)) {
3172 			memcpy_ext(pmadapter,
3173 				   (t_u8 *)(pevent->event_buf +
3174 					    sizeof(pevent->event_id) +
3175 					    payload_len),
3176 				   &tstamps, sizeof(struct timestamps),
3177 				   sizeof(struct timestamps));
3178 			pevent->event_len = payload_len +
3179 					    sizeof(pevent->event_id) +
3180 					    sizeof(struct timestamps);
3181 		}
3182 #endif
3183 #ifdef ENABLE_802_11R
3184 	}
3185 #endif
3186 	wlan_recv_event(priv, pevent->event_id, pevent);
3187 	if (event_buf)
3188 		pcb->moal_mfree(pmadapter->pmoal_handle, event_buf);
3189 #endif
3190 
3191     memmove((uint8_t *)pieee_pkt_hdr + (sizeof(wlan_802_11_header) - MLAN_MAC_ADDR_LENGTH),
3192             (uint8_t *)pieee_pkt_hdr + (sizeof(wlan_802_11_header)), payload_len - sizeof(wlan_802_11_header));
3193 
3194     payload_len -= MLAN_MAC_ADDR_LENGTH;
3195     if (payload_len > sizeof(wm_wifi.mgmt_resp.frame.frame))
3196     {
3197         wifi_w("The payload length (%d) overs the max length(%d), dropping mgmt frame: type=%d", payload_len,
3198                sizeof(wm_wifi.mgmt_resp.frame.frame), sub_type);
3199         dump_hex(payload, 64);
3200         return MLAN_STATUS_FAILURE;
3201     }
3202 
3203     if (priv->bss_role == MLAN_BSS_ROLE_STA)
3204     {
3205         if (sub_type == (t_u16)SUBTYPE_AUTH)
3206         {
3207             nxp_wifi_event_mlme_t *auth_resp = &wm_wifi.mgmt_resp;
3208 
3209             if (payload_len <= sizeof(auth_resp->frame.frame))
3210             {
3211                 memset(auth_resp, 0, sizeof(nxp_wifi_event_mlme_t));
3212                 auth_resp->frame.frame_len = payload_len;
3213                 memcpy((void *)auth_resp->frame.frame, (const void *)pieee_pkt_hdr, payload_len);
3214                 if (wm_wifi.supp_if_callbk_fns->auth_resp_callbk_fn)
3215                 {
3216                     wm_wifi.supp_if_callbk_fns->auth_resp_callbk_fn(wm_wifi.if_priv, auth_resp,
3217                                                                     auth_resp->frame.frame_len);
3218                 }
3219             }
3220             else
3221             {
3222                 wifi_e("Insufficient frame buffer");
3223             }
3224         }
3225 
3226         if (sub_type == (t_u16)SUBTYPE_DEAUTH)
3227         {
3228             nxp_wifi_event_mlme_t *deauth_resp = &wm_wifi.mgmt_resp;
3229 
3230             wlan_abort_split_scan();
3231             wifi_user_scan_config_cleanup();
3232 
3233             if (payload_len <= (int)sizeof(deauth_resp->frame.frame))
3234             {
3235                 memset(deauth_resp, 0, sizeof(nxp_wifi_event_mlme_t));
3236                 deauth_resp->frame.frame_len = payload_len;
3237                 memcpy((void *)deauth_resp->frame.frame, (const void *)pieee_pkt_hdr, deauth_resp->frame.frame_len);
3238                 if (wm_wifi.supp_if_callbk_fns->deauth_callbk_fn)
3239                 {
3240                     wm_wifi.supp_if_callbk_fns->deauth_callbk_fn(wm_wifi.if_priv, deauth_resp,
3241                                                                  deauth_resp->frame.frame_len);
3242                 }
3243             }
3244             else
3245             {
3246                 wifi_e("Insufficient frame buffer");
3247             }
3248         }
3249 
3250         if (sub_type == (t_u16)SUBTYPE_DISASSOC)
3251         {
3252             nxp_wifi_event_mlme_t *disassoc_resp = &wm_wifi.mgmt_resp;
3253 
3254             wlan_abort_split_scan();
3255             wifi_user_scan_config_cleanup();
3256 
3257             if (payload_len <= (int)sizeof(disassoc_resp->frame.frame))
3258             {
3259                 memset(disassoc_resp, 0, sizeof(nxp_wifi_event_mlme_t));
3260                 disassoc_resp->frame.frame_len = payload_len;
3261                 memcpy((void *)disassoc_resp->frame.frame, (const void *)pieee_pkt_hdr, disassoc_resp->frame.frame_len);
3262                 if (wm_wifi.supp_if_callbk_fns->disassoc_callbk_fn)
3263                 {
3264                     wm_wifi.supp_if_callbk_fns->disassoc_callbk_fn(wm_wifi.if_priv, disassoc_resp,
3265                                                                    disassoc_resp->frame.frame_len);
3266                 }
3267             }
3268             else
3269             {
3270                 wifi_e("Insufficient frame buffer");
3271             }
3272         }
3273 
3274         if (sub_type == (t_u16)SUBTYPE_ACTION)
3275         {
3276             nxp_wifi_event_mlme_t *mgmt_rx = &wm_wifi.mgmt_rx;
3277 
3278             if (payload_len <= (int)sizeof(mgmt_rx->frame.frame))
3279             {
3280                 memset(mgmt_rx, 0, sizeof(nxp_wifi_event_mlme_t));
3281                 mgmt_rx->frame.frame_len = payload_len;
3282                 memcpy((void *)mgmt_rx->frame.frame, (const void *)pieee_pkt_hdr, mgmt_rx->frame.frame_len);
3283 #if CONFIG_RX_CHAN_INFO
3284                 mgmt_rx->frame.freq = channel_to_frequency(chan_num, band_config);
3285 #endif
3286                 if (wm_wifi.supp_if_callbk_fns->mgmt_rx_callbk_fn)
3287                 {
3288                     wm_wifi.supp_if_callbk_fns->mgmt_rx_callbk_fn(wm_wifi.if_priv, mgmt_rx, mgmt_rx->frame.frame_len,
3289                         prx_pd->snr - prx_pd->nf);
3290                 }
3291             }
3292             else
3293             {
3294                 wifi_e("Insufficient frame buffer");
3295             }
3296         }
3297     }
3298     else if (priv->bss_role == MLAN_BSS_ROLE_UAP)
3299     {
3300         nxp_wifi_event_mlme_t *mgmt_rx = &wm_wifi.mgmt_rx;
3301 
3302         mgmt_rx->frame.frame_len = payload_len;
3303 
3304         if (mgmt_rx->frame.frame_len <= (int)sizeof(mgmt_rx->frame.frame))
3305         {
3306             memcpy((void *)mgmt_rx->frame.frame, (const void *)pieee_pkt_hdr, mgmt_rx->frame.frame_len);
3307 #if CONFIG_RX_CHAN_INFO
3308             mgmt_rx->frame.freq = channel_to_frequency(chan_num, band_config);
3309 #endif
3310             if (wm_wifi.supp_if_callbk_fns->mgmt_rx_callbk_fn)
3311             {
3312                 wm_wifi.supp_if_callbk_fns->mgmt_rx_callbk_fn(wm_wifi.hapd_if_priv, mgmt_rx, mgmt_rx->frame.frame_len,
3313                     prx_pd->snr - prx_pd->nf);
3314             }
3315         }
3316         else
3317         {
3318             wifi_e("Insufficient frame buffer");
3319         }
3320     }
3321 
3322     LEAVE();
3323     return MLAN_STATUS_SUCCESS;
3324 }
3325 
wifi_is_wpa_supplicant_input(const uint8_t interface,const uint8_t * buffer,const uint16_t len)3326 void wifi_is_wpa_supplicant_input(const uint8_t interface, const uint8_t *buffer, const uint16_t len)
3327 {
3328     mlan_private *priv           = (mlan_private *)mlan_adap->priv[interface];
3329     RxPD *prx_pd                 = (RxPD *)(void *)((t_u8 *)buffer + INTF_HEADER_LEN);
3330     wlan_mgmt_pkt *pmgmt_pkt_hdr = MNULL;
3331 
3332     /* Check if this is mgmt packet and needs to
3333      * forwarded to app as an event
3334      */
3335     pmgmt_pkt_hdr          = (wlan_mgmt_pkt *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);
3336     pmgmt_pkt_hdr->frm_len = wlan_le16_to_cpu(pmgmt_pkt_hdr->frm_len);
3337 
3338     if ((pmgmt_pkt_hdr->wlan_header.frm_ctl & IEEE80211_FC_MGMT_FRAME_TYPE_MASK) == 0)
3339         wlan_process_802dot11_mgmt_pkt2(priv, (t_u8 *)&pmgmt_pkt_hdr->wlan_header,
3340                                         pmgmt_pkt_hdr->frm_len + sizeof(wlan_mgmt_pkt) - sizeof(pmgmt_pkt_hdr->frm_len),
3341                                         prx_pd);
3342 }
3343 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
wifi_wpa_supplicant_eapol_input(const uint8_t interface,const uint8_t * src_addr,const uint8_t * buffer,const uint16_t len)3344 void wifi_wpa_supplicant_eapol_input(const uint8_t interface,
3345                                      const uint8_t *src_addr,
3346                                      const uint8_t *buffer,
3347                                      const uint16_t len)
3348 {
3349     nxp_wifi_event_eapol_mlme_t *eapol_rx = &wm_wifi.eapol_rx;
3350 
3351     memcpy((void *)eapol_rx->mac_addr, (const void *)src_addr, MLAN_MAC_ADDR_LENGTH);
3352 
3353     eapol_rx->frame.frame_len = len;
3354     memcpy((void *)eapol_rx->frame.frame, (const void *)buffer, eapol_rx->frame.frame_len);
3355     if (wm_wifi.supp_if_callbk_fns->eapol_rx_callbk_fn)
3356     {
3357         wm_wifi.supp_if_callbk_fns->eapol_rx_callbk_fn(
3358             interface == MLAN_BSS_TYPE_STA ? wm_wifi.if_priv : wm_wifi.hapd_if_priv, eapol_rx,
3359             eapol_rx->frame.frame_len);
3360     }
3361 }
3362 #endif
3363 #define RX_PKT_TYPE_OFFSET  5U
3364 #define ETH_PROTO_EAPOL     0x888EU
3365 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
3366 #define WIFI_SIZEOF_ETH_HDR 14U
3367 static t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
3368 #endif
3369 #endif
3370 
wifi_low_level_input(const uint8_t interface,const uint8_t * buffer,const uint16_t len)3371 static int wifi_low_level_input(const uint8_t interface, const uint8_t *buffer, const uint16_t len)
3372 {
3373 #if CONFIG_WPA_SUPP
3374 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
3375     RxPD *prx_pd  = (RxPD *)(void *)((t_u8 *)buffer + INTF_HEADER_LEN);
3376     eth_hdr *ethh = MNULL;
3377     t_u16 eth_proto;
3378     t_u8 offset = 0;
3379 #endif
3380     if (*((t_u16 *)buffer + RX_PKT_TYPE_OFFSET) == PKT_TYPE_MGMT_FRAME)
3381     {
3382         wifi_is_wpa_supplicant_input(interface, buffer, len);
3383         return WM_SUCCESS;
3384     }
3385 
3386 #if !CONFIG_WIFI_NM_WPA_SUPPLICANT
3387     ethh = (eth_hdr *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset);
3388 
3389     eth_proto = mlan_ntohs(ethh->h_proto);
3390 
3391     if (memcmp((t_u8 *)prx_pd + prx_pd->rx_pkt_offset + WIFI_SIZEOF_ETH_HDR, rfc1042_eth_hdr,
3392                sizeof(rfc1042_eth_hdr)) == 0U)
3393     {
3394         eth_llc_hdr *ethllchdr = (eth_llc_hdr *)(void *)((t_u8 *)prx_pd + prx_pd->rx_pkt_offset + WIFI_SIZEOF_ETH_HDR);
3395         eth_proto              = mlan_ntohs(ethllchdr->type);
3396         offset                 = sizeof(eth_llc_hdr);
3397     }
3398 
3399     if (eth_proto == ETH_PROTO_EAPOL)
3400     {
3401         wifi_wpa_supplicant_eapol_input(interface, ethh->src_addr, (uint8_t *)(ethh + 1) + offset,
3402                                         prx_pd->rx_pkt_length - sizeof(eth_hdr) - offset);
3403         return WM_SUCCESS;
3404     }
3405 #endif
3406 #endif
3407     if (wifi_rx_status == WIFI_DATA_BLOCK)
3408     {
3409         wifi_rx_block_cnt++;
3410         return WM_SUCCESS;
3411     }
3412 
3413     if (mlan_adap->ps_state == PS_STATE_SLEEP)
3414     {
3415         OSA_RWLockWriteUnlock(&sleep_rwlock);
3416         mlan_adap->ps_state = PS_STATE_AWAKE;
3417     }
3418 
3419 #if CONFIG_WIFI_RX_REORDER
3420     RxPD *rxpd        = (RxPD *)(void *)((t_u8 *)buffer + INTF_HEADER_LEN);
3421     t_u8 *payload     = MNULL;
3422     t_u16 payload_len = (t_u16)0U;
3423     void *p           = MNULL;
3424     void *p_payload   = MNULL;
3425 
3426     if (wm_wifi.gen_pbuf_from_data2 != MNULL)
3427     {
3428         payload     = (t_u8 *)rxpd + rxpd->rx_pkt_offset;
3429         payload_len = rxpd->rx_pkt_length;
3430 
3431         p = wm_wifi.gen_pbuf_from_data2(payload, payload_len, &p_payload);
3432 
3433         if (p == MNULL)
3434             return -WM_FAIL;
3435 
3436         return wrapper_wlan_handle_rx_packet(len, rxpd, p, p_payload);
3437     }
3438 #else
3439     if (wm_wifi.data_input_callback != NULL)
3440     {
3441         wm_wifi.data_input_callback(interface, buffer, len);
3442         return WM_SUCCESS;
3443     }
3444 
3445 #endif
3446 
3447     return -WM_FAIL;
3448 }
3449 
3450 #define ERR_INPROGRESS -5
3451 
3452 #define WL_ID_LL_OUTPUT "wifi_low_level_output"
3453 
wifi_tx_card_awake_lock(void)3454 void wifi_tx_card_awake_lock(void)
3455 {
3456     int ret;
3457 
3458     /* Write mutex is used to avoid the case that, during waitting for sleep confirm cmd response,
3459      * wifi_driver_tx task might be scheduled and send data to FW */
3460     (void)OSA_MutexLock((osa_mutex_handle_t)sleep_rwlock.write_mutex, osaWaitForever_c);
3461     ret = OSA_RWLockReadLock(&sleep_rwlock, MAX_WAIT_TIME);
3462     (void)OSA_MutexUnlock((osa_mutex_handle_t)sleep_rwlock.write_mutex);
3463     if (ret != WM_SUCCESS)
3464     {
3465 #if CONFIG_WIFI_PS_DEBUG
3466         wifi_e("Failed to wakeup card for Tx");
3467 #endif
3468 #if CONFIG_WIFI_RECOVERY
3469         wifi_recovery_enable = true;
3470 #else
3471         assert(0);
3472 #endif
3473     }
3474 }
3475 
wifi_tx_card_awake_unlock(void)3476 void wifi_tx_card_awake_unlock(void)
3477 {
3478     OSA_RWLockReadUnlock(&sleep_rwlock);
3479 }
3480 
3481 #if CONFIG_WMM
3482 
3483 #define ETHER_TYPE_IP_01         0xc
3484 #define ETHER_TYPE_IP_02         0xd
3485 #define ETHER_TYPE_IPV4_VALUE_01 0x8
3486 #define ETHER_TYPE_IPV4_VALUE_02 0x0
3487 #define WMM_PACKET_TOS_IV4       0xf
3488 #define PRIORITY_COMPENSATOR     0x20
3489 #define UDP_IDENTIFIER_POS       0x11
3490 #define UDP_IDENTIFIER_VAL       0xda
3491 
3492 #define ETHER_TYPE_IPV6_VALUE_01 0x86
3493 #define ETHER_TYPE_IPV6_VALUE_02 0xdd
3494 #define WMM_PACKET_TOS_IPV6_01   0xe
3495 #define WMM_PACKET_TOS_IPV6_02   0xf
3496 #define TOS_MASK_IPV6            0x0ff0 /* 0000111111110000 */
3497 
wifi_wmm_init()3498 void wifi_wmm_init()
3499 {
3500     mlan_private *pmpriv    = (mlan_private *)mlan_adap->priv[0];
3501     mlan_adapter *pmadapter = pmpriv->adapter;
3502     mlan_status status      = MLAN_STATUS_SUCCESS;
3503 
3504     status =
3505         wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_PARAM_CONFIG, HostCmd_ACT_GEN_SET, 0, MNULL, &pmadapter->ac_params);
3506     if (status != MLAN_STATUS_SUCCESS)
3507     {
3508         wifi_e("ERR: WMM wlan_prepare_cmd returned status=0x%x", status);
3509     }
3510 }
3511 
3512 /* Packet priority is 16th byte of payload.
3513  * Provided that the packet is IPV4 type
3514  * Since value comes between the range of 0-255, coversion is expected between 0-7 to map to TIDs.
3515  * */
wifi_wmm_get_pkt_prio(void * buf,t_u8 * tid)3516 t_u32 wifi_wmm_get_pkt_prio(void *buf, t_u8 *tid)
3517 {
3518     bool ip_hdr = 0;
3519 
3520     if (buf == NULL)
3521         return -WM_FAIL;
3522     t_u8 *type_01 = net_stack_buffer_skip(buf, ETHER_TYPE_IP_01);
3523     t_u8 *type_02 = net_stack_buffer_skip(buf, ETHER_TYPE_IP_02);
3524     if (*type_01 == ETHER_TYPE_IPV4_VALUE_01 && *type_02 == ETHER_TYPE_IPV4_VALUE_02)
3525     {
3526         t_u8 *id = net_stack_buffer_skip(buf, WMM_PACKET_TOS_IV4);
3527         *tid     = *id / PRIORITY_COMPENSATOR;
3528         ip_hdr   = 1;
3529     }
3530     else if (*type_01 == ETHER_TYPE_IPV6_VALUE_01 && *type_02 == ETHER_TYPE_IPV6_VALUE_02)
3531     {
3532         t_u8 *tos1     = net_stack_buffer_skip(buf, WMM_PACKET_TOS_IPV6_01);
3533         t_u8 *tos2     = net_stack_buffer_skip(buf, WMM_PACKET_TOS_IPV6_02);
3534         t_u16 ipv6_tos = (*tos1 << 8) | (*tos2);
3535         *tid           = (t_u8)(((ipv6_tos & TOS_MASK_IPV6) >> 4) / PRIORITY_COMPENSATOR);
3536         ip_hdr         = 1;
3537     }
3538     if (ip_hdr)
3539     {
3540         switch (*tid)
3541         {
3542             case 0:
3543                 return WMM_AC_BE;
3544             case 1:
3545             case 2:
3546                 return WMM_AC_BK;
3547             case 3:
3548                 return WMM_AC_BE;
3549             case 4:
3550             case 5:
3551                 return WMM_AC_VI;
3552             case 6:
3553             case 7:
3554                 return WMM_AC_VO;
3555             default:
3556                 return WMM_AC_BE;
3557         }
3558     }
3559     else
3560         return WMM_AC_BE;
3561 }
3562 
wifi_wmm_get_packet_cnt(void)3563 INLINE t_u8 wifi_wmm_get_packet_cnt(void)
3564 {
3565     return (MAX_WMM_BUF_NUM - mlan_adap->outbuf_pool.free_cnt);
3566 }
3567 
3568 #if CONFIG_WIFI_TP_STAT
3569 t_u32 g_wifi_xmit_schedule_end = 0;
3570 #endif
3571 
3572 #if CONFIG_AMSDU_IN_AMPDU
3573 /* aggregate one amsdu packet and xmit */
wifi_xmit_amsdu_pkts(mlan_private * priv,t_u8 ac,raListTbl * ralist)3574 static mlan_status wifi_xmit_amsdu_pkts(mlan_private *priv, t_u8 ac, raListTbl *ralist)
3575 {
3576     outbuf_t *buf                = MNULL;
3577     t_u32 max_amsdu_size         = MIN(priv->max_amsdu, priv->adapter->tx_buffer_size);
3578     t_u32 amsdu_offset           = sizeof(TxPD) + INTF_HEADER_LEN;
3579     t_u8 amsdu_cnt               = 0;
3580     t_u32 amsdu_buf_used_size    = 0;
3581     int amsdu_buf_available_size = max_amsdu_size - amsdu_buf_used_size;
3582     t_u32 amsdu_pkt_len          = 0;
3583     int pad_len                  = 0;
3584     int last_pad_len             = 0;
3585 #if CONFIG_WIFI_TP_STAT
3586     t_u8 *buf_end = MNULL;
3587 #endif
3588 
3589     while (ralist->total_pkts > 0)
3590     {
3591         mlan_adap->callbacks.moal_semaphore_get(mlan_adap->pmoal_handle, &ralist->buf_head.plock);
3592         buf = (outbuf_t *)util_peek_list(mlan_adap->pmoal_handle, &ralist->buf_head, MNULL, MNULL);
3593         ASSERT(buf != NULL);
3594 
3595 #if CONFIG_WIFI_TP_STAT
3596         buf_end = &buf->data[0] + buf->tx_pd.tx_pkt_length;
3597         wifi_stat_tx_dequeue_start(buf_end, g_wifi_xmit_schedule_end);
3598 #endif
3599 
3600         /* calculate amsdu buffer length */
3601         amsdu_buf_used_size += buf->tx_pd.tx_pkt_length + sizeof(TxPD) + INTF_HEADER_LEN;
3602         if (amsdu_cnt == 0)
3603         {
3604             /* First A-MSDU packet */
3605             amsdu_buf_available_size = max_amsdu_size - amsdu_buf_used_size - LLC_SNAP_LEN;
3606         }
3607         else
3608         {
3609             /* The following A-MSDU packets */
3610             amsdu_pkt_len            = amsdu_buf_used_size - sizeof(TxPD) - INTF_HEADER_LEN + LLC_SNAP_LEN;
3611             pad_len                  = ((amsdu_pkt_len & 3)) ? (4 - ((amsdu_pkt_len)&3)) : 0;
3612             amsdu_buf_available_size = max_amsdu_size - amsdu_pkt_len - pad_len;
3613         }
3614 
3615         /* dequeue and store this buffer in amsdu buffer */
3616         if (amsdu_buf_available_size >= 0)
3617         {
3618             util_unlink_list(mlan_adap->pmoal_handle, &ralist->buf_head, &buf->entry, MNULL, MNULL);
3619             ralist->total_pkts--;
3620             mlan_adap->callbacks.moal_semaphore_put(mlan_adap->pmoal_handle, &ralist->buf_head.plock);
3621 
3622             amsdu_offset += wlan_11n_form_amsdu_pkt(wifi_get_amsdu_outbuf(amsdu_offset), &buf->data[0],
3623                                                     buf->tx_pd.tx_pkt_length, &last_pad_len);
3624             amsdu_cnt++;
3625 
3626 #if CONFIG_WIFI_TP_STAT
3627             wifi_stat_tx_dequeue_end(buf_end);
3628 #endif
3629             wifi_wmm_buf_put(buf);
3630             priv->wmm.pkts_queued[ac]--;
3631         }
3632         else
3633         {
3634             mlan_adap->callbacks.moal_semaphore_put(mlan_adap->pmoal_handle, &ralist->buf_head.plock);
3635         }
3636 
3637         /*
3638          * amsdu buffer room not enough, or last packet in this ra_list in AC queue,
3639          * add amsdu buffer to imu queue
3640          */
3641         if (amsdu_buf_available_size < 0 || ralist->total_pkts == 0)
3642         {
3643             return wlan_xmit_wmm_amsdu_pkt((mlan_wmm_ac_e)ac, priv->bss_index, amsdu_offset - last_pad_len,
3644                                            wifi_get_amsdu_outbuf(0), amsdu_cnt);
3645         }
3646     }
3647     return MLAN_STATUS_SUCCESS;
3648 }
3649 #endif
3650 
wifi_txbuf_available()3651 t_u8 wifi_txbuf_available()
3652 {
3653 #ifdef RW610
3654     return !(HAL_ImuIsTxBufQueueEmpty(kIMU_LinkCpu1Cpu3));
3655 #else
3656     return !!(mlan_adap->mp_wr_bitmap);
3657 #endif
3658 }
3659 
wifi_is_max_tx_cnt(t_u8 pkt_cnt)3660 static inline t_u8 wifi_is_max_tx_cnt(t_u8 pkt_cnt)
3661 {
3662 #ifdef RW610
3663     return (pkt_cnt >= IMU_PAYLOAD_SIZE) ? MTRUE : MFALSE;
3664 #else
3665     return (pkt_cnt >= SDIO_PAYLOAD_SIZE) ? MTRUE : MFALSE;
3666 #endif
3667 }
3668 
3669 /* dequeue and xmit one packet */
wifi_xmit_pkts(mlan_private * priv,t_u8 ac,raListTbl * ralist)3670 static mlan_status wifi_xmit_pkts(mlan_private *priv, t_u8 ac, raListTbl *ralist)
3671 {
3672     mlan_status ret;
3673     outbuf_t *buf = MNULL;
3674 
3675     mlan_adap->callbacks.moal_semaphore_get(mlan_adap->pmoal_handle, &ralist->buf_head.plock);
3676     buf = (outbuf_t *)util_dequeue_list(mlan_adap->pmoal_handle, &ralist->buf_head, MNULL, MNULL);
3677     ralist->total_pkts--;
3678     mlan_adap->callbacks.moal_semaphore_put(mlan_adap->pmoal_handle, &ralist->buf_head.plock);
3679     ASSERT(buf != MNULL);
3680 
3681     /* TODO: this may go wrong for TxPD->tx_pkt_type 0xe5 */
3682     /* this will get card port lock and probably sleep */
3683 #if CONFIG_TX_RX_ZERO_COPY
3684     ret = wlan_xmit_wmm_pkt(priv->bss_index, buf->tx_pd.tx_pkt_length + sizeof(TxPD) + INTF_HEADER_LEN, (t_u8 *)buf);
3685 #else
3686     ret = wlan_xmit_wmm_pkt(priv->bss_index, buf->tx_pd.tx_pkt_length + sizeof(TxPD) + INTF_HEADER_LEN,
3687                             (t_u8 *)&buf->intf_header[0]);
3688 #endif
3689     if (ret != MLAN_STATUS_SUCCESS)
3690     {
3691 #ifdef RW610
3692         ASSERT(0);
3693 #else
3694         mlan_adap->callbacks.moal_semaphore_get(mlan_adap->pmoal_handle, &ralist->buf_head.plock);
3695         util_enqueue_list_head(mlan_adap->pmoal_handle, &ralist->buf_head, &buf->entry, MNULL, MNULL);
3696         ralist->total_pkts++;
3697         mlan_adap->callbacks.moal_semaphore_put(mlan_adap->pmoal_handle, &ralist->buf_head.plock);
3698         return MLAN_STATUS_RESOURCE;
3699 #endif
3700     }
3701 
3702     wifi_wmm_buf_put(buf);
3703     priv->wmm.pkts_queued[ac]--;
3704 
3705     return MLAN_STATUS_SUCCESS;
3706 }
3707 
3708 /*
3709  *  xmit all buffers under this ralist
3710  *  should be called inside wmm tid_tbl_ptr ra_list lock,
3711  *  return MLAN_STATUS_SUCESS to continue looping ralists,
3712  *  return MLAN_STATUS_RESOURCE to break looping ralists
3713  */
wifi_xmit_ralist_pkts(mlan_private * priv,t_u8 ac,raListTbl * ralist,t_u8 * pkt_cnt)3714 static mlan_status wifi_xmit_ralist_pkts(mlan_private *priv, t_u8 ac, raListTbl *ralist, t_u8 *pkt_cnt)
3715 {
3716     mlan_status ret;
3717 
3718     if (ralist->tx_pause == MTRUE)
3719         return MLAN_STATUS_SUCCESS;
3720 
3721     while (ralist->total_pkts > 0)
3722     {
3723         if ((wifi_txbuf_available() == MFALSE) || (WIFI_DATA_RUNNING != wifi_tx_status))
3724             break;
3725 
3726 #if CONFIG_AMSDU_IN_AMPDU
3727         if (wlan_is_amsdu_allowed(priv, priv->bss_index, ralist->total_pkts, ac))
3728             ret = wifi_xmit_amsdu_pkts(priv, ac, ralist);
3729         else
3730 #endif
3731             ret = wifi_xmit_pkts(priv, ac, ralist);
3732 
3733         if (ret != MLAN_STATUS_SUCCESS)
3734             return ret;
3735 
3736         /*
3737          * in amsdu case,
3738          * multiple packets aggregated as one amsdu packet, are counted as one imu packet
3739          */
3740         (*pkt_cnt)++;
3741         if (wifi_is_max_tx_cnt(*pkt_cnt) == MTRUE)
3742         {
3743             wlan_flush_wmm_pkt(*pkt_cnt);
3744             *pkt_cnt = 0;
3745         }
3746     }
3747     return MLAN_STATUS_SUCCESS;
3748 }
3749 
3750 /*
3751  *  dequeue and xmit all buffers under ac queue
3752  *  loop each ac queue
3753  *  loop each ralist
3754  *  dequeue all buffers from buf_head list and xmit
3755  */
wifi_xmit_wmm_ac_pkts_enh(mlan_private * priv)3756 static int wifi_xmit_wmm_ac_pkts_enh(mlan_private *priv)
3757 {
3758     int ac;
3759     mlan_status ret;
3760     t_u8 pkt_cnt       = 0;
3761     raListTbl *ralist  = MNULL;
3762     tid_tbl_t *tid_ptr = MNULL;
3763 
3764 #if CONFIG_WIFI_TP_STAT
3765     g_wifi_xmit_schedule_end = OSA_GetTimestamp();
3766 #endif
3767 
3768     for (ac = WMM_AC_VO; ac >= 0; ac--)
3769     {
3770         tid_ptr = &priv->wmm.tid_tbl_ptr[ac];
3771 
3772         mlan_adap->callbacks.moal_semaphore_get(mlan_adap->pmoal_handle, &tid_ptr->ra_list.plock);
3773 
3774         if (priv->wmm.pkts_queued[ac] == 0)
3775         {
3776             mlan_adap->callbacks.moal_semaphore_put(mlan_adap->pmoal_handle, &tid_ptr->ra_list.plock);
3777             continue;
3778         }
3779 
3780         ralist =
3781             (raListTbl *)util_peek_list(mlan_adap->pmoal_handle, (mlan_list_head *)&tid_ptr->ra_list, MNULL, MNULL);
3782 
3783         while (ralist && ralist != (raListTbl *)&tid_ptr->ra_list)
3784         {
3785             ret = wifi_xmit_ralist_pkts(priv, ac, ralist, &pkt_cnt);
3786             if (ret != MLAN_STATUS_SUCCESS)
3787             {
3788                 mlan_adap->callbacks.moal_semaphore_put(mlan_adap->pmoal_handle, &tid_ptr->ra_list.plock);
3789                 goto RET;
3790             }
3791             ralist = ralist->pnext;
3792         }
3793         mlan_adap->callbacks.moal_semaphore_put(mlan_adap->pmoal_handle, &tid_ptr->ra_list.plock);
3794     }
3795 
3796 RET:
3797     wlan_flush_wmm_pkt(pkt_cnt);
3798     return WM_SUCCESS;
3799 }
3800 
wlan_process_bypass_txq(t_u8 interface)3801 t_void wlan_process_bypass_txq(t_u8 interface)
3802 {
3803     bypass_outbuf_t *buf;
3804     mlan_status status = MLAN_STATUS_SUCCESS;
3805     pmlan_private priv = mlan_adap->priv[interface];
3806 
3807     wifi_tx_card_awake_lock();
3808 #ifndef RW610
3809     wifi_sdio_lock();
3810 #endif
3811 
3812     while (!wlan_bypass_txq_empty(interface) && (wifi_txbuf_available() == MTRUE))
3813     {
3814         wlan_get_bypass_lock(interface);
3815         buf = (bypass_outbuf_t *)util_dequeue_list(mlan_adap->pmoal_handle, &priv->bypass_txq, MNULL, MNULL);
3816         priv->bypass_txq_cnt--;
3817         wlan_put_bypass_lock(interface);
3818 
3819         status = wlan_xmit_bypass_pkt((t_u8 *)&buf->intf_header[0],
3820                                       buf->tx_pd.tx_pkt_length + sizeof(TxPD) + INTF_HEADER_LEN, interface);
3821 
3822 #if !CONFIG_MEM_POOLS
3823         OSA_MemoryFree(buf);
3824 #else
3825         OSA_MemoryPoolFree(buf_1536_MemoryPool, buf);
3826 #endif
3827 
3828         if (status != MLAN_STATUS_SUCCESS)
3829         {
3830             wifi_d("[%s] bypass xmit pkt failed \r\n", __func__);
3831         }
3832     }
3833 
3834 #ifndef RW610
3835     wifi_sdio_unlock();
3836 #endif
3837     wifi_tx_card_awake_unlock();
3838 }
3839 
3840 typedef enum _wifi_tx_event
3841 {
3842     TX_TYPE_DATA = 10U,
3843     TX_TYPE_NULL_DATA,
3844     TX_TYPE_BYPASS_DATA,
3845 } wifi_tx_event_t;
3846 
notify_wifi_driver_tx_event(uint32_t events)3847 static void notify_wifi_driver_tx_event(uint32_t events)
3848 {
3849     struct bus_message msg;
3850     osa_status_t status;
3851 
3852     if (events & WIFI_EVENT_TX_DATA)
3853     {
3854         msg.event = MLAN_TYPE_DATA;
3855     }
3856     else if (events & WIFI_EVENT_TX_NULL_DATA)
3857     {
3858         msg.event = MLAN_TYPE_NULL_DATA;
3859     }
3860     else if (events & WIFI_EVENT_TX_BYPASS_DATA)
3861     {
3862         msg.event = MLAN_TYPE_BYPASS_DATA;
3863     }
3864     else
3865     {
3866         msg.event = MLAN_TYPE_DATA;
3867         wifi_w("unknown tx event");
3868     }
3869 
3870     msg.reason = (events & 1) ? MLAN_BSS_TYPE_STA : MLAN_BSS_TYPE_UAP;
3871 
3872     status = OSA_MsgQPut((osa_msgq_handle_t)wm_wifi.tx_data, &msg);
3873     if (status == KOSA_StatusSuccess)
3874     {
3875         if (msg.event == MLAN_TYPE_BYPASS_DATA && !OSA_IsISR())
3876         {
3877             OSA_TaskYield();
3878         }
3879     }
3880 }
3881 
send_wifi_driver_tx_data_event(t_u8 interface)3882 int send_wifi_driver_tx_data_event(t_u8 interface)
3883 {
3884     osa_event_flags_t events;
3885 
3886     events = (1U << interface) | WIFI_EVENT_TX_DATA;
3887 
3888     if(1 != wm_wifi.wifi_core_init_done)
3889         return 0;
3890 
3891     notify_wifi_driver_tx_event(events);
3892 
3893     return 0;
3894 }
3895 
send_wifi_driver_tx_null_data_event(t_u8 interface)3896 int send_wifi_driver_tx_null_data_event(t_u8 interface)
3897 {
3898     osa_event_flags_t events;
3899 
3900     events = (1U << interface) | WIFI_EVENT_TX_NULL_DATA;
3901 
3902     notify_wifi_driver_tx_event(events);
3903 
3904     return 0;
3905 }
3906 
send_wifi_driver_bypass_data_event(t_u8 interface)3907 int send_wifi_driver_bypass_data_event(t_u8 interface)
3908 {
3909     osa_event_flags_t events;
3910 
3911     events = (1U << interface) | WIFI_EVENT_TX_BYPASS_DATA;
3912 
3913     notify_wifi_driver_tx_event(events);
3914 
3915     return 0;
3916 }
3917 
wifi_drv_tx_task(osa_task_param_t arg)3918 static void wifi_drv_tx_task(osa_task_param_t arg)
3919 {
3920     mlan_private *pmpriv    = (mlan_private *)mlan_adap->priv[0];
3921     mlan_adapter *pmadapter = pmpriv->adapter;
3922     t_u8 i;
3923     t_u16 event    = 0;
3924     t_u8 interface = 0;
3925     struct bus_message msg;
3926     osa_status_t status;
3927 
3928     for (;;)
3929     {
3930         event     = 0;
3931         interface = 0;
3932 
3933 #if CONFIG_ECSA
3934         /*
3935          * Reduce block tx check interval, try to make it sync with ECSA status.
3936          */
3937         while (true == get_ecsa_block_tx_flag())
3938         {
3939             OSA_TimeDelay(wm_wifi.beacon_period);
3940         }
3941 #endif
3942         status = OSA_MsgQGet((osa_msgq_handle_t)wm_wifi.tx_data, &msg, osaWaitForever_c);
3943         if (status == KOSA_StatusSuccess)
3944         {
3945             event     = msg.event;
3946             interface = msg.reason;
3947         }
3948         pmadapter = mlan_adap;
3949 
3950 #if CONFIG_HOST_SLEEP
3951         wakelock_get();
3952 #endif
3953         if (event == MLAN_TYPE_DATA || event == MLAN_TYPE_NULL_DATA || event == MLAN_TYPE_BYPASS_DATA)
3954         {
3955 #if CONFIG_WMM_UAPSD
3956             while (pmadapter->pps_uapsd_mode && (pmadapter->tx_lock_flag == MTRUE))
3957             {
3958                 OSA_TimeDelay(1);
3959             }
3960 #endif
3961             for (i = 0; i < MLAN_MAX_BSS_NUM; i++)
3962             {
3963                 if (!wlan_bypass_txq_empty(i))
3964                 {
3965                     /*Give high priority to xmit bypass txqueue*/
3966                     wlan_process_bypass_txq(i);
3967                 }
3968             }
3969 
3970             /* Send packet when the outbuf pool is not empty and not in block tx status*/
3971             if ((wifi_wmm_get_packet_cnt() > 0) && (WIFI_DATA_RUNNING == wifi_tx_status))
3972             {
3973                 for (i = 0; i < MLAN_MAX_BSS_NUM; i++)
3974                 {
3975                     pmpriv = pmadapter->priv[i];
3976                     if (!pmpriv->media_connected || pmpriv->tx_pause)
3977                     {
3978                         continue;
3979                     }
3980 
3981                     wifi_tx_card_awake_lock();
3982 #ifndef RW610
3983                     wifi_sdio_lock();
3984 #endif
3985                     wifi_xmit_wmm_ac_pkts_enh(pmpriv);
3986 #ifndef RW610
3987                     wifi_sdio_unlock();
3988 #endif
3989                     wifi_tx_card_awake_unlock();
3990                 }
3991             }
3992 #if CONFIG_WMM_UAPSD
3993             else
3994             {
3995                 if (event == MLAN_TYPE_NULL_DATA)
3996                 {
3997                     wifi_tx_card_awake_lock();
3998                     /* send null packet until the finish of CMD response processing */
3999                     OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
4000                     pmpriv = pmadapter->priv[interface];
4001                     if (pmadapter->pps_uapsd_mode && pmpriv->media_connected && pmadapter->gen_null_pkt)
4002                     {
4003                         if (wlan_send_null_packet(
4004                                 pmpriv, MRVDRV_TxPD_POWER_MGMT_NULL_PACKET | MRVDRV_TxPD_POWER_MGMT_LAST_PACKET) ==
4005                             MLAN_STATUS_SUCCESS)
4006                         {
4007                             pmadapter->tx_lock_flag = MTRUE;
4008                         }
4009                         else
4010                         {
4011                             OSA_SemaphorePost((osa_semaphore_handle_t)uapsd_sem);
4012                             pmadapter->tx_lock_flag = MFALSE;
4013                         }
4014                     }
4015                     else
4016                     {
4017                         wifi_d(
4018                             "No need to send null packet, pps_uapsd_mode: %d, media_connected: %d, gen_null_pkt: "
4019                             "%d",
4020                             pmadapter->pps_uapsd_mode, pmpriv->media_connected, pmadapter->gen_null_pkt);
4021                         OSA_SemaphorePost((osa_semaphore_handle_t)uapsd_sem);
4022                         pmadapter->tx_lock_flag = MFALSE;
4023                     }
4024                     wifi_tx_card_awake_unlock();
4025                 }
4026             }
4027 #endif
4028         }
4029 #if CONFIG_HOST_SLEEP
4030         wakelock_put();
4031 #endif
4032     }
4033 }
4034 #endif /* CONFIG_WMM */
4035 
4036 #if CONFIG_11AX
4037 #if CONFIG_TCP_ACK_ENH
4038 #define ETH_PROTO_IP     0x0800U
4039 #define WIFI_IPPROTO_TCP 6
4040 
4041 #define RATEID_VHT_MCS7_1SS_BW80 58
4042 #define RATEID_VHT_MCS7_1SS_BW40 48
4043 #define RATEID_VHT_MCS7_1SS_BW20 38
4044 
4045 #define RATEID_VHT_MCS8_1SS_BW80 59
4046 #define RATEID_VHT_MCS8_1SS_BW40 49
4047 #define RATEID_VHT_MCS8_1SS_BW20 39
4048 
4049 #define RATEID_VHT_MCS9_1SS_BW80 60
4050 #define RATEID_VHT_MCS9_1SS_BW40 50
4051 #define RATEID_VHT_MCS9_1SS_BW20 40
4052 
4053 #define RATEID_HE_MCS9_1SS_BW80 94
4054 #define RATEID_HE_MCS8_1SS_BW40 81
4055 #define RATEID_HE_MCS7_1SS_BW20 68
4056 
wlan_is_tcp_ack(mlan_private * priv,const t_u8 * pmbuf)4057 static int wlan_is_tcp_ack(mlan_private *priv, const t_u8 *pmbuf)
4058 {
4059     eth_hdr *ethh = NULL;
4060     ip_hdr *iph   = NULL;
4061     tcp_hdr *tcph = NULL;
4062 
4063     ENTER();
4064 
4065     /** check the tcp packet */
4066 #if CONFIG_TX_RX_ZERO_COPY
4067     ethh = (eth_hdr *)(((outbuf_t *)pmbuf)->eth_header);
4068 #else
4069     ethh = (eth_hdr *)(pmbuf);
4070 #endif
4071     if (mlan_ntohs(ethh->h_proto) != ETH_PROTO_IP)
4072     {
4073         LEAVE();
4074         return 0;
4075     }
4076 #if CONFIG_TX_RX_ZERO_COPY
4077     iph = (ip_hdr *)(((outbuf_t *)pmbuf)->payload);
4078     if (iph == NULL)
4079     {
4080         return 0;
4081     }
4082 #else
4083     iph  = (ip_hdr *)((t_u8 *)ethh + sizeof(eth_hdr));
4084 #endif
4085     if (iph->protocol != WIFI_IPPROTO_TCP)
4086     {
4087         LEAVE();
4088         return 0;
4089     }
4090 #if CONFIG_TX_RX_ZERO_COPY
4091     tcph = (tcp_hdr *)(net_stack_buffer_skip(((outbuf_t *)pmbuf)->buffer, (uint16_t)(iph->ihl * 4)));
4092 #else
4093     tcph = (tcp_hdr *)((t_u8 *)iph + iph->ihl * 4);
4094 #endif
4095 
4096     if (*((t_u8 *)tcph + 13) == 0x10)
4097     {
4098         /* Only replace ACK */
4099         if (mlan_ntohs(iph->tot_len) > (iph->ihl + tcph->_hdrlen_rsvd_flags.doff) * 4)
4100         {
4101             /* Don't drop ACK with payload */
4102             /* TODO: should we delete previous TCP session */
4103             LEAVE();
4104             return 0;
4105         }
4106         return 1;
4107     }
4108 
4109     LEAVE();
4110     return 0;
4111 }
4112 #endif /** CONFIG_TCP_ACK_ENH */
4113 #endif /** CONFIG_11AX*/
4114 
4115 #if CONFIG_WMM
4116 
wifi_add_to_bypassq(const t_u8 interface,void * pkt,t_u32 len)4117 int wifi_add_to_bypassq(const t_u8 interface, void *pkt, t_u32 len)
4118 {
4119     t_u32 pkt_len            = 0;
4120     t_u32 link_point_len     = 0;
4121     bypass_outbuf_t *poutbuf = NULL;
4122     t_u16 eth_type           = 0;
4123     t_u32 magic_cookie       = 0;
4124 
4125     eth_type = mlan_ntohs(*(t_u16 *)(net_stack_buffer_skip(pkt, MLAN_ETHER_PKT_TYPE_OFFSET)));
4126 
4127     if (len > MLAN_ETHER_PKT_DHCP_MAGIC_COOKIE_OFFSET)
4128     {
4129         magic_cookie = mlan_ntohl(*((t_u32 *)(net_stack_buffer_skip(pkt, MLAN_ETHER_PKT_DHCP_MAGIC_COOKIE_OFFSET))));
4130     }
4131 
4132     if ((eth_type == MLAN_ETHER_PKT_TYPE_EAPOL) || (eth_type == MLAN_ETHER_PKT_TYPE_ARP) ||
4133         (magic_cookie == MLAN_ETHER_PKT_DHCP_MAGIC_COOKIE))
4134     {
4135         /*Dword align*/
4136         pkt_len        = sizeof(TxPD) + INTF_HEADER_LEN;
4137         link_point_len = sizeof(mlan_linked_list);
4138 
4139 #if !CONFIG_MEM_POOLS
4140         poutbuf = OSA_MemoryAllocate(link_point_len + pkt_len + len);
4141 #else
4142         poutbuf = (bypass_outbuf_t *)OSA_MemoryPoolAllocate(buf_1536_MemoryPool);
4143 #endif
4144         if (!poutbuf)
4145         {
4146             wuap_e("[%s] ERR:Cannot allocate buffer!\r\n", __func__);
4147             return -WM_FAIL;
4148         }
4149 
4150         (void)memset((t_u8 *)poutbuf, 0, link_point_len + pkt_len);
4151 
4152         (void)net_stack_buffer_copy_partial(pkt, (void *)((t_u8 *)poutbuf + link_point_len + pkt_len), (t_u16)len, 0);
4153 
4154         /* process packet headers with interface header and TxPD */
4155         process_pkt_hdrs((void *)((t_u8 *)poutbuf + link_point_len), pkt_len + len, interface, 0, 0);
4156 
4157         wlan_add_buf_bypass_txq((t_u8 *)poutbuf, interface);
4158         send_wifi_driver_bypass_data_event(interface);
4159 
4160         return WM_SUCCESS;
4161     }
4162 
4163     return -WM_FAIL;
4164 }
4165 #endif
4166 
wifi_low_level_output(const t_u8 interface,const t_u8 * sd_buffer,const t_u16 len,t_u8 pkt_prio,t_u8 tid)4167 int wifi_low_level_output(const t_u8 interface,
4168                           const t_u8 *sd_buffer,
4169                           const t_u16 len
4170 #if CONFIG_WMM
4171                           ,
4172                           t_u8 pkt_prio,
4173                           t_u8 tid
4174 #endif
4175 )
4176 {
4177     int ret;
4178 #if CONFIG_TX_RX_ZERO_COPY
4179     const t_u8 *buffer = ((outbuf_t *)sd_buffer)->eth_header;
4180 #else
4181     const t_u8 *buffer = sd_buffer +
4182 #if CONFIG_WMM
4183                          sizeof(mlan_linked_list) +
4184 #endif
4185                          sizeof(TxPD) + INTF_HEADER_LEN;
4186 #endif
4187 #if !CONFIG_WMM
4188     int retry = retry_attempts;
4189     mlan_status i;
4190 #endif
4191 
4192     /** Tx control */
4193     t_u32 tx_control = 0;
4194     mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[interface];
4195 
4196     w_pkt_d("Data TX: Kernel=>Driver, if %d, len %d", interface, len);
4197 
4198     // wakelock_get(WL_ID_LL_OUTPUT);
4199     /* Following condition is added to check if device is not connected and data packet is being transmitted */
4200     if ((pmpriv->media_connected == MFALSE))
4201     {
4202 #if CONFIG_WMM
4203         wifi_wmm_buf_put((outbuf_t *)sd_buffer);
4204         wifi_wmm_drop_no_media(interface);
4205 #endif
4206         return WM_SUCCESS;
4207     }
4208 
4209 #if CONFIG_11AX
4210 #if CONFIG_TCP_ACK_ENH
4211     if ((interface == MLAN_BSS_TYPE_STA) && (pmpriv->enable_tcp_ack_enh == MTRUE) &&
4212         (pmpriv->curr_bss_params.bss_descriptor.phe_cap != NULL))
4213     {
4214 #if CONFIG_TX_RX_ZERO_COPY
4215         ret = wlan_is_tcp_ack(pmpriv, sd_buffer);
4216 #else
4217         ret = wlan_is_tcp_ack(pmpriv, buffer);
4218 #endif
4219         if (ret)
4220         {
4221             if (pmpriv->curr_bss_params.bss_descriptor.curr_bandwidth == BW_80MHZ)
4222             {
4223                 if (pmpriv->curr_bss_params.bss_descriptor.phe_cap != NULL)
4224                 {
4225                     tx_control = (RATEID_HE_MCS9_1SS_BW80 << 16) | TXPD_TXRATE_ENABLE;
4226                 }
4227                 else if (pmpriv->curr_bss_params.bss_descriptor.pvht_cap != NULL)
4228                 {
4229                     tx_control = (RATEID_VHT_MCS9_1SS_BW80 << 16) | TXPD_TXRATE_ENABLE;
4230                 }
4231 #if CONFIG_WMM
4232                 /* Though TID is not used in case of TCP traffic,
4233                  * but making tid as voice traffic is a way to tell firmware to not to use
4234                  * MCS rates above 9 for TCP ack packets.
4235                  * This introduction is harmless for TCP traffic as TID is dont care
4236                  * */
4237                 tid = WMM_HIGHEST_PRIORITY - 1;
4238 #endif
4239             }
4240             else if (pmpriv->curr_bss_params.bss_descriptor.curr_bandwidth == BW_40MHZ)
4241             {
4242                 if (pmpriv->curr_bss_params.bss_descriptor.phe_cap != NULL)
4243                 {
4244                     tx_control = (RATEID_HE_MCS8_1SS_BW40 << 16) | TXPD_TXRATE_ENABLE;
4245                 }
4246                 else if (pmpriv->curr_bss_params.bss_descriptor.pvht_cap != NULL)
4247                 {
4248                     tx_control = (RATEID_VHT_MCS8_1SS_BW40 << 16) | TXPD_TXRATE_ENABLE;
4249                 }
4250 #if CONFIG_WMM
4251                 /* Though TID is not used in case of TCP traffic,
4252                  * but making tid as voice traffic is a way to tell firmware to not to use
4253                  * MCS rates above 9 for TCP ack packets.
4254                  * This introduction is harmless for TCP traffic as TID is dont care
4255                  * */
4256                 tid = WMM_HIGHEST_PRIORITY - 1;
4257 #endif
4258             }
4259             else if (pmpriv->curr_bss_params.bss_descriptor.curr_bandwidth == BW_20MHZ)
4260             {
4261                 if (pmpriv->curr_bss_params.bss_descriptor.phe_cap != NULL)
4262                 {
4263                     tx_control = (RATEID_HE_MCS7_1SS_BW20 << 16) | TXPD_TXRATE_ENABLE;
4264                 }
4265                 else if (pmpriv->curr_bss_params.bss_descriptor.pvht_cap != NULL)
4266                 {
4267                     tx_control = (RATEID_VHT_MCS7_1SS_BW20 << 16) | TXPD_TXRATE_ENABLE;
4268                 }
4269             }
4270         }
4271     }
4272     else if (interface == MLAN_BSS_TYPE_UAP)
4273     {
4274         ret = wlan_is_tcp_ack(pmpriv, buffer);
4275         if (ret)
4276         {
4277             if (wm_wifi.bandwidth == BANDWIDTH_80MHZ)
4278             {
4279                 if (mlan_adap->usr_dot_11ax_enable == MTRUE)
4280                 {
4281                     tx_control = (RATEID_HE_MCS9_1SS_BW80 << 16) | TXPD_TXRATE_ENABLE;
4282                 }
4283                 else if (mlan_adap->usr_dot_11ac_enable == MTRUE)
4284                 {
4285                     tx_control = (RATEID_VHT_MCS9_1SS_BW80 << 16) | TXPD_TXRATE_ENABLE;
4286                 }
4287             }
4288             else if (wm_wifi.bandwidth == BANDWIDTH_40MHZ)
4289             {
4290                 if (mlan_adap->usr_dot_11ax_enable == MTRUE)
4291                 {
4292                     tx_control = (RATEID_HE_MCS8_1SS_BW40 << 16) | TXPD_TXRATE_ENABLE;
4293                 }
4294                 else if (mlan_adap->usr_dot_11ac_enable == MTRUE)
4295                 {
4296                     tx_control = (RATEID_VHT_MCS8_1SS_BW40 << 16) | TXPD_TXRATE_ENABLE;
4297                 }
4298             }
4299             else if (wm_wifi.bandwidth == BANDWIDTH_20MHZ)
4300             {
4301                 if (mlan_adap->usr_dot_11ax_enable == MTRUE)
4302                 {
4303                     tx_control = (RATEID_HE_MCS7_1SS_BW20 << 16) | TXPD_TXRATE_ENABLE;
4304                 }
4305                 else if (mlan_adap->usr_dot_11ac_enable == MTRUE)
4306                 {
4307                     tx_control = (RATEID_VHT_MCS7_1SS_BW20 << 16) | TXPD_TXRATE_ENABLE;
4308                 }
4309             }
4310         }
4311     }
4312 #endif /** CONFIG_TCP_ACK_ENH */
4313 #endif /** CONFIG_11AX */
4314 
4315 #if CONFIG_WMM
4316     /* process packet headers with interface header and TxPD */
4317     process_pkt_hdrs((void *)(sd_buffer + sizeof(mlan_linked_list)), len - sizeof(mlan_linked_list), interface, tid,
4318                      tx_control);
4319 
4320     /* add buffer to ra lists */
4321     if (wlan_wmm_add_buf_txqueue_enh(interface, sd_buffer, len, pkt_prio) != MLAN_STATUS_SUCCESS)
4322     {
4323         wifi_wmm_drop_no_media(interface);
4324         ret = -WM_E_BUSY;
4325         goto exit_fn;
4326     }
4327 
4328     send_wifi_driver_tx_data_event(interface);
4329 #else
4330     wifi_tx_card_awake_lock();
4331 #if defined(RW610)
4332     wifi_imu_lock();
4333 #else
4334     (void)wifi_sdio_lock();
4335 #endif
4336 
4337     while (true)
4338     {
4339         i = wlan_xmit_pkt((t_u8 *)sd_buffer, len, interface, tx_control);
4340 #if defined(RW610)
4341         wifi_imu_unlock();
4342 #else
4343         wifi_sdio_unlock();
4344 #endif
4345         if (i == MLAN_STATUS_SUCCESS)
4346         {
4347             break;
4348         }
4349         else
4350         {
4351             if (i == MLAN_STATUS_FAILURE)
4352             {
4353                 ret = -WM_E_NOMEM;
4354                 goto exit_fn;
4355             }
4356             else if (i == MLAN_STATUS_RESOURCE)
4357             {
4358                 if (retry == 0)
4359                 {
4360                     ret = -WM_E_BUSY;
4361                     goto exit_fn;
4362                 }
4363                 else
4364                 {
4365                     retry--;
4366                     /* Allow the other thread to run and hence
4367                      * update the write bitmap so that pkt
4368                      * can be sent to FW */
4369                     OSA_TimeDelay(1);
4370 #if defined(RW610)
4371                     wifi_imu_lock();
4372 #else
4373                     (void)wifi_sdio_lock();
4374 #endif
4375                     continue;
4376                 }
4377             }
4378             else
4379             { /* Do Nothing */
4380             }
4381             break;
4382         } /* if (i != MLAN_STATUS_SUCCESS) */
4383     }     /* while(true) */
4384 
4385     wifi_tx_card_awake_unlock();
4386 #endif
4387 
4388 #if CONFIG_STA_AMPDU_TX
4389     if (interface == BSS_TYPE_STA && sta_ampdu_tx_enable
4390 #if CONFIG_WMM
4391         && wifi_sta_ampdu_tx_enable_per_tid_is_allowed(tid)
4392 #endif
4393     )
4394     {
4395         if (wm_wifi.wrapper_net_is_ip_or_ipv6_callback(buffer))
4396         {
4397             (void)wrapper_wlan_sta_ampdu_enable(
4398 #if CONFIG_WMM
4399                 tid
4400 #endif
4401             );
4402         }
4403     }
4404 #endif
4405 
4406 #if CONFIG_UAP_AMPDU_TX
4407     if (interface == BSS_TYPE_UAP && uap_ampdu_tx_enable
4408 #if CONFIG_WMM
4409         && wifi_uap_ampdu_tx_enable_per_tid_is_allowed(tid)
4410 #endif
4411     )
4412     {
4413         if (wm_wifi.wrapper_net_is_ip_or_ipv6_callback(buffer))
4414         {
4415             (void)wrapper_wlan_uap_ampdu_enable((uint8_t *)buffer
4416 #if CONFIG_WMM
4417                                                 ,
4418                                                 tid
4419 #endif
4420             );
4421         }
4422     }
4423 #endif
4424 
4425     ret = WM_SUCCESS;
4426 
4427 exit_fn:
4428 
4429 #if !CONFIG_WMM
4430     if (ret != WM_SUCCESS)
4431     {
4432         wifi_tx_card_awake_unlock();
4433     }
4434 #endif
4435 
4436     wifi_set_xfer_pending(false);
4437     // wakelock_put(WL_ID_LL_OUTPUT);
4438 
4439     return ret;
4440 }
4441 
wifi_get_outbuf(uint32_t * outbuf_len)4442 uint8_t *wifi_get_outbuf(uint32_t *outbuf_len)
4443 {
4444 #if defined(RW610)
4445     return wifi_get_imu_outbuf(outbuf_len);
4446 #else
4447     return wifi_get_sdio_outbuf(outbuf_len);
4448 #endif
4449 }
4450 
4451 #if CONFIG_HEAP_DEBUG
get_os_mem_stat_index(char const * func,t_u32 * index)4452 static bool get_os_mem_stat_index(char const *func, t_u32 *index)
4453 {
4454     int i     = 0;
4455     t_u32 len = strlen(func);
4456 
4457     len = (len > MAX_FUNC_SYMBOL_LEN - 1) ? (MAX_FUNC_SYMBOL_LEN - 1) : len;
4458 
4459     for (i = 0; i < valid_item_cnt; i++)
4460     {
4461         if (!strncmp(wifi_os_mem_stat[i].name, func, len))
4462         {
4463             // Find matched item
4464             *index = i;
4465             return true;
4466         }
4467     }
4468 
4469     if (valid_item_cnt >= OS_MEM_STAT_TABLE_SIZE)
4470     {
4471         (void)PRINTF("os_mem_stat table full\r\n");
4472         *index = OS_MEM_STAT_TABLE_SIZE - 1;
4473     }
4474     else
4475     {
4476         // Add a new item, increase valid_item_cnt
4477         *index = valid_item_cnt;
4478         valid_item_cnt++;
4479     }
4480 
4481     return false;
4482 }
4483 
record_os_mem_item(t_u32 size,char const * func,t_u32 line_num,bool is_alloc)4484 static int record_os_mem_item(t_u32 size, char const *func, t_u32 line_num, bool is_alloc)
4485 {
4486     t_u32 index = 0;
4487     t_u32 len   = strlen(func);
4488 
4489     len = (len > MAX_FUNC_SYMBOL_LEN - 1) ? (MAX_FUNC_SYMBOL_LEN - 1) : len;
4490 
4491     // If don't get matched item, record stat in new item; else just increase alloc_cnt or free_cnt.
4492     if (false == get_os_mem_stat_index(func, &index))
4493     {
4494         wifi_os_mem_stat[index].line_num = line_num;
4495 
4496         if (true == is_alloc)
4497         {
4498             wifi_os_mem_stat[index].size = size;
4499         }
4500 
4501         memcpy(wifi_os_mem_stat[index].name, func, len);
4502     }
4503 
4504     return index;
4505 }
4506 
record_os_mem_alloc(t_u32 size,char const * func,t_u32 line_num)4507 void record_os_mem_alloc(t_u32 size, char const *func, t_u32 line_num)
4508 {
4509     int index     = 0;
4510     bool is_alloc = true;
4511 
4512     OSA_SemaphoreWait((osa_semaphore_handle_t)os_mem_stat_sem, osaWaitForever_c);
4513     index = record_os_mem_item(size, func, line_num, is_alloc);
4514     wifi_os_mem_stat[index].alloc_cnt++;
4515     OSA_SemaphorePost((osa_semaphore_handle_t)os_mem_stat_sem);
4516 }
4517 
record_os_mem_free(char const * func,t_u32 line_num)4518 void record_os_mem_free(char const *func, t_u32 line_num)
4519 {
4520     int index     = 0;
4521     t_u32 size    = 0;
4522     bool is_alloc = false;
4523 
4524     OSA_SemaphoreWait((osa_semaphore_handle_t)os_mem_stat_sem, osaWaitForever_c);
4525     index = record_os_mem_item(size, func, line_num, is_alloc);
4526     wifi_os_mem_stat[index].free_cnt++;
4527     OSA_SemaphorePost((osa_semaphore_handle_t)os_mem_stat_sem);
4528 }
4529 
wifi_show_os_mem_stat()4530 void wifi_show_os_mem_stat()
4531 {
4532     int index = 0;
4533 
4534     (void)PRINTF("os_mem_alloc_stat: \r\n");
4535     (void)PRINTF(
4536         "Func name                                                         line_num    size        alloc_cnt    "
4537         "free_cnt\r\n");
4538 
4539     for (index = 0; index < valid_item_cnt; index++)
4540     {
4541         (void)PRINTF("%-64s  %-10d  %-10d  %-10d   %-10d \r\n", wifi_os_mem_stat[index].name,
4542                      wifi_os_mem_stat[index].line_num, wifi_os_mem_stat[index].size, wifi_os_mem_stat[index].alloc_cnt,
4543                      wifi_os_mem_stat[index].free_cnt);
4544     }
4545 }
4546 #endif
4547 
4548 /**
4549  * Frame Tx - Injecting Wireless frames from Host
4550  *
4551  * This function is used to Inject Wireless frames from application
4552  * directly.
4553  *
4554  * \param[in] interface Interface on which frame to be injected.
4555  * \param[in] buf Buffer holding 802.11 Wireless frame (Header + Data).
4556  * \param[in] len Length of the 802.11 Wireless frame.
4557  *
4558  * \return WM_SUCCESS on success or error code.
4559  *
4560  */
raw_low_level_output(const t_u8 interface,const t_u8 * buf,t_u32 len)4561 static int raw_low_level_output(const t_u8 interface, const t_u8 *buf, t_u32 len)
4562 {
4563     mlan_private *pmpriv = NULL;
4564 #if (CONFIG_WMM)
4565     t_u32 pkt_len            = 0;
4566     t_u32 link_point_len     = 0;
4567     bypass_outbuf_t *poutbuf = NULL;
4568 
4569     /*Dword align*/
4570     pkt_len        = sizeof(TxPD) + INTF_HEADER_LEN - 2;
4571     link_point_len = sizeof(mlan_linked_list);
4572 
4573 #if !CONFIG_MEM_POOLS
4574     poutbuf = OSA_MemoryAllocate(link_point_len + pkt_len + len);
4575 #else
4576     poutbuf = (bypass_outbuf_t *)OSA_MemoryPoolAllocate(buf_1536_MemoryPool);
4577 #endif
4578     if (interface == (t_u8)WLAN_BSS_TYPE_STA)
4579         pmpriv = (mlan_private *)mlan_adap->priv[0];
4580     if (!poutbuf)
4581     {
4582         wuap_e("[%s] ERR:Cannot allocate buffer!\r\n", __func__);
4583         return -WM_FAIL;
4584     }
4585 
4586     (void)memset((t_u8 *)poutbuf, 0, link_point_len + pkt_len);
4587 
4588     (void)raw_process_pkt_hdrs((t_u8 *)poutbuf + link_point_len, pkt_len + len, interface);
4589     (void)memcpy((void *)((t_u8 *)poutbuf + link_point_len + pkt_len), (const void *)buf, (size_t)len);
4590     /* process packet headers with interface header and TxPD */
4591     if (interface == (t_u8)WLAN_BSS_TYPE_STA)
4592         process_pkt_hdrs((void *)((t_u8 *)poutbuf + link_point_len), pkt_len + len, interface, 0, pmpriv->pkt_tx_ctrl);
4593     else
4594         process_pkt_hdrs((void *)((t_u8 *)poutbuf + link_point_len), pkt_len + len, interface, 0, 0);
4595 
4596     wlan_add_buf_bypass_txq((t_u8 *)poutbuf, interface);
4597     send_wifi_driver_bypass_data_event(interface);
4598 
4599     return WM_SUCCESS;
4600 #else
4601     mlan_status i;
4602     t_u32 pkt_len       = 0;
4603     uint32_t outbuf_len = 0;
4604     uint8_t *poutbuf    = wifi_get_outbuf(&outbuf_len);
4605 
4606     pkt_len = sizeof(TxPD) + INTF_HEADER_LEN;
4607 
4608     if (interface == (t_u8)WLAN_BSS_TYPE_STA)
4609         pmpriv = (mlan_private *)mlan_adap->priv[0];
4610     wifi_tx_card_awake_lock();
4611 #if defined(RW610)
4612     wifi_imu_lock();
4613 #else
4614     (void)wifi_sdio_lock();
4615 #endif
4616 
4617     (void)memset(poutbuf, 0, pkt_len);
4618 
4619     (void)raw_process_pkt_hdrs((t_u8 *)poutbuf, pkt_len + len - 2U, interface);
4620     (void)memcpy((void *)((t_u8 *)poutbuf + pkt_len - 2), (const void *)buf, (size_t)len);
4621     if (interface == (t_u8)WLAN_BSS_TYPE_STA)
4622         i = wlan_xmit_pkt(poutbuf, pkt_len + len - 2U, interface, pmpriv->pkt_tx_ctrl);
4623     else
4624         i = wlan_xmit_pkt(poutbuf, pkt_len + len - 2U, interface, 0);
4625 
4626 #if defined(RW610)
4627     wifi_imu_unlock();
4628 #else
4629     wifi_sdio_unlock();
4630 #endif
4631     wifi_tx_card_awake_unlock();
4632 
4633     if (i == MLAN_STATUS_FAILURE)
4634     {
4635         return (int)-WM_FAIL;
4636     }
4637 
4638     wifi_set_xfer_pending(false);
4639     return WM_SUCCESS;
4640 
4641 #endif
4642 }
4643 
wifi_inject_frame(const enum wlan_bss_type bss_type,const uint8_t * buff,const size_t len)4644 int wifi_inject_frame(const enum wlan_bss_type bss_type, const uint8_t *buff, const size_t len)
4645 {
4646     return raw_low_level_output((t_u8)bss_type, buff, len);
4647 }
4648 
4649 #if CONFIG_WPS2
wps_low_level_output(const uint8_t interface,const uint8_t * buf,const uint16_t len)4650 int wps_low_level_output(const uint8_t interface, const uint8_t *buf, const uint16_t len)
4651 {
4652     mlan_status i;
4653     t_u32 pkt_len;
4654     uint32_t outbuf_len = 0;
4655 
4656     uint8_t *outbuf = wifi_get_outbuf(&outbuf_len);
4657     if (!outbuf)
4658         return (int)-WM_FAIL;
4659 
4660     pkt_len = sizeof(TxPD) + INTF_HEADER_LEN;
4661     if ((pkt_len + len) > outbuf_len)
4662     {
4663         return (int)-WM_FAIL;
4664     }
4665 
4666     wifi_tx_card_awake_lock();
4667 #if defined(RW610)
4668     wifi_imu_lock();
4669 #else
4670     wifi_sdio_lock();
4671 #endif
4672 
4673     (void)memset(outbuf, 0x00, pkt_len);
4674 
4675     (void)memcpy((t_u8 *)outbuf + pkt_len, buf, len);
4676 
4677     i = wlan_xmit_pkt(outbuf, pkt_len + len, interface, 0);
4678 
4679 #if defined(RW610)
4680     wifi_imu_unlock();
4681 #else
4682     wifi_sdio_unlock();
4683 #endif
4684     wifi_tx_card_awake_unlock();
4685 
4686     if (i == MLAN_STATUS_FAILURE)
4687     {
4688         return (int)-WM_FAIL;
4689     }
4690 
4691     return WM_SUCCESS;
4692 }
4693 #endif /* CONFIG_WPS2 */
4694 
wifi_set_country_code(const char * alpha2)4695 int wifi_set_country_code(const char *alpha2)
4696 {
4697     mlan_adapter *pmadapter             = (mlan_adapter *)mlan_adap;
4698     t_u8 country_code[COUNTRY_CODE_LEN] = {0};
4699 
4700 #ifdef OTP_CHANINFO
4701     if (pmadapter->otp_region && pmadapter->otp_region->force_reg)
4702     {
4703         wifi_e("ForceRegionRule is set in the on-chip OTP memory");
4704         return -WM_FAIL;
4705     }
4706 #endif
4707 
4708     (void)memcpy(country_code, alpha2, COUNTRY_CODE_LEN - 1);
4709 
4710     pmadapter->region_code = region_string_2_region_code(country_code);
4711 
4712     pmadapter->cfp_code_bg = pmadapter->region_code;
4713 #if CONFIG_5GHz_SUPPORT
4714     pmadapter->cfp_code_a = pmadapter->region_code;
4715 #endif
4716 
4717     if (wlan_set_regiontable(pmadapter->priv[1], pmadapter->region_code, pmadapter->config_bands))
4718     {
4719         wifi_e("%s set regiontable fail", __func__);
4720         return -WM_FAIL;
4721     }
4722     (void)memcpy(pmadapter->country_code, country_code, COUNTRY_CODE_LEN);
4723 
4724 #if CONFIG_WPA_SUPP
4725     if (wm_wifi.supp_if_callbk_fns->chan_list_changed_callbk_fn)
4726     {
4727 #if CONFIG_WPA_SUPP_AP
4728         if ((wm_wifi.hostapd_op) || mlan_adap->priv[1]->uap_bss_started)
4729         {
4730             wm_wifi.supp_if_callbk_fns->chan_list_changed_callbk_fn(wm_wifi.hapd_if_priv, alpha2);
4731         }
4732         if(!wm_wifi.hostapd_op)
4733         {
4734             wm_wifi.supp_if_callbk_fns->chan_list_changed_callbk_fn(wm_wifi.if_priv, alpha2);
4735         }
4736         wm_wifi.hostapd_op = false;
4737 #endif
4738     }
4739 #endif
4740 
4741     return WM_SUCCESS;
4742 }
4743 
wifi_get_country_code(char * alpha2)4744 int wifi_get_country_code(char *alpha2)
4745 {
4746     (void)memcpy(alpha2, mlan_adap->country_code, COUNTRY_CODE_LEN - 1);
4747 
4748     return WM_SUCCESS;
4749 }
4750 
wifi_set_country_ie_ignore(uint8_t * ignore)4751 int wifi_set_country_ie_ignore(uint8_t *ignore)
4752 {
4753     mlan_adap->country_ie_ignore = *ignore;
4754     return WM_SUCCESS;
4755 }
4756 
4757 #if CONFIG_WPA_SUPP
wifi_nxp_scan_res_num(void)4758 int wifi_nxp_scan_res_num(void)
4759 {
4760     mlan_private *pmpriv    = (mlan_private *)mlan_adap->priv[0];
4761     mlan_adapter *pmadapter = pmpriv->adapter;
4762 
4763     return pmadapter->num_in_scan_table;
4764 }
4765 
wifi_nxp_scan_res_get2(t_u32 table_idx,nxp_wifi_event_new_scan_result_t * scan_res)4766 int wifi_nxp_scan_res_get2(t_u32 table_idx, nxp_wifi_event_new_scan_result_t *scan_res)
4767 {
4768     mlan_private *pmpriv    = (mlan_private *)mlan_adap->priv[0];
4769     mlan_adapter *pmadapter = pmpriv->adapter;
4770     struct os_reltime t;
4771     BSSDescriptor_t *bss_new_entry;
4772 
4773     bss_new_entry = &pmadapter->pscan_table[table_idx];
4774     memcpy(scan_res->mac_addr, bss_new_entry->mac_address, sizeof(bss_new_entry->mac_address));
4775     scan_res->frequency  = channel_to_frequency(bss_new_entry->channel, (bss_new_entry->bss_band == BAND_A ? 1 : 0));
4776     scan_res->chan_width = bss_new_entry->curr_bandwidth;
4777     scan_res->beacon_interval = bss_new_entry->beacon_period;
4778     memcpy(&scan_res->capability, &bss_new_entry->cap_info, sizeof(unsigned short));
4779     memcpy(&scan_res->ies_tsf, bss_new_entry->time_stamp, sizeof(bss_new_entry->time_stamp));
4780     os_get_reltime(&t);
4781     scan_res->seen_ms_ago = t.sec * 1000 - bss_new_entry->scan_result_tsf / 1000000 * 1000;
4782     if (bss_new_entry->ies_len > 0)
4783     {
4784         scan_res->ies.ie     = bss_new_entry->ies;
4785         bss_new_entry->ies   = NULL;
4786         scan_res->ies.ie_len = (t_u16)bss_new_entry->ies_len;
4787         bss_new_entry->ies_len = 0;
4788     }
4789     else
4790     {
4791         scan_res->ies.ie_len = (t_u16)0U;
4792     }
4793 
4794     scan_res->rssi = (t_u8) - (bss_new_entry->rssi);
4795 #if CONFIG_SCAN_CHANNEL_GAP
4796     scan_res->noise = bss_new_entry->chan_noise;
4797 #endif
4798 
4799     if ((pmpriv->media_connected == MTRUE) &&
4800         (memcmp(bss_new_entry->mac_address, (t_u8 *)&pmpriv->curr_bss_params.bss_descriptor.mac_address,
4801                 MLAN_MAC_ADDR_LENGTH) == 0U))
4802 
4803     {
4804         scan_res->status = 1;
4805     }
4806     return WM_SUCCESS;
4807 }
4808 
wifi_nxp_reset_scan_flag()4809 void wifi_nxp_reset_scan_flag()
4810 {
4811     mlan_adap->wpa_supp_scan_triggered = MFALSE;
4812 }
4813 
wifi_nxp_survey_res_get(void)4814 int wifi_nxp_survey_res_get(void)
4815 {
4816 #if CONFIG_SCAN_CHANNEL_GAP
4817     mlan_private *pmpriv          = (mlan_private *)mlan_adap->priv[0];
4818     ChanStatistics_t *pchan_stats = NULL;
4819     mlan_scan_resp scan_resp;
4820     t_u32 idx;
4821     nxp_wifi_event_new_survey_result_t survey_res;
4822     bool more_res = true;
4823 #endif
4824 
4825     ENTER();
4826     wifi_d("dump_survey");
4827 
4828 #if CONFIG_SCAN_CHANNEL_GAP
4829     memset(&scan_resp, 0, sizeof(scan_resp));
4830     wifi_get_scan_table(pmpriv, &scan_resp);
4831 
4832     pchan_stats = (ChanStatistics_t *)scan_resp.pchan_stats;
4833 
4834     for (idx = 0; idx < scan_resp.num_in_chan_stats; idx++)
4835     {
4836         if (pchan_stats[idx].chan_num == 0)
4837         {
4838             if (wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn)
4839             {
4840 #if CONFIG_WPA_SUPP_AP
4841                 if (wm_wifi.hostapd_op)
4842                 {
4843                     wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn(wm_wifi.hapd_if_priv, NULL, 0, false);
4844                 }
4845                 else
4846 #endif
4847                 {
4848                     wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn(wm_wifi.if_priv, NULL, 0, false);
4849                 }
4850 
4851                 OSA_TimeDelay(50);
4852             }
4853 
4854             break;
4855         }
4856 
4857         memset(&survey_res, 0x00, sizeof(nxp_wifi_event_new_survey_result_t));
4858 
4859         survey_res.freq         = channel_to_frequency(pchan_stats[idx].chan_num, pchan_stats[idx].bandcfg.chanBand);
4860         survey_res.nf           = pchan_stats[idx].noise;
4861         survey_res.channel_time = pchan_stats[idx].cca_scan_duration;
4862         survey_res.channel_time_busy = pchan_stats[idx].cca_busy_duration;
4863 
4864         if (pchan_stats[idx + 1].chan_num == 0)
4865         {
4866             more_res = false;
4867         }
4868         if (wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn)
4869         {
4870 #if CONFIG_WPA_SUPP_AP
4871             if (wm_wifi.hostapd_op)
4872             {
4873                 wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn(wm_wifi.hapd_if_priv, &survey_res,
4874                                                                  sizeof(nxp_wifi_event_new_survey_result_t), more_res);
4875             }
4876             else
4877 #endif
4878             {
4879                 wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn(wm_wifi.if_priv, &survey_res,
4880                                                                  sizeof(nxp_wifi_event_new_survey_result_t), more_res);
4881             }
4882 
4883             OSA_TimeDelay(50);
4884         }
4885     }
4886 #else
4887     if (wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn)
4888     {
4889 #if CONFIG_WPA_SUPP_AP
4890         if (wm_wifi.hostapd_op)
4891         {
4892             wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn(wm_wifi.hapd_if_priv, NULL, 0, false);
4893         }
4894         else
4895 #endif
4896         {
4897             wm_wifi.supp_if_callbk_fns->survey_res_callbk_fn(wm_wifi.if_priv, NULL, 0, false);
4898         }
4899 
4900         OSA_TimeDelay(50);
4901     }
4902 #endif
4903     return WM_SUCCESS;
4904 }
4905 
4906 #if CONFIG_WPA_SUPP_WPS
wifi_nxp_wps_session_enable(void)4907 bool wifi_nxp_wps_session_enable(void)
4908 {
4909     mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[0];
4910 
4911     return pmpriv->wps.session_enable;
4912 }
4913 #endif
4914 
4915 #if CONFIG_1AS
raw_wlan_xmit_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface,t_u32 tx_control)4916 mlan_status raw_wlan_xmit_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface, t_u32 tx_control)
4917 {
4918     int ret;
4919     mlan_status i;
4920 
4921     wifi_tx_card_awake_lock();
4922     i = wlan_xmit_pkt(buffer, txlen, interface, tx_conttol);
4923     wifi_tx_card_awake_unlock();
4924 
4925     return i;
4926 }
4927 #endif
4928 
supp_low_level_output(const t_u8 interface,const t_u8 * buf,t_u32 len)4929 static int supp_low_level_output(const t_u8 interface, const t_u8 *buf, t_u32 len)
4930 {
4931 #if (CONFIG_WMM)
4932     t_u32 pkt_len            = 0;
4933     t_u32 link_point_len     = 0;
4934     bypass_outbuf_t *poutbuf = NULL;
4935 
4936     /*Dword align*/
4937     pkt_len        = sizeof(TxPD) + INTF_HEADER_LEN;
4938     link_point_len = sizeof(mlan_linked_list);
4939 
4940 #if !CONFIG_MEM_POOLS
4941     poutbuf = OSA_MemoryAllocate(link_point_len + pkt_len + len);
4942 #else
4943     poutbuf = (bypass_outbuf_t *)OSA_MemoryPoolAllocate(buf_1536_MemoryPool);
4944 #endif
4945     if (!poutbuf)
4946     {
4947         wuap_e("[%s] ERR:Cannot allocate buffer!\r\n", __func__);
4948         return -WM_FAIL;
4949     }
4950 
4951     (void)memset((t_u8 *)poutbuf, 0, link_point_len + pkt_len);
4952 
4953     (void)memcpy((void *)((t_u8 *)poutbuf + link_point_len + pkt_len), (const void *)buf, (size_t)len);
4954     /* process packet headers with interface header and TxPD */
4955     process_pkt_hdrs((void *)((t_u8 *)poutbuf + link_point_len), pkt_len + len, interface, 0, 0);
4956 
4957     wlan_add_buf_bypass_txq((t_u8 *)poutbuf, interface);
4958     send_wifi_driver_bypass_data_event(interface);
4959 
4960     return WM_SUCCESS;
4961 #else
4962     mlan_status i;
4963     uint32_t pkt_len, outbuf_len;
4964 
4965     uint8_t *outbuf = wifi_get_outbuf(&outbuf_len);
4966 
4967     if (!outbuf)
4968     {
4969         return (int)-WM_FAIL;
4970     }
4971 
4972     pkt_len = sizeof(TxPD) + INTF_HEADER_LEN;
4973 
4974     if ((len + pkt_len) > outbuf_len)
4975     {
4976         return (int)-WM_FAIL;
4977     }
4978 
4979     wifi_tx_card_awake_lock();
4980 #if defined(RW610)
4981     wifi_imu_lock();
4982 #else
4983     wifi_sdio_lock();
4984 #endif
4985 
4986     (void)memset(outbuf, 0x00, pkt_len);
4987 
4988     (void)memcpy((t_u8 *)outbuf + pkt_len, buf, len);
4989 
4990     i = wlan_xmit_pkt(outbuf, pkt_len + len, interface, 0);
4991 
4992 #if defined(RW610)
4993     wifi_imu_unlock();
4994 #else
4995     wifi_sdio_unlock();
4996 #endif
4997     wifi_tx_card_awake_unlock();
4998 
4999     if (i == MLAN_STATUS_FAILURE)
5000     {
5001         return (int)-WM_FAIL;
5002     }
5003 
5004     wifi_set_xfer_pending(false);
5005     return (int)WM_SUCCESS;
5006 
5007 #endif
5008 }
5009 
wifi_supp_inject_frame(const unsigned int bss_type,const uint8_t * buff,const size_t len)5010 int wifi_supp_inject_frame(const unsigned int bss_type, const uint8_t *buff, const size_t len)
5011 {
5012     return supp_low_level_output((t_u8)bss_type, buff, len);
5013 }
5014 
5015 /**
5016  *  Alpha2 may has only 2 octets.
5017  *  Need to avoid accessing the third octet.
5018  *  If On-Chip OTP memory sets ForceRegion Rule, set country may return fail.
5019  *  Ignore it to not let it block AP setup.
5020  */
wifi_nxp_set_country(const unsigned int bss_type,const char * alpha2)5021 int wifi_nxp_set_country(const unsigned int bss_type, const char *alpha2)
5022 {
5023     (void)wifi_set_country_code(alpha2);
5024     return WM_SUCCESS;
5025 }
5026 
5027 /**
5028  *  Alpha2 may has only 2 octets.
5029  *  Need to avoid accessing the third octet.
5030  */
wifi_nxp_get_country(const unsigned int bss_type,char * alpha2)5031 int wifi_nxp_get_country(const unsigned int bss_type, char *alpha2)
5032 {
5033     return wifi_get_country_code(alpha2);
5034 }
5035 
wifi_nxp_get_signal(unsigned int bss_type,nxp_wifi_signal_info_t * signal_params)5036 int wifi_nxp_get_signal(unsigned int bss_type, nxp_wifi_signal_info_t *signal_params)
5037 {
5038     wifi_rssi_info_t rssi_info;
5039 
5040     (void)wifi_send_rssi_info_cmd(&rssi_info);
5041 
5042     signal_params->current_signal    = rssi_info.bcn_rssi_last;
5043     signal_params->avg_signal        = rssi_info.data_rssi_avg;
5044     signal_params->avg_beacon_signal = rssi_info.bcn_rssi_avg;
5045     signal_params->current_noise     = rssi_info.bcn_nf_last;
5046 
5047     return WM_SUCCESS;
5048 }
5049 
wifi_nxp_send_mlme(unsigned int bss_type,int channel,unsigned int wait_time,const t_u8 * data,size_t data_len)5050 int wifi_nxp_send_mlme(unsigned int bss_type, int channel, unsigned int wait_time, const t_u8 *data, size_t data_len)
5051 {
5052     mlan_private *pmpriv              = (mlan_private *)mlan_adap->priv[bss_type];
5053     wlan_mgmt_pkt *pmgmt_pkt_hdr      = MNULL;
5054     wlan_802_11_header *pieee_pkt_hdr = MNULL;
5055     t_u8 buf[1580];
5056 
5057     // dump_hex(data, data_len);
5058     memset(buf, 0x00, sizeof(buf));
5059 
5060     if ((bss_type == BSS_TYPE_STA) && (pmpriv->media_connected == MFALSE))
5061     {
5062         if (wait_time == 0)
5063         {
5064             wait_time = 1000;
5065         }
5066         wifi_remain_on_channel(true, channel, wait_time);
5067     }
5068 
5069     pmgmt_pkt_hdr = (wlan_mgmt_pkt *)&buf[0];
5070 
5071     pmgmt_pkt_hdr->frm_len = data_len + MLAN_MAC_ADDR_LENGTH;
5072 
5073     pieee_pkt_hdr = (wlan_802_11_header *)(void *)&pmgmt_pkt_hdr->wlan_header;
5074 
5075     memcpy(pieee_pkt_hdr, data, sizeof(wlan_802_11_header) - MLAN_MAC_ADDR_LENGTH);
5076     // coverity[overrun-local:SUPPRESS]
5077     memcpy(pieee_pkt_hdr + 1, data + sizeof(wlan_802_11_header) - MLAN_MAC_ADDR_LENGTH,
5078            data_len - (sizeof(wlan_802_11_header) - MLAN_MAC_ADDR_LENGTH));
5079 
5080     data_len = pmgmt_pkt_hdr->frm_len + 2U;
5081 
5082     return wifi_inject_frame((enum wlan_bss_type)bss_type, buf, data_len);
5083 }
5084 #else
wifi_supp_inject_frame(const unsigned int bss_type,const uint8_t * buff,const size_t len)5085 int wifi_supp_inject_frame(const unsigned int bss_type, const uint8_t *buff, const size_t len)
5086 {
5087     (void)bss_type;
5088     (void)buff;
5089     (void)len;
5090 
5091     return WM_SUCCESS;
5092 }
5093 #endif
5094 
wifi_is_remain_on_channel(void)5095 bool wifi_is_remain_on_channel(void)
5096 {
5097     return (mlan_adap->remain_on_channel ? true : false);
5098 }
5099 
wifi_remain_on_channel(const bool status,const uint8_t channel,const uint32_t duration)5100 int wifi_remain_on_channel(const bool status, const uint8_t channel, const uint32_t duration)
5101 {
5102     wifi_remain_on_channel_t roc;
5103 
5104     (void)memset(&roc, 0x00, sizeof(wifi_remain_on_channel_t));
5105 
5106     roc.remove = (uint16_t)!status;
5107 
5108     roc.channel = channel;
5109 
5110     roc.remain_period = duration;
5111 
5112 #if CONFIG_5GHz_SUPPORT
5113     if (channel > 14)
5114     {
5115         roc.bandcfg |= 1;
5116     }
5117 #endif
5118 #if CONFIG_WMM
5119     if (true == status)
5120     {
5121         /* Block tx data before send remain on channel,
5122          * then get txbuf_sem, keep the next auth frame can get txbuf
5123          */
5124         wifi_set_tx_status(WIFI_DATA_BLOCK);
5125 
5126         if (wifi_txbuf_available() == MFALSE)
5127         {
5128             mlan_adap->wait_txbuf = true;
5129             OSA_SemaphoreWait((osa_semaphore_handle_t)txbuf_sem, osaWaitForever_c);
5130             mlan_adap->wait_txbuf = false;
5131         }
5132     }
5133     else if (false == status)
5134     {
5135         /* Restore tx when cancel remain on channel*/
5136         wifi_set_tx_status(WIFI_DATA_RUNNING);
5137 
5138         send_wifi_driver_tx_data_event(MLAN_BSS_TYPE_STA);
5139         send_wifi_driver_tx_data_event(MLAN_BSS_TYPE_UAP);
5140     }
5141 #endif
5142 
5143     return wifi_send_remain_on_channel_cmd(MLAN_BSS_TYPE_STA, &roc);
5144 }
5145 
5146 #ifdef RW610
wifi_imu_get_task_lock(void)5147 int wifi_imu_get_task_lock(void)
5148 {
5149     return imu_get_task_lock();
5150 }
5151 
wifi_imu_put_task_lock(void)5152 int wifi_imu_put_task_lock(void)
5153 {
5154     return imu_put_task_lock();
5155 }
5156 #endif
5157 
5158 #if CONFIG_CSI
5159 
5160 /* csi data recv user callback */
5161 int (*csi_data_recv)(void *buffer, size_t len) = NULL;
5162 
register_csi_user_callback(int (* csi_data_recv_callback)(void * buffer,size_t len))5163 int register_csi_user_callback(int (*csi_data_recv_callback)(void *buffer, size_t len))
5164 {
5165     csi_data_recv = csi_data_recv_callback;
5166 
5167     return WM_SUCCESS;
5168 }
5169 
unregister_csi_user_callback(void)5170 int unregister_csi_user_callback(void)
5171 {
5172     csi_data_recv = NULL;
5173 
5174     return WM_SUCCESS;
5175 }
5176 
process_csi_info_callback(void * data,size_t len)5177 void process_csi_info_callback(void *data, size_t len)
5178 {
5179     if (csi_data_recv != NULL)
5180     {
5181         csi_data_recv(data, len);
5182     }
5183 }
5184 
csi_local_buff_init()5185 void csi_local_buff_init()
5186 {
5187     csi_event_cnt      = 0;
5188     csi_event_data_len = 0;
5189 
5190     csi_buff_stat.write_index    = 0;
5191     csi_buff_stat.read_index     = 0;
5192     csi_buff_stat.valid_data_cnt = 0;
5193 
5194     memset(csi_local_buff, 0x00, sizeof(csi_local_buff));
5195 }
5196 
csi_save_data_to_local_buff(void * data)5197 void csi_save_data_to_local_buff(void *data)
5198 {
5199     OSA_SemaphoreWait((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem, osaWaitForever_c);
5200 
5201     if (csi_buff_stat.valid_data_cnt >= MAX_CSI_LOCAL_BUF)
5202     {
5203         OSA_SemaphorePost((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem);
5204         wifi_w("******csi_local_buff is full******\r\n");
5205         return;
5206     }
5207 
5208     memcpy(&csi_local_buff[csi_buff_stat.write_index][0], (t_u8 *)data, CSI_LOCAL_BUF_ENTRY_SIZE);
5209 
5210     csi_buff_stat.valid_data_cnt++;
5211 
5212     csi_buff_stat.write_index = (csi_buff_stat.write_index + 1) % MAX_CSI_LOCAL_BUF;
5213 
5214     OSA_SemaphorePost((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem);
5215 }
5216 
csi_deliver_data_to_user()5217 void csi_deliver_data_to_user()
5218 {
5219     int i               = 0;
5220     t_u16 save_data_len = 0;
5221 
5222     OSA_SemaphoreWait((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem, osaWaitForever_c);
5223 
5224     for (i = 0; (i < MAX_CSI_LOCAL_BUF) && (csi_buff_stat.valid_data_cnt > 0); i++)
5225     {
5226         pcsi_record_ds csi_record = (pcsi_record_ds)(&csi_local_buff[csi_buff_stat.read_index][0]);
5227         save_data_len             = (csi_record->Len & 0x1fff) * 4;
5228         save_data_len = (save_data_len >= CSI_LOCAL_BUF_ENTRY_SIZE) ? CSI_LOCAL_BUF_ENTRY_SIZE : save_data_len;
5229 
5230         process_csi_info_callback((t_u8 *)csi_record, save_data_len);
5231 
5232         csi_buff_stat.valid_data_cnt--;
5233 
5234         csi_buff_stat.read_index = (csi_buff_stat.read_index + 1) % MAX_CSI_LOCAL_BUF;
5235     }
5236 
5237     OSA_SemaphorePost((osa_semaphore_handle_t)csi_buff_stat.csi_data_sem);
5238 }
5239 #endif
5240