Re: [PATCH 18/30] brcmfmac: Cleanup offsetof()

2017-08-31 Thread Ian Molton
On 30/08/17 20:37, Arend van Spriel wrote:
> On 22-08-17 13:25, Ian Molton wrote:
>> +#define __sd_reg(field) \
>> +(offsetof(struct sdpcmd_regs, field))
> 
> I really dislike __foo() stuff. Please just stick with uppercase for
> macros, so SD_REG(). I am fine with dropping the base here.

I'm fine with that. Will change.

-Ian


Re: [PATCH 13/30] brcmfmac: Clarify if using braces.

2017-08-31 Thread Ian Molton
On 30/08/17 20:11, Arend van Spriel wrote:
>> Whilst this if () statement is technically correct, it lacks clarity.
> 
> I don't see the unclarity here. In my opinion people reading the code
> should have a good level in C language and a decent level of curiosity
> when they come across a function/macro like skb_queue_walk().

I thought it to be part of the general codingstyle for the kernel that
multi-line ifs and elses should be in braces, although I accept that
technically the if-clause is a single block-level statement.

Having said that, *this* specific example falls into a grey area in the
codingstyle, which covers multi-statement, multi-line if() clauses and
single-statement, single-line ones. It does not cover single-statement,
multi-line examples such as the one here.

Whilst I can't therefore definitively justify my position, I can show,
for example, line 999 in net/mac80211/iface.c where a for() statement
uses braces around the skb_queue_walk()

for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
skb_queue_walk_safe(>pending[i], skb, tmp) {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (info->control.vif == >vif) {
__skb_unlink(skb, >pending[i]);
ieee80211_free_txskb(>hw, skb);
}
}
}


And the following in ath9k_htc_tx_cleanup_queue()

if (process) {
skb_queue_walk_safe(, skb, tmp) {
__skb_unlink(skb, );
ath9k_htc_tx_process(priv, skb, NULL);
}
}

So I feel that we should do the same.

-Ian


Re: [PATCH 03/30] brcmfmac: Split brcmf_sdiod_regrw_helper() up.

2017-08-31 Thread Ian Molton
On 30/08/17 19:59, Arend van Spriel wrote:
>> +static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32
>> addr,
>> + u8 regsz, void *data)
> 
> Thought I mentioned this before, but the indentation should be aligned
> to opening bracket.

I checked this locally, and its fine. I suspect its getting mangled
somewhere along the way.

It looks fine in my original email - I see 4 tabs and a space.

-Ian


Re: [PATCH 01/30] brcmfmac: Fix parameter order in brcmf_sdiod_f0_writeb()

2017-08-31 Thread Ian Molton
On 30/08/17 19:51, Arend van Spriel wrote:
> On 22-08-17 13:25, Ian Molton wrote:
>> All the other IO functions are the other way round in this
>> driver. Make this one match.
> 
> Sorry for being a nit, but not sure why the commit message starts with a
> tab.

Not a problem - I don't mind nits being pointed out. Not at all.

> Other than that...

Will update it in the next (hopefully last!) rev.

> Acked-by: Arend van Spriel <arend.vanspr...@broadcom.com>

Ta :)

>> Signed-off-by: Ian Molton <i...@mnementh.co.uk>
>> ---
>>   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 
>>   1 file changed, 4 insertions(+), 4 deletions(-)

-Ian


Re: [PATCH 17/30] brcmfamc: remove unnecessary call to brcmf_sdiod_set_backplane_window()

2017-08-23 Thread Ian Molton
On 23/08/17 13:36, Julian Calaby wrote:
> Hi Ian,
> 
> On Wed, Aug 23, 2017 at 10:27 PM, Ian Molton <i...@mnementh.co.uk> wrote:
>> On 23/08/17 11:09, Julian Calaby wrote:
>>> I don't think I explained my point well.
>>>
>>> The description of this patch implies that this method
>>> brcmf_sdiod_ramrw(), now relies on the window being set elsewhere
>>> before it's called.
>>
>> I don't think it does.
> 
> "Resetting" can mean both changing it back after setting it to
> something or changing it from some other state to a known one. I read
> it as the latter.

True

>>> I'm asking why we can't move the setting of the window inside this
>>> function and remove any redundant calls to
>>> brcmf_sdiod_set_backplane_window() outside of it.
>>
>> We do call brcmf_sdiod_set_backplane_window() in this function. We just
>> dont need to call it a second time to restore the original window.
> 
> Ah, I do not have the full code in front of me, so I couldn't see
> that, therefore my point is invalid.

No worries.

-Ian


Re: [PATCH 17/30] brcmfamc: remove unnecessary call to brcmf_sdiod_set_backplane_window()

2017-08-23 Thread Ian Molton
On 23/08/17 11:09, Julian Calaby wrote:
> I don't think I explained my point well.
> 
> The description of this patch implies that this method
> brcmf_sdiod_ramrw(), now relies on the window being set elsewhere
> before it's called.

I don't think it does.

> I'm asking why we can't move the setting of the window inside this
> function and remove any redundant calls to
> brcmf_sdiod_set_backplane_window() outside of it.

We do call brcmf_sdiod_set_backplane_window() in this function. We just
dont need to call it a second time to restore the original window.

It may have been required in the past because the code relied on a value
not changing (swbadr) which was a poor assumption. In practice, the
current code does not provoke this potential bug, which I remove all
possibility of happening in patch 23/30

-Ian


Re: [PATCH 17/30] brcmfamc: remove unnecessary call to brcmf_sdiod_set_backplane_window()

2017-08-22 Thread Ian Molton
On 22/08/17 20:44, Arend van Spriel wrote:
> By the way, the driver prefix in the subject is wrong, ie. brcmfamc
> should be brcmfmac. I think it already was wrong in the previous series,
> but I forgot to mention it.

Drat. well spotted :)

-Ian


Re: [PATCH v5] brcmfmac cleanup

2017-08-22 Thread Ian Molton
On 22/08/17 20:41, Arend van Spriel wrote:
> On 22-08-17 13:25, Ian Molton wrote:
>> Hi folks,
>>
>> Arend, as requested - a respin to take account of your comments.
>>
>> Unfortunately, although I've only included the patches you requested
>> from v4,
>> breaking out some of the simpler changes (whitespace, macos, etc.) has
>> grown
>> the set back up to 30 patches. I hope this is OK.
> 
> :-( Grumbl, you also introduced some new ideas, eg. patch 26/30.

Oh, yeah. Forgot about that one, but its so uncontroversial I didn't see
the harm.

The same lines were touched in 25/30 and I didn't want to sneak the
change in there, as it felt dishonest to do so.

> I reviewed 15 patches that mostly involved in cleaning up bcmsdh.c. My
> hopes were that you addressed those 15 patches with a respin to get that
> part at least in for 4.14 as we are steadily moving towards the merge
> window. Maybe you did, but going from 15 to 30 feels like things are
> moving in the wrong direction. I will dig through it again.

I may have misunderstood, but you wrote:

"From this series I reviewed patches 1 upto and including patch 15, and
patches 29 through 34. Please rework those as requested and resubmit
them. Please also resubmit the remaining patch after that"

I took that to mean you wanted a respin that included 1-15 and 29-34.

- That would have been 21 patches on its own, but a couple of the later
ones drew in dependencies, and you asked me to break up a couple of
others, eg. whitespace.

Thats how we arrived at 30 patches again. I'm not attempting to take the
piss, I swear :)

I do appreciate the review. I've replied to your emails on the v4
series, so if you have a question as to why I've done something, you may
well find the answer there.

-Ian


[PATCH 29/30] brcmfmac: Remove array of functions

2017-08-22 Thread Ian Molton
Replace the array of functions with a pair of pointers to the
 relevant functions.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Acked-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 115 +++---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 170 ++---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|  15 +-
 3 files changed, 147 insertions(+), 153 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 75e9a70857e3..4080085ef44b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -118,7 +118,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
  pdata->oob_irq_flags, "brcmf_oob_intr",
- >func[1]->dev);
+ >func1->dev);
if (ret != 0) {
brcmf_err("request_irq failed %d\n", ret);
return ret;
@@ -132,7 +132,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
}
sdiodev->irq_wake = true;
 
-   sdio_claim_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
 
if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
/* assign GPIO to SDIO core */
@@ -157,13 +157,13 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
);
-   sdio_release_host(sdiodev->func[1]);
+   sdio_release_host(sdiodev->func1);
} else {
brcmf_dbg(SDIO, "Entering\n");
-   sdio_claim_host(sdiodev->func[1]);
-   sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
-   sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
-   sdio_release_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
+   sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler);
+   sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler);
+   sdio_release_host(sdiodev->func1);
sdiodev->sd_irq_requested = true;
}
 
@@ -181,26 +181,26 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
struct brcmfmac_sdio_pd *pdata;
 
pdata = >settings->bus.sdio;
-   sdio_claim_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
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]);
+   sdio_release_host(sdiodev->func1);
 
sdiodev->oob_irq_requested = false;
if (sdiodev->irq_wake) {
disable_irq_wake(pdata->oob_irq_nr);
sdiodev->irq_wake = false;
}
-   free_irq(pdata->oob_irq_nr, >func[1]->dev);
+   free_irq(pdata->oob_irq_nr, >func1->dev);
sdiodev->irq_en = false;
sdiodev->oob_irq_requested = false;
}
 
if (sdiodev->sd_irq_requested) {
-   sdio_claim_host(sdiodev->func[1]);
-   sdio_release_irq(sdiodev->func[2]);
-   sdio_release_irq(sdiodev->func[1]);
-   sdio_release_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
+   sdio_release_irq(sdiodev->func2);
+   sdio_release_irq(sdiodev->func1);
+   sdio_release_host(sdiodev->func1);
sdiodev->sd_irq_requested = false;
}
 }
@@ -262,7 +262,7 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
addr &= SBSDIO_SB_OFT_ADDR_MASK;
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-   data = sdio_readl(sdiodev->func[1], addr, );
+   data = sdio_readl(sdiodev->func1, addr, );
 
 out:
if (ret)
@@ -283,7 +283,7 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 
addr,
addr &= SBSDIO_SB_OFT_ADDR_MASK;
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-   sdio_writel(sdiodev->func[1], data, addr, );
+   sdio_writel(sdiodev->func1, data, addr, );
 
 out:
if (ret)
@@ -546,7 +546,7 @@ int b

[PATCH 15/30] brcmfmac: Tidy register definitions a little

2017-08-22 Thread Ian Molton
Trivial tidy of register definitions.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  4 ++--
 .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 19 ++-
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 50f207bb3dc6..721c7bd9478f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -152,9 +152,9 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, );
 
/* 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, 
);
sdio_release_host(sdiodev->func[1]);
} else {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 453213b071de..01def16cd236 100644
--- 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_CARDCTRL0xf1
-#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_CARDCTRL0xf1
+#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET  BIT(1)
 
-#define  SDIO_SEPINT_MASK  0x01
-#define  SDIO_SEPINT_OE0x02
-#define  SDIO_SEPINT_ACT_HI0x04
+#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 */
 
-- 
2.11.0



[PATCH 27/30] brcmfmac: Replace function index with function pointer

2017-08-22 Thread Ian Molton
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 <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 83 --
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 15 ++--
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|  6 +-
 3 files changed, 54 insertions(+), 50 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 69a6699126fd..0cd081d732f9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -289,8 +289,9 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 
addr,
*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;
@@ -299,13 +300,17 @@ static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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:
+   BUG();
+   };
 
if (err == -ENOMEDIUM)
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
@@ -313,8 +318,9 @@ static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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;
@@ -323,8 +329,7 @@ static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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);
@@ -335,7 +340,7 @@ static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev 
*sdiodev, uint fn,
 /**
  * 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
@@ -344,7 +349,8 @@ static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev 
*sdiodev, uint fn,
  * 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)
 {
@@ -370,7 +376,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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) {
@@ -389,7 +395,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev 
*sdiodev, uint fn,
target_list = _list;
}
 
-   func_blk_sz = 

[PATCH 10/30] brcmfmac: Rename bcmerror to err

2017-08-22 Thread Ian Molton
Trivial cleanup of nasty variable name

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Acked-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 6669e28279d9..834aa3e358ce 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -745,7 +745,7 @@ int
 brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
  u8 *data, uint size)
 {
-   int bcmerror = 0;
+   int err = 0;
struct sk_buff *pkt;
u32 sdaddr;
uint dsize;
@@ -770,8 +770,8 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
/* Do the transfer(s) */
while (size) {
/* Set the backplane window to include the start address */
-   bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
-   if (bcmerror)
+   err = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
+   if (err)
break;
 
brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 
0x%08x\n",
@@ -784,9 +784,9 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
skb_put(pkt, dsize);
if (write)
memcpy(pkt->data, data, dsize);
-   bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write,
- sdaddr, pkt);
-   if (bcmerror) {
+   err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr,
+pkt);
+   if (err) {
brcmf_err("membytes transfer failed\n");
break;
}
@@ -813,7 +813,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
 
sdio_release_host(sdiodev->func[1]);
 
-   return bcmerror;
+   return err;
 }
 
 int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn)
-- 
2.11.0



[PATCH 30/30] brcmfmac: Reduce the noise from repeatedly dereferencing common pointers

2017-08-22 Thread Ian Molton
This introduces no functional changes, but makes the code drastically more
readable, reducing the amount of dereferencing performed inside functions
throughout the SDIO core.

For example, reduce:
sdio_release_host(bus->sdiodev->func1);
to:
sdio_release_host(func1);

Fixup a few inconsistently named pointers whilst we are at it ie.

sdiod -> sdiodev

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 140 +++
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 406 +++--
 2 files changed, 293 insertions(+), 253 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 4080085ef44b..106f92372396 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -105,6 +105,8 @@ static void brcmf_sdiod_dummy_irqhandler(struct sdio_func 
*func)
 int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
 {
struct brcmfmac_sdio_pd *pdata;
+   struct sdio_func *func1 = sdiodev->func1;
+   struct sdio_func *func2 = sdiodev->func2;
int ret = 0;
u8 data;
u32 addr, gpiocontrol;
@@ -118,7 +120,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
  pdata->oob_irq_flags, "brcmf_oob_intr",
- >func1->dev);
+ >dev);
if (ret != 0) {
brcmf_err("request_irq failed %d\n", ret);
return ret;
@@ -132,7 +134,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
}
sdiodev->irq_wake = true;
 
-   sdio_claim_host(sdiodev->func1);
+   sdio_claim_host(func1);
 
if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
/* assign GPIO to SDIO core */
@@ -157,13 +159,13 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
);
-   sdio_release_host(sdiodev->func1);
+   sdio_release_host(func1);
} else {
brcmf_dbg(SDIO, "Entering\n");
-   sdio_claim_host(sdiodev->func1);
-   sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler);
-   sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler);
-   sdio_release_host(sdiodev->func1);
+   sdio_claim_host(func1);
+   sdio_claim_irq(func1, brcmf_sdiod_ib_irqhandler);
+   sdio_claim_irq(func2, brcmf_sdiod_dummy_irqhandler);
+   sdio_release_host(func1);
sdiodev->sd_irq_requested = true;
}
 
@@ -172,6 +174,8 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
 void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
 {
+   struct sdio_func *func1 = sdiodev->func1;
+   struct sdio_func *func2 = sdiodev->func2;
 
brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",
  sdiodev->oob_irq_requested,
@@ -181,26 +185,26 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
struct brcmfmac_sdio_pd *pdata;
 
pdata = >settings->bus.sdio;
-   sdio_claim_host(sdiodev->func1);
+   sdio_claim_host(func1);
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->func1);
+   sdio_release_host(func1);
 
sdiodev->oob_irq_requested = false;
if (sdiodev->irq_wake) {
disable_irq_wake(pdata->oob_irq_nr);
sdiodev->irq_wake = false;
}
-   free_irq(pdata->oob_irq_nr, >func1->dev);
+   free_irq(pdata->oob_irq_nr, >dev);
sdiodev->irq_en = false;
sdiodev->oob_irq_requested = false;
}
 
if (sdiodev->sd_irq_requested) {
-   sdio_claim_host(sdiodev->func1);
-   sdio_release_irq(sdiodev->func2);
-   sdio_release_irq(sdiodev->func1);
-   sdio_release_host(sdiodev->func1);
+   sdio_claim_host(func1);
+   sdio_release_irq(func2);
+   sdio_release_irq(

[PATCH 22/30] brcmfmac: Rename buscore->core for consistency

2017-08-22 Thread Ian Molton
Avoid confusion with unrelated _buscore labels.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index c1f3366871e5..09b4db117e0d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -2475,14 +2475,12 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio 
*bus)
 
 static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 {
-   struct brcmf_core *buscore = bus->sdio_core;
-   u32 addr;
+   struct brcmf_core *core = bus->sdio_core;
unsigned long val;
int ret;
 
-   addr = buscore->base + __sd_reg(intstatus);
-
-   val = brcmf_sdiod_readl(bus->sdiodev, addr, );
+   val = brcmf_sdiod_readl(bus->sdiodev, core->base + __sd_reg(intstatus),
+   );
bus->sdcnt.f1regdata++;
if (ret != 0)
return ret;
@@ -2492,7 +2490,8 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 
/* Clear interrupts */
if (val) {
-   brcmf_sdiod_writel(bus->sdiodev, addr, val, );
+   brcmf_sdiod_writel(bus->sdiodev,
+  core->base + __sd_reg(intstatus), val, );
bus->sdcnt.f1regdata++;
atomic_or(val, >intstatus);
}
-- 
2.11.0



[PATCH 26/30] brcmfmac: More efficient and slightly easier to read fixup for 4339 chips

2017-08-22 Thread Ian Molton
Its more efficient to test the register we're interested in first,
potentially avoiding two more comparisons, and therefore always avoiding
one comparison per call on all other chips.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 7ebe6460cb5c..8a730133db77 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3766,15 +3766,18 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 
addr)
/* Force 4339 chips over rev2 to use the same ID */
/* This is borderline tolerable whilst there is only two exceptions */
/* But could be handled better */
-   if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
-sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
-addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
+   if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) && 
+   (sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339 ||
+sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) {
+
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
+
if (rev >= 2) {
val &= ~CID_ID_MASK;
val |= BRCM_CC_4339_CHIP_ID;
}
}
+
return val;
 }
 
-- 
2.11.0



[PATCH 19/30] brcmfmac: Remove unused macro.

2017-08-22 Thread Ian Molton
This macro is used exactly nowhere in the code. Delete it.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 8f3e99da871a..b095bb66fe96 100644
--- 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_LEN6
 
-#define CORE_BUS_REG(base, field) \
-   (base + offsetof(struct sdpcmd_regs, field))
 #define __sd_reg(field) \
(offsetof(struct sdpcmd_regs, field))
 
-- 
2.11.0



[PATCH 13/30] brcmfmac: Clarify if using braces.

2017-08-22 Thread Ian Molton
Whilst this if () statement is technically correct, it lacks clarity.


Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index d5d2bcc1..257655d7fce4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -745,16 +745,17 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
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;
 }
-- 
2.11.0



[PATCH 14/30] brcmfmac: Rename / replace old IO functions with simpler ones.

2017-08-22 Thread Ian Molton
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 <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 166 +++
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 182 ++---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|  28 +++-
 3 files changed, 132 insertions(+), 244 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 257655d7fce4..50f207bb3dc6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -137,27 +137,25 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
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, );
+   gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, );
gpiocontrol |= 0x2;
-   brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, );
+   brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, );
 
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
- );
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, );
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, );
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT, 0xf, 
);
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, );
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, );
}
 
/* must configure SDIO_CCCR_IENx to enable irq */
-   data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, );
+   data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, );
data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
-   brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, );
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, );
 
/* 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, );
-
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
);
sdio_release_host(sdiodev->func[1]);
} else {
brcmf_dbg(SDIO, "Entering\n");
@@ -183,8 +181,8 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
 
pdata = >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 +240,8 @@ static int brcmf_sdiod_set_sbaddr_window(struct 
brcmf_sdio_dev *sdiodev,
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, );
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
+  addr & 0xff, );
 
return err;
 }
@@ -267,123 +265,15 @@ static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev 
*sdiodev, u32 *addr)
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, _ret);
-   else
-   sdio_f0_writeb(func, byte, regaddr, _ret);
-
-   return err_ret;
-}
-
-static int

[PATCH 28/30] brcmfmac: Clean up interrupt macros

2017-08-22 Thread Ian Molton
Make it more obvious that this code acually enables interrupts, and
provide nice definitions for the bits in the register.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++-
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 8 +---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 0cd081d732f9..75e9a70857e3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -148,7 +148,8 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
/* must configure SDIO_CCCR_IENx to enable irq */
data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, );
-   data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
+   data |= SDIO_CCCR_IEN_FUNC1 | SDIO_CCCR_IEN_FUNC2 |
+   SDIO_CCCR_IEN_FUNC0;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, );
 
/* redirect, configure and enable io for interrupt signal */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 54a03036fccb..04661ecbf395 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -24,9 +24,6 @@
 /* Maximum number of I/O funcs */
 #define NUM_SDIO_FUNCS 3
 
-#define SDIO_FUNC_11
-#define SDIO_FUNC_22
-
 #define SDIOD_FBR_SIZE 0x100
 
 /* io_en */
@@ -52,6 +49,11 @@
 #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT   BIT(2)
 #define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC   BIT(3)
 
+/* Interrupt enable bits for each function */
+#define SDIO_CCCR_IEN_FUNC0BIT(0)
+#define SDIO_CCCR_IEN_FUNC1BIT(1)
+#define SDIO_CCCR_IEN_FUNC2BIT(2)
+
 #define SDIO_CCCR_BRCM_CARDCTRL0xf1
 #define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET  BIT(1)
 
-- 
2.11.0



[PATCH 12/30] brcmfmac: Whitespace fixes.

2017-08-22 Thread Ian Molton
Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 916f75e5e7a1..d5d2bcc1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -713,6 +713,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
int err;
 
mypkt = brcmu_pkt_buf_get_skb(nbytes);
+
if (!mypkt) {
brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
  nbytes);
@@ -727,8 +728,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
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,
-- 
2.11.0



[PATCH 23/30] brcmfmac: stabilise the value of ->sbwad in use for some xfer routines.

2017-08-22 Thread Ian Molton
The IO functions operate within the Chipcommon IO window. Explicitly
set this, rather than relying on the last initialisation IO access to
leave it set to the right value by chance.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c   | 5 +
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index cabfab9a02a2..eeddefeef9b9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -527,7 +527,7 @@ int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
 
 int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)
 {
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err = 0;
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
@@ -550,7 +550,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
 {
struct sk_buff *glom_skb = NULL;
struct sk_buff *skb;
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err = 0;
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
@@ -591,7 +591,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
 int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
 {
struct sk_buff *mypkt;
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err;
 
mypkt = brcmu_pkt_buf_get_skb(nbytes);
@@ -623,7 +623,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
 struct sk_buff_head *pktq)
 {
struct sk_buff *skb;
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err;
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 09b4db117e0d..62561782ab90 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3833,6 +3833,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
if (!bus->sdio_core)
goto fail;
 
+   /* Pick up the CHIPCOMMON core info struct, for bulk IO in bcmsdh.c */
+   sdiodev->cc_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_CHIPCOMMON);
+   if (!sdiodev->cc_core)
+   goto fail;
+
sdiodev->settings = brcmf_get_module_param(sdiodev->dev,
   BRCMF_BUSTYPE_SDIO,
   bus->ci->chip,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 01def16cd236..ac5f814ff019 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -178,6 +178,7 @@ struct brcmf_sdio_dev {
struct sdio_func *func[SDIO_MAX_FUNCS];
u8 num_funcs;   /* Supported funcs on client */
u32 sbwad;  /* Save backplane window address */
+   struct brcmf_core *cc_core; /* chipcommon core info struct */
struct brcmf_sdio *bus;
struct device *dev;
struct brcmf_bus *bus_if;
-- 
2.11.0



[PATCH 25/30] brcmfmac: Remove func0 from function array

2017-08-22 Thread Ian Molton
Linux doesnt pass you func0 as a function when probing - instead
providing specific access functions to read/write it.

This prepares for a patch to remove the actual array entry itself.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  5 +
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c   | 10 +++---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 13 ++---
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 5fa77f8c0abb..69a6699126fd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -1019,8 +1019,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
/* store refs to functions used. mmc_card does
 * not hold the F0 function pointer.
 */
-   sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
-   sdiodev->func[0]->num = 0;
+   sdiodev->func[0] = NULL;
sdiodev->func[1] = func->card->sdio_func[0];
sdiodev->func[2] = func;
 
@@ -1046,7 +1045,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
 fail:
dev_set_drvdata(>dev, NULL);
dev_set_drvdata(>func[1]->dev, NULL);
-   kfree(sdiodev->func[0]);
kfree(sdiodev);
kfree(bus_if);
return err;
@@ -1079,7 +1077,6 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
dev_set_drvdata(>func[2]->dev, NULL);
 
kfree(bus_if);
-   kfree(sdiodev->func[0]);
kfree(sdiodev);
}
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 62561782ab90..7ebe6460cb5c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3762,9 +3762,13 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
u32 val, rev;
 
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)) {
+
+   /* Force 4339 chips over rev2 to use the same ID */
+   /* This is borderline tolerable whilst there is only two exceptions */
+   /* But could be handled better */
+   if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
+sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
+addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
if (rev >= 2) {
val &= ~CID_ID_MASK;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index d113c7d814b6..6e2fc065b8a7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -21,7 +21,9 @@
 #include 
 #include "firmware.h"
 
-#define SDIO_FUNC_00
+/* Maximum number of I/O funcs */
+#define NUM_SDIO_FUNCS 3
+
 #define SDIO_FUNC_11
 #define SDIO_FUNC_22
 
@@ -39,9 +41,6 @@
 #define INTR_STATUS_FUNC1  0x2
 #define INTR_STATUS_FUNC2  0x4
 
-/* Maximum number of I/O funcs */
-#define SDIOD_MAX_IOFUNCS  7
-
 /* mask of register map */
 #define REG_F0_REG_MASK0x7FF
 #define REG_F1_MISC_MASK   0x1
@@ -175,7 +174,7 @@ struct brcmf_sdio;
 struct brcmf_sdiod_freezer;
 
 struct brcmf_sdio_dev {
-   struct sdio_func *func[SDIO_MAX_FUNCS];
+   struct sdio_func *func[NUM_SDIO_FUNCS];
u8 num_funcs;   /* Supported funcs on client */
u32 sbwad;  /* Save backplane window address */
struct brcmf_core *cc_core; /* chipcommon core info struct */
@@ -297,10 +296,10 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev);
 /* SDIO device register access interface */
 /* Accessors for SDIO Function 0 */
 #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
-   sdio_f0_readb((sdiodev)->func[0], (addr), (r))
+   sdio_f0_readb((sdiodev)->func[1], (addr), (r))
 
 #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
-   sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
+   sdio_f0_writeb((sdiodev)->func[1], (v), (addr), (ret))
 
 /* Accessors for SDIO Function 1 */
 #define brcmf_sdiod_readb(sdiodev, addr, r) \
-- 
2.11.0



[PATCH 21/30] brcmfmac: Remove {r,w}_sdreg32

2017-08-22 Thread Ian Molton
Remove yet another IO function from the code and replace with one
that already exists.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 91 +++---
 1 file changed, 45 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 289ff61b7bf8..c1f3366871e5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -657,30 +657,6 @@ static bool data_ok(struct brcmf_sdio *bus)
   ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
 }
 
-/*
- * Reads a register in the SDIO hardware block. This block occupies a series of
- * adresses on the 32 bit backplane bus.
- */
-static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
-{
-   struct brcmf_core *core = bus->sdio_core;
-   int ret;
-
-   *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, );
-
-   return ret;
-}
-
-static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
-{
-   struct brcmf_core *core = bus->sdio_core;
-   int ret;
-
-   brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, );
-
-   return ret;
-}
-
 static int
 brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
 {
@@ -1075,6 +1051,8 @@ static void brcmf_sdio_get_console_addr(struct brcmf_sdio 
*bus)
 
 static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
 {
+   struct brcmf_sdio_dev *sdiod = bus->sdiodev;
+   struct brcmf_core *core = bus->sdio_core;
u32 intstatus = 0;
u32 hmb_data;
u8 fcbits;
@@ -1083,10 +1061,13 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
brcmf_dbg(SDIO, "Enter\n");
 
/* Read mailbox data and ack that we did so */
-   ret = r_sdreg32(bus, _data, __sd_reg(tohostmailboxdata));
+   hmb_data = brcmf_sdiod_readl(sdiod, core->base +
+   __sd_reg(tohostmailboxdata), );
+
+   if (!ret)
+   brcmf_sdiod_writel(sdiod, core->base + __sd_reg(tosbmailbox),
+  SMB_INT_ACK, );
 
-   if (ret == 0)
-   w_sdreg32(bus, SMB_INT_ACK, __sd_reg(tosbmailbox));
bus->sdcnt.f1regdata += 2;
 
/* Dongle recomposed rx frames, accept them again */
@@ -1155,6 +1136,8 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
 
 static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
 {
+   struct brcmf_sdio_dev *sdiod = bus->sdiodev;
+   struct brcmf_core *core = bus->sdio_core;
uint retries = 0;
u16 lastrbc;
u8 hi, lo;
@@ -1194,7 +1177,8 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, 
bool abort, bool rtx)
 
if (rtx) {
bus->sdcnt.rxrtx++;
-   err = w_sdreg32(bus, SMB_NAK, __sd_reg(tosbmailbox));
+   brcmf_sdiod_writel(sdiod, core->base + __sd_reg(tosbmailbox),
+  SMB_NAK, );
 
bus->sdcnt.f1regdata++;
if (err == 0)
@@ -2279,6 +2263,7 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, 
struct sk_buff_head *pktq,
 
 static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
 {
+   struct brcmf_core *core = bus->sdio_core;
struct sk_buff *pkt;
struct sk_buff_head pktq;
u32 intstatus = 0;
@@ -2319,7 +2304,9 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, 
uint maxframes)
if (!bus->intr) {
/* Check device status, signal pending interrupt */
sdio_claim_host(bus->sdiodev->func[1]);
-   ret = r_sdreg32(bus, , __sd_reg(intstatus));
+   intstatus = brcmf_sdiod_readl(bus->sdiodev, core->base +
+ __sd_reg(intstatus),
+ );
sdio_release_host(bus->sdiodev->func[1]);
bus->sdcnt.f2txdata++;
if (ret != 0)
@@ -2403,12 +2390,13 @@ static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio 
*bus, u8 *frame, u16 len)
 
 static void brcmf_sdio_bus_stop(struct device *dev)
 {
-   u32 local_hostintmask;
-   u8 saveclk;
-   int err;
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;
+   u32 local_hostintmask;
+   u8 saveclk;
+   int err;
 
brcmf_dbg(TRACE, "Enter\n");
 
@@ -2425,7 +2413,9 @@ static void brcmf_sdio_bus_stop(struct device *dev)
brcmf_sdio_bus_sleep(bus, fal

[PATCH 18/30] brcmfmac: Cleanup offsetof()

2017-08-22 Thread Ian Molton
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 <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 35 +-
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index ce19ccf5d1d6..8f3e99da871a 100644
--- 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 */
@@ -1084,12 +1086,10 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
brcmf_dbg(SDIO, "Enter\n");
 
/* Read mailbox data and ack that we did so */
-   ret = r_sdreg32(bus, _data,
-   offsetof(struct sdpcmd_regs, tohostmailboxdata));
+   ret = r_sdreg32(bus, _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 recomposed rx frames, accept them again */
@@ -1197,8 +1197,7 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, 
bool abort, bool rtx)
 
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)
@@ -2323,9 +2322,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, 
uint maxframes)
if (!bus->intr) {
/* Check device status, signal pending interrupt */
sdio_claim_host(bus->sdiodev->func[1]);
-   ret = r_sdreg32(bus, ,
-   offsetof(struct sdpcmd_regs,
-intstatus));
+   ret = r_sdreg32(bus, , __sd_reg(intstatus));
sdio_release_host(bus->sdiodev->func[1]);
bus->sdcnt.f2txdata++;
if (ret != 0)
@@ -2431,7 +2428,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
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;
 
@@ -2450,8 +2447,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
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]);
}
@@ -2497,7 +2493,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
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, );
bus->sdcnt.f1regdata++;
@@ -2574,11 +2570,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
 */
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, ,
-   offsetof(struct sdpcmd_regs, intstatus));
+   err = r_sdreg32(bus, , __sd_reg(intstatus));
bus->sdcnt.f1regdata += 2;
atomic_set(>fcstate,
   !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
@@ -3760,7 +3754,7 @@ static void brcmf_sdio_buscore_activate(void *ctx, struct 
brcmf_chip *chip,
 
/* clear all interrupts */
core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
-   reg_addr = core->base + 

[PATCH 20/30] brcmfmac: Remove repeated calls to brcmf_chip_get_core()

2017-08-22 Thread Ian Molton
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 <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 25 +-
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b095bb66fe96..289ff61b7bf8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -435,6 +435,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 */
@@ -662,10 +663,9 @@ static bool data_ok(struct brcmf_sdio *bus)
  */
 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, );
 
return ret;
@@ -673,10 +673,9 @@ static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, 
u32 offset)
 
 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, );
 
return ret;
@@ -2485,12 +2484,11 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio 
*bus)
 
 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, );
@@ -3367,13 +3365,14 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
 /* 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, );
@@ -3401,6 +3400,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
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;
@@ -3409,7 +3409,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
 * 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", ,
@@ -3747,11 +3747,10 @@ static void brcmf_sdio_buscore_activate(void *ctx, 
struct brcmf_chip *chip,
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, 0x, NULL);
 
@@ -3832,6 +3831,12 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
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,
-- 
2.11.0



[PATCH 11/30] brcmfmac: Split brcmf_sdiod_buffrw function up.

2017-08-22 Thread Ian Molton
This function needs to be split up into separate read / write variants
for clarity.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 67 +++---
 1 file changed, 45 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 834aa3e358ce..916f75e5e7a1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -413,8 +413,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 
addr,
*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;
@@ -423,18 +423,36 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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;
 }
 
@@ -642,7 +660,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, 
struct sk_buff *pkt)
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;
@@ -664,14 +682,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
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;
 
@@ -706,8 +724,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
err = brcmf_sdiod_addrprep(sdiodev, );
 
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;
@@ -729,8 +746,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
 
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;
}
@@ -782,10 +799,

[PATCH 17/30] brcmfamc: remove unnecessary call to brcmf_sdiod_set_backplane_window()

2017-08-22 Thread Ian Molton
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 <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 0d37c68637f2..cabfab9a02a2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -721,11 +721,6 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
 
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;
-- 
2.11.0



[PATCH 16/30] brcmfmac: Remove brcmf_sdiod_addrprep()

2017-08-22 Thread Ian Molton
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 <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 84 --
 1 file changed, 46 insertions(+), 38 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 721c7bd9478f..0d37c68637f2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -228,41 +228,25 @@ void brcmf_sdiod_change_state(struct brcmf_sdio_dev 
*sdiodev,
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, );
-
-   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, );
 
+   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)
@@ -270,11 +254,16 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
u32 data = 0;
int retval;
 
-   retval = brcmf_sdiod_addrprep(sdiodev, );
+   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, );
+   data = sdio_readl(sdiodev->func[1], addr, );
 
+out:
if (ret)
*ret = retval;
 
@@ -286,11 +275,16 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, 
u32 addr,
 {
int retval;
 
-   retval = brcmf_sdiod_addrprep(sdiodev, );
+   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, );
+   sdio_writel(sdiodev->func[1], data, addr, );
 
+out:
if (ret)
*ret = retval;
 }
@@ -538,10 +532,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, );
+   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:
@@ -559,10 +556,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
  addr, pktq->qlen);
 
-   err = brcmf_sdiod_addrprep(sdiodev, );
+   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);
@@ -604,7 +604,12 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, 
u8 *buf, uint nbytes)
 
memcpy(mypkt->data, buf, nbytes);
 
-   err = brcmf_sdiod_addrprep(sdiodev, );
+   err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+   if (err)
+   return err;
+
+  

[PATCH 24/30] brcmfmac: Correctly handle accesses to SDIO func0

2017-08-22 Thread Ian Molton
Rather than workaround the restrictions on func0 addressing in the
driver, set MMC_QUIRK_LENIENT_FN0

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index eeddefeef9b9..5fa77f8c0abb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -992,6 +992,10 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
brcmf_dbg(SDIO, "Function#: %d\n", func->num);
 
dev = >dev;
+
+   /* Set MMC_QUIRK_LENIENT_FN0 for this card */
+   func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+
/* prohibit ACPI power management for this device */
brcmf_sdiod_acpi_set_power_manageable(dev, 0);
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index ac5f814ff019..d113c7d814b6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -297,10 +297,10 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev);
 /* 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))
+   sdio_f0_readb((sdiodev)->func[0], (addr), (r))
 
 #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
-   sdio_writeb((sdiodev)->func[0], (v), (addr), (ret))
+   sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
 
 /* Accessors for SDIO Function 1 */
 #define brcmf_sdiod_readb(sdiodev, addr, r) \
-- 
2.11.0



[PATCH 04/30] brcmfmac: Clean up brcmf_sdiod_set_sbaddr_window()

2017-08-22 Thread Ian Molton
This function sets the address of the IO window used for
SDIO accesses onto the backplane of the chip.

It currently uses 3 separate masks despite the full mask being
defined in the code already. Remove the separate masks and clean up.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c   | 17 +
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  3 ---
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 1ee0f91b6c50..7b2184d1e365 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -410,23 +410,16 @@ static int
 brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
 {
int err = 0, i;
-   u8 addr[3];
+   u32 addr;
 
if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
return -ENOMEDIUM;
 
-   addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
-   addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
-   addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
+   addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
 
-   for (i = 0; i < 3; i++) {
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i],
- );
-   if (err) {
-   brcmf_err("failed at addr: 0x%0x\n",
- SBSDIO_FUNC1_SBADDRLOW + i);
-   }
-   }
+   for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
+   brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
+ addr & 0xff, );
 
return err;
 }
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index f3da32fc6360..e3b78db331b5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -133,9 +133,6 @@
 
 /* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
 
-#define SBSDIO_SBADDRLOW_MASK  0x80/* Valid bits in SBADDRLOW */
-#define SBSDIO_SBADDRMID_MASK  0xff/* Valid bits in SBADDRMID */
-#define SBSDIO_SBADDRHIGH_MASK 0xffU   /* Valid bits in SBADDRHIGH */
 /* Address bits from SBADDR regs */
 #define SBSDIO_SBWINDOW_MASK   0x8000
 
-- 
2.11.0



[PATCH 06/30] brcmfmac: Remove bandaid for SleepCSR

2017-08-22 Thread Ian Molton
Register access code is not the place for band-aid fixes like this.
If this is a genuine problem, it should be fixed further up in the driver
stack.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 28 +-
 1 file changed, 1 insertion(+), 27 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 609a934c1658..d217b1281e0d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -334,21 +334,8 @@ static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
} while (ret != 0 && ret != -ENOMEDIUM &&
 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 
-   if (ret == -ENOMEDIUM) {
+   if (ret == -ENOMEDIUM)
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
-   } else if (ret != 0) {
-   /*
-* SleepCSR register access can fail when
-* waking up the device so reduce this noise
-* in the logs.
-*/
-   if (addr != SBSDIO_FUNC1_SLEEPCSR)
-   brcmf_err("failed to write data F%d@0x%05x, err: %d\n",
- func, addr, ret);
-   else
-   brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: 
%d\n",
- func, addr, ret);
-   }
 
return ret;
 }
@@ -389,19 +376,6 @@ static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
 
if (ret == -ENOMEDIUM)
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
-   else if (ret != 0) {
-   /*
-* SleepCSR register access can fail when
-* waking up the device so reduce this noise
-* in the logs.
-*/
-   if (addr != SBSDIO_FUNC1_SLEEPCSR)
-   brcmf_err("failed to read data F%d@0x%05x, err: %d\n",
- func, addr, ret);
-   else
-   brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: 
%d\n",
- func, addr, ret);
-   }
 
return ret;
 }
-- 
2.11.0



[PATCH 07/30] brcmfmac: Remove brcmf_sdiod_request_data()

2017-08-22 Thread Ian Molton
This function is obfuscating how IO works on this chip. Remove it
and push its logic into brcmf_sdiod_reg_{read,write}().

Handling of -ENOMEDIUM is altered, but as that's pretty much broken anyway
we can ignore that.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 236 -
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|   2 +-
 2 files changed, 86 insertions(+), 152 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index d217b1281e0d..6659c614a17f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -230,6 +230,43 @@ void brcmf_sdiod_change_state(struct brcmf_sdio_dev 
*sdiodev,
sdiodev->state = state;
 }
 
+static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
+u32 address)
+{
+   int err = 0, i;
+   u32 addr;
+
+   if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
+   return -ENOMEDIUM;
+
+   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, );
+
+   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;
+
+   sdiodev->sbwad = bar0;
+   }
+
+   *addr &= SBSDIO_SB_OFT_ADDR_MASK;
+   *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+   return 0;
+}
+
 static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
uint regaddr)
 {
@@ -249,173 +286,83 @@ static inline int brcmf_sdiod_f0_writeb(struct sdio_func 
*func, u8 byte,
return err_ret;
 }
 
-static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
-   u32 addr, u8 regsz, void *data, bool write)
-{
-   struct sdio_func *func;
-   int ret = -EINVAL;
-
-   brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
- write, fn, addr, regsz);
-
-   /* only allow byte access on F0 */
-   if (WARN_ON(regsz > 1 && !fn))
-   return -EINVAL;
-   func = sdiodev->func[fn];
-
-   switch (regsz) {
-   case 1:
-   if (write) {
-   if (fn)
-   sdio_writeb(func, *(u8 *)data, addr, );
-   else
-   ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data,
-   addr);
-   } else {
-   if (fn)
-   *(u8 *)data = sdio_readb(func, addr, );
-   else
-   *(u8 *)data = sdio_f0_readb(func, addr, );
-   }
-   break;
-   case 2:
-   if (write)
-   sdio_writew(func, *(u16 *)data, addr, );
-   else
-   *(u16 *)data = sdio_readw(func, addr, );
-   break;
-   case 4:
-   if (write)
-   sdio_writel(func, *(u32 *)data, addr, );
-   else
-   *(u32 *)data = sdio_readl(func, addr, );
-   break;
-   default:
-   brcmf_err("invalid size: %d\n", regsz);
-   break;
-   }
-
-   if (ret)
-   brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
- write ? "write" : "read", fn, addr, ret);
-
-   return ret;
-}
-
 static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
 u8 regsz, void *data)
 {
-   u8 func;
-   s32 retry = 0;
int ret;
 
-   if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
-   return -ENOMEDIUM;
-
/*
 * figure out how to read the register based on address range
 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
 * 0x1 ~ 0x1: function 1 miscellaneous registers
 * The rest: function 1 silicon backplane core registers
+* f0 writes must be bytewise
 */
-   if ((addr & ~REG_F0_REG_MASK) == 0)
-   func = SDIO_FUNC_0;
-   else
-   func = SDIO_FUNC_1;
 
-   do {
-   /* for retry wait for 1 ms till bus get settled down */
-

[PATCH 09/30] brcmfmac: Remove noisy debugging.

2017-08-22 Thread Ian Molton
If you need debugging this low level, you're doing something wrong.
Remove these noisy debug statements so the code is more readable.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 074dc10b5ac5..6669e28279d9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -370,9 +370,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
u8 data;
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, );
-   brcmf_dbg(SDIO, "data:0x%02x\n", data);
 
if (ret)
*ret = retval;
@@ -385,9 +383,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
u32 data;
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, );
-   brcmf_dbg(SDIO, "data:0x%08x\n", data);
 
if (ret)
*ret = retval;
@@ -400,7 +396,6 @@ void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 
addr,
 {
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, );
 
if (ret)
@@ -412,7 +407,6 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 
addr,
 {
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, );
 
if (ret)
-- 
2.11.0



[PATCH 08/30] brcmfmac: Fix asymmetric IO functions.

2017-08-22 Thread Ian Molton
Unlikely to be a problem, but brcmf_sdiod_regrb() is
not symmetric with brcmf_sdiod_regrl(). Fix.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 6659c614a17f..074dc10b5ac5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -382,7 +382,7 @@ 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)
 {
-   u32 data = 0;
+   u32 data;
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-- 
2.11.0



[PATCH 05/30] brcmfmac: Remove dead IO code

2017-08-22 Thread Ian Molton
The value passed to brcmf_sdiod_addrprep() is *always* 4
remove this parameter and the unused code to handle it.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 7b2184d1e365..609a934c1658 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -425,7 +425,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev 
*sdiodev, u32 address)
 }
 
 static int
-brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
+brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
 {
uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
@@ -439,9 +439,7 @@ brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint 
width, u32 *addr)
}
 
*addr &= SBSDIO_SB_OFT_ADDR_MASK;
-
-   if (width == 4)
-   *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+   *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
return 0;
 }
@@ -467,7 +465,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
+   retval = brcmf_sdiod_addrprep(sdiodev, );
if (retval)
goto done;
 
@@ -500,7 +498,7 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 
addr,
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
-   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
+   retval = brcmf_sdiod_addrprep(sdiodev, );
if (retval)
goto done;
 
@@ -736,7 +734,7 @@ 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, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
if (err)
goto done;
 
@@ -757,7 +755,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
  addr, pktq->qlen);
 
-   err = brcmf_sdiod_addrprep(sdiodev, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
if (err)
goto done;
 
@@ -801,7 +799,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
 
memcpy(mypkt->data, buf, nbytes);
 
-   err = brcmf_sdiod_addrprep(sdiodev, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
 
if (!err)
err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
@@ -821,7 +819,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
 
-   err = brcmf_sdiod_addrprep(sdiodev, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
if (err)
return err;
 
-- 
2.11.0



[PATCH 03/30] brcmfmac: Split brcmf_sdiod_regrw_helper() up.

2017-08-22 Thread Ian Molton
This large function is concealing a LOT of obscure logic about
how the hardware functions. Time to split it up.

This first patch splits the function into two pieces - read and write,
doing away with the rw flag in the process.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 94 +-
 1 file changed, 73 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 2b441ce91d5f..1ee0f91b6c50 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -302,8 +302,8 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
return ret;
 }
 
-static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
-  u8 regsz, void *data, bool write)
+static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
+u8 regsz, void *data)
 {
u8 func;
s32 retry = 0;
@@ -324,13 +324,66 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
func = SDIO_FUNC_1;
 
do {
-   if (!write)
-   memset(data, 0, regsz);
/* for retry wait for 1 ms till bus get settled down */
if (retry)
usleep_range(1000, 2000);
+
+   ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
+  data, true);
+
+   } while (ret != 0 && ret != -ENOMEDIUM &&
+retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
+
+   if (ret == -ENOMEDIUM) {
+   brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
+   } else if (ret != 0) {
+   /*
+* SleepCSR register access can fail when
+* waking up the device so reduce this noise
+* in the logs.
+*/
+   if (addr != SBSDIO_FUNC1_SLEEPCSR)
+   brcmf_err("failed to write data F%d@0x%05x, err: %d\n",
+ func, addr, ret);
+   else
+   brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: 
%d\n",
+ func, addr, ret);
+   }
+
+   return ret;
+}
+
+static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr,
+   u8 regsz, void *data)
+{
+   u8 func;
+   s32 retry = 0;
+   int ret;
+
+   if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
+   return -ENOMEDIUM;
+
+   /*
+* figure out how to read the register based on address range
+* 0x00 ~ 0x7FF: function 0 CCCR and FBR
+* 0x1 ~ 0x1: function 1 miscellaneous registers
+* The rest: function 1 silicon backplane core registers
+*/
+   if ((addr & ~REG_F0_REG_MASK) == 0)
+   func = SDIO_FUNC_0;
+   else
+   func = SDIO_FUNC_1;
+
+   do {
+   memset(data, 0, regsz);
+
+   /* for retry wait for 1 ms till bus get settled down */
+   if (retry)
+   usleep_range(1000, 2000);
+
ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
-  data, write);
+  data, false);
+
} while (ret != 0 && ret != -ENOMEDIUM &&
 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 
@@ -343,12 +396,13 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
 * in the logs.
 */
if (addr != SBSDIO_FUNC1_SLEEPCSR)
-   brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
- write ? "write" : "read", func, addr, ret);
+   brcmf_err("failed to read data F%d@0x%05x, err: %d\n",
+ func, addr, ret);
else
-   brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: 
%d\n",
- write ? "write" : "read", func, addr, ret);
+   brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: 
%d\n",
+ func, addr, ret);
}
+
return ret;
 }
 
@@ -366,13 +420,11 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev 
*sdiodev, u32 address)
addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
 
for (i = 0; i < 3; i++) {
-   err 

[PATCH v5] brcmfmac cleanup

2017-08-22 Thread Ian Molton
Hi folks,

Arend, as requested - a respin to take account of your comments.

Unfortunately, although I've only included the patches you requested from v4,
breaking out some of the simpler changes (whitespace, macos, etc.) has grown
the set back up to 30 patches. I hope this is OK.

I've tried to include everything you asked for but may not have understood
everything you wrote, so please bear with me :) Im happy to keep at this until
it's right.

I did have to include a couple of patches from v4 that you didnt request,
because they were dependencies of ones you wanted. I've kept this as minimal
as possible, however.

The whole patchset was compile tested at each commit on 4.13-rc5.

No functional changes from v4 (other than this is a subset of the v4 series).

-Ian



[PATCH 01/30] brcmfmac: Fix parameter order in brcmf_sdiod_f0_writeb()

2017-08-22 Thread Ian Molton
All the other IO functions are the other way round in this
driver. Make this one match.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 984c1d0560b1..f585dfd89453 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -230,8 +230,8 @@ void brcmf_sdiod_change_state(struct brcmf_sdio_dev 
*sdiodev,
sdiodev->state = state;
 }
 
-static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
-   uint regaddr, u8 byte)
+static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
+   uint regaddr)
 {
int err_ret;
 
@@ -269,8 +269,8 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
if (fn)
sdio_writeb(func, *(u8 *)data, addr, );
else
-   ret = brcmf_sdiod_f0_writeb(func, addr,
-   *(u8 *)data);
+   ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data,
+   addr);
} else {
if (fn)
*(u8 *)data = sdio_readb(func, addr, );
-- 
2.11.0



[PATCH 02/30] brcmfmac: Register sizes on hardware are not dependent on compiler types

2017-08-22 Thread Ian Molton
The 4 IO functions in this patch are incorrect as they use compiler types
to determine how many bytes to send to the hardware.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index f585dfd89453..2b441ce91d5f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -264,7 +264,7 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
func = sdiodev->func[fn];
 
switch (regsz) {
-   case sizeof(u8):
+   case 1:
if (write) {
if (fn)
sdio_writeb(func, *(u8 *)data, addr, );
@@ -278,13 +278,13 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
*(u8 *)data = sdio_f0_readb(func, addr, );
}
break;
-   case sizeof(u16):
+   case 2:
if (write)
sdio_writew(func, *(u16 *)data, addr, );
else
*(u16 *)data = sdio_readw(func, addr, );
break;
-   case sizeof(u32):
+   case 4:
if (write)
sdio_writel(func, *(u32 *)data, addr, );
else
@@ -368,7 +368,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev 
*sdiodev, u32 address)
for (i = 0; i < 3; i++) {
err = brcmf_sdiod_regrw_helper(sdiodev,
   SBSDIO_FUNC1_SBADDRLOW + i,
-  sizeof(u8), [i], true);
+  1, [i], true);
if (err) {
brcmf_err("failed at addr: 0x%0x\n",
  SBSDIO_FUNC1_SBADDRLOW + i);
@@ -407,7 +407,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, ,
  false);
brcmf_dbg(SDIO, "data:0x%02x\n", data);
 
@@ -423,10 +423,10 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-   retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), );
+   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
if (retval)
goto done;
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, ,
  false);
brcmf_dbg(SDIO, "data:0x%08x\n", data);
 
@@ -443,7 +443,7 @@ void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 
addr,
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, ,
  true);
if (ret)
*ret = retval;
@@ -455,10 +455,10 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, 
u32 addr,
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
-   retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), );
+   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
if (retval)
goto done;
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, ,
  true);
 
 done:
@@ -876,7 +876,7 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint 
fn)
 
/* issue abort cmd52 command through F0 */
brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT,
-sizeof(t_func), _func, true);
+1, _func, true);
 
brcmf_dbg(SDIO, "Exit\n");
return 0;
-- 
2.11.0



Re: [PATCH 12/34] brcmfmac: Replace old IO functions with simpler ones.

2017-08-19 Thread Ian Molton
On 07/08/17 18:55, Ian Molton wrote:
> On 07/08/17 12:26, Arend van Spriel wrote:
>> On 7/26/2017 10:25 PM, Ian Molton wrote:
>>> Primarily this patch removes:
>>>
>>> brcmf_sdiod_f0_writeb()
>>> brcmf_sdiod_reg_write()
>>> brcmf_sdiod_reg_read()
>>
>> Having [patch 30/34] "brcmfmac: Correctly handle accesses to SDIO func0"
>> before this patch could make this look cleaner.
> 
> This is an artifact of how I came to the realisation the code was using
> the obsoleted functions - it could be reordered, but it'd probably get
> messy...

I gave it a try, and it got messy - I'd prefer to leave these patches in
their current ordering if thats OK.

-Ian


Re: [PATCH 11/34] brcmfmac: Split brcmf_sdiod_buffrw function up.

2017-08-19 Thread Ian Molton
On 07/08/17 12:26, Arend van Spriel wrote:

>> +err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
>>
>>   brcmu_pkt_buf_free_skb(mypkt);
>> +
> 
> You are keen on sprinkling whitespace here and there. Could you please
> use separate patches for that as much as possible. Not sure why you
> added this one...
> 
>>   return err;
>>
> 
> ...and kept this one.
> 
>>   }
> 

Good catch. There's a couple of others - I'll break them out. That
latter one is clearly an error on my part.

-Ian


Re: [PATCH 08/34] brcmfmac: Fix uninitialised variable

2017-08-19 Thread Ian Molton
On 07/08/17 12:26, Arend van Spriel wrote:
> On 7/26/2017 10:25 PM, Ian Molton wrote:
>> Unlikely to be a problem, but brcmf_sdiod_regrb() is
>> not symmetric with brcmf_sdiod_regrl() in this regard.
> 
> You are pretty keen on symmetry, but you could also remove the
> initialization in brcmf_sdiod_regrl(). As long as no -Wunitialized pops
> up that would have my preference.

Whilst the compiler does not complain, there are paths through
brcmf_sdiod_reg_read() that do not set *data, so I think it best to
initialise the value, but its not really very important. Code that isn't
checking the return value is asking for it anyway :)

In the later patches we could remove the initialisation, as IIRC the
Linux MMC IO functions do it for us and we don't avoid calling them in
that version of the code.

-Ian


Re: [PATCH 06/34] brcmfmac: Remove bandaid for SleepCSR

2017-08-19 Thread Ian Molton
On 07/08/17 12:25, Arend van Spriel wrote:
> On 26-07-17 22:25, Ian Molton wrote:
>> Register access code is not the place for band-aid fixes like this.
>> If this is a genuine problem, it should be fixed further up in the driver
>> stack.
> 
> So lets make it a SDIO debug message for all register accesses getting
> rid of the error message.

Not quite sure I follow here - but as the code is completely gone in
later patches in the series, does it matter?

Perhaps address this if it in future, if it crops up as a problem, since
it wont be fatal even if it does...

-Ian


Re: [PATCH 34/34] brcmfmac: Reduce the noise from repeatedly dereferencing common pointers

2017-08-19 Thread Ian Molton
On 08/08/17 13:29, Arend van Spriel wrote:
>>  int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep)
>>  {
>> +struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
>> +struct sdio_func *func1 = sdiodev->func1;
>
> Actually only wanted to explicitly mention this one. Probably the
> compiler is smart enough to keep sdiodev from the stack, but I would say
> it is a variable you do not really need and also in terms of readability
> it seems clear enough to do it in one assignment.

Yeah, it could be - but as you say, the compiler *will* be smart enough,
and doing it in this manner makes it consistent with all the other code :-)

I'm looking at your other comments atm. :)

-Ian

>>  int ret;
>>  
>> -sdio_claim_host(bus->sdiodev->func1);
>> +sdio_claim_host(func1);
>>  ret = brcmf_sdio_bus_sleep(bus, sleep, false);
>> -sdio_release_host(bus->sdiodev->func1);
>> +sdio_release_host(func1);
>>  



Re: [PATCH 31/34] brcmfmac: Remove func0 from function array

2017-08-19 Thread Ian Molton
On 08/08/17 12:19, Arend van Spriel wrote:
>> -sdio_f0_readb((sdiodev)->func[0], (addr), (r))
>> +sdio_f0_readb((sdiodev)->func[1], (addr), (r))
> 
> There is no reason to keep these any longer as these do not provide any
> functionality over the core sdio function unless you consider the
> sdiodev dereference.

I'm happy to submit an incremental patch to these that gets us right
down to the linux mmc core functions. Just seemed like too big a change
to do in one hit.

-Ian


Re: [PATCH 29/34] brcmfmac: stabilise the value of ->sbwad in use for some xfer routines.

2017-08-19 Thread Ian Molton
On 07/08/17 13:32, Arend van Spriel wrote:
> 
> We actually just need the chipcommon base address so why not have that
> here, ie.:
> +u32 cc_base;

I see no advantage to that - the u32 is the same size as (or not much
bigger than the pointer to the struct brcmf_core, and my approach makes
it clear where the value came from rather than making another copy of it.

> Another option is to simple use SI_ENUM_BASE as the chipcommon base
> address will always be 0x1800 for the SDIO chips.

I don't like this approach. Why bother probing the core if we then dont
use the values returned? May as well hard code everything... Also not
futureproof.

-Ian


Re: [PATCH 14/34] brcmfmac: Remove brcmf_sdiod_addrprep()

2017-08-19 Thread Ian Molton
On 07/08/17 12:27, Arend van Spriel wrote:
> On 7/26/2017 10:25 PM, Ian Molton wrote:
>> 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.
> 
> Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
>> Signed-off-by: Ian Molton <i...@mnementh.co.uk>
> 
> comments below...
> 

>> -if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
>> -return -ENOMEDIUM;
> 
> So now you are dropping the state check here, which seems significant
> enough to mention in the commit log. We need to discuss that. The idea
> of it was to refrain from using IO function of the MMC stack when we no
> there is no longer a device, ie. when stack has previously returned a
> -ENOMEDIUM.

Yeah, that code is broken (see earlier email) AFAICT anyway, and we
should probably handle losing our card a lot more gracefully in general.

>> +if (bar0 == sdiodev->sbwad)
>> +return 0;
>>
>> -addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
>> +v = bar0 >> 8;
> 
> why introducing a new variable on the stack. You actually don't need any
> and just mask and shift the addr variable passed to the function.

Linux code *generally* doesn't do this. Its stylistic anyway, since the
compiler certainly won't be dumb enough to allocate another register (or
stack space) in this instance.

>>   if (!retval)
>>   data = sdio_readl(sdiodev->func[1], addr, );
> 
> The if-statement is now redundant here...

Good catch! :)

-Ian


Re: [PATCH 09/34] brcmfmac: Remove noisy debugging.

2017-08-19 Thread Ian Molton
On 07/08/17 12:26, Arend van Spriel wrote:
> 
> Needing this debugging does not necessarily means you are doing
> something wrong. You may be dealing with hardware that is doing
> something wrong and when that happens this debug can be useful. I
> frankly hardly ever enable SDIO debug level unless I am in that
> scenario. Maybe adding a debug level for low-level access would be
> useful to reduce the noise for SDIO debug level.

Perhaps, but its only actually called from a half dozen or so places in
the code + the buscore_*32 entrypoints.

All it actually does now is ensure the address window is right and call
the Linux SDIO core readl method. if we can't trust that, we're kinda
screwed anyway. If we later bring the SDIO code in line with the PCIe
code, it wont even do the address window checking (it'll just assume its
already correct).

We can always enable the SDIO core lowlevel debug if we really want to
see register level acceses.

-Ian


Re: [PATCH 07/34] brcmfmac: Remove brcmf_sdiod_request_data()

2017-08-19 Thread Ian Molton
On 07/08/17 18:51, Ian Molton wrote:
> On 07/08/17 12:25, Arend van Spriel wrote:
>>> Handling of -ENOMEDIUM is altered, but as that's pretty much broken
>>> anyway
>>> we can ignore that.
>>
>> Please explain why you think it is broken.
> 
> Not got the code to hand right now, but from memory, theres a trapdoor
> case where the state can wind up set to something that prevents it ever
> being changed again. I'll dig it up when I get back from holiday (this
> next few days).

Hi,

Here is the function I had in mind:


void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
  enum brcmf_sdiod_state state)
{
if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||
state == sdiodev->state)
return;

brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);
switch (sdiodev->state) {
case BRCMF_SDIOD_DATA:
/* any other state means bus interface is down */
brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
break;
case BRCMF_SDIOD_DOWN:
/* transition from DOWN to DATA means bus interface is up */
if (state == BRCMF_SDIOD_DATA)
brcmf_bus_change_state(sdiodev->bus_if,
BRCMF_BUS_UP);
break;
default:
break;
}
sdiodev->state = state;
}


If it's *ever*  called with state = BRCMF_SDIOD_NOMEDIUM it will
eventually (last line) set sdiodev->state to the same value.

If its ever called again, the first if() statement will make it return
before ever changing sdiodev->state again, no matter what value is
passed for state.

This has to be a bug, surely?

-Ian


Re: [PATCH 01/34] brcmfmac: Fix parameter order in brcmf_sdiod_f0_writeb()

2017-08-19 Thread Ian Molton
On 07/08/17 12:25, Arend van Spriel wrote:
>> All the other IO functions are the other way round in this
>> driver. Make this one match.
> 
> Core SDIO functions are indeed the other way around, but the IO
> functions in this file use (addr, data) pattern. So should we aim to get
> it all consistent with core SDIO or just consistent on its own.

This is preparatory for a later patch that removes this abstraction
altogether, so yes, it should match the SDIO order.

-Ian


Re: [PATCH 12/34] brcmfmac: Replace old IO functions with simpler ones.

2017-08-07 Thread Ian Molton
On 07/08/17 12:26, Arend van Spriel wrote:
> On 7/26/2017 10:25 PM, Ian Molton wrote:
>> Primarily this patch removes:
>>
>> brcmf_sdiod_f0_writeb()
>> brcmf_sdiod_reg_write()
>> brcmf_sdiod_reg_read()
> 
> Having [patch 30/34] "brcmfmac: Correctly handle accesses to SDIO func0"
> before this patch could make this look cleaner.

This is an artifact of how I came to the realisation the code was using
the obsoleted functions - it could be reordered, but it'd probably get
messy...

>> 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.
> 
> As mentioned here this is more a rename than a replace so please use
> that in the subject as well.

Noted.

> Reviewed-by: Arend van Spriel <arend.vanspr...@broadcom.com>
>> Signed-off-by: Ian Molton <i...@mnementh.co.uk>
>> ---
>>   .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 166
>> +++
>>   .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 182
>> ++---
>>   .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|  28 +++-
>>   3 files changed, 132 insertions(+), 244 deletions(-)
> 

-Ian


Re: [PATCH 07/34] brcmfmac: Remove brcmf_sdiod_request_data()

2017-08-07 Thread Ian Molton
On 07/08/17 12:25, Arend van Spriel wrote:
>> Handling of -ENOMEDIUM is altered, but as that's pretty much broken
>> anyway
>> we can ignore that.
> 
> Please explain why you think it is broken.

Not got the code to hand right now, but from memory, theres a trapdoor
case where the state can wind up set to something that prevents it ever
being changed again. I'll dig it up when I get back from holiday (this
next few days).

-Ian


Re: [PATCH 03/34] brcmfmac: Split brcmf_sdiod_regrw_helper() up.

2017-08-07 Thread Ian Molton
On 07/08/17 12:25, Arend van Spriel wrote:
> On 26-07-17 22:25, Ian Molton wrote:
>> This large function is concealing a LOT of obscure logic about
>> how the hardware functions. Time to split it up.
>>
>> This first patch splits the function into two pieces - read and write,
>> doing away with the rw flag in the process.
> 
> I really don't this it is all that obscure, but alas. Everything is in
> the eye of the beholder. The reason for having the helper was to not
> duplicate code for read and write and different access sizes. So now you
> are duplicating it. In subsequent patches you throw away pieces of this
> helper so duplication is not as bad in the net result. It would have
> been easier if those patches were done before this one.

I agree, this is a big and unwieldy patchset - I've attempted to break
the thing down in such a way that all the steps leading to the end
result are at least sane. I initially did it all in one hit and it was
utterly illegible :-(


> Fix the indent and column align to opening bracket.

I guess a few of these got through. I blame git rebase :)

-Ian


Re: Patch v4: Clean up brcmfmac driver

2017-07-27 Thread Ian Molton
On 27/07/17 11:09, Arend van Spriel wrote:
>>
>> Hi Arend,
>>
>> Noted for future series. I take it I shouldn't re-spin if you're going
>> through them already?
> 
> My "guess" is a v5 is likely ;-)

No prob. I've spotted a gem in it myself (FIXME comment that crept
through). I'll split it into two series at v5 then.

-Ian


Re: Patch v4: Clean up brcmfmac driver

2017-07-27 Thread Ian Molton
On 27/07/17 10:52, Arend van Spriel wrote:
>>
>> How many patches would you like at once?
> 
> Hi Ian,
> 
> ~10-15 patches should be fine although I am simply ploughing through the
> lot right now.

Hi Arend,

Noted for future series. I take it I shouldn't re-spin if you're going
through them already?

Thanks,

-Ian


Re: Patch v4: Clean up brcmfmac driver

2017-07-27 Thread Ian Molton
On 27/07/17 07:17, Kalle Valo wrote:
>> Here's a v4 of the cleanup patchset - checkpatch clean(er - I have purposely
>> left some warnings unaddressed).
>>
>> I also dropped an accidental adjustment of a debug macro from v3.
> Like I said already last time, please split the patchset into reasonable
> sizes (and submit one patchset at a time). I will automatically drop
> patchbombs like this.

How many patches would you like at once?

-Ian


[PATCH 13/34] brcmfmac: Tidy register definitions a little

2017-07-26 Thread Ian Molton
Trivial tidy of register definitions.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 4c81ea24d19c..fb4f24dfc99d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -51,17 +51,18 @@
 
 /* function 0 vendor specific CCCR registers */
 
-#define SDIO_CCCR_BRCM_CARDCAP 0xf0
+#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_CARDCTRL0xf1
 #define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET  0x02
-#define SDIO_CCCR_BRCM_SEPINT  0xf2
 
-#define  SDIO_SEPINT_MASK  0x01
-#define  SDIO_SEPINT_OE0x02
-#define  SDIO_SEPINT_ACT_HI0x04
+#define SDIO_CCCR_BRCM_SEPINT  0xf2
+#define SDIO_SEPINT_MASK   0x01
+#define SDIO_SEPINT_OE 0x02
+#define SDIO_SEPINT_ACT_HI 0x04
 
 /* function 1 miscellaneous registers */
 
-- 
2.11.0



[PATCH 31/34] brcmfmac: Remove func0 from function array

2017-07-26 Thread Ian Molton
Linux doesnt pass you func0 as a function when probing - instead
providing specific access functions to read/write it.

This prepares for a patch to remove the actual array entry itself.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  5 +
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c   |  6 +++---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 13 ++---
 3 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 95149c686c5f..da0654c50db9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -1021,8 +1021,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
/* store refs to functions used. mmc_card does
 * not hold the F0 function pointer.
 */
-   sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
-   sdiodev->func[0]->num = 0;
+   sdiodev->func[0] = NULL;
sdiodev->func[1] = func->card->sdio_func[0];
sdiodev->func[2] = func;
 
@@ -1048,7 +1047,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
 fail:
dev_set_drvdata(>dev, NULL);
dev_set_drvdata(>func[1]->dev, NULL);
-   kfree(sdiodev->func[0]);
kfree(sdiodev);
kfree(bus_if);
return err;
@@ -1081,7 +1079,6 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
dev_set_drvdata(>func[2]->dev, NULL);
 
kfree(bus_if);
-   kfree(sdiodev->func[0]);
kfree(sdiodev);
}
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 91a17ef63a6b..230a24cb6c0a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3766,9 +3766,9 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
/* Force 4339 chips over rev2 to use the same ID */
/* This is borderline tolerable whilst there is only two exceptions */
/* But could be handled better */
-   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)) {
+   if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
+sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
+addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
 
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 8a976c89cf63..227c90198a8e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -21,7 +21,9 @@
 #include 
 #include "firmware.h"
 
-#define SDIO_FUNC_00
+/* Maximum number of I/O funcs */
+#define NUM_SDIO_FUNCS 3
+
 #define SDIO_FUNC_11
 #define SDIO_FUNC_22
 
@@ -39,9 +41,6 @@
 #define INTR_STATUS_FUNC1  0x2
 #define INTR_STATUS_FUNC2  0x4
 
-/* Maximum number of I/O funcs */
-#define SDIOD_MAX_IOFUNCS  7
-
 /* mask of register map */
 #define REG_F0_REG_MASK0x7FF
 #define REG_F1_MISC_MASK   0x1
@@ -175,7 +174,7 @@ struct brcmf_sdio;
 struct brcmf_sdiod_freezer;
 
 struct brcmf_sdio_dev {
-   struct sdio_func *func[SDIO_MAX_FUNCS];
+   struct sdio_func *func[NUM_SDIO_FUNCS];
u8 num_funcs;   /* Supported funcs on client */
u32 sbwad;  /* Save backplane window address */
struct brcmf_core *cc_core; /* chipcommon core info struct */
@@ -297,10 +296,10 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev);
 /* SDIO device register access interface */
 /* Functions for accessing SDIO Function 0 */
 #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
-   sdio_f0_readb((sdiodev)->func[0], (addr), (r))
+   sdio_f0_readb((sdiodev)->func[1], (addr), (r))
 
 #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
-   sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
+   sdio_f0_writeb((sdiodev)->func[1], (v), (addr), (ret))
 
 /* Functions for accessing SDIO Function 1 */
 #define brcmf_sdiod_readb(sdiodev, addr, r) \
-- 
2.11.0



[PATCH 24/34] brcmfmac: Rename chip.ctx -> chip.bus_priv

2017-07-26 Thread Ian Molton
This driver uses the label ctx like its going out of fashion.

Lets rename this usage of it so that its easier to see whats going on.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c| 24 +++---
 .../wireless/broadcom/brcm80211/brcmfmac/chip.h| 16 +++
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 9cfabf4a7f62..0b70d61cc912 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -222,18 +222,18 @@ struct sbsocramregs {
 
 static inline int brcmf_readl(struct brcmf_chip *chip, u32 addr)
 {
-   return chip->ops->read32(chip->ctx, addr);
+   return chip->ops->read32(chip->bus_priv, addr);
 }
 
 static inline void brcmf_writel(struct brcmf_chip *chip, u32 addr, u32 v)
 {
-   chip->ops->write32(chip->ctx, addr, v);
+   chip->ops->write32(chip->bus_priv, addr, v);
 }
 
 static inline void brcmf_writelp(struct brcmf_chip *chip, u32 addr, u32 v)
 {
-   chip->ops->write32(chip->ctx, addr, v);
-   chip->ops->read32(chip->ctx, addr);
+   chip->ops->write32(chip->bus_priv, addr, v);
+   chip->ops->read32(chip->bus_priv, addr);
 }
 
 static void brcmf_clear_bits(struct brcmf_chip *ci, u32 reg, u32 bits)
@@ -1018,7 +1018,7 @@ static int brcmf_chip_probe(struct brcmf_chip *ci)
 * specific reset at this point.
 */
if (ci->ops->reset) {
-   ci->ops->reset(ci->ctx, ci);
+   ci->ops->reset(ci->bus_priv, ci);
brcmf_chip_set_passive(ci);
}
 
@@ -1089,12 +1089,12 @@ static int brcmf_chip_setup(struct brcmf_chip *chip)
 
/* execute bus core specific setup */
if (chip->ops->setup)
-   ret = chip->ops->setup(chip->ctx, chip);
+   ret = chip->ops->setup(chip->bus_priv, chip);
 
return ret;
 }
 
-struct brcmf_chip *brcmf_chip_attach(void *ctx,
+struct brcmf_chip *brcmf_chip_attach(void *bus_priv,
 const struct brcmf_buscore_ops *ops)
 {
struct brcmf_chip *chip;
@@ -1118,9 +1118,9 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx,
INIT_LIST_HEAD(>cores);
chip->num_cores = 0;
chip->ops = ops;
-   chip->ctx = ctx;
+   chip->bus_priv = bus_priv;
 
-   err = ops->prepare(ctx);
+   err = ops->prepare(bus_priv);
if (err < 0)
goto fail;
 
@@ -1241,7 +1241,7 @@ static bool brcmf_chip_cm3_set_active(struct brcmf_chip 
*chip)
return false;
}
 
-   chip->ops->activate(chip->ctx, chip, 0);
+   chip->ops->activate(chip->bus_priv, chip, 0);
 
core = brcmf_chip_get_core(chip, BCMA_CORE_ARM_CM3);
brcmf_chip_resetcore(core, 0, 0, 0);
@@ -1267,7 +1267,7 @@ static bool brcmf_chip_cr4_set_active(struct brcmf_chip 
*chip, u32 rstvec)
 {
struct brcmf_core *core;
 
-   chip->ops->activate(chip->ctx, chip, rstvec);
+   chip->ops->activate(chip->bus_priv, chip, rstvec);
 
/* restore ARM */
core = brcmf_chip_get_core(chip, BCMA_CORE_ARM_CR4);
@@ -1294,7 +1294,7 @@ static bool brcmf_chip_ca7_set_active(struct brcmf_chip 
*chip, u32 rstvec)
 {
struct brcmf_core *core;
 
-   chip->ops->activate(chip->ctx, chip, rstvec);
+   chip->ops->activate(chip->bus_priv, chip, rstvec);
 
/* restore ARM */
core = brcmf_chip_get_core(chip, BCMA_CORE_ARM_CA7);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
index 060bfa896bf1..680875423f91 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
@@ -50,7 +50,7 @@ struct brcmf_chip {
void (*resetcore)(struct brcmf_core *core, u32 prereset, u32 reset,
  u32 postreset);
 
-   void *ctx;
+   void *bus_priv;
 
u32 chip;
u32 chiprev;
@@ -94,15 +94,15 @@ struct brcmf_core {
  * The callback should use the provided @rstvec when non-zero.
  */
 struct brcmf_buscore_ops {
-   u32 (*read32)(void *ctx, u32 addr);
-   void (*write32)(void *ctx, u32 addr, u32 value);
-   int (*prepare)(void *ctx);
-   int (*reset)(void *ctx, struct brcmf_chip *chip);
-   int (*setup)(void *ctx, struct brcmf_chip *chip);
-   void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
+   u32 (*read32)(void *bus_priv, u32 addr);
+   void (*write32)(void *bus_priv, u32 addr, u32 value);
+   int (*prepare)(void *bus_priv);
+   int (*

[PATCH 12/34] brcmfmac: Replace old IO functions with simpler ones.

2017-07-26 Thread Ian Molton
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.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 166 +++
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 182 ++---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|  28 +++-
 3 files changed, 132 insertions(+), 244 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 858ad2d8706b..b2945b463fd3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -137,27 +137,25 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
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, );
+   gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, );
gpiocontrol |= 0x2;
-   brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, );
+   brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, );
 
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
- );
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, );
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, );
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT, 0xf, 
);
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, );
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, );
}
 
/* must configure SDIO_CCCR_IENx to enable irq */
-   data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, );
+   data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, );
data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
-   brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, );
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, );
 
/* 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, );
-
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
);
sdio_release_host(sdiodev->func[1]);
} else {
brcmf_dbg(SDIO, "Entering\n");
@@ -183,8 +181,8 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
 
pdata = >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 +240,8 @@ static int brcmf_sdiod_set_sbaddr_window(struct 
brcmf_sdio_dev *sdiodev,
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, );
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
+  addr & 0xff, );
 
return err;
 }
@@ -267,123 +265,15 @@ static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev 
*sdiodev, u32 *addr)
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, _ret);
-   else
-   sdio_f0_writeb(func, byte, regaddr, _ret);
-
-   return err_ret;
-}
-
-static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
-u8 regsz, void *data)
-{
-

[PATCH 10/34] brcmfmac: Rename bcmerror to err

2017-07-26 Thread Ian Molton
Trivial cleanup of nasty variable name

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 049086f6db97..9d5716d0ad73 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -745,7 +745,7 @@ int
 brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
  u8 *data, uint size)
 {
-   int bcmerror = 0;
+   int err = 0;
struct sk_buff *pkt;
u32 sdaddr;
uint dsize;
@@ -770,8 +770,8 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
/* Do the transfer(s) */
while (size) {
/* Set the backplane window to include the start address */
-   bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
-   if (bcmerror)
+   err = brcmf_sdiod_set_sbaddr_window(sdiodev, address);
+   if (err)
break;
 
brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 
0x%08x\n",
@@ -784,9 +784,9 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
skb_put(pkt, dsize);
if (write)
memcpy(pkt->data, data, dsize);
-   bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write,
- sdaddr, pkt);
-   if (bcmerror) {
+   err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr,
+pkt);
+   if (err) {
brcmf_err("membytes transfer failed\n");
break;
}
@@ -813,7 +813,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
 
sdio_release_host(sdiodev->func[1]);
 
-   return bcmerror;
+   return err;
 }
 
 int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn)
-- 
2.11.0



[PATCH 22/34] brcmfmac: Rename axi functions for clarity.

2017-07-26 Thread Ian Molton
These functions are poorly named. for the sake of one character,
correct this.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 3fe75aa30d9b..ec47924b0f76 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -239,7 +239,7 @@ static bool brcmf_chip_sb_iscoreup(struct brcmf_core *core)
return SSB_TMSLOW_CLOCK == regdata;
 }
 
-static bool brcmf_chip_ai_iscoreup(struct brcmf_core *core)
+static bool brcmf_chip_axi_iscoreup(struct brcmf_core *core)
 {
struct brcmf_chip *ci = core->chip;
u32 regdata;
@@ -340,7 +340,7 @@ static void brcmf_chip_sb_coredisable(struct brcmf_core 
*core,
udelay(1);
 }
 
-static void brcmf_chip_ai_coredisable(struct brcmf_core *core,
+static void brcmf_chip_axi_coredisable(struct brcmf_core *core,
  u32 prereset, u32 reset)
 {
struct brcmf_chip *ci = core->chip;
@@ -432,14 +432,14 @@ static void brcmf_chip_sb_resetcore(struct brcmf_core 
*core, u32 prereset,
udelay(1);
 }
 
-static void brcmf_chip_ai_resetcore(struct brcmf_core *core, u32 prereset,
+static void brcmf_chip_axi_resetcore(struct brcmf_core *core, u32 prereset,
u32 reset, u32 postreset)
 {
struct brcmf_chip *ci = core->chip;
int count;
 
/* must disable first to work for arbitrary current core state */
-   brcmf_chip_ai_coredisable(core, prereset, reset);
+   brcmf_chip_axi_coredisable(core, prereset, reset);
 
count = 0;
 
@@ -1004,9 +1004,9 @@ static int brcmf_chip_probe(struct brcmf_chip *ci)
if (brcmf_chip_dmp_erom_scan(ci))
return -ENODEV;
 
-   ci->iscoreup = brcmf_chip_ai_iscoreup;
-   ci->coredisable = brcmf_chip_ai_coredisable;
-   ci->resetcore = brcmf_chip_ai_resetcore;
+   ci->iscoreup = brcmf_chip_axi_iscoreup;
+   ci->coredisable = brcmf_chip_axi_coredisable;
+   ci->resetcore = brcmf_chip_axi_resetcore;
 
break;
default:
-- 
2.11.0



[PATCH 25/34] brcmfmac: Remove repeated calls to brcmf_chip_get_core()

2017-07-26 Thread Ian Molton
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 <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 25 +-
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b4fd832cdabe..3feaf9125b25 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -435,6 +435,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 */
@@ -662,10 +663,9 @@ static bool data_ok(struct brcmf_sdio *bus)
  */
 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, );
 
return ret;
@@ -673,10 +673,9 @@ static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, 
u32 offset)
 
 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, );
 
return ret;
@@ -2484,12 +2483,11 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio 
*bus)
 
 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, );
@@ -3366,13 +3364,14 @@ static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
 /* 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, );
@@ -3400,6 +3399,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
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;
@@ -3408,7 +3408,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
 * 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", ,
@@ -3746,11 +3746,10 @@ static void brcmf_sdio_buscore_activate(void *ctx, 
struct brcmf_chip *chip,
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, 0x, NULL);
 
@@ -3831,6 +3830,12 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
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,
-- 
2.11.0



[PATCH 11/34] brcmfmac: Split brcmf_sdiod_buffrw function up.

2017-07-26 Thread Ian Molton
This function needs to be split up into separate read / write variants
for clarity.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 69 +++---
 1 file changed, 47 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 9d5716d0ad73..858ad2d8706b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -413,8 +413,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 
addr,
*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;
@@ -423,18 +423,36 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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;
 }
 
@@ -642,7 +660,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, 
struct sk_buff *pkt)
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;
@@ -664,14 +682,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
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;
 
@@ -695,6 +713,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
int err;
 
mypkt = brcmu_pkt_buf_get_skb(nbytes);
+
if (!mypkt) {
brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n",
  nbytes);
@@ -706,10 +725,10 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, 
u8 *buf, uint nbytes)
err = brcmf_sdiod_addrprep(sdiodev, );
 
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;
 
 }
@@ -729,8 +748,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
 
if (pktq->qlen == 1 || !sdiodev->sg_support)
skb_queue_walk(pktq, skb) {
-   err = brcmf_sdiod_buffrw(sd

[PATCH 14/34] brcmfmac: Remove brcmf_sdiod_addrprep()

2017-07-26 Thread Ian Molton
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 <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 78 --
 1 file changed, 44 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index b2945b463fd3..24775869aee4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -228,41 +228,25 @@ void brcmf_sdiod_change_state(struct brcmf_sdio_dev 
*sdiodev,
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, );
-
-   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, );
 
+   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)
@@ -270,11 +254,17 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
u32 data = 0;
int retval;
 
-   retval = brcmf_sdiod_addrprep(sdiodev, );
+   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, );
 
+out:
if (ret)
*ret = retval;
 
@@ -286,11 +276,17 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, 
u32 addr,
 {
int retval;
 
-   retval = brcmf_sdiod_addrprep(sdiodev, );
+   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, );
 
+out:
if (ret)
*ret = retval;
 }
@@ -538,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, );
+   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:
@@ -559,10 +558,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
  addr, pktq->qlen);
 
-   err = brcmf_sdiod_addrprep(sdiodev, );
+   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);
@@ -604,7 +606,12 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, 
u8 *buf, uint nbytes)
 
memcpy(mypkt->data, buf, nbytes);
 
-   err = brcmf_sdiod_addrprep(sdiodev, );
+   err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+   if (err)
+   return err;
+
+   addr &= SBSDIO_SB_OFT_A

[PATCH 28/34] brcmfmac: Rename buscore->core for consistency

2017-07-26 Thread Ian Molton
Avoid confusion with unrelated _buscore labels.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index bee377fcc48f..b06018e589bb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -2475,14 +2475,12 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio 
*bus)
 
 static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 {
-   struct brcmf_core *buscore = bus->sdio_core;
-   u32 addr;
+   struct brcmf_core *core = bus->sdio_core;
unsigned long val;
int ret;
 
-   addr = buscore->base + __sd_reg(intstatus);
-
-   val = brcmf_sdiod_readl(bus->sdiodev, addr, );
+   val = brcmf_sdiod_readl(bus->sdiodev, core->base + __sd_reg(intstatus),
+   );
bus->sdcnt.f1regdata++;
if (ret != 0)
return ret;
@@ -2492,7 +2490,8 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 
/* Clear interrupts */
if (val) {
-   brcmf_sdiod_writel(bus->sdiodev, addr, val, );
+   brcmf_sdiod_writel(bus->sdiodev,
+  core->base + __sd_reg(intstatus), val, );
bus->sdcnt.f1regdata++;
atomic_or(val, >intstatus);
}
-- 
2.11.0



[PATCH 17/34] brcmfmac: Remove unused macro.

2017-07-26 Thread Ian Molton
This macro is used exactly nowhere in the code. Delete it.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 82769276654d..b4fd832cdabe 100644
--- 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_LEN6
 
-#define CORE_BUS_REG(base, field) \
-   (base + offsetof(struct sdpcmd_regs, field))
 #define __sd_reg(field) \
(offsetof(struct sdpcmd_regs, field))
 
-- 
2.11.0



[PATCH 27/34] brcmfmac: Remove {r,w}_sdreg32

2017-07-26 Thread Ian Molton
Remove yet another IO function from the code and replace with one
that already exists.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 91 +++---
 1 file changed, 45 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 9ef137d6eb3f..bee377fcc48f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -659,30 +659,6 @@ static bool data_ok(struct brcmf_sdio *bus)
   ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
 }
 
-/*
- * Reads a register in the SDIO hardware block. This block occupies a series of
- * adresses on the 32 bit backplane bus.
- */
-static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
-{
-   struct brcmf_core *core = bus->sdio_core;
-   int ret;
-
-   *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, );
-
-   return ret;
-}
-
-static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
-{
-   struct brcmf_core *core = bus->sdio_core;
-   int ret;
-
-   brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, );
-
-   return ret;
-}
-
 static int
 brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
 {
@@ -1077,6 +1053,8 @@ static void brcmf_sdio_get_console_addr(struct brcmf_sdio 
*bus)
 
 static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
 {
+   struct brcmf_sdio_dev *sdiod = bus->sdiodev;
+   struct brcmf_core *core = bus->sdio_core;
u32 intstatus = 0;
u32 hmb_data;
u8 fcbits;
@@ -1085,10 +1063,13 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
brcmf_dbg(SDIO, "Enter\n");
 
/* Read mailbox data and ack that we did so */
-   ret = r_sdreg32(bus, _data, __sd_reg(tohostmailboxdata));
+   hmb_data = brcmf_sdiod_readl(sdiod, core->base +
+   __sd_reg(tohostmailboxdata), );
+
+   if (!ret)
+   brcmf_sdiod_writel(sdiod, core->base + __sd_reg(tosbmailbox),
+  SMB_INT_ACK, );
 
-   if (ret == 0)
-   w_sdreg32(bus, SMB_INT_ACK, __sd_reg(tosbmailbox));
bus->sdcnt.f1regdata += 2;
 
/* Dongle recomposed rx frames, accept them again */
@@ -1157,6 +1138,8 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
 
 static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
 {
+   struct brcmf_sdio_dev *sdiod = bus->sdiodev;
+   struct brcmf_core *core = bus->sdio_core;
uint retries = 0;
u16 lastrbc;
u8 hi, lo;
@@ -1196,7 +1179,8 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, 
bool abort, bool rtx)
 
if (rtx) {
bus->sdcnt.rxrtx++;
-   err = w_sdreg32(bus, SMB_NAK, __sd_reg(tosbmailbox));
+   brcmf_sdiod_writel(sdiod, core->base + __sd_reg(tosbmailbox),
+  SMB_NAK, );
 
bus->sdcnt.f1regdata++;
if (err == 0)
@@ -2280,6 +2264,7 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, 
struct sk_buff_head *pktq,
 
 static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
 {
+   struct brcmf_core *core = bus->sdio_core;
struct sk_buff *pkt;
struct sk_buff_head pktq;
u32 intstatus = 0;
@@ -2320,7 +2305,9 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, 
uint maxframes)
if (!bus->intr) {
/* Check device status, signal pending interrupt */
sdio_claim_host(bus->sdiodev->func[1]);
-   ret = r_sdreg32(bus, , __sd_reg(intstatus));
+   intstatus = brcmf_sdiod_readl(bus->sdiodev, core->base +
+ __sd_reg(intstatus),
+ );
sdio_release_host(bus->sdiodev->func[1]);
bus->sdcnt.f2txdata++;
if (ret != 0)
@@ -2404,12 +2391,13 @@ static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio 
*bus, u8 *frame, u16 len)
 
 static void brcmf_sdio_bus_stop(struct device *dev)
 {
-   u32 local_hostintmask;
-   u8 saveclk;
-   int err;
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;
+   u32 local_hostintmask;
+   u8 saveclk;
+   int err;
 
brcmf_dbg(TRACE, "Enter\n");
 
@@ -2426,7 +2414,9 @@ static void brcmf_sdio_bus_stop(struct device *dev)
brcmf_sdio_bus_sleep(bus, fal

[PATCH 32/34] brcmfmac: Replace function index with function pointer

2017-07-26 Thread Ian Molton
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 <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 86 --
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 14 ++--
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h| 14 ++--
 3 files changed, 61 insertions(+), 53 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index da0654c50db9..5787348003d9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -148,7 +148,8 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
/* must configure SDIO_CCCR_IENx to enable irq */
data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, );
-   data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
+   data |= SDIO_CCCR_IEN_FUNC1 | SDIO_CCCR_IEN_FUNC2 |
+   SDIO_CCCR_IEN_BIT0;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, );
 
/* redirect, configure and enable io for interrupt signal */
@@ -291,8 +292,9 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 
addr,
*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 +303,17 @@ static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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:
+   BUG();
+   };
 
if (err == -ENOMEDIUM)
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
@@ -315,8 +321,9 @@ static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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 +332,7 @@ static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev 
*sdiodev, uint fn,
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 +343,7 @@ static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev 
*sdiodev, uint fn,
 /**
  * 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 +352,8 @@ static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev 
*sdiodev, uint fn,
  * 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 +379,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev 
*sdiodev, uint fn,
req_sz = 0;
skb_queue_walk(pktlist, pkt_next)
req_sz += pkt_n

[PATCH 30/34] brcmfmac: Correctly handle accesses to SDIO func0

2017-07-26 Thread Ian Molton
Rather than workaround the restrictions on func0 addressing in the
driver, set MMC_QUIRK_LENIENT_FN0

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 26b39f0ffdd4..95149c686c5f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -994,6 +994,10 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
brcmf_dbg(SDIO, "Function#: %d\n", func->num);
 
dev = >dev;
+
+   /* Set MMC_QUIRK_LENIENT_FN0 for this card */
+   func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+
/* prohibit ACPI power management for this device */
brcmf_sdiod_acpi_set_power_manageable(dev, 0);
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 1ab95011adb0..8a976c89cf63 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -297,10 +297,10 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev);
 /* SDIO device register access interface */
 /* Functions for accessing SDIO Function 0 */
 #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
-   sdio_readb((sdiodev)->func[0], (addr), (r))
+   sdio_f0_readb((sdiodev)->func[0], (addr), (r))
 
 #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
-   sdio_writeb((sdiodev)->func[0], (v), (addr), (ret))
+   sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
 
 /* Functions for accessing SDIO Function 1 */
 #define brcmf_sdiod_readb(sdiodev, addr, r) \
-- 
2.11.0



[PATCH 15/34] brcmfamc: remove unnecessary call to brcmf_sdiod_set_backplane_window()

2017-07-26 Thread Ian Molton
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 <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 24775869aee4..6884d1f0b935 100644
--- 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 *sdiodev, bool 
write, u32 address,
 
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;
-- 
2.11.0



[PATCH 19/34] brcmfmac: Get rid of chip_priv and core_priv structs

2017-07-26 Thread Ian Molton
There is zero need to keep these structures separate, they are *always*
allocated together. All they do is obfuscate the code, whilst offering
zero real gain.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c| 383 +
 .../wireless/broadcom/brcm80211/brcmfmac/chip.h|  22 ++
 2 files changed, 191 insertions(+), 214 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 7b8ba7192e1a..ecd242b33691 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -223,75 +223,58 @@ struct sbsocramregs {
 #defineARMCR4_BSZ_MASK 0x3f
 #defineARMCR4_BSZ_MULT 8192
 
-struct brcmf_core_priv {
-   struct brcmf_core pub;
-   u32 wrapbase;
-   struct list_head list;
-   struct brcmf_chip_priv *chip;
-};
-
-struct brcmf_chip_priv {
-   struct brcmf_chip pub;
-   const struct brcmf_buscore_ops *ops;
-   void *ctx;
-   /* assured first core is chipcommon, second core is buscore */
-   struct list_head cores;
-   u16 num_cores;
-
-   bool (*iscoreup)(struct brcmf_core_priv *core);
-   void (*coredisable)(struct brcmf_core_priv *core, u32 prereset,
-   u32 reset);
-   void (*resetcore)(struct brcmf_core_priv *core, u32 prereset, u32 reset,
- u32 postreset);
-};
 
-static void brcmf_chip_sb_corerev(struct brcmf_chip_priv *ci,
+static void brcmf_chip_sb_corerev(struct brcmf_chip *ci,
  struct brcmf_core *core)
 {
u32 regdata;
 
regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
+
core->rev = SBCOREREV(regdata);
 }
 
-static bool brcmf_chip_sb_iscoreup(struct brcmf_core_priv *core)
+static bool brcmf_chip_sb_iscoreup(struct brcmf_core *core)
 {
-   struct brcmf_chip_priv *ci;
+   struct brcmf_chip *ci = core->chip;
u32 regdata;
u32 address;
 
-   ci = core->chip;
-   address = CORE_SB(core->pub.base, sbtmstatelow);
+   address = CORE_SB(core->base, sbtmstatelow);
+
regdata = ci->ops->read32(ci->ctx, address);
+
regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
+
return SSB_TMSLOW_CLOCK == regdata;
 }
 
-static bool brcmf_chip_ai_iscoreup(struct brcmf_core_priv *core)
+static bool brcmf_chip_ai_iscoreup(struct brcmf_core *core)
 {
-   struct brcmf_chip_priv *ci;
+   struct brcmf_chip *ci = core->chip;
u32 regdata;
bool ret;
 
-   ci = core->chip;
regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
+
ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
 
regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
+
ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
 
return ret;
 }
 
-static void brcmf_chip_sb_coredisable(struct brcmf_core_priv *core,
+static void brcmf_chip_sb_coredisable(struct brcmf_core *core,
  u32 prereset, u32 reset)
 {
-   struct brcmf_chip_priv *ci;
+   struct brcmf_chip *ci = core->chip;
u32 val, base;
 
-   ci = core->chip;
-   base = core->pub.base;
+   base = core->base;
+
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
if (val & SSB_TMSLOW_RESET)
return;
@@ -354,14 +337,12 @@ static void brcmf_chip_sb_coredisable(struct 
brcmf_core_priv *core,
udelay(1);
 }
 
-static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
+static void brcmf_chip_ai_coredisable(struct brcmf_core *core,
  u32 prereset, u32 reset)
 {
-   struct brcmf_chip_priv *ci;
+   struct brcmf_chip *ci = core->chip;
u32 regdata;
 
-   ci = core->chip;
-
/* if core is already in reset, skip reset */
regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
if ((regdata & BCMA_RESET_CTL_RESET) != 0)
@@ -388,15 +369,13 @@ static void brcmf_chip_ai_coredisable(struct 
brcmf_core_priv *core,
ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
 }
 
-static void brcmf_chip_sb_resetcore(struct brcmf_core_priv *core, u32 prereset,
+static void brcmf_chip_sb_resetcore(struct brcmf_core *core, u32 prereset,
u32 reset, u32 postreset)
 {
-   struct brcmf_chip_priv *ci;
+   struct brcmf_chip *ci = core->chip;
+   u32 base = core->base;
u32 regdata;
-   u32 base;
 
-   ci = core->chip;
-   base = core->pub.base;
/*

[PATCH 18/34] brcmfmac: Rename SOC_AI to SOC_AXI

2017-07-26 Thread Ian Molton
This #define is poorly named. Correct it.

At the same time, convert the if..elseif...else it is used in to a switch
for clarity.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index 05f22ff81d60..7b8ba7192e1a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -30,7 +30,7 @@
 
 /* SOC Interconnect types (aka chip types) */
 #define SOCI_SB0
-#define SOCI_AI1
+#define SOCI_AXI   1
 
 /* PL-368 DMP definitions */
 #define DMP_DESC_TYPE_MSK  0x000F
@@ -927,7 +927,8 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv 
*ci)
  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name,
  ci->pub.chiprev);
 
-   if (socitype == SOCI_SB) {
+   switch(socitype) {
+   case SOCI_SB:
if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {
brcmf_err("SB chip is not supported\n");
return -ENODEV;
@@ -951,13 +952,15 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv 
*ci)
 
core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
brcmf_chip_sb_corerev(ci, core);
-   } else if (socitype == SOCI_AI) {
+   break;
+   case SOCI_AXI:
ci->iscoreup = brcmf_chip_ai_iscoreup;
ci->coredisable = brcmf_chip_ai_coredisable;
ci->resetcore = brcmf_chip_ai_resetcore;
 
brcmf_chip_dmp_erom_scan(ci);
-   } else {
+   break;
+   default:
brcmf_err("chip backplane type %u is not supported\n",
  socitype);
return -ENODEV;
-- 
2.11.0



[PATCH 16/34] brcmfmac: Cleanup offsetof()

2017-07-26 Thread Ian Molton
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 <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 35 +-
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index a622df81c501..82769276654d 100644
--- 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 */
@@ -1084,12 +1086,10 @@ static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
brcmf_dbg(SDIO, "Enter\n");
 
/* Read mailbox data and ack that we did so */
-   ret = r_sdreg32(bus, _data,
-   offsetof(struct sdpcmd_regs, tohostmailboxdata));
+   ret = r_sdreg32(bus, _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 recomposed rx frames, accept them again */
@@ -1197,8 +1197,7 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, 
bool abort, bool rtx)
 
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)
@@ -2322,9 +2321,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, 
uint maxframes)
if (!bus->intr) {
/* Check device status, signal pending interrupt */
sdio_claim_host(bus->sdiodev->func[1]);
-   ret = r_sdreg32(bus, ,
-   offsetof(struct sdpcmd_regs,
-intstatus));
+   ret = r_sdreg32(bus, , __sd_reg(intstatus));
sdio_release_host(bus->sdiodev->func[1]);
bus->sdcnt.f2txdata++;
if (ret != 0)
@@ -2430,7 +2427,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
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;
 
@@ -2449,8 +2446,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
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]);
}
@@ -2496,7 +2492,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
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, );
bus->sdcnt.f1regdata++;
@@ -2573,11 +2569,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
 */
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, ,
-   offsetof(struct sdpcmd_regs, intstatus));
+   err = r_sdreg32(bus, , __sd_reg(intstatus));
bus->sdcnt.f1regdata += 2;
atomic_set(>fcstate,
   !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
@@ -3759,7 +3753,7 @@ static void brcmf_sdio_buscore_activate(void *ctx, struct 
brcmf_chip *chip,
 
/* clear all interrupts */
core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
-   reg_addr = core->base + 

[PATCH 21/34] brcmfmac: Simplify chip probe routine

2017-07-26 Thread Ian Molton
* Renamed routine in line with kernel convention.
* Improved handling of chips that cannot autoprobe

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c| 132 +
 1 file changed, 84 insertions(+), 48 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index daa3c335804b..3fe75aa30d9b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -223,17 +223,6 @@ struct sbsocramregs {
 #defineARMCR4_BSZ_MASK 0x3f
 #defineARMCR4_BSZ_MULT 8192
 
-
-static void brcmf_chip_sb_corerev(struct brcmf_chip *ci,
- struct brcmf_core *core)
-{
-   u32 regdata;
-
-   regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
-
-   core->rev = SBCOREREV(regdata);
-}
-
 static bool brcmf_chip_sb_iscoreup(struct brcmf_core *core)
 {
struct brcmf_chip *ci = core->chip;
@@ -482,15 +471,15 @@ static char *brcmf_chip_name(uint chipid, char *buf, uint 
len)
return buf;
 }
 
-static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip *ci,
- u16 coreid, u32 base,
- u32 wrapbase)
+static struct brcmf_core *__brcmf_chip_add_core(struct brcmf_chip *ci,
+   u16 coreid, u32 base,
+   u32 wrapbase)
 {
struct brcmf_core *core;
 
core = kzalloc(sizeof(*core), GFP_KERNEL);
if (!core)
-   return ERR_PTR(-ENOMEM);
+   return NULL;
 
core->id = coreid;
core->base = base;
@@ -502,6 +491,40 @@ static struct brcmf_core *brcmf_chip_add_core(struct 
brcmf_chip *ci,
return core;
 }
 
+static struct brcmf_core *brcmf_chip_add_sb_core(struct brcmf_chip *ci,
+u16 coreid, u32 base,
+u32 wrapbase)
+{
+   struct brcmf_core *core;
+   u32 regdata;
+
+   core = __brcmf_chip_add_core(ci, coreid, base, wrapbase);
+
+   if (!core)
+   goto out;
+
+   regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
+
+   core->rev = SBCOREREV(regdata);
+
+out:
+   return core;
+}
+
+static struct brcmf_core *brcmf_chip_add_axi_core(struct brcmf_chip *ci,
+ u16 coreid, u32 base,
+ u32 wrapbase, u8 rev)
+{
+   struct brcmf_core *core;
+
+   core = __brcmf_chip_add_core(ci, coreid, base, wrapbase);
+
+   if (core)
+   core->rev = rev;
+
+   return core;
+}
+
 /* safety check for chipinfo */
 static int brcmf_chip_cores_check(struct brcmf_chip *ci)
 {
@@ -900,19 +923,41 @@ int brcmf_chip_dmp_erom_scan(struct brcmf_chip *ci)
continue;
 
/* finally a core to be added */
-   core = brcmf_chip_add_core(ci, id, base, wrap);
-   if (IS_ERR(core))
-   return PTR_ERR(core);
-
-   core->rev = rev;
+   core = brcmf_chip_add_axi_core(ci, id, base, wrap, rev);
+   if (!core)
+   return -ENOMEM; //FIXME - Cleanup the allocated cores?
}
 
return 0;
 }
 
-static int brcmf_chip_recognition(struct brcmf_chip *ci)
+struct brcmf_chip_desc {
+   u16 id;
+   u32 base;
+};
+
+static struct brcmf_chip_desc brcmf_4329[] = {
+   { BCMA_CORE_CHIPCOMMON,   SI_ENUM_BASE },
+   { BCMA_CORE_SDIO_DEV, BCM4329_CORE_BUS_BASE },
+   { BCMA_CORE_INTERNAL_MEM, BCM4329_CORE_SOCRAM_BASE },
+   { BCMA_CORE_ARM_CM3,  BCM4329_CORE_ARM_BASE },
+   { BCMA_CORE_80211,0x18001000 },
+   { 0, 0},
+};
+
+static int brcmf_chip_add_static(struct brcmf_chip *ci,
+struct brcmf_chip_desc *desc)
+{
+   for ( ; desc->id ; desc++)
+   brcmf_chip_add_sb_core(ci, desc->id, desc->base, 0);
+
+   //FIXME: cleanup if we fail to add a core?
+
+   return 0;
+}
+
+static int brcmf_chip_probe(struct brcmf_chip *ci)
 {
-   struct brcmf_core *core;
u32 regdata;
u32 socitype;
int ret;
@@ -920,11 +965,13 @@ static int brcmf_chip_recognition(struct brcmf_chip *ci)
/* Get CC core rev
 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
 * For different chiptypes or old sdio hosts w/o chipcommon,
-* other ways of recognition should be added here.
+* other ways of to probe should be added here.
 */
regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
+
ci->chi

[PATCH 29/34] brcmfmac: stabilise the value of ->sbwad in use for some xfer routines.

2017-07-26 Thread Ian Molton
The IO functions operate within the Chipcommon IO window. Explicitly
set this, rather than relying on the last initialisation IO access to
leave it set to the right value by chance.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c   | 5 +
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 6884d1f0b935..26b39f0ffdd4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -529,7 +529,7 @@ int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
 
 int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt)
 {
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err = 0;
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len);
@@ -552,7 +552,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
 {
struct sk_buff *glom_skb = NULL;
struct sk_buff *skb;
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err = 0;
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
@@ -593,7 +593,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
 int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes)
 {
struct sk_buff *mypkt;
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err;
 
mypkt = brcmu_pkt_buf_get_skb(nbytes);
@@ -626,7 +626,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
 struct sk_buff_head *pktq)
 {
struct sk_buff *skb;
-   u32 addr = sdiodev->sbwad;
+   u32 addr = sdiodev->cc_core->base;
int err;
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b06018e589bb..91a17ef63a6b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3838,6 +3838,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
if (!bus->sdio_core)
goto fail;
 
+   /* Pick up the CHIPCOMMON core info struct, for bulk IO in bcmsdh.c */
+   sdiodev->cc_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_CHIPCOMMON);
+   if (!sdiodev->cc_core)
+   goto fail;
+
sdiodev->settings = brcmf_get_module_param(sdiodev->dev,
   BRCMF_BUSTYPE_SDIO,
   bus->ci->chip,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index fb4f24dfc99d..1ab95011adb0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -178,6 +178,7 @@ struct brcmf_sdio_dev {
struct sdio_func *func[SDIO_MAX_FUNCS];
u8 num_funcs;   /* Supported funcs on client */
u32 sbwad;  /* Save backplane window address */
+   struct brcmf_core *cc_core; /* chipcommon core info struct */
struct brcmf_sdio *bus;
struct device *dev;
struct brcmf_bus *bus_if;
-- 
2.11.0



[PATCH 34/34] brcmfmac: Reduce the noise from repeatedly dereferencing common pointers

2017-07-26 Thread Ian Molton
This introduces no functional changes, but makes the code drastically more
readable, reducing the amount of dereferencing performed inside functions
throughout the SDIO core.

For example, reduce:
sdio_release_host(bus->sdiodev->func1);
to:
sdio_release_host(func1);

Fixup a few inconsistently named pointers whilst we are at it ie.

sdiod -> sdiodev

Signed-off-by: Ian Molton <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 140 +++
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 409 +++--
 2 files changed, 294 insertions(+), 255 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 8cfd2cbb1dfa..c2f821b28fee 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -105,6 +105,8 @@ static void brcmf_sdiod_dummy_irqhandler(struct sdio_func 
*func)
 int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
 {
struct brcmfmac_sdio_pd *pdata;
+   struct sdio_func *func1 = sdiodev->func1;
+   struct sdio_func *func2 = sdiodev->func2;
int ret = 0;
u8 data;
u32 addr, gpiocontrol;
@@ -118,7 +120,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
  pdata->oob_irq_flags, "brcmf_oob_intr",
- >func1->dev);
+ >dev);
if (ret != 0) {
brcmf_err("request_irq failed %d\n", ret);
return ret;
@@ -132,7 +134,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
}
sdiodev->irq_wake = true;
 
-   sdio_claim_host(sdiodev->func1);
+   sdio_claim_host(func1);
 
if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
/* assign GPIO to SDIO core */
@@ -157,13 +159,13 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
data |= SDIO_SEPINT_ACT_HI;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
);
-   sdio_release_host(sdiodev->func1);
+   sdio_release_host(func1);
} else {
brcmf_dbg(SDIO, "Entering\n");
-   sdio_claim_host(sdiodev->func1);
-   sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler);
-   sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler);
-   sdio_release_host(sdiodev->func1);
+   sdio_claim_host(func1);
+   sdio_claim_irq(func1, brcmf_sdiod_ib_irqhandler);
+   sdio_claim_irq(func2, brcmf_sdiod_dummy_irqhandler);
+   sdio_release_host(func1);
sdiodev->sd_irq_requested = true;
}
 
@@ -172,6 +174,8 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
 void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
 {
+   struct sdio_func *func1 = sdiodev->func1;
+   struct sdio_func *func2 = sdiodev->func2;
 
brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",
  sdiodev->oob_irq_requested,
@@ -181,26 +185,26 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
struct brcmfmac_sdio_pd *pdata;
 
pdata = >settings->bus.sdio;
-   sdio_claim_host(sdiodev->func1);
+   sdio_claim_host(func1);
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->func1);
+   sdio_release_host(func1);
 
sdiodev->oob_irq_requested = false;
if (sdiodev->irq_wake) {
disable_irq_wake(pdata->oob_irq_nr);
sdiodev->irq_wake = false;
}
-   free_irq(pdata->oob_irq_nr, >func1->dev);
+   free_irq(pdata->oob_irq_nr, >dev);
sdiodev->irq_en = false;
sdiodev->oob_irq_requested = false;
}
 
if (sdiodev->sd_irq_requested) {
-   sdio_claim_host(sdiodev->func1);
-   sdio_release_irq(sdiodev->func2);
-   sdio_release_irq(sdiodev->func1);
-   sdio_release_host(sdiodev->func1);
+   sdio_claim_host

[PATCH 33/34] brcmfmac: Remove array of functions

2017-07-26 Thread Ian Molton
Replace the array of functions with a pair of pointers to the
 relevant functions.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 117 +++
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 166 ++---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|  15 +-
 3 files changed, 146 insertions(+), 152 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 5787348003d9..8cfd2cbb1dfa 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -118,7 +118,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
  pdata->oob_irq_flags, "brcmf_oob_intr",
- >func[1]->dev);
+ >func1->dev);
if (ret != 0) {
brcmf_err("request_irq failed %d\n", ret);
return ret;
@@ -132,7 +132,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
}
sdiodev->irq_wake = true;
 
-   sdio_claim_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
 
if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
/* assign GPIO to SDIO core */
@@ -157,13 +157,13 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
data |= SDIO_SEPINT_ACT_HI;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
);
-   sdio_release_host(sdiodev->func[1]);
+   sdio_release_host(sdiodev->func1);
} else {
brcmf_dbg(SDIO, "Entering\n");
-   sdio_claim_host(sdiodev->func[1]);
-   sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler);
-   sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler);
-   sdio_release_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
+   sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler);
+   sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler);
+   sdio_release_host(sdiodev->func1);
sdiodev->sd_irq_requested = true;
}
 
@@ -181,26 +181,26 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
struct brcmfmac_sdio_pd *pdata;
 
pdata = >settings->bus.sdio;
-   sdio_claim_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
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]);
+   sdio_release_host(sdiodev->func1);
 
sdiodev->oob_irq_requested = false;
if (sdiodev->irq_wake) {
disable_irq_wake(pdata->oob_irq_nr);
sdiodev->irq_wake = false;
}
-   free_irq(pdata->oob_irq_nr, >func[1]->dev);
+   free_irq(pdata->oob_irq_nr, >func1->dev);
sdiodev->irq_en = false;
sdiodev->oob_irq_requested = false;
}
 
if (sdiodev->sd_irq_requested) {
-   sdio_claim_host(sdiodev->func[1]);
-   sdio_release_irq(sdiodev->func[2]);
-   sdio_release_irq(sdiodev->func[1]);
-   sdio_release_host(sdiodev->func[1]);
+   sdio_claim_host(sdiodev->func1);
+   sdio_release_irq(sdiodev->func2);
+   sdio_release_irq(sdiodev->func1);
+   sdio_release_host(sdiodev->func1);
sdiodev->sd_irq_requested = false;
}
 }
@@ -263,7 +263,7 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
if (!retval)
-   data = sdio_readl(sdiodev->func[1], addr, );
+   data = sdio_readl(sdiodev->func1, addr, );
 
 out:
if (ret)
@@ -285,7 +285,7 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 
addr,
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
if (!retval)
-   sdio_writel(sdiodev->func[1], data, addr, );
+   sdio_writel(sdiode

[PATCH 26/34] brcmfmac: General cleaning up. whitespace and comments fix.

2017-07-26 Thread Ian Molton
Tidy code, fix whitespace, remove useless debug code.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 24 ++
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 3feaf9125b25..9ef137d6eb3f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -642,11 +642,13 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] 
= {
 
 static void pkt_align(struct sk_buff *p, int len, int align)
 {
-   uint datalign;
-   datalign = (unsigned long)(p->data);
+   uint datalign = (unsigned long)(p->data);
+
datalign = roundup(datalign, (align)) - datalign;
+
if (datalign)
skb_pull(p, datalign);
+
__skb_trim(p, len);
 }
 
@@ -2467,10 +2469,9 @@ static void brcmf_sdio_bus_stop(struct device *dev)
 
 static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus)
 {
-   struct brcmf_sdio_dev *sdiodev;
+   struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
unsigned long flags;
 
-   sdiodev = bus->sdiodev;
if (sdiodev->oob_irq_requested) {
spin_lock_irqsave(>irq_en_lock, flags);
if (!sdiodev->irq_en && !atomic_read(>ipend)) {
@@ -3765,15 +3766,23 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 
addr)
u32 val, rev;
 
val = brcmf_sdiod_readl(sdiodev, addr, NULL);
+
+   /* Force 4339 chips over rev2 to use the same ID */
+   /* This is borderline tolerable whilst there is only two exceptions */
+   /* But could be handled better */
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)) {
+   sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
+   addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
+
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
+
if (rev >= 2) {
val &= ~CID_ID_MASK;
val |= BRCM_CC_4339_CHIP_ID;
}
+
}
+
return val;
 }
 
@@ -3804,9 +3813,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
sdiodev = bus->sdiodev;
sdio_claim_host(sdiodev->func[1]);
 
-   pr_debug("F1 signature read @0x1800=0x%4x\n",
-brcmf_sdiod_readl(sdiodev, SI_ENUM_BASE, NULL));
-
/*
 * Force PLL off until brcmf_chip_attach()
 * programs PLL control regs
-- 
2.11.0



[PATCH 23/34] brcmfmac: HUGE cleanup of IO access functions.

2017-07-26 Thread Ian Molton
Most of the core IO functions are called via a long train of pointers.

Introduce brcmf_readl(), brcmf_writel(), brcmf_writelp(),
brcmf_clear_bits(), and brcmf_set_bits_post() in an attempt to deal with
this.

These brcmf_writelp() and brcmf_set_bits_post() issue posted writes.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c| 447 ++---
 1 file changed, 219 insertions(+), 228 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index ec47924b0f76..9cfabf4a7f62 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -106,9 +106,6 @@
 
 #define CORE_SB(base, field) \
(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
-#defineSBCOREREV(sbidh) \
-   sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
- ((sbidh) & SSB_IDHIGH_RCLO))
 
 struct sbconfig {
u32 PAD[2];
@@ -223,252 +220,251 @@ struct sbsocramregs {
 #defineARMCR4_BSZ_MASK 0x3f
 #defineARMCR4_BSZ_MULT 8192
 
+static inline int brcmf_readl(struct brcmf_chip *chip, u32 addr)
+{
+   return chip->ops->read32(chip->ctx, addr);
+}
+
+static inline void brcmf_writel(struct brcmf_chip *chip, u32 addr, u32 v)
+{
+   chip->ops->write32(chip->ctx, addr, v);
+}
+
+static inline void brcmf_writelp(struct brcmf_chip *chip, u32 addr, u32 v)
+{
+   chip->ops->write32(chip->ctx, addr, v);
+   chip->ops->read32(chip->ctx, addr);
+}
+
+static void brcmf_clear_bits(struct brcmf_chip *ci, u32 reg, u32 bits)
+{
+   u32 val;
+
+   val = brcmf_readl(ci, reg);
+   val &= ~bits;
+   brcmf_writel(ci, reg, val);
+}
+
+static void brcmf_set_bits_post(struct brcmf_chip *ci, u32 reg, u32 bits)
+{
+   u32 val;
+
+   val = brcmf_readl(ci, reg);
+   val |= bits;
+   brcmf_writelp(ci, reg, val);
+}
+
 static bool brcmf_chip_sb_iscoreup(struct brcmf_core *core)
 {
struct brcmf_chip *ci = core->chip;
-   u32 regdata;
-   u32 address;
-
-   address = CORE_SB(core->base, sbtmstatelow);
+   u32 val;
 
-   regdata = ci->ops->read32(ci->ctx, address);
+   val = brcmf_readl(ci, CORE_SB(core->base, sbtmstatelow));
 
-   regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
-   SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
+   val &= SSB_TMSLOW_RESET |
+   SSB_TMSLOW_REJECT |
+   SSB_IMSTATE_REJECT |
+   SSB_TMSLOW_CLOCK;
 
-   return SSB_TMSLOW_CLOCK == regdata;
+   return val == SSB_TMSLOW_CLOCK;
 }
 
 static bool brcmf_chip_axi_iscoreup(struct brcmf_core *core)
 {
struct brcmf_chip *ci = core->chip;
-   u32 regdata;
-   bool ret;
+   u32 val;
 
-   regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
+   val = brcmf_readl(ci, core->wrapbase + BCMA_IOCTL);
 
-   ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
+   if ((val & BCMA_IOCTL_FGC) || !(val & BCMA_IOCTL_CLK))
+   return 0;
 
-   regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
+   /* Is core in reset? */
+   val = brcmf_readl(ci, core->wrapbase + BCMA_RESET_CTL);
 
-   ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
+   val &= BCMA_RESET_CTL_RESET;
 
-   return ret;
+   return !val;
 }
 
-static void brcmf_chip_sb_coredisable(struct brcmf_core *core,
- u32 prereset, u32 reset)
+/* prereset and reset ignored */
+static void brcmf_chip_sb_core_disable(struct brcmf_core *core,
+  u32 prereset, u32 reset)
 {
struct brcmf_chip *ci = core->chip;
u32 val, base;
 
base = core->base;
 
-   val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+   val = brcmf_readl(ci, CORE_SB(base, sbtmstatelow));
 
+   /* If core is already in reset, skip reset */
if (val & SSB_TMSLOW_RESET)
return;
 
-   val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
-
-   if ((val & SSB_TMSLOW_CLOCK) != 0) {
-   /*
-* set target reject and spin until busy is clear
-* (preserve core-specific bits)
-*/
-   val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+   if (!(val & SSB_TMSLOW_CLOCK))
+   goto out_clock_off;
 
-   ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
-val | SSB_TMSLOW_REJECT);
+   /* Clock is running, so do other stuff? */
 
-   val = ci->

[PATCH 20/34] brcmfmac: Whitespace patch

2017-07-26 Thread Ian Molton
Improve legibility / conform to kernel coding style.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c| 47 ++
 1 file changed, 47 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
index ecd242b33691..daa3c335804b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -276,29 +276,36 @@ static void brcmf_chip_sb_coredisable(struct brcmf_core 
*core,
base = core->base;
 
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+
if (val & SSB_TMSLOW_RESET)
return;
 
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+
if ((val & SSB_TMSLOW_CLOCK) != 0) {
/*
 * set target reject and spin until busy is clear
 * (preserve core-specific bits)
 */
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+
ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
 val | SSB_TMSLOW_REJECT);
 
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+
udelay(1);
+
SPINWAIT((ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh))
  & SSB_TMSHIGH_BUSY), 10);
 
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
+
if (val & SSB_TMSHIGH_BUSY)
brcmf_err("core state still busy\n");
 
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
+
if (val & SSB_IDLOW_INITIATOR) {
val = ci->ops->read32(ci->ctx,
  CORE_SB(base, sbimstate));
@@ -316,16 +323,22 @@ static void brcmf_chip_sb_coredisable(struct brcmf_core 
*core,
/* set reset and reject while enabling the clocks */
val = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
+
ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow), val);
+
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+
udelay(10);
 
/* clear the initiator reject bit */
val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
+
if (val & SSB_IDLOW_INITIATOR) {
val = ci->ops->read32(ci->ctx,
  CORE_SB(base, sbimstate));
+
val &= ~SSB_IMSTATE_REJECT;
+
ci->ops->write32(ci->ctx,
 CORE_SB(base, sbimstate), val);
}
@@ -334,6 +347,7 @@ static void brcmf_chip_sb_coredisable(struct brcmf_core 
*core,
/* leave reset and reject asserted */
ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
+
udelay(1);
 }
 
@@ -345,17 +359,20 @@ static void brcmf_chip_ai_coredisable(struct brcmf_core 
*core,
 
/* if core is already in reset, skip reset */
regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
+
if ((regdata & BCMA_RESET_CTL_RESET) != 0)
goto in_reset_configure;
 
/* configure reset */
ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
 prereset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
+
ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
 
/* put in reset */
ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL,
 BCMA_RESET_CTL_RESET);
+
usleep_range(10, 20);
 
/* wait till reset is 1 */
@@ -366,6 +383,7 @@ static void brcmf_chip_ai_coredisable(struct brcmf_core 
*core,
/* in-reset configure */
ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
 reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
+
ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
 }
 
@@ -390,15 +408,19 @@ static void brcmf_chip_sb_resetcore(struct brcmf_core 
*core, u32 prereset,
ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
 SSB_TMSLOW_RESET);
+
regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
+
udelay(1);
 
/* clear any serror */
regdata = ci->ops->read32(ci-&g

[PATCH 06/34] brcmfmac: Remove bandaid for SleepCSR

2017-07-26 Thread Ian Molton
Register access code is not the place for band-aid fixes like this.
If this is a genuine problem, it should be fixed further up in the driver
stack.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 28 +-
 1 file changed, 1 insertion(+), 27 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 609a934c1658..d217b1281e0d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -334,21 +334,8 @@ static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
} while (ret != 0 && ret != -ENOMEDIUM &&
 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 
-   if (ret == -ENOMEDIUM) {
+   if (ret == -ENOMEDIUM)
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
-   } else if (ret != 0) {
-   /*
-* SleepCSR register access can fail when
-* waking up the device so reduce this noise
-* in the logs.
-*/
-   if (addr != SBSDIO_FUNC1_SLEEPCSR)
-   brcmf_err("failed to write data F%d@0x%05x, err: %d\n",
- func, addr, ret);
-   else
-   brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: 
%d\n",
- func, addr, ret);
-   }
 
return ret;
 }
@@ -389,19 +376,6 @@ static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
 
if (ret == -ENOMEDIUM)
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
-   else if (ret != 0) {
-   /*
-* SleepCSR register access can fail when
-* waking up the device so reduce this noise
-* in the logs.
-*/
-   if (addr != SBSDIO_FUNC1_SLEEPCSR)
-   brcmf_err("failed to read data F%d@0x%05x, err: %d\n",
- func, addr, ret);
-   else
-   brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: 
%d\n",
- func, addr, ret);
-   }
 
return ret;
 }
-- 
2.11.0



[PATCH 03/34] brcmfmac: Split brcmf_sdiod_regrw_helper() up.

2017-07-26 Thread Ian Molton
This large function is concealing a LOT of obscure logic about
how the hardware functions. Time to split it up.

This first patch splits the function into two pieces - read and write,
doing away with the rw flag in the process.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 94 +-
 1 file changed, 73 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 2b441ce91d5f..1ee0f91b6c50 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -302,8 +302,8 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
return ret;
 }
 
-static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
-  u8 regsz, void *data, bool write)
+static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
+u8 regsz, void *data)
 {
u8 func;
s32 retry = 0;
@@ -324,13 +324,66 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
func = SDIO_FUNC_1;
 
do {
-   if (!write)
-   memset(data, 0, regsz);
/* for retry wait for 1 ms till bus get settled down */
if (retry)
usleep_range(1000, 2000);
+
+   ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
+  data, true);
+
+   } while (ret != 0 && ret != -ENOMEDIUM &&
+retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
+
+   if (ret == -ENOMEDIUM) {
+   brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
+   } else if (ret != 0) {
+   /*
+* SleepCSR register access can fail when
+* waking up the device so reduce this noise
+* in the logs.
+*/
+   if (addr != SBSDIO_FUNC1_SLEEPCSR)
+   brcmf_err("failed to write data F%d@0x%05x, err: %d\n",
+ func, addr, ret);
+   else
+   brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: 
%d\n",
+ func, addr, ret);
+   }
+
+   return ret;
+}
+
+static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr,
+   u8 regsz, void *data)
+{
+   u8 func;
+   s32 retry = 0;
+   int ret;
+
+   if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
+   return -ENOMEDIUM;
+
+   /*
+* figure out how to read the register based on address range
+* 0x00 ~ 0x7FF: function 0 CCCR and FBR
+* 0x1 ~ 0x1: function 1 miscellaneous registers
+* The rest: function 1 silicon backplane core registers
+*/
+   if ((addr & ~REG_F0_REG_MASK) == 0)
+   func = SDIO_FUNC_0;
+   else
+   func = SDIO_FUNC_1;
+
+   do {
+   memset(data, 0, regsz);
+
+   /* for retry wait for 1 ms till bus get settled down */
+   if (retry)
+   usleep_range(1000, 2000);
+
ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
-  data, write);
+  data, false);
+
} while (ret != 0 && ret != -ENOMEDIUM &&
 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
 
@@ -343,12 +396,13 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
 * in the logs.
 */
if (addr != SBSDIO_FUNC1_SLEEPCSR)
-   brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
- write ? "write" : "read", func, addr, ret);
+   brcmf_err("failed to read data F%d@0x%05x, err: %d\n",
+ func, addr, ret);
else
-   brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: 
%d\n",
- write ? "write" : "read", func, addr, ret);
+   brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: 
%d\n",
+ func, addr, ret);
}
+
return ret;
 }
 
@@ -366,13 +420,11 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev 
*sdiodev, u32 address)
addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
 
for (i = 0; i < 3; i++) {
-   err = brcmf_sdiod_regrw_helper(sdiodev,
- 

[PATCH 04/34] brcmfmac: Clean up brcmf_sdiod_set_sbaddr_window()

2017-07-26 Thread Ian Molton
This function sets the address of the IO window used for
SDIO accesses onto the backplane of the chip.

It currently uses 3 separate masks despite the full mask being
defined in the code already. Remove the separate masks and clean up.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
---
 .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c   | 17 +
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h |  3 ---
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 1ee0f91b6c50..7b2184d1e365 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -410,23 +410,16 @@ static int
 brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
 {
int err = 0, i;
-   u8 addr[3];
+   u32 addr;
 
if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
return -ENOMEDIUM;
 
-   addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
-   addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
-   addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
+   addr = (address & SBSDIO_SBWINDOW_MASK) >> 8;
 
-   for (i = 0; i < 3; i++) {
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i],
- );
-   if (err) {
-   brcmf_err("failed at addr: 0x%0x\n",
- SBSDIO_FUNC1_SBADDRLOW + i);
-   }
-   }
+   for (i = 0 ; i < 3 && !err ; i++, addr >>= 8)
+   brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
+ addr & 0xff, );
 
return err;
 }
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index f3da32fc6360..e3b78db331b5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -133,9 +133,6 @@
 
 /* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
 
-#define SBSDIO_SBADDRLOW_MASK  0x80/* Valid bits in SBADDRLOW */
-#define SBSDIO_SBADDRMID_MASK  0xff/* Valid bits in SBADDRMID */
-#define SBSDIO_SBADDRHIGH_MASK 0xffU   /* Valid bits in SBADDRHIGH */
 /* Address bits from SBADDR regs */
 #define SBSDIO_SBWINDOW_MASK   0x8000
 
-- 
2.11.0



[PATCH 07/34] brcmfmac: Remove brcmf_sdiod_request_data()

2017-07-26 Thread Ian Molton
This function is obfuscating how IO works on this chip. Remove it
and push its logic into brcmf_sdiod_reg_{read,write}().

Handling of -ENOMEDIUM is altered, but as that's pretty much broken anyway
we can ignore that.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>

# Conflicts:
#   drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 239 -
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.h|   2 +-
 2 files changed, 87 insertions(+), 154 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index d217b1281e0d..f703d7be6a85 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -230,6 +230,43 @@ void brcmf_sdiod_change_state(struct brcmf_sdio_dev 
*sdiodev,
sdiodev->state = state;
 }
 
+static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
+u32 address)
+{
+   int err = 0, i;
+   u32 addr;
+
+   if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
+   return -ENOMEDIUM;
+
+   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, );
+
+   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;
+
+   sdiodev->sbwad = bar0;
+   }
+
+   *addr &= SBSDIO_SB_OFT_ADDR_MASK;
+   *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+   return 0;
+}
+
 static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
uint regaddr)
 {
@@ -249,173 +286,83 @@ static inline int brcmf_sdiod_f0_writeb(struct sdio_func 
*func, u8 byte,
return err_ret;
 }
 
-static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
-   u32 addr, u8 regsz, void *data, bool write)
-{
-   struct sdio_func *func;
-   int ret = -EINVAL;
-
-   brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
- write, fn, addr, regsz);
-
-   /* only allow byte access on F0 */
-   if (WARN_ON(regsz > 1 && !fn))
-   return -EINVAL;
-   func = sdiodev->func[fn];
-
-   switch (regsz) {
-   case 1:
-   if (write) {
-   if (fn)
-   sdio_writeb(func, *(u8 *)data, addr, );
-   else
-   ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data,
-   addr);
-   } else {
-   if (fn)
-   *(u8 *)data = sdio_readb(func, addr, );
-   else
-   *(u8 *)data = sdio_f0_readb(func, addr, );
-   }
-   break;
-   case 2:
-   if (write)
-   sdio_writew(func, *(u16 *)data, addr, );
-   else
-   *(u16 *)data = sdio_readw(func, addr, );
-   break;
-   case 4:
-   if (write)
-   sdio_writel(func, *(u32 *)data, addr, );
-   else
-   *(u32 *)data = sdio_readl(func, addr, );
-   break;
-   default:
-   brcmf_err("invalid size: %d\n", regsz);
-   break;
-   }
-
-   if (ret)
-   brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
- write ? "write" : "read", fn, addr, ret);
-
-   return ret;
-}
-
 static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,
 u8 regsz, void *data)
 {
-   u8 func;
-   s32 retry = 0;
int ret;
 
-   if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
-   return -ENOMEDIUM;
-
/*
 * figure out how to read the register based on address range
 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
 * 0x1 ~ 0x1: function 1 miscellaneous registers
 * The rest: function 1 silicon backplane core registers
+* f0 writes must be bytewise
 */
-   if ((addr & ~REG_F0_REG_MASK) == 0)
-   func = SDIO_FUNC_0;
-   else
-   func = SDIO_FUNC_1;
-
-   do {
-   /* for retry wait for 1 ms

[PATCH 08/34] brcmfmac: Fix uninitialised variable

2017-07-26 Thread Ian Molton
Unlikely to be a problem, but brcmf_sdiod_regrb() is
not symmetric with brcmf_sdiod_regrl() in this regard.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index f703d7be6a85..73f2194a854f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -367,7 +367,7 @@ static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev 
*sdiodev, u32 addr,
 
 u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
 {
-   u8 data;
+   u8 data = 0;
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-- 
2.11.0



[PATCH 09/34] brcmfmac: Remove noisy debugging.

2017-07-26 Thread Ian Molton
If you need debugging this low level, you're doing something wrong.
Remove these noisy debug statements so the code is more readable.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 73f2194a854f..049086f6db97 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -370,9 +370,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
u8 data = 0;
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, );
-   brcmf_dbg(SDIO, "data:0x%02x\n", data);
 
if (ret)
*ret = retval;
@@ -385,8 +383,6 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
u32 data = 0;
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-   brcmf_dbg(SDIO, "data:0x%08x\n", data);
retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, );
 
if (ret)
@@ -400,7 +396,6 @@ void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 
addr,
 {
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, );
 
if (ret)
@@ -412,7 +407,7 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 
addr,
 {
int retval;
 
-   brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
+   retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, );
 
if (ret)
*ret = retval;
-- 
2.11.0



[PATCH 01/34] brcmfmac: Fix parameter order in brcmf_sdiod_f0_writeb()

2017-07-26 Thread Ian Molton
All the other IO functions are the other way round in this
driver. Make this one match.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 984c1d0560b1..f585dfd89453 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -230,8 +230,8 @@ void brcmf_sdiod_change_state(struct brcmf_sdio_dev 
*sdiodev,
sdiodev->state = state;
 }
 
-static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
-   uint regaddr, u8 byte)
+static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte,
+   uint regaddr)
 {
int err_ret;
 
@@ -269,8 +269,8 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
if (fn)
sdio_writeb(func, *(u8 *)data, addr, );
else
-   ret = brcmf_sdiod_f0_writeb(func, addr,
-   *(u8 *)data);
+   ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data,
+   addr);
} else {
if (fn)
*(u8 *)data = sdio_readb(func, addr, );
-- 
2.11.0



[PATCH 05/34] brcmfmac: Remove dead IO code

2017-07-26 Thread Ian Molton
The value passed to brcmf_sdiod_addrprep() is *always* 4
remove this parameter and the unused code to handle it.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 7b2184d1e365..609a934c1658 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -425,7 +425,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev 
*sdiodev, u32 address)
 }
 
 static int
-brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
+brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
 {
uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
@@ -439,9 +439,7 @@ brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint 
width, u32 *addr)
}
 
*addr &= SBSDIO_SB_OFT_ADDR_MASK;
-
-   if (width == 4)
-   *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+   *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
return 0;
 }
@@ -467,7 +465,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
+   retval = brcmf_sdiod_addrprep(sdiodev, );
if (retval)
goto done;
 
@@ -500,7 +498,7 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 
addr,
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
-   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
+   retval = brcmf_sdiod_addrprep(sdiodev, );
if (retval)
goto done;
 
@@ -736,7 +734,7 @@ 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, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
if (err)
goto done;
 
@@ -757,7 +755,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n",
  addr, pktq->qlen);
 
-   err = brcmf_sdiod_addrprep(sdiodev, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
if (err)
goto done;
 
@@ -801,7 +799,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 
*buf, uint nbytes)
 
memcpy(mypkt->data, buf, nbytes);
 
-   err = brcmf_sdiod_addrprep(sdiodev, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
 
if (!err)
err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
@@ -821,7 +819,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev,
 
brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen);
 
-   err = brcmf_sdiod_addrprep(sdiodev, 4, );
+   err = brcmf_sdiod_addrprep(sdiodev, );
if (err)
return err;
 
-- 
2.11.0



[PATCH 02/34] brcmfmac: Register sizes on hardware are not dependent on compiler types

2017-07-26 Thread Ian Molton
The 4 IO functions in this patch are incorrect as they use compiler types
to determine how many bytes to send to the hardware.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index f585dfd89453..2b441ce91d5f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -264,7 +264,7 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
func = sdiodev->func[fn];
 
switch (regsz) {
-   case sizeof(u8):
+   case 1:
if (write) {
if (fn)
sdio_writeb(func, *(u8 *)data, addr, );
@@ -278,13 +278,13 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
*(u8 *)data = sdio_f0_readb(func, addr, );
}
break;
-   case sizeof(u16):
+   case 2:
if (write)
sdio_writew(func, *(u16 *)data, addr, );
else
*(u16 *)data = sdio_readw(func, addr, );
break;
-   case sizeof(u32):
+   case 4:
if (write)
sdio_writel(func, *(u32 *)data, addr, );
else
@@ -368,7 +368,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev 
*sdiodev, u32 address)
for (i = 0; i < 3; i++) {
err = brcmf_sdiod_regrw_helper(sdiodev,
   SBSDIO_FUNC1_SBADDRLOW + i,
-  sizeof(u8), [i], true);
+  1, [i], true);
if (err) {
brcmf_err("failed at addr: 0x%0x\n",
  SBSDIO_FUNC1_SBADDRLOW + i);
@@ -407,7 +407,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, ,
  false);
brcmf_dbg(SDIO, "data:0x%02x\n", data);
 
@@ -423,10 +423,10 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 
addr, int *ret)
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
-   retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), );
+   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
if (retval)
goto done;
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, ,
  false);
brcmf_dbg(SDIO, "data:0x%08x\n", data);
 
@@ -443,7 +443,7 @@ void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 
addr,
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data);
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, ,
  true);
if (ret)
*ret = retval;
@@ -455,10 +455,10 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, 
u32 addr,
int retval;
 
brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data);
-   retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), );
+   retval = brcmf_sdiod_addrprep(sdiodev, 4, );
if (retval)
goto done;
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), ,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, ,
  true);
 
 done:
@@ -876,7 +876,7 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint 
fn)
 
/* issue abort cmd52 command through F0 */
brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT,
-sizeof(t_func), _func, true);
+1, _func, true);
 
brcmf_dbg(SDIO, "Exit\n");
return 0;
-- 
2.11.0



Patch v4: Clean up brcmfmac driver

2017-07-26 Thread Ian Molton
Hi folks,

Here's a v4 of the cleanup patchset - checkpatch clean(er - I have purposely
left some warnings unaddressed).

I also dropped an accidental adjustment of a debug macro from v3.

-Ian



Re: PATCH v3 brcmfmac driver cleanup

2017-07-26 Thread Ian Molton
On 24/07/17 20:47, Arend van Spriel wrote:
> On 19-07-17 21:07, Ian Molton wrote:
>> Hi all,
>>
>> Please find the 3rd revision of my cleanup patchset for brcmfmac.
>>
>> I've done some further cleanup and it now handles SDIO the ay the MMC 
>> subsystem
>> was designed to.
>>
>> I've also taken the liberty of greatly reducing the amount of indirection
>> used thoughout the SDIO code, which I think has improved readability quite a
>> lot.
>>
>> Hope this finds you all well.
> After only one week of vacation there was quite some catching up to do.
> So I decided to get an easy start and run 'checkpatch.pl --strict' over
> the series. Attached the output of that. Might be stuff that was already
> wrong before.

Some of it will be. I can see a couple of lines have crept over 80 chars.

Some lines are ~81-83 chars - I tend to leave those as its usually quite
apparent what is missing off the end. Longer ones I agree should be split.

The original source has some inconsistent whitespace too, which
complicates matters.

> I did only a quick check on patch 1/34 and it is really
> introduced by that patch. So can you please check the output.

Will have a run through and resubmit.

> FWIW, I tend to ignore the warning about block comments, ie.:

Yeah, I tend to agree. /* Blah as the first line of a multiline comment
just looks unbalanced to me.

-Ian


Re: brcm43430 sdio wifi regression with 4.13-rc1

2017-07-22 Thread Ian Molton
On 22/07/17 20:18, Ian Molton wrote:
> On 22/07/17 19:43, Hans de Goede wrote:
>> Hi,
>>
>> When upgrading my devel environment to 4.13-rc1+ I noticed that
>> the brcm43430 sdio wifi on a Chuwi Hi8 plus stopped working:
> 
> There is a fix for this:
> 
> https://patchwork.kernel.org/patch/9836383/

Sorry, ignore me - this was a fix for the other 4.13-rc1 regression.
Arend is looking into he other one. It affects me too.

It appears to be the firmware going astray.

-Ian


Re: brcm43430 sdio wifi regression with 4.13-rc1

2017-07-22 Thread Ian Molton
On 22/07/17 19:43, Hans de Goede wrote:
> Hi,
> 
> When upgrading my devel environment to 4.13-rc1+ I noticed that
> the brcm43430 sdio wifi on a Chuwi Hi8 plus stopped working:

There is a fix for this:



https://patchwork.kernel.org/patch/9836383/

IIRC

-Ian


Re: [PATCH 28/29] brcmfmac: Rename buscore->core for consistency

2017-07-20 Thread Ian Molton
On 20/07/17 08:00, kbuild test robot wrote:
> Hi Ian,
> 
> [auto build test WARNING on wireless-drivers-next/master]
> [also build test WARNING on v4.13-rc1]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
> 
> url:
> https://github.com/0day-ci/linux/commits/Ian-Molton/brcmfmac-Fix-parameter-order-in-brcmf_sdiod_f0_writeb/20170718-123057
> base:   
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git
>  master
> config: x86_64-randconfig-a0-07201347 (attached as .config)
> compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64 
> 
> All warnings (new ones prefixed by >>):
> 
>drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c: In function 
> 'brcmf_sdio_intr_rstatus':
>>> drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:2470: warning: 
>>> unused variable 'addr'

Fixed in v3 spin of this series.


Re: brcmfmac bus level addressing issues.

2017-07-19 Thread Ian Molton
On 19/07/17 12:47, Arend van Spriel wrote:
> On 19-07-17 00:45, Ian Molton wrote:

>> (as it stands, back to back wpasuplpicant runs make it keel over, as
>> does module unload and reload).
> 
> It is good to get such feedback. We should get in details about this.

I'll reply with a couple of logs on here. I was going to just post the
one, but of course, typically, it did not fail the same way this time...

# rmmod brcmfmac

brcmfmac: brcmf_proto_bcdc_query_dcmd: brcmf_proto_bcdc_msg failed
w/status -5
brcmfmac: brcmf_cfg80211_get_tx_power: error (-5)
brcmfmac: brcmf_fil_cmd_data: bus is down. we have nothing to do.
brcmfmac: brcmf_link_down: WLC_DISASSOC failed (-5)
brcmfmac: brcmf_fil_cmd_data: bus is down. we have nothing to do.
brcmfmac: brcmf_fil_cmd_data: bus is down. we have nothing to do.
brcmfmac: brcmf_fil_cmd_data: bus is down. we have nothing to do.
brcmfmac: brcmf_cfg80211_get_channel: chanspec failed (-5)
Enter

# modprobe brcmfmac
 [1 ] core 0x800:49 base 0x1800 wrap 0x1810
 [2 ] core 0x812:39 base 0x18001000 wrap 0x18101000
 [3 ] core 0x829:21 base 0x18002000 wrap 0x18102000
 [4 ] core 0x82a:9  base 0x18003000 wrap 0x18103000
 [5 ] core 0x80e:22 base 0x18004000 wrap 0x18104000
 [6 ] core 0x135:0  base 0x wrap 0x18105000
 [7 ] core 0x240:0  base 0x wrap 0x18106000
Enter
RAM: base=0x0 size=524288 (0x8) sr=65536 (0x1)
Found BCM43430, AXI backplane, rev=1
ccrev=49, pmurev=24, pmucaps=0x39d25f18
Enter
Enter
Enter
Enter
brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Aug 29 2016
20:48:16 version 7.45.41.26 (r640327) FWID 01-4527cfab
IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready

#
# wpa_supplicant -B -i wlan0 -c <(wpa_passphrase vortex24 password) &&
dhclient wlan0

Successfully initialized wpa_supplicant
rfkill: Cannot open RFKILL control device
brcmfmac: brcmf_link_down: WLC_DISASSOC failed (-11)
rfkill: Cannot open RFKILL control device
brcmfmac: brcmf_cfg80211_escan: Connecting: status (3)
brcmfmac: brcmf_cfg80211_scan: scan error (-11)

# wget --no-check-certificate
https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.12.tar.xz
--2017-07-19 19:13:22--
https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.12.tar.xz
Resolving cdn.kernel.org (cdn.kernel.org)... 151.101.17.176,
2a04:4e42:4::432
Connecting to cdn.kernel.org (cdn.kernel.org)|151.101.17.176|:443...
connected.
WARNING: The certificate of ‘cdn.kernel.org’ is not trusted.
WARNING: The certificate of ‘cdn.kernel.org’ hasn't got a known issuer.
HTTP request sent, awaiting response... 200 OK
Length: 99186576 (95M) [application/x-xz]
Saving to: ‘linux-4.12.tar.xz.30’

linux-4.12.tar.xz.3   1%[]   1.81M  1.08MB/s
  ^C
root@martel:~# brcmfmac: brcmf_cfg80211_escan: Connecting: status (3)
brcmfmac: brcmf_cfg80211_scan: scan error (-11)

# wget --no-check-certificate
https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.12.tar.xz
--2017-07-19 19:15:01--
https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.12.tar.xz
Resolving cdn.kernel.org (cdn.kernel.org)...


brcmfmac: brcmf_cfg80211_escan: Connecting: status (3)
brcmfmac: brcmf_cfg80211_scan: scan error (-11)
brcmfmac: brcmf_cfg80211_escan: Scanning already: status (1)
brcmfmac: brcmf_cfg80211_scan: scan error (-11)
brcmfmac: brcmf_cfg80211_escan: Connecting: status (3)
brcmfmac: brcmf_cfg80211_scan: scan error (-11)
brcmfmac: brcmf_cfg80211_escan: Connecting: status (3)
brcmfmac: brcmf_cfg80211_scan: scan error (-11)



[PATCH 31/34] brcmfmac: Remove func0 from function array

2017-07-19 Thread Ian Molton
Linux doesnt pass you func0 as a function when probing - instead
providing specific access functions to read/write it.

This prepares for a patch to remove the actual array entry itself.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |  5 +
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c   |  4 ++--
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 13 ++---
 3 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 42b09a301f5f..89cf71d98cee 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -1021,8 +1021,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
/* store refs to functions used. mmc_card does
 * not hold the F0 function pointer.
 */
-   sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL);
-   sdiodev->func[0]->num = 0;
+   sdiodev->func[0] = NULL;
sdiodev->func[1] = func->card->sdio_func[0];
sdiodev->func[2] = func;
 
@@ -1048,7 +1047,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
 fail:
dev_set_drvdata(>dev, NULL);
dev_set_drvdata(>func[1]->dev, NULL);
-   kfree(sdiodev->func[0]);
kfree(sdiodev);
kfree(bus_if);
return err;
@@ -1081,7 +1079,6 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
dev_set_drvdata(>func[2]->dev, NULL);
 
kfree(bus_if);
-   kfree(sdiodev->func[0]);
kfree(sdiodev);
}
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 2a52f48bdddc..9b8bd870c1fc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3751,8 +3751,8 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
/* Force 4339 chips over rev2 to use the same ID */
/* This is borderline tolerable whilst there is only two exceptions */
/* But could be handled better */
-   if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
-   sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
+   if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
+   sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
 
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index d0dd69454bbd..cae21d14042d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -21,7 +21,9 @@
 #include 
 #include "firmware.h"
 
-#define SDIO_FUNC_00
+/* Maximum number of I/O funcs */
+#define NUM_SDIO_FUNCS 3
+
 #define SDIO_FUNC_11
 #define SDIO_FUNC_22
 
@@ -39,9 +41,6 @@
 #define INTR_STATUS_FUNC1  0x2
 #define INTR_STATUS_FUNC2  0x4
 
-/* Maximum number of I/O funcs */
-#define SDIOD_MAX_IOFUNCS  7
-
 /* mask of register map */
 #define REG_F0_REG_MASK0x7FF
 #define REG_F1_MISC_MASK   0x1
@@ -175,7 +174,7 @@ struct brcmf_sdio;
 struct brcmf_sdiod_freezer;
 
 struct brcmf_sdio_dev {
-   struct sdio_func *func[SDIO_MAX_FUNCS];
+   struct sdio_func *func[NUM_SDIO_FUNCS];
u8 num_funcs;   /* Supported funcs on client */
u32 sbwad;  /* Save backplane window address */
struct brcmf_core *cc_core; /* chipcommon core info struct */
@@ -297,10 +296,10 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev);
 /* SDIO device register access interface */
 /* Functions for accessing SDIO Function 0 */
 #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
-   sdio_f0_readb((sdiodev)->func[0], (addr), (r))
+   sdio_f0_readb((sdiodev)->func[1], (addr), (r))
 
 #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
-   sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
+   sdio_f0_writeb((sdiodev)->func[1], (v), (addr), (ret))
 
 /* Functions for accessing SDIO Function 1 */
 #define brcmf_sdiod_readb(sdiodev, addr, r) \
-- 
2.11.0



[PATCH 28/34] brcmfmac: Rename buscore->core for consistency

2017-07-19 Thread Ian Molton
Avoid confusion with unrelated _buscore labels.

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index cc83388b8c72..19f40a1ee418 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -2466,14 +2466,11 @@ static inline void brcmf_sdio_clrintr(struct brcmf_sdio 
*bus)
 
 static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 {
-   struct brcmf_core *buscore = bus->sdio_core;
-   u32 addr;
+   struct brcmf_core *core = bus->sdio_core;
unsigned long val;
int ret;
 
-   addr = buscore->base + __sd_reg(intstatus);
-
-   val = brcmf_sdiod_readl(bus->sdiodev, addr, );
+   val = brcmf_sdiod_readl(bus->sdiodev, core->base + __sd_reg(intstatus), 
);
bus->sdcnt.f1regdata++;
if (ret != 0)
return ret;
@@ -2483,7 +2480,8 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 
/* Clear interrupts */
if (val) {
-   brcmf_sdiod_writel(bus->sdiodev, addr, val, );
+   brcmf_sdiod_writel(bus->sdiodev, core->base + 
__sd_reg(intstatus),
+   val, );
bus->sdcnt.f1regdata++;
atomic_or(val, >intstatus);
}
-- 
2.11.0



[PATCH 30/34] brcmfmac: Correctly handle accesses to SDIO func0

2017-07-19 Thread Ian Molton
Rather than workaround the restrictions on func0 addressing in the
driver, set MMC_QUIRK_LENIENT_FN0

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h   | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index dcdebe8e8ff4..42b09a301f5f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -994,6 +994,10 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
brcmf_dbg(SDIO, "Function#: %d\n", func->num);
 
dev = >dev;
+
+   /* Set MMC_QUIRK_LENIENT_FN0 for this card */
+   func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+
/* prohibit ACPI power management for this device */
brcmf_sdiod_acpi_set_power_manageable(dev, 0);
 
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index a5a05d1a34bf..d0dd69454bbd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -297,10 +297,10 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev);
 /* SDIO device register access interface */
 /* Functions for accessing SDIO Function 0 */
 #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \
-   sdio_readb((sdiodev)->func[0], (addr), (r))
+   sdio_f0_readb((sdiodev)->func[0], (addr), (r))
 
 #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \
-   sdio_writeb((sdiodev)->func[0], (v), (addr), (ret))
+   sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret))
 
 /* Functions for accessing SDIO Function 1 */
 #define brcmf_sdiod_readb(sdiodev, addr, r) \
-- 
2.11.0



[PATCH 34/34] brcmfmac: Reduce the noise from repeatedly dereferencing common pointers

2017-07-19 Thread Ian Molton
This introduces no functional changes, but makes the code drastically more
readable, reducing the amount of dereferencing performed inside functions
throughout the SDIO core.

For example, reduce:
sdio_release_host(bus->sdiodev->func1);
to:
sdio_release_host(func1);

Fixup a few inconsistently named pointers whilst we are at it ie.

sdiod -> sdiodev

Signed-off-by: Ian Molton <i...@mnementh.co.uk>
---
 .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c  | 139 
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c| 380 +++--
 2 files changed, 285 insertions(+), 234 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index d9fe2faf2b04..3319deb0e889 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -105,6 +105,8 @@ static void brcmf_sdiod_dummy_irqhandler(struct sdio_func 
*func)
 int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
 {
struct brcmfmac_sdio_pd *pdata;
+   struct sdio_func *func1 = sdiodev->func1;
+   struct sdio_func *func2 = sdiodev->func2;
int ret = 0;
u8 data;
u32 addr, gpiocontrol;
@@ -118,7 +120,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
  pdata->oob_irq_flags, "brcmf_oob_intr",
- >func1->dev);
+ >dev);
if (ret != 0) {
brcmf_err("request_irq failed %d\n", ret);
return ret;
@@ -132,7 +134,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
}
sdiodev->irq_wake = true;
 
-   sdio_claim_host(sdiodev->func1);
+   sdio_claim_host(func1);
 
if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
/* assign GPIO to SDIO core */
@@ -156,13 +158,13 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
data |= SDIO_SEPINT_ACT_HI;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
);
-   sdio_release_host(sdiodev->func1);
+   sdio_release_host(func1);
} else {
brcmf_dbg(SDIO, "Entering\n");
-   sdio_claim_host(sdiodev->func1);
-   sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler);
-   sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler);
-   sdio_release_host(sdiodev->func1);
+   sdio_claim_host(func1);
+   sdio_claim_irq(func1, brcmf_sdiod_ib_irqhandler);
+   sdio_claim_irq(func2, brcmf_sdiod_dummy_irqhandler);
+   sdio_release_host(func1);
sdiodev->sd_irq_requested = true;
}
 
@@ -171,6 +173,8 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev 
*sdiodev)
 
 void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
 {
+   struct sdio_func *func1 = sdiodev->func1;
+   struct sdio_func *func2 = sdiodev->func2;
 
brcmf_dbg(SDIO, "Entering oob=%d sd=%d\n",
  sdiodev->oob_irq_requested,
@@ -180,26 +184,26 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
struct brcmfmac_sdio_pd *pdata;
 
pdata = >settings->bus.sdio;
-   sdio_claim_host(sdiodev->func1);
+   sdio_claim_host(func1);
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->func1);
+   sdio_release_host(func1);
 
sdiodev->oob_irq_requested = false;
if (sdiodev->irq_wake) {
disable_irq_wake(pdata->oob_irq_nr);
sdiodev->irq_wake = false;
}
-   free_irq(pdata->oob_irq_nr, >func1->dev);
+   free_irq(pdata->oob_irq_nr, >dev);
sdiodev->irq_en = false;
sdiodev->oob_irq_requested = false;
}
 
if (sdiodev->sd_irq_requested) {
-   sdio_claim_host(sdiodev->func1);
-   sdio_release_irq(sdiodev->func2);
-   sdio_release_irq(sdiodev->func1);
-   sdio_release_host(sdiodev->func1);
+   sdio_claim_host(func1);
+   sdio_release_irq(func2);
+   sdio_release_irq(func1);
+   sdio_release_host(func1);
sdiodev-

  1   2   3   >