From bbe062b4b7d13370bcd61f7ad77f5faa86da3f1a Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Tue, 23 Nov 2021 15:34:15 +0530 Subject: [PATCH] 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 --- dp/inc/cdp_txrx_mlo.h | 32 ++++++ dp/inc/cdp_txrx_ops.h | 18 +++- dp/wifi3.0/be/dp_be.c | 216 +++++++++++++++++++++++++++++++++++++ dp/wifi3.0/be/dp_be.h | 63 +++++++++++ dp/wifi3.0/be/mlo/dp_mlo.c | 168 ++++++++++++++++++++++++++++- dp/wifi3.0/be/mlo/dp_mlo.h | 11 +- dp/wifi3.0/dp_main.c | 79 ++++++++------ dp/wifi3.0/dp_peer.c | 209 +++++++++++------------------------ dp/wifi3.0/dp_peer.h | 90 +++++++++++++++- dp/wifi3.0/dp_types.h | 25 +++-- 10 files changed, 713 insertions(+), 198 deletions(-) diff --git a/dp/inc/cdp_txrx_mlo.h b/dp/inc/cdp_txrx_mlo.h index 7fa22d008f..8b47ac1354 100644 --- a/dp/inc/cdp_txrx_mlo.h +++ b/dp/inc/cdp_txrx_mlo.h @@ -15,6 +15,8 @@ */ #ifndef _CDP_TXRX_MLO_H_ #define _CDP_TXRX_MLO_H_ +#include "cdp_txrx_ops.h" + struct cdp_mlo_ctxt; /** @@ -37,4 +39,34 @@ void cdp_mlo_ctxt_detach(struct cdp_mlo_ctxt *ml_ctxt) { dp_mlo_ctxt_detach_wifi3(ml_ctxt); } + +static inline void cdp_soc_mlo_soc_setup(ol_txrx_soc_handle soc, + struct cdp_mlo_ctxt *mlo_ctx) +{ + if (!soc || !soc->ops) { + QDF_BUG(0); + return; + } + + if (!soc->ops->mlo_ops || + !soc->ops->mlo_ops->mlo_soc_setup) + return; + + soc->ops->mlo_ops->mlo_soc_setup(soc, mlo_ctx); +} + +static inline void cdp_soc_mlo_soc_teardown(ol_txrx_soc_handle soc, + struct cdp_mlo_ctxt *mlo_ctx) +{ + if (!soc || !soc->ops) { + QDF_BUG(0); + return; + } + + if (!soc->ops->mlo_ops || + !soc->ops->mlo_ops->mlo_soc_teardown) + return; + + soc->ops->mlo_ops->mlo_soc_teardown(soc, mlo_ctx); +} #endif /*_CDP_TXRX_MLO_H_*/ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 23d6c87340..a42bfbef56 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -105,6 +105,20 @@ enum vdev_ll_conn_actions { CDP_VDEV_LL_CONN_DEL }; +/** + * struct cdp_mlo_ops - MLO ops for multichip + * @mlo_soc_setup: setup DP mlo for SOC + * @mlo_soc_teardown: teardown DP mlo for SOC + */ +#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) +struct cdp_mlo_ops { + void (*mlo_soc_setup)(struct cdp_soc_t *cdp_soc, + struct cdp_mlo_ctxt *mlo_ctxt); + void (*mlo_soc_teardown)(struct cdp_soc_t *cdp_soc, + struct cdp_mlo_ctxt *mlo_ctxt); +}; +#endif + /****************************************************************************** * * Control Interface (A Interface) @@ -1874,6 +1888,8 @@ struct cdp_ops { #ifdef WLAN_SUPPORT_MESH_LATENCY struct cdp_mesh_latency_ops *mesh_latency_ops; #endif - +#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) + struct cdp_mlo_ops *mlo_ops; +#endif }; #endif diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index 4ec14c3a38..0754aef7eb 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -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); } diff --git a/dp/wifi3.0/be/dp_be.h b/dp/wifi3.0/be/dp_be.h index 51cf1703cd..ea80409860 100644 --- a/dp/wifi3.0/be/dp_be.h +++ b/dp/wifi3.0/be/dp_be.h @@ -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 diff --git a/dp/wifi3.0/be/mlo/dp_mlo.c b/dp/wifi3.0/be/mlo/dp_mlo.c index b21c448a75..63a4d36759 100644 --- a/dp/wifi3.0/be/mlo/dp_mlo.c +++ b/dp/wifi3.0/be/mlo/dp_mlo.c @@ -19,6 +19,8 @@ #include #include "dp_mlo.h" #include +#include +#include /* * 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); diff --git a/dp/wifi3.0/be/mlo/dp_mlo.h b/dp/wifi3.0/be/mlo/dp_mlo.h index 4f3d62f254..db3c0059af 100644 --- a/dp/wifi3.0/be/mlo/dp_mlo.h +++ b/dp/wifi3.0/be/mlo/dp_mlo.h @@ -17,10 +17,13 @@ #define __DP_MLO_H #include +#include /* 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; }; /** diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 2cc9ed6f1b..fe4f80cbb4 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -5515,6 +5515,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc) dp_mon_soc_detach_wrapper(soc); } + qdf_mem_free(soc->cdp_soc.ops); qdf_mem_free(soc); } @@ -12341,42 +12342,43 @@ static struct cdp_peer_ops dp_ops_peer = { }; #endif -static struct cdp_ops dp_txrx_ops = { - .cmn_drv_ops = &dp_ops_cmn, - .ctrl_ops = &dp_ops_ctrl, - .me_ops = &dp_ops_me, - .host_stats_ops = &dp_ops_host_stats, - .wds_ops = &dp_ops_wds, - .raw_ops = &dp_ops_raw, +static void dp_soc_txrx_ops_attach(struct dp_soc *soc) +{ + soc->cdp_soc.ops->cmn_drv_ops = &dp_ops_cmn; + soc->cdp_soc.ops->ctrl_ops = &dp_ops_ctrl; + soc->cdp_soc.ops->me_ops = &dp_ops_me; + soc->cdp_soc.ops->host_stats_ops = &dp_ops_host_stats; + soc->cdp_soc.ops->wds_ops = &dp_ops_wds; + soc->cdp_soc.ops->raw_ops = &dp_ops_raw; #ifdef PEER_FLOW_CONTROL - .pflow_ops = &dp_ops_pflow, + soc->cdp_soc.ops->pflow_ops = &dp_ops_pflow; #endif /* PEER_FLOW_CONTROL */ #ifdef DP_PEER_EXTENDED_API - .misc_ops = &dp_ops_misc, - .ocb_ops = &dp_ops_ocb, - .peer_ops = &dp_ops_peer, - .mob_stats_ops = &dp_ops_mob_stats, + soc->cdp_soc.ops->misc_ops = &dp_ops_misc; + soc->cdp_soc.ops->ocb_ops = &dp_ops_ocb; + soc->cdp_soc.ops->peer_ops = &dp_ops_peer; + soc->cdp_soc.ops->mob_stats_ops = &dp_ops_mob_stats; #endif #ifdef DP_FLOW_CTL - .cfg_ops = &dp_ops_cfg, - .flowctl_ops = &dp_ops_flowctl, - .l_flowctl_ops = &dp_ops_l_flowctl, - .throttle_ops = &dp_ops_throttle, + soc->cdp_soc.ops->cfg_ops = &dp_ops_cfg; + soc->cdp_soc.ops->flowctl_ops = &dp_ops_flowctl; + soc->cdp_soc.ops->l_flowctl_ops = &dp_ops_l_flowctl; + soc->cdp_soc.ops->throttle_ops = &dp_ops_throttle; #endif #ifdef IPA_OFFLOAD - .ipa_ops = &dp_ops_ipa, + soc->cdp_soc.ops->ipa_ops = &dp_ops_ipa; #endif #ifdef DP_POWER_SAVE - .bus_ops = &dp_ops_bus, + soc->cdp_soc.ops->bus_ops = &dp_ops_bus; #endif #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) - .cfr_ops = &dp_ops_cfr, + soc->cdp_soc.ops->cfr_ops = &dp_ops_cfr; #endif #ifdef WLAN_SUPPORT_MSCS - .mscs_ops = &dp_ops_mscs, + soc->cdp_soc.ops->mscs_ops = &dp_ops_mscs; #endif #ifdef WLAN_SUPPORT_MESH_LATENCY - .mesh_latency_ops = &dp_ops_mesh_latency, + soc->cdp_soc.ops->mesh_latency_ops = &dp_ops_mesh_latency; #endif }; @@ -12483,7 +12485,12 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, &soc->cmem_size); int_ctx = 0; soc->device_id = device_id; - soc->cdp_soc.ops = &dp_txrx_ops; + soc->cdp_soc.ops = + (struct cdp_ops *)qdf_mem_malloc(sizeof(struct cdp_ops)); + if (!soc->cdp_soc.ops) + goto fail1; + + dp_soc_txrx_ops_attach(soc); soc->cdp_soc.ol_ops = ol_ops; soc->ctrl_psoc = ctrl_psoc; soc->osdev = qdf_osdev; @@ -12507,40 +12514,40 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, soc->wlan_cfg_ctx = wlan_cfg_soc_attach(soc->ctrl_psoc); if (!soc->wlan_cfg_ctx) { dp_err("wlan_cfg_ctx failed\n"); - goto fail1; + goto fail2; } dp_soc_cfg_attach(soc); if (dp_hw_link_desc_pool_banks_alloc(soc, WLAN_INVALID_PDEV_ID)) { dp_err("failed to allocate link desc pool banks"); - goto fail2; + goto fail3; } if (dp_hw_link_desc_ring_alloc(soc)) { dp_err("failed to allocate link_desc_ring"); - goto fail3; + goto fail4; } if (!QDF_IS_STATUS_SUCCESS(soc->arch_ops.txrx_soc_attach(soc, params))) { dp_err("unable to do target specific attach"); - goto fail4; + goto fail5; } if (dp_soc_srng_alloc(soc)) { dp_err("failed to allocate soc srng rings"); - goto fail5; + goto fail6; } if (dp_soc_tx_desc_sw_pools_alloc(soc)) { dp_err("dp_soc_tx_desc_sw_pools_alloc failed"); - goto fail6; + goto fail7; } if (!dp_monitor_modularized_enable()) { if (dp_mon_soc_attach_wrapper(soc)) { dp_err("failed to attach monitor"); - goto fail7; + goto fail8; } } @@ -12559,18 +12566,20 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, qdf_skb_total_mem_stats_read()); return soc; -fail7: +fail8: dp_soc_tx_desc_sw_pools_free(soc); -fail6: +fail7: dp_soc_srng_free(soc); -fail5: +fail6: soc->arch_ops.txrx_soc_detach(soc); -fail4: +fail5: dp_hw_link_desc_ring_free(soc); -fail3: +fail4: dp_hw_link_desc_pool_banks_free(soc, WLAN_INVALID_PDEV_ID); -fail2: +fail3: wlan_cfg_soc_detach(soc->wlan_cfg_ctx); +fail2: + qdf_mem_free(soc->cdp_soc.ops); fail1: qdf_mem_free(soc); fail0: diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 3cbb9bf238..d9aacafd59 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -209,13 +209,44 @@ static QDF_STATUS dp_peer_find_map_attach(struct dp_soc *soc) return QDF_STATUS_SUCCESS; /* success */ } -#define DP_PEER_HASH_LOAD_MULT 2 -#define DP_PEER_HASH_LOAD_SHIFT 0 - #define DP_AST_HASH_LOAD_MULT 2 #define DP_AST_HASH_LOAD_SHIFT 0 +static inline uint32_t +dp_peer_find_hash_index(struct dp_soc *soc, + 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 >> soc->peer_hash.idx_bits; + index &= soc->peer_hash.mask; + return index; +} + #ifdef WLAN_FEATURE_11BE_MLO +/* + * dp_peer_find_hash_detach() - cleanup memory for peer_hash table + * @soc: soc handle + * + * return: none + */ +static void dp_peer_find_hash_detach(struct dp_soc *soc) +{ + if (soc->peer_hash.bins) { + qdf_mem_free(soc->peer_hash.bins); + soc->peer_hash.bins = NULL; + qdf_spinlock_destroy(&soc->peer_hash_lock); + } + + if (soc->arch_ops.mlo_peer_find_hash_detach) + soc->arch_ops.mlo_peer_find_hash_detach(soc); +} + /* * dp_peer_find_hash_attach() - allocate memory for peer_hash table * @soc: soc handle @@ -235,76 +266,26 @@ static QDF_STATUS dp_peer_find_hash_attach(struct dp_soc *soc) soc->peer_hash.mask = hash_elems - 1; soc->peer_hash.idx_bits = log2; - soc->mld_peer_hash.mask = hash_elems - 1; - soc->mld_peer_hash.idx_bits = log2; /* allocate an array of TAILQ peer object lists */ soc->peer_hash.bins = qdf_mem_malloc( hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q, dp_peer))); if (!soc->peer_hash.bins) return QDF_STATUS_E_NOMEM; - soc->mld_peer_hash.bins = qdf_mem_malloc( - hash_elems * sizeof(TAILQ_HEAD(anonymous_tail_q1, dp_peer))); - if (!soc->mld_peer_hash.bins) { - qdf_mem_free(soc->peer_hash.bins); - return QDF_STATUS_E_NOMEM; - } - - for (i = 0; i < hash_elems; i++) { + for (i = 0; i < hash_elems; i++) TAILQ_INIT(&soc->peer_hash.bins[i]); - TAILQ_INIT(&soc->mld_peer_hash.bins[i]); - } qdf_spinlock_create(&soc->peer_hash_lock); - qdf_spinlock_create(&soc->mld_peer_hash_lock); + if (soc->arch_ops.mlo_peer_find_hash_attach && + (soc->arch_ops.mlo_peer_find_hash_attach(soc) != + QDF_STATUS_SUCCESS)) { + dp_peer_find_hash_detach(soc); + return QDF_STATUS_E_NOMEM; + } return QDF_STATUS_SUCCESS; } -/* - * dp_peer_find_hash_detach() - cleanup memory for peer_hash table - * @soc: soc handle - * - * return: none - */ -static void dp_peer_find_hash_detach(struct dp_soc *soc) -{ - if (soc->peer_hash.bins) { - qdf_mem_free(soc->peer_hash.bins); - soc->peer_hash.bins = NULL; - qdf_spinlock_destroy(&soc->peer_hash_lock); - } - - if (soc->mld_peer_hash.bins) { - qdf_mem_free(soc->mld_peer_hash.bins); - soc->mld_peer_hash.bins = NULL; - qdf_spinlock_destroy(&soc->mld_peer_hash_lock); - } -} - -static inline unsigned dp_peer_find_hash_index(struct dp_soc *soc, - union dp_align_mac_addr *mac_addr, - enum cdp_peer_type peer_type) -{ - unsigned index; - - index = - mac_addr->align2.bytes_ab ^ - mac_addr->align2.bytes_cd ^ - mac_addr->align2.bytes_ef; - if (peer_type == CDP_LINK_PEER_TYPE) { - index ^= index >> soc->peer_hash.idx_bits; - index &= soc->peer_hash.mask; - } else if (peer_type == CDP_MLD_PEER_TYPE) { - index ^= index >> soc->mld_peer_hash.idx_bits; - index &= soc->mld_peer_hash.mask; - } else { - dp_err("unknown peer type %d", peer_type); - } - - return index; -} - /* * dp_peer_find_hash_add() - add peer to peer_hash_table * @soc: soc handle @@ -317,8 +298,7 @@ void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer) { unsigned index; - index = dp_peer_find_hash_index(soc, &peer->mac_addr, - peer->peer_type); + index = dp_peer_find_hash_index(soc, &peer->mac_addr); if (peer->peer_type == CDP_LINK_PEER_TYPE) { qdf_spin_lock_bh(&soc->peer_hash_lock); @@ -342,18 +322,8 @@ void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer) qdf_spin_unlock_bh(&soc->peer_hash_lock); } else if (peer->peer_type == CDP_MLD_PEER_TYPE) { - qdf_spin_lock_bh(&soc->mld_peer_hash_lock); - - if (QDF_IS_STATUS_ERROR(dp_peer_get_ref(soc, 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(&soc->mld_peer_hash_lock); - return; - } - TAILQ_INSERT_TAIL(&soc->mld_peer_hash.bins[index], peer, - hash_list_elem); - qdf_spin_unlock_bh(&soc->mld_peer_hash_lock); + if (soc->arch_ops.mlo_peer_find_hash_add) + soc->arch_ops.mlo_peer_find_hash_add(soc, peer); } else { dp_err("unknown peer type %d", peer->peer_type); } @@ -381,7 +351,7 @@ struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, unsigned index; struct dp_peer *peer; - if (!soc->peer_hash.bins || !soc->mld_peer_hash.bins) + if (!soc->peer_hash.bins) return NULL; if (mac_addr_is_aligned) { @@ -393,7 +363,7 @@ struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, mac_addr = &local_mac_addr_aligned; } /* search link peer table firstly */ - index = dp_peer_find_hash_index(soc, mac_addr, CDP_LINK_PEER_TYPE); + index = dp_peer_find_hash_index(soc, mac_addr); qdf_spin_lock_bh(&soc->peer_hash_lock); TAILQ_FOREACH(peer, &soc->peer_hash.bins[index], hash_list_elem) { if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 && @@ -410,24 +380,11 @@ struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, } qdf_spin_unlock_bh(&soc->peer_hash_lock); - /* search mld peer table if no link peer for given mac address */ - index = dp_peer_find_hash_index(soc, mac_addr, CDP_MLD_PEER_TYPE); - qdf_spin_lock_bh(&soc->mld_peer_hash_lock); - TAILQ_FOREACH(peer, &soc->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(soc, peer, mod_id) != - QDF_STATUS_SUCCESS) - peer = NULL; - - qdf_spin_unlock_bh(&soc->mld_peer_hash_lock); - return peer; - } - } - qdf_spin_unlock_bh(&soc->mld_peer_hash_lock); - - return NULL; /* failure */ + if (soc->arch_ops.mlo_peer_find_hash_find) + return soc->arch_ops.mlo_peer_find_hash_find(soc, peer_mac_addr, + mac_addr_is_aligned, + mod_id); + return NULL; } qdf_export_symbol(dp_peer_find_hash_find); @@ -445,7 +402,7 @@ void dp_peer_find_hash_remove(struct dp_soc *soc, struct dp_peer *peer) struct dp_peer *tmppeer = NULL; int found = 0; - index = dp_peer_find_hash_index(soc, &peer->mac_addr, peer->peer_type); + index = dp_peer_find_hash_index(soc, &peer->mac_addr); if (peer->peer_type == CDP_LINK_PEER_TYPE) { /* Check if tail is not empty before delete*/ @@ -466,22 +423,8 @@ void dp_peer_find_hash_remove(struct dp_soc *soc, struct dp_peer *peer) dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG); qdf_spin_unlock_bh(&soc->peer_hash_lock); } else if (peer->peer_type == CDP_MLD_PEER_TYPE) { - QDF_ASSERT(!TAILQ_EMPTY(&soc->mld_peer_hash.bins[index])); - - qdf_spin_lock_bh(&soc->mld_peer_hash_lock); - TAILQ_FOREACH(tmppeer, &soc->mld_peer_hash.bins[index], - hash_list_elem) { - if (tmppeer == peer) { - found = 1; - break; - } - } - QDF_ASSERT(found); - TAILQ_REMOVE(&soc->mld_peer_hash.bins[index], peer, - hash_list_elem); - - dp_peer_unref_delete(peer, DP_MOD_ID_CONFIG); - qdf_spin_unlock_bh(&soc->mld_peer_hash_lock); + if (soc->arch_ops.mlo_peer_find_hash_remove) + soc->arch_ops.mlo_peer_find_hash_remove(soc, peer); } else { dp_err("unknown peer type %d", peer->peer_type); } @@ -515,7 +458,7 @@ static bool dp_peer_exist_on_pdev(struct dp_soc *soc, peer_mac_addr, QDF_MAC_ADDR_SIZE); mac_addr = &local_mac_addr_aligned; } - index = dp_peer_find_hash_index(soc, mac_addr, CDP_LINK_PEER_TYPE); + index = dp_peer_find_hash_index(soc, mac_addr); qdf_spin_lock_bh(&soc->peer_hash_lock); TAILQ_FOREACH(peer, &soc->peer_hash.bins[index], hash_list_elem) { if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 && @@ -526,20 +469,6 @@ static bool dp_peer_exist_on_pdev(struct dp_soc *soc, } qdf_spin_unlock_bh(&soc->peer_hash_lock); - if (found) - return found; - - index = dp_peer_find_hash_index(soc, mac_addr, CDP_MLD_PEER_TYPE); - qdf_spin_lock_bh(&soc->mld_peer_hash_lock); - TAILQ_FOREACH(peer, &soc->mld_peer_hash.bins[index], hash_list_elem) { - if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 && - (peer->vdev->pdev == pdev)) { - found = true; - break; - } - } - qdf_spin_unlock_bh(&soc->mld_peer_hash_lock); - return found; } #else @@ -578,21 +507,6 @@ static void dp_peer_find_hash_detach(struct dp_soc *soc) } } -static inline unsigned dp_peer_find_hash_index( - struct dp_soc *soc, - union dp_align_mac_addr *mac_addr) -{ - unsigned index; - - index = - mac_addr->align2.bytes_ab ^ - mac_addr->align2.bytes_cd ^ - mac_addr->align2.bytes_ef; - index ^= index >> soc->peer_hash.idx_bits; - index &= soc->peer_hash.mask; - return index; -} - void dp_peer_find_hash_add(struct dp_soc *soc, struct dp_peer *peer) { unsigned index; @@ -2573,6 +2487,7 @@ static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc, return NULL; } dp_peer_find_id_to_obj_add(soc, peer, peer_id); + dp_mlo_partner_chips_map(soc, peer, peer_id); if (peer->peer_id == HTT_INVALID_PEER) { peer->peer_id = peer_id; dp_monitor_peer_tid_peer_id_update(soc, peer, @@ -2822,6 +2737,7 @@ dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, soc, peer_id, peer); dp_peer_find_id_to_obj_remove(soc, peer_id); + dp_mlo_partner_chips_unmap(soc, peer_id); peer->peer_id = HTT_INVALID_PEER; /* @@ -2980,6 +2896,7 @@ static QDF_STATUS dp_peer_rx_reorder_queue_setup(struct dp_soc *soc, struct dp_mld_link_peers link_peers_info; struct dp_peer *link_peer; struct dp_rx_tid *rx_tid; + struct dp_soc *link_peer_soc; if (IS_MLO_DP_MLD_PEER(peer)) { /* get link peers with reference */ @@ -2990,10 +2907,12 @@ static QDF_STATUS dp_peer_rx_reorder_queue_setup(struct dp_soc *soc, for (i = 0; i < link_peers_info.num_links; i++) { link_peer = link_peers_info.link_peers[i]; rx_tid = &link_peer->rx_tid[tid]; - if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) { - if (soc->cdp_soc.ol_ops-> + link_peer_soc = link_peer->vdev->pdev->soc; + if (link_peer_soc->cdp_soc.ol_ops-> + peer_rx_reorder_queue_setup) { + if (link_peer_soc->cdp_soc.ol_ops-> peer_rx_reorder_queue_setup( - soc->ctrl_psoc, + link_peer_soc->ctrl_psoc, link_peer->vdev->pdev->pdev_id, link_peer->vdev->vdev_id, link_peer->mac_addr.raw, @@ -3001,7 +2920,7 @@ static QDF_STATUS dp_peer_rx_reorder_queue_setup(struct dp_soc *soc, tid, tid, 1, ba_window_size)) { dp_peer_err("%pK: Failed to send reo queue setup to FW - tid %d\n", - soc, tid); + link_peer_soc, tid); return QDF_STATUS_E_FAILURE; } } diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 64d619f9aa..5cd2122daf 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -34,6 +34,9 @@ #define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000 +#define DP_PEER_HASH_LOAD_MULT 2 +#define DP_PEER_HASH_LOAD_SHIFT 0 + #define dp_peer_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_DP_PEER, params) #define dp_peer_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_DP_PEER, params) #define dp_peer_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_DP_PEER, params) @@ -1044,6 +1047,36 @@ void dp_peer_delete(struct dp_soc *soc, #define IS_MLO_DP_MLD_PEER(_peer) \ ((_peer)->peer_type == CDP_MLD_PEER_TYPE) +#ifdef WLAN_MLO_MULTI_CHIP +uint8_t dp_mlo_get_chip_id(struct dp_soc *soc); + +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); +#else +static inline uint8_t dp_mlo_get_chip_id(struct dp_soc *soc) +{ + return 0; +} + +static inline 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) +{ + return dp_peer_find_hash_find(soc, peer_mac_addr, + mac_addr_is_aligned, + vdev_id, mod_id); +} +#endif + /** * dp_link_peer_add_mld_peer() - add mld peer pointer to link peer, increase mld peer ref_cnt @@ -1127,6 +1160,8 @@ void dp_mld_peer_add_link_peer(struct dp_peer *mld_peer, QDF_MAC_ADDR_SIZE); link_peer_info->is_valid = true; link_peer_info->vdev_id = link_peer->vdev->vdev_id; + link_peer_info->chip_id = + dp_mlo_get_chip_id(link_peer->vdev->pdev->soc); mld_peer->num_links++; break; } @@ -1200,11 +1235,12 @@ void dp_get_link_peers_ref_from_mld_peer( for (i = 0; i < DP_MAX_MLO_LINKS; i++) { link_peer_info = &mld_peer->link_peers[i]; if (link_peer_info->is_valid) { - peer = dp_peer_find_hash_find( + peer = dp_link_peer_hash_find_by_chip_id( soc, link_peer_info->mac_addr.raw, true, link_peer_info->vdev_id, + link_peer_info->chip_id, mod_id); if (peer) mld_link_peers->link_peers[j++] = peer; @@ -1358,6 +1394,7 @@ QDF_STATUS dp_peer_mlo_setup( struct dp_peer *peer, uint8_t vdev_id, struct cdp_peer_setup_info *setup_info); + #else #define DP_PEER_SET_TYPE(_peer, _type_val) /* no op */ #define IS_MLO_DP_LINK_PEER(_peer) false @@ -1419,8 +1456,59 @@ void dp_mlo_peer_authorize(struct dp_soc *soc, struct dp_peer *link_peer) { } + +static inline uint8_t dp_mlo_get_chip_id(struct dp_soc *soc) +{ + return 0; +} + +static inline 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) +{ + return dp_peer_find_hash_find(soc, peer_mac_addr, + mac_addr_is_aligned, + vdev_id, mod_id); +} #endif /* WLAN_FEATURE_11BE_MLO */ +#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) +/** + * dp_mlo_partner_chips_map() - Map MLO peers to partner SOCs + * @soc: Soc handle + * @peer: DP peer handle for ML peer + * @peer_id: peer_id + * Return: None + */ +void dp_mlo_partner_chips_map(struct dp_soc *soc, + struct dp_peer *peer, + uint16_t peer_id); + +/** + * dp_mlo_partner_chips_unmap() - Unmap MLO peers to partner SOCs + * @soc: Soc handle + * @peer_id: peer_id + * Return: None + */ +void dp_mlo_partner_chips_unmap(struct dp_soc *soc, + uint16_t peer_id); +#else +static inline void dp_mlo_partner_chips_map(struct dp_soc *soc, + struct dp_peer *peer, + uint16_t peer_id) +{ +} + +static inline void dp_mlo_partner_chips_unmap(struct dp_soc *soc, + uint16_t peer_id) +{ +} +#endif + static inline QDF_STATUS dp_peer_rx_tids_create(struct dp_peer *peer) { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index ed65790e98..2abe14edb6 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1675,6 +1675,20 @@ struct dp_arch_ops { int (*dp_srng_test_and_update_nf_params)(struct dp_soc *soc, struct dp_srng *dp_srng, int *max_reap_limit); + + /* MLO ops */ +#ifdef WLAN_FEATURE_11BE_MLO + void (*mlo_peer_find_hash_detach)(struct dp_soc *soc); + QDF_STATUS (*mlo_peer_find_hash_attach)(struct dp_soc *soc); + void (*mlo_peer_find_hash_add)(struct dp_soc *soc, + struct dp_peer *peer); + void (*mlo_peer_find_hash_remove)(struct dp_soc *soc, + struct dp_peer *peer); + struct dp_peer *(*mlo_peer_find_hash_find)(struct dp_soc *soc, + uint8_t *peer_mac_addr, + int mac_addr_is_aligned, + enum dp_mod_id mod_id); +#endif }; /** @@ -1911,15 +1925,6 @@ struct dp_soc { TAILQ_HEAD(, dp_peer) * bins; } peer_hash; -#ifdef WLAN_FEATURE_11BE_MLO - /* Protect mld peer hash table */ - DP_MUTEX_TYPE mld_peer_hash_lock; - struct { - unsigned mask; - unsigned idx_bits; - TAILQ_HEAD(, dp_peer) * bins; - } mld_peer_hash; -#endif /* rx defrag state – TBD: do we need this per radio? */ struct { struct { @@ -3176,11 +3181,13 @@ struct dp_peer_mesh_latency_parameter { * @mac_add: Mac address * @vdev_id: Vdev ID for current link peer * @is_valid: flag for link peer info valid or not + * @chip_id: chip id */ struct dp_peer_link_info { union dp_align_mac_addr mac_addr; uint8_t vdev_id; uint8_t is_valid; + uint8_t chip_id; }; /**