MCUXpresso_MIMXRT1052xxxxB/middleware/wifi_nxp/wifidriver/mlan_sta_rx.c
Yilin Sun 75f32185d2
Updated to v2.14.0
Signed-off-by: Yilin Sun <imi415@imi.moe>
2023-11-30 20:55:00 +08:00

258 lines
7.6 KiB
C

/** @file mlan_sta_rx.c
*
* @brief This file provides handling of RX in MLA module.
*
* Copyright 2008-2022 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/********************************************************
Change log:
10/27/2008: initial version
********************************************************/
#include <mlan_api.h>
/* Additional WMSDK header files */
#include <wmerrno.h>
#include <wm_os.h>
/* Always keep this include at the end of all include files */
#include <mlan_remap_mem_operations.h>
/********************************************************
Local Variables
********************************************************/
/** Ethernet II header */
typedef struct
{
/** Ethernet II header destination address */
t_u8 dest_addr[MLAN_MAC_ADDR_LENGTH];
/** Ethernet II header source address */
t_u8 src_addr[MLAN_MAC_ADDR_LENGTH];
/** Ethernet II header length */
t_u16 ethertype;
} EthII_Hdr_t;
/** IPv4 ARP request header */
typedef MLAN_PACK_START struct
{
/** Hardware type */
t_u16 Htype;
/** Protocol type */
t_u16 Ptype;
/** Hardware address length */
t_u8 addr_len;
/** Protocol address length */
t_u8 proto_len;
/** Operation code */
t_u16 op_code;
/** Source mac address */
t_u8 src_mac[MLAN_MAC_ADDR_LENGTH];
/** Sender IP address */
t_u8 src_ip[4];
/** Destination mac address */
t_u8 dst_mac[MLAN_MAC_ADDR_LENGTH];
/** Destination IP address */
t_u8 dst_ip[4];
} MLAN_PACK_END IPv4_ARP_t;
/** IPv6 Nadv packet header */
typedef MLAN_PACK_START struct
{
/** IP protocol version */
t_u8 version;
/** flow label */
t_u8 flow_lab[3];
/** Payload length */
t_u16 payload_len;
/** Next header type */
t_u8 next_hdr;
/** Hot limit */
t_u8 hop_limit;
/** Source address */
t_u8 src_addr[16];
/** Destination address */
t_u8 dst_addr[16];
/** ICMP type */
t_u8 icmp_type;
/** IPv6 Code */
t_u8 ipv6_code;
/** IPv6 Checksum */
t_u16 ipv6_checksum;
/** Flags */
t_u32 flags;
/** Target address */
t_u8 taget_addr[16];
/** Reserved */
t_u8 rev[8];
} MLAN_PACK_END IPv6_Nadv_t;
/********************************************************
Global Variables
********************************************************/
/********************************************************
Local Functions
********************************************************/
/********************************************************
Global functions
********************************************************/
/**
* @brief This function processes received packet and forwards it
* to kernel/upper layer
*
* @param pmadapter A pointer to mlan_adapter
* @param pmbuf A pointer to mlan_buffer which includes the received packet
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
{
mlan_status ret = MLAN_STATUS_SUCCESS;
pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
/* RxPacketHdr_t *prx_pkt; */
RxPD *prx_pd;
ENTER();
prx_pd = (RxPD *)(void *)(pmbuf->pbuf + pmbuf->data_offset);
/* Note: Important. We do not have actual data @ prx_pd->rx_pkt_offset */
/* prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset); */
/* prx_pkt = (RxPacketHdr_t *)pmbuf->pdesc; */
/** Small debug type */
#define DBG_TYPE_SMALL 2
/** Size of debugging structure */
#define SIZE_OF_DBG_STRUCT 4
/*
This additional processing does not seem to be required by us for
the moment. Let skip it for now. They seem to be doing some kind of
ethernet header processing.
*/
priv->rxpd_rate = prx_pd->rx_rate;
#ifdef SD8801
priv->rxpd_htinfo = prx_pd->ht_info;
#else
priv->rxpd_rate_info = prx_pd->rate_info;
#endif
ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf);
if (ret == MLAN_STATUS_FAILURE)
{
pmbuf->status_code = (t_u32)MLAN_ERROR_PKT_INVALID;
PRINTM(MERROR, "STA Rx Error: moal_recv_packet returned error\n");
}
/* done: */
if (ret != MLAN_STATUS_PENDING)
{
wlan_free_mlan_buffer(pmadapter, pmbuf);
}
LEAVE();
return ret;
}
/**
* @brief This function processes the received buffer
*
* @param adapter A pointer to mlan_adapter
* @param pmbuf A pointer to the received buffer
*
* @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
*/
mlan_status wlan_ops_sta_process_rx_packet(IN t_void *adapter, IN pmlan_buffer pmbuf)
{
pmlan_adapter pmadapter = (pmlan_adapter)adapter;
mlan_status ret = MLAN_STATUS_SUCCESS;
RxPD *prx_pd;
RxPacketHdr_t *prx_pkt;
pmlan_private priv = pmadapter->priv[pmbuf->bss_index];
t_u8 ta[MLAN_MAC_ADDR_LENGTH] = {0};
t_u16 rx_pkt_type = 0;
ENTER();
prx_pd = (RxPD *)(void *)(pmbuf->pbuf + pmbuf->data_offset);
/* Endian conversion */
endian_convert_RxPD(prx_pd);
rx_pkt_type = prx_pd->rx_pkt_type;
/* Note: We do not have data @ some offset of pbuf. pbuf only has RxPD */
/* prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset); */
prx_pkt = (RxPacketHdr_t *)pmbuf->pdesc;
/* PRINTM(MMSG, "%p + %d: O: %d PL: %d DL: %d\n\r", */
/* pmbuf->pbuf, pmbuf->data_offset, */
/* prx_pd->rx_pkt_offset, prx_pd->rx_pkt_length, pmbuf->data_len); */
if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) > (t_u16)pmbuf->data_len)
{
PRINTM(MERROR,
"Wrong rx packet: len=%d,rx_pkt_offset=%d,"
" rx_pkt_length=%d\n",
pmbuf->data_len, prx_pd->rx_pkt_offset, prx_pd->rx_pkt_length);
pmbuf->status_code = (t_u32)MLAN_ERROR_PKT_SIZE_INVALID;
ret = MLAN_STATUS_FAILURE;
wlan_free_mlan_buffer(pmadapter, pmbuf);
goto done;
}
pmbuf->data_len = prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length;
if (pmadapter->priv[pmbuf->bss_index]->mgmt_frame_passthru_mask && prx_pd->rx_pkt_type == PKT_TYPE_MGMT_FRAME)
{
/* Check if this is mgmt packet and needs to forwarded to app as an
event */
/* fixme */
PRINTM(MMSG, "Is a management packet expected here?\n\r");
(void)os_enter_critical_section();
while (true)
{
}
}
#ifdef DUMP_PACKET_MAC
dump_mac_addr("Own: ", priv->curr_addr);
dump_mac_addr("Dest: ", prx_pkt->eth803_hdr.dest_addr);
#endif /* DUMP_PACKET_MAC */
/*
* If the packet is not an unicast packet then send the packet
* directly to os. Don't pass thru rx reordering
*/
if (!IS_11N_ENABLED(priv) ||
__memcmp(priv->adapter, priv->curr_addr, prx_pkt->eth803_hdr.dest_addr, MLAN_MAC_ADDR_LENGTH))
{
(void)wlan_process_rx_packet(pmadapter, pmbuf);
goto done;
}
if (queuing_ra_based(priv) == MTRUE)
{
(void)__memcpy(pmadapter, ta, prx_pkt->eth803_hdr.src_addr, MLAN_MAC_ADDR_LENGTH);
}
else
{
if ((rx_pkt_type != PKT_TYPE_BAR) && (prx_pd->priority < MAX_NUM_TID))
{
priv->rx_seq[prx_pd->priority] = prx_pd->seq_num;
}
(void)__memcpy(pmadapter, ta, priv->curr_bss_params.bss_descriptor.mac_address, MLAN_MAC_ADDR_LENGTH);
}
/* Reorder and send to OS */
if ((ret = mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num, prx_pd->priority, ta, (t_u8)prx_pd->rx_pkt_type,
(void *)pmbuf)) ||
(rx_pkt_type == PKT_TYPE_BAR))
{
wlan_free_mlan_buffer(pmadapter, pmbuf);
}
done:
LEAVE();
return (ret);
}