[WCNCR00147164] wowlan: add wow UI (enable/AdvPws/mdtim) support

[Description]
Add wowlan UI support: enable/AdvPws/mdtim
    1. Add iwpriv of wow enable, AdvPws, and multiple DTIM
    2. Add wifi.cfg setting of AdvPws, and multiple DTIM
    3. Enlarge WLAN_CFG_ENTRY_NUM_MAX from 128 to 200 due to no empty entry
    4. Add wow UI as link down check in mtk_cfg80211_suspend
    5. Add wow UI as condition to trigger wow command in usb_suspend
    6. Add wow UI as multiple DTIM selection rule

Feature: wowlan
Change-Id: I2ae01cfd04eee0e4b7b9332b5212b4d55b51a1ea
CR-Id: WCNCR00147164
Signed-off-by: Bennett Ou <bennett.ou@mediatek.com>
diff --git a/common/wlan_lib.c b/common/wlan_lib.c
index 7ad5530..eb3e3e3 100644
--- a/common/wlan_lib.c
+++ b/common/wlan_lib.c
@@ -6751,8 +6751,12 @@
 	prWifiVar->ucCalTimingCtrl = (UINT_8) wlanCfgGetUint32(prAdapter, "CalTimingCtrl", 0 /* power on full cal */);
 	prWifiVar->ucWow = (UINT_8) wlanCfgGetUint32(prAdapter, "Wow", FEATURE_DISABLED);
 	prWifiVar->ucOffload = (UINT_8) wlanCfgGetUint32(prAdapter, "Offload", FEATURE_DISABLED);
+	prWifiVar->ucAdvPws = (UINT_8) wlanCfgGetUint32(prAdapter, "AdvPws", FEATURE_ENABLED);
+	prWifiVar->ucWowOnMdtim = (UINT_8) wlanCfgGetUint32(prAdapter, "WowOnMdtim", 1);
+	prWifiVar->ucWowOffMdtim = (UINT_8) wlanCfgGetUint32(prAdapter, "WowOffMdtim", 3);
 
-	prAdapter->rWowCtrl.fgEnable = (UINT_8) wlanCfgGetUint32(prAdapter, "WowEnable", FEATURE_ENABLED);
+#if CFG_WOW_SUPPORT
+	prAdapter->rWowCtrl.fgWowEnable = (UINT_8) wlanCfgGetUint32(prAdapter, "WowEnable", FEATURE_ENABLED);
 	prAdapter->rWowCtrl.ucScenarioId = (UINT_8) wlanCfgGetUint32(prAdapter, "WowScenarioId", 0);
 	prAdapter->rWowCtrl.ucBlockCount = (UINT_8) wlanCfgGetUint32(prAdapter, "WowPinCnt", 1);
 	prAdapter->rWowCtrl.astWakeHif[0].ucWakeupHif =
@@ -6760,6 +6764,7 @@
 	prAdapter->rWowCtrl.astWakeHif[0].ucGpioPin = (UINT_8) wlanCfgGetUint32(prAdapter, "WowGpioPin", 0xFF);
 	prAdapter->rWowCtrl.astWakeHif[0].ucTriggerLvl = (UINT_8) wlanCfgGetUint32(prAdapter, "WowTriigerLevel", 3);
 	prAdapter->rWowCtrl.astWakeHif[0].u4GpioInterval = wlanCfgGetUint32(prAdapter, "GpioInterval", 0);
+#endif
 
 	/* SW Test Mode: Mainly used for Sigma */
 	prWifiVar->u4SwTestMode = (UINT_8) wlanCfgGetUint32(prAdapter, "Sigma", ENUM_SW_TEST_MODE_NONE);
@@ -8703,6 +8708,26 @@
 	rSuspendCmd.ucBssIndex = prNetDevPrivate->ucBssIdx;
 	rSuspendCmd.ucEnableSuspendMode = fgSuspend;
 
+	if (prGlueInfo->prAdapter->rWifiVar.ucWow && prGlueInfo->prAdapter->rWowCtrl.fgWowEnable) {
+		/* cfg enable + wow enable => Wow On mdtim*/
+		rSuspendCmd.ucMdtim = prGlueInfo->prAdapter->rWifiVar.ucWowOnMdtim;
+		DBGLOG(REQ, INFO, "mdtim [1]\n");
+	} else if (prGlueInfo->prAdapter->rWifiVar.ucWow && !prGlueInfo->prAdapter->rWowCtrl.fgWowEnable) {
+		if (prGlueInfo->prAdapter->rWifiVar.ucAdvPws) {
+			/* cfg enable + wow disable + adv pws enable => Wow Off mdtim */
+			rSuspendCmd.ucMdtim = prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim;
+			DBGLOG(REQ, INFO, "mdtim [2]\n");
+		}
+	} else if (!prGlueInfo->prAdapter->rWifiVar.ucWow) {
+		if (prGlueInfo->prAdapter->rWifiVar.ucAdvPws) {
+			/* cfg disable + adv pws enable => MT6632 case => Wow Off mdtim */
+			rSuspendCmd.ucMdtim = prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim;
+			DBGLOG(REQ, INFO, "mdtim [3]\n");
+		}
+	}
+
+    /* When FW receive command, it check connection state to decide apply setting or not */
+
 	rStatus = kalIoctl(prGlueInfo,
 				wlanoidNotifyFwSuspend,
 				(PVOID)&rSuspendCmd,
diff --git a/include/nic/adapter.h b/include/nic/adapter.h
index 568dea6..e0776dd 100644
--- a/include/nic/adapter.h
+++ b/include/nic/adapter.h
@@ -783,6 +783,9 @@
 	UINT_8 ucCalTimingCtrl;
 	UINT_8 ucWow;
 	UINT_8 ucOffload;
+	UINT_8 ucAdvPws; /* enable LP multiple DTIM function, default enable */
+	UINT_8 ucWowOnMdtim; /* multiple DTIM if WOW enable, default 1 */
+	UINT_8 ucWowOffMdtim; /* multiple DTIM if WOW disable, default 3 */
 
 	UINT_8 u4SwTestMode;
 	UINT_8	ucCtrlFlagAssertPath;
diff --git a/include/nic_cmd_event.h b/include/nic_cmd_event.h
index 570e10a..3f25e59 100644
--- a/include/nic_cmd_event.h
+++ b/include/nic_cmd_event.h
@@ -2711,7 +2711,8 @@
 typedef struct _CMD_SUSPEND_MODE_SETTING_T {
 	UINT_8 ucBssIndex;
 	UINT_8 ucEnableSuspendMode;
-	UINT_8 ucReserved1[2];
+	UINT_8 ucMdtim; /* LP parameter */
+	UINT_8 ucReserved1[1];
 	UINT_8 ucReserved2[64];
 } CMD_SUSPEND_MODE_SETTING_T, *P_CMD_SUSPEND_MODE_SETTING_T;
 
diff --git a/include/wlan_lib.h b/include/wlan_lib.h
index 97b2f5d..fad9217 100644
--- a/include/wlan_lib.h
+++ b/include/wlan_lib.h
@@ -127,7 +127,7 @@
 
 #define WLAN_CFG_ARGV_MAX 8
 #define WLAN_CFG_ARGV_MAX_LONG 22 /* for WOW, 2+20 */
-#define WLAN_CFG_ENTRY_NUM_MAX 128
+#define WLAN_CFG_ENTRY_NUM_MAX 200 /* 128 */
 #define WLAN_CFG_KEY_LEN_MAX 32	/* include \x00  EOL */
 #define WLAN_CFG_VALUE_LEN_MAX 32	/* include \x00 EOL */
 #define WLAN_CFG_FLAG_SKIP_CB BIT(0)
@@ -475,7 +475,7 @@
 } WOW_PORT_T, *P_WOW_PORT_T;
 
 typedef struct _WOW_CTRL_T {
-	BOOLEAN fgEnable;	/* Reserved, but not use now */
+	UINT_8 fgWowEnable;	/* 0: disable, 1: wow enable */
 	UINT_8 ucScenarioId;	/* just a profile ID */
 	UINT_8 ucBlockCount;
 	UINT_8 aucReserved1[1];
diff --git a/os/linux/gl_cfg80211.c b/os/linux/gl_cfg80211.c
index 9a6f3fe..d9e4c32 100644
--- a/os/linux/gl_cfg80211.c
+++ b/os/linux/gl_cfg80211.c
@@ -3460,9 +3460,17 @@
 
 	prAdapter = prGlueInfo->prAdapter;
 
-	if (!prAdapter->rWifiVar.ucWow)
-		rStatus = kalIoctl(prGlueInfo, wlanoidLinkDown, NULL, 0, TRUE, FALSE, FALSE,
-				   &u4BufLen);
+	DBGLOG(REQ, WARN, "Wow:%d, WowEnable:%d, state:%d\n",
+		prGlueInfo->prAdapter->rWifiVar.ucWow, prGlueInfo->prAdapter->rWowCtrl.fgWowEnable,
+		kalGetMediaStateIndicated(prGlueInfo));
+
+    /* 1) wifi cfg "Wow" must be true, 2) wow is disable 3) WIfI connected => execute link down flow */
+	if (prGlueInfo->prAdapter->rWifiVar.ucWow && !prGlueInfo->prAdapter->rWowCtrl.fgWowEnable) {
+		if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+			DBGLOG(REQ, WARN, "CFG80211 suspend link down\n");
+			rStatus = kalIoctl(prGlueInfo, wlanoidLinkDown, NULL, 0, TRUE, FALSE, FALSE, &u4BufLen);
+		}
+	}
 
 	if (rStatus != WLAN_STATUS_SUCCESS) {
 		DBGLOG(REQ, WARN, "cfg 80211 suspend fail!\n");
diff --git a/os/linux/gl_proc.c b/os/linux/gl_proc.c
index 9bd89d6..177b297 100644
--- a/os/linux/gl_proc.c
+++ b/os/linux/gl_proc.c
@@ -125,8 +125,8 @@
 static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = {
 	"INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", "SW1", "SW2",
 	"SW3", "SW4", "HEM", "AIS", "RLM", "MEM", "CNM", "RSN", "BSS", "SCN",
-	"SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "OID",
-	"NIC"
+	"SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "PF",
+	"OID", "NIC"
 };
 /* This buffer could be overwrite by any proc commands */
 static UINT_8 g_aucProcBuf[3000];
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index 774425b..f23f802 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -2292,12 +2292,15 @@
 #define CMD_GET_STA_STAT2       "STAT2"
 
 #if CFG_WOW_SUPPORT
+#define CMD_WOW_START			"WOW_START"
 #define CMD_SET_WOW_ENABLE		"SET_WOW_ENABLE"
 #define CMD_SET_WOW_PAR			"SET_WOW_PAR"
 #define CMD_SET_WOW_UDP			"SET_WOW_UDP"
 #define CMD_SET_WOW_TCP			"SET_WOW_TCP"
-#define CMD_GET_WOW_PORT			"GET_WOW_PORT"
+#define CMD_GET_WOW_PORT		"GET_WOW_PORT"
 #endif
+#define CMD_SET_ADV_PWS			"SET_ADV_PWS"
+#define CMD_SET_MDTIM			"SET_MDTIM"
 
 #define CMD_SET_DBDC			"SET_DBDC"
 
@@ -6128,7 +6131,7 @@
 #endif
 
 #if CFG_WOW_SUPPORT
-static int priv_driver_set_wow_enable(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+static int priv_driver_set_wow(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
 {
 	P_GLUE_INFO_T prGlueInfo = NULL;
 	P_WOW_CTRL_T pWOW_CTRL = NULL;
@@ -6149,16 +6152,44 @@
 	if (u4Ret)
 		DBGLOG(REQ, LOUD, "parse bEnable error u4Ret=%d\n", u4Ret);
 
-	pWOW_CTRL->fgEnable = Enable;
+	pWOW_CTRL->fgWowEnable = Enable;
 
-	DBGLOG(INIT, INFO, "CMD set_wow_enable = %d\n", pWOW_CTRL->fgEnable);
+	DBGLOG(INIT, INFO, "CMD set_wow_enable = %d\n", pWOW_CTRL->fgWowEnable);
 	DBGLOG(INIT, INFO, "Scenario ID %d\n", pWOW_CTRL->ucScenarioId);
 	DBGLOG(INIT, INFO, "ucBlockCount %d\n", pWOW_CTRL->ucBlockCount);
 	DBGLOG(INIT, INFO, "interface %d\n", pWOW_CTRL->astWakeHif[0].ucWakeupHif);
 	DBGLOG(INIT, INFO, "gpio_pin %d\n", pWOW_CTRL->astWakeHif[0].ucGpioPin);
 	DBGLOG(INIT, INFO, "gpio_level 0x%x\n", pWOW_CTRL->astWakeHif[0].ucTriggerLvl);
 	DBGLOG(INIT, INFO, "gpio_timer %d\n", pWOW_CTRL->astWakeHif[0].u4GpioInterval);
-	kalWowProcess(prGlueInfo, pWOW_CTRL->fgEnable);
+	kalWowProcess(prGlueInfo, pWOW_CTRL->fgWowEnable);
+
+	return 0;
+}
+
+static int priv_driver_set_wow_enable(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	P_WOW_CTRL_T pWOW_CTRL = NULL;
+	INT_32 i4Argc = 0;
+	PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
+	UINT_32 u4Ret = 0;
+	UINT_8 ucEnable = 0;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+	pWOW_CTRL = &prGlueInfo->prAdapter->rWowCtrl;
+
+	DBGLOG(REQ, LOUD, "command is %s\n", pcCommand);
+	wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
+	DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
+
+	u4Ret = kalkStrtou8(apcArgv[1], 0, &ucEnable);
+
+	if (u4Ret)
+		DBGLOG(REQ, LOUD, "parse bEnable error u4Ret=%d\n", u4Ret);
+
+	pWOW_CTRL->fgWowEnable = ucEnable;
+
+	DBGLOG(PF, INFO, "WOW enable %d\n", pWOW_CTRL->fgWowEnable);
 
 	return 0;
 }
@@ -6250,14 +6281,14 @@
 
 		/* Pick Max */
 		ucCount = ((i4Argc - 2) > MAX_TCP_UDP_PORT) ? MAX_TCP_UDP_PORT : (i4Argc - 2);
-		DBGLOG(REQ, WARN, "UDP ucCount=%d\n", ucCount);
+		DBGLOG(PF, INFO, "UDP ucCount=%d\n", ucCount);
 
 		u4Ret = kalkStrtou8(apcPortArgv[1], 0, &ucVer);
 		if (u4Ret)
 			DBGLOG(REQ, LOUD, "parse ucWakeupHif error u4Ret=%d\n", u4Ret);
 
 		/* IPv4/IPv6 */
-		DBGLOG(REQ, WARN, "ucVer=%d\n", ucVer);
+		DBGLOG(PF, INFO, "ucVer=%d\n", ucVer);
 		if (ucVer == 0) {
 			pWOW_CTRL->stWowPort.ucIPv4UdpPortCnt = ucCount;
 			pausPortArry = pWOW_CTRL->stWowPort.ausIPv4UdpPort;
@@ -6270,10 +6301,10 @@
 		for (ii = 0; ii < ucCount; ii++) {
 			u4Ret = kalkStrtou16(apcPortArgv[ii+2], 0, &u2Port);
 			if (u4Ret)
-				DBGLOG(REQ, ERROR, "parse u2Port error u4Ret=%d\n", u4Ret);
+				DBGLOG(PF, ERROR, "parse u2Port error u4Ret=%d\n", u4Ret);
 
 			pausPortArry[ii] = u2Port;
-			DBGLOG(REQ, WARN, "ucPort=%d, idx=%d\n", u2Port, ii);
+			DBGLOG(PF, INFO, "ucPort=%d, idx=%d\n", u2Port, ii);
 		}
 
 		return 0;
@@ -6319,14 +6350,14 @@
 
 		/* Pick Max */
 		ucCount = ((i4Argc - 2) > MAX_TCP_UDP_PORT) ? MAX_TCP_UDP_PORT : (i4Argc - 2);
-		DBGLOG(REQ, WARN, "TCP ucCount=%d\n", ucCount);
+		DBGLOG(PF, INFO, "TCP ucCount=%d\n", ucCount);
 
 		u4Ret = kalkStrtou8(apcPortArgv[1], 0, &ucVer);
 		if (u4Ret)
 			DBGLOG(REQ, LOUD, "parse ucWakeupHif error u4Ret=%d\n", u4Ret);
 
 		/* IPv4/IPv6 */
-		DBGLOG(REQ, WARN, "Ver=%d\n", ucVer);
+		DBGLOG(PF, INFO, "Ver=%d\n", ucVer);
 		if (ucVer == 0) {
 			pWOW_CTRL->stWowPort.ucIPv4TcpPortCnt = ucCount;
 			pausPortArry = pWOW_CTRL->stWowPort.ausIPv4TcpPort;
@@ -6339,10 +6370,10 @@
 		for (ii = 0; ii < ucCount; ii++) {
 			u4Ret = kalkStrtou16(apcPortArgv[ii+2], 0, &u2Port);
 			if (u4Ret)
-				DBGLOG(REQ, ERROR, "parse u2Port error u4Ret=%d\n", u4Ret);
+				DBGLOG(PF, ERROR, "parse u2Port error u4Ret=%d\n", u4Ret);
 
 			pausPortArry[ii] = u2Port;
-			DBGLOG(REQ, WARN, "ucPort=%d, idx=%d\n", u2Port, ii);
+			DBGLOG(PF, INFO, "ucPort=%d, idx=%d\n", u2Port, ii);
 		}
 
 		return 0;
@@ -6429,10 +6460,10 @@
 
 		/* Dunp Port */
 		for (ii = 0; ii < ucCount; ii++)
-			DBGLOG(REQ, WARN, "ucPort=%d, idx=%d\n", pausPortArry[ii], ii);
+			DBGLOG(PF, INFO, "ucPort=%d, idx=%d\n", pausPortArry[ii], ii);
 
 
-		DBGLOG(REQ, WARN, "[%s/%s] count:%d\n", aucIp[ucVer], aucProto[ucProto], ucCount);
+		DBGLOG(PF, INFO, "[%s/%s] count:%d\n", aucIp[ucVer], aucProto[ucProto], ucCount);
 
 		return 0;
 	} else
@@ -6441,6 +6472,75 @@
 }
 #endif
 
+static int priv_driver_set_adv_pws(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Argc = 0;
+	PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
+	UINT_32 u4Ret = 0;
+	UINT_8 ucAdvPws = 0;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	DBGLOG(REQ, LOUD, "command is %s\n", pcCommand);
+	wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
+	DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
+
+	u4Ret = kalkStrtou8(apcArgv[1], 0, &ucAdvPws);
+
+	if (u4Ret)
+		DBGLOG(REQ, LOUD, "parse bEnable error u4Ret=%d\n", u4Ret);
+
+	prGlueInfo->prAdapter->rWifiVar.ucAdvPws = ucAdvPws;
+
+	DBGLOG(INIT, INFO, "AdvPws:%d\n", &prGlueInfo->prAdapter->rWifiVar.ucAdvPws);
+
+	return 0;
+
+}
+
+static int priv_driver_set_mdtim(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+	P_GLUE_INFO_T prGlueInfo = NULL;
+	INT_32 i4Argc = 0;
+	PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
+	UINT_32 u4Ret = 0;
+	UINT_8 ucMultiDtim = 0, ucVer;
+
+	prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
+
+	DBGLOG(REQ, LOUD, "command is %s\n", pcCommand);
+	wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv);
+	DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc);
+
+	/* iwpriv wlan0 driver "set_mdtim 1 3 */
+	if (i4Argc >= 3) {
+
+		u4Ret = kalkStrtou8(apcArgv[1], 0, &ucVer);
+		if (u4Ret) {
+			DBGLOG(REQ, ERROR, "parse apcArgv1 error u4Ret=%d\n", u4Ret);
+			return -1;
+		}
+
+		u4Ret = kalkStrtou8(apcArgv[2], 0, &ucMultiDtim);
+		if (u4Ret) {
+			DBGLOG(REQ, ERROR, "parse apcArgv2 error u4Ret=%d\n", u4Ret);
+			return -1;
+		}
+
+		if (ucVer == 0) {
+			prGlueInfo->prAdapter->rWifiVar.ucWowOnMdtim = ucMultiDtim;
+			DBGLOG(REQ, INFO, "WOW On MDTIM:%d\n", &prGlueInfo->prAdapter->rWifiVar.ucWowOnMdtim);
+		} else {
+			prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim = ucMultiDtim;
+			DBGLOG(REQ, INFO, "WOW Off MDTIM:%d\n", &prGlueInfo->prAdapter->rWifiVar.ucWowOffMdtim);
+		}
+	}
+
+	return 0;
+
+}
+
 int priv_driver_set_suspend_mode(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
 {
 	P_GLUE_INFO_T prGlueInfo = NULL;
@@ -7141,6 +7241,8 @@
 			i4BytesWritten = priv_driver_set_calbackup_test_drv_fw(prNetDev, pcCommand, i4TotalLen);
 #endif
 #if CFG_WOW_SUPPORT
+		else if (strnicmp(pcCommand, CMD_WOW_START, strlen(CMD_WOW_START)) == 0)
+			i4BytesWritten = priv_driver_set_wow(prNetDev, pcCommand, i4TotalLen);
 		else if (strnicmp(pcCommand, CMD_SET_WOW_ENABLE, strlen(CMD_SET_WOW_ENABLE)) == 0)
 			i4BytesWritten = priv_driver_set_wow_enable(prNetDev, pcCommand, i4TotalLen);
 		else if (strnicmp(pcCommand, CMD_SET_WOW_PAR, strlen(CMD_SET_WOW_PAR)) == 0)
@@ -7152,6 +7254,10 @@
 		else if (strnicmp(pcCommand, CMD_GET_WOW_PORT, strlen(CMD_GET_WOW_PORT)) == 0)
 			i4BytesWritten = priv_driver_get_wow_port(prNetDev, pcCommand, i4TotalLen);
 #endif
+		else if (strnicmp(pcCommand, CMD_SET_ADV_PWS, strlen(CMD_SET_ADV_PWS)) == 0)
+			i4BytesWritten = priv_driver_set_adv_pws(prNetDev, pcCommand, i4TotalLen);
+		else if (strnicmp(pcCommand, CMD_SET_MDTIM, strlen(CMD_SET_MDTIM)) == 0)
+			i4BytesWritten = priv_driver_set_mdtim(prNetDev, pcCommand, i4TotalLen);
 #if CFG_SUPPORT_QA_TOOL
 		else if (strnicmp(pcCommand, CMD_GET_RX_STATISTICS, strlen(CMD_GET_RX_STATISTICS)) == 0)
 			i4BytesWritten = priv_driver_get_rx_statistics(prNetDev, pcCommand, i4TotalLen);
diff --git a/os/linux/hif/usb/usb.c b/os/linux/hif/usb/usb.c
index f5fd468..4a8c049 100644
--- a/os/linux/hif/usb/usb.c
+++ b/os/linux/hif/usb/usb.c
@@ -275,9 +275,14 @@
 
 	DBGLOG(HAL, STATE, "mtk_usb_suspend()\n");
 
-	if (prGlueInfo->prAdapter->rWifiVar.ucWow) {
-		DBGLOG(HAL, EVENT, "enter WOW flow\n");
-		kalWowProcess(prGlueInfo, TRUE);
+	/* 1) wifi cfg "Wow" is true, 2) wow is enable 3) WIfI connected => execute WOW flow */
+	if (prGlueInfo->prAdapter->rWifiVar.ucWow && prGlueInfo->prAdapter->rWowCtrl.fgWowEnable) {
+		if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) {
+			DBGLOG(HAL, EVENT, "enter WOW flow\n");
+			kalWowProcess(prGlueInfo, TRUE);
+		}
+
+		/* else: do nothing, and FW enter LMAC sleep */
 	}
 
 	halUSBPreSuspendCmd(prGlueInfo->prAdapter);