// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
if (!ab->rhead_peer_id || !ab->rhead_peer_addr) return -EPERM;
ret = ath11k_peer_rhash_insert(ab, ab->rhead_peer_id, &peer->rhash_id,
&ab->rhash_peer_id_param, &peer->peer_id); if (ret) {
ath11k_warn(ab, "failed to add peer %pM with id %d in rhash_id ret %d\n",
peer->addr, peer->peer_id, ret); return ret;
}
ret = ath11k_peer_rhash_insert(ab, ab->rhead_peer_addr, &peer->rhash_addr,
&ab->rhash_peer_addr_param, &peer->addr); if (ret) {
ath11k_warn(ab, "failed to add peer %pM with id %d in rhash_addr ret %d\n",
peer->addr, peer->peer_id, ret); goto err_clean;
}
peer = ath11k_peer_find_by_addr(ab, addr); /* Check if the found peer is what we want to remove. * While the sta is transitioning to another band we may * have 2 peer with the same addr assigned to different * vdev_id. Make sure we are deleting the correct peer.
*/ if (peer && peer->vdev_id == vdev_id)
ath11k_peer_rhash_delete(ab, peer);
/* Fallback to peer list search if the correct peer can't be found. * Skip the deletion of the peer from the rhash since it has already * been deleted in peer add.
*/ if (!peer)
peer = ath11k_peer_find(ab, vdev_id, addr);
if (!peer) {
spin_unlock_bh(&ab->base_lock);
mutex_unlock(&ab->tbl_mtx_lock);
ath11k_warn(ab, "failed to find peer vdev_id %d addr %pM in delete\n",
vdev_id, addr); return -EINVAL;
}
if (ar->num_peers > (ar->max_num_peers - 1)) {
ath11k_warn(ar->ab, "failed to create peer due to insufficient peer entry resource in firmware\n"); 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); if (peer) { if (peer->vdev_id == param->vdev_id) {
spin_unlock_bh(&ar->ab->base_lock);
mutex_unlock(&ar->ab->tbl_mtx_lock); return -EINVAL;
}
/* Assume sta is transitioning to another band. * Remove here the peer from rhash.
*/
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) {
ath11k_warn(ar->ab, "failed to send peer create vdev_id %d ret %d\n",
param->vdev_id, ret); return ret;
}
ret = ath11k_wait_for_peer_created(ar, param->vdev_id,
param->peer_addr); if (ret) return ret;
if (!ab->rhead_peer_id || !ab->rhead_peer_addr) return -EPERM;
ret = ath11k_peer_rhash_remove(ab, ab->rhead_peer_addr, &peer->rhash_addr,
&ab->rhash_peer_addr_param); if (ret) {
ath11k_warn(ab, "failed to remove peer %pM id %d in rhash_addr ret %d\n",
peer->addr, peer->peer_id, ret); return ret;
}
ret = ath11k_peer_rhash_remove(ab, ab->rhead_peer_id, &peer->rhash_id,
&ab->rhash_peer_id_param); if (ret) {
ath11k_warn(ab, "failed to remove peer %pM id %d in rhash_id ret %d\n",
peer->addr, peer->peer_id, ret); return ret;
}
size = sizeof(*ab->rhead_peer_id);
rhash_id_tbl = kzalloc(size, GFP_KERNEL); if (!rhash_id_tbl) {
ath11k_warn(ab, "failed to init rhash id table due to no mem (size %zu)\n",
size); return -ENOMEM;
}
size = sizeof(*ab->rhead_peer_addr);
rhash_addr_tbl = kzalloc(size, GFP_KERNEL); if (!rhash_addr_tbl) {
ath11k_warn(ab, "failed to init rhash addr table due to no mem (size %zu)\n",
size); return -ENOMEM;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.