[PATCH] mac80211: fix deauth TX when we disconnect

2018-12-03 Thread Emmanuel Grumbach
The iTXQs stop/wake queue mechanism involves a whole bunch
of locks and this is probably why the call to
ieee80211_wake_txqs is deferred to a tasklet when called from
__ieee80211_wake_queue.

Another advantage of that is that ieee80211_wake_txqs might
call the wake_tx_queue() callback and then the driver may
call mac80211 which will call it back in the same context.

The bug I saw is that when we send a deauth frame as a
station we do:

flush(drop=1)
tx deauth
flush(drop=0)

While we flush we stop the queues and wake them up
immediately after we finished flushing. The problem here is
that the tasklet that de-facto enables the queue may not have
run until we send the deauth. Then the deauth frame is sent
to the driver (which is surprising by itself), but the driver
won't get anything useful from ieee80211_tx_dequeue because
the queue is stopped (or more precisely because
vif->txqs_stopped[0] is true).
Then the deauth is not sent. Later on, the tasklet will run,
but that'll be too late. We'll already have removed all the
vif etc...

Fix this by calling ieee80211_wake_txqs synchronously if we
are not waking up the queues from the driver (we check the
reason to determine that). This makes the code really
convoluted because we may call ieee80211_wake_txqs from
__ieee80211_wake_queue. The latter assumes that
queue_stop_reason_lock has been taken by the caller and
ieee80211_wake_txqs may release the lock to send the frames.

Signed-off-by: Emmanuel Grumbach 
---
 net/mac80211/util.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index bec4243..40ea41a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -299,16 +299,17 @@ static void __ieee80211_wake_txqs(struct 
ieee80211_sub_if_data *sdata, int ac)
spin_unlock_bh(>lock);
 }
 
-void ieee80211_wake_txqs(unsigned long data)
+static void
+__releases(>queue_stop_reason_lock)
+__acquires(>queue_stop_reason_lock)
+_ieee80211_wake_txqs(struct ieee80211_local *local,
+unsigned long *flags)
 {
-   struct ieee80211_local *local = (struct ieee80211_local *)data;
struct ieee80211_sub_if_data *sdata;
int n_acs = IEEE80211_NUM_ACS;
-   unsigned long flags;
int i;
 
rcu_read_lock();
-   spin_lock_irqsave(>queue_stop_reason_lock, flags);
 
if (local->hw.queues < IEEE80211_NUM_ACS)
n_acs = 1;
@@ -317,7 +318,7 @@ void ieee80211_wake_txqs(unsigned long data)
if (local->queue_stop_reasons[i])
continue;
 
-   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
+   spin_unlock_irqrestore(>queue_stop_reason_lock, *flags);
list_for_each_entry_rcu(sdata, >interfaces, list) {
int ac;
 
@@ -329,13 +330,22 @@ void ieee80211_wake_txqs(unsigned long data)
__ieee80211_wake_txqs(sdata, ac);
}
}
-   spin_lock_irqsave(>queue_stop_reason_lock, flags);
+   spin_lock_irqsave(>queue_stop_reason_lock, *flags);
}
 
-   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
rcu_read_unlock();
 }
 
+void ieee80211_wake_txqs(unsigned long data)
+{
+   struct ieee80211_local *local = (struct ieee80211_local *)data;
+   unsigned long flags;
+
+   spin_lock_irqsave(>queue_stop_reason_lock, flags);
+   _ieee80211_wake_txqs(local, );
+   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
+}
+
 void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
 {
struct ieee80211_sub_if_data *sdata;
@@ -371,7 +381,8 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local 
*local, int queue)
 
 static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
   enum queue_stop_reason reason,
-  bool refcounted)
+  bool refcounted,
+  unsigned long *flags)
 {
struct ieee80211_local *local = hw_to_local(hw);
 
@@ -405,8 +416,19 @@ static void __ieee80211_wake_queue(struct ieee80211_hw 
*hw, int queue,
} else
tasklet_schedule(>tx_pending_tasklet);
 
-   if (local->ops->wake_tx_queue)
-   tasklet_schedule(>wake_txqs_tasklet);
+   /*
+* Calling _ieee80211_wake_txqs here can be a problem because it may
+* release queue_stop_reason_lock which has been taken by
+* __ieee80211_wake_queue's caller. It is certainly not very nice to
+* release someone's lock, but it is fine because all the callers of
+* __ieee80211_wake_queue call it right before releasing the lock.
+*/
+   if (local->ops->wake_tx_queue) 

[PATCH] mac80211: ignore NullFunc frames in the duplicate detection

2018-12-03 Thread Emmanuel Grumbach
NullFunc packets should never be duplicate just like
QoS-NullFunc packets.

We saw a client that enters / exits power save with
NullFunc frames (and not with QoS-NullFunc) despite the
fact that the association supports HT.
This specific client also re-uses a non-zero sequence number
for different NullFunc frames.
At some point, the client had to send a retransmission of
the NullFunc frame and we dropped it, leading to a
misalignment in the power save state.
Fix this by never consider a NullFunc frame as duplicate,
just like we do for QoS NullFunc frames.

This fixes https://bugzilla.kernel.org/show_bug.cgi?id=201449

CC: 
Signed-off-by: Emmanuel Grumbach 
---
 net/mac80211/rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3bd3b57..2c6515a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1403,6 +1403,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx)
return RX_CONTINUE;
 
if (ieee80211_is_ctl(hdr->frame_control) ||
+   ieee80211_is_nullfunc(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1))
return RX_CONTINUE;
-- 
2.7.4



Re: Intel 8260 Firmware Init Failure

2018-11-17 Thread Emmanuel Grumbach
>
> What can I do about this? My wireless card is unusable. Seems to be a
> spontaneous failure. This is the output of dmesg | grep iwlwifi:
>
> [7.206387] iwlwifi :02:00.0: enabling device ( -> 0002)
> [7.215066] iwlwifi :02:00.0: loaded firmware version
> 36.7596afd4.0 op_mode iwlmvm
> [7.686950] iwlwifi :02:00.0: Detected Intel(R) Dual Band
> Wireless AC 8260, REV=0x208
> [7.769839] iwlwifi :02:00.0: base HW address: 14:ab:c5:7c:5e:a2
> [7.770427] iwlwifi :02:00.0: Microcode SW error detected.
> Restarting 0x200.
> [7.770555] iwlwifi :02:00.0: Start IWL Error Log Dump:
> [7.770557] iwlwifi :02:00.0: Status: 0x0100, count: 6
> [7.770559] iwlwifi :02:00.0: Loaded firmware version: 36.7596afd4.0
> [7.770561] iwlwifi :02:00.0: 0x1392 | ADVANCED_SYSASSERT
> [7.770562] iwlwifi :02:00.0: 0x02F2 | trm_hw_status0
> [7.770564] iwlwifi :02:00.0: 0x | trm_hw_status1
> [7.770565] iwlwifi :02:00.0: 0x000124BE | branchlink2
> [7.770566] iwlwifi :02:00.0: 0x0001C1E2 | interruptlink1
> [7.770568] iwlwifi :02:00.0: 0x | interruptlink2
> [7.770569] iwlwifi :02:00.0: 0x010B | data1
> [7.770570] iwlwifi :02:00.0: 0x | data2
> [7.770572] iwlwifi :02:00.0: 0xDEADBEEF | data3

Report of bug on bugzilla.kernel.org as explained here:
https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi/debugging

>From what I see this is a bug in calibrations. Not fun.

>
> This happened once before, about a year ago. It resolved itself when I
> tried installing Windows 10 and running an update. Now when I try a
> clean install of Windows 10 it bluescreens on startup with probable
> cause Netwtw06.sys.
>

Even less fun. When you want to compare this to any other problem you have seen,
please check the ASSERT number. In this case, you have ASSERT 1392.


Re: Intel 8265 iwlwifi broken recent linux-firmware

2018-11-06 Thread Emmanuel Grumbach
On Wed, Nov 7, 2018 at 7:36 AM Petri Lehtinen  wrote:
>
> Loading iwlwifi produces the following messages to dmesg. Trying to
> bring the wifi interface up also fails.
>
> [Tue Oct 23 07:17:12 2018] iwlwifi :3a:00.0: loaded firmware version 
> 36.7596afd4.0 op_mode iwlmvm
> [Tue Oct 23 07:17:12 2018] iwlwifi :3a:00.0: Detected Intel(R) Dual Band 
> Wireless AC 8265, REV=0x230
> [Tue Oct 23 07:17:13 2018] iwlwifi :3a:00.0: SecBoot CPU1 Status: 
> 0x3040001, CPU2 Status: 0x0
> [Tue Oct 23 07:17:13 2018] iwlwifi :3a:00.0: Failed to start INIT ucode: 
> -110
> [Tue Oct 23 07:17:13 2018] iwlwifi :3a:00.0: Failed to run INIT ucode: 
> -110
>
> I'm on Arch Linux, and linux-firmware is built from commit d877533.
> With older firmware (commit f1b95fe), it works with this in dmesg
> output:
>
> [Tue Oct 23 07:28:51 2018] iwlwifi :3a:00.0: enabling device ( -> 
> 0002)
> [Tue Oct 23 07:28:51 2018] iwlwifi :3a:00.0: loaded firmware version 
> 36.e91976c0.0 op_mode iwlmvm
> [Tue Oct 23 07:28:51 2018] iwlwifi :3a:00.0: Detected Intel(R) Dual Band 
> Wireless AC 8265, REV=0x230
> [Tue Oct 23 07:28:51 2018] iwlwifi :3a:00.0: base HW address: 
> 00:28:f8:87:a2:e9
>

I checked the diff between e91976c0 and 7596afd4 and it is very very small.
Is your machine dual boot?
A few users have reported a race between BT firmware load and Wifi
firmware load. They also reported that booting in Windows, and then
shutting down in Windows helps to boot Linux properly.
If the above is not applicable, please open a bug in
bugzilla.kernel.org and add linuxw...@intel.com to the bug.
Thank you.


Re: [RFC] mac80211: fix deauth TX when we disconnect

2018-11-06 Thread Emmanuel Grumbach
On Tue, Nov 6, 2018 at 2:32 PM Emmanuel Grumbach
 wrote:
>
> The iTXQs stop/wake queue mechanism involves a whole bunch
> of locks and this is probably why the call to
> ieee80211_wake_txqs is deferred to a tasklet when called from
> __ieee80211_wake_queue.
>
> Another advantage of that is that ieee80211_wake_txqs might
> call the wake_tx_queue() callback and then the driver may
> call mac80211 which will call it back in the same context.
>
> The bug I saw is that when we send a deauth frame as a
> station we do:
>
> flush(drop=1)
> tx deauth
> flush(drop=0)
>
> While we flush we stop the queues and wake them up
> immediately after we finished flushing. The problem here is
> that the tasklet that de-facto enables the queue may not have
> run until we send the deauth. Then the deauth frame is sent
> to the driver (which is surprising by itself), but the driver
> won't get anything useful from ieee80211_tx_dequeue because
> the queue is stopped (or more precisely because
> vif->txqs_stopped[0] is true).
> Then the deauth is not sent. Later on, the tasklet will run,
> but that'll be too late. We'll already have removed all the
> vif etc...
>
> There are 2 options I see here:
> 1) do what I did in this patch (which is pretty awful because
>of the if (lock) thing. If we wake up the queue because of
>a reason which is internal to mac80211, call
>ieee80211_wake_txqs synchronously since we know we are not
>coming from the driver.
> 2) we could set vif->txqs_stopped to false synchrously and do
>the rest of the job in a tasklet. This would allow the code
>that sends the Tx to put the frame in the queue and the
>driver would actually get it.
>
> Maybe others have better ideas?
>
> Change-Id: I5d3bd20ec765becb91944741c35e35f6e3888981
> Cc: Manikanta Pubbisetty 
> Signed-off-by: Emmanuel Grumbach 
> ---
>  net/mac80211/util.c | 24 ++--
>  1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
> index c9cb00a..c731ddb 100644
> --- a/net/mac80211/util.c
> +++ b/net/mac80211/util.c
> @@ -299,16 +299,16 @@ out:
> spin_unlock_bh(>lock);
>  }
>
> -void ieee80211_wake_txqs(unsigned long data)
> +static void _ieee80211_wake_txqs(struct ieee80211_local *local, bool lock)
>  {
> -   struct ieee80211_local *local = (struct ieee80211_local *)data;
> struct ieee80211_sub_if_data *sdata;
> int n_acs = IEEE80211_NUM_ACS;
> unsigned long flags;
> int i;
>
> rcu_read_lock();
> -   spin_lock_irqsave(>queue_stop_reason_lock, flags);
> +   if (lock)
> +   spin_lock_irqsave(>queue_stop_reason_lock, flags);
>

This is buggy of course... If lock is false, then we'll call
spin_unlock_irqrestore
further down in the function, but flags won't be initialized.
I don't really know why we have this strange pattern of a
lock
  loop
unlock
  wake_tx_queue()
lock
unlock

If we want not to call wake_tx_queue with the lock taken, we can
prepare a bitmap of ACs
and then call wake_tx_queue() for all the ACs, bu then of course, we
may have races.
OTOH, we may have races here as well. Someone could change queue_stop_reasons
after we release the lock and before we call wake_tx_queue and because
of that, we'd end up
waking a queue that is supposed to be stopped.

> if (local->hw.queues < IEEE80211_NUM_ACS)
> n_acs = 1;
> @@ -332,10 +332,18 @@ void ieee80211_wake_txqs(unsigned long data)
> spin_lock_irqsave(>queue_stop_reason_lock, flags);
> }
>
> -   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
> +   if (lock)
> +   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
> rcu_read_unlock();
>  }
>
> +void ieee80211_wake_txqs(unsigned long data)
> +{
> +   struct ieee80211_local *local = (struct ieee80211_local *)data;
> +
> +   _ieee80211_wake_txqs(local, true);
> +}
> +
>  void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
>  {
> struct ieee80211_sub_if_data *sdata;
> @@ -405,8 +413,12 @@ static void __ieee80211_wake_queue(struct ieee80211_hw 
> *hw, int queue,
> } else
> tasklet_schedule(>tx_pending_tasklet);
>
> -   if (local->ops->wake_tx_queue)
> -   tasklet_schedule(>wake_txqs_tasklet);
> +   if (local->ops->wake_tx_queue) {
> +   if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER)
> +   tasklet_schedule(>wake_txqs_tasklet);
> +   else
> +   _ieee80211_wake_txqs(local, false);
> +   }
>  }
>
>  void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
> --
> 2.7.4
>


[RFC] mac80211: fix deauth TX when we disconnect

2018-11-06 Thread Emmanuel Grumbach
The iTXQs stop/wake queue mechanism involves a whole bunch
of locks and this is probably why the call to
ieee80211_wake_txqs is deferred to a tasklet when called from
__ieee80211_wake_queue.

Another advantage of that is that ieee80211_wake_txqs might
call the wake_tx_queue() callback and then the driver may
call mac80211 which will call it back in the same context.

The bug I saw is that when we send a deauth frame as a
station we do:

flush(drop=1)
tx deauth
flush(drop=0)

While we flush we stop the queues and wake them up
immediately after we finished flushing. The problem here is
that the tasklet that de-facto enables the queue may not have
run until we send the deauth. Then the deauth frame is sent
to the driver (which is surprising by itself), but the driver
won't get anything useful from ieee80211_tx_dequeue because
the queue is stopped (or more precisely because
vif->txqs_stopped[0] is true).
Then the deauth is not sent. Later on, the tasklet will run,
but that'll be too late. We'll already have removed all the
vif etc...

There are 2 options I see here:
1) do what I did in this patch (which is pretty awful because
   of the if (lock) thing. If we wake up the queue because of
   a reason which is internal to mac80211, call
   ieee80211_wake_txqs synchronously since we know we are not
   coming from the driver.
2) we could set vif->txqs_stopped to false synchrously and do
   the rest of the job in a tasklet. This would allow the code
   that sends the Tx to put the frame in the queue and the
   driver would actually get it.

Maybe others have better ideas?

Change-Id: I5d3bd20ec765becb91944741c35e35f6e3888981
Cc: Manikanta Pubbisetty 
Signed-off-by: Emmanuel Grumbach 
---
 net/mac80211/util.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index c9cb00a..c731ddb 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -299,16 +299,16 @@ out:
spin_unlock_bh(>lock);
 }
 
-void ieee80211_wake_txqs(unsigned long data)
+static void _ieee80211_wake_txqs(struct ieee80211_local *local, bool lock)
 {
-   struct ieee80211_local *local = (struct ieee80211_local *)data;
struct ieee80211_sub_if_data *sdata;
int n_acs = IEEE80211_NUM_ACS;
unsigned long flags;
int i;
 
rcu_read_lock();
-   spin_lock_irqsave(>queue_stop_reason_lock, flags);
+   if (lock)
+   spin_lock_irqsave(>queue_stop_reason_lock, flags);
 
if (local->hw.queues < IEEE80211_NUM_ACS)
n_acs = 1;
@@ -332,10 +332,18 @@ void ieee80211_wake_txqs(unsigned long data)
spin_lock_irqsave(>queue_stop_reason_lock, flags);
}
 
-   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
+   if (lock)
+   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
rcu_read_unlock();
 }
 
+void ieee80211_wake_txqs(unsigned long data)
+{
+   struct ieee80211_local *local = (struct ieee80211_local *)data;
+
+   _ieee80211_wake_txqs(local, true);
+}
+
 void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
 {
struct ieee80211_sub_if_data *sdata;
@@ -405,8 +413,12 @@ static void __ieee80211_wake_queue(struct ieee80211_hw 
*hw, int queue,
} else
tasklet_schedule(>tx_pending_tasklet);
 
-   if (local->ops->wake_tx_queue)
-   tasklet_schedule(>wake_txqs_tasklet);
+   if (local->ops->wake_tx_queue) {
+   if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER)
+   tasklet_schedule(>wake_txqs_tasklet);
+   else
+   _ieee80211_wake_txqs(local, false);
+   }
 }
 
 void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
-- 
2.7.4



[PATCH] iw: fix the beacon average signal parsing

2018-10-04 Thread Emmanuel Grumbach
NL80211_STA_INFO_BEACON_SIGNAL_AVG is parsed as a u8, but
it should be casted to a int8_t before being printed.

Change-Id: Ieb6fab3b803d8ea82819a450f07cc4b537d8de8b
Signed-off-by: Emmanuel Grumbach 
---
 station.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/station.c b/station.c
index 4885dc0..f4e0093 100644
--- a/station.c
+++ b/station.c
@@ -317,7 +317,7 @@ static int print_sta_handler(struct nl_msg *msg, void *arg)
 
if (sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG])
printf("\n\tbeacon signal avg:\t%d dBm",
-  nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]));
+  
(int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]));
if (sinfo[NL80211_STA_INFO_T_OFFSET])
printf("\n\tToffset:\t%llu us",
   (unsigned long 
long)nla_get_u64(sinfo[NL80211_STA_INFO_T_OFFSET]));
-- 
2.7.4



[PATCH] mac80211: don't update the PM state of a peer upon a multicast frame

2018-08-20 Thread Emmanuel Grumbach
I changed the way mac80211 updates the PM state of the peer.
I forgot that we could also have multicast frames from the
peer and that those frame should of course not change the
PM state of the peer: A peer goes to power save when it
needs to scan, but it won't send the broadcast Probe Request
with the PM bit set.

This made us mark the peer as awake when it wasn't and then
Intel's firmware would fail to transmit because the peer is
asleep according to its database. The driver warned about
this and it looked like this:

 WARNING: CPU: 0 PID: 184 at 
/usr/src/linux-4.16.14/drivers/net/wireless/intel/iwlwifi/mvm/tx.c:1369 
iwl_mvm_rx_tx_cmd+0x53b/0x860
 CPU: 0 PID: 184 Comm: irq/124-iwlwifi Not tainted 4.16.14 #1
 RIP: 0010:iwl_mvm_rx_tx_cmd+0x53b/0x860
 Call Trace:
  iwl_pcie_rx_handle+0x220/0x880
  iwl_pcie_irq_handler+0x6c9/0xa20
  ? irq_forced_thread_fn+0x60/0x60
  ? irq_thread_dtor+0x90/0x90

The relevant code that spits the WARNING is:

case TX_STATUS_FAIL_DEST_PS:
/* the FW should have stopped the queue and not
 * return this status
 */
WARN_ON(1);
info->flags |= IEEE80211_TX_STAT_TX_FILTERED;

This fixes https://bugzilla.kernel.org/show_bug.cgi?id=199967.

Fixes: 9fef65443388 ("mac80211: always update the PM state of a peer on MGMT / 
DATA frames")
Cc:#4.16+
Signed-off-by: Emmanuel Grumbach 
---
 net/mac80211/rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a16ba56..3cf6027 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1728,6 +1728,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 */
if (!ieee80211_hw_check(>local->hw, AP_LINK_PS) &&
!ieee80211_has_morefrags(hdr->frame_control) &&
+   !is_multicast_ether_addr(hdr->addr1) &&
(ieee80211_is_mgmt(hdr->frame_control) ||
 ieee80211_is_data(hdr->frame_control)) &&
!(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
-- 
2.7.4



[PATCH] iwlwifi: add more card IDs for 9000 series

2018-07-17 Thread Emmanuel Grumbach
Add new device IDs for the 9000 series.

Cc: sta...@vger.kernel.org [4.14+]
Signed-off-by: Emmanuel Grumbach 
---
Hi Kalle,

Luca is on vacation and customers need those device IDs.
Can you please apply this on wireless-drivers.git?

Thank you
---
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c   | 69 +
 drivers/net/wireless/intel/iwlwifi/iwl-config.h |  5 ++
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c   | 22 
 3 files changed, 96 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index e20c30b..c8ea63d 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -178,6 +178,17 @@ const struct iwl_cfg iwl9260_2ac_cfg = {
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
+const struct iwl_cfg iwl9260_killer_2ac_cfg = {
+   .name = "Killer (R) Wireless-AC 1550 Wireless Network Adapter 
(9260NGW)",
+   .fw_name_pre = IWL9260A_FW_PRE,
+   .fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
+   IWL_DEVICE_9000,
+   .ht_params = _ht_params,
+   .nvm_ver = IWL9000_NVM_VERSION,
+   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+};
+
 const struct iwl_cfg iwl9270_2ac_cfg = {
.name = "Intel(R) Dual Band Wireless AC 9270",
.fw_name_pre = IWL9260A_FW_PRE,
@@ -267,6 +278,34 @@ const struct iwl_cfg iwl9560_2ac_cfg_soc = {
.soc_latency = 5000,
 };
 
+const struct iwl_cfg iwl9560_killer_2ac_cfg_soc = {
+   .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter 
(9560NGW)",
+   .fw_name_pre = IWL9000A_FW_PRE,
+   .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+   .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+   IWL_DEVICE_9000,
+   .ht_params = _ht_params,
+   .nvm_ver = IWL9000_NVM_VERSION,
+   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+   .integrated = true,
+   .soc_latency = 5000,
+};
+
+const struct iwl_cfg iwl9560_killer_s_2ac_cfg_soc = {
+   .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter 
(9560NGW)",
+   .fw_name_pre = IWL9000A_FW_PRE,
+   .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+   .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+   IWL_DEVICE_9000,
+   .ht_params = _ht_params,
+   .nvm_ver = IWL9000_NVM_VERSION,
+   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+   .integrated = true,
+   .soc_latency = 5000,
+};
+
 const struct iwl_cfg iwl9460_2ac_cfg_shared_clk = {
.name = "Intel(R) Dual Band Wireless AC 9460",
.fw_name_pre = IWL9000A_FW_PRE,
@@ -327,6 +366,36 @@ const struct iwl_cfg iwl9560_2ac_cfg_shared_clk = {
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
 };
 
+const struct iwl_cfg iwl9560_killer_2ac_cfg_shared_clk = {
+   .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter 
(9560NGW)",
+   .fw_name_pre = IWL9000A_FW_PRE,
+   .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+   .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+   IWL_DEVICE_9000,
+   .ht_params = _ht_params,
+   .nvm_ver = IWL9000_NVM_VERSION,
+   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+   .integrated = true,
+   .soc_latency = 5000,
+   .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
+const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk = {
+   .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter 
(9560NGW)",
+   .fw_name_pre = IWL9000A_FW_PRE,
+   .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+   .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+   IWL_DEVICE_9000,
+   .ht_params = _ht_params,
+   .nvm_ver = IWL9000_NVM_VERSION,
+   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+   .integrated = true,
+   .soc_latency = 5000,
+   .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
 MODULE_FIRMWARE(IWL9000A_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL9000B_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL9000RFB_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index c503b26..84a8168 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -551,6 +551,7 @@ extern const struct iwl_cfg iwl8275_2ac_cfg;
 extern const struct iwl_cfg iwl4165_2ac_cfg;
 extern const struct iwl_cfg iwl9160_2ac_cfg;
 extern const struct iwl_cfg iwl9260_2ac_cfg;
+extern const struct iwl_cfg iwl9260_killer_2ac_cfg;
 extern const struct iwl_cfg iwl9270_2ac_cfg;
 ext

Re: Simultaneous 2.4 GHz WiFi and Bluetooth issue on Intel Dual Band Wireless-AC 8260

2018-04-20 Thread Emmanuel Grumbach
Hi,


On Thu, Apr 19, 2018 at 11:46 PM, Nathan Schulte  wrote:
> Hi!
>

[...]

>
> Specifically, when testing with Debian Sid, I am unable to connect to
> 2.4 GHz WiFi and Bluetooth at the same time.  I can successfully use
> both independently, and 5 GHz WiFi and Bluetooth works fine.  It's been
> a number of months, but I believe simultaneous 2.4 GHz and Bluetooth
> worked fine in the past, and has slowly degraded.
>
> Under Windows 10, the hardware appears to work without issue.
> Additionally, I believe I managed to warm-reboot from Windows 10 to
> Linux (with Bluetooth connected), and was able to continue using the
> same 2.4 GHz WiFi and Bluetooth audio sink without issue.

This was reported in the past. Please make sure you have the latest BT
firmware files.
Ubuntu may not be shipping the newest BT firmware files. You can find them here:

https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git

Specifically, I can see that the BT firmware files were updated not long ago:
https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/commit/?id=9cb49be0eecf1de2c020e9de235a4fb5fd6665d7

Then you'll need a cold reboot.

>
> When blueman-manager isn't hanging (it tends to do that a lot in this
> situation), I am sometimes able to connect to 2.4 GHz WiFi and Bluetooth
> device for a short while before the Bluetooth stack disconnects the
> device.  Usually this requires removing and re-pairing the device.

Regardless of the BT firmware version thing which is a pure Intel
problem, I have heard
about problems in the BT stack itself but I can't help about this.


Re: iwlwifi 4.18rc1 SYNC TIME_QUOTA_CMD with fw 31

2018-04-18 Thread Emmanuel Grumbach
On Wed, Apr 18, 2018 at 5:47 AM, Scott Register  wrote:
>
> Hello,
>
> After upgrading to 4.18rc1 iwlwifi is printing a FW error. There was a
> previous thread with a similar
> issue but they seemed to resolve it with a ucode update. I think I'm
> running a newer FW and
> am still having an issue. 4.13 works--I haven't gone any higher so far.

Please download the firmware from
https://git.kernel.org/cgit/linux/kernel/git/iwlwifi/linux-firmware.git/plain/iwlwifi-8265-36.ucode
This should fix your problem.

>
> iwlwifi :02:00.0: Microcode SW error detected.  Restarting 0x200.
> iwlwifi :02:00.0: Start IWL Error Log Dump:
> iwlwifi :02:00.0: Status: 0x0100, count: 6
> iwlwifi :02:00.0: Loaded firmware version: 31.560484.0
> iwlwifi :02:00.0: 0x0038 | BAD_COMMAND
> iwlwifi :02:00.0: 0x00A002F1 | trm_hw_status0
> iwlwifi :02:00.0: 0x | trm_hw_status1
> iwlwifi :02:00.0: 0x0002495C | branchlink2
> iwlwifi :02:00.0: 0x0003962E | interruptlink1
> iwlwifi :02:00.0: 0x | interruptlink2
> iwlwifi :02:00.0: 0x | data1
> iwlwifi :02:00.0: 0x0032 | data2
> iwlwifi :02:00.0: 0x0032 | data3
> iwlwifi :02:00.0: 0x003B15C2 | beacon time
> iwlwifi :02:00.0: 0x0004EA3C | tsf low
> iwlwifi :02:00.0: 0x | tsf hi
> iwlwifi :02:00.0: 0x | time gp1
> iwlwifi :02:00.0: 0x0004EA3D | time gp2
> iwlwifi :02:00.0: 0x0001 | uCode revision type
> iwlwifi :02:00.0: 0x001F | uCode version major
> iwlwifi :02:00.0: 0x00088D64 | uCode version minor
> iwlwifi :02:00.0: 0x0230 | hw version
> iwlwifi :02:00.0: 0x00489000 | board version
> iwlwifi :02:00.0: 0x | hcmd
> iwlwifi :02:00.0: 0x00122080 | isr0
> iwlwifi :02:00.0: 0x | isr1
> iwlwifi :02:00.0: 0x28201802 | isr2
> iwlwifi :02:00.0: 0x404001C0 | isr3
> iwlwifi :02:00.0: 0x | isr4
> iwlwifi :02:00.0: 0x802F0051 | last cmd Id
> iwlwifi :02:00.0: 0x | wait_event
> iwlwifi :02:00.0: 0x277E | l2p_control
> iwlwifi :02:00.0: 0x0820 | l2p_duration
> iwlwifi :02:00.0: 0x | l2p_mhvalid
> iwlwifi :02:00.0: 0x | l2p_addr_match
> iwlwifi :02:00.0: 0x000D | lmpm_pmg_sel
> iwlwifi :02:00.0: 0x13091828 | timestamp
> iwlwifi :02:00.0: 0x2838 | flow_handler
> iwlwifi :02:00.0: Start IWL Error Log Dump:
> iwlwifi :02:00.0: Status: 0x0100, count: 7
> iwlwifi :02:00.0: 0x0034 | NMI_INTERRUPT_WDG
> iwlwifi :02:00.0: 0x | umac branchlink1
> iwlwifi :02:00.0: 0xC0086950 | umac branchlink2
> iwlwifi :02:00.0: 0xC00842BC | umac interruptlink1
> iwlwifi :02:00.0: 0xC00840CC | umac interruptlink2
> iwlwifi :02:00.0: 0x0400 | umac data1
> iwlwifi :02:00.0: 0xC00840CC | umac data2
> iwlwifi :02:00.0: 0xDEADBEEF | umac data3
> iwlwifi :02:00.0: 0x001F | umac major
> iwlwifi :02:00.0: 0x00088D64 | umac minor
> iwlwifi :02:00.0: 0xC08861DC | frame pointer
> iwlwifi :02:00.0: 0xC08861DC | stack pointer
> iwlwifi :02:00.0: 0x | last host cmd
> iwlwifi :02:00.0: 0x4008 | isr status reg
> ieee80211 phy0: Hardware restart was requested
> ieee80211 phy0: Hardware restart was requested
> iwlwifi :02:00.0: FW Error notification: type 0x cmd_id 0x34
> iwlwifi :02:00.0: FW Error notification: seq 0x0070 service 0x0034
> iwlwifi :02:00.0: FW Error notification: timestamp 0xD559
> iwlwifi :02:00.0: FW error in SYNC CMD TIME_QUOTA_CMD
> CPU: 7 PID: 83 Comm: kworker/7:1 Tainted: GW
> 4.17.0-041700rc1-generic #201804152230
> Hardware name: LENOVO 20KHCTO1WW/20KHCTO1WW, BIOS N23ET37W (1.12 ) 02/27/2018
>
> ethtool & lspci:
> driver: iwlwifi
> version: 4.17.0-041700rc1-generic
> firmware-version: 31.560484.0
> expansion-rom-version:
> bus-info: :02:00.0
> supports-statistics: yes
> supports-test: no
> supports-eeprom-access: no
> supports-register-dump: no
> supports-priv-flags: no
> 02:00.0 Network controller: Intel Corporation Wireless 8265 / 8275 (rev 78)
>
> Any ideas?
>
> Cheers,
> Scott


[PATCH] mac80211: don't WARN on bad WMM parameters from buggy APs

2018-03-26 Thread Emmanuel Grumbach
Apparently, some APs are buggy enough to send a zeroed
WMM IE. Don't WARN on this since this is not caused by a bug
on the client's system.

This aligns the condition of the WARNING in drv_conf_tx
with the validity check in ieee80211_sta_wmm_params.
We will now pick the default values whenever we get
a zeroed WMM IE.

This has been reported here:
https://bugzilla.kernel.org/show_bug.cgi?id=199161

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 net/mac80211/mlme.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 39b660b9a908..a6b628964b84 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1785,7 +1785,8 @@ static bool ieee80211_sta_wmm_params(struct 
ieee80211_local *local,
params[ac].acm = acm;
params[ac].uapsd = uapsd;
 
-   if (params[ac].cw_min > params[ac].cw_max) {
+   if (params->cw_min == 0 ||
+   params[ac].cw_min > params[ac].cw_max) {
sdata_info(sdata,
   "AP has invalid WMM params (CWmin/max=%d/%d 
for ACI %d), using defaults\n",
   params[ac].cw_min, params[ac].cw_max, aci);
-- 
2.14.3



Re: A few questions about iwlwifi and its rate control mechanism

2018-01-18 Thread Emmanuel Grumbach
On Thu, Jan 18, 2018 at 12:54 PM, Tambet Arak  wrote:
> I see. I might try playing around with hacking iwl-agn-rs, in that case.
>
>> What do you mean by 'drop'. Disassociated? Or associated but no traffic?
>> Association state can be checked with iw  link
>
> Sorry, that was ambiguous. I meant that the rate is decreased to e.g. MCS3-5.
>

Oh - that can happen because of lower quality radio conditions.


Re: A few questions about iwlwifi and its rate control mechanism

2018-01-18 Thread Emmanuel Grumbach
Hi,

On Thu, Jan 18, 2018 at 11:09 AM, Tambet Arak  wrote:
> Hi all,
>

[snip]

>
> In any case, I was looking into how to optimally tune wireless
> reception at work, since the APs are aging and only support up to MCS7
> (65 Mb/s), so any improvements would help. I'm using a HP laptop with
> a Intel Centrino Advanced-N 6235, driven by iwlwifi / iwldvm (vanilla
> Linux 4.14.8). I noticed that `iw dev wlo1 station dump` generally
> reports a 58.5-65 Mb/s rx bitrate, but when the connection is taxed
> (e.g. downloading a file), it drops.

What do you mean by 'drop'. Disassociated? Or associated but no traffic?
Association state can be checked with iw  link

>
> Since the only other OS on my machine is Windows, I tested by
> downloading a large file there and generally the average throughput
> was slightly higher. I'm not a Windows user, so I don't have a clue if
> `netsh show interfaces` reports a correct effective bit rate, but it
> was always fixed to 65 Mb/s in my tests.
>
> This led me to digging around in iwlwifi. It seems that iwlwifi
> registers its own rate control algorithm (iwl-agn-rs) with the
> mac80211 subsystem and this is hardcoded.
>
> Hence a few questions:
>
> - Why does iwlwifi have / need its own rc algorithm, instead of using 
> minstrel?

Because Intel devices' firmware works differently from atheros for
which minstrel was designed.
This is one of the main reasons.

> - It seems that iwl-agn-rs is not configurable by the end user. Would
> there be any interest in development for iwl-agn-rs configurability,
> e.g. being less / more conservative about lowering rates? I'm mostly
> interested in rx performance - I'm making the assumption here that rx
> rates are negotiated with the AP (as opposed to being forced).

Not really. iwl-agn-rs is very old and serves EOL'ed devices. Newer
devices have a algorithm that is not very different, but it was more
tested.
It shouldn't be too hard to forbid high rates though. You can just put
some limits in the existing code if you want.

> - Is there any documentation regarding iwlwifi or its rc algorithm
> implementation? If so, I would kindly appreciate pointers.

Well... System requirements are typically confidential, but you can
always dig in the code.


Re: Poor performance on 5G network with Intel 9000 series cards

2018-01-09 Thread Emmanuel Grumbach
On Mon, Jan 8, 2018 at 8:34 AM, AceLan Kao  wrote:
>
> Hi all,
>
> Forgot to append the device info, here it is.
>
> 02:00.0 Network controller [0280]: Intel Corporation Device [8086:2526] (rev 
> 29)
> Subsystem: Intel Corporation Device [8086:4010]
>
> Best regards,
> AceLan Kao.
>
> 2018-01-08 14:25 GMT+08:00 AceLan Kao :
> > Hi all,
> >
> > We found that Intel 9000 series wifi cards have tx performance issue
> > on 5G network.
> > Here are the test result.
> >
> > Client(10.101.46.25) is the platform with 9260 wifi card on 5G
> > network, and server(10.101.46.219) is another machine with ethernet
> > network.
> >

I think this matches this bug:
https://bugzilla.kernel.org/show_bug.cgi?id=198351

> > kernel v4.15-rc5 with firmware API 33
> >
> > acelan@u-Kabylake-Client-platform ~ % iperf -c 10.101.46.219 -er
> > 
> > Server listening on TCP port 5001 with pid 2248
> > Read buffer size: 1.44 KByte
> > TCP window size: 85.3 KByte (default)
> > 
> > 
> > Client connecting to 10.101.46.219, TCP port 5001 with pid 2248
> > Write buffer size: 128 KByte
> > TCP window size: 85.0 KByte (default)
> > 
> > [ 5] local 10.101.46.25 port 54308 connected with 10.101.46.219 port 5001
> > [ ID] Interval Transfer Bandwidth Write/Err Rtry Cwnd/RTT
> > [ 5] 0.00-11.06 sec 7.75 MBytes 5.88 Mbits/sec 1/0 77 7K/165143 us
> > [ 4] local 10.101.46.25 port 5001 connected with 10.101.46.219 port 38816
> > [ ID] Interval Transfer Bandwidth Reads Dist(bin=0.2K)
> > [ 4] 0.00-10.31 sec 77.0 MBytes 62.7 Mbits/sec 55729
> > 49:23:176:59:1140:294:168:53820
> >
> > 
> >
> > With firmware API 34, no luck
> >
> > acelan@u-Kabylake-Client-platform ~ % iperf -c 10.101.46.219 -er
> > 
> > Server listening on TCP port 5001 with pid 2138
> > Read buffer size: 1.44 KByte
> > TCP window size: 85.3 KByte (default)
> > 
> > 
> > Client connecting to 10.101.46.219, TCP port 5001 with pid 2138
> > Write buffer size: 128 KByte
> > TCP window size: 187 KByte (default)
> > 
> > [ 5] local 10.101.46.25 port 43560 connected with 10.101.46.219 port 5001
> > [ ID] Interval Transfer Bandwidth Write/Err Rtry Cwnd/RTT
> > [ 5] 0.00-10.01 sec 896 KBytes 733 Kbits/sec 1/0 58 7K/140474 us
> > [ 4] local 10.101.46.25 port 5001 connected with 10.101.46.219 port 38844
> > [ ID] Interval Transfer Bandwidth Reads Dist(bin=0.2K)
> > [ 4] 0.00-10.11 sec 79.8 MBytes 66.2 Mbits/sec 57744
> > 37:6:191:52:1236:413:143:55666
> >
> > Any ideas?
> >
> > Best regards,
> > AceLan Kao.


[PATCH] iwlwifi: pcie: fix DMA memory mapping / unmapping

2018-01-03 Thread Emmanuel Grumbach
22000 devices (previously referenced as A000) can support
short transmit queues. This means that we have less DMA
descriptors (TFD) for those shorter queues.
Previous devices must still have 256 TFDs for each queue
even if those 256 TFDs point to fewer buffers.

When I introduced support for the short queues for 22000
I broke older devices by assuming that they can also have
less TFDs in their queues. This led to several problems:

1) the payload of the commands weren't unmapped properly
   which caused the SWIOTLB to complain at some point.
2) the hardware could get confused and we get hardware
   crashes.

The corresponding bugzilla entries are:

https://bugzilla.kernel.org/show_bug.cgi?id=198201
https://bugzilla.kernel.org/show_bug.cgi?id=198265

Cc: sta...@vger.kernel.org # 4.14+
Fixes: 4ecab5616023 ("iwlwifi: pcie: support short Tx queues for A000 device 
family")
Reviewed-by: Sharon, Sara <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
Hi Kalle,

Luca is on vacation is 4.15 will be closed soon.
I am fixing here a bug that caused much troube on our side.
There are two bugzillas on it. Users on both bugs validated
this fix.
Please apply this on wireless-drivers.git directly and I'll sync
with Luca when he'll be back.

Thank you!
---
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 10 +++---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  | 11 +++
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   |  8 
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index d749abeca3ae..403e65c309d0 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -670,11 +670,15 @@ static inline u8 iwl_pcie_get_cmd_index(struct iwl_txq 
*q, u32 index)
return index & (q->n_window - 1);
 }
 
-static inline void *iwl_pcie_get_tfd(struct iwl_trans_pcie *trans_pcie,
+static inline void *iwl_pcie_get_tfd(struct iwl_trans *trans,
 struct iwl_txq *txq, int idx)
 {
-   return txq->tfds + trans_pcie->tfd_size * iwl_pcie_get_cmd_index(txq,
-idx);
+   struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+   if (trans->cfg->use_tfh)
+   idx = iwl_pcie_get_cmd_index(txq, idx);
+
+   return txq->tfds + trans_pcie->tfd_size * idx;
 }
 
 static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 16b345f54ff0..6d0a907d5ba5 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -171,8 +171,6 @@ static void iwl_pcie_gen2_tfd_unmap(struct iwl_trans *trans,
 
 static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, struct iwl_txq 
*txq)
 {
-   struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-
/* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and
 * idx is bounded by n_window
 */
@@ -181,7 +179,7 @@ static void iwl_pcie_gen2_free_tfd(struct iwl_trans *trans, 
struct iwl_txq *txq)
lockdep_assert_held(>lock);
 
iwl_pcie_gen2_tfd_unmap(trans, >entries[idx].meta,
-   iwl_pcie_get_tfd(trans_pcie, txq, idx));
+   iwl_pcie_get_tfd(trans, txq, idx));
 
/* free SKB */
if (txq->entries) {
@@ -364,11 +362,9 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct 
iwl_trans *trans,
struct sk_buff *skb,
struct iwl_cmd_meta *out_meta)
 {
-   struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
-   struct iwl_tfh_tfd *tfd =
-   iwl_pcie_get_tfd(trans_pcie, txq, idx);
+   struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, idx);
dma_addr_t tb_phys;
bool amsdu;
int i, len, tb1_len, tb2_len, hdr_len;
@@ -565,8 +561,7 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans 
*trans,
u8 group_id = iwl_cmd_groupid(cmd->id);
const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
-   struct iwl_tfh_tfd *tfd =
-   iwl_pcie_get_tfd(trans_pcie, txq, txq->write_ptr);
+   struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, txq->write_ptr);
 
memset(tfd, 0, sizeof(*tfd));
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index fed6d842a5e1..3f857

Re: iwlwifi: mvm: rx ops with kernel >= 4.14

2018-01-03 Thread Emmanuel Grumbach
Hi,

>
> hi,
>
> after updating to kernel >= 4.14 (from 4.13.X) my wifi stops working every 
> couple hours with the following stacktrace (I've already updated firmware to 
> latest version):
>
> jan 03 13:28:17 tmi kernel: iwlwifi :3b:00.0: loaded firmware version 
> 17.608620.0 op_mode iwlmvm
> jan 03 13:28:17 tmi kernel: iwlwifi :3b:00.0: Detected Intel(R) Dual Band 
> Wireless AC 7260, REV=0x144
> jan 03 13:28:17 tmi kernel: iwlwifi :3b:00.0: base HW address: 
> d8:fc:93:14:cc:15
> jan 03 13:28:17 tmi kernel: ieee80211 phy0: Selected rate control algorithm 
> 'iwl-mvm-rs'
> [...]
> jan 03 16:14:05 tmi kernel: iwlwifi :3b:00.0: iwl_pcie_cmdq_reclaim: Read 
> index for DMA queue txq id (0), index 0 is out of range [0-256] 70 70.
> jan 03 16:14:05 tmi kernel: iwlwifi :3b:00.0: HCMD_ACTIVE already clear 
> for command LQ_CMD
> jan 03 16:14:05 tmi kernel: frame on invalid queue - is on 0 and indicates 1
> jan 03 16:14:05 tmi kernel: [ cut here ]

Can you please check if the patch in
https://bugzilla.kernel.org/show_bug.cgi?id=198265 helps?


[PATCH] mac80211: always update the PM state of a peer on MGMT / DATA frames

2017-09-06 Thread Emmanuel Grumbach
The 2016 version of the spec is more generic about when the
AP should update the power management state of the peer:
the AP shall update the state based on any management or
data frames. This means that even non-bufferable management
frames should be looked at to update to maintain the power
management state of the peer.

This can avoid problematic cases for example if a station
disappears while being asleep and then re-appears. The AP
would remember it as in power save, but the Authentication
frame couldn't be used to set the peer as awake again.
Note that this issues wasn't really critical since at some
point (after the association) we would have removed the
station and created another one with all the states cleared.

type=feature
ticket=none

Change-Id: Iae1fbbd502d64f0c31db3e0f2d81224b29acb5af
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 net/mac80211/rx.c | 17 +
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fdf616811865..89db6b11af8a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1749,23 +1749,16 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 
/*
 * Change STA power saving mode only at the end of a frame
-* exchange sequence.
+* exchange sequence, and only for a data or management
+* frame as specified in ieee80211-2016 11.2.3.2
 */
if (!ieee80211_hw_check(>local->hw, AP_LINK_PS) &&
!ieee80211_has_morefrags(hdr->frame_control) &&
-   !ieee80211_is_back_req(hdr->frame_control) &&
+   (ieee80211_is_mgmt(hdr->frame_control) ||
+ieee80211_is_data(hdr->frame_control)) &&
!(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
-rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
-   /*
-* PM bit is only checked in frames where it isn't reserved,
-* in AP mode it's reserved in non-bufferable management frames
-* (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
-* BAR frames should be ignored as specified in
-* IEEE 802.11-2012 10.2.1.2.
-*/
-   (!ieee80211_is_mgmt(hdr->frame_control) ||
-ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {
+rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
if (!ieee80211_has_pm(hdr->frame_control))
sta_ps_end(sta);
-- 
2.9.3



[PATCH v3] nl80211: add an option to allow MFP without requiring it

2017-08-15 Thread Emmanuel Grumbach
User space can now allow the kernel to associate to an AP
that requires MFP or that doesn't have MFP enabled in the
same NL80211_CMD_CONNECT command.
The driver / firmware will decide whether to use it or not.
Add a feature bit to inform the user space the kernel
supports this setting.

This new option will be useful for firmwares that can
generate the RSN IE internally and when the user space does
not have the RSN IE of the AP we're connecting to. Since
the user space doesn't see the RSN IE of the AP, it cannot
fully decide whether to require or to forbid MFP. It needs
to be given the possibility to allow the driver to use MFP
without making it mandatory.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
v2: * add a feature flag
* fix the comment of NL80211_MFP_OPTIONAL as pointed out by Igor
v3: check the feature flag
---
 include/uapi/linux/nl80211.h | 13 +++--
 net/wireless/nl80211.c   |  5 -
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 7950c71c0ad4..e98c93d86220 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1410,8 +1410,12 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
  * used for the association ( nl80211_mfp, represented as a u32);
- * this attribute can be used
- * with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests
+ * this attribute can be used with %NL80211_CMD_ASSOCIATE and
+ * %NL80211_CMD_CONNECT requests. %NL80211_MFP_OPTIONAL is not allowed for
+ * %NL80211_CMD_ASSOCIATE since user space SME is expected and hence, it
+ * must have decided whether to use management frame protection or not.
+ * Setting %NL80211_MFP_OPTIONAL with a %NL80211_CMD_CONNECT request will
+ * let the driver (or the firmware) decide whether to use MFP or not.
  *
  * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
  *  nl80211_sta_flag_update.
@@ -4086,10 +4090,12 @@ enum nl80211_key_type {
  * enum nl80211_mfp - Management frame protection state
  * @NL80211_MFP_NO: Management frame protection not used
  * @NL80211_MFP_REQUIRED: Management frame protection required
+ * @NL80211_MFP_OPTIONAL: Management frame protection is optional
  */
 enum nl80211_mfp {
NL80211_MFP_NO,
NL80211_MFP_REQUIRED,
+   NL80211_MFP_OPTIONAL,
 };
 
 enum nl80211_wpa_versions {
@@ -5058,6 +5064,8 @@ enum nl80211_feature_flags {
  * the first probe request in each channel at rate of at least 5.5Mbps.
  * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: Driver supports
  * probe request tx deferral and suppression
+ * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
+ * value in %NL80211_ATTR_USE_MFP.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5083,6 +5091,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
+   NL80211_EXT_FEATURE_MFP_OPTIONAL,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8f035d9868d1..42a48577f3f7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9115,7 +9115,10 @@ static int nl80211_connect(struct sk_buff *skb, struct 
genl_info *info)
if (info->attrs[NL80211_ATTR_USE_MFP]) {
connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
if (connect.mfp != NL80211_MFP_REQUIRED &&
-   connect.mfp != NL80211_MFP_NO)
+   connect.mfp != NL80211_MFP_NO &&
+   (connect.mfp != NL80211_MFP_OPTIONAL ||
+!wiphy_ext_feature_isset(>wiphy,
+   NL80211_EXT_FEATURE_MFP_OPTIONAL)))
return -EINVAL;
} else {
connect.mfp = NL80211_MFP_NO;
-- 
2.9.3



[PATCH v2] nl80211: add an option to allow MFP without requiring it

2017-08-15 Thread Emmanuel Grumbach
User space can now allow the kernel to associate to an AP
that requires MFP or that doesn't have MFP enabled in the
same NL80211_CMD_CONNECT command.
The driver / firmware will decide whether to use it or not.
Add a feature bit to inform the user space the kernel
supports this setting.

This new option will be useful for firmwares that can
generate the RSN IE internally and when the user space does
not have the RSN IE of the AP we're connecting to. Since
the user space doesn't see the RSN IE of the AP, it cannot
fully decide whether to require or to forbid MFP. It needs
to be given the possibility to allow the driver to use MFP
without making it mandatory.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
v2: * add a feature flag
* fix the comment of NL80211_MFP_OPTIONAL as pointed out by Igor
---
 include/uapi/linux/nl80211.h | 13 +++--
 net/wireless/nl80211.c   |  1 +
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 7950c71c0ad4..e98c93d86220 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1410,8 +1410,12 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
  * used for the association ( nl80211_mfp, represented as a u32);
- * this attribute can be used
- * with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests
+ * this attribute can be used with %NL80211_CMD_ASSOCIATE and
+ * %NL80211_CMD_CONNECT requests. %NL80211_MFP_OPTIONAL is not allowed for
+ * %NL80211_CMD_ASSOCIATE since user space SME is expected and hence, it
+ * must have decided whether to use management frame protection or not.
+ * Setting %NL80211_MFP_OPTIONAL with a %NL80211_CMD_CONNECT request will
+ * let the driver (or the firmware) decide whether to use MFP or not.
  *
  * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
  *  nl80211_sta_flag_update.
@@ -4086,10 +4090,12 @@ enum nl80211_key_type {
  * enum nl80211_mfp - Management frame protection state
  * @NL80211_MFP_NO: Management frame protection not used
  * @NL80211_MFP_REQUIRED: Management frame protection required
+ * @NL80211_MFP_OPTIONAL: Management frame protection is optional
  */
 enum nl80211_mfp {
NL80211_MFP_NO,
NL80211_MFP_REQUIRED,
+   NL80211_MFP_OPTIONAL,
 };
 
 enum nl80211_wpa_versions {
@@ -5058,6 +5064,8 @@ enum nl80211_feature_flags {
  * the first probe request in each channel at rate of at least 5.5Mbps.
  * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: Driver supports
  * probe request tx deferral and suppression
+ * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
+ * value in %NL80211_ATTR_USE_MFP.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5083,6 +5091,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
+   NL80211_EXT_FEATURE_MFP_OPTIONAL,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8f035d9868d1..829867132326 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9115,6 +9115,7 @@ static int nl80211_connect(struct sk_buff *skb, struct 
genl_info *info)
if (info->attrs[NL80211_ATTR_USE_MFP]) {
connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
if (connect.mfp != NL80211_MFP_REQUIRED &&
+   connect.mfp != NL80211_MFP_OPTIONAL &&
connect.mfp != NL80211_MFP_NO)
return -EINVAL;
} else {
-- 
2.9.3



[PATCH] nl80211: add an option to allow MFP without requiring it

2017-08-14 Thread Emmanuel Grumbach
User space can now allow the kernel to associate to an AP
that requires MFP or that doesn't have MFP enabled in the
same NL80211_CMD_CONNECT command.
The driver / firmware will decide whether to use it or not.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
A short tour of the drivers taught me that only Quantenna really look
at cfg80211_connect_params::sme which can now be 2. This is why
the maintainer of this driver is CCed.
---
 include/uapi/linux/nl80211.h | 10 --
 net/wireless/nl80211.c   |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 7950c71c0ad4..ea1cfecbf6f4 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1410,8 +1410,12 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
  * used for the association ( nl80211_mfp, represented as a u32);
- * this attribute can be used
- * with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests
+ * this attribute can be used with %NL80211_CMD_ASSOCIATE and
+ * %NL80211_CMD_CONNECT requests. %NL80211_MFP_OPTIONAL is not allowed for
+ * %NL80211_CMD_ASSOCIATE since user space SME is expected and hence, it
+ * must have decided whether to use management frame protection or not.
+ * Setting %NL80211_MFP_OPTIONAL with a %NL80211_CMD_CONNECT request will
+ * let the driver (or the firmware) decide whether to use MFP or not.
  *
  * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
  *  nl80211_sta_flag_update.
@@ -4086,10 +4090,12 @@ enum nl80211_key_type {
  * enum nl80211_mfp - Management frame protection state
  * @NL80211_MFP_NO: Management frame protection not used
  * @NL80211_MFP_REQUIRED: Management frame protection required
+ * @NL80211_MFP_OPTIONAL: Management frame is optional
  */
 enum nl80211_mfp {
NL80211_MFP_NO,
NL80211_MFP_REQUIRED,
+   NL80211_MFP_OPTIONAL,
 };
 
 enum nl80211_wpa_versions {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8f035d9868d1..829867132326 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9115,6 +9115,7 @@ static int nl80211_connect(struct sk_buff *skb, struct 
genl_info *info)
if (info->attrs[NL80211_ATTR_USE_MFP]) {
connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
if (connect.mfp != NL80211_MFP_REQUIRED &&
+   connect.mfp != NL80211_MFP_OPTIONAL &&
connect.mfp != NL80211_MFP_NO)
return -EINVAL;
} else {
-- 
2.9.3



Re: System freezes when send packet to mon device in TX_RING mode

2017-07-30 Thread Emmanuel Grumbach
On Sun, Jul 30, 2017 at 10:22 AM, angus  wrote:
>
> Hi Wifi-Devs,

So you seem to be using an old Intel device.
What you can do is to use netconsole to send your kernel output to a
separate machine. This way you'll be able to collect logs.
Running in a VM is also an option.

>
> I got the full system freeze when tried to send rtap packet via monitor
> interface with
> TX_RING mode using trafgen tool (example of packet is below):
>
> # it sends 1 packet via monitor wlan0 interface in TX_RING mode
> trafgen/trafgen -i ~/pcap/rtap.cfg -o wlan0 -n 1
>
> after that system totally freezes so I can only reboot system
> via power button.
>
> But when I run the same command w/o using TX_RING on this
> interface then everything is OK:
>
> trafgen/trafgen -i ~/pcap/rtap.cfg -o wlan0 -n 1
>
> Would you suggest some debugging approaches how to debug
> such issue when system is totally freezed ?
> Or may you please point some references to investigate the
> issue ?
>
> I wonder what may happen to full stuck the system.
>
> Below I provided some info which may help.
>
> I provided an strace of sending the packet via regular eth
> interface to demonstrate how interface
> is actually configured in TX_RING mode by trafgen util.
>
> Thanks,
> Vadim Kochan
>
> [Sys Info]-
> Thinkpad x230
> Linux angus 4.8.0-59-generic #64-Ubuntu SMP Thu Jun 29 19:38:34 UTC 2017 
> x86_64 x86_64 x86_64 GNU/Linux
>
> [monitor setup]--
> #!/bin/bash
> DEV=wlp3s0
>
> sudo iw dev $DEV interface add $1 type monitor
> sudo ifconfig $DEV down
> sudo ifconfig $1 up
> sudo iw dev $1 set channel 1
> sudo ifconfig $DEV down
>
> [packet in trafgen's 
> format]---
> {
>   0x00, 0x00, 0x18, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
> 0x00, 0x00, 0x00,
>   0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x02, 0xff, 
> 0xff, 0x01, 0x23,
>   0x45, 0x67, 0x89, 0xab, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x01, 0x23, 
> 0x45, 0x67, 0x89,
>   0xab, 0x00, 0x00, 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 
> 0x00, 0x00, 0x1c,
>   0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 0x8f, 0xd2, 0xa9, 0xfe, 0x01, 0x01, 
> 0xff, 0xff, 0xff,
>   0xff, 0xc5, 0x49, 0xc5, 0x49, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 
> 0x00,
> }
>
> --- [strace of sending via eth iface] 
> -
> angus@angus:~/src/netsniff-ng$ sudo strace -f trafgen/trafgen -i 
> ~/pcap/rtap.cfg -o wlp3s0 -n 1
> execve("trafgen/trafgen", ["trafgen/trafgen", "-i", 
> "/home/angus/pcap/rtap.cfg", "-o", "wlp3s0", "-n", "1"], [/* 27 vars */]) = 0
> brk(NULL)   = 0x557b13f71000
> access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or 
> directory)
> mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
> 0x7f7dcdd2a000
> access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or 
> directory)
> open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
> fstat(3, {st_mode=S_IFREG|0644, st_size=124132, ...}) = 0
> mmap(NULL, 124132, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7dcdd0b000
> close(3)= 0
> access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or 
> directory)
> open("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
> read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20W\0\0\0\0\0\0"..., 
> 832) = 832
> fstat(3, {st_mode=S_IFREG|0644, st_size=1088952, ...}) = 0
> mmap(NULL, 3178744, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 
> 0x7f7dcd7ff000
> mprotect(0x7f7dcd907000, 2093056, PROT_NONE) = 0
> mmap(0x7f7dcdb06000, 8192, PROT_READ|PROT_WRITE, 
> MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x107000) = 0x7f7dcdb06000
> close(3)= 0
> access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or 
> directory)
> open("/lib/x86_64-linux-gnu/libnl-3.so.200", O_RDONLY|O_CLOEXEC) = 3
> read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200r\0\0\0\0\0\0"..., 
> 832) = 832
> fstat(3, {st_mode=S_IFREG|0644, st_size=125664, ...}) = 0
> mmap(NULL, 2221096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 
> 0x7f7dcd5e
> mprotect(0x7f7dcd5fd000, 2093056, PROT_NONE) = 0
> mmap(0x7f7dcd7fc000, 12288, PROT_READ|PROT_WRITE, 
> MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x7f7dcd7fc000
> close(3)= 0
> access("/etc/ld.so.nohwcap", F_OK)  = -1 ENOENT (No such file or 
> directory)
> open("/lib/x86_64-linux-gnu/libnl-genl-3.so.200", O_RDONLY|O_CLOEXEC) = 3
> read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\ \0\0\0\0\0\0"..., 
> 832) = 832
> fstat(3, {st_mode=S_IFREG|0644, st_size=23792, ...}) = 0
> mmap(NULL, 2118856, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 

Re: [PATCH] cfg80211: don't change the regulatory HT flags in custom regulatory flows

2017-07-07 Thread Emmanuel Grumbach
On Fri, Jul 7, 2017 at 12:56 PM, Emmanuel Grumbach
<emmanuel.grumb...@intel.com> wrote:
> When the regulatory is handled by the driver, don't
> interact with the flags it sets.
> iwlwifi doesn't want to use channel 40 HT40+ for example.
>
> Cc: <sta...@vger.kernel.org> [4.0+]
> Fixes: b0d7aa59592b ("cfg80211: allow wiphy specific regdomain management")
> Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

I sent a v2 for this, but forgot to change the subject to PATCH v2...
Sorry for the mess.
In the v2, I just changed the commit log.

> ---
>  net/wireless/reg.c | 20 ++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 5fae296a6a58..29879440626e 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -4,6 +4,7 @@
>   * Copyright 2007  Johannes Berg <johan...@sipsolutions.net>
>   * Copyright 2008-2011 Luis R. Rodriguez <mcg...@qca.qualcomm.com>
>   * Copyright 2013-2014  Intel Mobile Communications GmbH
> + * Copyright  2017  Intel Deutschland GmbH
>   *
>   * Permission to use, copy, modify, and/or distribute this software for any
>   * purpose with or without fee is hereby granted, provided that the above
> @@ -1483,7 +1484,9 @@ static void reg_process_ht_flags_channel(struct wiphy 
> *wiphy,
>  {
> struct ieee80211_supported_band *sband = wiphy->bands[channel->band];
> struct ieee80211_channel *channel_before = NULL, *channel_after = 
> NULL;
> +   const struct ieee80211_regdomain *regd;
> unsigned int i;
> +   u32 flags;
>
> if (!is_ht40_allowed(channel)) {
> channel->flags |= IEEE80211_CHAN_NO_HT40;
> @@ -1503,17 +1506,30 @@ static void reg_process_ht_flags_channel(struct wiphy 
> *wiphy,
> channel_after = c;
> }
>
> +   regd = get_wiphy_regdom(wiphy);
> +   if (regd) {
> +   const struct ieee80211_reg_rule *reg_rule =
> +   freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq),
> +  regd, MHZ_TO_KHZ(20));
> +
> +   flags = reg_rule->flags;
> +   } else {
> +   flags = 0;
> +   }
> +
> /*
>  * Please note that this assumes target bandwidth is 20 MHz,
>  * if that ever changes we also need to change the below logic
>  * to include that as well.
>  */
> -   if (!is_ht40_allowed(channel_before))
> +   if (!is_ht40_allowed(channel_before) ||
> +   flags & NL80211_RRF_NO_HT40MINUS)
> channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
> else
> channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
>
> -   if (!is_ht40_allowed(channel_after))
> +   if (!is_ht40_allowed(channel_after) ||
> +   flags & NL80211_RRF_NO_HT40PLUS)
> channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
> else
> channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
> --
> 2.9.3
>


[PATCH] cfg80211: honor NL80211_RRF_NO_HT40{MINUS,PLUS}

2017-07-07 Thread Emmanuel Grumbach
Honor the NL80211_RRF_NO_HT40{MINUS,PLUS} flags in
reg_process_ht_flags_channel. Not doing so leads can lead
to a firmware assert in iwlwifi for example.

Fixes: b0d7aa59592b ("cfg80211: allow wiphy specific regdomain management")
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 net/wireless/reg.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5fae296a6a58..29879440626e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -4,6 +4,7 @@
  * Copyright 2007  Johannes Berg <johan...@sipsolutions.net>
  * Copyright 2008-2011 Luis R. Rodriguez <mcg...@qca.qualcomm.com>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
+ * Copyright  2017  Intel Deutschland GmbH
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1483,7 +1484,9 @@ static void reg_process_ht_flags_channel(struct wiphy 
*wiphy,
 {
struct ieee80211_supported_band *sband = wiphy->bands[channel->band];
struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
+   const struct ieee80211_regdomain *regd;
unsigned int i;
+   u32 flags;
 
if (!is_ht40_allowed(channel)) {
channel->flags |= IEEE80211_CHAN_NO_HT40;
@@ -1503,17 +1506,30 @@ static void reg_process_ht_flags_channel(struct wiphy 
*wiphy,
channel_after = c;
}
 
+   regd = get_wiphy_regdom(wiphy);
+   if (regd) {
+   const struct ieee80211_reg_rule *reg_rule =
+   freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq),
+  regd, MHZ_TO_KHZ(20));
+
+   flags = reg_rule->flags;
+   } else {
+   flags = 0;
+   }
+
/*
 * Please note that this assumes target bandwidth is 20 MHz,
 * if that ever changes we also need to change the below logic
 * to include that as well.
 */
-   if (!is_ht40_allowed(channel_before))
+   if (!is_ht40_allowed(channel_before) ||
+   flags & NL80211_RRF_NO_HT40MINUS)
channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
else
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
 
-   if (!is_ht40_allowed(channel_after))
+   if (!is_ht40_allowed(channel_after) ||
+   flags & NL80211_RRF_NO_HT40PLUS)
channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
else
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
-- 
2.9.3



[PATCH] cfg80211: don't change the regulatory HT flags in custom regulatory flows

2017-07-07 Thread Emmanuel Grumbach
When the regulatory is handled by the driver, don't
interact with the flags it sets.
iwlwifi doesn't want to use channel 40 HT40+ for example.

Cc: <sta...@vger.kernel.org> [4.0+]
Fixes: b0d7aa59592b ("cfg80211: allow wiphy specific regdomain management")
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 net/wireless/reg.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5fae296a6a58..29879440626e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -4,6 +4,7 @@
  * Copyright 2007  Johannes Berg <johan...@sipsolutions.net>
  * Copyright 2008-2011 Luis R. Rodriguez <mcg...@qca.qualcomm.com>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
+ * Copyright  2017  Intel Deutschland GmbH
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1483,7 +1484,9 @@ static void reg_process_ht_flags_channel(struct wiphy 
*wiphy,
 {
struct ieee80211_supported_band *sband = wiphy->bands[channel->band];
struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
+   const struct ieee80211_regdomain *regd;
unsigned int i;
+   u32 flags;
 
if (!is_ht40_allowed(channel)) {
channel->flags |= IEEE80211_CHAN_NO_HT40;
@@ -1503,17 +1506,30 @@ static void reg_process_ht_flags_channel(struct wiphy 
*wiphy,
channel_after = c;
}
 
+   regd = get_wiphy_regdom(wiphy);
+   if (regd) {
+   const struct ieee80211_reg_rule *reg_rule =
+   freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq),
+  regd, MHZ_TO_KHZ(20));
+
+   flags = reg_rule->flags;
+   } else {
+   flags = 0;
+   }
+
/*
 * Please note that this assumes target bandwidth is 20 MHz,
 * if that ever changes we also need to change the below logic
 * to include that as well.
 */
-   if (!is_ht40_allowed(channel_before))
+   if (!is_ht40_allowed(channel_before) ||
+   flags & NL80211_RRF_NO_HT40MINUS)
channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
else
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
 
-   if (!is_ht40_allowed(channel_after))
+   if (!is_ht40_allowed(channel_after) ||
+   flags & NL80211_RRF_NO_HT40PLUS)
channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
else
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
-- 
2.9.3



Re: Command equivalent in iw

2017-07-06 Thread Emmanuel Grumbach
On Thu, Jul 6, 2017 at 5:51 AM, Larry Finger  wrote:
>
> Someone using the rtlwifi code that is posted at GitHub wants to know the iw 
> equivalent of "iwpriv wlan0 bandcfg" to limit the wireless interface to 
> 802.11b, 802.11g, or 802.11n. I only use simple iw commands, and I could not 
> answer the question.

This seems to be a private IOCTL and I can't find the code for that
handler in the kernel today. Even in wireless extensions..
I am not aware of something like this with iw today.

In iwlwifi we have module parameter for this since this should really
be used seldom.


Re: [PATCH] mac80211/wpa: use constant time memory comparison for MACs

2017-06-18 Thread Emmanuel Grumbach
On Sun, Jun 18, 2017 at 10:18 PM, Jason A. Donenfeld  wrote:
> Otherwise, we enable all sorts of forgeries via timing attack.

crypto_memneq's description says:

Returns 0 when data is equal, 1 otherwise.

Clearly this is not suitable here. You are allowing replay attacks...
For network drivers, this is worse than timing attacks. You still need
to explain how you can exploit timing attacks *on a remote system*. On
your local system, threads are impacted etc... Fine. On a remote
system (you are in Rx path here..) how do you exploit them?


>
> Signed-off-by: Jason A. Donenfeld 
> Cc: Johannes Berg 
> Cc: linux-wireless@vger.kernel.org
> Cc: sta...@vger.kernel.org
> Signed-off-by: Johannes Berg 
> ---
> Here's the backport for 3.18.
>
>  net/mac80211/wpa.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
> index 983527a4c1ab..49592c7e4199 100644
> --- a/net/mac80211/wpa.c
> +++ b/net/mac80211/wpa.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include "ieee80211_i.h"
>  #include "michael.h"
> @@ -150,7 +151,7 @@ ieee80211_rx_h_michael_mic_verify(struct 
> ieee80211_rx_data *rx)
> data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
> key = >key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
> michael_mic(key, hdr, data, data_len, mic);
> -   if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0)
> +   if (crypto_memneq(mic, data + data_len, MICHAEL_MIC_LEN) != 0)
> goto mic_fail;
>
> /* remove Michael MIC from payload */
> @@ -520,7 +521,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data 
> *rx)
>
> queue = rx->security_idx;
>
> -   if (memcmp(pn, key->u.ccmp.rx_pn[queue], IEEE80211_CCMP_PN_LEN) <= 0) 
> {
> +   if (crypto_memneq(pn, key->u.ccmp.rx_pn[queue], 
> IEEE80211_CCMP_PN_LEN) <= 0) {
> key->u.ccmp.replays++;
> return RX_DROP_UNUSABLE;
> }
> @@ -771,7 +772,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct 
> ieee80211_rx_data *rx)
> bip_aad(skb, aad);
> ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
>skb->data + 24, skb->len - 24, mic);
> -   if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
> +   if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
> key->u.aes_cmac.icverrors++;
> return RX_DROP_UNUSABLE;
> }
> --
> 2.13.1
>


Re: Question on flushing and deauth frames

2017-06-15 Thread Emmanuel Grumbach
>>
>> Keep in mind that this code is also called when roaming, any
>> additional operations will slow down the roaming process. Not all the
>
>
> This is a reason to not retransmit, but logically the flush(drop=false) is
> supposed to wait for the frame to be transmitted anyway, and at that point,
> tx-status should be immediately available.
>

I can't disagree here although waiting for the Tx status can be tricky
for the low level drivers that don't implement tx_status.

>> drivers support tx_status, but I think that this could be implemented
>> internally in ath10k. In iwlwifi, we just wait until the queues get
>> empty without dropping the packets.
>
>
> When you support virtual stations and a fat firmware, that can be tricky to
> implement.
>
> From your description, are you waiting on a single vdev, or multiple when
> you flush?

In the past, we had queues per vdev. So that we had to wait for the
queues of the vdev. Note that Intel is more focused on the BSS
scenario in which vdev = station pretty much. I understand that you
are more focused on the AP scenario, but that shouldn't really delete
stations all that often, right?

> If multiple, then waiting for tx status of just the deauth frame should be
> faster
> on average than waiting for the flush since you don't have to flush the
> other
> vdevs.

True. Well, on Intel devices, we work with Tx queues, and now we have
a Tx queue for each ra/tid. Yes it limits the number of peers we can
support, but as I said, we are less AP mode oriented.

>
> Whether drivers support a correct tx-status, I think all of them report
> *some* tx
> status...that is how mac80211 knows it can clean up the frame?  That would
> be enough
> to know that the frame at least went through the tx logic and thus was
> flushed.

It is an option. Maybe mac80211 could pass the pointer to the skb it
is waiting for in the flush(drop=false) call and that would make it
easier for you to wait for it internally in ath10k?

I'll let Johannes decide here :)

>
>> Of course, I am giving my *non authoritative* opinion :)
>
>
> I appreciate it none the less!
>
>
> Thanks,
> Ben
>
>
> --
> Ben Greear 
> Candela Technologies Inc  http://www.candelatech.com
>


Re: Question on flushing and deauth frames

2017-06-15 Thread Emmanuel Grumbach
On Thu, Jun 15, 2017 at 4:32 PM, Ben Greear <gree...@candelatech.com> wrote:
>
>
> On 06/14/2017 11:18 PM, Emmanuel Grumbach wrote:
>>>
>>> ath10k is a bit weird about flushing frames, and at least my variant of
>>> the wave-2
>>> firmware does not always put the deauth frame on the air when deleting
>>> stations.
>>>
>>> It will likely not be much fun to fix this.  I was wondering if the code
>>> below
>>> from ieee80211_set_disassoc() could (easily?) be made to wait for a
>>> tx-status of the deauth frame
>>> instead of trying to force a flush?
>>
>>
>> That's exactly what it does:
>
>
> Well, the end effect is supposed to be the same, at least...
>
>>>/*
>>>  * drop any frame before deauth/disassoc, this can be data or
>>>  * management frame. Since we are disconnecting, we should not
>>>  * insist sending these frames which can take time and delay
>>>  * the disconnection and possible the roaming.
>>>  */
>>> if (tx)
>>> ieee80211_flush_queues(local, sdata, true);
>>
>>
>> Remove all the pending data frames from the queues to clear the way
>> for the deauth.
>> Note the drop=true
>>
>>>
>>> /* deauthenticate/disassociate now */
>>> if (tx || frame_buf)
>>> ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid,
>>> stype,
>>>reason, tx, frame_buf);
>>>
>>
>> Send the deauth.
>>
>>> /* flush out frame - make sure the deauth was actually sent */
>>> if (tx)
>>> ieee80211_flush_queues(local, sdata, false);
>>>
>>
>> Wait for the deauth (drop=false).
>> The question here is how ath10k implements the flush(, drop=false)
>
>
> Not well, it seems.  I don't think it has a good way to flush (drop=false)
> an individual vdev, though probably I could implement it.  And, I think that
> the packets in the mac80211 txqs might be difficult to flush.
>
> But, mac80211 gets a txstatus when the deauth is sent, so if it simply
> waited on that, it would not matter how flush is implemented.  And, it might
> try to re-send a time or two if getting the deauth through was worth the
> wait and the initial attempt(s) got a false txstatus.
>

Keep in mind that this code is also called when roaming, any
additional operations will slow down the roaming process. Not all the
drivers support tx_status, but I think that this could be implemented
internally in ath10k. In iwlwifi, we just wait until the queues get
empty without dropping the packets.
Of course, I am giving my *non authoritative* opinion :)


Re: Question on flushing and deauth frames

2017-06-15 Thread Emmanuel Grumbach
> ath10k is a bit weird about flushing frames, and at least my variant of the 
> wave-2
> firmware does not always put the deauth frame on the air when deleting 
> stations.
>
> It will likely not be much fun to fix this.  I was wondering if the code below
> from ieee80211_set_disassoc() could (easily?) be made to wait for a tx-status 
> of the deauth frame
> instead of trying to force a flush?

That's exactly what it does:

>
>/*
>  * drop any frame before deauth/disassoc, this can be data or
>  * management frame. Since we are disconnecting, we should not
>  * insist sending these frames which can take time and delay
>  * the disconnection and possible the roaming.
>  */
> if (tx)
> ieee80211_flush_queues(local, sdata, true);

Remove all the pending data frames from the queues to clear the way
for the deauth.
Note the drop=true

>
> /* deauthenticate/disassociate now */
> if (tx || frame_buf)
> ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
>reason, tx, frame_buf);
>

Send the deauth.

> /* flush out frame - make sure the deauth was actually sent */
> if (tx)
> ieee80211_flush_queues(local, sdata, false);
>

Wait for the deauth (drop=false).
The question here is how ath10k implements the flush(, drop=false)


Re: [PATCH 0/6] Constant Time Memory Comparisons Are Important

2017-06-11 Thread Emmanuel Grumbach
On Mon, Jun 12, 2017 at 12:30 AM, Emil Lenngren <emil.lenng...@gmail.com> wrote:
> 2017-06-11 22:48 GMT+02:00 Emmanuel Grumbach <egrumb...@gmail.com>:
>> On Sun, Jun 11, 2017 at 4:36 PM, Kees Cook <keesc...@chromium.org> wrote:
>>>
>>> On Sun, Jun 11, 2017 at 1:13 AM, Kalle Valo <kv...@codeaurora.org> wrote:
>>> > "Jason A. Donenfeld" <ja...@zx2c4.com> writes:
>>> >
>>> >> Whenever you're comparing two MACs, it's important to do this using
>>> >> crypto_memneq instead of memcmp. With memcmp, you leak timing 
>>> >> information,
>>> >> which could then be used to iteratively forge a MAC.
>>> >
>>> > Do you have any pointers where I could learn more about this?
>>>
>>> While not using C specifically, this talks about the problem generally:
>>> https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html
>>>
>>
>> Sorry for the stupid question, but the MAC address is in plaintext in
>> the air anyway or easily accessible via user space tools. I fail to
>> see what it is so secret about a MAC address in that code where that
>> same MAC address is accessible via myriads of ways.
>
> I think you're mixing up Media Access Control (MAC) addresses with
> Message Authentication Code (MAC). The second one is a cryptographic
> signature of a message.

Obviously... Sorry for the noise.


Re: [PATCH 0/6] Constant Time Memory Comparisons Are Important

2017-06-11 Thread Emmanuel Grumbach
On Sun, Jun 11, 2017 at 4:36 PM, Kees Cook  wrote:
>
> On Sun, Jun 11, 2017 at 1:13 AM, Kalle Valo  wrote:
> > "Jason A. Donenfeld"  writes:
> >
> >> Whenever you're comparing two MACs, it's important to do this using
> >> crypto_memneq instead of memcmp. With memcmp, you leak timing information,
> >> which could then be used to iteratively forge a MAC.
> >
> > Do you have any pointers where I could learn more about this?
>
> While not using C specifically, this talks about the problem generally:
> https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html
>

Sorry for the stupid question, but the MAC address is in plaintext in
the air anyway or easily accessible via user space tools. I fail to
see what it is so secret about a MAC address in that code where that
same MAC address is accessible via myriads of ways.


[PATCH] mac80211: don't look at the PM bit of BAR frames

2017-06-08 Thread Emmanuel Grumbach
When a peer sends a BAR frame with PM bit clear, we should
not modify its PM state as madated by the spec in
802.11-20012 10.2.1.2.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 net/mac80211/rx.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e48724a6725e..bb1e4bbf55e2 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1558,12 +1558,16 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 */
if (!ieee80211_hw_check(>local->hw, AP_LINK_PS) &&
!ieee80211_has_morefrags(hdr->frame_control) &&
+   !ieee80211_is_back_req(hdr->frame_control) &&
!(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
(rx->sdata->vif.type == NL80211_IFTYPE_AP ||
 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
-   /* PM bit is only checked in frames where it isn't reserved,
+   /*
+* PM bit is only checked in frames where it isn't reserved,
 * in AP mode it's reserved in non-bufferable management frames
 * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
+* BAR frames should be ignored as specified in
+* IEEE 802.11-2012 10.2.1.2.
 */
(!ieee80211_is_mgmt(hdr->frame_control) ||
 ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {
-- 
2.9.3



Re: Intel Wireless 7260 failed to work

2016-12-28 Thread Emmanuel Grumbach
On Wed, Dec 28, 2016 at 10:10 AM, Peter Xu  wrote:
> On Wed, Dec 28, 2016 at 09:27:15AM +0200, Luca Coelho wrote:
>
> [...]
>
>> > > > Is this a known issue? Please let me know if anyone wants more info or
>> > > > logs, since this error triggers easily (everytime I boot).
>> > >
>> > > The error message isn't really telling much to the user (hint hint) but
>> > > I suspect this is by design:
>> > >
>> > > "iwlwifi: remove support for fw older than -17 and -22
>>
>> Right, we only maintain support for a certain number of firmware
>> versions.  The FW APIs change with time and we don't want to keep all
>> legacy code supporting old firmwares in the driver forever.
>>
>> I agree that "no suitable firmware found!" is a bit scarce.  I'll see
>> if we can improve that with something: "no suitable firmware found! You
>> need iwlwifi-7260-17.ucode ()".
>
> That'll be great if we can have this info in the log. Maybe no need
> for a full URL, the firmware name would suffice at least for me.

In this case, I think we should also print the range that is supported
when we fail to find any suitable firmware.

>
> [...]
>
>> I don't think we are very aggressive, we have been supporting -17 since
>> v4.3:
>>
>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5865f3658ba37c54e346b0fdee08a1c7a152681b
>>
>> And we have published the firmware about half a year ago:
>>
>> http://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/commit/iwlwifi-7260-17.ucode?id=f2cf4d67e8eced29c8a473d3a27057aa2df57c42
>>
>> I understand your concern, but if you want to be on the bleeding-edge
>> kernel, you should be on the bleeding-edge linux-firmware as well. ;)
>
> Fair enough. :-)
>
>>
>> But as I said, I'll try to improve the error message, as that should
>> make it easier to figure out.
>
> Thank you!
>
> -- peterx


Re: [PATCH] mac80211: fix broken AP mode handling of powersave clients

2016-11-03 Thread Emmanuel Grumbach
On Thu, Nov 3, 2016 at 1:08 PM, Felix Fietkau <n...@nbd.name> wrote:
> On 2016-11-03 11:51, Emmanuel Grumbach wrote:
>> On Thu, Nov 3, 2016 at 12:51 PM, Emmanuel Grumbach <egrumb...@gmail.com> 
>> wrote:
>>> On Thu, Nov 3, 2016 at 11:59 AM, Felix Fietkau <n...@nbd.name> wrote:
>>>> Commit c68df2e7be0c ("mac80211: allow using AP_LINK_PS with
>>>> mac80211-generated TIM IE") introduced a logic error, where
>>>> __sta_info_recalc_tim turns into a no-op if local->ops->set_tim is not
>>>> set. This prevents the beacon TIM bit from being set for all drivers
>>>> that do not implement this op (almost all of them), thus thoroughly
>>>> essential AP mode powersave functionality.
>>>>
>>>> Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
>>>> Fixes: c68df2e7be0c ("mac80211: allow using AP_LINK_PS with 
>>>> mac80211-generated TIM IE")
>>>> Signed-off-by: Felix Fietkau <n...@nbd.name>
>>>> ---
>>>>  net/mac80211/sta_info.c | 2 +-
>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
>>>> index 236d47e..621734e 100644
>>>> --- a/net/mac80211/sta_info.c
>>>> +++ b/net/mac80211/sta_info.c
>>>> @@ -688,7 +688,7 @@ static void __sta_info_recalc_tim(struct sta_info 
>>>> *sta, bool ignore_pending)
>>>> }
>>>>
>>>> /* No need to do anything if the driver does all */
>>>> -   if (!local->ops->set_tim)
>>>> +   if (local->ops->set_tim)
>>>> return;
>>>
>>> but ... then, you'll need call to drv_set_tim below...
>>
>> s/need/never/
>>
>>> Apparently, we can't rely on the ops pointer to enter or not enter this 
>>> flow.
> Are you going to submit a fix, or should I just send a revert of your
> commit?
>

Go ahead and send a revert. I won't be fast enough :)


Re: [PATCH] mac80211: fix broken AP mode handling of powersave clients

2016-11-03 Thread Emmanuel Grumbach
On Thu, Nov 3, 2016 at 12:51 PM, Emmanuel Grumbach <egrumb...@gmail.com> wrote:
> On Thu, Nov 3, 2016 at 11:59 AM, Felix Fietkau <n...@nbd.name> wrote:
>> Commit c68df2e7be0c ("mac80211: allow using AP_LINK_PS with
>> mac80211-generated TIM IE") introduced a logic error, where
>> __sta_info_recalc_tim turns into a no-op if local->ops->set_tim is not
>> set. This prevents the beacon TIM bit from being set for all drivers
>> that do not implement this op (almost all of them), thus thoroughly
>> essential AP mode powersave functionality.
>>
>> Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
>> Fixes: c68df2e7be0c ("mac80211: allow using AP_LINK_PS with 
>> mac80211-generated TIM IE")
>> Signed-off-by: Felix Fietkau <n...@nbd.name>
>> ---
>>  net/mac80211/sta_info.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
>> index 236d47e..621734e 100644
>> --- a/net/mac80211/sta_info.c
>> +++ b/net/mac80211/sta_info.c
>> @@ -688,7 +688,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, 
>> bool ignore_pending)
>> }
>>
>> /* No need to do anything if the driver does all */
>> -   if (!local->ops->set_tim)
>> +   if (local->ops->set_tim)
>> return;
>
> but ... then, you'll need call to drv_set_tim below...

s/need/never/

> Apparently, we can't rely on the ops pointer to enter or not enter this flow.


Re: [PATCH] mac80211: fix broken AP mode handling of powersave clients

2016-11-03 Thread Emmanuel Grumbach
On Thu, Nov 3, 2016 at 11:59 AM, Felix Fietkau <n...@nbd.name> wrote:
> Commit c68df2e7be0c ("mac80211: allow using AP_LINK_PS with
> mac80211-generated TIM IE") introduced a logic error, where
> __sta_info_recalc_tim turns into a no-op if local->ops->set_tim is not
> set. This prevents the beacon TIM bit from being set for all drivers
> that do not implement this op (almost all of them), thus thoroughly
> essential AP mode powersave functionality.
>
> Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
> Fixes: c68df2e7be0c ("mac80211: allow using AP_LINK_PS with 
> mac80211-generated TIM IE")
> Signed-off-by: Felix Fietkau <n...@nbd.name>
> ---
>  net/mac80211/sta_info.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
> index 236d47e..621734e 100644
> --- a/net/mac80211/sta_info.c
> +++ b/net/mac80211/sta_info.c
> @@ -688,7 +688,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, 
> bool ignore_pending)
> }
>
> /* No need to do anything if the driver does all */
> -   if (!local->ops->set_tim)
> +   if (local->ops->set_tim)
> return;

but ... then, you'll need call to drv_set_tim below...
Apparently, we can't rely on the ops pointer to enter or not enter this flow.


Re: Intel 7260 not working on 4.4.24 / armv7

2016-10-18 Thread Emmanuel Grumbach
On Tue, Oct 18, 2016 at 7:22 PM, Oliver Zemann  wrote:
> Because of the problems with the ath10 card, i bought an intel 7260 (mpcie)
> wifi card. Unfortunately it is also not working.
> I get tons of those messages:
>
> [  175.777030] usb 1-1: new full-speed USB device number 2 using orion-ehci
> [  175.933953] usb 1-1: New USB device found, idVendor=8087, idProduct=07dc
> [  175.940681] usb 1-1: New USB device strings: Mfr=0, Product=0,
> SerialNumber=0
> [  175.966954] Bluetooth: hci0: read Intel version: 3707100180012d0d00
> [  175.973313] Bluetooth: hci0: Intel Bluetooth firmware file:
> intel/ibt-hw-37.7.10-fw-1.80.1.2d.d.bseq
> [  176.183954] Bluetooth: hci0: Intel Bluetooth firmware patch completed and
> activated
> [  176.749831] usb 1-1: USB disconnect, device number 2
> [  177.076993] usb 1-1: new full-speed USB device number 3 using orion-ehci
> [  177.233953] usb 1-1: New USB device found, idVendor=8087, idProduct=07dc
> [  177.240682] usb 1-1: New USB device strings: Mfr=0, Product=0,
> SerialNumber=0
> [  177.266957] Bluetooth: hci0: read Intel version: 3707100180012d0d00
> [  177.273316] Bluetooth: hci0: Intel Bluetooth firmware file:
> intel/ibt-hw-37.7.10-fw-1.80.1.2d.d.bseq
> [  177.482955] Bluetooth: hci0: Intel Bluetooth firmware patch completed and
> activated
> [  178.046910] usb 1-1: USB disconnect, device number 3
> [  178.376958] usb 1-1: new full-speed USB device number 4 using orion-ehci
> [  178.533954] usb 1-1: New USB device found, idVendor=8087, idProduct=07dc
> [  178.540682] usb 1-1: New USB device strings: Mfr=0, Product=0,
> SerialNumber=0

Hmm... bad connectors? USB seems to think that the device keeps disconnecting.
But that's the BT part.

> some information about the card:
> Bus 001 Device 011: ID 8087:07dc Intel Corp.
> Couldn't open device, some information will be missing
> Device Descriptor:
>   bLength18
>   bDescriptorType 1
>   bcdUSB   2.00
>   bDeviceClass  224 Wireless
>   bDeviceSubClass 1 Radio Frequency
>   bDeviceProtocol 1 Bluetooth
>   bMaxPacketSize064
>   idVendor   0x8087 Intel Corp.
>   idProduct  0x07dc
>   bcdDevice0.01
>   iManufacturer   0
>   iProduct0
>   iSerial 0
>   bNumConfigurations  1
>   Configuration Descriptor:
> bLength 9
> bDescriptorType 2
> wTotalLength  177
> bNumInterfaces  2
> bConfigurationValue 1
> iConfiguration  0
> bmAttributes 0xe0
>   Self Powered
>   Remote Wakeup
> MaxPower  100mA
> Interface Descriptor:
>   bLength 9
>   bDescriptorType 4
>   bInterfaceNumber0
>   bAlternateSetting   0
>   bNumEndpoints   3
>   bInterfaceClass   224 Wireless
>   bInterfaceSubClass  1 Radio Frequency
>   bInterfaceProtocol  1 Bluetooth
>   iInterface  0
>   Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x81  EP 1 IN
> bmAttributes3
>   Transfer TypeInterrupt
>   Synch Type   None
>   Usage Type   Data
> wMaxPacketSize 0x0040  1x 64 bytes
> bInterval   1
>   Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x02  EP 2 OUT
> bmAttributes2
>   Transfer TypeBulk
>   Synch Type   None
>   Usage Type   Data
> wMaxPacketSize 0x0040  1x 64 bytes
> bInterval   1
>   Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x82  EP 2 IN
> bmAttributes2
>   Transfer TypeBulk
>   Synch Type   None
>   Usage Type   Data
> wMaxPacketSize 0x0040  1x 64 bytes
> bInterval   1
> Interface Descriptor:
>   bLength 9
>   bDescriptorType 4
>   bInterfaceNumber1
>   bAlternateSetting   0
>   bNumEndpoints   2
>   bInterfaceClass   224 Wireless
>   bInterfaceSubClass  1 Radio Frequency
>   bInterfaceProtocol  1 Bluetooth
>   iInterface  0
>   Endpoint Descriptor:
> bLength 7
> bDescriptorType 5
> bEndpointAddress 0x03  EP 3 OUT
> bmAttributes1
>   Transfer TypeIsochronous
>   Synch Type   None
>   Usage Type   Data
> wMaxPacketSize 0x  1x 0 bytes
> bInterval

Re: Problem with 40Mhz on 2.5GHz with Intel 8260

2016-09-21 Thread Emmanuel Grumbach
On Wed, Sep 21, 2016 at 11:19 PM, Volker Mische <volker.mis...@gmail.com> wrote:
> Hi,
>
> On 09/21/2016 09:20 AM, Emmanuel Grumbach wrote:
>>>> can you try to unplug the power cord? I had reports that said that
>>>> this can help. Again, just a debug step to give us a hint of what you
>>>> can be experiencing.
>>>
>>> Unplug without any module parameters or combined with the
>>> cfg80211_disable_40mhz_24ghz or power_scheme one?
>>
>> Nope - default configuration.
>
> the issue also happens when the power cord is unplugged.

Ok - thanks for trying.

>
>>>> Besides this, we need to go for firmware debugging. But as I said,
>>>> don't expect this to be fast and easy. Please open a bug in
>>>> bugzilla.kernel.org. CC linuxw...@intel.com and we will guide you
>>>> there on how to provide the information we need.
>
> I've filled bug 172431
>
> [1]: https://bugzilla.kernel.org/show_bug.cgi?id=172431

Saw that. Thanks.

>
> Cheers,
>   Volker


Re: Problem with 40Mhz on 2.5GHz with Intel 8260

2016-09-21 Thread Emmanuel Grumbach
>>>
>>> I've set the iwlmvm power_scheme to 1 (and allowed the 40Mhz
>>> connection). First I thought it's good, but after a while the queue
>>> still got stuck. Especially after waking up from a suspend (not sure if
>>> that matters).
>>
>> Ok - good to know.
>>
>>>
>>> What are the next steps?
>>
>> can you try to unplug the power cord? I had reports that said that
>> this can help. Again, just a debug step to give us a hint of what you
>> can be experiencing.
>
> Unplug without any module parameters or combined with the
> cfg80211_disable_40mhz_24ghz or power_scheme one?

Nope - default configuration.

>
>
>> Besides this, we need to go for firmware debugging. But as I said,
>> don't expect this to be fast and easy. Please open a bug in
>> bugzilla.kernel.org. CC linuxw...@intel.com and we will guide you
>> there on how to provide the information we need.
>
> OK, will do once I did try with unplugging. I've seen previous reports
> on the issue. As I'm already running a Kernel compiled from source I
> hope that at least I can move fast :)

Oh - the firmware debugging doesn't involve any source modification.

>
> Cheers,
>   Volker
>


Re: Problem with 40Mhz on 2.5GHz with Intel 8260

2016-09-21 Thread Emmanuel Grumbach
> Hi,
>
> On 09/20/2016 08:22 AM, Volker Mische wrote:
>> On 09/20/2016 07:39 AM, Emmanuel Grumbach wrote:
>>> On Mon, Sep 19, 2016 at 5:00 PM, Volker Mische <volker.mis...@gmail.com> 
>>> wrote:
>>>> I'm having connectivity issues with an Intel 8260 on a 2.5GHz network
>>>> when using 40Mhz. I'm getting errors like
>>>>
>>>> Queue 2 stuck for 1 ms.
>>>>
>>>> I've upgrade my system to the firmware version 21 (21.373438.0) and
>>>> Kernel 4.8.0-rc6 in hope that it fixes the issue and to be able to debug
>>>> the problem.
>>>>
>>>> I then found the page about platform noise [1]. I don't have any issue
>>>> for several hours now (normally I was hitting the issue every few
>>>> minutes) as I've set the cfg80211_disable_40mhz_24ghz parameter.
>
>>> We tried a few times to debug those, but they take a very long time to debug
>>> since typically we need lots of reproductions and the firmware team
>>> doesn't always
>>> the time to look at the data immediately so in the end, the people who
>>> reported this
>>> originally went away.
>>> Note that 40MHz on 2.4GHz is not an optimal configuration in crowded
>>> environment,
>>> but if you live in a place where you are pretty much the only one using 
>>> those
>>> frequencies, then, it can be beneficial.
>>
>> It's at home. I normally see only one other wifi (I need to check which
>> frequency that one is using).
>>
>>
>>> What you can try is to disable low power states (by using power_scheme
>>> in iwlmvm) and see if it helps.
>>
>> I will try that.
>
> I've set the iwlmvm power_scheme to 1 (and allowed the 40Mhz
> connection). First I thought it's good, but after a while the queue
> still got stuck. Especially after waking up from a suspend (not sure if
> that matters).

Ok - good to know.

>
> What are the next steps?

can you try to unplug the power cord? I had reports that said that
this can help. Again, just a debug step to give us a hint of what you
can be experiencing.
Besides this, we need to go for firmware debugging. But as I said,
don't expect this to be fast and easy. Please open a bug in
bugzilla.kernel.org. CC linuxw...@intel.com and we will guide you
there on how to provide the information we need.


Re: Problem with 40Mhz on 2.5GHz with Intel 8260

2016-09-19 Thread Emmanuel Grumbach
Hi,

On Mon, Sep 19, 2016 at 5:00 PM, Volker Mische  wrote:
> Hi,
>
> I'm having connectivity issues with an Intel 8260 on a 2.5GHz network
> when using 40Mhz. I'm getting errors like
>
> Queue 2 stuck for 1 ms.
>
> I've upgrade my system to the firmware version 21 (21.373438.0) and
> Kernel 4.8.0-rc6 in hope that it fixes the issue and to be able to debug
> the problem.
>
> I then found the page about platform noise [1]. I don't have any issue
> for several hours now (normally I was hitting the issue every few
> minutes) as I've set the cfg80211_disable_40mhz_24ghz parameter.
>
> Now I wonder, is it worth debugging the issue with being on 40MHz or is
> disabling the proper solution and I should bother.

Well... depends whom you ask and how much time you have :)
We tried a few times to debug those, but they take a very long time to debug
since typically we need lots of reproductions and the firmware team
doesn't always
the time to look at the data immediately so in the end, the people who
reported this
originally went away.
Note that 40MHz on 2.4GHz is not an optimal configuration in crowded
environment,
but if you live in a place where you are pretty much the only one using those
frequencies, then, it can be beneficial.
What you can try is to disable low power states (by using power_scheme
in iwlmvm)
and see if it helps. This setting has a bigger impact than
cfg80211_disable_40mhz_24ghz
but it can give a hint as where the problem is coming from.

>
> [1]:
> https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi#about_platform_noise
>
> Cheers,
>   Volker


Re: pull request: iwlwifi 2016-04-12

2016-08-06 Thread Emmanuel Grumbach
On Sun, Aug 7, 2016 at 7:35 AM, Grumbach, Emmanuel
 wrote:
>
> Hi Kalle,
>
> Here is a pull request for 4.6. I have here a patch that was merged to
> -next already, but clearly, it should have been routed through the
> current cycle's trees. Sorry about that.
> The patch is:


Wow.. I knew evolution was sometimes stupid, but this is new to me..
Obviously you should ignore that.
Sorry...

>
> commit cd49727e1a2bccc4ff008dde24c2f8430dd9e368
> Author: Ayala Beker 
> Date:   Wed Feb 3 15:36:52 2016 +0200
>
> iwlwifi: mvm: avoid to WARN about gscan capabilities
>
> Gscan capabilities were updated with new capabilities supported
> by the device. Update GSCAN capabilities TLV and avoid to WARN
> if the firmware does not have the new capabilities.
>
> It appears in -next as:
>
> commit a0b09f13036cedfd67c9cb4b9d05138e7022723d
> Author: Ayala Beker 
> Date:   Wed Feb 3 15:36:52 2016 +0200
>
> iwlwifi: mvm: update GSCAN capabilities
>
> Gscan capabilities were updated with new capabilities supported
> by the device. Update GSCAN capabilities TLV.
>
> The commit message wasn't good enough for the current cycle, so I
> rewrote it. Besides that one, all is fairly normal.
> Let me know if you have issues!
>
> Thanks.
>
>
> The following changes since commit 7fdf9663261cc77a516396fec82cee8a8ea07e76:
>
>   iwlwifi: mvm: fix memory leak in paging (2016-03-20 23:01:54 +0200)
>
> are available in the git repository at:
>
>   https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git 
> tags/iwlwifi-for-kalle-2016-04-12
>
> for you to fetch changes up to 2d25fb8b3a138706b63bd26ad72a95c58029954a:
>
>   iwlwifi: mvm: fix accessing Null pointer during fw dump collection 
> (2016-04-12 10:03:17 +0300)
>
> 
> * add new device IDs for 8265
> * fix a NULL pointer dereference when paging firmware asserts
> * remove a WARNING on gscan capabilities
> * fix MODULE_FIRMWARE for 8260
>
> 
> Ayala Beker (1):
>   iwlwifi: mvm: avoid to WARN about gscan capabilities
>
> Matti Gottlieb (1):
>   iwlwifi: mvm: fix accessing Null pointer during fw dump collection
>
> Oren Givon (1):
>   iwlwifi: add device IDs for the 8265 device
>
> Sara Sharon (1):
>   iwlwifi: 8000: fix MODULE_FIRMWARE input
>
>  drivers/net/wireless/intel/iwlwifi/iwl-8000.c   |  2 +-
>  drivers/net/wireless/intel/iwlwifi/iwl-drv.c| 26 
> ++
>  drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c |  6 --
>  drivers/net/wireless/intel/iwlwifi/mvm/fw.c |  2 ++
>  drivers/net/wireless/intel/iwlwifi/pcie/drv.c   | 10 ++
>  5 files changed, 27 insertions(+), 19 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] ath10k: silence firmware file probing warnings

2016-07-25 Thread Emmanuel Grumbach
On Sat, Jul 23, 2016 at 1:19 AM, Luis R. Rodriguez  wrote:
> On Fri, Jul 22, 2016 at 08:51:36AM -0400, Prarit Bhargava wrote:
>> On 07/22/2016 08:21 AM, Arend Van Spriel wrote:
>> >> Another option to solve to problem would be stop requesting not
>> >> available publicly firmware. However, I assume some drivers would
>> >> like to preserve that option.
>> >
>> > Actually, this is not the case with brcmfmac. We do need a firmware
>> > file, ie. brcm/brcmfmac4356-pcie.bin, and also request for a nvram file,
>> > ie. brcm/brcmfmac4356-pcie.txt. The latter is optional and the device
>> > works fine without it.
>> >
>> > What is still unclear to me is when request_firmware_direct() would fail
>> > and in what circumstances the udev helper is a valid callback. Can you
>> > explain such a scenario. Another question I have is what the reasons are
>> > behind the 60 seconds timeout.
>>
>> request_firmware_direct() will fail when the specified FW file is not 
>> present.
>> This is different from request_firmware() which implements a usermode helper 
>> to
>> potentially download firmware, or unpack a firmware image.
>>
>> Re: 60 second timeout ... The 60 second timeout with request_firmware() is
>> completely arbitrary.  There is no way for udev to signal back to the kernel
>> that userspace helper has not completed its actions, so the kernel has a 60 
>> dead
>> man timer-ish delay.
>
> Lets call it what it was: the 60 second timeout thing was simply a mistake.
> Its no longer 60 seconds anyway, and in fact its accepted a dreaded issue.
> What *we* should be doing is thinking about proper long term architecture now.
> Async probe was one solution to some issues, a new flexible firmware API
> that avoids the usermode helper 100% is another.
>
> Distros stuck with the fallback option should review their strategies,
> either disabling the fallback option, upgrade systemd, or use alternative
> solutions (opensuse has a good one).
>
>>  However I wonder if changing that will not broke the case when
>>  driver is build-in in the kernel and f/w is not yet available when
>>  driver start to initialize. Or maybe nowadays this is not the case
>>  any longer, i.e. the MODULE_FIRMWARE macros assure proper f/w
>>  images are build-in in the kernel or copied to initramfs?
>> >>>
>> >>> That is a nice idea, but I have not seen any change in that area. Could
>> >>> have missed it.
>> >>
>> >> I believe this is how the things are already done, IOW switching to
>> >> request_firmware_direct() in the driver should be no harm.
>> >
>> > Ok. What are the consequences when:
>> > - driver is built-in.
>> > - driver+firmware present on initramfs.
>> > - driver on initramfs, firmware only present on rootfs.
>> > - driver+firmware only on rootfs.
>> >
>> > I assume the third one would be considered a configuration issue.
>>
>> I think your question here can be answered by reading 
>> drivers/base/Kconfig:88,
>> and reading about those 4 config options.
>
> No, this documentation is terrible, I've posted some patches to help with this
> mess.
>
>> I could paraphrase it butI think the
>> Kconfig notes are better than I could explain it.  Note that this is how 
>> things
>> currently work with request_firmware_nowait().  IIRC 
>> request_firmware_nowait()
>> is just an asynchronous version of request_firmware().
>
> ... its a mess.
>

Awesome. I leave the code as is and ignore any RHEL bugs that are
related to that. If someone wants to improve all this, I'd be thankful
if he could do the work in the subsystem as Arend suggested.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] ath10k: silence firmware file probing warnings

2016-07-21 Thread Emmanuel Grumbach
On Thu, Jul 21, 2016 at 10:09 AM, Stanislaw Gruszka  wrote:
> On Tue, Jul 19, 2016 at 03:00:37PM +0200, Michal Kazior wrote:
>> Firmware files are versioned to prevent older
>> driver instances to load unsupported firmware
>> blobs. This is reflected with a fallback logic
>> which attempts to load several firmware files.
>>
>> This however produced a lot of unnecessary
>> warnings sometimes confusing users and leading
>> them to rename firmware files making things even
>> more confusing.
>
> This happens on kernels configured with
> CONFIG_FW_LOADER_USER_HELPER_FALLBACK and cause not only ugly warnings,
> but also 60 seconds delay before loading next firmware version.
> For some reason RHEL kernel needs above config option, so this
> patch is very welcome from my perspective.
>

Sorry for my ignorance but how does the firmware loading work if not
with udev's help? As you can imagine, iwlwifi is suffering from the
same problem and I would be interested in applying the same change,
but I'd love to understand a bit more :)
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: iwlwifi + wpa2-leap + multiple AP's = call trace

2016-07-14 Thread Emmanuel Grumbach
On Wed, Jul 13, 2016 at 9:33 PM, Ismael Farfán <sulfur...@gmail.com> wrote:
> Hi
>
> I'm using wicd, so changed from wext to nl80211 and I don't see the
> trace anymore... it still refuses to connect though, so I'll check
> what's wrong with my configuration.
>
> Do you want me to collect some information regarding wpa_supplicant
> and wext from my system?
> If so, how?

I am very busy right now, so I doubt  I will have the time to look at
it. So let's drop it unless it still doesn't work for you.

>
>
> 2016-07-13 11:31 GMT-05:00 Emmanuel Grumbach <egrumb...@gmail.com>:
>> On Jul 13, 2016 9:23 AM, "Arend Van Spriel" <arend.vanspr...@broadcom.com>
>> wrote:
>>>
>>>
>>>
>>> On 13-7-2016 2:29, Ismael Farfán wrote:
>>> > Hello list
>>> >
>>> > I searched this error around and didn't find anything, so here it goes.
>>> >
>>> > Today I tried to connect to an enterprise network, which means,
>>> > literally, tens of AP's sharing the same name... the network requieres
>>> > user/password authentication (wpa2-leap).
>>> >
>>> > I'm using Arch
>>> > $ uname -a
>>> > Linux 4.6.3-1-ARCH #1 SMP PREEMPT Fri Jun 24 21:19:13 CEST 2016 x86_64
>>> > GNU/Linux
>>> >
>>> > Since the thing just didn't connect, I checked dmesg and found this:
>>> >
>>> > Any ideas?
>>>
>>> From the stack trace it seems wpa_supplicant on Arch is using WEXT API.
>>> You could try and change it to use NL80211 API. Personally, I have not
>>> used Arch Linux so no idea where to change that.
>>>
>>> The warning is here [1]:
>>>
>>> 503 IWL_DEBUG_TE(mvm, "Add new TE, duration %d TU\n",
>>> 504  le32_to_cpu(te_cmd->duration));
>>> 505
>>> 506 spin_lock_bh(>time_event_lock);
>>> 507 if (WARN_ON(te_data->id != TE_MAX)) {
>>> 508 spin_unlock_bh(>time_event_lock);
>>> 509 return -EIO;
>>> 510 }
>>>
>>> It seems this function is called with te_data that is already in use,
>>> but that is my uneducated guess so I may be wrong.
>>>
>>
>> This is right :)
>>
>> Can you please record tracing of this?
>>
>> Thank you.
>>
>>> Regards,
>>> Arend
>>>
>>> [1]
>>>
>>> http://lxr.free-electrons.com/source/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c#L507
>>> >
>>> > [   83.030072] wifi0: aborting authentication with xx:xx:xx:xx:xx:xx
>>> > by local choice (Reason: 3=DEAUTH_LEAVING)
>>> > [   83.030073] [ cut here ]
>>> > [   83.030082] WARNING: CPU: 2 PID: 1087 at
>>> > drivers/net/wireless/intel/iwlwifi/mvm/time-event.c:507 iwl_mvm_tim
>>> > e_event_send_add+0x1c6/0x200 [iwlmvm]
>>> > [   83.030157] CPU: 2 PID: 1087 Comm: wpa_supplicant Tainted: G
>>> >O4.6.3-1-ARCH #1
>>> > [   83.030158] Hardware name: Notebook
>>> > P65_P67SA   /P65_P67SA
>>> > , BIOS 1.03.01 07/22/2015
>>> > [   83.030160]  0286 09e998bc 880403a5b940
>>> > 812e54c2
>>> > [   83.030162]    880403a5b980
>>> > 8107a6bb
>>> > [   83.030164]  01fb81a8a180 88041b443580 88041c329548
>>> > fffb
>>> > [   83.030167] Call Trace:
>>> > [   83.030172]  [] dump_stack+0x63/0x81
>>> > [   83.030174]  [] __warn+0xcb/0xf0
>>> > [   83.030176]  [] warn_slowpath_null+0x1d/0x20
>>> > [   83.030181]  []
>>> > iwl_mvm_time_event_send_add+0x1c6/0x200 [iwlmvm]
>>> > [   83.030184]  [] ? up+0x32/0x50
>>> > [   83.030187]  [] ? wake_up_klogd+0x3b/0x50
>>> > [   83.030189]  [] ? console_unlock+0x4e9/0x590
>>> > [   83.030193]  []
>>> > iwl_mvm_protect_session+0x220/0x280 [iwlmvm]
>>> > [   83.030196]  [] ? iwl_mvm_ref_sync+0x2e/0x140
>>> > [iwlmvm]
>>> > [   83.030199]  [] ? vprintk_default+0x1f/0x30
>>> > [   83.030202]  []
>>> > iwl_mvm_mac_mgd_prepare_tx+0x5a/0xa0 [iwlmvm]
>>> > [   83.030216]  [] ieee80211_mgd_deauth+0x338/0x4d0
>>> > [mac80211]
>>> > [   83.030219]  [] ? enqueue_entity+0x323/0xd70
>>> > [   83.030228]  [] 

Re: [PATCH RESEND] iwlwifi, Do not implement thermal zone unless ucode is loaded

2016-07-11 Thread Emmanuel Grumbach
On Mon, Jul 11, 2016 at 6:18 PM, Prarit Bhargava <pra...@redhat.com> wrote:
>
> Didn't get any feedback or review comments on this patch.  Resending ...
>
> P.

This change is obviously completely broken. It simply disables the
registration to thermal zone core.

>
> ---8<---
>
> The iwlwifi driver implements a thermal zone and hwmon device, but
> returns -EIO on temperature reads if the firmware isn't loaded.  This
> results in the error
>
> iwlwifi-virtual-0
> Adapter: Virtual device
> ERROR: Can't get value of subfeature temp1_input: I/O error
> temp1:N/A
>
> being output when using sensors from the lm-sensors package.  Since
> the temperature cannot be read unless the ucode is loaded there is no
> reason to add the interface only to have it return an error 100% of
> the time.
>
> This patch moves the firmware check to iwl_mvm_thermal_zone_register() and
> stops the thermal zone from being created if the ucode hasn't been loaded.
>
> Signed-off-by: Prarit Bhargava <pra...@redhat.com>
> Cc: Johannes Berg <johannes.b...@intel.com>
> Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
> Cc: Luca Coelho <luciano.coe...@intel.com>
> Cc: Intel Linux Wireless <linuxw...@intel.com>
> Cc: Kalle Valo <kv...@codeaurora.org>
> Cc: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>
> Cc: Sara Sharon <sara.sha...@intel.com>
> Cc: linux-wireless@vger.kernel.org
> Cc: net...@vger.kernel.org
> ---
>  drivers/net/wireless/intel/iwlwifi/mvm/tt.c |   13 +++--
>  1 file changed, 3 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c 
> b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
> index 58fc7b3c711c..64802659711f 100644
> --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
> +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
> @@ -634,11 +634,6 @@ static int iwl_mvm_tzone_get_temp(struct 
> thermal_zone_device *device,
>
> mutex_lock(>mutex);
>
> -   if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) {
> -   ret = -EIO;
> -   goto out;
> -   }
> -
> ret = iwl_mvm_get_temp(mvm, );
> if (ret)
> goto out;
> @@ -684,11 +679,6 @@ static int iwl_mvm_tzone_set_trip_temp(struct 
> thermal_zone_device *device,
>
> mutex_lock(>mutex);
>
> -   if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) {
> -   ret = -EIO;
> -   goto out;
> -   }
> -
> if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
> ret = -EINVAL;
> goto out;
> @@ -750,6 +740,9 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm 
> *mvm)
> return;
> }
>
> +   if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR))
> +   return;
> +
> BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
>
> mvm->tz_device.tzone = thermal_zone_device_register(name,
> --
> 1.7.9.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [GIT] Networking

2016-05-17 Thread Emmanuel Grumbach
On Wed, May 18, 2016 at 4:00 AM, Linus Torvalds
 wrote:
> On Tue, May 17, 2016 at 12:11 PM, David Miller  wrote:
>>
>> Highlights:
>
> Lowlights:
>
>  1) the iwlwifi driver seems to be broken
>
> My laptop that uses the intel 7680 iwlwifi module no longer connects
> to the network. It fails with a "Microcode SW error detected." and
> spews out register state over and over again.

Can we have the register state and the ASSERT / NMI / whatever that
goes along with it?
This clearly means that the firmware is crashing, but I don't know why,
I copied here the lines that I need from another bug with another
device with another firmware,
but the log that we will still explain what I need:

[  800.880402] iwlwifi :02:00.0: Start IWL Error Log Dump:
[  800.880406] iwlwifi :02:00.0: Status: 0x, count: 6
[  800.880409] iwlwifi :02:00.0: Loaded firmware version: 21.311951.0
[  800.880413] iwlwifi :02:00.0: 0x0394 | ADVANCED_SYSASSERT
[  800.880416] iwlwifi :02:00.0: 0x0220 | trm_hw_status0
[  800.880419] iwlwifi :02:00.0: 0x | trm_hw_status1
[  800.880422] iwlwifi :02:00.0: 0x0BD8 | branchlink2
[  800.880425] iwlwifi :02:00.0: 0x00026AC4 | interruptlink1
[  800.880428] iwlwifi :02:00.0: 0x | interruptlink2
[  800.880431] iwlwifi :02:00.0: 0x0001 | data1
[  800.880434] iwlwifi :02:00.0: 0x02039845 | data2
[  800.880437] iwlwifi :02:00.0: 0x0056 | data3
[  800.880440] iwlwifi :02:00.0: 0x8E4184A7 | beacon time
[  800.880443] iwlwifi :02:00.0: 0x30E2CB41 | tsf low
[  800.880446] iwlwifi :02:00.0: 0x0027 | tsf hi
[  800.880449] iwlwifi :02:00.0: 0x | time gp1
[  800.880451] iwlwifi :02:00.0: 0x2F842F8A | time gp2
[  800.880454] iwlwifi :02:00.0: 0x | uCode revision type
[  800.880457] iwlwifi :02:00.0: 0x0015 | uCode version major
[  800.880460] iwlwifi :02:00.0: 0x0004C28F | uCode version minor
[  800.880463] iwlwifi :02:00.0: 0x0201 | hw version
[  800.880466] iwlwifi :02:00.0: 0x00489008 | board version
[  800.880469] iwlwifi :02:00.0: 0x001C | hcmd
[  800.880472] iwlwifi :02:00.0: 0x24022000 | isr0
[  800.880475] iwlwifi :02:00.0: 0x0100 | isr1
[  800.880478] iwlwifi :02:00.0: 0x580A | isr2
[  800.880481] iwlwifi :02:00.0: 0x4041FCC1 | isr3
[  800.880483] iwlwifi :02:00.0: 0x | isr4
[  800.880486] iwlwifi :02:00.0: 0x00800110 | last cmd Id
[  800.880489] iwlwifi :02:00.0: 0x | wait_event
[  800.880492] iwlwifi :02:00.0: 0x02C8 | l2p_control
[  800.880495] iwlwifi :02:00.0: 0x00018030 | l2p_duration
[  800.880498] iwlwifi :02:00.0: 0x00BF | l2p_mhvalid
[  800.880501] iwlwifi :02:00.0: 0x00EF | l2p_addr_match
[  800.880503] iwlwifi :02:00.0: 0x000D | lmpm_pmg_sel
[  800.880506] iwlwifi :02:00.0: 0x30031805 | timestamp
[  800.880509] iwlwifi :02:00.0: 0xE0F0 | flow_handler




>
> The last thing it says before falling over is:
>
>   wlp1s0: authenticate with xx:xx:xx:xx:xx:xx
>   wlp1s0: send auth to xx:xx:xx:xx:xx:xx (try 1/3)
>   wlp1s0: send auth to xx:xx:xx:xx:xx:xx (try 2/3)
>
> and then it goes all titsup.
>
> I thought that it might be because I had downloaded one of the daily
> firmware versions (it calls itself iwlwifi-7260-17.ucode, but isn't a
> real release afaik - but it has worked fien for me before), but the
> problem persists with the ver-16 ucode too, so that wasn't it.
>
> I haven't bisected it, but there is absolutely nothing odd in my hardware.
>
> I do have a 802.11ac network, which apparently not everybody does,
> judging by previous bug-reports of mine..
>
> Intel iwlwifi people: please check this out.
>
>Linus
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] iwlwifi: mvm: don't override the rate with the AMSDU len

2016-05-04 Thread Emmanuel Grumbach
The TSO code creates A-MSDUs from a single large send. Each
A-MSDU is an skb and skb->len doesn't include the number of
bytes which need to be added for the headers being added
(subframe header, TCP header, IP header, SNAP, padding).

To be able to set the right value in the Tx command, we
put the number of bytes added by those headers in
driver_data in iwl_mvm_tx_tso and use this value in
iwl_mvm_set_tx_cmd.

The problem by setting this value in driver_data is that
it overrides the ieee80211_tx_info. The bug manifested
itself when we send P2P related frames in CCK since the
rate in ieee80211_tx_info is zero-ed. This of course is
a violation of the P2P specification.

To fix this, copy the original ieee80211_tx_info to the
stack and pass it to the functions which need it.
Assign the number of bytes added by the headers to the
driver_data inside the skb itself.

Fixes: a6d5e32f247c ("iwlwifi: mvm: send large SKBs to the transport")
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 83 +
 1 file changed, 48 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 75870e6..34731e2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -105,6 +105,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff 
*skb,
struct iwl_tx_cmd *tx_cmd,
struct ieee80211_tx_info *info, u8 sta_id)
 {
+   struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (void *)skb->data;
__le16 fc = hdr->frame_control;
u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags);
@@ -185,7 +186,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff 
*skb,
tx_cmd->tx_flags = cpu_to_le32(tx_flags);
/* Total # bytes to be transmitted */
tx_cmd->len = cpu_to_le16((u16)skb->len +
-   (uintptr_t)info->driver_data[0]);
+   (uintptr_t)skb_info->driver_data[0]);
tx_cmd->next_frame_len = 0;
tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
tx_cmd->sta_id = sta_id;
@@ -327,10 +328,11 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
  */
 static struct iwl_device_cmd *
 iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
- int hdrlen, struct ieee80211_sta *sta, u8 sta_id)
+ struct ieee80211_tx_info *info, int hdrlen,
+ struct ieee80211_sta *sta, u8 sta_id)
 {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-   struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+   struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
struct iwl_device_cmd *dev_cmd;
struct iwl_tx_cmd *tx_cmd;
 
@@ -350,10 +352,10 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff 
*skb,
 
iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control);
 
-   memset(>status, 0, sizeof(info->status));
-   memset(info->driver_data, 0, sizeof(info->driver_data));
+   memset(_info->status, 0, sizeof(skb_info->status));
+   memset(skb_info->driver_data, 0, sizeof(skb_info->driver_data));
 
-   info->driver_data[1] = dev_cmd;
+   skb_info->driver_data[1] = dev_cmd;
 
return dev_cmd;
 }
@@ -361,22 +363,25 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff 
*skb,
 int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
 {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-   struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+   struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
+   struct ieee80211_tx_info info;
struct iwl_device_cmd *dev_cmd;
struct iwl_tx_cmd *tx_cmd;
u8 sta_id;
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
-   if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU))
+   memcpy(, skb->cb, sizeof(info));
+
+   if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU))
return -1;
 
-   if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
-(!info->control.vif ||
- info->hw_queue != info->control.vif->cab_queue)))
+   if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
+(!info.control.vif ||
+ info.hw_queue != info.control.vif->cab_queue)))
return -1;
 
/* This holds the amsdu headers length */
-   info->driver_data[0] = (void *)(uintptr_t)0;
+   skb_info->driver_data[0] = (void *)(uintptr_t)0;
 
/*
 

[PATCH 2/4] iwlwifi: mvm: avoid to WARN about gscan capabilities

2016-04-12 Thread Emmanuel Grumbach
From: Ayala Beker <ayala.be...@intel.com>

Gscan capabilities were updated with new capabilities supported
by the device. Update GSCAN capabilities TLV and avoid to WARN
if the firmware does not have the new capabilities.

Signed-off-by: Ayala Beker <ayala.be...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index f899666..33d0d51 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1060,11 +1060,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
return -EINVAL;
}
 
-   if (WARN(fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) &&
-!gscan_capa,
-"GSCAN is supported but capabilities TLV is unavailable\n"))
+   /*
+* If ucode advertises that it supports GSCAN but GSCAN
+* capabilities TLV is not present, or if it has an old format,
+* warn and continue without GSCAN.
+*/
+   if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) &&
+   !gscan_capa) {
+   IWL_DEBUG_INFO(drv,
+  "GSCAN is supported but capabilities TLV is 
unavailable\n");
__clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT,
capa->_capa);
+   }
 
return 0;
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] iwlwifi: 8000: fix MODULE_FIRMWARE input

2016-04-12 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

The firwmare name for 8000 is iwlwifi-8000C. The C is
appended based on a value read from a register. This
allows to load different firwmare versions based on
the hardware step during development. Now that the
hardware development is completed, we can hard code
the 'C' and along the way, fix the input to
MODULE_FIRMWARE.

This fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=116041

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-8000.c |  2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  | 13 -
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
index 97be104..cf48122 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
@@ -93,7 +93,7 @@
 #define IWL8260_SMEM_OFFSET0x40
 #define IWL8260_SMEM_LEN   0x68000
 
-#define IWL8000_FW_PRE "iwlwifi-8000"
+#define IWL8000_FW_PRE "iwlwifi-8000C"
 #define IWL8000_MODULE_FIRMWARE(api) \
IWL8000_FW_PRE "-" __stringify(api) ".ucode"
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 33d0d51..9e45bf9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -238,19 +238,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool 
first)
snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode",
 name_pre, tag);
 
-   /*
-* Starting 8000B - FW name format has changed. This overwrites the
-* previous name and uses the new format.
-*/
-   if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
-   char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev);
-
-   if (rev_step != 'A')
-   snprintf(drv->firmware_name,
-sizeof(drv->firmware_name), "%s%c-%s.ucode",
-name_pre, rev_step, tag);
-   }
-
IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n",
   (drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
? "EXPERIMENTAL " : "",
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] iwlwifi: mvm: fix accessing Null pointer during fw dump collection

2016-04-12 Thread Emmanuel Grumbach
From: Matti Gottlieb <matti.gottl...@intel.com>

The firwmare file can come with data that is relevant for paging. This
data is availablet to the firmware upon request, but it stored in the
host's memory. During the firmware init flow, the driver configures the
firmware so that the firwmare knows where is the data.
When paging is used, the variable paging_mem_size is the number of bytes
that are available through paging. This variable is not zeror-ed if the
driver fails to configure the paging in the firmware, but the memory is
freed which is inconsistent.
This inconsistency led to a NULL pointer dereference in the code that
collects the debug data.

Fix this by zero-ing the paging_mem_size variable and NULLify the
relevant pointers, so that the code that collects the debug data will
know that the paging data is not available.

Signed-off-by: Matti Gottlieb <matti.gottl...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | 6 --
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
index 4856eac..6938cd3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
@@ -526,7 +526,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;
 
/* Make room for fw's virtual image pages, if it exists */
-   if (mvm->fw->img[mvm->cur_ucode].paging_mem_size)
+   if (mvm->fw->img[mvm->cur_ucode].paging_mem_size &&
+   mvm->fw_paging_db[0].fw_paging_block)
file_len += mvm->num_of_paging_blk *
(sizeof(*dump_data) +
 sizeof(struct iwl_fw_error_dump_paging) +
@@ -643,7 +644,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
}
 
/* Dump fw's virtual image */
-   if (mvm->fw->img[mvm->cur_ucode].paging_mem_size) {
+   if (mvm->fw->img[mvm->cur_ucode].paging_mem_size &&
+   mvm->fw_paging_db[0].fw_paging_block) {
for (i = 1; i < mvm->num_of_paging_blk + 1; i++) {
struct iwl_fw_error_dump_paging *paging;
struct page *pages =
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 594cd0d..09d895f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -144,9 +144,11 @@ void iwl_free_fw_paging(struct iwl_mvm *mvm)
 
__free_pages(mvm->fw_paging_db[i].fw_paging_block,
 get_order(mvm->fw_paging_db[i].fw_paging_size));
+   mvm->fw_paging_db[i].fw_paging_block = NULL;
}
kfree(mvm->trans->paging_download_buf);
mvm->trans->paging_download_buf = NULL;
+   mvm->trans->paging_db = NULL;
 
memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db));
 }
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] iwlwifi: add device IDs for the 8265 device

2016-04-12 Thread Emmanuel Grumbach
From: Oren Givon <oren.gi...@intel.com>

Add new 8265 series PCI IDs.

Signed-off-by: Oren Givon <oren.gi...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 05b9685..79d7cd7 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -479,8 +479,18 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x24F3, 0x0930, iwl8260_2ac_cfg)},
{IWL_PCI_DEVICE(0x24F3, 0x, iwl8265_2ac_cfg)},
{IWL_PCI_DEVICE(0x24FD, 0x0010, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x0110, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x1110, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x1010, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x0050, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x0150, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x9010, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x8110, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x8050, iwl8265_2ac_cfg)},
{IWL_PCI_DEVICE(0x24FD, 0x8010, iwl8265_2ac_cfg)},
{IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x9110, iwl8265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x24FD, 0x8130, iwl8265_2ac_cfg)},
 
 /* 9000 Series */
{IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)},
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: hardware restart on Intel 7260

2016-04-11 Thread Emmanuel Grumbach
Hi,

On Mon, Apr 11, 2016 at 5:09 PM, Johann Haarhoff  wrote:
>
> Hi
>
> (Please CC as I am not subscribed to the list)
>
> I'm seeing the following trace on a Lenovo Yoga 2 Pro with an Intel 7260 (rev 
> 6b).
>
> Kernel is 4.5 on using the latest -16 firmware from wireless.wiki.kernel.org. 
> I tried the -17 firmware from git.kernel.org with a
> very similar result.
>
> module was loaded with:
>
> options iwlwifi power_save=0 bt_coex_active=0 swcrypto=1

Can you try:
options iwlmvm power_scheme=1

>
> The trace is accompanied by a couple seconds where no data transfer can 
> happen (youtube stutters etc.), but other than that it seems
> to resume fine. This happens every 2-15 minutes if I am moving data.
>
> Disabling 11n fixes the problem, but that is not really an viable option.

That can help to know where the problem hides.

>
> Please let me know if there is anything I can add to help with the debugging.
>
> > Apr 11 15:52:30  kernel: [13827.165868] iwlwifi :01:00.0: Queue 2 stuck 
> > for 1 ms.
> > Apr 11 15:52:30  kernel: [13827.165878] iwlwifi :01:00.0: Current SW 
> > read_ptr 135 write_ptr 171

Meh... So what happens here is that the firmware is stuck while
transmitting. The driver detects this and as a workaround, resets the
firmware. The detection takes 10 seconds.
The only way to understand what is going on here is to take the
firmware from [1] and to run the steps to collect firmware debug data
from [2]. I recommend you open a bug on bugzilla.
Out of curiosity, did you try to work in DC mode (on battery, not
connected to the power)? A user reported that it helped [3].

[1] https://bugzilla.kernel.org/attachment.cgi?id=208381
[2] 
https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi/debugging#firmware_debugging
[3] https://bugzilla.kernel.org/show_bug.cgi?id=112931


>
>
> Thanks,
>
> Johann
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] mac80211: add an option to not disconnect on beacon loss

2016-04-05 Thread Emmanuel Grumbach
From: Avraham Stern <avraham.st...@intel.com>

Add the option to set mac80211 to not disconnect on beacon loss.
If this option is set, mac80211 will send a beacon loss event
to userspace but will not disconnect.
The beacon loss event is sent only once as long as no response
is received from the AP. If after receiving response from the AP the
beacon loss threshold is hit again, another beacon loss event will
be sent.
The default behavior remains as it was: probe the AP and disconnect
if the AP does not respond.

Signed-off-by: Avraham Stern <avraham.st...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
v2: fix the race
---
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/main.c|  2 ++
 net/mac80211/mlme.c| 15 ++-
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ff8d08b..ea4fef3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -356,6 +356,8 @@ enum ieee80211_sta_flags {
IEEE80211_STA_DISABLE_160MHZ= BIT(13),
IEEE80211_STA_DISABLE_WMM   = BIT(14),
IEEE80211_STA_ENABLE_RRM= BIT(15),
+   IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT = BIT(16),
+   IEEE80211_STA_BEACON_LOSS_REPORTED  = BIT(17),
 };
 
 struct ieee80211_mgd_auth_data {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 33c80de..6083256 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -554,6 +554,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
   NL80211_FEATURE_AP_SCAN;
 
+   wiphy_ext_feature_set(wiphy,
+ 
NL80211_EXT_FEATURE_BEACON_LOSS_DO_NOT_DISCONNECT);
 
if (!ops->set_key)
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d3c75ac..1c9823e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -128,6 +128,8 @@ void ieee80211_sta_reset_conn_monitor(struct 
ieee80211_sub_if_data *sdata)
if (ifmgd->probe_send_count)
ifmgd->probe_send_count = 0;
 
+   sdata->u.mgd.flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
+
if (ieee80211_hw_check(>local->hw, CONNECTION_MONITOR))
return;
 
@@ -1927,6 +1929,7 @@ static void ieee80211_set_associated(struct 
ieee80211_sub_if_data *sdata,
 
/* just to be sure */
ieee80211_stop_poll(sdata);
+   sdata->u.mgd.flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
 
ieee80211_led_assoc(local, 1);
 
@@ -1985,6 +1988,7 @@ static void ieee80211_set_disassoc(struct 
ieee80211_sub_if_data *sdata,
return;
 
ieee80211_stop_poll(sdata);
+   ifmgd->flags &= ~IEEE80211_STA_BEACON_LOSS_REPORTED;
 
ifmgd->associated = NULL;
netif_carrier_off(sdata->dev);
@@ -2432,8 +2436,12 @@ static void ieee80211_beacon_connection_loss_work(struct 
work_struct *work)
sdata_info(sdata, "Connection to AP %pM lost\n",
   ifmgd->bssid);
__ieee80211_disconnect(sdata);
-   } else {
+   } else if (!(ifmgd->flags & 
IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT)) {
ieee80211_mgd_probe_ap(sdata, true);
+   } else if (!(ifmgd->flags & IEEE80211_STA_BEACON_LOSS_REPORTED)) {
+   ieee80211_cqm_beacon_loss_notify(>vif,
+GFP_KERNEL);
+   ifmgd->flags |= IEEE80211_STA_BEACON_LOSS_REPORTED;
}
 }
 
@@ -4752,6 +4760,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data 
*sdata,
sdata->encrypt_headroom = ieee80211_cs_headroom(local, >crypto,
sdata->vif.type);
 
+   if (req->flags & ASSOC_REQ_BEACON_LOSS_DO_NOT_DISCONNECT)
+   ifmgd->flags |= IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT;
+   else
+   ifmgd->flags &= ~IEEE80211_STA_BEACON_LOSS_DO_NOT_DISCONNECT;
+
/* kick off associate process */
 
ifmgd->assoc_data = assoc_data;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] mac80211: close the SP when we enqueue frames during the SP

2016-04-05 Thread Emmanuel Grumbach
Since we enqueued the frame that was supposed to be sent
during the SP, and that frame may very well cary the
IEEE80211_TX_STATUS_EOSP bit, we may never close the SP
(WLAN_STA_SP will never be cleared). If that happens, we
will not open any new SP and will never respond to any poll
frame from the client.
Clear WLAN_STA_SP manually if a frame that was polled during
the SP is queued because of a starting A-MPDU session. The
client may not see the EOSP bit, but it will at least be
able to poll new frames in another SP.

Reported-by: Alesya Shapira <alesya.shap...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
v2: remove TODO comment
---
 net/mac80211/tx.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 597c8fe..9fbc1b6 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1116,6 +1116,12 @@ static bool ieee80211_tx_prep_agg(struct 
ieee80211_tx_data *tx,
reset_agg_timer = true;
} else {
queued = true;
+   if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
+   clear_sta_flag(tx->sta, WLAN_STA_SP);
+   ps_dbg(tx->sta->sdata,
+  "STA %pM aid %d: SP frame queued, close 
the SP w/o telling the peer\n",
+  tx->sta->sta.addr, tx->sta->sta.aid);
+   }
info->control.vif = >sdata->vif;
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS |
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/10] mac80211: remove rx_stats.last_rx update after sta alloc

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

There's no need to update rx_stats.last_rx after allocating
a station since it's already updated during allocation.

Signed-off-by: Johannes Berg 
---
 net/mac80211/ibss.c | 4 
 net/mac80211/ocb.c  | 2 --
 2 files changed, 6 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index fc32383..b3407db 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -649,8 +649,6 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, 
const u8 *bssid,
return NULL;
}
 
-   sta->rx_stats.last_rx = jiffies;
-
/* make sure mandatory rates are always added */
sband = local->hw.wiphy->bands[band];
sta->sta.supp_rates[band] = supp_rates |
@@ -1236,8 +1234,6 @@ void ieee80211_ibss_rx_no_sta(struct 
ieee80211_sub_if_data *sdata,
if (!sta)
return;
 
-   sta->rx_stats.last_rx = jiffies;
-
/* make sure mandatory rates are always added */
sband = local->hw.wiphy->bands[band];
sta->sta.supp_rates[band] = supp_rates |
diff --git a/net/mac80211/ocb.c b/net/mac80211/ocb.c
index 0be0aad..88e6ebb 100644
--- a/net/mac80211/ocb.c
+++ b/net/mac80211/ocb.c
@@ -75,8 +75,6 @@ void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data 
*sdata,
if (!sta)
return;
 
-   sta->rx_stats.last_rx = jiffies;
-
/* Add only mandatory rates for now */
sband = local->hw.wiphy->bands[band];
sta->sta.supp_rates[band] =
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/10] mac80211: fix RX u64 stats consistency on 32-bit platforms

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

On 32-bit platforms, the 64-bit counters we keep need to be protected
to be consistently read. Use the u64_stats_sync mechanism to do that.

In order to not end up with overly long lines, refactor the tidstats
assignments a bit.

Signed-off-by: Johannes Berg 
---
 net/mac80211/rx.c   |  6 +
 net/mac80211/sta_info.c | 72 ++---
 net/mac80211/sta_info.h |  5 +++-
 3 files changed, 54 insertions(+), 29 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 40981f8..1511bd1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1441,7 +1441,11 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
ieee80211_sta_rx_notify(rx->sdata, hdr);
 
sta->rx_stats.fragments++;
+
+   u64_stats_update_begin(>sta->rx_stats.syncp);
sta->rx_stats.bytes += rx->skb->len;
+   u64_stats_update_end(>sta->rx_stats.syncp);
+
if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
sta->rx_stats.last_signal = status->signal;
ewma_signal_add(>rx_stats_avg.signal, -status->signal);
@@ -2106,7 +2110,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
 * for non-QoS-data frames. Here we know it's a data
 * frame, so count MSDUs.
 */
+   u64_stats_update_begin(>sta->rx_stats.syncp);
rx->sta->rx_stats.msdu[rx->seqno_idx]++;
+   u64_stats_update_end(>sta->rx_stats.syncp);
}
 
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 81f1d6c..f097a5e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -335,6 +335,8 @@ struct sta_info *sta_info_alloc(struct 
ieee80211_sub_if_data *sdata,
sta->sdata = sdata;
sta->rx_stats.last_rx = jiffies;
 
+   u64_stats_init(>rx_stats.syncp);
+
sta->sta_state = IEEE80211_STA_NONE;
 
/* Mark TID as unreserved */
@@ -1971,6 +1973,41 @@ static void sta_set_rate_info_rx(struct sta_info *sta, 
struct rate_info *rinfo)
sta_stats_decode_rate(sta->local, rate, rinfo);
 }
 
+static void sta_set_tidstats(struct sta_info *sta,
+struct cfg80211_tid_stats *tidstats,
+int tid)
+{
+   struct ieee80211_local *local = sta->local;
+
+   if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) {
+   unsigned int start;
+
+   do {
+   start = u64_stats_fetch_begin(>rx_stats.syncp);
+   tidstats->rx_msdu = sta->rx_stats.msdu[tid];
+   } while (u64_stats_fetch_retry(>rx_stats.syncp, start));
+
+   tidstats->filled |= BIT(NL80211_TID_STATS_RX_MSDU);
+   }
+
+   if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) {
+   tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU);
+   tidstats->tx_msdu = sta->tx_stats.msdu[tid];
+   }
+
+   if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_RETRIES)) &&
+   ieee80211_hw_check(>hw, REPORTS_TX_ACK_STATUS)) {
+   tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_RETRIES);
+   tidstats->tx_msdu_retries = sta->status_stats.msdu_retries[tid];
+   }
+
+   if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_FAILED)) &&
+   ieee80211_hw_check(>hw, REPORTS_TX_ACK_STATUS)) {
+   tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_FAILED);
+   tidstats->tx_msdu_failed = sta->status_stats.msdu_failed[tid];
+   }
+}
+
 void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 {
struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -2025,7 +2062,12 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo)
 
if (!(sinfo->filled & (BIT(NL80211_STA_INFO_RX_BYTES64) |
   BIT(NL80211_STA_INFO_RX_BYTES {
-   sinfo->rx_bytes = sta->rx_stats.bytes;
+   unsigned int start;
+
+   do {
+   start = u64_stats_fetch_begin(>rx_stats.syncp);
+   sinfo->rx_bytes = sta->rx_stats.bytes;
+   } while (u64_stats_fetch_retry(>rx_stats.syncp, start));
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64);
}
 
@@ -2097,33 +2139,7 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo)
for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
struct cfg80211_tid_stats *tidstats = >pertid[i];
 
-   if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) {
-   tidstats->filled |= BIT(NL80211_TID_STATS_RX_MSDU);
-   tidstats->rx_msdu = sta->rx_stats.msdu[i];
-   }
-
-   if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) {
- 

[PATCH 03/10] mac80211: move semicolon out of CALL_RXH macro

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

Move the semicolon, people typically assume that and
once line already put a semicolon behind the "call".

Signed-off-by: Johannes Berg 
---
 net/mac80211/rx.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d979818..1df3a3e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3183,7 +3183,7 @@ static void ieee80211_rx_handlers(struct 
ieee80211_rx_data *rx,
res = rxh(rx);  \
if (res != RX_CONTINUE) \
goto rxh_next;  \
-   } while (0);
+   } while (0)
 
/* Lock here to avoid hitting all of the data used in the RX
 * path (e.g. key data, station data, ...) concurrently when
@@ -3201,30 +3201,30 @@ static void ieee80211_rx_handlers(struct 
ieee80211_rx_data *rx,
 */
rx->skb = skb;
 
-   CALL_RXH(ieee80211_rx_h_check_more_data)
-   CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
-   CALL_RXH(ieee80211_rx_h_sta_process)
-   CALL_RXH(ieee80211_rx_h_decrypt)
-   CALL_RXH(ieee80211_rx_h_defragment)
-   CALL_RXH(ieee80211_rx_h_michael_mic_verify)
+   CALL_RXH(ieee80211_rx_h_check_more_data);
+   CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll);
+   CALL_RXH(ieee80211_rx_h_sta_process);
+   CALL_RXH(ieee80211_rx_h_decrypt);
+   CALL_RXH(ieee80211_rx_h_defragment);
+   CALL_RXH(ieee80211_rx_h_michael_mic_verify);
/* must be after MMIC verify so header is counted in MPDU mic */
 #ifdef CONFIG_MAC80211_MESH
if (ieee80211_vif_is_mesh(>sdata->vif))
CALL_RXH(ieee80211_rx_h_mesh_fwding);
 #endif
-   CALL_RXH(ieee80211_rx_h_amsdu)
-   CALL_RXH(ieee80211_rx_h_data)
+   CALL_RXH(ieee80211_rx_h_amsdu);
+   CALL_RXH(ieee80211_rx_h_data);
 
/* special treatment -- needs the queue */
res = ieee80211_rx_h_ctrl(rx, frames);
if (res != RX_CONTINUE)
goto rxh_next;
 
-   CALL_RXH(ieee80211_rx_h_mgmt_check)
-   CALL_RXH(ieee80211_rx_h_action)
-   CALL_RXH(ieee80211_rx_h_userspace_mgmt)
-   CALL_RXH(ieee80211_rx_h_action_return)
-   CALL_RXH(ieee80211_rx_h_mgmt)
+   CALL_RXH(ieee80211_rx_h_mgmt_check);
+   CALL_RXH(ieee80211_rx_h_action);
+   CALL_RXH(ieee80211_rx_h_userspace_mgmt);
+   CALL_RXH(ieee80211_rx_h_action_return);
+   CALL_RXH(ieee80211_rx_h_mgmt);
 
  rxh_next:
ieee80211_rx_handlers_result(rx, res);
@@ -3247,10 +3247,10 @@ static void ieee80211_invoke_rx_handlers(struct 
ieee80211_rx_data *rx)
res = rxh(rx);  \
if (res != RX_CONTINUE) \
goto rxh_next;  \
-   } while (0);
+   } while (0)
 
-   CALL_RXH(ieee80211_rx_h_check_dup)
-   CALL_RXH(ieee80211_rx_h_check)
+   CALL_RXH(ieee80211_rx_h_check_dup);
+   CALL_RXH(ieee80211_rx_h_check);
 
ieee80211_rx_reorder_ampdu(rx, _release);
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/10] mac80211: allow passing transmitter station on RX

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

Sometimes drivers already looked up, or know out-of-band
from their device, which station transmitted a given RX
frame. Allow them to pass the station pointer to mac80211
to save the extra lookup.

Signed-off-by: Johannes Berg 
---
 drivers/net/wireless/intel/iwlwifi/dvm/rx.c   |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rx.c   |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |  2 +-
 include/net/mac80211.h|  7 ---
 net/mac80211/rx.c | 18 +-
 6 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c 
b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
index 52ab1e0..27ea61e 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
@@ -686,7 +686,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv 
*priv,
 
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 
-   ieee80211_rx_napi(priv->hw, skb, priv->napi);
+   ieee80211_rx_napi(priv->hw, NULL, skb, priv->napi);
 }
 
 static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 535134d..4918d5e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -1497,5 +1497,5 @@ void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
memcpy(IEEE80211_SKB_RXCB(skb), _status, sizeof(rx_status));
 
/* pass it as regular rx to mac80211 */
-   ieee80211_rx_napi(mvm->hw, skb, NULL);
+   ieee80211_rx_napi(mvm->hw, NULL, skb, NULL);
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index 145ec68..29dbfaf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -130,7 +130,7 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm 
*mvm,
fraglen, rxb->truesize);
}
 
-   ieee80211_rx_napi(mvm->hw, skb, napi);
+   ieee80211_rx_napi(mvm->hw, NULL, skb, napi);
 }
 
 /*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 615dea1..00d90e9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -194,7 +194,7 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm 
*mvm,
if (iwl_mvm_check_pn(mvm, skb, queue, sta))
kfree_skb(skb);
else
-   ieee80211_rx_napi(mvm->hw, skb, napi);
+   ieee80211_rx_napi(mvm->hw, NULL, skb, napi);
 }
 
 static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6e34675..fd5ec44 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3855,11 +3855,12 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
  * This function must be called with BHs disabled.
  *
  * @hw: the hardware this frame came in on
+ * @sta: the station the frame was received from, or %NULL
  * @skb: the buffer to receive, owned by mac80211 after this call
  * @napi: the NAPI context
  */
-void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb,
-  struct napi_struct *napi);
+void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+  struct sk_buff *skb, struct napi_struct *napi);
 
 /**
  * ieee80211_rx - receive frame
@@ -3883,7 +3884,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct 
sk_buff *skb,
  */
 static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-   ieee80211_rx_napi(hw, skb, NULL);
+   ieee80211_rx_napi(hw, NULL, skb, NULL);
 }
 
 /**
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 57a0ccd..6c3829d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3533,6 +3533,7 @@ static bool ieee80211_prepare_and_rx_handle(struct 
ieee80211_rx_data *rx,
  * be called with rcu_read_lock protection.
  */
 static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
+struct ieee80211_sta *pubsta,
 struct sk_buff *skb,
 struct napi_struct *napi)
 {
@@ -3542,7 +3543,6 @@ static void __ieee80211_rx_handle_packet(struct 
ieee80211_hw *hw,
__le16 fc;
struct ieee80211_rx_data rx;
struct ieee80211_sub_if_data *prev;
-   struct sta_info *sta, *prev_sta;
struct rhash_head *tmp;
int err = 0;
 
@@ -3578,7 +3578,14 @@ static void __ieee80211_rx_handle_packet(struct 
ieee80211_hw *hw,
 

[PATCH 04/10] mac80211: move averaged values out of rx_stats

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

Move the averaged values out of rx_stats and into rx_stats_avg,
to cleanly split them out. The averaged ones cannot be supported
for parallel RX in a per-CPU fashion, while the other values can
be collected per CPU and then combined/selected when needed.

Signed-off-by: Johannes Berg 
---
 net/mac80211/mesh_plink.c |  2 +-
 net/mac80211/rx.c |  4 ++--
 net/mac80211/sta_info.c   | 10 +-
 net/mac80211/sta_info.h   |  6 --
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index a07e93c..a261fdf 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -61,7 +61,7 @@ static bool rssi_threshold_check(struct ieee80211_sub_if_data 
*sdata,
s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold;
return rssi_threshold == 0 ||
   (sta &&
-   (s8)-ewma_signal_read(>rx_stats.avg_signal) >
+   (s8)-ewma_signal_read(>rx_stats_avg.signal) >
rssi_threshold);
 }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 1df3a3e..4ae3bf8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1455,7 +1455,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
sta->rx_stats.bytes += rx->skb->len;
if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
sta->rx_stats.last_signal = status->signal;
-   ewma_signal_add(>rx_stats.avg_signal, -status->signal);
+   ewma_signal_add(>rx_stats_avg.signal, -status->signal);
}
 
if (status->chains) {
@@ -1467,7 +1467,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
continue;
 
sta->rx_stats.chain_signal_last[i] = signal;
-   ewma_signal_add(>rx_stats.chain_signal_avg[i],
+   ewma_signal_add(>rx_stats_avg.chain_signal[i],
-signal);
}
}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 01e070c..4f19505 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -341,9 +341,9 @@ struct sta_info *sta_info_alloc(struct 
ieee80211_sub_if_data *sdata,
sta->reserved_tid = IEEE80211_TID_UNRESERVED;
 
sta->last_connected = ktime_get_seconds();
-   ewma_signal_init(>rx_stats.avg_signal);
-   for (i = 0; i < ARRAY_SIZE(sta->rx_stats.chain_signal_avg); i++)
-   ewma_signal_init(>rx_stats.chain_signal_avg[i]);
+   ewma_signal_init(>rx_stats_avg.signal);
+   for (i = 0; i < ARRAY_SIZE(sta->rx_stats_avg.chain_signal); i++)
+   ewma_signal_init(>rx_stats_avg.chain_signal[i]);
 
if (local->ops->wake_tx_queue) {
void *txq_data;
@@ -2056,7 +2056,7 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo)
 
if (!(sinfo->filled & BIT(NL80211_STA_INFO_SIGNAL_AVG))) {
sinfo->signal_avg =
-   -ewma_signal_read(>rx_stats.avg_signal);
+   -ewma_signal_read(>rx_stats_avg.signal);
sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL_AVG);
}
}
@@ -2072,7 +2072,7 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo)
sinfo->chain_signal[i] =
sta->rx_stats.chain_signal_last[i];
sinfo->chain_signal_avg[i] =
-   
-ewma_signal_read(>rx_stats.chain_signal_avg[i]);
+   
-ewma_signal_read(>rx_stats_avg.chain_signal[i]);
}
}
 
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index fc91290..67a604c 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -450,16 +450,18 @@ struct sta_info {
unsigned long fragments;
unsigned long dropped;
int last_signal;
-   struct ewma_signal avg_signal;
u8 chains;
s8 chain_signal_last[IEEE80211_MAX_CHAINS];
-   struct ewma_signal chain_signal_avg[IEEE80211_MAX_CHAINS];
int last_rate_idx;
u32 last_rate_flag;
u32 last_rate_vht_flag;
u8 last_rate_vht_nss;
u64 msdu[IEEE80211_NUM_TIDS + 1];
} rx_stats;
+   struct {
+   struct ewma_signal signal;
+   struct ewma_signal chain_signal[IEEE80211_MAX_CHAINS];
+   } rx_stats_avg;
 
/* Plus 1 for non-QoS frames */
__le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  

[PATCH 06/10] mac80211: add separate last_ack variable

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

Instead of touching the rx_stats.last_rx from the status path, introduce
and use a status_stats.last_ack variable. This will make rx_stats.last_rx
indicate when the last frame was received, making it available for real
"last_rx" and statistics gathering; statistics, when done per-CPU, will
need to figure out which place was updated last for those items where the
"last" value is exposed.

Signed-off-by: Johannes Berg 
---
 net/mac80211/ibss.c | 13 -
 net/mac80211/sta_info.c | 13 +++--
 net/mac80211/sta_info.h |  3 +++
 net/mac80211/status.c   |  4 ++--
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b3407db..4babd8a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -668,10 +668,11 @@ static int ieee80211_sta_active_ibss(struct 
ieee80211_sub_if_data *sdata)
rcu_read_lock();
 
list_for_each_entry_rcu(sta, >sta_list, list) {
+   unsigned long last_active = ieee80211_sta_last_active(sta);
+
if (sta->sdata == sdata &&
-   time_after(sta->rx_stats.last_rx +
-  IEEE80211_IBSS_MERGE_INTERVAL,
-  jiffies)) {
+   time_is_after_jiffies(last_active +
+ IEEE80211_IBSS_MERGE_INTERVAL)) {
active++;
break;
}
@@ -1255,11 +1256,13 @@ static void ieee80211_ibss_sta_expire(struct 
ieee80211_sub_if_data *sdata)
mutex_lock(>sta_mtx);
 
list_for_each_entry_safe(sta, tmp, >sta_list, list) {
+   unsigned long last_active = ieee80211_sta_last_active(sta);
+
if (sdata != sta->sdata)
continue;
 
-   if (time_after(jiffies, sta->rx_stats.last_rx + exp_time) ||
-   (time_after(jiffies, sta->rx_stats.last_rx + exp_rsn) &&
+   if (time_is_after_jiffies(last_active + exp_time) ||
+   (time_is_after_jiffies(last_active + exp_rsn) &&
 sta->sta_state != IEEE80211_STA_AUTHORIZED)) {
sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n",
sta->sta_state != IEEE80211_STA_AUTHORIZED ?
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 4f19505..b49e2fb 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1094,10 +1094,12 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data 
*sdata,
mutex_lock(>sta_mtx);
 
list_for_each_entry_safe(sta, tmp, >sta_list, list) {
+   unsigned long last_active = ieee80211_sta_last_active(sta);
+
if (sdata != sta->sdata)
continue;
 
-   if (time_after(jiffies, sta->rx_stats.last_rx + exp_time)) {
+   if (time_is_after_jiffies(last_active + exp_time)) {
sta_dbg(sta->sdata, "expiring inactive STA %pM\n",
sta->sta.addr);
 
@@ -2000,7 +2002,7 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo)
 
sinfo->connected_time = ktime_get_seconds() - sta->last_connected;
sinfo->inactive_time =
-   jiffies_to_msecs(jiffies - sta->rx_stats.last_rx);
+   jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta));
 
if (!(sinfo->filled & (BIT(NL80211_STA_INFO_TX_BYTES64) |
   BIT(NL80211_STA_INFO_TX_BYTES {
@@ -2186,3 +2188,10 @@ void sta_set_sinfo(struct sta_info *sta, struct 
station_info *sinfo)
sinfo->expected_throughput = thr;
}
 }
+
+unsigned long ieee80211_sta_last_active(struct sta_info *sta)
+{
+   if (time_after(sta->rx_stats.last_rx, sta->status_stats.last_ack))
+   return sta->rx_stats.last_rx;
+   return sta->status_stats.last_ack;
+}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 67a604c..0ad9a67 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -474,6 +474,7 @@ struct sta_info {
unsigned long last_tdls_pkt_time;
u64 msdu_retries[IEEE80211_NUM_TIDS + 1];
u64 msdu_failed[IEEE80211_NUM_TIDS + 1];
+   unsigned long last_ack;
} status_stats;
 
/* Updated from TX path only, no locking requirements */
@@ -683,4 +684,6 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
 void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
 void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
 
+unsigned long ieee80211_sta_last_active(struct sta_info *sta);
+
 #endif /* STA_INFO_H */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 6101deb..93a4608 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -188,7 +188,7 @@ static void 

[PATCH 07/10] mac80211: fix last RX rate data consistency

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

When storing the last_rate_* values in the RX code, there's nothing
to guarantee consistency, so a concurrent reader could see, e.g.
last_rate_idx on the new value, but last_rate_flag still on the old,
getting completely bogus values in the end.

To fix this, I lifted the sta_stats_encode_rate() function from my
old rate statistics code, which encodes the entire rate data into a
single 16-bit value, avoiding the consistency issue.

Signed-off-by: Johannes Berg 
---
 net/mac80211/rx.c   | 21 +
 net/mac80211/sta_info.c | 60 ++---
 net/mac80211/sta_info.h | 45 -
 3 files changed, 77 insertions(+), 49 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 4ae3bf8..40981f8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1421,16 +1421,9 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
sta->rx_stats.last_rx = jiffies;
if (ieee80211_is_data(hdr->frame_control) &&
-   !is_multicast_ether_addr(hdr->addr1)) {
-   sta->rx_stats.last_rate_idx =
-   status->rate_idx;
-   sta->rx_stats.last_rate_flag =
-   status->flag;
-   sta->rx_stats.last_rate_vht_flag =
-   status->vht_flag;
-   sta->rx_stats.last_rate_vht_nss =
-   status->vht_nss;
-   }
+   !is_multicast_ether_addr(hdr->addr1))
+   sta->rx_stats.last_rate =
+   sta_stats_encode_rate(status);
}
} else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) {
sta->rx_stats.last_rx = jiffies;
@@ -1440,12 +1433,8 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 * match the current local configuration when processed.
 */
sta->rx_stats.last_rx = jiffies;
-   if (ieee80211_is_data(hdr->frame_control)) {
-   sta->rx_stats.last_rate_idx = status->rate_idx;
-   sta->rx_stats.last_rate_flag = status->flag;
-   sta->rx_stats.last_rate_vht_flag = status->vht_flag;
-   sta->rx_stats.last_rate_vht_nss = status->vht_nss;
-   }
+   if (ieee80211_is_data(hdr->frame_control))
+   sta->rx_stats.last_rate = sta_stats_encode_rate(status);
}
 
if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index b49e2fb..81f1d6c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1928,43 +1928,47 @@ u8 sta_info_tx_streams(struct sta_info *sta)
>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
 }
 
-static void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
+static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate,
+ struct rate_info *rinfo)
 {
-   rinfo->flags = 0;
-
-   if (sta->rx_stats.last_rate_flag & RX_FLAG_HT) {
-   rinfo->flags |= RATE_INFO_FLAGS_MCS;
-   rinfo->mcs = sta->rx_stats.last_rate_idx;
-   } else if (sta->rx_stats.last_rate_flag & RX_FLAG_VHT) {
-   rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
-   rinfo->nss = sta->rx_stats.last_rate_vht_nss;
-   rinfo->mcs = sta->rx_stats.last_rate_idx;
-   } else {
+   rinfo->bw = (rate & STA_STATS_RATE_BW_MASK) >>
+   STA_STATS_RATE_BW_SHIFT;
+
+   if (rate & STA_STATS_RATE_VHT) {
+   rinfo->flags = RATE_INFO_FLAGS_VHT_MCS;
+   rinfo->mcs = rate & 0xf;
+   rinfo->nss = (rate & 0xf0) >> 4;
+   } else if (rate & STA_STATS_RATE_HT) {
+   rinfo->flags = RATE_INFO_FLAGS_MCS;
+   rinfo->mcs = rate & 0xff;
+   } else if (rate & STA_STATS_RATE_LEGACY) {
struct ieee80211_supported_band *sband;
-   int shift = ieee80211_vif_get_shift(>sdata->vif);
u16 brate;
-
-   sband = sta->local->hw.wiphy->bands[
-   ieee80211_get_sdata_band(sta->sdata)];
-   brate = sband->bitrates[sta->rx_stats.last_rate_idx].bitrate;
+   unsigned int shift;
+
+   sband = local->hw.wiphy->bands[(rate >> 4) & 0xf];
+   brate = sband->bitrates[rate & 0xf].bitrate;
+   if (rinfo->bw == RATE_INFO_BW_5)
+   shift = 2;
+   else if (rinfo->bw == 

[PATCH 09/10] mac80211: add fast-rx path

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

The regular RX path has a lot of code, but with a few
assumptions on the hardware it's possible to reduce the
amount of code significantly. Currently the assumptions
on the driver are the following:
 * hardware/driver reordering buffer (if supporting aggregation)
 * hardware/driver decryption & PN checking (if using encryption)
 * hardware/driver did de-duplication
 * hardware/driver did A-MSDU deaggregation
 * AP_LINK_PS is used (in AP mode)
 * no client powersave handling in mac80211 (in client mode)

of which some are actually checked per packet:
 * de-duplication
 * PN checking
 * decryption
and additionally packets must
 * not be A-MSDU (have been deaggregated by driver/device)
 * be data packets
 * not be fragmented
 * be unicast
 * have RFC 1042 header

Additionally dynamically we assume:
 * no encryption or CCMP/GCMP, TKIP/WEP/other not allowed
 * station must be authorized
 * 4-addr format not enabled

Some data needed for the RX path is cached in a new per-station
"fast_rx" structure, so that we only need to look at this and
the packet, no other memory when processing packets on the fast
RX path.

After doing the above per-packet checks, the data path collapses
down to a pretty simple conversion function taking advantage of
the data cached in the small fast_rx struct.

This should speed up the RX processing, and will make it easier
to reason about parallelizing RX (for which statistics will need
to be per-CPU still.)

Signed-off-by: Johannes Berg 
---
 include/linux/ieee80211.h  |  10 ++
 net/mac80211/cfg.c |  10 +-
 net/mac80211/ieee80211_i.h |   4 +
 net/mac80211/key.c |   1 +
 net/mac80211/mlme.c|   7 +
 net/mac80211/rx.c  | 344 +
 net/mac80211/sta_info.c|   2 +
 net/mac80211/sta_info.h|  34 +
 8 files changed, 409 insertions(+), 3 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index bf9706c..113bfc4 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -638,6 +638,16 @@ static inline bool ieee80211_is_first_frag(__le16 seq_ctrl)
return (seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0;
 }
 
+/**
+ * ieee80211_is_frag - check if a frame is a fragment
+ * @hdr: 802.11 header of the frame
+ */
+static inline bool ieee80211_is_frag(struct ieee80211_hdr *hdr)
+{
+   return ieee80211_has_morefrags(hdr->frame_control) ||
+  hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG);
+}
+
 struct ieee80211s_hdr {
u8 flags;
u8 ttl;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 62a90f2..484bcdb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -65,11 +65,13 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
return ret;
 
if (type == NL80211_IFTYPE_AP_VLAN &&
-   params && params->use_4addr == 0)
+   params && params->use_4addr == 0) {
RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
-   else if (type == NL80211_IFTYPE_STATION &&
-params && params->use_4addr >= 0)
+   ieee80211_check_fast_rx_iface(sdata);
+   } else if (type == NL80211_IFTYPE_STATION &&
+  params && params->use_4addr >= 0) {
sdata->u.mgd.use_4addr = params->use_4addr;
+   }
 
if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
struct ieee80211_local *local = sdata->local;
@@ -1367,6 +1369,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 
rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
new_4addr = true;
+   ieee80211_check_fast_rx_iface(vlansdata);
}
 
if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
@@ -1889,6 +1892,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
else
sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
+   ieee80211_check_fast_rx_iface(sdata);
}
 
if (params->ht_opmode >= 0) {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 0008f28..d0f6534 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1496,6 +1496,10 @@ u64 ieee80211_mgmt_tx_cookie(struct ieee80211_local 
*local);
 int ieee80211_attach_ack_skb(struct ieee80211_local *local, struct sk_buff 
*skb,
 u64 *cookie, gfp_t gfp);
 
+void ieee80211_check_fast_rx(struct sta_info *sta);
+void ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata);
+void ieee80211_clear_fast_rx(struct sta_info *sta);
+
 /* STA code */
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/key.c 

[PATCH 10/10] mac80211: enable collecting station statistics per-CPU

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

If the driver advertises the new HW flag USE_RSS, make the
station statistics on the fast-rx path per-CPU. This will
enable calling the RX in parallel, only hitting locking or
shared cachelines when the fast-RX path isn't available.

Signed-off-by: Johannes Berg 
---
 include/net/mac80211.h  |   4 ++
 net/mac80211/debugfs.c  |   1 +
 net/mac80211/rx.c   |  37 ++---
 net/mac80211/sta_info.c | 108 +---
 net/mac80211/sta_info.h |  36 +---
 5 files changed, 140 insertions(+), 46 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index fd5ec44..5f4b4c7 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1980,6 +1980,9 @@ struct ieee80211_txq {
  * order and does not need to manage its own reorder buffer or BA session
  * timeout.
  *
+ * @IEEE80211_HW_USES_RSS: The device uses RSS and thus requires parallel RX,
+ * which implies using per-CPU station statistics.
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2017,6 +2020,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_BEACON_TX_STATUS,
IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
IEEE80211_HW_SUPPORTS_REORDERING_BUFFER,
+   IEEE80211_HW_USES_RSS,
 
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 4ab5c52..52ed2af 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -127,6 +127,7 @@ static const char *hw_flag_names[] = {
FLAG(BEACON_TX_STATUS),
FLAG(NEEDS_UNIQUE_STA_ADDR),
FLAG(SUPPORTS_REORDERING_BUFFER),
+   FLAG(USES_RSS),
 #undef FLAG
 };
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9bdb009..012be85 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3509,6 +3509,8 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
ether_addr_copy(fastrx.rfc1042_hdr, rfc1042_header);
ether_addr_copy(fastrx.vif_addr, sdata->vif.addr);
 
+   fastrx.uses_rss = ieee80211_hw_check(>hw, USES_RSS);
+
/* fast-rx doesn't do reordering */
if (ieee80211_hw_check(>hw, AMPDU_AGGREGATION) &&
!ieee80211_hw_check(>hw, SUPPORTS_REORDERING_BUFFER))
@@ -3652,6 +3654,10 @@ static bool ieee80211_invoke_fast_rx(struct 
ieee80211_rx_data *rx,
u8 da[ETH_ALEN];
u8 sa[ETH_ALEN];
} addrs __aligned(2);
+   struct ieee80211_sta_rx_stats *stats = >rx_stats;
+
+   if (fast_rx->uses_rss)
+   stats = this_cpu_ptr(sta->pcpu_rx_stats);
 
/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
 * to a common data structure; drivers can implement that per queue
@@ -3733,29 +3739,32 @@ static bool ieee80211_invoke_fast_rx(struct 
ieee80211_rx_data *rx,
}
 
/* statistics part of ieee80211_rx_h_sta_process() */
-   sta->rx_stats.last_rx = jiffies;
-   sta->rx_stats.last_rate = sta_stats_encode_rate(status);
+   stats->last_rx = jiffies;
+   stats->last_rate = sta_stats_encode_rate(status);
 
-   sta->rx_stats.fragments++;
+   stats->fragments++;
 
if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
-   sta->rx_stats.last_signal = status->signal;
-   ewma_signal_add(>rx_stats_avg.signal, -status->signal);
+   stats->last_signal = status->signal;
+   if (!fast_rx->uses_rss)
+   ewma_signal_add(>rx_stats_avg.signal,
+   -status->signal);
}
 
if (status->chains) {
int i;
 
-   sta->rx_stats.chains = status->chains;
+   stats->chains = status->chains;
for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
int signal = status->chain_signal[i];
 
if (!(status->chains & BIT(i)))
continue;
 
-   sta->rx_stats.chain_signal_last[i] = signal;
-   ewma_signal_add(>rx_stats_avg.chain_signal[i],
-   -signal);
+   stats->chain_signal_last[i] = signal;
+   if (!fast_rx->uses_rss)
+   
ewma_signal_add(>rx_stats_avg.chain_signal[i],
+   -signal);
}
}
/* end of statistics */
@@ -3780,10 +3789,10 @@ static bool ieee80211_invoke_fast_rx(struct 
ieee80211_rx_data *rx,
 * for non-QoS-data frames. Here we know it's a data
 * frame, so count MSDUs.
 */
-   u64_stats_update_begin(>rx_stats.syncp);
-   sta->rx_stats.msdu[rx->seqno_idx]++;
-   sta->rx_stats.bytes += orig_len;
-   u64_stats_update_end(>rx_stats.syncp);
+   

[PATCH 02/10] mac80211: count MSDUs in A-MSDU properly

2016-03-31 Thread Emmanuel Grumbach
From: Johannes Berg 

For the RX MSDU statistics, we need to count the number of
MSDUs created and accepted from an A-MSDU. Right now, all
frames in any A-MSDUs were completely ignored. Fix this by
moving the RX MSDU statistics accounting into the deliver
function.

Signed-off-by: Johannes Berg 
---
 net/mac80211/rx.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6c3829d..d979818 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2111,6 +2111,15 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
 
ieee80211_rx_stats(dev, skb->len);
 
+   if (rx->sta) {
+   /* The seqno index has the same property as needed
+* for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
+* for non-QoS-data frames. Here we know it's a data
+* frame, so count MSDUs.
+*/
+   rx->sta->rx_stats.msdu[rx->seqno_idx]++;
+   }
+
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
!(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
@@ -2397,15 +2406,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
return RX_DROP_MONITOR;
 
-   if (rx->sta) {
-   /* The seqno index has the same property as needed
-* for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
-* for non-QoS-data frames. Here we know it's a data
-* frame, so count MSDUs.
-*/
-   rx->sta->rx_stats.msdu[rx->seqno_idx]++;
-   }
-
/*
 * Send unexpected-4addr-frame event to hostapd. For older versions,
 * also drop the frame to cooked monitor interfaces.
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 28/43] iwlwifi: mvm: remove uneeded D0I3 checking

2016-03-30 Thread Emmanuel Grumbach
From: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>

The driver can read the current state during D0I3,
therefore there is no reason not to do it.

Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 8d27137..3f5df76 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -787,9 +787,6 @@ static int iwl_mvm_tcool_get_cur_state(struct 
thermal_cooling_device *cdev,
 {
struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata);
 
-   if (test_bit(IWL_MVM_STATUS_IN_D0I3, >status))
-   return -EBUSY;
-
*state = mvm->cooling_dev.cur_state;
 
return 0;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 41/43] iwlwifi: mvm: fix inconsistent lock in dqa mode

2016-03-30 Thread Emmanuel Grumbach
From: Liad Kaufman <liad.kauf...@intel.com>

When working in DQA mode, there is a lockdep log warning
about an inconsistent state of the mvmsta->lock and the
mvm->queue_info_lock. Fix this. This mode is not activated
for now.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index e157bd5..12614b7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -296,7 +296,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
 
lockdep_assert_held(>mutex);
 
-   spin_lock(>queue_info_lock);
+   spin_lock_bh(>queue_info_lock);
 
/*
 * Non-QoS, QoS NDP and MGMT frames should go to a MGMT queue, if one
@@ -324,7 +324,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
if (queue >= 0)
mvm->queue_info[queue].setup_reserved = false;
 
-   spin_unlock(>queue_info_lock);
+   spin_unlock_bh(>queue_info_lock);
 
/* TODO: support shared queues for same RA */
if (queue < 0)
@@ -402,12 +402,12 @@ static void iwl_mvm_tx_deferred_stream(struct iwl_mvm 
*mvm,
 
__skb_queue_head_init(_tx);
 
+   /* Disable bottom-halves when entering TX path */
+   local_bh_disable();
spin_lock(>lock);
skb_queue_splice_init(_data->deferred_tx_frames, _tx);
spin_unlock(>lock);
 
-   /* Disable bottom-halves when entering TX path */
-   local_bh_disable();
while ((skb = __skb_dequeue(_tx)))
if (no_queue || iwl_mvm_tx_skb(mvm, skb, sta))
ieee80211_free_txskb(mvm->hw, skb);
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 31/43] iwlwifi: edit the 9000 series PCI IDs

2016-03-30 Thread Emmanuel Grumbach
From: Oren Givon <oren.gi...@intel.com>

Edit some of the 9560 series and 5165 series PCI IDs.
These devices do not exist yet.

Signed-off-by: Oren Givon <oren.gi...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index fb8b5ec..41c6dd5 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -483,17 +483,19 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x24FD, 0x0810, iwl8265_2ac_cfg)},
 
 /* 9000 Series */
+   {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9560_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x2010, iwl5165_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x2526, 0x0A10, iwl9560_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x2526, 0x1420, iwl5165_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x2526, 0x0010, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x0310, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x0510, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x0710, iwl5165_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x2526, 0x0210, iwl9560_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x2526, 0x0410, iwl9560_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x2526, 0x0610, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x9DF0, 0x0210, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x9DF0, 0x0410, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x9DF0, 0x0610, iwl9560_2ac_cfg)},
 #endif /* CONFIG_IWLMVM */
 
{0}
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/43] iwlwifi: mvm: support dumping UMAC internal txfifos

2016-03-30 Thread Emmanuel Grumbach
From: Golan Ben-Ami <golan.ben@intel.com>

In case of FW error, support dumping the UMAC internal txfifos.
To do so, support version 2 of shared memory cfg command, which
contains the sizes of the internal txfifos, and move the command
to the system group.

Signed-off-by: Golan Ben-Ami <golan.ben@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 .../net/wireless/intel/iwlwifi/iwl-fw-error-dump.h |  1 +
 drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h   |  3 +
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h  | 12 
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h| 17 -
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c| 79 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c| 28 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |  3 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   |  8 +++
 8 files changed, 146 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-error-dump.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fw-error-dump.h
index 8425e1a..09b7ea2 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-error-dump.h
@@ -105,6 +105,7 @@ enum iwl_fw_error_dump_type {
IWL_FW_ERROR_DUMP_RB = 11,
IWL_FW_ERROR_DUMP_PAGING = 12,
IWL_FW_ERROR_DUMP_RADIO_REG = 13,
+   IWL_FW_ERROR_DUMP_INTERNAL_TXF = 14,
 
IWL_FW_ERROR_DUMP_MAX,
 };
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
index 15ec4e2..3a72b97 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
@@ -324,6 +324,8 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
  * @IWL_UCODE_TLV_CAPA_CTDP_SUPPORT: supports cTDP command
  * @IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED: supports usniffer enabled in
  * regular image.
+ * @IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG: support getting more shared
+ * memory addresses from the firmware.
  *
  * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
  */
@@ -361,6 +363,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT  = (__force 
iwl_ucode_tlv_capa_t)75,
IWL_UCODE_TLV_CAPA_CTDP_SUPPORT = (__force 
iwl_ucode_tlv_capa_t)76,
IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED = (__force 
iwl_ucode_tlv_capa_t)77,
+   IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG= (__force 
iwl_ucode_tlv_capa_t)80,
 
NUM_IWL_UCODE_TLV_CAPA
 #ifdef __CHECKER__
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index c46e596..6c1d20d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2016Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2016Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -345,6 +347,16 @@ enum secure_load_status_reg {
 #define TXF_READ_MODIFY_DATA   (0xa00448)
 #define TXF_READ_MODIFY_ADDR   (0xa0044c)
 
+/* UMAC Internal Tx Fifo */
+#define TXF_CPU2_FIFO_ITEM_CNT (0xA00538)
+#define TXF_CPU2_WR_PTR(0xA00514)
+#define TXF_CPU2_RD_PTR(0xA00510)
+#define TXF_CPU2_FENCE_PTR (0xA00518)
+#define TXF_CPU2_LOCK_FENCE(0xA00524)
+#define TXF_CPU2_NUM   (0xA0053C)
+#define TXF_CPU2_READ_MODIFY_DATA  (0xA00548)
+#define TXF_CPU2_READ_MODIFY_ADDR  (0xA0054C)
+
 /* Radio registers access */
 #define RSP_RADIO_CMD  (0xa02804)
 #define RSP_RADIO_RDDAT(0xa02814)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index 4a0fc47..61711b1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -287,6 +287,10 @@ enum iwl_phy_ops_subcmd_ids {
DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
 };
 
+enum iwl_system_subcmd_ids {
+   SHARED_MEM_CFG_CMD = 0x0,
+};
+
 enum iwl_data_path_subcmd_ids {
UPDATE_MU_GROUPS_CMD = 0x1,
TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2,
@@ -302,6 +306,7 @@ enum iwl_prot_offload_subcmd_ids {
 enum {
LEGACY_GROUP = 0x0,
LONG_GROUP = 0x1,
+   SYSTEM_GROUP = 0x2,
PHY_OPS_GROUP = 0x4,
DAT

[PATCH 25/43] iwlwifi: mvm: report checksum is done also for IPv6 packets

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

Currently the code checks if hardware reported both L4 and L3
checksums as valid, and only then reports it as validated to
the stack.
However, IPv6 does not have checksum at all and the L3 checksum
valid bit is always off for IPv6 packets, with the result of the
stack re-validating L4 checksum.
Fix code to set CHECKSUM_UNNECESSARY also for IPv6 packets whose
TCP/UDP checksum was verified.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h | 15 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c  |  9 +++--
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
index 7a16e55..4c086d0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
@@ -268,12 +268,25 @@ enum iwl_rx_mpdu_amsdu_info {
IWL_RX_MPDU_AMSDU_LAST_SUBFRAME = 0x80,
 };
 
+enum iwl_rx_l3_proto_values {
+   IWL_RX_L3_TYPE_NONE,
+   IWL_RX_L3_TYPE_IPV4,
+   IWL_RX_L3_TYPE_IPV4_FRAG,
+   IWL_RX_L3_TYPE_IPV6_FRAG,
+   IWL_RX_L3_TYPE_IPV6,
+   IWL_RX_L3_TYPE_IPV6_IN_IPV4,
+   IWL_RX_L3_TYPE_ARP,
+   IWL_RX_L3_TYPE_EAPOL,
+};
+
+#define IWL_RX_L3_PROTO_POS 4
+
 enum iwl_rx_l3l4_flags {
IWL_RX_L3L4_IP_HDR_CSUM_OK  = BIT(0),
IWL_RX_L3L4_TCP_UDP_CSUM_OK = BIT(1),
IWL_RX_L3L4_TCP_FIN_SYN_RST_PSH = BIT(2),
IWL_RX_L3L4_TCP_ACK = BIT(3),
-   IWL_RX_L3L4_L3_PROTO_MASK   = 0xf << 4,
+   IWL_RX_L3L4_L3_PROTO_MASK   = 0xf << IWL_RX_L3_PROTO_POS,
IWL_RX_L3L4_L4_PROTO_MASK   = 0xf << 8,
IWL_RX_L3L4_RSS_HASH_MASK   = 0xf << 12,
 };
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 9a54f2d..b2bc3d9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -294,10 +294,15 @@ static void iwl_mvm_rx_csum(struct ieee80211_sta *sta,
 {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
+   u16 flags = le16_to_cpu(desc->l3l4_flags);
+   u8 l3_prot = (u8)((flags & IWL_RX_L3L4_L3_PROTO_MASK) >>
+ IWL_RX_L3_PROTO_POS);
 
if (mvmvif->features & NETIF_F_RXCSUM &&
-   desc->l3l4_flags & cpu_to_le16(IWL_RX_L3L4_IP_HDR_CSUM_OK) &&
-   desc->l3l4_flags & cpu_to_le16(IWL_RX_L3L4_TCP_UDP_CSUM_OK))
+   flags & IWL_RX_L3L4_TCP_UDP_CSUM_OK &&
+   (flags & IWL_RX_L3L4_IP_HDR_CSUM_OK ||
+l3_prot == IWL_RX_L3_TYPE_IPV6 ||
+l3_prot == IWL_RX_L3_TYPE_IPV6_FRAG))
skb->ip_summed = CHECKSUM_UNNECESSARY;
 }
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 29/43] iwlwifi: pcie: request one more interrupt vector

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

We want to request an interrupt vector for RSS queue per CPU,
one vector for fallback queue, and one for non-rx interrupts.
Future patch will make sure that no RSS traffic is directed to
fallback queue.
This will enable us to enable fast path on traffic that otherwise
would have been received on the fallback queue.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 0c40209..f1a506b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1435,7 +1435,7 @@ static void iwl_pcie_set_interrupt_capa(struct pci_dev 
*pdev,
int ret, i;
 
if (trans->cfg->mq_rx_supported) {
-   max_vector = min_t(u32, (num_possible_cpus() + 1),
+   max_vector = min_t(u32, (num_possible_cpus() + 2),
   IWL_MAX_RX_HW_QUEUES);
for (i = 0; i < max_vector; i++)
trans_pcie->msix_entries[i].entry = i;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 37/43] iwlwifi: mvm: enable TCP/UDP checksum support for 9000 family

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

Declare and enable support of RX and TX checksum for 9000 family.
Configure offload_assist in the TX cmd accordingly to support
TX csum.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-9000.c |   1 +
 drivers/net/wireless/intel/iwlwifi/iwl-config.h   |   2 +
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |  13 +--
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 124 +-
 4 files changed, 133 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
index 277396a..1f25ba6 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
@@ -137,6 +137,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.dccm2_len = IWL9000_DCCM2_LEN, \
.smem_offset = IWL9000_SMEM_OFFSET, \
.smem_len = IWL9000_SMEM_LEN,   \
+   .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,   \
.thermal_params = _tt_params,   \
.apmg_not_supported = true, \
.mq_rx_supported = true,\
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 8cbd248..b002557 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -131,6 +131,8 @@ enum iwl_led_mode {
 #define IWL_MAX_WD_TIMEOUT 12
 
 #define IWL_DEFAULT_MAX_TX_POWER 22
+#define IWL_TX_CSUM_NETIF_FLAGS (NETIF_F_IPV6_CSUM | NETIF_F_IP_CSUM |\
+NETIF_F_TSO | NETIF_F_TSO6)
 
 /* Antenna presence definitions */
 #defineANT_NONE0x0
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 115d7aa..4f5ec49 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -665,12 +665,13 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
}
 
hw->netdev_features |= mvm->cfg->features;
-   if (!iwl_mvm_is_csum_supported(mvm))
-   hw->netdev_features &= ~NETIF_F_RXCSUM;
-
-   if (IWL_MVM_SW_TX_CSUM_OFFLOAD)
-   hw->netdev_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-   NETIF_F_TSO | NETIF_F_TSO6;
+   if (!iwl_mvm_is_csum_supported(mvm)) {
+   hw->netdev_features &= ~(IWL_TX_CSUM_NETIF_FLAGS |
+NETIF_F_RXCSUM);
+   /* We may support SW TX CSUM */
+   if (IWL_MVM_SW_TX_CSUM_OFFLOAD)
+   hw->netdev_features |= IWL_TX_CSUM_NETIF_FLAGS;
+   }
 
ret = ieee80211_register_hw(mvm->hw);
if (ret)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 24cff98..efb9b98 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -67,6 +67,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "iwl-trans.h"
 #include "iwl-eeprom-parse.h"
@@ -98,6 +99,111 @@ iwl_mvm_bar_check_trigger(struct iwl_mvm *mvm, const u8 
*addr,
addr, tid, ssn);
 }
 
+#define OPT_HDR(type, skb, off) \
+   (type *)(skb_network_header(skb) + (off))
+
+static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
+   struct ieee80211_hdr *hdr,
+   struct ieee80211_tx_info *info,
+   struct iwl_tx_cmd *tx_cmd)
+{
+#if IS_ENABLED(CONFIG_INET)
+   u16 mh_len = ieee80211_hdrlen(hdr->frame_control);
+   u16 offload_assist = le16_to_cpu(tx_cmd->offload_assist);
+   u8 protocol = 0;
+
+   /*
+* Do not compute checksum if already computed or if transport will
+* compute it
+*/
+   if (skb->ip_summed != CHECKSUM_PARTIAL || IWL_MVM_SW_TX_CSUM_OFFLOAD)
+   return;
+
+   /* We do not expect to be requested to csum stuff we do not support */
+   if (WARN_ONCE(!(mvm->hw->netdev_features & IWL_TX_CSUM_NETIF_FLAGS) ||
+ (skb->protocol != htons(ETH_P_IP) &&
+  skb->protocol != htons(ETH_P_IPV6)),
+ "No support for requested checksum\n")) {
+   skb_checksum_help(skb);
+   return;
+   }
+
+   if (skb->protocol == htons(ETH_P_IP)) {
+   protocol = ip_hdr(skb)->protocol;
+   } else {
+#if IS_ENABLE

[PATCH 32/43] iwlwifi: mvm: use bss client queue for bss station

2016-03-30 Thread Emmanuel Grumbach
From: Liad Kaufman <liad.kauf...@intel.com>

Use the reserved BSS Client queue when connecting to an AP
in DQA mode.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h |  3 +++
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c| 18 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index 8217eb2..9652687 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -89,6 +89,8 @@ enum {
 /*
  * DQA queue numbers
  *
+ * @IWL_MVM_DQA_BSS_CLIENT_QUEUE: a queue reserved for BSS activity, to ensure
+ * that we are never left without the possibility to connect to an AP.
  * @IWL_MVM_DQA_MIN_MGMT_QUEUE: first TXQ in pool for MGMT and non-QOS frames.
  * Each MGMT queue is mapped to a single STA
  * MGMT frames are frames that return true on ieee80211_is_mgmt()
@@ -100,6 +102,7 @@ enum {
  * @IWL_MVM_DQA_MAX_DATA_QUEUE: last TXQ in pool for DATA frames
  */
 enum iwl_mvm_dqa_txq {
+   IWL_MVM_DQA_BSS_CLIENT_QUEUE = 4,
IWL_MVM_DQA_MIN_MGMT_QUEUE = 5,
IWL_MVM_DQA_MAX_MGMT_QUEUE = 8,
IWL_MVM_DQA_MIN_DATA_QUEUE = 10,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 3f36a66..e157bd5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -336,7 +336,8 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
 * as aggregatable.
 * Mark all DATA queues as allowing to be aggregated at some point
 */
-   cfg.aggregate = (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE);
+   cfg.aggregate = (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE ||
+queue == IWL_MVM_DQA_BSS_CLIENT_QUEUE);
 
IWL_DEBUG_TX_QUEUES(mvm, "Allocating queue #%d to sta %d on tid %d\n",
queue, mvmsta->sta_id, tid);
@@ -448,7 +449,8 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
 }
 
 static int iwl_mvm_reserve_sta_stream(struct iwl_mvm *mvm,
- struct ieee80211_sta *sta)
+ struct ieee80211_sta *sta,
+ enum nl80211_iftype vif_type)
 {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
int queue;
@@ -456,8 +458,13 @@ static int iwl_mvm_reserve_sta_stream(struct iwl_mvm *mvm,
spin_lock_bh(>queue_info_lock);
 
/* Make sure we have free resources for this STA */
-   queue = iwl_mvm_find_free_queue(mvm, IWL_MVM_DQA_MIN_DATA_QUEUE,
-   IWL_MVM_DQA_MAX_DATA_QUEUE);
+   if (vif_type == NL80211_IFTYPE_STATION && !sta->tdls &&
+   !mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].hw_queue_refcount &&
+   !mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].setup_reserved)
+   queue = IWL_MVM_DQA_BSS_CLIENT_QUEUE;
+   else
+   queue = iwl_mvm_find_free_queue(mvm, IWL_MVM_DQA_MIN_DATA_QUEUE,
+   IWL_MVM_DQA_MAX_DATA_QUEUE);
if (queue < 0) {
spin_unlock_bh(>queue_info_lock);
IWL_ERR(mvm, "No available queues for new station\n");
@@ -551,7 +558,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
}
 
if (iwl_mvm_is_dqa_supported(mvm)) {
-   ret = iwl_mvm_reserve_sta_stream(mvm, sta);
+   ret = iwl_mvm_reserve_sta_stream(mvm, sta,
+ieee80211_vif_type_p2p(vif));
if (ret)
goto err;
}
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 13/43] iwlwifi: pcie: do not pad QoS AMSDU

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

We insert padding if the MAC header's size is not a multiple of 4
to ensure that the SNAP header is DWORD aligned. When we do so, we
let the firmware know by setting a bit in Tx command
(TX_CMD_FLG_MH_PAD) which will instruct the firmware to drop those
2 bytes before sending the frame.
However, this is not needed for AMSDU as the sub frame header (14B)
complements the MAC header (26B) so that the SNAP header is DWORD
aligned without adding any pad.

Until 9000, the firmware didn't check the TX_CMD_FLG_MH_PAD bit
but rather checked the length of the MAC header itself and
assumed the entity that enqueued the frame (driver or internal
firmware code) added the pad.
Since the driver inserted the pad even for AMSDU this logic applied.
Note that the padding is a DMA optimization but it's not strictly
needed, so we could pad even if it was not needed.

However, the CSUM hardware introduced for the 9000 devices requires
to not pad AMSDU as it is not needed, and will fail if such a pad
exists.
Due to older FW not checking the padding bit but checking the mac
header size itself - we cannot do this adjustments for older
generations.
Do not align the size if it is an AMSDU and HW checksum is enabled -
which will only happen on 9000 devices and on.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index cc6fa00..e1f7a3f 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -2210,6 +2210,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct 
sk_buff *skb,
__le16 fc;
u8 hdr_len;
u16 wifi_seq;
+   bool amsdu;
 
txq = _pcie->txq[txq_id];
q = >q;
@@ -2301,11 +2302,18 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct 
sk_buff *skb,
 */
len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
  hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;
-   tb1_len = ALIGN(len, 4);
-
-   /* Tell NIC about any 2-byte padding after MAC header */
-   if (tb1_len != len)
-   tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
+   /* do not align A-MSDU to dword as the subframe header aligns it */
+   amsdu = ieee80211_is_data_qos(fc) &&
+   (*ieee80211_get_qos_ctl(hdr) &
+IEEE80211_QOS_CTL_A_MSDU_PRESENT);
+   if (trans_pcie->sw_csum_tx || !amsdu) {
+   tb1_len = ALIGN(len, 4);
+   /* Tell NIC about any 2-byte padding after MAC header */
+   if (tb1_len != len)
+   tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
+   } else {
+   tb1_len = len;
+   }
 
/* The first TB points to the scratchbuf data - min_copy bytes */
memcpy(>scratchbufs[q->write_ptr], _cmd->hdr,
@@ -2323,8 +2331,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct 
sk_buff *skb,
goto out_err;
iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, false);
 
-   if (ieee80211_is_data_qos(fc) &&
-   (*ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_A_MSDU_PRESENT)) {
+   if (amsdu) {
if (unlikely(iwl_fill_data_tbs_amsdu(trans, skb, txq, hdr_len,
 out_meta, dev_cmd,
 tb1_len)))
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 38/43] iwlwifi: remove IWL_*_UCODE_API_OK

2016-03-30 Thread Emmanuel Grumbach
_UCODE_API_OK was a intermediate version between MIN and
MAX. If a user had a firmware below _OK but above _MIN, the
driver would work but the user would get a warning in the
kernel log telling him to update his firmware.
This is not needed since most users won't look for these
messages in the kernel log if their wifi is working.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-1000.c   | 10 ++
 drivers/net/wireless/intel/iwlwifi/iwl-2000.c   | 18 --
 drivers/net/wireless/intel/iwlwifi/iwl-5000.c   | 11 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-6000.c   | 20 
 drivers/net/wireless/intel/iwlwifi/iwl-7000.c   | 20 +---
 drivers/net/wireless/intel/iwlwifi/iwl-8000.c   | 11 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-9000.c   |  6 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h |  3 ---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c| 24 +---
 9 files changed, 21 insertions(+), 102 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-1000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-1000.c
index a90dbab..ef22c3d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-1000.c
@@ -34,10 +34,6 @@
 #define IWL1000_UCODE_API_MAX 5
 #define IWL100_UCODE_API_MAX 5
 
-/* Oldest version we won't warn about */
-#define IWL1000_UCODE_API_OK 5
-#define IWL100_UCODE_API_OK 5
-
 /* Lowest firmware API version supported */
 #define IWL1000_UCODE_API_MIN 1
 #define IWL100_UCODE_API_MIN 5
@@ -86,7 +82,6 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = 
{
 #define IWL_DEVICE_1000\
.fw_name_pre = IWL1000_FW_PRE,  \
.ucode_api_max = IWL1000_UCODE_API_MAX, \
-   .ucode_api_ok = IWL1000_UCODE_API_OK,   \
.ucode_api_min = IWL1000_UCODE_API_MIN, \
.device_family = IWL_DEVICE_FAMILY_1000,\
.max_inst_size = IWLAGN_RTC_INST_SIZE,  \
@@ -112,7 +107,6 @@ const struct iwl_cfg iwl1000_bg_cfg = {
 #define IWL_DEVICE_100 \
.fw_name_pre = IWL100_FW_PRE,   \
.ucode_api_max = IWL100_UCODE_API_MAX,  \
-   .ucode_api_ok = IWL100_UCODE_API_OK,\
.ucode_api_min = IWL100_UCODE_API_MIN,  \
.device_family = IWL_DEVICE_FAMILY_100, \
.max_inst_size = IWLAGN_RTC_INST_SIZE,  \
@@ -136,5 +130,5 @@ const struct iwl_cfg iwl100_bg_cfg = {
IWL_DEVICE_100,
 };
 
-MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK));
-MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK));
+MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-2000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-2000.c
index a6da959..dc246c9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-2000.c
@@ -36,12 +36,6 @@
 #define IWL105_UCODE_API_MAX 6
 #define IWL135_UCODE_API_MAX 6
 
-/* Oldest version we won't warn about */
-#define IWL2030_UCODE_API_OK 6
-#define IWL2000_UCODE_API_OK 6
-#define IWL105_UCODE_API_OK 6
-#define IWL135_UCODE_API_OK 6
-
 /* Lowest firmware API version supported */
 #define IWL2030_UCODE_API_MIN 5
 #define IWL2000_UCODE_API_MIN 5
@@ -114,7 +108,6 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params 
= {
 #define IWL_DEVICE_2000\
.fw_name_pre = IWL2000_FW_PRE,  \
.ucode_api_max = IWL2000_UCODE_API_MAX, \
-   .ucode_api_ok = IWL2000_UCODE_API_OK,   \
.ucode_api_min = IWL2000_UCODE_API_MIN, \
.device_family = IWL_DEVICE_FAMILY_2000,\
.max_inst_size = IWL60_RTC_INST_SIZE,   \
@@ -142,7 +135,6 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
 #define IWL_DEVICE_2030\
.fw_name_pre = IWL2030_FW_PRE,  \
.ucode_api_max = IWL2030_UCODE_API_MAX, \
-   .ucode_api_ok = IWL2030_UCODE_API_OK,   \
.ucode_api_min = IWL2030_UCODE_API_MIN, \
.device_family = IWL_DEVICE_FAMILY_2030,\
.max_inst_size = IWL60_RTC_INST_SIZE,   \
@@ -163,7 +155,6 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
 #define IWL_DEVICE_105 \
.fw_name_pre = IWL105_FW_PRE,   \
.ucode_api_max = IWL105_UCODE_A

[PATCH 27/43] iwlwifi: trans: fix iwl_trans_txq_scd_cfg.sta_id sign

2016-03-30 Thread Emmanuel Grumbach
From: Liad Kaufman <liad.kauf...@intel.com>

For some reason, this was defined as a signed variable.
Make it unsigned.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 91d74b3..fa4ab4b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -519,7 +521,7 @@ struct iwl_trans;
 
 struct iwl_trans_txq_scd_cfg {
u8 fifo;
-   s8 sta_id;
+   u8 sta_id;
u8 tid;
bool aggregate;
int frame_limit;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/43] iwlwifi: pcie: fix global table size

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

My patch resized the pool size, but neglected to resize
the global table, which is obviously wrong since the global
table maps the pool's rxb to vid one to one. This results
in a panic in 9000 devices.
Add a build bug to avoid such a case in the future.

Fixes: 7b5424361ec9 ("iwlwifi: pcie: fine tune number of rxbs")
Reported-by: Haim Dreyfuss <haim.dreyf...@intel.com>
Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index dadafbd..34bf7ce 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -348,7 +348,7 @@ struct iwl_tso_hdr_page {
 struct iwl_trans_pcie {
struct iwl_rxq *rxq;
struct iwl_rx_mem_buffer rx_pool[RX_POOL_SIZE];
-   struct iwl_rx_mem_buffer *global_table[MQ_RX_TABLE_SIZE];
+   struct iwl_rx_mem_buffer *global_table[RX_POOL_SIZE];
struct iwl_rb_allocator rba;
struct iwl_trans *trans;
struct iwl_drv *drv;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 4be3c35..e379dba 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -908,6 +908,8 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
allocator_pool_size = trans->num_rx_queues *
(RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC);
num_alloc = queue_size + allocator_pool_size;
+   BUILD_BUG_ON(ARRAY_SIZE(trans_pcie->global_table) !=
+ARRAY_SIZE(trans_pcie->rx_pool));
for (i = 0; i < num_alloc; i++) {
struct iwl_rx_mem_buffer *rxb = _pcie->rx_pool[i];
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 24/43] iwlwifi: dvm: use alloc_ordered_workqueue()

2016-03-30 Thread Emmanuel Grumbach
From: Eva Rachel Retuya <eraret...@gmail.com>

Use alloc_ordered_workqueue() to allocate the workqueue instead of
create_singlethread_workqueue() since the latter is deprecated and is scheduled
for removal.

There are work items doing related operations that shouldn't be swapped when
queued in a certain order hence preserve the strict execution ordering of a
single threaded (ST) workqueue by switching to alloc_ordered_workqueue().

WQ_MEM_RECLAIM flag is not needed since the worker is not depended
during memory reclaim.

Signed-off-by: Eva Rachel Retuya <eraret...@gmail.com>
Acked-by: Tejun Heo <t...@kernel.org>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/dvm/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c 
b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index 85628127..6147162 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1071,7 +1071,7 @@ static void iwl_bg_restart(struct work_struct *data)
 
 static void iwl_setup_deferred_work(struct iwl_priv *priv)
 {
-   priv->workqueue = create_singlethread_workqueue(DRV_NAME);
+   priv->workqueue = alloc_ordered_workqueue(DRV_NAME, 0);
 
INIT_WORK(>restart, iwl_bg_restart);
INIT_WORK(>beacon_update, iwl_bg_beacon_update);
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/43] iwlwifi: pcie: refcounting is not necessary anymore

2016-03-30 Thread Emmanuel Grumbach
From: Luca Coelho <luciano.coe...@intel.com>

We don't use the refcount value anymore, all the refcounting is done
in the runtime PM usage_count value.  Remove it.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c  |  4 +---
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  4 
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c| 25 --
 3 files changed, 10 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 05b9685..3456669 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -651,10 +651,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)
/* The PCI device starts with a reference taken and we are
 * supposed to release it here.  But to simplify the
 * interaction with the opmode, we don't do it now, but let
-* the opmode release it when it's ready.  To account for this
-* reference, we start with ref_count set to 1.
+* the opmode release it when it's ready.
 */
-   trans_pcie->ref_count = 1;
 
return 0;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 34bf7ce..9ce4ec6 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -403,10 +403,6 @@ struct iwl_trans_pcie {
bool cmd_hold_nic_awake;
bool ref_cmd_in_flight;
 
-   /* protect ref counter */
-   spinlock_t ref_lock;
-   u32 ref_count;
-
dma_addr_t fw_mon_phys;
struct page *fw_mon_page;
u32 fw_mon_size;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index d4306e2..007bcb5 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2015,38 +2015,32 @@ static void iwl_trans_pcie_set_bits_mask(struct 
iwl_trans *trans, u32 reg,
 void iwl_trans_pcie_ref(struct iwl_trans *trans)
 {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-   unsigned long flags;
 
if (iwlwifi_mod_params.d0i3_disable)
return;
 
-   spin_lock_irqsave(_pcie->ref_lock, flags);
-   IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
-   trans_pcie->ref_count++;
pm_runtime_get(_pcie->pci_dev->dev);
-   spin_unlock_irqrestore(_pcie->ref_lock, flags);
+
+#ifdef CONFIG_PM
+   IWL_DEBUG_RPM(trans, "runtime usage count: %d\n",
+ atomic_read(_pcie->pci_dev->dev.power.usage_count));
+#endif /* CONFIG_PM */
 }
 
 void iwl_trans_pcie_unref(struct iwl_trans *trans)
 {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-   unsigned long flags;
 
if (iwlwifi_mod_params.d0i3_disable)
return;
 
-   spin_lock_irqsave(_pcie->ref_lock, flags);
-   IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
-   if (WARN_ON_ONCE(trans_pcie->ref_count == 0)) {
-   spin_unlock_irqrestore(_pcie->ref_lock, flags);
-   return;
-   }
-   trans_pcie->ref_count--;
-
pm_runtime_mark_last_busy(_pcie->pci_dev->dev);
pm_runtime_put_autosuspend(_pcie->pci_dev->dev);
 
-   spin_unlock_irqrestore(_pcie->ref_lock, flags);
+#ifdef CONFIG_PM
+   IWL_DEBUG_RPM(trans, "runtime usage count: %d\n",
+ atomic_read(_pcie->pci_dev->dev.power.usage_count));
+#endif /* CONFIG_PM */
 }
 
 static const char *get_csr_string(int cmd)
@@ -2794,7 +2788,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev 
*pdev,
trans_pcie->trans = trans;
spin_lock_init(_pcie->irq_lock);
spin_lock_init(_pcie->reg_lock);
-   spin_lock_init(_pcie->ref_lock);
mutex_init(_pcie->mutex);
init_waitqueue_head(_pcie->ucode_write_waitq);
trans_pcie->tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page);
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 30/43] iwlwifi: mvm: improve RSS configuration

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

Improve current RSS configuration:
 * Use netdev_rss_key instead of keeping a local copy.
 * Configure also UDP hashing to have UDP traffic spread across queues.
 * Do not direct RSS traffic to our fallback queue.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 5 -
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c  | 9 +++--
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 -
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ---
 4 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index abc16f7..362a546 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -65,6 +65,7 @@
  */
 #include 
 #include 
+#include 
 
 #include "mvm.h"
 #include "fw-dbg.h"
@@ -880,8 +881,10 @@ static ssize_t iwl_dbgfs_indirection_tbl_write(struct 
iwl_mvm *mvm,
struct iwl_rss_config_cmd cmd = {
.flags = cpu_to_le32(IWL_RSS_ENABLE),
.hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
+IWL_RSS_HASH_TYPE_IPV4_UDP |
 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
 IWL_RSS_HASH_TYPE_IPV6_TCP |
+IWL_RSS_HASH_TYPE_IPV6_UDP |
 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
};
int ret, i, num_repeats, nbytes = count / 2;
@@ -905,7 +908,7 @@ static ssize_t iwl_dbgfs_indirection_tbl_write(struct 
iwl_mvm *mvm,
memcpy(_table[i * nbytes], cmd.indirection_table,
   ARRAY_SIZE(cmd.indirection_table) % nbytes);
 
-   memcpy(cmd.secret_key, mvm->secret_key, sizeof(cmd.secret_key));
+   netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));
 
mutex_lock(>mutex);
ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), );
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index f375275..2dc97a1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -64,6 +64,7 @@
  *
  */
 #include 
+#include 
 
 #include "iwl-trans.h"
 #include "iwl-op-mode.h"
@@ -114,14 +115,18 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
struct iwl_rss_config_cmd cmd = {
.flags = cpu_to_le32(IWL_RSS_ENABLE),
.hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
+IWL_RSS_HASH_TYPE_IPV4_UDP |
 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
 IWL_RSS_HASH_TYPE_IPV6_TCP |
+IWL_RSS_HASH_TYPE_IPV6_UDP |
 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
};
 
+   /* Do not direct RSS traffic to Q 0 which is our fallback queue */
for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++)
-   cmd.indirection_table[i] = i % mvm->trans->num_rx_queues;
-   memcpy(cmd.secret_key, mvm->secret_key, sizeof(cmd.secret_key));
+   cmd.indirection_table[i] =
+   1 + (i % (mvm->trans->num_rx_queues - 1));
+   netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));
 
return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), );
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index f0e2597..a9de2ad 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -699,7 +699,6 @@ struct iwl_mvm {
atomic_t pending_frames[IWL_MVM_STATION_COUNT];
u32 tfd_drained[IWL_MVM_STATION_COUNT];
u8 rx_ba_sessions;
-   u32 secret_key[IWL_RSS_HASH_KEY_CNT];
 
/* configured by mac80211 */
u32 rts_threshold;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 9fc705c..e36bcad 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -725,9 +725,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
 
iwl_mvm_tof_init(mvm);
 
-   /* init RSS hash key */
-   get_random_bytes(mvm->secret_key, sizeof(mvm->secret_key));
-
return op_mode;
 
  out_unregister:
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/43] iwlwifi: mvm: modify the max SP to infinite

2016-03-30 Thread Emmanuel Grumbach
This makes u-APSD work with more peers.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   | 2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/power.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 0668601..2e0a882 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -208,7 +208,7 @@ enum iwl_power_scheme {
 };
 
 #define IWL_CONN_MAX_LISTEN_INTERVAL   10
-#define IWL_UAPSD_MAX_SP   IEEE80211_WMM_IE_STA_QOSINFO_SP_2
+#define IWL_UAPSD_MAX_SP   IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 enum iwl_dbgfs_pm_mask {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
index f313910..7b1f6ad 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
@@ -227,7 +227,7 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm 
*mvm,
cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
}
 
-   cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
+   cmd->uapsd_max_sp = mvm->hw->uapsd_max_sp_len;
 
if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 35/43] iwlwifi: mvm: move cmd queue to be #0 in dqa mode

2016-03-30 Thread Emmanuel Grumbach
From: Liad Kaufman <liad.kauf...@intel.com>

Change the CMD queue to be queue #0 (rather than queue #9)
when working in DQA mode.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h   | 2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   | 5 -
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 8 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  | 5 -
 4 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index b38cb03..60eed84 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -89,6 +89,7 @@ enum {
 /*
  * DQA queue numbers
  *
+ * @IWL_MVM_DQA_CMD_QUEUE: a queue reserved for sending HCMDs to the FW
  * @IWL_MVM_DQA_GCAST_QUEUE: a queue reserved for P2P GO/SoftAP GCAST frames
  * @IWL_MVM_DQA_BSS_CLIENT_QUEUE: a queue reserved for BSS activity, to ensure
  * that we are never left without the possibility to connect to an AP.
@@ -103,6 +104,7 @@ enum {
  * @IWL_MVM_DQA_MAX_DATA_QUEUE: last TXQ in pool for DATA frames
  */
 enum iwl_mvm_dqa_txq {
+   IWL_MVM_DQA_CMD_QUEUE = 0,
IWL_MVM_DQA_GCAST_QUEUE = 3,
IWL_MVM_DQA_BSS_CLIENT_QUEUE = 4,
IWL_MVM_DQA_MIN_MGMT_QUEUE = 5,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 2dc97a1..6ad5c60 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -652,7 +652,10 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm 
*mvm,
 */
 
memset(>queue_info, 0, sizeof(mvm->queue_info));
-   mvm->queue_info[IWL_MVM_CMD_QUEUE].hw_queue_refcount = 1;
+   if (iwl_mvm_is_dqa_supported(mvm))
+   mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].hw_queue_refcount = 1;
+   else
+   mvm->queue_info[IWL_MVM_CMD_QUEUE].hw_queue_refcount = 1;
 
for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
atomic_set(>mac80211_queue_stop_count[i], 0);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 43fd857..5f95056 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -252,10 +252,14 @@ unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm 
*mvm,
.exclude_vif = exclude_vif,
.used_hw_queues =
BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
-   BIT(mvm->aux_queue) |
-   BIT(IWL_MVM_CMD_QUEUE),
+   BIT(mvm->aux_queue),
};
 
+   if (iwl_mvm_is_dqa_supported(mvm))
+   data.used_hw_queues |= BIT(IWL_MVM_DQA_CMD_QUEUE);
+   else
+   data.used_hw_queues |= BIT(IWL_MVM_CMD_QUEUE);
+
lockdep_assert_held(>mutex);
 
/* mark all VIF used hw queues */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index e36bcad..cb00926 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -619,7 +619,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const 
struct iwl_cfg *cfg,
trans_cfg.command_groups = iwl_mvm_groups;
trans_cfg.command_groups_size = ARRAY_SIZE(iwl_mvm_groups);
 
-   trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
+   if (iwl_mvm_is_dqa_supported(mvm))
+   trans_cfg.cmd_queue = IWL_MVM_DQA_CMD_QUEUE;
+   else
+   trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD;
trans_cfg.scd_set_active = true;
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 34/43] iwlwifi: mvm: allocate dedicated queue for cab in dqa mode

2016-03-30 Thread Emmanuel Grumbach
From: Liad Kaufman <liad.kauf...@intel.com>

In DQA mode, allocate a dedicated queue (#3) for content
after beacon (AKA "CaB").

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h   |  2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 18 --
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index 9652687..b38cb03 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -89,6 +89,7 @@ enum {
 /*
  * DQA queue numbers
  *
+ * @IWL_MVM_DQA_GCAST_QUEUE: a queue reserved for P2P GO/SoftAP GCAST frames
  * @IWL_MVM_DQA_BSS_CLIENT_QUEUE: a queue reserved for BSS activity, to ensure
  * that we are never left without the possibility to connect to an AP.
  * @IWL_MVM_DQA_MIN_MGMT_QUEUE: first TXQ in pool for MGMT and non-QOS frames.
@@ -102,6 +103,7 @@ enum {
  * @IWL_MVM_DQA_MAX_DATA_QUEUE: last TXQ in pool for DATA frames
  */
 enum iwl_mvm_dqa_txq {
+   IWL_MVM_DQA_GCAST_QUEUE = 3,
IWL_MVM_DQA_BSS_CLIENT_QUEUE = 4,
IWL_MVM_DQA_MIN_MGMT_QUEUE = 5,
IWL_MVM_DQA_MAX_MGMT_QUEUE = 8,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index c02c105..43fd857 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -447,13 +447,19 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct 
iwl_mvm *mvm,
 
/* Allocate the CAB queue for softAP and GO interfaces */
if (vif->type == NL80211_IFTYPE_AP) {
-   u8 queue = find_first_zero_bit(_hw_queues,
-  mvm->first_agg_queue);
+   u8 queue;
 
-   if (queue >= mvm->first_agg_queue) {
-   IWL_ERR(mvm, "Failed to allocate cab queue\n");
-   ret = -EIO;
-   goto exit_fail;
+   if (!iwl_mvm_is_dqa_supported(mvm)) {
+   queue = find_first_zero_bit(_hw_queues,
+   mvm->first_agg_queue);
+
+   if (queue >= mvm->first_agg_queue) {
+   IWL_ERR(mvm, "Failed to allocate cab queue\n");
+   ret = -EIO;
+   goto exit_fail;
+   }
+   } else {
+   queue = IWL_MVM_DQA_GCAST_QUEUE;
}
 
vif->cab_queue = queue;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 33/43] iwlwifi: mvm: set sta_id in SCD_QUEUE_CONFIG cmd

2016-03-30 Thread Emmanuel Grumbach
From: Liad Kaufman <liad.kauf...@intel.com>

Set the correct sta_id in the SCD_QUEUE_CONFIG command sent
to the FW when enabling/disabling queues. This is needed in
DQA-mode to allow the FW to associate between queue and STA.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   | 1 +
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 4 
 2 files changed, 5 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index a9de2ad..cd5f16e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -665,6 +665,7 @@ struct iwl_mvm {
/* Map to HW queue */
u32 hw_queue_to_mac80211;
u8 hw_queue_refcount;
+   u8 ra_sta_id; /* The RA this queue is mapped to, if exists */
/*
 * This is to mark that queue is reserved for a STA but not yet
 * allocated. This is needed to make sure we have at least one
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 76866b9..486c985 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -608,6 +608,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int 
mac80211_queue,
mvm->queue_info[queue].hw_queue_refcount++;
if (mvm->queue_info[queue].hw_queue_refcount > 1)
enable_queue = false;
+   else
+   mvm->queue_info[queue].ra_sta_id = cfg->sta_id;
mvm->queue_info[queue].tid_bitmap |= BIT(cfg->tid);
 
IWL_DEBUG_TX_QUEUES(mvm,
@@ -693,6 +695,8 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, 
int mac80211_queue,
return;
}
 
+   cmd.sta_id = mvm->queue_info[queue].ra_sta_id;
+
/* Make sure queue info is correct even though we overwrite it */
WARN(mvm->queue_info[queue].hw_queue_refcount ||
 mvm->queue_info[queue].tid_bitmap ||
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 36/43] iwlwifi: mvm: add a scan timeout for regular scans

2016-03-30 Thread Emmanuel Grumbach
From: Luca Coelho <luciano.coe...@intel.com>

If something goes wrong with the firmware and we never get a scan
complete notification, we stay stuck forever.  In order to avoid this
situation, add a timeout and trigger an NMI if it expires before
receiving the notification., so we can clean things up.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  5 +
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 21 +
 3 files changed, 28 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index cd5f16e..2d685e0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -710,6 +710,7 @@ struct iwl_mvm {
struct iwl_mcast_filter_cmd *mcast_filter_cmd;
enum iwl_mvm_scan_type scan_type;
enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all;
+   struct timer_list scan_timer;
 
/* max number of simultaneous scans the FW supports */
unsigned int max_scans;
@@ -1314,6 +1315,7 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm);
 int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify);
 int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm);
 void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm);
+void iwl_mvm_scan_timeout(unsigned long data);
 
 /* Scheduled scan */
 void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index cb00926..656541c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -728,6 +728,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
 
iwl_mvm_tof_init(mvm);
 
+   setup_timer(>scan_timer, iwl_mvm_scan_timeout,
+   (unsigned long)mvm);
+
return op_mode;
 
  out_unregister:
@@ -783,6 +786,8 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode 
*op_mode)
 
iwl_mvm_tof_clean(mvm);
 
+   del_timer_sync(>scan_timer);
+
mutex_destroy(>mutex);
mutex_destroy(>d0i3_suspend_mutex);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 25b007c..c1d1be9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -70,6 +70,7 @@
 
 #include "mvm.h"
 #include "fw-api-scan.h"
+#include "iwl-io.h"
 
 #define IWL_DENSE_EBS_SCAN_RATIO 5
 #define IWL_SPARSE_EBS_SCAN_RATIO 1
@@ -398,6 +399,10 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm 
*mvm,
ieee80211_scan_completed(mvm->hw,
scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
+   del_timer(>scan_timer);
+   } else {
+   IWL_ERR(mvm,
+   "got scan complete notification but no scan is 
running\n");
}
 
mvm->last_ebs_successful =
@@ -1217,6 +1222,18 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm 
*mvm, int type)
return -EIO;
 }
 
+#define SCAN_TIMEOUT (16 * HZ)
+
+void iwl_mvm_scan_timeout(unsigned long data)
+{
+   struct iwl_mvm *mvm = (struct iwl_mvm *)data;
+
+   IWL_ERR(mvm, "regular scan timed out\n");
+
+   del_timer(>scan_timer);
+   iwl_force_nmi(mvm->trans);
+}
+
 int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
   struct cfg80211_scan_request *req,
   struct ieee80211_scan_ies *ies)
@@ -1296,6 +1313,8 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct 
ieee80211_vif *vif,
mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
 
+   mod_timer(>scan_timer, jiffies + SCAN_TIMEOUT);
+
return 0;
 }
 
@@ -1413,6 +1432,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm 
*mvm,
if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) {
ieee80211_scan_completed(mvm->hw, aborted);
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
+   del_timer(>scan_timer);
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
ieee80211_sched_scan_stopped(mvm->hw);
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
@@ -1608,6 +1628,7 @@ out:
 * to release the scan reference here.
 */
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
+   del_timer(>scan_timer);
if (notify)
ieee80211_scan_completed(mvm-&g

[PATCH 26/43] iwlwifi: mvm: set aux STA ID in scan config

2016-03-30 Thread Emmanuel Grumbach
From: David Spinadel <david.spina...@intel.com>

Auxilary station ID in flag in scan config command wasn't set
although we set the station ID. Add the flag.

Signed-off-by: David Spinadel <david.spina...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 09eb72c..25b007c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -961,6 +961,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
 SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS |
 SCAN_CONFIG_FLAG_SET_TX_CHAINS |
 SCAN_CONFIG_FLAG_SET_RX_CHAINS |
+SCAN_CONFIG_FLAG_SET_AUX_STA_ID |
 SCAN_CONFIG_FLAG_SET_ALL_TIMES |
 SCAN_CONFIG_FLAG_SET_LEGACY_RATES |
 SCAN_CONFIG_FLAG_SET_MAC_ADDR |
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 42/43] iwlwifi: mvm: allow setting the thermal state in D0i3

2016-03-30 Thread Emmanuel Grumbach
From: Luca Coelho <luciano.coe...@intel.com>

We were not allowing the thermal state to be set when we were in D0i3
mode.  It was not very clearly specified how it should work, but now a
decision was made to allow the state to be set in D0i3 (which will
cause a brief wake up).  Remove the check in the set_cur_state
operation.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 3f5df76..eb3f460 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -801,9 +801,6 @@ static int iwl_mvm_tcool_set_cur_state(struct 
thermal_cooling_device *cdev,
if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR))
return -EIO;
 
-   if (test_bit(IWL_MVM_STATUS_IN_D0I3, >status))
-   return -EBUSY;
-
mutex_lock(>mutex);
 
if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) {
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 43/43] iwlwifi: pcie: remove duplicate assignment of variable isr_stats

2016-03-30 Thread Emmanuel Grumbach
From: Colin Ian King <colin.k...@canonical.com>

isr_stats is written twice with the same value, remove one of the
redundant assignments to isr_stats.

Signed-off-by: Colin Ian King <colin.k...@canonical.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 59a7e45..7f8a232 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1811,7 +1811,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void 
*dev_id)
struct msix_entry *entry = dev_id;
struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry);
struct iwl_trans *trans = trans_pcie->trans;
-   struct isr_statistics *isr_stats = isr_stats = _pcie->isr_stats;
+   struct isr_statistics *isr_stats = _pcie->isr_stats;
u32 inta_fh, inta_hw;
 
lock_map_acquire(>sync_cmd_lockdep_map);
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 39/43] iwlwifi: pcie: Fix index iteration on free_irq in MSIX mode

2016-03-30 Thread Emmanuel Grumbach
From: Haim Dreyfuss <haim.dreyf...@intel.com>

In MSIX mode we iterate over the allocated interrupt vectors and
register them to an handler. In case of registration failure,
we free all the allocated irq.
we use the outer index mistakenly instead of the inner one.

Signed-off-by: Haim Dreyfuss <haim.dreyf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f1a506b..5e1a13e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1500,8 +1500,8 @@ static int iwl_pcie_init_msix_handler(struct pci_dev 
*pdev,
IWL_ERR(trans_pcie->trans,
"Error allocating IRQ %d\n", i);
for (j = 0; j < i; j++)
-   free_irq(trans_pcie->msix_entries[i].vector,
-_pcie->msix_entries[i]);
+   free_irq(trans_pcie->msix_entries[j].vector,
+_pcie->msix_entries[j]);
pci_disable_msix(pdev);
return ret;
}
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 40/43] iwlwifi: store fw memory segments length and addresses in run-time

2016-03-30 Thread Emmanuel Grumbach
From: Golan Ben-Ami <golan.ben@intel.com>

Currently reading the fw memory segments is done according to
addresses and data length that are hard-coded.
Lately a new tlv was appended to the ucode, that contains
the data type, length and address.
Parse this tlv, and in run-time store the memory segments length
and addresses that would be dumped upon a fw error.

Signed-off-by: Golan Ben-Ami <golan.ben@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 45 +
 drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h | 32 +
 drivers/net/wireless/intel/iwlwifi/iwl-fw.h  |  2 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c  | 61 ++--
 4 files changed, 125 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 605910f..48e8737 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -179,6 +179,8 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
kfree(drv->fw.dbg_conf_tlv[i]);
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
kfree(drv->fw.dbg_trigger_tlv[i]);
+   for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++)
+   kfree(drv->fw.dbg_mem_tlv[i]);
 
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
iwl_free_fw_img(drv, drv->fw.img + i);
@@ -297,6 +299,7 @@ struct iwl_firmware_pieces {
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
+   struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX];
 };
 
 /*
@@ -1041,6 +1044,37 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
iwl_store_gscan_capa(>fw, tlv_data, tlv_len);
gscan_capa = true;
break;
+   case IWL_UCODE_TLV_FW_MEM_SEG: {
+   struct iwl_fw_dbg_mem_seg_tlv *dbg_mem =
+   (void *)tlv_data;
+   u32 type;
+
+   if (tlv_len != (sizeof(*dbg_mem)))
+   goto invalid_tlv_len;
+
+   type = le32_to_cpu(dbg_mem->data_type);
+   drv->fw.dbg_dynamic_mem = true;
+
+   if (type >= ARRAY_SIZE(drv->fw.dbg_mem_tlv)) {
+   IWL_ERR(drv,
+   "Skip unknown dbg mem segment: %u\n",
+   dbg_mem->data_type);
+   break;
+   }
+
+   if (pieces->dbg_mem_tlv[type]) {
+   IWL_ERR(drv,
+   "Ignore duplicate mem segment: %u\n",
+   dbg_mem->data_type);
+   break;
+   }
+
+   IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n",
+  dbg_mem->data_type);
+
+   pieces->dbg_mem_tlv[type] = dbg_mem;
+   break;
+   }
default:
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
break;
@@ -1350,6 +1384,17 @@ static void iwl_req_fw_callback(const struct firmware 
*ucode_raw, void *context)
}
}
 
+   for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++) {
+   if (pieces->dbg_mem_tlv[i]) {
+   drv->fw.dbg_mem_tlv[i] =
+   kmemdup(pieces->dbg_mem_tlv[i],
+   sizeof(*drv->fw.dbg_mem_tlv[i]),
+   GFP_KERNEL);
+   if (!drv->fw.dbg_mem_tlv[i])
+   goto out_free_fw;
+   }
+   }
+
/* Now that we can no longer fail, copy information */
 
/*
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
index a6e8826..843232b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
@@ -142,6 +142,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_FW_DBG_CONF   = 39,
IWL_UCODE_TLV_FW_DBG_TRIGGER= 40,
IWL_UCODE_TLV_FW_GSCAN_CAPA = 50,
+   IWL_UCODE_TLV_FW_MEM_SEG= 51,
 };
 
 struct iwl_ucode_tlv {
@@ -492,6 +493,37 @@ enum iwl_fw_dbg_monitor_mode {
 };
 
 /**
+ * enum iwl_fw_mem_seg_type - data types for dumping on error
+ *
+ * @FW_DBG_MEM

[PATCH 20/43] iwlwifi: pcie: write to legacy register also in MQ

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

Due to hardware bug, upon any shadow free-queue register write
access, a legacy RBD shadow register must be written as well.
This is required in order to trigger a copy of the shadow registers
values after MAC exits sleep state.
Specifically, the driver has to write (any value) to the legacy RBD
register each time FRBDCB is accessed.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index e379dba..59a7e45 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -210,8 +210,12 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans 
*trans,
if (trans->cfg->mq_rx_supported)
iwl_write_prph(trans, RFH_Q_FRBDCB_WIDX(rxq->id),
   rxq->write_actual);
-   else
-   iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
+   /*
+* write to FH_RSCSR_CHNL0_WPTR register even in MQ as a W/A to
+* hardware shadow registers bug - writing to RFH_Q_FRBDCB_WIDX will
+* not wake the NIC.
+*/
+   iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
 }
 
 static void iwl_pcie_rxq_check_wrptr(struct iwl_trans *trans)
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 19/43] iwlwifi: mvm: support bss dynamic alloc/dealloc of queues

2016-03-30 Thread Emmanuel Grumbach
From: Liad Kaufman <liad.kauf...@intel.com>

"DQA" is shorthand for "dynamic queue allocation". This
enables on-demand allocation of queues per RA/TID rather than
statically allocating per vif, thus allowing a potential
benefit of various factors.

Please refer to the DOC section this patch adds to sta.h to
see a more in-depth explanation of this feature.

There are many things to take into consideration when working
in DQA mode, and this patch is only one in a series. Note that
default operation mode is non-DQA mode, unless the FW
indicates that it supports DQA mode.

This patch enables support of DQA for a station connected to
an AP, and works in a non-aggregated mode.

When a frame for an unused RA/TID arrives at the driver, it
isn't TXed immediately, but deferred first until a suitable
queue is first allocated for it, and then TXed by a worker
that both allocates the queues and TXes deferred traffic.

When a STA is removed, its queues goes back into the queue
pools for reuse as needed.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h   |  22 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |  21 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |  49 +
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   7 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |   1 +
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 254 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h  |  87 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   |  54 +
 9 files changed, 481 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index c1a3131..e3561bb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -723,7 +723,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct 
ieee80211_vif *vif,
return -EIO;
}
 
-   ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false);
+   ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false, 0);
if (ret)
return ret;
rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index e6bd0c8..8217eb2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -80,12 +80,32 @@
 #include "fw-api-stats.h"
 #include "fw-api-tof.h"
 
-/* Tx queue numbers */
+/* Tx queue numbers for non-DQA mode */
 enum {
IWL_MVM_OFFCHANNEL_QUEUE = 8,
IWL_MVM_CMD_QUEUE = 9,
 };
 
+/*
+ * DQA queue numbers
+ *
+ * @IWL_MVM_DQA_MIN_MGMT_QUEUE: first TXQ in pool for MGMT and non-QOS frames.
+ * Each MGMT queue is mapped to a single STA
+ * MGMT frames are frames that return true on ieee80211_is_mgmt()
+ * @IWL_MVM_DQA_MAX_MGMT_QUEUE: last TXQ in pool for MGMT frames
+ * @IWL_MVM_DQA_MIN_DATA_QUEUE: first TXQ in pool for DATA frames.
+ * DATA frames are intended for !ieee80211_is_mgmt() frames, but if
+ * the MGMT TXQ pool is exhausted, mgmt frames can be sent on DATA queues
+ * as well
+ * @IWL_MVM_DQA_MAX_DATA_QUEUE: last TXQ in pool for DATA frames
+ */
+enum iwl_mvm_dqa_txq {
+   IWL_MVM_DQA_MIN_MGMT_QUEUE = 5,
+   IWL_MVM_DQA_MAX_MGMT_QUEUE = 8,
+   IWL_MVM_DQA_MIN_DATA_QUEUE = 10,
+   IWL_MVM_DQA_MAX_DATA_QUEUE = 31,
+};
+
 enum iwl_mvm_tx_fifo {
IWL_MVM_TX_FIFO_BK = 0,
IWL_MVM_TX_FIFO_BE,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index e885db3..c02c105 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -425,12 +425,17 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct 
iwl_mvm *mvm,
return 0;
}
 
-   /* Find available queues, and allocate them to the ACs */
+   /*
+* Find available queues, and allocate them to the ACs. When in
+* DQA-mode they aren't really used, and this is done only so the
+* mac80211 ieee80211_check_queues() function won't fail
+*/
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
u8 queue = find_first_zero_bit(_hw_queues,
   mvm->first_agg_queue);
 
-   if (queue >= mvm->first_agg_queue) {
+   if (!iwl_mvm_is_dqa_supported(mvm) &&
+   queue >= mvm->first_agg_queue) {
IWL_ERR(mvm, "Failed to allocate queue\n");
ret = -EIO;
goto exit_

[PATCH 23/43] iwlwifi: remove support for fw older than -16.ucode

2016-03-30 Thread Emmanuel Grumbach
From: Sara Sharon <sara.sha...@intel.com>

API version lower than 16 is not supported anymore - don't
load older ucode.
Remove code handling older versions.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-7000.c  |   12 +-
 drivers/net/wireless/intel/iwlwifi/iwl-8000.c  |4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-9000.c  |4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c   |5 +-
 drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h   |4 -
 drivers/net/wireless/intel/iwlwifi/mvm/Makefile|2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/coex.c  |   42 -
 .../net/wireless/intel/iwlwifi/mvm/coex_legacy.c   | 1315 
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c   |  164 +--
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |   16 -
 drivers/net/wireless/intel/iwlwifi/mvm/sf.c|8 +-
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c |   86 --
 12 files changed, 41 insertions(+), 1621 deletions(-)
 delete mode 100644 drivers/net/wireless/intel/iwlwifi/mvm/coex_legacy.c

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
index fc475ce..f4012a3 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
@@ -77,15 +77,15 @@
 #define IWL3168_UCODE_API_MAX  21
 
 /* Oldest version we won't warn about */
-#define IWL7260_UCODE_API_OK   13
-#define IWL7265_UCODE_API_OK   13
-#define IWL7265D_UCODE_API_OK  13
+#define IWL7260_UCODE_API_OK   16
+#define IWL7265_UCODE_API_OK   16
+#define IWL7265D_UCODE_API_OK  16
 #define IWL3168_UCODE_API_OK   20
 
 /* Lowest firmware API version supported */
-#define IWL7260_UCODE_API_MIN  13
-#define IWL7265_UCODE_API_MIN  13
-#define IWL7265D_UCODE_API_MIN 13
+#define IWL7260_UCODE_API_MIN  16
+#define IWL7265_UCODE_API_MIN  16
+#define IWL7265D_UCODE_API_MIN 16
 #define IWL3168_UCODE_API_MIN  20
 
 /* NVM versions */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
index 97be104..49bb2a5 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
@@ -74,11 +74,11 @@
 #define IWL8265_UCODE_API_MAX  21
 
 /* Oldest version we won't warn about */
-#define IWL8000_UCODE_API_OK   13
+#define IWL8000_UCODE_API_OK   16
 #define IWL8265_UCODE_API_OK   20
 
 /* Lowest firmware API version supported */
-#define IWL8000_UCODE_API_MIN  13
+#define IWL8000_UCODE_API_MIN  16
 #define IWL8265_UCODE_API_MIN  20
 
 /* NVM versions */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
index 642fc92..277396a 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
@@ -58,10 +58,10 @@
 #define IWL9000_UCODE_API_MAX  21
 
 /* Oldest version we won't warn about */
-#define IWL9000_UCODE_API_OK   13
+#define IWL9000_UCODE_API_OK   16
 
 /* Lowest firmware API version supported */
-#define IWL9000_UCODE_API_MIN  13
+#define IWL9000_UCODE_API_MIN  16
 
 /* NVM versions */
 #define IWL9000_NVM_VERSION0x0a1d
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 7cd17f0..9a680ac 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1255,10 +1255,7 @@ static void iwl_req_fw_callback(const struct firmware 
*ucode_raw, void *context)
if (err)
goto try_again;
 
-   if (fw_has_api(>fw.ucode_capa, IWL_UCODE_TLV_API_NEW_VERSION))
-   api_ver = drv->fw.ucode_ver;
-   else
-   api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
+   api_ver = drv->fw.ucode_ver;
 
/*
 * api_ver should match the api version forming part of the
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
index c82b9416..a6e8826 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
@@ -245,13 +245,11 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_api_t;
 
 /**
  * enum iwl_ucode_tlv_api - ucode api
- * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
  * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
  * longer than the passive one, which is essential for fragmented scan.
  * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source.
  * @IWL_UCODE_TLV_API_WIDE_CMD_HDR: ucode supports wide command header
  * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params
- * @IWL_UCODE_TLV_API_NEW_VERSION: new versioning format
  * @IWL_UCODE_TLV_API_EXT_SCAN_PRIORITY: scan APIs use 8-level priority
  * instead of 3.
  * @IWL_UC

[PATCH 17/43] iwlwifi: 9000: update device id and FW serial number

2016-03-30 Thread Emmanuel Grumbach
From: Haim Dreyfuss <haim.dreyf...@intel.com>

Update device id and FW serial number for 2X2 antenna devices
in 9000 generation product. These will not be available on
the market in the coming year.

Signed-off-by: Haim Dreyfuss <haim.dreyf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-9000.c   |  8 
 drivers/net/wireless/intel/iwlwifi/iwl-config.h |  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c   | 10 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
index 318b1dc..642fc92 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015-2016 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -18,7 +18,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015-2016 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -143,8 +143,8 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.vht_mu_mimo_supported = true,  \
.mac_addr_from_csr = true
 
-const struct iwl_cfg iwl9260_2ac_cfg = {
-   .name = "Intel(R) Dual Band Wireless AC 9260",
+const struct iwl_cfg iwl9560_2ac_cfg = {
+   .name = "Intel(R) Dual Band Wireless AC 9560",
.fw_name_pre = IWL9000_FW_PRE,
IWL_DEVICE_9000,
.ht_params = _ht_params,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 3e4d346..8cbd248 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -439,7 +439,7 @@ extern const struct iwl_cfg iwl8265_2ac_cfg;
 extern const struct iwl_cfg iwl4165_2ac_cfg;
 extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
 extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
-extern const struct iwl_cfg iwl9260_2ac_cfg;
+extern const struct iwl_cfg iwl9560_2ac_cfg;
 extern const struct iwl_cfg iwl5165_2ac_cfg;
 #endif /* CONFIG_IWLMVM */
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 3456669..fb8b5ec 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -485,15 +485,15 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
 /* 9000 Series */
{IWL_PCI_DEVICE(0x9DF0, 0x2A10, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x2010, iwl5165_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x9DF0, 0x0A10, iwl9260_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9260_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x2526, 0x0A10, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9560_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x0310, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x0510, iwl5165_2ac_cfg)},
{IWL_PCI_DEVICE(0x9DF0, 0x0710, iwl5165_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x9DF0, 0x0210, iwl9260_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x9DF0, 0x0410, iwl9260_2ac_cfg)},
-   {IWL_PCI_DEVICE(0x9DF0, 0x0610, iwl9260_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x2526, 0x0210, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x2526, 0x0410, iwl9560_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x2526, 0x0610, iwl9560_2ac_cfg)},
 #endif /* CONFIG_IWLMVM */
 
{0}
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 21/43] iwlwifi: remove IWLWIFI_UAPSD Kconfig

2016-03-30 Thread Emmanuel Grumbach
We have a module parameter, this is enough.
per platform customizations will be done through the init
script of the platform.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/Kconfig   | 10 --
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c |  7 ---
 2 files changed, 17 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig 
b/drivers/net/wireless/intel/iwlwifi/Kconfig
index 16c4f38..492035f 100644
--- a/drivers/net/wireless/intel/iwlwifi/Kconfig
+++ b/drivers/net/wireless/intel/iwlwifi/Kconfig
@@ -88,16 +88,6 @@ config IWLWIFI_BCAST_FILTERING
  If unsure, don't enable this option, as some programs might
  expect incoming broadcasts for their normal operations.
 
-config IWLWIFI_UAPSD
-   bool "enable U-APSD by default"
-   depends on IWLMVM
-   help
- Say Y here to enable U-APSD by default. This may cause
- interoperability problems with some APs, manifesting in lower than
- expected throughput due to those APs not enabling aggregation
-
- If unsure, say N.
-
 config IWLWIFI_PCIE_RTPM
bool "Enable runtime power management mode for PCIe devices"
depends on IWLMVM && PM
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 2cd9c31..9c2a2fd 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1560,9 +1560,7 @@ struct iwl_mod_params iwlwifi_mod_params = {
.power_level = IWL_POWER_INDEX_1,
.d0i3_disable = true,
.d0i3_entry_delay = 1000,
-#ifndef CONFIG_IWLWIFI_UAPSD
.uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT,
-#endif /* CONFIG_IWLWIFI_UAPSD */
/* the rest are 0 by default */
 };
 IWL_EXPORT_SYMBOL(iwlwifi_mod_params);
@@ -1682,13 +1680,8 @@ MODULE_PARM_DESC(lar_disable, "disable LAR functionality 
(default: N)");
 
 module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
   uint, S_IRUGO | S_IWUSR);
-#ifdef CONFIG_IWLWIFI_UAPSD
-MODULE_PARM_DESC(uapsd_disable,
-"disable U-APSD functionality bitmap 1: BSS 2: P2P Client 
(default: 0)");
-#else
 MODULE_PARM_DESC(uapsd_disable,
 "disable U-APSD functionality bitmap 1: BSS 2: P2P Client 
(default: 3)");
-#endif
 
 /*
  * set bt_coex_active to true, uCode will do kill/defer
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 22/43] iwlwifi: mvm: update GSCAN capabilities

2016-03-30 Thread Emmanuel Grumbach
From: Ayala Beker <ayala.be...@intel.com>

Gscan capabilities were updated with new capabilities supported
by the device. Update GSCAN capabilities TLV.

Signed-off-by: Ayala Beker <ayala.be...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 9c2a2fd..7cd17f0 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1060,11 +1060,18 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
return -EINVAL;
}
 
-   if (WARN(fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) &&
-!gscan_capa,
-"GSCAN is supported but capabilities TLV is unavailable\n"))
+   /*
+* If ucode advertises that it supports GSCAN but GSCAN
+* capabilities TLV is not present, or if it has an old format,
+* warn and continue without GSCAN.
+*/
+   if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) &&
+   !gscan_capa) {
+   IWL_DEBUG_INFO(drv,
+  "GSCAN is supported but capabilities TLV is 
unavailable\n");
__clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT,
capa->_capa);
+   }
 
return 0;
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/43] iwlwifi: mvm: add LQM vendor command and notification

2016-03-30 Thread Emmanuel Grumbach
From: Aviya Erenfeld <aviya.erenf...@intel.com>

LQM stands for Link Quality Measurement. The firmware
will collect a defined set of statitics (see the
notification for details) that allow to know how busy
the medium is. The driver issues a request to the firmware
that includes the duration of the measurement (the firmware
needs to be on channel for that amount of time) and the
timeout (in case the firmware has a lot of offchannel
activities). If the timeout elapses, the firmware will
send partial results which are still valuable.
In case of disassociation / channel switch and alike, the
driver is in charge of stopping the measurements and the
firmware will reply with partial results.

The user space API for now is debugfs only and will be
implmemented in an upcoming patch.

Signed-off-by: Aviya Erenfeld <aviya.erenf...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h  |  2 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h   | 62 
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 10 
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  | 12 
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  9 +++
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c| 71 +++
 6 files changed, 166 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
index 3a72b97..c82b9416 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
@@ -326,6 +326,7 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
  * regular image.
  * @IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG: support getting more shared
  * memory addresses from the firmware.
+ * @IWL_UCODE_TLV_CAPA_LQM_SUPPORT: supports Link Quality Measurement
  *
  * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
  */
@@ -364,6 +365,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_CTDP_SUPPORT = (__force 
iwl_ucode_tlv_capa_t)76,
IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED = (__force 
iwl_ucode_tlv_capa_t)77,
IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG= (__force 
iwl_ucode_tlv_capa_t)80,
+   IWL_UCODE_TLV_CAPA_LQM_SUPPORT  = (__force 
iwl_ucode_tlv_capa_t)81,
 
NUM_IWL_UCODE_TLV_CAPA
 #ifdef __CHECKER__
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index 61711b1..e6bd0c8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -279,6 +279,11 @@ enum {
 /* Please keep this enum *SORTED* by hex value.
  * Needed for binary search, otherwise a warning will be triggered.
  */
+enum iwl_mac_conf_subcmd_ids {
+   LINK_QUALITY_MEASUREMENT_CMD = 0x1,
+   LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF = 0xFE,
+};
+
 enum iwl_phy_ops_subcmd_ids {
CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0,
CTDP_CONFIG_CMD = 0x03,
@@ -307,6 +312,7 @@ enum {
LEGACY_GROUP = 0x0,
LONG_GROUP = 0x1,
SYSTEM_GROUP = 0x2,
+   MAC_CONF_GROUP = 0x3,
PHY_OPS_GROUP = 0x4,
DATA_PATH_GROUP = 0x5,
PROT_OFFLOAD_GROUP = 0xb,
@@ -2017,4 +2023,60 @@ struct iwl_stored_beacon_notif {
u8 data[MAX_STORED_BEACON_SIZE];
 } __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_1 */
 
+#define LQM_NUMBER_OF_STATIONS_IN_REPORT 16
+
+enum iwl_lqm_cmd_operatrions {
+   LQM_CMD_OPERATION_START_MEASUREMENT = 0x01,
+   LQM_CMD_OPERATION_STOP_MEASUREMENT = 0x02,
+};
+
+enum iwl_lqm_status {
+   LQM_STATUS_SUCCESS = 0,
+   LQM_STATUS_TIMEOUT = 1,
+   LQM_STATUS_ABORT = 2,
+};
+
+/**
+ * Link Quality Measurement command
+ * @cmd_operatrion: command operation to be performed (start or stop)
+ * as defined above.
+ * @mac_id: MAC ID the measurement applies to.
+ * @measurement_time: time of the total measurement to be performed, in uSec.
+ * @timeout: maximum time allowed until a response is sent, in uSec.
+ */
+struct iwl_link_qual_msrmnt_cmd {
+   __le32 cmd_operation;
+   __le32 mac_id;
+   __le32 measurement_time;
+   __le32 timeout;
+} __packed /* LQM_CMD_API_S_VER_1 */;
+
+/**
+ * Link Quality Measurement notification
+ *
+ * @frequent_stations_air_time: an array containing the total air time
+ * (in uSec) used by the most frequently transmitting stations.
+ * @number_of_stations: the number of uniqe stations included in the array
+ * (a number between 0 to 16)
+ * @total_air_time_other_stations: the total air time (uSec) used by all the
+ * stations which are not included in the above report.
+ * @time_in_measurement_window: the total time in uSec in which a measurement
+ * took place.
+ * @tx_frame_dropped: the number of TX frames dropped due to retry limit during
+ * measurement
+ * @mac_id: MAC ID the measurement applies to.
+

[PATCH 15/43] iwlwifi: add missing mutex_destroy statements

2016-03-30 Thread Emmanuel Grumbach
iwlwifi / iwlmvm didn't destroy their mutexes. Fix that.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c| 3 +++
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 6153c8e..d4b71a7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -782,6 +782,9 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode 
*op_mode)
 
iwl_mvm_tof_clean(mvm);
 
+   mutex_destroy(>mutex);
+   mutex_destroy(>d0i3_suspend_mutex);
+
ieee80211_free_hw(mvm->hw);
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 28fe220..0c40209 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1695,6 +1695,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
}
 
free_percpu(trans_pcie->tso_hdr_page);
+   mutex_destroy(_pcie->mutex);
iwl_trans_free(trans);
 }
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/43] iwlwifi: mvm: handle async temperature notification with unlocked mutex

2016-03-30 Thread Emmanuel Grumbach
From: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>

Use RX_HANDLER_ASYNC_UNLOCKED instead of unlock and re-lock
the mutex independently.

Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/tt.c  | 9 -
 2 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 46a22fd..6153c8e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -292,7 +292,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = 
{
RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif,
   RX_HANDLER_ASYNC_LOCKED),
RX_HANDLER_GRP(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE,
-  iwl_mvm_temp_notif, RX_HANDLER_ASYNC_LOCKED),
+  iwl_mvm_temp_notif, RX_HANDLER_ASYNC_UNLOCKED),
RX_HANDLER_GRP(PHY_OPS_GROUP, CT_KILL_NOTIFICATION,
   iwl_mvm_ct_kill_notif, RX_HANDLER_SYNC),
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index f1f2825..8d27137 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -204,20 +204,11 @@ void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct 
iwl_rx_cmd_buffer *rxb)
if (WARN_ON(ths_crossed >= IWL_MAX_DTS_TRIPS))
return;
 
-   /*
-* We are now handling a temperature notification from the firmware
-* in ASYNC and hold the mutex. thermal_notify_framework will call
-* us back through get_temp() which ought to send a SYNC command to
-* the firmware and hence to take the mutex.
-* Avoid the deadlock by unlocking the mutex here.
-*/
if (mvm->tz_device.tzone) {
struct iwl_mvm_thermal_device *tz_dev = >tz_device;
 
-   mutex_unlock(>mutex);
thermal_notify_framework(tz_dev->tzone,
 tz_dev->fw_trips_index[ths_crossed]);
-   mutex_lock(>mutex);
}
 #endif /* CONFIG_THERMAL */
 }
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   6   7   8   9   10   >