From 8061effc78fae30b0b4d52d18bae8b37a72ebc93 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 4 Mar 2022 13:21:17 +0200 Subject: [PATCH 01/13] iwlwifi: bump FW API to 71 for AX devices Start supporting API version 71 for AX devices. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.d0898482506f.I2de2f9140c23f39a837f68199bbaf15a20f26abb@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 918dd0f6f8b54..a0c777914e38c 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -10,7 +10,7 @@ #include "fw/api/txq.h" /* Highest firmware API version supported */ -#define IWL_22000_UCODE_API_MAX 70 +#define IWL_22000_UCODE_API_MAX 71 /* Lowest firmware API version supported */ #define IWL_22000_UCODE_API_MIN 39 From b0aa02b3de89aaed95b9b17dfb4639e7190deebd Mon Sep 17 00:00:00 2001 From: Ayala Barazani Date: Fri, 4 Mar 2022 13:21:18 +0200 Subject: [PATCH 02/13] iwlwifi: mvm: add a flag to reduce power command. Add a flags bitfield in REDUCED_TX_POWER_CMD, and send it as is to FW. Signed-off-by: Ayala Barazani Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.55c2f014f5ee.Iceb632f620de959800f979e212f0dc20240f9d38@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 8 +++--- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 3 +++ .../net/wireless/intel/iwlwifi/fw/api/power.h | 27 +++++++++++++++++-- .../net/wireless/intel/iwlwifi/fw/runtime.h | 3 ++- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 8 ++++-- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 ++- 6 files changed, 44 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 0e9e61508ae5f..4441f92c004f1 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -537,8 +537,8 @@ IWL_EXPORT_SYMBOL(iwl_sar_select_profile); int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt) { union acpi_object *wifi_pkg, *table, *data; - bool enabled; int ret, tbl_rev; + u32 flags; u8 num_chains, num_sub_bands; data = iwl_acpi_get_object(fwrt->dev, ACPI_WRDS_METHOD); @@ -604,7 +604,8 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt) IWL_DEBUG_RADIO(fwrt, "Reading WRDS tbl_rev=%d\n", tbl_rev); - enabled = !!(wifi_pkg->package.elements[1].integer.value); + flags = wifi_pkg->package.elements[1].integer.value; + fwrt->reduced_power_flags = flags >> IWL_REDUCE_POWER_FLAGS_POS; /* position of the actual table */ table = &wifi_pkg->package.elements[2]; @@ -612,7 +613,8 @@ int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt) /* The profile from WRDS is officially profile 1, but goes * into sar_profiles[0] (because we don't have a profile 0). */ - ret = iwl_sar_set_profile(table, &fwrt->sar_profiles[0], enabled, + ret = iwl_sar_set_profile(table, &fwrt->sar_profiles[0], + flags & IWL_SAR_ENABLE_MSK, num_chains, num_sub_bands); out_free: kfree(data); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 466c95c21aa94..089dd90025283 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -92,6 +92,9 @@ #define ACPI_PPAG_MIN_HB -16 #define ACPI_PPAG_MAX_HB 40 +#define IWL_SAR_ENABLE_MSK BIT(0) +#define IWL_REDUCE_POWER_FLAGS_POS 1 + /* * The profile for revision 2 is a superset of revision 1, which is in * turn a superset of revision 0. So we can store all revisions diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index 81318208f2f66..f92cac1da764a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -340,7 +340,7 @@ struct iwl_dev_tx_power_cmd_v5 { } __packed; /* TX_REDUCED_POWER_API_S_VER_5 */ /** - * struct iwl_dev_tx_power_cmd_v5 - TX power reduction command version 5 + * struct iwl_dev_tx_power_cmd_v6 - TX power reduction command version 6 * @per_chain: per chain restrictions * @enable_ack_reduction: enable or disable close range ack TX power * reduction. @@ -360,6 +360,28 @@ struct iwl_dev_tx_power_cmd_v6 { __le32 timer_period; } __packed; /* TX_REDUCED_POWER_API_S_VER_6 */ +/** + * struct iwl_dev_tx_power_cmd_v7 - TX power reduction command version 7 + * @per_chain: per chain restrictions + * @enable_ack_reduction: enable or disable close range ack TX power + * reduction. + * @per_chain_restriction_changed: is per_chain_restriction has changed + * from last command. used if set_mode is + * IWL_TX_POWER_MODE_SET_SAR_TIMER. + * note: if not changed, the command is used for keep alive only. + * @reserved: reserved (padding) + * @timer_period: timer in milliseconds. if expires FW will change to default + * BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER + * @flags: reduce power flags. + */ +struct iwl_dev_tx_power_cmd_v7 { + __le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2]; + u8 enable_ack_reduction; + u8 per_chain_restriction_changed; + u8 reserved[2]; + __le32 timer_period; + __le32 flags; +} __packed; /* TX_REDUCED_POWER_API_S_VER_7 */ /** * struct iwl_dev_tx_power_cmd - TX power reduction command (multiversion) * @common: common part of the command @@ -375,6 +397,7 @@ struct iwl_dev_tx_power_cmd { struct iwl_dev_tx_power_cmd_v4 v4; struct iwl_dev_tx_power_cmd_v5 v5; struct iwl_dev_tx_power_cmd_v6 v6; + struct iwl_dev_tx_power_cmd_v7 v7; }; }; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index afc822cab6746..d3cb1ae68a96c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #ifndef __iwl_fw_runtime_h__ #define __iwl_fw_runtime_h__ @@ -163,6 +163,7 @@ struct iwl_fw_runtime { u32 ppag_ver; struct iwl_sar_offset_mapping_cmd sgom_table; bool sgom_enabled; + u8 reduced_power_flags; #endif }; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 8537e1ea27d66..a178b83ee8a22 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -806,8 +806,12 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b) u32 n_subbands; u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, IWL_FW_CMD_VER_UNKNOWN); - - if (cmd_ver == 6) { + if (cmd_ver == 7) { + len = sizeof(cmd.v7); + n_subbands = IWL_NUM_SUB_BANDS_V2; + per_chain = cmd.v7.per_chain[0][0]; + cmd.v7.flags = cpu_to_le32(mvm->fwrt.reduced_power_flags); + } else if (cmd_ver == 6) { len = sizeof(cmd.v6); n_subbands = IWL_NUM_SUB_BANDS_V2; per_chain = cmd.v6.per_chain[0][0]; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 6a9d9ce0007ae..2ce09e58e74cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1336,7 +1336,9 @@ static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (tx_power == IWL_DEFAULT_MAX_TX_POWER) cmd.common.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER); - if (cmd_ver == 6) + if (cmd_ver == 7) + len = sizeof(cmd.v7); + else if (cmd_ver == 6) len = sizeof(cmd.v6); else if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_REDUCE_TX_POWER)) From b49c2b252b58e8afa2b0a908d61ef979334d78bd Mon Sep 17 00:00:00 2001 From: Ayala Barazani Date: Fri, 4 Mar 2022 13:21:19 +0200 Subject: [PATCH 03/13] iwlwifi: Configure FW debug preset via module param. The module param "enable_ini" is currently used to be enable/disable ini. Add the option to configure the FW debug preset via this module param, by change it type from boolean to an integer. Signed-off-by: Ayala Barazani Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.4929e4b14956.I1bdffa4c37d4ee349aa0001978b716b96e38b090@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 4 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 41 +++++++++++++++++-- .../wireless/intel/iwlwifi/iwl-modparams.h | 5 ++- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index 79287708bd6e6..128059ca77e60 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #ifndef __iwl_dbg_tlv_h__ #define __iwl_dbg_tlv_h__ @@ -10,6 +10,8 @@ #include #include +#define IWL_DBG_TLV_MAX_PRESET 15 + /** * struct iwl_dbg_tlv_node - debug TLV node * @list: list of &struct iwl_dbg_tlv_node diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index ab52136cffb4a..f92bcab5fdf6d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1796,6 +1796,7 @@ void iwl_drv_stop(struct iwl_drv *drv) kfree(drv); } +#define ENABLE_INI (IWL_DBG_TLV_MAX_PRESET + 1) /* shared module parameters */ struct iwl_mod_params iwlwifi_mod_params = { @@ -1803,7 +1804,7 @@ struct iwl_mod_params iwlwifi_mod_params = { .bt_coex_active = true, .power_level = IWL_POWER_INDEX_1, .uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT, - .enable_ini = true, + .enable_ini = ENABLE_INI, /* the rest are 0 by default */ }; IWL_EXPORT_SYMBOL(iwlwifi_mod_params); @@ -1915,10 +1916,42 @@ MODULE_PARM_DESC(nvm_file, "NVM file name"); module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, uint, 0644); MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3)"); -module_param_named(enable_ini, iwlwifi_mod_params.enable_ini, - bool, S_IRUGO | S_IWUSR); + +static int enable_ini_set(const char *arg, const struct kernel_param *kp) +{ + int ret = 0; + bool res; + __u32 new_enable_ini; + + /* in case the argument type is a number */ + ret = kstrtou32(arg, 0, &new_enable_ini); + if (!ret) { + if (new_enable_ini > ENABLE_INI) { + pr_err("enable_ini cannot be %d, in range 0-16\n", new_enable_ini); + return -EINVAL; + } + goto out; + } + + /* in case the argument type is boolean */ + ret = kstrtobool(arg, &res); + if (ret) + return ret; + new_enable_ini = (res ? ENABLE_INI : 0); + +out: + iwlwifi_mod_params.enable_ini = new_enable_ini; + return 0; +} + +static const struct kernel_param_ops enable_ini_ops = { + .set = enable_ini_set +}; + +module_param_cb(enable_ini, &enable_ini_ops, &iwlwifi_mod_params.enable_ini, 0644); MODULE_PARM_DESC(enable_ini, - "Enable debug INI TLV FW debug infrastructure (default: true"); + "0:disable, 1-15:FW_DBG_PRESET Values, 16:enabled without preset value defined," + "Debug INI TLV FW debug infrastructure (default: 16)"); /* * set bt_coex_active to true, uCode will do kill/defer diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h index 004ebdac45358..d0b4d02bdab92 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2018-2020 Intel Corporation + * Copyright (C) 2005-2014, 2018-2022 Intel Corporation */ #ifndef __iwl_modparams_h__ #define __iwl_modparams_h__ @@ -83,7 +83,8 @@ struct iwl_mod_params { */ bool disable_11ax; bool remove_when_gone; - bool enable_ini; + u32 enable_ini; + bool disable_11be; }; static inline bool iwl_enable_rx_ampdu(void) From 8b3d2c4882874f32dd1470a92e98417a8d0345cb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 4 Mar 2022 13:21:20 +0200 Subject: [PATCH 04/13] iwlwifi: mvm: remove cipher scheme support There are no shipping firmware versions with this, and there will also not be in the future, so remove the support. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.8b3c8b4adf41.Ib3ddb6b250ea2dd72b4ecc88bdd5cffb86af1dcc@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 28 ------------------ drivers/net/wireless/intel/iwlwifi/fw/img.h | 12 -------- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 28 ------------------ .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 29 +------------------ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 - 5 files changed, 1 insertion(+), 97 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index fa2a73ae41832..35e4adb7006f5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -518,34 +518,6 @@ enum iwl_fw_phy_cfg { FW_PHY_CFG_SHARED_CLK = BIT(31), }; -#define IWL_UCODE_MAX_CS 1 - -/** - * struct iwl_fw_cipher_scheme - a cipher scheme supported by FW. - * @cipher: a cipher suite selector - * @flags: cipher scheme flags (currently reserved for a future use) - * @hdr_len: a size of MPDU security header - * @pn_len: a size of PN - * @pn_off: an offset of pn from the beginning of the security header - * @key_idx_off: an offset of key index byte in the security header - * @key_idx_mask: a bit mask of key_idx bits - * @key_idx_shift: bit shift needed to get key_idx - * @mic_len: mic length in bytes - * @hw_cipher: a HW cipher index used in host commands - */ -struct iwl_fw_cipher_scheme { - __le32 cipher; - u8 flags; - u8 hdr_len; - u8 pn_len; - u8 pn_off; - u8 key_idx_off; - u8 key_idx_mask; - u8 key_idx_shift; - u8 mic_len; - u8 hw_cipher; -} __packed; - enum iwl_fw_dbg_reg_operator { CSR_ASSIGN, CSR_SETBIT, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 89869edb23e8b..f878ac5088017 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -133,16 +133,6 @@ struct iwl_fw_paging { u32 fw_offs; }; -/** - * struct iwl_fw_cscheme_list - a cipher scheme list - * @size: a number of entries - * @cs: cipher scheme entries - */ -struct iwl_fw_cscheme_list { - u8 size; - struct iwl_fw_cipher_scheme cs[]; -} __packed; - /** * enum iwl_fw_type - iwlwifi firmware type * @IWL_FW_DVM: DVM firmware @@ -197,7 +187,6 @@ struct iwl_dump_exclude { * @inst_evtlog_size: event log size for runtime ucode. * @inst_errlog_ptr: error log offfset for runtime ucode. * @type: firmware type (&enum iwl_fw_type) - * @cipher_scheme: optional external cipher scheme. * @human_readable: human readable version * we get the ALIVE from the uCode * @phy_integration_ver: PHY integration version string @@ -228,7 +217,6 @@ struct iwl_fw { enum iwl_fw_type type; - struct iwl_fw_cipher_scheme cs[IWL_UCODE_MAX_CS]; u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; struct iwl_fw_dbg dbg; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index f92bcab5fdf6d..8bb4f54d9b387 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -324,30 +324,6 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces, pieces->img[type].sec[sec].offset = offset; } -static int iwl_store_cscheme(struct iwl_fw *fw, const u8 *data, const u32 len) -{ - int i, j; - const struct iwl_fw_cscheme_list *l = - (const struct iwl_fw_cscheme_list *)data; - const struct iwl_fw_cipher_scheme *fwcs; - - if (len < sizeof(*l) || - len < sizeof(l->size) + l->size * sizeof(l->cs[0])) - return -EINVAL; - - for (i = 0, j = 0; i < IWL_UCODE_MAX_CS && i < l->size; i++) { - fwcs = &l->cs[j]; - - /* we skip schemes with zero cipher suite selector */ - if (!fwcs->cipher) - continue; - - fw->cs[j++] = *fwcs; - } - - return 0; -} - /* * Gets uCode section from tlv. */ @@ -926,10 +902,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -EINVAL; } break; - case IWL_UCODE_TLV_CSCHEME: - if (iwl_store_cscheme(&drv->fw, tlv_data, tlv_len)) - goto invalid_tlv_len; - break; case IWL_UCODE_TLV_N_SCAN_CHANNELS: if (tlv_len != sizeof(u32)) goto invalid_tlv_len; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 2ce09e58e74cf..81d02a17dfe40 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -448,28 +448,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->n_cipher_suites++; } - /* currently FW API supports only one optional cipher scheme */ - if (mvm->fw->cs[0].cipher) { - const struct iwl_fw_cipher_scheme *fwcs = &mvm->fw->cs[0]; - struct ieee80211_cipher_scheme *cs = &mvm->cs[0]; - - mvm->hw->n_cipher_schemes = 1; - - cs->cipher = le32_to_cpu(fwcs->cipher); - cs->iftype = BIT(NL80211_IFTYPE_STATION); - cs->hdr_len = fwcs->hdr_len; - cs->pn_len = fwcs->pn_len; - cs->pn_off = fwcs->pn_off; - cs->key_idx_off = fwcs->key_idx_off; - cs->key_idx_mask = fwcs->key_idx_mask; - cs->key_idx_shift = fwcs->key_idx_shift; - cs->mic_len = fwcs->mic_len; - - mvm->hw->cipher_schemes = mvm->cs; - mvm->ciphers[hw->wiphy->n_cipher_suites] = cs->cipher; - hw->wiphy->n_cipher_suites++; - } - if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_FTM_CALIBRATED)) { wiphy_ext_feature_set(hw->wiphy, @@ -3744,12 +3722,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, /* support HW crypto on TX */ return 0; default: - /* currently FW supports only one optional cipher scheme */ - if (hw->n_cipher_schemes && - hw->cipher_schemes->cipher == key->cipher) - key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; - else - return -EOPNOTSUPP; + return -EOPNOTSUPP; } switch (cmd) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ecfe322ebef2b..7c6802f92ef72 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1075,7 +1075,6 @@ struct iwl_mvm { u32 ciphers[IWL_MVM_NUM_CIPHERS]; - struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; struct cfg80211_ftm_responder_stats ftm_resp_stats; struct { From 5053a451109e08d62d9086c1427c55c0411c9c3e Mon Sep 17 00:00:00 2001 From: Mukesh Sisodiya Date: Fri, 4 Mar 2022 13:21:21 +0200 Subject: [PATCH 05/13] iwlwifi: yoyo: disable IMR DRAM region if IMR is disabled Disable IMR region if it is enabled in the TLVs, but disabled at runtime by the FW. Signed-off-by: Mukesh Sisodiya Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.2a696656a161.I99705472a8838121ffaca72977015dc2069549b9@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index a178b83ee8a22..f4de8250696f0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -124,6 +124,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, u32 lmac_error_event_table, umac_error_table; u32 version = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, UCODE_ALIVE_NTFY, 0); + u32 i; if (version == 6) { struct iwl_alive_ntf_v6 *palive; @@ -146,6 +147,28 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, mvm->trans->dbg.imr_data.imr_enable, mvm->trans->dbg.imr_data.imr_size, le64_to_cpu(mvm->trans->dbg.imr_data.imr_base_addr)); + + if (!mvm->trans->dbg.imr_data.imr_enable) { + for (i = 0; i < ARRAY_SIZE(mvm->trans->dbg.active_regions); i++) { + struct iwl_ucode_tlv *reg_tlv; + struct iwl_fw_ini_region_tlv *reg; + + reg_tlv = mvm->trans->dbg.active_regions[i]; + if (!reg_tlv) + continue; + + reg = (void *)reg_tlv->data; + /* + * We have only one DRAM IMR region, so we + * can break as soon as we find the first + * one. + */ + if (reg->type == IWL_FW_INI_REGION_DRAM_IMR) { + mvm->trans->dbg.unsupported_region_msk |= BIT(i); + break; + } + } + } } if (version >= 5) { From 1c4db7613f35b248ff05b8bfb3a4580a3d11d75c Mon Sep 17 00:00:00 2001 From: Mukesh Sisodiya Date: Fri, 4 Mar 2022 13:21:22 +0200 Subject: [PATCH 06/13] iwlwifi: mvm: add support for IMR based on platform Driver needs to enable IMR which is needed for debug on certain platforms, so add a device config flag to set it. Signed-off-by: Mukesh Sisodiya Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.0b96b2760503.I08bc741c8c497a2edbe4784cdab6abd8d04c62f3@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 15 +++++++++++++++ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 5 ++++- .../intel/iwlwifi/iwl-context-info-gen3.h | 4 +++- .../wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 5 ++++- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 ++- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index a0c777914e38c..8afd5e16e5d85 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -391,6 +391,21 @@ const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg = { .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, }; +const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg = { + .mq_rx_supported = true, + .use_tfh = true, + .rf_id = true, + .gen2 = true, + .device_family = IWL_DEVICE_FAMILY_AX210, + .base_params = &iwl_ax210_base_params, + .umac_prph_offset = 0x300000, + .integrated = true, + .low_latency_xtal = true, + .xtal_latency = 12000, + .ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US, + .imr_enabled = true, +}; + /* * If the device doesn't support HE, no need to have that many buffers. * 22000 devices can split multiple frames into a single RB, so fewer are diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index b7e430ad5e2a6..f5b556a103e8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -260,6 +260,7 @@ enum iwl_cfg_trans_ltr_delay { * @integrated: discrete or integrated * @low_latency_xtal: use the low latency xtal if supported * @ltr_delay: LTR delay parameter, &enum iwl_cfg_trans_ltr_delay. + * @imr_enabled: use the IMR if supported. */ struct iwl_cfg_trans_params { const struct iwl_base_params *base_params; @@ -274,7 +275,8 @@ struct iwl_cfg_trans_params { integrated:1, low_latency_xtal:1, bisr_workaround:1, - ltr_delay:2; + ltr_delay:2, + imr_enabled:1; }; /** @@ -491,6 +493,7 @@ extern const struct iwl_cfg_trans_params iwl_ax200_trans_cfg; extern const struct iwl_cfg_trans_params iwl_snj_trans_cfg; extern const struct iwl_cfg_trans_params iwl_so_trans_cfg; extern const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg; +extern const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg; extern const struct iwl_cfg_trans_params iwl_ma_trans_cfg; extern const struct iwl_cfg_trans_params iwl_bz_trans_cfg; extern const char iwl9162_name[]; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h index 5adf485db38e2..b84884034c747 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2018, 2020-2021 Intel Corporation + * Copyright (C) 2018, 2020-2022 Intel Corporation */ #ifndef __iwl_context_info_file_gen3_h__ #define __iwl_context_info_file_gen3_h__ @@ -34,6 +34,7 @@ enum iwl_prph_scratch_mtr_format { /** * enum iwl_prph_scratch_flags - PRPH scratch control flags + * @IWL_PRPH_SCRATCH_IMR_DEBUG_EN: IMR support for debug * @IWL_PRPH_SCRATCH_EARLY_DEBUG_EN: enable early debug conf * @IWL_PRPH_SCRATCH_EDBG_DEST_DRAM: use DRAM, with size allocated * in hwm config. @@ -55,6 +56,7 @@ enum iwl_prph_scratch_mtr_format { * @IWL_PRPH_SCRATCH_RB_SIZE_EXT_16K: 16kB RB size */ enum iwl_prph_scratch_flags { + IWL_PRPH_SCRATCH_IMR_DEBUG_EN = BIT(1), IWL_PRPH_SCRATCH_EARLY_DEBUG_EN = BIT(4), IWL_PRPH_SCRATCH_EDBG_DEST_DRAM = BIT(8), IWL_PRPH_SCRATCH_EDBG_DEST_INTERNAL = BIT(9), diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 85a6da70ca787..75fd386b048e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #include "iwl-trans.h" #include "iwl-fh.h" @@ -125,6 +125,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, control_flags |= IWL_PRPH_SCRATCH_MTR_MODE; control_flags |= IWL_PRPH_MTR_FORMAT_256B & IWL_PRPH_SCRATCH_MTR_FORMAT; + if (trans->trans_cfg->imr_enabled) + control_flags |= IWL_PRPH_SCRATCH_IMR_DEBUG_EN; + /* initialize RX default queue */ prph_sc_ctrl->rbd_cfg.free_rbd_addr = cpu_to_le64(trans_pcie->rxq->bd_dma); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 58a7111d4f406..b16d4ae182d10 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -491,9 +491,10 @@ static const struct pci_device_id iwl_hw_card_ids[] = { /* So devices */ {IWL_PCI_DEVICE(0x2725, PCI_ANY_ID, iwl_so_trans_cfg)}, {IWL_PCI_DEVICE(0x2726, PCI_ANY_ID, iwl_snj_trans_cfg)}, - {IWL_PCI_DEVICE(0x7A70, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, + {IWL_PCI_DEVICE(0x7A70, PCI_ANY_ID, iwl_so_long_latency_imr_trans_cfg)}, {IWL_PCI_DEVICE(0x7AF0, PCI_ANY_ID, iwl_so_trans_cfg)}, {IWL_PCI_DEVICE(0x51F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, + {IWL_PCI_DEVICE(0x51F1, PCI_ANY_ID, iwl_so_long_latency_imr_trans_cfg)}, {IWL_PCI_DEVICE(0x54F0, PCI_ANY_ID, iwl_so_long_latency_trans_cfg)}, {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_so_trans_cfg)}, From a6d21729ff7a116744daeadd8382c97c9ea85503 Mon Sep 17 00:00:00 2001 From: Mukesh Sisodiya Date: Fri, 4 Mar 2022 13:21:23 +0200 Subject: [PATCH 07/13] iwlwifi: yoyo: dump IMR DRAM only for HW and FW error Support debug collection of the platform IMR memory region only for HW and FW error. This region needs to be collected as the last region. Signed-off-by: Mukesh Sisodiya Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.5b70e5ba9a41.I502f9b6179b97b163992729edd2b3c5c4ca9e311@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 1083922345293..53f0fe77aa102 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2430,6 +2430,9 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, struct iwl_dump_ini_region_data reg_data = { .dump_data = dump_data, }; + struct iwl_dump_ini_region_data imr_reg_data = { + .dump_data = dump_data, + }; int i; u32 size = 0; u64 regions_mask = le64_to_cpu(trigger->regions_mask) & @@ -2465,10 +2468,32 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, tp_id); continue; } + /* + * DRAM_IMR can be collected only for FW/HW error timepoint + * when fw is not alive. In addition, it must be collected + * lastly as it overwrites SRAM that can possibly contain + * debug data which also need to be collected. + */ + if (reg_type == IWL_FW_INI_REGION_DRAM_IMR) { + if (tp_id == IWL_FW_INI_TIME_POINT_FW_ASSERT || + tp_id == IWL_FW_INI_TIME_POINT_FW_HW_ERROR) + imr_reg_data.reg_tlv = fwrt->trans->dbg.active_regions[i]; + else + IWL_INFO(fwrt, + "WRT: trying to collect DRAM_IMR at time point: %d, skipping\n", + tp_id); + /* continue to next region */ + continue; + } + size += iwl_dump_ini_mem(fwrt, list, ®_data, &iwl_dump_ini_region_ops[reg_type]); } + /* collect DRAM_IMR region in the last */ + if (imr_reg_data.reg_tlv) + size += iwl_dump_ini_mem(fwrt, list, ®_data, + &iwl_dump_ini_region_ops[IWL_FW_INI_REGION_DRAM_IMR]); if (size) size += iwl_dump_ini_info(fwrt, trigger, list); From 7b9f485091a5755f6e0a7dd3725f3b312768ecd0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 4 Mar 2022 13:21:24 +0200 Subject: [PATCH 08/13] iwlwifi: pcie: fix SW error MSI-X mapping We need to also update the IVAR location, since we've shifted the bit. Signed-off-by: Johannes Berg Fixes: 571836a02c7b ("iwlwifi: pcie: update sw error interrupt for BZ family") Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.bcfb28484e50.I921df6b5134785d7eeb0c934e4a43157c582fa79@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 518700388fdd5..6ad5df6113709 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1112,7 +1112,7 @@ static const struct iwl_causes_list causes_list_pre_bz[] = { }; static const struct iwl_causes_list causes_list_bz[] = { - {MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ, CSR_MSIX_HW_INT_MASK_AD, 0x29}, + {MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ, CSR_MSIX_HW_INT_MASK_AD, 0x15}, }; static void iwl_pcie_map_list(struct iwl_trans *trans, From bb16ffd561b60638108f1cc97b08f18270468678 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 4 Mar 2022 13:21:25 +0200 Subject: [PATCH 09/13] iwlwifi: use 4k queue size for Bz A-step There's a hardware bug in Bz A-step that can be worked around by using 4k queue size, so do that. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.10ea0e115d05.Idfb3706133bf3b15f1f68f1145e77e89947449d1@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/queue/tx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c index 42e631cc16e81..726185d6fab8b 100644 --- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c @@ -1199,6 +1199,10 @@ int iwl_txq_dyn_alloc(struct iwl_trans *trans, u32 flags, u32 sta_mask, }; int ret; + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_BZ && + trans->hw_rev_step == SILICON_A_STEP) + size = 4096; + txq = iwl_txq_dyn_alloc_dma(trans, size, timeout); if (IS_ERR(txq)) return PTR_ERR(txq); From f0c163382cd2497348c9212f5d3b87754ed33a7b Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Fri, 4 Mar 2022 13:21:26 +0200 Subject: [PATCH 10/13] iwlwifi: dbg: in sync mode don't call schedule Today in the code we have two options for collecting data sync/schedule, the two options call the same function and can lead to racing in free resources after done. So we call only one of two sync/schedule, and in case of sync only call sync function without also schedule to immediately run as a side job. Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.88574097ce1b.I1b42297619d638d677a2300ed9a95105c1262101@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 53f0fe77aa102..d3ac8ea049a43 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2992,10 +2992,10 @@ int iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt, "WRT: Collecting data: ini trigger %d fired (delay=%dms).\n", tp_id, (u32)(delay / USEC_PER_MSEC)); - schedule_delayed_work(&fwrt->dump.wks[idx].wk, usecs_to_jiffies(delay)); - if (sync) iwl_fw_dbg_collect_sync(fwrt, idx); + else + schedule_delayed_work(&fwrt->dump.wks[idx].wk, usecs_to_jiffies(delay)); return 0; } From 97374513bbc426cea115882847369efac633ead3 Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Fri, 4 Mar 2022 13:21:27 +0200 Subject: [PATCH 11/13] iwlwifi: dbg: check trigger data before access Without trigger data set, no point in any collection. so check that we have the info for collecting the data. Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.5fb34fb1f0eb.I4d7f2a4d162e80474540c5caf1194ed7d32977bc@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index d3ac8ea049a43..abf49022edbe4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2905,6 +2905,11 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) if (!test_bit(wk_idx, &fwrt->dump.active_wks)) return; + if (!dump_data->trig) { + IWL_ERR(fwrt, "dump trigger data is not set\n"); + goto out; + } + if (!test_bit(STATUS_DEVICE_ENABLED, &fwrt->trans->status)) { IWL_ERR(fwrt, "Device is not enabled - cannot dump error\n"); goto out; From e8e10a37c51c08b99d272b2e1b3ef70fcd38f9e8 Mon Sep 17 00:00:00 2001 From: Matt Chen Date: Fri, 4 Mar 2022 13:21:28 +0200 Subject: [PATCH 12/13] iwlwifi: acpi: move ppag code from mvm to fw/acpi Move the ppag code to fw/acpi to keep consistency with the other ACPI handling we do. Signed-off-by: Matt Chen Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.7f250088b443.I61e64c2758ad178da729ce00428287cc94430eed@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 203 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 25 +++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 190 +---------------- 3 files changed, 234 insertions(+), 184 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 4441f92c004f1..dd220e1d79969 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -4,6 +4,7 @@ * Copyright (C) 2019-2021 Intel Corporation */ #include +#include #include "iwl-drv.h" #include "iwl-debug.h" #include "acpi.h" @@ -19,6 +20,30 @@ const guid_t iwl_rfi_guid = GUID_INIT(0x7266172C, 0x220B, 0x4B29, 0xDD, 0x26, 0xB5, 0xFD); IWL_EXPORT_SYMBOL(iwl_rfi_guid); +static const struct dmi_system_id dmi_ppag_approved_list[] = { + { .ident = "HP", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + }, + }, + { .ident = "SAMSUNG", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), + }, + }, + { .ident = "MSFT", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + }, + }, + { .ident = "ASUS", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek COMPUTER INC."), + }, + }, + {} +}; + static int iwl_acpi_get_handle(struct device *dev, acpi_string method, acpi_handle *ret_handle) { @@ -971,3 +996,181 @@ __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) return config_bitmap; } IWL_EXPORT_SYMBOL(iwl_acpi_get_lari_config_bitmap); + +int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) +{ + union acpi_object *wifi_pkg, *data, *flags; + int i, j, ret, tbl_rev, num_sub_bands = 0; + int idx = 2; + + fwrt->ppag_flags = 0; + + data = iwl_acpi_get_object(fwrt->dev, ACPI_PPAG_METHOD); + if (IS_ERR(data)) + return PTR_ERR(data); + + /* try to read ppag table rev 2 or 1 (both have the same data size) */ + wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, + ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev); + + if (!IS_ERR(wifi_pkg)) { + if (tbl_rev == 1 || tbl_rev == 2) { + num_sub_bands = IWL_NUM_SUB_BANDS_V2; + IWL_DEBUG_RADIO(fwrt, + "Reading PPAG table v2 (tbl_rev=%d)\n", + tbl_rev); + goto read_table; + } else { + ret = -EINVAL; + goto out_free; + } + } + + /* try to read ppag table revision 0 */ + wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, + ACPI_PPAG_WIFI_DATA_SIZE_V1, &tbl_rev); + + if (!IS_ERR(wifi_pkg)) { + if (tbl_rev != 0) { + ret = -EINVAL; + goto out_free; + } + num_sub_bands = IWL_NUM_SUB_BANDS_V1; + IWL_DEBUG_RADIO(fwrt, "Reading PPAG table v1 (tbl_rev=0)\n"); + goto read_table; + } + +read_table: + fwrt->ppag_ver = tbl_rev; + flags = &wifi_pkg->package.elements[1]; + + if (flags->type != ACPI_TYPE_INTEGER) { + ret = -EINVAL; + goto out_free; + } + + fwrt->ppag_flags = flags->integer.value & ACPI_PPAG_MASK; + + if (!fwrt->ppag_flags) { + ret = 0; + goto out_free; + } + + /* + * read, verify gain values and save them into the PPAG table. + * first sub-band (j=0) corresponds to Low-Band (2.4GHz), and the + * following sub-bands to High-Band (5GHz). + */ + for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { + for (j = 0; j < num_sub_bands; j++) { + union acpi_object *ent; + + ent = &wifi_pkg->package.elements[idx++]; + if (ent->type != ACPI_TYPE_INTEGER) { + ret = -EINVAL; + goto out_free; + } + + fwrt->ppag_chains[i].subbands[j] = ent->integer.value; + + if ((j == 0 && + (fwrt->ppag_chains[i].subbands[j] > ACPI_PPAG_MAX_LB || + fwrt->ppag_chains[i].subbands[j] < ACPI_PPAG_MIN_LB)) || + (j != 0 && + (fwrt->ppag_chains[i].subbands[j] > ACPI_PPAG_MAX_HB || + fwrt->ppag_chains[i].subbands[j] < ACPI_PPAG_MIN_HB))) { + fwrt->ppag_flags = 0; + ret = -EINVAL; + goto out_free; + } + } + } + + + ret = 0; + +out_free: + kfree(data); + return ret; +} +IWL_EXPORT_SYMBOL(iwl_acpi_get_ppag_table); + +int iwl_read_ppag_table(struct iwl_fw_runtime *fwrt, union iwl_ppag_table_cmd *cmd, + int *cmd_size) +{ + u8 cmd_ver; + int i, j, num_sub_bands; + s8 *gain; + + if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) { + IWL_DEBUG_RADIO(fwrt, + "PPAG capability not supported by FW, command not sent.\n"); + return -EINVAL; + } + if (!fwrt->ppag_flags) { + IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n"); + return -EINVAL; + } + + /* The 'flags' field is the same in v1 and in v2 so we can just + * use v1 to access it. + */ + cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); + cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw, + WIDE_ID(PHY_OPS_GROUP, PER_PLATFORM_ANT_GAIN_CMD), + IWL_FW_CMD_VER_UNKNOWN); + if (cmd_ver == 1) { + num_sub_bands = IWL_NUM_SUB_BANDS_V1; + gain = cmd->v1.gain[0]; + *cmd_size = sizeof(cmd->v1); + if (fwrt->ppag_ver == 1 || fwrt->ppag_ver == 2) { + IWL_DEBUG_RADIO(fwrt, + "PPAG table rev is %d but FW supports v1, sending truncated table\n", + fwrt->ppag_ver); + cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); + } + } else if (cmd_ver == 2 || cmd_ver == 3) { + num_sub_bands = IWL_NUM_SUB_BANDS_V2; + gain = cmd->v2.gain[0]; + *cmd_size = sizeof(cmd->v2); + if (fwrt->ppag_ver == 0) { + IWL_DEBUG_RADIO(fwrt, + "PPAG table is v1 but FW supports v2, sending padded table\n"); + } else if (cmd_ver == 2 && fwrt->ppag_ver == 2) { + IWL_DEBUG_RADIO(fwrt, + "PPAG table is v3 but FW supports v2, sending partial bitmap.\n"); + cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); + } + } else { + IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n"); + return -EINVAL; + } + + for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { + for (j = 0; j < num_sub_bands; j++) { + gain[i * num_sub_bands + j] = + fwrt->ppag_chains[i].subbands[j]; + IWL_DEBUG_RADIO(fwrt, + "PPAG table: chain[%d] band[%d]: gain = %d\n", + i, j, gain[i * num_sub_bands + j]); + } + } + + return 0; +} +IWL_EXPORT_SYMBOL(iwl_read_ppag_table); + +bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt) +{ + + if (!dmi_check_system(dmi_ppag_approved_list)) { + IWL_DEBUG_RADIO(fwrt, + "System vendor '%s' is not in the approved list, disabling PPAG.\n", + dmi_get_system_info(DMI_SYS_VENDOR)); + fwrt->ppag_flags = 0; + return false; + } + + return true; +} +IWL_EXPORT_SYMBOL(iwl_acpi_is_ppag_approved); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 089dd90025283..6f361c59106f3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -91,6 +91,8 @@ #define ACPI_PPAG_MAX_LB 24 #define ACPI_PPAG_MIN_HB -16 #define ACPI_PPAG_MAX_HB 40 +#define ACPI_PPAG_MASK 3 +#define IWL_PPAG_ETSI_MASK BIT(0) #define IWL_SAR_ENABLE_MSK BIT(0) #define IWL_REDUCE_POWER_FLAGS_POS 1 @@ -223,6 +225,13 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt); +int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt); + +int iwl_read_ppag_table(struct iwl_fw_runtime *fwrt, union iwl_ppag_table_cmd *cmd, + int *cmd_size); + +bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt); + #else /* CONFIG_ACPI */ static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method) @@ -310,6 +319,22 @@ static inline __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt return 0; } +static inline int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) +{ + return -ENOENT; +} + +static inline int iwl_read_ppag_table(struct iwl_fw_runtime *fwrt, + union iwl_ppag_table_cmd *cmd, int *cmd_size) +{ + return -ENOENT; +} + +static inline bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt) +{ + return false; +} + #endif /* CONFIG_ACPI */ static inline union acpi_object * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index f4de8250696f0..94d291a56e4a6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -25,9 +25,6 @@ #define MVM_UCODE_ALIVE_TIMEOUT (HZ) #define MVM_UCODE_CALIB_TIMEOUT (2 * HZ) -#define IWL_PPAG_MASK 3 -#define IWL_PPAG_ETSI_MASK BIT(0) - #define IWL_TAS_US_MCC 0x5553 #define IWL_TAS_CANADA_MCC 0x4341 @@ -1012,161 +1009,15 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) return iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, len, &cmd); } -static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm) -{ - union acpi_object *wifi_pkg, *data, *flags; - int i, j, ret, tbl_rev, num_sub_bands; - int idx = 2; - - mvm->fwrt.ppag_flags = 0; - - data = iwl_acpi_get_object(mvm->dev, ACPI_PPAG_METHOD); - if (IS_ERR(data)) - return PTR_ERR(data); - - /* try to read ppag table rev 2 or 1 (both have the same data size) */ - wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, - ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev == 1 || tbl_rev == 2) { - num_sub_bands = IWL_NUM_SUB_BANDS_V2; - IWL_DEBUG_RADIO(mvm, - "Reading PPAG table v2 (tbl_rev=%d)\n", - tbl_rev); - goto read_table; - } else { - ret = -EINVAL; - goto out_free; - } - } - - /* try to read ppag table revision 0 */ - wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, - ACPI_PPAG_WIFI_DATA_SIZE_V1, &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 0) { - ret = -EINVAL; - goto out_free; - } - num_sub_bands = IWL_NUM_SUB_BANDS_V1; - IWL_DEBUG_RADIO(mvm, "Reading PPAG table v1 (tbl_rev=0)\n"); - goto read_table; - } - ret = PTR_ERR(wifi_pkg); - goto out_free; - -read_table: - mvm->fwrt.ppag_ver = tbl_rev; - flags = &wifi_pkg->package.elements[1]; - - if (flags->type != ACPI_TYPE_INTEGER) { - ret = -EINVAL; - goto out_free; - } - - mvm->fwrt.ppag_flags = flags->integer.value & IWL_PPAG_MASK; - - if (!mvm->fwrt.ppag_flags) { - ret = 0; - goto out_free; - } - - /* - * read, verify gain values and save them into the PPAG table. - * first sub-band (j=0) corresponds to Low-Band (2.4GHz), and the - * following sub-bands to High-Band (5GHz). - */ - for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { - for (j = 0; j < num_sub_bands; j++) { - union acpi_object *ent; - - ent = &wifi_pkg->package.elements[idx++]; - if (ent->type != ACPI_TYPE_INTEGER) { - ret = -EINVAL; - goto out_free; - } - - mvm->fwrt.ppag_chains[i].subbands[j] = ent->integer.value; - - if ((j == 0 && - (mvm->fwrt.ppag_chains[i].subbands[j] > ACPI_PPAG_MAX_LB || - mvm->fwrt.ppag_chains[i].subbands[j] < ACPI_PPAG_MIN_LB)) || - (j != 0 && - (mvm->fwrt.ppag_chains[i].subbands[j] > ACPI_PPAG_MAX_HB || - mvm->fwrt.ppag_chains[i].subbands[j] < ACPI_PPAG_MIN_HB))) { - mvm->fwrt.ppag_flags = 0; - ret = -EINVAL; - goto out_free; - } - } - } - - ret = 0; -out_free: - kfree(data); - return ret; -} - int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm) { union iwl_ppag_table_cmd cmd; - u8 cmd_ver; - int i, j, ret, num_sub_bands, cmd_size; - s8 *gain; + int ret, cmd_size; - if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) { - IWL_DEBUG_RADIO(mvm, - "PPAG capability not supported by FW, command not sent.\n"); - return 0; - } - if (!mvm->fwrt.ppag_flags) { - IWL_DEBUG_RADIO(mvm, "PPAG not enabled, command not sent.\n"); - return 0; - } - - /* The 'flags' field is the same in v1 and in v2 so we can just - * use v1 to access it. - */ - cmd.v1.flags = cpu_to_le32(mvm->fwrt.ppag_flags); - cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, - WIDE_ID(PHY_OPS_GROUP, PER_PLATFORM_ANT_GAIN_CMD), - IWL_FW_CMD_VER_UNKNOWN); - if (cmd_ver == 1) { - num_sub_bands = IWL_NUM_SUB_BANDS_V1; - gain = cmd.v1.gain[0]; - cmd_size = sizeof(cmd.v1); - if (mvm->fwrt.ppag_ver == 1 || mvm->fwrt.ppag_ver == 2) { - IWL_DEBUG_RADIO(mvm, - "PPAG table rev is %d but FW supports v1, sending truncated table\n", - mvm->fwrt.ppag_ver); - cmd.v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); - } - } else if (cmd_ver == 2 || cmd_ver == 3) { - num_sub_bands = IWL_NUM_SUB_BANDS_V2; - gain = cmd.v2.gain[0]; - cmd_size = sizeof(cmd.v2); - if (mvm->fwrt.ppag_ver == 0) { - IWL_DEBUG_RADIO(mvm, - "PPAG table is v1 but FW supports v2, sending padded table\n"); - } else if (cmd_ver == 2 && mvm->fwrt.ppag_ver == 2) { - IWL_DEBUG_RADIO(mvm, - "PPAG table is v3 but FW supports v2, sending partial bitmap.\n"); - cmd.v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); - } - } else { - IWL_DEBUG_RADIO(mvm, "Unsupported PPAG command version\n"); - return 0; - } + ret = iwl_read_ppag_table(&mvm->fwrt, &cmd, &cmd_size); + if(ret < 0) + return ret; - for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { - for (j = 0; j < num_sub_bands; j++) { - gain[i * num_sub_bands + j] = - mvm->fwrt.ppag_chains[i].subbands[j]; - IWL_DEBUG_RADIO(mvm, - "PPAG table: chain[%d] band[%d]: gain = %d\n", - i, j, gain[i * num_sub_bands + j]); - } - } IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n"); ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP, PER_PLATFORM_ANT_GAIN_CMD), @@ -1178,40 +1029,11 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm) return ret; } -static const struct dmi_system_id dmi_ppag_approved_list[] = { - { .ident = "HP", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - }, - }, - { .ident = "SAMSUNG", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"), - }, - }, - { .ident = "MSFT", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - }, - }, - { .ident = "ASUS", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek COMPUTER INC."), - }, - }, - {} -}; - static int iwl_mvm_ppag_init(struct iwl_mvm *mvm) { /* no need to read the table, done in INIT stage */ - if (!dmi_check_system(dmi_ppag_approved_list)) { - IWL_DEBUG_RADIO(mvm, - "System vendor '%s' is not in the approved list, disabling PPAG.\n", - dmi_get_system_info(DMI_SYS_VENDOR)); - mvm->fwrt.ppag_flags = 0; + if (!(iwl_acpi_is_ppag_approved(&mvm->fwrt))) return 0; - } return iwl_mvm_ppag_send_cmd(mvm); } @@ -1438,7 +1260,7 @@ void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm) int ret; /* read PPAG table */ - ret = iwl_mvm_get_ppag_table(mvm); + ret = iwl_acpi_get_ppag_table(&mvm->fwrt); if (ret < 0) { IWL_DEBUG_RADIO(mvm, "PPAG BIOS table invalid or unavailable. (%d)\n", From 8594ab868799ce78c770498b74fe55ded30def9e Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 4 Mar 2022 13:21:29 +0200 Subject: [PATCH 13/13] iwlwifi: bump FW API to 72 for AX devices Start supporting API version 72 for AX devices. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20220304131517.8de72a8ea67f.I66681363afeb34c619379a5989090264fe6b5f2a@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 8afd5e16e5d85..8ff967edc8f0a 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #include #include @@ -10,7 +10,7 @@ #include "fw/api/txq.h" /* Highest firmware API version supported */ -#define IWL_22000_UCODE_API_MAX 71 +#define IWL_22000_UCODE_API_MAX 72 /* Lowest firmware API version supported */ #define IWL_22000_UCODE_API_MIN 39