diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index e1b711d8a6be..ddac4bd191df 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -469,7 +469,6 @@ static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status) { struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt; - struct hal_reo_cmd_params params; if (reo_status->queue_status.header.status) { /* Should not happen normally. Just print error for now */ @@ -479,14 +478,6 @@ static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt, reo_status->rx_queue_status.header.status, rx_tid->tid); } - - qdf_mem_zero(¶ms, sizeof(params)); - - params.std.need_status = 1; - params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff; - params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32; - - dp_reo_send_cmd(soc, CMD_GET_QUEUE_STATS, ¶ms, dp_rx_tid_stats_cb, rx_tid); } /* @@ -704,8 +695,7 @@ static void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, rx_tid->hw_qdesc_vaddr_unaligned, rx_tid->hw_qdesc_paddr_unaligned, 0); - rx_tid->hw_qdesc_vaddr_unaligned = NULL; - rx_tid->hw_qdesc_alloc_size = 0; + qdf_mem_free(rx_tid); } /* @@ -720,6 +710,15 @@ static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid) struct dp_rx_tid *rx_tid = &(peer->rx_tid[tid]); struct dp_soc *soc = peer->vdev->pdev->soc; struct hal_reo_cmd_params params; + struct dp_rx_tid *rx_tid_copy = qdf_mem_malloc(sizeof(*rx_tid_copy)); + if (!rx_tid_copy) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s: malloc failed for rx_tid_copy: tid %d\n", + __func__, rx_tid->tid); + return -ENOMEM; + } + + *rx_tid_copy = *rx_tid; qdf_mem_zero(¶ms, sizeof(params)); @@ -729,8 +728,11 @@ static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid) params.u.upd_queue_params.update_vld = 1; params.u.upd_queue_params.vld = 0; + rx_tid->hw_qdesc_vaddr_unaligned = NULL; + rx_tid->hw_qdesc_alloc_size = 0; + dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, ¶ms, - dp_rx_tid_delete_cb, (void *)rx_tid); + dp_rx_tid_delete_cb, (void *)rx_tid_copy); return 0; } diff --git a/dp/wifi3.0/dp_reo.c b/dp/wifi3.0/dp_reo.c index 1f0d8f4269c8..14571e2cbad2 100644 --- a/dp/wifi3.0/dp_reo.c +++ b/dp/wifi3.0/dp_reo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017 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 @@ -58,7 +58,7 @@ QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc, enum hal_reo_cmd_type type, return QDF_STATUS_E_FAILURE; }; - if (num == QDF_STATUS_E_FAILURE) { + if (num < 0) { qdf_print("%s: Error with sending REO command\n", __func__); return QDF_STATUS_E_FAILURE; } diff --git a/hal/wifi3.0/hal_reo.c b/hal/wifi3.0/hal_reo.c index 3c68b693db26..4e8a195b5c60 100644 --- a/hal/wifi3.0/hal_reo.c +++ b/hal/wifi3.0/hal_reo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017 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 @@ -87,13 +87,20 @@ inline int hal_reo_cmd_queue_stats(void *reo_ring, struct hal_soc *soc, hal_srng_access_start(soc, reo_ring); reo_desc = hal_srng_src_get_next(soc, reo_ring); + if (!reo_desc) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Out of cmd ring entries\n", __func__); + hal_srng_access_end(soc, reo_ring); + return -EBUSY; + } HAL_SET_TLV_HDR(reo_desc, WIFIREO_GET_QUEUE_STATS_E, - sizeof(struct reo_update_rx_reo_queue)); + sizeof(struct reo_get_queue_stats)); /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); + qdf_mem_zero((void *)reo_desc, sizeof(struct reo_get_queue_stats)); HAL_DESC_SET_FIELD(reo_desc, UNIFORM_REO_CMD_HEADER_0, REO_STATUS_REQUIRED, cmd->std.need_status); @@ -119,13 +126,20 @@ inline int hal_reo_cmd_flush_queue(void *reo_ring, struct hal_soc *soc, hal_srng_access_start(soc, reo_ring); reo_desc = hal_srng_src_get_next(soc, reo_ring); + if (!reo_desc) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Out of cmd ring entries\n", __func__); + hal_srng_access_end(soc, reo_ring); + return -EBUSY; + } HAL_SET_TLV_HDR(reo_desc, WIFIREO_FLUSH_QUEUE_E, - sizeof(struct reo_update_rx_reo_queue)); + sizeof(struct reo_flush_queue)); /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); + qdf_mem_zero((void *)reo_desc, sizeof(struct reo_flush_queue)); HAL_DESC_SET_FIELD(reo_desc, UNIFORM_REO_CMD_HEADER_0, REO_STATUS_REQUIRED, cmd->std.need_status); @@ -167,18 +181,25 @@ inline int hal_reo_cmd_flush_cache(void *reo_ring, struct hal_soc *soc, if (index > 3) { qdf_print("%s, No blocking resource available!\n", __func__); hal_srng_access_end(soc, reo_ring); - return QDF_STATUS_E_FAILURE; + return -EBUSY; } soc->index = index; reo_desc = hal_srng_src_get_next(soc, reo_ring); + if (!reo_desc) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Out of cmd ring entries\n", __func__); + hal_srng_access_end(soc, reo_ring); + return -EBUSY; + } HAL_SET_TLV_HDR(reo_desc, WIFIREO_FLUSH_CACHE_E, - sizeof(struct reo_update_rx_reo_queue)); + sizeof(struct reo_flush_cache)); /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); + qdf_mem_zero((void *)reo_desc, sizeof(struct reo_flush_cache)); HAL_DESC_SET_FIELD(reo_desc, UNIFORM_REO_CMD_HEADER_0, REO_STATUS_REQUIRED, cmd->std.need_status); @@ -227,18 +248,25 @@ inline int hal_reo_cmd_unblock_cache(void *reo_ring, struct hal_soc *soc, hal_srng_access_end(soc, reo_ring); qdf_print("%s: No blocking resource to unblock!\n", __func__); - return QDF_STATUS_E_FAILURE; + return -EBUSY; } } reo_desc = hal_srng_src_get_next(soc, reo_ring); + if (!reo_desc) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Out of cmd ring entries\n", __func__); + hal_srng_access_end(soc, reo_ring); + return -EBUSY; + } HAL_SET_TLV_HDR(reo_desc, WIFIREO_UNBLOCK_CACHE_E, - sizeof(struct reo_update_rx_reo_queue)); + sizeof(struct reo_unblock_cache)); /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); + qdf_mem_zero((void *)reo_desc, sizeof(struct reo_unblock_cache)); HAL_DESC_SET_FIELD(reo_desc, UNIFORM_REO_CMD_HEADER_0, REO_STATUS_REQUIRED, cmd->std.need_status); @@ -265,13 +293,20 @@ inline int hal_reo_cmd_flush_timeout_list(void *reo_ring, struct hal_soc *soc, hal_srng_access_start(soc, reo_ring); reo_desc = hal_srng_src_get_next(soc, reo_ring); + if (!reo_desc) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Out of cmd ring entries\n", __func__); + hal_srng_access_end(soc, reo_ring); + return -EBUSY; + } HAL_SET_TLV_HDR(reo_desc, WIFIREO_FLUSH_TIMEOUT_LIST_E, - sizeof(struct reo_update_rx_reo_queue)); + sizeof(struct reo_flush_timeout_list)); /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); + qdf_mem_zero((void *)reo_desc, sizeof(struct reo_flush_timeout_list)); HAL_DESC_SET_FIELD(reo_desc, UNIFORM_REO_CMD_HEADER_0, REO_STATUS_REQUIRED, cmd->std.need_status); @@ -303,6 +338,12 @@ inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc, hal_srng_access_start(soc, reo_ring); reo_desc = hal_srng_src_get_next(soc, reo_ring); + if (!reo_desc) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, + "%s: Out of cmd ring entries\n", __func__); + hal_srng_access_end(soc, reo_ring); + return -EBUSY; + } HAL_SET_TLV_HDR(reo_desc, WIFIREO_UPDATE_RX_REO_QUEUE_E, sizeof(struct reo_update_rx_reo_queue)); @@ -310,6 +351,7 @@ inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc, /* Offsets of descriptor fields defined in HW headers start from * the field after TLV header */ reo_desc += (sizeof(struct tlv_32_hdr) >> 2); + qdf_mem_zero((void *)reo_desc, sizeof(struct reo_update_rx_reo_queue)); HAL_DESC_SET_FIELD(reo_desc, UNIFORM_REO_CMD_HEADER_0, REO_STATUS_REQUIRED, cmd->std.need_status);