1 /** @file mlan_txrx.c
2  *
3  *  @brief  This file provides the handling of TX/RX in MLAN
4  *
5  *  Copyright 2008-2024 NXP
6  *
7  *  SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 /*************************************************************
12 Change Log:
13     05/11/2009: initial version
14 ************************************************************/
15 #include <mlan_api.h>
16 
17 /* Additional WMSDK header files */
18 #include <wmerrno.h>
19 #include <osa.h>
20 #if CONFIG_WIFI_PKT_FWD
21 #include <wm_net.h>
22 #if defined(RW610)
23 #include "wifi-imu.h"
24 #else
25 #include "wifi-sdio.h"
26 #endif
27 #endif
28 /* Always keep this include at the end of all include files */
29 #include <mlan_remap_mem_operations.h>
30 /********************************************************
31                 Local Variables
32 ********************************************************/
33 
34 /********************************************************
35                 Global Variables
36 ********************************************************/
37 
38 /********************************************************
39                 Local Functions
40 ********************************************************/
41 
42 /********************************************************
43                 Global Functions
44 ********************************************************/
45 /**
46  *   @brief This function processes the received buffer
47  *
48  *   @param pmadapter A pointer to mlan_adapter
49  *   @param pmbuf     A pointer to the received buffer
50  *
51  *   @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
52  */
wlan_handle_rx_packet(pmlan_adapter pmadapter,pmlan_buffer pmbuf)53 mlan_status wlan_handle_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
54 {
55     mlan_status ret    = MLAN_STATUS_SUCCESS;
56     pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
57     RxPD *prx_pd;
58 #ifdef DEBUG_LEVEL1
59     t_u32 sec, usec;
60 #endif
61 
62     ENTER();
63 
64     prx_pd = (RxPD *)(void *)(pmbuf->pbuf + pmbuf->data_offset);
65     /* Get the BSS number from RxPD, get corresponding priv */
66     priv = wlan_get_priv_by_id(pmadapter, prx_pd->bss_num & BSS_NUM_MASK, prx_pd->bss_type);
67     if (priv == MNULL)
68     {
69         priv = wlan_get_priv(pmadapter, MLAN_BSS_ROLE_ANY);
70     }
71     pmbuf->bss_index = priv->bss_index;
72     PRINTM_GET_SYS_TIME(MDATA, &sec, &usec);
73     PRINTM_NETINTF(MDATA, priv);
74     /* PRINTM(MDATA, "%lu.%06lu : Data <= FW\n", sec, usec); */
75     ret = priv->ops.process_rx_packet(pmadapter, pmbuf);
76 
77     LEAVE();
78     return ret;
79 }
80 
81 #if CONFIG_WIFI_PKT_FWD
82 /**
83  *  @brief This function processes received packet and forwards it
84  *  		to kernel/upper layer or send back to firmware
85  *
86  *  @param priv A pointer to mlan_private
87  *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
88  *
89  *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
90  */
wlan_process_uap_rx_packet(mlan_private * priv,pmlan_buffer pmbuf)91 mlan_status wlan_process_uap_rx_packet(mlan_private *priv, pmlan_buffer pmbuf)
92 {
93     mlan_status ret = MLAN_STATUS_SUCCESS;
94     pmlan_adapter pmadapter = priv->adapter;
95     RxPacketHdr_t *prx_pkt = (RxPacketHdr_t *)pmbuf->pdesc;
96     RxPD *prx_pd = (RxPD *)(void *)(pmbuf->pbuf + pmbuf->data_offset);
97 
98     /* Don't do packet forwarding in disconnected state */
99     if (priv->media_connected == MFALSE)
100         goto upload;
101 
102     if (prx_pkt->eth803_hdr.dest_addr[0] & 0x01)
103     {
104         /* Allocate new buffer here, to avoid the conflict between
105          * driver handling and TCP/IP stack handling */
106         void *pkt = (void *)gen_tx_pkt_from_data(priv->bss_type,
107                 net_stack_buffer_get_payload(pmbuf->lwip_pbuf), prx_pd->rx_pkt_length);
108         if (pkt == NULL)
109         {
110             /* Allocate TX buffer failed, directly upload the packet to TCP/IP stack */
111             goto upload;
112         }
113 
114         net_wifi_packet_send(WLAN_BSS_TYPE_UAP, pkt);
115         net_stack_buffer_free(pkt);
116     }
117     else
118     {
119         if (wlan_11n_get_txbastream_tbl(priv, prx_pkt->eth803_hdr.dest_addr))
120         {
121             int iret = net_wifi_packet_send(WLAN_BSS_TYPE_UAP, pmbuf->lwip_pbuf);
122             if (iret != WM_SUCCESS)
123             {
124                 ret = MLAN_STATUS_FAILURE;
125             }
126             net_stack_buffer_free(pmbuf->lwip_pbuf);
127 #if !(CONFIG_TX_RX_ZERO_COPY) && !(FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER)
128 #if !CONFIG_MEM_POOLS
129             /* Free RxPD */
130             OSA_MemoryFree(pmbuf->pbuf);
131             OSA_MemoryFree(pmbuf);
132 #else
133             OSA_MemoryPoolFree(buf_128_MemoryPool, pmbuf->pbuf);
134             OSA_MemoryPoolFree(buf_128_MemoryPool, pmbuf);
135 #endif
136 #endif
137             return ret;
138         }
139     }
140 
141 upload:
142     ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf);
143     if (ret == MLAN_STATUS_FAILURE)
144     {
145         pmbuf->status_code = (t_u32)MLAN_ERROR_PKT_INVALID;
146         PRINTM(MERROR, "uAP Rx Error: moal_recv_packet returned error\n");
147     }
148 
149     if (ret != MLAN_STATUS_PENDING)
150     {
151         wlan_free_mlan_buffer(pmadapter, pmbuf);
152     }
153 
154     LEAVE();
155     return ret;
156 }
157 #endif
158