Re: [PATCH 1/2] cfg80211/nl80211: Optional authentication offload to userspace

2017-12-14 Thread Marcel Holtmann
Hi Jouni,

> This interface allows the host driver to offload the authentication to
> user space. This is exclusively defined for host drivers that do not
> define separate commands for authentication and association, but rely on
> userspace SME (e.g., in wpa_supplicant for the ~WPA_DRIVER_FLAGS_SME
> case) for the authentication to happen. This can be used to implement
> SAE without full implementation in the kernel/firmware while still being
> able to use NL80211_CMD_CONNECT with driver-based BSS selection.
> 
> The host driver sends the NL80211_CMD_EXTERNAL_AUTH event to start/abort
> the authentication to userspace and status of authentication is further
> indicated by user space to host driver through the same command
> interface. Such drivers advertise the capability through
> NL80211_EXT_FEATURE_EXTERNAL_AUTH.

don’t we actually need a flag in NL80211_CMD_CONNECT that indicates that 
userspace is able to actually handle NL80211_CMD_EXTERNAL_AUTH. It is nice that 
there is feature for userspace to see if the driver supports it, but how is the 
driver able to offload successfully if it doesn’t know that userspace can do it.

Regards

Marcel



Re: [PATCH] nl80211: Introduce scan flags to emphasize requested scan behavior

2017-12-14 Thread Marcel Holtmann
Hi Jouni,

> This commit defines new scan flags (LOW_SPAN, LOW_POWER, HIGH_LATENCY)
> to emphasize the requested scan behavior for the driver. These flags are
> optional and are mutually exclusive. Driver shall resort to default
> behavior if a respective flag is not supported. The implementation of
> the respective functionality can be driver/hardware specific.

I really dislike falling back to some unspecified default behavior in case 
something is not supported. That is a really bad API towards userspace. Let the 
driver just fail and reject that operation. Userspace can define the policy and 
behavior if certain low power or high accuracy functionality is not available. 
Asking the kernel to do one thing and then the driver does whatever it wants 
anyway is Wireless Extensions behavior. We complained about it back then and 
falling back into the same pattern is bad.

And as Dan mentioned, just indicate the capabilities to userspace and then it 
knows what it can use. That means a good userspace will not use unsupported 
flags and a bad one gets hit with an error (which is a good thing).

Regards

Marcel



rsi_91x: Low bandwidth: sends ~100 Kbits/sec, receives ~1.5 Mbits/sec

2017-12-14 Thread Alexey Brodkin
Hi Amitkumar,

Yet another observation with RS-9113 module.
I managed to setup an access point on my board with RS-9113 connected either
via SDIO (this one is soldered on my board) or via USB (this is your RS9113
Evaluation Board Rev 4.0).

But regardless the module I use I still see the same bandwidth figures.
RS-9113 sends data at ~100 Kbits and receives at ~1.5-2 Mbits.
See below results of iperf3 runs (from development host side).

The board with RS-9113 acts as a server:
>8---
# iperf3 -c 192.168.111.1
Connecting to host 192.168.111.1, port 5201
[  4] local 192.168.111.64 port 43430 connected to 192.168.111.1 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.00   sec   328 KBytes  2.68 Mbits/sec0   31.1 KBytes   
[  4]   1.00-2.00   sec  63.6 KBytes   521 Kbits/sec1   31.1 KBytes   
[  4]   2.00-3.00   sec   191 KBytes  1.57 Mbits/sec0   31.1 KBytes   
[  4]   3.00-4.00   sec   191 KBytes  1.56 Mbits/sec0   32.5 KBytes   
[  4]   4.00-5.00   sec   191 KBytes  1.56 Mbits/sec0   36.8 KBytes   
[  4]   5.00-6.00   sec  63.6 KBytes   521 Kbits/sec0   38.2 KBytes   
[  4]   6.00-7.00   sec  63.6 KBytes   521 Kbits/sec0   38.2 KBytes   
[  4]   7.00-8.00   sec   191 KBytes  1.56 Mbits/sec0   48.1 KBytes   
[  4]   8.00-9.00   sec   255 KBytes  2.09 Mbits/sec0   48.1 KBytes   
[  4]   9.00-10.00  sec   191 KBytes  1.56 Mbits/sec0   48.1 KBytes   
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1.69 MBytes  1.42 Mbits/sec1 sender
[  4]   0.00-10.00  sec  1.39 MBytes  1.16 Mbits/sec  receiver
>8---

The board with RS-9113 acts as a server (but with "-R" it sends us data now):
>8---
# iperf3 -c 192.168.111.1 -R
Connecting to host 192.168.111.1, port 5201
Reverse mode, remote host 192.168.111.1 is sending
[  4] local 192.168.111.64 port 45230 connected to 192.168.111.1 port 5201
[ ID] Interval   Transfer Bandwidth
[  4]   0.00-1.14   sec  15.6 KBytes   112 Kbits/sec  
[  4]   1.14-2.00   sec  2.83 KBytes  27.0 Kbits/sec  
[  4]   2.00-3.00   sec  12.7 KBytes   104 Kbits/sec  
[  4]   3.00-4.00   sec  14.1 KBytes   116 Kbits/sec  
[  4]   4.00-5.00   sec  12.7 KBytes   104 Kbits/sec  
[  4]   5.00-6.00   sec  14.1 KBytes   116 Kbits/sec  
[  4]   6.00-7.00   sec  14.1 KBytes   116 Kbits/sec  
[  4]   7.00-8.00   sec  12.7 KBytes   104 Kbits/sec  
[  4]   8.00-9.00   sec  14.1 KBytes   116 Kbits/sec  
[  4]   9.00-10.00  sec  12.7 KBytes   104 Kbits/sec  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec   296 KBytes   242 Kbits/sec2 sender
[  4]   0.00-10.00  sec   254 KBytes   208 Kbits/sec  receiver  
>8---

My configurations are as below.
hostapd.conf:
>8---
interface=wlan0
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=AP_NAME
hw_mode=g
channel=1
>8---

wpa_supplicant.conf
>8---
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1

network={
ssid="AP_NAME"
psk="password"
}
>8---

Note I use vanilla Linux v4.14.4.

I'm wondering if you may see different results in your setup and if so
could you please suggest something for me to try.


Thanks in advance,
Alexey

P.S. I do remember about my previous email but so far I was not able to
get with the board to the place with "problematic" Wi-FI AP, once I get
there I'll grab longs for you.

RE: [PATCH] nl80211: Introduce scan flags to emphasize requested scan behavior

2017-12-14 Thread Sunil Dutt Undekari
> Can't we have some kind of capability indication that the driver supports 
> each of these flags or not?  Otherwise we get into a situation where you just 
> have to try the flag and hope it works, since it doesn't look like drivers 
> are required to error out if they don't support the flag.
Sure Dan . We shall have the support for capability indication from the driver.

Regards,
Sunil

 

-Original Message-
From: Dan Williams [mailto:d...@redhat.com] 
Sent: Thursday, December 14, 2017 12:40 AM
To: Jouni Malinen ; Johannes Berg 

Cc: linux-wireless@vger.kernel.org; Sunil Dutt Undekari 

Subject: Re: [PATCH] nl80211: Introduce scan flags to emphasize requested scan 
behavior

On Wed, 2017-12-13 at 19:52 +0200, Jouni Malinen wrote:
> From: Sunil Dutt 
> 
> This commit defines new scan flags (LOW_SPAN, LOW_POWER,
> HIGH_LATENCY)
> to emphasize the requested scan behavior for the driver. These flags 
> are optional and are mutually exclusive. Driver shall resort to 
> default behavior if a respective flag is not supported. The 
> implementation of the respective functionality can be driver/hardware 
> specific.

Can't we have some kind of capability indication that the driver supports each 
of these flags or not?  Otherwise we get into a situation where you just have 
to try the flag and hope it works, since it doesn't look like drivers are 
required to error out if they don't support the flag.

Dan

> These flags can be used to control the compromise between how long a 
> scan takes, how much power it uses, and high accurate/complete the 
> scan is in finding the BSSs.
> 
> Signed-off-by: Sunil Dutt 
> Signed-off-by: Jouni Malinen 
> ---
>  include/uapi/linux/nl80211.h | 23 ++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/include/uapi/linux/nl80211.h 
> b/include/uapi/linux/nl80211.h index 6dd6939..68fdb95 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -5059,6 +5059,11 @@ enum nl80211_timeout_reason {
>   * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
>   * requests.
>   *
> + * NL80211_SCAN_FLAG_LOW_SPAN, NL80211_SCAN_FLAG_LOW_POWER, and
> + * NL80211_SCAN_FLAG_HIGH_ACCURACY flags are exclusive of each
> other, i.e., only
> + * one of them can be used in the request. If the driver does not
> support the
> + * requested behavior, default scan behavior will be used instead.
> + *
>   * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority
>   * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning
>   * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is 
> configured @@ -5086,7 +5091,20 @@ enum nl80211_timeout_reason {
>   *   and suppression (if it has received a broadcast Probe
> Response frame,
>   *   Beacon frame or FILS Discovery frame from an AP that the
> STA considers
>   *   a suitable candidate for (re-)association - suitable in
> terms of
> - *   SSID and/or RSSI
> + *   SSID and/or RSSI.
> + * @NL80211_SCAN_FLAG_LOW_SPAN: Span corresponds to the total time
> taken to
> + *   accomplish the scan. Thus, this flag intends the driver to
> perform the
> + *   scan request with lesser span/duration. It is specific to
> the driver
> + *   implementations on how this is accomplished. Scan accuracy
> may get
> + *   impacted with this flag. This flag cannot be used with
> + * @NL80211_SCAN_FLAG_LOW_POWER: This flag intends the scan attempts
> to consume
> + *   optimal possible power. Drivers can resort to their
> specific means to
> + *   optimize the power. Scan accuracy may get impacted with
> this flag.
> + * @NL80211_SCAN_FLAG_HIGH_ACCURACY: Accuracy here intends to the
> extent of scan
> + *   results obtained. Thus HIGH_ACCURACY scan flag aims to get
> maximum
> + *   possible scan results. This flag hints the driver to use
> the best
> + *   possible scan configuration to improve the accuracy in
> scanning.
> + *   Latency and power use may get impacted with this flag.
>   */
>  enum nl80211_scan_flags {
>   NL80211_SCAN_FLAG_LOW_PRIORITY  
> = 1<<0,
> @@ -5097,6 +5115,9 @@ enum nl80211_scan_flags {
>   NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP   =
> 1<<5,
>   NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE
> = 1<<6,
>   NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION
> = 1<<7,
> + NL80211_SCAN_FLAG_LOW_SPAN  =
> 1<<8,
> + NL80211_SCAN_FLAG_LOW_POWER =
> 1<<9,
> + NL80211_SCAN_FLAG_HIGH_ACCURACY 
> = 1<<10,
>  };
>  
>  /**


[PATCH v2 2/9] wil6210: support 40bit DMA addresses

2017-12-14 Thread Maya Erez
From: Lazar Alexei 

Add the option to support 40bit addresses since some platforms
may not support 48bits but support 40bits

Signed-off-by: Lazar Alexei 
Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/pcie_bus.c | 26 +++---
 drivers/net/wireless/ath/wil6210/pmc.c  | 11 ++-
 drivers/net/wireless/ath/wil6210/txrx.c | 11 ++-
 drivers/net/wireless/ath/wil6210/wil6210.h  |  2 +-
 4 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c 
b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 42a5480..d4bb0bd 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -206,6 +206,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
.fw_recovery = wil_platform_rop_fw_recovery,
};
u32 bar_size = pci_resource_len(pdev, 0);
+   int dma_addr_size[] = {48, 40, 32}; /* keep descending order */
+   int i;
 
/* check HW */
dev_info(&pdev->dev, WIL_NAME
@@ -241,21 +243,23 @@ static int wil_pcie_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
}
/* rollback to err_plat */
 
-   /* device supports 48bit addresses */
-   rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
-   if (rc) {
-   dev_err(dev, "dma_set_mask_and_coherent(48) failed: %d\n", rc);
-   rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+   /* device supports >32bit addresses */
+   for (i = 0; i < ARRAY_SIZE(dma_addr_size); i++) {
+   rc = dma_set_mask_and_coherent(dev,
+  DMA_BIT_MASK(dma_addr_size[i]));
if (rc) {
-   dev_err(dev,
-   "dma_set_mask_and_coherent(32) failed: %d\n",
-   rc);
-   goto err_plat;
+   dev_err(dev, "dma_set_mask_and_coherent(%d) failed: 
%d\n",
+   dma_addr_size[i], rc);
+   continue;
}
-   } else {
-   wil->use_extended_dma_addr = 1;
+   dev_info(dev, "using dma mask %d", dma_addr_size[i]);
+   wil->dma_addr_size = dma_addr_size[i];
+   break;
}
 
+   if (wil->dma_addr_size == 0)
+   goto err_plat;
+
rc = pci_enable_device(pdev);
if (rc && pdev->msi_enabled == 0) {
wil_err(wil,
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c 
b/drivers/net/wireless/ath/wil6210/pmc.c
index 2e301b6..4ea27b0 100644
--- a/drivers/net/wireless/ath/wil6210/pmc.c
+++ b/drivers/net/wireless/ath/wil6210/pmc.c
@@ -111,14 +111,14 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
 *
 * HW has limitation that all vrings addresses must share the same
 * upper 16 msb bits part of 48 bits address. To workaround that,
-* if we are using 48 bit addresses switch to 32 bit allocation
-* before allocating vring memory.
+* if we are using more than 32 bit addresses switch to 32 bit
+* allocation before allocating vring memory.
 *
 * There's no check for the return value of dma_set_mask_and_coherent,
 * since we assume if we were able to set the mask during
 * initialization in this system it will not fail if we set it again
 */
-   if (wil->use_extended_dma_addr)
+   if (wil->dma_addr_size > 32)
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 
pmc->pring_va = dma_alloc_coherent(dev,
@@ -126,8 +126,9 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
&pmc->pring_pa,
GFP_KERNEL);
 
-   if (wil->use_extended_dma_addr)
-   dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+   if (wil->dma_addr_size > 32)
+   dma_set_mask_and_coherent(dev,
+ DMA_BIT_MASK(wil->dma_addr_size));
 
wil_dbg_misc(wil,
 "pmc_alloc: allocated pring %p => %pad. %zd x %d = total 
%zd bytes\n",
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c 
b/drivers/net/wireless/ath/wil6210/txrx.c
index 389c718..62c04f0 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -178,14 +178,14 @@ static int wil_vring_alloc(struct wil6210_priv *wil, 
struct vring *vring)
 *
 * HW has limitation that all vrings addresses must share the same
 * upper 16 msb bits part of 48 bits address. To workaround that,
-* if we are using 48 bit addresses switch to 32 bit allocation
-* before allocating vring memory.
+* if we are using more than 32 bit addresses switch to 32 bit
+* allocation before allocating vring memory.
 *
 * There's no check for the return 

[PATCH v2 5/9] wil6210: prevent parallel suspend and dump collection

2017-12-14 Thread Maya Erez
Suspend and crash dump operations can happen simultaneously
in case there is a FW assert during the suspend procedure
or when SSR calls all the devices crashdump callbacks.

To prevent that, a new flag is added, indicating that the
dumps collection is in progress, in order to allow the
suspend/reset decline if the dumps collection already started.

Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/main.c   | 33 +--
 drivers/net/wireless/ath/wil6210/pm.c | 17 
 drivers/net/wireless/ath/wil6210/wil6210.h|  1 +
 drivers/net/wireless/ath/wil6210/wil_crash_dump.c | 11 
 4 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/main.c 
b/drivers/net/wireless/ath/wil6210/main.c
index 7a8f8c2..aa6f9c4 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -998,6 +998,7 @@ static void wil_pre_fw_config(struct wil6210_priv *wil)
 int wil_reset(struct wil6210_priv *wil, bool load_fw)
 {
int rc;
+   unsigned long status_flags = BIT(wil_status_resetting);
 
wil_dbg_misc(wil, "reset\n");
 
@@ -1037,6 +1038,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
}
 
set_bit(wil_status_resetting, wil->status);
+   if (test_bit(wil_status_collecting_dumps, wil->status)) {
+   /* Device collects crash dump, cancel the reset.
+* following crash dump collection, reset would take place.
+*/
+   wil_dbg_misc(wil, "reject reset while collecting crash dump\n");
+   rc = -EBUSY;
+   goto out;
+   }
 
cancel_work_sync(&wil->disconnect_worker);
wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
@@ -1051,7 +1060,11 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
 
/* prevent NAPI from being scheduled and prevent wmi commands */
mutex_lock(&wil->wmi_mutex);
-   bitmap_zero(wil->status, wil_status_last);
+   if (test_bit(wil_status_suspending, wil->status))
+   status_flags |= BIT(wil_status_suspending);
+   bitmap_and(wil->status, wil->status, &status_flags,
+  wil_status_last);
+   wil_dbg_misc(wil, "wil->status (0x%lx)\n", *wil->status);
mutex_unlock(&wil->wmi_mutex);
 
wil_mask_irq(wil);
@@ -1069,14 +1082,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
wil_rx_fini(wil);
if (rc) {
wil_bl_crash_info(wil, true);
-   return rc;
+   goto out;
}
 
rc = wil_get_bl_info(wil);
if (rc == -EAGAIN && !load_fw) /* ignore RF error if not going up */
rc = 0;
if (rc)
-   return rc;
+   goto out;
 
wil_set_oob_mode(wil, oob_mode);
if (load_fw) {
@@ -1088,10 +1101,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
/* Loading f/w from the file */
rc = wil_request_firmware(wil, wil->wil_fw_name, true);
if (rc)
-   return rc;
+   goto out;
rc = wil_request_firmware(wil, WIL_BOARD_FILE_NAME, true);
if (rc)
-   return rc;
+   goto out;
 
wil_pre_fw_config(wil);
wil_release_cpu(wil);
@@ -1103,6 +1116,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
reinit_completion(&wil->wmi_call);
reinit_completion(&wil->halp.comp);
 
+   clear_bit(wil_status_resetting, wil->status);
+
if (load_fw) {
wil_configure_interrupt_moderation(wil);
wil_unmask_irq(wil);
@@ -1136,6 +1151,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
}
 
return rc;
+
+out:
+   clear_bit(wil_status_resetting, wil->status);
+   return rc;
 }
 
 void wil_fw_error_recovery(struct wil6210_priv *wil)
@@ -1241,9 +1260,7 @@ int __wil_down(struct wil6210_priv *wil)
wil_abort_scan(wil, false);
mutex_unlock(&wil->p2p_wdev_mutex);
 
-   wil_reset(wil, false);
-
-   return 0;
+   return wil_reset(wil, false);
 }
 
 int wil_down(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/ath/wil6210/pm.c 
b/drivers/net/wireless/ath/wil6210/pm.c
index 056b180..0a96518 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -145,6 +145,13 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv 
*wil)
 
/* Prevent handling of new tx and wmi commands */
set_bit(wil_status_suspending, wil->status);
+   if (test_bit(wil_status_collecting_dumps, wil->status)) {
+   /* Device collects crash dump, cancel the suspend */
+   wil_dbg_pm(wil, "reject suspend while collecting crash dump\n");
+   clear_bit(wil_status_suspending, wil->stat

[PATCH v2 4/9] wil6210: set platform features based on FW capabilities

2017-12-14 Thread Maya Erez
In some cases the platform should be aware of the FW capabilities
to decide which feature to enable.
For example, FW can control the external REF clock for power saving.
Driver should notify the platform about that, to allow platform
power management optimization.

Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/main.c | 11 +++
 drivers/net/wireless/ath/wil6210/wil_platform.h |  6 ++
 drivers/net/wireless/ath/wil6210/wmi.h  |  1 +
 3 files changed, 18 insertions(+)

diff --git a/drivers/net/wireless/ath/wil6210/main.c 
b/drivers/net/wireless/ath/wil6210/main.c
index bafd8d5..7a8f8c2 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -771,6 +771,7 @@ static void wil_collect_fw_info(struct wil6210_priv *wil)
 void wil_refresh_fw_capabilities(struct wil6210_priv *wil)
 {
struct wiphy *wiphy = wil_to_wiphy(wil);
+   int features;
 
wil->keep_radio_on_during_sleep =
test_bit(WIL_PLATFORM_CAPA_RADIO_ON_IN_SUSPEND,
@@ -792,6 +793,16 @@ void wil_refresh_fw_capabilities(struct wil6210_priv *wil)
wiphy->max_sched_scan_ie_len = WMI_MAX_IE_LEN;
wiphy->max_sched_scan_plans = WMI_MAX_PLANS_NUM;
}
+
+   if (wil->platform_ops.set_features) {
+   features = (test_bit(WMI_FW_CAPABILITY_REF_CLOCK_CONTROL,
+wil->fw_capabilities) &&
+   test_bit(WIL_PLATFORM_CAPA_EXT_CLK,
+wil->platform_capa)) ?
+   BIT(WIL_PLATFORM_FEATURE_FW_EXT_CLK_CONTROL) : 0;
+
+   wil->platform_ops.set_features(wil->platform_handle, features);
+   }
 }
 
 void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.h 
b/drivers/net/wireless/ath/wil6210/wil_platform.h
index 5cfb946..177026e 100644
--- a/drivers/net/wireless/ath/wil6210/wil_platform.h
+++ b/drivers/net/wireless/ath/wil6210/wil_platform.h
@@ -27,6 +27,11 @@ enum wil_platform_event {
WIL_PLATFORM_EVT_POST_SUSPEND = 4,
 };
 
+enum wil_platform_features {
+   WIL_PLATFORM_FEATURE_FW_EXT_CLK_CONTROL = 0,
+   WIL_PLATFORM_FEATURE_MAX,
+};
+
 enum wil_platform_capa {
WIL_PLATFORM_CAPA_RADIO_ON_IN_SUSPEND = 0,
WIL_PLATFORM_CAPA_T_PWR_ON_0 = 1,
@@ -45,6 +50,7 @@ struct wil_platform_ops {
void (*uninit)(void *handle);
int (*notify)(void *handle, enum wil_platform_event evt);
int (*get_capa)(void *handle);
+   void (*set_features)(void *handle, int features);
 };
 
 /**
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h 
b/drivers/net/wireless/ath/wil6210/wmi.h
index c7b84d1..d3e75f0 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -72,6 +72,7 @@ enum wmi_fw_capability {
WMI_FW_CAPABILITY_SET_SILENT_RSSI_TABLE = 13,
WMI_FW_CAPABILITY_LO_POWER_CALIB_FROM_OTP   = 14,
WMI_FW_CAPABILITY_PNO   = 15,
+   WMI_FW_CAPABILITY_REF_CLOCK_CONTROL = 18,
WMI_FW_CAPABILITY_MAX,
 };
 
-- 
1.9.1



[PATCH v2 3/9] wil6210: add platform capabilities bitmap

2017-12-14 Thread Maya Erez
Add get_capa callback to platform ops to allow reading the platform
capabilities.
Supported capabilities:
- Keeping 11ad connection during suspend
- T_POWER_ON 0 support
- Usage of external clock

Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/main.c | 15 ---
 drivers/net/wireless/ath/wil6210/pcie_bus.c | 10 ++
 drivers/net/wireless/ath/wil6210/wil6210.h  |  5 +
 drivers/net/wireless/ath/wil6210/wil_platform.h |  9 -
 4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/main.c 
b/drivers/net/wireless/ath/wil6210/main.c
index 5d69796..bafd8d5 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -773,9 +773,8 @@ void wil_refresh_fw_capabilities(struct wil6210_priv *wil)
struct wiphy *wiphy = wil_to_wiphy(wil);
 
wil->keep_radio_on_during_sleep =
-   wil->platform_ops.keep_radio_on_during_sleep &&
-   wil->platform_ops.keep_radio_on_during_sleep(
-   wil->platform_handle) &&
+   test_bit(WIL_PLATFORM_CAPA_RADIO_ON_IN_SUSPEND,
+wil->platform_capa) &&
test_bit(WMI_FW_CAPABILITY_D3_SUSPEND, wil->fw_capabilities);
 
wil_info(wil, "keep_radio_on_during_sleep (%d)\n",
@@ -1008,6 +1007,16 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
if (wil->hw_version == HW_VER_UNKNOWN)
return -ENODEV;
 
+   if (test_bit(WIL_PLATFORM_CAPA_T_PWR_ON_0, wil->platform_capa)) {
+   wil_dbg_misc(wil, "Notify FW to set T_POWER_ON=0\n");
+   wil_s(wil, RGF_USER_USAGE_8, BIT_USER_SUPPORT_T_POWER_ON_0);
+   }
+
+   if (test_bit(WIL_PLATFORM_CAPA_EXT_CLK, wil->platform_capa)) {
+   wil_dbg_misc(wil, "Notify FW on ext clock configuration\n");
+   wil_s(wil, RGF_USER_USAGE_8, BIT_USER_EXT_CLK);
+   }
+
if (wil->platform_ops.notify) {
rc = wil->platform_ops.notify(wil->platform_handle,
  WIL_PLATFORM_EVT_PRE_RESET);
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c 
b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index d4bb0bd..dc84001 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -43,9 +43,11 @@ void wil_set_capabilities(struct wil6210_priv *wil)
u32 jtag_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
u8 chip_revision = (wil_r(wil, RGF_USER_REVISION_ID) &
RGF_USER_REVISION_ID_MASK);
+   int platform_capa;
 
bitmap_zero(wil->hw_capabilities, hw_capability_last);
bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX);
+   bitmap_zero(wil->platform_capa, WIL_PLATFORM_CAPA_MAX);
wil->wil_fw_name = ftm_mode ? WIL_FW_NAME_FTM_DEFAULT :
   WIL_FW_NAME_DEFAULT;
wil->chip_revision = chip_revision;
@@ -81,6 +83,14 @@ void wil_set_capabilities(struct wil6210_priv *wil)
 
wil_info(wil, "Board hardware is %s\n", wil->hw_name);
 
+   /* Get platform capabilities */
+   if (wil->platform_ops.get_capa) {
+   platform_capa =
+   wil->platform_ops.get_capa(wil->platform_handle);
+   memcpy(wil->platform_capa, &platform_capa,
+  min(sizeof(wil->platform_capa), sizeof(platform_capa)));
+   }
+
/* extract FW capabilities from file without loading the FW */
wil_request_firmware(wil, wil->wil_fw_name, false);
wil_refresh_fw_capabilities(wil);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h 
b/drivers/net/wireless/ath/wil6210/wil6210.h
index db68209..f2bb55e 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -161,6 +161,10 @@ struct RGF_ICR {
 #define RGF_USER_USAGE_6   (0x880018)
#define BIT_USER_OOB_MODE   BIT(31)
#define BIT_USER_OOB_R2_MODEBIT(30)
+#define RGF_USER_USAGE_8   (0x880020)
+   #define BIT_USER_PREVENT_DEEP_SLEEP BIT(0)
+   #define BIT_USER_SUPPORT_T_POWER_ON_0   BIT(1)
+   #define BIT_USER_EXT_CLKBIT(2)
 #define RGF_USER_HW_MACHINE_STATE  (0x8801dc)
#define HW_MACHINE_BOOT_DONE(0x3fd)
 #define RGF_USER_USER_CPU_0(0x8801e0)
@@ -643,6 +647,7 @@ struct wil6210_priv {
const char *wil_fw_name;
DECLARE_BITMAP(hw_capabilities, hw_capability_last);
DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX);
+   DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX);
u8 n_mids; /* number of additional MIDs as reported by FW */
u32 recovery_count; /* num of FW recovery attempts in a short time */
u32 recovery_state; /* FW recovery state machine */
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.h 
b/drive

[PATCH v2 9/9] wil6210: remove reference to preset_chandef

2017-12-14 Thread Maya Erez
From: Lior David 

The field preset_chandef of wireless_dev must not be accessed
by the driver because it is private to cfg80211. Store the
monitor channel locally in wil6210_priv instead.

Signed-off-by: Lior David 
Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/cfg80211.c | 3 +--
 drivers/net/wireless/ath/wil6210/debugfs.c  | 1 -
 drivers/net/wireless/ath/wil6210/netdev.c   | 2 +-
 drivers/net/wireless/ath/wil6210/txrx.c | 3 +--
 drivers/net/wireless/ath/wil6210/wil6210.h  | 1 +
 drivers/net/wireless/ath/wil6210/wmi.c  | 2 +-
 6 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c 
b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 39509d0..768f63f38 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -956,9 +956,8 @@ static int wil_cfg80211_set_channel(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef)
 {
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-   struct wireless_dev *wdev = wil_to_wdev(wil);
 
-   wdev->preset_chandef = *chandef;
+   wil->monitor_chandef = *chandef;
 
return 0;
 }
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c 
b/drivers/net/wireless/ath/wil6210/debugfs.c
index 4475937..4a48882 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -869,7 +869,6 @@ static ssize_t wil_write_file_txmgmt(struct file *file, 
const char __user *buf,
 
params.buf = frame;
params.len = len;
-   params.chan = wdev->preset_chandef.chan;
 
rc = wil_cfg80211_mgmt_tx(wiphy, wdev, ¶ms, NULL);
 
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c 
b/drivers/net/wireless/ath/wil6210/netdev.c
index b641ac1..7ba4e0a 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -150,7 +150,7 @@ void *wil_if_alloc(struct device *dev)
wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */
/* default monitor channel */
ch = wdev->wiphy->bands[NL80211_BAND_60GHZ]->channels;
-   cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
+   cfg80211_chandef_create(&wil->monitor_chandef, ch, NL80211_CHAN_NO_HT);
 
ndev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, wil_dev_setup);
if (!ndev) {
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c 
b/drivers/net/wireless/ath/wil6210/txrx.c
index 4fc05f7..9f8c6087f 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -428,7 +428,6 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, 
struct vring *vring,
 static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
   struct sk_buff *skb)
 {
-   struct wireless_dev *wdev = wil->wdev;
struct wil6210_rtap {
struct ieee80211_radiotap_header rthdr;
/* fields should be in the order of bits in rthdr.it_present */
@@ -455,7 +454,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv 
*wil,
int rtap_len = sizeof(struct wil6210_rtap);
int phy_length = 0; /* phy info header size, bytes */
static char phy_data[128];
-   struct ieee80211_channel *ch = wdev->preset_chandef.chan;
+   struct ieee80211_channel *ch = wil->monitor_chandef.chan;
 
if (rtap_include_phy_info) {
rtap_len = sizeof(*rtap_vendor) + sizeof(*d);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h 
b/drivers/net/wireless/ath/wil6210/wil6210.h
index 703e09e..1131893 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -655,6 +655,7 @@ struct wil6210_priv {
unsigned long last_fw_recovery; /* jiffies of last fw recovery */
wait_queue_head_t wq; /* for all wait_event() use */
/* profile */
+   struct cfg80211_chan_def monitor_chandef;
u32 monitor_flags;
u32 privacy; /* secure connection? */
u8 hidden_ssid; /* relevant in AP mode */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c 
b/drivers/net/wireless/ath/wil6210/wmi.c
index 9b9882c..2ab71bb 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -1782,7 +1782,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct 
vring *vring)
int rc;
 
if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
-   struct ieee80211_channel *ch = wdev->preset_chandef.chan;
+   struct ieee80211_channel *ch = wil->monitor_chandef.chan;
 
cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON);
if (ch)
-- 
1.9.1



[PATCH v2 1/9] wil6210: support Scheduled scan

2017-12-14 Thread Maya Erez
From: Dedy Lansky 

Add support for sched_scan_start/stop by sending PNO commands to FW.
Driver reports max_sched_scan_reqs and invokes
cfg80211_sched_scan_results upon receiving WMI_SCHED_SCAN_RESULT_EVENTID
from FW.

Signed-off-by: Dedy Lansky 
Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/cfg80211.c |  65 
 drivers/net/wireless/ath/wil6210/main.c |   8 +
 drivers/net/wireless/ath/wil6210/wil6210.h  |   4 +
 drivers/net/wireless/ath/wil6210/wmi.c  | 237 
 drivers/net/wireless/ath/wil6210/wmi.h  |  99 +---
 5 files changed, 395 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c 
b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 771a534..39509d0 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1751,6 +1751,69 @@ static int wil_cfg80211_resume(struct wiphy *wiphy)
return 0;
 }
 
+static int
+wil_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_sched_scan_request *request)
+{
+   struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+   int i, rc;
+
+   wil_dbg_misc(wil,
+"sched scan start: n_ssids %d, ie_len %zu, flags 0x%x\n",
+request->n_ssids, request->ie_len, request->flags);
+   for (i = 0; i < request->n_ssids; i++) {
+   wil_dbg_misc(wil, "SSID[%d]:", i);
+   wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
+ request->ssids[i].ssid,
+ request->ssids[i].ssid_len, true);
+   }
+   wil_dbg_misc(wil, "channels:");
+   for (i = 0; i < request->n_channels; i++)
+   wil_dbg_misc(wil, " %d%s", request->channels[i]->hw_value,
+i == request->n_channels - 1 ? "\n" : "");
+   wil_dbg_misc(wil, "n_match_sets %d, min_rssi_thold %d, delay %d\n",
+request->n_match_sets, request->min_rssi_thold,
+request->delay);
+   for (i = 0; i < request->n_match_sets; i++) {
+   struct cfg80211_match_set *ms = &request->match_sets[i];
+
+   wil_dbg_misc(wil, "MATCHSET[%d]: rssi_thold %d\n",
+i, ms->rssi_thold);
+   wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
+ ms->ssid.ssid,
+ ms->ssid.ssid_len, true);
+   }
+   wil_dbg_misc(wil, "n_scan_plans %d\n", request->n_scan_plans);
+   for (i = 0; i < request->n_scan_plans; i++) {
+   struct cfg80211_sched_scan_plan *sp = &request->scan_plans[i];
+
+   wil_dbg_misc(wil, "SCAN PLAN[%d]: interval %d iterations %d\n",
+i, sp->interval, sp->iterations);
+   }
+
+   rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie);
+   if (rc)
+   return rc;
+   return wmi_start_sched_scan(wil, request);
+}
+
+static int
+wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev,
+u64 reqid)
+{
+   struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+   int rc;
+
+   rc = wmi_stop_sched_scan(wil);
+   /* device would return error if it thinks PNO is already stopped.
+* ignore the return code so user space and driver gets back in-sync
+*/
+   wil_dbg_misc(wil, "sched scan stopped (%d)\n", rc);
+
+   return 0;
+}
+
 static const struct cfg80211_ops wil_cfg80211_ops = {
.add_virtual_intf = wil_cfg80211_add_iface,
.del_virtual_intf = wil_cfg80211_del_iface,
@@ -1784,6 +1847,8 @@ static int wil_cfg80211_resume(struct wiphy *wiphy)
.set_power_mgmt = wil_cfg80211_set_power_mgmt,
.suspend = wil_cfg80211_suspend,
.resume = wil_cfg80211_resume,
+   .sched_scan_start = wil_cfg80211_sched_scan_start,
+   .sched_scan_stop = wil_cfg80211_sched_scan_stop,
 };
 
 static void wil_wiphy_init(struct wiphy *wiphy)
diff --git a/drivers/net/wireless/ath/wil6210/main.c 
b/drivers/net/wireless/ath/wil6210/main.c
index 1b53cd3..5d69796 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -785,6 +785,14 @@ void wil_refresh_fw_capabilities(struct wil6210_priv *wil)
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
else
wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
+
+   if (test_bit(WMI_FW_CAPABILITY_PNO, wil->fw_capabilities)) {
+   wiphy->max_sched_scan_reqs = 1;
+   wiphy->max_sched_scan_ssids = WMI_MAX_PNO_SSID_NUM;
+   wiphy->max_match_sets = WMI_MAX_PNO_SSID_NUM;
+   wiphy->max_sched_scan_ie_len = WMI_MAX_IE_LEN;
+   wiphy->max_sched_scan_plans = WMI_MAX_PLANS_NUM;
+   }
 }
 
 void wil_m

[PATCH v2 7/9] wil6210: configurable broadcast TX MCS

2017-12-14 Thread Maya Erez
From: Lior David 

Add 2 module parameters that control broadcast/multicast
TX packets:
1. bcast_mcs0_limit - specify the maximum packet size
that will be sent with MCS 0.
2. bcast_mcs - specify the MCS index to use when sending
packets larger than above limit.

Signed-off-by: Lior David 
Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/txrx.c | 59 +++--
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/txrx.c 
b/drivers/net/wireless/ath/wil6210/txrx.c
index 89967ce..4fc05f7 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -67,6 +67,60 @@ static int headroom_size_set(const char *val, const struct 
kernel_param *kp)
 MODULE_PARM_DESC(headroom_size,
 " headroom size for rx skb allocation, default - 0");
 
+static uint bcast_mcs0_limit = WIL_BCAST_MCS0_LIMIT;
+static int bcast_mcs0_limit_set(const char *val, const struct kernel_param *kp)
+{
+   int ret;
+   uint saved = bcast_mcs0_limit;
+
+   ret = param_set_uint(val, kp);
+   if (ret)
+   return ret;
+
+   if (bcast_mcs0_limit > WIL_BCAST_MCS0_LIMIT) {
+   bcast_mcs0_limit = saved;
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
+static const struct kernel_param_ops bcast_mcs0_limit_ops = {
+   .set = bcast_mcs0_limit_set,
+   .get = param_get_uint,
+};
+
+module_param_cb(bcast_mcs0_limit_set, &bcast_mcs0_limit_ops,
+   &bcast_mcs0_limit, 0644);
+MODULE_PARM_DESC(bcast_mcs0_limit,
+" max broadcast packet size with MCS0, default - 1024 bytes");
+
+static uint bcast_mcs = 1;
+static int bcast_mcs_set(const char *val, const struct kernel_param *kp)
+{
+   int ret;
+   uint saved = bcast_mcs;
+
+   ret = param_set_uint(val, kp);
+   if (ret)
+   return ret;
+
+   if (bcast_mcs > WIL_MCS_MAX || bcast_mcs == 0) {
+   bcast_mcs = saved;
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
+static const struct kernel_param_ops bcast_mcs_ops = {
+   .set = bcast_mcs_set,
+   .get = param_get_uint,
+};
+
+module_param_cb(bcast_mcs, &bcast_mcs_ops, &bcast_mcs, 0644);
+MODULE_PARM_DESC(bcast_mcs, " MCS index for large bcast TX, default - 1");
+
 static inline uint wil_rx_snaplen(void)
 {
return rx_align_2 ? 6 : 0;
@@ -1783,8 +1837,9 @@ static int __wil_tx_vring(struct wil6210_priv *wil, 
struct vring *vring,
wil_tx_desc_map(d, pa, len, vring_index);
if (unlikely(mcast)) {
d->mac.d[0] |= BIT(MAC_CFG_DESC_TX_0_MCS_EN_POS); /* MCS 0 */
-   if (unlikely(len > WIL_BCAST_MCS0_LIMIT)) /* set MCS 1 */
-   d->mac.d[0] |= (1 << MAC_CFG_DESC_TX_0_MCS_INDEX_POS);
+   if (unlikely(len > bcast_mcs0_limit)) /* use bcast_mcs */
+   d->mac.d[0] |= (bcast_mcs <<
+   MAC_CFG_DESC_TX_0_MCS_INDEX_POS);
}
/* Process TCP/UDP checksum offloading */
if (unlikely(wil_tx_desc_offload_setup(d, skb))) {
-- 
1.9.1



[PATCH v2 6/9] wil6210: add support for headroom configuration

2017-12-14 Thread Maya Erez
From: Lazar Alexei 

Add module parameter for configuring the headroom size
in the skb allocation.

Signed-off-by: Lazar Alexei 
Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/txrx.c | 28 +++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wil6210/txrx.c 
b/drivers/net/wireless/ath/wil6210/txrx.c
index 62c04f0..89967ce 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -41,6 +41,32 @@
 module_param(rx_large_buf, bool, 0444);
 MODULE_PARM_DESC(rx_large_buf, " allocate 8KB RX buffers, default - no");
 
+#define WIL6210_MAX_HEADROOM_SIZE  (256)
+
+static ushort headroom_size; /* = 0; */
+static int headroom_size_set(const char *val, const struct kernel_param *kp)
+{
+   int ret;
+
+   ret = param_set_uint(val, kp);
+   if (ret)
+   return ret;
+
+   if (headroom_size > WIL6210_MAX_HEADROOM_SIZE)
+   return -EINVAL;
+
+   return 0;
+}
+
+static const struct kernel_param_ops headroom_ops = {
+   .set = headroom_size_set,
+   .get = param_get_ushort,
+};
+
+module_param_cb(headroom_size, &headroom_ops, &headroom_size, 0644);
+MODULE_PARM_DESC(headroom_size,
+" headroom size for rx skb allocation, default - 0");
+
 static inline uint wil_rx_snaplen(void)
 {
return rx_align_2 ? 6 : 0;
@@ -630,7 +656,7 @@ static int wil_rx_refill(struct wil6210_priv *wil, int 
count)
u32 next_tail;
int rc = 0;
int headroom = ndev->type == ARPHRD_IEEE80211_RADIOTAP ?
-   WIL6210_RTAP_SIZE : 0;
+   WIL6210_RTAP_SIZE : headroom_size;
 
for (; next_tail = wil_vring_next_tail(v),
(next_tail != v->swhead) && (count-- > 0);
-- 
1.9.1



[PATCH v2 8/9] wil6210: remove leftover "FIXME"s

2017-12-14 Thread Maya Erez
From: Dedy Lansky 

"FIXME: IRQ mask debug" and "FIXME: interrupts enabled - for debug"
can be removed because wil6210_debug_irq_mask() is now considered
production feature.

"FIXME FW can transmit only ucast frames to peer" and "FIXME real
ring_id instead of hard coded 0" can be removed because FW/HW already
support multicast transmission.

Signed-off-by: Dedy Lansky 
Signed-off-by: Maya Erez 
---
 drivers/net/wireless/ath/wil6210/interrupt.c | 2 +-
 drivers/net/wireless/ath/wil6210/wil6210.h   | 2 +-
 drivers/net/wireless/ath/wil6210/wmi.c   | 2 --
 3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c 
b/drivers/net/wireless/ath/wil6210/interrupt.c
index 5cf3417..dcf87a7 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -565,7 +565,7 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
if (unlikely((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff)))
return IRQ_NONE;
 
-   /* FIXME: IRQ mask debug */
+   /* IRQ mask debug */
if (unlikely(wil6210_debug_irq_mask(wil, pseudo_cause)))
return IRQ_NONE;
 
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h 
b/drivers/net/wireless/ath/wil6210/wil6210.h
index ca5abbd..703e09e 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -439,7 +439,7 @@ enum { /* for wil6210_priv.status */
wil_status_fwconnected,
wil_status_dontscan,
wil_status_mbox_ready, /* MBOX structures ready */
-   wil_status_irqen, /* FIXME: interrupts enabled - for debug */
+   wil_status_irqen, /* interrupts enabled - for debug */
wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
wil_status_resetting, /* reset in progress */
wil_status_suspending, /* suspend in progress */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c 
b/drivers/net/wireless/ath/wil6210/wmi.c
index d06090d..9b9882c 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -813,8 +813,6 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int 
id, void *d, int len)
}
}
 
-   /* FIXME FW can transmit only ucast frames to peer */
-   /* FIXME real ring_id instead of hard coded 0 */
ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid);
wil->sta[evt->cid].status = wil_sta_conn_pending;
 
-- 
1.9.1



[PATCH v2 0/9] wil6210 patches

2017-12-14 Thread Maya Erez
Changes from v1:
- Fix code review comments on "wil6210: support Scheduled scan"

The following patches include several wil6210 fixes.

Dedy Lansky (2):
  wil6210: support Scheduled scan
  wil6210: remove leftover "FIXME"s

Lazar Alexei (2):
  wil6210: support 40bit DMA addresses
  wil6210: add support for headroom configuration

Lior David (2):
  wil6210: configurable broadcast TX MCS
  wil6210: remove reference to preset_chandef

Maya Erez (3):
  wil6210: add platform capabilities bitmap
  wil6210: set platform features based on FW capabilities
  wil6210: prevent parallel suspend and dump collection

 drivers/net/wireless/ath/wil6210/cfg80211.c   |  68 +-
 drivers/net/wireless/ath/wil6210/debugfs.c|   1 -
 drivers/net/wireless/ath/wil6210/interrupt.c  |   2 +-
 drivers/net/wireless/ath/wil6210/main.c   |  67 +-
 drivers/net/wireless/ath/wil6210/netdev.c |   2 +-
 drivers/net/wireless/ath/wil6210/pcie_bus.c   |  36 +++-
 drivers/net/wireless/ath/wil6210/pm.c |  17 ++
 drivers/net/wireless/ath/wil6210/pmc.c|  11 +-
 drivers/net/wireless/ath/wil6210/txrx.c   | 101 -
 drivers/net/wireless/ath/wil6210/wil6210.h|  15 +-
 drivers/net/wireless/ath/wil6210/wil_crash_dump.c |  11 +
 drivers/net/wireless/ath/wil6210/wil_platform.h   |  15 +-
 drivers/net/wireless/ath/wil6210/wmi.c| 241 +-
 drivers/net/wireless/ath/wil6210/wmi.h| 100 +++--
 14 files changed, 621 insertions(+), 66 deletions(-)

-- 
1.9.1



Re: [PATCH] mt76x2: eeprom: fix typo in mt76x2_get_power_info_5g()

2017-12-14 Thread Kalle Valo
Colin Ian King  writes:

> On 14/12/17 10:46, Lorenzo Bianconi wrote:
>> Fix typo in 5GHz power vs channel eeprom parsing
>> 
>> Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
>> Signed-off-by: Lorenzo Bianconi 
>> ---
>>  drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c 
>> b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
>> index 440b7e7d73a9..29dc52ef629d 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
>> @@ -524,7 +524,7 @@ mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct 
>> mt76x2_tx_power_info *t,
>>  
>>  if (channel >= 192)
>>  delta_idx = 4;
>> -else if (channel >= 484)
>> +else if (channel >= 184)
>>  delta_idx = 3;
>>  else if (channel < 44)
>>  delta_idx = 3;
>> 
> any possibility of adding:
>
> Reported-by: Colin Ian King 

Sure, I'll add that during commit.

-- 
Kalle Valo


Re: [PATCH 2/3] rtlwifi: Add beacon check mechanism to check if AP settings changed.

2017-12-14 Thread Larry Finger

On 12/14/2017 06:35 AM, Kalle Valo wrote:

Larry Finger  writes:


From: Tsang-Shian Lin 

+bool rtl_check_beacon_key(struct ieee80211_hw *hw, void *data, unsigned int 
len)
+{
+   struct rtl_priv *rtlpriv = rtl_priv(hw);
+   struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+   struct rtl_phy *rtlphy = &rtlpriv->phy;
+   struct ieee80211_hdr *hdr = data;
+   struct ieee80211_ht_cap *ht_cap_ie;
+   struct ieee80211_ht_operation *ht_oper_ie = NULL;
+   struct rtl_beacon_keys bcn_key = {0};
+   struct rtl_beacon_keys *cur_bcn_key;
+   u8 *ht_cap;
+   u8 ht_cap_len;
+   u8 *ht_oper;
+   u8 ht_oper_len;
+   u8 *ds_param;
+   u8 ds_param_len;
+
+   if (mac->opmode != NL80211_IFTYPE_STATION)
+   return false;
+
+   /* check if this really is a beacon*/
+   if (!ieee80211_is_beacon(hdr->frame_control))
+   return false;
+
+   /* min. beacon length + FCS_LEN */
+   if (len <= 40 + FCS_LEN)
+   return false;
+
+   cur_bcn_key = &mac->cur_beacon_keys;
+
+   if (rtlpriv->mac80211.link_state == MAC80211_NOLINK) {
+   if (cur_bcn_key->valid) {
+   cur_bcn_key->valid = false;
+   RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
+"Reset cur_beacon_keys.valid to false!\n");
+   }
+   return false;
+   }
+
+   /* and only beacons from the associated BSSID, please */
+   if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
+   return false;
+
+   /* Parsing DS Param IE **/
+   ds_param = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_DS_PARAMS);
+
+   if (ds_param && !(ds_param[1] < sizeof(*ds_param)))
+   ds_param_len = ds_param[1];
+   else
+   ds_param = NULL;
+
+   /* Parsing HT Cap. IE **/
+   ht_cap = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_HT_CAPABILITY);
+
+   if (ht_cap && !(ht_cap[1] < sizeof(*ht_cap))) {
+   ht_cap_len = ht_cap[1];
+   ht_cap_ie = (struct ieee80211_ht_cap *)&ht_cap[2];
+   } else  {
+   ht_cap = NULL;
+   ht_cap_ie = NULL;
+   }
+
+   /* Parsing HT Info. IE **/
+   ht_oper = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_HT_OPERATION);
+
+   if (ht_oper && !(ht_oper[1] < sizeof(*ht_oper))) {
+   ht_oper_len = ht_oper[1];
+   ht_oper_ie = (struct ieee80211_ht_operation *)&ht_oper[2];
+   } else {
+   ht_oper = NULL;
+   }
+
+   /* update bcn_key */
+   memset(&bcn_key, 0, sizeof(bcn_key));
+
+   if (ds_param)
+   bcn_key.bcn_channel = ds_param[2];
+   else if (ht_oper && ht_oper_ie)
+   bcn_key.bcn_channel = ht_oper_ie->primary_chan;
+
+   if (ht_cap_ie)
+   bcn_key.ht_cap_info = ht_cap_ie->cap_info;
+
+   if (ht_oper && ht_oper_ie)
+   bcn_key.ht_info_infos_0_sco = ht_oper_ie->ht_param & 0x03;
+
+   bcn_key.valid = true;
+
+   /* update cur_beacon_keys or compare beacon key */
+   if (rtlpriv->mac80211.link_state != MAC80211_LINKED &&
+   rtlpriv->mac80211.link_state != MAC80211_LINKED_SCANNING)
+   return true;
+
+   if (!cur_bcn_key->valid) {
+   /* update cur_beacon_keys */
+   memset(cur_bcn_key, 0, sizeof(bcn_key));
+   memcpy(cur_bcn_key, &bcn_key, sizeof(bcn_key));
+   cur_bcn_key->valid = true;
+
+   RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
+"Beacon key update!ch=%d, ht_cap_info=0x%x, 
sco=0x%x\n",
+cur_bcn_key->bcn_channel,
+cur_bcn_key->ht_cap_info,
+cur_bcn_key->ht_info_infos_0_sco);
+
+   return true;
+   }
+
+   /* compare beacon key */
+   if (!memcmp(cur_bcn_key, &bcn_key, sizeof(bcn_key))) {
+   /* same beacon key */
+   mac->new_beacon_cnt = 0;
+   goto chk_exit;
+   }
+
+   if (cur_bcn_key->bcn_channel == bcn_key.bcn_channel &&
+   cur_bcn_key->ht_cap_info == bcn_key.ht_cap_info) {
+   /* Beacon HT info IE, secondary channel offset check */
+   /* 40M -> 20M */
+   if (cur_bcn_key->ht_info_infos_0_sco >
+   bcn_key.ht_info_infos_0_sco) {
+   /* Not a new beacon */
+   RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+"Beacon BW change! sco:0x%x -> 0x%x\n",
+cur_bcn_key->ht_info_infos_0_sco,
+bcn_key.ht_info_infos_0_sco);
+
+   cur_bcn_key->ht_info_infos_0_sco =
+   bcn_key.ht_info_infos_0_sco;
+   } else {
+   /* 20M -> 40M */
+   if (rtlphy->

Re: [PATCH] mt76x2: eeprom: fix typo in mt76x2_get_power_info_5g()

2017-12-14 Thread Colin Ian King
On 14/12/17 10:46, Lorenzo Bianconi wrote:
> Fix typo in 5GHz power vs channel eeprom parsing
> 
> Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
> Signed-off-by: Lorenzo Bianconi 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
> index 440b7e7d73a9..29dc52ef629d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
> @@ -524,7 +524,7 @@ mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct 
> mt76x2_tx_power_info *t,
>  
>   if (channel >= 192)
>   delta_idx = 4;
> - else if (channel >= 484)
> + else if (channel >= 184)
>   delta_idx = 3;
>   else if (channel < 44)
>   delta_idx = 3;
> 
any possibility of adding:

Reported-by: Colin Ian King 



[PATCH 02/14] mt76: fix returnvar.cocci warnings

2017-12-14 Thread Felix Fietkau
From: Fengguang Wu 

drivers/net/wireless/mediatek/mt76/mt76x2_main.c:86:5-8: Unneeded variable: 
"ret". Return "0" on line 112

 Remove unneeded variable used to store return value.

Generated by: scripts/coccinelle/misc/returnvar.cocci

Fixes: a5f6039c8f9c ("mt76: add driver code for MT76x2e")
CC: Felix Fietkau 
Signed-off-by: Fengguang Wu 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index 33469e32567b..88fe5e0de0b9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -83,7 +83,6 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
struct mt76x2_dev *dev = hw->priv;
struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv;
unsigned int idx = 0;
-   int ret = 0;
 
if (vif->addr[0] & BIT(1))
idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7);
@@ -109,7 +108,7 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
mvif->group_wcid.hw_key_idx = -1;
mt76x2_txq_init(dev, vif->txq);
 
-   return ret;
+   return 0;
 }
 
 static void
-- 
2.14.2



[PATCH 04/14] mt76x2: fix transmission of encrypted management frames

2017-12-14 Thread Felix Fietkau
Hardware encryption seems to break encrypted unicast mgmt tx.
Unfortunately the hardware TXWI header does not have a bit to indicate
that a frame is software encrypted, so sw-encrypted frames need to use a
different WCID. For that to work, the CCMP PN needs to be generated in
software, which makes things a bit slower, so only do it for keys that
also need to tx management frames.

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76.h|  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  | 16 
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c |  8 +++-
 drivers/net/wireless/mediatek/mt76/mt76x2_tx.c   |  6 --
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index aa0880bbea7f..f88d9a15210a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -129,6 +129,7 @@ struct mt76_wcid {
bool tx_rate_set;
u8 tx_rate_nss;
s8 max_txpwr_adj;
+   bool sw_iv;
 };
 
 struct mt76_txq {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index f7c0df0759f7..a7416a01baa4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -171,10 +171,12 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct 
mt76x2_txwi *txwi,
 {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rate = &info->control.rates[0];
+   struct ieee80211_key_conf *key = info->control.hw_key;
u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
u16 txwi_flags = 0;
u8 nss;
s8 txpwr_adj, max_txpwr_adj;
+   u8 ccmp_pn[8];
 
memset(txwi, 0, sizeof(*txwi));
 
@@ -185,6 +187,20 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct 
mt76x2_txwi *txwi,
 
txwi->pktid = 1;
 
+   if (wcid && wcid->sw_iv && key) {
+   u64 pn = atomic64_inc_return(&key->tx_pn);
+   ccmp_pn[0] = pn;
+   ccmp_pn[1] = pn >> 8;
+   ccmp_pn[2] = 0;
+   ccmp_pn[3] = 0x20 | (key->keyidx << 6);
+   ccmp_pn[4] = pn >> 16;
+   ccmp_pn[5] = pn >> 24;
+   ccmp_pn[6] = pn >> 32;
+   ccmp_pn[7] = pn >> 40;
+   txwi->iv = *((u32 *) &ccmp_pn[0]);
+   txwi->eiv = *((u32 *) &ccmp_pn[1]);
+   }
+
spin_lock_bh(&dev->mt76.lock);
if (wcid && (rate->idx < 0 || !rate->count)) {
txwi->rate = wcid->tx_rate;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index 88fe5e0de0b9..02dd2cafa52f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -343,9 +343,15 @@ mt76x2_set_key(struct ieee80211_hw *hw, enum set_key_cmd 
cmd,
if (cmd == SET_KEY) {
key->hw_key_idx = wcid->idx;
wcid->hw_key_idx = idx;
+   if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
+   key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+   wcid->sw_iv = true;
+   }
} else {
-   if (idx == wcid->hw_key_idx)
+   if (idx == wcid->hw_key_idx) {
wcid->hw_key_idx = -1;
+   wcid->sw_iv = true;
+   }
 
key = NULL;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c
index 1a32e1fb8743..534e4bf9a34c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c
@@ -36,7 +36,9 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct 
ieee80211_tx_control *control,
 
msta = (struct mt76x2_sta *) control->sta->drv_priv;
wcid = &msta->wcid;
-   } else if (vif) {
+   }
+
+   if (vif || (!info->control.hw_key && wcid->hw_key_idx != -1)) {
struct mt76x2_vif *mvif;
 
mvif = (struct mt76x2_vif *) vif->drv_priv;
@@ -166,7 +168,7 @@ int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
*tx_info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
   MT_TXD_INFO_80211;
 
-   if (!wcid || wcid->hw_key_idx == 0xff)
+   if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv)
*tx_info |= MT_TXD_INFO_WIV;
 
return 0;
-- 
2.14.2



[PATCH 01/14] mt76: fix debugfs_simple_attr.cocci warnings

2017-12-14 Thread Felix Fietkau
From: Fengguang Wu 

drivers/net/wireless/mediatek/mt76/debugfs.c:36:0-23: WARNING: fops_regval 
should be defined with DEFINE_DEBUGFS_ATTRIBUTE

 Use DEFINE_DEBUGFS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTRIBUTE
 for debugfs files.

Semantic patch information:
 Rationale: DEFINE_SIMPLE_ATTRIBUTE + debugfs_create_file()
 imposes some significant overhead as compared to
 DEFINE_DEBUGFS_ATTRIBUTE + debugfs_create_file_unsafe().

Generated by: scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci

Fixes: a5f6039c8f9c ("mt76: add driver code for MT76x2e")
CC: Felix Fietkau 
Signed-off-by: Fengguang Wu 
---
 drivers/net/wireless/mediatek/mt76/debugfs.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c 
b/drivers/net/wireless/mediatek/mt76/debugfs.c
index 7c3612aaa8c4..c121b502a462 100644
--- a/drivers/net/wireless/mediatek/mt76/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/debugfs.c
@@ -33,7 +33,8 @@ mt76_reg_get(void *data, u64 *val)
return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(fops_regval, mt76_reg_get, mt76_reg_set, "0x%08llx\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt76_reg_get, mt76_reg_set,
+"0x%08llx\n");
 
 static int
 mt76_queues_read(struct seq_file *s, void *data)
@@ -65,8 +66,8 @@ struct dentry *mt76_register_debugfs(struct mt76_dev *dev)
 
debugfs_create_u8("led_pin", S_IRUSR | S_IWUSR, dir, &dev->led_pin);
debugfs_create_u32("regidx", S_IRUSR | S_IWUSR, dir, &dev->debugfs_reg);
-   debugfs_create_file("regval", S_IRUSR | S_IWUSR, dir, dev,
-   &fops_regval);
+   debugfs_create_file_unsafe("regval", S_IRUSR | S_IWUSR, dir, dev,
+  &fops_regval);
debugfs_create_blob("eeprom", S_IRUSR, dir, &dev->eeprom);
if (dev->otp.data)
debugfs_create_blob("otp", S_IRUSR, dir, &dev->otp);
-- 
2.14.2



[PATCH 08/14] mt76x2: convert between per-chain tx power and combined output

2017-12-14 Thread Felix Fietkau
Using both chains adds max. 3 dBm. A similar worst-case calculation is
being used in ath9k as well to ensure that the hardware stays within
regulatory limits

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 3 +++
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 7 +++
 2 files changed, 10 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index 0755b451829e..3e3a01b6f2ce 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -785,6 +785,9 @@ mt76x2_init_txpower(struct mt76x2_dev *dev,
chan->max_power = mt76x2_get_max_rate_power(&t) +
  target_power;
chan->max_power /= 2;
+
+   /* convert to combined output power on 2x2 devices */
+   chan->max_power += 3;
}
 }
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index 02dd2cafa52f..8098a2b82c5b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -155,6 +155,9 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_POWER) {
dev->txpower_conf = hw->conf.power_level * 2;
 
+   /* convert to per-chain power for 2x2 devices */
+   dev->txpower_conf -= 6;
+
if (test_bit(MT76_STATE_RUNNING, &dev->mt76.state)) {
mt76x2_phy_set_txpower(dev);
mt76x2_tx_set_txpwr_auto(dev, dev->txpower_conf);
@@ -443,6 +446,10 @@ mt76x2_get_txpower(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif, int *dbm)
struct mt76x2_dev *dev = hw->priv;
 
*dbm = dev->txpower_cur / 2;
+
+   /* convert from per-chain power to combined output on 2x2 devices */
+   *dbm += 3;
+
return 0;
 }
 
-- 
2.14.2



[PATCH 09/14] mt76x2: remove MAC address limitation for multi-vif setups

2017-12-14 Thread Felix Fietkau
The hardware has a separate set of registers to configure a
per-interface MAC address.

Signed-off-by: Lorenzo Bianconi 
Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2.h  |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c |  2 ++
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  | 27 +
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.h  |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 30 ++--
 drivers/net/wireless/mediatek/mt76/mt76x2_regs.h |  8 +++
 6 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2.h
index a12dfce8c0d1..a993cc09cd1b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h
@@ -90,6 +90,7 @@ struct mt76x2_dev {
 
const u16 *beacon_offsets;
unsigned long wcid_mask[128 / BITS_PER_LONG];
+   unsigned long vif_mask;
 
int txpower_conf;
int txpower_cur;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index 3e3a01b6f2ce..ac4eeaf2c993 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -279,6 +279,8 @@ int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard)
FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */
MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
 
+   mt76_set(dev, MT_MAC_ADDR_EXT_CTL, MT_MAC_ADDR_EXT_CTL_EN);
+
/* Fire a pre-TBTT interrupt 8 ms before TBTT */
mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT,
   8 << 4);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index a7416a01baa4..60cee4abed7c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -22,10 +22,29 @@
 
 void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr)
 {
-   idx &= 7;
-   mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
-   mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
-  get_unaligned_le16(addr + 4));
+   u32 lo = 0, hi = 0;
+
+   if (addr) {
+   lo = get_unaligned_le32(addr);
+   hi = get_unaligned_le16(addr + 4);
+   hi |= MT_MAC_APC_BSSID0_H_EN;
+   }
+
+   mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), lo);
+   mt76_wr(dev, MT_MAC_APC_BSSID_H(idx), hi);
+}
+
+void mt76x2_mac_set_ext_mac(struct mt76x2_dev *dev, u8 idx, const u8 *addr)
+{
+   u32 lo = 0, hi = 0;
+
+   if (addr) {
+   lo = get_unaligned_le32(addr);
+   hi = get_unaligned_le16(addr + 4);
+   }
+
+   mt76_wr(dev, MT_MAC_ADDR_EXT_L(idx), lo);
+   mt76_wr(dev, MT_MAC_ADDR_EXT_H(idx), hi);
 }
 
 static int
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h
index 8a8a25e32d5f..a993c383d9e7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h
@@ -162,6 +162,7 @@ int mt76x2_mac_start(struct mt76x2_dev *dev);
 void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force);
 void mt76x2_mac_resume(struct mt76x2_dev *dev);
 void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr);
+void mt76x2_mac_set_ext_mac(struct mt76x2_dev *dev, u8 idx, const u8 *addr);
 
 int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
  void *rxi);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index 8098a2b82c5b..240e11508ecd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -82,26 +82,15 @@ mt76x2_add_interface(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif)
 {
struct mt76x2_dev *dev = hw->priv;
struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv;
-   unsigned int idx = 0;
+   unsigned int idx;
 
-   if (vif->addr[0] & BIT(1))
-   idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7);
+   idx = ffs(~dev->vif_mask);
+   if (!idx || idx > 8)
+   return -ENOSPC;
 
-   /*
-* Client mode typically only has one configurable BSSID register,
-* which is used for bssidx=0. This is linked to the MAC address.
-* Since mac80211 allows changing interface types, and we cannot
-* force the use of the primary MAC address for a station mode
-* interface, we need some other way of configuring a per-interface
-* remote BSSID.
-* The hardware provides an AP-Client feature, where bssidx 0-7 are
-* used for AP mode and bssidx 8-15 for client mode.
- 

[PATCH 07/14] mt76x2: initialize channel power limits at probe time

2017-12-14 Thread Felix Fietkau
This allows user space to query the real hardware limits directly

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c | 11 
 drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c   | 30 ++
 drivers/net/wireless/mediatek/mt76/mt76x2_phy.c| 14 +-
 4 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
index 8fef400cb58e..9c9bf3e785ba 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
@@ -483,6 +483,17 @@ void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct 
mt76_rate_power *t,
t->vht[8] = t->vht[9] = mt76x2_rate_power_val(val >> 8);
 }
 
+int mt76x2_get_max_rate_power(struct mt76_rate_power *r)
+{
+   int i;
+   s8 ret = 0;
+
+   for (i = 0; i < sizeof(r->all); i++)
+   ret = max(ret, r->all[i]);
+
+   return ret;
+}
+
 static void
 mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info 
*t,
 struct ieee80211_channel *chan, int chain, int offset)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
index 6db2c6e47569..d79122728dca 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
@@ -148,6 +148,7 @@ mt76x2_eeprom_get(struct mt76x2_dev *dev, enum 
mt76x2_eeprom_field field)
 
 void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
   struct ieee80211_channel *chan);
+int mt76x2_get_max_rate_power(struct mt76_rate_power *r);
 void mt76x2_get_power_info(struct mt76x2_dev *dev,
   struct mt76x2_tx_power_info *t,
   struct ieee80211_channel *chan);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index d3f03a8aee90..0755b451829e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -760,6 +760,34 @@ static void mt76x2_led_set_brightness(struct led_classdev 
*led_cdev,
mt76x2_led_set_config(mt76, 0xff, 0);
 }
 
+static void
+mt76x2_init_txpower(struct mt76x2_dev *dev,
+   struct ieee80211_supported_band *sband)
+{
+   struct ieee80211_channel *chan;
+   struct mt76x2_tx_power_info txp;
+   struct mt76_rate_power t = {};
+   int target_power;
+   int i;
+
+   for (i = 0; i < sband->n_channels; i++) {
+   chan = &sband->channels[i];
+
+   mt76x2_get_power_info(dev, &txp, chan);
+
+   target_power = max_t(int, (txp.chain[0].target_power +
+  txp.chain[0].delta),
+ (txp.chain[1].target_power +
+  txp.chain[1].delta));
+
+   mt76x2_get_rate_power(dev, &t, chan);
+
+   chan->max_power = mt76x2_get_max_rate_power(&t) +
+ target_power;
+   chan->max_power /= 2;
+   }
+}
+
 int mt76x2_register_device(struct mt76x2_dev *dev)
 {
struct ieee80211_hw *hw = mt76_hw(dev);
@@ -828,6 +856,8 @@ int mt76x2_register_device(struct mt76x2_dev *dev)
goto fail;
 
mt76x2_init_debugfs(dev);
+   mt76x2_init_txpower(dev, &dev->mt76.sband_2g.sband);
+   mt76x2_init_txpower(dev, &dev->mt76.sband_5g.sband);
 
return 0;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index 81cea7e8414e..5b742749d5de 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -102,18 +102,6 @@ mt76x2_limit_rate_power(struct mt76_rate_power *r, int 
limit)
r->all[i] = limit;
 }
 
-static int
-mt76x2_get_max_power(struct mt76_rate_power *r)
-{
-   int i;
-   s8 ret = 0;
-
-   for (i = 0; i < sizeof(r->all); i++)
-   ret = max(ret, r->all[i]);
-
-   return ret;
-}
-
 void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
 {
enum nl80211_chan_width width = dev->mt76.chandef.width;
@@ -136,7 +124,7 @@ void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
mt76x2_add_rate_power_offset(&t, txp.chain[0].target_power +
   txp.chain[0].delta);
mt76x2_limit_rate_power(&t, dev->txpower_conf);
-   dev->txpower_cur = mt76x2_get_max_power(&t);
+   dev->txpower_cur = mt76x2_get_max_rate_power(&t);
mt76x2_add_rate_power_offset(&t, -(txp.chain[0].target_power +
 txp.chain[0].delta + delta));
dev->target_power = txp.chain[0

[PATCH 00/14] mt76 fixes

2017-12-14 Thread Felix Fietkau
Felix Fietkau (10):
  mt76x2: remove some harmless WARN_ONs in tx status and rx path
  mt76x2: fix transmission of encrypted management frames
  mt76x2: increase OFDM SIFS time
  mt76x2: add channel argument to eeprom tx power functions
  mt76x2: initialize channel power limits at probe time
  mt76x2: convert between per-chain tx power and combined output
  mt76x2: remove MAC address limitation for multi-vif setups
  mt76x2: clean up MAC/BSSID address initialization
  mt76x2: drop wiphy->addresses
  mt76x2: configure rx filter based on monitor mode setting

Fengguang Wu (2):
  mt76: fix debugfs_simple_attr.cocci warnings
  mt76: fix returnvar.cocci warnings

Lorenzo Bianconi (2):
  mt76x2: init: disable APCLI by default
  mt76x2: init: fix rx filter default value during init

 drivers/net/wireless/mediatek/mt76/debugfs.c   |  7 +-
 drivers/net/wireless/mediatek/mt76/mt76.h  |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2.h|  3 +-
 drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c | 41 ---
 drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h |  7 +-
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c   | 67 ++---
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c| 85 +-
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.h|  1 +
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c   | 57 +--
 drivers/net/wireless/mediatek/mt76/mt76x2_phy.c| 30 ++--
 drivers/net/wireless/mediatek/mt76/mt76x2_regs.h   |  8 ++
 drivers/net/wireless/mediatek/mt76/mt76x2_tx.c |  6 +-
 12 files changed, 204 insertions(+), 109 deletions(-)

-- 
2.14.2



[PATCH 14/14] mt76x2: init: fix rx filter default value during init

2017-12-14 Thread Felix Fietkau
From: Lorenzo Bianconi 

mt76x2_mac_start writes dev->rxfilter to the hardware. It also happens
during init, before dev->rxfilter is filled with the initval register
value, leading to issues like promisc mode being enabled
unconditionally.

Fix this by reading the default value into dev->rxfilter earlier

Signed-off-by: Lorenzo Bianconi 
Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index ad17f9462358..62d702164dfe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -583,6 +583,8 @@ int mt76x2_init_hardware(struct mt76x2_dev *dev)
if (ret)
return ret;
 
+   dev->rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
+
ret = mt76x2_dma_init(dev);
if (ret)
return ret;
@@ -597,7 +599,6 @@ int mt76x2_init_hardware(struct mt76x2_dev *dev)
return ret;
 
mt76x2_mac_stop(dev, false);
-   dev->rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
 
return 0;
 }
-- 
2.14.2



[PATCH 10/14] mt76x2: clean up MAC/BSSID address initialization

2017-12-14 Thread Felix Fietkau
Drop the use of the EEPROM address entirely, rely on interface address
only

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 11 ---
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  | 14 ++
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index ac4eeaf2c993..f54dc67a13d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -231,7 +231,6 @@ mt76x2_init_beacon_offsets(struct mt76x2_dev *dev)
 int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard)
 {
static const u8 null_addr[ETH_ALEN] = {};
-   const u8 *macaddr = dev->mt76.macaddr;
u32 val;
int i, k;
 
@@ -271,13 +270,11 @@ int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard)
mt76_wr(dev, MT_MCU_CLOCK_CTL, 0x1401);
mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
 
-   mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(macaddr));
-   mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(macaddr + 4));
+   mt76_wr(dev, MT_MAC_ADDR_DW0, 0);
+   mt76_wr(dev, MT_MAC_ADDR_DW1, 0);
 
-   mt76_wr(dev, MT_MAC_BSSID_DW0, get_unaligned_le32(macaddr));
-   mt76_wr(dev, MT_MAC_BSSID_DW1, get_unaligned_le16(macaddr + 4) |
-   FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */
-   MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
+   mt76_wr(dev, MT_MAC_BSSID_DW0, 0);
+   mt76_wr(dev, MT_MAC_BSSID_DW1, 0);
 
mt76_set(dev, MT_MAC_ADDR_EXT_CTL, MT_MAC_ADDR_EXT_CTL_EN);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index 60cee4abed7c..d2ae093b7092 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -27,6 +27,15 @@ void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, 
const u8 *addr)
if (addr) {
lo = get_unaligned_le32(addr);
hi = get_unaligned_le16(addr + 4);
+
+   if (!idx) {
+   mt76_wr(dev, MT_MAC_BSSID_DW0, lo);
+
+   mt76_rmw_field(dev, MT_MAC_BSSID_DW1,
+  MT_MAC_BSSID_DW1_ADDR,
+  hi);
+   }
+
hi |= MT_MAC_APC_BSSID0_H_EN;
}
 
@@ -41,6 +50,11 @@ void mt76x2_mac_set_ext_mac(struct mt76x2_dev *dev, u8 idx, 
const u8 *addr)
if (addr) {
lo = get_unaligned_le32(addr);
hi = get_unaligned_le16(addr + 4);
+
+   if (!idx) {
+   mt76_wr(dev, MT_MAC_ADDR_DW0, lo);
+   mt76_wr(dev, MT_MAC_ADDR_DW1, hi);
+   }
}
 
mt76_wr(dev, MT_MAC_ADDR_EXT_L(idx), lo);
-- 
2.14.2



[PATCH 12/14] mt76x2: init: disable APCLI by default

2017-12-14 Thread Felix Fietkau
From: Lorenzo Bianconi 

It is no longer necessary for client mode operation, vif index entries
8-16 are no longer used

Signed-off-by: Lorenzo Bianconi 
Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index 818164d1ed7a..ad17f9462358 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -307,8 +307,6 @@ int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard)
for (i = 0; i < 16; i++)
mt76_rr(dev, MT_TX_STAT_FIFO);
 
-   mt76_set(dev, MT_MAC_APC_BSSID_H(0), MT_MAC_APC_BSSID0_H_EN);
-
mt76_wr(dev, MT_CH_TIME_CFG,
MT_CH_TIME_CFG_TIMER_EN |
MT_CH_TIME_CFG_TX_AS_BUSY |
-- 
2.14.2



[PATCH 11/14] mt76x2: drop wiphy->addresses

2017-12-14 Thread Felix Fietkau
Now that the MAC address limitation is resolved, we no longer need a MAC
address list

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2.h  |  2 --
 drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 16 +---
 2 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2.h
index a993cc09cd1b..7f961cc4504a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h
@@ -84,8 +84,6 @@ struct mt76x2_calibration {
 struct mt76x2_dev {
struct mt76_dev mt76; /* must be first */
 
-   struct mac_address macaddr_list[8];
-
struct mutex mutex;
 
const u16 *beacon_offsets;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
index f54dc67a13d0..818164d1ed7a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
@@ -796,7 +796,7 @@ int mt76x2_register_device(struct mt76x2_dev *dev)
struct wiphy *wiphy = hw->wiphy;
void *status_fifo;
int fifo_size;
-   int i, ret;
+   int ret;
 
fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x2_tx_status));
status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL);
@@ -818,20 +818,6 @@ int mt76x2_register_device(struct mt76x2_dev *dev)
hw->sta_data_size = sizeof(struct mt76x2_sta);
hw->vif_data_size = sizeof(struct mt76x2_vif);
 
-   for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) {
-   u8 *addr = dev->macaddr_list[i].addr;
-
-   memcpy(addr, dev->mt76.macaddr, ETH_ALEN);
-
-   if (!i)
-   continue;
-
-   addr[0] |= BIT(1);
-   addr[0] ^= ((i - 1) << 2);
-   }
-   wiphy->addresses = dev->macaddr_list;
-   wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
-
wiphy->iface_combinations = if_comb;
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
 
-- 
2.14.2



[PATCH 13/14] mt76x2: configure rx filter based on monitor mode setting

2017-12-14 Thread Felix Fietkau
Due to an unrelated issue, the MT_RX_FILTR_CFG_PROMISC flag is currently
unset, which means that monitor mode is unconditionally enabled.
Toggle this flag based on the mac80211 monitor mode setting instead

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index 240e11508ecd..a69d441d9a47 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -146,6 +146,15 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed)
 
mutex_lock(&dev->mutex);
 
+   if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+   if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
+   dev->rxfilter |= MT_RX_FILTR_CFG_PROMISC;
+   else
+   dev->rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
+
+   mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter);
+   }
+
if (changed & IEEE80211_CONF_CHANGE_POWER) {
dev->txpower_conf = hw->conf.power_level * 2;
 
-- 
2.14.2



[PATCH 06/14] mt76x2: add channel argument to eeprom tx power functions

2017-12-14 Thread Felix Fietkau
Preparation for exposing maximum power to mac80211

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c | 30 +-
 drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h |  6 +++--
 drivers/net/wireless/mediatek/mt76/mt76x2_phy.c|  7 ++---
 3 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
index 29dc52ef629d..8fef400cb58e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
@@ -425,12 +425,13 @@ mt76x2_rate_power_val(u8 val)
return mt76x2_sign_extend_optional(val, 7);
 }
 
-void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t)
+void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
+  struct ieee80211_channel *chan)
 {
bool is_5ghz;
u16 val;
 
-   is_5ghz = dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ;
+   is_5ghz = chan->band == NL80211_BAND_5GHZ;
 
memset(t, 0, sizeof(*t));
 
@@ -484,9 +485,9 @@ void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct 
mt76_rate_power *t)
 
 static void
 mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info 
*t,
-  int chain, int offset)
+struct ieee80211_channel *chan, int chain, int offset)
 {
-   int channel = dev->mt76.chandef.chan->hw_value;
+   int channel = chan->hw_value;
int delta_idx;
u8 data[6];
u16 val;
@@ -511,9 +512,9 @@ mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct 
mt76x2_tx_power_info *t,
 
 static void
 mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info 
*t,
-  int chain, int offset)
+struct ieee80211_channel *chan, int chain, int offset)
 {
-   int channel = dev->mt76.chandef.chan->hw_value;
+   int channel = chan->hw_value;
enum mt76x2_cal_channel_group group;
int delta_idx;
u16 val;
@@ -559,7 +560,8 @@ mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct 
mt76x2_tx_power_info *t,
 }
 
 void mt76x2_get_power_info(struct mt76x2_dev *dev,
-  struct mt76x2_tx_power_info *t)
+  struct mt76x2_tx_power_info *t,
+  struct ieee80211_channel *chan)
 {
u16 bw40, bw80;
 
@@ -568,13 +570,17 @@ void mt76x2_get_power_info(struct mt76x2_dev *dev,
bw40 = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW40);
bw80 = mt76x2_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80);
 
-   if (dev->mt76.chandef.chan->band == NL80211_BAND_5GHZ) {
+   if (chan->band == NL80211_BAND_5GHZ) {
bw40 >>= 8;
-   mt76x2_get_power_info_5g(dev, t, 0, MT_EE_TX_POWER_0_START_5G);
-   mt76x2_get_power_info_5g(dev, t, 1, MT_EE_TX_POWER_1_START_5G);
+   mt76x2_get_power_info_5g(dev, t, chan, 0,
+MT_EE_TX_POWER_0_START_5G);
+   mt76x2_get_power_info_5g(dev, t, chan, 1,
+MT_EE_TX_POWER_1_START_5G);
} else {
-   mt76x2_get_power_info_2g(dev, t, 0, MT_EE_TX_POWER_0_START_2G);
-   mt76x2_get_power_info_2g(dev, t, 1, MT_EE_TX_POWER_1_START_2G);
+   mt76x2_get_power_info_2g(dev, t, chan, 0,
+MT_EE_TX_POWER_0_START_2G);
+   mt76x2_get_power_info_2g(dev, t, chan, 1,
+MT_EE_TX_POWER_1_START_2G);
}
 
if (mt76x2_tssi_enabled(dev) || !field_valid(t->target_power))
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h 
b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
index 063d6c8451c9..6db2c6e47569 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
@@ -146,9 +146,11 @@ mt76x2_eeprom_get(struct mt76x2_dev *dev, enum 
mt76x2_eeprom_field field)
return get_unaligned_le16(dev->mt76.eeprom.data + field);
 }
 
-void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t);
+void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
+  struct ieee80211_channel *chan);
 void mt76x2_get_power_info(struct mt76x2_dev *dev,
-  struct mt76x2_tx_power_info *t);
+  struct mt76x2_tx_power_info *t,
+  struct ieee80211_channel *chan);
 int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t);
 bool mt76x2_ext_pa_enabled(struct mt76x2_dev *dev, enum nl80211_band band);
 void mt76x2_read_rx_gain(struct mt76x2_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index fe3a4b6a19cc

[PATCH 05/14] mt76x2: increase OFDM SIFS time

2017-12-14 Thread Felix Fietkau
Fixes throughput issues in combination with LDPC

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_phy.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
index 126497172284..fe3a4b6a19cc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
@@ -325,8 +325,7 @@ mt76x2_configure_tx_delay(struct mt76x2_dev *dev, enum 
nl80211_band band, u8 bw)
mt76_wr(dev, MT_TX_SW_CFG0, cfg0);
mt76_wr(dev, MT_TX_SW_CFG1, cfg1);
 
-   mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_CCK_SIFS,
-  13 + (bw ? 1 : 0));
+   mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_OFDM_SIFS, 15);
 }
 
 static void
@@ -559,7 +558,6 @@ int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
u8 bw, bw_index;
int freq, freq1;
int ret;
-   u8 sifs = 13;
 
dev->cal.channel_cal_done = false;
freq = chandef->chan->center_freq;
@@ -611,11 +609,6 @@ int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
  MT_EXT_CCA_CFG_CCA_MASK),
 ext_cca_chan[ch_group_index]);
 
-   if (chandef->width >= NL80211_CHAN_WIDTH_40)
-   sifs++;
-
-   mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_OFDM_SIFS, sifs);
-
ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
if (ret)
return ret;
-- 
2.14.2



[PATCH 03/14] mt76x2: remove some harmless WARN_ONs in tx status and rx path

2017-12-14 Thread Felix Fietkau
Discard affected packets instead. Should reduce the frequency of bogus
bug reports

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 28 -
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index a1f695e9b51c..f7c0df0759f7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -28,7 +28,7 @@ void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, 
const u8 *addr)
   get_unaligned_le16(addr + 4));
 }
 
-static void
+static int
 mt76x2_mac_process_rate(struct ieee80211_rx_status *status, u16 rate)
 {
u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate);
@@ -42,7 +42,7 @@ mt76x2_mac_process_rate(struct ieee80211_rx_status *status, 
u16 rate)
idx += 4;
 
status->rate_idx = idx;
-   return;
+   return 0;
case MT_PHY_TYPE_CCK:
if (idx >= 8) {
idx -= 8;
@@ -53,7 +53,7 @@ mt76x2_mac_process_rate(struct ieee80211_rx_status *status, 
u16 rate)
idx = 0;
 
status->rate_idx = idx;
-   return;
+   return 0;
case MT_PHY_TYPE_HT_GF:
status->enc_flags |= RX_ENC_FLAG_HT_GF;
/* fall through */
@@ -67,8 +67,7 @@ mt76x2_mac_process_rate(struct ieee80211_rx_status *status, 
u16 rate)
status->nss = FIELD_GET(MT_RATE_INDEX_VHT_NSS, idx) + 1;
break;
default:
-   WARN_ON(1);
-   return;
+   return -EINVAL;
}
 
if (rate & MT_RXWI_RATE_LDPC)
@@ -92,6 +91,8 @@ mt76x2_mac_process_rate(struct ieee80211_rx_status *status, 
u16 rate)
default:
break;
}
+
+   return 0;
 }
 
 static __le16
@@ -272,12 +273,10 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct 
sk_buff *skb,
status->freq = dev->mt76.chandef.chan->center_freq;
status->band = dev->mt76.chandef.chan->band;
 
-   mt76x2_mac_process_rate(status, rate);
-
-   return 0;
+   return mt76x2_mac_process_rate(status, rate);
 }
 
-static void
+static int
 mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate,
   enum nl80211_band band)
 {
@@ -293,13 +292,13 @@ mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate 
*txrate, u16 rate,
idx += 4;
 
txrate->idx = idx;
-   return;
+   return 0;
case MT_PHY_TYPE_CCK:
if (idx >= 8)
idx -= 8;
 
txrate->idx = idx;
-   return;
+   return 0;
case MT_PHY_TYPE_HT_GF:
txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD;
/* fall through */
@@ -312,8 +311,7 @@ mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate 
*txrate, u16 rate,
txrate->idx = idx;
break;
default:
-   WARN_ON(1);
-   return;
+   return -EINVAL;
}
 
switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) {
@@ -326,12 +324,14 @@ mt76x2_mac_process_tx_rate(struct ieee80211_tx_rate 
*txrate, u16 rate,
txrate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
break;
default:
-   WARN_ON(1);
+   return -EINVAL;
break;
}
 
if (rate & MT_RXWI_RATE_SGI)
txrate->flags |= IEEE80211_TX_RC_SHORT_GI;
+
+   return 0;
 }
 
 static void
-- 
2.14.2



Re: [v3,1/4] ath10k: WMI: modify svc bitmap parsing for wcn3990

2017-12-14 Thread Kalle Valo
Rakesh Pillai  wrote:

> Due to the limitation of wmi tlv parsing logic, if there are
> two parameters in a wmi event with same tlv tag, we can get only
> the last value, as it overwrites the prev value of the same tlv tag.
> 
> The service ready event in wcn3990 contains two parameters of the
> same tag UINT32, due to which the svc bitmap is overwritten with the
> DBS support parameter.
> 
> Refactor the service ready event parsing to allow parsing two tlv
> of the same tag UINT32 for wcn3990.
> 
> Signed-off-by: Rakesh Pillai 
> Signed-off-by: Govind Singh 
> Signed-off-by: Kalle Valo 

4 patches applied to ath-next branch of ath.git, thanks.

229329ff345f ath10k: wmi: modify svc bitmap parsing for wcn3990
1807da49733e ath10k: wmi: add management tx by reference support over wmi
9f2992fea580 ath10k: wmi: get wmi init parameter values from hw params
03a72288c546 ath10k: wmi: add hw params entry for wcn3990

-- 
https://patchwork.kernel.org/patch/10105283/

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



Re: wcn36xx: Reduce spinlock in indication handler

2017-12-14 Thread Kalle Valo
Bjorn Andersson  wrote:

> The purpose of pushing indication on a list and handle these in a
> separate worker is to allow the handlers to sleep. It does therefor not
> make much sense to hold the queue spinlock through the entire indication
> worker function.
> 
> By removing items from the queue early we don't need to hold the lock
> throughout the indication worker, allowing the individual handlers to
> sleep.
> 
> Signed-off-by: Bjorn Andersson 
> Signed-off-by: Kalle Valo 

Patch applied to ath-next branch of ath.git, thanks.

6d1f37323f5b wcn36xx: Reduce spinlock in indication handler

-- 
https://patchwork.kernel.org/patch/10103469/

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



Re: ath9k_htc: Add a sanity check in ath9k_htc_ampdu_action()

2017-12-14 Thread Kalle Valo
Dan Carpenter  wrote:

> Smatch generates a warning here:
> 
> drivers/net/wireless/ath/ath9k/htc_drv_main.c:1688 
> ath9k_htc_ampdu_action()
> error: buffer overflow 'ista->tid_state' 8 <= 15
> 
> I don't know if it's a real bug or not but the other paths through this
> function all ensure that "tid" is less than ATH9K_HTC_MAX_TID (8) so
> checking here makes things more consistent.
> 
> Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
> Signed-off-by: Dan Carpenter 
> Signed-off-by: Kalle Valo 

Patch applied to ath-next branch of ath.git, thanks.

413fd2f5c023 ath9k_htc: Add a sanity check in ath9k_htc_ampdu_action()

-- 
https://patchwork.kernel.org/patch/10093021/

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



Re: [PATCH 0/2] Fix two possible NULL pointer dereferencing issues

2017-12-14 Thread Felix Fietkau
On 2017-12-14 13:03, Lorenzo Bianconi wrote:
> Lorenzo Bianconi (2):
>   mt76: fix possible NULL pointer dereferencing in mt76x2_ampdu_action()
>   mt76: fix possible NULL pointer dereferencing in
> mt76x2_mac_write_txwi()
For both patches:
Acked-by: Felix Fietkau 


Re: [PATCH] mt76x2: eeprom: fix typo in mt76x2_get_power_info_5g()

2017-12-14 Thread Felix Fietkau
On 2017-12-14 11:46, Lorenzo Bianconi wrote:
> Fix typo in 5GHz power vs channel eeprom parsing
> 
> Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
> Signed-off-by: Lorenzo Bianconi 
Acked-by: Felix Fietkau 


Re: wcn36xx: Add hardware scan offload support

2017-12-14 Thread Kalle Valo
Loic Poulain  wrote:

> Current hw_scan implementation does not trigger offloaded
> hardware scan and seems to only put the device in a kind of
> listening mode (beacon/probe-response) for software scan.
> Since no probe request are generated by the software, current
> scanning method is similar to a passive scan.
> 
> This patch introduces support for 'true' hardware offloaded scan.
> Hardware scan is configured and started via the start-scan-offload
> firmware message. Once scan has been completed a scan indicator
> message is received from firmware.
> 
> Moreover, this patch includes support for directed probe-request,
> allowing connection with hidden APs. It also fixes scan issues with
> band-steering AP which are not 'visible' with passive scan (due to
> hidden ssid in beacons).
> 
> Let's keep the 'legacy' scanning method in case scan-offload is not
> supported.
> 
> Signed-off-by: Loic Poulain 
> Signed-off-by: Kalle Valo 

Patch applied to ath-next branch of ath.git, thanks.

2f3bef4b247e wcn36xx: Add hardware scan offload support

-- 
https://patchwork.kernel.org/patch/10101937/

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



Re: [v2, 1/2] dt: bindings: add new dt entry for ath10k calibration variant

2017-12-14 Thread Kalle Valo
Sven Eckelmann  wrote:

> The bus + bmi-chip-id + bmi-board-id is not enough to identify the correct
> board data file on QCA4019 based devices. Multiple different boards share
> the same values. Only the original reference designs can currently be
> identified and loaded from the board-2.bin. But these will not result in
> the correct calibration data when combined with the pre-calibration data
> from the device.
> 
> An additional "variant" information has to be provided (via SMBIOS or DT)
> to select the correct board data for a design which was modified by an ODM.
> 
> Signed-off-by: Sven Eckelmann 
> Signed-off-by: Kalle Valo 

2 patches applied to ath-next branch of ath.git, thanks.

40fb0eab30ba dt: bindings: add new dt entry for ath10k calibration variant
d06f26c5c8a4 ath10k: search DT for qcom,ath10k-calibration-variant

-- 
https://patchwork.kernel.org/patch/10102249/

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



Re: [PATCHv2, 1/3] ath10k: remove MAC80211_DEBUGFS dependency on ath10k_sta_statistics

2017-12-14 Thread Kalle Valo
ako...@qti.qualcomm.com wrote:

> Remove CONFIG_MAC80211_DEBUGFS dependency on ath10k_sta_statistics().
> ath10k_sta_statistics() has per sta tx/rx stats and this should not
> be dependent on MAC80211_DEBUGFS.
> 
> No changes in functionality.
> 
> Signed-off-by: Anilkumar Kolli 
> Signed-off-by: Kalle Valo 

3 patches applied to ath-next branch of ath.git, thanks.

6a7f891178c2 ath10k: remove MAC80211_DEBUGFS dependency on ath10k_sta_statistics
7f9befbb555d ath10k: move pktlog_filter out of ath10k_debug
e8123bb74c4e ath10k: add per peer tx stats support for 10.2.4

-- 
https://patchwork.kernel.org/patch/10092915/

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



Re: ath10k: handling qos at STA side based on AP WMM enable/disable

2017-12-14 Thread Kalle Valo
bpoth...@qti.qualcomm.com wrote:

> Data packets are not sent by STA in case of STA joined to
> non QOS AP (WMM disabled AP). This is happening because of STA
> is sending data packets to firmware from host with qos enabled
> along with non qos queue value(TID = 16).
> Due to qos enabled, firmware is discarding the packet.
> 
> This patch fixes this issue by updating the qos based on station
> WME capability field if WMM is disabled in AP.
> 
> This patch is required by 10.4 family chipsets like
> QCA4019/QCA9888/QCA9884/QCA99X0.
> Firmware Versoin : 10.4-3.5.1-00018.
> 
> For 10.2.4 family chipsets QCA988X/QCA9887 and QCA6174 this patch
> has no effect.
> 
> Signed-off-by: Balaji Pothunoori 
> Signed-off-by: Kalle Valo 

Patch applied to ath-next branch of ath.git, thanks.

07ffb4497360 ath10k: handling qos at STA side based on AP WMM enable/disable

-- 
https://patchwork.kernel.org/patch/10079089/

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



Re: [PATCH v3 1/3] mac80211: Add TXQ scheduling API

2017-12-14 Thread Toke Høiland-Jørgensen
Felix Fietkau  writes:

> On 2017-12-14 13:15, Toke Høiland-Jørgensen wrote:
>> Felix Fietkau  writes:
>> 
>>> On 2017-10-31 12:27, Toke Høiland-Jørgensen wrote:
 This adds an API to mac80211 to handle scheduling of TXQs and changes the
 interface between driver and mac80211 for TXQ handling as follows:
 
 - The wake_tx_queue callback interface no longer includes the TXQ. Instead,
   the driver is expected to retrieve that from ieee80211_next_txq()
 
 - Two new mac80211 functions are added: ieee80211_next_txq() and
   ieee80211_schedule_txq(). The former returns the next TXQ that should be
   scheduled, and is how the driver gets a queue to pull packets from. The
   latter is called internally by mac80211 to start scheduling a queue, and
   the driver is supposed to call it to re-schedule the TXQ after it is
   finished pulling packets from it (unless the queue emptied).
 
 The ath9k and ath10k drivers are changed to use the new API.
 
 Signed-off-by: Toke Høiland-Jørgensen 
>>> Sorry that I didn't have time to give this a thorough review earlier,
>>> since I was pretty busy with other projects. Now that I'm working on
>>> porting mt76 to this new API, some things in this patch strike me as
>>> rather odd, and there might be some bugs and nasty limitations here:
>>>
>>> In the new API you can no longer select txq entries by hardware queue.
>>> When using multiple WMM queues, this could lead to station entries being
>>> requeued unnecessarily (because there is no room in the hw queue for the
>>> txq entry that ieee80211_next_txq happens to return).
>> 
>> Yeah, there's some tension between enforcing fairness (which is a per
>> station thing) and the WMM queueing stuff (which gives priority based on
>> WMM levels and ignores stations). There are basically two ways to
>> resolve this: Prioritising fairness or prioritising WMM levels. In the
>> former case, we first select which station to transmit to, and then
>> select the highest WMM priority level queued *for that station* (the
>> last part of this is missing from the code as it is now). In the latter
>> case, we keep scheduling per-WMM, then enforce fairness within that.
>> 
>> The former case has the potential to lead to starved hardware queues,
>> while the latter leads to unfairness. We had a bit of discussion of
>> which is better at netdev, but did not resolve it. Personally, I think
>> prioritising fairness is better, but I'm willing to be convinced
>> otherwise by data :). So my plan is to implement that fully and try it
>> out, then evaluate based on actual experiments...
>
> I don't really see how the approach taken in the current code is
> actually prioritising fairness by starving hardware queues, since any
> txq that can't be serviced in the current call because of queue depth
> will be requeued. So based on the traffic pattern this might actually
> lead to *more* unfairness.

Yeah, I'm not quite happy with the current state of the code as far as
that is concerned. I thought I would have had time to revisit this, but
then a bunch of other stuff came up and I never got around to it... Will
come back to this soon I hope... :/

>>> Since ieee80211_next_txq also refills the airtime fairness quantum, this
>>> might lead to some minor fairness issues.
>> 
>> I'm planning to change the way the scheduler works anyway, so this issue
>> should go away. Haven't had time to do that yet, unfortunately.
>
> Well, the problem is that the new code inside ath9k is a lot harder to
> verify for correct behavior (regarding the queue starvation issue), and
> I would really like to avoid nasty regressions that will be a nightmare
> to debug.

Fair point, avoiding that would be good of course :)

>>> In ath9k the code used to have a loop that goes through all pending txq
>>> entries until it has filled the hw queues again. You replaced that with
>>> some calls to ath_txq_schedule which now only considers one single txq.
>>> There are several reasons why this queue could potentially not be serviced:
>>> - ieee80211_tx_dequeue returned no frame
>>> - frame does not fit within BA window
>>> - txq was for another queue which is already filled
>>> Depending on the exact circumstances with enough stations this might
>>> lead to hardware queues getting starved.
>> 
>> Well, that loop was already removed when I implemented the in-driver
>> fairness scheduler.
> Now that's not true. I'm looking at the diff for "mac80211: Add TXQ
> scheduling API", and it removes these lines:
>
> -   /*
> -* If we succeed in scheduling something, immediately restart to
> make
> -* sure we keep the HW busy.
> -*/
> -   if(ath_tx_sched_aggr(sc, txq, tid)) {
> -   if (!active) {
> -   spin_lock_bh(&acq->lock);
> -   list_move_tail(&tid->list, &acq->acq_old);
> -   spin_unlock_bh(&acq->lock);
> -   }
> -   g

Re: BCM4356 does not initalize after firmware update

2017-12-14 Thread Stanislaw Gruszka
On Thu, Dec 14, 2017 at 10:13:29AM +0100, Arend van Spriel wrote:
> The cur_etheraddr is the first piece of info we try to get from the
> firmware. Could you build the driver with CONFIG_BRCMDBG and load
> the module with 'debug=0x181416'.

dmesg attached. 

Thanks
Stanislaw
[ 2665.150833] usbcore: deregistering interface driver brcmfmac
[ 2685.122741] brcmfmac: brcmfmac_module_init No platform data available.
[ 2685.123368] usbcore: registered new interface driver brcmfmac
[ 2685.129239] brcmfmac: brcmf_pcie_register Enter
[ 2685.131783] brcmfmac: brcmf_pcie_probe Enter 14e4:43ec (1/3)
[ 2685.132186] brcmfmac: brcmf_pcie_get_resource Phys addr : reg space = 
a0ff40af base addr 0x00f7c0
[ 2685.132194] brcmfmac: brcmf_pcie_get_resource Phys addr : mem space = 
a0ff4180 base addr 0x00f780 size 0x40
[ 2685.132213] brcmfmac: brcmf_chip_recognition found AXI chip: BCM4356, rev=2
[ 2685.133298] brcmfmac: brcmf_chip_cores_check  [1 ] core 0x800:47 base 
0x1800 wrap 0x1810
[ 2685.133306] brcmfmac: brcmf_chip_cores_check  [2 ] core 0x812:48 base 
0x18001000 wrap 0x18101000
[ 2685.133312] brcmfmac: brcmf_chip_cores_check  [3 ] core 0x83e:6  base 
0x18002000 wrap 0x18102000
[ 2685.133320] brcmfmac: brcmf_chip_cores_check  [4 ] core 0x83c:11 base 
0x18003000 wrap 0x18103000
[ 2685.133326] brcmfmac: brcmf_chip_cores_check  [5 ] core 0x81a:22 base 
0x18004000 wrap 0x18104000
[ 2685.12] brcmfmac: brcmf_chip_cores_check  [6 ] core 0x829:21 base 
0x18005000 wrap 0x18105000
[ 2685.17] brcmfmac: brcmf_chip_cores_check  [7 ] core 0x83d:2  base 
0x18006000 wrap 0x18106000
[ 2685.133343] brcmfmac: brcmf_chip_cores_check  [8 ] core 0x135:0  base 
0x wrap 0x1810a000
[ 2685.133348] brcmfmac: brcmf_chip_cores_check  [9 ] core 0x240:0  base 
0x wrap 0x
[ 2685.133353] brcmfmac: brcmf_chip_set_passive Enter
[ 2685.236599] brcmfmac: brcmf_pcie_reset_device config offset 0x0004, value 
0x100106
[ 2685.236610] brcmfmac: brcmf_pcie_reset_device config offset 0x004c, value 
0x4008
[ 2685.236618] brcmfmac: brcmf_pcie_reset_device config offset 0x0058, value 
0x886805
[ 2685.236625] brcmfmac: brcmf_pcie_reset_device config offset 0x005c, value 
0xfee0300c
[ 2685.236632] brcmfmac: brcmf_pcie_reset_device config offset 0x0060, value 
0x
[ 2685.236638] brcmfmac: brcmf_pcie_reset_device config offset 0x0064, value 
0x4182
[ 2685.236645] brcmfmac: brcmf_pcie_reset_device config offset 0x00dc, value 
0x10001
[ 2685.236652] brcmfmac: brcmf_pcie_reset_device config offset 0x0228, value 
0x0222
[ 2685.236658] brcmfmac: brcmf_pcie_reset_device config offset 0x0248, value 
0x
[ 2685.236665] brcmfmac: brcmf_pcie_reset_device config offset 0x04e0, value 
0x0017
[ 2685.236672] brcmfmac: brcmf_pcie_reset_device config offset 0x04f4, value 
0x
[ 2685.236679] brcmfmac: brcmf_chip_set_passive Enter
[ 2685.237106] brcmfmac: brcmf_chip_get_raminfo RAM: base=0x18 size=786432 
(0xc) sr=0 (0x0)
[ 2685.237137] brcmfmac: brcmf_chip_setup ccrev=47, pmurev=24, 
pmucaps=0x420e5f18
[ 2685.237141] brcmfmac: brcmf_get_module_param Enter, bus=2, chip=17238, rev=2
[ 2685.237148] brcmfmac: brcmf_fw_map_chip_to_name: using 
brcm/brcmfmac4356-pcie.bin for chip 0x004356(17238) rev 0x02
[ 2685.248121] brcmfmac: brcmf_fw_get_firmwares_pcie enter: dev=:03:00.0
[ 2685.252332] brcmfmac: brcmf_fw_request_code_done enter: dev=:03:00.0
[ 2685.252606] brcmfmac: brcmf_fw_request_nvram_done enter: dev=:03:00.0
[ 2685.256784] brcmfmac: brcmf_pcie_download_fw_nvram Halt ARM.
[ 2685.256790] brcmfmac: brcmf_pcie_download_fw_nvram Download FW 
brcm/brcmfmac4356-pcie.bin
[ 2685.588821] brcmfmac: brcmf_pcie_download_fw_nvram No matching NVRAM file 
found brcm/brcmfmac4356-pcie.txt
[ 2685.588831] brcmfmac: brcmf_pcie_download_fw_nvram Bring ARM in running state
[ 2685.588834] brcmfmac: brcmf_chip_set_active Enter
[ 2685.589035] brcmfmac: brcmf_pcie_download_fw_nvram Wait for FW init
[ 2685.639593] brcmfmac: brcmf_pcie_download_fw_nvram Shared RAM addr: 
0x001f1528
[ 2685.639603] brcmfmac: brcmf_pcie_init_share_ram_info PCIe protocol version 5
[ 2685.639620] brcmfmac: brcmf_pcie_init_share_ram_info max rx buf post 255, rx 
dataoffset 0
[ 2685.639633] brcmfmac: brcmf_pcie_bus_console_init Console: base 23debc, buf 
23dab4, size 1024
[ 2685.639657] brcmfmac: brcmf_pcie_init_ringbuffers Using TCM indices
[ 2685.639712] brcmfmac: brcmf_pcie_init_ringbuffers Nr of flowrings is 40
[ 2685.639736] brcmfmac: brcmf_pcie_request_irq Enter
[ 2685.639822] brcmfmac :03:00.0: irq 31 for MSI/MSI-X
[ 2685.640052] brcmfmac: brcmf_attach Enter
[ 2685.640202] brcmfmac: brcmf_proto_attach Enter
[ 2685.642347] brcmfmac: brcmf_pcie_ring_mb_write_wptr W w_ptr 255 (0), ring 1
[ 2685.642354] brcmfmac: brcmf_pcie_ring_mb_ring_bell RING !
[ 2685.642594] brcmfmac: brcmf_pcie_ring_mb_write_wptr W w_ptr 8 (0), ring 0
[ 2685.642599] brcmfmac: brcmf_pcie_ring_mb_ring_bell RING !
[ 2685.642790] brcmfmac: brcmf_pcie_r

Re: [v5 5/8] Bluetooth: btrsi: add new rsi bluetooth driver

2017-12-14 Thread Amitkumar Karwar
On Wed, Dec 13, 2017 at 7:16 PM, Marcel Holtmann  wrote:
> Hi Amitkumar,
>
>> Redpine bluetooth driver is a thin driver which depends on
>> 'rsi_91x' driver for transmitting and receiving packets
>> to/from device. It creates hci interface when attach() is
>> called from 'rsi_91x' module.
>>
>> Signed-off-by: Prameela Rani Garnepudi 
>> Signed-off-by: Siva Rebbagondla 
>> Signed-off-by: Amitkumar Karwar 
>> ---
>> v5: Addressed review comments from Marcel.
>>Removed reduntant switch case code from rsi_hci_recv_pkt()
>>Changed bt_cb(skb)->pkt_type to hci_skb_pkt_type(skb)
>>Removed reduntant '\n' from BT_ERR and redundant BT_INFO messages
>>Changed u8 *pkt to const u8 *pkt in rsi_hci_recv_pkt()
>> v4: Removed rsi_hci.h file. Made the functions static(Marcel)
>> v3: Made BT_RSI module by default off(Marcel)
>>Removed redundant exported function rsi_get_hci_ops()(Marcel)
>> v2: Addressed review comments from Marcel
>>Removed unnecessary 'depends on BT && BT_RFOMM' line in Kconfig
>>Removed redundant BT_INFO messages
>>h_adapter initialization and declaration in a single line.
>>Removed unnecessary error checks for HCI_RUNNING and fsm_state
>>Allocated new skb with skb_realloc_headroom() API if headroom is not 
>> sufficient
>>Used get_unaligned_le16 helpers
>>Moved a structure and union from header file to btrsi.c file
>> ---
>> drivers/bluetooth/Kconfig  |  11 +++
>> drivers/bluetooth/Makefile |   2 +
>> drivers/bluetooth/btrsi.c  | 188 
>> +
>> include/linux/rsi_header.h |   4 +-
>> 4 files changed, 204 insertions(+), 1 deletion(-)
>> create mode 100644 drivers/bluetooth/btrsi.c
>>
>> diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
>> index 60e1c7d..33d7514 100644
>> --- a/drivers/bluetooth/Kconfig
>> +++ b/drivers/bluetooth/Kconfig
>> @@ -378,4 +378,15 @@ config BT_QCOMSMD
>> Say Y here to compile support for HCI over Qualcomm SMD into the
>> kernel or say M to compile as a module.
>>
>> +config BT_RSI
>> + tristate "Redpine HCI support"
>> + default n
>> + help
>> +   Redpine BT driver.
>> +   This driver handles BT traffic from upper layers and pass
>> +   to the RSI_91x coex module for further scheduling to device
>> +
>> +   Say Y here to compile support for HCI over Redpine into the
>> +   kernel or say M to compile as a module.
>> +
>> endmenu
>> diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
>> index 4e4e44d..712af83a 100644
>> --- a/drivers/bluetooth/Makefile
>> +++ b/drivers/bluetooth/Makefile
>> @@ -28,6 +28,8 @@ obj-$(CONFIG_BT_QCA)+= btqca.o
>>
>> obj-$(CONFIG_BT_HCIUART_NOKIA)+= hci_nokia.o
>>
>> +obj-$(CONFIG_BT_RSI) += btrsi.o
>> +
>
> actually I never caught this before. Since this driver is doing the HCI 
> portion, for consistency CONFIG_BT_HCIRSI would be better.
>
>> btmrvl-y  := btmrvl_main.o
>> btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
>>
>> diff --git a/drivers/bluetooth/btrsi.c b/drivers/bluetooth/btrsi.c
>> new file mode 100644
>> index 000..c9e92cc
>> --- /dev/null
>> +++ b/drivers/bluetooth/btrsi.c
>> @@ -0,0 +1,188 @@
>> +/**
>> + * Copyright (c) 2017 Redpine Signals Inc.
>> + *
>> + * Permission to use, copy, modify, and/or distribute this software for any
>> + * purpose with or without fee is hereby granted, provided that the above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define RSI_HEADROOM_FOR_BT_HAL  16
>> +#define RSI_FRAME_DESC_SIZE  16
>> +
>> +static struct rsi_hci_adapter {
>> + void *priv;
>> + struct rsi_proto_ops *proto_ops;
>> + struct hci_dev *hdev;
>> +};
>> +
>> +static int rsi_hci_open(struct hci_dev *hdev)
>> +{
>> + return 0;
>> +}
>> +
>> +static int rsi_hci_close(struct hci_dev *hdev)
>> +{
>> + return 0;
>> +}
>> +
>> +static int rsi_hci_flush(struct hci_dev *hdev)
>> +{
>> + return 0;
>> +}
>> +
>> +static int rsi_hci_send_pkt(struct hci_dev *hdev, struct sk_buff *skb)
>> +{
>> + struct rsi_hci_adapter *h_adapter = hci_get_drvdata(hdev);
>> + struct sk_buff *new_skb = NULL;
>> +
>> + switch (hci_skb_pkt_type(skb)) {
>> + case HCI_COMMAND_PKT:
>> + hdev->stat.cmd_tx++;
>

[PATCH] wireless: Always rewrite generated files from scratch

2017-12-14 Thread Thierry Reding
From: Thierry Reding 

Currently the certs C code generation appends to the generated files,
which is most likely a leftover from commit 715a12334764 ("wireless:
don't write C files on failures"). This causes duplicate code in the
generated files if the certificates have their timestamps modified
between builds and thereby trigger the generation rules.

Fixes: 715a12334764 ("wireless: don't write C files on failures")
Signed-off-by: Thierry Reding 
---
Based on next-20171214

 net/wireless/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index d7d6cb00c47b..b662be3422e1 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -43,7 +43,7 @@ $(obj)/shipped-certs.c: $(wildcard 
$(srctree)/$(src)/certs/*.x509)
  echo "$$allf"; \
  echo '};'; \
  echo 'unsigned int shipped_regdb_certs_len = 
sizeof(shipped_regdb_certs);'; \
- ) >> $@)
+ ) > $@)
 
 $(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \
  $(wildcard 
$(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509)
@@ -66,4 +66,4 @@ $(obj)/extra-certs.c: 
$(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \
  echo "$$allf"; \
  echo '};'; \
  echo 'unsigned int extra_regdb_certs_len = 
sizeof(extra_regdb_certs);'; \
- ) >> $@)
+ ) > $@)
-- 
2.15.1



Re: [PATCH] ath10k: fix recent bandwidth conversion bug

2017-12-14 Thread Kalle Valo
Christian Lamparter  writes:

> On Monday, November 20, 2017 11:57:21 AM CET Kalle Valo wrote:
>> Christian Lamparter  writes:
>> 
>> > On Wednesday, November 1, 2017 9:37:53 PM CET Sebastian Gottschall wrote:
>> >> a additional array bounds check would be good
>> >
>> > Ah, about that:
>> >
>> > the bw variable in ath10k_htt_rx_h_rates() is extracted from info2
>> > in the following way [0]:
>> > |  bw = info2 & 3;
>> >
>> > the txrate.bw variable in ath10k_update_per_peer_tx_stats() is set by [1]:
>> > |  txrate.bw = ATH10K_HW_BW(peer_stats->flags);
>> >
>> > ATH10K_HW_BW is a macro defined as [2]:
>> > |  #define ATH10K_HW_BW(flags) (((flags) >> 3) & 0x3)
>> >
>> > In both cases the bandwidth values already are limited to 0-3 by
>> > the "and 3" operation.
>> 
>> Until someone changes that part of the code (and the firmware
>> interface). IMHO a switch is safer as there we don't have any risk of
>> out of bands access.
>
> The kbuild-bot/CI can catch this too. 
>
> For example, it will look like this:
> drivers/net/wireless/ath/ath10k//htt_rx.c:710:52: warning: invalid
> access past the end of 'ath10k_bw_to_mac80211' (4 4)

Sure, but after reading about all these security vulnerabilities I have
become even more cautious and try to avoid all tricky stuff.

> BTW:
> Have you noticed:
>
> 
>
> Is this really your signed-off-by or not?

I suspect that patch is taken from my pending branch.

> In any case, you - as the maintainer - can modify the patch as
> you see fit. So, please do so.

Ok, we'll send v2.

-- 
Kalle Valo

Re: regulatory.db file for ath10k

2017-12-14 Thread Kalle Valo
(please don't top post)

"KAVITA MATHUR"  writes:

> I do not want to use regulatory.db. Can you please share your ath10k build
> configuration? I may be missing something in configuration.

If you don't want to use regulatory.db you can just ignore the warning
and continue to use CRDA as before.

-- 
Kalle Valo

Re: rt2800usb firmware rt2870.bin 0.36 not scanning

2017-12-14 Thread Stanislaw Gruszka
On Wed, Dec 13, 2017 at 11:24:28PM +, Craig McQueen wrote:
> > Actually, I was wrong. With the 3.14.x Yocto-built kernel, this no-scan 
> > issue
> > only happens with the Edup with the 5390 chipset, and the D-Link is fine.
> > 
> > But further testing with the 4.4.12 Yocto-built kernel shows that it 
> > randomly
> > sometimes happens and sometimes doesn't with either the Edup or D-Link
> > devices. That's especially interesting, because it suggests that there may 
> > be a
> > race condition happening during the driver initialisation code (called from
> > rt2x00lib_start()). At first I thought it was a race condition between the 
> > calls
> > to rt2x00lib_load_firmware() and rt2x00lib_initialize(), but adding a time
> > delay between those calls didn't help.
> > 
> > I'm wondering what the difference is between the two chipsets, so that the
> > problem happens more on one chipset than the other. But not exclusively, as
> > I mentioned above, so again, this points to a marginal timing issue that
> > affects one more than the other.
> > 
> > > With the Ubuntu 4.4.6 kernel, both devices work fine, without this
> > > no-scan problem.
> > > ...
> 
> Now I'm using a 4.9.65 kernel, and this problem is still present. When the 
> USB Wi-Fi dongle is plugged in, it just doesn't do anything -- doesn't scan 
> for Wi-Fi networks, doesn't connect to anything.
> 
> My project is using ConnMan, so I've patched ConnMan so that it takes the 
> device up, then down, then up again. Then it reliably works. But of course 
> this is an ugly hack.
> 
> Based on my initial investigation, my hypothesis was that there's a race 
> condition during rt2x00lib_start() in rt2x00dev.c. At first I thought it was 
> between firmware loading and initialisation. But adding a time delay between 
> the calls to rt2x00lib_load_firmware() and rt2x00lib_initialize() didn't 
> help. Adding time delays at many possible points in the initialisation didn't 
> seem to help. I thought there must be a race condition in a very specific 
> location in the initialisation sequence, but could not confirm that 
> hypothesis. So now I've drawn a blank.
> 
> Any advice on how to diagnose and remedy this issue?

I know the vendor driver do initialization sequence twice - after
finish first sequence the same steps are repeated second time.
I don't know why that is needed and on all my Ralink USB devices
one initialization sequence is sufficient with rt2x00 driver.

Right fix to this will be found proper initialization sequence,
so second step will not be needed, but perhaps this is firmware
problem. Anyway ConnMan patch seems to be a good solution
as well ;-) 

Cheers
Stanislaw


Re: wlcore: fix unused function warning

2017-12-14 Thread Kalle Valo
Arnd Bergmann  wrote:

> The newly added wlcore_fw_sleep function is called conditionally,
> which causes a warning without CONFIG_PM:
> 
> drivers/net/wireless/ti/wlcore/main.c:981:12: error: 'wlcore_fw_sleep' 
> defined but not used [-Werror=unused-function]
> 
> Instead of trying to keep track of what should be in the #ifdef and what
> should not, it's easier to mark the top-level suspend/resume functions
> as __maybe_unused so the compiler can silently drop all the unused code.
> 
> Fixes: 37bf241b8e7b ("wlcore: allow elp during wowlan suspend")
> Signed-off-by: Arnd Bergmann 

Patch applied to wireless-drivers-next.git, thanks.

7de241f3b705 wlcore: fix unused function warning

-- 
https://patchwork.kernel.org/patch/10104839/

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



Re: [1/1] rtlwifi: always initialize variables given to RT_TRACE()

2017-12-14 Thread Kalle Valo
Nicolas Iooss  wrote:

> In rtl_rx_ampdu_apply(), when rtlpriv->cfg->ops->get_btc_status()
> returns false, RT_TRACE() is called with the values of variables
> reject_agg and agg_size, which have not been initialized.
> 
> Always initialize these variables in order to prevent using
> uninitialized values.
> 
> This issue has been found with clang. The compiler reported:
> 
> drivers/net/wireless/realtek/rtlwifi/base.c:1665:6: error: variable
> 'agg_size' is used uninitialized whenever 'if' condition is false
> [-Werror,-Wsometimes-uninitialized]
> if (rtlpriv->cfg->ops->get_btc_status())
> ^~~
> drivers/net/wireless/realtek/rtlwifi/base.c:1671:31: note:
> uninitialized use occurs here
>  reject_agg, ctrl_agg_size, agg_size);
> ^~~~
> 
> drivers/net/wireless/realtek/rtlwifi/base.c:1665:6: error: variable
> 'reject_agg' is used uninitialized whenever 'if' condition
>   is false [-Werror,-Wsometimes-uninitialized]
> if (rtlpriv->cfg->ops->get_btc_status())
> ^~~
> drivers/net/wireless/realtek/rtlwifi/base.c:1671:4: note:
> uninitialized use occurs here
>  reject_agg, ctrl_agg_size, agg_size);
>  ^~
> 
> Fixes: 2635664e6e4a ("rtlwifi: Add rx ampdu cfg for btcoexist.")
> Signed-off-by: Nicolas Iooss 

Patch applied to wireless-drivers-next.git, thanks.

e4779162f737 rtlwifi: always initialize variables given to RT_TRACE()

-- 
https://patchwork.kernel.org/patch/10103995/

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



Re: [PATCH v3 1/3] mac80211: Add TXQ scheduling API

2017-12-14 Thread Felix Fietkau
On 2017-12-14 13:15, Toke Høiland-Jørgensen wrote:
> Felix Fietkau  writes:
> 
>> On 2017-10-31 12:27, Toke Høiland-Jørgensen wrote:
>>> This adds an API to mac80211 to handle scheduling of TXQs and changes the
>>> interface between driver and mac80211 for TXQ handling as follows:
>>> 
>>> - The wake_tx_queue callback interface no longer includes the TXQ. Instead,
>>>   the driver is expected to retrieve that from ieee80211_next_txq()
>>> 
>>> - Two new mac80211 functions are added: ieee80211_next_txq() and
>>>   ieee80211_schedule_txq(). The former returns the next TXQ that should be
>>>   scheduled, and is how the driver gets a queue to pull packets from. The
>>>   latter is called internally by mac80211 to start scheduling a queue, and
>>>   the driver is supposed to call it to re-schedule the TXQ after it is
>>>   finished pulling packets from it (unless the queue emptied).
>>> 
>>> The ath9k and ath10k drivers are changed to use the new API.
>>> 
>>> Signed-off-by: Toke Høiland-Jørgensen 
>> Sorry that I didn't have time to give this a thorough review earlier,
>> since I was pretty busy with other projects. Now that I'm working on
>> porting mt76 to this new API, some things in this patch strike me as
>> rather odd, and there might be some bugs and nasty limitations here:
>>
>> In the new API you can no longer select txq entries by hardware queue.
>> When using multiple WMM queues, this could lead to station entries being
>> requeued unnecessarily (because there is no room in the hw queue for the
>> txq entry that ieee80211_next_txq happens to return).
> 
> Yeah, there's some tension between enforcing fairness (which is a per
> station thing) and the WMM queueing stuff (which gives priority based on
> WMM levels and ignores stations). There are basically two ways to
> resolve this: Prioritising fairness or prioritising WMM levels. In the
> former case, we first select which station to transmit to, and then
> select the highest WMM priority level queued *for that station* (the
> last part of this is missing from the code as it is now). In the latter
> case, we keep scheduling per-WMM, then enforce fairness within that.
> 
> The former case has the potential to lead to starved hardware queues,
> while the latter leads to unfairness. We had a bit of discussion of
> which is better at netdev, but did not resolve it. Personally, I think
> prioritising fairness is better, but I'm willing to be convinced
> otherwise by data :). So my plan is to implement that fully and try it
> out, then evaluate based on actual experiments...
I don't really see how the approach taken in the current code is
actually prioritising fairness by starving hardware queues, since any
txq that can't be serviced in the current call because of queue depth
will be requeued. So based on the traffic pattern this might actually
lead to *more* unfairness.

>> Since ieee80211_next_txq also refills the airtime fairness quantum, this
>> might lead to some minor fairness issues.
> 
> I'm planning to change the way the scheduler works anyway, so this issue
> should go away. Haven't had time to do that yet, unfortunately.Well, the 
> problem is that the new code inside ath9k is a lot harder to
verify for correct behavior (regarding the queue starvation issue), and
I would really like to avoid nasty regressions that will be a nightmare
to debug.

>> In ath9k the code used to have a loop that goes through all pending txq
>> entries until it has filled the hw queues again. You replaced that with
>> some calls to ath_txq_schedule which now only considers one single txq.
>> There are several reasons why this queue could potentially not be serviced:
>> - ieee80211_tx_dequeue returned no frame
>> - frame does not fit within BA window
>> - txq was for another queue which is already filled
>> Depending on the exact circumstances with enough stations this might
>> lead to hardware queues getting starved.
> 
> Well, that loop was already removed when I implemented the in-driver
> fairness scheduler.
Now that's not true. I'm looking at the diff for "mac80211: Add TXQ
scheduling API", and it removes these lines:

-   /*
-* If we succeed in scheduling something, immediately restart to
make
-* sure we keep the HW busy.
-*/
-   if(ath_tx_sched_aggr(sc, txq, tid)) {
-   if (!active) {
-   spin_lock_bh(&acq->lock);
-   list_move_tail(&tid->list, &acq->acq_old);
-   spin_unlock_bh(&acq->lock);
-   }
-   goto begin;
-   }


> We can't really avoid those cases entirely if we
> want to enforce fairness (the BAW case in particular; if the only
> eligible station from an airtime PoW has a full BAW, you have to
> throttle and can potentially starve hwqs). However, don't think this
> happens much in practice (or we would have seen performance regressions
> by now).I think so far you simply haven't had enough users hammering on the 
> new
code

Re: [1/3] rtlwifi: rtl_pci: 8822BE puts broadcast and multicast packet to HIQ

2017-12-14 Thread Kalle Valo
Larry Finger  wrote:

> From: Ping-Ke Shih 
> 
> Making this change to HIQ, which has high priority, improves the response
> time for transmission after TBTT or beacon.
> 
> Signed-off-by: Ping-Ke Shih 
> Signed-off-by: Larry Finger 
> Cc: Yan-Hsuan Chuang 
> Cc: Birming Chiu 
> Cc: Shaofu 
> Cc: Steven Ting 

2 patches applied to wireless-drivers-next.git, thanks.

e298be2a97fd rtlwifi: rtl_pci: 8822BE puts broadcast and multicast packet to HIQ
b7573a0a27bf rtlwifi: rtl_pci: Fix the bug when inactiveps is enabled.

-- 
https://patchwork.kernel.org/patch/10103759/

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



Re: brcmfmac: enlarge buffer size of caps to 512 bytes

2017-12-14 Thread Kalle Valo
Wright Feng  wrote:

> The buffer size of return of cap iovar is greater than 256 bytes in some
> firmwares. For instance, the return size of cap iovar is 271 bytes in 4373
> 13.10.246.79 firmare. It makes feature capability parsing failed because
> caps buffer is default value.
> So we enlarge caps buffer size to 512 bytes and add the error print for
> cap iovar error.
> 
> Signed-off-by: Wright Feng 
> Acked-by: Arend van Spriel 

Patch applied to wireless-drivers-next.git, thanks.

7762bb134e3b brcmfmac: enlarge buffer size of caps to 512 bytes

-- 
https://patchwork.kernel.org/patch/10104357/

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



Re: [01/10] brcmfmac: Split brcmf_sdiod_buffrw function up.

2017-12-14 Thread Kalle Valo
Arend Van Spriel  wrote:

> From: Ian Molton 
> 
> This function needs to be split up into separate read / write variants
> for clarity.
> 
> Signed-off-by: Ian Molton 
> Reviewed-by: Arend van Spriel 
> Signed-off-by: Arend van Spriel 

10 patches applied to wireless-drivers-next.git, thanks.

8f13c87ccc49 brcmfmac: Split brcmf_sdiod_buffrw function up.
6e24dd012bfd brcmfmac: whitespace fixes in brcmf_sdiod_send_buf()
a7323378dcf1 brcmfmac: Clarify if using braces.
71bd508d7ded brcmfmac: Rename / replace old IO functions with simpler ones.
eeef8a5da781 brcmfmac: Tidy register definitions a little
a7c3aa1509e2 brcmfmac: Remove brcmf_sdiod_addrprep()
c900072bd6fa brcmfmac: remove unnecessary call to 
brcmf_sdiod_set_backplane_window()
e4c05fc3c0a6 brcmfmac: Cleanup offsetof()
5cfe38f1f8d3 brcmfmac: Remove unused macro.
21a10846d09d brcmfmac: Remove repeated calls to brcmf_chip_get_core()

-- 
https://patchwork.kernel.org/patch/10102409/

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



Re: brcmsmac: use ARRAY_SIZE on rfseq_updategainu_events

2017-12-14 Thread Kalle Valo
Colin Ian King  wrote:

> From: Colin Ian King 
> 
> Use the ARRAY_SIZE macro on rfseq_updategainu_events to determine
> size of the array. Improvement suggested by coccinelle.
> 
> Signed-off-by: Colin Ian King 
> Acked-by: Arend van Spriel 

Patch applied to wireless-drivers-next.git, thanks.

18907f20ea71 brcmsmac: use ARRAY_SIZE on rfseq_updategainu_events

-- 
https://patchwork.kernel.org/patch/10098257/

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



Re: brcmfmac: Support 43455 save-restore (SR) feature if FW include -sr

2017-12-14 Thread Kalle Valo
Wright Feng  wrote:

> From: Double Lo 
> 
> This patch will add 43455 into the save-restore(SR) capable chip list, so
> the SR engine will be enabled with 43455 FW which built-in the -sr
> function.
> 
> Signed-off-by: Double Lo 

Wright's s-o-b is missing:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#signed-off-by_missing

-- 
https://patchwork.kernel.org/patch/10097897/

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



Re: [PATCH 2/3] rtlwifi: Add beacon check mechanism to check if AP settings changed.

2017-12-14 Thread Kalle Valo
Larry Finger  writes:

> From: Tsang-Shian Lin 
>
> AP WiFi settings are changed(channel, bandwidth), but deauth may not
> received by STA. For these cases, we need to detect and handle beacon
> changes.
>
> Signed-off-by: Tsang-Shian Lin 
> Signed-off-by: Ping-Ke Shih 
> Signed-off-by: Larry Finger 
> Cc: Yan-Hsuan Chuang 
> Cc: Birming Chiu 
> Cc: Shaofu 
> Cc: Steven Ting 

[...]

> --- a/drivers/net/wireless/realtek/rtlwifi/base.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/base.c
> @@ -2360,6 +2360,185 @@ struct sk_buff *rtl_make_del_ba(struct ieee80211_hw 
> *hw,
>   return skb;
>  }
>  
> +bool rtl_check_beacon_key(struct ieee80211_hw *hw, void *data, unsigned int 
> len)
> +{
> + struct rtl_priv *rtlpriv = rtl_priv(hw);
> + struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
> + struct rtl_phy *rtlphy = &rtlpriv->phy;
> + struct ieee80211_hdr *hdr = data;
> + struct ieee80211_ht_cap *ht_cap_ie;
> + struct ieee80211_ht_operation *ht_oper_ie = NULL;
> + struct rtl_beacon_keys bcn_key = {0};
> + struct rtl_beacon_keys *cur_bcn_key;
> + u8 *ht_cap;
> + u8 ht_cap_len;
> + u8 *ht_oper;
> + u8 ht_oper_len;
> + u8 *ds_param;
> + u8 ds_param_len;
> +
> + if (mac->opmode != NL80211_IFTYPE_STATION)
> + return false;
> +
> + /* check if this really is a beacon*/
> + if (!ieee80211_is_beacon(hdr->frame_control))
> + return false;
> +
> + /* min. beacon length + FCS_LEN */
> + if (len <= 40 + FCS_LEN)
> + return false;
> +
> + cur_bcn_key = &mac->cur_beacon_keys;
> +
> + if (rtlpriv->mac80211.link_state == MAC80211_NOLINK) {
> + if (cur_bcn_key->valid) {
> + cur_bcn_key->valid = false;
> + RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
> +  "Reset cur_beacon_keys.valid to false!\n");
> + }
> + return false;
> + }
> +
> + /* and only beacons from the associated BSSID, please */
> + if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
> + return false;
> +
> + /* Parsing DS Param IE **/
> + ds_param = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_DS_PARAMS);
> +
> + if (ds_param && !(ds_param[1] < sizeof(*ds_param)))
> + ds_param_len = ds_param[1];
> + else
> + ds_param = NULL;
> +
> + /* Parsing HT Cap. IE **/
> + ht_cap = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_HT_CAPABILITY);
> +
> + if (ht_cap && !(ht_cap[1] < sizeof(*ht_cap))) {
> + ht_cap_len = ht_cap[1];
> + ht_cap_ie = (struct ieee80211_ht_cap *)&ht_cap[2];
> + } else  {
> + ht_cap = NULL;
> + ht_cap_ie = NULL;
> + }
> +
> + /* Parsing HT Info. IE **/
> + ht_oper = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_HT_OPERATION);
> +
> + if (ht_oper && !(ht_oper[1] < sizeof(*ht_oper))) {
> + ht_oper_len = ht_oper[1];
> + ht_oper_ie = (struct ieee80211_ht_operation *)&ht_oper[2];
> + } else {
> + ht_oper = NULL;
> + }
> +
> + /* update bcn_key */
> + memset(&bcn_key, 0, sizeof(bcn_key));
> +
> + if (ds_param)
> + bcn_key.bcn_channel = ds_param[2];
> + else if (ht_oper && ht_oper_ie)
> + bcn_key.bcn_channel = ht_oper_ie->primary_chan;
> +
> + if (ht_cap_ie)
> + bcn_key.ht_cap_info = ht_cap_ie->cap_info;
> +
> + if (ht_oper && ht_oper_ie)
> + bcn_key.ht_info_infos_0_sco = ht_oper_ie->ht_param & 0x03;
> +
> + bcn_key.valid = true;
> +
> + /* update cur_beacon_keys or compare beacon key */
> + if (rtlpriv->mac80211.link_state != MAC80211_LINKED &&
> + rtlpriv->mac80211.link_state != MAC80211_LINKED_SCANNING)
> + return true;
> +
> + if (!cur_bcn_key->valid) {
> + /* update cur_beacon_keys */
> + memset(cur_bcn_key, 0, sizeof(bcn_key));
> + memcpy(cur_bcn_key, &bcn_key, sizeof(bcn_key));
> + cur_bcn_key->valid = true;
> +
> + RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
> +  "Beacon key update!ch=%d, ht_cap_info=0x%x, 
> sco=0x%x\n",
> +  cur_bcn_key->bcn_channel,
> +  cur_bcn_key->ht_cap_info,
> +  cur_bcn_key->ht_info_infos_0_sco);
> +
> + return true;
> + }
> +
> + /* compare beacon key */
> + if (!memcmp(cur_bcn_key, &bcn_key, sizeof(bcn_key))) {
> + /* same beacon key */
> + mac->new_beacon_cnt = 0;
> + goto chk_exit;
> + }
> +
> + if (cur_bcn_key->bcn_channel == bcn_key.bcn_channel &&
> + cur_bcn_key->ht_cap_info == bcn_key.ht_cap_info) {
> + /* Beacon HT info IE, secondary channel offset check */
> + /* 40M -> 20M */
> + if (cur_bcn_key->ht_info_infos_0_sco >
> + bcn_key.ht_

Re: [v4 5/8] Bluetooth: btrsi: add new rsi bluetooth driver

2017-12-14 Thread Kalle Valo
Marcel Holtmann  writes:

>> Thanks for your review.
>> We have addressed these comments and submitted v5.
>
> minor comment from my side, but otherwise looks good to me. Due to the
> dependency, I think this should go via wireless-drivers tree.
>
> Kalle, I think it is up to you to take the whole set.

Ok, thanks.. But please note that I haven't had a chance to review the
wireless part yet.

-- 
Kalle Valo


Re: [PATCH v3 1/3] mac80211: Add TXQ scheduling API

2017-12-14 Thread Toke Høiland-Jørgensen
Felix Fietkau  writes:

> On 2017-10-31 12:27, Toke Høiland-Jørgensen wrote:
>> This adds an API to mac80211 to handle scheduling of TXQs and changes the
>> interface between driver and mac80211 for TXQ handling as follows:
>> 
>> - The wake_tx_queue callback interface no longer includes the TXQ. Instead,
>>   the driver is expected to retrieve that from ieee80211_next_txq()
>> 
>> - Two new mac80211 functions are added: ieee80211_next_txq() and
>>   ieee80211_schedule_txq(). The former returns the next TXQ that should be
>>   scheduled, and is how the driver gets a queue to pull packets from. The
>>   latter is called internally by mac80211 to start scheduling a queue, and
>>   the driver is supposed to call it to re-schedule the TXQ after it is
>>   finished pulling packets from it (unless the queue emptied).
>> 
>> The ath9k and ath10k drivers are changed to use the new API.
>> 
>> Signed-off-by: Toke Høiland-Jørgensen 
> Sorry that I didn't have time to give this a thorough review earlier,
> since I was pretty busy with other projects. Now that I'm working on
> porting mt76 to this new API, some things in this patch strike me as
> rather odd, and there might be some bugs and nasty limitations here:
>
> In the new API you can no longer select txq entries by hardware queue.
> When using multiple WMM queues, this could lead to station entries being
> requeued unnecessarily (because there is no room in the hw queue for the
> txq entry that ieee80211_next_txq happens to return).

Yeah, there's some tension between enforcing fairness (which is a per
station thing) and the WMM queueing stuff (which gives priority based on
WMM levels and ignores stations). There are basically two ways to
resolve this: Prioritising fairness or prioritising WMM levels. In the
former case, we first select which station to transmit to, and then
select the highest WMM priority level queued *for that station* (the
last part of this is missing from the code as it is now). In the latter
case, we keep scheduling per-WMM, then enforce fairness within that.

The former case has the potential to lead to starved hardware queues,
while the latter leads to unfairness. We had a bit of discussion of
which is better at netdev, but did not resolve it. Personally, I think
prioritising fairness is better, but I'm willing to be convinced
otherwise by data :). So my plan is to implement that fully and try it
out, then evaluate based on actual experiments...

> Since ieee80211_next_txq also refills the airtime fairness quantum, this
> might lead to some minor fairness issues.

I'm planning to change the way the scheduler works anyway, so this issue
should go away. Haven't had time to do that yet, unfortunately.

> In ath9k the code used to have a loop that goes through all pending txq
> entries until it has filled the hw queues again. You replaced that with
> some calls to ath_txq_schedule which now only considers one single txq.
> There are several reasons why this queue could potentially not be serviced:
> - ieee80211_tx_dequeue returned no frame
> - frame does not fit within BA window
> - txq was for another queue which is already filled
> Depending on the exact circumstances with enough stations this might
> lead to hardware queues getting starved.

Well, that loop was already removed when I implemented the in-driver
fairness scheduler. We can't really avoid those cases entirely if we
want to enforce fairness (the BAW case in particular; if the only
eligible station from an airtime PoW has a full BAW, you have to
throttle and can potentially starve hwqs). However, don't think this
happens much in practice (or we would have seen performance regressions
by now).

The 'txq was for another queue' case is new with this patch, but that
goes back to the WMM/fairness tention above.

> In ath10k the issues are different. You left a loop to service queues in
> place, and if I'm reading it correctly, you could be facing an infinite
> loop here:
> Let's assume that ath10k_mac_tx_push_pending gets called and there are
> multiple txqs pending.
> The first txq has 16 frames pending, gets serviced, requeued.
> Second txq has lots of frames pending, 16 frames are pushed out, the txq
> is requeued.
> Back to the first one, ath10k_mac_tx_push_txq returns -ENOENT, so no
> requeue.
> Back to the second one, hardware queues are filled,
> ath10k_mac_tx_can_push returns false, so ret stays 0, txq gets requeued.
> By now first == txq can never happen anymore because the first txq is
> not scheduled anymore.
> Seems like an infinite loop to me.

Hmm, you may be right here. I don't have the hardware to test this on
ath10k :/

> I think dealing with these corner cases will be easier if we support
> filtering by queue in ieee80211_next_txq, so I will send a patch for
> that.

Not necessarily opposed to a flag (or however you end up implementing
this). We may have to ignore it if we want to prioritise fairness, as
noted above. However, having the flag could potentially make t

[PATCH 1/2] mt76: fix possible NULL pointer dereferencing in mt76x2_ampdu_action()

2017-12-14 Thread Lorenzo Bianconi
Initialize mt76_txq pointer after ieee80211_txq pointer check.
Remove space after the pointer cast

Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
index 2cef48edb275..33469e32567b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
@@ -450,13 +450,15 @@ mt76x2_ampdu_action(struct ieee80211_hw *hw, struct 
ieee80211_vif *vif,
struct mt76x2_dev *dev = hw->priv;
struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv;
struct ieee80211_txq *txq = sta->txq[params->tid];
-   struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
u16 tid = params->tid;
u16 *ssn = ¶ms->ssn;
+   struct mt76_txq *mtxq;
 
if (!txq)
return -EINVAL;
 
+   mtxq = (struct mt76_txq *)txq->drv_priv;
+
switch (action) {
case IEEE80211_AMPDU_RX_START:
mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
-- 
2.13.6



[PATCH 0/2] Fix two possible NULL pointer dereferencing issues

2017-12-14 Thread Lorenzo Bianconi
Lorenzo Bianconi (2):
  mt76: fix possible NULL pointer dereferencing in mt76x2_ampdu_action()
  mt76: fix possible NULL pointer dereferencing in
mt76x2_mac_write_txwi()

 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c  | 2 +-
 drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

-- 
2.13.6



[PATCH 2/2] mt76: fix possible NULL pointer dereferencing in mt76x2_mac_write_txwi()

2017-12-14 Thread Lorenzo Bianconi
Verify wcid is not NULL before dereferencing the pointer to initialize
txwi rate/power info

Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index 39fc1d7b65ce..a1f695e9b51c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -185,7 +185,7 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct 
mt76x2_txwi *txwi,
txwi->pktid = 1;
 
spin_lock_bh(&dev->mt76.lock);
-   if (rate->idx < 0 || !rate->count) {
+   if (wcid && (rate->idx < 0 || !rate->count)) {
txwi->rate = wcid->tx_rate;
max_txpwr_adj = wcid->max_txpwr_adj;
nss = wcid->tx_rate_nss;
-- 
2.13.6



Re: [PATCH v3 1/3] mac80211: Add TXQ scheduling API

2017-12-14 Thread Felix Fietkau
On 2017-10-31 12:27, Toke Høiland-Jørgensen wrote:
> This adds an API to mac80211 to handle scheduling of TXQs and changes the
> interface between driver and mac80211 for TXQ handling as follows:
> 
> - The wake_tx_queue callback interface no longer includes the TXQ. Instead,
>   the driver is expected to retrieve that from ieee80211_next_txq()
> 
> - Two new mac80211 functions are added: ieee80211_next_txq() and
>   ieee80211_schedule_txq(). The former returns the next TXQ that should be
>   scheduled, and is how the driver gets a queue to pull packets from. The
>   latter is called internally by mac80211 to start scheduling a queue, and
>   the driver is supposed to call it to re-schedule the TXQ after it is
>   finished pulling packets from it (unless the queue emptied).
> 
> The ath9k and ath10k drivers are changed to use the new API.
> 
> Signed-off-by: Toke Høiland-Jørgensen 
Sorry that I didn't have time to give this a thorough review earlier,
since I was pretty busy with other projects. Now that I'm working on
porting mt76 to this new API, some things in this patch strike me as
rather odd, and there might be some bugs and nasty limitations here:

In the new API you can no longer select txq entries by hardware queue.
When using multiple WMM queues, this could lead to station entries being
requeued unnecessarily (because there is no room in the hw queue for the
txq entry that ieee80211_next_txq happens to return).
Since ieee80211_next_txq also refills the airtime fairness quantum, this
might lead to some minor fairness issues.

In ath9k the code used to have a loop that goes through all pending txq
entries until it has filled the hw queues again. You replaced that with
some calls to ath_txq_schedule which now only considers one single txq.
There are several reasons why this queue could potentially not be serviced:
- ieee80211_tx_dequeue returned no frame
- frame does not fit within BA window
- txq was for another queue which is already filled
Depending on the exact circumstances with enough stations this might
lead to hardware queues getting starved.

In ath10k the issues are different. You left a loop to service queues in
place, and if I'm reading it correctly, you could be facing an infinite
loop here:
Let's assume that ath10k_mac_tx_push_pending gets called and there are
multiple txqs pending.
The first txq has 16 frames pending, gets serviced, requeued.
Second txq has lots of frames pending, 16 frames are pushed out, the txq
is requeued.
Back to the first one, ath10k_mac_tx_push_txq returns -ENOENT, so no
requeue.
Back to the second one, hardware queues are filled,
ath10k_mac_tx_can_push returns false, so ret stays 0, txq gets requeued.
By now first == txq can never happen anymore because the first txq is
not scheduled anymore.
Seems like an infinite loop to me.

I think dealing with these corner cases will be easier if we support
filtering by queue in ieee80211_next_txq, so I will send a patch for that.

- Felix


[PATCH] mt76x2: eeprom: fix typo in mt76x2_get_power_info_5g()

2017-12-14 Thread Lorenzo Bianconi
Fix typo in 5GHz power vs channel eeprom parsing

Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
index 440b7e7d73a9..29dc52ef629d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
@@ -524,7 +524,7 @@ mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct 
mt76x2_tx_power_info *t,
 
if (channel >= 192)
delta_idx = 4;
-   else if (channel >= 484)
+   else if (channel >= 184)
delta_idx = 3;
else if (channel < 44)
delta_idx = 3;
-- 
2.13.6



Re: [PATCH] mt76: fix memcpy to potential null pointer on failed allocation

2017-12-14 Thread Felix Fietkau
On 2017-12-14 11:13, Colin King wrote:
> From: Colin Ian King 
> 
> Currently if the allocation of skb fails and returns NULL then the
> call to skb_put will cause a null pointer dereference. Fix this by
> checking for a null skb and returning NULL.  Note that calls to
> function mt76x2_mcu_msg_alloc don't directly check the null return
> but instead pass the NULL pointer to mt76x2_mcu_msg_send which
> checks for the NULL and returns ENOMEM in this case.
> 
> Detected by CoverityScan, CID#1462624 ("Dereference null return value")
> 
> Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
> Signed-off-by: Colin Ian King 
Acked-by: Felix Fietkau 


[PATCH] mt76: fix memcpy to potential null pointer on failed allocation

2017-12-14 Thread Colin King
From: Colin Ian King 

Currently if the allocation of skb fails and returns NULL then the
call to skb_put will cause a null pointer dereference. Fix this by
checking for a null skb and returning NULL.  Note that calls to
function mt76x2_mcu_msg_alloc don't directly check the null return
but instead pass the NULL pointer to mt76x2_mcu_msg_send which
checks for the NULL and returns ENOMEM in this case.

Detected by CoverityScan, CID#1462624 ("Dereference null return value")

Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
Signed-off-by: Colin Ian King 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c
index d45737ee1412..15820b11f9db 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c
@@ -45,6 +45,8 @@ static struct sk_buff *mt76x2_mcu_msg_alloc(const void *data, 
int len)
struct sk_buff *skb;
 
skb = alloc_skb(len, GFP_KERNEL);
+   if (!skb)
+   return NULL;
memcpy(skb_put(skb, len), data, len);
 
return skb;
-- 
2.14.1



Re: BCM4356 does not initalize after firmware update

2017-12-14 Thread Arend van Spriel

On 12/13/2017 5:12 PM, Stanislaw Gruszka wrote:

Hi

After firmware update, this device:

[0280]: Broadcom Limited BCM4356 802.11ac Wireless Network Adapter [14e4:43ec] 
(rev 02)

no longer initialize. With the firmware update I have:

[  272.063814] brcmfmac: brcmf_fw_map_chip_to_name: using 
brcm/brcmfmac4356-pcie.bin for chip 0x004356(17238) rev 0x02
[  272.529582] brcmfmac :03:00.0: irq 31 for MSI/MSI-X
[  274.529476] brcmfmac: brcmf_msgbuf_query_dcmd: Timeout on response for query 
command
[  274.537356] brcmfmac: brcmf_c_preinit_dcmds: Retreiving cur_etheraddr 
failed, -5
[  274.544881] brcmfmac: brcmf_bus_started: failed: -5
[  274.549854] brcmfmac: brcmf_pcie_attach_bus: dongle is not responding

and no wlan device is created. With older version of the firmware I have:

[   10.716878] brcmfmac: brcmf_fw_map_chip_to_name: using 
brcm/brcmfmac4356-pcie.bin for chip 0x004356(17238) rev 0x02
[   11.312875] brcmfmac :03:00.0: irq 31 for MSI/MSI-X
[   11.314735] brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Oct 22 
2015 06:16:41 version 7.35.180.119 (r594535) FWID 01-1a5c4016
[   16.598211] brcmfmac: brcmf_p2p_create_p2pdev: set p2p_disc error
[   16.604416] brcmfmac: brcmf_cfg80211_add_iface: add iface p2p-dev-wlp3s0 
type 10 failed: err=-16

and despite P2P errors, device works correctly.


The cur_etheraddr is the first piece of info we try to get from the 
firmware. Could you build the driver with CONFIG_BRCMDBG and load the 
module with 'debug=0x181416'.


Regards,
Arend


[bug report] mt76: add driver code for MT76x2e

2017-12-14 Thread Dan Carpenter
Hello Felix Fietkau,

This is a semi-automatic email about new static checker warnings.

The patch 7bc04215a66b: "mt76: add driver code for MT76x2e" from Nov 
21, 2017, leads to the following Smatch complaint:

drivers/net/wireless/mediatek/mt76/mt76x2_main.c:457 mt76x2_ampdu_action()
warn: variable dereferenced before check 'txq' (see line 453)

drivers/net/wireless/mediatek/mt76/mt76x2_main.c
   452  struct ieee80211_txq *txq = sta->txq[params->tid];
   453  struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
^
Unchecked dereference.  Also the cast is has a checkpatch a space issue.
No space after the cast, because casting is a high precedence operation.

   454  u16 tid = params->tid;
   455  u16 *ssn = ¶ms->ssn;
   456  
   457  if (!txq)
 ^^^
Check is too late.

   458  return -EINVAL;
   459  

regards,
dan carpenter


[bug report] mt76: add driver code for MT76x2e

2017-12-14 Thread Dan Carpenter
Hello Felix Fietkau,

This is a semi-automatic email about new static checker warnings.

The patch 7bc04215a66b: "mt76: add driver code for MT76x2e" from Nov 
21, 2017, leads to the following Smatch complaint:

drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:189 mt76x2_mac_write_txwi()
error: we previously assumed 'wcid' could be null (see line 180)

drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
   179  
   180  if (wcid)

Check for NULL

   181  txwi->wcid = wcid->idx;
   182  else
   183  txwi->wcid = 0xff;
   184  
   185  txwi->pktid = 1;
   186  
   187  spin_lock_bh(&dev->mt76.lock);
   188  if (rate->idx < 0 || !rate->count) {
   189  txwi->rate = wcid->tx_rate;
 ^
Unchecked dereference

   190  max_txpwr_adj = wcid->max_txpwr_adj;
   191  nss = wcid->tx_rate_nss;

regards,
dan carpenter