[PATCH 07/10] mac80211: add api to start ba session timer expired flow

2017-08-05 Thread Luca Coelho
From: Naftali Goldstein <naftali.goldst...@intel.com>

Some drivers handle rx buffer reordering internally (and by extension
handle also the rx ba session timer internally), but do not ofload the
addba/delba negotiation.
Add an api for these drivers to properly tear-down the ba session,
including sending a delba.

Signed-off-by: Naftali Goldstein <naftali.goldst...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 include/net/mac80211.h | 15 +++
 net/mac80211/agg-rx.c  | 22 +-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index b2b5419467cc..64f5abb02030 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -5499,6 +5499,21 @@ static inline void 
ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif,
ieee80211_manage_rx_ba_offl(vif, addr, tid + IEEE80211_NUM_TIDS);
 }
 
+/**
+ * ieee80211_rx_ba_timer_expired - stop a Rx BA session due to timeout
+ *
+ * Some device drivers do not offload AddBa/DelBa negotiation, but handle rx
+ * buffer reording internally, and therefore also handle the session timer.
+ *
+ * Trigger the timeout flow, which sends a DelBa.
+ *
+ * @vif:  ieee80211_vif pointer from the add_interface callback
+ * @addr: station mac address
+ * @tid: the rx tid
+ */
+void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
+  const u8 *addr, unsigned int bit);
+
 /* Rate control API */
 
 /**
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 8708cbe8af5b..34599bd38991 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -7,7 +7,7 @@
  * Copyright 2006-2007 Jiri Benc <jb...@suse.cz>
  * Copyright 2007, Michael Wu <flaming...@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015-2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -466,3 +466,23 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
rcu_read_unlock();
 }
 EXPORT_SYMBOL(ieee80211_manage_rx_ba_offl);
+
+void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
+  const u8 *addr, unsigned int bit)
+{
+   struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+   struct ieee80211_local *local = sdata->local;
+   struct sta_info *sta;
+
+   rcu_read_lock();
+   sta = sta_info_get_bss(sdata, addr);
+   if (!sta)
+   goto unlock;
+
+   set_bit(bit, sta->ampdu_mlme.tid_rx_timer_expired);
+   ieee80211_queue_work(>hw, >ampdu_mlme.work);
+
+ unlock:
+   rcu_read_unlock();
+}
+EXPORT_SYMBOL(ieee80211_rx_ba_timer_expired);
-- 
2.13.2



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

2017-08-05 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

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

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

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

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



[PATCH 02/10] mac80211: shorten debug prints using ht_dbg() to avoid warning

2017-08-05 Thread Luca Coelho
From: Sharon Dvir <sharon.d...@intel.com>

Invoking ht_dbg() with too long of a string will print a warning.
Shorten the messages while retaining the printed patameters.

Signed-off-by: Sharon Dvir <sharon.d...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 net/mac80211/agg-tx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index cbd48762256c..420486b5a1d9 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -436,7 +436,7 @@ static void sta_addba_resp_timer_expired(unsigned long data)
test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, _tx->state)) {
rcu_read_unlock();
ht_dbg(sta->sdata,
-  "timer expired on %pM tid %d but we are not (or no 
longer) expecting addBA response there\n",
+  "timer expired on %pM tid %d not expecting addBA 
response\n",
   sta->sta.addr, tid);
return;
}
@@ -639,7 +639,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta 
*pubsta, u16 tid,
time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] +
HT_AGG_RETRIES_PERIOD)) {
ht_dbg(sdata,
-  "BA request denied - waiting a grace period after %d 
failed requests on %pM tid %u\n",
+  "BA request denied - %d failed requests on %pM tid %u\n",
   sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid);
ret = -EBUSY;
goto err_unlock_sta;
-- 
2.13.2



[PATCH 01/10] mac80211: add MESH IE in the correct order

2017-08-05 Thread Luca Coelho
From: Liad Kaufman <liad.kauf...@intel.com>

VHT MESH support was added, but the order of the IEs
wasn't enforced. Fix that.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 net/mac80211/util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 259698de569f..6aef6793d052 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1436,7 +1436,7 @@ static int ieee80211_build_preq_ies_band(struct 
ieee80211_local *local,
WLAN_EID_SSID_LIST,
WLAN_EID_CHANNEL_USAGE,
WLAN_EID_INTERWORKING,
-   /* mesh ID can't happen here */
+   WLAN_EID_MESH_ID,
/* 60 GHz can't happen here right now */
};
noffset = ieee80211_ie_split(ie, ie_len,
-- 
2.13.2



[PATCH 15/24] iwlwifi: mvm: support fw reading empty OTP

2017-07-28 Thread Luca Coelho
From: Liad Kaufman <liad.kauf...@intel.com>

If the OTP is empty, the NVM_GET_INFO command returns
with flags' bit(0) on. This means the FW returns the
default values for working with. This is allowed, so
use this returned data.

Fixes: e9e1ba3dbf00 ("iwlwifi: mvm: support getting nvm data from firmware")
Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | 10 +-
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c|  7 ++-
 2 files changed, 11 insertions(+), 6 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 d4c01f3dce32..00bc7a25dece 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -164,8 +164,16 @@ struct iwl_nvm_get_info {
 } __packed; /* GRP_REGULATORY_NVM_GET_INFO_CMD_S_VER_1 */
 
 /**
+ * enum iwl_nvm_info_general_flags - flags in NVM_GET_INFO resp
+ * @NVM_GENERAL_FLAGS_EMPTY_OTP: 1 if OTP is empty
+ */
+enum iwl_nvm_info_general_flags {
+   NVM_GENERAL_FLAGS_EMPTY_OTP = BIT(0),
+};
+
+/**
  * struct iwl_nvm_get_info_general - general NVM data
- * @flags: 1 - empty, 0 - valid
+ * @flags: bit 0: 1 - empty, 0 - non-empty
  * @nvm_version: nvm version
  * @board_type: board type
  * @reserved: reserved
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index dac7e542a190..5cc749261ce3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -576,11 +576,8 @@ int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm)
}
 
rsp = (void *)hcmd.resp_pkt->data;
-   if (le32_to_cpu(rsp->general.flags)) {
-   IWL_ERR(mvm, "Invalid NVM data from FW\n");
-   ret = -EINVAL;
-   goto out;
-   }
+   if (le32_to_cpu(rsp->general.flags) & NVM_GENERAL_FLAGS_EMPTY_OTP)
+   IWL_INFO(mvm, "OTP is empty\n");
 
mvm->nvm_data = kzalloc(sizeof(*mvm->nvm_data) +
sizeof(struct ieee80211_channel) *
-- 
2.13.2



[PATCH 18/24] iwlwifi: pcie: rename iwl_trans_check_hw_rf_kill() to pcie

2017-07-28 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Rename this function to the more appropriate iwl_pcie_check_hw_rf_kill()
since it's only a function in the pcie code and cannot be called from
any other place.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c| 4 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h   | 2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 4 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c  | 8 
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index f16c1bb9bf94..87712aeac31f 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -805,11 +805,11 @@ static int iwl_pci_resume(struct device *device)
/*
 * Enable rfkill interrupt (in order to keep track of the rfkill
 * status). Must be locked to avoid processing a possible rfkill
-* interrupt while in iwl_trans_check_hw_rf_kill().
+* interrupt while in iwl_pcie_check_hw_rf_kill().
 */
mutex_lock(_pcie->mutex);
iwl_enable_rfkill_int(trans);
-   iwl_trans_check_hw_rf_kill(trans);
+   iwl_pcie_check_hw_rf_kill(trans);
mutex_unlock(_pcie->mutex);
 
return 0;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index fa315d84e98e..a8ffd4ca8cd8 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -791,7 +791,7 @@ void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool 
enable);
 void iwl_pcie_apm_config(struct iwl_trans *trans);
 int iwl_pcie_prepare_card_hw(struct iwl_trans *trans);
 void iwl_pcie_synchronize_irqs(struct iwl_trans *trans);
-bool iwl_trans_check_hw_rf_kill(struct iwl_trans *trans);
+bool iwl_pcie_check_hw_rf_kill(struct iwl_trans *trans);
 void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans,
   bool was_in_rfkill);
 void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index b84b78293e7b..c59f4581e972 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -307,7 +307,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
mutex_lock(_pcie->mutex);
 
/* If platform's RF_KILL switch is NOT set to KILL */
-   hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
+   hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
if (hw_rfkill && !run_in_rfkill) {
ret = -ERFKILL;
goto out;
@@ -340,7 +340,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
goto out;
 
/* re-check RF-Kill state since we may have missed the interrupt */
-   hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
+   hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
if (hw_rfkill && !run_in_rfkill)
ret = -ERFKILL;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 92b3a55d0fbc..3fac3f29a139 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -986,7 +986,7 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans 
*trans,
   _ucode_section);
 }
 
-bool iwl_trans_check_hw_rf_kill(struct iwl_trans *trans)
+bool iwl_pcie_check_hw_rf_kill(struct iwl_trans *trans)
 {
struct iwl_trans_pcie *trans_pcie =  IWL_TRANS_GET_PCIE_TRANS(trans);
bool hw_rfkill = iwl_is_rfkill_set(trans);
@@ -1252,7 +1252,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans 
*trans,
mutex_lock(_pcie->mutex);
 
/* If platform's RF_KILL switch is NOT set to KILL */
-   hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
+   hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
if (hw_rfkill && !run_in_rfkill) {
ret = -ERFKILL;
goto out;
@@ -1300,7 +1300,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans 
*trans,
ret = iwl_pcie_load_given_ucode(trans, fw);
 
/* re-check RF-Kill state since we may have missed the interrupt */
-   hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
+   hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
if (hw_rfkill && !run_in_rfkill)
ret = -ERFKILL;
 
@@ -1663,7 +1663,7 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans 
*trans, bool low_power)
trans_pcie->is_down = false;
 
   

[PATCH 17/24] iwlwifi: mvm: add compile-time option to disable EBS

2017-07-28 Thread Luca Coelho
From: "Zamir, Roee" <roee.za...@intel.com>

For testing purposes, we may want to disable EBS scans at compile time.

Signed-off-by: Roee Zamir <roee.za...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 1 +
 drivers/net/wireless/intel/iwlwifi/mvm/scan.c  | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
index 21845034d80d..a922a351c916 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
@@ -140,5 +140,6 @@
 #define IWL_MVM_RS_TPC_SR_FORCE_INCREASE   75  /* percent */
 #define IWL_MVM_RS_TPC_SR_NO_INCREASE  85  /* percent */
 #define IWL_MVM_RS_TPC_TX_POWER_STEP   3
+#define IWL_MVM_ENABLE_EBS 1
 
 #endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index cb44e4114655..50983615dce6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -743,7 +743,7 @@ static inline bool iwl_mvm_scan_use_ebs(struct iwl_mvm *mvm,
 *  4. it's not a p2p find operation.
 */
return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
-   mvm->last_ebs_successful &&
+   mvm->last_ebs_successful && IWL_MVM_ENABLE_EBS &&
vif->type != NL80211_IFTYPE_P2P_DEVICE);
 }
 
-- 
2.13.2



[PATCH v2 12/19] iwlwifi: mvm: support new beacon template command

2017-08-09 Thread Luca Coelho
From: Haim Dreyfuss <haim.dreyf...@intel.com>

Support a new version of the beacon template command. This replaces v8
of the command, which was missing the rate code.  Also, export rate
decision logic to a separate function.

Signed-off-by: Haim Dreyfuss <haim.dreyf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/tx.h| 17 +---
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 47 ---
 3 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
index 2909d1ed89cf..4928310ddd31 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
@@ -786,13 +786,20 @@ struct iwl_mac_beacon_cmd_v7 {
struct ieee80211_hdr frame[0];
 } __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
 
+enum iwl_mac_beacon_flags {
+   IWL_MAC_BEACON_CCK  = BIT(8),
+   IWL_MAC_BEACON_ANT_A= BIT(9),
+   IWL_MAC_BEACON_ANT_B= BIT(10),
+   IWL_MAC_BEACON_ANT_C= BIT(11),
+};
+
 /**
  * struct iwl_mac_beacon_cmd - beacon template command with offloaded CSA
- * @byte_cnt: byte count of the beacon frame
- * @flags: for future use
+ * @byte_cnt: byte count of the beacon frame.
+ * @flags: least significant byte for rate code. The most significant byte
+ * is  iwl_mac_beacon_flags.
  * @reserved: reserved
- * @template_id: currently equal to the mac context id of the coresponding
- *  mac.
+ * @template_id: currently equal to the mac context id of the coresponding mac.
  * @tim_idx: the offset of the tim IE in the beacon
  * @tim_size: the length of the tim IE
  * @ecsa_offset: offset to the ECSA IE if present
@@ -809,7 +816,7 @@ struct iwl_mac_beacon_cmd {
__le32 ecsa_offset;
__le32 csa_offset;
struct ieee80211_hdr frame[0];
-} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_8 */
+} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_9 */
 
 struct iwl_beacon_notif {
struct iwl_mvm_tx_resp beacon_notify_hdr;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h 
b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 0fa8c473f1e2..d933aa324ffe 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -260,6 +260,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_STA_TYPE  = (__force 
iwl_ucode_tlv_api_t)30,
IWL_UCODE_TLV_API_NAN2_VER2 = (__force 
iwl_ucode_tlv_api_t)31,
/* API Set 1 */
+   IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE   = (__force 
iwl_ucode_tlv_api_t)34,
IWL_UCODE_TLV_API_NEW_RX_STATS  = (__force 
iwl_ucode_tlv_api_t)35,
 
NUM_IWL_UCODE_TLV_API
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 8fe955d58c6e..cb4e311b059f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -923,6 +923,19 @@ static u32 iwl_mvm_find_ie_offset(u8 *beacon, u8 eid, u32 
frame_size)
return ie - beacon;
 }
 
+static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
+  struct ieee80211_vif *vif)
+{
+   u8 rate;
+
+   if (info->band == NL80211_BAND_5GHZ || vif->p2p)
+   rate = IWL_FIRST_OFDM_RATE;
+   else
+   rate = IWL_FIRST_CCK_RATE;
+
+   return rate;
+}
+
 static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct sk_buff *beacon,
@@ -930,7 +943,8 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
 {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_tx_info *info;
-   u32 rate, tx_flags;
+   u8 rate;
+   u32 tx_flags;
 
info = IEEE80211_SKB_CB(beacon);
 
@@ -955,14 +969,12 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
RATE_MCS_ANT_POS);
 
-   if (info->band == NL80211_BAND_5GHZ || vif->p2p) {
-   rate = IWL_FIRST_OFDM_RATE;
-   } else {
-   rate = IWL_FIRST_CCK_RATE;
-   tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
-   }
+   rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
 
tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
+   if (rate == IWL_FIRST_CCK_RATE)
+   tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
+
 }
 
 static int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
@@ -1033,19 +1045,27 @@ static int iwl_mvm_mac_ctxt_send_beacon_v7(struct 
iwl_mvm *mvm,
 

[PATCH 1/2] mac80211: add api to start ba session timer expired flow

2017-08-09 Thread Luca Coelho
From: Naftali Goldstein <naftali.goldst...@intel.com>

Some drivers handle rx buffer reordering internally (and by extension
handle also the rx ba session timer internally), but do not ofload the
addba/delba negotiation.
Add an api for these drivers to properly tear-down the ba session,
including sending a delba.

Signed-off-by: Naftali Goldstein <naftali.goldst...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 include/net/mac80211.h | 15 +++
 net/mac80211/agg-rx.c  | 22 +-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index b2b5419467cc..f8149ca192b4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -5499,6 +5499,21 @@ static inline void 
ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif,
ieee80211_manage_rx_ba_offl(vif, addr, tid + IEEE80211_NUM_TIDS);
 }
 
+/**
+ * ieee80211_rx_ba_timer_expired - stop a Rx BA session due to timeout
+ *
+ * Some device drivers do not offload AddBa/DelBa negotiation, but handle rx
+ * buffer reording internally, and therefore also handle the session timer.
+ *
+ * Trigger the timeout flow, which sends a DelBa.
+ *
+ * @vif:  ieee80211_vif pointer from the add_interface callback
+ * @addr: station mac address
+ * @tid: the rx tid
+ */
+void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
+  const u8 *addr, unsigned int tid);
+
 /* Rate control API */
 
 /**
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 8708cbe8af5b..2b36eff5d97e 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -7,7 +7,7 @@
  * Copyright 2006-2007 Jiri Benc <jb...@suse.cz>
  * Copyright 2007, Michael Wu <flaming...@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015-2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -466,3 +466,23 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
rcu_read_unlock();
 }
 EXPORT_SYMBOL(ieee80211_manage_rx_ba_offl);
+
+void ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif,
+  const u8 *addr, unsigned int tid)
+{
+   struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+   struct ieee80211_local *local = sdata->local;
+   struct sta_info *sta;
+
+   rcu_read_lock();
+   sta = sta_info_get_bss(sdata, addr);
+   if (!sta)
+   goto unlock;
+
+   set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired);
+   ieee80211_queue_work(>hw, >ampdu_mlme.work);
+
+ unlock:
+   rcu_read_unlock();
+}
+EXPORT_SYMBOL(ieee80211_rx_ba_timer_expired);
-- 
2.13.2



[PATCH 2/2] iwlwifi: mvm: send delba upon rx ba session timeout

2017-08-09 Thread Luca Coelho
From: Naftali Goldstein <naftali.goldst...@intel.com>

When an RX block-ack session times out, the firmware, which offloads
RX reordering but not the BA session negotiation, stops the session
but doesn't send a DELBA.  This causes the the session to remain
active in the remote device, so no more BA sessions will be
established, causing a severe throughput degradation due to the lack
of aggregation.

Use the new ieee80211_rx_ba_timer_expired API when the ba session timer
expires, since this will tear down the ba session and also send a delba.

The previous API used is intended for drivers that offload the
addba/delba negotiation, but not the rx reordering, while our driver
does the opposite.

This patch depends on "mac80211: add api to start ba session timer
expired flow".

Signed-off-by: Naftali Goldstein <naftali.goldst...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index dcaef7c043ac..027ee5e72172 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -291,8 +291,8 @@ static void iwl_mvm_rx_agg_session_expired(unsigned long 
data)
goto unlock;
 
mvm_sta = iwl_mvm_sta_from_mac80211(sta);
-   ieee80211_stop_rx_ba_session_offl(mvm_sta->vif,
- sta->addr, ba_data->tid);
+   ieee80211_rx_ba_timer_expired(mvm_sta->vif,
+ sta->addr, ba_data->tid);
 unlock:
rcu_read_unlock();
 }
-- 
2.13.2



[PATCH 0/2] iwlwifi: one more fix intended for 4.13 2017-08-09

2017-08-09 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

Hi,

This is the mac80211+iwlwifi fix we talked about earlier.  As I
mentioned, the iwlwifi patch fixes a severe degradation of throughput
in the 9000 device series, due to a BA-session getting stuck and the
lack of future aggregation.  The mac80211 patch adds a new callback
that allows us to solve this problem.

As agreed, I'm planning to apply this to my tree and send a
pull-request containing both patches.

Please review and let me know if there are any issues.

Cheers,
Luca.


Naftali Goldstein (2):
  mac80211: add api to start ba session timer expired flow
  iwlwifi: mvm: send delba upon rx ba session timeout

 drivers/net/wireless/intel/iwlwifi/mvm/sta.c |  4 ++--
 include/net/mac80211.h   | 15 +++
 net/mac80211/agg-rx.c| 22 +-
 3 files changed, 38 insertions(+), 3 deletions(-)

-- 
2.13.2



[PATCH v2 4/19] iwlwifi: mvm: add debugfs to force CT-kill

2017-08-09 Thread Luca Coelho
From: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>

CT-kill is a thermal-based "RF-kill", which disables the NIC
completely if the temperature gets too high, in order to avoid damage.

Add a debugfs entry to simulate high temperatures, in order to test
CT-kill flows in the driver without having to physically heat the
device up.

Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 14 ++
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/tt.c  |  2 +-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index 29f1d1807415..0b5cae54b86b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -114,6 +114,18 @@ static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm 
*mvm, char *buf,
return ret ?: count;
 }
 
+static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf,
+   size_t count, loff_t *ppos)
+{
+   if (!iwl_mvm_firmware_running(mvm) ||
+   mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
+   return -EIO;
+
+   iwl_mvm_enter_ctkill(mvm);
+
+   return count;
+}
+
 static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
size_t count, loff_t *ppos)
 {
@@ -1641,6 +1653,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
 /* Device wide debugfs entries */
 MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget);
 MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8);
+MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8);
 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
 MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8);
@@ -1828,6 +1841,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct 
dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, S_IWUSR);
+   MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 8b6238e1c7ea..a6983042d3b8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1755,6 +1755,7 @@ void iwl_mvm_thermal_exit(struct iwl_mvm *mvm);
 void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
 int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp);
 void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
+void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm);
 int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm);
 int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 3f143402cf7f..8876c2abc440 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -71,7 +71,7 @@
 
 #define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUTHZ
 
-static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
+void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
 {
struct iwl_mvm_tt_mgmt *tt = >thermal_throttle;
u32 duration = tt->params.ct_kill_duration;
-- 
2.13.2



pull-request: iwlwifi 2017-08-09

2017-08-09 Thread Luca Coelho
Hi Kalle,

Here is the third set of fixes for 4.13.  More details in the tag
description.

This includes both series I sent out, the first one, with v2 of the
second patch, with an improved commit message, and the second one, which
contains the mac80211 patch as well.

I have sent this out before and kbuildbot didn't find any issues. 
Please let me know if there are any issues.

Cheers,
Luca.


The following changes since commit 368bd88ebb64cabe4a1ec727659214bb8d693707:

  Merge tag 'iwlwifi-for-kalle-2017-08-02' of 
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes (2017-08-03 
11:01:11 +0300)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git 
tags/iwlwifi-for-kalle-2018-08-09

for you to fetch changes up to 20fc690f38d17b8f961101a477a9aa0841fb6e20:

  iwlwifi: mvm: send delba upon rx ba session timeout (2017-08-09 10:05:01 
+0300)


Some more fixes for 4.13

* Fix a memory leak in the SAR code;
* Fix a stuck queue case in AP mode;
* Convert a WARN to a simple debug in a legitimate race case (from
  which we can recover);
* Fix a severe throughput aggregation on 9000-family devices due to
  aggregation issues.


Avraham Stern (1):
  iwlwifi: mvm: start mac queues when deferred tx frames are purged

Christophe Jaillet (1):
  iwlwifi: mvm: Fix a memory leak in an error handling path in 
'iwl_mvm_sar_get_wgds_table()'

Emmanuel Grumbach (1):
  iwlwifi: mvm: don't WARN when a legit race happens in A-MPDU

Naftali Goldstein (2):
  mac80211: add api to start ba session timer expired flow
  iwlwifi: mvm: send delba upon rx ba session timeout

 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  6 --
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 10 ++
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  |  4 ++--
 include/net/mac80211.h| 15 +++
 net/mac80211/agg-rx.c | 22 +-
 6 files changed, 59 insertions(+), 10 deletions(-)

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


[PATCH v2 2/3] iwlwifi: mvm: start mac queues when deferred tx frames are purged

2017-08-09 Thread Luca Coelho
From: Avraham Stern <avraham.st...@intel.com>

In AP mode, if a station is removed just as it is adding a new stream,
the queue in question will remain stopped and no more TX will happen
in this queue, leading to connection failures and other problems.

This is because under DQA, when tx is deferred because a queue needs
to be allocated, the mac queue for that TID is stopped until the new
stream is added.  If at this point the station that this stream
belongs to is removed, all the deferred tx frames are purged, but the
mac queue is not restarted. As a result, all following tx on this
queue will not be transmitted.

Fix this by starting the relevant mac queues when the deferred tx
frames are purged.

Fixes: 24afba7690e4 ("iwlwifi: mvm: support bss dynamic alloc/dealloc of 
queues")
Signed-off-by: Avraham Stern <avraham.st...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index c7b1e58e3384..ce901be5fba8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2597,8 +2597,18 @@ static void iwl_mvm_purge_deferred_tx_frames(struct 
iwl_mvm *mvm,
spin_lock_bh(_sta->lock);
for (i = 0; i <= IWL_MAX_TID_COUNT; i++) {
tid_data = _sta->tid_data[i];
-   while ((skb = __skb_dequeue(_data->deferred_tx_frames)))
+
+   while ((skb = __skb_dequeue(_data->deferred_tx_frames))) {
+   struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+   /*
+* The first deferred frame should've stopped the MAC
+* queues, so we should never get a second deferred
+* frame for the RA/TID.
+*/
+   iwl_mvm_start_mac_queues(mvm, info->hw_queue);
ieee80211_free_txskb(mvm->hw, skb);
+   }
}
spin_unlock_bh(_sta->lock);
 }
-- 
2.13.2



[PATCH v3 12/19] iwlwifi: mvm: support new beacon template command

2017-08-09 Thread Luca Coelho
From: Haim Dreyfuss <haim.dreyf...@intel.com>

Support a new version of the beacon template command. This replaces v8
of the command, which was missing the rate code.  Also, export rate
decision logic to a separate function.

Signed-off-by: Haim Dreyfuss <haim.dreyf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---

In v3:
   * fix a bug in the CCK flag check

drivers/net/wireless/intel/iwlwifi/fw/api/tx.h| 17 +---
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 47 ---
 3 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h 
b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
index 2909d1ed89cf..4928310ddd31 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
@@ -786,13 +786,20 @@ struct iwl_mac_beacon_cmd_v7 {
struct ieee80211_hdr frame[0];
 } __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
 
+enum iwl_mac_beacon_flags {
+   IWL_MAC_BEACON_CCK  = BIT(8),
+   IWL_MAC_BEACON_ANT_A= BIT(9),
+   IWL_MAC_BEACON_ANT_B= BIT(10),
+   IWL_MAC_BEACON_ANT_C= BIT(11),
+};
+
 /**
  * struct iwl_mac_beacon_cmd - beacon template command with offloaded CSA
- * @byte_cnt: byte count of the beacon frame
- * @flags: for future use
+ * @byte_cnt: byte count of the beacon frame.
+ * @flags: least significant byte for rate code. The most significant byte
+ * is  iwl_mac_beacon_flags.
  * @reserved: reserved
- * @template_id: currently equal to the mac context id of the coresponding
- *  mac.
+ * @template_id: currently equal to the mac context id of the coresponding mac.
  * @tim_idx: the offset of the tim IE in the beacon
  * @tim_size: the length of the tim IE
  * @ecsa_offset: offset to the ECSA IE if present
@@ -809,7 +816,7 @@ struct iwl_mac_beacon_cmd {
__le32 ecsa_offset;
__le32 csa_offset;
struct ieee80211_hdr frame[0];
-} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_8 */
+} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_9 */
 
 struct iwl_beacon_notif {
struct iwl_mvm_tx_resp beacon_notify_hdr;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h 
b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 0fa8c473f1e2..d933aa324ffe 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -260,6 +260,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_STA_TYPE  = (__force 
iwl_ucode_tlv_api_t)30,
IWL_UCODE_TLV_API_NAN2_VER2 = (__force 
iwl_ucode_tlv_api_t)31,
/* API Set 1 */
+   IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE   = (__force 
iwl_ucode_tlv_api_t)34,
IWL_UCODE_TLV_API_NEW_RX_STATS  = (__force 
iwl_ucode_tlv_api_t)35,
 
NUM_IWL_UCODE_TLV_API
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 8fe955d58c6e..a2bf530eeae4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -923,6 +923,19 @@ static u32 iwl_mvm_find_ie_offset(u8 *beacon, u8 eid, u32 
frame_size)
return ie - beacon;
 }
 
+static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
+  struct ieee80211_vif *vif)
+{
+   u8 rate;
+
+   if (info->band == NL80211_BAND_5GHZ || vif->p2p)
+   rate = IWL_FIRST_OFDM_RATE;
+   else
+   rate = IWL_FIRST_CCK_RATE;
+
+   return rate;
+}
+
 static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct sk_buff *beacon,
@@ -930,7 +943,8 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
 {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct ieee80211_tx_info *info;
-   u32 rate, tx_flags;
+   u8 rate;
+   u32 tx_flags;
 
info = IEEE80211_SKB_CB(beacon);
 
@@ -955,14 +969,12 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
RATE_MCS_ANT_POS);
 
-   if (info->band == NL80211_BAND_5GHZ || vif->p2p) {
-   rate = IWL_FIRST_OFDM_RATE;
-   } else {
-   rate = IWL_FIRST_CCK_RATE;
-   tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
-   }
+   rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
 
tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
+   if (rate == IWL_FIRST_CCK_RATE)
+   tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
+
 }
 
 static int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
@@ -1033,19 +1045,27 @@ static int iwl_

Re: [PATCH 00/10] mac80211 patches from our internal tree 2017-08-05

2017-08-07 Thread Luca Coelho
On Mon, 2017-08-07 at 12:06 +0300, Kalle Valo wrote:
> Luca Coelho <l...@coelho.fi> writes:
> 
> > Here are some pending mac80211 patches from our internal tree.
> > 
> > The "mac80211: add api to start ba session timer expired flow" patch
> > is needed by an iwlwifi patch that I want to send for -fixes, so it
> > would have to be applied to -fixes as well.
> 
> We are getting to the later stages of the release cycle and I'm raising
> the bar for wireless-drivers even higher. How serious iwlwifi bug is
> that fixing?

The problem is a bad degradation in throughput with our new 9000 family
of devices because when aggregation times out we stop the aggregation
internally in the firmware but don't send a delba.  Then on the AP side,
 also with our driver, we don't handle the timeout as we should, so
aggregations the devices get out of sync and BA sessions are not
possible anymore, limiting our throughput to ~30Mbps, in some specific
internal tests.


> > Should I send a separate patchset with these two so they can be both
> > applied at the same time (either in the mac80211 or in
> > wireless-drivers tree)?
> 
> Now that Johannes is away and I'm taking any urgent mac80211 patches, I
> think the best approach is that you include mac80211 patch in the same
> patchset as the iwlwifi patches destined for wireless-drivers.

Okay, if you think the (one-liner) iwlwifi driver fix is -rc'able, I'll
resend this in a patchset including both changes.


--
Cheers,
Luca.


Re: [PATCH 04/19] iwlwifi: mvm: add debugfs to force CT-kill

2017-08-07 Thread Luca Coelho
On Mon, 2017-08-07 at 16:11 +0300, Kalle Valo wrote:
> Luca Coelho <l...@coelho.fi> writes:
> 
> > From: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>
> > 
> > In order to test the enter/exit CT-kill flow.
> > 
> > Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>
> > Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
> 
> The commit log doesn't explain what's CT-kill and how/where it could be
> used. For example, I have no clue what this could be about.

You're right, sorry for that.  I'll update the commit log and submit v2.

Basically CT-kill is a thermal "RF-kill".  Whenever the NIC gets too
hot, we shut it down to prevent further damage.  This is nothing new. 
What this patch is adding is a fake way to simulate the NIC getting too
hot by kicking off a debugfs entry, in the same way the FW would kick it
off by sending a notification to the driver.

This is mostly for R, but it's very useful for us and I we need it for
our internal tests.  Not that useful for non-developers but I didn't
want to carry this in internal driver to avoid unnecessary conflicts
when syncing it with upstream.

--
Luca.


Re: [PATCH 1/3] iwlwifi: mvm: Fix a memory leak in an error handling path in 'iwl_mvm_sar_get_wgds_table()'

2017-08-07 Thread Luca Coelho
On Mon, 2017-08-07 at 16:37 +0300, Kalle Valo wrote:
> Luca Coelho <l...@coelho.fi> writes:
> 
> > On Mon, 2017-08-07 at 15:57 +0300, Kalle Valo wrote:
> > > Luca Coelho <l...@coelho.fi> writes:
> > > 
> > > > From: Christophe Jaillet <christophe.jail...@wanadoo.fr>
> > > > 
> > > > We should free 'wgds.pointer' here as done a few lines above in another
> > > > error handling path.
> > > > It was allocated within 'acpi_evaluate_object()'.
> > > > 
> > > > Fixes: c52030a01ccc ("iwlwifi: mvm: add GEO_TX_POWER_LIMIT cmd for 
> > > > geographic tx power table")
> > > > Signed-off-by: Christophe JAILLET <christophe.jail...@wanadoo.fr>
> > > > Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
> > > > ---
> > > >  drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 6 --
> > > >  1 file changed, 4 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
> > > > b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> > > > index 79e7a7a285dc..82863e9273eb 100644
> > > > --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> > > > +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> > > > @@ -1275,8 +1275,10 @@ static int iwl_mvm_sar_get_wgds_table(struct 
> > > > iwl_mvm *mvm)
> > > >  
> > > > entry = _pkg->package.elements[idx++];
> > > > if ((entry->type != ACPI_TYPE_INTEGER) ||
> > > > -   (entry->integer.value > U8_MAX))
> > > > -   return -EINVAL;
> > > > +   (entry->integer.value > U8_MAX)) {
> > > > +   ret = -EINVAL;
> > > > +   goto out_free;
> > > > +   }
> > > 
> > > How likely is this leak to happen in real world? To me it looks like
> > > more like a theoretical issue and could have easily waited for 4.14. But
> > > it's fine this time, just something to keep in mind in the future.
> > 
> > This is a one-liner fix and I consider memory leaks serious enough to
> > deserve a fix for rc5.  This bug can happen with broken ACPI tables and,
> > trust me, broken ACPI tables are not that hard to find.
> 
> Sure, anything's possible. But what I'm reading here this is still a
> theoretical issue, not a leak which we _know_ will happen to thousands
> of people.
> 
> > But you rule here, feel free to NACK my patches whenever you see fit! :)
> 
> I'm trying to minimise the numbers of patches going to wireless-drivers
> and striving for only fixes which really matter and keep the theoretical
> stuff for -next. The is mostly selfish reasons as wireless-drivers are a
> lot more work, especially if there are conflicts.

I totally understand.  It's a lot more work for me too, with all the
reordering I need to do and the conflicts these cause.


> But like I said in my previous mail, no need to drop this.

Okay, thanks!

--
Cheers,
Luca.


Re: [PATCH 1/3] iwlwifi: mvm: Fix a memory leak in an error handling path in 'iwl_mvm_sar_get_wgds_table()'

2017-08-07 Thread Luca Coelho
On Mon, 2017-08-07 at 15:57 +0300, Kalle Valo wrote:
> Luca Coelho <l...@coelho.fi> writes:
> 
> > From: Christophe Jaillet <christophe.jail...@wanadoo.fr>
> > 
> > We should free 'wgds.pointer' here as done a few lines above in another
> > error handling path.
> > It was allocated within 'acpi_evaluate_object()'.
> > 
> > Fixes: c52030a01ccc ("iwlwifi: mvm: add GEO_TX_POWER_LIMIT cmd for 
> > geographic tx power table")
> > Signed-off-by: Christophe JAILLET <christophe.jail...@wanadoo.fr>
> > Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
> > ---
> >  drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 6 --
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
> > b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> > index 79e7a7a285dc..82863e9273eb 100644
> > --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> > +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> > @@ -1275,8 +1275,10 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm 
> > *mvm)
> >  
> > entry = _pkg->package.elements[idx++];
> > if ((entry->type != ACPI_TYPE_INTEGER) ||
> > -   (entry->integer.value > U8_MAX))
> > -   return -EINVAL;
> > +   (entry->integer.value > U8_MAX)) {
> > +   ret = -EINVAL;
> > +   goto out_free;
> > +   }
> 
> How likely is this leak to happen in real world? To me it looks like
> more like a theoretical issue and could have easily waited for 4.14. But
> it's fine this time, just something to keep in mind in the future.

This is a one-liner fix and I consider memory leaks serious enough to
deserve a fix for rc5.  This bug can happen with broken ACPI tables and,
trust me, broken ACPI tables are not that hard to find.

But you rule here, feel free to NACK my patches whenever you see fit! :)

--
Cheers,
Luca.


[PATCH 04/10] mac80211: simplify and clarify IE splitting

2017-08-05 Thread Luca Coelho
From: Johannes Berg 

There's no need to split off IEs from the ones obtained
from userspace, if they were already split off, so for
example IEs that went before HT don't have to be listed
again to go before VHT. Simplify the code here so it's
clearer.

While at it, also clarify the comments regarding the DMG
(60 GHz) elements.

Signed-off-by: Johannes Berg 
---
 net/mac80211/mlme.c | 19 +++
 net/mac80211/util.c | 21 +
 2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7be7917e1541..5bb570643494 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -780,11 +780,12 @@ static void ieee80211_send_assoc(struct 
ieee80211_sub_if_data *sdata)
WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
WLAN_EID_HT_CAPABILITY,
WLAN_EID_BSS_COEX_2040,
+   /* luckily this is almost always there */
WLAN_EID_EXT_CAPABILITY,
WLAN_EID_QOS_TRAFFIC_CAPA,
WLAN_EID_TIM_BCAST_REQ,
WLAN_EID_INTERWORKING,
-   /* 60GHz doesn't happen right now */
+   /* 60 GHz (Multi-band, DMG, MMS) can't happen */
WLAN_EID_VHT_CAPABILITY,
WLAN_EID_OPMODE_NOTIF,
};
@@ -812,22 +813,16 @@ static void ieee80211_send_assoc(struct 
ieee80211_sub_if_data *sdata)
/* if present, add any custom IEs that go before VHT */
if (assoc_data->ie_len) {
static const u8 before_vht[] = {
-   WLAN_EID_SSID,
-   WLAN_EID_SUPP_RATES,
-   WLAN_EID_EXT_SUPP_RATES,
-   WLAN_EID_PWR_CAPABILITY,
-   WLAN_EID_SUPPORTED_CHANNELS,
-   WLAN_EID_RSN,
-   WLAN_EID_QOS_CAPA,
-   WLAN_EID_RRM_ENABLED_CAPABILITIES,
-   WLAN_EID_MOBILITY_DOMAIN,
-   WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
-   WLAN_EID_HT_CAPABILITY,
+   /*
+* no need to list the ones split off before HT
+* or generated here
+*/
WLAN_EID_BSS_COEX_2040,
WLAN_EID_EXT_CAPABILITY,
WLAN_EID_QOS_TRAFFIC_CAPA,
WLAN_EID_TIM_BCAST_REQ,
WLAN_EID_INTERWORKING,
+   /* 60 GHz (Multi-band, DMG, MMS) can't happen */
};
 
/* RIC already taken above, so no need to handle here anymore */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 6aef6793d052..bfecc3e86318 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1392,10 +1392,10 @@ static int ieee80211_build_preq_ies_band(struct 
ieee80211_local *local,
/* insert custom IEs that go before HT */
if (ie && ie_len) {
static const u8 before_ht[] = {
-   WLAN_EID_SSID,
-   WLAN_EID_SUPP_RATES,
-   WLAN_EID_REQUEST,
-   WLAN_EID_EXT_SUPP_RATES,
+   /*
+* no need to list the ones split off already
+* (or generated here)
+*/
WLAN_EID_DS_PARAMS,
WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
};
@@ -1424,20 +1424,17 @@ static int ieee80211_build_preq_ies_band(struct 
ieee80211_local *local,
/* insert custom IEs that go before VHT */
if (ie && ie_len) {
static const u8 before_vht[] = {
-   WLAN_EID_SSID,
-   WLAN_EID_SUPP_RATES,
-   WLAN_EID_REQUEST,
-   WLAN_EID_EXT_SUPP_RATES,
-   WLAN_EID_DS_PARAMS,
-   WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
-   WLAN_EID_HT_CAPABILITY,
+   /*
+* no need to list the ones split off already
+* (or generated here)
+*/
WLAN_EID_BSS_COEX_2040,
WLAN_EID_EXT_CAPABILITY,
WLAN_EID_SSID_LIST,
WLAN_EID_CHANNEL_USAGE,
WLAN_EID_INTERWORKING,
WLAN_EID_MESH_ID,
-   /* 60 GHz can't happen here right now */
+   /* 60 GHz (Multi-band, DMG, MMS) can't happen */
};
noffset = ieee80211_ie_split(ie, ie_len,
 before_vht, ARRAY_SIZE(before_vht),
-- 
2.13.2



[PATCH 05/10] ieee80211: Add WFA TPC report element OUI type

2017-08-05 Thread Luca Coelho
From: Avraham Stern <avraham.st...@intel.com>

Signed-off-by: Avraham Stern <avraham.st...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 include/linux/ieee80211.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 34e1bcd2d7ff..6572c2ca1261 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2412,6 +2412,7 @@ enum ieee80211_sa_query_action {
 #define WLAN_OUI_TYPE_MICROSOFT_WPA1
 #define WLAN_OUI_TYPE_MICROSOFT_WMM2
 #define WLAN_OUI_TYPE_MICROSOFT_WPS4
+#define WLAN_OUI_TYPE_MICROSOFT_TPC8
 
 /*
  * WMM/802.11e Tspec Element
-- 
2.13.2



[PATCH 10/10] nl80211: return error for invalid center_freq in 40 MHz

2017-08-05 Thread Luca Coelho
From: Tova Mussai <tova.mus...@intel.com>

When NL80211_ATTR_WIPHY_CHANNEL_TYPE is given, nl80211 would parse the
channel definition the old way, discarding NL80211_ATTR_CENTER_FREQ1,
NL80211_ATTR_CENTER_FREQ2 etc. However, it is possible that user space
added both NL80211_ATTR_WIPHY_CHANNEL_TYPE and NL80211_ATTR_CENTER_FREQ1
or NL80211_ATTR_CENTER_FREQ2 assuming that all settings would be honored.

In such a case, validate that NL80211_ATTR_CENTER_FREQ1 and
NL80211_ATTR_CENTER_FREQ2 values match the channel configuration,
as otherwise user space would assume that the desired configuration was
applied.

For example, when trying to start ap with
NL80211_ATTR_WIPHY_CHANNEL_TYPE = NL80211_CHAN_HT40MINUS,
NL80211_ATTR_WIPHY_FREQ = 5180 and NL80211_ATTR_CENTER_FREQ1 = 5250
without this fix, the ap will start on channel 36 (center_freq1 will be
corrected to 5180).  With this fix, we will throw an error instead.

Signed-off-by: Tova Mussai <tova.mus...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 net/wireless/nl80211.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 45ba3d0872cc..edf484fe1f80 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2122,6 +2122,15 @@ static int nl80211_parse_chandef(struct 
cfg80211_registered_device *rdev,
case NL80211_CHAN_HT40MINUS:
cfg80211_chandef_create(chandef, chandef->chan,
chantype);
+   /* user input for center_freq is incorrect */
+   if (info->attrs[NL80211_ATTR_CENTER_FREQ1] &&
+   chandef->center_freq1 != nla_get_u32(
+   info->attrs[NL80211_ATTR_CENTER_FREQ1]))
+   return -EINVAL;
+   /* center_freq2 must be zero */
+   if (info->attrs[NL80211_ATTR_CENTER_FREQ2] &&
+   nla_get_u32(info->attrs[NL80211_ATTR_CENTER_FREQ2]))
+   return -EINVAL;
break;
default:
return -EINVAL;
-- 
2.13.2



[PATCH 09/10] mac80211_hwsim: Add command to control rx status RSSI

2017-08-05 Thread Luca Coelho
From: Beni Lev <beni@intel.com>

Set the base RSSI of a TX frame. The final RSSI of the frame will be
the base RSSI + the radio's TX power

Signed-off-by: Beni Lev <beni@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/mac80211_hwsim.c | 36 +--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 6467ffac9811..7c3811f0c730 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -368,6 +368,8 @@ static const struct ieee80211_rate hwsim_rates[] = {
{ .bitrate = 540 }
 };
 
+#define DEFAULT_RX_RSSI -50
+
 #define OUI_QCA 0x001374
 #define QCA_NL80211_SUBCMD_TEST 1
 enum qca_nl80211_vendor_subcmds {
@@ -571,6 +573,9 @@ struct mac80211_hwsim_data {
u64 rx_bytes;
u64 tx_dropped;
u64 tx_failed;
+
+   /* RSSI in rx status of the receiver */
+   int rx_rssi;
 };
 
 
@@ -783,6 +788,29 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group,
hwsim_fops_group_read, hwsim_fops_group_write,
"%llx\n");
 
+static int hwsim_fops_rx_rssi_read(void *dat, u64 *val)
+{
+   struct mac80211_hwsim_data *data = dat;
+   *val = data->rx_rssi;
+   return 0;
+}
+
+static int hwsim_fops_rx_rssi_write(void *dat, u64 val)
+{
+   struct mac80211_hwsim_data *data = dat;
+   int rssi = (int)val;
+
+   if (rssi >= 0 || rssi < -100)
+   return -EINVAL;
+
+   data->rx_rssi = rssi;
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_rx_rssi,
+   hwsim_fops_rx_rssi_read, hwsim_fops_rx_rssi_write,
+   "%lld\n");
+
 static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
struct net_device *dev)
 {
@@ -1210,8 +1238,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct 
ieee80211_hw *hw,
rx_status.bw = RATE_INFO_BW_20;
if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
rx_status.enc_flags |= RX_ENC_FLAG_SHORT_GI;
-   /* TODO: simulate real signal strength (and optional packet loss) */
-   rx_status.signal = -50;
+   /* TODO: simulate optional packet loss */
+   rx_status.signal = data->rx_rssi;
if (info->control.vif)
rx_status.signal += info->control.vif->bss_conf.txpower;
 
@@ -2554,6 +2582,8 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
}
 
+   data->rx_rssi = DEFAULT_RX_RSSI;
+
INIT_DELAYED_WORK(>roc_start, hw_roc_start);
INIT_DELAYED_WORK(>roc_done, hw_roc_done);
INIT_DELAYED_WORK(>hw_scan, hw_scan_work);
@@ -2715,6 +2745,8 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
debugfs_create_file("ps", 0666, data->debugfs, data, _fops_ps);
debugfs_create_file("group", 0666, data->debugfs, data,
_fops_group);
+   debugfs_create_file("rx_rssi", 0666, data->debugfs, data,
+   _fops_rx_rssi);
if (!data->use_chanctx)
debugfs_create_file("dfs_simulate_radar", 0222,
data->debugfs,
-- 
2.13.2



[PATCH 00/10] mac80211 patches from our internal tree 2017-08-05

2017-08-05 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

Hi,

Here are some pending mac80211 patches from our internal tree.

The "mac80211: add api to start ba session timer expired flow" patch
is needed by an iwlwifi patch that I want to send for -fixes, so it
would have to be applied to -fixes as well.  Should I send a separate
patchset with these two so they can be both applied at the same time
(either in the mac80211 or in wireless-drivers tree)?

Please review.

Cheers,
Luca.

Avraham Stern (1):
  ieee80211: Add WFA TPC report element OUI type

Beni Lev (1):
  mac80211_hwsim: Add command to control rx status RSSI

Emmanuel Grumbach (1):
  cfg80211: honor NL80211_RRF_NO_HT40{MINUS,PLUS}

Gregory Greenman (1):
  mac80211: recalculate some sta parameters after insertion

Johannes Berg (1):
  mac80211: simplify and clarify IE splitting

Liad Kaufman (2):
  mac80211: add MESH IE in the correct order
  mac80211: extend ieee80211_ie_split to support EXTENSION

Naftali Goldstein (1):
  mac80211: add api to start ba session timer expired flow

Sharon Dvir (1):
  mac80211: shorten debug prints using ht_dbg() to avoid warning

Tova Mussai (1):
  nl80211: return error for invalid center_freq in 40 MHz

 drivers/net/wireless/mac80211_hwsim.c | 36 --
 include/linux/ieee80211.h |  1 +
 include/net/cfg80211.h|  6 ++--
 include/net/mac80211.h| 15 +
 net/mac80211/agg-rx.c | 22 +-
 net/mac80211/agg-tx.c |  4 +--
 net/mac80211/mlme.c   | 19 +---
 net/mac80211/sta_info.c   | 57 ---
 net/mac80211/util.c   | 23 ++
 net/wireless/nl80211.c|  9 ++
 net/wireless/reg.c| 20 ++--
 net/wireless/util.c   | 54 -
 12 files changed, 199 insertions(+), 67 deletions(-)

-- 
2.13.2



[PATCH 03/10] mac80211: extend ieee80211_ie_split to support EXTENSION

2017-08-05 Thread Luca Coelho
From: Liad Kaufman <liad.kauf...@intel.com>

Current ieee80211_ie_split() implementation doesn't
account for elements that are sub-elements of the
EXTENSION IE. To extend support to these IEs as well,
treat the WLAN_EID_EXTENSION ids in the %ids array
as indicating that the next id in the array is a
sub-element of the EXTENSION IE.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 include/net/cfg80211.h |  6 --
 net/wireless/util.c| 54 ++
 2 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f12fa5245a45..aa9d993e519a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5934,7 +5934,8 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len,
  * @ies: the IE buffer
  * @ielen: the length of the IE buffer
  * @ids: an array with element IDs that are allowed before
- * the split
+ * the split. A WLAN_EID_EXTENSION value means that the next
+ * EID in the list is a sub-element of the EXTENSION IE.
  * @n_ids: the size of the element ID array
  * @after_ric: array IE types that come after the RIC element
  * @n_after_ric: size of the @after_ric array
@@ -5965,7 +5966,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
  * @ies: the IE buffer
  * @ielen: the length of the IE buffer
  * @ids: an array with element IDs that are allowed before
- * the split
+ * the split. A WLAN_EID_EXTENSION value means that the next
+ * EID in the list is a sub-element of the EXTENSION IE.
  * @n_ids: the size of the element ID array
  * @offset: offset where to start splitting in the buffer
  *
diff --git a/net/wireless/util.c b/net/wireless/util.c
index bcb1284c3415..4aab793c2f00 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1367,13 +1367,29 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int 
len,
 }
 EXPORT_SYMBOL(cfg80211_get_p2p_attr);
 
-static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
+static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id, bool id_ext)
 {
int i;
 
-   for (i = 0; i < n_ids; i++)
-   if (ids[i] == id)
+   /* Make sure array values are legal */
+   if (WARN_ON(ids[n_ids - 1] == WLAN_EID_EXTENSION))
+   return false;
+
+   i = 0;
+   while (i < n_ids) {
+   if (ids[i] == WLAN_EID_EXTENSION) {
+   if (id_ext && (ids[i + 1] == id))
+   return true;
+
+   i += 2;
+   continue;
+   }
+
+   if (ids[i] == id && !id_ext)
return true;
+
+   i++;
+   }
return false;
 }
 
@@ -1403,14 +1419,36 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t 
ielen,
 {
size_t pos = offset;
 
-   while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) {
+   while (pos < ielen) {
+   u8 ext = 0;
+
+   if (ies[pos] == WLAN_EID_EXTENSION)
+   ext = 2;
+   if ((pos + ext) >= ielen)
+   break;
+
+   if (!ieee80211_id_in_list(ids, n_ids, ies[pos + ext],
+ ies[pos] == WLAN_EID_EXTENSION))
+   break;
+
if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {
pos = skip_ie(ies, ielen, pos);
 
-   while (pos < ielen &&
-  !ieee80211_id_in_list(after_ric, n_after_ric,
-ies[pos]))
-   pos = skip_ie(ies, ielen, pos);
+   while (pos < ielen) {
+   if (ies[pos] == WLAN_EID_EXTENSION)
+   ext = 2;
+   else
+   ext = 0;
+
+   if ((pos + ext) >= ielen)
+   break;
+
+   if (!ieee80211_id_in_list(after_ric,
+ n_after_ric,
+ ies[pos + ext],
+ ext == 2))
+   pos = skip_ie(ies, ielen, pos);
+   }
} else {
pos = skip_ie(ies, ielen, pos);
}
-- 
2.13.2



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

2017-08-18 Thread Luca Coelho
Hi Dariusz,

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

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

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

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

--
Cheers,
Luca.


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

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

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

--
Cheers,
Luca.


pull-request: iwlwifi-next 2017-08-18

2017-08-19 Thread Luca Coelho
Hi Kalle,

Here's my third pull-request intended for v4.14.  We continued doing
generic development work, with improvements, bug fixes and cleanups all
around.  More details in the tag description.

My patch "iwlwifi: update channel flags parser" is going to cause a
conflict with net because they both change the same string in debug
message.  Emmanuel's patch "iwlwifi: split the regulatory rules when the
bandwidth flags require it" added "reg_flags" to the string and changed
the Ad-hoc string.  My patch added a few %s's and also changed the Ad-
hoc string.  The result of the conflict resolution should look like
this:

"Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x) reg_flags 0x%x: %s\n"


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 38ef62353acbaa0eea062a9f047b33aebd7d52ce:

  rsi: security enhancements for AP mode (2017-08-17 10:07:00 +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-2017-08-18

for you to fetch changes up to 8fe34b060a4b11be35ffd9383acdd0bc7bee72e2:

  iwlwifi: use big-endian for the hw section of the nvm (2017-08-18 17:36:42 
+0300)


Third set of iwlwifi patches for 4.14

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


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

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

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

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

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

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

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

 drivers/net/wireless/intel/iwlwifi/cfg/a000.c|  34 ++-
 drivers/net/wireless/intel/iwlwifi/fw/api/coex.h |  50 +++-
 drivers/net/wireless/intel/iwlwifi/fw/api/commands.h |  12 
 drivers/net/wireless/intel/iwlwifi/fw/api/config.h   |   8 ---
 drivers/net/wireless/intel/iwlwifi/fw/api/tx.h   |   9 +--
 drivers/net/wireless/intel/iwlwifi/fw/file.h |   3 +
 drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c   |  25 
 drivers/net/wireless/intel/iwlwifi/fw/nvm.c  |   2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h  |   4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-csr.h |   7 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c |  12 ++--
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c   | 118 
+++---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h   |   5 +-
 drivers/net/wireless/intel/iwlwifi/mvm/coex.c| 301 
+
 drivers/net/wireless/intel/iwlwifi/mvm/constants.h   |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c |  30 --
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c  |  54 ++
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c|  16 --
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h |  31 +++---
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 106 
+-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c |   6 +-
 drivers/net/

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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

The user space can now allow the kernel to associate to an AP that
requires MFP or that doesn't have MFP enabled in the same
NL80211_CMD_CONNECT command, by using a new NL80211_MFP_OPTIONAL flag.
The driver / firmware will decide whether to use it or not.

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

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

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

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



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

2017-08-18 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

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

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

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



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

2017-08-18 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

Here are two pending mac80211 patches from our internal tree.

Please review.

Cheers,
Luca.


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

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

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

-- 
2.14.1



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

2017-08-18 Thread Luca Coelho
From: Avraham Stern <avraham.st...@intel.com>

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

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

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

Signed-off-by: Avraham Stern <avraham.st...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 net/mac80211/offchannel.c | 2 ++
 1 file changed, 2 insertions(+)

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



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

2017-08-18 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

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

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

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

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

2017-08-18 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

Hi,

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

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

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

Please review.

Cheers,
Luca.

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

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

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

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

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

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

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

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

-- 
2.14.1



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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

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

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

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

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

2017-08-18 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

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

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

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



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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

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

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

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

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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

This name was missing in the list.

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

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



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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

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

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

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

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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

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

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

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



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

2017-08-18 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

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

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

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

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

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

2017-08-18 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

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

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

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



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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

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

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

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



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

2017-08-18 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

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

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

(loop of 2 and 3)

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

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

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



pull-request: iwlwifi firmwares update 2017-05-10

2017-05-10 Thread Luca Coelho
Hi Kyle,

The last time we pushed new -22 firmwares, we forgot to update the
relevant version for 3168 devices.  This pull-request contains only this
update.

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

Cheers,
Luca.


The following changes since commit ade8332383e228cbdcfc605b5e5ef3aa51211401:

  Merge branch 'master' of git://git.marvell.com/mwifiex-firmware (2017-04-22 
11:25:59 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware.git 
tags/iwlwifi-fw-2017-05-10

for you to fetch changes up to ca89d62df8fbeb0b8131437dfd5b8098c85f8164:

  iwlwifi: update -22 firmware for 3168 (2017-05-10 23:43:18 +0300)


Update firmware for 3168

* update -22 firmware binaries for iwlwifi device 3168


Emmanuel Grumbach (1):
  iwlwifi: update -22 firmware for 3168

 WHENCE|   2 +-
 iwlwifi-3168-22.ucode | Bin 1028032 -> 1028092 bytes
 2 files changed, 1 insertion(+), 1 deletion(-)



[PATCH 20/25] iwlwifi: pcie: don't report RF-kill enabled while shutting down

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

When toggling the RF-kill pin quickly in succession, the driver can
get rather confused because it might be in the process of shutting
down, expecting all commands to go through quickly due to rfkill,
but the transport already thinks the device is accessible again,
even though it previously shut it down. This leads to bugs, and I
even observed a kernel panic.

Avoid this by making the PCIe code only report that the radio is
enabled again after the higher layers actually decided to shut it
off.

This also pulls out this common RF-kill checking code into a common
function called by both transport generations and also moves it to
the direct method - in the internal helper we don't really care
about the RF-kill status anymore since we won't report it up until
the stop anyway.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-trans.c |  2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h |  6 +-
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c  | 12 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  4 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   | 20 --
 .../net/wireless/intel/iwlwifi/pcie/trans-gen2.c   | 28 ++--
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c| 82 ++
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  |  4 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   |  4 +-
 9 files changed, 88 insertions(+), 74 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
index dcf596217d9e..784bdd0ed233 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
@@ -117,7 +117,7 @@ int iwl_trans_send_cmd(struct iwl_trans *trans, struct 
iwl_host_cmd *cmd)
int ret;
 
if (unlikely(!(cmd->flags & CMD_SEND_IN_RFKILL) &&
-test_bit(STATUS_RFKILL, >status)))
+test_bit(STATUS_RFKILL_OPMODE, >status)))
return -ERFKILL;
 
if (unlikely(test_bit(STATUS_FW_ERROR, >status)))
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index a150da3c824b..2e975c0be045 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -322,7 +322,8 @@ enum iwl_d3_status {
  * @STATUS_DEVICE_ENABLED: APM is enabled
  * @STATUS_TPOWER_PMI: the device might be asleep (need to wake it up)
  * @STATUS_INT_ENABLED: interrupts are enabled
- * @STATUS_RFKILL: the HW RFkill switch is in KILL position
+ * @STATUS_RFKILL_HW: the actual HW state of the RF-kill switch
+ * @STATUS_RFKILL_OPMODE: RF-kill state reported to opmode
  * @STATUS_FW_ERROR: the fw is in error state
  * @STATUS_TRANS_GOING_IDLE: shutting down the trans, only special commands
  * are sent
@@ -334,7 +335,8 @@ enum iwl_trans_status {
STATUS_DEVICE_ENABLED,
STATUS_TPOWER_PMI,
STATUS_INT_ENABLED,
-   STATUS_RFKILL,
+   STATUS_RFKILL_HW,
+   STATUS_RFKILL_OPMODE,
STATUS_FW_ERROR,
STATUS_TRANS_GOING_IDLE,
STATUS_TRANS_IDLE,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 2d92d3708619..a8fb77483313 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -766,7 +766,6 @@ static int iwl_pci_resume(struct device *device)
struct pci_dev *pdev = to_pci_dev(device);
struct iwl_trans *trans = pci_get_drvdata(pdev);
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-   bool hw_rfkill;
 
/* Before you put code here, think about WoWLAN. You cannot check here
 * whether WoWLAN is enabled or not, and your code will run even if
@@ -783,16 +782,13 @@ static int iwl_pci_resume(struct device *device)
return 0;
 
/*
-* Enable rfkill interrupt (in order to keep track of
-* the rfkill status). Must be locked to avoid processing
-* a possible rfkill interrupt between reading the state
-* and calling iwl_trans_pcie_rf_kill() with it.
+* Enable rfkill interrupt (in order to keep track of the rfkill
+* status). Must be locked to avoid processing a possible rfkill
+* interrupt while in iwl_trans_check_hw_rf_kill().
 */
mutex_lock(_pcie->mutex);
iwl_enable_rfkill_int(trans);
-
-   hw_rfkill = iwl_is_rfkill_set(trans);
-   iwl_trans_pcie_rf_kill(trans, hw_rfkill);
+   iwl_trans_check_hw_rf_kill(trans);
mutex_unlock(_pcie->mutex);
 
return 0;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index

[PATCH 17/25] iwlwifi: pcie: pull out common rfkill IRQ handling code

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

There's no point in duplicating exactly the same code here
for legacy and MSI-X interrupts, so pull it out into a new
function to call in both places.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 82 +++-
 1 file changed, 33 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 293f4b2c1955..c27d6f711abf 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1509,6 +1509,36 @@ static u32 iwl_pcie_int_cause_ict(struct iwl_trans 
*trans)
return inta;
 }
 
+static void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans)
+{
+   struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+   struct isr_statistics *isr_stats = _pcie->isr_stats;
+   bool hw_rfkill;
+
+   mutex_lock(_pcie->mutex);
+   hw_rfkill = iwl_is_rfkill_set(trans);
+   if (hw_rfkill)
+   set_bit(STATUS_RFKILL, >status);
+
+   IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
+hw_rfkill ? "disable radio" : "enable radio");
+
+   isr_stats->rfkill++;
+
+   iwl_trans_pcie_rf_kill(trans, hw_rfkill);
+   mutex_unlock(_pcie->mutex);
+
+   if (hw_rfkill) {
+   if (test_and_clear_bit(STATUS_SYNC_HCMD_ACTIVE,
+  >status))
+   IWL_DEBUG_RF_KILL(trans,
+ "Rfkill while SYNC HCMD in flight\n");
+   wake_up(_pcie->wait_command_queue);
+   } else {
+   clear_bit(STATUS_RFKILL, >status);
+   }
+}
+
 irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
 {
struct iwl_trans *trans = dev_id;
@@ -1632,30 +1662,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
 
/* HW RF KILL switch toggled */
if (inta & CSR_INT_BIT_RF_KILL) {
-   bool hw_rfkill;
-
-   mutex_lock(_pcie->mutex);
-   hw_rfkill = iwl_is_rfkill_set(trans);
-   if (hw_rfkill)
-   set_bit(STATUS_RFKILL, >status);
-
-   IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
-hw_rfkill ? "disable radio" : "enable radio");
-
-   isr_stats->rfkill++;
-
-   iwl_trans_pcie_rf_kill(trans, hw_rfkill);
-   mutex_unlock(_pcie->mutex);
-   if (hw_rfkill) {
-   if (test_and_clear_bit(STATUS_SYNC_HCMD_ACTIVE,
-  >status))
-   IWL_DEBUG_RF_KILL(trans,
- "Rfkill while SYNC HCMD in 
flight\n");
-   wake_up(_pcie->wait_command_queue);
-   } else {
-   clear_bit(STATUS_RFKILL, >status);
-   }
-
+   iwl_pcie_handle_rfkill_irq(trans);
handled |= CSR_INT_BIT_RF_KILL;
}
 
@@ -1982,31 +1989,8 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void 
*dev_id)
}
 
/* HW RF KILL switch toggled */
-   if (inta_hw & MSIX_HW_INT_CAUSES_REG_RF_KILL) {
-   bool hw_rfkill;
-
-   mutex_lock(_pcie->mutex);
-   hw_rfkill = iwl_is_rfkill_set(trans);
-   if (hw_rfkill)
-   set_bit(STATUS_RFKILL, >status);
-
-   IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
-hw_rfkill ? "disable radio" : "enable radio");
-
-   isr_stats->rfkill++;
-
-   iwl_trans_pcie_rf_kill(trans, hw_rfkill);
-   mutex_unlock(_pcie->mutex);
-   if (hw_rfkill) {
-   if (test_and_clear_bit(STATUS_SYNC_HCMD_ACTIVE,
-  >status))
-   IWL_DEBUG_RF_KILL(trans,
- "Rfkill while SYNC HCMD in 
flight\n");
-   wake_up(_pcie->wait_command_queue);
-   } else {
-   clear_bit(STATUS_RFKILL, >status);
-   }
-   }
+   if (inta_hw & MSIX_HW_INT_CAUSES_REG_RF_KILL)
+   iwl_pcie_handle_rfkill_irq(trans);
 
if (inta_hw & MSIX_HW_INT_CAUSES_REG_HW_ERR) {
IWL_ERR(trans,
-- 
2.11.0



[PATCH 21/25] iwlwifi: pcie: remove pointless debugfs parsing for csr file

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

We don't actually care about the value at all, just making sure
that we can successfully parse a single integer value, but that's
entirely pointless - remove it.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 959a3d5ece67..280b14ace175 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2450,16 +2450,6 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file,
   size_t count, loff_t *ppos)
 {
struct iwl_trans *trans = file->private_data;
-   char buf[8];
-   int buf_size;
-   int csr;
-
-   memset(buf, 0, sizeof(buf));
-   buf_size = min(count, sizeof(buf) -  1);
-   if (copy_from_user(buf, user_buf, buf_size))
-   return -EFAULT;
-   if (sscanf(buf, "%d", ) != 1)
-   return -EFAULT;
 
iwl_pcie_dump_csr(trans);
 
-- 
2.11.0



[PATCH 22/25] iwlwifi: mvm: document status bits

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index a4bee9c740e0..0b5e92c1483e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1081,6 +1081,18 @@ struct iwl_mvm {
 #define IWL_MAC80211_GET_MVM(_hw)  \
IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv))
 
+/**
+ * enum iwl_mvm_status - MVM status bits
+ * @IWL_MVM_STATUS_HW_RFKILL: HW RF-kill is asserted
+ * @IWL_MVM_STATUS_HW_CTKILL: CT-kill is active
+ * @IWL_MVM_STATUS_ROC_RUNNING: remain-on-channel is running
+ * @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
+ * @IWL_MVM_STATUS_IN_D0I3: NIC is in D0i3
+ * @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
+ * @IWL_MVM_STATUS_D3_RECONFIG: D3 reconfiguration is being done
+ * @IWL_MVM_STATUS_DUMPING_FW_LOG: FW log is being dumped
+ * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
+ */
 enum iwl_mvm_status {
IWL_MVM_STATUS_HW_RFKILL,
IWL_MVM_STATUS_HW_CTKILL,
-- 
2.11.0



[PATCH 16/25] iwlwifi: mvm: rs: add logs for the wrong antenna case

2017-06-22 Thread Luca Coelho
From: Gregory Greenman <gregory.green...@intel.com>

In case that rate's antenna is wrong at the init stage, it's
very hard to say what went wrong. Add debug data to the already
existing WARN_ON_ONCE.

Signed-off-by: Gregory Greenman <gregory.green...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 +
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 6 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index f3236ea7edb5..127017efdd87 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -131,6 +131,7 @@ enum iwl_led_mode {
 
 /* Antenna presence definitions */
 #defineANT_NONE0x0
+#defineANT_INVALID 0xff
 #defineANT_A   BIT(0)
 #defineANT_B   BIT(1)
 #define ANT_C  BIT(2)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index aa785cf3cf68..a02dda8d9ea3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -2836,7 +2836,11 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
rs_get_initial_rate(mvm, sta, lq_sta, band, rate);
rs_init_optimal_rate(mvm, sta, lq_sta);
 
-   WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
+   WARN_ONCE(rate->ant != ANT_A && rate->ant != ANT_B,
+ "ant: 0x%x, chains 0x%x, fw tx ant: 0x%x, nvm tx ant: 0x%x\n",
+ rate->ant, lq_sta->pers.chains, mvm->fw->valid_tx_ant,
+ mvm->nvm_data ? mvm->nvm_data->valid_tx_ant : ANT_INVALID);
+
tbl->column = rs_get_column_from_rate(rate);
 
rs_set_expected_tpt_table(lq_sta, tbl);
-- 
2.11.0



[PATCH 23/25] iwlwifi: mvm: support aggregations on A000 HW

2017-06-22 Thread Luca Coelho
From: Liad Kaufman <liad.kauf...@intel.com>

On A000 HW, the SCD rdptr has only 8 bits allocated
for it, thus when checking if a queue is full, or
when checking if the SSN is equal to the TID's
next_reclaimed, A000 HW should trim the SSN.

Fix this by "normalizing" the SSN to wrap around
0xFF when comparing to the next_reclaimed on A000
HW.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 27 +--
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h  |  8 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   | 15 ++---
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c|  2 +-
 6 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 2449be6f95a5..d608ce8305c7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2395,7 +2395,7 @@ static void __iwl_mvm_mac_sta_notify(struct ieee80211_hw 
*hw,
 
__set_bit(tid_data->txq_id, );
 
-   if (iwl_mvm_tid_queued(tid_data) == 0)
+   if (iwl_mvm_tid_queued(mvm, tid_data) == 0)
continue;
 
__set_bit(tid, );
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 30fc756b5b01..3a8c95162811 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1323,7 +1323,7 @@ static bool iwl_mvm_disallow_offloading(struct iwl_mvm 
*mvm,
 * for offloading in order to prevent reuse of the same
 * qos seq counters.
 */
-   if (iwl_mvm_tid_queued(tid_data))
+   if (iwl_mvm_tid_queued(mvm, tid_data))
continue;
 
if (tid_data->state != IWL_AGG_OFF)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 59cd2486a449..0249300c4600 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2529,6 +2529,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct 
ieee80211_vif *vif,
 {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_tid_data *tid_data;
+   u16 normalized_ssn;
int txq_id;
int ret;
 
@@ -2616,7 +2617,15 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct 
ieee80211_vif *vif,
mvmsta->sta_id, tid, txq_id, tid_data->ssn,
tid_data->next_reclaimed);
 
-   if (tid_data->ssn == tid_data->next_reclaimed) {
+   /*
+* In A000 HW, the next_reclaimed index is only 8 bit, so we'll need
+* to align the wrap around of ssn so we compare relevant values.
+*/
+   normalized_ssn = tid_data->ssn;
+   if (mvm->trans->cfg->gen2)
+   normalized_ssn &= 0xff;
+
+   if (normalized_ssn == tid_data->next_reclaimed) {
tid_data->state = IWL_AGG_STARTING;
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
} else {
@@ -3540,7 +3549,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm 
*mvm,
return;
}
 
-   n_queued = iwl_mvm_tid_queued(tid_data);
+   n_queued = iwl_mvm_tid_queued(mvm, tid_data);
if (n_queued > remaining) {
more_data = true;
remaining = 0;
@@ -3722,3 +3731,17 @@ void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, 
struct ieee80211_vif *vif)
 
rcu_read_unlock();
 }
+
+u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data)
+{
+   u16 sn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
+
+   /*
+* In A000 HW, the next_reclaimed index is only 8 bit, so we'll need
+* to align the wrap around of ssn so we compare relevant values.
+*/
+   if (mvm->trans->cfg->gen2)
+   sn &= 0xff;
+
+   return ieee80211_sn_sub(sn, tid_data->next_reclaimed);
+}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
index 357ff2bf75c1..05fecbe87da4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
@@ -341,12 +341,6 @@ struct iwl_mvm_tid_data {
bool is_tid_active;
 };
 
-static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data)
-{
-   return ieee

[PATCH 13/25] iwlwifi: mvm: support D0I3_END_CMD at the start of resume

2017-06-22 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

New FW versions require the D0I3_END_CMD to be sent as the first
command to the FW in the resume flow.  If the TLV is set, send that
command first, otherwise keep the original behavior (i.e. send last).

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c  | 22 +++---
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
index 52616f3c0184..a216657b3c60 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
@@ -353,6 +353,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_STA_PM_NOTIF = (__force 
iwl_ucode_tlv_capa_t)38,
IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT  = (__force 
iwl_ucode_tlv_capa_t)39,
IWL_UCODE_TLV_CAPA_CDB_SUPPORT  = (__force 
iwl_ucode_tlv_capa_t)40,
+   IWL_UCODE_TLV_CAPA_D0I3_END_FIRST   = (__force 
iwl_ucode_tlv_capa_t)41,
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force 
iwl_ucode_tlv_capa_t)64,
IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS= (__force 
iwl_ucode_tlv_capa_t)65,
IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force 
iwl_ucode_tlv_capa_t)67,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index f5b65c1ef42f..0028325fa22d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -7,7 +7,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016   Intel Deutschland GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016   Intel Deutschland GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -2075,6 +2075,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool 
test)
bool keep = false;
bool unified_image = fw_has_capa(>fw->ucode_capa,
 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
+   bool d0i3_first = fw_has_capa(>fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_D0I3_END_FIRST);
 
mutex_lock(>mutex);
 
@@ -2095,6 +2097,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 (d0i3_first) {
+   ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
+   if (ret < 0) {
+   IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n",
+   ret);
+   goto err;
+   }
+   }
+
/*
 * Query the current location and source from the D3 firmware so we
 * can play it back when we re-intiailize the D0 firmware
@@ -2140,9 +2151,14 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool 
test)
iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
 
 out:
+   /* no need to reset the device in unified images, if successful */
if (unified_image && !ret) {
+   /* nothing else to do if we already sent D0I3_END_CMD */
+   if (d0i3_first)
+   return 0;
+
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
-   if (!ret) /* D3 ended successfully - no need to reset device */
+   if (!ret)
return 0;
}
 
-- 
2.11.0



[PATCH 07/25] iwlwifi: pcie: fix TVQM queue ID range check

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

The queue ID should never be 512 either, so correct the check
to be >= instead of just >.

Fixes: 310181ec34e2 ("iwlwifi: move to TVQM mode")
Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 6e186501f43c..8f00019cd3b4 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -1076,7 +1076,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
rsp = (void *)hcmd.resp_pkt->data;
qid = le16_to_cpu(rsp->queue_number);
 
-   if (qid > ARRAY_SIZE(trans_pcie->txq)) {
+   if (qid >= ARRAY_SIZE(trans_pcie->txq)) {
WARN_ONCE(1, "queue index %d unsupported", qid);
ret = -EIO;
goto error_free_resp;
-- 
2.11.0



[PATCH 00/25] iwlwifi: updates intended for v4.13 2017-06-23

2017-06-22 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

Morjens,

More patches intended for 4.13.  These are the changes:

* Johannes' documentation work continues;
* Some changes in suspend/resume handling to support new FWs;
* A bunch of RF-kill related fixes;
* Continued work towards the A000 family;
* Some small improvements, fixes and cleanups;

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

Please review.

Cheers,
Luca.


David Spinadel (1):
  iwlwifi: mvm: Enable security on new TX API

Emmanuel Grumbach (1):
  iwlwifi: mvm: avoid unnecessary cache trashing in Tx path

Gregory Greenman (1):
  iwlwifi: mvm: rs: add logs for the wrong antenna case

Johannes Berg (16):
  iwlwifi: remove resp_pkt NULL checks
  iwlwifi: mvm: remove pointless num_stored condition
  iwlwifi: pcie: fix TVQM queue ID range check
  iwlwifi: mvm: avoid variable shadowing
  iwlwifi: mvm: use scnprintf() instead of snprintf()
  iwlwifi: use bitfield.h for some registers
  iwlwifi: mvm: track and report IBSS manager status to mac80211
  iwlwifi: mvm: make iwl_mvm_update_mcc() easier to follow
  iwlwifi: pcie: pull out common rfkill IRQ handling code
  iwlwifi: pcie: add fake RF-kill to debugfs
  iwlwifi: mvm: don't warn in queue sync on RF-kill
  iwlwifi: pcie: don't report RF-kill enabled while shutting down
  iwlwifi: pcie: remove pointless debugfs parsing for csr file
  iwlwifi: mvm: document status bits
  iwlwifi: pcie: use kstrtou32_from_user()
  iwlwifi: mvm: better link scan notification results length

Liad Kaufman (3):
  iwlwifi: mvm: remove txq EMPTYING_DELBA state for DQA
  iwlwifi: mvm: disable dbg data collect when fw isn't alive
  iwlwifi: mvm: support aggregations on A000 HW

Luca Coelho (2):
  iwlwifi: mvm: make D0I3_END_CMD sync during system resume
  iwlwifi: mvm: support D0I3_END_CMD at the start of resume

Mordechai Goodstein (1):
  iwlwifi: mvm: change the firmware name loading

 drivers/net/wireless/intel/iwlwifi/iwl-a000.c  |   2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h|   1 +
 drivers/net/wireless/intel/iwlwifi/iwl-fh.h|  10 +-
 drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h   |   1 +
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h  |  17 +--
 drivers/net/wireless/intel/iwlwifi/iwl-trans.c |   5 +-
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h |   6 +-
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c|  39 +++---
 .../net/wireless/intel/iwlwifi/mvm/debugfs-vif.c   |  22 ++--
 .../net/wireless/intel/iwlwifi/mvm/fw-api-scan.h   |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c|   4 +
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c  |   1 +
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  |  31 -
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |  17 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c   |  33 ++---
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   |  19 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c|   6 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c  |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c   | 144 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/sta.h   |   8 +-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c|  24 +++-
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c |   7 +-
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c  |  12 +-
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  14 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   | 106 +++
 .../net/wireless/intel/iwlwifi/pcie/trans-gen2.c   |  28 +---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c| 145 ++---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  |   6 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   |  10 +-
 29 files changed, 434 insertions(+), 288 deletions(-)

-- 
2.11.0



[PATCH 14/25] iwlwifi: mvm: change the firmware name loading

2017-06-22 Thread Luca Coelho
From: Mordechai Goodstein <mordechay.goodst...@intel.com>

The firmware moved the development from a0 MAC to z0.
z0 is using the same RFID and device ID as a0 so we only
need to switch the name.

Signed-off-by: Mordechai Goodstein <mordechay.goodst...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-a000.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
index 63a4183c0de7..4634c46d1eb4 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c
@@ -74,7 +74,7 @@
 
 #define IWL_A000_JF_FW_PRE "iwlwifi-Qu-a0-jf-b0-"
 #define IWL_A000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
-#define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-a0-hrcdb-a0-"
+#define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
 
 #define IWL_A000_HR_MODULE_FIRMWARE(api) \
IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode"
-- 
2.11.0



[PATCH 04/25] iwlwifi: mvm: Enable security on new TX API

2017-06-22 Thread Luca Coelho
From: David Spinadel <david.spina...@intel.com>

Install GTKs on AP side for new TX API.
Don't add IV space, it's added by the HW.

While at that fix GCMP abnd GCMP-256 GTK installation
which work similarly to the new TX API.

Signed-off-by: David Spinadel <david.spina...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |  12 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 108 ++
 2 files changed, 80 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 08f86e77eba5..05041d37773b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2883,7 +2883,8 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
-   key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+   if (!iwl_mvm_has_new_tx_api(mvm))
+   key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
break;
case WLAN_CIPHER_SUITE_AES_CMAC:
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
@@ -2929,8 +2930,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
ret = -EOPNOTSUPP;
else
ret = 0;
-   key->hw_key_idx = STA_KEY_IDX_INVALID;
-   break;
+
+   if (key->cipher != WLAN_CIPHER_SUITE_GCMP &&
+   key->cipher != WLAN_CIPHER_SUITE_GCMP_256 &&
+   !iwl_mvm_has_new_tx_api(mvm)) {
+   key->hw_key_idx = STA_KEY_IDX_INVALID;
+   break;
+   }
}
 
/* During FW restart, in order to restore the state as it was,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index c76ffe1476b4..59cd2486a449 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2980,7 +2980,7 @@ static struct iwl_mvm_sta *iwl_mvm_get_key_sta(struct 
iwl_mvm *mvm,
 }
 
 static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
-   struct iwl_mvm_sta *mvm_sta,
+   u32 sta_id,
struct ieee80211_key_conf *key, bool mcast,
u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags,
u8 key_offset)
@@ -2998,6 +2998,9 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
bool new_api = fw_has_api(>fw->ucode_capa,
  IWL_UCODE_TLV_API_TKIP_MIC_KEYS);
 
+   if (sta_id == IWL_MVM_INVALID_STA)
+   return -EINVAL;
+
keyidx = (key->keyidx << STA_KEY_FLG_KEYID_POS) &
 STA_KEY_FLG_KEYID_MSK;
key_flags = cpu_to_le16(keyidx);
@@ -3056,7 +3059,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
 
u.cmd.common.key_offset = key_offset;
u.cmd.common.key_flags = key_flags;
-   u.cmd.common.sta_id = mvm_sta->sta_id;
+   u.cmd.common.sta_id = sta_id;
 
if (new_api) {
u.cmd.transmit_seq_cnt = cpu_to_le64(pn);
@@ -3189,19 +3192,37 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
 u8 key_offset,
 bool mcast)
 {
-   struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
int ret;
const u8 *addr;
struct ieee80211_key_seq seq;
u16 p1k[5];
+   u32 sta_id;
+
+   if (sta) {
+   struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+
+   sta_id = mvm_sta->sta_id;
+   } else if (vif->type == NL80211_IFTYPE_AP &&
+  !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+   struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+   sta_id = mvmvif->mcast_sta.sta_id;
+   } else {
+   IWL_ERR(mvm, "Failed to find station id\n");
+   return -EINVAL;
+   }
 
switch (keyconf->cipher) {
case WLAN_CIPHER_SUITE_TKIP:
+   if (vif->type == NL80211_IFTYPE_AP) {
+   ret = -EINVAL;
+   break;
+   }
addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
/* get phase 1 key from mac80211 */
ieee80211_get_key_rx_seq(keyconf, 0, );
ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
-   ret = iwl_mvm

[PATCH 08/25] iwlwifi: mvm: avoid variable shadowing

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Avoid one kind of symbol shadowing another in iwl_mvm_flush_sta()
by renaming the function parameter.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 9a9163f64553..cdd13bc343e6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1370,7 +1370,7 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status);
 static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; }
 #endif
 int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, u32 flags);
-int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool int_sta, u32 flags);
+int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 
flags);
 
 void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 63b938028144..da05801c9ca1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1904,11 +1904,11 @@ int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 
tfd_msk, u32 flags)
return ret;
 }
 
-int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool int_sta, u32 flags)
+int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 flags)
 {
u32 mask;
 
-   if (int_sta) {
+   if (internal) {
struct iwl_mvm_int_sta *int_sta = sta;
 
mask = int_sta->tfd_queue_msk;
-- 
2.11.0



[PATCH 09/25] iwlwifi: mvm: use scnprintf() instead of snprintf()

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

It's safer to use scnprintf() here because the buffer might
be too short for the full format strings. In most cases
this isn't true because of external limits on the values.

In one case, this fixes a stack data leak.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 .../net/wireless/intel/iwlwifi/mvm/debugfs-vif.c   | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
index 5d475b4850ae..a7ac281e5cde 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
@@ -7,7 +7,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016Intel Deutschland GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016Intel Deutschland GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1304,11 +1304,11 @@ static ssize_t iwl_dbgfs_low_latency_read(struct file 
*file,
char buf[30] = {};
int len;
 
-   len = snprintf(buf, sizeof(buf) - 1,
-  "traffic=%d\ndbgfs=%d\nvcmd=%d\n",
-  mvmvif->low_latency_traffic,
-  mvmvif->low_latency_dbgfs,
-  mvmvif->low_latency_vcmd);
+   len = scnprintf(buf, sizeof(buf) - 1,
+   "traffic=%d\ndbgfs=%d\nvcmd=%d\n",
+   mvmvif->low_latency_traffic,
+   mvmvif->low_latency_dbgfs,
+   mvmvif->low_latency_vcmd);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
@@ -1385,10 +1385,12 @@ static ssize_t iwl_dbgfs_rx_phyinfo_read(struct file 
*file,
struct ieee80211_vif *vif = file->private_data;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
char buf[8];
+   int len;
 
-   snprintf(buf, sizeof(buf), "0x%04x\n", mvmvif->mvm->dbgfs_rx_phyinfo);
+   len = scnprintf(buf, sizeof(buf), "0x%04x\n",
+   mvmvif->mvm->dbgfs_rx_phyinfo);
 
-   return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
+   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
 static void iwl_dbgfs_quota_check(void *data, u8 *mac,
@@ -1439,7 +1441,7 @@ static ssize_t iwl_dbgfs_quota_min_read(struct file *file,
char buf[10];
int len;
 
-   len = snprintf(buf, sizeof(buf), "%d\n", mvmvif->dbgfs_quota_min);
+   len = scnprintf(buf, sizeof(buf), "%d\n", mvmvif->dbgfs_quota_min);
 
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
-- 
2.11.0



[PATCH 02/25] iwlwifi: remove resp_pkt NULL checks

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Contrary to what some of the comments say, if rfkill was
asserted the transport will return -ERFKILL instead of
success, if CMD_WANT_SKB was set, so it's not necessary
to check cmd.resp_pkt for being NULL if the return code
was success.

Validate that this is true in iwl_trans_send_cmd().

Most of the other code modifications were done with the
following spatch:
@@
struct iwl_host_cmd cmd;
identifier pkt;
@@
<...
(
pkt = cmd.resp_pkt;
...
-if (!pkt) { ... }
|
pkt = cmd.resp_pkt;
...
-if (WARN_ON(!pkt)) { ... }
|
-if (!cmd.resp_pkt) { ... }
)
...>

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-trans.c |  3 +++
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c| 12 
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c   |  4 
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   |  3 ---
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c |  5 -
 5 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
index c0871f8f2c68..dcf596217d9e 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
@@ -143,6 +143,9 @@ int iwl_trans_send_cmd(struct iwl_trans *trans, struct 
iwl_host_cmd *cmd)
if (!(cmd->flags & CMD_ASYNC))
lock_map_release(>sync_cmd_lockdep_map);
 
+   if (WARN_ON((cmd->flags & CMD_WANT_SKB) && !ret && !cmd->resp_pkt))
+   return -EIO;
+
return ret;
 }
 IWL_EXPORT_SYMBOL(iwl_trans_send_cmd);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 119a3bd92c50..0493a03ec3ed 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1795,12 +1795,6 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct 
ieee80211_vif *vif)
return ERR_PTR(ret);
}
 
-   /* RF-kill already asserted again... */
-   if (!cmd.resp_pkt) {
-   fw_status = ERR_PTR(-ERFKILL);
-   goto out_free_resp;
-   }
-
status_size = sizeof(*fw_status);
 
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
@@ -1925,12 +1919,6 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
return ret;
}
 
-   /* RF-kill already asserted again... */
-   if (!cmd.resp_pkt) {
-   ret = -ERFKILL;
-   goto out_free_resp;
-   }
-
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (len < sizeof(*query)) {
IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index 87b9ebfc653e..beead0bc08c9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -118,10 +118,6 @@ static int iwl_nvm_write_chunk(struct iwl_mvm *mvm, u16 
section,
return ret;
 
pkt = cmd.resp_pkt;
-   if (!pkt) {
-   IWL_ERR(mvm, "Error in NVM_ACCESS response\n");
-   return -EINVAL;
-   }
/* Extract & check NVM write response */
nvm_resp = (void *)pkt->data;
if (le16_to_cpu(nvm_resp->status) != READ_NVM_CHUNK_SUCCEED) {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 1da55e4a1048..c9686e31b32e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1611,9 +1611,6 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
if (ret)
goto out;
 
-   if (!get_status_cmd.resp_pkt)
-   goto out;
-
status = (void *)get_status_cmd.resp_pkt->data;
wakeup_reasons = le32_to_cpu(status->wakeup_reasons);
qos_seq = status->qos_seq_ctr;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 8f4f176e204e..cc5a56818db8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -168,11 +168,6 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct 
iwl_host_cmd *cmd,
}
 
pkt = cmd->resp_pkt;
-   /* Can happen if RFKILL is asserted */
-   if (!pkt) {
-   ret = 0;
-   goto out_free_resp;
-   }
 
resp_len = iwl_rx_packet_payload_len(pkt);
if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
-- 
2.11.0



[PATCH 10/25] iwlwifi: use bitfield.h for some registers

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Letting the preprocessor/compiler generate the shift/mask by itself
is a win for readability, so use bitfield.h for some registers.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-fh.h   | 10 +-
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 17 +
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c  | 14 +++---
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  |  6 ++
 4 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
index 2a992277c671..77be149276b6 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
@@ -66,6 +66,7 @@
 #define __iwl_fh_h__
 
 #include 
+#include 
 
 //
 /* Flow Handler Definitions */
@@ -478,13 +479,12 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(struct 
iwl_trans *trans,
 #define RFH_GEN_CFG0xA09800
 #define RFH_GEN_CFG_SERVICE_DMA_SNOOP  BIT(0)
 #define RFH_GEN_CFG_RFH_DMA_SNOOP  BIT(1)
-#define RFH_GEN_CFG_RB_CHUNK_SIZE_POS  4
+#define RFH_GEN_CFG_RB_CHUNK_SIZE  BIT(4)
 #define RFH_GEN_CFG_RB_CHUNK_SIZE_128  1
 #define RFH_GEN_CFG_RB_CHUNK_SIZE_64   0
-#define RFH_GEN_CFG_DEFAULT_RXQ_NUM_MASK 0xF00
-#define RFH_GEN_CFG_DEFAULT_RXQ_NUM_POS 8
-
-#define DEFAULT_RXQ_NUM0
+/* the driver assumes everywhere that the default RXQ is 0 */
+#define RFH_GEN_CFG_DEFAULT_RXQ_NUM0xF00
+#define RFH_GEN_CFG_VAL(_n, _v)FIELD_PREP(RFH_GEN_CFG_ ## _n, 
_v)
 
 /* end of 9000 rx series registers */
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 77efbb78e867..6772c59b7764 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -66,6 +66,7 @@
 
 #ifndef__iwl_prph_h__
 #define __iwl_prph_h__
+#include 
 
 /*
  * Registers in this file are internal, not PCI bus memory mapped.
@@ -247,14 +248,14 @@
 #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
 #define SCD_QUEUE_STTS_REG_MSK (0x017F)
 
-#define SCD_QUEUE_CTX_REG1_CREDIT_POS  (8)
-#define SCD_QUEUE_CTX_REG1_CREDIT_MSK  (0x0000)
-#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS(24)
-#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK(0xFF00)
-#define SCD_QUEUE_CTX_REG2_WIN_SIZE_POS(0)
-#define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK(0x007F)
-#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
-#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F)
+#define SCD_QUEUE_CTX_REG1_CREDIT  (0x0000)
+#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT(0xFF00)
+#define SCD_QUEUE_CTX_REG1_VAL(_n, _v) FIELD_PREP(SCD_QUEUE_CTX_REG1_ 
## _n, _v)
+
+#define SCD_QUEUE_CTX_REG2_WIN_SIZE(0x007F)
+#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT (0x007F)
+#define SCD_QUEUE_CTX_REG2_VAL(_n, _v) FIELD_PREP(SCD_QUEUE_CTX_REG2_ 
## _n, _v)
+
 #define SCD_GP_CTRL_ENABLE_31_QUEUES   BIT(0)
 #define SCD_GP_CTRL_AUTO_ACTIVE_MODE   BIT(18)
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 1da2de205cdf..293f4b2c1955 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -845,14 +845,14 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans 
*trans)
 * Set RX DMA chunk size to 64B for IOSF and 128B for PCIe
 * Default queue is 0
 */
-   iwl_write_prph_no_grab(trans, RFH_GEN_CFG, RFH_GEN_CFG_RFH_DMA_SNOOP |
-  (DEFAULT_RXQ_NUM <<
-   RFH_GEN_CFG_DEFAULT_RXQ_NUM_POS) |
+   iwl_write_prph_no_grab(trans, RFH_GEN_CFG,
+  RFH_GEN_CFG_RFH_DMA_SNOOP |
+  RFH_GEN_CFG_VAL(DEFAULT_RXQ_NUM, 0) |
   RFH_GEN_CFG_SERVICE_DMA_SNOOP |
-  (trans->cfg->integrated ?
-   RFH_GEN_CFG_RB_CHUNK_SIZE_64 :
-   RFH_GEN_CFG_RB_CHUNK_SIZE_128) <<
-  RFH_GEN_CFG_RB_CHUNK_SIZE_POS);
+  RFH_GEN_CFG_VAL(RB_CHUNK_SIZE,
+  trans->cfg->integrated ?
+  RFH_GEN_CFG_RB_CHUNK_SIZE_64 :
+  RFH_GEN_CFG_RB_CHUNK_SIZE_128));
/* Enable the relevant rx queues */
iwl_write_prph_no_grab(trans, RFH_RXF_RXQ_ACTIVE, enabled);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx

[PATCH 15/25] iwlwifi: mvm: make iwl_mvm_update_mcc() easier to follow

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Some static checkers (e.g. smatch) complain about the logic, saying that
resp_cp might be leaked. Clearly that isn't true, but making the logic
easier to follow does not result in any significant code changes and makes
the code more readable by moving the NULL check closer to its source.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 29 ++--
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index beead0bc08c9..ad8bd90deed2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -779,6 +779,10 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
resp_len = sizeof(struct iwl_mcc_update_resp) +
   n_channels * sizeof(__le32);
resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
+   if (!resp_cp) {
+   resp_cp = ERR_PTR(-ENOMEM);
+   goto exit;
+   }
} else {
struct iwl_mcc_update_resp_v1 *mcc_resp_v1 = (void *)pkt->data;
 
@@ -786,21 +790,18 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char 
*alpha2,
resp_len = sizeof(struct iwl_mcc_update_resp) +
   n_channels * sizeof(__le32);
resp_cp = kzalloc(resp_len, GFP_KERNEL);
-
-   if (resp_cp) {
-   resp_cp->status = mcc_resp_v1->status;
-   resp_cp->mcc = mcc_resp_v1->mcc;
-   resp_cp->cap = mcc_resp_v1->cap;
-   resp_cp->source_id = mcc_resp_v1->source_id;
-   resp_cp->n_channels = mcc_resp_v1->n_channels;
-   memcpy(resp_cp->channels, mcc_resp_v1->channels,
-  n_channels * sizeof(__le32));
+   if (!resp_cp) {
+   resp_cp = ERR_PTR(-ENOMEM);
+   goto exit;
}
-   }
 
-   if (!resp_cp) {
-   ret = -ENOMEM;
-   goto exit;
+   resp_cp->status = mcc_resp_v1->status;
+   resp_cp->mcc = mcc_resp_v1->mcc;
+   resp_cp->cap = mcc_resp_v1->cap;
+   resp_cp->source_id = mcc_resp_v1->source_id;
+   resp_cp->n_channels = mcc_resp_v1->n_channels;
+   memcpy(resp_cp->channels, mcc_resp_v1->channels,
+  n_channels * sizeof(__le32));
}
 
status = le32_to_cpu(resp_cp->status);
@@ -820,8 +821,6 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
 
 exit:
iwl_free_resp();
-   if (ret)
-   return ERR_PTR(ret);
return resp_cp;
 }
 
-- 
2.11.0



[PATCH 12/25] iwlwifi: mvm: make D0I3_END_CMD sync during system resume

2017-06-22 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

There is no need to send D0I3_END_CMD as ASYNC during the system
resume flow.  Additionally, the other flags used are meaningless in
this case (they were just copied from the runtime resume flow), so
remove them all.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 0493a03ec3ed..f5b65c1ef42f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -2076,9 +2076,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool 
test)
bool unified_image = fw_has_capa(>fw->ucode_capa,
 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 
-   u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
-   CMD_WAKE_UP_TRANS;
-
mutex_lock(>mutex);
 
/* get the BSS vif pointer again */
@@ -2144,7 +2141,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool 
test)
 
 out:
if (unified_image && !ret) {
-   ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
+   ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
if (!ret) /* D3 ended successfully - no need to reset device */
return 0;
}
-- 
2.11.0



[PATCH 18/25] iwlwifi: pcie: add fake RF-kill to debugfs

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

In order to debug "hardware" RF-kill flows, add a low-level hook to
allow changing the "hardware" RF-kill from debugfs.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 10 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   |  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c| 40 ++
 3 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 4b7be7ba9780..17bd95614483 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -404,6 +404,7 @@ struct iwl_trans_pcie {
int ict_index;
bool use_ict;
bool is_down;
+   bool debug_rfkill;
struct isr_statistics isr_stats;
 
spinlock_t irq_lock;
@@ -675,6 +676,8 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans 
*trans)
}
 }
 
+void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans);
+
 static inline void iwl_wake_queue(struct iwl_trans *trans,
  struct iwl_txq *txq)
 {
@@ -713,7 +716,12 @@ static inline u8 get_cmd_index(struct iwl_txq *q, u32 
index)
 
 static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
 {
-   lockdep_assert_held(_TRANS_GET_PCIE_TRANS(trans)->mutex);
+   struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+   lockdep_assert_held(_pcie->mutex);
+
+   if (trans_pcie->debug_rfkill)
+   return true;
 
return !(iwl_read32(trans, CSR_GP_CNTRL) &
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index c27d6f711abf..b6b04e72521e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1509,7 +1509,7 @@ static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans)
return inta;
 }
 
-static void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans)
+void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans)
 {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct isr_statistics *isr_stats = _pcie->isr_stats;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index a3c5d3b195ad..6c4f8e377fb9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2461,11 +2461,50 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
return ret;
 }
 
+static ssize_t iwl_dbgfs_rfkill_read(struct file *file,
+char __user *user_buf,
+size_t count, loff_t *ppos)
+{
+   struct iwl_trans *trans = file->private_data;
+   struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+   char buf[100];
+   int pos;
+
+   pos = scnprintf(buf, sizeof(buf), "debug: %d\nhw: %d\n",
+   trans_pcie->debug_rfkill,
+   !(iwl_read32(trans, CSR_GP_CNTRL) &
+   CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW));
+
+   return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+static ssize_t iwl_dbgfs_rfkill_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+   struct iwl_trans *trans = file->private_data;
+   struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+   bool old = trans_pcie->debug_rfkill;
+   int ret;
+
+   ret = kstrtobool_from_user(user_buf, count, _pcie->debug_rfkill);
+   if (ret)
+   return ret;
+   if (old == trans_pcie->debug_rfkill)
+   return count;
+   IWL_WARN(trans, "changing debug rfkill %d->%d\n",
+old, trans_pcie->debug_rfkill);
+   iwl_pcie_handle_rfkill_irq(trans);
+
+   return count;
+}
+
 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 DEBUGFS_READ_FILE_OPS(fh_reg);
 DEBUGFS_READ_FILE_OPS(rx_queue);
 DEBUGFS_READ_FILE_OPS(tx_queue);
 DEBUGFS_WRITE_FILE_OPS(csr);
+DEBUGFS_READ_WRITE_FILE_OPS(rfkill);
 
 /* Create the debugfs files and directories */
 int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)
@@ -2477,6 +2516,7 @@ int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)
DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
+   DEBUGFS_ADD_FILE(rfkill, dir, S_IWUSR | S_IRUSR);
return 0;
 
 err:
-- 
2.11.0



[PATCH 24/25] iwlwifi: pcie: use kstrtou32_from_user()

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Use kstrtou32_from_user() in debugfs instead of open-coding it.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 280b14ace175..67343b10b0da 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2428,17 +2428,12 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file 
*file,
struct iwl_trans *trans = file->private_data;
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct isr_statistics *isr_stats = _pcie->isr_stats;
-
-   char buf[8];
-   int buf_size;
u32 reset_flag;
+   int ret;
 
-   memset(buf, 0, sizeof(buf));
-   buf_size = min(count, sizeof(buf) -  1);
-   if (copy_from_user(buf, user_buf, buf_size))
-   return -EFAULT;
-   if (sscanf(buf, "%x", _flag) != 1)
-   return -EFAULT;
+   ret = kstrtou32_from_user(user_buf, count, 16, _flag);
+   if (ret)
+   return ret;
if (reset_flag == 0)
memset(isr_stats, 0, sizeof(*isr_stats));
 
-- 
2.11.0



[PATCH 01/25] iwlwifi: mvm: remove txq EMPTYING_DELBA state for DQA

2017-06-22 Thread Luca Coelho
From: Liad Kaufman <liad.kauf...@intel.com>

In DQA mode, there is no need to wait for the TXQ to
clear out after getting a DELBA, since traffic can
continue running on the queue.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index bc52739eeb25..c76ffe1476b4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2814,8 +2814,13 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct 
ieee80211_vif *vif,
"ssn = %d, next_recl = %d\n",
tid_data->ssn, tid_data->next_reclaimed);
 
-   /* There are still packets for this RA / TID in the HW */
-   if (tid_data->ssn != tid_data->next_reclaimed) {
+   /*
+* There are still packets for this RA / TID in the HW.
+* Not relevant for DQA mode, since there is no need to disable
+* the queue.
+*/
+   if (!iwl_mvm_is_dqa_supported(mvm) &&
+   tid_data->ssn != tid_data->next_reclaimed) {
tid_data->state = IWL_EMPTYING_HW_QUEUE_DELBA;
err = 0;
break;
-- 
2.11.0



[PATCH 03/25] iwlwifi: mvm: disable dbg data collect when fw isn't alive

2017-06-22 Thread Luca Coelho
From: Liad Kaufman <liad.kauf...@intel.com>

If FW isn't alive, trying to collect debug data will
result in errors both in driver and in the collected
data, so just warn and leave the collecting function
in this case.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
index c66baf1e1443..d5cb47e2fe44 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
@@ -915,6 +915,10 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
if (trigger)
delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay));
 
+   if (WARN(mvm->trans->state == IWL_TRANS_NO_FW,
+"Can't collect dbg data when FW isn't alive\n"))
+   return -EIO;
+
if (test_and_set_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, >status))
return -EBUSY;
 
-- 
2.11.0



[PATCH 06/25] iwlwifi: mvm: remove pointless num_stored condition

2017-06-22 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Since we exit if buf->num_stored is 0, there's no need to
check it again later.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 966cd7543629..36fd8c87027c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -503,7 +503,7 @@ void iwl_mvm_reorder_timer_expired(unsigned long data)
 buf->sta_id, sn);
iwl_mvm_release_frames(buf->mvm, sta, NULL, buf, sn);
rcu_read_unlock();
-   } else if (buf->num_stored) {
+   } else {
/*
 * If no frame expired and there are stored frames, index is now
 * pointing to the first unexpired frame - modify timer
-- 
2.11.0



[PATCH 05/25] iwlwifi: mvm: avoid unnecessary cache trashing in Tx path

2017-06-22 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

When sending a Tx Command with a Tx packet, we allocate the
Tx command separately from the payload of the packet.
The WiFi MAC header is then copied into the buffer that was
allocated for the Tx Command. This means that this buffer
needs to be big enough to contain both. This is why it is
allocated with iwl_trans_alloc_tx_cmd which returns a
pointer to a newly allocated not zeroed struct
iwl_device_cmd.

The Tx command has a few bit fields and hence it needs to
be zeroed, but all the rest of the buffer doesn't need to
be zeroed since it will either be memcopy'ed with the MAC
header, or not even sent to the device.
This means that we don't need to zero all the
iwl_device_cmd structure, but rather only the size of
the iwl_tx_cmd structure.

Since sizeof(iwl_tx_cmd) - sizeof(iwl_tx_cmd) is about
260 bytes, this can avoid touching 4 cache lines for each
packet.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index aa3a3f336929..63b938028144 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -473,7 +473,10 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff 
*skb,
if (unlikely(!dev_cmd))
return NULL;
 
-   memset(dev_cmd, 0, sizeof(*dev_cmd));
+   /* Make sure we zero enough of dev_cmd */
+   BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_gen2) > sizeof(*tx_cmd));
+
+   memset(dev_cmd, 0, sizeof(dev_cmd->hdr) + sizeof(*tx_cmd));
dev_cmd->hdr.cmd = TX_CMD;
 
if (iwl_mvm_has_new_tx_api(mvm)) {
-- 
2.11.0



[PATCH v2] nl80211: Don't verify owner_nlportid on NAN commands

2017-06-26 Thread Luca Coelho
From: Andrei Otcheretianski <andrei.otcheretian...@intel.com>

If NAN interface is created with NL80211_ATTR_SOCKET_OWNER, the socket
that is used to create the interface is used for all NAN operations and
reporting NAN events.
However, it turns out that sending commands and receiving events on
the same socket is not possible in a completely race-free way:
If the socket buffer is overflowed by the events, the command response
will not be sent. In that case the caller will block forever on recv.
Using non-blocking socket for commands is more complicated and still
the command response or ack may not be received.
So, keep unicasting NAN events to the interface creator, but allow
using a different socket for commands.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretian...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---

In v2:
   * Andrei fixed the documentation.

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

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 828aa4703e22..51626b4175c0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1909,11 +1909,10 @@ enum nl80211_commands {
  * that configured the indoor setting, and the indoor operation would be
  * cleared when the socket is closed.
  * If set during NAN interface creation, the interface will be destroyed
- * if the socket is closed just like any other interface. Moreover, only
- * the netlink socket that created the interface will be allowed to add
- * and remove functions. NAN notifications will be sent in unicast to that
- * socket. Without this attribute, any socket can add functions and the
- * notifications will be sent to the %NL80211_MCGRP_NAN multicast group.
+ * if the socket is closed just like any other interface. Moreover, NAN
+ * notifications will be sent in unicast to that socket. Without this
+ * attribute, the notifications will be sent to the %NL80211_MCGRP_NAN
+ * multicast group.
  * If set during %NL80211_CMD_ASSOCIATE or %NL80211_CMD_CONNECT the
  * station will deauthenticate when the socket is closed.
  *
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5487cd775b6f..45ba3d0872cc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -11206,10 +11206,6 @@ static int nl80211_nan_add_func(struct sk_buff *skb,
if (!info->attrs[NL80211_ATTR_NAN_FUNC])
return -EINVAL;
 
-   if (wdev->owner_nlportid &&
-   wdev->owner_nlportid != info->snd_portid)
-   return -ENOTCONN;
-
err = nla_parse_nested(tb, NL80211_NAN_FUNC_ATTR_MAX,
   info->attrs[NL80211_ATTR_NAN_FUNC],
   nl80211_nan_func_policy, info->extack);
@@ -11441,10 +11437,6 @@ static int nl80211_nan_del_func(struct sk_buff *skb,
if (!info->attrs[NL80211_ATTR_COOKIE])
return -EINVAL;
 
-   if (wdev->owner_nlportid &&
-   wdev->owner_nlportid != info->snd_portid)
-   return -ENOTCONN;
-
cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
 
rdev_del_nan_func(rdev, wdev, cookie);
-- 
2.11.0



[PATCH 17/26] iwlwifi: mvm: set assoc_beacon_arrive_time

2017-06-25 Thread Luca Coelho
From: Avraham Stern <avraham.st...@intel.com>

When updating the mac context after association,
assoc_beacon_arrive_time is not being set, which causes the FW to
set a wrong TSF to the MAC.

Fix this by setting the assoc_beacon_arrive_time when updating the
mac context after association.

Signed-off-by: Avraham Stern <avraham.st...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 50a71da2e96e..f06751598fb8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -846,6 +846,8 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
cpu_to_le64(vif->bss_conf.sync_tsf + dtim_offs);
ctxt_sta->dtim_time =
cpu_to_le32(vif->bss_conf.sync_device_ts + dtim_offs);
+   ctxt_sta->assoc_beacon_arrive_time =
+   cpu_to_le32(vif->bss_conf.sync_device_ts);
 
IWL_DEBUG_INFO(mvm, "DTIM TBTT is 0x%llx/0x%x, offset %d\n",
   le64_to_cpu(ctxt_sta->dtim_tsf),
-- 
2.11.0



[PATCH 06/26] iwlwifi: mvm: disentangle union in TX status struct

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

This improves documentation, since kernel-doc can't deal with the
union well.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h | 73 ++
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h|  3 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |  9 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c|  3 +-
 4 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
index a5a8616dad6f..0562ce406249 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
@@ -513,7 +513,7 @@ struct agg_tx_status {
 #define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4)
 
 /**
- * struct iwl_mvm_tx_resp - notifies that fw is TXing a packet
+ * struct iwl_mvm_tx_resp_v3 - notifies that fw is TXing a packet
  * ( REPLY_TX = 0x1c )
  * @frame_count: 1 no aggregation, >1 aggregation
  * @bt_kill_count: num of times blocked by bluetooth (unused for agg)
@@ -540,7 +540,63 @@ struct agg_tx_status {
  * @tx_queue: TX queue for this response
  * @status: for non-agg:  frame status TX_STATUS_*
  * for agg: status of 1st frame, AGG_TX_STATE_*; other frame status fields
- * follow this one, up to frame_count.
+ * follow this one, up to frame_count. Length in @frame_count.
+ *
+ * After the array of statuses comes the SSN of the SCD. Look at
+ * %iwl_mvm_get_scd_ssn for more details.
+ */
+struct iwl_mvm_tx_resp_v3 {
+   u8 frame_count;
+   u8 bt_kill_count;
+   u8 failure_rts;
+   u8 failure_frame;
+   __le32 initial_rate;
+   __le16 wireless_media_time;
+
+   u8 pa_status;
+   u8 pa_integ_res_a[3];
+   u8 pa_integ_res_b[3];
+   u8 pa_integ_res_c[3];
+   __le16 measurement_req_id;
+   u8 reduced_tpc;
+   u8 reserved;
+
+   __le32 tfd_info;
+   __le16 seq_ctl;
+   __le16 byte_cnt;
+   u8 tlc_info;
+   u8 ra_tid;
+   __le16 frame_ctrl;
+   struct agg_tx_status status[];
+} __packed; /* TX_RSP_API_S_VER_3 */
+
+/**
+ * struct iwl_mvm_tx_resp - notifies that fw is TXing a packet
+ * ( REPLY_TX = 0x1c )
+ * @frame_count: 1 no aggregation, >1 aggregation
+ * @bt_kill_count: num of times blocked by bluetooth (unused for agg)
+ * @failure_rts: num of failures due to unsuccessful RTS
+ * @failure_frame: num failures due to no ACK (unused for agg)
+ * @initial_rate: for non-agg: rate of the successful Tx. For agg: rate of the
+ * Tx of all the batch. RATE_MCS_*
+ * @wireless_media_time: for non-agg: RTS + CTS + frame tx attempts time + ACK.
+ * for agg: RTS + CTS + aggregation tx time + block-ack time.
+ * in usec.
+ * @pa_status: tx power info
+ * @pa_integ_res_a: tx power info
+ * @pa_integ_res_b: tx power info
+ * @pa_integ_res_c: tx power info
+ * @measurement_req_id: tx power info
+ * @reduced_tpc: transmit power reduction used
+ * @reserved: reserved
+ * @tfd_info: TFD information set by the FH
+ * @seq_ctl: sequence control from the Tx cmd
+ * @byte_cnt: byte count from the Tx cmd
+ * @tlc_info: TLC rate info
+ * @ra_tid: bits [3:0] = ra, bits [7:4] = tid
+ * @frame_ctrl: frame control
+ * @tx_queue: TX queue for this response
+ * @status: for non-agg:  frame status TX_STATUS_*
  * For version 6 TX response isn't received for aggregation at all.
  *
  * After the array of statuses comes the SSN of the SCD. Look at
@@ -568,16 +624,9 @@ struct iwl_mvm_tx_resp {
u8 tlc_info;
u8 ra_tid;
__le16 frame_ctrl;
-   union {
-   struct {
-   struct agg_tx_status status;
-   } v3;/* TX_RSP_API_S_VER_3 */
-   struct {
-   __le16 tx_queue;
-   __le16 reserved2;
-   struct agg_tx_status status;
-   } v6;
-   };
+   __le16 tx_queue;
+   __le16 reserved2;
+   struct agg_tx_status status;
 } __packed; /* TX_RSP_API_S_VER_6 */
 
 /**
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index 7a52fb6b4924..dc613b604914 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -217,7 +217,8 @@ enum iwl_legacy_cmds {
 
/**
 * @TX_CMD: uses  iwl_tx_cmd or  iwl_tx_cmd_gen2,
-*  response in  iwl_mvm_tx_resp
+*  response in  iwl_mvm_tx_resp or
+*   iwl_mvm_tx_resp_v3
 */
TX_CMD = 0x1c,
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 0b5e92c1483e..e616472afd45 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel

[PATCH 12/26] iwlwifi: pcie: don't disable bh when handling FW errors

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

When we started using threaded irqs, all the opmode calls were changed
to be called with local_bh disabled.  The reason for this was it was
that mac80211 needs that.  When we are handling FW errors, mac80211 is
not involved, so we don't need it.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 6eef2e789426..fa5f39f72d22 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1413,11 +1413,9 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans 
*trans)
return;
}
 
-   local_bh_disable();
/* The STATUS_FW_ERROR bit is set in this function. This must happen
 * before we wake up the command caller, to ensure a proper cleanup. */
iwl_trans_fw_error(trans);
-   local_bh_enable();
 
for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
if (!trans_pcie->txq[i])
-- 
2.11.0



[PATCH 14/26] iwlwifi: mvm: don't mark TIDs that are not idle wrt BA as inactive

2017-06-25 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

A TID may not have traffic but still have a BA agreement
active (or being setup / torn down) since a BA agreement
can be triggered by a debugfs hook.
Just avoid to consider such a TID as inactive to make the
logic safer.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index e7cc8e05615a..8ba8b71dd1a4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -1215,6 +1215,10 @@ static void iwl_mvm_remove_inactive_tids(struct iwl_mvm 
*mvm,
/* If some TFDs are still queued - don't mark TID as inactive */
if (iwl_mvm_tid_queued(mvm, >tid_data[tid]))
tid_bitmap &= ~BIT(tid);
+
+   /* Don't mark as inactive any TID that has an active BA */
+   if (mvmsta->tid_data[tid].state != IWL_AGG_OFF)
+   tid_bitmap &= ~BIT(tid);
}
 
/* If all TIDs in the queue are inactive - mark queue as inactive. */
-- 
2.11.0



[PATCH 11/26] iwlwifi: mvm: fix the recovery flow while connecting

2017-06-25 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

In BSS mode in the disconnection flow, mac80211 removes
the AP station before the vif is set to unassociated.
Our firmware wants it the other way around: first set
the vif as unassociated, and then remove the AP station.

In order to bridge between those two different behaviors,
iwlmvm doesn't remove the station from the firmware when
mac80211 removes it, but only after the vif is set to
unassociated. The implementation is in
iwl_mvm_bss_info_changed_station:

if (assoc state was modified && mvmvif->ap_sta_id is VALID
&& assoc state is now UNASSC)
remove_the_station_from_the_firmware()

During the recovery flow, mac80211 re-adds the AP station
and then reconfigures the vif. Since the vif is not
associated, and then, we enter the if above (which was
intended to be taken in the disconnection flow only) and
remove the station we just added. This defeats the
recovery flow.

Fix this by not removing the AP station in this flow if
we are in recovery flow.

Cc: sta...@vger.kernel.org
Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 32 ++-
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index d608ce8305c7..d04a88c6c593 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1988,14 +1988,32 @@ static void iwl_mvm_bss_info_changed_station(struct 
iwl_mvm *mvm,
WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false),
  "Failed to update SF upon disassociation\n");
 
-   /* remove AP station now that the MAC is unassoc */
-   ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
-   if (ret)
-   IWL_ERR(mvm, "failed to remove AP station\n");
+   /*
+* If we get an assert during the connection (after the
+* station has been added, but before the vif is set
+* to associated), mac80211 will re-add the station and
+* then configure the vif. Since the vif is not
+* associated, we would remove the station here and
+* this would fail the recovery.
+*/
+   if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
+ >status)) {
+   /*
+* Remove AP station now that
+* the MAC is unassoc
+*/
+   ret = iwl_mvm_rm_sta_id(mvm, vif,
+   mvmvif->ap_sta_id);
+   if (ret)
+   IWL_ERR(mvm,
+   "failed to remove AP 
station\n");
+
+   if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
+   mvm->d0i3_ap_sta_id =
+   IWL_MVM_INVALID_STA;
+   mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
+   }
 
-   if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
-   mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
-   mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
/* remove quota for this interface */
ret = iwl_mvm_update_quotas(mvm, false, NULL);
if (ret)
-- 
2.11.0



[PATCH 19/26] iwlwifi: mvm: support new flush API

2017-06-25 Thread Luca Coelho
From: Mordechai Goodstein <mordechay.goodst...@intel.com>

This new API allows flushing queues based on station ID and TID in A000
devices.  One reason for using this is that tfd_queue_mask is only good
for 32 queues, which is not enough for A000 devices.

Signed-off-by: Sara Sharon <sara.sha...@intel.com>
Signed-off-by: Mordechai Goodstein <mordechay.goodst...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c   | 19 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h | 14 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |  2 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   | 12 +++--
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c   | 51 --
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c| 44 ++-
 6 files changed, 100 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index 744dc069ff23..c2a1aeef74ec 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -119,19 +119,30 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm 
*mvm, char *buf,
size_t count, loff_t *ppos)
 {
int ret;
-   u32 scd_q_msk;
+   u32 flush_arg;
 
if (!iwl_mvm_firmware_running(mvm) ||
mvm->cur_ucode != IWL_UCODE_REGULAR)
return -EIO;
 
-   if (sscanf(buf, "%x", _q_msk) != 1)
+   if (kstrtou32(buf, 0, _arg))
return -EINVAL;
 
-   IWL_ERR(mvm, "FLUSHING queues: scd_q_msk = 0x%x\n", scd_q_msk);
+   if (iwl_mvm_has_new_tx_api(mvm)) {
+   IWL_DEBUG_TX_QUEUES(mvm,
+   "FLUSHING all tids queues on sta_id = %d\n",
+   flush_arg);
+   mutex_lock(>mutex);
+   ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFF, 0) ? : count;
+   mutex_unlock(>mutex);
+   return ret;
+   }
+
+   IWL_DEBUG_TX_QUEUES(mvm, "FLUSHING queues mask to flush = 0x%x\n",
+   flush_arg);
 
mutex_lock(>mutex);
-   ret =  iwl_mvm_flush_tx_path(mvm, scd_q_msk, 0) ? : count;
+   ret =  iwl_mvm_flush_tx_path(mvm, flush_arg, 0) ? : count;
mutex_unlock(>mutex);
 
return ret;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
index 0562ce406249..a37c584b0b48 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
@@ -846,12 +846,24 @@ enum iwl_dump_control {
  * @flush_ctl: control flags
  * @reserved: reserved
  */
-struct iwl_tx_path_flush_cmd {
+struct iwl_tx_path_flush_cmd_v1 {
__le32 queues_ctl;
__le16 flush_ctl;
__le16 reserved;
 } __packed; /* TX_PATH_FLUSH_CMD_API_S_VER_1 */
 
+/**
+ * struct iwl_tx_path_flush_cmd -- queue/FIFO flush command
+ * @sta_id: station ID to flush
+ * @tid_mask: TID mask to flush
+ * @reserved: reserved
+ */
+struct iwl_tx_path_flush_cmd {
+   __le32 sta_id;
+   __le16 tid_mask;
+   __le16 reserved;
+} __packed; /* TX_PATH_FLUSH_CMD_API_S_VER_2 */
+
 /* Available options for the SCD_QUEUE_CFG HCMD */
 enum iwl_scd_cfg_actions {
SCD_CFG_DISABLE_QUEUE   = 0x0,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 7171928872de..3b1f15873034 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1385,6 +1385,8 @@ static inline const char *iwl_mvm_get_tx_fail_reason(u32 
status) { return ""; }
 #endif
 int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, u32 flags);
 int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 
flags);
+int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id,
+  u16 tids, u32 flags);
 
 void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index fc2c607013fb..2e4bfe9f07ec 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1477,9 +1477,15 @@ int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
synchronize_net();
 
/* Flush the hw queues, in case something got queued during entry */
-   ret = iwl_mvm_flush_tx_path(mvm, iwl_mvm_flushable_queues(mvm), flags);
-   if (ret)
-   return ret;
+   /* TODO new tx api */
+   if (iwl_mvm_has_new_tx_api(mvm)) {
+   WARN_ONCE(1, "d0i3: Need to implement flush TX queue\n");
+   } else {
+   ret = iwl_mvm_

[PATCH 21/26] iwlwifi: mvm: print base HW address during init

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

It's sometimes hard to find out which HW address the iwlwifi device is
using, for instance when reading crouded sniffer logs.  To make it
easier, print out an info level message with the HW address as soon as
we know it.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c   | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 070f3dfb94ce..5c08f4d40f6a 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -640,6 +640,8 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
return -EINVAL;
}
 
+   IWL_INFO(trans, "base HW address: %pM\n", data->hw_addr);
+
return 0;
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index efdcffbaac6f..dac7e542a190 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -599,6 +599,8 @@ int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm)
goto err_free;
}
 
+   IWL_INFO(trans, "base HW address: %pM\n", mvm->nvm_data->hw_addr);
+
/* Initialize general data */
mvm->nvm_data->nvm_version = le16_to_cpu(rsp->general.nvm_version);
 
-- 
2.11.0



[PATCH 26/26] iwlwifi: mvm: support TX on MONITOR iface

2017-06-25 Thread Luca Coelho
From: Liad Kaufman <liad.kauf...@intel.com>

When trying to TX through a monitor interface, the
conditions in iwl_mvm_tx_skb_non_sta() don't match
and the frame tries to go out from an usued TXQ.

Add a check for monitor iface, and use the AUX queue
in such a case.

In non-DQA mode the frame is sent through the
static-allocated queues anyway, so the problem is
in DQA mode only.

Signed-off-by: Liad Kaufman <liad.kauf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 157a75394763..c89bb453c496 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -651,6 +651,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct 
sk_buff *skb)
   info.control.vif->type == NL80211_IFTYPE_STATION &&
   queue != mvm->aux_queue) {
queue = IWL_MVM_DQA_BSS_CLIENT_QUEUE;
+   } else if (iwl_mvm_is_dqa_supported(mvm) &&
+  info.control.vif->type == NL80211_IFTYPE_MONITOR) {
+   queue = mvm->aux_queue;
}
}
 
-- 
2.11.0



[PATCH 20/26] iwlwifi: mvm: document assoc_beacon_arrive_time

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

Document the assoc_beacon_arrive_time element in the iwl_mac_data_sta
struct.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h
index aa5aaf7c940d..1d970bf0d735 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h
@@ -199,6 +199,7 @@ struct iwl_mac_data_ibss {
  * @dtim_reciprocal: 2^32 / dtim_interval , applicable only when associated
  * @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
  */
 struct iwl_mac_data_sta {
__le32 is_assoc;
-- 
2.11.0



[PATCH 15/26] iwlwifi: add a W/A for a scheduler hardware bug

2017-06-25 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

In case we need to move the scheduler write pointer by
steps of 0x40, 0x80 or 0xc0, the scheduler gets stuck.
This leads to hardware error interrupts with status:
0x5A5A5A5A or alike.

In order to work around this, detect in the transport
layer that we are going to hit this case and tell iwlmvm
to increment the sequence number of the packets. This
allows to keep the requirement that the WiFi sequence
number is in sync with the index in the scheduler Tx queue
and it also allows to avoid the problematic sequence.
This means that from time to time, we will start a queue
from ssn + 1, but that shouldn't be a problem since we
don't switch to new queues for AMPDU now that we have
DQA which allows to keep the same queue while toggling
the AMPDU state.

This bug has been fixed on 9000 devices and up.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 13 +++---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c   | 17 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 50 --
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   | 22 +-
 6 files changed, 72 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 2e975c0be045..57db6250a329 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -482,7 +482,9 @@ struct iwl_trans_txq_scd_cfg {
  * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before
  * this one. The op_mode must not configure the HCMD queue. The scheduler
  * configuration may be %NULL, in which case the hardware will not be
- * configured. May sleep.
+ * configured. If true is returned, the operation mode needs to increment
+ * the sequence number of the packets routed to this queue because of a
+ * hardware scheduler bug. May sleep.
  * @txq_disable: de-configure a Tx queue to send AMPDUs
  * Must be atomic
  * @txq_set_shared_mode: change Tx queue shared/unshared marking
@@ -544,7 +546,7 @@ struct iwl_trans_ops {
void (*reclaim)(struct iwl_trans *trans, int queue, int ssn,
struct sk_buff_head *skbs);
 
-   void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
+   bool (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
   const struct iwl_trans_txq_scd_cfg *cfg,
   unsigned int queue_wdg_timeout);
void (*txq_disable)(struct iwl_trans *trans, int queue,
@@ -952,7 +954,7 @@ static inline void iwl_trans_txq_disable(struct iwl_trans 
*trans, int queue,
trans->ops->txq_disable(trans, queue, configure_scd);
 }
 
-static inline void
+static inline bool
 iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
 const struct iwl_trans_txq_scd_cfg *cfg,
 unsigned int queue_wdg_timeout)
@@ -961,10 +963,11 @@ iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int 
queue, u16 ssn,
 
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
-   return;
+   return false;
}
 
-   trans->ops->txq_enable(trans, queue, ssn, cfg, queue_wdg_timeout);
+   return trans->ops->txq_enable(trans, queue, ssn,
+ cfg, queue_wdg_timeout);
 }
 
 static inline void
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index e616472afd45..7171928872de 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1744,7 +1744,7 @@ static inline bool iwl_mvm_vif_low_latency(struct 
iwl_mvm_vif *mvmvif)
 }
 
 /* hw scheduler queue config */
-void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
+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,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 0249300c4600..aa41ee8ed916 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -758,7 +758,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
bool using_inactive_queue = false, same_sta = false;
unsigned long disable_agg_tids = 0;

[PATCH 22/26] iwlwifi: pcie: reduce unwanted noise in the logs

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

The driver prints "L1 Enabled - LTR Enabled" all the time as dev_info,
which is just useless noise in most cases.  Convert this to
IWL_DEBUG_POWER() so we don't pollute the log unnecessarily but still
can get this info on demand.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 106e822308c7..233b6734c237 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -224,9 +224,9 @@ void iwl_pcie_apm_config(struct iwl_trans *trans)
 
pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, );
trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN;
-   dev_info(trans->dev, "L1 %sabled - LTR %sabled\n",
-(lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis",
-trans->ltr_enabled ? "En" : "Dis");
+   IWL_DEBUG_POWER(trans, "L1 %sabled - LTR %sabled\n",
+   (lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis",
+   trans->ltr_enabled ? "En" : "Dis");
 }
 
 /*
-- 
2.11.0



[PATCH 10/26] iwlwifi: mvm: fix nvm_data leak

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

We allocate nvm_data in iwl_mvm_nvm_get_from_fw().  If something goes
wrong after the allocation (i.e. if no valid MAC address is valid), we
should free nvm_data before returning an error.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index ad8bd90deed2..efdcffbaac6f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -596,7 +596,7 @@ int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm)
if (!is_valid_ether_addr(mvm->nvm_data->hw_addr)) {
IWL_ERR(trans, "no valid mac address was found\n");
ret = -EINVAL;
-   goto out;
+   goto err_free;
}
 
/* Initialize general data */
@@ -628,7 +628,11 @@ int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm)
mvm->nvm_data->valid_rx_ant & mvm->fw->valid_rx_ant,
rsp->regulatory.lar_enabled && lar_fw_supported);
 
-   ret = 0;
+   iwl_free_resp();
+   return 0;
+
+err_free:
+   kfree(mvm->nvm_data);
 out:
iwl_free_resp();
return ret;
-- 
2.11.0



[PATCH 24/26] iwlwifi: mvm: fix typo in CTDP_CMD_OPERATION_REPORT description

2017-06-25 Thread Luca Coelho
From: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>

Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.i...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index 224d10b1b076..b84e8ddbbbc9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -2130,7 +2130,7 @@ struct ct_kill_notif {
 * enum ctdp_cmd_operation - CTDP command operations
 * @CTDP_CMD_OPERATION_START: update the current budget
 * @CTDP_CMD_OPERATION_STOP: stop ctdp
-* @CTDP_CMD_OPERATION_REPORT: get the avgerage budget
+* @CTDP_CMD_OPERATION_REPORT: get the average budget
 */
 enum iwl_mvm_ctdp_cmd_operation {
CTDP_CMD_OPERATION_START= 0x1,
-- 
2.11.0



[PATCH 16/26] iwlwifi: pcie: make iwl_pcie_apm_stop_master() return void

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Nothing ever checks the return value of iwl_pcie_apm_stop_master(),
so there's no point in it having one - make it return void.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 +-
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c| 6 ++
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h 
b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 4295b8409720..1f4bc933f0f2 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -779,7 +779,7 @@ void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans 
*trans,
   bool was_in_rfkill);
 void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq);
 int iwl_queue_space(const struct iwl_txq *q);
-int iwl_pcie_apm_stop_master(struct iwl_trans *trans);
+void iwl_pcie_apm_stop_master(struct iwl_trans *trans);
 void iwl_pcie_conf_msix_hw(struct iwl_trans_pcie *trans_pcie);
 int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
  int slots_num, bool cmd_queue);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 67343b10b0da..106e822308c7 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -448,9 +448,9 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans 
*trans)
 ~SHR_APMG_XTAL_CFG_XTAL_ON_REQ);
 }
 
-int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
+void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
 {
-   int ret = 0;
+   int ret;
 
/* stop device's busmaster DMA activity */
iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
@@ -462,8 +462,6 @@ int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
 
IWL_DEBUG_INFO(trans, "stop master\n");
-
-   return ret;
 }
 
 static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
-- 
2.11.0



[PATCH 09/26] iwlwifi: remove useless iwl_free_nvm_data() function

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

This function just calls kfree(), so it only obscures the code without
bringing any benefits.  Remove it.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 ++--
 drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h | 9 -
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  | 2 +-
 3 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c 
b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index b49848683587..4c8f9f1a5532 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1513,7 +1513,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct 
iwl_trans *trans,
 out_free_eeprom_blob:
kfree(priv->eeprom_blob);
 out_free_eeprom:
-   iwl_free_nvm_data(priv->nvm_data);
+   kfree(priv->nvm_data);
 out_free_hw:
ieee80211_free_hw(priv->hw);
 out:
@@ -1532,7 +1532,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode 
*op_mode)
iwl_tt_exit(priv);
 
kfree(priv->eeprom_blob);
-   iwl_free_nvm_data(priv->nvm_data);
+   kfree(priv->nvm_data);
 
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
index e04a91d70a15..b33888991b94 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
@@ -121,15 +121,6 @@ struct iwl_nvm_data *
 iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
  const u8 *eeprom, size_t eeprom_size);
 
-/**
- * iwl_free_nvm_data - free NVM data
- * @data: the data to free
- */
-static inline void iwl_free_nvm_data(struct iwl_nvm_data *data)
-{
-   kfree(data);
-}
-
 int iwl_nvm_check_version(struct iwl_nvm_data *data,
  struct iwl_trans *trans);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 4e66cc662120..fc2c607013fb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -849,7 +849,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode 
*op_mode)
iwl_phy_db_free(mvm->phy_db);
mvm->phy_db = NULL;
 
-   iwl_free_nvm_data(mvm->nvm_data);
+   kfree(mvm->nvm_data);
for (i = 0; i < NVM_MAX_NUM_SECTIONS; i++)
kfree(mvm->nvm_sections[i].data);
 
-- 
2.11.0



[PATCH 03/26] iwlwifi: pcie: fix command completion name debug

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

When the command name is printed on command completion, the wrong
group is used, leading to the wrong name being printed. Fix this
by using the group ID without inappropriately mangling it through
iwl_cmd_groupid() - it's already a u8. Also, while at it, use it
from the same place as the command ID, everything else is just
confusing.

Fixes: ab02165ccec4 ("iwlwifi: add wide firmware command infrastructure for TX")
Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index be38dd3a6d93..6b19ccc0ae41 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1706,7 +1706,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
 {
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
-   u8 group_id = iwl_cmd_groupid(pkt->hdr.group_id);
+   u8 group_id;
u32 cmd_id;
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
@@ -1732,6 +1732,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
cmd_index = get_cmd_index(txq, index);
cmd = txq->entries[cmd_index].cmd;
meta = >entries[cmd_index].meta;
+   group_id = cmd->hdr.group_id;
cmd_id = iwl_cmd_id(cmd->hdr.cmd, group_id, 0);
 
iwl_pcie_tfd_unmap(trans, meta, txq, index);
-- 
2.11.0



[PATCH 08/26] iwlwifi: document transmit buffer bits better

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Properly document the transmit buffer bits using an enum and
kernel-doc documentation.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-fh.h | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
index 77be149276b6..66e5db41e559 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -655,6 +655,17 @@ static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
 {
return (sizeof(addr) > sizeof(u32) ? upper_32_bits(addr) : 0) & 0xF;
 }
+
+/**
+ * enum iwl_tfd_tb_hi_n_len - TB hi_n_len bits
+ * @TB_HI_N_LEN_ADDR_HI_MSK: high 4 bits (to make it 36) of DMA address
+ * @TB_HI_N_LEN_LEN_MSK: length of the TB
+ */
+enum iwl_tfd_tb_hi_n_len {
+   TB_HI_N_LEN_ADDR_HI_MSK = 0xf,
+   TB_HI_N_LEN_LEN_MSK = 0xfff0,
+};
+
 /**
  * struct iwl_tfd_tb transmit buffer descriptor within transmit frame 
descriptor
  *
@@ -662,8 +673,7 @@ static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
  *
  * @lo: low [31:0] portion of the dma address of TX buffer
  * every even is unaligned on 16 bit boundary
- * @hi_n_len 0-3 [35:32] portion of dma
- *  4-15 length of the tx buffer
+ * @hi_n_len:  iwl_tfd_tb_hi_n_len
  */
 struct iwl_tfd_tb {
__le32 lo;
-- 
2.11.0



[PATCH 00/26] iwlwifi: updates intended for v4.13 2017-06-25

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

Hi,

More patches intended for 4.13.  These are the changes:

* Support for a new version of the TX flush FW API;
* Some fixes in monitor interfaces;
* A few fixes in the recovery flows;
* Documentation fixes and FW API struct cleanups;
* Remove some noise from the kernel logs;
* Clean-ups and small fixes here and there.

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

Please review.

Cheers,
Luca.

Avraham Stern (1):
  iwlwifi: mvm: set assoc_beacon_arrive_time

Chaya Rachel Ivgi (1):
  iwlwifi: mvm: fix typo in CTDP_CMD_OPERATION_REPORT description

Emmanuel Grumbach (5):
  iwlwifi: mvm: fix the recovery flow while connecting
  iwlwifi: mvm: don't mark TIDs that are not idle wrt BA as inactive
  iwlwifi: add a W/A for a scheduler hardware bug
  iwlwifi: mvm: reset the fw_dump_desc pointer after ASSERT
  iwlwifi: pcie: delete the Tx queue timer earlier upon firmware crash

Johannes Berg (9):
  iwlwifi: simplify data tracepoint
  iwlwifi: fix TX tracing for non-linear SKBs
  iwlwifi: pcie: fix command completion name debug
  iwlwifi: mvm: docs: fix enum link, provide TX response link
  iwlwifi: mvm: disentangle union in TX status struct
  iwlwifi: mvm: add documentation for enum iwl_debug_cmds
  iwlwifi: document transmit buffer bits better
  iwlwifi: pcie: make iwl_pcie_apm_stop_master() return void
  iwlwifi: pcie: work around suspend/resume issue

Liad Kaufman (2):
  iwlwifi: mvm: fix fw monitor 7000 HW recollecting
  iwlwifi: mvm: support TX on MONITOR iface

Luca Coelho (7):
  iwlwifi: remove useless iwl_free_nvm_data() function
  iwlwifi: mvm: fix nvm_data leak
  iwlwifi: pcie: don't disable bh when handling FW errors
  iwlwifi: mvm: reset the HW before dumping if HW error is detected
  iwlwifi: mvm: document assoc_beacon_arrive_time
  iwlwifi: mvm: print base HW address during init
  iwlwifi: pcie: reduce unwanted noise in the logs

Mordechai Goodstein (1):
  iwlwifi: mvm: support new flush API

 drivers/net/wireless/intel/iwlwifi/dvm/main.c  |  4 +-
 drivers/net/wireless/intel/iwlwifi/iwl-csr.h   |  4 +
 .../net/wireless/intel/iwlwifi/iwl-devtrace-data.h | 11 +--
 .../wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h  | 19 +++--
 .../net/wireless/intel/iwlwifi/iwl-eeprom-parse.h  |  9 ---
 drivers/net/wireless/intel/iwlwifi/iwl-fh.h| 18 -
 drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c |  2 +
 drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 13 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c   | 19 -
 .../net/wireless/intel/iwlwifi/mvm/fw-api-mac.h|  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h | 89 ++
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h| 23 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c|  6 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c  |  2 +
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  | 32 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h   | 13 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/nvm.c   | 10 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   | 20 +++--
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c   | 68 ++---
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c| 50 +---
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 86 +++--
 drivers/net/wireless/intel/iwlwifi/pcie/internal.h |  4 +-
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c   | 10 +--
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c| 23 --
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  |  8 +-
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   | 33 ++--
 26 files changed, 413 insertions(+), 164 deletions(-)

-- 
2.11.0



[PATCH 04/26] iwlwifi: mvm: docs: fix enum link, provide TX response link

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

Fix the enum link by adding the missing & and provide the link
to the TX response documentation.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h | 2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h| 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
index c30e0e95b0b0..a5a8616dad6f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
@@ -488,7 +488,7 @@ enum iwl_tx_agg_status {
 
 /**
  * struct agg_tx_status - per packet TX aggregation status
- * @status: enum iwl_tx_agg_status
+ * @status: See  iwl_tx_agg_status
  * @sequence: Sequence # for this frame's Tx cmd (not SSN!)
  */
 struct agg_tx_status {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index cc6af9bd4e10..7a52fb6b4924 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -216,7 +216,8 @@ enum iwl_legacy_cmds {
FW_GET_ITEM_CMD = 0x1a,
 
/**
-* @TX_CMD: uses  iwl_tx_cmd or  iwl_tx_cmd_gen2
+* @TX_CMD: uses  iwl_tx_cmd or  iwl_tx_cmd_gen2,
+*  response in  iwl_mvm_tx_resp
 */
TX_CMD = 0x1c,
 
-- 
2.11.0



[PATCH 01/26] iwlwifi: simplify data tracepoint

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

There's no need to calculate the data_len outside of the tracepoint,
since it's always skb->len - hdr_len, which are both available inside.
Simplify the callers and move the calculation in.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h | 11 ++-
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c  |  3 +--
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c   |  3 +--
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
index d80312b46f16..a80e4202cd03 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
@@ -35,19 +35,20 @@
 
 TRACE_EVENT(iwlwifi_dev_tx_data,
TP_PROTO(const struct device *dev,
-struct sk_buff *skb,
-u8 hdr_len, size_t data_len),
-   TP_ARGS(dev, skb, hdr_len, data_len),
+struct sk_buff *skb, u8 hdr_len),
+   TP_ARGS(dev, skb, hdr_len),
TP_STRUCT__entry(
DEV_ENTRY
 
-   __dynamic_array(u8, data, iwl_trace_data(skb) ? data_len : 0)
+   __dynamic_array(u8, data,
+   iwl_trace_data(skb) ? skb->len - hdr_len : 0)
),
TP_fast_assign(
DEV_ASSIGN;
if (iwl_trace_data(skb))
skb_copy_bits(skb, hdr_len,
- __get_dynamic_array(data), data_len);
+ __get_dynamic_array(data),
+ skb->len - hdr_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 464a435a4440..a0b237b58b3d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -469,8 +469,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct 
iwl_trans *trans,
trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), _cmd->hdr,
 IWL_FIRST_TB_SIZE + tb1_len,
 skb->data + hdr_len, tb2_len);
-   trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len,
- skb->len - hdr_len);
+   trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len);
 
return tfd;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 0a6e36a8a0bf..98cccaeeecdd 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1979,8 +1979,7 @@ static int iwl_fill_data_tbs(struct iwl_trans *trans, 
struct sk_buff *skb,
 trans_pcie->tfd_size,
 _cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len,
 skb->data + hdr_len, tb2_len);
-   trace_iwlwifi_dev_tx_data(trans->dev, skb,
- hdr_len, skb->len - hdr_len);
+   trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len);
return 0;
 }
 
-- 
2.11.0



[PATCH 02/26] iwlwifi: fix TX tracing for non-linear SKBs

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

When sending non-linear SKBs that should be included in the regular
TX tracing completely (and not be pushed into the tx_data tracing),
the (tracing) code didn't correctly take the fact that they were
non-linear into account and added only the skb head portion.

This probably never really triggered, since those frames we want
traced fully are most likely linear anyway, but the code gets easier
to understand and we lose an argument to the tracing function, so
overall fixing this is better.

Fixes: 206eea783385 ("iwlwifi: pcie: support frag SKBs")
Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 .../net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h | 19 ---
 drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c |  5 ++---
 drivers/net/wireless/intel/iwlwifi/pcie/tx.c  |  5 ++---
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
index f02e2c89abbb..7f16dcce0995 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
@@ -2,7 +2,7 @@
  *
  * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016Intel Deutschland GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -91,8 +91,8 @@ TRACE_EVENT(iwlwifi_dev_tx,
TP_PROTO(const struct device *dev, struct sk_buff *skb,
 void *tfd, size_t tfdlen,
 void *buf0, size_t buf0_len,
-void *buf1, size_t buf1_len),
-   TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
+int hdr_len),
+   TP_ARGS(dev, skb, tfd, tfdlen, buf0, buf0_len, hdr_len),
TP_STRUCT__entry(
DEV_ENTRY
 
@@ -105,15 +105,20 @@ TRACE_EVENT(iwlwifi_dev_tx,
 * for the possible padding).
 */
__dynamic_array(u8, buf0, buf0_len)
-   __dynamic_array(u8, buf1, iwl_trace_data(skb) ? 0 : buf1_len)
+   __dynamic_array(u8, buf1, hdr_len > 0 && iwl_trace_data(skb) ?
+   0 : skb->len - hdr_len)
),
TP_fast_assign(
DEV_ASSIGN;
-   __entry->framelen = buf0_len + buf1_len;
+   __entry->framelen = buf0_len;
+   if (hdr_len > 0)
+   __entry->framelen += skb->len - hdr_len;
memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
-   if (!iwl_trace_data(skb))
-   memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
+   if (hdr_len > 0 && !iwl_trace_data(skb))
+   skb_copy_bits(skb, hdr_len,
+ __get_dynamic_array(buf1),
+ skb->len - hdr_len);
),
TP_printk("[%s] TX %.2x (%zu bytes)",
  __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0],
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index a0b237b58b3d..a3795ba0d7b9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -249,7 +249,7 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans 
*trans,
IEEE80211_CCMP_HDR_LEN : 0;
 
trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd),
-_cmd->hdr, start_len, NULL, 0);
+_cmd->hdr, start_len, 0);
 
ip_hdrlen = skb_transport_header(skb) - skb_network_header(skb);
snap_ip_tcp_hdrlen = 8 + ip_hdrlen + tcp_hdrlen(skb);
@@ -467,8 +467,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct 
iwl_trans *trans,
}
 
trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), _cmd->hdr,
-IWL_FIRST_TB_SIZE + tb1_len,
-skb->data + hdr_len, tb2_len);
+IWL_FIRST_TB_SIZE + tb1_len, hdr_len);
trace_iwlwifi_dev_tx_data(trans->dev, skb, hdr_len);
 
return tfd;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 98cccaeeecdd..be38dd3a6d93 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1978,7 +1978,7 @@ static int iwl_fill_data_tbs(struct iwl_trans *tran

[PATCH 25/26] iwlwifi: pcie: work around suspend/resume issue

2017-06-25 Thread Luca Coelho
From: Johannes Berg <johannes.b...@intel.com>

In some platforms, having the device enabled with certain radio
frontends causes the platform to not be able to resume properly
from suspend, regardless of the wakeup cause. This was traced to
a hardware issue with the integrated 9000-series A-step variant.
Set the right hardware bit to disable the problematic state.

Signed-off-by: Johannes Berg <johannes.b...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-csr.h|  4 
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 11 +++
 2 files changed, 15 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index 36fb20168598..e239b1d92cf9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -153,6 +153,10 @@
 /* GIO Chicken Bits (PCI Express bus link power management) */
 #define CSR_GIO_CHICKEN_BITS(CSR_BASE+0x100)
 
+/* host chicken bits */
+#define CSR_HOST_CHICKEN   (CSR_BASE + 0x204)
+#define CSR_HOST_CHICKEN_PM_IDLE_SRC_DIS_SB_PMEBIT(19)
+
 /* Analog phase-lock-loop configuration  */
 #define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 233b6734c237..5778ba2278d1 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3134,6 +3134,17 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev 
*pdev,
}
}
 
+   /*
+* 9000-series integrated A-step has a problem with suspend/resume
+* and sometimes even causes the whole platform to get stuck. This
+* workaround makes the hardware not go into the problematic state.
+*/
+   if (trans->cfg->integrated &&
+   trans->cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
+   CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)
+   iwl_set_bit(trans, CSR_HOST_CHICKEN,
+   CSR_HOST_CHICKEN_PM_IDLE_SRC_DIS_SB_PME);
+
trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
 
iwl_pcie_set_interrupt_capa(pdev, trans);
-- 
2.11.0



[PATCH 23/26] iwlwifi: pcie: delete the Tx queue timer earlier upon firmware crash

2017-06-25 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

When the firmware crashes, the transmit queues can't make
any progress. This is why we stop the counter that monitor
the transmit queues' activity.
The call that notifies the error to the op_mode may take
a bit of time, so stop the timer of the transmit queues
earlier.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c 
b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index fa5f39f72d22..a5c0f69423d2 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1413,16 +1413,16 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans 
*trans)
return;
}
 
-   /* The STATUS_FW_ERROR bit is set in this function. This must happen
-* before we wake up the command caller, to ensure a proper cleanup. */
-   iwl_trans_fw_error(trans);
-
for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
if (!trans_pcie->txq[i])
continue;
del_timer(_pcie->txq[i]->stuck_timer);
}
 
+   /* The STATUS_FW_ERROR bit is set in this function. This must happen
+* before we wake up the command caller, to ensure a proper cleanup. */
+   iwl_trans_fw_error(trans);
+
clear_bit(STATUS_SYNC_HCMD_ACTIVE, >status);
wake_up(_pcie->wait_command_queue);
 }
-- 
2.11.0



[PATCH 13/26] iwlwifi: mvm: reset the HW before dumping if HW error is detected

2017-06-25 Thread Luca Coelho
From: Luca Coelho <luciano.coe...@intel.com>

If the hardware is stuck, we can't read any of the memory we need to
dump it, so we end up printing only 0xa5a5a5a5, which is useless.

To solve this, poke the hardware by triggering a reset and re-enabling
the clocks if we detect a HW error.

Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 32 ++
 1 file changed, 32 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index dc8104d846f9..e7cc8e05615a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -69,6 +69,7 @@
 #include "iwl-debug.h"
 #include "iwl-io.h"
 #include "iwl-prph.h"
+#include "iwl-csr.h"
 #include "fw-dbg.h"
 #include "mvm.h"
 #include "fw-api-rs.h"
@@ -497,6 +498,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm 
*mvm, u32 base)
 {
struct iwl_trans *trans = mvm->trans;
struct iwl_error_event_table table;
+   u32 val;
 
if (mvm->cur_ucode == IWL_UCODE_INIT) {
if (!base)
@@ -515,6 +517,36 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm 
*mvm, u32 base)
return;
}
 
+   /* check if there is a HW error */
+   val = iwl_trans_read_mem32(trans, base);
+   if (((val & ~0xf) == 0xa5a5a5a0) || ((val & ~0xf) == 0x5a5a5a50)) {
+   int err;
+
+   IWL_ERR(trans, "HW error, resetting before reading\n");
+
+   /* reset the device */
+   iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+   usleep_range(1000, 2000);
+
+   /* set INIT_DONE flag */
+   iwl_set_bit(trans, CSR_GP_CNTRL,
+   CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+   /* and wait for clock stabilization */
+   if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+   udelay(2);
+
+   err = iwl_poll_bit(trans, CSR_GP_CNTRL,
+  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+  25000);
+   if (err < 0) {
+   IWL_DEBUG_INFO(trans,
+  "Failed to reset the card for the 
dump\n");
+   return;
+   }
+   }
+
iwl_trans_read_mem_bytes(trans, base, , sizeof(table));
 
if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
-- 
2.11.0



Re: [PATCH] nl80211: Don't verify owner_nlportid on NAN commands

2017-06-26 Thread Luca Coelho
On Fri, 2017-06-23 at 23:03 +0200, Arend van Spriel wrote:
> On 23-06-17 11:26, Luca Coelho wrote:
> > From: Andrei Otcheretianski <andrei.otcheretian...@intel.com>
> > 
> > If NAN interface is created with NL80211_ATTR_SOCKET_OWNER, the socket
> > that is used to create the interface is used for all NAN operations and
> > reporting NAN events.
> > However, it turns out that sending commands and receiving events on
> > the same socket is not possible in a completely race-free way:
> > If the socket buffer is overflowed by the events, the command response
> > will not be sent. In that case the caller will block forever on recv.
> > Using non-blocking socket for commands is more complicated and still
> > the command response or ack may not be received.
> > So, keep unicasting NAN events to the interface creator, but allow
> > using a different socket for commands.
> 
> Sounds like this patch is missing significant changes in the
> documentation of nl80211 API:

Thanks Arend!

Andrei is going to fix the documentation and I'll send v2.


--
Luca.


[PATCH] nl80211: Don't verify owner_nlportid on NAN commands

2017-06-23 Thread Luca Coelho
From: Andrei Otcheretianski <andrei.otcheretian...@intel.com>

If NAN interface is created with NL80211_ATTR_SOCKET_OWNER, the socket
that is used to create the interface is used for all NAN operations and
reporting NAN events.
However, it turns out that sending commands and receiving events on
the same socket is not possible in a completely race-free way:
If the socket buffer is overflowed by the events, the command response
will not be sent. In that case the caller will block forever on recv.
Using non-blocking socket for commands is more complicated and still
the command response or ack may not be received.
So, keep unicasting NAN events to the interface creator, but allow
using a different socket for commands.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretian...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 net/wireless/nl80211.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5487cd775b6f..45ba3d0872cc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -11206,10 +11206,6 @@ static int nl80211_nan_add_func(struct sk_buff *skb,
if (!info->attrs[NL80211_ATTR_NAN_FUNC])
return -EINVAL;
 
-   if (wdev->owner_nlportid &&
-   wdev->owner_nlportid != info->snd_portid)
-   return -ENOTCONN;
-
err = nla_parse_nested(tb, NL80211_NAN_FUNC_ATTR_MAX,
   info->attrs[NL80211_ATTR_NAN_FUNC],
   nl80211_nan_func_policy, info->extack);
@@ -11441,10 +11437,6 @@ static int nl80211_nan_del_func(struct sk_buff *skb,
if (!info->attrs[NL80211_ATTR_COOKIE])
return -EINVAL;
 
-   if (wdev->owner_nlportid &&
-   wdev->owner_nlportid != info->snd_portid)
-   return -ENOTCONN;
-
cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
 
rdev_del_nan_func(rdev, wdev, cookie);
-- 
2.11.0



pull-request: iwlwifi firmwares update 2017-06-27

2017-06-27 Thread Luca Coelho
Hi Kyle,

We have some updates for our -27 firmware version (on supported devices)
and versions -29 and -31 that will be supported by the iwlwifi driver on
v4.13.

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

Cheers,
Luca.


The following changes since commit 7d2c913dcd1be083350d97a8cb1eba24cfacbc8a:

  ath10k: update year in license (2017-06-22 12:06:02 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware.git 
tags/iwlwifi-fw-2017-06-27

for you to fetch changes up to d392df8feda805e37022686d76be96de407a9e18:

  iwlwifi: add new firmware for 3168, 7265D, 8000C and 8265 (2017-06-27 
14:45:20 +0300)


Update and add new firmwares for 3168, 7265D, 8000C and 8265

* new -29 for 3168 and 7265D;
* new -31 for 8000C and 8265;
* updated -27 for 3168, 7265D, 8000C and 8265.


Emmanuel Grumbach (1):
  iwlwifi: update -27 firmware for 3168, 7265D, 8000C and 8265

Johannes Berg (1):
  iwlwifi: add new firmware for 3168, 7265D, 8000C and 8265

 WHENCE |  20 
 iwlwifi-3168-27.ucode  | Bin 1032168 -> 1032436 bytes
 iwlwifi-3168-29.ucode  | Bin 0 -> 1036372 bytes
 iwlwifi-7265D-27.ucode | Bin 1032452 -> 1032740 bytes
 iwlwifi-7265D-29.ucode | Bin 0 -> 1036528 bytes
 iwlwifi-8000C-27.ucode | Bin 2227284 -> 2227284 bytes
 iwlwifi-8000C-31.ucode | Bin 0 -> 2309768 bytes
 iwlwifi-8265-27.ucode  | Bin 2234528 -> 2234528 bytes
 iwlwifi-8265-31.ucode  | Bin 0 -> 2303024 bytes
 9 files changed, 16 insertions(+), 4 deletions(-)
 create mode 100644 iwlwifi-3168-29.ucode
 create mode 100644 iwlwifi-7265D-29.ucode
 create mode 100644 iwlwifi-8000C-31.ucode
 create mode 100644 iwlwifi-8265-31.ucode


Re: [Linux-4.9.28] iwlwifi 6230 AGN: Microcode SW error detected

2017-05-24 Thread Luca Coelho
On Wed, 2017-05-24 at 09:41 +0200, Sedat Dilek wrote:
> Hi,

Hi Sedat,


> I am seeing the below/following in my logs today.
> My AP is a Lenovo Moto-Z with LTE support.
> 
> Can you comment on this?
> Is this a "buggy" firmware and a new firmware around?

Looks like a buggy firmware, but unfortunately we don't have a newer
firmware with a fix for this.


> My kernel-config and full dmesg are attached.
> 
> If you need further informations, please let me know.
> 
> Hope this helps.
> 
> Regards,
> - Sedat -
> 
> P.S.: Excerpts from my dmesg-log.
> 
> [   16.708016] iwlwifi :01:00.0: Detected Intel(R) Centrino(R)
> Advanced-N 6230 AGN, REV=0xB0

This is a really old NIC (6+ years old) and unfortunately we can't
provide firmware fixes for it anymore.

Hopefully the recovery flow in the driver recovers the connectivity and
everything continues working fine.


--
Cheers,
Luca.


Re: [Linux-4.9.28] iwlwifi 6230 AGN: Microcode SW error detected

2017-05-24 Thread Luca Coelho
On Wed, 2017-05-24 at 10:15 +0200, Sedat Dilek wrote:
> On Wed, May 24, 2017 at 9:57 AM, Luca Coelho <l...@coelho.fi> wrote:
> > On Wed, 2017-05-24 at 09:41 +0200, Sedat Dilek wrote:
> > > Hi,
> > 
> > Hi Sedat,
> > 
> > 
> > > I am seeing the below/following in my logs today.
> > > My AP is a Lenovo Moto-Z with LTE support.
> > > 
> > > Can you comment on this?
> > > Is this a "buggy" firmware and a new firmware around?
> > 
> > Looks like a buggy firmware, but unfortunately we don't have a newer
> > firmware with a fix for this.
> > 
> > 
> > > My kernel-config and full dmesg are attached.
> > > 
> > > If you need further informations, please let me know.
> > > 
> > > Hope this helps.
> > > 
> > > Regards,
> > > - Sedat -
> > > 
> > > P.S.: Excerpts from my dmesg-log.
> > > 
> > > [   16.708016] iwlwifi :01:00.0: Detected Intel(R) Centrino(R)
> > > Advanced-N 6230 AGN, REV=0xB0
> > 
> > This is a really old NIC (6+ years old) and unfortunately we can't
> > provide firmware fixes for it anymore.
> > 
> > Hopefully the recovery flow in the driver recovers the connectivity and
> > everything continues working fine.
> > 
> 
> Thanks for the fast reply.
> 
> Intel was(?) a good choice is my conclusion after getting no more
> replies/fixes for my SandyBridge-GPU from intel-gfx guys.
> This Samsung Ultrabook is 5 years young.
> I can understand that fixing a 6 years old NIC is not your prio #1.
> 
> As an example, there is no vulkan support for my GPU, so it's time for a 
> change?
> 
> No glue if other hardware vendors have better support.

We still do our best effort to fix driver bugs for these old NICs, but
unfortunately fixing the FW is a much more complicated issue and there's
nothing we can do. :(

Regarding the GPU stuff, I really can't comment, since I don't know much
about it.

--
Cheers,
Luca.


[PATCH 02/10] iwlwifi: mvm: Fix command queue number on d0i3 flow

2017-06-02 Thread Luca Coelho
From: Haim Dreyfuss <haim.dreyf...@intel.com>

During d0i3 flow we flush all the queue except from the command queue.
Currently, in this flow the command queue is hard coded to 9.
In DQA the command queue number has changed from 9 to 0.
Fix that.

Fixes: 097129c9e625 ("iwlwifi: mvm: move cmd queue to be #0 in dqa mode")
Signed-off-by: Haim Dreyfuss <haim.dreyf...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 4e74a6b90e70..ed20c0c5abc8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1730,8 +1730,11 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 
sta_id, u8 minq, u8 maxq);
  */
 static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
 {
+   u32 cmd_queue = iwl_mvm_is_dqa_supported(mvm) ? IWL_MVM_DQA_CMD_QUEUE :
+   IWL_MVM_CMD_QUEUE;
+
return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) &
-   ~BIT(IWL_MVM_CMD_QUEUE));
+   ~BIT(cmd_queue));
 }
 
 static inline
-- 
2.11.0



[PATCH 05/10] iwlwifi: mvm: fix firmware debug restart recording

2017-06-02 Thread Luca Coelho
From: Emmanuel Grumbach <emmanuel.grumb...@intel.com>

When we want to stop the recording of the firmware debug
and restart it later without reloading the firmware we
don't need to resend the configuration that comes with
host commands.
Sending those commands confused the hardware and led to
an NMI 0x66.

Change the flow as following:
* read the relevant registers (DBGC_IN_SAMPLE, DBGC_OUT_CTRL)
* clear those registers
* wait for the hardware to complete its write to the buffer
* get the data
* restore the value of those registers (to restart the
  recording)

For early start (where the configuration is already
compiled in the firmware), we don't need to set those
registers after the firmware has been loaded, but only
when we want to restart the recording without having
restarted the firmware.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h   |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c | 12 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h|  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c| 32 ++---
 4 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h 
b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 306bc967742e..77efbb78e867 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -370,6 +370,7 @@
 #define MON_DMARB_RD_DATA_ADDR (0xa03c5c)
 
 #define DBGC_IN_SAMPLE (0xa03c00)
+#define DBGC_OUT_CTRL  (0xa03c0c)
 
 /* enable the ID buf for read */
 #define WFPM_PS_CTL_CLR0xA0300C
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
index 7b86a4f1b574..c8712e6eea74 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
@@ -1002,14 +1002,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
return 0;
 }
 
-static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm)
-{
-   if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
-   iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
-   else
-   iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1);
-}
-
 int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
 {
u8 *ptr;
@@ -1023,10 +1015,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 
conf_id)
/* EARLY START - firmware's configuration is hard coded */
if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
 !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
-   conf_id == FW_DBG_START_FROM_ALIVE) {
-   iwl_mvm_restart_early_start(mvm);
+   conf_id == FW_DBG_START_FROM_ALIVE)
return 0;
-   }
 
if (!mvm->fw->dbg_conf_tlv[conf_id])
return -EINVAL;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index ed20c0c5abc8..52f8d7a6a7dc 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1756,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm 
*mvm)
if (!iwl_mvm_has_new_tx_api(mvm))
iwl_free_fw_paging(mvm);
mvm->ucode_loaded = false;
+   mvm->fw_dbg_conf = FW_DBG_INVALID;
iwl_trans_stop_device(mvm->trans);
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 96ed8133..3da5ec40aaea 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1149,21 +1149,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct 
*work)
 
mutex_lock(>mutex);
 
-   /* stop recording */
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+   /* stop recording */
iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
+
+   iwl_mvm_fw_error_dump(mvm);
+
+   /* start recording again if the firmware is not crashed */
+   if (!test_bit(STATUS_FW_ERROR, >trans->status) &&
+   mvm->fw->dbg_dest_tlv)
+   iwl_clear_bits_prph(mvm->trans,
+   MON_BUFF_SAMPLE_CTL, 0x100);
} else {
+   u32 in_sample = iwl_read_prph(mvm->trans, DBGC_IN_SAMPLE);
+   u32 out_ctrl = iwl_read_prph(mvm->trans, DBGC_OUT_CTRL);
+
+   /* stop recording */
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
-   /* wait before we collect the data till the DBGC stop */
udelay(100);
-   }
+

<    5   6   7   8   9   10   11   12   13   14   >