Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba540b01 authored by Franky Lin's avatar Franky Lin Committed by John W. Linville
Browse files

brcmfmac: aggregate dongle ram access interface



For fullmac chips host driver can access to dongle RAM through SDIO function 1.
Introduce brcmf_sdio_ramrw and place it at bcmsdh.c with other interface
functions.

Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4a3da990
Loading
Loading
Loading
Loading
+66 −22
Original line number Diff line number Diff line
@@ -457,36 +457,80 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
	return err;
}

int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
			u8 *buf, uint nbytes)
int
brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
		 u8 *data, uint size)
{
	struct sk_buff *mypkt;
	bool write = rw ? SDIOH_WRITE : SDIOH_READ;
	int err;

	addr &= SBSDIO_SB_OFT_ADDR_MASK;
	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;

	mypkt = brcmu_pkt_buf_get_skb(nbytes);
	if (!mypkt) {
		brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
			  nbytes);
	int bcmerror = 0;
	struct sk_buff *pkt;
	u32 sdaddr;
	uint dsize;

	dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
	pkt = dev_alloc_skb(dsize);
	if (!pkt) {
		brcmf_err("dev_alloc_skb failed: len %d\n", dsize);
		return -EIO;
	}
	pkt->priority = 0;

	/* Determine initial transfer parameters */
	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
	else
		dsize = size;

	sdio_claim_host(sdiodev->func[1]);

	/* For a write, copy the buffer data into the packet. */
	/* Do the transfer(s) */
	while (size) {
		/* Set the backplane window to include the start address */
		bcmerror = brcmf_sdcard_set_sbaddr_window(sdiodev, address);
		if (bcmerror)
			break;

		brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
			  write ? "write" : "read", dsize,
			  sdaddr, address & SBSDIO_SBWINDOW_MASK);

		sdaddr &= SBSDIO_SB_OFT_ADDR_MASK;
		sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG;

		skb_put(pkt, dsize);
		if (write)
		memcpy(mypkt->data, buf, nbytes);
			memcpy(pkt->data, data, dsize);
		bcmerror = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
						      write, SDIO_FUNC_1,
						      sdaddr, pkt);
		if (bcmerror) {
			brcmf_err("membytes transfer failed\n");
			break;
		}
		if (!write)
			memcpy(data, pkt->data, dsize);
		skb_trim(pkt, dsize);

	err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write,
					 SDIO_FUNC_1, addr, mypkt);
		/* Adjust for next transfer (if any) */
		size -= dsize;
		if (size) {
			data += dsize;
			address += dsize;
			sdaddr = 0;
			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
		}
	}

	/* For a read, copy the packet data back to the buffer. */
	if (!err && !write)
		memcpy(buf, mypkt->data, nbytes);
	dev_kfree_skb(pkt);

	brcmu_pkt_buf_free_skb(mypkt);
	return err;
	/* Return the window to backplane enumeration space for core access */
	if (brcmf_sdcard_set_sbaddr_window(sdiodev, sdiodev->sbwad))
		brcmf_err("FAILED to set window back to 0x%x\n",
			  sdiodev->sbwad);

	sdio_release_host(sdiodev->func[1]);

	return bcmerror;
}

int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
+28 −92
Original line number Diff line number Diff line
@@ -2486,69 +2486,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
	return ret;
}

static int
brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data,
		 uint size)
{
	int bcmerror = 0;
	u32 sdaddr;
	uint dsize;

	/* Determine initial transfer parameters */
	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
	else
		dsize = size;

	sdio_claim_host(bus->sdiodev->func[1]);

	/* Set the backplane window to include the start address */
	bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
	if (bcmerror) {
		brcmf_err("window change failed\n");
		goto xfer_done;
	}

	/* Do the transfer(s) */
	while (size) {
		brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
			  write ? "write" : "read", dsize,
			  sdaddr, address & SBSDIO_SBWINDOW_MASK);
		bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
					       sdaddr, data, dsize);
		if (bcmerror) {
			brcmf_err("membytes transfer failed\n");
			break;
		}

		/* Adjust for next transfer (if any) */
		size -= dsize;
		if (size) {
			data += dsize;
			address += dsize;
			bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev,
								  address);
			if (bcmerror) {
				brcmf_err("window change failed\n");
				break;
			}
			sdaddr = 0;
			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
		}
	}

xfer_done:
	/* Return the window to backplane enumeration space for core access */
	if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad))
		brcmf_err("FAILED to set window back to 0x%x\n",
			  bus->sdiodev->sbwad);

	sdio_release_host(bus->sdiodev->func[1]);

	return bcmerror;
}

#ifdef DEBUG
#define CONSOLE_LINE_MAX	192

@@ -2565,7 +2502,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)

	/* Read console log struct */
	addr = bus->console_addr + offsetof(struct rte_console, log_le);
	rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le,
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le,
			      sizeof(c->log_le));
	if (rv < 0)
		return rv;
@@ -2591,7 +2528,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)

	/* Read the console buffer */
	addr = le32_to_cpu(c->log_le.buf);
	rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize);
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize);
	if (rv < 0)
		return rv;

@@ -2812,8 +2749,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
	 */
	sdio_claim_host(bus->sdiodev->func[1]);
	brcmf_sdbrcm_bus_sleep(bus, false, false);
	rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
				   (u8 *)&addr_le, 4);
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
	sdio_release_host(bus->sdiodev->func[1]);
	if (rv < 0)
		return rv;
@@ -2833,7 +2769,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
	}

	/* Read hndrte_shared structure */
	rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
			      sizeof(struct sdpcm_shared_le));
	if (rv < 0)
		return rv;
@@ -2870,21 +2806,21 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,

	/* obtain console information from device memory */
	addr = sh->console_addr + offsetof(struct rte_console, log_le);
	rv = brcmf_sdbrcm_membytes(bus, false, addr,
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr,
			      (u8 *)&sh_val, sizeof(u32));
	if (rv < 0)
		return rv;
	console_ptr = le32_to_cpu(sh_val);

	addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size);
	rv = brcmf_sdbrcm_membytes(bus, false, addr,
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr,
			      (u8 *)&sh_val, sizeof(u32));
	if (rv < 0)
		return rv;
	console_size = le32_to_cpu(sh_val);

	addr = sh->console_addr + offsetof(struct rte_console, log_le.idx);
	rv = brcmf_sdbrcm_membytes(bus, false, addr,
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr,
			      (u8 *)&sh_val, sizeof(u32));
	if (rv < 0)
		return rv;
@@ -2899,7 +2835,7 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,

	/* obtain the console data from device */
	conbuf[console_size] = '\0';
	rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf,
	rv = brcmf_sdio_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf,
			      console_size);
	if (rv < 0)
		goto done;
@@ -2937,7 +2873,7 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
		return 0;
	}

	error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
	error = brcmf_sdio_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr,
				 sizeof(struct brcmf_trap_info));
	if (error < 0)
		return error;
@@ -2981,14 +2917,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,

	sdio_claim_host(bus->sdiodev->func[1]);
	if (sh->assert_file_addr != 0) {
		error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
					      (u8 *)file, 80);
		error = brcmf_sdio_ramrw(bus->sdiodev, false,
					 sh->assert_file_addr, (u8 *)file, 80);
		if (error < 0)
			return error;
	}
	if (sh->assert_exp_addr != 0) {
		error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr,
					      (u8 *)expr, 80);
		error = brcmf_sdio_ramrw(bus->sdiodev, false,
					 sh->assert_exp_addr, (u8 *)expr, 80);
		if (error < 0)
			return error;
	}
@@ -3162,7 +3098,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)

	if (bus->vars) {
		/* Write the vars list */
		bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr,
		bcmerror = brcmf_sdio_ramrw(bus->sdiodev, true, varaddr,
					    bus->vars, bus->varsz);
#ifdef DEBUG
		/* Verify NVRAM bytes */
@@ -3176,7 +3112,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
		memset(nvram_ularray, 0xaa, bus->varsz);

		/* Read the vars list to temp buffer for comparison */
		bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr,
		bcmerror = brcmf_sdio_ramrw(bus->sdiodev, false, varaddr,
					    nvram_ularray, bus->varsz);
		if (bcmerror) {
			brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n",
@@ -3215,7 +3151,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
		  bus->varsz, varsizew);

	/* Write the length token to the last word */
	bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
	bcmerror = brcmf_sdio_ramrw(bus->sdiodev, true, (bus->ramsize - 4),
				    (u8 *)&varsizew_le, 4);

	return bcmerror;
@@ -3239,7 +3175,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
		/* Clear the top bit of memory */
		if (bus->ramsize) {
			u32 zeros = 0;
			brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4,
			brcmf_sdio_ramrw(bus->sdiodev, true, bus->ramsize - 4,
					 (u8 *)&zeros, 4);
		}
	} else {
@@ -3308,7 +3244,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
	/* Download image */
	while ((len =
		brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
		ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len);
		ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len);
		if (ret) {
			brcmf_err("error %d on writing %d membytes at 0x%08x\n",
				  ret, MEMBLOCK, offset);
+2 −0
Original line number Diff line number Diff line
@@ -242,6 +242,8 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 */
extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
			       u32 addr, u8 *buf, uint nbytes);
extern int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write,
			    u32 address, u8 *data, uint size);

/* Issue an abort to the specified function */
extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);