summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaniel oh <daniel.oh@broadcom.corp-partner.google.com>2021-04-06 21:05:13 +0900
committerRoger Wang <wangroger@google.com>2021-04-07 18:50:38 +0800
commitbf7579793d693956440bb6a2006d5aa3c1024bae (patch)
tree5eae3341037bb066b7790f4e6d844be5bf78cffb
parent1b79d6513d715576ce065222b19f8ac19c5a3651 (diff)
downloadbcm43752-bf7579793d693956440bb6a2006d5aa3c1024bae.tar.gz
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>
-rwxr-xr-xKbuild6
-rwxr-xr-xdhd.h79
-rwxr-xr-xdhd_common.c86
-rwxr-xr-xdhd_linux.c302
-rwxr-xr-xdhd_linux.h4
-rwxr-xr-xdhd_linux_exportfs.c22
-rwxr-xr-xdhd_pcie.c80
-rw-r--r--dhd_pktlog.c8
-rwxr-xr-xlinux_osl.c8
-rw-r--r--wl_bam.c16
-rwxr-xr-xwl_cfg80211.c6
11 files changed, 507 insertions, 110 deletions
diff --git a/Kbuild b/Kbuild
index f8c0769..02eeb01 100755
--- a/Kbuild
+++ b/Kbuild
@@ -796,6 +796,12 @@ endif
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 @@ extern void copy_debug_dump_time(char *dest, char *src);
#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_cto_recovery(dhd_pub_t *dhdp);
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 @@ typedef enum wifi_alert_reason_codes {
} 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 @@ wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num)
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 @@ err:
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 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf,
{
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 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf,
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 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf,
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 @@ dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf,
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 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
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 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
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 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
* 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 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
#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 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
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 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
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 @@ dhd_os_write_file_posn(void *fp, unsigned long *posn, void *buf,
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 @@ dhd_os_read_file(void *file, char *buf, uint32 size)
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 @@ static int
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 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
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 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
}
}
- 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 @@ fail:
fail1:
if (!IS_ERR(filep))
- filp_close(filep, NULL);
+ dhd_filp_close(filep, NULL);
set_fs(fs);
temp->fmts = NULL;
@@ -8554,8 +8552,8 @@ dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
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 @@ dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
fail:
if (!IS_ERR(filep))
- filp_close(filep, NULL);
+ dhd_filp_close(filep, NULL);
set_fs(fs);
@@ -8582,8 +8580,13 @@ static int
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 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn,
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 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn,
}
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 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn,
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 @@ dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn,
* 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 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
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 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
}
}
- 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 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
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 @@ fail:
fail1:
if (!IS_ERR(filep))
- filp_close(filep, NULL);
+ dhd_filp_close(filep, NULL);
set_fs(fs);
@@ -9594,12 +9637,17 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
/* 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 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
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 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
/* 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 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
*
* 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 @@ dhd_check_filesystem_is_up(void)
{
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 @@ exit:
#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 @@ dhd_os_open_image1(dhd_pub_t *pub, char *filename)
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 @@ dhd_os_get_image_block(char *buf, int len, void *image)
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 @@ dhd_os_gets_image(dhd_pub_t *pub, char *str, int len, void *image)
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 @@ dhd_os_get_image_size(void *image)
return 0;
}
- size = i_size_read(file_inode(fp));
+ size = dhd_i_size_read(file_inode(fp));
return size;
}
@@ -14790,7 +14869,7 @@ void
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 @@ int write_file(const char * file_name, uint32 flags, uint8 *buf, int size)
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 @@ int write_file(const char * file_name, uint32 flags, uint8 *buf, int size)
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 @@ write_dump_to_file(dhd_pub_t *dhd, uint8 *buf, int size, char *fname)
*/
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 @@ void dhd_schedule_memdump(dhd_pub_t *dhdp, uint8 *buf, uint32 size)
#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 @@ dhd_mem_dump(void *handle, void *event_info, u8 event)
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_mem_dump(void *handle, void *event_info, u8 event)
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 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type)
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 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type)
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 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type)
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 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type)
#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 @@ do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type)
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 @@ dhd_export_debug_data(void *mem_buf, void *fp, const void *user_buf, uint32 buf_
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 @@ dhd_debug_uart_exec(dhd_pub_t *dhdp, char *cmd)
#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 @@ dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path)
}
#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 @@ dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path)
#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 @@ dhd_write_file(const char *filepath, char *buf, int buf_len)
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 @@ dhd_write_file(const char *filepath, char *buf, int buf_len)
ret = BCME_OK;
}
}
- filp_close(fp, NULL);
+ dhd_filp_close(fp, NULL);
}
/* restore previous address limit */
@@ -21969,15 +22077,15 @@ dhd_read_file(const char *filepath, char *buf, int buf_len)
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 @@ dhd_write_file_and_check(const char *filepath, char *buf, int buf_len)
#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 @@ int dhd_read_from_file(dhd_pub_t *dhd)
}
/* 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 @@ int dhd_read_from_file(dhd_pub_t *dhd)
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 @@ dhd_ring_whole_unlock(void *_ring)
#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 @@ struct dhd_rx_tx_work {
#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 @@ get_mem_val_from_file(void)
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 @@ get_mem_val_from_file(void)
/* 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 @@ get_mem_val_from_file(void)
}
/* 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 @@ get_mem_val_from_file(void)
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 @@ get_assert_val_from_file(void)
* 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 @@ get_assert_val_from_file(void)
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 @@ dhdpcie_download_firmware(struct dhd_bus *bus, osl_t *osh)
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 @@ err:
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 @@ dhd_pktlog_dump_write_file(dhd_pub_t *dhdp)
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 @@ dhd_pktlog_dump_write_file(dhd_pub_t *dhdp)
}
/* 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 @@ osl_os_open_image(char *filename)
{
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 @@ osl_os_get_image_block(char *buf, int len, void *image)
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 @@ osl_os_close_image(void *image)
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 @@ wl_bad_ap_mngr_fread(struct bcm_cfg80211 *cfg, const char *fname)
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 @@ wl_bad_ap_mngr_fread(struct bcm_cfg80211 *cfg, const char *fname)
}
fail:
if (fp) {
- filp_close(fp, NULL);
+ dhd_filp_close(fp, NULL);
}
set_fs(fs);
@@ -283,8 +283,8 @@ wl_bad_ap_mngr_fwrite(struct bcm_cfg80211 *cfg, const char *fname)
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 @@ wl_bad_ap_mngr_fwrite(struct bcm_cfg80211 *cfg, const char *fname)
#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 @@ wl_bad_ap_mngr_fwrite(struct bcm_cfg80211 *cfg, const char *fname)
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_cfg80211_check_axi_error(struct bcm_cfg80211 *cfg)
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 @@ _wl_cfg80211_check_axi_error(struct bcm_cfg80211 *cfg)
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) {