1 /** @file wifi-sdio.c
2  *
3  *  @brief  This file provides WLAN Card related API
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 #include <mlan_api.h>
12 
13 #include <mlan_sdio_api.h>
14 
15 #if (CONFIG_XZ_DECOMPRESSION)
16 #include <xz.h>
17 #include <decompress.h>
18 #endif /* CONFIG_XZ_DECOMPRESSION */
19 
20 /* Additional WMSDK header files */
21 #include <wmerrno.h>
22 #include <osa.h>
23 #include <wm_utils.h>
24 #include <mlan_fw.h>
25 #include "wifi-sdio.h"
26 #include "wifi-internal.h"
27 #include "sdio.h"
28 #include "firmware_dnld.h"
29 #include "fwdnld_sdio.h"
30 
31 #define SDIO_COMMAND_RESPONSE_WAIT_MS 20000
32 
33 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
34 SDK_ALIGN(uint8_t rx_bufs[SDIO_MP_AGGR_DEF_PKT_LIMIT][2 * DATA_BUFFER_SIZE], BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE);
35 
36 static size_t num_sg = 0;
37 #endif
38 
39 /* Buffer pointers to point to command and, command response buffer */
40 static uint8_t ctrl_cmd_buf[WIFI_FW_CMDBUF_SIZE];
41 #if CONFIG_FW_VDLL
42 static uint8_t vdll_cmd_buf[WIFI_FW_CMDBUF_SIZE] = {0};
43 #endif
44 static int seqnum;
45 // static int pm_handle;
46 
47 /*
48  * Used to authorize the SDIO interrupt handler to accept the incoming
49  * packet from the SDIO interface. If this flag is set a semaphore is
50  * signalled.
51  */
52 bool g_txrx_flag;
53 
54 int mlan_subsys_init(void);
55 int mlan_subsys_deinit(void);
56 void set_ioport_inmlan(t_u32 port);
57 
58 static t_u8 txportno;
59 
60 static t_u32 last_cmd_sent, fw_init_cfg;
61 
62 OSA_MUTEX_HANDLE_DEFINE(txrx_mutex);
63 #if CONFIG_WIFI_IND_RESET
64 OSA_MUTEX_HANDLE_DEFINE(ind_reset_mutex);
65 #endif
66 OSA_SEMAPHORE_HANDLE_DEFINE(sdio_command_resp_sem);
67 
68 #if CONFIG_TX_RX_ZERO_COPY
69 extern void net_tx_zerocopy_process_cb(void *destAddr, void *srcAddr, uint32_t len);
70 #endif
71 
72 static struct
73 {
74     /* Where the cmdresp/event should be dispached depends on its value */
75     /* int special; */
76     /* Default queue where the cmdresp/events will be sent */
77     osa_msgq_handle_t event_queue;
78 #if CONFIG_P2P
79     /* Special queue on which only cmdresp will be sent based on
80      * value in special */
81     osa_msgq_handle_t special_queue;
82 #endif /* CONFIG_P2P */
83     int (*wifi_low_level_input)(const uint8_t interface, const uint8_t *buffer, const uint16_t len);
84 } bus;
85 
86 /* fixme: This structure is not present in mlan and can be removed later */
87 typedef MLAN_PACK_START struct
88 {
89     t_u16 size;
90     t_u16 pkttype;
91     HostCmd_DS_COMMAND hostcmd;
92 } MLAN_PACK_END SDIOPkt;
93 
94 static SDIOPkt *sdiopkt = (SDIOPkt *)outbuf;
95 
96 void wrapper_wlan_cmd_11n_cfg(HostCmd_DS_COMMAND *cmd);
97 
98 static uint32_t dev_value1 = -1;
99 uint8_t dev_mac_addr[MLAN_MAC_ADDR_LENGTH];
100 uint8_t dev_mac_addr_uap[MLAN_MAC_ADDR_LENGTH];
101 static uint8_t dev_fw_ver_ext[MLAN_MAX_VER_STR_LEN];
102 
wifi_send_fw_data(t_u8 * data,t_u32 txlen)103 static mlan_status wifi_send_fw_data(t_u8 *data, t_u32 txlen)
104 {
105     t_u32 tx_blocks = 0, buflen = 0;
106     uint32_t resp;
107     bool ret;
108 #if CONFIG_WIFI_FW_DEBUG
109     int ret_cb;
110 #endif
111 
112     if (data == NULL || txlen == 0)
113         return MLAN_STATUS_FAILURE;
114 
115     w_pkt_d("Data TX SIG: Driver=>FW, len %d", txlen);
116 
117     calculate_sdio_write_params(txlen, &tx_blocks, &buflen);
118 
119 #if CONFIG_WIFI_IO_DEBUG
120     (void)PRINTF("%s: txportno = %d mlan_adap->mp_wr_bitmap: %x\n\r", __func__, txportno, mlan_adap->mp_wr_bitmap);
121 #endif /* CONFIG_WIFI_IO_DEBUG */
122     /* Check if the port is available */
123     if (!((1U << txportno) & mlan_adap->mp_wr_bitmap))
124     {
125         /*
126          * fixme: This condition is triggered in legacy as well as
127          * this new code. Check this out later.
128          */
129 #if CONFIG_WIFI_IO_DEBUG
130         wifi_io_e(
131             "txportno out of sync txportno "
132             "= (%d) mp_wr_bitmap = (0x%x)",
133             txportno, mlan_adap->mp_wr_bitmap);
134 #endif /* CONFIG_WIFI_IO_DEBUG */
135         return MLAN_STATUS_RESOURCE;
136     }
137     else
138     {
139         /* Mark the port number we will use */
140         mlan_adap->mp_wr_bitmap &= ~(1U << txportno);
141     }
142 
143     /* send CMD53 */
144     ret = sdio_drv_write(mlan_adap->ioport + txportno, 1, tx_blocks, buflen, data, &resp);
145 
146     txportno++;
147     if (txportno == mlan_adap->mp_end_port)
148     {
149 #if defined(SD8801)
150         txportno = 1;
151 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
152         txportno   = 0;
153 #endif
154     }
155 
156     if (ret == false)
157     {
158         wifi_io_e("sdio_drv_write failed (%d)", ret);
159 #if CONFIG_WIFI_FW_DEBUG
160         wifi_sdio_reg_dbg(NULL);
161         if (wm_wifi.wifi_usb_mount_cb != NULL)
162         {
163             ret_cb = wm_wifi.wifi_usb_mount_cb();
164             if (ret_cb == WM_SUCCESS)
165                 wifi_dump_firmware_info(NULL);
166             else
167                 wifi_e("USB mounting failed");
168         }
169         else
170             wifi_e("USB mount callback is not registered");
171 #endif
172         return MLAN_STATUS_RESOURCE;
173     }
174     return MLAN_STATUS_SUCCESS;
175 }
176 
wifi_sdio_lock(void)177 int wifi_sdio_lock(void)
178 {
179     return OSA_MutexLock((osa_mutex_handle_t)txrx_mutex, osaWaitForever_c);
180 }
181 
wifi_sdio_unlock(void)182 void wifi_sdio_unlock(void)
183 {
184     (void)OSA_MutexUnlock((osa_mutex_handle_t)txrx_mutex);
185 }
186 
187 #if CONFIG_WIFI_IND_RESET
wifi_ind_reset_lock(void)188 int wifi_ind_reset_lock(void)
189 {
190     return OSA_MutexLock((osa_mutex_handle_t)ind_reset_mutex, osaWaitForever_c);
191 }
192 
wifi_ind_reset_unlock(void)193 void wifi_ind_reset_unlock(void)
194 {
195     (void)OSA_MutexUnlock((osa_mutex_handle_t)ind_reset_mutex);
196 }
197 #endif
198 
199 #if CONFIG_WIFI_IND_RESET
200 static bool ind_reset_in_progress = false;
201 
wifi_ind_reset_in_progress(void)202 bool wifi_ind_reset_in_progress(void)
203 {
204     return ind_reset_in_progress;
205 }
206 
wifi_ind_reset_start(void)207 void wifi_ind_reset_start(void)
208 {
209     ind_reset_in_progress = true;
210 }
211 
wifi_ind_reset_stop(void)212 void wifi_ind_reset_stop(void)
213 {
214    ind_reset_in_progress = false;
215 }
216 #endif
217 
wifi_sdio_get_command_resp_sem(unsigned long wait)218 static int wifi_sdio_get_command_resp_sem(unsigned long wait)
219 {
220     return OSA_SemaphoreWait((osa_semaphore_handle_t)sdio_command_resp_sem, wait);
221 }
222 
wifi_sdio_put_command_resp_sem(void)223 static int wifi_sdio_put_command_resp_sem(void)
224 {
225     return OSA_SemaphorePost((osa_semaphore_handle_t)sdio_command_resp_sem);
226 }
227 
wifi_sdio_wait_for_cmdresp()228 static void wifi_sdio_wait_for_cmdresp()
229 {
230     /* Wait max 20 sec for the command response */
231     int ret = wifi_sdio_get_command_resp_sem(SDIO_COMMAND_RESPONSE_WAIT_MS);
232     if (ret != WM_SUCCESS)
233     {
234         /* assert as command flow cannot work anymore */
235         assert(0);
236     }
237 }
238 
wifi_get_device_value1(void)239 uint32_t wifi_get_device_value1(void)
240 {
241     return dev_value1;
242 }
243 
wifi_get_device_mac_addr(wifi_mac_addr_t * mac_addr)244 int wifi_get_device_mac_addr(wifi_mac_addr_t *mac_addr)
245 {
246     (void)memcpy(mac_addr->mac, dev_mac_addr, MLAN_MAC_ADDR_LENGTH);
247     return WM_SUCCESS;
248 }
249 
wifi_get_device_uap_mac_addr(wifi_mac_addr_t * mac_addr_uap)250 int wifi_get_device_uap_mac_addr(wifi_mac_addr_t *mac_addr_uap)
251 {
252     (void)memcpy(mac_addr_uap->mac, dev_mac_addr_uap, MLAN_MAC_ADDR_LENGTH);
253     return WM_SUCCESS;
254 }
255 
wifi_get_device_firmware_version_ext(wifi_fw_version_ext_t * fw_ver_ext)256 int wifi_get_device_firmware_version_ext(wifi_fw_version_ext_t *fw_ver_ext)
257 {
258     (void)memcpy((void *)fw_ver_ext->version_str, (const void *)dev_fw_ver_ext, MLAN_MAX_VER_STR_LEN);
259     return WM_SUCCESS;
260 }
261 
262 /* Initializes the driver struct */
wlan_init_struct(void)263 static int wlan_init_struct(void)
264 {
265     osa_status_t status;
266 
267     status = OSA_MutexCreate((osa_mutex_handle_t)txrx_mutex);
268     if (status != KOSA_StatusSuccess)
269     {
270         return -WM_FAIL;
271     }
272 #if CONFIG_WIFI_IND_RESET
273     status = OSA_MutexCreate((osa_mutex_handle_t)ind_reset_mutex);
274     if (status != KOSA_StatusSuccess)
275     {
276         return -WM_FAIL;
277     }
278 #endif
279 
280     status = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)sdio_command_resp_sem);
281     if (status != KOSA_StatusSuccess)
282     {
283         return -WM_FAIL;
284     }
285 
286     return WM_SUCCESS;
287 }
288 
wlan_deinit_struct(void)289 static int wlan_deinit_struct(void)
290 {
291     osa_status_t status;
292 
293     status = OSA_MutexDestroy((osa_mutex_handle_t)txrx_mutex);
294     if (status != KOSA_StatusSuccess)
295     {
296         wifi_io_e("%s mutex deletion error %d", __FUNCTION__, status);
297         return -WM_FAIL;
298     }
299 #if CONFIG_WIFI_IND_RESET
300     status = OSA_MutexDestroy((osa_mutex_handle_t)ind_reset_mutex);
301     if (status != KOSA_StatusSuccess)
302     {
303         wifi_io_e("%s mutex deletion error %d", __FUNCTION__, status);
304         return -WM_FAIL;
305     }
306 #endif
307     status = OSA_SemaphoreDestroy((osa_semaphore_handle_t)sdio_command_resp_sem);
308     if (status != KOSA_StatusSuccess)
309     {
310         wifi_io_e("%s mutex deletion error %d", __FUNCTION__, status);
311         return -WM_FAIL;
312     }
313 
314     (void)memset(dev_mac_addr, 0, sizeof(dev_mac_addr));
315     (void)memset(dev_fw_ver_ext, 0, sizeof(dev_fw_ver_ext));
316 
317     return WM_SUCCESS;
318 }
319 
raw_process_pkt_hdrs(void * pbuf,t_u32 payloadlen,t_u8 interface)320 int raw_process_pkt_hdrs(void *pbuf, t_u32 payloadlen, t_u8 interface)
321 {
322     mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[interface];
323     SDIOPkt *sdiohdr     = (SDIOPkt *)pbuf;
324     TxPD *ptxpd          = (TxPD *)(void *)((uint8_t *)pbuf + INTF_HEADER_LEN);
325 
326     ptxpd->bss_type      = interface;
327     ptxpd->bss_num       = GET_BSS_NUM(pmpriv);
328     ptxpd->tx_pkt_offset = 0x14; /* we'll just make this constant */
329     ptxpd->tx_pkt_length = (t_u16)(payloadlen - ptxpd->tx_pkt_offset - INTF_HEADER_LEN);
330     ptxpd->tx_pkt_type   = 0xE5;
331     ptxpd->tx_control    = 0;
332     ptxpd->priority      = 0;
333     ptxpd->flags         = 0;
334     ptxpd->pkt_delay_2ms = 0;
335 
336 #if CONFIG_WPA_SUPP
337     if (pmpriv->tx_seq_num == 0)
338     {
339         pmpriv->tx_seq_num++;
340     }
341     ptxpd->tx_token_id = pmpriv->tx_seq_num++;
342     ptxpd->flags |= MRVDRV_TxPD_FLAGS_TX_PACKET_STATUS;
343 #endif
344 
345     sdiohdr->size = (t_u16)(payloadlen + ptxpd->tx_pkt_offset + INTF_HEADER_LEN);
346 
347     return (int)(ptxpd->tx_pkt_offset + INTF_HEADER_LEN);
348 }
349 
350 /*
351  * fixme: mlan_sta_tx.c can be used directly here. This functionality is
352  * already present there.
353  */
354 /* SDIO  TxPD  PAYLOAD | 4 | 22 | payload | */
355 
process_pkt_hdrs(void * pbuf,t_u32 payloadlen,t_u8 interface,t_u8 tid,t_u32 tx_control)356 void process_pkt_hdrs(void *pbuf, t_u32 payloadlen, t_u8 interface, t_u8 tid, t_u32 tx_control)
357 {
358     mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[interface];
359 #if CONFIG_FW_VDLL
360     mlan_adapter *pmadapter = pmpriv->adapter;
361 #endif
362     SDIOPkt *sdiohdr     = (SDIOPkt *)pbuf;
363     TxPD *ptxpd          = (TxPD *)(void *)((uint8_t *)pbuf + INTF_HEADER_LEN);
364 
365     ptxpd->bss_type      = interface;
366     ptxpd->bss_num       = GET_BSS_NUM(pmpriv);
367     ptxpd->tx_pkt_offset = 0x16; /* we'll just make this constant */
368     ptxpd->tx_pkt_length = (t_u16)(payloadlen - ptxpd->tx_pkt_offset - INTF_HEADER_LEN);
369     ptxpd->tx_control    = tx_control;
370     ptxpd->priority      = tid;
371     ptxpd->flags         = 0;
372 
373     if (ptxpd->tx_pkt_type == 0xe5U)
374     {
375         ptxpd->tx_pkt_offset = 0x14; /* Override for special frame */
376     }
377 
378     ptxpd->pkt_delay_2ms = 0;
379 
380     sdiohdr->size = (t_u16)payloadlen;
381 
382 #if CONFIG_FW_VDLL
383     while (pmadapter->vdll_in_progress == MTRUE)
384     {
385         OSA_TimeDelay(50);
386     }
387 #endif
388 }
389 
process_pkt_hdrs_flags(void * pbuf,t_u8 flags)390 void process_pkt_hdrs_flags(void *pbuf, t_u8 flags)
391 {
392     TxPD *ptxpd  = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
393     ptxpd->flags = flags;
394 }
395 
bus_register_event_queue(osa_msgq_handle_t event_queue)396 int bus_register_event_queue(osa_msgq_handle_t event_queue)
397 {
398     if (bus.event_queue != NULL)
399     {
400         return -WM_FAIL;
401     }
402 
403     bus.event_queue = event_queue;
404 
405     return WM_SUCCESS;
406 }
407 
bus_deregister_event_queue(void)408 void bus_deregister_event_queue(void)
409 {
410     if (bus.event_queue != NULL)
411     {
412         bus.event_queue = NULL;
413     }
414 }
415 
bus_register_data_input_function(int (* wifi_low_level_input)(const uint8_t interface,const uint8_t * buffer,const uint16_t len))416 int bus_register_data_input_function(int (*wifi_low_level_input)(const uint8_t interface,
417                                                                  const uint8_t *buffer,
418                                                                  const uint16_t len))
419 {
420     if (bus.wifi_low_level_input != NULL)
421     {
422         return -WM_FAIL;
423     }
424 
425     bus.wifi_low_level_input = wifi_low_level_input;
426 
427     return WM_SUCCESS;
428 }
429 
bus_deregister_data_input_funtion(void)430 void bus_deregister_data_input_funtion(void)
431 {
432     bus.wifi_low_level_input = NULL;
433 }
434 
435 #if CONFIG_P2P
bus_register_special_queue(osa_msgq_handle_t special_queue)436 int bus_register_special_queue(osa_msgq_handle_t special_queue)
437 {
438     if (bus.special_queue)
439         return -WM_FAIL;
440     bus.special_queue = special_queue;
441     return WM_SUCCESS;
442 }
443 
bus_deregister_special_queue()444 void bus_deregister_special_queue()
445 {
446     if (bus.special_queue)
447         bus.special_queue = NULL;
448 }
449 #endif
450 
451 void wifi_get_mac_address_from_cmdresp(const HostCmd_DS_COMMAND *resp, uint8_t *mac_addr);
452 void wifi_get_firmware_ver_ext_from_cmdresp(const HostCmd_DS_COMMAND *resp, uint8_t *fw_ver_ext);
453 void wifi_get_value1_from_cmdresp(const HostCmd_DS_COMMAND *resp, uint32_t *dev_value1);
454 
455 #if CONFIG_FW_VDLL
wlan_handle_event_packet(t_u8 * pmbuf)456 static mlan_status wlan_handle_event_packet(t_u8 *pmbuf)
457 {
458     t_u16 evttype      = wlan_le16_to_cpu(*(t_u16 *)pmbuf);
459     mlan_status status = MLAN_STATUS_SUCCESS;
460 
461 #if CONFIG_FW_VDLL_DEBUG
462     wevt_d("Event %x", evttype);
463 #endif
464 
465     switch (evttype)
466     {
467         case EVENT_VDLL_IND:
468         {
469             status = wlan_process_vdll_event((mlan_private *)mlan_adap->priv[0], pmbuf);
470             break;
471         }
472         default:
473             wevt_d("Unhandled pre Queue event %x", evttype);
474             break;
475     }
476 
477     return status;
478 }
479 #endif
480 
wlan_handle_cmd_resp_packet(t_u8 * pmbuf)481 static mlan_status wlan_handle_cmd_resp_packet(t_u8 *pmbuf)
482 {
483     HostCmd_DS_GEN *cmdresp;
484     t_u32 cmdtype;
485     int bss_type;
486 
487     cmdresp = (HostCmd_DS_GEN *)(void *)(pmbuf + INTF_HEADER_LEN); /* size + pkttype=4 */
488     cmdtype = cmdresp->command & HostCmd_CMD_ID_MASK;
489 
490     bss_type = HostCmd_GET_BSS_TYPE(cmdresp->seq_num);
491 
492     if ((cmdresp->command & 0xf000) != 0x8000)
493     {
494         wifi_io_d("cmdresp->command = (0x%x)", cmdresp->command);
495     }
496 
497     /* Do not process response of wlan firmware shutdown command
498      *
499      * This is required to flush out any previous response
500      * from the wlan_deinit() which might have been called
501      * prior to this.
502      *
503      */
504     if ((cmdresp->command & 0x00ff) == HostCmd_CMD_FUNC_SHUTDOWN)
505     {
506         return MLAN_STATUS_SUCCESS;
507     }
508 
509     if ((cmdresp->command & 0x0fffU) != last_cmd_sent)
510     {
511         wifi_io_d("cmdresp->command = (0x%x) last_cmd_sent = (0x%x)", cmdresp->command, last_cmd_sent);
512     }
513 
514     if (cmdresp->result != 0U)
515     {
516         wifi_io_d("cmdresp->result = (0x%x)", cmdresp->result);
517     }
518 
519     wifi_io_d("Resp : (0x%x)", cmdtype);
520     switch (cmdtype)
521     {
522         case HostCmd_CMD_FUNC_INIT:
523         case HostCmd_CMD_MAC_CONTROL:
524         case HostCmd_CMD_CFG_DATA:
525             break;
526         case HostCmd_CMD_MAC_REG_ACCESS:
527             wifi_get_value1_from_cmdresp((HostCmd_DS_COMMAND *)(void *)cmdresp, &dev_value1);
528             break;
529         case HostCmd_CMD_802_11_MAC_ADDRESS:
530             if (bss_type == MLAN_BSS_TYPE_UAP)
531             {
532                 wifi_get_mac_address_from_cmdresp((HostCmd_DS_COMMAND *)(void *)cmdresp, dev_mac_addr_uap);
533             }
534             else
535             {
536                 wifi_get_mac_address_from_cmdresp((HostCmd_DS_COMMAND *)(void *)cmdresp, dev_mac_addr);
537             }
538             break;
539 #ifdef OTP_CHANINFO
540         case HostCmd_CMD_CHAN_REGION_CFG:
541             (void)wlan_ret_chan_region_cfg((mlan_private *)mlan_adap->priv[0], (HostCmd_DS_COMMAND *)(void *)cmdresp,
542                                            NULL);
543             break;
544 #endif
545         case HostCmd_CMD_GET_HW_SPEC:
546             (void)wlan_ret_get_hw_spec((mlan_private *)mlan_adap->priv[0], (HostCmd_DS_COMMAND *)(void *)cmdresp, NULL);
547             break;
548         case HostCmd_CMD_VERSION_EXT:
549             wifi_get_firmware_ver_ext_from_cmdresp((HostCmd_DS_COMMAND *)(void *)cmdresp, dev_fw_ver_ext);
550             break;
551 #if CONFIG_11N
552         case HostCmd_CMD_11N_CFG:
553         case HostCmd_CMD_AMSDU_AGGR_CTRL:
554             break;
555 #endif
556         case HostCmd_CMD_FUNC_SHUTDOWN:
557             break;
558 #ifdef WLAN_LOW_POWER_ENABLE
559         case HostCmd_CMD_LOW_POWER_MODE:
560             break;
561 #endif
562         case HostCmd_CMD_ED_MAC_MODE:
563         case HostCmd_CMD_CHANNEL_TRPC_CONFIG:
564             break;
565         case HostCmd_CMD_RECONFIGURE_TX_BUFF:
566             break;
567 #if CONFIG_EXTERNAL_BLE_COEX
568         case HostCmd_CMD_ROBUST_COEX:
569             break;
570 #endif
571         default:
572             wifi_io_d("Unimplemented Resp : (0x%x)", cmdtype);
573 #if CONFIG_WIFI_IO_DUMP
574             dump_hex(cmdresp, cmdresp->size);
575 #endif
576             break;
577     }
578 
579     wifi_sdio_put_command_resp_sem();
580 
581     return MLAN_STATUS_SUCCESS;
582 }
583 
584 /*
585  * Accepts event and command packets. Redirects them to queues if
586  * registered. If queues are not registered (as is the case during
587  * initialization then the packet is given to lower layer cmd/event
588  * handling part.
589  */
wlan_decode_rx_packet(t_u8 * pmbuf,t_u32 upld_type)590 static mlan_status wlan_decode_rx_packet(t_u8 *pmbuf, t_u32 upld_type)
591 {
592     if (upld_type == MLAN_TYPE_DATA)
593     {
594         return MLAN_STATUS_FAILURE;
595     }
596 
597     if (upld_type == MLAN_TYPE_CMD)
598     {
599         wifi_io_d("  --- Rx: Cmd Response ---");
600     }
601     else
602     {
603         wifi_io_d(" --- Rx: EVENT Response ---");
604     }
605 
606     SDIOPkt *sdiopkt = (SDIOPkt *)(void *)pmbuf;
607 
608 #if CONFIG_FW_VDLL
609     if (upld_type == MLAN_TYPE_EVENT && (wlan_le16_to_cpu(sdiopkt->hostcmd.command) == EVENT_VDLL_IND))
610     {
611 #if CONFIG_FW_VDLL_DEBUG
612         dump_hex(pmbuf, sdiopkt->size);
613 #endif
614         return wlan_handle_event_packet(pmbuf + INTF_HEADER_LEN);
615     }
616 #endif
617 #if CONFIG_CSI
618     if (upld_type == MLAN_TYPE_EVENT && (wlan_le16_to_cpu(sdiopkt->hostcmd.command) == EVENT_CSI))
619     {
620         csi_save_data_to_local_buff((t_u8 *)pmbuf + 8);
621     }
622 #endif
623 
624 #if CONFIG_P2P
625     t_u8 *cmdBuf;
626 #endif /* CONFIG_P2P */
627     osa_status_t status;
628     struct bus_message msg;
629 
630 #if CONFIG_P2P
631     if (bus.special_queue != NULL && upld_type == MLAN_TYPE_CMD)
632     {
633         msg.data = OSA_MemoryAllocate(sdiopkt->size);
634         if (!msg.data)
635         {
636             wifi_io_e("Buffer allocation failed");
637             return MLAN_STATUS_FAILURE;
638         }
639 
640         msg.event = upld_type;
641         cmdBuf    = pmbuf;
642         cmdBuf    = cmdBuf + INTF_HEADER_LEN;
643         (void)memcpy((void *)msg.data, (const void *)cmdBuf, sdiopkt->size);
644 
645         status = OSA_MsgQPut(bus.special_queue, &msg);
646 
647         if (status != KOSA_StatusSuccess)
648         {
649             wifi_io_e("Failed to send response on Queue");
650             if (upld_type != MLAN_TYPE_CMD)
651                 wifi_free_eventbuf(msg.data);
652             return MLAN_STATUS_FAILURE;
653         }
654     }
655     else
656 #endif /* CONFIG_P2P */
657         if ((fw_init_cfg == 0U) && (bus.event_queue != NULL))
658     {
659         if (upld_type == MLAN_TYPE_CMD)
660         {
661             msg.data = wifi_mem_malloc_cmdrespbuf();
662         }
663         else
664         {
665             msg.data = wifi_malloc_eventbuf((size_t)sdiopkt->size);
666         }
667 
668         if (msg.data == MNULL)
669         {
670             wifi_io_e("[fail] Buffer alloc: T: %d S: %d", upld_type, sdiopkt->size);
671             return MLAN_STATUS_FAILURE;
672         }
673 
674         msg.event = (uint16_t)upld_type;
675         (void)memcpy((void *)msg.data, (const void *)pmbuf, sdiopkt->size);
676 
677 #if CONFIG_WMM
678         if (upld_type == MLAN_TYPE_EVENT && sdiopkt->hostcmd.command == EVENT_TX_DATA_PAUSE)
679         {
680             wifi_handle_event_data_pause(msg.data);
681             wifi_free_eventbuf(msg.data);
682             return MLAN_STATUS_SUCCESS;
683         }
684 #endif
685         status = OSA_MsgQPut(bus.event_queue, &msg);
686 
687         if (status != KOSA_StatusSuccess)
688         {
689             wifi_io_e("Failed to send response on Queue");
690             return MLAN_STATUS_FAILURE;
691         }
692     }
693     else
694     {
695         /* No queues registered yet. Use local handling */
696         if (upld_type == MLAN_TYPE_CMD)
697         {
698             (void)wlan_handle_cmd_resp_packet(pmbuf);
699         }
700     }
701 
702     return MLAN_STATUS_SUCCESS;
703 }
704 
705 #if 0
706 static t_u32 get_ioport(void)
707 {
708     return mlan_adap->ioport;
709 }
710 #endif
711 
wlan_read_rcv_packet(t_u32 port,t_u32 rxlen,t_u32 rx_blocks,t_u32 * type,bool aggr)712 static t_u8 *wlan_read_rcv_packet(t_u32 port, t_u32 rxlen, t_u32 rx_blocks, t_u32 *type, bool aggr)
713 {
714     t_u32 blksize = MLAN_SDIO_BLOCK_SIZE;
715     uint32_t resp;
716     int ret;
717 #if CONFIG_SDIO_MULTI_PORT_RX_AGGR
718     int i = 0;
719 
720     while (true)
721     {
722         /* addr = 0 fn = 1 */
723 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
724         if (aggr == true)
725         {
726             ret = sdio_drv_read_mb(port, 1, rx_blocks, blksize);
727         }
728         else
729         {
730             ret = sdio_drv_read(port, 1, rx_blocks, blksize, inbuf, &resp);
731         }
732 #else
733         {
734             ret = sdio_drv_read(port, 1, rx_blocks, blksize, inbuf, &resp);
735         }
736 #endif
737         if (aggr && !ret)
738         {
739             PRINTF("sdio mp cmd53 read failed: %d ioport=0x%x retry=%d\r\n", ret, port, i);
740             i++;
741             if (sdio_drv_creg_write(HOST_TO_CARD_EVENT_REG, 1, HOST_TERM_CMD53, &resp) == false)
742             {
743                 wifi_d("Set Term cmd53 failed\r\n");
744             }
745             if (i > MAX_READ_IOMEM_RETRY)
746             {
747                 wifi_io_e("sdio_drv_read failed (%d)", ret);
748 #if CONFIG_WIFI_FW_DEBUG
749                 wifi_sdio_reg_dbg(NULL);
750                 if (wm_wifi.wifi_usb_mount_cb != NULL)
751                 {
752                     ret = wm_wifi.wifi_usb_mount_cb();
753                     if (ret == WM_SUCCESS)
754                     {
755                         wifi_dump_firmware_info(NULL);
756                     }
757                     else
758                     {
759                         wifi_e("USB mounting failed");
760                     }
761                 }
762                 else
763                 {
764                     wifi_e("USB mount callback is not registered");
765                 }
766 #endif
767                 return NULL;
768             } /* if (i > MAX_READ_IOMEM_RETRY) */
769             continue;
770         } /* if (aggr && !ret) */
771         break;
772     } /* while(true) */
773 #else
774     /* addr = 0 fn = 1 */
775     ret = sdio_drv_read(port, 1, rx_blocks, blksize, inbuf, &resp);
776     if (!ret)
777     {
778         wifi_io_e("sdio_drv_read failed (%d)", ret);
779 #if CONFIG_WIFI_FW_DEBUG
780         wifi_sdio_reg_dbg(NULL);
781         if (wm_wifi.wifi_usb_mount_cb != NULL)
782         {
783             ret = wm_wifi.wifi_usb_mount_cb();
784             if (ret == WM_SUCCESS)
785             {
786                 wifi_dump_firmware_info(NULL);
787             }
788             else
789             {
790                 wifi_e("USB mounting failed");
791             }
792         }
793         else
794         {
795             wifi_e("USB mount callback is not registered");
796         }
797 
798 #endif
799         return NULL;
800     }
801 #endif
802 
803 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
804 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
805     if ((aggr == false) && (port & (CMD_PORT_SLCT | MLAN_SDIO_BYTE_MODE_MASK)))
806 #endif
807 #endif
808     {
809         SDIOPkt *insdiopkt = (SDIOPkt *)(void *)inbuf;
810         *type              = insdiopkt->pkttype;
811 
812 #if CONFIG_WIFI_IO_DUMP
813         if (insdiopkt->pkttype != 0)
814         {
815             (void)PRINTF("wlan_read_rcv_packet: DUMP:");
816             dump_hex((t_u8 *)inbuf, rx_blocks * blksize);
817         }
818 #endif /* CONFIG_WIFI_IO_DUMP */
819     }
820 
821     return inbuf;
822 }
823 
wlan_get_next_seq_num(void)824 static int wlan_get_next_seq_num(void)
825 {
826      /* No need to increase seqnum as all cmds in RT uses seqnum 0 for STA and
827       * 4096 for uAP */
828     /* seqnum++; */
829     return seqnum;
830 }
831 
832 void wifi_prepare_set_cal_data_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
_wlan_set_cal_data(void)833 static void _wlan_set_cal_data(void)
834 {
835     t_u32 tx_blocks = 4, buflen = MLAN_SDIO_BLOCK_SIZE;
836     uint32_t resp;
837 
838     wifi_sdio_lock();
839 
840     (void)memset(outbuf, 0, SDIO_OUTBUF_LEN);
841 
842     /* sdiopkt = outbuf */
843     wifi_prepare_set_cal_data_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
844 
845     sdiopkt->pkttype = MLAN_TYPE_CMD;
846     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
847 
848     last_cmd_sent = HostCmd_CMD_CFG_DATA;
849 
850     /* send CMD53 to write the command to get mac address */
851 #if defined(SD8801)
852     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
853 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
854     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
855 #endif
856 
857     wifi_sdio_unlock();
858 
859     wifi_sdio_wait_for_cmdresp();
860 }
861 
862 void wifi_prepare_reconfigure_tx_buf_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
863 
wlan_reconfigure_tx_buffers(void)864 static void wlan_reconfigure_tx_buffers(void)
865 {
866     t_u32 tx_blocks = 4, buflen = MLAN_SDIO_BLOCK_SIZE;
867     uint32_t resp;
868 
869     wifi_sdio_lock();
870 
871     (void)memset(outbuf, 0, SDIO_OUTBUF_LEN);
872 
873     /* sdiopkt = outbuf */
874     wifi_prepare_reconfigure_tx_buf_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
875     sdiopkt->pkttype = MLAN_TYPE_CMD;
876     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
877 
878     last_cmd_sent = HostCmd_CMD_RECONFIGURE_TX_BUFF;
879 
880     /* send CMD53 to write the command to get mac address */
881 #if defined(SD8801)
882     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
883 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
884     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
885 #endif
886 
887     wifi_sdio_unlock();
888 
889     wifi_sdio_wait_for_cmdresp();
890 }
891 
892 void wifi_prepare_get_mac_addr_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
893 #ifdef OTP_CHANINFO
894 void wifi_prepare_get_channel_region_cfg_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
895 #endif
896 void wifi_prepare_get_hw_spec_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
897 
898 #ifdef OTP_CHANINFO
wlan_get_channel_region_cfg(void)899 static void wlan_get_channel_region_cfg(void)
900 {
901     uint32_t tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
902     uint32_t resp;
903 
904     wifi_sdio_lock();
905 
906     (void)memset(outbuf, 0, buflen);
907 
908     /* sdiopkt = outbuf */
909     wifi_prepare_get_channel_region_cfg_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
910 
911     sdiopkt->pkttype = MLAN_TYPE_CMD;
912     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
913 
914     last_cmd_sent = HostCmd_CMD_CHAN_REGION_CFG;
915 #if defined(SD8801)
916     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
917 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
918     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
919 #endif
920 
921     wifi_sdio_unlock();
922 
923     wifi_sdio_wait_for_cmdresp();
924 
925 }
926 #endif
927 
wlan_get_hw_spec(void)928 static void wlan_get_hw_spec(void)
929 {
930     uint32_t tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
931     uint32_t resp;
932 
933     wifi_sdio_lock();
934 
935     (void)memset(outbuf, 0, buflen);
936     /* sdiopkt = outbuf */
937     wifi_prepare_get_hw_spec_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
938 
939     sdiopkt->pkttype = MLAN_TYPE_CMD;
940     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
941 
942     last_cmd_sent = HostCmd_CMD_GET_HW_SPEC;
943 #if defined(SD8801)
944     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
945 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
946     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
947 #endif
948 
949     wifi_sdio_unlock();
950 
951     wifi_sdio_wait_for_cmdresp();
952 
953 }
954 
wlan_get_mac_addr_sta(void)955 static void wlan_get_mac_addr_sta(void)
956 {
957     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
958     uint32_t resp;
959 
960     wifi_sdio_lock();
961 
962     (void)memset(outbuf, 0, buflen);
963 
964     /* sdiopkt = outbuf */
965     wifi_prepare_get_mac_addr_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
966 
967     sdiopkt->pkttype = MLAN_TYPE_CMD;
968     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
969 
970     last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
971 
972     /* send CMD53 to write the command to get mac address */
973 #if defined(SD8801)
974     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
975 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
976     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
977 #endif
978 
979     wifi_sdio_unlock();
980 
981     wifi_sdio_wait_for_cmdresp();
982 
983 }
984 
985 #if UAP_SUPPORT
wlan_get_mac_addr_uap(void)986 static void wlan_get_mac_addr_uap(void)
987 {
988     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
989     uint32_t resp;
990     t_u16 seq_number = 0;
991 
992     wifi_sdio_lock();
993 
994     (void)memset(outbuf, 0, buflen);
995     seq_number = HostCmd_SET_SEQ_NO_BSS_INFO(0 /* seq_num */, 0 /* bss_num */, MLAN_BSS_TYPE_UAP);
996 
997     /* sdiopkt = outbuf */
998     wifi_prepare_get_mac_addr_cmd(&sdiopkt->hostcmd, seq_number);
999 
1000     sdiopkt->pkttype = MLAN_TYPE_CMD;
1001     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1002 
1003     last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
1004 
1005     /* send CMD53 to write the command to get mac address */
1006 #if defined(SD8801)
1007     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1008 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1009     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1010 #endif
1011 
1012     wifi_sdio_unlock();
1013 
1014     wifi_sdio_wait_for_cmdresp();
1015 
1016 }
1017 #endif
1018 
1019 void wifi_prepare_get_fw_ver_ext_cmd(HostCmd_DS_COMMAND *cmd, int seq_number, int version_str_sel);
wlan_get_fw_ver_ext(int version_str_sel)1020 static void wlan_get_fw_ver_ext(int version_str_sel)
1021 {
1022     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1023     uint32_t resp;
1024 
1025     wifi_sdio_lock();
1026 
1027     (void)memset(outbuf, 0, buflen);
1028 
1029     /* sdiopkt = outbuf */
1030     wifi_prepare_get_fw_ver_ext_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num(), version_str_sel);
1031 
1032     sdiopkt->pkttype = MLAN_TYPE_CMD;
1033     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1034 
1035     last_cmd_sent = HostCmd_CMD_VERSION_EXT;
1036 
1037     /* send CMD53 to write the command to get mac address */
1038 #if defined(SD8801)
1039     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1040 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1041     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1042 #endif
1043 
1044     wifi_sdio_unlock();
1045 
1046     wifi_sdio_wait_for_cmdresp();
1047 
1048 }
1049 
1050 void wifi_prepare_get_value1(HostCmd_DS_COMMAND *cmd, int seq_number);
1051 
wlan_get_value_1(void)1052 static void wlan_get_value_1(void)
1053 {
1054     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1055     uint32_t resp;
1056 
1057     wifi_sdio_lock();
1058 
1059     (void)memset(outbuf, 0, buflen);
1060 
1061     /* sdiopkt = outbuf */
1062     wifi_prepare_get_value1(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1063 
1064     sdiopkt->pkttype = MLAN_TYPE_CMD;
1065     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1066 
1067     last_cmd_sent = HostCmd_CMD_MAC_REG_ACCESS;
1068 
1069 #if defined(SD8801)
1070     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1071 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1072     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1073 #endif
1074 
1075     wifi_sdio_unlock();
1076 
1077     wifi_sdio_wait_for_cmdresp();
1078 
1079 }
1080 
1081 void wifi_prepare_set_mac_addr_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
_wlan_set_mac_addr(void)1082 static void _wlan_set_mac_addr(void)
1083 {
1084     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1085     uint32_t resp;
1086 
1087     wifi_sdio_lock();
1088 
1089     (void)memset(outbuf, 0, buflen);
1090 
1091     /* sdiopkt = outbuf */
1092     wifi_prepare_set_mac_addr_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1093 
1094     sdiopkt->pkttype = MLAN_TYPE_CMD;
1095     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1096 
1097     last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
1098 
1099     /* send CMD53 to write the command to get mac address */
1100 #if defined(SD8801)
1101     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1102 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1103     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1104 #endif
1105 
1106     wifi_sdio_unlock();
1107 
1108     wifi_sdio_wait_for_cmdresp();
1109 }
1110 
1111 #if CONFIG_11N
wlan_set_11n_cfg(void)1112 static void wlan_set_11n_cfg(void)
1113 {
1114     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1115     uint32_t resp;
1116 
1117     wifi_sdio_lock();
1118 
1119     (void)memset(outbuf, 0, SDIO_OUTBUF_LEN);
1120 
1121     wrapper_wlan_cmd_11n_cfg(&sdiopkt->hostcmd);
1122     /* sdiopkt = outbuf */
1123     sdiopkt->hostcmd.seq_num = (t_u16)wlan_get_next_seq_num();
1124     sdiopkt->pkttype         = MLAN_TYPE_CMD;
1125     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1126 
1127     last_cmd_sent            = HostCmd_CMD_11N_CFG;
1128 
1129 #if defined(SD8801)
1130     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1131 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1132     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1133 #endif
1134 
1135     wifi_sdio_unlock();
1136 
1137     wifi_sdio_wait_for_cmdresp();
1138 }
1139 
1140 #if CONFIG_ENABLE_AMSDU_RX
1141 void wifi_prepare_enable_amsdu_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
wlan_enable_amsdu(void)1142 static void wlan_enable_amsdu(void)
1143 {
1144     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1145     uint32_t resp;
1146 
1147     wifi_sdio_lock();
1148 
1149     (void)memset(outbuf, 0, buflen);
1150 
1151     /* sdiopkt = outbuf */
1152     wifi_prepare_enable_amsdu_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1153 
1154     sdiopkt->pkttype = MLAN_TYPE_CMD;
1155     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1156 
1157     last_cmd_sent = HostCmd_CMD_AMSDU_AGGR_CTRL;
1158 
1159 #if defined(SD8801)
1160     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1161 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1162     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1163 #endif
1164 
1165     wifi_sdio_unlock();
1166 
1167     wifi_sdio_wait_for_cmdresp();
1168 
1169 }
1170 #endif /* CONFIG_ENABLE_AMSDU_RX */
1171 #endif /* CONFIG_11N */
1172 
wlan_cmd_shutdown(void)1173 static void wlan_cmd_shutdown(void)
1174 {
1175     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1176     uint32_t resp;
1177 
1178     (void)memset(outbuf, 0, buflen);
1179 
1180     /* sdiopkt = outbuf */
1181     sdiopkt->hostcmd.command = HostCmd_CMD_FUNC_SHUTDOWN;
1182     sdiopkt->hostcmd.size    = (t_u16)S_DS_GEN;
1183     sdiopkt->hostcmd.seq_num = (t_u16)wlan_get_next_seq_num();
1184     sdiopkt->hostcmd.result  = 0;
1185 
1186     sdiopkt->pkttype = MLAN_TYPE_CMD;
1187     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1188 
1189     last_cmd_sent = HostCmd_CMD_FUNC_SHUTDOWN;
1190 
1191     (void)sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1192 }
1193 
1194 void wlan_prepare_mac_control_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
wlan_set_mac_ctrl(void)1195 static void wlan_set_mac_ctrl(void)
1196 {
1197     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1198     uint32_t resp;
1199 
1200     wifi_sdio_lock();
1201 
1202     (void)memset(outbuf, 0, buflen);
1203 
1204     /* sdiopkt = outbuf */
1205     wlan_prepare_mac_control_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1206 
1207     sdiopkt->pkttype = MLAN_TYPE_CMD;
1208     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1209 
1210     last_cmd_sent = HostCmd_CMD_MAC_CONTROL;
1211 
1212     /* send CMD53 to write the command to set mac control */
1213 #if defined(SD8801)
1214     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1215 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1216     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1217 #endif
1218 
1219     wifi_sdio_unlock();
1220 
1221     wifi_sdio_wait_for_cmdresp();
1222 
1223 }
1224 
wlan_cmd_init(void)1225 static void wlan_cmd_init(void)
1226 {
1227     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1228     uint32_t resp;
1229 
1230     wifi_sdio_lock();
1231 
1232     (void)memset(outbuf, 0, buflen);
1233 
1234     /* sdiopkt = outbuf */
1235     sdiopkt->hostcmd.command = HostCmd_CMD_FUNC_INIT;
1236     sdiopkt->hostcmd.size    = (t_u16)S_DS_GEN;
1237     sdiopkt->hostcmd.seq_num = (t_u16)wlan_get_next_seq_num();
1238     sdiopkt->hostcmd.result  = 0;
1239 
1240     sdiopkt->pkttype = MLAN_TYPE_CMD;
1241     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1242 
1243     last_cmd_sent = HostCmd_CMD_FUNC_INIT;
1244 
1245 #if defined(SD8801)
1246     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1247 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1248     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1249 #endif
1250 
1251     wifi_sdio_unlock();
1252 
1253     wifi_sdio_wait_for_cmdresp();
1254 }
1255 
1256 #ifdef WLAN_LOW_POWER_ENABLE
1257 void wifi_prepare_low_power_mode_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
wlan_set_low_power_mode()1258 static int wlan_set_low_power_mode()
1259 {
1260     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1261     uint32_t resp;
1262 
1263     wifi_sdio_lock();
1264 
1265     (void)memset(outbuf, 0, buflen);
1266 
1267     /* sdiopkt = outbuf */
1268 
1269     wifi_prepare_low_power_mode_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1270 
1271     sdiopkt->pkttype = MLAN_TYPE_CMD;
1272     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1273 
1274     last_cmd_sent = HostCmd_CMD_LOW_POWER_MODE;
1275 
1276     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1277 
1278     wifi_sdio_unlock();
1279 
1280     wifi_sdio_wait_for_cmdresp();
1281 
1282     return true;
1283 }
1284 #endif
1285 
1286 #if CONFIG_EXTERNAL_BLE_COEX
1287 void wifi_prepare_set_coex_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
1288 
wlan_set_ext_ble_coex_mode()1289 static int wlan_set_ext_ble_coex_mode()
1290 {
1291     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1292     uint32_t resp;
1293 
1294     if (!board_coex_interface())
1295     {
1296         return false;
1297     }
1298 
1299     board_coex_pin_config(1);
1300 
1301     wifi_sdio_lock();
1302 
1303     (void)memset(outbuf, 0, buflen);
1304 
1305     /* sdiopkt = outbuf */
1306     wifi_prepare_set_coex_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1307 
1308     sdiopkt->pkttype = MLAN_TYPE_CMD;
1309     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1310 
1311     last_cmd_sent = HostCmd_CMD_ROBUST_COEX;
1312 
1313     /* send CMD53 to write the command to set mac control */
1314     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1315 
1316     wifi_sdio_unlock();
1317 
1318     wifi_sdio_wait_for_cmdresp();
1319 
1320     return true;
1321 }
1322 #endif
1323 
1324 /* Setup the firmware with commands */
wlan_fw_init_cfg(void)1325 static void wlan_fw_init_cfg(void)
1326 {
1327 #if CONFIG_FW_VDLL
1328     mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[0];
1329     mlan_adapter *pmadapter = pmpriv->adapter;
1330 #endif
1331 
1332     wifi_io_d("FWCMD : INIT (0xa9)");
1333 
1334     wlan_cmd_init();
1335 
1336 #ifdef WLAN_LOW_POWER_ENABLE
1337     if (low_power_mode)
1338     {
1339 #if CONFIG_FW_VDLL
1340         while (pmadapter->vdll_in_progress == MTRUE)
1341         {
1342             OSA_TimeDelay(50);
1343         }
1344 #endif
1345         wifi_io_d("CMD : LOW_POWER_MODE (0x128)");
1346 
1347         wlan_set_low_power_mode();
1348     }
1349 #endif
1350 
1351     if (cal_data_valid)
1352     {
1353 #if CONFIG_FW_VDLL
1354         while (pmadapter->vdll_in_progress == MTRUE)
1355         {
1356             OSA_TimeDelay(50);
1357         }
1358 #endif
1359         wifi_io_d("CMD : SET_CAL_DATA (0x8f)");
1360 
1361         _wlan_set_cal_data();
1362     }
1363 
1364     /* When cal data set command is sent, fimrware looses alignment of SDIO Tx buffers.
1365      * So we need to send reconfigure command. This can be removed if fix is added in firmware.
1366      */
1367     wifi_io_d("CMD : RECONFIGURE_TX_BUFF (0xd9)");
1368 
1369 #if CONFIG_FW_VDLL
1370     while (pmadapter->vdll_in_progress == MTRUE)
1371     {
1372         OSA_TimeDelay(50);
1373     }
1374 #endif
1375 
1376     wlan_reconfigure_tx_buffers();
1377 
1378     if (mac_addr_valid)
1379     {
1380         wifi_io_d("CMD : SET_MAC_ADDR (0x4d)");
1381 #if CONFIG_FW_VDLL
1382         while (pmadapter->vdll_in_progress == MTRUE)
1383         {
1384             OSA_TimeDelay(50);
1385         }
1386 #endif
1387         _wlan_set_mac_addr();
1388     }
1389 
1390 #ifdef OTP_CHANINFO
1391     wifi_io_d("CMD : Channel Region CFG (0x0242)");
1392 
1393 #if CONFIG_FW_VDLL
1394     while (pmadapter->vdll_in_progress == MTRUE)
1395     {
1396         OSA_TimeDelay(50);
1397     }
1398 #endif
1399 
1400     wlan_get_channel_region_cfg();
1401 #endif
1402 
1403     wifi_io_d("CMD : GET_HW_SPEC (0x03)");
1404 
1405 #if CONFIG_FW_VDLL
1406     while (pmadapter->vdll_in_progress == MTRUE)
1407     {
1408         OSA_TimeDelay(50);
1409     }
1410 #endif
1411 
1412     wlan_get_hw_spec();
1413 
1414 #if CONFIG_FW_VDLL
1415     while (pmadapter->vdll_in_progress == MTRUE)
1416     {
1417         OSA_TimeDelay(50);
1418     }
1419 #endif
1420 
1421     wlan_get_value_1();
1422 
1423     if (wm_wifi.wifi_init_done == 0U)
1424     {
1425 
1426         wifi_io_d("CMD : GET_FW_VER_EXT (0x97)");
1427 
1428 #if CONFIG_FW_VDLL
1429         while (pmadapter->vdll_in_progress == MTRUE)
1430         {
1431             OSA_TimeDelay(50);
1432         }
1433 #endif
1434 
1435         wlan_get_fw_ver_ext(0);
1436     }
1437 
1438     wifi_io_d("CMD : GET_MAC_ADDR (0x4d)");
1439 
1440 #if CONFIG_FW_VDLL
1441     while (pmadapter->vdll_in_progress == MTRUE)
1442     {
1443         OSA_TimeDelay(50);
1444     }
1445 #endif
1446 
1447     wlan_get_mac_addr_sta();
1448 
1449     wifi_io_d("CMD : GET_MAC_ADDR (0x4d)");
1450 
1451 #if CONFIG_FW_VDLL
1452     while (pmadapter->vdll_in_progress == MTRUE)
1453     {
1454         OSA_TimeDelay(50);
1455     }
1456 #endif
1457 
1458 #if UAP_SUPPORT
1459     wlan_get_mac_addr_uap();
1460 #endif
1461 
1462     if (wm_wifi.wifi_init_done == 0U)
1463     {
1464 
1465         wifi_io_d("CMD : GET_FW_VER_EXT (0x97)");
1466 
1467 #if CONFIG_FW_VDLL
1468         while (pmadapter->vdll_in_progress == MTRUE)
1469         {
1470             OSA_TimeDelay(50);
1471         }
1472 #endif
1473 
1474         wlan_get_fw_ver_ext(3);
1475 
1476     }
1477 
1478     wifi_io_d("CMD : MAC_CTRL (0x28)");
1479 
1480 #if CONFIG_FW_VDLL
1481     while (pmadapter->vdll_in_progress == MTRUE)
1482     {
1483         OSA_TimeDelay(50);
1484     }
1485 #endif
1486 
1487     wlan_set_mac_ctrl();
1488 
1489     if (wm_wifi.wifi_init_done == 0U)
1490     {
1491         wifi_io_d("CMD : GET_FW_VER_EXT (0x97)");
1492 
1493 #if CONFIG_FW_VDLL
1494         while (pmadapter->vdll_in_progress == MTRUE)
1495         {
1496             OSA_TimeDelay(50);
1497         }
1498 #endif
1499 
1500         wlan_get_fw_ver_ext(4);
1501     }
1502 
1503 #if CONFIG_EXTERNAL_BLE_COEX
1504 #if CONFIG_FW_VDLL
1505     while (pmadapter->vdll_in_progress == MTRUE)
1506     {
1507         OSA_TimeDelay(50);
1508     }
1509 #endif
1510 
1511     wlan_set_ext_ble_coex_mode();
1512 #endif
1513 
1514 #if CONFIG_11N
1515     wifi_io_d("CMD : 11N_CFG (0xcd)");
1516 
1517 #if CONFIG_FW_VDLL
1518     while (pmadapter->vdll_in_progress == MTRUE)
1519     {
1520         OSA_TimeDelay(50);
1521     }
1522 #endif
1523 
1524     wlan_set_11n_cfg();
1525 
1526 #if CONFIG_ENABLE_AMSDU_RX
1527     wifi_io_d("CMD : AMSDU_AGGR_CTRL (0xdf)");
1528 
1529 #if CONFIG_FW_VDLL
1530     while (pmadapter->vdll_in_progress == MTRUE)
1531     {
1532         OSA_TimeDelay(50);
1533     }
1534 #endif
1535 
1536     wlan_enable_amsdu();
1537 
1538 #endif /* CONFIG_ENABLE_AMSDU_RX */
1539 #endif /* CONFIG_11N */
1540 
1541     return;
1542 }
1543 
1544 #if CONFIG_P2P
wlan_send_gen_sdio_cmd(t_u8 * buf,t_u32 buflen)1545 mlan_status wlan_send_gen_sdio_cmd(t_u8 *buf, t_u32 buflen)
1546 {
1547     SDIOPkt *sdio = (SDIOPkt *)outbuf;
1548     uint32_t resp;
1549 
1550     (void)memset(outbuf, 0, 512);
1551 
1552     wifi_sdio_lock();
1553     (void)memcpy((void *)outbuf, (const void *)buf, buflen);
1554     sdio->pkttype         = MLAN_TYPE_CMD;
1555     sdio->hostcmd.seq_num = (0x01) << 13;
1556     sdio->size            = sdio->hostcmd.size + INTF_HEADER_LEN;
1557 
1558     sdio_drv_write(mlan_adap->ioport, 1, 1, buflen, (t_u8 *)outbuf, &resp);
1559 
1560     last_cmd_sent = sdio->hostcmd.command;
1561     wifi_sdio_unlock();
1562 
1563     return 0;
1564 }
1565 #endif
1566 
1567 #if CONFIG_FW_VDLL
wlan_send_sdio_vdllcmd(t_u8 * buf,t_u32 tx_blocks,t_u32 buflen)1568 int wlan_send_sdio_vdllcmd(t_u8 *buf, t_u32 tx_blocks, t_u32 buflen)
1569 {
1570     SDIOPkt *sdio = (SDIOPkt *)(void *)outbuf;
1571     uint32_t resp;
1572 
1573     (void)memcpy((void *)outbuf, (const void *)buf, tx_blocks * buflen);
1574     sdio->pkttype = MLAN_TYPE_VDLL;
1575     sdio->size    = sdio->hostcmd.size + INTF_HEADER_LEN;
1576 
1577 #if CONFIG_WIFI_IO_DUMP
1578     (void)PRINTF("OUT_CMD");
1579     dump_hex(outbuf, sdio->size);
1580 #endif /* CONFIG_WIFI_IO_DUMP */
1581 #if defined(SD8801)
1582     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1583 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1584     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1585 #endif
1586 
1587     return WM_SUCCESS;
1588 }
1589 #endif
1590 
wlan_send_sdio_cmd(t_u8 * buf,t_u32 tx_blocks,t_u32 buflen)1591 int wlan_send_sdio_cmd(t_u8 *buf, t_u32 tx_blocks, t_u32 buflen)
1592 {
1593     SDIOPkt *sdio = (SDIOPkt *)(void *)outbuf;
1594     uint32_t resp;
1595 
1596     (void)wifi_sdio_lock();
1597 
1598     (void)memcpy((void *)outbuf, (const void *)buf, tx_blocks * buflen);
1599     sdio->pkttype = MLAN_TYPE_CMD;
1600     sdio->size    = sdio->hostcmd.size + INTF_HEADER_LEN;
1601 
1602 #if CONFIG_WIFI_IO_DUMP
1603     (void)PRINTF("OUT_CMD");
1604     dump_hex(outbuf, sdio->size);
1605 #endif /* CONFIG_WIFI_IO_DUMP */
1606 #if defined(SD8801)
1607     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1608 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1609     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1610 #endif
1611 
1612     last_cmd_sent = sdio->hostcmd.command;
1613     wifi_sdio_unlock();
1614 
1615     return WM_SUCCESS;
1616 }
1617 
wifi_send_cmdbuffer(t_u32 tx_blocks,t_u32 len)1618 int wifi_send_cmdbuffer(t_u32 tx_blocks, t_u32 len)
1619 {
1620     return wlan_send_sdio_cmd(ctrl_cmd_buf, tx_blocks, len);
1621 }
1622 
1623 #if CONFIG_FW_VDLL
wifi_send_vdllcmdbuffer(t_u32 tx_blocks,t_u32 len)1624 int wifi_send_vdllcmdbuffer(t_u32 tx_blocks, t_u32 len)
1625 {
1626     return wlan_send_sdio_vdllcmd(vdll_cmd_buf, tx_blocks, len);
1627 }
1628 #endif
1629 
1630 #if CONFIG_WMM
1631 
1632 #if CONFIG_SDIO_MULTI_PORT_TX_AGGR
1633 static t_u32 buf_block_len = 0;
1634 static t_u8 start_port     = -1;
1635 static t_u8 ports          = 0;
1636 static t_u8 pkt_cnt        = 0;
1637 
1638 /**
1639  *  @brief This function gets available SDIO port for writing data
1640  *
1641  *  @param pmadapter  A pointer to mlan_adapter structure
1642  *  @param pport      A pointer to port number
1643  *  @return           MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1644  */
wlan_get_wr_port_data(t_u8 * pport)1645 mlan_status wlan_get_wr_port_data(t_u8 *pport)
1646 {
1647 #if CONFIG_WIFI_IO_DEBUG
1648     t_u32 wr_bitmap = mlan_adap->mp_wr_bitmap;
1649 #endif
1650 
1651     ENTER();
1652 
1653     wifi_io_d("wlan_get_wr_port_data: mp_wr_bitmap=0x%08x", wr_bitmap);
1654 
1655     if ((1U << txportno) & mlan_adap->mp_wr_bitmap)
1656     {
1657         mlan_adap->mp_wr_bitmap &= (t_u32)(~(1 << txportno));
1658         *pport = txportno;
1659         txportno++;
1660 
1661         if (txportno == mlan_adap->mp_end_port)
1662         {
1663 #if defined(SD8801)
1664             txportno = 1;
1665 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1666             txportno = 0;
1667 #endif
1668         }
1669     }
1670     else
1671     {
1672         LEAVE();
1673         return MLAN_STATUS_RESOURCE;
1674     }
1675 
1676 #if defined(SD8801)
1677     if (*pport == CTRL_PORT)
1678     {
1679         wifi_io_d("Invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\r\n", *pport, txportno, wr_bitmap,
1680                mlan_adap->mp_wr_bitmap);
1681         LEAVE();
1682         return MLAN_STATUS_FAILURE;
1683     }
1684 #endif
1685 
1686     wifi_io_d("port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n", *pport, wr_bitmap, mlan_adap->mp_wr_bitmap);
1687 
1688     LEAVE();
1689     return MLAN_STATUS_SUCCESS;
1690 }
1691 
wifi_tx_data(t_u8 start_port,t_u8 ports,t_u8 pkt_cnt,t_u32 txlen)1692 static mlan_status wifi_tx_data(t_u8 start_port, t_u8 ports, t_u8 pkt_cnt, t_u32 txlen)
1693 {
1694     t_u32 cmd53_port;
1695     t_u32 tx_blocks = 0, buflen = 0;
1696     uint32_t resp;
1697     bool ret;
1698 #if CONFIG_WIFI_FW_DEBUG
1699     int ret_cb;
1700 #endif
1701 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1702     t_u32 port_count = 0;
1703 #endif
1704 
1705     calculate_sdio_write_params(txlen, &tx_blocks, &buflen);
1706 
1707     if (pkt_cnt == 1)
1708     {
1709         cmd53_port = mlan_adap->ioport + start_port;
1710     }
1711     else
1712     {
1713 #if defined(SD8801)
1714         cmd53_port = (mlan_adap->ioport | SDIO_MPA_ADDR_BASE | (ports << 4)) + start_port;
1715 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1716         port_count = ports - 1U;
1717         cmd53_port = (mlan_adap->ioport | SDIO_MPA_ADDR_BASE | (port_count << 8)) + start_port;
1718 #endif
1719     }
1720 
1721     //(void)PRINTF("cmd53_port=%x, ports=%x, start_port=%x, pkt_cnt=%d, txlen=%d, txblocks=%d\r\n", cmd53_port, ports, start_port, pkt_cnt, txlen, tx_blocks);
1722 
1723     /* send CMD53 */
1724     ret = sdio_drv_write(cmd53_port, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1725 
1726     if (ret == false)
1727     {
1728         wifi_io_e("sdio_drv_write failed (%d)", ret);
1729 #if CONFIG_WIFI_FW_DEBUG
1730         wifi_sdio_reg_dbg(NULL);
1731         if (wm_wifi.wifi_usb_mount_cb != NULL)
1732         {
1733             ret_cb = wm_wifi.wifi_usb_mount_cb();
1734             if (ret_cb == WM_SUCCESS)
1735                 wifi_dump_firmware_info(NULL);
1736             else
1737                 wifi_e("USB mounting failed");
1738         }
1739         else
1740             wifi_e("USB mount callback is not registered");
1741 #endif
1742         return MLAN_STATUS_RESOURCE;
1743     }
1744     return MLAN_STATUS_SUCCESS;
1745 }
1746 
wlan_xmit_wmm_pkt(t_u8 interface,t_u32 txlen,t_u8 * tx_buf)1747 mlan_status wlan_xmit_wmm_pkt(t_u8 interface, t_u32 txlen, t_u8 *tx_buf)
1748 {
1749     t_u32 tx_blocks = 0, buflen = 0;
1750     mlan_status ret = MLAN_STATUS_SUCCESS;
1751 #if CONFIG_WMM_UAPSD
1752     bool last_packet = 0;
1753 #endif
1754     t_u8 port     = 0;
1755 
1756     if (buf_block_len == 0)
1757     {
1758         start_port = -1;
1759         ports      = 0;
1760         pkt_cnt    = 0;
1761     }
1762 
1763     calculate_sdio_write_params(txlen, &tx_blocks, &buflen);
1764 
1765 #if CONFIG_WIFI_IO_DEBUG
1766     (void)PRINTF("%s: txportno = %d mlan_adap->mp_wr_bitmap: %x\n\r", __func__, txportno, mlan_adap->mp_wr_bitmap);
1767 #endif /* CONFIG_WIFI_IO_DEBUG */
1768 
1769     ret = wlan_get_wr_port_data(&port);
1770     if (ret != WM_SUCCESS)
1771     {
1772         return MLAN_STATUS_RESOURCE;
1773     }
1774 
1775 #if CONFIG_WMM_UAPSD
1776     if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1777         wifi_check_last_packet_indication(mlan_adap->priv[interface]))
1778     {
1779 #if CONFIG_TX_RX_ZERO_COPY
1780         process_pkt_hdrs_flags(&((outbuf_t *)tx_buf)->intf_header[0], MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1781 #else
1782         process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1783 #endif
1784         last_packet = 1;
1785     }
1786 #endif
1787 
1788     if (buf_block_len == 0)
1789     {
1790         start_port = port;
1791     }
1792 
1793 #if CONFIG_TX_RX_ZERO_COPY
1794     net_tx_zerocopy_process_cb(outbuf + buf_block_len, tx_buf, txlen);
1795 #else
1796     memcpy(outbuf + buf_block_len, tx_buf, txlen);
1797 #endif
1798 
1799     buf_block_len += tx_blocks * buflen;
1800 
1801     ports++;
1802     pkt_cnt++;
1803 
1804 #if CONFIG_WMM_UAPSD
1805     if (last_packet)
1806     {
1807         mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1808         OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1809     }
1810 #endif
1811 
1812     wifi_io_info_d("OUT: i/f: %d, len: %d, start port: %d, pkt_cnt: %d, bufblocklen %d", interface, tx_blocks * buflen, start_port, pkt_cnt, buf_block_len);
1813 
1814     return MLAN_STATUS_SUCCESS;
1815 }
1816 
wlan_flush_wmm_pkt(t_u8 pkt_count)1817 mlan_status wlan_flush_wmm_pkt(t_u8 pkt_count)
1818 {
1819     int ret;
1820 
1821     if (pkt_count == 0)
1822         return MLAN_STATUS_SUCCESS;
1823 
1824     w_pkt_d("Data TX: Driver=>FW, pkt_count %d", pkt_cnt);
1825 
1826     ret = wifi_tx_data(start_port, ports, pkt_cnt, buf_block_len);
1827 
1828     buf_block_len = 0;
1829 
1830     if (ret != MLAN_STATUS_SUCCESS)
1831     {
1832         return MLAN_STATUS_RESOURCE;
1833     }
1834 
1835     return MLAN_STATUS_SUCCESS;
1836 }
1837 #else
1838 extern int retry_attempts;
1839 
get_free_port(void)1840 static int get_free_port(void)
1841 {
1842     /* Check if the port is available */
1843     if (!((1 << txportno) & mlan_adap->mp_wr_bitmap))
1844     {
1845 #if CONFIG_WIFI_IO_DEBUG
1846         wifi_io_e(
1847             "txportno out of sync txportno "
1848             "= (%d) mp_wr_bitmap = (0x%x)",
1849             txportno, mlan_adap->mp_wr_bitmap);
1850 #endif /* CONFIG_WIFI_IO_DEBUG */
1851 
1852         return -WM_FAIL;
1853     }
1854     else
1855     {
1856         /* Mark the port number we will use */
1857         mlan_adap->mp_wr_bitmap &= ~(1 << txportno);
1858     }
1859     return WM_SUCCESS;
1860 }
1861 
wlan_xmit_wmm_pkt(t_u8 interface,t_u32 txlen,t_u8 * tx_buf)1862 mlan_status wlan_xmit_wmm_pkt(t_u8 interface, t_u32 txlen, t_u8 *tx_buf)
1863 {
1864     t_u32 tx_blocks = 0, buflen = 0;
1865     uint32_t resp;
1866     int ret   = false;
1867     int retry = retry_attempts;
1868 #if CONFIG_WMM_UAPSD
1869     bool last_packet = 0;
1870 #endif
1871 
1872     wifi_io_info_d("OUT: i/f: %d len: %d", interface, tx_blocks * buflen);
1873 
1874     calculate_sdio_write_params(txlen, &tx_blocks, &buflen);
1875 
1876 #if CONFIG_WIFI_IO_DEBUG
1877     (void)PRINTF("%s: txportno = %d mlan_adap->mp_wr_bitmap: %x\n\r", __func__, txportno, mlan_adap->mp_wr_bitmap);
1878 #endif /* CONFIG_WIFI_IO_DEBUG */
1879 
1880 retry_xmit:
1881     ret = get_free_port();
1882     if (ret == -WM_FAIL)
1883     {
1884         if (!retry)
1885         {
1886             ret = MLAN_STATUS_RESOURCE;
1887             goto exit_fn;
1888         }
1889         else
1890         {
1891             retry--;
1892             /* Allow the other thread to run and hence
1893              * update the write bitmap so that pkt
1894              * can be sent to FW */
1895             OSA_TimeDelay(1);
1896             goto retry_xmit;
1897         }
1898     }
1899 
1900 #if CONFIG_WMM_UAPSD
1901     if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1902         wifi_check_last_packet_indication(mlan_adap->priv[interface]))
1903     {
1904         process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1905         last_packet = 1;
1906     }
1907 #endif
1908 
1909     /* send CMD53 */
1910     ret = sdio_drv_write(mlan_adap->ioport + txportno, 1, tx_blocks, buflen, tx_buf, &resp);
1911 
1912     txportno++;
1913     if (txportno == mlan_adap->mp_end_port)
1914     {
1915 #if defined(SD8801)
1916         txportno = 1;
1917 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1918         txportno = 0;
1919 #endif
1920     }
1921 
1922     if (ret == false)
1923     {
1924 #if CONFIG_WMM_UAPSD
1925         if (last_packet)
1926             process_pkt_hdrs_flags((t_u8 *)tx_buf, 0);
1927 #endif
1928 
1929         wifi_io_e("sdio_drv_write failed (%d)", ret);
1930 #if CONFIG_WIFI_FW_DEBUG
1931         wifi_sdio_reg_dbg(NULL);
1932         if (wm_wifi.wifi_usb_mount_cb != NULL)
1933         {
1934             ret = wm_wifi.wifi_usb_mount_cb();
1935             if (ret == WM_SUCCESS)
1936                 wifi_dump_firmware_info(NULL);
1937             else
1938                 wifi_e("USB mounting failed");
1939         }
1940         else
1941             wifi_e("USB mount callback is not registered");
1942 #endif
1943         ret = MLAN_STATUS_RESOURCE;
1944         goto exit_fn;
1945     }
1946 
1947 #if CONFIG_WMM_UAPSD
1948     if (last_packet)
1949     {
1950         mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1951         OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1952     }
1953 #endif
1954 
1955     ret = MLAN_STATUS_SUCCESS;
1956 
1957 exit_fn:
1958 
1959     return ret;
1960 }
1961 
wlan_flush_wmm_pkt(t_u8 pkt_count)1962 mlan_status wlan_flush_wmm_pkt(t_u8 pkt_count)
1963 {
1964     return MLAN_STATUS_SUCCESS;
1965 }
1966 
1967 #endif
1968 #endif
1969 
wlan_xmit_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface,t_u32 tx_control)1970 mlan_status wlan_xmit_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface, t_u32 tx_control)
1971 {
1972 
1973     (void)interface;
1974 
1975     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1976 
1977     process_pkt_hdrs((t_u8 *)buffer, txlen, interface, 0, tx_control);
1978 
1979     return wifi_send_fw_data(buffer, txlen);
1980 }
1981 
1982 #if CONFIG_WMM
wlan_xmit_bypass_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface)1983 mlan_status wlan_xmit_bypass_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface)
1984 {
1985 
1986     (void)interface;
1987 
1988     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1989 
1990     return wifi_send_fw_data(buffer, txlen);
1991 }
1992 #endif
1993 
wlan_send_null_packet(pmlan_private priv,t_u8 flags)1994 mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
1995 {
1996     mlan_status ret;
1997     t_u8 pbuf[128]  = {0};
1998     TxPD *ptxpd    = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
1999 
2000     ptxpd->bss_type      = priv->bss_type;
2001     ptxpd->bss_num       = GET_BSS_NUM(priv);
2002     ptxpd->tx_pkt_offset = 0x16; /* we'll just make this constant */
2003     ptxpd->tx_pkt_length = 0;
2004     ptxpd->tx_control    = 0;
2005     ptxpd->priority      = 0;
2006     ptxpd->flags         = flags;
2007     ptxpd->pkt_delay_2ms = 0;
2008 
2009     ret = wifi_send_fw_data(pbuf, sizeof(TxPD) + INTF_HEADER_LEN);
2010 
2011     if (ret != MLAN_STATUS_SUCCESS)
2012     {
2013         wifi_io_d("sdio_drv_write failed (%d)", ret);
2014         return MLAN_STATUS_FAILURE;
2015     }
2016 
2017     return MLAN_STATUS_SUCCESS;
2018 }
2019 
2020 /*
2021  * This function gets interrupt status.
2022  */
wlan_interrupt(mlan_adapter * pmadapter)2023 t_void wlan_interrupt(mlan_adapter *pmadapter)
2024 {
2025     /* Read SDIO multiple port group registers */
2026     uint32_t resp = 0;
2027     int ret;
2028     t_u8 *mp_regs = pmadapter->mp_regs;
2029 
2030     /* Read the registers in DMA aligned buffer */
2031 #if defined(SD8801)
2032     ret = sdio_drv_read(0, 1, 1, MAX_MP_REGS, mp_regs, &resp);
2033 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2034     ret = sdio_drv_read(REG_PORT | MLAN_SDIO_BYTE_MODE_MASK, 1, 1, MAX_MP_REGS, mp_regs, &resp);
2035 #endif
2036 
2037     if (!ret)
2038     {
2039         return;
2040     }
2041 
2042     t_u8 sdio_ireg = mp_regs[HOST_INT_STATUS_REG];
2043 
2044     if (sdio_ireg != 0U)
2045     {
2046         /*
2047          * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
2048          * Clear the interrupt status register
2049          */
2050         pmadapter->sdio_ireg |= sdio_ireg;
2051     }
2052 
2053 #if CONFIG_WMM
2054     t_u32 wr_bitmap;
2055 
2056 #if defined(SD8801)
2057     wr_bitmap = ((t_u16)mp_regs[WR_BITMAP_U]) << 8;
2058     wr_bitmap |= (t_u16)mp_regs[WR_BITMAP_L];
2059 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2060     wr_bitmap = (t_u32)mp_regs[WR_BITMAP_L];
2061     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_U]) << 8;
2062     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1L]) << 16;
2063     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1U]) << 24;
2064 #endif
2065 
2066     if (!!wr_bitmap)
2067     {
2068         if (mlan_adap->wait_txbuf == true)
2069         {
2070             OSA_SemaphorePost((osa_semaphore_handle_t)txbuf_sem);
2071             send_wifi_driver_tx_data_event(0);
2072         }
2073     }
2074 #endif
2075 
2076 #if CONFIG_WIFI_IO_DEBUG
2077     t_u32 rd_bitmap;
2078 #if !CONFIG_WMM
2079     t_u32 wr_bitmap;
2080 
2081 #if defined(SD8801)
2082     wr_bitmap = ((t_u16)mp_regs[WR_BITMAP_U]) << 8;
2083     wr_bitmap |= (t_u16)mp_regs[WR_BITMAP_L];
2084 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2085     wr_bitmap = (t_u32)mp_regs[WR_BITMAP_L];
2086     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_U]) << 8;
2087     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1L]) << 16;
2088     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1U]) << 24;
2089 #endif
2090 
2091 #endif
2092 #if defined(SD8801)
2093     rd_bitmap = ((t_u16)mp_regs[RD_BITMAP_U]) << 8;
2094     rd_bitmap |= (t_u16)mp_regs[RD_BITMAP_L];
2095 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2096     rd_bitmap = (t_u32)mp_regs[RD_BITMAP_L];
2097     rd_bitmap |= ((t_u32)mp_regs[RD_BITMAP_U]) << 8;
2098     rd_bitmap |= ((t_u32)mp_regs[RD_BITMAP_1L]) << 16;
2099     rd_bitmap |= ((t_u32)mp_regs[RD_BITMAP_1U]) << 24;
2100 #endif
2101 
2102     (void)PRINTF("INT : rd_bitmap=0x%x\n\r", rd_bitmap);
2103 
2104     (void)PRINTF("INT : wr_bitmap=0x%x\n\r", wr_bitmap);
2105 
2106     (void)PRINTF("INT : sdio_ireg = (0x%x)\r\n", sdio_ireg);
2107 #endif /* CONFIG_WIFI_IO_DEBUG */
2108 }
2109 
2110 #if CONFIG_TP_OPTIMIZATIONS
bitcount(t_u32 num)2111 static t_u32 bitcount(t_u32 num)
2112 {
2113     t_u32 count = 0;
2114     static t_u32 nibblebits[] = { 0, 1, 1, 2, 1, 2, 2, 3,
2115                     1, 2, 2, 3, 2, 3, 3, 4 };
2116     for (; num != 0; num >>= 4)
2117         count += nibblebits[num & 0x0f];
2118     return count;
2119 }
2120 #endif
2121 #if CONFIG_SDIO_MULTI_PORT_RX_AGGR
2122 #if CONFIG_TP_OPTIMIZATIONS
2123 static t_u8 start_check = 0;
2124 static t_u8 skip_int = 0;
2125 #endif
2126 
2127 /* returns port number from rd_bitmap. if ctrl port, then it clears
2128  * the bit and does nothing else
2129  * if data port then increments curr_port value also */
wlan_get_rd_port(mlan_adapter * pmadapter,t_u32 * pport,t_u32 * rxlen,t_u32 * rxblocks,bool * aggr)2130 static mlan_status wlan_get_rd_port(mlan_adapter *pmadapter, t_u32 *pport, t_u32 *rxlen, t_u32 *rxblocks, bool *aggr)
2131 {
2132 #if defined(SD8801)
2133     t_u16 rd_bitmap = pmadapter->mp_rd_bitmap;
2134 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2135     t_u32 rd_bitmap = pmadapter->mp_rd_bitmap;
2136 #endif
2137     t_u16 pkt_cnt = 0;
2138     t_u32 len_reg_l, len_reg_u;
2139     t_u32 rx_len;
2140     t_u32 rx_blocks;
2141     t_u16 ports      = 0;
2142     t_u32 start_port = -1;
2143     t_u32 cmd53_port = 0;
2144 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2145     t_u32 port_count = 0;
2146 #endif
2147 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2148     uint32_t *rxdataAddr = NULL;
2149 #endif
2150 
2151     *pport    = -1;
2152     *rxlen    = 0;
2153     *rxblocks = 0;
2154 
2155     wifi_io_d(
2156         "wlan_get_rd_port: mp_rd_bitmap=0x%x"
2157         " curr_rd_bitmap=0x%x\r\n",
2158         pmadapter->mp_rd_bitmap, pmadapter->curr_rd_port);
2159 
2160 #if defined(SD8801)
2161     if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
2162 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2163     if (!(rd_bitmap & DATA_PORT_MASK))
2164 #endif
2165     {
2166         return MLAN_STATUS_FAILURE;
2167     }
2168 
2169 #if defined(SD8801)
2170     if (pmadapter->mp_rd_bitmap & CTRL_PORT_MASK)
2171     {
2172         pmadapter->mp_rd_bitmap &= (t_u32)(~CTRL_PORT_MASK);
2173         *pport = CTRL_PORT;
2174 
2175         len_reg_l = RD_LEN_P0_L + (*pport << 1);
2176         len_reg_u = RD_LEN_P0_U + (*pport << 1);
2177         rx_len    = ((t_u16)pmadapter->mp_regs[len_reg_u]) << 8;
2178         rx_len |= (t_u16)pmadapter->mp_regs[len_reg_l];
2179         rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1) / MLAN_SDIO_BLOCK_SIZE;
2180         rx_len    = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2181         *rxlen    = rx_len;
2182         *rxblocks = rx_blocks;
2183 
2184         *pport = mlan_adap->ioport + *pport;
2185 
2186         wifi_io_d("RX: port=%d rxlen=%u rx_blocks=%u\r\n", *pport, *rxlen, *rxblocks);
2187 
2188         wifi_io_d("wlan_get_rd_port: port=%d mp_rd_bitmap=0x%04x", *pport, pmadapter->mp_rd_bitmap);
2189     }
2190     else
2191     {
2192 #endif
2193 
2194 #if CONFIG_TP_OPTIMIZATIONS
2195         /* This change is being added to handle low throughput caused for Tx due to excess interrupts received for Rx.
2196         * The intention is to ignore the interrupt if received agreggated packets are less than 4.
2197         * However, there could be single data packets during DHCP request, etc. whose Rx interrupt should not be skipped.
2198         * For actual data, we are checking if read bitmap has at least 4 ports available if current read port is 27.
2199         * If current read port is greater than 27 then any number of available ports is fine. */
2200         if (bitcount(pmadapter->mp_rd_bitmap) == 8U)
2201         {
2202             start_check = 1;
2203         }
2204 
2205         if (skip_int == 2)
2206         {
2207             start_check = 0;
2208         }
2209         /* Data */
2210         if ((start_check) && ((pmadapter->mp_rd_bitmap & ((pmadapter->curr_rd_port > 27 ? 1U : 0xFU) << pmadapter->curr_rd_port)) == 0U))
2211         {
2212             skip_int++;
2213             return MLAN_STATUS_FAILURE;
2214         }
2215 #endif
2216         while ((pmadapter->mp_rd_bitmap & (1U << pmadapter->curr_rd_port)) != 0U)
2217         {
2218             *pport = pmadapter->curr_rd_port;
2219 
2220             len_reg_l = RD_LEN_P0_L + (*pport << 1U);
2221             len_reg_u = RD_LEN_P0_U + (*pport << 1U);
2222             rx_len    = ((t_u16)pmadapter->mp_regs[len_reg_u]) << 8;
2223             rx_len |= (t_u16)pmadapter->mp_regs[len_reg_l];
2224             rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2225             rx_len    = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2226 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2227             if (wm_wifi.wifi_get_rxbuf_desc != NULL)
2228             {
2229                 rxdataAddr = (uint32_t *)wm_wifi.wifi_get_rxbuf_desc(rx_len);
2230 
2231                 if (rxdataAddr == NULL)
2232                 {
2233                     PRINTF("No pbuf\r\n");
2234                     break;
2235                 }
2236             }
2237 #else
2238             if ((*rxlen + rx_len) > INBUF_SIZE)
2239             {
2240                 break;
2241             }
2242 #endif
2243 
2244             pmadapter->mp_rd_bitmap &=
2245 #if defined(SD8801)
2246                 (t_u16)(~(1 << pmadapter->curr_rd_port));
2247 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2248             (t_u32)(~(1 << pmadapter->curr_rd_port));
2249 #endif
2250 
2251 #if defined(SD8801)
2252             if (!pkt_cnt)
2253                 start_port = *pport;
2254 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2255         if (start_port == -1)
2256         {
2257             start_port = *pport;
2258         }
2259 #endif
2260 
2261 #if defined(SD8801)
2262             if (start_port <= *pport)
2263             {
2264                 ports |= (1 << (pkt_cnt));
2265             }
2266             else
2267             {
2268                 ports |= (1 << (pkt_cnt + 1));
2269             }
2270 #endif
2271 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2272             if (rxdataAddr)
2273             {
2274                 sg_set_buf(rxdataAddr, rx_len);
2275                 num_sg++;
2276             }
2277 #endif
2278 
2279             *rxlen += rx_len;
2280             *rxblocks += rx_blocks;
2281 
2282             //PRINTF("RX: port=%d rxlen=%u rx_blocks=%u\r\n", *pport, *rxlen, *rxblocks);
2283 
2284             if (++pmadapter->curr_rd_port == MAX_PORT)
2285             {
2286 #if defined(SD8801)
2287                 pmadapter->curr_rd_port = 1;
2288 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2289             pmadapter->curr_rd_port = 0;
2290 #endif
2291             }
2292 
2293             pkt_cnt++;
2294 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2295             ports++;
2296 #endif
2297 
2298             if (pkt_cnt == SDIO_MP_AGGR_DEF_PKT_LIMIT_MAX)
2299             {
2300                 break;
2301             }
2302 #if defined(SD8801)
2303             if ((pmadapter->curr_rd_port < start_port) &&
2304                 (((MAX_PORT - start_port) + pmadapter->curr_rd_port) >= SDIO_MP_AGGR_DEF_PKT_LIMIT))
2305             {
2306                 break;
2307             }
2308 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2309         if (((pmadapter->curr_rd_port < start_port) &&
2310              (((MAX_PORT - start_port) + pmadapter->curr_rd_port) >= (pmadapter->mp_end_port >> 1))) ||
2311             ((pmadapter->curr_rd_port - start_port) >= (pmadapter->mp_end_port >> 1)))
2312         {
2313             break;
2314         }
2315 #endif
2316         }
2317 
2318         if (*pport == -1 || ports == 0)
2319         {
2320             wifi_io_e("wlan_get_rd_port : Returning FAILURE");
2321             return MLAN_STATUS_FAILURE;
2322         }
2323 
2324 #if defined(SD8801)
2325         if (pkt_cnt > 1)
2326 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2327         if (ports > 1U)
2328 #endif
2329         {
2330 #if defined(SD8801)
2331             cmd53_port = (pmadapter->ioport | SDIO_MPA_ADDR_BASE | (ports << 4)) + start_port;
2332 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2333         port_count = ports - 1U;
2334         cmd53_port = (pmadapter->ioport | SDIO_MPA_ADDR_BASE | (port_count << 8)) + start_port;
2335 #endif
2336             *pport = cmd53_port;
2337 
2338             *aggr = true;
2339 
2340             //(void)PRINTF("cmd53_port=%x, ports=%x, start_port=%x rxlen=%d rxblocks=%d\r\n", cmd53_port, ports,
2341             //start_port, *rxlen, *rxblocks);
2342         }
2343         else
2344         {
2345             *pport = mlan_adap->ioport + *pport;
2346         }
2347 
2348         wifi_io_d("port=%x mp_rd_bitmap=0x%x -> 0x%x\n", *pport, rd_bitmap, pmadapter->mp_rd_bitmap);
2349 #if defined(SD8801)
2350     }
2351 #endif
2352 
2353     return MLAN_STATUS_SUCCESS;
2354 }
2355 
2356 /*
2357  * Assumes that pmadapter->mp_rd_bitmap contains latest values
2358  */
_handle_sdio_packet_read(mlan_adapter * pmadapter,t_u8 ** packet,t_u32 * datalen,t_u32 * pkt_type)2359 static mlan_status _handle_sdio_packet_read(mlan_adapter *pmadapter, t_u8 **packet, t_u32 *datalen, t_u32 *pkt_type)
2360 {
2361     t_u32 port;
2362     t_u32 rx_len = 0, rx_blocks = 0;
2363     bool aggr = false;
2364 
2365     mlan_status ret = wlan_get_rd_port(pmadapter, &port, &rx_len, &rx_blocks, &aggr);
2366 
2367     /* nothing to read */
2368     if (ret != MLAN_STATUS_SUCCESS)
2369     {
2370         return ret;
2371     }
2372 
2373     *datalen = rx_len;
2374 
2375     *packet = wlan_read_rcv_packet(port, rx_len, rx_blocks, pkt_type, aggr);
2376 
2377     if ((*packet) == MNULL)
2378     {
2379         return MLAN_STATUS_FAILURE;
2380     }
2381 
2382     return MLAN_STATUS_SUCCESS;
2383 }
2384 #else
2385 /* returns port number from rd_bitmap. if ctrl port, then it clears
2386  * the bit and does nothing else
2387  * if data port then increments curr_port value also */
wlan_get_rd_port(mlan_adapter * pmadapter,t_u32 * pport)2388 static mlan_status wlan_get_rd_port(mlan_adapter *pmadapter, t_u32 *pport)
2389 {
2390 #if defined(SD8801)
2391     t_u16 rd_bitmap = pmadapter->mp_rd_bitmap;
2392 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2393     t_u32 rd_bitmap = pmadapter->mp_rd_bitmap;
2394 #endif
2395 
2396     wifi_io_d(
2397         "wlan_get_rd_port: mp_rd_bitmap=0x%x"
2398         " curr_rd_bitmap=0x%x",
2399         pmadapter->mp_rd_bitmap, pmadapter->curr_rd_port);
2400 
2401 #if defined(SD8801)
2402     if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
2403 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2404     if (!(rd_bitmap & DATA_PORT_MASK))
2405 #endif
2406         return MLAN_STATUS_FAILURE;
2407 
2408 #if defined(SD8801)
2409     if (pmadapter->mp_rd_bitmap & CTRL_PORT_MASK)
2410     {
2411         pmadapter->mp_rd_bitmap &= (t_u16)(~CTRL_PORT_MASK);
2412         *pport = CTRL_PORT;
2413 
2414         wifi_io_d("wlan_get_rd_port: port=%d mp_rd_bitmap=0x%04x", *pport, pmadapter->mp_rd_bitmap);
2415     }
2416     else
2417     {
2418 #endif
2419         /* Data */
2420         if ((pmadapter->mp_rd_bitmap & (1 << pmadapter->curr_rd_port)) != 0U)
2421         {
2422             pmadapter->mp_rd_bitmap &=
2423 #if defined(SD8801)
2424                 (t_u16)(~(1 << pmadapter->curr_rd_port));
2425 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2426             (t_u32)(~(1 << pmadapter->curr_rd_port));
2427 #endif
2428             *pport = pmadapter->curr_rd_port;
2429 
2430             if (++pmadapter->curr_rd_port == MAX_PORT)
2431 #if defined(SD8801)
2432                 pmadapter->curr_rd_port = 1;
2433 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2434             pmadapter->curr_rd_port = 0;
2435 #endif
2436         }
2437         else
2438         {
2439             wifi_io_e("wlan_get_rd_port : Returning FAILURE");
2440             return MLAN_STATUS_FAILURE;
2441         }
2442 
2443         wifi_io_d("port=%d mp_rd_bitmap=0x%x -> 0x%x\n", *pport, rd_bitmap, pmadapter->mp_rd_bitmap);
2444 #if defined(SD8801)
2445     }
2446 #endif
2447 
2448     return MLAN_STATUS_SUCCESS;
2449 }
2450 
2451 /*
2452  * Assumes that pmadapter->mp_rd_bitmap contains latest values
2453  */
_handle_sdio_packet_read(mlan_adapter * pmadapter,t_u8 ** packet,t_u32 * datalen,t_u32 * pkt_type)2454 static mlan_status _handle_sdio_packet_read(mlan_adapter *pmadapter, t_u8 **packet, t_u32 *datalen, t_u32 *pkt_type)
2455 {
2456     t_u32 port;
2457     t_u32 rx_len, rx_blocks;
2458 
2459     mlan_status ret = wlan_get_rd_port(pmadapter, &port);
2460 
2461     /* nothing to read */
2462     if (ret != MLAN_STATUS_SUCCESS)
2463         return ret;
2464 
2465     t_u32 len_reg_l = RD_LEN_P0_L + (port << 1);
2466     t_u32 len_reg_u = RD_LEN_P0_U + (port << 1);
2467 
2468     rx_len = ((t_u16)pmadapter->mp_regs[len_reg_u]) << 8;
2469     *datalen = rx_len |= (t_u16)pmadapter->mp_regs[len_reg_l];
2470 
2471     rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1) / MLAN_SDIO_BLOCK_SIZE;
2472     rx_len = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2473 
2474     port = mlan_adap->ioport + port;
2475 
2476     *packet = wlan_read_rcv_packet(port, rx_len, rx_blocks, pkt_type, false);
2477 
2478     if (!*packet)
2479         return MLAN_STATUS_FAILURE;
2480 
2481     return MLAN_STATUS_SUCCESS;
2482 }
2483 #endif
2484 
2485 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
_handle_sdio_cmd_read(mlan_adapter * pmadapter,t_u8 ** packet,t_u32 * datalen,t_u32 * pkt_type,t_u32 rx_len,t_u32 rx_blocks)2486 static mlan_status _handle_sdio_cmd_read(
2487     mlan_adapter *pmadapter, t_u8 **packet, t_u32 *datalen, t_u32 *pkt_type, t_u32 rx_len, t_u32 rx_blocks)
2488 {
2489     *datalen = rx_len;
2490 
2491     *packet = wlan_read_rcv_packet(mlan_adap->ioport | CMD_PORT_SLCT, rx_len, rx_blocks, pkt_type, false);
2492 
2493     if ((*packet) == MNULL)
2494     {
2495         return MLAN_STATUS_FAILURE;
2496     }
2497 
2498     return MLAN_STATUS_SUCCESS;
2499 }
2500 /*
2501  * This function keeps on looping till all the packets are read
2502  */
handle_sdio_cmd_read(mlan_adapter * pmadapter,t_u32 rx_len,t_u32 rx_blocks)2503 static void handle_sdio_cmd_read(mlan_adapter *pmadapter, t_u32 rx_len, t_u32 rx_blocks)
2504 {
2505     t_u32 datalen = 0;
2506 
2507     t_u32 pkt_type = 0;
2508     t_u8 *packet   = NULL;
2509 
2510     (void)_handle_sdio_cmd_read(pmadapter, &packet, &datalen, &pkt_type, rx_len, rx_blocks);
2511     if (pkt_type == MLAN_TYPE_CMD || pkt_type == MLAN_TYPE_EVENT)
2512     {
2513         /* non-data packets such as events
2514            and command responses are
2515            handled here */
2516         (void)wlan_decode_rx_packet(packet, pkt_type);
2517     }
2518 }
2519 #endif
2520 
2521 /*
2522  * This function keeps on looping till all the packets are read
2523  */
handle_sdio_packet_read(mlan_adapter * pmadapter)2524 static void handle_sdio_packet_read(mlan_adapter *pmadapter)
2525 {
2526     mlan_status ret = MLAN_STATUS_SUCCESS;
2527     t_u32 datalen   = 0;
2528 
2529     pmadapter->mp_rd_bitmap =
2530 #if defined(SD8801)
2531         ((t_u16)pmadapter->mp_regs[RD_BITMAP_U]) << 8;
2532     pmadapter->mp_rd_bitmap |= (t_u16)pmadapter->mp_regs[RD_BITMAP_L];
2533 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2534         (t_u32)pmadapter->mp_regs[RD_BITMAP_L];
2535     pmadapter->mp_rd_bitmap |= ((t_u32)pmadapter->mp_regs[RD_BITMAP_U]) << 8;
2536     pmadapter->mp_rd_bitmap |= ((t_u32)pmadapter->mp_regs[RD_BITMAP_1L]) << 16;
2537     pmadapter->mp_rd_bitmap |= ((t_u32)pmadapter->mp_regs[RD_BITMAP_1U]) << 24;
2538 #endif
2539 
2540     while (true)
2541     {
2542         t_u32 pkt_type = 0;
2543 #if !FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2544         t_u8 interface;
2545         t_u32 rx_blocks;
2546         t_u32 total_size = 0;
2547         t_u32 size       = 0;
2548 #endif
2549         t_u8 *packet     = NULL;
2550 
2551 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2552         num_sg = 0;
2553         sg_init_table();
2554 #endif
2555 
2556         ret = _handle_sdio_packet_read(pmadapter, &packet, &datalen, &pkt_type);
2557         if (ret != MLAN_STATUS_SUCCESS)
2558         {
2559             /* nothing to read. break out of while loop */
2560             break;
2561         }
2562 
2563         if (pkt_type == MLAN_TYPE_DATA)
2564         {
2565 
2566 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2567             if (num_sg > 0)
2568             {
2569 //                extern void net_rx_notify();
2570 
2571 //                net_rx_notify();
2572                 wm_wifi.data_input_callback(0, NULL, 0);
2573 #if 0
2574                 for (sg_idx = 0; sg_idx < num_sg; sg_idx++)
2575                 {
2576                     SDIOPkt *insdiopkt = (SDIOPkt *)(void *)rx_bufs[sg_idx];
2577                     size               = insdiopkt->size;
2578                     pkt_type           = insdiopkt->pkttype;
2579 
2580                     interface = *((t_u8 *)packet + INTF_HEADER_LEN);
2581 
2582                     //PRINTF("IN: i/f: %d len: %d\r\n", interface, size);
2583 
2584                     if (bus.wifi_low_level_input != NULL)
2585                     {
2586                         (void)bus.wifi_low_level_input(interface, rx_bufs[sg_idx], size);
2587                     }
2588                 }
2589 #endif
2590             }
2591 #else
2592             {
2593                 while (total_size < datalen)
2594                 {
2595                     SDIOPkt *insdiopkt = (SDIOPkt *)(void *)packet;
2596                     size               = insdiopkt->size;
2597                     pkt_type           = insdiopkt->pkttype;
2598 
2599                     rx_blocks = (size + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2600                     size      = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2601 
2602                     interface = *((t_u8 *)packet + INTF_HEADER_LEN);
2603 
2604                     //PRINTF("IN: i/f: %d len: %d\r\n", interface, size);
2605 
2606                     if (!size)
2607                     {
2608                         break;
2609                     }
2610 
2611                     if (bus.wifi_low_level_input != NULL)
2612                     {
2613                         (void)bus.wifi_low_level_input(interface, packet, size);
2614                     }
2615 
2616                     packet += size;
2617                     total_size += size;
2618                 }
2619             }
2620 #endif
2621         }
2622         else
2623         {
2624             /* non-data packets such as events
2625                and command responses are
2626                handled here */
2627             (void)wlan_decode_rx_packet(packet, pkt_type);
2628         }
2629     }
2630 }
2631 
2632 /*
2633  * This is supposed to be called in thread context.
2634  */
wlan_process_int_status(mlan_adapter * pmadapter)2635 mlan_status wlan_process_int_status(mlan_adapter *pmadapter)
2636 {
2637     mlan_status ret = MLAN_STATUS_SUCCESS;
2638 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2639     t_u8 cmd_rd_len_0 = CMD_RD_LEN_0;
2640     t_u8 cmd_rd_len_1 = CMD_RD_LEN_1;
2641     t_u32 rx_len;
2642     t_u32 rx_blocks;
2643 #endif
2644 
2645     /* Get the interrupt status */
2646     wlan_interrupt(pmadapter);
2647 
2648     t_u8 sdio_ireg       = pmadapter->sdio_ireg;
2649     pmadapter->sdio_ireg = 0;
2650 
2651     if (!sdio_ireg)
2652     {
2653         goto done;
2654     }
2655 
2656 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2657     /* check the command port */
2658     if ((sdio_ireg & DN_LD_CMD_PORT_HOST_INT_STATUS) != 0U)
2659     {
2660         if (pmadapter->cmd_sent != 0U)
2661         {
2662             pmadapter->cmd_sent = MFALSE;
2663         }
2664         PRINTM(MINFO, "cmd_sent=%d\n", pmadapter->cmd_sent);
2665     }
2666 
2667     if ((sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS) != 0U)
2668     {
2669         /* read the len of control packet */
2670         rx_len = ((t_u32)pmadapter->mp_regs[cmd_rd_len_1]) << 8;
2671         rx_len |= (t_u32)pmadapter->mp_regs[cmd_rd_len_0];
2672         PRINTM(MINFO, "RX: cmd port rx_len=%u\n", rx_len);
2673 
2674         rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2675 
2676         // (void)PRINTF("CMD: cmd port rx_len=%u rx_blocks=%u\r\n", rx_len, rx_blocks);
2677         rx_len = (t_u32)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2678 
2679         handle_sdio_cmd_read(pmadapter, rx_len, rx_blocks);
2680     }
2681 #elif defined(SD8801)
2682     /*
2683      * Below two statement look like they are present for the purpose
2684      * of unconditional initializing of mp_wr_bitmap which will be used
2685      * during packet xmit. proper mlan code does not do this most
2686      * probably because they have used wlan_get_wr_port_data() to
2687      * decide on the write port which we have not done. Check this out
2688      * later.
2689      */
2690     pmadapter->mp_wr_bitmap = ((t_u16)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2691     pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L];
2692 #endif
2693 
2694     pmadapter->mp_wr_bitmap =
2695 #if defined(SD8801)
2696         ((t_u16)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2697     pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L];
2698 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2699         (t_u32)pmadapter->mp_regs[WR_BITMAP_L];
2700     pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2701     pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1L]) << 16;
2702     pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1U]) << 24;
2703 #endif
2704 
2705     /*
2706      * DN_LD_HOST_INT_STATUS interrupt happens when the txmit sdio
2707      * ports are freed This is usually when we write to port most
2708      * significant port.
2709      */
2710     if ((sdio_ireg & DN_LD_HOST_INT_STATUS) != 0U)
2711     {
2712         pmadapter->mp_wr_bitmap =
2713 #if defined(SD8801)
2714             ((t_u16)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2715         pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L];
2716 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2717             (t_u32)pmadapter->mp_regs[WR_BITMAP_L];
2718         pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2719         pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1L]) << 16;
2720         pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1U]) << 24;
2721 #endif
2722     }
2723 
2724     /*
2725      * As firmware will not generate download ready interrupt if the
2726      * port updated is command port only, cmd_sent should be done for
2727      * any SDIO interrupt.
2728      */
2729 #if defined(SD8801)
2730     if (pmadapter->cmd_sent == true)
2731     {
2732         /*
2733          * Check if firmware has attach buffer at command port and
2734          * update just that in wr_bit_map.
2735          */
2736         pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
2737 
2738         if (pmadapter->mp_wr_bitmap & CTRL_PORT_MASK)
2739             pmadapter->cmd_sent = false;
2740     }
2741 #endif
2742 
2743     if ((sdio_ireg & UP_LD_HOST_INT_STATUS) != 0U)
2744     {
2745         /* This means there is data to be read */
2746         handle_sdio_packet_read(pmadapter);
2747     }
2748 
2749     ret = MLAN_STATUS_SUCCESS;
2750 
2751 done:
2752     return ret;
2753 }
2754 
2755 /**
2756  * Interrupt callback handler registered with the SDIO driver.
2757  */
handle_cdint(int error)2758 void handle_cdint(int error)
2759 {
2760     /* Wake up LWIP thread. */
2761     if (!error && g_txrx_flag)
2762     {
2763         g_txrx_flag = false;
2764 #if CONFIG_ZEPHYR
2765         (void)OSA_EventNotifyPost(wm_wifi.wifi_core_task_Handle);
2766 #else
2767         (void)OSA_EventSet((osa_event_handle_t)wm_wifi.wifi_event_Handle, WIFI_EVENT_SDIO);
2768 #endif
2769     }
2770 }
2771 
wifi_raw_packet_recv(t_u8 ** data,t_u32 * pkt_type)2772 int wifi_raw_packet_recv(t_u8 **data, t_u32 *pkt_type)
2773 {
2774     OSA_SR_ALLOC()
2775     osa_event_flags_t flagsToWait = WIFI_EVENT_SDIO;
2776     osa_event_flags_t pSetFlags;
2777 
2778     if (data == MNULL)
2779     {
2780         return -WM_FAIL;
2781     }
2782 
2783     OSA_ENTER_CRITICAL();
2784     /* Allow interrupt handler to deliver us a packet */
2785     g_txrx_flag = true;
2786 
2787     sdio_enable_interrupt();
2788 
2789     OSA_EXIT_CRITICAL()
2790 
2791     (void)OSA_EventWait((osa_event_handle_t)wm_wifi.wifi_event_Handle, flagsToWait, false, osaWaitForever_c, &pSetFlags);
2792 
2793     OSA_EventClear((osa_event_handle_t)wm_wifi.wifi_event_Handle, WIFI_EVENT_SDIO);
2794 
2795     if ((pSetFlags & WIFI_EVENT_SDIO) == 0U)
2796     {
2797         return -WM_FAIL;
2798     }
2799 
2800     /* Get the interrupt status */
2801     wlan_interrupt(mlan_adap);
2802 
2803     t_u8 sdio_ireg       = mlan_adap->sdio_ireg;
2804     mlan_adap->sdio_ireg = 0;
2805 
2806 #if defined(SD8801)
2807     if (!(sdio_ireg & UP_LD_HOST_INT_STATUS))
2808 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2809     if (!(sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS))
2810 #endif
2811     {
2812         return -WM_FAIL;
2813     }
2814 
2815     t_u32 datalen = 0;
2816 
2817     mlan_adap->mp_rd_bitmap =
2818 #if defined(SD8801)
2819         ((t_u16)mlan_adap->mp_regs[RD_BITMAP_U]) << 8;
2820     mlan_adap->mp_rd_bitmap |= (t_u16)mlan_adap->mp_regs[RD_BITMAP_L];
2821 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2822         (t_u32)mlan_adap->mp_regs[RD_BITMAP_L];
2823     mlan_adap->mp_rd_bitmap |= ((t_u32)mlan_adap->mp_regs[RD_BITMAP_U]) << 8;
2824     mlan_adap->mp_rd_bitmap |= ((t_u32)mlan_adap->mp_regs[RD_BITMAP_1L]) << 16;
2825     mlan_adap->mp_rd_bitmap |= ((t_u32)mlan_adap->mp_regs[RD_BITMAP_1U]) << 24;
2826 #endif
2827 
2828     t_u8 *packet = NULL;
2829 
2830 #if defined(SD8801)
2831     int ret;
2832     while (1)
2833     {
2834         ret = _handle_sdio_packet_read(mlan_adap, &packet, &datalen, pkt_type);
2835         if (ret == MLAN_STATUS_SUCCESS)
2836         {
2837             break;
2838         }
2839     }
2840 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2841 
2842     t_u8 cmd_rd_len_0 = CMD_RD_LEN_0;
2843     t_u8 cmd_rd_len_1 = CMD_RD_LEN_1;
2844     t_u32 rx_len;
2845     t_u32 rx_blocks;
2846 
2847     /* read the len of control packet */
2848     rx_len = ((t_u32)mlan_adap->mp_regs[cmd_rd_len_1]) << 8;
2849     rx_len |= (t_u32)mlan_adap->mp_regs[cmd_rd_len_0];
2850     PRINTM(MINFO, "RX: cmd port rx_len=%u\n", rx_len);
2851 
2852     rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2853 
2854     rx_len = (t_u32)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2855 
2856     (void)_handle_sdio_cmd_read(mlan_adap, &packet, &datalen, pkt_type, rx_len, rx_blocks);
2857 #endif
2858     *data = packet;
2859     return WM_SUCCESS;
2860 }
2861 
wifi_raw_packet_send(const t_u8 * packet,t_u32 length)2862 int wifi_raw_packet_send(const t_u8 *packet, t_u32 length)
2863 {
2864     if ((packet == MNULL) || !length)
2865     {
2866         return -WM_E_INVAL;
2867     }
2868 
2869     if (length > SDIO_OUTBUF_LEN)
2870     {
2871         wifi_io_e("Insufficient buffer");
2872         return -WM_FAIL;
2873     }
2874 
2875     t_u32 tx_blocks = 0, buflen = 0;
2876     calculate_sdio_write_params(length, &tx_blocks, &buflen);
2877 
2878     (void)memcpy((void *)outbuf, (const void *)packet, length);
2879 #if CONFIG_WIFI_IO_DUMP
2880     dump_hex(outbuf, length);
2881 #endif
2882     uint32_t resp;
2883 #if defined(SD8801)
2884     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
2885 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2886     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
2887 #endif
2888     return WM_SUCCESS;
2889 }
2890 
sd_wifi_preinit(void)2891 static mlan_status sd_wifi_preinit(void)
2892 {
2893     mlan_status mlanstatus = MLAN_STATUS_SUCCESS;
2894 
2895     /* initializes the driver struct */
2896     int sdiostatus = wlan_init_struct();
2897     if (sdiostatus != WM_SUCCESS)
2898     {
2899         wifi_io_e("Init failed. Cannot create init struct");
2900         return MLAN_STATUS_FAILURE;
2901     }
2902 
2903     /*
2904      * Register a callback with power manager of MC200/MW300
2905      * This callback will be called on entry /exit
2906      * of low power mode of MC200/MW300 based on first paramter
2907      * passed to the call.
2908      */
2909     //	pm_handle = pm_register_cb(ACTION_EXIT_PM3 | ACTION_ENTER_PM4,
2910     //		       sd_wifi_ps_cb, NULL);
2911 
2912     (void)mlan_subsys_init();
2913     seqnum   = 0;
2914     txportno = 0;
2915     return mlanstatus;
2916 }
2917 
sd_wifi_reset_ports()2918 void sd_wifi_reset_ports()
2919 {
2920 #if defined(SD8801)
2921     txportno = 1;
2922     mlan_adap->curr_rd_port = 1;
2923 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2924     txportno = 0;
2925     mlan_adap->curr_rd_port = 0;
2926 #endif
2927 }
2928 
sd_wifi_post_init(enum wlan_type type)2929 mlan_status sd_wifi_post_init(enum wlan_type type)
2930 {
2931     mlan_status mlanstatus = MLAN_STATUS_SUCCESS;
2932     uint32_t resp;
2933     bool invalid_wlantype = MFALSE;
2934 #if defined(SD8801)
2935     sdio_drv_creg_write(HOST_INT_MASK_REG, 1, 0x3, &resp);
2936 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2937     (void)sdio_drv_creg_write(HOST_INT_MASK_REG, 1, HIM_ENABLE, &resp);
2938 #endif
2939 
2940     /* If we're running a Manufacturing image, start the tasks.
2941        If not, initialize and setup the firmware */
2942     switch (type)
2943     {
2944         case WLAN_TYPE_NORMAL:
2945             fw_init_cfg = 1;
2946             wlan_fw_init_cfg();
2947             fw_init_cfg = 0;
2948             break;
2949         case WLAN_TYPE_WIFI_CALIB:
2950             g_txrx_flag = true;
2951             break;
2952         case WLAN_TYPE_FCC_CERTIFICATION:
2953             g_txrx_flag = true;
2954             break;
2955         default:
2956             wifi_io_e("Enter a valid input to sd_wifi_init");
2957             invalid_wlantype = MTRUE;
2958             break;
2959     }
2960 
2961     if (invalid_wlantype == MTRUE)
2962     {
2963         return MLAN_STATUS_FAILURE;
2964     }
2965 
2966     sd_wifi_reset_ports();
2967 
2968     return mlanstatus;
2969 }
2970 
2971 static void *intf;
2972 
sd_wifi_init(enum wlan_type type,const uint8_t * fw_start_addr,const size_t size)2973 mlan_status sd_wifi_init(enum wlan_type type, const uint8_t *fw_start_addr, const size_t size)
2974 {
2975     mlan_status ret = MLAN_STATUS_SUCCESS;
2976 
2977     ret = sd_wifi_preinit();
2978 
2979     if (ret == MLAN_STATUS_SUCCESS)
2980     {
2981         intf = (void *)sdio_init_interface(NULL);
2982 
2983         if (intf != MNULL)
2984         {
2985             mlan_adap->fw_start_addr = fw_start_addr;
2986 
2987             ret = (mlan_status)firmware_download(fw_start_addr, size, intf, 0);
2988         } else {
2989             ret = MLAN_STATUS_FAILURE;
2990 	}
2991     }
2992     return ret;
2993 }
2994 
2995 #if (CONFIG_WIFI_IND_DNLD)
sd_wifi_reinit(enum wlan_type type,const uint8_t * fw_start_addr,const size_t size,uint8_t fw_reload)2996 mlan_status sd_wifi_reinit(enum wlan_type type, const uint8_t *fw_start_addr, const size_t size, uint8_t fw_reload)
2997 {
2998     mlan_status ret = MLAN_STATUS_SUCCESS;
2999 
3000     if (fw_reload == FW_RELOAD_NO_EMULATION)
3001     {
3002         OSA_SR_ALLOC();
3003         OSA_ENTER_CRITICAL();
3004 
3005         /* Allow interrupt handler to deliver us a packet */
3006         g_txrx_flag = false;
3007 
3008         sdio_disable_interrupt();
3009 
3010         OSA_EXIT_CRITICAL();
3011 
3012         sdio_ioport_init();
3013     }
3014 
3015     ret = (mlan_status)firmware_download(fw_start_addr, size, intf, fw_reload);
3016 
3017     if (ret != MLAN_STATUS_FAILURE)
3018     {
3019         if (fw_reload == FW_RELOAD_NO_EMULATION)
3020         {
3021             OSA_SR_ALLOC();
3022             OSA_ENTER_CRITICAL();
3023             /* Allow interrupt handler to deliver us a packet */
3024             g_txrx_flag = true;
3025 
3026             sdio_enable_interrupt();
3027 
3028             OSA_EXIT_CRITICAL();
3029         }
3030     }
3031 
3032     return ret;
3033 }
3034 #endif
3035 
3036 #if CONFIG_BT_SUPPORT
read_sdio_function_recvd()3037 uint8_t read_sdio_function_recvd()
3038 {
3039     uint32_t resp = 0;
3040     uint8_t val;
3041     sdio_drv_creg_read(0x5, 0x0, &resp);
3042     val = resp & 0xf;
3043     return val;
3044 }
3045 #endif
3046 
sd_wifi_deinit(void)3047 void sd_wifi_deinit(void)
3048 {
3049 #ifdef WLAN_LOW_POWER_ENABLE
3050     low_power_mode = false;
3051 #endif
3052     cal_data_valid = false;
3053     mac_addr_valid = false;
3054     //	pm_deregister_cb(pm_handle);
3055 
3056     (void)wlan_cmd_shutdown();
3057     sdio_drv_deinit();
3058     (void)mlan_subsys_deinit();
3059     (void)wlan_deinit_struct();
3060 }
3061 
3062 #if CONFIG_FW_VDLL
wifi_get_vdllcommand_buffer(void)3063 HostCmd_DS_COMMAND *wifi_get_vdllcommand_buffer(void)
3064 {
3065     /* First 4 bytes reserved for SDIO pkt header */
3066     return (HostCmd_DS_COMMAND *)(void *)(vdll_cmd_buf + INTF_HEADER_LEN);
3067 }
3068 #endif
3069 
wifi_get_command_buffer(void)3070 HostCmd_DS_COMMAND *wifi_get_command_buffer(void)
3071 {
3072     /* First 4 bytes reserved for SDIO pkt header */
3073     return (HostCmd_DS_COMMAND *)(void *)(ctrl_cmd_buf + INTF_HEADER_LEN);
3074 }
3075 
3076 /**
3077  * Function to set mlan ioport.
3078  */
set_ioport_inmlan(t_u32 port)3079 void set_ioport_inmlan(t_u32 port)
3080 {
3081     mlan_adap->ioport = port;
3082 }
3083 
3084 #if CONFIG_HOST_SLEEP
wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)3085 void wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)
3086 {
3087     if (hs_wakeup_reason == 0)
3088     {
3089         PRINTF("Woken up by unknown reason\r\n");
3090     }
3091     else if (hs_wakeup_reason == 1)
3092     {
3093         PRINTF("Woken up by Broadcast data matched\r\n");
3094     }
3095     else if (hs_wakeup_reason == 2)
3096     {
3097         PRINTF("Woken up by Multicast data matched\r\n");
3098     }
3099     else if (hs_wakeup_reason == 3)
3100     {
3101         PRINTF("Woken up by Unicast data matched\r\n");
3102     }
3103     else if (hs_wakeup_reason == 4)
3104     {
3105         PRINTF("Woken up by Maskable event matched\r\n");
3106     }
3107     else if (hs_wakeup_reason == 5)
3108     {
3109         PRINTF("Woken up by Non-maskable event matched\r\n");
3110     }
3111     else if (hs_wakeup_reason == 6)
3112     {
3113         PRINTF("Woken up by Non-maskable condition matched (EAPoL rekey)\r\n");
3114     }
3115     else if (hs_wakeup_reason == 7)
3116     {
3117         PRINTF("Woken up by Magic pattern matched\r\n");
3118     }
3119     else if (hs_wakeup_reason == 8)
3120     {
3121         PRINTF("Woken up by control frames matched \r\n");
3122     }
3123     else if (hs_wakeup_reason == 9)
3124     {
3125         PRINTF("Woken up by management frame matched \r\n");
3126     }
3127     else if (hs_wakeup_reason == 10)
3128     {
3129         PRINTF("Woken up by GTK rekey failure\r\n");
3130     }
3131     else if (hs_wakeup_reason == 11)
3132     {
3133         PRINTF("Woken up by management frame filter extension matched\r\n");
3134     }
3135     else
3136     {
3137         PRINTF("Woken up by reserved reason\r\n");
3138     }
3139 }
3140 
wifi_clear_wakeup_reason(void)3141 void wifi_clear_wakeup_reason(void)
3142 {
3143     if (mlan_adap != NULL)
3144     {
3145         memset(&mlan_adap->wlan_wakeup, 0x0, sizeof(wlan_wakeup_reason));
3146     }
3147 }
3148 #endif
3149