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

brcmfmac: replace brcmf_sdioh_request_buffer with brcmf_sdio_buffrw

Introducing a new SDIO block data access interface function
brcmf_sdio_buffrw. It will act as a unified interface function for any block
data access to WiFi dongle through SDIO interface. This patch enables
the support for single skb transmission.
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarArend van Spriel <arend@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 16035d51
...@@ -303,6 +303,49 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, ...@@ -303,6 +303,49 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
*ret = retval; *ret = retval;
} }
/**
* brcmf_sdio_buffrw - SDIO interface function for block data access
* @sdiodev: brcmfmac sdio device
* @fn: SDIO function number
* @write: direction flag
* @addr: dongle memory address as source/destination
* @pkt: skb pointer
*
* This function takes the respbonsibility as the interface function to MMC
* stack for block data access. It assumes that the skb passed down by the
* caller has already been padded and aligned.
*/
static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
bool write, u32 addr, struct sk_buff *pkt)
{
uint len;
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
if (brcmf_pm_resume_error(sdiodev))
return -EIO;
/* Single skb use the standard mmc interface */
if (!pkt->next) {
len = pkt->len + 3;
len &= (uint)~3;
if (write)
return sdio_memcpy_toio(sdiodev->func[fn], addr,
((u8 *)(pkt->data)), len);
else if (fn == 1)
return sdio_memcpy_fromio(sdiodev->func[fn],
((u8 *)(pkt->data)), addr,
len);
else
/* function 2 read is FIFO operation */
return sdio_readsb(sdiodev->func[fn],
((u8 *)(pkt->data)), addr, len);
}
brcmf_err("skb chain is not supported yet.\n");
return -EOPNOTSUPP;
}
static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
uint flags, uint width, u32 *addr) uint flags, uint width, u32 *addr)
{ {
...@@ -355,7 +398,6 @@ int ...@@ -355,7 +398,6 @@ int
brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, struct sk_buff *pkt) uint flags, struct sk_buff *pkt)
{ {
uint incr_fix;
uint width; uint width;
int err = 0; int err = 0;
...@@ -367,9 +409,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, ...@@ -367,9 +409,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
if (err) if (err)
goto done; goto done;
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt);
err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
fn, addr, pkt);
done: done:
return err; return err;
...@@ -424,7 +464,6 @@ int ...@@ -424,7 +464,6 @@ int
brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, struct sk_buff *pkt) uint flags, struct sk_buff *pkt)
{ {
uint incr_fix;
uint width; uint width;
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0; int err = 0;
...@@ -446,13 +485,11 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, ...@@ -446,13 +485,11 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
addr &= SBSDIO_SB_OFT_ADDR_MASK; addr &= SBSDIO_SB_OFT_ADDR_MASK;
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
if (width == 4) if (width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn, err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, pkt);
addr, pkt);
done: done:
return err; return err;
...@@ -501,9 +538,8 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, ...@@ -501,9 +538,8 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
skb_put(pkt, dsize); skb_put(pkt, dsize);
if (write) if (write)
memcpy(pkt->data, data, dsize); memcpy(pkt->data, data, dsize);
bcmerror = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write,
write, SDIO_FUNC_1, sdaddr, pkt);
sdaddr, pkt);
if (bcmerror) { if (bcmerror) {
brcmf_err("membytes transfer failed\n"); brcmf_err("membytes transfer failed\n");
break; break;
......
...@@ -66,7 +66,7 @@ MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); ...@@ -66,7 +66,7 @@ MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
static bool bool
brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
{ {
bool is_err = false; bool is_err = false;
...@@ -76,7 +76,7 @@ brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) ...@@ -76,7 +76,7 @@ brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
return is_err; return is_err;
} }
static void void
brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq) brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
{ {
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
...@@ -283,43 +283,6 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc, ...@@ -283,43 +283,6 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
return err_ret; return err_ret;
} }
/*
* This function takes a single DMA-able packet.
*/
int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
uint fix_inc, uint write, uint func, uint addr,
struct sk_buff *pkt)
{
int status;
uint pkt_len;
bool fifo = (fix_inc == SDIOH_DATA_FIX);
brcmf_dbg(SDIO, "Enter\n");
if (pkt == NULL)
return -EINVAL;
pkt_len = pkt->len;
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
if (brcmf_pm_resume_error(sdiodev))
return -EIO;
pkt_len += 3;
pkt_len &= (uint)~3;
status = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
addr, pkt, pkt_len);
if (status) {
brcmf_err("%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
write ? "TX" : "RX", pkt, addr, pkt_len, status);
} else {
brcmf_dbg(SDIO, "%s xfr'd %p, addr=0x%05x, len=%d\n",
write ? "TX" : "RX", pkt, addr, pkt_len);
}
return status;
}
static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
{ {
/* read 24 bits and return valid 17 bit addr */ /* read 24 bits and return valid 17 bit addr */
......
...@@ -274,10 +274,6 @@ brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, ...@@ -274,10 +274,6 @@ brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
/* read or write any buffer using cmd53 */ /* read or write any buffer using cmd53 */
extern int extern int
brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
uint fix_inc, uint rw, uint fnc_num, u32 addr,
struct sk_buff *pkt);
extern int
brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc, brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
uint write, uint func, uint addr, uint write, uint func, uint addr,
struct sk_buff_head *pktq); struct sk_buff_head *pktq);
...@@ -291,4 +287,8 @@ extern void brcmf_sdbrcm_disconnect(void *ptr); ...@@ -291,4 +287,8 @@ extern void brcmf_sdbrcm_disconnect(void *ptr);
extern void brcmf_sdbrcm_isr(void *arg); extern void brcmf_sdbrcm_isr(void *arg);
extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick);
extern void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev,
wait_queue_head_t *wq);
extern bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev);
#endif /* _BRCM_SDH_H_ */ #endif /* _BRCM_SDH_H_ */
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