diff options
author | Shengxi Xu <shengxi.xu@mediatek.com> | 2019-01-16 15:48:30 +0800 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-03-21 02:16:47 +0000 |
commit | ae6277fdabc9363b6cce6e53a468ef1e0b5466b7 (patch) | |
tree | 991c86888828822131a7815a151536f7ae235fe6 | |
parent | 3d869412eb13863f277d5661669f55e9593001db (diff) | |
download | mt8516-v4.4-ae6277fdabc9363b6cce6e53a468ef1e0b5466b7.tar.gz |
[ALPS04272300] wifi: Add 7668 wifi reset recovery
Add 7668 wifi driver for reset recovery
Remove unused debug code
Enable premalloc for reset alloc fail issue
Change wlanRemove for P2P hang issue doing reset
Bug: 120142188
Test: pass
CR-Id: ALPS04272300
Change-Id: I4d0f39885c61c21c096492cf2fe9285c7a8a4460
Feature: Wi-Fi
Signed-off-by: Shengxi Xu <shengxi.xu@mediatek.com>
(cherry picked from commit 092346e43bf63f4b09ee70bb96d6b953f49eb903)
16 files changed, 1089 insertions, 72 deletions
diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/common/wlan_lib.c index 4f2e7d2d763b..b31ddd4133e5 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/common/wlan_lib.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/common/wlan_lib.c @@ -1681,6 +1681,11 @@ VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulParamPtr) } prAdapter->fgIsChipNoAck = TRUE; +#if CFG_CHIP_RESET_SUPPORT + DBGLOG(HAL, ERROR, "fgIsChipNoAck = %d\n", + prAdapter->fgIsChipNoAck); + glResetTrigger(prAdapter); +#endif } set_bit(GLUE_FLAG_HIF_PRT_HIF_DBG_INFO_BIT, &(prAdapter->prGlueInfo->ulFlag)); } @@ -2212,6 +2217,11 @@ WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerM DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); status = WLAN_STATUS_FAILURE; prAdapter->fgIsChipNoAck = TRUE; +#if CFG_CHIP_RESET_SUPPORT + DBGLOG(HAL, ERROR, "fgIsChipNoAck = %d\n", + prAdapter->fgIsChipNoAck); + glResetTrigger(prAdapter); +#endif break; } continue; @@ -8450,6 +8460,8 @@ BOOLEAN wlanIsChipRstRecEnabled(IN P_ADAPTER_T prAdapter) BOOLEAN wlanIsChipAssert(IN P_ADAPTER_T prAdapter) { + if (prAdapter == NULL) + return TRUE; return prAdapter->rWifiVar.fgChipResetRecover && prAdapter->fgIsChipAssert; } diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/config.h b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/config.h index 097920b49bf3..a3ad59e87b0a 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/config.h +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/config.h @@ -323,7 +323,7 @@ #define HW_WMM_NUM 4 /* HW WMM number by chip */ #ifndef CFG_CHIP_RESET_SUPPORT -#define CFG_CHIP_RESET_SUPPORT 0 +#define CFG_CHIP_RESET_SUPPORT 1 #endif /*------------------------------------------------------------------------------ @@ -992,7 +992,7 @@ *------------------------------------------------------------------------------ */ #ifndef CFG_PRE_ALLOCATION_IO_BUFFER -#define CFG_PRE_ALLOCATION_IO_BUFFER 0 +#define CFG_PRE_ALLOCATION_IO_BUFFER 1 #endif diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/precomp.h index 8dd937f8c18f..9274cb64c66c 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/precomp.h +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/include/precomp.h @@ -289,5 +289,15 @@ * F U N C T I O N S ******************************************************************************** */ +#if MTK_WCN_HIF_SDIO +extern INT_32 mtk_sdio_probe(MTK_WCN_HIF_SDIO_CLTCTX cltCtx, + const MTK_WCN_HIF_SDIO_FUNCINFO * prFuncInfo); +extern INT_32 mtk_sdio_remove(MTK_WCN_HIF_SDIO_CLTCTX cltCtx); +#else +extern int mtk_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id); +extern void mtk_sdio_remove(struct sdio_func *func); +#endif + #endif /* _PRECOMP_H */ diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/saa_fsm.c index a061d7a1bc98..5dbcc353ecbc 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/saa_fsm.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/mgmt/saa_fsm.c @@ -139,7 +139,7 @@ saaFsmSteps(IN P_ADAPTER_T prAdapter, BOOLEAN fgIsTransition; ASSERT(prStaRec); - if (!prStaRec) + if (!prStaRec || g_u4HaltFlag) return; do { diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_cfg80211.c index 9f14617c74fa..cea87b360a63 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_cfg80211.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_cfg80211.c @@ -418,10 +418,14 @@ int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_in prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); +#if CFG_CHIP_RESET_SUPPORT if (g_u4HaltFlag) { - DBGLOG(RSN, WARN, "wlan is halt, skip key deletion\n"); + DBGLOG(INIT, WARN, "wlan is halt, skip key deletion\n"); return WLAN_STATUS_FAILURE; } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif #if DBG DBGLOG(RSN, TRACE, "mtk_cfg80211_del_key\n"); @@ -451,6 +455,10 @@ int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_in else i4Rslt = 0; +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return i4Rslt; } @@ -530,7 +538,14 @@ int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); - +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip get station\n"); + return WLAN_STATUS_FAILURE; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, " entry_conut = %d\n", rst_data.entry_conut); +#endif kalMemZero(arBssid, MAC_ADDR_LEN); wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); @@ -541,6 +556,11 @@ int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const DBGLOG(REQ, WARN, "incorrect BSSID: [" MACSTR "] currently connected BSSID[" MACSTR "]\n", MAC2STR(mac), MAC2STR(arBssid)); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, " entry_conut = %d\n", + rst_data.entry_conut); +#endif return -ENOENT; } @@ -642,7 +662,10 @@ int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const #endif sinfo->tx_failed = prDevStats->tx_errors; } - +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, " entry_conut = %d\n", rst_data.entry_conut); +#endif return 0; } #else @@ -659,7 +682,14 @@ int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, u8 *m prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); - +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip get station\n"); + return WLAN_STATUS_FAILURE; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, " entry_conut = %d\n", rst_data.entry_conut); +#endif kalMemZero(arBssid, MAC_ADDR_LEN); wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); @@ -669,6 +699,11 @@ int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, u8 *m DBGLOG(REQ, WARN, "incorrect BSSID: [" MACSTR "] currently connected BSSID[" MACSTR "]\n", MAC2STR(mac), MAC2STR(arBssid)); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, " entry_conut = %d\n", + rst_data.entry_conut); +#endif return -ENOENT; } @@ -751,7 +786,10 @@ int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, u8 *m sinfo->filled |= STATION_INFO_TX_FAILED; sinfo->tx_failed = prDevStats->tx_errors; } - +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return 0; } #endif @@ -864,9 +902,35 @@ int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request ASSERT(prGlueInfo); kalMemZero(&rScanRequest, sizeof(rScanRequest)); + if (!wlanGetHifState(prGlueInfo)) + return -EINVAL; + +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip scan"); + return WLAN_STATUS_FAILURE; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif + /* check if there is any pending scan/sched_scan not yet finished */ - if (prGlueInfo->prScanRequest != NULL) + if (prGlueInfo->prScanRequest != NULL) { +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return -EBUSY; + } + + if (prGlueInfo->u4ReadyFlag == 0) { + DBGLOG(REQ, WARN, "prGlueInfo->u4ReadyFlag == 0\n"); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif + return -EFAULT; + } if (request->n_ssids == 0) { rScanRequest.u4SsidNum = 0; @@ -878,6 +942,10 @@ int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request rScanRequest.rSsid[i].u4SsidLen, request->ssids[i].ssid, request->ssids[i].ssid_len); } } else { +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return -EINVAL; } @@ -914,7 +982,10 @@ int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request rStatus = kalIoctl(prGlueInfo, wlanoidSetBssidListScanAdv, &rScanRequest, sizeof(PARAM_SCAN_REQUEST_ADV_T), FALSE, FALSE, FALSE, &u4BufLen); - +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, "scan error:%lx\n", rStatus); return -EINVAL; @@ -977,16 +1048,49 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf ENUM_PARAM_OP_MODE_T eOpMode; UINT_32 i, u4AkmSuite = 0; P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; + struct wireless_dev *wdev = NULL; #if CFG_SUPPORT_REPLAY_DETECTION P_BSS_INFO_T prBssInfo = NULL; struct SEC_DETECT_REPLAY_INFO *prDetRplyInfo = NULL; #endif - +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip conn."); + return WLAN_STATUS_FAILURE; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); - /* printk("[wlan]mtk_cfg80211_connect\n"); */ + if (ndev == NULL) { + DBGLOG(REQ, ERROR, "ndev is NULL\n"); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif + return -EINVAL; + } + wdev = ndev->ieee80211_ptr; + + /* Supplicant requests connecting during driver do disconnecting, + * it will cause to install key fail, error is -67(link has been + * servered). + * Beacaus driver disconnected is done, but cfg80211 is disconnecting. + * Reject this request.Supplicant will issue the connecting request again. + */ + if (wdev->current_bss && + kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { + DBGLOG(REQ, WARN, "Reject this connecting request\n"); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif + return -EALREADY; + } + if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) eOpMode = NET_TYPE_AUTO_SWITCH; else @@ -997,6 +1101,10 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, INFO, "wlanoidSetInfrastructureMode fail 0x%lx\n", rStatus); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return -EFAULT; } @@ -1076,6 +1184,11 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf break; default: DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", + rst_data.entry_conut); +#endif return -EINVAL; } } @@ -1100,6 +1213,11 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf break; default: DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", + rst_data.entry_conut); +#endif return -EINVAL; } } @@ -1120,6 +1238,11 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf break; default: DBGLOG(REQ, WARN, "invalid Akm Suite (%d)\n", sme->crypto.akm_suites[0]); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", + rst_data.entry_conut); +#endif return -EINVAL; } } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { @@ -1145,6 +1268,11 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf #endif default: DBGLOG(REQ, WARN, "invalid Akm Suite (%d)\n", sme->crypto.akm_suites[0]); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", + rst_data.entry_conut); +#endif return -EINVAL; } } @@ -1289,6 +1417,11 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf prWepKey->u4KeyIndex |= IS_TRANSMIT_KEY; if (prWepKey->u4KeyLength > MAX_KEY_LEN) { DBGLOG(REQ, WARN, "Too long key length (%lu)\n", prWepKey->u4KeyLength); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", + rst_data.entry_conut); +#endif return -EINVAL; } kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); @@ -1298,6 +1431,11 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, INFO, "wlanoidSetAddWep fail 0x%lx\n", rStatus); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", + rst_data.entry_conut); +#endif return -EFAULT; } } @@ -1311,6 +1449,10 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return -EINVAL; } #if 0 @@ -1345,6 +1487,10 @@ int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cf } } #endif +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return 0; } @@ -1479,6 +1625,20 @@ int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bo if (!prGlueInfo->prAdapter->prAisBssInfo) return -EFAULT; + if (prGlueInfo->u4ReadyFlag == 0) { + DBGLOG(REQ, WARN, "prGlueInfo->u4ReadyFlag == 0\n"); + return -EFAULT; + } + +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip set pwr mgmt\n"); + return WLAN_STATUS_FAILURE; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif + if (enabled) { if (timeout == -1) rPowerMode.ePowerMode = Param_PowerModeFast_PSP; @@ -1493,7 +1653,10 @@ int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bo rStatus = kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, &rPowerMode, sizeof(PARAM_POWER_MODE_T), FALSE, FALSE, TRUE, &u4BufLen); - +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, "set_power_mgmt error:%lx\n", rStatus); return -EFAULT; @@ -1587,6 +1750,14 @@ int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) return -ENOMEM; } +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip flush pmksa\n"); + return WLAN_STATUS_FAILURE; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif prPmkid->u4Length = 8; prPmkid->u4BSSIDInfoCount = 0; @@ -1596,6 +1767,10 @@ int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) DBGLOG(INIT, INFO, "flush pmkid error:%lx\n", rStatus); kalMemFree(prPmkid, VIR_MEM_TYPE, 8); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return 0; } @@ -1707,6 +1882,14 @@ void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, #endif P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip mgmt reg."); + return; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif do { DBGLOG(INIT, TRACE, "mtk_cfg80211_mgmt_frame_register\n"); @@ -1769,6 +1952,11 @@ void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, } while (FALSE); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif + } /* mtk_cfg80211_mgmt_frame_register */ /*----------------------------------------------------------------------------*/ @@ -1801,6 +1989,9 @@ int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); + if (!wlanGetHifState(prGlueInfo)) + break; + #if 1 DBGLOG(INIT, INFO, "--> %s()\n", __func__); #endif diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_init.c index f8434dc5b9ed..5d4d9e91d1da 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_init.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_init.c @@ -161,6 +161,11 @@ static PUINT_8 apucEepromName[] = { }; #endif +#if CFG_CHIP_RESET_SUPPORT +static int g_u4ProbeChipResetTimes; +#define PROBE_CHIP_RESET_LIMIT 3 +#endif + int CFG80211_Suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) { DBGLOG(INIT, INFO, "CFG80211 suspend CB\n"); @@ -830,6 +835,43 @@ P_GLUE_INFO_T wlanGetGlueInfo(VOID) /*----------------------------------------------------------------------------*/ /*! +* \brief This function check the HIF state allow to handle callback or not. +* +* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T +* +* \return TRUE: HIF state allow to handle it. +* FALSE: HIF state NOT allow to handle it. +*/ +/*---------------------------------------------------------------------------*/ +BOOLEAN wlanGetHifState(IN P_GLUE_INFO_T prGlueInfo) +{ + P_GL_HIF_INFO_T prHifInfo; + BOOLEAN fgIsHifReady = TRUE; +#if defined(_HIF_USB) + unsigned long flags; +#endif + + if (!prGlueInfo) { + DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); + return FALSE; + } + + prHifInfo = &prGlueInfo->rHifInfo; + +#if defined(_HIF_USB) + spin_lock_irqsave(&prHifInfo->rStateLock, flags); + if (prHifInfo->state != USB_STATE_LINK_UP) { + DBGLOG(INIT, WARN, "USB in suspend skip cfg callback\n"); + fgIsHifReady = FALSE; + } + spin_unlock_irqrestore(&prHifInfo->rStateLock, flags); +#endif + + return fgIsHifReady; +} + +/*----------------------------------------------------------------------------*/ +/*! * \brief This function is to set multicast list and set rx mode. * * \param[in] prDev Pointer to struct net_device @@ -2217,7 +2259,7 @@ label_exit: * \retval negative value Failed */ /*----------------------------------------------------------------------------*/ -static INT_32 wlanProbe(PVOID pvData, PVOID pvDriverData) +INT_32 wlanProbe(PVOID pvData, PVOID pvDriverData) { struct wireless_dev *prWdev = NULL; P_WLANDEV_INFO_T prWlandevInfo = NULL; @@ -2513,6 +2555,24 @@ static INT_32 wlanProbe(PVOID pvData, PVOID pvDriverData) #endif } while (FALSE); + + if (i4Status != 0) { + if (prGlueInfo == NULL) + return -1; + + glBusFreeIrq(prGlueInfo->prDevHandler, prGlueInfo); + DBGLOG(INIT, ERROR, "probe failed %d\n", i4Status); + +#if CFG_CHIP_RESET_SUPPORT + if (g_u4ProbeChipResetTimes < PROBE_CHIP_RESET_LIMIT) { + DBGLOG(INIT, ERROR, "wlanProbe: trigger whole reset\n"); + g_u4ProbeChipResetTimes++; + glResetTrigger(prGlueInfo->prAdapter); + } +#endif + return i4Status; + } + /* Configure 5G band for registered wiphy */ if (prAdapter->fgEnable5GBand) prWdev->wiphy->bands[KAL_BAND_5GHZ] = &mtk_band_5ghz; @@ -2616,6 +2676,11 @@ static INT_32 wlanProbe(PVOID pvData, PVOID pvDriverData) GTK_REKEY_CMD_MODE_RPY_OFFLOAD_OFF); } #endif +#if CFG_CHIP_RESET_SUPPORT + g_u4ProbeChipResetTimes = 0; +#endif + DBGLOG(INIT, EVENT, "wlanProbe: probe success\n"); + set_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag); return i4Status; } /* end of wlanProbe() */ @@ -2628,7 +2693,7 @@ static INT_32 wlanProbe(PVOID pvData, PVOID pvDriverData) * \return (none) */ /*----------------------------------------------------------------------------*/ -static VOID wlanRemove(VOID) +VOID wlanRemove(VOID) { struct net_device *prDev = NULL; P_WLANDEV_INFO_T prWlandevInfo = NULL; @@ -2692,8 +2757,13 @@ static VOID wlanRemove(VOID) flush_delayed_work(&sched_workq); + rtnl_lock(); + clear_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag); + rtnl_unlock(); + down(&g_halt_sem); g_u4HaltFlag = 1; + up(&g_halt_sem); /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); @@ -2784,8 +2854,6 @@ static VOID wlanRemove(VOID) /* 4 <5> Release the Bus */ glBusRelease(prDev); - up(&g_halt_sem); - /* 4 <6> Unregister the card */ wlanNetUnregister(prDev->ieee80211_ptr); @@ -2823,6 +2891,10 @@ static int initWlan(void) int ret = 0; DBGLOG(INIT, INFO, "initWlan\n"); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut = 0; +#endif + #ifdef CFG_DRIVER_INF_NAME_CHANGE diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_kal.c index deb23aa3ec42..c42c6dcf3442 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_kal.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_kal.c @@ -157,7 +157,7 @@ static PPUINT_8 appucFwNameTable[] = { }; #if CFG_ASSERT_DUMP /* Core dump debug usage */ -#if MTK_WCN_HIF_SDIO +#if 1 PUINT_8 apucCorDumpN9FileName = "/data/misc/wifi/FW_DUMP_N9"; PUINT_8 apucCorDumpCr4FileName = "/data/misc/wifi/FW_DUMP_Cr4"; #else @@ -963,6 +963,7 @@ kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus struct cfg80211_bss *bss; UINT_8 ucChannelNum; P_BSS_DESC_T prBssDesc = NULL; + gfp_t flags = GFP_KERNEL; GLUE_SPIN_LOCK_DECLARATION(); @@ -1096,6 +1097,9 @@ kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus DBGLOG(INIT, INFO, "[wifi] %s netif_carrier_off\n", prGlueInfo->prDevHandler->name); #endif + if (prGlueInfo->prAdapter->fgIsChipAssert) + flags = GFP_ATOMIC; + netif_carrier_off(prGlueInfo->prDevHandler); if (prGlueInfo->fgIsRegistered == TRUE) { P_BSS_INFO_T prBssInfo = prGlueInfo->prAdapter->prAisBssInfo; @@ -1109,7 +1113,7 @@ kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus (eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY)); cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, - GFP_KERNEL); + flags); #else @@ -1127,7 +1131,7 @@ kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus u2DeauthReason = prBssInfo->u2DeauthReason; /* CFG80211 Indication */ cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, - GFP_KERNEL); + flags); } @@ -5076,6 +5080,9 @@ WLAN_STATUS kalWriteCorDumpFile(PUINT_8 pucBuffer, UINT_16 u2Size, BOOLEAN fgIsN UINT_32 ret; PUINT_8 apucFileName; + DBGLOG(INIT, WARN, "kalWriteCorDumpFile undo...\n"); + return WLAN_STATUS_SUCCESS; + if (fgIsN9) apucFileName = apucCorDumpN9FileName; else diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p.c index 06823632cc0d..3d5f12f9f0b6 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p.c @@ -113,7 +113,6 @@ ******************************************************************************** */ - /******************************************************************************* * P R I V A T E D A T A ******************************************************************************** @@ -1493,6 +1492,11 @@ static void p2pSetMulticastList(IN struct net_device *prDev) return; } +#if CFG_CHIP_RESET_SUPPORT + if (g_u4HaltFlag || checkResetState()) + return; +#endif + g_P2pPrDev = prDev; /* 4 Mark HALT, notify main thread to finish current job */ @@ -1592,6 +1596,11 @@ int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) ASSERT(prSkb); ASSERT(prDev); +#if CFG_CHIP_RESET_SUPPORT + if (g_u4HaltFlag || checkResetState()) + return NETDEV_TX_BUSY; +#endif + prNetDevPrivate = (P_NETDEV_PRIVATE_GLUE_INFO) netdev_priv(prDev); prGlueInfo = prNetDevPrivate->prGlueInfo; ucBssIndex = prNetDevPrivate->ucBssIdx; @@ -1636,6 +1645,11 @@ int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) ASSERT(prDev && prIfReq); +#if CFG_CHIP_RESET_SUPPORT + if (g_u4HaltFlag || checkResetState()) + return -EFAULT; +#endif + DBGLOG(P2P, ERROR, "p2pDoIOCTL In %x %x\n", i4Cmd, SIOCDEVPRIVATE); prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p_cfg80211.c index 3c4b025527ce..e430a4e46e2b 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p_cfg80211.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_p2p_cfg80211.c @@ -630,7 +630,6 @@ int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, #endif ASSERT(wiphy); - prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); if (mtk_Netdev_To_RoleIdx(prGlueInfo, ndev, &ucRoleIdx) != 0) @@ -1002,6 +1001,9 @@ int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *req if (wlanIsChipAssert(prGlueInfo->prAdapter)) break; + if (!wlanGetHifState(prGlueInfo)) + break; + prP2pGlueInfo = prGlueInfo->prP2PInfo[0]; prP2pGlueDevInfo = prGlueInfo->prP2PDevInfo; @@ -1970,6 +1972,10 @@ int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, } prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); + + if (!wlanGetHifState(prGlueInfo)) + break; + prGlueP2pDevInfo = prGlueInfo->prP2PDevInfo; *cookie = prGlueP2pDevInfo->u8Cookie++; @@ -2758,6 +2764,20 @@ void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, PUINT_32 pu4P2pPacketFilter = NULL; P_P2P_ROLE_FSM_INFO_T prP2pRoleFsmInfo = (P_P2P_ROLE_FSM_INFO_T) NULL; +#if CFG_CHIP_RESET_SUPPORT + if (checkResetState() || g_u4HaltFlag) { + DBGLOG(INIT, WARN, "wlan is halt, skip reg callback"); + return; + } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#else + if (g_u4HaltFlag) { + DBGLOG(RLM, WARN, "wlan is halt, skip reg callback\n"); + return; + } +#endif + do { if ((wiphy == NULL) || (wdev == NULL)) break; @@ -2836,6 +2856,11 @@ void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, } while (FALSE); +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif + } /* mtk_p2p_cfg80211_mgmt_frame_register */ #ifdef CONFIG_NL80211_TESTMODE @@ -3364,7 +3389,6 @@ int mtk_p2p_cfg80211_testmode_hotspot_block_list_cmd(IN struct wiphy *wiphy, IN UINT_32 i; ASSERT(wiphy); - prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); if (data && len) @@ -3390,7 +3414,6 @@ int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN i UINT_32 u4SetInfoLen = 0; ASSERT(wiphy); - prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); #if 1 @@ -3436,7 +3459,6 @@ int mtk_p2p_cfg80211_testmode_get_best_channel(IN struct wiphy *wiphy, IN void * WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; ASSERT(wiphy); - prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); if (!prGlueInfo) { DBGLOG(P2P, ERROR, "No glue info\n"); diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_proc.c index 7afb70835685..be9d2d31e659 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_proc.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_proc.c @@ -98,8 +98,6 @@ #define PROC_CSI_DATA_NAME "csi_data" #define PROC_GET_TXPWR_TBL "get_txpwr_tbl" - - #define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN 20 #define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN 10 #define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN 10 @@ -597,6 +595,17 @@ static ssize_t procDbgLevelWrite(struct file *file, const char __user *buffer, } g_aucProcBuf[u4CopySize] = '\0'; +#if CFG_CHIP_RESET_SUPPORT + if (temp[0] == 'R') { + P_GLUE_INFO_T prGlueInfo = NULL; + + prGlueInfo = g_prGlueInfo_proc; + DBGLOG(RSN, ERROR, "WIFI trigger reset!!\n"); + glResetTrigger(prGlueInfo->prAdapter); + temp[0] = 'X'; + } +#endif + while (temp) { if (sscanf(temp, "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2) { DBGLOG(INIT, ERROR, "debug module and debug level should be one byte in length\n"); @@ -1294,7 +1303,6 @@ INT_32 procRemoveProcfs(VOID) #if CFG_SUPPORT_DEBUG_FS remove_proc_entry(PROC_ROAM_PARAM, gprProcRoot); remove_proc_entry(PROC_COUNTRY, gprProcRoot); - #endif return 0; } /* end of procRemoveProcfs() */ @@ -1361,6 +1369,7 @@ INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo) DBGLOG(INIT, ERROR, "Unable to create /proc entry csidata\n\r"); return -1; } + return 0; } diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_rst.c index 22ed24dc610b..9014d2c4298a 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_rst.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_rst.c @@ -71,6 +71,9 @@ ******************************************************************************** */ #include "precomp.h" +#include "gl_os.h" +#include <linux/timer.h> +#include <linux/mmc/card.h> #if CFG_CHIP_RESET_SUPPORT @@ -78,29 +81,108 @@ * C O N S T A N T S ******************************************************************************** */ +#ifdef _HIF_SDIO +#define WAIT_CD_STAR_TIME 3 +#define WAIT_CD_END_TIME 30 + +#define MT76x8_PMU_EN_PIN_NAME "mt76x8_pmu_en_gpio" +#define MT76x8_PMU_EN_DELAY_NAME "mt76x8_pmu_en_delay" +#define MT76x8_PMU_EN_DEFAULT_DELAY (5) /* Default delay 5ms */ + +#define BT_NOTIFY 1 +#define TIMEOUT_NOTIFY 2 + +#define NOTIFY_SUCCESS 0 +#define RESETTING 1 +#define NOTIFY_REPEAT 2 +#endif /******************************************************************************* * P U B L I C D A T A ******************************************************************************** */ +struct rst_struct rst_data; + +#ifdef _HIF_SDIO + +BOOLEAN g_fgIsCoreDumpStart = FALSE; +BOOLEAN g_fgIsCoreDumpEnd = FALSE; +BOOLEAN g_fgIsNotifyWlanRemove = FALSE; +BOOLEAN gl_sdio_fail = FALSE; + +struct work_struct remove_work; + + +wait_queue_head_t wait_core_dump_start; +wait_queue_head_t wait_core_dump_end; +struct timer_list wait_CD_start_timer; +struct timer_list wait_CD_end_timer; + +#endif /******************************************************************************* * P R I V A T E D A T A ******************************************************************************** */ +#ifdef _HIF_SDIO +BOOLEAN g_fgIsWifiTrig = FALSE; +BOOLEAN g_fgIsBTTrig = FALSE; + +static BOOLEAN g_fgIsBTExist = TRUE; +static BOOLEAN g_fgIsCDEndTimeout = FALSE; +static BOOLEAN g_fgIsNotifyBTRemoveEnd = FALSE; + +#endif +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef _HIF_SDIO + +#define IS_CORE_DUMP_START() (g_fgIsCoreDumpStart) +#define IS_CORE_DUMP_END() (g_fgIsCoreDumpEnd) + +#endif /******************************************************************************* * F U N C T I O N D E C L A R A T I O N S ******************************************************************************** */ +#ifdef _HIF_SDIO +static void resetInit(void); + +static INT_32 pmu_toggle(struct rst_struct *data); + +static void init_wait_CD_start_timer(void); +static void start_wait_CD_start_timer(void); +static void wait_CD_start_timeout(unsigned long data); + +static void init_wait_CD_end_timer(void); +static void start_wait_CD_end_timer(void); +static void wait_CD_end_timeout(unsigned long data); + +static void removeWlanSelf(struct work_struct *work); +static void probeWlanSelf(struct work_struct *work); + +static void RSTClearResource(void); +static void RSTClearState(void); +static VOID set_core_dump_start(BOOLEAN fgVal); + +static INT_32 notify_wlan_toggle_rst_end(INT_32 reserved); +static void RSTP2pDestroyWirelessDevice(void); + +#endif + + /******************************************************************************* * F U N C T I O N S ******************************************************************************** */ - +#ifdef _HIF_USB VOID glResetTrigger(P_ADAPTER_T prAdapter) { + void (*btmtk_usb_toggle_rst_pin)(void); /* Call POR(Power On Reset) off->on API provided by BT driver */ @@ -112,8 +194,474 @@ VOID glResetTrigger(P_ADAPTER_T prAdapter) DBGLOG(HAL, ERROR, "Trigger MT7668 POR(Power On Reset) off->on by BT driver\n"); btmtk_usb_toggle_rst_pin(); } + +} +#endif + +#ifdef _HIF_SDIO +VOID glResetTrigger(P_ADAPTER_T prAdapter) +{ + int bet = 0; + typedef int (*p_bt_fun_type) (int); + p_bt_fun_type bt_func; + + /* int btmtk_sdio_bt_trigger_core_dump(int reserved); */ + char *bt_func_name = "btmtk_sdio_bt_trigger_core_dump"; + + DBGLOG(HAL, INFO, "[RST] rst_mutex lock\n"); + mutex_lock(&(rst_data.rst_mutex)); + + if (checkResetState()) { + DBGLOG(HAL, STATE, "[RST] resetting...\n"); + mutex_unlock(&(rst_data.rst_mutex)); + DBGLOG(INIT, INFO, "[RST] rst_mutex unlock\n"); + return; + } + + dump_stack(); + DBGLOG(HAL, STATE, "[RST] glResetTrigger start\n"); + g_fgIsWifiTrig = TRUE; + + mutex_unlock(&(rst_data.rst_mutex)); + DBGLOG(INIT, INFO, "[RST] rst_mutex unlock\n"); + + resetInit(); + + /* check bt module */ + bt_func = (p_bt_fun_type) kallsyms_lookup_name(bt_func_name); + if (bt_func) { + BOOLEAN is_coredump = (~(prAdapter->fgIsChipNoAck)) & 0x1; + + is_coredump = 0; + + DBGLOG(INIT, STATE, "[RST] wifi driver trigger rst\n"); + DBGLOG(INIT, STATE, "[RST] is_coredump = %d\n", + is_coredump); +#if CFG_ASSERT_DUMP + bet = bt_func(is_coredump); +#else + bet = bt_func(0); +#endif + if (bet) { + g_fgIsBTExist = FALSE; + DBGLOG(INIT, ERROR, "[RST] bt driver is not ready\n"); + /* error handle not yet */ + goto RESET_START; + } else { + g_fgIsBTExist = TRUE; + start_wait_CD_start_timer(); + DBGLOG(INIT, STATE, + "[RST] wait bt core dump start...\n"); + + if (!IS_CORE_DUMP_START()) { + /* wait bt notify */ + wait_event(wait_core_dump_start, + g_fgIsCoreDumpStart); + DBGLOG(INIT, STATE, + "[RST] wait_core_dump_start end\n"); + } + bet = del_timer_sync(&wait_CD_start_timer); + DBGLOG(INIT, INFO, + "[RST] cancel wait_CD_start_timer=%d\n", bet); + + goto RESET_START; + } + } else { + g_fgIsBTExist = FALSE; + DBGLOG(INIT, ERROR, "[RST] %s: do not get %s\n", __func__, + bt_func_name); + goto RESET_START; + + } + +RESET_START: + + /* checkResetState(); // for debug */ + schedule_work(&remove_work); + DBGLOG(INIT, STATE, "[RST] creat remove_work\n"); +} +#endif + +#ifdef _HIF_PCIE +VOID glResetTrigger(P_ADAPTER_T prAdapter) +{ + DBGLOG(HAL, ERROR, "pcie does not support trigger core dump yet !!\n"); } +#endif + +#ifdef _HIF_SDIO +/*----------------------------------------------------------------------------*/ +/*! +* \brief . +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +void resetInit(void) +{ + DBGLOG(INIT, STATE, "[RST] resetInit start\n"); + + g_fgIsCoreDumpStart = FALSE; + g_fgIsCoreDumpEnd = FALSE; + g_fgIsCDEndTimeout = FALSE; + g_fgIsNotifyWlanRemove = FALSE; + g_fgIsNotifyBTRemoveEnd = FALSE; + + INIT_WORK(&remove_work, removeWlanSelf); + INIT_WORK(&(rst_data.rst_work), probeWlanSelf); + + init_waitqueue_head(&wait_core_dump_start); + /* init_waitqueue_head(&wait_core_dump_end); */ + init_wait_CD_start_timer(); + init_wait_CD_end_timer(); + + DBGLOG(INIT, STATE, "[RST] resetInit end\n"); + +} +static void RSTClearResource(void) +{ + DBGLOG(INIT, STATE, "[RST] resetClear start\n"); + + del_timer_sync(&wait_CD_start_timer); + del_timer_sync(&wait_CD_end_timer); + + /* cancel_work_sync(&rst_data.rst_work); */ + cancel_work_sync(&remove_work); + + gl_sdio_fail = FALSE; + DBGLOG(INIT, STATE, "[RST] resetClear end\n"); +} + +static void RSTClearState(void) +{ + DBGLOG(INIT, STATE, "[RST] RSTClearState\n"); + g_fgIsWifiTrig = FALSE; + g_fgIsBTTrig = FALSE; + g_fgIsNotifyWlanRemove = FALSE; +} + +void removeWlanSelf(struct work_struct *work) +{ + int bet = 0; + typedef int (*p_bt_fun_type) (void); + p_bt_fun_type bt_func; + /* int btmtk_sdio_notify_wlan_remove_end(void) */ + char *bt_func_name = "btmtk_sdio_notify_wlan_remove_end"; + + DBGLOG(INIT, STATE, "[RST] check entry_conut = %d\n", + rst_data.entry_conut); + while (rst_data.entry_conut != 0) + kalMsleep(100); + + DBGLOG(INIT, STATE, "[RST] start mtk_sdio_remove\n"); +#if MTK_WCN_HIF_SDIO + bet = mtk_sdio_remove(); +#else + mtk_sdio_remove(rst_data.func); +#endif + DBGLOG(INIT, STATE, "[RST] mtk_sdio_remove end\n"); + + DBGLOG(INIT, STATE, "[RST] RSTP2pDestroyWirelessDevice start\n"); + RSTP2pDestroyWirelessDevice(); + DBGLOG(INIT, STATE, "[RST] RSTP2pDestroyWirelessDevice end\n"); + + /* notify bt wifi remove end */ + bt_func = (p_bt_fun_type) kallsyms_lookup_name(bt_func_name); + if (bt_func) { + + DBGLOG(INIT, STATE, "[RST] notify bt remove...\n"); + bet = bt_func(); + if (bet) { + g_fgIsBTExist = FALSE; + DBGLOG(INIT, ERROR, "[RST] notify bt fail\n"); + notify_wlan_toggle_rst_end(0); + } else { + g_fgIsNotifyBTRemoveEnd = TRUE; + DBGLOG(INIT, STATE, "[RST] notify bt remove end\n"); + start_wait_CD_end_timer(); + } + } else { + g_fgIsBTExist = FALSE; + DBGLOG(INIT, ERROR, "[RST] do not get %s\n", + bt_func_name); + notify_wlan_toggle_rst_end(0); + } + +} +void probeWlanSelf(struct work_struct *work) +{ + INT_32 i4Status = 0; + + DBGLOG(INIT, INFO, "[RST] g_fgIsBTExist=%d\n", g_fgIsBTExist); + DBGLOG(INIT, INFO, "[RST] g_fgIsCDEndTimeout=%d\n", + g_fgIsCDEndTimeout); + DBGLOG(INIT, INFO, "[RST] g_fgIsNotifyBTRemoveEnd=%d\n", + g_fgIsNotifyBTRemoveEnd); + + while (g_fgIsNotifyBTRemoveEnd == FALSE && g_fgIsBTExist == TRUE) + kalMsleep(10); + + DBGLOG(INIT, STATE, "[RST] probeWlanSelf start\n"); + + if (g_fgIsBTExist == FALSE || g_fgIsCDEndTimeout == TRUE) { + DBGLOG(INIT, WARN, "[RST] sdio_claim_host\n"); + sdio_claim_host(rst_data.func); + + i4Status = pmu_toggle(&rst_data); + if (i4Status) { + DBGLOG(INIT, WARN, + "[RST] pmu_toggle fail num=%d!\n" + , i4Status); + return; + } + kalMsleep(500); + + DBGLOG(INIT, WARN, "[RST] sdio_reset_comm\n"); + i4Status = sdio_reset_comm(rst_data.func->card); + if (i4Status) + DBGLOG(INIT, ERROR, + "[RST] sdio_reset_comm, err=%d\n", i4Status); + kalMsleep(1000); + + sdio_release_host(rst_data.func); + DBGLOG(INIT, WARN, "[RST] sdio_release_host\n"); + } + + RSTClearResource(); + + /* + * When removed wlan, android framework insmod wlan driver agian. + * So no need mtk_sdio_probe() when trigger reset. + */ +#if 1 + DBGLOG(INIT, STATE, "[RST] mtk_sdio_probe start\n"); +#if MTK_WCN_HIF_SDIO + i4Status = mtk_sdio_probe(rst_data.func, &mtk_sdio_ids[1]); +#else + i4Status = mtk_sdio_probe(rst_data.func, &mtk_sdio_ids[1]); +#endif + if (i4Status) { + DBGLOG(INIT, ERROR, "[RST] mtk_sdio_probe fail num=%d!\n" + , i4Status); + } +#endif + + RSTClearState(); + + DBGLOG(INIT, STATE, "[RST] resetWlanSelf end\n"); +} +void init_wait_CD_start_timer(void) +{ + DBGLOG(INIT, INFO, "[RST] init CD start timer\n"); + init_timer(&wait_CD_start_timer); + wait_CD_start_timer.function = wait_CD_start_timeout; +} + +void start_wait_CD_start_timer(void) +{ + DBGLOG(INIT, LOUD, "[RST] create CD start timer\n"); + + wait_CD_start_timer.expires = jiffies + (WAIT_CD_STAR_TIME * HZ); + wait_CD_start_timer.data = ((unsigned long) 0); + add_timer(&wait_CD_start_timer); +} + +void wait_CD_start_timeout(unsigned long data) +{ + DBGLOG(INIT, ERROR, "[RST] timeout=%d\n", WAIT_CD_STAR_TIME); + DBGLOG(INIT, ERROR, "[RST] g_fgIsCoreDumpStart = %d\n", + g_fgIsCoreDumpStart); + DBGLOG(INIT, ERROR, "[RST] wake up glResetTrigger\n"); + wake_up(&wait_core_dump_start); + set_core_dump_start(TRUE); + g_fgIsBTExist = FALSE; +} + +void init_wait_CD_end_timer(void) +{ + DBGLOG(INIT, INFO, "[RST] init CD end timer\n"); + init_timer(&wait_CD_end_timer); + wait_CD_end_timer.function = wait_CD_end_timeout; +} + +void start_wait_CD_end_timer(void) +{ + DBGLOG(INIT, STATE, "[RST] create CD end timer\n"); + wait_CD_end_timer.expires = jiffies + (WAIT_CD_END_TIME * HZ); + wait_CD_end_timer.data = ((unsigned long) 0); + add_timer(&wait_CD_end_timer); +} +void wait_CD_end_timeout(unsigned long data) +{ + DBGLOG(INIT, ERROR, "[RST] timeout=%ld\n", WAIT_CD_END_TIME); + DBGLOG(INIT, ERROR, "[RST] g_fgIsCoreDumpEnd = %d\n", + g_fgIsCoreDumpEnd); + + if (g_fgIsCoreDumpEnd == FALSE) { + g_fgIsCDEndTimeout = TRUE; + notify_wlan_toggle_rst_end(0); + } +} + +BOOLEAN checkResetState(void) +{ + return (g_fgIsWifiTrig | g_fgIsBTTrig); +} +/*----------------------------------------------------------------------------*/ +/*! +* \brief . +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +VOID set_core_dump_start(BOOLEAN fgVal) +{ + DBGLOG(INIT, ERROR, "[RST] set_core_dump_start = %d\n", fgVal); + g_fgIsCoreDumpStart = fgVal; +} +INT_32 bt_notify_wlan_remove(INT_32 reserved) +{ + if (g_fgIsNotifyWlanRemove) { + DBGLOG(INIT, ERROR, "[RST] g_fgIsNotifyWlanRemove=%d\n", + g_fgIsNotifyWlanRemove); + return NOTIFY_REPEAT; + } + g_fgIsNotifyWlanRemove = TRUE; + DBGLOG(INIT, ERROR, "[RST] bt notify cd start...\n"); + if (g_fgIsWifiTrig) { + DBGLOG(INIT, ERROR, "[RST] wake up glResetTrigger\n"); + set_core_dump_start(TRUE); + wake_up(&wait_core_dump_start); + } else { + g_fgIsBTTrig = TRUE; + g_fgIsBTExist = TRUE; + resetInit(); + set_core_dump_start(TRUE); + schedule_work(&remove_work); + DBGLOG(INIT, ERROR, "[RST] creat remove_work\n"); + } + DBGLOG(INIT, ERROR, "[RST] bt notify cd start end\n"); + return NOTIFY_SUCCESS; + +} + +INT_32 notify_wlan_remove_start(INT_32 reserved) +{ + return bt_notify_wlan_remove(reserved); +} +EXPORT_SYMBOL(notify_wlan_remove_start); +/*----------------------------------------------------------------------------*/ +/*! +* \brief . +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +VOID set_core_dump_end(BOOLEAN fgVal) +{ + DBGLOG(INIT, INFO, "[RST] g_fgIsCoreDumpEnd = %d\n", fgVal); + g_fgIsCoreDumpEnd = fgVal; +} + +INT_32 notify_wlan_toggle_rst_end(INT_32 reserved) +{ + /* create work queue */ + DBGLOG(INIT, STATE, "[RST] bt notify CD end\n"); + set_core_dump_end(TRUE); + schedule_work(&rst_data.rst_work); + DBGLOG(INIT, STATE, "[RST] create probe work\n"); + + /* cencel timer */ + del_timer_sync(&wait_CD_end_timer); + + return NOTIFY_SUCCESS; +} +EXPORT_SYMBOL(notify_wlan_toggle_rst_end); + +INT_32 pmu_toggle(struct rst_struct *data) +{ + UINT_32 pmu_en_delay = MT76x8_PMU_EN_DEFAULT_DELAY; + int pmu_en; + struct device *prDev; + INT_32 i4Status = 0; + + typedef void (*p_sdio_fun_type) (int); + p_sdio_fun_type sdio_func; + /* int btmtk_sdio_notify_wlan_remove_end(void) */ + char *sdio_func_name = "sdio_set_card_clkpd"; + + ASSERT(data); + + /* stop mtk sdio clk */ + sdio_func = (p_sdio_fun_type) kallsyms_lookup_name(sdio_func_name); + if (sdio_func) { + sdio_func(0); + DBGLOG(INIT, STATE, "[RST] stop sdio clk\n"); + } else { + DBGLOG(INIT, ERROR, "[RST] do not get %s\n", sdio_func); + } + + DBGLOG(INIT, STATE, "[RST] get device\n"); + prDev = mmc_dev(data->func->card->host); + if (!prDev) { + DBGLOG(INIT, ERROR, "unable to get struct dev for wlan\n"); + return WLAN_STATUS_FAILURE; + } + + DBGLOG(INIT, STATE, "[RST] pmu reset\n"); + pmu_en = of_get_named_gpio(prDev->of_node, MT76x8_PMU_EN_PIN_NAME, 0); + + if (gpio_is_valid(pmu_en)) { + i4Status = of_property_read_u32(prDev->of_node, + MT76x8_PMU_EN_DELAY_NAME, + &pmu_en_delay); + if (i4Status) { + DBGLOG(INIT, ERROR, + "[RST] undefined pmu_en delay, use default %ums\n", + i4Status); + } + gpio_direction_output(pmu_en, 0); + mdelay(pmu_en_delay); + gpio_direction_output(pmu_en, 1); + } else { + DBGLOG(INIT, ERROR, "[RST] invalid gpio %s\n", + MT76x8_PMU_EN_PIN_NAME); + return WLAN_STATUS_FAILURE; + } + + return WLAN_STATUS_SUCCESS; +} + +void RSTP2pDestroyWirelessDevice(void) +{ + int i = 0; + + for (i = 1; i < KAL_P2P_NUM; i++) { + + if (gprP2pRoleWdev[i] == NULL) + continue; + + DBGLOG(INIT, STATE, + "glP2pDestroyWirelessDevice[%d] (0x%p)\n", + i, gprP2pRoleWdev[i]->wiphy); + set_wiphy_dev(gprP2pRoleWdev[i]->wiphy, NULL); + wiphy_unregister(gprP2pRoleWdev[i]->wiphy); + wiphy_free(gprP2pRoleWdev[i]->wiphy); + kfree(gprP2pRoleWdev[i]); + + gprP2pRoleWdev[i] = NULL; + } + +} + + +#else +BOOLEAN checkResetState(void) +{ + return FALSE; +} +#endif #endif /* CFG_CHIP_RESET_SUPPORT */ /*----------------------------------------------------------------------------*/ diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_wext_priv.c index c759bbca43da..c9ab40e7e5ad 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_wext_priv.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/gl_wext_priv.c @@ -674,6 +674,11 @@ priv_set_int(IN struct net_device *prNetDev, return -EINVAL; prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + /*check if needs handle 32 bit userspace to 64 bit kernel*/ COMPAT_FROMUSER(prIwReqInfo, prIwReqData); @@ -956,6 +961,11 @@ priv_get_int(IN struct net_device *prNetDev, return -EINVAL; prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + /*check if needs handle 32 bit userspace to 64 bit kernel*/ COMPAT_FROMUSER(prIwReqInfo, prIwReqData); @@ -1155,6 +1165,11 @@ priv_set_ints(IN struct net_device *prNetDev, return -EINVAL; prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + /*check if needs handle 32 bit userspace to 64 bit kernel*/ COMPAT_FROMUSER(prIwReqInfo, prIwReqData); @@ -1262,6 +1277,11 @@ priv_get_ints(IN struct net_device *prNetDev, return -EINVAL; prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + /*check if needs handle 32 bit userspace to 64 bit kernel*/ COMPAT_FROMUSER(prIwReqInfo, prIwReqData); @@ -1333,6 +1353,11 @@ priv_set_struct(IN struct net_device *prNetDev, return -EINVAL; prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + /*check if needs handle 32 bit userspace to 64 bit kernel*/ COMPAT_FROMUSER(prIwReqInfo, prIwReqData); @@ -1513,6 +1538,12 @@ priv_get_struct(IN struct net_device *prNetDev, prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); return -EINVAL; } + + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + #if 0 DBGLOG(INIT, INFO, "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", prIwReqInfo->cmd, u4SubCmd); #endif @@ -1857,6 +1888,12 @@ priv_ate_set(IN struct net_device *prNetDev, GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &GlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + + u4SubCmd = (UINT_32) prIwReqData->data.flags; DBGLOG(REQ, INFO, "MT6632 : priv_ate_set u4SubCmd = %d\n", u4SubCmd); @@ -1957,6 +1994,12 @@ priv_set_driver(IN struct net_device *prNetDev, return -EINVAL; } + if (!test_bit(GLUE_FLAG_ADAPT_RDY_BIT, &prGlueInfo->ulFlag)) { + DBGLOG(REQ, INFO, "adapter is not ready\n"); + return -EIO; + } + + /* trick,hack in ./net/wireless/wext-priv.c ioctl_private_iw_point */ /* because the cmd number is odd (get), the input string will not be copy_to_user */ @@ -10801,13 +10844,23 @@ INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN I P_GLUE_INFO_T prGlueInfo = NULL; INT_32 i4BytesWritten = 0; - if (g_u4HaltFlag) { - DBGLOG(REQ, WARN, "wlan is halt, skip priv_driver_cmds\n"); +#if CFG_CHIP_RESET_SUPPORT + if (g_u4HaltFlag || checkResetState()) { + DBGLOG(INIT, WARN, "wlan is halt, skip priv_driver_cmds\n"); return -1; } + rst_data.entry_conut++; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif - if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) + if (GLUE_CHK_PR2(prNetDev, pcCommand) == FALSE) { +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return -1; + } + prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) { @@ -11098,7 +11151,10 @@ INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN I i4BytesWritten++; } } - +#if CFG_CHIP_RESET_SUPPORT + rst_data.entry_conut--; + DBGLOG(INIT, TRACE, "entry_conut = %d\n", rst_data.entry_conut); +#endif return i4BytesWritten; } /* priv_driver_cmds */ diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/hal_api.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/hal_api.c index e64829561a40..10da491675a3 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/hal_api.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/hal_api.c @@ -1880,7 +1880,7 @@ VOID halProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter) if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) { halPrintFirmwareAssertInfo(prAdapter); #if CFG_CHIP_RESET_SUPPORT - glResetTrigger(); + glResetTrigger(prAdapter); #endif } diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/sdio.c b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/sdio.c index 7c25422cb4cf..2e43b8c5d8f9 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/sdio.c +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/hif/sdio/sdio.c @@ -146,7 +146,7 @@ static MTK_WCN_HIF_SDIO_CLTINFO cltInfo = { static int mtk_sdio_pm_suspend(struct device *pDev); static int mtk_sdio_pm_resume(struct device *pDev); -static const struct sdio_device_id mtk_sdio_ids[] = { +const struct sdio_device_id mtk_sdio_ids[] = { { SDIO_DEVICE(0x037a, 0x6602), .driver_data = (kernel_ulong_t)&mt66xx_driver_data_mt6632},/* Not an SDIO standard class device */ { SDIO_DEVICE(0x037a, 0x7608), @@ -325,69 +325,69 @@ static INT_32 mtk_sdio_probe(MTK_WCN_HIF_SDIO_CLTCTX cltCtx, const MTK_WCN_HIF_S return ret; } #else -static int mtk_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) +int mtk_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret = 0; /* int i = 0; */ - - /* printk(KERN_INFO DRV_NAME "mtk_sdio_probe()\n"); */ + DBGLOG(HAL, WARN, "start mtk_sdio_probe\n"); ASSERT(func); ASSERT(id); - /* - *printk(KERN_INFO DRV_NAME "Basic struct size checking...\n"); - *printk(KERN_INFO DRV_NAME "sizeof(struct device) = %d\n", sizeof(struct device)); - *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_host) = %d\n", sizeof(struct mmc_host)); - *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_card) = %d\n", sizeof(struct mmc_card)); - *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_driver) = %d\n", sizeof(struct mmc_driver)); - *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_data) = %d\n", sizeof(struct mmc_data)); - *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_command) = %d\n", sizeof(struct mmc_command)); - *printk(KERN_INFO DRV_NAME "sizeof(struct mmc_request) = %d\n", sizeof(struct mmc_request)); - *printk(KERN_INFO DRV_NAME "sizeof(struct sdio_func) = %d\n", sizeof(struct sdio_func)); - * - *printk(KERN_INFO DRV_NAME "Card information checking...\n"); - *printk(KERN_INFO DRV_NAME "func = 0x%p\n", func); - *printk(KERN_INFO DRV_NAME "Number of info = %d:\n", func->card->num_info); - * - * - *for (i = 0; i < func->card->num_info; i++) - * printk(KERN_INFO DRV_NAME "info[%d]: %s\n", i, func->card->info[i]); - * - */ + +#if 0 + DBGLOG(HAL, WARN, "Basic struct size checking...\n"); + DBGLOG(HAL, WARN, "sizeof(struct device) = %d\n", sizeof(struct device)); + DBGLOG(HAL, WARN, "sizeof(struct mmc_host) = %d\n", sizeof(struct mmc_host)); + DBGLOG(HAL, WARN, "sizeof(struct mmc_card) = %d\n", sizeof(struct mmc_card)); + DBGLOG(HAL, WARN, "sizeof(struct mmc_driver) = %d\n", sizeof(struct mmc_driver)); + DBGLOG(HAL, WARN, "sizeof(struct mmc_data) = %d\n", sizeof(struct mmc_data)); + DBGLOG(HAL, WARN, "sizeof(struct mmc_command) = %d\n", + sizeof(struct mmc_command)); + DBGLOG(HAL, WARN, "sizeof(struct mmc_request) = %d\n", + sizeof(struct mmc_request)); + DBGLOG(HAL, WARN, "sizeof(struct sdio_func) = %d\n", sizeof(struct sdio_func)); + + DBGLOG(HAL, WARN, "Card information checking...\n"); + DBGLOG(HAL, WARN, "func = 0x%p\n", func); + DBGLOG(HAL, WARN, "Number of info = %d:\n", func->card->num_info); + + for (i = 0; i < func->card->num_info; i++) + DBGLOG(HAL, WARN, "info[%d]: %s\n", i, func->card->info[i]); +#endif sdio_claim_host(func); ret = sdio_enable_func(func); sdio_release_host(func); if (ret) { - /* printk(KERN_INFO DRV_NAME"sdio_enable_func failed!\n"); */ + DBGLOG(HAL, ERROR, "sdio_enable_func failed!\n"); goto out; } - /* printk(KERN_INFO DRV_NAME"sdio_enable_func done!\n"); */ + /* DBGLOG(HAL, WARN, "sdio_enable_func done!\n"); */ if (pfWlanProbe((PVOID) func, (PVOID) id->driver_data) != WLAN_STATUS_SUCCESS) { - /* printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); */ + DBGLOG(HAL, ERROR, "pfWlanProbe fail!call pfWlanRemove()\n"); pfWlanRemove(); ret = -1; } out: - /* printk(KERN_INFO DRV_NAME"mtk_sdio_probe() done(%d)\n", ret); */ + DBGLOG(HAL, WARN, "mtk_sdio_probe() done(%d)\n", ret); return ret; } #endif #if MTK_WCN_HIF_SDIO -static INT_32 mtk_sdio_remove(MTK_WCN_HIF_SDIO_CLTCTX cltCtx) +int32_t mtk_sdio_remove(MTK_WCN_HIF_SDIO_CLTCTX cltCtx) { - INT_32 ret = HIF_SDIO_ERR_SUCCESS; + int32_t ret = HIF_SDIO_ERR_SUCCESS; /* printk(KERN_INFO DRV_NAME"pfWlanRemove done\n"); */ pfWlanRemove(); return ret; } #else -static void mtk_sdio_remove(struct sdio_func *func) +void mtk_sdio_remove(struct sdio_func *func) { /* printk(KERN_INFO DRV_NAME"mtk_sdio_remove()\n"); */ @@ -670,7 +670,11 @@ VOID glSetHifInfo(P_GLUE_INFO_T prGlueInfo, ULONG ulCookie) mutex_init(&prHif->rRxFreeBufQueMutex); mutex_init(&prHif->rRxDeAggQueMutex); - +#if CFG_CHIP_RESET_SUPPORT + rst_data.func = prGlueInfo->rHifInfo.func; + mutex_init(&(rst_data.rst_mutex)); + /* DBGLOG(HAL, WARN, "[RST]set rst_data.func = 0x%p\n", rst_data.func); */ +#endif } /* end of glSetHifInfo() */ /*----------------------------------------------------------------------------*/ @@ -915,9 +919,19 @@ BOOL kalDevRegRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT } while (ret); if (ret) { +#if CFG_CHIP_RESET_SUPPORT + P_ADAPTER_T prAdapter = NULL; +#endif kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_readl() reports error: %x retry: %u", ret, ucRetryCount); DBGLOG(HAL, ERROR, "sdio_readl() reports error: %x retry: %u\n", ret, ucRetryCount); +#if CFG_CHIP_RESET_SUPPORT + prAdapter = container_of(&prGlueInfo, ADAPTER_T, prGlueInfo); + prAdapter->fgIsChipNoAck = TRUE; + DBGLOG(HAL, ERROR, "fgIsChipNoAck = %d\n", + prAdapter->fgIsChipNoAck); + glResetTrigger(prAdapter); +#endif } return (ret) ? FALSE : TRUE; @@ -1032,9 +1046,19 @@ BOOL kalDevRegWrite(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_ } while (ret); if (ret) { +#if CFG_CHIP_RESET_SUPPORT + P_ADAPTER_T prAdapter = NULL; +#endif kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_writel() reports error: %x retry: %u", ret, ucRetryCount); DBGLOG(HAL, ERROR, "sdio_writel() reports error: %x retry: %u\n", ret, ucRetryCount); +#if CFG_CHIP_RESET_SUPPORT + prAdapter = container_of(&prGlueInfo, ADAPTER_T, prGlueInfo); + prAdapter->fgIsChipNoAck = TRUE; + DBGLOG(HAL, ERROR, "fgIsChipNoAck = %d\n", + prAdapter->fgIsChipNoAck); + glResetTrigger(prAdapter); +#endif } return (ret) ? FALSE : TRUE; @@ -1198,8 +1222,18 @@ kalDevPortRead(IN P_GLUE_INFO_T prGlueInfo, #endif if (ret) { +#if CFG_CHIP_RESET_SUPPORT + P_ADAPTER_T prAdapter = NULL; +#endif kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_readsb() reports error: %x", ret); DBGLOG(HAL, ERROR, "sdio_readsb() reports error: %x\n", ret); +#if CFG_CHIP_RESET_SUPPORT + prAdapter = container_of(&prGlueInfo, ADAPTER_T, prGlueInfo); + prAdapter->fgIsChipNoAck = TRUE; + DBGLOG(HAL, ERROR, "fgIsChipNoAck = %d\n", + prAdapter->fgIsChipNoAck); + glResetTrigger(prAdapter); +#endif } return (ret) ? FALSE : TRUE; @@ -1296,9 +1330,19 @@ kalDevPortWrite(IN P_GLUE_INFO_T prGlueInfo, #endif if (ret) { +#if CFG_CHIP_RESET_SUPPORT + P_ADAPTER_T prAdapter = NULL; +#endif kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_writesb() reports error: %x", ret); DBGLOG(HAL, ERROR, "sdio_writesb() reports error: %x\n", ret); +#if CFG_CHIP_RESET_SUPPORT + prAdapter = container_of(&prGlueInfo, ADAPTER_T, prGlueInfo); + prAdapter->fgIsChipNoAck = TRUE; + DBGLOG(HAL, ERROR, "fgIsChipNoAck = %d\n", + prAdapter->fgIsChipNoAck); + glResetTrigger(prAdapter); +#endif } return (ret) ? FALSE : TRUE; @@ -1391,8 +1435,18 @@ BOOL kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN #endif if (ret) { +#if CFG_CHIP_RESET_SUPPORT + P_ADAPTER_T prAdapter = container_of(&prGlueInfo, ADAPTER_T, + prGlueInfo); +#endif kalSendAeeWarning(HIF_SDIO_ERR_TITLE_STR, HIF_SDIO_ERR_DESC_STR "sdio_writeb() reports error: %x", ret); DBGLOG(HAL, ERROR, "sdio_writeb() reports error: %x\n", ret); +#if CFG_CHIP_RESET_SUPPORT + prAdapter->fgIsChipNoAck = TRUE; + DBGLOG(HAL, ERROR, "fgIsChipNoAck = %d\n", + prAdapter->fgIsChipNoAck); + glResetTrigger(prAdapter); +#endif } return (ret) ? FALSE : TRUE; diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_os.h index 81ffe312647e..52657494c745 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_os.h +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_os.h @@ -292,6 +292,9 @@ extern const INT_32 mtk_iface_combinations_sta_num; #define GLUE_FLAG_HIF_FW_OWN_BIT (15) #define GLUE_FLAG_HIF_PRT_HIF_DBG_INFO_BIT (16) #endif +#define GLUE_FLAG_ADAPT_RDY BIT(17) + +#define GLUE_FLAG_ADAPT_RDY_BIT (17) #define GLUE_BOW_KFIFO_DEPTH (1024) /* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ @@ -979,6 +982,7 @@ void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo); P_GLUE_INFO_T wlanGetGlueInfo(VOID); +BOOLEAN wlanGetHifState(P_GLUE_INFO_T prGlueInfo); #if KERNEL_VERSION(3, 14, 0) <= LINUX_VERSION_CODE u16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb, void *accel_priv, select_queue_fallback_t fallback); diff --git a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_rst.h index 0fa39607d437..32694ec90b02 100755 --- a/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_rst.h +++ b/drivers/misc/mediatek/connectivity/wlan/gen4-mt7668/os/linux/include/gl_rst.h @@ -71,7 +71,8 @@ ******************************************************************************** */ #include "gl_typedef.h" - +#include <linux/of_gpio.h> +#include <linux/mmc/host.h> /******************************************************************************* * C O N S T A N T S ******************************************************************************** @@ -82,6 +83,15 @@ ******************************************************************************** */ +struct rst_struct { +#ifdef _HIF_SDIO + struct sdio_func *func; + struct work_struct rst_work; +#endif + struct mutex rst_mutex; + int entry_conut; +}; + /******************************************************************************* * E X T E R N A L F U N C T I O N S ******************************************************************************** @@ -91,11 +101,11 @@ * P U B L I C D A T A ******************************************************************************** */ +extern struct rst_struct rst_data; -/******************************************************************************* -* P R I V A T E D A T A -******************************************************************************** -*/ +#ifdef _HIF_SDIO +extern const struct sdio_device_id mtk_sdio_ids[]; +#endif /******************************************************************************* * M A C R O S @@ -106,14 +116,22 @@ * F U N C T I O N D E C L A R A T I O N S ******************************************************************************** */ +#ifdef _HIF_SDIO +extern int sdio_reset_comm(struct mmc_card *card); +#endif + /******************************************************************************* * F U N C T I O N S ******************************************************************************** */ - BOOLEAN kalIsResetting(VOID); +#if CFG_CHIP_RESET_SUPPORT +BOOLEAN checkResetState(void); VOID glResetTrigger(P_ADAPTER_T prAdapter); +#else +#define glResetTrigger(A) +#endif #endif /* _GL_RST_H */ |