--- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -93,6 +93,25 @@ struct ath11k_peer *ath11k_peer_find_by_ return NULL; } +struct ath11k_peer *ath11k_peer_find_by_pdev_idx(struct ath11k_base *ab, + u8 pdev_idx, const u8 *addr) +{ + struct ath11k_peer *peer; + + lockdep_assert_held(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (peer->pdev_idx != pdev_idx) + continue; + if (!ether_addr_equal(peer->addr, addr)) + continue; + + return peer; + } + + return NULL; +} + struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, int ast_hash) { @@ -867,13 +886,21 @@ int ath11k_peer_create(struct ath11k *ar return -ENOBUFS; } + mutex_lock(&ar->ab->tbl_mtx_lock); spin_lock_bh(&ar->ab->base_lock); - peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr); + peer = ath11k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, param->peer_addr); if (peer) { spin_unlock_bh(&ar->ab->base_lock); + mutex_unlock(&ar->ab->tbl_mtx_lock); return -EINVAL; } + + peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr); + if (peer) + ath11k_peer_rhash_delete(ar->ab, peer); + spin_unlock_bh(&ar->ab->base_lock); + mutex_unlock(&ar->ab->tbl_mtx_lock); ret = ath11k_wmi_send_peer_create_cmd(ar, param); if (ret) {