aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordragonpt <cesar.maximo@gmail.com>2015-12-26 22:53:22 +0000
committerMoyster <oysterized@gmail.com>2016-11-11 02:41:46 +0100
commit750b2be8621bbdcd8253624663207d192159b855 (patch)
treedfa49cdab90f9da2d81c9da0f51d1402ff588582
parent63d84f67a7c04fab23a82d1e99d38e3bb4e5eab3 (diff)
wlan: WiFi Direct CTS fixs
Cylen Yao <cylen.yao@mediatek.com> Details: 1. WiFi Direct CTS tests will fail as supplicant and driver could not keep sync in following case: 1.1 supplicant will request channel when do p2p listen, but driver/firmware has not switch to the target channel when supplicant get remain on channel credit by call driver API of remain on channel; This will make supplicant and driver in unsync state which will make supplicant fail to go to listen state randomly. 1.2 Supplicant and driver will also keep unsync when do mgmt frame TX; supplicant will do other task once mgmt frame TX is returned by calling driver API mgmt_tx, but, driver has not actually TX the mgmt frame out. In extremely case, driver will drop the second mgmt frame if the previous on has not been TX out, just as the group owner test case.
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_fsm.c5
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_func.c4
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_state.c7
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_init.c2
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p_cfg80211.c57
-rw-r--r--drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h2
6 files changed, 66 insertions, 11 deletions
diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_fsm.c
index 1be7c79a0..f95851acb 100644
--- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_fsm.c
+++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_fsm.c
@@ -1530,6 +1530,9 @@ p2pFsmRunEventChannelAbort (
(prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND)));
p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE);
+ } else {
+ /* just avoid supplicant waiting too long */
+ complete(&prAdapter->prGlueInfo->rChannelReq);
}
} while (FALSE);
@@ -2490,6 +2493,8 @@ p2pFsmRunEventMgmtFrameTxDone (
(UINT_32)prMsduInfo->u2FrameLength);
prMgmtTxReqInfo->prMgmtTxMsdu = NULL;
+
+ complete(&prAdapter->prGlueInfo->rChannelReq);
}
} while (FALSE);
diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_func.c
index aa1cebd27..934a5ec7d 100644
--- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_func.c
+++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_func.c
@@ -1140,7 +1140,7 @@ p2pFuncTxMgmtFrame (
FALSE,
prTxMsduInfo->prPacket,
(UINT_32)prTxMsduInfo->u2FrameLength);
-
+ DBGLOG(P2P, EVENT, ("%s drop mgmt cookie 0x%llx\n", __func__, prMgmtTxReqInfo->u8Cookie));
// Leave it to TX Done handler.
//cnmMgtPktFree(prAdapter, prTxMsduInfo);
prMgmtTxReqInfo->prMgmtTxMsdu = NULL;
@@ -2036,7 +2036,7 @@ p2pFuncValidateRxActionFrame (
{
P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
- DEBUGFUNC("p2pFuncValidateProbeReq");
+ DEBUGFUNC("p2pFuncValidateActionFrame");
do {
diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_state.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_state.c
index 3cce79f04..f10fe8063 100644
--- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_state.c
+++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/mgmt/p2p_state.c
@@ -123,7 +123,8 @@ p2pStateInit_CHNL_ON_HAND (
prChnlReqInfo->eBand,
prChnlReqInfo->eChnlSco,
prChnlReqInfo->u4MaxInterval);
-
+ /* Complete channel request */
+ complete(&prAdapter->prGlueInfo->rChannelReq);
} while (FALSE);
return;
@@ -159,6 +160,8 @@ p2pStateAbort_CHNL_ON_HAND (
// Return Channel.
p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+ /* case: if supplicant cancel remain on channel */
+ complete(&prAdapter->prGlueInfo->rChannelReq);
}
} while (FALSE);
@@ -202,6 +205,8 @@ p2pStateAbort_REQING_CHANNEL (
else {
// Return Channel.
p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+ /* possible have not acquire channel */
+ complete(&prAdapter->prGlueInfo->rChannelReq);
}
}
diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_init.c
index b8df23cb7..8ec822f09 100644
--- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_init.c
+++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_init.c
@@ -2499,6 +2499,8 @@ wlanNetCreate(
init_completion(&prGlueInfo->rScanComp);
init_completion(&prGlueInfo->rHaltComp);
init_completion(&prGlueInfo->rPendComp);
+ init_completion(&prGlueInfo->rChannelReq);
+
#if CFG_ENABLE_WIFI_DIRECT
init_completion(&prGlueInfo->rSubModComp);
#endif
diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p_cfg80211.c
index 6717fcd5b..333f586c9 100644
--- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p_cfg80211.c
+++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/gl_p2p_cfg80211.c
@@ -1249,10 +1249,12 @@ mtk_p2p_cfg80211_remain_on_channel (
)
{
INT_32 i4Rslt = -EINVAL;
+ ULONG timeout = 0;
P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T)NULL;
P_MSG_P2P_CHNL_REQUEST_T prMsgChnlReq = (P_MSG_P2P_CHNL_REQUEST_T)NULL;
-
+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL;
+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
do {
if ((wiphy == NULL) ||
@@ -1268,6 +1270,8 @@ mtk_p2p_cfg80211_remain_on_channel (
prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
prGlueP2pInfo = prGlueInfo->prP2PInfo;
+ prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo;
+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
*cookie = prGlueP2pInfo->u8Cookie++;
@@ -1298,14 +1302,31 @@ mtk_p2p_cfg80211_remain_on_channel (
&prMsgChnlReq->rChannelInfo,
&prMsgChnlReq->eChnlSco);
#endif
-
+ INIT_COMPLETION(prGlueInfo->rChannelReq);
mboxSendMsg(prGlueInfo->prAdapter,
MBOX_ID_0,
(P_MSG_HDR_T)prMsgChnlReq,
MSG_SEND_METHOD_BUF);
-
- i4Rslt = 0;
-
+ /*
+ *Need wait until firmare grant channel to sync with supplicant,
+ *wait 2HZ to avoid grant channel takes too long or failed
+ */
+ timeout = wait_for_completion_timeout(&prGlueInfo->rChannelReq, msecs_to_jiffies(2000));
+ if (timeout == 0) {
+ DBGLOG(P2P, EVENT,("Request channel timeout(2HZ)\n"));
+ /* Throw out remain/cancel on request channel to simulate this channel request has been success */
+ kalP2PIndicateChannelReady(prGlueInfo,
+ prChnlReqInfo->u8Cookie,
+ prChnlReqInfo->ucReqChnlNum,
+ prChnlReqInfo->eBand,
+ prChnlReqInfo->eChnlSco,
+ prChnlReqInfo->u4MaxInterval);
+ /* Indicate channel return. */
+ kalP2PIndicateChannelExpired(prGlueInfo, &prP2pFsmInfo->rChnlReqInfo);
+
+ /* Return Channel */
+ p2pFuncReleaseCh(prGlueInfo->prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+ }
i4Rslt = 0;
} while (FALSE);
@@ -1327,8 +1348,11 @@ mtk_p2p_cfg80211_cancel_remain_on_channel (
)
{
INT_32 i4Rslt = -EINVAL;
+ ULONG timeout = 0;
+
P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
P_MSG_P2P_CHNL_ABORT_T prMsgChnlAbort = (P_MSG_P2P_CHNL_ABORT_T)NULL;
+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
do {
if ((wiphy == NULL) ||
@@ -1343,6 +1367,7 @@ mtk_p2p_cfg80211_cancel_remain_on_channel (
prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy));
+ prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo;
prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_ABORT_T));
@@ -1357,12 +1382,21 @@ mtk_p2p_cfg80211_cancel_remain_on_channel (
prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT;
prMsgChnlAbort->u8Cookie = cookie;
-
+ INIT_COMPLETION(prGlueInfo->rChannelReq);
mboxSendMsg(prGlueInfo->prAdapter,
MBOX_ID_0,
(P_MSG_HDR_T)prMsgChnlAbort,
MSG_SEND_METHOD_BUF);
+ timeout = wait_for_completion_timeout(&prGlueInfo->rChannelReq, msecs_to_jiffies(2000));
+ if (timeout == 0) {
+ DBGLOG(P2P, EVENT,("Cancel remain on channel timeout(2HZ)\n"));
+ /* Indicate channel return. */
+ kalP2PIndicateChannelExpired(prGlueInfo, &prP2pFsmInfo->rChnlReqInfo);
+
+ /* Return Channel */
+ p2pFuncReleaseCh(prGlueInfo->prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
+ }
i4Rslt = 0;
} while (FALSE);
@@ -1398,6 +1432,7 @@ mtk_p2p_cfg80211_mgmt_tx (
P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T)NULL;
INT_32 i4Rslt = -EINVAL;
+ ULONG timeout = 0;
P_MSG_P2P_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_P2P_MGMT_TX_REQUEST_T)NULL;
P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T)NULL;
PUINT_8 pucFrameBuf = (PUINT_8)NULL;
@@ -1450,12 +1485,18 @@ mtk_p2p_cfg80211_mgmt_tx (
kalMemCopy(pucFrameBuf, buf, len);
prMgmtFrame->u2FrameLength = len;
-
+ INIT_COMPLETION(prGlueInfo->rChannelReq);
mboxSendMsg(prGlueInfo->prAdapter,
MBOX_ID_0,
(P_MSG_HDR_T)prMsgTxReq,
MSG_SEND_METHOD_BUF);
-
+ /* should wait until frame tx successfully */
+ timeout = wait_for_completion_timeout(&prGlueInfo->rChannelReq, msecs_to_jiffies(2000));
+ if (timeout == 0) {
+ DBGLOG(P2P, EVENT, ("%s wait mgmt tx done timeout cookie 0x%llx\n", __func__, prMsgTxReq->u8Cookie));
+ i4Rslt = -EIO;
+ break;
+ }
i4Rslt = 0;
} while (FALSE);
diff --git a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h
index cfd5442c2..7c6de2a14 100644
--- a/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h
+++ b/drivers/misc/mediatek/connectivity/conn_soc/drv_wlan/mt_wifi/wlan/os/linux/include/gl_os.h
@@ -856,6 +856,8 @@ struct _GLUE_INFO_T {
struct completion rScanComp; /* indicate scan complete */
struct completion rHaltComp; /* indicate main thread halt complete */
struct completion rPendComp; /* indicate main thread halt complete */
+ struct completion rChannelReq; /* indicate channel request complete */
+
#if CFG_ENABLE_WIFI_DIRECT
struct completion rSubModComp; /*indicate sub module init or exit complete*/
#endif