wlan: Enabling caching EAPOL packets at pre-assoc
Enable TL caching at pre assoc and forwarding/flushing
packets after pre assoc.
Change-Id: Ibf9db6dfc709e6510983bf04d11014d952ee2b70
CRs-Fixed: 1115231
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h
index 8194730..a474443 100644
--- a/CORE/HDD/inc/wlan_hdd_assoc.h
+++ b/CORE/HDD/inc/wlan_hdd_assoc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -135,6 +135,9 @@
int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType );
int hdd_set_csr_auth_type( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType );
+
+void hdd_assoc_registerFwdEapolCB(void *pContext);
+
VOS_STATUS hdd_roamRegisterTDLSSTA( hdd_adapter_t *pAdapter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tANI_U8 *peerMac,
diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h
index 68f7174..06c5acc 100644
--- a/CORE/HDD/inc/wlan_hdd_tx_rx.h
+++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -400,4 +400,14 @@
}
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+/**
+ * hdd_rx_fwd_eapol() - forward cached eapol frames
+ * @vosContext : pointer to vos global context
+ * @pVosPacket: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket);
+
#endif // end #if !defined( WLAN_HDD_TX_RX_H )
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index f45ad5b..f88f7c7 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -4096,6 +4096,19 @@
return 0;
}
+/**
+ * hdd_rx_fwd_eapol() - forward cached eapol frames
+ * @vosContext : pointer to vos global context
+ * @pVosPacket: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+void hdd_assoc_registerFwdEapolCB(void *pContext)
+{
+ WLANTL_RegisterFwdEapol(pContext, hdd_rx_fwd_eapol);
+}
+
/**---------------------------------------------------------------------------
\brief __iw_set_essid() -
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index ad9c081..94984b6 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -12660,6 +12660,9 @@
pHddCtx->is_ap_mode_wow_supported =
sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
+
+ hdd_assoc_registerFwdEapolCB(pVosContext);
+
goto success;
err_reg_netdev:
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index b08ac0d..089282a 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -2879,6 +2879,74 @@
return;
}
+/**
+ * hdd_rx_fwd_eapol() - forward cached eapol frames
+ * @vosContext : pointer to vos global context
+ * @pVosPacket: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket)
+{
+ hdd_context_t *pHddCtx = NULL;
+ hdd_adapter_t * pAdapter;
+ hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
+ struct sk_buff *skb = NULL;
+ uint8_t proto_type;
+ uint8_t status;
+
+ if ((NULL == vosContext) || (NULL == pVosPacket))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
+ "%s: Null global context", __func__);
+ return;
+ }
+
+ pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vosContext);
+ if (NULL == pHddCtx)
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
+ "%s: HDD adapter context is Null", __func__);
+ return;
+ }
+
+ status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
+
+ while ( NULL != pAdapterNode && 0 == status )
+ {
+ pAdapter = pAdapterNode->pAdapter;
+
+ if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
+ break;
+
+ status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
+ pAdapterNode = pNext;
+ }
+
+ if (NULL == pAdapter)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
+ "%s: No adapter", __func__);
+ return;
+ }
+
+ vos_pkt_get_os_packet(pVosPacket, (v_VOID_t **)&skb, VOS_FALSE);
+ proto_type = vos_pkt_get_proto_type(skb,
+ pHddCtx->cfg_ini->gEnableDebugLog);
+ if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "STA RX EAPOL");
+ }
+
+ skb->dev = pAdapter->dev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx_ni(skb);
+}
+
#ifdef FEATURE_WLAN_DIAG_SUPPORT
/*
* wlan_hdd_get_eapol_params() - Function to extract EAPOL params
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index 9d1a7ea..631be11 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -721,7 +721,16 @@
vos_pkt_t* vosDataBuff,
v_U8_t ucSTAId,
WLANTL_RxMetaInfoType* pRxMetaInfo);
-
+/**
+ * WLANTL_FwdEapolCBType() - Call back to forward Eapol packet
+ * @pvosGCtx : pointer to vos global context
+ * @vosDataBuff: pointer to vos packet
+ *
+ * Return: None
+ *
+ */
+typedef void (*WLANTL_FwdEapolCBType) (v_PVOID_t pvosGCtx,
+ vos_pkt_t* vosDataBuff);
/*----------------------------------------------------------------------------
INTERACTION WITH BAP
@@ -3388,4 +3397,26 @@
*/
void WLANTL_SampleTx(void *data);
+/*
+ * WLANTL_EnablePreAssocCaching - Enable caching during pre-assoc
+ * @staid: sta client where frames are cached
+ *
+ * Return: none
+ */
+void WLANTL_EnablePreAssocCaching(void);
+
+/*
+ * WLANTL_PreAssocForward - Forward the cached packets
+ *
+ * This function forwards or flushes the packets after
+ * pre assoc success/failure.
+ *
+ * Return: none
+ */
+void WLANTL_PreAssocForward(bool flag);
+
+/* make before break */
+void WLANTL_RegisterFwdEapol(v_PVOID_t pvosGCtx,
+ WLANTL_FwdEapolCBType pfnFwdEapol);
+
#endif /* #ifndef WLAN_QCT_WLANTL_H */
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
old mode 100644
new mode 100755
index 74a1fe9..014927b
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -6078,6 +6078,30 @@
return true;
}
+/**
+ * WLANTL_CacheEapol() - cache eapol frames
+ * @pTLCb : pointer to TL context
+ * @vosTempBuff: pointer to vos packet buff
+ *
+ * Return: None
+ *
+ */
+static void WLANTL_CacheEapol(WLANTL_CbType* pTLCb, vos_pkt_t* vosTempBuff)
+{
+ if ((NULL == pTLCb) || (NULL == vosTempBuff))
+ {
+ TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid input pointer", __func__));
+ return;
+ }
+
+ if (NULL == pTLCb->vosEapolCachedFrame) {
+ TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "%s: Cache Eapol frame", __func__));
+ pTLCb->vosEapolCachedFrame = vosTempBuff;
+ }
+}
+
/*==========================================================================
FUNCTION WLANTL_RxFrames
@@ -6141,8 +6165,8 @@
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
v_S7_t currentAvgRSSI = 0;
v_U8_t ac;
-
#endif
+ uint16_t seq_no;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
@@ -6322,6 +6346,8 @@
{
ucSTAId = (v_U8_t)WDA_GET_RX_STAID( pvBDHeader );
ucTid = (v_U8_t)WDA_GET_RX_TID( pvBDHeader );
+ uDPUSig = WDA_GET_RX_DPUSIG(pvBDHeader);
+ seq_no = (uint16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pvBDHeader);
TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
"WLAN TL:Data packet received for STA %d", ucSTAId));
@@ -6346,6 +6372,16 @@
}
}/*if bcast*/
+ /* Pre assoc cache eapol */
+ if (pTLCb->preassoc_caching)
+ {
+ TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
+ "WLAN TL:TL preassoc_caching is enabled seq No: %d", seq_no));
+ WLANTL_CacheEapol(pTLCb, vosTempBuff);
+ vosTempBuff = vosDataBuff;
+ continue;
+ }
+
if (WLANTL_STA_ID_INVALID(ucSTAId))
{
TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
@@ -6456,8 +6492,7 @@
vosTempBuff = vosDataBuff;
continue;
}
- uDPUSig = WDA_GET_RX_DPUSIG( pvBDHeader );
- //Station has not yet been registered with TL - cache the frame
+ /* Station has not yet been registered with TL - cache the frame */
TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
"%s: staId %d exist %d tlState %d cache rx frame", __func__, ucSTAId,
pClientSTA->ucExists, pClientSTA->tlState));
@@ -7069,6 +7104,47 @@
return VOS_STATUS_SUCCESS;
}/* WLANTL_RxCachedFrames */
+/**
+ * WLANTL_ForwardPkts() - forward cached eapol frames
+ * @pvosGCtx: pointer to vos global context
+ * @data: value to indicate either forward or flush
+ *
+ * Return: None
+ *
+ */
+static VOS_STATUS WLANTL_ForwardPkts(void* pvosGCtx, uint32_t data)
+{
+ WLANTL_CbType* pTLCb = NULL;
+
+ pTLCb = VOS_GET_TL_CB(pvosGCtx);
+ if (NULL == pTLCb) {
+ TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid input pointer", __func__));
+ return VOS_STATUS_E_FAULT;
+ }
+
+ if (!data) {
+ TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: Pre assoc fail flush cache", __func__));
+ WLANTL_FlushCachedFrames(pTLCb->vosEapolCachedFrame);
+ goto done;
+ }
+
+ /* forward packets to HDD */
+ if (NULL != pTLCb->vosEapolCachedFrame) {
+ TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: forward pre assoc cached frames", __func__));
+ WLANTL_MonTranslate80211To8023Header(pTLCb->vosEapolCachedFrame, pTLCb);
+ pTLCb->pfnEapolFwd(pvosGCtx, pTLCb->vosEapolCachedFrame);
+ }
+
+done:
+ pTLCb->vosEapolCachedFrame = NULL;
+ pTLCb->preassoc_caching = false;
+
+ return VOS_STATUS_SUCCESS;
+}
+
/*==========================================================================
FUNCTION WLANTL_RxProcessMsg
@@ -7146,6 +7222,11 @@
ucUcastSig, ucBcastSig);
break;
+ case WLANTL_RX_FWD_PRE_ASSOC_CACHED:
+ uData = message->bodyval;
+ vosStatus = WLANTL_ForwardPkts(pvosGCtx, uData);
+ break;
+
default:
/*no processing for now*/
break;
@@ -14152,6 +14233,82 @@
vos_timer_start(&pTLCb->tx_frames_timer, WLANTL_SAMPLE_INTERVAL);
}
+
+/**
+ * WLANTL_EnablePreAssocCaching() - Enable caching EAPOL frames
+ *
+ * Return: None
+ *
+ */
+void WLANTL_EnablePreAssocCaching(void)
+{
+ v_PVOID_t pvosGCtx= vos_get_global_context(VOS_MODULE_ID_TL,NULL);
+ WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx);
+ if (NULL == pTLCb ) {
+ TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid TL pointer for global context", __func__));
+ return;
+ }
+
+ pTLCb->vosEapolCachedFrame = NULL;
+ pTLCb->preassoc_caching = true;
+}
+
+/**
+ * WLANTL_ForwardPreAssoc() - forward cached eapol frames
+ * @flag: Value to forward or flush
+ *
+ * Return: vos status
+ *
+ */
+static VOS_STATUS WLANTL_ForwardPreAssoc(bool flag)
+{
+ vos_msg_t sMessage;
+
+ VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ " ---- Serializing TL for forwarding pre assoc cache frames");
+
+ vos_mem_zero( &sMessage, sizeof(vos_msg_t));
+ sMessage.type = WLANTL_RX_FWD_PRE_ASSOC_CACHED;
+ sMessage.bodyval = flag;
+
+ return vos_rx_mq_serialize(VOS_MQ_ID_TL, &sMessage);
+}
+
+/**
+ * WLANTL_PreAssocForward() - forward cached eapol frames
+ * @flag: Value to forward or flush
+ *
+ * Return: None
+ *
+ */
+void WLANTL_PreAssocForward(bool flag)
+{
+ if(!VOS_IS_STATUS_SUCCESS(WLANTL_ForwardPreAssoc(flag)))
+ {
+ VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
+ " %s fails to forward packets", __func__);
+ }
+}
+
+/**
+ * WLANTL_RegisterFwdEapol() - register call back to forward cached eapol frame
+ * @pvosGCtx : pointer to vos global context
+ * @pfnFwdEapol: call back function pointer
+ *
+ * Return: None
+ *
+ */
+void WLANTL_RegisterFwdEapol(v_PVOID_t pvosGCtx,
+ WLANTL_FwdEapolCBType pfnFwdEapol)
+{
+ WLANTL_CbType* pTLCb = NULL;
+ pTLCb = VOS_GET_TL_CB(pvosGCtx);
+
+ pTLCb->pfnEapolFwd = pfnFwdEapol;
+
+}
+
#ifdef WLAN_FEATURE_RMC
VOS_STATUS WLANTL_RmcInit
(
diff --git a/CORE/TL/src/wlan_qct_tli.h b/CORE/TL/src/wlan_qct_tli.h
index 254122f..1ea05be 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -305,6 +305,8 @@
/* Forwarding RX cached frames */
WLANTL_RX_FWD_CACHED = 0,
+ /* Forward pre assoc cached frames */
+ WLANTL_RX_FWD_PRE_ASSOC_CACHED = 1,
}WLANTL_RxSignalsType;
/*---------------------------------------------------------------------------
@@ -1001,6 +1003,9 @@
vos_timer_t tx_frames_timer;
uint8_t sample_count;
+ bool preassoc_caching;
+ vos_pkt_t* vosEapolCachedFrame;
+ WLANTL_FwdEapolCBType pfnEapolFwd;
}WLANTL_CbType;