wlan: Do SMSM notify at first HDD TX timeout

In case of UDP bi-directional traffic very often DXE descriptors
threshold is reached and some times DMA is unable to transfer the
host space memory to BMU space. Due to out of resources condition
of DXE descriptors data stall happens at TL layer resulting in TX
timeout and eventually leading to crash.

In this change do kick DXE at first TX time out before flushing
firmware BTQMS.

Change-Id: I0f328257d01e768ae4a6732cf19a930559ada554
CRs-Fixed: 945426
diff --git a/CORE/DXE/inc/wlan_qct_dxe.h b/CORE/DXE/inc/wlan_qct_dxe.h
index 91f917c..70c2eb6 100644
--- a/CORE/DXE/inc/wlan_qct_dxe.h
+++ b/CORE/DXE/inc/wlan_qct_dxe.h
@@ -442,6 +442,25 @@
    wpt_uint8      debugFlags
 );
 
+/*==========================================================================
+  @  Function Name
+    WLANDXE_KickDxe
+
+  @  Description
+    Kick Dxe when HDD TX timeout happen
+
+  @  Parameters
+    NONE
+
+  @  Return
+    NONE
+
+===========================================================================*/
+void WLANDXE_KickDxe
+(
+   void
+);
+
 wpt_uint32 WLANDXE_SetupLogTransfer
 (
    wpt_uint64 bufferAddr,
diff --git a/CORE/DXE/src/wlan_qct_dxe.c b/CORE/DXE/src/wlan_qct_dxe.c
index 26f54f5..9467f29 100644
--- a/CORE/DXE/src/wlan_qct_dxe.c
+++ b/CORE/DXE/src/wlan_qct_dxe.c
@@ -3250,13 +3250,15 @@
 {
    wpt_status                  status = eWLAN_PAL_STATUS_SUCCESS;
    WLANDXE_DescCtrlBlkType    *currentCtrlBlk = NULL;
+   WLANDXE_DescCtrlBlkType    *tailCtrlBlk    = NULL;
    WLANDXE_DescType           *currentDesc    = NULL;
    WLANDXE_DescType           *firstDesc      = NULL;
    WLANDXE_DescType           *LastDesc       = NULL;
+   WLANDXE_DescType           *tailDesc       = NULL;
    void                       *sourcePhysicalAddress = NULL;
    wpt_uint32                  xferSize = 0;
    wpt_iterator                iterator;
-   wpt_uint32                  KickDxe = 0;
+   wpt_uint8                   KickDxe   = 0;
 
    HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
             "%s Enter", __func__);
@@ -3270,7 +3272,17 @@
 
    /* Kick DXE when the ring is about to fill */
    if (WLANDXE_TX_LOW_RES_THRESHOLD >= channelEntry->numFreeDesc)
+   {
        KickDxe = 1;
+       tailCtrlBlk = channelEntry->tailCtrlBlk;
+       tailDesc = tailCtrlBlk->linkedDesc;
+
+       if(tailDesc->descCtrl.ctrl& WLANDXE_DESC_CTRL_VALID)
+       {
+          HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
+                   "dxeTXPushFrame Descs threshold reached No DMA");
+       }
+   }
 
    channelEntry->numFragmentCurrentChain = 0;
    currentCtrlBlk = channelEntry->headCtrlBlk;
@@ -5862,6 +5874,29 @@
    return;
 }
 
+/*==========================================================================
+  @  Function Name
+    WLANDXE_KickDxe
+
+  @  Description
+    Kick DXE when HDD TX time out happen
+
+  @  Parameters
+    NONE
+
+  @  Return
+    NONE
+
+===========================================================================*/
+void WLANDXE_KickDxe(void)
+{
+   HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
+               "%s: Kick Dxe for HDD TX timeout",__func__);
+   /* Make wake up HW */
+   dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
+   dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
+}
+
 wpt_uint32 WLANDXE_SetupLogTransfer(wpt_uint64 bufferAddr, wpt_uint32 bufferLen)
 {
    WLANDXE_ChannelCBType    *channelEntry;
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index 0deb0ef..37d479a 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -90,6 +90,7 @@
 #define HDD_TX_STALL_SSR_THRESHOLD        5
 #define HDD_TX_STALL_SSR_THRESHOLD_HIGH   13
 #define HDD_TX_STALL_RECOVERY_THRESHOLD HDD_TX_STALL_SSR_THRESHOLD - 2
+#define HDD_TX_STALL_KICKDXE_THRESHOLD  HDD_TX_STALL_SSR_THRESHOLD - 4
 #define HDD_TX_STALL_FATAL_EVENT_THRESHOLD 2
 #define EAPOL_MASK 0x8013
 #define EAPOL_M1_BIT_MASK 0x8000
@@ -1175,6 +1176,13 @@
       goto print_log;
    }
    if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
+          HDD_TX_STALL_KICKDXE_THRESHOLD)
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
+                "%s: Request Kick DXE for recovery",__func__);
+      WLANTL_TLDebugMessage(WLANTL_DEBUG_KICKDXE);
+   }
+   if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
           HDD_TX_STALL_RECOVERY_THRESHOLD)
    {
       VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index 2831a0d..80975c7 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -609,8 +609,8 @@
 typedef enum
 {
   WLANTL_DEBUG_TX_SNAPSHOT = 1<<0,
-
   WLANTL_DEBUG_FW_CLEANUP = 1<<1,
+  WLANTL_DEBUG_KICKDXE = 1<<2
 }WLANTL_DebugFlags;
 
 /*----------------------------------------------------------------------------
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index 929141c..5396d27 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -7290,6 +7290,19 @@
             return;
         }
    }
+   if(debugFlags & WLANTL_DEBUG_KICKDXE)
+   {
+        vosMsg.reserved = 0;
+        vosMsg.bodyptr  = NULL;
+        vosMsg.type     = WLANTL_TX_KICKDXE;
+
+        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;
 }
 
@@ -9439,6 +9452,10 @@
     vos_fwDumpReq(274, 0, 0, 0, 0, 1); //Async event
     break;
 
+  case WLANTL_TX_KICKDXE:
+    WDA_TransportKickDxe();
+    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 ac0247d..c59067c 100644
--- a/CORE/TL/src/wlan_qct_tli.h
+++ b/CORE/TL/src/wlan_qct_tli.h
@@ -282,6 +282,8 @@
 
   WLANTL_TX_FW_DEBUG = 8,
 
+  WLANTL_TX_KICKDXE = 9,
+
   WLANTL_TX_MAX
 }WLANTL_TxSignalsType;
 
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 87570c2..209c616 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -2089,6 +2089,22 @@
 );
 
 /*==========================================================================
+  FUNCTION   WDA_TransportKickDxe
+
+  DESCRIPTION
+    Request Kick DXE when first hdd TX time out
+    happens
+
+  PARAMETERS
+    NONE
+
+  RETURN VALUE
+    NONE
+
+===========================================================================*/
+void WDA_TransportKickDxe(void);
+
+/*==========================================================================
   FUNCTION   WDA_TrafficStatsTimerActivate
 
   DESCRIPTION
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 68541df..86453c0 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -18832,6 +18832,27 @@
 }
 
 /*==========================================================================
+  FUNCTION   WDA_TransportKickDxe
+
+  DESCRIPTION
+    Request Kick Dxe when first hdd TX time out
+    happens
+
+  PARAMETERS
+    NONE
+
+  RETURN VALUE
+    NONE
+
+===========================================================================*/
+void WDA_TransportKickDxe()
+{
+   WDI_TransportKickDxe();
+   return;
+}
+
+
+/*==========================================================================
   FUNCTION   WDA_SetEnableSSR
 
   DESCRIPTION
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 0d30012..ae5c766 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -11397,6 +11397,16 @@
 );
 
 /**
+ @brief WDI_TransportKickDxe -
+    Request Kick DXE when first HDD TX time out
+    happens
+ @param  none
+ @see
+ @return none
+*/
+void WDI_TransportKickDxe(void);
+
+/**
  @brief WDI_SsrTimerCB
     Callback function for SSR timer, if this is called then the graceful
     shutdown for Riva did not happen.
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index a8d24cb..908f5e2 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -30159,6 +30159,21 @@
    WDTS_ChannelDebug(displaySnapshot, debugFlags);
    return;
 }
+
+/**
+ @brief WDI_TransportKickDxe -
+    Request Kick DXE when HDD TX time out happen
+
+ @param  none
+ @see
+ @return none
+*/
+void WDI_TransportKickDxe()
+{
+   WDTS_ChannelKickDxe();
+   return;
+}
+
 /**
  @brief WDI_SsrTimerCB
     Callback function for SSR timer, if this is called then the graceful
diff --git a/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h b/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h
index b20b7d6..363c946 100644
--- a/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h
+++ b/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h
@@ -137,6 +137,7 @@
                                WDTS_SetPSCbType cBack);
   void (*channelDebug)(wpt_boolean displaySnapshot,
                        wpt_uint8   debugFlags);
+  void (*kickDxe) (void);
   wpt_status (*stop) (void *pContext);
   wpt_status (*close) (void *pContext);
   wpt_uint32 (*getFreeTxDataResNumber) (void *pContext);
@@ -260,6 +261,15 @@
  */
 void WDTS_ChannelDebug(wpt_boolean displaySnapshot, wpt_uint8 debugFlags);
 
+/* DTS Transport Channel Kick Dxe
+ * Request Kick DXE when HDD TX timeout happen
+ *
+ * Parameters  : NONE
+ * Return Value: NONE
+ *
+ */
+void WDTS_ChannelKickDxe(void);
+
 /* DTS Stop function. 
  * Stop Transport driver, ie DXE, SDIO
  * Parameters:
diff --git a/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c b/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
index b88af2c..26b3ab8 100644
--- a/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
+++ b/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c
@@ -58,6 +58,7 @@
   WLANDXE_CompleteTX,
   WLANDXE_SetPowerState,
   WLANDXE_ChannelDebug,
+  WLANDXE_KickDxe,
   WLANDXE_Stop,
   WLANDXE_Close,
   WLANDXE_GetFreeTxDataResNumber,
@@ -1208,6 +1209,19 @@
    return;
 }
 
+/* DTS Transport Channel Kick Dxe
+ * Request Kick DXE when HDD TX time out happen
+ *
+ * Parameters  : NONE
+ * Return Value: NONE
+ *
+ */
+void WDTS_ChannelKickDxe()
+{
+   gTransportDriver.kickDxe();
+   return;
+}
+
 /* DTS Stop function. 
  * Stop Transport driver, ie DXE, SDIO
  * Parameters: