summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath11k/dp_rx.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 33425707c084..5b717b731197 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -762,6 +762,9 @@ static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx,
struct ath11k_base *ab = dp->ab;
struct dp_rx_tid *rx_tid = ctx;
struct dp_reo_cache_flush_elem *elem, *tmp;
+ struct list_head flush_list;
+
+ INIT_LIST_HEAD(&flush_list);
if (status == HAL_REO_CMD_DRAIN) {
goto free_desc;
@@ -783,23 +786,25 @@ static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx,
list_add_tail(&elem->list, &dp->reo_cmd_cache_flush_list);
dp->reo_cmd_cache_flush_count++;
- /* Flush and invalidate aged REO desc from HW cache */
+ /* identify aged REO desc that needs removal */
list_for_each_entry_safe(elem, tmp, &dp->reo_cmd_cache_flush_list,
list) {
if (dp->reo_cmd_cache_flush_count > DP_REO_DESC_FREE_THRESHOLD ||
time_after(jiffies, elem->ts +
msecs_to_jiffies(DP_REO_DESC_FREE_TIMEOUT_MS))) {
- list_del(&elem->list);
+ list_move_tail(&elem->list, &flush_list);
dp->reo_cmd_cache_flush_count--;
- spin_unlock_bh(&dp->reo_cmd_lock);
-
- ath11k_dp_reo_cache_flush(ab, &elem->data);
- kfree(elem);
- spin_lock_bh(&dp->reo_cmd_lock);
}
}
spin_unlock_bh(&dp->reo_cmd_lock);
+ /* remove aged REO desc from HW */
+ list_for_each_entry_safe(elem, tmp, &flush_list, list) {
+ ath11k_dp_reo_cache_flush(ab, &elem->data);
+ list_del(&elem->list);
+ kfree(elem);
+ }
+
return;
free_desc:
dma_free_noncoherent(ab->dev, rx_tid->unaligned_size,