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