diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 992690933e66..1df97ca69083 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -8788,8 +8788,6 @@ static int hdd_context_init(struct hdd_context *hdd_ctx) hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX; - hdd_init_ll_stats_ctx(); - init_completion(&hdd_ctx->mc_sus_event_var); init_completion(&hdd_ctx->ready_to_suspend); diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index f5812b7cf118..4076144217b4 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -161,7 +161,25 @@ static int rssi_mcs_tbl[][10] = { #ifdef WLAN_FEATURE_LINK_LAYER_STATS -static struct hdd_ll_stats_context ll_stats_context; + +/** + * struct hdd_ll_stats_priv - hdd link layer stats private + * @request_id: userspace-assigned link layer stats request id + * @request_bitmap: userspace-assigned link layer stats request bitmap + */ +struct hdd_ll_stats_priv { + uint32_t request_id; + uint32_t request_bitmap; +}; + +/* + * Used to allocate the size of 4096 for the link layer stats. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements on link layer + * statistics. + */ +#define LL_STATS_EVENT_BUF_SIZE 4096 /** * put_wifi_rate_stat() - put wifi rate stats @@ -1063,12 +1081,14 @@ static void hdd_ll_process_peer_stats(struct hdd_adapter *adapter, void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, int indication_type, - tSirLLStatsResults *results) + tSirLLStatsResults *results, + void *cookie) { struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); - struct hdd_ll_stats_context *context; + struct hdd_ll_stats_priv *priv; struct hdd_adapter *adapter = NULL; int status; + struct osif_request *request; status = wlan_hdd_validate_context(hdd_ctx); if (status) @@ -1077,7 +1097,7 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, adapter = hdd_get_adapter_by_vdev(hdd_ctx, results->ifaceId); - if (NULL == adapter) { + if (!adapter) { hdd_err("vdev_id %d does not exist with host", results->ifaceId); return; @@ -1096,18 +1116,23 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, results->num_radio, results->results); - context = &ll_stats_context; - spin_lock(&context->context_lock); - /* validate response received from target */ - if ((context->request_id != results->rspId) || - !(context->request_bitmap & results->paramId)) { - spin_unlock(&context->context_lock); - hdd_err("Error : Request id %d response id %d request bitmap 0x%x response bitmap 0x%x", - context->request_id, results->rspId, - context->request_bitmap, results->paramId); + request = osif_request_get(cookie); + if (!request) { + hdd_err("Obsolete request"); + return; + } + + priv = osif_request_priv(request); + + /* validate response received from target */ + if ((priv->request_id != results->rspId) || + !(priv->request_bitmap & results->paramId)) { + hdd_err("Request id %d response id %d request bitmap 0x%x response bitmap 0x%x", + priv->request_id, results->rspId, + priv->request_bitmap, results->paramId); + osif_request_put(request); return; } - spin_unlock(&context->context_lock); if (results->paramId & WMI_LINK_STATS_RADIO) { hdd_ll_process_radio_stats(adapter, @@ -1116,10 +1141,8 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, results->num_radio, results->rspId); - spin_lock(&context->context_lock); if (!results->moreResultToFollow) - context->request_bitmap &= ~(WMI_LINK_STATS_RADIO); - spin_unlock(&context->context_lock); + priv->request_bitmap &= ~(WMI_LINK_STATS_RADIO); } else if (results->paramId & WMI_LINK_STATS_IFACE) { @@ -1128,17 +1151,15 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, results->num_peers, results->rspId); - spin_lock(&context->context_lock); /* Firmware doesn't send peerstats event if no peers are * connected. HDD should not wait for any peerstats in * this case and return the status to middleware after * receiving iface stats */ if (!results->num_peers) - context->request_bitmap &= + priv->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER); - context->request_bitmap &= ~(WMI_LINK_STATS_IFACE); - spin_unlock(&context->context_lock); + priv->request_bitmap &= ~(WMI_LINK_STATS_IFACE); } else if (results-> paramId & WMI_LINK_STATS_ALL_PEER) { @@ -1147,21 +1168,19 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, results->results, results->rspId); - spin_lock(&context->context_lock); if (!results->moreResultToFollow) - context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER); - spin_unlock(&context->context_lock); + priv->request_bitmap &= + ~(WMI_LINK_STATS_ALL_PEER); } else { hdd_err("INVALID LL_STATS_NOTIFY RESPONSE"); } - spin_lock(&context->context_lock); /* complete response event if all requests are completed */ - if (0 == context->request_bitmap) - complete(&context->response_event); - spin_unlock(&context->context_lock); + if (!priv->request_bitmap) + osif_request_complete(request); + osif_request_put(request); break; } default: @@ -1341,31 +1360,50 @@ nla_policy static int wlan_hdd_send_ll_stats_req(struct hdd_context *hdd_ctx, tSirLLStatsGetReq *req) { - unsigned long rc; - struct hdd_ll_stats_context *context; + int ret; + struct hdd_ll_stats_priv *priv; + struct osif_request *request; + void *cookie; + static const struct osif_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_LL_STATS, + }; - context = &ll_stats_context; - spin_lock(&context->context_lock); - context->request_id = req->reqId; - context->request_bitmap = req->paramIdMask; - INIT_COMPLETION(context->response_event); - spin_unlock(&context->context_lock); + hdd_enter(); + + request = osif_request_alloc(¶ms); + if (!request) { + hdd_err("Request Allocation Failure"); + return -ENOMEM; + } + + cookie = osif_request_cookie(request); + + priv = osif_request_priv(request); + + priv->request_id = req->reqId; + priv->request_bitmap = req->paramIdMask; if (QDF_STATUS_SUCCESS != - sme_ll_stats_get_req(hdd_ctx->mac_handle, req)) { + sme_ll_stats_get_req(hdd_ctx->mac_handle, req, + cookie)) { hdd_err("sme_ll_stats_get_req Failed"); - return -EINVAL; + ret = -EINVAL; + goto exit; } - rc = wait_for_completion_timeout(&context->response_event, - msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS)); - if (!rc) { + ret = osif_request_wait_for_response(request); + if (ret) { hdd_err("Target response timed out request id %d request bitmap 0x%x", - context->request_id, context->request_bitmap); - return -ETIMEDOUT; + priv->request_id, priv->request_bitmap); + ret = -ETIMEDOUT; + goto exit; } + hdd_exit(); - return 0; +exit: + osif_request_put(request); + return ret; } int wlan_hdd_ll_stats_get(struct hdd_adapter *adapter, uint32_t req_id, @@ -2824,18 +2862,6 @@ int wlan_hdd_cfg80211_ll_stats_ext_set_param(struct wiphy *wiphy, return ret; } - -/** - * hdd_init_ll_stats_ctx() - initialize link layer stats context - * - * Return: none - */ -inline void hdd_init_ll_stats_ctx(void) -{ - spin_lock_init(&ll_stats_context.context_lock); - init_completion(&ll_stats_context.response_event); - ll_stats_context.request_bitmap = 0; -} #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ #ifdef WLAN_FEATURE_STATS_EXT diff --git a/core/hdd/src/wlan_hdd_stats.h b/core/hdd/src/wlan_hdd_stats.h index 2841ad73da89..d59fc7f6ab47 100644 --- a/core/hdd/src/wlan_hdd_stats.h +++ b/core/hdd/src/wlan_hdd_stats.h @@ -79,29 +79,6 @@ struct index_data_rate_type { #ifdef WLAN_FEATURE_LINK_LAYER_STATS -/** - * struct hdd_ll_stats_context - hdd link layer stats context - * - * @request_id: userspace-assigned link layer stats request id - * @request_bitmap: userspace-assigned link layer stats request bitmap - * @response_event: LL stats request wait event - */ -struct hdd_ll_stats_context { - uint32_t request_id; - uint32_t request_bitmap; - struct completion response_event; - spinlock_t context_lock; -}; - -/* - * Used to allocate the size of 4096 for the link layer stats. - * The size of 4096 is considered assuming that all data per - * respective event fit with in the limit.Please take a call - * on the limit based on the data requirements on link layer - * statistics. - */ -#define LL_STATS_EVENT_BUF_SIZE 4096 - /** * wlan_hdd_cfg80211_ll_stats_set() - set link layer stats * @wiphy: Pointer to wiphy @@ -147,8 +124,6 @@ int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy, void wlan_hdd_clear_link_layer_stats(struct hdd_adapter *adapter); -void hdd_init_ll_stats_ctx(void); - static inline bool hdd_link_layer_stats_supported(void) { return true; @@ -193,6 +168,7 @@ int wlan_hdd_ll_stats_get(struct hdd_adapter *adapter, uint32_t req_id, * @hdd_handle: Handle to HDD context * @indication_type: Indication type * @results: Pointer to results + * @cookie: Callback context * * After receiving Link Layer indications from FW.This callback converts the * firmware data to the NL data and send the same to the kernel/upper layers. @@ -201,7 +177,8 @@ int wlan_hdd_ll_stats_get(struct hdd_adapter *adapter, uint32_t req_id, */ void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, int indication_type, - tSirLLStatsResults *results); + tSirLLStatsResults *results, + void *cookie); /** * wlan_hdd_cfg80211_link_layer_stats_ext_callback() - Callback for LL ext @@ -230,10 +207,6 @@ void hdd_lost_link_info_cb(hdd_handle_t hdd_handle, #else /* WLAN_FEATURE_LINK_LAYER_STATS */ -static inline void hdd_init_ll_stats_ctx(void) -{ -} - static inline bool hdd_link_layer_stats_supported(void) { return false; @@ -263,7 +236,8 @@ wlan_hdd_clear_link_layer_stats(struct hdd_adapter *adapter) static inline void wlan_hdd_cfg80211_link_layer_stats_callback(hdd_handle_t hdd_handle, int indication_type, - tSirLLStatsResults *results) + tSirLLStatsResults *results, + void *cookie) { } diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 6754651d5c24..308a983968b9 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1022,14 +1022,24 @@ QDF_STATUS sme_ll_stats_clear_req(tHalHandle hHal, tSirLLStatsClearReq * pclearStatsReq); QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq *psetStatsReq); -QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, - tSirLLStatsGetReq *pgetStatsReq); + +/** + * sme_ll_stats_get_req() - SME API to get the Link Layer Statistics + * @mac_handle: Global MAC handle + * @get_stats_req: Link Layer get stats request params structure + * @context: Callback context + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle, + tSirLLStatsGetReq *get_stats_req, + void *context); /** * sme_set_link_layer_stats_ind_cb() - * SME API to trigger the stats are available after get request * @mac_handle: MAC handle - * @callback_routine - HDD callback which needs to be invoked after + * @callback: HDD callback which needs to be invoked after * getting status notification from FW * * Return: QDF_STATUS diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 6c8f946832d1..a67f0e98e029 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -143,7 +143,8 @@ typedef struct sSelfRecoveryStats { typedef void (*link_layer_stats_cb)(hdd_handle_t hdd_handle, int indication_type, - tSirLLStatsResults *results); + tSirLLStatsResults *results, + void *cookie); typedef void (*ext_scan_ind_cb)(hdd_handle_t hdd_handle, const uint16_t, void *); @@ -271,6 +272,7 @@ typedef struct tagSmeStruct { #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR host_event_wlan_status_payload_type eventPayload; #endif + void *ll_stats_context; link_layer_stats_cb link_layer_stats_cb; void (*link_layer_stats_ext_cb)(hdd_handle_t callback_ctx, tSirLLStatsResults *rsp); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 594a225aeaf9..70ed1e8f9675 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -11717,57 +11717,40 @@ QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq return status; } -/* - * sme_ll_stats_get_req() - - * SME API to get the Link Layer Statistics - * - * hHal - * pgetStatsReq: Link Layer get stats request params structure - * Return QDF_STATUS - */ -QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, tSirLLStatsGetReq - *pgetStatsReq) +QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle, + tSirLLStatsGetReq *get_stats_req, + void *context) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + QDF_STATUS status = QDF_STATUS_E_FAILURE; + tpAniSirGlobal mac = MAC_CONTEXT(mac_handle); struct scheduler_msg message = {0}; - tSirLLStatsGetReq *get_stats_req; + tSirLLStatsGetReq *ll_stats_get_req; - get_stats_req = qdf_mem_malloc(sizeof(*get_stats_req)); + ll_stats_get_req = qdf_mem_malloc(sizeof(*ll_stats_get_req)); - if (!get_stats_req) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: Not able to allocate memory for WMA_LL_STATS_GET_REQ", - __func__); + if (!ll_stats_get_req) { + sme_err("Unable to allocate memory for WMA_LL_STATS_GET_REQ"); return QDF_STATUS_E_NOMEM; } - *get_stats_req = *pgetStatsReq; + *ll_stats_get_req = *get_stats_req; - if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { + mac->sme.ll_stats_context = context; + if (sme_acquire_global_lock(&mac->sme) == QDF_STATUS_SUCCESS) { /* Serialize the req through MC thread */ - message.bodyptr = get_stats_req; + message.bodyptr = ll_stats_get_req; message.type = WMA_LINK_LAYER_STATS_GET_REQ; - MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, - NO_SESSION, message.type)); - qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, - &message); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: not able to post WMA_LL_STATS_GET_REQ", - __func__); - - qdf_mem_free(get_stats_req); - status = QDF_STATUS_E_FAILURE; - + qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, + NO_SESSION, message.type); + status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_err("Not able to post WMA_LL_STATS_GET_REQ"); + qdf_mem_free(ll_stats_get_req); } - sme_release_global_lock(&pMac->sme); + sme_release_global_lock(&mac->sme); } else { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: sme_acquire_global_lock error", __func__); - qdf_mem_free(get_stats_req); - status = QDF_STATUS_E_FAILURE; + sme_err("sme_acquire_global_lock error"); + qdf_mem_free(ll_stats_get_req); } return status; diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 65bb5348cb8d..69cadb7b4c38 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1246,14 +1246,14 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, bool excess_data = false; uint32_t buf_len = 0; - tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE); + tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE); - if (!pMac) { - WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + if (!mac) { + WMA_LOGD("%s: NULL mac ptr. Exiting", __func__); return -EINVAL; } - if (!pMac->sme.link_layer_stats_cb) { + if (!mac->sme.link_layer_stats_cb) { WMA_LOGD("%s: HDD callback is null", __func__); return -EINVAL; } @@ -1375,9 +1375,10 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, * vdev_id/ifacId in link_stats_results will be * used to retrieve the correct HDD context */ - pMac->sme.link_layer_stats_cb(pMac->hdd_handle, - WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + mac->sme.link_layer_stats_cb(mac->hdd_handle, + WMA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results, + mac->sme.ll_stats_context); qdf_mem_free(link_stats_results); return 0; @@ -1573,7 +1574,8 @@ post_stats: */ mac->sme.link_layer_stats_cb(mac->hdd_handle, WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + link_stats_results, + mac->sme.ll_stats_context); wma_unified_radio_tx_mem_free(handle); return 0; @@ -1604,14 +1606,14 @@ static int wma_unified_link_radio_stats_event_handler(void *handle, tSirWifiRadioStat *rs_results; tSirWifiChannelStats *chn_results; - tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE); + tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE); - if (!pMac) { - WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + if (!mac) { + WMA_LOGD("%s: NULL mac ptr. Exiting", __func__); return -EINVAL; } - if (!pMac->sme.link_layer_stats_cb) { + if (!mac->sme.link_layer_stats_cb) { WMA_LOGD("%s: HDD callback is null", __func__); return -EINVAL; } @@ -1779,9 +1781,10 @@ static int wma_unified_link_radio_stats_event_handler(void *handle, return 0; } - pMac->sme.link_layer_stats_cb(pMac->hdd_handle, - WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + mac->sme.link_layer_stats_cb(mac->hdd_handle, + WMA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results, + mac->sme.ll_stats_context); wma_unified_radio_tx_mem_free(handle); return 0; @@ -2065,14 +2068,14 @@ int wma_unified_link_iface_stats_event_handler(void *handle, size_t link_stats_results_size, offload_stats_size; size_t total_ac_size, total_offload_size; - tpAniSirGlobal pMac = cds_get_context(QDF_MODULE_ID_PE); + tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE); - if (!pMac) { - WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + if (!mac) { + WMA_LOGD("%s: NULL mac ptr. Exiting", __func__); return -EINVAL; } - if (!pMac->sme.link_layer_stats_cb) { + if (!mac->sme.link_layer_stats_cb) { WMA_LOGD("%s: HDD callback is null", __func__); return -EINVAL; } @@ -2181,9 +2184,10 @@ int wma_unified_link_iface_stats_event_handler(void *handle, * vdev_id/ifacId in link_stats_results will be * used to retrieve the correct HDD context */ - pMac->sme.link_layer_stats_cb(pMac->hdd_handle, - WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + mac->sme.link_layer_stats_cb(mac->hdd_handle, + WMA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results, + mac->sme.ll_stats_context); qdf_mem_free(link_stats_results); return 0;