diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 7acdef2068..31491d86ee 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -1462,6 +1462,7 @@ enum cdp_pdev_bpr_param { * @CDP_SKIP_BAR_UPDATE_AP: enable/disable bar * @CDP_UPDATE_DSCP_TO_TID_MAP: Set DSCP to TID map id * @CDP_SET_MCAST_VDEV: Set primary mcast vdev + * @CDP_RESET_MLO_MCAST_VDEV: Reset mlo mcast vdev settings * @CDP_SET_MCAST_VDEV_HW_UPDATE: Not in use * @CDP_DROP_3ADDR_MCAST: enable/disable drop 3addr multicast flag * @CDP_ENABLE_WRAP: qwrap ap @@ -1505,6 +1506,7 @@ enum cdp_vdev_param_type { #endif CDP_UPDATE_DSCP_TO_TID_MAP, CDP_SET_MCAST_VDEV, + CDP_RESET_MLO_MCAST_VDEV, CDP_SET_MCAST_VDEV_HW_UPDATE, CDP_DROP_3ADDR_MCAST, CDP_ENABLE_WRAP, diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index ff55d0c830..544c1ff134 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -674,17 +674,15 @@ dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev) be_vdev->mcast_primary = false; be_vdev->seq_num = 0; - dp_tx_mcast_mlo_reinject_routing_set(soc, - (void *)&be_vdev->mcast_primary); + + hal_tx_mcast_mlo_reinject_routing_set( + soc->hal_soc, + HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY); + if (vdev->opmode == wlan_op_mode_ap) { - if (vdev->mlo_vdev) - hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, - vdev->vdev_id, - HAL_TX_MCAST_CTRL_DROP); - else - hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, - vdev->vdev_id, - HAL_TX_MCAST_CTRL_FW_EXCEPTION); + hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, + vdev->vdev_id, + HAL_TX_MCAST_CTRL_FW_EXCEPTION); } } @@ -2000,22 +1998,16 @@ static void dp_reconfig_tx_vdev_mcast_ctrl_be(struct dp_soc *soc, hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, HAL_TX_MCAST_CTRL_MEC_NOTIFY); } else if (vdev->opmode == wlan_op_mode_ap) { + hal_tx_mcast_mlo_reinject_routing_set( + hal_soc, + HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY); if (vdev->mlo_vdev) { - if (be_vdev->mcast_primary) { - hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, - HAL_TX_MCAST_CTRL_NO_SPECIAL); - hal_tx_vdev_mcast_ctrl_set(hal_soc, - vdev_id + 128, - HAL_TX_MCAST_CTRL_FW_EXCEPTION); - dp_mcast_mlo_iter_ptnr_soc(be_soc, - dp_tx_mcast_mlo_reinject_routing_set, - (void *)&be_vdev->mcast_primary); - } else { - hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, - HAL_TX_MCAST_CTRL_DROP); - } + hal_tx_vdev_mcast_ctrl_set( + hal_soc, + vdev_id, + HAL_TX_MCAST_CTRL_NO_SPECIAL); } else { - hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, + hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, HAL_TX_MCAST_CTRL_FW_EXCEPTION); } @@ -2052,34 +2044,40 @@ static void dp_mlo_mcast_reset_pri_mcast(struct dp_vdev_be *be_vdev, } static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( - struct dp_vdev_be *be_vdev, + struct dp_vdev *vdev, cdp_config_param_type val) { + struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc( be_vdev->vdev.pdev->soc); - hal_soc_handle_t hal_soc = be_vdev->vdev.pdev->soc->hal_soc; - uint8_t vdev_id = be_vdev->vdev.vdev_id; be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev; + vdev->mlo_vdev = true; + hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, + vdev->vdev_id, + HAL_TX_MCAST_CTRL_NO_SPECIAL); if (be_vdev->mcast_primary) { - hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, - HAL_TX_MCAST_CTRL_NO_SPECIAL); - hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id + 128, - HAL_TX_MCAST_CTRL_FW_EXCEPTION); - dp_mcast_mlo_iter_ptnr_soc(be_soc, - dp_tx_mcast_mlo_reinject_routing_set, - (void *)&be_vdev->mcast_primary); dp_mcast_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_mlo_mcast_reset_pri_mcast, (void *)&be_vdev->mcast_primary, DP_MOD_ID_TX_MCAST); - } else { - hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, - HAL_TX_MCAST_CTRL_DROP); } } +static void dp_txrx_reset_mlo_mcast_primary_vdev_param_be( + struct dp_vdev *vdev, + cdp_config_param_type val) +{ + struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); + + be_vdev->mcast_primary = false; + vdev->mlo_vdev = false; + hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, + vdev->vdev_id, + HAL_TX_MCAST_CTRL_FW_EXCEPTION); +} + /** * dp_txrx_get_vdev_mcast_param_be() - Target specific ops for getting vdev * params related to multicast @@ -2105,7 +2103,13 @@ QDF_STATUS dp_txrx_get_vdev_mcast_param_be(struct dp_soc *soc, } #else static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( - struct dp_vdev_be *be_vdev, + struct dp_vdev *vdev, + cdp_config_param_type val) +{ +} + +static void dp_txrx_reset_mlo_mcast_primary_vdev_param_be( + struct dp_vdev *vdev, cdp_config_param_type val) { } @@ -2165,7 +2169,10 @@ QDF_STATUS dp_txrx_set_vdev_param_be(struct dp_soc *soc, dp_tx_update_bank_profile(be_soc, be_vdev); break; case CDP_SET_MCAST_VDEV: - dp_txrx_set_mlo_mcast_primary_vdev_param_be(be_vdev, val); + dp_txrx_set_mlo_mcast_primary_vdev_param_be(vdev, val); + break; + case CDP_RESET_MLO_MCAST_VDEV: + dp_txrx_reset_mlo_mcast_primary_vdev_param_be(vdev, val); break; default: dp_warn("invalid param %d", param); @@ -2273,6 +2280,7 @@ dp_initialize_arch_ops_be_mcast_mlo(struct dp_arch_ops *arch_ops) { arch_ops->dp_tx_mcast_handler = dp_tx_mlo_mcast_handler_be; arch_ops->dp_rx_mcast_handler = dp_rx_mlo_igmp_handler; + arch_ops->dp_tx_is_mcast_primary = dp_tx_mlo_is_mcast_primary_be; } #else /* WLAN_MCAST_MLO */ static inline void diff --git a/dp/wifi3.0/be/dp_be_tx.c b/dp/wifi3.0/be/dp_be_tx.c index b6811b4c79..e2c6992b31 100644 --- a/dp/wifi3.0/be/dp_be_tx.c +++ b/dp/wifi3.0/be/dp_be_tx.c @@ -685,21 +685,6 @@ dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc, struct dp_vdev *vdev, } #endif -void dp_tx_mcast_mlo_reinject_routing_set(struct dp_soc *soc, void *arg) -{ - hal_soc_handle_t hal_soc = soc->hal_soc; - uint8_t *cmd = (uint8_t *)arg; - - if (*cmd) - hal_tx_mcast_mlo_reinject_routing_set( - hal_soc, - HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY); - else - hal_tx_mcast_mlo_reinject_routing_set( - hal_soc, - HAL_TX_MCAST_MLO_REINJECT_FW_NOTIFY); -} - void dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev, struct dp_vdev *ptnr_vdev, @@ -770,6 +755,17 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc, else be_vdev->seq_num++; } + +bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc, + struct dp_vdev *vdev) +{ + struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); + + if (be_vdev->mcast_primary) + return true; + + return false; +} #else static inline void dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached, @@ -786,6 +782,12 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc, qdf_nbuf_t nbuf) { } + +bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc, + struct dp_vdev *vdev) +{ + return false; +} #endif #ifdef CONFIG_SAWF diff --git a/dp/wifi3.0/be/dp_be_tx.h b/dp/wifi3.0/be/dp_be_tx.h index 6492dab71e..8ed07f0a71 100644 --- a/dp/wifi3.0/be/dp_be_tx.h +++ b/dp/wifi3.0/be/dp_be_tx.h @@ -240,6 +240,17 @@ int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota); void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc, struct dp_vdev *vdev, qdf_nbuf_t nbuf); + +/** + * dp_tx_mlo_is_mcast_primary_be() - Function to check for primary mcast vdev + * @soc: Handle to DP Soc structure + * @vdev: DP vdev handle + * + * Return: True if vdev is mcast primary + * False for all othercase + */ +bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc, + struct dp_vdev *vdev); #ifdef WLAN_MCAST_MLO #ifdef WLAN_MLO_MULTI_CHIP /** @@ -253,15 +264,6 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc, void dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev, struct dp_vdev *ptnr_vdev, void *arg); - -/** - * dp_tx_mcast_mlo_reinject_routing_set() - mlo mcast reinject routing handler - * @be_vdev: Handle to DP be_vdev structure - * @cmd: cmd to set TQM/FW based reinjection - * - * Return: None - */ -void dp_tx_mcast_mlo_reinject_routing_set(struct dp_soc *soc, void *arg); #endif #endif #endif diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 882336b676..191a3787a7 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -7036,30 +7036,12 @@ static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev, #endif #ifdef WLAN_FEATURE_11BE_MLO -#if defined(WLAN_MLO_MULTI_CHIP) && defined(WLAN_MCAST_MLO) -static inline void dp_vdev_save_mld_info(struct dp_vdev *vdev, - struct cdp_vdev_info *vdev_info) -{ - if (qdf_is_macaddr_zero((struct qdf_mac_addr *)vdev_info->mld_mac_addr)) - vdev->mlo_vdev = false; - else - vdev->mlo_vdev = true; -} -#else -static inline void dp_vdev_save_mld_info(struct dp_vdev *vdev, - struct cdp_vdev_info *vdev_info) -{ -} -#endif static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev, struct cdp_vdev_info *vdev_info) { if (vdev_info->mld_mac_addr) qdf_mem_copy(&vdev->mld_mac_addr.raw[0], vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE); - - dp_vdev_save_mld_info(vdev, vdev_info); - } #else static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev, diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index d6cd1be410..571c019819 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -5470,7 +5470,8 @@ dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc) struct dp_vdev *vdev = NULL; if (desc->tx_status == HAL_TX_TQM_RR_MULTICAST_DROP) { - if (!soc->arch_ops.dp_tx_mcast_handler) + if (!soc->arch_ops.dp_tx_mcast_handler || + !soc->arch_ops.dp_tx_is_mcast_primary) return false; vdev = dp_vdev_get_ref_by_id(soc, desc->vdev_id, @@ -5481,6 +5482,11 @@ dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc) desc->id); return false; } + + if (!(soc->arch_ops.dp_tx_is_mcast_primary(soc, vdev))) { + dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_REINJECT); + return false; + } DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1, qdf_nbuf_len(desc->nbuf)); soc->arch_ops.dp_tx_mcast_handler(soc, vdev, desc->nbuf); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index c9383bf8c5..ef4a99099e 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1971,6 +1971,8 @@ struct dp_arch_ops { qdf_nbuf_t nbuf); bool (*dp_rx_mcast_handler)(struct dp_soc *soc, struct dp_vdev *vdev, struct dp_txrx_peer *peer, qdf_nbuf_t nbuf); + bool (*dp_tx_is_mcast_primary)(struct dp_soc *soc, + struct dp_vdev *vdev); #endif struct dp_soc * (*dp_soc_get_by_idle_bm_id)(struct dp_soc *soc, uint8_t bm_id);