prima: WLAN Driver Release 3.2.0.9
diff --git a/CORE/MAC/src/pe/lim/limP2P.c b/CORE/MAC/src/pe/lim/limP2P.c
index 6f4d465..1b99e87 100644
--- a/CORE/MAC/src/pe/lim/limP2P.c
+++ b/CORE/MAC/src/pe/lim/limP2P.c
@@ -60,6 +60,8 @@
#define BSSID_OFFSET 16
#define ADDR2_OFFSET 10
#define ACTION_OFFSET 24
+#define LIM_MIN_REM_TIME_FOR_TX_ACTION_FRAME 30
+#define LIM_MIN_REM_TIME_EXT_FOR_TX_ACTION_FRAME 40
@@ -76,7 +78,7 @@
tpSetLinkStateCallback callback, void *callbackArg);
static tSirRetStatus limCreateSessionForRemainOnChn(tpAniSirGlobal pMac, tPESession **ppP2pSession);
-
+eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess);
/*------------------------------------------------------------------
*
* Below function is callback function, it is called when
@@ -129,6 +131,8 @@
tANI_U32 val;
tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time();
+ pMac->lim.gTotalScanDuration = MsgBuff->duration;
/* get the duration from the request */
val = SYS_MS_TO_TICKS(MsgBuff->duration);
@@ -315,6 +319,8 @@
// Start timer here to come back to operating channel.
pMac->lim.limTimers.gLimRemainOnChannelTimer.sessionId =
psessionEntry->peSessionId;
+ pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time();
+ pMac->lim.gTotalScanDuration = MsgRemainonChannel->duration;
/* get the duration from the request */
val = SYS_MS_TO_TICKS(MsgRemainonChannel->duration);
@@ -367,6 +373,15 @@
tpPESession psessionEntry;
tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ //Timer might get extended while Sending Action Frame
+ //In that case don't process Channel Timeout
+ if (tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer))
+ {
+ limLog( pMac, LOGE,
+ "still timer is running already and not processing limProcessRemainOnChnTimeout");
+ return;
+ }
+
limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER);
if (NULL == pMac->lim.gpLimRemainOnChanReq)
@@ -480,6 +495,7 @@
peDeleteSession( pMac, psessionEntry);
}
}
+
/* Post the meessage to Sme */
limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP, status,
MsgRemainonChannel->sessionId, 0);
@@ -488,6 +504,14 @@
pMac->lim.gpLimRemainOnChanReq = NULL;
pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+
+ /* If remain on channel timer expired and action frame is pending then
+ * indicaiton confirmation with status failure */
+ if (pMac->lim.actionFrameSessionId != 0xff)
+ {
+ limP2PActionCnf(pMac, 0);
+ }
+
return;
}
@@ -500,7 +524,7 @@
void limSendSmeMgmtFrameInd(
tpAniSirGlobal pMac, tANI_U8 frameType,
tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId,
- tANI_U32 rxChannel)
+ tANI_U32 rxChannel, tpPESession psessionEntry)
{
tSirMsgQ mmhMsg;
tpSirSmeMgmtFrameInd pSirSmeMgmtFrame = NULL;
@@ -521,7 +545,21 @@
pSirSmeMgmtFrame->mesgLen = length;
pSirSmeMgmtFrame->sessionId = sessionId;
pSirSmeMgmtFrame->frameType = frameType;
- pSirSmeMgmtFrame->rxChan = rxChannel;
+
+ /* work around for 5Ghz channel is not correct since rxhannel
+ * is 4 bits. So we don't indicate more than 16 channels
+ */
+ if( (VOS_FALSE ==
+ tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer)) &&
+ (psessionEntry != NULL) &&
+ (SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) )
+ {
+ pSirSmeMgmtFrame->rxChan = psessionEntry->currentOperChannel;
+ }
+ else
+ {
+ pSirSmeMgmtFrame->rxChan = rxChannel;
+ }
vos_mem_zero(pSirSmeMgmtFrame->frameBuf,frameLen);
vos_mem_copy(pSirSmeMgmtFrame->frameBuf,frame,frameLen);
@@ -529,6 +567,41 @@
mmhMsg.type = eWNI_SME_MGMT_FRM_IND;
mmhMsg.bodyptr = pSirSmeMgmtFrame;
mmhMsg.bodyval = 0;
+
+ if(VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer) &&
+ ( (psessionEntry != NULL) && (psessionEntry->pePersona != VOS_P2P_GO_MODE)) &&
+ (frameType == SIR_MAC_MGMT_ACTION))
+ {
+ tANI_U32 curTime = vos_timer_get_system_time();
+ if((curTime - pMac->lim.p2pRemOnChanTimeStamp) > (pMac->lim.gTotalScanDuration - LIM_MIN_REM_TIME_FOR_TX_ACTION_FRAME))
+ {
+ unsigned int chanWaitTime, vStatus ;
+
+ limLog( pMac, LOG1, FL("Rx: Extend the gLimRemainOnChannelTimer"));
+
+ pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time();
+ pMac->lim.gTotalScanDuration = LIM_MIN_REM_TIME_EXT_FOR_TX_ACTION_FRAME;
+
+ chanWaitTime = SYS_MS_TO_TICKS(40);
+ vStatus = tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer);
+
+ if (VOS_STATUS_SUCCESS != vStatus)
+ {
+ limLog( pMac, LOGE, FL("Rx: Extend the gLimRemainOnChannelTimer"));
+ }
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimRemainOnChannelTimer, chanWaitTime, 0) != TX_SUCCESS)
+ {
+ limLog( pMac, LOGE, FL("Unable to change the gLimRemainOnChannelTimer"));
+ }
+
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimRemainOnChannelTimer) != 0)
+ {
+ limLog( pMac, LOGE, FL("Unable to active the gLimRemainOnChannelTimer"));
+ }
+ }
+ }
+
limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT);
return;
} /*** end limSendSmeListenRsp() ***/
@@ -536,20 +609,26 @@
eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, tANI_U32 txCompleteSuccess)
{
- limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
- (txCompleteSuccess ? eSIR_SME_SUCCESS : eSIR_SME_SEND_ACTION_FAIL),
- pMac->lim.actionFrameSessionId, 0);
+ if (pMac->lim.actionFrameSessionId != 0xff)
+ {
+ /* The session entry might be invalid(0xff) action confirmation received after
+ * remain on channel timer expired */
+ limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ (txCompleteSuccess ? eSIR_SME_SUCCESS : eSIR_SME_SEND_ACTION_FAIL),
+ pMac->lim.actionFrameSessionId, 0);
+ pMac->lim.actionFrameSessionId = 0xff;
+ }
return eHAL_STATUS_SUCCESS;
}
-void limSetHtCaps(tpAniSirGlobal pMac,tANI_U8 *pIeStartPtr,tANI_U32 nBytes)
+void limSetHtCaps(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 *pIeStartPtr,tANI_U32 nBytes)
{
v_U8_t *pIe=NULL;
tDot11fIEHTCaps dot11HtCap;
- PopulateDot11fHTCaps(pMac,&dot11HtCap);
+ PopulateDot11fHTCaps(pMac, psessionEntry, &dot11HtCap);
pIe = limGetIEPtr(pMac,pIeStartPtr, nBytes,
DOT11F_EID_HTCAPS,ONE_BYTE);
limLog( pMac, LOGE, FL("pIe 0x%x dot11HtCap.supportedMCSSet[0]=0x%x"),
@@ -772,9 +851,53 @@
if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType)
{
- limSetHtCaps( pMac,(tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET,
+ limSetHtCaps( pMac, psessionEntry, (tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET,
nBytes);
}
+
+ /* The minimum wait for any action frame should be atleast 100 ms.
+ * If supplicant sends action frame at the end of already running remain on channel time
+ * Then there is a chance to miss the response of the frame. So increase the remain on channel
+ * time for all action frame to make sure that we receive the response frame */
+ if ((SIR_MAC_MGMT_ACTION == pFc->subType) &&
+ (0 != pMbMsg->wait))
+ {
+ if (tx_timer_running(&pMac->lim.limTimers.gLimRemainOnChannelTimer))
+ {
+ tANI_U32 val = 0;
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimRemainOnChannelTimer);
+ /* get the duration from the request */
+ pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time();
+ pMac->lim.gTotalScanDuration = pMbMsg->wait;
+
+ val = SYS_MS_TO_TICKS(pMbMsg->wait);
+
+ limLog(pMac, LOG1,
+ FL("Tx: Extending the gLimRemainOnChannelTimer\n"));
+ if (tx_timer_change(
+ &pMac->lim.limTimers.gLimRemainOnChannelTimer, val, 0)
+ != TX_SUCCESS)
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to change remain on channel Timer val\n"));
+ return;
+ }
+ else if(TX_SUCCESS != tx_timer_activate(
+ &pMac->lim.limTimers.gLimRemainOnChannelTimer))
+ {
+ limLog(pMac, LOGP,
+ FL("Unable to activate remain on channel Timer\n"));
+ limDeactivateAndChangeTimer(pMac, eLIM_REMAIN_CHN_TIMER);
+ return;
+ }
+ }
+ else
+ {
+ limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0);
+ return;
+ }
+ }
}
@@ -812,15 +935,21 @@
*/
txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
- if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType)
+ if ( (SIR_MAC_MGMT_PROBE_RSP == pFc->subType) ||
+ (pMbMsg->noack)
+ )
{
halstatus = halTxFrame( pMac, pPacket, (tANI_U16)nBytes,
HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
7,/*SMAC_SWBD_TX_TID_MGMT_HIGH */ limTxComplete, pFrame,
txFlag );
- limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ if (!pMbMsg->noack)
+ {
+ limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
halstatus, pMbMsg->sessionId, 0);
+ }
+ pMac->lim.actionFrameSessionId = 0xff;
}
else
{
@@ -834,10 +963,14 @@
limLog( pMac, LOGE, FL("could not send action frame!\n" ));
limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, halstatus,
pMbMsg->sessionId, 0);
+ pMac->lim.actionFrameSessionId = 0xff;
}
else
{
pMac->lim.actionFrameSessionId = pMbMsg->sessionId;
+ limLog( pMac, LOGE, FL("lim.actionFrameSessionId = %lu\n" ),
+ pMac->lim.actionFrameSessionId);
+
}
}