diff options
| -rw-r--r-- | drivers/net/wireless/ath/ath11k/dp_rx.c | 19 |
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, |
