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