wlan: issue command for recovery if data stall persists

If the kernel queues are stopped for too long, issue
firmware command which will try to recover the low
resource condition in firmware by disconnecting from
devices which are taking up too many resources.

Change-Id: I2dc4d08c180bc8db16c8c1c433277e02f880c70e
CRs-Fixed: 755421
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 18575c4..96e6e32 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1956,7 +1956,7 @@
     hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
     hddLog(LOGE, "%s: called for SAP",__func__);
     hdd_wmm_tx_snapshot(pHostapdAdapter);
-    WLANTL_TLDebugMessage(VOS_TRUE);
+    WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
     return 0;
 }
 
diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index 3741114..dca6c52 100644
--- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -96,6 +96,7 @@
 #define HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ
 #define HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST    1
 #define HDD_SAP_TX_STALL_SSR_THRESHOLD        5
+#define HDD_SAP_TX_STALL_RECOVERY_THRESHOLD HDD_SAP_TX_STALL_SSR_THRESHOLD - 2
 
 static DEFINE_RATELIMIT_STATE(hdd_softap_tx_timeout_rs,                 \
                               HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL,    \
@@ -648,6 +649,13 @@
 
    ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;
 
+   if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
+          HDD_SAP_TX_STALL_RECOVERY_THRESHOLD)
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
+                "%s: Request firmware for recovery",__func__);
+      WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
+   }
    if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
           HDD_SAP_TX_STALL_SSR_THRESHOLD)
    {
@@ -668,7 +676,7 @@
    if (__ratelimit(&hdd_softap_tx_timeout_rs))
    {
       hdd_wmm_tx_snapshot(pAdapter);
-      WLANTL_TLDebugMessage(VOS_TRUE);
+      WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
    }
 
 } 
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index 48d3ad2..653f67d 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -89,6 +89,7 @@
 #define HDD_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ
 #define HDD_TX_TIMEOUT_RATELIMIT_BURST    1
 #define HDD_TX_STALL_SSR_THRESHOLD        5
+#define HDD_TX_STALL_RECOVERY_THRESHOLD HDD_TX_STALL_SSR_THRESHOLD - 2
 
 static DEFINE_RATELIMIT_STATE(hdd_tx_timeout_rs,                 \
                               HDD_TX_TIMEOUT_RATELIMIT_INTERVAL, \
@@ -1083,6 +1084,14 @@
    //update last jiffies after the check
    pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut = jiffies;
 
+   if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
+          HDD_TX_STALL_RECOVERY_THRESHOLD)
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
+                "%s: Request firmware for recovery",__func__);
+      WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
+   }
+
    if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
        HDD_TX_STALL_SSR_THRESHOLD)
    {
@@ -1103,7 +1112,7 @@
    if (__ratelimit(&hdd_tx_timeout_rs))
    {
       hdd_wmm_tx_snapshot(pAdapter);
-      WLANTL_TLDebugMessage(VOS_TRUE);
+      WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
    }
 
 }
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 9453e9f..d81bcb7 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -5828,7 +5828,7 @@
         {
             hddLog(LOGE, "%s: called %d",__func__, sub_cmd);
             hdd_wmm_tx_snapshot(pAdapter);
-            WLANTL_TLDebugMessage(VOS_TRUE);
+            WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
             break;
         }
 
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index e7005ba..bd647c9 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -591,6 +591,13 @@
 #define WLANTL_HS_NUM_CLIENT         2
 #define WLANTL_SINGLE_CLNT_THRESHOLD 4
 
+typedef enum
+{
+  WLANTL_DEBUG_TX_SNAPSHOT = 1<<0,
+
+  WLANTL_DEBUG_FW_CLEANUP = 1<<1,
+}WLANTL_DebugFlags;
+
 /*----------------------------------------------------------------------------
  *   TL callback types
  *--------------------------------------------------------------------------*/
@@ -3156,7 +3163,7 @@
 v_VOID_t
 WLANTL_TLDebugMessage
 (
-  v_BOOL_t displaySnapshot
+  v_U32_t debugFlags
 );
 
 /*==========================================================================
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index a8530aa..ade1a2c 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -7112,13 +7112,13 @@
 v_VOID_t
 WLANTL_TLDebugMessage
 (
- v_BOOL_t   displaySnapshot
+ v_U32_t debugFlags
 )
 {
    vos_msg_t vosMsg;
    VOS_STATUS status;
 
-   if(displaySnapshot)
+   if(debugFlags & WLANTL_DEBUG_TX_SNAPSHOT)
    {
         vosMsg.reserved = 0;
         vosMsg.bodyptr  = NULL;
@@ -7131,6 +7131,19 @@
             return;
         }
    }
+   if (debugFlags & WLANTL_DEBUG_FW_CLEANUP)
+   {
+        vosMsg.reserved = 0;
+        vosMsg.bodyptr  = NULL;
+        vosMsg.type     = WLANTL_TX_FW_DEBUG;
+
+        status = vos_tx_mq_serialize( VOS_MODULE_ID_TL, &vosMsg);
+        if(status != VOS_STATUS_SUCCESS)
+        {
+            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "TX Msg Posting Failed with status: %d",status));
+            return;
+        }
+   }
    return;
 }
 
@@ -9255,6 +9268,10 @@
     WLANTL_FatalErrorHandler(pvosGCtx);
     break;
 
+  case WLANTL_TX_FW_DEBUG:
+    vos_fwDumpReq(274, 0, 0, 0, 0);
+    break;
+
   default:
     /*no processing for now*/
     break;
diff --git a/CORE/TL/src/wlan_qct_tli.h b/CORE/TL/src/wlan_qct_tli.h
index baabbfd..da5f3e4 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -279,6 +279,8 @@
   /* Detected a fatal error issue SSR */
   WLANTL_TX_FATAL_ERROR = 7,
 
+  WLANTL_TX_FW_DEBUG = 8,
+
   WLANTL_TX_MAX
 }WLANTL_TxSignalsType;