summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaveen Rawat <nrawat@qca.qualcomm.com>2013-09-13 15:32:51 -0700
committerMadan Mohan Koyyalamudi <mkoyyala@qca.qualcomm.com>2013-10-23 20:05:50 -0700
commit02049e9abfa8b4810ef48371f4b0b30ab69b3aa3 (patch)
tree300b200a3a49080693a0ba080630aa0204ec46a2
parent51f2db7c1ea52905f0afc3d434b09846677de2ae (diff)
cld: CCX features enabling for CLD
What: CCX porting changes for CLD. Contains: 1) IAPP frame routing from data path to PE/LIM in tl_shim.c 2) TSM changes in wma.c 3) TPC changes 4) few other minor changes Why: For Enabling CCX features in CLD code. CRs-fixed: 548540 Change-Id: I8c4632940f94d74d53a910f0d7188df1ccf7c204
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c278
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.h18
-rw-r--r--CORE/MAC/src/pe/include/limAdmitControl.h6
-rw-r--r--CORE/MAC/src/pe/lim/limAdmitControl.c17
-rw-r--r--CORE/MAC/src/pe/lim/limProcessActionFrame.c9
-rw-r--r--CORE/SERVICES/WMA/inc/legacy/halMsgApi.h5
-rw-r--r--CORE/SERVICES/WMA/wma.c81
-rw-r--r--CORE/SYS/legacy/src/utils/src/parserApi.c13
-rw-r--r--CORE/WDA/inc/legacy/halMsgApi.h5
9 files changed, 417 insertions, 15 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index 2fe9e69e59cb..98fb601b6a00 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -55,9 +55,254 @@
VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, ## args)
#define TLSHIM_LOGP(args...) \
VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, ## args)
+
+#ifdef FEATURE_WLAN_CCX
+
/************************/
-/* Internal Func */
+/* Internal defines */
/************************/
+#define SIZEOF_80211_HDR (sizeof(struct ieee80211_frame))
+#define LLC_SNAP_SIZE 8
+
+/* Cisco Aironet SNAP hdr */
+static u_int8_t AIRONET_SNAP_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x40,
+ 0x96, 0x00, 0x00 };
+
+/*
+ * @brief: Creates vos_pkt_t for IAPP packet and routes them to PE/LIM.
+ * @detail: This function will be executed by new deferred task. It calls
+ * in the function to process and route IAPP frame. After IAPP
+ * has been processed, it will free the passed adb_nbuf_t pointer.
+ * This function will run in non interrupt context
+ * @param: ptr_work - pointer to work struct containing passed parameters
+ * from calling function.
+ */
+void
+tlshim_mgmt_over_data_rx_handler(struct work_struct *ptr_work)
+{
+ struct deferred_iapp_work *ptr_my_work
+ = container_of(ptr_work, struct deferred_iapp_work, deferred_work);
+ pVosContextType pVosGCtx = ptr_my_work->pVosGCtx;
+ u_int8_t *data = adf_nbuf_data(ptr_my_work->nbuf);
+ u_int32_t data_len = adf_nbuf_len(ptr_my_work->nbuf);
+ struct ol_txrx_vdev_t *vdev = ptr_my_work->vdev;
+
+ /*
+ * data : is a either data starting from snap hdr or 802.11 frame
+ * data_len : length of above data
+ */
+
+ struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL,
+ pVosGCtx);
+ vos_pkt_t *rx_pkt;
+ adf_nbuf_t wbuf;
+ struct ieee80211_frame *wh;
+
+ if (!tl_shim->mgmt_rx) {
+ TLSHIM_LOGE("Not registered for Mgmt rx, dropping the frame");
+ /* this buffer is used now, free it */
+ adf_nbuf_free(ptr_my_work->nbuf);
+ /* set inUse to false, so that next IAPP frame can be processed */
+ ptr_my_work->inUse = false;
+ return;
+ }
+
+ /*
+ * allocate rx_packet: this will be used for encapsulating a
+ * sk_buff which then is passed to peHandleMgmtFrame(ptr fn)
+ * along with vos_ctx.
+ */
+ rx_pkt = vos_mem_malloc(sizeof(*rx_pkt));
+ if (!rx_pkt) {
+ TLSHIM_LOGE("Failed to allocate rx packet");
+ /* this buffer is used now, free it */
+ adf_nbuf_free(ptr_my_work->nbuf);
+ /* set inUse to false, so that next IAPP frame can be processed */
+ ptr_my_work->inUse = false;
+ return;
+ }
+
+ vos_mem_zero(rx_pkt, sizeof(*rx_pkt));
+
+ /*
+ * TODO: also check if following is used for IAPP
+ * if yes, find out how to populate this
+ * rx_pkt->pkt_meta.channel = 0;
+ */
+ rx_pkt->pkt_meta.snr = rx_pkt->pkt_meta.rssi = 0;
+
+ rx_pkt->pkt_meta.timestamp = (u_int32_t) jiffies;
+ rx_pkt->pkt_meta.mpdu_hdr_len = SIZEOF_80211_HDR;
+
+ /*
+ * mpdu len and data len will be different for native and non native
+ * format
+ */
+ if (vdev->pdev->frame_format == wlan_frm_fmt_native_wifi) {
+ rx_pkt->pkt_meta.mpdu_len = data_len;
+ rx_pkt->pkt_meta.mpdu_data_len = data_len -
+ rx_pkt->pkt_meta.mpdu_hdr_len;
+ }
+ else {
+ rx_pkt->pkt_meta.mpdu_len = data_len +
+ rx_pkt->pkt_meta.mpdu_hdr_len - ETHERNET_HDR_LEN;
+ rx_pkt->pkt_meta.mpdu_data_len = data_len - ETHERNET_HDR_LEN;
+ }
+
+ /* allocate a sk_buff with enough memory for 802.11 IAPP frame */
+ wbuf = adf_nbuf_alloc(NULL, roundup(rx_pkt->pkt_meta.mpdu_len, 4),
+ 0, 4, FALSE);
+ if (!wbuf) {
+ TLSHIM_LOGE("Failed to allocate wbuf for mgmt rx");
+ vos_mem_free(rx_pkt);
+ /* this buffer is used now, free it */
+ adf_nbuf_free(ptr_my_work->nbuf);
+ /* set inUse to false, so that next IAPP frame can be processed */
+ ptr_my_work->inUse = false;
+ return;
+ }
+
+ adf_nbuf_put_tail(wbuf, data_len);
+ adf_nbuf_set_protocol(wbuf, ETH_P_SNAP);
+
+ /* wh will contain 802.11 frame, it will be encpsulated inside sk_buff */
+ wh = (struct ieee80211_frame *) adf_nbuf_data(wbuf);
+
+ /* set mpdu hdr pointre to data of sk_buff */
+ rx_pkt->pkt_meta.mpdu_hdr_ptr = adf_nbuf_data(wbuf);
+ /* set mpdu data pointer to appropriate offset from hdr */
+ rx_pkt->pkt_meta.mpdu_data_ptr = rx_pkt->pkt_meta.mpdu_hdr_ptr +
+ rx_pkt->pkt_meta.mpdu_hdr_len;
+ /* encapsulate newly allocated sk_buff in rx_pkt */
+ rx_pkt->pkt_buf = wbuf;
+
+ if (vdev->pdev->frame_format == wlan_frm_fmt_native_wifi) {
+ /* if native wifi: copy full frame */
+ adf_os_mem_copy(wh, data, data_len);
+ }
+ else {
+ /*
+ * if not native wifi populate: copy just part after 802.11 hdr
+ * i.e. part starting from snap header
+ */
+ tpCcxIappHdr iapp_hdr_ptr = (tpCcxIappHdr)&data[ETHERNET_HDR_LEN];
+ u_int8_t *snap_hdr_ptr = &(((u_int8_t*)wh)[SIZEOF_80211_HDR]);
+ tpSirMacFrameCtl ptr_80211_FC = (tpSirMacFrameCtl)&wh->i_fc;
+ ptr_80211_FC->protVer = SIR_MAC_PROTOCOL_VERSION;
+ ptr_80211_FC->type = SIR_MAC_DATA_FRAME;
+ ptr_80211_FC->subType = SIR_MAC_DATA_QOS_DATA;
+ ptr_80211_FC->toDS = 0;
+ ptr_80211_FC->fromDS = 1;
+ ptr_80211_FC->moreFrag = 0;
+ ptr_80211_FC->retry = 0;
+ ptr_80211_FC->powerMgmt = 0;
+ ptr_80211_FC->moreData = 0;
+ ptr_80211_FC->wep = 0;
+ ptr_80211_FC->order = 0;
+
+ wh->i_dur[0] = 0;
+ wh->i_dur[1] = 0;
+
+ adf_os_mem_copy(&wh->i_addr1, &iapp_hdr_ptr->DestMac[0],
+ ETHERNET_ADDR_LEN);
+ adf_os_mem_copy(&wh->i_addr2, &iapp_hdr_ptr->SrcMac[0],
+ ETHERNET_ADDR_LEN);
+ adf_os_mem_copy(&wh->i_addr3, &vdev->last_real_peer->mac_addr.raw[0],
+ ETHERNET_ADDR_LEN);
+
+ wh->i_seq[0] = 0;
+ wh->i_seq[1] = 0;
+
+ adf_os_mem_copy( snap_hdr_ptr, &data[ETHERNET_HDR_LEN],
+ data_len - ETHERNET_HDR_LEN);
+ }
+
+ tl_shim->mgmt_rx(pVosGCtx, rx_pkt);
+ /* this buffer is used now, free it */
+ adf_nbuf_free(ptr_my_work->nbuf);
+ /* set inUse to false, so that next IAPP frame can be processed */
+ ptr_my_work->inUse = false;
+}
+
+/*
+ * @brief: This function creates the deferred task and schedules it. this is
+ * still in interrrupt context. The deferred task is created to run
+ * in non interrut context as a memory allocation of vos_pkt_t is
+ * needed and memory allocation should not be done in interrupt
+ * context.
+ * @param - pVosGCtx - vos context
+ * @param - data - data containing ieee80211 IAPP frame
+ * @param - data_len - data len containing ieee80211 IAPP frame
+ * @param - vdev - virtual device
+ */
+void
+tlshim_mgmt_over_data_rx_handler_non_interrupt_ctx(pVosContextType pVosGCtx,
+ adf_nbuf_t nbuf, struct ol_txrx_vdev_t *vdev)
+{
+ struct txrx_tl_shim_ctx *tl_shim = vos_get_context(VOS_MODULE_ID_TL,
+ pVosGCtx);
+
+ /*
+ * if there is already a deferred IAPP processing, do not start
+ * another. Instead drop it as IAPP frames are not critical and
+ * can be dropped without any disruptive effects.
+ */
+ if(tl_shim->iapp_work.inUse == false) {
+ tl_shim->iapp_work.pVosGCtx = pVosGCtx;
+ tl_shim->iapp_work.nbuf = nbuf;
+ tl_shim->iapp_work.vdev = vdev;
+ tl_shim->iapp_work.inUse = true;
+ schedule_work(&(tl_shim->iapp_work.deferred_work));
+ return;
+ }
+
+ /* Previous IAPP frame is not yet processed, drop this frame */
+ TLSHIM_LOGE("Dropping IAPP frame because previous is yet unprocessed");
+ /*
+ * TODO: If needed this can changed to have queue rather
+ * than drop frame
+ */
+ adf_nbuf_free(nbuf);
+ return;
+}
+
+/*
+ * @brief: This checks if frame is IAPP and if yes routes them to PE/LIM
+ * @param - pVosGCtx - vos context
+ * @param - msdu - frame
+ * @param - sta_id - station ID
+ */
+bool
+tlshim_check_n_process_iapp_frame (pVosContextType pVosGCtx,
+ adf_nbuf_t msdu, u_int16_t sta_id)
+{
+ u_int8_t *data = adf_nbuf_data(msdu);
+ u_int8_t offset_snap_header;
+ struct ol_txrx_pdev_t *pdev = pVosGCtx->pdev_txrx_ctx;
+ struct ol_txrx_peer_t *peer =
+ ol_txrx_peer_find_by_local_id(pVosGCtx->pdev_txrx_ctx, sta_id);
+ struct ol_txrx_vdev_t *vdev = peer->vdev;
+
+ /* frame format is natve wifi */
+ if(pdev->frame_format == wlan_frm_fmt_native_wifi)
+ offset_snap_header = SIZEOF_80211_HDR;
+ else
+ offset_snap_header = ETHERNET_HDR_LEN;
+
+ if(vos_mem_compare( &data[offset_snap_header],
+ &AIRONET_SNAP_HEADER[0], LLC_SNAP_SIZE) == VOS_TRUE) {
+ /* process IAPP frames */
+ tlshim_mgmt_over_data_rx_handler_non_interrupt_ctx(pVosGCtx,
+ msdu, vdev);
+ /* if returned true: the packet will not be passed to upper layer */
+ return true;
+ }
+
+ /* if returned false the packet will be handled by the upper layer */
+ return false;
+}
+
+#endif /* FEATURE_WLAN_CCX */
#ifdef QCA_WIFI_ISOC
static void tlshim_mgmt_rx_dxe_handler(void *context, adf_nbuf_t buflist)
@@ -341,10 +586,28 @@ static void tlshim_data_rx_handler(void *context, u_int16_t staid,
buf = rx_buf_list;
while (buf) {
next_buf = adf_nbuf_queue_next(buf);
- ret = sta_info->data_rx(vos_ctx, buf, staid);
- if (ret != VOS_STATUS_SUCCESS)
- adf_nbuf_free(buf);
- buf = next_buf;
+
+#ifdef FEATURE_WLAN_CCX
+ /*
+ * in case following returns true, a defered task was created
+ * inside function, which does following:
+ * 1) create vos packet
+ * 2) send to PE/LIM
+ * 3) free the involved sk_buff
+ */
+ if(tlshim_check_n_process_iapp_frame(vos_ctx, buf, staid)) {
+ buf = next_buf;
+ continue;
+ }
+#endif
+ /*
+ * above returned false, the packet was not IAPP.
+ * process normally
+ */
+ ret = sta_info->data_rx(vos_ctx, buf, staid);
+ if (ret != VOS_STATUS_SUCCESS)
+ adf_nbuf_free(buf);
+ buf = next_buf;
}
} else /* This should not happen if sta_info->registered is true */
goto drop_rx_buf;
@@ -930,7 +1193,10 @@ VOS_STATUS WLANTL_Open(void *vos_ctx, WLANTL_ConfigInfoType *tl_cfg)
}
INIT_WORK(&tl_shim->cache_flush_work, tl_shim_cache_flush_work);
-
+#ifdef FEATURE_WLAN_CCX
+ INIT_WORK(&(tl_shim->iapp_work.deferred_work),
+ tlshim_mgmt_over_data_rx_handler);
+#endif
/*
* TODO: Allocate memory for tx callback for maximum supported
* vdevs to maintain tx callbacks per vdev.
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
index 38389b64a848..db1ef78445c4 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
@@ -28,6 +28,16 @@
#ifndef TXRX_TL_SHIM_H
#define TXRX_TL_SHIM_H
+#ifdef FEATURE_WLAN_CCX
+typedef struct deferred_iapp_work {
+ pVosContextType pVosGCtx;
+ adf_nbuf_t nbuf;
+ struct ol_txrx_vdev_t *vdev;
+ bool inUse;
+ struct work_struct deferred_work;
+} deferred_iapp_work;
+#endif
+
struct tlshim_buf {
struct list_head list;
adf_nbuf_t buf;
@@ -49,6 +59,14 @@ struct txrx_tl_shim_ctx {
struct tlshim_sta_info sta_info[WLAN_MAX_STA_COUNT];
adf_os_spinlock_t bufq_lock;
struct work_struct cache_flush_work;
+
+#ifdef FEATURE_WLAN_CCX
+ /*
+ * work structures to defer IAPP processing to
+ * non interrupt context
+ */
+struct deferred_iapp_work iapp_work;
+#endif
};
/*
diff --git a/CORE/MAC/src/pe/include/limAdmitControl.h b/CORE/MAC/src/pe/include/limAdmitControl.h
index e9c3f0014697..e1ea2e0b1e72 100644
--- a/CORE/MAC/src/pe/include/limAdmitControl.h
+++ b/CORE/MAC/src/pe/include/limAdmitControl.h
@@ -96,8 +96,12 @@ limUpdateAdmitPolicy(
tpAniSirGlobal pMac);
tSirRetStatus limAdmitControlInit(tpAniSirGlobal pMac);
-
+#ifdef FEATURE_WLAN_CCX
+tSirRetStatus limSendHalMsgAddTs(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U8 tspecIdx, tSirMacTspecIE tspecIE, tANI_U8 sessionId, tANI_U16 tsm_interval);
+#else
tSirRetStatus limSendHalMsgAddTs(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U8 tspecIdx, tSirMacTspecIE tspecIE, tANI_U8 sessionId);
+#endif
+
tSirRetStatus limSendHalMsgDelTs(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U8 tspecIdx, tSirDeltsReqInfo delts, tANI_U8 sessionId);
void limProcessHalAddTsRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
diff --git a/CORE/MAC/src/pe/lim/limAdmitControl.c b/CORE/MAC/src/pe/lim/limAdmitControl.c
index 4ed6d531a562..1eecd32e8cd1 100644
--- a/CORE/MAC/src/pe/lim/limAdmitControl.c
+++ b/CORE/MAC/src/pe/lim/limAdmitControl.c
@@ -1071,9 +1071,19 @@ tSirRetStatus limUpdateAdmitPolicy(tpAniSirGlobal pMac)
\param tSirMacTspecIE tspecIE
\param tSirTclasInfo *tclasInfo
\param tANI_U8 tclasProc
+\param tANI_U16 tsm_interval
\return eSirRetStatus - status
-------------------------------------------------------------*/
-
+#ifdef FEATURE_WLAN_CCX
+tSirRetStatus
+limSendHalMsgAddTs(
+ tpAniSirGlobal pMac,
+ tANI_U16 staIdx,
+ tANI_U8 tspecIdx,
+ tSirMacTspecIE tspecIE,
+ tANI_U8 sessionId,
+ tANI_U16 tsm_interval)
+#else
tSirRetStatus
limSendHalMsgAddTs(
tpAniSirGlobal pMac,
@@ -1081,6 +1091,7 @@ limSendHalMsgAddTs(
tANI_U8 tspecIdx,
tSirMacTspecIE tspecIE,
tANI_U8 sessionId)
+#endif
{
tSirMsgQ msg;
tpAddTsParams pAddTsParam;
@@ -1097,6 +1108,10 @@ limSendHalMsgAddTs(
palCopyMemory(pMac->hHdd, &pAddTsParam->tspec, &tspecIE, sizeof(tSirMacTspecIE));
pAddTsParam->sessionId = sessionId;
+#ifdef FEATURE_WLAN_CCX
+ pAddTsParam->tsm_interval = tsm_interval;
+#endif
+
msg.type = WDA_ADD_TS_REQ;
msg.bodyptr = pAddTsParam;
msg.bodyval = 0;
diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index 545bc3076398..019003327091 100644
--- a/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -58,7 +58,7 @@
#endif
#include "limSessionUtils.h"
-#if defined FEATURE_WLAN_CCX
+#ifdef FEATURE_WLAN_CCX
#include "ccxApi.h"
#endif
#include "wlan_qct_wda.h"
@@ -593,8 +593,7 @@ __limProcessAddTsRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession pse
return;
}
#ifdef FEATURE_WLAN_CCX
- if (addts.tsmPresent)
- {
+ if (addts.tsmPresent) {
limLog(pMac, LOGW, "TSM IE Present");
psessionEntry->ccxContext.tsm.tid = addts.tspec.tsinfo.traffic.userPrio;
vos_mem_copy(&psessionEntry->ccxContext.tsm.tsmInfo,
@@ -700,7 +699,11 @@ __limProcessAddTsRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession pse
((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC) &&
(psessionEntry->gLimEdcaParams[upToAc(addts.tspec.tsinfo.traffic.userPrio)].aci.acm)))
{
+#ifdef FEATURE_WLAN_CCX
+ retval = limSendHalMsgAddTs(pMac, pSta->staIndex, tspecInfo->idx, addts.tspec, psessionEntry->peSessionId, addts.tsmIE.msmt_interval);
+#else
retval = limSendHalMsgAddTs(pMac, pSta->staIndex, tspecInfo->idx, addts.tspec, psessionEntry->peSessionId);
+#endif
if(eSIR_SUCCESS != retval)
{
limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecInfo->idx);
diff --git a/CORE/SERVICES/WMA/inc/legacy/halMsgApi.h b/CORE/SERVICES/WMA/inc/legacy/halMsgApi.h
index f8ec797c281b..79d2d491a33a 100644
--- a/CORE/SERVICES/WMA/inc/legacy/halMsgApi.h
+++ b/CORE/SERVICES/WMA/inc/legacy/halMsgApi.h
@@ -969,7 +969,10 @@ typedef struct
tANI_U16 tspecIdx; //TSPEC handler uniquely identifying a TSPEC for a STA in a BSS
tSirMacTspecIE tspec;
eHalStatus status;
- tANI_U8 sessionId; //PE session id for PE<->HAL interface
+ tANI_U8 sessionId; //PE session id for PE<->HAL interface
+#ifdef FEATURE_WLAN_CCX
+ tANI_U16 tsm_interval; // TSM interval period passed from lim to wma
+#endif
} tAddTsParams, *tpAddTsParams;
typedef struct
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 051273c4b9ed..ca9e079fc5e5 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -6453,10 +6453,81 @@ static void wma_start_oem_data_req(tp_wma_handle wma_handle,
}
#endif /* FEATURE_OEM_DATA_SUPPORT */
+#ifdef FEATURE_WLAN_CCX
+
+#define TSM_DELAY_HISTROGRAM_BINS 4
+/*
+ * @brief: A parallel function to WDA_ProcessTsmStatsReq for pronto. This
+ * function fetches stats from data path APIs and post
+ * WDA_TSM_STATS_RSP msg back to LIM.
+ * @param: wma_handler - handle to wma
+ * @param: pTsmStats - TSM stats struct that needs to be populated and
+ * passed in message.
+ */
+
+VOS_STATUS wma_process_tsm_stats_req(tp_wma_handle wma_handler,
+ tTSMStats *pTsmStats)
+{
+ int tid = pTsmStats->tid;
+ u_int8_t counter;
+ u_int32_t queue_delay_microsec = 0;
+ u_int32_t tx_delay_microsec = 0;
+ u_int16_t packet_count = 0;
+ u_int16_t packet_loss_count = 0;
+ /*
+ * The number of histrogram bin report by data path api are different
+ * than required by TSM, hence different (6) size array used
+ */
+ u_int16_t bin_values[QCA_TX_DELAY_HIST_REPORT_BINS] = {0,};
+
+ ol_txrx_pdev_handle pdev = vos_get_context(VOS_MODULE_ID_TXRX,
+ wma_handler->vos_context);
+
+ /* get required values from data path APIs */
+ ol_tx_delay(pdev, &queue_delay_microsec, &tx_delay_microsec, tid);
+ ol_tx_delay_hist(pdev, bin_values, tid);
+ ol_tx_packet_count(pdev, &packet_count, &packet_loss_count, tid );
+
+ /* populate pTsmStats */
+ pTsmStats->tsmMetrics.UplinkPktQueueDly = queue_delay_microsec;
+ /* store only required number of bin values */
+ for ( counter = 0; counter < TSM_DELAY_HISTROGRAM_BINS; counter++)
+ {
+ pTsmStats->tsmMetrics.UplinkPktQueueDlyHist[counter] =
+ bin_values[counter];
+ }
+ pTsmStats->tsmMetrics.UplinkPktTxDly = tx_delay_microsec;
+ pTsmStats->tsmMetrics.UplinkPktLoss = packet_loss_count;
+ pTsmStats->tsmMetrics.UplinkPktCount = packet_count;
+
+ /*
+ * No need to populate roaming delay and roaming count as they are
+ * being populated just before sending IAPP frame out
+ */
+
+ /* post this message to LIM/PE */
+ wma_send_msg(wma_handler, WDA_TSM_STATS_RSP, (void *)pTsmStats , 0) ;
+ return VOS_STATUS_SUCCESS;
+}
+
+#endif
+
static void wma_add_ts_req(tp_wma_handle wma, tAddTsParams *msg)
{
- msg->status = eHAL_STATUS_SUCCESS;
- wma_send_msg(wma, WDA_ADD_TS_RSP, msg, 0);
+#ifdef FEATURE_WLAN_CCX
+ /*
+ * msmt_interval is in unit called TU (1 TU = 1024 us)
+ * max value of msmt_interval cannot make resulting
+ * interval_miliseconds overflow 32 bit
+ */
+ ol_txrx_pdev_handle pdev =
+ vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context);
+ tANI_U32 intervalMiliseconds =
+ (msg->tsm_interval*1024)/1000;
+ ol_tx_set_compute_interval(pdev, intervalMiliseconds);
+#endif
+ msg->status = eHAL_STATUS_SUCCESS;
+ wma_send_msg(wma, WDA_ADD_TS_RSP, msg, 0);
}
static void wma_data_tx_ack_work_handler(struct work_struct *ack_work)
@@ -6799,6 +6870,12 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
}
switch (msg->type) {
+#ifdef FEATURE_WLAN_CCX
+ case WDA_TSM_STATS_REQ:
+ WMA_LOGA("McThread: WDA_TSM_STATS_REQ");
+ wma_process_tsm_stats_req(wma_handle, (tTSMStats *)msg->bodyptr);
+ break;
+#endif
case WNI_CFG_DNLD_REQ:
WMA_LOGA("McThread: WNI_CFG_DNLD_REQ");
vos_status = wma_wni_cfg_dnld(wma_handle);
diff --git a/CORE/SYS/legacy/src/utils/src/parserApi.c b/CORE/SYS/legacy/src/utils/src/parserApi.c
index 2d5c958e9a0f..9d9a478533c4 100644
--- a/CORE/SYS/legacy/src/utils/src/parserApi.c
+++ b/CORE/SYS/legacy/src/utils/src/parserApi.c
@@ -3138,6 +3138,19 @@ sirConvertBeaconFrame2Struct(tpAniSirGlobal pMac,
}
#endif
+#ifdef FEATURE_WLAN_CCX
+ /* copy CCX TPC info element */
+ if (pBeacon->CCXTxmitPower.present) {
+ pBeaconStruct->ccxTxPwr.present = 1;
+ pBeaconStruct->ccxTxPwr.power_limit =
+ pBeacon->CCXTxmitPower.power_limit;
+ }
+ if (pBeacon->QBSSLoad.present) {
+ palCopyMemory(pMac, &pBeaconStruct->QBSSLoad, &pBeacon->QBSSLoad,
+ sizeof(tDot11fIEQBSSLoad));
+ }
+#endif
+
palFreeMemory(pMac->hHdd, pBeacon);
return eSIR_SUCCESS;
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index df4066d4c0fa..416a1bf39d81 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -981,7 +981,10 @@ typedef struct
tANI_U16 tspecIdx; //TSPEC handler uniquely identifying a TSPEC for a STA in a BSS
tSirMacTspecIE tspec;
eHalStatus status;
- tANI_U8 sessionId; //PE session id for PE<->HAL interface
+ tANI_U8 sessionId; //PE session id for PE<->HAL interface
+#ifdef FEATURE_WLAN_CCX
+ tANI_U16 tsm_interval; // TSM interval period passed from lim to wda
+#endif
} tAddTsParams, *tpAddTsParams;
typedef struct