diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index 88502d8627..318c5d9a48 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -1355,11 +1355,13 @@ 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) + enum dp_mod_id mod_id, + uint8_t vdev_id) { union dp_align_mac_addr local_mac_addr_aligned, *mac_addr; uint32_t index; struct dp_peer *peer; + struct dp_vdev *vdev; dp_mld_peer_hash_obj_t mld_hash_obj; mld_hash_obj = dp_mlo_get_peer_hash_obj(soc); @@ -1378,22 +1380,43 @@ dp_mlo_peer_find_hash_find_be(struct dp_soc *soc, mac_addr = &local_mac_addr_aligned; } + if (vdev_id != DP_VDEV_ALL) { + vdev = dp_vdev_get_ref_by_id(soc, vdev_id, mod_id); + if (!vdev) { + dp_err("vdev is null\n"); + return NULL; + } + } else { + vdev = NULL; + } /* 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) != + if ((vdev_id == DP_VDEV_ALL) || ( + dp_peer_find_mac_addr_cmp( + &peer->vdev->mld_mac_addr, + &vdev->mld_mac_addr) == 0)) { + /* take peer reference before returning */ + if (dp_peer_get_ref(NULL, peer, mod_id) != QDF_STATUS_SUCCESS) - peer = NULL; + peer = NULL; - qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock); - return peer; + if (vdev) + dp_vdev_unref_delete(soc, vdev, mod_id); + + qdf_spin_unlock_bh( + &mld_hash_obj->mld_peer_hash_lock); + return peer; + } } } + + if (vdev) + dp_vdev_unref_delete(soc, vdev, mod_id); + qdf_spin_unlock_bh(&mld_hash_obj->mld_peer_hash_lock); return NULL; /* failure */ diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index cf9c0c2cf8..9c5b399d25 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -2941,6 +2941,10 @@ static void dp_htt_mlo_peer_map_handler(struct htt_soc *soc, uint16_t mlo_peer_id; uint8_t num_links; struct dp_mlo_flow_override_info mlo_flow_info[DP_MLO_FLOW_INFO_MAX]; + struct dp_mlo_link_info mlo_link_info[DP_MAX_MLO_LINKS]; + MLO_PEER_MAP_TLV_TAG_ID tlv_type = 0xff; + uint32_t tlv_len = 0; + int i = 0; mlo_peer_id = HTT_RX_MLO_PEER_MAP_MLO_PEER_ID_GET(*msg_word); num_links = @@ -2982,9 +2986,34 @@ static void dp_htt_mlo_peer_map_handler(struct htt_soc *soc, mlo_flow_info[2].cache_set_num = HTT_RX_MLO_PEER_MAP_CACHE_SET_NUM_AST_INDEX_GET(*(msg_word + 3)); + msg_word = msg_word + 8; + while (msg_word && (i < DP_MAX_MLO_LINKS)) { + mlo_link_info[i].peer_chip_id = 0xFF; + mlo_link_info[i].vdev_id = 0xFF; + + tlv_type = HTT_RX_MLO_PEER_MAP_TLV_TAG_GET(*msg_word); + tlv_len = HTT_RX_MLO_PEER_MAP_TLV_LENGTH_GET(*msg_word); + + if (tlv_len == 0) { + dp_err("TLV Length is 0"); + break; + } + + if (tlv_type == MLO_PEER_MAP_TLV_STRUCT_SOC_VDEV_PEER_IDS) { + mlo_link_info[i].peer_chip_id = + HTT_RX_MLO_PEER_MAP_CHIP_ID_GET( + *(msg_word + 1)); + mlo_link_info[i].vdev_id = + HTT_RX_MLO_PEER_MAP_VDEV_ID_GET( + *(msg_word + 1)); + } + msg_word = (uint32_t *)(((uint8_t *)msg_word) + tlv_len); + i++; + } + dp_rx_mlo_peer_map_handler(soc->dp_soc, mlo_peer_id, mlo_peer_mac_addr, - mlo_flow_info); + mlo_flow_info, mlo_link_info); } static void dp_htt_mlo_peer_unmap_handler(struct htt_soc *soc, diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 44d2d700aa..7ee61ce0a1 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -7387,7 +7387,7 @@ QDF_STATUS dp_peer_mlo_setup( peer->primary_link = setup_info->is_primary_link; mld_peer = dp_peer_find_hash_find(soc, setup_info->mld_peer_mac, - 0, DP_VDEV_ALL, DP_MOD_ID_CDP); + 0, vdev_id, DP_MOD_ID_CDP); if (mld_peer) { if (setup_info->is_first_link) { /* assign rx_tid to mld peer */ diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index f281246afd..95c621a90f 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -520,7 +520,7 @@ struct dp_peer *dp_peer_find_hash_find(struct dp_soc *soc, 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); + mod_id, vdev_id); return NULL; } @@ -2709,13 +2709,15 @@ static inline uint16_t dp_gen_ml_peer_id(struct dp_soc *soc, QDF_STATUS dp_rx_mlo_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, uint8_t *peer_mac_addr, - struct dp_mlo_flow_override_info *mlo_flow_info) + struct dp_mlo_flow_override_info *mlo_flow_info, + struct dp_mlo_link_info *mlo_link_info) { struct dp_peer *peer = NULL; uint16_t hw_peer_id = mlo_flow_info[0].ast_idx; uint16_t ast_hash = mlo_flow_info[0].cache_set_num; - uint8_t vdev_id = DP_VDEV_ALL; + uint8_t vdev_id = 0; uint8_t is_wds = 0; + int i; uint16_t ml_peer_id = dp_gen_ml_peer_id(soc, peer_id); enum cdp_txrx_ast_entry_type type = CDP_TXRX_AST_TYPE_STATIC; QDF_STATUS err = QDF_STATUS_SUCCESS; @@ -2725,6 +2727,16 @@ dp_rx_mlo_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, soc, peer_id, ml_peer_id, QDF_MAC_ADDR_REF(peer_mac_addr)); + /* Get corresponding vdev ID for the peer based + * on chip ID obtained from mlo peer_map event + */ + for (i = 0; i < DP_MAX_MLO_LINKS; i++) { + if (mlo_link_info[i].peer_chip_id == dp_mlo_get_chip_id(soc)) { + vdev_id = mlo_link_info[i].vdev_id; + break; + } + } + peer = dp_peer_find_add_id(soc, peer_mac_addr, ml_peer_id, hw_peer_id, vdev_id); diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 6729caa8a3..a50c31da18 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -618,6 +618,7 @@ void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, * @peer_id - ML peer_id from firmware * @peer_mac_addr - mac address of the peer * @mlo_ast_flow_info: MLO AST flow info + * @mlo_link_info - MLO link info * * associate the ML peer_id that firmware provided with peer entry * and update the ast table in the host with the hw_peer_id. @@ -627,7 +628,8 @@ void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, QDF_STATUS dp_rx_mlo_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, uint8_t *peer_mac_addr, - struct dp_mlo_flow_override_info *mlo_flow_info); + struct dp_mlo_flow_override_info *mlo_flow_info, + struct dp_mlo_link_info *mlo_link_info); /** * dp_rx_mlo_peer_unmap_handler() - handle MLO peer unmap event from firmware diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 99b86521a5..d706ba7b3f 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1804,7 +1804,8 @@ struct dp_arch_ops { 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); + enum dp_mod_id mod_id, + uint8_t vdev_id); #endif void (*txrx_print_peer_stats)(struct cdp_peer_stats *peer_stats, enum peer_stats_type stats_type); @@ -3311,6 +3312,16 @@ struct dp_mlo_flow_override_info { uint8_t cache_set_num; }; +/** + * struct dp_mlo_link_info - Link info + * @peer_chip_id: Peer Chip ID + * @vdev_id: Vdev ID + */ +struct dp_mlo_link_info { + uint8_t peer_chip_id; + uint8_t vdev_id; +}; + #ifdef WLAN_SUPPORT_MSCS /*MSCS Procedure based macros */ #define IEEE80211_MSCS_MAX_ELEM_SIZE 5