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

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
...@@ -457,36 +457,80 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, ...@@ -457,36 +457,80 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
return err; return err;
} }
int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, int
u8 *buf, uint nbytes) brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
u8 *data, uint size)
{ {
struct sk_buff *mypkt; int bcmerror = 0;
bool write = rw ? SDIOH_WRITE : SDIOH_READ; struct sk_buff *pkt;
int err; 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;
addr &= SBSDIO_SB_OFT_ADDR_MASK; /* Determine initial transfer parameters */
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
else
dsize = size;
mypkt = brcmu_pkt_buf_get_skb(nbytes); sdio_claim_host(sdiodev->func[1]);
if (!mypkt) {
brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", /* Do the transfer(s) */
nbytes); while (size) {
return -EIO; /* 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(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);
/* 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 write, copy the buffer data into the packet. */ dev_kfree_skb(pkt);
if (write)
memcpy(mypkt->data, buf, nbytes);
err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write, /* Return the window to backplane enumeration space for core access */
SDIO_FUNC_1, addr, mypkt); if (brcmf_sdcard_set_sbaddr_window(sdiodev, sdiodev->sbwad))
brcmf_err("FAILED to set window back to 0x%x\n",
sdiodev->sbwad);
/* For a read, copy the packet data back to the buffer. */ sdio_release_host(sdiodev->func[1]);
if (!err && !write)
memcpy(buf, mypkt->data, nbytes);
brcmu_pkt_buf_free_skb(mypkt); return bcmerror;
return err;
} }
int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
......
...@@ -2486,69 +2486,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) ...@@ -2486,69 +2486,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
return ret; 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 #ifdef DEBUG
#define CONSOLE_LINE_MAX 192 #define CONSOLE_LINE_MAX 192
...@@ -2565,8 +2502,8 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) ...@@ -2565,8 +2502,8 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
/* Read console log struct */ /* Read console log struct */
addr = bus->console_addr + offsetof(struct rte_console, log_le); 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)); sizeof(c->log_le));
if (rv < 0) if (rv < 0)
return rv; return rv;
...@@ -2591,7 +2528,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) ...@@ -2591,7 +2528,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
/* Read the console buffer */ /* Read the console buffer */
addr = le32_to_cpu(c->log_le.buf); 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) if (rv < 0)
return rv; return rv;
...@@ -2812,8 +2749,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, ...@@ -2812,8 +2749,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
*/ */
sdio_claim_host(bus->sdiodev->func[1]); sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_bus_sleep(bus, false, false); brcmf_sdbrcm_bus_sleep(bus, false, false);
rv = brcmf_sdbrcm_membytes(bus, false, shaddr, rv = brcmf_sdio_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
(u8 *)&addr_le, 4);
sdio_release_host(bus->sdiodev->func[1]); sdio_release_host(bus->sdiodev->func[1]);
if (rv < 0) if (rv < 0)
return rv; return rv;
...@@ -2833,8 +2769,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, ...@@ -2833,8 +2769,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
} }
/* Read hndrte_shared structure */ /* 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)); sizeof(struct sdpcm_shared_le));
if (rv < 0) if (rv < 0)
return rv; return rv;
...@@ -2870,22 +2806,22 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, ...@@ -2870,22 +2806,22 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
/* obtain console information from device memory */ /* obtain console information from device memory */
addr = sh->console_addr + offsetof(struct rte_console, log_le); 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)); (u8 *)&sh_val, sizeof(u32));
if (rv < 0) if (rv < 0)
return rv; return rv;
console_ptr = le32_to_cpu(sh_val); console_ptr = le32_to_cpu(sh_val);
addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); 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)); (u8 *)&sh_val, sizeof(u32));
if (rv < 0) if (rv < 0)
return rv; return rv;
console_size = le32_to_cpu(sh_val); console_size = le32_to_cpu(sh_val);
addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); 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)); (u8 *)&sh_val, sizeof(u32));
if (rv < 0) if (rv < 0)
return rv; return rv;
console_index = le32_to_cpu(sh_val); console_index = le32_to_cpu(sh_val);
...@@ -2899,8 +2835,8 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, ...@@ -2899,8 +2835,8 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
/* obtain the console data from device */ /* obtain the console data from device */
conbuf[console_size] = '\0'; 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); console_size);
if (rv < 0) if (rv < 0)
goto done; goto done;
...@@ -2937,8 +2873,8 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, ...@@ -2937,8 +2873,8 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
return 0; 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)); sizeof(struct brcmf_trap_info));
if (error < 0) if (error < 0)
return error; return error;
...@@ -2981,14 +2917,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, ...@@ -2981,14 +2917,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
sdio_claim_host(bus->sdiodev->func[1]); sdio_claim_host(bus->sdiodev->func[1]);
if (sh->assert_file_addr != 0) { if (sh->assert_file_addr != 0) {
error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, error = brcmf_sdio_ramrw(bus->sdiodev, false,
(u8 *)file, 80); sh->assert_file_addr, (u8 *)file, 80);
if (error < 0) if (error < 0)
return error; return error;
} }
if (sh->assert_exp_addr != 0) { if (sh->assert_exp_addr != 0) {
error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr, error = brcmf_sdio_ramrw(bus->sdiodev, false,
(u8 *)expr, 80); sh->assert_exp_addr, (u8 *)expr, 80);
if (error < 0) if (error < 0)
return error; return error;
} }
...@@ -3162,8 +3098,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) ...@@ -3162,8 +3098,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
if (bus->vars) { if (bus->vars) {
/* Write the vars list */ /* Write the vars list */
bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, bcmerror = brcmf_sdio_ramrw(bus->sdiodev, true, varaddr,
bus->vars, bus->varsz); bus->vars, bus->varsz);
#ifdef DEBUG #ifdef DEBUG
/* Verify NVRAM bytes */ /* Verify NVRAM bytes */
brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n",
...@@ -3176,8 +3112,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) ...@@ -3176,8 +3112,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
memset(nvram_ularray, 0xaa, bus->varsz); memset(nvram_ularray, 0xaa, bus->varsz);
/* Read the vars list to temp buffer for comparison */ /* 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); nvram_ularray, bus->varsz);
if (bcmerror) { if (bcmerror) {
brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n",
bcmerror, bus->varsz, varaddr); bcmerror, bus->varsz, varaddr);
...@@ -3215,8 +3151,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) ...@@ -3215,8 +3151,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
bus->varsz, varsizew); bus->varsz, varsizew);
/* Write the length token to the last word */ /* 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); (u8 *)&varsizew_le, 4);
return bcmerror; return bcmerror;
} }
...@@ -3239,7 +3175,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) ...@@ -3239,7 +3175,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
/* Clear the top bit of memory */ /* Clear the top bit of memory */
if (bus->ramsize) { if (bus->ramsize) {
u32 zeros = 0; u32 zeros = 0;
brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4, brcmf_sdio_ramrw(bus->sdiodev, true, bus->ramsize - 4,
(u8 *)&zeros, 4); (u8 *)&zeros, 4);
} }
} else { } else {
...@@ -3308,7 +3244,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) ...@@ -3308,7 +3244,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
/* Download image */ /* Download image */
while ((len = while ((len =
brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) { 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) { if (ret) {
brcmf_err("error %d on writing %d membytes at 0x%08x\n", brcmf_err("error %d on writing %d membytes at 0x%08x\n",
ret, MEMBLOCK, offset); ret, MEMBLOCK, offset);
......
...@@ -242,6 +242,8 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, ...@@ -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, extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
u32 addr, u8 *buf, uint nbytes); 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 */ /* Issue an abort to the specified function */
extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
......
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