// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
*/
#include <crypto/hash.h>
#include "core.h"
#include "dp_tx.h"
#include "hal_tx.h"
#include "hif.h"
#include "debug.h"
#include "dp_rx.h"
#include "peer.h"
static void ath11k_dp_htt_htc_tx_complete(struct ath11k_base *ab,
struct sk_buff *skb)
{
dev_kfree_skb_any(skb);
}
void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
{
struct ath11k_base *ab = ar->ab;
struct ath11k_peer *peer;
/* TODO: Any other peer specific DP cleanup */
spin_lock_bh(&ab->base_lock);
peer = ath11k_peer_find(ab, vdev_id, addr);
if (!peer) {
ath11k_warn(ab, "failed to lookup peer %pM on vdev %d\n",
addr, vdev_id);
spin_unlock_bh(&ab->base_lock);
return;
}
ath11k_peer_rx_tid_cleanup(ar, peer);
crypto_free_shash(peer->tfm_mmic);
spin_unlock_bh(&ab->base_lock);
}
int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
{
struct ath11k_base *ab = ar->ab;
struct ath11k_peer *peer;
u32 reo_dest;
int ret = 0, tid;
/* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */
reo_dest = ar->dp.mac_id + 1;
ret = ath11k_wmi_set_peer_param(ar, addr, vdev_id,
WMI_PEER_SET_DEFAULT_ROUTING,
DP_RX_HASH_ENABLE | (reo_dest << 1));
if (ret) {
ath11k_warn(ab, "failed to set default routing %d peer :%pM vdev_id :%d\n",
ret, addr, vdev_id);
return ret;
}
for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {
ret = ath11k_peer_rx_tid_setup(ar, addr, vdev_id, tid, 1, 0,
HAL_PN_TYPE_NONE);
if (ret) {
ath11k_warn(ab, "failed to setup rxd tid queue for tid %d: %d\n",
tid, ret);
goto peer_clean;
}
}
ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
if (ret) {
ath11k_warn(ab, "failed to setup rx defrag context\n");
return ret;
}
/* TODO: Setup other peer specific resource used in data path */
return 0;
peer_clean:
spin_lock_bh(&ab->base_lock);
peer = ath11k_peer_find(ab, vdev_id, addr);
if (!peer) {
ath11k_warn(ab, "failed to find the peer to del rx tid\n");
spin_unlock_bh(&ab->base_lock);
return -ENOENT;
}
for (; tid >= 0; tid--)
ath11k_peer_rx_tid_delete(ar, peer, tid);
spin_unlock_bh(&ab->base_lock);
return ret;
}
void ath11k_dp_srng_cleanup(struct ath11k_base *ab, struct dp_srng *ring)
{
if (!ring->vaddr_unaligned)
return;
dma_free_coherent(