[PATCH v2 05/15] iwlwifi: don't define OTP_LOW_IMAGE_SIZE per family, but per size

2018-12-03 Thread Luca Coelho
From: Luca Coelho 

Using OTP_LOW_IMAGE_SIZE_FAMILY_8000/9000/22000 only obfuscates the
actual values, since these 3 are the same.  Redefine the values per
size so it's easier to understand and compare the different
configurations.

Signed-off-by: Luca Coelho 
---

In v2: fix erroneously commented out line

drivers/net/wireless/intel/iwlwifi/cfg/1000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/2000.c   | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c  | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/6000.c   | 6 +++---
 drivers/net/wireless/intel/iwlwifi/cfg/7000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/8000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h | 8 +++-
 8 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
index 76b5ddb20248..1ff388b593ad 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
@@ -48,7 +48,7 @@
 static const struct iwl_base_params iwl1000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.pll_cfg = true,
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
index e7e45846dd07..a6ec7ad39dcb 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
@@ -57,7 +57,7 @@
 #define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
 
 static const struct iwl_base_params iwl2000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
@@ -71,7 +71,7 @@ static const struct iwl_base_params iwl2000_base_params = {
 
 
 static const struct iwl_base_params iwl2030_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 8b2339165bca..2d395a4a5375 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -109,7 +109,7 @@
 #define NVM_HW_SECTION_NUM_FAMILY_2200010
 
 static const struct iwl_base_params iwl_22000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 512,
.max_tfd_queue_size = 256,
.shadow_ram_support = true,
@@ -121,7 +121,7 @@ static const struct iwl_base_params iwl_22000_base_params = 
{
 };
 
 static const struct iwl_base_params iwl_22560_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 512,
.max_tfd_queue_size = 65536,
.shadow_ram_support = true,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
index 30e62a7c9d52..fbb18d066cd0 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
@@ -66,7 +66,7 @@
 #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
 
 static const struct iwl_base_params iwl6000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -79,7 +79,7 @@ static const struct iwl_base_params iwl6000_base_params = {
 };
 
 static const struct iwl_base_params iwl6050_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
@@ -92,7 +92,7 @@ static const struct iwl_base_params iwl6050_base_params = {
 };
 
 static const struct iwl_base_params iwl6000_g2_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index c973bfaa3414..38d5db50b1ed 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/700

[PATCH 11/15] iwlwifi: mvm: change PHY data RX for HE radiotap

2018-11-23 Thread Luca Coelho
From: Shaul Triebitz 

The firmware changed the PHY data API, so follow suit.
Some data is now available even for HT/VHT frames, so
the info type in the metadata was changed. This change
isn't backwards compatible, but
 1) the firmware with the old API was never released;
 2) the only overlap in the info type field is from the
old type of TB to the new of HT, so this basically
just means that with older FW and newer driver the
data will be considered missing.

While at it, remove the extra code to set the LTF syms
corresponding to the streams and use the data from the
device instead - we don't really need this in any case
other than when we have it from the device.

As the new API gives use the spatial reuse 1-4 fields
for trigger-based PPDUs, also expose that to radiotap.

Signed-off-by: Johannes Berg 
Signed-off-by: Shaul Triebitz 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/fw/api/rx.h| 190 +
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 367 +-
 2 files changed, 296 insertions(+), 261 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
index 0537496b6eb1..8961227ff44d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
@@ -345,66 +345,98 @@ enum iwl_rx_mpdu_mac_info {
IWL_RX_MPDU_PHY_PHY_INDEX_MASK  = 0xf0,
 };
 
-/*
- * enum iwl_rx_he_phy - HE PHY data
- */
-enum iwl_rx_he_phy {
-   IWL_RX_HE_PHY_BEAM_CHNG = BIT(0),
-   IWL_RX_HE_PHY_UPLINK= BIT(1),
-   IWL_RX_HE_PHY_BSS_COLOR_MASK= 0xfc,
-   IWL_RX_HE_PHY_SPATIAL_REUSE_MASK= 0xf00,
-   IWL_RX_HE_PHY_SU_EXT_BW10   = BIT(12),
-   IWL_RX_HE_PHY_TXOP_DUR_MASK = 0xfe000,
-   IWL_RX_HE_PHY_LDPC_EXT_SYM  = BIT(20),
-   IWL_RX_HE_PHY_PRE_FEC_PAD_MASK  = 0x60,
-   IWL_RX_HE_PHY_PE_DISAMBIG   = BIT(23),
-   IWL_RX_HE_PHY_DOPPLER   = BIT(24),
+/* TSF overload low dword */
+enum iwl_rx_phy_data0 {
+   /* info type: HE any */
+   IWL_RX_PHY_DATA0_HE_BEAM_CHNG   = 0x0001,
+   IWL_RX_PHY_DATA0_HE_UPLINK  = 0x0002,
+   IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK  = 0x00fc,
+   IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK  = 0x0f00,
+   /* 1 bit reserved */
+   IWL_RX_PHY_DATA0_HE_TXOP_DUR_MASK   = 0x000fe000,
+   IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM= 0x0010,
+   IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK= 0x0060,
+   IWL_RX_PHY_DATA0_HE_PE_DISAMBIG = 0x0080,
+   IWL_RX_PHY_DATA0_HE_DOPPLER = 0x0100,
/* 6 bits reserved */
-   IWL_RX_HE_PHY_DELIM_EOF = BIT(31),
+   IWL_RX_PHY_DATA0_HE_DELIM_EOF   = 0x8000,
+};
+
+enum iwl_rx_phy_info_type {
+   IWL_RX_PHY_INFO_TYPE_NONE   = 0,
+   IWL_RX_PHY_INFO_TYPE_CCK= 1,
+   IWL_RX_PHY_INFO_TYPE_OFDM_LGCY  = 2,
+   IWL_RX_PHY_INFO_TYPE_HT = 3,
+   IWL_RX_PHY_INFO_TYPE_VHT_SU = 4,
+   IWL_RX_PHY_INFO_TYPE_VHT_MU = 5,
+   IWL_RX_PHY_INFO_TYPE_HE_SU  = 6,
+   IWL_RX_PHY_INFO_TYPE_HE_MU  = 7,
+   IWL_RX_PHY_INFO_TYPE_HE_TB  = 8,
+   IWL_RX_PHY_INFO_TYPE_HE_MU_EXT  = 9,
+   IWL_RX_PHY_INFO_TYPE_HE_TB_EXT  = 10,
+};
+
+/* TSF overload high dword */
+enum iwl_rx_phy_data1 {
+   /*
+* check this first - if TSF overload is set,
+* see  iwl_rx_phy_info_type
+*/
+   IWL_RX_PHY_DATA1_INFO_TYPE_MASK = 0xf000,
+
+   /* info type: HT/VHT/HE any */
+   IWL_RX_PHY_DATA1_LSIG_LEN_MASK  = 0x0fff,
 
-   /* second dword - common data */
-   IWL_RX_HE_PHY_HE_LTF_NUM_MASK   = 0xe0ULL,
-   IWL_RX_HE_PHY_RU_ALLOC_SEC80= BIT_ULL(32 + 8),
+   /* info type: HE MU/MU-EXT */
+   IWL_RX_PHY_DATA1_HE_MU_SIGB_COMPRESSION = 0x0001,
+   IWL_RX_PHY_DATA1_HE_MU_SIBG_SYM_OR_USER_NUM_MASK= 0x001e,
+
+   /* info type: HE any */
+   IWL_RX_PHY_DATA1_HE_LTF_NUM_MASK= 0x00e0,
+   IWL_RX_PHY_DATA1_HE_RU_ALLOC_SEC80  = 0x0100,
/* trigger encoded */
-   IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe00ULL,
-   IWL_RX_HE_PHY_INFO_TYPE_MASK= 0xf000ULL

[PATCH 14/15] iwlwifi: pcie: set cmd_len in the correct place

2018-11-23 Thread Luca Coelho
From: Sara Sharon 

command len is set too early in the code, since when building
AMSDU, the size changes. This causes the byte count table to
have the wrong size.

Fixes: a0ec0169b7a9 ("iwlwifi: support new tx api")
Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 24 +--
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 0c5f11d2c5da..16e8c3eb09b8 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -583,18 +583,6 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct 
sk_buff *skb,
 
spin_lock(>lock);
 
-   if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
-   struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
-   (void *)dev_cmd->payload;
-
-   cmd_len = le16_to_cpu(tx_cmd_gen3->len);
-   } else {
-   struct iwl_tx_cmd_gen2 *tx_cmd_gen2 =
-   (void *)dev_cmd->payload;
-
-   cmd_len = le16_to_cpu(tx_cmd_gen2->len);
-   }
-
if (iwl_queue_space(trans, txq) < txq->high_mark) {
iwl_stop_queue(trans, txq);
 
@@ -632,6 +620,18 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct 
sk_buff *skb,
return -1;
}
 
+   if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+   struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
+   (void *)dev_cmd->payload;
+
+   cmd_len = le16_to_cpu(tx_cmd_gen3->len);
+   } else {
+   struct iwl_tx_cmd_gen2 *tx_cmd_gen2 =
+   (void *)dev_cmd->payload;
+
+   cmd_len = le16_to_cpu(tx_cmd_gen2->len);
+   }
+
/* Set up entry for this TFD in Tx byte-count array */
iwl_pcie_gen2_update_byte_tbl(trans_pcie, txq, cmd_len,
  iwl_pcie_gen2_get_num_tbs(trans, tfd));
-- 
2.19.1



[PATCH 10/15] iwlwifi: pcie: fix erroneous print

2018-11-23 Thread Luca Coelho
From: Sara Sharon 

When removing the driver, the following flow can happen:
1. host command is in progress, for example at index 68.
2. RX interrupt is received with the response.
3. Before it is processed, the remove flow kicks in, and
   calls iwl_pcie_txq_unmap. The function cleans all DMA,
   and promotes the read pointer to 69.
4. RX thread proceeds with the processing, and is calling
   iwl_pcie_cmdq_reclaim, which will print this error:
   iwl_pcie_cmdq_reclaim: Read index for DMA queue txq id (0),
   index 4 is out of range [0-256] 69 69.

Detect this situation, and avoid the print. Change it to
warning while at it, to make such issues more noticeable
in the future.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 87b7225fe289..3d53842ee60e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1245,11 +1245,11 @@ void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int 
txq_id, int idx)
 
if (idx >= trans->cfg->base_params->max_tfd_queue_size ||
(!iwl_queue_used(txq, idx))) {
-   IWL_ERR(trans,
-   "%s: Read index for DMA queue txq id (%d), index %d is 
out of range [0-%d] %d %d.\n",
-   __func__, txq_id, idx,
-   trans->cfg->base_params->max_tfd_queue_size,
-   txq->write_ptr, txq->read_ptr);
+   WARN_ONCE(test_bit(txq_id, trans_pcie->queue_used),
+ "%s: Read index for DMA queue txq id (%d), index %d 
is out of range [0-%d] %d %d.\n",
+ __func__, txq_id, idx,
+ trans->cfg->base_params->max_tfd_queue_size,
+ txq->write_ptr, txq->read_ptr);
return;
}
 
-- 
2.19.1



[PATCH 12/15] iwlwifi: mvm: add L-SIG length to radiotap

2018-11-23 Thread Luca Coelho
From: Shaul Triebitz 

We may have the L-SIG length depending on the phy_data info type;
add it to radiotap when we do.

Move getting the phy_data out one layer up and the info type into
it so we can use this data more generically. We need to call the
iwl_mvm_rx_he() function for other reasons as well, so can't just
combine all of that into something like iwl_mvm_parse_phy_data().

Signed-off-by: Johannes Berg 
Signed-off-by: Shaul Triebitz 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 96 ---
 1 file changed, 60 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index d7f6b7aec981..87c245c85d9c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -864,6 +864,7 @@ static void iwl_mvm_flip_address(u8 *addr)
 }
 
 struct iwl_mvm_rx_phy_data {
+   enum iwl_rx_phy_info_type info_type;
__le32 d0, d1, d2, d3;
__le16 d4;
 };
@@ -999,19 +1000,13 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
   struct ieee80211_rx_status *rx_status,
   u32 rate_n_flags, int queue)
 {
-   enum iwl_rx_phy_info_type info_type;
-
-   info_type = le32_get_bits(phy_data->d1, 
IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
-
-   switch (info_type) {
+   switch (phy_data->info_type) {
case IWL_RX_PHY_INFO_TYPE_NONE:
case IWL_RX_PHY_INFO_TYPE_CCK:
case IWL_RX_PHY_INFO_TYPE_OFDM_LGCY:
-   return;
case IWL_RX_PHY_INFO_TYPE_HT:
case IWL_RX_PHY_INFO_TYPE_VHT_SU:
case IWL_RX_PHY_INFO_TYPE_VHT_MU:
-   /* TODO: we have LSIG-LEN, where do we put it? */
return;
case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT:
he->data1 |= 
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
@@ -1075,7 +1070,7 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
break;
}
 
-   switch (info_type) {
+   switch (phy_data->info_type) {
case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
he_mu->flags1 |=
le16_encode_bits(le16_get_bits(phy_data->d4,
@@ -1119,7 +1114,7 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
 }
 
 static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
- struct iwl_rx_mpdu_desc *desc,
+ struct iwl_mvm_rx_phy_data *phy_data,
  u32 rate_n_flags, u16 phy_info, int queue)
 {
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
@@ -1144,33 +1139,13 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct 
sk_buff *skb,
  
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
};
unsigned int radiotap_len = 0;
-   struct iwl_mvm_rx_phy_data phy_data = {
-   .d4 = desc->phy_data4,
-   };
-   enum iwl_rx_phy_info_type info_type = IWL_RX_PHY_INFO_TYPE_NONE;
-
-   if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
-   phy_data.d0 = desc->v3.phy_data0;
-   phy_data.d1 = desc->v3.phy_data1;
-   phy_data.d2 = desc->v3.phy_data2;
-   phy_data.d3 = desc->v3.phy_data3;
-   } else {
-   phy_data.d0 = desc->v1.phy_data0;
-   phy_data.d1 = desc->v1.phy_data1;
-   phy_data.d2 = desc->v1.phy_data2;
-   phy_data.d3 = desc->v1.phy_data3;
-   }
-
-   if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD)
-   info_type = le32_get_bits(phy_data.d1,
- IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
 
he = skb_put_data(skb, , sizeof(known));
radiotap_len += sizeof(known);
rx_status->flag |= RX_FLAG_RADIOTAP_HE;
 
-   if (info_type == IWL_RX_PHY_INFO_TYPE_HE_MU ||
-   info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) {
+   if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU ||
+   phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) {
he_mu = skb_put_data(skb, _known, sizeof(mu_known));
radiotap_len += sizeof(mu_known);
rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
@@ -1179,18 +1154,18 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct 
sk_buff *skb,
/* temporarily hide the radiotap data */
__skb_pull(skb, radiotap_len);
 
-   if (info_type == IWL_RX_PHY_INFO_TYPE_HE_SU) {
+   if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_SU) {
/* report the AMPDU-EOF bit on single frames */
if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
rx_status->flag |= RX

[PATCH 15/15] iwlwifi: mvm: don't check if a pointer is set if it can't be unset

2018-11-23 Thread Luca Coelho
From: Emmanuel Grumbach 

We used to have many versions of statistics notification
coming from the firmware. In one of the cleanup patches,
we forgot to clean the code that checks if data->general
is set. Since it is always set, remove the check.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 37 ++---
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index ef624833cf1b..6653a238f32e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -593,31 +593,28 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
int hyst = vif->bss_conf.cqm_rssi_hyst;
u16 id = le32_to_cpu(data->mac_id);
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+   u16 vif_id = mvmvif->id;
 
/* This doesn't need the MAC ID check since it's not taking the
 * data copied into the "data" struct, but rather the data from
 * the notification directly.
 */
-   if (data->general) {
-   u16 vif_id = mvmvif->id;
-
-   if (iwl_mvm_is_cdb_supported(mvm)) {
-   struct mvm_statistics_general_cdb *general =
-   data->general;
-
-   mvmvif->beacon_stats.num_beacons =
-   le32_to_cpu(general->beacon_counter[vif_id]);
-   mvmvif->beacon_stats.avg_signal =
-   -general->beacon_average_energy[vif_id];
-   } else {
-   struct mvm_statistics_general_v8 *general =
-   data->general;
-
-   mvmvif->beacon_stats.num_beacons =
-   le32_to_cpu(general->beacon_counter[vif_id]);
-   mvmvif->beacon_stats.avg_signal =
-   -general->beacon_average_energy[vif_id];
-   }
+   if (iwl_mvm_is_cdb_supported(mvm)) {
+   struct mvm_statistics_general_cdb *general =
+   data->general;
+
+   mvmvif->beacon_stats.num_beacons =
+   le32_to_cpu(general->beacon_counter[vif_id]);
+   mvmvif->beacon_stats.avg_signal =
+   -general->beacon_average_energy[vif_id];
+   } else {
+   struct mvm_statistics_general_v8 *general =
+   data->general;
+
+   mvmvif->beacon_stats.num_beacons =
+   le32_to_cpu(general->beacon_counter[vif_id]);
+   mvmvif->beacon_stats.avg_signal =
+   -general->beacon_average_energy[vif_id];
}
 
if (mvmvif->id != id)
-- 
2.19.1



[PATCH 13/15] iwlwifi: mvm: radiotap: remove UL_DL bit in HE TRIG_BASED

2018-11-23 Thread Luca Coelho
From: Shaul Triebitz 

UL_DL is irrelevant to HE TRIG_BASED PPDU.

Signed-off-by: Shaul Triebitz 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 87c245c85d9c..8b014456e6d8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -1032,7 +1032,6 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
case IWL_RX_PHY_INFO_TYPE_HE_TB:
/* HE common */
he->data1 |= 
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
-
IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
 
IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
 
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
 
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
@@ -1043,9 +1042,13 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,

IWL_RX_PHY_DATA0_HE_BSS_COLOR_MASK),
  
IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
-   he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
+   if (phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB &&
+   phy_data->info_type != IWL_RX_PHY_INFO_TYPE_HE_TB_EXT) {
+   he->data1 |= 
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN);
+   he->data3 |= 
le16_encode_bits(le32_get_bits(phy_data->d0,

IWL_RX_PHY_DATA0_HE_UPLINK),
- 
IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
+ 
IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
+   }
he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,

IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM),
  
IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
-- 
2.19.1



[PATCH 00/15] iwlwifi: updates intended for v4.21 2018-11-23

2018-11-23 Thread Luca Coelho
From: Luca Coelho 

Hi,

Here's the third set of patches intended for v4.21.  It's the usual
development, with some small new features, cleanups and bugfixes.

The changes are:

* Some cleanups in the HW configuration structures;
* More work on the debugging infrastructure;
* Fixes related to 802.11ax;
* Other cleanups and small fixes;

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: force TCM re-evaluation on TCM resume

Emmanuel Grumbach (1):
  iwlwifi: mvm: don't check if a pointer is set if it can't be unset

Luca Coelho (5):
  iwlwifi: move common 9000 cfg parameters to common macro
  iwlwifi: don't define OTP_LOW_IMAGE_SIZE per family, but per size
  iwlwifi: remove useless NVM_HW_SECTION_NUM_FAMILY_* macros
  iwlwifi: move iwl_nvm_check_version() into dvm
  iwlwifi: remove all unnecessary occurrences of nvm_calib_ver

Sara Sharon (5):
  iwlwifi: dbg: dump data according to the new ini TLVs
  iwlwifi: add support for triggering ini triggers
  iwlwifi: mvm: activate apply points
  iwlwifi: pcie: fix erroneous print
  iwlwifi: pcie: set cmd_len in the correct place

Shaul Triebitz (3):
  iwlwifi: mvm: change PHY data RX for HE radiotap
  iwlwifi: mvm: add L-SIG length to radiotap
  iwlwifi: mvm: radiotap: remove UL_DL bit in HE TRIG_BASED

 drivers/net/wireless/intel/iwlwifi/cfg/1000.c |   2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/2000.c |   4 +-
 .../net/wireless/intel/iwlwifi/cfg/22000.c|  10 +-
 drivers/net/wireless/intel/iwlwifi/cfg/6000.c |   6 +-
 drivers/net/wireless/intel/iwlwifi/cfg/7000.c |  27 +-
 drivers/net/wireless/intel/iwlwifi/cfg/8000.c |  11 +-
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c |  85 +---
 drivers/net/wireless/intel/iwlwifi/dvm/main.c |  17 +
 .../net/wireless/intel/iwlwifi/fw/api/rx.h| 190 +
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 322 +-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |  41 +-
 .../wireless/intel/iwlwifi/fw/error-dump.h|  17 +
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |   2 +-
 .../net/wireless/intel/iwlwifi/iwl-config.h   |   8 +-
 .../wireless/intel/iwlwifi/iwl-eeprom-parse.c |  19 -
 .../wireless/intel/iwlwifi/iwl-eeprom-parse.h |   5 +-
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h |   6 +
 .../net/wireless/intel/iwlwifi/mvm/debugfs.c  |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  20 +-
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |   2 +
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |   2 +
 drivers/net/wireless/intel/iwlwifi/mvm/rx.c   |  37 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 394 +-
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c |   2 +
 .../net/wireless/intel/iwlwifi/mvm/utils.c|  14 +
 .../intel/iwlwifi/pcie/ctxt-info-gen3.c   |  13 +-
 .../wireless/intel/iwlwifi/pcie/ctxt-info.c   |   2 +-
 .../wireless/intel/iwlwifi/pcie/internal.h|   5 +
 .../net/wireless/intel/iwlwifi/pcie/trans.c   |  71 +++-
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c |  24 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  |  10 +-
 31 files changed, 872 insertions(+), 498 deletions(-)

-- 
2.19.1



[PATCH 06/15] iwlwifi: remove useless NVM_HW_SECTION_NUM_FAMILY_* macros

2018-11-23 Thread Luca Coelho
From: Luca Coelho 

These macros are useless because each one of them is used only once
and the element they are assigned to is already pretty clear about
what they mean, "nvm_hw_section_num".

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 4 +---
 drivers/net/wireless/intel/iwlwifi/cfg/7000.c  | 4 +---
 drivers/net/wireless/intel/iwlwifi/cfg/8000.c  | 3 +--
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c  | 4 +---
 4 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 2d395a4a5375..157ff1f76ba6 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -106,8 +106,6 @@
 #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
 
-#define NVM_HW_SECTION_NUM_FAMILY_2200010
-
 static const struct iwl_base_params iwl_22000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 512,
@@ -142,7 +140,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
.ucode_api_max = IWL_22000_UCODE_API_MAX,   \
.ucode_api_min = IWL_22000_UCODE_API_MIN,   \
.led_mode = IWL_LED_RF_STATE,   \
-   .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_22000,  \
+   .nvm_hw_section_num = 10,   \
.non_shared_ant = ANT_B,\
.dccm_offset = IWL_22000_DCCM_OFFSET,   \
.dccm_len = IWL_22000_DCCM_LEN, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index 38d5db50b1ed..5b4efa8ddffb 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
@@ -113,8 +113,6 @@
 #define IWL7265D_FW_PRE "iwlwifi-7265D-"
 #define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode"
 
-#define NVM_HW_SECTION_NUM_FAMILY_7000 0
-
 static const struct iwl_base_params iwl7000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_16K,
.num_of_queues = 31,
@@ -159,7 +157,7 @@ static const struct iwl_ht_params iwl7000_ht_params = {
.device_family = IWL_DEVICE_FAMILY_7000,\
.base_params = _base_params,\
.led_mode = IWL_LED_RF_STATE,   \
-   .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000,   \
+   .nvm_hw_section_num = 0,\
.non_shared_ant = ANT_A,\
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,\
.dccm_offset = IWL7000_DCCM_OFFSET, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
index dd2785e65f80..5b1da5206336 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
@@ -93,7 +93,6 @@
 #define IWL8265_MODULE_FIRMWARE(api) \
IWL8265_FW_PRE __stringify(api) ".ucode"
 
-#define NVM_HW_SECTION_NUM_FAMILY_8000 10
 #define DEFAULT_NVM_FILE_FAMILY_8000C  "nvmData-8000C"
 
 static const struct iwl_base_params iwl8000_base_params = {
@@ -139,7 +138,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
.device_family = IWL_DEVICE_FAMILY_8000,\
.base_params = _base_params,\
.led_mode = IWL_LED_RF_STATE,   \
-   .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000,   \
+   .nvm_hw_section_num = 10,   \
.features = NETIF_F_RXCSUM, \
.non_shared_ant = ANT_A,\
.dccm_offset = IWL8260_DCCM_OFFSET, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index 1bc12f8b716d..b589b0e9d515 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -90,8 +90,6 @@
 #define IWL9260B_MODULE_FIRMWARE(api) \
IWL9260B_FW_PRE __stringify(api) ".ucode"
 
-#define NVM_HW_SECTION_NUM_FAMILY_9000 10
-
 static const struct iwl_base_params iwl9000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 31,
@@ -137,7 +135,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.device_family = IWL_DEVICE_FAMILY_9000,\
.base_params = _base_par

[PATCH 09/15] iwlwifi: mvm: force TCM re-evaluation on TCM resume

2018-11-23 Thread Luca Coelho
From: Avraham Stern 

When traffic load is not low or low latency is active, TCM schedules
re-evaluation work so in case traffic stops TCM will detect that
traffic load has become low or that low latency is no longer active.
However, if TCM is paused when the re-evaluation work runs, it does
not re-evaluate and the re-evaluation work is no longer scheduled.
As a result, TCM will not indicate that low latency is no longer
active or that traffic load is low when traffic stops.

Fix this by forcing TCM re-evaluation when TCM is resumed in case
low latency is active or traffic load is not low.

Signed-off-by: Avraham Stern 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 3761fbfff292..5ad352ef8e9b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -1378,6 +1378,7 @@ void iwl_mvm_pause_tcm(struct iwl_mvm *mvm, bool 
with_cancel)
 void iwl_mvm_resume_tcm(struct iwl_mvm *mvm)
 {
int mac;
+   bool low_latency = false;
 
spin_lock_bh(>tcm.lock);
mvm->tcm.ts = jiffies;
@@ -1389,10 +1390,23 @@ void iwl_mvm_resume_tcm(struct iwl_mvm *mvm)
memset(>tx.pkts, 0, sizeof(mdata->tx.pkts));
memset(>rx.airtime, 0, sizeof(mdata->rx.airtime));
memset(>tx.airtime, 0, sizeof(mdata->tx.airtime));
+
+   if (mvm->tcm.result.low_latency[mac])
+   low_latency = true;
}
/* The TCM data needs to be reset before "paused" flag changes */
smp_mb();
mvm->tcm.paused = false;
+
+   /*
+* if the current load is not low or low latency is active, force
+* re-evaluation to cover the case of no traffic.
+*/
+   if (mvm->tcm.result.global_load > IWL_MVM_TRAFFIC_LOW)
+   schedule_delayed_work(>tcm.work, MVM_TCM_PERIOD);
+   else if (low_latency)
+   schedule_delayed_work(>tcm.work, MVM_LL_PERIOD);
+
spin_unlock_bh(>tcm.lock);
 }
 
-- 
2.19.1



[PATCH 08/15] iwlwifi: remove all unnecessary occurrences of nvm_calib_ver

2018-11-23 Thread Luca Coelho
From: Luca Coelho 

Now that nvm_calib_ver is not checked in opmodes other than dvm, we
can remove it from all irrelevant configurations.

Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/cfg/22000.c|  2 --
 drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 21 ---
 drivers/net/wireless/intel/iwlwifi/cfg/8000.c |  6 --
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c |  2 --
 4 files changed, 31 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 157ff1f76ba6..a03d0b5617af 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -63,7 +63,6 @@
 
 /* NVM versions */
 #define IWL_22000_NVM_VERSION  0x0a1d
-#define IWL_22000_TX_POWER_VERSION 0x /* meaningless */
 
 /* Memory offsets and lengths */
 #define IWL_22000_DCCM_OFFSET  0x80 /* LMAC1 */
@@ -155,7 +154,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
.mac_addr_from_csr = true,  \
.ht_params = _22000_ht_params,  \
.nvm_ver = IWL_22000_NVM_VERSION,   \
-   .nvm_calib_ver = IWL_22000_TX_POWER_VERSION,\
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,\
.use_tfh = true,\
.rf_id = true,  \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index 5b4efa8ddffb..289e3c398a12 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
@@ -80,17 +80,11 @@
 
 /* NVM versions */
 #define IWL7260_NVM_VERSION0x0a1d
-#define IWL7260_TX_POWER_VERSION   0x /* meaningless */
 #define IWL3160_NVM_VERSION0x709
-#define IWL3160_TX_POWER_VERSION   0x /* meaningless */
 #define IWL3165_NVM_VERSION0x709
-#define IWL3165_TX_POWER_VERSION   0x /* meaningless */
 #define IWL3168_NVM_VERSION0xd01
-#define IWL3168_TX_POWER_VERSION   0x /* meaningless */
 #define IWL7265_NVM_VERSION0x0a1d
-#define IWL7265_TX_POWER_VERSION   0x /* meaningless */
 #define IWL7265D_NVM_VERSION   0x0c11
-#define IWL7265_TX_POWER_VERSION   0x /* meaningless */
 
 /* DCCM offsets and lengths */
 #define IWL7000_DCCM_OFFSET0x80
@@ -189,7 +183,6 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
IWL_DEVICE_7000,
.ht_params = _ht_params,
.nvm_ver = IWL7260_NVM_VERSION,
-   .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
.lp_xtal_workaround = true,
.dccm_len = IWL7260_DCCM_LEN,
@@ -201,7 +194,6 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
IWL_DEVICE_7000,
.ht_params = _ht_params,
.nvm_ver = IWL7260_NVM_VERSION,
-   .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.high_temp = true,
.host_interrupt_operation_mode = true,
.lp_xtal_workaround = true,
@@ -215,7 +207,6 @@ const struct iwl_cfg iwl7260_2n_cfg = {
IWL_DEVICE_7000,
.ht_params = _ht_params,
.nvm_ver = IWL7260_NVM_VERSION,
-   .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
.lp_xtal_workaround = true,
.dccm_len = IWL7260_DCCM_LEN,
@@ -227,7 +218,6 @@ const struct iwl_cfg iwl7260_n_cfg = {
IWL_DEVICE_7000,
.ht_params = _ht_params,
.nvm_ver = IWL7260_NVM_VERSION,
-   .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
.lp_xtal_workaround = true,
.dccm_len = IWL7260_DCCM_LEN,
@@ -239,7 +229,6 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
IWL_DEVICE_7000,
.ht_params = _ht_params,
.nvm_ver = IWL3160_NVM_VERSION,
-   .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
.dccm_len = IWL3160_DCCM_LEN,
 };
@@ -250,7 +239,6 @@ const struct iwl_cfg iwl3160_2n_cfg = {
IWL_DEVICE_7000,
.ht_params = _ht_params,
.nvm_ver = IWL3160_NVM_VERSION,
-   .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
.dccm_len = IWL3160_DCCM_LEN,
 };
@@ -261,7 +249,6 @@ const struct iwl_cfg iwl3160_n_cfg = {
IWL_DEVICE_7000,
.ht_params = _ht_params,
.nvm_ver = IWL3160_NVM_VERSION,
-   .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
.dccm_len = IWL3160_DCCM_LEN,
 };
@@ -289,7 +276,6 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
IWL_DEVICE_7005D,
.ht_params = _ht_params,
.nvm_ver = IWL3165_NVM_VERSION,
-   .nvm_calib_ver

[PATCH 02/15] iwlwifi: dbg: dump data according to the new ini TLVs

2018-11-23 Thread Luca Coelho
From: Sara Sharon 

When ini TLVs are loaded, dump data according to the
stored configuration.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 263 +-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |   2 +-
 .../wireless/intel/iwlwifi/fw/error-dump.h|  17 ++
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h |   6 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  12 +-
 .../intel/iwlwifi/pcie/ctxt-info-gen3.c   |  13 +-
 .../wireless/intel/iwlwifi/pcie/ctxt-info.c   |   2 +-
 .../wireless/intel/iwlwifi/pcie/internal.h|   5 +
 .../net/wireless/intel/iwlwifi/pcie/trans.c   |  71 +++--
 9 files changed, 355 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 76050cc3532a..58771e253396 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -605,6 +605,28 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
 }
 
+static void iwl_fw_dump_named_mem(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_error_dump_data **dump_data,
+ u32 len, u32 ofs, u8 *name, u8 name_len)
+{
+   struct iwl_fw_error_dump_named_mem *dump_mem;
+
+   if (!len)
+   return;
+
+   (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
+   (*dump_data)->len = cpu_to_le32(len + sizeof(*dump_mem));
+   dump_mem = (void *)(*dump_data)->data;
+   dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_NAMED_MEM);
+   dump_mem->offset = cpu_to_le32(ofs);
+   dump_mem->name_len = name_len;
+   memcpy(dump_mem->name, name, name_len);
+   iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len);
+   *dump_data = iwl_fw_error_next_data(*dump_data);
+
+   IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
+}
+
 #define ADD_LEN(len, item_len, const_len) \
do {size_t item = item_len; len += (!!item) * const_len + item; } \
while (0)
@@ -928,6 +950,238 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
return dump_file;
 }
 
+static void iwl_dump_prph_ini(struct iwl_trans *trans,
+ struct iwl_fw_error_dump_data **data,
+ struct iwl_fw_ini_region_cfg *reg)
+{
+   struct iwl_fw_error_dump_prph *prph;
+   unsigned long flags;
+   u32 i, size = le32_to_cpu(reg->num_regions);
+
+   IWL_DEBUG_INFO(trans, "WRT PRPH dump\n");
+
+   if (!iwl_trans_grab_nic_access(trans, ))
+   return;
+
+   for (i = 0; i < size; i++) {
+   (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
+   (*data)->len = cpu_to_le32(le32_to_cpu(reg->size) +
+  sizeof(*prph));
+   prph = (void *)(*data)->data;
+   prph->prph_start = reg->start_addr[i];
+   prph->data[0] = cpu_to_le32(iwl_read_prph_no_grab(trans,
+ 
le32_to_cpu(prph->prph_start)));
+   *data = iwl_fw_error_next_data(*data);
+   }
+   iwl_trans_release_nic_access(trans, );
+}
+
+static void iwl_dump_csr_ini(struct iwl_trans *trans,
+struct iwl_fw_error_dump_data **data,
+struct iwl_fw_ini_region_cfg *reg)
+{
+   int i, num = le32_to_cpu(reg->num_regions);
+   u32 size = le32_to_cpu(reg->size);
+
+   IWL_DEBUG_INFO(trans, "WRT CSR dump\n");
+
+   for (i = 0; i < num; i++) {
+   u32 add = le32_to_cpu(reg->start_addr[i]);
+   __le32 *val;
+   int j;
+
+   (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_CSR);
+   (*data)->len = cpu_to_le32(size);
+   val = (void *)(*data)->data;
+
+   for (j = 0; j < size; j += 4)
+   *val++ = cpu_to_le32(iwl_trans_read32(trans, j + add));
+
+   *data = iwl_fw_error_next_data(*data);
+   }
+}
+
+static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_ini_trigger *trigger)
+{
+   int i, num, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
+
+   if (!trigger || !trigger->num_regions)
+   return 0;
+
+   num = le32_to_cpu(trigger->num_regions);
+   for (i = 0; i < num; i++) {
+   u32 reg_id = le32_to_cpu(trigger->data[i]);
+   struct iwl_fw_ini_region_cfg *reg;
+   enum iwl_fw_ini_region_type type;
+   u32 num_entries;
+
+   if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt-&g

[PATCH 03/15] iwlwifi: add support for triggering ini triggers

2018-11-23 Thread Luca Coelho
From: Sara Sharon 

Add support for ini triggers.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 59 +--
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   | 39 +++-
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |  2 +-
 .../net/wireless/intel/iwlwifi/mvm/debugfs.c  |  2 +-
 4 files changed, 91 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 58771e253396..b17298ba7dc0 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1329,10 +1329,10 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);
 
-int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
-  enum iwl_fw_dbg_trigger trig,
-  const char *str, size_t len,
-  struct iwl_fw_dbg_trigger_tlv *trigger)
+int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
+   enum iwl_fw_dbg_trigger trig,
+   const char *str, size_t len,
+   struct iwl_fw_dbg_trigger_tlv *trigger)
 {
struct iwl_fw_dump_desc *desc;
unsigned int delay = 0;
@@ -1367,6 +1367,47 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
 
return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
 }
+IWL_EXPORT_SYMBOL(_iwl_fw_dbg_collect);
+
+int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
+  u32 id, const char *str, size_t len)
+{
+   struct iwl_fw_dump_desc *desc;
+   u32 occur, delay;
+
+   if (!fwrt->trans->ini_valid)
+   return _iwl_fw_dbg_collect(fwrt, id, str, len, NULL);
+
+   if (id == FW_DBG_TRIGGER_USER)
+   id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
+
+   if (WARN_ON(!fwrt->dump.active_trigs[id].active))
+   return -EINVAL;
+
+   delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->ignore_consec);
+   occur = le32_to_cpu(fwrt->dump.active_trigs[id].conf->occurrences);
+   if (!occur)
+   return 0;
+
+   if (le32_to_cpu(fwrt->dump.active_trigs[id].conf->force_restart)) {
+   IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id);
+   iwl_force_nmi(fwrt->trans);
+   return 0;
+   }
+
+   desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
+   if (!desc)
+   return -ENOMEM;
+
+   occur--;
+   fwrt->dump.active_trigs[id].conf->occurrences = cpu_to_le32(occur);
+
+   desc->len = len;
+   desc->trig_desc.type = cpu_to_le32(id);
+   memcpy(desc->trig_desc.data, str, len);
+
+   return iwl_fw_dbg_collect_desc(fwrt, desc, true, delay);
+}
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
 
 int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
@@ -1395,8 +1436,8 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
len = strlen(buf) + 1;
}
 
-   ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
-trigger);
+   ret = _iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
+ trigger);
 
if (ret)
return ret;
@@ -1668,6 +1709,12 @@ static void iwl_fw_dbg_update_triggers(struct 
iwl_fw_runtime *fwrt,
active->conf = trig;
}
 
+   /* Since zero means infinity - just set to -1 */
+   if (!le32_to_cpu(trig->occurrences))
+   trig->occurrences = cpu_to_le32(-1);
+   if (!le32_to_cpu(trig->ignore_consec))
+   trig->ignore_consec = cpu_to_le32(-1);
+
iter += sizeof(*trig) +
le32_to_cpu(trig->num_regions) * sizeof(__le32);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 324ee063224d..c14e4614a2ea 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -108,10 +108,12 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
const struct iwl_fw_dump_desc *desc,
bool monitor_only, unsigned int delay);
+int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
+   enum iwl_fw_dbg_trigger trig,
+   const char *str, size_t len,
+   struct iwl_fw_dbg_trigger_tlv *trigger);
 int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
-  enum iwl_fw_dbg_trigger trig,
-  const char *str, size_t len,
-  struct iwl_fw_dbg_trigger_tlv *trigger);
+  u32 id, const c

[PATCH 07/15] iwlwifi: move iwl_nvm_check_version() into dvm

2018-11-23 Thread Luca Coelho
From: Luca Coelho 

This function is only half-used by mvm (i.e. only the nvm_version part
matters, since the calibration version is irrelevant), so it's
pointless to export it from iwlwifi.  If mvm uses this function, it
has the additional complexity of setting the calib version to a bogus
value on all cfg structs.

To avoid this, move the function to dvm and make a simple comparison
of the nvm_version in mvm instead.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/dvm/main.c | 17 +
 .../wireless/intel/iwlwifi/iwl-eeprom-parse.c | 19 ---
 .../wireless/intel/iwlwifi/iwl-eeprom-parse.h |  5 ++---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  4 +++-
 4 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c 
b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index 1088ff036e13..c219bca5cff4 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1224,6 +1224,23 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv 
*priv)
return 0;
 }
 
+static int iwl_nvm_check_version(struct iwl_nvm_data *data,
+struct iwl_trans *trans)
+{
+   if (data->nvm_version >= trans->cfg->nvm_ver ||
+   data->calib_version >= trans->cfg->nvm_calib_ver) {
+   IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
+  data->nvm_version, data->calib_version);
+   return 0;
+   }
+
+   IWL_ERR(trans,
+   "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 
0x%x\n",
+   data->nvm_version, trans->cfg->nvm_ver,
+   data->calib_version,  trans->cfg->nvm_calib_ver);
+   return -EINVAL;
+}
+
 static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
 const struct iwl_cfg *cfg,
 const struct iwl_fw *fw,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
index 4e3422a1c7bb..75940ac406b9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
@@ -927,22 +927,3 @@ iwl_parse_eeprom_data(struct device *dev, const struct 
iwl_cfg *cfg,
return NULL;
 }
 IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data);
-
-/* helper functions */
-int iwl_nvm_check_version(struct iwl_nvm_data *data,
-struct iwl_trans *trans)
-{
-   if (data->nvm_version >= trans->cfg->nvm_ver ||
-   data->calib_version >= trans->cfg->nvm_calib_ver) {
-   IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n",
-  data->nvm_version, data->calib_version);
-   return 0;
-   }
-
-   IWL_ERR(trans,
-   "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 
0x%x\n",
-   data->nvm_version, trans->cfg->nvm_ver,
-   data->calib_version,  trans->cfg->nvm_calib_ver);
-   return -EINVAL;
-}
-IWL_EXPORT_SYMBOL(iwl_nvm_check_version);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
index d910bda087f7..2375d300a7cd 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
@@ -7,6 +7,7 @@
  *
  * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2018 Intel Corporation
  *
  * 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
@@ -28,6 +29,7 @@
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2015 Intel Mobile Communications GmbH
+ * Copyright (C) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -117,9 +119,6 @@ struct iwl_nvm_data *
 iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
  const u8 *eeprom, size_t eeprom_size);
 
-int iwl_nvm_check_version(struct iwl_nvm_data *data,
- struct iwl_trans *trans);
-
 int iwl_init_sband_channels(struct iwl_nvm_data *data,
struct ieee80211_supported_band *sband,
int n_channels, enum nl80211_band band);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index dcb739fb7c35..717924136d5b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/ne

[PATCH 01/15] iwlwifi: move common 9000 cfg parameters to common macro

2018-11-23 Thread Luca Coelho
From: Luca Coelho 

The ht_params, nvm_ver, nvm_calib_ver and max_ht_ampdu_exponent
elements in 9000 devices are always the same.  Move them to the common
macro.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 79 ++-
 1 file changed, 6 insertions(+), 73 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index d55fd23cafe6..baaaf2a5dc7b 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -157,17 +157,18 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.min_umac_error_event_table = 0x80, \
.csr = _csr_v1, \
.d3_debug_data_base_addr = 0x401000,\
-   .d3_debug_data_length = 92 * 1024
+   .d3_debug_data_length = 92 * 1024,  \
+   .ht_params = _ht_params,\
+   .nvm_ver = IWL9000_NVM_VERSION, \
+   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,  \
+   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+
 
 const struct iwl_cfg iwl9160_2ac_cfg = {
.name = "Intel(R) Dual Band Wireless AC 9160",
.fw_name_pre = IWL9260A_FW_PRE,
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
 const struct iwl_cfg iwl9260_2ac_cfg = {
@@ -175,10 +176,6 @@ const struct iwl_cfg iwl9260_2ac_cfg = {
.fw_name_pre = IWL9260A_FW_PRE,
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
 const struct iwl_cfg iwl9260_killer_2ac_cfg = {
@@ -186,10 +183,6 @@ const struct iwl_cfg iwl9260_killer_2ac_cfg = {
.fw_name_pre = IWL9260A_FW_PRE,
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
 const struct iwl_cfg iwl9270_2ac_cfg = {
@@ -197,10 +190,6 @@ const struct iwl_cfg iwl9270_2ac_cfg = {
.fw_name_pre = IWL9260A_FW_PRE,
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
 const struct iwl_cfg iwl9460_2ac_cfg = {
@@ -208,10 +197,6 @@ const struct iwl_cfg iwl9460_2ac_cfg = {
.fw_name_pre = IWL9260A_FW_PRE,
.fw_name_pre_b_or_c_step = IWL9260B_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
 const struct iwl_cfg iwl9460_2ac_cfg_soc = {
@@ -220,10 +205,6 @@ const struct iwl_cfg iwl9460_2ac_cfg_soc = {
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
.integrated = true,
.soc_latency = 5000,
 };
@@ -234,10 +215,6 @@ const struct iwl_cfg iwl9461_2ac_cfg_soc = {
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
.integrated = true,
.soc_latency = 5000,
 };
@@ -248,10 +225,6 @@ const struct iwl_cfg iwl9462_2ac_cfg_soc = {
.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
IWL_DEVICE_9000,
-   .ht_params = _ht_params,
-   .nvm_ver = IWL9000_NVM_VERSION,
-   .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
-   .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
.integrated = true,
.soc_latency = 5000,
 };
@@ -261,10 +234,6 @@ const struct iwl_cfg iwl9560_2ac_cfg = {
.fw_name_pre = IWL9260A_FW_PRE,
.fw_name_pre_b

[PATCH 05/15] iwlwifi: don't define OTP_LOW_IMAGE_SIZE per family, but per size

2018-11-23 Thread Luca Coelho
From: Luca Coelho 

Using OTP_LOW_IMAGE_SIZE_FAMILY_8000/9000/22000 only obfuscates the
actual values, since these 3 are the same.  Redefine the values per
size so it's easier to understand and compare the different
configurations.

Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/cfg/1000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/2000.c   | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c  | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/6000.c   | 6 +++---
 drivers/net/wireless/intel/iwlwifi/cfg/7000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/8000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h | 8 +++-
 8 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
index 76b5ddb20248..b67e08dfbe29 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
@@ -48,7 +48,7 @@
 static const struct iwl_base_params iwl1000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   /* .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, */
.pll_cfg = true,
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
index e7e45846dd07..a6ec7ad39dcb 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
@@ -57,7 +57,7 @@
 #define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
 
 static const struct iwl_base_params iwl2000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
@@ -71,7 +71,7 @@ static const struct iwl_base_params iwl2000_base_params = {
 
 
 static const struct iwl_base_params iwl2030_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 8b2339165bca..2d395a4a5375 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -109,7 +109,7 @@
 #define NVM_HW_SECTION_NUM_FAMILY_2200010
 
 static const struct iwl_base_params iwl_22000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 512,
.max_tfd_queue_size = 256,
.shadow_ram_support = true,
@@ -121,7 +121,7 @@ static const struct iwl_base_params iwl_22000_base_params = 
{
 };
 
 static const struct iwl_base_params iwl_22560_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 512,
.max_tfd_queue_size = 65536,
.shadow_ram_support = true,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
index 30e62a7c9d52..fbb18d066cd0 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
@@ -66,7 +66,7 @@
 #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
 
 static const struct iwl_base_params iwl6000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -79,7 +79,7 @@ static const struct iwl_base_params iwl6000_base_params = {
 };
 
 static const struct iwl_base_params iwl6050_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
@@ -92,7 +92,7 @@ static const struct iwl_base_params iwl6050_base_params = {
 };
 
 static const struct iwl_base_params iwl6000_g2_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index c973bfaa3414..38d5db50b1ed 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
@@ -116,

pull-request: iwlwifi-next 2018-11-23

2018-11-23 Thread Luca Coelho
Hi Kalle,

This is the second batch of patches intended for v4.21.  This includes
only the last patchset I sent.  Usual development work, mostly in the
debugging infrastructure and small fixes and cleanups.  More details
about the contents in the tag description.

I have sent this out before and kbuildbot reported success.

Please let me know if there are any issues.

Cheers,
Luca.


The following changes since commit 12d56175c89c8a8cc41e478775155709274ff733:

  Merge tag 'iwlwifi-next-for-kalle-2018-11-11' of 
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next (2018-11-15 
16:59:01 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git 
tags/iwlwifi-next-for-kalle-2018-11-23

for you to fetch changes up to 520229e4b02dc4f5241a251a569fe0691a2c2e2c:

  iwlwifi: mvm: set HW capability VHT_EXT_NSS_BW (2018-11-23 13:01:08 +0200)


second batch of iwlwifi patches intended for v4.21

* New FW debugging infrastructure;
* Some more work on 802.11ax;
* Improve support for multiple RF modules with 22000 devices;
* Remove an unused FW parameter;
* Other debugging improvements;


Emmanuel Grumbach (2):
  iwlwifi: mvm: remove assignment of the reciprocal
  iwlwifi: mvm: add support for TWT capabilities

Lior Cohen (2):
  iwlwifi: add fw dump upon RT ucode start failure
  iwlwifi: add debugfs file to read fw debug data recording

Luca Coelho (1):
  iwlwifi: fix cfg structs for 22000 with different RF modules

Sara Sharon (8):
  iwlwifi: dbg: don't limit dump decisions to all or monitor
  iwlwifi: dbg: split fifos dump
  iwlwifi: fw: add FW API of new TLV infrastructure
  iwlwifi: trans: parse and store debug ini TLVs
  iwlwifi: trans: support loading ini TLVs from external file
  iwlwifi: dbg: disable triggers for ini
  iwlwifi: dbg: add apply point logic
  iwlwifi: fw: support API change to debug TLVs

Shaul Triebitz (3):
  iwlwifi: mvm: set MAC_FILTER_IN_11AX in AP mode
  iwlwifi: mvm: send the STA_HE_CTXT command in AP mode
  iwlwifi: mvm: set HW capability VHT_EXT_NSS_BW

 drivers/net/wireless/intel/iwlwifi/Makefile |   1 +
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c  |   1 -
 drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 401 
++
 drivers/net/wireless/intel/iwlwifi/fw/api/mac.h |  39 +-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 277 

 drivers/net/wireless/intel/iwlwifi/fw/dbg.h |  22 ++
 drivers/net/wireless/intel/iwlwifi/fw/file.h|   7 ++
 drivers/net/wireless/intel/iwlwifi/fw/img.h |  26 +++
 drivers/net/wireless/intel/iwlwifi/fw/runtime.h |   3 +
 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c| 230 

 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h|  87 
++
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c|  24 +-
 drivers/net/wireless/intel/iwlwifi/iwl-modparams.h  |   2 +
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h  |  23 --
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c |   5 ++
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c   |  39 ++
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c   |   4 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c|   1 -
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c   |   2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h  |  44 +++
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 213 
+++-
 21 files changed, 1374 insertions(+), 77 deletions(-)
 create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
 create mode 100644 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
 create mode 100644 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h


signature.asc
Description: This is a digitally signed message part


pull-request: iwlwifi 2018-11-15

2018-11-15 Thread Luca Coelho
Hi Kalle,

This is the first batch of fixes for v4.20.  More details about the
contents in the tag description.

I have sent this out before and kbuildbot reported success.

Please let me know if there are any issues.

Cheers,
Luca.


The following changes since commit b374e8686fc35ae124e62dc78725ea656ba1ef8a:

  mt76: fix building without CONFIG_LEDS_CLASS (2018-11-06 18:46:33 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git 
tags/iwlwifi-for-kalle-2018-11-15

for you to fetch changes up to 5d041c46ccb9b48acc110e214beff5e2789311df:

  iwlwifi: mvm: don't use SAR Geo if basic SAR is not used (2018-11-15 23:50:59 
+0200)


First batch of iwlwifi fixes for 4.20

* New FW debugging infrastructure;
* Some more work on 802.11ax;
* Improve support for multiple RF modules with 22000 devices;
* Remove an unused FW parameter;
* Other debugging improvements;


Emmanuel Grumbach (2):
  iwlwifi: mvm: support sta_statistics() even on older firmware
  iwlwifi: mvm: fix regulatory domain update when the firmware starts

Luca Coelho (1):
  iwlwifi: mvm: don't use SAR Geo if basic SAR is not used

Matt Chen (1):
  iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE

Shahar S Matityahu (1):
  iwlwifi: fix D3 debug data buffer memory leak

 drivers/net/wireless/intel/iwlwifi/fw/acpi.h  |  4 +++-
 drivers/net/wireless/intel/iwlwifi/fw/runtime.h   |  6 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   | 38 
+-
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c  |  5 ++---
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  2 ++
 6 files changed, 47 insertions(+), 20 deletions(-)


signature.asc
Description: This is a digitally signed message part


[PATCH v2 5/5] iwlwifi: mvm: don't use SAR Geo if basic SAR is not used

2018-11-12 Thread Luca Coelho
From: Luca Coelho 

We can't use SAR Geo if basic SAR is not enabled, since the SAR Geo
tables define offsets in relation to the basic SAR table in use.

To fix this, make iwl_mvm_sar_init() return one in case WRDS is not
available, so we can skip reading WGDS entirely.

Fixes: a6bff3cb19b7 ("iwlwifi: mvm: add GEO_TX_POWER_LIMIT cmd for geographic 
tx power table")
Cc: sta...@vger.kernel.org # 4.12+
Signed-off-by: Luca Coelho 
---
In v2:
   * fix compilation when CONFIG_ACPI is not set;

drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 36 -
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 899f4a6432fb..2ba890445c35 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -928,6 +928,11 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)
return -ENOENT;
 }
 
+static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
+{
+   return -ENOENT;
+}
+
 static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
 {
return 0;
@@ -954,8 +959,11 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
IWL_DEBUG_RADIO(mvm,
"WRDS SAR BIOS table invalid or unavailable. 
(%d)\n",
ret);
-   /* if not available, don't fail and don't bother with EWRD */
-   return 0;
+   /*
+* If not available, don't fail and don't bother with EWRD.
+* Return 1 to tell that we can't use WGDS either.
+*/
+   return 1;
}
 
ret = iwl_mvm_sar_get_ewrd_table(mvm);
@@ -968,9 +976,13 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
/* choose profile 1 (WRDS) as default for both chains */
ret = iwl_mvm_sar_select_profile(mvm, 1, 1);
 
-   /* if we don't have profile 0 from BIOS, just skip it */
+   /*
+* If we don't have profile 0 from BIOS, just skip it.  This
+* means that SAR Geo will not be enabled either, even if we
+* have other valid profiles.
+*/
if (ret == -ENOENT)
-   return 0;
+   return 1;
 
return ret;
 }
@@ -1168,11 +1180,19 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
 
ret = iwl_mvm_sar_init(mvm);
-   if (ret)
-   goto error;
+   if (ret == 0) {
+   ret = iwl_mvm_sar_geo_init(mvm);
+   } else if (ret > 0 && !iwl_mvm_sar_get_wgds_table(mvm)) {
+   /*
+* If basic SAR is not available, we check for WGDS,
+* which should *not* be available either.  If it is
+* available, issue an error, because we can't use SAR
+* Geo without basic SAR.
+*/
+   IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n");
+   }
 
-   ret = iwl_mvm_sar_geo_init(mvm);
-   if (ret)
+   if (ret < 0)
goto error;
 
iwl_mvm_leds_sync(mvm);
-- 
2.19.1



[PATCH 01/16] iwlwifi: dbg: don't limit dump decisions to all or monitor

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

Currently opmode is limited to asking transport to either
dump all the dumps configured at startup, or monitor only.
Instead, pass to transport a bitmask, to allow flexibility.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   |  7 +++--
 .../net/wireless/intel/iwlwifi/iwl-trans.h|  7 ++---
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  1 -
 .../net/wireless/intel/iwlwifi/pcie/trans.c   | 31 +--
 4 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 58a980070445..67e6a35f14c4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -908,6 +908,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
struct iwl_fw_error_dump_file *dump_file;
struct scatterlist *sg_dump_data;
u32 file_len;
+   u32 dump_mask = fwrt->fw->dbg.dump_mask;
 
IWL_DEBUG_INFO(fwrt, "WRT dump start\n");
 
@@ -927,8 +928,10 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
goto out;
}
 
-   fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans,
-  fwrt->dump.monitor_only);
+   if (fwrt->dump.monitor_only)
+   dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR;
+
+   fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask);
file_len = le32_to_cpu(dump_file->file_len);
fw_error_dump->fwrt_len = file_len;
if (fw_error_dump->trans_ptr) {
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index f384a98a021c..b0300e824815 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -602,7 +602,7 @@ struct iwl_trans_ops {
void (*resume)(struct iwl_trans *trans);
 
struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
-bool monitor_only);
+u32 dump_mask);
 };
 
 /**
@@ -776,7 +776,6 @@ struct iwl_trans {
const struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv;
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
-   u32 dbg_dump_mask;
u8 dbg_n_dest_reg;
int num_blocks;
struct iwl_dram_data fw_mon[IWL_MAX_DEBUG_ALLOCATIONS];
@@ -896,11 +895,11 @@ static inline void iwl_trans_resume(struct iwl_trans 
*trans)
 }
 
 static inline struct iwl_trans_dump_data *
-iwl_trans_dump_data(struct iwl_trans *trans, bool monitor_only)
+iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask)
 {
if (!trans->ops->dump_data)
return NULL;
-   return trans->ops->dump_data(trans, monitor_only);
+   return trans->ops->dump_data(trans, dump_mask);
 }
 
 static inline struct iwl_device_cmd *
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 2291661dd72d..0a5b35312b59 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -769,7 +769,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
memcpy(trans->dbg_conf_tlv, mvm->fw->dbg.conf_tlv,
   sizeof(trans->dbg_conf_tlv));
trans->dbg_trigger_tlv = mvm->fw->dbg.trigger_tlv;
-   trans->dbg_dump_mask = mvm->fw->dbg.dump_mask;
 
trans->iml = mvm->fw->iml;
trans->iml_len = mvm->fw->iml_len;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 551ce439647b..16eed9b0f301 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2990,7 +2990,7 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans 
*trans, int *len)
 
 static struct iwl_trans_dump_data
 *iwl_trans_pcie_dump_data(struct iwl_trans *trans,
- bool monitor_only)
+ u32 dump_mask)
 {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_fw_error_dump_data *data;
@@ -3002,7 +3002,10 @@ static struct iwl_trans_dump_data
int i, ptr;
bool dump_rbs = test_bit(STATUS_FW_ERROR, >status) &&
!trans->cfg->mq_rx_supported &&
-   trans->dbg_dump_mask & BIT(IWL_FW_ERROR_DUMP_RB);
+   dump_mask & BIT(IWL_FW_ERROR_DUMP_RB);
+
+   if (!dump_mask)
+   return NULL;
 
/* transport dump header */
len = sizeof(*d

[PATCH 00/16] iwlwifi: updates intended for v4.21 2018-11-11

2018-11-11 Thread Luca Coelho
From: Luca Coelho 

Hi,

Here's the second set of patches intended for v4.21.  It's the usual
development, with some small new features, cleanups and bugfixes.

The changes are:

* New FW debugging infrastructure;
* Some more work on 802.11ax;
* Improve support for multiple RF modules with 22000 devices;
* Remove an unused FW parameter;
* Other debugging improvements;

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

Please review.

Cheers,
Luca.


Emmanuel Grumbach (2):
  iwlwifi: mvm: remove assignment of the reciprocal
  iwlwifi: mvm: add support for TWT capabilities

Lior Cohen (2):
  iwlwifi: add fw dump upon RT ucode start failure
  iwlwifi: add debugfs file to read fw debug data recording

Luca Coelho (1):
  iwlwifi: fix cfg structs for 22000 with different RF modules

Sara Sharon (8):
  iwlwifi: dbg: don't limit dump decisions to all or monitor
  iwlwifi: dbg: split fifos dump
  iwlwifi: fw: add FW API of new TLV infrastructure
  iwlwifi: trans: parse and store debug ini TLVs
  iwlwifi: trans: support loading ini TLVs from external file
  iwlwifi: dbg: disable triggers for ini
  iwlwifi: dbg: add apply point logic
  iwlwifi: fw: support API change to debug TLVs

Shaul Triebitz (3):
  iwlwifi: mvm: set MAC_FILTER_IN_11AX in AP mode
  iwlwifi: mvm: send the STA_HE_CTXT command in AP mode
  iwlwifi: mvm: set HW capability VHT_EXT_NSS_BW

 drivers/net/wireless/intel/iwlwifi/Makefile   |   1 +
 .../net/wireless/intel/iwlwifi/cfg/22000.c|   1 -
 .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h   | 401 ++
 .../net/wireless/intel/iwlwifi/fw/api/mac.h   |  39 +-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 277 +++-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |  22 +
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |   7 +
 drivers/net/wireless/intel/iwlwifi/fw/img.h   |  26 ++
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |   3 +
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c  | 230 ++
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h  |  87 
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  |  24 +-
 .../wireless/intel/iwlwifi/iwl-modparams.h|   2 +
 .../net/wireless/intel/iwlwifi/iwl-trans.h|  23 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |   5 +
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |  39 +-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |   4 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |   1 -
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c |   2 +-
 .../wireless/intel/iwlwifi/pcie/internal.h|  44 ++
 .../net/wireless/intel/iwlwifi/pcie/trans.c   | 213 +-
 21 files changed, 1374 insertions(+), 77 deletions(-)
 create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
 create mode 100644 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
 create mode 100644 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h

-- 
2.19.1



[PATCH 02/16] iwlwifi: dbg: split fifos dump

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

Split the dump of RXF and TXF. This is in order to
enable code reuse for INI, which may decide to dump
only RXF and not TXF, and vice versa.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 52 +++--
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 67e6a35f14c4..6243b503d0b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -225,17 +225,13 @@ static void iwl_fwrt_dump_txf(struct iwl_fw_runtime *fwrt,
*dump_data = iwl_fw_error_next_data(*dump_data);
 }
 
-static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_error_dump_data **dump_data)
+static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt,
+   struct iwl_fw_error_dump_data **dump_data)
 {
-   struct iwl_fw_error_dump_fifo *fifo_hdr;
struct iwl_fwrt_shared_mem_cfg *cfg = >smem_cfg;
-   u32 *fifo_data;
-   u32 fifo_len;
unsigned long flags;
-   int i, j;
 
-   IWL_DEBUG_INFO(fwrt, "WRT FIFO dump\n");
+   IWL_DEBUG_INFO(fwrt, "WRT RX FIFO dump\n");
 
if (!iwl_trans_grab_nic_access(fwrt->trans, ))
return;
@@ -254,6 +250,24 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
  LMAC2_PRPH_OFFSET, 2);
}
 
+   iwl_trans_release_nic_access(fwrt->trans, );
+}
+
+static void iwl_fw_dump_txf(struct iwl_fw_runtime *fwrt,
+   struct iwl_fw_error_dump_data **dump_data)
+{
+   struct iwl_fw_error_dump_fifo *fifo_hdr;
+   struct iwl_fwrt_shared_mem_cfg *cfg = >smem_cfg;
+   u32 *fifo_data;
+   u32 fifo_len;
+   unsigned long flags;
+   int i, j;
+
+   IWL_DEBUG_INFO(fwrt, "WRT TX FIFO dump\n");
+
+   if (!iwl_trans_grab_nic_access(fwrt->trans, ))
+   return;
+
if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_TXF)) {
/* Pull TXF data from LMAC1 */
for (i = 0; i < fwrt->smem_cfg.num_txfifo_entries; i++) {
@@ -595,8 +609,8 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
do {size_t item = item_len; len += (!!item) * const_len + item; } \
while (0)
 
-static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
-  struct iwl_fwrt_shared_mem_cfg *mem_cfg)
+static int iwl_fw_rxf_len(struct iwl_fw_runtime *fwrt,
+ struct iwl_fwrt_shared_mem_cfg *mem_cfg)
 {
size_t hdr_len = sizeof(struct iwl_fw_error_dump_data) +
 sizeof(struct iwl_fw_error_dump_fifo);
@@ -604,7 +618,7 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
int i;
 
if (!iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RXF))
-   goto dump_txf;
+   return 0;
 
/* Count RXF2 size */
ADD_LEN(fifo_len, mem_cfg->rxfifo2_size, hdr_len);
@@ -613,7 +627,17 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
for (i = 0; i < mem_cfg->num_lmacs; i++)
ADD_LEN(fifo_len, mem_cfg->lmac[i].rxfifo1_size, hdr_len);
 
-dump_txf:
+   return fifo_len;
+}
+
+static int iwl_fw_txf_len(struct iwl_fw_runtime *fwrt,
+ struct iwl_fwrt_shared_mem_cfg *mem_cfg)
+{
+   size_t hdr_len = sizeof(struct iwl_fw_error_dump_data) +
+sizeof(struct iwl_fw_error_dump_fifo);
+   u32 fifo_len = 0;
+   int i;
+
if (!iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_TXF))
goto dump_internal_txf;
 
@@ -697,7 +721,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
 
/* reading RXF/TXF sizes */
if (test_bit(STATUS_FW_ERROR, >trans->status)) {
-   fifo_len = iwl_fw_fifo_len(fwrt, mem_cfg);
+   fifo_len = iwl_fw_rxf_len(fwrt, mem_cfg);
+   fifo_len += iwl_fw_txf_len(fwrt, mem_cfg);
 
/* Make room for PRPH registers */
if (!fwrt->trans->cfg->gen2 &&
@@ -817,7 +842,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
 
/* We only dump the FIFOs if the FW is in error state */
if (fifo_len) {
-   iwl_fw_dump_fifos(fwrt, _data);
+   iwl_fw_dump_rxf(fwrt, _data);
+   iwl_fw_dump_txf(fwrt, _data);
if (radio_len)
iwl_read_radio_regs(fwrt, _data);
}
-- 
2.19.1



[PATCH 06/16] iwlwifi: mvm: add support for TWT capabilities

2018-11-11 Thread Luca Coelho
From: Emmanuel Grumbach 

We need to check the TWT support of the peer and to
propagte the capability to the firmware.
The current implementation will enable TWT only if the TWT
support is advertised in the HE CAP IE and in the Extended
Capability IE.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/fw/api/mac.h   | 16 +
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 24 ++-
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
index d0b79fb461bf..2c9e40eedef5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
@@ -185,6 +185,14 @@ struct iwl_mac_data_ibss {
__le32 beacon_template;
 } __packed; /* IBSS_MAC_DATA_API_S_VER_1 */
 
+/**
+ * enum iwl_mac_data_policy - policy of the data path for this MAC
+ * @TWT_SUPPORTED: twt is supported
+ */
+enum iwl_mac_data_policy {
+   TWT_SUPPORTED   = BIT(0),
+};
+
 /**
  * struct iwl_mac_data_sta - configuration data for station MAC context
  * @is_assoc: 1 for associated state, 0 otherwise
@@ -193,7 +201,7 @@ struct iwl_mac_data_ibss {
  * @bi: beacon interval in TU, applicable only when associated
  * @reserved1: reserved
  * @dtim_interval: DTIM interval in TU, applicable only when associated
- * @reserved2: reserved
+ * @data_policy: see  iwl_mac_data_policy
  * @listen_interval: in beacon intervals, applicable only when associated
  * @assoc_id: unique ID assigned by the AP during association
  * @assoc_beacon_arrive_time: TSF of first beacon after association
@@ -205,11 +213,11 @@ struct iwl_mac_data_sta {
__le32 bi;
__le32 reserved1;
__le32 dtim_interval;
-   __le32 reserved2;
+   __le32 data_policy;
__le32 listen_interval;
__le32 assoc_id;
__le32 assoc_beacon_arrive_time;
-} __packed; /* STA_MAC_DATA_API_S_VER_1 */
+} __packed; /* STA_MAC_DATA_API_S_VER_2 */
 
 /**
  * struct iwl_mac_data_go - configuration data for P2P GO MAC context
@@ -233,7 +241,7 @@ struct iwl_mac_data_go {
 struct iwl_mac_data_p2p_sta {
struct iwl_mac_data_sta sta;
__le32 ctwin;
-} __packed; /* P2P_STA_MAC_DATA_API_S_VER_1 */
+} __packed; /* P2P_STA_MAC_DATA_API_S_VER_2 */
 
 /**
  * struct iwl_mac_data_pibss - Pseudo IBSS config data
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 3b93293d4559..990ebf89f342 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -777,8 +777,30 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
 
if (vif->bss_conf.assoc && vif->bss_conf.he_support &&
-   !iwlwifi_mod_params.disable_11ax)
+   !iwlwifi_mod_params.disable_11ax) {
+   struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+   u8 sta_id = mvmvif->ap_sta_id;
+
cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_11AX);
+   if (sta_id != IWL_MVM_INVALID_STA) {
+   struct ieee80211_sta *sta;
+
+   sta = 
rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
+   lockdep_is_held(>mutex));
+
+   /*
+* TODO: we should check the ext cap IE but it is
+* unclear why the spec requires two bits (one in HE
+* cap IE, and one in the ext cap IE). In the meantime
+* rely on the HE cap IE only.
+*/
+   if (sta && (sta->he_cap.he_cap_elem.mac_cap_info[0] &
+   IEEE80211_HE_MAC_CAP0_TWT_RES))
+   ctxt_sta->data_policy |=
+   cpu_to_le32(TWT_SUPPORTED);
+   }
+   }
+
 
return iwl_mvm_mac_ctxt_send_cmd(mvm, );
 }
-- 
2.19.1



[PATCH 08/16] iwlwifi: trans: parse and store debug ini TLVs

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

The new debug ini TLVs can be either packed into firmware
binary or written in external file. Support loading them
from both. Store the data per apply point. Apply point is
a point during driver runtime, where the TLV becomes active.
For example, a trigger of hardware error may be configured
to collect a subset of data pre-alive, as a opposed to HW
error that occurs after alive.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/Makefile   |   1 +
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |   7 +
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c  | 154 ++
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h  |  84 ++
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  |  17 ++
 .../wireless/intel/iwlwifi/iwl-modparams.h|   2 +
 .../net/wireless/intel/iwlwifi/iwl-trans.h|   4 +
 7 files changed, 269 insertions(+)
 create mode 100644 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
 create mode 100644 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h

diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile 
b/drivers/net/wireless/intel/iwlwifi/Makefile
index 04e376cc898c..ff41987a7e35 100644
--- a/drivers/net/wireless/intel/iwlwifi/Makefile
+++ b/drivers/net/wireless/intel/iwlwifi/Makefile
@@ -11,6 +11,7 @@ iwlwifi-objs  += pcie/ctxt-info.o 
pcie/ctxt-info-gen3.o
 iwlwifi-objs   += pcie/trans-gen2.o pcie/tx-gen2.o
 iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o cfg/5000.o cfg/6000.o
 iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/22000.o
+iwlwifi-objs   += iwl-dbg-tlv.o
 iwlwifi-objs   += iwl-trans.o
 iwlwifi-objs   += fw/notif-wait.o
 iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h 
b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 6005a41c53d1..81f557c0b58d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -91,6 +91,8 @@ struct iwl_ucode_header {
} u;
 };
 
+#define IWL_UCODE_INI_TLV_GROUPBIT(24)
+
 /*
  * new TLV uCode file layout
  *
@@ -141,6 +143,11 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_FW_GSCAN_CAPA = 50,
IWL_UCODE_TLV_FW_MEM_SEG= 51,
IWL_UCODE_TLV_IML   = 52,
+   IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION= IWL_UCODE_INI_TLV_GROUP | 0x1,
+   IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP | 0x2,
+   IWL_UCODE_TLV_TYPE_REGIONS  = IWL_UCODE_INI_TLV_GROUP | 0x3,
+   IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_INI_TLV_GROUP | 0x4,
+   IWL_UCODE_TLV_TYPE_DEBUG_FLOW   = IWL_UCODE_INI_TLV_GROUP | 0x5,
 
/* TLVs 0x1000-0x2000 are for internal driver usage */
IWL_UCODE_TLV_FW_DBG_DUMP_LST   = 0x1000,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
new file mode 100644
index ..acefd7d5d099
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -0,0 +1,154 @@
+/**
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless 
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright (C) 2018 Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in
+ *the documentation and/or other materials provided with the
+ *distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *contributors may be used to endorse or promote products derived
+ *from

[PATCH 07/16] iwlwifi: fw: add FW API of new TLV infrastructure

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

Add the FW API of the new debug infrastructure. Next patches
will introduce the utilization of this infra.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h   | 399 ++
 1 file changed, 399 insertions(+)
 create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
new file mode 100644
index ..82f3c9bbd9b1
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
@@ -0,0 +1,399 @@
+/**
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless 
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright (C) 2018 Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in
+ *the documentation and/or other materials provided with the
+ *distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *contributors may be used to endorse or promote products derived
+ *from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __iwl_fw_dbg_tlv_h__
+#define __iwl_fw_dbg_tlv_h__
+
+#include 
+
+/*
+ * struct iwl_fw_ini_header: Common Header for all debug group TLV's structures
+ * @tlv_version: version info
+ * @apply_point:  iwl_fw_ini_apply_point
+ * @data: TLV data followed
+ **/
+struct iwl_fw_ini_header {
+   __le32 tlv_version;
+   __le32 apply_point;
+   u8 data[];
+} __packed; /* FW_INI_HEADER_TLV_S */
+
+/**
+ * struct iwl_fw_ini_allocation_tlv - (IWL_FW_INI_TLV_TYPE_BUFFER_ALLOCATION)
+ * buffer allocation TLV - for debug
+ *
+ * @iwl_fw_ini_header: header
+ * @allocation_id:  iwl_fw_ini_allocation_id - to bind allocation and hcmd
+ * if needed (DBGC1/DBGC2/SDFX/...)
+ * @buffer_location: type of iwl_fw_ini_buffer_location
+ * @size: size in bytes
+ * @max_fragments: the maximum allowed fragmentation in the desired memory
+ * allocation above
+ * @min_frag_size: the minimum allowed fragmentation size in bytes
+*/
+struct iwl_fw_ini_allocation_tlv {
+   struct iwl_fw_ini_header header;
+   __le32 allocation_id;
+   __le32 buffer_location;
+   __le32 size;
+   __le32 max_fragments;
+   __le32 min_frag_size;
+} __packed; /* FW_INI_BUFFER_ALLOCATION_TLV_S_VER_1 */
+
+/**
+ * struct iwl_fw_ini_hcmd (IWL_FW_INI_TLV_TYPE_HCMD)
+ * Generic Host command pass through TLV
+ *
+ * @id: the debug configuration command type for instance: 0xf6 / 0xf5 / DHC
+ * @group: the desired cmd group
+ * @padding: all zeros for dword alignment
+ * @data: all of the relevant command (0xf6/0xf5) to be sent
+*/
+struct iwl_fw_ini_hcmd {
+   u8 id;
+   u8 group;
+   __le16 padding;
+   u8 data[0];
+

[PATCH 09/16] iwlwifi: trans: support loading ini TLVs from external file

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

Support loading and storing ini TLVs from external
file. Those TLVs are appended to the default TLVs,
so store them separately.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c  | 81 +--
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h  |  7 +-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  |  9 ++-
 .../net/wireless/intel/iwlwifi/iwl-trans.h|  3 +
 4 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index acefd7d5d099..7b2951521c77 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -63,7 +63,8 @@
 #include "iwl-trans.h"
 #include "iwl-dbg-tlv.h"
 
-void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv)
+void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
+bool ext)
 {
struct iwl_apply_point_data *data;
struct iwl_fw_ini_header *header = (void *)>data[0];
@@ -75,7 +76,10 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct 
iwl_ucode_tlv *tlv)
  "Invalid apply point id %d\n", apply_point))
return;
 
-   data = >apply_points[apply_point];
+   if (ext)
+   data = >apply_points_ext[apply_point];
+   else
+   data = >apply_points[apply_point];
 
/*
 * Make sure we still have room to copy this TLV. Offset points to the
@@ -90,7 +94,8 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct 
iwl_ucode_tlv *tlv)
data->offset += copy_size;
 }
 
-void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data)
+void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
+  bool ext)
 {
struct iwl_ucode_tlv *tlv;
u32 size[IWL_FW_INI_APPLY_NUM] = {0};
@@ -137,8 +142,13 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t 
len, const u8 *data)
return;
}
 
-   trans->apply_points[i].data = mem;
-   trans->apply_points[i].size = size[i];
+   if (ext) {
+   trans->apply_points_ext[i].data = mem;
+   trans->apply_points_ext[i].size = size[i];
+   } else {
+   trans->apply_points[i].data = mem;
+   trans->apply_points[i].size = size[i];
+   }
}
 }
 
@@ -150,5 +160,66 @@ void iwl_fw_dbg_free(struct iwl_trans *trans)
kfree(trans->apply_points[i].data);
trans->apply_points[i].size = 0;
trans->apply_points[i].offset = 0;
+
+   kfree(trans->apply_points_ext[i].data);
+   trans->apply_points_ext[i].size = 0;
+   trans->apply_points_ext[i].offset = 0;
+   }
+}
+
+static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
+   size_t len)
+{
+   struct iwl_ucode_tlv *tlv;
+   enum iwl_ucode_tlv_type tlv_type;
+   u32 tlv_len;
+
+   while (len >= sizeof(*tlv)) {
+   len -= sizeof(*tlv);
+   tlv = (void *)data;
+
+   tlv_len = le32_to_cpu(tlv->length);
+   tlv_type = le32_to_cpu(tlv->type);
+
+   if (len < tlv_len) {
+   IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
+   len, tlv_len);
+   return -EINVAL;
+   }
+   len -= ALIGN(tlv_len, 4);
+   data += sizeof(*tlv) + ALIGN(tlv_len, 4);
+
+   switch (tlv_type) {
+   case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
+   case IWL_UCODE_TLV_TYPE_HCMD:
+   case IWL_UCODE_TLV_TYPE_REGIONS:
+   case IWL_UCODE_TLV_TYPE_TRIGGERS:
+   case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
+   iwl_fw_dbg_copy_tlv(trans, tlv, true);
+   default:
+   WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
+   break;
+   }
}
+
+   return 0;
+}
+
+void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans)
+{
+   const struct firmware *fw;
+   int res;
+
+   if (trans->external_ini_loaded || !iwlwifi_mod_params.enable_ini)
+   return;
+
+   res = request_firmware(, "iwl-dbg-tlv.ini", dev);
+   if (res)
+   return;
+
+   iwl_alloc_dbg_tlv(trans, fw->size, fw->data, true);
+   iwl_parse_fw_dbg_tlv(trans, fw->data, fw->size);
+
+   trans->external_ini_loaded = true;
+   release_firmware(fw);
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-t

[PATCH 12/16] iwlwifi: add debugfs file to read fw debug data recording

2018-11-11 Thread Luca Coelho
From: Lior Cohen 

FW debug data will oneshot read all data available in DRAM
and fill the supplied user buffer. In case the read request
is greater than the new data in DRAM, the driver will write
all data it has and return the buffer immediately.

Signed-off-by: Shahar S Matityahu 
Signed-off-by: Lior Cohen 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |  14 ++
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  |   2 +
 .../net/wireless/intel/iwlwifi/iwl-trans.h|   5 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |   3 +
 .../wireless/intel/iwlwifi/pcie/internal.h|  44 +
 .../net/wireless/intel/iwlwifi/pcie/trans.c   | 160 ++
 6 files changed, 228 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 6b3c5677c53a..ab81ea8b636f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -266,6 +266,9 @@ _iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
iwl_write_prph(trans, DBGC_IN_SAMPLE, 0);
udelay(100);
iwl_write_prph(trans, DBGC_OUT_CTRL, 0);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+   trans->dbg_rec_on = false;
+#endif
 }
 
 static inline void
@@ -296,6 +299,14 @@ _iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
}
 }
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt)
+{
+   if (fwrt->fw->dbg.dest_tlv && fwrt->cur_fw_img == IWL_UCODE_REGULAR)
+   fwrt->trans->dbg_rec_on = true;
+}
+#endif
+
 static inline void
 iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt,
 struct iwl_fw_dbg_params *params)
@@ -304,6 +315,9 @@ iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt,
_iwl_fw_dbg_restart_recording(fwrt->trans, params);
else
iwl_fw_dbg_start_stop_hcmd(fwrt, true);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+   iwl_fw_set_dbg_rec_on(fwrt);
+#endif
 }
 
 static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 7b98125e4eb9..a65ba955783d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1628,6 +1628,8 @@ void iwl_drv_stop(struct iwl_drv *drv)
mutex_unlock(_opmode_table_mtx);
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
+   drv->trans->ops->debugfs_cleanup(drv->trans);
+
debugfs_remove_recursive(drv->dbgfs_drv);
 #endif
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index c2531eae5e16..a7009cd4232d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -536,6 +536,8 @@ struct iwl_trans_rxq_dma_data {
  * @dump_data: return a vmalloc'ed buffer with debug data, maybe containing 
last
  * TX'ed commands and similar. The buffer will be vfree'd by the caller.
  * Note that the transport must fill in the proper file headers.
+ * @debugfs_cleanup: used in the driver unload flow to make a proper cleanup
+ * of the trans debugfs
  */
 struct iwl_trans_ops {
 
@@ -605,6 +607,7 @@ struct iwl_trans_ops {
 
struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
 u32 dump_mask);
+   void (*debugfs_cleanup)(struct iwl_trans *trans);
 };
 
 /**
@@ -734,6 +737,7 @@ struct iwl_dram_data {
  * @runtime_pm_mode: the runtime power management mode in use.  This
  * mode is set during the initialization phase and is not
  * supposed to change during runtime.
+ * @dbg_rec_on: true iff there is a fw debug recording currently active
  */
 struct iwl_trans {
const struct iwl_trans_ops *ops;
@@ -790,6 +794,7 @@ struct iwl_trans {
enum iwl_plat_pm_mode system_pm_mode;
enum iwl_plat_pm_mode runtime_pm_mode;
bool suspending;
+   bool dbg_rec_on;
 
/* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 2cd07247e0a7..263b03b3ea66 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -377,6 +377,9 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm 
*mvm,
atomic_set(>mac80211_queue_stop_count[i], 0);
 
set_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, >status);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+   iwl_fw_set_dbg_rec_on(>fwrt);
+#endif
clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, >fwrt.status);
 
return 0;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
i

[PATCH 11/16] iwlwifi: dbg: add apply point logic

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

Add a function to be called when apply point occurs.
For each of the TLVs, the function will perform the
apply point logic:
- For HCMD - send the stored host command
- For buffer allocation - allocate the memory and send the
  buffer allocation command
- For trigger and region - update the stored configuration

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 207 ++
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |   4 +
 drivers/net/wireless/intel/iwlwifi/fw/img.h   |  26 +++
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |   3 +
 .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c  |   3 +
 .../net/wireless/intel/iwlwifi/iwl-trans.h|   3 +-
 6 files changed, 244 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 6460b937d331..76050cc3532a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1263,3 +1263,210 @@ void iwl_fw_dbg_read_d3_debug_data(struct 
iwl_fw_runtime *fwrt)
 cfg->d3_debug_data_length);
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
+
+static void
+iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt,
+struct iwl_fw_ini_allocation_tlv *alloc)
+{
+   struct iwl_trans *trans = fwrt->trans;
+   struct iwl_continuous_record_cmd cont_rec = {};
+   struct iwl_buffer_allocation_cmd *cmd = (void *)_rec.pad[0];
+   struct iwl_host_cmd hcmd = {
+   .id = LDBG_CONFIG_CMD,
+   .flags = CMD_ASYNC,
+   .data[0] = _rec,
+   .len[0] = sizeof(cont_rec),
+   };
+   void *virtual_addr = NULL;
+   u32 size = le32_to_cpu(alloc->size);
+   dma_addr_t phys_addr;
+
+   cont_rec.record_mode.enable_recording = cpu_to_le16(BUFFER_ALLOCATION);
+
+   if (!trans->num_blocks &&
+   le32_to_cpu(alloc->buffer_location) !=
+   IWL_FW_INI_LOCATION_DRAM_PATH)
+   return;
+
+   virtual_addr = dma_alloc_coherent(fwrt->trans->dev, size,
+ _addr, GFP_KERNEL);
+
+   /* TODO: alloc fragments if needed */
+   if (!virtual_addr)
+   IWL_ERR(fwrt, "Failed to allocate debug memory\n");
+
+   if (WARN_ON_ONCE(trans->num_blocks == ARRAY_SIZE(trans->fw_mon)))
+   return;
+
+   trans->fw_mon[trans->num_blocks].block = virtual_addr;
+   trans->fw_mon[trans->num_blocks].physical = phys_addr;
+   trans->fw_mon[trans->num_blocks].size = size;
+   trans->num_blocks++;
+
+   IWL_DEBUG_FW(trans, "Allocated debug block of size %d\n", size);
+
+   /* First block is assigned via registers / context info */
+   if (trans->num_blocks == 1)
+   return;
+
+   cmd->num_frags = cpu_to_le32(1);
+   cmd->fragments[0].address = cpu_to_le64(phys_addr);
+   cmd->fragments[0].size = alloc->size;
+   cmd->allocation_id = alloc->allocation_id;
+   cmd->buffer_location = alloc->buffer_location;
+
+   iwl_trans_send_cmd(trans, );
+}
+
+static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt,
+struct iwl_ucode_tlv *tlv)
+{
+   struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)>data[0];
+   struct iwl_fw_ini_hcmd *data = _tlv->hcmd;
+   u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv);
+
+   struct iwl_host_cmd hcmd = {
+   .id = WIDE_ID(data->group, data->id),
+   .len = { len, },
+   .data = { data->data, },
+   };
+
+   iwl_trans_send_cmd(fwrt->trans, );
+}
+
+static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_ini_region_tlv *tlv,
+ bool ext, enum iwl_fw_ini_apply_point pnt)
+{
+   void *iter = (void *)tlv->region_config;
+   int i, size = le32_to_cpu(tlv->num_regions);
+
+   for (i = 0; i < size; i++) {
+   struct iwl_fw_ini_region_cfg *reg = iter;
+   int id = le32_to_cpu(reg->region_id);
+   struct iwl_fw_ini_active_regs *active;
+
+   if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_regs)))
+   break;
+
+   active = >dump.active_regs[id];
+
+   if (ext && active->apply_point == pnt)
+   IWL_WARN(fwrt->trans,
+"External region TLV overrides FW default 
%x\n",
+id);
+
+   IWL_DEBUG_FW(fwrt,
+"%s: apply point %d, activating region ID %d\n",
+__func__, pnt, id);
+
+  

[PATCH 14/16] iwlwifi: mvm: set MAC_FILTER_IN_11AX in AP mode

2018-11-11 Thread Luca Coelho
From: Shaul Triebitz 

In AP mode, if AP supports 11ax, add the MAC_FILTER_IN_11AX
flag in MAC_CTXT command (needed for various 11ax stuff).

Signed-off-by: Shaul Triebitz 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 990ebf89f342..e049d34a3553 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -1194,6 +1194,9 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm 
*mvm,
IWL_DEBUG_HC(mvm, "No need to receive beacons\n");
}
 
+   if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax)
+   cmd->filter_flags |= cpu_to_le32(MAC_FILTER_IN_11AX);
+
ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
ctxt_ap->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
 vif->bss_conf.dtim_period);
-- 
2.19.1



[PATCH 10/16] iwlwifi: dbg: disable triggers for ini

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

When ini is loaded, disable all legacy trigger
configuration.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c  | 3 +++
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h  | 3 +++
 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 2 ++
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h   | 1 +
 4 files changed, 9 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index efd4ac5bba73..6460b937d331 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1117,6 +1117,9 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
int ret, len = 0;
char buf[64];
 
+   if (fwrt->trans->ini_valid)
+   return 0;
+
if (fmt) {
va_list ap;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 544b42f9fb19..07403aa29793 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -192,6 +192,9 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
 {
struct iwl_fw_dbg_trigger_tlv *trig;
 
+   if (fwrt->trans->ini_valid)
+   return NULL;
+
if (!iwl_fw_dbg_trigger_enabled(fwrt->fw, id))
return NULL;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 7b2951521c77..0160662a1749 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -149,6 +149,8 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, 
const u8 *data,
trans->apply_points[i].data = mem;
trans->apply_points[i].size = size[i];
}
+
+   trans->ini_valid = true;
}
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 0c0cd7dccde8..3d455cf5822b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -779,6 +779,7 @@ struct iwl_trans {
struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM];
 
bool external_ini_loaded;
+   bool ini_valid;
 
const struct iwl_fw_dbg_dest_tlv_v1 *dbg_dest_tlv;
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
-- 
2.19.1



[PATCH 15/16] iwlwifi: mvm: send the STA_HE_CTXT command in AP mode

2018-11-11 Thread Luca Coelho
From: Shaul Triebitz 

In AP mode, if AP supports HE (and the STA), send the
STA_HE_CTXT command.

This is needed mainly for PPE (packet extension) params.

Signed-off-by: Shaul Triebitz 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 55b965629e33..64be5fa7eda3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2968,6 +2968,9 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_AP) {
mvmvif->ap_assoc_sta_count++;
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
+   if (vif->bss_conf.he_support &&
+   !iwlwifi_mod_params.disable_11ax)
+   iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id);
}
 
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
-- 
2.19.1



[PATCH 16/16] iwlwifi: mvm: set HW capability VHT_EXT_NSS_BW

2018-11-11 Thread Luca Coelho
From: Shaul Triebitz 

Enable the VHT extended NSS BW feature in iwlwifi/mvm.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 64be5fa7eda3..6fe48cc31071 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -419,6 +419,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
ieee80211_hw_set(hw, DEAUTH_NEED_MGD_TX_PREP);
+   ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
 
if (iwl_mvm_has_tlc_offload(mvm)) {
ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
-- 
2.19.1



[PATCH 05/16] iwlwifi: add fw dump upon RT ucode start failure

2018-11-11 Thread Luca Coelho
From: Lior Cohen 

FW dump was missing in case the RT FW ucode
section failed to load. This failure happens when
the RT section of the FW file is corrupted.

Signed-off-by: Lior Cohen 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 8 
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 1 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 6243b503d0b0..efd4ac5bba73 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -998,6 +998,14 @@ const struct iwl_fw_dump_desc iwl_dump_desc_assert = {
 };
 IWL_EXPORT_SYMBOL(iwl_dump_desc_assert);
 
+void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt)
+{
+   IWL_INFO(fwrt, "error dump due to fw assert\n");
+   fwrt->dump.desc = _dump_desc_assert;
+   iwl_fw_error_dump(fwrt);
+}
+IWL_EXPORT_SYMBOL(iwl_fw_assert_error_dump);
+
 void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
 {
struct iwl_fw_dump_desc *iwl_dump_desc_no_alive =
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 4a5fa05c7ac2..544b42f9fb19 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -378,6 +378,7 @@ static inline void iwl_fw_resume_timestamp(struct 
iwl_fw_runtime *fwrt) {}
 
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
+void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt);
 void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
 void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
 #endif  /* __iwl_fw_dbg_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index dade206d5511..2cd07247e0a7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -407,6 +407,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, 
bool read_nvm)
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
if (ret) {
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
+   iwl_fw_assert_error_dump(>fwrt);
goto error;
}
 
@@ -1024,6 +1025,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
ret = iwl_mvm_load_rt_fw(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
+   iwl_fw_assert_error_dump(>fwrt);
goto error;
}
 
-- 
2.19.1



[PATCH 13/16] iwlwifi: fw: support API change to debug TLVs

2018-11-11 Thread Luca Coelho
From: Sara Sharon 

A new field was added. Since the code isn't operational (yet) no
need to worry about backward compatibility.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
index 82f3c9bbd9b1..ab82b7a67967 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
@@ -180,6 +180,7 @@ struct iwl_fw_ini_region_tlv {
  * @occurrences: max amount of times to be fired
  * @ignore_consec: ignore consecutive triggers, in usec
  * @force_restart: force FW restart
+ * @multi_dut: initiate debug dump data on several DUTs
  * @trigger_data: generic data to be utilized per trigger
  * @num_regions: number of dump regions defined for this trigger
  * @data: region IDs
@@ -191,6 +192,7 @@ struct iwl_fw_ini_trigger {
__le32 occurrences;
__le32 ignore_consec;
__le32 force_restart;
+   __le32 multi_dut;
__le32 trigger_data;
__le32 num_regions;
__le32 data[];
-- 
2.19.1



[PATCH 04/16] iwlwifi: fix cfg structs for 22000 with different RF modules

2018-11-11 Thread Luca Coelho
From: Luca Coelho 

We have to choose different configuration and different firmwares
depending on the external RF module that is installed.  Since the
external module is not represented in the PCI IDs, we need to change
the configuration at runtime, after checking the RF ID of the module
installed.  We have a bit of a mess in the code that does this,
because it applies cfg's according to the RF ID only, ignoring the
integrated module that is in use.

Fix that for some devices by adding correct configurations for them
and not ignoring the integrated module's type when making the
decision.

Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/cfg/22000.c|  1 -
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c |  2 +-
 .../net/wireless/intel/iwlwifi/pcie/trans.c   | 22 +--
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index da5d5f9b2573..8b2339165bca 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -323,7 +323,6 @@ 
MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 
MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 
MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 8d4711590dfc..353581ccc01e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -882,7 +882,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x34F0, 0x0040, iwl22000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0070, iwl22000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0078, iwl22000_2ax_cfg_hr)},
-   {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl22000_2ac_cfg_jf)},
+   {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl22000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x40C0, 0x, iwl22560_2ax_cfg_su_cdb)},
{IWL_PCI_DEVICE(0x40C0, 0x0010, iwl22560_2ax_cfg_su_cdb)},
{IWL_PCI_DEVICE(0x40c0, 0x0090, iwl22560_2ax_cfg_su_cdb)},
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 16eed9b0f301..231ec8131ee8 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3401,8 +3401,26 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev 
*pdev,
 #if IS_ENABLED(CONFIG_IWLMVM)
trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
 
-   if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
-   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
+   if (cfg == _2ax_cfg_hr) {
+   if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
+   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
+   trans->cfg = _2ax_cfg_hr;
+   } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
+  CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
+   trans->cfg = _2ax_cfg_jf;
+   } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
+  CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) {
+   IWL_ERR(trans, "RF ID HRCDB is not supported\n");
+   ret = -EINVAL;
+   goto out_no_pci;
+   } else {
+   IWL_ERR(trans, "Unrecognized RF ID 0x%08x\n",
+   CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id));
+   ret = -EINVAL;
+   goto out_no_pci;
+   }
+   } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
+  CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
u32 hw_status;
 
hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
-- 
2.19.1



[PATCH 03/16] iwlwifi: mvm: remove assignment of the reciprocal

2018-11-11 Thread Luca Coelho
From: Emmanuel Grumbach 

The firmware stopped looking at this field long ago.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/fw/api/mac.h   | 27 +++
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 12 -
 2 files changed, 10 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
index 1dd23f846fb9..d0b79fb461bf 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
@@ -151,9 +151,9 @@ enum iwl_tsf_id {
  * @beacon_time: beacon transmit time in system time
  * @beacon_tsf: beacon transmit time in TSF
  * @bi: beacon interval in TU
- * @bi_reciprocal: 2^32 / bi
+ * @reserved1: reserved
  * @dtim_interval: dtim transmit time in TU
- * @dtim_reciprocal: 2^32 / dtim_interval
+ * @reserved2: reserved
  * @mcast_qid: queue ID for multicast traffic.
  * NOTE: obsolete from VER2 and on
  * @beacon_template: beacon template ID
@@ -162,9 +162,9 @@ struct iwl_mac_data_ap {
__le32 beacon_time;
__le64 beacon_tsf;
__le32 bi;
-   __le32 bi_reciprocal;
+   __le32 reserved1;
__le32 dtim_interval;
-   __le32 dtim_reciprocal;
+   __le32 reserved2;
__le32 mcast_qid;
__le32 beacon_template;
 } __packed; /* AP_MAC_DATA_API_S_VER_2 */
@@ -174,14 +174,14 @@ struct iwl_mac_data_ap {
  * @beacon_time: beacon transmit time in system time
  * @beacon_tsf: beacon transmit time in TSF
  * @bi: beacon interval in TU
- * @bi_reciprocal: 2^32 / bi
+ * @reserved: reserved
  * @beacon_template: beacon template ID
  */
 struct iwl_mac_data_ibss {
__le32 beacon_time;
__le64 beacon_tsf;
__le32 bi;
-   __le32 bi_reciprocal;
+   __le32 reserved;
__le32 beacon_template;
 } __packed; /* IBSS_MAC_DATA_API_S_VER_1 */
 
@@ -191,9 +191,9 @@ struct iwl_mac_data_ibss {
  * @dtim_time: DTIM arrival time in system time
  * @dtim_tsf: DTIM arrival time in TSF
  * @bi: beacon interval in TU, applicable only when associated
- * @bi_reciprocal: 2^32 / bi , applicable only when associated
+ * @reserved1: reserved
  * @dtim_interval: DTIM interval in TU, applicable only when associated
- * @dtim_reciprocal: 2^32 / dtim_interval , applicable only when associated
+ * @reserved2: reserved
  * @listen_interval: in beacon intervals, applicable only when associated
  * @assoc_id: unique ID assigned by the AP during association
  * @assoc_beacon_arrive_time: TSF of first beacon after association
@@ -203,9 +203,9 @@ struct iwl_mac_data_sta {
__le32 dtim_time;
__le64 dtim_tsf;
__le32 bi;
-   __le32 bi_reciprocal;
+   __le32 reserved1;
__le32 dtim_interval;
-   __le32 dtim_reciprocal;
+   __le32 reserved2;
__le32 listen_interval;
__le32 assoc_id;
__le32 assoc_beacon_arrive_time;
@@ -378,13 +378,6 @@ struct iwl_mac_ctx_cmd {
};
 } __packed; /* MAC_CONTEXT_CMD_API_S_VER_1 */
 
-static inline u32 iwl_mvm_reciprocal(u32 v)
-{
-   if (!v)
-   return 0;
-   return 0x / v;
-}
-
 #define IWL_NONQOS_SEQ_GET 0x1
 #define IWL_NONQOS_SEQ_SET 0x2
 struct iwl_nonqos_seq_query_cmd {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index b9c45a40e251..3b93293d4559 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -767,13 +767,8 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
}
 
ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
-   ctxt_sta->bi_reciprocal =
-   cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
ctxt_sta->dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int *
  vif->bss_conf.dtim_period);
-   ctxt_sta->dtim_reciprocal =
-   cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int *
-  vif->bss_conf.dtim_period));
 
ctxt_sta->listen_interval = cpu_to_le32(mvm->hw->conf.listen_interval);
ctxt_sta->assoc_id = cpu_to_le32(vif->bss_conf.aid);
@@ -832,8 +827,6 @@ static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
 
/* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int);
-   cmd.ibss.bi_reciprocal =
-   cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
 
/* TODO: Assumes that the beacon id == mac context id */
cmd.ibss.beacon_template = cpu_to_le32(mvmvif->id);
@@ -1180,13 +1173,8 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm 
*mvm,
}
 
ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
-   ctxt_ap->

[PATCH 1/5] iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE

2018-11-11 Thread Luca Coelho
From: Matt Chen 

>From coreboot/BIOS:
Name ("WGDS", Package() {
 Revision,
 Package() {
 DomainType, // 0x7:WiFi ==> We miss this one.
 WgdsWiFiSarDeltaGroup1PowerMax1,// Group 1 FCC 2400 Max
 WgdsWiFiSarDeltaGroup1PowerChainA1, // Group 1 FCC 2400 A Offset
 WgdsWiFiSarDeltaGroup1PowerChainB1, // Group 1 FCC 2400 B Offset
 WgdsWiFiSarDeltaGroup1PowerMax2,// Group 1 FCC 5200 Max
 WgdsWiFiSarDeltaGroup1PowerChainA2, // Group 1 FCC 5200 A Offset
 WgdsWiFiSarDeltaGroup1PowerChainB2, // Group 1 FCC 5200 B Offset
 WgdsWiFiSarDeltaGroup2PowerMax1,// Group 2 EC Jap 2400 Max
 WgdsWiFiSarDeltaGroup2PowerChainA1, // Group 2 EC Jap 2400 A Offset
 WgdsWiFiSarDeltaGroup2PowerChainB1, // Group 2 EC Jap 2400 B Offset
 WgdsWiFiSarDeltaGroup2PowerMax2,// Group 2 EC Jap 5200 Max
 WgdsWiFiSarDeltaGroup2PowerChainA2, // Group 2 EC Jap 5200 A Offset
 WgdsWiFiSarDeltaGroup2PowerChainB2, // Group 2 EC Jap 5200 B Offset
 WgdsWiFiSarDeltaGroup3PowerMax1,// Group 3 ROW 2400 Max
 WgdsWiFiSarDeltaGroup3PowerChainA1, // Group 3 ROW 2400 A Offset
 WgdsWiFiSarDeltaGroup3PowerChainB1, // Group 3 ROW 2400 B Offset
 WgdsWiFiSarDeltaGroup3PowerMax2,// Group 3 ROW 5200 Max
 WgdsWiFiSarDeltaGroup3PowerChainA2, // Group 3 ROW 5200 A Offset
 WgdsWiFiSarDeltaGroup3PowerChainB2, // Group 3 ROW 5200 B Offset
 }
})

When read the ACPI data to find out the WGDS, the DATA_SIZE is never
matched.
>From the above format, it gives 19 numbers, but our driver is hardcode
as 18.
Fix it to pass then can parse the data into our wgds table.
Then we will see:
iwlwifi :01:00.0: U iwl_mvm_sar_geo_init Sending GEO_TX_POWER_LIMIT
iwlwifi :01:00.0: U iwl_mvm_sar_geo_init SAR geographic profile[0]
Band[0]: chain A = 68 chain B = 69 max_tx_power = 54
iwlwifi :01:00.0: U iwl_mvm_sar_geo_init SAR geographic profile[0]
Band[1]: chain A = 48 chain B = 49 max_tx_power = 70
iwlwifi :01:00.0: U iwl_mvm_sar_geo_init SAR geographic profile[1]
Band[0]: chain A = 51 chain B = 67 max_tx_power = 50
iwlwifi :01:00.0: U iwl_mvm_sar_geo_init SAR geographic profile[1]
Band[1]: chain A = 69 chain B = 70 max_tx_power = 68
iwlwifi :01:00.0: U iwl_mvm_sar_geo_init SAR geographic profile[2]
Band[0]: chain A = 49 chain B = 50 max_tx_power = 48
iwlwifi :01:00.0: U iwl_mvm_sar_geo_init SAR geographic profile[2]
Band[1]: chain A = 52 chain B = 53 max_tx_power = 51

Cc: sta...@vger.kernel.org # 4.12+
Fixes: a6bff3cb19b7 ("iwlwifi: mvm: add GEO_TX_POWER_LIMIT cmd for geographic 
tx power table")
Signed-off-by: Matt Chen 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 4 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c  | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h 
b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index 2439e98431ee..7492dfb6729b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -6,6 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2017Intel Deutschland GmbH
+ * Copyright(c) 2018Intel Corporation
  *
  * 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
@@ -26,6 +27,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2017Intel Deutschland GmbH
+ * Copyright(c) 2018Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,7 +83,7 @@
 #define ACPI_WRDS_WIFI_DATA_SIZE   (ACPI_SAR_TABLE_SIZE + 2)
 #define ACPI_EWRD_WIFI_DATA_SIZE   ((ACPI_SAR_PROFILE_NUM - 1) * \
 ACPI_SAR_TABLE_SIZE + 3)
-#define ACPI_WGDS_WIFI_DATA_SIZE   18
+#define ACPI_WGDS_WIFI_DATA_SIZE   19
 #define ACPI_WRDD_WIFI_DATA_SIZE   2
 #define ACPI_SPLC_WIFI_DATA_SIZE   2
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index dade206d5511..899f4a6432fb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -893,7 +893,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
IWL_DEBUG_RADIO(mvm, "Sending GEO_TX_POWER_LIMIT\n");
 
BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS *
-ACPI_WGDS_TABLE_SIZE !=  ACPI_WGDS_WIFI_DATA_SIZE);
+ACPI_WGDS_TABLE_SIZE + 1 !=  ACPI_WGDS_WIFI_DATA_SIZE);
 
BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES > IWL_NUM_GEO_PROFILES);
 
-- 
2.19.1



[PATCH 3/5] iwlwifi: mvm: fix regulatory domain update when the firmware starts

2018-11-11 Thread Luca Coelho
From: Emmanuel Grumbach 

When the firmware starts, it doesn't have any regulatory
information, hence it uses the world wide limitations. The
driver can feed the firmware with previous knowledge that
was kept in the driver, but the firmware may still not
update its internal tables.

This happens when we start a BSS interface, and then the
firmware can change the regulatory tables based on our
location and it'll use more lenient, location specific
rules. Then, if the firmware is shut down (when the
interface is brought down), and then an AP interface is
created, the firmware will forget the country specific
rules.

The host will think that we are in a certain country that
may allow channels and will try to teach the firmware about
our location, but the firmware may still not allow to drop
the world wide limitations and apply country specific rules
because it was just re-started.

In this case, the firmware will reply with MCC_RESP_ILLEGAL
to the MCC_UPDATE_CMD. In that case, iwlwifi needs to let
the upper layers (cfg80211 / hostapd) know that the channel
list they know about has been updated.

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

Cc: sta...@vger.kernel.org
Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 8 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c  | 5 ++---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 7c09ce20e8b1..00f831d88366 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -301,8 +301,12 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct 
wiphy *wiphy,
goto out;
}
 
-   if (changed)
-   *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE);
+   if (changed) {
+   u32 status = le32_to_cpu(resp->status);
+
+   *changed = (status == MCC_RESP_NEW_CHAN_PROFILE ||
+   status == MCC_RESP_ILLEGAL);
+   }
 
regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
  __le32_to_cpu(resp->n_channels),
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index 3633f27d048a..6fc5cc1f2b5b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -539,9 +539,8 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
}
 
IWL_DEBUG_LAR(mvm,
- "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') 
change: %d n_chans: %d\n",
- status, mcc, mcc >> 8, mcc & 0xff,
- !!(status == MCC_RESP_NEW_CHAN_PROFILE), n_channels);
+ "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') 
n_chans: %d\n",
+ status, mcc, mcc >> 8, mcc & 0xff, n_channels);
 
 exit:
iwl_free_resp();
-- 
2.19.1



[PATCH 2/5] iwlwifi: mvm: support sta_statistics() even on older firmware

2018-11-11 Thread Luca Coelho
From: Emmanuel Grumbach 

The oldest firmware supported by iwlmvm do support getting
the average beacon RSSI. Enable the sta_statistics() call
from mac80211 even on older firmware versions.

Fixes: 33cef9256342 ("iwlwifi: mvm: support beacon statistics for BSS client")
Cc: sta...@vger.kernel.org # 4.2+
Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 505b0385d800..7c09ce20e8b1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -,10 +,6 @@ static void iwl_mvm_mac_sta_statistics(struct 
ieee80211_hw *hw,
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
}
 
-   if (!fw_has_capa(>fw->ucode_capa,
-IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
-   return;
-
/* if beacon filtering isn't on mac80211 does it anyway */
if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
return;
-- 
2.19.1



[PATCH 0/5] iwlwifi: fixes intended for 4.20 2018-11-11

2018-11-11 Thread Luca Coelho
From: Luca Coelho 

Hi,

This is my first batch of fixes inteded for 4.20.

These are the fixes:

* fix statistics collection with older FWs (was causing issues on userspace);
* fix a problem with regulatory after FW restart (bugzilla fix)
* fix a problem related to SAR with buggy BIOSes;
* fix geographic SAR parsing of ACPI entries;
* fix a memory leak in debug code;

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

Please review.

Cheers,
Luca.


Emmanuel Grumbach (2):
  iwlwifi: mvm: support sta_statistics() even on older firmware
  iwlwifi: mvm: fix regulatory domain update when the firmware starts

Luca Coelho (1):
  iwlwifi: mvm: don't use SAR Geo if basic SAR is not used

Matt Chen (1):
  iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE

Shahar S Matityahu (1):
  iwlwifi: fix D3 debug data buffer memory leak

 drivers/net/wireless/intel/iwlwifi/fw/acpi.h  |  4 ++-
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |  6 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   | 33 ++-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 +++
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c  |  5 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  2 ++
 6 files changed, 42 insertions(+), 20 deletions(-)

-- 
2.19.1



[PATCH 4/5] iwlwifi: fix D3 debug data buffer memory leak

2018-11-11 Thread Luca Coelho
From: Shahar S Matityahu 

If the driver is unloaded when D3 debug data pulling is enabled
but not triggered, it doesn't release the data buffer.

Fix this by adding iwl_fw_runtime_free and calling it from the
relevant places.

Fixes: 2d8c261511ab ("iwlwifi: add d3 debug data support")
Signed-off-by: Shahar S Matityahu 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 6 +-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c| 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h 
b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 6b95d0e75889..2b8b50a77990 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -154,7 +154,11 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, 
struct iwl_trans *trans,
const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
struct dentry *dbgfs_dir);
 
-void iwl_fw_runtime_exit(struct iwl_fw_runtime *fwrt);
+static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
+{
+   kfree(fwrt->dump.d3_debug_data);
+   fwrt->dump.d3_debug_data = NULL;
+}
 
 void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 0e2092526fae..af3fba10abc1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -858,6 +858,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
iwl_mvm_thermal_exit(mvm);
  out_free:
iwl_fw_flush_dump(>fwrt);
+   iwl_fw_runtime_free(>fwrt);
 
if (iwlmvm_mod_params.init_dbg)
return op_mode;
@@ -910,6 +911,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode 
*op_mode)
 
iwl_mvm_tof_clean(mvm);
 
+   iwl_fw_runtime_free(>fwrt);
mutex_destroy(>mutex);
mutex_destroy(>d0i3_suspend_mutex);
 
-- 
2.19.1



[PATCH 5/5] iwlwifi: mvm: don't use SAR Geo if basic SAR is not used

2018-11-11 Thread Luca Coelho
From: Luca Coelho 

We can't use SAR Geo if basic SAR is not enabled, since the SAR Geo
tables define offsets in relation to the basic SAR table in use.

To fix this, make iwl_mvm_sar_init() return one in case WRDS is not
available, so we can skip reading WGDS entirely.

Fixes: a6bff3cb19b7 ("iwlwifi: mvm: add GEO_TX_POWER_LIMIT cmd for geographic 
tx power table")
Cc: sta...@vger.kernel.org # 4.12+
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 31 +++--
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 899f4a6432fb..da9afa6824cb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -954,8 +954,11 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
IWL_DEBUG_RADIO(mvm,
"WRDS SAR BIOS table invalid or unavailable. 
(%d)\n",
ret);
-   /* if not available, don't fail and don't bother with EWRD */
-   return 0;
+   /*
+* If not available, don't fail and don't bother with EWRD.
+* Return 1 to tell that we can't use WGDS either.
+*/
+   return 1;
}
 
ret = iwl_mvm_sar_get_ewrd_table(mvm);
@@ -968,9 +971,13 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
/* choose profile 1 (WRDS) as default for both chains */
ret = iwl_mvm_sar_select_profile(mvm, 1, 1);
 
-   /* if we don't have profile 0 from BIOS, just skip it */
+   /*
+* If we don't have profile 0 from BIOS, just skip it.  This
+* means that SAR Geo will not be enabled either, even if we
+* have other valid profiles.
+*/
if (ret == -ENOENT)
-   return 0;
+   return 1;
 
return ret;
 }
@@ -1168,11 +1175,19 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
 
ret = iwl_mvm_sar_init(mvm);
-   if (ret)
-   goto error;
+   if (ret == 0) {
+   ret = iwl_mvm_sar_geo_init(mvm);
+   } else if (ret > 0 && !iwl_mvm_sar_get_wgds_table(mvm)) {
+   /*
+* If basic SAR is not available, we check for WGDS,
+* which should *not* be available either.  If it is
+* available, issue an error, because we can't use SAR
+* Geo without basic SAR.
+*/
+   IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n");
+   }
 
-   ret = iwl_mvm_sar_geo_init(mvm);
-   if (ret)
+   if (ret < 0)
goto error;
 
iwl_mvm_leds_sync(mvm);
-- 
2.19.1



pull-request: iwlwifi-next 2018-11-11

2018-11-11 Thread Luca Coelho
Hi Kalle,

This is the first batch of patches intended for v4.21.  This includes
only the last patchset I sent.  Usual development work, new PCI IDs and
small fixes and cleanups.  More details about the contents in the tag
description.

I have sent this out before and kbuildbot reported success.

Please let me know if there are any issues.

Cheers,
Luca.


The following changes since commit bb38177cb6c6dc973ad8b88f219742b29f3002f1:

  Merge ath-next from 
git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git (2018-11-09 
17:15:25 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git 
tags/iwlwifi-next-for-kalle-2018-11-11

for you to fetch changes up to 56b657f7f9c07421a4f910b7e2b382184f1ddbc8:

  iwlwifi: fw: use helper to determine whether to dump paging (2018-11-11 
11:06:23 +0200)


First set of iwlwifi patches for 4.21

* PCI IDs for some new 9000-series cards;
* Improve antenna usage on connection problems;
* Some improvements in the debugging code;
* Other clean-ups and small fixes;


Andrei Otcheretianski (1):
  iwlwifi: mvm: Send non offchannel traffic via AP sta

Avraham Stern (2):
  iwlwifi: mvm: switch management tx antenna only on tx failure
  iwlwifi: mvm: toggle tx antenna if tx fails during connection 
establishment

Emmanuel Grumbach (1):
  iwlwifi: mvm: remove unused conversion table

Ihab Zhaika (1):
  iwlwifi: add new cards for 9560, 9462, 9461 and killer series

Johannes Berg (2):
  iwlwifi: mvm: synchronize TID queue removal
  iwlwifi: mvm: remove queue_info_lock

Naftali Goldstein (2):
  iwlwifi: fw: do not set sgi bits for HE connection
  iwlwifi: mvm: add description to a few generic assert numbers

Sara Sharon (4):
  iwlwifi: pcie: don't reset TXQ write pointer
  iwlwifi: dbg: avoid passing trigger around
  iwlwifi: dbg: use helper to check if debug type is set
  iwlwifi: fw: use helper to determine whether to dump paging

Shahar S Matityahu (1):
  iwlwifi: trans: Clear persistence bit when starting the FW

Tova Mussai (1):
  iwlwifi: mvm: enable low latency for soft ap

YueHaibing (1):
  iwlwifi: mvm: remove set but not used variable 'he_phy_data'

 drivers/net/wireless/intel/iwlwifi/fw/dbg.c  | 109 
++--
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h  |  18 +---
 drivers/net/wireless/intel/iwlwifi/fw/runtime.h  |   2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h|   7 ++
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h   |   8 +++
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c  |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c |  14 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c|   7 ++
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c|  27 
+++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |  10 -
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c |  17 +--
 drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c   |   4 
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c|   6 --
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c|   4 +---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 114 
-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h |   4 
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c  |  83 
+-
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c   |  54 
+-
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c|  50 
+++
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c  |  16 --
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c|   3 +--
 21 files changed, 313 insertions(+), 246 deletions(-)


signature.asc
Description: This is a digitally signed message part


[PATCH 12/15] iwlwifi: dbg: use helper to check if debug type is set

2018-11-02 Thread Luca Coelho
From: Sara Sharon 

This enables to incorporate more logic in one place.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 36 ++---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h |  7 +++-
 2 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 310af0d60101..aebdf433b409 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -240,7 +240,7 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
if (!iwl_trans_grab_nic_access(fwrt->trans, ))
return;
 
-   if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_RXF)) {
+   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RXF)) {
/* Pull RXF1 */
iwl_fwrt_dump_rxf(fwrt, dump_data,
  cfg->lmac[0].rxfifo1_size, 0, 0);
@@ -254,7 +254,7 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
  LMAC2_PRPH_OFFSET, 2);
}
 
-   if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_TXF)) {
+   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_TXF)) {
/* Pull TXF data from LMAC1 */
for (i = 0; i < fwrt->smem_cfg.num_txfifo_entries; i++) {
/* Mark the number of TXF we're pulling now */
@@ -279,7 +279,7 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
}
}
 
-   if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_INTERNAL_TXF) &&
+   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_INTERNAL_TXF) &&
fw_has_capa(>fw->ucode_capa,
IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) {
/* Pull UMAC internal TXF data from all TXFs */
@@ -603,7 +603,7 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
u32 fifo_len = 0;
int i;
 
-   if (!(fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_RXF)))
+   if (!iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RXF))
goto dump_txf;
 
/* Count RXF2 size */
@@ -614,7 +614,7 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
ADD_LEN(fifo_len, mem_cfg->lmac[i].rxfifo1_size, hdr_len);
 
 dump_txf:
-   if (!(fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_TXF)))
+   if (!iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_TXF))
goto dump_internal_txf;
 
/* Count TXF sizes */
@@ -627,7 +627,7 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
}
 
 dump_internal_txf:
-   if (!((fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_INTERNAL_TXF)) &&
+   if (!(iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_INTERNAL_TXF) &&
  fw_has_capa(>fw->ucode_capa,
  IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)))
goto out;
@@ -675,22 +675,22 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
 
/* Make room for PRPH registers */
if (!fwrt->trans->cfg->gen2 &&
-   fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_PRPH))
+  iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PRPH))
prph_len += iwl_fw_get_prph_len(fwrt);
 
if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 &&
-   fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_RADIO_REG))
+   iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG))
radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ;
}
 
file_len = sizeof(*dump_file) + fifo_len + prph_len + radio_len;
 
-   if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_DEV_FW_INFO))
+   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_DEV_FW_INFO))
file_len += sizeof(*dump_data) + sizeof(*dump_info);
-   if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM_CFG))
+   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_MEM_CFG))
file_len += sizeof(*dump_data) + sizeof(*dump_smem_cfg);
 
-   if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) {
+   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_MEM)) {
size_t hdr_len = sizeof(*dump_data) +
 sizeof(struct iwl_fw_error_dump_mem);
 
@@ -707,7 +707,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
}
 
/* Make room for fw's virtual image pages, if it exists */
-   if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING) &&
+   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) &&
!fwrt->tra

[PATCH 13/15] iwlwifi: mvm: remove unused conversion table

2018-11-02 Thread Luca Coelho
From: Emmanuel Grumbach 

chanwidths isn't used now in debugfs-vif.c.  Remove it.

Signed-off-by: Emmanuel Grumbach 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
index e9767bbdea1e..33b0af24a537 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
@@ -1441,15 +1441,6 @@ static ssize_t iwl_dbgfs_quota_min_read(struct file 
*file,
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
-static const char * const chanwidths[] = {
-   [NL80211_CHAN_WIDTH_20_NOHT] = "noht",
-   [NL80211_CHAN_WIDTH_20] = "ht20",
-   [NL80211_CHAN_WIDTH_40] = "ht40",
-   [NL80211_CHAN_WIDTH_80] = "vht80",
-   [NL80211_CHAN_WIDTH_80P80] = "vht80p80",
-   [NL80211_CHAN_WIDTH_160] = "vht160",
-};
-
 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
-- 
2.19.1



[PATCH 07/15] iwlwifi: mvm: toggle tx antenna if tx fails during connection establishment

2018-11-02 Thread Luca Coelho
From: Avraham Stern 

If tx fails during connection establishment, try another antenna for
the next tx. This will increase the chance to establish connection if
one of the antennas is blocked.  Note that the antenna is toggled even
when failing to tx data frames since connection establishment may use
EAPOLs for 802.1X authentication/ 4 way handshake.

Signed-off-by: Avraham Stern 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c |  2 +
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h |  4 ++
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c  | 65 +++-
 3 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 79ccc698ad83..e82194836f03 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1768,6 +1768,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
if (iwl_mvm_has_tlc_offload(mvm))
iwl_mvm_rs_add_sta(mvm, mvm_sta);
 
+   iwl_mvm_toggle_tx_ant(mvm, _sta->tx_ant);
+
 update_fw:
ret = iwl_mvm_sta_send_to_fw(mvm, sta, sta_update, sta_flags);
if (ret)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
index de1a0a2d8723..d52cd888f77d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
@@ -397,6 +397,9 @@ struct iwl_mvm_rxq_dup_data {
  * @ptk_pn: per-queue PTK PN data structures
  * @dup_data: per queue duplicate packet detection data
  * @deferred_traffic_tid_map: indication bitmap of deferred traffic per-TID
+ * @tx_ant: the index of the antenna to use for data tx to this station. Only
+ * used during connection establishment (e.g. for the 4 way handshake
+ * exchange).
  *
  * When mac80211 creates a station it reserves some space (hw->sta_data_size)
  * in the structure for use by driver. This structure is placed in that
@@ -439,6 +442,7 @@ struct iwl_mvm_sta {
u8 agg_tids;
u8 sleep_tx_count;
u8 avg_energy;
+   u8 tx_ant;
 };
 
 u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index ac4fa0363942..09cabf336310 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -302,13 +302,30 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct 
sk_buff *skb,
offload_assist));
 }
 
+static u32 iwl_mvm_get_tx_ant(struct iwl_mvm *mvm,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta, __le16 fc)
+{
+   if (info->band == NL80211_BAND_2GHZ &&
+   !iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
+   return mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS;
+
+   if (sta && ieee80211_is_data(fc)) {
+   struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+
+   return BIT(mvmsta->tx_ant) << RATE_MCS_ANT_POS;
+   }
+
+   return BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
+}
+
 static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
   struct ieee80211_tx_info *info,
   struct ieee80211_sta *sta)
 {
int rate_idx;
u8 rate_plcp;
-   u32 rate_flags;
+   u32 rate_flags = 0;
 
/* HT rate doesn't make sense for a non data frame */
WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS,
@@ -332,13 +349,6 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
/* Get PLCP rate for tx_cmd->rate_n_flags */
rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
 
-   if (info->band == NL80211_BAND_2GHZ &&
-   !iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
-   rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS;
-   else
-   rate_flags =
-   BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
-
/* Set CCK flag as needed */
if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
rate_flags |= RATE_MCS_CCK_MSK;
@@ -346,6 +356,14 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
return (u32)rate_plcp | rate_flags;
 }
 
+static u32 iwl_mvm_get_tx_rate_n_flags(struct iwl_mvm *mvm,
+  struct ieee80211_tx_info *info,
+  struct ieee80211_sta *sta, __le16 fc)
+{
+   return iwl_mvm_get_tx_rate(mvm, info, sta) |
+   iwl_mvm_get_tx_ant(mvm, info, sta, fc);
+}
+
 /*
  * Sets the fields in the Tx cmd that are rate related
  */
@@ -373,16 +391,21 @@ void iwl_mvm_set_tx_c

[PATCH 08/15] iwlwifi: pcie: don't reset TXQ write pointer

2018-11-02 Thread Luca Coelho
From: Sara Sharon 

Currently code sets the write pointer when getting the TX queue
allocate response. This causes a redundant interrupt with any actual
change in the pointer. Remove this write altogether.

Fixes: 310181ec34e2 ("iwlwifi: move to TVQM mode")
Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index e880f69eac26..0c5f11d2c5da 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -1228,8 +1228,7 @@ int iwl_trans_pcie_txq_alloc_response(struct iwl_trans 
*trans,
/* Place first TFD at index corresponding to start sequence number */
txq->read_ptr = wr_ptr;
txq->write_ptr = wr_ptr;
-   iwl_write_direct32(trans, HBUS_TARG_WRPTR,
-  (txq->write_ptr) | (qid << 16));
+
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);
 
iwl_free_resp(hcmd);
-- 
2.19.1



[PATCH 05/15] iwlwifi: mvm: switch management tx antenna only on tx failure

2018-11-02 Thread Luca Coelho
From: Avraham Stern 

Switch the antenna used for management tx only if previous tx failed.
If previous tx succeeded, there is no reason to switch antennas.

Signed-off-by: Avraham Stern 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 7 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  | 5 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  | 2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 4 +---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 8 
 5 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 6486cfb33f40..b9c45a40e251 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -965,11 +965,8 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
tx->tx_flags = cpu_to_le32(tx_flags);
 
if (!fw_has_capa(>fw->ucode_capa,
-IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION)) {
-   mvm->mgmt_last_antenna_idx =
-   iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
-mvm->mgmt_last_antenna_idx);
-   }
+IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION))
+   iwl_mvm_toggle_tx_ant(mvm, >mgmt_last_antenna_idx);
 
tx->rate_n_flags =
cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 03fdc8b1892d..707bc7d1f37f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1522,6 +1522,11 @@ static inline u8 iwl_mvm_get_valid_rx_ant(struct iwl_mvm 
*mvm)
   mvm->fw->valid_rx_ant;
 }
 
+static inline void iwl_mvm_toggle_tx_ant(struct iwl_mvm *mvm, u8 *ant)
+{
+   *ant = iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm), *ant);
+}
+
 static inline u32 iwl_mvm_get_phy_config(struct iwl_mvm *mvm)
 {
u32 phy_config = ~(FW_PHY_CFG_TX_CHAIN |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 758aa1f75ca1..0d5b55ed8dda 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -845,6 +845,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
 
iwl_mvm_tof_init(mvm);
 
+   iwl_mvm_toggle_tx_ant(mvm, >mgmt_last_antenna_idx);
+
return op_mode;
 
  out_unregister:
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index cfb784fea77b..cb376e869144 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -205,9 +205,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum 
nl80211_band band,
 {
u32 tx_ant;
 
-   mvm->scan_last_antenna_idx =
-   iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
-mvm->scan_last_antenna_idx);
+   iwl_mvm_toggle_tx_ant(mvm, >scan_last_antenna_idx);
tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
 
if (band == NL80211_BAND_2GHZ && !no_cck)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 320453f51ec7..ac4fa0363942 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -381,10 +381,6 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct 
iwl_tx_cmd *tx_cmd,
cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR);
}
 
-   mvm->mgmt_last_antenna_idx =
-   iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
-mvm->mgmt_last_antenna_idx);
-
/* Set the rate in the TX cmd */
tx_cmd->rate_n_flags = cpu_to_le32(iwl_mvm_get_tx_rate(mvm, info, sta));
 }
@@ -1501,6 +1497,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
break;
}
 
+   if ((status & TX_STATUS_MSK) != TX_STATUS_SUCCESS &&
+   ieee80211_is_mgmt(hdr->frame_control))
+   iwl_mvm_toggle_tx_ant(mvm, >mgmt_last_antenna_idx);
+
/*
 * If we are freeing multiple frames, mark all the frames
 * but the first one as acked, since they were acknowledged
-- 
2.19.1



[PATCH 01/15] iwlwifi: mvm: synchronize TID queue removal

2018-11-02 Thread Luca Coelho
From: Johannes Berg 

When we mark a TID as no longer having a queue, there's no
guarantee the TX path isn't using this txq_id right now,
having accessed it just before we reset the value. To fix
this, add synchronize_net() when we change the TIDs from
having a queue to not having one, so that we can then be
sure that the TX path is no longer accessing that queue.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 1887d2b9f185..c2b7bb5d107c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -545,6 +545,16 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm 
*mvm, int queue)
 
rcu_read_unlock();
 
+   /*
+* The TX path may have been using this TXQ_ID from the tid_data,
+* so make sure it's no longer running so that we can safely reuse
+* this TXQ later. We've set all the TIDs to IWL_MVM_INVALID_QUEUE
+* above, but nothing guarantees we've stopped using them. Thus,
+* without this, we could get to iwl_mvm_disable_txq() and remove
+* the queue while still sending frames to it.
+*/
+   synchronize_net();
+
return disable_agg_tids;
 }
 
-- 
2.19.1



[PATCH 06/15] iwlwifi: fw: do not set sgi bits for HE connection

2018-11-02 Thread Luca Coelho
From: Naftali Goldstein 

If the association supports HE, HT/VHT rates will never be used for Tx
and therefore there's no need to set the sgi-per-channel-width-support
bits, so don't set them in this case.

Fixes: 110b32f065f3 ("iwlwifi: mvm: rs: add basic implementation of the new RS 
API handlers")
Signed-off-by: Naftali Goldstein 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
index 7a98e1a1dc40..dabbc04853ac 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
@@ -98,8 +98,12 @@ static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta)
 {
struct ieee80211_sta_ht_cap *ht_cap = >ht_cap;
struct ieee80211_sta_vht_cap *vht_cap = >vht_cap;
+   struct ieee80211_sta_he_cap *he_cap = >he_cap;
u8 supp = 0;
 
+   if (he_cap && he_cap->has_he)
+   return 0;
+
if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
supp |= BIT(IWL_TLC_MNG_CH_WIDTH_20MHZ);
if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
-- 
2.19.1



[PATCH 00/15] iwlwifi: updates intended for v4.21 2018-11-02

2018-11-02 Thread Luca Coelho
From: Luca Coelho 

Hi,

Here's the first set of patches intended for v4.21.  It's the usual
development, with some small new feauters, cleanups and bugfixes.

The changes are:

* PCI IDs for some new 9000-series cards;
* Improve antenna usage on connection problems;
* Some improvements in the debugging code;
* Other clean-ups and small fixes;

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

Please review.

Cheers,
Luca.


Andrei Otcheretianski (1):
  iwlwifi: mvm: Send non offchannel traffic via AP sta

Avraham Stern (2):
  iwlwifi: mvm: switch management tx antenna only on tx failure
  iwlwifi: mvm: toggle tx antenna if tx fails during connection
establishment

Emmanuel Grumbach (1):
  iwlwifi: mvm: remove unused conversion table

Ihab Zhaika (1):
  iwlwifi: add new cards for 9560, 9462, 9461 and killer series

Johannes Berg (2):
  iwlwifi: mvm: synchronize TID queue removal
  iwlwifi: mvm: remove queue_info_lock

Naftali Goldstein (2):
  iwlwifi: fw: do not set sgi bits for HE connection
  iwlwifi: mvm: add description to a few generic assert numbers

Sara Sharon (4):
  iwlwifi: pcie: don't reset TXQ write pointer
  iwlwifi: dbg: avoid passing trigger around
  iwlwifi: dbg: use helper to check if debug type is set
  iwlwifi: fw: use helper to determine whether to dump paging

Shahar S Matityahu (1):
  iwlwifi: trans: Clear persistence bit when starting the FW

Tova Mussai (1):
  iwlwifi: mvm: enable low latency for soft ap

 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 109 +
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |  18 ++-
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |   2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h |   7 ++
 .../net/wireless/intel/iwlwifi/iwl-trans.h|   8 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   |   2 +-
 .../wireless/intel/iwlwifi/mvm/debugfs-vif.c  |  14 +--
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |   7 +-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |  27 +
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  10 +-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  17 +--
 .../net/wireless/intel/iwlwifi/mvm/rs-fw.c|   4 +
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c |   4 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 114 --
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h  |   4 +
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   |  83 +
 .../net/wireless/intel/iwlwifi/mvm/utils.c|  54 +
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c |  50 
 .../net/wireless/intel/iwlwifi/pcie/trans.c   |  16 ++-
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c |   3 +-
 20 files changed, 313 insertions(+), 240 deletions(-)

-- 
2.19.1



[PATCH 09/15] iwlwifi: dbg: avoid passing trigger around

2018-11-02 Thread Luca Coelho
From: Sara Sharon 

The trigger structure is being passed around, when
all we care about is whether to dump only monitor
or not. Pass a bool instead.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 20 +--
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |  3 +--
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |  2 +-
 .../net/wireless/intel/iwlwifi/iwl-trans.h|  8 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  2 +-
 .../net/wireless/intel/iwlwifi/pcie/trans.c   |  4 ++--
 7 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index c16757051f16..310af0d60101 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -655,13 +655,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->cfg->smem_len;
u32 sram2_len = fwrt->fw->dbg.n_mem_tlv ?
0 : fwrt->trans->cfg->dccm2_len;
-   bool monitor_dump_only = false;
int i;
 
-   if (fwrt->dump.trig &&
-   fwrt->dump.trig->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY)
-   monitor_dump_only = true;
-
/* SRAM - include stack CCM if driver knows the values for it */
if (!fwrt->trans->cfg->dccm_offset || !fwrt->trans->cfg->dccm_len) {
const struct fw_img *img;
@@ -727,7 +722,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
}
 
/* If we only want a monitor dump, reset the file length */
-   if (monitor_dump_only) {
+   if (fwrt->dump.monitor_only) {
file_len = sizeof(*dump_file) + sizeof(*dump_data) * 2 +
   sizeof(*dump_info) + sizeof(*dump_smem_cfg);
}
@@ -817,7 +812,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
}
 
/* In case we only want monitor dump, skip to dump trasport data */
-   if (monitor_dump_only)
+   if (fwrt->dump.monitor_only)
goto out;
 
if (fwrt->fw->dbg.dump_mask & BIT(IWL_FW_ERROR_DUMP_MEM)) {
@@ -932,7 +927,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
}
 
fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans,
-  fwrt->dump.trig);
+  fwrt->dump.monitor_only);
file_len = le32_to_cpu(dump_file->file_len);
fw_error_dump->fwrt_len = file_len;
if (fw_error_dump->trans_ptr) {
@@ -998,7 +993,8 @@ void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
 IWL_EXPORT_SYMBOL(iwl_fw_alive_error_dump);
 
 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
-   const struct iwl_fw_dump_desc *desc, void *trigger,
+   const struct iwl_fw_dump_desc *desc,
+   bool monitor_only,
unsigned int delay)
 {
/*
@@ -1028,7 +1024,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
 le32_to_cpu(desc->trig_desc.type));
 
fwrt->dump.desc = desc;
-   fwrt->dump.trig = trigger;
+   fwrt->dump.monitor_only = monitor_only;
 
schedule_delayed_work(>dump.wk, delay);
 
@@ -1043,6 +1039,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
 {
struct iwl_fw_dump_desc *desc;
unsigned int delay = 0;
+   bool monitor_only = false;
 
if (trigger) {
u16 occurrences = le16_to_cpu(trigger->occurrences) - 1;
@@ -1059,6 +1056,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
 
trigger->occurrences = cpu_to_le16(occurrences);
delay = le16_to_cpu(trigger->trig_dis_ms);
+   monitor_only = trigger->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY;
}
 
desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
@@ -1070,7 +1068,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
desc->trig_desc.type = cpu_to_le32(trig);
memcpy(desc->trig_desc.data, str, len);
 
-   return iwl_fw_dbg_collect_desc(fwrt, desc, trigger, delay);
+   return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 6f8d3256f7b0..b56d787ffc1e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -101,13 +101,12 @@ static inline void iwl_fw_free_dump_desc(struct 
iwl_fw_runtime *fwrt)
if (fwrt->dump.desc != _dump_desc_assert)
kfree

[PATCH 11/15] iwlwifi: mvm: Send non offchannel traffic via AP sta

2018-11-02 Thread Luca Coelho
From: Andrei Otcheretianski 

TDLS discovery response frame is a unicast direct frame to the peer.
Since we don't have a STA for this peer, this frame goes through
iwl_tx_skb_non_sta(). As the result aux_sta and some completely
arbitrary queue would be selected for this frame, resulting in a queue
hang.  Fix that by sending such frames through AP sta instead.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 5bdc638fc999..55b965629e33 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -809,6 +809,21 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
!ieee80211_is_bufferable_mmpdu(hdr->frame_control))
sta = NULL;
 
+   /* If there is no sta, and it's not offchannel - send through AP */
+   if (info->control.vif->type == NL80211_IFTYPE_STATION &&
+   info->hw_queue != IWL_MVM_OFFCHANNEL_QUEUE && !sta) {
+   struct iwl_mvm_vif *mvmvif =
+   iwl_mvm_vif_from_mac80211(info->control.vif);
+   u8 ap_sta_id = READ_ONCE(mvmvif->ap_sta_id);
+
+   if (ap_sta_id < IWL_MVM_STATION_COUNT) {
+   /* mac80211 holds rcu read lock */
+   sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]);
+   if (IS_ERR_OR_NULL(sta))
+   goto drop;
+   }
+   }
+
if (sta) {
if (iwl_mvm_defer_tx(mvm, sta, skb))
return;
-- 
2.19.1



[PATCH 15/15] iwlwifi: fw: use helper to determine whether to dump paging

2018-11-02 Thread Luca Coelho
From: Sara Sharon 

Logic is there twice, and we'll need a third place
soon for ini dumping. In addition move the dumping
to a function, also to enable reuse.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 57 +++--
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h |  8 +++
 2 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index aebdf433b409..58a980070445 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -639,6 +639,32 @@ static int iwl_fw_fifo_len(struct iwl_fw_runtime *fwrt,
return fifo_len;
 }
 
+static void iwl_dump_paging(struct iwl_fw_runtime *fwrt,
+   struct iwl_fw_error_dump_data **data)
+{
+   int i;
+
+   IWL_DEBUG_INFO(fwrt, "WRT paging dump\n");
+   for (i = 1; i < fwrt->num_of_paging_blk + 1; i++) {
+   struct iwl_fw_error_dump_paging *paging;
+   struct page *pages =
+   fwrt->fw_paging_db[i].fw_paging_block;
+   dma_addr_t addr = fwrt->fw_paging_db[i].fw_paging_phys;
+
+   (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING);
+   (*data)->len = cpu_to_le32(sizeof(*paging) +
+PAGING_BLOCK_SIZE);
+   paging =  (void *)(*data)->data;
+   paging->index = cpu_to_le32(i);
+   dma_sync_single_for_cpu(fwrt->trans->dev, addr,
+   PAGING_BLOCK_SIZE,
+   DMA_BIDIRECTIONAL);
+   memcpy(paging->data, page_address(pages),
+  PAGING_BLOCK_SIZE);
+   (*data) = iwl_fw_error_next_data(*data);
+   }
+}
+
 static struct iwl_fw_error_dump_file *
 _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
   struct iwl_fw_dump_ptrs *fw_error_dump)
@@ -707,10 +733,7 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
}
 
/* Make room for fw's virtual image pages, if it exists */
-   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) &&
-   !fwrt->trans->cfg->gen2 &&
-   fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
-   fwrt->fw_paging_db[0].fw_paging_block)
+   if (iwl_fw_dbg_is_paging_enabled(fwrt))
file_len += fwrt->num_of_paging_blk *
(sizeof(*dump_data) +
 sizeof(struct iwl_fw_error_dump_paging) +
@@ -860,30 +883,8 @@ _iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
}
 
/* Dump fw's virtual image */
-   if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) &&
-   !fwrt->trans->cfg->gen2 &&
-   fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
-   fwrt->fw_paging_db[0].fw_paging_block) {
-   IWL_DEBUG_INFO(fwrt, "WRT paging dump\n");
-   for (i = 1; i < fwrt->num_of_paging_blk + 1; i++) {
-   struct iwl_fw_error_dump_paging *paging;
-   struct page *pages =
-   fwrt->fw_paging_db[i].fw_paging_block;
-   dma_addr_t addr = fwrt->fw_paging_db[i].fw_paging_phys;
-
-   dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING);
-   dump_data->len = cpu_to_le32(sizeof(*paging) +
-PAGING_BLOCK_SIZE);
-   paging = (void *)dump_data->data;
-   paging->index = cpu_to_le32(i);
-   dma_sync_single_for_cpu(fwrt->trans->dev, addr,
-   PAGING_BLOCK_SIZE,
-   DMA_BIDIRECTIONAL);
-   memcpy(paging->data, page_address(pages),
-  PAGING_BLOCK_SIZE);
-   dump_data = iwl_fw_error_next_data(dump_data);
-   }
-   }
+   if (iwl_fw_dbg_is_paging_enabled(fwrt))
+   iwl_dump_paging(fwrt, _data);
 
if (prph_len) {
iwl_dump_prph(fwrt->trans, _data,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 0d5169c4cf51..4a5fa05c7ac2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -322,6 +322,14 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct 
iwl_fw_runtime *fwrt)
iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);
 }
 
+static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt)
+{
+   return iwl_fw_dbg_type_

[PATCH 14/15] iwlwifi: add new cards for 9560, 9462, 9461 and killer series

2018-11-02 Thread Luca Coelho
From: Ihab Zhaika 

add few PCI ID'S for 9560, 9462, 9461 and killer series.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 9e015212c2c0..8d4711590dfc 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -513,6 +513,56 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)},
 
 /* 9000 Series */
+   {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x00A4, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0230, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x02A4, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x1552, iwl9560_killer_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x2030, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x2034, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x4030, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x4034, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x40A4, iwl9462_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x4234, iwl9560_2ac_cfg_soc)},
+   {IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_cfg)},
{IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_cfg)},
{IWL_PCI_DEVICE(0x2526, 0x0018, iwl9260_2ac_cfg)},
-- 
2.19.1



[PATCH 10/15] iwlwifi: mvm: add description to a few generic assert numbers

2018-11-02 Thread Luca Coelho
From: Naftali Goldstein 

FW asserts 0x70, 0x71, and 0x73 all just mean that the real error
happened in another MAC, and to look there for the problem. Add their
descriptions to the assert number lookup table so users get a nicer
error message in the logs.
Also, since the 4 most-significant bits of the assert number are
dynamic, and depend on which MAC the assert occurred on, ignore those
bits when looking up the assert name.

Signed-off-by: Naftali Goldstein 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 3fd673128d51..3761fbfff292 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -285,6 +285,7 @@ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 
last_idx)
return last_idx;
 }
 
+#define FW_SYSASSERT_CPU_MASK 0xf000
 static const struct {
const char *name;
u8 num;
@@ -301,6 +302,9 @@ static const struct {
{ "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
{ "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
{ "NMI_INTERRUPT_HOST", 0x66 },
+   { "NMI_INTERRUPT_LMAC_FATAL", 0x70 },
+   { "NMI_INTERRUPT_UMAC_FATAL", 0x71 },
+   { "NMI_INTERRUPT_OTHER_LMAC_FATAL", 0x73 },
{ "NMI_INTERRUPT_ACTION_PT", 0x7C },
{ "NMI_INTERRUPT_UNKNOWN", 0x84 },
{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
@@ -312,7 +316,7 @@ static const char *desc_lookup(u32 num)
int i;
 
for (i = 0; i < ARRAY_SIZE(advanced_lookup) - 1; i++)
-   if (advanced_lookup[i].num == num)
+   if (advanced_lookup[i].num == (num & ~FW_SYSASSERT_CPU_MASK))
return advanced_lookup[i].name;
 
/* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
-- 
2.19.1



[PATCH 04/15] iwlwifi: mvm: enable low latency for soft ap

2018-11-02 Thread Luca Coelho
From: Tova Mussai 

Enable low latency for softAP in all modes (standalone, SCM
and DCM).
This is in order to minimize the time the softAP leaves the channel for
other operations

Signed-off-by: Tova Mussai 
Signed-off-by: Luca Coelho 
---
 .../wireless/intel/iwlwifi/mvm/debugfs-vif.c  |  5 ++-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 ++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  4 ++
 .../net/wireless/intel/iwlwifi/mvm/utils.c| 42 +++
 4 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
index 1aa6c7e93088..e9767bbdea1e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
@@ -1299,10 +1299,11 @@ static ssize_t iwl_dbgfs_low_latency_read(struct file 
*file,
int len;
 
len = scnprintf(buf, sizeof(buf) - 1,
-   "traffic=%d\ndbgfs=%d\nvcmd=%d\n",
+   "traffic=%d\ndbgfs=%d\nvcmd=%d\nvif_type=%d\n",
!!(mvmvif->low_latency & LOW_LATENCY_TRAFFIC),
!!(mvmvif->low_latency & LOW_LATENCY_DEBUGFS),
-   !!(mvmvif->low_latency & LOW_LATENCY_VCMD));
+   !!(mvmvif->low_latency & LOW_LATENCY_VCMD),
+   !!(mvmvif->low_latency & LOW_LATENCY_VIF_TYPE));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 505b0385d800..5bdc638fc999 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2379,6 +2379,12 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
/* must be set before quota calculations */
mvmvif->ap_ibss_active = true;
 
+   if (vif->type == NL80211_IFTYPE_AP && !vif->p2p) {
+   iwl_mvm_vif_set_low_latency(mvmvif, true,
+   LOW_LATENCY_VIF_TYPE);
+   iwl_mvm_send_low_latency_cmd(mvm, true, mvmvif->id);
+   }
+
/* power updated needs to be done before quotas */
iwl_mvm_power_update_mac(mvm);
 
@@ -2441,6 +2447,12 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
mvmvif->ap_ibss_active = false;
mvm->ap_last_beacon_gp2 = 0;
 
+   if (vif->type == NL80211_IFTYPE_AP && !vif->p2p) {
+   iwl_mvm_vif_set_low_latency(mvmvif, false,
+   LOW_LATENCY_VIF_TYPE);
+   iwl_mvm_send_low_latency_cmd(mvm, false,  mvmvif->id);
+   }
+
iwl_mvm_bt_coex_vif_change(mvm);
 
iwl_mvm_unref(mvm, IWL_MVM_REF_AP_IBSS);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 8a933774a934..03fdc8b1892d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -303,11 +303,13 @@ enum iwl_bt_force_ant_mode {
 * @LOW_LATENCY_TRAFFIC: indicates low latency traffic was detected
 * @LOW_LATENCY_DEBUGFS: low latency mode set from debugfs
 * @LOW_LATENCY_VCMD: low latency mode set from vendor command
+* @LOW_LATENCY_VIF_TYPE: low latency mode set because of vif type (ap)
 */
 enum iwl_mvm_low_latency_cause {
LOW_LATENCY_TRAFFIC = BIT(0),
LOW_LATENCY_DEBUGFS = BIT(1),
LOW_LATENCY_VCMD = BIT(2),
+   LOW_LATENCY_VIF_TYPE = BIT(3),
 };
 
 /**
@@ -1845,6 +1847,8 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, 
struct ieee80211_vif *vif,
 /* get SystemLowLatencyMode - only needed for beacon threshold? */
 bool iwl_mvm_low_latency(struct iwl_mvm *mvm);
 bool iwl_mvm_low_latency_band(struct iwl_mvm *mvm, enum nl80211_band band);
+void iwl_mvm_send_low_latency_cmd(struct iwl_mvm *mvm, bool low_latency,
+ u16 mac_id);
 
 /* get VMACLowLatencyMode */
 static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 11730d018e20..3fd673128d51 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -764,6 +764,29 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
return result;
 }
 
+void iwl_mvm_send_low_latency_cmd(struct iwl_mvm *mvm,
+ bool low_latency, u16 mac_id)
+{
+   struct iwl_mac_low_latency_cmd cmd = {
+   .mac_id = cpu_to_le32(mac_id)
+   };
+
+   if (!fw_has_capa(>fw->ucode_capa,
+IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA))
+   return;
+
+   if (low_latency) {

[PATCH 02/15] iwlwifi: mvm: remove queue_info_lock

2018-11-02 Thread Luca Coelho
From: Johannes Berg 

All the queue management code runs under mvm->mutex, so there are
only very few cases of accessing the data structures without it:
 * TX path, which doesn't take any locks anyway
 * iwl_mvm_wake_sw_queue() and iwl_mvm_stop_sw_queue() where we
   just (atomically) read a bitmap, so the lock isn't needed.

Therefore, we can remove the spinlock. This enables some cleanup
in the ugly locking in iwl_mvm_inactivity_check().

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   1 -
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  13 +--
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 102 ++
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   |  10 +-
 .../net/wireless/intel/iwlwifi/mvm/utils.c|   6 +-
 5 files changed, 19 insertions(+), 113 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 7ba5bc2ed1c4..8a933774a934 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -844,7 +844,6 @@ struct iwl_mvm {
u16 hw_queue_to_mac80211[IWL_MAX_TVQM_QUEUES];
 
struct iwl_mvm_dqa_txq_info queue_info[IWL_MAX_HW_QUEUES];
-   spinlock_t queue_info_lock; /* For syncing queue mgmt operations */
struct work_struct add_stream_wk; /* To add streams to queues */
 
atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES];
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 0e2092526fae..758aa1f75ca1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -676,7 +676,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
INIT_LIST_HEAD(>aux_roc_te_list);
INIT_LIST_HEAD(>async_handlers_list);
spin_lock_init(>time_event_lock);
-   spin_lock_init(>queue_info_lock);
 
INIT_WORK(>async_handlers_wk, iwl_mvm_async_handlers_wk);
INIT_WORK(>roc_done_wk, iwl_mvm_roc_done_wk);
@@ -1108,11 +1107,7 @@ static void iwl_mvm_async_cb(struct iwl_op_mode *op_mode,
 static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int hw_queue)
 {
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-   unsigned long mq;
-
-   spin_lock_bh(>queue_info_lock);
-   mq = mvm->hw_queue_to_mac80211[hw_queue];
-   spin_unlock_bh(>queue_info_lock);
+   unsigned long mq = mvm->hw_queue_to_mac80211[hw_queue];
 
iwl_mvm_stop_mac_queues(mvm, mq);
 }
@@ -1138,11 +1133,7 @@ void iwl_mvm_start_mac_queues(struct iwl_mvm *mvm, 
unsigned long mq)
 static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int hw_queue)
 {
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-   unsigned long mq;
-
-   spin_lock_bh(>queue_info_lock);
-   mq = mvm->hw_queue_to_mac80211[hw_queue];
-   spin_unlock_bh(>queue_info_lock);
+   unsigned long mq = mvm->hw_queue_to_mac80211[hw_queue];
 
iwl_mvm_start_mac_queues(mvm, mq);
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index c2b7bb5d107c..79ccc698ad83 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -319,9 +319,7 @@ static int iwl_mvm_invalidate_sta_queue(struct iwl_mvm 
*mvm, int queue,
if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
return -EINVAL;
 
-   spin_lock_bh(>queue_info_lock);
sta_id = mvm->queue_info[queue].ra_sta_id;
-   spin_unlock_bh(>queue_info_lock);
 
rcu_read_lock();
 
@@ -372,25 +370,17 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int 
queue,
return -EINVAL;
 
if (iwl_mvm_has_new_tx_api(mvm)) {
-   spin_lock_bh(>queue_info_lock);
-
if (remove_mac_queue)
mvm->hw_queue_to_mac80211[queue] &=
~BIT(mac80211_queue);
 
-   spin_unlock_bh(>queue_info_lock);
-
iwl_trans_txq_free(mvm->trans, queue);
 
return 0;
}
 
-   spin_lock_bh(>queue_info_lock);
-
-   if (WARN_ON(mvm->queue_info[queue].tid_bitmap == 0)) {
-   spin_unlock_bh(>queue_info_lock);
+   if (WARN_ON(mvm->queue_info[queue].tid_bitmap == 0))
return 0;
-   }
 
mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
 
@@ -426,10 +416,8 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int 
queue,
mvm->hw_queue_to_mac80211[queue]);
 
/* If the queue is still enabled - nothing left to do in this func */
-   if (cmd.action == SCD_CFG_ENABLE_QUEUE) {
-   spin_unlock_bh(>queue_info_lock);
+   if (cmd.action == SCD_CFG

[PATCH 03/15] iwlwifi: trans: Clear persistence bit when starting the FW

2018-11-02 Thread Luca Coelho
From: Shahar S Matityahu 

In D3 suspend flow in 9260 gen2 HW, the NIC receives two PERST signals.
The first PERST is expected and indicates the device on coming resume flow.
The second PERST causes FW restart FW restart.
In order to avoid this issue, the FW set the persistence bit on.
Once this bit is set, the FW ignores reset attempts.
The problem is when the FW gets assert during D3 and then the persistence
bit is set and causes the FW to ignore reset.
To handle this issue, the FW opens the preg bit which allows access
to the persistence bit, so that the driver clear the persistence bit
and reset the NIC.

The flow is as follows:
the driver checks if the persistence bit is set.
If the bit is set, the driver checks if he can clear the bit.
If the driver can not clear the bit then there is no point to continue
configuring the NIC since it will fail.

The fix was added is in start HW flow instead of the resume flow since in
general, if the persistence bit is set, the driver can not start the FW.
So it is good to check it when we start configuring the NIC.

The driver does not need to close the preg bit since the FW close it
during the start flow.

Signed-off-by: Shahar S Matityahu 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h   |  7 +++
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 12 
 2 files changed, 19 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 0f51c7bea8d0..2084c63dc670 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -8,6 +8,7 @@
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2016Intel Deutschland GmbH
+ * Copyright (C) 2018 Intel Corporation
  *
  * 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
@@ -30,6 +31,7 @@
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2016Intel Deutschland GmbH
+ * Copyright (C) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -394,6 +396,7 @@ enum aux_misc_master1_en {
 #define AUX_MISC_MASTER1_SMPHR_STATUS  0xA20800
 #define RSA_ENABLE 0xA24B08
 #define PREG_AUX_BUS_WPROT_0   0xA04CC0
+#define PREG_PRPH_WPROT_0  0xA04CE0
 #define SB_CPU_1_STATUS0xA01E30
 #define SB_CPU_2_STATUS0xA01E34
 #define UMAG_SB_CPU_1_STATUS   0xA038C0
@@ -420,4 +423,8 @@ enum {
 #define UREG_CHICK (0xA05C00)
 #define UREG_CHICK_MSI_ENABLE  BIT(24)
 #define UREG_CHICK_MSIX_ENABLE BIT(25)
+
+#define HPM_DEBUG  0xA03440
+#define PERSISTENCE_BITBIT(12)
+#define PREG_WFPM_ACCESS   BIT(12)
 #endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 5bafb3f46eb8..890b51b223a1 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1729,6 +1729,7 @@ static int iwl_pcie_init_msix_handler(struct pci_dev 
*pdev,
 static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
 {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+   u32 hpm;
int err;
 
lockdep_assert_held(_pcie->mutex);
@@ -1739,6 +1740,17 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans 
*trans, bool low_power)
return err;
}
 
+   hpm = iwl_trans_read_prph(trans, HPM_DEBUG);
+   if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) {
+   if (iwl_trans_read_prph(trans, PREG_PRPH_WPROT_0) &
+   PREG_WFPM_ACCESS) {
+   IWL_ERR(trans,
+   "Error, can not clear persistence bit\n");
+   return -EPERM;
+   }
+   iwl_trans_write_prph(trans, HPM_DEBUG, hpm & ~PERSISTENCE_BIT);
+   }
+
iwl_trans_pcie_sw_reset(trans);
 
err = iwl_pcie_apm_init(trans);
-- 
2.19.1



Re: iwlwifi firmware

2018-11-02 Thread Luca Coelho
Hi Michael,

On Fri, 2018-11-02 at 09:47 +0100, Michael Köbberich wrote:
> Sehr geehrtes Intel Team
> 
> Ich bin auf der Suche nach Firmware für einen Axxiv FIN NUC DH17012,
> genauer gesagt dessen WIFI Karte. Sind die Treiber:
> 
> iwlwifi-8000C-26.ucode
> iwlwifi-8000C-25.ucode
> iwlwifi-8000C-24.ucode
> iwlwifi-8000C-23.ucode
> iwlwifi-8000C-22.ucode
> iwlwifi-8000C-21.ucode
> iwlwifi-8000C-20.ucode
> iwlwifi-8000C-19.ucode
> iwlwifi-8000C-18.ucode
> iwlwifi-8000C-17.ucode
> 
> bei Ihnen erhältlich?

I sort of understood what you wrote in German, but excuse me for
replying in English.

All our public firmwares are available here:

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


Not all versions supported by the driver are released publicly, so you
may get some warnings about missing files, but they are not mandatory,
the driver only needs one of them (and chooses the highest version
available).  So if you're seeing messages about missing firmwares, but
your card works anyway, you can ignore them.

HTH.

--
Cheers,
Luca.



Re: [PATCH] Minor corrections of comments in the iwlwifi mvm rate scaling source

2018-10-17 Thread Luca Coelho
On Thu, 2018-09-13 at 13:07 +0200, Rémy Grünblatt wrote:
> Hi,
> 
> I believe some comments in the rate scaling source of the iwlwifi mvm
> are wrong, as we have #define RATE_MCS_SGI_POS  13 and #define
> RATE_MCS_SGI_MSK  (1 << RATE_MCS_SGI_POS)

Hi Remy,

Sorry for the delay, your patch was not correctly formatted and since
this is a minor fix in a comment, it slipped through my fingers.

I have made a different patch to fix this, changing the hex values for
the tables instead, because in the example we say this is about SGI, so
I just set the SGI bit:

- * rate[0] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
- * rate[1] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
- * rate[2] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
- * rate[3] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
- * rate[4] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
- * rate[5] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
+ * rate[0] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
+ * rate[1] 0x400F019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
+ * rate[2] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
+ * rate[3] 0x400F018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
+ * rate[4] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
+ * rate[5] 0x400F017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI


This is now queued in our internal tree and will reach the mainline at
some point, following our normal process.

Thanks for reporting.

--
Cheers,
Luca.



[PATCH] iwlwifi: mvm: check return value of rs_rate_from_ucode_rate()

2018-10-13 Thread Luca Coelho
From: Luca Coelho 

The rs_rate_from_ucode_rate() function may return -EINVAL if the rate
is invalid, but none of the callsites check for the error, potentially
making us access arrays with index IWL_RATE_INVALID, which is larger
than the arrays, causing an out-of-bounds access.  This will trigger
KASAN warnings, such as the one reported in the bugzilla issue
mentioned below.

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

Cc: sta...@vger.kernel.org
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 24 -
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 2c75f51a04e4..089972280daa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1239,7 +1239,11 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct 
ieee80211_sta *sta,
!(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
 
-   rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, _resp_rate);
+   if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,
+   _resp_rate)) {
+   WARN_ON_ONCE(1);
+   return;
+   }
 
 #ifdef CONFIG_MAC80211_DEBUGFS
/* Disable last tx check if we are debugging with fixed rate but
@@ -1290,7 +1294,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct 
ieee80211_sta *sta,
 */
table = _sta->lq;
lq_hwrate = le32_to_cpu(table->rs_table[0]);
-   rs_rate_from_ucode_rate(lq_hwrate, info->band, _rate);
+   if (rs_rate_from_ucode_rate(lq_hwrate, info->band, _rate)) {
+   WARN_ON_ONCE(1);
+   return;
+   }
 
/* Here we actually compare this rate to the latest LQ command */
if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
@@ -1392,8 +1399,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct 
ieee80211_sta *sta,
/* Collect data for each rate used during failed TX attempts */
for (i = 0; i <= retries; ++i) {
lq_hwrate = le32_to_cpu(table->rs_table[i]);
-   rs_rate_from_ucode_rate(lq_hwrate, info->band,
-   _rate);
+   if (rs_rate_from_ucode_rate(lq_hwrate, info->band,
+   _rate)) {
+   WARN_ON_ONCE(1);
+   return;
+   }
+
/*
 * Only collect stats if retried rate is in the same RS
 * table as active/search.
@@ -3260,7 +3271,10 @@ static void rs_build_rates_table_from_fixed(struct 
iwl_mvm *mvm,
for (i = 0; i < num_rates; i++)
lq_cmd->rs_table[i] = ucode_rate_le32;
 
-   rs_rate_from_ucode_rate(ucode_rate, band, );
+   if (rs_rate_from_ucode_rate(ucode_rate, band, )) {
+   WARN_ON_ONCE(1);
+   return;
+   }
 
if (is_mimo())
lq_cmd->mimo_delim = num_rates - 1;
-- 
2.19.1



pull-request: iwlwifi-next 2018-10-12

2018-10-12 Thread Luca Coelho
Hi Kalle,

This is the fourth batch of patches intended for v4.20.  This includes
only the last patchset I sent.  Usual development work, mostly queue
handling cleanups.  More details about the contents in the tag
description.

I have sent this out before and kbuildbot reported success.

Please let me know if there are any issues.

Cheers,
Luca.


The following changes since commit abf1a08ff3237a27188ff8cc2904f2cea893af55:

  net: vhost: remove bad code line (2018-10-07 21:31:32 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git 
tags/iwlwifi-next-for-kalle-2018-10-12

for you to fetch changes up to 724fe7710ac5f4289886b90060ed67e3a4bdd584:

  iwlwifi: mvm: kill INACTIVE queue state (2018-10-08 10:49:22 +0300)


Fourth set of iwlwifi patches intended for 4.20

* Support for a new scan type;
* Clean-up in the queue handling code;
* A few bug fixes;


Ayala Beker (2):
  iwlwifi: mvm: introduce a new fragmented scan type: fast balance
  iwlwifi: mvm: use fast balance scan in case of DCM mode with P2P GO

Johannes Berg (11):
  iwlwifi: mvm: give TX queue info struct a name
  iwlwifi: mvm: move queue management into sta.c
  iwlwifi: mvm: remove per-queue hw refcount
  iwlwifi: mvm: clean up iteration in iwl_mvm_inactivity_check()
  iwlwifi: mvm: move queue reconfiguration into new function
  iwlwifi: mvm: reconfigure queues during inactivity check
  iwlwifi: mvm: remove RECONFIGURING queue state
  iwlwifi: mvm: make queue TID change more explicit
  iwlwifi: mvm: make iwl_mvm_scd_queue_redirect() static
  iwlwifi: mvm: move iwl_mvm_sta_alloc_queue() down
  iwlwifi: mvm: kill INACTIVE queue state

Sara Sharon (3):
  iwlwifi: mvm: don't send keys when entering D3
  iwlwifi: pcie: don't pad AMSDU packets
  iwlwifi: trace: change trace to trace one TB at a time

Shahar S Matityahu (2):
  iwlwifi: dump debug data before stop device
  iwlwifi: mvm: move rt status check to the start of the resume flow

 drivers/net/wireless/intel/iwlwifi/fw/dbg.c|  27 +++-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h|   1 +
 drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h |  30 +---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c|  64 +---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c|   9 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |  54 +++
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c  | 115 +
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c   | 837 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h   |   8 -
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c|  34 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 420 
+---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  |  28 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   |  29 ++--
 13 files changed, 825 insertions(+), 831 deletions(-)


signature.asc
Description: This is a digitally signed message part


[PATCH 17/18] iwlwifi: mvm: move iwl_mvm_sta_alloc_queue() down

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

We want to call iwl_mvm_inactivity_check() from here in the
next patch, so need to move the code down to be able to.

Fix a minor checkpatch complaint while at it.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 410 +--
 1 file changed, 205 insertions(+), 205 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 24631866a174..8ae4fbf17f03 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -936,211 +936,6 @@ static bool iwl_mvm_enable_txq(struct iwl_mvm *mvm, int 
queue,
return inc_ssn;
 }
 
-static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
-  struct ieee80211_sta *sta, u8 ac, int tid,
-  struct ieee80211_hdr *hdr)
-{
-   struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
-   struct iwl_trans_txq_scd_cfg cfg = {
-   .fifo = iwl_mvm_mac_ac_to_tx_fifo(mvm, ac),
-   .sta_id = mvmsta->sta_id,
-   .tid = tid,
-   .frame_limit = IWL_FRAME_LIMIT,
-   };
-   unsigned int wdg_timeout =
-   iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false);
-   u8 mac_queue = mvmsta->vif->hw_queue[ac];
-   int queue = -1;
-   bool using_inactive_queue = false, same_sta = false;
-   unsigned long disable_agg_tids = 0;
-   enum iwl_mvm_agg_state queue_state;
-   bool shared_queue = false, inc_ssn;
-   int ssn;
-   unsigned long tfd_queue_mask;
-   int ret;
-
-   lockdep_assert_held(>mutex);
-
-   if (iwl_mvm_has_new_tx_api(mvm))
-   return iwl_mvm_sta_alloc_queue_tvqm(mvm, sta, ac, tid);
-
-   spin_lock_bh(>lock);
-   tfd_queue_mask = mvmsta->tfd_queue_msk;
-   spin_unlock_bh(>lock);
-
-   spin_lock_bh(>queue_info_lock);
-
-   /*
-* Non-QoS, QoS NDP and MGMT frames should go to a MGMT queue, if one
-* exists
-*/
-   if (!ieee80211_is_data_qos(hdr->frame_control) ||
-   ieee80211_is_qos_nullfunc(hdr->frame_control)) {
-   queue = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
-   IWL_MVM_DQA_MIN_MGMT_QUEUE,
-   IWL_MVM_DQA_MAX_MGMT_QUEUE);
-   if (queue >= IWL_MVM_DQA_MIN_MGMT_QUEUE)
-   IWL_DEBUG_TX_QUEUES(mvm, "Found free MGMT queue #%d\n",
-   queue);
-
-   /* If no such queue is found, we'll use a DATA queue instead */
-   }
-
-   if ((queue < 0 && mvmsta->reserved_queue != IEEE80211_INVAL_HW_QUEUE) &&
-   (mvm->queue_info[mvmsta->reserved_queue].status ==
-IWL_MVM_QUEUE_RESERVED ||
-mvm->queue_info[mvmsta->reserved_queue].status ==
-IWL_MVM_QUEUE_INACTIVE)) {
-   queue = mvmsta->reserved_queue;
-   mvm->queue_info[queue].reserved = true;
-   IWL_DEBUG_TX_QUEUES(mvm, "Using reserved queue #%d\n", queue);
-   }
-
-   if (queue < 0)
-   queue = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
-   IWL_MVM_DQA_MIN_DATA_QUEUE,
-   IWL_MVM_DQA_MAX_DATA_QUEUE);
-
-   /*
-* Check if this queue is already allocated but inactive.
-* In such a case, we'll need to first free this queue before enabling
-* it again, so we'll mark it as reserved to make sure no new traffic
-* arrives on it
-*/
-   if (queue > 0 &&
-   mvm->queue_info[queue].status == IWL_MVM_QUEUE_INACTIVE) {
-   mvm->queue_info[queue].status = IWL_MVM_QUEUE_RESERVED;
-   using_inactive_queue = true;
-   same_sta = mvm->queue_info[queue].ra_sta_id == mvmsta->sta_id;
-   IWL_DEBUG_TX_QUEUES(mvm,
-   "Re-assigning TXQ %d: sta_id=%d, tid=%d\n",
-   queue, mvmsta->sta_id, tid);
-   }
-
-   /* No free queue - we'll have to share */
-   if (queue <= 0) {
-   queue = iwl_mvm_get_shared_queue(mvm, tfd_queue_mask, ac);
-   if (queue > 0) {
-   shared_queue = true;
-   mvm->queue_info[queue].status = IWL_MVM_QUEUE_SHARED;
-   }
-   }
-
-   /*
-* Mark TXQ as ready, even though it hasn't been fully configured yet,
-* to make sure no one else takes it.
-* This will allow avoiding re-acquiring the lock at the end of the
-* configuration. On error we'll mark it back as fre

[PATCH 18/18] iwlwifi: mvm: kill INACTIVE queue state

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

We don't really need this state: instead of having an inactive
state where we can awaken zombie queues again if needed, just
keep them in their normal state unless a new queue is actually
needed and there's no other way of getting one.

We do this here by making the inactivity check not free queues
unless instructed that we now really need to allocate one to a
specific station, and in that case it'll just free the queue
immediately, without doing any inactivity step inbetween.

The only downside is a little bit more processing in this case,
but the code complexity is lower.

Additionally, this fixes a corner case: due to the way the code
worked, we could only ever reuse an inactive queue if it was
the reserved queue for a station, as iwl_mvm_find_free_queue()
would never consider returning an inactive queue.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |   7 -
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 136 ---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h |   4 -
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c  |  34 ++---
 4 files changed, 66 insertions(+), 115 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 8cbd9468aa8b..7ba5bc2ed1c4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -754,19 +754,12 @@ iwl_mvm_baid_data_from_reorder_buf(struct 
iwl_mvm_reorder_buffer *buf)
  * This is a state in which a single queue serves more than one TID, all of
  * which are not aggregated. Note that the queue is only associated to one
  * RA.
- * @IWL_MVM_QUEUE_INACTIVE: queue is allocated but no traffic on it
- * This is a state of a queue that has had traffic on it, but during the
- * last %IWL_MVM_DQA_QUEUE_TIMEOUT time period there has been no traffic on
- * it. In this state, when a new queue is needed to be allocated but no
- * such free queue exists, an inactive queue might be freed and given to
- * the new RA/TID.
  */
 enum iwl_mvm_queue_status {
IWL_MVM_QUEUE_FREE,
IWL_MVM_QUEUE_RESERVED,
IWL_MVM_QUEUE_READY,
IWL_MVM_QUEUE_SHARED,
-   IWL_MVM_QUEUE_INACTIVE,
 };
 
 #define IWL_MVM_DQA_QUEUE_TIMEOUT  (5 * HZ)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 8ae4fbf17f03..1887d2b9f185 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -549,11 +549,12 @@ static int iwl_mvm_remove_sta_queue_marking(struct 
iwl_mvm *mvm, int queue)
 }
 
 static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue,
-  bool same_sta)
+  u8 new_sta_id)
 {
struct iwl_mvm_sta *mvmsta;
u8 txq_curr_ac, sta_id, tid;
unsigned long disable_agg_tids = 0;
+   bool same_sta;
int ret;
 
lockdep_assert_held(>mutex);
@@ -567,6 +568,8 @@ static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, 
int queue,
tid = mvm->queue_info[queue].txq_tid;
spin_unlock_bh(>queue_info_lock);
 
+   same_sta = sta_id == new_sta_id;
+
mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
if (WARN_ON(!mvmsta))
return -EINVAL;
@@ -581,10 +584,6 @@ static int iwl_mvm_free_inactive_queue(struct iwl_mvm 
*mvm, int queue,
  mvmsta->vif->hw_queue[txq_curr_ac],
  tid, 0);
if (ret) {
-   /* Re-mark the inactive queue as inactive */
-   spin_lock_bh(>queue_info_lock);
-   mvm->queue_info[queue].status = IWL_MVM_QUEUE_INACTIVE;
-   spin_unlock_bh(>queue_info_lock);
IWL_ERR(mvm,
"Failed to free inactive queue %d (ret=%d)\n",
queue, ret);
@@ -844,7 +843,6 @@ static int iwl_mvm_sta_alloc_queue_tvqm(struct iwl_mvm *mvm,
 
spin_lock_bh(>lock);
mvmsta->tid_data[tid].txq_id = queue;
-   mvmsta->tid_data[tid].is_tid_active = true;
spin_unlock_bh(>lock);
 
return 0;
@@ -1063,8 +1061,10 @@ static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, 
int queue)
  * Remove inactive TIDs of a given queue.
  * If all queue TIDs are inactive - mark the queue as inactive
  * If only some the queue TIDs are inactive - unmap them from the queue
+ *
+ * Returns %true if all TIDs were removed and the queue could be reused.
  */
-static void iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
+static bool iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
 struct iwl_mvm_sta *mvmsta, int queue,
 unsigned long tid_bitmap,

[PATCH 14/18] iwlwifi: mvm: remove RECONFIGURING queue state

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

We set the queue to this state, only to pretty much immediately
move it out of it again. However, we can't even hit any of the
code that checks if the queue is reconfiguring, because all of
this happens under mvm->mutex and we hold the all the way from
marking the queue as RECONFIGURING to marking it as READY again.

Additionally, the queue that became RECONFIGURING would've been
in SHARED state before, and it can safely stay in that state. In
case of errors, it previously would have stayed in RECONFIGURING
which it could never have left again.

Remove the state entirely and just track the queues that need to
be reconfigured in a separate, local, bitmap.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |  5 ---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 36 
 2 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 7074fd1f8ce7..8cbd9468aa8b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -760,10 +760,6 @@ iwl_mvm_baid_data_from_reorder_buf(struct 
iwl_mvm_reorder_buffer *buf)
  * it. In this state, when a new queue is needed to be allocated but no
  * such free queue exists, an inactive queue might be freed and given to
  * the new RA/TID.
- * @IWL_MVM_QUEUE_RECONFIGURING: queue is being reconfigured
- * This is the state of a queue that has had traffic pass through it, but
- * needs to be reconfigured for some reason, e.g. the queue needs to
- * become unshared and aggregations re-enabled on.
  */
 enum iwl_mvm_queue_status {
IWL_MVM_QUEUE_FREE,
@@ -771,7 +767,6 @@ enum iwl_mvm_queue_status {
IWL_MVM_QUEUE_READY,
IWL_MVM_QUEUE_SHARED,
IWL_MVM_QUEUE_INACTIVE,
-   IWL_MVM_QUEUE_RECONFIGURING,
 };
 
 #define IWL_MVM_DQA_QUEUE_TIMEOUT  (5 * HZ)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 8a0cf736122a..b30980c34fd0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -606,7 +606,13 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm,
u8 ac_to_queue[IEEE80211_NUM_ACS];
int i;
 
+   /*
+* This protects us against grabbing a queue that's being reconfigured
+* by the inactivity checker.
+*/
+   lockdep_assert_held(>mutex);
lockdep_assert_held(>queue_info_lock);
+
if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
return -EINVAL;
 
@@ -619,11 +625,6 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm,
i != IWL_MVM_DQA_BSS_CLIENT_QUEUE)
continue;
 
-   /* Don't try and take queues being reconfigured */
-   if (mvm->queue_info[queue].status ==
-   IWL_MVM_QUEUE_RECONFIGURING)
-   continue;
-
ac_to_queue[mvm->queue_info[i].mac80211_ac] = i;
}
 
@@ -664,14 +665,6 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm,
return -ENOSPC;
}
 
-   /* Make sure the queue isn't in the middle of being reconfigured */
-   if (mvm->queue_info[queue].status == IWL_MVM_QUEUE_RECONFIGURING) {
-   IWL_ERR(mvm,
-   "TXQ %d is in the middle of re-config - try again\n",
-   queue);
-   return -EBUSY;
-   }
-
return queue;
 }
 
@@ -1278,7 +1271,8 @@ static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, 
int queue)
  */
 static void iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
 struct iwl_mvm_sta *mvmsta, int queue,
-unsigned long tid_bitmap)
+unsigned long tid_bitmap,
+unsigned long *unshare_queues)
 {
int tid;
 
@@ -1345,19 +1339,17 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm 
*mvm,
/* If the queue is marked as shared - "unshare" it */
if (hweight16(mvm->queue_info[queue].tid_bitmap) == 1 &&
mvm->queue_info[queue].status == IWL_MVM_QUEUE_SHARED) {
-   mvm->queue_info[queue].status = IWL_MVM_QUEUE_RECONFIGURING;
IWL_DEBUG_TX_QUEUES(mvm, "Marking Q:%d for reconfig\n",
queue);
+   set_bit(queue, unshare_queues);
}
 }
 
 static void iwl_mvm_reconfigure_queue(struct iwl_mvm *mvm, int queue)
 {
-   bool reconfig;
bool change_owner;
 
spin_lock_bh(>queue_info_lock);
-   reconfig = mvm->queue_info[queue].status == IWL_MVM_QUEUE_RECONFIGURING;
 
/*
 * We need t

[PATCH 04/18] iwlwifi: mvm: introduce a new fragmented scan type: fast balance

2018-10-08 Thread Luca Coelho
From: Ayala Beker 

Fast balance scan is similar to SCAN_TYPE_MILD, but this scan is
fragmented and has shorter out of operating channel time,
and therefore better match low latency scenarios.

Signed-off-by: Ayala Beker 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 24 +--
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 8f71eeed50d9..6f927052aeaf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -512,6 +512,7 @@ enum iwl_mvm_scan_type {
IWL_SCAN_TYPE_WILD,
IWL_SCAN_TYPE_MILD,
IWL_SCAN_TYPE_FRAGMENTED,
+   IWL_SCAN_TYPE_FAST_BALANCE,
 };
 
 enum iwl_mvm_sched_scan_pass_all_states {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index ffcd0ca86041..b43bf116c7e8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -110,6 +110,10 @@ static struct iwl_mvm_scan_timing_params scan_timing[] = {
.suspend_time = 95,
.max_out_time = 44,
},
+   [IWL_SCAN_TYPE_FAST_BALANCE] = {
+   .suspend_time = 30,
+   .max_out_time = 37,
+   },
 };
 
 struct iwl_mvm_scan_params {
@@ -860,6 +864,12 @@ static inline bool iwl_mvm_is_regular_scan(struct 
iwl_mvm_scan_params *params)
params->scan_plans[0].iterations == 1;
 }
 
+static bool iwl_mvm_is_scan_fragmented(enum iwl_mvm_scan_type type)
+{
+   return (type == IWL_SCAN_TYPE_FRAGMENTED ||
+   type == IWL_SCAN_TYPE_FAST_BALANCE);
+}
+
 static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
   struct iwl_mvm_scan_params *params,
   struct ieee80211_vif *vif)
@@ -872,7 +882,7 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
 
-   if (params->type == IWL_SCAN_TYPE_FRAGMENTED)
+   if (iwl_mvm_is_scan_fragmented(params->type))
flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED;
 
if (iwl_mvm_rrm_scan_needed(mvm) &&
@@ -895,7 +905,7 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
 
if (iwl_mvm_is_regular_scan(params) &&
vif->type != NL80211_IFTYPE_P2P_DEVICE &&
-   params->type != IWL_SCAN_TYPE_FRAGMENTED)
+   !iwl_mvm_is_scan_fragmented(params->type))
flags |= IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL;
 
return flags;
@@ -1162,7 +1172,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
 SCAN_CONFIG_FLAG_SET_MAC_ADDR |
 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS |
 SCAN_CONFIG_N_CHANNELS(num_channels) |
-(type == IWL_SCAN_TYPE_FRAGMENTED ?
+(iwl_mvm_is_scan_fragmented(type) ?
  SCAN_CONFIG_FLAG_SET_FRAGMENTED :
  SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED);
 
@@ -1177,7 +1187,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
 */
if (iwl_mvm_cdb_scan_api(mvm)) {
if (iwl_mvm_is_cdb_supported(mvm))
-   flags |= (hb_type == IWL_SCAN_TYPE_FRAGMENTED) ?
+   flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ?
 SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED :
 SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED;
iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags);
@@ -1338,11 +1348,11 @@ static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm,
if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
flags |= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT;
 
-   if (params->type == IWL_SCAN_TYPE_FRAGMENTED)
+   if (iwl_mvm_is_scan_fragmented(params->type))
flags |= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED;
 
if (iwl_mvm_is_cdb_supported(mvm) &&
-   params->hb_type == IWL_SCAN_TYPE_FRAGMENTED)
+   iwl_mvm_is_scan_fragmented(params->hb_type))
flags |= IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED;
 
if (iwl_mvm_rrm_scan_needed(mvm) &&
@@ -1380,7 +1390,7 @@ static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm,
 */
if (iwl_mvm_is_regular_scan(params) &&
vif->type != NL80211_IFTYPE_P2P_DEVICE &&
-   params->type != IWL_SCAN_TYPE_FRAGMENTED &&
+   !iwl_mvm_is_scan_fragmented(params->type) &&
!iwl_mvm_is_adaptive_dwell_supported(mvm) &&
!iwl_mvm_is_oce_supported(mvm))
flags |= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL;
-- 
2.19.0



[PATCH 03/18] iwlwifi: trace: change trace to trace one TB at a time

2018-10-08 Thread Luca Coelho
From: Sara Sharon 

Split TX tracing to be per TB. This is needed now that
AMSDUs can be sent and skb can be larger than trace
limit.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 .../intel/iwlwifi/iwl-devtrace-data.h | 30 ---
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 18 ++-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  | 29 ++
 3 files changed, 34 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
index 2cc6c019d0e1..420e6d745f77 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
@@ -30,38 +30,20 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi_data
 
-TRACE_EVENT(iwlwifi_dev_tx_data,
-   TP_PROTO(const struct device *dev,
-struct sk_buff *skb, u8 hdr_len),
-   TP_ARGS(dev, skb, hdr_len),
+TRACE_EVENT(iwlwifi_dev_tx_tb,
+   TP_PROTO(const struct device *dev, struct sk_buff *skb,
+u8 *data_src, size_t data_len),
+   TP_ARGS(dev, skb, data_src, data_len),
TP_STRUCT__entry(
DEV_ENTRY
 
__dynamic_array(u8, data,
-   iwl_trace_data(skb) ? skb->len - hdr_len : 0)
+   iwl_trace_data(skb) ? data_len : 0)
),
TP_fast_assign(
DEV_ASSIGN;
if (iwl_trace_data(skb))
-   skb_copy_bits(skb, hdr_len,
- __get_dynamic_array(data),
- skb->len - hdr_len);
-   ),
-   TP_printk("[%s] TX frame data", __get_str(dev))
-);
-
-TRACE_EVENT(iwlwifi_dev_tx_tso_chunk,
-   TP_PROTO(const struct device *dev,
-u8 *data_src, size_t data_len),
-   TP_ARGS(dev, data_src, data_len),
-   TP_STRUCT__entry(
-   DEV_ENTRY
-
-   __dynamic_array(u8, data, data_len)
-   ),
-   TP_fast_assign(
-   DEV_ASSIGN;
-   memcpy(__get_dynamic_array(data), data_src, data_len);
+   memcpy(__get_dynamic_array(data), data_src, data_len);
),
TP_printk("[%s] TX frame data", __get_str(dev))
 );
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 09cdc15f7645..e880f69eac26 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -330,7 +330,7 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans 
*trans,
goto out_err;
}
iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len);
-   trace_iwlwifi_dev_tx_tso_chunk(trans->dev, start_hdr, tb_len);
+   trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr, tb_len);
/* add this subframe's headers' length to the tx_cmd */
le16_add_cpu(_cmd->len, hdr_page->pos - subf_hdrs_start);
 
@@ -347,8 +347,8 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans 
*trans,
goto out_err;
}
iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len);
-   trace_iwlwifi_dev_tx_tso_chunk(trans->dev, tso.data,
-  tb_len);
+   trace_iwlwifi_dev_tx_tb(trans->dev, skb, tso.data,
+   tb_len);
 
data_left -= tb_len;
tso_build_data(skb, , tb_len);
@@ -438,6 +438,9 @@ static int iwl_pcie_gen2_tx_add_frags(struct iwl_trans 
*trans,
return -ENOMEM;
tb_idx = iwl_pcie_gen2_set_tb(trans, tfd, tb_phys,
  skb_frag_size(frag));
+   trace_iwlwifi_dev_tx_tb(trans->dev, skb,
+   skb_frag_address(frag),
+   skb_frag_size(frag));
if (tb_idx < 0)
return tb_idx;
 
@@ -490,6 +493,8 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans,
if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
goto out_err;
iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb1_len);
+   trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), _cmd->hdr,
+IWL_FIRST_TB_SIZE + tb1_len, hdr_len);
 
/* set up TFD's third entry to point to remainder of skb's head */
tb2_len = skb_headlen(skb) - hdr_len;
@@ -500,15 +505,14 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans 
*trans,
if (unlikely(dma_mapping_error(trans->dev, tb_phys)))
goto out_err;
   

[PATCH 10/18] iwlwifi: mvm: remove per-queue hw refcount

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

There's no need to have a hw refcount if we just mark the
command queue with a (fake) TID; at that point, the refcount
becomes equivalent to the hweight() of the TID bitmap.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  9 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  1 -
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 41 +--
 .../net/wireless/intel/iwlwifi/mvm/utils.c|  2 +-
 4 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index c5df73231ba3..dade206d5511 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -364,7 +364,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm 
*mvm,
 */
 
memset(>queue_info, 0, sizeof(mvm->queue_info));
-   mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].hw_queue_refcount = 1;
+   /*
+* Set a 'fake' TID for the command queue, since we use the
+* hweight() of the tid_bitmap as a refcount now. Not that
+* we ever even consider the command queue as one we might
+* want to reuse, but be safe nevertheless.
+*/
+   mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].tid_bitmap =
+   BIT(IWL_MAX_TID_COUNT + 2);
 
for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
atomic_set(>mac80211_queue_stop_count[i], 0);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index f5a532dc712d..7074fd1f8ce7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -789,7 +789,6 @@ struct iwl_mvm_geo_profile {
 };
 
 struct iwl_mvm_dqa_txq_info {
-   u8 hw_queue_refcount;
u8 ra_sta_id; /* The RA this queue is mapped to, if exists */
bool reserved; /* Is this the TXQ reserved for a STA */
u8 mac80211_ac; /* The mac80211 AC this queue is mapped to */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index fd33b8d148b3..ce03f9750c3a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -387,7 +387,7 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int 
queue,
 
spin_lock_bh(>queue_info_lock);
 
-   if (WARN_ON(mvm->queue_info[queue].hw_queue_refcount == 0)) {
+   if (WARN_ON(mvm->queue_info[queue].tid_bitmap == 0)) {
spin_unlock_bh(>queue_info_lock);
return 0;
}
@@ -413,17 +413,16 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int 
queue,
if (remove_mac_queue)
mvm->hw_queue_to_mac80211[queue] &=
~BIT(mac80211_queue);
-   mvm->queue_info[queue].hw_queue_refcount--;
 
-   cmd.action = mvm->queue_info[queue].hw_queue_refcount ?
+   cmd.action = mvm->queue_info[queue].tid_bitmap ?
SCD_CFG_ENABLE_QUEUE : SCD_CFG_DISABLE_QUEUE;
if (cmd.action == SCD_CFG_DISABLE_QUEUE)
mvm->queue_info[queue].status = IWL_MVM_QUEUE_FREE;
 
IWL_DEBUG_TX_QUEUES(mvm,
-   "Disabling TXQ #%d refcount=%d (mac80211 
map:0x%x)\n",
+   "Disabling TXQ #%d tids=0x%x (mac80211 map:0x%x)\n",
queue,
-   mvm->queue_info[queue].hw_queue_refcount,
+   mvm->queue_info[queue].tid_bitmap,
mvm->hw_queue_to_mac80211[queue]);
 
/* If the queue is still enabled - nothing left to do in this func */
@@ -436,16 +435,13 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int 
queue,
cmd.tid = mvm->queue_info[queue].txq_tid;
 
/* Make sure queue info is correct even though we overwrite it */
-   WARN(mvm->queue_info[queue].hw_queue_refcount ||
-mvm->queue_info[queue].tid_bitmap ||
-mvm->hw_queue_to_mac80211[queue],
-"TXQ #%d info out-of-sync - refcount=%d, mac map=0x%x, tid=0x%x\n",
-queue, mvm->queue_info[queue].hw_queue_refcount,
+   WARN(mvm->queue_info[queue].tid_bitmap ||
 mvm->hw_queue_to_mac80211[queue],
+"TXQ #%d info out-of-sync - mac map=0x%x, tids=0x%x\n",
+queue, mvm->hw_queue_to_mac80211[queue],
 mvm->queue_info[queue].tid_bitmap);
 
/* If we are here - the queue is freed and we can zero out these vals */
-   mvm->queue_info[queue].hw_queue_refcount = 0;
mvm->queue_info[queue].tid_bitmap = 0;
mvm->hw_queue_to_mac80211[queue] = 0;
 
@@ -722,7 +718,7 @@ int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int 
queue, int 

[PATCH 09/18] iwlwifi: mvm: move queue management into sta.c

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

None of these functions really need to be separate, they're all
only used in sta.c, move them there and make them static.

Fix a small typo in related code while at it.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  13 -
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 409 +
 .../net/wireless/intel/iwlwifi/mvm/utils.c| 418 --
 3 files changed, 409 insertions(+), 431 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index cff58ed35fbe..f5a532dc712d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1886,17 +1886,6 @@ void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif 
*mvmvif, bool set,
mvmvif->low_latency &= ~cause;
 }
 
-/* hw scheduler queue config */
-bool iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
-   u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg,
-   unsigned int wdg_timeout);
-int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue,
-   u8 sta_id, u8 tid, unsigned int timeout);
-
-int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
-   u8 tid, u8 flags);
-int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq);
-
 /* Return a bitmask with all the hw supported queues, except for the
  * command queue, which can't be flushed.
  */
@@ -1998,8 +1987,6 @@ void iwl_mvm_reorder_timer_expired(struct timer_list *t);
 struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
 bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm);
 
-void iwl_mvm_inactivity_check(struct iwl_mvm *mvm);
-
 #define MVM_TCM_PERIOD_MSEC 500
 #define MVM_TCM_PERIOD (HZ * MVM_TCM_PERIOD_MSEC / 1000)
 #define MVM_LL_PERIOD (10 * HZ)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 8f929c774e70..fd33b8d148b3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -358,6 +358,112 @@ static int iwl_mvm_invalidate_sta_queue(struct iwl_mvm 
*mvm, int queue,
return ret;
 }
 
+static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue,
+  int mac80211_queue, u8 tid, u8 flags)
+{
+   struct iwl_scd_txq_cfg_cmd cmd = {
+   .scd_queue = queue,
+   .action = SCD_CFG_DISABLE_QUEUE,
+   };
+   bool remove_mac_queue = mac80211_queue != IEEE80211_INVAL_HW_QUEUE;
+   int ret;
+
+   if (WARN_ON(remove_mac_queue && mac80211_queue >= IEEE80211_MAX_QUEUES))
+   return -EINVAL;
+
+   if (iwl_mvm_has_new_tx_api(mvm)) {
+   spin_lock_bh(>queue_info_lock);
+
+   if (remove_mac_queue)
+   mvm->hw_queue_to_mac80211[queue] &=
+   ~BIT(mac80211_queue);
+
+   spin_unlock_bh(>queue_info_lock);
+
+   iwl_trans_txq_free(mvm->trans, queue);
+
+   return 0;
+   }
+
+   spin_lock_bh(>queue_info_lock);
+
+   if (WARN_ON(mvm->queue_info[queue].hw_queue_refcount == 0)) {
+   spin_unlock_bh(>queue_info_lock);
+   return 0;
+   }
+
+   mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
+
+   /*
+* If there is another TID with the same AC - don't remove the MAC queue
+* from the mapping
+*/
+   if (tid < IWL_MAX_TID_COUNT) {
+   unsigned long tid_bitmap =
+   mvm->queue_info[queue].tid_bitmap;
+   int ac = tid_to_mac80211_ac[tid];
+   int i;
+
+   for_each_set_bit(i, _bitmap, IWL_MAX_TID_COUNT) {
+   if (tid_to_mac80211_ac[i] == ac)
+   remove_mac_queue = false;
+   }
+   }
+
+   if (remove_mac_queue)
+   mvm->hw_queue_to_mac80211[queue] &=
+   ~BIT(mac80211_queue);
+   mvm->queue_info[queue].hw_queue_refcount--;
+
+   cmd.action = mvm->queue_info[queue].hw_queue_refcount ?
+   SCD_CFG_ENABLE_QUEUE : SCD_CFG_DISABLE_QUEUE;
+   if (cmd.action == SCD_CFG_DISABLE_QUEUE)
+   mvm->queue_info[queue].status = IWL_MVM_QUEUE_FREE;
+
+   IWL_DEBUG_TX_QUEUES(mvm,
+   "Disabling TXQ #%d refcount=%d (mac80211 
map:0x%x)\n",
+   queue,
+   mvm->queue_info[queue].hw_queue_refcount,
+   mvm->hw_queue_to_mac80211[queue]);
+
+   /* If the queue is still enabled - nothing left to do in this func */
+   if (cmd.action == SCD_CFG_ENABLE_QUEUE) {
+   spin_unl

[PATCH 02/18] iwlwifi: pcie: don't pad AMSDU packets

2018-10-08 Thread Luca Coelho
From: Sara Sharon 

When we TX AMSDU, we shouldn't pad the packet. In the past,
we were building AMSDU only in transport layer, and gen2
functions are built based on this. However, now that op mode
may build AMSDUs, we need to take care of padding also in
gen2 "non-pcie-amsdu" path.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index b71cf55480fc..09cdc15f7645 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -454,7 +454,8 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans,
struct sk_buff *skb,
struct iwl_cmd_meta *out_meta,
int hdr_len,
-   int tx_cmd_len)
+   int tx_cmd_len,
+   bool pad)
 {
int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
struct iwl_tfh_tfd *tfd = iwl_pcie_get_tfd(trans, txq, idx);
@@ -478,7 +479,10 @@ iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans 
*trans,
len = tx_cmd_len + sizeof(struct iwl_cmd_header) + hdr_len -
  IWL_FIRST_TB_SIZE;
 
-   tb1_len = ALIGN(len, 4);
+   if (pad)
+   tb1_len = ALIGN(len, 4);
+   else
+   tb1_len = len;
 
/* map the data for TB1 */
tb1_addr = ((u8 *)_cmd->hdr) + IWL_FIRST_TB_SIZE;
@@ -551,7 +555,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct 
iwl_trans *trans,
out_meta, hdr_len, len);
 
return iwl_pcie_gen2_build_tx(trans, txq, dev_cmd, skb, out_meta,
- hdr_len, len);
+ hdr_len, len, !amsdu);
 }
 
 int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
-- 
2.19.0



[PATCH 01/18] iwlwifi: mvm: don't send keys when entering D3

2018-10-08 Thread Luca Coelho
From: Sara Sharon 

In the past, we needed to program the keys when entering D3. This was
since we replaced the image. However, now that there is a single
image, this is no longer needed.  Note that RSC is sent separately in
a new command.  This solves issues with newer devices that support PN
offload. Since driver re-sent the keys, the PN got zeroed and the
receiver dropped the next packets, until PN caught up again.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 210be26aadaa..fb981270f224 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -722,8 +722,10 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 {
struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
+   bool unified = fw_has_capa(>fw->ucode_capa,
+  IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
struct wowlan_key_data key_data = {
-   .configure_keys = !d0i3,
+   .configure_keys = !d0i3 && !unified,
.use_rsc_tsc = false,
.tkip = _cmd,
.use_tkip = false,
-- 
2.19.0



[PATCH 08/18] iwlwifi: mvm: give TX queue info struct a name

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

Make this a named struct rather than an anonymous one,
we'll want to refer to it by name later.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 24 +++-
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index ff1ba84f3aa6..cff58ed35fbe 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -788,6 +788,18 @@ struct iwl_mvm_geo_profile {
u8 values[ACPI_GEO_TABLE_SIZE];
 };
 
+struct iwl_mvm_dqa_txq_info {
+   u8 hw_queue_refcount;
+   u8 ra_sta_id; /* The RA this queue is mapped to, if exists */
+   bool reserved; /* Is this the TXQ reserved for a STA */
+   u8 mac80211_ac; /* The mac80211 AC this queue is mapped to */
+   u8 txq_tid; /* The TID "owner" of this queue*/
+   u16 tid_bitmap; /* Bitmap of the TIDs mapped to this queue */
+   /* Timestamp for inactivation per TID of this queue */
+   unsigned long last_frame_time[IWL_MAX_TID_COUNT + 1];
+   enum iwl_mvm_queue_status status;
+};
+
 struct iwl_mvm {
/* for logger access */
struct device *dev;
@@ -844,17 +856,7 @@ struct iwl_mvm {
 
u16 hw_queue_to_mac80211[IWL_MAX_TVQM_QUEUES];
 
-   struct {
-   u8 hw_queue_refcount;
-   u8 ra_sta_id; /* The RA this queue is mapped to, if exists */
-   bool reserved; /* Is this the TXQ reserved for a STA */
-   u8 mac80211_ac; /* The mac80211 AC this queue is mapped to */
-   u8 txq_tid; /* The TID "owner" of this queue*/
-   u16 tid_bitmap; /* Bitmap of the TIDs mapped to this queue */
-   /* Timestamp for inactivation per TID of this queue */
-   unsigned long last_frame_time[IWL_MAX_TID_COUNT + 1];
-   enum iwl_mvm_queue_status status;
-   } queue_info[IWL_MAX_HW_QUEUES];
+   struct iwl_mvm_dqa_txq_info queue_info[IWL_MAX_HW_QUEUES];
spinlock_t queue_info_lock; /* For syncing queue mgmt operations */
struct work_struct add_stream_wk; /* To add streams to queues */
 
-- 
2.19.0



[PATCH 13/18] iwlwifi: mvm: reconfigure queues during inactivity check

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

We currently reconfigure the queues after the inactivity check,
but only in one of the two callers. This might leave queues in
a state where the TID owner is wrong, if called when reserving
a queue for a new station.

Clean this up and do the reconfiguration inside the inactivity
check function. This requires changing the locking, but one of
the two places already holds the mvm mutex and the other easily
can.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index a36a631cdfa6..8a0cf736122a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1383,6 +1383,8 @@ static void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
unsigned long now = jiffies;
int i;
 
+   lockdep_assert_held(>mutex);
+
if (iwl_mvm_has_new_tx_api(mvm))
return;
 
@@ -1461,6 +1463,10 @@ static void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
 
rcu_read_unlock();
spin_unlock_bh(>queue_info_lock);
+
+   /* Reconfigure queues requiring reconfiguation */
+   for (i = 0; i < ARRAY_SIZE(mvm->queue_info); i++)
+   iwl_mvm_reconfigure_queue(mvm, i);
 }
 
 static inline u8 iwl_mvm_tid_to_ac_queue(int tid)
@@ -1533,19 +1539,9 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct 
*wk)
unsigned long deferred_tid_traffic;
int sta_id, tid;
 
-   /* Check inactivity of queues */
-   iwl_mvm_inactivity_check(mvm);
-
mutex_lock(>mutex);
 
-   /* No queue reconfiguration in TVQM mode */
-   if (!iwl_mvm_has_new_tx_api(mvm)) {
-   int queue;
-
-   /* Reconfigure queues requiring reconfiguation */
-   for (queue = 0; queue < ARRAY_SIZE(mvm->queue_info); queue++)
-   iwl_mvm_reconfigure_queue(mvm, queue);
-   }
+   iwl_mvm_inactivity_check(mvm);
 
/* Go over all stations with deferred traffic */
for_each_set_bit(sta_id, mvm->sta_deferred_frames,
-- 
2.19.0



[PATCH 11/18] iwlwifi: mvm: clean up iteration in iwl_mvm_inactivity_check()

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

There's no need to build a bitmap first and then iterate,
just do the iteration with the right locking directly.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 32 +---
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index ce03f9750c3a..5b6ec7de8043 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1353,7 +1353,6 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm 
*mvm,
 
 static void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
 {
-   unsigned long timeout_queues_map = 0;
unsigned long now = jiffies;
int i;
 
@@ -1361,22 +1360,18 @@ static void iwl_mvm_inactivity_check(struct iwl_mvm 
*mvm)
return;
 
spin_lock_bh(>queue_info_lock);
-   /* skip the CMD queue */
-   BUILD_BUG_ON(IWL_MVM_DQA_CMD_QUEUE != 0);
-   for (i = 1; i < IWL_MAX_HW_QUEUES; i++) {
-   if (mvm->queue_info[i].tid_bitmap)
-   timeout_queues_map |= BIT(i);
-   }
-   spin_unlock_bh(>queue_info_lock);
 
rcu_read_lock();
 
+   /* we skip the CMD queue below by starting at 1 */
+   BUILD_BUG_ON(IWL_MVM_DQA_CMD_QUEUE != 0);
+
/*
 * If a queue times out - mark it as INACTIVE (don't remove right away
 * if we don't have to.) This is an optimization in case traffic comes
 * later, and we don't HAVE to use a currently-inactive queue
 */
-   for_each_set_bit(i, _queues_map, IWL_MAX_HW_QUEUES) {
+   for (i = 1; i < IWL_MAX_HW_QUEUES; i++) {
struct ieee80211_sta *sta;
struct iwl_mvm_sta *mvmsta;
u8 sta_id;
@@ -1384,15 +1379,14 @@ static void iwl_mvm_inactivity_check(struct iwl_mvm 
*mvm)
unsigned long inactive_tid_bitmap = 0;
unsigned long queue_tid_bitmap;
 
-   spin_lock_bh(>queue_info_lock);
queue_tid_bitmap = mvm->queue_info[i].tid_bitmap;
+   if (!queue_tid_bitmap)
+   continue;
 
/* If TXQ isn't in active use anyway - nothing to do here... */
if (mvm->queue_info[i].status != IWL_MVM_QUEUE_READY &&
-   mvm->queue_info[i].status != IWL_MVM_QUEUE_SHARED) {
-   spin_unlock_bh(>queue_info_lock);
+   mvm->queue_info[i].status != IWL_MVM_QUEUE_SHARED)
continue;
-   }
 
/* Check to see if there are inactive TIDs on this queue */
for_each_set_bit(tid, _tid_bitmap,
@@ -1403,7 +1397,6 @@ static void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
 
inactive_tid_bitmap |= BIT(tid);
}
-   spin_unlock_bh(>queue_info_lock);
 
/* If all TIDs are active - finish check on this queue */
if (!inactive_tid_bitmap)
@@ -1427,15 +1420,20 @@ static void iwl_mvm_inactivity_check(struct iwl_mvm 
*mvm)
 
mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
-   spin_lock_bh(>lock);
+   /* this isn't so nice, but works OK due to the way we loop */
+   spin_unlock(>queue_info_lock);
+
+   /* and we need this locking order */
+   spin_lock(>lock);
spin_lock(>queue_info_lock);
iwl_mvm_remove_inactive_tids(mvm, mvmsta, i,
 inactive_tid_bitmap);
-   spin_unlock(>queue_info_lock);
-   spin_unlock_bh(>lock);
+   /* only unlock sta lock - we still need the queue info lock */
+   spin_unlock(>lock);
}
 
rcu_read_unlock();
+   spin_unlock_bh(>queue_info_lock);
 }
 
 static inline u8 iwl_mvm_tid_to_ac_queue(int tid)
-- 
2.19.0



[PATCH 12/18] iwlwifi: mvm: move queue reconfiguration into new function

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

If TVQM is used we skip over this, move the code into a new
function to get rid of the label.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 64 ++--
 1 file changed, 33 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 5b6ec7de8043..a36a631cdfa6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1351,6 +1351,33 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm 
*mvm,
}
 }
 
+static void iwl_mvm_reconfigure_queue(struct iwl_mvm *mvm, int queue)
+{
+   bool reconfig;
+   bool change_owner;
+
+   spin_lock_bh(>queue_info_lock);
+   reconfig = mvm->queue_info[queue].status == IWL_MVM_QUEUE_RECONFIGURING;
+
+   /*
+* We need to take into account a situation in which a TXQ was
+* allocated to TID x, and then turned shared by adding TIDs y
+* and z. If TID x becomes inactive and is removed from the TXQ,
+* ownership must be given to one of the remaining TIDs.
+* This is mainly because if TID x continues - a new queue can't
+* be allocated for it as long as it is an owner of another TXQ.
+*/
+   change_owner = !(mvm->queue_info[queue].tid_bitmap &
+BIT(mvm->queue_info[queue].txq_tid)) &&
+  (mvm->queue_info[queue].status == IWL_MVM_QUEUE_SHARED);
+   spin_unlock_bh(>queue_info_lock);
+
+   if (reconfig)
+   iwl_mvm_unshare_queue(mvm, queue);
+   else if (change_owner)
+   iwl_mvm_change_queue_owner(mvm, queue);
+}
+
 static void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
 {
unsigned long now = jiffies;
@@ -1504,7 +1531,7 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)
struct ieee80211_sta *sta;
struct iwl_mvm_sta *mvmsta;
unsigned long deferred_tid_traffic;
-   int queue, sta_id, tid;
+   int sta_id, tid;
 
/* Check inactivity of queues */
iwl_mvm_inactivity_check(mvm);
@@ -1512,39 +1539,14 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct 
*wk)
mutex_lock(>mutex);
 
/* No queue reconfiguration in TVQM mode */
-   if (iwl_mvm_has_new_tx_api(mvm))
-   goto alloc_queues;
-
-   /* Reconfigure queues requiring reconfiguation */
-   for (queue = 0; queue < ARRAY_SIZE(mvm->queue_info); queue++) {
-   bool reconfig;
-   bool change_owner;
-
-   spin_lock_bh(>queue_info_lock);
-   reconfig = (mvm->queue_info[queue].status ==
-   IWL_MVM_QUEUE_RECONFIGURING);
-
-   /*
-* We need to take into account a situation in which a TXQ was
-* allocated to TID x, and then turned shared by adding TIDs y
-* and z. If TID x becomes inactive and is removed from the TXQ,
-* ownership must be given to one of the remaining TIDs.
-* This is mainly because if TID x continues - a new queue can't
-* be allocated for it as long as it is an owner of another TXQ.
-*/
-   change_owner = !(mvm->queue_info[queue].tid_bitmap &
-BIT(mvm->queue_info[queue].txq_tid)) &&
-  (mvm->queue_info[queue].status ==
-   IWL_MVM_QUEUE_SHARED);
-   spin_unlock_bh(>queue_info_lock);
+   if (!iwl_mvm_has_new_tx_api(mvm)) {
+   int queue;
 
-   if (reconfig)
-   iwl_mvm_unshare_queue(mvm, queue);
-   else if (change_owner)
-   iwl_mvm_change_queue_owner(mvm, queue);
+   /* Reconfigure queues requiring reconfiguation */
+   for (queue = 0; queue < ARRAY_SIZE(mvm->queue_info); queue++)
+   iwl_mvm_reconfigure_queue(mvm, queue);
}
 
-alloc_queues:
/* Go over all stations with deferred traffic */
for_each_set_bit(sta_id, mvm->sta_deferred_frames,
 IWL_MVM_STATION_COUNT) {
-- 
2.19.0



[PATCH 15/18] iwlwifi: mvm: make queue TID change more explicit

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

Instead of iterating all the queues after having potentially
changed some queue configurations, rechecking if that was done,
mark the ones that do need a TID change explicitly in a bitmap
and use that to send the change to the firmware.

While at it, also rename iwl_mvm_change_queue_owner() to
iwl_mvm_change_queue_tid() since that's more obvious - the
"kind" of owner isn't immediately clear right now.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 53 +---
 1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index b30980c34fd0..ec4925c89295 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1141,7 +1141,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
return ret;
 }
 
-static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue)
+static void iwl_mvm_change_queue_tid(struct iwl_mvm *mvm, int queue)
 {
struct iwl_scd_txq_cfg_cmd cmd = {
.scd_queue = queue,
@@ -1272,7 +1272,8 @@ static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, 
int queue)
 static void iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
 struct iwl_mvm_sta *mvmsta, int queue,
 unsigned long tid_bitmap,
-unsigned long *unshare_queues)
+unsigned long *unshare_queues,
+unsigned long *changetid_queues)
 {
int tid;
 
@@ -1311,12 +1312,29 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm 
*mvm,
 */
for_each_set_bit(tid, _bitmap, IWL_MAX_TID_COUNT + 1) {
int mac_queue = mvmsta->vif->hw_queue[tid_to_mac80211_ac[tid]];
+   u16 tid_bitmap;
 
mvmsta->tid_data[tid].txq_id = IWL_MVM_INVALID_QUEUE;
mvm->hw_queue_to_mac80211[queue] &= ~BIT(mac_queue);
mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
mvmsta->tid_data[tid].is_tid_active = false;
 
+   tid_bitmap = mvm->queue_info[queue].tid_bitmap;
+
+   /*
+* We need to take into account a situation in which a TXQ was
+* allocated to TID x, and then turned shared by adding TIDs y
+* and z. If TID x becomes inactive and is removed from the TXQ,
+* ownership must be given to one of the remaining TIDs.
+* This is mainly because if TID x continues - a new queue can't
+* be allocated for it as long as it is an owner of another TXQ.
+*
+* Mark this queue in the right bitmap, we'll send the command
+* to the firmware later.
+*/
+   if (!(tid_bitmap & BIT(mvm->queue_info[queue].txq_tid)))
+   set_bit(queue, changetid_queues);
+
IWL_DEBUG_TX_QUEUES(mvm,
"Removing inactive TID %d from shared 
Q:%d\n",
tid, queue);
@@ -1345,33 +1363,11 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm 
*mvm,
}
 }
 
-static void iwl_mvm_reconfigure_queue(struct iwl_mvm *mvm, int queue)
-{
-   bool change_owner;
-
-   spin_lock_bh(>queue_info_lock);
-
-   /*
-* We need to take into account a situation in which a TXQ was
-* allocated to TID x, and then turned shared by adding TIDs y
-* and z. If TID x becomes inactive and is removed from the TXQ,
-* ownership must be given to one of the remaining TIDs.
-* This is mainly because if TID x continues - a new queue can't
-* be allocated for it as long as it is an owner of another TXQ.
-*/
-   change_owner = !(mvm->queue_info[queue].tid_bitmap &
-BIT(mvm->queue_info[queue].txq_tid)) &&
-  (mvm->queue_info[queue].status == IWL_MVM_QUEUE_SHARED);
-   spin_unlock_bh(>queue_info_lock);
-
-   if (change_owner)
-   iwl_mvm_change_queue_owner(mvm, queue);
-}
-
 static void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
 {
unsigned long now = jiffies;
unsigned long unshare_queues = 0;
+   unsigned long changetid_queues = 0;
int i;
 
lockdep_assert_held(>mutex);
@@ -1448,7 +1444,8 @@ static void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
spin_lock(>queue_info_lock);
iwl_mvm_remove_inactive_tids(mvm, mvmsta, i,
 inactive_tid_bitmap,
-_queues);
+

[PATCH 07/18] iwlwifi: mvm: move rt status check to the start of the resume flow

2018-10-08 Thread Luca Coelho
From: Shahar S Matityahu 

Move the rt status checking to the start of the resume flow in order
to avoid sending D0I3_END_CMD to the FW.  Also, collect dump if an
assert was encountered.

Signed-off-by: Shahar S Matityahu 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 60 -
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index fb981270f224..843f3b41b72e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1638,32 +1638,10 @@ struct iwl_wowlan_status 
*iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm)
 }
 
 static struct iwl_wowlan_status *
-iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm)
 {
-   u32 base = mvm->error_event_table[0];
-   struct error_table_start {
-   /* cf. struct iwl_error_event_table */
-   u32 valid;
-   u32 error_id;
-   } err_info;
int ret;
 
-   iwl_trans_read_mem_bytes(mvm->trans, base,
-_info, sizeof(err_info));
-
-   if (err_info.valid) {
-   IWL_INFO(mvm, "error table is valid (%d) with error (%d)\n",
-err_info.valid, err_info.error_id);
-   if (err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
-   struct cfg80211_wowlan_wakeup wakeup = {
-   .rfkill_release = true,
-   };
-   ieee80211_report_wowlan_wakeup(vif, ,
-  GFP_KERNEL);
-   }
-   return ERR_PTR(-EIO);
-   }
-
/* only for tracing for now */
ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0, 0, NULL);
if (ret)
@@ -1682,7 +1660,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm 
*mvm,
bool keep;
struct iwl_mvm_sta *mvm_ap_sta;
 
-   fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
+   fw_status = iwl_mvm_get_wakeup_status(mvm);
if (IS_ERR_OR_NULL(fw_status))
goto out_unlock;
 
@@ -1807,7 +1785,7 @@ static void iwl_mvm_query_netdetect_reasons(struct 
iwl_mvm *mvm,
u32 reasons = 0;
int i, j, n_matches, ret;
 
-   fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
+   fw_status = iwl_mvm_get_wakeup_status(mvm);
if (!IS_ERR_OR_NULL(fw_status)) {
reasons = le32_to_cpu(fw_status->wakeup_reasons);
kfree(fw_status);
@@ -1920,6 +1898,29 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 
*mac,
ieee80211_resume_disconnect(vif);
 }
 
+static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
+  struct ieee80211_vif *vif)
+{
+   u32 base = mvm->error_event_table[0];
+   struct error_table_start {
+   /* cf. struct iwl_error_event_table */
+   u32 valid;
+   u32 error_id;
+   } err_info;
+
+   iwl_trans_read_mem_bytes(mvm->trans, base,
+_info, sizeof(err_info));
+
+   if (err_info.valid &&
+   err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
+   struct cfg80211_wowlan_wakeup wakeup = {
+   .rfkill_release = true,
+   };
+   ieee80211_report_wowlan_wakeup(vif, , GFP_KERNEL);
+   }
+   return err_info.valid;
+}
+
 static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
 {
struct ieee80211_vif *vif = NULL;
@@ -1951,6 +1952,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool 
test)
/* query SRAM first in case we want event logging */
iwl_mvm_read_d3_sram(mvm);
 
+   if (iwl_mvm_check_rt_status(mvm, vif)) {
+   set_bit(STATUS_FW_ERROR, >trans->status);
+   iwl_mvm_dump_nic_error_log(mvm);
+   iwl_fw_dbg_collect_desc(>fwrt, _dump_desc_assert,
+   NULL, 0);
+   ret = 1;
+   goto err;
+   }
+
if (d0i3_first) {
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
if (ret < 0) {
-- 
2.19.0



[PATCH 06/18] iwlwifi: dump debug data before stop device

2018-10-08 Thread Luca Coelho
From: Shahar S Matityahu 

Debug data dump is not working in flows that stop the device is used
in their error handling. During these flows the op mode mutex is
locked until the device stops.  Because of that, any assert generated
from the firmware can be handled only after the device already
stopped.

Since dumping cannot occour after stopping the device, split the the
dump function to two parts, Part that handles locking, and the part
that starts the actual dumping and call the second part in the op mode
stop device function.

Signed-off-by: Shahar S Matityahu 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c  | 27 +++-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h  |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |  5 
 3 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index f44c716b1130..c16757051f16 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1154,14 +1154,14 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, 
u8 conf_id)
 }
 IWL_EXPORT_SYMBOL(iwl_fw_start_dbg_conf);
 
-void iwl_fw_error_dump_wk(struct work_struct *work)
+/* this function assumes dump_start was called beforehand and dump_end will be
+ * called afterwards
+ */
+void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt)
 {
-   struct iwl_fw_runtime *fwrt =
-   container_of(work, struct iwl_fw_runtime, dump.wk.work);
struct iwl_fw_dbg_params params = {0};
 
-   if (fwrt->ops && fwrt->ops->dump_start &&
-   fwrt->ops->dump_start(fwrt->ops_ctx))
+   if (!test_bit(IWL_FWRT_STATUS_DUMPING, >status))
return;
 
if (fwrt->ops && fwrt->ops->fw_running &&
@@ -1169,7 +1169,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
IWL_ERR(fwrt, "Firmware not running - cannot dump error\n");
iwl_fw_free_dump_desc(fwrt);
clear_bit(IWL_FWRT_STATUS_DUMPING, >status);
-   goto out;
+   return;
}
 
iwl_fw_dbg_stop_recording(fwrt, );
@@ -1183,7 +1183,20 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
udelay(500);
iwl_fw_dbg_restart_recording(fwrt, );
}
-out:
+}
+IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_sync);
+
+void iwl_fw_error_dump_wk(struct work_struct *work)
+{
+   struct iwl_fw_runtime *fwrt =
+   container_of(work, struct iwl_fw_runtime, dump.wk.work);
+
+   if (fwrt->ops && fwrt->ops->dump_start &&
+   fwrt->ops->dump_start(fwrt->ops_ctx))
+   return;
+
+   iwl_fw_dbg_collect_sync(fwrt);
+
if (fwrt->ops && fwrt->ops->dump_end)
fwrt->ops->dump_end(fwrt->ops_ctx);
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index d9578dcec24c..6f8d3256f7b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -367,4 +367,5 @@ static inline void iwl_fw_resume_timestamp(struct 
iwl_fw_runtime *fwrt) {}
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
 void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
+void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
 #endif  /* __iwl_fw_dbg_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 6f927052aeaf..ff1ba84f3aa6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1906,6 +1906,11 @@ static inline u32 iwl_mvm_flushable_queues(struct 
iwl_mvm *mvm)
 
 static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
 {
+   lockdep_assert_held(>mutex);
+   /* calling this function without using dump_start/end since at this
+* point we already hold the op mode mutex
+*/
+   iwl_fw_dbg_collect_sync(>fwrt);
iwl_fw_cancel_timestamp(>fwrt);
iwl_free_fw_paging(>fwrt);
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, >status);
-- 
2.19.0



[PATCH 16/18] iwlwifi: mvm: make iwl_mvm_scd_queue_redirect() static

2018-10-08 Thread Luca Coelho
From: Johannes Berg 

This function is only used in the file where it's declared,
so just make it static.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 6 +++---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 4 
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index ec4925c89295..24631866a174 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -674,9 +674,9 @@ static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm,
  * in such a case, otherwise - if no redirection required - it does nothing,
  * unless the %force param is true.
  */
-int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid,
-  int ac, int ssn, unsigned int wdg_timeout,
-  bool force)
+static int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid,
+ int ac, int ssn, unsigned int wdg_timeout,
+ bool force)
 {
struct iwl_scd_txq_cfg_cmd cmd = {
.scd_queue = queue,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
index 0fc211108149..492cfd37521b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
@@ -572,8 +572,4 @@ void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
 void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk);
 
-int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid,
-  int ac, int ssn, unsigned int wdg_timeout,
-  bool force);
-
 #endif /* __sta_h__ */
-- 
2.19.0



[PATCH 05/18] iwlwifi: mvm: use fast balance scan in case of DCM mode with P2P GO

2018-10-08 Thread Luca Coelho
From: Ayala Beker 

Currently in case of DCM with P2P GO where BSS DTIM interval < 220 msec
the fw fails to allocate events for the P2P GO dtim due to long passive
scan events.

Fix this by requesting all scans in this scenario to be fragmented with
fast balance scan time settings.  The only exception is in case
fragmented scan was planned to be set due to low latency or high
throughput reason, set the scan timing as planned.

Signed-off-by: Ayala Beker 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 91 ++-
 1 file changed, 68 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index b43bf116c7e8..cfb784fea77b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -239,8 +239,32 @@ iwl_mvm_get_traffic_load_band(struct iwl_mvm *mvm, enum 
nl80211_band band)
return mvm->tcm.result.band_load[band];
 }
 
+struct iwl_is_dcm_with_go_iterator_data {
+   struct ieee80211_vif *current_vif;
+   bool is_dcm_with_p2p_go;
+};
+
+static void iwl_mvm_is_dcm_with_go_iterator(void *_data, u8 *mac,
+   struct ieee80211_vif *vif)
+{
+   struct iwl_is_dcm_with_go_iterator_data *data = _data;
+   struct iwl_mvm_vif *other_mvmvif = iwl_mvm_vif_from_mac80211(vif);
+   struct iwl_mvm_vif *curr_mvmvif =
+   iwl_mvm_vif_from_mac80211(data->current_vif);
+
+   /* exclude the given vif */
+   if (vif == data->current_vif)
+   return;
+
+   if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
+   other_mvmvif->phy_ctxt && curr_mvmvif->phy_ctxt &&
+   other_mvmvif->phy_ctxt->id != curr_mvmvif->phy_ctxt->id)
+   data->is_dcm_with_p2p_go = true;
+}
+
 static enum
-iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device,
+iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
+struct ieee80211_vif *vif,
 enum iwl_mvm_traffic_load load,
 bool low_latency)
 {
@@ -253,9 +277,30 @@ iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm 
*mvm, bool p2p_device,
if (!global_cnt)
return IWL_SCAN_TYPE_UNASSOC;
 
-   if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) && !p2p_device &&
-   fw_has_api(>fw->ucode_capa, IWL_UCODE_TLV_API_FRAGMENTED_SCAN))
-   return IWL_SCAN_TYPE_FRAGMENTED;
+   if (fw_has_api(>fw->ucode_capa,
+  IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
+   if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) &&
+   (!vif || vif->type != NL80211_IFTYPE_P2P_DEVICE))
+   return IWL_SCAN_TYPE_FRAGMENTED;
+
+   /* in case of DCM with GO where BSS DTIM interval < 220msec
+* set all scan requests as fast-balance scan
+* */
+   if (vif && vif->type == NL80211_IFTYPE_STATION &&
+   vif->bss_conf.dtim_period < 220) {
+   struct iwl_is_dcm_with_go_iterator_data data = {
+   .current_vif = vif,
+   .is_dcm_with_p2p_go = false,
+   };
+
+   ieee80211_iterate_active_interfaces_atomic(mvm->hw,
+   IEEE80211_IFACE_ITER_NORMAL,
+   iwl_mvm_is_dcm_with_go_iterator,
+   );
+   if (data.is_dcm_with_p2p_go)
+   return IWL_SCAN_TYPE_FAST_BALANCE;
+   }
+   }
 
if (load >= IWL_MVM_TRAFFIC_MEDIUM || low_latency)
return IWL_SCAN_TYPE_MILD;
@@ -264,7 +309,8 @@ iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm 
*mvm, bool p2p_device,
 }
 
 static enum
-iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm, bool p2p_device)
+iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
+   struct ieee80211_vif *vif)
 {
enum iwl_mvm_traffic_load load;
bool low_latency;
@@ -272,12 +318,12 @@ iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm 
*mvm, bool p2p_device)
load = iwl_mvm_get_traffic_load(mvm);
low_latency = iwl_mvm_low_latency(mvm);
 
-   return _iwl_mvm_get_scan_type(mvm, p2p_device, load, low_latency);
+   return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
 }
 
 static enum
 iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm,
-bool p2p_device,
+

[PATCH 00/18] iwlwifi: updates intended for v4.20 2018-10-08

2018-10-08 Thread Luca Coelho
From: Luca Coelho 

Hi,

Here's the seventh set of patches intended for v4.20.  It's the usual
development, the majority of the changes are cleanups in the queue
lifetime management code by Johannes, and also some improvements,
debugging and bugfixes again.

The changes are:

* Support for a new scan type;
* Clean-up in the queue handling code;
* A few bug fixes;

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

Please review.

Cheers,
Luca.


Ayala Beker (2):
  iwlwifi: mvm: introduce a new fragmented scan type: fast balance
  iwlwifi: mvm: use fast balance scan in case of DCM mode with P2P GO

Johannes Berg (11):
  iwlwifi: mvm: give TX queue info struct a name
  iwlwifi: mvm: move queue management into sta.c
  iwlwifi: mvm: remove per-queue hw refcount
  iwlwifi: mvm: clean up iteration in iwl_mvm_inactivity_check()
  iwlwifi: mvm: move queue reconfiguration into new function
  iwlwifi: mvm: reconfigure queues during inactivity check
  iwlwifi: mvm: remove RECONFIGURING queue state
  iwlwifi: mvm: make queue TID change more explicit
  iwlwifi: mvm: make iwl_mvm_scd_queue_redirect() static
  iwlwifi: mvm: move iwl_mvm_sta_alloc_queue() down
  iwlwifi: mvm: kill INACTIVE queue state

Sara Sharon (3):
  iwlwifi: mvm: don't send keys when entering D3
  iwlwifi: pcie: don't pad AMSDU packets
  iwlwifi: trace: change trace to trace one TB at a time

Shahar S Matityahu (2):
  iwlwifi: dump debug data before stop device
  iwlwifi: mvm: move rt status check to the start of the resume flow

 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   |  27 +-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |   1 +
 .../intel/iwlwifi/iwl-devtrace-data.h |  30 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c   |  64 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |   9 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  54 +-
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 115 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 837 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h  |   8 -
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   |  34 +-
 .../net/wireless/intel/iwlwifi/mvm/utils.c| 420 +
 .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c |  28 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  |  29 +-
 13 files changed, 825 insertions(+), 831 deletions(-)

-- 
2.19.0



pull-request: iwlwifi-next 2018-10-06

2018-10-06 Thread Luca Coelho
Hi Kalle,

This is the third batch of patches intended for v4.20.  This includes
the last 2 patchsets I sent.  Usual development work, including some
improvements in the HE radiotap stuff, a new FW version support and
other small improvements and fixes.  More details about the contents in
the tag description.

I have sent this out before and kbuildbot reported success.

Please let me know if there are any issues.

Cheers,
Luca.


The following changes since commit e1c02eb16a9c742178874a7d1a08d300981715fb:

  qtnfmac: implement dump_station support for STA mode (2018-10-05 14:01:44 
+0300)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git 
tags/iwlwifi-next-for-kalle-2018-10-06

for you to fetch changes up to ea7cb8293874f8d9cf36c9e5387e2247f15373dc:

  iwlwifi: dbg: make trigger functions type agnostic (2018-10-06 10:25:55 +0300)


Third set of iwlwifi patches for 4.20

* Fix for a race condition that caused the FW to crash;
* HE radiotap cleanup and improvements;
* Reorder channel optimization for scans;
* Bumped the FW API version supported after the last API change for
  this release;
* Debugging improvements;
* A few bug fixes;
* Some cleanups in preparation for a new implementation;
* Other small improvements, cleanups and fixes.


Ayala Beker (1):
  iwlwifi: mvm: allow channel reorder optimization during scan

Emmanuel Grumbach (1):
  iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface

Haim Dreyfuss (1):
  iwlwifi: mvm Support new MCC update response

Johannes Berg (16):
  iwlwifi: mvm: remove unnecessary overload variable
  iwlwifi: mvm: minor cleanups to HE radiotap code
  iwlwifi: mvm: put HE SIG-B symbols/users data correctly
  iwlwifi: mvm: pull some he_phy_data decoding into a separate function
  iwlwifi: mvm: clean up HE radiotap RU allocation parsing
  iwlwifi: mvm: move HE-MU LTF_NUM parsing to he_phy_data parsing
  iwlwifi: mvm: add TXOP to HE radiotap data
  iwlwifi: mvm: add LDPC-XSYM to HE radiotap data
  iwlwifi: mvm: add more information to HE radiotap
  iwlwifi: mvm: set max TX/RX A-MPDU subframes to HE limit
  iwlwifi: pcie gen2: check iwl_pcie_gen2_set_tb() return value
  iwlwifi: add fall through comment
  iwlwifi: pcie: check iwl_pcie_txq_build_tfd() return value
  iwlwifi: bump firmware API version for 9000 and 22000 series devices
  iwlwifi: mvm: decode HE information for MU (without ext info)
  iwlwifi: mvm: show more HE radiotap data for TB PPDUs

Luca Coelho (1):
  iwlwifi: mvm: check for n_profiles validity in EWRD ACPI

Naftali Goldstein (1):
  iwlwifi: nvm: get num of hw addresses from firmware

Sara Sharon (8):
  iwlwifi: dbg: move debug data to a struct
  iwlwifi: dbg: refactor dump code to improve readability
  iwlwifi: dbg: split iwl_fw_error_dump to two functions
  iwlwifi: dbg: dump memory in a helper function
  iwlwifi: dbg: group trigger condition to helper function
  iwlwifi: dbg: make iwl_fw_dbg_no_trig_window trigger agnostic
  iwlwifi: dbg: decrement occurrences for all triggers
  iwlwifi: dbg: make trigger functions type agnostic

Shahar S Matityahu (3):
  iwlwifi: add dump collection in case alive flow fails
  iwlwifi: runtime: add send host command op to firmware runtime op struct
  iwlwifi: add debugfs to send host command

Shaul Triebitz (1):
  iwlwifi: pcie: avoid empty free RB queue

Yisheng Xie (1):
  iwlwifi: mvm: use match_string() helper

 drivers/net/wireless/intel/iwlwifi/cfg/22000.c  |   2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c   |   2 +-
 drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h |  81 +---
 drivers/net/wireless/intel/iwlwifi/fw/api/rx.h  |   8 +-
 drivers/net/wireless/intel/iwlwifi/fw/api/scan.h|   5 +-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 411 
--
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h |  45 ---
 drivers/net/wireless/intel/iwlwifi/fw/debugfs.c |  64 
 drivers/net/wireless/intel/iwlwifi/fw/error-dump.h  |   2 +
 drivers/net/wireless/intel/iwlwifi/fw/file.h|   7 +-
 drivers/net/wireless/intel/iwlwifi/fw/img.h |  41 ++
 drivers/net/wireless/intel/iwlwifi/fw/runtime.h |   2 +
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c|  77 +--
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c  |  10 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h  |   4 +-
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c|  13 +---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c |  12 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c   |  12 +--
 drivers/net

pull-request: iwlwifi firmwares update 2018-10-03

2018-10-03 Thread Luca Coelho
Hi,

We have updated all the firmwares we currently support.

Please pull or let me know if there are any issues.

Cheers,
Luca.


The following changes since commit 7c81f23ad903f72e87e2102d8f52408305c0f7a2:

  ti-connectivity: add firmware for CC2560(A) Bluetooth (2018-10-01 10:08:30 
-0400)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware.git 
tags/iwlwifi-fw-2018-10-03

for you to fetch changes up to da110f2f392ab0f9a4e3cc35402b1f3e2c58127f:

  iwlwifi: add -41.ucode firmwares for 9000 series (2018-10-03 10:08:09 +0300)


iwlwifi: updata all currently supported FWs

* Update FWs for 3160, 7260 and 7265;
* Update FWs for 3168 and 7265D;
* Update FWs for 8000C and 8265;
* Update FWs for 9000 and 9260.


Emmanuel Grumbach (2):
  iwlwifi: update firmwares for 9000 series
  iwlwifi: add -41.ucode firmwares for 9000 series

Luca Coelho (1):
  iwlwifi: update firmwares for 7000, 8000 and 9000 series

 WHENCE|  20 +---
 iwlwifi-3160-17.ucode | Bin 918268 -> 918268 bytes
 iwlwifi-7260-17.ucode | Bin 1049340 -> 1049340 bytes
 iwlwifi-7265-17.ucode | Bin 1180412 -> 1180412 bytes
 iwlwifi-8000C-36.ucode| Bin 2486572 -> 2486572 bytes
 iwlwifi-8265-36.ucode | Bin 2498044 -> 2498044 bytes
 iwlwifi-9000-pu-b0-jf-b0-38.ucode | Bin 2520568 -> 2520568 bytes
 iwlwifi-9000-pu-b0-jf-b0-41.ucode | Bin 0 -> 2961864 bytes
 iwlwifi-9260-th-b0-jf-b0-38.ucode | Bin 2521412 -> 2521412 bytes
 iwlwifi-9260-th-b0-jf-b0-41.ucode | Bin 0 -> 2620368 bytes
 10 files changed, 13 insertions(+), 7 deletions(-)
 create mode 100644 iwlwifi-9000-pu-b0-jf-b0-41.ucode
 create mode 100644 iwlwifi-9260-th-b0-jf-b0-41.ucode


signature.asc
Description: This is a digitally signed message part


[PATCH 15/16] iwlwifi: dbg: decrement occurrences for all triggers

2018-10-01 Thread Luca Coelho
From: Sara Sharon 

iwl_fw_dbg_collect can be called by any function that already
has the error string ready. iwl_fw_dbg_collect_trig, on the
other hand, does string formatting. The occurrences decrement
is at iwl_fw_dbg_collect_trig, instead of iwl_fw_dbg_collect,
which causes it to sometimes be skipped. Move it to the right
location.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index a049367ac08a..1ae04577aed3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1044,10 +1044,13 @@ IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);
 int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
   enum iwl_fw_dbg_trigger trig,
   const char *str, size_t len,
-  const struct iwl_fw_dbg_trigger_tlv *trigger)
+  struct iwl_fw_dbg_trigger_tlv *trigger)
 {
struct iwl_fw_dump_desc *desc;
 
+   if (trigger && !le16_to_cpu(trigger->occurrences))
+   return 0;
+
if (trigger && trigger->flags & IWL_FW_DBG_FORCE_RESTART) {
IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", trig);
iwl_force_nmi(fwrt->trans);
@@ -1058,6 +1061,12 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
if (!desc)
return -ENOMEM;
 
+   if (trigger) {
+   u16 occurrences = le16_to_cpu(trigger->occurrences) - 1;
+
+   trigger->occurrences = cpu_to_le16(occurrences);
+   }
+
desc->len = len;
desc->trig_desc.type = cpu_to_le32(trig);
memcpy(desc->trig_desc.data, str, len);
@@ -1070,13 +1079,9 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
struct iwl_fw_dbg_trigger_tlv *trigger,
const char *fmt, ...)
 {
-   u16 occurrences = le16_to_cpu(trigger->occurrences);
int ret, len = 0;
char buf[64];
 
-   if (!occurrences)
-   return 0;
-
if (fmt) {
va_list ap;
 
@@ -1099,7 +1104,6 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
if (ret)
return ret;
 
-   trigger->occurrences = cpu_to_le16(occurrences - 1);
return 0;
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_trig);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index bee7a938a721..701bac1aba4d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -111,7 +111,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
 int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
   enum iwl_fw_dbg_trigger trig,
   const char *str, size_t len,
-  const struct iwl_fw_dbg_trigger_tlv *trigger);
+  struct iwl_fw_dbg_trigger_tlv *trigger);
 int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
struct iwl_fw_dbg_trigger_tlv *trigger,
const char *fmt, ...) __printf(3, 4);
-- 
2.19.0



[PATCH 12/16] iwlwifi: mvm: show more HE radiotap data for TB PPDUs

2018-10-01 Thread Luca Coelho
From: Johannes Berg 

For trigger-based PPDUs, most values aren't part of the HE-SIG-A
because they're preconfigured by the trigger frame. However, we
still have this information since we used the trigger frame to
configure the hardware, so we can (and do) read it back out and
can thus show it in radiotap.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 67 +--
 1 file changed, 31 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index a63a073e8562..26ac9402568d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -1005,16 +1005,41 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
 {
u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
bool sigb_data;
-
-   he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
+   u16 d1known = IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN;
+   u16 d2known = IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
+ IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN;
+
+   he->data1 |= cpu_to_le16(d1known);
+   he->data2 |= cpu_to_le16(d2known);
he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_BSS_COLOR_MASK,
he_phy_data),
  IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR);
-
-   he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN);
+   he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_UPLINK,
+   he_phy_data),
+ IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
+   he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_LDPC_EXT_SYM,
+   he_phy_data),
+ IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
+   he->data4 |= 
le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_SPATIAL_REUSE_MASK,
+   he_phy_data),
+ 
IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
+   he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PRE_FEC_PAD_MASK,
+   he_phy_data),
+ IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
+   he->data5 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_PE_DISAMBIG,
+   he_phy_data),
+ IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG);
he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_TXOP_DUR_MASK,
he_phy_data),
  IEEE80211_RADIOTAP_HE_DATA6_TXOP);
+   he->data6 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_DOPPLER,
+   he_phy_data),
+ IEEE80211_RADIOTAP_HE_DATA6_DOPPLER);
 
switch (he_type) {
case RATE_MCS_HE_TYPE_MU:
@@ -1044,7 +1069,8 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO;
if (sigb_data)
iwl_mvm_decode_he_sigb(mvm, desc, rate_n_flags, he_mu);
-
+   /* fall through */
+   case RATE_MCS_HE_TYPE_TRIG:
he->data2 |=

cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN);
he->data5 |=
@@ -1063,37 +1089,6 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
break;
}
 
-   if (he_type != RATE_MCS_HE_TYPE_TRIG) {
-   u16 d1known = IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
- IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
- IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
- IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN;
-   u16 d2known = IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
- IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN;
-
-   he->data1 |= cpu_to_le16(d1known);
-   he->data2 |= cpu_to_le16(d2known);
-
-   he->data3 |= le16_encode_bits(FIELD_GET(IWL_RX_HE_PHY_UPLINK,
-   he_phy_data),
- 
IEEE80211_RADIOTAP_HE_DATA3_UL_DL);
-

[PATCH 07/16] iwlwifi: mvm Support new MCC update response

2018-10-01 Thread Luca Coelho
From: Haim Dreyfuss 

Change MCC update response API to be compatible with new FW API.
While at it change v2 which is not in use anymore to v3 and cleanup
mcc_update v1 command and response which is obsolete.

Signed-off-by: Haim Dreyfuss 
Signed-off-by: Luca Coelho 
---
 .../wireless/intel/iwlwifi/fw/api/nvm-reg.h   | 67 ---
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |  7 +-
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c  | 25 ---
 3 files changed, 45 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index d22c1eefba6a..93b392f0c6a4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -269,22 +269,6 @@ struct iwl_nvm_access_complete_cmd {
__le32 reserved;
 } __packed; /* NVM_ACCESS_COMPLETE_CMD_API_S_VER_1 */
 
-/**
- * struct iwl_mcc_update_cmd_v1 - Request the device to update geographic
- * regulatory profile according to the given MCC (Mobile Country Code).
- * The MCC is two letter-code, ascii upper case[A-Z] or '00' for world domain.
- * 'ZZ' MCC will be used to switch to NVM default profile; in this case, the
- * MCC in the cmd response will be the relevant MCC in the NVM.
- * @mcc: given mobile country code
- * @source_id: the source from where we got the MCC, see iwl_mcc_source
- * @reserved: reserved for alignment
- */
-struct iwl_mcc_update_cmd_v1 {
-   __le16 mcc;
-   u8 source_id;
-   u8 reserved;
-} __packed; /* LAR_UPDATE_MCC_CMD_API_S_VER_1 */
-
 /**
  * struct iwl_mcc_update_cmd - Request the device to update geographic
  * regulatory profile according to the given MCC (Mobile Country Code).
@@ -306,7 +290,18 @@ struct iwl_mcc_update_cmd {
 } __packed; /* LAR_UPDATE_MCC_CMD_API_S_VER_2 */
 
 /**
- * struct iwl_mcc_update_resp_v1  - response to MCC_UPDATE_CMD.
+ * enum iwl_geo_information - geographic information.
+ * @GEO_NO_INFO: no special info for this geo profile.
+ * @GEO_WMM_ETSI_5GHZ_INFO: this geo profile limits the WMM params
+ * for the 5 GHz band.
+ */
+enum iwl_geo_information {
+   GEO_NO_INFO =   0,
+   GEO_WMM_ETSI_5GHZ_INFO =BIT(0),
+};
+
+/**
+ * struct iwl_mcc_update_resp_v3 - response to MCC_UPDATE_CMD.
  * Contains the new channel control profile map, if changed, and the new MCC
  * (mobile country code).
  * The new MCC may be different than what was requested in MCC_UPDATE_CMD.
@@ -314,30 +309,23 @@ struct iwl_mcc_update_cmd {
  * @mcc: the new applied MCC
  * @cap: capabilities for all channels which matches the MCC
  * @source_id: the MCC source, see iwl_mcc_source
- * @n_channels: number of channels in @channels_data (may be 14, 39, 50 or 51
- * channels, depending on platform)
+ * @time: time elapsed from the MCC test start (in units of 30 seconds)
+ * @geo_info: geographic specific profile information
+ * see  iwl_geo_information.
+ * @n_channels: number of channels in @channels_data.
  * @channels: channel control data map, DWORD for each channel. Only the first
  * 16bits are used.
  */
-struct iwl_mcc_update_resp_v1  {
+struct iwl_mcc_update_resp_v3 {
__le32 status;
__le16 mcc;
u8 cap;
u8 source_id;
+   __le16 time;
+   __le16 geo_info;
__le32 n_channels;
__le32 channels[0];
-} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_1 */
-
-/**
- * enum iwl_geo_information - geographic information.
- * @GEO_NO_INFO: no special info for this geo profile.
- * @GEO_WMM_ETSI_5GHZ_INFO: this geo profile limits the WMM params
- * for the 5 GHz band.
- */
-enum iwl_geo_information {
-   GEO_NO_INFO =   0,
-   GEO_WMM_ETSI_5GHZ_INFO =BIT(0),
-};
+} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S_VER_3 */
 
 /**
  * struct iwl_mcc_update_resp - response to MCC_UPDATE_CMD.
@@ -347,25 +335,26 @@ enum iwl_geo_information {
  * @status: see  iwl_mcc_update_status
  * @mcc: the new applied MCC
  * @cap: capabilities for all channels which matches the MCC
- * @source_id: the MCC source, see iwl_mcc_source
- * @time: time elapsed from the MCC test start (in 30 seconds TU)
+ * @time: time elapsed from the MCC test start (in units of 30 seconds)
  * @geo_info: geographic specific profile information
  * see  iwl_geo_information.
- * @n_channels: number of channels in @channels_data (may be 14, 39, 50 or 51
- * channels, depending on platform)
+ * @source_id: the MCC source, see iwl_mcc_source
+ * @reserved: for four bytes alignment.
+ * @n_channels: number of channels in @channels_data.
  * @channels: channel control data map, DWORD for each channel. Only the first
  * 16bits are used.
  */
 struct iwl_mcc_update_resp {
__le32 status;
__le16 mcc;
-   u8 cap;
-   u8 source_id;
+   __le16 cap;
__le16 time;
__le16 geo_info;
+   u8 source_id;
+   u8 reserved[3

[PATCH 14/16] iwlwifi: mvm: use match_string() helper

2018-10-01 Thread Luca Coelho
From: Yisheng Xie 

match_string() returns the index of an array for a matching string,
which can be used intead of open coded variant.

Reviewed-by: Andy Shevchenko 
Signed-off-by: Yisheng Xie 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index de40752aa67e..3b6b3d8fb961 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -666,16 +666,11 @@ iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char 
*buf,
};
int ret, bt_force_ant_mode;
 
-   for (bt_force_ant_mode = 0;
-bt_force_ant_mode < ARRAY_SIZE(modes_str);
-bt_force_ant_mode++) {
-   if (!strcmp(buf, modes_str[bt_force_ant_mode]))
-   break;
-   }
-
-   if (bt_force_ant_mode >= ARRAY_SIZE(modes_str))
-   return -EINVAL;
+   ret = match_string(modes_str, ARRAY_SIZE(modes_str), buf);
+   if (ret < 0)
+   return ret;
 
+   bt_force_ant_mode = ret;
ret = 0;
mutex_lock(>mutex);
if (mvm->bt_force_ant_mode == bt_force_ant_mode)
-- 
2.19.0



[PATCH 09/16] iwlwifi: runtime: add send host command op to firmware runtime op struct

2018-10-01 Thread Luca Coelho
From: Shahar S Matityahu 

Add send host command op to firmware runtime op struct to allow sending
host commands to the op mode from the fw runtime context.

Signed-off-by: Shahar S Matityahu 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/runtime.h |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c| 13 +
 2 files changed, 14 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h 
b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index ac6db5e2b3d0..6b95d0e75889 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -71,6 +71,7 @@ struct iwl_fw_runtime_ops {
int (*dump_start)(void *ctx);
void (*dump_end)(void *ctx);
bool (*fw_running)(void *ctx);
+   int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd);
 };
 
 #define MAX_NUM_LMAC 2
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index c388e0e758e7..3acf512bad47 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -565,10 +565,23 @@ static bool iwl_mvm_fwrt_fw_running(void *ctx)
return iwl_mvm_firmware_running(ctx);
 }
 
+static int iwl_mvm_fwrt_send_hcmd(void *ctx, struct iwl_host_cmd *host_cmd)
+{
+   struct iwl_mvm *mvm = (struct iwl_mvm *)ctx;
+   int ret;
+
+   mutex_lock(>mutex);
+   ret = iwl_mvm_send_cmd(mvm, host_cmd);
+   mutex_unlock(>mutex);
+
+   return ret;
+}
+
 static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = {
.dump_start = iwl_mvm_fwrt_dump_start,
.dump_end = iwl_mvm_fwrt_dump_end,
.fw_running = iwl_mvm_fwrt_fw_running,
+   .send_hcmd = iwl_mvm_fwrt_send_hcmd,
 };
 
 static struct iwl_op_mode *
-- 
2.19.0



[PATCH 06/16] iwlwifi: pcie: check iwl_pcie_txq_build_tfd() return value

2018-10-01 Thread Luca Coelho
From: Johannes Berg 

If we use the iwl_pcie_txq_build_tfd() return value for BIT(),
we should validate that it's not going to be negative, so do
the check and bail out if we hit an error. We shouldn't, as
we check if it'll fit beforehand, but better be safe.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 67820bfaba64..f227b91098c9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -2013,6 +2013,8 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, 
struct sk_buff *skb,
return -EINVAL;
tb_idx = iwl_pcie_txq_build_tfd(trans, txq, tb_phys,
skb_frag_size(frag), false);
+   if (tb_idx < 0)
+   return tb_idx;
 
out_meta->tbs |= BIT(tb_idx);
}
-- 
2.19.0



[PATCH 11/16] iwlwifi: mvm: decode HE information for MU (without ext info)

2018-10-01 Thread Luca Coelho
From: Johannes Berg 

When the info type is MU, we still have the data from the TSF
overload words, so should decode that. When it's MU_EXT_INFO
we additionally have the SIG-B common 0/1/2 fields.

Also document the validity depending on the info type and fix
the name of the regular TB PPDU info type accordingly.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/api/rx.h | 8 
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c  | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
index 415b8842b426..0537496b6eb1 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
@@ -368,10 +368,10 @@ enum iwl_rx_he_phy {
/* trigger encoded */
IWL_RX_HE_PHY_RU_ALLOC_MASK = 0xfe00ULL,
IWL_RX_HE_PHY_INFO_TYPE_MASK= 0xf000ULL,
-   IWL_RX_HE_PHY_INFO_TYPE_SU  = 0x0,
-   IWL_RX_HE_PHY_INFO_TYPE_MU  = 0x1,
-   IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2,
-   IWL_RX_HE_PHY_INFO_TYPE_TB_EXT_INFO = 0x3,
+   IWL_RX_HE_PHY_INFO_TYPE_SU  = 0x0, /* TSF low valid (first 
DW) */
+   IWL_RX_HE_PHY_INFO_TYPE_MU  = 0x1, /* TSF low/high valid 
(both DWs) */
+   IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO = 0x2, /* same + 
SIGB-common0/1/2 valid */
+   IWL_RX_HE_PHY_INFO_TYPE_TB  = 0x3, /* TSF low/high valid 
(both DWs) */
 
/* second dword - MU data */
IWL_RX_HE_PHY_MU_SIGB_COMPRESSION   = BIT_ULL(32 + 0),
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 61916f39bac2..a63a073e8562 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -1095,8 +1095,9 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm 
*mvm,
}
 
switch (FIELD_GET(IWL_RX_HE_PHY_INFO_TYPE_MASK, he_phy_data)) {
+   case IWL_RX_HE_PHY_INFO_TYPE_MU:
case IWL_RX_HE_PHY_INFO_TYPE_MU_EXT_INFO:
-   case IWL_RX_HE_PHY_INFO_TYPE_TB_EXT_INFO:
+   case IWL_RX_HE_PHY_INFO_TYPE_TB:
iwl_mvm_decode_he_phy_ru_alloc(he_phy_data, rate_n_flags,
   he, he_mu, rx_status);
break;
-- 
2.19.0



[PATCH 13/16] iwlwifi: dbg: make iwl_fw_dbg_no_trig_window trigger agnostic

2018-10-01 Thread Luca Coelho
From: Sara Sharon 

As preparation for new trigger format, make the function
agnostic to the trigger fomat. Instead it gets the relevant
parameters - id and delay.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 0f09a2128ad2..bee7a938a721 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -154,12 +154,9 @@ iwl_fw_dbg_trigger_stop_conf_match(struct iwl_fw_runtime 
*fwrt,
 }
 
 static inline bool
-iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_dbg_trigger_tlv *trig)
+iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt, u32 id, u32 dis_ms)
 {
-   unsigned long wind_jiff =
-   msecs_to_jiffies(le16_to_cpu(trig->trig_dis_ms));
-   u32 id = le32_to_cpu(trig->id);
+   unsigned long wind_jiff = msecs_to_jiffies(dis_ms);
 
/* If this is the first event checked, jump to update start ts */
if (fwrt->dump.non_collect_ts_start[id] &&
@@ -179,7 +176,8 @@ iwl_fw_dbg_trigger_check_stop(struct iwl_fw_runtime *fwrt,
if (wdev && !iwl_fw_dbg_trigger_vif_match(trig, wdev))
return false;
 
-   if (iwl_fw_dbg_no_trig_window(fwrt, trig)) {
+   if (iwl_fw_dbg_no_trig_window(fwrt, le32_to_cpu(trig->id),
+ le16_to_cpu(trig->trig_dis_ms))) {
IWL_WARN(fwrt, "Trigger %d occurred while no-collect window.\n",
 trig->id);
return false;
-- 
2.19.0



[PATCH 02/16] iwlwifi: add dump collection in case alive flow fails

2018-10-01 Thread Luca Coelho
From: Shahar S Matityahu 

Trigger dump collection if the alive flow fails, regardless of the
reason.

Signed-off-by: Shahar S Matityahu 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 27 ++-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |  1 +
 .../wireless/intel/iwlwifi/fw/error-dump.h|  2 ++
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  2 ++
 6 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 146ec5065825..a049367ac08a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -973,6 +973,30 @@ const struct iwl_fw_dump_desc iwl_dump_desc_assert = {
 };
 IWL_EXPORT_SYMBOL(iwl_dump_desc_assert);
 
+void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
+{
+   struct iwl_fw_dump_desc *iwl_dump_desc_no_alive =
+   kmalloc(sizeof(*iwl_dump_desc_no_alive), GFP_KERNEL);
+
+   if (!iwl_dump_desc_no_alive)
+   return;
+
+   iwl_dump_desc_no_alive->trig_desc.type =
+   cpu_to_le32(FW_DBG_TRIGGER_NO_ALIVE);
+   iwl_dump_desc_no_alive->len = 0;
+
+   if (WARN_ON(fwrt->dump.desc))
+   iwl_fw_free_dump_desc(fwrt);
+
+   IWL_WARN(fwrt, "Collecting data: trigger %d fired.\n",
+FW_DBG_TRIGGER_NO_ALIVE);
+
+   fwrt->dump.desc = iwl_dump_desc_no_alive;
+   iwl_fw_error_dump(fwrt);
+   clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, >status);
+}
+IWL_EXPORT_SYMBOL(iwl_fw_alive_error_dump);
+
 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
const struct iwl_fw_dump_desc *desc,
const struct iwl_fw_dbg_trigger_tlv *trigger)
@@ -998,7 +1022,8 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
fwrt->smem_cfg.num_lmacs)
return -EIO;
 
-   if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, >status))
+   if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, >status) ||
+   test_bit(IWL_FWRT_STATUS_WAIT_ALIVE, >status))
return -EBUSY;
 
if (WARN_ON(fwrt->dump.desc))
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 5b087fc4f380..0f09a2128ad2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -368,4 +368,5 @@ static inline void iwl_fw_resume_timestamp(struct 
iwl_fw_runtime *fwrt) {}
 
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
+void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
 #endif  /* __iwl_fw_dbg_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h 
b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
index 6d3ef331b7d5..6fede174c664 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
@@ -328,6 +328,7 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
  * @FW_DBG_TDLS: trigger log collection upon TDLS related events.
  * @FW_DBG_TRIGGER_TX_STATUS: trigger log collection upon tx status when
  *  the firmware sends a tx reply.
+ * @FW_DBG_TRIGGER_NO_ALIVE: trigger log collection if alive flow fails
  */
 enum iwl_fw_dbg_trigger {
FW_DBG_TRIGGER_INVALID = 0,
@@ -345,6 +346,7 @@ enum iwl_fw_dbg_trigger {
FW_DBG_TRIGGER_TX_LATENCY,
FW_DBG_TRIGGER_TDLS,
FW_DBG_TRIGGER_TX_STATUS,
+   FW_DBG_TRIGGER_NO_ALIVE,
 
/* must be last */
FW_DBG_TRIGGER_MAX,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h 
b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 9ed5819defaf..ac6db5e2b3d0 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -88,6 +88,7 @@ struct iwl_fwrt_shared_mem_cfg {
 
 enum iwl_fw_runtime_status {
IWL_FWRT_STATUS_DUMPING = 0,
+   IWL_FWRT_STATUS_WAIT_ALIVE,
 };
 
 /**
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 3fee304cddbb..c5df73231ba3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -299,6 +299,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm 
*mvm,
enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;
static const u16 alive_cmd[] = { MVM_ALIVE };
 
+   set_bit(IWL_FWRT_STATUS_WAIT_ALIVE, >fwrt.status);
if (ucode_type == IWL_UCODE_REGULAR &&
iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
!(fw_has_capa(>fw->ucode_capa,
@@ -369,6 +370,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm 
*mvm,
atomic_set(>mac80211_queue_sto

[PATCH 08/16] iwlwifi: bump firmware API version for 9000 and 22000 series devices

2018-10-01 Thread Luca Coelho
From: Johannes Berg 

Bump the firmware API version to 41.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index a8acc755a02c..da5d5f9b2573 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -56,7 +56,7 @@
 #include "iwl-config.h"
 
 /* Highest firmware API version supported */
-#define IWL_22000_UCODE_API_MAX38
+#define IWL_22000_UCODE_API_MAX41
 
 /* Lowest firmware API version supported */
 #define IWL_22000_UCODE_API_MIN39
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index 37deaf4fd7b3..d55fd23cafe6 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -57,7 +57,7 @@
 #include "fw/file.h"
 
 /* Highest firmware API version supported */
-#define IWL9000_UCODE_API_MAX  38
+#define IWL9000_UCODE_API_MAX  41
 
 /* Lowest firmware API version supported */
 #define IWL9000_UCODE_API_MIN  30
-- 
2.19.0



[PATCH 05/16] iwlwifi: add fall through comment

2018-10-01 Thread Luca Coelho
From: Johannes Berg 

The fall-through to the MVM case is intended as we have to do
*something* to continue, and can't easily clean up. So we'll
just fail in mvm later, if this does happen.

Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 809f8daa5c10..ba41d23b4211 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1471,6 +1471,7 @@ static void iwl_req_fw_callback(const struct firmware 
*ucode_raw, void *context)
break;
default:
WARN(1, "Invalid fw type %d\n", fw->type);
+   /* fall through */
case IWL_FW_MVM:
op = _opmode_table[MVM_OP_MODE];
break;
-- 
2.19.0



[PATCH 04/16] iwlwifi: pcie gen2: check iwl_pcie_gen2_set_tb() return value

2018-10-01 Thread Luca Coelho
From: Johannes Berg 

If we use the iwl_pcie_gen2_set_tb() return value for BIT(),
we should validate that it's not going to be negative, so do
the check and bail out if we hit an error. We shouldn't, as
we check if it'll fit beforehand, but better be safe.

Fixes: ab6c644539e9 ("iwlwifi: pcie: copy TX functions to new transport")
Signed-off-by: Johannes Berg 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index ba9d37bed4c2..b71cf55480fc 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -438,6 +438,8 @@ static int iwl_pcie_gen2_tx_add_frags(struct iwl_trans 
*trans,
return -ENOMEM;
tb_idx = iwl_pcie_gen2_set_tb(trans, tfd, tb_phys,
  skb_frag_size(frag));
+   if (tb_idx < 0)
+   return tb_idx;
 
out_meta->tbs |= BIT(tb_idx);
}
-- 
2.19.0



[PATCH 10/16] iwlwifi: add debugfs to send host command

2018-10-01 Thread Luca Coelho
From: Shahar S Matityahu 

Add debugfs to send host command in mvm and fmac op modes.
Allows to send host command at runtime via send_hcmd debugfs file.
The command is received as a string that represents hex values.

The struct of the command is as follows:
[cmd_id][flags][length][data]
cmd_id and flags are 8 chars long each.
length is 4 chars long.
data is length * 2 chars long.

Signed-off-by: Shahar S Matityahu 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/fw/debugfs.c   | 64 +++
 1 file changed, 64 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c 
b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
index 1049bdfe1e69..3e120dd47305 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
@@ -258,11 +258,75 @@ static ssize_t iwl_dbgfs_timestamp_marker_read(struct 
iwl_fw_runtime *fwrt,
 
 FWRT_DEBUGFS_READ_WRITE_FILE_OPS(timestamp_marker, 16);
 
+struct hcmd_write_data {
+   __be32 cmd_id;
+   __be32 flags;
+   __be16 length;
+   u8 data[0];
+} __packed;
+
+static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char 
*buf,
+size_t count)
+{
+   size_t header_size = (sizeof(u32) * 2 + sizeof(u16)) * 2;
+   size_t data_size = (count - 1) / 2;
+   int ret;
+   struct hcmd_write_data *data;
+   struct iwl_host_cmd hcmd = {
+   .len = { 0, },
+   .data = { NULL, },
+   };
+
+   if (fwrt->ops && fwrt->ops->fw_running &&
+   !fwrt->ops->fw_running(fwrt->ops_ctx))
+   return -EIO;
+
+   if (count < header_size + 1 || count > 1024 * 4)
+   return -EINVAL;
+
+   data = kmalloc(data_size, GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   ret = hex2bin((u8 *)data, buf, data_size);
+   if (ret)
+   goto out;
+
+   hcmd.id = be32_to_cpu(data->cmd_id);
+   hcmd.flags = be32_to_cpu(data->flags);
+   hcmd.len[0] = be16_to_cpu(data->length);
+   hcmd.data[0] = data->data;
+
+   if (count != header_size + hcmd.len[0] * 2 + 1) {
+   IWL_ERR(fwrt,
+   "host command data size does not match header 
length\n");
+   ret = -EINVAL;
+   goto out;
+   }
+
+   if (fwrt->ops && fwrt->ops->send_hcmd)
+   ret = fwrt->ops->send_hcmd(fwrt->ops_ctx, );
+   else
+   ret = -EPERM;
+
+   if (ret < 0)
+   goto out;
+
+   if (hcmd.flags & CMD_WANT_SKB)
+   iwl_free_resp();
+out:
+   kfree(data);
+   return ret ?: count;
+}
+
+FWRT_DEBUGFS_WRITE_FILE_OPS(send_hcmd, 512);
+
 int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
struct dentry *dbgfs_dir)
 {
INIT_DELAYED_WORK(>timestamp.wk, iwl_fw_timestamp_marker_wk);
FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, 0200);
+   FWRT_DEBUGFS_ADD_FILE(send_hcmd, dbgfs_dir, 0200);
return 0;
 err:
IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n");
-- 
2.19.0



[PATCH 01/16] iwlwifi: pcie: avoid empty free RB queue

2018-10-01 Thread Luca Coelho
From: Shaul Triebitz 

If all free RB queues are empty, the driver will never restock the
free RB queue.  That's because the restocking happens in the Rx flow,
and if the free queue is empty there will be no Rx.

Although there's a background worker (a.k.a. allocator) allocating
memory for RBs so that the Rx handler can restock them, the worker may
run only after the free queue has become empty (and then it is too
late for restocking as explained above).

There is a solution for that called 'emergency': If the number of used
RB's reaches half the amount of all RB's, the Rx handler will not wait
for the allocator but immediately allocate memory for the used RB's
and restock the free queue.

But, since the used RB's is per queue, it may happen that the used
RB's are spread between the queues such that the emergency check will
fail for each of the queues
(and still run out of RBs, causing the above symptom).

To fix it, move to emergency mode if the sum of *all* used RBs (for
all Rx queues) reaches half the amount of all RB's

Signed-off-by: Shaul Triebitz 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 32 +---
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index d519e7ebdbe8..e965cc588850 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1144,6 +1144,14 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
kfree(trans_pcie->rxq);
 }
 
+static void iwl_pcie_rx_move_to_allocator(struct iwl_rxq *rxq,
+ struct iwl_rb_allocator *rba)
+{
+   spin_lock(>lock);
+   list_splice_tail_init(>rx_used, >rbd_empty);
+   spin_unlock(>lock);
+}
+
 /*
  * iwl_pcie_rx_reuse_rbd - Recycle used RBDs
  *
@@ -1175,9 +1183,7 @@ static void iwl_pcie_rx_reuse_rbd(struct iwl_trans *trans,
if ((rxq->used_count % RX_CLAIM_REQ_ALLOC) == RX_POST_REQ_ALLOC) {
/* Move the 2 RBDs to the allocator ownership.
 Allocator has another 6 from pool for the request completion*/
-   spin_lock(>lock);
-   list_splice_tail_init(>rx_used, >rbd_empty);
-   spin_unlock(>lock);
+   iwl_pcie_rx_move_to_allocator(rxq, rba);
 
atomic_inc(>req_pending);
queue_work(rba->alloc_wq, >rx_alloc);
@@ -1400,10 +1406,18 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, 
int queue)
IWL_DEBUG_RX(trans, "Q %d: HW = SW = %d\n", rxq->id, r);
 
while (i != r) {
+   struct iwl_rb_allocator *rba = _pcie->rba;
struct iwl_rx_mem_buffer *rxb;
-
-   if (unlikely(rxq->used_count == rxq->queue_size / 2))
+   /* number of RBDs still waiting for page allocation */
+   u32 rb_pending_alloc =
+   atomic_read(_pcie->rba.req_pending) *
+   RX_CLAIM_REQ_ALLOC;
+
+   if (unlikely(rb_pending_alloc >= rxq->queue_size / 2 &&
+!emergency)) {
+   iwl_pcie_rx_move_to_allocator(rxq, rba);
emergency = true;
+   }
 
rxb = iwl_pcie_get_rxb(trans, rxq, i);
if (!rxb)
@@ -1425,17 +1439,13 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, 
int queue)
iwl_pcie_rx_allocator_get(trans, rxq);
 
if (rxq->used_count % RX_CLAIM_REQ_ALLOC == 0 && !emergency) {
-   struct iwl_rb_allocator *rba = _pcie->rba;
-
/* Add the remaining empty RBDs for allocator use */
-   spin_lock(>lock);
-   list_splice_tail_init(>rx_used, >rbd_empty);
-   spin_unlock(>lock);
+   iwl_pcie_rx_move_to_allocator(rxq, rba);
} else if (emergency) {
count++;
if (count == 8) {
count = 0;
-   if (rxq->used_count < rxq->queue_size / 3)
+   if (rb_pending_alloc < rxq->queue_size / 3)
emergency = false;
 
rxq->read = i;
-- 
2.19.0



[PATCH 03/16] iwlwifi: nvm: get num of hw addresses from firmware

2018-10-01 Thread Luca Coelho
From: Naftali Goldstein 

With NICs that don't read the NVM directly and instead rely on getting
the relevant data from the firmware, the number of reserved MAC
addresses was not added to the API. This caused the driver to assume
there is only one address which results in all interfaces getting the
same address. Update the API to fix this.

While at it, fix-up the comments with firmware api names to actually
match what we have in the firmware.

Fixes: e9e1ba3dbf00 ("iwlwifi: mvm: support getting nvm data from firmware")
Signed-off-by: Naftali Goldstein 
Signed-off-by: Luca Coelho 
---
 .../net/wireless/intel/iwlwifi/fw/api/nvm-reg.h| 14 +++---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 10 +-
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index 6c5338364794..d22c1eefba6a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -165,7 +165,7 @@ struct iwl_nvm_access_resp {
  */
 struct iwl_nvm_get_info {
__le32 reserved;
-} __packed; /* GRP_REGULATORY_NVM_GET_INFO_CMD_S_VER_1 */
+} __packed; /* REGULATORY_NVM_GET_INFO_CMD_API_S_VER_1 */
 
 /**
  * enum iwl_nvm_info_general_flags - flags in NVM_GET_INFO resp
@@ -180,14 +180,14 @@ enum iwl_nvm_info_general_flags {
  * @flags: bit 0: 1 - empty, 0 - non-empty
  * @nvm_version: nvm version
  * @board_type: board type
- * @reserved: reserved
+ * @n_hw_addrs: number of reserved MAC addresses
  */
 struct iwl_nvm_get_info_general {
__le32 flags;
__le16 nvm_version;
u8 board_type;
-   u8 reserved;
-} __packed; /* GRP_REGULATORY_NVM_GET_INFO_GENERAL_S_VER_1 */
+   u8 n_hw_addrs;
+} __packed; /* REGULATORY_NVM_GET_INFO_GENERAL_S_VER_2 */
 
 /**
  * enum iwl_nvm_mac_sku_flags - flags in _nvm_get_info_sku
@@ -231,7 +231,7 @@ struct iwl_nvm_get_info_sku {
 struct iwl_nvm_get_info_phy {
__le32 tx_chains;
__le32 rx_chains;
-} __packed; /* GRP_REGULATORY_NVM_GET_INFO_PHY_SKU_SECTION_S_VER_1 */
+} __packed; /* REGULATORY_NVM_GET_INFO_PHY_SKU_SECTION_S_VER_1 */
 
 #define IWL_NUM_CHANNELS (51)
 
@@ -245,7 +245,7 @@ struct iwl_nvm_get_info_regulatory {
__le32 lar_enabled;
__le16 channel_profile[IWL_NUM_CHANNELS];
__le16 reserved;
-} __packed; /* GRP_REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_1 */
+} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_1 */
 
 /**
  * struct iwl_nvm_get_info_rsp - response to get NVM data
@@ -259,7 +259,7 @@ struct iwl_nvm_get_info_rsp {
struct iwl_nvm_get_info_sku mac_sku;
struct iwl_nvm_get_info_phy phy_sku;
struct iwl_nvm_get_info_regulatory regulatory;
-} __packed; /* GRP_REGULATORY_NVM_GET_INFO_CMD_RSP_S_VER_2 */
+} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_3 */
 
 /**
  * struct iwl_nvm_access_complete_cmd - NVM_ACCESS commands are completed
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 137dedc844ad..4ed8fb49a091 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -1350,6 +1350,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
bool lar_fw_supported = !iwlwifi_mod_params.lar_disable &&
fw_has_capa(>ucode_capa,
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
+   bool empty_otp;
u32 mac_flags;
u32 sbands_flags = 0;
 
@@ -1365,7 +1366,9 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
}
 
rsp = (void *)hcmd.resp_pkt->data;
-   if (le32_to_cpu(rsp->general.flags) & NVM_GENERAL_FLAGS_EMPTY_OTP)
+   empty_otp = !!(le32_to_cpu(rsp->general.flags) &
+  NVM_GENERAL_FLAGS_EMPTY_OTP);
+   if (empty_otp)
IWL_INFO(trans, "OTP is empty\n");
 
nvm = kzalloc(sizeof(*nvm) +
@@ -1389,6 +1392,11 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
 
/* Initialize general data */
nvm->nvm_version = le16_to_cpu(rsp->general.nvm_version);
+   nvm->n_hw_addrs = rsp->general.n_hw_addrs;
+   if (nvm->n_hw_addrs == 0)
+   IWL_WARN(trans,
+"Firmware declares no reserved mac addresses. OTP is 
empty: %d\n",
+empty_otp);
 
/* Initialize MAC sku data */
mac_flags = le32_to_cpu(rsp->mac_sku.mac_sku_flags);
-- 
2.19.0



[PATCH 16/16] iwlwifi: dbg: make trigger functions type agnostic

2018-10-01 Thread Luca Coelho
From: Sara Sharon 

As preparation for new trigger type, make iwl_fw_dbg_collect_desc
agnostic to the trigger structure.

Signed-off-by: Sara Sharon 
Signed-off-by: Luca Coelho 
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c  | 37 ++--
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h  |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c |  2 +-
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 1ae04577aed3..f44c716b1130 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -998,14 +998,9 @@ void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
 IWL_EXPORT_SYMBOL(iwl_fw_alive_error_dump);
 
 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
-   const struct iwl_fw_dump_desc *desc,
-   const struct iwl_fw_dbg_trigger_tlv *trigger)
+   const struct iwl_fw_dump_desc *desc, void *trigger,
+   unsigned int delay)
 {
-   unsigned int delay = 0;
-
-   if (trigger)
-   delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay));
-
/*
 * If the loading of the FW completed successfully, the next step is to
 * get the SMEM config data. Thus, if fwrt->smem_cfg.num_lmacs is non
@@ -1047,31 +1042,35 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
   struct iwl_fw_dbg_trigger_tlv *trigger)
 {
struct iwl_fw_dump_desc *desc;
+   unsigned int delay = 0;
 
-   if (trigger && !le16_to_cpu(trigger->occurrences))
-   return 0;
+   if (trigger) {
+   u16 occurrences = le16_to_cpu(trigger->occurrences) - 1;
 
-   if (trigger && trigger->flags & IWL_FW_DBG_FORCE_RESTART) {
-   IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", trig);
-   iwl_force_nmi(fwrt->trans);
-   return 0;
+   if (!le16_to_cpu(trigger->occurrences))
+   return 0;
+
+   if (trigger->flags & IWL_FW_DBG_FORCE_RESTART) {
+   IWL_WARN(fwrt, "Force restart: trigger %d fired.\n",
+trig);
+   iwl_force_nmi(fwrt->trans);
+   return 0;
+   }
+
+   trigger->occurrences = cpu_to_le16(occurrences);
+   delay = le16_to_cpu(trigger->trig_dis_ms);
}
 
desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
if (!desc)
return -ENOMEM;
 
-   if (trigger) {
-   u16 occurrences = le16_to_cpu(trigger->occurrences) - 1;
-
-   trigger->occurrences = cpu_to_le16(occurrences);
-   }
 
desc->len = len;
desc->trig_desc.type = cpu_to_le32(trig);
memcpy(desc->trig_desc.data, str, len);
 
-   return iwl_fw_dbg_collect_desc(fwrt, desc, trigger);
+   return iwl_fw_dbg_collect_desc(fwrt, desc, trigger, delay);
 }
 IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 701bac1aba4d..d9578dcec24c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -107,7 +107,7 @@ static inline void iwl_fw_free_dump_desc(struct 
iwl_fw_runtime *fwrt)
 void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
const struct iwl_fw_dump_desc *desc,
-   const struct iwl_fw_dbg_trigger_tlv *trigger);
+   void *trigger, unsigned int delay);
 int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
   enum iwl_fw_dbg_trigger trig,
   const char *str, size_t len,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 3acf512bad47..0e2092526fae 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1240,7 +1240,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool 
fw_error)
 */
if (!mvm->fw_restart && fw_error) {
iwl_fw_dbg_collect_desc(>fwrt, _dump_desc_assert,
-   NULL);
+   NULL, 0);
} else if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, >status)) {
struct iwl_mvm_reprobe *reprobe;
 
-- 
2.19.0



  1   2   3   4   5   6   7   8   9   10   >