summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRongjun Chen <rongjun.chen@amlogic.com>2018-08-28 14:07:58 +0800
committerRongjun Chen <rongjun.chen@amlogic.com>2018-08-29 10:07:34 +0800
commit07d6b24ace75a7513c013ad8dae757dc51a7bcaf (patch)
tree232c7f5ad5e7c37877d2c01039465cf1fc54c7c5
parent565fad4ddba722a2b99c208c0c7ee2c15a530011 (diff)
downloaddhd-driver-07d6b24ace75a7513c013ad8dae757dc51a7bcaf.tar.gz
wifi: fix vma let wifi open fail issue
PD# 172294 fix vmap let wifi open fail issue Change-Id: Ib3cf910c0df62370cb42e17d3723abb0718919f8 Signed-off-by: Rongjun Chen <rongjun.chen@amlogic.com>
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_sdio.c72
1 files changed, 39 insertions, 33 deletions
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c b/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
index e091724..c22288f 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
@@ -113,6 +113,7 @@ static int dhdsdio_resume(void *context);
#define MAX_MEMBLOCK (32 * 1024) /* Block size used for downloading of dongle image */
#define MAX_DATA_BUF (64 * 1024) /* Must be large enough to hold biggest possible glom */
+#define MAX_MEM_BUF 4096
#ifndef DHD_FIRSTREAD
#define DHD_FIRSTREAD 32
@@ -436,6 +437,7 @@ typedef struct dhd_bus {
#endif /* defined (BT_OVER_SDIO) */
uint txglomframes; /* Number of tx glom frames (superframes) */
uint txglompkts; /* Number of packets from tx glom frames */
+ uint8 *membuf; /* Buffer for receiving big glom packet */
} dhd_bus_t;
@@ -3375,6 +3377,10 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint s
dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
else
dsize = size;
+ if (dsize > MAX_MEM_BUF) {
+ DHD_ERROR(("%s: dsize %d > %d\n", __FUNCTION__, dsize, MAX_MEM_BUF));
+ goto xfer_done;
+ }
/* Set the backplane window to include the start address */
if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) {
@@ -3387,10 +3393,14 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, uint32 address, uint8 *data, uint s
DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n",
__FUNCTION__, (write ? "write" : "read"), dsize, sdaddr,
(address & SBSDIO_SBWINDOW_MASK)));
- if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) {
+ if (write)
+ memcpy(bus->membuf, data, dsize);
+ if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, bus->membuf, dsize))) {
DHD_ERROR(("%s: membytes transfer failed\n", __FUNCTION__));
break;
}
+ if (!write)
+ memcpy(data, bus->membuf, dsize);
/* Adjust for next transfer (if any) */
if ((size -= dsize)) {
@@ -4703,46 +4713,20 @@ dhdsdio_download_state(dhd_bus_t *bus, bool enter)
(uint8 *)&bus->resetinstr, sizeof(bus->resetinstr));
if (bcmerror == BCME_OK) {
-#ifdef CONFIG_VMAP_STACK
- char *tmp;
- tmp = kmalloc(4, GFP_KERNEL);
- if (!tmp)
- goto fail;
-#else
uint32 tmp;
-#endif
+
/* verify write */
-#ifdef CONFIG_VMAP_STACK
- bcmerror = dhdsdio_membytes(bus, FALSE, 0,
- (uint8 *)tmp, 4);
-#else
bcmerror = dhdsdio_membytes(bus, FALSE, 0,
- (uint8 *)&tmp, sizeof(tmp));
-#endif
-#ifdef CONFIG_VMAP_STACK
- if (bcmerror == BCME_OK && *(uint32*)tmp != bus->resetinstr)
-#else
- if (bcmerror == BCME_OK && tmp != bus->resetinstr)
-#endif
- {
- DHD_ERROR(("%s: Filed to write 0x%08x to addr 0\n",
+ (uint8 *)&tmp, sizeof(tmp));
+
+ if (bcmerror == BCME_OK && tmp != bus->resetinstr) {
+ DHD_ERROR(("%s: Failed to write 0x%08x to addr 0\n",
__FUNCTION__, bus->resetinstr));
-#ifdef CONFIG_VMAP_STACK
- DHD_ERROR(("%s: contents of addr 0 is 0x%08x\n",
- __FUNCTION__, *(uint32*)tmp));
-#else
DHD_ERROR(("%s: contents of addr 0 is 0x%08x\n",
- __FUNCTION__, tmp));
-#endif
+ __FUNCTION__, tmp));
bcmerror = BCME_SDIO_ERROR;
-#ifdef CONFIG_VMAP_STACK
- kfree(tmp);
-#endif
goto fail;
}
-#ifdef CONFIG_VMAP_STACK
- kfree(tmp);
-#endif
}
/* now remove reset and halt and continue to run CR4 */
@@ -8182,6 +8166,23 @@ dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh)
DHD_OS_PREFREE(bus->dhd, bus->rxbuf, bus->rxblen);
goto fail;
}
+ /* Allocate buffer to membuf */
+ bus->membuf = MALLOC(osh, MAX_MEM_BUF);
+ if (bus->membuf == NULL) {
+ DHD_ERROR(("%s: MALLOC of %d-byte membuf failed\n",
+ __FUNCTION__, MAX_MEM_BUF));
+ if (bus->databuf) {
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+ MFREE(osh, bus->databuf, MAX_DATA_BUF);
+#endif
+ bus->databuf = NULL;
+ }
+ /* release rxbuf which was already located as above */
+ if (!bus->rxblen)
+ DHD_OS_PREFREE(bus->dhd, bus->rxbuf, bus->rxblen);
+ goto fail;
+ }
+ memset(bus->membuf, 0, MAX_MEM_BUF);
/* Align the buffer */
if ((uintptr)bus->databuf % DHD_SDALIGN)
@@ -8458,6 +8459,11 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
bus->databuf = NULL;
}
+ if (bus->membuf) {
+ MFREE(osh, bus->membuf, MAX_DATA_BUF);
+ bus->membuf = NULL;
+ }
+
if (bus->vars && bus->varsz) {
MFREE(osh, bus->vars, bus->varsz);
bus->vars = NULL;