diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index bf5dfa7cef..de2a1670b0 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -1019,7 +1019,10 @@ static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt, { struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt; - if (reo_status->queue_status.header.status) { + if ((reo_status->rx_queue_status.header.status != + HAL_REO_CMD_SUCCESS) && + (reo_status->rx_queue_status.header.status != + HAL_REO_CMD_DRAIN)) { /* Should not happen normally. Just print error for now */ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: Rx tid HW desc update failed(%d): tid %d\n", @@ -1114,7 +1117,10 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, (struct reo_desc_list_node *)cb_ctxt; struct dp_rx_tid *rx_tid = &freedesc->rx_tid; - if (reo_status->rx_queue_status.header.status) { + if ((reo_status->fl_cache_status.header.status != + HAL_REO_CMD_SUCCESS) && + (reo_status->fl_cache_status.header.status != + HAL_REO_CMD_DRAIN)) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: Rx tid HW desc flush failed(%d): tid %d\n", __func__, @@ -1317,8 +1323,13 @@ static void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, uint32_t desc_size, tot_desc_size; struct hal_reo_cmd_params params; - - if (reo_status->rx_queue_status.header.status) { + if (reo_status->rx_queue_status.header.status == HAL_REO_CMD_DRAIN) { + qdf_mem_zero(reo_status, sizeof(*reo_status)); + reo_status->fl_cache_status.header.status = HAL_REO_CMD_DRAIN; + dp_reo_desc_free(soc, (void *)freedesc, reo_status); + return; + } else if (reo_status->rx_queue_status.header.status != + HAL_REO_CMD_SUCCESS) { /* Should not happen normally. Just print error for now */ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s: Rx tid HW desc deletion failed(%d): tid %d\n", diff --git a/dp/wifi3.0/dp_reo.c b/dp/wifi3.0/dp_reo.c index 31d2e8ac47..d7fc4d3eb6 100644 --- a/dp/wifi3.0/dp_reo.c +++ b/dp/wifi3.0/dp_reo.c @@ -178,12 +178,17 @@ void dp_reo_cmdlist_destroy(struct dp_soc *soc) { struct dp_reo_cmd_info *reo_cmd = NULL; struct dp_reo_cmd_info *tmp_cmd = NULL; + union hal_reo_status reo_status; + + reo_status.queue_status.header.status = + HAL_REO_CMD_DRAIN; qdf_spin_lock_bh(&soc->rx.reo_cmd_lock); TAILQ_FOREACH_SAFE(reo_cmd, &soc->rx.reo_cmd_list, - reo_cmd_list_elem, tmp_cmd) { + reo_cmd_list_elem, tmp_cmd) { TAILQ_REMOVE(&soc->rx.reo_cmd_list, reo_cmd, - reo_cmd_list_elem); + reo_cmd_list_elem); + reo_cmd->handler(soc, reo_cmd->data, &reo_status); qdf_mem_free(reo_cmd); } qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock); diff --git a/hal/wifi3.0/hal_reo.h b/hal/wifi3.0/hal_reo.h index 3b4c02d463..3dd5740a47 100644 --- a/hal/wifi3.0/hal_reo.h +++ b/hal/wifi3.0/hal_reo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -137,7 +137,8 @@ enum reo_cmd_exec_status { HAL_REO_CMD_SUCCESS = 0, HAL_REO_CMD_BLOCKED = 1, HAL_REO_CMD_FAILED = 2, - HAL_REO_CMD_RESOURCE_BLOCKED = 3 + HAL_REO_CMD_RESOURCE_BLOCKED = 3, + HAL_REO_CMD_DRAIN = 0xff }; /**