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 
wlan_get_mac_addr_uap(void)985 static void wlan_get_mac_addr_uap(void)
986 {
987     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
988     uint32_t resp;
989     t_u16 seq_number = 0;
990 
991     wifi_sdio_lock();
992 
993     (void)memset(outbuf, 0, buflen);
994     seq_number = HostCmd_SET_SEQ_NO_BSS_INFO(0 /* seq_num */, 0 /* bss_num */, MLAN_BSS_TYPE_UAP);
995 
996     /* sdiopkt = outbuf */
997     wifi_prepare_get_mac_addr_cmd(&sdiopkt->hostcmd, seq_number);
998 
999     sdiopkt->pkttype = MLAN_TYPE_CMD;
1000     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1001 
1002     last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
1003 
1004     /* send CMD53 to write the command to get mac address */
1005 #if defined(SD8801)
1006     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1007 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1008     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1009 #endif
1010 
1011     wifi_sdio_unlock();
1012 
1013     wifi_sdio_wait_for_cmdresp();
1014 
1015 }
1016 
1017 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)1018 static void wlan_get_fw_ver_ext(int version_str_sel)
1019 {
1020     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1021     uint32_t resp;
1022 
1023     wifi_sdio_lock();
1024 
1025     (void)memset(outbuf, 0, buflen);
1026 
1027     /* sdiopkt = outbuf */
1028     wifi_prepare_get_fw_ver_ext_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num(), version_str_sel);
1029 
1030     sdiopkt->pkttype = MLAN_TYPE_CMD;
1031     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1032 
1033     last_cmd_sent = HostCmd_CMD_VERSION_EXT;
1034 
1035     /* send CMD53 to write the command to get mac address */
1036 #if defined(SD8801)
1037     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1038 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1039     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1040 #endif
1041 
1042     wifi_sdio_unlock();
1043 
1044     wifi_sdio_wait_for_cmdresp();
1045 
1046 }
1047 
1048 void wifi_prepare_get_value1(HostCmd_DS_COMMAND *cmd, int seq_number);
1049 
wlan_get_value_1(void)1050 static void wlan_get_value_1(void)
1051 {
1052     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1053     uint32_t resp;
1054 
1055     wifi_sdio_lock();
1056 
1057     (void)memset(outbuf, 0, buflen);
1058 
1059     /* sdiopkt = outbuf */
1060     wifi_prepare_get_value1(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1061 
1062     sdiopkt->pkttype = MLAN_TYPE_CMD;
1063     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1064 
1065     last_cmd_sent = HostCmd_CMD_MAC_REG_ACCESS;
1066 
1067 #if defined(SD8801)
1068     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1069 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1070     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1071 #endif
1072 
1073     wifi_sdio_unlock();
1074 
1075     wifi_sdio_wait_for_cmdresp();
1076 
1077 }
1078 
1079 void wifi_prepare_set_mac_addr_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
_wlan_set_mac_addr(void)1080 static void _wlan_set_mac_addr(void)
1081 {
1082     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1083     uint32_t resp;
1084 
1085     wifi_sdio_lock();
1086 
1087     (void)memset(outbuf, 0, buflen);
1088 
1089     /* sdiopkt = outbuf */
1090     wifi_prepare_set_mac_addr_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1091 
1092     sdiopkt->pkttype = MLAN_TYPE_CMD;
1093     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1094 
1095     last_cmd_sent = HostCmd_CMD_802_11_MAC_ADDRESS;
1096 
1097     /* send CMD53 to write the command to get mac address */
1098 #if defined(SD8801)
1099     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1100 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1101     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1102 #endif
1103 
1104     wifi_sdio_unlock();
1105 
1106     wifi_sdio_wait_for_cmdresp();
1107 }
1108 
1109 #if CONFIG_11N
wlan_set_11n_cfg(void)1110 static void wlan_set_11n_cfg(void)
1111 {
1112     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1113     uint32_t resp;
1114 
1115     wifi_sdio_lock();
1116 
1117     (void)memset(outbuf, 0, SDIO_OUTBUF_LEN);
1118 
1119     wrapper_wlan_cmd_11n_cfg(&sdiopkt->hostcmd);
1120     /* sdiopkt = outbuf */
1121     sdiopkt->hostcmd.seq_num = (t_u16)wlan_get_next_seq_num();
1122     sdiopkt->pkttype         = MLAN_TYPE_CMD;
1123     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1124 
1125     last_cmd_sent            = HostCmd_CMD_11N_CFG;
1126 
1127 #if defined(SD8801)
1128     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1129 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1130     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1131 #endif
1132 
1133     wifi_sdio_unlock();
1134 
1135     wifi_sdio_wait_for_cmdresp();
1136 }
1137 
1138 #if CONFIG_ENABLE_AMSDU_RX
1139 void wifi_prepare_enable_amsdu_cmd(HostCmd_DS_COMMAND *cmd, int seq_number);
wlan_enable_amsdu(void)1140 static void wlan_enable_amsdu(void)
1141 {
1142     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1143     uint32_t resp;
1144 
1145     wifi_sdio_lock();
1146 
1147     (void)memset(outbuf, 0, buflen);
1148 
1149     /* sdiopkt = outbuf */
1150     wifi_prepare_enable_amsdu_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1151 
1152     sdiopkt->pkttype = MLAN_TYPE_CMD;
1153     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1154 
1155     last_cmd_sent = HostCmd_CMD_AMSDU_AGGR_CTRL;
1156 
1157 #if defined(SD8801)
1158     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1159 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1160     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1161 #endif
1162 
1163     wifi_sdio_unlock();
1164 
1165     wifi_sdio_wait_for_cmdresp();
1166 
1167 }
1168 #endif /* CONFIG_ENABLE_AMSDU_RX */
1169 #endif /* CONFIG_11N */
1170 
wlan_cmd_shutdown(void)1171 static void wlan_cmd_shutdown(void)
1172 {
1173     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1174     uint32_t resp;
1175 
1176     (void)memset(outbuf, 0, buflen);
1177 
1178     /* sdiopkt = outbuf */
1179     sdiopkt->hostcmd.command = HostCmd_CMD_FUNC_SHUTDOWN;
1180     sdiopkt->hostcmd.size    = (t_u16)S_DS_GEN;
1181     sdiopkt->hostcmd.seq_num = (t_u16)wlan_get_next_seq_num();
1182     sdiopkt->hostcmd.result  = 0;
1183 
1184     sdiopkt->pkttype = MLAN_TYPE_CMD;
1185     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1186 
1187     last_cmd_sent = HostCmd_CMD_FUNC_SHUTDOWN;
1188 
1189     (void)sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1190 }
1191 
1192 void wlan_prepare_mac_control_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
wlan_set_mac_ctrl(void)1193 static void wlan_set_mac_ctrl(void)
1194 {
1195     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1196     uint32_t resp;
1197 
1198     wifi_sdio_lock();
1199 
1200     (void)memset(outbuf, 0, buflen);
1201 
1202     /* sdiopkt = outbuf */
1203     wlan_prepare_mac_control_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1204 
1205     sdiopkt->pkttype = MLAN_TYPE_CMD;
1206     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1207 
1208     last_cmd_sent = HostCmd_CMD_MAC_CONTROL;
1209 
1210     /* send CMD53 to write the command to set mac control */
1211 #if defined(SD8801)
1212     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1213 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1214     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1215 #endif
1216 
1217     wifi_sdio_unlock();
1218 
1219     wifi_sdio_wait_for_cmdresp();
1220 
1221 }
1222 
wlan_cmd_init(void)1223 static void wlan_cmd_init(void)
1224 {
1225     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1226     uint32_t resp;
1227 
1228     wifi_sdio_lock();
1229 
1230     (void)memset(outbuf, 0, buflen);
1231 
1232     /* sdiopkt = outbuf */
1233     sdiopkt->hostcmd.command = HostCmd_CMD_FUNC_INIT;
1234     sdiopkt->hostcmd.size    = (t_u16)S_DS_GEN;
1235     sdiopkt->hostcmd.seq_num = (t_u16)wlan_get_next_seq_num();
1236     sdiopkt->hostcmd.result  = 0;
1237 
1238     sdiopkt->pkttype = MLAN_TYPE_CMD;
1239     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1240 
1241     last_cmd_sent = HostCmd_CMD_FUNC_INIT;
1242 
1243 #if defined(SD8801)
1244     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1245 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1246     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1247 #endif
1248 
1249     wifi_sdio_unlock();
1250 
1251     wifi_sdio_wait_for_cmdresp();
1252 }
1253 
1254 #ifdef WLAN_LOW_POWER_ENABLE
1255 void wifi_prepare_low_power_mode_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
wlan_set_low_power_mode()1256 static int wlan_set_low_power_mode()
1257 {
1258     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1259     uint32_t resp;
1260 
1261     wifi_sdio_lock();
1262 
1263     (void)memset(outbuf, 0, buflen);
1264 
1265     /* sdiopkt = outbuf */
1266 
1267     wifi_prepare_low_power_mode_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1268 
1269     sdiopkt->pkttype = MLAN_TYPE_CMD;
1270     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1271 
1272     last_cmd_sent = HostCmd_CMD_LOW_POWER_MODE;
1273 
1274     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1275 
1276     wifi_sdio_unlock();
1277 
1278     wifi_sdio_wait_for_cmdresp();
1279 
1280     return true;
1281 }
1282 #endif
1283 
1284 #if CONFIG_EXTERNAL_BLE_COEX
1285 void wifi_prepare_set_coex_cmd(HostCmd_DS_COMMAND *cmd, t_u16 seq_number);
1286 
wlan_set_ext_ble_coex_mode()1287 static int wlan_set_ext_ble_coex_mode()
1288 {
1289     t_u32 tx_blocks = 1, buflen = MLAN_SDIO_BLOCK_SIZE;
1290     uint32_t resp;
1291 
1292     if (!board_coex_interface())
1293     {
1294         return false;
1295     }
1296 
1297     board_coex_pin_config(1);
1298 
1299     wifi_sdio_lock();
1300 
1301     (void)memset(outbuf, 0, buflen);
1302 
1303     /* sdiopkt = outbuf */
1304     wifi_prepare_set_coex_cmd(&sdiopkt->hostcmd, (t_u16)wlan_get_next_seq_num());
1305 
1306     sdiopkt->pkttype = MLAN_TYPE_CMD;
1307     sdiopkt->size    = sdiopkt->hostcmd.size + INTF_HEADER_LEN;
1308 
1309     last_cmd_sent = HostCmd_CMD_ROBUST_COEX;
1310 
1311     /* send CMD53 to write the command to set mac control */
1312     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1313 
1314     wifi_sdio_unlock();
1315 
1316     wifi_sdio_wait_for_cmdresp();
1317 
1318     return true;
1319 }
1320 #endif
1321 
1322 /* Setup the firmware with commands */
wlan_fw_init_cfg(void)1323 static void wlan_fw_init_cfg(void)
1324 {
1325 #if CONFIG_FW_VDLL
1326     mlan_private *pmpriv = (mlan_private *)mlan_adap->priv[0];
1327     mlan_adapter *pmadapter = pmpriv->adapter;
1328 #endif
1329 
1330     wifi_io_d("FWCMD : INIT (0xa9)");
1331 
1332     wlan_cmd_init();
1333 
1334 #ifdef WLAN_LOW_POWER_ENABLE
1335     if (low_power_mode)
1336     {
1337 #if CONFIG_FW_VDLL
1338         while (pmadapter->vdll_in_progress == MTRUE)
1339         {
1340             OSA_TimeDelay(50);
1341         }
1342 #endif
1343         wifi_io_d("CMD : LOW_POWER_MODE (0x128)");
1344 
1345         wlan_set_low_power_mode();
1346     }
1347 #endif
1348 
1349     if (cal_data_valid)
1350     {
1351 #if CONFIG_FW_VDLL
1352         while (pmadapter->vdll_in_progress == MTRUE)
1353         {
1354             OSA_TimeDelay(50);
1355         }
1356 #endif
1357         wifi_io_d("CMD : SET_CAL_DATA (0x8f)");
1358 
1359         _wlan_set_cal_data();
1360     }
1361 
1362     /* When cal data set command is sent, fimrware looses alignment of SDIO Tx buffers.
1363      * So we need to send reconfigure command. This can be removed if fix is added in firmware.
1364      */
1365     wifi_io_d("CMD : RECONFIGURE_TX_BUFF (0xd9)");
1366 
1367 #if CONFIG_FW_VDLL
1368     while (pmadapter->vdll_in_progress == MTRUE)
1369     {
1370         OSA_TimeDelay(50);
1371     }
1372 #endif
1373 
1374     wlan_reconfigure_tx_buffers();
1375 
1376     if (mac_addr_valid)
1377     {
1378         wifi_io_d("CMD : SET_MAC_ADDR (0x4d)");
1379 #if CONFIG_FW_VDLL
1380         while (pmadapter->vdll_in_progress == MTRUE)
1381         {
1382             OSA_TimeDelay(50);
1383         }
1384 #endif
1385         _wlan_set_mac_addr();
1386     }
1387 
1388 #ifdef OTP_CHANINFO
1389     wifi_io_d("CMD : Channel Region CFG (0x0242)");
1390 
1391 #if CONFIG_FW_VDLL
1392     while (pmadapter->vdll_in_progress == MTRUE)
1393     {
1394         OSA_TimeDelay(50);
1395     }
1396 #endif
1397 
1398     wlan_get_channel_region_cfg();
1399 #endif
1400 
1401     wifi_io_d("CMD : GET_HW_SPEC (0x03)");
1402 
1403 #if CONFIG_FW_VDLL
1404     while (pmadapter->vdll_in_progress == MTRUE)
1405     {
1406         OSA_TimeDelay(50);
1407     }
1408 #endif
1409 
1410     wlan_get_hw_spec();
1411 
1412 #if CONFIG_FW_VDLL
1413     while (pmadapter->vdll_in_progress == MTRUE)
1414     {
1415         OSA_TimeDelay(50);
1416     }
1417 #endif
1418 
1419     wlan_get_value_1();
1420 
1421     if (wm_wifi.wifi_init_done == 0U)
1422     {
1423 
1424         wifi_io_d("CMD : GET_FW_VER_EXT (0x97)");
1425 
1426 #if CONFIG_FW_VDLL
1427         while (pmadapter->vdll_in_progress == MTRUE)
1428         {
1429             OSA_TimeDelay(50);
1430         }
1431 #endif
1432 
1433         wlan_get_fw_ver_ext(0);
1434     }
1435 
1436     wifi_io_d("CMD : GET_MAC_ADDR (0x4d)");
1437 
1438 #if CONFIG_FW_VDLL
1439     while (pmadapter->vdll_in_progress == MTRUE)
1440     {
1441         OSA_TimeDelay(50);
1442     }
1443 #endif
1444 
1445     wlan_get_mac_addr_sta();
1446 
1447     wifi_io_d("CMD : GET_MAC_ADDR (0x4d)");
1448 
1449 #if CONFIG_FW_VDLL
1450     while (pmadapter->vdll_in_progress == MTRUE)
1451     {
1452         OSA_TimeDelay(50);
1453     }
1454 #endif
1455 
1456     wlan_get_mac_addr_uap();
1457 
1458     if (wm_wifi.wifi_init_done == 0U)
1459     {
1460 
1461         wifi_io_d("CMD : GET_FW_VER_EXT (0x97)");
1462 
1463 #if CONFIG_FW_VDLL
1464         while (pmadapter->vdll_in_progress == MTRUE)
1465         {
1466             OSA_TimeDelay(50);
1467         }
1468 #endif
1469 
1470         wlan_get_fw_ver_ext(3);
1471 
1472     }
1473 
1474     wifi_io_d("CMD : MAC_CTRL (0x28)");
1475 
1476 #if CONFIG_FW_VDLL
1477     while (pmadapter->vdll_in_progress == MTRUE)
1478     {
1479         OSA_TimeDelay(50);
1480     }
1481 #endif
1482 
1483     wlan_set_mac_ctrl();
1484 
1485     if (wm_wifi.wifi_init_done == 0U)
1486     {
1487         wifi_io_d("CMD : GET_FW_VER_EXT (0x97)");
1488 
1489 #if CONFIG_FW_VDLL
1490         while (pmadapter->vdll_in_progress == MTRUE)
1491         {
1492             OSA_TimeDelay(50);
1493         }
1494 #endif
1495 
1496         wlan_get_fw_ver_ext(4);
1497     }
1498 
1499 #if CONFIG_EXTERNAL_BLE_COEX
1500 #if CONFIG_FW_VDLL
1501     while (pmadapter->vdll_in_progress == MTRUE)
1502     {
1503         OSA_TimeDelay(50);
1504     }
1505 #endif
1506 
1507     wlan_set_ext_ble_coex_mode();
1508 #endif
1509 
1510 #if CONFIG_11N
1511     wifi_io_d("CMD : 11N_CFG (0xcd)");
1512 
1513 #if CONFIG_FW_VDLL
1514     while (pmadapter->vdll_in_progress == MTRUE)
1515     {
1516         OSA_TimeDelay(50);
1517     }
1518 #endif
1519 
1520     wlan_set_11n_cfg();
1521 
1522 #if CONFIG_ENABLE_AMSDU_RX
1523     wifi_io_d("CMD : AMSDU_AGGR_CTRL (0xdf)");
1524 
1525 #if CONFIG_FW_VDLL
1526     while (pmadapter->vdll_in_progress == MTRUE)
1527     {
1528         OSA_TimeDelay(50);
1529     }
1530 #endif
1531 
1532     wlan_enable_amsdu();
1533 
1534 #endif /* CONFIG_ENABLE_AMSDU_RX */
1535 #endif /* CONFIG_11N */
1536 
1537     return;
1538 }
1539 
1540 #if CONFIG_P2P
wlan_send_gen_sdio_cmd(t_u8 * buf,t_u32 buflen)1541 mlan_status wlan_send_gen_sdio_cmd(t_u8 *buf, t_u32 buflen)
1542 {
1543     SDIOPkt *sdio = (SDIOPkt *)outbuf;
1544     uint32_t resp;
1545 
1546     (void)memset(outbuf, 0, 512);
1547 
1548     wifi_sdio_lock();
1549     (void)memcpy((void *)outbuf, (const void *)buf, buflen);
1550     sdio->pkttype         = MLAN_TYPE_CMD;
1551     sdio->hostcmd.seq_num = (0x01) << 13;
1552     sdio->size            = sdio->hostcmd.size + INTF_HEADER_LEN;
1553 
1554     sdio_drv_write(mlan_adap->ioport, 1, 1, buflen, (t_u8 *)outbuf, &resp);
1555 
1556     last_cmd_sent = sdio->hostcmd.command;
1557     wifi_sdio_unlock();
1558 
1559     return 0;
1560 }
1561 #endif
1562 
1563 #if CONFIG_FW_VDLL
wlan_send_sdio_vdllcmd(t_u8 * buf,t_u32 tx_blocks,t_u32 buflen)1564 int wlan_send_sdio_vdllcmd(t_u8 *buf, t_u32 tx_blocks, t_u32 buflen)
1565 {
1566     SDIOPkt *sdio = (SDIOPkt *)(void *)outbuf;
1567     uint32_t resp;
1568 
1569     (void)memcpy((void *)outbuf, (const void *)buf, tx_blocks * buflen);
1570     sdio->pkttype = MLAN_TYPE_VDLL;
1571     sdio->size    = sdio->hostcmd.size + INTF_HEADER_LEN;
1572 
1573 #if CONFIG_WIFI_IO_DUMP
1574     (void)PRINTF("OUT_CMD");
1575     dump_hex(outbuf, sdio->size);
1576 #endif /* CONFIG_WIFI_IO_DUMP */
1577 #if defined(SD8801)
1578     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1579 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1580     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1581 #endif
1582 
1583     return WM_SUCCESS;
1584 }
1585 #endif
1586 
wlan_send_sdio_cmd(t_u8 * buf,t_u32 tx_blocks,t_u32 buflen)1587 int wlan_send_sdio_cmd(t_u8 *buf, t_u32 tx_blocks, t_u32 buflen)
1588 {
1589     SDIOPkt *sdio = (SDIOPkt *)(void *)outbuf;
1590     uint32_t resp;
1591 
1592     (void)wifi_sdio_lock();
1593 
1594     (void)memcpy((void *)outbuf, (const void *)buf, tx_blocks * buflen);
1595     sdio->pkttype = MLAN_TYPE_CMD;
1596     sdio->size    = sdio->hostcmd.size + INTF_HEADER_LEN;
1597 
1598 #if CONFIG_WIFI_IO_DUMP
1599     (void)PRINTF("OUT_CMD");
1600     dump_hex(outbuf, sdio->size);
1601 #endif /* CONFIG_WIFI_IO_DUMP */
1602 #if defined(SD8801)
1603     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1604 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1605     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1606 #endif
1607 
1608     last_cmd_sent = sdio->hostcmd.command;
1609     wifi_sdio_unlock();
1610 
1611     return WM_SUCCESS;
1612 }
1613 
wifi_send_cmdbuffer(t_u32 tx_blocks,t_u32 len)1614 int wifi_send_cmdbuffer(t_u32 tx_blocks, t_u32 len)
1615 {
1616     return wlan_send_sdio_cmd(ctrl_cmd_buf, tx_blocks, len);
1617 }
1618 
1619 #if CONFIG_FW_VDLL
wifi_send_vdllcmdbuffer(t_u32 tx_blocks,t_u32 len)1620 int wifi_send_vdllcmdbuffer(t_u32 tx_blocks, t_u32 len)
1621 {
1622     return wlan_send_sdio_vdllcmd(vdll_cmd_buf, tx_blocks, len);
1623 }
1624 #endif
1625 
1626 #if CONFIG_WMM
1627 
1628 #if CONFIG_SDIO_MULTI_PORT_TX_AGGR
1629 static t_u32 buf_block_len = 0;
1630 static t_u8 start_port     = -1;
1631 static t_u8 ports          = 0;
1632 static t_u8 pkt_cnt        = 0;
1633 
1634 /**
1635  *  @brief This function gets available SDIO port for writing data
1636  *
1637  *  @param pmadapter  A pointer to mlan_adapter structure
1638  *  @param pport      A pointer to port number
1639  *  @return           MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1640  */
wlan_get_wr_port_data(t_u8 * pport)1641 mlan_status wlan_get_wr_port_data(t_u8 *pport)
1642 {
1643 #if CONFIG_WIFI_IO_DEBUG
1644     t_u32 wr_bitmap = mlan_adap->mp_wr_bitmap;
1645 #endif
1646 
1647     ENTER();
1648 
1649     wifi_io_d("wlan_get_wr_port_data: mp_wr_bitmap=0x%08x", wr_bitmap);
1650 
1651     if ((1U << txportno) & mlan_adap->mp_wr_bitmap)
1652     {
1653         mlan_adap->mp_wr_bitmap &= (t_u32)(~(1 << txportno));
1654         *pport = txportno;
1655         txportno++;
1656 
1657         if (txportno == mlan_adap->mp_end_port)
1658         {
1659 #if defined(SD8801)
1660             txportno = 1;
1661 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1662             txportno = 0;
1663 #endif
1664         }
1665     }
1666     else
1667     {
1668         LEAVE();
1669         return MLAN_STATUS_RESOURCE;
1670     }
1671 
1672 #if defined(SD8801)
1673     if (*pport == CTRL_PORT)
1674     {
1675         wifi_io_d("Invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\r\n", *pport, txportno, wr_bitmap,
1676                mlan_adap->mp_wr_bitmap);
1677         LEAVE();
1678         return MLAN_STATUS_FAILURE;
1679     }
1680 #endif
1681 
1682     wifi_io_d("port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n", *pport, wr_bitmap, mlan_adap->mp_wr_bitmap);
1683 
1684     LEAVE();
1685     return MLAN_STATUS_SUCCESS;
1686 }
1687 
wifi_tx_data(t_u8 start_port,t_u8 ports,t_u8 pkt_cnt,t_u32 txlen)1688 static mlan_status wifi_tx_data(t_u8 start_port, t_u8 ports, t_u8 pkt_cnt, t_u32 txlen)
1689 {
1690     t_u32 cmd53_port;
1691     t_u32 tx_blocks = 0, buflen = 0;
1692     uint32_t resp;
1693     bool ret;
1694 #if CONFIG_WIFI_FW_DEBUG
1695     int ret_cb;
1696 #endif
1697 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1698     t_u32 port_count = 0;
1699 #endif
1700 
1701     calculate_sdio_write_params(txlen, &tx_blocks, &buflen);
1702 
1703     if (pkt_cnt == 1)
1704     {
1705         cmd53_port = mlan_adap->ioport + start_port;
1706     }
1707     else
1708     {
1709 #if defined(SD8801)
1710         cmd53_port = (mlan_adap->ioport | SDIO_MPA_ADDR_BASE | (ports << 4)) + start_port;
1711 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1712         port_count = ports - 1U;
1713         cmd53_port = (mlan_adap->ioport | SDIO_MPA_ADDR_BASE | (port_count << 8)) + start_port;
1714 #endif
1715     }
1716 
1717     //(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);
1718 
1719     /* send CMD53 */
1720     ret = sdio_drv_write(cmd53_port, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
1721 
1722     if (ret == false)
1723     {
1724         wifi_io_e("sdio_drv_write failed (%d)", ret);
1725 #if CONFIG_WIFI_FW_DEBUG
1726         wifi_sdio_reg_dbg(NULL);
1727         if (wm_wifi.wifi_usb_mount_cb != NULL)
1728         {
1729             ret_cb = wm_wifi.wifi_usb_mount_cb();
1730             if (ret_cb == WM_SUCCESS)
1731                 wifi_dump_firmware_info(NULL);
1732             else
1733                 wifi_e("USB mounting failed");
1734         }
1735         else
1736             wifi_e("USB mount callback is not registered");
1737 #endif
1738         return MLAN_STATUS_RESOURCE;
1739     }
1740     return MLAN_STATUS_SUCCESS;
1741 }
1742 
wlan_xmit_wmm_pkt(t_u8 interface,t_u32 txlen,t_u8 * tx_buf)1743 mlan_status wlan_xmit_wmm_pkt(t_u8 interface, t_u32 txlen, t_u8 *tx_buf)
1744 {
1745     t_u32 tx_blocks = 0, buflen = 0;
1746     mlan_status ret = MLAN_STATUS_SUCCESS;
1747 #if CONFIG_WMM_UAPSD
1748     bool last_packet = 0;
1749 #endif
1750     t_u8 port     = 0;
1751 
1752     if (buf_block_len == 0)
1753     {
1754         start_port = -1;
1755         ports      = 0;
1756         pkt_cnt    = 0;
1757     }
1758 
1759     calculate_sdio_write_params(txlen, &tx_blocks, &buflen);
1760 
1761 #if CONFIG_WIFI_IO_DEBUG
1762     (void)PRINTF("%s: txportno = %d mlan_adap->mp_wr_bitmap: %x\n\r", __func__, txportno, mlan_adap->mp_wr_bitmap);
1763 #endif /* CONFIG_WIFI_IO_DEBUG */
1764 
1765     ret = wlan_get_wr_port_data(&port);
1766     if (ret != WM_SUCCESS)
1767     {
1768         return MLAN_STATUS_RESOURCE;
1769     }
1770 
1771 #if CONFIG_WMM_UAPSD
1772     if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1773         wifi_check_last_packet_indication(mlan_adap->priv[interface]))
1774     {
1775 #if CONFIG_TX_RX_ZERO_COPY
1776         process_pkt_hdrs_flags(&((outbuf_t *)tx_buf)->intf_header[0], MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1777 #else
1778         process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1779 #endif
1780         last_packet = 1;
1781     }
1782 #endif
1783 
1784     if (buf_block_len == 0)
1785     {
1786         start_port = port;
1787     }
1788 
1789 #if CONFIG_TX_RX_ZERO_COPY
1790     net_tx_zerocopy_process_cb(outbuf + buf_block_len, tx_buf, txlen);
1791 #else
1792     memcpy(outbuf + buf_block_len, tx_buf, txlen);
1793 #endif
1794 
1795     buf_block_len += tx_blocks * buflen;
1796 
1797     ports++;
1798     pkt_cnt++;
1799 
1800 #if CONFIG_WMM_UAPSD
1801     if (last_packet)
1802     {
1803         mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1804         OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1805     }
1806 #endif
1807 
1808     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);
1809 
1810     return MLAN_STATUS_SUCCESS;
1811 }
1812 
wlan_flush_wmm_pkt(t_u8 pkt_count)1813 mlan_status wlan_flush_wmm_pkt(t_u8 pkt_count)
1814 {
1815     int ret;
1816 
1817     if (pkt_count == 0)
1818         return MLAN_STATUS_SUCCESS;
1819 
1820     w_pkt_d("Data TX: Driver=>FW, pkt_count %d", pkt_cnt);
1821 
1822     ret = wifi_tx_data(start_port, ports, pkt_cnt, buf_block_len);
1823 
1824     buf_block_len = 0;
1825 
1826     if (ret != MLAN_STATUS_SUCCESS)
1827     {
1828         return MLAN_STATUS_RESOURCE;
1829     }
1830 
1831     return MLAN_STATUS_SUCCESS;
1832 }
1833 #else
1834 extern int retry_attempts;
1835 
get_free_port(void)1836 static int get_free_port(void)
1837 {
1838     /* Check if the port is available */
1839     if (!((1 << txportno) & mlan_adap->mp_wr_bitmap))
1840     {
1841 #if CONFIG_WIFI_IO_DEBUG
1842         wifi_io_e(
1843             "txportno out of sync txportno "
1844             "= (%d) mp_wr_bitmap = (0x%x)",
1845             txportno, mlan_adap->mp_wr_bitmap);
1846 #endif /* CONFIG_WIFI_IO_DEBUG */
1847 
1848         return -WM_FAIL;
1849     }
1850     else
1851     {
1852         /* Mark the port number we will use */
1853         mlan_adap->mp_wr_bitmap &= ~(1 << txportno);
1854     }
1855     return WM_SUCCESS;
1856 }
1857 
wlan_xmit_wmm_pkt(t_u8 interface,t_u32 txlen,t_u8 * tx_buf)1858 mlan_status wlan_xmit_wmm_pkt(t_u8 interface, t_u32 txlen, t_u8 *tx_buf)
1859 {
1860     t_u32 tx_blocks = 0, buflen = 0;
1861     uint32_t resp;
1862     int ret   = false;
1863     int retry = retry_attempts;
1864 #if CONFIG_WMM_UAPSD
1865     bool last_packet = 0;
1866 #endif
1867 
1868     wifi_io_info_d("OUT: i/f: %d len: %d", interface, tx_blocks * buflen);
1869 
1870     calculate_sdio_write_params(txlen, &tx_blocks, &buflen);
1871 
1872 #if CONFIG_WIFI_IO_DEBUG
1873     (void)PRINTF("%s: txportno = %d mlan_adap->mp_wr_bitmap: %x\n\r", __func__, txportno, mlan_adap->mp_wr_bitmap);
1874 #endif /* CONFIG_WIFI_IO_DEBUG */
1875 
1876 retry_xmit:
1877     ret = get_free_port();
1878     if (ret == -WM_FAIL)
1879     {
1880         if (!retry)
1881         {
1882             ret = MLAN_STATUS_RESOURCE;
1883             goto exit_fn;
1884         }
1885         else
1886         {
1887             retry--;
1888             /* Allow the other thread to run and hence
1889              * update the write bitmap so that pkt
1890              * can be sent to FW */
1891             OSA_TimeDelay(1);
1892             goto retry_xmit;
1893         }
1894     }
1895 
1896 #if CONFIG_WMM_UAPSD
1897     if (mlan_adap->priv[interface]->adapter->pps_uapsd_mode &&
1898         wifi_check_last_packet_indication(mlan_adap->priv[interface]))
1899     {
1900         process_pkt_hdrs_flags((t_u8 *)tx_buf, MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
1901         last_packet = 1;
1902     }
1903 #endif
1904 
1905     /* send CMD53 */
1906     ret = sdio_drv_write(mlan_adap->ioport + txportno, 1, tx_blocks, buflen, tx_buf, &resp);
1907 
1908     txportno++;
1909     if (txportno == mlan_adap->mp_end_port)
1910     {
1911 #if defined(SD8801)
1912         txportno = 1;
1913 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
1914         txportno = 0;
1915 #endif
1916     }
1917 
1918     if (ret == false)
1919     {
1920 #if CONFIG_WMM_UAPSD
1921         if (last_packet)
1922             process_pkt_hdrs_flags((t_u8 *)tx_buf, 0);
1923 #endif
1924 
1925         wifi_io_e("sdio_drv_write failed (%d)", ret);
1926 #if CONFIG_WIFI_FW_DEBUG
1927         wifi_sdio_reg_dbg(NULL);
1928         if (wm_wifi.wifi_usb_mount_cb != NULL)
1929         {
1930             ret = wm_wifi.wifi_usb_mount_cb();
1931             if (ret == WM_SUCCESS)
1932                 wifi_dump_firmware_info(NULL);
1933             else
1934                 wifi_e("USB mounting failed");
1935         }
1936         else
1937             wifi_e("USB mount callback is not registered");
1938 #endif
1939         ret = MLAN_STATUS_RESOURCE;
1940         goto exit_fn;
1941     }
1942 
1943 #if CONFIG_WMM_UAPSD
1944     if (last_packet)
1945     {
1946         mlan_adap->priv[interface]->adapter->tx_lock_flag = MTRUE;
1947         OSA_SemaphoreWait((osa_semaphore_handle_t)uapsd_sem, osaWaitForever_c);
1948     }
1949 #endif
1950 
1951     ret = MLAN_STATUS_SUCCESS;
1952 
1953 exit_fn:
1954 
1955     return ret;
1956 }
1957 
wlan_flush_wmm_pkt(t_u8 pkt_count)1958 mlan_status wlan_flush_wmm_pkt(t_u8 pkt_count)
1959 {
1960     return MLAN_STATUS_SUCCESS;
1961 }
1962 
1963 #endif
1964 #endif
1965 
wlan_xmit_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface,t_u32 tx_control)1966 mlan_status wlan_xmit_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface, t_u32 tx_control)
1967 {
1968 
1969     (void)interface;
1970 
1971     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1972 
1973     process_pkt_hdrs((t_u8 *)buffer, txlen, interface, 0, tx_control);
1974 
1975     return wifi_send_fw_data(buffer, txlen);
1976 }
1977 
1978 #if CONFIG_WMM
wlan_xmit_bypass_pkt(t_u8 * buffer,t_u32 txlen,t_u8 interface)1979 mlan_status wlan_xmit_bypass_pkt(t_u8 *buffer, t_u32 txlen, t_u8 interface)
1980 {
1981 
1982     (void)interface;
1983 
1984     wifi_io_info_d("OUT: i/f: %d len: %d", interface, txlen);
1985 
1986     return wifi_send_fw_data(buffer, txlen);
1987 }
1988 #endif
1989 
wlan_send_null_packet(pmlan_private priv,t_u8 flags)1990 mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags)
1991 {
1992     mlan_status ret;
1993     t_u8 pbuf[128]  = {0};
1994     TxPD *ptxpd    = (TxPD *)((uint8_t *)pbuf + INTF_HEADER_LEN);
1995 
1996     ptxpd->bss_type      = priv->bss_type;
1997     ptxpd->bss_num       = GET_BSS_NUM(priv);
1998     ptxpd->tx_pkt_offset = 0x16; /* we'll just make this constant */
1999     ptxpd->tx_pkt_length = 0;
2000     ptxpd->tx_control    = 0;
2001     ptxpd->priority      = 0;
2002     ptxpd->flags         = flags;
2003     ptxpd->pkt_delay_2ms = 0;
2004 
2005     ret = wifi_send_fw_data(pbuf, sizeof(TxPD) + INTF_HEADER_LEN);
2006 
2007     if (ret != MLAN_STATUS_SUCCESS)
2008     {
2009         wifi_io_d("sdio_drv_write failed (%d)", ret);
2010         return MLAN_STATUS_FAILURE;
2011     }
2012 
2013     return MLAN_STATUS_SUCCESS;
2014 }
2015 
2016 /*
2017  * This function gets interrupt status.
2018  */
wlan_interrupt(mlan_adapter * pmadapter)2019 t_void wlan_interrupt(mlan_adapter *pmadapter)
2020 {
2021     /* Read SDIO multiple port group registers */
2022     uint32_t resp = 0;
2023     int ret;
2024     t_u8 *mp_regs = pmadapter->mp_regs;
2025 
2026     /* Read the registers in DMA aligned buffer */
2027 #if defined(SD8801)
2028     ret = sdio_drv_read(0, 1, 1, MAX_MP_REGS, mp_regs, &resp);
2029 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2030     ret = sdio_drv_read(REG_PORT | MLAN_SDIO_BYTE_MODE_MASK, 1, 1, MAX_MP_REGS, mp_regs, &resp);
2031 #endif
2032 
2033     if (!ret)
2034     {
2035         return;
2036     }
2037 
2038     t_u8 sdio_ireg = mp_regs[HOST_INT_STATUS_REG];
2039 
2040     if (sdio_ireg != 0U)
2041     {
2042         /*
2043          * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
2044          * Clear the interrupt status register
2045          */
2046         pmadapter->sdio_ireg |= sdio_ireg;
2047     }
2048 
2049 #if CONFIG_WMM
2050     t_u32 wr_bitmap;
2051 
2052 #if defined(SD8801)
2053     wr_bitmap = ((t_u16)mp_regs[WR_BITMAP_U]) << 8;
2054     wr_bitmap |= (t_u16)mp_regs[WR_BITMAP_L];
2055 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2056     wr_bitmap = (t_u32)mp_regs[WR_BITMAP_L];
2057     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_U]) << 8;
2058     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1L]) << 16;
2059     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1U]) << 24;
2060 #endif
2061 
2062     if (!!wr_bitmap)
2063     {
2064         if (mlan_adap->wait_txbuf == true)
2065         {
2066             OSA_SemaphorePost((osa_semaphore_handle_t)txbuf_sem);
2067             send_wifi_driver_tx_data_event(0);
2068         }
2069     }
2070 #endif
2071 
2072 #if CONFIG_WIFI_IO_DEBUG
2073     t_u32 rd_bitmap;
2074 #if !CONFIG_WMM
2075     t_u32 wr_bitmap;
2076 
2077 #if defined(SD8801)
2078     wr_bitmap = ((t_u16)mp_regs[WR_BITMAP_U]) << 8;
2079     wr_bitmap |= (t_u16)mp_regs[WR_BITMAP_L];
2080 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2081     wr_bitmap = (t_u32)mp_regs[WR_BITMAP_L];
2082     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_U]) << 8;
2083     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1L]) << 16;
2084     wr_bitmap |= ((t_u32)mp_regs[WR_BITMAP_1U]) << 24;
2085 #endif
2086 
2087 #endif
2088 #if defined(SD8801)
2089     rd_bitmap = ((t_u16)mp_regs[RD_BITMAP_U]) << 8;
2090     rd_bitmap |= (t_u16)mp_regs[RD_BITMAP_L];
2091 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2092     rd_bitmap = (t_u32)mp_regs[RD_BITMAP_L];
2093     rd_bitmap |= ((t_u32)mp_regs[RD_BITMAP_U]) << 8;
2094     rd_bitmap |= ((t_u32)mp_regs[RD_BITMAP_1L]) << 16;
2095     rd_bitmap |= ((t_u32)mp_regs[RD_BITMAP_1U]) << 24;
2096 #endif
2097 
2098     (void)PRINTF("INT : rd_bitmap=0x%x\n\r", rd_bitmap);
2099 
2100     (void)PRINTF("INT : wr_bitmap=0x%x\n\r", wr_bitmap);
2101 
2102     (void)PRINTF("INT : sdio_ireg = (0x%x)\r\n", sdio_ireg);
2103 #endif /* CONFIG_WIFI_IO_DEBUG */
2104 }
2105 
2106 #if CONFIG_TP_OPTIMIZATIONS
bitcount(t_u32 num)2107 static t_u32 bitcount(t_u32 num)
2108 {
2109     t_u32 count = 0;
2110     static t_u32 nibblebits[] = { 0, 1, 1, 2, 1, 2, 2, 3,
2111                     1, 2, 2, 3, 2, 3, 3, 4 };
2112     for (; num != 0; num >>= 4)
2113         count += nibblebits[num & 0x0f];
2114     return count;
2115 }
2116 #endif
2117 #if CONFIG_SDIO_MULTI_PORT_RX_AGGR
2118 #if CONFIG_TP_OPTIMIZATIONS
2119 static t_u8 start_check = 0;
2120 static t_u8 skip_int = 0;
2121 #endif
2122 
2123 /* returns port number from rd_bitmap. if ctrl port, then it clears
2124  * the bit and does nothing else
2125  * 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)2126 static mlan_status wlan_get_rd_port(mlan_adapter *pmadapter, t_u32 *pport, t_u32 *rxlen, t_u32 *rxblocks, bool *aggr)
2127 {
2128 #if defined(SD8801)
2129     t_u16 rd_bitmap = pmadapter->mp_rd_bitmap;
2130 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2131     t_u32 rd_bitmap = pmadapter->mp_rd_bitmap;
2132 #endif
2133     t_u16 pkt_cnt = 0;
2134     t_u32 len_reg_l, len_reg_u;
2135     t_u32 rx_len;
2136     t_u32 rx_blocks;
2137     t_u16 ports      = 0;
2138     t_u32 start_port = -1;
2139     t_u32 cmd53_port = 0;
2140 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2141     t_u32 port_count = 0;
2142 #endif
2143 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2144     uint32_t *rxdataAddr = NULL;
2145 #endif
2146 
2147     *pport    = -1;
2148     *rxlen    = 0;
2149     *rxblocks = 0;
2150 
2151     wifi_io_d(
2152         "wlan_get_rd_port: mp_rd_bitmap=0x%x"
2153         " curr_rd_bitmap=0x%x\r\n",
2154         pmadapter->mp_rd_bitmap, pmadapter->curr_rd_port);
2155 
2156 #if defined(SD8801)
2157     if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
2158 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2159     if (!(rd_bitmap & DATA_PORT_MASK))
2160 #endif
2161     {
2162         return MLAN_STATUS_FAILURE;
2163     }
2164 
2165 #if defined(SD8801)
2166     if (pmadapter->mp_rd_bitmap & CTRL_PORT_MASK)
2167     {
2168         pmadapter->mp_rd_bitmap &= (t_u32)(~CTRL_PORT_MASK);
2169         *pport = CTRL_PORT;
2170 
2171         len_reg_l = RD_LEN_P0_L + (*pport << 1);
2172         len_reg_u = RD_LEN_P0_U + (*pport << 1);
2173         rx_len    = ((t_u16)pmadapter->mp_regs[len_reg_u]) << 8;
2174         rx_len |= (t_u16)pmadapter->mp_regs[len_reg_l];
2175         rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1) / MLAN_SDIO_BLOCK_SIZE;
2176         rx_len    = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2177         *rxlen    = rx_len;
2178         *rxblocks = rx_blocks;
2179 
2180         *pport = mlan_adap->ioport + *pport;
2181 
2182         wifi_io_d("RX: port=%d rxlen=%u rx_blocks=%u\r\n", *pport, *rxlen, *rxblocks);
2183 
2184         wifi_io_d("wlan_get_rd_port: port=%d mp_rd_bitmap=0x%04x", *pport, pmadapter->mp_rd_bitmap);
2185     }
2186     else
2187     {
2188 #endif
2189 
2190 #if CONFIG_TP_OPTIMIZATIONS
2191         /* This change is being added to handle low throughput caused for Tx due to excess interrupts received for Rx.
2192         * The intention is to ignore the interrupt if received agreggated packets are less than 4.
2193         * However, there could be single data packets during DHCP request, etc. whose Rx interrupt should not be skipped.
2194         * For actual data, we are checking if read bitmap has at least 4 ports available if current read port is 27.
2195         * If current read port is greater than 27 then any number of available ports is fine. */
2196         if (bitcount(pmadapter->mp_rd_bitmap) == 8U)
2197         {
2198             start_check = 1;
2199         }
2200 
2201         if (skip_int == 2)
2202         {
2203             start_check = 0;
2204         }
2205         /* Data */
2206         if ((start_check) && ((pmadapter->mp_rd_bitmap & ((pmadapter->curr_rd_port > 27 ? 1U : 0xFU) << pmadapter->curr_rd_port)) == 0U))
2207         {
2208             skip_int++;
2209             return MLAN_STATUS_FAILURE;
2210         }
2211 #endif
2212         while ((pmadapter->mp_rd_bitmap & (1U << pmadapter->curr_rd_port)) != 0U)
2213         {
2214             *pport = pmadapter->curr_rd_port;
2215 
2216             len_reg_l = RD_LEN_P0_L + (*pport << 1U);
2217             len_reg_u = RD_LEN_P0_U + (*pport << 1U);
2218             rx_len    = ((t_u16)pmadapter->mp_regs[len_reg_u]) << 8;
2219             rx_len |= (t_u16)pmadapter->mp_regs[len_reg_l];
2220             rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2221             rx_len    = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2222 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2223             if (wm_wifi.wifi_get_rxbuf_desc != NULL)
2224             {
2225                 rxdataAddr = (uint32_t *)wm_wifi.wifi_get_rxbuf_desc(rx_len);
2226 
2227                 if (rxdataAddr == NULL)
2228                 {
2229                     PRINTF("No pbuf\r\n");
2230                     break;
2231                 }
2232             }
2233 #else
2234             if ((*rxlen + rx_len) > INBUF_SIZE)
2235             {
2236                 break;
2237             }
2238 #endif
2239 
2240             pmadapter->mp_rd_bitmap &=
2241 #if defined(SD8801)
2242                 (t_u16)(~(1 << pmadapter->curr_rd_port));
2243 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2244             (t_u32)(~(1 << pmadapter->curr_rd_port));
2245 #endif
2246 
2247 #if defined(SD8801)
2248             if (!pkt_cnt)
2249                 start_port = *pport;
2250 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2251         if (start_port == -1)
2252         {
2253             start_port = *pport;
2254         }
2255 #endif
2256 
2257 #if defined(SD8801)
2258             if (start_port <= *pport)
2259             {
2260                 ports |= (1 << (pkt_cnt));
2261             }
2262             else
2263             {
2264                 ports |= (1 << (pkt_cnt + 1));
2265             }
2266 #endif
2267 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2268             if (rxdataAddr)
2269             {
2270                 sg_set_buf(rxdataAddr, rx_len);
2271                 num_sg++;
2272             }
2273 #endif
2274 
2275             *rxlen += rx_len;
2276             *rxblocks += rx_blocks;
2277 
2278             //PRINTF("RX: port=%d rxlen=%u rx_blocks=%u\r\n", *pport, *rxlen, *rxblocks);
2279 
2280             if (++pmadapter->curr_rd_port == MAX_PORT)
2281             {
2282 #if defined(SD8801)
2283                 pmadapter->curr_rd_port = 1;
2284 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2285             pmadapter->curr_rd_port = 0;
2286 #endif
2287             }
2288 
2289             pkt_cnt++;
2290 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2291             ports++;
2292 #endif
2293 
2294             if (pkt_cnt == SDIO_MP_AGGR_DEF_PKT_LIMIT_MAX)
2295             {
2296                 break;
2297             }
2298 #if defined(SD8801)
2299             if ((pmadapter->curr_rd_port < start_port) &&
2300                 (((MAX_PORT - start_port) + pmadapter->curr_rd_port) >= SDIO_MP_AGGR_DEF_PKT_LIMIT))
2301             {
2302                 break;
2303             }
2304 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2305         if (((pmadapter->curr_rd_port < start_port) &&
2306              (((MAX_PORT - start_port) + pmadapter->curr_rd_port) >= (pmadapter->mp_end_port >> 1))) ||
2307             ((pmadapter->curr_rd_port - start_port) >= (pmadapter->mp_end_port >> 1)))
2308         {
2309             break;
2310         }
2311 #endif
2312         }
2313 
2314         if (*pport == -1 || ports == 0)
2315         {
2316             wifi_io_e("wlan_get_rd_port : Returning FAILURE");
2317             return MLAN_STATUS_FAILURE;
2318         }
2319 
2320 #if defined(SD8801)
2321         if (pkt_cnt > 1)
2322 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2323         if (ports > 1U)
2324 #endif
2325         {
2326 #if defined(SD8801)
2327             cmd53_port = (pmadapter->ioport | SDIO_MPA_ADDR_BASE | (ports << 4)) + start_port;
2328 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2329         port_count = ports - 1U;
2330         cmd53_port = (pmadapter->ioport | SDIO_MPA_ADDR_BASE | (port_count << 8)) + start_port;
2331 #endif
2332             *pport = cmd53_port;
2333 
2334             *aggr = true;
2335 
2336             //(void)PRINTF("cmd53_port=%x, ports=%x, start_port=%x rxlen=%d rxblocks=%d\r\n", cmd53_port, ports,
2337             //start_port, *rxlen, *rxblocks);
2338         }
2339         else
2340         {
2341             *pport = mlan_adap->ioport + *pport;
2342         }
2343 
2344         wifi_io_d("port=%x mp_rd_bitmap=0x%x -> 0x%x\n", *pport, rd_bitmap, pmadapter->mp_rd_bitmap);
2345 #if defined(SD8801)
2346     }
2347 #endif
2348 
2349     return MLAN_STATUS_SUCCESS;
2350 }
2351 
2352 /*
2353  * Assumes that pmadapter->mp_rd_bitmap contains latest values
2354  */
_handle_sdio_packet_read(mlan_adapter * pmadapter,t_u8 ** packet,t_u32 * datalen,t_u32 * pkt_type)2355 static mlan_status _handle_sdio_packet_read(mlan_adapter *pmadapter, t_u8 **packet, t_u32 *datalen, t_u32 *pkt_type)
2356 {
2357     t_u32 port;
2358     t_u32 rx_len = 0, rx_blocks = 0;
2359     bool aggr = false;
2360 
2361     mlan_status ret = wlan_get_rd_port(pmadapter, &port, &rx_len, &rx_blocks, &aggr);
2362 
2363     /* nothing to read */
2364     if (ret != MLAN_STATUS_SUCCESS)
2365     {
2366         return ret;
2367     }
2368 
2369     *datalen = rx_len;
2370 
2371     *packet = wlan_read_rcv_packet(port, rx_len, rx_blocks, pkt_type, aggr);
2372 
2373     if ((*packet) == MNULL)
2374     {
2375         return MLAN_STATUS_FAILURE;
2376     }
2377 
2378     return MLAN_STATUS_SUCCESS;
2379 }
2380 #else
2381 /* returns port number from rd_bitmap. if ctrl port, then it clears
2382  * the bit and does nothing else
2383  * if data port then increments curr_port value also */
wlan_get_rd_port(mlan_adapter * pmadapter,t_u32 * pport)2384 static mlan_status wlan_get_rd_port(mlan_adapter *pmadapter, t_u32 *pport)
2385 {
2386 #if defined(SD8801)
2387     t_u16 rd_bitmap = pmadapter->mp_rd_bitmap;
2388 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2389     t_u32 rd_bitmap = pmadapter->mp_rd_bitmap;
2390 #endif
2391 
2392     wifi_io_d(
2393         "wlan_get_rd_port: mp_rd_bitmap=0x%x"
2394         " curr_rd_bitmap=0x%x",
2395         pmadapter->mp_rd_bitmap, pmadapter->curr_rd_port);
2396 
2397 #if defined(SD8801)
2398     if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
2399 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2400     if (!(rd_bitmap & DATA_PORT_MASK))
2401 #endif
2402         return MLAN_STATUS_FAILURE;
2403 
2404 #if defined(SD8801)
2405     if (pmadapter->mp_rd_bitmap & CTRL_PORT_MASK)
2406     {
2407         pmadapter->mp_rd_bitmap &= (t_u16)(~CTRL_PORT_MASK);
2408         *pport = CTRL_PORT;
2409 
2410         wifi_io_d("wlan_get_rd_port: port=%d mp_rd_bitmap=0x%04x", *pport, pmadapter->mp_rd_bitmap);
2411     }
2412     else
2413     {
2414 #endif
2415         /* Data */
2416         if ((pmadapter->mp_rd_bitmap & (1 << pmadapter->curr_rd_port)) != 0U)
2417         {
2418             pmadapter->mp_rd_bitmap &=
2419 #if defined(SD8801)
2420                 (t_u16)(~(1 << pmadapter->curr_rd_port));
2421 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2422             (t_u32)(~(1 << pmadapter->curr_rd_port));
2423 #endif
2424             *pport = pmadapter->curr_rd_port;
2425 
2426             if (++pmadapter->curr_rd_port == MAX_PORT)
2427 #if defined(SD8801)
2428                 pmadapter->curr_rd_port = 1;
2429 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2430             pmadapter->curr_rd_port = 0;
2431 #endif
2432         }
2433         else
2434         {
2435             wifi_io_e("wlan_get_rd_port : Returning FAILURE");
2436             return MLAN_STATUS_FAILURE;
2437         }
2438 
2439         wifi_io_d("port=%d mp_rd_bitmap=0x%x -> 0x%x\n", *pport, rd_bitmap, pmadapter->mp_rd_bitmap);
2440 #if defined(SD8801)
2441     }
2442 #endif
2443 
2444     return MLAN_STATUS_SUCCESS;
2445 }
2446 
2447 /*
2448  * Assumes that pmadapter->mp_rd_bitmap contains latest values
2449  */
_handle_sdio_packet_read(mlan_adapter * pmadapter,t_u8 ** packet,t_u32 * datalen,t_u32 * pkt_type)2450 static mlan_status _handle_sdio_packet_read(mlan_adapter *pmadapter, t_u8 **packet, t_u32 *datalen, t_u32 *pkt_type)
2451 {
2452     t_u32 port;
2453     t_u32 rx_len, rx_blocks;
2454 
2455     mlan_status ret = wlan_get_rd_port(pmadapter, &port);
2456 
2457     /* nothing to read */
2458     if (ret != MLAN_STATUS_SUCCESS)
2459         return ret;
2460 
2461     t_u32 len_reg_l = RD_LEN_P0_L + (port << 1);
2462     t_u32 len_reg_u = RD_LEN_P0_U + (port << 1);
2463 
2464     rx_len = ((t_u16)pmadapter->mp_regs[len_reg_u]) << 8;
2465     *datalen = rx_len |= (t_u16)pmadapter->mp_regs[len_reg_l];
2466 
2467     rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1) / MLAN_SDIO_BLOCK_SIZE;
2468     rx_len = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2469 
2470     port = mlan_adap->ioport + port;
2471 
2472     *packet = wlan_read_rcv_packet(port, rx_len, rx_blocks, pkt_type, false);
2473 
2474     if (!*packet)
2475         return MLAN_STATUS_FAILURE;
2476 
2477     return MLAN_STATUS_SUCCESS;
2478 }
2479 #endif
2480 
2481 #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)2482 static mlan_status _handle_sdio_cmd_read(
2483     mlan_adapter *pmadapter, t_u8 **packet, t_u32 *datalen, t_u32 *pkt_type, t_u32 rx_len, t_u32 rx_blocks)
2484 {
2485     *datalen = rx_len;
2486 
2487     *packet = wlan_read_rcv_packet(mlan_adap->ioport | CMD_PORT_SLCT, rx_len, rx_blocks, pkt_type, false);
2488 
2489     if ((*packet) == MNULL)
2490     {
2491         return MLAN_STATUS_FAILURE;
2492     }
2493 
2494     return MLAN_STATUS_SUCCESS;
2495 }
2496 /*
2497  * This function keeps on looping till all the packets are read
2498  */
handle_sdio_cmd_read(mlan_adapter * pmadapter,t_u32 rx_len,t_u32 rx_blocks)2499 static void handle_sdio_cmd_read(mlan_adapter *pmadapter, t_u32 rx_len, t_u32 rx_blocks)
2500 {
2501     t_u32 datalen = 0;
2502 
2503     t_u32 pkt_type = 0;
2504     t_u8 *packet   = NULL;
2505 
2506     (void)_handle_sdio_cmd_read(pmadapter, &packet, &datalen, &pkt_type, rx_len, rx_blocks);
2507     if (pkt_type == MLAN_TYPE_CMD || pkt_type == MLAN_TYPE_EVENT)
2508     {
2509         /* non-data packets such as events
2510            and command responses are
2511            handled here */
2512         (void)wlan_decode_rx_packet(packet, pkt_type);
2513     }
2514 }
2515 #endif
2516 
2517 /*
2518  * This function keeps on looping till all the packets are read
2519  */
handle_sdio_packet_read(mlan_adapter * pmadapter)2520 static void handle_sdio_packet_read(mlan_adapter *pmadapter)
2521 {
2522     mlan_status ret = MLAN_STATUS_SUCCESS;
2523     t_u32 datalen   = 0;
2524 
2525     pmadapter->mp_rd_bitmap =
2526 #if defined(SD8801)
2527         ((t_u16)pmadapter->mp_regs[RD_BITMAP_U]) << 8;
2528     pmadapter->mp_rd_bitmap |= (t_u16)pmadapter->mp_regs[RD_BITMAP_L];
2529 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2530         (t_u32)pmadapter->mp_regs[RD_BITMAP_L];
2531     pmadapter->mp_rd_bitmap |= ((t_u32)pmadapter->mp_regs[RD_BITMAP_U]) << 8;
2532     pmadapter->mp_rd_bitmap |= ((t_u32)pmadapter->mp_regs[RD_BITMAP_1L]) << 16;
2533     pmadapter->mp_rd_bitmap |= ((t_u32)pmadapter->mp_regs[RD_BITMAP_1U]) << 24;
2534 #endif
2535 
2536     while (true)
2537     {
2538         t_u32 pkt_type = 0;
2539 #if !FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2540         t_u8 interface;
2541         t_u32 rx_blocks;
2542         t_u32 total_size = 0;
2543         t_u32 size       = 0;
2544 #endif
2545         t_u8 *packet     = NULL;
2546 
2547 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2548         num_sg = 0;
2549         sg_init_table();
2550 #endif
2551 
2552         ret = _handle_sdio_packet_read(pmadapter, &packet, &datalen, &pkt_type);
2553         if (ret != MLAN_STATUS_SUCCESS)
2554         {
2555             /* nothing to read. break out of while loop */
2556             break;
2557         }
2558 
2559         if (pkt_type == MLAN_TYPE_DATA)
2560         {
2561 
2562 #if FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER
2563             if (num_sg > 0)
2564             {
2565 //                extern void net_rx_notify();
2566 
2567 //                net_rx_notify();
2568                 wm_wifi.data_input_callback(0, NULL, 0);
2569 #if 0
2570                 for (sg_idx = 0; sg_idx < num_sg; sg_idx++)
2571                 {
2572                     SDIOPkt *insdiopkt = (SDIOPkt *)(void *)rx_bufs[sg_idx];
2573                     size               = insdiopkt->size;
2574                     pkt_type           = insdiopkt->pkttype;
2575 
2576                     interface = *((t_u8 *)packet + INTF_HEADER_LEN);
2577 
2578                     //PRINTF("IN: i/f: %d len: %d\r\n", interface, size);
2579 
2580                     if (bus.wifi_low_level_input != NULL)
2581                     {
2582                         (void)bus.wifi_low_level_input(interface, rx_bufs[sg_idx], size);
2583                     }
2584                 }
2585 #endif
2586             }
2587 #else
2588             {
2589                 while (total_size < datalen)
2590                 {
2591                     SDIOPkt *insdiopkt = (SDIOPkt *)(void *)packet;
2592                     size               = insdiopkt->size;
2593                     pkt_type           = insdiopkt->pkttype;
2594 
2595                     rx_blocks = (size + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2596                     size      = (t_u16)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2597 
2598                     interface = *((t_u8 *)packet + INTF_HEADER_LEN);
2599 
2600                     //PRINTF("IN: i/f: %d len: %d\r\n", interface, size);
2601 
2602                     if (!size)
2603                     {
2604                         break;
2605                     }
2606 
2607                     if (bus.wifi_low_level_input != NULL)
2608                     {
2609                         (void)bus.wifi_low_level_input(interface, packet, size);
2610                     }
2611 
2612                     packet += size;
2613                     total_size += size;
2614                 }
2615             }
2616 #endif
2617         }
2618         else
2619         {
2620             /* non-data packets such as events
2621                and command responses are
2622                handled here */
2623             (void)wlan_decode_rx_packet(packet, pkt_type);
2624         }
2625     }
2626 }
2627 
2628 /*
2629  * This is supposed to be called in thread context.
2630  */
wlan_process_int_status(mlan_adapter * pmadapter)2631 mlan_status wlan_process_int_status(mlan_adapter *pmadapter)
2632 {
2633     mlan_status ret = MLAN_STATUS_SUCCESS;
2634 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2635     t_u8 cmd_rd_len_0 = CMD_RD_LEN_0;
2636     t_u8 cmd_rd_len_1 = CMD_RD_LEN_1;
2637     t_u32 rx_len;
2638     t_u32 rx_blocks;
2639 #endif
2640 
2641     /* Get the interrupt status */
2642     wlan_interrupt(pmadapter);
2643 
2644     t_u8 sdio_ireg       = pmadapter->sdio_ireg;
2645     pmadapter->sdio_ireg = 0;
2646 
2647     if (!sdio_ireg)
2648     {
2649         goto done;
2650     }
2651 
2652 #if defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2653     /* check the command port */
2654     if ((sdio_ireg & DN_LD_CMD_PORT_HOST_INT_STATUS) != 0U)
2655     {
2656         if (pmadapter->cmd_sent != 0U)
2657         {
2658             pmadapter->cmd_sent = MFALSE;
2659         }
2660         PRINTM(MINFO, "cmd_sent=%d\n", pmadapter->cmd_sent);
2661     }
2662 
2663     if ((sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS) != 0U)
2664     {
2665         /* read the len of control packet */
2666         rx_len = ((t_u32)pmadapter->mp_regs[cmd_rd_len_1]) << 8;
2667         rx_len |= (t_u32)pmadapter->mp_regs[cmd_rd_len_0];
2668         PRINTM(MINFO, "RX: cmd port rx_len=%u\n", rx_len);
2669 
2670         rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2671 
2672         // (void)PRINTF("CMD: cmd port rx_len=%u rx_blocks=%u\r\n", rx_len, rx_blocks);
2673         rx_len = (t_u32)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2674 
2675         handle_sdio_cmd_read(pmadapter, rx_len, rx_blocks);
2676     }
2677 #elif defined(SD8801)
2678     /*
2679      * Below two statement look like they are present for the purpose
2680      * of unconditional initializing of mp_wr_bitmap which will be used
2681      * during packet xmit. proper mlan code does not do this most
2682      * probably because they have used wlan_get_wr_port_data() to
2683      * decide on the write port which we have not done. Check this out
2684      * later.
2685      */
2686     pmadapter->mp_wr_bitmap = ((t_u16)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2687     pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L];
2688 #endif
2689 
2690     pmadapter->mp_wr_bitmap =
2691 #if defined(SD8801)
2692         ((t_u16)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2693     pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L];
2694 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2695         (t_u32)pmadapter->mp_regs[WR_BITMAP_L];
2696     pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2697     pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1L]) << 16;
2698     pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1U]) << 24;
2699 #endif
2700 
2701     /*
2702      * DN_LD_HOST_INT_STATUS interrupt happens when the txmit sdio
2703      * ports are freed This is usually when we write to port most
2704      * significant port.
2705      */
2706     if ((sdio_ireg & DN_LD_HOST_INT_STATUS) != 0U)
2707     {
2708         pmadapter->mp_wr_bitmap =
2709 #if defined(SD8801)
2710             ((t_u16)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2711         pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L];
2712 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2713             (t_u32)pmadapter->mp_regs[WR_BITMAP_L];
2714         pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_U]) << 8;
2715         pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1L]) << 16;
2716         pmadapter->mp_wr_bitmap |= ((t_u32)pmadapter->mp_regs[WR_BITMAP_1U]) << 24;
2717 #endif
2718     }
2719 
2720     /*
2721      * As firmware will not generate download ready interrupt if the
2722      * port updated is command port only, cmd_sent should be done for
2723      * any SDIO interrupt.
2724      */
2725 #if defined(SD8801)
2726     if (pmadapter->cmd_sent == true)
2727     {
2728         /*
2729          * Check if firmware has attach buffer at command port and
2730          * update just that in wr_bit_map.
2731          */
2732         pmadapter->mp_wr_bitmap |= (t_u16)pmadapter->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
2733 
2734         if (pmadapter->mp_wr_bitmap & CTRL_PORT_MASK)
2735             pmadapter->cmd_sent = false;
2736     }
2737 #endif
2738 
2739     if ((sdio_ireg & UP_LD_HOST_INT_STATUS) != 0U)
2740     {
2741         /* This means there is data to be read */
2742         handle_sdio_packet_read(pmadapter);
2743     }
2744 
2745     ret = MLAN_STATUS_SUCCESS;
2746 
2747 done:
2748     return ret;
2749 }
2750 
2751 /**
2752  * Interrupt callback handler registered with the SDIO driver.
2753  */
handle_cdint(int error)2754 void handle_cdint(int error)
2755 {
2756     /* Wake up LWIP thread. */
2757     if (!error && g_txrx_flag)
2758     {
2759         g_txrx_flag = false;
2760 #if CONFIG_ZEPHYR
2761         (void)OSA_EventNotifyPost(wm_wifi.wifi_core_task_Handle);
2762 #else
2763         (void)OSA_EventSet((osa_event_handle_t)wm_wifi.wifi_event_Handle, WIFI_EVENT_SDIO);
2764 #endif
2765     }
2766 }
2767 
wifi_raw_packet_recv(t_u8 ** data,t_u32 * pkt_type)2768 int wifi_raw_packet_recv(t_u8 **data, t_u32 *pkt_type)
2769 {
2770     OSA_SR_ALLOC()
2771     osa_event_flags_t flagsToWait = WIFI_EVENT_SDIO;
2772     osa_event_flags_t pSetFlags;
2773 
2774     if (data == MNULL)
2775     {
2776         return -WM_FAIL;
2777     }
2778 
2779     OSA_ENTER_CRITICAL();
2780     /* Allow interrupt handler to deliver us a packet */
2781     g_txrx_flag = true;
2782 
2783     sdio_enable_interrupt();
2784 
2785     OSA_EXIT_CRITICAL()
2786 
2787     (void)OSA_EventWait((osa_event_handle_t)wm_wifi.wifi_event_Handle, flagsToWait, false, osaWaitForever_c, &pSetFlags);
2788 
2789     OSA_EventClear((osa_event_handle_t)wm_wifi.wifi_event_Handle, WIFI_EVENT_SDIO);
2790 
2791     if ((pSetFlags & WIFI_EVENT_SDIO) == 0U)
2792     {
2793         return -WM_FAIL;
2794     }
2795 
2796     /* Get the interrupt status */
2797     wlan_interrupt(mlan_adap);
2798 
2799     t_u8 sdio_ireg       = mlan_adap->sdio_ireg;
2800     mlan_adap->sdio_ireg = 0;
2801 
2802 #if defined(SD8801)
2803     if (!(sdio_ireg & UP_LD_HOST_INT_STATUS))
2804 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2805     if (!(sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS))
2806 #endif
2807     {
2808         return -WM_FAIL;
2809     }
2810 
2811     t_u32 datalen = 0;
2812 
2813     mlan_adap->mp_rd_bitmap =
2814 #if defined(SD8801)
2815         ((t_u16)mlan_adap->mp_regs[RD_BITMAP_U]) << 8;
2816     mlan_adap->mp_rd_bitmap |= (t_u16)mlan_adap->mp_regs[RD_BITMAP_L];
2817 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2818         (t_u32)mlan_adap->mp_regs[RD_BITMAP_L];
2819     mlan_adap->mp_rd_bitmap |= ((t_u32)mlan_adap->mp_regs[RD_BITMAP_U]) << 8;
2820     mlan_adap->mp_rd_bitmap |= ((t_u32)mlan_adap->mp_regs[RD_BITMAP_1L]) << 16;
2821     mlan_adap->mp_rd_bitmap |= ((t_u32)mlan_adap->mp_regs[RD_BITMAP_1U]) << 24;
2822 #endif
2823 
2824     t_u8 *packet = NULL;
2825 
2826 #if defined(SD8801)
2827     int ret;
2828     while (1)
2829     {
2830         ret = _handle_sdio_packet_read(mlan_adap, &packet, &datalen, pkt_type);
2831         if (ret == MLAN_STATUS_SUCCESS)
2832         {
2833             break;
2834         }
2835     }
2836 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2837 
2838     t_u8 cmd_rd_len_0 = CMD_RD_LEN_0;
2839     t_u8 cmd_rd_len_1 = CMD_RD_LEN_1;
2840     t_u32 rx_len;
2841     t_u32 rx_blocks;
2842 
2843     /* read the len of control packet */
2844     rx_len = ((t_u32)mlan_adap->mp_regs[cmd_rd_len_1]) << 8;
2845     rx_len |= (t_u32)mlan_adap->mp_regs[cmd_rd_len_0];
2846     PRINTM(MINFO, "RX: cmd port rx_len=%u\n", rx_len);
2847 
2848     rx_blocks = (rx_len + MLAN_SDIO_BLOCK_SIZE - 1U) / MLAN_SDIO_BLOCK_SIZE;
2849 
2850     rx_len = (t_u32)(rx_blocks * MLAN_SDIO_BLOCK_SIZE);
2851 
2852     (void)_handle_sdio_cmd_read(mlan_adap, &packet, &datalen, pkt_type, rx_len, rx_blocks);
2853 #endif
2854     *data = packet;
2855     return WM_SUCCESS;
2856 }
2857 
wifi_raw_packet_send(const t_u8 * packet,t_u32 length)2858 int wifi_raw_packet_send(const t_u8 *packet, t_u32 length)
2859 {
2860     if ((packet == MNULL) || !length)
2861     {
2862         return -WM_E_INVAL;
2863     }
2864 
2865     if (length > SDIO_OUTBUF_LEN)
2866     {
2867         wifi_io_e("Insufficient buffer");
2868         return -WM_FAIL;
2869     }
2870 
2871     t_u32 tx_blocks = 0, buflen = 0;
2872     calculate_sdio_write_params(length, &tx_blocks, &buflen);
2873 
2874     (void)memcpy((void *)outbuf, (const void *)packet, length);
2875 #if CONFIG_WIFI_IO_DUMP
2876     dump_hex(outbuf, length);
2877 #endif
2878     uint32_t resp;
2879 #if defined(SD8801)
2880     sdio_drv_write(mlan_adap->ioport, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
2881 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2882     (void)sdio_drv_write(mlan_adap->ioport | CMD_PORT_SLCT, 1, tx_blocks, buflen, (t_u8 *)outbuf, &resp);
2883 #endif
2884     return WM_SUCCESS;
2885 }
2886 
sd_wifi_preinit(void)2887 static mlan_status sd_wifi_preinit(void)
2888 {
2889     mlan_status mlanstatus = MLAN_STATUS_SUCCESS;
2890 
2891     /* initializes the driver struct */
2892     int sdiostatus = wlan_init_struct();
2893     if (sdiostatus != WM_SUCCESS)
2894     {
2895         wifi_io_e("Init failed. Cannot create init struct");
2896         return MLAN_STATUS_FAILURE;
2897     }
2898 
2899     /*
2900      * Register a callback with power manager of MC200/MW300
2901      * This callback will be called on entry /exit
2902      * of low power mode of MC200/MW300 based on first paramter
2903      * passed to the call.
2904      */
2905     //	pm_handle = pm_register_cb(ACTION_EXIT_PM3 | ACTION_ENTER_PM4,
2906     //		       sd_wifi_ps_cb, NULL);
2907 
2908     (void)mlan_subsys_init();
2909     seqnum   = 0;
2910     txportno = 0;
2911     return mlanstatus;
2912 }
2913 
sd_wifi_reset_ports()2914 void sd_wifi_reset_ports()
2915 {
2916 #if defined(SD8801)
2917     txportno = 1;
2918     mlan_adap->curr_rd_port = 1;
2919 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2920     txportno = 0;
2921     mlan_adap->curr_rd_port = 0;
2922 #endif
2923 }
2924 
sd_wifi_post_init(enum wlan_type type)2925 mlan_status sd_wifi_post_init(enum wlan_type type)
2926 {
2927     mlan_status mlanstatus = MLAN_STATUS_SUCCESS;
2928     uint32_t resp;
2929     bool invalid_wlantype = MFALSE;
2930 #if defined(SD8801)
2931     sdio_drv_creg_write(HOST_INT_MASK_REG, 1, 0x3, &resp);
2932 #elif defined(SD8978) || defined(SD8987) || defined(SD8997) || defined(SD9097) || defined(SD9098) || defined(SD9177)
2933     (void)sdio_drv_creg_write(HOST_INT_MASK_REG, 1, HIM_ENABLE, &resp);
2934 #endif
2935 
2936     /* If we're running a Manufacturing image, start the tasks.
2937        If not, initialize and setup the firmware */
2938     switch (type)
2939     {
2940         case WLAN_TYPE_NORMAL:
2941             fw_init_cfg = 1;
2942             wlan_fw_init_cfg();
2943             fw_init_cfg = 0;
2944             break;
2945         case WLAN_TYPE_WIFI_CALIB:
2946             g_txrx_flag = true;
2947             break;
2948         case WLAN_TYPE_FCC_CERTIFICATION:
2949             g_txrx_flag = true;
2950             break;
2951         default:
2952             wifi_io_e("Enter a valid input to sd_wifi_init");
2953             invalid_wlantype = MTRUE;
2954             break;
2955     }
2956 
2957     if (invalid_wlantype == MTRUE)
2958     {
2959         return MLAN_STATUS_FAILURE;
2960     }
2961 
2962     sd_wifi_reset_ports();
2963 
2964     return mlanstatus;
2965 }
2966 
2967 static void *intf;
2968 
sd_wifi_init(enum wlan_type type,const uint8_t * fw_start_addr,const size_t size)2969 mlan_status sd_wifi_init(enum wlan_type type, const uint8_t *fw_start_addr, const size_t size)
2970 {
2971     mlan_status ret = MLAN_STATUS_SUCCESS;
2972 
2973     ret = sd_wifi_preinit();
2974 
2975     if (ret == MLAN_STATUS_SUCCESS)
2976     {
2977         intf = (void *)sdio_init_interface(NULL);
2978 
2979         if (intf != MNULL)
2980         {
2981             mlan_adap->fw_start_addr = fw_start_addr;
2982 
2983             ret = (mlan_status)firmware_download(fw_start_addr, size, intf, 0);
2984         } else {
2985             ret = MLAN_STATUS_FAILURE;
2986 	}
2987     }
2988     return ret;
2989 }
2990 
2991 #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)2992 mlan_status sd_wifi_reinit(enum wlan_type type, const uint8_t *fw_start_addr, const size_t size, uint8_t fw_reload)
2993 {
2994     mlan_status ret = MLAN_STATUS_SUCCESS;
2995 
2996     if (fw_reload == FW_RELOAD_NO_EMULATION)
2997     {
2998         OSA_SR_ALLOC();
2999         OSA_ENTER_CRITICAL();
3000 
3001         /* Allow interrupt handler to deliver us a packet */
3002         g_txrx_flag = false;
3003 
3004         sdio_disable_interrupt();
3005 
3006         OSA_EXIT_CRITICAL();
3007 
3008         sdio_ioport_init();
3009     }
3010 
3011     ret = (mlan_status)firmware_download(fw_start_addr, size, intf, fw_reload);
3012 
3013     if (ret != MLAN_STATUS_FAILURE)
3014     {
3015         if (fw_reload == FW_RELOAD_NO_EMULATION)
3016         {
3017             OSA_SR_ALLOC();
3018             OSA_ENTER_CRITICAL();
3019             /* Allow interrupt handler to deliver us a packet */
3020             g_txrx_flag = true;
3021 
3022             sdio_enable_interrupt();
3023 
3024             OSA_EXIT_CRITICAL();
3025         }
3026     }
3027 
3028     return ret;
3029 }
3030 #endif
3031 
3032 #if CONFIG_BT_SUPPORT
read_sdio_function_recvd()3033 uint8_t read_sdio_function_recvd()
3034 {
3035     uint32_t resp = 0;
3036     uint8_t val;
3037     sdio_drv_creg_read(0x5, 0x0, &resp);
3038     val = resp & 0xf;
3039     return val;
3040 }
3041 #endif
3042 
sd_wifi_deinit(void)3043 void sd_wifi_deinit(void)
3044 {
3045 #ifdef WLAN_LOW_POWER_ENABLE
3046     low_power_mode = false;
3047 #endif
3048     cal_data_valid = false;
3049     mac_addr_valid = false;
3050     //	pm_deregister_cb(pm_handle);
3051 
3052     (void)wlan_cmd_shutdown();
3053     sdio_drv_deinit();
3054     (void)mlan_subsys_deinit();
3055     (void)wlan_deinit_struct();
3056 }
3057 
3058 #if CONFIG_FW_VDLL
wifi_get_vdllcommand_buffer(void)3059 HostCmd_DS_COMMAND *wifi_get_vdllcommand_buffer(void)
3060 {
3061     /* First 4 bytes reserved for SDIO pkt header */
3062     return (HostCmd_DS_COMMAND *)(void *)(vdll_cmd_buf + INTF_HEADER_LEN);
3063 }
3064 #endif
3065 
wifi_get_command_buffer(void)3066 HostCmd_DS_COMMAND *wifi_get_command_buffer(void)
3067 {
3068     /* First 4 bytes reserved for SDIO pkt header */
3069     return (HostCmd_DS_COMMAND *)(void *)(ctrl_cmd_buf + INTF_HEADER_LEN);
3070 }
3071 
3072 /**
3073  * Function to set mlan ioport.
3074  */
set_ioport_inmlan(t_u32 port)3075 void set_ioport_inmlan(t_u32 port)
3076 {
3077     mlan_adap->ioport = port;
3078 }
3079 
3080 #if CONFIG_HOST_SLEEP
wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)3081 void wifi_print_wakeup_reason(t_u16 hs_wakeup_reason)
3082 {
3083     if (hs_wakeup_reason == 0)
3084     {
3085         PRINTF("Woken up by unknown reason\r\n");
3086     }
3087     else if (hs_wakeup_reason == 1)
3088     {
3089         PRINTF("Woken up by Broadcast data matched\r\n");
3090     }
3091     else if (hs_wakeup_reason == 2)
3092     {
3093         PRINTF("Woken up by Multicast data matched\r\n");
3094     }
3095     else if (hs_wakeup_reason == 3)
3096     {
3097         PRINTF("Woken up by Unicast data matched\r\n");
3098     }
3099     else if (hs_wakeup_reason == 4)
3100     {
3101         PRINTF("Woken up by Maskable event matched\r\n");
3102     }
3103     else if (hs_wakeup_reason == 5)
3104     {
3105         PRINTF("Woken up by Non-maskable event matched\r\n");
3106     }
3107     else if (hs_wakeup_reason == 6)
3108     {
3109         PRINTF("Woken up by Non-maskable condition matched (EAPoL rekey)\r\n");
3110     }
3111     else if (hs_wakeup_reason == 7)
3112     {
3113         PRINTF("Woken up by Magic pattern matched\r\n");
3114     }
3115     else if (hs_wakeup_reason == 8)
3116     {
3117         PRINTF("Woken up by control frames matched \r\n");
3118     }
3119     else if (hs_wakeup_reason == 9)
3120     {
3121         PRINTF("Woken up by management frame matched \r\n");
3122     }
3123     else if (hs_wakeup_reason == 10)
3124     {
3125         PRINTF("Woken up by GTK rekey failure\r\n");
3126     }
3127     else if (hs_wakeup_reason == 11)
3128     {
3129         PRINTF("Woken up by management frame filter extension matched\r\n");
3130     }
3131     else
3132     {
3133         PRINTF("Woken up by reserved reason\r\n");
3134     }
3135 }
3136 
wifi_clear_wakeup_reason(void)3137 void wifi_clear_wakeup_reason(void)
3138 {
3139     if (mlan_adap != NULL)
3140     {
3141         memset(&mlan_adap->wlan_wakeup, 0x0, sizeof(wlan_wakeup_reason));
3142     }
3143 }
3144 #endif
3145