qcacmn: Add support for intra-bss forwarding

pkts should be forwarded from one STA to another
STA belonging to same VAP from within the driver

Change-Id: I68eb0dd91f7ac54352b4882ffdb9d5d53d627db1

Conflicts:
	dp/wifi3.0/dp_rx.c
	dp/wifi3.0/dp_types.h

Conflicts:
	dp/wifi3.0/dp_rx.c

Change-Id: I68eb0dd91f7ac54352b4882ffdb9d5d53d627db1
This commit is contained in:
Tallapragada Kalyan
2017-02-17 17:00:23 +05:30
committed by Sandeep Puligilla
parent 975bf37ab6
commit 6f6166e36c
7 changed files with 394 additions and 19 deletions

View File

@@ -518,9 +518,12 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
u_int8_t mac_addr_deswizzle_buf[HTT_MAC_ADDR_LEN]; u_int8_t mac_addr_deswizzle_buf[HTT_MAC_ADDR_LEN];
u_int8_t *peer_mac_addr; u_int8_t *peer_mac_addr;
u_int16_t peer_id; u_int16_t peer_id;
u_int16_t hw_peer_id;
u_int8_t vdev_id; u_int8_t vdev_id;
peer_id = HTT_RX_PEER_MAP_PEER_ID_GET(*msg_word); peer_id = HTT_RX_PEER_MAP_PEER_ID_GET(*msg_word);
hw_peer_id =
HTT_RX_PEER_MAP_HW_PEER_ID_GET(*(msg_word+2));
vdev_id = HTT_RX_PEER_MAP_VDEV_ID_GET(*msg_word); vdev_id = HTT_RX_PEER_MAP_VDEV_ID_GET(*msg_word);
peer_mac_addr = htt_t2h_mac_addr_deswizzle( peer_mac_addr = htt_t2h_mac_addr_deswizzle(
(u_int8_t *) (msg_word+1), (u_int8_t *) (msg_word+1),
@@ -530,8 +533,8 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
"HTT_T2H_MSG_TYPE_PEER_MAP msg for peer id %d vdev id %d n", "HTT_T2H_MSG_TYPE_PEER_MAP msg for peer id %d vdev id %d n",
peer_id, vdev_id); peer_id, vdev_id);
dp_rx_peer_map_handler( dp_rx_peer_map_handler(soc->dp_soc, peer_id, hw_peer_id,
soc->dp_soc, peer_id, vdev_id, peer_mac_addr); vdev_id, peer_mac_addr);
break; break;
} }
case HTT_T2H_MSG_TYPE_PEER_UNMAP: case HTT_T2H_MSG_TYPE_PEER_UNMAP:

View File

@@ -1692,6 +1692,13 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle,
if (!peer) if (!peer)
return NULL; /* failure */ return NULL; /* failure */
TAILQ_INIT(&peer->ast_entry_list);
qdf_mem_copy(&peer->self_ast_entry.mac_addr, peer_mac_addr,
DP_MAC_ADDR_LEN);
peer->self_ast_entry.peer = peer;
TAILQ_INSERT_HEAD(&peer->ast_entry_list, &peer->self_ast_entry,
ast_entry_elem);
qdf_mem_zero(peer, sizeof(struct dp_peer)); qdf_mem_zero(peer, sizeof(struct dp_peer));
qdf_spinlock_create(&peer->peer_info_lock); qdf_spinlock_create(&peer->peer_info_lock);
@@ -1849,6 +1856,8 @@ void dp_peer_unref_delete(void *peer_handle)
struct dp_peer *tmppeer; struct dp_peer *tmppeer;
int found = 0; int found = 0;
uint16_t peer_id; uint16_t peer_id;
uint16_t hw_peer_id;
struct dp_ast_entry *ast_entry;
/* /*
* Hold the lock all the way from checking if the peer ref count * Hold the lock all the way from checking if the peer ref count
@@ -1932,6 +1941,17 @@ void dp_peer_unref_delete(void *peer_handle)
#ifdef notyet #ifdef notyet
qdf_mempool_free(soc->osdev, soc->mempool_ol_ath_peer, peer); qdf_mempool_free(soc->osdev, soc->mempool_ol_ath_peer, peer);
#else #else
TAILQ_FOREACH(ast_entry, &peer->ast_entry_list,
ast_entry_elem) {
hw_peer_id = ast_entry->ast_idx;
if (peer->self_ast_entry.ast_idx != hw_peer_id)
qdf_mem_free(ast_entry);
else
peer->self_ast_entry.ast_idx =
HTT_INVALID_PEER;
soc->ast_table[hw_peer_id] = NULL;
}
qdf_mem_free(peer); qdf_mem_free(peer);
#endif #endif
if (soc->cdp_soc.ol_ops->peer_unref_delete) { if (soc->cdp_soc.ol_ops->peer_unref_delete) {

View File

@@ -327,7 +327,8 @@ int dp_peer_find_attach(struct dp_soc *soc)
} }
static inline void dp_peer_find_add_id(struct dp_soc *soc, static inline void dp_peer_find_add_id(struct dp_soc *soc,
uint8_t *peer_mac_addr, uint16_t peer_id, uint8_t vdev_id) uint8_t *peer_mac_addr, uint16_t peer_id, uint16_t hw_peer_id,
uint8_t vdev_id)
{ {
struct dp_peer *peer; struct dp_peer *peer;
@@ -353,6 +354,8 @@ static inline void dp_peer_find_add_id(struct dp_soc *soc,
"%s: ref_cnt: %d", __func__, "%s: ref_cnt: %d", __func__,
qdf_atomic_read(&peer->ref_cnt)); qdf_atomic_read(&peer->ref_cnt));
soc->peer_id_to_obj_map[peer_id] = peer; soc->peer_id_to_obj_map[peer_id] = peer;
peer->self_ast_entry.ast_idx = hw_peer_id;
soc->ast_table[hw_peer_id] = &peer->self_ast_entry;
if (dp_peer_find_add_id_to_obj(peer, peer_id)) { if (dp_peer_find_add_id_to_obj(peer, peer_id)) {
/* TBDXXX: assert for now */ /* TBDXXX: assert for now */
@@ -363,19 +366,95 @@ static inline void dp_peer_find_add_id(struct dp_soc *soc,
} }
} }
static inline void dp_peer_add_ast(struct dp_soc *soc,
struct dp_peer *peer, uint8_t *peer_mac_addr, uint16_t hw_peer_id,
uint8_t vdev_id)
{
struct dp_ast_entry *ast_entry;
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: peer %p ID %d vid %d mac %02x:%02x:%02x:%02x:%02x:%02x\n",
__func__, peer, hw_peer_id, vdev_id, peer_mac_addr[0],
peer_mac_addr[1], peer_mac_addr[2], peer_mac_addr[3],
peer_mac_addr[4], peer_mac_addr[5]);
TAILQ_FOREACH(ast_entry, &peer->ast_entry_list, ast_entry_elem) {
if (!(qdf_mem_cmp(peer_mac_addr, ast_entry->mac_addr,
DP_MAC_ADDR_LEN))) {
soc->ast_table[ast_entry->ast_idx] = NULL;
ast_entry->ast_idx = hw_peer_id;
soc->ast_table[hw_peer_id] = ast_entry;
return;
}
}
ast_entry = (struct dp_ast_entry *)
qdf_mem_malloc(sizeof(struct dp_ast_entry));
if (!ast_entry) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
FL("fail to allocate ast_entry for: %d"), hw_peer_id);
QDF_ASSERT(0);
}
qdf_mem_copy(&ast_entry->mac_addr, peer_mac_addr, DP_MAC_ADDR_LEN);
ast_entry->peer = peer;
ast_entry->next_hop = 1;
TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry, ast_entry_elem);
soc->ast_table[hw_peer_id] = ast_entry;
return;
}
/**
* dp_rx_peer_map_handler() - handle peer map event from firmware
* @soc_handle - genereic soc handle
* @peeri_id - peer_id from firmware
* @hw_peer_id - ast index for this peer
* vdev_id - vdev ID
* peer_mac_addr - macc assress of the peer
*
* associate the peer_id that firmware provided with peer entry
* and update the ast table in the host with the hw_peer_id.
*
* Return: none
*/
void void
dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, uint8_t vdev_id, dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, uint16_t hw_peer_id,
uint8_t *peer_mac_addr) uint8_t vdev_id, uint8_t *peer_mac_addr)
{ {
struct dp_soc *soc = (struct dp_soc *)soc_handle; struct dp_soc *soc = (struct dp_soc *)soc_handle;
struct dp_peer *peer = NULL;
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH, QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
"peer_map_event (soc:%p): peer_id %d, peer_mac " "peer_map_event (soc:%p): peer_id %di, hw_peer_id %d, peer_mac "
"%02x:%02x:%02x:%02x:%02x:%02x, vdev_id %d\n", soc, peer_id, "%02x:%02x:%02x:%02x:%02x:%02x, vdev_id %d\n", soc, peer_id,
peer_mac_addr[0], peer_mac_addr[1], peer_mac_addr[2], hw_peer_id, peer_mac_addr[0], peer_mac_addr[1],
peer_mac_addr[3], peer_mac_addr[4], peer_mac_addr[5], vdev_id); peer_mac_addr[2], peer_mac_addr[3], peer_mac_addr[4],
peer_mac_addr[5], vdev_id);
dp_peer_find_add_id(soc, peer_mac_addr, peer_id, vdev_id); peer = soc->peer_id_to_obj_map[peer_id];
if ((hw_peer_id < 0) || (hw_peer_id > WLAN_UMAC_PSOC_MAX_PEERS)) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"invalid hw_peer_id: %d", hw_peer_id);
QDF_ASSERT(0);
}
/*
* check if peer already exists for this peer_id, if so
* this peer map event is in response for a wds peer add
* wmi command sent during wds source port learning.
* in this case just add the ast entry to the existing
* peer ast_list.
*/
if (!peer)
dp_peer_find_add_id(soc, peer_mac_addr, peer_id,
hw_peer_id, vdev_id);
else
dp_peer_add_ast(soc, peer, peer_mac_addr,
hw_peer_id, vdev_id);
} }
void void

View File

@@ -46,7 +46,7 @@ dp_peer_find_by_id(struct dp_soc *soc,
} }
void dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, void dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id,
uint8_t vdev_id, uint8_t *peer_mac_addr); uint16_t hw_peer_id, uint8_t vdev_id, uint8_t *peer_mac_addr);
void dp_rx_peer_unmap_handler(void *soc_handle, uint16_t peer_id); void dp_rx_peer_unmap_handler(void *soc_handle, uint16_t peer_id);
void dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id, void dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id,
enum htt_sec_type sec_type, int is_unicast, enum htt_sec_type sec_type, int is_unicast,

View File

@@ -283,10 +283,62 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
uint8_t *rx_tlv_hdr, uint8_t *rx_tlv_hdr,
qdf_nbuf_t nbuf) qdf_nbuf_t nbuf)
{ {
DP_STATS_INC_PKT(sa_peer, rx.intra_bss, 1, uint16_t da_idx;
qdf_nbuf_len(nbuf)); uint16_t len;
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, struct dp_peer *da_peer;
FL("Intra-BSS forwarding not implemented")); struct dp_ast_entry *ast_entry;
qdf_nbuf_t nbuf_copy;
/* check if the destination peer is available in peer table
* and also check if the source peer and destination peer
* belong to the same vap and destination peer is not bss peer.
*/
if ((hal_rx_msdu_end_da_is_valid_get(rx_tlv_hdr) &&
!hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) {
da_idx = hal_rx_msdu_end_da_idx_get(rx_tlv_hdr);
ast_entry = soc->ast_table[da_idx];
if (!ast_entry)
return false;
da_peer = ast_entry->peer;
if (!da_peer)
return false;
if (da_peer->vdev == sa_peer->vdev && !da_peer->bss_peer) {
memset(nbuf->cb, 0x0, sizeof(nbuf->cb));
len = qdf_nbuf_len(nbuf);
if (!dp_tx_send(sa_peer->vdev, nbuf)) {
DP_STATS_INC_PKT(sa_peer, rx.intra_bss, 1, len);
return true;
} else
return false;
}
}
/* if it is a broadcast pkt (eg: ARP) and it is not its own
* source, then clone the pkt and send the cloned pkt for
* intra BSS forwarding and original pkt up the network stack
* Note: how do we handle multicast pkts. do we forward
* all multicast pkts as is or let a higher layer module
* like igmpsnoop decide whether to forward or not with
* Mcast enhancement.
*/
else if (qdf_unlikely((hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr) &&
!sa_peer->bss_peer))) {
nbuf_copy = qdf_nbuf_copy(nbuf);
if (!nbuf_copy)
return false;
memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb));
len = qdf_nbuf_len(nbuf_copy);
if (dp_tx_send(sa_peer->vdev, nbuf_copy))
qdf_nbuf_free(nbuf_copy);
else
DP_STATS_INC_PKT(sa_peer, rx.intra_bss, 1, len);
}
/* return false as we have to still send the original pkt
* up the stack
*/
return false; return false;
} }
@@ -426,7 +478,6 @@ QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
#endif #endif
/** /**
* dp_rx_process() - Brain of the Rx processing functionality * dp_rx_process() - Brain of the Rx processing functionality
* Called from the bottom half (tasklet/NET_RX_SOFTIRQ) * Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
@@ -749,9 +800,10 @@ done:
dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, peer, nbuf); dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, peer, nbuf);
/* Intrabss-fwd */ /* Intrabss-fwd */
if (peer && if (vdev->opmode != wlan_op_mode_sta)
dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr, nbuf)) if (dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr,
continue; /* Get next descriptor */ nbuf))
continue; /* Get next descriptor */
rx_bufs_used++; rx_bufs_used++;
DP_RX_LIST_APPEND(deliver_list_head, DP_RX_LIST_APPEND(deliver_list_head,

View File

@@ -56,6 +56,27 @@
#define DP_QOS_TID 0x0f #define DP_QOS_TID 0x0f
#define DP_IPV6_PRIORITY_SHIFT 20 #define DP_IPV6_PRIORITY_SHIFT 20
#if defined(CONFIG_MCL)
#define MAX_PDEV_CNT 1
#else
#define MAX_PDEV_CNT 3
#endif
#define MAX_LINK_DESC_BANKS 8
#define MAX_TXDESC_POOLS 4
#define MAX_RXDESC_POOLS 4
#define MAX_REO_DEST_RINGS 4
#define MAX_TCL_DATA_RINGS 4
#define DP_MAX_TX_RINGS 8
#define DP_MAX_RX_RINGS 8
#define MAX_IDLE_SCATTER_BUFS 16
#define DP_MAX_IRQ_PER_CONTEXT 12
#define DP_MAX_INTERRUPT_CONTEXTS 8
#define DEFAULT_HW_PEER_ID 0xffff
#define MAX_TX_HW_QUEUES 3
#define DP_MAX_INTERRUPT_CONTEXTS 8
struct dp_soc_cmn; struct dp_soc_cmn;
struct dp_pdev; struct dp_pdev;
struct dp_vdev; struct dp_vdev;
@@ -91,6 +112,7 @@ union dp_rx_desc_list_elem_t;
#define DP_SW2HW_MACID(id) ((id) + 1) #define DP_SW2HW_MACID(id) ((id) + 1)
#define DP_HW2SW_MACID(id) ((id) > 0 ? ((id) - 1) : 0) #define DP_HW2SW_MACID(id) ((id) > 0 ? ((id) - 1) : 0)
#define DP_MAC_ADDR_LEN 6
/** /**
* enum dp_tx_frm_type * enum dp_tx_frm_type
@@ -290,6 +312,124 @@ struct reo_desc_list_node {
struct dp_rx_tid rx_tid; struct dp_rx_tid rx_tid;
}; };
/* TODO: Proper comments have been added in the subsequesnt gerrit */
/* packet info */
struct dp_pkt_info {
uint32_t num; /*no of packets*/
uint32_t bytes; /* total no of bytes */
};
/* per pdev tx stats*/
struct dp_tx_pdev_stats {
struct dp_pkt_info rcvd; /*total packets received for transmission */
struct {
/* Pkt Info for which completions were received */
struct dp_pkt_info comp_pkt;
uint32_t mcs_count[MAX_MCS + 1]; /* MCS Count */
} comp; /* Tx completions received*/
struct dp_pkt_info freed; /* Tx packets freed*/
struct dp_pkt_info processed; /* Tx packets processed*/
struct dp_pkt_info outstanding; /* Tx packets remaining for processing*/
struct {
struct dp_pkt_info dropped_pkt; /* Total packets dropped */
uint32_t desc_total; /* total descriptors dropped */
uint32_t dma_map_error; /* Dropped due to Dma Error */
uint32_t ring_full; /* dropped due to ring full */
uint32_t fw_discard; /* Discarded bu firmware */
uint32_t fw_discard_retired; /* fw_discard_retired */
/* firmware_discard_untransmitted */
uint32_t firmware_discard_untransmitted;
uint32_t mpdu_age_out; /* mpdu_age_out */
uint32_t firmware_discard_reason1; /*firmware_discard_reason1*/
uint32_t firmware_discard_reason2; /*firmware_discard_reason2*/
uint32_t firmware_discard_reason3; /*firmware_discard_reason3*/
} dropped; /* Packets dropped on the Tx side */
struct {
struct dp_pkt_info sg_pkt; /* total scatter gather packets */
uint32_t dropped_host; /* SG packets dropped by host */
uint32_t dropped_target; /* SG packets dropped by target */
} sg; /* Scatter Gather packet info */
struct {
uint32_t num_seg; /* No of segments in TSO packets */
struct dp_pkt_info tso_pkt; /* total no of TSO packets */
uint32_t dropped_host; /* TSO packets dropped by host */
uint32_t dropped_target; /* TSO packets dropped by target */
} tso; /* TSO packets info */
struct {
/* total no of multicast conversion packets */
struct dp_pkt_info mcast_pkt;
/* packets dropped due to map error */
uint32_t dropped_map_error;
/* packets dropped due to self Mac address */
uint32_t dropped_self_mac;
/* Packets dropped due to send fail */
uint32_t dropped_send_fail;
/* total unicast packets transmitted */
uint32_t ucast;
} mcast_en; /* Multicast Enhancement packets info */
/* Total packets passed Reinject handler */
struct dp_pkt_info reinject_pkts;
/* Total packets passed to inspect handler */
struct dp_pkt_info inspect_pkts;
/* Total Raw packets */
struct dp_pkt_info raw_pkt;
};
/* Per pdev RX stats */
struct dp_rx_pdev_stats {
struct dp_pkt_info rcvd_reo; /* packets received on the reo ring */
struct {
/* packets dropped because of no peer */
struct dp_pkt_info no_peer;
/* packets dropped because nsdu_done bit not set */
struct dp_pkt_info msdu_not_done;
} dropped; /* packets dropped on rx */
struct dp_pkt_info replenished; /* total packets replnished */
struct dp_pkt_info to_stack; /* total packets sent up the stack */
struct dp_pkt_info intra_bss; /* Intra BSS packets received */
struct dp_pkt_info wds; /* WDS packets received */
struct dp_pkt_info desc;
struct dp_pkt_info buff;
struct dp_pkt_info raw; /* Raw Pakets received */
struct {
uint32_t rxdma_unitialized; /* rxdma_unitialized errors */
uint32_t desc_alloc_fail; /* desc alloc failed errors */
} err; /* Rx errors */
uint32_t buf_freelist; /* buffers added back in freelist */
uint32_t mcs_count[MAX_MCS + 1]; /* packets in different MCS rates */
uint32_t sgi_count[MAX_MCS + 1]; /* SGI count */
/* Number of MSDUs with no MPDU level aggregation */
uint32_t non_ampdu_cnt;
/* Number of MSDUs part of AMSPU */
uint32_t ampdu_cnt;
/* Number of MSDUs with no MSDU level aggregation */
uint32_t non_amsdu_cnt;
/* Number of MSDUs part of AMSDU*/
uint32_t amsdu_cnt;
/* Packet count in spatiel Streams */
uint32_t nss[SS_COUNT];
/* Packet count in different Bandwidths */
uint32_t bw[SUPPORTED_BW];
/* reception type os packets */
uint32_t reception_type[SUPPORTED_RECEPTION_TYPES];
};
struct dp_ast_entry {
uint16_t ast_idx;
uint8_t mac_addr[DP_MAC_ADDR_LEN];
uint8_t next_hop;
struct dp_peer *peer;
TAILQ_ENTRY(dp_ast_entry) ast_entry_elem;
};
/* SOC level structure for data path */ /* SOC level structure for data path */
struct dp_soc { struct dp_soc {
/* Common base structure - Should be the first member */ /* Common base structure - Should be the first member */
@@ -502,6 +642,8 @@ struct dp_soc {
/* Enable processing of Tx completion status words */ /* Enable processing of Tx completion status words */
bool process_tx_status; bool process_tx_status;
struct dp_ast_entry *ast_table[WLAN_UMAC_PSOC_MAX_PEERS];
#ifdef DP_INTR_POLL_BASED #ifdef DP_INTR_POLL_BASED
/*interrupt timer*/ /*interrupt timer*/
qdf_timer_t int_timer; qdf_timer_t int_timer;
@@ -601,7 +743,6 @@ struct dp_pdev {
struct dp_peer; struct dp_peer;
#define DP_MAC_ADDR_LEN 6
union dp_align_mac_addr { union dp_align_mac_addr {
uint8_t raw[DP_MAC_ADDR_LEN]; uint8_t raw[DP_MAC_ADDR_LEN];
struct { struct {
@@ -731,6 +872,8 @@ struct dp_peer {
/* VDEV to which this peer is associated */ /* VDEV to which this peer is associated */
struct dp_vdev *vdev; struct dp_vdev *vdev;
struct dp_ast_entry self_ast_entry;
qdf_atomic_t ref_cnt; qdf_atomic_t ref_cnt;
/* TODO: See if multiple peer IDs are required in wifi3.0 */ /* TODO: See if multiple peer IDs are required in wifi3.0 */
@@ -785,5 +928,8 @@ struct dp_peer {
qdf_time_t last_deauth_rcvd; qdf_time_t last_deauth_rcvd;
/* Peer Stats */ /* Peer Stats */
struct cdp_peer_stats stats; struct cdp_peer_stats stats;
TAILQ_HEAD(, dp_ast_entry) ast_entry_list;
/* TBD */
}; };
#endif /* _DP_TYPES_H_ */ #endif /* _DP_TYPES_H_ */

View File

@@ -1252,6 +1252,81 @@ QDF_STATUS hal_rx_mpdu_get_addr2(uint8_t *buf, uint8_t *mac_addr)
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
#define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \
RX_MSDU_END_13_DA_IDX_OFFSET)), \
RX_MSDU_END_13_DA_IDX_MASK, \
RX_MSDU_END_13_DA_IDX_LSB))
/**
* hal_rx_msdu_end_da_idx_get: API to get da_idx
* from rx_msdu_end TLV
*
* @ buf: pointer to the start of RX PKT TLV headers
* Return: da index
*/
static inline uint16_t
hal_rx_msdu_end_da_idx_get(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end;
uint16_t da_idx;
da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end);
return da_idx;
}
#define HAL_RX_MSDU_END_DA_IS_VALID_GET(_rx_msdu_end) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \
RX_MSDU_END_5_DA_IS_VALID_OFFSET)), \
RX_MSDU_END_5_DA_IS_VALID_MASK, \
RX_MSDU_END_5_DA_IS_VALID_LSB))
/**
* hal_rx_msdu_end_da_is_valid_get: API to check if da is valid
* from rx_msdu_end TLV
*
* @ buf: pointer to the start of RX PKT TLV headers
* Return: da_is_valid
*/
static inline uint8_t
hal_rx_msdu_end_da_is_valid_get(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end;
uint8_t da_is_valid;
da_is_valid = HAL_RX_MSDU_END_DA_IS_VALID_GET(msdu_end);
return da_is_valid;
}
#define HAL_RX_MSDU_END_DA_IS_MCBC_GET(_rx_msdu_end) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end, \
RX_MSDU_END_5_DA_IS_MCBC_OFFSET)), \
RX_MSDU_END_5_DA_IS_MCBC_MASK, \
RX_MSDU_END_5_DA_IS_MCBC_LSB))
/**
* hal_rx_msdu_end_da_is_mcbc_get: API to check if pkt is MCBC
* from rx_msdu_end TLV
*
* @ buf: pointer to the start of RX PKT TLV headers
* Return: da_is_mcbc
*/
static inline uint8_t
hal_rx_msdu_end_da_is_mcbc_get(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end;
uint8_t da_is_mcbc;
da_is_mcbc = HAL_RX_MSDU_END_DA_IS_MCBC_GET(msdu_end);
return da_is_mcbc;
}
/******************************************************************************* /*******************************************************************************
* RX ERROR APIS * RX ERROR APIS
******************************************************************************/ ******************************************************************************/