summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h1
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c224
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(&params);
+ 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 )