bcmdhd : Remove VFS dependency on 43752 driver

Removed VFS dependency because of GKI requirements

Bug: 182959271
Test: verified on slider + 43752 and it is able to connect AP.

Change-Id: I6540024056027fcf89dd83bc2a1782d09ca2d861
Signed-off-by: daniel oh <daniel.oh@broadcom.corp-partner.google.com>
Signed-off-by: Roger Wang <wangroger@google.com>
diff --git a/Kbuild b/Kbuild
index f8c0769..02eeb01 100755
--- a/Kbuild
+++ b/Kbuild
@@ -796,6 +796,12 @@
 ifneq ($(filter y, $(CONFIG_SOC_GS101) $(CONFIG_SOC_EXYNOS9820)),)
   DHDCFLAGS += -DCONFIG_ARCH_EXYNOS
   DHDCFLAGS += -DBCMPCIE_DISABLE_ASYNC_SUSPEND
+  DHDCFLAGS += -DDHD_LINUX_STD_FW_API
+  DHDCFLAGS += -DDHD_FW_NAME="\"fw_bcm43752.bin\""
+  DHDCFLAGS += -DDHD_NVRAM_NAME="\"bcmdhd_43752.cal\""
+  DHDCFLAGS += -DDHD_NVRAM_USI_NAME="\"bcmdhd_43752_usi.cal\""
+  DHDCFLAGS += -DDHD_CLM_NAME="\"bcmdhd_clm_43752.blob\""
+  DHDCFLAGS += -DDHD_MAP_NAME="\"rtecdc_43752.map\""
 endif
 
 EXTRA_CFLAGS += $(DHDCFLAGS) -DDHD_DEBUG
diff --git a/dhd.h b/dhd.h
index 3b69026..83a0260 100755
--- a/dhd.h
+++ b/dhd.h
@@ -33,6 +33,7 @@
 #ifndef _dhd_h_
 #define _dhd_h_
 
+#include <linux/firmware.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -45,6 +46,8 @@
 #include <linux/proc_fs.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
 #include <linux/sched/types.h>
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
@@ -866,7 +869,7 @@
 #ifdef PLATFORM_PATH
 #define DHD_COMMON_DUMP_PATH	PLATFORM_PATH
 #else
-#define DHD_COMMON_DUMP_PATH	"/vendor/etc/wifi/
+#define DHD_COMMON_DUMP_PATH	"/vendor/etc/wifi/"
 #endif /* PLATFORM_PATH*/
 
 struct cntry_locales_custom {
@@ -2171,6 +2174,11 @@
 void dhd_schedule_edl_work(dhd_pub_t *dhdp, uint delay_ms);
 #endif /* EWP_EDL */
 
+#if defined(linux) || defined(LINUX)
+int dhd_os_get_img_fwreq(dhd_pub_t *dhd, const struct firmware **fw, char *file_path);
+void dhd_os_close_img_fwreq(const struct firmware *fw);
+#endif /* linux || LINUX */
+
 #ifdef PKT_FILTER_SUPPORT
 #define DHD_UNICAST_FILTER_NUM		0
 #define DHD_BROADCAST_FILTER_NUM	1
@@ -3686,4 +3694,73 @@
 } wifi_alert_reason_codes_t;
 int dhd_os_send_alert_message(dhd_pub_t *dhdp);
 #endif
+
+#if defined(__linux__)
+#ifdef DHD_SUPPORT_VFS_CALL
+static INLINE struct file *dhd_filp_open(const char *filename, int flags, int mode)
+{
+	return filp_open(filename, flags, mode);
+}
+
+static INLINE int dhd_filp_close(void *image, void *id)
+{
+	return filp_close((struct file *)image, id);
+}
+
+static INLINE int dhd_i_size_read(const struct inode *inode)
+{
+	return i_size_read(inode);
+}
+
+static INLINE int dhd_kernel_read_compat(struct file *fp, loff_t pos, void *buf, size_t count)
+{
+	return kernel_read_compat(fp, pos, buf, count);
+}
+
+static INLINE int dhd_vfs_read(struct file *filep, char *buf, size_t size, loff_t *pos)
+{
+	return vfs_read(filep, buf, size, pos);
+}
+
+static INLINE int dhd_vfs_write(struct file *filep, char *buf, size_t size, loff_t *pos)
+{
+	return vfs_write(filep, buf, size, pos);
+}
+
+static INLINE int dhd_vfs_fsync(struct file *filep, int datasync)
+{
+	return vfs_fsync(filep, datasync);
+}
+
+static INLINE int dhd_vfs_stat(char *buf, struct kstat *stat)
+{
+	return vfs_stat(buf, stat);
+}
+
+static INLINE int dhd_kern_path(char *name, int flags, struct path *file_path)
+{
+	return kern_path(name, flags, file_path);
+}
+#else
+static INLINE struct file *dhd_filp_open(const char *filename, int flags, int mode)
+	{ return NULL; }
+static INLINE int dhd_filp_close(void *image, void *id)
+	{ return 0; }
+static INLINE int dhd_i_size_read(const struct inode *inode)
+	{ return 0; }
+static INLINE int dhd_kernel_read_compat(struct file *fp, loff_t pos, void *buf, size_t count)
+	{ return 0; }
+static INLINE int dhd_vfs_read(struct file *filep, char *buf, size_t size, loff_t *pos)
+	{ return 0; }
+static INLINE int dhd_vfs_write(struct file *filep, char *buf, size_t size, loff_t *pos)
+	{ return 0; }
+static INLINE int dhd_vfs_fsync(struct file *filep, int datasync)
+	{ return 0; }
+static INLINE int dhd_vfs_stat(char *buf, struct kstat *stat)
+	{ return 0; }
+static INLINE int dhd_kern_path(char *name, int flags, struct path *file_path)
+	{ return 0; }
+#endif /* DHD_SUPPORT_VFS_CALL */
+#endif /* __linux__ */
+
 #endif /* _dhd_h_ */
diff --git a/dhd_common.c b/dhd_common.c
index 1c66848..0934072 100755
--- a/dhd_common.c
+++ b/dhd_common.c
@@ -6319,13 +6319,54 @@
 	return num;
 }
 
+#ifdef DHD_LINUX_STD_FW_API
+int dhd_get_download_buffer(dhd_pub_t	*dhd, char *file_path, download_type_t component,
+	char ** buffer, int *length)
+{
+	int ret = BCME_ERROR;
+	const struct firmware *fw = NULL;
+
+	if (file_path) {
+		ret = dhd_os_get_img_fwreq(dhd, &fw, file_path);
+		if (ret < 0) {
+			DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n", ret));
+			goto err;
+		} else {
+			DHD_ERROR(("dhd_os_get_img(Request Firmware API) success\n"));
+			if ((fw->size <= 0 || fw->size > *length)) {
+				*length = fw->size;
+				goto err;
+			}
+			*buffer = MALLOCZ(dhd->osh, fw->size);
+			if (*buffer == NULL) {
+				DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
+					__FUNCTION__, (int)fw->size));
+				goto err;
+			}
+			*length = fw->size;
+			ret = memcpy_s(*buffer, fw->size, fw->data, fw->size);
+			if (ret != BCME_OK) {
+				DHD_ERROR(("%s: memcpy_s failed, err : %d\n", __FUNCTION__, ret));
+				goto err;
+			}
+			ret = BCME_OK;
+		}
+	}
+err:
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+	return ret;
+}
+
+#else
+
 /* Given filename and download type,  returns a buffer pointer and length
 * for download to f/w. Type can be FW or NVRAM.
 *
 */
 int dhd_get_download_buffer(dhd_pub_t	*dhd, char *file_path, download_type_t component,
 	char ** buffer, int *length)
-
 {
 	int ret = BCME_ERROR;
 	int len = 0;
@@ -6373,6 +6414,7 @@
 
 	return ret;
 }
+#endif /* DHD_LINUX_STD_FW_API */
 
 int
 dhd_download_2_dongle(dhd_pub_t	*dhd, char *iovar, uint16 flag, uint16 dload_type,
@@ -6413,6 +6455,10 @@
 
 {
 	int chunk_len;
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+	int cumulative_len = 0;
+#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */
+
 	int size2alloc;
 	unsigned char *new_buf;
 	int err = 0, data_offset;
@@ -6424,6 +6470,15 @@
 
 	if ((new_buf = (unsigned char *)MALLOCZ(dhd->osh, size2alloc)) != NULL) {
 		do {
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+			if (len >= MAX_CHUNK_LEN)
+				chunk_len = MAX_CHUNK_LEN;
+			else
+				chunk_len = len;
+
+			memcpy(new_buf + data_offset, buf + cumulative_len, chunk_len);
+			cumulative_len += chunk_len;
+#else
 			chunk_len = dhd_os_get_image_block((char *)(new_buf + data_offset),
 				MAX_CHUNK_LEN, buf);
 			if (chunk_len < 0) {
@@ -6432,6 +6487,7 @@
 				err = BCME_ERROR;
 				goto exit;
 			}
+#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */
 			if (len - chunk_len == 0)
 				dl_flag |= DL_END;
 
@@ -6442,13 +6498,18 @@
 
 			len = len - chunk_len;
 		} while ((len > 0) && (err == 0));
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+		MFREE(dhd->osh, new_buf, size2alloc);
+#endif /* !LINUX && !linux */
 	} else {
 		err = BCME_NOMEM;
 	}
+#if (defined(LINUX) || defined(linux)) && !defined(DHD_LINUX_STD_FW_API)
 exit:
 	if (new_buf) {
 		MFREE(dhd->osh, new_buf, size2alloc);
 	}
+#endif /* LINUX || linux */
 	return err;
 }
 
@@ -6506,6 +6567,9 @@
 		clm_blob_path = clm_path;
 		DHD_TRACE(("clm path from module param:%s\n", clm_path));
 	} else {
+#ifdef DHD_LINUX_STD_FW_API
+		clm_blob_path = DHD_CLM_NAME;
+#else
 		clm_blob_path = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH;
 #if defined(AUTO_CHIP_DETECTION)
 		if (dhd_bus_chip_id(dhd) == BCM4375_CHIP_ID) {
@@ -6524,6 +6588,7 @@
 						CONFIG_BCMDHD_4389_CLM_PATH;
 		}
 #endif /* AUTO_CHIP_DETECTION */
+#endif /* DHD_LINUX_STD_FW_API */
 	}
 
 	/* If CLM blob file is found on the filesystem, download the file.
@@ -6531,7 +6596,16 @@
 	 * validate the country code before proceeding with the initialization.
 	 * If country code is not valid, fail the initialization.
 	 */
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+	DHD_ERROR(("Clmblob file : %s\n", clm_blob_path));
+	len = MAX_CLM_BUF_SIZE;
+	dhd_get_download_buffer(dhd, clm_blob_path, CLM_BLOB, &memblock, &len);
+#else
 	memblock = dhd_os_open_image1(dhd, (char *)clm_blob_path);
+	len = dhd_os_get_image_size(memblock);
+#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */
+
+#if defined(LINUX) || defined(linux)
 	if (memblock == NULL) {
 #if defined(DHD_BLOB_EXISTENCE_CHECK)
 		if (dhd->is_blob) {
@@ -6547,8 +6621,7 @@
 #endif /* DHD_BLOB_EXISTENCE_CHECK */
 		goto exit;
 	}
-
-	len = dhd_os_get_image_size(memblock);
+#endif /* defined(LINUX) || defined(linux) */
 
 	if ((len > 0) && (len < MAX_CLM_BUF_SIZE) && memblock) {
 		status = dhd_check_current_clm_data(dhd);
@@ -6596,7 +6669,7 @@
 			err = BCME_ERROR;
 			goto exit;
 		} else {
-			DHD_INFO(("%s: CLM download succeeded \n", __FUNCTION__));
+			DHD_ERROR(("%s: CLM download succeeded \n", __FUNCTION__));
 		}
 	} else {
 		DHD_INFO(("Skipping the clm download. len:%d memblk:%p \n", len, memblock));
@@ -6613,7 +6686,12 @@
 exit:
 
 	if (memblock) {
+#if (defined(LINUX) || defined(linux)) && !defined(DHD_LINUX_STD_FW_API)
 		dhd_os_close_image1(dhd, memblock);
+#else
+		dhd_free_download_buffer(dhd, memblock, MAX_CLM_BUF_SIZE);
+#endif /* LINUX || linux */
+
 	}
 
 	return err;
diff --git a/dhd_linux.c b/dhd_linux.c
index ffab7fd..67148cf 100755
--- a/dhd_linux.c
+++ b/dhd_linux.c
@@ -48,7 +48,6 @@
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/fcntl.h>
-#include <linux/fs.h>
 #include <linux/ip.h>
 #include <linux/reboot.h>
 #include <linux/notifier.h>
@@ -61,7 +60,6 @@
 #include <linux/cpufreq.h>
 #endif /* ENABLE_ADAPTIVE_SCHED */
 #include <linux/rtc.h>
-#include <linux/namei.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <dhd_linux_priv.h>
@@ -8429,7 +8427,7 @@
 	if (!fp || !buf || buflen == 0)
 		return -1;
 
-	if (vfs_write((struct file *)fp, buf, buflen, &wr_posn) < 0)
+	if (dhd_vfs_write((struct file *)fp, buf, buflen, &wr_posn) < 0)
 		return -1;
 
 	*posn = wr_posn;
@@ -8445,7 +8443,7 @@
 	if (!file || !buf)
 		return -1;
 
-	return vfs_read(filep, buf, size, &filep->f_pos);
+	return dhd_vfs_read(filep, buf, size, &filep->f_pos);
 }
 
 int
@@ -8465,7 +8463,7 @@
 dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
 {
 	struct file *filep = NULL;
-	struct kstat stat;
+	struct kstat stat = {0};
 	mm_segment_t fs;
 	char *raw_fmts =  NULL;
 	int logstrs_size = 0;
@@ -8479,13 +8477,13 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	filep = filp_open(logstrs_path, O_RDONLY, 0);
+	filep = dhd_filp_open(logstrs_path, O_RDONLY, 0);
 
-	if (IS_ERR(filep)) {
+	if (IS_ERR(filep) || (filep == NULL)) {
 		DHD_ERROR_NO_HW4(("%s: Failed to open the file %s \n", __FUNCTION__, logstrs_path));
 		goto fail;
 	}
-	error = vfs_stat(logstrs_path, &stat);
+	error = dhd_vfs_stat(logstrs_path, &stat);
 	if (error) {
 		DHD_ERROR_NO_HW4(("%s: Failed to stat file %s \n", __FUNCTION__, logstrs_path));
 		goto fail;
@@ -8507,14 +8505,14 @@
 		}
 	}
 
-	if (vfs_read(filep, raw_fmts, logstrs_size, &filep->f_pos) !=	logstrs_size) {
+	if (dhd_vfs_read(filep, raw_fmts, logstrs_size, &filep->f_pos) !=	logstrs_size) {
 		DHD_ERROR_NO_HW4(("%s: Failed to read file %s\n", __FUNCTION__, logstrs_path));
 		goto fail;
 	}
 
 	if (dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp)
 				== BCME_OK) {
-		filp_close(filep, NULL);
+		dhd_filp_close(filep, NULL);
 		set_fs(fs);
 		return BCME_OK;
 	}
@@ -8529,7 +8527,7 @@
 
 fail1:
 	if (!IS_ERR(filep))
-		filp_close(filep, NULL);
+		dhd_filp_close(filep, NULL);
 
 	set_fs(fs);
 	temp->fmts = NULL;
@@ -8554,8 +8552,8 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	filep = filp_open(fname, O_RDONLY, 0);
-	if (IS_ERR(filep)) {
+	filep = dhd_filp_open(fname, O_RDONLY, 0);
+	if (IS_ERR(filep) || (filep == NULL)) {
 		DHD_ERROR_NO_HW4(("%s: Failed to open %s \n",  __FUNCTION__, fname));
 		goto fail;
 	}
@@ -8566,7 +8564,7 @@
 
 fail:
 	if (!IS_ERR(filep))
-		filp_close(filep, NULL);
+		dhd_filp_close(filep, NULL);
 
 	set_fs(fs);
 
@@ -8582,8 +8580,13 @@
 dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn,
 		uint32 lr, char *lr_fn)
 {
+#ifdef DHD_LINUX_STD_FW_API
+	const struct firmware *fw = NULL;
+	uint32 size = 0, mem_offset = 0;
+#else
 	struct file *filep = NULL;
 	mm_segment_t fs;
+#endif /* DHD_LINUX_STD_FW_API */
 	char *raw_fmts = NULL, *raw_fmts_loc = NULL, *cptr = NULL;
 	uint32 read_size = READ_NUM_BYTES;
 	int err = BCME_ERROR;
@@ -8610,14 +8613,24 @@
 		return BCME_ERROR;
 	}
 
+#ifdef DHD_LINUX_STD_FW_API
+	err = dhd_os_get_img_fwreq(g_dhd_pub, &fw, fname);
+	if (err < 0) {
+		DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+			err));
+		goto fail;
+	}
+	size = fw->size;
+#else
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	filep = filp_open(fname, O_RDONLY, 0);
-	if (IS_ERR(filep)) {
+	filep = dhd_filp_open(fname, O_RDONLY, 0);
+	if (IS_ERR(filep) || (filep == NULL)) {
 		DHD_ERROR(("%s: Failed to open %s \n",  __FUNCTION__, fname));
 		goto fail;
 	}
+#endif /* DHD_LINUX_STD_FW_API */
 
 	if (pc_fn == NULL) {
 		count |= PC_FOUND_BIT;
@@ -8627,12 +8640,27 @@
 	}
 	while (count != ALL_ADDR_VAL)
 	{
+#ifdef DHD_LINUX_STD_FW_API
+		/* Bound check for size before doing memcpy() */
+		if ((mem_offset + read_size) > size) {
+			read_size = size - mem_offset;
+		}
+
+		err = memcpy_s(raw_fmts, read_size,
+				((char *)(fw->data) + mem_offset), read_size);
+		if (err) {
+			DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n",
+				 __FUNCTION__, err));
+			goto fail;
+		}
+#else
 		err = dhd_os_read_file(filep, raw_fmts, read_size);
 		if (err < 0) {
 			DHD_ERROR(("%s: map file read failed err:%d \n",
 				__FUNCTION__, err));
 			goto fail;
 		}
+#endif /* DHD_LINUX_STD_FW_API */
 
 		/* End raw_fmts with NULL as strstr expects NULL terminated
 		* strings
@@ -8725,6 +8753,14 @@
 			offset += (len + 1);
 		}
 
+#ifdef DHD_LINUX_STD_FW_API
+        if ((mem_offset + read_size) >= size) {
+            break;
+        }
+
+        memset(raw_fmts, 0, read_size);
+        mem_offset += (read_size -(len + 1));
+#else
 		if (err < (int)read_size) {
 			/*
 			* since we reset file pos back to earlier pos by
@@ -8742,14 +8778,21 @@
 		* the string and addr even if it comes as splited in next read.
 		*/
 		dhd_os_seek_file(filep, -(len + 1));
+#endif /* DHD_LINUX_STD_FW_API */
 		DHD_TRACE(("%s: seek %d \n", __FUNCTION__, -(len + 1)));
 	}
 
 fail:
+#ifdef DHD_LINUX_STD_FW_API
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+#else
 	if (!IS_ERR(filep))
-		filp_close(filep, NULL);
+		dhd_filp_close(filep, NULL);
 
 	set_fs(fs);
+#endif /* DHD_LINUX_STD_FW_API */
 
 	if (!(count & PC_FOUND_BIT)) {
 		sprintf(pc_fn, "0x%08x", pc);
@@ -8790,8 +8833,8 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	filep = filp_open(str_file, O_RDONLY, 0);
-	if (IS_ERR(filep)) {
+	filep = dhd_filp_open(str_file, O_RDONLY, 0);
+	if (IS_ERR(filep) || (filep == NULL)) {
 		DHD_ERROR(("%s: Failed to open the file %s \n",  __FUNCTION__, str_file));
 		goto fail;
 	}
@@ -8828,7 +8871,7 @@
 		}
 	}
 
-	error = vfs_read(filep, raw_fmts, logstrs_size, (&filep->f_pos));
+	error = dhd_vfs_read(filep, raw_fmts, logstrs_size, (&filep->f_pos));
 	if (error != logstrs_size) {
 		DHD_ERROR(("%s: %s read failed %d \n", __FUNCTION__, str_file, error));
 		goto fail;
@@ -8846,7 +8889,7 @@
 		temp->rom_rodata_end = rodata_end;
 	}
 
-	filp_close(filep, NULL);
+	dhd_filp_close(filep, NULL);
 	set_fs(fs);
 
 	return BCME_OK;
@@ -8858,7 +8901,7 @@
 
 fail1:
 	if (!IS_ERR(filep))
-		filp_close(filep, NULL);
+		dhd_filp_close(filep, NULL);
 
 	set_fs(fs);
 
@@ -9594,12 +9637,17 @@
 
 	/* set default firmware and nvram path for built-in type driver */
 	if (!dhd_download_fw_on_driverload) {
+#ifdef DHD_LINUX_STD_FW_API
+		fw = DHD_FW_NAME;
+		nv = DHD_NVRAM_NAME;
+#else
 #ifdef CONFIG_BCMDHD_FW_PATH
 		fw = VENDOR_PATH CONFIG_BCMDHD_FW_PATH;
 #endif /* CONFIG_BCMDHD_FW_PATH */
 #ifdef CONFIG_BCMDHD_NVRAM_PATH
 		nv = VENDOR_PATH CONFIG_BCMDHD_NVRAM_PATH;
 #endif /* CONFIG_BCMDHD_NVRAM_PATH */
+#endif /* DHD_LINUX_STD_FW_API */
 #ifdef AUTO_CHIP_DETECTION
 		if (dhdp->bus && dhd_bus_chip_id(dhdp) == BCM4375_CHIP_ID) {
 			if (dhd_bus_chiprev_id(dhdp) == 1) {
@@ -9616,8 +9664,12 @@
 				nv = VENDOR_PATH
 					 CONFIG_BCMDHD_4385_NVRAM_PATH;
 		} else if (dhdp->bus && dhd_bus_chip_id(dhdp) == BCM43752_CHIP_ID) {
+#ifdef DHD_LINUX_STD_FW_API
+				nv = DHD_NVRAM_USI_NAME;
+#else
 				nv = VENDOR_PATH
 					 CONFIG_BCMDHD_43752_NVRAM_PATH;
+#endif /* DHD_LINUX_STD_FW_API */
 		} else if (dhdp->bus && dhd_bus_chip_id(dhdp) == BCM4389_CHIP_ID) {
 				fw = VENDOR_PATH CONFIG_BCMDHD_4389_FW_PATH;
 				nv = VENDOR_PATH
@@ -9628,9 +9680,9 @@
 
 	/* check if we need to initialize the path */
 	if (dhdinfo->fw_path[0] == '\0') {
-		if (adapter && adapter->fw_path && adapter->fw_path[0] != '\0')
+		if (adapter && adapter->fw_path && adapter->fw_path[0] != '\0') {
 			fw = adapter->fw_path;
-
+		}
 	}
 	if (dhdinfo->nv_path[0] == '\0') {
 		if (adapter && adapter->nv_path && adapter->nv_path[0] != '\0')
@@ -9641,11 +9693,24 @@
 	 *
 	 * TODO: need a solution for multi-chip, can't use the same firmware for all chips
 	 */
-	if (firmware_path[0] != '\0')
+	if (firmware_path[0] != '\0') {
+		/* Newline is getting added sometimes when firmware_path module parameter
+		 * is updated via command line using echo command, due to which
+		 * file not found error is seen, hence replacing '\n' with '\0'.
+		 */
+		if (firmware_path[strlen(firmware_path) - 1] == '\n') {
+			firmware_path[strlen(firmware_path)-1] = '\0';
+		}
 		fw = firmware_path;
+	}
 
-	if (nvram_path[0] != '\0')
+	if (nvram_path[0] != '\0') {
+		if (nvram_path[strlen(nvram_path)-1] == '\n') {
+			nvram_path[strlen(nvram_path)-1] = '\0';
+		}
 		nv = nvram_path;
+	}
+
 
 #ifdef DHD_UCODE_DOWNLOAD
 	if (ucode_path[0] != '\0')
@@ -13382,10 +13447,10 @@
 {
 	struct file *fp;
 	const char *fw = VENDOR_PATH CONFIG_BCMDHD_FW_PATH;
-	fp = filp_open(fw, O_RDONLY, 0);
+	fp = dhd_filp_open(fw, O_RDONLY, 0);
 
-	if (IS_ERR(fp)) {
-		DHD_ERROR(("%s: filp_open(%s) failed(%d) schedule wl_accel_work\n",
+	if (IS_ERR(fp) || fp == NULL) {
+		DHD_ERROR(("%s: dhd_filp_open(%s) failed(%d) schedule wl_accel_work\n",
 			__FUNCTION__, fw, (int)IS_ERR(fp)));
 		return FALSE;
 	}
@@ -14682,20 +14747,34 @@
 
 #endif /* DHD_PCIE_RUNTIMEPM */
 
+int
+dhd_os_get_img_fwreq(dhd_pub_t *dhd, const struct firmware **fw, char *file_path)
+{
+	return request_firmware(fw, file_path,
+		dhd_bus_to_dev(dhd->bus));
+}
+
+void
+dhd_os_close_img_fwreq(const struct firmware *fw)
+{
+	release_firmware(fw);
+}
+
 void *
 dhd_os_open_image1(dhd_pub_t *pub, char *filename)
 {
 	struct file *fp;
 	int size;
 
-	fp = filp_open(filename, O_RDONLY, 0);
+	fp = dhd_filp_open(filename, O_RDONLY, 0);
+
 	/*
-	 * 2.6.11 (FC4) supports filp_open() but later revs don't?
+	 * 2.6.11 (FC4) supports dhd_filp_open() but later revs don't?
 	 * Alternative:
 	 * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
 	 * ???
 	 */
-	 if (IS_ERR(fp)) {
+	 if (IS_ERR(fp) || (fp == NULL)) {
 		 fp = NULL;
 		 goto err;
 	 }
@@ -14706,7 +14785,7 @@
 		 goto err;
 	 }
 
-	 size = i_size_read(file_inode(fp));
+	 size = dhd_i_size_read(file_inode(fp));
 	 if (size <= 0) {
 		 DHD_ERROR(("%s: %s file size invalid %d\n", __FUNCTION__, filename, size));
 		 fp = NULL;
@@ -14730,8 +14809,8 @@
 		return 0;
 	}
 
-	size = i_size_read(file_inode(fp));
-	rdlen = kernel_read_compat(fp, fp->f_pos, buf, MIN(len, size));
+	size = dhd_i_size_read(file_inode(fp));
+	rdlen = dhd_kernel_read_compat(fp, fp->f_pos, buf, MIN(len, size));
 
 	if (len >= size && size != rdlen) {
 		return -EIO;
@@ -14756,7 +14835,7 @@
 	if (!image)
 		return 0;
 
-	rd_len = kernel_read_compat(fp, fp->f_pos, str, len);
+	rd_len = dhd_kernel_read_compat(fp, fp->f_pos, str, len);
 	str_end = strnchr(str, len, '\n');
 	if (str_end == NULL) {
 		goto err;
@@ -14781,7 +14860,7 @@
 		return 0;
 	}
 
-	size = i_size_read(file_inode(fp));
+	size = dhd_i_size_read(file_inode(fp));
 
 	return size;
 }
@@ -14790,7 +14869,7 @@
 dhd_os_close_image1(dhd_pub_t *pub, void *image)
 {
 	if (image) {
-		filp_close((struct file *)image, NULL);
+		dhd_filp_close((struct file *)image, NULL);
 	}
 }
 
@@ -17038,21 +17117,21 @@
 	set_fs(KERNEL_DS);
 
 	/* open file to write */
-	fp = filp_open(file_name, flags, 0664);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(file_name, flags, 0664);
+	if (IS_ERR(fp) || (fp == NULL)) {
 		DHD_ERROR(("open file error, err = %ld\n", PTR_ERR(fp)));
 		goto exit;
 	}
 
 	/* Write buf to file */
-	ret = vfs_write(fp, buf, size, &pos);
+	ret = dhd_vfs_write(fp, buf, size, &pos);
 	if (ret < 0) {
 		DHD_ERROR(("write file error, err = %d\n", ret));
 		goto exit;
 	}
 
 	/* Sync file from filesystem to physical media */
-	ret = vfs_fsync(fp, 0);
+	ret = dhd_vfs_fsync(fp, 0);
 	if (ret < 0) {
 		DHD_ERROR(("sync file error, error = %d\n", ret));
 		goto exit;
@@ -17062,7 +17141,7 @@
 exit:
 	/* close file before return */
 	if (!IS_ERR(fp))
-		filp_close(fp, current->files);
+		dhd_filp_close(fp, current->files);
 
 	/* restore previous address limit */
 	set_fs(old_fs);
@@ -17249,14 +17328,14 @@
 	 */
 	file_mode = O_CREAT | O_WRONLY | O_SYNC;
 	{
-		struct file *fp = filp_open(memdump_path, file_mode, 0664);
+		struct file *fp = dhd_filp_open(memdump_path, file_mode, 0664);
 		/* Check if it is live Brix image having /installmedia, else use /data */
-		if (IS_ERR(fp)) {
+		if (IS_ERR(fp) || (fp == NULL)) {
 			DHD_ERROR(("open file %s, try /data/\n", memdump_path));
 			snprintf(memdump_path, sizeof(memdump_path), "%s%s_%s_" "%s",
 				"/data/", fname, memdump_type,  dhd->debug_dump_time_str);
 		} else {
-			filp_close(fp, NULL);
+			dhd_filp_close(fp, NULL);
 		}
 	}
 #endif /* CUSTOMER_HW4_DEBUG */
@@ -18615,6 +18694,15 @@
 #if defined(WL_CFGVENDOR_SEND_HANG_EVENT)
 char hang_reason_str[DHD_MEMDUMP_TYPE_LONGSTR_LEN];
 #endif
+
+#ifdef DHD_COREDUMP
+#ifdef DHD_LINUX_STD_FW_API
+char map_path[PATH_MAX] = DHD_MAP_NAME;
+#else
+char map_path[PATH_MAX] = VENDOR_PATH CONFIG_BCMDHD_MAP_PATH;
+#endif /* DHD_LINUX_STD_FW_API */
+#endif /* DHD_COREDUMP */
+
 static void
 dhd_mem_dump(void *handle, void *event_info, u8 event)
 {
@@ -18626,7 +18714,6 @@
 	char memdump_type[DHD_MEMDUMP_TYPE_LONGSTR_LEN];
 	char pc_fn[DHD_FUNC_STR_LEN] = "\0";
 	char lr_fn[DHD_FUNC_STR_LEN] = "\0";
-	char *map_path = VENDOR_PATH CONFIG_BCMDHD_MAP_PATH;
 	trap_t *tr;
 #endif /* DHD_COREDUMP */
 
@@ -18693,11 +18780,6 @@
 		DHD_MEMDUMP_TYPE_LONGSTR_LEN, dhdp->debug_dump_subcmd);
 	if (dhdp->memdump_type == DUMP_TYPE_DONGLE_TRAP &&
 		dhdp->dongle_trap_occured == TRUE) {
-#ifdef AUTO_CHIP_DETECTION
-		if (dhd_bus_chip_id(dhdp) == 0x4389) {
-			map_path = VENDOR_PATH CONFIG_BCMDHD_4389_MAP_PATH;
-		}
-#endif /* AUTO_CHIP_DETECTION  */
 		tr = &dhdp->last_trap_info;
 		dhd_lookup_map(dhdp->osh, map_path,
 			ltoh32(tr->epc), pc_fn, ltoh32(tr->r14), lr_fn);
@@ -20335,7 +20417,7 @@
 	unsigned long flags = 0;
 	size_t log_size = 0;
 	size_t fspace_remain = 0;
-	struct kstat stat;
+	struct kstat stat = {0};
 	char time_str[128];
 	unsigned int len = 0;
 	log_dump_section_hdr_t sec_hdr;
@@ -20376,8 +20458,8 @@
 	else
 		file_mode = O_CREAT | O_RDWR | O_SYNC;
 
-	fp = filp_open(dump_path, file_mode, 0664);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(dump_path, file_mode, 0664);
+	if (IS_ERR(fp) || (fp == NULL)) {
 		/* If android installed image, try '/data' directory */
 #if defined(CONFIG_X86)
 		DHD_ERROR(("%s: File open error on Installed android image, trying /data...\n",
@@ -20388,8 +20470,8 @@
 				sizeof(dump_path) - strlen(dump_path),
 				"_%s", dhdp->debug_dump_time_str);
 		}
-		fp = filp_open(dump_path, file_mode, 0664);
-		if (IS_ERR(fp)) {
+		fp = dhd_filp_open(dump_path, file_mode, 0664);
+		if (IS_ERR(fp) || (fp == NULL)) {
 			ret = PTR_ERR(fp);
 			DHD_ERROR(("open file error, err = %d\n", ret));
 			goto exit2;
@@ -20402,7 +20484,7 @@
 #endif /* CONFIG_X86 && OEM_ANDROID */
 	}
 
-	ret = vfs_stat(dump_path, &stat);
+	ret = dhd_vfs_stat(dump_path, &stat);
 	if (ret < 0) {
 		DHD_ERROR(("file stat error, err = %d\n", ret));
 		goto exit2;
@@ -20556,7 +20638,7 @@
 
 exit2:
 	if (!IS_ERR(fp) && fp != NULL) {
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 		DHD_ERROR(("%s: Finished writing log dump to file - '%s' \n",
 				__FUNCTION__, dump_path));
 	}
@@ -20589,7 +20671,7 @@
 	int ret = BCME_OK;
 
 	if (fp) {
-		ret = vfs_write(fp, mem_buf, buf_len, (loff_t *)pos);
+		ret = dhd_vfs_write(fp, mem_buf, buf_len, (loff_t *)pos);
 		if (ret < 0) {
 			DHD_ERROR(("write file error, err = %d\n", ret));
 			goto exit;
@@ -21793,6 +21875,31 @@
 #endif	/* DHD_DEBUG_UART */
 
 #if defined(DHD_BLOB_EXISTENCE_CHECK)
+#ifdef DHD_LINUX_STD_FW_API
+void
+dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path)
+{
+	char *filepath = DHD_CLM_NAME;
+	const struct firmware *fw = NULL;
+	int ret = 0;
+
+	ret = dhd_os_get_img_fwreq(dhdp, &fw, filepath);
+	if (ret < 0) {
+		DHD_ERROR(("%s: ----- blob file doesn't exist (%s) -----\n", __FUNCTION__,
+			filepath));
+		dhdp->is_blob = FALSE;
+	} else {
+		DHD_ERROR(("%s: ----- blob file exists (%s) -----\n", __FUNCTION__, filepath));
+		dhdp->is_blob = TRUE;
+#if defined(CONCATE_BLOB)
+		strncat(fw_path, "_blob", strlen("_blob"));
+#else
+		BCM_REFERENCE(fw_path);
+#endif /* SKIP_CONCATE_BLOB */
+		dhd_os_close_img_fwreq(fw);
+	}
+}
+#else
 void
 dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path)
 {
@@ -21813,8 +21920,8 @@
 	}
 #endif /* AUTO_CHIP_DETECTION */
 
-	fp = filp_open(filepath, O_RDONLY, 0);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
 		DHD_ERROR(("%s: ----- blob file doesn't exist (%s) -----\n", __FUNCTION__,
 			filepath));
 		dhdp->is_blob = FALSE;
@@ -21826,9 +21933,10 @@
 #else
 		BCM_REFERENCE(fw_path);
 #endif /* SKIP_CONCATE_BLOB */
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 	}
 }
+#endif /* DHD_LINUX_STD_FW_API */
 #endif /* DHD_BLOB_EXISTENCE_CHECK */
 
 #if defined(PCIE_FULL_DONGLE)
@@ -21933,14 +22041,14 @@
 	set_fs(KERNEL_DS);
 
 	/* File is always created. */
-	fp = filp_open(filepath, O_RDWR | O_CREAT, 0664);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(filepath, O_RDWR | O_CREAT, 0664);
+	if (IS_ERR(fp) || (fp == NULL)) {
 		DHD_ERROR(("%s: Couldn't open file '%s' err %ld\n",
 			__FUNCTION__, filepath, PTR_ERR(fp)));
 		ret = BCME_ERROR;
 	} else {
 		if (fp->f_mode & FMODE_WRITE) {
-			ret = vfs_write(fp, buf, buf_len, &fp->f_pos);
+			ret = dhd_vfs_write(fp, buf, buf_len, &fp->f_pos);
 			if (ret < 0) {
 				DHD_ERROR(("%s: Couldn't write file '%s'\n",
 					__FUNCTION__, filepath));
@@ -21949,7 +22057,7 @@
 				ret = BCME_OK;
 			}
 		}
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 	}
 
 	/* restore previous address limit */
@@ -21969,15 +22077,15 @@
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	fp = filp_open(filepath, O_RDONLY, 0);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
 		set_fs(old_fs);
 		DHD_ERROR(("%s: File %s doesn't exist\n", __FUNCTION__, filepath));
 		return BCME_ERROR;
 	}
 
-	ret = kernel_read_compat(fp, 0, buf, buf_len);
-	filp_close(fp, NULL);
+	ret = dhd_kernel_read_compat(fp, 0, buf, buf_len);
+	dhd_filp_close(fp, NULL);
 
 	/* restore previous address limit */
 	set_fs(old_fs);
@@ -22015,8 +22123,15 @@
 #ifdef FILTER_IE
 int dhd_read_from_file(dhd_pub_t *dhd)
 {
-	int ret = 0, nread = 0;
+	int ret = 0;
+#ifdef DHD_LINUX_STD_FW_API
+	const struct firmware *fw = NULL;
+	char *filepath = FILTER_IE_PATH;
+	int filelen = 0;
+#else
+	int nread = 0;
 	void *fd;
+#endif /* DHD_LINUX_STD_FW_API */
 	uint8 *buf;
 	NULL_CHECK(dhd, "dhd is NULL", ret);
 
@@ -22027,6 +22142,32 @@
 	}
 
 	/* open file to read */
+#ifdef DHD_LINUX_STD_FW_API
+	ret = dhd_os_get_img_fwreq(dhd, &fw, filepath);
+	if (ret < 0) {
+		DHD_ERROR(("dhd_os_get_img_fwreq(%s) error : %d\n",
+			filepath, ret));
+		goto exit;
+	}
+
+	filelen = fw->size;
+	if (filelen == 0) {
+		DHD_ERROR(("error: zero length file.failed to read\n"));
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	ret = memcpy_s(buf, FILE_BLOCK_READ_SIZE, fw->data, fw->size);
+	if (ret < 0) {
+		DHD_ERROR((" memcpy_s() error : %d\n", ret));
+		goto exit;
+	}
+
+	ret = dhd_parse_filter_ie(dhd, buf);
+	if (ret < 0) {
+		DHD_ERROR(("error: failed to parse filter ie\n"));
+	}
+#else
 	fd = dhd_os_open_image1(dhd, FILTER_IE_PATH);
 	if (!fd) {
 		DHD_ERROR(("No filter file(not an error), filter path%s\n", FILTER_IE_PATH));
@@ -22043,8 +22184,15 @@
 		DHD_ERROR(("error: zero length file.failed to read\n"));
 		ret = BCME_ERROR;
 	}
-	dhd_os_close_image1(dhd, fd);
+#endif /* DHD_LINUX_STD_FW_API */
 exit:
+#ifdef DHD_LINUX_STD_FW_API
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+#else
+	dhd_os_close_image1(dhd, fd);
+#endif /* DHD_LINUX_STD_FW_API */
 	if (buf) {
 		MFREE(dhd->osh, buf, FILE_BLOCK_READ_SIZE);
 	}
@@ -23995,19 +24143,23 @@
 #define DHD_VFS_INODE(dir) d_inode(dir)
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) */
 
+#ifdef DHD_SUPPORT_VFS_CALL
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
 #define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b)
 #else
 #define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b, c)
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
+#else
+#define DHD_VFS_UNLINK(dir, b, c) 0
+#endif /* DHD_SUPPORT_VFS_CALL */
 int
 dhd_file_delete(char *path)
 {
-	struct path file_path;
+	struct path file_path = {.dentry = 0};
 	int err;
 	struct dentry *dir;
 
-	err = kern_path(path, 0, &file_path);
+	err = dhd_kern_path(path, 0, &file_path);
 
 	if (err < 0) {
 		DHD_ERROR(("Failed to get kern-path delete file: %s error: %d\n", path, err));
diff --git a/dhd_linux.h b/dhd_linux.h
index bfaf63d..5e6713e 100755
--- a/dhd_linux.h
+++ b/dhd_linux.h
@@ -368,7 +368,11 @@
 #endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
 
 #ifdef FILTER_IE
+#ifdef DHD_LINUX_STD_FW_API
+#define FILTER_IE_PATH "filter_ie"
+#else
 #define FILTER_IE_PATH "/vendor/etc/wifi/filter_ie"
+#endif /* DHD_LINUX_STD_FW_API */
 #define FILTER_IE_BUFSZ 1024 /* ioc buffsize for FILTER_IE */
 #define FILE_BLOCK_READ_SIZE 256
 #define WL_FILTER_IE_IOV_HDR_SIZE OFFSETOF(wl_filter_ie_iov_v1_t, tlvs)
diff --git a/dhd_linux_exportfs.c b/dhd_linux_exportfs.c
index 54bcfca..8fc34c2 100755
--- a/dhd_linux_exportfs.c
+++ b/dhd_linux_exportfs.c
@@ -699,8 +699,8 @@
 	int ret = 0;
 
 	/* Read memdump info from the file */
-	fp = filp_open(filepath, O_RDONLY, 0);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
 		DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
 #if defined(CONFIG_X86)
 		/* Check if it is Live Brix Image */
@@ -710,8 +710,8 @@
 		/* Try if it is Installed Brix Image */
 		filepath = MEMDUMPINFO_INST;
 		DHD_ERROR(("%s: Try File [%s]\n", __FUNCTION__, filepath));
-		fp = filp_open(filepath, O_RDONLY, 0);
-		if (IS_ERR(fp)) {
+		fp = dhd_filp_open(filepath, O_RDONLY, 0);
+		if (IS_ERR(fp) || (fp == NULL)) {
 			DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
 			goto done;
 		}
@@ -721,10 +721,10 @@
 	}
 
 	/* Handle success case */
-	ret = kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32));
+	ret = dhd_kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32));
 	if (ret < 0) {
 		DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret));
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 		goto done;
 	}
 
@@ -732,7 +732,7 @@
 	p_mem_val[sizeof(uint32) - 1] = '\0';
 	mem_val = bcm_atoi(p_mem_val);
 
-	filp_close(fp, NULL);
+	dhd_filp_close(fp, NULL);
 
 done:
 	return mem_val;
@@ -837,11 +837,11 @@
 	 * 2: Trigger Kernel crash by BUG()
 	 * File doesn't exist: Keep default value (1).
 	 */
-	fp = filp_open(filepath, O_RDONLY, 0);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
 		DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
 	} else {
-		int ret = kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32));
+		int ret = dhd_kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32));
 		if (ret < 0) {
 			DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret));
 		} else {
@@ -850,7 +850,7 @@
 			mem_val = bcm_atoi(p_mem_val);
 			DHD_ERROR(("%s: ASSERT ENABLED = %d\n", __FUNCTION__, mem_val));
 		}
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 	}
 
 #ifdef CUSTOMER_HW4_DEBUG
diff --git a/dhd_pcie.c b/dhd_pcie.c
index 4c39f46..3a6527e 100755
--- a/dhd_pcie.c
+++ b/dhd_pcie.c
@@ -3153,6 +3153,85 @@
 	return ret;
 } /* dhdpcie_download_firmware */
 
+#ifdef DHD_LINUX_STD_FW_API
+static int
+dhdpcie_download_code_file(struct dhd_bus *bus, char *pfw_path)
+{
+	int bcmerror = BCME_ERROR;
+	int offset = 0;
+	int len = 0;
+	bool store_reset;
+	int offset_end = bus->ramsize;
+	const struct firmware *fw = NULL;
+	int buf_offset = 0, residual_len = 0;
+
+#if defined(DHD_FW_MEM_CORRUPTION)
+		if (dhd_bus_get_fw_mode(bus->dhd) == DHD_FLAG_MFG_MODE) {
+			dhd_tcm_test_enable = TRUE;
+		} else {
+			dhd_tcm_test_enable = FALSE;
+		}
+#endif /* DHD_FW_MEM_CORRUPTION */
+		DHD_ERROR(("%s: dhd_tcm_test_enable %u\n", __FUNCTION__, dhd_tcm_test_enable));
+		/* TCM check */
+		if (dhd_tcm_test_enable && !dhd_bus_tcm_test(bus)) {
+			DHD_ERROR(("dhd_bus_tcm_test failed\n"));
+			bcmerror = BCME_ERROR;
+			goto err;
+		}
+
+	DHD_ERROR(("%s: download firmware %s\n", __FUNCTION__, pfw_path));
+
+	/* check if CR4/CA7 */
+	store_reset = (si_setcore(bus->sih, ARMCR4_CORE_ID, 0) ||
+			si_setcore(bus->sih, ARMCA7_CORE_ID, 0));
+
+	bcmerror = dhd_os_get_img_fwreq(bus->dhd, &fw, bus->fw_path);
+	if (bcmerror < 0) {
+		DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+			bcmerror));
+		goto err;
+	}
+	DHD_ERROR(("dhd_os_get_img(Request Firmware API) success\n"));
+	residual_len = fw->size;
+	while (residual_len) {
+		len = MIN(residual_len, MEMBLOCK);
+
+		/* if address is 0, store the reset instruction to be written in 0 */
+		if (store_reset) {
+			ASSERT(offset == 0);
+			bus->resetinstr = *(((uint32*)fw->data + buf_offset));
+			/* Add start of RAM address to the address given by user */
+			offset += bus->dongle_ram_base;
+			offset_end += offset;
+			store_reset = FALSE;
+		}
+
+		bcmerror = dhdpcie_bus_membytes(bus, TRUE, offset, (uint8 *)fw->data + buf_offset, len);
+		if (bcmerror) {
+			DHD_ERROR(("%s: error %d on writing %d membytes at 0x%08x\n",
+				__FUNCTION__, bcmerror, MEMBLOCK, offset));
+			goto err;
+		}
+		offset += MEMBLOCK;
+
+		if (offset >= offset_end) {
+			DHD_ERROR(("%s: invalid address access to %x (offset end: %x)\n",
+				__FUNCTION__, offset, offset_end));
+			bcmerror = BCME_ERROR;
+			goto err;
+		}
+		residual_len -= len;
+		buf_offset += len;
+	}
+err:
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+	return bcmerror;
+} /* dhdpcie_download_code_file */
+
+#else
 /**
  * Downloads a file containing firmware into dongle memory. In case of a .bea file, the DHD
  * is updated with the event logging partitions within that file as well.
@@ -3270,6 +3349,7 @@
 
 	return bcmerror;
 } /* dhdpcie_download_code_file */
+#endif
 
 #ifdef CUSTOMER_HW4_DEBUG
 #define MIN_NVRAMVARS_SIZE 128
diff --git a/dhd_pktlog.c b/dhd_pktlog.c
index 0ad2ac4..acb9eb0 100644
--- a/dhd_pktlog.c
+++ b/dhd_pktlog.c
@@ -1194,8 +1194,8 @@
 	set_fs(KERNEL_DS);
 	file_mode = O_CREAT | O_WRONLY;
 
-	w_pcap_fp = filp_open(pktlogdump_path, file_mode, 0664);
-	if (IS_ERR(w_pcap_fp)) {
+	w_pcap_fp = dhd_filp_open(pktlogdump_path, file_mode, 0664);
+	if (IS_ERR(w_pcap_fp) || (w_pcap_fp == NULL)) {
 		DHD_ERROR(("%s: Couldn't open file '%s' err %ld\n",
 			__FUNCTION__, pktlogdump_path, PTR_ERR(w_pcap_fp)));
 		ret = BCME_ERROR;
@@ -1209,14 +1209,14 @@
 	}
 
 	/* Sync file from filesystem to physical media */
-	ret = vfs_fsync(w_pcap_fp, 0);
+	ret = dhd_vfs_fsync(w_pcap_fp, 0);
 	if (ret < 0) {
 		DHD_ERROR(("%s(): sync pcap file error, err = %d\n", __FUNCTION__, ret));
 		goto fail;
 	}
 fail:
 	if (!IS_ERR(w_pcap_fp)) {
-		filp_close(w_pcap_fp, NULL);
+		dhd_filp_close(w_pcap_fp, NULL);
 	}
 
 	set_fs(old_fs);
diff --git a/linux_osl.c b/linux_osl.c
index b715d31..ebbd604 100755
--- a/linux_osl.c
+++ b/linux_osl.c
@@ -1009,14 +1009,14 @@
 {
 	struct file *fp;
 
-	fp = filp_open(filename, O_RDONLY, 0);
+	fp = dhd_filp_open(filename, O_RDONLY, 0);
 	/*
 	 * 2.6.11 (FC4) supports filp_open() but later revs don't?
 	 * Alternative:
 	 * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
 	 * ???
 	 */
-	if (IS_ERR(fp)) {
+	if (IS_ERR(fp) || fp == NULL) {
 		DHD_ERROR(("ERROR %ld: Unable to open file %s\n", PTR_ERR(fp), filename));
 		fp = NULL;
 	}
@@ -1034,7 +1034,7 @@
 		return 0;
 	}
 
-	rdlen = kernel_read_compat(fp, fp->f_pos, buf, len);
+	rdlen = dhd_kernel_read_compat(fp, fp->f_pos, buf, len);
 	if (rdlen > 0) {
 		fp->f_pos += rdlen;
 	}
@@ -1048,7 +1048,7 @@
 	struct file *fp = (struct file *)image;
 
 	if (fp != NULL) {
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 	}
 }
 
diff --git a/wl_bam.c b/wl_bam.c
index 3ec8eea..5fbc1df 100644
--- a/wl_bam.c
+++ b/wl_bam.c
@@ -236,8 +236,8 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	fp = filp_open(fname, O_RDONLY, 0);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(fname, O_RDONLY, 0);
+	if (IS_ERR(fp) || fp == NULL) {
 		fp = NULL;
 		WL_ERR(("%s: file open failed(%d)\n", __FUNCTION__, ret));
 		goto fail;
@@ -248,7 +248,7 @@
 	}
 fail:
 	if (fp) {
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 	}
 	set_fs(fs);
 
@@ -283,8 +283,8 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	fp = filp_open(fname, O_CREAT | O_RDWR | O_TRUNC,  0666);
-	if (IS_ERR(fp)) {
+	fp = dhd_filp_open(fname, O_CREAT | O_RDWR | O_TRUNC,  0666);
+	if (IS_ERR(fp) || fp == NULL) {
 		ret = PTR_ERR(fp);
 		WL_ERR(("%s: file open failed(%d)\n", __FUNCTION__, ret));
 		fp = NULL;
@@ -310,13 +310,13 @@
 #pragma GCC diagnostic pop
 #endif
 
-	ret = vfs_write(fp, tmp, len, &fp->f_pos);
+	ret = dhd_vfs_write(fp, tmp, len, &fp->f_pos);
 	if (ret < 0) {
 		WL_ERR(("%s: file write failed(%d)\n", __FUNCTION__, ret));
 		goto fail;
 	}
 	/* Sync file from filesystem to physical media */
-	ret = vfs_fsync(fp, 0);
+	ret = dhd_vfs_fsync(fp, 0);
 	if (ret < 0) {
 		WL_ERR(("%s: sync file failed(%d)\n", __FUNCTION__, ret));
 		goto fail;
@@ -324,7 +324,7 @@
 	ret = BCME_OK;
 fail:
 	if (fp) {
-		filp_close(fp, NULL);
+		dhd_filp_close(fp, NULL);
 	}
 	set_fs(fs);
 	mutex_unlock(&cfg->bad_ap_mngr.fs_lock);
diff --git a/wl_cfg80211.c b/wl_cfg80211.c
index 86e0c10..2ccb973 100755
--- a/wl_cfg80211.c
+++ b/wl_cfg80211.c
@@ -2923,7 +2923,7 @@
 
 	WL_ERR(("%s: starts to read %s. Axi error \n", __FUNCTION__, filename));
 
-	fp = filp_open(filename, O_RDONLY, 0);
+	fp = dhd_filp_open(filename, O_RDONLY, 0);
 
 	if (IS_ERR(fp) || (fp == NULL)) {
 		WL_ERR(("%s: Couldn't read the file, err %ld,File [%s]  No previous axi error \n",
@@ -2931,8 +2931,8 @@
 		return ret;
 	}
 
-	kernel_read_compat(fp, fp->f_pos, (char *)dhd->axi_err_dump, sizeof(dhd_axi_error_dump_t));
-	filp_close(fp, NULL);
+	dhd_kernel_read_compat(fp, fp->f_pos, (char *)dhd->axi_err_dump, sizeof(dhd_axi_error_dump_t));
+	dhd_filp_close(fp, NULL);
 
 	/* Delete axi error info file */
 	if (dhd_file_delete(filename) < 0) {