diff options
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 1 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_wext.c | 224 |
2 files changed, 106 insertions, 119 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 06e33898c2d1..da6c77981a8e 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -348,7 +348,6 @@ extern spinlock_t hdd_context_lock; #define STATS_CONTEXT_MAGIC 0x53544154 //STAT #define PEER_INFO_CONTEXT_MAGIC 0x52535349 /* PEER_INFO */ #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 f868152b1173..e5feff793009 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -1235,64 +1235,6 @@ hdd_IsAuthTypeRSN( tHalHandle halHandle, eCsrAuthType authType) return rsnType; } -static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext) -{ - struct statsContext *pStatsContext; - hdd_adapter_t *pAdapter; - - if (ioctl_debug) - { - pr_info("%s: snr [%d] STA [%d] pContext [%pK]\n", - __func__, (int)snr, (int)staId, pContext); - } - - if (NULL == pContext) - { - hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Bad param, pContext [%pK]", - __func__, pContext); - 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); - hddLog(VOS_TRACE_LEVEL_WARN, - "%s: Invalid context, pAdapter [%pK] magic [%08x]", - __func__, pAdapter, pStatsContext->magic); - if (ioctl_debug) - { - pr_info("%s: Invalid context, pAdapter [%pK] magic [%08x]\n", - __func__, 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); -} - struct rssi_priv { v_S7_t rssi; }; @@ -1426,74 +1368,120 @@ VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) return VOS_STATUS_SUCCESS; } +struct snr_priv { + tANI_S8 snr; +}; + +/** + * hdd_get_snr_cb() - "Get SNR" callback function + * @snr: Current SNR of the station + * @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(tANI_S8 snr, tANI_U32 sta_id, void *context) +{ + struct hdd_request *request; + struct snr_priv *priv; + + if (ioctl_debug) { + pr_info("%s: snr [%d] sta_id [%d] context [%pK]\n", + __func__, (int)snr, (int)sta_id, context); + } + + request = hdd_request_get(context); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Obsolete request", __func__); + return; + } + + /* propagate response back to requesting thread */ + priv = hdd_request_priv(request); + priv->snr = snr; + hdd_request_complete(request); + hdd_request_put(request); +} + +/** + * wlan_hdd_get_snr() - Get the current SNR + * @pAdapter: adapter upon which the measurement is requested + * @snr: pointer to where the SNR should be returned + * + * Return: VOS_STATUS_SUCCESS on success, VOS_STATUS_E_** on error + */ VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr) { - struct statsContext context; - hdd_context_t *pHddCtx; - hdd_station_ctx_t *pHddStaCtx; - eHalStatus hstatus; - unsigned long rc; - int valid; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + eHalStatus hstatus; + 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(); - if (NULL == pAdapter) - { - hddLog(VOS_TRACE_LEVEL_ERROR, - "%s: Invalid context, pAdapter", __func__); - return VOS_STATUS_E_FAULT; - } + ENTER(); - pHddCtx = WLAN_HDD_GET_CTX(pAdapter); - valid = wlan_hdd_validate_context(pHddCtx); - if (0 != valid) - return VOS_STATUS_E_FAULT; + if (NULL == pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } - pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); - init_completion(&context.completion); - context.pAdapter = pAdapter; - context.magic = SNR_CONTEXT_MAGIC; + valid = wlan_hdd_validate_context(pHddCtx); + if (0 != valid) + return VOS_STATUS_E_FAULT; - hstatus = sme_GetSnr(pHddCtx->hHal, hdd_GetSnrCB, - pHddStaCtx->conn_info.staId[ 0 ], - pHddStaCtx->conn_info.bssId, - &context); - if (eHAL_STATUS_SUCCESS != hstatus) - { - hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI", - __func__); - /* 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) { - hddLog(VOS_TRACE_LEVEL_ERROR, - FL("SME timed out while retrieving SNR")); - /* we'll now returned a cached value below */ - } - } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - /* 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); - - *snr = pAdapter->snr; - EXIT(); - return VOS_STATUS_SUCCESS; + request = hdd_request_alloc(¶ms); + if (!request) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Request allocation failure", __func__); + return VOS_STATUS_E_FAULT; + } + cookie = hdd_request_cookie(request); + + hstatus = sme_GetSnr(pHddCtx->hHal, hdd_get_snr_cb, + pHddStaCtx->conn_info.staId[0], + pHddStaCtx->conn_info.bssId, cookie); + if (eHAL_STATUS_SUCCESS != hstatus) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve SNR", __func__); + /* we'll returned a cached value below */ + } else { + /* request was sent -- wait for the response */ + ret = hdd_request_wait_for_response(request); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("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. + * regardless we are done with the request. + */ + hdd_request_put(request); + + *snr = pAdapter->snr; + EXIT(); + return VOS_STATUS_SUCCESS; } void hdd_StatisticsCB( void *pStats, void *pContext ) |
