[PATCH v5 1/5] soc: qcom: smem_state: Fix include for ERR_PTR()

2016-11-14 Thread Bjorn Andersson
The correct include file for getting errno constants and ERR_PTR() is
linux/err.h, rather than linux/errno.h, so fix the include.

Fixes: e8b123e60084 ("soc: qcom: smem_state: Add stubs for disabled smem_state")
Acked-by: Andy Gross 
Signed-off-by: Bjorn Andersson 
---

Kalle, please merge this patch through your tree.

Changes since v4:
- New patch

 include/linux/soc/qcom/smem_state.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/soc/qcom/smem_state.h 
b/include/linux/soc/qcom/smem_state.h
index 7b88697929e9..b8478ee7a71f 100644
--- a/include/linux/soc/qcom/smem_state.h
+++ b/include/linux/soc/qcom/smem_state.h
@@ -1,7 +1,7 @@
 #ifndef __QCOM_SMEM_STATE__
 #define __QCOM_SMEM_STATE__
 
-#include 
+#include 
 
 struct device_node;
 struct qcom_smem_state;
-- 
2.5.0



[PATCH v5 2/5] wcn36xx: Transition driver to SMD client

2016-11-14 Thread Bjorn Andersson
The wcn36xx wifi driver follows the life cycle of the WLAN_CTRL SMD
channel, as such it should be a SMD client. This patch makes this
transition, now that we have the necessary frameworks available.

Signed-off-by: Bjorn Andersson 
---

Changes since v4:
- Added Kconfig dependency to handle dependencies compiled as modules

 drivers/net/wireless/ath/wcn36xx/Kconfig   |  2 +
 drivers/net/wireless/ath/wcn36xx/dxe.c | 16 +++---
 drivers/net/wireless/ath/wcn36xx/main.c| 79 --
 drivers/net/wireless/ath/wcn36xx/smd.c | 31 +---
 drivers/net/wireless/ath/wcn36xx/smd.h |  5 ++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 21 +++-
 6 files changed, 88 insertions(+), 66 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/Kconfig 
b/drivers/net/wireless/ath/wcn36xx/Kconfig
index 591ebaea8265..4b83e87f0b94 100644
--- a/drivers/net/wireless/ath/wcn36xx/Kconfig
+++ b/drivers/net/wireless/ath/wcn36xx/Kconfig
@@ -1,6 +1,8 @@
 config WCN36XX
tristate "Qualcomm Atheros WCN3660/3680 support"
depends on MAC80211 && HAS_DMA
+   depends on QCOM_WCNSS_CTRL || QCOM_WCNSS_CTRL=n
+   depends on QCOM_SMD || QCOM_SMD=n
---help---
  This module adds support for wireless adapters based on
  Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 231fd022f0f5..87dfdaf9044c 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -23,6 +23,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
+#include 
 #include "wcn36xx.h"
 #include "txrx.h"
 
@@ -151,9 +152,12 @@ int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
goto out_err;
 
/* Initialize SMSM state  Clear TX Enable RING EMPTY STATE */
-   ret = wcn->ctrl_ops->smsm_change_state(
-   WCN36XX_SMSM_WLAN_TX_ENABLE,
-   WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
+   ret = qcom_smem_state_update_bits(wcn->tx_enable_state,
+ WCN36XX_SMSM_WLAN_TX_ENABLE |
+ WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY,
+ WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
+   if (ret)
+   goto out_err;
 
return 0;
 
@@ -678,9 +682,9 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
 * notify chip about new frame through SMSM bus.
 */
if (is_low &&  vif_priv->pw_state == WCN36XX_BMPS) {
-   wcn->ctrl_ops->smsm_change_state(
- 0,
- WCN36XX_SMSM_WLAN_TX_ENABLE);
+   qcom_smem_state_update_bits(wcn->tx_rings_empty_state,
+   WCN36XX_SMSM_WLAN_TX_ENABLE,
+   WCN36XX_SMSM_WLAN_TX_ENABLE);
} else {
/* indicate End Of Packet and generate interrupt on descriptor
 * done.
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index e1d59da2ad20..3c2522b07c90 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -21,6 +21,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 #include "wcn36xx.h"
 
 unsigned int wcn36xx_dbg_mask;
@@ -1058,8 +1062,7 @@ static int wcn36xx_platform_get_resources(struct wcn36xx 
*wcn,
int ret;
 
/* Set TX IRQ */
-   res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-  "wcnss_wlantx_irq");
+   res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tx");
if (!res) {
wcn36xx_err("failed to get tx_irq\n");
return -ENOENT;
@@ -1067,14 +1070,29 @@ static int wcn36xx_platform_get_resources(struct 
wcn36xx *wcn,
wcn->tx_irq = res->start;
 
/* Set RX IRQ */
-   res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-  "wcnss_wlanrx_irq");
+   res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "rx");
if (!res) {
wcn36xx_err("failed to get rx_irq\n");
return -ENOENT;
}
wcn->rx_irq = res->start;
 
+   /* Acquire SMSM tx enable handle */
+   wcn->tx_enable_state = qcom_smem_state_get(>dev,
+   "tx-enable", >tx_enable_state_bit);
+   if (IS_ERR(wcn->tx_enable_state)) {
+   wcn36xx_err("failed to get tx-enable state\n");
+   return PTR_ERR(wcn->tx_enable_state);
+   }
+
+   /* Acquire SMSM tx rings empty handle */
+   wcn->tx_rings_empty_state = qcom_smem_state_get(>dev,
+   "tx-rings-empty", >tx_rings_empty_state_bit);
+   if (IS_ERR(wcn->tx_rings_empty_state)) {
+   

[PATCH v5 4/5] wcn36xx: Implement print_reg indication

2016-11-14 Thread Bjorn Andersson
Some firmware versions sends a "print register indication", handle this
by printing out the content.

Cc: Nicolas Dechesne 
Signed-off-by: Bjorn Andersson 
---

Changes since v4:
- None

 drivers/net/wireless/ath/wcn36xx/hal.h | 16 
 drivers/net/wireless/ath/wcn36xx/smd.c | 30 ++
 2 files changed, 46 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h 
b/drivers/net/wireless/ath/wcn36xx/hal.h
index 4f87ef1e1eb8..b765c647319d 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -350,6 +350,8 @@ enum wcn36xx_hal_host_msg_type {
 
WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233,
 
+   WCN36XX_HAL_PRINT_REG_INFO_IND = 259,
+
WCN36XX_HAL_MSG_MAX = WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE
 };
 
@@ -4703,4 +4705,18 @@ struct stats_class_b_ind {
u32 rx_time_total;
 };
 
+/* WCN36XX_HAL_PRINT_REG_INFO_IND */
+struct wcn36xx_hal_print_reg_info_ind {
+   struct wcn36xx_hal_msg_header header;
+
+   u32 count;
+   u32 scenario;
+   u32 reason;
+
+   struct {
+   u32 addr;
+   u32 value;
+   } regs[];
+} __packed;
+
 #endif /* _HAL_H_ */
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index be5e5ea1e5c3..1c2966f7db7a 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2109,6 +2109,30 @@ static int wcn36xx_smd_delete_sta_context_ind(struct 
wcn36xx *wcn,
return -ENOENT;
 }
 
+static int wcn36xx_smd_print_reg_info_ind(struct wcn36xx *wcn,
+ void *buf,
+ size_t len)
+{
+   struct wcn36xx_hal_print_reg_info_ind *rsp = buf;
+   int i;
+
+   if (len < sizeof(*rsp)) {
+   wcn36xx_warn("Corrupted print reg info indication\n");
+   return -EIO;
+   }
+
+   wcn36xx_dbg(WCN36XX_DBG_HAL,
+   "reginfo indication, scenario: 0x%x reason: 0x%x\n",
+   rsp->scenario, rsp->reason);
+
+   for (i = 0; i < rsp->count; i++) {
+   wcn36xx_dbg(WCN36XX_DBG_HAL, "\t0x%x: 0x%x\n",
+   rsp->regs[i].addr, rsp->regs[i].value);
+   }
+
+   return 0;
+}
+
 int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value)
 {
struct wcn36xx_hal_update_cfg_req_msg msg_body, *body;
@@ -2237,6 +2261,7 @@ int wcn36xx_smd_rsp_process(struct qcom_smd_channel 
*channel,
case WCN36XX_HAL_OTA_TX_COMPL_IND:
case WCN36XX_HAL_MISSED_BEACON_IND:
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
+   case WCN36XX_HAL_PRINT_REG_INFO_IND:
msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_ATOMIC);
if (!msg_ind) {
wcn36xx_err("Run out of memory while handling SMD_EVENT 
(%d)\n",
@@ -2296,6 +2321,11 @@ static void wcn36xx_ind_smd_work(struct work_struct 
*work)
   hal_ind_msg->msg,
   hal_ind_msg->msg_len);
break;
+   case WCN36XX_HAL_PRINT_REG_INFO_IND:
+   wcn36xx_smd_print_reg_info_ind(wcn,
+  hal_ind_msg->msg,
+  hal_ind_msg->msg_len);
+   break;
default:
wcn36xx_err("SMD_EVENT (%d) not supported\n",
  msg_header->msg_type);
-- 
2.5.0



[PATCH v5 3/5] wcn36xx: Implement firmware assisted scan

2016-11-14 Thread Bjorn Andersson
Using the software based channel scan mechanism from mac80211 keeps us
offline for 10-15 second, we should instead issue a start_scan/end_scan
on each channel reducing this time.

Signed-off-by: Bjorn Andersson 
---

Changes since v4:
- None

 drivers/net/wireless/ath/wcn36xx/main.c| 64 +-
 drivers/net/wireless/ath/wcn36xx/smd.c |  8 ++--
 drivers/net/wireless/ath/wcn36xx/smd.h |  4 +-
 drivers/net/wireless/ath/wcn36xx/txrx.c| 19 ++---
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  9 +
 5 files changed, 81 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index 3c2522b07c90..96a9584edcbb 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -568,23 +568,59 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum 
set_key_cmd cmd,
return ret;
 }
 
-static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- const u8 *mac_addr)
+static void wcn36xx_hw_scan_worker(struct work_struct *work)
 {
-   struct wcn36xx *wcn = hw->priv;
+   struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
+   struct cfg80211_scan_request *req = wcn->scan_req;
+   u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
+   struct cfg80211_scan_info scan_info = {};
+   int i;
+
+   wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", 
req->n_channels);
+
+   for (i = 0; i < req->n_channels; i++)
+   channels[i] = req->channels[i]->hw_value;
+
+   wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
 
wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
-   wcn36xx_smd_start_scan(wcn);
+   for (i = 0; i < req->n_channels; i++) {
+   wcn->scan_freq = req->channels[i]->center_freq;
+   wcn->scan_band = req->channels[i]->band;
+
+   wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
+   msleep(30);
+   wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
+
+   wcn->scan_freq = 0;
+   }
+   wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+
+   scan_info.aborted = false;
+   ieee80211_scan_completed(wcn->hw, _info);
+
+   mutex_lock(>scan_lock);
+   wcn->scan_req = NULL;
+   mutex_unlock(>scan_lock);
 }
 
-static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
-struct ieee80211_vif *vif)
+static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
+  struct ieee80211_vif *vif,
+  struct ieee80211_scan_request *hw_req)
 {
struct wcn36xx *wcn = hw->priv;
 
-   wcn36xx_smd_end_scan(wcn);
-   wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+   mutex_lock(>scan_lock);
+   if (wcn->scan_req) {
+   mutex_unlock(>scan_lock);
+   return -EBUSY;
+   }
+   wcn->scan_req = _req->req;
+   mutex_unlock(>scan_lock);
+
+   schedule_work(>scan_work);
+
+   return 0;
 }
 
 static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
@@ -997,8 +1033,7 @@ static const struct ieee80211_ops wcn36xx_ops = {
.configure_filter   = wcn36xx_configure_filter,
.tx = wcn36xx_tx,
.set_key= wcn36xx_set_key,
-   .sw_scan_start  = wcn36xx_sw_scan_start,
-   .sw_scan_complete   = wcn36xx_sw_scan_complete,
+   .hw_scan= wcn36xx_hw_scan,
.bss_info_changed   = wcn36xx_bss_info_changed,
.set_rts_threshold  = wcn36xx_set_rts_threshold,
.sta_add= wcn36xx_sta_add,
@@ -1023,6 +1058,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
ieee80211_hw_set(wcn->hw, SUPPORTS_PS);
ieee80211_hw_set(wcn->hw, SIGNAL_DBM);
ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
+   ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS);
 
wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
@@ -1032,6 +1068,9 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = _band_2ghz;
wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = _band_5ghz;
 
+   wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
+   wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN;
+
wcn->hw->wiphy->cipher_suites = cipher_suites;
wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 
@@ -1152,6 +1191,9 @@ static int wcn36xx_probe(struct platform_device *pdev)
wcn->hw = hw;
wcn->dev = >dev;
mutex_init(>hal_mutex);
+   mutex_init(>scan_lock);
+
+   INIT_WORK(>scan_work, wcn36xx_hw_scan_worker);
 

[PATCH v5 5/5] wcn36xx: Don't use the destroyed hal_mutex

2016-11-14 Thread Bjorn Andersson
ieee80211_unregister_hw() might invoke operations to stop the interface,
that uses the hal_mutex. So don't destroy it until after we're done
using it.

Signed-off-by: Bjorn Andersson 
---

With this patch I can successfully (although with a SMD send timeout in the
shutdown path) start and stop the WCNSS PIL/remoteproc multiple times and the
wlan0 interface will come and go accordingly.

Will submit the necessary DT patches soon as well.

Changes since v4:
- New patch

 drivers/net/wireless/ath/wcn36xx/main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index 96a9584edcbb..0002190c9041 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1241,7 +1241,6 @@ static int wcn36xx_remove(struct platform_device *pdev)
wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n");
 
release_firmware(wcn->nv);
-   mutex_destroy(>hal_mutex);
 
ieee80211_unregister_hw(hw);
 
@@ -1250,6 +1249,8 @@ static int wcn36xx_remove(struct platform_device *pdev)
 
iounmap(wcn->dxe_base);
iounmap(wcn->ccu_base);
+
+   mutex_destroy(>hal_mutex);
ieee80211_free_hw(hw);
 
return 0;
-- 
2.5.0



[PATCH] brcmfmac: update beacon IE when bss up and clear when stopped

2016-11-14 Thread Wright Feng
Firmware doesn't update beacon vendor IEs when bss is down, so move 
brcmf_config_ap_mgmt_ie after BSS up. And host driver should clear IEs when AP 
stopped so that the IEs in host side will be synced with in firmware side.

Signed-off-by: Wright Feng 
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index b777e1b..d022605 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -4578,8 +4578,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct 
net_device *ndev,
brcmf_configure_opensecurity(ifp);
}
 
-   brcmf_config_ap_mgmt_ie(ifp->vif, >beacon);
-
/* Parameters shared by all radio interfaces */
if (!mbss) {
if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
@@ -4708,6 +4706,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct 
net_device *ndev,
WARN_ON(1);
}
 
+   brcmf_config_ap_mgmt_ie(ifp->vif, >beacon);
set_bit(BRCMF_VIF_STATUS_AP_CREATED, >vif->sme_state);
brcmf_net_setcarrier(ifp, true);
 
@@ -4764,6 +4763,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, 
struct net_device *ndev)
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
if (err < 0)
brcmf_err("BRCMF_C_UP error %d\n", err);
+
+   brcmf_vif_clear_mgmt_ies(ifp->vif);
} else {
bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
bss_enable.enable = cpu_to_le32(0);
-- 
2.1.0



Re: [ath9k-devel] [NOT FOR MERGE] ath9k: work around key cache corruption

2016-11-14 Thread Adrian Chadd
Hiya,

maybe the right thing to do is to set a flag that says "please
replumb", then do a reset, and have the reset path see if we need to
replumb keys and do so?

To make locking less terrible, maybe we need to cache the keys in the
ath9k driver somewhere so replumbing doesn't require reaching into
mac82011.



-adrian


Re: [PATCH v3 01/11] mwifiex: check tx_hw_pending before downloading sleep confirm

2016-11-14 Thread Brian Norris
Hi Amit, Kalle,

On Fri, Nov 11, 2016 at 06:40:08PM +0530, Amitkumar Karwar wrote:
> From: Shengzhen Li 
> 
> We may get SLEEP event from firmware even if TXDone interrupt
> for last Tx packet is still pending. In this case, we may
> end up accessing PCIe memory for handling TXDone after power
> save handshake is completed. This causes kernel crash with
> external abort.
> 
> This patch will only allow downloading sleep confirm
> when no tx done interrupt is pending in the hardware.
> 
> Signed-off-by: Cathy Luo 
> Signed-off-by: Shengzhen Li 
> Tested-by: Xinming Hu 
> Signed-off-by: Amitkumar Karwar 
> ---
> v2: address format issues(Brain)
> RESEND v2(Applicable for complete patch series):
> 1) Fixed syntax issue "changelog not placed after the  Sign-offs"
>pointed by Brian.
> 2) Dropped "[v2,03/12] mwifiex: don't do unbalanced free()'ing in
>cleanup_if()" patch in this series. It was already sent by Brian
>separately.
> v3: Same as RESEND v2.
> 
> Hi Kalle,
> 
> There are multiple mwifiex patches under review. I want you consider them
> in following sequence(first being oldest) to avoid conflicts

Thanks for doing this! It's a little confusing about what's outstanding
at the moment (and I think I was just confused on a review a bit ago; I
wasn't 100% sure what it was based on), so this listing helps.

If it helps, I'll put my comments here, since I've reviewed most of
these:

> [v3] mwifiex: report wakeup for wowlan

Reviewed, SGMT.

> mwifiex: add power save parameters in hs_cfg cmd

Didn't review. No comment.

> [2/2] mwifiex: ignore calibration data failure (Note: 1/2 has dropped)

Didn't review. But FWIW, Kalle expressed a preference for full series,
not partial.

> [v6] mwifiex: parse device tree node for PCIe

This one is marked Deferred in patchwork, and I had some comments about
it, since it introduced a double-free issue. I'd prefer it get fixed and
resent, and I expect Kalle is also waiting for this.

> [v2,1/3] mwifiex: Allow mwifiex early access to device structure
> [v2,2/3] mwifiex: Introduce mwifiex_probe_of() to parse common properties
> [v2,3/3] mwifiex: Enable WoWLAN for both sdio and pcie

You sent v3 for the above, and those LGTM (I provided my review). I was
probably also confused because they were based on the above "[v6]
mwifiex: parse device tree node for PCIe", which was not completely
correct.

> mwifiex: don't do unbalanced free()'ing in cleanup_if()
> mwifiex: printk() overflow with 32-byte SSIDs
> mwifiex: fix memory leak in mwifiex_save_hidden_ssid_channels()

I wrote or reviewed the above 3. LGTM.

> [v3,01/11] mwifiex: check tx_hw_pending before downloading sleep confirm
> [v3,02/11] mwifiex: complete blocked power save handshake in main process
> [v3,03/11] mwifiex: resolve races between async FW init (failure) and device 
> removal
> [v3,04/11] mwifiex: remove redundant pdev check in suspend/resume handlers
> [v3,05/11] mwifiex: don't pretend to resume while remove()'ing
> [v3,06/11] mwifiex: resolve suspend() race with async FW init failure
> [v3,07/11] mwifiex: reset card->adapter during device unregister
> [v3,08/11] mwifiex: usb: handle HS failures
> [v3,09/11] mwifiex: sdio: don't check for NULL sdio_func
> [v3,10/11] mwifiex: stop checking for NULL drvata/intfdata
> [v3,11/11] mwifiex: pcie: stop checking for NULL adapter->card

For this entire series, I looked over them again (and I wrote several in
the first place), so for all 11:

Reviewed-by: Brian Norris 

> ---
>  drivers/net/wireless/marvell/mwifiex/cmdevt.c | 5 +++--
>  drivers/net/wireless/marvell/mwifiex/init.c   | 1 +
>  drivers/net/wireless/marvell/mwifiex/main.h   | 1 +
>  drivers/net/wireless/marvell/mwifiex/pcie.c   | 5 +
>  4 files changed, 10 insertions(+), 2 deletions(-)
> 
[...] 


Re: [PATCH v3 3/3] mwifiex: Enable WoWLAN for both sdio and pcie

2016-11-14 Thread Brian Norris
On Mon, Nov 14, 2016 at 06:19:12PM +0530, Amitkumar Karwar wrote:
> From: Rajat Jain 
> 
> Commit ce4f6f0c353b ("mwifiex: add platform specific wakeup interrupt
> support") added WoWLAN feature only for sdio. This patch moves that
> code to the common module so that all the interface drivers can use
> it for free. It enables pcie and sdio for its use currently.
> 
> Signed-off-by: Rajat Jain 
> ---
> v2: v1 doesn't apply smoothly on latest code due to recently merged
> patch "mwifiex: report error to PCIe for suspend failure". Minor
> conflict is resolved in v2
> v3: Same as v2 

For the whole series:

Reviewed-by: Brian Norris 

I think there are some trivial conflicts with one of your/our other
series, but that can be worked out once one of them is accepted. I also
expect you'll send patches to fix the existing bugs I noted already.

Also, this implicitly extends device tree support to PCIe devices. While
that's probably OK, it would be good to promptly update a patch like
this:

[PATCH v6] mwifiex: parse device tree node for PCIe
https://patchwork.kernel.org/patch/9390225/

to check for the appropriate compatible properties before accepting the
device and registering the card. That patch should be just a little bit
simpler on top of this patch set.

Brian

> ---
>  drivers/net/wireless/marvell/mwifiex/main.c | 41 
>  drivers/net/wireless/marvell/mwifiex/main.h | 25 ++
>  drivers/net/wireless/marvell/mwifiex/pcie.c |  2 +
>  drivers/net/wireless/marvell/mwifiex/sdio.c | 72 
> ++---
>  drivers/net/wireless/marvell/mwifiex/sdio.h |  8 
>  5 files changed, 73 insertions(+), 75 deletions(-)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/main.c 
> b/drivers/net/wireless/marvell/mwifiex/main.c
> index 835d330..948f5c2 100644
> --- a/drivers/net/wireless/marvell/mwifiex/main.c
> +++ b/drivers/net/wireless/marvell/mwifiex/main.c
> @@ -1552,14 +1552,55 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, 
> bool prepare)
>  }
>  EXPORT_SYMBOL_GPL(mwifiex_do_flr);
>  
> +static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
> +{
> + struct mwifiex_adapter *adapter = priv;
> +
> + if (adapter->irq_wakeup >= 0) {
> + dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
> + adapter->wake_by_wifi = true;
> + disable_irq_nosync(irq);
> + }
> +
> + /* Notify PM core we are wakeup source */
> + pm_wakeup_event(adapter->dev, 0);
> +
> + return IRQ_HANDLED;
> +}
> +
>  static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
>  {
> + int ret;
>   struct device *dev = adapter->dev;
>  
>   if (!dev->of_node)
>   return;
>  
>   adapter->dt_node = dev->of_node;
> + adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0);
> + if (!adapter->irq_wakeup) {
> + dev_info(dev, "fail to parse irq_wakeup from device tree\n");
> + return;
> + }
> +
> + ret = devm_request_irq(dev, adapter->irq_wakeup,
> +mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
> +"wifi_wake", adapter);
> + if (ret) {
> + dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
> + adapter->irq_wakeup, ret);
> + goto err_exit;
> + }
> +
> + disable_irq(adapter->irq_wakeup);
> + if (device_init_wakeup(dev, true)) {
> + dev_err(dev, "fail to init wakeup for mwifiex\n");
> + goto err_exit;
> + }
> + return;
> +
> +err_exit:
> + adapter->irq_wakeup = 0;
>  }
>  
>  /*
> diff --git a/drivers/net/wireless/marvell/mwifiex/main.h 
> b/drivers/net/wireless/marvell/mwifiex/main.h
> index 549e1ba..ae5afe5 100644
> --- a/drivers/net/wireless/marvell/mwifiex/main.h
> +++ b/drivers/net/wireless/marvell/mwifiex/main.h
> @@ -1011,6 +1011,10 @@ struct mwifiex_adapter {
>   bool usb_mc_setup;
>   struct cfg80211_wowlan_nd_info *nd_info;
>   struct ieee80211_regdomain *regd;
> +
> + /* Wake-on-WLAN (WoWLAN) */
> + int irq_wakeup;
> + bool wake_by_wifi;
>  };
>  
>  void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
> @@ -1410,6 +1414,27 @@ static inline u8 mwifiex_is_tdls_link_setup(u8 status)
>   return false;
>  }
>  
> +/* Disable platform specific wakeup interrupt */
> +static inline void mwifiex_disable_wake(struct mwifiex_adapter *adapter)
> +{
> + if (adapter->irq_wakeup >= 0) {
> + disable_irq_wake(adapter->irq_wakeup);
> + if (!adapter->wake_by_wifi)
> + disable_irq(adapter->irq_wakeup);
> + }
> +}
> +
> +/* Enable platform specific wakeup interrupt */
> +static inline void mwifiex_enable_wake(struct mwifiex_adapter *adapter)
> +{
> + /* Enable platform specific wakeup interrupt */
> + if (adapter->irq_wakeup >= 0) {
> + 

[RFC 08/12] ath10k: Added ATH10K_BUS_SDIO enum

2016-11-14 Thread Erik Stromdahl
Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/core.h |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index b7067cc..8c7b080 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -74,6 +74,7 @@
 enum ath10k_bus {
ATH10K_BUS_PCI,
ATH10K_BUS_AHB,
+   ATH10K_BUS_SDIO,
 };
 
 static inline const char *ath10k_bus_str(enum ath10k_bus bus)
@@ -83,6 +84,8 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
return "pci";
case ATH10K_BUS_AHB:
return "ahb";
+   case ATH10K_BUS_SDIO:
+   return "sdio";
}
 
return "unknown";
-- 
1.7.9.5



[RFC 10/12] ath10k: Added QCA65XX hw definition

2016-11-14 Thread Erik Stromdahl
Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/hw.h |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 46142e9..ef45ecf 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -224,6 +224,7 @@ enum ath10k_hw_rev {
ATH10K_HW_QCA9377,
ATH10K_HW_QCA4019,
ATH10K_HW_QCA9887,
+   ATH10K_HW_QCA65XX,
 };
 
 struct ath10k_hw_regs {
-- 
1.7.9.5



[RFC 03/12] ath10k: htc: Changed order of wait target and ep connect

2016-11-14 Thread Erik Stromdahl
This patch changes the order in which the driver waits for the
target to become ready and the service connect of the HTC
control service.

The HTC control service is connected before the driver starts
waiting for the HTC ready control message.

The reason for this is that the HTC ready control message is
transmitted on EP 0 and that sdio/mbox based systems will ignore
messages received on unconnected endpoints.

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/htc.c |   32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index e3f7bf4..7257366 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -606,6 +606,22 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
u16 credit_count;
u16 credit_size;
 
+   /* setup our pseudo HTC control endpoint connection */
+   memset(_req, 0, sizeof(conn_req));
+   memset(_resp, 0, sizeof(conn_resp));
+   conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
+   conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
+   conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
+   conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;
+
+   /* connect fake service */
+   status = ath10k_htc_connect_service(htc, _req, _resp);
+   if (status) {
+   ath10k_err(ar, "could not connect to htc service (%d)\n",
+  status);
+   return status;
+   }
+
time_left = wait_for_completion_timeout(>ctl_resp,
ATH10K_HTC_WAIT_TIMEOUT_HZ);
if (!time_left) {
@@ -665,22 +681,6 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
 
ath10k_htc_setup_target_buffer_assignments(htc);
 
-   /* setup our pseudo HTC control endpoint connection */
-   memset(_req, 0, sizeof(conn_req));
-   memset(_resp, 0, sizeof(conn_resp));
-   conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
-   conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
-   conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
-   conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;
-
-   /* connect fake service */
-   status = ath10k_htc_connect_service(htc, _req, _resp);
-   if (status) {
-   ath10k_err(ar, "could not connect to htc service (%d)\n",
-  status);
-   return status;
-   }
-
return 0;
 }
 
-- 
1.7.9.5



[RFC 07/12] ath10k: Added SDIO dbg masks

2016-11-14 Thread Erik Stromdahl
Debug masks for SDIO HIF layer.

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/debug.h |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/debug.h 
b/drivers/net/wireless/ath/ath10k/debug.h
index 335512b..d35263c 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -38,6 +38,8 @@ enum ath10k_debug_mask {
ATH10K_DBG_WMI_PRINT= 0x2000,
ATH10K_DBG_PCI_PS   = 0x4000,
ATH10K_DBG_AHB  = 0x8000,
+   ATH10K_DBG_SDIO = 0x0001,
+   ATH10K_DBG_SDIO_DUMP= 0x0002,
ATH10K_DBG_ANY  = 0x,
 };
 
-- 
1.7.9.5



[RFC 12/12] ath10k: Added sdio support

2016-11-14 Thread Erik Stromdahl
Initial HIF sdio/mailbox implementation.

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/Kconfig  |6 +
 drivers/net/wireless/ath/ath10k/Makefile |3 +
 drivers/net/wireless/ath/ath10k/sdio.c   | 1855 ++
 drivers/net/wireless/ath/ath10k/sdio.h   |  276 +
 4 files changed, 2140 insertions(+)
 create mode 100644 drivers/net/wireless/ath/ath10k/sdio.c
 create mode 100644 drivers/net/wireless/ath/ath10k/sdio.h

diff --git a/drivers/net/wireless/ath/ath10k/Kconfig 
b/drivers/net/wireless/ath/ath10k/Kconfig
index db1ca62..9a03178 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -21,6 +21,12 @@ config ATH10K_AHB
---help---
  This module adds support for AHB bus
 
+config ATH10K_SDIO
+   tristate "Atheros ath10k SDIO support (EXPERIMENTAL)"
+   depends on ATH10K && MMC
+   ---help---
+ This module adds support for SDIO/MMC bus
+
 config ATH10K_DEBUG
bool "Atheros ath10k debugging"
depends on ATH10K
diff --git a/drivers/net/wireless/ath/ath10k/Makefile 
b/drivers/net/wireless/ath/ath10k/Makefile
index 930fadd..b0b19a7 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -27,5 +27,8 @@ ath10k_pci-y += pci.o \
 
 ath10k_pci-$(CONFIG_ATH10K_AHB) += ahb.o
 
+obj-$(CONFIG_ATH10K_SDIO) += ath10k_sdio.o
+ath10k_sdio-y += sdio.o
+
 # for tracing framework to find trace.h
 CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c 
b/drivers/net/wireless/ath/ath10k/sdio.c
new file mode 100644
index 000..72b0732
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/sdio.c
@@ -0,0 +1,1855 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
+ * Copyright (c) 2016 Kapsch Trafficcom AB
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "core.h"
+#include "bmi.h"
+#include "debug.h"
+#include "hif.h"
+#include "htc.h"
+#include "targaddrs.h"
+#include "trace.h"
+#include "sdio.h"
+
+#define CALC_TXRX_PADDED_LEN(ar_sdio, len) \
+   (__ALIGN_MASK((len), (ar_sdio)->mbox_info.block_mask))
+
+static int ath10k_sdio_read_write_sync(struct ath10k *ar, u32 addr, u8 *buf,
+  u32 len, u32 request);
+static int ath10k_sdio_hif_diag_read(struct ath10k *ar, u32 address, void *buf,
+size_t buf_len);
+static int ath10k_sdio_hif_diag_read32(struct ath10k *ar, u32 address,
+  u32 *value);
+
+/* HIF mbox interrupt handling */
+
+static int ath10k_sdio_mbox_rx_process_packet(struct ath10k_sdio *ar_sdio,
+ struct ath10k_sdio_rx_data *pkt,
+ u32 *next_lkahds, int *n_lkahds)
+{
+   int status = 0;
+   struct ath10k_htc *htc = _sdio->ar->htc;
+   struct sk_buff *skb = pkt->skb;
+   struct ath10k_htc_hdr *htc_hdr = (struct ath10k_htc_hdr *)skb->data;
+   bool trailer_present = htc_hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
+   u16 payload_len;
+
+   payload_len = le16_to_cpu(htc_hdr->len);
+
+   if (trailer_present) {
+   u8 *trailer;
+   enum ath10k_htc_ep_id eid;
+
+   trailer = skb->data + sizeof(struct ath10k_htc_hdr) +
+ payload_len - htc_hdr->trailer_len;
+
+   eid = (enum ath10k_htc_ep_id)htc_hdr->eid;
+
+   status = ath10k_htc_process_trailer(htc,
+   trailer,
+   htc_hdr->trailer_len,
+   eid,
+   next_lkahds,
+   n_lkahds);
+   if (status)
+   goto err;
+
+   skb_pull(skb, sizeof(*htc_hdr));
+   skb_trim(skb, skb->len - htc_hdr->trailer_len);
+   }
+
+err:
+   return status;
+}
+
+static inline void 

[RFC 04/12] ath10k: htc: refactorization

2016-11-14 Thread Erik Stromdahl
Code refactorization:

Moved the code for ep 0 in ath10k_htc_rx_completion_handler
to ath10k_htc_control_rx_complete.

This eases the implementation of SDIO/mbox significantly since
the ep_rx_complete cb is invoked directly from the SDIO/mbox
hif layer.

Since the ath10k_htc_control_rx_complete already is present
(only containing a warning message) there is no reason for not
using it (instead of having a special case for ep 0 in
ath10k_htc_rx_completion_handler).

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/htc.c |   73 +++--
 1 file changed, 34 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index 7257366..a5a2f78 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -457,42 +457,6 @@ void ath10k_htc_rx_completion_handler(struct ath10k *ar, 
struct sk_buff *skb)
/* zero length packet with trailer data, just drop these */
goto out;
 
-   if (eid == ATH10K_HTC_EP_0) {
-   struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
-
-   switch (__le16_to_cpu(msg->hdr.message_id)) {
-   case ATH10K_HTC_MSG_READY_ID:
-   case ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID:
-   /* handle HTC control message */
-   if (completion_done(>ctl_resp)) {
-   /*
-* this is a fatal error, target should not be
-* sending unsolicited messages on the ep 0
-*/
-   ath10k_warn(ar, "HTC rx ctrl still 
processing\n");
-   complete(>ctl_resp);
-   goto out;
-   }
-
-   htc->control_resp_len =
-   min_t(int, skb->len,
- ATH10K_HTC_MAX_CTRL_MSG_LEN);
-
-   memcpy(htc->control_resp_buffer, skb->data,
-  htc->control_resp_len);
-
-   complete(>ctl_resp);
-   break;
-   case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
-   htc->htc_ops.target_send_suspend_complete(ar);
-   break;
-   default:
-   ath10k_warn(ar, "ignoring unsolicited htc ep0 event\n");
-   break;
-   }
-   goto out;
-   }
-
ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %pK\n",
   eid, skb);
ep->ep_ops.ep_rx_complete(ar, skb);
@@ -507,9 +471,40 @@ void ath10k_htc_rx_completion_handler(struct ath10k *ar, 
struct sk_buff *skb)
 static void ath10k_htc_control_rx_complete(struct ath10k *ar,
   struct sk_buff *skb)
 {
-   /* This is unexpected. FW is not supposed to send regular rx on this
-* endpoint. */
-   ath10k_warn(ar, "unexpected htc rx\n");
+   struct ath10k_htc *htc = >htc;
+   struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
+
+   switch (__le16_to_cpu(msg->hdr.message_id)) {
+   case ATH10K_HTC_MSG_READY_ID:
+   case ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID:
+   /* handle HTC control message */
+   if (completion_done(>ctl_resp)) {
+   /* this is a fatal error, target should not be
+* sending unsolicited messages on the ep 0
+*/
+   ath10k_warn(ar, "HTC rx ctrl still processing\n");
+   complete(>ctl_resp);
+   goto out;
+   }
+
+   htc->control_resp_len =
+   min_t(int, skb->len,
+ ATH10K_HTC_MAX_CTRL_MSG_LEN);
+
+   memcpy(htc->control_resp_buffer, skb->data,
+  htc->control_resp_len);
+
+   complete(>ctl_resp);
+   break;
+   case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
+   htc->htc_ops.target_send_suspend_complete(ar);
+   break;
+   default:
+   ath10k_warn(ar, "ignoring unsolicited htc ep0 event\n");
+   break;
+   }
+
+out:
kfree_skb(skb);
 }
 
-- 
1.7.9.5



[RFC 06/12] ath10k: bmi: Added SOC reg read/write functions

2016-11-14 Thread Erik Stromdahl
Added functions implementing the following BMI commands:

BMI_READ_SOC_REGISTER
BMI_WRITE_SOC_REGISTER

Reading and writing BMI registers is sometimes needed for
SDIO chipsets.

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/bmi.c |   79 -
 drivers/net/wireless/ath/ath10k/bmi.h |4 ++
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/bmi.c 
b/drivers/net/wireless/ath/ath10k/bmi.c
index 2872d34..1c378a2 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.c
+++ b/drivers/net/wireless/ath/ath10k/bmi.c
@@ -97,7 +97,8 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
u32 rxlen;
int ret;
 
-   ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n",
+   ath10k_dbg(ar, ATH10K_DBG_BMI,
+  "bmi read memory address 0x%x length %d\n",
   address, length);
 
if (ar->bmi.done_sent) {
@@ -137,7 +138,8 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
u32 txlen;
int ret;
 
-   ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n",
+   ath10k_dbg(ar, ATH10K_DBG_BMI,
+  "bmi write memory address 0x%x length %d\n",
   address, length);
 
if (ar->bmi.done_sent) {
@@ -175,6 +177,79 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
return 0;
 }
 
+int ath10k_bmi_read_soc_reg(struct ath10k *ar,
+   u32 address, u32 *regval)
+{
+   struct bmi_cmd cmd;
+   union bmi_resp resp;
+   u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.read_soc_reg);
+   u32 rxlen;
+   int ret;
+
+   ath10k_dbg(ar, ATH10K_DBG_BMI,
+  "bmi read SOC register address 0x%x\n",
+  address);
+
+   if (ar->bmi.done_sent) {
+   ath10k_warn(ar, "command disallowed\n");
+   return -EBUSY;
+   }
+
+   rxlen = sizeof(resp.read_soc_reg.value);
+
+   cmd.id= __cpu_to_le32(BMI_READ_SOC_REGISTER);
+   cmd.read_soc_reg.addr = __cpu_to_le32(address);
+
+   ret = ath10k_hif_exchange_bmi_msg(ar, , cmdlen,
+ , );
+   if (ret) {
+   ath10k_warn(ar, "unable to read from the device (%d)\n",
+   ret);
+   return ret;
+   }
+
+   if (rxlen != sizeof(resp.read_soc_reg.value)) {
+   ath10k_warn(ar, "Unexpected read len: %u (expected %u)\n",
+   rxlen, sizeof(resp.read_soc_reg.value));
+   return ret;
+   }
+
+   *regval = __le32_to_cpu(resp.read_soc_reg.value);
+
+   return 0;
+}
+
+int ath10k_bmi_write_soc_reg(struct ath10k *ar,
+u32 address, u32 regval)
+{
+   struct bmi_cmd cmd;
+   u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.write_soc_reg);
+   int ret;
+
+   ath10k_dbg(ar, ATH10K_DBG_BMI,
+  "bmi write SOC register address 0x%x\n",
+  address);
+
+   if (ar->bmi.done_sent) {
+   ath10k_warn(ar, "command disallowed\n");
+   return -EBUSY;
+   }
+
+   cmd.id  = __cpu_to_le32(BMI_WRITE_SOC_REGISTER);
+   cmd.write_soc_reg.addr  = __cpu_to_le32(address);
+   cmd.write_soc_reg.value = __cpu_to_le32(regval);
+
+   ret = ath10k_hif_exchange_bmi_msg(ar, , cmdlen,
+ NULL, NULL);
+   if (ret) {
+   ath10k_warn(ar, "unable to write to the device (%d)\n",
+   ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
 {
struct bmi_cmd cmd;
diff --git a/drivers/net/wireless/ath/ath10k/bmi.h 
b/drivers/net/wireless/ath/ath10k/bmi.h
index 7d3231a..a867867 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.h
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
@@ -201,6 +201,10 @@ int ath10k_bmi_read_memory(struct ath10k *ar, u32 address,
   void *buffer, u32 length);
 int ath10k_bmi_write_memory(struct ath10k *ar, u32 address,
const void *buffer, u32 length);
+int ath10k_bmi_read_soc_reg(struct ath10k *ar,
+   u32 address, u32 *regval);
+int ath10k_bmi_write_soc_reg(struct ath10k *ar,
+u32 address, u32 regval);
 
 #define ath10k_bmi_read32(ar, item, val)   \
({  \
-- 
1.7.9.5



[RFC 09/12] ath10k: Mailbox address definitions

2016-11-14 Thread Erik Stromdahl
Address definitions for SDIO/mbox based chipsets.

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/hw.h |   53 ++
 1 file changed, 53 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 883547f..46142e9 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -814,6 +814,59 @@ struct ath10k_hw_ops {
 #define QCA9887_EEPROM_ADDR_LO_MASK0x00ff
 #define QCA9887_EEPROM_ADDR_LO_LSB 16
 
+#define MBOX_RESET_CONTROL_ADDRESS 0x
+#define MBOX_HOST_INT_STATUS_ADDRESS   0x0800
+#define MBOX_HOST_INT_STATUS_ERROR_LSB 7
+#define MBOX_HOST_INT_STATUS_ERROR_MASK0x0080
+#define MBOX_HOST_INT_STATUS_CPU_LSB   6
+#define MBOX_HOST_INT_STATUS_CPU_MASK  0x0040
+#define MBOX_HOST_INT_STATUS_COUNTER_LSB   4
+#define MBOX_HOST_INT_STATUS_COUNTER_MASK  0x0010
+#define MBOX_CPU_INT_STATUS_ADDRESS0x0801
+#define MBOX_ERROR_INT_STATUS_ADDRESS  0x0802
+#define MBOX_ERROR_INT_STATUS_WAKEUP_LSB   2
+#define MBOX_ERROR_INT_STATUS_WAKEUP_MASK  0x0004
+#define MBOX_ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1
+#define MBOX_ERROR_INT_STATUS_RX_UNDERFLOW_MASK0x0002
+#define MBOX_ERROR_INT_STATUS_TX_OVERFLOW_LSB  0
+#define MBOX_ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x0001
+#define MBOX_COUNTER_INT_STATUS_ADDRESS0x0803
+#define MBOX_COUNTER_INT_STATUS_COUNTER_LSB0
+#define MBOX_COUNTER_INT_STATUS_COUNTER_MASK   0x00ff
+#define MBOX_RX_LOOKAHEAD_VALID_ADDRESS0x0805
+#define MBOX_INT_STATUS_ENABLE_ADDRESS 0x0828
+#define MBOX_INT_STATUS_ENABLE_ERROR_LSB   7
+#define MBOX_INT_STATUS_ENABLE_ERROR_MASK  0x0080
+#define MBOX_INT_STATUS_ENABLE_CPU_LSB 6
+#define MBOX_INT_STATUS_ENABLE_CPU_MASK0x0040
+#define MBOX_INT_STATUS_ENABLE_INT_LSB 5
+#define MBOX_INT_STATUS_ENABLE_INT_MASK0x0020
+#define MBOX_INT_STATUS_ENABLE_COUNTER_LSB 4
+#define MBOX_INT_STATUS_ENABLE_COUNTER_MASK0x0010
+#define MBOX_INT_STATUS_ENABLE_MBOX_DATA_LSB   0
+#define MBOX_INT_STATUS_ENABLE_MBOX_DATA_MASK  0x000f
+#define MBOX_CPU_INT_STATUS_ENABLE_ADDRESS 0x0819
+#define MBOX_CPU_INT_STATUS_ENABLE_BIT_LSB 0
+#define MBOX_CPU_INT_STATUS_ENABLE_BIT_MASK0x00ff
+#define MBOX_ERROR_STATUS_ENABLE_ADDRESS   0x081a
+#define MBOX_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB  1
+#define MBOX_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x0002
+#define MBOX_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB   0
+#define MBOX_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK  0x0001
+#define MBOX_COUNTER_INT_STATUS_ENABLE_ADDRESS 0x081b
+#define MBOX_COUNTER_INT_STATUS_ENABLE_BIT_LSB 0
+#define MBOX_COUNTER_INT_STATUS_ENABLE_BIT_MASK0x00ff
+#define MBOX_COUNT_ADDRESS 0x0820
+#define MBOX_COUNT_DEC_ADDRESS 0x0840
+#define MBOX_WINDOW_DATA_ADDRESS   0x0874
+#define MBOX_WINDOW_WRITE_ADDR_ADDRESS 0x0878
+#define MBOX_WINDOW_READ_ADDR_ADDRESS  0x087c
+#define MBOX_CPU_DBG_SEL_ADDRESS   0x0883
+#define MBOX_CPU_DBG_ADDRESS   0x0884
+#define MBOX_RTC_BASE_ADDRESS  0x
+#define MBOX_GPIO_BASE_ADDRESS 0x5000
+#define MBOX_MBOX_BASE_ADDRESS 0x8000
+
 #define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB)
 
 /* Register definitions for first generation ath10k cards. These cards include
-- 
1.7.9.5



[RFC 01/12] ath10k: htc: made static function public

2016-11-14 Thread Erik Stromdahl
Changed ath10k_htc_notify_tx_completion and
ath10k_htc_process_trailer from static to non static.

These functions are needed by SDIO/mbox.

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/htc.c |   14 --
 drivers/net/wireless/ath/ath10k/htc.h |6 ++
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index 175aae3..26b1e15 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -57,8 +57,8 @@ static inline void ath10k_htc_restore_tx_skb(struct 
ath10k_htc *htc,
skb_pull(skb, sizeof(struct ath10k_htc_hdr));
 }
 
-static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
-   struct sk_buff *skb)
+void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
+struct sk_buff *skb)
 {
struct ath10k *ar = ep->htc->ar;
 
@@ -75,6 +75,7 @@ static void ath10k_htc_notify_tx_completion(struct 
ath10k_htc_ep *ep,
 
ep->ep_ops.ep_tx_complete(ep->htc->ar, skb);
 }
+EXPORT_SYMBOL(ath10k_htc_notify_tx_completion);
 
 static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
  struct sk_buff *skb)
@@ -227,10 +228,10 @@ void ath10k_htc_tx_completion_handler(struct ath10k *ar, 
struct sk_buff *skb)
spin_unlock_bh(>tx_lock);
 }
 
-static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
- u8 *buffer,
- int length,
- enum ath10k_htc_ep_id src_eid)
+int ath10k_htc_process_trailer(struct ath10k_htc *htc,
+  u8 *buffer,
+  int length,
+  enum ath10k_htc_ep_id src_eid)
 {
struct ath10k *ar = htc->ar;
int status = 0;
@@ -291,6 +292,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc 
*htc,
 
return status;
 }
+EXPORT_SYMBOL(ath10k_htc_process_trailer);
 
 void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb)
 {
diff --git a/drivers/net/wireless/ath/ath10k/htc.h 
b/drivers/net/wireless/ath/ath10k/htc.h
index 0c55cd9..858e19f 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -354,5 +354,11 @@ int ath10k_htc_send(struct ath10k_htc *htc, enum 
ath10k_htc_ep_id eid,
 struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size);
 void ath10k_htc_tx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
 void ath10k_htc_rx_completion_handler(struct ath10k *ar, struct sk_buff *skb);
+void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
+struct sk_buff *skb);
+int ath10k_htc_process_trailer(struct ath10k_htc *htc,
+  u8 *buffer,
+  int length,
+  enum ath10k_htc_ep_id src_eid);
 
 #endif
-- 
1.7.9.5



[RFC 05/12] ath10k: htc: Added ATH10K_HTC_FLAG_BUNDLE_LSB

2016-11-14 Thread Erik Stromdahl
Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/htc.h |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/htc.h 
b/drivers/net/wireless/ath/ath10k/htc.h
index 589800a..df16a04 100644
--- a/drivers/net/wireless/ath/ath10k/htc.h
+++ b/drivers/net/wireless/ath/ath10k/htc.h
@@ -62,6 +62,8 @@ enum ath10k_htc_rx_flags {
ATH10K_HTC_FLAG_BUNDLE_MASK = 0xF0
 };
 
+#define ATH10K_HTC_FLAG_BUNDLE_LSB 4
+
 struct ath10k_htc_hdr {
u8 eid; /* @enum ath10k_htc_ep_id */
u8 flags; /* @enum ath10k_htc_tx_flags, ath10k_htc_rx_flags */
-- 
1.7.9.5



[RFC 00/12] ath10k sdio support

2016-11-14 Thread Erik Stromdahl
This patch series adds sdio support to ath10k.

Some of the patches affect the existing pcie/ahb code as well.
Those are patches 3 and 4 in the series.

Overview:
A new HIF layer: sdio/mailbox.
The current HIF ops are unaltered even though some ops
are not applicable for sdio.

The HTC layer has only suffered minor modifications:
- A few new functions for handling the mailbox specific
  RX trailers (lookahead reports)
- Some minor refactorization of the existing code
  (patches 3 and 4)

This is not included in this patch series:

- HTT High latency RX and TX support
- Full integration in core.c

The following basic tests have been made so far:

BMI fw load and firmware startup (all the steps in ath10k_core_start).
This means:

- HTT service connect
- WMI control service connect
- WMI unified init

The above mentioned bullets where verified with a QCA6584 chipset.

I have not been able to test the patch series together with
ath10k pcie hardware, but I will do so as soon as I can get
my hands on some hardware.

The patches have been built and tested against the ath tree:
git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
branch/tag: master/ath-201611090123

Erik Stromdahl (12):
  ath10k: htc: made static function public
  ath10k: htc: rx trailer lookahead support
  ath10k: htc: Changed order of wait target and ep connect
  ath10k: htc: refactorization
  ath10k: htc: Added ATH10K_HTC_FLAG_BUNDLE_LSB
  ath10k: bmi: Added SOC reg read/write functions
  ath10k: Added SDIO dbg masks
  ath10k: Added ATH10K_BUS_SDIO enum
  ath10k: Mailbox address definitions
  ath10k: Added QCA65XX hw definition
  ath10k: Added more host_interest members
  ath10k: Added sdio support

 drivers/net/wireless/ath/ath10k/Kconfig |6 +
 drivers/net/wireless/ath/ath10k/Makefile|3 +
 drivers/net/wireless/ath/ath10k/bmi.c   |   79 +-
 drivers/net/wireless/ath/ath10k/bmi.h   |4 +
 drivers/net/wireless/ath/ath10k/core.h  |3 +
 drivers/net/wireless/ath/ath10k/debug.h |2 +
 drivers/net/wireless/ath/ath10k/htc.c   |  208 ++-
 drivers/net/wireless/ath/ath10k/htc.h   |   36 +-
 drivers/net/wireless/ath/ath10k/hw.h|   54 +
 drivers/net/wireless/ath/ath10k/sdio.c  | 1855 +++
 drivers/net/wireless/ath/ath10k/sdio.h  |  276 
 drivers/net/wireless/ath/ath10k/targaddrs.h |   24 +
 12 files changed, 2484 insertions(+), 66 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/sdio.c
 create mode 100644 drivers/net/wireless/ath/ath10k/sdio.h

-- 
1.7.9.5



[RFC 02/12] ath10k: htc: rx trailer lookahead support

2016-11-14 Thread Erik Stromdahl
The RX trailer parsing is now capable of parsing lookahead reports.
This is needed by SDIO/mbox.

Signed-off-by: Erik Stromdahl 
---
 drivers/net/wireless/ath/ath10k/htc.c |   91 -
 drivers/net/wireless/ath/ath10k/htc.h |   30 +--
 2 files changed, 116 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htc.c 
b/drivers/net/wireless/ath/ath10k/htc.c
index 26b1e15..e3f7bf4 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -228,10 +228,74 @@ void ath10k_htc_tx_completion_handler(struct ath10k *ar, 
struct sk_buff *skb)
spin_unlock_bh(>tx_lock);
 }
 
+static int
+ath10k_htc_process_lookahead(struct ath10k_htc *htc,
+const struct ath10k_htc_lookahead_report *report,
+int len,
+enum ath10k_htc_ep_id eid,
+u32 *next_lk_ahds,
+int *next_lk_ahds_len)
+{
+   struct ath10k *ar = htc->ar;
+
+   if (report->pre_valid != ((~report->post_valid) & 0xFF))
+   /* Invalid lookahead flags are actually transmitted by
+* the target in the HTC control message.
+* Since this will happen at every boot we silently ignore
+* the lookahead in this case
+*/
+   return 0;
+
+   if (next_lk_ahds && next_lk_ahds_len) {
+   ath10k_dbg(ar, ATH10K_DBG_HTC,
+  "htc rx lk_ahd found pre_valid 0x%x post_valid 
0x%x\n",
+  report->pre_valid, report->post_valid);
+
+   /* look ahead bytes are valid, copy them over */
+   memcpy((u8 *)_lk_ahds[0], report->lk_ahd, 4);
+
+   *next_lk_ahds_len = 1;
+   }
+
+   return 0;
+}
+
+static int
+ath10k_htc_process_lookahead_bundle(struct ath10k_htc *htc,
+   const struct 
ath10k_htc_lookahead_report_bundle *report,
+   int len,
+   enum ath10k_htc_ep_id eid,
+   u32 *next_lk_ahds,
+   int *next_lk_ahds_len)
+{
+   int bundle_cnt = len / sizeof(*report);
+
+   if (!bundle_cnt || (bundle_cnt > HTC_HOST_MAX_MSG_PER_BUNDLE)) {
+   WARN_ON(1);
+   return -EINVAL;
+   }
+
+   if (next_lk_ahds && next_lk_ahds_len) {
+   int i;
+
+   for (i = 0; i < bundle_cnt; i++) {
+   memcpy((u8 *)_lk_ahds[i], report->lk_ahd,
+  sizeof(u32));
+   report++;
+   }
+
+   *next_lk_ahds_len = bundle_cnt;
+   }
+
+   return 0;
+}
+
 int ath10k_htc_process_trailer(struct ath10k_htc *htc,
   u8 *buffer,
   int length,
-  enum ath10k_htc_ep_id src_eid)
+  enum ath10k_htc_ep_id src_eid,
+  u32 *next_lk_ahds,
+  int *next_lk_ahds_len)
 {
struct ath10k *ar = htc->ar;
int status = 0;
@@ -272,6 +336,28 @@ int ath10k_htc_process_trailer(struct ath10k_htc *htc,
 record->hdr.len,
 src_eid);
break;
+   case ATH10K_HTC_RECORD_LOOKAHEAD:
+   len = sizeof(struct ath10k_htc_lookahead_report);
+   if (record->hdr.len < len) {
+   ath10k_warn(ar, "Lookahead report too long\n");
+   status = -EINVAL;
+   break;
+   }
+   status = ath10k_htc_process_lookahead(htc,
+ 
record->lkahd_report,
+ record->hdr.len,
+ src_eid,
+ next_lk_ahds,
+ next_lk_ahds_len);
+   break;
+   case ATH10K_HTC_RECORD_LOOKAHEAD_BUNDLE:
+   status = ath10k_htc_process_lookahead_bundle(htc,
+
record->lkahd_bundle,
+
record->hdr.len,
+src_eid,
+
next_lk_ahds,
+
next_lk_ahds_len);
+   break;
 

Re: [PATCH] rtl8xxxu: Fix failure to reconnect to AP

2016-11-14 Thread Jes Sorensen
Barry Day  writes:
> On Mon, Nov 14, 2016 at 08:24:45AM -0500, Jes Sorensen wrote:
>> Barry Day  writes:
>> > The rtl8192e and rtl8723 fail to reconnect to an AP after being
>> > disconnected. Ths patch fixes that without affecting the rtl8192cu.
>> > I don't have a rtl8723 to test but it has been tested on a rtl8192eu.
>> > After going through the orginal realtek code for the rtl8723, I am
>> > confident the patch is applicable to both.
>> >
>> > Signed-off-by: Barry Day 
>> > ---
>> >  rtl8xxxu_core.c | 18 ++
>> >  1 file changed, 14 insertions(+), 4 deletions(-)
>> 
>> Hi Barry,
>> 
>> Thank you for the patch. There are a couple of items which I am not
>> 100% sure about the order of.
>> 
>> > diff --git a/rtl8xxxu_core.c b/rtl8xxxu_core.c
>> > index 04141e5..6ac10d2 100644
>> > --- a/rtl8xxxu_core.c
>> > +++ b/rtl8xxxu_core.c
>> > @@ -4372,17 +4372,25 @@ void rtl8xxxu_gen1_report_connect(struct 
>> > rtl8xxxu_priv *priv,
>> >  void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
>> >  u8 macid, bool connect)
>> >  {
>> > +  u8 val8;
>> >struct h2c_cmd h2c;
>> >  
>> >memset(, 0, sizeof(struct h2c_cmd));
>> >  
>> >h2c.media_status_rpt.cmd = H2C_8723B_MEDIA_STATUS_RPT;
>> > -  if (connect)
>> > +  if (connect) {
>> >h2c.media_status_rpt.parm |= BIT(0);
>> > -  else
>> > -  h2c.media_status_rpt.parm &= ~BIT(0);
>> > +  rtl8xxxu_gen2_h2c_cmd(priv, ,
>> > +  sizeof(h2c.media_status_rpt));
>> > +  } else {
>> > +  val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
>> > +  val8 &= ~BEACON_FUNCTION_ENABLE;
>> > +
>> > +  rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
>> > +  rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x00);
>> > +  rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
>> > +  }
>> >  
>> > -  rtl8xxxu_gen2_h2c_cmd(priv, , sizeof(h2c.media_status_rpt));
>> >  }
>> 
>> This only affects 8192eu and not 8192cu - we left RXFLTMAP2 out of here
>> on purpose for monitor mode, but you now disable it for 8192eu/8723bu.
>
> Even in monitor mode the interface has to brought up to use it which invokes
> rtl8xxxu_start which sets it back to accepting frames.
>
>
>> >  void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
>> > @@ -4515,6 +4523,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, 
>> > struct ieee80211_vif *vif,
>> >sgi = 1;
>> >rcu_read_unlock();
>> >  
>> > +  rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x);
>> > +
>> >priv->fops->update_rate_mask(priv, ramask, sgi);
>> >  
>> >rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
>> 
>> Here you enable RXFLTMAP2 for all devices - this doesn't balance with
>> the above.
>
> The original realtek code I have for the 8192cu does the disconnect the
> same way as in this patch. I tested the 8192cu using the patched
> gen2_report connect and it works. That would make things consistent across
> all chipsets.

My concern is that you only set FLATMAP and BEACON_CTRL for gen2
devices, which has zero impact on gen1 devices, such as the 8192cu. If
need to do this for gen2 (8723bu/8192eu) I assume we need to do it for
gen1 as well.

I'd like to see us do a little more investigating on this first.

Jes


Re: [PATCH] rtl8xxxu: Fix failure to reconnect to AP

2016-11-14 Thread Barry Day
On Mon, Nov 14, 2016 at 08:24:45AM -0500, Jes Sorensen wrote:
> Barry Day  writes:
> > The rtl8192e and rtl8723 fail to reconnect to an AP after being
> > disconnected. Ths patch fixes that without affecting the rtl8192cu.
> > I don't have a rtl8723 to test but it has been tested on a rtl8192eu.
> > After going through the orginal realtek code for the rtl8723, I am
> > confident the patch is applicable to both.
> >
> > Signed-off-by: Barry Day 
> > ---
> >  rtl8xxxu_core.c | 18 ++
> >  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> Hi Barry,
> 
> Thank you for the patch. There are a couple of items which I am not
> 100% sure about the order of.
> 
> > diff --git a/rtl8xxxu_core.c b/rtl8xxxu_core.c
> > index 04141e5..6ac10d2 100644
> > --- a/rtl8xxxu_core.c
> > +++ b/rtl8xxxu_core.c
> > @@ -4372,17 +4372,25 @@ void rtl8xxxu_gen1_report_connect(struct 
> > rtl8xxxu_priv *priv,
> >  void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
> >   u8 macid, bool connect)
> >  {
> > +   u8 val8;
> > struct h2c_cmd h2c;
> >  
> > memset(, 0, sizeof(struct h2c_cmd));
> >  
> > h2c.media_status_rpt.cmd = H2C_8723B_MEDIA_STATUS_RPT;
> > -   if (connect)
> > +   if (connect) {
> > h2c.media_status_rpt.parm |= BIT(0);
> > -   else
> > -   h2c.media_status_rpt.parm &= ~BIT(0);
> > +   rtl8xxxu_gen2_h2c_cmd(priv, ,
> > +   sizeof(h2c.media_status_rpt));
> > +   } else {
> > +   val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
> > +   val8 &= ~BEACON_FUNCTION_ENABLE;
> > +
> > +   rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
> > +   rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x00);
> > +   rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
> > +   }
> >  
> > -   rtl8xxxu_gen2_h2c_cmd(priv, , sizeof(h2c.media_status_rpt));
> >  }
> 
> This only affects 8192eu and not 8192cu - we left RXFLTMAP2 out of here
> on purpose for monitor mode, but you now disable it for 8192eu/8723bu.
> 

Even in monitor mode the interface has to brought up to use it which invokes
rtl8xxxu_start which sets it back to accepting frames.


> >  void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
> > @@ -4515,6 +4523,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, 
> > struct ieee80211_vif *vif,
> > sgi = 1;
> > rcu_read_unlock();
> >  
> > +   rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x);
> > +
> > priv->fops->update_rate_mask(priv, ramask, sgi);
> >  
> > rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
> 
> Here you enable RXFLTMAP2 for all devices - this doesn't balance with
> the above.
> 

The original realtek code I have for the 8192cu does the disconnect the
same way as in this patch. I tested the 8192cu using the patched
gen2_report connect and it works. That would make things consistent across
all chipsets.




Re: [RFC] change mac80211_hwsim tx_rates to ieee80211_tx_rate

2016-11-14 Thread Johannes Berg

> Mhh, I thought also some atheros drivers implement hardware multirate
> retry changes, which maps to this struct. Only one rate per frame
> would introduce a extreme additional communication overhead, which
> will make testing with standard wmediumd impractical. I think we need
> to keep such a structure, but we should align that with other
> mac80211 depended drivers.

Yeah, I was being imprecise. The driver interface is usually similar to
the mac80211 struct in one way or another (though it might also be a
more global table, like other drivers implement).

I was more thinking of the actual air interface. I'm not too worried
about the efficiency of this (we can push quite a few gbps over hwsim
today iirc), but it actually doesn't make sense because an accurate
simulation would require NAV/TXOP simulation, and that wouldn't be
possible with "software retry".

So I think our best bet remains to map this to new attributes - better
with properly formatted ones etc. than with the struct (keeping that
only for compatibility)

If you're worried about the overhead, we could consider converting
hwsim to use the rate_table API - see struct ieee80211_sta -> rates,
and maybe adding a signal to update that in the driver, send that to
userspace directly and work with that, rather than "serializing" the
table for every frame?

johannes


Re: [RFC] change mac80211_hwsim tx_rates to ieee80211_tx_rate

2016-11-14 Thread Benjamin Beichler
> I agree with that, but there exist also other code in hwsim, which is
>> tightly coupled with the mac80211 API, as e.g., the usage of
>> IEEE80211_TX_MAX_RATES, which already broke older versions of
>> wmediumd or similar implementations. Maybe a review regarding such
>> things would be good to decouple the userspace daemon from the
>> special kernel version.
> Agree. It'd be better if that were using nested attributes etc.
> Although then again, to really decouple this we should make hwsim
> behave towards wmediumd more like real hardware would, and have it pass
> just a single rate to userspace, with only success/fail indication
> coming back - if it fails, it could walk down the chain of rates
> itself. Right now we let wmediumd do this, which is why we have all
> these API internals exposed to it.
Mhh, I thought also some atheros drivers implement hardware multirate
retry changes, which maps to this struct. Only one rate per frame would
introduce a extreme additional communication overhead, which will make
testing with standard wmediumd impractical. I think we need to keep such
a structure, but we should align that with other mac80211 depended drivers.
>
 but I think that will break up the communication to e.g. bob
 copelands
 wmediumd and similar simulations. I would like to have our
 Implementation working with mainline kernels and therefore ask
 how we
 could achieve this easily.

 Obviously, we could define another field in the hwsim messages,
 but
 as bob copeland already stated, significantly more information
 within
 the netlink messages could  intensify the timing overhead of
 hwsim.
>>> I don't think we have any other choice but add the relevant fields
>>> as
>>> proper attributes.
>> I'm totally fine with that. Nonetheless,  I would suggest to add the
>> flags to "struct hwsim_tx_rate", since the flags are also tightly
>> coupled to the rates and tries of a frame. To not break up things, we
>> could add the flags as a separate attribute in the struct and not as
>> part of the bitfield like in the original. This would be possible,
>> due
>> to the "__packed" flag, but I'm also unsure, whether this is a really
>> good idea for a userspace API/ABI.
> Changing the struct size itself would break ABI though?

You are totally right ... I was a bit absent. But the point is, without
the rates and tries, the flags are useless, so I think it is better to
put them together, but I'm also fine with another attribute ;-)


Benjamin




[RFC 2/2] ath9k: Reset chip on potential deaf state

2016-11-14 Thread Sven Eckelmann
From: Simon Wunderlich 

The chip is switching seemingly random into a state which can be described
as "deaf". No or nearly no interrupts are generated anymore for incoming
packets. Existing links either break down after a while and new links will
not be established.

The driver doesn't know if there is no other device available or if it
ended up in an "deaf" state. Resetting the chip proactively avoids
permanent problems in case the chip really was in its "deaf" state but
maybe causes unnecessary resets in case it wasn't "deaf".

Signed-off-by: Simon Wunderlich 
[sven.eckelm...@open-mesh.com: port to recent ath9k, add commit message]
Signed-off-by: Sven Eckelmann 
---
This problem was discovered in mesh setups. It was noticed that some nodes
were not able to see their neighbors (mostly after running for a while) -
even when those neighbors received data from them via IBSS. A simple `iw
dev wlan0 scan` fixed the problem for them. But the problem seems to
reappear after while(tm) in a large enough(tm) mesh.

This patch is a little bit obscure because it requires CONFIG_ATH9K_DEBUGFS
to actually work. But there still seems to be potential interest in
Freifunk communities or Freifunk meta-projects (e.g. freifunk-gluon). It is
currently not known if it helps them but publishing this to allow them to
test and play around with it will not hurt :)
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  3 +++
 drivers/net/wireless/ath/ath9k/debug.c |  1 +
 drivers/net/wireless/ath/ath9k/debug.h |  1 +
 drivers/net/wireless/ath/ath9k/link.c  | 45 ++
 4 files changed, 50 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index 9c6fee7..3987ad5 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -996,6 +996,9 @@ struct ath_softc {
short nbcnvifs;
unsigned long ps_usecount;
 
+   unsigned long last_check_time;
+   u32 last_check_interrupts;
+
struct ath_rx rx;
struct ath_tx tx;
struct ath_beacon beacon;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c 
b/drivers/net/wireless/ath/ath9k/debug.c
index 608b370..6d5c253 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -768,6 +768,7 @@ static int read_file_reset(struct seq_file *file, void 
*data)
[RESET_TX_DMA_ERROR] = "Tx DMA stop error",
[RESET_RX_DMA_ERROR] = "Rx DMA stop error",
[RESET_TYPE_DEADBEEF] = "deadbeef hang",
+   [RESET_TYPE_DEAF] = "deaf hang",
};
int i;
 
diff --git a/drivers/net/wireless/ath/ath9k/debug.h 
b/drivers/net/wireless/ath/ath9k/debug.h
index 0d77abbf6..6f186bd 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -53,6 +53,7 @@ enum ath_reset_type {
RESET_TX_DMA_ERROR,
RESET_RX_DMA_ERROR,
RESET_TYPE_DEADBEEF,
+   RESET_TYPE_DEAF,
__RESET_TYPE_MAX
 };
 
diff --git a/drivers/net/wireless/ath/ath9k/link.c 
b/drivers/net/wireless/ath/ath9k/link.c
index ff11d85..f4b74b7 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -158,6 +158,48 @@ static bool ath_hw_hang_deadbeef(struct ath_softc *sc)
return true;
 }
 
+static bool ath_hw_hang_deaf(struct ath_softc *sc)
+{
+#ifndef CONFIG_ATH9K_DEBUGFS
+   return false;
+#else
+   struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+   u32 interrupts, interrupt_per_s;
+   unsigned int interval;
+
+   /* get historic data */
+   interval = jiffies_to_msecs(jiffies - sc->last_check_time);
+   if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+   interrupts = sc->debug.stats.istats.rxlp;
+   else
+   interrupts = sc->debug.stats.istats.rxok;
+
+   interrupts -= sc->last_check_interrupts;
+
+   /* save current data */
+   sc->last_check_time = jiffies;
+   if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+   sc->last_check_interrupts = sc->debug.stats.istats.rxlp;
+   else
+   sc->last_check_interrupts = sc->debug.stats.istats.rxok;
+
+   /* sanity check, should be 30 seconds */
+   if (interval > 4 || interval < 2)
+   return false;
+
+   /* should be at least one interrupt per second */
+   interrupt_per_s = interrupts / (interval / 1000);
+   if (interrupt_per_s >= 1)
+   return false;
+
+   ath_dbg(common, RESET,
+   "RX deaf hang is detected. Schedule chip reset\n");
+   ath9k_queue_reset(sc, RESET_TYPE_DEAF);
+
+   return true;
+#endif
+}
+
 void ath_hw_hang_work(struct work_struct *work)
 {
struct ath_softc *sc = container_of(work, struct ath_softc,
@@ -166,6 +208,9 @@ void 

[RFC 1/2] ath9k: work around AR_CFG 0xdeadbeef chip hang

2016-11-14 Thread Sven Eckelmann
From: Simon Wunderlich 

QCA 802.11n chips (especially AR9330/AR9340) sometimes end up in a state in
which a read of AR_CFG always returns 0xdeadbeef. This should not happen
when when the power_mode of the device is ATH9K_PM_AWAKE.

This problem is not yet detected by any other workaround in ath9k. No way
is known to reproduce the problem easily.

Signed-off-by: Simon Wunderlich 
[sven.eckelm...@open-mesh.com: port to recent ath9k, add commit message]
Signed-off-by: Sven Eckelmann 
---
This was discussed 4 years ago on the OpenWrt mailing list. The most
relevant post is
https://lists.openwrt.org/pipermail/openwrt-devel/2012-September/016708.html
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  3 +++
 drivers/net/wireless/ath/ath9k/debug.c |  1 +
 drivers/net/wireless/ath/ath9k/debug.h |  1 +
 drivers/net/wireless/ath/ath9k/init.c  |  1 +
 drivers/net/wireless/ath/ath9k/link.c  | 33 +
 drivers/net/wireless/ath/ath9k/main.c  |  4 
 6 files changed, 43 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h 
b/drivers/net/wireless/ath/ath9k/ath9k.h
index 26fc8ec..9c6fee7 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -710,11 +710,13 @@ void ath9k_csa_update(struct ath_softc *sc);
 #define ATH_ANI_MAX_SKIP_COUNT10
 #define ATH_PAPRD_TIMEOUT 100 /* msecs */
 #define ATH_PLL_WORK_INTERVAL 100
+#define ATH_HANG_WORK_INTERVAL3
 
 void ath_tx_complete_poll_work(struct work_struct *work);
 void ath_reset_work(struct work_struct *work);
 bool ath_hw_check(struct ath_softc *sc);
 void ath_hw_pll_work(struct work_struct *work);
+void ath_hw_hang_work(struct work_struct *work);
 void ath_paprd_calibrate(struct work_struct *work);
 void ath_ani_calibrate(unsigned long data);
 void ath_start_ani(struct ath_softc *sc);
@@ -1014,6 +1016,7 @@ struct ath_softc {
 #endif
struct delayed_work tx_complete_work;
struct delayed_work hw_pll_work;
+   struct delayed_work hw_hang_work;
struct timer_list sleep_timer;
 
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
diff --git a/drivers/net/wireless/ath/ath9k/debug.c 
b/drivers/net/wireless/ath/ath9k/debug.c
index c56e40f..608b370 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -767,6 +767,7 @@ static int read_file_reset(struct seq_file *file, void 
*data)
[RESET_TYPE_CALIBRATION] = "Calibration error",
[RESET_TX_DMA_ERROR] = "Tx DMA stop error",
[RESET_RX_DMA_ERROR] = "Rx DMA stop error",
+   [RESET_TYPE_DEADBEEF] = "deadbeef hang",
};
int i;
 
diff --git a/drivers/net/wireless/ath/ath9k/debug.h 
b/drivers/net/wireless/ath/ath9k/debug.h
index cd68c5f..0d77abbf6 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -52,6 +52,7 @@ enum ath_reset_type {
RESET_TYPE_CALIBRATION,
RESET_TX_DMA_ERROR,
RESET_RX_DMA_ERROR,
+   RESET_TYPE_DEADBEEF,
__RESET_TYPE_MAX
 };
 
diff --git a/drivers/net/wireless/ath/ath9k/init.c 
b/drivers/net/wireless/ath/ath9k/init.c
index 368d9b3..9bc7d1c 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -638,6 +638,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
INIT_WORK(>hw_reset_work, ath_reset_work);
INIT_WORK(>paprd_work, ath_paprd_calibrate);
INIT_DELAYED_WORK(>hw_pll_work, ath_hw_pll_work);
+   INIT_DELAYED_WORK(>hw_hang_work, ath_hw_hang_work);
 
ath9k_init_channel_context(sc);
 
diff --git a/drivers/net/wireless/ath/ath9k/link.c 
b/drivers/net/wireless/ath/ath9k/link.c
index 5ad0fee..ff11d85 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -138,6 +138,39 @@ void ath_hw_pll_work(struct work_struct *work)
 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
 }
 
+static bool ath_hw_hang_deadbeef(struct ath_softc *sc)
+{
+   struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+   u32 reg;
+
+   /* check for stucked MAC */
+   ath9k_ps_wakeup(sc);
+   reg = REG_READ(sc->sc_ah, AR_CFG);
+   ath9k_ps_restore(sc);
+
+   if (reg != 0xdeadbeef)
+   return false;
+
+   ath_dbg(common, RESET,
+   "0xdeadbeef hang is detected. Schedule chip reset\n");
+   ath9k_queue_reset(sc, RESET_TYPE_DEADBEEF);
+
+   return true;
+}
+
+void ath_hw_hang_work(struct work_struct *work)
+{
+   struct ath_softc *sc = container_of(work, struct ath_softc,
+   hw_hang_work.work);
+
+   if (ath_hw_hang_deadbeef(sc))
+   goto requeue_worker;
+
+requeue_worker:
+   ieee80211_queue_delayed_work(sc->hw, >hw_hang_work,
+

Re: [RFC] change mac80211_hwsim tx_rates to ieee80211_tx_rate

2016-11-14 Thread Johannes Berg

> I agree with that, but there exist also other code in hwsim, which is
> tightly coupled with the mac80211 API, as e.g., the usage of
> IEEE80211_TX_MAX_RATES, which already broke older versions of
> wmediumd or similar implementations. Maybe a review regarding such
> things would be good to decouple the userspace daemon from the
> special kernel version.

Agree. It'd be better if that were using nested attributes etc.
Although then again, to really decouple this we should make hwsim
behave towards wmediumd more like real hardware would, and have it pass
just a single rate to userspace, with only success/fail indication
coming back - if it fails, it could walk down the chain of rates
itself. Right now we let wmediumd do this, which is why we have all
these API internals exposed to it.

> > > but I think that will break up the communication to e.g. bob
> > > copelands
> > > wmediumd and similar simulations. I would like to have our
> > > Implementation working with mainline kernels and therefore ask
> > > how we
> > > could achieve this easily.
> > > 
> > > Obviously, we could define another field in the hwsim messages,
> > > but
> > > as bob copeland already stated, significantly more information
> > > within
> > > the netlink messages could  intensify the timing overhead of
> > > hwsim.
> > I don't think we have any other choice but add the relevant fields
> > as
> > proper attributes.
> 
> I'm totally fine with that. Nonetheless,  I would suggest to add the
> flags to "struct hwsim_tx_rate", since the flags are also tightly
> coupled to the rates and tries of a frame. To not break up things, we
> could add the flags as a separate attribute in the struct and not as
> part of the bitfield like in the original. This would be possible,
> due
> to the "__packed" flag, but I'm also unsure, whether this is a really
> good idea for a userspace API/ABI.

Changing the struct size itself would break ABI though?

johannes


[PATCH] ath10k: add spectral scan support to wmi-tlv

2016-11-14 Thread Michal Kazior
Command structure and event flow doesn't seem to
be any different compared to existing
implementation for other firmware branches.

This patch effectively adds in-driver support for
spectral scanning on QCA61x4 and QCA9377.

Tested QCA9377 w/ WLAN.TF.1.0-00267-1.

Signed-off-by: Michal Kazior 
---
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 72 +++
 1 file changed, 72 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c 
b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index e64f59300a7c..7f9b1185b549 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -3136,6 +3136,76 @@ ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value)
return skb;
 }
 
+static struct sk_buff *
+ath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar,
+const struct 
wmi_vdev_spectral_conf_arg *arg)
+{
+   struct wmi_vdev_spectral_conf_cmd *cmd;
+   struct sk_buff *skb;
+   struct wmi_tlv *tlv;
+   void *ptr;
+   size_t len;
+
+   len = sizeof(*tlv) + sizeof(*cmd);
+   skb = ath10k_wmi_alloc_skb(ar, len);
+   if (!skb)
+   return ERR_PTR(-ENOMEM);
+
+   ptr = (void *)skb->data;
+   tlv = ptr;
+   tlv->tag = 
__cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD);
+   tlv->len = __cpu_to_le16(sizeof(*cmd));
+   cmd = (void *)tlv->value;
+   cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
+   cmd->scan_count = __cpu_to_le32(arg->scan_count);
+   cmd->scan_period = __cpu_to_le32(arg->scan_period);
+   cmd->scan_priority = __cpu_to_le32(arg->scan_priority);
+   cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size);
+   cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena);
+   cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena);
+   cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref);
+   cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay);
+   cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr);
+   cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr);
+   cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode);
+   cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode);
+   cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr);
+   cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format);
+   cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode);
+   cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale);
+   cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
+   cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
+
+   return skb;
+}
+
+static struct sk_buff *
+ath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
+  u32 trigger, u32 enable)
+{
+   struct wmi_vdev_spectral_enable_cmd *cmd;
+   struct sk_buff *skb;
+   struct wmi_tlv *tlv;
+   void *ptr;
+   size_t len;
+
+   len = sizeof(*tlv) + sizeof(*cmd);
+   skb = ath10k_wmi_alloc_skb(ar, len);
+   if (!skb)
+   return ERR_PTR(-ENOMEM);
+
+   ptr = (void *)skb->data;
+   tlv = ptr;
+   tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD);
+   tlv->len = __cpu_to_le16(sizeof(*cmd));
+   cmd = (void *)tlv->value;
+   cmd->vdev_id = __cpu_to_le32(vdev_id);
+   cmd->trigger_cmd = __cpu_to_le32(trigger);
+   cmd->enable_cmd = __cpu_to_le32(enable);
+
+   return skb;
+}
+
 //
 /* TLV mappings */
 //
@@ -3542,6 +3612,8 @@ static const struct wmi_ops wmi_tlv_ops = {
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
+   .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
+   .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
 };
 
 static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
-- 
2.1.4



[PATCH] ath10k: fix null deref on wmi-tlv when trying spectral scan

2016-11-14 Thread Michal Kazior
WMI ops wrappers did not properly check for null
function pointers for spectral scan. This caused
null dereference crash with WMI-TLV based firmware
which doesn't implement spectral scan.

The crash could be triggered with:

  ip link set dev wlan0 up
  echo background > /sys/kernel/debug/ieee80211/phy0/ath10k/spectral_scan_ctl

The crash looked like this:

  [  168.031989] BUG: unable to handle kernel NULL pointer dereference at   
(null)
  [  168.037406] IP: [<  (null)>]   (null)
  [  168.040395] PGD cdd4067 PUD fa0f067 PMD 0
  [  168.043303] Oops: 0010 [#1] SMP
  [  168.045377] Modules linked in: ath10k_pci(O) ath10k_core(O) ath mac80211 
cfg80211 [last unloaded: cfg80211]
  [  168.051560] CPU: 1 PID: 1380 Comm: bash Tainted: GW  O4.8.0 #78
  [  168.054336] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
1.7.5-20140531_083030-gandalf 04/01/2014
  [  168.059183] task: 88000c460c00 task.stack: 88000d4bc000
  [  168.061736] RIP: 0010:[<>]  [<  (null)>]   
(null)
  ...
  [  168.100620] Call Trace:
  [  168.101910]  [] ? ath10k_spectral_scan_config+0x96/0x200 
[ath10k_core]
  [  168.104871]  [] ? filemap_fault+0xb2/0x4a0
  [  168.106696]  [] write_file_spec_scan_ctl+0x116/0x280 
[ath10k_core]
  [  168.109618]  [] full_proxy_write+0x51/0x80
  [  168.111443]  [] __vfs_write+0x28/0x120
  [  168.113090]  [] ? security_file_permission+0x3d/0xc0
  [  168.114932]  [] ? percpu_down_read+0x12/0x60
  [  168.116680]  [] vfs_write+0xb8/0x1a0
  [  168.118293]  [] SyS_write+0x46/0xa0
  [  168.119912]  [] entry_SYSCALL_64_fastpath+0x1a/0xa4
  [  168.121737] Code:  Bad RIP value.
  [  168.123318] RIP  [<  (null)>]   (null)

Signed-off-by: Michal Kazior 
---
 drivers/net/wireless/ath/ath10k/wmi-ops.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h 
b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index c9a8bb1186f2..c7956e181f80 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -660,6 +660,9 @@ ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
struct sk_buff *skb;
u32 cmd_id;
 
+   if (!ar->wmi.ops->gen_vdev_spectral_conf)
+   return -EOPNOTSUPP;
+
skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg);
if (IS_ERR(skb))
return PTR_ERR(skb);
@@ -675,6 +678,9 @@ ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 
vdev_id, u32 trigger,
struct sk_buff *skb;
u32 cmd_id;
 
+   if (!ar->wmi.ops->gen_vdev_spectral_enable)
+   return -EOPNOTSUPP;
+
skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger,
enable);
if (IS_ERR(skb))
-- 
2.1.4



Re: [PATCH] rtl8xxxu: Fix failure to reconnect to AP

2016-11-14 Thread Jes Sorensen
Barry Day  writes:
> The rtl8192e and rtl8723 fail to reconnect to an AP after being
> disconnected. Ths patch fixes that without affecting the rtl8192cu.
> I don't have a rtl8723 to test but it has been tested on a rtl8192eu.
> After going through the orginal realtek code for the rtl8723, I am
> confident the patch is applicable to both.
>
> Signed-off-by: Barry Day 
> ---
>  rtl8xxxu_core.c | 18 ++
>  1 file changed, 14 insertions(+), 4 deletions(-)

Hi Barry,

Thank you for the patch. There are a couple of items which I am not
100% sure about the order of.

> diff --git a/rtl8xxxu_core.c b/rtl8xxxu_core.c
> index 04141e5..6ac10d2 100644
> --- a/rtl8xxxu_core.c
> +++ b/rtl8xxxu_core.c
> @@ -4372,17 +4372,25 @@ void rtl8xxxu_gen1_report_connect(struct 
> rtl8xxxu_priv *priv,
>  void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
> u8 macid, bool connect)
>  {
> + u8 val8;
>   struct h2c_cmd h2c;
>  
>   memset(, 0, sizeof(struct h2c_cmd));
>  
>   h2c.media_status_rpt.cmd = H2C_8723B_MEDIA_STATUS_RPT;
> - if (connect)
> + if (connect) {
>   h2c.media_status_rpt.parm |= BIT(0);
> - else
> - h2c.media_status_rpt.parm &= ~BIT(0);
> + rtl8xxxu_gen2_h2c_cmd(priv, ,
> + sizeof(h2c.media_status_rpt));
> + } else {
> + val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
> + val8 &= ~BEACON_FUNCTION_ENABLE;
> +
> + rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
> + rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x00);
> + rtl8xxxu_write8(priv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
> + }
>  
> - rtl8xxxu_gen2_h2c_cmd(priv, , sizeof(h2c.media_status_rpt));
>  }

This only affects 8192eu and not 8192cu - we left RXFLTMAP2 out of here
on purpose for monitor mode, but you now disable it for 8192eu/8723bu.

>  void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
> @@ -4515,6 +4523,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, 
> struct ieee80211_vif *vif,
>   sgi = 1;
>   rcu_read_unlock();
>  
> + rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x);
> +
>   priv->fops->update_rate_mask(priv, ramask, sgi);
>  
>   rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);

Here you enable RXFLTMAP2 for all devices - this doesn't balance with
the above.

I am not against the aproach, but I think we need to investigate a
little further what is going on.

Cheers,
Jes


RE: [ath9k-devel] [NOT FOR MERGE] ath9k: work around key cache corruption

2016-11-14 Thread Stam, Michel [FINT]
Dear List,

After 2 weeks of Ferry Huberts and me trying to resolve this issue, this is the 
result:
The problem can be mitigated by resetting the chip and immediately replumbing 
the encryption keys. I wrote a patch for this, which unfortunately this seems 
to suffer from some locking issues, rtnl_lock and sc->mutex being the chief 
culprits.

Code snippet:
static void ath9k_plumb_key(struct ieee80211_hw *hw,
   struct ieee80211_vif *vif,
   struct ieee80211_sta *sta,
   struct ieee80211_key_conf *keyconf, void *data)
{
   struct ath_common *common = (struct ath_common *)data;
   int ret;

   /* delete and re-install keys which were programmed into the hardware */
   if (vif && test_bit(keyconf->hw_key_idx, common->keymap)) {
   ath_key_delete(common, keyconf);
   keyconf->hw_key_idx = 0;
   ret = ath_key_config(common, vif, sta, keyconf);
   if (ret >= 0)
   keyconf->hw_key_idx = ret;
   }
}

To reset and replumb, taken from ath_reset_internal():
ath9k_hw_kill_interrupts(sc->sc_ah);
set_bit(ATH_OP_HW_RESET, >op_flags);
ath9k_ps_wakeup(sc);
ath_reset_internal(sc, NULL);
rtnl_lock();
ieee80211_iter_keys(sc->hw, NULL, ath9k_plumb_key, common);
rtnl_unlock();
ath9k_ps_restore(sc);

In any case, the problem is only mitigated. It is not solved, as I see the 
error appearing still (less frequently though).
Looking at the OpenHAL has not yielded anything working either (there is a 
reference to KEY_PLUMB_WAR, but it is not a full implementation).

What I understand from previous attempts to tackle this issue is that Qualcomm 
is aware of the problem, and a workaround exists in at least the proprietary 
driver. I have tried to contact Qualcomm support about this, since it is not 
radio card specific, but I have not received any response so far.

I hope a Qualcomm employee reads this and is able to help obtain the 
information that is necessary to resolve this issue. Until then, I recommend 
using software encryption (nohwcrypt), or setting a very long rekeying time.

Kind regards,

Michel Stam
-Original Message-
From: ath9k-devel-boun...@lists.ath9k.org 
[mailto:ath9k-devel-boun...@lists.ath9k.org] On Behalf Of Johannes Berg
Sent: Thursday, October 27, 2016 17:07 PM
To: Sebastian Gottschall; Kalle Valo; Antonio Quartulli
Cc: ath9k-de...@lists.ath9k.org; linux-wireless@vger.kernel.org; Antonio 
Quartulli
Subject: Re: [ath9k-devel] [NOT FOR MERGE] ath9k: work around key cache 
corruption

On Thu, 2016-10-27 at 09:54 +0200, Sebastian Gottschall wrote:
> all patches have a unclear license since most patches are not comming
> with any licence declaration ;-)

You should read the DCO some time. Maybe you shouldn't be sending
patches if you think so.

johannes
___
ath9k-devel mailing list
ath9k-de...@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel



RE: [bug report] iwlwifi: mvm: use dev_coredumpsg()

2016-11-14 Thread Erenfeld, Aviya
Thanks,

Right, we already have a pending fix for that one.

Aviya

-Original Message-
From: Dan Carpenter [mailto:dan.carpen...@oracle.com] 
Sent: Monday, November 14, 2016 13:21
To: Erenfeld, Aviya 
Cc: linux-wireless@vger.kernel.org
Subject: [bug report] iwlwifi: mvm: use dev_coredumpsg()

Hello Aviya Erenfeld,

The patch 7e62a699aafb: "iwlwifi: mvm: use dev_coredumpsg()" from Sep 20, 2016, 
leads to the following static checker warning:

drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c:821 
iwl_mvm_fw_error_dump()
error: we previously assumed 'fw_error_dump->trans_ptr' could be null 
(see line 809)

drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
   805  dump_trans_data:
   806  fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans,
   807 
mvm->fw_dump_trig);
   808  fw_error_dump->op_mode_len = file_len;
   809  if (fw_error_dump->trans_ptr)
   810  file_len += fw_error_dump->trans_ptr->len;

We assume ->trans_ptr can be NULL.

   811  dump_file->file_len = cpu_to_le32(file_len);
   812  
   813  sg_dump_data = alloc_sgtable(file_len);

That probably means file_len is zero?  (didn't look).  That means sg_dump_data 
is ZERO_SIZE_PTR (16).

   814  if (sg_dump_data) {
   815  sg_pcopy_from_buffer(sg_dump_data,
   816   sg_nents(sg_dump_data),
   817   fw_error_dump->op_mode_ptr,
   818   fw_error_dump->op_mode_len, 0);
   819  sg_pcopy_from_buffer(sg_dump_data,
   820   sg_nents(sg_dump_data),
   821   fw_error_dump->trans_ptr->data,

Leading to an oops.

   822   fw_error_dump->trans_ptr->len,
   823   fw_error_dump->op_mode_len);
   824  dev_coredumpsg(mvm->trans->dev, sg_dump_data, file_len,
   825 GFP_KERNEL);
   826  }
   827  vfree(fw_error_dump->op_mode_ptr);
   828  vfree(fw_error_dump->trans_ptr);
   829  kfree(fw_error_dump);
   830  
   831  out:
   832  iwl_mvm_free_fw_dump_desc(mvm);
   833  mvm->fw_dump_trig = NULL;
   834  clear_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, >status);
   835  }

regards,
dan carpenter
-
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.



[PATCH v3 1/3] mwifiex: Allow mwifiex early access to device structure

2016-11-14 Thread Amitkumar Karwar
From: Rajat Jain 

Today all the interface drivers (usb/pcie/sdio) assign the
adapter->dev in the register_dev() callback, although they
have this piece of info well before hand.

This patch makes the device structure available for mwifiex
right at the beginning, so that it can be used for early
initialization if needed.

This is needed for subsequent patches in this patchset that
intend to unify and consolidate some of the code that would
otherwise have to be duplicated among the interface drivers
(sdio, pcie, usb).

Signed-off-by: Rajat Jain 
Signed-off-by: Amitkumar Karwar 
---
v2: Same as v1
v3: Fixed checkpatch warnings
WARNING: function definition argument 'void *' should also have an identifier 
name
#59: FILE: drivers/net/wireless/marvell/mwifiex/main.h:1415:
+int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8,

WARNING: function definition argument 'struct semaphore *' should also have an 
identifier name
#59: FILE: drivers/net/wireless/marvell/mwifiex/main.h:1415:
+int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8,

WARNING: function definition argument 'struct mwifiex_if_ops *' should also 
have an identifier name
#59: FILE: drivers/net/wireless/marvell/mwifiex/main.h:1415:
+int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8,

WARNING: function definition argument 'u8' should also have an identifier name
#59: FILE: drivers/net/wireless/marvell/mwifiex/main.h:1415:
+int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8,

WARNING: function definition argument 'struct device *' should also have an 
identifier name
#59: FILE: drivers/net/wireless/marvell/mwifiex/main.h:1415:
+int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8,
---
 drivers/net/wireless/marvell/mwifiex/main.c | 4 +++-
 drivers/net/wireless/marvell/mwifiex/main.h | 4 +++-
 drivers/net/wireless/marvell/mwifiex/pcie.c | 4 +---
 drivers/net/wireless/marvell/mwifiex/sdio.c | 5 +
 drivers/net/wireless/marvell/mwifiex/usb.c  | 3 +--
 5 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.c 
b/drivers/net/wireless/marvell/mwifiex/main.c
index 2478ccd..dcceab2 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1567,7 +1567,8 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool 
prepare)
  */
 int
 mwifiex_add_card(void *card, struct semaphore *sem,
-struct mwifiex_if_ops *if_ops, u8 iface_type)
+struct mwifiex_if_ops *if_ops, u8 iface_type,
+struct device *dev)
 {
struct mwifiex_adapter *adapter;
 
@@ -1579,6 +1580,7 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool 
prepare)
goto err_init_sw;
}
 
+   adapter->dev = dev;
adapter->iface_type = iface_type;
adapter->card_sem = sem;
 
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h 
b/drivers/net/wireless/marvell/mwifiex/main.h
index d61fe3a..549e1ba 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -1412,7 +1412,9 @@ static inline u8 mwifiex_is_tdls_link_setup(u8 status)
 
 int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
 u32 func_init_shutdown);
-int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
+int mwifiex_add_card(void *card, struct semaphore *sem,
+struct mwifiex_if_ops *if_ops, u8 iface_type,
+struct device *dev);
 int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
 
 void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c 
b/drivers/net/wireless/marvell/mwifiex/pcie.c
index fed6a1d..de6939c 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -231,7 +231,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
}
 
ret = mwifiex_add_card(card, _remove_card_sem, _ops,
-  MWIFIEX_PCIE);
+  MWIFIEX_PCIE, >dev);
if (ret) {
pr_err("%s failed\n", __func__);
goto err_free;
@@ -2999,11 +2999,9 @@ static void mwifiex_pcie_get_fw_name(struct 
mwifiex_adapter *adapter)
 static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
 {
struct pcie_service_card *card = adapter->card;
-   struct pci_dev *pdev = card->dev;
 
/* save adapter pointer in card */
card->adapter = adapter;
-   adapter->dev = >dev;
 
if (mwifiex_pcie_request_irq(adapter))
return -1;
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c 
b/drivers/net/wireless/marvell/mwifiex/sdio.c
index 807af13..c95f41f 100644
--- 

[PATCH v3 3/3] mwifiex: Enable WoWLAN for both sdio and pcie

2016-11-14 Thread Amitkumar Karwar
From: Rajat Jain 

Commit ce4f6f0c353b ("mwifiex: add platform specific wakeup interrupt
support") added WoWLAN feature only for sdio. This patch moves that
code to the common module so that all the interface drivers can use
it for free. It enables pcie and sdio for its use currently.

Signed-off-by: Rajat Jain 
---
v2: v1 doesn't apply smoothly on latest code due to recently merged
patch "mwifiex: report error to PCIe for suspend failure". Minor
conflict is resolved in v2
v3: Same as v2 
---
 drivers/net/wireless/marvell/mwifiex/main.c | 41 
 drivers/net/wireless/marvell/mwifiex/main.h | 25 ++
 drivers/net/wireless/marvell/mwifiex/pcie.c |  2 +
 drivers/net/wireless/marvell/mwifiex/sdio.c | 72 ++---
 drivers/net/wireless/marvell/mwifiex/sdio.h |  8 
 5 files changed, 73 insertions(+), 75 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.c 
b/drivers/net/wireless/marvell/mwifiex/main.c
index 835d330..948f5c2 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1552,14 +1552,55 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, 
bool prepare)
 }
 EXPORT_SYMBOL_GPL(mwifiex_do_flr);
 
+static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
+{
+   struct mwifiex_adapter *adapter = priv;
+
+   if (adapter->irq_wakeup >= 0) {
+   dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
+   adapter->wake_by_wifi = true;
+   disable_irq_nosync(irq);
+   }
+
+   /* Notify PM core we are wakeup source */
+   pm_wakeup_event(adapter->dev, 0);
+
+   return IRQ_HANDLED;
+}
+
 static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
 {
+   int ret;
struct device *dev = adapter->dev;
 
if (!dev->of_node)
return;
 
adapter->dt_node = dev->of_node;
+   adapter->irq_wakeup = irq_of_parse_and_map(adapter->dt_node, 0);
+   if (!adapter->irq_wakeup) {
+   dev_info(dev, "fail to parse irq_wakeup from device tree\n");
+   return;
+   }
+
+   ret = devm_request_irq(dev, adapter->irq_wakeup,
+  mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
+  "wifi_wake", adapter);
+   if (ret) {
+   dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
+   adapter->irq_wakeup, ret);
+   goto err_exit;
+   }
+
+   disable_irq(adapter->irq_wakeup);
+   if (device_init_wakeup(dev, true)) {
+   dev_err(dev, "fail to init wakeup for mwifiex\n");
+   goto err_exit;
+   }
+   return;
+
+err_exit:
+   adapter->irq_wakeup = 0;
 }
 
 /*
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h 
b/drivers/net/wireless/marvell/mwifiex/main.h
index 549e1ba..ae5afe5 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -1011,6 +1011,10 @@ struct mwifiex_adapter {
bool usb_mc_setup;
struct cfg80211_wowlan_nd_info *nd_info;
struct ieee80211_regdomain *regd;
+
+   /* Wake-on-WLAN (WoWLAN) */
+   int irq_wakeup;
+   bool wake_by_wifi;
 };
 
 void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
@@ -1410,6 +1414,27 @@ static inline u8 mwifiex_is_tdls_link_setup(u8 status)
return false;
 }
 
+/* Disable platform specific wakeup interrupt */
+static inline void mwifiex_disable_wake(struct mwifiex_adapter *adapter)
+{
+   if (adapter->irq_wakeup >= 0) {
+   disable_irq_wake(adapter->irq_wakeup);
+   if (!adapter->wake_by_wifi)
+   disable_irq(adapter->irq_wakeup);
+   }
+}
+
+/* Enable platform specific wakeup interrupt */
+static inline void mwifiex_enable_wake(struct mwifiex_adapter *adapter)
+{
+   /* Enable platform specific wakeup interrupt */
+   if (adapter->irq_wakeup >= 0) {
+   adapter->wake_by_wifi = false;
+   enable_irq(adapter->irq_wakeup);
+   enable_irq_wake(adapter->irq_wakeup);
+   }
+}
+
 int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
 u32 func_init_shutdown);
 int mwifiex_add_card(void *card, struct semaphore *sem,
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c 
b/drivers/net/wireless/marvell/mwifiex/pcie.c
index de6939c..7942b28 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -131,6 +131,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
}
 
adapter = card->adapter;
+   mwifiex_enable_wake(adapter);
 
/* Enable the Host Sleep */
if (!mwifiex_enable_hs(adapter)) {
@@ -186,6 +187,7 @@ static int mwifiex_pcie_resume(struct device *dev)
 
mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),

[PATCH v3 2/3] mwifiex: Introduce mwifiex_probe_of() to parse common properties

2016-11-14 Thread Amitkumar Karwar
From: Rajat Jain 

Introduce function mwifiex_probe_of() to parse common properties.
Interface drivers get to decide whether or not the device tree node
was a valid one (depending on the compatible property),
Lets fill "adapter->dt_node" in mwifiex_add_card().

The function mwifiex_probe_of() is currently only a place holder with
the next patch adding content to it.

Signed-off-by: Rajat Jain 
Signed-off-by: Amitkumar Karwar 
---
v2: Same as v1
v3: Redundant flag "of_node_valid" is removed (Brian)
---
 drivers/net/wireless/marvell/mwifiex/main.c| 12 
 drivers/net/wireless/marvell/mwifiex/sta_cmd.c |  5 +
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.c 
b/drivers/net/wireless/marvell/mwifiex/main.c
index dcceab2..835d330 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1552,6 +1552,16 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, 
bool prepare)
 }
 EXPORT_SYMBOL_GPL(mwifiex_do_flr);
 
+static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
+{
+   struct device *dev = adapter->dev;
+
+   if (!dev->of_node)
+   return;
+
+   adapter->dt_node = dev->of_node;
+}
+
 /*
  * This function adds the card.
  *
@@ -1581,6 +1591,8 @@ void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool 
prepare)
}
 
adapter->dev = dev;
+   mwifiex_probe_of(adapter);
+
adapter->iface_type = iface_type;
adapter->card_sem = sem;
 
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c 
b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index b697b61..bcd6408 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -2235,10 +2235,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, 
u8 first_sta, bool init)
 * The cal-data can be read from device tree and/or
 * a configuration file and downloaded to firmware.
 */
-   if ((priv->adapter->iface_type == MWIFIEX_SDIO ||
-   priv->adapter->iface_type == MWIFIEX_PCIE) &&
-   adapter->dev->of_node) {
-   adapter->dt_node = adapter->dev->of_node;
+   if (adapter->dt_node) {
if (of_property_read_u32(adapter->dt_node,
 "marvell,wakeup-pin",
 ) == 0) {
-- 
1.9.1



RE: [PATCH v2 2/3] mwifiex: Introduce mwifiex_probe_of() to parse common properties

2016-11-14 Thread Amitkumar Karwar
Hi Brian,

> From: Brian Norris [mailto:briannor...@chromium.org]
> Sent: Saturday, November 12, 2016 2:20 AM
> To: Amitkumar Karwar
> Cc: linux-wireless@vger.kernel.org; Cathy Luo; Nishant Sarmukadam;
> raja...@google.com; dmitry.torok...@gmail.com
> Subject: Re: [PATCH v2 2/3] mwifiex: Introduce mwifiex_probe_of() to
> parse common properties
> 
> On Fri, Nov 11, 2016 at 04:45:10PM +0530, Amitkumar Karwar wrote:
> > From: Rajat Jain 
> >
> > Introduce function mwifiex_probe_of() to parse common properties.
> > Since the interface drivers get to decide whether or not the device
> > tree node was a valid one (depending on the compatible property), let
> > the interface drivers pass a flag to indicate whether the device tree
> > node was a valid one.
> 
> Wait, what? I don't understand why this is needed. The current of_node
> user (SDIO) always checks dev->of_node (if !NULL), and if it's not
> matching, it rejects the device and doesn't even try to register the
> card at all. That's a common pattern for DT-based drivers, and I don't
> see why we need to do differently for any other driver (e.g., PCIe).
> 
> So...isn't 'dev->of_node != NULL' an equivalent test to
> 'of_node_valid'?
> Or put another way, mwifiex_add_card() should never see a 'struct
> device' whose of_node is not compatible. Do you agree?

I agree. 'of_node_valid' seems to be redundant here. I will remove it and post 
updated version.

Regards,
Amitkumar


Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor

2016-11-14 Thread Stanislaw Gruszka
On Wed, Nov 02, 2016 at 03:11:00PM +0100, Stanislaw Gruszka wrote:
> We can calculate BA window size (max number of pending frames not
> yet block acked) of remote station using Maximum A-MPDU length factor
> for that station.
> 
> Signed-off-by: Stanislaw Gruszka 

Kalle, please drop this patch from the set, it requires some rework.

Thanks
Stanislaw


> ---
>  drivers/net/wireless/ralink/rt2x00/rt2x00queue.c |   15 ++-
>  1 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c 
> b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
> index 68b620b..9da89e3 100644
> --- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
> +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
> @@ -305,14 +305,19 @@ static void rt2x00queue_create_tx_descriptor_ht(struct 
> rt2x00_dev *rt2x00dev,
>   struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
>   struct ieee80211_tx_rate *txrate = _info->control.rates[0];
>   struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
> - struct rt2x00_sta *sta_priv = NULL;
> + u8 ba_size = 0;
>  
>   if (sta) {
> - txdesc->u.ht.mpdu_density =
> - sta->ht_cap.ampdu_density;
> + struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta);
>  
> - sta_priv = sta_to_rt2x00_sta(sta);
> + txdesc->u.ht.mpdu_density = sta->ht_cap.ampdu_density;
>   txdesc->u.ht.wcid = sta_priv->wcid;
> +
> + if (!(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) {
> + ba_size = IEEE80211_MIN_AMPDU_BUF;
> + ba_size <<= sta->ht_cap.ampdu_factor;
> + ba_size = min_t(int, 63, ba_size - 1);
> + }
>   }
>  
>   /*
> @@ -345,7 +350,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct 
> rt2x00_dev *rt2x00dev,
>   return;
>   }
>  
> - txdesc->u.ht.ba_size = 7;   /* FIXME: What value is needed? */
> + txdesc->u.ht.ba_size = ba_size;
>  
>   /*
>* Only one STBC stream is supported for now.
> -- 
> 1.7.1
> 


RE: [PATCH v2 3/3] mwifiex: Enable WoWLAN for both sdio and pcie

2016-11-14 Thread Amitkumar Karwar
Hi Brian,

> From: Brian Norris [mailto:briannor...@chromium.org]
> Sent: Saturday, November 12, 2016 2:13 AM
> To: Amitkumar Karwar
> Cc: linux-wireless@vger.kernel.org; Cathy Luo; Nishant Sarmukadam;
> raja...@google.com; dmitry.torok...@gmail.com
> Subject: Re: [PATCH v2 3/3] mwifiex: Enable WoWLAN for both sdio and
> pcie
> 
> On Fri, Nov 11, 2016 at 04:45:11PM +0530, Amitkumar Karwar wrote:
> > From: Rajat Jain 
> >
> > Commit ce4f6f0c353b ("mwifiex: add platform specific wakeup interrupt
> > support") added WoWLAN feature only for sdio. This patch moves that
> > code to the common module so that all the interface drivers can use
> it
> > for free. It enables pcie and sdio for its use currently.
> >
> > Signed-off-by: Rajat Jain 
> > ---
> > v2: v1 doesn't apply smoothly on latest code due to recently merged
> > patch "mwifiex: report error to PCIe for suspend failure". Minor
> > conflict is resolved in v2
> > ---
> 
> In case you haven't noticed my comments elsewhere, I'll repeat them
> here: you're copy-and-pasting buggy code. That can be OK I suppose, but
> please fix these issues, possibly in a follow-up patch.

Thanks for pointing this. I will post separate follow-up patch which address 
this issue as per your suggestion.

Regards,
Amitkumar


Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor

2016-11-14 Thread Stanislaw Gruszka
On Mon, Nov 14, 2016 at 09:45:36AM +0100, Stanislaw Gruszka wrote:
> Could you check below patch and see if it helps? If it does not,
> could you printk sta->ht_cap.ampdu_density and ba_size values
> and provide them here.

Actually please print parameters from below patch. I think ba_size
should be based on per TID buf_size instead of ampdu_factor, in case
STA has buf size different for some TIDs.

Also adding Felix to cc since my orginal patch:
http://marc.info/?l=linux-wireless=147809595316289=2
was shamelessly stolen from mt76 driver. Perhaps Felix could provide
us some expertise.

Thanks
Stanislaw

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 
b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 2515702..35bc38c 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -7950,6 +7950,8 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
struct rt2x00_sta *sta_priv = (struct rt2x00_sta *)sta->drv_priv;
int ret = 0;
 
+   printk("action %d sta %pM tid %u buf_size %u ampdu_factor %u\n", 
params->action, sta->addr, params->tid, params->buf_size, 
sta->ht_cap.ampdu_factor);
+
/*
 * Don't allow aggregation for stations the hardware isn't aware
 * of because tx status reports for frames to an unknown station


[PATCH 5/5] rsi: Added support for 802.11d

2016-11-14 Thread Prameela Rani Garnepudi
Transmit power value in a channel are determined based on the dfs region
in firmware. To support regulatory rules dfs region should be configured
to device during set channel request. Also antenna gain values are taken
from the mac80211 channel parameters.

Signed-off-by: Prameela Rani Garnepudi 
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 30 -
 drivers/net/wireless/rsi/rsi_91x_mgmt.c | 26 -
 drivers/net/wireless/rsi/rsi_main.h |  1 +
 drivers/net/wireless/rsi/rsi_mgmt.h |  3 ++-
 4 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c 
b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 07314ea..064f38b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -376,7 +376,7 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
 
status = rsi_band_check(common);
if (!status)
-   status = rsi_set_channel(adapter->priv, channel);
+   status = rsi_set_channel(adapter->priv, curchan);
 
if (bss->assoc) {
if (common->hw_data_qs_blocked &&
@@ -1147,6 +1147,32 @@ static int rsi_mac80211_get_antenna(struct ieee80211_hw 
*hw,
return 0;   
 }
 
+static void rsi_reg_notify(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+   struct ieee80211_supported_band *sband;
+   struct ieee80211_channel *ch;
+   struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+   struct rsi_hw * adapter = hw->priv; 
+   int i;
+
+   sband = wiphy->bands[NL80211_BAND_5GHZ];
+   
+   for (i = 0; i < sband->n_channels; i++) {
+   ch = >channels[i];
+   if (ch->flags & IEEE80211_CHAN_DISABLED)
+   continue;
+
+   if (ch->flags & IEEE80211_CHAN_RADAR)
+   ch->flags |= IEEE80211_CHAN_NO_IR;
+   }
+   
+   rsi_dbg(INFO_ZONE,
+   "country = %s dfs_region = %d\n",
+   request->alpha2, request->dfs_region);
+   adapter->dfs_region = request->dfs_region;
+}
+
 static struct ieee80211_ops mac80211_ops = {
.tx = rsi_mac80211_tx,
.start = rsi_mac80211_start,
@@ -1229,6 +1255,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
wiphy->bands[NL80211_BAND_5GHZ] =
>sbands[NL80211_BAND_5GHZ];
 
+   wiphy->reg_notifier = rsi_reg_notify;
+
status = ieee80211_register_hw(hw);
if (status)
return status;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c 
b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 16dc3ac..a4d7bf9 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -924,7 +924,8 @@ int rsi_band_check(struct rsi_common *common)
  *
  * Return: 0 on success, corresponding error code on failure.
  */
-int rsi_set_channel(struct rsi_common *common, u16 channel)
+int rsi_set_channel(struct rsi_common *common,
+   struct ieee80211_channel *channel)
 {
struct sk_buff *skb = NULL;
struct rsi_mac_frame *mgmt_frame;
@@ -939,24 +940,39 @@ int rsi_set_channel(struct rsi_common *common, u16 
channel)
return -ENOMEM;
}
 
+   if (!channel) {
+   dev_kfree_skb(skb);
+   return 0;
+   }
memset(skb->data, 0, FRAME_DESC_SZ);
mgmt_frame = (struct rsi_mac_frame *)skb->data;
 
mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST);
-   mgmt_frame->desc_word[4] = cpu_to_le16(channel);
+   mgmt_frame->desc_word[4] = cpu_to_le16(channel->hw_value);
+
+   mgmt_frame->desc_word[4] |=
+   cpu_to_le16(((char)(channel->max_antenna_gain)) << 8);
+   mgmt_frame->desc_word[5] =
+   cpu_to_le16((char)(channel->max_antenna_gain));
 
mgmt_frame->desc_word[7] = cpu_to_le16(PUT_BBP_RESET |
   BBP_REG_WRITE |
   (RSI_RF_TYPE << 4));
 
-   mgmt_frame->desc_word[5] = cpu_to_le16(0x01);
-   mgmt_frame->desc_word[6] = cpu_to_le16(0x12);
+   if (!(channel->flags & IEEE80211_CHAN_NO_IR) &&
+  !(channel->flags & IEEE80211_CHAN_RADAR)) {
+   if (common->tx_power < channel->max_power)
+   mgmt_frame->desc_word[6] = 
cpu_to_le16(common->tx_power);
+   else
+   mgmt_frame->desc_word[6] = 
cpu_to_le16(channel->max_power);
+   }
+   mgmt_frame->desc_word[7] = cpu_to_le16(common->priv->dfs_region);
 
if (common->channel_width == BW_40MHZ)
mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8);
 
-   common->channel = channel;
+   common->channel = channel->hw_value;
 

[PATCH 2/5] rsi: Added rx filter frame

2016-11-14 Thread Prameela Rani Garnepudi
Filtering the rx frames in firmware after connection in station mode
avoids the overhead of processing un-necessary frames. Hence rx filter
frame is added which can be configured to device at suitable times.

Signed-off-by: Prameela Rani Garnepudi 
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 22 
 drivers/net/wireless/rsi/rsi_91x_mgmt.c | 32 +
 drivers/net/wireless/rsi/rsi_mgmt.h | 11 ++
 3 files changed, 65 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c 
b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index dbb2389..fa9498d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -259,11 +259,14 @@ static int rsi_mac80211_start(struct ieee80211_hw *hw)
 {
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
+   u16 rx_filter_word = 0;
 
mutex_lock(>mutex);
common->iface_down = false;
mutex_unlock(>mutex);
 
+   rsi_send_rx_filter_frame(common, rx_filter_word);
+
return 0;
 }
 
@@ -456,11 +459,28 @@ static void rsi_mac80211_bss_info_changed(struct 
ieee80211_hw *hw,
 {
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
+   struct ieee80211_bss_conf *bss = >vifs[0]->bss_conf;
+   u16 rx_filter_word = 0;
 
mutex_lock(>mutex);
if (changed & BSS_CHANGED_ASSOC) {
rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n",
__func__, bss_conf->assoc);
+   bss->assoc = bss_conf->assoc;
+   if (bss_conf->assoc) {
+   /* Send the RX filter frame */
+   rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
+ ALLOW_CTRL_ASSOC_PEER |
+ ALLOW_MGMT_ASSOC_PEER);
+   rsi_send_rx_filter_frame(common, rx_filter_word);
+   }
+   rsi_dbg(INFO_ZONE,
+   "assoc_status=%d, qos=%d, aid=%d\n",
+   bss->assoc, bss->qos, bss->aid);
+   rsi_dbg(INFO_ZONE,
+   "bssid=%02x:%02x:%02x:%02x:%02x:%02x",
+   bss->bssid[0], bss->bssid[1], bss->bssid[2],
+   bss->bssid[3], bss->bssid[4], bss->bssid[5]);
rsi_inform_bss_status(common,
  bss_conf->assoc,
  bss_conf->bssid,
@@ -1009,6 +1029,8 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw 
*hw,
common->secinfo.gtk_cipher = 0;
mutex_unlock(>mutex);
 
+   if (!common->iface_down)
+   rsi_send_rx_filter_frame(common, 0);
return 0;
 }
 
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c 
b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 8db377b..ae4a814 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1254,6 +1254,38 @@ int rsi_send_block_unblock_frame(struct rsi_common 
*common, bool block_event)
 
 }
 
+/**
+ * This function sends a frame to filter the RX packets
+ *
+ * @param common Pointer to the driver private structure.
+ * @param rx_filter_word - Flags of filter packets
+ * @return 0 on success, -1 on failure.
+ */
+int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word)
+{
+   struct rsi_mac_frame *mgmt_frame;
+   struct sk_buff *skb;
+
+   rsi_dbg(MGMT_TX_ZONE, "%s: Sending RX filter frame\n", __func__);
+
+   skb = dev_alloc_skb(FRAME_DESC_SZ);
+   if (!skb) {
+   rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+   __func__);
+   return -ENOMEM;
+   }
+
+   memset(skb->data, 0, FRAME_DESC_SZ);
+   mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
+   mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+   mgmt_frame->desc_word[1] = cpu_to_le16(SET_RX_FILTER);
+   mgmt_frame->desc_word[4] = cpu_to_le16(rx_filter_word);
+
+   skb_put(skb, FRAME_DESC_SZ);
+
+   return rsi_send_internal_mgmt_frame(common, skb);
+}
 
 /**
  * rsi_handle_ta_confirm_type() - This function handles the confirm frames.
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h 
b/drivers/net/wireless/rsi/rsi_mgmt.h
index 3741173..40e8f8e 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -140,6 +140,16 @@
 
 #define RSI_SUPP_FILTERS   (FIF_ALLMULTI | FIF_PROBE_REQ |\
 FIF_BCN_PRBRESP_PROMISC)
+
+/* Rx filter word definitions */
+#define PROMISCOUS_MODEBIT(0)
+#define ALLOW_DATA_ASSOC_PEER  BIT(1)
+#define ALLOW_MGMT_ASSOC_PEER  BIT(2)
+#define ALLOW_CTRL_ASSOC_PEER  BIT(3)
+#define DISALLOW_BEACONS   BIT(4)
+#define 

[PATCH 3/5] rsi: Added support for configuring tx power

2016-11-14 Thread Prameela Rani Garnepudi
TX power can be configured from iwconfig, iw or from mac80211 when
regulatory changes are done. Hence support for configuring tx power
to device is added. This can be done by sending RADIO_PARAMS_UPDATE
command frame to device with upated tx power value.

Signed-off-by: Prameela Rani Garnepudi 
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 37 +++
 drivers/net/wireless/rsi/rsi_91x_mgmt.c | 38 +++
 drivers/net/wireless/rsi/rsi_main.h |  2 +
 drivers/net/wireless/rsi/rsi_mgmt.h | 72 ++---
 4 files changed, 123 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c 
b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index fa9498d..ba21608 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -397,6 +397,37 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
 }
 
 /**
+ * rsi_config_power() - This function configures tx power in device
+ * @hw: Pointer to the ieee80211_hw structure.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int rsi_config_power(struct ieee80211_hw *hw)
+{
+   struct rsi_hw *adapter = hw->priv;
+   struct rsi_common *common = adapter->priv;
+   struct ieee80211_conf *conf = >conf;
+   int status;
+
+   if (adapter->sc_nvifs <= 0) {
+   rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
+   return -EINVAL;
+   }
+
+   rsi_dbg(INFO_ZONE,
+   "%s: Set tx power: %d dBM\n", __func__, conf->power_level);
+
+   if (conf->power_level == common->tx_power)
+   return 0;
+
+   common->tx_power = conf->power_level;
+
+   status = rsi_send_radio_params_update(common);
+
+   return status;
+}
+
+/**
  * rsi_mac80211_config() - This function is a handler for configuration
  *requests. The stack calls this function to
  *change hardware configuration, e.g., channel.
@@ -417,6 +448,12 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
status = rsi_channel_change(hw);
 
+   /* tx power */
+   if (changed & IEEE80211_CONF_CHANGE_POWER) {
+   rsi_dbg(INFO_ZONE, "%s: Configuring Power\n", __func__);
+   status = rsi_config_power(hw);
+   }
+
mutex_unlock(>mutex);
 
return status;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c 
b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index ae4a814..2e8e5dc 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -964,6 +964,44 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
 }
 
 /**
+ * rsi_send_radio_params_update() - This function sends the radio
+ * parameters update to device
+ * @common: Pointer to the driver private structure.
+ * @channel: Channel value to be set.
+ *
+ * Return: 0 on success, corresponding error code on failure.
+ */
+int rsi_send_radio_params_update(struct rsi_common *common)
+{
+   struct rsi_mac_frame *mgmt_frame;
+   struct sk_buff *skb = NULL;
+
+   rsi_dbg(MGMT_TX_ZONE,
+   "%s: Sending Radio Params update frame\n", __func__);
+
+   skb = dev_alloc_skb(FRAME_DESC_SZ);
+   if (!skb) {
+   rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+   __func__);
+   return -ENOMEM;
+   }
+
+   memset(skb->data, 0, FRAME_DESC_SZ);
+   mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
+   mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+   mgmt_frame->desc_word[1] = cpu_to_le16(RADIO_PARAMS_UPDATE);
+   mgmt_frame->desc_word[3] = cpu_to_le16(BIT(0));
+
+   mgmt_frame->desc_word[3] |= cpu_to_le16(common->tx_power << 8);
+
+   skb_put(skb, FRAME_DESC_SZ);
+
+   return rsi_send_internal_mgmt_frame(common, skb);
+}
+
+
+/**
  * rsi_compare() - This function is used to compare two integers
  * @a: pointer to the first integer
  * @b: pointer to the second integer
diff --git a/drivers/net/wireless/rsi/rsi_main.h 
b/drivers/net/wireless/rsi/rsi_main.h
index dcd0957..3938f13 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -204,6 +204,8 @@ struct rsi_common {
struct cqm_info cqm_info;
 
bool hw_data_qs_blocked;
+   
+   int tx_power;
 };
 
 struct rsi_hw {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h 
b/drivers/net/wireless/rsi/rsi_mgmt.h
index 40e8f8e..6547ae7 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -169,32 +169,51 @@ enum sta_notify_events {
 
 /* Send Frames Types */
 enum cmd_frame_type {
-   TX_DOT11_MGMT,
-   RESET_MAC_REQ,
-   RADIO_CAPABILITIES,
-   BB_PROG_VALUES_REQUEST,
-   RF_PROG_VALUES_REQUEST,

[PATCH 4/5] rsi: Added support for antenna selection

2016-11-14 Thread Prameela Rani Garnepudi
RSI 9113 device supports single antenna for tx and rx. Support for using
external is added. This can be configured from user space using iw.

Signed-off-by: Prameela Rani Garnepudi 
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 78 +
 drivers/net/wireless/rsi/rsi_91x_mgmt.c | 33 
 drivers/net/wireless/rsi/rsi_main.h |  1 +
 drivers/net/wireless/rsi/rsi_mgmt.h |  4 ++
 4 files changed, 116 insertions(+)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c 
b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index ba21608..07314ea 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -1071,6 +1071,82 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw 
*hw,
return 0;
 }
 
+/**
+ * rsi_mac80211_set_antenna() - This function is used to configure
+ * tx and rx antennas.
+ * @hw: Pointer to the ieee80211_hw structure.
+ * @tx_ant: Bitmap for tx antenna
+ * @rx_ant: Bitmap for rx antenna
+ *
+ * Return: 0 on success, -1 on failure.
+ */
+static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw,
+   u32 tx_ant, u32 rx_ant)
+{
+   struct rsi_hw *adapter = hw->priv;
+   struct rsi_common *common = adapter->priv;
+   u32 antenna = 0;
+
+   if (tx_ant > 1 || rx_ant > 1) {
+   rsi_dbg(ERR_ZONE,
+   "Invalid antenna selection (tx: %d, rx:%d)\n",
+   tx_ant, rx_ant);
+   rsi_dbg(ERR_ZONE,
+   "Use 0 for int_ant, 1 for ext_ant\n");
+   return -EINVAL; 
+   }
+
+   rsi_dbg(INFO_ZONE, "%s: Antenna map Tx %x Rx %d\n",
+   __func__, tx_ant, rx_ant);
+
+   mutex_lock(>mutex);
+
+   antenna = tx_ant ? ANTENNA_SEL_UFL : ANTENNA_SEL_INT;
+   if (common->ant_in_use != antenna)
+   if (rsi_set_antenna(common, antenna))
+   goto fail_set_antenna;
+
+   rsi_dbg(INFO_ZONE, "(%s) Antenna path configured successfully\n",
+   tx_ant ? "UFL" : "INT");
+
+   common->ant_in_use = antenna;
+   
+   mutex_unlock(>mutex);
+   
+   return 0;
+
+fail_set_antenna:
+   rsi_dbg(ERR_ZONE, "%s: Failed.\n", __func__);
+   mutex_unlock(>mutex);
+   return -EINVAL;
+}
+
+/**
+ * rsi_mac80211_get_antenna() - This function is used to configure 
+ * tx and rx antennas.
+ *
+ * @hw: Pointer to the ieee80211_hw structure.
+ * @tx_ant: Bitmap for tx antenna
+ * @rx_ant: Bitmap for rx antenna
+ * 
+ * Return: 0 on success, -1 on failure.
+ */
+static int rsi_mac80211_get_antenna(struct ieee80211_hw *hw,
+   u32 *tx_ant, u32 *rx_ant)
+{
+   struct rsi_hw *adapter = hw->priv;
+   struct rsi_common *common = adapter->priv;
+
+   mutex_lock(>mutex);
+
+   *tx_ant = (common->ant_in_use == ANTENNA_SEL_UFL) ? 1 : 0;
+   *rx_ant = 0;
+
+   mutex_unlock(>mutex);
+   
+   return 0;   
+}
+
 static struct ieee80211_ops mac80211_ops = {
.tx = rsi_mac80211_tx,
.start = rsi_mac80211_start,
@@ -1087,6 +1163,8 @@ static struct ieee80211_ops mac80211_ops = {
.ampdu_action = rsi_mac80211_ampdu_action,
.sta_add = rsi_mac80211_sta_add,
.sta_remove = rsi_mac80211_sta_remove,
+   .set_antenna = rsi_mac80211_set_antenna,
+   .get_antenna = rsi_mac80211_get_antenna,
 };
 
 /**
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c 
b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 2e8e5dc..16dc3ac 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1326,6 +1326,39 @@ int rsi_send_rx_filter_frame(struct rsi_common *common, 
u16 rx_filter_word)
 }
 
 /**
+ * rsi_set_antenna() - This fuction handles antenna selection functionality.
+ *
+ * @common: Pointer to the driver private structure.
+ * @antenna: bitmap for tx antenna selection
+ *
+ * Return: 0 on Success, < 0 on failure
+ */
+int rsi_set_antenna(struct rsi_common *common,
+   u8 antenna)
+{
+   struct rsi_mac_frame *mgmt_frame;
+   struct sk_buff *skb;
+
+   skb = dev_alloc_skb(FRAME_DESC_SZ);
+   if (!skb) {
+   rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+   __func__);
+   return -ENOMEM;
+   }
+
+   memset(skb->data, 0, FRAME_DESC_SZ);
+   mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
+   mgmt_frame->desc_word[1] = cpu_to_le16(ANT_SEL_FRAME);
+   mgmt_frame->desc_word[3] = cpu_to_le16(antenna & 0x00ff);
+   mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+
+   skb_put(skb, FRAME_DESC_SZ);
+
+   return rsi_send_internal_mgmt_frame(common, skb);
+}
+
+/**
  * rsi_handle_ta_confirm_type() - This function handles the confirm frames.
  * @common: Pointer to the 

[PATCH 1/5] rsi: Device configuration bootup parameters updated

2016-11-14 Thread Prameela Rani Garnepudi
Switch clock info values are changed in the firmware for both 20MHZ
and 40MHZ modes. Hence these values which are configured through boot
parameters request frame are updated. Also three other power save
related parameters are added to boot up parameters.

Signed-off-by: Prameela Rani Garnepudi 
---
 drivers/net/wireless/rsi/rsi_91x_mgmt.c| 30 +---
 drivers/net/wireless/rsi/rsi_boot_params.h | 37 +-
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c 
b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 35c14cc..8db377b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -18,6 +18,7 @@
 #include "rsi_mgmt.h"
 #include "rsi_common.h"
 
+/* Bootup Parameters for 20MHz */
 static struct bootup_params boot_params_20 = {
.magic_number = cpu_to_le16(0x5aa5),
.crystal_good_time = 0x0,
@@ -28,6 +29,7 @@ static struct bootup_params boot_params_20 = {
.rtls_timestamp_en = 0x0,
.host_spi_intr_cfg = 0x0,
.device_clk_info = {{
+   /* WLAN params */
.pll_config_g = {
.tapll_info_g = {
.pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)|
@@ -45,12 +47,13 @@ static struct bootup_params boot_params_20 = {
}
},
.switch_clk_g = {
-   .switch_clk_info = cpu_to_le16(BIT(3)),
-   .bbp_lmac_clk_reg_val = cpu_to_le16(0x121),
-   .umac_clock_reg_config = 0x0,
-   .qspi_uart_clock_reg_config = 0x0
+   .switch_clk_info = cpu_to_le16(0xB),
+   .bbp_lmac_clk_reg_val = cpu_to_le16(0x111),
+   .umac_clock_reg_config = cpu_to_le16(0x48),
+   .qspi_uart_clock_reg_config = cpu_to_le16(0x1211)
}
},
+   /* Bluetooth params */
{
.pll_config_g = {
.tapll_info_g = {
@@ -75,6 +78,7 @@ static struct bootup_params boot_params_20 = {
.qspi_uart_clock_reg_config = 0x0
}
},
+   /* Zigbee params */
{
.pll_config_g = {
.tapll_info_g = {
@@ -99,6 +103,7 @@ static struct bootup_params boot_params_20 = {
.qspi_uart_clock_reg_config = 0x0
}
} },
+   /* ULP Params */
.buckboost_wakeup_cnt = 0x0,
.pmu_wakeup_wait = 0x0,
.shutdown_wait_time = 0x0,
@@ -106,9 +111,13 @@ static struct bootup_params boot_params_20 = {
.wdt_prog_value = 0x0,
.wdt_soc_rst_delay = 0x0,
.dcdc_operation_mode = 0x0,
-   .soc_reset_wait_cnt = 0x0
+   .soc_reset_wait_cnt = 0x0,
+   .waiting_time_at_fresh_sleep = 0x0,
+   .max_threshold_to_avoid_sleep = 0x0,
+   .beacon_resedue_alg_en = 0,
 };
 
+/* Bootup parameters for 40MHz */
 static struct bootup_params boot_params_40 = {
.magic_number = cpu_to_le16(0x5aa5),
.crystal_good_time = 0x0,
@@ -136,12 +145,13 @@ static struct bootup_params boot_params_40 = {
}
},
.switch_clk_g = {
-   .switch_clk_info = cpu_to_le16(0x09),
+   .switch_clk_info = cpu_to_le16(0xB),
.bbp_lmac_clk_reg_val = cpu_to_le16(0x1121),
.umac_clock_reg_config = cpu_to_le16(0x48),
-   .qspi_uart_clock_reg_config = 0x0
+   .qspi_uart_clock_reg_config = cpu_to_le16(0x1211) 
}
},
+   /* Bluetooth Params */
{
.pll_config_g = {
.tapll_info_g = {
@@ -190,6 +200,7 @@ static struct bootup_params boot_params_40 = {
.qspi_uart_clock_reg_config = 0x0
}
} },
+   /* ULP Params */
.buckboost_wakeup_cnt = 0x0,
.pmu_wakeup_wait = 0x0,
.shutdown_wait_time = 0x0,
@@ -197,7 +208,10 @@ static struct bootup_params boot_params_40 = {
.wdt_prog_value = 0x0,
.wdt_soc_rst_delay = 0x0,
.dcdc_operation_mode = 0x0,
-   .soc_reset_wait_cnt = 0x0
+   .soc_reset_wait_cnt = 0x0,
+   .waiting_time_at_fresh_sleep = 0x0,
+   .max_threshold_to_avoid_sleep = 0x0,
+   .beacon_resedue_alg_en = 0,
 };
 
 static u16 mcs[] = {13, 26, 39, 52, 78, 104, 117, 130};
diff --git a/drivers/net/wireless/rsi/rsi_boot_params.h 
b/drivers/net/wireless/rsi/rsi_boot_params.h
index 5e2721f..0d77aeb 100644
--- a/drivers/net/wireless/rsi/rsi_boot_params.h
+++ b/drivers/net/wireless/rsi/rsi_boot_params.h
@@ -99,11 +99,43 @@ struct device_clk_info {
 
 struct bootup_params {
__le16 magic_number;
+#define LOADED_TOKEN  0x5AA5   /* Bootup 

Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value

2016-11-14 Thread Gianfranco Costamagna
Hi Arend,



>Well, not before you pointed it out ;-). You are welcome to send a patch
>fixing it. Otherwise, I will take care of it.


attaching a format-patch like version.
I don't think we need a Tested-by or whatever, because it is just a typo in a 
comment.
(this is my first contribution, feel free to rebase or change whatever you 
prefer
to make it in line with other styles)

(I gave authorship to Marco, the first one who discovered such typo)

thanks!

G.
From bf0cdd8ad27833639447a3071d662f79a7219b1d Mon Sep 17 00:00:00 2001
From: Arlone Marco 
Date: Sat, 22 Oct 2016 15:08:35 +0200
Subject: [PATCH] broadcom cfg80211: fix typo in REG channel frequency comment

frequency 2472 corresponds to channel 13, not channel 11

Signed-off-by: Gianfranco Costamagna 
Signed-off-by: Nicola Smaldone 
Signed-off-by: Arlone Marco 
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index b777e1b..b4d8b1b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -203,7 +203,7 @@ static const struct ieee80211_regdomain brcmf_regdom = {
 	.n_reg_rules = 4,
 	.alpha2 =  "99",
 	.reg_rules = {
-		/* IEEE 802.11b/g, channels 1..11 */
+		/* IEEE 802.11b/g, channels 1..13 */
 		REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
 		/* If any */
 		/* IEEE 802.11 channel 14 - Only JP enables
-- 
2.7.4



Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value

2016-11-14 Thread Gianfranco Costamagna
Hi Arend,


>Finally response. As it turns out the range was explcitly changed

>enabling channels 12 and 13 to be used where applicable. They forgot to
>update the comment.


so, the struct in net/wireless/reg.c is actually used in that case?

static const struct ieee80211_regdomain world_regdom = {

do you plan to update the comment?

thanks!

Gianfranco


Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value

2016-11-14 Thread Arend Van Spriel
On 14-11-2016 12:34, Gianfranco Costamagna wrote:
> Hi Arend,
> 
> 
>> Finally response. As it turns out the range was explcitly changed
> 
>> enabling channels 12 and 13 to be used where applicable. They forgot to
>> update the comment.
> 
> 
> so, the struct in net/wireless/reg.c is actually used in that case?
> 
> static const struct ieee80211_regdomain world_regdom = {
> 
> do you plan to update the comment?

Well, not before you pointed it out ;-). You are welcome to send a patch
fixing it. Otherwise, I will take care of it.

Regards,
Arend


Re: [PATCH] broadcom/brcm80211/brcmfmac/cfg80211 driver, bad regulatory domain frequency value

2016-11-14 Thread Arend Van Spriel
On 28-10-2016 22:41, Arend Van Spriel wrote:
> On 28-10-2016 18:15, Gianfranco Costamagna wrote:
>> (resending from my debian.org mail address, to avoid spam filtering)
>>
>> Hi Broadcom developers and linux wireless list.
>>
>> We found a possible issue in the cfg80211 implementation of the regulatory 
>> domain rules:
>>
>> .reg_rules = {
>> /* IEEE 802.11b/g, channels 1..11 */
>> REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
>>
>>
>> the referred channel 11 has/should have a frequency of 2462, not 2472 
>> (corresponding to channel 13).
>> Is this a typo in the code or the above comment?
>>
>> (I'm not sure why the override of reg.c is in place for 2.4 Ghz frequencies)
>>
>> Can you please double check and in case apply the attached patch?
> 
> checking stay tuned.

Hi Gianfranco,

Finally response. As it turns out the range was explcitly changed
enabling channels 12 and 13 to be used where applicable. They forgot to
update the comment.

Regards,
Arend


[bug report] iwlwifi: mvm: use dev_coredumpsg()

2016-11-14 Thread Dan Carpenter
Hello Aviya Erenfeld,

The patch 7e62a699aafb: "iwlwifi: mvm: use dev_coredumpsg()" from Sep
20, 2016, leads to the following static checker warning:

drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c:821 
iwl_mvm_fw_error_dump()
error: we previously assumed 'fw_error_dump->trans_ptr' could be null 
(see line 809)

drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
   805  dump_trans_data:
   806  fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans,
   807 
mvm->fw_dump_trig);
   808  fw_error_dump->op_mode_len = file_len;
   809  if (fw_error_dump->trans_ptr)
   810  file_len += fw_error_dump->trans_ptr->len;

We assume ->trans_ptr can be NULL.

   811  dump_file->file_len = cpu_to_le32(file_len);
   812  
   813  sg_dump_data = alloc_sgtable(file_len);

That probably means file_len is zero?  (didn't look).  That means
sg_dump_data is ZERO_SIZE_PTR (16).

   814  if (sg_dump_data) {
   815  sg_pcopy_from_buffer(sg_dump_data,
   816   sg_nents(sg_dump_data),
   817   fw_error_dump->op_mode_ptr,
   818   fw_error_dump->op_mode_len, 0);
   819  sg_pcopy_from_buffer(sg_dump_data,
   820   sg_nents(sg_dump_data),
   821   fw_error_dump->trans_ptr->data,

Leading to an oops.

   822   fw_error_dump->trans_ptr->len,
   823   fw_error_dump->op_mode_len);
   824  dev_coredumpsg(mvm->trans->dev, sg_dump_data, file_len,
   825 GFP_KERNEL);
   826  }
   827  vfree(fw_error_dump->op_mode_ptr);
   828  vfree(fw_error_dump->trans_ptr);
   829  kfree(fw_error_dump);
   830  
   831  out:
   832  iwl_mvm_free_fw_dump_desc(mvm);
   833  mvm->fw_dump_trig = NULL;
   834  clear_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, >status);
   835  }

regards,
dan carpenter


Re: [RFC] change mac80211_hwsim tx_rates to ieee80211_tx_rate

2016-11-14 Thread Benjamin Beichler

>> So I would propose to put the whole struct into the netlink messages,
> This is a terrible idea, since internal changes to this struct would
> break the userland API/ABI. hwsim seems perhaps less important than
> most APIs, but there is wmediumd etc. already.
I agree with that, but there exist also other code in hwsim, which is
tightly coupled with the mac80211 API, as e.g., the usage of
IEEE80211_TX_MAX_RATES, which already broke older versions of wmediumd
or similar implementations. Maybe a review regarding such things would
be good to decouple the userspace daemon from the special kernel version.

>> but I think that will break up the communication to e.g. bob
>> copelands
>> wmediumd and similar simulations. I would like to have our
>> Implementation working with mainline kernels and therefore ask how we
>> could achieve this easily.
>>
>> Obviously, we could define another field in the hwsim messages, but
>> as bob copeland already stated, significantly more information within
>> the netlink messages could  intensify the timing overhead of hwsim.
> I don't think we have any other choice but add the relevant fields as
> proper attributes.

I'm totally fine with that. Nonetheless,  I would suggest to add the
flags to "struct hwsim_tx_rate", since the flags are also tightly
coupled to the rates and tries of a frame. To not break up things, we
could add the flags as a separate attribute in the struct and not as
part of the bitfield like in the original. This would be possible, due
to the "__packed" flag, but I'm also unsure, whether this is a really
good idea for a userspace API/ABI.


Benjamin




Re: Problems with mwifiex_pcie firmware activation

2016-11-14 Thread Stanislaw Gruszka
On Thu, Aug 25, 2016 at 05:06:26PM +0200, Stanislaw Gruszka wrote:
> On Fri, Aug 12, 2016 at 10:13:43AM +0200, Stanislaw Gruszka wrote:
> > On Fri, Aug 12, 2016 at 07:17:38AM +, Amitkumar Karwar wrote:
> > > The problem looks strange. The patch just splits 
> > > mwifiex_check_fw_status() and increases poll count. It should not have 
> > > any side-effects.
> > > Our code used to check winner status before this patch also.
> > 
> > Ok, I misread the patch. Anyway checking "winner status" seems
> > does not work well on some condition and prevent loading firmware
> > into device.
> 
> I debug this a bit more on latest wireless-testing-next tree + 3 patches
> I just posted and debug_mask=0x70ff.
> 
> On broken system, we do not download FW to device when system is
> rebooted, due to PCI-E is not the winner. However if system is
> powered OFF and then powered ON, we do FW downloading. Hence
> download the new FW into device does not make it work as was
> my theory.
> 
> In attachments are full dmesgs of good/bad and reboot/power-off-on
> cases.
> 
> The difference is that on broken system FW (or HW) do not create
> new USB Bluetooth device (1286:2046) and do not report
> FIRMWARE_READY_PCIE. Additionally on reboot case there are errors
> from USB xhci.

It was discovered that not working device require pcie8897_uapsta.bin 
firmware from ubuntu package to work:
https://launchpad.net/~snappy-dev/+archive/ubuntu/snappy-devices/+sourcepub/5936055/+listing-archive-extra

Device initialize like this then:

[   15.374630] mwifiex_pcie :02:00.0: info: FW download over, size 689624 
bytes
[   16.101214] mwifiex_pcie :02:00.0: WLAN FW is active
[   16.242825] mwifiex_pcie :02:00.0: info: MWIFIEX VERSION: mwifiex 1.0 
(15.150.13.p21) 
[   16.251231] mwifiex_pcie :02:00.0: driver_version = mwifiex 1.0 
(15.150.13.p21) 

I'm not sure where ubuntu get this 15.150.13.p21 version of firmware as
it seems it's not present nor in upstream linux-firmware repo not in
http://git.marvell.com/?p=mwifiex-firmware.git;a=summary

Anyway could you modify firmware to support this device or modify
driver to load 15.150.13.p21 if required and push this F/W image
upstream ?

Thanks
Stanislaw
 


Re: [RFC] qtn: add FullMAC firmware for Quantenna QSR10G wifi device

2016-11-14 Thread IgorMitsyanko

Thanks, Johannes.

To clarify with you and Kalle, as persons involved with linux-wireless: 
is my understanding correct that submitting firmware into linux-fimware 
repository is a prerequisite to accepting new driver into linux-wireless?


There is an option to start Quantenna device from internal flash memory, 
no external binary files involved. If we will introduce this 
functionality and remove code handling external firmware for now (until 
firmware problem resolved), would that allow driver to be reviewed/accepted?


On 11/11/2016 02:35 PM, Johannes Berg wrote:

Adding linux-firmware people to Cc, since presumably they don't
necessarily read linux-wireless...


Johannes, from that perspective, who are the "redistributors"?
Specifically, is linux-firmware git repository considered a
redistributor or its just hosting files? I mean, at what moment
someone else other then Quantenna will start to be legally obliged to
make GPL code used in firmware available for others?

Look, I don't know. I'd assume people who ship it, like any regular
distro, would be (re)distributors thereof. "Normal" (non-GPL) firmware
images come with a redistribution license, but that obviously can't
work here.

There's some info from Ben here regarding the carl9170 case:
http://lkml.iu.edu/hypermail/linux/kernel/1605.3/01176.html


Personally I still hope that linux-firmware itself is not legally
concerned with what is the content of firmware its hosting, but looks
like there already was a precedent case  with carl9170 driver and
we have to somehow deal with it.

That's really all I wanted to bring up. I'm not involved with the
linux-firmware git tree.


There still may be a difference though: Quantenna is semiconductor
company only, software
used on actual products based on Quantenna chipsets is released by
other
companies.
I just want to present our legal team with a clear case (and position
of
Linux maintainers) so that they can
work with it and make decision on how to proceed.

  From technical perspective, as I mentioned, SDK is quite huge and
include a lot of opensource
components including full Linux, I don't think its reasonable to have
it
inside linux-firmware tree.
What are the options to share it other then providing it on request
basis:
- git repository
- store tarball somewhere on official website

Clearly that wasn't deemed appropriate for carl9170, so I don't see why
it'd be different here.

johannes




Re: [PATCH V3] qtnfmac: announcement of new FullMAC driver for Quantenna chipsets

2016-11-14 Thread Johannes Berg

> +++ b/drivers/net/wireless/quantenna/qtnfmac/Kconfig
> @@ -0,0 +1,23 @@
> +config QTNFMAC
> + tristate "Quantenna WiFi FullMAC WLAN driver"
> + default n

No need to state that default explicitly, but it also doesn't really
matter.

> +   it as a module, it will be called qtnfmac_pearl_pcie.ko.


Where did the "pearl" come from? You didn't mention that in the commit
log.

Also, are you planning to add any other things to this soon? It seems
to me that perhaps the PCIe option should be the only one that's user-
visible, selecting the other one internally?

> + struct qtnf_bus_ops *bus_ops;

You should make that const and actually make all instances const, it's
better for security :)

> +/* Supported crypto cipher suits to be advertised to cfg80211 */
> +static const u32 qtnf_cipher_suites[] = {
> + WLAN_CIPHER_SUITE_TKIP,
> + WLAN_CIPHER_SUITE_CCMP,
> + WLAN_CIPHER_SUITE_AES_CMAC,
> +};

I'm surprised - no WEP? No CMAC and GCMP/GMAC?


> +static int
> +qtnf_change_virtual_intf(struct wiphy *wiphy,
> +  struct net_device *dev,
> +  enum nl80211_iftype type, u32 *flags,
> +  struct vif_params *params)
> +{
> + struct qtnf_vif *vif;
> + u8 *mac_addr;
> +
> + vif = qtnf_netdev_get_priv(dev);
> +
> + if (params)
> + mac_addr = params->macaddr;
> + else
> + mac_addr = NULL;
> +
> + if (qtnf_cmd_send_change_intf_type(vif, type, mac_addr)) {
> + pr_err("failed to change interface type\n");
> + return -EFAULT;

Maybe -EIO would be better.

> +struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
> +    const char *name,
> +    unsigned char
> name_assign_type,
> +    enum nl80211_iftype type,
> +    u32 *flags,
> +    struct vif_params
> *params)
> +{
> + struct qtnf_wmac *mac;
> + struct qtnf_vif *vif;
> + u8 *mac_addr = NULL;
> +
> + mac = wiphy_priv(wiphy);
> +
> + if (!mac)
> + return ERR_PTR(-EFAULT);
> +
> + switch (type) {
> + case NL80211_IFTYPE_STATION:
> + case NL80211_IFTYPE_AP:
> + vif = qtnf_get_free_vif(mac);
> + if (!vif) {
> + pr_err("could not get free private
> structure\n");
> + return ERR_PTR(-EFAULT);
> + }

This is probably fairly natural to do, and it's not the first driver to
do this (brcmfmac also does), but some users may assume that they can
add interfaces as much as they want, until they bring them up (netdev
open).

It's probably worth having a discussion about this behaviour difference
- not necessarily in the context of this driver submission though.

> + if (qtnf_cmd_send_add_intf(vif, type, mac_addr)) {
> + vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
> + pr_err("failed to send add_intf command\n");
> + return ERR_PTR(-EFAULT);

I can't really tell, does this leak "vif"?

OK I need to find another way to review this patch now, it's too big
for my email client to work responsively...

johannes



Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor

2016-11-14 Thread Stanislaw Gruszka
Hi

On Mon, Nov 14, 2016 at 08:41:57PM +1100, Julian Calaby wrote:
> > -   rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 1);
> > +   rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 3;
> 
> You're missing a closing parenthesis, so it isn't going to work unless
> it's added back in.

Thanks for the notice, hopefully Mathias can fix that.

Stanislaw


Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor

2016-11-14 Thread Julian Calaby
Hi Stainslaw,

On Mon, Nov 14, 2016 at 7:45 PM, Stanislaw Gruszka  wrote:
> On Sat, Nov 05, 2016 at 01:56:58PM +0100, Mathias Kresin wrote:
>> 02.11.2016 15:11, Stanislaw Gruszka:
>> >
>> >-sta_priv = sta_to_rt2x00_sta(sta);
>> >+txdesc->u.ht.mpdu_density = sta->ht_cap.ampdu_density;
>> > txdesc->u.ht.wcid = sta_priv->wcid;
>> >+
>> >+if (!(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) {
>> >+ba_size = IEEE80211_MIN_AMPDU_BUF;
>> >+ba_size <<= sta->ht_cap.ampdu_factor;
>> >+ba_size = min_t(int, 63, ba_size - 1);
>> >+}
>> > }
>> >
>> > /*
>> >@@ -345,7 +350,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct 
>> >rt2x00_dev *rt2x00dev,
>> > return;
>> > }
>> >
>> >-txdesc->u.ht.ba_size = 7;   /* FIXME: What value is needed? */
>> >+txdesc->u.ht.ba_size = ba_size;
>> >
>> > /*
>> >  * Only one STBC stream is supported for now.
>> >
>>
>> Having this patch applied, the throughput on a vgv7510kw22 (RT3062F)
>> in AP mode using LEDE head is decreased by somewhat around 10
>> Mbits/sec. I'm using iperf3 for throughput tests and having this
>> patch reverted the throughout is back to 80 Mbits/sec.
>>
>> When bringing down the wifi interface the following messages are
>> logged with the patch applied:
>>
>> [  281.738373] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
>> Queue 2 failed to flush
>> [  281.906380] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
>> Queue 2 failed to flush
>
> Could you check below patch and see if it helps? If it does not,
> could you printk sta->ht_cap.ampdu_density and ba_size values
> and provide them here.
>
> Thanks
> Stanislaw
>
> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 
> b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> index 2515702..72c7948 100644
> --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> @@ -4707,7 +4707,7 @@ static int rt2800_init_registers(struct rt2x00_dev 
> *rt2x00dev)
> rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
> rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 2);
> else
> -   rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 1);
> +   rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 3;

You're missing a closing parenthesis, so it isn't going to work unless
it's added back in.

> rt2x00_set_field32(, MAX_LEN_CFG_MIN_PSDU, 0);
> rt2x00_set_field32(, MAX_LEN_CFG_MIN_MPDU, 0);
> rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);

Thanks,

-- 
Julian Calaby

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


Re: [RFC] qtn: add FullMAC firmware for Quantenna QSR10G wifi device

2016-11-14 Thread Johannes Berg
On Mon, 2016-11-14 at 11:26 +0300, IgorMitsyanko wrote:
> Thanks, Johannes.
> 
> To clarify with you and Kalle, as persons involved with linux-
> wireless: is my understanding correct that submitting firmware into
> linux-fimware repository is a prerequisite to accepting new driver
> into linux-wireless?

I personally don't think it needs to be quite that strict, but I don't
think I've heard anyone else express an opinion either way.

Frankly, so far I only commented on the firmware patch because I
haven't had time to go over the driver code at all.

johannes


Re: [PATCH 05/10] rt2800: make ba_size depend on ampdu_factor

2016-11-14 Thread Stanislaw Gruszka
On Sat, Nov 05, 2016 at 01:56:58PM +0100, Mathias Kresin wrote:
> 02.11.2016 15:11, Stanislaw Gruszka:
> >
> >-sta_priv = sta_to_rt2x00_sta(sta);
> >+txdesc->u.ht.mpdu_density = sta->ht_cap.ampdu_density;
> > txdesc->u.ht.wcid = sta_priv->wcid;
> >+
> >+if (!(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) {
> >+ba_size = IEEE80211_MIN_AMPDU_BUF;
> >+ba_size <<= sta->ht_cap.ampdu_factor;
> >+ba_size = min_t(int, 63, ba_size - 1);
> >+}
> > }
> >
> > /*
> >@@ -345,7 +350,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct 
> >rt2x00_dev *rt2x00dev,
> > return;
> > }
> >
> >-txdesc->u.ht.ba_size = 7;   /* FIXME: What value is needed? */
> >+txdesc->u.ht.ba_size = ba_size;
> >
> > /*
> >  * Only one STBC stream is supported for now.
> >
> 
> Having this patch applied, the throughput on a vgv7510kw22 (RT3062F)
> in AP mode using LEDE head is decreased by somewhat around 10
> Mbits/sec. I'm using iperf3 for throughput tests and having this
> patch reverted the throughout is back to 80 Mbits/sec.
> 
> When bringing down the wifi interface the following messages are
> logged with the patch applied:
> 
> [  281.738373] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
> Queue 2 failed to flush
> [  281.906380] ieee80211 phy0: rt2x00queue_flush_queue: Warning -
> Queue 2 failed to flush

Could you check below patch and see if it helps? If it does not,
could you printk sta->ht_cap.ampdu_density and ba_size values
and provide them here.

Thanks
Stanislaw 

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 
b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 2515702..72c7948 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -4707,7 +4707,7 @@ static int rt2800_init_registers(struct rt2x00_dev 
*rt2x00dev)
rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 2);
else
-   rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 1);
+   rt2x00_set_field32(, MAX_LEN_CFG_MAX_PSDU, 3;
rt2x00_set_field32(, MAX_LEN_CFG_MIN_PSDU, 0);
rt2x00_set_field32(, MAX_LEN_CFG_MIN_MPDU, 0);
rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);


Re: [PATCH 04/10] rt2800: do not overwrite WPDMA_GLO_CFG_WP_DMA_BURST_SIZE

2016-11-14 Thread Stanislaw Gruszka
On Sat, Nov 05, 2016 at 01:55:14PM +0100, Mathias Kresin wrote:
> 02.11.2016 15:10, Stanislaw Gruszka:
> >We already initlized WPDMA_GLO_CFG_WP_DMA_BURST_SIZE to 3 on
> >rt2800_init_registers().
> >
> >Signed-off-by: Stanislaw Gruszka 
> >---
> > drivers/net/wireless/ralink/rt2x00/rt2800lib.c |1 -
> > 1 files changed, 0 insertions(+), 1 deletions(-)
> >
> >diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c 
> >b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> >index feceb13..9ecdc4c 100644
> >--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> >+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
> >@@ -6756,7 +6756,6 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
> > rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, );
> > rt2x00_set_field32(, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
> > rt2x00_set_field32(, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
> >-rt2x00_set_field32(, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2);
> 
> More a notice than a potential issue since I don't have much
> knowledge about the driver/chip internals.
> 
> But WPDMA_GLO_CFG_WP_DMA_BURST_SIZE in rt2800_init_registers() is
> set conditionally for rt2x00_is_usb(rt2x00dev), where this one is
> set unconditionally. Not sure if this change has side effects.

Default HW setting of WP_DMA_BURTS_SIZE is 2, hence patch does not
change behaviour on PCI devices. However I looked at RT3290 and
RT5592 PCI vendor drivers and there this value is initialized to 3.
So I think we can remove is_usb condition in rt2800_init_registers().

Stanislaw


Re: Outdated wl12xx firmwares

2016-11-14 Thread Luca Coelho
Hi,
I'm CCing Maxim, since he seems to be the last developer from TI to
post patches for the WiLink drivers here.


On Thu, 2016-10-27 at 12:45 +0200, Gary Bisson wrote:
> Hi,
> 
> Adding linux-wireless in CC, hoping to get more traction.
> 
> Just checked the MAINTAINERS file of this driver and it is listed as
> 'Orphan', so is it ok if a non-TI person submits the up-to-date
> firmware files?

AFAICT, the license text in the github repository you pointed to is not
exactly the same as the one in linux-firmware.git.  So, not being a
lawyer, I don't know how you could handle that, since the license in
github explicitly says that you need to reproduce that license.


> Regards,
> Gary
> 
> On Fri, Oct 14, 2016 at 7:32 PM, Gary Bisson
>  wrote:
> > Hi,
> > 
> > I am wondering why the w127x and wl128x firmware files have not been
> > updated to their latest version (since Jan 2014)?
> > 
> > The current version in the linux-firmware repo are:
> > - 6.3.10.0.133 for single-role
> > - 6.5.7.0.42 for multi-role
> > 
> > Looking at TI's forum[1], they recommend using the latest one to avoid
> > issues like firmware reload:
> > - 6.3.10.0.139 for single-role
> > - 6.5.7.0.47 for multi-role
> > 
> > The up-to-date firmware files can be found in the following repo:
> > https://github.com/TI-OpenLink/ti-utils/tree/master/hw/firmware
> > 
> > What is the procedure to update them, does it need to be a TI employee
> > that sends the patch? The former wl12xx maintainer (Luciano Coelho)
> > seems to work for Intel now.

Right, I'm not working for TI anymore, so there's nothing that I can do
for you.  If I were you, I'd keep poking at current TI developers to
see if they can send these new FW versions to linux-firmware.git.  They
probably even have newer versions than the ones published in github.


> > Regards,
> > Gary
> > 
> > [1] 
> > https://e2e.ti.com/support/wireless_connectivity/wilink_wifi_bluetooth/f/307/p/350832/1236099#1236099


--
Cheers,
Luca.