From dda167ca8104de77f46fd29c66f66f807c63b309 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 23 Jan 2017 10:37:57 -0800 Subject: [PATCH] qcacld-3.0: Use request manager for station stats We are transitioning to the new request manager framework. Change wlan_hdd_get_station_stats() and hdd_get_station_statistics_cb() to this framework. Change-Id: I4f0255975e8c37fa91215bcddc7896bb8d309cf8 CRs-Fixed: 2005303 --- core/hdd/src/wlan_hdd_wext.c | 132 ++++++++++++++++------------------- 1 file changed, 61 insertions(+), 71 deletions(-) diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index d0e912a59cf7..c98347f609ad 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -4330,66 +4330,53 @@ return_cached_results: return QDF_STATUS_SUCCESS; } +struct station_stats { + tCsrSummaryStatsInfo summary_stats; + tCsrGlobalClassAStatsInfo class_a_stats; + struct csr_per_chain_rssi_stats_info per_chain_rssi_stats; +}; + /** * hdd_get_station_statistics_cb() - Get stats callback function - * @pStats: pointer to Class A stats - * @pContext: user context originally registered with SME + * @stats: pointer to combined station stats + * @context: user context originally registered with SME (always the + * cookie from the request context) * * Return: None */ -static void hdd_get_station_statistics_cb(void *pStats, void *pContext) +static void hdd_get_station_statistics_cb(void *stats, void *context) { - struct statsContext *pStatsContext; - tCsrSummaryStatsInfo *pSummaryStats; - tCsrGlobalClassAStatsInfo *pClassAStats; + struct hdd_request *request; + struct station_stats *priv; + tCsrSummaryStatsInfo *summary_stats; + tCsrGlobalClassAStatsInfo *class_a_stats; struct csr_per_chain_rssi_stats_info *per_chain_rssi_stats; - hdd_adapter_t *pAdapter; - if ((NULL == pStats) || (NULL == pContext)) { + if ((NULL == stats) || (NULL == context)) { hdd_err("Bad param, pStats [%p] pContext [%p]", - pStats, pContext); + stats, context); return; } - /* there is a race condition that exists between this callback - * function and the caller since the caller could time out - * either before or while this code is executing. we use a - * spinlock to serialize these actions - */ - spin_lock(&hdd_context_lock); + request = hdd_request_get(context); + if (!request) { + hdd_err("Obsolete request"); + return; + } - pSummaryStats = (tCsrSummaryStatsInfo *) pStats; - pClassAStats = (tCsrGlobalClassAStatsInfo *) (pSummaryStats + 1); + summary_stats = (tCsrSummaryStatsInfo *) stats; + class_a_stats = (tCsrGlobalClassAStatsInfo *) (summary_stats + 1); per_chain_rssi_stats = (struct csr_per_chain_rssi_stats_info *) - (pClassAStats + 1); - pStatsContext = pContext; - pAdapter = pStatsContext->pAdapter; - if ((NULL == pAdapter) || - (STATS_CONTEXT_MAGIC != pStatsContext->magic)) { - /* the caller presumably timed out so there is nothing - * we can do - */ - spin_unlock(&hdd_context_lock); - hdd_warn("Invalid context, pAdapter [%p] magic [%08x]", - pAdapter, pStatsContext->magic); - return; - } - - /* context is valid so caller is still waiting */ - - /* paranoia: invalidate the magic */ - pStatsContext->magic = 0; + (class_a_stats + 1); + priv = hdd_request_priv(request); /* copy over the stats. do so as a struct copy */ - pAdapter->hdd_stats.summary_stat = *pSummaryStats; - pAdapter->hdd_stats.ClassA_stat = *pClassAStats; - pAdapter->hdd_stats.per_chain_rssi_stats = *per_chain_rssi_stats; + priv->summary_stats = *summary_stats; + priv->class_a_stats = *class_a_stats; + priv->per_chain_rssi_stats = *per_chain_rssi_stats; - /* notify the caller */ - complete(&pStatsContext->completion); - - /* serialization is complete */ - spin_unlock(&hdd_context_lock); + hdd_request_complete(request); + hdd_request_put(request); } /** @@ -4402,18 +4389,26 @@ QDF_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter) { hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); QDF_STATUS hstatus; - unsigned long rc; - static struct statsContext context; + int ret; + void *cookie; + struct hdd_request *request; + struct station_stats *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; if (NULL == pAdapter) { hdd_err("pAdapter is NULL"); return QDF_STATUS_SUCCESS; } - /* we are connected so prepare our callback context */ - init_completion(&context.completion); - context.pAdapter = pAdapter; - context.magic = STATS_CONTEXT_MAGIC; + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + cookie = hdd_request_cookie(request); /* query only for Summary & Class A statistics */ hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter), @@ -4425,37 +4420,32 @@ QDF_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter) 0, /* not periodic */ false, /* non-cached results */ pHddStaCtx->conn_info.staId[0], - &context, pAdapter->sessionId); + cookie, pAdapter->sessionId); if (QDF_STATUS_SUCCESS != hstatus) { hdd_err("Unable to retrieve statistics"); /* we'll return with cached values */ } else { /* request was sent -- wait for the response */ - rc = wait_for_completion_timeout - (&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - - if (!rc) { - hdd_err("SME timed out while retrieving statistics"); + ret = hdd_request_wait_for_response(request); + if (ret) { + hdd_warn("SME timed out while retrieving statistics"); + /* we'll returned a cached value below */ + } else { + /* update the adapter with the fresh results */ + priv = hdd_request_priv(request); + pAdapter->hdd_stats.summary_stat = priv->summary_stats; + pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats; + pAdapter->hdd_stats.per_chain_rssi_stats = + priv->per_chain_rssi_stats; } } - /* either we never sent a request, we sent a request and - * received a response or we sent a request and timed out. if - * we never sent a request or if we sent a request and got a - * response, we want to clear the magic out of paranoia. if - * we timed out there is a race condition such that the - * callback function could be executing at the same time we - * are. of primary concern is if the callback function had - * already verified the "magic" but had not yet set the - * completion variable when a timeout occurred. we serialize - * these activities by invalidating the magic while holding a - * shared spinlock which will cause us to block if the - * callback is currently executing + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); + hdd_request_put(request); /* either callback updated pAdapter stats or it has cached data */ return QDF_STATUS_SUCCESS;