wifi: fix vma let wifi open fail issue
authorRongjun Chen <rongjun.chen@amlogic.com>
Tue, 28 Aug 2018 06:07:58 +0000 (14:07 +0800)
committerRongjun Chen <rongjun.chen@amlogic.com>
Wed, 29 Aug 2018 02:07:34 +0000 (10:07 +0800)
PD# 172294

fix vmap let wifi open fail issue
Change-Id: Ib3cf910c0df62370cb42e17d3723abb0718919f8
Signed-off-by: Rongjun Chen <rongjun.chen@amlogic.com>
bcmdhd.1.579.77.41.1.cn/dhd_sdio.c

index e09172478cedfd8bda9f47e2dda07a7a3e12b53a..c22288f07f6c08d80460b6f32b8509de0ab178a7 100644 (file)
@@ -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;