Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 278389
b: refs/heads/master
c: 5adfeb6
h: refs/heads/master
i:
  278387: 5d95737
v: v3
  • Loading branch information
Arend van Spriel authored and John W. Linville committed Nov 28, 2011
1 parent 4f13074 commit 7b8b549
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 78 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3030794fcae9b07d62a9ff7649a413dff0c88e01
refs/heads/master: 5adfeb632c52a6c15e98fa6465bdade6fff915d9
116 changes: 97 additions & 19 deletions trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,19 +222,12 @@ bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev)
return sdiodev->regfail;
}

int
brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags,
u8 *buf, uint nbytes, struct sk_buff *pkt)
static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
uint flags, uint width, u32 *addr)
{
int status;
uint incr_fix;
uint width;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;

brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);

/* Async not implemented yet */
if (flags & SDIO_REQ_ASYNC)
return -ENOTSUPP;
Expand All @@ -247,29 +240,114 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
sdiodev->sbwad = bar0;
}

addr &= SBSDIO_SB_OFT_ADDR_MASK;
*addr &= SBSDIO_SB_OFT_ADDR_MASK;

if (width == 4)
*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;

return 0;
}

int
brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, u8 *buf, uint nbytes)
{
struct sk_buff *mypkt;
int err;

mypkt = brcmu_pkt_buf_get_skb(nbytes);
if (!mypkt) {
brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
nbytes);
return -EIO;
}

err = brcmf_sdcard_recv_pkt(sdiodev, addr, fn, flags, mypkt);
if (!err)
memcpy(buf, mypkt->data, nbytes);

brcmu_pkt_buf_free_skb(mypkt);
return err;
}

int
brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, struct sk_buff *pkt)
{
uint incr_fix;
uint width;
int err = 0;

brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
fn, addr, pkt->len);

width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
if (err)
return err;

incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
fn, addr, width, 0, NULL, pkt);

return err;
}

int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, struct sk_buff_head *pktq)
{
uint incr_fix;
uint width;
int err = 0;

brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
fn, addr, pktq->qlen);

width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
if (width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
if (err)
return err;

status = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
fn, addr, width, nbytes, buf, pkt);
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr,
pktq);

return status;
return err;
}

int
brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt)
uint flags, u8 *buf, uint nbytes)
{
struct sk_buff *mypkt;
int err;

mypkt = brcmu_pkt_buf_get_skb(nbytes);
if (!mypkt) {
brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
nbytes);
return -EIO;
}

memcpy(mypkt->data, buf, nbytes);
err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, mypkt);

brcmu_pkt_buf_free_skb(mypkt);
return err;

}

int
brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, struct sk_buff *pkt)
{
uint incr_fix;
uint width;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;

brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
fn, addr, pkt->len);

/* Async not implemented yet */
if (flags & SDIO_REQ_ASYNC)
Expand All @@ -291,7 +369,7 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;

return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
addr, width, nbytes, buf, pkt);
addr, width, 0, NULL, pkt);
}

int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
Expand Down
97 changes: 72 additions & 25 deletions trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,79 @@ int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
return err_ret;
}

/* precondition: host controller is claimed */
static int
brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo,
uint func, uint addr, struct sk_buff *pkt, uint pktlen)
{
int err_ret = 0;

if ((write) && (!fifo)) {
err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
((u8 *) (pkt->data)), pktlen);
} else if (write) {
err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
((u8 *) (pkt->data)), pktlen);
} else if (fifo) {
err_ret = sdio_readsb(sdiodev->func[func],
((u8 *) (pkt->data)), addr, pktlen);
} else {
err_ret = sdio_memcpy_fromio(sdiodev->func[func],
((u8 *) (pkt->data)),
addr, pktlen);
}

return err_ret;
}

static int
brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
uint write, uint func, uint addr,
struct sk_buff *pkt)
{
bool fifo = (fix_inc == SDIOH_DATA_FIX);
int err_ret = 0;
uint pkt_len = pkt->len;

brcmf_dbg(TRACE, "Enter\n");

brcmf_pm_resume_wait(sdiodev, &sdiodev->request_packet_wait);
if (brcmf_pm_resume_error(sdiodev))
return -EIO;

/* Claim host controller */
sdio_claim_host(sdiodev->func[func]);

pkt_len += 3;
pkt_len &= 0xFFFFFFFC;

err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
addr, pkt, pkt_len);
if (err_ret) {
brcmf_dbg(ERROR, "%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
write ? "TX" : "RX", pkt, addr, pkt_len, err_ret);
} else {
brcmf_dbg(TRACE, "%s xfr'd %p, addr=0x%05x, len=%d\n",
write ? "TX" : "RX", pkt, addr, pkt_len);
}

/* Release host controller */
sdio_release_host(sdiodev->func[func]);

brcmf_dbg(TRACE, "Exit\n");
return err_ret;
}

int
brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
uint write, uint func, uint addr,
struct sk_buff_head *pktq)
{
bool fifo = (fix_inc == SDIOH_DATA_FIX);
u32 SGCount = 0;
int err_ret = 0;

struct sk_buff *pnext;
struct sk_buff *pkt;

brcmf_dbg(TRACE, "Enter\n");

Expand All @@ -223,43 +286,27 @@ brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc,

/* Claim host controller */
sdio_claim_host(sdiodev->func[func]);
for (pnext = pkt; pnext; pnext = pnext->next) {
uint pkt_len = pnext->len;

skb_queue_walk(pktq, pkt) {
uint pkt_len = pkt->len;
pkt_len += 3;
pkt_len &= 0xFFFFFFFC;

if ((write) && (!fifo)) {
err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
((u8 *) (pnext->data)),
pkt_len);
} else if (write) {
err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
((u8 *) (pnext->data)),
pkt_len);
} else if (fifo) {
err_ret = sdio_readsb(sdiodev->func[func],
((u8 *) (pnext->data)),
addr, pkt_len);
} else {
err_ret = sdio_memcpy_fromio(sdiodev->func[func],
((u8 *) (pnext->data)),
addr, pkt_len);
}

err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
addr, pkt, pkt_len);
if (err_ret) {
brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
write ? "TX" : "RX", pnext, SGCount, addr,
write ? "TX" : "RX", pkt, SGCount, addr,
pkt_len, err_ret);
} else {
brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
write ? "TX" : "RX", pnext, SGCount, addr,
write ? "TX" : "RX", pkt, SGCount, addr,
pkt_len);
}

if (!fifo)
addr += pkt_len;
SGCount++;

SGCount++;
}

/* Release host controller */
Expand Down
Loading

0 comments on commit 7b8b549

Please sign in to comment.