|
@@ -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,74 +266,24 @@ 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);
|
|
|
-
|
|
|
- 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);
|
|
|
+ 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 index;
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -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;
|
|
|
}
|
|
|
}
|