Merge "CHROMIUM: iwl7000: Merge "core64_sp-50" driver updates" into chromeos-4.4
diff --git a/drivers/net/wireless/iwl7000/hdrs/config.h b/drivers/net/wireless/iwl7000/hdrs/config.h
index 007e24f..063aa0e 100644
--- a/drivers/net/wireless/iwl7000/hdrs/config.h
+++ b/drivers/net/wireless/iwl7000/hdrs/config.h
@@ -73,5 +73,6 @@
#endif
#define CPTCFG_IWLWIFI_DHC 1
+#define CPTCFG_IWLWIFI_DONT_DUMP_FIFOS 1
#endif
diff --git a/drivers/net/wireless/iwl7000/hdrs/version.h b/drivers/net/wireless/iwl7000/hdrs/version.h
index e737f0a..cf64296 100644
--- a/drivers/net/wireless/iwl7000/hdrs/version.h
+++ b/drivers/net/wireless/iwl7000/hdrs/version.h
@@ -1,6 +1,6 @@
#ifndef __IWL_CHROME_VERSION_H
#define __IWL_CHROME_VERSION_H
-#define BACKPORTS_GIT_TRACKED "chromium:" UTS_RELEASE ":core64-70:"
+#define BACKPORTS_GIT_TRACKED "chromium:" UTS_RELEASE ":core64_sp-50:"
#endif /* __IWL_CHROME_VERSION_H */
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/iwl7000/iwlwifi/fw/api/dbg-tlv.h
index fd88d3a0..3988f5f 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/fw/api/dbg-tlv.h
+++ b/drivers/net/wireless/iwl7000/iwlwifi/fw/api/dbg-tlv.h
@@ -7,6 +7,7 @@
#include <linux/bitops.h>
+#define IWL_FW_INI_HW_SMEM_REGION_ID 15
#define IWL_FW_INI_MAX_REGION_ID 64
#define IWL_FW_INI_MAX_NAME 32
#define IWL_FW_INI_MAX_CFG_NAME 64
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/fw/dbg.c b/drivers/net/wireless/iwl7000/iwlwifi/fw/dbg.c
index 155c01a..225368a 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/iwl7000/iwlwifi/fw/dbg.c
@@ -804,8 +804,10 @@
/* reading RXF/TXF sizes */
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
- fifo_len = iwl_fw_rxf_len(fwrt, mem_cfg);
- fifo_len += iwl_fw_txf_len(fwrt, mem_cfg);
+ if (!IS_ENABLED(CPTCFG_IWLWIFI_DONT_DUMP_FIFOS)) {
+ fifo_len = iwl_fw_rxf_len(fwrt, mem_cfg);
+ fifo_len += iwl_fw_txf_len(fwrt, mem_cfg);
+ }
/* Make room for PRPH registers */
if (iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PRPH))
@@ -1165,6 +1167,13 @@
iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
le32_to_cpu(reg->dev_addr.size));
+ if ((le32_to_cpu(reg->id) & IWL_FW_INI_REGION_V2_MASK) ==
+ IWL_FW_INI_HW_SMEM_REGION_ID &&
+ fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
+ fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
+ range->data,
+ le32_to_cpu(reg->dev_addr.size));
+
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/iwl7000/iwlwifi/iwl-dbg-tlv.c
index 3da1cd8..4af8010 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/iwl7000/iwlwifi/iwl-dbg-tlv.c
@@ -211,6 +211,14 @@
return -EOPNOTSUPP;
}
+#ifdef CPTCFG_IWLWIFI_DONT_DUMP_FIFOS
+ if (type == IWL_FW_INI_REGION_DEVICE_MEMORY &&
+ id == IWL_FW_INI_HW_SMEM_REGION_ID) {
+ IWL_DEBUG_FW(trans, "WRT: skipping HW-SMEM region\n");
+ return -EOPNOTSUPP;
+ }
+#endif
+
active_reg = &trans->dbg.active_regions[id];
if (*active_reg) {
IWL_WARN(trans, "WRT: Overriding region id %u\n", id);
@@ -222,6 +230,14 @@
if (!*active_reg)
return -ENOMEM;
+#ifdef CPTCFG_IWLWIFI_DONT_DUMP_FIFOS
+ if (type == IWL_FW_INI_REGION_TXF || type == IWL_FW_INI_REGION_RXF) {
+ struct iwl_fw_ini_region_tlv *reg = (void *)(*active_reg)->data;
+
+ reg->fifos.hdr_only = cpu_to_le32(1);
+ }
+#endif
+
IWL_DEBUG_FW(trans, "WRT: Enabling region id %u type %u\n", id, type);
return 0;
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwl7000/iwlwifi/iwl-trans.h
index 7220893..f6af1c6 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwl7000/iwlwifi/iwl-trans.h
@@ -307,6 +307,8 @@
* @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent
* @STATUS_TA_ACTIVE: target access is in progress
* @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation
+ * @STATUS_SUPPRESS_CMD_ERROR_ONCE: suppress "FW error in SYNC CMD" once,
+ * e.g. for testing
*/
enum iwl_trans_status {
STATUS_SYNC_HCMD_ACTIVE,
@@ -320,6 +322,7 @@
STATUS_TRANS_IDLE,
STATUS_TA_ACTIVE,
STATUS_TRANS_DEAD,
+ STATUS_SUPPRESS_CMD_ERROR_ONCE,
};
static inline int
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwl7000/iwlwifi/mvm/debugfs.c
index c664c48..c125f20 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwl7000/iwlwifi/mvm/debugfs.c
@@ -1136,6 +1136,11 @@
if (mvm->fw_restart >= 0)
mvm->fw_restart++;
+ if (count == 6 && !strcmp(buf, "nolog\n")) {
+ set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
+ set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &mvm->trans->status);
+ }
+
/* take the return value to make compiler happy - it will fail anyway */
ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(LONG_GROUP, REPLY_ERROR),
@@ -1152,6 +1157,9 @@
if (!iwl_mvm_firmware_running(mvm))
return -EIO;
+ if (count == 6 && !strcmp(buf, "nolog\n"))
+ set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
+
iwl_force_nmi(mvm->trans);
return count;
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwl7000/iwlwifi/mvm/mvm.h
index 0878cd2..d9e30a4 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwl7000/iwlwifi/mvm/mvm.h
@@ -1242,6 +1242,8 @@
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
* @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it)
+ * @IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE: suppress one error log
+ * if this is set, when intentionally triggered
*/
enum iwl_mvm_status {
IWL_MVM_STATUS_HW_RFKILL,
@@ -1253,6 +1255,7 @@
IWL_MVM_STATUS_FIRMWARE_RUNNING,
IWL_MVM_STATUS_NEED_FLUSH_P2P,
IWL_MVM_STATUS_IN_D3,
+ IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE,
};
struct iwl_mvm_csme_conn_info {
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwl7000/iwlwifi/mvm/ops.c
index b8e1138..6ac422a 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwl7000/iwlwifi/mvm/ops.c
@@ -2063,7 +2063,9 @@
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
- if (!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status))
+ if (!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status) &&
+ !test_and_clear_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE,
+ &mvm->status))
iwl_mvm_dump_nic_error_log(mvm);
if (sync) {
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwl7000/iwlwifi/mvm/time-event.c
index 36e61a9..e681331 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwl7000/iwlwifi/mvm/time-event.c
@@ -662,12 +662,13 @@
u32 *uid)
{
u32 id;
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
+ struct iwl_mvm_vif *mvmvif;
enum nl80211_iftype iftype;
if (!te_data->vif)
return false;
+ mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
iftype = te_data->vif->type;
/*
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwl7000/iwlwifi/pcie/drv.c
index 63f5ab3..f775af9 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwl7000/iwlwifi/pcie/drv.c
@@ -378,6 +378,7 @@
IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL),
+ IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name),
IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0xA0F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL),
IWL_DEV_INFO(0xA0F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL),
diff --git a/drivers/net/wireless/iwl7000/iwlwifi/queue/tx.c b/drivers/net/wireless/iwl7000/iwlwifi/queue/tx.c
index 2bbb5ce..d08172a 100644
--- a/drivers/net/wireless/iwl7000/iwlwifi/queue/tx.c
+++ b/drivers/net/wireless/iwl7000/iwlwifi/queue/tx.c
@@ -1754,8 +1754,11 @@
}
if (test_bit(STATUS_FW_ERROR, &trans->status)) {
- IWL_ERR(trans, "FW error in SYNC CMD %s\n", cmd_str);
- dump_stack();
+ if (!test_and_clear_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE,
+ &trans->status)) {
+ IWL_ERR(trans, "FW error in SYNC CMD %s\n", cmd_str);
+ dump_stack();
+ }
ret = -EIO;
goto cancel;
}
diff --git a/drivers/net/wireless/iwl7000/mac80211/agg-tx.c b/drivers/net/wireless/iwl7000/mac80211/agg-tx.c
index c7e5f1b..1167d4b 100644
--- a/drivers/net/wireless/iwl7000/mac80211/agg-tx.c
+++ b/drivers/net/wireless/iwl7000/mac80211/agg-tx.c
@@ -9,7 +9,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation
* Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2020 Intel Corporation
+ * Copyright (C) 2018 - 2021 Intel Corporation
*/
#include <linux/ieee80211.h>
@@ -213,6 +213,8 @@
struct ieee80211_txq *txq = sta->sta.txq[tid];
struct txq_info *txqi;
+ lockdep_assert_held(&sta->ampdu_mlme.mtx);
+
if (!txq)
return;
@@ -290,7 +292,6 @@
ieee80211_assign_tid_tx(sta, tid, NULL);
ieee80211_agg_splice_finish(sta->sdata, tid);
- ieee80211_agg_start_txq(sta, tid, false);
kfree_rcu(tid_tx, rcu_head);
}
@@ -889,6 +890,7 @@
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
bool send_delba = false;
+ bool start_txq = false;
ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n",
sta->sta.addr, tid);
@@ -906,10 +908,14 @@
send_delba = true;
ieee80211_remove_tid_tx(sta, tid);
+ start_txq = true;
unlock_sta:
spin_unlock_bh(&sta->lock);
+ if (start_txq)
+ ieee80211_agg_start_txq(sta, tid, false);
+
if (send_delba)
ieee80211_send_delba(sdata, sta->sta.addr, tid,
WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
diff --git a/drivers/net/wireless/iwl7000/mac80211/mlme.c b/drivers/net/wireless/iwl7000/mac80211/mlme.c
index a669f17..00b04c9 100644
--- a/drivers/net/wireless/iwl7000/mac80211/mlme.c
+++ b/drivers/net/wireless/iwl7000/mac80211/mlme.c
@@ -5000,13 +5000,20 @@
rcu_read_unlock();
}
-static u8 ieee80211_ht_vht_rx_chains(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_bss *cbss)
+static u8 ieee80211_max_rx_chains(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_bss *cbss)
{
+ struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
const u8 *ht_cap_ie, *vht_cap_ie;
+ const struct cfg80211_bss_ies *ies;
const struct ieee80211_ht_cap *ht_cap;
const struct ieee80211_vht_cap *vht_cap;
+ const struct ieee80211_he_cap_elem *he_cap;
+ const struct element *he_cap_elem;
+ u16 mcs_80_map, mcs_160_map;
+ u8 i, mcs_nss_size;
+ bool support_160;
u8 chains = 1;
if (ifmgd->flags & IEEE80211_STA_DISABLE_HT)
@@ -5041,6 +5048,53 @@
chains = max(chains, nss);
}
+ if (ifmgd->flags & IEEE80211_STA_DISABLE_HE)
+ return chains;
+
+ ies = rcu_dereference(cbss->ies);
+ he_cap_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY,
+ ies->data, ies->len);
+
+ if (!he_cap_elem || he_cap_elem->datalen < sizeof(*he_cap))
+ return chains;
+
+ he_cap = (void *)(he_cap_elem->data);
+ mcs_nss_size = ieee80211_he_mcs_nss_size(he_cap);
+
+ /* invalid HE IE */
+ if (he_cap_elem->datalen < mcs_nss_size + sizeof(*he_cap))
+ return chains;
+
+ /* mcs_nss is right after he_cap info */
+ he_mcs_nss_supp = (void *)(he_cap + 1);
+
+ mcs_80_map = le16_to_cpu(he_mcs_nss_supp->tx_mcs_80);
+
+ for (i = 7; i >= 0; i--) {
+ u8 mcs_80 = mcs_80_map >> (2 * i) & 3;
+
+ if (mcs_80 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
+ chains = max_t(u8, chains, i + 1);
+ break;
+ }
+ }
+
+ support_160 = he_cap->phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
+
+ if (!support_160)
+ return chains;
+
+ mcs_160_map = le16_to_cpu(he_mcs_nss_supp->tx_mcs_160);
+ for (i = 7; i >= 0; i--) {
+ u8 mcs_160 = mcs_160_map >> (2 * i) & 3;
+
+ if (mcs_160 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
+ chains = max_t(u8, chains, i + 1);
+ break;
+ }
+ }
+
return chains;
}
@@ -5249,7 +5303,7 @@
s1g_oper,
&chandef, false);
- sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
+ sdata->needed_rx_chains = min(ieee80211_max_rx_chains(sdata, cbss),
local->rx_chains);
rcu_read_unlock();