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