summaryrefslogtreecommitdiff
path: root/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch')
-rw-r--r--package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch347
1 files changed, 347 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch b/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch
new file mode 100644
index 0000000..4354a70
--- /dev/null
+++ b/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch
@@ -0,0 +1,347 @@
+From 00eb62cfc5f806b003fe5d54c8b5fe9a9665482f Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian@mnementh.co.uk>
+Date: Tue, 19 Dec 2017 13:47:13 +0100
+Subject: [PATCH] brcmfmac: Replace function index with function pointer
+
+In preparation for removing the function array, remove all code that
+refers to function by index and replace with pointers to the function
+itself.
+
+Signed-off-by: Ian Molton <ian@mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+[arend: replace BUG() with WARN() macro]
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 85 ++++++++++++----------
+ .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 15 ++--
+ .../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 6 +-
+ 3 files changed, 56 insertions(+), 50 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -291,8 +291,9 @@ out:
+ *ret = retval;
+ }
+
+-static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn,
+- u32 addr, struct sk_buff *pkt)
++static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev,
++ struct sdio_func *func, u32 addr,
++ struct sk_buff *pkt)
+ {
+ unsigned int req_sz;
+ int err;
+@@ -301,13 +302,19 @@ static int brcmf_sdiod_buff_read(struct
+ req_sz = pkt->len + 3;
+ req_sz &= (uint)~3;
+
+- if (fn == 1)
+- err = sdio_memcpy_fromio(sdiodev->func[fn],
+- ((u8 *)(pkt->data)), addr, req_sz);
+- else
+- /* function 2 read is FIFO operation */
+- err = sdio_readsb(sdiodev->func[fn],
+- ((u8 *)(pkt->data)), addr, req_sz);
++ switch (func->num) {
++ case 1:
++ err = sdio_memcpy_fromio(func, ((u8 *)(pkt->data)), addr,
++ req_sz);
++ break;
++ case 2:
++ err = sdio_readsb(func, ((u8 *)(pkt->data)), addr, req_sz);
++ break;
++ default:
++ /* bail out as things are really fishy here */
++ WARN(1, "invalid sdio function number: %d\n", func->num);
++ err = -ENOMEDIUM;
++ };
+
+ if (err == -ENOMEDIUM)
+ brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
+@@ -315,8 +322,9 @@ static int brcmf_sdiod_buff_read(struct
+ return err;
+ }
+
+-static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn,
+- u32 addr, struct sk_buff *pkt)
++static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev,
++ struct sdio_func *func, u32 addr,
++ struct sk_buff *pkt)
+ {
+ unsigned int req_sz;
+ int err;
+@@ -325,8 +333,7 @@ static int brcmf_sdiod_buff_write(struct
+ req_sz = pkt->len + 3;
+ req_sz &= (uint)~3;
+
+- err = sdio_memcpy_toio(sdiodev->func[fn], addr,
+- ((u8 *)(pkt->data)), req_sz);
++ err = sdio_memcpy_toio(func, addr, ((u8 *)(pkt->data)), req_sz);
+
+ if (err == -ENOMEDIUM)
+ brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
+@@ -337,7 +344,7 @@ static int brcmf_sdiod_buff_write(struct
+ /**
+ * brcmf_sdiod_sglist_rw - SDIO interface function for block data access
+ * @sdiodev: brcmfmac sdio device
+- * @fn: SDIO function number
++ * @func: SDIO function
+ * @write: direction flag
+ * @addr: dongle memory address as source/destination
+ * @pkt: skb pointer
+@@ -346,7 +353,8 @@ static int brcmf_sdiod_buff_write(struct
+ * stack for block data access. It assumes that the skb passed down by the
+ * caller has already been padded and aligned.
+ */
+-static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
++static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev,
++ struct sdio_func *func,
+ bool write, u32 addr,
+ struct sk_buff_head *pktlist)
+ {
+@@ -372,7 +380,7 @@ static int brcmf_sdiod_sglist_rw(struct
+ req_sz = 0;
+ skb_queue_walk(pktlist, pkt_next)
+ req_sz += pkt_next->len;
+- req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
++ req_sz = ALIGN(req_sz, func->cur_blksize);
+ while (req_sz > PAGE_SIZE) {
+ pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
+ if (pkt_next == NULL) {
+@@ -391,7 +399,7 @@ static int brcmf_sdiod_sglist_rw(struct
+ target_list = &local_list;
+ }
+
+- func_blk_sz = sdiodev->func[fn]->cur_blksize;
++ func_blk_sz = func->cur_blksize;
+ max_req_sz = sdiodev->max_request_size;
+ max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count,
+ target_list->qlen);
+@@ -408,10 +416,10 @@ static int brcmf_sdiod_sglist_rw(struct
+ mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+ mmc_cmd.opcode = SD_IO_RW_EXTENDED;
+ mmc_cmd.arg = write ? 1<<31 : 0; /* write flag */
+- mmc_cmd.arg |= (fn & 0x7) << 28; /* SDIO func num */
+- mmc_cmd.arg |= 1<<27; /* block mode */
++ mmc_cmd.arg |= (func->num & 0x7) << 28; /* SDIO func num */
++ mmc_cmd.arg |= 1 << 27; /* block mode */
+ /* for function 1 the addr will be incremented */
+- mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
++ mmc_cmd.arg |= (func->num == 1) ? 1 << 26 : 0;
+ mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+ mmc_req.cmd = &mmc_cmd;
+ mmc_req.data = &mmc_dat;
+@@ -457,11 +465,11 @@ static int brcmf_sdiod_sglist_rw(struct
+ mmc_cmd.arg |= (addr & 0x1FFFF) << 9; /* address */
+ mmc_cmd.arg |= mmc_dat.blocks & 0x1FF; /* block count */
+ /* incrementing addr for function 1 */
+- if (fn == 1)
++ if (func->num == 1)
+ addr += req_sz;
+
+- mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
+- mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req);
++ mmc_set_data_timeout(&mmc_dat, func->card);
++ mmc_wait_for_req(func->card->host, &mmc_req);
+
+ ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
+ if (ret == -ENOMEDIUM) {
+@@ -541,7 +549,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd
+ addr &= SBSDIO_SB_OFT_ADDR_MASK;
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt);
++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, pkt);
+
+ done:
+ return err;
+@@ -566,13 +574,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+ if (pktq->qlen == 1)
+- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr,
+ pktq->next);
+ else if (!sdiodev->sg_support) {
+ glom_skb = brcmu_pkt_buf_get_skb(totlen);
+ if (!glom_skb)
+ return -ENOMEM;
+- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr,
+ glom_skb);
+ if (err)
+ goto done;
+@@ -582,8 +590,8 @@ int brcmf_sdiod_recv_chain(struct brcmf_
+ skb_pull(glom_skb, skb->len);
+ }
+ } else
+- err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr,
+- pktq);
++ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], false,
++ addr, pktq);
+
+ done:
+ brcmu_pkt_buf_free_skb(glom_skb);
+@@ -614,7 +622,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
+ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+ if (!err)
+- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], addr,
++ mypkt);
+
+ brcmu_pkt_buf_free_skb(mypkt);
+
+@@ -639,14 +648,14 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
+
+ if (pktq->qlen == 1 || !sdiodev->sg_support) {
+ skb_queue_walk(pktq, skb) {
+- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2],
+ addr, skb);
+ if (err)
+ break;
+ }
+ } else {
+- err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr,
+- pktq);
++ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], true,
++ addr, pktq);
+ }
+
+ return err;
+@@ -696,10 +705,10 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
+
+ if (write) {
+ memcpy(pkt->data, data, dsize);
+- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1,
++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[1],
+ sdaddr, pkt);
+ } else {
+- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1,
++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[1],
+ sdaddr, pkt);
+ }
+
+@@ -728,12 +737,12 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
+ return err;
+ }
+
+-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn)
++int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func)
+ {
+ brcmf_dbg(SDIO, "Enter\n");
+
+ /* Issue abort cmd52 command through F0 */
+- brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL);
++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, func->num, NULL);
+
+ brcmf_dbg(SDIO, "Exit\n");
+ return 0;
+@@ -1105,7 +1114,7 @@ static int brcmf_ops_sdio_suspend(struct
+
+ func = container_of(dev, struct sdio_func, dev);
+ brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
+- if (func->num != SDIO_FUNC_1)
++ if (func->num != 1)
+ return 0;
+
+
+@@ -1134,7 +1143,7 @@ static int brcmf_ops_sdio_resume(struct
+ struct sdio_func *func = container_of(dev, struct sdio_func, dev);
+
+ brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
+- if (func->num != SDIO_FUNC_2)
++ if (func->num != 2)
+ return 0;
+
+ brcmf_sdiod_freezer_off(sdiodev);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -1157,7 +1157,7 @@ static void brcmf_sdio_rxfail(struct brc
+ rtx ? ", send NAK" : "");
+
+ if (abort)
+- brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
++ brcmf_sdiod_abort(bus->sdiodev, bus->sdiodev->func[2]);
+
+ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM,
+ &err);
+@@ -1209,7 +1209,7 @@ static void brcmf_sdio_txfail(struct brc
+ brcmf_err("sdio error, abort command and terminate frame\n");
+ bus->sdcnt.tx_sderrs++;
+
+- brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
++ brcmf_sdiod_abort(sdiodev, sdiodev->func[2]);
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
+ bus->sdcnt.f1regdata++;
+
+@@ -2072,7 +2072,7 @@ static int brcmf_sdio_txpkt_prep_sg(stru
+ int ntail, ret;
+
+ sdiodev = bus->sdiodev;
+- blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
++ blksize = sdiodev->func[2]->cur_blksize;
+ /* sg entry alignment should be a divisor of block size */
+ WARN_ON(blksize % bus->sgentry_align);
+
+@@ -2441,7 +2441,7 @@ static void brcmf_sdio_bus_stop(struct d
+
+ /* Turn off the bus (F2), free any pending packets */
+ brcmf_dbg(INTR, "disable SDIO interrupts\n");
+- sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
++ sdio_disable_func(sdiodev->func[2]);
+
+ /* Clear any pending interrupts now that F2 is disabled */
+ brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus),
+@@ -4066,8 +4066,7 @@ static void brcmf_sdio_firmware_callback
+ brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata),
+ SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL);
+
+- err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
+-
++ err = sdio_enable_func(sdiodev->func[2]);
+
+ brcmf_dbg(INFO, "enable F2: err=%d\n", err);
+
+@@ -4082,7 +4081,7 @@ static void brcmf_sdio_firmware_callback
+ brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err);
+ } else {
+ /* Disable F2 again */
+- sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
++ sdio_disable_func(sdiodev->func[2]);
+ goto release;
+ }
+
+@@ -4219,7 +4218,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
+ sdio_claim_host(bus->sdiodev->func[1]);
+
+ /* Disable F2 to clear any intermediate frame state on the dongle */
+- sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
++ sdio_disable_func(bus->sdiodev->func[2]);
+
+ bus->rxflow = false;
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+@@ -45,9 +45,6 @@
+ #define REG_F0_REG_MASK 0x7FF
+ #define REG_F1_MISC_MASK 0x1FFFF
+
+-/* as of sdiod rev 0, supports 3 functions */
+-#define SBSDIO_NUM_FUNCTION 3
+-
+ /* function 0 vendor specific CCCR registers */
+
+ #define SDIO_CCCR_BRCM_CARDCAP 0xf0
+@@ -350,7 +347,8 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_
+ u8 *data, uint size);
+
+ /* Issue an abort to the specified function */
+-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn);
++int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func);
++
+ void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev);
+ void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
+ enum brcmf_sdiod_state state);