Re: [POC/GIT] mac80211 multicast rate selection (help wanted!)

2017-08-18 Thread David Lamparter
On Fri, Aug 18, 2017 at 03:49:39PM -0700, Ben Greear wrote:
> On 08/18/2017 03:29 PM, David Lamparter wrote:
> > I've taken up an hacking endeavour in trying to improve multicast on
> > wifi, specifically to get it off the stupid 1 MBit rate.  Before anyone
> > yells "that's not allowed by the spec" - it actually is, please refer to
> > section 9.7.5 of 802.11-2012. ("... using one of the rates included in
> > the BSSBasicRateSet parameter ...")  Also, Cisco and Aruba are doing
> > this in their enterprise APs, and it's rather nice.
> 
> For ath10k, at least, rate-ctrl is controlled in the firmware.
> But, the driver can set the multicast rate to a fixed value.

Yeah, I've hacked this straight in minstrel_ht, so it's only gonna work
on mac80211 drivers.

The information about which STAs are joined to a multicast group is
available to all drivers though, so, if a hardmac driver has sufficient
information on STA rates, it could still dynamically pick a multicast
rate on a per-packet level and tell that to the MAC.

> I am pretty sure this works on stock firmware, maybe with some driver
> tweaks.  It definitely works on my ath10k-ct driver/firmware (tested on
> the wave-1 stuff, not sure anyone has tested on the wave-2 stuff yet).
> 
> My api is through the ath10k debugfs API, so a kludge at best, but it could
> be wired into a better API with some work.

I actually need to try the CT stuff, particularly the TX rate reporting
-- wonder how useful the information is (cf. above).  Unfortunately the
only ath10k I have is in my plastic router...  a bit annoying to hack
around on.

> I'll read through your stuff when I get a chance.

Thanks in advance, all input appreciated!


-David


Re: [POC/GIT] mac80211 multicast rate selection (help wanted!)

2017-08-18 Thread David Lamparter
On Sat, Aug 19, 2017 at 12:58:11AM +0200, Matteo Croce wrote:
> Il giorno sab, 19/08/2017 alle 00.29 +0200, David Lamparter ha scritto:
> > So, from some completely unrelated datacenter work, I have hacked up
> > the bridge to hand back down to the driver detailed info on
> > multicast receivers.  Then I took this and fudged around in the
> > minstrel_ht code and, well, it gave me 9 MBit/s ;)
> > 
> > Now, I have pretty little no clue about the Linux wireless stack, so
> > I'd appreciate if someone could tell me how massively wrong I'm
> > doing this and which places in particular are the wrongest!
[cut]
> So you are scanning the multicast receivers list to select the lowest
> rate, comparing the rates by data rate?

Right now it's just using the lowest rate index.  I did say I have no
clue, right? :)

> I think that this is incorrect, the data rate is a combination of many
> parameters (modulation, GI interval, coding rate, streams, etc.) so a
> rate with higher data rate could be better than another with lower
> speed in some circumstances. Or even worse, some station could not
> receive the packet at all (too many streams, unsupported modulations.
> etc.).
>
> You could try to select the lowest MCS rate, the longer GI and the
> minimum number of stream from all the receivers and use a data rate
> compatible with these settings, if any (not all combinations are
> allowed unfortunately)

Yes, basically I need to find the best rate in the common subset
supported by all receivers.  This is far from trivial and will have
'interesting' interactions (for example, if a station only does
multicast, minstrel has nothing to learn the rate on because multicast
isn't ACKed so you can't probe with it).  That said, my goal here is
"simple", not "perfect".  There's always room and time for
improvement...


-David


Re: [POC/GIT] mac80211 multicast rate selection (help wanted!)

2017-08-18 Thread Matteo Croce
Il giorno sab, 19/08/2017 alle 00.29 +0200, David Lamparter ha scritto:
> Hello Linux Wireless hackers,
> 
> 
> I've taken up an hacking endeavour in trying to improve multicast on
> wifi, specifically to get it off the stupid 1 MBit rate.  Before
> anyone
> yells "that's not allowed by the spec" - it actually is, please refer
> to
> section 9.7.5 of 802.11-2012. ("... using one of the rates included
> in
> the BSSBasicRateSet parameter ...")  Also, Cisco and Aruba are doing
> this in their enterprise APs, and it's rather nice.
> 
> So, from some completely unrelated datacenter work, I have hacked up
> the
> bridge to hand back down to the driver detailed info on multicast
> receivers.  Then I took this and fudged around in the minstrel_ht
> code
> and, well, it gave me 9 MBit/s ;)
> 
> Now, I have pretty little no clue about the Linux wireless stack, so
> I'd
> appreciate if someone could tell me how massively wrong I'm doing
> this
> and which places in particular are the wrongest!
> 
> You can find the code here:
> https://github.com/eqvinox/vpls-linux-kernel/commits/mdb-hack
> https://github.com/eqvinox/vpls-iproute2/tree/mdb-hack
> 
> Please note that all of this is proof-of-concept level, it probably
> leaks tons of memory, has great race conditions and eats your cat for
> breakfast.  It also contains some debug printks like this:
> [ 9006.253504] mac80211_hwsim hwsim0 wlan0: multi-dst TX:
> 02:00:00:00:02:00 02:00:00:00:01:00
> [ 9006.255007] mac80211_hwsim hwsim0 wlan0: rc 02:00:00:00:02:00 =>
> rate #1
> [ 9006.256095] mac80211_hwsim hwsim0 wlan0: rc 02:00:00:00:01:00 =>
> rate #12
> [ 9006.257186] mac80211_hwsim hwsim0 wlan0: result rate #1
> 
> 
> Cheers,
> 
> -David
> 
> 
> P.S.: yes, I know about unicast conversion.  But that's not helpful
> when, for example, you want to get a 10 MBit multicast TV livestream
> to
> 5 simultaneous wifi clients...

So you are scanning the multicast receivers list to select the lowest
rate, comparing the rates by data rate?
I think that this is incorrect, the data rate is a combination of many
parameters (modulation, GI interval, coding rate, streams, etc.) so a
rate with higher data rate could be better than another with lower
speed in some circumstances. Or even worse, some station could not
receive the packet at all (too many streams, unsupported modulations.
etc.).

You could try to select the lowest MCS rate, the longer GI and the
minimum number of stream from all the receivers and use a data rate
compatible with these settings, if any (not all combinations are
allowed unfortunately)

Ciao,
-- 
Matteo Croce
per aspera ad upstream


Re: [POC/GIT] mac80211 multicast rate selection (help wanted!)

2017-08-18 Thread Ben Greear

On 08/18/2017 03:29 PM, David Lamparter wrote:

Hello Linux Wireless hackers,


I've taken up an hacking endeavour in trying to improve multicast on
wifi, specifically to get it off the stupid 1 MBit rate.  Before anyone
yells "that's not allowed by the spec" - it actually is, please refer to
section 9.7.5 of 802.11-2012. ("... using one of the rates included in
the BSSBasicRateSet parameter ...")  Also, Cisco and Aruba are doing
this in their enterprise APs, and it's rather nice.


For ath10k, at least, rate-ctrl is controlled in the firmware.
But, the driver can set the multicast rate to a fixed value.

I am pretty sure this works on stock firmware, maybe with some driver
tweaks.  It definitely works on my ath10k-ct driver/firmware (tested on
the wave-1 stuff, not sure anyone has tested on the wave-2 stuff yet).

My api is through the ath10k debugfs API, so a kludge at best, but it could
be wired into a better API with some work.

I'll read through your stuff when I get a chance.

Thanks,
Ben



So, from some completely unrelated datacenter work, I have hacked up the
bridge to hand back down to the driver detailed info on multicast
receivers.  Then I took this and fudged around in the minstrel_ht code
and, well, it gave me 9 MBit/s ;)

Now, I have pretty little no clue about the Linux wireless stack, so I'd
appreciate if someone could tell me how massively wrong I'm doing this
and which places in particular are the wrongest!

You can find the code here:
https://github.com/eqvinox/vpls-linux-kernel/commits/mdb-hack
https://github.com/eqvinox/vpls-iproute2/tree/mdb-hack

Please note that all of this is proof-of-concept level, it probably
leaks tons of memory, has great race conditions and eats your cat for
breakfast.  It also contains some debug printks like this:
[ 9006.253504] mac80211_hwsim hwsim0 wlan0: multi-dst TX: 02:00:00:00:02:00 
02:00:00:00:01:00
[ 9006.255007] mac80211_hwsim hwsim0 wlan0: rc 02:00:00:00:02:00 => rate #1
[ 9006.256095] mac80211_hwsim hwsim0 wlan0: rc 02:00:00:00:01:00 => rate #12
[ 9006.257186] mac80211_hwsim hwsim0 wlan0: result rate #1


Cheers,

-David


P.S.: yes, I know about unicast conversion.  But that's not helpful
when, for example, you want to get a 10 MBit multicast TV livestream to
5 simultaneous wifi clients...




--
Ben Greear 
Candela Technologies Inc  http://www.candelatech.com



[POC/GIT] mac80211 multicast rate selection (help wanted!)

2017-08-18 Thread David Lamparter
Hello Linux Wireless hackers,


I've taken up an hacking endeavour in trying to improve multicast on
wifi, specifically to get it off the stupid 1 MBit rate.  Before anyone
yells "that's not allowed by the spec" - it actually is, please refer to
section 9.7.5 of 802.11-2012. ("... using one of the rates included in
the BSSBasicRateSet parameter ...")  Also, Cisco and Aruba are doing
this in their enterprise APs, and it's rather nice.

So, from some completely unrelated datacenter work, I have hacked up the
bridge to hand back down to the driver detailed info on multicast
receivers.  Then I took this and fudged around in the minstrel_ht code
and, well, it gave me 9 MBit/s ;)

Now, I have pretty little no clue about the Linux wireless stack, so I'd
appreciate if someone could tell me how massively wrong I'm doing this
and which places in particular are the wrongest!

You can find the code here:
https://github.com/eqvinox/vpls-linux-kernel/commits/mdb-hack
https://github.com/eqvinox/vpls-iproute2/tree/mdb-hack

Please note that all of this is proof-of-concept level, it probably
leaks tons of memory, has great race conditions and eats your cat for
breakfast.  It also contains some debug printks like this:
[ 9006.253504] mac80211_hwsim hwsim0 wlan0: multi-dst TX: 02:00:00:00:02:00 
02:00:00:00:01:00
[ 9006.255007] mac80211_hwsim hwsim0 wlan0: rc 02:00:00:00:02:00 => rate #1
[ 9006.256095] mac80211_hwsim hwsim0 wlan0: rc 02:00:00:00:01:00 => rate #12
[ 9006.257186] mac80211_hwsim hwsim0 wlan0: result rate #1


Cheers,

-David


P.S.: yes, I know about unicast conversion.  But that's not helpful
when, for example, you want to get a 10 MBit multicast TV livestream to
5 simultaneous wifi clients...


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

2017-08-18 Thread Håvard Rabbe
Hi
Thank you so much. You made my day!
The command works. Im looking forward to test it out :-)


I also have two of these card. they don’t have the same bitmap, but I assume 
they work the same way?

qca9882 chipset with 2 chains available using ath10k driver:
Available Antennas: TX 0x3 RX 0x3
Configured Antennas: TX 0x3 RX 0x3

qca9880 chipset with 3 chains available using ath10k driver:
Available Antennas: TX 0x3 RX 0x3
Configured Antennas: TX 0x3 RX 0x3


Best Regards,

Håvard

> On 18 Aug 2017, at 09:00, Matthias May  wrote:
> 
> On 18/08/17 01:32, Håvard Rabbe wrote:
>> Hi
>> I’m using wifi card with AR9280 chipset that uses the ath9k driver.
>> 
>> The card has 2 available radio chains and I’m only going to connect 1 
>> antenna.
>> 
>> Is it possible to disable the radio chain im not using?
>> 
>> 
>> Best Regards,
>> 
>> Håvard Rabbe
>> 
> 
> Help text from iw:
> phy  set antenna  | all |  
> 
> You can set the rx/tx mask with
> iw phy phy0 set antenna 1
> to not use the second chain
> 
> or
> iw phy phy0 set antenna 1 3
> to not use the second chain for tx, but still use it for rx.
> 
> You can see the currently active mask with:
> iw list | grep Antenna
> 
> Be aware that the value set here is a bitmask only allows the values 1/3/7 
> (for 1, 2 and 3 chains).
> Chain 0 is always active.
> --> You can not disable chain 0 and only use chain 1.
> 
> BR
> Matthias



Re: Cisco's Wi-Fi Direct Client Policy and iwlwifi (8260)

2017-08-18 Thread Luca Coelho
On Fri, 2017-08-18 at 20:16 +0300, Luca Coelho wrote:
> Hi Dariusz,
> 
> On Fri, 2017-08-18 at 14:48 +0200, Dariusz Gadomski wrote:
> > Hi,
> > 
> > There is a “Wi-Fi Direct Client Policy” setting in some Cisco AP hardware 
> > [1].
> > I am unaware how that works exactly behind the scenes (except for some 
> > hints at
> > [2]), but I have noticed that with that setting set to “Deny” I am observing
> > issues when trying to connect from a machine with an Intel 8260 on a 4.10.0
> > kernel - all connection attempts lead to failure.
> > 
> > I have managed to obtain some captured packets from that attempt as well as
> > from a successful attempt (a machine with Broadcom bcm43224). What I have
> > noticed is that AP puts the P2P IE in the beacon frames and when 8260 sends 
> > a
> > probe request it also puts a P2P IE element in it. No response from the AP 
> > is
> > ever transmitted.
> > 
> > In case of the Broadcom-based device the probe request does not contain P2P 
> > IE
> > and it is able to correct normally. My understanding of this issue is that 
> > the
> > AP makes the decision to temporarily blacklist the client after receiving a 
> > P2P
> > IE from it.
> > 
> > I have made an additional test by commenting out the P2P interface types 
> > from
> > iwlwifi/mvn/mac80211.c - using such kernel allowed the 8260 device to 
> > connect
> > successfully.
> > 
> > I’m wondering if there’s a way of changing this behavior to enable the 8260 
> > to
> > connect to a network ‘secured’ in this way?  I would also appreciate some
> > information about which behavior is correct (bcm43224 vs 8260) and is it
> > specified anywhere in the Wi-Fi P2P specs (or anywhere else ftm)?
> 
> I have heard about this before.  The issue is that the Cisco AP doesn't
> allow the 8260 to connect because it has the P2P IE in it.  But AFAICT
> it is not against any specs to include this IE.  The Cisco AP is using
> the IE as an indication that we are trying to connect as a P2P device,
> which in this case we are not.
> 
> I'll try to dig the thread I had about this and take it again with our
> system engineers to hear what they have to say about it.
> 
> In the meantime, I think it would be helpful if you could contact Cisco
> about this issue as well.

Also, as a workaround if you are really not interested in using P2P is
to start wpa_supplicant with “p2p_disabled=1” in the configuration. 
This should prevent the P2P IE from being sent.

--
Cheers,
Luca.


Re: Cisco's Wi-Fi Direct Client Policy and iwlwifi (8260)

2017-08-18 Thread Luca Coelho
Hi Dariusz,

On Fri, 2017-08-18 at 14:48 +0200, Dariusz Gadomski wrote:
> Hi,
> 
> There is a “Wi-Fi Direct Client Policy” setting in some Cisco AP hardware [1].
> I am unaware how that works exactly behind the scenes (except for some hints 
> at
> [2]), but I have noticed that with that setting set to “Deny” I am observing
> issues when trying to connect from a machine with an Intel 8260 on a 4.10.0
> kernel - all connection attempts lead to failure.
> 
> I have managed to obtain some captured packets from that attempt as well as
> from a successful attempt (a machine with Broadcom bcm43224). What I have
> noticed is that AP puts the P2P IE in the beacon frames and when 8260 sends a
> probe request it also puts a P2P IE element in it. No response from the AP is
> ever transmitted.
> 
> In case of the Broadcom-based device the probe request does not contain P2P IE
> and it is able to correct normally. My understanding of this issue is that the
> AP makes the decision to temporarily blacklist the client after receiving a 
> P2P
> IE from it.
> 
> I have made an additional test by commenting out the P2P interface types from
> iwlwifi/mvn/mac80211.c - using such kernel allowed the 8260 device to connect
> successfully.
> 
> I’m wondering if there’s a way of changing this behavior to enable the 8260 to
> connect to a network ‘secured’ in this way?  I would also appreciate some
> information about which behavior is correct (bcm43224 vs 8260) and is it
> specified anywhere in the Wi-Fi P2P specs (or anywhere else ftm)?

I have heard about this before.  The issue is that the Cisco AP doesn't
allow the 8260 to connect because it has the P2P IE in it.  But AFAICT
it is not against any specs to include this IE.  The Cisco AP is using
the IE as an indication that we are trying to connect as a P2P device,
which in this case we are not.

I'll try to dig the thread I had about this and take it again with our
system engineers to hear what they have to say about it.

In the meantime, I think it would be helpful if you could contact Cisco
about this issue as well.

--
Cheers,
Luca.


[PATCH 22/24] iwlwifi: mvm: remove useless argument in iwl_nvm_init()

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

We always call iwl_nvm_init() with read_nvm_from_nic == true, so this
argument is useless.  Remove it.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c  |  5 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 98 ++--
 3 files changed, 51 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 90ae50f7768a..3d65ab49a8a6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -388,7 +388,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, 
bool read_nvm)
}
 
if (IWL_MVM_PARSE_NVM && read_nvm) {
-   ret = iwl_nvm_init(mvm, true);
+   ret = iwl_nvm_init(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
goto error;
@@ -486,8 +486,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool 
read_nvm)
 
/* Read the NVM only at driver load time, no need to do this twice */
if (read_nvm) {
-   /* Read nvm */
-   ret = iwl_nvm_init(mvm, true);
+   ret = iwl_nvm_init(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
goto remove_notif;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 74fdd33fd9fb..83303bac0e4b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1373,7 +1373,7 @@ int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool 
clear);
 void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
 
 /* NVM */
-int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
+int iwl_nvm_init(struct iwl_mvm *mvm);
 int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
 int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index 08020386c3d4..5a6916f0b9ec 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -546,7 +546,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
return ret;
 }
 
-int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
+int iwl_nvm_init(struct iwl_mvm *mvm)
 {
int ret, section;
u32 size_read = 0;
@@ -557,63 +557,61 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool 
read_nvm_from_nic)
return -EINVAL;
 
/* load NVM values from nic */
-   if (read_nvm_from_nic) {
-   /* Read From FW NVM */
-   IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
-
-   nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
-GFP_KERNEL);
-   if (!nvm_buffer)
-   return -ENOMEM;
-   for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
-   /* we override the constness for initial read */
-   ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
-  size_read);
-   if (ret < 0)
-   continue;
-   size_read += ret;
-   temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
-   if (!temp) {
-   ret = -ENOMEM;
-   break;
-   }
+   /* Read From FW NVM */
+   IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
+
+   nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
+GFP_KERNEL);
+   if (!nvm_buffer)
+   return -ENOMEM;
+   for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
+   /* we override the constness for initial read */
+   ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
+  size_read);
+   if (ret < 0)
+   continue;
+   size_read += ret;
+   temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
+   if (!temp) {
+   ret = -ENOMEM;
+   break;
+   }
 
-   iwl_mvm_nvm_fixups(mvm, section, temp, ret);
+   iwl_mvm_nvm_fixups(mvm, section, temp, ret);
 
-   mvm->nvm_sections[section].data = temp;
-   mvm->nvm_sections[section].length = ret;
+   mvm->nvm_sections[section].data = temp;
+   mvm->nvm_sections[section].length = ret;
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-   switch (section) 

[PATCH 20/24] iwlwifi: add workaround to disable wide channels in 5GHz

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

The OTP in some SKUs have erroneously allowed 40MHz and 80MHz channels
in the 5.2GHz band.  The firmware has been modified to not allow this
in those SKUs, so the driver needs to do the same otherwise the
firmware will assert when we try to use it.

Cc: sta...@vger.kernel.org
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/nvm.c|  3 +-
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 62 ++
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h |  3 +-
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/fw/nvm.c
index ae03d0f5564f..e81f6dd3744e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/nvm.c
@@ -148,7 +148,8 @@ struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime 
*fwrt)
rsp->regulatory.channel_profile,
nvm->valid_tx_ant & fwrt->fw->valid_tx_ant,
nvm->valid_rx_ant & fwrt->fw->valid_rx_ant,
-   rsp->regulatory.lar_enabled && lar_fw_supported);
+   rsp->regulatory.lar_enabled && lar_fw_supported,
+   false);
 
iwl_free_resp();
return nvm;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 1172e4572a82..ea165b3e6dd3 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -79,6 +79,7 @@
 /* NVM offsets (in words) definitions */
 enum wkp_nvm_offsets {
/* NVM HW-Section offset (in words) definitions */
+   SUBSYSTEM_ID = 0x0A,
HW_ADDR = 0x15,
 
/* NVM SW-Section offset (in words) definitions */
@@ -258,13 +259,12 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, 
bool is_5ghz,
 static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const __le16 * const nvm_ch_flags,
-   bool lar_supported)
+   bool lar_supported, bool no_wide_in_5ghz)
 {
int ch_idx;
int n_channels = 0;
struct ieee80211_channel *channel;
u16 ch_flags;
-   bool is_5ghz;
int num_of_ch, num_2ghz_channels;
const u8 *nvm_chan;
 
@@ -279,12 +279,20 @@ static int iwl_init_channel_map(struct device *dev, const 
struct iwl_cfg *cfg,
}
 
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
+   bool is_5ghz = (ch_idx >= num_2ghz_channels);
+
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
 
-   if (ch_idx >= num_2ghz_channels &&
-   !data->sku_cap_band_52GHz_enable)
+   if (is_5ghz && !data->sku_cap_band_52GHz_enable)
continue;
 
+   /* workaround to disable wide channels in 5GHz */
+   if (no_wide_in_5ghz && is_5ghz) {
+   ch_flags &= ~(NVM_CHANNEL_40MHZ |
+NVM_CHANNEL_80MHZ |
+NVM_CHANNEL_160MHZ);
+   }
+
if (ch_flags & NVM_CHANNEL_160MHZ)
data->vht160_supported = true;
 
@@ -307,8 +315,8 @@ static int iwl_init_channel_map(struct device *dev, const 
struct iwl_cfg *cfg,
n_channels++;
 
channel->hw_value = nvm_chan[ch_idx];
-   channel->band = (ch_idx < num_2ghz_channels) ?
-   NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+   channel->band = is_5ghz ?
+   NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
channel->center_freq =
ieee80211_channel_to_frequency(
channel->hw_value, channel->band);
@@ -320,7 +328,6 @@ static int iwl_init_channel_map(struct device *dev, const 
struct iwl_cfg *cfg,
 * is not used in mvm, and is used for backwards compatibility
 */
channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
-   is_5ghz = channel->band == NL80211_BAND_5GHZ;
 
/* don't put limitations in case we're using LAR */
if (!lar_supported)
@@ -438,14 +445,15 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg 
*cfg,
 
 void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
 struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
-u8 tx_chains, u8 rx_chains, bool lar_supported)
+u8 tx_chains, u8 rx_chains, bool lar_supported,
+bool no_wide_in_5ghz)
 {
int n_channels;
int n_used = 0;
struct 

[PATCH 11/24] iwlwifi: mvm: remove session protection to allow channel switch

2017-08-18 Thread Luca Coelho
From: Avraham Stern 

If a time event is already scheduled when trying to schedule one for
channel switch, the code assumes the channel switch is already
scheduled and no further action is required.
However, it is possible that the scheduled time event is actually
for session protection (e.g. when the first beacon after association
contains the CSA IE). In this case the channel switch will not be
scheduled which will finally lead to disconnection.

Fix this by removing the old time event and schduling a new one for
the channel switch.

Signed-off-by: Avraham Stern 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  |  3 +-
 .../net/wireless/intel/iwlwifi/mvm/time-event.c| 34 --
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 2d1404c9fbf4..01143c491e53 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2023,8 +2023,7 @@ static void iwl_mvm_bss_info_changed_station(struct 
iwl_mvm *mvm,
 * We received a beacon from the associated AP so
 * remove the session protection.
 */
-   iwl_mvm_remove_time_event(mvm, mvmvif,
- >time_event_data);
+   iwl_mvm_stop_session_protection(mvm, vif);
 
iwl_mvm_sf_update(mvm, vif, false);
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
index 65d8299108d5..4d0314912e94 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2017 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
@@ -33,6 +34,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -726,8 +728,21 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
 {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_data *te_data = >time_event_data;
+   u32 id;
 
lockdep_assert_held(>mutex);
+
+   spin_lock_bh(>time_event_lock);
+   id = te_data->id;
+   spin_unlock_bh(>time_event_lock);
+
+   if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
+   IWL_DEBUG_TE(mvm,
+"don't remove TE with id=%u (not session 
protection)\n",
+id);
+   return;
+   }
+
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
 }
 
@@ -859,8 +874,23 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
lockdep_assert_held(>mutex);
 
if (te_data->running) {
-   IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
-   return -EBUSY;
+   u32 id;
+
+   spin_lock_bh(>time_event_lock);
+   id = te_data->id;
+   spin_unlock_bh(>time_event_lock);
+
+   if (id == TE_CHANNEL_SWITCH_PERIOD) {
+   IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
+   return -EBUSY;
+   }
+
+   /*
+* Remove the session protection time event to allow the
+* channel switch. If we got here, we just heard a beacon so
+* the session protection is not needed anymore anyway.
+*/
+   iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
}
 
time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
-- 
2.14.1



[PATCH 23/24] iwlwifi: mvm: remove useless check for mvm->cfg in iwl_parse_nvm_section()

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

At this point we have already copied the cfg pointer to mvm and we
have been dereferencing this pointer many times before, so it will
never be NULL or we would have crashed.  Remove the useless check.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index 5a6916f0b9ec..b05673e4a193 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -326,9 +326,6 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
}
}
 
-   if (WARN_ON(!mvm->cfg))
-   return NULL;
-
hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
-- 
2.14.1



[PATCH 18/24] iwlwifi: update channel flags parser

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

There are some new flags in the channel flags that we don't know
about.  Also, the "WIDE" flag is very confusing, because it actually
means 20MHz bandwidth, which is not very wide.

Add the new flags and rename the confusing one.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 51 +-
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 5c08f4d40f6a..1172e4572a82 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -183,22 +183,26 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
  * @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
  * @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
  * on same channel on 2.4 or same UNII band on 5.2
- * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
- * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
- * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
- * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
+ * @NVM_CHANNEL_UNIFORM: uniform spreading required
+ * @NVM_CHANNEL_20MHZ: 20 MHz channel okay
+ * @NVM_CHANNEL_40MHZ: 40 MHz channel okay
+ * @NVM_CHANNEL_80MHZ: 80 MHz channel okay
+ * @NVM_CHANNEL_160MHZ: 160 MHz channel okay
+ * @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
  */
 enum iwl_nvm_channel_flags {
-   NVM_CHANNEL_VALID = BIT(0),
-   NVM_CHANNEL_IBSS = BIT(1),
-   NVM_CHANNEL_ACTIVE = BIT(3),
-   NVM_CHANNEL_RADAR = BIT(4),
-   NVM_CHANNEL_INDOOR_ONLY = BIT(5),
-   NVM_CHANNEL_GO_CONCURRENT = BIT(6),
-   NVM_CHANNEL_WIDE = BIT(8),
-   NVM_CHANNEL_40MHZ = BIT(9),
-   NVM_CHANNEL_80MHZ = BIT(10),
-   NVM_CHANNEL_160MHZ = BIT(11),
+   NVM_CHANNEL_VALID   = BIT(0),
+   NVM_CHANNEL_IBSS= BIT(1),
+   NVM_CHANNEL_ACTIVE  = BIT(3),
+   NVM_CHANNEL_RADAR   = BIT(4),
+   NVM_CHANNEL_INDOOR_ONLY = BIT(5),
+   NVM_CHANNEL_GO_CONCURRENT   = BIT(6),
+   NVM_CHANNEL_UNIFORM = BIT(7),
+   NVM_CHANNEL_20MHZ   = BIT(8),
+   NVM_CHANNEL_40MHZ   = BIT(9),
+   NVM_CHANNEL_80MHZ   = BIT(10),
+   NVM_CHANNEL_160MHZ  = BIT(11),
+   NVM_CHANNEL_DC_HIGH = BIT(12),
 };
 
 #define CHECK_AND_PRINT_I(x)   \
@@ -327,7 +331,7 @@ static int iwl_init_channel_map(struct device *dev, const 
struct iwl_cfg *cfg,
channel->flags = 0;
 
IWL_DEBUG_EEPROM(dev,
-"Ch. %d [%sGHz] flags 0x%x 
%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
+"Ch. %d [%sGHz] flags 0x%x 
%s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
 channel->hw_value,
 is_5ghz ? "5.2" : "2.4",
 ch_flags,
@@ -337,10 +341,12 @@ static int iwl_init_channel_map(struct device *dev, const 
struct iwl_cfg *cfg,
 CHECK_AND_PRINT_I(RADAR),
 CHECK_AND_PRINT_I(INDOOR_ONLY),
 CHECK_AND_PRINT_I(GO_CONCURRENT),
-CHECK_AND_PRINT_I(WIDE),
+CHECK_AND_PRINT_I(UNIFORM),
+CHECK_AND_PRINT_I(20MHZ),
 CHECK_AND_PRINT_I(40MHZ),
 CHECK_AND_PRINT_I(80MHZ),
 CHECK_AND_PRINT_I(160MHZ),
+CHECK_AND_PRINT_I(DC_HIGH),
 channel->max_power,
 ((ch_flags & NVM_CHANNEL_IBSS) &&
  !(ch_flags & NVM_CHANNEL_RADAR))
@@ -865,22 +871,25 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct 
iwl_cfg *cfg,
prev_center_freq = center_freq;
 
IWL_DEBUG_DEV(dev, IWL_DL_LAR,
- "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x): 
Ad-Hoc %ssupported\n",
+ "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x): 
%s\n",
  center_freq,
  band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
  CHECK_AND_PRINT_I(VALID),
+ CHECK_AND_PRINT_I(IBSS),
  CHECK_AND_PRINT_I(ACTIVE),
  CHECK_AND_PRINT_I(RADAR),
- CHECK_AND_PRINT_I(WIDE),
+ CHECK_AND_PRINT_I(INDOOR_ONLY),
+ CHECK_AND_PRINT_I(GO_CONCURRENT),
+ CHECK_AND_PRINT_I(UNIFORM),
+ 

[PATCH 19/24] iwlwifi: mvm: change open and close criteria of a BA session

2017-08-18 Thread Luca Coelho
From: Gregory Greenman 

Tx BA session should be started according to the current throughput
without any dependence on the internal rate scaling state. The criteria
for opening a BA session will be 10 frames per second.

Sending frequent del BAs can cause inter-op issues with some APs. We'll
not close a BA session until we receive an explicit del BA from the
peer.

Signed-off-by: Gregory Greenman 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/constants.h |   1 +
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c| 117 -
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h   |   7 ++
 3 files changed, 73 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
index 753d4138e30f..976640fed334 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
@@ -136,6 +136,7 @@
 #define IWL_MVM_RS_SR_NO_DECREASE  85  /* percent */
 #define IWL_MVM_RS_AGG_TIME_LIMIT  4000/* 4 msecs. valid 
100-8000 */
 #define IWL_MVM_RS_AGG_DISABLE_START   3
+#define IWL_MVM_RS_AGG_START_THRESHOLD 10  /* num frames per 
second */
 #define IWL_MVM_RS_TPC_SR_FORCE_INCREASE   75  /* percent */
 #define IWL_MVM_RS_TPC_SR_NO_INCREASE  85  /* percent */
 #define IWL_MVM_RS_TPC_TX_POWER_STEP   3
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index cdf10ce9dbea..44c873082a31 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -622,7 +622,9 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
 
IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
 sta->addr, tid);
-   ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
+
+   /* start BA session until the peer sends del BA */
+   ret = ieee80211_start_tx_ba_session(sta, tid, 0);
if (ret == -EAGAIN) {
/*
 * driver and mac80211 is out of sync
@@ -636,15 +638,31 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
return ret;
 }
 
-static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, u8 tid,
- struct iwl_lq_sta *lq_data,
+static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
+ u8 tid, struct iwl_lq_sta *lq_sta,
  struct ieee80211_sta *sta)
 {
-   if (tid < IWL_MAX_TID_COUNT)
-   rs_tl_turn_on_agg_for_tid(mvm, lq_data, tid, sta);
-   else
+   struct iwl_mvm_tid_data *tid_data;
+
+   /*
+* In AP mode, tid can be equal to IWL_MAX_TID_COUNT
+* when the frame is not QoS
+*/
+   if (WARN_ON_ONCE(tid > IWL_MAX_TID_COUNT)) {
IWL_ERR(mvm, "tid exceeds max TID count: %d/%d\n",
tid, IWL_MAX_TID_COUNT);
+   return;
+   } else if (tid == IWL_MAX_TID_COUNT) {
+   return;
+   }
+
+   tid_data = >tid_data[tid];
+   if ((tid_data->state == IWL_AGG_OFF) &&
+   (lq_sta->tx_agg_tid_en & BIT(tid)) &&
+   (tid_data->tx_count_last >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
+   IWL_DEBUG_RATE(mvm, "try to aggregate tid %d\n", tid);
+   rs_tl_turn_on_agg_for_tid(mvm, lq_sta, tid, sta);
+   }
 }
 
 static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
@@ -753,8 +771,38 @@ static int rs_collect_tpc_data(struct iwl_mvm *mvm,
window);
 }
 
+static void rs_update_tid_tpt_stats(struct iwl_mvm *mvm,
+   struct iwl_mvm_sta *mvmsta,
+   u8 tid, int successes)
+{
+   struct iwl_mvm_tid_data *tid_data;
+
+   if (tid >= IWL_MAX_TID_COUNT)
+   return;
+
+   tid_data = >tid_data[tid];
+
+   /*
+* Measure if there're enough successful transmits per second.
+* These statistics are used only to decide if we can start a
+* BA session, so it should be updated only when A-MPDU is
+* off.
+*/
+   if (tid_data->state != IWL_AGG_OFF)
+   return;
+
+   if (time_is_before_jiffies(tid_data->tpt_meas_start + HZ) ||
+   (tid_data->tx_count >= IWL_MVM_RS_AGG_START_THRESHOLD)) {
+   tid_data->tx_count_last = tid_data->tx_count;
+   tid_data->tx_count = 0;
+   tid_data->tpt_meas_start = jiffies;
+   } else {
+   tid_data->tx_count += successes;
+   }
+}
+
 static int rs_collect_tlc_data(struct iwl_mvm *mvm,
-  struct iwl_lq_sta *lq_sta,
+  struct iwl_mvm_sta *mvmsta, u8 tid,
   

[PATCH 24/24] iwlwifi: use big-endian for the hw section of the nvm

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

Unlike the other sections of the NVM, the hw section is in big-endian.
To read a value from it, we had to cast it to __be16.  Fix that by
using __be16 * for the entire section.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 11 +--
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c   |  5 +++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index ea165b3e6dd3..aa382f719988 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -582,7 +582,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans 
*trans,
   const struct iwl_cfg *cfg,
   struct iwl_nvm_data *data,
   const __le16 *mac_override,
-  const __le16 *nvm_hw)
+  const __be16 *nvm_hw)
 {
const u8 *hw_addr;
 
@@ -629,7 +629,7 @@ static void iwl_set_hw_address_family_8000(struct iwl_trans 
*trans,
 
 static int iwl_set_hw_address(struct iwl_trans *trans,
  const struct iwl_cfg *cfg,
- struct iwl_nvm_data *data, const __le16 *nvm_hw,
+ struct iwl_nvm_data *data, const __be16 *nvm_hw,
  const __le16 *mac_override)
 {
if (cfg->mac_addr_from_csr) {
@@ -661,7 +661,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
 
 static bool
 iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
-   const __le16 *nvm_hw)
+   const __be16 *nvm_hw)
 {
/*
 * Workaround a bug in Indonesia SKUs where the regulatory in
@@ -677,8 +677,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct 
iwl_cfg *cfg,
 * Unlike the other sections in the NVM, the hw
 * section uses big-endian.
 */
-   u16 subsystem_id = be16_to_cpup((const __be16 *)nvm_hw
-   + SUBSYSTEM_ID);
+   u16 subsystem_id = be16_to_cpup(nvm_hw + SUBSYSTEM_ID);
u8 sku = (subsystem_id & 0x1e) >> 1;
 
if (sku == 5 || sku == 9) {
@@ -694,7 +693,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct 
iwl_cfg *cfg,
 
 struct iwl_nvm_data *
 iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
-  const __le16 *nvm_hw, const __le16 *nvm_sw,
+  const __be16 *nvm_hw, const __le16 *nvm_sw,
   const __le16 *nvm_calib, const __le16 *regulatory,
   const __le16 *mac_override, const __le16 *phy_sku,
   u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
index 50d9b3eaa4f8..2d1a24dd8410 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
@@ -77,7 +77,7 @@
  */
 struct iwl_nvm_data *
 iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
-  const __le16 *nvm_hw, const __le16 *nvm_sw,
+  const __be16 *nvm_hw, const __le16 *nvm_sw,
   const __le16 *nvm_calib, const __le16 *regulatory,
   const __le16 *mac_override, const __le16 *phy_sku,
   u8 tx_chains, u8 rx_chains, bool lar_fw_supported);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index b05673e4a193..422aa6be9932 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -292,7 +292,8 @@ static struct iwl_nvm_data *
 iwl_parse_nvm_sections(struct iwl_mvm *mvm)
 {
struct iwl_nvm_section *sections = mvm->nvm_sections;
-   const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku;
+   const __be16 *hw;
+   const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku;
bool lar_enabled;
 
/* Checking for required sections */
@@ -326,7 +327,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
}
}
 
-   hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
+   hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data;
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
-- 
2.14.1



[PATCH 13/24] iwlwifi: move BT_MBOX_PRINT macro to common header

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

Move the BT_MBOX_PRINT() macro from mvm/debugfs.c to fw/api/coex.h so
it can be reused and remove duplicate definition of BT_MBOX_MSG(),
keeping only the one already in coex.h.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/api/coex.h |  6 ++
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 12 
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
index d9a74db01f90..d09555afe2c5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
@@ -197,6 +197,12 @@ enum iwl_bt_mxbox_dw4 {
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS)
 
+#define BT_MBOX_PRINT(_num, _field, _end)  \
+   pos += scnprintf(buf + pos, bufsz - pos,\
+"\t%s: %d%s",  \
+#_field,   \
+BT_MBOX_MSG(notif, _num, _field),  \
+true ? "\n" : ", ");
 enum iwl_bt_activity_grading {
BT_OFF  = 0,
BT_ON_NO_CONNECTION = 1,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index c88a37397075..e97904c2c4d4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -469,18 +469,6 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct 
iwl_mvm *mvm, char *buf,
return ret ?: count;
 }
 
-#define BT_MBOX_MSG(_notif, _num, _field)   \
-   ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
-   >> BT_MBOX##_num##_##_field##_POS)
-
-
-#define BT_MBOX_PRINT(_num, _field, _end)  \
-   pos += scnprintf(buf + pos, bufsz - pos,\
-"\t%s: %d%s",  \
-#_field,   \
-BT_MBOX_MSG(notif, _num, _field),  \
-true ? "\n" : ", ");
-
 static
 int iwl_mvm_coex_dump_mbox(struct iwl_mvm *mvm,
   struct iwl_bt_coex_profile_notif *notif, char *buf,
-- 
2.14.1



[PATCH 21/24] iwlwifi: fw: fix lar_enabled endian problem in iwl_fw_get_nvm

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

We read the regulatory.lar_enabled field in iwl_fw_get_nvm() and store
it in nvm->lar_enabled, taking care of endianness.  But then later we
read it again to pass the value to iwl_init_sbands() without handling
endianness.  To solve this, simply reuse nvm->lar_enabled when calling
that function.

Fixes: e9e1ba3dbf00 ("iwlwifi: mvm: support getting nvm data from firmware")
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/nvm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/fw/nvm.c
index e81f6dd3744e..bd2e1fb43f5a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/nvm.c
@@ -148,8 +148,7 @@ struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime 
*fwrt)
rsp->regulatory.channel_profile,
nvm->valid_tx_ant & fwrt->fw->valid_tx_ant,
nvm->valid_rx_ant & fwrt->fw->valid_rx_ant,
-   rsp->regulatory.lar_enabled && lar_fw_supported,
-   false);
+   nvm->lar_enabled, false);
 
iwl_free_resp();
return nvm;
-- 
2.14.1



[PATCH 16/24] iwlwifi: distinguish different RF modules in A000 devices

2017-08-18 Thread Luca Coelho
From: Tzipi Peres 

Newer versions of A000 devices come with two diffenent RF modules.
The PCI_ID, the subsystem ID and the RF ID are identical in these two cases,
so we need to differentiate them by using the CSR_HW_RF_ID register-
in order to load the appropriate firmware.

Signed-off-by: Tzipi Peres 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/cfg/a000.c   | 34 ++---
 drivers/net/wireless/intel/iwlwifi/iwl-config.h |  4 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-csr.h|  7 -
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c   | 23 -
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c |  2 +-
 5 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
index 40d67a5a2635..dcd35b5c9d24 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
@@ -76,13 +76,19 @@
 #define IWL_A000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
 #define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
 #define IWL_A000_HR_F0_FW_PRE  "iwlwifi-QuQnj-f0-hr-a0-"
+#define IWL_A000_JF_B0_FW_PRE  "iwlwifi-QuQnj-a0-jf-b0-"
+#define IWL_A000_HR_A0_FW_PRE  "iwlwifi-QuQnj-a0-hr-a0-"
 
 #define IWL_A000_HR_MODULE_FIRMWARE(api) \
IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode"
 #define IWL_A000_JF_MODULE_FIRMWARE(api) \
IWL_A000_JF_FW_PRE "-" __stringify(api) ".ucode"
-#define IWL_A000_HR_QNJ_MODULE_FIRMWARE(api) \
+#define IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(api) \
IWL_A000_HR_F0_FW_PRE "-" __stringify(api) ".ucode"
+#define IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(api) \
+   IWL_A000_JF_B0_FW_PRE "-" __stringify(api) ".ucode"
+#define IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(api) \
+   IWL_A000_HR_A0_FW_PRE "-" __stringify(api) ".ucode"
 
 #define NVM_HW_SECTION_NUM_FAMILY_A000 10
 
@@ -171,7 +177,7 @@ const struct iwl_cfg iwla000_2ax_cfg_hr = {
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
-const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = {
+const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0 = {
.name = "Intel(R) Dual Band Wireless AX a000",
.fw_name_pre = IWL_A000_HR_F0_FW_PRE,
IWL_DEVICE_A000,
@@ -181,6 +187,28 @@ const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = {
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
+const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0 = {
+   .name = "Intel(R) Dual Band Wireless AX a000",
+   .fw_name_pre = IWL_A000_JF_B0_FW_PRE,
+   IWL_DEVICE_A000,
+   .ht_params = _a000_ht_params,
+   .nvm_ver = IWL_A000_NVM_VERSION,
+   .nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+};
+
+const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0 = {
+   .name = "Intel(R) Dual Band Wireless AX a000",
+   .fw_name_pre = IWL_A000_HR_A0_FW_PRE,
+   IWL_DEVICE_A000,
+   .ht_params = _a000_ht_params,
+   .nvm_ver = IWL_A000_NVM_VERSION,
+   .nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+};
+
 MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL_A000_HR_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL_A000_HR_F0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL_A000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL_A000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 573dbeed3fbf..b82a3d0f64b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -463,7 +463,9 @@ extern const struct iwl_cfg iwla000_2ac_cfg_hr;
 extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb;
 extern const struct iwl_cfg iwla000_2ac_cfg_jf;
 extern const struct iwl_cfg iwla000_2ax_cfg_hr;
-extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr;
+extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0;
+extern const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0;
+extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0;
 #endif /* CONFIG_IWLMVM */
 
 #endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index 7d468ad7cb6a..b03e0f975b5a 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -354,11 +354,16 @@ enum {
 #define CSR_HW_REV_TYPE_135(0x120)
 #define CSR_HW_REV_TYPE_7265D  (0x210)
 #define 

[PATCH 15/24] iwlwifi: mvm: Fix channel switch in case of count <= 1

2017-08-18 Thread Luca Coelho
From: Ilan Peer 

The code did not consider the case that the channel switch counter
is <= 1, which would result with an inaccurate calculation of the
time event apply time.

As the specification states that in case of counter == 0 the switch
occurs at any time after the reception the frame, and for counter == 1
the switch would happens before the next TBTT, schedule the time
event immediately.

Signed-off-by: Ilan Peer 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 01143c491e53..cfabe302c9c7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -3875,11 +3875,16 @@ static int iwl_mvm_pre_channel_switch(struct 
ieee80211_hw *hw,
 
/* Schedule the time event to a bit before beacon 1,
 * to make sure we're in the new channel when the
-* GO/AP arrives.
+* GO/AP arrives. In case count <= 1 immediately schedule the
+* TE (this might result with some packet loss or connection
+* loss).
 */
-   apply_time = chsw->device_timestamp +
-   ((vif->bss_conf.beacon_int * (chsw->count - 1) -
- IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
+   if (chsw->count <= 1)
+   apply_time = 0;
+   else
+   apply_time = chsw->device_timestamp +
+   ((vif->bss_conf.beacon_int * (chsw->count - 1) -
+ IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
 
if (chsw->block_tx)
iwl_mvm_csa_client_absent(mvm, vif);
-- 
2.14.1



[PATCH 17/24] iwlwifi: pci: add new PCI ID for 7265D

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

We have a new PCI subsystem ID for 7265D.  Add it to the list.

Cc: sta...@vger.kernel.org
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 27d1eec1c899..5398a0917f06 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -430,6 +430,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
+   {IWL_PCI_DEVICE(0x095A, 0x9E10, iwl7265_2ac_cfg)},
 
 /* 8000 Series */
{IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
-- 
2.14.1



[PATCH 14/24] iwlwifi: Demote messages about fw flags size to info

2017-08-18 Thread Luca Coelho
From: João Paulo Rechi Vita 

These messages are not reporting a real error, just the fact that the
firmware knows about more flags than the driver.

Currently these messages are presented to the user during boot if there
is no bootsplash covering the console, even when booting the kernel with
"quiet".

Demoting it to the warn level helps having a clean boot process.

Signed-off-by: João Paulo Rechi Vita 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index cdb765656115..bd3902f888e0 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -487,9 +487,9 @@ static void iwl_set_ucode_api_flags(struct iwl_drv *drv, 
const u8 *data,
int i;
 
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32)) {
-   IWL_ERR(drv,
-   "api flags index %d larger than supported by driver\n",
-   api_index);
+   IWL_WARN(drv,
+"api flags index %d larger than supported by driver\n",
+api_index);
return;
}
 
@@ -508,9 +508,9 @@ static void iwl_set_ucode_capabilities(struct iwl_drv *drv, 
const u8 *data,
int i;
 
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32)) {
-   IWL_ERR(drv,
-   "capa flags index %d larger than supported by driver\n",
-   api_index);
+   IWL_WARN(drv,
+"capa flags index %d larger than supported by 
driver\n",
+api_index);
return;
}
 
-- 
2.14.1



[PATCH 12/24] iwlwifi: mvm: don't send BAR on flushed frames

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

When we flush a queue, the packets will have a 'failed'
status but we shouldn't send a BAR. This check was missing.
Because of that, when we got an ampdu_action with
IEEE80211_AMPDU_TX_STOP_FLUSH, we started the following
ping pong with the firmware:

1) Set the station as 'draining'
2) Get a failed Tx status (DRAINED)
3) Send a BAR because of the failed Tx status

(loop of 2 and 3)

This loop wasn't endless since the BAR isn't sent on a
queue that would trigger a "nested" BAR.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 48f028366d51..52f9e8a76124 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1331,6 +1331,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
while (!skb_queue_empty()) {
struct sk_buff *skb = __skb_dequeue();
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+   bool flushed = false;
 
skb_freed++;
 
@@ -1344,6 +1345,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
case TX_STATUS_DIRECT_DONE:
info->flags |= IEEE80211_TX_STAT_ACK;
break;
+   case TX_STATUS_FAIL_FIFO_FLUSHED:
+   case TX_STATUS_FAIL_DRAIN_FLOW:
+   flushed = true;
+   break;
case TX_STATUS_FAIL_DEST_PS:
/* the FW should have stopped the queue and not
 * return this status
@@ -1366,7 +1371,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
/* Single frame failure in an AMPDU queue => send BAR */
if (info->flags & IEEE80211_TX_CTL_AMPDU &&
!(info->flags & IEEE80211_TX_STAT_ACK) &&
-   !(info->flags & IEEE80211_TX_STAT_TX_FILTERED))
+   !(info->flags & IEEE80211_TX_STAT_TX_FILTERED) && !flushed)
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
 
-- 
2.14.1



[PATCH 10/24] iwlwifi: mvm: update the firmware API in TX

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

The firmware team is now re-using a bit that hasn't been
used for a few generations. Re-use for TX_ON_AIR drop.
This bit will be set by the firmware to indicate that
a frame in an A-MPDU was dropped but not because of the
already mapped reasons.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/api/tx.h | 9 +++--
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c| 2 +-
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
index 4928310ddd31..14ad9fb895f9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
@@ -409,7 +409,8 @@ enum iwl_tx_status {
  * @AGG_TX_STATE_BT_PRIO:
  * @AGG_TX_STATE_FEW_BYTES:
  * @AGG_TX_STATE_ABORT:
- * @AGG_TX_STATE_LAST_SENT_TTL:
+ * @AGG_TX_STATE_TX_ON_AIR_DROP: TX_ON_AIR signal drop without underrun or
+ * BT detection
  * @AGG_TX_STATE_LAST_SENT_TRY_CNT:
  * @AGG_TX_STATE_LAST_SENT_BT_KILL:
  * @AGG_TX_STATE_SCD_QUERY:
@@ -433,7 +434,7 @@ enum iwl_tx_agg_status {
AGG_TX_STATE_BT_PRIO = 0x002,
AGG_TX_STATE_FEW_BYTES = 0x004,
AGG_TX_STATE_ABORT = 0x008,
-   AGG_TX_STATE_LAST_SENT_TTL = 0x010,
+   AGG_TX_STATE_TX_ON_AIR_DROP = 0x010,
AGG_TX_STATE_LAST_SENT_TRY_CNT = 0x020,
AGG_TX_STATE_LAST_SENT_BT_KILL = 0x040,
AGG_TX_STATE_SCD_QUERY = 0x080,
@@ -445,10 +446,6 @@ enum iwl_tx_agg_status {
AGG_TX_STATE_TRY_CNT_MSK = 0xf << AGG_TX_STATE_TRY_CNT_POS,
 };
 
-#define AGG_TX_STATE_LAST_SENT_MSK  (AGG_TX_STATE_LAST_SENT_TTL| \
-AGG_TX_STATE_LAST_SENT_TRY_CNT| \
-AGG_TX_STATE_LAST_SENT_BT_KILL)
-
 /*
  * The mask below describes a status where we are absolutely sure that the MPDU
  * wasn't sent. For BA/Underrun we cannot be that sure. All we know that we've
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 6d7d1a66af81..48f028366d51 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1515,7 +1515,7 @@ static const char *iwl_get_agg_tx_status(u16 status)
AGG_TX_STATE_(BT_PRIO);
AGG_TX_STATE_(FEW_BYTES);
AGG_TX_STATE_(ABORT);
-   AGG_TX_STATE_(LAST_SENT_TTL);
+   AGG_TX_STATE_(TX_ON_AIR_DROP);
AGG_TX_STATE_(LAST_SENT_TRY_CNT);
AGG_TX_STATE_(LAST_SENT_BT_KILL);
AGG_TX_STATE_(SCD_QUERY);
-- 
2.14.1



[PATCH 07/24] iwlwifi: mvm: include more debug data when we get an unexpected baid

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

When we get a valid baid in a received frame, we need to
check that we are aware of this baid. If not, we check
that the OLD_SN bit set. If that's not the case, we issue
a WARNING. Print more data when that happens.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 6b8e57b7234a..4fbf102b3a98 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -636,8 +636,8 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
baid_data = rcu_dereference(mvm->baid_map[baid]);
if (!baid_data) {
WARN(!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN),
-"Received baid %d, but no data exists for this BAID\n",
-baid);
+"Received baid %d, but no data exists for this BAID - 
reorder data 0x%x\n",
+baid, reorder);
return false;
}
 
@@ -758,7 +758,9 @@ static void iwl_mvm_agg_rx_received(struct iwl_mvm *mvm,
 
data = rcu_dereference(mvm->baid_map[baid]);
if (!data) {
-   WARN_ON(!(reorder_data & IWL_RX_MPDU_REORDER_BA_OLD_SN));
+   WARN(!(reorder_data & IWL_RX_MPDU_REORDER_BA_OLD_SN),
+"OLD_SN isn't set, but no data exists for baid %d - 
reorder data 0x%x\n",
+baid, reorder_data);
goto out;
}
 
-- 
2.14.1



[PATCH 02/24] iwlwifi: mvm: consider RFKILL during INIT as success

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

There's no need to differentiate an INIT that ended early because of
RFKILL from one that succeded.  Additionally, if INIT fails later,
during calibration, due to RFKILL, we can just return success and
continue as if we were already in RFKILL to start with.

Remove this unnecessary differentiation and do some other small
clean-ups while at it.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c  | 38 +---
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c |  1 -
 2 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 0099050f6e2b..ed18479a7b8c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -475,13 +475,13 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool 
read_nvm)
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_INIT);
if (ret) {
IWL_ERR(mvm, "Failed to start INIT ucode: %d\n", ret);
-   goto error;
+   goto remove_notif;
}
 
if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
ret = iwl_mvm_send_bt_init_conf(mvm);
if (ret)
-   goto error;
+   goto remove_notif;
}
 
/* Read the NVM only at driver load time, no need to do this twice */
@@ -490,7 +490,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool 
read_nvm)
ret = iwl_nvm_init(mvm, true);
if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
-   goto error;
+   goto remove_notif;
}
}
 
@@ -498,8 +498,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool 
read_nvm)
if (mvm->nvm_file_name)
iwl_mvm_load_nvm_to_nic(mvm);
 
-   ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
-   WARN_ON(ret);
+   WARN_ON(iwl_nvm_check_version(mvm->nvm_data, mvm->trans));
 
/*
 * abort after reading the nvm in case RF Kill is on, we will complete
@@ -508,9 +507,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool 
read_nvm)
if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm,
  "jump over all phy activities due to RF 
kill\n");
-   iwl_remove_notification(>notif_wait, _wait);
-   ret = 1;
-   goto out;
+   goto remove_notif;
}
 
mvm->calibrating = true;
@@ -518,17 +515,13 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool 
read_nvm)
/* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
if (ret)
-   goto error;
+   goto remove_notif;
 
-   /*
-* Send phy configurations command to init uCode
-* to start the 16.0 uCode init image internal calibrations.
-*/
ret = iwl_send_phy_cfg_cmd(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
ret);
-   goto error;
+   goto remove_notif;
}
 
/*
@@ -536,15 +529,21 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool 
read_nvm)
 * just wait for the calibration complete notification.
 */
ret = iwl_wait_notification(>notif_wait, _wait,
-   MVM_UCODE_CALIB_TIMEOUT);
+   MVM_UCODE_CALIB_TIMEOUT);
+   if (!ret)
+   goto out;
 
-   if (ret && iwl_mvm_is_radio_hw_killed(mvm)) {
+   if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
-   ret = 1;
+   ret = 0;
+   } else {
+   IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
+   ret);
}
+
goto out;
 
-error:
+remove_notif:
iwl_remove_notification(>notif_wait, _wait);
 out:
mvm->calibrating = false;
@@ -1043,9 +1042,6 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
 
if (ret) {
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
-   /* this can't happen */
-   if (WARN_ON(ret > 0))
-   ret = -ERFKILL;
return ret;
}
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 640881c8d703..76d256a9ad71 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -751,7 +751,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
iwl_mvm_stop_device(mvm);

[PATCH 05/24] iwlwifi: pcie: support short Tx queues for A000 device family

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

This allows to modify TFD_TX_CMD_SLOTS to a power of 2
which is smaller than 256.
Note that we still need to set values to wrap at 256
into the scheduler's write pointer, but all the rest of
the code can use shorter transmit queues.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/pcie/ctxt-info.c|  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 13 +++
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   |  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c|  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  | 41 +++---
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   | 13 +++
 6 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
index eddaca76d514..3fc4343581ee 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
@@ -244,7 +244,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
ctxt_info->hcmd_cfg.cmd_queue_addr =
cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
ctxt_info->hcmd_cfg.cmd_queue_size =
-   TFD_QUEUE_CB_SIZE(TFD_QUEUE_SIZE_MAX);
+   TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS);
 
/* allocate ucode sections in dram and set addresses */
ret = iwl_pcie_ctxt_info_init_fw_sec(trans, fw, ctxt_info);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index f46871840fd2..79020cf8c79c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -661,10 +661,16 @@ static inline void iwl_pcie_sw_reset(struct iwl_trans 
*trans)
usleep_range(5000, 6000);
 }
 
+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,
 struct iwl_txq *txq, int idx)
 {
-   return txq->tfds + trans_pcie->tfd_size * idx;
+   return txq->tfds + trans_pcie->tfd_size * iwl_pcie_get_cmd_index(txq,
+idx);
 }
 
 static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
@@ -726,11 +732,6 @@ static inline bool iwl_queue_used(const struct iwl_txq *q, 
int i)
!(i < q->read_ptr && i >= q->write_ptr);
 }
 
-static inline u8 get_cmd_index(struct iwl_txq *q, u32 index)
-{
-   return index & (q->n_window - 1);
-}
-
 static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
 {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 351c4423125a..e5d2bf0bde37 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1176,7 +1176,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
 
sequence = le16_to_cpu(pkt->hdr.sequence);
index = SEQ_TO_INDEX(sequence);
-   cmd_index = get_cmd_index(txq, index);
+   cmd_index = iwl_pcie_get_cmd_index(txq, index);
 
if (rxq->id == 0)
iwl_op_mode_rx(trans->op_mode, >napi,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 382d7c251066..3ecafa2ad922 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2835,7 +2835,7 @@ static struct iwl_trans_dump_data
spin_lock_bh(>lock);
ptr = cmdq->write_ptr;
for (i = 0; i < cmdq->n_window; i++) {
-   u8 idx = get_cmd_index(cmdq, ptr);
+   u8 idx = iwl_pcie_get_cmd_index(cmdq, ptr);
u32 caplen, cmdlen;
 
cmdlen = iwl_trans_pcie_get_cmdlen(trans, cmdq->tfds +
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 4db45e56b6ba..d74613fcb756 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -88,14 +88,14 @@ static void iwl_pcie_gen2_update_byte_tbl(struct iwl_txq 
*txq, u16 byte_cnt,
  int num_tbs)
 {
struct iwlagn_scd_bc_tbl *scd_bc_tbl = txq->bc_tbl.addr;
-   int write_ptr = txq->write_ptr;
+   int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
u8 filled_tfd_size, num_fetch_chunks;
u16 len = byte_cnt;
__le16 bc_ent;
 
len = DIV_ROUND_UP(len, 4);
 
-   if 

[PATCH 06/24] iwlwifi: mvm: add command name for FRAME_RELEASE

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

This name was missing in the list.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 76d256a9ad71..231878969332 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -384,6 +384,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = 
{
HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
HCMD_NAME(REPLY_RX_PHY_CMD),
HCMD_NAME(REPLY_RX_MPDU_CMD),
+   HCMD_NAME(FRAME_RELEASE),
HCMD_NAME(BA_NOTIF),
HCMD_NAME(MCC_UPDATE_CMD),
HCMD_NAME(MCC_CHUB_UPDATE_CMD),
-- 
2.14.1



[PATCH 04/24] iwlwifi: mvm: support new Coex firmware API

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

The firmware now adds more information about time sharing
with the Bluetooth core.
Adapt the API structures and add the new fields in the
debugfs hooks.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/api/coex.h | 31 ++
 drivers/net/wireless/intel/iwlwifi/fw/file.h |  3 +++
 drivers/net/wireless/intel/iwlwifi/mvm/coex.c| 33 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 13 +++---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |  6 +
 5 files changed, 77 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
index 2ba3ea4fa999..d9a74db01f90 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
@@ -178,6 +178,7 @@ enum iwl_bt_mxbox_dw3 {
BT_MBOX(3, ACL_STATE, 3, 1),
BT_MBOX(3, MSTR_STATE, 4, 1),
BT_MBOX(3, OBX_STATE, 5, 1),
+   BT_MBOX(3, A2DP_SRC, 6, 1),
BT_MBOX(3, OPEN_CON_2, 8, 2),
BT_MBOX(3, TRAFFIC_LOAD, 10, 2),
BT_MBOX(3, CHL_SEQN_LSB, 12, 1),
@@ -187,6 +188,11 @@ enum iwl_bt_mxbox_dw3 {
BT_MBOX(3, UPDATE_REQUEST, 21, 1),
 };
 
+enum iwl_bt_mxbox_dw4 {
+   BT_MBOX(4, ATS_BT_INTERVAL, 0, 7),
+   BT_MBOX(4, ATS_BT_ACTIVE_MAX_TH, 7, 7),
+};
+
 #define BT_MBOX_MSG(_notif, _num, _field)   \
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS)
@@ -220,6 +226,31 @@ enum iwl_bt_ci_compliance {
  * @reserved: reserved
  */
 struct iwl_bt_coex_profile_notif {
+   __le32 mbox_msg[8];
+   __le32 msg_idx;
+   __le32 bt_ci_compliance;
+
+   __le32 primary_ch_lut;
+   __le32 secondary_ch_lut;
+   __le32 bt_activity_grading;
+   u8 ttc_status;
+   u8 rrc_status;
+   __le16 reserved;
+} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_5 */
+
+/**
+ * struct iwl_bt_coex_profile_notif - notification about BT coex
+ * @mbox_msg: message from BT to WiFi
+ * @msg_idx: the index of the message
+ * @bt_ci_compliance: enum %iwl_bt_ci_compliance
+ * @primary_ch_lut: LUT used for primary channel  iwl_bt_coex_lut_type
+ * @secondary_ch_lut: LUT used for secondary channel  iwl_bt_coex_lut_type
+ * @bt_activity_grading: the activity of BT  iwl_bt_activity_grading
+ * @ttc_status: is TTC enabled - one bit per PHY
+ * @rrc_status: is RRC enabled - one bit per PHY
+ * @reserved: reserved
+ */
+struct iwl_bt_coex_profile_notif_v4 {
__le32 mbox_msg[4];
__le32 msg_idx;
__le32 bt_ci_compliance;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h 
b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index d933aa324ffe..a1cd2f41b026 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -246,6 +246,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
  * @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement.
  * @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2
  * @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used
+ * @IWL_UCODE_TLV_API_ATS_COEX_EXTERNAL: the coex notification is enlared to
+ * include information about ACL time sharing.
  *
  * @NUM_IWL_UCODE_TLV_API: number of bits used
  */
@@ -262,6 +264,7 @@ enum iwl_ucode_tlv_api {
/* API Set 1 */
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE   = (__force 
iwl_ucode_tlv_api_t)34,
IWL_UCODE_TLV_API_NEW_RX_STATS  = (__force 
iwl_ucode_tlv_api_t)35,
+   IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL = (__force 
iwl_ucode_tlv_api_t)37,
 
NUM_IWL_UCODE_TLV_API
 #ifdef __CHECKER__
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
index 890dbfff3a06..79c80f181f7d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2017Intel 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) 2013 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2017Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -512,17 +514,36 @@ void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_bt_coex_profile_notif 

[PATCH 08/24] iwlwifi: mvm: group all dummy SAR function declarations together

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

We have some of the SAR dummy functions when ACPI is not set declared
in mvm.h and some declared in fw.c.  Group them all together in fw.c
for consistency and to avoid static/non-static issues.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c  | 11 +++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 14 --
 2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index ed18479a7b8c..90ae50f7768a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -996,6 +996,17 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
 {
return 0;
 }
+
+int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a,
+  int prof_b)
+{
+   return -ENOENT;
+}
+
+int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
+{
+   return -ENOENT;
+}
 #endif /* CONFIG_ACPI */
 
 static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index d58de9b80886..74fdd33fd9fb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1825,21 +1825,7 @@ int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
 u32 duration, u32 timeout);
 bool iwl_mvm_lqm_active(struct iwl_mvm *mvm);
 
-#ifdef CONFIG_ACPI
 int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
 int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
-#else
-static inline
-int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
-{
-   return -ENOENT;
-}
-
-static inline
-int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
-{
-   return -ENOENT;
-}
-#endif /* CONFIG_ACPI */
 
 #endif /* __IWL_MVM_H__ */
-- 
2.14.1



[PATCH 09/24] iwlwifi: mvm: use mvmsta consistently in rs.c

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

We use mvmsta for the sta->drv_priv in mvm, but in rs.c we have a
bunch of instances using sta_priv, which is probably due to it being
copied from dvm.  Change all occurrences to mvmsta for consistency
with the rest of the driver

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 30 ++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 65beca3a457a..cdf10ce9dbea 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1673,14 +1673,14 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, 
struct ieee80211_sta *sta,
 struct iwl_scale_tbl_info *tbl,
 enum rs_action scale_action)
 {
-   struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
+   struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
if ((!is_vht(>rate) && !is_ht(>rate)) ||
tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
scale_action == RS_ACTION_DOWNSCALE)
-   sta_priv->tlc_amsdu = false;
+   mvmsta->tlc_amsdu = false;
else
-   sta_priv->tlc_amsdu = true;
+   mvmsta->tlc_amsdu = true;
 }
 
 /*
@@ -2228,11 +2228,11 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
u16 high_low;
s32 sr;
u8 prev_agg = lq_sta->is_agg;
-   struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
+   struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_tid_data *tid_data;
struct rs_rate *rate;
 
-   lq_sta->is_agg = !!sta_priv->agg_tids;
+   lq_sta->is_agg = !!mvmsta->agg_tids;
 
/*
 * Select rate-scale / modulation-mode table to work with in
@@ -2491,7 +2491,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
 
if (tid != IWL_MAX_TID_COUNT) {
-   tid_data = _priv->tid_data[tid];
+   tid_data = >tid_data[tid];
if (tid_data->state != IWL_AGG_OFF) {
IWL_DEBUG_RATE(mvm,
   "Stop aggregation on tid 
%d\n",
@@ -2507,7 +2507,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != IWL_MAX_TID_COUNT)) {
-   tid_data = _priv->tid_data[tid];
+   tid_data = >tid_data[tid];
if (tid_data->state == IWL_AGG_OFF && !ndp) {
IWL_DEBUG_RATE(mvm,
   "try to aggregate tid 
%d\n",
@@ -2900,10 +2900,10 @@ static void rs_get_rate(void *mvm_r, struct 
ieee80211_sta *sta, void *mvm_sta,
 static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
  gfp_t gfp)
 {
-   struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
+   struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
struct iwl_mvm *mvm  = IWL_OP_MODE_GET_MVM(op_mode);
-   struct iwl_lq_sta *lq_sta = _priv->lq_sta;
+   struct iwl_lq_sta *lq_sta = >lq_sta;
 
IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
 
@@ -2917,7 +2917,7 @@ static void *rs_alloc_sta(void *mvm_rate, struct 
ieee80211_sta *sta,
memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));
lq_sta->pers.last_rssi = S8_MIN;
 
-   return _priv->lq_sta;
+   return >lq_sta;
 }
 
 static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
@@ -3109,8 +3109,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct 
ieee80211_sta *sta,
struct ieee80211_hw *hw = mvm->hw;
struct ieee80211_sta_ht_cap *ht_cap = >ht_cap;
struct ieee80211_sta_vht_cap *vht_cap = >vht_cap;
-   struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
-   struct iwl_lq_sta *lq_sta = _priv->lq_sta;
+   struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+   struct iwl_lq_sta *lq_sta = >lq_sta;
struct ieee80211_supported_band *sband;
unsigned long supp; /* must be unsigned long for for_each_set_bit */
 
@@ -3119,8 +3119,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct 
ieee80211_sta *sta,
 
sband = hw->wiphy->bands[band];
 
-   lq_sta->lq.sta_id = sta_priv->sta_id;
-   sta_priv->tlc_amsdu = false;
+   

[PATCH 00/24] iwlwifi: updates intended for v4.14 2017-08-18

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

Hi,

Here's one more set of patches for v4.14.  These are the changes:

* Work for the upcoming A000 device family continues;
* Improvements in debugging;
* A couple of improvements in block-ack sessions;
* Some fixes for channel switch;
* A workaround for a HW data bug;
* Some FW API updates;
* General fixes and cleanups here and there.

As usual, I'm pushing this to a pending branch, for kbuild bot, and
will send a pull-request later.

Please review.

Cheers,
Luca.

Avraham Stern (1):
  iwlwifi: mvm: remove session protection to allow channel switch

Emmanuel Grumbach (7):
  iwlwifi: mvm: remove the corunning support
  iwlwifi: mvm: support new Coex firmware API
  iwlwifi: pcie: support short Tx queues for A000 device family
  iwlwifi: mvm: add command name for FRAME_RELEASE
  iwlwifi: mvm: include more debug data when we get an unexpected baid
  iwlwifi: mvm: update the firmware API in TX
  iwlwifi: mvm: don't send BAR on flushed frames

Gregory Greenman (1):
  iwlwifi: mvm: change open and close criteria of a BA session

Ilan Peer (1):
  iwlwifi: mvm: Fix channel switch in case of count <= 1

João Paulo Rechi Vita (1):
  iwlwifi: Demote messages about fw flags size to info

Luca Coelho (12):
  iwlwifi: mvm: consider RFKILL during INIT as success
  iwlwifi: call iwl_remove_notification from iwl_wait_notification
  iwlwifi: mvm: group all dummy SAR function declarations together
  iwlwifi: mvm: use mvmsta consistently in rs.c
  iwlwifi: move BT_MBOX_PRINT macro to common header
  iwlwifi: pci: add new PCI ID for 7265D
  iwlwifi: update channel flags parser
  iwlwifi: add workaround to disable wide channels in 5GHz
  iwlwifi: fw: fix lar_enabled endian problem in iwl_fw_get_nvm
  iwlwifi: mvm: remove useless argument in iwl_nvm_init()
  iwlwifi: mvm: remove useless check for mvm->cfg in
iwl_parse_nvm_section()
  iwlwifi: use big-endian for the hw section of the nvm

Tzipi Peres (1):
  iwlwifi: distinguish different RF modules in A000 devices

 drivers/net/wireless/intel/iwlwifi/cfg/a000.c  |  34 ++-
 drivers/net/wireless/intel/iwlwifi/fw/api/coex.h   |  50 +++-
 .../net/wireless/intel/iwlwifi/fw/api/commands.h   |  12 -
 drivers/net/wireless/intel/iwlwifi/fw/api/config.h |   8 -
 drivers/net/wireless/intel/iwlwifi/fw/api/tx.h |   9 +-
 drivers/net/wireless/intel/iwlwifi/fw/file.h   |   3 +
 drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c |  25 +-
 drivers/net/wireless/intel/iwlwifi/fw/nvm.c|   2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h|   4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-csr.h   |   7 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c   |  12 +-
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 118 +---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h |   5 +-
 drivers/net/wireless/intel/iwlwifi/mvm/coex.c  | 301 ++---
 drivers/net/wireless/intel/iwlwifi/mvm/constants.h |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c   |  30 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c|  54 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  |  16 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |  31 +--
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c   | 106 
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   |   6 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c| 143 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c  |   8 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h   |   7 +
 .../net/wireless/intel/iwlwifi/mvm/time-event.c|  34 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c|   9 +-
 .../net/wireless/intel/iwlwifi/pcie/ctxt-info.c|   2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c  |  24 +-
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  13 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   |   2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c|   4 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  |  41 ++-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   |  13 +-
 33 files changed, 511 insertions(+), 624 deletions(-)

-- 
2.14.1



[PATCH 01/24] iwlwifi: mvm: remove the corunning support

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

The corunning block was supposed to help in coex scenarios.
It required the driver to configure the firmware based on
the coupling between the two antennas of the devices.
This was never in use and the configuration sent by the
driver has always been blank.
Remove all that code.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/api/coex.h   |  13 -
 .../net/wireless/intel/iwlwifi/fw/api/commands.h   |  12 -
 drivers/net/wireless/intel/iwlwifi/fw/api/config.h |   8 -
 drivers/net/wireless/intel/iwlwifi/mvm/coex.c  | 268 -
 drivers/net/wireless/intel/iwlwifi/mvm/constants.h |   1 -
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c   |   5 -
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |   9 -
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   |   4 -
 8 files changed, 320 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
index df4ecec59b40..2ba3ea4fa999 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
@@ -76,7 +76,6 @@ enum iwl_bt_coex_lut_type {
BT_COEX_INVALID_LUT = 0xff,
 }; /* BT_COEX_DECISION_LUT_INDEX_API_E_VER_1 */
 
-#define BT_COEX_CORUN_LUT_SIZE (32)
 #define BT_REDUCED_TX_POWER_BIT BIT(7)
 
 enum iwl_bt_coex_mode {
@@ -106,18 +105,6 @@ struct iwl_bt_coex_cmd {
__le32 enabled_modules;
 } __packed; /* BT_COEX_CMD_API_S_VER_6 */
 
-/**
- * struct iwl_bt_coex_corun_lut_update - bt coex update the corun lut
- * @corun_lut20: co-running 20 MHz LUT configuration
- * @corun_lut40: co-running 40 MHz LUT configuration
- *
- * The structure is used for the BT_COEX_UPDATE_CORUN_LUT command.
- */
-struct iwl_bt_coex_corun_lut_update_cmd {
-   __le32 corun_lut20[BT_COEX_CORUN_LUT_SIZE];
-   __le32 corun_lut40[BT_COEX_CORUN_LUT_SIZE];
-} __packed; /* BT_COEX_UPDATE_CORUN_LUT_API_S_VER_1 */
-
 /**
  * struct iwl_bt_coex_reduced_txp_update_cmd
  * @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 0eb35b119ae9..074868394427 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -135,12 +135,6 @@ enum iwl_legacy_cmds {
 */
DBG_CFG = 0x9,
 
-   /**
-* @ANTENNA_COUPLING_NOTIFICATION:
-* Antenna coupling data,  iwl_mvm_antenna_coupling_notif
-*/
-   ANTENNA_COUPLING_NOTIFICATION = 0xa,
-
/**
 * @SCAN_ITERATION_COMPLETE_UMAC:
 * Firmware indicates a scan iteration completed, using
@@ -523,12 +517,6 @@ enum iwl_legacy_cmds {
 */
BT_CONFIG = 0x9b,
 
-   /**
-* @BT_COEX_UPDATE_CORUN_LUT:
-*  iwl_bt_coex_corun_lut_update_cmd
-*/
-   BT_COEX_UPDATE_CORUN_LUT = 0x5b,
-
/**
 * @BT_COEX_UPDATE_REDUCED_TXP:
 *  iwl_bt_coex_reduced_txp_update_cmd
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/config.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/config.h
index ee1bd45b7021..7f645b62804e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/config.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/config.h
@@ -181,12 +181,4 @@ struct iwl_dc2dc_config_resp {
__le32 dc2dc_freq_tune1;
 } __packed; /* DC2DC_CONFIG_RESP_API_S_VER_1 */
 
-/**
- * struct iwl_mvm_antenna_coupling_notif - antenna coupling notification
- * @isolation: antenna isolation value
- */
-struct iwl_mvm_antenna_coupling_notif {
-   __le32 isolation;
-} __packed;
-
 #endif /* __iwl_fw_api_config_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
index 0b4486114ddc..890dbfff3a06 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
@@ -148,215 +148,6 @@ static const __le64 iwl_ci_mask[][3] = {
},
 };
 
-struct corunning_block_luts {
-   u8 range;
-   __le32 lut20[BT_COEX_CORUN_LUT_SIZE];
-};
-
-/*
- * Ranges for the antenna coupling calibration / co-running block LUT:
- * LUT0: [ 0, 12[
- * LUT1: [12, 20[
- * LUT2: [20, 21[
- * LUT3: [21, 23[
- * LUT4: [23, 27[
- * LUT5: [27, 30[
- * LUT6: [30, 32[
- * LUT7: [32, 33[
- * LUT8: [33, - [
- */
-static const struct corunning_block_luts antenna_coupling_ranges[] = {
-   {
-   .range = 0,
-   .lut20 = {
-   cpu_to_le32(0x),  cpu_to_le32(0x),
-   cpu_to_le32(0x),  cpu_to_le32(0x),
-   cpu_to_le32(0x),  

[PATCH 03/24] iwlwifi: call iwl_remove_notification from iwl_wait_notification

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

The iwl_wait_notification() function removes the wait entry from the
list.  To make it clearer that it's doing the same thing as
iwl_remove_notification(), call the latter instead of having duplicate
code.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c | 25 +++---
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c 
b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
index 29bb92e3df59..1096c945a68b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015 - 2017 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
@@ -32,6 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -161,6 +162,15 @@ iwl_init_notification_wait(struct iwl_notif_wait_data 
*notif_wait,
 }
 IWL_EXPORT_SYMBOL(iwl_init_notification_wait);
 
+void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
+struct iwl_notification_wait *wait_entry)
+{
+   spin_lock_bh(_wait->notif_wait_lock);
+   list_del(_entry->list);
+   spin_unlock_bh(_wait->notif_wait_lock);
+}
+IWL_EXPORT_SYMBOL(iwl_remove_notification);
+
 int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
  struct iwl_notification_wait *wait_entry,
  unsigned long timeout)
@@ -171,9 +181,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data 
*notif_wait,
 wait_entry->triggered || wait_entry->aborted,
 timeout);
 
-   spin_lock_bh(_wait->notif_wait_lock);
-   list_del(_entry->list);
-   spin_unlock_bh(_wait->notif_wait_lock);
+   iwl_remove_notification(notif_wait, wait_entry);
 
if (wait_entry->aborted)
return -EIO;
@@ -184,12 +192,3 @@ int iwl_wait_notification(struct iwl_notif_wait_data 
*notif_wait,
return 0;
 }
 IWL_EXPORT_SYMBOL(iwl_wait_notification);
-
-void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
-struct iwl_notification_wait *wait_entry)
-{
-   spin_lock_bh(_wait->notif_wait_lock);
-   list_del(_entry->list);
-   spin_unlock_bh(_wait->notif_wait_lock);
-}
-IWL_EXPORT_SYMBOL(iwl_remove_notification);
-- 
2.14.1



Re: [PATCH] rtlwifi: make a couple arrays larger

2017-08-18 Thread Larry Finger

On 08/18/2017 03:05 AM, Dan Carpenter wrote:

This is a static checker fix.  "cal_num" is 10.  We're declaring the
tx_dt[] and rx_td[] arrays as 3 element arrays.  The static checker
complains that we do:

tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);

"cal" is the iterator and it is in the 0-9 range so it looks like
we could corrupt memory.

Signed-off-by: Dan Carpenter 
---
I'm pretty sure this patch is correct and absolutely harmless.  But the
code is pretty involved and I didn't test it.  So you may want to review
this one carefully.


I believe the patch is correct. In testing, I also confirmed that this branch is 
executed, thus the memory corruption does happen.


Acked-by: Larry Finger 

Thanks,

Larry


Cisco's Wi-Fi Direct Client Policy and iwlwifi (8260)

2017-08-18 Thread Dariusz Gadomski
Hi,

There is a “Wi-Fi Direct Client Policy” setting in some Cisco AP hardware [1].
I am unaware how that works exactly behind the scenes (except for some hints at
[2]), but I have noticed that with that setting set to “Deny” I am observing
issues when trying to connect from a machine with an Intel 8260 on a 4.10.0
kernel - all connection attempts lead to failure.

I have managed to obtain some captured packets from that attempt as well as
from a successful attempt (a machine with Broadcom bcm43224). What I have
noticed is that AP puts the P2P IE in the beacon frames and when 8260 sends a
probe request it also puts a P2P IE element in it. No response from the AP is
ever transmitted.

In case of the Broadcom-based device the probe request does not contain P2P IE
and it is able to correct normally. My understanding of this issue is that the
AP makes the decision to temporarily blacklist the client after receiving a P2P
IE from it.

I have made an additional test by commenting out the P2P interface types from
iwlwifi/mvn/mac80211.c - using such kernel allowed the 8260 device to connect
successfully.

I’m wondering if there’s a way of changing this behavior to enable the 8260 to
connect to a network ‘secured’ in this way?  I would also appreciate some
information about which behavior is correct (bcm43224 vs 8260) and is it
specified anywhere in the Wi-Fi P2P specs (or anywhere else ftm)?

Thanks, Dariusz

[1] 
https://www.cisco.com/c/en/us/td/docs/wireless/controller/7-4/configuration/guides/consolidated/b_cg74_CONSOLIDATED/b_cg74_CONSOLIDATED_chapter_01010.html
[2] 
https://supportforums.cisco.com/discussion/11851216/wi-fi-direct-client-policy



[PATCH 1/2] mac80211: add documentation to ieee80211_rx_ba_offl()

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

Add documentation to ieee80211_rx_ba_offl() function and, while at it,
rename the bit argument to tid, for consistency.

Signed-off-by: Luca Coelho 
---
 include/net/mac80211.h | 8 +++-
 net/mac80211/agg-rx.c  | 4 ++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f8149ca192b4..b232487be696 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -5452,8 +5452,14 @@ void ieee80211_mark_rx_ba_filtered_frames(struct 
ieee80211_sta *pubsta, u8 tid,
  */
 void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
 
+/**
+ * ieee80211_manage_rx_ba_offl - helper to queue an RX BA work
+ * @vif:  ieee80211_vif pointer from the add_interface callback
+ * @addr: station mac address
+ * @tid: the rx tid
+ */
 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, const u8 *addr,
-unsigned int bit);
+unsigned int tid);
 
 /**
  * ieee80211_start_rx_ba_session_offl - start a Rx BA session
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 2b36eff5d97e..90e7807d3505 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -449,7 +449,7 @@ void ieee80211_process_addba_request(struct ieee80211_local 
*local,
 }
 
 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
-const u8 *addr, unsigned int bit)
+const u8 *addr, unsigned int tid)
 {
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
@@ -460,7 +460,7 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
if (!sta)
goto unlock;
 
-   set_bit(bit, sta->ampdu_mlme.tid_rx_manage_offl);
+   set_bit(tid, sta->ampdu_mlme.tid_rx_manage_offl);
ieee80211_queue_work(>hw, >ampdu_mlme.work);
  unlock:
rcu_read_unlock();
-- 
2.14.1



[PATCH 2/2] mac80211: flush hw_roc_start work before cancelling the ROC

2017-08-18 Thread Luca Coelho
From: Avraham Stern 

When HW ROC is supported it is possible that after the HW notified
that the ROC has started, the ROC was cancelled and another ROC was
added while the hw_roc_start worker is waiting on the mutex (since
cancelling the ROC and adding another one also holds the same mutex).
As a result, the hw_roc_start worker will continue to run after the
new ROC is added but before it is actually started by the HW.
This may result in notifying userspace that the ROC has started before
it actually does, or in case of management tx ROC, in an attempt to
tx while not on the right channel.

In addition, when the driver will notify mac80211 that the second ROC
has started, mac80211 will warn that this ROC has already been
notified.

Fix this by flushing the hw_roc_start work before cancelling an ROC.

Signed-off-by: Avraham Stern 
Signed-off-by: Luca Coelho 
---
 net/mac80211/offchannel.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index f8e7a8bbc618..faf4f6055000 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -707,6 +707,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local 
*local,
if (!cookie)
return -ENOENT;
 
+   flush_work(>hw_roc_start);
+
mutex_lock(>mtx);
list_for_each_entry_safe(roc, tmp, >roc_list, list) {
if (!mgmt_tx && roc->cookie != cookie)
-- 
2.14.1



[PATCH 0/2] mac80211 patches from our internal tree 2017-08-18

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

Here are two pending mac80211 patches from our internal tree.

Please review.

Cheers,
Luca.


Avraham Stern (1):
  mac80211: flush hw_roc_start work before cancelling the ROC

Luca Coelho (1):
  mac80211: add documentation to ieee80211_rx_ba_offl()

 include/net/mac80211.h| 8 +++-
 net/mac80211/agg-rx.c | 4 ++--
 net/mac80211/offchannel.c | 2 ++
 3 files changed, 11 insertions(+), 3 deletions(-)

-- 
2.14.1



[PATCH v4 12/19] nl80211: add an option to allow MFP without requiring it

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach 

The 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, by using a new NL80211_MFP_OPTIONAL flag.
The driver / firmware will decide whether to use it or not.

Include a feature bit to advertise support for NL80211_MFP_OPTIONAL.
This allows new user space to run on old kernels and know that it
cannot use the new attribute if it isn't supported.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
v2: * add a feature flag
* fix the comment of NL80211_MFP_OPTIONAL as pointed out by Igor
v3: check the feature flag
v4: return -EOPNOTSUPP if OPTIONAL is set but not supported by the
driver (internal review)

 include/uapi/linux/nl80211.h | 13 +++--
 net/wireless/nl80211.c   |  8 +++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 76404d8a8863..59ba6ca66a0d 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1407,8 +1407,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.
@@ -3947,10 +3951,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 {
@@ -4923,6 +4929,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.
@@ -4949,6 +4957,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 d57abdfa60da..8ed9ef40bbee 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8948,8 +8948,14 @@ 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_OPTIONAL &&
+   !wiphy_ext_feature_isset(>wiphy,
+NL80211_EXT_FEATURE_MFP_OPTIONAL))
+   return -EOPNOTSUPP;
+
if (connect.mfp != NL80211_MFP_REQUIRED &&
-   connect.mfp != NL80211_MFP_NO)
+   connect.mfp != NL80211_MFP_NO &&
+   connect.mfp != NL80211_MFP_OPTIONAL)
return -EINVAL;
} else {
connect.mfp = NL80211_MFP_NO;
-- 
2.14.1



Re: brcmfmac experiment for a specific use case - tx throughput maximization for slow CPU with glomming

2017-08-18 Thread Fabio Estevam
Hi Jörg,

On Thu, Jun 1, 2017 at 3:37 AM, Jörg Krause  wrote:

> I'm experiencing low throughput with a BCM43362 wifi chip attached via
> SDIO to an i.MX28 [1,2]. After disabling some Kernel debug features I'm
> getting now a TCP throughput of 12.5 Mbps for the wifi interface, which
> is still below the throughput I get for the Cubietruck.

Does it help if you disable CONFIG_PROVE_LOCKING?

--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -175,7 +175,6 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOCKUP_DETECTOR=y
 CONFIG_TIMER_STATS=y
-CONFIG_PROVE_LOCKING=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_STRICT_DEVMEM=y
 CONFIG_DEBUG_USER=y


[PATCH] rtlwifi: make a couple arrays larger

2017-08-18 Thread Dan Carpenter
This is a static checker fix.  "cal_num" is 10.  We're declaring the
tx_dt[] and rx_td[] arrays as 3 element arrays.  The static checker
complains that we do:

tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);

"cal" is the iterator and it is in the 0-9 range so it looks like
we could corrupt memory.

Signed-off-by: Dan Carpenter 
---
I'm pretty sure this patch is correct and absolutely harmless.  But the
code is pretty involved and I didn't test it.  So you may want to review
this one carefully.

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
index aa3ccc740521..176deb2b5386 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
@@ -3773,10 +3773,11 @@ static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, 
enum radio_path path)
u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, 
temp_reg65;
int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, 
rx_average = 0;
int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
-   tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
+   tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num],
+   tx_dt[cal_num], rx_dt[cal_num];
booltx0iqkok = false, rx0iqkok = false;
boolvdf_enable = false;
-   int i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
+   int i, k, vdf_y[3], vdf_x[3],
ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
 
RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,


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

2017-08-18 Thread Matthias May
On 18/08/17 01:32, Håvard Rabbe wrote:
> Hi
> I’m using wifi card with AR9280 chipset that uses the ath9k driver.
> 
> The card has 2 available radio chains and I’m only going to connect 1 antenna.
> 
> Is it possible to disable the radio chain im not using?
> 
> 
> Best Regards,
> 
> Håvard Rabbe
> 

Help text from iw:
phy  set antenna  | all |  

You can set the rx/tx mask with
iw phy phy0 set antenna 1
to not use the second chain

or
iw phy phy0 set antenna 1 3
to not use the second chain for tx, but still use it for rx.

You can see the currently active mask with:
iw list | grep Antenna

Be aware that the value set here is a bitmask only allows the values 1/3/7 (for 
1, 2 and 3 chains).
Chain 0 is always active.
--> You can not disable chain 0 and only use chain 1.

BR
Matthias