From 6182567d90eb0e3b9105cdd9c415569f2cd13925 Mon Sep 17 00:00:00 2001 From: Owen Huang Date: Sun, 25 Dec 2022 21:06:12 -0600 Subject: [PATCH 215/296] non-upstream: btsdio: enable export api for F3 transferring buffer 1. enable export api ifx_bus_send_buf for F3 transferring buffer 2. add argument function number (fn) to separate F2/F3 flow 3. function 3 use sdio_writesb to a FIFO of a SDIO function Signed-off-by: Owen Huang --- .../broadcom/brcm80211/brcmfmac/bcmsdh.c | 47 +++++++++++++++---- .../brcm80211/brcmfmac/bt_shared_sdio_ifx.c | 3 +- .../broadcom/brcm80211/brcmfmac/sdio.c | 2 +- .../broadcom/brcm80211/brcmfmac/sdio.h | 3 +- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index 925cc0f8a40c..0f0c2b6b085e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -328,7 +328,12 @@ static int brcmf_sdiod_skbuff_write(struct brcmf_sdio_dev *sdiodev, req_sz = skb->len + 3; req_sz &= (uint)~3; - err = sdio_memcpy_toio(func, addr, ((u8 *)(skb->data)), req_sz); + if (func->num == SDIO_FUNC_1 || func->num == SDIO_FUNC_2) + err = sdio_memcpy_toio(func, addr, ((u8 *)(skb->data)), req_sz); + else if (func->num == SDIO_FUNC_3) + err = sdio_writesb(func, addr, ((u8 *)(skb->data)), req_sz); + else + return -EINVAL; if (err == -ENOMEDIUM) brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); @@ -626,11 +631,35 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, return err; } -int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) +int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 fn, + u8 *buf, uint nbytes) { - struct sk_buff *mypkt; - u32 addr = sdiodev->cc_core->base; - int err; + struct sk_buff *mypkt = NULL; + struct sdio_func *func = NULL; + u32 base_addr = 0; + u32 send_addr = 0; + int err = 0; + + if (fn == 2) { + /* F2 is only DMA. HW ignore the address field in the cmd53 /cmd52. */ + base_addr = sdiodev->cc_core->base; + send_addr = base_addr & SBSDIO_SB_OFT_ADDR_MASK; + send_addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + func = sdiodev->func2; + } else if (fn == 3) { + /* F3 has registers and DMA. A DMA access is identified using the + * address value 0x0. If the address field has any other value, it + * won't be considered as F3 packet transfer. If the address corresponds + * to a valid F3 register address, driver will get proper response, + * otherwise driver will get error response. + */ + base_addr = 0; + send_addr = 0; + func = sdiodev->func3; + } else { + brcmf_err("invalid function number: %d\n", fn); + return -EINVAL; + } mypkt = brcmu_pkt_buf_get_skb(nbytes); @@ -642,14 +671,14 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) memcpy(mypkt->data, buf, nbytes); - err = brcmf_sdiod_set_backplane_window(sdiodev, addr); + err = brcmf_sdiod_set_backplane_window(sdiodev, base_addr); if (err) goto out; - addr &= SBSDIO_SB_OFT_ADDR_MASK; - addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + err = brcmf_sdiod_skbuff_write(sdiodev, func, send_addr, mypkt); - err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, mypkt); + brcmf_dbg(DATA, "F%d, base addr: 0x%x, send addr: 0x%x, size: %d, err: %d\n", + fn, base_addr, send_addr, mypkt->len, err); out: brcmu_pkt_buf_free_skb(mypkt); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio_ifx.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio_ifx.c index 28cad10e79c9..0d50f626f2c9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio_ifx.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bt_shared_sdio_ifx.c @@ -765,8 +765,7 @@ int inf_bus_send_buf(struct brcmf_bus *bus_if, u8 *buf, u32 nbytes) sdiodev = bus_if->bus_priv.sdio; sdio_claim_host(sdiodev->func1); - // wait for next commit for Tx - //err = brcmf_sdiod_send_buf(sdiodev, SDIO_FUNC_3, buf, nbytes); + err = brcmf_sdiod_send_buf(sdiodev, SDIO_FUNC_3, buf, nbytes); sdio_release_host(sdiodev->func1); brcmf_dbg(DATA, "F3 send nbytes: %d, err: %d\n", nbytes, err); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 1218d2ad66db..3a99975f739e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -2818,7 +2818,7 @@ static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio *bus, u8 *frame, u16 len) frame, min_t(u16, len, 16), "TxHdr:\n"); do { - ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len); + ret = brcmf_sdiod_send_buf(bus->sdiodev, SDIO_FUNC_2, frame, len); if (ret < 0) brcmf_sdio_txfail(bus); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h index 6faaeddc98a4..fa86cf932c51 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h @@ -398,7 +398,8 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, */ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff_head *pktq); -int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes); +int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 fn, + u8 *buf, uint nbytes); int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, u8 fn, struct sk_buff *pkt); -- 2.25.1