Re: wcn36xx: bug #538: stuck tx management frames

2018-05-24 Thread Ramon Fried
On Thu, May 24, 2018 at 3:39 PM, Kalle Valo  wrote:
> Daniel Mack  writes:
>
>> On Thursday, May 24, 2018 01:48 PM, Kalle Valo wrote:
>>> Daniel Mack  writes:
 On Thursday, May 24, 2018 10:44 AM, Kalle Valo wrote:
> Daniel Mack  writes:
>>
 It seems that once a network is successfully joined, the network
 stability is fine. I haven't seen any starvation of streams lately, at
 least not with the the patches in this series which I'm running since
 a while. That is, until a disconnect/reconnect attempt is made, and at
 this point, only management frames are involved.
>>>
>>> Ah, maybe originally you were seeing different issues with similar
>>> symptoms? But now you have fixed the other bugsand now the stuck
>>> transmitted management frame issue is left? Just guessing...
>>
>> Yeah, I wish I had a clearer picture on all this myself :(
>>
>> My patches definitely address some of the issues I have seen before,
>> also the fixes for potential race conditions are likely to have a
>> positive effect. But as you guessed yourself, I'm afraid that there's
>> a multitude of possible sources for bugs, so it's hard to tell.
>
> Sure, but things seem to going be forward in steady state. Thanks for
> your hard work!
>
>>> It would be great to have wcn36xx logging via tracing, just like ath10k
>>> and iwlwifi does. This way logging shouldn't slow down the system too
>>> much and with wpasupplicant's -T switch you can even get wpasupplicant's
>>> debug messages to the same log with proper timestamps! And almost
>>> forgot, you can also include mac80211 tracing logs as well:
>>>
>>> https://wireless.wiki.kernel.org/en/developers/documentation/mac80211/tracing
>>>
>>> https://wireless.wiki.kernel.org/en/users/drivers/ath10k/debug#tracing
>>>
>>> See ath10k_dbg() and trace_ath10k_log_dbg() for ideas how to implement
>>> this, and you can also take a look at iwlwifi. Should be pretty easy.
>>> Patches more than welcome :)
>>
>> Okay, I'll see if I can find some time to look into this.
>>
>> The reason why I didn't focus the logging possibilities is that I
>> looked at the SMD messages that are flying around which result from
>> ieee80211 API calls into the driver, and I can't seem to find anything
>> that's wrong, especially not before the timeouts occur. Hence, I don't
>> actually expect any oddness on the ieee80211 layer.
>>
>> But I agree that in general, better logging is certainly helpful.
>
> Yeah, I'm not expecting tracing logs to solve this case either but maybe
> we could find some hints. And it just makes it so much easier to see
> what's really happening from tracing logs instead trying to guess from
> the bug description. "a tracing log is worth a thousand words" ;)
>
> But if you don't have time to implement tracing support to wcn36xx
> hopefully someone else has, all one needs is a DragonBoard 410c. A
> simple project for a student or someone who wants to contribute
> something to the kernel.
I have time to do it. If nobody else started yet...
Thanks.
>
 It seems it does, yes. Tests at night seem to take a bit more time to
 make the effect happen. But then again, it could also be unrelated. I
 can't be certain at this point.
>>>
>>> Can you describe what kind of radio environment you have, is it a busy
>>> office complex? How many APs around etc?
>>
>> I've tried different environments. In the office with 15-20
>> laptops/mobiles in the room I see about 10-15 APs. At home, where I
>> did long-term nightly test, there's maybe a higher number of APs, but
>> fewer devices on the channel of the AP that I used for tests.
>>
>> I haven't used any more sophisticated environments like a sealed
>> reverberation chamber yet though.
>
> Ok, but please let me know if you see any differences caused by the
> environment.
>
> --
> Kalle Valo
>
> ___
> wcn36xx mailing list
> wcn3...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/wcn36xx


[PATCH v3] wcn36xx: Add support for Factory Test Mode (FTM)

2018-05-22 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

Introduce infrastructure for supporting Factory Test Mode (FTM) of the
wireless LAN subsystem. In order for the user space to access the
firmware in test mode the relevant netlink channel needs to be exposed
from the kernel driver.

The above is achieved as follows:
1) Register wcn36xx driver to testmode callback from netlink
2) Add testmode callback implementation to handle incoming FTM commands
3) Add FTM command packet structure
4) Add handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2)
5) Add generic handling for all PTT_MSG packets

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <ramon.fr...@linaro.org>
---
v3:
* fixed kbuild warning
v2:
* check for NULL after kmalloc
* don't assign value to ret.
 drivers/net/wireless/ath/wcn36xx/Makefile |   2 +
 drivers/net/wireless/ath/wcn36xx/hal.h|  16 ++
 drivers/net/wireless/ath/wcn36xx/main.c   |   3 +
 drivers/net/wireless/ath/wcn36xx/smd.c|  81 ++
 drivers/net/wireless/ath/wcn36xx/smd.h|   4 +
 drivers/net/wireless/ath/wcn36xx/testmode.c   | 149 ++
 drivers/net/wireless/ath/wcn36xx/testmode.h   |  46 ++
 drivers/net/wireless/ath/wcn36xx/testmode_i.h |  29 
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h|   2 +
 9 files changed, 332 insertions(+)
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.c
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.h
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode_i.h

diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile 
b/drivers/net/wireless/ath/wcn36xx/Makefile
index 3b09435104eb..582049f65735 100644
--- a/drivers/net/wireless/ath/wcn36xx/Makefile
+++ b/drivers/net/wireless/ath/wcn36xx/Makefile
@@ -6,3 +6,5 @@ wcn36xx-y +=   main.o \
smd.o \
pmc.o \
debug.o
+
+wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h 
b/drivers/net/wireless/ath/wcn36xx/hal.h
index 182963522941..8491b3cb3206 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2230,6 +2230,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg {
 
 } __packed;
 
+struct wcn36xx_hal_process_ptt_msg_req_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
+struct wcn36xx_hal_process_ptt_msg_rsp_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* FTM Command response status */
+   u32 ptt_msg_resp_status;
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
 struct update_edca_params_req_msg {
struct wcn36xx_hal_msg_header header;
 
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index 69d6be59d97f..ea14f87d11ff 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include "wcn36xx.h"
+#include "testmode.h"
 
 unsigned int wcn36xx_dbg_mask;
 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
@@ -1116,6 +1117,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
.sta_add= wcn36xx_sta_add,
.sta_remove = wcn36xx_sta_remove,
.ampdu_action   = wcn36xx_ampdu_action,
+
+   CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
 };
 
 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 8932af5e4d8d..fb0192b7ee99 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -292,12 +292,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header 
*hdr,
msg_body.header.len = sizeof(msg_body); \
} while (0) \
 
+#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \
+   do { \
+   memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \
+   p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \
+   p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \
+   p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \
+   } while (0)
+
 #define PREPARE_HAL_BUF(send_buf, msg_body) \
do {\
memset(send_buf, 0, msg_body.header.len);   \
memcpy(send_buf, _body, sizeof(msg_body));  \
} while (0) \
 
+#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \
+   do {\
+   memset(send_buf, 0, p_msg_body->header.len); \
+   memcpy(send_buf, p_msg_body, p_msg_body

[PATCH v2] wcn36xx: Add support for Factory Test Mode (FTM)

2018-05-18 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

Introduce infrastructure for supporting Factory Test Mode (FTM) of the
wireless LAN subsystem. In order for the user space to access the
firmware in test mode the relevant netlink channel needs to be exposed
from the kernel driver.

The above is achieved as follows:
1) Register wcn36xx driver to testmode callback from netlink
2) Add testmode callback implementation to handle incoming FTM commands
3) Add FTM command packet structure
4) Add handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2)
5) Add generic handling for all PTT_MSG packets

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <ramon.fr...@linaro.org>
---
v2:
* check for NULL after kmalloc
* don't assign value to ret.

 drivers/net/wireless/ath/wcn36xx/Makefile |   2 +
 drivers/net/wireless/ath/wcn36xx/hal.h|  16 ++
 drivers/net/wireless/ath/wcn36xx/main.c   |   3 +
 drivers/net/wireless/ath/wcn36xx/smd.c|  81 ++
 drivers/net/wireless/ath/wcn36xx/smd.h|   4 +
 drivers/net/wireless/ath/wcn36xx/testmode.c   | 151 ++
 drivers/net/wireless/ath/wcn36xx/testmode.h   |  46 ++
 drivers/net/wireless/ath/wcn36xx/testmode_i.h |  29 
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h|   2 +
 9 files changed, 334 insertions(+)
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.c
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.h
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode_i.h

diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile 
b/drivers/net/wireless/ath/wcn36xx/Makefile
index 3b09435104eb..582049f65735 100644
--- a/drivers/net/wireless/ath/wcn36xx/Makefile
+++ b/drivers/net/wireless/ath/wcn36xx/Makefile
@@ -6,3 +6,5 @@ wcn36xx-y +=   main.o \
smd.o \
pmc.o \
debug.o
+
+wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h 
b/drivers/net/wireless/ath/wcn36xx/hal.h
index 182963522941..8491b3cb3206 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2230,6 +2230,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg {
 
 } __packed;
 
+struct wcn36xx_hal_process_ptt_msg_req_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
+struct wcn36xx_hal_process_ptt_msg_rsp_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* FTM Command response status */
+   u32 ptt_msg_resp_status;
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
 struct update_edca_params_req_msg {
struct wcn36xx_hal_msg_header header;
 
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index 69d6be59d97f..ea14f87d11ff 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include "wcn36xx.h"
+#include "testmode.h"
 
 unsigned int wcn36xx_dbg_mask;
 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
@@ -1116,6 +1117,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
.sta_add= wcn36xx_sta_add,
.sta_remove = wcn36xx_sta_remove,
.ampdu_action   = wcn36xx_ampdu_action,
+
+   CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
 };
 
 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 8932af5e4d8d..fb0192b7ee99 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -292,12 +292,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header 
*hdr,
msg_body.header.len = sizeof(msg_body); \
} while (0) \
 
+#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \
+   do { \
+   memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \
+   p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \
+   p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \
+   p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \
+   } while (0)
+
 #define PREPARE_HAL_BUF(send_buf, msg_body) \
do {\
memset(send_buf, 0, msg_body.header.len);   \
memcpy(send_buf, _body, sizeof(msg_body));  \
} while (0) \
 
+#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \
+   do {\
+   memset(send_buf, 0, p_msg_body->header.len); \
+   memcpy(send_buf, p_msg_body, p_msg_body->header.len); \
+   } while (0)
+
 static i

Re: [PATCH] wcn36xx: Add support for Factory Test Mode (FTM)

2018-05-18 Thread Ramon Fried
On 17 May 2018 at 21:37, Jeff Johnson <jjohn...@codeaurora.org> wrote:
> On 2018-05-17 04:32, Ramon Fried wrote:
>>
>> From: Eyal Ilsar <eil...@codeaurora.org>
>
> ...
>>
>> +int wcn36xx_smd_process_ptt_msg(struct wcn36xx *wcn,
>> +   struct ieee80211_vif *vif, void *ptt_msg,
>> size_t len,
>> +   void **ptt_rsp_msg)
>> +{
>> +   struct wcn36xx_hal_process_ptt_msg_req_msg *p_msg_body;
>> +   int ret = 0;
>> +
>> +   mutex_lock(>hal_mutex);
>> +   p_msg_body = kmalloc(
>> +   sizeof(struct wcn36xx_hal_process_ptt_msg_req_msg) + len,
>> +   GFP_ATOMIC);
>
>
> NULL check required?
>
>> +   INIT_HAL_PTT_MSG(p_msg_body, len);
>> +

Thanks Jeff. will fix it and send again :)


[PATCH] wcn36xx: Add support for Factory Test Mode (FTM)

2018-05-17 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

Introduce infrastructure for supporting Factory Test Mode (FTM) of the
wireless LAN subsystem. In order for the user space to access the
firmware in test mode the relevant netlink channel needs to be exposed
from the kernel driver.

The above is achieved as follows:
1) Register wcn36xx driver to testmode callback from netlink
2) Add testmode callback implementation to handle incoming FTM commands
3) Add FTM command packet structure
4) Add handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2)
5) Add generic handling for all PTT_MSG packets

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <ramon.fr...@linaro.org>
---
 drivers/net/wireless/ath/wcn36xx/Makefile |   2 +
 drivers/net/wireless/ath/wcn36xx/hal.h|  16 ++
 drivers/net/wireless/ath/wcn36xx/main.c   |   3 +
 drivers/net/wireless/ath/wcn36xx/smd.c|  74 +
 drivers/net/wireless/ath/wcn36xx/smd.h|   4 +
 drivers/net/wireless/ath/wcn36xx/testmode.c   | 151 ++
 drivers/net/wireless/ath/wcn36xx/testmode.h   |  46 ++
 drivers/net/wireless/ath/wcn36xx/testmode_i.h |  29 
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h|   2 +
 9 files changed, 327 insertions(+)
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.c
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.h
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode_i.h

diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile 
b/drivers/net/wireless/ath/wcn36xx/Makefile
index 3b09435104eb..582049f65735 100644
--- a/drivers/net/wireless/ath/wcn36xx/Makefile
+++ b/drivers/net/wireless/ath/wcn36xx/Makefile
@@ -6,3 +6,5 @@ wcn36xx-y +=   main.o \
smd.o \
pmc.o \
debug.o
+
+wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h 
b/drivers/net/wireless/ath/wcn36xx/hal.h
index 182963522941..8491b3cb3206 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2230,6 +2230,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg {
 
 } __packed;
 
+struct wcn36xx_hal_process_ptt_msg_req_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
+struct wcn36xx_hal_process_ptt_msg_rsp_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* FTM Command response status */
+   u32 ptt_msg_resp_status;
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
 struct update_edca_params_req_msg {
struct wcn36xx_hal_msg_header header;
 
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index 69d6be59d97f..ea14f87d11ff 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include "wcn36xx.h"
+#include "testmode.h"
 
 unsigned int wcn36xx_dbg_mask;
 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
@@ -1116,6 +1117,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
.sta_add= wcn36xx_sta_add,
.sta_remove = wcn36xx_sta_remove,
.ampdu_action   = wcn36xx_ampdu_action,
+
+   CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
 };
 
 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 8932af5e4d8d..8eaf192f8bdb 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -292,12 +292,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header 
*hdr,
msg_body.header.len = sizeof(msg_body); \
} while (0) \
 
+#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \
+   do { \
+   memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \
+   p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \
+   p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \
+   p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \
+   } while (0)
+
 #define PREPARE_HAL_BUF(send_buf, msg_body) \
do {\
memset(send_buf, 0, msg_body.header.len);   \
memcpy(send_buf, _body, sizeof(msg_body));  \
} while (0) \
 
+#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \
+   do {\
+   memset(send_buf, 0, p_msg_body->header.len); \
+   memcpy(send_buf, p_msg_body, p_msg_body->header.len); \
+   } while (0)
+
 static int wcn36xx_smd_rsp_status_check(void *buf, size_t len)
 {
struct wcn

Re: [PATCH 02/10] wcn36xx: set DMA mask explicitly

2018-05-17 Thread Ramon Fried
On Wed, May 16, 2018 at 5:08 PM, Daniel Mack <dan...@zonque.org> wrote:
> The device takes 32-bit addresses only, so inform the DMA API about it.
> This is the default on msm8016, so that doesn't change anything, but
> it's best practice to be explicit.
>
> Signed-off-by: Daniel Mack <dan...@zonque.org>
> ---
>  drivers/net/wireless/ath/wcn36xx/main.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
> b/drivers/net/wireless/ath/wcn36xx/main.c
> index e3b91b3b38ef..e6330ad372b3 100644
> --- a/drivers/net/wireless/ath/wcn36xx/main.c
> +++ b/drivers/net/wireless/ath/wcn36xx/main.c
> @@ -1309,6 +1309,12 @@ static int wcn36xx_probe(struct platform_device *pdev)
> mutex_init(>hal_mutex);
> mutex_init(>scan_lock);
>
> +   ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32));
> +   if (ret < 0) {
> +   wcn36xx_err("failed to set DMA mask: %d\n", ret);
> +   goto out_wq;
> +   }
> +
> INIT_WORK(>scan_work, wcn36xx_hw_scan_worker);
>
> wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", 
> wcn36xx_smd_rsp_process, hw);
> --
> 2.14.3
>
>
> ___
> wcn36xx mailing list
> wcn3...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/wcn36xx
Acked-by: Ramon Fried <ramon.fr...@linaro.org>


Re: [PATCH 01/10] wcn36xx: fix buffer commit logic on TX path

2018-05-17 Thread Ramon Fried
le(wcn->dev,
> - skb->data,
> - skb->len,
> - DMA_TO_DEVICE);
> -   if (dma_mapping_error(wcn->dev, desc->src_addr_l)) {
> +   desc_skb->src_addr_l = dma_map_single(wcn->dev,
> + skb->data,
> + skb->len,
> + DMA_TO_DEVICE);
> +   if (dma_mapping_error(wcn->dev, desc_skb->src_addr_l)) {
> dev_err(wcn->dev, "unable to DMA map src_addr_l\n");
> ret = -ENOMEM;
> goto unlock;
> }
>
> -   ctl->skb = skb;
> -   desc->dst_addr_l = ch->dxe_wq;
> -   desc->fr_len = ctl->skb->len;
> -
> -   /* set dxe descriptor to VALID */
> -   desc->ctrl = ch->ctrl_skb;
> +   ctl_skb->skb = skb;
> +   desc_skb->dst_addr_l = ch->dxe_wq;
> +   desc_skb->fr_len = ctl_skb->skb->len;
>
> wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC2 >>> ",
> -(char *)desc, sizeof(*desc));
> +(char *)desc_skb, sizeof(*desc_skb));
> wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "SKB   >>> ",
> -    (char *)ctl->skb->data, ctl->skb->len);
> +(char *)ctl_skb->skb->data, ctl_skb->skb->len);
>
> /* Move the head of the ring to the next empty descriptor */
> -ch->head_blk_ctl = ctl->next;
> +ch->head_blk_ctl = ctl_skb->next;
> +
> +   /* Commit all previous writes and set descriptors to VALID */
> +   wmb();
> +   desc_skb->ctrl = ch->ctrl_skb;
> +   wmb();
> +   desc_bd->ctrl = ch->ctrl_bd;
>
> /*
>  * When connected and trying to send data frame chip can be in sleep
> --
> 2.14.3
>
>
> ___
> wcn36xx mailing list
> wcn3...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/wcn36xx

Acked-by: Ramon Fried <ramon.fr...@linaro.org>


Re: [PATCH 0/5] wcn36xx: scan related patches

2018-04-16 Thread Ramon Fried
On 16 April 2018 at 16:16, Daniel Mack  wrote:
> Here's another series of 5 patches for wcn36xx that address some issues
> with scanning. The first one is the most important one.
>
Nicely done. Thanks !
>
> Daniel
>
> Daniel Mack (5):
>   wcn36xx: abort scan request when 'dequeued' indicator is sent
>   wcn36xx: cancel pending scan request when interface goes down
>   wcn36xx: handle scan cancellation when firmware support is missing
>   wcn36xx: send bss_type in scan requests
>   wcn36xx: pass information elements in scan requests
>
>  drivers/net/wireless/ath/wcn36xx/hal.h |  8 +++-
>  drivers/net/wireless/ath/wcn36xx/main.c| 29 +
>  drivers/net/wireless/ath/wcn36xx/smd.c | 20 +---
>  drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  7 +--
>  4 files changed, 50 insertions(+), 14 deletions(-)
>
> --
> 2.14.3
>


Re: [PATCH] wcn36xx: use READ_ONCE() to access desc->ctrl

2018-04-11 Thread Ramon Fried
On 11 April 2018 at 09:58, Daniel Mack <dan...@zonque.org> wrote:
> On Tuesday, April 10, 2018 08:17 PM, Ramon Fried wrote:
>> On 10 April 2018 at 20:35, Daniel Mack <dan...@zonque.org> wrote:
>>> When accessing shared memory to check for the stat of submitted
>>> descriptors, make sure to use READ_ONCE(). This will guarantee the
>>> compiler treats these memory locations as volatile and doesn't apply
>>> any caching.
>>
>> The structure that is tested is not shared memory. It's accessed only
>> by the apps processor.
>
> Hmm? ctl->desc is of type struct wcn36xx_dxe_desc, which is packed and
> shared with the firmware. The WCN36xx_DXE_CTRL_VLD bit in ctrl bitfield
> is set by the firmware when a frame is valid, and before asserting the
> RX interrupt. So the host CPU must treat it as volatile and expect it to
> change.
>
> Am I reading this wrong?
>
No, you're right. I missed that.
>
> Thanks,
> Daniel


Re: [PATCH] wcn36xx: use READ_ONCE() to access desc->ctrl

2018-04-10 Thread Ramon Fried
On 10 April 2018 at 20:35, Daniel Mack  wrote:
> When accessing shared memory to check for the stat of submitted
> descriptors, make sure to use READ_ONCE(). This will guarantee the
> compiler treats these memory locations as volatile and doesn't apply
> any caching.
The structure that is tested is not shared memory. It's accessed only
by the apps processor.
In this case, caching does make sense.
I'm not sure regarding READ_ONCE in that context I'll have to do some
reading regarding that.
But I don't think this is right here.

Thanks,
Ramon
>
> While this doesn't fix any particular problem I ran into, it's best
> practice to do it this way.
>
> Note that this patch also removes the superflous extra condition check
> in the do-while loop in reap_tx_dxes(), as the loop will break
> instantly anyway in that case.
>
> Signed-off-by: Daniel Mack 
> ---
>  drivers/net/wireless/ath/wcn36xx/dxe.c | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
> b/drivers/net/wireless/ath/wcn36xx/dxe.c
> index 26e6c42f886a..c52f1c21ece9 100644
> --- a/drivers/net/wireless/ath/wcn36xx/dxe.c
> +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
> @@ -363,7 +363,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct 
> wcn36xx_dxe_ch *ch)
> spin_lock_irqsave(>lock, flags);
> ctl = ch->tail_blk_ctl;
> do {
> -   if (ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD)
> +   if (READ_ONCE(ctl->desc->ctrl) & WCN36xx_DXE_CTRL_VLD)
> break;
> if (ctl->skb) {
> dma_unmap_single(wcn->dev, ctl->desc->src_addr_l,
> @@ -382,8 +382,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct 
> wcn36xx_dxe_ch *ch)
> ctl->skb = NULL;
> }
> ctl = ctl->next;
> -   } while (ctl != ch->head_blk_ctl &&
> -  !(ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD));
> +   } while (ctl != ch->head_blk_ctl);
>
> ch->tail_blk_ctl = ctl;
> spin_unlock_irqrestore(>lock, flags);
> @@ -525,7 +524,7 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
> int_mask = WCN36XX_DXE_INT_CH3_MASK;
> }
>
> -   while (!(dxe->ctrl & WCN36xx_DXE_CTRL_VLD)) {
> +   while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) {
> skb = ctl->skb;
> dma_addr = dxe->dst_addr_l;
> ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC);
> --
> 2.14.3
>


Re: [PATCH 0/1] RFC: memory coherency and data races on TX path

2018-04-10 Thread Ramon Fried
On 10 April 2018 at 20:42, Daniel Mack  wrote:
> I found something that I believe might be an issue, and I have an
> idea on how to correct this, but unfortunately, this doesn't solve
> the issues I occasionally see with this driver. I'd still like to
> share it, because I might be totally mistaken in my understanding.
>
Thanks for sharing you idea. Are you aware of the recent patch I sent
that Loic Poulain
wrote that fixes a race issue in access to wcn36xx_dxe_tx_frame()  ?
Kalle just recently applied it to ath-next, I don't think it's
available yet upstream.
The patch was fixing something similar, perhaps it will solve the
issue you're experiencing.

> With no firmware code or documentation at hand, it's not exactly clear
> which assumption the firmware makes, but obviously, the driver and the
> firmware share memory to exchange descriptors that either contain
> control information or payload. The driver puts control descriptors
> and payload descriptors in a ring buffer in an interleaved fashion.
>
> When the driver wants to send an skb, it looks for a currently unused
> control descriptor, and then fills it, together with its directly
> chained payload descriptor. The descriptors are both marked valid and
> then the firmware is instructed to start processing the ringbuffer.
> In case the firmware is idle when wcn36xx_dxe_tx_frame() is entered,
> this is all fine. However, when sending many packets in a short time
> frame, there are cases when the firmware is still processing the ring
> buffer (iow, ch->reg_ctrl & WCN36xx_DXE_CH_CTRL_EN != 0), and in this
> case, writes to the shared memory area depict a data race. The local
> spinlock of course doesn't help to prevent that. OTOH, it should be
> completely fine to modify the descriptors while firmware is still
> reading them, as the firmware should only pay attention to such that
> are marked valid.
>
> There's a problem with the latter presumption however which looks like
> this in the driver code:
>
> desc->fr_len = ctl->skb->len;
> /* set dxe descriptor to VALID */
> desc->ctrl = ch->ctrl_skb;
>
The firmware won't start reading the descriptors until it receives an
interrupt from driver.
which in turn happen later in the function using: wcn36xx_dxe_write_register()
so I don't think reordering in this case make any problem.

> The CPU may very well reorder the two writes, even though the memory is
> allocated as coherent DMA. When that happens, the firmware may see a
> wrong length for a valid descriptor. A simple memory write barrier would
> suffice to solve this, but then again, there are two descriptors
> involved.
>
> My attempt to fix that restructures the code a bit and makes the
> payload descriptor valid first and then the control descriptor, both
> strongly ordered through memory fences. This however assumes that the
> firmware will ignore valid payload descriptors unless they have a
> valid control descriptor preceding them, but that's really just
> guessing.
>
> Does that make sense? As I said, I can't really say this improves
> anything, sadly, so I might be mistaken entirely. But I'll leave this
> here for further discussion. Ideally, somebody with access to the
> firmware sources could give an assessment whether this is an issue at
> all or not.
When I'm not sure regarding some implementation I consult with the
downstream pronto driver.
https://github.com/sultanqasim/qcom_wlan_prima

Did you look there if they actually placed wmb() ?

>
>
> Thanks,
> Daniel
>
>
> Daniel Mack (1):
>   wcn36xx: fix buffer commit logic on TX path
>
>  drivers/net/wireless/ath/wcn36xx/dxe.c | 75 
> +-
>  1 file changed, 38 insertions(+), 37 deletions(-)
>
> --
> 2.14.3
>


Re: [PATCH 3/3] wcn36xx: don't delete invalid bss indices

2018-04-03 Thread Ramon Fried


On 4/3/2018 7:51 PM, Daniel Mack wrote:
> The firmware code cannot cope with requests to remove BSS indices that have
> not previously been added. This primarily happens when the device is
> suspended and then resumed. ieee80211_reconfig() then calls into
> wcn36xx_bss_info_changed() with an empty bssid and BSS_CHANGED_BSSID set,
> which subsequently leads to a firmware crash:
>
> [   43.647928] qcom-wcnss-pil a204000.wcnss: fatal error received: 
> halMsg.c:4964:halMsg_DelBss: Invalid BSSIndex 0
> [   43.647959] remoteproc remoteproc0: crash detected in a204000.wcnss: type 
> fatal error
>
> To fix this, set bss_index to WCN36XX_HAL_BSS_INVALID_IDX for all bss
> that have not been configured in the firmware, and don't call into the
> firmware with invalid indices.
>
> Signed-off-by: Daniel Mack 
> ---
>  drivers/net/wireless/ath/wcn36xx/main.c | 1 +
>  drivers/net/wireless/ath/wcn36xx/smd.c  | 6 ++
>  2 files changed, 7 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
> b/drivers/net/wireless/ath/wcn36xx/main.c
> index 69d6be59d97f..32bbd6e2fd09 100644
> --- a/drivers/net/wireless/ath/wcn36xx/main.c
> +++ b/drivers/net/wireless/ath/wcn36xx/main.c
> @@ -953,6 +953,7 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw,
>  
>   mutex_lock(>conf_mutex);
>  
> + vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX;
>   list_add(_priv->list, >vif_list);
>   wcn36xx_smd_add_sta_self(wcn, vif);
>  
> diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
> b/drivers/net/wireless/ath/wcn36xx/smd.c
> index 8932af5e4d8d..5be07e40a86d 100644
> --- a/drivers/net/wireless/ath/wcn36xx/smd.c
> +++ b/drivers/net/wireless/ath/wcn36xx/smd.c
> @@ -1446,6 +1446,10 @@ int wcn36xx_smd_delete_bss(struct wcn36xx *wcn, struct 
> ieee80211_vif *vif)
>   int ret = 0;
>  
>   mutex_lock(>hal_mutex);
> +
> + if (vif_priv->bss_index == WCN36XX_HAL_BSS_INVALID_IDX)
> + goto out;
> +
>   INIT_HAL_MSG(msg_body, WCN36XX_HAL_DELETE_BSS_REQ);
>  
>   msg_body.bss_index = vif_priv->bss_index;
> @@ -1464,6 +1468,8 @@ int wcn36xx_smd_delete_bss(struct wcn36xx *wcn, struct 
> ieee80211_vif *vif)
>   wcn36xx_err("hal_delete_bss response failed err=%d\n", ret);
>   goto out;
>   }
> +
> + vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX;
>  out:
>   mutex_unlock(>hal_mutex);
>   return ret;
Interesting. I have never seen this bug before.
Do you have a way of recreating it so I can test it on my side ?

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH 1/3] wcn36xx: check for DMA mapping errors in wcn36xx_dxe_tx_frame()

2018-04-03 Thread Ramon Fried


On 4/3/2018 7:51 PM, Daniel Mack wrote:
> Bail out if the mapping fails. Even though this hasn't occured during
> tests, this unlikely case should still be handled.
>
> Signed-off-by: Daniel Mack <dan...@zonque.org>
> ---
>  drivers/net/wireless/ath/wcn36xx/dxe.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
> b/drivers/net/wireless/ath/wcn36xx/dxe.c
> index 6e9a3583c447..e8ad8f989ccd 100644
> --- a/drivers/net/wireless/ath/wcn36xx/dxe.c
> +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
> @@ -707,6 +707,11 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
> ctl->skb->data,
> ctl->skb->len,
> DMA_TO_DEVICE);
> + if (dma_mapping_error(wcn->dev, desc->src_addr_l)) {
> + dev_err(wcn->dev, "unable to DMA map src_addr_l\n");
> + ret = -ENOMEM;
> + goto unlock;
> + }
>  
>   desc->dst_addr_l = ch->dxe_wq;
>       desc->fr_len = ctl->skb->len;
I have the exact patch ready for submission, you got a head of me :)
Acked-by: Ramon Fried <rfr...@codeaurora.org>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2] wcn36xx: Disable 5GHz for wcn3610

2018-03-29 Thread Ramon Fried
(adding Bjorn Andersson)


On 3/29/2018 10:15 AM, Kalle Valo wrote:
> (adding devicetree list)
>
> Ramon Fried <rfr...@codeaurora.org> writes:
>
>> wcn3610 can only operate on 2.4GHz band due to RF limitation.
>> If wcn36xx digital block is associated with an external IRIS
>> RF module, retrieve the id and disable 5GHz band in case of
>> wcn3610 id.
>>
>> Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
>> ---
>> v2: fixed wrong assignment, which is logically introduces the 
>>  same behaviour, but for correctness.
>>
>>  drivers/net/wireless/ath/wcn36xx/main.c| 4 +++-
>>  drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
>>  2 files changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
>> b/drivers/net/wireless/ath/wcn36xx/main.c
>> index ab5be6d2c691..833531a68c95 100644
>> --- a/drivers/net/wireless/ath/wcn36xx/main.c
>> +++ b/drivers/net/wireless/ath/wcn36xx/main.c
>> @@ -1146,7 +1146,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
>>  BIT(NL80211_IFTYPE_MESH_POINT);
>>  
>>  wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = _band_2ghz;
>> -if (wcn->rf_id != RF_IRIS_WCN3620)
>> +if (wcn->rf_id != RF_IRIS_WCN3610 && wcn->rf_id != RF_IRIS_WCN3620)
>>  wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = _band_5ghz;
>>  
>>  wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
>> @@ -1248,6 +1248,8 @@ static int wcn36xx_platform_get_resources(struct 
>> wcn36xx *wcn,
>>  if (iris_node) {
>>  if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
>>  wcn->rf_id = RF_IRIS_WCN3620;
>> +else if (of_device_is_compatible(iris_node, "qcom,wcn3610"))
>> +wcn->rf_id = RF_IRIS_WCN3610;
>>  of_node_put(iris_node);
>>  }
> Should we document qcom,wcn3610 just like wcn3620 is:
>
> Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt:  
>   "qcom,wcn3620",
IMHO the mentioned bindings is related to the PIL (peripheral image loaded) 
which is just the firmware part and has
nothing to do with wifi frontend(IRIS).



Re: [PATCH] wcn36xx: Disable 5GHz for wcn3610

2018-03-29 Thread Ramon Fried


On 3/29/2018 9:58 AM, Rafał Miłecki wrote:
> On 03/29/2018 08:20 AM, Ramon Fried wrote:
>> wcn3610 can only operate on 2.4GHz band due to RF limitation.
>> If wcn36xx digital block is associated with an external IRIS
>> RF module, retrieve the id and disable 5GHz band in case of
>> wcn3610 id.
>>
>> Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
>> ---
>>  drivers/net/wireless/ath/wcn36xx/main.c    | 4 +++-
>>  drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
>>  2 files changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
>> b/drivers/net/wireless/ath/wcn36xx/main.c
>> index ab5be6d2c691..833531a68c95 100644
>> --- a/drivers/net/wireless/ath/wcn36xx/main.c
>> +++ b/drivers/net/wireless/ath/wcn36xx/main.c
>> @@ -1146,7 +1146,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
>>  BIT(NL80211_IFTYPE_MESH_POINT);
>>
>>  wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = _band_2ghz;
>> -    if (wcn->rf_id != RF_IRIS_WCN3620)
>> +    if (wcn->rf_id != RF_IRIS_WCN3610 && wcn->rf_id != RF_IRIS_WCN3620)
>>  wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = _band_5ghz;
>>
>>  wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
>> @@ -1248,6 +1248,8 @@ static int wcn36xx_platform_get_resources(struct 
>> wcn36xx *wcn,
>>  if (iris_node) {
>>  if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
>>  wcn->rf_id = RF_IRIS_WCN3620;
>> +    else if (of_device_is_compatible(iris_node, "qcom,wcn3610"))
>> +    wcn->rf_id = RF_IRIS_WCN3620;
>
> RF_IRIS_WCN3610 ?
You're correct. I also noticed just now.
Sent v2. Thanks.
>
> ___
> wcn36xx mailing list
> wcn3...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/wcn36xx



[PATCH v2] wcn36xx: Disable 5GHz for wcn3610

2018-03-29 Thread Ramon Fried
wcn3610 can only operate on 2.4GHz band due to RF limitation.
If wcn36xx digital block is associated with an external IRIS
RF module, retrieve the id and disable 5GHz band in case of
wcn3610 id.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
v2: fixed wrong assignment, which is logically introduces the 
same behaviour, but for correctness.

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

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..833531a68c95 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1146,7 +1146,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
BIT(NL80211_IFTYPE_MESH_POINT);
 
wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = _band_2ghz;
-   if (wcn->rf_id != RF_IRIS_WCN3620)
+   if (wcn->rf_id != RF_IRIS_WCN3610 && wcn->rf_id != RF_IRIS_WCN3620)
wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = _band_5ghz;
 
wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
@@ -1248,6 +1248,8 @@ static int wcn36xx_platform_get_resources(struct wcn36xx 
*wcn,
if (iris_node) {
if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
wcn->rf_id = RF_IRIS_WCN3620;
+   else if (of_device_is_compatible(iris_node, "qcom,wcn3610"))
+   wcn->rf_id = RF_IRIS_WCN3610;
of_node_put(iris_node);
}
 
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h 
b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 81017e6703b4..bc4d1a10d90e 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -95,6 +95,7 @@ enum wcn36xx_ampdu_state {
 #define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power)
 
 #define RF_UNKNOWN 0x
+#define RF_IRIS_WCN36100x3610
 #define RF_IRIS_WCN36200x3620
 
 static inline void buff_to_be(u32 *buf, size_t len)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] wcn36xx: Disable 5GHz for wcn3610

2018-03-29 Thread Ramon Fried
wcn3610 can only operate on 2.4GHz band due to RF limitation.
If wcn36xx digital block is associated with an external IRIS
RF module, retrieve the id and disable 5GHz band in case of
wcn3610 id.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/main.c| 4 +++-
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..833531a68c95 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1146,7 +1146,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
BIT(NL80211_IFTYPE_MESH_POINT);
 
wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = _band_2ghz;
-   if (wcn->rf_id != RF_IRIS_WCN3620)
+   if (wcn->rf_id != RF_IRIS_WCN3610 && wcn->rf_id != RF_IRIS_WCN3620)
wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = _band_5ghz;
 
wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
@@ -1248,6 +1248,8 @@ static int wcn36xx_platform_get_resources(struct wcn36xx 
*wcn,
if (iris_node) {
if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
wcn->rf_id = RF_IRIS_WCN3620;
+   else if (of_device_is_compatible(iris_node, "qcom,wcn3610"))
+   wcn->rf_id = RF_IRIS_WCN3620;
of_node_put(iris_node);
}
 
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h 
b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 81017e6703b4..bc4d1a10d90e 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -95,6 +95,7 @@ enum wcn36xx_ampdu_state {
 #define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power)
 
 #define RF_UNKNOWN 0x
+#define RF_IRIS_WCN36100x3610
 #define RF_IRIS_WCN36200x3620
 
 static inline void buff_to_be(u32 *buf, size_t len)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v3] wcn36xx: reduce verbosity of drivers messages

2018-03-26 Thread Ramon Fried
Hi Kalle.

Kind reminder. Is the patch ok ?

Thanks,

Ramon


On 2/27/2018 4:05 PM, Ramon Fried wrote:
> Whenever the WLAN interface is started the FW
> version and caps are printed.
> The caps now will be displayed only in debug mode.
> Firmware version will be displayed only once on first
> startup of the interface.
>
> Change-Id: I4db6ea7f384fe15eebe4c3ddb1d1ccab00094332
> Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
> ---
> v2: print the firwmare version as info but only
>   onetime.
> v3: change the static variable to a struct variable.
>
>  drivers/net/wireless/ath/wcn36xx/main.c|  3 ++-
>  drivers/net/wireless/ath/wcn36xx/smd.c | 18 ++
>  drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  2 ++
>  3 files changed, 14 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
> b/drivers/net/wireless/ath/wcn36xx/main.c
> index ab5be6d2c691..bfe9062bfa52 100644
> --- a/drivers/net/wireless/ath/wcn36xx/main.c
> +++ b/drivers/net/wireless/ath/wcn36xx/main.c
> @@ -261,7 +261,7 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
>  
>   for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) {
>   if (get_feat_caps(wcn->fw_feat_caps, i))
> - wcn36xx_info("FW Cap %s\n", wcn36xx_get_cap_name(i));
> + wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n", 
> wcn36xx_get_cap_name(i));
>   }
>  }
>  
> @@ -1283,6 +1283,7 @@ static int wcn36xx_probe(struct platform_device *pdev)
>   wcn = hw->priv;
>   wcn->hw = hw;
>   wcn->dev = >dev;
> + wcn->first_boot = true;
>   mutex_init(>conf_mutex);
>   mutex_init(>hal_mutex);
>   mutex_init(>scan_lock);
> diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
> b/drivers/net/wireless/ath/wcn36xx/smd.c
> index 2a4871ca9c72..1a5b4d57c0ac 100644
> --- a/drivers/net/wireless/ath/wcn36xx/smd.c
> +++ b/drivers/net/wireless/ath/wcn36xx/smd.c
> @@ -409,15 +409,17 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, 
> void *buf, size_t len)
>   wcn->fw_minor = rsp->start_rsp_params.version.minor;
>   wcn->fw_major = rsp->start_rsp_params.version.major;
>  
> - wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n",
> -  wcn->wlan_version, wcn->crm_version);
> -
> - wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n",
> -  wcn->fw_major, wcn->fw_minor,
> -  wcn->fw_version, wcn->fw_revision,
> -  rsp->start_rsp_params.stations,
> -  rsp->start_rsp_params.bssids);
> + if (wcn->first_boot) {
> + wcn->first_boot = false;
> + wcn36xx_info("firmware WLAN version '%s' and CRM version 
> '%s'\n",
> +  wcn->wlan_version, wcn->crm_version);
>  
> + wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u 
> bssids\n",
> +  wcn->fw_major, wcn->fw_minor,
> +  wcn->fw_version, wcn->fw_revision,
> +  rsp->start_rsp_params.stations,
> +  rsp->start_rsp_params.bssids);
> + }
>   return 0;
>  }
>  
> diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h 
> b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> index 81017e6703b4..5854adf43f3a 100644
> --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
> @@ -192,6 +192,8 @@ struct wcn36xx {
>   u8  crm_version[WCN36XX_HAL_VERSION_LENGTH + 1];
>   u8  wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1];
>  
> + boolfirst_boot;
> +
>   /* IRQs */
>   int tx_irq;
>   int rx_irq;



Re: [PATCH] wcn36xx: dequeue all pending indicator messages

2018-03-16 Thread Ramon Fried


On 3/16/2018 12:37 AM, Daniel Mack wrote:

In case wcn36xx_smd_rsp_process() is called more than once before
hal_ind_work was dispatched, the messages will end up in hal_ind_queue,
but wcn36xx_ind_smd_work() will only look at the first message in that
list.

Fix this by dequeing the messages from the list in a loop, and only stop
when it's empty.

Interesting. does it solve a specific bug ? can you elaborate ?


Signed-off-by: Daniel Mack 
---
  drivers/net/wireless/ath/wcn36xx/smd.c | 95 +++---
  1 file changed, 52 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 7cc29285e052..a6b5352f59e9 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -2409,54 +2409,63 @@ static void wcn36xx_ind_smd_work(struct work_struct 
*work)
  {
struct wcn36xx *wcn =
container_of(work, struct wcn36xx, hal_ind_work);
-   struct wcn36xx_hal_msg_header *msg_header;
-   struct wcn36xx_hal_ind_msg *hal_ind_msg;
-   unsigned long flags;
  
-	spin_lock_irqsave(>hal_ind_lock, flags);

+   for (;;) {
+   struct wcn36xx_hal_msg_header *msg_header;
+   struct wcn36xx_hal_ind_msg *hal_ind_msg;
+   unsigned long flags;
  
-	hal_ind_msg = list_first_entry(>hal_ind_queue,

-  struct wcn36xx_hal_ind_msg,
-  list);
-   list_del(wcn->hal_ind_queue.next);
-   spin_unlock_irqrestore(>hal_ind_lock, flags);
+   spin_lock_irqsave(>hal_ind_lock, flags);
  
-	msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg;

+   if (list_empty(>hal_ind_queue)) {
+   spin_unlock_irqrestore(>hal_ind_lock, flags);
+   return;
+   }
  
-	switch (msg_header->msg_type) {

-   case WCN36XX_HAL_COEX_IND:
-   case WCN36XX_HAL_DEL_BA_IND:
-   case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
-   break;
-   case WCN36XX_HAL_OTA_TX_COMPL_IND:
-   wcn36xx_smd_tx_compl_ind(wcn,
-hal_ind_msg->msg,
-hal_ind_msg->msg_len);
-   break;
-   case WCN36XX_HAL_MISSED_BEACON_IND:
-   wcn36xx_smd_missed_beacon_ind(wcn,
- hal_ind_msg->msg,
- hal_ind_msg->msg_len);
-   break;
-   case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
-   wcn36xx_smd_delete_sta_context_ind(wcn,
-  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;
-   case WCN36XX_HAL_SCAN_OFFLOAD_IND:
-   wcn36xx_smd_hw_scan_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);
+   hal_ind_msg = list_first_entry(>hal_ind_queue,
+  struct wcn36xx_hal_ind_msg,
+  list);
+   list_del(_ind_msg->list);
+   spin_unlock_irqrestore(>hal_ind_lock, flags);
+
+   msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg;
+
+   switch (msg_header->msg_type) {
+   case WCN36XX_HAL_COEX_IND:
+   case WCN36XX_HAL_DEL_BA_IND:
+   case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
+   break;
+   case WCN36XX_HAL_OTA_TX_COMPL_IND:
+   wcn36xx_smd_tx_compl_ind(wcn,
+hal_ind_msg->msg,
+hal_ind_msg->msg_len);
+   break;
+   case WCN36XX_HAL_MISSED_BEACON_IND:
+   wcn36xx_smd_missed_beacon_ind(wcn,
+ hal_ind_msg->msg,
+ hal_ind_msg->msg_len);
+   break;
+   case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
+   wcn36xx_smd_delete_sta_context_ind(wcn,
+  hal_ind_msg->msg,
+  
hal_ind_msg->msg_len);
+   break;
+   case WCN36XX_HAL_PRINT_REG_INFO_IND:
+   

[PATCH] wcn36xx: Fix firmware crash due to corrupted buffer address

2018-03-15 Thread Ramon Fried
From: Loic Poulain <loic.poul...@linaro.org>

wcn36xx_start_tx function retrieves the buffer descriptor from the
channel control queue to start filling tx buffer information. However,
nothing prevents this same buffer to be concurrently accessed in a
concurent tx call, leading to potential buffer coruption and firmware
crash (observed during iperf test). The channel control queue should
only be accessed and updated with the channel lock.

Fix this issue by using a local buffer descriptor which will be copied
in the thread-safe wcn36xx_dxe_tx_frame.

Note that buffer descriptor size is few bytes so the introduced copy
overhead is insignificant. Moreover, this allows to keep the locked
section minimal.

Signed-off-by: Loic Poulain <loic.poul...@linaro.org>
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c  | 13 -
 drivers/net/wireless/ath/wcn36xx/dxe.h  |  3 ++-
 drivers/net/wireless/ath/wcn36xx/txrx.c | 32 ++--
 3 files changed, 16 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 7d5ecaf02288..2c3b899a88fa 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -27,15 +27,6 @@
 #include "wcn36xx.h"
 #include "txrx.h"
 
-void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low)
-{
-   struct wcn36xx_dxe_ch *ch = is_low ?
-   >dxe_tx_l_ch :
-   >dxe_tx_h_ch;
-
-   return ch->head_blk_ctl->bd_cpu_addr;
-}
-
 static void wcn36xx_ccu_write_register(struct wcn36xx *wcn, int addr, int data)
 {
wcn36xx_dbg(WCN36XX_DBG_DXE,
@@ -648,6 +639,7 @@ void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn)
 
 int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
 struct wcn36xx_vif *vif_priv,
+struct wcn36xx_tx_bd *bd,
 struct sk_buff *skb,
 bool is_low)
 {
@@ -681,6 +673,9 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
ctl->skb = NULL;
desc = ctl->desc;
 
+   /* write buffer descriptor */
+   memcpy(ctl->bd_cpu_addr, bd, sizeof(*bd));
+
/* Set source address of the BD we send */
desc->src_addr_l = ctl->bd_phy_addr;
 
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h 
b/drivers/net/wireless/ath/wcn36xx/dxe.h
index 2bc376c5391b..ce580960d109 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.h
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.h
@@ -452,6 +452,7 @@ struct wcn36xx_dxe_mem_pool {
dma_addr_t  phy_addr;
 };
 
+struct wcn36xx_tx_bd;
 struct wcn36xx_vif;
 int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
 void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
@@ -463,8 +464,8 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
 int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
 int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
 struct wcn36xx_vif *vif_priv,
+struct wcn36xx_tx_bd *bd,
 struct sk_buff *skb,
 bool is_low);
 void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status);
-void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low);
 #endif /* _DXE_H_ */
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c 
b/drivers/net/wireless/ath/wcn36xx/txrx.c
index 22304edc5948..b1768ed6b0be 100644
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
@@ -272,21 +272,9 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
bool is_low = ieee80211_is_data(hdr->frame_control);
bool bcast = is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1);
-   struct wcn36xx_tx_bd *bd = wcn36xx_dxe_get_next_bd(wcn, is_low);
-
-   if (!bd) {
-   /*
-* TX DXE are used in pairs. One for the BD and one for the
-* actual frame. The BD DXE's has a preallocated buffer while
-* the skb ones does not. If this isn't true something is really
-* wierd. TODO: Recover from this situation
-*/
-
-   wcn36xx_err("bd address may not be NULL for BD DXE\n");
-   return -EINVAL;
-   }
+   struct wcn36xx_tx_bd bd;
 
-   memset(bd, 0, sizeof(*bd));
+   memset(, 0, sizeof(bd));
 
wcn36xx_dbg(WCN36XX_DBG_TX,
"tx skb %p len %d fc %04x sn %d %s %s\n",
@@ -296,10 +284,10 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
 
wcn36xx_dbg_dump(WCN36XX_DBG_TX_DUMP, "", skb->data, skb->len);
 
-   bd->dpu_rf = WCN36XX_BMU_WQ_TX;
+   bd.dpu_rf = WCN36XX_BMU_WQ_TX;
 
-   bd->tx_comp = !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS);
-   if (bd->tx_comp) {
+   bd.tx_comp = !!(info->flags &

[PATCH] wcn36xx: turn off probe response offloading

2018-03-14 Thread Ramon Fried
It appears that the WCN36xx firmware doesn't actually respond to
probe requests. Until it's resolved, switch the probe response
responsibility to the 802.11 layer to allow creation of
hidden SSID AP's.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/main.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..9d8c177ac7e1 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1155,8 +1155,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
wcn->hw->wiphy->cipher_suites = cipher_suites;
wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 
-   wcn->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
-
 #ifdef CONFIG_PM
wcn->hw->wiphy->wowlan = _support;
 #endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2] wcn36xx: Add support for FTM WLAN

2018-03-12 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

Introduce infrastructure for supporting Factory Test Mode (FTM) of the
wireless LAN subsystem. In order for the user space to access the
firmware in test mode the relevant netlink channel needs to be exposed
from the kernel driver.

The above is achieved as follows:
1) Register wcn36xx driver to testmode callback from netlink
2) Add testmode callback implementation to handle incoming FTM commands
3) Add FTM command packet structure
4) Add handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2)
5) Add generic handling for all PTT_MSG packets

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
v2: * changed commit msg
* remove unnecessary whitespace
* kept the stop/start as the messages do arrive, but
changed the documentation to explain the purpose.

 drivers/net/wireless/ath/wcn36xx/Makefile |   2 +
 drivers/net/wireless/ath/wcn36xx/hal.h|  16 +++
 drivers/net/wireless/ath/wcn36xx/main.c   |   3 +
 drivers/net/wireless/ath/wcn36xx/smd.c|  74 +++
 drivers/net/wireless/ath/wcn36xx/smd.h|   4 +
 drivers/net/wireless/ath/wcn36xx/testmode.c   | 173 ++
 drivers/net/wireless/ath/wcn36xx/testmode.h   |  46 +++
 drivers/net/wireless/ath/wcn36xx/testmode_i.h |  45 +++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h|   2 +
 9 files changed, 365 insertions(+)
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.c
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.h
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode_i.h

diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile 
b/drivers/net/wireless/ath/wcn36xx/Makefile
index 3b09435104eb..582049f65735 100644
--- a/drivers/net/wireless/ath/wcn36xx/Makefile
+++ b/drivers/net/wireless/ath/wcn36xx/Makefile
@@ -6,3 +6,5 @@ wcn36xx-y +=   main.o \
smd.o \
pmc.o \
debug.o
+
+wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h 
b/drivers/net/wireless/ath/wcn36xx/hal.h
index 182963522941..8491b3cb3206 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2230,6 +2230,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg {
 
 } __packed;
 
+struct wcn36xx_hal_process_ptt_msg_req_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
+struct wcn36xx_hal_process_ptt_msg_rsp_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* FTM Command response status */
+   u32 ptt_msg_resp_status;
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
 struct update_edca_params_req_msg {
struct wcn36xx_hal_msg_header header;
 
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index 8c2654075eb8..6b73da6f7fde 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include "wcn36xx.h"
+#include "testmode.h"
 
 unsigned int wcn36xx_dbg_mask;
 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
@@ -1119,6 +1120,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
.sta_add= wcn36xx_sta_add,
.sta_remove = wcn36xx_sta_remove,
.ampdu_action   = wcn36xx_ampdu_action,
+
+   CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
 };
 
 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 3048722f0484..c4c2fc6309bf 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -292,12 +292,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header 
*hdr,
msg_body.header.len = sizeof(msg_body); \
} while (0) \
 
+#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \
+   do { \
+   memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \
+   p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \
+   p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \
+   p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \
+   } while (0)
+
 #define PREPARE_HAL_BUF(send_buf, msg_body) \
do {\
memset(send_buf, 0, msg_body.header.len);   \
memcpy(send_buf, _body, sizeof(msg_body));  \
} while (0) \
 
+#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \
+   do {\
+   memset(send_buf, 0, p_

Re: [PATCH] wcn36xx: Add support for FTM WLAN

2018-03-11 Thread Ramon Fried


On 3/10/2018 11:45 AM, Kalle Valo wrote:
> Ramon Fried <rfr...@codeaurora.org> writes:
>
>> From: Eyal Ilsar <eil...@codeaurora.org>
>>
>> Introduced infrastructure for supporting FTM WLAN in user space exposing
>> the netlink channel from the kernel WLAN driver.
> What's FTM WLAN? Don't assume that people know all the acronyms.
FTM is factory test mode if I recall correctly, but you're right. I elaborate 
more in the commit message.
>
> This included:
>> 1) Registered wcn36xx driver to testmode callback from netlink
>> 2) Added testmode callback implementation to handle incoming FTM commands
>> 3) Added FTM command packet structure
>> 4) Added handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2)
>> 5) Added generic handling for all PTT_MSG packets
> I don't remember the english grammar terminology, but in the commit log
> use the form "register", "add" instead of "registered", "added".
OK. Will fix.
>> +struct wcn36xx_hal_process_ptt_msg_rsp_msg {
>> +struct wcn36xx_hal_msg_header header;
>> +
>> +/* FTM Command response status */
>> +u32   ptt_msg_resp_status;
> Unnecessary whitespace after u32.
Thanks.

>> +static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len,
>> +void **p_ptt_rsp_msg)
>> +{
>> +struct wcn36xx_hal_process_ptt_msg_rsp_msg *rsp;
>> +int ret = 0;
>> +
>> +ret = wcn36xx_smd_rsp_status_check(buf, len);
>> +if (ret)
>> +return ret;
>> +rsp = (struct wcn36xx_hal_process_ptt_msg_rsp_msg *)buf;
>> +wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length 
>> %d\n",
>> +rsp->header.len);
>> +wcn36xx_dbg_dump(WCN36XX_DBG_HAL_DUMP, "HAL_PTT_MSG_RSP:", rsp->ptt_msg,
>> +rsp->header.len - sizeof(rsp->ptt_msg_resp_status));
>> +if (rsp->header.len > 0) {
>> +*p_ptt_rsp_msg = kmalloc(rsp->header.len, GFP_ATOMIC);
>> +memcpy(*p_ptt_rsp_msg, rsp->ptt_msg, rsp->header.len);
>> +}
>> +return ret;
>> +}
> Adding few empty lines to the function would make it more readable.
Ok, I will add.
>> @@ -2330,6 +2399,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
>>  struct ieee80211_hw *hw = priv;
>>  struct wcn36xx *wcn = hw->priv;
>>  struct wcn36xx_hal_ind_msg *msg_ind;
>> +
>>  wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD <<< ", buf, len);
> Unrelated change.
Nice catch. thanks.
>> +int wcn36xx_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>> +  void *data, int len)
>> +{
>> +struct wcn36xx *wcn = hw->priv;
>> +struct nlattr *tb[WCN36XX_TM_ATTR_MAX + 1];
>> +int ret = 0;
>> +unsigned short attr;
>> +
>> +wcn36xx_dbg_dump(WCN36XX_DBG_TESTMODE_DUMP, "Data:", data, len);
>> +ret = nla_parse(tb, WCN36XX_TM_ATTR_MAX, data, len,
>> +wcn36xx_tm_policy, NULL);
>> +if (ret)
>> +return ret;
>> +
>> +if (!tb[WCN36XX_TM_ATTR_CMD])
>> +return -EINVAL;
>> +
>> +attr = nla_get_u16(tb[WCN36XX_TM_ATTR_CMD]);
>> +
>> +switch (attr) {
>> +case WCN36XX_TM_CMD_START:
>> +case WCN36XX_TM_CMD_STOP:
>> +// N/A to this driver as it does not need to switch state
>> +break;
> [...]
>
>> +enum wcn36xx_tm_cmd {
>> +/* For backwards compatibility
>> + */
>> +WCN36XX_TM_CMD_START = 1,
>> +
>> +/* For backwards compatibility
>> + */
>> +WCN36XX_TM_CMD_STOP = 2,
> This looks odd. If wcn36xx does not need START and STOP commands why add
> those in the first place?
AFAIK the user-space app sends these commands, but I will check again. in 
WCN36xx unlike ATH10k it's not needed to do any transition or replace the 
firmware
to go in test mode, but I assume that if this command arrives we should return 
success.

>



[PATCH] wcn36xx: calculate DXE default channel values

2018-03-11 Thread Ramon Fried
DXE channel defaults used hardcoded magic values.
Added bit definitions of the control register and
calculate this values in compilation for clarity.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.h | 104 +++--
 1 file changed, 99 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h 
b/drivers/net/wireless/ath/wcn36xx/dxe.h
index 73a14953920d..feb3cb7ee81f 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.h
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.h
@@ -140,12 +140,106 @@ H2H_TEST_RX_TX = DMA2
 #define WCN36XX_DXE_WQ_RX_L0xB
 #define WCN36XX_DXE_WQ_RX_H0x4
 
-/* TODO This must calculated properly but not hardcoded */
+/* Channel enable or restart */
+#define WCN36xx_DXE_CH_CTRL_EN BIT(0)
+/* End of packet bit */
+#define WCN36xx_DXE_CH_CTRL_EOPBIT(3)
+/* BD Handling bit */
+#define WCN36xx_DXE_CH_CTRL_BDHBIT(4)
+/* Source is queue */
+#define WCN36xx_DXE_CH_CTRL_SIQBIT(5)
+/* Destination is queue */
+#define WCN36xx_DXE_CH_CTRL_DIQBIT(6)
+/* Pointer descriptor is queue */
+#define WCN36xx_DXE_CH_CTRL_PIQBIT(7)
+/* Relase PDU when done */
+#define WCN36xx_DXE_CH_CTRL_PDU_RELBIT(8)
+/* Stop channel processing */
+#define WCN36xx_DXE_CH_CTRL_STOP   BIT(16)
+/* Enable external descriptor interrupt */
+#define WCN36xx_DXE_CH_CTRL_INE_ED BIT(17)
+/* Enable channel interrupt on errors */
+#define WCN36xx_DXE_CH_CTRL_INE_ERRBIT(18)
+/* Enable Channel interrupt when done */
+#define WCN36xx_DXE_CH_CTRL_INE_DONE   BIT(19)
+/* External descriptor enable */
+#define WCN36xx_DXE_CH_CTRL_EDEN   BIT(20)
+/* Wait for valid bit */
+#define WCN36xx_DXE_CH_CTRL_EDVEN  BIT(21)
+/* Endianness is little endian*/
+#define WCN36xx_DXE_CH_CTRL_ENDIANNESS BIT(26)
+/* Abort transfer */
+#define WCN36xx_DXE_CH_CTRL_ABORT  BIT(27)
+/* Long descriptor format */
+#define WCN36xx_DXE_CH_CTRL_DFMT   BIT(28)
+/* Endian byte swap enable */
+#define WCN36xx_DXE_CH_CTRL_SWAP   BIT(31)
+
+/* Transfer type */
+#define WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT 1
+#define WCN36xx_DXE_CH_CTRL_XTYPE_MASK GENMASK(2, 
WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)
+#define WCN36xx_DXE_CH_CTRL_XTYPE_SET(x)   ((x) << 
WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)
+
+/* Channel BMU Threshold select */
+#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT 9
+#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_MASK GENMASK(12, 
WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)
+#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(x) ((x) << 
WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)
+
+/* Channel Priority */
+#define WCN36xx_DXE_CH_CTRL_PRIO_SHIFT 13
+#define WCN36xx_DXE_CH_CTRL_PRIO_MASK GENMASK(15, 
WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)
+#define WCN36xx_DXE_CH_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)
+
+/* Counter select */
+#define WCN36xx_DXE_CH_CTRL_SEL_SHIFT 22
+#define WCN36xx_DXE_CH_CTRL_SEL_MASK GENMASK(25, WCN36xx_DXE_CH_CTRL_SEL_SHIFT)
+#define WCN36xx_DXE_CH_CTRL_SEL_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_SEL_SHIFT)
+
+/* Channel BD template index */
+#define WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT 29
+#define WCN36xx_DXE_CH_CTRL_BDT_IDX_MASK GENMASK(30, 
WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)
+#define WCN36xx_DXE_CH_CTRL_BDT_IDX_SET(x) ((x) << 
WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)
+
 /* DXE default control register values */
-#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L0x847EAD2F
-#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H0x84FED12F
-#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H0x853ECF4D
-#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L0x843e8b4d
+#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L (WCN36xx_DXE_CH_CTRL_EN | \
+   WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
+   WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
+   WCN36xx_DXE_CH_CTRL_PDU_REL | 
WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(6) | \
+   WCN36xx_DXE_CH_CTRL_PRIO_SET(5) | WCN36xx_DXE_CH_CTRL_INE_ED | \
+   WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
+   WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
+   WCN36xx_DXE_CH_CTRL_SEL_SET(1) | WCN36xx_DXE_CH_CTRL_ENDIANNESS 
| \
+   WCN36xx_DXE_CH_CTRL_SWAP)
+
+#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H (WCN36xx_DXE_CH_CTRL_EN | \
+   WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
+   WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
+   WCN36xx_DXE_CH_CTRL_PDU_REL | 
WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(8) | \
+   WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \
+   WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
+   

[PATCH] wcn36xx: Check DXE IRQ reason

2018-03-11 Thread Ramon Fried
IRQ reason was not cheked for errors.
Although error handing is not currently supported, it
will be nice to output an error value to the log if the
DMA operation failed.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c | 50 +-
 drivers/net/wireless/ath/wcn36xx/dxe.h |  4 +++
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 8e4d6d9ea277..7d5ecaf02288 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -415,14 +415,31 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void 
*dev)
  WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H,
  _reason);
 
-   /* TODO: Check int_reason */
-
wcn36xx_dxe_write_register(wcn,
   WCN36XX_DXE_0_INT_CLR,
   WCN36XX_INT_MASK_CHAN_TX_H);
 
-   wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR,
-  WCN36XX_INT_MASK_CHAN_TX_H);
+   if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) {
+   wcn36xx_dxe_write_register(wcn,
+  WCN36XX_DXE_0_INT_ERR_CLR,
+  WCN36XX_INT_MASK_CHAN_TX_H);
+
+   wcn36xx_err("DXE IRQ reported error: 0x%x in high TX 
channel\n",
+   int_src);
+   }
+
+   if (int_reason & WCN36XX_CH_STAT_INT_DONE_MASK) {
+   wcn36xx_dxe_write_register(wcn,
+  WCN36XX_DXE_0_INT_DONE_CLR,
+  WCN36XX_INT_MASK_CHAN_TX_H);
+   }
+
+   if (int_reason & WCN36XX_CH_STAT_INT_ED_MASK) {
+   wcn36xx_dxe_write_register(wcn,
+  WCN36XX_DXE_0_INT_ED_CLR,
+  WCN36XX_INT_MASK_CHAN_TX_H);
+   }
+
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n");
reap_tx_dxes(wcn, >dxe_tx_h_ch);
}
@@ -431,14 +448,33 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void 
*dev)
wcn36xx_dxe_read_register(wcn,
  WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L,
  _reason);
-   /* TODO: Check int_reason */
 
wcn36xx_dxe_write_register(wcn,
   WCN36XX_DXE_0_INT_CLR,
   WCN36XX_INT_MASK_CHAN_TX_L);
 
-   wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR,
-  WCN36XX_INT_MASK_CHAN_TX_L);
+
+   if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) {
+   wcn36xx_dxe_write_register(wcn,
+  WCN36XX_DXE_0_INT_ERR_CLR,
+  WCN36XX_INT_MASK_CHAN_TX_L);
+
+   wcn36xx_err("DXE IRQ reported error: 0x%x in low TX 
channel\n",
+   int_src);
+   }
+
+   if (int_reason & WCN36XX_CH_STAT_INT_DONE_MASK) {
+   wcn36xx_dxe_write_register(wcn,
+  WCN36XX_DXE_0_INT_DONE_CLR,
+  WCN36XX_INT_MASK_CHAN_TX_L);
+   }
+
+   if (int_reason & WCN36XX_CH_STAT_INT_ED_MASK) {
+   wcn36xx_dxe_write_register(wcn,
+  WCN36XX_DXE_0_INT_ED_CLR,
+  WCN36XX_INT_MASK_CHAN_TX_L);
+   }
+
wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n");
reap_tx_dxes(wcn, >dxe_tx_l_ch);
}
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h 
b/drivers/net/wireless/ath/wcn36xx/dxe.h
index feb3cb7ee81f..2bc376c5391b 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.h
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.h
@@ -262,6 +262,10 @@ H2H_TEST_RX_TX = DMA2
 #define WCN36XX_DXE_0_INT_DONE_CLR (WCN36XX_DXE_MEM_REG + 0x38)
 #define WCN36XX_DXE_0_INT_ERR_CLR  (WCN36XX_DXE_MEM_REG + 0x3C)
 
+#define WCN36XX_CH_STAT_INT_DONE_MASK   0x8000
+#define WCN36XX_CH_STAT_INT_ERR_MASK0x4000
+#define WCN36XX_CH_STAT_INT_ED_MASK 0x2000
+
 #define WCN36XX_DXE_0_CH0_STATUS   (WCN36XX_DXE_MEM_REG + 0x404)
 #define WCN36XX_DXE_0_CH1_STATUS  

Re: [PATCH] wcn36xx: calculate DXE control registers values

2018-03-10 Thread Ramon Fried


On 3/10/2018 11:47 AM, Kalle Valo wrote:
> Ramon Fried <rfr...@codeaurora.org> writes:
>
>> DXE descriptor control registers used hardcoded magic values. Added
>> bit definitions of the control register and calculate this values in
>> compilation for clarity.
>>
>> Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
> I assume that the values are still the same and there are no functional
> changes? If yes, I'll add that to the commit log when I commit this.
Yes. I double verified this. the values are the same.



[PATCH] wcn36xx: calculate DXE control registers values

2018-03-04 Thread Ramon Fried
DXE descriptor control registers used hardcoded magic
values.
Added bit definitions of the control register and
calculate this values in compilation for clarity.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c |   6 +-
 drivers/net/wireless/ath/wcn36xx/dxe.h | 112 +
 2 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index a3f1f7d042a4..8e4d6d9ea277 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -376,7 +376,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct 
wcn36xx_dxe_ch *ch)
spin_lock_irqsave(>lock, flags);
ctl = ch->tail_blk_ctl;
do {
-   if (ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)
+   if (ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD)
break;
if (ctl->skb) {
dma_unmap_single(wcn->dev, ctl->desc->src_addr_l,
@@ -397,7 +397,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct 
wcn36xx_dxe_ch *ch)
}
ctl = ctl->next;
} while (ctl != ch->head_blk_ctl &&
-  !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK));
+  !(ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD));
 
ch->tail_blk_ctl = ctl;
spin_unlock_irqrestore(>lock, flags);
@@ -503,7 +503,7 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
int_mask = WCN36XX_DXE_INT_CH3_MASK;
}
 
-   while (!(dxe->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) {
+   while (!(dxe->ctrl & WCN36xx_DXE_CTRL_VLD)) {
skb = ctl->skb;
dma_addr = dxe->dst_addr_l;
ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl);
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h 
b/drivers/net/wireless/ath/wcn36xx/dxe.h
index c012e807753b..73a14953920d 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.h
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.h
@@ -33,15 +33,106 @@ H2H_TEST_RX_TX = DMA2
 #define WCN36XX_CCU_DXE_INT_SELECT_RIVA0x310
 #define WCN36XX_CCU_DXE_INT_SELECT_PRONTO  0x10dc
 
-/* TODO This must calculated properly but not hardcoded */
-#define WCN36XX_DXE_CTRL_TX_L  0x328a44
-#define WCN36XX_DXE_CTRL_TX_H  0x32ce44
-#define WCN36XX_DXE_CTRL_RX_L  0x12ad2f
-#define WCN36XX_DXE_CTRL_RX_H  0x12d12f
-#define WCN36XX_DXE_CTRL_TX_H_BD   0x30ce45
-#define WCN36XX_DXE_CTRL_TX_H_SKB  0x32ce4d
-#define WCN36XX_DXE_CTRL_TX_L_BD   0x308a45
-#define WCN36XX_DXE_CTRL_TX_L_SKB  0x328a4d
+/* Descriptor valid */
+#define WCN36xx_DXE_CTRL_VLD   BIT(0)
+/* End of packet */
+#define WCN36xx_DXE_CTRL_EOP   BIT(3)
+/* BD handling bit */
+#define WCN36xx_DXE_CTRL_BDH   BIT(4)
+/* Source is a queue */
+#define WCN36xx_DXE_CTRL_SIQ   BIT(5)
+/* Destination is a queue */
+#define WCN36xx_DXE_CTRL_DIQ   BIT(6)
+/* Pointer address is a queue */
+#define WCN36xx_DXE_CTRL_PIQ   BIT(7)
+/* Release PDU when done */
+#define WCN36xx_DXE_CTRL_PDU_REL   BIT(8)
+/* STOP channel processing */
+#define WCN36xx_DXE_CTRL_STOP  BIT(16)
+/* INT on descriptor done */
+#define WCN36xx_DXE_CTRL_INT   BIT(17)
+/* Endian byte swap enable */
+#define WCN36xx_DXE_CTRL_SWAP  BIT(20)
+/* Master endianness */
+#define WCN36xx_DXE_CTRL_ENDIANNESSBIT(21)
+
+/* Transfer type */
+#define WCN36xx_DXE_CTRL_XTYPE_SHIFT 1
+#define WCN36xx_DXE_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CTRL_XTYPE_SHIFT)
+#define WCN36xx_DXE_CTRL_XTYPE_SET(x)  ((x) << WCN36xx_DXE_CTRL_XTYPE_SHIFT)
+
+/* BMU Threshold select */
+#define WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT 9
+#define WCN36xx_DXE_CTRL_BTHLD_SEL_MASK GENMASK(12, 
WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)
+#define WCN36xx_DXE_CTRL_BTHLD_SEL_SET(x) ((x) << 
WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)
+
+/* Priority */
+#define WCN36xx_DXE_CTRL_PRIO_SHIFT 13
+#define WCN36xx_DXE_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CTRL_PRIO_SHIFT)
+#define WCN36xx_DXE_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CTRL_PRIO_SHIFT)
+
+/* BD Template index */
+#define WCN36xx_DXE_CTRL_BDT_IDX_SHIFT 18
+#define WCN36xx_DXE_CTRL_BDT_IDX_MASK GENMASK(19, 
WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)
+#define WCN36xx_DXE_CTRL_BDT_IDX_SET(x) ((x) << WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)
+
+/* Transfer types: */
+/* Host to host */
+#define WCN36xx_DXE_XTYPE_H2H (0)
+/* Host to BMU */
+#define WCN36xx_DXE_XTYPE_H2B (2)
+/* BMU to host */
+#define WCN36xx_DXE_XTYPE_B2H (3)
+
+#define WCN36XX_DXE_CTRL_TX_L  
(WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
+   WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \
+   WCN36xx_DXE_CTRL_P

[PATCH] wcn36xx: Add support for FTM WLAN

2018-02-27 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

Introduced infrastructure for supporting FTM WLAN in user space exposing
the netlink channel from the kernel WLAN driver. This included:
1) Registered wcn36xx driver to testmode callback from netlink
2) Added testmode callback implementation to handle incoming FTM commands
3) Added FTM command packet structure
4) Added handling for GET_BUILD_RELEASE_NUMBER (msgid=0x32A2)
5) Added generic handling for all PTT_MSG packets

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/Makefile |   2 +
 drivers/net/wireless/ath/wcn36xx/hal.h|  16 +++
 drivers/net/wireless/ath/wcn36xx/main.c   |   3 +
 drivers/net/wireless/ath/wcn36xx/smd.c|  72 
 drivers/net/wireless/ath/wcn36xx/smd.h|   4 +
 drivers/net/wireless/ath/wcn36xx/testmode.c   | 161 ++
 drivers/net/wireless/ath/wcn36xx/testmode.h   |  42 +++
 drivers/net/wireless/ath/wcn36xx/testmode_i.h |  41 +++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h|   2 +
 9 files changed, 343 insertions(+)
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.c
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode.h
 create mode 100644 drivers/net/wireless/ath/wcn36xx/testmode_i.h

diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile 
b/drivers/net/wireless/ath/wcn36xx/Makefile
index 3b09435104eb..582049f65735 100644
--- a/drivers/net/wireless/ath/wcn36xx/Makefile
+++ b/drivers/net/wireless/ath/wcn36xx/Makefile
@@ -6,3 +6,5 @@ wcn36xx-y +=   main.o \
smd.o \
pmc.o \
debug.o
+
+wcn36xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h 
b/drivers/net/wireless/ath/wcn36xx/hal.h
index 182963522941..d2df6750e5f6 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2230,6 +2230,22 @@ struct wcn36xx_hal_switch_channel_rsp_msg {
 
 } __packed;
 
+struct wcn36xx_hal_process_ptt_msg_req_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
+struct wcn36xx_hal_process_ptt_msg_rsp_msg {
+   struct wcn36xx_hal_msg_header header;
+
+   /* FTM Command response status */
+   u32   ptt_msg_resp_status;
+   /* Actual FTM Command body */
+   u8 ptt_msg[0];
+} __packed;
+
 struct update_edca_params_req_msg {
struct wcn36xx_hal_msg_header header;
 
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index 8c2654075eb8..6b73da6f7fde 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include "wcn36xx.h"
+#include "testmode.h"
 
 unsigned int wcn36xx_dbg_mask;
 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
@@ -1119,6 +1120,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
.sta_add= wcn36xx_sta_add,
.sta_remove = wcn36xx_sta_remove,
.ampdu_action   = wcn36xx_ampdu_action,
+
+   CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
 };
 
 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 3048722f0484..b6f1e98395d0 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -292,12 +292,26 @@ static void init_hal_msg(struct wcn36xx_hal_msg_header 
*hdr,
msg_body.header.len = sizeof(msg_body); \
} while (0) \
 
+#define INIT_HAL_PTT_MSG(p_msg_body, ppt_msg_len) \
+   do { \
+   memset(p_msg_body, 0, sizeof(*p_msg_body) + ppt_msg_len); \
+   p_msg_body->header.msg_type = WCN36XX_HAL_PROCESS_PTT_REQ; \
+   p_msg_body->header.msg_version = WCN36XX_HAL_MSG_VERSION0; \
+   p_msg_body->header.len = sizeof(*p_msg_body) + ppt_msg_len; \
+   } while (0)
+
 #define PREPARE_HAL_BUF(send_buf, msg_body) \
do {\
memset(send_buf, 0, msg_body.header.len);   \
memcpy(send_buf, _body, sizeof(msg_body));  \
} while (0) \
 
+#define PREPARE_HAL_PTT_MSG_BUF(send_buf, p_msg_body) \
+   do {\
+   memset(send_buf, 0, p_msg_body->header.len); \
+   memcpy(send_buf, p_msg_body, p_msg_body->header.len); \
+   } while (0)
+
 static int wcn36xx_smd_rsp_status_check(void *buf, size_t len)
 {
struct wcn36xx_fw_msg_status_rsp *rsp;
@@ -742,6 +756,61 @@ int wcn36xx_smd_switch_channel(stru

[PATCH v3] wcn36xx: reduce verbosity of drivers messages

2018-02-27 Thread Ramon Fried
Whenever the WLAN interface is started the FW
version and caps are printed.
The caps now will be displayed only in debug mode.
Firmware version will be displayed only once on first
startup of the interface.

Change-Id: I4db6ea7f384fe15eebe4c3ddb1d1ccab00094332
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
v2: print the firwmare version as info but only
onetime.
v3: change the static variable to a struct variable.

 drivers/net/wireless/ath/wcn36xx/main.c|  3 ++-
 drivers/net/wireless/ath/wcn36xx/smd.c | 18 ++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  2 ++
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..bfe9062bfa52 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -261,7 +261,7 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
 
for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) {
if (get_feat_caps(wcn->fw_feat_caps, i))
-   wcn36xx_info("FW Cap %s\n", wcn36xx_get_cap_name(i));
+   wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n", 
wcn36xx_get_cap_name(i));
}
 }
 
@@ -1283,6 +1283,7 @@ static int wcn36xx_probe(struct platform_device *pdev)
wcn = hw->priv;
wcn->hw = hw;
wcn->dev = >dev;
+   wcn->first_boot = true;
mutex_init(>conf_mutex);
mutex_init(>hal_mutex);
mutex_init(>scan_lock);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 2a4871ca9c72..1a5b4d57c0ac 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -409,15 +409,17 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, 
void *buf, size_t len)
wcn->fw_minor = rsp->start_rsp_params.version.minor;
wcn->fw_major = rsp->start_rsp_params.version.major;
 
-   wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n",
-wcn->wlan_version, wcn->crm_version);
-
-   wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n",
-wcn->fw_major, wcn->fw_minor,
-wcn->fw_version, wcn->fw_revision,
-rsp->start_rsp_params.stations,
-rsp->start_rsp_params.bssids);
+   if (wcn->first_boot) {
+   wcn->first_boot = false;
+   wcn36xx_info("firmware WLAN version '%s' and CRM version 
'%s'\n",
+wcn->wlan_version, wcn->crm_version);
 
+   wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u 
bssids\n",
+wcn->fw_major, wcn->fw_minor,
+wcn->fw_version, wcn->fw_revision,
+rsp->start_rsp_params.stations,
+rsp->start_rsp_params.bssids);
+   }
return 0;
 }
 
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h 
b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 81017e6703b4..5854adf43f3a 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -192,6 +192,8 @@ struct wcn36xx {
u8  crm_version[WCN36XX_HAL_VERSION_LENGTH + 1];
u8  wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1];
 
+   boolfirst_boot;
+
/* IRQs */
int tx_irq;
int rx_irq;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2] wcn36xx: reduce verbosity of drivers messages

2018-02-27 Thread Ramon Fried
Whenever the WLAN interface is started the FW
version and caps are printed.
The caps now will be displayed only in debug mode.
Firmware version will be displayed only once on first
startup of the interface.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
v2: print the firwmare version as info but only
onetime.

 drivers/net/wireless/ath/wcn36xx/main.c |  2 +-
 drivers/net/wireless/ath/wcn36xx/smd.c  | 19 +++
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..8c2654075eb8 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -261,7 +261,7 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
 
for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) {
if (get_feat_caps(wcn->fw_feat_caps, i))
-   wcn36xx_info("FW Cap %s\n", wcn36xx_get_cap_name(i));
+   wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n", 
wcn36xx_get_cap_name(i));
}
 }
 
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 2a4871ca9c72..3048722f0484 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -385,6 +385,7 @@ out:return ret;
 
 static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len)
 {
+   static bool first = true;
struct wcn36xx_hal_mac_start_rsp_msg *rsp;
 
if (len < sizeof(*rsp))
@@ -409,15 +410,17 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, 
void *buf, size_t len)
wcn->fw_minor = rsp->start_rsp_params.version.minor;
wcn->fw_major = rsp->start_rsp_params.version.major;
 
-   wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n",
-wcn->wlan_version, wcn->crm_version);
-
-   wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n",
-wcn->fw_major, wcn->fw_minor,
-wcn->fw_version, wcn->fw_revision,
-rsp->start_rsp_params.stations,
-rsp->start_rsp_params.bssids);
+   if (first) {
+   first = false;
+   wcn36xx_info("firmware WLAN version '%s' and CRM version 
'%s'\n",
+wcn->wlan_version, wcn->crm_version);
 
+   wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u 
bssids\n",
+wcn->fw_major, wcn->fw_minor,
+wcn->fw_version, wcn->fw_revision,
+rsp->start_rsp_params.stations,
+rsp->start_rsp_params.bssids);
+   }
return 0;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] wcn36xx: reduce verbosity of drivers messages

2018-02-17 Thread Ramon Fried
Whenever the WLAN interface is started the FW
version and caps are printed, this info should appear as
debug info.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/main.c | 2 +-
 drivers/net/wireless/ath/wcn36xx/smd.c  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..8c2654075eb8 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -261,7 +261,7 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
 
for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) {
if (get_feat_caps(wcn->fw_feat_caps, i))
-   wcn36xx_info("FW Cap %s\n", wcn36xx_get_cap_name(i));
+   wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n", 
wcn36xx_get_cap_name(i));
}
 }
 
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 2a4871ca9c72..7c4d19b041bc 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -409,10 +409,10 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, 
void *buf, size_t len)
wcn->fw_minor = rsp->start_rsp_params.version.minor;
wcn->fw_major = rsp->start_rsp_params.version.major;
 
-   wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n",
+   wcn36xx_dbg(WCN36XX_DBG_HAL, "firmware WLAN version '%s' and CRM 
version '%s'\n",
 wcn->wlan_version, wcn->crm_version);
 
-   wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n",
+   wcn36xx_dbg(WCN36XX_DBG_HAL, "firmware API %u.%u.%u.%u, %u stations, %u 
bssids\n",
 wcn->fw_major, wcn->fw_minor,
 wcn->fw_version, wcn->fw_revision,
 rsp->start_rsp_params.stations,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v2] wcn36xx: release resources in case of error

2018-01-23 Thread Ramon Fried
wcn36xx_dxe_init() doesn't check for the return value
of wcn36xx_dxe_init_descs().
This patch releases the resources in case an error ocurred.

Change-Id: I924bd7489b60243c0a0cbaa716caf924f11d7587
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c | 48 +-
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index d5c810a8cc52..60bf9b25d07f 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -236,6 +236,16 @@ static int wcn36xx_dxe_init_descs(struct device *dev, 
struct wcn36xx_dxe_ch *wcn
return 0;
 }
 
+static void wcn36xx_dxe_deinit_descs(struct device *dev, struct wcn36xx_dxe_ch 
*wcn_ch)
+{
+   size_t size;
+
+   size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc);
+   dma_free_coherent(dev, size,
+   wcn_ch->cpu_addr,
+   wcn_ch->dma_addr);
+}
+
 static void wcn36xx_dxe_init_tx_bd(struct wcn36xx_dxe_ch *ch,
   struct wcn36xx_dxe_mem_pool *pool)
 {
@@ -722,7 +732,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   if (ret) {
+   dev_err(wcn->dev, "Error allocating descriptor\n");
+   return ret;
+   }
wcn36xx_dxe_init_tx_bd(>dxe_tx_l_ch, >data_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -740,7 +754,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   if (ret) {
+   dev_err(wcn->dev, "Error allocating descriptor\n");
+   goto out_err_txh_ch;
+   }
+
wcn36xx_dxe_init_tx_bd(>dxe_tx_h_ch, >mgmt_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -760,7 +779,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   if (ret) {
+   dev_err(wcn->dev, "Error allocating descriptor\n");
+   goto out_err_rxl_ch;
+   }
+
 
/* For RX we need to preallocated buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_l_ch);
@@ -790,7 +814,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch);
+   if (ret) {
+   dev_err(wcn->dev, "Error allocating descriptor\n");
+   goto out_err_rxh_ch;
+   }
 
/* For RX we need to prealocat buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_h_ch);
@@ -819,11 +847,19 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
 
ret = wcn36xx_dxe_request_irqs(wcn);
if (ret < 0)
-   goto out_err;
+   goto out_err_irq;
 
return 0;
 
-out_err:
+out_err_irq:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_h_ch);
+out_err_rxh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_l_ch);
+out_err_rxl_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_h_ch);
+out_err_txh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_l_ch);
+
return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: wcn36xx: release resources in case of error

2018-01-23 Thread Ramon Fried


On 1/22/2018 8:14 AM, Kalle Valo wrote:
> Ramon Fried <rfr...@codeaurora.org> wrote:
>
>> wcn36xx_dxe_init() doesn't check for the return value
>> of wcn36xx_dxe_init_descs().
>> This patch releases the resources in case an error ocurred.
>>
>> Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
> Doesn't compile:
Sorry Kalle, I mistakenly sent the wrong version of the patch :(
I will sent the correct one shortly.
>
> drivers/net/wireless/ath/wcn36xx/dxe.c: In function 
> ‘wcn36xx_dxe_deinit_descs’:
> drivers/net/wireless/ath/wcn36xx/dxe.c:243:15: error: ‘struct wcn36xx_dxe_ch’ 
> has no member named ‘desc_bum’
>   size = wcn_ch->desc_bum * sizeof(struct wcn36xx_dxe_desc);
>^
> drivers/net/wireless/ath/wcn36xx/dxe.c:244:20: error: ‘wcn’ undeclared (first 
> use in this function)
>   dma_free_coherent(wcn->dev, size,
> ^
> drivers/net/wireless/ath/wcn36xx/dxe.c:244:20: note: each undeclared 
> identifier is reported only once for each function it appears in
> drivers/net/wireless/ath/wcn36xx/dxe.c: In function ‘wcn36xx_dxe_init’:
> drivers/net/wireless/ath/wcn36xx/dxe.c:737:3: error: implicit declaration of 
> function ‘dev_error’ [-Werror=implicit-function-declaration]
>dev_error("Error allocating descriptor\n");
>^
> drivers/net/wireless/ath/wcn36xx/dxe.c:818:2: error: expected ‘;’ before ‘if’
>   if (ret) {
>   ^
> drivers/net/wireless/ath/wcn36xx/dxe.c:860:1: warning: label ‘out_err_txh_ch’ 
> defined but not used [-Wunused-label]
>  out_err_txh_ch:
>  ^
> drivers/net/wireless/ath/wcn36xx/dxe.c:856:1: warning: label ‘out_err_rxh_ch’ 
> defined but not used [-Wunused-label]
>  out_err_rxh_ch:
>  ^
> drivers/net/wireless/ath/wcn36xx/dxe.c:760:3: error: label ‘our_err_txh_ch’ 
> used but not defined
>goto our_err_txh_ch;
>^
> cc1: some warnings being treated as errors
> make[5]: *** [drivers/net/wireless/ath/wcn36xx/dxe.o] Error 1
> make[4]: *** [drivers/net/wireless/ath/wcn36xx] Error 2
> make[3]: *** [drivers/net/wireless/ath] Error 2
> make[2]: *** [drivers/net/wireless] Error 2
> make[1]: *** [drivers/net] Error 2
> make[1]: *** Waiting for unfinished jobs
> make: *** [drivers] Error 2
>
> Patch set to Changes Requested.
>



[PATCH] wcn36xx: release resources in case of error

2018-01-18 Thread Ramon Fried
wcn36xx_dxe_init() doesn't check for the return value
of wcn36xx_dxe_init_descs().
This patch releases the resources in case an error ocurred.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c | 48 +-
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index d5c810a8cc52..dc7129edac96 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -236,6 +236,16 @@ static int wcn36xx_dxe_init_descs(struct device *dev, 
struct wcn36xx_dxe_ch *wcn
return 0;
 }
 
+static void wcn36xx_dxe_deinit_descs(struct device *dev, struct wcn36xx_dxe_ch 
*wcn_ch)
+{
+   size_t size;
+
+   size = wcn_ch->desc_bum * sizeof(struct wcn36xx_dxe_desc);
+   dma_free_coherent(wcn->dev, size,
+   wcn_ch->cpu_addr,
+   wcn_ch->dma_addr);
+}
+
 static void wcn36xx_dxe_init_tx_bd(struct wcn36xx_dxe_ch *ch,
   struct wcn36xx_dxe_mem_pool *pool)
 {
@@ -722,7 +732,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   return ret;
+   }
wcn36xx_dxe_init_tx_bd(>dxe_tx_l_ch, >data_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -740,7 +754,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto our_err_txh_ch;
+   }
+
wcn36xx_dxe_init_tx_bd(>dxe_tx_h_ch, >mgmt_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -760,7 +779,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto out_err_rxl_ch;
+   }
+
 
/* For RX we need to preallocated buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_l_ch);
@@ -790,7 +814,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch)
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto out_err_rxh_ch;
+   }
 
/* For RX we need to prealocat buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_h_ch);
@@ -819,11 +847,19 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
 
ret = wcn36xx_dxe_request_irqs(wcn);
if (ret < 0)
-   goto out_err;
+   goto out_err_irq;
 
return 0;
 
-out_err:
+out_err_irq:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_h_ch);
+out_err_rxh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_l_ch);
+out_err_rxl_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_h_ch);
+out_err_txh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_l_ch);
+
return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] wcn36xx: release resources in case of error

2018-01-18 Thread Ramon Fried
wcn36xx_dxe_init() doesn't check for the return value
of wcn36xx_dxe_init_descs().
This patch releases the resources in case an error ocurred.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c | 48 +-
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index d5c810a8cc52..dc7129edac96 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -236,6 +236,16 @@ static int wcn36xx_dxe_init_descs(struct device *dev, 
struct wcn36xx_dxe_ch *wcn
return 0;
 }
 
+static void wcn36xx_dxe_deinit_descs(struct device *dev, struct wcn36xx_dxe_ch 
*wcn_ch)
+{
+   size_t size;
+
+   size = wcn_ch->desc_bum * sizeof(struct wcn36xx_dxe_desc);
+   dma_free_coherent(wcn->dev, size,
+   wcn_ch->cpu_addr,
+   wcn_ch->dma_addr);
+}
+
 static void wcn36xx_dxe_init_tx_bd(struct wcn36xx_dxe_ch *ch,
   struct wcn36xx_dxe_mem_pool *pool)
 {
@@ -722,7 +732,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   return ret;
+   }
wcn36xx_dxe_init_tx_bd(>dxe_tx_l_ch, >data_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -740,7 +754,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto our_err_txh_ch;
+   }
+
wcn36xx_dxe_init_tx_bd(>dxe_tx_h_ch, >mgmt_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -760,7 +779,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto out_err_rxl_ch;
+   }
+
 
/* For RX we need to preallocated buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_l_ch);
@@ -790,7 +814,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch)
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto out_err_rxh_ch;
+   }
 
/* For RX we need to prealocat buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_h_ch);
@@ -819,11 +847,19 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
 
ret = wcn36xx_dxe_request_irqs(wcn);
if (ret < 0)
-   goto out_err;
+   goto out_err_irq;
 
return 0;
 
-out_err:
+out_err_irq:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_h_ch);
+out_err_rxh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_l_ch);
+out_err_rxl_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_h_ch);
+out_err_txh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_l_ch);
+
return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] wcn36xx: release resources in case of error

2018-01-18 Thread Ramon Fried
wcn36xx_dxe_init() doesn't check for the return value
of wcn36xx_dxe_init_descs().
This patch releases the resources in case an error ocurred.

Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c | 48 +-
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c 
b/drivers/net/wireless/ath/wcn36xx/dxe.c
index d5c810a8cc52..dc7129edac96 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -236,6 +236,16 @@ static int wcn36xx_dxe_init_descs(struct device *dev, 
struct wcn36xx_dxe_ch *wcn
return 0;
 }
 
+static void wcn36xx_dxe_deinit_descs(struct device *dev, struct wcn36xx_dxe_ch 
*wcn_ch)
+{
+   size_t size;
+
+   size = wcn_ch->desc_bum * sizeof(struct wcn36xx_dxe_desc);
+   dma_free_coherent(wcn->dev, size,
+   wcn_ch->cpu_addr,
+   wcn_ch->dma_addr);
+}
+
 static void wcn36xx_dxe_init_tx_bd(struct wcn36xx_dxe_ch *ch,
   struct wcn36xx_dxe_mem_pool *pool)
 {
@@ -722,7 +732,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_l_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   return ret;
+   }
wcn36xx_dxe_init_tx_bd(>dxe_tx_l_ch, >data_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -740,7 +754,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for TX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_tx_h_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto our_err_txh_ch;
+   }
+
wcn36xx_dxe_init_tx_bd(>dxe_tx_h_ch, >mgmt_mem_pool);
 
/* Write channel head to a NEXT register */
@@ -760,7 +779,12 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX LOW channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_l_ch);
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto out_err_rxl_ch;
+   }
+
 
/* For RX we need to preallocated buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_l_ch);
@@ -790,7 +814,11 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
/***/
/* Init descriptors for RX HIGH channel */
/***/
-   wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch);
+   ret = wcn36xx_dxe_init_descs(wcn->dev, >dxe_rx_h_ch)
+   if (ret) {
+   dev_error("Error allocating descriptor\n");
+   goto out_err_rxh_ch;
+   }
 
/* For RX we need to prealocat buffers */
wcn36xx_dxe_ch_alloc_skb(wcn, >dxe_rx_h_ch);
@@ -819,11 +847,19 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn)
 
ret = wcn36xx_dxe_request_irqs(wcn);
if (ret < 0)
-   goto out_err;
+   goto out_err_irq;
 
return 0;
 
-out_err:
+out_err_irq:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_h_ch);
+out_err_rxh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_rx_l_ch);
+out_err_rxl_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_h_ch);
+out_err_txh_ch:
+   wcn36xx_dxe_deinit_descs(wcn->dev, >dxe_tx_l_ch);
+
return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v2] wcn36xx: Fix dynamic power saving

2017-12-11 Thread Ramon Fried
On Mon, Dec 11, 2017 at 10:52:22AM +0200, Loic Poulain wrote:
> Since driver does not report hardware dynamic power saving cap,
> this is up to the mac80211 to manage power saving timeout and
> state machine, using the ieee80211 config callback to report
> PS changes. This patch enables/disables PS mode according to
> the new configuration.
> 
> Remove old behaviour enabling PS mode in a static way, this make
> the device unusable when power save is enabled since device is
> forced to PS regardless RX/TX traffic.
> 

Hi.
I tried to see if this patch solves the ping delay once power save is
turned on and it appears it doesn't (log below).
I do see some change in the delay though in comparison to testing without the 
patch.
Bjorn, How did you test it ?

Thanks, Ramon.


root@dragonboard-410c:~# ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1): 56 data bytes
64 bytes from 192.168.0.1: seq=0 ttl=64 time=2.688 ms
64 bytes from 192.168.0.1: seq=1 ttl=64 time=1.593 ms
64 bytes from 192.168.0.1: seq=2 ttl=64 time=1.581 ms
64 bytes from 192.168.0.1: seq=3 ttl=64 time=1.466 ms
64 bytes from 192.168.0.1: seq=4 ttl=64 time=1.625 ms
64 bytes from 192.168.0.1: seq=5 ttl=64 time=1.620 ms
64 bytes from 192.168.0.1: seq=6 ttl=64 time=2.907 ms
64 bytes from 192.168.0.1: seq=7 ttl=64 time=1.426 ms
64 bytes from 192.168.0.1: seq=8 ttl=64 time=1.521 ms
64 bytes from 192.168.0.1: seq=9 ttl=64 time=1.543 ms
64 bytes from 192.168.0.1: seq=10 ttl=64 time=6.804 ms
64 bytes from 192.168.0.1: seq=11 ttl=64 time=1.562 ms
64 bytes from 192.168.0.1: seq=12 ttl=64 time=3.148 ms
64 bytes from 192.168.0.1: seq=13 ttl=64 time=1.568 ms
64 bytes from 192.168.0.1: seq=14 ttl=64 time=1.491 ms
64 bytes from 192.168.0.1: seq=15 ttl=64 time=2.884 ms
64 bytes from 192.168.0.1: seq=16 ttl=64 time=1.669 ms
64 bytes from 192.168.0.1: seq=17 ttl=64 time=1.556 ms
64 bytes from 192.168.0.1: seq=18 ttl=64 time=1.487 ms
64 bytes from 192.168.0.1: seq=19 ttl=64 time=1.377 ms
64 bytes from 192.168.0.1: seq=20 ttl=64 time=1.534 ms
^C
--- 192.168.0.1 ping statistics ---
21 packets transmitted, 21 packets received, 0% packet loss
round-trip min/avg/max = 1.377/2.050/6.804 ms
root@dragonboard-410c:~# iw dev wlan0 set power_save on
root@dragonboard-410c:~# ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1): 56 data bytes
64 bytes from 192.168.0.1: seq=0 ttl=64 time=4.849 ms
64 bytes from 192.168.0.1: seq=1 ttl=64 time=11.250 ms
64 bytes from 192.168.0.1: seq=2 ttl=64 time=11.402 ms
64 bytes from 192.168.0.1: seq=3 ttl=64 time=11.732 ms
64 bytes from 192.168.0.1: seq=4 ttl=64 time=10.076 ms
64 bytes from 192.168.0.1: seq=5 ttl=64 time=11.532 ms
64 bytes from 192.168.0.1: seq=6 ttl=64 time=15.479 ms
64 bytes from 192.168.0.1: seq=7 ttl=64 time=11.318 ms
64 bytes from 192.168.0.1: seq=8 ttl=64 time=13.299 ms
64 bytes from 192.168.0.1: seq=9 ttl=64 time=11.068 ms
64 bytes from 192.168.0.1: seq=10 ttl=64 time=11.087 ms
64 bytes from 192.168.0.1: seq=11 ttl=64 time=11.362 ms
64 bytes from 192.168.0.1: seq=12 ttl=64 time=11.341 ms
64 bytes from 192.168.0.1: seq=13 ttl=64 time=15.945 ms
64 bytes from 192.168.0.1: seq=14 ttl=64 time=11.318 ms
64 bytes from 192.168.0.1: seq=15 ttl=64 time=11.343 ms
64 bytes from 192.168.0.1: seq=16 ttl=64 time=11.378 ms
64 bytes from 192.168.0.1: seq=17 ttl=64 time=7.693 ms
64 bytes from 192.168.0.1: seq=18 ttl=64 time=11.703 ms
64 bytes from 192.168.0.1: seq=19 ttl=64 time=11.528 ms
64 bytes from 192.168.0.1: seq=20 ttl=64 time=12.008 ms
64 bytes from 192.168.0.1: seq=21 ttl=64 time=11.522 ms
64 bytes from 192.168.0.1: seq=22 ttl=64 time=12.949 ms
64 bytes from 192.168.0.1: seq=23 ttl=64 time=12.056 ms
64 bytes from 192.168.0.1: seq=24 ttl=64 time=13.097 ms
64 bytes from 192.168.0.1: seq=25 ttl=64 time=11.638 ms
^C
--- 192.168.0.1 ping statistics ---


> Acked-by: Bjorn Andersson 
> Signed-off-by: Loic Poulain 
> ---
>  v2: remove error msg on unbalanced bmps exit
>  return -EALREADY if not in bmps mode
> 
>  drivers/net/wireless/ath/wcn36xx/main.c | 23 ---
>  drivers/net/wireless/ath/wcn36xx/pmc.c  |  6 --
>  2 files changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/wcn36xx/main.c
> b/drivers/net/wireless/ath/wcn36xx/main.c
> index f0b4d43..436b8ea 100644
> --- a/drivers/net/wireless/ath/wcn36xx/main.c
> +++ b/drivers/net/wireless/ath/wcn36xx/main.c
> @@ -384,6 +384,18 @@ static int wcn36xx_config(struct ieee80211_hw *hw,
> u32 changed)
>   }
>   }
>  
> + if (changed & IEEE80211_CONF_CHANGE_PS) {
> + list_for_each_entry(tmp, >vif_list, list) {
> + vif = wcn36xx_priv_to_vif(tmp);
> + if (hw->conf.flags & IEEE80211_CONF_PS) {
> + if (vif->bss_conf.ps) /* ps allowed ? */
> + wcn36xx_pmc_enter_bmps_state(wcn,
> vif);
> + } else {
> + 

[PATCH v4] wcn36xx: Set default BTLE coexistence config

2017-11-16 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

If the value for the firmware configuration parameters
BTC_STATIC_LEN_LE_BT and BTC_STATIC_LEN_LE_WLAN are not set the duty
cycle between BT and WLAN is such that if BT (including BLE) is active
WLAN gets 0 bandwidth. When tuning these parameters having a too high
value for WLAN means that BLE performance degrades.
The "sweet" point of roughly half of the maximal values was empirically
found to achieve a balance between BLE and Wi-Fi coexistence
performance.

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/smd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 9c6590d5348a..6f1e741acf3e 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -73,6 +73,8 @@ static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = {
WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1),
WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1),
WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_BT, 12),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 3),
WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v3] wcn36xx: Set default BTLE coexistence config

2017-11-13 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

If the value for the firmware configuration parameters
BTC_STATIC_LEN_LE_BT and BTC_STATIC_LEN_LE_WLAN are not set the duty
cycle between BT and WLAN is such that if BT (including BLE) is active
WLAN gets 0 bandwidth. When tuning these parameters having a too high
value for WLAN means that BLE performance degrades.
The "sweet" point of roughly half of the maximal values was empirically
found to achieve a balance between BLE and Wi-Fi coexistence
performance.

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/smd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 9c6590d5348a..1c7598752255 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -72,8 +72,10 @@ static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = {
WCN36XX_CFG_VAL(DYNAMIC_PS_POLL_VALUE, 0),
WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1),
WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1),
-   WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_BT, 12),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 3),
WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
+   WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] wcn36xx: Set BTLE coexistence related configuration values to defaults

2017-11-12 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

If the value for the firmware configuration parameters BTC_STATIC_LEN_LE_BT
and BTC_STATIC_LEN_LE_WLAN are not set the duty cycle between BT and WLAN
is such that if BT (including BLE) is active WLAN gets 0 bandwidth.
When tuning these parameters having a too high value for WLAN means that BLE 
performance degrades.
The "sweet" point of roughly half of the maximal values was empirically found 
to achieve
a balance between BLE and Wi-Fi coexistence performance.

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/smd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 9c6590d..1c75987 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -72,8 +72,10 @@ struct wcn36xx_cfg_val {
WCN36XX_CFG_VAL(DYNAMIC_PS_POLL_VALUE, 0),
WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1),
WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1),
-   WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_BT, 12),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 3),
WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
+   WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH] wcn36xx: Set BTLE coexistence related configuration values to defaults

2017-11-12 Thread Ramon Fried
From: Eyal Ilsar <eil...@codeaurora.org>

Signed-off-by: Eyal Ilsar <eil...@codeaurora.org>
Signed-off-by: Ramon Fried <rfr...@codeaurora.org>
---
 drivers/net/wireless/ath/wcn36xx/main.c | 2 +-
 drivers/net/wireless/ath/wcn36xx/smd.c  | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/main.c 
b/drivers/net/wireless/ath/wcn36xx/main.c
index b83f01d..0d4ed41 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -27,7 +27,7 @@
 #include 
 #include "wcn36xx.h"
 
-unsigned int wcn36xx_dbg_mask;
+unsigned int wcn36xx_dbg_mask = WCN36XX_DBG_NONE;
 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
 MODULE_PARM_DESC(debug_mask, "Debugging mask");
 
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c 
b/drivers/net/wireless/ath/wcn36xx/smd.c
index 9c6590d..1c75987 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -72,8 +72,10 @@ struct wcn36xx_cfg_val {
WCN36XX_CFG_VAL(DYNAMIC_PS_POLL_VALUE, 0),
WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1),
WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1),
-   WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_BT, 12),
+   WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 3),
WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
+   WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project