diff options
| author | Dundi Raviteja <dundi@codeaurora.org> | 2018-04-25 18:13:36 +0530 |
|---|---|---|
| committer | nshrivas <nshrivas@codeaurora.org> | 2018-05-04 01:09:09 -0700 |
| commit | 18a5585cc2cdc6b0790c3e3a144d559f27e26b2a (patch) | |
| tree | 02f0f677a82f61fc5f36b01c8c72b8e0b9b1e270 | |
| parent | 4b06d228f5a7f8b6a4dddee567ed31023d1b92e3 (diff) | |
qcacld-3.0: Use request manager for linkspeed
We are transitioning to the new request manager framework.
Change wlan_hdd_get_linkspeed_for_peermac() and hdd_get_link_speed_cb() to
this framework. Note that this framework provides the infrastructure
to pass data from the response thread to the request thread and hence
eliminates the need to maintain tSirLinkSpeedInfo in the HDD adapter
struct.
Change-Id: I27cdbb986b23c4895f7e6e444697994f26bc6ea1
CRs-Fixed: 2005313
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 12 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_wext.h | 16 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_hostapd.c | 10 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_wext.c | 176 |
4 files changed, 86 insertions, 128 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index a0221d9c4667..aa3df6c23ffd 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -403,12 +403,6 @@ struct statsContext { unsigned int magic; }; -struct linkspeedContext { - struct completion completion; - hdd_adapter_t *pAdapter; - unsigned int magic; -}; - /** * struct hdd_apf_context - hdd Context for apf * @magic: magic number @@ -453,7 +447,6 @@ extern struct mutex hdd_init_deinit_lock; #define PEER_INFO_CONTEXT_MAGIC 0x50494E46 /* PEER_INFO(PINF) */ #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) */ #define APF_CONTEXT_MAGIC 0x4575354 /* APF */ @@ -1398,8 +1391,9 @@ struct hdd_adapter_s { struct net_device_stats stats; /** HDD statistics*/ hdd_stats_t hdd_stats; - /** linkspeed statistics */ - tSirLinkSpeedInfo ls_stats; + + /* estimated link speed */ + u32 estimated_linkspeed; /* SAP peer station info */ struct sir_peer_sta_info peer_sta_info; diff --git a/core/hdd/inc/wlan_hdd_wext.h b/core/hdd/inc/wlan_hdd_wext.h index 45c94f4601c4..84c147b589a0 100644 --- a/core/hdd/inc/wlan_hdd_wext.h +++ b/core/hdd/inc/wlan_hdd_wext.h @@ -362,8 +362,20 @@ extern int hdd_priv_get_data(struct iw_point *p_priv_data, extern void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len); -int wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, - struct qdf_mac_addr mac_address); +/** + * wlan_hdd_get_linkspeed_for_peermac() - Get link speed for a peer + * @adapter: adapter upon which the peer is active + * @mac_address: MAC address of the peer + * @linkspeed: pointer to memory where returned link speed is to be placed + * + * This function will send a query to SME for the linkspeed of the + * given peer, and then wait for the callback to be invoked. + * + * Return: 0 if linkspeed data is available, negative errno otherwise + */ +int wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *adapter, + struct qdf_mac_addr *mac_address, + uint32_t *linkspeed); void hdd_clear_roam_profile_ie(hdd_adapter_t *pAdapter); uint8_t *wlan_hdd_get_vendor_oui_ie_ptr(uint8_t *oui, uint8_t oui_size, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index a4d4711bd684..647bbeef92bc 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5653,15 +5653,13 @@ int __iw_get_softap_linkspeed(struct net_device *dev, hdd_err("Invalid peer macaddress"); return -EINVAL; } - errno = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter, - macAddress); - if (errno) { + rc = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter, &macAddress, + &link_speed); + if (rc) { hdd_err("Unable to retrieve SME linkspeed: %d", errno); - return errno; + return rc; } - link_speed = pHostapdAdapter->ls_stats.estLinkSpeed; - /* linkspeed in units of 500 kbps */ link_speed = link_speed / 500; wrqu->data.length = len; diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index d1014488271d..8f9293ab184d 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -43,6 +43,7 @@ #include <wlan_hdd_wmm.h> #include "utils_api.h" #include "wlan_hdd_p2p.h" +#include "wlan_hdd_request_manager.h" #ifdef FEATURE_WLAN_TDLS #include "wlan_hdd_tdls.h" #endif @@ -3632,139 +3633,92 @@ QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr) return QDF_STATUS_SUCCESS; } -/** - * hdd_get_link_speed_cb() - Get link speed callback function - * @pLinkSpeed: pointer to the link speed record - * @pContext: pointer to the user context passed to SME - * - * This function is passed as the callback function to - * sme_get_link_speed() by wlan_hdd_get_linkspeed_for_peermac(). By - * agreement a &struct linkspeedContext is passed as @pContext. If - * the context is valid, then the contents of @pLinkSpeed are copied - * into the adapter record referenced by @pContext where they can be - * subsequently retrieved. If the context is invalid, then this - * function does nothing since it is assumed the caller has already - * timed-out and destroyed the context. - * - * Return: None. - */ +struct linkspeed_priv { + tSirLinkSpeedInfo linkspeed_info; +}; + static void -hdd_get_link_speed_cb(tSirLinkSpeedInfo *pLinkSpeed, void *pContext) +hdd_get_link_speed_cb(tSirLinkSpeedInfo *linkspeed_info, void *context) { - struct linkspeedContext *pLinkSpeedContext; - hdd_adapter_t *pAdapter; + struct hdd_request *request; + struct linkspeed_priv *priv; - if ((NULL == pLinkSpeed) || (NULL == pContext)) { - hdd_err("Bad param, pLinkSpeed [%pK] pContext [%pK]", - pLinkSpeed, pContext); + if (!linkspeed_info) { + hdd_err("NULL linkspeed"); return; } - spin_lock(&hdd_context_lock); - pLinkSpeedContext = pContext; - pAdapter = pLinkSpeedContext->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 - */ - if ((NULL == pAdapter) || - (LINK_CONTEXT_MAGIC != pLinkSpeedContext->magic)) { - /* the caller presumably timed out so there is nothing - * we can do - */ - spin_unlock(&hdd_context_lock); - hdd_warn("Invalid context, pAdapter [%pK] magic [%08x]", - pAdapter, pLinkSpeedContext->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 */ - pLinkSpeedContext->magic = 0; - - /* copy over the stats. do so as a struct copy */ - pAdapter->ls_stats = *pLinkSpeed; - - /* notify the caller */ - complete(&pLinkSpeedContext->completion); - - /* serialization is complete */ - spin_unlock(&hdd_context_lock); + priv = hdd_request_priv(request); + priv->linkspeed_info = *linkspeed_info; + hdd_request_complete(request); + hdd_request_put(request); } -/** - * wlan_hdd_get_linkspeed_for_peermac() - Get link speed for a peer - * @pAdapter: adapter upon which the peer is active - * @macAddress: MAC address of the peer - * - * This function will send a query to SME for the linkspeed of the - * given peer, and then wait for the callback to be invoked. - * - * Return: Errno - */ -int wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, - struct qdf_mac_addr macAddress) +int wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *adapter, + struct qdf_mac_addr *mac_address, + uint32_t *linkspeed) { + int ret; QDF_STATUS status; - int errno; - unsigned long rc; - static struct linkspeedContext context; - tSirLinkSpeedInfo *linkspeed_req; + void *cookie; + tSirLinkSpeedInfo *linkspeed_info; + struct hdd_request *request; + struct linkspeed_priv *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"); + if ((!adapter) || (!linkspeed)) { + hdd_err("NULL argument"); return -EINVAL; } - linkspeed_req = qdf_mem_malloc(sizeof(*linkspeed_req)); - if (NULL == linkspeed_req) { - hdd_err("Request Buffer Alloc Fail"); - return -ENOMEM; + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + ret = -ENOMEM; + goto return_cached_value; } - init_completion(&context.completion); - context.pAdapter = pAdapter; - context.magic = LINK_CONTEXT_MAGIC; - - qdf_copy_macaddr(&linkspeed_req->peer_macaddr, &macAddress); - status = sme_get_link_speed(WLAN_HDD_GET_HAL_CTX(pAdapter), - linkspeed_req, - &context, hdd_get_link_speed_cb); - qdf_mem_free(linkspeed_req); - errno = qdf_status_to_os_return(status); - if (errno) { + cookie = hdd_request_cookie(request); + priv = hdd_request_priv(request); + + linkspeed_info = &priv->linkspeed_info; + qdf_copy_macaddr(&linkspeed_info->peer_macaddr, mac_address); + status = sme_get_link_speed(WLAN_HDD_GET_HAL_CTX(adapter), + linkspeed_info, + cookie, hdd_get_link_speed_cb); + if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Unable to retrieve statistics for link speed"); - } else { - rc = wait_for_completion_timeout - (&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - if (!rc) { - hdd_err("SME timed out while retrieving link speed"); - errno = -ETIMEDOUT; - } + ret = qdf_status_to_os_return(status); + goto cleanup; } + ret = hdd_request_wait_for_response(request); + if (ret) { + hdd_err("SME timed out while retrieving link speed"); + goto cleanup; + } + adapter->estimated_linkspeed = linkspeed_info->estLinkSpeed; - /* 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 +cleanup: + /* + * 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); - return errno; +return_cached_value: + *linkspeed = adapter->estimated_linkspeed; + + return ret; } /** @@ -3805,12 +3759,12 @@ int wlan_hdd_get_link_speed(hdd_adapter_t *sta_adapter, uint32_t *link_speed) qdf_copy_macaddr(&bssid, &hdd_stactx->conn_info.bssId); - errno = wlan_hdd_get_linkspeed_for_peermac(sta_adapter, bssid); + errno = wlan_hdd_get_linkspeed_for_peermac(sta_adapter, &bssid, + link_speed); if (errno) { hdd_err("Unable to retrieve SME linkspeed: %d", errno); return errno; } - *link_speed = sta_adapter->ls_stats.estLinkSpeed; /* linkspeed in units of 500 kbps */ *link_speed = (*link_speed) / 500; } |
