From 07d6b24ace75a7513c013ad8dae757dc51a7bcaf Mon Sep 17 00:00:00 2001 From: Rongjun Chen Date: Tue, 28 Aug 2018 14:07:58 +0800 Subject: [PATCH] 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 --- bcmdhd.1.579.77.41.1.cn/dhd_sdio.c | 72 ++++++++++++++++-------------- 1 file 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; -- 2.20.1