diff options
Diffstat (limited to 'drivers/net/wireless/bcmdhd/dhd_sdio.c')
-rwxr-xr-x | drivers/net/wireless/bcmdhd/dhd_sdio.c | 114 |
1 files changed, 49 insertions, 65 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c index ec44acdf098f..f9de6efaca75 100755 --- a/drivers/net/wireless/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_sdio.c 440335 2013-12-02 09:33:45Z $ + * $Id: dhd_sdio.c 426658 2013-09-30 12:14:01Z $ */ #include <typedefs.h> @@ -418,8 +418,13 @@ static bool sd1idle; static bool retrydata; #define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) -static uint watermark = 8; -static uint mesbusyctrl = 0; +#if defined(SDIO_CRC_ERROR_FIX) +static uint watermark = 48; +static uint mesbusyctrl = 80; +#else +static const uint watermark = 8; +static const uint mesbusyctrl = 0; +#endif static const uint firstread = DHD_FIRSTREAD; #define HDATLEN (firstread - (SDPCM_HDRLEN)) @@ -597,42 +602,31 @@ extern uint32 dhd_get_htsf(void *dhd, int ifidx); #endif /* WLMEDIA_HTSF */ static void -dhdsdio_tune_fifoparam(struct dhd_bus *bus) +dhd_overflow_war(struct dhd_bus *bus) { int err; uint8 devctl, wm, mes; - if (bus->sih->buscorerev >= 15) { - /* See .ppt in PR for these recommended values */ - if (bus->blocksize == 512) { - wm = OVERFLOW_BLKSZ512_WM; - mes = OVERFLOW_BLKSZ512_MES; - } else { - mes = bus->blocksize/4; - wm = bus->blocksize/4; - } - watermark = wm; - mesbusyctrl = mes; + /* See .ppt in PR for these recommended values */ + if (bus->blocksize == 512) { + wm = OVERFLOW_BLKSZ512_WM; + mes = OVERFLOW_BLKSZ512_MES; } else { - DHD_INFO(("skip fifotune: SdioRev(%d) is lower than minimal requested ver\n", - bus->sih->buscorerev)); - return; + mes = bus->blocksize/4; + wm = bus->blocksize/4; } + /* Update watermark */ - if (wm > 0) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, wm, &err); + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, wm, &err); - devctl = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); - devctl |= SBSDIO_DEVCTL_F2WM_ENAB; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - } + devctl = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); + devctl |= SBSDIO_DEVCTL_F2WM_ENAB; + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); /* Update MES */ - if (mes > 0) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, - (mes | SBSDIO_MESBUSYCTRL_ENAB), &err); - } + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, + (mes | SBSDIO_MESBUSYCTRL_ENAB), &err); DHD_INFO(("Apply overflow WAR: 0x%02x 0x%02x 0x%02x\n", bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err), @@ -2723,10 +2717,10 @@ enum { IOV_SDALIGN, IOV_DEVRESET, IOV_CPU, -#if defined(USE_SDIOFIFO_IOVAR) +#if defined(SDIO_CRC_ERROR_FIX) IOV_WATERMARK, IOV_MESBUSYCTRL, -#endif /* USE_SDIOFIFO_IOVAR */ +#endif /* SDIO_CRC_ERROR_FIX */ #ifdef SDTEST IOV_PKTGEN, IOV_EXTLOOP, @@ -2789,10 +2783,10 @@ const bcm_iovar_t dhdsdio_iovars[] = { {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0 }, {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t) }, #endif /* SDTEST */ -#if defined(USE_SDIOFIFO_IOVAR) +#if defined(SDIO_CRC_ERROR_FIX) {"watermark", IOV_WATERMARK, 0, IOVT_UINT32, 0 }, {"mesbusyctrl", IOV_MESBUSYCTRL, 0, IOVT_UINT32, 0 }, -#endif /* USE_SDIOFIFO_IOVAR */ +#endif /* SDIO_CRC_ERROR_FIX */ {"devcap", IOV_DEVCAP, 0, IOVT_UINT32, 0 }, {"dngl_isolation", IOV_DONGLEISOLATION, 0, IOVT_UINT32, 0 }, {"kso", IOV_KSO, 0, IOVT_UINT32, 0 }, @@ -3921,7 +3915,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch break; #endif /* SDTEST */ -#if defined(USE_SDIOFIFO_IOVAR) +#if defined(SDIO_CRC_ERROR_FIX) case IOV_GVAL(IOV_WATERMARK): int_val = (int32)watermark; bcopy(&int_val, arg, val_size); @@ -3947,7 +3941,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, ((uint8)mesbusyctrl | 0x80), NULL); break; -#endif +#endif /* SDIO_CRC_ERROR_FIX */ case IOV_GVAL(IOV_DONGLEISOLATION): @@ -4409,7 +4403,10 @@ dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, } else { DHD_INFO(("%s: noted %s update, value now %d\n", __FUNCTION__, "sd_blocksize", bus->blocksize)); - dhdsdio_tune_fifoparam(bus); + + if ((bus->sih->chip == BCM4335_CHIP_ID) || + (bus->sih->chip == BCM4339_CHIP_ID)) + dhd_overflow_war(bus); } } bus->roundup = MIN(max_roundup, bus->blocksize); @@ -4644,11 +4641,22 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) bus->hostintmask |= I_XMTDATA_AVAIL; } W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries); - - if (bus->sih->buscorerev < 15) { +#ifdef SDIO_CRC_ERROR_FIX + if (bus->blocksize < 512) { + mesbusyctrl = watermark = bus->blocksize / 4; + } +#endif /* SDIO_CRC_ERROR_FIX */ + if (!((bus->sih->chip == BCM4335_CHIP_ID) || + (bus->sih->chip == BCM4339_CHIP_ID))) { bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, (uint8)watermark, &err); } +#ifdef SDIO_CRC_ERROR_FIX + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_MESBUSYCTRL, + (uint8)mesbusyctrl|0x80, &err); + bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, + SBSDIO_DEVCTL_EN_F2_BLK_WATERMARK, NULL); +#endif /* SDIO_CRC_ERROR_FIX */ /* Set bus state according to enable result */ dhdp->busstate = DHD_BUS_DATA; @@ -7404,7 +7412,10 @@ dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) } else { DHD_INFO(("%s: Initial value for %s is %d\n", __FUNCTION__, "sd_blocksize", bus->blocksize)); - dhdsdio_tune_fifoparam(bus); + + if ((bus->sih->chip == BCM4335_CHIP_ID) || + (bus->sih->chip == BCM4339_CHIP_ID)) + dhd_overflow_war(bus); } bus->roundup = MIN(max_roundup, bus->blocksize); @@ -8286,30 +8297,3 @@ dhd_get_chipid(dhd_pub_t *dhd) else return 0; } - -#if defined(SOFTAP_TPUT_ENHANCE) -void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time) -{ - if (!dhdp || !dhdp->bus) { - DHD_ERROR(("%s:Bus is Invalid\n", __FUNCTION__)); - return; - } - - dhdp->bus->idletime = idle_time; -} - -void dhd_bus_getidletime(dhd_pub_t *dhdp, int* idle_time) -{ - if (!dhdp || !dhdp->bus) { - DHD_ERROR(("%s:Bus is Invalid\n", __FUNCTION__)); - return; - } - - if (!idle_time) { - DHD_ERROR(("%s:Arg idle_time is NULL\n", __FUNCTION__)); - return; - } - - *idle_time = dhdp->bus->idletime; -} -#endif /* SOFTAP_TPUT_ENHANCE */ |