Commit 9819a902 authored by Arend van Spriel's avatar Arend van Spriel Committed by Kalle Valo

brcmfmac: take save&restore memory into account for SDIO shared info

The firmware provides pointer to SDIO shared information at end of
RAM during firmware initialization. End of RAM is obviously determined
by the actual ram size, but part of that may be used for save&restore
memory. In that case another location in RAM will hold the pointer.
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 0da32ba4
...@@ -1067,44 +1067,47 @@ static inline bool brcmf_sdio_valid_shared_address(u32 addr) ...@@ -1067,44 +1067,47 @@ static inline bool brcmf_sdio_valid_shared_address(u32 addr)
static int brcmf_sdio_readshared(struct brcmf_sdio *bus, static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
struct sdpcm_shared *sh) struct sdpcm_shared *sh)
{ {
u32 addr; u32 addr = 0;
int rv; int rv;
u32 shaddr = 0; u32 shaddr = 0;
struct sdpcm_shared_le sh_le; struct sdpcm_shared_le sh_le;
__le32 addr_le; __le32 addr_le;
shaddr = bus->ci->rambase + bus->ci->ramsize - 4; sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdio_bus_sleep(bus, false, false);
/* /*
* Read last word in socram to determine * Read last word in socram to determine
* address of sdpcm_shared structure * address of sdpcm_shared structure
*/ */
sdio_claim_host(bus->sdiodev->func[1]); shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
brcmf_sdio_bus_sleep(bus, false, false); if (!bus->ci->rambase && brcmf_chip_sr_capable(bus->ci))
rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); shaddr -= bus->ci->srsize;
sdio_release_host(bus->sdiodev->func[1]); rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr,
(u8 *)&addr_le, 4);
if (rv < 0) if (rv < 0)
return rv; goto fail;
addr = le32_to_cpu(addr_le);
brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
/* /*
* Check if addr is valid. * Check if addr is valid.
* NVRAM length at the end of memory should have been overwritten. * NVRAM length at the end of memory should have been overwritten.
*/ */
addr = le32_to_cpu(addr_le);
if (!brcmf_sdio_valid_shared_address(addr)) { if (!brcmf_sdio_valid_shared_address(addr)) {
brcmf_err("invalid sdpcm_shared address 0x%08X\n", brcmf_err("invalid sdpcm_shared address 0x%08X\n", addr);
addr); rv = -EINVAL;
return -EINVAL; goto fail;
} }
brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr);
/* Read hndrte_shared structure */ /* Read hndrte_shared structure */
rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
sizeof(struct sdpcm_shared_le)); sizeof(struct sdpcm_shared_le));
if (rv < 0) if (rv < 0)
return rv; goto fail;
sdio_release_host(bus->sdiodev->func[1]);
/* Endianness */ /* Endianness */
sh->flags = le32_to_cpu(sh_le.flags); sh->flags = le32_to_cpu(sh_le.flags);
...@@ -1121,8 +1124,13 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, ...@@ -1121,8 +1124,13 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
sh->flags & SDPCM_SHARED_VERSION_MASK); sh->flags & SDPCM_SHARED_VERSION_MASK);
return -EPROTO; return -EPROTO;
} }
return 0; return 0;
fail:
brcmf_err("unable to obtain sdpcm_shared info: rv=%d (addr=0x%x)\n",
rv, addr);
sdio_release_host(bus->sdiodev->func[1]);
return rv;
} }
static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus) static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment