qcacmn: Multicast support for MLO
Multicast support for MLO 1. Following functions are newly added. dp_rx_igmp_handler() dp_tx_mlo_mcast_handler_be() dp_rx_mlo_mcast_handler_be() dp_mlo_get_mcast_primary_vdev() Change-Id: If215f843369e6e2621ef302b924e524c86f0d30b
This commit is contained in:

committed by
Madan Koyyalamudi

父節點
64d845ab39
當前提交
b43e679a58
@@ -1238,6 +1238,22 @@ dp_mlo_peer_find_hash_add_be(struct dp_soc *soc, struct dp_peer *peer)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
|
||||
defined(WLAN_MCAST_MLO)
|
||||
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
|
||||
struct dp_vdev_be *be_vdev,
|
||||
cdp_config_param_type val)
|
||||
{
|
||||
be_vdev->mcast_primary = val.cdp_vdev_param_mcast_vdev;
|
||||
}
|
||||
#else
|
||||
static void dp_txrx_set_mlo_mcast_primary_vdev_param_be(
|
||||
struct dp_vdev_be *be_vdev,
|
||||
cdp_config_param_type val)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DP_TX_IMPLICIT_RBM_MAPPING
|
||||
static void dp_tx_implicit_rbm_set_be(struct dp_soc *soc,
|
||||
uint8_t tx_ring_id,
|
||||
@@ -1348,6 +1364,9 @@ QDF_STATUS dp_txrx_set_vdev_param_be(struct dp_soc *soc,
|
||||
if (vdev->tx_encap_type == htt_cmn_pkt_type_raw)
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
dp_warn("invalid param %d", param);
|
||||
break;
|
||||
@@ -1438,6 +1457,10 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
|
||||
arch_ops->txrx_set_vdev_param = dp_txrx_set_vdev_param_be;
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
#ifdef WLAN_MCAST_MLO
|
||||
arch_ops->dp_tx_mcast_handler = dp_tx_mlo_mcast_handler_be;
|
||||
arch_ops->dp_rx_mcast_handler = dp_rx_mlo_igmp_handler;
|
||||
#endif
|
||||
arch_ops->mlo_peer_find_hash_detach =
|
||||
dp_mlo_peer_find_hash_detach_wrapper;
|
||||
arch_ops->mlo_peer_find_hash_attach =
|
||||
|
@@ -256,6 +256,14 @@ struct dp_vdev_be {
|
||||
#ifdef WLAN_MLO_MULTI_CHIP
|
||||
/* partner list used for Intra-BSS */
|
||||
uint8_t partner_vdev_list[WLAN_MAX_MLO_CHIPS][WLAN_MAX_MLO_LINKS_PER_SOC];
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
#ifdef WLAN_MCAST_MLO
|
||||
/* DP MLO seq number */
|
||||
uint16_t seq_num;
|
||||
/* MLO Mcast primary vdev */
|
||||
bool mcast_primary;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -320,6 +328,39 @@ dp_mlo_get_peer_hash_obj(struct dp_soc *soc)
|
||||
}
|
||||
|
||||
void dp_clr_mlo_ptnr_list(struct dp_soc *soc, struct dp_vdev *vdev);
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MCAST_MLO)
|
||||
typedef void dp_ptnr_vdev_iter_func(struct dp_vdev_be *be_vdev,
|
||||
struct dp_vdev *ptnr_vdev,
|
||||
void *arg);
|
||||
/*
|
||||
* dp_mcast_mlo_iter_ptnr_vdev - API to iterate through ptnr vdev list
|
||||
* @be_soc: dp_soc_be pointer
|
||||
* @be_vdev: dp_vdev_be pointer
|
||||
* @func : function to be called for each peer
|
||||
* @arg : argument need to be passed to func
|
||||
* @mod_id: module id
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
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,
|
||||
void *arg,
|
||||
enum dp_mod_id mod_id);
|
||||
/*
|
||||
* dp_mlo_get_mcast_primary_vdev- get ref to mcast primary vdev
|
||||
* @be_soc: dp_soc_be pointer
|
||||
* @be_vdev: dp_vdev_be pointer
|
||||
* @mod_id: module id
|
||||
*
|
||||
* Return: mcast primary DP VDEV handle on success, NULL on failure
|
||||
*/
|
||||
struct dp_vdev *dp_mlo_get_mcast_primary_vdev(struct dp_soc_be *be_soc,
|
||||
struct dp_vdev_be *be_vdev,
|
||||
enum dp_mod_id mod_id);
|
||||
#endif
|
||||
|
||||
#else
|
||||
typedef struct dp_soc_be *dp_mld_peer_hash_obj_t;
|
||||
|
||||
|
@@ -1072,6 +1072,72 @@ struct dp_rx_desc *dp_rx_desc_cookie_2_va_be(struct dp_soc *soc,
|
||||
return (struct dp_rx_desc *)dp_cc_desc_find(soc, cookie);
|
||||
}
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO)
|
||||
#if defined(WLAN_MLO_MULTI_CHIP) && defined(WLAN_MCAST_MLO)
|
||||
static inline void dp_rx_dummy_src_mac(qdf_nbuf_t nbuf)
|
||||
{
|
||||
qdf_ether_header_t *eh =
|
||||
(qdf_ether_header_t *)qdf_nbuf_data(nbuf);
|
||||
|
||||
eh->ether_shost[0] = 0x4d; /* M */
|
||||
eh->ether_shost[1] = 0x4c; /* L */
|
||||
eh->ether_shost[2] = 0x4d; /* M */
|
||||
eh->ether_shost[3] = 0x43; /* C */
|
||||
eh->ether_shost[4] = 0x41; /* A */
|
||||
eh->ether_shost[5] = 0x53; /* S */
|
||||
}
|
||||
|
||||
bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct dp_vdev *mcast_primary_vdev = NULL;
|
||||
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)))
|
||||
return false;
|
||||
|
||||
if (vdev->mcast_enhancement_en || be_vdev->mcast_primary)
|
||||
goto send_pkt;
|
||||
|
||||
mcast_primary_vdev = dp_mlo_get_mcast_primary_vdev(be_soc, be_vdev,
|
||||
DP_MOD_ID_RX);
|
||||
if (!mcast_primary_vdev) {
|
||||
dp_rx_debug("Non mlo vdev");
|
||||
goto send_pkt;
|
||||
}
|
||||
dp_rx_dummy_src_mac(nbuf);
|
||||
dp_rx_deliver_to_stack(mcast_primary_vdev->pdev->soc,
|
||||
mcast_primary_vdev,
|
||||
peer,
|
||||
nbuf,
|
||||
NULL);
|
||||
dp_vdev_unref_delete(mcast_primary_vdev->pdev->soc,
|
||||
mcast_primary_vdev,
|
||||
DP_MOD_ID_RX);
|
||||
return true;
|
||||
send_pkt:
|
||||
dp_rx_deliver_to_stack(be_vdev->vdev.pdev->soc,
|
||||
&be_vdev->vdev,
|
||||
peer,
|
||||
nbuf,
|
||||
NULL);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
|
||||
uint32_t dp_rx_nf_process(struct dp_intr *int_ctx,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
|
@@ -209,4 +209,23 @@ dp_rx_replensih_soc_get(struct dp_soc *soc, uint8_t reo_ring_num)
|
||||
return soc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
#ifdef WLAN_MCAST_MLO
|
||||
/**
|
||||
* dp_rx_mlo_igmp_handler() - Rx handler for Mcast packets
|
||||
* @soc: Handle to DP Soc structure
|
||||
* @vdev: DP vdev handle
|
||||
* @peer: DP peer handle
|
||||
* @nbuf: nbuf to be enqueued
|
||||
*
|
||||
* Return: true when packet sent to stack, false failure
|
||||
*/
|
||||
bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
struct dp_peer *peer,
|
||||
qdf_nbuf_t nbuf);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -38,6 +38,14 @@
|
||||
#define DP_TX_BANK_LOCK_RELEASE(lock) qdf_spin_unlock_bh(lock)
|
||||
#endif
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
|
||||
#ifdef WLAN_MCAST_MLO
|
||||
/* MLO peer id for reinject*/
|
||||
#define DP_MLO_MCAST_REINJECT_PEER_ID 0XFFFD
|
||||
#define MAX_GSN_NUM 0x0FFF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern uint8_t sec_type_map[MAX_CDP_SEC_TYPE];
|
||||
|
||||
#ifdef DP_USE_REDUCED_PEER_ID_FIELD_WIDTH
|
||||
@@ -156,6 +164,93 @@ static inline uint8_t dp_tx_get_rbm_id_be(struct dp_soc *soc,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
|
||||
defined(WLAN_MCAST_MLO)
|
||||
void
|
||||
dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
|
||||
struct dp_vdev *ptnr_vdev,
|
||||
void *arg)
|
||||
{
|
||||
qdf_nbuf_t nbuf = (qdf_nbuf_t)arg;
|
||||
qdf_nbuf_t nbuf_clone;
|
||||
struct dp_vdev_be *be_ptnr_vdev = NULL;
|
||||
struct dp_tx_msdu_info_s msdu_info;
|
||||
|
||||
be_ptnr_vdev = dp_get_be_vdev_from_dp_vdev(ptnr_vdev);
|
||||
if (be_vdev != be_ptnr_vdev) {
|
||||
nbuf_clone = qdf_nbuf_clone(nbuf);
|
||||
if (qdf_unlikely(!nbuf_clone)) {
|
||||
dp_tx_debug("nbuf clone failed");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
nbuf_clone = nbuf;
|
||||
}
|
||||
|
||||
qdf_mem_zero(&msdu_info, sizeof(msdu_info));
|
||||
dp_tx_get_queue(ptnr_vdev, nbuf_clone, &msdu_info.tx_queue);
|
||||
msdu_info.gsn = be_vdev->seq_num;
|
||||
be_ptnr_vdev->seq_num = be_vdev->seq_num;
|
||||
|
||||
nbuf_clone = dp_tx_send_msdu_single(
|
||||
ptnr_vdev,
|
||||
nbuf_clone,
|
||||
&msdu_info,
|
||||
DP_MLO_MCAST_REINJECT_PEER_ID,
|
||||
NULL);
|
||||
if (qdf_unlikely(nbuf_clone)) {
|
||||
dp_info("pkt send failed");
|
||||
qdf_nbuf_free(nbuf_clone);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached,
|
||||
struct dp_vdev *vdev,
|
||||
struct dp_tx_msdu_info_s *msdu_info)
|
||||
{
|
||||
hal_tx_desc_set_vdev_id(hal_tx_desc_cached, msdu_info->vdev_id);
|
||||
}
|
||||
|
||||
void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
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);
|
||||
|
||||
/* send frame on partner vdevs */
|
||||
dp_mcast_mlo_iter_ptnr_vdev(be_soc, be_vdev,
|
||||
dp_tx_mlo_mcast_pkt_send,
|
||||
nbuf, DP_MOD_ID_TX);
|
||||
|
||||
/* send frame on mcast primary vdev */
|
||||
dp_tx_mlo_mcast_pkt_send(be_vdev, vdev, nbuf);
|
||||
|
||||
if (qdf_unlikely(be_vdev->seq_num > MAX_GSN_NUM))
|
||||
be_vdev->seq_num = 0;
|
||||
else
|
||||
be_vdev->seq_num++;
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached,
|
||||
struct dp_vdev *vdev,
|
||||
struct dp_tx_msdu_info_s *msdu_info)
|
||||
{
|
||||
hal_tx_desc_set_vdev_id(hal_tx_desc_cached, vdev->vdev_id);
|
||||
}
|
||||
#endif
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && !defined(WLAN_MLO_MULTI_CHIP) && \
|
||||
!defined(WLAN_MCAST_MLO)
|
||||
void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS
|
||||
dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc, uint16_t fw_metadata,
|
||||
@@ -229,7 +324,7 @@ dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
|
||||
hal_tx_desc_set_bank_id(hal_tx_desc_cached, be_vdev->bank_id);
|
||||
|
||||
hal_tx_desc_set_vdev_id(hal_tx_desc_cached, vdev->vdev_id);
|
||||
dp_tx_vdev_id_set_hal_tx_desc(hal_tx_desc_cached, vdev, msdu_info);
|
||||
|
||||
if (tid != HTT_TX_EXT_TID_INVALID)
|
||||
hal_tx_desc_set_hlos_tid(hal_tx_desc_cached, tid);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -139,6 +140,35 @@ void dp_tx_desc_pool_deinit_be(struct dp_soc *soc,
|
||||
struct dp_tx_desc_pool_s *tx_desc_pool,
|
||||
uint8_t pool_id);
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
#ifdef WLAN_MCAST_MLO
|
||||
/**
|
||||
* dp_tx_mlo_mcast_handler_be() - Tx handler for Mcast packets
|
||||
* @soc: Handle to DP Soc structure
|
||||
* @vdev: DP vdev handle
|
||||
* @nbuf: nbuf to be enqueued
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
qdf_nbuf_t nbuf);
|
||||
#ifdef WLAN_MLO_MULTI_CHIP
|
||||
/**
|
||||
* dp_tx_mlo_mcast_pkt_send() - handler to send MLO Mcast packets
|
||||
* @be_vdev: Handle to DP be_vdev structure
|
||||
* @ptnr_vdev: DP ptnr_vdev handle
|
||||
* @nbuf: nbuf to be enqueued
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
|
||||
struct dp_vdev *ptnr_vdev,
|
||||
void *arg);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
|
||||
/**
|
||||
* dp_tx_comp_nf_handler() - Tx completion ring Near full scenario handler
|
||||
|
@@ -472,3 +472,77 @@ dp_rx_replensih_soc_get(struct dp_soc *soc, uint8_t reo_ring_num)
|
||||
|
||||
return soc;
|
||||
}
|
||||
|
||||
#ifdef WLAN_MCAST_MLO
|
||||
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,
|
||||
void *arg,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
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++) {
|
||||
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 *ptnr_vdev;
|
||||
|
||||
ptnr_vdev = dp_vdev_get_ref_by_id(
|
||||
ptnr_soc,
|
||||
be_vdev->partner_vdev_list[i][j],
|
||||
mod_id);
|
||||
if (!ptnr_vdev)
|
||||
continue;
|
||||
(*func)(be_vdev, ptnr_vdev, arg);
|
||||
dp_vdev_unref_delete(ptnr_vdev->pdev->soc,
|
||||
ptnr_vdev,
|
||||
mod_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_mcast_mlo_iter_ptnr_vdev);
|
||||
|
||||
struct dp_vdev *dp_mlo_get_mcast_primary_vdev(struct dp_soc_be *be_soc,
|
||||
struct dp_vdev_be *be_vdev,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
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++) {
|
||||
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 *ptnr_vdev = NULL;
|
||||
struct dp_vdev_be *be_ptnr_vdev = NULL;
|
||||
|
||||
ptnr_vdev = dp_vdev_get_ref_by_id(
|
||||
ptnr_soc,
|
||||
be_vdev->partner_vdev_list[i][j],
|
||||
mod_id);
|
||||
if (!ptnr_vdev)
|
||||
continue;
|
||||
be_ptnr_vdev = dp_get_be_vdev_from_dp_vdev(ptnr_vdev);
|
||||
if (be_ptnr_vdev->mcast_primary)
|
||||
return ptnr_vdev;
|
||||
dp_vdev_unref_delete(be_ptnr_vdev->vdev.pdev->soc,
|
||||
&be_ptnr_vdev->vdev,
|
||||
mod_id);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_mlo_get_mcast_primary_vdev);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user