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 #if !defined(OVERRIDE_CALIBRATION_DATA)
479             t_u32 fw_cap_ext_rw610;
480             fw_cap_ext_rw610 = mlan_adap->priv[0]->adapter->fw_cap_ext;
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 
689 #if UAP_SUPPORT
wlan_get_mac_addr_uap()690 static int wlan_get_mac_addr_uap()
691 {
692     int seq_number = 0;
693 
694     seq_number = HostCmd_SET_SEQ_NO_BSS_INFO(0 /* seq_num */, 0 /* bss_num */, MLAN_BSS_TYPE_UAP);
695     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
696 
697     /* imupkt = outbuf */
698     wifi_prepare_get_mac_addr_cmd(&imupkt->hostcmd, seq_number);
699 
700     imupkt->pkttype = MLAN_TYPE_CMD;
701     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
702 
703     last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
704 
705     /* send CMD53 to write the command to get mac address */
706     wifi_send_fw_cmd(HostCmd_CMD_802_11_MAC_ADDRESS, (uint8_t *)outbuf, imupkt->size);
707     return true;
708 }
709 #endif
710 
711 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)712 static int wlan_get_fw_ver_ext(int version_str_sel)
713 {
714     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
715 
716     /* imupkt = outbuf */
717     wifi_prepare_get_fw_ver_ext_cmd(&imupkt->hostcmd, wlan_get_next_seq_num(), version_str_sel);
718 
719     imupkt->pkttype = MLAN_TYPE_CMD;
720     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
721 
722     last_cmd_sent = HostCmd_CMD_VERSION_EXT;
723 
724     /* send CMD53 to write the command to get mac address */
725     wifi_send_fw_cmd(HostCmd_CMD_VERSION_EXT, (uint8_t *)outbuf, imupkt->size);
726     return true;
727 }
728 
729 void wifi_prepare_get_value1(void *cmd, int seq_number);
730 
wlan_get_value1()731 static int wlan_get_value1()
732 {
733     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
734 
735     /* imupkt = outbuf */
736     wifi_prepare_get_value1(&imupkt->hostcmd, wlan_get_next_seq_num());
737 
738     imupkt->pkttype = MLAN_TYPE_CMD;
739     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
740 
741     last_cmd_sent = HostCmd_CMD_MAC_REG_ACCESS;
742     wifi_send_fw_cmd(HostCmd_CMD_MAC_REG_ACCESS, (uint8_t *)outbuf, imupkt->size);
743     return true;
744 }
745 
746 void wifi_prepare_set_mac_addr_cmd(void *cmd, int seq_number);
_wlan_set_mac_addr()747 static int _wlan_set_mac_addr()
748 {
749     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
750 
751     /* imupkt = outbuf */
752     wifi_prepare_set_mac_addr_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
753 
754     imupkt->pkttype = MLAN_TYPE_CMD;
755     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
756 
757     last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
758 
759     /* send CMD53 to write the command to get mac address */
760     wifi_send_fw_cmd(HostCmd_CMD_802_11_MAC_ADDRESS, (uint8_t *)outbuf, imupkt->size);
761     return true;
762 }
763 
wlan_set_11n_cfg()764 static int wlan_set_11n_cfg()
765 {
766     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
767     wrapper_wlan_cmd_11n_cfg(&imupkt->hostcmd);
768     /* imupkt = outbuf */
769     imupkt->hostcmd.seq_num = wlan_get_next_seq_num();
770     imupkt->pkttype         = MLAN_TYPE_CMD;
771     imupkt->size            = imupkt->hostcmd.size + INTF_HEADER_LEN;
772     last_cmd_sent           = HostCmd_CMD_11N_CFG;
773     wifi_send_fw_cmd(HostCmd_CMD_11N_CFG, (uint8_t *)outbuf, imupkt->size);
774 
775     return true;
776 }
777 
778 #if CONFIG_WIFI_TX_BUFF
_wlan_return_all_tx_buf(imu_link_t link)779 int _wlan_return_all_tx_buf(imu_link_t link)
780 {
781     HAL_ImuReturnAllTxBuf(link);
782 
783     return true;
784 }
785 
786 void wifi_prepare_set_tx_buf_size(void *cmd, int seq_number);
_wlan_recfg_tx_buf_size(uint16_t buf_size)787 static int _wlan_recfg_tx_buf_size(uint16_t buf_size)
788 {
789     wifi_calibrate_tx_buf_size(buf_size);
790 
791     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
792 
793     /* imupkt = outbuf */
794     wifi_prepare_set_tx_buf_size(&imupkt->hostcmd, wlan_get_next_seq_num());
795 
796     imupkt->pkttype = MLAN_TYPE_CMD;
797     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
798 
799     last_cmd_sent = HostCmd_CMD_RECONFIGURE_TX_BUFF;
800 
801     wifi_send_fw_cmd(HostCmd_CMD_RECONFIGURE_TX_BUFF, (uint8_t *)outbuf, imupkt->size);
802 
803     return true;
804 }
805 #endif
806 
807 #if CONFIG_AMSDU_IN_AMPDU
808 void wifi_prepare_enable_amsdu_cmd(void *cmd, int seq_number);
wlan_enable_amsdu()809 static int wlan_enable_amsdu()
810 {
811     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
812 
813     /* imupkt = outbuf */
814     wifi_prepare_enable_amsdu_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
815 
816     imupkt->pkttype = MLAN_TYPE_CMD;
817     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
818 
819     last_cmd_sent = HostCmd_CMD_AMSDU_AGGR_CTRL;
820 
821     wifi_send_fw_cmd(HostCmd_CMD_AMSDU_AGGR_CTRL, (uint8_t *)outbuf, imupkt->size);
822 
823     return true;
824 }
825 #endif
826 /* This function was only used in imu_wifi_deinit, and now is replaced by wifi_send_shutdown_cmd with the same 0xaa cmd
827  */
828 #if 0
829 static int wlan_cmd_shutdown()
830 {
831     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
832 
833     /* imupkt = outbuf */
834     imupkt->hostcmd.command = HostCmd_CMD_FUNC_SHUTDOWN;
835     imupkt->hostcmd.size    = S_DS_GEN;
836     imupkt->hostcmd.seq_num = wlan_get_next_seq_num();
837     imupkt->hostcmd.result  = 0;
838 
839     imupkt->pkttype = MLAN_TYPE_CMD;
840     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
841 
842     last_cmd_sent = HostCmd_CMD_FUNC_SHUTDOWN;
843 
844     wifi_send_fw_cmd(HostCmd_CMD_FUNC_SHUTDOWN, (uint8_t *)outbuf, imupkt->size);
845 
846     return true;
847 }
848 #endif
849 
850 void wlan_prepare_mac_control_cmd(void *cmd, int seq_number);
wlan_set_mac_ctrl()851 static int wlan_set_mac_ctrl()
852 {
853     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
854 
855     /* imupkt = outbuf */
856     wlan_prepare_mac_control_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
857 
858     imupkt->pkttype = MLAN_TYPE_CMD;
859     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
860 
861     last_cmd_sent = HostCmd_CMD_MAC_CONTROL;
862 
863     wifi_send_fw_cmd(HostCmd_CMD_MAC_CONTROL, (uint8_t *)outbuf, imupkt->size);
864 
865     return true;
866 }
867 
wlan_cmd_init()868 static int wlan_cmd_init()
869 {
870     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
871 
872     /* imupkt = outbuf */
873     imupkt->hostcmd.command = HostCmd_CMD_FUNC_INIT;
874     imupkt->hostcmd.size    = S_DS_GEN;
875     imupkt->hostcmd.seq_num = wlan_get_next_seq_num();
876     imupkt->hostcmd.result  = 0;
877 
878     imupkt->pkttype = MLAN_TYPE_CMD;
879     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
880 
881     last_cmd_sent = HostCmd_CMD_FUNC_INIT;
882 
883     wifi_send_fw_cmd(HostCmd_CMD_FUNC_INIT, (uint8_t *)outbuf, imupkt->size);
884 
885     return true;
886 }
887 
888 #ifdef WLAN_LOW_POWER_ENABLE
889 void wifi_prepare_low_power_mode_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
wlan_set_low_power_mode()890 static int wlan_set_low_power_mode()
891 {
892     (void)memset(outbuf, 0, IMU_INIT_FW_CMD_SIZE);
893 
894     /* imupkt = outbuf */
895 
896     wifi_prepare_low_power_mode_cmd(&imupkt->hostcmd, wlan_get_next_seq_num());
897 
898     imupkt->pkttype = MLAN_TYPE_CMD;
899     imupkt->size    = imupkt->hostcmd.size + INTF_HEADER_LEN;
900 
901     last_cmd_sent = HostCmd_CMD_LOW_POWER_MODE;
902 
903     wifi_send_fw_cmd(HostCmd_CMD_LOW_POWER_MODE, (uint8_t *)outbuf, imupkt->size);
904     return true;
905 }
906 #endif
907 
wlan_wait_for_last_resp_rcvd(t_u16 command)908 static int wlan_wait_for_last_resp_rcvd(t_u16 command)
909 {
910     int retry_cnt = WIFI_COMMAND_RESPONSE_WAIT_MS / WIFI_POLL_CMD_RESP_TIME;
911 
912     while ((last_resp_rcvd != command) && (retry_cnt > 0))
913     {
914         OSA_TimeDelay(WIFI_POLL_CMD_RESP_TIME);
915         retry_cnt--;
916     }
917 
918     if (last_resp_rcvd == command)
919     {
920         return true;
921     }
922     else
923     {
924         wifi_io_e("%s: wait cmd 0x%x fail (last 0x%x)", __FUNCTION__, command, last_resp_rcvd);
925         return false;
926     }
927 }
928 
929 // mlan_status wlan_process_int_status(mlan_adapter *pmadapter);
930 /* Setup the firmware with commands */
wlan_fw_init_cfg()931 static int wlan_fw_init_cfg()
932 {
933     wcmdr_d("FWCMD : INIT (0xa9)");
934 
935     /* Add while loop here to wait until command buffer has been attached */
936     while (HAL_ImuLinkIsUp(kIMU_LinkCpu1Cpu3) != 0)
937     {
938         OSA_TimeDelay(WIFI_POLL_CMD_RESP_TIME);
939     }
940 
941     wlan_cmd_init();
942 
943     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_FUNC_INIT) != true)
944     {
945         return false;
946     }
947 
948 #ifdef WLAN_LOW_POWER_ENABLE
949     if (low_power_mode)
950     {
951         wcmdr_d("CMD : LOW_POWER_MODE (0x128)");
952 
953         wlan_set_low_power_mode();
954 
955         if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_LOW_POWER_MODE) != true)
956         {
957             return false;
958         }
959     }
960 #endif
961 
962     if (mac_addr_valid)
963     {
964         wcmdr_d("CMD : SET_MAC_ADDR (0x4d)");
965 
966         _wlan_set_mac_addr();
967 
968         if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_802_11_MAC_ADDRESS) != true)
969         {
970             return false;
971         }
972     }
973 
974 #ifdef OTP_CHANINFO
975     wcmdr_d("CMD : Channel Region CFG (0x0242)");
976 
977     wlan_get_channel_region_cfg();
978 
979     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_CHAN_REGION_CFG) != true)
980     {
981         return false;
982     }
983 #endif
984 
985     wcmdr_d("CMD : GET_HW_SPEC (0x03)");
986 
987     wlan_get_hw_spec();
988 
989     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_GET_HW_SPEC) != true)
990     {
991         return false;
992     }
993     if (cal_data_valid
994 #ifdef RW610
995         && !cal_data_valid_rw610
996 #endif
997     )
998     {
999         wcmdr_d("CMD : SET_CAL_DATA (0x8f)");
1000 
1001         _wlan_set_cal_data();
1002 
1003         if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_CFG_DATA) != true)
1004         {
1005             return false;
1006         }
1007     }
1008 
1009 #if CONFIG_WIFI_TX_BUFF
1010     // TODO:Reconfig tx buffer size to 4K
1011     wcmdr_d("CMD : RECONFIGURE_TX_BUFF (0xd9)");
1012 
1013     _wlan_recfg_tx_buf_size(tx_buf_size);
1014 
1015     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_RECONFIGURE_TX_BUFF) != true)
1016     {
1017         return false;
1018     }
1019 #endif
1020 
1021     wcmdr_d("CMD : MAC_REG_ACCESS (0x19)");
1022 
1023     wlan_get_value1();
1024 
1025     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_MAC_REG_ACCESS) != true)
1026     {
1027         return false;
1028     }
1029 
1030     wcmdr_d("CMD : GET_FW_VER_EXT (0x97)");
1031 
1032     wlan_get_fw_ver_ext(0);
1033 
1034     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_VERSION_EXT) != true)
1035     {
1036         return false;
1037     }
1038 
1039     wcmdr_d("CMD : GET_MAC_ADDR (0x4d)");
1040 
1041     wlan_get_mac_addr_sta();
1042 
1043     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_802_11_MAC_ADDRESS) != true)
1044     {
1045         return false;
1046     }
1047 
1048 #if UAP_SUPPORT
1049     last_resp_rcvd = 0;
1050 
1051     wlan_get_mac_addr_uap();
1052 
1053     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_802_11_MAC_ADDRESS) != true)
1054     {
1055         return false;
1056     }
1057 #endif
1058 
1059     wcmdr_d("CMD : GET_FW_VER_EXT (0x97)");
1060 
1061     wlan_get_fw_ver_ext(3);
1062 
1063     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_VERSION_EXT) != true)
1064     {
1065         return false;
1066     }
1067 
1068     wcmdr_d("CMD : MAC_CTRL (0x28)");
1069 
1070     wlan_set_mac_ctrl();
1071 
1072     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_MAC_CONTROL) != true)
1073     {
1074         return false;
1075     }
1076 
1077     wcmdr_d("CMD : GET_FW_VER_EXT (0x97)");
1078 
1079     wlan_get_fw_ver_ext(4);
1080 
1081     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_VERSION_EXT) != true)
1082     {
1083         return false;
1084     }
1085 
1086     wcmdr_d("CMD : 11N_CFG (0xcd)");
1087     wlan_set_11n_cfg();
1088 
1089     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_11N_CFG) != true)
1090     {
1091         return false;
1092     }
1093 
1094 #if CONFIG_AMSDU_IN_AMPDU
1095     wcmdr_d("CMD : AMSDU_AGGR_CTRL (0xdf)");
1096     wlan_enable_amsdu();
1097 
1098     if (wlan_wait_for_last_resp_rcvd(HostCmd_CMD_AMSDU_AGGR_CTRL) != true)
1099     {
1100         return false;
1101     }
1102 #endif
1103 
1104     return true;
1105 }
1106 
wlan_send_imu_cmd(t_u8 * buf)1107 int wlan_send_imu_cmd(t_u8 *buf)
1108 {
1109     IMUPkt *imu_cmd = (IMUPkt *)outbuf;
1110 
1111     wifi_imu_lock();
1112 
1113     (void)memcpy(outbuf, buf, MIN(WIFI_FW_CMDBUF_SIZE, IMU_OUTBUF_LEN));
1114     imu_cmd->pkttype = MLAN_TYPE_CMD;
1115     imu_cmd->size    = imu_cmd->hostcmd.size + INTF_HEADER_LEN;
1116     wifi_send_fw_cmd(imu_cmd->hostcmd.command, (uint8_t *)outbuf, imu_cmd->size);
1117 
1118     last_cmd_sent = imu_cmd->hostcmd.command;
1119     wifi_imu_unlock();
1120 
1121     return WM_SUCCESS;
1122 }
1123 
wifi_send_cmdbuffer(void)1124 int wifi_send_cmdbuffer(void)
1125 {
1126     return wlan_send_imu_cmd(cmd_buf);
1127 }
1128 
wifi_get_imu_outbuf(uint32_t * outbuf_len)1129 uint8_t *wifi_get_imu_outbuf(uint32_t *outbuf_len)
1130 {
1131     *outbuf_len = sizeof(outbuf);
1132     return outbuf;
1133 }
1134 #if CONFIG_AMSDU_IN_AMPDU
wifi_get_amsdu_outbuf(uint32_t offset)1135 uint8_t *wifi_get_amsdu_outbuf(uint32_t offset)
1136 {
1137     return (amsdu_outbuf + offset);
1138 }
1139 #endif
1140 t_u16 get_mp_end_port(void);
wlan_xmit_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface,t_u32 tx_control)1141 mlan_status wlan_xmit_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface, t_u32 tx_control)
1142 {
1143     int ret;
1144 
1145     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1146 
1147     process_pkt_hdrs((t_u8 *)buffer, txlen, interface, 0, tx_control);
1148     /* send tx data via imu */
1149     ret = wifi_send_fw_data(buffer, txlen);
1150 
1151     if (ret != kStatus_HAL_RpmsgSuccess)
1152     {
1153         wifi_io_e("Send tx data via imu failed (%d)", ret);
1154 #if CONFIG_WIFI_FW_DEBUG
1155 #if 0
1156         if (wm_wifi.wifi_usb_mount_cb != NULL)
1157         {
1158             ret = wm_wifi.wifi_usb_mount_cb();
1159             if (ret == WM_SUCCESS)
1160                 wifi_dump_firmware_info(NULL);
1161             else
1162                 wifi_e("USB mounting failed");
1163         }
1164         else
1165             wifi_e("USB mount callback is not registered");
1166 #endif
1167         wifi_dump_firmware_info();
1168 #endif
1169         return MLAN_STATUS_FAILURE;
1170     }
1171     return MLAN_STATUS_SUCCESS;
1172 }
1173 
1174 #if CONFIG_WMM
wlan_xmit_bypass_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface)1175 mlan_status wlan_xmit_bypass_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface)
1176 {
1177     int ret;
1178 
1179     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1180 
1181     wifi_imu_lock();
1182     /* send tx data via imu */
1183     ret = wifi_send_fw_data(buffer, txlen);
1184 
1185     if (ret != kStatus_HAL_RpmsgSuccess)
1186     {
1187         wifi_io_e("Send tx data via imu failed (%d)", ret);
1188 #if CONFIG_WIFI_FW_DEBUG
1189 #if 0
1190         if (wm_wifi.wifi_usb_mount_cb != NULL)
1191         {
1192             ret = wm_wifi.wifi_usb_mount_cb();
1193             if (ret == WM_SUCCESS)
1194                 wifi_dump_firmware_info(NULL);
1195             else
1196                 wifi_e("USB mounting failed");
1197         }
1198         else
1199             wifi_e("USB mount callback is not registered");
1200 #endif
1201         wifi_dump_firmware_info();
1202 #endif
1203 
1204         wifi_imu_unlock();
1205         return MLAN_STATUS_FAILURE;
1206     }
1207 
1208     wifi_imu_unlock();
1209     return MLAN_STATUS_SUCCESS;
1210 }
1211 #endif
1212 
1213 #if CONFIG_WMM
wlan_xmit_wmm_pkt(t_u8 interface,t_u32 txlen,t_u8 * tx_buf)1214 mlan_status wlan_xmit_wmm_pkt(t_u8 interface, t_u32 txlen, t_u8 *tx_buf)
1215 {
1216     int ret;
1217 #if CONFIG_WMM_UAPSD
1218     bool last_packet = 0;
1219 #endif
1220 
1221     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1222 
1223     wifi_imu_lock();
1224 #if CONFIG_WMM_UAPSD
1225     if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1226         wifi_check_last_packet_indication(mlan_adap->priv[interface]))
1227     {
1228 #if CONFIG_TX_RX_ZERO_COPY
1229         process_pkt_hdrs_flags(&((outbuf_t *)tx_buf)->intf_header[0], MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1230 #else
1231         process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1232 #endif
1233         last_packet = 1;
1234     }
1235 #endif
1236 
1237 #if CONFIG_TX_RX_ZERO_COPY
1238     ret = HAL_ImuAddWlanTxPacketExt(kIMU_LinkCpu1Cpu3, tx_buf, txlen, net_tx_zerocopy_process_cb);
1239 #else
1240     ret              = HAL_ImuAddWlanTxPacket(kIMU_LinkCpu1Cpu3, tx_buf, txlen);
1241 #endif
1242 
1243     if (ret != kStatus_HAL_RpmsgSuccess)
1244     {
1245 #if CONFIG_WMM_UAPSD
1246         if (last_packet)
1247         {
1248 #if CONFIG_TX_RX_ZERO_COPY
1249             process_pkt_hdrs_flags(&((outbuf_t *)tx_buf)->intf_header[0], 0);
1250 #else
1251             process_pkt_hdrs_flags((t_u8 *)tx_buf, 0);
1252 #endif
1253         }
1254 #endif
1255 
1256         wifi_imu_unlock();
1257         return MLAN_STATUS_FAILURE;
1258     }
1259 
1260 #if CONFIG_WMM_UAPSD
1261     if (last_packet)
1262     {
1263         mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1264         OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1265     }
1266 #endif
1267 
1268     wifi_imu_unlock();
1269     return MLAN_STATUS_SUCCESS;
1270 }
1271 
wlan_flush_wmm_pkt(int pkt_cnt)1272 mlan_status wlan_flush_wmm_pkt(int pkt_cnt)
1273 {
1274     int ret;
1275 
1276     if (pkt_cnt == 0)
1277         return MLAN_STATUS_SUCCESS;
1278 
1279     w_pkt_d("Data TX: Driver=>FW, pkt_cnt %d", pkt_cnt);
1280 
1281     ret = HAL_ImuSendMultiTxData(kIMU_LinkCpu1Cpu3);
1282     ;
1283     if (ret != kStatus_HAL_RpmsgSuccess)
1284     {
1285         wifi_io_e("wlan_flush_wmm_pkt failed (%d)", ret);
1286 #if CONFIG_WIFI_FW_DEBUG
1287 #if 0
1288         if (wm_wifi.wifi_usb_mount_cb != NULL)
1289         {
1290             ret = wm_wifi.wifi_usb_mount_cb();
1291             if (ret == WM_SUCCESS)
1292                 wifi_dump_firmware_info(NULL);
1293             else
1294                 wifi_e("USB mounting failed");
1295         }
1296         else
1297             wifi_e("USB mount callback is not registered");
1298 #endif
1299         wifi_dump_firmware_info();
1300 #endif
1301         return MLAN_STATUS_FAILURE;
1302     }
1303     return MLAN_STATUS_SUCCESS;
1304 }
1305 
1306 #if CONFIG_AMSDU_IN_AMPDU
1307 /**
1308  *  @brief This function checks if we need to send last amsdu indication.
1309  *
1310  *  @param priv    A pointer to mlan_private structure
1311  *
1312  *  @return        MTRUE or MFALSE
1313  */
wifi_check_last_amsdu_packet_indication(mlan_private * priv,t_u8 amsdu_cnt)1314 static t_u8 wifi_check_last_amsdu_packet_indication(mlan_private *priv, t_u8 amsdu_cnt)
1315 {
1316     if ((wifi_wmm_get_packet_cnt() == amsdu_cnt) && priv->wmm_qosinfo && priv->curr_bss_params.wmm_uapsd_enabled)
1317         return TRUE;
1318     else
1319         return FALSE;
1320 }
1321 
wlan_xmit_wmm_amsdu_pkt(mlan_wmm_ac_e ac,t_u8 interface,t_u32 txlen,t_u8 * tx_buf,t_u8 amsdu_cnt)1322 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)
1323 {
1324     int ret;
1325 #if CONFIG_WMM_UAPSD
1326     bool last_packet = 0;
1327 #endif
1328 
1329     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1330 
1331     wifi_imu_lock();
1332 #if defined(RW610)
1333     process_amsdu_pkt_hdrs((t_u8 *)tx_buf, txlen, ac, interface);
1334 #if CONFIG_WMM_UAPSD
1335     if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1336         wifi_check_last_amsdu_packet_indication(mlan_adap->priv[interface], amsdu_cnt))
1337     {
1338         process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1339         last_packet = 1;
1340     }
1341 #endif
1342 #else
1343     process_amsdu_pkt_hdrs((t_u8 *)tx_buf, txlen, ac);
1344 #endif
1345 
1346     ret = HAL_ImuAddWlanTxPacket(kIMU_LinkCpu1Cpu3, tx_buf, txlen);
1347 
1348     if (ret != kStatus_HAL_RpmsgSuccess)
1349     {
1350 #if CONFIG_WMM_UAPSD
1351         if (last_packet)
1352             process_pkt_hdrs_flags((t_u8 *)tx_buf, 0);
1353 #endif
1354         wifi_imu_unlock();
1355         return MLAN_STATUS_FAILURE;
1356     }
1357 
1358 #if CONFIG_WMM_UAPSD
1359     if (last_packet)
1360     {
1361         mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1362         OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1363     }
1364 #endif
1365 
1366     wifi_imu_unlock();
1367     return MLAN_STATUS_SUCCESS;
1368 }
1369 #endif
1370 #endif
1371 
wlan_send_null_packet(pmlan_private priv,t_u8 flags)1372 mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
1373 {
1374     int ret;
1375     t_u8 pbuf[32] = {0};
1376     TxPD *ptxpd   = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
1377 
1378     ptxpd->bss_type      = priv->bss_type;
1379     ptxpd->bss_num       = GET_BSS_NUM(priv);
1380     ptxpd->tx_pkt_offset = 0x16; /* we'll just make this constant */
1381     ptxpd->tx_pkt_length = 0;
1382     ptxpd->tx_control    = 0;
1383     ptxpd->priority      = 0;
1384     ptxpd->flags         = flags;
1385     ptxpd->pkt_delay_2ms = 0;
1386 
1387     ret = wifi_send_fw_data(pbuf, sizeof(TxPD) + INTF_HEADER_LEN);
1388     if (ret != kStatus_HAL_RpmsgSuccess)
1389     {
1390         wifi_io_e("imu_drv_write failed (%d)", ret);
1391         return MLAN_STATUS_FAILURE;
1392     }
1393 
1394     return MLAN_STATUS_SUCCESS;
1395 }
1396 
rpmsg_cmdrsp_handler(IMU_Msg_t * pImuMsg,uint32_t length)1397 hal_rpmsg_status_t rpmsg_cmdrsp_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1398 {
1399     assert(NULL != pImuMsg);
1400     assert(0 != length);
1401     assert(IMU_MSG_COMMAND_RESPONSE == pImuMsg->Hdr.type);
1402 
1403 #if CONFIG_HOST_SLEEP
1404     if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1405     {
1406         wakeup_by                      = WAKEUP_BY_WLAN;
1407         mlan_adap->wlan_wakeup.type    = IMU_MSG_COMMAND_RESPONSE;
1408         mlan_adap->wlan_wakeup.subtype = 0;
1409         mlan_adap->wlan_wakeup.id      = *(uint16_t *)((uint8_t *)pImuMsg->PayloadPtr[0] + 4);
1410         POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1411     }
1412 #endif
1413 
1414     wlan_decode_rx_packet((t_u8 *)pImuMsg->PayloadPtr[0], MLAN_TYPE_CMD);
1415 
1416     return kStatus_HAL_RpmsgSuccess;
1417 }
1418 
rpmsg_event_handler(IMU_Msg_t * pImuMsg,uint32_t length)1419 hal_rpmsg_status_t rpmsg_event_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1420 {
1421     assert(NULL != pImuMsg);
1422     assert(0 != length);
1423     assert(IMU_MSG_EVENT == pImuMsg->Hdr.type);
1424 
1425 #if CONFIG_HOST_SLEEP
1426     if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1427     {
1428         wakeup_by                      = WAKEUP_BY_WLAN;
1429         mlan_adap->wlan_wakeup.type    = IMU_MSG_EVENT;
1430         mlan_adap->wlan_wakeup.subtype = 0;
1431         mlan_adap->wlan_wakeup.id      = *(uint16_t *)((uint8_t *)pImuMsg->PayloadPtr[0] + 4);
1432         POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1433     }
1434 #endif
1435 
1436 #if CONFIG_CSI
1437     if (EVENT_CSI == *((t_u8 *)pImuMsg->PayloadPtr[0] + 4))
1438     {
1439         csi_save_data_to_local_buff((t_u8 *)pImuMsg->PayloadPtr[0] + 8);
1440     }
1441 #endif
1442 
1443     wlan_decode_rx_packet((t_u8 *)pImuMsg->PayloadPtr[0], MLAN_TYPE_EVENT);
1444 
1445     return kStatus_HAL_RpmsgSuccess;
1446 }
1447 
rpmsg_rxpkt_handler(IMU_Msg_t * pImuMsg,uint32_t length)1448 hal_rpmsg_status_t rpmsg_rxpkt_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1449 {
1450     IMUPkt *inimupkt;
1451     t_u32 size;
1452     t_u8 interface;
1453     t_u8 i = 0;
1454 
1455     assert(NULL != pImuMsg);
1456     assert(0 != length);
1457     assert((IMU_MSG_RX_DATA == pImuMsg->Hdr.type) || (IMU_MSG_MULTI_RX_DATA == pImuMsg->Hdr.type));
1458 
1459 #if CONFIG_HOST_SLEEP
1460     wakelock_get();
1461     if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1462     {
1463         wakeup_by                      = WAKEUP_BY_WLAN;
1464         mlan_adap->wlan_wakeup.type    = pImuMsg->Hdr.type;
1465         mlan_adap->wlan_wakeup.subtype = 0;
1466         mlan_adap->wlan_wakeup.id      = 0;
1467         POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1468     }
1469 #endif
1470 
1471     for (i = 0; i < pImuMsg->Hdr.length; i++)
1472     {
1473         inimupkt = (IMUPkt *)pImuMsg->PayloadPtr[i];
1474         size     = inimupkt->size;
1475         if ((size <= INTF_HEADER_LEN) || (size > sizeof(inbuf)))
1476         {
1477 #if CONFIG_HOST_SLEEP
1478             wakelock_put();
1479 #endif
1480             wifi_io_e("pImuMsg->PayloadPtr[%u] has invalid size=%u", i, size);
1481             return kStatus_HAL_RpmsgError;
1482         }
1483 
1484 #if !CONFIG_TX_RX_ZERO_COPY
1485 #if CONFIG_IMU_GDMA
1486         HAL_ImuGdmaCopyData(inbuf, inimupkt, size);
1487 #else
1488         memcpy(inbuf, inimupkt, size);
1489 #endif
1490 #endif
1491         interface = *((t_u8 *)inimupkt + INTF_HEADER_LEN);
1492         wifi_io_info_d("IN: i/f: %d len: %d", interface, size);
1493         w_pkt_d("Data RX: FW=>Driver, if %d, len %d", interface, size);
1494 
1495         if (bus.wifi_low_level_input != NULL)
1496 #if CONFIG_TX_RX_ZERO_COPY
1497             bus.wifi_low_level_input(interface, (uint8_t *)inimupkt, size);
1498 #else
1499             bus.wifi_low_level_input(interface, inbuf, size);
1500 #endif
1501     }
1502 #if CONFIG_HOST_SLEEP
1503     wakelock_put();
1504 #endif
1505     /*! To be the last action of the handler*/
1506     return kStatus_HAL_RpmsgSuccess;
1507 }
1508 
imu_fw_is_hang(void)1509 static bool imu_fw_is_hang(void)
1510 {
1511     uint32_t *peer_magic_addr = (uint32_t *)0x41380000;
1512 
1513     if ((*peer_magic_addr) == 0xDEADDEAD)
1514         return true;
1515     else
1516         return false;
1517 }
1518 
rpmsg_ctrl_handler(IMU_Msg_t * pImuMsg,uint32_t length)1519 hal_rpmsg_status_t rpmsg_ctrl_handler(IMU_Msg_t *pImuMsg, uint32_t length)
1520 {
1521     t_u32 imuControlType;
1522 
1523     assert(NULL != pImuMsg);
1524     assert(IMU_MSG_CONTROL == pImuMsg->Hdr.type);
1525 
1526 #if CONFIG_HOST_SLEEP
1527     if (POWER_GetWakeupStatus(WL_MCI_WAKEUP0_IRQn))
1528     {
1529         wakeup_by                      = WAKEUP_BY_WLAN;
1530         mlan_adap->wlan_wakeup.type    = IMU_MSG_CONTROL;
1531         mlan_adap->wlan_wakeup.subtype = pImuMsg->Hdr.sub_type;
1532         mlan_adap->wlan_wakeup.id      = 0;
1533         POWER_ClearWakeupStatus(WL_MCI_WAKEUP0_IRQn);
1534     }
1535 #endif
1536 
1537     imuControlType = pImuMsg->Hdr.sub_type;
1538     switch (imuControlType)
1539     {
1540         case IMU_MSG_CONTROL_TX_BUF_ADDR:
1541 #if CONFIG_WMM
1542 
1543             if (mlan_adap->wait_txbuf == true)
1544             {
1545                 OSA_SemaphorePost((osa_semaphore_handle_t)txbuf_sem);
1546             }
1547 
1548             send_wifi_driver_tx_data_event(0);
1549 #endif
1550             break;
1551         default:
1552             break;
1553     }
1554     return kStatus_HAL_RpmsgSuccess;
1555 }
1556 
imu_wakeup_card()1557 void imu_wakeup_card()
1558 {
1559     /* Wakeup CPU1 */
1560     PMU_EnableWlanWakeup(1);
1561 }
1562 
WL_MCI_WAKEUP_DONE0_DriverIRQHandler(void)1563 void WL_MCI_WAKEUP_DONE0_DriverIRQHandler(void)
1564 {
1565     IRQn_Type irq_num = WL_MCI_WAKEUP_DONE0_IRQn;
1566 
1567     /* Mask IMU ICU interrupt */
1568     DisableIRQ(irq_num);
1569     /* Clear CPU1 wakeup register */
1570     PMU_DisableWlanWakeup(1);
1571     EnableIRQ(irq_num);
1572 }
1573 
mlan_init_wakeup_irq()1574 void mlan_init_wakeup_irq()
1575 {
1576 }
1577 
mlan_deinit_wakeup_irq()1578 void mlan_deinit_wakeup_irq()
1579 {
1580 }
1581 
imu_wifi_init(enum wlan_type type,const uint8_t * fw_ram_start_addr,const size_t size)1582 mlan_status imu_wifi_init(enum wlan_type type, const uint8_t *fw_ram_start_addr, const size_t size)
1583 {
1584     mlan_status mlanstatus = MLAN_STATUS_SUCCESS;
1585     int ret                = 0;
1586     int retry_cnt          = 3;
1587     int retry_cnt_fw_init  = 3;
1588 #ifdef RW610
1589     int temperature_val = 0;
1590 #endif
1591 
1592     ret = wlan_init_struct();
1593     if (ret != WM_SUCCESS)
1594     {
1595         wifi_io_e("Init failed. Cannot create init struct");
1596         return MLAN_STATUS_FAILURE;
1597     }
1598 
1599     /* Initialize the mlan subsystem before initializing 878x driver */
1600     mlan_subsys_init();
1601 
1602 retry:
1603     /* Comment out this line if CPU1 image is downloaded through J-Link.
1604      * This is for load service case only.
1605      */
1606     power_off_device(LOAD_WIFI_FIRMWARE);
1607     wifi_io_d("%u IMU download WLAN FW.\n", OSA_TicksGet());
1608     /* Download firmware */
1609     ret = sb3_fw_download(LOAD_WIFI_FIRMWARE, 1, (uint32_t)fw_ram_start_addr);
1610     /* If fw download is failed, retry downloading for 3 times. */
1611     if (ret)
1612     {
1613         if (retry_cnt != 0)
1614         {
1615             retry_cnt--;
1616             goto retry;
1617         }
1618         else
1619         {
1620             wifi_io_e("Download firmware failed");
1621             mlanstatus = MLAN_STATUS_FAILURE;
1622             return mlanstatus;
1623         }
1624     }
1625     wifi_io_d("%u WLAN FW is active.\n", OSA_TicksGet());
1626 #if CONFIG_WIFI_RECOVERY
1627     if (wifi_recovery_enable)
1628     {
1629         wifi_w("WiFi recovery mode done!");
1630         wifi_recovery_enable = false;
1631     }
1632 #endif
1633     if (wifi_shutdown_enable)
1634     {
1635         wifi_shutdown_enable = false;
1636     }
1637 
1638 #ifdef RW610
1639     wifi_cau_temperature_enable();
1640     wifi_pmip_v33_enable();
1641     temperature_val = wifi_cau_temperature_write_to_firmware();
1642     PRINTF("Wi-Fi cau temperature : %d\r\n", temperature_val);
1643 #endif
1644 
1645     wifi_init_imulink();
1646 
1647     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_cmdrsp_handler, IMU_MSG_COMMAND_RESPONSE);
1648 
1649     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_event_handler, IMU_MSG_EVENT);
1650 
1651     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_rxpkt_handler, IMU_MSG_RX_DATA);
1652 
1653     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, rpmsg_ctrl_handler, IMU_MSG_CONTROL);
1654 
1655     /* If we're running a Manufacturing image, start the tasks.
1656        If not, initialize and setup the firmware */
1657     switch (type)
1658     {
1659         case WLAN_TYPE_NORMAL:
1660             ret = wlan_fw_init_cfg();
1661             if (ret != true)
1662             {
1663                 if (retry_cnt_fw_init > 0)
1664                 {
1665                     wifi_io_e("wlan_fw_init_cfg failed: retry %d", retry_cnt_fw_init);
1666                     (void)HAL_ImuGetTaskLock();
1667                     mlan_deinit_wakeup_irq();
1668                     HAL_ImuDeinit(kIMU_LinkCpu1Cpu3, MBIT(1) | MBIT(0));
1669                     (void)HAL_ImuPutTaskLock();
1670                     retry_cnt_fw_init--;
1671                     goto retry;
1672                 }
1673                 else
1674                 {
1675                     wifi_io_e("wlan_fw_init_cfg failed: return for retry done");
1676                     mlanstatus = MLAN_STATUS_FAILURE;
1677                     return mlanstatus;
1678                 }
1679             }
1680             break;
1681         case WLAN_TYPE_WIFI_CALIB:
1682             g_txrx_flag = true;
1683             break;
1684         case WLAN_TYPE_FCC_CERTIFICATION:
1685             g_txrx_flag = true;
1686             break;
1687         default:
1688             wifi_io_e("Enter a valid input to sd_wifi_init");
1689             return MLAN_STATUS_FAILURE;
1690     }
1691 
1692     mlan_init_wakeup_irq();
1693 
1694     return mlanstatus;
1695 }
1696 
imu_wifi_deinit(void)1697 void imu_wifi_deinit(void)
1698 {
1699     uint32_t flag = 0;
1700 
1701 #ifdef WLAN_LOW_POWER_ENABLE
1702     low_power_mode = false;
1703 #endif
1704     cal_data_valid = false;
1705     mac_addr_valid = false;
1706 #if 0
1707     wlan_cmd_shutdown();
1708     // sdio_drv_deinit();
1709 #endif
1710     wlan_deinit_struct();
1711 
1712     flag = MBIT(1) | MBIT(0);
1713 #if CONFIG_WIFI_RECOVERY
1714     flag |= wifi_recovery_enable;
1715 #endif
1716 
1717     mlan_deinit_wakeup_irq();
1718     HAL_ImuDeinit(kIMU_LinkCpu1Cpu3, flag);
1719 
1720     mlan_subsys_deinit();
1721 }
1722 
imu_uninstall_callback(void)1723 void imu_uninstall_callback(void)
1724 {
1725     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_COMMAND_RESPONSE);
1726     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_EVENT);
1727     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_RX_DATA);
1728     HAL_ImuInstallCallback(kIMU_LinkCpu1Cpu3, NULL, IMU_MSG_CONTROL);
1729 }
1730 
wifi_get_command_buffer()1731 HostCmd_DS_COMMAND *wifi_get_command_buffer()
1732 {
1733     /* First 4 bytes reserved for SDIO pkt header */
1734     return (HostCmd_DS_COMMAND *)(cmd_buf + INTF_HEADER_LEN);
1735 }
1736 
1737 bus_operations imu_ops = {
1738     .fw_is_hang      = imu_fw_is_hang,
1739     .intf_header_len = INTF_HEADER_LEN,
1740 };
1741 
imu_create_task_lock(void)1742 int imu_create_task_lock(void)
1743 {
1744     int ret = 0;
1745 
1746     ret = HAL_ImuCreateTaskLock();
1747     if (ret != WM_SUCCESS)
1748     {
1749         wifi_e("Create imu task lock failed.");
1750         return -WM_FAIL;
1751     }
1752 
1753     return WM_SUCCESS;
1754 }
1755 
imu_delete_task_lock(void)1756 void imu_delete_task_lock(void)
1757 {
1758     HAL_ImuDeleteTaskLock();
1759 }
1760 
imu_get_task_lock(void)1761 int imu_get_task_lock(void)
1762 {
1763     int ret = 0;
1764 
1765     ret = HAL_ImuGetTaskLock();
1766     if (ret != WM_SUCCESS)
1767     {
1768         wifi_d("Get imu task lock failed.");
1769         return -WM_FAIL;
1770     }
1771 
1772     return WM_SUCCESS;
1773 }
1774 
imu_put_task_lock(void)1775 int imu_put_task_lock(void)
1776 {
1777     int ret = 0;
1778 
1779     ret = HAL_ImuPutTaskLock();
1780     if (ret != WM_SUCCESS)
1781     {
1782         wifi_d("Put imu task lock failed.");
1783         return -WM_FAIL;
1784     }
1785 
1786     return WM_SUCCESS;
1787 }
1788 
1789 #if CONFIG_HOST_SLEEP
wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)1790 void wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)
1791 {
1792     ARG_UNUSED(hs_wakeup_reason);
1793     if (mlan_adap->wlan_wakeup.type == IMU_MSG_CONTROL)
1794         PRINTF("Woken up by WLAN(IMU ctrl msg subtype 0x%x)\r\n", mlan_adap->wlan_wakeup.subtype);
1795     else if (mlan_adap->wlan_wakeup.type == IMU_MSG_COMMAND_RESPONSE)
1796         PRINTF("Woken up by WLAN(command response 0x%x)\r\n", mlan_adap->wlan_wakeup.id);
1797     else if (mlan_adap->wlan_wakeup.type == IMU_MSG_EVENT)
1798         PRINTF("Woken up by WLAN(event 0x%x)\r\n", mlan_adap->wlan_wakeup.id);
1799     else if (mlan_adap->wlan_wakeup.type == IMU_MSG_RX_DATA || mlan_adap->wlan_wakeup.type == IMU_MSG_MULTI_RX_DATA)
1800         PRINTF("Woken up by WLAN(Rx data)\r\n");
1801 }
1802 
wifi_clear_wakeup_reason(void)1803 void wifi_clear_wakeup_reason(void)
1804 {
1805     if (mlan_adap != NULL)
1806     {
1807         memset(&mlan_adap->wlan_wakeup, 0x0, sizeof(wlan_wakeup_reason));
1808     }
1809 }
1810 #endif
1811