From 36cc2d0c3abcb07d8f804a0328c6a198e1564c7b Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Fri, 23 Sep 2011 13:49:14 -0700 Subject: [PATCH] net: wireless: bcmdhd: Fix SB address window caching Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/bcmdhd/bcmsdh.c | 116 ++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/bcmdhd/bcmsdh.c b/drivers/net/wireless/bcmdhd/bcmsdh.c index fc68b642e746..918c8e648f13 100644 --- a/drivers/net/wireless/bcmdhd/bcmsdh.c +++ b/drivers/net/wireless/bcmdhd/bcmsdh.c @@ -22,8 +22,13 @@ * 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: bcmsdh.c,v 1.57.6.4 2010-12-23 01:13:15 Exp $ + * $Id: bcmsdh.c 275784 2011-08-04 22:41:49Z $ */ + +/** + * @file bcmsdh.c + */ + /* ****************** BCMSDH Interface Functions *************************** */ #include @@ -36,14 +41,16 @@ #include /* BRCM API for SDIO clients (such as wl, dhd) */ #include /* common SDIO/controller interface */ -#include /* BRCM sdio device core */ +#include /* SDIO device core hardware definitions. */ -#include /* sdio spec */ +#include /* SDIO Device and Protocol Specs */ #define SDIOH_API_ACCESS_RETRY_LIMIT 2 const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; - +/** + * BCMSDH API context + */ struct bcmsdh_info { bool init_success; /* underlying driver successfully attached */ @@ -67,6 +74,15 @@ bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) } #endif +/* Attach BCMSDH layer to SDIO Host Controller Driver + * + * @param osh OSL Handle. + * @param cfghdl Configuration Handle. + * @param regsva Virtual address of controller registers. + * @param irq Interrupt number of SDIO controller. + * + * @return bcmsdh_info_t Handle to BCMSDH context. + */ bcmsdh_info_t * bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq) { @@ -201,6 +217,14 @@ bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) return BCME_UNSUPPORTED; } +/** + * Read from SDIO Configuration Space + * @param sdh SDIO Host context. + * @param func_num Function number to read from. + * @param addr Address to read from. + * @param err Error return. + * @return value read from SDIO configuration space. + */ uint8 bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err) { @@ -349,20 +373,30 @@ bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length) } -static int -bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address) +int +bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set) { int err = 0; + uint bar0 = address & ~SBSDIO_SB_OFT_ADDR_MASK; bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); - if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); + if (bar0 != bcmsdh->sbwad || force_set) { + bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, + (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); + if (!err) + bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, + (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); + if (!err) + bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, + (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); + + if (!err) + bcmsdh->sbwad = bar0; + else + /* invalidate cached window var */ + bcmsdh->sbwad = 0; + + } return err; } @@ -373,7 +407,6 @@ bcmsdh_reg_read(void *sdh, uint32 addr, uint size) bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; SDIOH_API_RC status; uint32 word = 0; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr)); @@ -382,12 +415,8 @@ bcmsdh_reg_read(void *sdh, uint32 addr, uint size) ASSERT(bcmsdh->init_success); - if (bar0 != bcmsdh->sbwad) { - if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0)) - return 0xFFFFFFFF; - - bcmsdh->sbwad = bar0; - } + if (bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)) + return 0xFFFFFFFF; addr &= SBSDIO_SB_OFT_ADDR_MASK; if (size == 4) @@ -425,7 +454,6 @@ bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; SDIOH_API_RC status; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", @@ -436,12 +464,8 @@ bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data) ASSERT(bcmsdh->init_success); - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } + if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) + return err; addr &= SBSDIO_SB_OFT_ADDR_MASK; if (size == 4) @@ -467,13 +491,12 @@ bcmsdh_regfail(void *sdh) int bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) + bcmsdh_cmplt_fn_t complete_fn, void *handle) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; SDIOH_API_RC status; uint incr_fix; uint width; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; ASSERT(bcmsdh); @@ -487,12 +510,8 @@ bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, if (flags & SDIO_REQ_ASYNC) return BCME_UNSUPPORTED; - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } + if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) + return err; addr &= SBSDIO_SB_OFT_ADDR_MASK; @@ -510,13 +529,12 @@ bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags, int bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, uint8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) + bcmsdh_cmplt_fn_t complete_fn, void *handle) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh; SDIOH_API_RC status; uint incr_fix; uint width; - uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; ASSERT(bcmsdh); @@ -530,12 +548,8 @@ bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags, if (flags & SDIO_REQ_ASYNC) return BCME_UNSUPPORTED; - if (bar0 != bcmsdh->sbwad) { - if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))) - return err; - - bcmsdh->sbwad = bar0; - } + if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE))) + return err; addr &= SBSDIO_SB_OFT_ADDR_MASK; @@ -660,3 +674,17 @@ bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev) { return; } + + +int +bcmsdh_sleep(void *sdh, bool enab) +{ +#ifdef SDIOH_SLEEP_ENABLED + bcmsdh_info_t *p = (bcmsdh_info_t *)sdh; + sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh); + + return sdioh_sleep(sd, enab); +#else + return BCME_UNSUPPORTED; +#endif +} -- 2.11.0