From 1d4d12e0e9dbbf6c24eb06a0fcfb8aabe06929e3 Mon Sep 17 00:00:00 2001 From: Rakesh Pillai Date: Fri, 13 Sep 2019 04:15:08 +0530 Subject: [PATCH] qcacmn: cdp: Convergence of cdp_bus_ops Currently the cdp apis are given pdev/vdev/peer handle as its arguments, which is directly accessed in those APIs. This can cause a race-condition in access of the respective handles, if it has been deleted in parallel. Hence as a part of cdp convergence, pass only the pdev/vdev id or peer mac address, which will be used to get the respective handles, and hence avoiding the unwanted access of the handles, if it has been deleted. Converged bus_ops - bus_suspend - bus_resume CRs-Fixed: 2539826 Change-Id: Id4d6ba16beae89f4052e72024ef8ce891ea33715 --- dp/inc/cdp_txrx_bus.h | 18 +++++++++--------- dp/inc/cdp_txrx_ops.h | 8 ++++---- dp/wifi3.0/dp_main.c | 19 ++++++++++++------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/dp/inc/cdp_txrx_bus.h b/dp/inc/cdp_txrx_bus.h index f6b9a3efe3..cda963e452 100644 --- a/dp/inc/cdp_txrx_bus.h +++ b/dp/inc/cdp_txrx_bus.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019 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 @@ -25,15 +25,15 @@ /** * cdp_bus_suspend() - suspend bus - * @soc - data path soc handle - * @ppdev: data path pdev handle + * @soc: data path soc handle + * @pdev_id: id of dp pdev handle * * suspend bus * * return QDF_STATUS_SUCCESS suspend is not implemented or suspend done */ static inline QDF_STATUS cdp_bus_suspend(ol_txrx_soc_handle soc, - struct cdp_pdev *ppdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->bus_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -42,21 +42,21 @@ static inline QDF_STATUS cdp_bus_suspend(ol_txrx_soc_handle soc, } if (soc->ops->bus_ops->bus_suspend) - return soc->ops->bus_ops->bus_suspend(ppdev); + return soc->ops->bus_ops->bus_suspend(soc, pdev_id); return QDF_STATUS_E_NOSUPPORT; } /** * cdp_bus_resume() - resume bus - * @soc - data path soc handle - * @ppdev: data path pdev handle + * @soc: data path soc handle + * @pdev_id: id of dp pdev handle * * resume bus * * return QDF_STATUS_SUCCESS resume is not implemented or suspend done */ static inline QDF_STATUS cdp_bus_resume(ol_txrx_soc_handle soc, - struct cdp_pdev *ppdev) + uint8_t pdev_id) { if (!soc || !soc->ops || !soc->ops->bus_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, @@ -65,7 +65,7 @@ static inline QDF_STATUS cdp_bus_resume(ol_txrx_soc_handle soc, } if (soc->ops->bus_ops->bus_resume) - return soc->ops->bus_ops->bus_resume(ppdev); + return soc->ops->bus_ops->bus_resume(soc, pdev_id); return QDF_STATUS_E_NOSUPPORT; } diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 7e36de5f7c..a5d958c7d7 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -1452,12 +1452,12 @@ struct cdp_tx_delay_ops { /** * struct cdp_bus_ops - mcl bus suspend/resume ops - * @bus_suspend: - * @bus_resume: + * @bus_suspend: handler for bus suspend + * @bus_resume: handler for bus resume */ struct cdp_bus_ops { - QDF_STATUS (*bus_suspend)(struct cdp_pdev *opaque_pdev); - QDF_STATUS (*bus_resume)(struct cdp_pdev *opaque_pdev); + QDF_STATUS (*bus_suspend)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + QDF_STATUS (*bus_resume)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); }; #endif diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 8e995165ad..1b3cb36685 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -9581,15 +9581,21 @@ static struct cdp_ipa_ops dp_ops_ipa = { #endif #ifdef DP_POWER_SAVE -static QDF_STATUS dp_bus_suspend(struct cdp_pdev *opaque_pdev) +static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct cdp_pdev *pdev = (struct cdp_pdev *) + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); int timeout = SUSPEND_DRAIN_WAIT; int drain_wait_delay = 50; /* 50 ms */ + if (qdf_unlikely(!pdev)) { + dp_err("pdev is NULL"); + return QDF_STATUS_E_INVAL; + } + /* Abort if there are any pending TX packets */ - while (dp_get_tx_pending(opaque_pdev) > 0) { + while (dp_get_tx_pending(pdev) > 0) { qdf_sleep(drain_wait_delay); if (timeout <= 0) { dp_err("TX frames are pending, abort suspend"); @@ -9604,10 +9610,9 @@ static QDF_STATUS dp_bus_suspend(struct cdp_pdev *opaque_pdev) return QDF_STATUS_SUCCESS; } -static QDF_STATUS dp_bus_resume(struct cdp_pdev *opaque_pdev) +static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { - struct dp_pdev *pdev = (struct dp_pdev *)opaque_pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); if (soc->intr_mode == DP_INTR_POLL) qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);