qcacmn: HW reinjection support for MLO Multicast

Enabling HW based reinjection for MLO Multicast

Change-Id: Ie9663e0e90ae1ae0a07d229fd6d4c66787d4224a
CRs-Fixed: 3142397
This commit is contained in:
Sai Rupesh Chevuru
2022-03-02 18:33:17 +05:30
committed by Madan Koyyalamudi
parent 484198b257
commit f179a624a1
11 changed files with 257 additions and 4 deletions

View File

@@ -419,6 +419,52 @@ static QDF_STATUS dp_soc_detach_be(struct dp_soc *soc)
}
#ifdef WLAN_MLO_MULTI_CHIP
#ifdef WLAN_MCAST_MLO
static inline void
dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
{
struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
be_vdev->mcast_primary = false;
be_vdev->seq_num = 0;
if (vdev->mlo_vdev)
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
vdev->vdev_id,
HAL_TX_MCAST_CTRL_DROP);
}
static inline void
dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev)
{
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);
be_vdev->seq_num = 0;
if (vdev->mlo_vdev) {
hal_tx_vdev_mcast_ctrl_set(vdev->pdev->soc->hal_soc,
vdev->vdev_id,
HAL_TX_MCAST_CTRL_FW_EXCEPTION);
vdev->mlo_vdev = false;
}
if (be_vdev->mcast_primary) {
be_vdev->mcast_primary = false;
dp_mcast_mlo_iter_ptnr_soc(be_soc,
dp_tx_mcast_mlo_reinject_routing_set,
(void *)&be_vdev->mcast_primary);
}
}
#else
static inline void
dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
{
}
static inline void
dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev)
{
}
#endif
static void dp_mlo_init_ptnr_list(struct dp_vdev *vdev)
{
struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
@@ -428,6 +474,16 @@ static void dp_mlo_init_ptnr_list(struct dp_vdev *vdev)
CDP_INVALID_VDEV_ID);
}
#else
static inline void
dp_mlo_mcast_init(struct dp_soc *soc, struct dp_vdev *vdev)
{
}
static inline void
dp_mlo_mcast_deinit(struct dp_soc *soc, struct dp_vdev *vdev)
{
}
static void dp_mlo_init_ptnr_list(struct dp_vdev *vdev)
{
}
@@ -594,6 +650,9 @@ static QDF_STATUS dp_vdev_attach_be(struct dp_soc *soc, struct dp_vdev *vdev)
HAL_TX_MCAST_CTRL_MEC_NOTIFY);
}
if (vdev->opmode == wlan_op_mode_ap)
dp_mlo_mcast_init(soc, vdev);
dp_mlo_init_ptnr_list(vdev);
return QDF_STATUS_SUCCESS;
@@ -607,6 +666,9 @@ static QDF_STATUS dp_vdev_detach_be(struct dp_soc *soc, struct dp_vdev *vdev)
if (vdev->opmode == wlan_op_mode_monitor)
return QDF_STATUS_SUCCESS;
if (vdev->opmode == wlan_op_mode_ap)
dp_mlo_mcast_deinit(soc, vdev);
dp_tx_put_bank_profile(be_soc, be_vdev);
dp_clr_mlo_ptnr_list(soc, vdev);
@@ -1403,7 +1465,22 @@ static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
struct dp_vdev_be *be_vdev,
cdp_config_param_type val)
{
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;
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
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(

View File

@@ -396,6 +396,8 @@ void dp_clr_mlo_ptnr_list(struct dp_soc *soc, struct dp_vdev *vdev);
typedef void dp_ptnr_vdev_iter_func(struct dp_vdev_be *be_vdev,
struct dp_vdev *ptnr_vdev,
void *arg);
typedef void dp_ptnr_soc_iter_func(struct dp_soc *ptnr_soc,
void *arg);
/*
* dp_mcast_mlo_iter_ptnr_vdev - API to iterate through ptnr vdev list
* @be_soc: dp_soc_be pointer
@@ -411,6 +413,17 @@ void dp_mcast_mlo_iter_ptnr_vdev(struct dp_soc_be *be_soc,
dp_ptnr_vdev_iter_func func,
void *arg,
enum dp_mod_id mod_id);
/*
* dp_mcast_mlo_iter_ptnr_soc - API to iterate through ptnr soc list
* @be_soc: dp_soc_be pointer
* @func : function to be called for each peer
* @arg : argument need to be passed to func
*
* Return: None
*/
void dp_mcast_mlo_iter_ptnr_soc(struct dp_soc_be *be_soc,
dp_ptnr_soc_iter_func func,
void *arg);
/*
* dp_mlo_get_mcast_primary_vdev- get ref to mcast primary vdev
* @be_soc: dp_soc_be pointer

View File

@@ -1109,10 +1109,12 @@ bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
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(soc);
if (!(qdf_nbuf_is_ipv4_igmp_pkt(buf) ||
qdf_nbuf_is_ipv6_igmp_pkt(buf)))
if (!(qdf_nbuf_is_ipv4_igmp_pkt(nbuf) ||
qdf_nbuf_is_ipv6_igmp_pkt(nbuf)))
return false;
qdf_nbuf_set_next(nbuf, NULL);
if (vdev->mcast_enhancement_en || be_vdev->mcast_primary)
goto send_pkt;
@@ -1143,7 +1145,7 @@ send_pkt:
#else
bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
struct dp_txrx_peer *peer,
qdf_nbuf_t nbuf)
{
return false;

View File

@@ -237,7 +237,7 @@ dp_rx_replensih_soc_get(struct dp_soc *soc, uint8_t reo_ring_num)
*/
bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
struct dp_vdev *vdev,
struct dp_peer *peer,
struct dp_txrx_peer *peer,
qdf_nbuf_t nbuf);
/**

View File

@@ -416,6 +416,21 @@ dp_tx_set_min_rates_for_critical_frames(struct dp_soc *soc,
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
defined(WLAN_MCAST_MLO)
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,

View File

@@ -181,6 +181,15 @@ 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

View File

@@ -540,6 +540,25 @@ dp_rx_replensih_soc_get(struct dp_soc *soc, uint8_t reo_ring_num)
}
#ifdef WLAN_MCAST_MLO
void dp_mcast_mlo_iter_ptnr_soc(struct dp_soc_be *be_soc,
dp_ptnr_soc_iter_func func,
void *arg)
{
int i = 0;
struct dp_mlo_ctxt *dp_mlo = be_soc->ml_ctxt;
for (i = 0; i < WLAN_MAX_MLO_CHIPS ; i++) {
struct dp_soc *ptnr_soc =
dp_mlo_get_soc_ref_by_chip_id(dp_mlo, i);
if (!ptnr_soc)
continue;
(*func)(ptnr_soc, arg);
}
}
qdf_export_symbol(dp_mcast_mlo_iter_ptnr_soc);
void dp_mcast_mlo_iter_ptnr_vdev(struct dp_soc_be *be_soc,
struct dp_vdev_be *be_vdev,
dp_ptnr_vdev_iter_func func,

View File

@@ -6428,12 +6428,30 @@ 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,

View File

@@ -4792,6 +4792,49 @@ void dp_tx_prefetch_next_nbuf_data(struct dp_tx_desc_s *next)
}
#endif
/**
* dp_tx_mcast_reinject_handler() - Tx reinjected multicast packets handler
* @soc: core txrx main context
* @desc: software descriptor
*
* Return: true when packet is reinjected
*/
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
defined(WLAN_MCAST_MLO)
static inline bool
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)
return false;
vdev = dp_vdev_get_ref_by_id(soc, desc->vdev_id,
DP_MOD_ID_TX_COMP);
if (qdf_unlikely(!vdev)) {
dp_tx_comp_info_rl("Unable to get vdev ref %d",
desc->id);
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);
dp_tx_desc_release(desc, desc->pool_id);
return true;
}
return false;
}
#else
static inline bool
dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc)
{
return false;
}
#endif
/**
* dp_tx_comp_process_desc_list() - Tx complete software descriptor handler
* @soc: core txrx main context
@@ -4832,6 +4875,10 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
DP_MOD_ID_TX_COMP);
}
if (dp_tx_mcast_reinject_handler(soc, desc)) {
desc = next;
continue;
}
if (qdf_likely(desc->flags & DP_TX_DESC_FLAG_SIMPLE)) {
struct dp_pdev *pdev = desc->pdev;
@@ -4855,6 +4902,7 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
desc = next;
continue;
}
hal_tx_comp_get_status(&desc->comp, &ts, soc->hal_soc);
dp_tx_comp_process_tx_status(soc, desc, &ts, txrx_peer,

View File

@@ -2996,6 +2996,9 @@ struct dp_vdev {
#ifdef WLAN_FEATURE_11BE_MLO
/* 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;
#endif
#endif
/* node in the pdev's list of vdevs */

View File

@@ -83,6 +83,16 @@ enum hal_tx_notify_frame_type {
TX_SEMI_HARD_NOTIFY_E = 3
};
/**
* enum hal_tx_mcast_mlo_reinject_notify
* @HAL_TX_MCAST_MLO_REINJECT_FW_NOTIFY: MLO Mcast reinject routed to FW
* @HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY: MLO Mcast reinject routed to TQM
*/
enum hal_tx_mcast_mlo_reinject_notify {
HAL_TX_MCAST_MLO_REINJECT_FW_NOTIFY = 0,
HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY,
};
/*---------------------------------------------------------------------------
* Structures
* ---------------------------------------------------------------------------
@@ -942,6 +952,45 @@ hal_tx_vdev_mismatch_routing_set(hal_soc_handle_t hal_soc_hdl,
}
#endif
/**
* hal_tx_mcast_mlo_reinject_routing_set - set MLO multicast reinject routing
* @hal_soc: HAL SoC context
* @config: HAL_TX_MCAST_MLO_REINJECT_FW_NOTIFY - route via FW
* HAL_TX_MCAST_MLO_REINJECT_TQM_NOTIFY - route via TQM
*
* Return: void
*/
#if defined(HWIO_TCL_R0_CMN_CONFIG_MCAST_CMN_PN_SN_MLO_REINJECT_ENABLE_BMSK) && \
defined(WLAN_MCAST_MLO)
static inline void
hal_tx_mcast_mlo_reinject_routing_set(
hal_soc_handle_t hal_soc_hdl,
enum hal_tx_mcast_mlo_reinject_notify config)
{
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
uint32_t reg_addr, reg_val = 0;
uint32_t val = 0;
reg_addr = HWIO_TCL_R0_CMN_CONFIG_ADDR(MAC_TCL_REG_REG_BASE);
val = HAL_REG_READ(hal_soc, reg_addr);
/* reset the corresponding bits in register */
val &= (~(HWIO_TCL_R0_CMN_CONFIG_MCAST_CMN_PN_SN_MLO_REINJECT_ENABLE_BMSK));
/* set config value */
reg_val = val | (config << HWIO_TCL_R0_CMN_CONFIG_MCAST_CMN_PN_SN_MLO_REINJECT_ENABLE_SHFT);
HAL_REG_WRITE(hal_soc, reg_addr, reg_val);
}
#else
static inline void
hal_tx_mcast_mlo_reinject_routing_set(
hal_soc_handle_t hal_soc_hdl,
enum hal_tx_mcast_mlo_reinject_notify config)
{
}
#endif
/*
* hal_tx_get_num_ppe_vp_tbl_entries() - Get the total number of VP table
* @hal_soc: HAL SoC Context