From a7af20587047abb52814db7b5d0887007dbf6919 Mon Sep 17 00:00:00 2001 From: Sai Rupesh Chevuru Date: Tue, 27 Jun 2023 17:11:08 +0530 Subject: [PATCH] qcacmn: populate the bridge vap in partner list populate the bridge vap in partner list Change-Id: Ie7c0ebc3b796f2b57e7837577079dcd1d4faac45 CRs-Fixed: 3550201 --- dp/inc/cdp_txrx_cmn_struct.h | 4 ++ dp/wifi3.0/be/dp_be.c | 17 ++++-- dp/wifi3.0/be/dp_be.h | 6 +- dp/wifi3.0/be/dp_be_tx.c | 13 +++-- dp/wifi3.0/be/mlo/dp_mlo.c | 104 ++++++++++++++++++++++++++++++++--- dp/wifi3.0/dp_main.c | 28 ++++++++++ dp/wifi3.0/dp_types.h | 10 +++- 7 files changed, 160 insertions(+), 22 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 24e497c4a3..a87172b3f3 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -750,6 +750,7 @@ enum wlan_op_subtype { * @subtype: subtype of the vdev * @qdf_opmode: Operation mode of the vdev * @mld_mac_addr: MLD mac addr of the current vdev. + * @is_bridge_vap: current vdev is bridge vap or not. */ struct cdp_vdev_info { uint8_t *vdev_mac_addr; @@ -760,6 +761,9 @@ struct cdp_vdev_info { enum QDF_OPMODE qdf_opmode; #ifdef WLAN_FEATURE_11BE_MLO uint8_t *mld_mac_addr; +#ifdef WLAN_MLO_MULTI_CHIP + bool is_bridge_vap; +#endif #endif }; diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index ed10243bdf..36e51e2915 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -927,7 +927,7 @@ dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev) be_vdev->seq_num = 0; be_vdev->mcast_primary = false; - vdev->mlo_vdev = false; + vdev->mlo_vdev = 0; } #else @@ -948,6 +948,9 @@ static void dp_mlo_init_ptnr_list(struct dp_vdev *vdev) qdf_mem_set(be_vdev->partner_vdev_list, WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC, CDP_INVALID_VDEV_ID); + qdf_mem_set(be_vdev->bridge_vdev_list, + WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC, + CDP_INVALID_VDEV_ID); } static void dp_get_rx_hash_key_be(struct dp_soc *soc, @@ -2413,7 +2416,7 @@ static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( be_vdev->vdev.pdev->soc); be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev; - vdev->mlo_vdev = true; + vdev->mlo_vdev = 1; if (be_vdev->mcast_primary) { struct cdp_txrx_peer_params_update params = {0}; @@ -2421,7 +2424,8 @@ static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( dp_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_mlo_mcast_reset_pri_mcast, (void *)&be_vdev->mcast_primary, - DP_MOD_ID_TX_MCAST); + DP_MOD_ID_TX_MCAST, + DP_LINK_VDEV_ITER); params.chip_id = be_soc->mlo_chip_id; params.pdev_id = be_vdev->vdev.pdev->pdev_id; @@ -2454,7 +2458,7 @@ static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( be_vdev->vdev.pdev->soc); be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev; - vdev->mlo_vdev = true; + vdev->mlo_vdev = 1; hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, vdev->vdev_id, HAL_TX_MCAST_CTRL_NO_SPECIAL); @@ -2465,7 +2469,8 @@ static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( dp_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_mlo_mcast_reset_pri_mcast, (void *)&be_vdev->mcast_primary, - DP_MOD_ID_TX_MCAST); + DP_MOD_ID_TX_MCAST, + DP_LINK_VDEV_ITER); params.chip_id = be_soc->mlo_chip_id; params.pdev_id = vdev->pdev->pdev_id; @@ -2486,7 +2491,7 @@ static void dp_txrx_reset_mlo_mcast_primary_vdev_param_be( struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev); be_vdev->mcast_primary = false; - vdev->mlo_vdev = false; + vdev->mlo_vdev = 0; hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc, vdev->vdev_id, HAL_TX_MCAST_CTRL_FW_EXCEPTION); diff --git a/dp/wifi3.0/be/dp_be.h b/dp/wifi3.0/be/dp_be.h index 03ef113bae..c3dccbba6c 100644 --- a/dp/wifi3.0/be/dp_be.h +++ b/dp/wifi3.0/be/dp_be.h @@ -402,6 +402,7 @@ struct dp_pdev_be { * @bank_id: bank_id to be used for TX * @vdev_id_check_en: flag if HW vdev_id check is enabled for vdev * @partner_vdev_list: partner list used for Intra-BSS + * @bridge_vdev_list: partner bridge vdev list * @mlo_stats: structure to hold stats for mlo unmapped peers * @seq_num: DP MLO seq number * @mcast_primary: MLO Mcast primary vdev @@ -412,6 +413,7 @@ struct dp_vdev_be { uint8_t vdev_id_check_en; #ifdef WLAN_MLO_MULTI_CHIP uint8_t partner_vdev_list[WLAN_MAX_MLO_CHIPS][WLAN_MAX_MLO_LINKS_PER_SOC]; + uint8_t bridge_vdev_list[WLAN_MAX_MLO_CHIPS][WLAN_MAX_MLO_LINKS_PER_SOC]; struct cdp_vdev_stats mlo_stats; #ifdef WLAN_FEATURE_11BE_MLO #ifdef WLAN_MCAST_MLO @@ -531,13 +533,15 @@ typedef void dp_ptnr_vdev_iter_func(struct dp_vdev_be *be_vdev, * @func: function to be called for each peer * @arg: argument need to be passed to func * @mod_id: module id + * @type: iterate type * * Return: None */ void dp_mlo_iter_ptnr_vdev(struct dp_soc_be *be_soc, struct dp_vdev_be *be_vdev, dp_ptnr_vdev_iter_func func, void *arg, - enum dp_mod_id mod_id); + enum dp_mod_id mod_id, + uint8_t type); #endif #ifdef WLAN_MCAST_MLO diff --git a/dp/wifi3.0/be/dp_be_tx.c b/dp/wifi3.0/be/dp_be_tx.c index c6412b0085..db655d1c85 100644 --- a/dp/wifi3.0/be/dp_be_tx.c +++ b/dp/wifi3.0/be/dp_be_tx.c @@ -661,7 +661,8 @@ dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc, if (mpass_buf.vlan_id == INVALID_VLAN_ID) { dp_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_tx_mlo_mcast_multipass_lookup, - &mpass_buf, DP_MOD_ID_TX); + &mpass_buf, DP_MOD_ID_TX, + DP_ALL_VDEV_ITER); /* * Do not drop the frame when vlan_id doesn't match. * Send the frame as it is. @@ -696,7 +697,8 @@ dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc, /* send frame on partner vdevs */ dp_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_tx_mlo_mcast_multipass_send, - &mpass_buf_copy, DP_MOD_ID_TX); + &mpass_buf_copy, DP_MOD_ID_TX, + DP_LINK_VDEV_ITER); /* send frame on mcast primary vdev */ dp_tx_mlo_mcast_multipass_send(be_vdev, vdev, &mpass_buf_copy); @@ -709,7 +711,7 @@ dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc, dp_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_tx_mlo_mcast_multipass_send, - &mpass_buf, DP_MOD_ID_TX); + &mpass_buf, DP_MOD_ID_TX, DP_LINK_VDEV_ITER); dp_tx_mlo_mcast_multipass_send(be_vdev, vdev, &mpass_buf); if (qdf_unlikely(be_vdev->seq_num > MAX_GSN_NUM)) @@ -804,7 +806,7 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc, /* send frame on partner vdevs */ dp_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_tx_mlo_mcast_pkt_send, - nbuf, DP_MOD_ID_REINJECT); + nbuf, DP_MOD_ID_REINJECT, DP_LINK_VDEV_ITER); /* send frame on mcast primary vdev */ dp_tx_mlo_mcast_pkt_send(be_vdev, vdev, nbuf); @@ -887,7 +889,8 @@ dp_tx_mlo_mcast_send_be(struct dp_soc *soc, struct dp_vdev *vdev, if (qdf_unlikely(!dp_tx_mcast_enhance(vdev, nbuf))) { dp_mlo_iter_ptnr_vdev(be_soc, be_vdev, dp_tx_mlo_mcast_enhance_be, - nbuf, DP_MOD_ID_TX); + nbuf, DP_MOD_ID_TX, + DP_ALL_VDEV_ITER); qdf_nbuf_free(nbuf); return NULL; } diff --git a/dp/wifi3.0/be/mlo/dp_mlo.c b/dp/wifi3.0/be/mlo/dp_mlo.c index ffbb904df5..329613a67a 100644 --- a/dp/wifi3.0/be/mlo/dp_mlo.c +++ b/dp/wifi3.0/be/mlo/dp_mlo.c @@ -321,12 +321,21 @@ static QDF_STATUS dp_mlo_add_ptnr_vdev(struct dp_vdev *vdev1, struct dp_vdev_be *vdev2_be = dp_get_be_vdev_from_dp_vdev(vdev2); /* return when valid entry exists */ - if (vdev2_be->partner_vdev_list[soc_be->mlo_chip_id][pdev_id] != + if (vdev1->is_bridge_vdev) { + if (vdev2_be->bridge_vdev_list[soc_be->mlo_chip_id][pdev_id] != CDP_INVALID_VDEV_ID) - return QDF_STATUS_SUCCESS; + return QDF_STATUS_SUCCESS; - vdev2_be->partner_vdev_list[soc_be->mlo_chip_id][pdev_id] = + vdev2_be->bridge_vdev_list[soc_be->mlo_chip_id][pdev_id] = vdev1->vdev_id; + } else { + if (vdev2_be->partner_vdev_list[soc_be->mlo_chip_id][pdev_id] != + CDP_INVALID_VDEV_ID) + return QDF_STATUS_SUCCESS; + + vdev2_be->partner_vdev_list[soc_be->mlo_chip_id][pdev_id] = + vdev1->vdev_id; + } mlo_debug("Add vdev%d to vdev%d list, mlo_chip_id = %d pdev_id = %d\n", vdev1->vdev_id, vdev2->vdev_id, soc_be->mlo_chip_id, pdev_id); @@ -451,8 +460,12 @@ void dp_clr_mlo_ptnr_list(struct dp_soc *soc, struct dp_vdev *vdev) /* remove self vdev from partner list */ pr_vdev_be = dp_get_be_vdev_from_dp_vdev(pr_vdev); - pr_vdev_be->partner_vdev_list[soc_id][pdev_id] = - CDP_INVALID_VDEV_ID; + if (vdev->is_bridge_vdev) + pr_vdev_be->bridge_vdev_list[soc_id][pdev_id] = + CDP_INVALID_VDEV_ID; + else + pr_vdev_be->partner_vdev_list[soc_id][pdev_id] = + CDP_INVALID_VDEV_ID; /* remove partner vdev from self list */ pr_pdev = pr_vdev->pdev; @@ -462,6 +475,47 @@ void dp_clr_mlo_ptnr_list(struct dp_soc *soc, struct dp_vdev *vdev) dp_vdev_unref_delete(pr_soc, pr_vdev, DP_MOD_ID_RX); } } + + for (i = 0; i < WLAN_MAX_MLO_CHIPS; i++) { + for (j = 0; j < WLAN_MAX_MLO_LINKS_PER_SOC; j++) { + struct dp_vdev *pr_vdev = NULL; + struct dp_soc *pr_soc = NULL; + struct dp_soc_be *pr_soc_be = NULL; + struct dp_pdev *pr_pdev = NULL; + struct dp_vdev_be *pr_vdev_be = NULL; + + if (vdev_be->bridge_vdev_list[i][j] == + CDP_INVALID_VDEV_ID) + continue; + + pr_soc = dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i); + if (!pr_soc) + continue; + pr_soc_be = dp_get_be_soc_from_dp_soc(pr_soc); + pr_vdev = dp_vdev_get_ref_by_id( + pr_soc, + vdev_be->bridge_vdev_list[i][j], + DP_MOD_ID_RX); + if (!pr_vdev) + continue; + + /* remove self vdev from partner list */ + pr_vdev_be = dp_get_be_vdev_from_dp_vdev(pr_vdev); + if (vdev->is_bridge_vdev) + pr_vdev_be->bridge_vdev_list[soc_id][pdev_id] = + CDP_INVALID_VDEV_ID; + else + pr_vdev_be->partner_vdev_list[soc_id][pdev_id] = + CDP_INVALID_VDEV_ID; + + /* remove partner vdev from self list */ + pr_pdev = pr_vdev->pdev; + vdev_be->bridge_vdev_list[pr_soc_be->mlo_chip_id][pr_pdev->pdev_id] = + CDP_INVALID_VDEV_ID; + + dp_vdev_unref_delete(pr_soc, pr_vdev, DP_MOD_ID_RX); + } + } } static QDF_STATUS @@ -810,7 +864,8 @@ static QDF_STATUS dp_mlo_get_mld_vdev_stats(struct cdp_soc_t *soc_hdl, dp_mlo_iter_ptnr_vdev(be_soc, vdev_be, dp_mlo_aggr_ptnr_iface_stats_mlo_links, buf, - DP_MOD_ID_GENERIC_STATS); + DP_MOD_ID_GENERIC_STATS, + DP_ALL_VDEV_ITER); } else { dp_aggregate_interface_stats(vdev, buf); @@ -820,7 +875,8 @@ static QDF_STATUS dp_mlo_get_mld_vdev_stats(struct cdp_soc_t *soc_hdl, /* Aggregate stats from partner vdevs */ dp_mlo_iter_ptnr_vdev(be_soc, vdev_be, dp_mlo_aggr_ptnr_iface_stats, buf, - DP_MOD_ID_GENERIC_STATS); + DP_MOD_ID_GENERIC_STATS, + DP_ALL_VDEV_ITER); } complete: @@ -1141,13 +1197,20 @@ void dp_mlo_iter_ptnr_vdev(struct dp_soc_be *be_soc, struct dp_vdev_be *be_vdev, dp_ptnr_vdev_iter_func func, void *arg, - enum dp_mod_id mod_id) + enum dp_mod_id mod_id, + uint8_t type) { int i = 0; int j = 0; struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt; - for (i = 0; i < WLAN_MAX_MLO_CHIPS ; i++) { + if (type < DP_LINK_VDEV_ITER || type > DP_ALL_VDEV_ITER) { + dp_err("invalid iterate type"); + return; + } + + for (i = 0; (i < WLAN_MAX_MLO_CHIPS) && + IS_LINK_VDEV_ITER_REQUIRED(type); i++) { struct dp_soc *ptnr_soc = dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i); @@ -1168,6 +1231,29 @@ void dp_mlo_iter_ptnr_vdev(struct dp_soc_be *be_soc, mod_id); } } + + for (i = 0; (i < WLAN_MAX_MLO_CHIPS) && + IS_BRIDGE_VDEV_ITER_REQUIRED(type); i++) { + struct dp_soc *ptnr_soc = + dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i); + + if (!ptnr_soc) + continue; + for (j = 0 ; j < WLAN_MAX_MLO_LINKS_PER_SOC ; j++) { + struct dp_vdev *bridge_vdev; + + bridge_vdev = dp_vdev_get_ref_by_id( + ptnr_soc, + be_vdev->bridge_vdev_list[i][j], + mod_id); + if (!bridge_vdev) + continue; + (*func)(be_vdev, bridge_vdev, arg); + dp_vdev_unref_delete(bridge_vdev->pdev->soc, + bridge_vdev, + mod_id); + } + } } qdf_export_symbol(dp_mlo_iter_ptnr_vdev); diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 63d7b8ee7a..6f0b7ea61a 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3737,11 +3737,38 @@ static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev, qdf_mem_copy(&vdev->mld_mac_addr.raw[0], vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE); } + +#ifdef WLAN_MLO_MULTI_CHIP +static inline void +dp_vdev_update_bridge_vdev_param(struct dp_vdev *vdev, + struct cdp_vdev_info *vdev_info) +{ + if (vdev_info->is_bridge_vap) + vdev->is_bridge_vdev = 1; + + dp_info("is_bridge_link = %d vdev id = %d chip id = %d", + vdev->is_bridge_vdev, vdev->vdev_id, + dp_mlo_get_chip_id(vdev->pdev->soc)); +} +#else +static inline void +dp_vdev_update_bridge_vdev_param(struct dp_vdev *vdev, + struct cdp_vdev_info *vdev_info) +{ +} +#endif /* WLAN_MLO_MULTI_CHIP */ + #else static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev, struct cdp_vdev_info *vdev_info) { +} + +static inline void +dp_vdev_update_bridge_vdev_param(struct dp_vdev *vdev, + struct cdp_vdev_info *vdev_info) +{ } #endif @@ -3883,6 +3910,7 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc, qdf_mem_copy(&vdev->mac_addr.raw[0], vdev_mac_addr, QDF_MAC_ADDR_SIZE); + dp_vdev_update_bridge_vdev_param(vdev, vdev_info); dp_vdev_save_mld_addr(vdev, vdev_info); /* TODO: Initialize default HTT meta data that will be used in diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 398b975d2a..ebe82a8622 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -200,6 +200,12 @@ typedef void dp_ptnr_soc_iter_func(struct dp_soc *ptnr_soc, void *arg, #define DP_MLD_MODE_UNIFIED_BOND 1 #define DP_MLD_MODE_HYBRID_NONBOND 2 #define DP_MLD_MODE_MAX DP_MLD_MODE_HYBRID_NONBOND + +#define DP_LINK_VDEV_ITER 1 +#define DP_BRIDGE_VDEV_ITER 2 +#define DP_ALL_VDEV_ITER 3 +#define IS_LINK_VDEV_ITER_REQUIRED(type) (type & DP_LINK_VDEV_ITER) +#define IS_BRIDGE_VDEV_ITER_REQUIRED(type) (type & DP_BRIDGE_VDEV_ITER) #endif enum rx_pktlog_mode { @@ -3872,7 +3878,9 @@ struct dp_vdev { /* MLO MAC address corresponding to vdev */ union dp_align_mac_addr mld_mac_addr; #if defined(WLAN_MLO_MULTI_CHIP) && defined(WLAN_MCAST_MLO) - bool mlo_vdev; + uint8_t mlo_vdev:1, + is_bridge_vdev:1, + reserved_1:6; #endif #endif