Commit 0801e6c5 authored by Daniel Kim's avatar Daniel Kim Committed by John W. Linville
Browse files

brcmfmac: enable firmware console logging functionality



Address of rte console was not initialized and so console logging
functionality didn't kick in. This patch fixes it and makes console
polling interval a debugfs variable.

Reviewed-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarDaniel Kim <dekim@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0b0acd8c
Loading
Loading
Loading
Loading
+88 −66
Original line number Diff line number Diff line
@@ -953,6 +953,86 @@ end:

}

#ifdef DEBUG
static inline bool brcmf_sdio_valid_shared_address(u32 addr)
{
	return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
}

static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
				 struct sdpcm_shared *sh)
{
	u32 addr;
	int rv;
	u32 shaddr = 0;
	struct sdpcm_shared_le sh_le;
	__le32 addr_le;

	shaddr = bus->ci->rambase + bus->ramsize - 4;

	/*
	 * Read last word in socram to determine
	 * address of sdpcm_shared structure
	 */
	sdio_claim_host(bus->sdiodev->func[1]);
	brcmf_sdio_bus_sleep(bus, false, false);
	rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
	sdio_release_host(bus->sdiodev->func[1]);
	if (rv < 0)
		return rv;

	addr = le32_to_cpu(addr_le);

	brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);

	/*
	 * Check if addr is valid.
	 * NVRAM length at the end of memory should have been overwritten.
	 */
	if (!brcmf_sdio_valid_shared_address(addr)) {
			brcmf_err("invalid sdpcm_shared address 0x%08X\n",
				  addr);
			return -EINVAL;
	}

	/* Read hndrte_shared structure */
	rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
			       sizeof(struct sdpcm_shared_le));
	if (rv < 0)
		return rv;

	/* Endianness */
	sh->flags = le32_to_cpu(sh_le.flags);
	sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
	sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
	sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
	sh->assert_line = le32_to_cpu(sh_le.assert_line);
	sh->console_addr = le32_to_cpu(sh_le.console_addr);
	sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);

	if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
		brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
			  SDPCM_SHARED_VERSION,
			  sh->flags & SDPCM_SHARED_VERSION_MASK);
		return -EPROTO;
	}

	return 0;
}

static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
{
	struct sdpcm_shared sh;

	if (brcmf_sdio_readshared(bus, &sh) == 0)
		bus->console_addr = sh.console_addr;
}
#else
static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
{
}
#endif /* DEBUG */

static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
{
	u32 intstatus = 0;
@@ -996,6 +1076,12 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
		else
			brcmf_dbg(SDIO, "Dongle ready, protocol version %d\n",
				  bus->sdpcm_ver);

		/*
		 * Retrieve console state address now that firmware should have
		 * updated it.
		 */
		brcmf_sdio_get_console_addr(bus);
	}

	/*
@@ -2810,72 +2896,6 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
}

#ifdef DEBUG
static inline bool brcmf_sdio_valid_shared_address(u32 addr)
{
	return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
}

static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
				 struct sdpcm_shared *sh)
{
	u32 addr;
	int rv;
	u32 shaddr = 0;
	struct sdpcm_shared_le sh_le;
	__le32 addr_le;

	shaddr = bus->ci->rambase + bus->ramsize - 4;

	/*
	 * Read last word in socram to determine
	 * address of sdpcm_shared structure
	 */
	sdio_claim_host(bus->sdiodev->func[1]);
	brcmf_sdio_bus_sleep(bus, false, false);
	rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
	sdio_release_host(bus->sdiodev->func[1]);
	if (rv < 0)
		return rv;

	addr = le32_to_cpu(addr_le);

	brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);

	/*
	 * Check if addr is valid.
	 * NVRAM length at the end of memory should have been overwritten.
	 */
	if (!brcmf_sdio_valid_shared_address(addr)) {
			brcmf_err("invalid sdpcm_shared address 0x%08X\n",
				  addr);
			return -EINVAL;
	}

	/* Read hndrte_shared structure */
	rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
			       sizeof(struct sdpcm_shared_le));
	if (rv < 0)
		return rv;

	/* Endianness */
	sh->flags = le32_to_cpu(sh_le.flags);
	sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
	sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
	sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
	sh->assert_line = le32_to_cpu(sh_le.assert_line);
	sh->console_addr = le32_to_cpu(sh_le.console_addr);
	sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);

	if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
		brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
			  SDPCM_SHARED_VERSION,
			  sh->flags & SDPCM_SHARED_VERSION_MASK);
		return -EPROTO;
	}

	return 0;
}

static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
				   struct sdpcm_shared *sh, char __user *data,
				   size_t count)
@@ -3105,6 +3125,8 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
	debugfs_create_file("forensics", S_IRUGO, dentry, bus,
			    &brcmf_sdio_forensic_ops);
	brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
	debugfs_create_u32("console_interval", 0644, dentry,
			   &bus->console_interval);
}
#else
static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)