summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrishna Kumaar Natarajan <kknatara@qca.qualcomm.com>2014-06-09 12:38:41 -0700
committerPitani Venkata Rajesh Kumar <c_vpitan@qti.qualcomm.com>2014-07-08 16:31:41 +0530
commit6fd05e62b09cd99bc7bb0796516c716cbaa280cf (patch)
treec6e629206f84c4a4b25fe26437c677ebac51bf90
parent3ab351192b1fe49a595f104865fb02613121c60a (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.h379
-rw-r--r--CORE/SME/inc/sme_Api.h50
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c223
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 */