diff options
| author | dragonpt <cesar.maximo@gmail.com> | 2015-12-26 22:53:22 +0000 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2016-11-11 02:41:46 +0100 |
| commit | 750b2be8621bbdcd8253624663207d192159b855 (patch) | |
| tree | dfa49cdab90f9da2d81c9da0f51d1402ff588582 | |
| parent | 63d84f67a7c04fab23a82d1e99d38e3bb4e5eab3 (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.
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 |
