diff --git a/dp/inc/cdp_txrx_ipa.h b/dp/inc/cdp_txrx_ipa.h index 04b4f83861..f040b30381 100644 --- a/dp/inc/cdp_txrx_ipa.h +++ b/dp/inc/cdp_txrx_ipa.h @@ -767,6 +767,33 @@ cdp_ipa_ast_create(ol_txrx_soc_handle soc, qdf_ipa_ast_info_type_t *data) } #endif +/** + * cdp_ipa_update_peer_rx_stats - update peer rx stats + * @soc: data path soc handle + * @vdev_id: vdev id + * @peer_mac: Peer Mac Address + * @nbuf: pointer to data packet + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +cdp_ipa_update_peer_rx_stats(ol_txrx_soc_handle soc, uint8_t vdev_id, + uint8_t *peer_mac, qdf_nbuf_t nbuf) +{ + if (!soc || !soc->ops || !soc->ops->ipa_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + if (soc->ops->ipa_ops->ipa_update_peer_rx_stats) + return soc->ops->ipa_ops->ipa_update_peer_rx_stats(soc, + vdev_id, + peer_mac, + nbuf); + + return QDF_STATUS_SUCCESS; +} #endif /* IPA_OFFLOAD */ #endif /* _CDP_TXRX_IPA_H_ */ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index f8c7b5aa02..f499b1de02 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -1961,6 +1961,10 @@ struct cdp_ipa_ops { uint8_t vdev_id, qdf_nbuf_t skb); void (*ipa_set_uc_tx_partition_base)(struct cdp_cfg *pdev, uint32_t value); + QDF_STATUS (*ipa_update_peer_rx_stats)(struct cdp_soc_t *soc_hdl, + uint8_t vdev_id, + uint8_t *peer_mac, + qdf_nbuf_t nbuf); #ifdef FEATURE_METERING QDF_STATUS (*ipa_uc_get_share_stats)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, diff --git a/dp/wifi3.0/dp_ipa.c b/dp/wifi3.0/dp_ipa.c index 478aab35c7..177502373d 100644 --- a/dp/wifi3.0/dp_ipa.c +++ b/dp/wifi3.0/dp_ipa.c @@ -3749,4 +3749,53 @@ QDF_STATUS dp_ipa_ast_create(struct cdp_soc_t *soc_hdl, return QDF_STATUS_SUCCESS; } #endif + +#ifdef QCA_ENHANCED_STATS_SUPPORT +/** + * dp_ipa_update_peer_rx_stats - update peer rx stats + * @soc: soc handle + * @vdev_id: vdev id + * @peer_mac: Peer Mac Address + * @nbuf: data nbuf + * + * Return: status success/failure + */ + +QDF_STATUS dp_ipa_update_peer_rx_stats(struct cdp_soc_t *soc, + uint8_t vdev_id, uint8_t *peer_mac, + qdf_nbuf_t nbuf) +{ + struct dp_peer *peer = dp_peer_find_hash_find((struct dp_soc *)soc, + peer_mac, 0, vdev_id, + DP_MOD_ID_IPA); + struct dp_txrx_peer *txrx_peer; + uint8_t da_is_bcmc; + qdf_ether_header_t *eh; + + if (!peer) + return QDF_STATUS_E_FAILURE; + + txrx_peer = dp_get_txrx_peer(peer); + + if (!txrx_peer) { + dp_peer_unref_delete(peer, DP_MOD_ID_IPA); + return QDF_STATUS_E_FAILURE; + } + + da_is_bcmc = ((uint8_t)nbuf->cb[1]) & 0x2; + eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf); + + if (da_is_bcmc) { + DP_PEER_PER_PKT_STATS_INC_PKT(txrx_peer, rx.multicast, 1, + qdf_nbuf_len(nbuf)); + if (QDF_IS_ADDR_BROADCAST(eh->ether_dhost)) + DP_PEER_PER_PKT_STATS_INC_PKT(txrx_peer, rx.bcast, + 1, qdf_nbuf_len(nbuf)); + } + + dp_peer_unref_delete(peer, DP_MOD_ID_IPA); + + return QDF_STATUS_SUCCESS; +} +#endif #endif diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 5932508d60..946067bb63 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -15059,6 +15059,9 @@ static struct cdp_ipa_ops dp_ops_ipa = { .ipa_rx_intrabss_fwd = dp_ipa_rx_intrabss_fwd, .ipa_tx_buf_smmu_mapping = dp_ipa_tx_buf_smmu_mapping, .ipa_tx_buf_smmu_unmapping = dp_ipa_tx_buf_smmu_unmapping, +#ifdef QCA_ENHANCED_STATS_SUPPORT + .ipa_update_peer_rx_stats = dp_ipa_update_peer_rx_stats, +#endif #ifdef IPA_WDS_EASYMESH_FEATURE .ipa_ast_create = dp_ipa_ast_create, #endif diff --git a/ipa/core/src/wlan_ipa_core.c b/ipa/core/src/wlan_ipa_core.c index fcfc7ab503..68f3931ada 100644 --- a/ipa/core/src/wlan_ipa_core.c +++ b/ipa/core/src/wlan_ipa_core.c @@ -1384,6 +1384,10 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, QDF_NBUF_SRC_MAC_OFFSET, QDF_MAC_ADDR_SIZE); + cdp_ipa_update_peer_rx_stats(ipa_ctx->dp_soc, + iface_context->session_id, + &peer_mac_addr.bytes[0], + skb); if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) { is_eapol_wapi = true; if (iface_context->device_mode == QDF_SAP_MODE &&