Pre-allocate memory for wifi driver

Bug: 20223541

Change-Id: I66024f69122e2e51bdd1c94411ad2588b20df481
diff --git a/arch/arm/configs/tetra_defconfig b/arch/arm/configs/tetra_defconfig
index b309d94..6e76ad6 100644
--- a/arch/arm/configs/tetra_defconfig
+++ b/arch/arm/configs/tetra_defconfig
@@ -288,6 +288,7 @@
 CONFIG_USB_USBNET=y
 CONFIG_WIFI_CONTROL_FUNC=y
 CONFIG_BRCM_UNIFIED_DHD_SUPPORT=y
+CONFIG_CONFIG_DHD_USE_STATIC_BUF=y
 CONFIG_BROADCOM_WIFI_RESERVED_MEM=y
 CONFIG_TARGET_LOCALE_CHN=y
 CONFIG_BCMDHD=y
diff --git a/arch/arm/mach-java/java_wifi.c b/arch/arm/mach-java/java_wifi.c
index 7fe8a37..b8c3d92 100644
--- a/arch/arm/mach-java/java_wifi.c
+++ b/arch/arm/mach-java/java_wifi.c
@@ -380,6 +380,13 @@
 
 #define WLAN_STATIC_SCAN_BUF0		5
 #define WLAN_STATIC_SCAN_BUF1		6
+#define WLAN_STATIC_DHD_WLFC_INFO	8
+#define WLAN_STATIC_DHD_WLFC_HANGER	12
+
+#define WLAN_SCAN_BUF_SIZE		(64 * 1024)
+#define WLAN_STATIC_DHD_WLFC_INFO_SIZE		(24 * 1024)
+#define WLAN_STATIC_DHD_WLFC_HANGER_SIZE	(64 * 1024)
+
 #define PREALLOC_WLAN_SEC_NUM		4
 #define PREALLOC_WLAN_BUF_NUM		160
 #define PREALLOC_WLAN_SECTION_HEADER	24
@@ -407,8 +414,10 @@
 	{NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
 };
 
-void *wlan_static_scan_buf0;
-void *wlan_static_scan_buf1;
+void *wlan_static_scan_buf0 = NULL;
+void *wlan_static_scan_buf1 = NULL;
+void *wlan_static_dhd_wlfc_info = NULL;
+void *wlan_static_dhd_wlfc_hanger = NULL;
 
 static void *hawaii_wifi_mem_prealloc(int section, unsigned long size)
 {
@@ -418,6 +427,27 @@
 		return wlan_static_scan_buf0;
 	if (section == WLAN_STATIC_SCAN_BUF1)
 		return wlan_static_scan_buf1;
+
+	if (section == WLAN_STATIC_DHD_WLFC_INFO)  {
+		if (size > WLAN_STATIC_DHD_WLFC_INFO_SIZE) {
+			pr_err("request DHD_WLFC_INFO size(%lu) is bigger than"
+				" static size(%d).\n",
+				size, WLAN_STATIC_DHD_WLFC_INFO_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_wlfc_info;
+	}
+
+	if (section == WLAN_STATIC_DHD_WLFC_HANGER)  {
+		if (size > WLAN_STATIC_DHD_WLFC_HANGER_SIZE) {
+			pr_err("request DHD_WLFC_HANGER size(%lu) is bigger than"
+				" static size(%d).\n",
+				size, WLAN_STATIC_DHD_WLFC_HANGER_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_wlfc_hanger;
+	}
+
 	if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM))
 		return NULL;
 
@@ -455,18 +485,50 @@
 		if (!wlan_mem_array[i].mem_ptr)
 			goto err_mem_alloc;
 	}
-	wlan_static_scan_buf0 = kmalloc(65536, GFP_KERNEL);
-	if (!wlan_static_scan_buf0)
+	wlan_static_scan_buf0 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+	if (!wlan_static_scan_buf0) {
+		pr_err("Failed to alloc wlan_static_scan_buf0\n");
 		goto err_mem_alloc;
-	wlan_static_scan_buf1 = kmalloc(65536, GFP_KERNEL);
-	if (!wlan_static_scan_buf1)
-		goto err_mem_alloc;
+	}
 
-	printk(KERN_ERR "%s: WIFI MEM Allocated\n", __func__);
+	wlan_static_scan_buf1 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+	if (!wlan_static_scan_buf1) {
+		pr_err("Failed to alloc wlan_static_scan_buf1\n");
+		goto err_mem_alloc;
+	}
+
+	wlan_static_dhd_wlfc_info = kmalloc(WLAN_STATIC_DHD_WLFC_INFO_SIZE,
+			GFP_KERNEL);
+	if (!wlan_static_dhd_wlfc_info) {
+		pr_err("Failed to alloc wlan_static_dhd_wlfc_info\n");
+		goto err_mem_alloc;
+	}
+
+	wlan_static_dhd_wlfc_hanger = kmalloc(WLAN_STATIC_DHD_WLFC_HANGER_SIZE,
+		GFP_KERNEL);
+	if (!wlan_static_dhd_wlfc_hanger) {
+		pr_err("Failed to alloc wlan_static_dhd_wlfc_hanger\n");
+		goto err_mem_alloc;
+	}
+
+	pr_err("%s: WIFI MEM Allocated\n", __FUNCTION__);
 	return 0;
 
 err_mem_alloc:
+	if (wlan_static_dhd_wlfc_info)
+		kfree(wlan_static_dhd_wlfc_info);
+
+	if (wlan_static_dhd_wlfc_hanger)
+		kfree(wlan_static_dhd_wlfc_hanger);
+
+	if (wlan_static_scan_buf1)
+		kfree(wlan_static_scan_buf1);
+
+	if (wlan_static_scan_buf0)
+		kfree(wlan_static_scan_buf0);
+
 	pr_err("Failed to mem_alloc for WLAN\n");
+
 	for (j = 0; j < i; j++)
 		kfree(wlan_mem_array[j].mem_ptr);
 
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index f182f04..7a4168e 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -159,7 +159,9 @@
 #if defined(STATIC_WL_PRIV_STRUCT)
 	DHD_PREALLOC_WIPHY_ESCAN0 = 5,
 #endif /* STATIC_WL_PRIV_STRUCT */
-	DHD_PREALLOC_DHD_INFO = 7
+	DHD_PREALLOC_DHD_INFO = 7,
+	DHD_PREALLOC_DHD_WLFC_INFO = 8,
+	DHD_PREALLOC_DHD_WLFC_HANGER = 12
 };
 
 typedef enum  {
diff --git a/drivers/net/wireless/bcmdhd/dhd_wlfc.c b/drivers/net/wireless/bcmdhd/dhd_wlfc.c
index 043bd88..cd6859f 100755
--- a/drivers/net/wireless/bcmdhd/dhd_wlfc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_wlfc.c
@@ -319,7 +319,7 @@
 	hang-er: noun, a contrivance on which things are hung, as a hook.
 */
 static void*
-dhd_wlfc_hanger_create(osl_t *osh, int max_items)
+dhd_wlfc_hanger_create(dhd_pub_t *dhd, int max_items)
 {
 	int i;
 	wlfc_hanger_t* hanger;
@@ -327,9 +327,10 @@
 	/* allow only up to a specific size for now */
 	ASSERT(max_items == WLFC_HANGER_MAXITEMS);
 
-	if ((hanger = (wlfc_hanger_t*)MALLOC(osh, WLFC_HANGER_SIZE(max_items))) == NULL)
+	if ((hanger = (wlfc_hanger_t*)DHD_OS_PREALLOC(dhd, DHD_PREALLOC_DHD_WLFC_HANGER,
+		WLFC_HANGER_SIZE(max_items))) == NULL) {
 		return NULL;
-
+	}
 	memset(hanger, 0, WLFC_HANGER_SIZE(max_items));
 	hanger->max_items = max_items;
 
@@ -340,12 +341,12 @@
 }
 
 static int
-dhd_wlfc_hanger_delete(osl_t *osh, void* hanger)
+dhd_wlfc_hanger_delete(dhd_pub_t *dhd, void* hanger)
 {
 	wlfc_hanger_t* h = (wlfc_hanger_t*)hanger;
 
 	if (h) {
-		MFREE(osh, h, WLFC_HANGER_SIZE(h->max_items));
+		DHD_OS_PREFREE(dhd, h, WLFC_HANGER_SIZE(h->max_items));
 		return BCME_OK;
 	}
 	return BCME_BADARG;
@@ -2293,7 +2294,8 @@
 		return BCME_OK;
 
 	/* allocate space to track txstatus propagated from firmware */
-	dhd->wlfc_state = MALLOC(dhd->osh, sizeof(athost_wl_status_info_t));
+	dhd->wlfc_state = DHD_OS_PREALLOC(dhd, DHD_PREALLOC_DHD_WLFC_INFO,
+		sizeof(athost_wl_status_info_t));
 	if (dhd->wlfc_state == NULL)
 		return BCME_NOMEM;
 
@@ -2306,9 +2308,10 @@
 	wlfc->dhdp = dhd;
 
 	wlfc->hanger =
-		dhd_wlfc_hanger_create(dhd->osh, WLFC_HANGER_MAXITEMS);
+		dhd_wlfc_hanger_create(dhd, WLFC_HANGER_MAXITEMS);
 	if (wlfc->hanger == NULL) {
-		MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t));
+		DHD_OS_PREFREE(dhd, dhd->wlfc_state,
+			sizeof(athost_wl_status_info_t));
 		dhd->wlfc_state = NULL;
 		DHD_ERROR(("Failed to malloc dhd->wlfc_state\n"));
 		return BCME_NOMEM;
@@ -2490,10 +2493,11 @@
 	}
 #endif
 	/* delete hanger */
-	dhd_wlfc_hanger_delete(dhd->osh, wlfc->hanger);
+	dhd_wlfc_hanger_delete(dhd, wlfc->hanger);
 
 	/* free top structure */
-	MFREE(dhd->osh, dhd->wlfc_state, sizeof(athost_wl_status_info_t));
+	DHD_OS_PREFREE(dhd, dhd->wlfc_state,
+		sizeof(athost_wl_status_info_t));
 	dhd->wlfc_state = NULL;
 	dhd_os_wlfc_unblock(dhd);