qcacld-3.0: Use request manager for Class A stats

We are transitioning to the new request manager framework. Change
wlan_hdd_get_class_astats() and hdd_get_class_a_statistics_cb() to
this framework.

Change-Id: I6cfa2155187e3d9ac4099f1e4480835917fd9ca6
CRs-Fixed: 2005302
This commit is contained in:
Jeff Johnson
2017-01-23 07:11:02 -08:00
zatwierdzone przez qcabuildsw
rodzic ce0032c5e0
commit a6ace5b9ea

Wyświetl plik

@@ -94,6 +94,7 @@
#endif
#include "wlan_hdd_lro.h"
#include "cds_utils.h"
#include "wlan_hdd_request_manager.h"
#define HDD_FINISH_ULA_TIME_OUT 800
#define HDD_SET_MCBC_FILTERS_TO_FW 1
@@ -4219,60 +4220,43 @@ static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
return ret;
}
struct class_a_stats {
tCsrGlobalClassAStatsInfo class_a_stats;
};
/**
* hdd_get_class_a_statistics_cb() - Get Class A stats callback function
* @pStats: pointer to Class A stats
* @pContext: user context originally registered with SME
* @stats: pointer to Class A stats
* @context: user context originally registered with SME (always the
* cookie from the request context)
*
* Return: None
*/
static void hdd_get_class_a_statistics_cb(void *pStats, void *pContext)
static void hdd_get_class_a_statistics_cb(void *stats, void *context)
{
struct statsContext *pStatsContext;
tCsrGlobalClassAStatsInfo *pClassAStats;
hdd_adapter_t *pAdapter;
struct hdd_request *request;
struct class_a_stats *priv;
tCsrGlobalClassAStatsInfo *returned_stats;
if ((NULL == pStats) || (NULL == pContext)) {
hdd_err("Bad param, pStats [%p] pContext [%p]",
pStats, pContext);
ENTER();
if ((NULL == stats) || (NULL == context)) {
hdd_err("Bad param, stats [%p] context [%p]",
stats, context);
return;
}
pClassAStats = pStats;
pStatsContext = pContext;
pAdapter = pStatsContext->pAdapter;
/* 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);
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);
request = hdd_request_get(context);
if (!request) {
hdd_err("Obsolete request");
return;
}
/* context is valid so caller is still waiting */
/* paranoia: invalidate the magic */
pStatsContext->magic = 0;
/* copy over the stats. do so as a struct copy */
pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
/* notify the caller */
complete(&pStatsContext->completion);
/* serialization is complete */
spin_unlock(&hdd_context_lock);
returned_stats = stats;
priv = hdd_request_priv(request);
priv->class_a_stats = *returned_stats;
hdd_request_complete(request);
hdd_request_put(request);
EXIT();
}
/**
@@ -4285,8 +4269,14 @@ QDF_STATUS wlan_hdd_get_class_astats(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 class_a_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");
@@ -4298,10 +4288,13 @@ QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter)
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(&params);
if (!request) {
hdd_err("Request allocation failure");
return QDF_STATUS_E_NOMEM;
}
cookie = hdd_request_cookie(request);
/* query only for Class A statistics (which include link speed) */
hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
@@ -4309,38 +4302,31 @@ QDF_STATUS wlan_hdd_get_class_astats(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_warn("Unable to retrieve Class A statistics");
/* we'll returned a cached value below */
} 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_warn("SME timed out while retrieving Class A statistics");
}
goto return_cached_results;
}
/* 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
*/
spin_lock(&hdd_context_lock);
context.magic = 0;
spin_unlock(&hdd_context_lock);
/* request was sent -- wait for the response */
ret = hdd_request_wait_for_response(request);
if (ret) {
hdd_warn("SME timed out while retrieving Class A statistics");
goto return_cached_results;
}
/* update the adapter with the fresh results */
priv = hdd_request_priv(request);
pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats;
return_cached_results:
/*
* 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.
*/
hdd_request_put(request);
/* either callback updated pAdapter stats or it has cached data */
return QDF_STATUS_SUCCESS;
}