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