summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath11k/dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/dp.c')
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.c72
1 files changed, 41 insertions, 31 deletions
diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index 8b790ce72e5d..56b1a657e0b0 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -1,9 +1,12 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <crypto/hash.h>
+#include <linux/export.h>
#include "core.h"
#include "dp_tx.h"
#include "hal_tx.h"
@@ -35,6 +38,7 @@ void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
}
ath11k_peer_rx_tid_cleanup(ar, peer);
+ peer->dp_setup_done = false;
crypto_free_shash(peer->tfm_mmic);
spin_unlock_bh(&ab->base_lock);
}
@@ -71,7 +75,8 @@ int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
if (ret) {
ath11k_warn(ab, "failed to setup rx defrag context\n");
- return ret;
+ tid--;
+ goto peer_clean;
}
/* TODO: Setup other peer specific resource used in data path */
@@ -102,7 +107,8 @@ void ath11k_dp_srng_cleanup(struct ath11k_base *ab, struct dp_srng *ring)
return;
if (ring->cached)
- kfree(ring->vaddr_unaligned);
+ dma_free_noncoherent(ab->dev, ring->size, ring->vaddr_unaligned,
+ ring->paddr_unaligned, DMA_FROM_DEVICE);
else
dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
ring->paddr_unaligned);
@@ -131,13 +137,11 @@ static int ath11k_dp_srng_calculate_msi_group(struct ath11k_base *ab,
switch (type) {
case HAL_WBM2SW_RELEASE:
- if (ring_num < 3) {
- grp_mask = &ab->hw_params.ring_mask->tx[0];
- } else if (ring_num == 3) {
+ if (ring_num == DP_RX_RELEASE_RING_NUM) {
grp_mask = &ab->hw_params.ring_mask->rx_wbm_rel[0];
ring_num = 0;
} else {
- return -ENOENT;
+ grp_mask = &ab->hw_params.ring_mask->tx[0];
}
break;
case HAL_REO_EXCEPTION:
@@ -221,7 +225,7 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring,
enum hal_ring_type type, int ring_num,
int mac_id, int num_entries)
{
- struct hal_srng_params params = { 0 };
+ struct hal_srng_params params = {};
int entry_sz = ath11k_hal_srng_get_entrysize(ab, type);
int max_entries = ath11k_hal_srng_get_max_entries(ab, type);
int ret;
@@ -245,14 +249,14 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring,
default:
cached = false;
}
-
- if (cached) {
- ring->vaddr_unaligned = kzalloc(ring->size, GFP_KERNEL);
- ring->paddr_unaligned = virt_to_phys(ring->vaddr_unaligned);
- }
}
- if (!cached)
+ if (cached)
+ ring->vaddr_unaligned = dma_alloc_noncoherent(ab->dev, ring->size,
+ &ring->paddr_unaligned,
+ DMA_FROM_DEVICE,
+ GFP_KERNEL);
+ else
ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size,
&ring->paddr_unaligned,
GFP_KERNEL);
@@ -371,6 +375,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
struct ath11k_dp *dp = &ab->dp;
struct hal_srng *srng;
int i, ret;
+ u8 tcl_num, wbm_num;
ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring,
HAL_SW2WBM_RELEASE, 0, 0,
@@ -396,9 +401,12 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
}
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
+ tcl_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].tcl_ring_num;
+ wbm_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num;
+
ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring,
- HAL_TCL_DATA, i, 0,
- DP_TCL_DATA_RING_SIZE);
+ HAL_TCL_DATA, tcl_num, 0,
+ ab->hw_params.tx_ring_size);
if (ret) {
ath11k_warn(ab, "failed to set up tcl_data ring (%d) :%d\n",
i, ret);
@@ -406,7 +414,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
}
ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_comp_ring,
- HAL_WBM2SW_RELEASE, i, 0,
+ HAL_WBM2SW_RELEASE, wbm_num, 0,
DP_TX_COMP_RING_SIZE);
if (ret) {
ath11k_warn(ab, "failed to set up tcl_comp ring (%d) :%d\n",
@@ -431,7 +439,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
}
ret = ath11k_dp_srng_setup(ab, &dp->rx_rel_ring, HAL_WBM2SW_RELEASE,
- 3, 0, DP_RX_RELEASE_RING_SIZE);
+ DP_RX_RELEASE_RING_NUM, 0, DP_RX_RELEASE_RING_SIZE);
if (ret) {
ath11k_warn(ab, "failed to set up rx_rel ring :%d\n", ret);
goto err;
@@ -774,9 +782,10 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
int i, j;
int tot_work_done = 0;
- if (ab->hw_params.ring_mask->tx[grp_id]) {
- i = __fls(ab->hw_params.ring_mask->tx[grp_id]);
- ath11k_dp_tx_completion_handler(ab, i);
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
+ if (BIT(ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num) &
+ ab->hw_params.ring_mask->tx[grp_id])
+ ath11k_dp_tx_completion_handler(ab, i);
}
if (ab->hw_params.ring_mask->rx_err[grp_id]) {
@@ -810,8 +819,8 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
if (ab->hw_params.ring_mask->rx_mon_status[grp_id]) {
for (i = 0; i < ab->num_radios; i++) {
- for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
- int id = i * ab->hw_params.num_rxmda_per_pdev + j;
+ for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
+ int id = i * ab->hw_params.num_rxdma_per_pdev + j;
if (ab->hw_params.ring_mask->rx_mon_status[grp_id] &
BIT(id)) {
@@ -833,8 +842,8 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
ath11k_dp_process_reo_status(ab);
for (i = 0; i < ab->num_radios; i++) {
- for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
- int id = i * ab->hw_params.num_rxmda_per_pdev + j;
+ for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
+ int id = i * ab->hw_params.num_rxdma_per_pdev + j;
if (ab->hw_params.ring_mask->rxdma2host[grp_id] & BIT(id)) {
work_done = ath11k_dp_process_rxdma_err(ab, id, budget);
@@ -868,7 +877,7 @@ void ath11k_dp_pdev_free(struct ath11k_base *ab)
struct ath11k *ar;
int i;
- del_timer_sync(&ab->mon_reap_timer);
+ timer_delete_sync(&ab->mon_reap_timer);
for (i = 0; i < ab->num_radios; i++) {
ar = ab->pdevs[i].ar;
@@ -893,7 +902,7 @@ void ath11k_dp_pdev_pre_alloc(struct ath11k_base *ab)
spin_lock_init(&dp->rx_refill_buf_ring.idr_lock);
atomic_set(&dp->num_tx_pending, 0);
init_waitqueue_head(&dp->tx_empty_waitq);
- for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
+ for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
idr_init(&dp->rx_mon_status_refill_ring[j].bufs_idr);
spin_lock_init(&dp->rx_mon_status_refill_ring[j].idr_lock);
}
@@ -963,7 +972,7 @@ static void ath11k_dp_update_vdev_search(struct ath11k_vif *arvif)
{
/* When v2_map_support is true:for STA mode, enable address
* search index, tcl uses ast_hash value in the descriptor.
- * When v2_map_support is false: for STA mode, dont' enable
+ * When v2_map_support is false: for STA mode, don't enable
* address search index.
*/
switch (arvif->vdev_type) {
@@ -1003,7 +1012,7 @@ void ath11k_dp_vdev_tx_attach(struct ath11k *ar, struct ath11k_vif *arvif)
static int ath11k_dp_tx_pending_cleanup(int buf_id, void *skb, void *ctx)
{
- struct ath11k_base *ab = (struct ath11k_base *)ctx;
+ struct ath11k_base *ab = ctx;
struct sk_buff *msdu = skb;
dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,
@@ -1110,8 +1119,9 @@ fail_link_desc_cleanup:
static void ath11k_dp_shadow_timer_handler(struct timer_list *t)
{
- struct ath11k_hp_update_timer *update_timer = from_timer(update_timer,
- t, timer);
+ struct ath11k_hp_update_timer *update_timer = timer_container_of(update_timer,
+ t,
+ timer);
struct ath11k_base *ab = update_timer->ab;
struct hal_srng *srng = &ab->hal.srng_list[update_timer->ring_id];
@@ -1163,7 +1173,7 @@ void ath11k_dp_shadow_stop_timer(struct ath11k_base *ab,
if (!update_timer->init)
return;
- del_timer_sync(&update_timer->timer);
+ timer_delete_sync(&update_timer->timer);
}
void ath11k_dp_shadow_init_timer(struct ath11k_base *ab,