diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index c8b12d9439..fbc92fed8a 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -325,7 +325,6 @@ extern spinlock_t hdd_context_lock; #define STATS_CONTEXT_MAGIC 0x53544154 /* STAT */ #define POWER_CONTEXT_MAGIC 0x504F5752 /* POWR */ -#define SNR_CONTEXT_MAGIC 0x534E5200 /* SNR */ #define LINK_CONTEXT_MAGIC 0x4C494E4B /* LINKSPEED */ #define LINK_STATUS_MAGIC 0x4C4B5354 /* LINKSTATUS(LNST) */ #define TEMP_CONTEXT_MAGIC 0x74656d70 /* TEMP (temperature) */ diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 5303b7aa47..e551d86cc6 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -1768,58 +1768,35 @@ QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value) return QDF_STATUS_SUCCESS; } +struct snr_priv { + int8_t snr; +}; + /** * hdd_get_snr_cb() - "Get SNR" callback function * @snr: Current SNR of the station - * @staId: ID of the station - * @pContext: opaque context originally passed to SME. HDD always passes - * a &struct statsContext + * @sta_id: ID of the station + * @context: opaque context originally passed to SME. HDD always passes + * a cookie for the request context * * Return: None */ -static void hdd_get_snr_cb(int8_t snr, uint32_t staId, void *pContext) +static void hdd_get_snr_cb(int8_t snr, uint32_t sta_id, void *context) { - struct statsContext *pStatsContext; - hdd_adapter_t *pAdapter; + struct hdd_request *request; + struct snr_priv *priv; - if (NULL == pContext) { - hdd_err("Bad param"); + request = hdd_request_get(context); + if (!request) { + hdd_err("Obsolete request"); return; } - 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) || (SNR_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; - - /* copy over the snr */ - pAdapter->snr = snr; - - /* notify the caller */ - complete(&pStatsContext->completion); - - /* serialization is complete */ - spin_unlock(&hdd_context_lock); + /* propagate response back to requesting thread */ + priv = hdd_request_priv(request); + priv->snr = snr; + hdd_request_complete(request); + hdd_request_put(request); } /** @@ -1831,12 +1808,18 @@ static void hdd_get_snr_cb(int8_t snr, uint32_t staId, void *pContext) */ QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr) { - static struct statsContext context; hdd_context_t *pHddCtx; hdd_station_ctx_t *pHddStaCtx; QDF_STATUS hstatus; - unsigned long rc; int valid; + int ret; + void *cookie; + struct hdd_request *request; + struct snr_priv *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; ENTER(); @@ -1853,43 +1836,38 @@ QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr) pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - init_completion(&context.completion); - context.pAdapter = pAdapter; - context.magic = SNR_CONTEXT_MAGIC; + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_FAULT; + } + cookie = hdd_request_cookie(request); hstatus = sme_get_snr(pHddCtx->hHal, hdd_get_snr_cb, pHddStaCtx->conn_info.staId[0], - pHddStaCtx->conn_info.bssId, &context); + pHddStaCtx->conn_info.bssId, cookie); if (QDF_STATUS_SUCCESS != hstatus) { hdd_err("Unable to retrieve RSSI"); /* 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) { + ret = hdd_request_wait_for_response(request); + if (ret) { hdd_err("SME timed out while retrieving SNR"); /* we'll now returned a cached value below */ + } else { + /* update the adapter with the fresh results */ + priv = hdd_request_priv(request); + pAdapter->snr = priv->snr; } } - /* 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); *snr = pAdapter->snr; EXIT();