mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-27 12:53:34 +07:00
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: Arend van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
4a3da9906b
commit
ba540b01a9
@ -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;
|
||||||
|
|
||||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
|
||||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
pkt = dev_alloc_skb(dsize);
|
||||||
|
if (!pkt) {
|
||||||
mypkt = brcmu_pkt_buf_get_skb(nbytes);
|
brcmf_err("dev_alloc_skb failed: len %d\n", dsize);
|
||||||
if (!mypkt) {
|
|
||||||
brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
|
|
||||||
nbytes);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
pkt->priority = 0;
|
||||||
|
|
||||||
/* For a write, copy the buffer data into the packet. */
|
/* Determine initial transfer parameters */
|
||||||
if (write)
|
sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
|
||||||
memcpy(mypkt->data, buf, nbytes);
|
if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
|
||||||
|
dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
|
||||||
|
else
|
||||||
|
dsize = size;
|
||||||
|
|
||||||
err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write,
|
sdio_claim_host(sdiodev->func[1]);
|
||||||
SDIO_FUNC_1, addr, mypkt);
|
|
||||||
|
|
||||||
/* For a read, copy the packet data back to the buffer. */
|
/* Do the transfer(s) */
|
||||||
if (!err && !write)
|
while (size) {
|
||||||
memcpy(buf, mypkt->data, nbytes);
|
/* Set the backplane window to include the start address */
|
||||||
|
bcmerror = brcmf_sdcard_set_sbaddr_window(sdiodev, address);
|
||||||
|
if (bcmerror)
|
||||||
|
break;
|
||||||
|
|
||||||
brcmu_pkt_buf_free_skb(mypkt);
|
brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
|
||||||
return err;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_kfree_skb(pkt);
|
||||||
|
|
||||||
|
/* 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)
|
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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
|
|
||||||
/* 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,
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
/* 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,
|
|||||||
*/
|
*/
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user