From 2ae71e05315671e91af10e3dc45fe16cc0090a09 Mon Sep 17 00:00:00 2001 From: Tallapragada Kalyan Date: Fri, 31 Aug 2018 19:30:54 +0530 Subject: [PATCH] qcacmn: Add AST entry for Destination MAC in RX path Because of a HW issue we have added a WAR where we do learning even on destination MAC address. This will ensure da_is_valid even for forwarding traffic and HW will cache this entry for subsequent pkts there by we achieve better throughput in UL. Change-Id: Ib61693e9ce52b3a1cdcd4c34eabb3d8368b1ef13 --- dp/inc/cdp_txrx_cmn_struct.h | 1 + dp/wifi3.0/dp_main.c | 2 +- dp/wifi3.0/dp_peer.c | 7 +++++- dp/wifi3.0/dp_rx.c | 49 +++++++++++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 5c170d3f86..5b12661360 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -313,6 +313,7 @@ enum cdp_txrx_ast_entry_type { CDP_TXRX_AST_TYPE_MEC, /* Multicast echo ast entry type */ CDP_TXRX_AST_TYPE_WDS_HM, /* HM WDS entry */ CDP_TXRX_AST_TYPE_STA_BSS, /* BSS entry(STA mode) */ + CDP_TXRX_AST_TYPE_DA, /* AST entry based on Destination address */ CDP_TXRX_AST_TYPE_MAX }; diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 1dd93cf7e7..2bbf5751f2 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -872,7 +872,7 @@ static void dp_print_ast_stats(struct dp_soc *soc) struct dp_peer *peer; struct dp_ast_entry *ase, *tmp_ase; char type[CDP_TXRX_AST_TYPE_MAX][10] = { - "NONE", "STATIC", "SELF", "WDS", "MEC", "HMWDS", "BSS"}; + "NONE", "STATIC", "SELF", "WDS", "MEC", "HMWDS", "BSS", "DA"}; DP_PRINT_STATS("AST Stats:"); DP_PRINT_STATS(" Entries Added = %d", soc->stats.ast.added); diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index f549cebacb..6f0767fdb0 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -587,6 +587,10 @@ int dp_peer_add_ast(struct dp_soc *soc, ast_entry->next_hop = 1; ast_entry->type = CDP_TXRX_AST_TYPE_MEC; break; + case CDP_TXRX_AST_TYPE_DA: + ast_entry->next_hop = 1; + ast_entry->type = CDP_TXRX_AST_TYPE_DA; + break; default: QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("Incorrect AST entry type")); @@ -598,7 +602,8 @@ int dp_peer_add_ast(struct dp_soc *soc, dp_peer_ast_hash_add(soc, ast_entry); qdf_spin_unlock_bh(&soc->ast_lock); - if (ast_entry->type == CDP_TXRX_AST_TYPE_MEC) + if (ast_entry->type == CDP_TXRX_AST_TYPE_MEC || + ast_entry->type == CDP_TXRX_AST_TYPE_DA) qdf_mem_copy(next_node_mac, peer->vdev->mac_addr.raw, 6); else qdf_mem_copy(next_node_mac, peer->mac_addr.raw, 6); diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 72a461602f..063f577419 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -336,6 +336,46 @@ dp_get_vdev_from_peer(struct dp_soc *soc, } #endif +/** + * dp_rx_da_learn() - Add AST entry based on DA lookup + * This is a WAR for HK 1.0 and will + * be removed in HK 2.0 + * + * @soc: core txrx main context + * @rx_tlv_hdr : start address of rx tlvs + * @sa_peer : source peer entry + * @nbuf : nbuf to retrieve destination mac for which AST will be added + * + */ +#ifdef FEATURE_WDS +static void +dp_rx_da_learn(struct dp_soc *soc, + uint8_t *rx_tlv_hdr, + struct dp_peer *ta_peer, + qdf_nbuf_t nbuf) +{ + if (ta_peer && (ta_peer->vdev->opmode != wlan_op_mode_ap)) + return; + + if (qdf_unlikely(!hal_rx_msdu_end_da_is_valid_get(rx_tlv_hdr) && + !hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) { + dp_peer_add_ast(soc, + ta_peer, + qdf_nbuf_data(nbuf), + CDP_TXRX_AST_TYPE_DA, + IEEE80211_NODE_F_WDS_HM); + } +} +#else +static void +dp_rx_da_learn(struct dp_soc *soc, + uint8_t *rx_tlv_hdr, + struct dp_peer *ta_peer, + qdf_nbuf_t nbuf) +{ +} +#endif + /** * dp_rx_intrabss_fwd() - Implements the Intra-BSS forwarding logic * @@ -371,6 +411,11 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, if (!ast_entry) return false; + if (ast_entry->type == CDP_TXRX_AST_TYPE_DA) { + ast_entry->is_active = TRUE; + return false; + } + da_peer = ast_entry->peer; if (!da_peer) @@ -1668,9 +1713,11 @@ done: htt_cmn_pkt_type_ethernet) && qdf_likely(!vdev->mesh_vdev)) { /* WDS Source Port Learning */ - if (vdev->wds_enabled) + if (vdev->wds_enabled) { + dp_rx_da_learn(soc, rx_tlv_hdr, peer, nbuf); dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, peer, nbuf); + } /* Intrabss-fwd */ if (dp_rx_check_ap_bridge(vdev))