From 6cc6ba3a0d9af64bfba573dec385af4302a29700 Mon Sep 17 00:00:00 2001 From: Triebitz Date: Thu, 17 Jan 2019 14:27:20 +0200 Subject: [PATCH 01/28] iwlwifi: pcie: allocate rb_stts's for all queues in one place AX210 devices assume that the (DRAM) addresses of the rb_stts's for the different queues are continuous. So allocate the rb_stts's for all the Rx queues in one place. Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/pcie/internal.h | 9 ++- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 66 ++++++++++++++----- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 0ecd90d050e6..bf8b61a476c5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -8,7 +8,7 @@ * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -526,6 +526,8 @@ struct cont_rec { * @fh_mask: current unmasked fh causes * @hw_mask: current unmasked hw causes * @in_rescan: true if we have triggered a device rescan + * @base_rb_stts: base virtual address of receive buffer status for all queues + * @base_rb_stts_dma: base physical address of receive buffer status */ struct iwl_trans_pcie { struct iwl_rxq *rxq; @@ -617,6 +619,9 @@ struct iwl_trans_pcie { cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES]; u16 tx_cmd_queue_size; bool in_rescan; + + void *base_rb_stts; + dma_addr_t base_rb_stts_dma; }; static inline struct iwl_trans_pcie * diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 38844215a58e..8d4f0628622b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -702,11 +702,6 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, rxq->bd_dma = 0; rxq->bd = NULL; - if (rxq->rb_stts) - dma_free_coherent(trans->dev, - use_rx_td ? sizeof(__le16) : - sizeof(struct iwl_rb_status), - rxq->rb_stts, rxq->rb_stts_dma); rxq->rb_stts_dma = 0; rxq->rb_stts = NULL; @@ -743,6 +738,8 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, int free_size; bool use_rx_td = (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560); + size_t rb_stts_size = use_rx_td ? sizeof(__le16) : + sizeof(struct iwl_rb_status); spin_lock_init(&rxq->lock); if (trans->cfg->mq_rx_supported) @@ -770,12 +767,9 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, goto err; } - /* Allocate the driver's pointer to receive buffer status */ - rxq->rb_stts = dma_alloc_coherent(dev, - use_rx_td ? sizeof(__le16) : sizeof(struct iwl_rb_status), - &rxq->rb_stts_dma, GFP_KERNEL); - if (!rxq->rb_stts) - goto err; + rxq->rb_stts = trans_pcie->base_rb_stts + rxq->id * rb_stts_size; + rxq->rb_stts_dma = + trans_pcie->base_rb_stts_dma + rxq->id * rb_stts_size; if (!use_rx_td) return 0; @@ -805,7 +799,6 @@ err: iwl_pcie_free_rxq_dma(trans, rxq); } - kfree(trans_pcie->rxq); return -ENOMEM; } @@ -815,6 +808,9 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; int i, ret; + size_t rb_stts_size = trans->cfg->device_family >= + IWL_DEVICE_FAMILY_22560 ? + sizeof(__le16) : sizeof(struct iwl_rb_status); if (WARN_ON(trans_pcie->rxq)) return -EINVAL; @@ -822,18 +818,46 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans) trans_pcie->rxq = kcalloc(trans->num_rx_queues, sizeof(struct iwl_rxq), GFP_KERNEL); if (!trans_pcie->rxq) - return -EINVAL; + return -ENOMEM; spin_lock_init(&rba->lock); + /* + * Allocate the driver's pointer to receive buffer status. + * Allocate for all queues continuously (HW requirement). + */ + trans_pcie->base_rb_stts = + dma_alloc_coherent(trans->dev, + rb_stts_size * trans->num_rx_queues, + &trans_pcie->base_rb_stts_dma, + GFP_KERNEL); + if (!trans_pcie->base_rb_stts) { + ret = -ENOMEM; + goto err; + } + for (i = 0; i < trans->num_rx_queues; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; + rxq->id = i; ret = iwl_pcie_alloc_rxq_dma(trans, rxq); if (ret) - return ret; + goto err; } return 0; + +err: + if (trans_pcie->base_rb_stts) { + dma_free_coherent(trans->dev, + rb_stts_size * trans->num_rx_queues, + trans_pcie->base_rb_stts, + trans_pcie->base_rb_stts_dma); + trans_pcie->base_rb_stts = NULL; + trans_pcie->base_rb_stts_dma = 0; + } + kfree(trans_pcie->rxq); + + return ret; } static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) @@ -1042,8 +1066,6 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans) for (i = 0; i < trans->num_rx_queues; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; - rxq->id = i; - spin_lock(&rxq->lock); /* * Set read write pointer to reflect that we have processed @@ -1130,6 +1152,9 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; int i; + size_t rb_stts_size = trans->cfg->device_family >= + IWL_DEVICE_FAMILY_22560 ? + sizeof(__le16) : sizeof(struct iwl_rb_status); /* * if rxq is NULL, it means that nothing has been allocated, @@ -1144,6 +1169,15 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) iwl_pcie_free_rbs_pool(trans); + if (trans_pcie->base_rb_stts) { + dma_free_coherent(trans->dev, + rb_stts_size * trans->num_rx_queues, + trans_pcie->base_rb_stts, + trans_pcie->base_rb_stts_dma); + trans_pcie->base_rb_stts = NULL; + trans_pcie->base_rb_stts_dma = 0; + } + for (i = 0; i < trans->num_rx_queues; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; From 1e78e759bed84cc55e08cc10988287464a49747f Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Sun, 20 Jan 2019 17:45:16 +0200 Subject: [PATCH 02/28] iwlwifi: mvm: Don't request HW restart if already requested In case mac80211 was requested to perform an HW restart, but the HW restart has not started yet, there is no need to request another one. Signed-off-by: Ilan Peer Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 33053d136a8c..0996c97c4b94 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1320,6 +1320,9 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) reprobe->dev = mvm->trans->dev; INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); schedule_work(&reprobe->work); + } else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, + &mvm->status)) { + IWL_ERR(mvm, "HW restart already requested, but not started\n"); } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR && mvm->hw_registered && !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) { From e8698301f2c13ea4b0e78f2ed8a15b244ee3649b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 10 Dec 2018 21:39:06 +0100 Subject: [PATCH 03/28] iwlwifi: fix false-positive maybe-uninitialized warning With CONFIG_NO_AUTO_INLINE, we run into a silly warning when gcc fails to remember that n_profiles is constant across the function call to iwl_mvm_sar_set_profile: drivers/net/wireless/intel/iwlwifi/mvm/fw.c: In function 'iwl_mvm_sar_get_ewrd_table': drivers/net/wireless/intel/iwlwifi/mvm/fw.c:746:9: error: 'ret' may be used uninitialized in this function [-Werror=maybe-uninitialized] Marking that function 'inline' avoids the warning. Signed-off-by: Arnd Bergmann Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 1bc51e3260eb..00a47f6f1d81 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -646,10 +646,10 @@ static int iwl_mvm_config_ltr(struct iwl_mvm *mvm) } #ifdef CONFIG_ACPI -static int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm, - union acpi_object *table, - struct iwl_mvm_sar_profile *profile, - bool enabled) +static inline int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm, + union acpi_object *table, + struct iwl_mvm_sar_profile *profile, + bool enabled) { int i; From 9178aa7c465440bae84a0de002d919ad7034a08a Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 8 Jan 2019 11:17:38 -0600 Subject: [PATCH 04/28] iwlwifi: eeprom-parse: use struct_size() in kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; void *entry[]; }; instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c index 75940ac406b9..04338c3a6205 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c @@ -850,8 +850,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, if (WARN_ON(!cfg || !cfg->eeprom_params)) return NULL; - data = kzalloc(sizeof(*data) + - sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, + data = kzalloc(struct_size(data, channels, IWL_NUM_CHANNELS), GFP_KERNEL); if (!data) return NULL; From 6b367c9f88b0813f6a557e688b665324499a159e Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 8 Jan 2019 11:55:19 -0600 Subject: [PATCH 05/28] iwlwifi: nvm-parse: use struct_size() in kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; void *entry[]; }; instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 503860a2b36d..ca6a243d704b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -946,15 +946,13 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, const __le16 *ch_section; if (cfg->nvm_type != IWL_NVM_EXT) - data = kzalloc(sizeof(*data) + - sizeof(struct ieee80211_channel) * - IWL_NVM_NUM_CHANNELS, - GFP_KERNEL); + data = kzalloc(struct_size(data, channels, + IWL_NVM_NUM_CHANNELS), + GFP_KERNEL); else - data = kzalloc(sizeof(*data) + - sizeof(struct ieee80211_channel) * - IWL_NVM_NUM_CHANNELS_EXT, - GFP_KERNEL); + data = kzalloc(struct_size(data, channels, + IWL_NVM_NUM_CHANNELS_EXT), + GFP_KERNEL); if (!data) return NULL; @@ -1441,9 +1439,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans, if (empty_otp) IWL_INFO(trans, "OTP is empty\n"); - nvm = kzalloc(sizeof(*nvm) + - sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, - GFP_KERNEL); + nvm = kzalloc(struct_size(nvm, channels, IWL_NUM_CHANNELS), GFP_KERNEL); if (!nvm) { ret = -ENOMEM; goto out; From de645e8992ef79a952cd5c7ca728f44c1c6b7ee6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 24 Jan 2019 13:26:28 +0100 Subject: [PATCH 06/28] iwlwifi: mvm: fix error path in iwl_mvm_mac_setup_register() The IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE bit shouldn't be set, and realistically we should complete all setup before we call the ieee80211_register_hw() function. Fix this. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index a3bbf2ce571f..a585ee509987 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -796,16 +796,19 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->netdev_features |= IWL_TX_CSUM_NETIF_FLAGS; } - ret = ieee80211_register_hw(mvm->hw); - if (ret) - iwl_mvm_leds_exit(mvm); - mvm->init_status |= IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE; - if (mvm->cfg->vht_mu_mimo_supported) wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER); - return ret; + ret = ieee80211_register_hw(mvm->hw); + if (ret) { + iwl_mvm_leds_exit(mvm); + return ret; + } + + mvm->init_status |= IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE; + + return 0; } static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm, From 7691fa6947374f2a0c3a17ae664fe258db508ae2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 24 Jan 2019 11:14:13 +0100 Subject: [PATCH 07/28] iwlwifi: nvm-parse: advertise IEEE80211_VHT_EXT_NSS_BW_CAPABLE in VHT We support this, so we should advertise it. In fact, if we don't, mac80211 will do it for us (as we advertise SUPPORTS_VHT_EXT_NSS_BW to it), but that requires a memory reallocation which is wasteful: ieee80211 phy0: copying sband (band 1) due to VHT EXT NSS BW flag Set the flag here to avoid that. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index ca6a243d704b..65228a092bd6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -8,7 +8,7 @@ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -463,6 +463,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, } vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; + + vht_cap->vht_mcs.tx_highest |= + cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE); } static struct ieee80211_sband_iftype_data iwl_he_capa[] = { From 84caa1dd0092e7e57bd39df0e1b8791c7a756103 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:19 +0100 Subject: [PATCH 08/28] iwlwifi: dvm: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Johannes Berg Cc: Emmanuel Grumbach Cc: Luca Coelho Cc: Intel Linux Wireless Cc: Kalle Valo Cc: linux-wireless@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/dvm/agn.h | 9 ++-- .../net/wireless/intel/iwlwifi/dvm/debugfs.c | 44 ++----------------- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 5 +-- 3 files changed, 8 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h index 431e13c6ee35..254a5ce52456 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h @@ -439,13 +439,10 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state) } #ifdef CONFIG_IWLWIFI_DEBUGFS -int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir); +void iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir); #else -static inline int iwl_dbgfs_register(struct iwl_priv *priv, - struct dentry *dbgfs_dir) -{ - return 0; -} +static inline void iwl_dbgfs_register(struct iwl_priv *priv, + struct dentry *dbgfs_dir) { } #endif /* CONFIG_IWLWIFI_DEBUGFS */ #ifdef CONFIG_IWLWIFI_DEBUG diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index e64cdafc5623..d4b19673b06a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c @@ -37,31 +37,8 @@ /* create and remove of files */ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ - if (!debugfs_create_file(#name, mode, parent, priv, \ - &iwl_dbgfs_##name##_ops)) \ - goto err; \ -} while (0) - -#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ - struct dentry *__tmp; \ - __tmp = debugfs_create_bool(#name, 0600, parent, ptr); \ - if (IS_ERR(__tmp) || !__tmp) \ - goto err; \ -} while (0) - -#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ - struct dentry *__tmp; \ - __tmp = debugfs_create_x32(#name, 0600, parent, ptr); \ - if (IS_ERR(__tmp) || !__tmp) \ - goto err; \ -} while (0) - -#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \ - struct dentry *__tmp; \ - __tmp = debugfs_create_u32(#name, mode, \ - parent, ptr); \ - if (IS_ERR(__tmp) || !__tmp) \ - goto err; \ + debugfs_create_file(#name, mode, parent, priv, \ + &iwl_dbgfs_##name##_ops); \ } while (0) /* file operation */ @@ -2348,21 +2325,15 @@ DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); * Create the debugfs files and directories * */ -int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) +void iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) { struct dentry *dir_data, *dir_rf, *dir_debug; priv->debugfs_dir = dbgfs_dir; dir_data = debugfs_create_dir("data", dbgfs_dir); - if (!dir_data) - goto err; dir_rf = debugfs_create_dir("rf", dbgfs_dir); - if (!dir_rf) - goto err; dir_debug = debugfs_create_dir("debug", dbgfs_dir); - if (!dir_debug) - goto err; DEBUGFS_ADD_FILE(nvm, dir_data, 0400); DEBUGFS_ADD_FILE(sram, dir_data, 0600); @@ -2422,13 +2393,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) snprintf(buf, 100, "../../%pd2", dev_dir); - if (!debugfs_create_symlink("iwlwifi", mac80211_dir, buf)) - goto err; + debugfs_create_symlink("iwlwifi", mac80211_dir, buf); } - - return 0; - -err: - IWL_ERR(priv, "failed to create the dvm debugfs entries\n"); - return -ENOMEM; } diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 114f0ab022a7..7c68a86ed9e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1509,13 +1509,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, if (iwlagn_mac_setup_register(priv, &fw->ucode_capa)) goto out_destroy_workqueue; - if (iwl_dbgfs_register(priv, dbgfs_dir)) - goto out_mac80211_unregister; + iwl_dbgfs_register(priv, dbgfs_dir); return op_mode; -out_mac80211_unregister: - iwlagn_mac_unregister(priv); out_destroy_workqueue: iwl_tt_exit(priv); iwl_cancel_deferred_work(priv); From 5987dfde6f555248f4b6c83147ec9bc877cd6f4c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:21 +0100 Subject: [PATCH 09/28] iwlwifi: fw: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Johannes Berg Cc: Emmanuel Grumbach Cc: Luca Coelho Cc: Intel Linux Wireless Cc: Kalle Valo Cc: linux-wireless@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 11 +++-------- drivers/net/wireless/intel/iwlwifi/fw/debugfs.h | 9 +++------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index 3e120dd47305..c1aa4360736b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -173,9 +173,8 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ _FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_fw_runtime) #define FWRT_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \ - if (!debugfs_create_file(alias, mode, parent, fwrt, \ - &iwl_dbgfs_##name##_ops)) \ - goto err; \ + debugfs_create_file(alias, mode, parent, fwrt, \ + &iwl_dbgfs_##name##_ops); \ } while (0) #define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \ FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) @@ -321,14 +320,10 @@ out: FWRT_DEBUGFS_WRITE_FILE_OPS(send_hcmd, 512); -int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, +void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, struct dentry *dbgfs_dir) { INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk); FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, 0200); FWRT_DEBUGFS_ADD_FILE(send_hcmd, dbgfs_dir, 0200); - return 0; -err: - IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n"); - return -ENOMEM; } diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h index 88255035e8ef..fde40ff88451 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h @@ -63,14 +63,11 @@ #include "runtime.h" #ifdef CONFIG_IWLWIFI_DEBUGFS -int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, +void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, struct dentry *dbgfs_dir); #else -static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, - struct dentry *dbgfs_dir) -{ - return 0; -} +static inline void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, + struct dentry *dbgfs_dir) { } #endif /* CONFIG_IWLWIFI_DEBUGFS */ From dc475ae9c00a83c4b29d165689ea5f7813f6ea99 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Jan 2019 16:21:22 +0100 Subject: [PATCH 10/28] iwlwifi: iwl-drv: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Cc: Johannes Berg Cc: Emmanuel Grumbach Cc: Luca Coelho Cc: Intel Linux Wireless Cc: Kalle Valo Cc: linux-wireless@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 22 -------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 4b75a93c7364..689a65b11cc3 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1253,11 +1253,6 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) #ifdef CONFIG_IWLWIFI_DEBUGFS drv->dbgfs_op_mode = debugfs_create_dir(op->name, drv->dbgfs_drv); - if (!drv->dbgfs_op_mode) { - IWL_ERR(drv, - "failed to create opmode debugfs directory\n"); - return op_mode; - } dbgfs_dir = drv->dbgfs_op_mode; #endif @@ -1620,20 +1615,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev), iwl_dbgfs_root); - if (!drv->dbgfs_drv) { - IWL_ERR(drv, "failed to create debugfs directory\n"); - ret = -ENOMEM; - goto err_free_tlv; - } - /* Create transport layer debugfs dir */ drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); - - if (!drv->trans->dbgfs_dir) { - IWL_ERR(drv, "failed to create transport debugfs directory\n"); - ret = -ENOMEM; - goto err_free_dbgfs; - } #endif ret = iwl_request_firmware(drv, true); @@ -1646,9 +1629,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) err_fw: #ifdef CONFIG_IWLWIFI_DEBUGFS -err_free_dbgfs: debugfs_remove_recursive(drv->dbgfs_drv); -err_free_tlv: iwl_fw_dbg_free(drv->trans); #endif kfree(drv); @@ -1759,9 +1740,6 @@ static int __init iwl_drv_init(void) #ifdef CONFIG_IWLWIFI_DEBUGFS /* Create the root of iwlwifi debugfs subsystem. */ iwl_dbgfs_root = debugfs_create_dir(DRV_NAME, NULL); - - if (!iwl_dbgfs_root) - return -EFAULT; #endif return iwl_pci_register_driver(); From 90a128291ded5f86a730729f74d6b2f0e8f668df Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Sun, 27 Jan 2019 11:24:30 +0200 Subject: [PATCH 11/28] iwlwifi: mvm: reject new beacons when in inject mode Verify we do not accept new beacon templates while beacon injection is active. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 7 +++++-- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 5 +++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 80b0b2ed69bb..05a6db2db478 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -8,7 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1238,6 +1238,8 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len) goto out_err; } + mvm->beacon_inject_active = true; + mvmvif = iwl_mvm_vif_from_mac80211(vif); info = IEEE80211_SKB_CB(beacon); rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); @@ -1287,6 +1289,7 @@ static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm, int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0); mvm->hw->extra_beacon_tailroom = 0; + mvm->beacon_inject_active = false; return ret ?: count; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 9bd4376cad9b..003a20630252 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1041,6 +1041,11 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, if (!beacon) return -ENOMEM; +#ifdef CONFIG_IWLWIFI_DEBUGFS + if (mvm->beacon_inject_active) + return -EBUSY; +#endif + ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon); dev_kfree_skb(beacon); return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 9993337a2bbd..acb4cca5bdcf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -978,6 +978,7 @@ struct iwl_mvm { u32 dbgfs_prph_reg_addr; bool disable_power_off; bool disable_power_off_d3; + bool beacon_inject_active; bool scan_iter_notif_enabled; From 8bf52e0ab3d6c4c64295250382fcff2d9d3fed6a Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Tue, 15 Jan 2019 13:38:30 +0200 Subject: [PATCH 12/28] iwlwifi: mvm: add read debugfs for he_sniffer_params Return the AID currently set when reading this debugfs entry. Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 25 +++++++++++++++++-- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 05a6db2db478..776b24f54200 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1789,6 +1789,7 @@ iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf, struct iwl_mvm_sniffer_apply { struct iwl_mvm *mvm; + u8 *bssid; u16 aid; }; @@ -1798,6 +1799,8 @@ static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data, struct iwl_mvm_sniffer_apply *apply = data; apply->mvm->cur_aid = cpu_to_le16(apply->aid); + memcpy(apply->mvm->cur_bssid, apply->bssid, + sizeof(apply->mvm->cur_bssid)); return true; } @@ -1830,6 +1833,7 @@ iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf, he_mon_cmd.aid = cpu_to_le16(aid); apply.aid = aid; + apply.bssid = (void *)he_mon_cmd.bssid; mutex_lock(&mvm->mutex); @@ -1858,6 +1862,23 @@ iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf, return ret ?: count; } +static ssize_t +iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + u8 buf[32]; + int len; + + len = scnprintf(buf, sizeof(buf), + "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", + le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0], + mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3], + mvm->cur_bssid[4], mvm->cur_bssid[5]); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + static ssize_t iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1928,7 +1949,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8); MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile); #endif -MVM_DEBUGFS_WRITE_FILE_OPS(he_sniffer_params, 32); +MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32); static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -2119,7 +2140,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) #ifdef CONFIG_ACPI MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400); #endif - MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0200); + MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600); if (!debugfs_create_bool("enable_scan_iteration_notif", 0600, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index acb4cca5bdcf..148aee1ad79d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1176,6 +1176,7 @@ struct iwl_mvm { /* sniffer data to include in radiotap */ __le16 cur_aid; + u8 cur_bssid[ETH_ALEN]; #ifdef CONFIG_ACPI struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM]; From 503863055d9eff82a985739a73f13337fe9580ba Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Tue, 29 Jan 2019 11:53:03 +0200 Subject: [PATCH 13/28] iwlwifi: mvm: support non-transmitting AP Add an option to not send beacons and probe responses. This is used for testing multiple-bssid. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 3 +++ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 10 ++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h index 6a3edea3d580..dff14f1ec55f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h @@ -117,6 +117,7 @@ #define IWL_MVM_TCM_LOWLAT_ENABLE_THRESH 100 /* packets/10 seconds */ #define IWL_MVM_UAPSD_NONAGG_PERIOD 5000 /* msecs */ #define IWL_MVM_UAPSD_NOAGG_LIST_LEN IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM +#define IWL_MVM_NON_TRANSMITTING_AP 0 #define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 003a20630252..6a70dece447d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1016,6 +1016,9 @@ int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, if (WARN_ON(!beacon)) return -EINVAL; + if (IWL_MVM_NON_TRANSMITTING_AP) + return 0; + if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD)) return iwl_mvm_mac_ctxt_send_beacon_v6(mvm, vif, beacon); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index ac62eb8c4b36..898bfda93029 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -8,7 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -719,6 +719,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) IEEE80211_TX_CTL_TX_OFFCHAN; int queue = -1; + if (IWL_MVM_NON_TRANSMITTING_AP && ieee80211_is_probe_resp(fc)) + return -1; + memcpy(&info, skb->cb, sizeof(info)); if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU)) @@ -1078,6 +1081,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, fc = hdr->frame_control; hdrlen = ieee80211_hdrlen(fc); + if (IWL_MVM_NON_TRANSMITTING_AP && ieee80211_is_probe_resp(fc)) + return -1; + if (WARN_ON_ONCE(!mvmsta)) return -1; From a371bb646ff72f7ea13bdb920b2353b34f9d45b5 Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Tue, 29 Jan 2019 20:38:48 +0200 Subject: [PATCH 14/28] iwlwifi: mvm: Set TX_CMD_FLG_PROT_REQUIRE correctly Previously the protection flag wasn't set on multicast frames even if the RA is unicast. Fix this by checking addr1 instead. Signed-off-by: Andrei Otcheretianski Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 898bfda93029..b82b2f062c95 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -278,7 +278,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, } if (ieee80211_is_data(fc) && len > mvm->rts_threshold && - !is_multicast_ether_addr(ieee80211_get_DA(hdr))) + !is_multicast_ether_addr(hdr->addr1)) tx_flags |= TX_CMD_FLG_PROT_REQUIRE; if (fw_has_capa(&mvm->fw->ucode_capa, From cad7eb754dbd8e921e481b0a41ee0596016afa2f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 29 Jan 2019 13:23:05 +0100 Subject: [PATCH 15/28] iwlwifi: mvm: remove IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE There's no point in this, we already do everything in a nested fashion, and if we didn't we'd already crash in iwl_mvm_leds_exit() etc. Just remove the bit. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 +---- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 +---- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index a585ee509987..24556a7cd29c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -803,12 +803,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) ret = ieee80211_register_hw(mvm->hw); if (ret) { iwl_mvm_leds_exit(mvm); - return ret; } - mvm->init_status |= IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE; - - return 0; + return ret; } static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 148aee1ad79d..bca6f6b536d9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1221,7 +1221,6 @@ enum iwl_mvm_status { enum iwl_mvm_init_status { IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE = BIT(0), IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE = BIT(1), - IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE = BIT(2), }; static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 0996c97c4b94..ba27dce4c2bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -919,10 +919,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) iwl_mvm_thermal_exit(mvm); - if (mvm->init_status & IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE) { - ieee80211_unregister_hw(mvm->hw); - mvm->init_status &= ~IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE; - } + ieee80211_unregister_hw(mvm->hw); kfree(mvm->scan_cmd); kfree(mvm->mcast_filter_cmd); From 8c739d8d7935e87bf68a0f8cefa6a947f787d642 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Mon, 28 Jan 2019 13:32:52 +0200 Subject: [PATCH 16/28] iwlwifi: mvm: Allow retries for probe responses When hostapd sends a probe response, it does not request an acknowledgment on the probe response. This setting is propagated to the driver and FW from mac80211, and as a result probe responses are transmitted only once without retries. In congested environments, this reduces the likelihood for finding the AP. To overcome this, enable acknowledgment and retries for probe responses, even in case no acknowledgment is requested. In such a case the retry limit is set to 3. Signed-off-by: Ilan Peer Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index b82b2f062c95..d01998853d1f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -209,7 +209,9 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, u16 offload_assist = 0; u8 ac; - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) || + (ieee80211_is_probe_resp(fc) && + !is_multicast_ether_addr(hdr->addr1))) tx_flags |= TX_CMD_FLG_ACK; else tx_flags &= ~TX_CMD_FLG_ACK; From a53b2a0b1245d70430a8b541d76666b585346882 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 24 Jan 2019 12:22:41 +0100 Subject: [PATCH 17/28] iwlwifi: mvm: implement VHT extended NSS support in rs.c For non-offloaded rate control, implement VHT extended NSS support by just ignoring 160 MHz on transmit if the peer doesn't support the full NSS (2). This is pretty unlikely and gets us 160 MHz RX as well as TX in most cases, since the typical case for this workaround is 4x4 AP only doing 2x2 on 160 MHz. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 23 +++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 2d7a089d93a3..e231a44d2423 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3,7 +3,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -1643,8 +1643,26 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm, static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta) { + struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->vht_cap; + struct ieee80211_vht_cap vht_cap = { + .vht_cap_info = cpu_to_le32(sta_vht_cap->cap), + .supp_mcs = sta_vht_cap->vht_mcs, + }; + switch (sta->bandwidth) { case IEEE80211_STA_RX_BW_160: + /* + * Don't use 160 MHz if VHT extended NSS support + * says we cannot use 2 streams, we don't want to + * deal with this. + * We only check MCS 0 - they will support that if + * we got here at all and we don't care which MCS, + * we want to determine a more global state. + */ + if (ieee80211_get_vht_max_nss(&vht_cap, + IEEE80211_VHT_CHANWIDTH_160MHZ, + 0, true) < sta->rx_nss) + return RATE_MCS_CHAN_WIDTH_80; return RATE_MCS_CHAN_WIDTH_160; case IEEE80211_STA_RX_BW_80: return RATE_MCS_CHAN_WIDTH_80; @@ -1796,7 +1814,7 @@ static bool rs_tweak_rate_tbl(struct iwl_mvm *mvm, struct iwl_scale_tbl_info *tbl, enum rs_action scale_action) { - if (sta->bandwidth != IEEE80211_STA_RX_BW_80) + if (rs_bw_from_sta_bw(sta) != RATE_MCS_CHAN_WIDTH_80) return false; if (!is_vht_siso(&tbl->rate)) @@ -4127,6 +4145,7 @@ static const struct rate_control_ops rs_mvm_ops_drv = { .add_sta_debugfs = rs_drv_add_sta_debugfs, .remove_sta_debugfs = rs_remove_sta_debugfs, #endif + .capa = RATE_CTRL_CAPA_VHT_EXT_NSS_BW, }; void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, From 714afd35065b6b5ad5a384d7401a82a3db50a477 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Wed, 23 Jan 2019 11:31:58 +0200 Subject: [PATCH 18/28] iwlwifi: remove redundant condition from prior alive dump flow After the FW image was loaded for the first time, fwrt->smem_cfg.num_lmacs value will no longer be zero since we don't clean it when we stop the device. So if we load the image once and then we fail on a consecutive attempt, the driver will abort any dumping. Solve this by removing the condition. It is safe to remove since when we do the actual dumping in iwl_fw_dbg_collect_sync we check that STATUS_DEVICE_ENABLED bit is still active. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 202f96e9ca0c..b189a605ec13 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1592,22 +1592,6 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, bool monitor_only, unsigned int delay) { - /* - * If the loading of the FW completed successfully, the next step is to - * get the SMEM config data. Thus, if fwrt->smem_cfg.num_lmacs is non - * zero, the FW was already loaded successully. If the state is "NO_FW" - * in such a case - exit, since FW may be dead. Otherwise, we - * can try to collect the data, since FW might just not be fully - * loaded (no "ALIVE" yet), and the debug data is accessible. - * - * Corner case: got the FW alive but crashed before getting the SMEM - * config. In such a case, due to HW access problems, we might - * collect garbage. - */ - if (fwrt->trans->state == IWL_TRANS_NO_FW && - fwrt->smem_cfg.num_lmacs) - return -EIO; - if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status)) return -EBUSY; From f50d693b9fbe1d533e29cf470ebe51140c5c0b13 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Mon, 28 Jan 2019 15:12:08 +0200 Subject: [PATCH 19/28] iwlwifi: mvm: add some debug data to TX path This helps debugging when things go wrong. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 8 +++++++- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 11 +++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 24556a7cd29c..f8928ba1f338 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -941,8 +941,14 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq) IWL_PLAT_PM_MODE_DISABLED))) { skb = ieee80211_tx_dequeue(hw, txq); - if (!skb) + if (!skb) { + if (txq->sta) + IWL_DEBUG_TX(mvm, + "TXQ of sta %pM tid %d is now empty\n", + txq->sta->addr, + txq->tid); break; + } if (!txq->sta) iwl_mvm_tx_skb_non_sta(mvm, skb); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index d01998853d1f..0c2aabc842f9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1115,12 +1115,14 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, */ if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { tid = ieee80211_get_tid(hdr); - if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) + if (WARN_ONCE(tid >= IWL_MAX_TID_COUNT, "Invalid TID %d", tid)) goto drop_unlock_sta; is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU; - if (WARN_ON_ONCE(is_ampdu && - mvmsta->tid_data[tid].state != IWL_AGG_ON)) + if (WARN_ONCE(is_ampdu && + mvmsta->tid_data[tid].state != IWL_AGG_ON, + "Invalid internal agg state %d for TID %d", + mvmsta->tid_data[tid].state, tid)) goto drop_unlock_sta; seq_number = mvmsta->tid_data[tid].seq_number; @@ -1142,7 +1144,7 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); - if (WARN_ON_ONCE(txq_id == IWL_MVM_INVALID_QUEUE)) { + if (WARN_ONCE(txq_id == IWL_MVM_INVALID_QUEUE, "Invalid TXQ id")) { iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); spin_unlock(&mvmsta->lock); return 0; @@ -1192,6 +1194,7 @@ drop_unlock_sta: iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); spin_unlock(&mvmsta->lock); drop: + IWL_DEBUG_TX(mvm, "TX to [%d|%d] dropped\n", mvmsta->sta_id, tid); return -1; } From 00276722194658d8e33e370845a198db42f8033f Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 29 Jan 2019 09:51:44 +0200 Subject: [PATCH 20/28] iwlwifi: dbg_ini: fix infinite time ignore consecutive dumps The driver sets ignore_consec to -1 which is 0xffffffff in u32 so when iwl_fw_ini_trigger_on is called, it will always return false and each trigger could be used only once. Solve this by removing the assignment to -1. Signed-off-by: Shahar S Matityahu Fixes: fe1b7d6c2888 ("iwlwifi: add support for triggering ini triggers") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index b189a605ec13..5e5c4e8c4a69 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2093,8 +2093,6 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, /* Since zero means infinity - just set to -1 */ if (!le32_to_cpu(active->trig->occurrences)) active->trig->occurrences = cpu_to_le32(-1); - if (!le32_to_cpu(active->trig->ignore_consec)) - active->trig->ignore_consec = cpu_to_le32(-1); active->active = true; next: From 05841faa8567fccf3bf9c223267ec76a3a040cef Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 27 Jan 2019 11:34:05 +0200 Subject: [PATCH 21/28] iwlwifi: dbg_ini: add print to iwl_dump_ini_mem in case of invalid range Add informative print in case the range is not available. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 5e5c4e8c4a69..e4e50d598377 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1300,14 +1300,18 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, memcpy(header->name, reg->name, le32_to_cpu(header->name_len)); range = ops->fill_mem_hdr(fwrt, header); - if (!range) + if (!range) { + IWL_ERR(fwrt, "Failed to fill region header: id=%d, type=%d\n", + le32_to_cpu(reg->region_id), type); return; + } for (i = 0; i < num_of_ranges; i++) { int range_data_size = ops->fill_range(fwrt, range, reg, i); if (range_data_size < 0) { - IWL_ERR(fwrt, "Failed to dump region type %d\n", type); + IWL_ERR(fwrt, "Failed to dump region: id=%d, type=%d\n", + le32_to_cpu(reg->region_id), type); return; } range = ((void *)range) + sizeof(*range) + range_data_size; From 01e591c9f42aa3ee0440e7547ecdad8009cfaf61 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 28 Jan 2019 11:02:30 +0200 Subject: [PATCH 22/28] iwlwifi: dbg_ini: make memory dump get_size handler include headers Make the get size handler of iwl_dump_ini_mem_ops include the total size of the region. It is needed for fifos dumping. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 106 ++++++++++---------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index e4e50d598377..5a98eb0d5c00 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1187,41 +1187,6 @@ static struct iwl_fw_ini_error_dump_range return mon_dump->ranges; } -static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg) -{ - return le32_to_cpu(reg->internal.num_of_ranges) * - le32_to_cpu(reg->internal.range_data_size); -} - -static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg) -{ - int i; - u32 size = 0; - - for (i = 0; i < fwrt->trans->init_dram.paging_cnt; i++) - size += fwrt->trans->init_dram.paging[i].size; - return size; -} - -static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg) -{ - int i; - u32 size = 0; - - for (i = 1; i <= fwrt->num_of_paging_blk; i++) - size += fwrt->fw_paging_db[i].fw_paging_size; - return size; -} - -static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg) -{ - return fwrt->trans->num_blocks ? fwrt->trans->fw_mon[0].size : 0; -} - static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { @@ -1246,10 +1211,57 @@ static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt, return 1; } +static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + return sizeof(struct iwl_fw_ini_error_dump) + + iwl_dump_ini_mem_ranges(fwrt, reg) * + (sizeof(struct iwl_fw_ini_error_dump_range) + + le32_to_cpu(reg->internal.range_data_size)); +} + +static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + int i; + u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range); + u32 size = sizeof(struct iwl_fw_ini_error_dump); + + for (i = 0; i < iwl_dump_ini_paging_gen2_ranges(fwrt, reg); i++) + size += range_header_len + + fwrt->trans->init_dram.paging[i].size; + + return size; +} + +static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + int i; + u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range); + u32 size = sizeof(struct iwl_fw_ini_error_dump); + + for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++) + size += range_header_len + fwrt->fw_paging_db[i].fw_paging_size; + + return size; +} + +static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + u32 size = sizeof(struct iwl_fw_ini_monitor_dram_dump); + + if (fwrt->trans->num_blocks) + size += fwrt->trans->fw_mon[0].size; + + return size; +} + /** * struct iwl_dump_ini_mem_ops - ini memory dump operations * @get_num_of_ranges: returns the number of memory ranges in the region. - * @get_size: returns the size of the region data without headers. + * @get_size: returns the total size of the region. * @fill_mem_hdr: fills region type specific headers and returns the first * range or NULL if failed to fill headers. * @fill_range: copies a given memory range into the dump. @@ -1291,8 +1303,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, num_of_ranges = ops->get_num_of_ranges(fwrt, reg); (*data)->type = cpu_to_le32(type | INI_DUMP_BIT); - (*data)->len = cpu_to_le32(sizeof(*header) + num_of_ranges * - sizeof(*range) + ops->get_size(fwrt, reg)); + (*data)->len = cpu_to_le32(ops->get_size(fwrt, reg)); header->num_of_ranges = cpu_to_le32(num_of_ranges); header->name_len = cpu_to_le32(min_t(int, IWL_FW_INI_MAX_NAME, @@ -1323,8 +1334,6 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_trigger *trigger) { int i, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data); - u32 dump_header_len = sizeof(struct iwl_fw_ini_error_dump); - u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range); if (!trigger || !trigger->num_regions) return 0; @@ -1349,9 +1358,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, case IWL_FW_INI_REGION_PERIPHERY_AUX: case IWL_FW_INI_REGION_INTERNAL_BUFFER: case IWL_FW_INI_REGION_CSR: - size += hdr_len + dump_header_len + range_header_len * - iwl_dump_ini_mem_ranges(fwrt, reg) + - iwl_dump_ini_mem_get_size(fwrt, reg); + size += hdr_len + iwl_dump_ini_mem_get_size(fwrt, reg); break; case IWL_FW_INI_REGION_TXF: size += iwl_fw_txf_len(fwrt, &fwrt->smem_cfg); @@ -1360,16 +1367,11 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg); break; case IWL_FW_INI_REGION_PAGING: { - size += hdr_len + dump_header_len; + size += hdr_len; if (iwl_fw_dbg_is_paging_enabled(fwrt)) { - size += range_header_len * - iwl_dump_ini_paging_ranges(fwrt, reg) + - iwl_dump_ini_paging_get_size(fwrt, reg); + size += iwl_dump_ini_paging_get_size(fwrt, reg); } else { - size += range_header_len * - iwl_dump_ini_paging_gen2_ranges(fwrt, - reg) + - iwl_dump_ini_paging_gen2_get_size(fwrt, + size += iwl_dump_ini_paging_gen2_get_size(fwrt, reg); } break; @@ -1378,8 +1380,6 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, if (!fwrt->trans->num_blocks) break; size += hdr_len + - sizeof(struct iwl_fw_ini_monitor_dram_dump) * - iwl_dump_ini_mon_dram_ranges(fwrt, reg) + iwl_dump_ini_mon_dram_get_size(fwrt, reg); break; case IWL_FW_INI_REGION_DRAM_IMR: From 1a6c8bb7f84c8f75e0fb16726186a8ec314a0010 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 28 Jan 2019 11:03:45 +0200 Subject: [PATCH 23/28] iwlwifi: dbg_ini: make fill_range handler accept generic range pointer Make fill_range handler of iwl_dump_ini_mem_ops accept a generic range pointer. It is needed for future support in fifos dumping. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 53 +++++++++++---------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 5a98eb0d5c00..b86691fdacb3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1044,10 +1044,10 @@ out: } static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_error_dump_range *range, struct iwl_fw_ini_region_cfg *reg, - int idx) + void *range_ptr, int idx) { + struct iwl_fw_ini_error_dump_range *range = range_ptr; __le32 *val = range->data; u32 addr, prph_val, offset = le32_to_cpu(reg->offset); int i; @@ -1061,14 +1061,15 @@ static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt, return -1; *val++ = cpu_to_le32(prph_val); } - return le32_to_cpu(range->range_data_size); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); } static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_error_dump_range *range, struct iwl_fw_ini_region_cfg *reg, - int idx) + void *range_ptr, int idx) { + struct iwl_fw_ini_error_dump_range *range = range_ptr; __le32 *val = range->data; u32 addr, offset = le32_to_cpu(reg->offset); int i; @@ -1080,14 +1081,15 @@ static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt, *val++ = cpu_to_le32(iwl_trans_read32(fwrt->trans, addr + offset)); } - return le32_to_cpu(range->range_data_size); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); } static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_error_dump_range *range, struct iwl_fw_ini_region_cfg *reg, - int idx) + void *range_ptr, int idx) { + struct iwl_fw_ini_error_dump_range *range = range_ptr; u32 addr = le32_to_cpu(range->start_addr); u32 offset = le32_to_cpu(reg->offset); @@ -1095,33 +1097,35 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt, range->range_data_size = reg->internal.range_data_size; iwl_trans_read_mem_bytes(fwrt->trans, addr + offset, range->data, le32_to_cpu(reg->internal.range_data_size)); - return le32_to_cpu(range->range_data_size); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); } static int iwl_dump_ini_paging_gen2_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_error_dump_range *range, struct iwl_fw_ini_region_cfg *reg, - int idx) + void *range_ptr, int idx) { + struct iwl_fw_ini_error_dump_range *range = range_ptr; u32 page_size = fwrt->trans->init_dram.paging[idx].size; range->start_addr = cpu_to_le32(idx); range->range_data_size = cpu_to_le32(page_size); memcpy(range->data, fwrt->trans->init_dram.paging[idx].block, page_size); - return le32_to_cpu(range->range_data_size); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); } static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_error_dump_range *range, struct iwl_fw_ini_region_cfg *reg, - int idx) + void *range_ptr, int idx) { /* increase idx by 1 since the pages are from 1 to * fwrt->num_of_paging_blk + 1 */ struct page *page = fwrt->fw_paging_db[++idx].fw_paging_block; + struct iwl_fw_ini_error_dump_range *range = range_ptr; dma_addr_t addr = fwrt->fw_paging_db[idx].fw_paging_phys; u32 page_size = fwrt->fw_paging_db[idx].fw_paging_size; @@ -1132,15 +1136,16 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, memcpy(range->data, page_address(page), page_size); dma_sync_single_for_device(fwrt->trans->dev, addr, page_size, DMA_BIDIRECTIONAL); - return le32_to_cpu(range->range_data_size); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); } static int iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_error_dump_range *range, - struct iwl_fw_ini_region_cfg *reg, + struct iwl_fw_ini_region_cfg *reg, void *range_ptr, int idx) { + struct iwl_fw_ini_error_dump_range *range = range_ptr; u32 start_addr = iwl_read_umac_prph(fwrt->trans, MON_BUFF_BASE_ADDR_VER2); @@ -1153,7 +1158,7 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, memcpy(range->data, fwrt->trans->fw_mon[idx].block, fwrt->trans->fw_mon[idx].size); - return le32_to_cpu(range->range_data_size); + return sizeof(*range) + le32_to_cpu(range->range_data_size); } static struct iwl_fw_ini_error_dump_range @@ -1275,8 +1280,8 @@ struct iwl_dump_ini_mem_ops { struct iwl_fw_ini_error_dump_range * (*fill_mem_hdr)(struct iwl_fw_runtime *fwrt, void *data); int (*fill_range)(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_error_dump_range *range, - struct iwl_fw_ini_region_cfg *reg, int idx); + struct iwl_fw_ini_region_cfg *reg, void *range, + int idx); }; /** @@ -1293,7 +1298,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct iwl_dump_ini_mem_ops *ops) { struct iwl_fw_ini_error_dump_header *header = (void *)(*data)->data; - struct iwl_fw_ini_error_dump_range *range; + void *range; u32 num_of_ranges, i; if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size || @@ -1318,14 +1323,14 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, } for (i = 0; i < num_of_ranges; i++) { - int range_data_size = ops->fill_range(fwrt, range, reg, i); + int range_size = ops->fill_range(fwrt, reg, range, i); - if (range_data_size < 0) { + if (range_size < 0) { IWL_ERR(fwrt, "Failed to dump region: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); return; } - range = ((void *)range) + sizeof(*range) + range_data_size; + range = range + range_size; } *data = iwl_fw_error_next_data(*data); } From 2dbf3aea791ebf10bbb67102d1c7a40868e2499e Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Wed, 19 Dec 2018 14:47:36 +0200 Subject: [PATCH 24/28] iwlwifi: dbg_ini: add region to fill_header handler Add iwl_fw_ini_region_cfg region struct to fill_header handler of iwl_dump_ini_mem_ops. it is needed for future support in fifos dumping. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index b86691fdacb3..c9a63b2c6c9b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1161,16 +1161,19 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, return sizeof(*range) + le32_to_cpu(range->range_data_size); } -static struct iwl_fw_ini_error_dump_range -*iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, void *data) +static void *iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + void *data) { struct iwl_fw_ini_error_dump *dump = data; return dump->ranges; } -static struct iwl_fw_ini_error_dump_range -*iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt, void *data) +static void +*iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + void *data) { struct iwl_fw_ini_monitor_dram_dump *mon_dump = (void *)data; u32 write_ptr, cycle_cnt; @@ -1267,8 +1270,8 @@ static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt, * struct iwl_dump_ini_mem_ops - ini memory dump operations * @get_num_of_ranges: returns the number of memory ranges in the region. * @get_size: returns the total size of the region. - * @fill_mem_hdr: fills region type specific headers and returns the first - * range or NULL if failed to fill headers. + * @fill_mem_hdr: fills region type specific headers and returns pointer to + * the first range or NULL if failed to fill headers. * @fill_range: copies a given memory range into the dump. * Returns the size of the range or -1 otherwise. */ @@ -1277,8 +1280,8 @@ struct iwl_dump_ini_mem_ops { struct iwl_fw_ini_region_cfg *reg); u32 (*get_size)(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg); - struct iwl_fw_ini_error_dump_range * - (*fill_mem_hdr)(struct iwl_fw_runtime *fwrt, void *data); + void *(*fill_mem_hdr)(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, void *data); int (*fill_range)(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg, void *range, int idx); @@ -1315,7 +1318,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, le32_to_cpu(reg->name_len))); memcpy(header->name, reg->name, le32_to_cpu(header->name_len)); - range = ops->fill_mem_hdr(fwrt, header); + range = ops->fill_mem_hdr(fwrt, reg, header); if (!range) { IWL_ERR(fwrt, "Failed to fill region header: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); From 1b64d58bd4cb60cd7b0251d8654e18e5b1539ef4 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 20 Dec 2018 14:54:58 +0200 Subject: [PATCH 25/28] iwlwifi: dbg_ini: implement Tx fifos dump Implement Tx fifos dump in the new dump mechanism. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 13 +- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 189 +++++++++++++++++- .../wireless/intel/iwlwifi/fw/error-dump.h | 29 ++- .../net/wireless/intel/iwlwifi/fw/runtime.h | 1 + 4 files changed, 218 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h index 70cc0820e068..33858787817b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -25,7 +25,7 @@ * * BSD LICENSE * - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -146,16 +146,17 @@ struct iwl_fw_ini_region_cfg_internal { /** * struct iwl_fw_ini_region_cfg_fifos - meta data of fifos region - * @lmac1_id: bit map of lmac1 fifos to include in the region. - * @lmac2_id: bit map of lmac2 fifos to include in the region. + * @fid1: fifo id 1 - bitmap of lmac tx/rx fifos to include in the region + * @fid2: fifo id 2 - bitmap of umac rx fifos to include in the region. + * It is unused for tx. * @num_of_registers: number of prph registers in the region, each register is * 4 bytes size. * @header_only: none zero value indicates that this region does not include * fifo data and includes only the given registers. */ struct iwl_fw_ini_region_cfg_fifos { - __le32 lmac1_id; - __le32 lmac2_id; + __le32 fid1; + __le32 fid2; __le32 num_of_registers; __le32 header_only; } __packed; /* FW_DEBUG_TLV_REGION_FIFOS_S */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index c9a63b2c6c9b..744d831b4dbb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1058,7 +1058,7 @@ static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt, addr = le32_to_cpu(range->start_addr) + i; prph_val = iwl_read_prph(fwrt->trans, addr + offset); if (prph_val == 0x5a5a5a5a) - return -1; + return -EBUSY; *val++ = cpu_to_le32(prph_val); } @@ -1150,7 +1150,7 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, MON_BUFF_BASE_ADDR_VER2); if (start_addr == 0x5a5a5a5a) - return -1; + return -EBUSY; range->start_addr = cpu_to_le32(start_addr); range->range_data_size = cpu_to_le32(fwrt->trans->fw_mon[idx].size); @@ -1161,6 +1161,124 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, return sizeof(*range) + le32_to_cpu(range->range_data_size); } +struct iwl_ini_txf_iter_data { + int fifo; + int lmac; + u32 fifo_size; + bool internal_txf; + bool init; +}; + +static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + struct iwl_ini_txf_iter_data *iter = fwrt->dump.fifo_iter; + struct iwl_fwrt_shared_mem_cfg *cfg = &fwrt->smem_cfg; + int txf_num = cfg->num_txfifo_entries; + int int_txf_num = ARRAY_SIZE(cfg->internal_txfifo_size); + u32 lmac_bitmap = le32_to_cpu(reg->fifos.fid1); + + if (!iter) + return false; + + if (iter->init) { + if (le32_to_cpu(reg->offset) && + WARN_ONCE(cfg->num_lmacs == 1, + "Invalid lmac offset: 0x%x\n", + le32_to_cpu(reg->offset))) + return false; + + iter->init = false; + iter->internal_txf = false; + iter->fifo_size = 0; + iter->fifo = -1; + if (le32_to_cpu(reg->offset)) + iter->lmac = 1; + else + iter->lmac = 0; + } + + if (!iter->internal_txf) + for (iter->fifo++; iter->fifo < txf_num; iter->fifo++) { + iter->fifo_size = + cfg->lmac[iter->lmac].txfifo_size[iter->fifo]; + if (iter->fifo_size && (lmac_bitmap & BIT(iter->fifo))) + return true; + } + + iter->internal_txf = true; + + if (!fw_has_capa(&fwrt->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) + return false; + + for (iter->fifo++; iter->fifo < int_txf_num + txf_num; iter->fifo++) { + iter->fifo_size = + cfg->internal_txfifo_size[iter->fifo - txf_num]; + if (iter->fifo_size && (lmac_bitmap & BIT(iter->fifo))) + return true; + } + + return false; +} + +static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + void *range_ptr, int idx) +{ + struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr; + struct iwl_ini_txf_iter_data *iter; + u32 offs = le32_to_cpu(reg->offset), addr; + u32 registers_size = + le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32); + __le32 *val = range->data; + unsigned long flags; + int i; + + if (!iwl_ini_txf_iter(fwrt, reg)) + return -EIO; + + if (!iwl_trans_grab_nic_access(fwrt->trans, &flags)) + return -EBUSY; + + iter = fwrt->dump.fifo_iter; + + range->fifo_num = cpu_to_le32(iter->fifo); + range->num_of_registers = reg->fifos.num_of_registers; + range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size); + + iwl_write_prph_no_grab(fwrt->trans, TXF_LARC_NUM + offs, iter->fifo); + + /* read txf registers */ + for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) { + addr = le32_to_cpu(reg->start_addr[i]) + offs; + + *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr)); + } + + if (reg->fifos.header_only) { + range->range_data_size = cpu_to_le32(registers_size); + goto out; + } + + /* Set the TXF_READ_MODIFY_ADDR to TXF_WR_PTR */ + iwl_write_prph_no_grab(fwrt->trans, TXF_READ_MODIFY_ADDR + offs, + TXF_WR_PTR + offs); + + /* Dummy-read to advance the read pointer to the head */ + iwl_read_prph_no_grab(fwrt->trans, TXF_READ_MODIFY_DATA + offs); + + /* Read FIFO */ + addr = TXF_READ_MODIFY_DATA + offs; + for (i = 0; i < iter->fifo_size; i += sizeof(__le32)) + *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr)); + +out: + iwl_trans_release_nic_access(fwrt->trans, &flags); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); +} + static void *iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg, void *data) @@ -1195,6 +1313,15 @@ static void return mon_dump->ranges; } +static void *iwl_dump_ini_fifo_fill_header(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + void *data) +{ + struct iwl_fw_ini_fifo_error_dump *dump = data; + + return dump->ranges; +} + static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { @@ -1219,6 +1346,22 @@ static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt, return 1; } +static u32 iwl_dump_ini_txf_ranges(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + struct iwl_ini_txf_iter_data iter = { .init = true }; + void *fifo_iter = fwrt->dump.fifo_iter; + u32 num_of_fifos = 0; + + fwrt->dump.fifo_iter = &iter; + while (iwl_ini_txf_iter(fwrt, reg)) + num_of_fifos++; + + fwrt->dump.fifo_iter = fifo_iter; + + return num_of_fifos; +} + static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { @@ -1266,6 +1409,30 @@ static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt, return size; } +static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + struct iwl_ini_txf_iter_data iter = { .init = true }; + void *fifo_iter = fwrt->dump.fifo_iter; + u32 size = 0; + u32 fifo_hdr = sizeof(struct iwl_fw_ini_fifo_error_dump_range) + + le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32); + + fwrt->dump.fifo_iter = &iter; + while (iwl_ini_txf_iter(fwrt, reg)) { + size += fifo_hdr; + if (!reg->fifos.header_only) + size += iter.fifo_size; + } + + if (size) + size += sizeof(struct iwl_fw_ini_fifo_error_dump); + + fwrt->dump.fifo_iter = fifo_iter; + + return size; +} + /** * struct iwl_dump_ini_mem_ops - ini memory dump operations * @get_num_of_ranges: returns the number of memory ranges in the region. @@ -1273,7 +1440,7 @@ static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt, * @fill_mem_hdr: fills region type specific headers and returns pointer to * the first range or NULL if failed to fill headers. * @fill_range: copies a given memory range into the dump. - * Returns the size of the range or -1 otherwise. + * Returns the size of the range or negative error value otherwise. */ struct iwl_dump_ini_mem_ops { u32 (*get_num_of_ranges)(struct iwl_fw_runtime *fwrt, @@ -1369,7 +1536,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, size += hdr_len + iwl_dump_ini_mem_get_size(fwrt, reg); break; case IWL_FW_INI_REGION_TXF: - size += iwl_fw_txf_len(fwrt, &fwrt->smem_cfg); + size += hdr_len + iwl_dump_ini_txf_get_size(fwrt, reg); break; case IWL_FW_INI_REGION_RXF: size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg); @@ -1463,9 +1630,19 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, iwl_dump_ini_mem(fwrt, type, data, reg, &ops); break; } - case IWL_FW_INI_REGION_TXF: - iwl_fw_dump_txf(fwrt, data); + case IWL_FW_INI_REGION_TXF: { + struct iwl_ini_txf_iter_data iter = { .init = true }; + void *fifo_iter = fwrt->dump.fifo_iter; + + fwrt->dump.fifo_iter = &iter; + ops.get_num_of_ranges = iwl_dump_ini_txf_ranges; + ops.get_size = iwl_dump_ini_txf_get_size; + ops.fill_mem_hdr = iwl_dump_ini_fifo_fill_header; + ops.fill_range = iwl_dump_ini_txf_iter; + iwl_dump_ini_mem(fwrt, type, data, reg, &ops); + fwrt->dump.fifo_iter = fifo_iter; break; + } case IWL_FW_INI_REGION_RXF: iwl_fw_dump_rxf(fwrt, data); break; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 063f2b925808..2cc4f13d0abb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -8,7 +8,7 @@ * Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -308,6 +308,31 @@ struct iwl_fw_ini_error_dump { struct iwl_fw_ini_error_dump_range ranges[]; } __packed; +/** + * struct iwl_fw_ini_fifo_error_dump_range - ini fifo range dump + * @fifo_num: the fifo num. In case of rxf and umac rxf, set BIT(31) to + * distinguish between lmac and umac + * @num_of_registers: num of registers to dump, dword size each + * @range_data_size: the size of the registers and fifo data + * @data: fifo data + */ +struct iwl_fw_ini_fifo_error_dump_range { + __le32 fifo_num; + __le32 num_of_registers; + __le32 range_data_size; + __le32 data[]; +} __packed; + +/** + * struct iwl_fw_ini_fifo_error_dump - ini fifo region dump + * @header: the header of this region + * @ranges: the memory ranges of this region + */ +struct iwl_fw_ini_fifo_error_dump { + struct iwl_fw_ini_error_dump_header header; + struct iwl_fw_ini_fifo_error_dump_range ranges[]; +} __packed; + /** * struct iwl_fw_error_dump_rb - content of an Receive Buffer * @index: the index of the Receive Buffer in the Rx queue diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 6e843998d1c8..a5fe1a8ca426 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -144,6 +144,7 @@ struct iwl_fw_runtime { struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM]; u32 lmac_err_id[MAX_NUM_LMAC]; u32 umac_err_id; + void *fifo_iter; } dump; #ifdef CONFIG_IWLWIFI_DEBUGFS struct { From 8d7dea25ada762f68d9522fb070a7cf6935cf822 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 27 Jan 2019 11:22:21 +0200 Subject: [PATCH 26/28] iwlwifi: dbg_ini: implement Rx fifos dump Implement Rx fifos dump in the new dump mechanism. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 133 +++++++++++++++++- .../wireless/intel/iwlwifi/fw/error-dump.h | 3 + 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 744d831b4dbb..f119c49cd39c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1279,6 +1279,105 @@ out: return sizeof(*range) + le32_to_cpu(range->range_data_size); } +struct iwl_ini_rxf_data { + u32 fifo_num; + u32 size; + u32 offset; +}; + +static void iwl_ini_get_rxf_data(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + struct iwl_ini_rxf_data *data) +{ + u32 fid1 = le32_to_cpu(reg->fifos.fid1); + u32 fid2 = le32_to_cpu(reg->fifos.fid2); + u32 fifo_idx; + + if (!data) + return; + + memset(data, 0, sizeof(*data)); + + if (WARN_ON_ONCE((fid1 && fid2) || (!fid1 && !fid2))) + return; + + fifo_idx = ffs(fid1) - 1; + if (fid1 && !WARN_ON_ONCE((~BIT(fifo_idx) & fid1) || + fifo_idx >= MAX_NUM_LMAC)) { + data->size = fwrt->smem_cfg.lmac[fifo_idx].rxfifo1_size; + data->fifo_num = fifo_idx; + return; + } + + fifo_idx = ffs(fid2) - 1; + if (fid2 && !WARN_ON_ONCE(fifo_idx != 0)) { + data->size = fwrt->smem_cfg.rxfifo2_size; + data->offset = RXF_DIFF_FROM_PREV; + /* use bit 31 to distinguish between umac and lmac rxf while + * parsing the dump + */ + data->fifo_num = fifo_idx | IWL_RXF_UMAC_BIT; + return; + } +} + +static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + void *range_ptr, int idx) +{ + struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr; + struct iwl_ini_rxf_data rxf_data; + u32 offs = le32_to_cpu(reg->offset), addr; + u32 registers_size = + le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32); + __le32 *val = range->data; + unsigned long flags; + int i; + + iwl_ini_get_rxf_data(fwrt, reg, &rxf_data); + if (!rxf_data.size) + return -EIO; + + if (!iwl_trans_grab_nic_access(fwrt->trans, &flags)) + return -EBUSY; + + offs += rxf_data.offset; + + range->fifo_num = cpu_to_le32(rxf_data.fifo_num); + range->num_of_registers = reg->fifos.num_of_registers; + range->range_data_size = cpu_to_le32(rxf_data.size + registers_size); + + /* read rxf registers */ + for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) { + addr = le32_to_cpu(reg->start_addr[i]) + offs; + + *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr)); + } + + if (reg->fifos.header_only) { + range->range_data_size = cpu_to_le32(registers_size); + goto out; + } + + /* Lock fence */ + iwl_write_prph_no_grab(fwrt->trans, RXF_SET_FENCE_MODE + offs, 0x1); + /* Set fence pointer to the same place like WR pointer */ + iwl_write_prph_no_grab(fwrt->trans, RXF_LD_WR2FENCE + offs, 0x1); + /* Set fence offset */ + iwl_write_prph_no_grab(fwrt->trans, RXF_LD_FENCE_OFFSET_ADDR + offs, + 0x0); + + /* Read FIFO */ + addr = RXF_FIFO_RD_FENCE_INC + offs; + for (i = 0; i < rxf_data.size; i += sizeof(__le32)) + *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr)); + +out: + iwl_trans_release_nic_access(fwrt->trans, &flags); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); +} + static void *iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg, void *data) @@ -1362,6 +1461,15 @@ static u32 iwl_dump_ini_txf_ranges(struct iwl_fw_runtime *fwrt, return num_of_fifos; } +static u32 iwl_dump_ini_rxf_ranges(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + /* Each Rx fifo needs a different offset and therefore, it's + * region can contain only one fifo, i.e. 1 memory range. + */ + return 1; +} + static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { @@ -1433,6 +1541,23 @@ static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt, return size; } +static u32 iwl_dump_ini_rxf_get_size(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg) +{ + struct iwl_ini_rxf_data rx_data; + u32 size = sizeof(struct iwl_fw_ini_fifo_error_dump) + + sizeof(struct iwl_fw_ini_fifo_error_dump_range) + + le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32); + + if (reg->fifos.header_only) + return size; + + iwl_ini_get_rxf_data(fwrt, reg, &rx_data); + size += rx_data.size; + + return size; +} + /** * struct iwl_dump_ini_mem_ops - ini memory dump operations * @get_num_of_ranges: returns the number of memory ranges in the region. @@ -1539,7 +1664,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, size += hdr_len + iwl_dump_ini_txf_get_size(fwrt, reg); break; case IWL_FW_INI_REGION_RXF: - size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg); + size += hdr_len + iwl_dump_ini_rxf_get_size(fwrt, reg); break; case IWL_FW_INI_REGION_PAGING: { size += hdr_len; @@ -1644,7 +1769,11 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, break; } case IWL_FW_INI_REGION_RXF: - iwl_fw_dump_rxf(fwrt, data); + ops.get_num_of_ranges = iwl_dump_ini_rxf_ranges; + ops.get_size = iwl_dump_ini_rxf_get_size; + ops.fill_mem_hdr = iwl_dump_ini_fifo_fill_header; + ops.fill_range = iwl_dump_ini_rxf_iter; + iwl_dump_ini_mem(fwrt, type, data, reg, &ops); break; case IWL_FW_INI_REGION_CSR: ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 2cc4f13d0abb..9b5077bd46c3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -308,6 +308,9 @@ struct iwl_fw_ini_error_dump { struct iwl_fw_ini_error_dump_range ranges[]; } __packed; +/* This bit is used to differentiate between lmac and umac rxf */ +#define IWL_RXF_UMAC_BIT BIT(31) + /** * struct iwl_fw_ini_fifo_error_dump_range - ini fifo range dump * @fifo_num: the fifo num. In case of rxf and umac rxf, set BIT(31) to From 3941310cf665b8a7965424d2a185c80782faa030 Mon Sep 17 00:00:00 2001 From: Ihab Zhaika Date: Mon, 4 Feb 2019 10:16:03 +0200 Subject: [PATCH 27/28] iwlwifi: add new card for 9260 series Add one PCI ID for 9260 series. CC: # 4.14+ Signed-off-by: Ihab Zhaika Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index b839a921cec8..fb7a0def9355 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -597,6 +597,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2526, 0x2030, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x2034, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x4018, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x401C, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_160_cfg_soc)}, From 085486de833e383705bce61dbde8d31077f5b8ca Mon Sep 17 00:00:00 2001 From: Ihab Zhaika Date: Sun, 3 Feb 2019 18:54:01 +0200 Subject: [PATCH 28/28] iwlwifi: add new cards for 22000 and killer series and change the market name Add a few PCI ID'S for 22000 and killer series in addition to chainging the marketing name. Signed-off-by: Ihab Zhaika Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 8 +- .../net/wireless/intel/iwlwifi/iwl-config.h | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 98 +++++++++++-------- .../net/wireless/intel/iwlwifi/pcie/trans.c | 4 +- 4 files changed, 64 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 2d472a04807f..fdc56f821b5a 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -223,8 +223,8 @@ const struct iwl_cfg iwl22000_2ac_cfg_jf = { IWL_DEVICE_22500, }; -const struct iwl_cfg iwl22560_2ax_cfg_hr = { - .name = "Intel(R) Wireless-AX 22560", +const struct iwl_cfg iwl_ax101_cfg_qu_hr = { + .name = "Intel(R) Wi-Fi 6 AX101", .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, IWL_DEVICE_22500, /* @@ -249,7 +249,7 @@ const struct iwl_cfg iwl22260_2ax_cfg = { }; const struct iwl_cfg killer1650x_2ax_cfg = { - .name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (22260NGW)", + .name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (200NGW)", .fw_name_pre = IWL_CC_A_FW_PRE, IWL_DEVICE_22500, /* @@ -262,7 +262,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = { }; const struct iwl_cfg killer1650w_2ax_cfg = { - .name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (22260D2W)", + .name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (200D2W)", .fw_name_pre = IWL_CC_A_FW_PRE, IWL_DEVICE_22500, /* diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 7f2fa5cc8c2c..f5f87773667b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -548,7 +548,7 @@ extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl22000_2ac_cfg_hr; extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; extern const struct iwl_cfg iwl22000_2ac_cfg_jf; -extern const struct iwl_cfg iwl22560_2ax_cfg_hr; +extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; extern const struct iwl_cfg iwl22000_2ax_cfg_hr; extern const struct iwl_cfg iwl22260_2ax_cfg; extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index fb7a0def9355..2b94e4cef56c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -517,6 +517,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0040, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x02F0, 0x0044, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)}, @@ -525,6 +527,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)}, @@ -542,6 +545,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0040, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x06F0, 0x0044, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)}, @@ -550,6 +555,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x06F0, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)}, @@ -615,6 +621,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x0044, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_soc)}, @@ -623,6 +630,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)}, @@ -700,6 +708,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0044, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, @@ -708,6 +717,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x34F0, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, @@ -754,6 +764,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x0044, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)}, @@ -762,6 +773,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x43F0, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)}, @@ -821,6 +833,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0044, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)}, @@ -829,6 +842,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)}, @@ -876,73 +890,75 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_cfg_qnj_jf_b0)}, /* 22000 Series */ - {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x0074, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x0078, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x007C, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x02F0, 0x0310, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x02F0, 0x0074, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x02F0, 0x0078, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x02F0, 0x007C, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x02F0, 0x0310, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x02F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, {IWL_PCI_DEVICE(0x02F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x02F0, 0x4070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0074, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0078, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x007C, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x06F0, 0x0310, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x02F0, 0x4070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x06F0, 0x0070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x06F0, 0x0074, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x06F0, 0x0078, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x06F0, 0x007C, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x06F0, 0x0310, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x06F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, {IWL_PCI_DEVICE(0x06F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0000, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0040, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0000, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0040, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0070, iwl22000_2ac_cfg_hr_cdb)}, - {IWL_PCI_DEVICE(0x2720, 0x0074, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0078, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x007C, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x2720, 0x0310, iwl22000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)}, - {IWL_PCI_DEVICE(0x2720, 0x1080, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x1080, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, {IWL_PCI_DEVICE(0x2720, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x2720, 0x4070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0040, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0074, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0078, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x007C, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x4070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0040, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0074, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0078, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x007C, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x34F0, 0x4070, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x4070, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x40C0, 0x0000, iwl22560_2ax_cfg_su_cdb)}, {IWL_PCI_DEVICE(0x40C0, 0x0010, iwl22560_2ax_cfg_su_cdb)}, {IWL_PCI_DEVICE(0x40c0, 0x0090, iwl22560_2ax_cfg_su_cdb)}, {IWL_PCI_DEVICE(0x40C0, 0x0310, iwl22560_2ax_cfg_su_cdb)}, {IWL_PCI_DEVICE(0x40C0, 0x0A10, iwl22560_2ax_cfg_su_cdb)}, - {IWL_PCI_DEVICE(0x43F0, 0x0040, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0074, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x0078, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0x43F0, 0x007C, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x0040, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x0070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x0074, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x0078, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x007C, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, {IWL_PCI_DEVICE(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0x43F0, 0x4070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0040, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x00B0, iwl22560_2ax_cfg_hr)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x43F0, 0x4070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0040, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x00B0, iwl_ax101_cfg_qu_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, {IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl22560_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2723, 0x0080, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x0084, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x0088, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x008C, iwl22260_2ax_cfg)}, + {IWL_PCI_DEVICE(0x2723, 0x1653, killer1650w_2ax_cfg)}, + {IWL_PCI_DEVICE(0x2723, 0x1654, killer1650x_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x4080, iwl22260_2ax_cfg)}, {IWL_PCI_DEVICE(0x2723, 0x4088, iwl22260_2ax_cfg)}, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index e2579a0bcc25..fe8269d023de 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3540,10 +3540,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) { trans->cfg = &iwlax210_2ax_cfg_so_gf_a0; } - } else if (cfg == &iwl22560_2ax_cfg_hr) { + } else if (cfg == &iwl_ax101_cfg_qu_hr) { if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { - trans->cfg = &iwl22560_2ax_cfg_hr; + trans->cfg = &iwl_ax101_cfg_qu_hr; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { trans->cfg = &iwl22000_2ax_cfg_jf;