1 /** @file wifi-imu.c
2 *
3 * @brief This file provides WLAN Card related API
4 *
5 * Copyright 2022-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10
11 #include <mlan_api.h>
12 #ifndef RW610
13 #include <mlan_sdio_api.h>
14 #endif
15 /* Additional WMSDK header files */
16 #include <wmerrno.h>
17 #include <osa.h>
18 #include <wm_utils.h>
19 #include <mlan_fw.h>
20 #include "wifi-imu.h"
21 #include "wifi-internal.h"
22 #include "fsl_adapter_rfimu.h"
23 #include "fsl_imu.h"
24 #include "fsl_loader.h"
25
26 /* Buffer pointers to point to command and, command response buffer */
27 static uint8_t cmd_buf[WIFI_FW_CMDBUF_SIZE];
28 // static t_u32 seqnum;
29 // static int pm_handle;
30 #define IMU_OUTBUF_LEN 3072
31 #define IMU_INIT_FW_CMD_SIZE 256
32
33 #if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
34 #ifndef MCI_WAKEUP_DONE_PRIORITY
35 #define MCI_WAKEUP_DONE_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1)
36 #endif
37 #ifndef MCI_WAKEUP_SRC_PRIORITY
38 #define MCI_WAKEUP_SRC_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 2)
39 #endif
40 #else
41 #ifndef MCI_WAKEUP_DONE_PRIORITY
42 #define MCI_WAKEUP_DONE_PRIORITY (3U)
43 #endif
44 #ifndef MCI_WAKEUP_SRC_PRIORITY
45 #define MCI_WAKEUP_SRC_PRIORITY (4U)
46 #endif
47 #endif
48 /*
49 * Used to authorize the SDIO interrupt handler to accept the incoming
50 * packet from the SDIO interface. If this flag is set a semaphore is
51 * signalled.
52 */
53 bool g_txrx_flag;
54
55 #ifdef RW610
56 bool cal_data_valid_rw610;
57 #endif
58
59 int mlan_subsys_init(void);
60 int mlan_subsys_deinit();
61
62 const uint8_t *wlanfw;
63
64 t_u32 last_resp_rcvd, last_cmd_sent;
65
66 OSA_MUTEX_HANDLE_DEFINE(txrx_mutex);
67
68 #ifndef RW610
69 osa_task_handle_t wifi_core_thread;
70 #endif
71 static struct
72 {
73 /* Where the cmdresp/event should be dispached depends on its value */
74 /* int special; */
75 /* Default queue where the cmdresp/events will be sent */
76 osa_msgq_handle_t event_queue;
77 int (*wifi_low_level_input)(const uint8_t interface, const uint8_t *buffer, const uint16_t len);
78 } bus;
79
80 /* remove this after mlan integration complete */
81 enum
82 {
83 MLAN_CARD_NOT_DETECTED = 3,
84 MLAN_STATUS_FW_DNLD_FAILED,
85 MLAN_STATUS_FW_NOT_DETECTED = 5,
86 MLAN_STATUS_FW_NOT_READY,
87 MLAN_STATUS_FW_XZ_FAILED,
88 MLAN_CARD_CMD_TIMEOUT
89 };
90
91 /* @brief decription about the read/write buffer
92 * The size of the read/write buffer should be a multiple of 512, since SDHC/SDXC card uses 512-byte fixed
93 * block length and this driver example is enabled with a SDHC/SDXC card.If you are using a SDSC card, you
94 * can define the block length by yourself if the card supports partial access.
95 * The address of the read/write buffer should align to the specific DMA data buffer address align value if
96 * DMA transfer is used, otherwise the buffer address is not important.
97 * At the same time buffer address/size should be aligned to the cache line size if cache is supported.
98 */
99 /*! @brief Data written to the card */
100 SDK_ALIGN(uint8_t outbuf[IMU_OUTBUF_LEN], 32);
101
102 #ifdef RW610
103 SDK_ALIGN(uint8_t inbuf[2 * DATA_BUFFER_SIZE], 32);
104 #else
105 /*! @brief Data read from the card */
106 SDK_ALIGN(uint8_t inbuf[SDIO_MP_AGGR_DEF_PKT_LIMIT * 2 * DATA_BUFFER_SIZE], 32);
107 #endif
108 #if CONFIG_AMSDU_IN_AMPDU
109 SDK_ALIGN(uint8_t amsdu_outbuf[MAX_SUPPORT_AMSDU_SIZE], 32);
110 #endif
111
112 hal_rpmsg_status_t rpmsg_cmdrsp_handler(IMU_Msg_t *pImuMsg, uint32_t length);
113 hal_rpmsg_status_t rpmsg_event_handler(IMU_Msg_t *pImuMsg, uint32_t length);
114 hal_rpmsg_status_t rpmsg_rxpkt_handler(IMU_Msg_t *pImuMsg, uint32_t length);
115 hal_rpmsg_status_t rpmsg_ctrl_handler(IMU_Msg_t *pImuMsg, uint32_t length);
116
117 /* Remove me: This structure is not present in mlan and can be removed later */
118 typedef MLAN_PACK_START struct
119 {
120 t_u16 size;
121 t_u16 pkttype;
122 HostCmd_DS_COMMAND hostcmd;
123 } MLAN_PACK_END IMUPkt;
124
125 IMUPkt *imupkt = (IMUPkt *)outbuf;
126
127 #if CONFIG_PALLADIUM_SUPPORT
128 #define WIFI_POLL_CMD_RESP_TIME 1
129 #else
130 #define WIFI_POLL_CMD_RESP_TIME 10
131 #endif
132 #if CONFIG_TX_RX_ZERO_COPY
133 extern void net_tx_zerocopy_process_cb(void *destAddr, void *srcAddr, uint32_t len);
134 #endif
135 void wrapper_wlan_cmd_11n_cfg(void *hostcmd);
136 void wrapper_wifi_ret_mib(void *resp);
137 uint32_t dev_value1 = -1;
138 uint8_t dev_mac_addr[MLAN_MAC_ADDR_LENGTH];
139 uint8_t dev_mac_addr_uap[MLAN_MAC_ADDR_LENGTH];
140 static uint8_t dev_fw_ver_ext[MLAN_MAX_VER_STR_LEN];
141
wifi_init_imulink(void)142 static void wifi_init_imulink(void)
143 {
144 /* Assign IMU channel for CPU1-CPU3 communication */
145 HAL_ImuInit(kIMU_LinkCpu1Cpu3);
146 }
147
148 uint8_t cmd_seqno = 0;
wifi_send_fw_cmd(t_u16 cmd_type,t_u8 * cmd_payload,t_u32 length)149 static hal_rpmsg_status_t wifi_send_fw_cmd(t_u16 cmd_type, t_u8 *cmd_payload, t_u32 length)
150 {
151 IMUPkt *imu_cmd = (IMUPkt *)cmd_payload;
152 HostCmd_DS_COMMAND *cmd = NULL;
153
154 if (cmd_payload == NULL || length == 0)
155 return kStatus_HAL_RpmsgError;
156
157 cmd = &(imu_cmd->hostcmd);
158 cmd->seq_num = (cmd->seq_num & 0xFF00) | cmd_seqno;
159 cmd_seqno++;
160
161 #if (CONFIG_ENABLE_WARNING_LOGS) || (CONFIG_WIFI_CMD_RESP_DEBUG)
162 wcmdr_d("DNLD_CMD: 0x%x, act 0x%x, len %d, seqno 0x%x", cmd->command, *(t_u16 *)((t_u8 *)cmd + S_DS_GEN), cmd->size,
163 cmd->seq_num);
164 #endif /* CONFIG_ENABLE_WARNING_LOGS || CONFIG_WIFI_CMD_RESP_DEBUG*/
165
166 #if CONFIG_WIFI_IO_DUMP
167 (void)PRINTF("OUT_CMD");
168 dump_hex(cmd_payload, length);
169 #endif /* CONFIG_WIFI_IO_DUMP */
170
171 while (kStatus_HAL_RpmsgSuccess != HAL_ImuSendCommand(kIMU_LinkCpu1Cpu3, cmd_payload, length))
172 {
173 OSA_TimeDelay(1);
174 }
175 return kStatus_HAL_RpmsgSuccess;
176 }
177
wifi_send_fw_data(t_u8 * data,t_u32 length)178 static hal_rpmsg_status_t wifi_send_fw_data(t_u8 *data, t_u32 length)
179 {
180 if (data == NULL || length == 0)
181 return kStatus_HAL_RpmsgError;
182 w_pkt_d("Data TX SIG: Driver=>FW, len %d", length);
183 return HAL_ImuSendTxData(kIMU_LinkCpu1Cpu3, data, length);
184 }
185
wifi_imu_lock()186 int wifi_imu_lock()
187 {
188 return OSA_MutexLock((osa_mutex_handle_t)txrx_mutex, osaWaitForever_c);
189 }
190
wifi_imu_unlock()191 void wifi_imu_unlock()
192 {
193 (void)OSA_MutexUnlock((osa_mutex_handle_t)txrx_mutex);
194 }
195
wifi_get_device_value1()196 uint32_t wifi_get_device_value1()
197 {
198 return dev_value1;
199 }
200
wifi_get_device_mac_addr(wifi_mac_addr_t * mac_addr)201 int wifi_get_device_mac_addr(wifi_mac_addr_t *mac_addr)
202 {
203 (void)memcpy(mac_addr->mac, dev_mac_addr, MLAN_MAC_ADDR_LENGTH);
204 return WM_SUCCESS;
205 }
206
wifi_get_device_uap_mac_addr(wifi_mac_addr_t * mac_addr_uap)207 int wifi_get_device_uap_mac_addr(wifi_mac_addr_t *mac_addr_uap)
208 {
209 (void)memcpy(mac_addr_uap->mac, dev_mac_addr_uap, MLAN_MAC_ADDR_LENGTH);
210 return WM_SUCCESS;
211 }
212
wifi_get_device_firmware_version_ext(wifi_fw_version_ext_t * fw_ver_ext)213 int wifi_get_device_firmware_version_ext(wifi_fw_version_ext_t *fw_ver_ext)
214 {
215 (void)memcpy(fw_ver_ext->version_str, dev_fw_ver_ext, MLAN_MAX_VER_STR_LEN);
216 return WM_SUCCESS;
217 }
218
219 /* Initializes the driver struct */
wlan_init_struct()220 static int wlan_init_struct()
221 {
222 osa_status_t status;
223
224 status = OSA_MutexCreate((osa_mutex_handle_t)txrx_mutex);
225 if (status != KOSA_StatusSuccess)
226 {
227 return -WM_FAIL;
228 }
229
230 return imu_create_task_lock();
231 }
232
wlan_deinit_struct()233 static int wlan_deinit_struct()
234 {
235 osa_status_t status;
236
237 status = OSA_MutexDestroy((osa_mutex_handle_t)txrx_mutex);
238 if (status != KOSA_StatusSuccess)
239 {
240 wifi_io_e("%s mutex deletion error %d", __FUNCTION__, status);
241 return -WM_FAIL;
242 }
243
244 imu_delete_task_lock();
245
246 (void)memset(dev_mac_addr, 0, sizeof(dev_mac_addr));
247 (void)memset(dev_fw_ver_ext, 0, sizeof(dev_fw_ver_ext));
248
249 return WM_SUCCESS;
250 }
251
raw_process_pkt_hdrs(void * pbuf,t_u32 payloadlen,t_u8 interface)252 int raw_process_pkt_hdrs(void *pbuf, t_u32 payloadlen, t_u8 interface)
253 {
254 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[0];
255 IMUPkt *imuhdr = (IMUPkt *)pbuf;
256 TxPD *ptxpd = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
257
258 ptxpd->bss_type = interface;
259 ptxpd->bss_num = GET_BSS_NUM(pmpriv);
260 ptxpd->tx_pkt_offset = 0x14; /* we'll just make this constant */
261 ptxpd->tx_pkt_length = payloadlen - ptxpd->tx_pkt_offset - INTF_HEADER_LEN;
262 ptxpd->tx_pkt_type = 0xE5;
263 ptxpd->tx_control = 0;
264 ptxpd->priority = 0;
265 ptxpd->flags = 0;
266 ptxpd->pkt_delay_2ms = 0;
267 /* set tx_token_id to 1 to get tx_status_event from FW */
268 ptxpd->tx_token_id = 1;
269
270 imuhdr->size = payloadlen + ptxpd->tx_pkt_offset + INTF_HEADER_LEN;
271
272 return ptxpd->tx_pkt_offset + INTF_HEADER_LEN;
273 }
274
275 /*
276 * fixme: mlan_sta_tx.c can be used directly here. This functionality is
277 * already present there.
278 */
279 /* SDIO TxPD PAYLOAD | 4 | 22 | payload | */
280
281 /* we return the offset of the payload from the beginning of the buffer */
process_pkt_hdrs(void * pbuf,t_u32 payloadlen,t_u8 interface,t_u8 tid,t_u32 tx_control)282 void process_pkt_hdrs(void *pbuf, t_u32 payloadlen, t_u8 interface, t_u8 tid, t_u32 tx_control)
283 {
284 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[0];
285 IMUPkt *imuhdr = (IMUPkt *)pbuf;
286 TxPD *ptxpd = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
287
288 ptxpd->bss_type = interface;
289 ptxpd->bss_num = GET_BSS_NUM(pmpriv);
290 ptxpd->tx_pkt_offset = 0x16; /* we'll just make this constant */
291 ptxpd->tx_pkt_length = payloadlen - ptxpd->tx_pkt_offset - INTF_HEADER_LEN;
292 if (ptxpd->tx_pkt_type == 0xe5)
293 {
294 ptxpd->tx_pkt_offset = 0x14; /* Override for special frame */
295 ptxpd->tx_pkt_length = payloadlen - ptxpd->tx_pkt_offset - INTF_HEADER_LEN;
296 }
297 ptxpd->tx_control = tx_control;
298 ptxpd->priority = tid;
299 ptxpd->flags = 0;
300 ptxpd->pkt_delay_2ms = 0;
301
302 imuhdr->size = payloadlen;
303 }
304
305 #if CONFIG_AMSDU_IN_AMPDU
306 #if defined(RW610)
process_amsdu_pkt_hdrs(void * pbuf,t_u32 payloadlen,mlan_wmm_ac_e ac,t_u8 interface)307 int process_amsdu_pkt_hdrs(void *pbuf, t_u32 payloadlen, mlan_wmm_ac_e ac, t_u8 interface)
308 #else
309 int process_amsdu_pkt_hdrs(void *pbuf, t_u32 payloadlen, mlan_wmm_ac_e ac)
310 #endif
311 {
312 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[0];
313 IMUPkt *imuhdr = (IMUPkt *)pbuf;
314 TxPD *ptxpd = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
315
316 #if defined(RW610)
317 ptxpd->bss_type = interface;
318 #else
319 TxPD *ptxpd_orig = (TxPD *)((uint8_t *)wifi_get_wmm_send_outbuf(ac, 0) + INTF_HEADER_LEN);
320 ptxpd->bss_type = ptxpd_orig->bss_type;
321 #endif
322 ptxpd->bss_num = GET_BSS_NUM(pmpriv);
323 ptxpd->tx_pkt_offset = 0x16; /* we'll just make this constant */
324 ptxpd->tx_pkt_length = payloadlen - ptxpd->tx_pkt_offset - INTF_HEADER_LEN;
325 ptxpd->tx_pkt_type = PKT_TYPE_AMSDU;
326 ptxpd->tx_control = 0;
327 ptxpd->priority = 0;
328 ptxpd->flags = 0;
329 ptxpd->pkt_delay_2ms = 0;
330
331 imuhdr->size = payloadlen;
332
333 return ptxpd->tx_pkt_offset + INTF_HEADER_LEN;
334 }
335 #endif
336
process_pkt_hdrs_flags(void * pbuf,t_u8 flags)337 void process_pkt_hdrs_flags(void *pbuf, t_u8 flags)
338 {
339 TxPD *ptxpd = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
340 ptxpd->flags = flags;
341 }
342
bus_register_event_queue(osa_msgq_handle_t event_queue)343 int bus_register_event_queue(osa_msgq_handle_t event_queue)
344 {
345 if (bus.event_queue != NULL)
346 return -WM_FAIL;
347
348 bus.event_queue = event_queue;
349
350 return WM_SUCCESS;
351 }
352
bus_deregister_event_queue()353 void bus_deregister_event_queue()
354 {
355 if (bus.event_queue != NULL)
356 bus.event_queue = NULL;
357 }
358
bus_register_data_input_function(int (* wifi_low_level_input)(const uint8_t interface,const uint8_t * buffer,const uint16_t len))359 int bus_register_data_input_function(int (*wifi_low_level_input)(const uint8_t interface,
360 const uint8_t *buffer,
361 const uint16_t len))
362 {
363 if (bus.wifi_low_level_input != NULL)
364 return -WM_FAIL;
365
366 bus.wifi_low_level_input = wifi_low_level_input;
367
368 return WM_SUCCESS;
369 }
370
bus_deregister_data_input_funtion(void)371 void bus_deregister_data_input_funtion(void)
372 {
373 bus.wifi_low_level_input = NULL;
374 }
375
376 void wifi_get_mac_address_from_cmdresp(void *resp, t_u8 *mac_addr);
377 void wifi_get_firmware_ver_ext_from_cmdresp(void *resp, t_u8 *fw_ver_ext);
378 void wifi_get_value1_from_cmdresp(void *resp, uint32_t *dev_value1);
379
380 #if CONFIG_FW_VDLLV2
wlan_handle_vdllv2_event_packet(t_u8 * pmbuf)381 static mlan_status wlan_handle_vdllv2_event_packet(t_u8 *pmbuf)
382 {
383 mlan_status status = MLAN_STATUS_SUCCESS;
384 pmlan_event_vdll_indication pevent_vdll_ind;
385
386 pevent_vdll_ind = (pmlan_event_vdll_indication)(pmbuf);
387 switch (wlan_le16_to_cpu(pevent_vdll_ind->vdllInd.type))
388 {
389 case VDLL_IND_TYPE_REQ:
390 wevt_d("VDLL_IND (VDLL REQ).");
391 (void)sb3_fw_download(LOAD_WIFI_VDLL_FIRMWARE, 1, pevent_vdll_ind->vdllInd.offset);
392 break;
393 case VDLL_IND_TYPE_INTF_RESET:
394 wevt_d("VDLLV2_IND (INTF RESET).");
395 HAL_ImuResetWlanTxq(kIMU_LinkCpu1Cpu3);
396 break;
397 default:
398 PRINTF("receive vdll event type=%d, Unhandled!\r\n", pevent_vdll_ind->vdllInd.type);
399 break;
400 }
401 return status;
402 }
403 #endif
404
wlan_handle_cmd_resp_packet(t_u8 * pmbuf)405 mlan_status wlan_handle_cmd_resp_packet(t_u8 *pmbuf)
406 {
407 HostCmd_DS_GEN *cmdresp;
408 t_u32 cmdtype;
409 t_u32 cmdsize;
410 int bss_type;
411
412 cmdresp = (HostCmd_DS_GEN *)(pmbuf + INTF_HEADER_LEN); /* size + pkttype=4 */
413 cmdtype = cmdresp->command & HostCmd_CMD_ID_MASK;
414 cmdsize = cmdresp->size;
415 #if CONFIG_IMU_GDMA
416 HAL_ImuGdmaCopyData(inbuf, cmdresp, cmdsize);
417 #else
418 memcpy(inbuf, cmdresp, cmdsize);
419 #endif
420 cmdresp = (HostCmd_DS_GEN *)inbuf;
421 bss_type = HostCmd_GET_BSS_TYPE(cmdresp->seq_num);
422
423 last_resp_rcvd = cmdtype;
424
425 if ((cmdresp->command & 0xf000) != 0x8000)
426 {
427 wifi_io_d("cmdresp->command = (0x%x)", cmdresp->command);
428 }
429
430 /* Do not process response of wlan firmware shutdown command
431 *
432 * This is required to flush out any previous response
433 * from the wlan_deinit() which might have been called
434 * prior to this.
435 *
436 */
437 if ((cmdresp->command & 0x00ff) == HostCmd_CMD_FUNC_SHUTDOWN)
438 return MLAN_STATUS_SUCCESS;
439
440 if ((cmdresp->command & 0x0fff) != last_cmd_sent)
441 {
442 wifi_io_d("cmdresp->command = (0x%x) last_cmd_sent = (0x%x)", cmdresp->command, last_cmd_sent);
443 }
444
445 if (cmdresp->result != 0U)
446 {
447 wifi_io_d("cmdresp->result = (0x%x)", cmdresp->result);
448 }
449
450 wifi_io_d("Resp : (0x%x)", cmdtype);
451 switch (cmdtype)
452 {
453 case HostCmd_CMD_MAC_CONTROL:
454 case HostCmd_CMD_FUNC_INIT:
455 case HostCmd_CMD_CFG_DATA:
456 break;
457 case HostCmd_CMD_MAC_REG_ACCESS:
458 wifi_get_value1_from_cmdresp(cmdresp, &dev_value1);
459 break;
460 case HostCmd_CMD_802_11_MAC_ADDRESS:
461 if (bss_type == MLAN_BSS_TYPE_UAP)
462 {
463 wifi_get_mac_address_from_cmdresp(cmdresp, dev_mac_addr_uap);
464 }
465 else
466 {
467 wifi_get_mac_address_from_cmdresp(cmdresp, dev_mac_addr);
468 }
469 break;
470 #ifdef OTP_CHANINFO
471 case HostCmd_CMD_CHAN_REGION_CFG:
472 wlan_ret_chan_region_cfg((mlan_private *)mlan_adap->priv[0], (HostCmd_DS_COMMAND *)cmdresp, NULL);
473 break;
474 #endif
475 case HostCmd_CMD_GET_HW_SPEC:
476 wlan_ret_get_hw_spec((mlan_private *)mlan_adap->priv[0], (HostCmd_DS_COMMAND *)cmdresp, NULL);
477 #ifdef RW610
478 t_u32 fw_cap_ext_rw610;
479 fw_cap_ext_rw610 = mlan_adap->priv[0]->adapter->fw_cap_ext;
480 #if !CONFIG_CUSTOM_CALDATA
481 cal_data_valid_rw610 = (((fw_cap_ext_rw610 & 0x0800) == 0) ? 0 : 1);
482 #else
483 cal_data_valid_rw610 = 0;
484 #endif
485 #endif
486 break;
487 case HostCmd_CMD_VERSION_EXT:
488 wifi_get_firmware_ver_ext_from_cmdresp(cmdresp, dev_fw_ver_ext);
489 break;
490 case HostCmd_CMD_11N_CFG:
491 break;
492 #if CONFIG_AMSDU_IN_AMPDU
493 case HostCmd_CMD_AMSDU_AGGR_CTRL:
494 wlan_ret_amsdu_aggr_ctrl((mlan_private *)mlan_adap->priv[0], (HostCmd_DS_COMMAND *)cmdresp, NULL);
495 break;
496 #endif
497 case HostCmd_CMD_FUNC_SHUTDOWN:
498 break;
499 #ifdef WLAN_LOW_POWER_ENABLE
500 case HostCmd_CMD_LOW_POWER_MODE:
501 break;
502 #endif
503 case HostCmd_CMD_ED_MAC_MODE:
504 case HostCmd_CMD_CHANNEL_TRPC_CONFIG:
505 break;
506 #if CONFIG_WIFI_TX_BUFF
507 case HostCmd_CMD_RECONFIGURE_TX_BUFF:
508 mlan_adap->tx_buffer_size = ((HostCmd_DS_COMMAND *)cmdresp)->params.tx_buf.buff_size;
509 break;
510 #endif
511 default:
512 wifi_io_d("Unimplemented Resp : (0x%x)", cmdtype);
513 break;
514 }
515
516 return MLAN_STATUS_SUCCESS;
517 }
518
519 /*
520 * Accepts event and command packets. Redirects them to queues if
521 * registered. If queues are not registered (as is the case during
522 * initialization then the packet is given to lower layer cmd/event
523 * handling part.
524 */
wlan_decode_rx_packet(t_u8 * pmbuf,t_u32 upld_type)525 static mlan_status wlan_decode_rx_packet(t_u8 *pmbuf, t_u32 upld_type)
526 {
527 IMUPkt *imupkt = (IMUPkt *)pmbuf;
528 t_u32 event_cause = 0;
529 int status;
530 struct bus_message msg;
531 #if CONFIG_FW_VDLLV2
532 mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[0];
533 #endif
534
535 if (upld_type == MLAN_TYPE_DATA)
536 return MLAN_STATUS_FAILURE;
537 if (upld_type == MLAN_TYPE_CMD)
538 {
539 wifi_io_d(" --- Rx: Cmd Response ---");
540 wcmdr_d("CMD_RESP: 0x%x, result %d, len %d, seqno 0x%x", imupkt->hostcmd.command, imupkt->hostcmd.result,
541 imupkt->hostcmd.size, imupkt->hostcmd.seq_num);
542
543 if (mlan_adap->cmd_sent != 0U)
544 {
545 mlan_adap->cmd_sent = MFALSE;
546 }
547 PRINTM(MINFO, "cmd_sent=%d\n", mlan_adap->cmd_sent);
548 }
549 else
550 {
551 event_cause = *((t_u32 *)(pmbuf + INTF_HEADER_LEN));
552 wifi_io_d(" --- Rx: EVENT Response ---");
553 if (event_cause != EVENT_PS_SLEEP && event_cause != EVENT_PS_AWAKE)
554 wevt_d("Event: 0x%x", event_cause);
555 }
556
557 #if CONFIG_WIFI_IO_DUMP
558 (void)PRINTF("Resp");
559 dump_hex(pmbuf, imupkt->size);
560 #endif
561
562 #if CONFIG_FW_VDLLV2
563 if (upld_type == MLAN_TYPE_EVENT && (wlan_le16_to_cpu(imupkt->hostcmd.command) == EVENT_VDLL_IND))
564 {
565 if (mlan_adap->ps_state == PS_STATE_SLEEP)
566 {
567 OSA_RWLockWriteUnlock(&sleep_rwlock);
568 pmpriv->adapter->ps_state = PS_STATE_AWAKE;
569 }
570 return wlan_handle_vdllv2_event_packet(pmbuf + INTF_HEADER_LEN);
571 }
572 #endif
573 if (bus.event_queue != NULL)
574 {
575 if (upld_type == MLAN_TYPE_CMD)
576 msg.data = wifi_mem_malloc_cmdrespbuf();
577 else
578 msg.data = wifi_malloc_eventbuf(imupkt->size);
579
580 if (!msg.data)
581 {
582 wifi_io_e("[fail] Buffer alloc: T: %d S: %d", upld_type, imupkt->size);
583 return MLAN_STATUS_FAILURE;
584 }
585
586 msg.event = upld_type;
587 #if CONFIG_IMU_GDMA
588 HAL_ImuGdmaCopyData(msg.data, pmbuf, imupkt->size);
589 #else
590 memcpy(msg.data, pmbuf, imupkt->size);
591 #endif
592
593 status = OSA_MsgQPut(bus.event_queue, &msg);
594
595 if (status != KOSA_StatusSuccess)
596 {
597 wifi_io_e("Failed to send response on Queue: upld_type=%d id=0x%x", upld_type,
598 (upld_type == MLAN_TYPE_CMD) ? imupkt->hostcmd.command : event_cause);
599 if (upld_type != MLAN_TYPE_CMD)
600 wifi_free_eventbuf(msg.data);
601 return MLAN_STATUS_FAILURE;
602 }
603 }
604 else
605 {
606 /* No queues registered yet. Use local handling */
607 wlan_handle_cmd_resp_packet(pmbuf);
608 }
609
610 return MLAN_STATUS_SUCCESS;
611 }
612
wlan_get_next_seq_num()613 static inline t_u32 wlan_get_next_seq_num()
614 {
615 return 0;
616 }
617
618 void wifi_prepare_set_cal_data_cmd(void *cmd, int seq_number);
_wlan_set_cal_data()619 static int _wlan_set_cal_data()
620 {
621 (void)memset(outbuf, 0, IMU_OUTBUF_LEN);
622
623 /* imupkt = outbuf */
624 wifi_prepare_set_cal_data_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
625
626 imupkt->pkttype = MLAN_TYPE_CMD;
627 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
628
629 last_cmd_sent = HostCmd_CMD_CFG_DATA;
630
631 /* send CMD53 to write the command to get mac address */
632 wifi_send_fw_cmd(HostCmd_CMD_CFG_DATA, (uint8_t *)outbuf, imupkt->size);
633 return true;
634 }
635
636 void wifi_prepare_get_mac_addr_cmd(void *cmd, int seq_number);
637 void wifi_prepare_get_channel_region_cfg_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
638 void wifi_prepare_get_hw_spec_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
639
640 #ifdef OTP_CHANINFO
wlan_get_channel_region_cfg()641 static int wlan_get_channel_region_cfg()
642 {
643 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
644 /* imupkt = outbuf */
645 wifi_prepare_get_channel_region_cfg_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
646
647 imupkt->pkttype = MLAN_TYPE_CMD;
648 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
649
650 last_cmd_sent = HostCmd_CMD_CHAN_REGION_CFG;
651 wifi_send_fw_cmd(HostCmd_CMD_CHAN_REGION_CFG, (uint8_t *)outbuf, imupkt->size);
652
653 return true;
654 }
655 #endif
656
wlan_get_hw_spec()657 static int wlan_get_hw_spec()
658 {
659 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
660 /* imupkt = outbuf */
661 wifi_prepare_get_hw_spec_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
662
663 imupkt->pkttype = MLAN_TYPE_CMD;
664 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
665
666 last_cmd_sent = HostCmd_CMD_GET_HW_SPEC;
667
668 wifi_send_fw_cmd(HostCmd_CMD_GET_HW_SPEC, (uint8_t *)outbuf, imupkt->size);
669 return true;
670 }
671
wlan_get_mac_addr_sta()672 static int wlan_get_mac_addr_sta()
673 {
674 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
675
676 /* imupkt = outbuf */
677 wifi_prepare_get_mac_addr_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
678
679 imupkt->pkttype = MLAN_TYPE_CMD;
680 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
681
682 last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
683
684 /* send CMD53 to write the command to get mac address */
685 wifi_send_fw_cmd(HostCmd_CMD_802_11_MAC_ADDRESS, (uint8_t *)outbuf, imupkt->size);
686 return true;
687 }
688
wlan_get_mac_addr_uap()689 static int wlan_get_mac_addr_uap()
690 {
691 int seq_number = 0;
692
693 seq_number = HostCmd_SET_SEQ_NO_BSS_INFO(0 /* seq_num */, 0 /* bss_num */, MLAN_BSS_TYPE_UAP);
694 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
695
696 /* imupkt = outbuf */
697 wifi_prepare_get_mac_addr_cmd(&imupkt->hostcmd, seq_number);
698
699 imupkt->pkttype = MLAN_TYPE_CMD;
700 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
701
702 last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
703
704 /* send CMD53 to write the command to get mac address */
705 wifi_send_fw_cmd(HostCmd_CMD_802_11_MAC_ADDRESS, (uint8_t *)outbuf, imupkt->size);
706 return true;
707 }
708
709 void wifi_prepare_get_fw_ver_ext_cmd(void *cmd, int seq_number, int version_str_sel);
wlan_get_fw_ver_ext(int version_str_sel)710 static int wlan_get_fw_ver_ext(int version_str_sel)
711 {
712 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
713
714 /* imupkt = outbuf */
715 wifi_prepare_get_fw_ver_ext_cmd(&imupkt->hostcmd, wlan_get_next_seq_num(), version_str_sel);
716
717 imupkt->pkttype = MLAN_TYPE_CMD;
718 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
719
720 last_cmd_sent = HostCmd_CMD_VERSION_EXT;
721
722 /* send CMD53 to write the command to get mac address */
723 wifi_send_fw_cmd(HostCmd_CMD_VERSION_EXT, (uint8_t *)outbuf, imupkt->size);
724 return true;
725 }
726
727 void wifi_prepare_get_value1(void *cmd, int seq_number);
728
wlan_get_value1()729 static int wlan_get_value1()
730 {
731 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
732
733 /* imupkt = outbuf */
734 wifi_prepare_get_value1(&imupkt->hostcmd, wlan_get_next_seq_num());
735
736 imupkt->pkttype = MLAN_TYPE_CMD;
737 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
738
739 last_cmd_sent = HostCmd_CMD_MAC_REG_ACCESS;
740 wifi_send_fw_cmd(HostCmd_CMD_MAC_REG_ACCESS, (uint8_t *)outbuf, imupkt->size);
741 return true;
742 }
743
744 void wifi_prepare_set_mac_addr_cmd(void *cmd, int seq_number);
_wlan_set_mac_addr()745 static int _wlan_set_mac_addr()
746 {
747 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
748
749 /* imupkt = outbuf */
750 wifi_prepare_set_mac_addr_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
751
752 imupkt->pkttype = MLAN_TYPE_CMD;
753 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
754
755 last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
756
757 /* send CMD53 to write the command to get mac address */
758 wifi_send_fw_cmd(HostCmd_CMD_802_11_MAC_ADDRESS, (uint8_t *)outbuf, imupkt->size);
759 return true;
760 }
761
wlan_set_11n_cfg()762 static int wlan_set_11n_cfg()
763 {
764 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
765 wrapper_wlan_cmd_11n_cfg(&imupkt->hostcmd);
766 /* imupkt = outbuf */
767 imupkt->hostcmd.seq_num = wlan_get_next_seq_num();
768 imupkt->pkttype = MLAN_TYPE_CMD;
769 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
770 last_cmd_sent = HostCmd_CMD_11N_CFG;
771 wifi_send_fw_cmd(HostCmd_CMD_11N_CFG, (uint8_t *)outbuf, imupkt->size);
772
773 return true;
774 }
775
776 #if CONFIG_WIFI_TX_BUFF
_wlan_return_all_tx_buf(imu_link_t link)777 int _wlan_return_all_tx_buf(imu_link_t link)
778 {
779 HAL_ImuReturnAllTxBuf(link);
780
781 return true;
782 }
783
784 void wifi_prepare_set_tx_buf_size(void *cmd, int seq_number);
_wlan_recfg_tx_buf_size(uint16_t buf_size)785 static int _wlan_recfg_tx_buf_size(uint16_t buf_size)
786 {
787 wifi_calibrate_tx_buf_size(buf_size);
788
789 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
790
791 /* imupkt = outbuf */
792 wifi_prepare_set_tx_buf_size(&imupkt->hostcmd, wlan_get_next_seq_num());
793
794 imupkt->pkttype = MLAN_TYPE_CMD;
795 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
796
797 last_cmd_sent = HostCmd_CMD_RECONFIGURE_TX_BUFF;
798
799 wifi_send_fw_cmd(HostCmd_CMD_RECONFIGURE_TX_BUFF, (uint8_t *)outbuf, imupkt->size);
800
801 return true;
802 }
803 #endif
804
805 #if CONFIG_AMSDU_IN_AMPDU
806 void wifi_prepare_enable_amsdu_cmd(void *cmd, int seq_number);
wlan_enable_amsdu()807 static int wlan_enable_amsdu()
808 {
809 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
810
811 /* imupkt = outbuf */
812 wifi_prepare_enable_amsdu_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
813
814 imupkt->pkttype = MLAN_TYPE_CMD;
815 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
816
817 last_cmd_sent = HostCmd_CMD_AMSDU_AGGR_CTRL;
818
819 wifi_send_fw_cmd(HostCmd_CMD_AMSDU_AGGR_CTRL, (uint8_t *)outbuf, imupkt->size);
820
821 return true;
822 }
823 #endif
824 /* This function was only used in imu_wifi_deinit, and now is replaced by wifi_send_shutdown_cmd with the same 0xaa cmd
825 */
826 #if 0
827 static int wlan_cmd_shutdown()
828 {
829 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
830
831 /* imupkt = outbuf */
832 imupkt->hostcmd.command = HostCmd_CMD_FUNC_SHUTDOWN;
833 imupkt->hostcmd.size = S_DS_GEN;
834 imupkt->hostcmd.seq_num = wlan_get_next_seq_num();
835 imupkt->hostcmd.result = 0;
836
837 imupkt->pkttype = MLAN_TYPE_CMD;
838 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
839
840 last_cmd_sent = HostCmd_CMD_FUNC_SHUTDOWN;
841
842 wifi_send_fw_cmd(HostCmd_CMD_FUNC_SHUTDOWN, (uint8_t *)outbuf, imupkt->size);
843
844 return true;
845 }
846 #endif
847
848 void wlan_prepare_mac_control_cmd(void *cmd, int seq_number);
wlan_set_mac_ctrl()849 static int wlan_set_mac_ctrl()
850 {
851 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
852
853 /* imupkt = outbuf */
854 wlan_prepare_mac_control_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
855
856 imupkt->pkttype = MLAN_TYPE_CMD;
857 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
858
859 last_cmd_sent = HostCmd_CMD_MAC_CONTROL;
860
861 wifi_send_fw_cmd(HostCmd_CMD_MAC_CONTROL, (uint8_t *)outbuf, imupkt->size);
862
863 return true;
864 }
865
wlan_cmd_init()866 static int wlan_cmd_init()
867 {
868 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
869
870 /* imupkt = outbuf */
871 imupkt->hostcmd.command = HostCmd_CMD_FUNC_INIT;
872 imupkt->hostcmd.size = S_DS_GEN;
873 imupkt->hostcmd.seq_num = wlan_get_next_seq_num();
874 imupkt->hostcmd.result = 0;
875
876 imupkt->pkttype = MLAN_TYPE_CMD;
877 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
878
879 last_cmd_sent = HostCmd_CMD_FUNC_INIT;
880
881 wifi_send_fw_cmd(HostCmd_CMD_FUNC_INIT, (uint8_t *)outbuf, imupkt->size);
882
883 return true;
884 }
885
886 #ifdef WLAN_LOW_POWER_ENABLE
887 void wifi_prepare_low_power_mode_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
wlan_set_low_power_mode()888 static int wlan_set_low_power_mode()
889 {
890 (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
891
892 /* imupkt = outbuf */
893
894 wifi_prepare_low_power_mode_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
895
896 imupkt->pkttype = MLAN_TYPE_CMD;
897 imupkt->size = imupkt->hostcmd.size + INTF_HEADER_LEN;
898
899 last_cmd_sent = HostCmd_CMD_LOW_POWER_MODE;
900
901 wifi_send_fw_cmd(HostCmd_CMD_LOW_POWER_MODE, (uint8_t *)outbuf, imupkt->size);
902 return true;
903 }
904 #endif
905
wlan_wait_for_last_resp_rcvd(t_u16 command)906 static int wlan_wait_for_last_resp_rcvd(t_u16 command)
907 {
908 int retry_cnt = WIFI_COMMAND_RESPONSE_WAIT_MS / WIFI_POLL_CMD_RESP_TIME;
909
910 while ((last_resp_rcvd != command) && (retry_cnt > 0))
911 {
912 OSA_TimeDelay(WIFI_POLL_CMD_RESP_TIME);
913 retry_cnt--;
914 }
915
916 if (last_resp_rcvd == command)
917 {
918 return true;
919 }
920 else
921 {
922 wifi_io_e("%s: wait cmd 0x%x fail (last 0x%x)", __FUNCTION__, command, last_resp_rcvd);
923 return false;
924 }
925 }
926
927 // mlan_status wlan_process_int_status(mlan_adapter *pmadapter);
928 /* Setup the firmware with commands */
wlan_fw_init_cfg()929 static int wlan_fw_init_cfg()
930 {
931 wcmdr_d("FWCMD : INIT (0xa9)");
932
933 /* Add while loop here to wait until command buffer has been attached */
934 while (HAL_ImuLinkIsUp(kIMU_LinkCpu1Cpu3) != 0)
935 {
936 OSA_TimeDelay(WIFI_POLL_CMD_RESP_TIME);
937 }
938
939 wlan_cmd_init();
940
941 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_FUNC_INIT) != true)
942 {
943 return false;
944 }
945
946 #ifdef WLAN_LOW_POWER_ENABLE
947 if (low_power_mode)
948 {
949 wcmdr_d("CMD : LOW_POWER_MODE (0x128)");
950
951 wlan_set_low_power_mode();
952
953 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_LOW_POWER_MODE) != true)
954 {
955 return false;
956 }
957 }
958 #endif
959
960 if (mac_addr_valid)
961 {
962 wcmdr_d("CMD : SET_MAC_ADDR (0x4d)");
963
964 _wlan_set_mac_addr();
965
966 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_802_11_MAC_ADDRESS) != true)
967 {
968 return false;
969 }
970 }
971
972 #ifdef OTP_CHANINFO
973 wcmdr_d("CMD : Channel Region CFG (0x0242)");
974
975 wlan_get_channel_region_cfg();
976
977 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_CHAN_REGION_CFG) != true)
978 {
979 return false;
980 }
981 #endif
982
983 wcmdr_d("CMD : GET_HW_SPEC (0x03)");
984
985 wlan_get_hw_spec();
986
987 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_GET_HW_SPEC) != true)
988 {
989 return false;
990 }
991 if (cal_data_valid
992 #ifdef RW610
993 && !cal_data_valid_rw610
994 #endif
995 )
996 {
997 wcmdr_d("CMD : SET_CAL_DATA (0x8f)");
998
999 _wlan_set_cal_data();
1000
1001 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_CFG_DATA) != true)
1002 {
1003 return false;
1004 }
1005 }
1006
1007 #if CONFIG_WIFI_TX_BUFF
1008 // TODO:Reconfig tx buffer size to 4K
1009 wcmdr_d("CMD : RECONFIGURE_TX_BUFF (0xd9)");
1010
1011 _wlan_recfg_tx_buf_size(tx_buf_size);
1012
1013 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_RECONFIGURE_TX_BUFF) != true)
1014 {
1015 return false;
1016 }
1017 #endif
1018
1019 wcmdr_d("CMD : MAC_REG_ACCESS (0x19)");
1020
1021 wlan_get_value1();
1022
1023 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_MAC_REG_ACCESS) != true)
1024 {
1025 return false;
1026 }
1027
1028 wcmdr_d("CMD : GET_FW_VER_EXT (0x97)");
1029
1030 wlan_get_fw_ver_ext(0);
1031
1032 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_VERSION_EXT) != true)
1033 {
1034 return false;
1035 }
1036
1037 wcmdr_d("CMD : GET_MAC_ADDR (0x4d)");
1038
1039 wlan_get_mac_addr_sta();
1040
1041 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_802_11_MAC_ADDRESS) != true)
1042 {
1043 return false;
1044 }
1045
1046 last_resp_rcvd = 0;
1047
1048 wlan_get_mac_addr_uap();
1049
1050 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_802_11_MAC_ADDRESS) != true)
1051 {
1052 return false;
1053 }
1054
1055 wcmdr_d("CMD : GET_FW_VER_EXT (0x97)");
1056
1057 wlan_get_fw_ver_ext(3);
1058
1059 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_VERSION_EXT) != true)
1060 {
1061 return false;
1062 }
1063
1064 wcmdr_d("CMD : MAC_CTRL (0x28)");
1065
1066 wlan_set_mac_ctrl();
1067
1068 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_MAC_CONTROL) != true)
1069 {
1070 return false;
1071 }
1072
1073 wcmdr_d("CMD : GET_FW_VER_EXT (0x97)");
1074
1075 wlan_get_fw_ver_ext(4);
1076
1077 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_VERSION_EXT) != true)
1078 {
1079 return false;
1080 }
1081
1082 wcmdr_d("CMD : 11N_CFG (0xcd)");
1083 wlan_set_11n_cfg();
1084
1085 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_11N_CFG) != true)
1086 {
1087 return false;
1088 }
1089
1090 #if CONFIG_AMSDU_IN_AMPDU
1091 wcmdr_d("CMD : AMSDU_AGGR_CTRL (0xdf)");
1092 wlan_enable_amsdu();
1093
1094 if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_AMSDU_AGGR_CTRL) != true)
1095 {
1096 return false;
1097 }
1098 #endif
1099
1100 return true;
1101 }
1102
wlan_send_imu_cmd(t_u8 * buf)1103 int wlan_send_imu_cmd(t_u8 *buf)
1104 {
1105 IMUPkt *imu_cmd = (IMUPkt *)outbuf;
1106
1107 wifi_imu_lock();
1108
1109 (void)memcpy(outbuf, buf, MIN(WIFI_FW_CMDBUF_SIZE, IMU_OUTBUF_LEN));
1110 imu_cmd->pkttype = MLAN_TYPE_CMD;
1111 imu_cmd->size = imu_cmd->hostcmd.size + INTF_HEADER_LEN;
1112 wifi_send_fw_cmd(imu_cmd->hostcmd.command, (uint8_t *)outbuf, imu_cmd->size);
1113
1114 last_cmd_sent = imu_cmd->hostcmd.command;
1115 wifi_imu_unlock();
1116
1117 return WM_SUCCESS;
1118 }
1119
wifi_send_cmdbuffer(void)1120 int wifi_send_cmdbuffer(void)
1121 {
1122 return wlan_send_imu_cmd(cmd_buf);
1123 }
1124
wifi_get_imu_outbuf(uint32_t * outbuf_len)1125 uint8_t *wifi_get_imu_outbuf(uint32_t *outbuf_len)
1126 {
1127 *outbuf_len = sizeof(outbuf);
1128 return outbuf;
1129 }
1130 #if CONFIG_AMSDU_IN_AMPDU
wifi_get_amsdu_outbuf(uint32_t offset)1131 uint8_t *wifi_get_amsdu_outbuf(uint32_t offset)
1132 {
1133 return (amsdu_outbuf + offset);
1134 }
1135 #endif
1136 t_u16 get_mp_end_port(void);
wlan_xmit_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface,t_u32 tx_control)1137 mlan_status wlan_xmit_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface, t_u32 tx_control)
1138 {
1139 int ret;
1140
1141 wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1142
1143 process_pkt_hdrs((t_u8 *)buffer, txlen, interface, 0, tx_control);
1144 /* send tx data via imu */
1145 ret = wifi_send_fw_data(buffer, txlen);
1146
1147 if (ret != kStatus_HAL_RpmsgSuccess)
1148 {
1149 wifi_io_e("Send tx data via imu failed (%d)", ret);
1150 #if CONFIG_WIFI_FW_DEBUG
1151 #if 0
1152 if (wm_wifi.wifi_usb_mount_cb != NULL)
1153 {
1154 ret = wm_wifi.wifi_usb_mount_cb();
1155 if (ret == WM_SUCCESS)
1156 wifi_dump_firmware_info(NULL);
1157 else
1158 wifi_e("USB mounting failed");
1159 }
1160 else
1161 wifi_e("USB mount callback is not registered");
1162 #endif
1163 wifi_dump_firmware_info();
1164 #endif
1165 return MLAN_STATUS_FAILURE;
1166 }
1167 return MLAN_STATUS_SUCCESS;
1168 }
1169
1170 #if CONFIG_WMM
wlan_xmit_bypass_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface)1171 mlan_status wlan_xmit_bypass_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface)
1172 {
1173 int ret;
1174
1175 wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1176
1177 wifi_imu_lock();
1178 /* send tx data via imu */
1179 ret = wifi_send_fw_data(buffer, txlen);
1180
1181 if (ret != kStatus_HAL_RpmsgSuccess)
1182 {
1183 wifi_io_e("Send tx data via imu failed (%d)", ret);
1184 #if CONFIG_WIFI_FW_DEBUG
1185 #if 0
1186 if (wm_wifi.wifi_usb_mount_cb != NULL)
1187 {
1188 ret = wm_wifi.wifi_usb_mount_cb();
1189 if (ret == WM_SUCCESS)
1190 wifi_dump_firmware_info(NULL);
1191 else
1192 wifi_e("USB mounting failed");
1193 }
1194 else
1195 wifi_e("USB mount callback is not registered");
1196 #endif
1197 wifi_dump_firmware_info();
1198 #endif
1199
1200 wifi_imu_unlock();
1201 return MLAN_STATUS_FAILURE;
1202 }
1203
1204 wifi_imu_unlock();
1205 return MLAN_STATUS_SUCCESS;
1206 }
1207 #endif
1208
1209 #if CONFIG_WMM
wlan_xmit_wmm_pkt(t_u8 interface,t_u32 txlen,t_u8 * tx_buf)1210 mlan_status wlan_xmit_wmm_pkt(t_u8 interface, t_u32 txlen, t_u8 *tx_buf)
1211 {
1212 int ret;
1213 #if CONFIG_WMM_UAPSD
1214 bool last_packet = 0;
1215 #endif
1216
1217 wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1218
1219 wifi_imu_lock();
1220 #if CONFIG_WMM_UAPSD
1221 if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1222 wifi_check_last_packet_indication(mlan_adap->priv[interface]))
1223 {
1224 #if CONFIG_TX_RX_ZERO_COPY
1225 process_pkt_hdrs_flags(&((outbuf_t *)tx_buf)->intf_header[0], MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1226 #else
1227 process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1228 #endif
1229 last_packet = 1;
1230 }
1231 #endif
1232
1233 #if CONFIG_TX_RX_ZERO_COPY
1234 ret = HAL_ImuAddWlanTxPacketExt(kIMU_LinkCpu1Cpu3, tx_buf, txlen, net_tx_zerocopy_process_cb);
1235 #else
1236 ret = HAL_ImuAddWlanTxPacket(kIMU_LinkCpu1Cpu3, tx_buf, txlen);
1237 #endif
1238
1239 if (ret != kStatus_HAL_RpmsgSuccess)
1240 {
1241 #if CONFIG_WMM_UAPSD
1242 if (last_packet)
1243 {
1244 #if CONFIG_TX_RX_ZERO_COPY
1245 process_pkt_hdrs_flags(&((outbuf_t *)tx_buf)->intf_header[0], 0);
1246 #else
1247 process_pkt_hdrs_flags((t_u8 *)tx_buf, 0);
1248 #endif
1249 }
1250 #endif
1251
1252 wifi_imu_unlock();
1253 return MLAN_STATUS_FAILURE;
1254 }
1255
1256 #if CONFIG_WMM_UAPSD
1257 if (last_packet)
1258 {
1259 mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1260 OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1261 }
1262 #endif
1263
1264 wifi_imu_unlock();
1265 return MLAN_STATUS_SUCCESS;
1266 }
1267
wlan_flush_wmm_pkt(int pkt_cnt)1268 mlan_status wlan_flush_wmm_pkt(int pkt_cnt)
1269 {
1270 int ret;
1271
1272 if (pkt_cnt == 0)
1273 return MLAN_STATUS_SUCCESS;
1274
1275 w_pkt_d("Data TX: Driver=>FW, pkt_cnt %d", pkt_cnt);
1276
1277 ret = HAL_ImuSendMultiTxData(kIMU_LinkCpu1Cpu3);
1278 ;
1279 if (ret != kStatus_HAL_RpmsgSuccess)
1280 {
1281 wifi_io_e("wlan_flush_wmm_pkt failed (%d)", ret);
1282 #if CONFIG_WIFI_FW_DEBUG
1283 #if 0
1284 if (wm_wifi.wifi_usb_mount_cb != NULL)
1285 {
1286 ret = wm_wifi.wifi_usb_mount_cb();
1287 if (ret == WM_SUCCESS)
1288 wifi_dump_firmware_info(NULL);
1289 else
1290 wifi_e("USB mounting failed");
1291 }
1292 else
1293 wifi_e("USB mount callback is not registered");
1294 #endif
1295 wifi_dump_firmware_info();
1296 #endif
1297 return MLAN_STATUS_FAILURE;
1298 }
1299 return MLAN_STATUS_SUCCESS;
1300 }
1301
1302 #if CONFIG_AMSDU_IN_AMPDU
1303 /**
1304 * @brief This function checks if we need to send last amsdu indication.
1305 *
1306 * @param priv A pointer to mlan_private structure
1307 *
1308 * @return MTRUE or MFALSE
1309 */
wifi_check_last_amsdu_packet_indication(mlan_private * priv,t_u8 amsdu_cnt)1310 static t_u8 wifi_check_last_amsdu_packet_indication(mlan_private *priv, t_u8 amsdu_cnt)
1311 {
1312 if ((wifi_wmm_get_packet_cnt() == amsdu_cnt) && priv->wmm_qosinfo && priv->curr_bss_params.wmm_uapsd_enabled)
1313 return TRUE;
1314 else
1315 return FALSE;
1316 }
1317
wlan_xmit_wmm_amsdu_pkt(mlan_wmm_ac_e ac,t_u8 interface,t_u32 txlen,t_u8 * tx_buf,t_u8 amsdu_cnt)1318 mlan_status wlan_xmit_wmm_amsdu_pkt(mlan_wmm_ac_e ac, t_u8 interface, t_u32 txlen, t_u8 *tx_buf, t_u8 amsdu_cnt)
1319 {
1320 int ret;
1321 #if CONFIG_WMM_UAPSD
1322 bool last_packet = 0;
1323 #endif
1324
1325 wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1326
1327 wifi_imu_lock();
1328 #if defined(RW610)
1329 process_amsdu_pkt_hdrs((t_u8 *)tx_buf, txlen, ac, interface);
1330 #if CONFIG_WMM_UAPSD
1331 if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1332 wifi_check_last_amsdu_packet_indication(mlan_adap->priv[interface], amsdu_cnt))
1333 {
1334 process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1335 last_packet = 1;
1336 }
1337 #endif
1338 #else
1339 process_amsdu_pkt_hdrs((t_u8 *)tx_buf, txlen, ac);
1340 #endif
1341
1342 ret = HAL_ImuAddWlanTxPacket(kIMU_LinkCpu1Cpu3, tx_buf, txlen);
1343
1344 if (ret != kStatus_HAL_RpmsgSuccess)
1345 {
1346 #if CONFIG_WMM_UAPSD
1347 if (last_packet)
1348 process_pkt_hdrs_flags((t_u8 *)tx_buf, 0);
1349 #endif
1350 wifi_imu_unlock();
1351 return MLAN_STATUS_FAILURE;
1352 }
1353
1354 #if CONFIG_WMM_UAPSD
1355 if (last_packet)
1356 {
1357 mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1358 OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1359 }
1360 #endif
1361
1362 wifi_imu_unlock();
1363 return MLAN_STATUS_SUCCESS;
1364 }
1365 #endif
1366 #endif
1367
wlan_send_null_packet(pmlan_private priv,t_u8 flags)1368 mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
1369 {
1370 int ret;
1371 t_u8 pbuf[32] = {0};
1372 TxPD *ptxpd = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
1373
1374 ptxpd->bss_type = priv->bss_type;
1375 ptxpd->bss_num = GET_BSS_NUM(priv);
1376 ptxpd->tx_pkt_offset = 0x16; /* we'll just make this constant */
1377 ptxpd->tx_pkt_length = 0;
1378 ptxpd->tx_control = 0;
1379 ptxpd->priority = 0;
1380 ptxpd->flags = flags;
1381 ptxpd->pkt_delay_2ms = 0;
1382
1383 ret = wifi_send_fw_data(pbuf, sizeof(TxPD) + INTF_HEADER_LEN);
1384 if (ret != kStatus_HAL_RpmsgSuccess)
1385 {
1386 wifi_io_e("imu_drv_write failed (%d)", ret);
1387 return MLAN_STATUS_FAILURE;
1388 }
1389
1390 return MLAN_STATUS_SUCCESS;
1391 }
1392
rpmsg_cmdrsp_handler(IMU_Msg_t * pImuMsg,uint32_t length)1393 hal_rpmsg_status_t rpmsg_cmdrsp_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1394 {
1395 assert(NULL != pImuMsg);
1396 assert(0 != length);
1397 assert(IMU_MSG_COMMAND_RESPONSE == pImuMsg->Hdr.type);
1398
1399 #if CONFIG_HOST_SLEEP
1400 if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1401 {
1402 wakeup_by = WAKEUP_BY_WLAN;
1403 mlan_adap->wlan_wakeup.type = IMU_MSG_COMMAND_RESPONSE;
1404 mlan_adap->wlan_wakeup.subtype = 0;
1405 mlan_adap->wlan_wakeup.id = *(uint16_t *)((uint8_t *)pImuMsg->PayloadPtr[0] + 4);
1406 POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1407 }
1408 #endif
1409
1410 wlan_decode_rx_packet((t_u8 *)pImuMsg->PayloadPtr[0], MLAN_TYPE_CMD);
1411
1412 return kStatus_HAL_RpmsgSuccess;
1413 }
1414
rpmsg_event_handler(IMU_Msg_t * pImuMsg,uint32_t length)1415 hal_rpmsg_status_t rpmsg_event_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1416 {
1417 assert(NULL != pImuMsg);
1418 assert(0 != length);
1419 assert(IMU_MSG_EVENT == pImuMsg->Hdr.type);
1420
1421 #if CONFIG_HOST_SLEEP
1422 if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1423 {
1424 wakeup_by = WAKEUP_BY_WLAN;
1425 mlan_adap->wlan_wakeup.type = IMU_MSG_EVENT;
1426 mlan_adap->wlan_wakeup.subtype = 0;
1427 mlan_adap->wlan_wakeup.id = *(uint16_t *)((uint8_t *)pImuMsg->PayloadPtr[0] + 4);
1428 POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1429 }
1430 #endif
1431
1432 #if CONFIG_CSI
1433 if (EVENT_CSI == *((t_u8 *)pImuMsg->PayloadPtr[0] + 4))
1434 {
1435 csi_save_data_to_local_buff((t_u8 *)pImuMsg->PayloadPtr[0] + 8);
1436 }
1437 #endif
1438
1439 wlan_decode_rx_packet((t_u8 *)pImuMsg->PayloadPtr[0], MLAN_TYPE_EVENT);
1440
1441 return kStatus_HAL_RpmsgSuccess;
1442 }
1443
rpmsg_rxpkt_handler(IMU_Msg_t * pImuMsg,uint32_t length)1444 hal_rpmsg_status_t rpmsg_rxpkt_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1445 {
1446 IMUPkt *inimupkt;
1447 t_u32 size;
1448 t_u8 interface;
1449 t_u8 i = 0;
1450
1451 assert(NULL != pImuMsg);
1452 assert(0 != length);
1453 assert((IMU_MSG_RX_DATA == pImuMsg->Hdr.type) || (IMU_MSG_MULTI_RX_DATA == pImuMsg->Hdr.type));
1454
1455 #if CONFIG_HOST_SLEEP
1456 wakelock_get();
1457 if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1458 {
1459 wakeup_by = WAKEUP_BY_WLAN;
1460 mlan_adap->wlan_wakeup.type = pImuMsg->Hdr.type;
1461 mlan_adap->wlan_wakeup.subtype = 0;
1462 mlan_adap->wlan_wakeup.id = 0;
1463 POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1464 }
1465 #endif
1466
1467 for (i = 0; i < pImuMsg->Hdr.length; i++)
1468 {
1469 inimupkt = (IMUPkt *)pImuMsg->PayloadPtr[i];
1470 size = inimupkt->size;
1471 if ((size <= INTF_HEADER_LEN) || (size > sizeof(inbuf)))
1472 {
1473 #if CONFIG_HOST_SLEEP
1474 wakelock_put();
1475 #endif
1476 wifi_io_e("pImuMsg->PayloadPtr[%u] has invalid size=%u", i, size);
1477 return kStatus_HAL_RpmsgError;
1478 }
1479
1480 #if !CONFIG_TX_RX_ZERO_COPY
1481 #if CONFIG_IMU_GDMA
1482 HAL_ImuGdmaCopyData(inbuf, inimupkt, size);
1483 #else
1484 memcpy(inbuf, inimupkt, size);
1485 #endif
1486 #endif
1487 interface = *((t_u8 *)inimupkt + INTF_HEADER_LEN);
1488 wifi_io_info_d("IN: i/f: %d len: %d", interface, size);
1489 w_pkt_d("Data RX: FW=>Driver, if %d, len %d", interface, size);
1490
1491 if (bus.wifi_low_level_input != NULL)
1492 #if CONFIG_TX_RX_ZERO_COPY
1493 bus.wifi_low_level_input(interface, (uint8_t *)inimupkt, size);
1494 #else
1495 bus.wifi_low_level_input(interface, inbuf, size);
1496 #endif
1497 }
1498 #if CONFIG_HOST_SLEEP
1499 wakelock_put();
1500 #endif
1501 /*! To be the last action of the handler*/
1502 return kStatus_HAL_RpmsgSuccess;
1503 }
1504
imu_fw_is_hang(void)1505 static bool imu_fw_is_hang(void)
1506 {
1507 uint32_t *peer_magic_addr = (uint32_t *)0x41380000;
1508
1509 if ((*peer_magic_addr) == 0xDEADDEAD)
1510 return true;
1511 else
1512 return false;
1513 }
1514
rpmsg_ctrl_handler(IMU_Msg_t * pImuMsg,uint32_t length)1515 hal_rpmsg_status_t rpmsg_ctrl_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1516 {
1517 t_u32 imuControlType;
1518
1519 assert(NULL != pImuMsg);
1520 assert(IMU_MSG_CONTROL == pImuMsg->Hdr.type);
1521
1522 #if CONFIG_HOST_SLEEP
1523 if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1524 {
1525 wakeup_by = WAKEUP_BY_WLAN;
1526 mlan_adap->wlan_wakeup.type = IMU_MSG_CONTROL;
1527 mlan_adap->wlan_wakeup.subtype = pImuMsg->Hdr.sub_type;
1528 mlan_adap->wlan_wakeup.id = 0;
1529 POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1530 }
1531 #endif
1532
1533 imuControlType = pImuMsg->Hdr.sub_type;
1534 switch (imuControlType)
1535 {
1536 case IMU_MSG_CONTROL_TX_BUF_ADDR:
1537 #if CONFIG_WMM
1538
1539 if (mlan_adap->wait_txbuf == true)
1540 {
1541 OSA_SemaphorePost((osa_semaphore_handle_t)txbuf_sem);
1542 }
1543
1544 send_wifi_driver_tx_data_event(0);
1545 #endif
1546 break;
1547 default:
1548 break;
1549 }
1550 return kStatus_HAL_RpmsgSuccess;
1551 }
1552
imu_wakeup_card()1553 void imu_wakeup_card()
1554 {
1555 /* Wakeup CPU1 */
1556 PMU_EnableWlanWakeup(1);
1557 }
1558
WL_MCI_WAKEUP_DONE0_DriverIRQHandler(void)1559 void WL_MCI_WAKEUP_DONE0_DriverIRQHandler(void)
1560 {
1561 IRQn_Type irq_num = WL_MCI_WAKEUP_DONE0_IRQn;
1562
1563 /* Mask IMU ICU interrupt */
1564 DisableIRQ(irq_num);
1565 /* Clear CPU1 wakeup register */
1566 PMU_DisableWlanWakeup(1);
1567 EnableIRQ(irq_num);
1568 }
1569
mlan_init_wakeup_irq()1570 void mlan_init_wakeup_irq()
1571 {
1572 }
1573
mlan_deinit_wakeup_irq()1574 void mlan_deinit_wakeup_irq()
1575 {
1576 }
1577
imu_wifi_init(enum wlan_type type,const uint8_t * fw_ram_start_addr,const size_t size)1578 mlan_status imu_wifi_init(enum wlan_type type, const uint8_t *fw_ram_start_addr, const size_t size)
1579 {
1580 mlan_status mlanstatus = MLAN_STATUS_SUCCESS;
1581 int ret = 0;
1582 int retry_cnt = 3;
1583 int retry_cnt_fw_init = 3;
1584 #ifdef RW610
1585 int temperature_val = 0;
1586 #endif
1587
1588 ret = wlan_init_struct();
1589 if (ret != WM_SUCCESS)
1590 {
1591 wifi_io_e("Init failed. Cannot create init struct");
1592 return MLAN_STATUS_FAILURE;
1593 }
1594
1595 /* Initialize the mlan subsystem before initializing 878x driver */
1596 mlan_subsys_init();
1597
1598 retry:
1599 /* Comment out this line if CPU1 image is downloaded through J-Link.
1600 * This is for load service case only.
1601 */
1602 power_off_device(LOAD_WIFI_FIRMWARE);
1603 wifi_io_d("%u IMU download WLAN FW.\n", OSA_TicksGet());
1604 /* Download firmware */
1605 ret = sb3_fw_download(LOAD_WIFI_FIRMWARE, 1, (uint32_t)fw_ram_start_addr);
1606 /* If fw download is failed, retry downloading for 3 times. */
1607 if (ret)
1608 {
1609 if (retry_cnt != 0)
1610 {
1611 retry_cnt--;
1612 goto retry;
1613 }
1614 else
1615 {
1616 wifi_io_e("Download firmware failed");
1617 mlanstatus = MLAN_STATUS_FAILURE;
1618 return mlanstatus;
1619 }
1620 }
1621 wifi_io_d("%u WLAN FW is active.\n", OSA_TicksGet());
1622 #if CONFIG_WIFI_RECOVERY
1623 if (wifi_recovery_enable)
1624 {
1625 wifi_w("WiFi recovery mode done!");
1626 wifi_recovery_enable = false;
1627 }
1628 #endif
1629 if (wifi_shutdown_enable)
1630 {
1631 wifi_shutdown_enable = false;
1632 }
1633
1634 #ifdef RW610
1635 wifi_cau_temperature_enable();
1636 temperature_val = wifi_cau_temperature_write_to_firmware();
1637 PRINTF("Wi-Fi cau temperature : %d\r\n", temperature_val);
1638 #endif
1639
1640 wifi_init_imulink();
1641
1642 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_cmdrsp_handler, IMU_MSG_COMMAND_RESPONSE);
1643
1644 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_event_handler, IMU_MSG_EVENT);
1645
1646 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_rxpkt_handler, IMU_MSG_RX_DATA);
1647
1648 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_ctrl_handler, IMU_MSG_CONTROL);
1649
1650 /* If we're running a Manufacturing image, start the tasks.
1651 If not, initialize and setup the firmware */
1652 switch (type)
1653 {
1654 case WLAN_TYPE_NORMAL:
1655 ret = wlan_fw_init_cfg();
1656 if (ret != true)
1657 {
1658 if (retry_cnt_fw_init > 0)
1659 {
1660 wifi_io_e("wlan_fw_init_cfg failed: retry %d", retry_cnt_fw_init);
1661 (void)HAL_ImuGetTaskLock();
1662 mlan_deinit_wakeup_irq();
1663 HAL_ImuDeinit(kIMU_LinkCpu1Cpu3, MBIT(1) | MBIT(0));
1664 (void)HAL_ImuPutTaskLock();
1665 retry_cnt_fw_init--;
1666 goto retry;
1667 }
1668 else
1669 {
1670 wifi_io_e("wlan_fw_init_cfg failed: return for retry done");
1671 mlanstatus = MLAN_STATUS_FAILURE;
1672 return mlanstatus;
1673 }
1674 }
1675 break;
1676 case WLAN_TYPE_WIFI_CALIB:
1677 g_txrx_flag = true;
1678 break;
1679 case WLAN_TYPE_FCC_CERTIFICATION:
1680 g_txrx_flag = true;
1681 break;
1682 default:
1683 wifi_io_e("Enter a valid input to sd_wifi_init");
1684 return MLAN_STATUS_FAILURE;
1685 }
1686
1687 mlan_init_wakeup_irq();
1688
1689 return mlanstatus;
1690 }
1691
imu_wifi_deinit(void)1692 void imu_wifi_deinit(void)
1693 {
1694 uint32_t flag = 0;
1695
1696 #ifdef WLAN_LOW_POWER_ENABLE
1697 low_power_mode = false;
1698 #endif
1699 cal_data_valid = false;
1700 mac_addr_valid = false;
1701 #if 0
1702 wlan_cmd_shutdown();
1703 // sdio_drv_deinit();
1704 #endif
1705 wlan_deinit_struct();
1706
1707 flag = MBIT(1) | MBIT(0);
1708 #if CONFIG_WIFI_RECOVERY
1709 flag |= wifi_recovery_enable;
1710 #endif
1711
1712 mlan_deinit_wakeup_irq();
1713 HAL_ImuDeinit(kIMU_LinkCpu1Cpu3, flag);
1714
1715 mlan_subsys_deinit();
1716 }
1717
imu_uninstall_callback(void)1718 void imu_uninstall_callback(void)
1719 {
1720 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_COMMAND_RESPONSE);
1721 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_EVENT);
1722 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_RX_DATA);
1723 HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_CONTROL);
1724 }
1725
wifi_get_command_buffer()1726 HostCmd_DS_COMMAND *wifi_get_command_buffer()
1727 {
1728 /* First 4 bytes reserved for SDIO pkt header */
1729 return (HostCmd_DS_COMMAND *)(cmd_buf + INTF_HEADER_LEN);
1730 }
1731
1732 bus_operations imu_ops = {
1733 .fw_is_hang = imu_fw_is_hang,
1734 .intf_header_len = INTF_HEADER_LEN,
1735 };
1736
imu_create_task_lock(void)1737 int imu_create_task_lock(void)
1738 {
1739 int ret = 0;
1740
1741 ret = HAL_ImuCreateTaskLock();
1742 if (ret != WM_SUCCESS)
1743 {
1744 wifi_e("Create imu task lock failed.");
1745 return -WM_FAIL;
1746 }
1747
1748 return WM_SUCCESS;
1749 }
1750
imu_delete_task_lock(void)1751 void imu_delete_task_lock(void)
1752 {
1753 HAL_ImuDeleteTaskLock();
1754 }
1755
imu_get_task_lock(void)1756 int imu_get_task_lock(void)
1757 {
1758 int ret = 0;
1759
1760 ret = HAL_ImuGetTaskLock();
1761 if (ret != WM_SUCCESS)
1762 {
1763 wifi_d("Get imu task lock failed.");
1764 return -WM_FAIL;
1765 }
1766
1767 return WM_SUCCESS;
1768 }
1769
imu_put_task_lock(void)1770 int imu_put_task_lock(void)
1771 {
1772 int ret = 0;
1773
1774 ret = HAL_ImuPutTaskLock();
1775 if (ret != WM_SUCCESS)
1776 {
1777 wifi_d("Put imu task lock failed.");
1778 return -WM_FAIL;
1779 }
1780
1781 return WM_SUCCESS;
1782 }
1783
1784 #if CONFIG_HOST_SLEEP
wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)1785 void wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)
1786 {
1787 ARG_UNUSED(hs_wakeup_reason);
1788 if (mlan_adap->wlan_wakeup.type == IMU_MSG_CONTROL)
1789 PRINTF("Woken up by WLAN(IMU ctrl msg subtype 0x%x)\r\n", mlan_adap->wlan_wakeup.subtype);
1790 else if (mlan_adap->wlan_wakeup.type == IMU_MSG_COMMAND_RESPONSE)
1791 PRINTF("Woken up by WLAN(command response 0x%x)\r\n", mlan_adap->wlan_wakeup.id);
1792 else if (mlan_adap->wlan_wakeup.type == IMU_MSG_EVENT)
1793 PRINTF("Woken up by WLAN(event 0x%x)\r\n", mlan_adap->wlan_wakeup.id);
1794 else if (mlan_adap->wlan_wakeup.type == IMU_MSG_RX_DATA || mlan_adap->wlan_wakeup.type == IMU_MSG_MULTI_RX_DATA)
1795 PRINTF("Woken up by WLAN(Rx data)\r\n");
1796 }
1797
wifi_clear_wakeup_reason(void)1798 void wifi_clear_wakeup_reason(void)
1799 {
1800 if (mlan_adap != NULL)
1801 {
1802 memset(&mlan_adap->wlan_wakeup, 0x0, sizeof(wlan_wakeup_reason));
1803 }
1804 }
1805 #endif
1806