[DTV00890206] wowlan: support the way to get wakeup reason between magic packet and Cast
[Description]
Add FW event handler to receive the wakeup reason
Add iwpriv command to provide framework to get the wakeup reason
Change-Id: I4e766dad16a0245b44445eb11b811e8c03021ece
Signed-off-by: Evelyn Tasi <evelyn.tsai@mediatek.com>
CR-Id: DTV00890206
Feature: wowlan
Signed-off-by: Evelyn <evelyn.tsai@mediatek.com>
diff --git a/include/nic_cmd_event.h b/include/nic_cmd_event.h
index 9c6cd73..fbacc11 100644
--- a/include/nic_cmd_event.h
+++ b/include/nic_cmd_event.h
@@ -628,6 +628,10 @@
EVENT_ID_CSA_DONE = 0x61,
#endif
+#if (CFG_WOW_SUPPORT == 1)
+ EVENT_ID_WOW_WAKEUP_REASON = 0x62,
+#endif
+
EVENT_ID_TDLS = 0x80, /* TDLS event_id */
EVENT_ID_UPDATE_COEX_PHYRATE = 0x90, /* 0x90 (Unsolicited) */
@@ -2325,6 +2329,14 @@
} EVENT_RDD_REPORT_T, *P_EVENT_RDD_REPORT_T;
#endif
+#if (CFG_WOW_SUPPORT == 1)
+/* event of wake up reason */
+struct _EVENT_WAKEUP_REASON_INFO {
+ UINT_8 reason;
+ UINT_8 aucReserved[3];
+};
+#endif
+
typedef struct _EVENT_BSS_BEACON_TIMEOUT_T {
UINT_8 ucBssIndex;
UINT_8 ucReasonCode;
@@ -3165,7 +3177,9 @@
VOID nicEventHifCtrl(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
VOID nicEventRddSendPulse(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
VOID nicEventUpdateCoexPhyrate(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
-
+#if (CFG_WOW_SUPPORT == 1)
+VOID nicEventWakeUpReason(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent);
+#endif
/*******************************************************************************
* F U N C T I O N S
********************************************************************************
diff --git a/include/wlan_lib.h b/include/wlan_lib.h
index a5741d4..96d6516 100644
--- a/include/wlan_lib.h
+++ b/include/wlan_lib.h
@@ -199,6 +199,10 @@
#define ACS_DIRTINESS_LEVEL_LOW 32
#endif
+#if CFG_WOW_SUPPORT
+#define INVALID_WOW_WAKE_UP_REASON 255
+#endif
+
typedef enum _CMD_VER_T {
CMD_VER_1, /* Type[2]+String[32]+Value[32] */
@@ -483,6 +487,7 @@
UINT_8 aucReserved1[1];
WOW_WAKE_HIF_T astWakeHif[2];
WOW_PORT_T stWowPort;
+ UINT_8 ucReason;
} WOW_CTRL_T, *P_WOW_CTRL_T;
#endif
diff --git a/nic/nic_cmd_event.c b/nic/nic_cmd_event.c
index 178f8c1..7ec02f2 100644
--- a/nic/nic_cmd_event.c
+++ b/nic/nic_cmd_event.c
@@ -3289,3 +3289,34 @@
}
}
+#if (CFG_WOW_SUPPORT == 1)
+VOID nicEventWakeUpReason(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent)
+{
+ struct _EVENT_WAKEUP_REASON_INFO *prWakeUpReason;
+ P_GLUE_INFO_T prGlueInfo;
+
+ DBGLOG(NIC, INFO, "nicEventWakeUpReason\n");
+ prGlueInfo = prAdapter->prGlueInfo;
+
+ /* Driver receives EVENT_ID_WOW_WAKEUP_REASON after firmware wake up host
+ * The possible Wakeup Reason define in FW as following
+ * 0: MAGIC PACKET
+ * 1: BITMAP
+ * 2: ARPNS
+ * 3: GTK_REKEY
+ * 4: COALESCING_FILTER
+ * 5: HW_GLOBAL_ENABLE
+ * 6: TCP_SYN PACKET
+ * 7: TDLS
+ * 8: DISCONNECT
+ * 9: IPV4_UDP PACKET
+ * 10: IPV4_TCP PACKET
+ * 11: IPV6_UDP PACKET
+ * 12: IPV6_TCP PACKET
+ */
+ prWakeUpReason = (struct _EVENT_WAKEUP_REASON_INFO *) (prEvent->aucBuffer);
+ prGlueInfo->prAdapter->rWowCtrl.ucReason = prWakeUpReason->reason;
+ DBGLOG(NIC, INFO, "nicEventWakeUpReason:%d\n", prGlueInfo->prAdapter->rWowCtrl.ucReason);
+}
+#endif
+
diff --git a/nic/nic_rx.c b/nic/nic_rx.c
index f48c29a..a2fab39 100644
--- a/nic/nic_rx.c
+++ b/nic/nic_rx.c
@@ -181,6 +181,10 @@
#else
{EVENT_ID_UPDATE_COEX_PHYRATE, nicEventUpdateCoexPhyrate},
#endif
+#if (CFG_WOW_SUPPORT == 1)
+ {EVENT_ID_WOW_WAKEUP_REASON, nicEventWakeUpReason},
+#endif
+
};
/*******************************************************************************
diff --git a/os/linux/gl_kal.c b/os/linux/gl_kal.c
index 95b2a82..05a2cb5 100644
--- a/os/linux/gl_kal.c
+++ b/os/linux/gl_kal.c
@@ -4983,6 +4983,7 @@
VOID kalWowInit(IN P_GLUE_INFO_T prGlueInfo)
{
kalMemZero(&prGlueInfo->prAdapter->rWowCtrl.stWowPort, sizeof(WOW_PORT_T));
+ prGlueInfo->prAdapter->rWowCtrl.ucReason = INVALID_WOW_WAKE_UP_REASON;
}
VOID kalWowCmdEventSetCb(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf)
@@ -5055,6 +5056,7 @@
wlanSetSuspendMode(prGlueInfo, enable);
/* p2pSetSuspendMode(prGlueInfo, TRUE); */
+ pWOW_CTRL->ucReason = INVALID_WOW_WAKE_UP_REASON;
/* Let WOW enable/disable as last command, so we can back/restore DMA classify filter in FW */
rCmdWowlanParam.ucScenarioID = pWOW_CTRL->ucScenarioId;
rCmdWowlanParam.ucBlockCount = pWOW_CTRL->ucBlockCount;
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index ab6fecf..6aeb404 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -2330,6 +2330,7 @@
#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_REASON "GET_WOW_REASON"
#endif
#define CMD_SET_ADV_PWS "SET_ADV_PWS"
#define CMD_SET_MDTIM "SET_MDTIM"
@@ -7826,6 +7827,28 @@
return -1;
}
+
+static int priv_driver_get_wow_reason(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+ P_GLUE_INFO_T prGlueInfo = NULL;
+ INT_32 i4Argc = 0;
+ INT_32 i4BytesWritten = 0;
+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 };
+ P_WOW_CTRL_T pWOW_CTRL = NULL;
+
+ ASSERT(prNetDev);
+ 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);
+
+ if (pWOW_CTRL->ucReason != INVALID_WOW_WAKE_UP_REASON)
+ LOGBUF(pcCommand, i4TotalLen, i4BytesWritten, "\nwakeup_reason:%d", pWOW_CTRL->ucReason);
+
+ return i4BytesWritten;
+}
#endif
static int priv_driver_set_adv_pws(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
@@ -9627,6 +9650,8 @@
i4BytesWritten = priv_driver_set_wow_tcpport(prNetDev, pcCommand, i4TotalLen);
else if (strnicmp(pcCommand, CMD_GET_WOW_PORT, strlen(CMD_GET_WOW_PORT)) == 0)
i4BytesWritten = priv_driver_get_wow_port(prNetDev, pcCommand, i4TotalLen);
+ else if (strnicmp(pcCommand, CMD_GET_WOW_REASON, strlen(CMD_GET_WOW_REASON)) == 0)
+ i4BytesWritten = priv_driver_get_wow_reason(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);