qcacmn: DP peer changes for multi-chip MLO

DP peer changes required for multi-chip MLO.
This change includes

1) Adding MLO peer to global peer hash at ML context
2) Add ML peer to all partner chips id to objtable

Change-Id: I230a6c1b14484c587b190a9a318fe9ffb1caea11
这个提交包含在:
Chaithanya Garrepalli
2021-11-23 15:34:15 +05:30
提交者 Madan Koyyalamudi
父节点 fb6af4edcd
当前提交 bbe062b4b7
修改 10 个文件,包含 713 行新增198 行删除

查看文件

@@ -1012,6 +1012,213 @@ fail:
return QDF_STATUS_E_NOMEM;
}
#ifdef WLAN_FEATURE_11BE_MLO
static inline unsigned
dp_mlo_peer_find_hash_index(dp_mld_peer_hash_obj_t mld_hash_obj,
union dp_align_mac_addr *mac_addr)
{
uint32_t index;
index =
mac_addr->align2.bytes_ab ^
mac_addr->align2.bytes_cd ^
mac_addr->align2.bytes_ef;
index ^= index >> mld_hash_obj->mld_peer_hash.idx_bits;
index &= mld_hash_obj->mld_peer_hash.mask;
return index;
}
QDF_STATUS
dp_mlo_peer_find_hash_attach_be(dp_mld_peer_hash_obj_t mld_hash_obj,
int hash_elems)
{
int i, log2;
if (!mld_hash_obj)
return QDF_STATUS_E_FAILURE;
hash_elems *= DP_PEER_HASH_LOAD_MULT;
hash_elems >>= DP_PEER_HASH_LOAD_SHIFT;
log2 = dp_log2_ceil(hash_elems);
hash_elems = 1 << log2;
mld_hash_obj->mld_peer_hash.mask = hash_elems - 1;
mld_hash_obj->mld_peer_hash.idx_bits = log2;
/* allocate an array of TAILQ peer object lists */
mld_hash_obj->mld_peer_hash.bins = qdf_mem_malloc(
hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q, dp_peer)));
if (!mld_hash_obj->mld_peer_hash.bins)
return QDF_STATUS_E_NOMEM;
for (i = 0; i < hash_elems; i++)
TAILQ_INIT(&mld_hash_obj->mld_peer_hash.bins[i]);
qdf_spinlock_create(&mld_hash_obj->mld_peer_hash_lock);
return QDF_STATUS_SUCCESS;
}
void
dp_mlo_peer_find_hash_detach_be(dp_mld_peer_hash_obj_t mld_hash_obj)
{
if (!mld_hash_obj)
return;
if (mld_hash_obj->mld_peer_hash.bins) {
qdf_mem_free(mld_hash_obj->mld_peer_hash.bins);
mld_hash_obj->mld_peer_hash.bins = NULL;
qdf_spinlock_destroy(&mld_hash_obj->mld_peer_hash_lock);
}
}
#ifdef WLAN_MLO_MULTI_CHIP
static QDF_STATUS dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc *soc)
{
/* In case of MULTI chip MLO peer hash table when MLO global object
* is created, avoid from SOC attach path
*/
return QDF_STATUS_SUCCESS;
}
static void dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc *soc)
{
}
#else
static QDF_STATUS dp_mlo_peer_find_hash_attach_wrapper(struct dp_soc *soc)
{
dp_mld_peer_hash_obj_t mld_hash_obj;
mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
if (!mld_hash_obj)
return QDF_STATUS_E_FAILURE;
return dp_mlo_peer_find_hash_attach_be(mld_hash_obj, soc->max_peers);
}
static void dp_mlo_peer_find_hash_detach_wrapper(struct dp_soc *soc)
{
dp_mld_peer_hash_obj_t mld_hash_obj;
mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
if (!mld_hash_obj)
return;
return dp_mlo_peer_find_hash_detach_be(mld_hash_obj);
}
#endif
static struct dp_peer *
dp_mlo_peer_find_hash_find_be(struct dp_soc *soc,
uint8_t *peer_mac_addr,
int mac_addr_is_aligned,
enum dp_mod_id mod_id)
{
union dp_align_mac_addr local_mac_addr_aligned, *mac_addr;
uint32_t index;
struct dp_peer *peer;
dp_mld_peer_hash_obj_t mld_hash_obj;
mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
if (!mld_hash_obj)
return NULL;
if (!mld_hash_obj->mld_peer_hash.bins)
return NULL;
if (mac_addr_is_aligned) {
mac_addr = (union dp_align_mac_addr *)peer_mac_addr;
} else {
qdf_mem_copy(
&local_mac_addr_aligned.raw[0],
peer_mac_addr, QDF_MAC_ADDR_SIZE);
mac_addr = &local_mac_addr_aligned;
}
/* search mld peer table if no link peer for given mac address */
index = dp_mlo_peer_find_hash_index(mld_hash_obj, mac_addr);
qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock);
TAILQ_FOREACH(peer, &mld_hash_obj->mld_peer_hash.bins[index],
hash_list_elem) {
/* do not check vdev ID for MLD peer */
if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0) {
/* take peer reference before returning */
if (dp_peer_get_ref(NULL, peer, mod_id) !=
QDF_STATUS_SUCCESS)
peer = NULL;
qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
return peer;
}
}
qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
return NULL; /* failure */
}
static void
dp_mlo_peer_find_hash_remove_be(struct dp_soc *soc, struct dp_peer *peer)
{
uint32_t index;
struct dp_peer *tmppeer = NULL;
int found = 0;
dp_mld_peer_hash_obj_t mld_hash_obj;
mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
if (!mld_hash_obj)
return;
index = dp_mlo_peer_find_hash_index(mld_hash_obj, &peer->mac_addr);
QDF_ASSERT(!TAILQ_EMPTY(&mld_hash_obj->mld_peer_hash.bins[index]));
qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock);
TAILQ_FOREACH(tmppeer, &mld_hash_obj->mld_peer_hash.bins[index],
hash_list_elem) {
if (tmppeer == peer) {
found = 1;
break;
}
}
QDF_ASSERT(found);
TAILQ_REMOVE(&mld_hash_obj->mld_peer_hash.bins[index], peer,
hash_list_elem);
dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG);
qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
}
static void
dp_mlo_peer_find_hash_add_be(struct dp_soc *soc, struct dp_peer *peer)
{
uint32_t index;
dp_mld_peer_hash_obj_t mld_hash_obj;
mld_hash_obj = dp_mlo_get_peer_hash_obj(soc);
if (!mld_hash_obj)
return;
index = dp_mlo_peer_find_hash_index(mld_hash_obj, &peer->mac_addr);
qdf_spin_lock_bh(&mld_hash_obj->mld_peer_hash_lock);
if (QDF_IS_STATUS_ERROR(dp_peer_get_ref(NULL, peer,
DP_MOD_ID_CONFIG))) {
dp_err("fail to get peer ref:" QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(peer->mac_addr.raw));
qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
return;
}
TAILQ_INSERT_TAIL(&mld_hash_obj->mld_peer_hash.bins[index], peer,
hash_list_elem);
qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock);
}
#endif
#ifdef DP_TX_IMPLICIT_RBM_MAPPING
static void dp_tx_implicit_rbm_set_be(struct dp_soc *soc,
uint8_t tx_ring_id,
@@ -1065,5 +1272,14 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
arch_ops->soc_cfg_attach = dp_soc_cfg_attach_be;
arch_ops->tx_implicit_rbm_set = dp_tx_implicit_rbm_set_be;
#ifdef WLAN_FEATURE_11BE_MLO
arch_ops->mlo_peer_find_hash_detach =
dp_mlo_peer_find_hash_detach_wrapper;
arch_ops->mlo_peer_find_hash_attach =
dp_mlo_peer_find_hash_attach_wrapper;
arch_ops->mlo_peer_find_hash_add = dp_mlo_peer_find_hash_add_be;
arch_ops->mlo_peer_find_hash_remove = dp_mlo_peer_find_hash_remove_be;
arch_ops->mlo_peer_find_hash_find = dp_mlo_peer_find_hash_find_be;
#endif
dp_init_near_full_arch_ops_be(arch_ops);
}

查看文件

@@ -178,6 +178,9 @@ struct dp_tx_bank_profile {
* @mlo_enabled: Flag to indicate MLO is enabled or not
* @mlo_chip_id: MLO chip_id
* @ml_ctxt: pointer to global ml_context
* @mld_peer_hash: peer hash table for ML peers
* Associated peer with this MAC address)
* @mld_peer_hash_lock: lock to protect mld_peer_hash
*/
struct dp_soc_be {
struct dp_soc soc;
@@ -196,10 +199,21 @@ struct dp_soc_be {
#if !defined(DISABLE_MON_CONFIG)
struct dp_mon_soc_be *monitor_soc_be;
#endif
#ifdef WLAN_FEATURE_11BE_MLO
#ifdef WLAN_MLO_MULTI_CHIP
uint8_t mlo_enabled;
uint8_t mlo_chip_id;
struct dp_mlo_ctxt *ml_ctxt;
#else
/* Protect mld peer hash table */
DP_MUTEX_TYPE mld_peer_hash_lock;
struct {
uint32_t mask;
uint32_t idx_bits;
TAILQ_HEAD(, dp_peer) * bins;
} mld_peer_hash;
#endif
#endif
};
@@ -276,6 +290,55 @@ static inline struct dp_soc_be *dp_get_be_soc_from_dp_soc(struct dp_soc *soc)
return (struct dp_soc_be *)soc;
}
#ifdef WLAN_MLO_MULTI_CHIP
typedef struct dp_mlo_ctxt *dp_mld_peer_hash_obj_t;
/*
* dp_mlo_get_peer_hash_obj() - return the container struct of MLO hash table
*
* @soc: soc handle
*
* return: MLD peer hash object
*/
static inline dp_mld_peer_hash_obj_t
dp_mlo_get_peer_hash_obj(struct dp_soc *soc)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
return be_soc->ml_ctxt;
}
#else
typedef struct dp_soc_be *dp_mld_peer_hash_obj_t;
static inline dp_mld_peer_hash_obj_t
dp_mlo_get_peer_hash_obj(struct dp_soc *soc)
{
return dp_get_be_soc_from_dp_soc(soc);
}
#endif
/*
* dp_mlo_peer_find_hash_attach_be() - API to initialize ML peer hash table
*
* @mld_hash_obj: Peer has object
* @hash_elems: number of entries in hash table
*
* return: QDF_STATUS_SUCCESS when attach is success else QDF_STATUS_FAILURE
*/
QDF_STATUS
dp_mlo_peer_find_hash_attach_be(dp_mld_peer_hash_obj_t mld_hash_obj,
int hash_elems);
/*
* dp_mlo_peer_find_hash_detach_be() - API to de-initialize ML peer hash table
*
* @mld_hash_obj: Peer has object
*
* return: void
*/
void dp_mlo_peer_find_hash_detach_be(dp_mld_peer_hash_obj_t mld_hash_obj);
/**
* dp_get_be_pdev_from_dp_pdev() - get dp_pdev_be from dp_pdev
* @pdev: dp_pdev pointer

查看文件

@@ -19,6 +19,8 @@
#include <hal_be_api.h>
#include "dp_mlo.h"
#include <dp_be.h>
#include <dp_htt.h>
#include <dp_internal.h>
/*
* dp_mlo_ctxt_attach_wifi3 () – Attach DP MLO context
@@ -38,6 +40,14 @@ dp_mlo_ctxt_attach_wifi3(struct cdp_ctrl_mlo_mgr *ctrl_ctxt)
mlo_ctxt->ctrl_ctxt = ctrl_ctxt;
if (dp_mlo_peer_find_hash_attach_be
(mlo_ctxt, DP_MAX_MLO_PEER) != QDF_STATUS_SUCCESS) {
dp_err("Failed to allocate peer hash");
qdf_mem_free(mlo_ctxt);
return NULL;
}
qdf_spinlock_create(&mlo_ctxt->ml_soc_list_lock);
return dp_mlo_ctx_to_cdp(mlo_ctxt);
}
@@ -50,9 +60,16 @@ qdf_export_symbol(dp_mlo_ctxt_attach_wifi3);
*
* Return: void
*/
void dp_mlo_ctxt_detach_wifi3(struct cdp_mlo_ctxt *ml_ctxt)
void dp_mlo_ctxt_detach_wifi3(struct cdp_mlo_ctxt *cdp_ml_ctxt)
{
qdf_mem_free(ml_ctxt);
struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
if (!cdp_ml_ctxt)
return;
qdf_spinlock_destroy(&mlo_ctxt->ml_soc_list_lock);
dp_mlo_peer_find_hash_detach_be(mlo_ctxt);
qdf_mem_free(mlo_ctxt);
}
qdf_export_symbol(dp_mlo_ctxt_detach_wifi3);
@@ -92,13 +109,50 @@ dp_mlo_get_soc_ref_by_chip_id(struct dp_mlo_ctxt *ml_ctxt,
struct dp_soc *soc = NULL;
qdf_spin_lock_bh(&ml_ctxt->ml_soc_list_lock);
qdf_atomic_inc(&soc->ref_count);
soc = ml_ctxt->ml_soc_list[chip_id];
if (!soc) {
qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
return NULL;
}
qdf_atomic_inc(&soc->ref_count);
qdf_spin_unlock_bh(&ml_ctxt->ml_soc_list_lock);
return soc;
}
static void dp_mlo_soc_setup(struct cdp_soc_t *soc_hdl,
struct cdp_mlo_ctxt *cdp_ml_ctxt)
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
if (!cdp_ml_ctxt)
return;
dp_mlo_set_soc_by_chip_id(mlo_ctxt, soc, be_soc->mlo_chip_id);
}
static void dp_mlo_soc_teardown(struct cdp_soc_t *soc_hdl,
struct cdp_mlo_ctxt *cdp_ml_ctxt)
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
struct dp_mlo_ctxt *mlo_ctxt = cdp_mlo_ctx_to_dp(cdp_ml_ctxt);
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
if (!cdp_ml_ctxt)
return;
dp_mlo_set_soc_by_chip_id(mlo_ctxt, NULL, be_soc->mlo_chip_id);
}
static struct cdp_mlo_ops dp_mlo_ops = {
.mlo_soc_setup = dp_mlo_soc_setup,
.mlo_soc_teardown = dp_mlo_soc_teardown,
};
void dp_soc_mlo_fill_params(struct dp_soc *soc,
struct cdp_soc_attach_params *params)
{
@@ -112,6 +166,7 @@ void dp_soc_mlo_fill_params(struct dp_soc *soc,
be_soc->mlo_chip_id = params->mlo_chip_id;
be_soc->ml_ctxt = cdp_mlo_ctx_to_dp(params->ml_context);
be_soc->mlo_enabled = 1;
soc->cdp_soc.ops->mlo_ops = &dp_mlo_ops;
}
void dp_pdev_mlo_fill_params(struct dp_pdev *pdev,
@@ -127,3 +182,110 @@ void dp_pdev_mlo_fill_params(struct dp_pdev *pdev,
be_pdev->mlo_link_id = params->mlo_link_id;
}
void dp_mlo_partner_chips_map(struct dp_soc *soc,
struct dp_peer *peer,
uint16_t peer_id)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
bool is_ml_peer_id = peer_id & HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_S;
uint8_t chip_id;
struct dp_soc *temp_soc;
if (!mlo_ctxt)
return;
/* for non ML peer dont map on partner chips*/
if (!is_ml_peer_id)
return;
qdf_spin_lock_bh(&mlo_ctxt->ml_soc_list_lock);
for (chip_id = 0; chip_id < DP_MAX_MLO_CHIPS; chip_id++) {
temp_soc = mlo_ctxt->ml_soc_list[chip_id];
if (!temp_soc)
continue;
/* skip if this is current soc */
if (temp_soc == soc)
continue;
dp_peer_find_id_to_obj_add(temp_soc, peer, peer_id);
}
qdf_spin_unlock_bh(&mlo_ctxt->ml_soc_list_lock);
}
qdf_export_symbol(dp_mlo_partner_chips_map);
void dp_mlo_partner_chips_unmap(struct dp_soc *soc,
uint16_t peer_id)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
bool is_ml_peer_id = peer_id & HTT_RX_PEER_META_DATA_V1_ML_PEER_VALID_S;
uint8_t chip_id;
struct dp_soc *temp_soc;
if (!is_ml_peer_id)
return;
if (!mlo_ctxt)
return;
qdf_spin_lock_bh(&mlo_ctxt->ml_soc_list_lock);
for (chip_id = 0; chip_id < DP_MAX_MLO_CHIPS; chip_id++) {
temp_soc = mlo_ctxt->ml_soc_list[chip_id];
if (!temp_soc)
continue;
/* skip if this is current soc */
if (temp_soc == soc)
continue;
dp_peer_find_id_to_obj_remove(temp_soc, peer_id);
}
qdf_spin_unlock_bh(&mlo_ctxt->ml_soc_list_lock);
}
qdf_export_symbol(dp_mlo_partner_chips_unmap);
uint8_t dp_mlo_get_chip_id(struct dp_soc *soc)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
return be_soc->mlo_chip_id;
}
qdf_export_symbol(dp_mlo_get_chip_id);
struct dp_peer *
dp_link_peer_hash_find_by_chip_id(struct dp_soc *soc,
uint8_t *peer_mac_addr,
int mac_addr_is_aligned,
uint8_t vdev_id,
uint8_t chip_id,
enum dp_mod_id mod_id)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct dp_mlo_ctxt *mlo_ctxt = be_soc->ml_ctxt;
struct dp_soc *link_peer_soc = NULL;
struct dp_peer *peer = NULL;
if (!mlo_ctxt)
return NULL;
link_peer_soc = dp_mlo_get_soc_ref_by_chip_id(mlo_ctxt, chip_id);
if (!link_peer_soc)
return NULL;
peer = dp_peer_find_hash_find(link_peer_soc, peer_mac_addr,
mac_addr_is_aligned, vdev_id,
mod_id);
qdf_atomic_dec(&link_peer_soc->ref_count);
return peer;
}
qdf_export_symbol(dp_link_peer_hash_find_by_chip_id);

查看文件

@@ -17,10 +17,13 @@
#define __DP_MLO_H
#include <dp_types.h>
#include <dp_peer.h>
/* Max number of chips that can participate in MLO */
#define DP_MAX_MLO_CHIPS 3
/* Max number of peers supported */
#define DP_MAX_MLO_PEER 512
/*
* dp_mlo_ctxt
*
@@ -28,9 +31,9 @@
* @ml_soc_list: list of socs which are mlo enabled. This also maintains
* mlo_chip_id to dp_soc mapping
* @ml_soc_list_lock: lock to protect ml_soc_list
* @ml_peer_hash: peer hash table for ML peers
* @mld_peer_hash: peer hash table for ML peers
* Associated peer with this MAC address)
* @ml_peer_hash_lock: lock to protect ml_peer_hash
* @mld_peer_hash_lock: lock to protect mld_peer_hash
*/
struct dp_mlo_ctxt {
struct cdp_ctrl_mlo_mgr *ctrl_ctxt;
@@ -41,9 +44,9 @@ struct dp_mlo_ctxt {
uint32_t idx_bits;
TAILQ_HEAD(, dp_peer) * bins;
} ml_peer_hash;
} mld_peer_hash;
qdf_spinlock_t ml_peer_hash_lock;
qdf_spinlock_t mld_peer_hash_lock;
};
/**