From e94a73784afd084975db36377eaba44bb6363697 Mon Sep 17 00:00:00 2001 From: Harsh Kumar Bijlani Date: Tue, 13 Dec 2022 12:42:22 +0530 Subject: [PATCH] qcacmn: Add support to drop tx mcast frames in WDS extended mode Add support to drop tx mcast frames in WDS extended mode Change-Id: Ia5af3b31c95393eb9c8af6b92ddeced6ac7a8d3d CRs-Fixed: 3359296 --- dp/inc/cdp_txrx_cmn_struct.h | 4 ++++ dp/inc/cdp_txrx_stats_struct.h | 1 + dp/wifi3.0/dp_main.c | 10 ++++++++++ dp/wifi3.0/dp_stats.c | 9 +++++++-- dp/wifi3.0/dp_tx.c | 31 +++++++++++++++++++++++++++++++ dp/wifi3.0/dp_types.h | 1 + 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 54180efca6..bb2c854580 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -1421,6 +1421,7 @@ enum cdp_pdev_param_type { * @cdp_sawf_stats: SAWF stats config * @cdp_vdev_param_traffic_end_ind: Traffic end indication enable/disable * @cdp_skel_enable : Enable/Disable skeleton code for Umac reset debug + * @cdp_drop_tx_mcast: Enable/Disable tx mcast drop */ typedef union cdp_config_param_t { /* peer params */ @@ -1510,6 +1511,7 @@ typedef union cdp_config_param_t { bool cdp_drop_3addr_mcast; bool cdp_vdev_param_traffic_end_ind; bool cdp_umac_rst_skel; + bool cdp_drop_tx_mcast; } cdp_config_param_type; /** @@ -1587,6 +1589,7 @@ enum cdp_pdev_bpr_param { * @CDP_ENABLE_IGMP_MCAST_EN: enable/disable igmp multicast enhancement * @CDP_ENABLE_HLOS_TID_OVERRIDE: set hlos tid override flag * @CDP_CFG_WDS_EXT: enable/disable wds ext feature + * @CDP_DROP_TX_MCAST: enable/disable tx mcast drop * @CDP_ENABLE_PEER_AUTHORIZE: enable peer authorize flag * @CDP_ENABLE_PEER_TID_LATENCY: set peer tid latency enable flag * @CDP_SET_VAP_MESH_TID: Set latency tid in vap @@ -1626,6 +1629,7 @@ enum cdp_vdev_param_type { CDP_ENABLE_HLOS_TID_OVERRIDE, #ifdef QCA_SUPPORT_WDS_EXTENDED CDP_CFG_WDS_EXT, + CDP_DROP_TX_MCAST, #endif /* QCA_SUPPORT_WDS_EXTENDED */ CDP_ENABLE_PEER_AUTHORIZE, #ifdef WLAN_SUPPORT_MESH_LATENCY diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index cc27f0c072..33b29a3ee8 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -1840,6 +1840,7 @@ struct cdp_tx_ingress_stats { uint32_t fail_per_pkt_vdev_id_check; uint32_t drop_ingress; uint32_t invalid_peer_id_in_exc_path; + uint32_t tx_mcast_drop; } dropped; /* Mesh packets info */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 1b9766b716..5932508d60 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -10885,6 +10885,11 @@ static QDF_STATUS dp_get_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, case CDP_SET_MCAST_VDEV: soc->arch_ops.txrx_get_vdev_mcast_param(soc, vdev, val); break; +#ifdef QCA_SUPPORT_WDS_EXTENDED + case CDP_DROP_TX_MCAST: + val->cdp_drop_tx_mcast = vdev->drop_tx_mcast; + break; +#endif default: dp_cdp_err("%pK: param value %d is wrong", soc, param); @@ -11007,6 +11012,11 @@ dp_set_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, if (vdev->opmode == wlan_op_mode_ap) vdev->wds_ext_enabled = val.cdp_vdev_param_wds_ext; break; + case CDP_DROP_TX_MCAST: + dp_info("vdev_id %d drop tx mcast :%d", vdev_id, + val.cdp_drop_tx_mcast); + vdev->drop_tx_mcast = val.cdp_drop_tx_mcast; + break; #endif case CDP_ENABLE_PEER_AUTHORIZE: vdev->peer_authorize = val.cdp_vdev_param_peer_authorize; diff --git a/dp/wifi3.0/dp_stats.c b/dp/wifi3.0/dp_stats.c index 22fc3e56c2..0903418319 100644 --- a/dp/wifi3.0/dp_stats.c +++ b/dp/wifi3.0/dp_stats.c @@ -7488,6 +7488,8 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev) pdev->stats.tx_i.dropped.drop_ingress); DP_PRINT_STATS(" invalid peer id in exception path = %u", pdev->stats.tx_i.dropped.invalid_peer_id_in_exc_path); + DP_PRINT_STATS(" Tx Mcast Drop = %u", + pdev->stats.tx_i.dropped.tx_mcast_drop); DP_PRINT_STATS("Tx failed = %u", pdev->stats.tx.tx_failed); DP_PRINT_STATS(" FW removed Pkts = %u", @@ -8814,7 +8816,8 @@ void dp_update_vdev_ingress_stats(struct dp_vdev *tgtobj) tgtobj->stats.tx_i.dropped.res_full + tgtobj->stats.tx_i.dropped.drop_ingress + tgtobj->stats.tx_i.dropped.headroom_insufficient + - tgtobj->stats.tx_i.dropped.invalid_peer_id_in_exc_path; + tgtobj->stats.tx_i.dropped.invalid_peer_id_in_exc_path + + tgtobj->stats.tx_i.dropped.tx_mcast_drop; } void dp_update_vdev_rate_stats(struct cdp_vdev_stats *tgtobj, @@ -8866,6 +8869,7 @@ void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj, DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.drop_ingress); DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.headroom_insufficient); DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.invalid_peer_id_in_exc_path); + DP_STATS_AGGR(tgtobj, srcobj, tx_i.dropped.tx_mcast_drop); DP_STATS_AGGR(tgtobj, srcobj, tx_i.cce_classified); DP_STATS_AGGR(tgtobj, srcobj, tx_i.cce_classified_raw); DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.sniffer_rcvd); @@ -8885,7 +8889,8 @@ void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj, tgtobj->stats.tx_i.dropped.res_full + tgtobj->stats.tx_i.dropped.drop_ingress + tgtobj->stats.tx_i.dropped.headroom_insufficient + - tgtobj->stats.tx_i.dropped.invalid_peer_id_in_exc_path; + tgtobj->stats.tx_i.dropped.invalid_peer_id_in_exc_path + + tgtobj->stats.tx_i.dropped.tx_mcast_drop; } QDF_STATUS dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl, diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index d964460c6d..227d937973 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -3088,6 +3088,34 @@ static inline bool dp_tx_mcast_enhance(struct dp_vdev *vdev, qdf_nbuf_t nbuf) } #endif +#ifdef QCA_SUPPORT_WDS_EXTENDED +/** + * dp_tx_mcast_drop() - Drop mcast frame if drop_tx_mcast is set in WDS_EXT + * @vdev: vdev handle + * @nbuf: skb + * + * Return: true if frame is dropped, false otherwise + */ +static inline bool dp_tx_mcast_drop(struct dp_vdev *vdev, qdf_nbuf_t nbuf) +{ + /* Drop tx mcast and WDS Extended feature check */ + if (qdf_unlikely((vdev->drop_tx_mcast) && (vdev->wds_ext_enabled))) { + qdf_ether_header_t *eh = (qdf_ether_header_t *) + qdf_nbuf_data(nbuf); + if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost)) { + DP_STATS_INC(vdev, tx_i.dropped.tx_mcast_drop, 1); + return true; + } + } + + return false; +} +#else +static inline bool dp_tx_mcast_drop(struct dp_vdev *vdev, qdf_nbuf_t nbuf) +{ + return false; +} +#endif /** * dp_tx_per_pkt_vdev_id_check() - vdev id check for frame * @nbuf: qdf_nbuf_t @@ -3699,6 +3727,9 @@ qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, if (qdf_unlikely(!dp_tx_mcast_enhance(vdev, nbuf))) return NULL; + if (qdf_unlikely(dp_tx_mcast_drop(vdev, nbuf))) + return nbuf; + /* RAW */ if (qdf_unlikely(vdev->tx_encap_type == htt_cmn_pkt_type_raw)) { struct dp_tx_seg_info_s seg_info = {0}; diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 47e91ab7b0..d99c949c02 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -3258,6 +3258,7 @@ struct dp_vdev { #ifdef QCA_SUPPORT_WDS_EXTENDED bool wds_ext_enabled; + bool drop_tx_mcast; #endif /* QCA_SUPPORT_WDS_EXTENDED */ bool drop_3addr_mcast; #ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE