wl1271: Fix recovery mechanism and buffer allocation

Change-Id: I342dbeaeff034403d7f23398411a84996ca3eb08
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wl1271/platforms/hw/linux/SdioAdapter.c b/wl1271/platforms/hw/linux/SdioAdapter.c
index 6abed57..aa223ba 100644
--- a/wl1271/platforms/hw/linux/SdioAdapter.c
+++ b/wl1271/platforms/hw/linux/SdioAdapter.c
@@ -148,7 +148,7 @@
 	}
 	/* Provide the DMA buffer address to the upper layer so it will use it as the transactions host buffer. */
 	if (pTxDmaSrcAddr) { /* Dm: check what to do with it */
-		*pTxDmaSrcAddr = kmalloc(TIWLAN_MMC_MAX_DMA, GFP_ATOMIC | GFP_DMA);
+		*pTxDmaSrcAddr = kmalloc(TIWLAN_MMC_MAX_DMA, GFP_KERNEL | GFP_DMA);
 	}
 	return 0;
 }
@@ -309,7 +309,7 @@
 	/* Allocate a DMA-able buffer and provide it to the upper layer to be used for all read and write transactions */
 	if (pDmaBufAddr == 0) /* allocate only once (in case this function is called multiple times) */
 	{
-		pDmaBufAddr = kmalloc (MAX_BUS_TXN_SIZE, GFP_ATOMIC | GFP_DMA);
+		pDmaBufAddr = kmalloc(MAX_BUS_TXN_SIZE, GFP_KERNEL | GFP_DMA);
 		if (pDmaBufAddr == 0)
 		{
 			iStatus = -1;
diff --git a/wl1271/platforms/os/linux/inc/tracebuf.h b/wl1271/platforms/os/linux/inc/tracebuf.h
index 249b785..441ef1e 100644
--- a/wl1271/platforms/os/linux/inc/tracebuf.h
+++ b/wl1271/platforms/os/linux/inc/tracebuf.h
@@ -40,7 +40,7 @@
 
 #define TB_TRACE_H
 
-#define TB_MALLOC(size) kmalloc(size, GFP_ATOMIC);
+#define TB_MALLOC(size) kmalloc(size, GFP_KERNEL);
 #define TB_FREE         kfree
 #define TB_PRINTF       printk
 #define TB_ID           current->pid
diff --git a/wl1271/platforms/os/linux/inc/wbuf.h b/wl1271/platforms/os/linux/inc/wbuf.h
index 1dbeb1d..4894cd6 100644
--- a/wl1271/platforms/os/linux/inc/wbuf.h
+++ b/wl1271/platforms/os/linux/inc/wbuf.h
@@ -108,9 +108,15 @@
  */
 static inline WBUF *WbufAlloc (TI_HANDLE hOs, TI_UINT32 len)
 {
-     WBUF *pWbuf = alloc_skb (len + WSPI_PAD_BYTES, GFP_ATOMIC);
-     WBUF_DATA (pWbuf) += WSPI_PAD_BYTES;
-     return pWbuf;
+	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
+	WBUF *pWbuf = alloc_skb(len + WSPI_PAD_BYTES, flags);
+
+	if (!pWbuf)
+	{
+		return NULL;
+	}
+	WBUF_DATA (pWbuf) += WSPI_PAD_BYTES;
+	return pWbuf;
 }
 
 #define WbufFree(hOs, pWbuf)		( dev_kfree_skb((struct sk_buff *)pWbuf) )
diff --git a/wl1271/platforms/os/linux/src/RxBuf.c b/wl1271/platforms/os/linux/src/RxBuf.c
index 4a18acf..bda7c10 100644
--- a/wl1271/platforms/os/linux/src/RxBuf.c
+++ b/wl1271/platforms/os/linux/src/RxBuf.c
@@ -51,8 +51,9 @@
 	TI_UINT32 alloc_len = len + WSPI_PAD_BYTES + PAYLOAD_ALIGN_PAD_BYTES + RX_HEAD_LEN_ALIGNED;
 	struct sk_buff *skb;
 	rx_head_t *rx_head;
+	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
 
-	skb = alloc_skb(alloc_len, GFP_ATOMIC);
+	skb = alloc_skb(alloc_len, flags);
 	if (!skb)
 	{
 		return NULL;
diff --git a/wl1271/platforms/os/linux/src/osmemapi.c b/wl1271/platforms/os/linux/src/osmemapi.c
index 85a7753..e71d303 100644
--- a/wl1271/platforms/os/linux/src/osmemapi.c
+++ b/wl1271/platforms/os/linux/src/osmemapi.c
@@ -99,6 +99,7 @@
 {
 	struct os_mem_block *blk;
 	__u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
+	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
 
 #ifdef TI_MEM_ALLOC_TRACE
 	os_printf("MTT:%s:%d ::os_memoryAlloc(0x%p, %lu) : %lu\n",__FUNCTION__, __LINE__,OsContext,Size,total_size);
@@ -115,14 +116,7 @@
 	if (total_size < 2 * 4096)
 #endif
 	{
-		if (in_atomic())
-		{
-			blk = kmalloc(total_size, GFP_ATOMIC);
-		}
-		else
-		{
-			blk = kmalloc(total_size, GFP_KERNEL);
-		}
+		blk = kmalloc(total_size, flags);
 		if (!blk)
 		{
 			printk("%s: NULL\n",__func__);	
@@ -303,13 +297,15 @@
 {
 	struct os_mem_block *blk;
 	__u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
+	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
+
 	/* 
 	if the size is greater than 2 pages then we cant allocate the memory
 	    through kmalloc so the function fails
 	*/
 	if (Size < 2 * OS_PAGE_SIZE)
 	{
-		blk = kmalloc(total_size, GFP_ATOMIC|GFP_DMA);
+		blk = kmalloc(total_size, flags | GFP_DMA);
 		if (!blk) {
 			printk("%s: NULL\n",__func__);
 			return NULL;
diff --git a/wl1271/stad/src/Ctrl_Interface/DrvMain.c b/wl1271/stad/src/Ctrl_Interface/DrvMain.c
index a19af48..1838493 100644
--- a/wl1271/stad/src/Ctrl_Interface/DrvMain.c
+++ b/wl1271/stad/src/Ctrl_Interface/DrvMain.c
@@ -1432,9 +1432,10 @@
     TI_STATUS    eStatus    = TI_NOK;
     TI_HANDLE    hOs        = pDrvMain->tStadHandles.hOs;
     TI_UINT32    uSdioConIndex = 0;
+    TI_BOOL      tmpRecovery;
 
     TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_INFORMATION , "drvMain_Sm():  State = %d, Event = %d\n", pDrvMain->eSmState, eEvent);
-    
+
     /* 
      *  General explenations:
      *  =====================
@@ -1495,7 +1496,7 @@
 			/* : We should split the call to txnQ_ConnectBus to other state in order to support Async bus connection */
             eStatus = txnQ_ConnectBus(pDrvMain->tStadHandles.hTxnQ, &pDrvMain->tBusDrvCfg, NULL, NULL, &pDrvMain->uRxDmaBufLen, &pDrvMain->uTxDmaBufLen); 
 
-			if((eStatus != TI_OK) &&
+            if((eStatus != TI_OK) &&
 			   (uSdioConIndex < (SDIO_CONNECT_THRESHOLD - 1)))
             {
                      TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_WARNING , "SDBus Connect Failed\n");
@@ -1508,22 +1509,22 @@
             }
         }
 
-		if(eStatus != TI_OK)
-		{
+        if(eStatus != TI_OK)
+        {
 			WLAN_OS_REPORT(("SDBus Connect Failed, Set Object Event !!\r\n"));
 			TRACE0(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "SDBus Connect Failed, Set Object Event !!\r\n");
 			if (!pDrvMain->bRecovery)
 			{
 				os_SignalObjectSet(hOs, pDrvMain->hSignalObj);
 			}
-		}
-		else /* SDBus Connect success */
+        }
+        else /* SDBus Connect success */
         {
             /*
              * We've got the NVS file.
              * Start HW-Init process providing the NVS file.
              */
-			if (eEvent == SM_EVENT_NVS_FILE_READY)
+            if (eEvent == SM_EVENT_NVS_FILE_READY)
             {
                 pDrvMain->eSmState = SM_STATE_HW_INIT;
                 eStatus = drvMain_InitHw (hDrvMain, pDrvMain->tFileInfo.pBuffer, pDrvMain->tFileInfo.uLength);
@@ -1600,13 +1601,14 @@
          * Enable STOP action
          * We are now in OPERATIONAL state, i.e. the driver is fully operational!
          */
-      
+
+        tmpRecovery = pDrvMain->bRecovery;
         if (eEvent == SM_EVENT_FW_CONFIG_COMPLETE) 
         {
             pDrvMain->eSmState = SM_STATE_OPERATIONAL;
             if (pDrvMain->bRecovery) 
             {
-				pDrvMain->uNumOfRecoveryAttempts = 0;
+                pDrvMain->uNumOfRecoveryAttempts = 0;
                 drvMain_RecoveryNotify (pDrvMain);
                 pDrvMain->bRecovery = TI_FALSE;
             }
@@ -1621,7 +1623,7 @@
             eStatus = TI_OK;
            
         }
-        if (!pDrvMain->bRecovery)
+        if (!tmpRecovery)
         {
             os_SignalObjectSet(hOs, pDrvMain->hSignalObj);
         }
@@ -1723,21 +1725,22 @@
         pDrvMain->eSmState = SM_STATE_FAILED;
         txnQ_DisconnectBus (pDrvMain->tStadHandles.hTxnQ);
         hPlatform_DevicePowerOff ();
-        WLAN_OS_REPORT(("[WLAN] Exit application\n"));
-        if (!pDrvMain->bRecovery) 
+        if (!pDrvMain->bRecovery)
         {
             os_SignalObjectSet (hOs, pDrvMain->hSignalObj);
-		}
-		else if (pDrvMain->uNumOfRecoveryAttempts < MAX_NUM_OF_RECOVERY_TRIGGERS) 
-		{
-			pDrvMain->eSmState = SM_STATE_STOPPING;
-			eStatus = drvMain_StopActivities (pDrvMain);
-		}
+        }
+        else if (pDrvMain->uNumOfRecoveryAttempts < MAX_NUM_OF_RECOVERY_TRIGGERS) 
+        {
+            pDrvMain->eSmState = SM_STATE_STOPPING;
+            eStatus = drvMain_StopActivities (pDrvMain);
+        }
+        WLAN_OS_REPORT(("[WLAN] Exit application\n"));
+        pDrvMain->bRecovery = TI_FALSE;
         break;
     case SM_STATE_FAILED:
         /* Nothing to do except waiting for Destroy */
         break;
- default:
+    default:
         TRACE2(pDrvMain->tStadHandles.hReport, REPORT_SEVERITY_ERROR , "drvMain_Sm: Unknown state, eEvent=%u at state=%u\n", eEvent, pDrvMain->eSmState);
         /* Note: Handled below as a failure since the status remains TI_NOK */
         break;