Re: [POC/GIT] mac80211 multicast rate selection (help wanted!)
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!)
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!)
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!)
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 GreearCandela Technologies Inc http://www.candelatech.com
[POC/GIT] mac80211 multicast rate selection (help wanted!)
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?
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 Maywrote: > > 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)
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)
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()
From: Luca CoelhoWe 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
From: Luca CoelhoThe 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
From: Avraham SternIf 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()
From: Luca CoelhoAt 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
From: Luca CoelhoThere 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
From: Gregory GreenmanTx 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
From: Luca CoelhoUnlike 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
From: Luca CoelhoMove 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
From: Luca CoelhoWe 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
From: Tzipi PeresNewer 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
From: Ilan PeerThe 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
From: Luca CoelhoWe 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
From: João Paulo Rechi VitaThese 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
From: Emmanuel GrumbachWhen 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
From: Emmanuel GrumbachThe 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
From: Emmanuel GrumbachWhen 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
From: Luca CoelhoThere'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
From: Emmanuel GrumbachThis 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
From: Emmanuel GrumbachThis 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
From: Emmanuel GrumbachThe 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
From: Luca CoelhoWe 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
From: Luca CoelhoWe 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
From: Luca CoelhoHi, 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
From: Emmanuel GrumbachThe 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
From: Luca CoelhoThe 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
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)
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()
From: Luca CoelhoAdd 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
From: Avraham SternWhen 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
From: Luca CoelhoHere 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
From: Emmanuel GrumbachThe 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
Hi Jörg, On Thu, Jun 1, 2017 at 3:37 AM, Jörg Krausewrote: > 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
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?
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