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:

committed by
Sandeep Puligilla

parent
975bf37ab6
commit
6f6166e36c
@@ -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:
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
|
@@ -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,
|
||||||
|
@@ -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_ */
|
||||||
|
@@ -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
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
Reference in New Issue
Block a user