* [PATCH 00/10] iwlwifi: updates intended for v4.15 2017-09-15
From: Luca Coelho @ 2017-09-15 12:46 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Luca Coelho
From: Luca Coelho <luciano.coelho@intel.com>
Hi,
Here's my first set of patches intended for 4.15. Nothing major here,
these are the changes:
* Cleanups: - remove an unused value that we read from the NVM;
- remove link quality measurement code that was never used;
* One FW command API update;
* A fix and an addition for PCI devices for the A000 family;
* Tiny refactor of ref/unref code used by runtime-PM;
* Some debugging improvements;
* Implementation of a more flexible way to define command queue sizes;
As usual, I'm pushing this to a pending branch, for kbuild bot, and
will send a pull-request later.
Please review.
Cheers,
Luca.
Chaya Rachel Ivgi (1):
iwlwifi: remove redundant reading from NVM file
David Spinadel (1):
iwlwifi: mvm: Add new quota command API
Emmanuel Grumbach (2):
iwlwifi: mvm: remove support for Link Quality Measurements
iwlwifi: mvm: support firmware debug trigger on frame reorder timeout
Ilan Peer (1):
iwlwifi: Add few debug prints to the WRT dump flow
Liad Kaufman (1):
iwlwifi: mvm: add dbgfs entry for fw info
Luca Coelho (1):
iwlwifi: trans: move ref/unref code to the common part of the
transport
Oren Givon (2):
iwlwifi: fix wrong struct for a000 device
iwlwifi: add a new a000 device
Shahar S Matityahu (1):
iwlwifi: pcie: dynamic Tx command queue size
drivers/net/wireless/intel/iwlwifi/cfg/a000.c | 3 +-
.../net/wireless/intel/iwlwifi/fw/api/binding.h | 41 ++++++++-
.../net/wireless/intel/iwlwifi/fw/api/mac-cfg.h | 67 ---------------
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 15 ++++
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 +
drivers/net/wireless/intel/iwlwifi/iwl-config.h | 3 +
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 7 --
drivers/net/wireless/intel/iwlwifi/iwl-trans.c | 16 ++++
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 14 +---
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 16 ++--
.../net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 76 -----------------
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 32 ++++++++
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 38 +--------
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 45 +++++++---
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 -
drivers/net/wireless/intel/iwlwifi/mvm/quota.c | 59 +++++++------
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 5 ++
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 1 +
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 96 ++++++----------------
.../net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 2 +-
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +-
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 3 +
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 8 +-
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 23 +++++-
24 files changed, 255 insertions(+), 323 deletions(-)
--
2.14.1
^ permalink raw reply
* [PATCH 01/10] iwlwifi: mvm: add dbgfs entry for fw info
From: Luca Coelho @ 2017-09-15 12:46 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Liad Kaufman, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Liad Kaufman <liad.kaufman@intel.com>
Add a dbgfs entry for an easy way during runtime to
check what FW file was loaded, and get some general
FW-related data.
Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 32 ++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index e97904c2c4d4..2ff594f11259 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -660,6 +660,36 @@ iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf,
return ret ?: count;
}
+static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_mvm *mvm = file->private_data;
+ char *buff, *pos, *endpos;
+ static const size_t bufsz = 1024;
+ int ret;
+
+ buff = kmalloc(bufsz, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
+ pos = buff;
+ endpos = pos + bufsz;
+
+ pos += scnprintf(pos, endpos - pos, "FW prefix: %s\n",
+ mvm->trans->cfg->fw_name_pre);
+ pos += scnprintf(pos, endpos - pos, "FW: %s\n",
+ mvm->fwrt.fw->human_readable);
+ pos += scnprintf(pos, endpos - pos, "Device: %s\n",
+ mvm->fwrt.trans->cfg->name);
+ pos += scnprintf(pos, endpos - pos, "Bus: %s\n",
+ mvm->fwrt.dev->bus->name);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
+ kfree(buff);
+
+ return ret;
+}
+
#define PRINT_STATS_LE32(_struct, _memb) \
pos += scnprintf(buf + pos, bufsz - pos, \
fmt_table, #_memb, \
@@ -1662,6 +1692,7 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
+MVM_DEBUGFS_READ_FILE_OPS(fw_ver);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
@@ -1843,6 +1874,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
S_IRUSR | S_IWUSR);
+ MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
--
2.14.1
^ permalink raw reply related
* [PATCH 02/10] iwlwifi: trans: move ref/unref code to the common part of the transport
From: Luca Coelho @ 2017-09-15 12:46 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Luca Coelho <luciano.coelho@intel.com>
De-inline iwl_trans_ref/unref and move it to common transport code
in preparation for more common code to come to these functions.
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/iwl-trans.c | 16 ++++++++++++++++
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 14 ++------------
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
index 784bdd0ed233..7e9c924e1220 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
@@ -6,6 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2015 Intel Mobile Communications 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
@@ -31,6 +32,7 @@
* BSD LICENSE
*
* Copyright(c) 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -205,3 +207,17 @@ int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans)
return 0;
}
IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted);
+
+void iwl_trans_ref(struct iwl_trans *trans)
+{
+ if (trans->ops->ref)
+ trans->ops->ref(trans);
+}
+IWL_EXPORT_SYMBOL(iwl_trans_ref);
+
+void iwl_trans_unref(struct iwl_trans *trans)
+{
+ if (trans->ops->unref)
+ trans->ops->unref(trans);
+}
+IWL_EXPORT_SYMBOL(iwl_trans_unref);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index e90abbfba718..91ec077900f6 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -875,18 +875,6 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
return trans->ops->d3_resume(trans, status, test, reset);
}
-static inline void iwl_trans_ref(struct iwl_trans *trans)
-{
- if (trans->ops->ref)
- trans->ops->ref(trans);
-}
-
-static inline void iwl_trans_unref(struct iwl_trans *trans)
-{
- if (trans->ops->unref)
- trans->ops->unref(trans);
-}
-
static inline int iwl_trans_suspend(struct iwl_trans *trans)
{
if (!trans->ops->suspend)
@@ -1191,6 +1179,8 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
const struct iwl_cfg *cfg,
const struct iwl_trans_ops *ops);
void iwl_trans_free(struct iwl_trans *trans);
+void iwl_trans_ref(struct iwl_trans *trans);
+void iwl_trans_unref(struct iwl_trans *trans);
/*****************************************************
* driver (transport) register/unregister functions
--
2.14.1
^ permalink raw reply related
* [PATCH 03/10] iwlwifi: fix wrong struct for a000 device
From: Luca Coelho @ 2017-09-15 12:46 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Oren Givon, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Oren Givon <oren.givon@intel.com>
The PCI ID (0x2720, 0x0070) was set with the config struct
iwla000_2ax_cfg_hr instead of iwla000_2ac_cfg_hr_cdb.
Fixes: 175b87c69253 ("iwlwifi: add the new a000_2ax series")
Signed-off-by: Oren Givon <oren.givon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 858765fed8f8..3416c6155996 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -576,7 +576,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2720, 0x0000, iwla000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0070, iwla000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0078, iwla000_2ax_cfg_hr)},
- {IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ax_cfg_hr)},
+ {IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ac_cfg_hr_cdb)},
{IWL_PCI_DEVICE(0x2720, 0x1080, iwla000_2ax_cfg_hr)},
#endif /* CONFIG_IWLMVM */
--
2.14.1
^ permalink raw reply related
* [PATCH 04/10] iwlwifi: add a new a000 device
From: Luca Coelho @ 2017-09-15 12:46 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Oren Givon, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Oren Givon <oren.givon@intel.com>
Add a new a000 device with PCI ID (0x2720, 0x0030).
Signed-off-by: Oren Givon <oren.givon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 3416c6155996..e0966f656376 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -577,6 +577,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x34F0, 0x0070, iwla000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0078, iwla000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ac_cfg_hr_cdb)},
+ {IWL_PCI_DEVICE(0x2720, 0x0030, iwla000_2ac_cfg_hr_cdb)},
{IWL_PCI_DEVICE(0x2720, 0x1080, iwla000_2ax_cfg_hr)},
#endif /* CONFIG_IWLMVM */
--
2.14.1
^ permalink raw reply related
* [PATCH 05/10] iwlwifi: mvm: Add new quota command API
From: Luca Coelho @ 2017-09-15 12:46 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, David Spinadel, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: David Spinadel <david.spinadel@intel.com>
New quota command adds a field indicating low latency
direction per quota.
A TLV API bit was added to indicate the new API.
Signed-off-by: David Spinadel <david.spinadel@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
.../net/wireless/intel/iwlwifi/fw/api/binding.h | 41 +++++++++++++--
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 ++
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 16 +++---
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 27 ++++++++++
drivers/net/wireless/intel/iwlwifi/mvm/quota.c | 59 +++++++++++++---------
5 files changed, 113 insertions(+), 33 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h b/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h
index d2717fafdf5b..570f19026c91 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h
@@ -116,14 +116,14 @@ struct iwl_binding_cmd {
#define IWL_MVM_MAX_QUOTA 128
/**
- * struct iwl_time_quota_data - configuration of time quota per binding
+ * struct iwl_time_quota_data_v1 - configuration of time quota per binding
* @id_and_color: ID and color of the relevant Binding,
* &enum iwl_ctxt_id_and_color
* @quota: absolute time quota in TU. The scheduler will try to divide the
* remainig quota (after Time Events) according to this quota.
* @max_duration: max uninterrupted context duration in TU
*/
-struct iwl_time_quota_data {
+struct iwl_time_quota_data_v1 {
__le32 id_and_color;
__le32 quota;
__le32 max_duration;
@@ -137,8 +137,43 @@ struct iwl_time_quota_data {
* essentially zero.
* On CDB the fourth one is a regular binding.
*/
+struct iwl_time_quota_cmd_v1 {
+ struct iwl_time_quota_data_v1 quotas[MAX_BINDINGS];
+} __packed; /* TIME_QUOTA_ALLOCATION_CMD_API_S_VER_1 */
+
+enum iwl_quota_low_latency {
+ IWL_QUOTA_LOW_LATENCY_NONE = 0,
+ IWL_QUOTA_LOW_LATENCY_TX = BIT(0),
+ IWL_QUOTA_LOW_LATENCY_RX = BIT(1),
+ IWL_QUOTA_LOW_LATENCY_TX_RX =
+ IWL_QUOTA_LOW_LATENCY_TX | IWL_QUOTA_LOW_LATENCY_RX,
+};
+
+/**
+ * struct iwl_time_quota_data - configuration of time quota per binding
+ * @id_and_color: ID and color of the relevant Binding.
+ * @quota: absolute time quota in TU. The scheduler will try to divide the
+ * remainig quota (after Time Events) according to this quota.
+ * @max_duration: max uninterrupted context duration in TU
+ * @low_latency: low latency status, &enum iwl_quota_low_latency
+ */
+struct iwl_time_quota_data {
+ __le32 id_and_color;
+ __le32 quota;
+ __le32 max_duration;
+ __le32 low_latency;
+} __packed; /* TIME_QUOTA_DATA_API_S_VER_2 */
+
+/**
+ * struct iwl_time_quota_cmd - configuration of time quota between bindings
+ * ( TIME_QUOTA_CMD = 0x2c )
+ * Note: on non-CDB the fourth one is the auxilary mac and is essentially zero.
+ * On CDB the fourth one is a regular binding.
+ *
+ * @quotas: allocations per binding
+ */
struct iwl_time_quota_cmd {
struct iwl_time_quota_data quotas[MAX_BINDINGS];
-} __packed; /* TIME_QUOTA_ALLOCATION_CMD_API_S_VER_1 */
+} __packed; /* TIME_QUOTA_ALLOCATION_CMD_API_S_VER_2 */
#endif /* __iwl_fw_api_binding_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 887f6d8fc8a7..7d794ad53e4b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -248,6 +248,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
* @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.
+ * @IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY: Quota command includes a field
+ * indicating low latency direction.
*
* @NUM_IWL_UCODE_TLV_API: number of bits used
*/
@@ -265,6 +267,7 @@ enum iwl_ucode_tlv_api {
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,
+ IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38,
NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 5de19ea10575..c5ea3fad8002 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -664,6 +664,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int ret, i;
struct iwl_binding_cmd binding_cmd = {};
struct iwl_time_quota_cmd quota_cmd = {};
+ struct iwl_time_quota_data *quota;
u32 status;
int size;
@@ -745,17 +746,20 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return ret;
/* and some quota */
- quota_cmd.quotas[0].id_and_color =
+ quota = iwl_mvm_quota_cmd_get_quota(mvm, "a_cmd, 0);
+ quota->id_and_color =
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
mvmvif->phy_ctxt->color));
- quota_cmd.quotas[0].quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
- quota_cmd.quotas[0].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
+ quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
+ quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
- for (i = 1; i < MAX_BINDINGS; i++)
- quota_cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
+ for (i = 1; i < MAX_BINDINGS; i++) {
+ quota = iwl_mvm_quota_cmd_get_quota(mvm, "a_cmd, i);
+ quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
+ }
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
- sizeof(quota_cmd), "a_cmd);
+ iwl_mvm_quota_cmd_size(mvm), "a_cmd);
if (ret)
IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 83303bac0e4b..48cb08eea700 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1248,6 +1248,12 @@ static inline bool iwl_mvm_has_new_ats_coex_api(struct iwl_mvm *mvm)
IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL);
}
+static inline bool iwl_mvm_has_quota_low_latency(struct iwl_mvm *mvm)
+{
+ return fw_has_api(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY);
+}
+
static inline struct agg_tx_status *
iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
{
@@ -1486,6 +1492,27 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
/* Quota management */
+static inline size_t iwl_mvm_quota_cmd_size(struct iwl_mvm *mvm)
+{
+ return iwl_mvm_has_quota_low_latency(mvm) ?
+ sizeof(struct iwl_time_quota_cmd) :
+ sizeof(struct iwl_time_quota_cmd_v1);
+}
+
+static inline struct iwl_time_quota_data
+*iwl_mvm_quota_cmd_get_quota(struct iwl_mvm *mvm,
+ struct iwl_time_quota_cmd *cmd,
+ int i)
+{
+ struct iwl_time_quota_data_v1 *quotas;
+
+ if (iwl_mvm_has_quota_low_latency(mvm))
+ return &cmd->quotas[i];
+
+ quotas = (struct iwl_time_quota_data_v1 *)cmd->quotas;
+ return (struct iwl_time_quota_data *)"as[i];
+}
+
int iwl_mvm_update_quotas(struct iwl_mvm *mvm, bool force_upload,
struct ieee80211_vif *disabled_vif);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/quota.c b/drivers/net/wireless/intel/iwlwifi/mvm/quota.c
index 2141db5bff82..b4a0264329b7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/quota.c
@@ -7,7 +7,7 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 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 - 2014 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
@@ -164,9 +164,12 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
beacon_int = mvm->noa_vif->bss_conf.beacon_int;
for (i = 0; i < MAX_BINDINGS; i++) {
- u32 id_n_c = le32_to_cpu(cmd->quotas[i].id_and_color);
+ struct iwl_time_quota_data *data =
+ iwl_mvm_quota_cmd_get_quota(mvm, cmd,
+ i);
+ u32 id_n_c = le32_to_cpu(data->id_and_color);
u32 id = (id_n_c & FW_CTXT_ID_MSK) >> FW_CTXT_ID_POS;
- u32 quota = le32_to_cpu(cmd->quotas[i].quota);
+ u32 quota = le32_to_cpu(data->quota);
if (id != phy_id)
continue;
@@ -175,9 +178,9 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
quota /= beacon_int;
IWL_DEBUG_QUOTA(mvm, "quota: adjust for NoA from %d to %d\n",
- le32_to_cpu(cmd->quotas[i].quota), quota);
+ le32_to_cpu(data->quota), quota);
- cmd->quotas[i].quota = cpu_to_le32(quota);
+ data->quota = cpu_to_le32(quota);
}
#endif
}
@@ -194,6 +197,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
.disabled_vif = disabled_vif,
};
struct iwl_time_quota_cmd *last = &mvm->last_quota_cmd;
+ struct iwl_time_quota_data *qdata, *last_data;
bool send = false;
lockdep_assert_held(&mvm->mutex);
@@ -216,7 +220,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
*/
num_active_macs = 0;
for (i = 0; i < MAX_BINDINGS; i++) {
- cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
+ qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, i);
+ qdata->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
num_active_macs += data.n_interfaces[i];
}
@@ -265,14 +270,16 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
if (data.colors[i] < 0)
continue;
- cmd.quotas[idx].id_and_color =
+ qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, idx);
+
+ qdata->id_and_color =
cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
if (data.n_interfaces[i] <= 0)
- cmd.quotas[idx].quota = cpu_to_le32(0);
+ qdata->quota = cpu_to_le32(0);
#ifdef CONFIG_IWLWIFI_DEBUGFS
else if (data.dbgfs_min[i])
- cmd.quotas[idx].quota =
+ qdata->quota =
cpu_to_le32(data.dbgfs_min[i] * QUOTA_100 / 100);
#endif
else if (data.n_low_latency_bindings == 1 && n_non_lowlat &&
@@ -283,24 +290,25 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
* the minimal required quota for the low latency
* binding.
*/
- cmd.quotas[idx].quota = cpu_to_le32(QUOTA_LOWLAT_MIN);
+ qdata->quota = cpu_to_le32(QUOTA_LOWLAT_MIN);
else
- cmd.quotas[idx].quota =
+ qdata->quota =
cpu_to_le32(quota * data.n_interfaces[i]);
- WARN_ONCE(le32_to_cpu(cmd.quotas[idx].quota) > QUOTA_100,
+ WARN_ONCE(le32_to_cpu(qdata->quota) > QUOTA_100,
"Binding=%d, quota=%u > max=%u\n",
- idx, le32_to_cpu(cmd.quotas[idx].quota), QUOTA_100);
+ idx, le32_to_cpu(qdata->quota), QUOTA_100);
- cmd.quotas[idx].max_duration = cpu_to_le32(0);
+ qdata->max_duration = cpu_to_le32(0);
idx++;
}
/* Give the remainder of the session to the first data binding */
for (i = 0; i < MAX_BINDINGS; i++) {
- if (le32_to_cpu(cmd.quotas[i].quota) != 0) {
- le32_add_cpu(&cmd.quotas[i].quota, quota_rem);
+ qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, i);
+ if (le32_to_cpu(qdata->quota) != 0) {
+ le32_add_cpu(&qdata->quota, quota_rem);
IWL_DEBUG_QUOTA(mvm,
"quota: giving remainder of %d to binding %d\n",
quota_rem, i);
@@ -312,17 +320,19 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
/* check that we have non-zero quota for all valid bindings */
for (i = 0; i < MAX_BINDINGS; i++) {
- if (cmd.quotas[i].id_and_color != last->quotas[i].id_and_color)
+ qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, i);
+ last_data = iwl_mvm_quota_cmd_get_quota(mvm, last, i);
+ if (qdata->id_and_color != last_data->id_and_color)
send = true;
- if (cmd.quotas[i].max_duration != last->quotas[i].max_duration)
+ if (qdata->max_duration != last_data->max_duration)
send = true;
- if (abs((int)le32_to_cpu(cmd.quotas[i].quota) -
- (int)le32_to_cpu(last->quotas[i].quota))
+ if (abs((int)le32_to_cpu(qdata->quota) -
+ (int)le32_to_cpu(last_data->quota))
> IWL_MVM_QUOTA_THRESHOLD)
send = true;
- if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID))
+ if (qdata->id_and_color == cpu_to_le32(FW_CTXT_INVALID))
continue;
- WARN_ONCE(cmd.quotas[i].quota == 0,
+ WARN_ONCE(qdata->quota == 0,
"zero quota on binding %d\n", i);
}
@@ -334,7 +344,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
return 0;
}
- err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, sizeof(cmd), &cmd);
+ err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
+ iwl_mvm_quota_cmd_size(mvm), &cmd);
if (err)
IWL_ERR(mvm, "Failed to send quota: %d\n", err);
--
2.14.1
^ permalink raw reply related
* [PATCH 06/10] iwlwifi: mvm: remove support for Link Quality Measurements
From: Luca Coelho @ 2017-09-15 12:47 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This was never used by any product. Remove it.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
.../net/wireless/intel/iwlwifi/fw/api/mac-cfg.h | 67 -------------------
.../net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | 76 ----------------------
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 10 ---
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 12 ----
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 -
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 71 --------------------
6 files changed, 238 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
index 39c89e85fd2f..ec42c84e5df2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
@@ -67,79 +67,12 @@
* enum iwl_mac_conf_subcmd_ids - mac configuration command IDs
*/
enum iwl_mac_conf_subcmd_ids {
- /**
- * @LINK_QUALITY_MEASUREMENT_CMD: &struct iwl_link_qual_msrmnt_cmd
- */
- LINK_QUALITY_MEASUREMENT_CMD = 0x1,
-
- /**
- * @LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF:
- * &struct iwl_link_qual_msrmnt_notif
- */
- LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF = 0xFE,
-
/**
* @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif
*/
CHANNEL_SWITCH_NOA_NOTIF = 0xFF,
};
-#define LQM_NUMBER_OF_STATIONS_IN_REPORT 16
-
-enum iwl_lqm_cmd_operatrions {
- LQM_CMD_OPERATION_START_MEASUREMENT = 0x01,
- LQM_CMD_OPERATION_STOP_MEASUREMENT = 0x02,
-};
-
-enum iwl_lqm_status {
- LQM_STATUS_SUCCESS = 0,
- LQM_STATUS_TIMEOUT = 1,
- LQM_STATUS_ABORT = 2,
-};
-
-/**
- * struct iwl_link_qual_msrmnt_cmd - Link Quality Measurement command
- * @cmd_operation: command operation to be performed (start or stop)
- * as defined above.
- * @mac_id: MAC ID the measurement applies to.
- * @measurement_time: time of the total measurement to be performed, in uSec.
- * @timeout: maximum time allowed until a response is sent, in uSec.
- */
-struct iwl_link_qual_msrmnt_cmd {
- __le32 cmd_operation;
- __le32 mac_id;
- __le32 measurement_time;
- __le32 timeout;
-} __packed /* LQM_CMD_API_S_VER_1 */;
-
-/**
- * struct iwl_link_qual_msrmnt_notif - Link Quality Measurement notification
- *
- * @frequent_stations_air_time: an array containing the total air time
- * (in uSec) used by the most frequently transmitting stations.
- * @number_of_stations: the number of uniqe stations included in the array
- * (a number between 0 to 16)
- * @total_air_time_other_stations: the total air time (uSec) used by all the
- * stations which are not included in the above report.
- * @time_in_measurement_window: the total time in uSec in which a measurement
- * took place.
- * @tx_frame_dropped: the number of TX frames dropped due to retry limit during
- * measurement
- * @mac_id: MAC ID the measurement applies to.
- * @status: return status. may be one of the LQM_STATUS_* defined above.
- * @reserved: reserved.
- */
-struct iwl_link_qual_msrmnt_notif {
- __le32 frequent_stations_air_time[LQM_NUMBER_OF_STATIONS_IN_REPORT];
- __le32 number_of_stations;
- __le32 total_air_time_other_stations;
- __le32 time_in_measurement_window;
- __le32 tx_frame_dropped;
- __le32 mac_id;
- __le32 status;
- u8 reserved[12];
-} __packed; /* LQM_MEASUREMENT_COMPLETE_NTF_API_S_VER1 */
-
/**
* struct iwl_channel_switch_noa_notif - Channel switch NOA notification
*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
index 71a01df96f8b..4228fac77f41 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
@@ -1455,80 +1455,6 @@ static const char * const chanwidths[] = {
[NL80211_CHAN_WIDTH_160] = "vht160",
};
-static bool iwl_mvm_lqm_notif_wait(struct iwl_notif_wait_data *notif_wait,
- struct iwl_rx_packet *pkt, void *data)
-{
- struct ieee80211_vif *vif = data;
- struct iwl_mvm *mvm =
- container_of(notif_wait, struct iwl_mvm, notif_wait);
- struct iwl_link_qual_msrmnt_notif *report = (void *)pkt->data;
- u32 num_of_stations = le32_to_cpu(report->number_of_stations);
- int i;
-
- IWL_INFO(mvm, "LQM report:\n");
- IWL_INFO(mvm, "\tstatus: %d\n", report->status);
- IWL_INFO(mvm, "\tmacID: %d\n", le32_to_cpu(report->mac_id));
- IWL_INFO(mvm, "\ttx_frame_dropped: %d\n",
- le32_to_cpu(report->tx_frame_dropped));
- IWL_INFO(mvm, "\ttime_in_measurement_window: %d us\n",
- le32_to_cpu(report->time_in_measurement_window));
- IWL_INFO(mvm, "\ttotal_air_time_other_stations: %d\n",
- le32_to_cpu(report->total_air_time_other_stations));
- IWL_INFO(mvm, "\tchannel_freq: %d\n",
- vif->bss_conf.chandef.center_freq1);
- IWL_INFO(mvm, "\tchannel_width: %s\n",
- chanwidths[vif->bss_conf.chandef.width]);
- IWL_INFO(mvm, "\tnumber_of_stations: %d\n", num_of_stations);
- for (i = 0; i < num_of_stations; i++)
- IWL_INFO(mvm, "\t\tsta[%d]: %d\n", i,
- report->frequent_stations_air_time[i]);
-
- return true;
-}
-
-static ssize_t iwl_dbgfs_lqm_send_cmd_write(struct ieee80211_vif *vif,
- char *buf, size_t count,
- loff_t *ppos)
-{
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- struct iwl_mvm *mvm = mvmvif->mvm;
- struct iwl_notification_wait wait_lqm_notif;
- static u16 lqm_notif[] = {
- WIDE_ID(MAC_CONF_GROUP,
- LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF)
- };
- int err;
- u32 duration;
- u32 timeout;
-
- if (sscanf(buf, "%d,%d", &duration, &timeout) != 2)
- return -EINVAL;
-
- iwl_init_notification_wait(&mvm->notif_wait, &wait_lqm_notif,
- lqm_notif, ARRAY_SIZE(lqm_notif),
- iwl_mvm_lqm_notif_wait, vif);
- mutex_lock(&mvm->mutex);
- err = iwl_mvm_send_lqm_cmd(vif, LQM_CMD_OPERATION_START_MEASUREMENT,
- duration, timeout);
- mutex_unlock(&mvm->mutex);
-
- if (err) {
- IWL_ERR(mvm, "Failed to send lqm cmdf(err=%d)\n", err);
- iwl_remove_notification(&mvm->notif_wait, &wait_lqm_notif);
- return err;
- }
-
- /* wait for 2 * timeout (safety guard) and convert to jiffies*/
- timeout = msecs_to_jiffies((timeout * 2) / 1000);
-
- err = iwl_wait_notification(&mvm->notif_wait, &wait_lqm_notif,
- timeout);
- if (err)
- IWL_ERR(mvm, "Getting lqm notif timed out\n");
-
- return count;
-}
-
#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -1553,7 +1479,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(tof_range_abort, 32);
MVM_DEBUGFS_READ_FILE_OPS(tof_range_response);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(tof_responder_params, 32);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(quota_min, 32);
-MVM_DEBUGFS_WRITE_FILE_OPS(lqm_send_cmd, 64);
MVM_DEBUGFS_READ_FILE_OPS(os_device_timediff);
@@ -1594,7 +1519,6 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
S_IRUSR | S_IWUSR);
MVM_DEBUGFS_ADD_FILE_VIF(quota_min, mvmvif->dbgfs_dir,
S_IRUSR | S_IWUSR);
- MVM_DEBUGFS_ADD_FILE_VIF(lqm_send_cmd, mvmvif->dbgfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE_VIF(os_device_timediff,
mvmvif->dbgfs_dir, S_IRUSR);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 15f2d826bb4b..8b4584541272 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1878,11 +1878,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
- if (changes & BSS_CHANGED_ASSOC && !bss_conf->assoc &&
- mvmvif->lqm_active)
- iwl_mvm_send_lqm_cmd(vif, LQM_CMD_OPERATION_STOP_MEASUREMENT,
- 0, 0);
-
/*
* If we're not associated yet, take the (new) BSSID before associating
* so the firmware knows. If we're already associated, then use the old
@@ -3879,11 +3874,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
break;
case NL80211_IFTYPE_STATION:
- if (mvmvif->lqm_active)
- iwl_mvm_send_lqm_cmd(vif,
- LQM_CMD_OPERATION_STOP_MEASUREMENT,
- 0, 0);
-
/* Schedule the time event to a bit before beacon 1,
* to make sure we're in the new channel when the
* GO/AP arrives. In case count <= 1 immediately schedule the
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 48cb08eea700..ec2cf248990b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -436,12 +436,6 @@ struct iwl_mvm_vif {
/* TCP Checksum Offload */
netdev_features_t features;
-
- /*
- * link quality measurement - used to check whether this interface
- * is in the middle of a link quality measurement
- */
- bool lqm_active;
};
static inline struct iwl_mvm_vif *
@@ -1846,12 +1840,6 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
const char *errmsg);
-/* Link Quality Measurement */
-int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
- enum iwl_lqm_cmd_operatrions operation,
- u32 duration, u32 timeout);
-bool iwl_mvm_lqm_active(struct iwl_mvm *mvm);
-
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);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 231878969332..d855920f5456 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -423,8 +423,6 @@ static const struct iwl_hcmd_names iwl_mvm_system_names[] = {
* Access is done through binary search
*/
static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = {
- HCMD_NAME(LINK_QUALITY_MEASUREMENT_CMD),
- HCMD_NAME(LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF),
HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF),
};
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 2ea74abad73d..328035640669 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -1389,74 +1389,3 @@ void iwl_mvm_get_sync_time(struct iwl_mvm *mvm, u32 *gp2, u64 *boottime)
iwl_mvm_power_update_device(mvm);
}
}
-
-int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
- enum iwl_lqm_cmd_operatrions operation,
- u32 duration, u32 timeout)
-{
- struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
- struct iwl_link_qual_msrmnt_cmd cmd = {
- .cmd_operation = cpu_to_le32(operation),
- .mac_id = cpu_to_le32(mvm_vif->id),
- .measurement_time = cpu_to_le32(duration),
- .timeout = cpu_to_le32(timeout),
- };
- u32 cmdid =
- iwl_cmd_id(LINK_QUALITY_MEASUREMENT_CMD, MAC_CONF_GROUP, 0);
- int ret;
-
- if (!fw_has_capa(&mvm_vif->mvm->fw->ucode_capa,
- IWL_UCODE_TLV_CAPA_LQM_SUPPORT))
- return -EOPNOTSUPP;
-
- if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
- return -EINVAL;
-
- switch (operation) {
- case LQM_CMD_OPERATION_START_MEASUREMENT:
- if (iwl_mvm_lqm_active(mvm_vif->mvm))
- return -EBUSY;
- if (!vif->bss_conf.assoc)
- return -EINVAL;
- mvm_vif->lqm_active = true;
- break;
- case LQM_CMD_OPERATION_STOP_MEASUREMENT:
- if (!iwl_mvm_lqm_active(mvm_vif->mvm))
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- ret = iwl_mvm_send_cmd_pdu(mvm_vif->mvm, cmdid, 0, sizeof(cmd),
- &cmd);
-
- /* command failed - roll back lqm_active state */
- if (ret) {
- mvm_vif->lqm_active =
- operation == LQM_CMD_OPERATION_STOP_MEASUREMENT;
- }
-
- return ret;
-}
-
-static void iwl_mvm_lqm_active_iterator(void *_data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
- bool *lqm_active = _data;
-
- *lqm_active = *lqm_active || mvm_vif->lqm_active;
-}
-
-bool iwl_mvm_lqm_active(struct iwl_mvm *mvm)
-{
- bool ret = false;
-
- lockdep_assert_held(&mvm->mutex);
- ieee80211_iterate_active_interfaces_atomic(
- mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
- iwl_mvm_lqm_active_iterator, &ret);
-
- return ret;
-}
--
2.14.1
^ permalink raw reply related
* [PATCH 07/10] iwlwifi: mvm: support firmware debug trigger on frame reorder timeout
From: Luca Coelho @ 2017-09-15 12:47 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Emmanuel Grumbach, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
The trigger that collects data when a frame is released
because of the timer of the reordering buffer was not
implemented for 9000 devices.
Fix this.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 28 ++---------------------
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 6 +++++
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 5 ++++
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 1 +
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 25 ++++++++++++++++++++
5 files changed, 39 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 8b4584541272..d7530474c1d3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -4186,31 +4186,6 @@ static void iwl_mvm_event_bar_rx_callback(struct iwl_mvm *mvm,
event->u.ba.ssn);
}
-static void
-iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- const struct ieee80211_event *event)
-{
- struct iwl_fw_dbg_trigger_tlv *trig;
- struct iwl_fw_dbg_trigger_ba *ba_trig;
-
- if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_BA))
- return;
-
- trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_BA);
- ba_trig = (void *)trig->data;
- if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
- ieee80211_vif_to_wdev(vif), trig))
- return;
-
- if (!(le16_to_cpu(ba_trig->frame_timeout) & BIT(event->u.ba.tid)))
- return;
-
- iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
- "Frame from %pM timed out, tid %d",
- event->u.ba.sta->addr, event->u.ba.tid);
-}
-
static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const struct ieee80211_event *event)
@@ -4225,7 +4200,8 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
iwl_mvm_event_bar_rx_callback(mvm, vif, event);
break;
case BA_FRAME_TIMEOUT:
- iwl_mvm_event_frame_timeout_callback(mvm, vif, event);
+ iwl_mvm_event_frame_timeout_callback(mvm, vif, event->u.ba.sta,
+ event->u.ba.tid);
break;
default:
break;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index ec2cf248990b..e8be5104b909 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -586,6 +586,7 @@ enum iwl_mvm_tdls_cs_state {
* @queue: queue of this reorder buffer
* @last_amsdu: track last ASMDU SN for duplication detection
* @last_sub_index: track ASMDU sub frame index for duplication detection
+ * @tid: the tid
* @entries: list of skbs stored
* @reorder_time: time the packet was stored in the reorder buffer
* @reorder_timer: timer for frames are in the reorder buffer. For AMSDU
@@ -603,6 +604,7 @@ struct iwl_mvm_reorder_buffer {
int queue;
u16 last_amsdu;
u8 last_sub_index;
+ u8 tid;
struct sk_buff_head entries[IEEE80211_MAX_AMPDU_BUF];
unsigned long reorder_time[IEEE80211_MAX_AMPDU_BUF];
struct timer_list reorder_timer;
@@ -1839,6 +1841,10 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
bool tdls, bool cmd_q);
void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
const char *errmsg);
+void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ const struct ieee80211_sta *sta,
+ u16 tid);
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);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 67ffd9774712..a0b406e68d55 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -492,13 +492,18 @@ void iwl_mvm_reorder_timer_expired(unsigned long data)
if (expired) {
struct ieee80211_sta *sta;
+ struct iwl_mvm_sta *mvmsta;
rcu_read_lock();
sta = rcu_dereference(buf->mvm->fw_id_to_mac_id[buf->sta_id]);
+ mvmsta = iwl_mvm_sta_from_mac80211(sta);
+
/* SN is set to the last expired frame + 1 */
IWL_DEBUG_HT(buf->mvm,
"Releasing expired frames for sta %u, sn %d\n",
buf->sta_id, sn);
+ iwl_mvm_event_frame_timeout_callback(buf->mvm, mvmsta->vif,
+ sta, buf->tid);
iwl_mvm_release_frames(buf->mvm, sta, NULL, buf, sn);
rcu_read_unlock();
} else {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 411a2055dc45..3711f226220c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2158,6 +2158,7 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm,
reorder_buf->mvm = mvm;
reorder_buf->queue = i;
reorder_buf->sta_id = sta_id;
+ reorder_buf->tid = data->tid;
reorder_buf->valid = false;
for (j = 0; j < reorder_buf->buf_size; j++)
__skb_queue_head_init(&reorder_buf->entries[j]);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 328035640669..2da1b088ac01 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -1368,6 +1368,31 @@ void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
rcu_read_unlock();
}
+void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ const struct ieee80211_sta *sta,
+ u16 tid)
+{
+ struct iwl_fw_dbg_trigger_tlv *trig;
+ struct iwl_fw_dbg_trigger_ba *ba_trig;
+
+ if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_BA))
+ return;
+
+ trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_BA);
+ ba_trig = (void *)trig->data;
+ if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
+ ieee80211_vif_to_wdev(vif), trig))
+ return;
+
+ if (!(le16_to_cpu(ba_trig->frame_timeout) & BIT(tid)))
+ return;
+
+ iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
+ "Frame from %pM timed out, tid %d",
+ sta->addr, tid);
+}
+
void iwl_mvm_get_sync_time(struct iwl_mvm *mvm, u32 *gp2, u64 *boottime)
{
bool ps_disabled;
--
2.14.1
^ permalink raw reply related
* [PATCH 08/10] iwlwifi: Add few debug prints to the WRT dump flow
From: Luca Coelho @ 2017-09-15 12:47 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Ilan Peer, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Ilan Peer <ilan.peer@intel.com>
This would enable to better catch timing issues with
cases that WRT dump takes too much time.
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 6afc7a799892..f7eab03937f2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -93,6 +93,8 @@ static void iwl_read_radio_regs(struct iwl_fw_runtime *fwrt,
unsigned long flags;
int i;
+ IWL_DEBUG_INFO(fwrt, "WRT radio registers dump\n");
+
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
return;
@@ -233,6 +235,8 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
unsigned long flags;
int i, j;
+ IWL_DEBUG_INFO(fwrt, "WRT FIFO dump\n");
+
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
return;
@@ -476,6 +480,8 @@ static void iwl_dump_prph(struct iwl_trans *trans,
unsigned long flags;
u32 i;
+ IWL_DEBUG_INFO(trans, "WRT PRPH dump\n");
+
if (!iwl_trans_grab_nic_access(trans, &flags))
return;
@@ -559,6 +565,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
bool monitor_dump_only = false;
int i;
+ IWL_DEBUG_INFO(fwrt, "WRT dump start\n");
+
/* there's no point in fw dump if the bus is dead */
if (test_bit(STATUS_TRANS_DEAD, &fwrt->trans->status)) {
IWL_ERR(fwrt, "Skip fw error dump since bus is dead\n");
@@ -816,6 +824,9 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
dump_mem->type = fw_dbg_mem[i].data_type;
dump_mem->offset = cpu_to_le32(ofs);
+ IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n",
+ dump_mem->type);
+
switch (dump_mem->type & cpu_to_le32(FW_DBG_MEM_TYPE_MASK)) {
case cpu_to_le32(FW_DBG_MEM_TYPE_REGULAR):
iwl_trans_read_mem_bytes(fwrt->trans, ofs,
@@ -841,6 +852,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
}
if (smem_len) {
+ IWL_DEBUG_INFO(fwrt, "WRT SMEM dump\n");
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
dump_data->len = cpu_to_le32(smem_len + sizeof(*dump_mem));
dump_mem = (void *)dump_data->data;
@@ -853,6 +865,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
}
if (sram2_len) {
+ IWL_DEBUG_INFO(fwrt, "WRT SRAM dump\n");
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem));
dump_mem = (void *)dump_data->data;
@@ -868,6 +881,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
if (!fwrt->trans->cfg->gen2 &&
fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
fwrt->fw_paging_db[0].fw_paging_block) {
+ IWL_DEBUG_INFO(fwrt, "WRT paging dump\n");
for (i = 1; i < fwrt->num_of_paging_blk + 1; i++) {
struct iwl_fw_error_dump_paging *paging;
struct page *pages =
@@ -930,6 +944,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
iwl_fw_free_dump_desc(fwrt);
fwrt->dump.trig = NULL;
clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status);
+ IWL_DEBUG_INFO(fwrt, "WRT dump done\n");
}
IWL_EXPORT_SYMBOL(iwl_fw_error_dump);
--
2.14.1
^ permalink raw reply related
* [PATCH 09/10] iwlwifi: pcie: dynamic Tx command queue size
From: Luca Coelho @ 2017-09-15 12:47 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Shahar S Matityahu, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Devices in the A000 family can use a different size for the command queue.
To allow this, make the command queue size configurable and set the size
for A000 devices to 32.
Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/cfg/a000.c | 3 ++-
drivers/net/wireless/intel/iwlwifi/iwl-config.h | 3 +++
.../net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 2 +-
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 3 +++
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 8 ++++++--
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 23 ++++++++++++++++++++--
6 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
index 76ba1f8bc72f..ed8bccd228f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c
@@ -134,7 +134,8 @@ static const struct iwl_ht_params iwl_a000_ht_params = {
.rf_id = true, \
.gen2 = true, \
.ext_nvm = true, \
- .dbgc_supported = true
+ .dbgc_supported = true, \
+ .tx_cmd_queue_size = 32
const struct iwl_cfg iwla000_2ac_cfg_hr = {
.name = "Intel(R) Dual Band Wireless AC a000",
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 3e057b539d5b..b9f3b350fe34 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -321,6 +321,8 @@ struct iwl_pwr_tx_backoff {
* @gen2: a000 and on transport operation
* @cdb: CDB support
* @ext_nvm: extended NVM format
+ * @tx_cmd_queue_size: size of the cmd queue. If zero, use the same value as
+ * the regular queues
*
* We enable the driver to be backward compatible wrt. hardware features.
* API differences in uCode shouldn't be handled here but through TLVs
@@ -371,6 +373,7 @@ struct iwl_cfg {
cdb:1,
ext_nvm:1,
dbgc_supported:1;
+ u16 tx_cmd_queue_size;
u8 valid_tx_ant;
u8 valid_rx_ant;
u8 non_shared_ant;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
index 3fc4343581ee..5ef216f3a60b 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_CMD_SLOTS);
+ TFD_QUEUE_CB_SIZE(trans_pcie->tx_cmd_queue_size);
/* 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 79020cf8c79c..5647182e1b46 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -383,6 +383,7 @@ struct iwl_self_init_dram {
* @hw_init_mask: initial unmasked hw causes
* @fh_mask: current unmasked fh causes
* @hw_mask: current unmasked hw causes
+ * @tx_cmd_queue_size: the size of the tx command queue
*/
struct iwl_trans_pcie {
struct iwl_rxq *rxq;
@@ -463,6 +464,7 @@ struct iwl_trans_pcie {
u32 fh_mask;
u32 hw_mask;
cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
+ u16 tx_cmd_queue_size;
};
static inline struct iwl_trans_pcie *
@@ -534,6 +536,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
struct sk_buff_head *skbs);
void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
+void iwl_pcie_set_tx_cmd_queue_size(struct iwl_trans *trans);
static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd,
u8 idx)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index d74613fcb756..79e4c73a9709 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -1160,6 +1160,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
struct iwl_txq *cmd_queue;
int txq_id = trans_pcie->cmd_queue, ret;
+ iwl_pcie_set_tx_cmd_queue_size(trans);
+
/* alloc and init the command queue */
if (!trans_pcie->txq[txq_id]) {
cmd_queue = kzalloc(sizeof(*cmd_queue), GFP_KERNEL);
@@ -1168,7 +1170,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
return -ENOMEM;
}
trans_pcie->txq[txq_id] = cmd_queue;
- ret = iwl_pcie_txq_alloc(trans, cmd_queue, TFD_CMD_SLOTS, true);
+ ret = iwl_pcie_txq_alloc(trans, cmd_queue,
+ trans_pcie->tx_cmd_queue_size, true);
if (ret) {
IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
goto error;
@@ -1177,7 +1180,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
cmd_queue = trans_pcie->txq[txq_id];
}
- ret = iwl_pcie_txq_init(trans, cmd_queue, TFD_CMD_SLOTS, true);
+ ret = iwl_pcie_txq_init(trans, cmd_queue,
+ trans_pcie->tx_cmd_queue_size, true);
if (ret) {
IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
goto error;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index c645d10d3707..e93c471ef9bf 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -951,7 +951,8 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
txq_id++) {
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
- slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+ slots_num = cmd_queue ? trans_pcie->tx_cmd_queue_size :
+ TFD_TX_CMD_SLOTS;
trans_pcie->txq[txq_id] = &trans_pcie->txq_memory[txq_id];
ret = iwl_pcie_txq_alloc(trans, trans_pcie->txq[txq_id],
slots_num, cmd_queue);
@@ -970,6 +971,21 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
return ret;
}
+void iwl_pcie_set_tx_cmd_queue_size(struct iwl_trans *trans)
+{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ int queue_size = TFD_CMD_SLOTS;
+
+ if (trans->cfg->tx_cmd_queue_size)
+ queue_size = trans->cfg->tx_cmd_queue_size;
+
+ if (WARN_ON(!(is_power_of_2(queue_size) &&
+ TFD_QUEUE_CB_SIZE(queue_size) > 0)))
+ trans_pcie->tx_cmd_queue_size = TFD_CMD_SLOTS;
+ else
+ trans_pcie->tx_cmd_queue_size = queue_size;
+}
+
int iwl_pcie_tx_init(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -977,6 +993,8 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
int txq_id, slots_num;
bool alloc = false;
+ iwl_pcie_set_tx_cmd_queue_size(trans);
+
if (!trans_pcie->txq_memory) {
ret = iwl_pcie_tx_alloc(trans);
if (ret)
@@ -1000,7 +1018,8 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
txq_id++) {
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
- slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+ slots_num = cmd_queue ? trans_pcie->tx_cmd_queue_size :
+ TFD_TX_CMD_SLOTS;
ret = iwl_pcie_txq_init(trans, trans_pcie->txq[txq_id],
slots_num, cmd_queue);
if (ret) {
--
2.14.1
^ permalink raw reply related
* [PATCH 10/10] iwlwifi: remove redundant reading from NVM file
From: Luca Coelho @ 2017-09-15 12:47 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Chaya Rachel Ivgi, Luca Coelho
In-Reply-To: <20170915124704.9032-1-luca@coelho.fi>
From: Chaya Rachel Ivgi <chaya.rachel.ivgi@intel.com>
The driver reads xtal_calib from NVM file, but actually never uses it.
This is only used in dvm driver.
Signed-off-by: Chaya Rachel Ivgi <chaya.rachel.ivgi@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 3014beef4873..4574a126c1ae 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -89,10 +89,6 @@ enum wkp_nvm_offsets {
SKU = 2,
N_HW_ADDRS = 3,
NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
-
- /* NVM calibration section offset (in words) definitions */
- NVM_CALIB_SECTION = 0x2B8,
- XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
};
enum ext_nvm_offsets {
@@ -748,9 +744,6 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
kfree(data);
return NULL;
}
- /* in family 8000 Xtal calibration values moved to OTP */
- data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
- data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
lar_enabled = true;
ch_section = &nvm_sw[NVM_CHANNELS];
} else {
--
2.14.1
^ permalink raw reply related
* Re: ROAM/CONNECT event with PORT_AUTHORIZED
From: Denis Kenzior @ 2017-09-15 12:50 UTC (permalink / raw)
To: Johannes Berg, Arend van Spriel, Jouni Malinen
Cc: Avraham Stern, linux-wireless
In-Reply-To: <1505459955.31630.26.camel@sipsolutions.net>
Hi Johannes,
On 09/15/2017 02:19 AM, Johannes Berg wrote:
> On Thu, 2017-09-14 at 14:54 -0500, Denis Kenzior wrote:
>
>> If you want roaming to keep oper state UP in all cases, then
>> yes. Does this work on full mac cards as well?
>
> I don't see why not.
>
>> E.g. if I CMD_CONNECT to AP1, then pre-authenticate to AP2 and issue
>> a CMD_CONNECT to AP2?
>
> That's not something you can do with full-MAC cards?
Err, why not? Pre-Authentication runs over a 0x88c7 protocol. So we
should get these just like regular PAE frames. But forget
pre-authentication, one can still force a roam between BSSes within the
same ESS by specifying NL80211_ATTR_PREV_BSSID. At least that's what
the docs say ;)
>
> And even mac80211 doesn't really support pre-authentication (unless you
> mean over-the-DS)
>
There's only one kind of preauthentication? Are you confusing this with
FT? We use FT-over-Air just fine on mac80211 and on real hardware. We
even have an autotest for this based on mac80211_hwsim. FT-over-DS
should work as well.
Full macs don't support FT due to lack of
CMD_ASSOCIATE/CMD_AUTHENTICATE. Can we fix that btw?
Regards,
-Denis
^ permalink raw reply
* Re: ROAM/CONNECT event with PORT_AUTHORIZED
From: Johannes Berg @ 2017-09-15 13:29 UTC (permalink / raw)
To: Denis Kenzior, Arend van Spriel, Jouni Malinen
Cc: Avraham Stern, linux-wireless
In-Reply-To: <ff73f237-71dd-5fde-9c9f-9bc8fce57e76@gmail.com>
On Fri, 2017-09-15 at 07:50 -0500, Denis Kenzior wrote:
> > > E.g. if I CMD_CONNECT to AP1, then pre-authenticate to AP2 and
> > > issue a CMD_CONNECT to AP2?
> >
> > That's not something you can do with full-MAC cards?
>
> Err, why not? Pre-Authentication runs over a 0x88c7 protocol. So
> we should get these just like regular PAE frames. But forget
> pre-authentication, one can still force a roam between BSSes within
> the same ESS by specifying NL80211_ATTR_PREV_BSSID. At least that's
> what the docs say ;)
Oh, you meant that kind of pre-authentication :-)
I thought you meant sending an 802.11 auth frame to the new AP before
breaking the connection to the old AP.
> > And even mac80211 doesn't really support pre-authentication (unless
> > you mean over-the-DS)
>
> There's only one kind of preauthentication? Are you confusing this
> with FT?
No, see above.
> We use FT-over-Air just fine on mac80211 and on real hardware. We
> even have an autotest for this based on mac80211_hwsim. FT-over-DS
> should work as well.
>
> Full macs don't support FT due to lack of
> CMD_ASSOCIATE/CMD_AUTHENTICATE. Can we fix that btw?
Well, with full MAC devices you should let the device decide on the
BSS?
johannes
^ permalink raw reply
* Re: [PATCH] Revert "PCI: Avoid race while enabling upstream bridges"
From: Konstantin Khlebnikov @ 2017-09-15 13:28 UTC (permalink / raw)
To: Bjorn Helgaas, linux-pci
Cc: Jens Axboe, Emmanuel Grumbach, linuxwifi, linux-wireless,
linux-kernel, Srinath Mannam, Johannes Berg, Luca Coelho
In-Reply-To: <20170915072352.10453.31977.stgit@bhelgaas-glaptop.roam.corp.google.com>
On 15.09.2017 10:23, Bjorn Helgaas wrote:
> This reverts commit 40f11adc7cd9281227f0a6a627d966dd0a5f0cd9.
>
> Jens found that iwlwifi firmware loading failed on a Lenovo X1 Carbon,
> gen4:
>
> iwlwifi 0000:04:00.0: Direct firmware load for iwlwifi-8000C-34.ucode failed with error -2
> iwlwifi 0000:04:00.0: Direct firmware load for iwlwifi-8000C-33.ucode failed with error -2
> iwlwifi 0000:04:00.0: Direct firmware load for iwlwifi-8000C-32.ucode failed with error -2
> iwlwifi 0000:04:00.0: loaded firmware version 31.532993.0 op_mode iwlmvm
> iwlwifi 0000:04:00.0: Detected Intel(R) Dual Band Wireless AC 8260, REV=0x208
> ...
> iwlwifi 0000:04:00.0: Failed to load firmware chunk!
> iwlwifi 0000:04:00.0: Could not load the [0] uCode section
> iwlwifi 0000:04:00.0: Failed to start INIT ucode: -110
> iwlwifi 0000:04:00.0: Failed to run INIT ucode: -110
>
> He bisected it to 40f11adc7cd9 ("PCI: Avoid race while enabling upstream
> bridges"). Revert that commit to fix the regression.
I've found this too. Bug in fast-path: reverting last hunk is enough
http://lkml.kernel.org/r/150547971091.977464.16294045866179907260.stgit@buzz
>
> Link: http://lkml.kernel.org/r/4bcbcbc1-7c79-09f0-5071-bc2f53bf6574@kernel.dk
> Fixes: 40f11adc7cd9 ("PCI: Avoid race while enabling upstream bridges")
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> CC: Srinath Mannam <srinath.mannam@broadcom.com>
> CC: Jens Axboe <axboe@kernel.dk>
> CC: Luca Coelho <luca@coelho.fi>
> CC: Johannes Berg <johannes@sipsolutions.net>
> CC: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
> ---
> drivers/pci/pci.c | 13 ++-----------
> 1 file changed, 2 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index b0002daa50f3..6078dfc11b11 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -52,7 +52,6 @@ static void pci_pme_list_scan(struct work_struct *work);
> static LIST_HEAD(pci_pme_list);
> static DEFINE_MUTEX(pci_pme_list_mutex);
> static DECLARE_DELAYED_WORK(pci_pme_work, pci_pme_list_scan);
> -static DEFINE_MUTEX(pci_bridge_mutex);
>
> struct pci_pme_device {
> struct list_head list;
> @@ -1351,16 +1350,10 @@ static void pci_enable_bridge(struct pci_dev *dev)
> if (bridge)
> pci_enable_bridge(bridge);
>
> - /*
> - * Hold pci_bridge_mutex to prevent a race when enabling two
> - * devices below the bridge simultaneously. The race may cause a
> - * PCI_COMMAND_MEMORY update to be lost (see changelog).
> - */
> - mutex_lock(&pci_bridge_mutex);
> if (pci_is_enabled(dev)) {
> if (!dev->is_busmaster)
> pci_set_master(dev);
> - goto end;
> + return;
> }
>
> retval = pci_enable_device(dev);
> @@ -1368,8 +1361,6 @@ static void pci_enable_bridge(struct pci_dev *dev)
> dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n",
> retval);
> pci_set_master(dev);
> -end:
> - mutex_unlock(&pci_bridge_mutex);
> }
>
> static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
> @@ -1394,7 +1385,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
> return 0; /* already enabled */
>
> bridge = pci_upstream_bridge(dev);
> - if (bridge && !pci_is_enabled(bridge))
> + if (bridge)
> pci_enable_bridge(bridge);
>
> /* only skip sriov related */
>
>
^ permalink raw reply
* Re: ROAM/CONNECT event with PORT_AUTHORIZED
From: Denis Kenzior @ 2017-09-15 13:50 UTC (permalink / raw)
To: Johannes Berg, Arend van Spriel, Jouni Malinen
Cc: Avraham Stern, linux-wireless
In-Reply-To: <1505482156.31630.39.camel@sipsolutions.net>
Hi Johannes,
On 09/15/2017 08:29 AM, Johannes Berg wrote:
> On Fri, 2017-09-15 at 07:50 -0500, Denis Kenzior wrote:
>
>>>> E.g. if I CMD_CONNECT to AP1, then pre-authenticate to AP2 and
>>>> issue a CMD_CONNECT to AP2?
>>>
>>> That's not something you can do with full-MAC cards?
>>
>> Err, why not? Pre-Authentication runs over a 0x88c7 protocol. So
>> we should get these just like regular PAE frames. But forget
>> pre-authentication, one can still force a roam between BSSes within
>> the same ESS by specifying NL80211_ATTR_PREV_BSSID. At least that's
>> what the docs say ;)
>
> Oh, you meant that kind of pre-authentication :-)
>
> I thought you meant sending an 802.11 auth frame to the new AP before
> breaking the connection to the old AP.
>
I mean 802.11-2012 Section 11.5.9.2 type preauthentication.
And AFAIK the kernel generates a disconnected event as soon as we send a
CMD_AUTHENTICATE, so not sure how you envision 'your' preauthentication
working...
However, you're not answering my question...
>>> And even mac80211 doesn't really support pre-authentication (unless
>>> you mean over-the-DS)
>
>>
>> There's only one kind of preauthentication? Are you confusing this
>> with FT?
>
> No, see above.
>
>> We use FT-over-Air just fine on mac80211 and on real hardware. We
>> even have an autotest for this based on mac80211_hwsim. FT-over-DS
>> should work as well.
>>
>> Full macs don't support FT due to lack of
>> CMD_ASSOCIATE/CMD_AUTHENTICATE. Can we fix that btw?
>
> Well, with full MAC devices you should let the device decide on the
> BSS?
>
Why? So we can deal with the various ways a vendor firmware can screw
up? Besides, you have an asymmetry in the kernel API. One can use
regular roaming on a full mac but not FT.
Regards,
-Denis
^ permalink raw reply
* Re: ROAM/CONNECT event with PORT_AUTHORIZED
From: Johannes Berg @ 2017-09-15 14:20 UTC (permalink / raw)
To: Denis Kenzior, Arend van Spriel, Jouni Malinen
Cc: Avraham Stern, linux-wireless
In-Reply-To: <9b466254-e9c1-c5e4-c3fd-b881c4c583e9@gmail.com>
On Fri, 2017-09-15 at 08:50 -0500, Denis Kenzior wrote:
> > I thought you meant sending an 802.11 auth frame to the new AP
> > before breaking the connection to the old AP.
> >
>
> I mean 802.11-2012 Section 11.5.9.2 type preauthentication.
Yeha, OK.
> And AFAIK the kernel generates a disconnected event as soon as we
> send a CMD_AUTHENTICATE, so not sure how you envision 'your'
> preauthentication working...
That's what I was trying to say - it doesn't. A few years ago we tried
to support that but it's not really possible to do well.
> However, you're not answering my question...
Which was?
> > Well, with full MAC devices you should let the device decide on the
> > BSS?
> >
>
> Why? So we can deal with the various ways a vendor firmware can
> screw up? Besides, you have an asymmetry in the kernel API.
:)
> One can use regular roaming on a full mac but not FT.
We had intended to have NL80211_CMD_ROAM to make that decision once,
but never really used it for that... I think it could be implemented
but I don't really know how well drivers were to support it.
johannes
^ permalink raw reply
* Re: ROAM/CONNECT event with PORT_AUTHORIZED
From: Denis Kenzior @ 2017-09-15 14:27 UTC (permalink / raw)
To: Johannes Berg, Arend van Spriel, Jouni Malinen
Cc: Avraham Stern, linux-wireless
In-Reply-To: <1505485208.31630.42.camel@sipsolutions.net>
Hi Johannes,
>> And AFAIK the kernel generates a disconnected event as soon as we
>> send a CMD_AUTHENTICATE, so not sure how you envision 'your'
>> preauthentication working...
>
> That's what I was trying to say - it doesn't. A few years ago we tried
> to support that but it's not really possible to do well.
Okay, *now* I'm with you :)
>
>> However, you're not answering my question...
>
> Which was?
So if we issue CMD_CONNECT with a PREV_BSSID, does/should OPERSTATE
still stay UP?
>> One can use regular roaming on a full mac but not FT.
>
> We had intended to have NL80211_CMD_ROAM to make that decision once,
> but never really used it for that... I think it could be implemented
> but I don't really know how well drivers were to support it.
I think it would be nice. Worst case a driver won't implement it, but
we can use FT on those that do.
Regards,
-Denis
^ permalink raw reply
* Re: rtlwifi/rtl8188ee baseband config explanation request
From: Larry Finger @ 2017-09-15 14:33 UTC (permalink / raw)
To: Farhan Khan, linux-wireless
In-Reply-To: <4e962e58-3e1a-2d97-b952-26a56c652bae@gmail.com>
On 09/15/2017 01:26 AM, Farhan Khan wrote:
> Thank you for your prompt response.
>
> I am trying to write a FreeBSD port of this driver. The structures of
> the two drivers are significantly different, so it is not a trivial
> exercise.
>
> The FreeBSD driver also has a similar block of code that writes over an
> array of data using an array of registers, and this should be easy to
> re-create. But I do not see the equivalent of phy_config_bb_with_pghdr()
> anywhere. I do not know if I need to maintain the order for any reason.
>
> I attempted to reach out to Realtek through multiple mediums but did not
> receive any replies. Ultimately, I may end up re-playing the same bits
> without understanding what is happening.
You should have stated your purpose at the start.
Those sections are loading data for the firmware to use. As you probably are not
writing your own firmware, and not doing your own calibration, then you should
just copy all the code that touches the data in the file table.c. The firmware
does not care whether the host is Linux or FreeBSD. It still has to do that same
operations on the radio, and this is the data it needs.
As I said in my initial response, I think the PHY register data needs to be
written before the AGC data as the latter is being written into a buffer that is
not directly accessible from the host, which means some previous step has set up
that transfer. As we do not know what that was, you likely need to do everything
in the same order.
Larry
^ permalink raw reply
* Re: ROAM/CONNECT event with PORT_AUTHORIZED
From: Johannes Berg @ 2017-09-15 14:52 UTC (permalink / raw)
To: Denis Kenzior, Arend van Spriel, Jouni Malinen
Cc: Avraham Stern, linux-wireless
In-Reply-To: <b87b61bc-6c29-3a4e-01bd-652cf1eb095c@gmail.com>
On Fri, 2017-09-15 at 09:27 -0500, Denis Kenzior wrote:
> > > However, you're not answering my question...
> >
> > Which was?
>
> So if we issue CMD_CONNECT with a PREV_BSSID, does/should OPERSTATE
> still stay UP?
It's difficult to do, but from a higher-layer POV I'd argue that it
should? I'd basically argue that it's no different from 802.1X
reauthentication, and the operstate docs say:
-set interface back to IF_OPER_DORMANT if 802.1X reauthentication
fails
> > We had intended to have NL80211_CMD_ROAM to make that decision
> > once,
> > but never really used it for that... I think it could be
> > implemented
> > but I don't really know how well drivers were to support it.
>
> I think it would be nice. Worst case a driver won't implement it,
> but we can use FT on those that do.
I have no idea how you'd ask them to do FT or just normal reassoc? I
guess they don't really care as long as the supplicant is in the host.
johannes
^ permalink raw reply
* Re: RTL8192EE PCIe Wireless Network Adapter crashed with linux-4.13
From: Larry Finger @ 2017-09-15 15:19 UTC (permalink / raw)
To: Zwindl
Cc: linux-wireless@vger.kernel.org, chaoming_li@realsil.com.cn,
kvalo@codeaurora.org, pkshih@realtek.com, johannes.berg@intel.com,
gregkh@linuxfoundation.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <jB0WJNG17mSfKo9m7T26r-b2Gr7mDL4lJ-1cWxeCJ6UCsA4TsxXz4znCLhYY5EASPQciwp1rf_xtwvDR-xzwD-OTApTUFoaVmIvahleDcJk=@protonmail.com>
On 09/15/2017 05:10 AM, Zwindl wrote:
>
>> -------- Original Message --------
>> Subject: Re: RTL8192EE PCIe Wireless Network Adapter crashed with linux-4.13
>> Local Time: 14 September 2017 6:05 PM
>> UTC Time: 14 September 2017 18:05
>> From: Larry.Finger@lwfinger.net
>> To: Zwindl <zwindl@protonmail.com>, linux-wireless@vger.kernel.org
>> <linux-wireless@vger.kernel.org>
>> chaoming_li@realsil.com.cn <chaoming_li@realsil.com.cn>, kvalo@codeaurora.org
>> <kvalo@codeaurora.org>, pkshih@realtek.com <pkshih@realtek.com>,
>> johannes.berg@intel.com <johannes.berg@intel.com>, gregkh@linuxfoundation.org
>> <gregkh@linuxfoundation.org>, netdev@vger.kernel.org <netdev@vger.kernel.org>,
>> linux-kernel@vger.kernel.org <linux-kernel@vger.kernel.org>
>>
>> On 09/14/2017 08:30 AM, Zwindl wrote:
>> > Dear developers:
>> > I"m using Arch Linux with testing enabled, the current kernel version and
>> > details are
>> > `Linux zwindl 4.13.2-1-ARCH #1 SMP PREEMPT Thu Sep 14 02:57:34 UTC 2017 x86_64
>> > GNU/Linux`.
>> > The wireless card can"t work properly from the kernel 4.13. Here"s the log(in
>> > attachment) when NetworkManager trying to connect my wifi which is named as
>> > "TP", my mac addr hided as xx:xx:xx:xx:xx.
>> > What should I provide to help to debug?
>> > ZWindL.
>>
>> The BUG-ON arises in __intel_map_single() due to dir (for direction of DMA)
>> equal to DMA_NONE (3). When rtl8192ee calls pci_map_single(), it uses
>> PCI_DMA_TODEVICE (1). I followed the calling sequence through the entire chain,
>> and none of the routines made any changes to "dir", other that changing the type
>> from int to enum dma_data_direction. That would not have changed a 1 to a 3.
>>
>> I built a 4.13.2 system. The problem does not happen here. At this point, the
>> system has been up for about two hours. I did discover a small memory leak
>> associated with firmware loading, but that should not have caused the problem.
>> Nonetheless, I will be sending a patch to fix that problem.
>>
>> I will continue testing, although I doubt that the problem will happen here.
>>
>> How long had your system been up when the problem occurred? Your dmesg fragment
>> did not show any times. What kernels have you tried besides 4.13.2?
>>
>> Larry
> Oh, sorry, the original log is from `journalctl`.
> Here's the `dmesg` prints(error.txt). I can't determine which part is related,
> so I paste all of it. I've tried 4.12.X(no issue), 4.13.1(issue), 4.13.2(issue).
> ZWindL
The output of dmesg is a lot more instructive than that of journalctl. I now
know exactly the location that triggered the WARNING. I still do not understand
it. In fact, it is likely a regression in kernel 4.13 that does not affect my
Toshiba laptop, nor a Lenovo machine I have, but does affect your Lenovo laptop.
Is it possible for you to install the mainline source from vger.kernel.org using
git and bisect the issue? It will take quite a bit of time, but it is likely the
only way to find the offending change. If you are willing to try this, I will
send you reasonably complete instructions.
By the way, it is usually better to load the dmesg output into a pastebin site
and post the link. Sending the entire file to a list makes a lot of people
receive a lot of data for which they have no interest.
Larry
^ permalink raw reply
* Re: RTL8192EE PCIe Wireless Network Adapter crashed with linux-4.13
From: Larry Finger @ 2017-09-15 19:21 UTC (permalink / raw)
To: Zwindl
Cc: linux-wireless@vger.kernel.org, chaoming_li@realsil.com.cn,
kvalo@codeaurora.org, pkshih@realtek.com, johannes.berg@intel.com,
gregkh@linuxfoundation.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <x1duse6v9TTP8Ta7rsTLlZ8DK0Ej7qq9iapef18K0eYSodmCBmfI_mX3c-3ocbPiGzEgV9weOh25dKWSbU5nIetYkfmmUxaxRpUdYFffRZA=@protonmail.com>
On 09/15/2017 12:12 PM, Zwindl wrote:
> Thanks for your patient and advice, I'll keep that in mind.
> I do want help, and I got 1 day to build the system, but I can't recall how to
> compile it, The last time I compile kernel is 2013, so, maybe I'll ask you so
> many stupid questions during the build time.
> ZWindL
Building a new kernel is not difficult. In an average week, I make at least 10
new kernels. Many of them are done on slow machines that take many hours. At
least, your i5 CPU should do it in less that one hour.
Step 1: Download the kernel sources using
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
If your system complains that the git command is unknown, then you will need to
install it with your package manager (pacman?).
Step 2: "cd linux" and copy the latest /boot/config-..... to the linux source
directory as ".config". Edit .config, find the line that says
"# CONFIG_LOCALVERSION_AUTO is not set", and change the line to read
"CONFIG_LOCALVERSION_AUTO=y".
Step 3: Build and install the latest version using
make -j9
sudo make modules_install install
You will need to answer some configuration questions at the start of the first
make line. Answer with the default value, i.e. just use an ENTER. When the build
is complete, reboot. Grub should show an entry for something like
v4.13-12084-ged43e4d190d0. The numbers after the 4.13 will likely be different,
but the form will match. Check that the new kernel still has the fault. If not,
it has been fixed and we do not need to find it.
It the problem is still in the latest version of the kernel, then we start the
bisection with the following:
git bisect start
git bisect bad v4.13
git bisect good v4.12
At this point, git will report the number of revisions to test, the likely
number of tries, and the SHA hash for the new kernel. Record the first 7 digits
of the hash, and repeat the make commands above. After the build is complete,
reboot into the kernel with the hash in the version name and test. Then enter
the command "git bisect xxx", where xxx is good or bad depending on the test. A
new trial will be generated by bisecting the appropriate half of the commits.
Record its hash and redo the build. Repeat until git tells you the bad commit.
This process will generate a number of kernels that will take quite a bit of
disk space. If you run short, you can delete kernels that have already been
tested from /boot. You should also delete the corresponding modules from
/lib/modules.
Good luck,
Larry
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Jens Axboe @ 2017-09-15 19:32 UTC (permalink / raw)
To: Srinath Mannam
Cc: Bjorn Helgaas, Johannes Berg, Luca Coelho, Grumbach, Emmanuel,
linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org, Linus Torvalds
In-Reply-To: <a5fd0c11-916f-1404-c979-2fd566ed72ec@kernel.dk>
On 09/14/2017 02:36 PM, Jens Axboe wrote:
> On 09/14/2017 02:04 PM, Srinath Mannam wrote:
>> Hi Jens Axboe,
>>
>>
>> On Thu, Sep 14, 2017 at 11:14 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>> On 09/14/2017 11:35 AM, Jens Axboe wrote:
>>>> On 09/14/2017 11:28 AM, Srinath Mannam wrote:
>>>>> Hi Bjorn,
>>>>>
>>>>> On Thu, Sep 14, 2017 at 10:52 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>>>>
>>>>>> On 09/14/2017 11:11 AM, Bjorn Helgaas wrote:
>>>>>>> [+cc linux-pci]
>>>>>>>
>>>>>>> On Thu, Sep 14, 2017 at 12:00 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>>>>>>> On 09/12/2017 02:04 PM, Johannes Berg wrote:
>>>>>>>>> On Tue, 2017-09-12 at 13:43 -0600, Jens Axboe wrote:
>>>>>>>>>
>>>>>>>>>> CC'ing the guilty part and Bjorn. I'm assuming it's the
>>>>>>>>>> pci_is_enabled() check, since the rest of the patch shouldn't have
>>>>>>>>>> functional changes.
>>>>>>>>>
>>>>>>>>> and pci_enable_bridge() already checks if it's already enabled, but
>>>>>>>>> still enables mastering in that case if it isn't:
>>>>>>>>>
>>>>>>>>> static void pci_enable_bridge(struct pci_dev *dev)
>>>>>>>>> {
>>>>>>>>> [...]
>>>>>>>>> if (pci_is_enabled(dev)) {
>>>>>>>>> if (!dev->is_busmaster)
>>>>>>>>> pci_set_master(dev);
>>>>>>>>> return;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> so I guess due to the new check we end up with mastering disabled, and
>>>>>>>>> thus the firmware can't load since that's a DMA thing?
>>>>>>>>
>>>>>>>> Bjorn/Srinath, any input here? This is a regression that prevents wifi
>>>>>>>> from working on a pretty standard laptop. It'd suck to have this be in
>>>>>>>> -rc1. Seems like the trivial fix would be:
>>>>>>>>
>>>>>>>>
>>>>>>>> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
>>>>>>>> index b0002daa50f3..ffbe11dbdd61 100644
>>>>>>>> --- a/drivers/pci/pci.c
>>>>>>>> +++ b/drivers/pci/pci.c
>>>>>>>> @@ -1394,7 +1394,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
>>>>>>>> return 0; /* already enabled */
>>>>>>>>
>>>>>>>> bridge = pci_upstream_bridge(dev);
>>>>>>>> - if (bridge && !pci_is_enabled(bridge))
>>>>>>>> + if (bridge)
>>>>> With this change and keeping "mutex_lock(&pci_bridge_mutex);" in
>>>>> pci_enable_bridge functoin will causes a nexted lock.
>>>>
>>>> Took a look, and looks like you are right. That code looks like a mess,
>>>> fwiw.
>>>>
>>>> I'd strongly suggest that the bad commit is reverted until a proper
>>>> solution is found, since the simple one-liner could potentially
>>>> introduce a deadlock with your patch applied.
>>>
>>> BTW, your patch looks pretty bad too, introducing a random mutex
>>> deep on code that can be recursive. Why isn't this check in
>>> pci_enable_device_flags() enough to prevent double-enable of
>>> an upstream bridge?
>>>
>>> if (atomic_inc_return(&dev->enable_cnt) > 1)
>>> return 0; /* already enabled */
>>>
>> This check only to verify device enable not for the bus master check.
>> But device enable function calls the bridge enable if it has the bridge.
>> Bridge enable function enables both device and bus master.
>>
>> Here the issue might be because, bridge of endpoint has already set
>> device enable without set bus master in some other context. which is
>> wrong.
>> because all bridges should enable with bridge_enable function only.
>> So we see the problem In this context, because "if (bridge &&
>> !pci_is_enabled(bridge))" check stops bridge enable which intern stops
>> bus master.
>> pci_enable_bridge function always makes sure that both device and bus
>> master are enabled in any case. If pci_enable_bridge function is not
>> called means, that bridge is already has device enable flag set. which
>> is not from pci_enable_bridge function.
>
> In any case, your patch introduces a regression on systems. Please get
> it reverted now, and then you can come up with a new approach to fix the
> double enable of the upstream bridge.
Who's sending in the revert? I can certainly do it if no one else does,
but it needs to be done.
I'm not seeing any patches coming out of Srinath to fix up the
situation, so we should revert the broken patch until a better solution
exists.
--
Jens Axboe
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Luca Coelho @ 2017-09-15 19:36 UTC (permalink / raw)
To: Jens Axboe, Srinath Mannam
Cc: Bjorn Helgaas, Johannes Berg, Grumbach, Emmanuel, linuxwifi,
linux-wireless@vger.kernel.org, linux-pci@vger.kernel.org,
Linus Torvalds
In-Reply-To: <ee04c95d-167b-0782-1860-253a2271d66c@kernel.dk>
On Fri, 2017-09-15 at 13:32 -0600, Jens Axboe wrote:
> On 09/14/2017 02:36 PM, Jens Axboe wrote:
> > On 09/14/2017 02:04 PM, Srinath Mannam wrote:
> > > Hi Jens Axboe,
> > >
> > >
> > > On Thu, Sep 14, 2017 at 11:14 PM, Jens Axboe <axboe@kernel.dk> wrote:
> > > > On 09/14/2017 11:35 AM, Jens Axboe wrote:
> > > > > On 09/14/2017 11:28 AM, Srinath Mannam wrote:
> > > > > > Hi Bjorn,
> > > > > >
> > > > > > On Thu, Sep 14, 2017 at 10:52 PM, Jens Axboe <axboe@kernel.dk> wrote:
> > > > > > >
> > > > > > > On 09/14/2017 11:11 AM, Bjorn Helgaas wrote:
> > > > > > > > [+cc linux-pci]
> > > > > > > >
> > > > > > > > On Thu, Sep 14, 2017 at 12:00 PM, Jens Axboe <axboe@kernel.dk> wrote:
> > > > > > > > > On 09/12/2017 02:04 PM, Johannes Berg wrote:
> > > > > > > > > > On Tue, 2017-09-12 at 13:43 -0600, Jens Axboe wrote:
> > > > > > > > > >
> > > > > > > > > > > CC'ing the guilty part and Bjorn. I'm assuming it's the
> > > > > > > > > > > pci_is_enabled() check, since the rest of the patch shouldn't have
> > > > > > > > > > > functional changes.
> > > > > > > > > >
> > > > > > > > > > and pci_enable_bridge() already checks if it's already enabled, but
> > > > > > > > > > still enables mastering in that case if it isn't:
> > > > > > > > > >
> > > > > > > > > > static void pci_enable_bridge(struct pci_dev *dev)
> > > > > > > > > > {
> > > > > > > > > > [...]
> > > > > > > > > > if (pci_is_enabled(dev)) {
> > > > > > > > > > if (!dev->is_busmaster)
> > > > > > > > > > pci_set_master(dev);
> > > > > > > > > > return;
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > so I guess due to the new check we end up with mastering disabled, and
> > > > > > > > > > thus the firmware can't load since that's a DMA thing?
> > > > > > > > >
> > > > > > > > > Bjorn/Srinath, any input here? This is a regression that prevents wifi
> > > > > > > > > from working on a pretty standard laptop. It'd suck to have this be in
> > > > > > > > > -rc1. Seems like the trivial fix would be:
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > > > > > > > > index b0002daa50f3..ffbe11dbdd61 100644
> > > > > > > > > --- a/drivers/pci/pci.c
> > > > > > > > > +++ b/drivers/pci/pci.c
> > > > > > > > > @@ -1394,7 +1394,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
> > > > > > > > > return 0; /* already enabled */
> > > > > > > > >
> > > > > > > > > bridge = pci_upstream_bridge(dev);
> > > > > > > > > - if (bridge && !pci_is_enabled(bridge))
> > > > > > > > > + if (bridge)
> > > > > >
> > > > > > With this change and keeping "mutex_lock(&pci_bridge_mutex);" in
> > > > > > pci_enable_bridge functoin will causes a nexted lock.
> > > > >
> > > > > Took a look, and looks like you are right. That code looks like a mess,
> > > > > fwiw.
> > > > >
> > > > > I'd strongly suggest that the bad commit is reverted until a proper
> > > > > solution is found, since the simple one-liner could potentially
> > > > > introduce a deadlock with your patch applied.
> > > >
> > > > BTW, your patch looks pretty bad too, introducing a random mutex
> > > > deep on code that can be recursive. Why isn't this check in
> > > > pci_enable_device_flags() enough to prevent double-enable of
> > > > an upstream bridge?
> > > >
> > > > if (atomic_inc_return(&dev->enable_cnt) > 1)
> > > > return 0; /* already enabled */
> > > >
> > >
> > > This check only to verify device enable not for the bus master check.
> > > But device enable function calls the bridge enable if it has the bridge.
> > > Bridge enable function enables both device and bus master.
> > >
> > > Here the issue might be because, bridge of endpoint has already set
> > > device enable without set bus master in some other context. which is
> > > wrong.
> > > because all bridges should enable with bridge_enable function only.
> > > So we see the problem In this context, because "if (bridge &&
> > > !pci_is_enabled(bridge))" check stops bridge enable which intern stops
> > > bus master.
> > > pci_enable_bridge function always makes sure that both device and bus
> > > master are enabled in any case. If pci_enable_bridge function is not
> > > called means, that bridge is already has device enable flag set. which
> > > is not from pci_enable_bridge function.
> >
> > In any case, your patch introduces a regression on systems. Please get
> > it reverted now, and then you can come up with a new approach to fix the
> > double enable of the upstream bridge.
>
> Who's sending in the revert? I can certainly do it if no one else does,
> but it needs to be done.
>
> I'm not seeing any patches coming out of Srinath to fix up the
> situation, so we should revert the broken patch until a better solution
> exists.
Bjorn already sent it:
https://lkml.org/lkml/2017/9/15/46
--
Cheers,
Luca.
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Linus Torvalds @ 2017-09-15 19:38 UTC (permalink / raw)
To: Jens Axboe
Cc: Srinath Mannam, Bjorn Helgaas, Johannes Berg, Luca Coelho,
Grumbach, Emmanuel, linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <ee04c95d-167b-0782-1860-253a2271d66c@kernel.dk>
On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
>>
>> In any case, your patch introduces a regression on systems. Please get
>> it reverted now, and then you can come up with a new approach to fix the
>> double enable of the upstream bridge.
>
> Who's sending in the revert? I can certainly do it if no one else does,
> but it needs to be done.
>
> I'm not seeing any patches coming out of Srinath to fix up the
> situation, so we should revert the broken patch until a better solution
> exists.
Hmm. I don't have the history here (apparently it never made lkml, for
example), so I don't even know which commit you're talking about.
>From some of the context it looks like commit 40f11adc7cd9 ("PCI:
Avoid race while enabling upstream bridges"), is that correct?
Linus
^ permalink raw reply
* Re: iwlwifi firmware load broken in current -git
From: Luca Coelho @ 2017-09-15 19:43 UTC (permalink / raw)
To: Linus Torvalds, Jens Axboe
Cc: Srinath Mannam, Bjorn Helgaas, Johannes Berg, Grumbach, Emmanuel,
linuxwifi, linux-wireless@vger.kernel.org,
linux-pci@vger.kernel.org
In-Reply-To: <CA+55aFzjz2c=q4Uatso1Lp6HAUOAyGdbZLWorFW56MiapoF5Sg@mail.gmail.com>
On Fri, 2017-09-15 at 12:38 -0700, Linus Torvalds wrote:
> On Fri, Sep 15, 2017 at 12:32 PM, Jens Axboe <axboe@kernel.dk> wrote:
> > >
> > > In any case, your patch introduces a regression on systems. Please get
> > > it reverted now, and then you can come up with a new approach to fix the
> > > double enable of the upstream bridge.
> >
> > Who's sending in the revert? I can certainly do it if no one else does,
> > but it needs to be done.
> >
> > I'm not seeing any patches coming out of Srinath to fix up the
> > situation, so we should revert the broken patch until a better solution
> > exists.
>
> Hmm. I don't have the history here (apparently it never made lkml, for
> example), so I don't even know which commit you're talking about.
>
> From some of the context it looks like commit 40f11adc7cd9 ("PCI:
> Avoid race while enabling upstream bridges"), is that correct?
Yes, that's the one. And Bjorn already sent a revert:
https://lkml.org/lkml/2017/9/15/46
--
Luca.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox