qcacmn: MLO Mcast Support for ML-Reconfig

1.Add check in Tx completion path to handle
mcast packets from all ML partner vdevs
2.Handle cases where a ML mcast vdev can be
deleted and started as NON-ML vdev and
viceversa by adding reset ML mcast conf.
3.Optimized Register configurations for Mcast
at Init/Delete and Start/Stop AP

Change-Id: Iab8a5a081e2e0377509574d362754d32c5b83df2
CRs-Fixed: 3350350
This commit is contained in:
Kenvish Butani
2022-11-01 22:39:36 -07:00
committed by Madan Koyyalamudi
parent 3bae1f975c
commit 069ca18f58
7 changed files with 86 additions and 82 deletions

View File

@@ -1462,6 +1462,7 @@ enum cdp_pdev_bpr_param {
* @CDP_SKIP_BAR_UPDATE_AP: enable/disable bar * @CDP_SKIP_BAR_UPDATE_AP: enable/disable bar
* @CDP_UPDATE_DSCP_TO_TID_MAP: Set DSCP to TID map id * @CDP_UPDATE_DSCP_TO_TID_MAP: Set DSCP to TID map id
* @CDP_SET_MCAST_VDEV: Set primary mcast vdev * @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_SET_MCAST_VDEV_HW_UPDATE: Not in use
* @CDP_DROP_3ADDR_MCAST: enable/disable drop 3addr multicast flag * @CDP_DROP_3ADDR_MCAST: enable/disable drop 3addr multicast flag
* @CDP_ENABLE_WRAP: qwrap ap * @CDP_ENABLE_WRAP: qwrap ap
@@ -1505,6 +1506,7 @@ enum cdp_vdev_param_type {
#endif #endif
CDP_UPDATE_DSCP_TO_TID_MAP, CDP_UPDATE_DSCP_TO_TID_MAP,
CDP_SET_MCAST_VDEV, CDP_SET_MCAST_VDEV,
CDP_RESET_MLO_MCAST_VDEV,
CDP_SET_MCAST_VDEV_HW_UPDATE, CDP_SET_MCAST_VDEV_HW_UPDATE,
CDP_DROP_3ADDR_MCAST, CDP_DROP_3ADDR_MCAST,
CDP_ENABLE_WRAP, CDP_ENABLE_WRAP,

View File

@@ -674,14 +674,12 @@ dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
be_vdev->mcast_primary = false; be_vdev->mcast_primary = false;
be_vdev->seq_num = 0; 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->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, hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
vdev->vdev_id, vdev->vdev_id,
HAL_TX_MCAST_CTRL_FW_EXCEPTION); 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_vdev_mcast_ctrl_set(hal_soc, vdev_id,
HAL_TX_MCAST_CTRL_MEC_NOTIFY); HAL_TX_MCAST_CTRL_MEC_NOTIFY);
} else if (vdev->opmode == wlan_op_mode_ap) { } 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 (vdev->mlo_vdev) {
if (be_vdev->mcast_primary) { hal_tx_vdev_mcast_ctrl_set(
hal_tx_vdev_mcast_ctrl_set(hal_soc, vdev_id, hal_soc,
vdev_id,
HAL_TX_MCAST_CTRL_NO_SPECIAL); HAL_TX_MCAST_CTRL_NO_SPECIAL);
} else {
hal_tx_vdev_mcast_ctrl_set(hal_soc, 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);
}
} else {
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
vdev_id, vdev_id,
HAL_TX_MCAST_CTRL_FW_EXCEPTION); 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( 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) 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( struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(
be_vdev->vdev.pdev->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; 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) { 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_mcast_mlo_iter_ptnr_vdev(be_soc, be_vdev,
dp_mlo_mcast_reset_pri_mcast, dp_mlo_mcast_reset_pri_mcast,
(void *)&be_vdev->mcast_primary, (void *)&be_vdev->mcast_primary,
DP_MOD_ID_TX_MCAST); 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 * dp_txrx_get_vdev_mcast_param_be() - Target specific ops for getting vdev
* params related to multicast * params related to multicast
@@ -2105,7 +2103,13 @@ QDF_STATUS dp_txrx_get_vdev_mcast_param_be(struct dp_soc *soc,
} }
#else #else
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be( 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) 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); dp_tx_update_bank_profile(be_soc, be_vdev);
break; break;
case CDP_SET_MCAST_VDEV: 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; break;
default: default:
dp_warn("invalid param %d", param); 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_tx_mcast_handler = dp_tx_mlo_mcast_handler_be;
arch_ops->dp_rx_mcast_handler = dp_rx_mlo_igmp_handler; 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 */ #else /* WLAN_MCAST_MLO */
static inline void static inline void

View File

@@ -685,21 +685,6 @@ dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc, struct dp_vdev *vdev,
} }
#endif #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 void
dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev, dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
struct dp_vdev *ptnr_vdev, struct dp_vdev *ptnr_vdev,
@@ -770,6 +755,17 @@ void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
else else
be_vdev->seq_num++; 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 #else
static inline void static inline void
dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached, 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) qdf_nbuf_t nbuf)
{ {
} }
bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
struct dp_vdev *vdev)
{
return false;
}
#endif #endif
#ifdef CONFIG_SAWF #ifdef CONFIG_SAWF

View File

@@ -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, void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
struct dp_vdev *vdev, struct dp_vdev *vdev,
qdf_nbuf_t nbuf); 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_MCAST_MLO
#ifdef WLAN_MLO_MULTI_CHIP #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, void dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
struct dp_vdev *ptnr_vdev, struct dp_vdev *ptnr_vdev,
void *arg); 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 #endif
#endif #endif

View File

@@ -7036,30 +7036,12 @@ static inline void dp_vdev_register_rx_eapol(struct dp_vdev *vdev,
#endif #endif
#ifdef WLAN_FEATURE_11BE_MLO #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, static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,
struct cdp_vdev_info *vdev_info) struct cdp_vdev_info *vdev_info)
{ {
if (vdev_info->mld_mac_addr) if (vdev_info->mld_mac_addr)
qdf_mem_copy(&vdev->mld_mac_addr.raw[0], qdf_mem_copy(&vdev->mld_mac_addr.raw[0],
vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE); vdev_info->mld_mac_addr, QDF_MAC_ADDR_SIZE);
dp_vdev_save_mld_info(vdev, vdev_info);
} }
#else #else
static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev, static inline void dp_vdev_save_mld_addr(struct dp_vdev *vdev,

View File

@@ -5470,7 +5470,8 @@ dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc)
struct dp_vdev *vdev = NULL; struct dp_vdev *vdev = NULL;
if (desc->tx_status == HAL_TX_TQM_RR_MULTICAST_DROP) { 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; return false;
vdev = dp_vdev_get_ref_by_id(soc, desc->vdev_id, 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); desc->id);
return false; 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, DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1,
qdf_nbuf_len(desc->nbuf)); qdf_nbuf_len(desc->nbuf));
soc->arch_ops.dp_tx_mcast_handler(soc, vdev, desc->nbuf); soc->arch_ops.dp_tx_mcast_handler(soc, vdev, desc->nbuf);

View File

@@ -1971,6 +1971,8 @@ struct dp_arch_ops {
qdf_nbuf_t nbuf); qdf_nbuf_t nbuf);
bool (*dp_rx_mcast_handler)(struct dp_soc *soc, struct dp_vdev *vdev, bool (*dp_rx_mcast_handler)(struct dp_soc *soc, struct dp_vdev *vdev,
struct dp_txrx_peer *peer, qdf_nbuf_t nbuf); struct dp_txrx_peer *peer, qdf_nbuf_t nbuf);
bool (*dp_tx_is_mcast_primary)(struct dp_soc *soc,
struct dp_vdev *vdev);
#endif #endif
struct dp_soc * (*dp_soc_get_by_idle_bm_id)(struct dp_soc *soc, struct dp_soc * (*dp_soc_get_by_idle_bm_id)(struct dp_soc *soc,
uint8_t bm_id); uint8_t bm_id);