2021-12-04 06:36:05

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 00/12] iwlwifi: updates intended for v5.16 2021-12-04 part 1

From: Luca Coelho <[email protected]>

Hi,

Here's the first set of patches intended for v5.17. It's the usual
development, new features, cleanups and bugfixes.

The changes are:

* Some improvements in D3;
* Support for new FW API commands;
* Fixes and cleanups in device configurations;
* Some other small fixes, clean-ups and improvements.

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

Please review.

Cheers,
Luca.


Haim Dreyfuss (1):
iwlwifi: pcie: support Bz suspend/resume trigger

Johannes Berg (8):
iwlwifi: mvm: fix delBA vs. NSSN queue sync race
iwlwifi: mvm: synchronize with FW after multicast commands
iwlwifi: mvm: d3: move GTK rekeys condition
iwlwifi: mvm: parse firmware alive message version 6
iwlwifi: mvm: d3: support v12 wowlan status
iwlwifi: mvm: support RLC configuration command
iwlwifi: fw: api: add link to PHY context command struct v1
iwlwifi: mvm: add support for PHY context command v4

Luca Coelho (1):
iwlwifi: remove unused iwlax210_2ax_cfg_so_hr_a0 structure

Mike Golant (2):
iwlwifi: properly support 4-bit MAC step
iwlwifi: add support for Bz-Z HW

.../net/wireless/intel/iwlwifi/cfg/22000.c | 17 +-
drivers/net/wireless/intel/iwlwifi/dvm/main.c | 8 +-
.../net/wireless/intel/iwlwifi/fw/api/alive.h | 17 +-
.../wireless/intel/iwlwifi/fw/api/commands.h | 5 +-
.../net/wireless/intel/iwlwifi/fw/api/d3.h | 81 +++++++-
.../wireless/intel/iwlwifi/fw/api/datapath.h | 62 ++++++
.../wireless/intel/iwlwifi/fw/api/phy-ctxt.h | 9 +-
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 +-
.../net/wireless/intel/iwlwifi/iwl-config.h | 2 +-
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 19 +-
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 4 +-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 2 +-
drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 7 +
.../net/wireless/intel/iwlwifi/iwl-trans.h | 2 +
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 184 +++++++++++++++---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 6 +-
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 17 ++
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 +-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 11 +-
.../net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 62 +++++-
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 5 +-
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 10 +
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 24 +--
.../net/wireless/intel/iwlwifi/pcie/trans.c | 80 ++++----
24 files changed, 514 insertions(+), 131 deletions(-)

--
2.33.1



2021-12-04 06:36:07

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 01/12] iwlwifi: mvm: fix delBA vs. NSSN queue sync race

From: Johannes Berg <[email protected]>

If we happen to decide an NSSN queue sync (IWL_MVM_RXQ_NSSN_SYNC)
for some remaining packets that are still on the queue, but just
after we've decided to do a delBA (which causes its own queues
sync with IWL_MVM_RXQ_NOTIF_DEL_BA) we can end up with a sequence
of events like this:

CPU 1 CPU 2

remove BA session with baid N
send IWL_MVM_RXQ_NOTIF_DEL_BA
send IWL_MVM_RXQ_NSSN_SYNC
get IWL_MVM_RXQ_NOTIF_DEL_BA
get IWL_MVM_RXQ_NOTIF_DEL_BA
get IWL_MVM_RXQ_NSSN_SYNC
complete IWL_MVM_RXQ_NOTIF_DEL_BA
remove N from baid_map[]
get IWL_MVM_RXQ_NSSN_SYNC
WARN_ON(!baid_map[N])

Thus, there's a race that leads in hitting the WARN_ON, but more
importantly, it's a race that potentially even results in a new
aggregation session getting assigned to baid N.

To fix this, remove the WARN_ON() in the NSSN_SYNC case, we can't
completely protect against hitting this case, so we shouldn't be
warning. However, guard ourselves against BAID reuse by doing yet
another round of queue synchronization after the entry is removed
from the baid_map, so that it cannot be reused with any in-flight
IWL_MVM_RXQ_NSSN_SYNC messages.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 5 ++++-
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 10 ++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index e0601f802628..03e90087576c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -766,8 +766,11 @@ static void iwl_mvm_release_frames_from_notif(struct iwl_mvm *mvm,
rcu_read_lock();

ba_data = rcu_dereference(mvm->baid_map[baid]);
- if (WARN_ON_ONCE(!ba_data))
+ if (!ba_data) {
+ WARN(!(flags & IWL_MVM_RELEASE_FROM_RSS_SYNC),
+ "BAID %d not found in map\n", baid);
goto out;
+ }

sta = rcu_dereference(mvm->fw_id_to_mac_id[ba_data->sta_id]);
if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index a64874c05ced..feab0bfcd7a2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -2684,6 +2684,16 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
RCU_INIT_POINTER(mvm->baid_map[baid], NULL);
kfree_rcu(baid_data, rcu_head);
IWL_DEBUG_HT(mvm, "BAID %d is free\n", baid);
+
+ /*
+ * After we've deleted it, do another queue sync
+ * so if an IWL_MVM_RXQ_NSSN_SYNC was concurrently
+ * running it won't find a new session in the old
+ * BAID. It can find the NULL pointer for the BAID,
+ * but we must not have it find a different session.
+ */
+ iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_EMPTY,
+ true, NULL, 0);
}
return 0;

--
2.33.1


2021-12-04 06:36:07

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 02/12] iwlwifi: mvm: synchronize with FW after multicast commands

From: Johannes Berg <[email protected]>

If userspace installs a lot of multicast groups very quickly, then
we may run out of command queue space as we send the updates in an
asynchronous fashion (due to locking concerns), and the CPU can
create them faster than the firmware can process them. This is true
even when mac80211 has a work struct that gets scheduled.

Fix this by synchronizing with the firmware after sending all those
commands - outside of the iteration we can send a synchronous echo
command that just has the effect of the CPU waiting for the prior
asynchronous commands to finish. This also will cause fewer of the
commands to be sent to the firmware overall, because the work will
only run once when rescheduled multiple times while it's running.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=213649
Suggested-by: Emmanuel Grumbach <[email protected]>
Reported-by: Maximilian Ernestus <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 20422e640059..9d84be991469 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1710,6 +1710,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
struct iwl_mvm_mc_iter_data iter_data = {
.mvm = mvm,
};
+ int ret;

lockdep_assert_held(&mvm->mutex);

@@ -1719,6 +1720,22 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_mc_iface_iterator, &iter_data);
+
+ /*
+ * Send a (synchronous) ech command so that we wait for the
+ * multiple asynchronous MCAST_FILTER_CMD commands sent by
+ * the interface iterator. Otherwise, we might get here over
+ * and over again (by userspace just sending a lot of these)
+ * and the CPU can send them faster than the firmware can
+ * process them.
+ * Note that the CPU is still faster - but with this we'll
+ * actually send fewer commands overall because the CPU will
+ * not schedule the work in mac80211 as frequently if it's
+ * still running when rescheduled (possibly multiple times).
+ */
+ ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
+ if (ret)
+ IWL_ERR(mvm, "Failed to synchronize multicast groups update\n");
}

static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
--
2.33.1


2021-12-04 06:36:09

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 04/12] iwlwifi: add support for Bz-Z HW

From: Mike Golant <[email protected]>

Add support for Bz Z step HW with GF RF.

Signed-off-by: Mike Golant <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 10 ++++++++++
drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 +
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 +
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 7 +++++++
4 files changed, 19 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 1572097bccf1..7a06bbae178b 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -55,6 +55,7 @@
#define IWL_BZ_A_MR_A_FW_PRE "iwlwifi-bz-a0-mr-a0-"
#define IWL_BZ_A_FM_A_FW_PRE "iwlwifi-bz-a0-fm-a0-"
#define IWL_GL_A_FM_A_FW_PRE "iwlwifi-gl-a0-fm7-a0-"
+#define IWL_BZ_Z_GF_A_FW_PRE "iwlwifi-bz-z0-gf-a0-"


#define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \
@@ -113,6 +114,8 @@
IWL_BZ_A_FM_A_FW_PRE __stringify(api) ".ucode"
#define IWL_GL_A_FM_A_MODULE_FIRMWARE(api) \
IWL_GL_A_FM_A_FW_PRE __stringify(api) ".ucode"
+#define IWL_BZ_Z_GF_A_MODULE_FIRMWARE(api) \
+ IWL_BZ_Z_GF_A_FW_PRE __stringify(api) ".ucode"

static const struct iwl_base_params iwl_22000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
@@ -879,6 +882,13 @@ const struct iwl_cfg iwl_cfg_gl_a0_fm_a0 = {
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};

+const struct iwl_cfg iwl_cfg_bz_z0_gf_a0 = {
+ .fw_name_pre = IWL_BZ_Z_GF_A_FW_PRE,
+ .uhb_supported = true,
+ IWL_DEVICE_BZ,
+ .num_rbds = IWL_NUM_RBDS_AX210_HE,
+};
+
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 665167a223f6..d704e278b577 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -634,6 +634,7 @@ extern const struct iwl_cfg iwl_cfg_bz_a0_gf4_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_mr_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_fm_a0;
extern const struct iwl_cfg iwl_cfg_gl_a0_fm_a0;
+extern const struct iwl_cfg iwl_cfg_bz_z0_gf_a0;
#endif /* CONFIG_IWLMVM */

#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index cfea20e507b3..046a01f5988b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -304,6 +304,7 @@ enum {
SILICON_A_STEP = 0,
SILICON_B_STEP,
SILICON_C_STEP,
+ SILICON_Z_STEP = 0xf,
};


diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index db8b62e432eb..93d789670f89 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1130,6 +1130,13 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
iwl_cfg_gl_a0_fm_a0, iwl_bz_name),

+/* BZ Z step */
+ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
+ IWL_CFG_MAC_TYPE_BZ, SILICON_Z_STEP,
+ IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY,
+ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB,
+ iwl_cfg_bz_z0_gf_a0, iwl_bz_name),
+
/* SoF with JF2 */
_IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY,
IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY,
--
2.33.1


2021-12-04 06:36:09

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 03/12] iwlwifi: properly support 4-bit MAC step

From: Mike Golant <[email protected]>

Properly support 4-bit MAC step by refactoring all the current
handling of the MAC step/dash.

Already from family 8000 and up the dash (bits 0-1) no longer exist
and the step (until 8000 bits 2-3) consists of also the dash bits.

To do this remove the CSR_HW_REV_STEP and the CSR_HW_REV_DASH
macros, replace them with CSR_HW_REV_STEP_DASH and add hw_rev_step
into the trans struct.

In addition remove the CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP and
CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH macros and create a new macro
combining the 2 (this way we don't need shifting or anything else.)

Signed-off-by: Matti Gottlieb <[email protected]>
Signed-off-by: Mike Golant <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/dvm/main.c | 8 ++------
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++--
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 14 ++++++--------
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 4 ++--
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 2 +-
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 2 ++
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 10 +++-------
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 +-
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 5 +++--
9 files changed, 22 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index fbd57a2b2bd5..90b9becd1673 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1974,12 +1974,8 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)

/* SKU Control */
iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
- CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP,
- (CSR_HW_REV_STEP(priv->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) |
- (CSR_HW_REV_DASH(priv->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_DASH));
+ CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH,
+ CSR_HW_REV_STEP_DASH(priv->trans->hw_rev));

/* write radio config values to register */
if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index a39013c401c9..c8a08bdfefa4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -880,7 +880,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
dump_info->hw_type =
cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->hw_rev));
dump_info->hw_step =
- cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev));
+ cpu_to_le32(fwrt->trans->hw_rev_step);
memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable,
sizeof(dump_info->fw_human_readable));
strncpy(dump_info->dev_human_readable, fwrt->trans->name,
@@ -2099,7 +2099,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);
dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype);

- dump->hw_step = cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev));
+ dump->hw_step = cpu_to_le32(fwrt->trans->hw_rev_step);

/*
* Several HWs all have type == 0x42, so we'll override this value
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index ff79a2ecb242..cfea20e507b3 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -143,8 +143,7 @@
#define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101)

/* Bits for CSR_HW_IF_CONFIG_REG */
-#define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003)
-#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C)
+#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH (0x0000000F)
#define CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM (0x00000080)
#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0)
#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
@@ -287,8 +286,7 @@
#define CSR_GP_CNTRL_REG_FLAG_SW_RESET BIT(31)

/* HW REV */
-#define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0)
-#define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2)
+#define CSR_HW_REV_STEP_DASH(_val) ((_val) & CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH)
#define CSR_HW_REV_TYPE(_val) (((_val) & 0x000FFF0) >> 4)

/* HW RFID */
@@ -328,10 +326,10 @@ enum {
#define CSR_HW_REV_TYPE_7265D (0x0000210)
#define CSR_HW_REV_TYPE_NONE (0x00001F0)
#define CSR_HW_REV_TYPE_QNJ (0x0000360)
-#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
-#define CSR_HW_REV_TYPE_QU_B0 (0x0000334)
-#define CSR_HW_REV_TYPE_QU_C0 (0x0000338)
-#define CSR_HW_REV_TYPE_QUZ (0x0000354)
+#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000361)
+#define CSR_HW_REV_TYPE_QU_B0 (0x0000331)
+#define CSR_HW_REV_TYPE_QU_C0 (0x0000332)
+#define CSR_HW_REV_TYPE_QUZ (0x0000351)
#define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
#define CSR_HW_REV_TYPE_SO (0x0000370)
#define CSR_HW_REV_TYPE_TY (0x0000420)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 36196e07b1a0..026116629040 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -163,8 +163,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
char tag[8];

if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
- (CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_B_STEP &&
- CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_C_STEP)) {
+ (drv->trans->hw_rev_step != SILICON_B_STEP &&
+ drv->trans->hw_rev_step != SILICON_C_STEP)) {
IWL_ERR(drv,
"Only HW steps B and C are currently supported (0x%0x)\n",
drv->trans->hw_rev);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 0cd4718372f5..9ef89ff09105 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -1609,7 +1609,7 @@ int iwl_read_external_nvm(struct iwl_trans *trans,

/* nvm file validation, dword_buff[2] holds the file version */
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
- CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP &&
+ trans->hw_rev_step == SILICON_C_STEP &&
le32_to_cpu(dword_buff[2]) < 0xE4A) {
ret = -EFAULT;
goto out;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index a4060af50201..947ed82b7f19 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -938,6 +938,7 @@ struct iwl_trans_txqs {
* @hw_id: a u32 with the ID of the device / sub-device.
* Set during transport allocation.
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
+ * @hw_rev_step: The mac step of the HW
* @pm_support: set to true in start_hw if link pm is supported
* @ltr_enabled: set to true if the LTR is enabled
* @wide_cmd_header: true when ucode supports wide command header format
@@ -971,6 +972,7 @@ struct iwl_trans {
struct device *dev;
u32 max_skb_frags;
u32 hw_rev;
+ u32 hw_rev_step;
u32 hw_rf_id;
u32 hw_id;
char hw_id_str[52];
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 3ab0217abeea..cd04f24dd7fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -78,7 +78,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
- u32 reg_val = 0;
+ u32 reg_val;
u32 phy_config = iwl_mvm_get_phy_config(mvm);

radio_cfg_type = (phy_config & FW_PHY_CFG_RADIO_TYPE) >>
@@ -89,10 +89,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
FW_PHY_CFG_RADIO_DASH_POS;

/* SKU control */
- reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
- reg_val |= CSR_HW_REV_DASH(mvm->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
+ reg_val = CSR_HW_REV_STEP_DASH(mvm->trans->hw_rev);

/* radio configuration */
reg_val |= radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
@@ -117,8 +114,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
reg_val |= CSR_HW_IF_CONFIG_REG_D3_DEBUG;

iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
- CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP |
+ CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH |
CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 5c56da36fc84..db8b62e432eb 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1450,7 +1450,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device,
CSR_HW_REV_TYPE(iwl_trans->hw_rev),
- CSR_HW_REV_STEP(iwl_trans->hw_rev),
+ iwl_trans->hw_rev_step,
CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id),
CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id),
IWL_SUBDEVICE_RF_ID(pdev->subsystem_device),
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 451b28de1392..f607edd41baa 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3616,8 +3616,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
* in the old format.
*/
if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_8000)
- trans->hw_rev = (trans->hw_rev & 0xfff0) |
- (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2);
+ trans->hw_rev_step = trans->hw_rev & 0xF;
+ else
+ trans->hw_rev_step = (trans->hw_rev & 0xC) >> 2;

IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev);

--
2.33.1


2021-12-04 06:36:11

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 05/12] iwlwifi: mvm: d3: move GTK rekeys condition

From: Johannes Berg <[email protected]>

Move the GTK rekeying condition into iwl_mvm_set_key_rx_seq()
so we can modify it in the next patch. In the next firmware
API revision we'll properly get data for both active GTKs and
will have to install it accordingly.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index a19f646a324f..f9b485fcfcdb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1651,8 +1651,12 @@ static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,

static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm,
struct ieee80211_key_conf *key,
- struct iwl_wowlan_status_data *status)
+ struct iwl_wowlan_status_data *status,
+ bool installed)
{
+ if (status->num_of_gtk_rekeys && !installed)
+ return;
+
switch (key->cipher) {
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
@@ -1740,8 +1744,9 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,

if (data->status->num_of_gtk_rekeys)
ieee80211_remove_key(key);
- else if (data->last_gtk == key)
- iwl_mvm_set_key_rx_seq(data->mvm, key, data->status);
+
+ if (data->last_gtk == key)
+ iwl_mvm_set_key_rx_seq(data->mvm, key, data->status, false);
}

static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
@@ -1825,7 +1830,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
key = ieee80211_gtk_rekey_add(vif, &conf.conf);
if (IS_ERR(key))
return false;
- iwl_mvm_set_key_rx_seq(mvm, key, status);
+ iwl_mvm_set_key_rx_seq(mvm, key, status, true);

replay_ctr = cpu_to_be64(status->replay_ctr);

--
2.33.1


2021-12-04 06:36:11

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 06/12] iwlwifi: pcie: support Bz suspend/resume trigger

From: Haim Dreyfuss <[email protected]>

Instead of using two bits in the doorbell interrupt, the new Bz
devices have a new CSR_IPC_SLEEP_CONTROL register to let drivers
indicate the desired transition before triggering the doorbell
interrupt.

Signed-off-by: Haim Dreyfuss <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 4 +
drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 7 ++
.../net/wireless/intel/iwlwifi/pcie/trans.c | 75 ++++++++++---------
3 files changed, 52 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index 046a01f5988b..21d8249980fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -105,6 +105,10 @@
/* GIO Chicken Bits (PCI Express bus link power management) */
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)

+#define CSR_IPC_SLEEP_CONTROL (CSR_BASE + 0x114)
+#define CSR_IPC_SLEEP_CONTROL_SUSPEND 0x3
+#define CSR_IPC_SLEEP_CONTROL_RESUME 0
+
/* Doorbell NMI (since Bz) */
#define CSR_DOORBELL_VECTOR (CSR_BASE + 0x130)
#define CSR_DOORBELL_VECTOR_NMI BIT(1)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index a84ab02cf9d7..2ca22e1b8bd9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -455,6 +455,13 @@ enum {
#define UREG_DOORBELL_TO_ISR6_RESUME BIT(19)
#define UREG_DOORBELL_TO_ISR6_PNVM BIT(20)

+/*
+ * From BZ family driver triggers this bit for suspend and resume
+ * The driver should update CSR_IPC_SLEEP_CONTROL before triggering
+ * this interrupt with suspend/resume value
+ */
+#define UREG_DOORBELL_TO_ISR6_SLEEP_CTRL BIT(31)
+
#define CNVI_MBOX_C 0xA3400C

#define FSEQ_ERROR_CODE 0xA340C8
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f607edd41baa..0aeab8acc247 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1499,33 +1499,54 @@ void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans,
iwl_pcie_set_pwr(trans, true);
}

+static int iwl_pcie_d3_handshake(struct iwl_trans *trans, bool suspend)
+{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ int ret;
+
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
+ iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
+ suspend ? UREG_DOORBELL_TO_ISR6_SUSPEND :
+ UREG_DOORBELL_TO_ISR6_RESUME);
+ } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+ iwl_write32(trans, CSR_IPC_SLEEP_CONTROL,
+ suspend ? CSR_IPC_SLEEP_CONTROL_SUSPEND :
+ CSR_IPC_SLEEP_CONTROL_RESUME);
+ iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
+ UREG_DOORBELL_TO_ISR6_SLEEP_CTRL);
+ } else {
+ return 0;
+ }
+
+ ret = wait_event_timeout(trans_pcie->sx_waitq,
+ trans_pcie->sx_complete, 2 * HZ);
+
+ /* Invalidate it toward next suspend or resume */
+ trans_pcie->sx_complete = false;
+
+ if (!ret) {
+ IWL_ERR(trans, "Timeout %s D3\n",
+ suspend ? "entering" : "exiting");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static int iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
bool reset)
{
int ret;
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

if (!reset)
/* Enable persistence mode to avoid reset */
iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_PERSIST_MODE);

- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
- iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
- UREG_DOORBELL_TO_ISR6_SUSPEND);
-
- ret = wait_event_timeout(trans_pcie->sx_waitq,
- trans_pcie->sx_complete, 2 * HZ);
- /*
- * Invalidate it toward resume.
- */
- trans_pcie->sx_complete = false;
+ ret = iwl_pcie_d3_handshake(trans, true);
+ if (ret)
+ return ret;

- if (!ret) {
- IWL_ERR(trans, "Timeout entering D3\n");
- return -ETIMEDOUT;
- }
- }
iwl_pcie_d3_complete_suspend(trans, test, reset);

return 0;
@@ -1542,6 +1563,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
if (test) {
iwl_enable_interrupts(trans);
*status = IWL_D3_STATUS_ALIVE;
+ ret = 0;
goto out;
}

@@ -1590,25 +1612,10 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
*status = IWL_D3_STATUS_ALIVE;

out:
- if (*status == IWL_D3_STATUS_ALIVE &&
- trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
- trans_pcie->sx_complete = false;
- iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
- UREG_DOORBELL_TO_ISR6_RESUME);
+ if (*status == IWL_D3_STATUS_ALIVE)
+ ret = iwl_pcie_d3_handshake(trans, false);

- ret = wait_event_timeout(trans_pcie->sx_waitq,
- trans_pcie->sx_complete, 2 * HZ);
- /*
- * Invalidate it toward next suspend.
- */
- trans_pcie->sx_complete = false;
-
- if (!ret) {
- IWL_ERR(trans, "Timeout exiting D3\n");
- return -ETIMEDOUT;
- }
- }
- return 0;
+ return ret;
}

static void
--
2.33.1


2021-12-04 06:36:16

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 07/12] iwlwifi: mvm: parse firmware alive message version 6

From: Johannes Berg <[email protected]>

There's a new version with some addition, we'll need to
do something with the additional data later, but for now
just parse it so we don't fail with the newer firmware.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/fw/api/alive.h | 17 ++++++++++++++++-
.../wireless/intel/iwlwifi/fw/api/commands.h | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 6 ++++--
3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
index c840a97e6a62..7dd984fbe0f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2018, 2020 Intel Corporation
+ * Copyright (C) 2012-2014, 2018, 2020-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -97,6 +97,21 @@ struct iwl_alive_ntf_v5 {
struct iwl_sku_id sku_id;
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_5 */

+struct iwl_imr_alive_info {
+ __le64 base_addr;
+ __le32 size;
+ __le32 enabled;
+} __packed; /* IMR_ALIVE_INFO_API_S_VER_1 */
+
+struct iwl_alive_ntf_v6 {
+ __le16 status;
+ __le16 flags;
+ struct iwl_lmac_alive lmac_data[2];
+ struct iwl_umac_alive umac_data;
+ struct iwl_sku_id sku_id;
+ struct iwl_imr_alive_info imr;
+} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_6 */
+
/**
* enum iwl_extended_cfg_flag - commands driver may send before
* finishing init flow
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index ee6b5844a871..8a90acbd0db9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -51,7 +51,7 @@ enum iwl_legacy_cmds {
* @UCODE_ALIVE_NTFY:
* Alive data from the firmware, as described in
* &struct iwl_alive_ntf_v3 or &struct iwl_alive_ntf_v4 or
- * &struct iwl_alive_ntf_v5.
+ * &struct iwl_alive_ntf_v5 or &struct iwl_alive_ntf_v6.
*/
UCODE_ALIVE_NTFY = 0x1,

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 6ce78c03e51f..7608b1e486c4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -123,13 +123,15 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
struct iwl_lmac_alive *lmac2 = NULL;
u16 status;
u32 lmac_error_event_table, umac_error_table;
+ u32 version = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
+ UCODE_ALIVE_NTFY, 0);

/*
* For v5 and above, we can check the version, for older
* versions we need to check the size.
*/
- if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
- UCODE_ALIVE_NTFY, 0) == 5) {
+ if (version == 5 || version == 6) {
+ /* v5 and v6 are compatible (only IMR addition) */
struct iwl_alive_ntf_v5 *palive;

if (pkt_len < sizeof(*palive))
--
2.33.1


2021-12-04 06:36:17

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 08/12] iwlwifi: mvm: d3: support v12 wowlan status

From: Johannes Berg <[email protected]>

Newer firmware versions are going to come with a new version
of the wowlan status API, which gives us replay counters for
both GTKs that might still be in use, as well as unifying the
layout of the counters to just be 64-bit quantities.

Extend our code to handle this case and be able to install
replay counters for both keys, if they're sent up from the
firmware.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/fw/api/d3.h | 81 +++++++-
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 183 +++++++++++++++---
2 files changed, 235 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index 1503119ea910..4cd9ab23954e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -554,7 +554,7 @@ struct iwl_wowlan_gtk_status_v1 {
} __packed; /* WOWLAN_GTK_MATERIAL_VER_1 */

/**
- * struct iwl_wowlan_gtk_status - GTK status
+ * struct iwl_wowlan_gtk_status_v2 - GTK status
* @key: GTK material
* @key_len: GTK legth, if set to 0, the key is not available
* @key_flags: information about the key:
@@ -565,7 +565,7 @@ struct iwl_wowlan_gtk_status_v1 {
* @tkip_mic_key: TKIP RX MIC key
* @rsc: TSC RSC counters
*/
-struct iwl_wowlan_gtk_status {
+struct iwl_wowlan_gtk_status_v2 {
u8 key[WOWLAN_KEY_MAX_SIZE];
u8 key_len;
u8 key_flags;
@@ -574,6 +574,41 @@ struct iwl_wowlan_gtk_status {
struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 rsc;
} __packed; /* WOWLAN_GTK_MATERIAL_VER_2 */

+/**
+ * struct iwl_wowlan_all_rsc_tsc_v5 - key counters
+ * @ucast_rsc: unicast RSC values
+ * @mcast_rsc: multicast RSC values (per key map value)
+ * @sta_id: station ID
+ * @mcast_key_id_map: map of key id to @mcast_rsc entry
+ */
+struct iwl_wowlan_all_rsc_tsc_v5 {
+ __le64 ucast_rsc[IWL_MAX_TID_COUNT];
+ __le64 mcast_rsc[2][IWL_MAX_TID_COUNT];
+ __le32 sta_id;
+ u8 mcast_key_id_map[4];
+} __packed; /* ALL_TSC_RSC_API_S_VER_5 */
+
+/**
+ * struct iwl_wowlan_gtk_status_v3 - GTK status
+ * @key: GTK material
+ * @key_len: GTK length, if set to 0, the key is not available
+ * @key_flags: information about the key:
+ * bits[0:1]: key index assigned by the AP
+ * bits[2:6]: GTK index of the key in the internal DB
+ * bit[7]: Set iff this is the currently used GTK
+ * @reserved: padding
+ * @tkip_mic_key: TKIP RX MIC key
+ * @sc: RSC/TSC counters
+ */
+struct iwl_wowlan_gtk_status_v3 {
+ u8 key[WOWLAN_KEY_MAX_SIZE];
+ u8 key_len;
+ u8 key_flags;
+ u8 reserved[2];
+ u8 tkip_mic_key[IWL_MIC_KEY_SIZE];
+ struct iwl_wowlan_all_rsc_tsc_v5 sc;
+} __packed; /* WOWLAN_GTK_MATERIAL_VER_3 */
+
#define IWL_WOWLAN_GTK_IDX_MASK (BIT(0) | BIT(1))

/**
@@ -640,7 +675,7 @@ struct iwl_wowlan_status_v6 {
* @wake_packet: wakeup packet
*/
struct iwl_wowlan_status_v7 {
- struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM];
+ struct iwl_wowlan_gtk_status_v2 gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
@@ -676,7 +711,7 @@ struct iwl_wowlan_status_v7 {
* @wake_packet: wakeup packet
*/
struct iwl_wowlan_status_v9 {
- struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM];
+ struct iwl_wowlan_gtk_status_v2 gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
@@ -693,6 +728,44 @@ struct iwl_wowlan_status_v9 {
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_9 */

+/**
+ * struct iwl_wowlan_status_v12 - WoWLAN status
+ * @gtk: GTK data
+ * @igtk: IGTK data
+ * @replay_ctr: GTK rekey replay counter
+ * @pattern_number: number of the matched pattern
+ * @non_qos_seq_ctr: non-QoS sequence counter to use next.
+ * Reserved if the struct has version >= 10.
+ * @qos_seq_ctr: QoS sequence counters to use next
+ * @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
+ * @num_of_gtk_rekeys: number of GTK rekeys
+ * @transmitted_ndps: number of transmitted neighbor discovery packets
+ * @received_beacons: number of received beacons
+ * @wake_packet_length: wakeup packet length
+ * @wake_packet_bufsize: wakeup packet buffer size
+ * @tid_tear_down: bit mask of tids whose BA sessions were closed
+ * in suspend state
+ * @reserved: unused
+ * @wake_packet: wakeup packet
+ */
+struct iwl_wowlan_status_v12 {
+ struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
+ struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
+ __le64 replay_ctr;
+ __le16 pattern_number;
+ __le16 non_qos_seq_ctr;
+ __le16 qos_seq_ctr[8];
+ __le32 wakeup_reasons;
+ __le32 num_of_gtk_rekeys;
+ __le32 transmitted_ndps;
+ __le32 received_beacons;
+ __le32 wake_packet_length;
+ __le32 wake_packet_bufsize;
+ u8 tid_tear_down;
+ u8 reserved[3];
+ u8 wake_packet[]; /* can be truncated from _length to _bufsize */
+} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_12 */
+
/* TODO: NetDetect API */

#endif /* __iwl_fw_api_d3_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index f9b485fcfcdb..b400867e94f0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1390,6 +1390,13 @@ struct iwl_wowlan_status_data {
u16 qos_seq_ctr[8];
u8 tid_tear_down;

+ struct {
+ /* including RX MIC key for TKIP */
+ u8 key[WOWLAN_KEY_MAX_SIZE];
+ u8 len;
+ u8 flags;
+ } gtk;
+
struct {
/*
* We store both the TKIP and AES representations
@@ -1400,11 +1407,15 @@ struct iwl_wowlan_status_data {
struct {
struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
} tkip, aes;
- /* including RX MIC key for TKIP */
- u8 key[WOWLAN_KEY_MAX_SIZE];
- u8 len;
- u8 flags;
- } gtk;
+
+ /*
+ * We use -1 for when we have valid data but don't know
+ * the key ID from firmware, and thus it needs to be
+ * installed with the last key (depending on rekeying).
+ */
+ s8 key_id;
+ bool valid;
+ } gtk_seq[2];

struct {
/* Same as above */
@@ -1556,12 +1567,10 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
kfree_skb(pkt);
}

-static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
- struct ieee80211_key_seq *seq)
+static void iwl_mvm_le64_to_aes_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
{
- u64 pn;
+ u64 pn = le64_to_cpu(le_pn);

- pn = le64_to_cpu(sc->pn);
seq->ccmp.pn[0] = pn >> 40;
seq->ccmp.pn[1] = pn >> 32;
seq->ccmp.pn[2] = pn >> 24;
@@ -1570,6 +1579,20 @@ static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
seq->ccmp.pn[5] = pn;
}

+static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
+ struct ieee80211_key_seq *seq)
+{
+ iwl_mvm_le64_to_aes_seq(sc->pn, seq);
+}
+
+static void iwl_mvm_le64_to_tkip_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
+{
+ u64 pn = le64_to_cpu(le_pn);
+
+ seq->tkip.iv16 = (u16)pn;
+ seq->tkip.iv32 = (u32)(pn >> 16);
+}
+
static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
struct ieee80211_key_seq *seq)
{
@@ -1630,10 +1653,12 @@ static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
/* GTK RX counters */
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i],
- &status->gtk.tkip.seq[i]);
+ &status->gtk_seq[0].tkip.seq[i]);
iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i],
- &status->gtk.aes.seq[i]);
+ &status->gtk_seq[0].aes.seq[i]);
}
+ status->gtk_seq[0].valid = true;
+ status->gtk_seq[0].key_id = -1;

/* PTK TX counter */
status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
@@ -1649,28 +1674,103 @@ static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
}
}

-static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm,
- struct ieee80211_key_conf *key,
- struct iwl_wowlan_status_data *status,
- bool installed)
+static void
+iwl_mvm_convert_key_counters_v5_gtk_seq(struct iwl_wowlan_status_data *status,
+ struct iwl_wowlan_all_rsc_tsc_v5 *sc,
+ unsigned int idx, unsigned int key_id)
{
- if (status->num_of_gtk_rekeys && !installed)
- return;
+ int tid;
+
+ for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
+ iwl_mvm_le64_to_tkip_seq(sc->mcast_rsc[idx][tid],
+ &status->gtk_seq[idx].tkip.seq[tid]);
+ iwl_mvm_le64_to_aes_seq(sc->mcast_rsc[idx][tid],
+ &status->gtk_seq[idx].aes.seq[tid]);
+ }
+
+ status->gtk_seq[idx].valid = true;
+ status->gtk_seq[idx].key_id = key_id;
+}
+
+static void
+iwl_mvm_convert_key_counters_v5(struct iwl_wowlan_status_data *status,
+ struct iwl_wowlan_all_rsc_tsc_v5 *sc)
+{
+ int i, tid;

+ BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
+ BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
+ BUILD_BUG_ON(ARRAY_SIZE(sc->mcast_rsc) != ARRAY_SIZE(status->gtk_seq));
+
+ /* GTK RX counters */
+ for (i = 0; i < ARRAY_SIZE(sc->mcast_key_id_map); i++) {
+ u8 entry = sc->mcast_key_id_map[i];
+
+ if (entry < ARRAY_SIZE(sc->mcast_rsc))
+ iwl_mvm_convert_key_counters_v5_gtk_seq(status, sc,
+ entry, i);
+ }
+
+ /* PTK TX counters not needed, assigned in device */
+
+ /* PTK RX counters */
+ for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
+ iwl_mvm_le64_to_tkip_seq(sc->ucast_rsc[tid],
+ &status->ptk.tkip.seq[tid]);
+ iwl_mvm_le64_to_aes_seq(sc->ucast_rsc[tid],
+ &status->ptk.aes.seq[tid]);
+ }
+}
+
+static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf *key,
+ struct iwl_wowlan_status_data *status,
+ int idx)
+{
switch (key->cipher) {
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
- iwl_mvm_set_key_rx_seq_tids(key, status->gtk.aes.seq);
+ iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].aes.seq);
break;
case WLAN_CIPHER_SUITE_TKIP:
- iwl_mvm_set_key_rx_seq_tids(key, status->gtk.tkip.seq);
+ iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].tkip.seq);
break;
default:
WARN_ON(1);
}
}

+static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
+ struct iwl_wowlan_status_data *status,
+ bool installed)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(status->gtk_seq); i++) {
+ if (!status->gtk_seq[i].valid)
+ continue;
+
+ /* Handle the case where we know the key ID */
+ if (status->gtk_seq[i].key_id == key->keyidx) {
+ s8 new_key_id = -1;
+
+ if (status->num_of_gtk_rekeys)
+ new_key_id = status->gtk.flags &
+ IWL_WOWLAN_GTK_IDX_MASK;
+
+ /* Don't install a new key's value to an old key */
+ if (new_key_id != key->keyidx)
+ iwl_mvm_set_key_rx_seq_idx(key, status, i);
+ continue;
+ }
+
+ /* handle the case where we didn't, last key only */
+ if (status->gtk_seq[i].key_id == -1 &&
+ (!status->num_of_gtk_rekeys || installed))
+ iwl_mvm_set_key_rx_seq_idx(key, status, i);
+ }
+}
+
struct iwl_mvm_d3_gtk_iter_data {
struct iwl_mvm *mvm;
struct iwl_wowlan_status_data *status;
@@ -1746,7 +1846,7 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
ieee80211_remove_key(key);

if (data->last_gtk == key)
- iwl_mvm_set_key_rx_seq(data->mvm, key, data->status, false);
+ iwl_mvm_set_key_rx_seq(key, data->status, false);
}

static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
@@ -1830,7 +1930,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
key = ieee80211_gtk_rekey_add(vif, &conf.conf);
if (IS_ERR(key))
return false;
- iwl_mvm_set_key_rx_seq(mvm, key, status, true);
+ iwl_mvm_set_key_rx_seq(key, status, true);

replay_ctr = cpu_to_be64(status->replay_ctr);

@@ -1898,9 +1998,10 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
iwl_mvm_parse_wowlan_status_common(v6)
iwl_mvm_parse_wowlan_status_common(v7)
iwl_mvm_parse_wowlan_status_common(v9)
+iwl_mvm_parse_wowlan_status_common(v12)

-static void iwl_mvm_convert_gtk(struct iwl_wowlan_status_data *status,
- struct iwl_wowlan_gtk_status *data)
+static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status,
+ struct iwl_wowlan_gtk_status_v2 *data)
{
BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key));
BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
@@ -1918,6 +2019,26 @@ static void iwl_mvm_convert_gtk(struct iwl_wowlan_status_data *status,
data->tkip_mic_key, sizeof(data->tkip_mic_key));
}

+static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status,
+ struct iwl_wowlan_gtk_status_v3 *data)
+{
+ /* The parts we need are identical in v2 and v3 */
+#define CHECK(_f) do { \
+ BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) != \
+ offsetof(struct iwl_wowlan_gtk_status_v3, _f)); \
+ BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\
+ offsetofend(struct iwl_wowlan_gtk_status_v3, _f)); \
+} while (0)
+
+ CHECK(key);
+ CHECK(key_len);
+ CHECK(key_flags);
+ CHECK(tkip_mic_key);
+#undef CHECK
+
+ iwl_mvm_convert_gtk_v2(status, (void *)data);
+}
+
static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_igtk_status *data)
{
@@ -2017,7 +2138,7 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
goto out_free_resp;

iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc);
- iwl_mvm_convert_gtk(status, &v7->gtk[0]);
+ iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]);
iwl_mvm_convert_igtk(status, &v7->igtk[0]);
} else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) {
struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;
@@ -2030,10 +2151,22 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
goto out_free_resp;

iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc);
- iwl_mvm_convert_gtk(status, &v9->gtk[0]);
+ iwl_mvm_convert_gtk_v2(status, &v9->gtk[0]);
iwl_mvm_convert_igtk(status, &v9->igtk[0]);

status->tid_tear_down = v9->tid_tear_down;
+ } else if (notif_ver == 12) {
+ struct iwl_wowlan_status_v12 *v12 = (void *)cmd.resp_pkt->data;
+
+ status = iwl_mvm_parse_wowlan_status_common_v12(mvm, v12, len);
+ if (IS_ERR(status))
+ goto out_free_resp;
+
+ iwl_mvm_convert_key_counters_v5(status, &v12->gtk[0].sc);
+ iwl_mvm_convert_gtk_v3(status, &v12->gtk[0]);
+ iwl_mvm_convert_igtk(status, &v12->igtk[0]);
+
+ status->tid_tear_down = v12->tid_tear_down;
} else {
IWL_ERR(mvm,
"Firmware advertises unknown WoWLAN status response %d!\n",
--
2.33.1


2021-12-04 06:36:18

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 09/12] iwlwifi: mvm: support RLC configuration command

From: Johannes Berg <[email protected]>

There's an RLC configuration command in the firmware that's
going to replace the chain information in the PHY context.
Add support for this command, while leaving the PHY context
fields unset when we know the RLC command will be used.

Also add support to send only the RLC configuration command
if only the # of chains used on the PHY context changes.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../wireless/intel/iwlwifi/fw/api/datapath.h | 62 +++++++++++++++++++
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 +--
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 +
.../net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 60 +++++++++++++++++-
4 files changed, 123 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
index 985b0dc5b52a..89236f42c5a4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
@@ -31,6 +31,11 @@ enum iwl_data_path_subcmd_ids {
*/
STA_HE_CTXT_CMD = 0x7,

+ /**
+ * @RLC_CONFIG_CMD: &struct iwl_rlc_config_cmd
+ */
+ RLC_CONFIG_CMD = 0x8,
+
/**
* @RFH_QUEUE_CONFIG_CMD: &struct iwl_rfh_queue_config
*/
@@ -195,4 +200,61 @@ struct iwl_thermal_dual_chain_request {
__le32 event;
} __packed; /* THERMAL_DUAL_CHAIN_DISABLE_REQ_NTFY_API_S_VER_1 */

+enum iwl_rlc_chain_info {
+ IWL_RLC_CHAIN_INFO_DRIVER_FORCE = BIT(0),
+ IWL_RLC_CHAIN_INFO_VALID = 0x000e,
+ IWL_RLC_CHAIN_INFO_FORCE = 0x0070,
+ IWL_RLC_CHAIN_INFO_FORCE_MIMO = 0x0380,
+ IWL_RLC_CHAIN_INFO_COUNT = 0x0c00,
+ IWL_RLC_CHAIN_INFO_MIMO_COUNT = 0x3000,
+};
+
+/**
+ * struct iwl_rlc_properties - RLC properties
+ * @rx_chain_info: RX chain info, &enum iwl_rlc_chain_info
+ * @reserved: reserved
+ */
+struct iwl_rlc_properties {
+ __le32 rx_chain_info;
+ __le32 reserved;
+} __packed; /* RLC_PROPERTIES_S_VER_1 */
+
+enum iwl_sad_mode {
+ IWL_SAD_MODE_ENABLED = BIT(0),
+ IWL_SAD_MODE_DEFAULT_ANT_MSK = 0x6,
+ IWL_SAD_MODE_DEFAULT_ANT_FW = 0x0,
+ IWL_SAD_MODE_DEFAULT_ANT_A = 0x2,
+ IWL_SAD_MODE_DEFAULT_ANT_B = 0x4,
+};
+
+/**
+ * struct iwl_sad_properties - SAD properties
+ * @chain_a_sad_mode: chain A SAD mode, &enum iwl_sad_mode
+ * @chain_b_sad_mode: chain B SAD mode, &enum iwl_sad_mode
+ * @mac_id: MAC index
+ * @reserved: reserved
+ */
+struct iwl_sad_properties {
+ __le32 chain_a_sad_mode;
+ __le32 chain_b_sad_mode;
+ __le32 mac_id;
+ __le32 reserved;
+} __packed;
+
+/**
+ * struct iwl_rlc_config_cmd - RLC configuration
+ * @phy_id: PHY index
+ * @rlc: RLC properties, &struct iwl_rlc_properties
+ * @sad: SAD (single antenna diversity) options, &struct iwl_sad_properties
+ * @flags: flags, &enum iwl_rlc_flags
+ * @reserved: reserved
+ */
+struct iwl_rlc_config_cmd {
+ __le32 phy_id;
+ struct iwl_rlc_properties rlc;
+ struct iwl_sad_properties sad;
+ u8 flags;
+ u8 reserved[3];
+} __packed; /* RLC_CONFIG_CMD_API_S_VER_2 */
+
#endif /* __iwl_fw_api_datapath_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 64ff2395800c..f7ff7f2e3928 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -94,11 +94,10 @@ struct iwl_mvm_phy_ctxt {

enum nl80211_chan_width width;

- /*
- * TODO: This should probably be removed. Currently here only for rate
- * scaling algorithm
- */
struct ieee80211_channel *channel;
+
+ /* track for RLC config command */
+ u32 center_freq1;
};

struct iwl_mvm_time_event_data {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index cd04f24dd7fa..baa1d8c597fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -530,6 +530,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
HCMD_NAME(UPDATE_MU_GROUPS_CMD),
HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
HCMD_NAME(STA_HE_CTXT_CMD),
+ HCMD_NAME(RLC_CONFIG_CMD),
HCMD_NAME(RFH_QUEUE_CONFIG_CMD),
HCMD_NAME(TLC_MNG_CONFIG_CMD),
HCMD_NAME(CHEST_COLLECTOR_FILTER_CONFIG_CMD),
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
index 035336a9e755..6feb2f664d2c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
@@ -157,8 +157,43 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
/* Set the channel info data */
iwl_mvm_set_chan_info_chandef(mvm, &cmd->ci, chandef);

- iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &cmd->rxchain_info,
+ /* we only support RLC command version 2 */
+ if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP,
+ RLC_CONFIG_CMD, 0) < 2)
+ iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &cmd->rxchain_info,
+ chains_static, chains_dynamic);
+}
+
+static int iwl_mvm_phy_send_rlc(struct iwl_mvm *mvm,
+ struct iwl_mvm_phy_ctxt *ctxt,
+ u8 chains_static, u8 chains_dynamic)
+{
+ struct iwl_rlc_config_cmd cmd = {
+ .phy_id = cpu_to_le32(ctxt->id),
+ };
+
+ if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP,
+ RLC_CONFIG_CMD, 0) < 2)
+ return 0;
+
+ BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_DRIVER_FORCE !=
+ PHY_RX_CHAIN_DRIVER_FORCE_MSK);
+ BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_VALID !=
+ PHY_RX_CHAIN_VALID_MSK);
+ BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_FORCE !=
+ PHY_RX_CHAIN_FORCE_SEL_MSK);
+ BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_FORCE_MIMO !=
+ PHY_RX_CHAIN_FORCE_MIMO_SEL_MSK);
+ BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_COUNT != PHY_RX_CHAIN_CNT_MSK);
+ BUILD_BUG_ON(IWL_RLC_CHAIN_INFO_MIMO_COUNT !=
+ PHY_RX_CHAIN_MIMO_CNT_MSK);
+
+ iwl_mvm_phy_ctxt_set_rxchain(mvm, ctxt, &cmd.rlc.rx_chain_info,
chains_static, chains_dynamic);
+
+ return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(RLC_CONFIG_CMD,
+ DATA_PATH_GROUP, 2),
+ 0, sizeof(cmd), &cmd);
}

/*
@@ -211,9 +246,16 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
}


- if (ret)
+ if (ret) {
IWL_ERR(mvm, "PHY ctxt cmd error. ret=%d\n", ret);
- return ret;
+ return ret;
+ }
+
+ if (action != FW_CTXT_ACTION_REMOVE)
+ return iwl_mvm_phy_send_rlc(mvm, ctxt, chains_static,
+ chains_dynamic);
+
+ return 0;
}

/*
@@ -228,6 +270,8 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
lockdep_assert_held(&mvm->mutex);

ctxt->channel = chandef->chan;
+ ctxt->width = chandef->width;
+ ctxt->center_freq1 = chandef->center_freq1;

return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
chains_static, chains_dynamic,
@@ -257,6 +301,14 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,

lockdep_assert_held(&mvm->mutex);

+ if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP,
+ RLC_CONFIG_CMD, 0) >= 2 &&
+ ctxt->channel == chandef->chan &&
+ ctxt->width == chandef->width &&
+ ctxt->center_freq1 == chandef->center_freq1)
+ return iwl_mvm_phy_send_rlc(mvm, ctxt, chains_static,
+ chains_dynamic);
+
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
ctxt->channel->band != chandef->chan->band) {
@@ -275,6 +327,8 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,

ctxt->channel = chandef->chan;
ctxt->width = chandef->width;
+ ctxt->center_freq1 = chandef->center_freq1;
+
return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
chains_static, chains_dynamic,
action);
--
2.33.1


2021-12-04 06:36:19

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 10/12] iwlwifi: fw: api: add link to PHY context command struct v1

From: Johannes Berg <[email protected]>

There are two possible versions of this command in use today,
add a link to v1 as well in the documentation.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/fw/api/commands.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 8a90acbd0db9..8ce03b08592c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -72,7 +72,8 @@ enum iwl_legacy_cmds {

/**
* @PHY_CONTEXT_CMD:
- * Add/modify/remove a PHY context, using &struct iwl_phy_context_cmd.
+ * Add/modify/remove a PHY context, using &struct iwl_phy_context_cmd
+ * or &struct iwl_phy_context_cmd_v1.
*/
PHY_CONTEXT_CMD = 0x8,

--
2.33.1


2021-12-04 06:36:19

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 11/12] iwlwifi: mvm: add support for PHY context command v4

From: Johannes Berg <[email protected]>

A new version of this command deprecates the rxchain_info field
but is otherwise the same, so treat it the same way. We already
leave the rxchain_info zeroed since the RLC command is supported.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h | 9 +++++----
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
index 68b788b92b7a..e66f77924f83 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2018, 2020 Intel Corporation
+ * Copyright (C) 2012-2014, 2018, 2020-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -150,11 +150,12 @@ struct iwl_phy_context_cmd {
/* COMMON_INDEX_HDR_API_S_VER_1 */
__le32 id_and_color;
__le32 action;
- /* PHY_CONTEXT_DATA_API_S_VER_3 */
+ /* PHY_CONTEXT_DATA_API_S_VER_3, PHY_CONTEXT_DATA_API_S_VER_4 */
struct iwl_fw_channel_info ci;
__le32 lmac_id;
- __le32 rxchain_info;
+ __le32 rxchain_info; /* reserved in _VER_4 */
__le32 dsp_cfg_flags;
__le32 reserved;
-} __packed; /* PHY_CONTEXT_CMD_API_VER_3 */
+} __packed; /* PHY_CONTEXT_CMD_API_VER_3, PHY_CONTEXT_CMD_API_VER_4 */
+
#endif /* __iwl_fw_api_phy_ctxt_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
index 6feb2f664d2c..9af40b0fa37a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
@@ -212,7 +212,7 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
int ver = iwl_fw_lookup_cmd_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
PHY_CONTEXT_CMD, 1);

- if (ver == 3) {
+ if (ver == 3 || ver == 4) {
struct iwl_phy_context_cmd cmd = {};

/* Set the command header fields */
--
2.33.1


2021-12-04 06:36:21

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 12/12] iwlwifi: remove unused iwlax210_2ax_cfg_so_hr_a0 structure

From: Luca Coelho <[email protected]>

We don't use this structure anymore, except for a check that will
never match, so we can remove this structure entirely.

Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 7 -------
drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 -
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 15 ---------------
3 files changed, 23 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 7a06bbae178b..0467c1e9eeb3 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -699,13 +699,6 @@ const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0 = {
.num_rbds = IWL_NUM_RBDS_NON_HE,
};

-const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = {
- .name = "Intel(R) Wi-Fi 6 AX210 160MHz",
- .fw_name_pre = IWL_SO_A_HR_B_FW_PRE,
- IWL_DEVICE_AX210,
- .num_rbds = IWL_NUM_RBDS_AX210_HE,
-};
-
const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = {
.name = iwl_ax211_name,
.fw_name_pre = IWL_SO_A_GF_A_FW_PRE,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index d704e278b577..1ecde7c86368 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -610,7 +610,6 @@ extern const struct iwl_cfg killer1650x_2ax_cfg;
extern const struct iwl_cfg killer1650w_2ax_cfg;
extern const struct iwl_cfg iwl_qnj_b0_hr_b0_cfg;
extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_b0;
-extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0;
extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0;
extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0_long;
extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 93d789670f89..89f0390963c9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1498,21 +1498,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D)
iwl_trans->cfg = cfg_7265d;

- if (cfg == &iwlax210_2ax_cfg_so_hr_a0) {
- if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_TY) {
- iwl_trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0;
- } else if (CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) ==
- CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF)) {
- iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_b0;
- } else if (CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) ==
- CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF)) {
- iwl_trans->cfg = &iwlax211_2ax_cfg_so_gf_a0;
- } else if (CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) ==
- CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF4)) {
- iwl_trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0;
- }
- }
-
/*
* This is a hack to switch from Qu B0 to Qu C0. We need to
* do this for all cfgs that use Qu B0, except for those using
--
2.33.1


2021-12-07 13:44:55

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 03/12] iwlwifi: properly support 4-bit MAC step

Luca Coelho <[email protected]> writes:

> From: Mike Golant <[email protected]>
>
> Properly support 4-bit MAC step by refactoring all the current
> handling of the MAC step/dash.

What is 4-bit MAC step?

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2021-12-07 13:49:26

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 03/12] iwlwifi: properly support 4-bit MAC step

On Tue, 2021-12-07 at 15:44 +0200, Kalle Valo wrote:
> Luca Coelho <[email protected]> writes:
>
> > From: Mike Golant <[email protected]>
> >
> > Properly support 4-bit MAC step by refactoring all the current
> > handling of the MAC step/dash.
>
> What is 4-bit MAC step?

Maybe a bit bad wording. We have a MAC component (which is inside the
SoC) and it has several different HW steps. 3 bits used to be enough
but now we need 4-bits to represent all the different steps.

Do you want me to reword the commit message?

--
Cheers,
Luca.

2021-12-07 13:49:27

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 00/12] iwlwifi: updates intended for v5.16 2021-12-04 part 1

Luca Coelho <[email protected]> writes:

> From: Luca Coelho <[email protected]>
>
> Hi,
>
> Here's the first set of patches intended for v5.17. It's the usual
> development, new features, cleanups and bugfixes.
>
> The changes are:
>
> * Some improvements in D3;
> * Support for new FW API commands;
> * Fixes and cleanups in device configurations;
> * Some other small fixes, clean-ups and improvements.
>
> As usual, I'm pushing this to a pending branch, for kbuild bot, and
> will send a pull-request later.
>
> Please review.

BTW, I switched my email to [email protected]. Please update your address
book.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2021-12-07 14:05:56

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 03/12] iwlwifi: support 4-bits in MAC step value

From: Mike Golant <[email protected]>

We have a MAC component (which is inside the SoC) and it has several
different HW steps. 3 bits used to be enough but now we need 4-bits
to represent all the different steps.

Properly support 4-bits in the MAC step value by refactoring all the
current handling of the MAC step/dash.

Already from family 8000 and up the dash (bits 0-1) no longer exists
and the step (until 8000 bits 2-3) consists of the dash bits as well.

To do this remove the CSR_HW_REV_STEP and the CSR_HW_REV_DASH
macros, replace them with CSR_HW_REV_STEP_DASH and add hw_rev_step
into the trans struct.

In addition remove the CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP and
CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH macros and create a new macro
combining the 2 (this way we don't need shifting or anything else.)

Signed-off-by: Matti Gottlieb <[email protected]>
Signed-off-by: Mike Golant <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---

In v2, reword commit subject, first paragraph and some other small
things in the commit message.

drivers/net/wireless/intel/iwlwifi/dvm/main.c | 8 ++------
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++--
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 14 ++++++--------
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 4 ++--
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 2 +-
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 2 ++
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 10 +++-------
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 +-
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 5 +++--
9 files changed, 22 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index fbd57a2b2bd5..90b9becd1673 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1974,12 +1974,8 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)

/* SKU Control */
iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
- CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP,
- (CSR_HW_REV_STEP(priv->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) |
- (CSR_HW_REV_DASH(priv->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_DASH));
+ CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH,
+ CSR_HW_REV_STEP_DASH(priv->trans->hw_rev));

/* write radio config values to register */
if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index a39013c401c9..c8a08bdfefa4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -880,7 +880,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
dump_info->hw_type =
cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->hw_rev));
dump_info->hw_step =
- cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev));
+ cpu_to_le32(fwrt->trans->hw_rev_step);
memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable,
sizeof(dump_info->fw_human_readable));
strncpy(dump_info->dev_human_readable, fwrt->trans->name,
@@ -2099,7 +2099,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);
dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype);

- dump->hw_step = cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev));
+ dump->hw_step = cpu_to_le32(fwrt->trans->hw_rev_step);

/*
* Several HWs all have type == 0x42, so we'll override this value
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index ff79a2ecb242..cfea20e507b3 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -143,8 +143,7 @@
#define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101)

/* Bits for CSR_HW_IF_CONFIG_REG */
-#define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003)
-#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C)
+#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH (0x0000000F)
#define CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM (0x00000080)
#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0)
#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
@@ -287,8 +286,7 @@
#define CSR_GP_CNTRL_REG_FLAG_SW_RESET BIT(31)

/* HW REV */
-#define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0)
-#define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2)
+#define CSR_HW_REV_STEP_DASH(_val) ((_val) & CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH)
#define CSR_HW_REV_TYPE(_val) (((_val) & 0x000FFF0) >> 4)

/* HW RFID */
@@ -328,10 +326,10 @@ enum {
#define CSR_HW_REV_TYPE_7265D (0x0000210)
#define CSR_HW_REV_TYPE_NONE (0x00001F0)
#define CSR_HW_REV_TYPE_QNJ (0x0000360)
-#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
-#define CSR_HW_REV_TYPE_QU_B0 (0x0000334)
-#define CSR_HW_REV_TYPE_QU_C0 (0x0000338)
-#define CSR_HW_REV_TYPE_QUZ (0x0000354)
+#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000361)
+#define CSR_HW_REV_TYPE_QU_B0 (0x0000331)
+#define CSR_HW_REV_TYPE_QU_C0 (0x0000332)
+#define CSR_HW_REV_TYPE_QUZ (0x0000351)
#define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
#define CSR_HW_REV_TYPE_SO (0x0000370)
#define CSR_HW_REV_TYPE_TY (0x0000420)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 36196e07b1a0..026116629040 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -163,8 +163,8 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
char tag[8];

if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
- (CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_B_STEP &&
- CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_C_STEP)) {
+ (drv->trans->hw_rev_step != SILICON_B_STEP &&
+ drv->trans->hw_rev_step != SILICON_C_STEP)) {
IWL_ERR(drv,
"Only HW steps B and C are currently supported (0x%0x)\n",
drv->trans->hw_rev);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 0cd4718372f5..9ef89ff09105 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -1609,7 +1609,7 @@ int iwl_read_external_nvm(struct iwl_trans *trans,

/* nvm file validation, dword_buff[2] holds the file version */
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
- CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP &&
+ trans->hw_rev_step == SILICON_C_STEP &&
le32_to_cpu(dword_buff[2]) < 0xE4A) {
ret = -EFAULT;
goto out;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index a4060af50201..947ed82b7f19 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -938,6 +938,7 @@ struct iwl_trans_txqs {
* @hw_id: a u32 with the ID of the device / sub-device.
* Set during transport allocation.
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
+ * @hw_rev_step: The mac step of the HW
* @pm_support: set to true in start_hw if link pm is supported
* @ltr_enabled: set to true if the LTR is enabled
* @wide_cmd_header: true when ucode supports wide command header format
@@ -971,6 +972,7 @@ struct iwl_trans {
struct device *dev;
u32 max_skb_frags;
u32 hw_rev;
+ u32 hw_rev_step;
u32 hw_rf_id;
u32 hw_id;
char hw_id_str[52];
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 3ab0217abeea..cd04f24dd7fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -78,7 +78,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
- u32 reg_val = 0;
+ u32 reg_val;
u32 phy_config = iwl_mvm_get_phy_config(mvm);

radio_cfg_type = (phy_config & FW_PHY_CFG_RADIO_TYPE) >>
@@ -89,10 +89,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
FW_PHY_CFG_RADIO_DASH_POS;

/* SKU control */
- reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
- reg_val |= CSR_HW_REV_DASH(mvm->trans->hw_rev) <<
- CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
+ reg_val = CSR_HW_REV_STEP_DASH(mvm->trans->hw_rev);

/* radio configuration */
reg_val |= radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
@@ -117,8 +114,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
reg_val |= CSR_HW_IF_CONFIG_REG_D3_DEBUG;

iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
- CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP |
+ CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH |
CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 5c56da36fc84..db8b62e432eb 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1450,7 +1450,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device,
CSR_HW_REV_TYPE(iwl_trans->hw_rev),
- CSR_HW_REV_STEP(iwl_trans->hw_rev),
+ iwl_trans->hw_rev_step,
CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id),
CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id),
IWL_SUBDEVICE_RF_ID(pdev->subsystem_device),
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 451b28de1392..f607edd41baa 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3616,8 +3616,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
* in the old format.
*/
if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_8000)
- trans->hw_rev = (trans->hw_rev & 0xfff0) |
- (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2);
+ trans->hw_rev_step = trans->hw_rev & 0xF;
+ else
+ trans->hw_rev_step = (trans->hw_rev & 0xC) >> 2;

IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev);

--
2.33.1


2021-12-07 14:24:22

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 03/12] iwlwifi: properly support 4-bit MAC step

Luca Coelho <[email protected]> writes:

> On Tue, 2021-12-07 at 15:44 +0200, Kalle Valo wrote:
>> Luca Coelho <[email protected]> writes:
>>
>> > From: Mike Golant <[email protected]>
>> >
>> > Properly support 4-bit MAC step by refactoring all the current
>> > handling of the MAC step/dash.
>>
>> What is 4-bit MAC step?
>
> Maybe a bit bad wording. We have a MAC component (which is inside the
> SoC) and it has several different HW steps. 3 bits used to be enough
> but now we need 4-bits to represent all the different steps.
>
> Do you want me to reword the commit message?

Yeah, please add what you wrote above to the commit log so that people
outside Intel understand what this is about.

--
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches