From f27b19f4feb50cc7a22f435f3b8051ed9b0a1475 Mon Sep 17 00:00:00 2001 From: Wright Feng Date: Tue, 20 Jun 2017 05:11:24 -0500 Subject: [PATCH] MLK-18675-02 brcmfmac: Set F2 blksz and Watermark to 256 for 4373 We got SDIO_CRC_ERROR with 4373 on SDR104 when doing bi-directional throughput test. Setting F2 blocksize and enable watermark to 256 to guarantee the operation stability. Signed-off-by: Wright Feng Signed-off-by: Fugang Duan (Vipul: Fixed merge conflictts) Signed-off-by: Vipul Kumar --- .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 11 +++++++++- .../broadcom/brcm80211/brcmfmac/sdio.c | 22 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index d2f788d88668..8f9396d84392 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -54,6 +54,7 @@ #define SDIO_FUNC1_BLOCKSIZE 64 #define SDIO_FUNC2_BLOCKSIZE 512 +#define SDIO_4373_FUNC2_BLOCKSIZE 256 /* Maximum milliseconds to wait for F2 to come up */ #define SDIO_WAIT_F2RDY 3000 @@ -905,6 +906,7 @@ static void brcmf_sdiod_host_fixup(struct mmc_host *host) static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) { int ret = 0; + unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE; sdio_claim_host(sdiodev->func1); @@ -914,11 +916,18 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) sdio_release_host(sdiodev->func1); goto out; } - ret = sdio_set_block_size(sdiodev->func2, SDIO_FUNC2_BLOCKSIZE); + + if (sdiodev->func[0]->device == SDIO_DEVICE_ID_CYPRESS_4373) { + f2_blksz = SDIO_4373_FUNC2_BLOCKSIZE; + } + + ret = sdio_set_block_size(sdiodev->func[2], f2_blksz); if (ret) { brcmf_err("Failed to set F2 blocksize\n"); sdio_release_host(sdiodev->func1); goto out; + } else { + brcmf_dbg(SDIO, "set F2 blocksize to %d\n", f2_blksz); } /* increase F2 timeout */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index a907d7b065fa..1617207d348d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -49,6 +49,9 @@ #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) +#define DEFAULT_F2_WATERMARK 0x8 +#define CY_4373_F2_WATERMARK 0x40 + #ifdef DEBUG #define BRCMF_TRAP_INFO_SIZE 80 @@ -138,6 +141,8 @@ struct rte_console { /* 1: isolate internal sdio signals, put external pads in tri-state; requires * sdio bus power cycle to clear (rev 9) */ #define SBSDIO_DEVCTL_PADS_ISO 0x08 +/* 1: enable F2 Watermark */ +#define SBSDIO_DEVCTL_F2WM_ENAB 0x10 /* Force SD->SB reset mapping (rev 11) */ #define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Determined by CoreControl bit */ @@ -4049,6 +4054,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, void *nvram; u32 nvram_len; u8 saveclk; + u8 devctl; brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); @@ -4103,9 +4109,19 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, bus->hostintmask = HOSTINTMASK; brcmf_sdiod_writel(sdiod, core->base + SD_REG(hostintmask), bus->hostintmask, NULL); - - - brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, 8, &err); + switch (sdiodev->func[0]->device) { + case SDIO_DEVICE_ID_CYPRESS_4373: + brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes for 4373\n", + CY_4373_F2_WATERMARK); + brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, CY_4373_F2_WATERMARK, &err); + devctl = brcmf_sdiod_regrb(sdiodev, SBSDIO_DEVICE_CTL, &err); + devctl |= SBSDIO_DEVCTL_F2WM_ENAB; + brcmf_sdiod_regwb(sdiodev, SBSDIO_DEVICE_CTL, devctl, &err); + break; + default: + brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, DEFAULT_F2_WATERMARK, &err); + break; + } } else { /* Disable F2 again */ sdio_disable_func(sdiod->func2); -- 2.17.1