qcacmn: Enable support for receive defragmentation

Enable support for receive defragmentation on Lithium.

Change-Id: I6c1213db29d3b6e0a11506d6945d9ea05ece2c73
CRs-Fixed: 1109359
This commit is contained in:
Ravi Joshi
2016-11-09 17:09:47 -08:00
committed by snandini
parent e7148bdd67
commit 36f68ad7cb
10 changed files with 2026 additions and 69 deletions

View File

@@ -80,6 +80,114 @@ struct dp_rx_desc {
(((_cookie) & RX_DESC_COOKIE_INDEX_MASK) >> \
RX_DESC_COOKIE_INDEX_SHIFT)
/*
*dp_rx_xor_block() - xor block of data
*@b: destination data block
*@a: source data block
*@len: length of the data to process
*
*Returns: None
*/
static inline void dp_rx_xor_block(uint8_t *b, const uint8_t *a, qdf_size_t len)
{
qdf_size_t i;
for (i = 0; i < len; i++)
b[i] ^= a[i];
}
/*
*dp_rx_rotl() - rotate the bits left
*@val: unsigned integer input value
*@bits: number of bits
*
*Returns: Integer with left rotated by number of 'bits'
*/
static inline uint32_t dp_rx_rotl(uint32_t val, int bits)
{
return (val << bits) | (val >> (32 - bits));
}
/*
*dp_rx_rotr() - rotate the bits right
*@val: unsigned integer input value
*@bits: number of bits
*
*Returns: Integer with right rotated by number of 'bits'
*/
static inline uint32_t dp_rx_rotr(uint32_t val, int bits)
{
return (val >> bits) | (val << (32 - bits));
}
/*
*dp_rx_xswap() - swap the bits left
*@val: unsigned integer input value
*
*Returns: Integer with bits swapped
*/
static inline uint32_t dp_rx_xswap(uint32_t val)
{
return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
}
/*
*dp_rx_get_le32_split() - get little endian 32 bits split
*@b0: byte 0
*@b1: byte 1
*@b2: byte 2
*@b3: byte 3
*
*Returns: Integer with split little endian 32 bits
*/
static inline uint32_t dp_rx_get_le32_split(uint8_t b0, uint8_t b1, uint8_t b2,
uint8_t b3)
{
return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
}
/*
*dp_rx_get_le32() - get little endian 32 bits
*@b0: byte 0
*@b1: byte 1
*@b2: byte 2
*@b3: byte 3
*
*Returns: Integer with little endian 32 bits
*/
static inline uint32_t dp_rx_get_le32(const uint8_t *p)
{
return dp_rx_get_le32_split(p[0], p[1], p[2], p[3]);
}
/*
* dp_rx_put_le32() - put little endian 32 bits
* @p: destination char array
* @v: source 32-bit integer
*
* Returns: None
*/
static inline void dp_rx_put_le32(uint8_t *p, uint32_t v)
{
p[0] = (v) & 0xff;
p[1] = (v >> 8) & 0xff;
p[2] = (v >> 16) & 0xff;
p[3] = (v >> 24) & 0xff;
}
/* Extract michal mic block of data */
#define dp_rx_michael_block(l, r) \
do { \
r ^= dp_rx_rotl(l, 17); \
l += r; \
r ^= dp_rx_xswap(l); \
l += r; \
r ^= dp_rx_rotl(l, 3); \
l += r; \
r ^= dp_rx_rotr(l, 2); \
l += r; \
} while (0)
/**
* struct dp_rx_desc_list_elem_t
*
@@ -340,6 +448,7 @@ static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf,
return QDF_STATUS_E_FAILURE;
}
#endif
/**
* dp_rx_cookie_2_link_desc_va() - Converts cookie to a virtual address of
* the MSDU Link Descriptor
@@ -392,10 +501,33 @@ void *dp_rx_cookie_2_mon_link_desc_va(struct dp_pdev *pdev,
link_desc_va = pdev->link_desc_banks[buf_info->sw_cookie].base_vaddr +
(buf_info->paddr -
pdev->link_desc_banks[buf_info->sw_cookie].base_paddr);
return link_desc_va;
}
/**
* dp_rx_defrag_concat() - Concatenate the fragments
*
* @dst: destination pointer to the buffer
* @src: source pointer from where the fragment payload is to be copied
*
* Return: QDF_STATUS
*/
static inline QDF_STATUS dp_rx_defrag_concat(qdf_nbuf_t dst, qdf_nbuf_t src)
{
/*
* Inside qdf_nbuf_cat, if it is necessary to reallocate dst
* to provide space for src, the headroom portion is copied from
* the original dst buffer to the larger new dst buffer.
* (This is needed, because the headroom of the dst buffer
* contains the rx desc.)
*/
if (qdf_nbuf_cat(dst, src))
return QDF_STATUS_E_DEFRAG_ERROR;
return QDF_STATUS_SUCCESS;
}
/*
* dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs
* called during dp rx initialization

File diff suppressed because it is too large Load Diff

View File

@@ -16,9 +16,116 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef _DP_RX_DEFRAG_H
#ifndef _DP_RX_DEFRAG_H
#define _DP_RX_DEFRAG_H
#include "hal_rx.h"
#ifdef CONFIG_MCL
#include <cds_ieee80211_common.h>
#else
#include <ieee80211.h>
#endif
#define DEFRAG_IEEE80211_ADDR_LEN 6
#define DEFRAG_IEEE80211_KEY_LEN 8
#define DEFRAG_IEEE80211_FCS_LEN 4
#define DP_RX_DEFRAG_IEEE80211_ADDR_COPY(dst, src) \
qdf_mem_copy(dst, src, IEEE80211_ADDR_LEN)
#define DP_RX_DEFRAG_IEEE80211_QOS_HAS_SEQ(wh) \
(((wh) & \
(IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) == \
(IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
/**
* struct dp_rx_defrag_cipher: structure to indicate cipher header
* @ic_name: Name
* @ic_header: header length
* @ic_trailer: trail length
* @ic_miclen: MIC length
*/
struct dp_rx_defrag_cipher {
const char *ic_name;
uint16_t ic_header;
uint8_t ic_trailer;
uint8_t ic_miclen;
};
uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc,
struct hal_rx_mpdu_desc_info *mpdu_desc_info,
union dp_rx_desc_list_elem_t **head,
union dp_rx_desc_list_elem_t **tail,
uint32_t quota);
/*
* dp_rx_frag_get_mac_hdr() - Return pointer to the mac hdr
* @rx_desc_info: Pointer to the pkt_tlvs in the
* nbuf (pkt_tlvs->mac_hdr->data)
*
* It is inefficient to peek into the packet for received
* frames but these APIs are required to get to some of
* 802.11 fields that hardware does not populate in the
* rx meta data.
*
* Returns: pointer to ieee80211_frame
*/
static inline
struct ieee80211_frame *dp_rx_frag_get_mac_hdr(uint8_t *rx_desc_info)
{
int rx_desc_len = hal_rx_get_desc_len();
return (struct ieee80211_frame *)(rx_desc_info + rx_desc_len);
}
/*
* dp_rx_frag_get_mpdu_seq_number() - Get mpdu sequence number
* @rx_desc_info: Pointer to the pkt_tlvs in the
* nbuf (pkt_tlvs->mac_hdr->data)
*
* Returns: uint16_t, rx sequence number
*/
static inline
uint16_t dp_rx_frag_get_mpdu_seq_number(uint8_t *rx_desc_info)
{
struct ieee80211_frame *mac_hdr;
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) >>
IEEE80211_SEQ_SEQ_SHIFT;
}
/*
* dp_rx_frag_get_mpdu_frag_number() - Get mpdu fragment number
* @rx_desc_info: Pointer to the pkt_tlvs in the
* nbuf (pkt_tlvs->mac_hdr->data)
*
* Returns: uint8_t, receive fragment number
*/
static inline
uint8_t dp_rx_frag_get_mpdu_frag_number(uint8_t *rx_desc_info)
{
struct ieee80211_frame *mac_hdr;
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) &
IEEE80211_SEQ_FRAG_MASK;
}
/*
* dp_rx_frag_get_more_frag_bit() - Get more fragment bit
* @rx_desc_info: Pointer to the pkt_tlvs in the
* nbuf (pkt_tlvs->mac_hdr->data)
*
* Returns: uint8_t, get more fragment bit
*/
static inline
uint8_t dp_rx_frag_get_more_frag_bit(uint8_t *rx_desc_info)
{
struct ieee80211_frame *mac_hdr;
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
return mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
}
#endif /* _DP_RX_DEFRAG_H */

View File

@@ -28,38 +28,8 @@
#else
#include <ieee80211.h>
#endif
/**
* dp_rx_frag_handle() - Handles fragmented Rx frames
*
* @soc: core txrx main context
* @ring_desc: opaque pointer to the REO error ring descriptor
* @mpdu_desc_info: MPDU descriptor information from ring descriptor
* @head: head of the local descriptor free-list
* @tail: tail of the local descriptor free-list
* @quota: No. of units (packets) that can be serviced in one shot.
*
* This function implements RX 802.11 fragmentation handling
* The handling is mostly same as legacy fragmentation handling.
* If required, this function can re-inject the frames back to
* REO ring (with proper setting to by-pass fragmentation check
* but use duplicate detection / re-ordering and routing these frames
* to a different core.
*
* Return: uint32_t: No. of elements processed
*/
static uint32_t
dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc,
struct hal_rx_mpdu_desc_info *mpdu_desc_info,
union dp_rx_desc_list_elem_t **head,
union dp_rx_desc_list_elem_t **tail,
uint32_t quota)
{
uint32_t rx_bufs_used = 0;
return rx_bufs_used;
}
#include "dp_rx_defrag.h"
#include <enet.h> /* LLC_SNAP_HDR_LEN */
/**
* dp_rx_msdus_drop() - Drops all MSDU's per MPDU
@@ -75,14 +45,12 @@ dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc,
*
* Return: uint32_t: No. of elements processed
*/
static uint32_t
dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc,
static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc,
struct hal_rx_mpdu_desc_info *mpdu_desc_info,
union dp_rx_desc_list_elem_t **head,
union dp_rx_desc_list_elem_t **tail,
uint32_t quota)
{
uint8_t num_msdus;
uint32_t rx_bufs_used = 0;
void *link_desc_va;
struct hal_buf_info buf_info;
@@ -93,11 +61,9 @@ dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc,
link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &buf_info);
qdf_assert(rx_msdu_link_desc);
/* No UNMAP required -- this is "malloc_consistent" memory */
hal_rx_msdu_list_get(link_desc_va, &msdu_list, &num_msdus);
hal_rx_msdu_list_get(link_desc_va, &msdu_list,
mpdu_desc_info->msdu_count);
for (i = 0; (i < HAL_RX_NUM_MSDU_DESC) && quota--; i++) {
struct dp_rx_desc *rx_desc =
@@ -657,7 +623,6 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
if (qdf_unlikely(rbm != HAL_RX_BUF_RBM_SW3_BM)) {
/* TODO */
/* Call appropriate handler */
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
FL("Invalid RBM %d"), rbm);
continue;

View File

@@ -138,7 +138,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
num_msdus = msdu_cnt;
hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, &num_msdus);
hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, num_msdus);
msdu_cnt -= num_msdus;

View File

@@ -30,6 +30,12 @@
#include <htt_common.h>
#include <cdp_txrx_cmn.h>
#ifdef CONFIG_MCL
#include <cds_ieee80211_common.h>
#else
#include <ieee80211.h>
#endif
#ifndef CONFIG_WIN
#include <wdi_event_api.h> /* WDI subscriber event list */
#endif
@@ -40,6 +46,7 @@
#include "hal_rx.h"
#include <hal_api.h>
#include <hal_api_mon.h>
#include "hal_rx.h"
#define MAX_TCL_RING 3
#define MAX_RXDMA_ERRORS 32
@@ -305,6 +312,18 @@ struct dp_rx_tid {
/* only used for defrag right now */
TAILQ_ENTRY(dp_rx_tid) defrag_waitlist_elem;
/* MSDU link pointers used for reinjection */
struct hal_rx_msdu_link_ptr_info
transcap_msdu_link_ptr[HAL_RX_MAX_SAVED_RING_DESC];
struct hal_rx_mpdu_desc_info transcap_rx_mpdu_desc_info;
uint8_t curr_ring_desc_idx;
/* Sequence and fragments that are being processed currently */
uint32_t curr_seq_num;
uint32_t curr_frag_num;
uint32_t defrag_timeout_ms;
uint16_t dialogtoken;
uint16_t statuscode;
@@ -903,9 +922,7 @@ struct dp_peer {
struct {
enum htt_sec_type sec_type;
#ifdef notyet /* TODO: See if this is required for defrag support */
u_int32_t michael_key[2]; /* relevant for TKIP */
#endif
} security[2]; /* 0 -> multicast, 1 -> unicast */
/*

View File

@@ -357,7 +357,6 @@ static inline void hal_rx_mpdu_desc_info_get(void *desc_addr,
HAL_RX_MPDU_DESC_PEER_META_DATA_GET(mpdu_info);
}
/*
* @ hal_rx_msdu_desc_info_get: Gets the flags related to MSDU desciptor.
* @ Specifically flags needed are:
@@ -1540,7 +1539,9 @@ hal_rx_mpdu_end_mic_err_get(uint8_t *buf)
RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET))
#define HAL_RX_NUM_MSDU_DESC 6
#define HAL_RX_MAX_SAVED_RING_DESC 16
/* TODO: rework the structure */
struct hal_rx_msdu_list {
struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC];
uint32_t sw_cookie[HAL_RX_NUM_MSDU_DESC];
@@ -1552,24 +1553,28 @@ struct hal_buf_info {
};
/**
* hal_rx_msdu_link_desc_get: API to get the MSDU information
* hal_rx_msdu_link_desc_get(): API to get the MSDU information
* from the MSDU link descriptor
*
* @ msdu_link_desc: Opaque pointer used by HAL to get to the
* @msdu_link_desc: Opaque pointer used by HAL to get to the
* MSDU link descriptor (struct rx_msdu_link)
* @ msdu_list: Return the list of MSDUs contained in this link descriptor
*
* @msdu_list: Return the list of MSDUs contained in this link descriptor
*
* @num_msdus: Number of MSDUs in the MPDU
*
* Return: void
*/
static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
struct hal_rx_msdu_list *msdu_list, uint8_t *num_msdus)
struct hal_rx_msdu_list *msdu_list, uint8_t num_msdus)
{
struct rx_msdu_details *msdu_details;
struct rx_msdu_desc_info *msdu_desc_info;
struct rx_msdu_link *msdu_link = (struct rx_msdu_link *)msdu_link_desc;
int i;
if (*num_msdus > HAL_RX_NUM_MSDU_DESC)
*num_msdus = HAL_RX_NUM_MSDU_DESC;
if (num_msdus > HAL_RX_NUM_MSDU_DESC)
num_msdus = HAL_RX_NUM_MSDU_DESC;
msdu_details = HAL_RX_LINK_DESC_MSDU0_PTR(msdu_link);
@@ -1577,8 +1582,7 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
"[%s][%d] msdu_link=%p msdu_details=%p\n",
__func__, __LINE__, msdu_link, msdu_details);
for (i = 0; i < *num_msdus; i++) {
for (i = 0; i < num_msdus; i++) {
msdu_desc_info = HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[i]);
msdu_list->msdu_info[i].msdu_flags =
HAL_RX_MSDU_FLAGS_GET(msdu_desc_info);
@@ -1592,7 +1596,6 @@ static inline void hal_rx_msdu_list_get(void *msdu_link_desc,
"[%s][%d] i=%d sw_cookie=%d\n",
__func__, __LINE__, i, msdu_list->sw_cookie[i]);
}
}
/**
@@ -2527,6 +2530,389 @@ static inline uint8_t hal_srng_ring_id_get(void *hal_ring)
return ((struct hal_srng *)hal_ring)->ring_id;
}
/* Rx MSDU link pointer info */
struct hal_rx_msdu_link_ptr_info {
struct rx_msdu_link msdu_link;
struct hal_buf_info msdu_link_buf_info;
};
/**
* hal_rx_get_pkt_tlvs(): Function to retrieve pkt tlvs from nbuf
*
* @nbuf: Pointer to data buffer field
* Returns: pointer to rx_pkt_tlvs
*/
static inline
struct rx_pkt_tlvs *hal_rx_get_pkt_tlvs(uint8_t *rx_buf_start)
{
return (struct rx_pkt_tlvs *)rx_buf_start;
}
/**
* hal_rx_get_mpdu_info(): Function to retrieve mpdu info from pkt tlvs
*
* @pkt_tlvs: Pointer to pkt_tlvs
* Returns: pointer to rx_mpdu_info structure
*/
static inline
struct rx_mpdu_info *hal_rx_get_mpdu_info(struct rx_pkt_tlvs *pkt_tlvs)
{
return &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details;
}
/**
* hal_rx_get_rx_sequence(): Function to retrieve rx sequence number
*
* @nbuf: Network buffer
* Returns: rx sequence number
*/
#define DOT11_SEQ_FRAG_MASK 0x000f
#define DOT11_FC1_MORE_FRAG_OFFSET 0x04
#define HAL_RX_MPDU_GET_SEQUENCE_NUMBER(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_OFFSET)), \
RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_MASK, \
RX_MPDU_INFO_2_MPDU_SEQUENCE_NUMBER_LSB))
static inline
uint16_t hal_rx_get_rx_sequence(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf);
struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs);
uint16_t seq_number = 0;
seq_number =
HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) >> 4;
/* Skip first 4-bits for fragment number */
return seq_number;
}
/**
* hal_rx_get_rx_fragment_number(): Function to retrieve rx fragment number
*
* @nbuf: Network buffer
* Returns: rx fragment number
*/
static inline
uint8_t hal_rx_get_rx_fragment_number(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf);
struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs);
uint8_t frag_number = 0;
frag_number = HAL_RX_MPDU_GET_SEQUENCE_NUMBER(rx_mpdu_info) &
DOT11_SEQ_FRAG_MASK;
/* Return first 4 bits as fragment number */
return frag_number;
}
#define HAL_RX_MPDU_GET_FRAME_CONTROL_FIELD(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_14_MPDU_FRAME_CONTROL_FIELD_OFFSET)), \
RX_MPDU_INFO_14_MPDU_FRAME_CONTROL_FIELD_MASK, \
RX_MPDU_INFO_14_MPDU_FRAME_CONTROL_FIELD_LSB))
/**
* hal_rx_get_rx_more_frag_bit(): Function to retrieve more fragment bit
*
* @nbuf: Network buffer
* Returns: rx more fragment bit
*/
static inline
uint8_t hal_rx_get_rx_more_frag_bit(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf);
struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs);
uint16_t frame_ctrl = 0;
frame_ctrl = HAL_RX_MPDU_GET_FRAME_CONTROL_FIELD(rx_mpdu_info) >>
DOT11_FC1_MORE_FRAG_OFFSET;
/* more fragment bit if at offset bit 4 */
return frame_ctrl;
}
/**
* hal_rx_get_frame_ctrl_field(): Function to retrieve frame control field
*
* @nbuf: Network buffer
* Returns: rx more fragment bit
*
*/
static inline
uint8_t hal_rx_get_frame_ctrl_field(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf);
struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs);
uint16_t frame_ctrl = 0;
frame_ctrl = HAL_RX_MPDU_GET_FRAME_CONTROL_FIELD(rx_mpdu_info);
return frame_ctrl;
}
/*
* hal_rx_msdu_is_wlan_mcast(): Check if the buffer is for multicast address
*
* @nbuf: Network buffer
* Returns: flag to indicate whether the nbuf has MC/BC address
*/
static inline
uint32_t hal_rx_msdu_is_wlan_mcast(qdf_nbuf_t nbuf)
{
uint8 *buf = qdf_nbuf_data(nbuf);
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_attention *rx_attn = &pkt_tlvs->attn_tlv.rx_attn;
return rx_attn->mcast_bcast;
}
#define HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB))
/*
* hal_rx_get_mpdu_sequence_control_valid(): Get mpdu sequence control valid
*
* @nbuf: Network buffer
* Returns: value of sequence control valid field
*/
static inline
uint8_t hal_rx_get_mpdu_sequence_control_valid(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf);
struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs);
uint8_t seq_ctrl_valid = 0;
seq_ctrl_valid =
HAL_RX_MPDU_GET_SEQUENCE_CONTROL_VALID(rx_mpdu_info);
return seq_ctrl_valid;
}
#define HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \
RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_OFFSET)), \
RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_MASK, \
RX_MPDU_INFO_2_MPDU_FRAME_CONTROL_VALID_LSB))
/*
* hal_rx_get_mpdu_frame_control_valid(): Retrieves mpdu frame control valid
*
* @nbuf: Network buffer
* Returns: value of frame control valid field
*/
static inline
uint8_t hal_rx_get_mpdu_frame_control_valid(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = hal_rx_get_pkt_tlvs(buf);
struct rx_mpdu_info *rx_mpdu_info = hal_rx_get_mpdu_info(pkt_tlvs);
uint8_t frm_ctrl_valid = 0;
frm_ctrl_valid =
HAL_RX_MPDU_GET_FRAME_CONTROL_VALID(rx_mpdu_info);
return frm_ctrl_valid;
}
/*
* hal_rx_clear_mpdu_desc_info(): Clears mpdu_desc_info
*
* @rx_mpdu_desc_info: HAL view of rx mpdu desc info
* Returns: None
*/
static inline
void hal_rx_clear_mpdu_desc_info(
struct hal_rx_mpdu_desc_info *rx_mpdu_desc_info)
{
qdf_mem_zero(rx_mpdu_desc_info,
sizeof(*rx_mpdu_desc_info));
}
/*
* hal_rx_clear_msdu_link_ptr(): Clears msdu_link_ptr
*
* @msdu_link_ptr: HAL view of msdu link ptr
* @size: number of msdu link pointers
* Returns: None
*/
static inline
void hal_rx_clear_msdu_link_ptr(struct hal_rx_msdu_link_ptr_info *msdu_link_ptr,
int size)
{
qdf_mem_zero(msdu_link_ptr,
(sizeof(*msdu_link_ptr) * size));
}
/*
* hal_rx_chain_msdu_links() - Chains msdu link pointers
* @msdu_link_ptr: msdu link pointer
* @mpdu_desc_info: mpdu descriptor info
*
* Build a list of msdus using msdu link pointer. If the
* number of msdus are more, chain them together
*
* Returns: Number of processed msdus
*/
static inline
int hal_rx_chain_msdu_links(qdf_nbuf_t msdu,
struct hal_rx_msdu_link_ptr_info *msdu_link_ptr_info,
struct hal_rx_mpdu_desc_info *mpdu_desc_info)
{
int j;
struct rx_msdu_link *msdu_link_ptr =
&msdu_link_ptr_info->msdu_link;
struct rx_msdu_link *prev_msdu_link_ptr = NULL;
struct rx_msdu_details *msdu_details =
HAL_RX_LINK_DESC_MSDU0_PTR(msdu_link_ptr);
uint8_t num_msdus = mpdu_desc_info->msdu_count;
struct rx_msdu_desc_info *msdu_desc_info;
uint8_t fragno, more_frag;
uint8_t *rx_desc_info;
struct hal_rx_msdu_list msdu_list;
for (j = 0; j < num_msdus; j++) {
msdu_desc_info =
HAL_RX_MSDU_DESC_INFO_GET(&msdu_details[j]);
msdu_list.msdu_info[j].msdu_flags =
HAL_RX_MSDU_FLAGS_GET(msdu_desc_info);
msdu_list.msdu_info[j].msdu_len =
HAL_RX_MSDU_PKT_LENGTH_GET(msdu_desc_info);
msdu_list.sw_cookie[j] = HAL_RX_BUF_COOKIE_GET(
&msdu_details[j].buffer_addr_info_details);
}
/* Chain msdu links together */
if (prev_msdu_link_ptr) {
/* 31-0 bits of the physical address */
prev_msdu_link_ptr->
next_msdu_link_desc_addr_info.buffer_addr_31_0 =
msdu_link_ptr_info->msdu_link_buf_info.paddr &
BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK;
/* 39-32 bits of the physical address */
prev_msdu_link_ptr->
next_msdu_link_desc_addr_info.buffer_addr_39_32
= ((msdu_link_ptr_info->msdu_link_buf_info.paddr
>> 32) &&
BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK);
prev_msdu_link_ptr->
next_msdu_link_desc_addr_info.sw_buffer_cookie =
msdu_link_ptr_info->msdu_link_buf_info.sw_cookie;
}
/* There is space for only 6 MSDUs in a MSDU link descriptor */
if (num_msdus < HAL_RX_NUM_MSDU_DESC) {
/* mark first and last MSDUs */
rx_desc_info = qdf_nbuf_data(msdu);
fragno = hal_rx_get_rx_fragment_number(rx_desc_info);
more_frag = hal_rx_get_rx_more_frag_bit(rx_desc_info);
/* TODO: create skb->fragslist[] */
if (more_frag == 0) {
msdu_list.msdu_info[num_msdus].msdu_flags |=
RX_MSDU_DESC_INFO_0_LAST_MSDU_IN_MPDU_FLAG_MASK;
} else if (fragno == 1) {
msdu_list.msdu_info[num_msdus].msdu_flags |=
RX_MSDU_DESC_INFO_0_FIRST_MSDU_IN_MPDU_FLAG_MASK;
msdu_list.msdu_info[num_msdus].msdu_flags |=
RX_MSDU_DESC_INFO_0_MSDU_CONTINUATION_MASK;
}
num_msdus++;
/* Number of MSDUs per mpdu descriptor is updated */
mpdu_desc_info->msdu_count += num_msdus;
} else {
num_msdus = 0;
prev_msdu_link_ptr = msdu_link_ptr;
}
return num_msdus;
}
/*
* hal_rx_defrag_update_src_ring_desc(): updates reo src ring desc
*
* @ring_desc: HAL view of ring descriptor
* @mpdu_des_info: saved mpdu desc info
* @msdu_link_ptr: saved msdu link ptr
*
* API used explicitely for rx defrag to update ring desc with
* mpdu desc info and msdu link ptr before reinjecting the
* packet back to REO
*
* Returns: None
*/
static inline
void hal_rx_defrag_update_src_ring_desc(void *ring_desc,
void *saved_mpdu_desc_info,
struct hal_rx_msdu_link_ptr_info *saved_msdu_link_ptr)
{
struct reo_entrance_ring *reo_ent_ring;
struct rx_mpdu_desc_info *reo_ring_mpdu_desc_info;
struct hal_buf_info buf_info;
reo_ent_ring = (struct reo_entrance_ring *)ring_desc;
reo_ring_mpdu_desc_info = &reo_ent_ring->
reo_level_mpdu_frame_info.rx_mpdu_desc_info_details;
qdf_mem_copy(&reo_ring_mpdu_desc_info, saved_mpdu_desc_info,
sizeof(*reo_ring_mpdu_desc_info));
/*
* TODO: Check for additional fields that need configuration in
* reo_ring_mpdu_desc_info
*/
/* Update msdu_link_ptr in the reo entrance ring */
hal_rx_reo_buf_paddr_get(ring_desc, &buf_info);
buf_info.paddr = saved_msdu_link_ptr->msdu_link_buf_info.paddr;
buf_info.sw_cookie =
saved_msdu_link_ptr->msdu_link_buf_info.sw_cookie;
}
/*
* hal_rx_defrag_save_info_from_ring_desc(): Saves info from ring desc
*
* @msdu_link_desc_va: msdu link descriptor handle
* @msdu_link_ptr_info: HAL view of msdu link pointer info
*
* API used to save msdu link information along with physical
* address. The API also copues the sw cookie.
*
* Returns: None
*/
static inline
void hal_rx_defrag_save_info_from_ring_desc(void *msdu_link_desc_va,
struct hal_rx_msdu_link_ptr_info *msdu_link_ptr_info,
struct hal_buf_info *hbi)
{
struct rx_msdu_link *msdu_link_ptr =
(struct rx_msdu_link *)msdu_link_desc_va;
qdf_mem_copy(&msdu_link_ptr_info->msdu_link, msdu_link_ptr,
sizeof(struct rx_msdu_link));
msdu_link_ptr_info->msdu_link_buf_info.paddr = hbi->paddr;
msdu_link_ptr_info->msdu_link_buf_info.sw_cookie = hbi->sw_cookie;
}
/*
* hal_rx_get_desc_len(): Returns rx descriptor length
*
* Returns the size of rx_pkt_tlvs which follows the
* data in the nbuf
*
* Returns: Length of rx descriptor
*/
static inline
uint16_t hal_rx_get_desc_len(void)
{
return sizeof(struct rx_pkt_tlvs);
}
#endif /* _HAL_RX_H */

View File

@@ -947,4 +947,5 @@ static inline qdf_dma_addr_t hal_srng_get_tp_addr(void *hal_soc, void *hal_ring)
*/
extern void hal_get_srng_params(void *hal_soc, void *hal_ring,
struct hal_srng_params *ring_params);
#endif /* _HAL_API_H_ */
#endif /* _HAL_APIH_ */

View File

@@ -33,6 +33,7 @@
#include "qdf_types.h"
#include "qdf_lock.h"
#include "qdf_mem.h"
#include "qdf_nbuf.h"
#include "wcss_seq_hwiobase.h"
#include "tlv_hdr.h"
#include "tlv_tag_def.h"
@@ -62,9 +63,11 @@
#include "rx_ppdu_start_user_info.h"
#include "rx_ppdu_end_user_stats.h"
#include "rx_ppdu_end_user_stats_ext.h"
#include "rx_mpdu_desc_info.h"
#include "tx_msdu_extension.h"
#include "wcss_version.h"
#include "pld_common.h"
#include "rx_msdu_link.h"
/* TBD: This should be movded to shared HW header file */
enum hal_srng_ring_id {

View File

@@ -139,6 +139,7 @@ typedef enum {
QDF_STATUS_CRYPTO_MIC_FAILURE,
QDF_STATUS_CRYPTO_ENCRYPT_FAILED,
QDF_STATUS_CRYPTO_DECRYPT_FAILED,
QDF_STATUS_E_DEFRAG_ERROR,
QDF_STATUS_MAX
} QDF_STATUS;