wlan: Link Layer Stats, implementation of interface Tx/Rx statistics
LLstats Implementation for Tx/Rx statistics
Change-Id: Id31c228b7e524b05a5509584b5e047c59c02303c
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 1b9b5ad..8295885 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -325,6 +325,9 @@
__u32 rxRefused;
__u32 pkt_tx_count; //TX pkt Counter used for dynamic splitscan
__u32 pkt_rx_count; //RX pkt Counter used for dynamic splitscan
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ __u32 txMcast[WIFI_AC_MAX];
+#endif
// tx timeout stats
__u32 txTimeoutCount;
__u32 continuousTxTimeoutCount;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 0ddc72f..ac89e87 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -823,11 +823,15 @@
return TRUE;
}
-static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
+static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
+ tpSirWifiIfaceStat pWifiIfaceStat,
struct sk_buff *vendor_event)
{
int i = 0;
struct nlattr *wmmInfo;
+ hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+ WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
+
if (FALSE == put_wifi_interface_info(
&pWifiIfaceStat->info,
vendor_event))
@@ -837,6 +841,80 @@
return FALSE;
}
+ pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
+ vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
+ if (NULL == pWifiIfaceStatTL)
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
+ return FALSE;
+ }
+
+
+ if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
+ {
+ if (VOS_STATUS_SUCCESS ==
+ WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
+ pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
+ {
+ /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
+ * obtained from TL structure
+ */
+
+ pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
+ pWifiIfaceStatTL->mgmtRx;
+ pWifiIfaceStat->mgmtActionRx = pWifiIfaceStatTL->mgmtActionRx;
+ pWifiIfaceStat->mgmtActionTx = pWifiIfaceStatTL->mgmtActionTx;
+ pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
+
+ vos_mem_copy(
+ (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VO],
+ (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO],
+ sizeof(WLANTL_AccessCategoryStatsType));
+
+ vos_mem_copy(
+ (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_VI],
+ (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI],
+ sizeof(WLANTL_AccessCategoryStatsType));
+
+ vos_mem_copy(
+ (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BE],
+ (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE],
+ sizeof(WLANTL_AccessCategoryStatsType));
+
+ vos_mem_copy(
+ (void *) &pWifiIfaceStat->AccessclassStats[WIFI_AC_BK],
+ (void *) &pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK],
+ sizeof(WLANTL_AccessCategoryStatsType));
+ }
+ else
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
+ }
+
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMpdu =
+ pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VO];
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMpdu =
+ pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_VI];
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMpdu =
+ pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BE];
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMpdu =
+ pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[WLANTL_AC_BK];
+
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
+ pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
+ pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
+ pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
+ pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
+ pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
+ }
+ else
+ {
+ hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
+ }
+
+
if (nla_put_u32(vendor_event,
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
@@ -850,18 +928,19 @@
nla_put_u32(vendor_event,
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
pWifiIfaceStat->mgmtActionTx) ||
- nla_put_u32(vendor_event,
+ nla_put_s32(vendor_event,
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
pWifiIfaceStat->rssiMgmt) ||
- nla_put_u32(vendor_event,
+ nla_put_s32(vendor_event,
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
pWifiIfaceStat->rssiData) ||
- nla_put_u32(vendor_event,
+ nla_put_s32(vendor_event,
QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
pWifiIfaceStat->rssiAck))
{
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("QCA_WLAN_VENDOR_ATTR put fail"));
+ vos_mem_free(pWifiIfaceStatTL);
return FALSE;
}
@@ -877,12 +956,14 @@
{
hddLog(VOS_TRACE_LEVEL_ERROR,
FL("QCA_WLAN_VENDOR_ATTR put Fail"));
+ vos_mem_free(pWifiIfaceStatTL);
return FALSE;
}
nla_nest_end(vendor_event, wmmStats);
}
nla_nest_end(vendor_event, wmmInfo);
+ vos_mem_free(pWifiIfaceStatTL);
return TRUE;
}
@@ -1153,6 +1234,25 @@
pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
+
+ if (FALSE == hdd_get_interface_info( pAdapter,
+ &pWifiIfaceStat->info))
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("hdd_get_interface_info get fail") );
+ kfree_skb(vendor_event);
+ return;
+ }
+
+ if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
+ vendor_event))
+ {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("put_wifi_iface_stats fail") );
+ kfree_skb(vendor_event);
+ return;
+ }
+
hddLog(VOS_TRACE_LEVEL_INFO,
"WMI_LINK_STATS_IFACE Data");
@@ -1191,9 +1291,9 @@
" mgmtRx %u "
" mgmtActionRx %u "
" mgmtActionTx %u "
- " rssiMgmt %u "
- " rssiData %u "
- " rssiAck %u",
+ " rssiMgmt %d "
+ " rssiData %d "
+ " rssiAck %d",
pWifiIfaceStat->beaconRx,
pWifiIfaceStat->mgmtRx,
pWifiIfaceStat->mgmtActionRx,
@@ -1243,23 +1343,6 @@
}
}
- if (FALSE == hdd_get_interface_info( pAdapter,
- &pWifiIfaceStat->info))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- FL("hdd_get_interface_info get fail") );
- kfree_skb(vendor_event);
- return;
- }
-
- if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
- vendor_event))
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,
- FL("put_wifi_iface_stats fail") );
- kfree_skb(vendor_event);
- return;
- }
cfg80211_vendor_event(vendor_event, GFP_KERNEL);
}
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index a658447..b3a3ad2 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -1530,6 +1530,20 @@
return VOS_STATUS_E_FAILURE;
}
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ {
+ v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
+ /* vos_is_macaddr_group expects data in v_MACADDR_t format
+ */
+ if (vos_is_macaddr_group(pDestMacAddress))
+ {
+ pAdapter->hdd_stats.hddTxRxStats.txMcast[ac]++;
+ }
+
+ }
+
+#endif
+
#ifdef FEATURE_WLAN_TDLS
if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
{
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 0e0ee1a..2187b75 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -5103,11 +5103,11 @@
// action frames transmit count
tANI_U32 mgmtActionTx;
// access Point Beacon and Management frames RSSI (averaged)
- tANI_U32 rssiMgmt;
+ tANI_S32 rssiMgmt;
// access Point Data Frames RSSI (averaged) from connected AP
- tANI_U32 rssiData;
+ tANI_S32 rssiData;
// access Point ACK RSSI (averaged) from connected AP
- tANI_U32 rssiAck;
+ tANI_S32 rssiAck;
// per ac data packet statistics
tSirWifiWmmAcStat AccessclassStats[WIFI_AC_MAX];
} tSirWifiIfaceStat, *tpSirWifiIfaceStat;
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index 5aedc81..8b268da 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -429,6 +429,91 @@
#endif
}WLANTL_RxMetaInfoType;
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+/* per interface per access category statistics */
+typedef PACKED_PRE struct PACKED_POST
+{
+ /* access category (VI, VO, BE, BK) */
+ v_U8_t ac;
+
+ /*Number of successfully transmitted unicast data pkts (ACK rcvd) */
+ v_U32_t txMpdu;
+
+ /* number of received unicast mpdu */
+ v_U32_t rxMpdu;
+
+ /* umber of succesfully transmitted multicast data packets
+ * STA case: implies ACK received from AP for the unicast packet in which mcast
+ * pkt was sent
+ */
+ v_U32_t txMcast;
+
+ /* number of received multicast data packets */
+ v_U32_t rxMcast;
+
+ /* number of received unicast a-mpdu */
+ v_U32_t rxAmpdu;
+
+ /* number of transmitted unicast a-mpdus */
+ v_U32_t txAmpdu;
+
+ /* number of data pkt losses (no ACK) */
+ v_U32_t mpduLost;
+
+ /* total number of data pkt retries */
+ v_U32_t retries;
+
+ /* number of short data pkt retries */
+ v_U32_t retriesShort;
+
+ /* number of long data pkt retries */
+ v_U32_t retriesLong;
+
+ /* data pkt min contention time (usecs) */
+ v_U32_t contentionTimeMin;
+
+ /* data pkt max contention time (usecs) */
+ v_U32_t contentionTimeMax;
+
+ /* data pkt avg contention time (usecs) */
+ v_U32_t contentionTimeAvg;
+
+ /* num of data pkts used for contention statistics */
+ v_U32_t contentionNumSamples;
+}WLANTL_AccessCategoryStatsType;
+
+/* per interface statistics */
+typedef PACKED_PRE struct PACKED_POST
+{
+ /* access point beacon received count from connected AP */
+ v_U32_t beaconRx;
+
+ /* access point mgmt frames received count from connected AP (including
+ * Beacon)
+ */
+ v_U32_t mgmtRx;
+
+ /* action frames received count */
+ v_U32_t mgmtActionRx;
+
+ /* action frames transmit count */
+ v_U32_t mgmtActionTx;
+
+ /* access Point Beacon and Management frames RSSI (averaged) */
+ v_U32_t rssiMgmt;
+
+ /* access Point Data Frames RSSI (averaged) from connected AP */
+ v_U32_t rssiData;
+
+ /* access Point ACK RSSI (averaged) from connected AP */
+ v_U32_t rssiAck;
+
+ WLANTL_AccessCategoryStatsType accessCategoryStats[WLANTL_MAX_AC];
+
+}WLANTL_InterfaceStatsType;
+
+
+#endif
/*---------------------------------------------------------------------------
Handoff support and statistics defines and enum types
@@ -1086,6 +1171,44 @@
v_U8_t ucSTAId
);
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+/*==========================================================================
+
+ FUNCTION WLANTL_CollectStats
+
+ DESCRIPTION
+ Utility function used by TL to send the statitics
+
+ DEPENDENCIES
+
+
+ PARAMETERS
+
+ IN
+
+ ucSTAId: station for which the statistics need to collected
+
+ vosDataBuff: it will contain the pointer to the corresponding
+ structure
+
+ RETURN VALUE
+ The result code associated with performing the operation
+
+ VOS_STATUS_E_INVAL: Input parameters are invalid
+ VOS_STATUS_SUCCESS: Everything is good :)
+
+ SIDE EFFECTS
+
+============================================================================*/
+VOS_STATUS
+WLANTL_CollectInterfaceStats
+(
+ v_PVOID_t pvosGCtx,
+ v_U8_t ucSTAId,
+ WLANTL_InterfaceStatsType *vosDataBuff
+);
+#endif
+
/*===========================================================================
FUNCTION WLANTL_ChangeSTAState
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index a8e8d4f..165416c 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -170,6 +170,11 @@
/*BT-AMP packet LLC OUI value*/
const v_U8_t WLANTL_BT_AMP_OUI[] = {0x00, 0x19, 0x58 };
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+extern const v_U8_t WLANTL_TID_2_AC[WLAN_MAX_TID];
+
+#endif
+
#define WLANTL_MAX_SNR_DATA_SAMPLES 20
#ifdef VOLANS_PERF
@@ -194,6 +199,11 @@
#define WLANTL_IS_MGMT_FRAME(_type_sub) \
( WLANTL_MGMT_FRAME_TYPE == ( (_type_sub) & 0x30 ))
+#define WLANTL_IS_MGMT_ACTION_FRAME(_type_sub) \
+ (( WLANTL_MGMT_FRAME_TYPE == ( (_type_sub) & 0x30 )) && \
+ ( ( WLANTL_80211_MGMT_ACTION_SUBTYPE == ( (_type_sub) & 0xF )) || \
+ ( WLANTL_80211_MGMT_ACTION_NO_ACK_SUBTYPE == ( (_type_sub) & 0xF ))))
+
#define WLANTL_IS_CTRL_FRAME(_type_sub) \
( WLANTL_CTRL_FRAME_TYPE == ( (_type_sub) & 0x30 ))
@@ -1387,6 +1397,13 @@
#else
pClientSTA->rssiAlpha = WLANTL_HO_DEFAULT_ALPHA;
#endif /* FEATURE_WLAN_TDLS */
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ pClientSTA->rssiDataAlpha = WLANTL_HO_DEFAULT_ALPHA;
+ pClientSTA->interfaceStats.accessCategoryStats[0].ac = WLANTL_AC_BK;
+ pClientSTA->interfaceStats.accessCategoryStats[1].ac = WLANTL_AC_BE;
+ pClientSTA->interfaceStats.accessCategoryStats[2].ac = WLANTL_AC_VI;
+ pClientSTA->interfaceStats.accessCategoryStats[3].ac = WLANTL_AC_VO;
+#endif
/*Tx not suspended and station fully registered*/
vos_atomic_set_U8(
@@ -5552,6 +5569,11 @@
v_U16_t usEtherType = 0;
#endif
v_BOOL_t bForwardIAPPwithLLC = VOS_FALSE;
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ v_S7_t currentAvgRSSI = 0;
+ v_U8_t ac;
+
+#endif
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
@@ -5716,6 +5738,18 @@
TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
FL("Failed to Read SNR")));
}
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ pClientSTA = pTLCb->atlSTAClients[ucSTAId];
+ if ( NULL != pClientSTA)
+ {
+ pClientSTA->interfaceStats.mgmtRx++;
+ if (WLANTL_IS_MGMT_ACTION_FRAME(ucFrmType))
+ {
+ pClientSTA->interfaceStats.mgmtActionRx++;
+
+ }
+ }
+#endif
}
pTLCb->tlMgmtFrmClient.pfnTlMgmtFrmRx( pvosGCtx, vosTempBuff);
@@ -5724,6 +5758,9 @@
{
ucSTAId = (v_U8_t)WDA_GET_RX_STAID( pvBDHeader );
ucTid = (v_U8_t)WDA_GET_RX_TID( pvBDHeader );
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ ac = WLANTL_TID_2_AC[ucTid];
+#endif
TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
"WLAN TL:Data packet received for STA %d", ucSTAId));
@@ -5737,7 +5774,6 @@
TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
"WLAN TL:TL rx Bcast frame - sending to last registered station"));
broadcast = VOS_TRUE;
-
/*-------------------------------------------------------------------
If Addr1 is b/mcast, but Addr3 is our own self MAC, it is a b/mcast
pkt we sent looping back to us. To be dropped if we are non BTAMP
@@ -5958,6 +5994,29 @@
* continue;
*/
}
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ pClientSTA = pTLCb->atlSTAClients[ucSTAId];
+ if ( NULL != pClientSTA)
+ {
+ tpSirMacMgmtHdr pMacHeader = WDA_GET_RX_MAC_HEADER( pvBDHeader );
+ if( !WDA_IS_RX_BCAST(pvBDHeader) && ( pMacHeader->da[0] & 0x1))
+ {
+ pClientSTA->interfaceStats.accessCategoryStats[ac].rxMcast++;
+ }
+
+ WLANTL_HSGetDataRSSI(pvosGCtx, pvBDHeader, ucSTAId,
+ ¤tAvgRSSI);
+ pClientSTA->interfaceStats.rssiData = currentAvgRSSI;
+
+ pClientSTA->interfaceStats.accessCategoryStats[ac].rxMpdu++;
+ if (WDA_IS_RX_AN_AMPDU (pvBDHeader))
+ {
+ pClientSTA->interfaceStats.accessCategoryStats[ac].rxAmpdu++;
+ }
+ }
+
+
+#endif
vosStatus = WLANTL_ReadSNR(pvosGCtx, pvBDHeader, ucSTAId);
if (!VOS_IS_STATUS_SUCCESS(vosStatus))
@@ -5986,6 +6045,76 @@
return VOS_STATUS_SUCCESS;
}/* WLANTL_RxFrames */
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+/*==========================================================================
+
+ FUNCTION WLANTL_CollectInterfaceStats
+
+ DESCRIPTION
+ Utility function used by TL to send the statitics
+
+ DEPENDENCIES
+
+
+ PARAMETERS
+
+ IN
+
+ ucSTAId: station for which the statistics need to collected
+
+ vosDataBuff: it will contain the pointer to the corresponding
+ structure
+
+ RETURN VALUE
+ The result code associated with performing the operation
+
+ VOS_STATUS_E_INVAL: Input parameters are invalid
+ VOS_STATUS_SUCCESS: Everything is good :)
+
+ SIDE EFFECTS
+
+============================================================================*/
+VOS_STATUS
+WLANTL_CollectInterfaceStats
+(
+ v_PVOID_t pvosGCtx,
+ v_U8_t ucSTAId,
+ WLANTL_InterfaceStatsType *vosDataBuff
+)
+{
+ WLANTL_CbType* pTLCb = NULL;
+ /*------------------------------------------------------------------------
+ Sanity check
+ ------------------------------------------------------------------------*/
+ if ( WLANTL_STA_ID_INVALID( ucSTAId ) )
+ {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "WLAN TL:Invalid station id requested on WLANTL_CollectStats"));
+ return VOS_STATUS_E_FAULT;
+ }
+ /*------------------------------------------------------------------------
+ Extract TL control block
+ ------------------------------------------------------------------------*/
+ pTLCb = VOS_GET_TL_CB(pvosGCtx);
+ if ( NULL == pTLCb )
+ {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_CollectStats"));
+ return VOS_STATUS_E_FAULT;
+ }
+
+ if ( NULL == pTLCb->atlSTAClients[ucSTAId] )
+ {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "WLAN TL:Client Memory was not allocated on %s", __func__));
+ return VOS_STATUS_E_FAILURE;
+ }
+ vos_mem_copy(vosDataBuff, &pTLCb->atlSTAClients[ucSTAId]->interfaceStats,
+ sizeof(WLANTL_InterfaceStatsType));
+ return VOS_STATUS_SUCCESS;
+}
+
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
/*==========================================================================
diff --git a/CORE/TL/src/wlan_qct_tl_hosupport.c b/CORE/TL/src/wlan_qct_tl_hosupport.c
index 1b46d77..03f213b 100644
--- a/CORE/TL/src/wlan_qct_tl_hosupport.c
+++ b/CORE/TL/src/wlan_qct_tl_hosupport.c
@@ -882,13 +882,99 @@
return status;
}
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+
+/*==========================================================================
+
+ FUNCTION WLANTL_HSGetDataRSSI
+
+ DESCRIPTION
+
+ PARAMETERS
+
+ RETURN VALUE
+
+============================================================================*/
+VOS_STATUS WLANTL_HSGetDataRSSI
+(
+ v_PVOID_t pAdapter,
+ v_PVOID_t pBDHeader,
+ v_U8_t STAid,
+ v_S7_t *currentAvgRSSI
+)
+{
+ WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter);
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+ v_S7_t currentRSSI, currentRSSI0, currentRSSI1;
+ WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL;
+
+
+ if(NULL == tlCtxt)
+ {
+ TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "Invalid TL handle"));
+ return VOS_STATUS_E_INVAL;
+ }
+
+ if ( NULL == tlCtxt->atlSTAClients[STAid] )
+ {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "WLAN TL:Client Memory was not allocated on %s", __func__));
+ return VOS_STATUS_E_FAILURE;
+ }
+
+ /*
+ * Compute RSSI only for the last MPDU of an AMPDU.
+ * Only last MPDU carries the Phy Stats Values
+ */
+ if (WDA_IS_RX_AN_AMPDU (pBDHeader)) {
+ if (!WDA_IS_RX_LAST_MPDU(pBDHeader)) {
+ return VOS_STATUS_E_FAILURE;
+ }
+ }
+
+ currentHO = &tlCtxt->hoSupport.currentHOState;
+
+ currentRSSI0 = WLANTL_GETRSSI0(pBDHeader);
+ currentRSSI1 = WLANTL_GETRSSI0(pBDHeader);
+ currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1;
+
+ if (0 == currentRSSI)
+ return VOS_STATUS_E_INVAL;
+
+#ifdef WLANTL_HO_UTEST
+ TLHS_UtestHandleNewRSSI(¤tRSSI, pAdapter);
+#endif /* WLANTL_HO_UTEST */
+
+ if(0 == tlCtxt->atlSTAClients[STAid]->rssiDataAvg)
+ {
+ *currentAvgRSSI = currentRSSI;
+ }
+ else
+ {
+ *currentAvgRSSI = ((tlCtxt->atlSTAClients[STAid]->rssiDataAvg *
+ tlCtxt->atlSTAClients[STAid]->rssiDataAlpha) +
+ (currentRSSI *
+ (10 - tlCtxt->atlSTAClients[STAid]->rssiDataAlpha))) / 10;
+ }
+
+
+ tlCtxt->atlSTAClients[STAid]->rssiDataAvg = *currentAvgRSSI;
+
+ TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "Current new Data RSSI is %d, averaged Data RSSI is %d",
+ currentRSSI, *currentAvgRSSI));
+ return status;
+}
+#endif
+
/*==========================================================================
FUNCTION
- DESCRIPTION
-
- PARAMETERS
+ DESCRIPTION
+
+ PARAMETERS
RETURN VALUE
diff --git a/CORE/TL/src/wlan_qct_tl_hosupport.h b/CORE/TL/src/wlan_qct_tl_hosupport.h
index 1d27e97..fcffea7 100644
--- a/CORE/TL/src/wlan_qct_tl_hosupport.h
+++ b/CORE/TL/src/wlan_qct_tl_hosupport.h
@@ -68,6 +68,27 @@
===========================================================================*/
#include "wlan_qct_tl.h"
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+/*==========================================================================
+
+ FUNCTION
+
+ DESCRIPTION
+
+ PARAMETERS
+
+ RETURN VALUE
+
+============================================================================*/
+VOS_STATUS WLANTL_HSGetDataRSSI
+(
+ v_PVOID_t pAdapter,
+ v_PVOID_t pBDHeader,
+ v_U8_t STAid,
+ v_S7_t *currentAvgRSSI
+);
+#endif
+
#if defined WLAN_FEATURE_NEIGHBOR_ROAMING
/*----------------------------------------------------------------------------
* Include Files
diff --git a/CORE/TL/src/wlan_qct_tli.h b/CORE/TL/src/wlan_qct_tli.h
index 7c22514..1215177 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -172,12 +172,15 @@
#define WLANTL_80211_DATA_TYPE 0x02
#define WLANTL_80211_DATA_QOS_SUBTYPE 0x08
#define WLANTL_80211_NULL_QOS_SUBTYPE 0x0C
+#define WLANTL_80211_MGMT_ACTION_SUBTYPE 0x0D
+#define WLANTL_80211_MGMT_ACTION_NO_ACK_SUBTYPE 0x0E
/*Defines for internal utility functions */
#define WLANTL_FRAME_TYPE_BCAST 0xff
#define WLANTL_FRAME_TYPE_MCAST 0x01
#define WLANTL_FRAME_TYPE_UCAST 0x00
+#define WLANTL_FRAME_TYPESUBTYPE_MASK 0x3F
/*-------------------------------------------------------------------------
BT-AMP related definition - !!! should probably be moved to BT-AMP header
@@ -492,6 +495,7 @@
v_TIME_t cacheClearTime;
}WLANTL_CacheInfoType;
+
/*---------------------------------------------------------------------------
STA Client type
---------------------------------------------------------------------------*/
@@ -673,6 +677,20 @@
v_U8_t ptkInstalled;
v_U32_t linkCapacity;
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+
+ /* Value of the averaged Data RSSI for this station */
+ v_S7_t rssiDataAvg;
+
+ /* Value of the averaged Data RSSI for this station in BMPS */
+ v_S7_t rssiDataAvgBmps;
+
+ /* Value of the Alpha to calculate Data RSSI average */
+ v_S7_t rssiDataAlpha;
+
+ WLANTL_InterfaceStatsType interfaceStats;
+#endif
}WLANTL_STAClientType;
/*---------------------------------------------------------------------------