diff options
| author | Krishna Kumaar Natarajan <kknatara@qca.qualcomm.com> | 2014-06-09 12:38:41 -0700 |
|---|---|---|
| committer | Pitani Venkata Rajesh Kumar <c_vpitan@qti.qualcomm.com> | 2014-07-08 16:31:41 +0530 |
| commit | 6fd05e62b09cd99bc7bb0796516c716cbaa280cf (patch) | |
| tree | c6e629206f84c4a4b25fe26437c677ebac51bf90 | |
| parent | 3ab351192b1fe49a595f104865fb02613121c60a (diff) | |
wlan: qcacld: SME Changes for Link Layer Statistics
This change set introduces the SME API implementation
for Link Layer statistics.
Change-Id: Ib91fb50d7e8442f3a17bc76fea28ae396263db3c
CRs-Fixed: 668379
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 379 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 50 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 223 |
3 files changed, 651 insertions, 1 deletions
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index b67303051461..87b3947f26e6 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -5374,4 +5374,383 @@ typedef struct #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 mpduSizeThreshold; + tANI_U32 aggressiveStatisticsGathering; +} tSirLLStatsSetReq, *tpSirLLStatsSetReq; + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 paramIdMask; +} tSirLLStatsGetReq, *tpSirLLStatsGetReq; + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 statsClearReqMask; + tANI_U8 stopReq; +} tSirLLStatsClearReq, *tpSirLLStatsClearReq; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_NOTIFY_STATS +---------------------------------------------------------------------------*/ + + +/******************************LINK LAYER Statistics**********************/ + +typedef int tSirWifiRadio; +typedef int tSirWifiChannel; +typedef int tSirwifiTxRate; + +/* channel operating width */ +typedef enum +{ + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, +} tSirWifiChannelWidth; + +typedef enum +{ + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ + WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ +} tSirWifiConnectionState; + +typedef enum +{ + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +} tSirWifiRoamState; + +typedef enum +{ + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + } tSirWifiInterfaceMode; + +/* set for QOS association */ +#define WIFI_CAPABILITY_QOS 0x00000001 +/* set for protected association (802.11 beacon frame control protected bit set) */ +#define WIFI_CAPABILITY_PROTECTED 0x00000002 +/* set if 802.11 Extended Capabilities element interworking bit is set */ +#define WIFI_CAPABILITY_INTERWORKING 0x00000004 +/* set for HS20 association */ +#define WIFI_CAPABILITY_HS20 0x00000008 +/* set is 802.11 Extended Capabilities element UTF-8 SSID bit is set */ +#define WIFI_CAPABILITY_SSID_UTF8 0x00000010 +/* set is 802.11 Country Element is present */ +#define WIFI_CAPABILITY_COUNTRY 0x00000020 + +typedef struct +{ + /* tSirWifiInterfaceMode */ + /* interface mode */ + tANI_U8 mode; + /* interface mac address (self) */ + tSirMacAddr macAddr; + /* tSirWifiConnectionState */ + /* connection state (valid for STA, CLI only) */ + tANI_U8 state; + /* tSirWifiRoamState */ + /* roaming state */ + tANI_U32 roaming; + /* WIFI_CAPABILITY_XXX (self) */ + tANI_U32 capabilities; + /* null terminated SSID */ + tANI_U8 ssid[33]; + /* bssid */ + tSirMacAddr bssid; + /* country string advertised by AP */ + tANI_U8 apCountryStr[WNI_CFG_COUNTRY_CODE_LEN]; + /* country string for this association */ + tANI_U8 countryStr[WNI_CFG_COUNTRY_CODE_LEN]; +} tSirWifiInterfaceInfo, *tpSirWifiInterfaceInfo; + +/* channel information */ +typedef struct +{ + /* channel width (20, 40, 80, 80+80, 160) */ + tSirWifiChannelWidth width; + /* primary 20 MHz channel */ + tSirWifiChannel centerFreq; + /* center frequency (MHz) first segment */ + tSirWifiChannel centerFreq0; + /* center frequency (MHz) second segment */ + tSirWifiChannel centerFreq1; +} tSirWifiChannelInfo, *tpSirWifiChannelInfo; + +/* wifi rate info */ +typedef struct +{ + /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + tANI_U32 preamble :3; + /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + tANI_U32 nss :2; + /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ + tANI_U32 bw :3; + /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ + /* HT/VHT it would be mcs index */ + tANI_U32 rateMcsIdx :8; + /* reserved */ + tANI_U32 reserved :16; + /* units of 100 Kbps */ + tANI_U32 bitrate; +} tSirWifiRate, *tpSirWifiRate; + +/* channel statistics */ +typedef struct +{ + /* channel */ + tSirWifiChannelInfo channel; + /* msecs the radio is awake (32 bits number accruing over time) */ + tANI_U32 onTime; + /* msecs the CCA register is busy (32 bits number accruing over time) */ + tANI_U32 ccaBusyTime; +} tSirWifiChannelStats, *tpSirWifiChannelStats; + +/* radio statistics */ +typedef struct +{ + /* wifi radio (if multiple radio supported) */ + tSirWifiRadio radio; + /* msecs the radio is awake (32 bits number accruing over time) */ + tANI_U32 onTime; + /* msecs the radio is transmitting + * (32 bits number accruing over time) + */ + tANI_U32 txTime; + /* msecs the radio is in active receive + *(32 bits number accruing over time) + */ + tANI_U32 rxTime; + /* msecs the radio is awake due to all scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeScan; + /* msecs the radio is awake due to NAN + * (32 bits number accruing over time) + */ + tANI_U32 onTimeNbd; + /* msecs the radio is awake due to Gscan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeGscan; + /* msecs the radio is awake due to roam?scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeRoamScan; + /* msecs the radio is awake due to PNO scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimePnoScan; + /* msecs the radio is awake due to HS2.0 scans and GAS exchange + * (32 bits number accruing over time) + */ + tANI_U32 onTimeHs20; + /* number of channels */ + tANI_U32 numChannels; + /* channel statistics tSirWifiChannelStats */ + tSirWifiChannelStats channels[0]; +} tSirWifiRadioStat, *tpSirWifiRadioStat; + +/* per rate statistics */ +typedef struct +{ + /* rate information */ + tSirWifiRate rate; + /* number of successfully transmitted data pkts (ACK rcvd) */ + tANI_U32 txMpdu; + /* number of received data pkts */ + tANI_U32 rxMpdu; + /* number of data packet losses (no ACK) */ + tANI_U32 mpduLost; + /* total number of data pkt retries * */ + tANI_U32 retries; + /* number of short data pkt retries */ + tANI_U32 retriesShort; + /* number of long data pkt retries */ + tANI_U32 retriesLong; +} tSirWifiRateStat, *tpSirWifiRateStat; + +/* access categories */ +typedef enum +{ + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +} tSirWifiTrafficAc; + +/* wifi peer type */ +typedef enum +{ + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +} tSirWifiPeerType; + +/* per peer statistics */ +typedef struct +{ + /* peer type (AP, TDLS, GO etc.) */ + tSirWifiPeerType type; + /* mac address */ + tSirMacAddr peerMacAddress; + /* peer WIFI_CAPABILITY_XXX */ + tANI_U32 capabilities; + /* number of rates */ + tANI_U32 numRate; + /* per rate statistics, number of entries = num_rate */ + tSirWifiRateStat rateStats[0]; +} tSirWifiPeerInfo, *tpSirWifiPeerInfo; + +/* per access category statistics */ +typedef struct +{ + /* tSirWifiTrafficAc */ + /* access category (VI, VO, BE, BK) */ + tANI_U32 ac; + /* number of successfully transmitted unicast data pkts (ACK rcvd) */ + tANI_U32 txMpdu; + /* number of received unicast mpdus */ + tANI_U32 rxMpdu; + /* number of succesfully transmitted multicast data packets */ + /* STA case: implies ACK received from AP for the unicast */ + /* packet in which mcast pkt was sent */ + tANI_U32 txMcast; + /* number of received multicast data packets */ + tANI_U32 rxMcast; + /* number of received unicast a-mpdus */ + tANI_U32 rxAmpdu; + /* number of transmitted unicast a-mpdus */ + tANI_U32 txAmpdu; + /* number of data pkt losses (no ACK) */ + tANI_U32 mpduLost; + /* total number of data pkt retries */ + tANI_U32 retries; + /* number of short data pkt retries */ + tANI_U32 retriesShort; + /* number of long data pkt retries */ + tANI_U32 retriesLong; + /* data pkt min contention time (usecs) */ + tANI_U32 contentionTimeMin; + /* data pkt max contention time (usecs) */ + tANI_U32 contentionTimeMax; + /* data pkt avg contention time (usecs) */ + tANI_U32 contentionTimeAvg; + /* num of data pkts used for contention statistics */ + tANI_U32 contentionNumSamples; +} tSirWifiWmmAcStat, *tpSirWifiWmmAcStat; + +/* Interface statistics - corresponding to 2nd most + * LSB in wifi statistics bitmap for getting statistics + */ +typedef struct +{ + /* current state of the interface */ + tSirWifiInterfaceInfo info; + /* access point beacon received count from connected AP */ + tANI_U32 beaconRx; + /* access point mgmt frames received count from */ + /* connected AP (including Beacon) */ + tANI_U32 mgmtRx; + /* action frames received count */ + tANI_U32 mgmtActionRx; + /* action frames transmit count */ + tANI_U32 mgmtActionTx; + /* access Point Beacon and Management frames RSSI (averaged) */ + tANI_U32 rssiMgmt; + /* access Point Data Frames RSSI (averaged) from connected AP */ + tANI_U32 rssiData; + /* access Point ACK RSSI (averaged) from connected AP */ + tANI_U32 rssiAck; + /* per ac data packet statistics */ + tSirWifiWmmAcStat AccessclassStats[WIFI_AC_MAX]; +} tSirWifiIfaceStat, *tpSirWifiIfaceStat; + +/* Peer statistics - corresponding to 3rd most LSB in + * wifi statistics bitmap for getting statistics + */ +typedef struct +{ + /* number of peers */ + tANI_U32 numPeers; + /* per peer statistics */ + tSirWifiPeerInfo peerInfo[0]; +} tSirWifiPeerStat, *tpSirWifiPeerStat; + +/* wifi statistics bitmap for getting statistics */ +#define WMI_LINK_STATS_RADIO 0x00000001 +#define WMI_LINK_STATS_IFACE 0x00000002 +#define WMI_LINK_STATS_ALL_PEER 0x00000004 +#define WMI_LINK_STATS_PER_PEER 0x00000008 + +/* wifi statistics bitmap for clearing statistics */ +/* all radio statistics */ +#define WIFI_STATS_RADIO 0x00000001 +/* cca_busy_time (within radio statistics) */ +#define WIFI_STATS_RADIO_CCA 0x00000002 +/* all channel statistics (within radio statistics) */ +#define WIFI_STATS_RADIO_CHANNELS 0x00000004 +/* all scan statistics (within radio statistics) */ +#define WIFI_STATS_RADIO_SCAN 0x00000008 +/* all interface statistics */ +#define WIFI_STATS_IFACE 0x00000010 +/* all tx rate statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_TXRATE 0x00000020 +/* all ac statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_AC 0x00000040 +/* all contention (min, max, avg) statistics (within ac statistics) */ +#define WIFI_STATS_IFACE_CONTENTION 0x00000080 + +typedef struct +{ + tANI_U32 paramId; + tANI_U8 ifaceId; + tANI_U32 rspId; + tANI_U32 moreResultToFollow; + union + { + tANI_U32 num_peers; + tANI_U32 num_radio; + }; + + tANI_U32 peer_event_number ; + /* Variable length field - Do not add anything after this */ + tANI_U8 results[0]; +} tSirLLStatsResults, *tpSirLLStatsResults; + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/* find the size of given member within a structure */ +#ifndef member_size +#define member_size(type, member) (sizeof(((type *)0)->member)) +#endif + #endif /* __SIR_API_H */ diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 49ebc2885799..97b99363251d 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -3471,7 +3471,6 @@ sme_StopBatchScanInd #endif - /* * SME API to enable/disable idle mode powersave * This should be called only if powersave offload @@ -3783,4 +3782,53 @@ eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, eHalStatus sme_abortRoamScan(tHalHandle hHal); #endif //#if WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief SME API to clear Link Layer Statistics + \param hHal + \param pclearStatsReq: Link Layer clear stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq (tHalHandle hHal, + tSirLLStatsClearReq *pclearStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief SME API to set the Link Layer Statistics + \param hHal + \param psetStatsReq: Link Layer set stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq (tHalHandle hHal, + tSirLLStatsSetReq *psetStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief SME API to get the Link Layer Statistics + \param hHal + \param pgetStatsReq: Link Layer get stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq (tHalHandle hHal, + tSirLLStatsGetReq *pgetStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief SME API to trigger the stats are available after get request + \param hHal + \param callbackRoutine - HDD callback which needs to be invoked after + getting status notification from FW + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp) +); + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + #endif //#if !defined( __SME_API_H ) diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index f1dbb5a41cff..8ebc1e09ebbb 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -13166,3 +13166,226 @@ eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief SME API to clear Link Layer Statistics + \param hHal + \param pclearStatsReq: Link Layer clear stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq (tHalHandle hHal, + tSirLLStatsClearReq *pclearStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsClearReq *clear_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "staId = %u", pclearStatsReq->staId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "statsClearReqMask = 0x%X", + pclearStatsReq->statsClearReqMask); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "stopReq = %u", pclearStatsReq->stopReq); + + clear_stats_req = vos_mem_malloc(sizeof(*clear_stats_req)); + + if (!clear_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_CLEAR_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *clear_stats_req = *pclearStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = clear_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_CLEAR_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_CLEAR_REQ", + __func__); + vos_mem_free(clear_stats_req); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(clear_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief SME API to set the Link Layer Statistics + \param hHal + \param psetStatsReq: Link Layer set stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq (tHalHandle hHal, + tSirLLStatsSetReq *psetStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsSetReq *set_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: MPDU Size = %u", __func__, + psetStatsReq->mpduSizeThreshold); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + " Aggressive Stats Collections = %u", + psetStatsReq->aggressiveStatisticsGathering); + + set_stats_req = vos_mem_malloc(sizeof(*set_stats_req)); + + if (!set_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_SET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *set_stats_req = *psetStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = set_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_SET_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_SET_REQ", + __func__); + vos_mem_free(set_stats_req); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(set_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief SME API to get the Link Layer Statistics + \param hHal + \param pgetStatsReq: Link Layer get stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq (tHalHandle hHal, + tSirLLStatsGetReq *pgetStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsGetReq *get_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "reqId = %u", pgetStatsReq->reqId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "staId = %u", pgetStatsReq->staId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Stats Type = %u", pgetStatsReq->paramIdMask); + + get_stats_req = vos_mem_malloc(sizeof(*get_stats_req)); + + if (!get_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_GET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *get_stats_req = *pgetStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = get_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_GET_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_GET_REQ", + __func__); + + vos_mem_free(get_stats_req); + status = eHAL_STATUS_FAILURE; + + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(get_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief SME API to trigger the stats are available after get request + \param hHal + \param callbackRoutine - HDD callback which needs to be invoked after + getting status notification from FW + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + pMac->sme.pLinkLayerStatsIndCallback = callbackRoutine; + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + } + + return(status); +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ |
