[openwrt/openwrt] mac80211: brcmfmac: restructuring sdio access functions - take 2

LEDE Commits lede-commits at lists.infradead.org
Thu Mar 1 09:30:51 PST 2018


rmilecki pushed a commit to openwrt/openwrt.git, branch master:
https://git.lede-project.org/66bdf62a2ad2a6c2d339a6949b647301994e629d

commit 66bdf62a2ad2a6c2d339a6949b647301994e629d
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Thu Mar 1 18:15:43 2018 +0100

    mac80211: brcmfmac: restructuring sdio access functions - take 2
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 ...fmac-Split-brcmf_sdiod_buffrw-function-up.patch | 143 ++++
 ...-whitespace-fixes-in-brcmf_sdiod_send_buf.patch |  34 +
 ....16-0003-brcmfmac-Clarify-if-using-braces.patch |  36 +
 ...name-replace-old-IO-functions-with-simple.patch | 831 +++++++++++++++++++++
 ...cmfmac-Tidy-register-definitions-a-little.patch |  59 ++
 ...0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch | 190 +++++
 ...move-unnecessary-call-to-brcmf_sdiod_set_.patch |  32 +
 .../312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch | 134 ++++
 ...2-v4.16-0009-brcmfmac-Remove-unused-macro.patch |  26 +
 ...move-repeated-calls-to-brcmf_chip_get_cor.patch | 128 ++++
 10 files changed, 1613 insertions(+)

diff --git a/package/kernel/mac80211/patches/312-v4.16-0001-brcmfmac-Split-brcmf_sdiod_buffrw-function-up.patch b/package/kernel/mac80211/patches/312-v4.16-0001-brcmfmac-Split-brcmf_sdiod_buffrw-function-up.patch
new file mode 100644
index 0000000..c260b96
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0001-brcmfmac-Split-brcmf_sdiod_buffrw-function-up.patch
@@ -0,0 +1,143 @@
+From 8f13c87ccc495e30de5f58bbda967f6edd5bec53 Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:26 +0100
+Subject: [PATCH] brcmfmac: Split brcmf_sdiod_buffrw function up.
+
+This function needs to be split up into separate read / write variants
+for clarity.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 67 +++++++++++++++-------
+ 1 file changed, 45 insertions(+), 22 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -414,8 +414,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio
+ 		*ret = retval;
+ }
+ 
+-static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
+-			     bool write, u32 addr, struct sk_buff *pkt)
++static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn,
++				 u32 addr, struct sk_buff *pkt)
+ {
+ 	unsigned int req_sz;
+ 	int err;
+@@ -424,18 +424,36 @@ static int brcmf_sdiod_buffrw(struct brc
+ 	req_sz = pkt->len + 3;
+ 	req_sz &= (uint)~3;
+ 
+-	if (write)
+-		err = sdio_memcpy_toio(sdiodev->func[fn], addr,
+-				       ((u8 *)(pkt->data)), req_sz);
+-	else if (fn == 1)
+-		err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)),
+-					 addr, req_sz);
++	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);
++		err = sdio_readsb(sdiodev->func[fn],
++				  ((u8 *)(pkt->data)), addr, req_sz);
++
++	if (err == -ENOMEDIUM)
++		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
++
++	return err;
++}
++
++static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn,
++				  u32 addr, struct sk_buff *pkt)
++{
++	unsigned int req_sz;
++	int err;
++
++	/* Single skb use the standard mmc interface */
++	req_sz = pkt->len + 3;
++	req_sz &= (uint)~3;
++
++	err = sdio_memcpy_toio(sdiodev->func[fn], addr,
++			       ((u8 *)(pkt->data)), req_sz);
++
+ 	if (err == -ENOMEDIUM)
+ 		brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
++
+ 	return err;
+ }
+ 
+@@ -643,7 +661,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd
+ 	if (err)
+ 		goto done;
+ 
+-	err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt);
++	err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt);
+ 
+ done:
+ 	return err;
+@@ -665,14 +683,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_
+ 		goto done;
+ 
+ 	if (pktq->qlen == 1)
+-		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
+-					 pktq->next);
++		err = brcmf_sdiod_buff_read(sdiodev, SDIO_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_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
+-					 glom_skb);
++		err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
++					    glom_skb);
+ 		if (err)
+ 			goto done;
+ 
+@@ -707,8 +725,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
+ 	err = brcmf_sdiod_addrprep(sdiodev, &addr);
+ 
+ 	if (!err)
+-		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
+-					 mypkt);
++		err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
+ 
+ 	brcmu_pkt_buf_free_skb(mypkt);
+ 	return err;
+@@ -730,8 +747,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
+ 
+ 	if (pktq->qlen == 1 || !sdiodev->sg_support)
+ 		skb_queue_walk(pktq, skb) {
+-			err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true,
+-						 addr, skb);
++			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
++						     addr, skb);
+ 			if (err)
+ 				break;
+ 		}
+@@ -783,10 +800,16 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
+ 		sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ 
+ 		skb_put(pkt, dsize);
+-		if (write)
++
++		if (write) {
+ 			memcpy(pkt->data, data, dsize);
+-		err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr,
+-					 pkt);
++			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1,
++						     sdaddr, pkt);
++		} else {
++			err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1,
++						    sdaddr, pkt);
++		}
++
+ 		if (err) {
+ 			brcmf_err("membytes transfer failed\n");
+ 			break;
diff --git a/package/kernel/mac80211/patches/312-v4.16-0002-brcmfmac-whitespace-fixes-in-brcmf_sdiod_send_buf.patch b/package/kernel/mac80211/patches/312-v4.16-0002-brcmfmac-whitespace-fixes-in-brcmf_sdiod_send_buf.patch
new file mode 100644
index 0000000..088a616
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0002-brcmfmac-whitespace-fixes-in-brcmf_sdiod_send_buf.patch
@@ -0,0 +1,34 @@
+From 6e24dd012bfda479d0046f7995058f167e1923bc Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:27 +0100
+Subject: [PATCH] brcmfmac: whitespace fixes in brcmf_sdiod_send_buf()
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+[arend: mention function in patch subject]
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -714,6 +714,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
+ 	int err;
+ 
+ 	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++
+ 	if (!mypkt) {
+ 		brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
+ 			  nbytes);
+@@ -728,8 +729,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
+ 		err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
+ 
+ 	brcmu_pkt_buf_free_skb(mypkt);
+-	return err;
+ 
++	return err;
+ }
+ 
+ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
diff --git a/package/kernel/mac80211/patches/312-v4.16-0003-brcmfmac-Clarify-if-using-braces.patch b/package/kernel/mac80211/patches/312-v4.16-0003-brcmfmac-Clarify-if-using-braces.patch
new file mode 100644
index 0000000..a44155b
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0003-brcmfmac-Clarify-if-using-braces.patch
@@ -0,0 +1,36 @@
+From a7323378dcf1f10a98f47b744e6f65e6fd671d84 Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:28 +0100
+Subject: [PATCH] brcmfmac: Clarify if using braces.
+
+Whilst this if () statement is technically correct, it lacks clarity.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -746,16 +746,17 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
+ 	if (err)
+ 		return err;
+ 
+-	if (pktq->qlen == 1 || !sdiodev->sg_support)
++	if (pktq->qlen == 1 || !sdiodev->sg_support) {
+ 		skb_queue_walk(pktq, skb) {
+ 			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
+ 						     addr, skb);
+ 			if (err)
+ 				break;
+ 		}
+-	else
++	} else {
+ 		err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr,
+ 					    pktq);
++	}
+ 
+ 	return err;
+ }
diff --git a/package/kernel/mac80211/patches/312-v4.16-0004-brcmfmac-Rename-replace-old-IO-functions-with-simple.patch b/package/kernel/mac80211/patches/312-v4.16-0004-brcmfmac-Rename-replace-old-IO-functions-with-simple.patch
new file mode 100644
index 0000000..7aa3de9
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0004-brcmfmac-Rename-replace-old-IO-functions-with-simple.patch
@@ -0,0 +1,831 @@
+From 71bd508d7ded8c504ef05d1b4befecfe25e54cb1 Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:29 +0100
+Subject: [PATCH] brcmfmac: Rename / replace old IO functions with simpler
+ ones.
+
+Primarily this patch removes:
+
+brcmf_sdiod_f0_writeb()
+brcmf_sdiod_reg_write()
+brcmf_sdiod_reg_read()
+
+Since we no longer use the quirky method of deciding which function to
+address via the address being accessed, take the opportunity to rename
+some IO functions more in line with common kernel code. We also convert
+those that map directly to sdio_{read,write}*() to macros.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 169 +++----------------
+ .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 186 ++++++++++-----------
+ .../wireless/broadcom/brcm80211/brcmfmac/sdio.h    |  28 +++-
+ 3 files changed, 138 insertions(+), 245 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -137,27 +137,27 @@ int brcmf_sdiod_intr_register(struct brc
+ 		if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
+ 			/* assign GPIO to SDIO core */
+ 			addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
+-			gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret);
++			gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret);
+ 			gpiocontrol |= 0x2;
+-			brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret);
++			brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret);
+ 
+-			brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
+-					  &ret);
+-			brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
+-			brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
++			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT,
++					   0xf, &ret);
++			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
++			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
+ 		}
+ 
+ 		/* must configure SDIO_CCCR_IENx to enable irq */
+-		data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
++		data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret);
+ 		data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
+-		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
++		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);
+ 
+ 		/* redirect, configure and enable io for interrupt signal */
+ 		data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
+ 		if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
+ 			data |= SDIO_SEPINT_ACT_HI;
+-		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
+-
++		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT,
++				     data, &ret);
+ 		sdio_release_host(sdiodev->func[1]);
+ 	} else {
+ 		brcmf_dbg(SDIO, "Entering\n");
+@@ -183,8 +183,8 @@ void brcmf_sdiod_intr_unregister(struct
+ 
+ 		pdata = &sdiodev->settings->bus.sdio;
+ 		sdio_claim_host(sdiodev->func[1]);
+-		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
+-		brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
++		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
++		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
+ 		sdio_release_host(sdiodev->func[1]);
+ 
+ 		sdiodev->oob_irq_requested = false;
+@@ -242,8 +242,8 @@ static int brcmf_sdiod_set_sbaddr_window
+ 	addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
+ 
+ 	for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
+-		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
+-				  addr & 0xff, &err);
++		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
++				   addr & 0xff, &err);
+ 
+ 	return err;
+ }
+@@ -267,124 +267,15 @@ static int brcmf_sdiod_addrprep(struct b
+ 	return 0;
+ }
+ 
+-static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
+-					uint regaddr)
+-{
+-	int err_ret;
+-
+-	/*
+-	 * Can only directly write to some F0 registers.
+-	 * Handle CCCR_IENx and CCCR_ABORT command
+-	 * as a special case.
+-	 */
+-	if ((regaddr == SDIO_CCCR_ABORT) ||
+-	    (regaddr == SDIO_CCCR_IENx))
+-		sdio_writeb(func, byte, regaddr, &err_ret);
+-	else
+-		sdio_f0_writeb(func, byte, regaddr, &err_ret);
+-
+-	return err_ret;
+-}
+-
+-static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
+-				 u8 regsz, void *data)
+-{
+-	int ret;
+-
+-	/*
+-	 * figure out how to read the register based on address range
+-	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
+-	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
+-	 * The rest: function 1 silicon backplane core registers
+-	 * f0 writes must be bytewise
+-	 */
+-
+-	if ((addr & ~REG_F0_REG_MASK) == 0) {
+-		if (WARN_ON(regsz > 1))
+-			return -EINVAL;
+-		ret = brcmf_sdiod_f0_writeb(sdiodev->func[0],
+-					    *(u8 *)data, addr);
+-	} else {
+-		switch (regsz) {
+-		case 1:
+-			sdio_writeb(sdiodev->func[1], *(u8 *)data, addr, &ret);
+-			break;
+-		case 4:
+-			ret = brcmf_sdiod_addrprep(sdiodev, &addr);
+-			if (ret)
+-				goto done;
+-
+-			sdio_writel(sdiodev->func[1], *(u32 *)data, addr, &ret);
+-			break;
+-		default:
+-			WARN(1, "Invalid reg size\n");
+-			ret = -EINVAL;
+-			break;
+-		}
+-	}
+-
+-done:
+-	return ret;
+-}
+-
+-static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr,
+-				u8 regsz, void *data)
+-{
+-	int ret;
+-
+-	/*
+-	 * figure out how to read the register based on address range
+-	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
+-	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
+-	 * The rest: function 1 silicon backplane core registers
+-	 * f0 reads must be bytewise
+-	 */
+-	if ((addr & ~REG_F0_REG_MASK) == 0) {
+-		if (WARN_ON(regsz > 1))
+-			return -EINVAL;
+-		*(u8 *)data = sdio_f0_readb(sdiodev->func[0], addr, &ret);
+-	} else {
+-		switch (regsz) {
+-		case 1:
+-			*(u8 *)data = sdio_readb(sdiodev->func[1], addr, &ret);
+-			break;
+-		case 4:
+-			ret = brcmf_sdiod_addrprep(sdiodev, &addr);
+-			if (ret)
+-				goto done;
+-
+-			*(u32 *)data = sdio_readl(sdiodev->func[1], addr, &ret);
+-			break;
+-		default:
+-			WARN(1, "Invalid reg size\n");
+-			ret = -EINVAL;
+-			break;
+-		}
+-	}
+-
+-done:
+-	return ret;
+-}
+-
+-u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
++u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
+ {
+-	u8 data;
++	u32 data = 0;
+ 	int retval;
+ 
+-	retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data);
++	retval = brcmf_sdiod_addrprep(sdiodev, &addr);
+ 
+-	if (ret)
+-		*ret = retval;
+-
+-	return data;
+-}
+-
+-u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
+-{
+-	u32 data;
+-	int retval;
+-
+-	retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data);
++	if (!retval)
++		data = sdio_readl(sdiodev->func[1], addr, &retval);
+ 
+ 	if (ret)
+ 		*ret = retval;
+@@ -392,23 +283,15 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_
+ 	return data;
+ }
+ 
+-void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
+-		      u8 data, int *ret)
++void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			u32 data, int *ret)
+ {
+ 	int retval;
+ 
+-	retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data);
+-
+-	if (ret)
+-		*ret = retval;
+-}
+-
+-void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
+-		      u32 data, int *ret)
+-{
+-	int retval;
++	retval = brcmf_sdiod_addrprep(sdiodev, &addr);
+ 
+-	retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data);
++	if (!retval)
++		sdio_writel(sdiodev->func[1], data, addr, &retval);
+ 
+ 	if (ret)
+ 		*ret = retval;
+@@ -846,8 +729,8 @@ int brcmf_sdiod_abort(struct brcmf_sdio_
+ {
+ 	brcmf_dbg(SDIO, "Enter\n");
+ 
+-	/* issue abort cmd52 command through F0 */
+-	brcmf_sdiod_reg_write(sdiodev, SDIO_CCCR_ABORT, 1, &fn);
++	/* Issue abort cmd52 command through F0 */
++	brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL);
+ 
+ 	brcmf_dbg(SDIO, "Exit\n");
+ 	return 0;
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -669,7 +669,7 @@ static int r_sdreg32(struct brcmf_sdio *
+ 	int ret;
+ 
+ 	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
+-	*regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret);
++	*regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret);
+ 
+ 	return ret;
+ }
+@@ -680,7 +680,7 @@ static int w_sdreg32(struct brcmf_sdio *
+ 	int ret;
+ 
+ 	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
+-	brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret);
++	brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret);
+ 
+ 	return ret;
+ }
+@@ -697,8 +697,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio
+ 
+ 	wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
+ 	/* 1st KSO write goes to AOS wake up core if device is asleep  */
+-	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
+-			  wr_val, &err);
++	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
+ 
+ 	if (on) {
+ 		/* device WAKEUP through KSO:
+@@ -724,7 +723,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio
+ 		 * just one write attempt may fail,
+ 		 * read it back until it matches written value
+ 		 */
+-		rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
++		rd_val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
+ 					   &err);
+ 		if (!err) {
+ 			if ((rd_val & bmask) == cmp_val)
+@@ -734,9 +733,11 @@ brcmf_sdio_kso_control(struct brcmf_sdio
+ 		/* bail out upon subsequent access errors */
+ 		if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS))
+ 			break;
++
+ 		udelay(KSO_WAIT_US);
+-		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
+-				  wr_val, &err);
++		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val,
++				   &err);
++
+ 	} while (try_cnt++ < MAX_KSO_ATTEMPTS);
+ 
+ 	if (try_cnt > 2)
+@@ -772,15 +773,15 @@ static int brcmf_sdio_htclk(struct brcmf
+ 		clkreq =
+ 		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
+ 
+-		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+-				  clkreq, &err);
++		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				   clkreq, &err);
+ 		if (err) {
+ 			brcmf_err("HT Avail request error: %d\n", err);
+ 			return -EBADE;
+ 		}
+ 
+ 		/* Check current status */
+-		clkctl = brcmf_sdiod_regrb(bus->sdiodev,
++		clkctl = brcmf_sdiod_readb(bus->sdiodev,
+ 					   SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ 		if (err) {
+ 			brcmf_err("HT Avail read error: %d\n", err);
+@@ -790,35 +791,34 @@ static int brcmf_sdio_htclk(struct brcmf
+ 		/* Go to pending and await interrupt if appropriate */
+ 		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
+ 			/* Allow only clock-available interrupt */
+-			devctl = brcmf_sdiod_regrb(bus->sdiodev,
++			devctl = brcmf_sdiod_readb(bus->sdiodev,
+ 						   SBSDIO_DEVICE_CTL, &err);
+ 			if (err) {
+-				brcmf_err("Devctl error setting CA: %d\n",
+-					  err);
++				brcmf_err("Devctl error setting CA: %d\n", err);
+ 				return -EBADE;
+ 			}
+ 
+ 			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
+-			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
+-					  devctl, &err);
++			brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					   devctl, &err);
+ 			brcmf_dbg(SDIO, "CLKCTL: set PENDING\n");
+ 			bus->clkstate = CLK_PENDING;
+ 
+ 			return 0;
+ 		} else if (bus->clkstate == CLK_PENDING) {
+ 			/* Cancel CA-only interrupt filter */
+-			devctl = brcmf_sdiod_regrb(bus->sdiodev,
++			devctl = brcmf_sdiod_readb(bus->sdiodev,
+ 						   SBSDIO_DEVICE_CTL, &err);
+ 			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
+-					  devctl, &err);
++			brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					   devctl, &err);
+ 		}
+ 
+ 		/* Otherwise, wait here (polling) for HT Avail */
+ 		timeout = jiffies +
+ 			  msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
+ 		while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
+-			clkctl = brcmf_sdiod_regrb(bus->sdiodev,
++			clkctl = brcmf_sdiod_readb(bus->sdiodev,
+ 						   SBSDIO_FUNC1_CHIPCLKCSR,
+ 						   &err);
+ 			if (time_after(jiffies, timeout))
+@@ -852,16 +852,16 @@ static int brcmf_sdio_htclk(struct brcmf
+ 
+ 		if (bus->clkstate == CLK_PENDING) {
+ 			/* Cancel CA-only interrupt filter */
+-			devctl = brcmf_sdiod_regrb(bus->sdiodev,
++			devctl = brcmf_sdiod_readb(bus->sdiodev,
+ 						   SBSDIO_DEVICE_CTL, &err);
+ 			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
+-					  devctl, &err);
++			brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					   devctl, &err);
+ 		}
+ 
+ 		bus->clkstate = CLK_SDONLY;
+-		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+-				  clkreq, &err);
++		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				   clkreq, &err);
+ 		brcmf_dbg(SDIO, "CLKCTL: turned OFF\n");
+ 		if (err) {
+ 			brcmf_err("Failed access turning clock off: %d\n",
+@@ -951,14 +951,14 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *
+ 
+ 		/* Going to sleep */
+ 		if (sleep) {
+-			clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
++			clkcsr = brcmf_sdiod_readb(bus->sdiodev,
+ 						   SBSDIO_FUNC1_CHIPCLKCSR,
+ 						   &err);
+ 			if ((clkcsr & SBSDIO_CSR_MASK) == 0) {
+ 				brcmf_dbg(SDIO, "no clock, set ALP\n");
+-				brcmf_sdiod_regwb(bus->sdiodev,
+-						  SBSDIO_FUNC1_CHIPCLKCSR,
+-						  SBSDIO_ALP_AVAIL_REQ, &err);
++				brcmf_sdiod_writeb(bus->sdiodev,
++						   SBSDIO_FUNC1_CHIPCLKCSR,
++						   SBSDIO_ALP_AVAIL_REQ, &err);
+ 			}
+ 			err = brcmf_sdio_kso_control(bus, false);
+ 		} else {
+@@ -1178,16 +1178,16 @@ static void brcmf_sdio_rxfail(struct brc
+ 	if (abort)
+ 		brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
+ 
+-	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
+-			  SFC_RF_TERM, &err);
++	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM,
++			   &err);
+ 	bus->sdcnt.f1regdata++;
+ 
+ 	/* Wait until the packet has been flushed (device/FIFO stable) */
+ 	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
+-		hi = brcmf_sdiod_regrb(bus->sdiodev,
+-				       SBSDIO_FUNC1_RFRAMEBCHI, &err);
+-		lo = brcmf_sdiod_regrb(bus->sdiodev,
+-				       SBSDIO_FUNC1_RFRAMEBCLO, &err);
++		hi = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCHI,
++				       &err);
++		lo = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO,
++				       &err);
+ 		bus->sdcnt.f1regdata += 2;
+ 
+ 		if ((hi == 0) && (lo == 0))
+@@ -1229,12 +1229,12 @@ static void brcmf_sdio_txfail(struct brc
+ 	bus->sdcnt.tx_sderrs++;
+ 
+ 	brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
+-	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
++	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
+ 	bus->sdcnt.f1regdata++;
+ 
+ 	for (i = 0; i < 3; i++) {
+-		hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
+-		lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
++		hi = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
++		lo = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
+ 		bus->sdcnt.f1regdata += 2;
+ 		if ((hi == 0) && (lo == 0))
+ 			break;
+@@ -2446,11 +2446,11 @@ static void brcmf_sdio_bus_stop(struct d
+ 		bus->hostintmask = 0;
+ 
+ 		/* Force backplane clocks to assure F2 interrupt propagates */
+-		saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++		saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+ 					    &err);
+ 		if (!err)
+-			brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+-					  (saveclk | SBSDIO_FORCE_HT), &err);
++			brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++					   (saveclk | SBSDIO_FORCE_HT), &err);
+ 		if (err)
+ 			brcmf_err("Failed to force clock for F2: err %d\n",
+ 				  err);
+@@ -2509,7 +2509,7 @@ static int brcmf_sdio_intr_rstatus(struc
+ 	buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
+ 	addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
+ 
+-	val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
++	val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret);
+ 	bus->sdcnt.f1regdata++;
+ 	if (ret != 0)
+ 		return ret;
+@@ -2519,7 +2519,7 @@ static int brcmf_sdio_intr_rstatus(struc
+ 
+ 	/* Clear interrupts */
+ 	if (val) {
+-		brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
++		brcmf_sdiod_writel(bus->sdiodev, addr, val, &ret);
+ 		bus->sdcnt.f1regdata++;
+ 		atomic_or(val, &bus->intstatus);
+ 	}
+@@ -2545,23 +2545,23 @@ static void brcmf_sdio_dpc(struct brcmf_
+ 
+ #ifdef DEBUG
+ 		/* Check for inconsistent device control */
+-		devctl = brcmf_sdiod_regrb(bus->sdiodev,
+-					   SBSDIO_DEVICE_CTL, &err);
++		devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					   &err);
+ #endif				/* DEBUG */
+ 
+ 		/* Read CSR, if clock on switch to AVAIL, else ignore */
+-		clkctl = brcmf_sdiod_regrb(bus->sdiodev,
++		clkctl = brcmf_sdiod_readb(bus->sdiodev,
+ 					   SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ 
+ 		brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
+ 			  devctl, clkctl);
+ 
+ 		if (SBSDIO_HTAV(clkctl)) {
+-			devctl = brcmf_sdiod_regrb(bus->sdiodev,
++			devctl = brcmf_sdiod_readb(bus->sdiodev,
+ 						   SBSDIO_DEVICE_CTL, &err);
+ 			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
+-					  devctl, &err);
++			brcmf_sdiod_writeb(bus->sdiodev,
++					   SBSDIO_DEVICE_CTL, devctl, &err);
+ 			bus->clkstate = CLK_AVAIL;
+ 		}
+ 	}
+@@ -3347,31 +3347,31 @@ static void brcmf_sdio_sr_init(struct br
+ 
+ 	brcmf_dbg(TRACE, "Enter\n");
+ 
+-	val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
++	val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
+ 	if (err) {
+ 		brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n");
+ 		return;
+ 	}
+ 
+ 	val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
+-	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
++	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
+ 	if (err) {
+ 		brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n");
+ 		return;
+ 	}
+ 
+ 	/* Add CMD14 Support */
+-	brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
+-			  (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
+-			   SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
+-			  &err);
++	brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
++			     (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
++			      SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
++			     &err);
+ 	if (err) {
+ 		brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n");
+ 		return;
+ 	}
+ 
+-	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+-			  SBSDIO_FORCE_HT, &err);
++	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++			   SBSDIO_FORCE_HT, &err);
+ 	if (err) {
+ 		brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n");
+ 		return;
+@@ -3394,7 +3394,7 @@ static int brcmf_sdio_kso_init(struct br
+ 	if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
+ 		return 0;
+ 
+-	val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
++	val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
+ 	if (err) {
+ 		brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n");
+ 		return err;
+@@ -3403,8 +3403,8 @@ static int brcmf_sdio_kso_init(struct br
+ 	if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) {
+ 		val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN <<
+ 			SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
+-		brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
+-				  val, &err);
++		brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
++				   val, &err);
+ 		if (err) {
+ 			brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n");
+ 			return err;
+@@ -3565,9 +3565,9 @@ static void brcmf_sdio_bus_watchdog(stru
+ 				u8 devpend;
+ 
+ 				sdio_claim_host(bus->sdiodev->func[1]);
+-				devpend = brcmf_sdiod_regrb(bus->sdiodev,
+-							    SDIO_CCCR_INTx,
+-							    NULL);
++				devpend = brcmf_sdiod_func0_rb(bus->sdiodev,
++							       SDIO_CCCR_INTx,
++							       NULL);
+ 				sdio_release_host(bus->sdiodev->func[1]);
+ 				intstatus = devpend & (INTR_STATUS_FUNC1 |
+ 						       INTR_STATUS_FUNC2);
+@@ -3705,12 +3705,12 @@ brcmf_sdio_drivestrengthinit(struct brcm
+ 			}
+ 		}
+ 		addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
+-		brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
+-		cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
++		brcmf_sdiod_writel(sdiodev, addr, 1, NULL);
++		cc_data_temp = brcmf_sdiod_readl(sdiodev, addr, NULL);
+ 		cc_data_temp &= ~str_mask;
+ 		drivestrength_sel <<= str_shift;
+ 		cc_data_temp |= drivestrength_sel;
+-		brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
++		brcmf_sdiod_writel(sdiodev, addr, cc_data_temp, NULL);
+ 
+ 		brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
+ 			  str_tab[i].strength, drivestrength, cc_data_temp);
+@@ -3725,7 +3725,7 @@ static int brcmf_sdio_buscoreprep(void *
+ 
+ 	/* Try forcing SDIO core to do ALPAvail request only */
+ 	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
+-	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
+ 	if (err) {
+ 		brcmf_err("error writing for HT off\n");
+ 		return err;
+@@ -3733,8 +3733,7 @@ static int brcmf_sdio_buscoreprep(void *
+ 
+ 	/* If register supported, wait for ALPAvail and then force ALP */
+ 	/* This may take up to 15 milliseconds */
+-	clkval = brcmf_sdiod_regrb(sdiodev,
+-				   SBSDIO_FUNC1_CHIPCLKCSR, NULL);
++	clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
+ 
+ 	if ((clkval & ~SBSDIO_AVBITS) != clkset) {
+ 		brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
+@@ -3742,10 +3741,11 @@ static int brcmf_sdio_buscoreprep(void *
+ 		return -EACCES;
+ 	}
+ 
+-	SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
+-					      SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
+-			!SBSDIO_ALPAV(clkval)),
+-			PMU_MAX_TRANSITION_DLY);
++	SPINWAIT(((clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++					      NULL)),
++		 !SBSDIO_ALPAV(clkval)),
++		 PMU_MAX_TRANSITION_DLY);
++
+ 	if (!SBSDIO_ALPAV(clkval)) {
+ 		brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
+ 			  clkval);
+@@ -3753,11 +3753,11 @@ static int brcmf_sdio_buscoreprep(void *
+ 	}
+ 
+ 	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
+-	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
+ 	udelay(65);
+ 
+ 	/* Also, disable the extra SDIO pull-ups */
+-	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
++	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
+ 
+ 	return 0;
+ }
+@@ -3772,7 +3772,7 @@ static void brcmf_sdio_buscore_activate(
+ 	/* clear all interrupts */
+ 	core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
+ 	reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
+-	brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
++	brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
+ 
+ 	if (rstvec)
+ 		/* Write reset vector to address 0 */
+@@ -3785,7 +3785,7 @@ static u32 brcmf_sdio_buscore_read32(voi
+ 	struct brcmf_sdio_dev *sdiodev = ctx;
+ 	u32 val, rev;
+ 
+-	val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
++	val = brcmf_sdiod_readl(sdiodev, addr, NULL);
+ 	if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
+ 	     sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
+ 	    addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
+@@ -3802,7 +3802,7 @@ static void brcmf_sdio_buscore_write32(v
+ {
+ 	struct brcmf_sdio_dev *sdiodev = ctx;
+ 
+-	brcmf_sdiod_regwl(sdiodev, addr, val, NULL);
++	brcmf_sdiod_writel(sdiodev, addr, val, NULL);
+ }
+ 
+ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
+@@ -3826,18 +3826,18 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
+ 	sdio_claim_host(sdiodev->func[1]);
+ 
+ 	pr_debug("F1 signature read @0x18000000=0x%4x\n",
+-		 brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL));
++		 brcmf_sdiod_readl(sdiodev, SI_ENUM_BASE, NULL));
+ 
+ 	/*
+ 	 * Force PLL off until brcmf_chip_attach()
+ 	 * programs PLL control regs
+ 	 */
+ 
+-	brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+-			  BRCMF_INIT_CLKCTL1, &err);
++	brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, BRCMF_INIT_CLKCTL1,
++			   &err);
+ 	if (!err)
+-		clkctl = brcmf_sdiod_regrb(sdiodev,
+-					   SBSDIO_FUNC1_CHIPCLKCSR, &err);
++		clkctl = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++					   &err);
+ 
+ 	if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
+ 		brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
+@@ -3897,25 +3897,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
+ 	brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength);
+ 
+ 	/* Set card control so an SDIO card reset does a WLAN backplane reset */
+-	reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err);
++	reg_val = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err);
+ 	if (err)
+ 		goto fail;
+ 
+ 	reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET;
+ 
+-	brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
++	brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
+ 	if (err)
+ 		goto fail;
+ 
+ 	/* set PMUControl so a backplane reset does PMU state reload */
+ 	reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol);
+-	reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err);
++	reg_val = brcmf_sdiod_readl(sdiodev, reg_addr, &err);
+ 	if (err)
+ 		goto fail;
+ 
+ 	reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
+ 
+-	brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err);
++	brcmf_sdiod_writel(sdiodev, reg_addr, reg_val, &err);
+ 	if (err)
+ 		goto fail;
+ 
+@@ -4055,10 +4055,10 @@ static void brcmf_sdio_firmware_callback
+ 		goto release;
+ 
+ 	/* Force clocks on backplane to be sure F2 interrupt propagates */
+-	saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
++	saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
+ 	if (!err) {
+-		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+-				  (saveclk | SBSDIO_FORCE_HT), &err);
++		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				   (saveclk | SBSDIO_FORCE_HT), &err);
+ 	}
+ 	if (err) {
+ 		brcmf_err("Failed to force clock for F2: err %d\n", err);
+@@ -4080,7 +4080,7 @@ static void brcmf_sdio_firmware_callback
+ 		w_sdreg32(bus, bus->hostintmask,
+ 			  offsetof(struct sdpcmd_regs, hostintmask));
+ 
+-		brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err);
++		brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err);
+ 	} else {
+ 		/* Disable F2 again */
+ 		sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
+@@ -4091,8 +4091,8 @@ static void brcmf_sdio_firmware_callback
+ 		brcmf_sdio_sr_init(bus);
+ 	} else {
+ 		/* Restore previous clock setting */
+-		brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
+-				  saveclk, &err);
++		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				   saveclk, &err);
+ 	}
+ 
+ 	if (err == 0) {
+@@ -4225,7 +4225,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
+ 	bus->rxflow = false;
+ 
+ 	/* Done with backplane-dependent accesses, can drop clock... */
+-	brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
++	brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
+ 
+ 	sdio_release_host(bus->sdiodev->func[1]);
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+@@ -50,6 +50,7 @@
+ #define SBSDIO_NUM_FUNCTION		3
+ 
+ /* function 0 vendor specific CCCR registers */
++
+ #define SDIO_CCCR_BRCM_CARDCAP			0xf0
+ #define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT	0x02
+ #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT	0x04
+@@ -131,8 +132,6 @@
+ /* with b15, maps to 32-bit SB access */
+ #define SBSDIO_SB_ACCESS_2_4B_FLAG	0x08000
+ 
+-/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
+-
+ /* Address bits from SBADDR regs */
+ #define SBSDIO_SBWINDOW_MASK		0xffff8000
+ 
+@@ -293,13 +292,24 @@ struct sdpcmd_regs {
+ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev);
+ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev);
+ 
+-/* sdio device register access interface */
+-u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
+-u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
+-void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data,
+-		       int *ret);
+-void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data,
+-		       int *ret);
++/* SDIO device register access interface */
++/* Accessors for SDIO Function 0 */
++#define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
++	sdio_readb((sdiodev)->func[0], (addr), (r))
++
++#define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
++	sdio_writeb((sdiodev)->func[0], (v), (addr), (ret))
++
++/* Accessors for SDIO Function 1 */
++#define brcmf_sdiod_readb(sdiodev, addr, r) \
++	sdio_readb((sdiodev)->func[1], (addr), (r))
++
++#define brcmf_sdiod_writeb(sdiodev, addr, v, ret) \
++	sdio_writeb((sdiodev)->func[1], (v), (addr), (ret))
++
++u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
++void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data,
++			int *ret);
+ 
+ /* Buffer transfer to/from device (client) core via cmd53.
+  *   fn:       function number
diff --git a/package/kernel/mac80211/patches/312-v4.16-0005-brcmfmac-Tidy-register-definitions-a-little.patch b/package/kernel/mac80211/patches/312-v4.16-0005-brcmfmac-Tidy-register-definitions-a-little.patch
new file mode 100644
index 0000000..e77d601
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0005-brcmfmac-Tidy-register-definitions-a-little.patch
@@ -0,0 +1,59 @@
+From eeef8a5da781e11746347b3cd9f1942be48ebaf0 Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:30 +0100
+Subject: [PATCH] brcmfmac: Tidy register definitions a little
+
+Trivial tidy of register definitions.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Acked-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  4 ++--
+ .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 19 ++++++++++---------
+ 2 files changed, 12 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -153,9 +153,9 @@ int brcmf_sdiod_intr_register(struct brc
+ 		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);
+ 
+ 		/* redirect, configure and enable io for interrupt signal */
+-		data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
++		data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE;
+ 		if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
+-			data |= SDIO_SEPINT_ACT_HI;
++			data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI;
+ 		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT,
+ 				     data, &ret);
+ 		sdio_release_host(sdiodev->func[1]);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+@@ -52,16 +52,17 @@
+ /* function 0 vendor specific CCCR registers */
+ 
+ #define SDIO_CCCR_BRCM_CARDCAP			0xf0
+-#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT	0x02
+-#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT	0x04
+-#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC	0x08
+-#define SDIO_CCCR_BRCM_CARDCTRL		0xf1
+-#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET	0x02
+-#define SDIO_CCCR_BRCM_SEPINT			0xf2
++#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT	BIT(1)
++#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT	BIT(2)
++#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC	BIT(3)
++
++#define SDIO_CCCR_BRCM_CARDCTRL			0xf1
++#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET	BIT(1)
+ 
+-#define  SDIO_SEPINT_MASK		0x01
+-#define  SDIO_SEPINT_OE			0x02
+-#define  SDIO_SEPINT_ACT_HI		0x04
++#define SDIO_CCCR_BRCM_SEPINT			0xf2
++#define SDIO_CCCR_BRCM_SEPINT_MASK		BIT(0)
++#define SDIO_CCCR_BRCM_SEPINT_OE		BIT(1)
++#define SDIO_CCCR_BRCM_SEPINT_ACT_HI		BIT(2)
+ 
+ /* function 1 miscellaneous registers */
+ 
diff --git a/package/kernel/mac80211/patches/312-v4.16-0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch b/package/kernel/mac80211/patches/312-v4.16-0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch
new file mode 100644
index 0000000..3c78af8
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch
@@ -0,0 +1,190 @@
+From a7c3aa1509e243a09c5b1660c8702d792ca76aed Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:31 +0100
+Subject: [PATCH] brcmfmac: Remove brcmf_sdiod_addrprep()
+
+This function has become trivial enough that it may as well be pushed into
+its callers, which has the side-benefit of clarifying what's going on.
+
+Remove it, and rename brcmf_sdiod_set_sbaddr_window() to
+brcmf_sdiod_set_backplane_window() as it's easier to understand.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 84 ++++++++++++----------
+ 1 file changed, 46 insertions(+), 38 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -230,41 +230,25 @@ void brcmf_sdiod_change_state(struct brc
+ 	sdiodev->state = state;
+ }
+ 
+-static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
+-					 u32 address)
++static int brcmf_sdiod_set_backplane_window(struct brcmf_sdio_dev *sdiodev,
++					    u32 addr)
+ {
++	u32 v, bar0 = addr & SBSDIO_SBWINDOW_MASK;
+ 	int err = 0, i;
+-	u32 addr;
+ 
+-	if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
+-		return -ENOMEDIUM;
++	if (bar0 == sdiodev->sbwad)
++		return 0;
+ 
+-	addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
++	v = bar0 >> 8;
+ 
+-	for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
++	for (i = 0 ; i < 3 && !err ; i++, v >>= 8)
+ 		brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
+-				   addr & 0xff, &err);
+-
+-	return err;
+-}
+-
+-static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
+-{
+-	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-	int err = 0;
+-
+-	if (bar0 != sdiodev->sbwad) {
+-		err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
+-		if (err)
+-			return err;
++				   v & 0xff, &err);
+ 
++	if (!err)
+ 		sdiodev->sbwad = bar0;
+-	}
+-
+-	*addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-	*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ 
+-	return 0;
++	return err;
+ }
+ 
+ u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
+@@ -272,11 +256,16 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
+ 	u32 data = 0;
+ 	int retval;
+ 
+-	retval = brcmf_sdiod_addrprep(sdiodev, &addr);
++	retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);
++	if (retval)
++		goto out;
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ 
+-	if (!retval)
+-		data = sdio_readl(sdiodev->func[1], addr, &retval);
++	data = sdio_readl(sdiodev->func[1], addr, &retval);
+ 
++out:
+ 	if (ret)
+ 		*ret = retval;
+ 
+@@ -288,11 +277,16 @@ void brcmf_sdiod_writel(struct brcmf_sdi
+ {
+ 	int retval;
+ 
+-	retval = brcmf_sdiod_addrprep(sdiodev, &addr);
++	retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);
++	if (retval)
++		goto out;
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ 
+-	if (!retval)
+-		sdio_writel(sdiodev->func[1], data, addr, &retval);
++	sdio_writel(sdiodev->func[1], data, addr, &retval);
+ 
++out:
+ 	if (ret)
+ 		*ret = retval;
+ }
+@@ -540,10 +534,13 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)
+ 
+ 	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
+ 
+-	err = brcmf_sdiod_addrprep(sdiodev, &addr);
++	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+ 	if (err)
+ 		goto done;
+ 
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
+ 	err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt);
+ 
+ done:
+@@ -561,10 +558,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_
+ 	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
+ 		  addr, pktq->qlen);
+ 
+-	err = brcmf_sdiod_addrprep(sdiodev, &addr);
++	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+ 	if (err)
+ 		goto done;
+ 
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
+ 	if (pktq->qlen == 1)
+ 		err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
+ 					    pktq->next);
+@@ -606,7 +606,12 @@ int brcmf_sdiod_send_buf(struct brcmf_sd
+ 
+ 	memcpy(mypkt->data, buf, nbytes);
+ 
+-	err = brcmf_sdiod_addrprep(sdiodev, &addr);
++	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
++	if (err)
++		return err;
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ 
+ 	if (!err)
+ 		err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
+@@ -625,10 +630,13 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd
+ 
+ 	brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
+ 
+-	err = brcmf_sdiod_addrprep(sdiodev, &addr);
++	err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+ 	if (err)
+ 		return err;
+ 
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
+ 	if (pktq->qlen == 1 || !sdiodev->sg_support) {
+ 		skb_queue_walk(pktq, skb) {
+ 			err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2,
+@@ -673,7 +681,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
+ 	/* Do the transfer(s) */
+ 	while (size) {
+ 		/* Set the backplane window to include the start address */
+-		err = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
++		err = brcmf_sdiod_set_backplane_window(sdiodev, address);
+ 		if (err)
+ 			break;
+ 
+@@ -716,7 +724,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
+ 	dev_kfree_skb(pkt);
+ 
+ 	/* Return the window to backplane enumeration space for core access */
+-	if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad))
++	if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad))
+ 		brcmf_err("FAILED to set window back to 0x%x\n",
+ 			  sdiodev->sbwad);
+ 
diff --git a/package/kernel/mac80211/patches/312-v4.16-0007-brcmfmac-remove-unnecessary-call-to-brcmf_sdiod_set_.patch b/package/kernel/mac80211/patches/312-v4.16-0007-brcmfmac-remove-unnecessary-call-to-brcmf_sdiod_set_.patch
new file mode 100644
index 0000000..b9410dd
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0007-brcmfmac-remove-unnecessary-call-to-brcmf_sdiod_set_.patch
@@ -0,0 +1,32 @@
+From c900072bd6faff089aa4fb7b19136a2a0fe3baf0 Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:32 +0100
+Subject: [PATCH] brcmfmac: remove unnecessary call to
+ brcmf_sdiod_set_backplane_window()
+
+All functions that might require the window address changing call
+brcmf_sdiod_set_backplane_window() prior to access. Thus resetting
+the window is not required.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+[arend: corrected the driver prefix in the subject]
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -723,11 +723,6 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev
+ 
+ 	dev_kfree_skb(pkt);
+ 
+-	/* Return the window to backplane enumeration space for core access */
+-	if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad))
+-		brcmf_err("FAILED to set window back to 0x%x\n",
+-			  sdiodev->sbwad);
+-
+ 	sdio_release_host(sdiodev->func[1]);
+ 
+ 	return err;
diff --git a/package/kernel/mac80211/patches/312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch b/package/kernel/mac80211/patches/312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch
new file mode 100644
index 0000000..f9e5df5
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch
@@ -0,0 +1,134 @@
+From e4c05fc3c0a6c79376f72f17d08014477e962ada Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:33 +0100
+Subject: [PATCH] brcmfmac: Cleanup offsetof()
+
+Create a macro to make the code a bit more readable, whilst we're stuck
+with using struct element offsets as register offsets.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+[arend: rename macro to SD_REG]
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 35 +++++++++-------------
+ 1 file changed, 14 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -161,6 +161,8 @@ struct rte_console {
+ 
+ #define CORE_BUS_REG(base, field) \
+ 		(base + offsetof(struct sdpcmd_regs, field))
++#define SD_REG(field) \
++		(offsetof(struct sdpcmd_regs, field))
+ 
+ /* SDIO function 1 register CHIPCLKCSR */
+ /* Force ALP request to backplane */
+@@ -1087,12 +1089,10 @@ static u32 brcmf_sdio_hostmail(struct br
+ 	brcmf_dbg(SDIO, "Enter\n");
+ 
+ 	/* Read mailbox data and ack that we did so */
+-	ret = r_sdreg32(bus, &hmb_data,
+-			offsetof(struct sdpcmd_regs, tohostmailboxdata));
++	ret = r_sdreg32(bus, &hmb_data,	SD_REG(tohostmailboxdata));
+ 
+ 	if (ret == 0)
+-		w_sdreg32(bus, SMB_INT_ACK,
+-			  offsetof(struct sdpcmd_regs, tosbmailbox));
++		w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox));
+ 	bus->sdcnt.f1regdata += 2;
+ 
+ 	/* dongle indicates the firmware has halted/crashed */
+@@ -1207,8 +1207,7 @@ static void brcmf_sdio_rxfail(struct brc
+ 
+ 	if (rtx) {
+ 		bus->sdcnt.rxrtx++;
+-		err = w_sdreg32(bus, SMB_NAK,
+-				offsetof(struct sdpcmd_regs, tosbmailbox));
++		err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox));
+ 
+ 		bus->sdcnt.f1regdata++;
+ 		if (err == 0)
+@@ -2333,9 +2332,7 @@ static uint brcmf_sdio_sendfromq(struct
+ 		if (!bus->intr) {
+ 			/* Check device status, signal pending interrupt */
+ 			sdio_claim_host(bus->sdiodev->func[1]);
+-			ret = r_sdreg32(bus, &intstatus,
+-					offsetof(struct sdpcmd_regs,
+-						 intstatus));
++			ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus));
+ 			sdio_release_host(bus->sdiodev->func[1]);
+ 			bus->sdcnt.f2txdata++;
+ 			if (ret != 0)
+@@ -2441,7 +2438,7 @@ static void brcmf_sdio_bus_stop(struct d
+ 		brcmf_sdio_bus_sleep(bus, false, false);
+ 
+ 		/* Disable and clear interrupts at the chip level also */
+-		w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
++		w_sdreg32(bus, 0, SD_REG(hostintmask));
+ 		local_hostintmask = bus->hostintmask;
+ 		bus->hostintmask = 0;
+ 
+@@ -2460,8 +2457,7 @@ static void brcmf_sdio_bus_stop(struct d
+ 		sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
+ 
+ 		/* Clear any pending interrupts now that F2 is disabled */
+-		w_sdreg32(bus, local_hostintmask,
+-			  offsetof(struct sdpcmd_regs, intstatus));
++		w_sdreg32(bus, local_hostintmask, SD_REG(intstatus));
+ 
+ 		sdio_release_host(sdiodev->func[1]);
+ 	}
+@@ -2507,7 +2503,7 @@ static int brcmf_sdio_intr_rstatus(struc
+ 	int ret;
+ 
+ 	buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
+-	addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
++	addr = buscore->base + SD_REG(intstatus);
+ 
+ 	val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret);
+ 	bus->sdcnt.f1regdata++;
+@@ -2584,11 +2580,9 @@ static void brcmf_sdio_dpc(struct brcmf_
+ 	 */
+ 	if (intstatus & I_HMB_FC_CHANGE) {
+ 		intstatus &= ~I_HMB_FC_CHANGE;
+-		err = w_sdreg32(bus, I_HMB_FC_CHANGE,
+-				offsetof(struct sdpcmd_regs, intstatus));
++		err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus));
+ 
+-		err = r_sdreg32(bus, &newstatus,
+-				offsetof(struct sdpcmd_regs, intstatus));
++		err = r_sdreg32(bus, &newstatus, SD_REG(intstatus));
+ 		bus->sdcnt.f1regdata += 2;
+ 		atomic_set(&bus->fcstate,
+ 			   !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
+@@ -3771,7 +3765,7 @@ static void brcmf_sdio_buscore_activate(
+ 
+ 	/* clear all interrupts */
+ 	core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
+-	reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
++	reg_addr = core->base + SD_REG(intstatus);
+ 	brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
+ 
+ 	if (rstvec)
+@@ -4067,7 +4061,7 @@ static void brcmf_sdio_firmware_callback
+ 
+ 	/* Enable function 2 (frame transfers) */
+ 	w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
+-		  offsetof(struct sdpcmd_regs, tosbmailboxdata));
++		  SD_REG(tosbmailboxdata));
+ 	err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
+ 
+ 
+@@ -4077,8 +4071,7 @@ static void brcmf_sdio_firmware_callback
+ 	if (!err) {
+ 		/* Set up the interrupt mask and enable interrupts */
+ 		bus->hostintmask = HOSTINTMASK;
+-		w_sdreg32(bus, bus->hostintmask,
+-			  offsetof(struct sdpcmd_regs, hostintmask));
++		w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask));
+ 
+ 		brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err);
+ 	} else {
diff --git a/package/kernel/mac80211/patches/312-v4.16-0009-brcmfmac-Remove-unused-macro.patch b/package/kernel/mac80211/patches/312-v4.16-0009-brcmfmac-Remove-unused-macro.patch
new file mode 100644
index 0000000..df72a70
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0009-brcmfmac-Remove-unused-macro.patch
@@ -0,0 +1,26 @@
+From 5cfe38f1f8d3c6b98e15b8cfde05028a3c79930b Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:34 +0100
+Subject: [PATCH] brcmfmac: Remove unused macro.
+
+This macro is used exactly nowhere in the code. Delete it.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -159,8 +159,6 @@ struct rte_console {
+ /* manfid tuple length, include tuple, link bytes */
+ #define SBSDIO_CIS_MANFID_TUPLE_LEN	6
+ 
+-#define CORE_BUS_REG(base, field) \
+-		(base + offsetof(struct sdpcmd_regs, field))
+ #define SD_REG(field) \
+ 		(offsetof(struct sdpcmd_regs, field))
+ 
diff --git a/package/kernel/mac80211/patches/312-v4.16-0010-brcmfmac-Remove-repeated-calls-to-brcmf_chip_get_cor.patch b/package/kernel/mac80211/patches/312-v4.16-0010-brcmfmac-Remove-repeated-calls-to-brcmf_chip_get_cor.patch
new file mode 100644
index 0000000..69fbf5c
--- /dev/null
+++ b/package/kernel/mac80211/patches/312-v4.16-0010-brcmfmac-Remove-repeated-calls-to-brcmf_chip_get_cor.patch
@@ -0,0 +1,128 @@
+From 21a10846d09db3c5e3bdfb0be0fc7aa9fdc7000a Mon Sep 17 00:00:00 2001
+From: Ian Molton <ian at mnementh.co.uk>
+Date: Fri, 8 Dec 2017 13:10:35 +0100
+Subject: [PATCH] brcmfmac: Remove repeated calls to brcmf_chip_get_core()
+
+There is no need to repeatdly call brcmf_chip_get_core(), which
+traverses a list of cores every time its called (including during
+register access code!).
+
+Call it once, and store a pointer to the core structure. The existing
+code does nto keep track of users of the cores anyway, and even so, this
+will allow for easier refcounting in future.
+
+Signed-off-by: Ian Molton <ian at mnementh.co.uk>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 25 +++++++++++++---------
+ 1 file changed, 15 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -436,6 +436,7 @@ struct brcmf_sdio_count {
+ struct brcmf_sdio {
+ 	struct brcmf_sdio_dev *sdiodev;	/* sdio device handler */
+ 	struct brcmf_chip *ci;	/* Chip info struct */
++	struct brcmf_core *sdio_core; /* sdio core info struct */
+ 
+ 	u32 hostintmask;	/* Copy of Host Interrupt Mask */
+ 	atomic_t intstatus;	/* Intstatus bits (events) pending */
+@@ -665,10 +666,9 @@ static bool data_ok(struct brcmf_sdio *b
+  */
+ static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
+ {
+-	struct brcmf_core *core;
++	struct brcmf_core *core = bus->sdio_core;
+ 	int ret;
+ 
+-	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
+ 	*regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret);
+ 
+ 	return ret;
+@@ -676,10 +676,9 @@ static int r_sdreg32(struct brcmf_sdio *
+ 
+ static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
+ {
+-	struct brcmf_core *core;
++	struct brcmf_core *core = bus->sdio_core;
+ 	int ret;
+ 
+-	core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
+ 	brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret);
+ 
+ 	return ret;
+@@ -2495,12 +2494,11 @@ static inline void brcmf_sdio_clrintr(st
+ 
+ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
+ {
+-	struct brcmf_core *buscore;
++	struct brcmf_core *buscore = bus->sdio_core;
+ 	u32 addr;
+ 	unsigned long val;
+ 	int ret;
+ 
+-	buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
+ 	addr = buscore->base + SD_REG(intstatus);
+ 
+ 	val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret);
+@@ -3377,13 +3375,14 @@ static void brcmf_sdio_sr_init(struct br
+ /* enable KSO bit */
+ static int brcmf_sdio_kso_init(struct brcmf_sdio *bus)
+ {
++	struct brcmf_core *core = bus->sdio_core;
+ 	u8 val;
+ 	int err = 0;
+ 
+ 	brcmf_dbg(TRACE, "Enter\n");
+ 
+ 	/* KSO bit added in SDIO core rev 12 */
+-	if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
++	if (core->rev < 12)
+ 		return 0;
+ 
+ 	val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
+@@ -3412,6 +3411,7 @@ static int brcmf_sdio_bus_preinit(struct
+ 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ 	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+ 	struct brcmf_sdio *bus = sdiodev->bus;
++	struct brcmf_core *core = bus->sdio_core;
+ 	uint pad_size;
+ 	u32 value;
+ 	int err;
+@@ -3420,7 +3420,7 @@ static int brcmf_sdio_bus_preinit(struct
+ 	 * a device perspective, ie. bus:txglom affects the
+ 	 * bus transfers from device to host.
+ 	 */
+-	if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) {
++	if (core->rev < 12) {
+ 		/* for sdio core rev < 12, disable txgloming */
+ 		value = 0;
+ 		err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
+@@ -3758,11 +3758,10 @@ static void brcmf_sdio_buscore_activate(
+ 					u32 rstvec)
+ {
+ 	struct brcmf_sdio_dev *sdiodev = ctx;
+-	struct brcmf_core *core;
++	struct brcmf_core *core = sdiodev->bus->sdio_core;
+ 	u32 reg_addr;
+ 
+ 	/* clear all interrupts */
+-	core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
+ 	reg_addr = core->base + SD_REG(intstatus);
+ 	brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
+ 
+@@ -3843,6 +3842,12 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
+ 		bus->ci = NULL;
+ 		goto fail;
+ 	}
++
++	/* Pick up the SDIO core info struct from chip.c */
++	bus->sdio_core   = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
++	if (!bus->sdio_core)
++		goto fail;
++
+ 	sdiodev->settings = brcmf_get_module_param(sdiodev->dev,
+ 						   BRCMF_BUSTYPE_SDIO,
+ 						   bus->ci->chip,



More information about the lede-commits mailing list