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