Re: [PATCH] drivers: net: wireless: atmel: check memory allocation failure

2017-08-22 Thread Kalle Valo
Himanshu Jha  writes:

> Check memory allocation failure and return -ENOMEM if failure
> occurs.
>
> Signed-off-by: Himanshu Jha 

The title prefix is wrong:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#commit_title_is_wrong

-- 
Kalle Valo


Re: [PATCH v12 7/8] wireless: ipw2200: Replace PCI pool old API

2017-08-22 Thread Kalle Valo
+ linux-wireless

Stanislav Yakovlev  writes:

> On 22 August 2017 at 07:47, Romain Perier  wrote:
>> The PCI pool API is deprecated. This commit replaces the PCI pool old
>> API by the appropriate function with the DMA pool API.
>>
>> Signed-off-by: Romain Perier 
>> Reviewed-by: Peter Senna Tschudin 
>> ---
>>  drivers/net/wireless/intel/ipw2x00/ipw2200.c | 13 +++--
>>  1 file changed, 7 insertions(+), 6 deletions(-)
>>
>
> Acked-by: Stanislav Yakovlev 
>
> Thanks, and sorry for the long review.
>
> Kalle, could you please apply it to the wireless-drivers-next tree?

It was not sent to linux-wireless so patchwork didn't see it and hence
it's not on my queue. Please resend.

[1] https://patchwork.kernel.org/project/linux-wireless/list/

-- 
Kalle Valo


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 v3 1/2] ath10k: add the PCI PM core suspend/resume ops

2017-08-22 Thread ryanhsu
From: Ryan Hsu 

The actual PCI suspend/resume in ath10k has been handled in wow.c,
but in the case of the device doesn't support remote wakeup,
the .hif_suspend() and .hif_resume() will never be handled.

  ath10k_wow_op_suspend()
  {
if (WARN_ON(!test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
ar->running_fw->fw_file.fw_features))) {
ret = 1;
goto exit;
}



ret = ath10k_hif_suspend(ar);
  }

So register the PCI PM core to support the suspend/resume if the device
doesn't support remote wakeup.

Signed-off-by: Ryan Hsu 
---
 drivers/net/wireless/ath/ath10k/pci.c | 42 +++
 1 file changed, 42 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 0457e31..4aac0de 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -3358,11 +3358,53 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
 
 MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table);
 
+#ifdef CONFIG_PM
+
+static int ath10k_pci_pm_suspend(struct device *dev)
+{
+   struct ath10k *ar = dev_get_drvdata(dev);
+   int ret;
+
+   if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ar->running_fw->fw_file.fw_features))
+   return 0;
+
+   ret = ath10k_hif_suspend(ar);
+   if (ret)
+   ath10k_warn(ar, "failed to suspend hif: %d\n", ret);
+
+   return ret;
+}
+
+static int ath10k_pci_pm_resume(struct device *dev)
+{
+   struct ath10k *ar = dev_get_drvdata(dev);
+   int ret;
+
+   if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ar->running_fw->fw_file.fw_features))
+   return 0;
+
+   ret = ath10k_hif_resume(ar);
+   if (ret)
+   ath10k_warn(ar, "failed to resume hif: %d\n", ret);
+
+   return ret;
+}
+
+SIMPLE_DEV_PM_OPS(ath10k_pci_pm_ops,
+ ath10k_pci_pm_suspend,
+ ath10k_pci_pm_resume);
+#endif
+
 static struct pci_driver ath10k_pci_driver = {
.name = "ath10k_pci",
.id_table = ath10k_pci_id_table,
.probe = ath10k_pci_probe,
.remove = ath10k_pci_remove,
+#ifdef CONFIG_PM
+   .driver.pm = &ath10k_pci_pm_ops,
+#endif
 };
 
 static int __init ath10k_pci_init(void)
-- 
1.9.1



[PATCH v3 2/2] ath10k: Configure and enable the wakeup capability

2017-08-22 Thread ryanhsu
From: Ryan Hsu 

ACPI will rely on device driver to tell it if the device could support
wakeup function when system in D3 state.

This has caused some platform can't support remote wakeup correctly,
because the ACPI wakeup GPE is not enabled, hence registers the .set_wakeup
callback to handle it if device supports wakeup.

Tested with QCA6174 hw3.0, firmware ('WLAN.RM.4.4.1-8-QCARMSWP-1')

Signed-off-by: Ryan Hsu 
---
 drivers/net/wireless/ath/ath10k/mac.c |  1 +
 drivers/net/wireless/ath/ath10k/wow.c | 14 ++
 drivers/net/wireless/ath/ath10k/wow.h |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 2e5d2ca..bbf7da1 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7488,6 +7488,7 @@ static const struct ieee80211_ops ath10k_ops = {
 #ifdef CONFIG_PM
.suspend= ath10k_wow_op_suspend,
.resume = ath10k_wow_op_resume,
+   .set_wakeup = ath10k_wow_op_set_wakeup,
 #endif
 #ifdef CONFIG_MAC80211_DEBUGFS
.sta_add_debugfs= ath10k_sta_add_debugfs,
diff --git a/drivers/net/wireless/ath/ath10k/wow.c 
b/drivers/net/wireless/ath/ath10k/wow.c
index 77100d4..0d46d6d 100644
--- a/drivers/net/wireless/ath/ath10k/wow.c
+++ b/drivers/net/wireless/ath/ath10k/wow.c
@@ -277,6 +277,18 @@ exit:
return ret ? 1 : 0;
 }
 
+void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+   struct ath10k *ar = hw->priv;
+
+   mutex_lock(&ar->conf_mutex);
+   if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ar->running_fw->fw_file.fw_features)) {
+   device_set_wakeup_enable(ar->dev, enabled);
+   }
+   mutex_unlock(&ar->conf_mutex);
+}
+
 int ath10k_wow_op_resume(struct ieee80211_hw *hw)
 {
struct ath10k *ar = hw->priv;
@@ -336,5 +348,7 @@ int ath10k_wow_init(struct ath10k *ar)
ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns;
ar->hw->wiphy->wowlan = &ar->wow.wowlan_support;
 
+   device_set_wakeup_capable(ar->dev, true);
+
return 0;
 }
diff --git a/drivers/net/wireless/ath/ath10k/wow.h 
b/drivers/net/wireless/ath/ath10k/wow.h
index abbb04b..9745b9d 100644
--- a/drivers/net/wireless/ath/ath10k/wow.h
+++ b/drivers/net/wireless/ath/ath10k/wow.h
@@ -28,6 +28,7 @@ int ath10k_wow_init(struct ath10k *ar);
 int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
  struct cfg80211_wowlan *wowlan);
 int ath10k_wow_op_resume(struct ieee80211_hw *hw);
+void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled);
 
 #else
 
-- 
1.9.1



[PATCH] ath10k: fix napi_poll budget overflow

2017-08-22 Thread ryanhsu
From: Ryan Hsu 

In napi_poll, the budget number is used to control the amount of packets
we should handle per poll to balance the resource in the system.

In the list of the amsdu packets reception, we check if there is budget
count left and handle the complete list of the packets, that it will have
chances the very last list will over the budget leftover.

So adding one more parameter - budget_left, this would help while
traversing the list to avoid handling more than the budget given.

Reported-by: Andrey Ryabinin 
Fix-suggested-by: Igor Mitsyanko 

Signed-off-by: Ryan Hsu 
---
 drivers/net/wireless/ath/ath10k/htt_rx.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 0b4c156..95a5a18 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1718,7 +1718,8 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct 
htt_resp *resp)
 }
 
 static int ath10k_htt_rx_extract_amsdu(struct sk_buff_head *list,
-  struct sk_buff_head *amsdu)
+  struct sk_buff_head *amsdu,
+  int budget_left)
 {
struct sk_buff *msdu;
struct htt_rx_desc *rxd;
@@ -1729,8 +1730,9 @@ static int ath10k_htt_rx_extract_amsdu(struct 
sk_buff_head *list,
if (WARN_ON(!skb_queue_empty(amsdu)))
return -EINVAL;
 
-   while ((msdu = __skb_dequeue(list))) {
+   while ((msdu = __skb_dequeue(list)) && budget_left) {
__skb_queue_tail(amsdu, msdu);
+   budget_left--;
 
rxd = (void *)msdu->data - sizeof(*rxd);
if (rxd->msdu_end.common.info0 &
@@ -1821,7 +1823,8 @@ static int ath10k_htt_rx_h_rx_offload(struct ath10k *ar,
return num_msdu;
 }
 
-static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
+static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb,
+   int budget_left)
 {
struct ath10k_htt *htt = &ar->htt;
struct htt_resp *resp = (void *)skb->data;
@@ -1878,9 +1881,9 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, 
struct sk_buff *skb)
if (offload)
num_msdus = ath10k_htt_rx_h_rx_offload(ar, &list);
 
-   while (!skb_queue_empty(&list)) {
+   while (!skb_queue_empty(&list) && budget_left) {
__skb_queue_head_init(&amsdu);
-   ret = ath10k_htt_rx_extract_amsdu(&list, &amsdu);
+   ret = ath10k_htt_rx_extract_amsdu(&list, &amsdu, budget_left);
switch (ret) {
case 0:
/* Note: The in-order indication may report interleaved
@@ -1890,6 +1893,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, 
struct sk_buff *skb)
 * should still give an idea about rx rate to the user.
 */
num_msdus += skb_queue_len(&amsdu);
+   budget_left -= skb_queue_len(&amsdu);
ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
ath10k_htt_rx_h_filter(ar, &amsdu, status);
ath10k_htt_rx_h_mpdu(ar, &amsdu, status);
@@ -2400,7 +2404,8 @@ int ath10k_htt_txrx_compl_task(struct ath10k *ar, int 
budget)
}
 
spin_lock_bh(&htt->rx_ring.lock);
-   num_rx_msdus = ath10k_htt_rx_in_ord_ind(ar, skb);
+   num_rx_msdus = ath10k_htt_rx_in_ord_ind(ar, skb,
+   (budget - quota));
spin_unlock_bh(&htt->rx_ring.lock);
if (num_rx_msdus < 0) {
resched_napi = true;
-- 
1.9.1



[PATCH v2 1/2] ath10k: add the PCI PM core suspend/resume ops

2017-08-22 Thread ryanhsu
From: Ryan Hsu 

The actual PCI suspend/resume in ath10k has been handled in wow.c,
but in the case of the device doesn't support remote wakeup,
the .hif_suspend() and .hif_resume() will never be handled.

  ath10k_wow_op_suspend()
  {
if (WARN_ON(!test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
ar->running_fw->fw_file.fw_features))) {
ret = 1;
goto exit;
}



ret = ath10k_hif_suspend(ar);
  }

So register the PCI PM core to support the suspend/resume if the device
doesn't support remote wakeup.

Signed-off-by: Ryan Hsu 
---
 drivers/net/wireless/ath/ath10k/pci.c | 42 +++
 1 file changed, 42 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 0457e31..4aac0de 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -3358,11 +3358,53 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
 
 MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table);
 
+#ifdef CONFIG_PM
+
+static int ath10k_pci_pm_suspend(struct device *dev)
+{
+   struct ath10k *ar = dev_get_drvdata(dev);
+   int ret;
+
+   if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ar->running_fw->fw_file.fw_features))
+   return 0;
+
+   ret = ath10k_hif_suspend(ar);
+   if (ret)
+   ath10k_warn(ar, "failed to suspend hif: %d\n", ret);
+
+   return ret;
+}
+
+static int ath10k_pci_pm_resume(struct device *dev)
+{
+   struct ath10k *ar = dev_get_drvdata(dev);
+   int ret;
+
+   if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ar->running_fw->fw_file.fw_features))
+   return 0;
+
+   ret = ath10k_hif_resume(ar);
+   if (ret)
+   ath10k_warn(ar, "failed to resume hif: %d\n", ret);
+
+   return ret;
+}
+
+SIMPLE_DEV_PM_OPS(ath10k_pci_pm_ops,
+ ath10k_pci_pm_suspend,
+ ath10k_pci_pm_resume);
+#endif
+
 static struct pci_driver ath10k_pci_driver = {
.name = "ath10k_pci",
.id_table = ath10k_pci_id_table,
.probe = ath10k_pci_probe,
.remove = ath10k_pci_remove,
+#ifdef CONFIG_PM
+   .driver.pm = &ath10k_pci_pm_ops,
+#endif
 };
 
 static int __init ath10k_pci_init(void)
-- 
1.9.1



[PATCH v2 2/2] ath10k: Configure and enable the wakeup capability

2017-08-22 Thread ryanhsu
From: Ryan Hsu 

ACPI will rely on device driver to tell it if the device could support
wakeup function when system in D3 state.

This has caused some platform can't support remote wakeup correctly,
because the ACPI wakeup GPE is not enabled, hence registers the .set_wakeup
callback to handle it if device supports wakeup.

Signed-off-by: Ryan Hsu 
---
 drivers/net/wireless/ath/ath10k/mac.c |  1 +
 drivers/net/wireless/ath/ath10k/wow.c | 14 ++
 drivers/net/wireless/ath/ath10k/wow.h |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 2e5d2ca..bbf7da1 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7488,6 +7488,7 @@ static const struct ieee80211_ops ath10k_ops = {
 #ifdef CONFIG_PM
.suspend= ath10k_wow_op_suspend,
.resume = ath10k_wow_op_resume,
+   .set_wakeup = ath10k_wow_op_set_wakeup,
 #endif
 #ifdef CONFIG_MAC80211_DEBUGFS
.sta_add_debugfs= ath10k_sta_add_debugfs,
diff --git a/drivers/net/wireless/ath/ath10k/wow.c 
b/drivers/net/wireless/ath/ath10k/wow.c
index 77100d4..0d46d6d 100644
--- a/drivers/net/wireless/ath/ath10k/wow.c
+++ b/drivers/net/wireless/ath/ath10k/wow.c
@@ -277,6 +277,18 @@ exit:
return ret ? 1 : 0;
 }
 
+void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+   struct ath10k *ar = hw->priv;
+
+   mutex_lock(&ar->conf_mutex);
+   if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ar->running_fw->fw_file.fw_features)) {
+   device_set_wakeup_enable(ar->dev, enabled);
+   }
+   mutex_unlock(&ar->conf_mutex);
+}
+
 int ath10k_wow_op_resume(struct ieee80211_hw *hw)
 {
struct ath10k *ar = hw->priv;
@@ -336,5 +348,7 @@ int ath10k_wow_init(struct ath10k *ar)
ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns;
ar->hw->wiphy->wowlan = &ar->wow.wowlan_support;
 
+   device_set_wakeup_capable(ar->dev, true);
+
return 0;
 }
diff --git a/drivers/net/wireless/ath/ath10k/wow.h 
b/drivers/net/wireless/ath/ath10k/wow.h
index abbb04b..9745b9d 100644
--- a/drivers/net/wireless/ath/ath10k/wow.h
+++ b/drivers/net/wireless/ath/ath10k/wow.h
@@ -28,6 +28,7 @@ int ath10k_wow_init(struct ath10k *ar);
 int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
  struct cfg80211_wowlan *wowlan);
 int ath10k_wow_op_resume(struct ieee80211_hw *hw);
+void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled);
 
 #else
 
-- 
1.9.1



[PATCH] wireless: allow send peer mac in rssi cqm notify

2017-08-22 Thread Pradeep Kumar Chitrapu
Extend cqm rssi notifier apis to include peer mac address. Currently
netlink cqm msg already accepts the mac. With this change just passing
the mac address as an argument to cfg and mac80211 apis.

Signed-off-by: Pradeep Kumar Chitrapu 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rx.c  |  4 ++--
 drivers/net/wireless/marvell/mwifiex/sta_event.c |  4 ++--
 drivers/net/wireless/rndis_wlan.c|  2 +-
 drivers/net/wireless/rsi/rsi_91x_mac80211.c  |  3 ++-
 drivers/net/wireless/st/cw1200/sta.c |  4 ++--
 drivers/net/wireless/ti/wl1251/event.c   |  4 ++--
 drivers/net/wireless/ti/wlcore/event.c   |  4 ++--
 include/net/cfg80211.h   |  3 ++-
 include/net/mac80211.h   |  3 ++-
 net/mac80211/mlme.c  | 14 +++---
 net/mac80211/trace.h |  8 +---
 net/wireless/nl80211.c   |  6 +++---
 net/wireless/trace.h |  9 ++---
 13 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index 622d543abb70..82d64ef87176 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -594,7 +594,7 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
IWL_DEBUG_RX(mvm, "cqm_iterator cqm low %d\n",
 sig);
ieee80211_cqm_rssi_notify(
-   vif,
+   vif, NULL,
NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
sig,
GFP_KERNEL);
@@ -604,7 +604,7 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
IWL_DEBUG_RX(mvm, "cqm_iterator cqm high %d\n",
 sig);
ieee80211_cqm_rssi_notify(
-   vif,
+   vif, NULL,
NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
sig,
GFP_KERNEL);
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c 
b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index 839df8a9634e..ba80d90ba5d0 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -822,7 +822,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
break;
 
case EVENT_RSSI_LOW:
-   cfg80211_cqm_rssi_notify(priv->netdev,
+   cfg80211_cqm_rssi_notify(priv->netdev, NULL,
 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
 0, GFP_KERNEL);
mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
@@ -837,7 +837,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
mwifiex_dbg(adapter, EVENT, "event: MAX_FAIL\n");
break;
case EVENT_RSSI_HIGH:
-   cfg80211_cqm_rssi_notify(priv->netdev,
+   cfg80211_cqm_rssi_notify(priv->netdev, NULL,
 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
 0, GFP_KERNEL);
mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
diff --git a/drivers/net/wireless/rndis_wlan.c 
b/drivers/net/wireless/rndis_wlan.c
index 9935bd09db1f..24f192deaf3d 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -3194,7 +3194,7 @@ static void rndis_do_cqm(struct usbnet *usbdev, s32 rssi)
return;
 
priv->last_cqm_event_rssi = rssi;
-   cfg80211_cqm_rssi_notify(usbdev->net, event, rssi, GFP_KERNEL);
+   cfg80211_cqm_rssi_notify(usbdev->net, NULL, event, rssi, GFP_KERNEL);
 }
 
 #define DEVICE_POLLER_JIFFIES (HZ)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c 
b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 021e5ac5f107..4daf78acd2dc 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -877,7 +877,8 @@ static void rsi_perform_cqm(struct rsi_common *common,
 
common->cqm_info.last_cqm_event_rssi = rssi;
rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
-   ieee80211_cqm_rssi_notify(adapter->vifs[0], event, rssi, GFP_KERNEL);
+   ieee80211_cqm_rssi_notify(adapter->vifs[0], NULL,  event,
+ rssi, GFP_KERNEL);
 
return;
 }
diff --git a/drivers/net/wireless/st/cw1200/sta.c 
b/drivers/net/wireless/st/cw1200/sta.c
index a52224836a2b..de786269468a 100644
--- a/drivers/net/wireless/st/cw1200/sta.c
+++ b/drivers/net/wireless/st/cw1200/sta.c
@@ -1019,8 +1019,8 @@ void cw1200_event_handler(struct work_struct *work)
NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
NL80211_CQM_RSSI_THRESHOL

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

2017-08-22 Thread Arend van Spriel

On 22-08-17 21:38, Arend van Spriel wrote:

On 22-08-17 14:50, Julian Calaby wrote:

Hi Ian,

On Tue, Aug 22, 2017 at 9:25 PM, Ian Molton  wrote:

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.


Wouldn't it be more safe to write these sorts of functions so that
they set the window themselves instead of relying on the caller?


The function brcmf_sdiod_set_backplane_window() is a helper function by 
which these sorts of functions set the window themselves. It would be 
duplicating too much code as setting the window involves three register 
accesses (or so) on the device.


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.


Regards,
Arend


Re: [PATCH v5] brcmfmac cleanup

2017-08-22 Thread Arend van Spriel

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. 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.


Regards,
Arend


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

2017-08-22 Thread Arend van Spriel

On 22-08-17 14:50, Julian Calaby wrote:

Hi Ian,

On Tue, Aug 22, 2017 at 9:25 PM, Ian Molton  wrote:

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.


Wouldn't it be more safe to write these sorts of functions so that
they set the window themselves instead of relying on the caller?


The function brcmf_sdiod_set_backplane_window() is a helper function by 
which these sorts of functions set the window themselves. It would be 
duplicating too much code as setting the window involves three register 
accesses (or so) on the device.


Regards,
Arend


[PATCH] rtlwifi: rtl8821ae: fix spelling mistake: "faill" -> "failed"

2017-08-22 Thread Colin King
From: Colin Ian King 

Trivial fix to spelling mistake in RT_TRACE message

Signed-off-by: Colin Ian King 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
index b84b4fa7b71c..f2b2c549e5b2 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
@@ -98,7 +98,7 @@ static int _rtl8821ae_fw_free_to_go(struct ieee80211_hw *hw)
 
if (counter >= FW_8821AE_POLLING_TIMEOUT_COUNT) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
-"chksum report faill ! REG_MCUFWDL:0x%08x .\n",
+"chksum report fail! REG_MCUFWDL:0x%08x .\n",
  value32);
goto exit;
}
-- 
2.14.1



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

2017-08-22 Thread Julian Calaby
Hi Ian,

On Tue, Aug 22, 2017 at 9:25 PM, Ian Molton  wrote:
> 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.

Wouldn't it be more safe to write these sorts of functions so that
they set the window themselves instead of relying on the caller?

> Signed-off-by: Ian Molton 
> ---
>  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
>



-- 
Julian Calaby

Email: julian.cal...@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/


[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 
Acked-by: Arend van Spriel 
---
 .../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",
- &sdiodev->func[1]->dev);
+ &sdiodev->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, 
&ret);
-   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 = &sdiodev->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, &sdiodev->func[1]->dev);
+   free_irq(pdata->oob_irq_nr, &sdiodev->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, &retval);
+   data = sdio_readl(sdiodev->func1, addr, &retval);
 
 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, &retval);
+   sdio_writel(sdiodev->func1, data, addr, &retval);
 
 out:
if (ret)
@@ -546,7 +546,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, 
struct sk_buff *pkt)
addr &= SBSDIO_SB_OFT_ADDR_MASK;
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-   err = brcmf_sdiod_buff_rea

[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 
---
 .../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, &ret);
 
/* redirect, configure and enable io for interrupt signal */
-   data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
+   data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE;
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
-   data |= SDIO_SEPINT_ACT_HI;
+   data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI;
brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
&ret);
sdio_release_host(sdiodev->func[1]);
} 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 
Reviewed-by: Arend van Spriel 

# 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 = &local_list;
}
 
-   func_blk_sz = sdiodev->func[fn]->cur_blksize;
+   func_blk_sz = func->cur_blksize;
max_req_sz = sdiodev->max_request_size;
max_

[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 
Acked-by: Arend van Spriel 
---
 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 
Reviewed-by: Arend van Spriel 
---
 .../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",
- &sdiodev->func1->dev);
+ &func1->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, 
&ret);
-   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 = &sdiodev->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, &sdiodev->func1->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->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->sd_irq_requested = false;
}
 }
@@ -252,6 +256,7 @@ brcmf_sdiod_set_backplane_window(struct brcmf_sdio_dev 
*sdiod

[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 
---
 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, &ret);
+   val = brcmf_sdiod_readl(bus->sdiodev, core->base + __sd_reg(intstatus),
+   &ret);
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, &ret);
+   brcmf_sdiod_writel(bus->sdiodev,
+  core->base + __sd_reg(intstatus), val, &ret);
bus->sdcnt.f1regdata++;
atomic_or(val, &bus->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 
---
 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 
---
 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 
---
 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 
Reviewed-by: Arend van Spriel 
---
 .../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, &ret);
+   gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret);
gpiocontrol |= 0x2;
-   brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret);
+   brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret);
 
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
- &ret);
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
-   brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT, 0xf, 
&ret);
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
}
 
/* must configure SDIO_CCCR_IENx to enable irq */
-   data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
+   data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret);
data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
-   brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);
 
/* redirect, configure and enable io for interrupt signal */
data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
data |= SDIO_SEPINT_ACT_HI;
-   brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
-
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, 
&ret);
sdio_release_host(sdiodev->func[1]);
} else {
brcmf_dbg(SDIO, "Entering\n");
@@ -183,8 +181,8 @@ void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev 
*sdiodev)
 
pdata = &sdiodev->settings->bus.sdio;
sdio_claim_host(sdiodev->func[1]);
-   brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
-   brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
+   brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
sdio_release_host(sdiodev->func[1]);
 
sdiodev->oob_irq_requested = false;
@@ -242,8 +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, &err);
+   brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i,
+  addr & 0xff, &err);
 
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, &err_ret);
-   else
-   sdio_f0_writeb(func, byte, regaddr, &err_ret);
-
-   return err_ret;
-}
-
-static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr,

[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 
---
 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, &ret);
-   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, &ret);
 
/* 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 
---
 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 
---
 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 

# 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(&func->dev, NULL);
dev_set_drvdata(&sdiodev->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(&sdiodev->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 
---
 .../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, &ret);
-
-   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, &ret);
-
-   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, &hmb_data, __sd_reg(tohostmailboxdata));
+   hmb_data = brcmf_sdiod_readl(sdiod, core->base +
+   __sd_reg(tohostmailboxdata), &ret);
+
+   if (!ret)
+   brcmf_sdiod_writel(sdiod, core->base + __sd_reg(tosbmailbox),
+  SMB_INT_ACK, &ret);
 
-   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, &err);
 
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, &intstatus, __sd_reg(intstatus));
+   intstatus = brcmf_sdiod_readl(bus->sdiodev, core->base +
+ __sd_reg(intstatus),
+ &ret);
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, false, false);
 
/* Disable and clear interrupts at the chip level also */
-   w_sdreg3

[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 
---
 .../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, &hmb_data,
-   offsetof(struct sdpcmd_regs, tohostmailboxdata));
+   ret = r_sdreg32(bus, &hmb_data, __sd_reg(tohostmailboxdata));
 
if (ret == 0)
-   w_sdreg32(bus, SMB_INT_ACK,
- offsetof(struct sdpcmd_regs, tosbmailbox));
+   w_sdreg32(bus, SMB_INT_ACK, __sd_reg(tosbmailbox));
bus->sdcnt.f1regdata += 2;
 
/* Dongle 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, &intstatus,
-   offsetof(struct sdpcmd_regs,
-intstatus));
+   ret = r_sdreg32(bus, &intstatus, __sd_reg(intstatus));
sdio_release_host(bus->sdiodev->func[1]);
bus->sdcnt.f2txdata++;
if (ret != 0)
@@ -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, &ret);
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, &newstatus,
-   offsetof(struct sdpcmd_regs, intstatus));
+   err = r_sdreg32(bus, &newstatus, __sd_reg(intstatus));
bus->sdcnt.f1regdata += 2;
atomic_set(&bus->fcstate,
   !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
@@ -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 + offsetof(struct sdpcmd_regs, intstatus);
+   reg_addr = core->base + __sd_re

[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 
---
 .../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, &ret);
 
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, &ret);
 
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, &ret);
@@ -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, &err);
@@ -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", &value,
@@ -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 
Reviewed-by: Arend van Spriel 
---
 .../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, &addr);
 
if (!err)
-   err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr,
-mypkt);
+   err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt);
 
brcmu_pkt_buf_free_skb(mypkt);
return err;
@@ -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,16 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool 
write, u32 address,
sdaddr |= SBSDIO_SB_ACCESS_2_4B_

[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 
---
 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 
---
 .../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, &err);
-
-   return err;
-}
-
-static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
-{
-   uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
-   int err = 0;
-
-   if (bar0 != sdiodev->sbwad) {
-   err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
-   if (err)
-   return err;
+  v & 0xff, &err);
 
+   if (!err)
sdiodev->sbwad = bar0;
-   }
-
-   *addr &= SBSDIO_SB_OFT_ADDR_MASK;
-   *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-   return 0;
+   return err;
 }
 
 u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
@@ -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, &addr);
+   retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+   if (retval)
+   goto out;
+
+   addr &= SBSDIO_SB_OFT_ADDR_MASK;
+   addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-   if (!retval)
-   data = sdio_readl(sdiodev->func[1], addr, &retval);
+   data = sdio_readl(sdiodev->func[1], addr, &retval);
 
+out:
if (ret)
*ret = retval;
 
@@ -286,11 +275,16 @@ void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, 
u32 addr,
 {
int retval;
 
-   retval = brcmf_sdiod_addrprep(sdiodev, &addr);
+   retval = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+   if (retval)
+   goto out;
+
+   addr &= SBSDIO_SB_OFT_ADDR_MASK;
+   addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-   if (!retval)
-   sdio_writel(sdiodev->func[1], data, addr, &retval);
+   sdio_writel(sdiodev->func[1], data, addr, &retval);
 
+out:
if (ret)
*ret = retval;
 }
@@ -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, &addr);
+   err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
if (err)
goto done;
 
+   addr &= SBSDIO_SB_OFT_ADDR_MASK;
+   addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt);
 
 done:
@@ -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, &addr);
+   err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
if (err)
goto done;
 
+   addr &= SBSDIO_SB_OFT_ADDR_MASK;
+   addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
if (pktq->qlen == 1)
err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr,
pktq->next);
@@ -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, &addr);
+   err = brcmf_sdiod_set_backplane_window(sdiodev, addr);
+   if (err)
+   return err;
+
+   addr &= SBSDIO_SB_OFT_ADDR_MASK;
+   addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
if (!err)
 

[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 
---
 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 = &func->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 
Reviewed-by: Arend van Spriel 
---
 .../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],
- &err);
-   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, &err);
 
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 
Reviewed-by: Arend van Spriel 
---
 .../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 
Reviewed-by: Arend van Spriel 
---
 .../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, &err);
+
+   return err;
+}
+
+static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr)
+{
+   uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+   int err = 0;
+
+   if (bar0 != sdiodev->sbwad) {
+   err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0);
+   if (err)
+   return err;
+
+   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, &ret);
-   else
-   ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data,
-   addr);
-   } else {
-   if (fn)
-   *(u8 *)data = sdio_readb(func, addr, &ret);
-   else
-   *(u8 *)data = sdio_f0_readb(func, addr, &ret);
-   }
-   break;
-   case 2:
-   if (write)
-   sdio_writew(func, *(u16 *)data, addr, &ret);
-   else
-   *(u16 *)data = sdio_readw(func, addr, &ret);
-   break;
-   case 4:
-   if (write)
-   sdio_writel(func, *(u32 *)data, addr, &ret);
-   else
-   *(u32 *)data = sdio_readl(func, addr, &ret);
-   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 */
-   if (retry)
-   usleep_range(1000, 2000);
-
-   ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
- 

[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 
---
 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, &data);
-   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, &data);
-   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, &data);
 
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, &data);
 
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 
Reviewed-by: Arend van Spriel 
---
 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 
Reviewed-by: Arend van Spriel 
---
 .../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, &addr);
+   retval = brcmf_sdiod_addrprep(sdiodev, &addr);
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, &addr);
+   retval = brcmf_sdiod_addrprep(sdiodev, &addr);
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, &addr);
+   err = brcmf_sdiod_addrprep(sdiodev, &addr);
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, &addr);
+   err = brcmf_sdiod_addrprep(sdiodev, &addr);
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, &addr);
+   err = brcmf_sdiod_addrprep(sdiodev, &addr);
 
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, &addr);
+   err = brcmf_sdiod_addrprep(sdiodev, &addr);
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 
Reviewed-by: Arend van Spriel 
---
 .../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,
-  SBSDIO_FUNC1_SBADDRLOW + i,
-  1, &addr[i], true);
+   brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC

[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 
---
 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, &ret);
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, &ret);
-- 
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 
Reviewed-by: Arend van Spriel 
---
 .../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, &ret);
@@ -278,13 +278,13 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev 
*sdiodev, u8 fn,
*(u8 *)data = sdio_f0_readb(func, addr, &ret);
}
break;
-   case sizeof(u16):
+   case 2:
if (write)
sdio_writew(func, *(u16 *)data, addr, &ret);
else
*(u16 *)data = sdio_readw(func, addr, &ret);
break;
-   case sizeof(u32):
+   case 4:
if (write)
sdio_writel(func, *(u32 *)data, addr, &ret);
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), &addr[i], true);
+  1, &addr[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), &data,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data,
  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), &addr);
+   retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
if (retval)
goto done;
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data,
  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), &data,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data,
  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), &addr);
+   retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr);
if (retval)
goto done;
-   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data,
+   retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data,
  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), &t_func, true);
+1, &t_func, true);
 
brcmf_dbg(SDIO, "Exit\n");
return 0;
-- 
2.11.0



Re: [PATCH] drivers: net: wireless: atmel: check memory allocation failure

2017-08-22 Thread Himanshu Jha
On Tue, Aug 22, 2017 at 10:41:45AM +0200, Matteo Croce wrote:
> Il giorno mar, 22/08/2017 alle 13.41 +0530, Himanshu Jha ha scritto:
> > Check memory allocation failure and return -ENOMEM if failure
> > occurs.
> > 
> > Signed-off-by: Himanshu Jha 
> > ---
> >  drivers/net/wireless/atmel/at76c50x-usb.c | 14 +++---
> >  1 file changed, 7 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c
> > b/drivers/net/wireless/atmel/at76c50x-usb.c
> > index 09defbc..73f0924 100644
> > --- a/drivers/net/wireless/atmel/at76c50x-usb.c
> > +++ b/drivers/net/wireless/atmel/at76c50x-usb.c
> > @@ -940,7 +940,7 @@ static void at76_dump_mib_mac_addr(struct
> > at76_priv *priv)
> >  GFP_KERNEL);
> >  
> > if (!m)
> > -   return;
> > +   return -ENOMEM;
> >  
> > ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
> >sizeof(struct mib_mac_addr));
> > @@ -969,7 +969,7 @@ static void at76_dump_mib_mac_wep(struct
> > at76_priv *priv)
> > struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep),
> > GFP_KERNEL);
> >  
> > if (!m)
> > -   return;
> > +   return -ENOMEM;
> >  
> > ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
> >sizeof(struct mib_mac_wep));
> > @@ -1006,7 +1006,7 @@ static void at76_dump_mib_mac_mgmt(struct
> > at76_priv *priv)
> >  GFP_KERNEL);
> >  
> > if (!m)
> > -   return;
> > +   return -ENOMEM;
> >  
> > ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
> >sizeof(struct mib_mac_mgmt));
> > @@ -1043,7 +1043,7 @@ static void at76_dump_mib_mac(struct at76_priv
> > *priv)
> > struct mib_mac *m = kmalloc(sizeof(struct mib_mac),
> > GFP_KERNEL);
> >  
> > if (!m)
> > -   return;
> > +   return -ENOMEM;
> >  
> > ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct
> > mib_mac));
> > if (ret < 0) {
> > @@ -1080,7 +1080,7 @@ static void at76_dump_mib_phy(struct at76_priv
> > *priv)
> > struct mib_phy *m = kmalloc(sizeof(struct mib_phy),
> > GFP_KERNEL);
> >  
> > if (!m)
> > -   return;
> > +   return -ENOMEM;
> >  
> > ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct
> > mib_phy));
> > if (ret < 0) {
> > @@ -1113,7 +1113,7 @@ static void at76_dump_mib_local(struct
> > at76_priv *priv)
> > struct mib_local *m = kmalloc(sizeof(*m), GFP_KERNEL);
> >  
> > if (!m)
> > -   return;
> > +   return -ENOMEM;
> >  
> > ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(*m));
> > if (ret < 0) {
> > @@ -1138,7 +1138,7 @@ static void at76_dump_mib_mdomain(struct
> > at76_priv *priv)
> > struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain),
> > GFP_KERNEL);
> >  
> > if (!m)
> > -   return;
> > +   return -ENOMEM;
> >  
> > ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
> >sizeof(struct mib_mdomain));
> 
> Perhaps these functions should return something instead of being void.
> 
> Regards,
> 
> -- 
> Matteo Croce
> per aspera ad upstream

Yes, it should return int to signal memory allocation failures and
therefore function prototype should be static int rather than static
void.

Thanks!


[PATCH v3] brcmfmac: add CLM download support

2017-08-22 Thread Wright Feng
From: Chung-Hsien Hsu 

The firmware for brcmfmac devices includes information regarding
regulatory constraints. For certain devices this information is kept
separately in a binary form that needs to be downloaded to the device.
This patch adds support to download this so-called CLM blob file. It
uses the same naming scheme as the other firmware files with extension
of .clm_blob.

The CLM blob file is optional. If the file does not exist, the download
process will be bypassed. It will not affect the driver loading.

Signed-off-by: Chung-Hsien Hsu 
---
v2: Revise commit message to describe in more detail
v3: Add error handling in brcmf_c_get_clm_name function
---
 .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  10 ++
 .../wireless/broadcom/brcm80211/brcmfmac/common.c  | 161 +
 .../wireless/broadcom/brcm80211/brcmfmac/core.c|   2 +
 .../wireless/broadcom/brcm80211/brcmfmac/core.h|   2 +
 .../broadcom/brcm80211/brcmfmac/fwil_types.h   |  31 
 .../wireless/broadcom/brcm80211/brcmfmac/pcie.c|  19 +++
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c|  19 +++
 .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  18 +++
 8 files changed, 262 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index b55c329..df42e09 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -71,6 +71,7 @@ struct brcmf_bus_dcmd {
  * @wowl_config: specify if dongle is configured for wowl when going to suspend
  * @get_ramsize: obtain size of device memory.
  * @get_memdump: obtain device memory dump in provided buffer.
+ * @get_fwname: obtain firmware name.
  *
  * This structure provides an abstract interface towards the
  * bus specific driver. For control messages to common driver
@@ -87,6 +88,8 @@ struct brcmf_bus_ops {
void (*wowl_config)(struct device *dev, bool enabled);
size_t (*get_ramsize)(struct device *dev);
int (*get_memdump)(struct device *dev, void *data, size_t len);
+   int (*get_fwname)(struct device *dev, uint chip, uint chiprev,
+ unsigned char *fw_name);
 };
 
 
@@ -214,6 +217,13 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void 
*data, size_t len)
return bus->ops->get_memdump(bus->dev, data, len);
 }
 
+static inline
+int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev,
+unsigned char *fw_name)
+{
+   return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name);
+}
+
 /*
  * interface functions from common layer
  */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 7a2b495..f5f00fa 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "core.h"
@@ -28,6 +29,7 @@
 #include "tracepoint.h"
 #include "common.h"
 #include "of.h"
+#include "firmware.h"
 
 MODULE_AUTHOR("Broadcom Corporation");
 MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -104,12 +106,139 @@ void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
brcmf_err("Set join_pref error (%d)\n", err);
 }
 
+static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
+   struct brcmf_dload_data_le *dload_buf,
+   u32 len)
+{
+   u16 flags;
+   s32 err;
+
+   flags = flag | (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
+   dload_buf->flag = cpu_to_le16(flags);
+   dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM);
+   dload_buf->len = cpu_to_le32(len);
+   dload_buf->crc = cpu_to_le32(0);
+   len = len + 8 - (len % 8);
+
+   err = brcmf_fil_iovar_data_set(ifp, "clmload", (void *)dload_buf, len);
+
+   return err;
+}
+
+static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name)
+{
+   struct brcmf_bus *bus = ifp->drvr->bus_if;
+   struct brcmf_rev_info *ri = &ifp->drvr->revinfo;
+   u8 fw_name[BRCMF_FW_NAME_LEN];
+   u8 *ptr;
+   size_t len;
+   s32 err;
+
+   memset(fw_name, 0, BRCMF_FW_NAME_LEN);
+   err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name);
+   if (err) {
+   brcmf_err("get firmware name failed (%d)\n", err);
+   goto done;
+   }
+
+   /* generate CLM blob file name */
+   ptr = strrchr(fw_name, '.');
+   if (!ptr) {
+   err = -ENOENT;
+   goto done;
+   }
+
+   len = ptr - fw_name + 1;
+   if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) {
+   err = -E2BIG;
+   } else {
+   strlcpy(clm_name, fw_name, len);
+   strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN);
+  

Re: [PATCH] drivers: net: wireless: atmel: check memory allocation failure

2017-08-22 Thread Matteo Croce
Il giorno mar, 22/08/2017 alle 13.41 +0530, Himanshu Jha ha scritto:
> Check memory allocation failure and return -ENOMEM if failure
> occurs.
> 
> Signed-off-by: Himanshu Jha 
> ---
>  drivers/net/wireless/atmel/at76c50x-usb.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c
> b/drivers/net/wireless/atmel/at76c50x-usb.c
> index 09defbc..73f0924 100644
> --- a/drivers/net/wireless/atmel/at76c50x-usb.c
> +++ b/drivers/net/wireless/atmel/at76c50x-usb.c
> @@ -940,7 +940,7 @@ static void at76_dump_mib_mac_addr(struct
> at76_priv *priv)
>GFP_KERNEL);
>  
>   if (!m)
> - return;
> + return -ENOMEM;
>  
>   ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
>  sizeof(struct mib_mac_addr));
> @@ -969,7 +969,7 @@ static void at76_dump_mib_mac_wep(struct
> at76_priv *priv)
>   struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep),
> GFP_KERNEL);
>  
>   if (!m)
> - return;
> + return -ENOMEM;
>  
>   ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
>  sizeof(struct mib_mac_wep));
> @@ -1006,7 +1006,7 @@ static void at76_dump_mib_mac_mgmt(struct
> at76_priv *priv)
>GFP_KERNEL);
>  
>   if (!m)
> - return;
> + return -ENOMEM;
>  
>   ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
>  sizeof(struct mib_mac_mgmt));
> @@ -1043,7 +1043,7 @@ static void at76_dump_mib_mac(struct at76_priv
> *priv)
>   struct mib_mac *m = kmalloc(sizeof(struct mib_mac),
> GFP_KERNEL);
>  
>   if (!m)
> - return;
> + return -ENOMEM;
>  
>   ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct
> mib_mac));
>   if (ret < 0) {
> @@ -1080,7 +1080,7 @@ static void at76_dump_mib_phy(struct at76_priv
> *priv)
>   struct mib_phy *m = kmalloc(sizeof(struct mib_phy),
> GFP_KERNEL);
>  
>   if (!m)
> - return;
> + return -ENOMEM;
>  
>   ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct
> mib_phy));
>   if (ret < 0) {
> @@ -1113,7 +1113,7 @@ static void at76_dump_mib_local(struct
> at76_priv *priv)
>   struct mib_local *m = kmalloc(sizeof(*m), GFP_KERNEL);
>  
>   if (!m)
> - return;
> + return -ENOMEM;
>  
>   ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(*m));
>   if (ret < 0) {
> @@ -1138,7 +1138,7 @@ static void at76_dump_mib_mdomain(struct
> at76_priv *priv)
>   struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain),
> GFP_KERNEL);
>  
>   if (!m)
> - return;
> + return -ENOMEM;
>  
>   ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
>  sizeof(struct mib_mdomain));

Perhaps these functions should return something instead of being void.

Regards,

-- 
Matteo Croce
per aspera ad upstream


[PATCH] drivers: net: wireless: atmel: check memory allocation failure

2017-08-22 Thread Himanshu Jha
Check memory allocation failure and return -ENOMEM if failure
occurs.

Signed-off-by: Himanshu Jha 
---
 drivers/net/wireless/atmel/at76c50x-usb.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c 
b/drivers/net/wireless/atmel/at76c50x-usb.c
index 09defbc..73f0924 100644
--- a/drivers/net/wireless/atmel/at76c50x-usb.c
+++ b/drivers/net/wireless/atmel/at76c50x-usb.c
@@ -940,7 +940,7 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv)
 GFP_KERNEL);
 
if (!m)
-   return;
+   return -ENOMEM;
 
ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
   sizeof(struct mib_mac_addr));
@@ -969,7 +969,7 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
 
if (!m)
-   return;
+   return -ENOMEM;
 
ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
   sizeof(struct mib_mac_wep));
@@ -1006,7 +1006,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
 GFP_KERNEL);
 
if (!m)
-   return;
+   return -ENOMEM;
 
ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
   sizeof(struct mib_mac_mgmt));
@@ -1043,7 +1043,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
 
if (!m)
-   return;
+   return -ENOMEM;
 
ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
if (ret < 0) {
@@ -1080,7 +1080,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
 
if (!m)
-   return;
+   return -ENOMEM;
 
ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
if (ret < 0) {
@@ -1113,7 +1113,7 @@ static void at76_dump_mib_local(struct at76_priv *priv)
struct mib_local *m = kmalloc(sizeof(*m), GFP_KERNEL);
 
if (!m)
-   return;
+   return -ENOMEM;
 
ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(*m));
if (ret < 0) {
@@ -1138,7 +1138,7 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
 
if (!m)
-   return;
+   return -ENOMEM;
 
ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
   sizeof(struct mib_mdomain));
-- 
2.7.4



[PATCH v2] iwlwifi: pcie: move rx workqueue initialization to iwl_trans_pcie_alloc()

2017-08-22 Thread Luca Coelho
From: Luca Coelho 

Work queues cannot be allocated when a mutex is held because the mutex
may be in use and that would make it sleep.  Doing so generates the
following splat with 4.13+:

[   19.513298] ==
[   19.513429] WARNING: possible circular locking dependency detected
[   19.513557] 4.13.0-rc5+ #6 Not tainted
[   19.513638] --
[   19.513767] cpuhp/0/12 is trying to acquire lock:
[   19.513867]  (&tz->lock){+.+.+.}, at: [] 
thermal_zone_get_temp+0x5b/0xb0
[   19.514047]
[   19.514047] but task is already holding lock:
[   19.514166]  (cpuhp_state){+.+.+.}, at: [] 
cpuhp_thread_fun+0x3a/0x210
[   19.514338]
[   19.514338] which lock already depends on the new lock.

This lock dependency already existed with previous kernel versions,
but it was not detected until commit 49dfe2a67797 ("cpuhotplug: Link
lock stacks for hotplug callbacks") was introduced.

Reported-by: David Weinehall 
Reported-by: Jiri Kosina 
Signed-off-by: Luca Coelho 
---
In v2:
   - updated the commit message to a new version, with a grammar fix
 and the actual commit that exposed the problem;

 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  2 ++
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   | 10 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c|  9 +
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index fa315d84e98e..a1ea9ef97ed9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -787,6 +787,8 @@ int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans);
 
 void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool enable);
 
+void iwl_pcie_rx_allocator_work(struct work_struct *data);
+
 /* common functions that are used by gen2 transport */
 void iwl_pcie_apm_config(struct iwl_trans *trans);
 int iwl_pcie_prepare_card_hw(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 351c4423125a..942736d3fa75 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -597,7 +597,7 @@ static void iwl_pcie_rx_allocator_get(struct iwl_trans 
*trans,
rxq->free_count += RX_CLAIM_REQ_ALLOC;
 }
 
-static void iwl_pcie_rx_allocator_work(struct work_struct *data)
+void iwl_pcie_rx_allocator_work(struct work_struct *data)
 {
struct iwl_rb_allocator *rba_p =
container_of(data, struct iwl_rb_allocator, rx_alloc);
@@ -900,10 +900,6 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
return err;
}
def_rxq = trans_pcie->rxq;
-   if (!rba->alloc_wq)
-   rba->alloc_wq = alloc_workqueue("rb_allocator",
-   WQ_HIGHPRI | WQ_UNBOUND, 1);
-   INIT_WORK(&rba->rx_alloc, iwl_pcie_rx_allocator_work);
 
spin_lock(&rba->lock);
atomic_set(&rba->req_pending, 0);
@@ -1017,10 +1013,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
}
 
cancel_work_sync(&rba->rx_alloc);
-   if (rba->alloc_wq) {
-   destroy_workqueue(rba->alloc_wq);
-   rba->alloc_wq = NULL;
-   }
 
iwl_pcie_free_rbs_pool(trans);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f95eec52508e..3927bbf04f72 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1786,6 +1786,11 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
iwl_pcie_tx_free(trans);
iwl_pcie_rx_free(trans);
 
+   if (trans_pcie->rba.alloc_wq) {
+   destroy_workqueue(trans_pcie->rba.alloc_wq);
+   trans_pcie->rba.alloc_wq = NULL;
+   }
+
if (trans_pcie->msix_enabled) {
for (i = 0; i < trans_pcie->alloc_vecs; i++) {
irq_set_affinity_hint(
@@ -3169,6 +3174,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev 
*pdev,
trans_pcie->inta_mask = CSR_INI_SET_MASK;
 }
 
+   trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator",
+  WQ_HIGHPRI | WQ_UNBOUND, 1);
+   INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work);
+
 #ifdef CONFIG_IWLWIFI_PCIE_RTPM
trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3;
 #else
-- 
2.14.1



[PATCH] iwlwifi: pcie: move rx workqueue initialization to iwl_trans_pcie_alloc()

2017-08-22 Thread Luca Coelho
From: Luca Coelho 

Work queues cannot be allocated in when a mutex is held because the
mutex may be in use and that would make it sleep.  Doing so generates
the following splat with 4.13+:

[   19.513298] ==
[   19.513429] WARNING: possible circular locking dependency detected
[   19.513557] 4.13.0-rc5+ #6 Not tainted
[   19.513638] --
[   19.513767] cpuhp/0/12 is trying to acquire lock:
[   19.513867]  (&tz->lock){+.+.+.}, at: [] 
thermal_zone_get_temp+0x5b/0xb0
[   19.514047]
[   19.514047] but task is already holding lock:
[   19.514166]  (cpuhp_state){+.+.+.}, at: [] 
cpuhp_thread_fun+0x3a/0x210
[   19.514338]
[   19.514338] which lock already depends on the new lock.

This lock dependency already existed with previous kernel versions,
but it was not detected until commit ... was introduced.

Reported-by: David Weinehall 
Reported-by: Jiri Kosina 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  2 ++
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   | 10 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c|  9 +
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index fa315d84e98e..a1ea9ef97ed9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -787,6 +787,8 @@ int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans);
 
 void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool enable);
 
+void iwl_pcie_rx_allocator_work(struct work_struct *data);
+
 /* common functions that are used by gen2 transport */
 void iwl_pcie_apm_config(struct iwl_trans *trans);
 int iwl_pcie_prepare_card_hw(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 351c4423125a..942736d3fa75 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -597,7 +597,7 @@ static void iwl_pcie_rx_allocator_get(struct iwl_trans 
*trans,
rxq->free_count += RX_CLAIM_REQ_ALLOC;
 }
 
-static void iwl_pcie_rx_allocator_work(struct work_struct *data)
+void iwl_pcie_rx_allocator_work(struct work_struct *data)
 {
struct iwl_rb_allocator *rba_p =
container_of(data, struct iwl_rb_allocator, rx_alloc);
@@ -900,10 +900,6 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
return err;
}
def_rxq = trans_pcie->rxq;
-   if (!rba->alloc_wq)
-   rba->alloc_wq = alloc_workqueue("rb_allocator",
-   WQ_HIGHPRI | WQ_UNBOUND, 1);
-   INIT_WORK(&rba->rx_alloc, iwl_pcie_rx_allocator_work);
 
spin_lock(&rba->lock);
atomic_set(&rba->req_pending, 0);
@@ -1017,10 +1013,6 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
}
 
cancel_work_sync(&rba->rx_alloc);
-   if (rba->alloc_wq) {
-   destroy_workqueue(rba->alloc_wq);
-   rba->alloc_wq = NULL;
-   }
 
iwl_pcie_free_rbs_pool(trans);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f95eec52508e..3927bbf04f72 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1786,6 +1786,11 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
iwl_pcie_tx_free(trans);
iwl_pcie_rx_free(trans);
 
+   if (trans_pcie->rba.alloc_wq) {
+   destroy_workqueue(trans_pcie->rba.alloc_wq);
+   trans_pcie->rba.alloc_wq = NULL;
+   }
+
if (trans_pcie->msix_enabled) {
for (i = 0; i < trans_pcie->alloc_vecs; i++) {
irq_set_affinity_hint(
@@ -3169,6 +3174,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev 
*pdev,
trans_pcie->inta_mask = CSR_INI_SET_MASK;
 }
 
+   trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator",
+  WQ_HIGHPRI | WQ_UNBOUND, 1);
+   INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work);
+
 #ifdef CONFIG_IWLWIFI_PCIE_RTPM
trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3;
 #else
-- 
2.14.1



Re: ath9k driver - is it possible to disable tx/rx radio chains?

2017-08-22 Thread Matthias May
On 18/08/17 23:04, Håvard Rabbe wrote:
> Hi
> Thank you so much. You made my day!
> The command works. Im looking forward to test it out :-)
> 
> 
> I also have two of these card. they don’t have the same bitmap, but I assume 
> they work the same way?
> 
> qca9882 chipset with 2 chains available using ath10k driver:
>   Available Antennas: TX 0x3 RX 0x3
>   Configured Antennas: TX 0x3 RX 0x3
> 
> qca9880 chipset with 3 chains available using ath10k driver:
>   Available Antennas: TX 0x3 RX 0x3
>   Configured Antennas: TX 0x3 RX 0x3
> 
> 

The bitmap is always the same.
0x1 for chain 0
0x3 for chain 0 and 1
0x7 for chain 0, 1 and 2
0xf for chain 0, 1, 2 and 3

Are you sure that your qca9880 card has 3 chains?
Because the "Available Antennas: TX 0x3 RX 0x3" says there are only 2 chains 
available.
It could be that the card physically has 3 chains, but the 3rd is disabled in 
eeprom.

BR
Matthias