From 1f171f4f1437f7811b7610ef959e4340b9212a11 Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Thu, 26 Aug 2021 22:47:46 +0300 Subject: [PATCH 001/114] iwlwifi: Add support for getting rf id with blank otp When having a blank OTP the only way to get the rf id and the cdb info is from prph registers. Currently there is some implementation for this, but it is located in the wrong place in the code (should be before trying to understand what HW is connected and not after), and it has a partial implementation. Signed-off-by: Matti Gottlieb Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20210826224715.820c2ae18c2b.Iec9b2e2615ce65e6aff5ce896589227a7030f4cf@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 +- .../wireless/intel/iwlwifi/fw/error-dump.h | 4 - drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 35 +++++++ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 96 +++++++++++++++++++ 4 files changed, 132 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 6dcafd0a3d4b1..b7f2f0662b826 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2077,7 +2077,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, */ hw_type = CSR_HW_REV_TYPE(fwrt->trans->hw_rev); if (hw_type == IWL_AX210_HW_TYPE) { - u32 prph_val = iwl_read_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR); + u32 prph_val = iwl_read_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR_GEN2); u32 is_jacket = !!(prph_val & WFPM_OTP_CFG1_IS_JACKET_BIT); u32 is_cdb = !!(prph_val & WFPM_OTP_CFG1_IS_CDB_BIT); u32 masked_bits = is_jacket | (is_cdb << 1); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 521ca2bb0e928..9036b32ec765d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -342,10 +342,6 @@ struct iwl_fw_ini_dump_cfg_name { #define IWL_AX210_HW_TYPE 0x42 /* How many bits to roll when adding to the HW type of AX210 HW */ #define IWL_AX210_HW_TYPE_ADDITION_SHIFT 12 -/* This prph is used to tell apart HW_TYPE == 0x42 NICs */ -#define WFPM_OTP_CFG1_ADDR 0xd03098 -#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4) -#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5) /* struct iwl_fw_ini_dump_info - ini dump information * @version: dump version diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index d0a7d58336a9e..48213d61bac7c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -347,6 +347,12 @@ #define RADIO_REG_SYS_MANUAL_DFT_0 0xAD4078 #define RFIC_REG_RD 0xAD0470 #define WFPM_CTRL_REG 0xA03030 +#define WFPM_CTRL_REG_GEN2 0xd03030 +#define WFPM_OTP_CFG1_ADDR 0x00a03098 +#define WFPM_OTP_CFG1_ADDR_GEN2 0x00d03098 +#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4) +#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5) + #define WFPM_GP2 0xA030B4 /* DBGI SRAM Register details */ @@ -399,10 +405,39 @@ enum { LMPM_PAGE_PASS_NOTIF_POS = BIT(20), }; +/* + * CRF ID register + * + * type: bits 0-11 + * reserved: bits 12-18 + * slave_exist: bit 19 + * dash: bits 20-23 + * step: bits 24-26 + * flavor: bits 27-31 + */ +#define REG_CRF_ID_TYPE(val) (((val) & 0x00000FFF) >> 0) +#define REG_CRF_ID_SLAVE(val) (((val) & 0x00080000) >> 19) +#define REG_CRF_ID_DASH(val) (((val) & 0x00F00000) >> 20) +#define REG_CRF_ID_STEP(val) (((val) & 0x07000000) >> 24) +#define REG_CRF_ID_FLAVOR(val) (((val) & 0xF8000000) >> 27) + #define UREG_CHICK (0xA05C00) #define UREG_CHICK_MSI_ENABLE BIT(24) #define UREG_CHICK_MSIX_ENABLE BIT(25) +#define SD_REG_VER 0xa29600 +#define SD_REG_VER_GEN2 0x00a2b800 + +#define REG_CRF_ID_TYPE_JF_1 0x201 +#define REG_CRF_ID_TYPE_JF_2 0x202 +#define REG_CRF_ID_TYPE_HR_CDB 0x503 +#define REG_CRF_ID_TYPE_HR_NONE_CDB 0x504 +#define REG_CRF_ID_TYPE_HR_NONE_CDB_1X1 0x501 +#define REG_CRF_ID_TYPE_HR_NONE_CDB_CCP 0x532 +#define REG_CRF_ID_TYPE_GF 0x410 +#define REG_CRF_ID_TYPE_GF_TC 0xF08 +#define REG_CRF_ID_TYPE_MR 0x810 + #define HPM_DEBUG 0xA03440 #define PERSISTENCE_BIT BIT(12) #define PREG_WFPM_ACCESS BIT(12) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 3b974388d834d..1a009bb047cde 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1191,6 +1191,92 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { #endif /* CONFIG_IWLMVM */ }; +/* + * In case that there is no OTP on the NIC, get the rf id and cdb info + * from the prph registers. + */ +static int get_crf_id(struct iwl_trans *iwl_trans) +{ + int ret = 0; + u32 wfpm_ctrl_addr; + u32 wfpm_otp_cfg_addr; + u32 sd_reg_ver_addr; + u32 cdb = 0; + u32 val; + + if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + wfpm_ctrl_addr = WFPM_CTRL_REG_GEN2; + wfpm_otp_cfg_addr = WFPM_OTP_CFG1_ADDR_GEN2; + sd_reg_ver_addr = SD_REG_VER_GEN2; + /* Qu/Pu families have other addresses */ + } else { + wfpm_ctrl_addr = WFPM_CTRL_REG; + wfpm_otp_cfg_addr = WFPM_OTP_CFG1_ADDR; + sd_reg_ver_addr = SD_REG_VER; + } + + if (!iwl_trans_grab_nic_access(iwl_trans)) { + IWL_ERR(iwl_trans, "Failed to grab nic access before reading crf id\n"); + ret = -EIO; + goto out; + } + + /* Enable access to peripheral registers */ + val = iwl_read_umac_prph_no_grab(iwl_trans, wfpm_ctrl_addr); + val |= ENABLE_WFPM; + iwl_write_umac_prph_no_grab(iwl_trans, wfpm_ctrl_addr, val); + + /* Read crf info */ + val = iwl_read_prph_no_grab(iwl_trans, sd_reg_ver_addr); + + /* Read cdb info (also contains the jacket info if needed in the future */ + cdb = iwl_read_umac_prph_no_grab(iwl_trans, wfpm_otp_cfg_addr); + + /* Map between crf id to rf id */ + switch (REG_CRF_ID_TYPE(val)) { + case REG_CRF_ID_TYPE_JF_1: + iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_JF1 << 12); + break; + case REG_CRF_ID_TYPE_JF_2: + iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_JF2 << 12); + break; + case REG_CRF_ID_TYPE_HR_NONE_CDB: + iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_HR1 << 12); + break; + case REG_CRF_ID_TYPE_HR_CDB: + iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_HR2 << 12); + break; + case REG_CRF_ID_TYPE_GF: + iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_GF << 12); + break; + case REG_CRF_ID_TYPE_MR: + iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_MR << 12); + break; + default: + ret = -EIO; + IWL_ERR(iwl_trans, + "Can find a correct rfid for crf id 0x%x\n", + REG_CRF_ID_TYPE(val)); + goto out_release; + + } + + /* Set CDB capabilities */ + if (cdb & BIT(4)) { + iwl_trans->hw_rf_id += BIT(28); + IWL_INFO(iwl_trans, "Adding cdb to rf id\n"); + } + + IWL_INFO(iwl_trans, "Detected RF 0x%x from crf id 0x%x\n", + iwl_trans->hw_rf_id, REG_CRF_ID_TYPE(val)); + +out_release: + iwl_trans_release_nic_access(iwl_trans); + +out: + return ret; +} + /* PCI registers */ #define PCI_CFG_RETRY_TIMEOUT 0x041 @@ -1224,6 +1310,16 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); + /* + * The RF_ID is set to zero in blank OTP so read version to + * extract the RF_ID. + * This is relevant only for family 9000 and up. + */ + if (iwl_trans->trans_cfg->rf_id && + iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000 && + !CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans)) + goto out_free_trans; + for (i = 0; i < ARRAY_SIZE(iwl_dev_info_table); i++) { const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; if ((dev_info->device == (u16)IWL_CFG_ANY || From af82c00736b4d1ef6a77b0467a1065916e0b15bf Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Thu, 26 Aug 2021 22:47:47 +0300 Subject: [PATCH 002/114] iwlwifi: Add support for more BZ HWs Add support for GA and for BZ with FM rf. Signed-off-by: Matti Gottlieb Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20210826224715.64ab5278fb9f.I4f2a547dc04c3d14cacdbc739da0b056fc04923d@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 23 +++++++++++++++++++ .../net/wireless/intel/iwlwifi/iwl-config.h | 3 +++ drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 14 +++++++++++ 4 files changed, 41 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index c18b27b0d60e7..0b8a897a18532 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -53,6 +53,9 @@ #define IWL_BZ_A_GF_A_FW_PRE "iwlwifi-bz-a0-gf-a0-" #define IWL_BZ_A_GF4_A_FW_PRE "iwlwifi-bz-a0-gf4-a0-" #define IWL_BZ_A_MR_A_FW_PRE "iwlwifi-bz-a0-mr-a0-" +#define IWL_BZ_A_FM_A_FW_PRE "iwlwifi-bz-a0-fm-a0-" +#define IWL_GL_A_FM_A_FW_PRE "iwlwifi-gl-a0-fm7-a0-" + #define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \ IWL_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" @@ -106,6 +109,10 @@ IWL_BZ_A_GF4_A_FW_PRE __stringify(api) ".ucode" #define IWL_BZ_A_MR_A_MODULE_FIRMWARE(api) \ IWL_BZ_A_MR_A_FW_PRE __stringify(api) ".ucode" +#define IWL_BZ_A_FM_A_MODULE_FIRMWARE(api) \ + IWL_BZ_A_FM_A_FW_PRE __stringify(api) ".ucode" +#define IWL_GL_A_FM_A_MODULE_FIRMWARE(api) \ + IWL_GL_A_FM_A_FW_PRE __stringify(api) ".ucode" static const struct iwl_base_params iwl_22000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, @@ -850,6 +857,20 @@ const struct iwl_cfg iwl_cfg_bz_a0_mr_a0 = { .num_rbds = IWL_NUM_RBDS_AX210_HE, }; +const struct iwl_cfg iwl_cfg_bz_a0_fm_a0 = { + .fw_name_pre = IWL_BZ_A_FM_A_FW_PRE, + .uhb_supported = true, + IWL_DEVICE_BZ, + .num_rbds = IWL_NUM_RBDS_AX210_HE, +}; + +const struct iwl_cfg iwl_cfg_gl_a0_fm_a0 = { + .fw_name_pre = IWL_GL_A_FM_A_FW_PRE, + .uhb_supported = true, + IWL_DEVICE_BZ, + .num_rbds = IWL_NUM_RBDS_AX210_HE, +}; + MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); @@ -876,3 +897,5 @@ MODULE_FIRMWARE(IWL_BZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_BZ_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_BZ_A_GF4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_BZ_A_MR_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_BZ_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_GL_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 7eb534df53310..f55f08d4d5119 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -420,6 +420,7 @@ struct iwl_cfg { #define IWL_CFG_MAC_TYPE_SOF 0x43 #define IWL_CFG_MAC_TYPE_MA 0x44 #define IWL_CFG_MAC_TYPE_BZ 0x46 +#define IWL_CFG_MAC_TYPE_GL 0x47 #define IWL_CFG_RF_TYPE_TH 0x105 #define IWL_CFG_RF_TYPE_TH1 0x108 @@ -628,6 +629,8 @@ extern const struct iwl_cfg iwl_cfg_bz_a0_hr_b0; extern const struct iwl_cfg iwl_cfg_bz_a0_gf_a0; extern const struct iwl_cfg iwl_cfg_bz_a0_gf4_a0; extern const struct iwl_cfg iwl_cfg_bz_a0_mr_a0; +extern const struct iwl_cfg iwl_cfg_bz_a0_fm_a0; +extern const struct iwl_cfg iwl_cfg_gl_a0_fm_a0; #endif /* CONFIG_IWLMVM */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index 48213d61bac7c..a84ab02cf9d7e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -437,6 +437,7 @@ enum { #define REG_CRF_ID_TYPE_GF 0x410 #define REG_CRF_ID_TYPE_GF_TC 0xF08 #define REG_CRF_ID_TYPE_MR 0x810 +#define REG_CRF_ID_TYPE_FM 0x910 #define HPM_DEBUG 0xA03440 #define PERSISTENCE_BIT BIT(12) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 1a009bb047cde..d1b9f85c00cf2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1112,6 +1112,17 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_RF_TYPE_MR, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_bz_a0_mr_a0, iwl_bz_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_BZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + iwl_cfg_bz_a0_fm_a0, iwl_bz_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + iwl_cfg_gl_a0_fm_a0, iwl_bz_name), + /* SoF with JF2 */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, @@ -1252,6 +1263,9 @@ static int get_crf_id(struct iwl_trans *iwl_trans) case REG_CRF_ID_TYPE_MR: iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_MR << 12); break; + case REG_CRF_ID_TYPE_FM: + iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_FM << 12); + break; default: ret = -EIO; IWL_ERR(iwl_trans, From 595c230b95130b2bdb1e210f1c4e70faf796764c Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Thu, 26 Aug 2021 22:47:48 +0300 Subject: [PATCH 003/114] iwlwifi: Start scratch debug register for Bz family Start scratch debug register for Bz family. This register is used for FW debug, and the driver should start this register with a fixed value, during init, and upon an error, should read it, and add it to the dump. Signed-off-by: Matti Gottlieb Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20210826224715.609ad58a49f3.I05c351233601ecc51dddfa5df69ace292216eb95@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dump.c | 7 +++++++ drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 7 +++++++ drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 8 +++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index a1842205e86a1..1f9cf4e405475 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c @@ -328,6 +328,13 @@ static void iwl_fwrt_dump_tcm_error_log(struct iwl_fw_runtime *fwrt) for (i = 0; i < ARRAY_SIZE(table.sw_status); i++) IWL_ERR(fwrt, "0x%08X | tcm SW status[%d]\n", table.sw_status[i], i); + + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH); + + IWL_ERR(fwrt, "Function Scratch status:\n"); + IWL_ERR(fwrt, "0x%08X | Func Scratch\n", scratch); + } } static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index cf796403c45c0..2c4d70fb32fa8 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -34,6 +34,7 @@ #define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */ #define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/ #define CSR_GP_CNTRL (CSR_BASE+0x024) +#define CSR_FUNC_SCRATCH (CSR_BASE+0x02c) /* Scratch register - used for FW dbg */ /* 2nd byte of CSR_INT_COALESCING, not accessible via iwl_write32()! */ #define CSR_INT_PERIODIC_REG (CSR_BASE+0x005) @@ -135,6 +136,12 @@ #define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240) #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) +/* + * Scratch register initial configuration - this is set on init, and read + * during a error FW error. + */ +#define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101) + /* Bits for CSR_HW_IF_CONFIG_REG */ #define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003) #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index bf0c32a74ca47..53bc5b7d8d5c8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -466,13 +466,15 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, iwl_pcie_set_ltr(trans); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { + iwl_write32(trans, CSR_FUNC_SCRATCH, CSR_FUNC_SCRATCH_INIT_VALUE); iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_ROM_START); - else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + } else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); - else + } else { iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1); + } /* re-check RF-Kill state since we may have missed the interrupt */ hw_rfkill = iwl_pcie_check_hw_rf_kill(trans); From 4e6b69ec9a9eb2954930e80c14f8f77e8ed91177 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 11:43:39 +0300 Subject: [PATCH 004/114] iwlwifi: mvm: fix ieee80211_get_he_iftype_cap() iftype We should consider the P2P interface type, which isn't in vif->type due to mac80211's special handling of that. Use ieee80211_vif_type_p2p() to convert appropriately. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.8e992a3beee2.I4231ac8a7ae8f844e35a1ec221baf3e2b676e765@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3a4585222d6d4..33198be6f0399 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2022,7 +2022,8 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, } sband = mvm->hw->wiphy->bands[chanctx_conf->def.chan->band]; - own_he_cap = ieee80211_get_he_iftype_cap(sband, vif->type); + own_he_cap = ieee80211_get_he_iftype_cap(sband, + ieee80211_vif_type_p2p(vif)); sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]); if (IS_ERR_OR_NULL(sta)) { From e5322b9ab5f63536c41301150b7ce64605ce52cc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 11:43:40 +0300 Subject: [PATCH 005/114] iwlwifi: mvm: disable RX-diversity in powersave Just like we have default SMPS mode as dynamic in powersave, we should not enable RX-diversity in powersave, to reduce power consumption when connected to a non-MIMO AP. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.fc896bc5cdaa.I1d11da71b8a5cbe921a37058d5f578f1b14a2023@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 4a3d2971a98b7..ec8a223f90e85 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -405,6 +405,9 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm, lockdep_assert_held(&mvm->mutex); + if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) + return false; + if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1) return false; From 5667ccc2a387a62769a3600e5167b69458e84676 Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Sun, 17 Oct 2021 11:43:41 +0300 Subject: [PATCH 006/114] iwlwifi: mvm: add lmac/umac PC info in case of error Currently it's only added to 22000 family in this patch we also add it to 9000 family where it's also relevant. Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.e51c61b31037.I118299d9d6eeef211cc8d4ee72193fdddc54d446@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 74404c96063bc..660860b8d02f0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -295,6 +295,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, if (ret) { struct iwl_trans *trans = mvm->trans; + /* SecBoot info */ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { IWL_ERR(mvm, @@ -302,6 +303,17 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS), iwl_read_umac_prph(trans, UMAG_SB_CPU_2_STATUS)); + } else if (trans->trans_cfg->device_family >= + IWL_DEVICE_FAMILY_8000) { + IWL_ERR(mvm, + "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", + iwl_read_prph(trans, SB_CPU_1_STATUS), + iwl_read_prph(trans, SB_CPU_2_STATUS)); + } + + /* LMAC/UMAC PC info */ + if (trans->trans_cfg->device_family >= + IWL_DEVICE_FAMILY_9000) { IWL_ERR(mvm, "UMAC PC: 0x%x\n", iwl_read_umac_prph(trans, UREG_UMAC_CURRENT_PC)); @@ -312,12 +324,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, IWL_ERR(mvm, "LMAC2 PC: 0x%x\n", iwl_read_umac_prph(trans, UREG_LMAC2_CURRENT_PC)); - } else if (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_8000) { - IWL_ERR(mvm, - "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", - iwl_read_prph(trans, SB_CPU_1_STATUS), - iwl_read_prph(trans, SB_CPU_2_STATUS)); } if (ret == -ETIMEDOUT) From ee02e598019e39717126c580e65fa74f2972ebc0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 11:43:42 +0300 Subject: [PATCH 007/114] iwlwifi: add vendor specific capabilities for some RFs On some RFs we want to advertise vendor specific capabilities to indicate support for improved beamforming rates and/or on 160 MHz, some APs where Intel has collaborated with the vendor will use it to improve behaviour. Add these elements where relevant, i.e. for HR and GF RFs. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.510f0ef9c2d5.If99bdb9009583ac7cc6cbb708e871a67df836dbe@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 475f951d4b1ef..f470f9aea50f5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -534,6 +534,17 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans, cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE); } +static const u8 iwl_vendor_caps[] = { + 0xdd, /* vendor element */ + 0x06, /* length */ + 0x00, 0x17, 0x35, /* Intel OUI */ + 0x08, /* type (Intel Capabilities) */ + /* followed by 16 bits of capabilities */ +#define IWL_VENDOR_CAP_IMPROVED_BF_FDBK_HE BIT(0) + IWL_VENDOR_CAP_IMPROVED_BF_FDBK_HE, + 0x00 +}; + static const struct ieee80211_sband_iftype_data iwl_he_capa[] = { { .types_mask = BIT(NL80211_IFTYPE_STATION), @@ -781,6 +792,12 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, if (fw_has_capa(&fw->ucode_capa, IWL_UCODE_TLV_CAPA_BROADCAST_TWT)) iftype_data->he_cap.he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_BCAST_TWT; + + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && + !is_ap) { + iftype_data->vendor_elems.data = iwl_vendor_caps; + iftype_data->vendor_elems.len = ARRAY_SIZE(iwl_vendor_caps); + } } static void iwl_init_he_hw_capab(struct iwl_trans *trans, From 8a2c1516231612c030cd980fa4e26d0f7267bfdd Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Sun, 17 Oct 2021 11:43:43 +0300 Subject: [PATCH 008/114] iwlwifi: mvm: add support for 160Mhz in ranging measurements Add support for 160Mhz bandwidth in ranging measurements for initiator and responder. Advertise 160Mhz in the supported bandwidths for ranging. Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.32a13ac0f4d4.I883492648518cc5067a2f91b7ecf8bfa55f6876a@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/location.h | 1 + .../wireless/intel/iwlwifi/mvm/ftm-initiator.c | 12 ++++++++++++ .../wireless/intel/iwlwifi/mvm/ftm-responder.c | 15 ++++++++++++--- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 ++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index 6bbb8b8c91cd6..294e733ecbc9b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -629,6 +629,7 @@ enum iwl_location_bw { IWL_LOCATION_BW_20MHZ, IWL_LOCATION_BW_40MHZ, IWL_LOCATION_BW_80MHZ, + IWL_LOCATION_BW_160MHZ, }; #define TK_11AZ_LEN 32 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c index 03e5bf5cb9094..73be95fffb954 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c @@ -324,6 +324,7 @@ iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm, u8 *ctrl_ch_position) { u32 freq = peer->chandef.chan->center_freq; + u8 cmd_ver; *channel = ieee80211_frequency_to_channel(freq); @@ -344,6 +345,17 @@ iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm, *format_bw = IWL_LOCATION_FRAME_FORMAT_VHT; *format_bw |= IWL_LOCATION_BW_80MHZ << LOCATION_BW_POS; break; + case NL80211_CHAN_WIDTH_160: + cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LOCATION_GROUP, + TOF_RANGE_REQ_CMD, + IWL_FW_CMD_VER_UNKNOWN); + + if (cmd_ver >= 13) { + *format_bw = IWL_LOCATION_FRAME_FORMAT_HE; + *format_bw |= IWL_LOCATION_BW_160MHZ << LOCATION_BW_POS; + break; + } + fallthrough; default: IWL_ERR(mvm, "Unsupported BW in FTM request (%d)\n", peer->chandef.width); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c index eba5433c2626d..bda6da7d988e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c @@ -46,8 +46,8 @@ static int iwl_mvm_ftm_responder_set_bw_v1(struct cfg80211_chan_def *chandef, } static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef, - u8 *format_bw, - u8 *ctrl_ch_position) + u8 *format_bw, u8 *ctrl_ch_position, + u8 cmd_ver) { switch (chandef->width) { case NL80211_CHAN_WIDTH_20_NOHT: @@ -68,6 +68,14 @@ static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef, *format_bw |= IWL_LOCATION_BW_80MHZ << LOCATION_BW_POS; *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); break; + case NL80211_CHAN_WIDTH_160: + if (cmd_ver >= 9) { + *format_bw = IWL_LOCATION_FRAME_FORMAT_HE; + *format_bw |= IWL_LOCATION_BW_160MHZ << LOCATION_BW_POS; + *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); + break; + } + fallthrough; default: return -ENOTSUPP; } @@ -140,7 +148,8 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm, if (cmd_ver >= 7) err = iwl_mvm_ftm_responder_set_bw_v2(chandef, &cmd.format_bw, - &cmd.ctrl_ch_position); + &cmd.ctrl_ch_position, + cmd_ver); else err = iwl_mvm_ftm_responder_set_bw_v1(chandef, &cmd.format_bw, &cmd.ctrl_ch_position); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 33198be6f0399..5374faa15684e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -145,7 +145,8 @@ static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = { .bandwidths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | BIT(NL80211_CHAN_WIDTH_20) | BIT(NL80211_CHAN_WIDTH_40) | - BIT(NL80211_CHAN_WIDTH_80), + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_160), .preambles = BIT(NL80211_PREAMBLE_LEGACY) | BIT(NL80211_PREAMBLE_HT) | BIT(NL80211_PREAMBLE_VHT) | From 57b7b345d279d08a6129dc61099b454847f71091 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 11:43:44 +0300 Subject: [PATCH 009/114] iwlwifi: mvm: Remove antenna c references Since antenna c is not in use and won't be relevant after the new rate & flags, remove all it's references Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.5e39106ec75b.I4281edc844f734bf9591396a5cc8009ad37ccda8@changeid Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/location.h | 2 +- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 5 +--- .../net/wireless/intel/iwlwifi/fw/api/rx.h | 3 +-- .../net/wireless/intel/iwlwifi/fw/api/tx.h | 3 +-- .../net/wireless/intel/iwlwifi/iwl-config.h | 1 - .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 7 ++--- .../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 4 --- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 26 ++++++------------- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 13 +++------- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 1 - drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 2 +- .../net/wireless/intel/iwlwifi/mvm/utils.c | 1 + 12 files changed, 20 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index 294e733ecbc9b..5f27829f89963 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -206,7 +206,7 @@ enum iwl_tof_responder_cfg_flags { IWL_TOF_RESPONDER_FLAGS_SPECIFIC_CALIB_MODE = BIT(8), IWL_TOF_RESPONDER_FLAGS_FAST_ALGO_SUPPORT = BIT(9), IWL_TOF_RESPONDER_FLAGS_RETRY_ON_ALGO_FAIL = BIT(10), - IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT = RATE_MCS_ANT_ABC_MSK, + IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT = RATE_MCS_ANT_AB_MSK, IWL_TOF_RESPONDER_FLAGS_NDP_SUPPORT = BIT(24), IWL_TOF_RESPONDER_FLAGS_LMR_FEEDBACK = BIT(25), IWL_TOF_RESPONDER_FLAGS_SESSION_ID = BIT(27), diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index fc2fa49e98252..810dceb649c71 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -372,12 +372,9 @@ enum { #define RATE_MCS_ANT_POS 14 #define RATE_MCS_ANT_A_MSK (1 << RATE_MCS_ANT_POS) #define RATE_MCS_ANT_B_MSK (2 << RATE_MCS_ANT_POS) -#define RATE_MCS_ANT_C_MSK (4 << RATE_MCS_ANT_POS) #define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | \ RATE_MCS_ANT_B_MSK) -#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \ - RATE_MCS_ANT_C_MSK) -#define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK +#define RATE_MCS_ANT_MSK RATE_MCS_ANT_AB_MSK /* Bit 17: (0) SS, (1) SS*2 */ #define RATE_MCS_STBC_POS 17 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 3f13b572915a8..88d600b376dc7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2020 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -13,7 +13,6 @@ #define IWL_RX_INFO_ENERGY_ANT_ABC_IDX 1 #define IWL_RX_INFO_ENERGY_ANT_A_MSK 0x000000ff #define IWL_RX_INFO_ENERGY_ANT_B_MSK 0x0000ff00 -#define IWL_RX_INFO_ENERGY_ANT_C_MSK 0x00ff0000 #define IWL_RX_INFO_ENERGY_ANT_A_POS 0 #define IWL_RX_INFO_ENERGY_ANT_B_POS 8 #define IWL_RX_INFO_ENERGY_ANT_C_POS 16 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index 24e4a82a55da1..c0caf9dca545f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2020 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021 Intel Corporation * Copyright (C) 2016-2017 Intel Deutschland GmbH */ #ifndef __iwl_fw_api_tx_h__ @@ -759,7 +759,6 @@ enum iwl_mac_beacon_flags { IWL_MAC_BEACON_CCK = BIT(8), IWL_MAC_BEACON_ANT_A = BIT(9), IWL_MAC_BEACON_ANT_B = BIT(10), - IWL_MAC_BEACON_ANT_C = BIT(11), IWL_MAC_BEACON_FILS = BIT(12), }; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index f55f08d4d5119..e06994610e77d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -95,7 +95,6 @@ enum iwl_nvm_type { #define ANT_AC (ANT_A | ANT_C) #define ANT_BC (ANT_B | ANT_C) #define ANT_ABC (ANT_A | ANT_B | ANT_C) -#define MAX_ANT_NUM 3 static inline u8 num_of_ant(u8 mask) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 5dc39fbb74d67..8c2251178f97a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -395,10 +395,9 @@ static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf, "A-MPDU size limit %d\n", lq_sta->pers.dbg_agg_frame_count_lim); desc += scnprintf(buff + desc, bufsz - desc, - "valid_tx_ant %s%s%s\n", + "valid_tx_ant %s%s\n", (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "", - (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "", - (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : ""); + (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : ""); desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X ", lq_sta->last_rate_n_flags); @@ -1060,8 +1059,6 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "A"); if (mvm->scan_rx_ant & ANT_B) pos += scnprintf(buf + pos, bufsz - pos, "B"); - if (mvm->scan_rx_ant & ANT_C) - pos += scnprintf(buf + pos, bufsz - pos, "C"); pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 2d58cb969918f..5b224a19bb320 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -32,10 +32,6 @@ static u8 rs_fw_set_active_chains(u8 chains) fw_chains |= IWL_TLC_MNG_CHAIN_A_MSK; if (chains & ANT_B) fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK; - if (chains & ANT_C) - WARN(false, - "tlc offload doesn't support antenna C. chains: 0x%x\n", - chains); return fw_chains; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index b97708cb869d5..b75505061e641 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -485,13 +485,9 @@ static const char *rs_pretty_ant(u8 ant) [ANT_A] = "A", [ANT_B] = "B", [ANT_AB] = "AB", - [ANT_C] = "C", - [ANT_AC] = "AC", - [ANT_BC] = "BC", - [ANT_ABC] = "ABC", }; - if (ant > ANT_ABC) + if (ant > ANT_AB) return "UNKNOWN"; return ant_name[ant]; @@ -654,8 +650,7 @@ static void rs_tl_turn_on_agg(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, static inline int get_num_of_ant_from_rate(u32 rate_n_flags) { return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) + - !!(rate_n_flags & RATE_MCS_ANT_B_MSK) + - !!(rate_n_flags & RATE_MCS_ANT_C_MSK); + !!(rate_n_flags & RATE_MCS_ANT_B_MSK); } /* @@ -820,7 +815,7 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, int index = rate->index; ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) & - RATE_MCS_ANT_ABC_MSK); + RATE_MCS_ANT_AB_MSK); if (is_legacy(rate)) { ucode_rate |= iwl_rates[index].plcp; @@ -885,7 +880,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, enum nl80211_band band, struct rs_rate *rate) { - u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK; + u32 ant_msk = ucode_rate & RATE_MCS_ANT_AB_MSK; u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate); u8 nss; @@ -981,9 +976,6 @@ static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate) { u8 new_ant_type; - if (!rate->ant || WARN_ON_ONCE(rate->ant & ANT_C)) - return 0; - if (!rs_is_valid_ant(valid_ant, rate->ant)) return 0; @@ -2652,7 +2644,6 @@ void rs_update_last_rssi(struct iwl_mvm *mvm, lq_sta->pers.chains = rx_status->chains; lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0]; lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1]; - lq_sta->pers.chain_signal[2] = rx_status->chain_signal[2]; lq_sta->pers.last_rssi = S8_MIN; for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { @@ -3323,7 +3314,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, int i; int num_rates = ARRAY_SIZE(lq_cmd->rs_table); __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate); - u8 ant = (ucode_rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS; + u8 ant = (ucode_rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; for (i = 0; i < num_rates; i++) lq_cmd->rs_table[i] = ucode_rate_le32; @@ -3693,7 +3684,7 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) char *type, *bw; u8 mcs = 0, nss = 0; - u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS; + u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; if (!(rate & RATE_MCS_HT_MSK) && !(rate & RATE_MCS_VHT_MSK) && @@ -3830,10 +3821,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, lq_sta->active_legacy_rate); desc += scnprintf(buff + desc, bufsz - desc, "fixed rate 0x%X\n", lq_sta->pers.dbg_fixed_rate); - desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s%s\n", + desc += scnprintf(buff + desc, bufsz - desc, "valid_tx_ant %s%s\n", (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "", - (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "", - (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : ""); + (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : ""); desc += scnprintf(buff + desc, bufsz - desc, "lq type %s\n", (is_legacy(rate)) ? "legacy" : is_vht(rate) ? "VHT" : "HT"); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 8ef5399ad9be6..87b0600ed48ab 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2020 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -103,7 +103,7 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, struct iwl_rx_phy_info *phy_info, struct ieee80211_rx_status *rx_status) { - int energy_a, energy_b, energy_c, max_energy; + int energy_a, energy_b, max_energy; u32 val; val = @@ -114,14 +114,10 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, energy_b = (val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >> IWL_RX_INFO_ENERGY_ANT_B_POS; energy_b = energy_b ? -energy_b : S8_MIN; - energy_c = (val & IWL_RX_INFO_ENERGY_ANT_C_MSK) >> - IWL_RX_INFO_ENERGY_ANT_C_POS; - energy_c = energy_c ? -energy_c : S8_MIN; max_energy = max(energy_a, energy_b); - max_energy = max(max_energy, energy_c); - IWL_DEBUG_STATS(mvm, "energy In A %d B %d C %d , and max %d\n", - energy_a, energy_b, energy_c, max_energy); + IWL_DEBUG_STATS(mvm, "energy In A %d B %d , and max %d\n", + energy_a, energy_b, max_energy); rx_status->signal = max_energy; rx_status->chains = (le16_to_cpu(phy_info->phy_flags) & @@ -129,7 +125,6 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, >> RX_RES_PHY_FLAGS_ANTENNA_POS; rx_status->chain_signal[0] = energy_a; rx_status->chain_signal[1] = energy_b; - rx_status->chain_signal[2] = energy_c; } /* diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index c12f303cf652c..ba65bfb2b43e4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -269,7 +269,6 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, (rate_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; rx_status->chain_signal[0] = energy_a; rx_status->chain_signal[1] = energy_b; - rx_status->chain_signal[2] = S8_MIN; } static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 0a13c2bda2eed..6151350fa66ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1329,7 +1329,7 @@ static void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags, struct ieee80211_tx_rate *r = &info->status.rates[0]; info->status.antenna = - ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); + ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS); iwl_mvm_hwrate_to_tx_rate(rate_n_flags, info->band, r); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index ec8a223f90e85..704fc71ac845b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -217,6 +217,7 @@ u8 first_antenna(u8 mask) return BIT(ffs(mask) - 1); } +#define MAX_ANT_NUM 2 /* * Toggles between TX antennas to send the probe request on. * Receives the bitmask of valid TX antennas and the *index* used From e79b2fc938f47dd520856667f1c2bac1380e97ab Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 11:43:45 +0300 Subject: [PATCH 010/114] iwlwifi: add some missing kernel-doc in struct iwl_fw The phy integration string members were missed, add them. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.8aa65feeda5f.Idf492c939f7f8856da09c5017c16b8b88438395d@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/img.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 153a3529e77ae..21a206631b2f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -194,6 +194,8 @@ struct iwl_fw_dbg { * @cipher_scheme: optional external cipher scheme. * @human_readable: human readable version * we get the ALIVE from the uCode + * @phy_integration_ver: PHY integration version string + * @phy_integration_ver_len: length of @phy_integration_ver */ struct iwl_fw { u32 ucode_ver; From 3d563f1290c48186bdd3327811fada0cac1c000f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 11:43:46 +0300 Subject: [PATCH 011/114] iwlwifi: api: remove unused RX status bits These bits are unused and don't actually exist in the firmware API any longer. Remove them. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.022a9f87fdbd.Iae7b8a0196b6e94f9dc525e92a541a28374b0cac@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/rx.h | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 88d600b376dc7..aa43ef67a2b5f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -125,14 +125,12 @@ enum iwl_rx_phy_flags { * @RX_MPDU_RES_STATUS_OVERRUN_OK: there was no RXE overflow * @RX_MPDU_RES_STATUS_SRC_STA_FOUND: station was found * @RX_MPDU_RES_STATUS_KEY_VALID: key was valid - * @RX_MPDU_RES_STATUS_KEY_PARAM_OK: key parameters were usable * @RX_MPDU_RES_STATUS_ICV_OK: ICV is fine, if not, the packet is destroyed * @RX_MPDU_RES_STATUS_MIC_OK: used for CCM alg only. TKIP MIC is checked * in the driver. * @RX_MPDU_RES_STATUS_TTAK_OK: TTAK is fine * @RX_MPDU_RES_STATUS_MNG_FRAME_REPLAY_ERR: valid for alg = CCM_CMAC or - * alg = CCM only. Checks replay attack for 11w frames. Relevant only if - * %RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME is set. + * alg = CCM only. Checks replay attack for 11w frames. * @RX_MPDU_RES_STATUS_SEC_NO_ENC: this frame is not encrypted * @RX_MPDU_RES_STATUS_SEC_WEP_ENC: this frame is encrypted using WEP * @RX_MPDU_RES_STATUS_SEC_CCM_ENC: this frame is encrypted using CCM @@ -144,9 +142,6 @@ enum iwl_rx_phy_flags { * @RX_MPDU_RES_STATUS_SEC_ENC_ERR: this frame couldn't be decrypted * @RX_MPDU_RES_STATUS_SEC_ENC_MSK: bitmask of the encryption algorithm * @RX_MPDU_RES_STATUS_DEC_DONE: this frame has been successfully decrypted - * @RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP: extended IV (set with TKIP) - * @RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT: key ID comparison done - * @RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME: this frame is an 11w management frame * @RX_MPDU_RES_STATUS_CSUM_DONE: checksum was done by the hw * @RX_MPDU_RES_STATUS_CSUM_OK: checksum found no errors * @RX_MPDU_RES_STATUS_STA_ID_MSK: station ID mask @@ -157,7 +152,6 @@ enum iwl_mvm_rx_status { RX_MPDU_RES_STATUS_OVERRUN_OK = BIT(1), RX_MPDU_RES_STATUS_SRC_STA_FOUND = BIT(2), RX_MPDU_RES_STATUS_KEY_VALID = BIT(3), - RX_MPDU_RES_STATUS_KEY_PARAM_OK = BIT(4), RX_MPDU_RES_STATUS_ICV_OK = BIT(5), RX_MPDU_RES_STATUS_MIC_OK = BIT(6), RX_MPDU_RES_STATUS_TTAK_OK = BIT(7), @@ -171,9 +165,6 @@ enum iwl_mvm_rx_status { RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8), RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8), RX_MPDU_RES_STATUS_DEC_DONE = BIT(11), - RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP = BIT(13), - RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT = BIT(14), - RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME = BIT(15), RX_MPDU_RES_STATUS_CSUM_DONE = BIT(16), RX_MPDU_RES_STATUS_CSUM_OK = BIT(17), RX_MDPU_RES_STATUS_STA_ID_SHIFT = 24, @@ -235,7 +226,6 @@ enum iwl_rx_mpdu_status { IWL_RX_MPDU_STATUS_OVERRUN_OK = BIT(1), IWL_RX_MPDU_STATUS_SRC_STA_FOUND = BIT(2), IWL_RX_MPDU_STATUS_KEY_VALID = BIT(3), - IWL_RX_MPDU_STATUS_KEY_PARAM_OK = BIT(4), IWL_RX_MPDU_STATUS_ICV_OK = BIT(5), IWL_RX_MPDU_STATUS_MIC_OK = BIT(6), IWL_RX_MPDU_RES_STATUS_TTAK_OK = BIT(7), @@ -250,12 +240,8 @@ enum iwl_rx_mpdu_status { IWL_RX_MPDU_STATUS_SEC_EXT_ENC = 0x4 << 8, IWL_RX_MPDU_STATUS_SEC_GCM = 0x5 << 8, IWL_RX_MPDU_STATUS_DECRYPTED = BIT(11), - IWL_RX_MPDU_STATUS_WEP_MATCH = BIT(12), - IWL_RX_MPDU_STATUS_EXT_IV_MATCH = BIT(13), - IWL_RX_MPDU_STATUS_KEY_ID_MATCH = BIT(14), IWL_RX_MPDU_STATUS_ROBUST_MNG_FRAME = BIT(15), - IWL_RX_MPDU_STATUS_KEY = 0x3f0000, IWL_RX_MPDU_STATUS_DUPLICATE = BIT(22), IWL_RX_MPDU_STATUS_STA_ID = 0x1f000000, From e0e0d16641cd8fa163ba21b98f8da9c5780ded5f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 11:43:47 +0300 Subject: [PATCH 012/114] iwlwifi: remove MODULE_AUTHOR() statements Consensus seems to be emerging that corporations or groups shouldn't be listed as module authors, and we will not maintain this email address any longer. Just remove it. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.32109514aad0.I91a7d745f4ab50ee8ef918ece00dda8251541595@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 1 - drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 1 - drivers/net/wireless/intel/iwlwifi/iwl-drv.h | 3 +-- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 69d1aae96bbb4..50d4e94817903 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -52,7 +52,6 @@ #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux" MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_AUTHOR(DRV_AUTHOR); MODULE_LICENSE("GPL"); /* Please keep this array *SORTED* by hex value. diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 77124b8b235ee..6712ff6772e7d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -31,7 +31,6 @@ #define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux" MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_AUTHOR(DRV_AUTHOR); MODULE_LICENSE("GPL"); #ifdef CONFIG_IWLWIFI_DEBUGFS diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h index b6442df0c6439..2e2d60a586925 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014, 2020 Intel Corporation + * Copyright (C) 2005-2014, 2020-2021 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH */ #ifndef __iwl_drv_h__ @@ -9,7 +9,6 @@ /* for all modules */ #define DRV_NAME "iwlwifi" -#define DRV_AUTHOR "Intel Corporation " /* radio config bits (actual values from NVM definition) */ #define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 77ea2d0a30916..c7ae284ae96d9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -29,7 +29,6 @@ #define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_AUTHOR(DRV_AUTHOR); MODULE_LICENSE("GPL"); static const struct iwl_op_mode_ops iwl_mvm_ops; From 854fe828e58ceafbab92d408ad344a168ea41555 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 11:43:48 +0300 Subject: [PATCH 013/114] iwlwifi: remove contact information The list address is going away, and the postal address isn't useful, remove all the contact information. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017113927.f73e3b6384cb.I967fd394995461277eafa149bb25cefd1673751e@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 5 ----- drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 5 ----- drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 5 ----- drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/dev.h | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/devices.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/led.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/led.h | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/lib.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/power.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/power.h | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/rs.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/rs.h | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/rx.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/rxon.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/scan.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/tt.c | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/tt.h | 4 ---- drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 5 ----- drivers/net/wireless/intel/iwlwifi/dvm/ucode.c | 5 ----- drivers/net/wireless/intel/iwlwifi/fw/img.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-debug.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c | 5 ----- drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 5 ----- drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 5 ----- 35 files changed, 169 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c index 44c4fe9753901..116defb15afbd 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c @@ -3,11 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2018 - 2020 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c index df6ac00340b26..ab2038a3fbe21 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c @@ -3,11 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2018 - 2020 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c index 6cdd7d983bdae..e2e23d2bc1fe5 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c @@ -3,11 +3,6 @@ * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2018 - 2020 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c index 541a3ec857770..20929e59c2f4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c @@ -3,11 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2018 - 2020 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index 9110492018387..b246dbd371b35 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c @@ -3,10 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2018 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h index 4bd792c06ff6e..bbd5740912012 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h @@ -2,11 +2,6 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014, 2020 Intel Corporation. All rights reserved. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ /* * Please use this file (dev.h) for driver implementation definitions. diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c index c3e25885d1943..39e40901fa464 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c @@ -3,11 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2019 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c index e8a4d604b9106..71f67a019cf60 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c @@ -3,11 +3,6 @@ * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2019 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.h b/drivers/net/wireless/intel/iwlwifi/dvm/led.h index 6fe20180dc87c..5038fc378a1f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.h @@ -2,11 +2,6 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #ifndef __iwl_leds_h__ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c index 3b937a7dd4032..40d790b36d85b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c @@ -2,11 +2,6 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 75e7665773c52..754876cd27ce8 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -6,11 +6,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 50d4e94817903..fbd57a2b2bd50 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -6,11 +6,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c index 93ef023905c96..6d16a7105656c 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c @@ -6,10 +6,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.h b/drivers/net/wireless/intel/iwlwifi/dvm/power.h index 3f8db1fc4b590..f38201ce1e991 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/power.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.h @@ -5,10 +5,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ #ifndef __iwl_power_setting_h__ #define __iwl_power_setting_h__ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c index 548540dd0c0f7..b7c8b209bfea4 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c @@ -3,11 +3,6 @@ * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2019 - 2020 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h index 68a840d739e83..0b47f1993c5db 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h @@ -2,11 +2,6 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #ifndef __iwl_agn_rs_h__ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c index 3cd7b423c588d..db0c41bbeb0e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c @@ -7,11 +7,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portionhelp of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c index 12a3d464ae640..70338bc7bb540 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c @@ -3,11 +3,6 @@ * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c index c4ecf6ed21860..2d38227dfdd20 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c @@ -3,10 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2018 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c index ddc14059b07d1..8f7a0f36c276b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c @@ -5,11 +5,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c index 2684a924ba574..43e8d04d5a8b2 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c @@ -6,10 +6,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h index 3b0ff458a158b..7ace052fc78a4 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.h @@ -5,10 +5,6 @@ * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ #ifndef __iwl_tt_setting_h__ #define __iwl_tt_setting_h__ diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c index 847b8e07f81c5..60a7b61d59aa3 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c @@ -3,11 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2019 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c index 24194c7912181..4b27a53d0bb4a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c @@ -3,11 +3,6 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.c b/drivers/net/wireless/intel/iwlwifi/fw/img.c index c2a4e60518bc7..5755e179066ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.c @@ -18,11 +18,6 @@ * * The full GNU General Public License is included in this distribution * in the file called COPYING. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * * BSD LICENSE * * Copyright(c) 2019 - 2020 Intel Corporation diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h index 528eba441926d..8db7aeddfd057 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h @@ -5,11 +5,6 @@ * Copyright(c) 2018 - 2020 Intel Corporation * * Portions of this file are derived from the ipw3945 project. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #ifndef __iwl_debug_h__ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h index 1bc6ecc321404..347fd95c4e3a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h @@ -4,11 +4,6 @@ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH * Copyright(c) 2018 - 2019 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #if !defined(__IWLWIFI_DEVICE_TRACE_DATA) || defined(TRACE_HEADER_MULTI_READ) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h index a57019241a780..0af9d8362c5b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h @@ -3,11 +3,6 @@ * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2016-2017 Intel Deutschland GmbH - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #if !defined(__IWLWIFI_DEVICE_TRACE_IO) || defined(TRACE_HEADER_MULTI_READ) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h index 72ca882daed5e..46ed723f138a6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h @@ -5,11 +5,6 @@ * Copyright(c) 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH * Copyright(c) 2018 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #if !defined(__IWLWIFI_DEVICE_TRACE_IWLWIFI) || defined(TRACE_HEADER_MULTI_READ) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h index d0467da5af034..7dd70011fd1ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h @@ -2,11 +2,6 @@ /****************************************************************************** * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #if !defined(__IWLWIFI_DEVICE_TRACE_MSG) || defined(TRACE_HEADER_MULTI_READ) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h index 2228faefffbca..3ec0205ac9f90 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-ucode.h @@ -2,11 +2,6 @@ /****************************************************************************** * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #if !defined(__IWLWIFI_DEVICE_TRACE_UCODE) || defined(TRACE_HEADER_MULTI_READ) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c index b5037db0c3817..999b7c652289d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c @@ -3,11 +3,6 @@ * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2018 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h index fc8bc212ee847..1455b578358bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h @@ -4,11 +4,6 @@ * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. * Copyright(C) 2016 Intel Deutschland GmbH * Copyright(c) 2018 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #ifndef __IWLWIFI_DEVICE_TRACE diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index b75505061e641..2783aca3619af 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -4,11 +4,6 @@ * Copyright(c) 2005 - 2014, 2018 - 2021 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index 32104c9f8f5ee..3e206df57347c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -5,11 +5,6 @@ * Copyright(c) 2015 Intel Mobile Communications GmbH * Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2018 - 2019 Intel Corporation - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * *****************************************************************************/ #ifndef __rs_h__ From 98c8bd77e62437499b6e421e4dce2d03c65ceed0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 12:40:08 +0300 Subject: [PATCH 014/114] iwlwifi: fix fw/img.c license statement We still had the entire license statement here, but with BSD, so the SPDX tag was not matching the actual text. Fix that and remove all the texts since they're no longer needed. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.328c2b33081c.Ib3570e8f214538a878204cc2b0b612b5ed0571b3@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/img.c | 53 ++------------------- 1 file changed, 3 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.c b/drivers/net/wireless/intel/iwlwifi/fw/img.c index 5755e179066ae..24a9666736913 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.c @@ -1,54 +1,7 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* * Copyright(c) 2019 - 2020 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * BSD LICENSE - * - * Copyright(c) 2019 - 2020 Intel Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ + */ #include "img.h" From 34c4eca167aeeb2e9436dbf0f565c547052a6c14 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 12:40:09 +0300 Subject: [PATCH 015/114] iwlwifi: api: fix struct iwl_wowlan_status_v7 kernel-doc This was mislabeled as struct iwl_wowlan_status, fix that. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.f2ff92fcbe4d.Id2b8edd2160d9a703a7a2744e1139017cfd958c0@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/d3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index 3ec82cae39816..e199d1813a613 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -624,7 +624,7 @@ struct iwl_wowlan_status_v6 { } __packed; /* WOWLAN_STATUSES_API_S_VER_6 */ /** - * struct iwl_wowlan_status - WoWLAN status + * struct iwl_wowlan_status_v7 - WoWLAN status * @gtk: GTK data * @igtk: IGTK data * @replay_ctr: GTK rekey replay counter From 4634b176810400be041ea106f03e4f013ddabc1b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 12:40:10 +0300 Subject: [PATCH 016/114] iwlwifi: mvm: correct sta-state logic for TDLS For TDLS stations, much of the sta-state logic shouldn't apply, since they don't affect the link to the AP. Fix that. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.954001ec079f.I9deb8bc7520ad569a453f72c8d99adc9c99c9be3@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 5374faa15684e..56da2759777cc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3194,32 +3194,35 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, if (iwl_mvm_phy_ctx_count(mvm) > 1) iwl_mvm_teardown_tdls_peers(mvm); - if (sta->tdls) + if (sta->tdls) { iwl_mvm_tdls_check_trigger(mvm, vif, sta->addr, NL80211_TDLS_ENABLE_LINK); + } else { + /* enable beacon filtering */ + WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); - /* enable beacon filtering */ - WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); - - /* - * Now that the station is authorized, i.e., keys were already - * installed, need to indicate to the FW that - * multicast data frames can be forwarded to the driver - */ - iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); + /* + * Now that the station is authorized, i.e., keys were already + * installed, need to indicate to the FW that + * multicast data frames can be forwarded to the driver + */ + iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); + } iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band, true); } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { - /* Multicast data frames are no longer allowed */ - iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); + if (!sta->tdls) { + /* Multicast data frames are no longer allowed */ + iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); - /* disable beacon filtering */ - ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); - WARN_ON(ret && - !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, - &mvm->status)); + /* disable beacon filtering */ + ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); + WARN_ON(ret && + !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, + &mvm->status)); + } ret = 0; } else if (old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTH) { From fdb70083dd2886e45dc2575b8b21dbf63505c29b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 12:40:11 +0300 Subject: [PATCH 017/114] iwlwifi: fw dump: add infrastructure for dump scrubbing In firmware dumps, currently all kinds of key material may be included, e.g. in host commands (if firmware crashes during the processing of a key-related command) or in the TX FIFO(s) if we have been using in-TX-command key material. Additionally, some firmware versions will advertise sections of their internal data to not dump, due to them containing some sensitive data. Add some infrastructure to allow scrubbing this data out, as dependent on the opmode's idea of what will need to be done. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.360cc8fe55b1.Ie3bd3ece38043969f7e116e61a6ec1197a58d78b@changeid Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 1 + drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 44 +++++++++++++++++-- drivers/net/wireless/intel/iwlwifi/fw/img.h | 2 + drivers/net/wireless/intel/iwlwifi/fw/init.c | 6 ++- .../net/wireless/intel/iwlwifi/fw/paging.c | 4 +- .../net/wireless/intel/iwlwifi/fw/runtime.h | 5 +++ .../net/wireless/intel/iwlwifi/iwl-trans.h | 25 +++++++++-- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- .../net/wireless/intel/iwlwifi/pcie/trans.c | 12 +++-- 9 files changed, 89 insertions(+), 12 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 d8b5870d6e9af..6ab5755beb533 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -7,6 +7,7 @@ #include +#define IWL_FW_INI_HW_SMEM_REGION_ID 15 #define IWL_FW_INI_MAX_REGION_ID 64 #define IWL_FW_INI_MAX_NAME 32 #define IWL_FW_INI_MAX_CFG_NAME 64 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index b7f2f0662b826..a39013c401c92 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -159,11 +159,15 @@ static void iwl_fwrt_dump_txf(struct iwl_fw_runtime *fwrt, iwl_trans_read_prph(fwrt->trans, TXF_READ_MODIFY_DATA + offset); /* Read FIFO */ - fifo_len /= sizeof(u32); /* Size in DWORDS */ - for (i = 0; i < fifo_len; i++) + for (i = 0; i < fifo_len / sizeof(u32); i++) fifo_data[i] = iwl_trans_read_prph(fwrt->trans, TXF_READ_MODIFY_DATA + offset); + + if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf) + fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx, + fifo_data, fifo_len); + *dump_data = iwl_fw_error_next_data(*dump_data); } @@ -659,6 +663,10 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt, iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len); *dump_data = iwl_fw_error_next_data(*dump_data); + if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem) + fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, ofs, + dump_mem->data, len); + IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type); } @@ -752,6 +760,12 @@ static void iwl_dump_paging(struct iwl_fw_runtime *fwrt, PAGING_BLOCK_SIZE, DMA_BIDIRECTIONAL); (*data) = iwl_fw_error_next_data(*data); + + if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem) + fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, + fwrt->fw_paging_db[i].fw_offs, + paging->data, + PAGING_BLOCK_SIZE); } } @@ -980,6 +994,11 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, dump_data->data + data_size, data_size); + if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem) + fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, addr, + dump_data->data + data_size, + data_size); + dump_data = iwl_fw_error_next_data(dump_data); } @@ -1146,6 +1165,13 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt, iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data, le32_to_cpu(reg->dev_addr.size)); + if ((le32_to_cpu(reg->id) & IWL_FW_INI_REGION_V2_MASK) == + IWL_FW_INI_HW_SMEM_REGION_ID && + fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf) + fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx, + range->data, + le32_to_cpu(reg->dev_addr.size)); + return sizeof(*range) + le32_to_cpu(range->range_data_size); } @@ -1338,6 +1364,10 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt, for (i = 0; i < iter->fifo_size; i += sizeof(*data)) *data++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr)); + if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf) + fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx, + reg_dump, iter->fifo_size); + out: iwl_trans_release_nic_access(fwrt->trans); @@ -2360,7 +2390,9 @@ static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt, if (dump_data->monitor_only) dump_mask &= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR); - fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask); + fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask, + fwrt->sanitize_ops, + fwrt->sanitize_ctx); file_len = le32_to_cpu(dump_file->file_len); fw_error_dump.fwrt_len = file_len; @@ -2788,6 +2820,12 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt) iwl_trans_read_mem_bytes(fwrt->trans, cfg->d3_debug_data_base_addr, fwrt->dump.d3_debug_data, cfg->d3_debug_data_length); + + if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem) + fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, + cfg->d3_debug_data_base_addr, + fwrt->dump.d3_debug_data, + cfg->d3_debug_data_length); } IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 21a206631b2f7..6099d1edaff2d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -124,11 +124,13 @@ struct fw_img { * @fw_paging_phys: page phy pointer * @fw_paging_block: pointer to the allocated block * @fw_paging_size: page size + * @fw_offs: offset in the device */ struct iwl_fw_paging { dma_addr_t fw_paging_phys; struct page *fw_paging_block; u32 fw_paging_size; + u32 fw_offs; }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index 2ecec00db9da7..566957ac45393 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2020 Intel Corporation + * Copyright (C) 2019-2021 Intel Corporation */ #include "iwl-drv.h" #include "runtime.h" @@ -16,6 +16,8 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, const struct iwl_fw *fw, const struct iwl_fw_runtime_ops *ops, void *ops_ctx, + const struct iwl_dump_sanitize_ops *sanitize_ops, + void *sanitize_ctx, struct dentry *dbgfs_dir) { int i; @@ -26,6 +28,8 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, fwrt->dev = trans->dev; fwrt->dump.conf = FW_DBG_INVALID; fwrt->ops = ops; + fwrt->sanitize_ops = sanitize_ops; + fwrt->sanitize_ctx = sanitize_ctx; fwrt->ops_ctx = ops_ctx; for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) { fwrt->dump.wks[i].idx = i; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c index 4a8fe9641a321..58ca3849d1f3f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2019 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -152,6 +152,7 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt, memcpy(page_address(fwrt->fw_paging_db[0].fw_paging_block), image->sec[sec_idx].data, image->sec[sec_idx].len); + fwrt->fw_paging_db[0].fw_offs = image->sec[sec_idx].offset; dma_sync_single_for_device(fwrt->trans->dev, fwrt->fw_paging_db[0].fw_paging_phys, fwrt->fw_paging_db[0].fw_paging_size, @@ -197,6 +198,7 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt, memcpy(page_address(block->fw_paging_block), image->sec[sec_idx].data + offset, len); + block->fw_offs = image->sec[sec_idx].offset + offset; dma_sync_single_for_device(fwrt->trans->dev, block->fw_paging_phys, block->fw_paging_size, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 35af85a5430be..a569ce3c5e961 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -105,6 +105,9 @@ struct iwl_fw_runtime { const struct iwl_fw_runtime_ops *ops; void *ops_ctx; + const struct iwl_dump_sanitize_ops *sanitize_ops; + void *sanitize_ctx; + /* Paging */ struct iwl_fw_paging fw_paging_db[NUM_OF_FW_PAGING_BLOCKS]; u16 num_of_paging_blk; @@ -161,6 +164,8 @@ struct iwl_fw_runtime { void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, const struct iwl_fw *fw, const struct iwl_fw_runtime_ops *ops, void *ops_ctx, + const struct iwl_dump_sanitize_ops *sanitize_ops, + void *sanitize_ctx, struct dentry *dbgfs_dir); static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 8f0ff540f4398..32d228d7e1fe6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -362,6 +362,20 @@ struct iwl_hcmd_arr { #define HCMD_ARR(x) \ { .arr = x, .size = ARRAY_SIZE(x) } +/** + * struct iwl_dump_sanitize_ops - dump sanitization operations + * @frob_txf: Scrub the TX FIFO data + * @frob_hcmd: Scrub a host command, the %hcmd pointer is to the header + * but that might be short or long (&struct iwl_cmd_header or + * &struct iwl_cmd_header_wide) + * @frob_mem: Scrub memory data + */ +struct iwl_dump_sanitize_ops { + void (*frob_txf)(void *ctx, void *buf, size_t buflen); + void (*frob_hcmd)(void *ctx, void *hcmd, size_t buflen); + void (*frob_mem)(void *ctx, u32 mem_addr, void *mem, size_t buflen); +}; + /** * struct iwl_trans_config - transport configuration * @@ -586,7 +600,9 @@ struct iwl_trans_ops { u32 value); struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans, - u32 dump_mask); + u32 dump_mask, + const struct iwl_dump_sanitize_ops *sanitize_ops, + void *sanitize_ctx); void (*debugfs_cleanup)(struct iwl_trans *trans); void (*sync_nmi)(struct iwl_trans *trans); int (*set_pnvm)(struct iwl_trans *trans, const void *data, u32 len); @@ -1086,11 +1102,14 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans, } static inline struct iwl_trans_dump_data * -iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask) +iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask, + const struct iwl_dump_sanitize_ops *sanitize_ops, + void *sanitize_ctx) { if (!trans->ops->dump_data) return NULL; - return trans->ops->dump_data(trans, dump_mask); + return trans->ops->dump_data(trans, dump_mask, + sanitize_ops, sanitize_ctx); } static inline struct iwl_device_tx_cmd * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index c7ae284ae96d9..b7f203fe7753f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -774,7 +774,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mvm->hw = hw; iwl_fw_runtime_init(&mvm->fwrt, trans, fw, &iwl_mvm_fwrt_ops, mvm, - dbgfs_dir); + NULL, NULL, dbgfs_dir); iwl_mvm_get_acpi_tables(mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index f252680f18e88..9e462633af552 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3203,9 +3203,11 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, u32 *len) return 0; } -static struct iwl_trans_dump_data -*iwl_trans_pcie_dump_data(struct iwl_trans *trans, - u32 dump_mask) +static struct iwl_trans_dump_data * +iwl_trans_pcie_dump_data(struct iwl_trans *trans, + u32 dump_mask, + const struct iwl_dump_sanitize_ops *sanitize_ops, + void *sanitize_ctx) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_fw_error_dump_data *data; @@ -3305,6 +3307,10 @@ static struct iwl_trans_dump_data txcmd->caplen = cpu_to_le32(caplen); memcpy(txcmd->data, cmdq->entries[idx].cmd, caplen); + if (sanitize_ops && sanitize_ops->frob_hcmd) + sanitize_ops->frob_hcmd(sanitize_ctx, + txcmd->data, + caplen); txcmd = (void *)((u8 *)txcmd->data + caplen); } From fad92a1d11f6ef81cca3c1ea24d5703930339291 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 12:40:12 +0300 Subject: [PATCH 018/114] iwlwifi: parse debug exclude data from firmware file Parse the memory dump exclusion TLVs from the firmware file and save the data to be able to apply them later upon dump. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.ec280bcb32cb.Iac0da0e22d7c3c0e237867c9113a06ddd95c7a51@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 7 ++++ drivers/net/wireless/intel/iwlwifi/fw/img.h | 8 ++++ drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 42 ++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 6c8e9f3a6af2e..3a031070d3679 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -100,6 +100,9 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_PNVM_SKU = 64, IWL_UCODE_TLV_TCM_DEBUG_ADDRS = 65, + IWL_UCODE_TLV_SEC_TABLE_ADDR = 66, + IWL_UCODE_TLV_D3_KEK_KCK_ADDR = 67, + IWL_UCODE_TLV_FW_NUM_STATIONS = IWL_UCODE_TLV_CONST_BASE + 0, IWL_UCODE_TLV_TYPE_DEBUG_INFO = IWL_UCODE_TLV_DEBUG_BASE + 0, @@ -956,6 +959,10 @@ struct iwl_fw_tcm_error_addr { __le32 addr; }; /* FW_TLV_TCM_ERROR_INFO_ADDRS_S */ +struct iwl_fw_dump_exclude { + __le32 addr, size; +}; + static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv, size_t fixed_size, size_t var_size) { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 6099d1edaff2d..993bda17fa309 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -176,6 +176,10 @@ struct iwl_fw_dbg { u32 dump_mask; }; +struct iwl_dump_exclude { + u32 addr, size; +}; + /** * struct iwl_fw - variables associated with the firmware * @@ -198,6 +202,8 @@ struct iwl_fw_dbg { * we get the ALIVE from the uCode * @phy_integration_ver: PHY integration version string * @phy_integration_ver_len: length of @phy_integration_ver + * @dump_excl: image dump exclusion areas for RT image + * @dump_excl_wowlan: image dump exclusion areas for WoWLAN image */ struct iwl_fw { u32 ucode_ver; @@ -229,6 +235,8 @@ struct iwl_fw { u8 *phy_integration_ver; u32 phy_integration_ver_len; + + struct iwl_dump_exclude dump_excl[2], dump_excl_wowlan[2]; }; static inline const char *get_fw_dbg_mode_string(int mode) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 6712ff6772e7d..8296b71aa76fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -549,6 +549,43 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, return 0; } +static void iwl_drv_set_dump_exclude(struct iwl_drv *drv, + enum iwl_ucode_tlv_type tlv_type, + const void *tlv_data, u32 tlv_len) +{ + const struct iwl_fw_dump_exclude *fw = tlv_data; + struct iwl_dump_exclude *excl; + + if (tlv_len < sizeof(*fw)) + return; + + if (tlv_type == IWL_UCODE_TLV_SEC_TABLE_ADDR) { + excl = &drv->fw.dump_excl[0]; + + /* second time we find this, it's for WoWLAN */ + if (excl->addr) + excl = &drv->fw.dump_excl_wowlan[0]; + } else if (fw_has_capa(&drv->fw.ucode_capa, + IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG)) { + /* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is regular image */ + excl = &drv->fw.dump_excl[0]; + } else { + /* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is WoWLAN image */ + excl = &drv->fw.dump_excl_wowlan[0]; + } + + if (excl->addr) + excl++; + + if (excl->addr) { + IWL_DEBUG_FW_INFO(drv, "found too many excludes in fw file\n"); + return; + } + + excl->addr = le32_to_cpu(fw->addr) & ~FW_ADDR_CACHE_CONTROL; + excl->size = le32_to_cpu(fw->size); +} + static int iwl_parse_tlv_firmware(struct iwl_drv *drv, const struct firmware *ucode_raw, struct iwl_firmware_pieces *pieces, @@ -1165,6 +1202,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, return -ENOMEM; drv->fw.phy_integration_ver_len = tlv_len; break; + case IWL_UCODE_TLV_SEC_TABLE_ADDR: + case IWL_UCODE_TLV_D3_KEK_KCK_ADDR: + iwl_drv_set_dump_exclude(drv, tlv_type, + tlv_data, tlv_len); + break; default: IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); break; From 12d60c1efc29e19f4dc0dc70cd48ce097fce6447 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 12:40:13 +0300 Subject: [PATCH 019/114] iwlwifi: mvm: scrub key material in firmware dumps Use the previously added infrastructure to scrub key material in firmware dumps: * in the TX FIFO data, just search for each key that we know about and override such data * scrub various commands that we sent to the firmware if they're present * in firmware memory, where advertised by firmware TLVs Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.d1514964e6a7.I18f8c2ce8082952af7cfe5f8fe75fe51851b8853@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 179 ++++++++++++++++++- 1 file changed, 178 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index b7f203fe7753f..3b0d5a0685414 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -725,6 +725,183 @@ static int iwl_mvm_start_post_nvm(struct iwl_mvm *mvm) return 0; } +struct iwl_mvm_frob_txf_data { + u8 *buf; + size_t buflen; +}; + +static void iwl_mvm_frob_txf_key_iter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + void *data) +{ + struct iwl_mvm_frob_txf_data *txf = data; + u8 keylen, match, matchend; + u8 *keydata; + size_t i; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + keydata = key->key; + keylen = key->keylen; + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + /* + * WEP has short keys which might show up in the payload, + * and then you can deduce the key, so in this case just + * remove all FIFO data. + * For TKIP, we don't know the phase 2 keys here, so same. + */ + memset(txf->buf, 0xBB, txf->buflen); + return; + default: + return; + } + + /* scan for key material and clear it out */ + match = 0; + for (i = 0; i < txf->buflen; i++) { + if (txf->buf[i] != keydata[match]) { + match = 0; + continue; + } + match++; + if (match == keylen) { + memset(txf->buf + i - keylen, 0xAA, keylen); + match = 0; + } + } + + /* we're dealing with a FIFO, so check wrapped around data */ + matchend = match; + for (i = 0; match && i < keylen - match; i++) { + if (txf->buf[i] != keydata[match]) + break; + match++; + if (match == keylen) { + memset(txf->buf, 0xAA, i + 1); + memset(txf->buf + txf->buflen - matchend, 0xAA, + matchend); + break; + } + } +} + +static void iwl_mvm_frob_txf(void *ctx, void *buf, size_t buflen) +{ + struct iwl_mvm_frob_txf_data txf = { + .buf = buf, + .buflen = buflen, + }; + struct iwl_mvm *mvm = ctx; + + /* embedded key material exists only on old API */ + if (iwl_mvm_has_new_tx_api(mvm)) + return; + + rcu_read_lock(); + ieee80211_iter_keys_rcu(mvm->hw, NULL, iwl_mvm_frob_txf_key_iter, &txf); + rcu_read_unlock(); +} + +static void iwl_mvm_frob_hcmd(void *ctx, void *hcmd, size_t len) +{ + /* we only use wide headers for commands */ + struct iwl_cmd_header_wide *hdr = hcmd; + unsigned int frob_start = sizeof(*hdr), frob_end = 0; + + if (len < sizeof(hdr)) + return; + + /* all the commands we care about are in LONG_GROUP */ + if (hdr->group_id != LONG_GROUP) + return; + + switch (hdr->cmd) { + case WEP_KEY: + case WOWLAN_TKIP_PARAM: + case WOWLAN_KEK_KCK_MATERIAL: + case ADD_STA_KEY: + /* + * blank out everything here, easier than dealing + * with the various versions of the command + */ + frob_end = INT_MAX; + break; + case MGMT_MCAST_KEY: + frob_start = offsetof(struct iwl_mvm_mgmt_mcast_key_cmd, igtk); + BUILD_BUG_ON(offsetof(struct iwl_mvm_mgmt_mcast_key_cmd, igtk) != + offsetof(struct iwl_mvm_mgmt_mcast_key_cmd_v1, igtk)); + + frob_end = offsetofend(struct iwl_mvm_mgmt_mcast_key_cmd, igtk); + BUILD_BUG_ON(offsetof(struct iwl_mvm_mgmt_mcast_key_cmd, igtk) < + offsetof(struct iwl_mvm_mgmt_mcast_key_cmd_v1, igtk)); + break; + } + + if (frob_start >= frob_end) + return; + + if (frob_end > len) + frob_end = len; + + memset((u8 *)hcmd + frob_start, 0xAA, frob_end - frob_start); +} + +static void iwl_mvm_frob_mem(void *ctx, u32 mem_addr, void *mem, size_t buflen) +{ + const struct iwl_dump_exclude *excl; + struct iwl_mvm *mvm = ctx; + int i; + + switch (mvm->fwrt.cur_fw_img) { + case IWL_UCODE_INIT: + default: + /* not relevant */ + return; + case IWL_UCODE_REGULAR: + case IWL_UCODE_REGULAR_USNIFFER: + excl = mvm->fw->dump_excl; + break; + case IWL_UCODE_WOWLAN: + excl = mvm->fw->dump_excl_wowlan; + break; + } + + BUILD_BUG_ON(sizeof(mvm->fw->dump_excl) != + sizeof(mvm->fw->dump_excl_wowlan)); + + for (i = 0; i < ARRAY_SIZE(mvm->fw->dump_excl); i++) { + u32 start, end; + + if (!excl[i].addr || !excl[i].size) + continue; + + start = excl[i].addr; + end = start + excl[i].size; + + if (end <= mem_addr || start >= mem_addr + buflen) + continue; + + if (start < mem_addr) + start = mem_addr; + + if (end > mem_addr + buflen) + end = mem_addr + buflen; + + memset((u8 *)mem + start - mem_addr, 0xAA, end - start); + } +} + +static const struct iwl_dump_sanitize_ops iwl_mvm_sanitize_ops = { + .frob_txf = iwl_mvm_frob_txf, + .frob_hcmd = iwl_mvm_frob_hcmd, + .frob_mem = iwl_mvm_frob_mem, +}; + static struct iwl_op_mode * iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir) @@ -774,7 +951,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mvm->hw = hw; iwl_fw_runtime_init(&mvm->fwrt, trans, fw, &iwl_mvm_fwrt_ops, mvm, - NULL, NULL, dbgfs_dir); + &iwl_mvm_sanitize_ops, mvm, dbgfs_dir); iwl_mvm_get_acpi_tables(mvm); From 48c6ebc13c1ce184716b1380d26fcc41e212fa5f Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 12:40:14 +0300 Subject: [PATCH 020/114] iwlwifi: mvm: update definitions due to new rate & flags As a part of preparing to the new rate & flags version Update the relevant definitions and use them. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.5862bf4f14c4.Ib476b5443faa085539b79d49a0aebd81a213b42f@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 58 +++++++------- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 2 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 34 ++++---- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 80 +++++++++---------- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 26 +++--- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 78 +++++++++--------- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 12 +-- .../net/wireless/intel/iwlwifi/mvm/utils.c | 2 +- 9 files changed, 147 insertions(+), 147 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index 810dceb649c71..c150bae761be8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -248,7 +248,7 @@ enum { }; /* - * rate_n_flags bit fields + * rate_n_flags bit fields version 1 * * The 32-bit value has different layouts in the low 8 bites depending on the * format. There are three formats, HT, VHT and legacy (11abg, with subformats @@ -266,15 +266,15 @@ enum { /* Bit 8: (1) HT format, (0) legacy or VHT format */ #define RATE_MCS_HT_POS 8 -#define RATE_MCS_HT_MSK (1 << RATE_MCS_HT_POS) +#define RATE_MCS_HT_MSK_V1 BIT(RATE_MCS_HT_POS) /* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ -#define RATE_MCS_CCK_POS 9 -#define RATE_MCS_CCK_MSK (1 << RATE_MCS_CCK_POS) +#define RATE_MCS_CCK_POS_V1 9 +#define RATE_MCS_CCK_MSK_V1 BIT(RATE_MCS_CCK_POS_V1) /* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */ -#define RATE_MCS_VHT_POS 26 -#define RATE_MCS_VHT_MSK (1 << RATE_MCS_VHT_POS) +#define RATE_MCS_VHT_POS_V1 26 +#define RATE_MCS_VHT_MSK_V1 BIT(RATE_MCS_VHT_POS_V1) /* @@ -300,15 +300,15 @@ enum { * streams and 16-23 have three streams. We could also support MCS 32 * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) */ -#define RATE_HT_MCS_RATE_CODE_MSK 0x7 -#define RATE_HT_MCS_NSS_POS 3 -#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS) +#define RATE_HT_MCS_RATE_CODE_MSK_V1 0x7 +#define RATE_HT_MCS_NSS_POS_V1 3 +#define RATE_HT_MCS_NSS_MSK_V1 (3 << RATE_HT_MCS_NSS_POS_V1) /* Bit 10: (1) Use Green Field preamble */ #define RATE_HT_MCS_GF_POS 10 #define RATE_HT_MCS_GF_MSK (1 << RATE_HT_MCS_GF_POS) -#define RATE_HT_MCS_INDEX_MSK 0x3f +#define RATE_HT_MCS_INDEX_MSK_V1 0x3f /* * Very High-throughput (VHT) rate format for bits 7:0 @@ -347,26 +347,26 @@ enum { * 110) 11 Mbps * (bit 7 is 0) */ -#define RATE_LEGACY_RATE_MSK 0xff +#define RATE_LEGACY_RATE_MSK_V1 0xff /* Bit 10 - OFDM HE */ -#define RATE_MCS_HE_POS 10 -#define RATE_MCS_HE_MSK BIT(RATE_MCS_HE_POS) +#define RATE_MCS_HE_POS_V1 10 +#define RATE_MCS_HE_MSK_V1 BIT(RATE_MCS_HE_POS_V1) /* * Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz * 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT */ #define RATE_MCS_CHAN_WIDTH_POS 11 -#define RATE_MCS_CHAN_WIDTH_MSK (3 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_MSK_V1 (3 << RATE_MCS_CHAN_WIDTH_POS) #define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS) #define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS) #define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS) #define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS) /* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ -#define RATE_MCS_SGI_POS 13 -#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS) +#define RATE_MCS_SGI_POS_V1 13 +#define RATE_MCS_SGI_MSK_V1 BIT(RATE_MCS_SGI_POS_V1) /* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */ #define RATE_MCS_ANT_POS 14 @@ -408,27 +408,27 @@ enum { * 3 (does not occur) */ #define RATE_MCS_HE_GI_LTF_POS 20 -#define RATE_MCS_HE_GI_LTF_MSK (3 << RATE_MCS_HE_GI_LTF_POS) +#define RATE_MCS_HE_GI_LTF_MSK_V1 (3 << RATE_MCS_HE_GI_LTF_POS) /* Bit 22-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */ -#define RATE_MCS_HE_TYPE_POS 22 -#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS) -#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS) -#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS) -#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS) -#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_POS_V1 22 +#define RATE_MCS_HE_TYPE_SU_V1 (0 << RATE_MCS_HE_TYPE_POS_V1) +#define RATE_MCS_HE_TYPE_EXT_SU_V1 BIT(RATE_MCS_HE_TYPE_POS_V1) +#define RATE_MCS_HE_TYPE_MU_V1 (2 << RATE_MCS_HE_TYPE_POS_V1) +#define RATE_MCS_HE_TYPE_TRIG_V1 (3 << RATE_MCS_HE_TYPE_POS_V1) +#define RATE_MCS_HE_TYPE_MSK_V1 (3 << RATE_MCS_HE_TYPE_POS_V1) /* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */ -#define RATE_MCS_DUP_POS 24 -#define RATE_MCS_DUP_MSK (3 << RATE_MCS_DUP_POS) +#define RATE_MCS_DUP_POS_V1 24 +#define RATE_MCS_DUP_MSK_V1 (3 << RATE_MCS_DUP_POS_V1) /* Bit 27: (1) LDPC enabled, (0) LDPC disabled */ -#define RATE_MCS_LDPC_POS 27 -#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS) +#define RATE_MCS_LDPC_POS_V1 27 +#define RATE_MCS_LDPC_MSK_V1 BIT(RATE_MCS_LDPC_POS_V1) /* Bit 28: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */ -#define RATE_MCS_HE_106T_POS 28 -#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS) +#define RATE_MCS_HE_106T_POS_V1 28 +#define RATE_MCS_HE_106T_MSK_V1 BIT(RATE_MCS_HE_106T_POS_V1) /* Bit 30-31: (1) RTS, (2) CTS */ #define RATE_MCS_RTS_REQUIRED_POS (30) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index fd352b2624a6f..0065cc76a2a04 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -846,7 +846,7 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm, tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate)); if (rate == IWL_FIRST_CCK_RATE) - tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK); + tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK_V1); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 56da2759777cc..1d664dd5915ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4878,7 +4878,7 @@ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) { - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { case RATE_MCS_CHAN_WIDTH_20: rinfo->bw = RATE_INFO_BW_20; break; @@ -4893,24 +4893,24 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) break; } - if (rate_n_flags & RATE_MCS_HT_MSK) { + if (rate_n_flags & RATE_MCS_HT_MSK_V1) { rinfo->flags |= RATE_INFO_FLAGS_MCS; - rinfo->mcs = u32_get_bits(rate_n_flags, RATE_HT_MCS_INDEX_MSK); + rinfo->mcs = u32_get_bits(rate_n_flags, RATE_HT_MCS_INDEX_MSK_V1); rinfo->nss = u32_get_bits(rate_n_flags, - RATE_HT_MCS_NSS_MSK) + 1; - if (rate_n_flags & RATE_MCS_SGI_MSK) + RATE_HT_MCS_NSS_MSK_V1) + 1; + if (rate_n_flags & RATE_MCS_SGI_MSK_V1) rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; - } else if (rate_n_flags & RATE_MCS_VHT_MSK) { + } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS; rinfo->mcs = u32_get_bits(rate_n_flags, RATE_VHT_MCS_RATE_CODE_MSK); rinfo->nss = u32_get_bits(rate_n_flags, RATE_VHT_MCS_NSS_MSK) + 1; - if (rate_n_flags & RATE_MCS_SGI_MSK) + if (rate_n_flags & RATE_MCS_SGI_MSK_V1) rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; - } else if (rate_n_flags & RATE_MCS_HE_MSK) { + } else if (rate_n_flags & RATE_MCS_HE_MSK_V1) { u32 gi_ltf = u32_get_bits(rate_n_flags, - RATE_MCS_HE_GI_LTF_MSK); + RATE_MCS_HE_GI_LTF_MSK_V1); rinfo->flags |= RATE_INFO_FLAGS_HE_MCS; rinfo->mcs = u32_get_bits(rate_n_flags, @@ -4918,24 +4918,24 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) rinfo->nss = u32_get_bits(rate_n_flags, RATE_VHT_MCS_NSS_MSK) + 1; - if (rate_n_flags & RATE_MCS_HE_106T_MSK) { + if (rate_n_flags & RATE_MCS_HE_106T_MSK_V1) { rinfo->bw = RATE_INFO_BW_HE_RU; rinfo->he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_106; } - switch (rate_n_flags & RATE_MCS_HE_TYPE_MSK) { - case RATE_MCS_HE_TYPE_SU: - case RATE_MCS_HE_TYPE_EXT_SU: + switch (rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1) { + case RATE_MCS_HE_TYPE_SU_V1: + case RATE_MCS_HE_TYPE_EXT_SU_V1: if (gi_ltf == 0 || gi_ltf == 1) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else if (gi_ltf == 2) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6; - else if (rate_n_flags & RATE_MCS_SGI_MSK) + else if (rate_n_flags & RATE_MCS_SGI_MSK_V1) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2; break; - case RATE_MCS_HE_TYPE_MU: + case RATE_MCS_HE_TYPE_MU_V1: if (gi_ltf == 0 || gi_ltf == 1) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else if (gi_ltf == 2) @@ -4943,7 +4943,7 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) else rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2; break; - case RATE_MCS_HE_TYPE_TRIG: + case RATE_MCS_HE_TYPE_TRIG_V1: if (gi_ltf == 0 || gi_ltf == 1) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6; else @@ -4954,7 +4954,7 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) if (rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK) rinfo->he_dcm = 1; } else { - switch (u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK)) { + switch (u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK_V1)) { case IWL_RATE_1M_PLCP: rinfo->legacy = 10; break; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 2783aca3619af..df248d83606ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -330,15 +330,15 @@ static const struct rs_tx_column rs_tx_columns[] = { static inline u8 rs_extract_rate(u32 rate_n_flags) { /* also works for HT because bits 7:6 are zero there */ - return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK); + return (u8)(rate_n_flags & RATE_LEGACY_RATE_MSK_V1); } static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) { int idx = 0; - if (rate_n_flags & RATE_MCS_HT_MSK) { - idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK; + if (rate_n_flags & RATE_MCS_HT_MSK_V1) { + idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK_V1; idx += IWL_RATE_MCS_0_INDEX; /* skip 9M not supported in HT*/ @@ -346,8 +346,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) idx += 1; if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE)) return idx; - } else if (rate_n_flags & RATE_MCS_VHT_MSK || - rate_n_flags & RATE_MCS_HE_MSK) { + } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1 || + rate_n_flags & RATE_MCS_HE_MSK_V1) { idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; idx += IWL_RATE_MCS_0_INDEX; @@ -356,8 +356,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) idx++; if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE)) return idx; - if ((rate_n_flags & RATE_MCS_HE_MSK) && - (idx <= IWL_LAST_HE_RATE)) + if ((rate_n_flags & RATE_MCS_HE_MSK_V1) && + idx <= IWL_LAST_HE_RATE) return idx; } else { /* legacy rate format, search for match in table */ @@ -815,7 +815,7 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, if (is_legacy(rate)) { ucode_rate |= iwl_rates[index].plcp; if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) - ucode_rate |= RATE_MCS_CCK_MSK; + ucode_rate |= RATE_MCS_CCK_MSK_V1; return ucode_rate; } @@ -830,7 +830,7 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, IWL_ERR(mvm, "Invalid HT rate index %d\n", index); index = IWL_LAST_HT_RATE; } - ucode_rate |= RATE_MCS_HT_MSK; + ucode_rate |= RATE_MCS_HT_MSK_V1; if (is_ht_siso(rate)) ucode_rate |= iwl_rates[index].plcp_ht_siso; @@ -843,7 +843,7 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); index = IWL_LAST_VHT_RATE; } - ucode_rate |= RATE_MCS_VHT_MSK; + ucode_rate |= RATE_MCS_VHT_MSK_V1; if (is_vht_siso(rate)) ucode_rate |= iwl_rates[index].plcp_vht_siso; else if (is_vht_mimo2(rate)) @@ -863,9 +863,9 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, ucode_rate |= rate->bw; if (rate->sgi) - ucode_rate |= RATE_MCS_SGI_MSK; + ucode_rate |= RATE_MCS_SGI_MSK_V1; if (rate->ldpc) - ucode_rate |= RATE_MCS_LDPC_MSK; + ucode_rate |= RATE_MCS_LDPC_MSK_V1; return ucode_rate; } @@ -888,9 +888,9 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, rate->ant = (ant_msk >> RATE_MCS_ANT_POS); /* Legacy */ - if (!(ucode_rate & RATE_MCS_HT_MSK) && - !(ucode_rate & RATE_MCS_VHT_MSK) && - !(ucode_rate & RATE_MCS_HE_MSK)) { + if (!(ucode_rate & RATE_MCS_HT_MSK_V1) && + !(ucode_rate & RATE_MCS_VHT_MSK_V1) && + !(ucode_rate & RATE_MCS_HE_MSK_V1)) { if (num_of_ant == 1) { if (band == NL80211_BAND_5GHZ) rate->type = LQ_LEGACY_A; @@ -902,20 +902,20 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, } /* HT, VHT or HE */ - if (ucode_rate & RATE_MCS_SGI_MSK) + if (ucode_rate & RATE_MCS_SGI_MSK_V1) rate->sgi = true; - if (ucode_rate & RATE_MCS_LDPC_MSK) + if (ucode_rate & RATE_MCS_LDPC_MSK_V1) rate->ldpc = true; if (ucode_rate & RATE_MCS_STBC_MSK) rate->stbc = true; if (ucode_rate & RATE_MCS_BF_MSK) rate->bfer = true; - rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; + rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK_V1; - if (ucode_rate & RATE_MCS_HT_MSK) { - nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >> - RATE_HT_MCS_NSS_POS) + 1; + if (ucode_rate & RATE_MCS_HT_MSK_V1) { + nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK_V1) >> + RATE_HT_MCS_NSS_POS_V1) + 1; if (nss == 1) { rate->type = LQ_HT_SISO; @@ -928,7 +928,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, } else { WARN_ON_ONCE(1); } - } else if (ucode_rate & RATE_MCS_VHT_MSK) { + } else if (ucode_rate & RATE_MCS_VHT_MSK_V1) { nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> RATE_VHT_MCS_NSS_POS) + 1; @@ -943,7 +943,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, } else { WARN_ON_ONCE(1); } - } else if (ucode_rate & RATE_MCS_HE_MSK) { + } else if (ucode_rate & RATE_MCS_HE_MSK_V1) { nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> RATE_VHT_MCS_NSS_POS) + 1; @@ -2895,7 +2895,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) mvm->drv_rx_stats.success_frames++; - switch (rate & RATE_MCS_CHAN_WIDTH_MSK) { + switch (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) { case RATE_MCS_CHAN_WIDTH_20: mvm->drv_rx_stats.bw_20_frames++; break; @@ -2912,10 +2912,10 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) WARN_ONCE(1, "bad BW. rate 0x%x", rate); } - if (rate & RATE_MCS_HT_MSK) { + if (rate & RATE_MCS_HT_MSK_V1) { mvm->drv_rx_stats.ht_frames++; - nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1; - } else if (rate & RATE_MCS_VHT_MSK) { + nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) >> RATE_HT_MCS_NSS_POS_V1) + 1; + } else if (rate & RATE_MCS_VHT_MSK_V1) { mvm->drv_rx_stats.vht_frames++; nss = ((rate & RATE_VHT_MCS_NSS_MSK) >> RATE_VHT_MCS_NSS_POS) + 1; @@ -2928,7 +2928,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) else if (nss == 2) mvm->drv_rx_stats.mimo2_frames++; - if (rate & RATE_MCS_SGI_MSK) + if (rate & RATE_MCS_SGI_MSK_V1) mvm->drv_rx_stats.sgi_frames++; else mvm->drv_rx_stats.ngi_frames++; @@ -3681,9 +3681,9 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) u8 mcs = 0, nss = 0; u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; - if (!(rate & RATE_MCS_HT_MSK) && - !(rate & RATE_MCS_VHT_MSK) && - !(rate & RATE_MCS_HE_MSK)) { + if (!(rate & RATE_MCS_HT_MSK_V1) && + !(rate & RATE_MCS_VHT_MSK_V1) && + !(rate & RATE_MCS_HE_MSK_V1)) { int index = iwl_hwrate_to_plcp_idx(rate); return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", @@ -3692,17 +3692,17 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) iwl_rate_mcs[index].mbps); } - if (rate & RATE_MCS_VHT_MSK) { + if (rate & RATE_MCS_VHT_MSK_V1) { type = "VHT"; mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; nss = ((rate & RATE_VHT_MCS_NSS_MSK) >> RATE_VHT_MCS_NSS_POS) + 1; - } else if (rate & RATE_MCS_HT_MSK) { + } else if (rate & RATE_MCS_HT_MSK_V1) { type = "HT"; - mcs = rate & RATE_HT_MCS_INDEX_MSK; - nss = ((rate & RATE_HT_MCS_NSS_MSK) - >> RATE_HT_MCS_NSS_POS) + 1; - } else if (rate & RATE_MCS_HE_MSK) { + mcs = rate & RATE_HT_MCS_INDEX_MSK_V1; + nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) + >> RATE_HT_MCS_NSS_POS_V1) + 1; + } else if (rate & RATE_MCS_HE_MSK_V1) { type = "HE"; mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; nss = ((rate & RATE_VHT_MCS_NSS_MSK) @@ -3711,7 +3711,7 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) type = "Unknown"; /* shouldn't happen */ } - switch (rate & RATE_MCS_CHAN_WIDTH_MSK) { + switch (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) { case RATE_MCS_CHAN_WIDTH_20: bw = "20Mhz"; break; @@ -3731,9 +3731,9 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) return scnprintf(buf, bufsz, "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s", rate, type, rs_pretty_ant(ant), bw, mcs, nss, - (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ", + (rate & RATE_MCS_SGI_MSK_V1) ? "SGI " : "NGI ", (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", - (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", + (rate & RATE_MCS_LDPC_MSK_V1) ? "LDPC " : "", (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "", (rate & RATE_MCS_BF_MSK) ? "BF " : ""); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 87b0600ed48ab..d22f40a5354d8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -230,7 +230,7 @@ static void iwl_mvm_rx_handle_tcm(struct iwl_mvm *mvm, mdata->rx.airtime += le16_to_cpu(phy_info->frame_time); } - if (!(rate_n_flags & (RATE_MCS_HT_MSK | RATE_MCS_VHT_MSK))) + if (!(rate_n_flags & (RATE_MCS_HT_MSK_V1 | RATE_MCS_VHT_MSK_V1))) return; mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); @@ -244,10 +244,10 @@ static void iwl_mvm_rx_handle_tcm(struct iwl_mvm *mvm, mvmsta->sta_id != mvmvif->ap_sta_id) return; - if (rate_n_flags & RATE_MCS_HT_MSK) { - thr = thresh_tpt[rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK]; - thr *= 1 + ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >> - RATE_HT_MCS_NSS_POS); + if (rate_n_flags & RATE_MCS_HT_MSK_V1) { + thr = thresh_tpt[rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK_V1]; + thr *= 1 + ((rate_n_flags & RATE_HT_MCS_NSS_MSK_V1) >> + RATE_HT_MCS_NSS_POS_V1); } else { if (WARN_ON((rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK) >= ARRAY_SIZE(thresh_tpt))) @@ -257,7 +257,7 @@ static void iwl_mvm_rx_handle_tcm(struct iwl_mvm *mvm, RATE_VHT_MCS_NSS_POS); } - thr <<= ((rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) >> + thr <<= ((rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) >> RATE_MCS_CHAN_WIDTH_POS); mdata->uapsd_nonagg_detect.rx_bytes += len; @@ -450,7 +450,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, } /* Set up the HT phy flags */ - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { case RATE_MCS_CHAN_WIDTH_20: break; case RATE_MCS_CHAN_WIDTH_40: @@ -463,20 +463,20 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->bw = RATE_INFO_BW_160; break; } - if (!(rate_n_flags & RATE_MCS_CCK_MSK) && - rate_n_flags & RATE_MCS_SGI_MSK) + if (!(rate_n_flags & RATE_MCS_CCK_MSK_V1) && + rate_n_flags & RATE_MCS_SGI_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; if (rate_n_flags & RATE_HT_MCS_GF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; - if (rate_n_flags & RATE_MCS_LDPC_MSK) + if (rate_n_flags & RATE_MCS_LDPC_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; - if (rate_n_flags & RATE_MCS_HT_MSK) { + if (rate_n_flags & RATE_MCS_HT_MSK_V1) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->encoding = RX_ENC_HT; - rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; + rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - } else if (rate_n_flags & RATE_MCS_VHT_MSK) { + } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->nss = diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index ba65bfb2b43e4..8cfec733756bd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1197,7 +1197,7 @@ static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm, } if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH2_CRC_OK, phy_data4) && - (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) != RATE_MCS_CHAN_WIDTH_20) { + (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) != RATE_MCS_CHAN_WIDTH_20) { he_mu->flags1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_RU_KNOWN | IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH2_CTR_26T_RU_KNOWN); @@ -1234,7 +1234,7 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data, * the TSF/timers are not be transmitted in HE-MU. */ u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK); - u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; + u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1; u8 offs = 0; rx_status->bw = RATE_INFO_BW_HE_RU; @@ -1289,13 +1289,13 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data, if (he_mu) he_mu->flags2 |= - le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK, + le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK_V1, rate_n_flags), IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); - else if (he_type == RATE_MCS_HE_TYPE_TRIG) + else if (he_type == RATE_MCS_HE_TYPE_TRIG_V1) he->data6 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_KNOWN) | - le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK, + le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK_V1, rate_n_flags), IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW); } @@ -1440,7 +1440,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); struct ieee80211_radiotap_he *he = NULL; struct ieee80211_radiotap_he_mu *he_mu = NULL; - u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; + u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1; u8 stbc, ltf; static const struct ieee80211_radiotap_he known = { .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | @@ -1493,15 +1493,15 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, } } - if (he_type == RATE_MCS_HE_TYPE_EXT_SU && - rate_n_flags & RATE_MCS_HE_106T_MSK) { + if (he_type == RATE_MCS_HE_TYPE_EXT_SU_V1 && + rate_n_flags & RATE_MCS_HE_106T_MSK_V1) { rx_status->bw = RATE_INFO_BW_HE_RU; rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; } /* actually data is filled in mac80211 */ - if (he_type == RATE_MCS_HE_TYPE_SU || - he_type == RATE_MCS_HE_TYPE_EXT_SU) + if (he_type == RATE_MCS_HE_TYPE_SU_V1 || + he_type == RATE_MCS_HE_TYPE_EXT_SU_V1) he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); @@ -1520,39 +1520,39 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, #define CHECK_TYPE(F) \ BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ - (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS)) + (RATE_MCS_HE_TYPE_ ## F ##_V1 >> RATE_MCS_HE_TYPE_POS_V1)) CHECK_TYPE(SU); CHECK_TYPE(EXT_SU); CHECK_TYPE(MU); CHECK_TYPE(TRIG); - he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS); + he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS_V1); if (rate_n_flags & RATE_MCS_BF_MSK) he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF); - switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >> + switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK_V1) >> RATE_MCS_HE_GI_LTF_POS) { case 0: - if (he_type == RATE_MCS_HE_TYPE_TRIG) + if (he_type == RATE_MCS_HE_TYPE_TRIG_V1) rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; else rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; - if (he_type == RATE_MCS_HE_TYPE_MU) + if (he_type == RATE_MCS_HE_TYPE_MU_V1) ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; else ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X; break; case 1: - if (he_type == RATE_MCS_HE_TYPE_TRIG) + if (he_type == RATE_MCS_HE_TYPE_TRIG_V1) rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; else rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; break; case 2: - if (he_type == RATE_MCS_HE_TYPE_TRIG) { + if (he_type == RATE_MCS_HE_TYPE_TRIG_V1) { rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; } else { @@ -1561,9 +1561,9 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, } break; case 3: - if ((he_type == RATE_MCS_HE_TYPE_SU || - he_type == RATE_MCS_HE_TYPE_EXT_SU) && - rate_n_flags & RATE_MCS_SGI_MSK) + if ((he_type == RATE_MCS_HE_TYPE_SU_V1 || + he_type == RATE_MCS_HE_TYPE_EXT_SU_V1) && + rate_n_flags & RATE_MCS_SGI_MSK_V1) rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; @@ -1729,7 +1729,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status = IEEE80211_SKB_RXCB(skb); /* This may be overridden by iwl_mvm_rx_he() to HE_RU */ - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { case RATE_MCS_CHAN_WIDTH_20: break; case RATE_MCS_CHAN_WIDTH_40: @@ -1743,7 +1743,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, break; } - if (rate_n_flags & RATE_MCS_HE_MSK) + if (rate_n_flags & RATE_MCS_HE_MSK_V1) iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags, phy_info, queue); @@ -1760,7 +1760,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; } /* set the preamble flag if appropriate */ - if (rate_n_flags & RATE_MCS_CCK_MSK && + if (rate_n_flags & RATE_MCS_CCK_MSK_V1 && phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE; @@ -1936,20 +1936,20 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } } - if (!(rate_n_flags & RATE_MCS_CCK_MSK) && - rate_n_flags & RATE_MCS_SGI_MSK) + if (!(rate_n_flags & RATE_MCS_CCK_MSK_V1) && + rate_n_flags & RATE_MCS_SGI_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; if (rate_n_flags & RATE_HT_MCS_GF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; - if (rate_n_flags & RATE_MCS_LDPC_MSK) + if (rate_n_flags & RATE_MCS_LDPC_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; - if (rate_n_flags & RATE_MCS_HT_MSK) { + if (rate_n_flags & RATE_MCS_HT_MSK_V1) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->encoding = RX_ENC_HT; - rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; + rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - } else if (rate_n_flags & RATE_MCS_VHT_MSK) { + } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->nss = @@ -1960,7 +1960,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; if (rate_n_flags & RATE_MCS_BF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_BF; - } else if (!(rate_n_flags & RATE_MCS_HE_MSK)) { + } else if (!(rate_n_flags & RATE_MCS_HE_MSK_V1)) { int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, rx_status->band); @@ -2060,7 +2060,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, } /* This may be overridden by iwl_mvm_rx_he() to HE_RU */ - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { case RATE_MCS_CHAN_WIDTH_20: break; case RATE_MCS_CHAN_WIDTH_40: @@ -2074,7 +2074,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, break; } - if (rate_n_flags & RATE_MCS_HE_MSK) + if (rate_n_flags & RATE_MCS_HE_MSK_V1) iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags, phy_info, queue); @@ -2090,20 +2090,20 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, rcu_read_lock(); - if (!(rate_n_flags & RATE_MCS_CCK_MSK) && - rate_n_flags & RATE_MCS_SGI_MSK) + if (!(rate_n_flags & RATE_MCS_CCK_MSK_V1) && + rate_n_flags & RATE_MCS_SGI_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; if (rate_n_flags & RATE_HT_MCS_GF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; - if (rate_n_flags & RATE_MCS_LDPC_MSK) + if (rate_n_flags & RATE_MCS_LDPC_MSK_V1) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; - if (rate_n_flags & RATE_MCS_HT_MSK) { + if (rate_n_flags & RATE_MCS_HT_MSK_V1) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->encoding = RX_ENC_HT; - rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; + rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - } else if (rate_n_flags & RATE_MCS_VHT_MSK) { + } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; @@ -2119,7 +2119,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK) + 1; - } else if (rate_n_flags & RATE_MCS_HE_MSK) { + } else if (rate_n_flags & RATE_MCS_HE_MSK_V1) { rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_HE_NSTS_MSK) + 1; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index d78e436fa8b53..ce8bdbc70b7e3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -163,7 +163,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum nl80211_band band, tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; if (band == NL80211_BAND_2GHZ && !no_cck) - return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK | + return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK_V1 | tx_ant); else return cpu_to_le32(IWL_RATE_6M_PLCP | tx_ant); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 6151350fa66ca..ff29c4b140dc1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -303,7 +303,7 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, /* Set CCK flag as needed */ if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) - rate_flags |= RATE_MCS_CCK_MSK; + rate_flags |= RATE_MCS_CCK_MSK_V1; return (u32)rate_plcp | rate_flags; } @@ -1290,7 +1290,7 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, { if (rate_n_flags & RATE_HT_MCS_GF_MSK) r->flags |= IEEE80211_TX_RC_GREEN_FIELD; - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { case RATE_MCS_CHAN_WIDTH_20: break; case RATE_MCS_CHAN_WIDTH_40: @@ -1303,12 +1303,12 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, r->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH; break; } - if (rate_n_flags & RATE_MCS_SGI_MSK) + if (rate_n_flags & RATE_MCS_SGI_MSK_V1) r->flags |= IEEE80211_TX_RC_SHORT_GI; - if (rate_n_flags & RATE_MCS_HT_MSK) { + if (rate_n_flags & RATE_MCS_HT_MSK_V1) { r->flags |= IEEE80211_TX_RC_MCS; - r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK; - } else if (rate_n_flags & RATE_MCS_VHT_MSK) { + r->idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1; + } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { ieee80211_rate_set_vht( r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK, ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 704fc71ac845b..70ca6d7a31bf2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -159,7 +159,7 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, enum nl80211_band band) { - int rate = rate_n_flags & RATE_LEGACY_RATE_MSK; + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; int idx; int band_offset = 0; From 179354a6637f8cb8e09060065795b45aaa952b8d Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 12:40:15 +0300 Subject: [PATCH 021/114] iwlwifi: mvm: add definitions for new rate & flags As a part of preparing to the new rate & flags, add new needed definitions. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.41563bea6610.I51a886fa75cca723c81877b386ba41b2a9db1122@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 148 +++++++++++++++++- 1 file changed, 144 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index c150bae761be8..8d71988975351 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -359,10 +359,6 @@ enum { */ #define RATE_MCS_CHAN_WIDTH_POS 11 #define RATE_MCS_CHAN_WIDTH_MSK_V1 (3 << RATE_MCS_CHAN_WIDTH_POS) -#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS) -#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS) -#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS) -#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS) /* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ #define RATE_MCS_SGI_POS_V1 13 @@ -437,6 +433,150 @@ enum { #define RATE_MCS_CTS_REQUIRED_POS (31) #define RATE_MCS_CTS_REQUIRED_MSK (0x1 << RATE_MCS_CTS_REQUIRED_POS) +/* rate_n_flags bit field version 2 + * + * The 32-bit value has different layouts in the low 8 bits depending on the + * format. There are three formats, HT, VHT and legacy (11abg, with subformats + * for CCK and OFDM). + * + */ + +/* Bits 10-8: rate format + * (0) Legacy CCK (1) Legacy OFDM (2) High-throughput (HT) + * (3) Very High-throughput (VHT) (4) High-efficiency (HE) + * (5) Extremely High-throughput (EHT) + */ +#define RATE_MCS_MOD_TYPE_POS 8 +#define RATE_MCS_MOD_TYPE_MSK (0x7 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_CCK_MSK (0 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_LEGACY_OFDM_MSK (1 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_HT_MSK (2 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_VHT_MSK (3 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_HE_MSK (4 << RATE_MCS_MOD_TYPE_POS) +#define RATE_MCS_EHT_MSK (5 << RATE_MCS_MOD_TYPE_POS) + +/* + * Legacy CCK rate format for bits 0:3: + * + * (0) 0xa - 1 Mbps + * (1) 0x14 - 2 Mbps + * (2) 0x37 - 5.5 Mbps + * (3) 0x6e - 11 nbps + * + * Legacy OFDM rate format for bis 3:0: + * + * (0) 6 Mbps + * (1) 9 Mbps + * (2) 12 Mbps + * (3) 18 Mbps + * (4) 24 Mbps + * (5) 36 Mbps + * (6) 48 Mbps + * (7) 54 Mbps + * + */ +#define RATE_LEGACY_RATE_MSK 0x7 + +/* + * HT, VHT, HE, EHT rate format for bits 3:0 + * 3-0: MCS + * + */ +#define RATE_HT_MCS_CODE_MSK 0x7 +#define RATE_MCS_NSS_POS 4 +#define RATE_MCS_NSS_MSK (1 << RATE_MCS_NSS_POS) +#define RATE_MCS_CODE_MSK 0xf +#define RATE_HT_MCS_INDEX(r) ((((r) & RATE_MCS_NSS_MSK) >> 1) | \ + ((r) & RATE_HT_MCS_CODE_MSK)) + +/* Bits 7-5: reserved */ + +/* + * Bits 13-11: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz, (4) 320MHz + */ +#define RATE_MCS_CHAN_WIDTH_MSK (0x7 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS) +#define RATE_MCS_CHAN_WIDTH_320 (4 << RATE_MCS_CHAN_WIDTH_POS) + +/* Bit 15-14: Antenna selection: + * Bit 14: Ant A active + * Bit 15: Ant B active + * + * All relevant definitions are same as in v1 + */ + +/* Bit 16 (1) LDPC enables, (0) LDPC disabled */ +#define RATE_MCS_LDPC_POS 16 +#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS) + +/* Bit 17: (0) SS, (1) SS*2 (same as v1) */ + +/* Bit 18: OFDM-HE dual carrier mode (same as v1) */ + +/* Bit 19: (0) Beamforming is off, (1) Beamforming is on (same as v1) */ + +/* + * Bit 22-20: HE LTF type and guard interval + * CCK: + * 0 long preamble + * 1 short preamble + * HT/VHT: + * 0 0.8us + * 1 0.4us + * HE (ext) SU: + * 0 1xLTF+0.8us + * 1 2xLTF+0.8us + * 2 2xLTF+1.6us + * 3 4xLTF+3.2us + * 4 4xLTF+0.8us + * HE MU: + * 0 4xLTF+0.8us + * 1 2xLTF+0.8us + * 2 2xLTF+1.6us + * 3 4xLTF+3.2us + * HE TRIG: + * 0 1xLTF+1.6us + * 1 2xLTF+1.6us + * 2 4xLTF+3.2us + * */ +#define RATE_MCS_HE_GI_LTF_MSK (0x7 << RATE_MCS_HE_GI_LTF_POS) +#define RATE_MCS_SGI_POS RATE_MCS_HE_GI_LTF_POS +#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS) + +/* Bit 24-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */ +#define RATE_MCS_HE_TYPE_POS 23 +#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS) + +/* Bit 25: duplicate channel enabled + * + * if this bit is set, duplicate is according to BW (bits 11-13): + * + * CCK: 2x 20MHz + * OFDM Legacy: N x 20Mhz, (N = BW \ 2 , either 2, 4, 8, 16) + * EHT: 2 x BW/2, (80 - 2x40, 160 - 2x80, 320 - 2x160) + * */ +#define RATE_MCS_DUP_POS 25 +#define RATE_MCS_DUP_MSK (1 << RATE_MCS_DUP_POS) + +/* Bit 26: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */ +#define RATE_MCS_HE_106T_POS 26 +#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS) + +/* Bit 27: EHT extra LTF: + * instead of 1 LTF for SISO use 2 LTFs, + * instead of 2 LTFs for NSTS=2 use 4 LTFs*/ +#define RATE_MCS_EHT_EXTRA_LTF_POS 27 +#define RATE_MCS_EHT_EXTRA_LTF_MSK (1 << RATE_MCS_EHT_EXTRA_LTF_POS) + +/* Bit 31-28: reserved */ + /* Link Quality definitions */ /* # entries in rate scale table to support Tx retries */ From 9998f81e4ba50493b9339dcf54721ea080537ecc Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 12:40:16 +0300 Subject: [PATCH 022/114] iwlwifi: mvm: convert old rate & flags to the new format. As part of the new rate & flags, convert an old format rate to the new. This is needed if the driver supports the new format but the FW supports the old one. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.1ea5263dafec.Iadffe7cb26554d4c23c9242eb2ec8326306202a9@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/Makefile | 2 +- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 7 + drivers/net/wireless/intel/iwlwifi/fw/rs.c | 131 ++++++++++++++++++ .../net/wireless/intel/iwlwifi/mvm/utils.c | 25 +--- 4 files changed, 141 insertions(+), 24 deletions(-) create mode 100644 drivers/net/wireless/intel/iwlwifi/fw/rs.c diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile b/drivers/net/wireless/intel/iwlwifi/Makefile index d86918d162aa0..0d4656efe908b 100644 --- a/drivers/net/wireless/intel/iwlwifi/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/Makefile @@ -15,7 +15,7 @@ iwlwifi-objs += iwl-dbg-tlv.o iwlwifi-objs += iwl-trans.o iwlwifi-objs += queue/tx.o -iwlwifi-objs += fw/img.o fw/notif-wait.o +iwlwifi-objs += fw/img.o fw/notif-wait.o fw/rs.o iwlwifi-objs += fw/dbg.o fw/pnvm.o fw/dump.o iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o iwlwifi-$(CONFIG_ACPI) += fw/acpi.o diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index 8d71988975351..8b4f3c3116348 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -303,6 +303,7 @@ enum { #define RATE_HT_MCS_RATE_CODE_MSK_V1 0x7 #define RATE_HT_MCS_NSS_POS_V1 3 #define RATE_HT_MCS_NSS_MSK_V1 (3 << RATE_HT_MCS_NSS_POS_V1) +#define RATE_HT_MCS_MIMO2_MSK BIT(RATE_HT_MCS_NSS_POS_V1) /* Bit 10: (1) Use Green Field preamble */ #define RATE_HT_MCS_GF_POS 10 @@ -324,6 +325,7 @@ enum { #define RATE_VHT_MCS_RATE_CODE_MSK 0xf #define RATE_VHT_MCS_NSS_POS 4 #define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS) +#define RATE_VHT_MCS_MIMO2_MSK BIT(RATE_VHT_MCS_NSS_POS) /* * Legacy OFDM rate format for bits 7:0 @@ -545,6 +547,7 @@ enum { #define RATE_MCS_HE_GI_LTF_MSK (0x7 << RATE_MCS_HE_GI_LTF_POS) #define RATE_MCS_SGI_POS RATE_MCS_HE_GI_LTF_POS #define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS) +#define RATE_MCS_HE_SU_4_LTF 3 /* Bit 24-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */ #define RATE_MCS_HE_TYPE_POS 23 @@ -694,4 +697,8 @@ struct iwl_lq_cmd { __le32 ss_params; }; /* LINK_QUALITY_CMD_API_S_VER_1 */ +u8 iwl_fw_rate_idx_to_plcp(int idx); +u32 iwl_new_rate_from_v1(u32 rate_v1); +u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags); + #endif /* __iwl_fw_api_rs_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/rs.c b/drivers/net/wireless/intel/iwlwifi/fw/rs.c new file mode 100644 index 0000000000000..4e066588d5bae --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/fw/rs.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2021 Intel Corporation + */ + +#include +#include "fw/api/rs.h" +#include "iwl-drv.h" + +#define IWL_DECLARE_RATE_INFO(r) \ + [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP + +u8 iwl_fw_rate_idx_to_plcp(int idx) +{ +/* + * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP + * */ +static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1), + IWL_DECLARE_RATE_INFO(2), + IWL_DECLARE_RATE_INFO(5), + IWL_DECLARE_RATE_INFO(11), + IWL_DECLARE_RATE_INFO(6), + IWL_DECLARE_RATE_INFO(9), + IWL_DECLARE_RATE_INFO(12), + IWL_DECLARE_RATE_INFO(18), + IWL_DECLARE_RATE_INFO(24), + IWL_DECLARE_RATE_INFO(36), + IWL_DECLARE_RATE_INFO(48), + IWL_DECLARE_RATE_INFO(54), +}; + + return fw_rate_idx_to_plcp[idx]; +} +IWL_EXPORT_SYMBOL(iwl_fw_rate_idx_to_plcp); + +u32 iwl_new_rate_from_v1(u32 rate_v1) +{ + u32 rate_v2 = 0; + u32 dup = 0; + + if (rate_v1 == 0) + return rate_v1; + /* convert rate */ + if (rate_v1 & RATE_MCS_HT_MSK_V1) { + u32 nss = 0; + + rate_v2 |= RATE_MCS_HT_MSK; + rate_v2 |= + rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1; + nss = (rate_v1 & RATE_HT_MCS_MIMO2_MSK) >> + RATE_HT_MCS_NSS_POS_V1; + rate_v2 |= nss << RATE_MCS_NSS_POS; + } else if (rate_v1 & RATE_MCS_VHT_MSK_V1 || + rate_v1 & RATE_MCS_HE_MSK_V1) { + rate_v2 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; + + rate_v2 |= rate_v1 & RATE_VHT_MCS_MIMO2_MSK; + + if (rate_v1 & RATE_MCS_HE_MSK_V1) { + u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1; + u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1; + u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >> + RATE_MCS_HE_106T_POS_V1; + u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >> + RATE_MCS_HE_GI_LTF_POS; + + if ((he_type_bits == RATE_MCS_HE_TYPE_SU || + he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) && + he_gi_ltf == RATE_MCS_HE_SU_4_LTF) + /* the new rate have an additional bit to + * represent the value 4 rather then using SGI + * bit for this purpose - as it was done in the old + * rate */ + he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >> + RATE_MCS_SGI_POS_V1; + + rate_v2 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS; + rate_v2 |= he_type << RATE_MCS_HE_TYPE_POS; + rate_v2 |= he_106t << RATE_MCS_HE_106T_POS; + rate_v2 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK; + rate_v2 |= RATE_MCS_HE_MSK; + } else { + rate_v2 |= RATE_MCS_VHT_MSK; + } + /* if legacy format */ + } else { + u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1); + + WARN_ON(legacy_rate < 0); + rate_v2 |= legacy_rate; + if (!(rate_v1 & RATE_MCS_CCK_MSK_V1)) + rate_v2 |= RATE_MCS_LEGACY_OFDM_MSK; + } + + /* convert flags */ + if (rate_v1 & RATE_MCS_LDPC_MSK_V1) + rate_v2 |= RATE_MCS_LDPC_MSK; + rate_v2 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) | + (rate_v1 & RATE_MCS_ANT_AB_MSK) | + (rate_v1 & RATE_MCS_STBC_MSK) | + (rate_v1 & RATE_MCS_BF_MSK); + + dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1; + if (dup) { + rate_v2 |= RATE_MCS_DUP_MSK; + rate_v2 |= dup << RATE_MCS_CHAN_WIDTH_POS; + } + + if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) && + (rate_v1 & RATE_MCS_SGI_MSK_V1)) + rate_v2 |= RATE_MCS_SGI_MSK; + + return rate_v2; +} +IWL_EXPORT_SYMBOL(iwl_new_rate_from_v1); + +u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) +{ + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1; + int idx; + bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1); + int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0; + int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE; + + for (idx = offset; idx < last; idx++) + if (iwl_fw_rate_idx_to_plcp(idx) == rate) + return idx - offset; + return -1; +} + diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 70ca6d7a31bf2..dc1727280248b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -135,27 +135,6 @@ int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len, return iwl_mvm_send_cmd_status(mvm, &cmd, status); } -#define IWL_DECLARE_RATE_INFO(r) \ - [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP - -/* - * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP - */ -static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { - IWL_DECLARE_RATE_INFO(1), - IWL_DECLARE_RATE_INFO(2), - IWL_DECLARE_RATE_INFO(5), - IWL_DECLARE_RATE_INFO(11), - IWL_DECLARE_RATE_INFO(6), - IWL_DECLARE_RATE_INFO(9), - IWL_DECLARE_RATE_INFO(12), - IWL_DECLARE_RATE_INFO(18), - IWL_DECLARE_RATE_INFO(24), - IWL_DECLARE_RATE_INFO(36), - IWL_DECLARE_RATE_INFO(48), - IWL_DECLARE_RATE_INFO(54), -}; - int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, enum nl80211_band band) { @@ -167,7 +146,7 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, if (band != NL80211_BAND_2GHZ) band_offset = IWL_FIRST_OFDM_RATE; for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++) - if (fw_rate_idx_to_plcp[idx] == rate) + if (iwl_fw_rate_idx_to_plcp(idx) == rate) return idx - band_offset; return -1; @@ -176,7 +155,7 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx) { /* Get PLCP rate for tx_cmd->rate_n_flags */ - return fw_rate_idx_to_plcp[rate_idx]; + return iwl_fw_rate_idx_to_plcp(rate_idx); } u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac) From 82cdbd11b60a19e59f7991350b0c4e901c48c687 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 12:40:17 +0300 Subject: [PATCH 023/114] iwlwifi: mvm: Support version 3 of tlc_update_notif. As part of the new rate_n_flags, a new version of tlc_update_notif was added in FW in order to support the new rate_n_flags. Add support for the new version, and move the all API to use the new rate_n_flags only (if FW supports the old one - convert it). Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.9fc0cb5d5898.I1f88e02317f79f1be7f792c01236d836045a44b3@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 16 ++ drivers/net/wireless/intel/iwlwifi/fw/rs.c | 125 ++++++++++++++- .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 150 ++++++++++-------- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- .../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 12 ++ drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 67 ++------ drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 12 -- 8 files changed, 244 insertions(+), 144 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index 8b4f3c3116348..a09081d7ed45e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -184,6 +184,14 @@ struct iwl_tlc_update_notif { __le32 amsdu_enabled; } __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */ + +#define IWL_MAX_MCS_DISPLAY_SIZE 12 + +struct iwl_rate_mcs_info { + char mbps[IWL_MAX_MCS_DISPLAY_SIZE]; + char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; +}; + /* * These serve as indexes into * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; @@ -226,6 +234,8 @@ enum { IWL_LAST_HE_RATE = IWL_RATE_MCS_11_INDEX, IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1, IWL_RATE_COUNT = IWL_LAST_HE_RATE + 1, + IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, + IWL_RATE_INVALID = IWL_RATE_COUNT, }; #define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX) @@ -548,6 +558,7 @@ enum { #define RATE_MCS_SGI_POS RATE_MCS_HE_GI_LTF_POS #define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS) #define RATE_MCS_HE_SU_4_LTF 3 +#define RATE_MCS_HE_SU_4_LTF_08_GI 4 /* Bit 24-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */ #define RATE_MCS_HE_TYPE_POS 23 @@ -700,5 +711,10 @@ struct iwl_lq_cmd { u8 iwl_fw_rate_idx_to_plcp(int idx); u32 iwl_new_rate_from_v1(u32 rate_v1); u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags); +const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx); +const char *iwl_rs_pretty_ant(u8 ant); +const char *iwl_rs_pretty_bw(int bw); +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate); +bool iwl_he_is_sgi(u32 rate_n_flags); #endif /* __iwl_fw_api_rs_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/rs.c b/drivers/net/wireless/intel/iwlwifi/fw/rs.c index 4e066588d5bae..a21c3befd93b5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/rs.c @@ -6,12 +6,11 @@ #include #include "fw/api/rs.h" #include "iwl-drv.h" +#include "iwl-config.h" #define IWL_DECLARE_RATE_INFO(r) \ [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP -u8 iwl_fw_rate_idx_to_plcp(int idx) -{ /* * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP * */ @@ -30,10 +29,68 @@ static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = { IWL_DECLARE_RATE_INFO(54), }; +/* mbps, mcs */ +static const struct iwl_rate_mcs_info rate_mcs[IWL_RATE_COUNT] = { + { "1", "BPSK DSSS"}, + { "2", "QPSK DSSS"}, + {"5.5", "BPSK CCK"}, + { "11", "QPSK CCK"}, + { "6", "BPSK 1/2"}, + { "9", "BPSK 1/2"}, + { "12", "QPSK 1/2"}, + { "18", "QPSK 3/4"}, + { "24", "16QAM 1/2"}, + { "36", "16QAM 3/4"}, + { "48", "64QAM 2/3"}, + { "54", "64QAM 3/4"}, + { "60", "64QAM 5/6"}, +}; + +static const char * const ant_name[] = { + [ANT_NONE] = "None", + [ANT_A] = "A", + [ANT_B] = "B", + [ANT_AB] = "AB", +}; + +static const char * const pretty_bw[] = { + "20Mhz", + "40Mhz", + "80Mhz", + "160 Mhz", + "320Mhz", +}; + +u8 iwl_fw_rate_idx_to_plcp(int idx) +{ return fw_rate_idx_to_plcp[idx]; } IWL_EXPORT_SYMBOL(iwl_fw_rate_idx_to_plcp); +const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx) +{ + return &rate_mcs[idx]; +} +IWL_EXPORT_SYMBOL(iwl_rate_mcs); + +const char *iwl_rs_pretty_ant(u8 ant) +{ + if (ant >= ARRAY_SIZE(ant_name)) + return "UNKNOWN"; + + return ant_name[ant]; +} +IWL_EXPORT_SYMBOL(iwl_rs_pretty_ant); + +const char *iwl_rs_pretty_bw(int bw) +{ + if (bw >= ARRAY_SIZE(pretty_bw)) + return "unknown bw"; + + return pretty_bw[bw]; +} +IWL_EXPORT_SYMBOL(iwl_rs_pretty_bw); + u32 iwl_new_rate_from_v1(u32 rate_v1) { u32 rate_v2 = 0; @@ -129,3 +186,67 @@ u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags) return -1; } +int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) +{ + char *type; + u8 mcs = 0, nss = 0; + u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; + u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK) >> + RATE_MCS_CHAN_WIDTH_POS; + u32 format = rate & RATE_MCS_MOD_TYPE_MSK; + bool sgi; + + if (format == RATE_MCS_CCK_MSK || + format == RATE_MCS_LEGACY_OFDM_MSK) { + int legacy_rate = rate & RATE_LEGACY_RATE_MSK; + int index = format == RATE_MCS_CCK_MSK ? + legacy_rate : + legacy_rate + IWL_FIRST_OFDM_RATE; + + return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", + iwl_rs_pretty_ant(ant), + index == IWL_RATE_INVALID ? "BAD" : + iwl_rate_mcs(index)->mbps); + } + + if (format == RATE_MCS_VHT_MSK) + type = "VHT"; + else if (format == RATE_MCS_HT_MSK) + type = "HT"; + else if (format == RATE_MCS_HE_MSK) + type = "HE"; + else + type = "Unknown"; /* shouldn't happen */ + + mcs = format == RATE_MCS_HT_MSK ? + RATE_HT_MCS_INDEX(rate) : + rate & RATE_MCS_CODE_MSK; + nss = ((rate & RATE_MCS_NSS_MSK) + >> RATE_MCS_NSS_POS) + 1; + sgi = format == RATE_MCS_HE_MSK ? + iwl_he_is_sgi(rate) : + rate & RATE_MCS_SGI_MSK; + + return scnprintf(buf, bufsz, + "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s", + rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss, + (sgi) ? "SGI " : "NGI ", + (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", + (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "", + (rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "", + (rate & RATE_MCS_BF_MSK) ? "BF " : ""); +} +IWL_EXPORT_SYMBOL(rs_pretty_print_rate); + +bool iwl_he_is_sgi(u32 rate_n_flags) +{ + u32 type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; + u32 ltf_gi = rate_n_flags & RATE_MCS_HE_GI_LTF_MSK; + + if (type == RATE_MCS_HE_TYPE_SU || + type == RATE_MCS_HE_TYPE_EXT_SU) + return ltf_gi == RATE_MCS_HE_SU_4_LTF_08_GI; + return false; +} +IWL_EXPORT_SYMBOL(iwl_he_is_sgi); + diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 8c2251178f97a..1fba6b421d311 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -985,8 +985,8 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm, continue; pos += scnprintf(pos, endpos - pos, "Rate[%d]: ", (int)(ARRAY_SIZE(stats->last_rates) - i)); - pos += rs_pretty_print_rate(pos, endpos - pos, - stats->last_rates[idx]); + pos += rs_pretty_print_rate_v1(pos, endpos - pos, + stats->last_rates[idx]); if (pos < endpos - 1) *pos++ = '\n'; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 1d664dd5915ca..4660f21c4e79a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4878,7 +4878,9 @@ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) { - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { + u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; + + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { case RATE_MCS_CHAN_WIDTH_20: rinfo->bw = RATE_INFO_BW_20; break; @@ -4893,49 +4895,84 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) break; } - if (rate_n_flags & RATE_MCS_HT_MSK_V1) { - rinfo->flags |= RATE_INFO_FLAGS_MCS; - rinfo->mcs = u32_get_bits(rate_n_flags, RATE_HT_MCS_INDEX_MSK_V1); - rinfo->nss = u32_get_bits(rate_n_flags, - RATE_HT_MCS_NSS_MSK_V1) + 1; - if (rate_n_flags & RATE_MCS_SGI_MSK_V1) - rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; - } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { - rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS; - rinfo->mcs = u32_get_bits(rate_n_flags, - RATE_VHT_MCS_RATE_CODE_MSK); - rinfo->nss = u32_get_bits(rate_n_flags, - RATE_VHT_MCS_NSS_MSK) + 1; - if (rate_n_flags & RATE_MCS_SGI_MSK_V1) - rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; - } else if (rate_n_flags & RATE_MCS_HE_MSK_V1) { + if (format == RATE_MCS_CCK_MSK || + format == RATE_MCS_LEGACY_OFDM_MSK) { + int rate = u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK); + + /* add the offset needed to get to the legacy ofdm indices */ + if (format == RATE_MCS_LEGACY_OFDM_MSK) + rate += IWL_FIRST_OFDM_RATE; + + switch (rate) { + case IWL_RATE_1M_INDEX: + rinfo->legacy = 10; + break; + case IWL_RATE_2M_INDEX: + rinfo->legacy = 20; + break; + case IWL_RATE_5M_INDEX: + rinfo->legacy = 55; + break; + case IWL_RATE_11M_INDEX: + rinfo->legacy = 110; + break; + case IWL_RATE_6M_INDEX: + rinfo->legacy = 60; + break; + case IWL_RATE_9M_INDEX: + rinfo->legacy = 90; + break; + case IWL_RATE_12M_INDEX: + rinfo->legacy = 120; + break; + case IWL_RATE_18M_INDEX: + rinfo->legacy = 180; + break; + case IWL_RATE_24M_INDEX: + rinfo->legacy = 240; + break; + case IWL_RATE_36M_INDEX: + rinfo->legacy = 360; + break; + case IWL_RATE_48M_INDEX: + rinfo->legacy = 480; + break; + case IWL_RATE_54M_INDEX: + rinfo->legacy = 540; + } + return; + } + + rinfo->nss = u32_get_bits(rate_n_flags, + RATE_MCS_NSS_MSK) + 1; + rinfo->mcs = format == RATE_MCS_HT_MSK ? + RATE_HT_MCS_INDEX(rate_n_flags) : + u32_get_bits(rate_n_flags, RATE_MCS_CODE_MSK); + + if (format == RATE_MCS_HE_MSK) { u32 gi_ltf = u32_get_bits(rate_n_flags, - RATE_MCS_HE_GI_LTF_MSK_V1); + RATE_MCS_HE_GI_LTF_MSK); rinfo->flags |= RATE_INFO_FLAGS_HE_MCS; - rinfo->mcs = u32_get_bits(rate_n_flags, - RATE_VHT_MCS_RATE_CODE_MSK); - rinfo->nss = u32_get_bits(rate_n_flags, - RATE_VHT_MCS_NSS_MSK) + 1; - if (rate_n_flags & RATE_MCS_HE_106T_MSK_V1) { + if (rate_n_flags & RATE_MCS_HE_106T_MSK) { rinfo->bw = RATE_INFO_BW_HE_RU; rinfo->he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_106; } - switch (rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1) { - case RATE_MCS_HE_TYPE_SU_V1: - case RATE_MCS_HE_TYPE_EXT_SU_V1: + switch (rate_n_flags & RATE_MCS_HE_TYPE_MSK) { + case RATE_MCS_HE_TYPE_SU: + case RATE_MCS_HE_TYPE_EXT_SU: if (gi_ltf == 0 || gi_ltf == 1) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else if (gi_ltf == 2) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6; - else if (rate_n_flags & RATE_MCS_SGI_MSK_V1) - rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8; - else + else if (gi_ltf == 3) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2; + else + rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8; break; - case RATE_MCS_HE_TYPE_MU_V1: + case RATE_MCS_HE_TYPE_MU: if (gi_ltf == 0 || gi_ltf == 1) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_0_8; else if (gi_ltf == 2) @@ -4943,7 +4980,7 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) else rinfo->he_gi = NL80211_RATE_INFO_HE_GI_3_2; break; - case RATE_MCS_HE_TYPE_TRIG_V1: + case RATE_MCS_HE_TYPE_TRIG: if (gi_ltf == 0 || gi_ltf == 1) rinfo->he_gi = NL80211_RATE_INFO_HE_GI_1_6; else @@ -4953,46 +4990,19 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) if (rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK) rinfo->he_dcm = 1; - } else { - switch (u32_get_bits(rate_n_flags, RATE_LEGACY_RATE_MSK_V1)) { - case IWL_RATE_1M_PLCP: - rinfo->legacy = 10; - break; - case IWL_RATE_2M_PLCP: - rinfo->legacy = 20; - break; - case IWL_RATE_5M_PLCP: - rinfo->legacy = 55; - break; - case IWL_RATE_11M_PLCP: - rinfo->legacy = 110; - break; - case IWL_RATE_6M_PLCP: - rinfo->legacy = 60; - break; - case IWL_RATE_9M_PLCP: - rinfo->legacy = 90; - break; - case IWL_RATE_12M_PLCP: - rinfo->legacy = 120; - break; - case IWL_RATE_18M_PLCP: - rinfo->legacy = 180; - break; - case IWL_RATE_24M_PLCP: - rinfo->legacy = 240; - break; - case IWL_RATE_36M_PLCP: - rinfo->legacy = 360; - break; - case IWL_RATE_48M_PLCP: - rinfo->legacy = 480; - break; - case IWL_RATE_54M_PLCP: - rinfo->legacy = 540; - break; - } + return; + } + + if (rate_n_flags & RATE_MCS_SGI_MSK) + rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; + + if (format == RATE_MCS_HT_MSK) { + rinfo->flags |= RATE_INFO_FLAGS_MCS; + + } else if (format == RATE_MCS_VHT_MSK) { + rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS; } + } static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index f877d86b038e3..50a11a595db1e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1732,7 +1732,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif) /* rate scaling */ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq); void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg); -int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate); +int rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate); void rs_update_last_rssi(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, struct ieee80211_rx_status *rx_status); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 5b224a19bb320..958702403a45d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -310,7 +310,19 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, if (flags & IWL_TLC_NOTIF_FLAG_RATE) { char pretty_rate[100]; + + if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, + TLC_MNG_UPDATE_NOTIF, 0) < 3) { + rs_pretty_print_rate_v1(pretty_rate, sizeof(pretty_rate), + le32_to_cpu(notif->rate)); + IWL_DEBUG_RATE(mvm, + "Got rate in old format. Rate: %s. Converting.\n", + pretty_rate); + lq_sta->last_rate_n_flags = + iwl_new_rate_from_v1(le32_to_cpu(notif->rate)); + } else { lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate); + } rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate), lq_sta->last_rate_n_flags); IWL_DEBUG_RATE(mvm, "new rate: %s\n", pretty_rate); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index df248d83606ae..88b5969d7b51c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -454,40 +454,8 @@ static const u16 expected_tpt_mimo2_160MHz[4][IWL_RATE_COUNT] = { {0, 0, 0, 0, 971, 0, 1925, 2861, 3779, 5574, 7304, 8147, 8976, 10592, 11640}, }; -/* mbps, mcs */ -static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { - { "1", "BPSK DSSS"}, - { "2", "QPSK DSSS"}, - {"5.5", "BPSK CCK"}, - { "11", "QPSK CCK"}, - { "6", "BPSK 1/2"}, - { "9", "BPSK 1/2"}, - { "12", "QPSK 1/2"}, - { "18", "QPSK 3/4"}, - { "24", "16QAM 1/2"}, - { "36", "16QAM 3/4"}, - { "48", "64QAM 2/3"}, - { "54", "64QAM 3/4"}, - { "60", "64QAM 5/6"}, -}; - #define MCS_INDEX_PER_STREAM (8) -static const char *rs_pretty_ant(u8 ant) -{ - static const char * const ant_name[] = { - [ANT_NONE] = "None", - [ANT_A] = "A", - [ANT_B] = "B", - [ANT_AB] = "AB", - }; - - if (ant > ANT_AB) - return "UNKNOWN"; - - return ant_name[ant]; -} - static const char *rs_pretty_lq_type(enum iwl_table_type type) { static const char * const lq_types[] = { @@ -549,7 +517,7 @@ static char *rs_pretty_rate(const struct rs_rate *rate) rate_str = "BAD_RATE"; sprintf(buf, "(%s|%s|%s)", rs_pretty_lq_type(rate->type), - rs_pretty_ant(rate->ant), rate_str); + iwl_rs_pretty_ant(rate->ant), rate_str); return buf; } @@ -2539,7 +2507,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm, } IWL_DEBUG_RATE(mvm, "Best ANT: %s Best RSSI: %d\n", - rs_pretty_ant(best_ant), best_rssi); + iwl_rs_pretty_ant(best_ant), best_rssi); if (best_ant != ANT_A && best_ant != ANT_B) rate->ant = first_antenna(valid_tx_ant); @@ -3674,12 +3642,14 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta) IWL_DEBUG_RATE(mvm, "leave\n"); } -int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) +int rs_pretty_print_rate_v1(char *buf, int bufsz, const u32 rate) { - char *type, *bw; + char *type; u8 mcs = 0, nss = 0; u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; + u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) >> + RATE_MCS_CHAN_WIDTH_POS; if (!(rate & RATE_MCS_HT_MSK_V1) && !(rate & RATE_MCS_VHT_MSK_V1) && @@ -3687,9 +3657,9 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) int index = iwl_hwrate_to_plcp_idx(rate); return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps", - rs_pretty_ant(ant), + iwl_rs_pretty_ant(ant), index == IWL_RATE_INVALID ? "BAD" : - iwl_rate_mcs[index].mbps); + iwl_rate_mcs(index)->mbps); } if (rate & RATE_MCS_VHT_MSK_V1) { @@ -3711,26 +3681,9 @@ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate) type = "Unknown"; /* shouldn't happen */ } - switch (rate & RATE_MCS_CHAN_WIDTH_MSK_V1) { - case RATE_MCS_CHAN_WIDTH_20: - bw = "20Mhz"; - break; - case RATE_MCS_CHAN_WIDTH_40: - bw = "40Mhz"; - break; - case RATE_MCS_CHAN_WIDTH_80: - bw = "80Mhz"; - break; - case RATE_MCS_CHAN_WIDTH_160: - bw = "160Mhz"; - break; - default: - bw = "BAD BW"; - } - return scnprintf(buf, bufsz, "0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s", - rate, type, rs_pretty_ant(ant), bw, mcs, nss, + rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss, (rate & RATE_MCS_SGI_MSK_V1) ? "SGI " : "NGI ", (rate & RATE_MCS_STBC_MSK) ? "STBC " : "", (rate & RATE_MCS_LDPC_MSK_V1) ? "LDPC " : "", @@ -3876,7 +3829,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, desc += scnprintf(buff + desc, bufsz - desc, " rate[%d] 0x%X ", i, r); - desc += rs_pretty_print_rate(buff + desc, bufsz - desc, r); + desc += rs_pretty_print_rate_v1(buff + desc, bufsz - desc, r); if (desc < bufsz - 1) buff[desc++] = '\n'; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index 3e206df57347c..b7bc8c1b2ddae 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -31,11 +31,6 @@ struct iwl_rs_rate_info { #define IWL_RATE_60M_PLCP 3 -enum { - IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, - IWL_RATE_INVALID = IWL_RATE_COUNT, -}; - #define LINK_QUAL_MAX_RETRY_NUM 16 enum { @@ -206,13 +201,6 @@ struct rs_rate { #define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80) #define is_ht160(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_160) -#define IWL_MAX_MCS_DISPLAY_SIZE 12 - -struct iwl_rate_mcs_info { - char mbps[IWL_MAX_MCS_DISPLAY_SIZE]; - char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; -}; - /** * struct iwl_lq_sta_rs_fw - rate and related statistics for RS in FW * @last_rate_n_flags: last rate reported by FW From bd8b5f30fa2c059ec3a2b48db1a24c8c64f3f53c Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 12:40:18 +0300 Subject: [PATCH 024/114] iwlwifi: mvm: Support new version of ranging response notification As part of the new rate_n_flags, FW added a new version for LOCATION_RANGE_RSP_NTFY, and it's internal structure - LOCATION_RANGE_RSP_AP_ETRY_NTFY. Add support for this. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.c5c6c863631e.I4b493f4eeabbfa1dc965ae012b72fc57de7d5f4f@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/location.h | 7 +++++-- drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c | 3 ++- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index 5f27829f89963..12af94e166ed0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -1501,7 +1501,9 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v6 { u8 reserved[3]; u8 rx_pn[IEEE80211_CCMP_PN_LEN]; u8 tx_pn[IEEE80211_CCMP_PN_LEN]; -} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6 */ +} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6, + LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_7 */ + /** * enum iwl_tof_response_status - tof response status @@ -1582,7 +1584,8 @@ struct iwl_tof_range_rsp_ntfy_v8 { u8 last_report; u8 reserved; struct iwl_tof_range_rsp_ap_entry_ntfy_v6 ap[IWL_MVM_TOF_MAX_APS]; -} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8 */ +} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8, + LOCATION_RANGE_RSP_NTFY_API_S_VER_9 */ #define IWL_MVM_TOF_MCSI_BUF_SIZE (245) /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c index 73be95fffb954..949fb790f8fb7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c @@ -1154,6 +1154,7 @@ static u8 iwl_mvm_ftm_get_range_resp_ver(struct iwl_mvm *mvm) static bool iwl_mvm_ftm_resp_size_validation(u8 ver, unsigned int pkt_len) { switch (ver) { + case 9: case 8: return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v8); case 7: @@ -1217,7 +1218,7 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) int peer_idx; if (new_api) { - if (notif_ver == 8) { + if (notif_ver >= 8) { fw_ap = &fw_resp_v8->ap[i]; iwl_mvm_ftm_pasn_update_pn(mvm, fw_ap); } else if (notif_ver == 7) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 3b0d5a0685414..e331e18b9ab18 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1044,8 +1044,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mvm->cmd_ver.range_resp = iwl_fw_lookup_notif_ver(mvm->fw, LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF, 5); - /* we only support up to version 8 */ - if (WARN_ON_ONCE(mvm->cmd_ver.range_resp > 8)) + /* we only support up to version 9 */ + if (WARN_ON_ONCE(mvm->cmd_ver.range_resp > 9)) goto out_free; /* From f21baf244112e646c6b6c9db94834cf06358db06 Mon Sep 17 00:00:00 2001 From: Mukesh Sisodiya Date: Sun, 17 Oct 2021 12:40:19 +0300 Subject: [PATCH 025/114] iwlwifi: yoyo: fw debug config from context info and preset Add new TLV for debug config set to read preset based on TLV is set in context info. This is needed to set the preset based on ucode in early trigger point. Add DRAM frag allocation info in first fragment of DBGC1 with all details. New capability from FW for DBGC frag debug support is added and BUFFER_ALLOCATION_CMD is disabled in capability is supported. Signed-off-by: Mukesh Sisodiya Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017123741.cacf0babc521.If3704b5fda09b344e3e438252360898a3f2e90fa@changeid Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 56 +++++++ .../net/wireless/intel/iwlwifi/fw/api/debug.h | 18 ++ drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 + .../intel/iwlwifi/iwl-context-info-gen3.h | 4 +- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 158 +++++++++++++++++- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 2 + drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 1 + .../net/wireless/intel/iwlwifi/iwl-trans.h | 5 +- .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 4 + 9 files changed, 245 insertions(+), 5 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 6ab5755beb533..3988f5fea33ab 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -243,6 +243,62 @@ struct iwl_fw_ini_hcmd_tlv { struct iwl_fw_ini_hcmd hcmd; } __packed; /* FW_TLV_DEBUG_HCMD_API_S_VER_1 */ +/** +* struct iwl_fw_ini_conf_tlv - preset configuration TLV +* +* @address: the base address +* @value: value to set at address + +*/ +struct iwl_fw_ini_addr_val { + __le32 address; + __le32 value; +} __packed; /* FW_TLV_DEBUG_ADDR_VALUE_VER_1 */ + +/** + * struct iwl_fw_ini_conf_tlv - configuration TLV to set register/memory. + * + * @hdr: debug header + * @time_point: time point to apply config. One of &enum iwl_fw_ini_time_point + * @set_type: write access type preset token for time point. + * one of &enum iwl_fw_ini_config_set_type + * @addr_offset: the offset to add to any item in address[0] field + * @addr_val: address value pair + */ +struct iwl_fw_ini_conf_set_tlv { + struct iwl_fw_ini_header hdr; + __le32 time_point; + __le32 set_type; + __le32 addr_offset; + struct iwl_fw_ini_addr_val addr_val[0]; +} __packed; /* FW_TLV_DEBUG_CONFIG_SET_API_S_VER_1 */ + +/** + * enum iwl_fw_ini_config_set_type + * + * @IWL_FW_INI_CONFIG_SET_TYPE_INVALID: invalid config set + * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: for PERIPHERY MAC configuration + * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_PHY: for PERIPHERY PHY configuration + * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_AUX: for PERIPHERY AUX configuration + * @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY: for DEVICE MEMORY configuration + * @IWL_FW_INI_CONFIG_SET_TYPE_CSR: for CSR configuration + * @IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR: for DBGC_DRAM_ADDR configuration + * @IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: for PERIPH SCRATCH HWM configuration + * @IWL_FW_INI_ALLOCATION_NUM: max number of configuration supported +*/ + +enum iwl_fw_ini_config_set_type { + IWL_FW_INI_CONFIG_SET_TYPE_INVALID = 0, + IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC, + IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_PHY, + IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_AUX, + IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY, + IWL_FW_INI_CONFIG_SET_TYPE_CSR, + IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR, + IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM, + IWL_FW_INI_CONFIG_SET_TYPE_MAX_NUM, +} __packed; + /** * enum iwl_fw_ini_allocation_id * diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index 8adccd5da095f..0abed12df2cb9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -361,6 +361,24 @@ struct iwl_buf_alloc_cmd { struct iwl_buf_alloc_frag frags[BUF_ALLOC_MAX_NUM_FRAGS]; } __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_2 */ +#define DRAM_INFO_FIRST_MAGIC_WORD 0x76543210 +#define DRAM_INFO_SECOND_MAGIC_WORD 0x89ABCDEF + +/** + * struct iwL_dram_info - DRAM fragments allocation struct + * + * Driver will fill in the first 1K(+) of the pointed DRAM fragment + * + * @first_word: magic word value + * @second_word: magic word value + * @framfrags: DRAM fragmentaion detail +*/ +struct iwl_dram_info { + __le32 first_word; + __le32 second_word; + struct iwl_buf_alloc_cmd dram_frags[IWL_FW_INI_ALLOCATION_NUM - 1]; +} __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */ + /** * struct iwl_dbg_host_event_cfg_cmd * @enabled_severities: enabled severities diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 3a031070d3679..c65196daf55b3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -110,6 +110,7 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_TLV_DEBUG_BASE + 2, IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_TLV_DEBUG_BASE + 3, IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_TLV_DEBUG_BASE + 4, + IWL_UCODE_TLV_TYPE_CONF_SET = IWL_UCODE_TLV_DEBUG_BASE + 5, IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_TRIGGERS, /* TLVs 0x1000-0x2000 are for internal driver usage */ @@ -453,6 +454,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT = (__force iwl_ucode_tlv_capa_t)100, IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)102, + IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT = (__force iwl_ucode_tlv_capa_t)104, #ifdef __CHECKER__ /* sparse says it cannot increment the previous enum member */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h index e1fec23ac07f6..5adf485db38e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h @@ -109,12 +109,12 @@ struct iwl_prph_scratch_pnvm_cfg { * struct iwl_prph_scratch_hwm_cfg - hwm config * @hwm_base_addr: hwm start address * @hwm_size: hwm size in DWs - * @reserved: reserved + * @debug_token_config: debug preset */ struct iwl_prph_scratch_hwm_cfg { __le64 hwm_base_addr; __le32 hwm_size; - __le32 reserved; + __le32 debug_token_config; } __packed; /* PERIPH_SCRATCH_HWM_CFG_S */ /* diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 125479b5c0d61..8692700207638 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -16,6 +16,7 @@ * @IWL_DBG_TLV_TYPE_HCMD: host command TLV * @IWL_DBG_TLV_TYPE_REGION: region TLV * @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV + * @IWL_DBG_TLV_TYPE_CONF_SET: conf set TLV * @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs */ enum iwl_dbg_tlv_type { @@ -25,6 +26,7 @@ enum iwl_dbg_tlv_type { IWL_DBG_TLV_TYPE_HCMD, IWL_DBG_TLV_TYPE_REGION, IWL_DBG_TLV_TYPE_TRIGGER, + IWL_DBG_TLV_TYPE_CONF_SET, IWL_DBG_TLV_TYPE_NUM, }; @@ -59,6 +61,7 @@ dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = { [IWL_DBG_TLV_TYPE_HCMD] = {.min_ver = 1, .max_ver = 1,}, [IWL_DBG_TLV_TYPE_REGION] = {.min_ver = 1, .max_ver = 2,}, [IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,}, + [IWL_DBG_TLV_TYPE_CONF_SET] = {.min_ver = 1, .max_ver = 1,}, }; static int iwl_dbg_tlv_add(const struct iwl_ucode_tlv *tlv, @@ -260,6 +263,37 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans, return ret; } +static int iwl_dbg_tlv_config_set(struct iwl_trans *trans, + const struct iwl_ucode_tlv *tlv) +{ + struct iwl_fw_ini_conf_set_tlv *conf_set = (void *)tlv->data; + u32 tp = le32_to_cpu(conf_set->time_point); + u32 type = le32_to_cpu(conf_set->set_type); + + if (tp <= IWL_FW_INI_TIME_POINT_INVALID || + tp >= IWL_FW_INI_TIME_POINT_NUM) { + IWL_DEBUG_FW(trans, + "WRT: Invalid time point %u for config set TLV\n", tp); + return -EINVAL; + } + + if (type <= IWL_FW_INI_CONFIG_SET_TYPE_INVALID || + type >= IWL_FW_INI_CONFIG_SET_TYPE_MAX_NUM) { + IWL_DEBUG_FW(trans, + "WRT: Invalid config set type %u for config set TLV\n", type); + return -EINVAL; + } + + if (type != IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM || + trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { + IWL_DEBUG_FW(trans, + "WRT: Config set type %u is not supported\n", type); + return -EINVAL; + } + + return iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].config_list); +} + static int (*dbg_tlv_alloc[])(struct iwl_trans *trans, const struct iwl_ucode_tlv *tlv) = { [IWL_DBG_TLV_TYPE_DEBUG_INFO] = iwl_dbg_tlv_alloc_debug_info, @@ -267,6 +301,7 @@ static int (*dbg_tlv_alloc[])(struct iwl_trans *trans, [IWL_DBG_TLV_TYPE_HCMD] = iwl_dbg_tlv_alloc_hcmd, [IWL_DBG_TLV_TYPE_REGION] = iwl_dbg_tlv_alloc_region, [IWL_DBG_TLV_TYPE_TRIGGER] = iwl_dbg_tlv_alloc_trigger, + [IWL_DBG_TLV_TYPE_CONF_SET] = iwl_dbg_tlv_config_set, }; void iwl_dbg_tlv_alloc(struct iwl_trans *trans, const struct iwl_ucode_tlv *tlv, @@ -399,6 +434,13 @@ void iwl_dbg_tlv_free(struct iwl_trans *trans) list_del(&tlv_node->list); kfree(tlv_node); } + + list_for_each_entry_safe(tlv_node, tlv_node_tmp, + &tp->config_list, list) { + list_del(&tlv_node->list); + kfree(tlv_node); + } + } for (i = 0; i < ARRAY_SIZE(trans->dbg.fw_mon_ini); i++) @@ -466,6 +508,7 @@ void iwl_dbg_tlv_init(struct iwl_trans *trans) INIT_LIST_HEAD(&tp->trig_list); INIT_LIST_HEAD(&tp->hcmd_list); INIT_LIST_HEAD(&tp->active_trig_list); + INIT_LIST_HEAD(&tp->config_list); } } @@ -649,6 +692,10 @@ static void iwl_dbg_tlv_apply_buffers(struct iwl_fw_runtime *fwrt) { int ret, i; + if (fw_has_capa(&fwrt->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT)) + return; + for (i = 0; i < IWL_FW_INI_ALLOCATION_NUM; i++) { ret = iwl_dbg_tlv_apply_buffer(fwrt, i); if (ret) @@ -658,6 +705,87 @@ static void iwl_dbg_tlv_apply_buffers(struct iwl_fw_runtime *fwrt) } } +static int iwl_dbg_tlv_update_dram(struct iwl_fw_runtime *fwrt, + enum iwl_fw_ini_allocation_id alloc_id, + struct iwl_dram_info *dram_info) +{ + struct iwl_fw_mon *fw_mon; + u32 remain_frags, num_frags; + int j, fw_mon_idx = 0; + struct iwl_buf_alloc_cmd *data; + + if (le32_to_cpu(fwrt->trans->dbg.fw_mon_cfg[alloc_id].buf_location) != + IWL_FW_INI_LOCATION_DRAM_PATH) { + IWL_DEBUG_FW(fwrt, "DRAM_PATH is not supported alloc_id %u\n", alloc_id); + return -1; + } + + fw_mon = &fwrt->trans->dbg.fw_mon_ini[alloc_id]; + + /* the first fragment of DBGC1 is given to the FW via register + * or context info + */ + if (alloc_id == IWL_FW_INI_ALLOCATION_ID_DBGC1) + fw_mon_idx++; + + remain_frags = fw_mon->num_frags - fw_mon_idx; + if (!remain_frags) + return -1; + + num_frags = min_t(u32, remain_frags, BUF_ALLOC_MAX_NUM_FRAGS); + data = &dram_info->dram_frags[alloc_id - 1]; + data->alloc_id = cpu_to_le32(alloc_id); + data->num_frags = cpu_to_le32(num_frags); + data->buf_location = cpu_to_le32(IWL_FW_INI_LOCATION_DRAM_PATH); + + IWL_DEBUG_FW(fwrt, "WRT: DRAM buffer details alloc_id=%u, num_frags=%u\n", + cpu_to_le32(alloc_id), cpu_to_le32(num_frags)); + + for (j = 0; j < num_frags; j++) { + struct iwl_buf_alloc_frag *frag = &data->frags[j]; + struct iwl_dram_data *fw_mon_frag = &fw_mon->frags[fw_mon_idx++]; + + frag->addr = cpu_to_le64(fw_mon_frag->physical); + frag->size = cpu_to_le32(fw_mon_frag->size); + IWL_DEBUG_FW(fwrt, "WRT: DRAM fragment details\n"); + IWL_DEBUG_FW(fwrt, "frag=%u, addr=0x%016llx, size=0x%x)\n", + j, cpu_to_le64(fw_mon_frag->physical), + cpu_to_le32(fw_mon_frag->size)); + } + return 0; +} + +static void iwl_dbg_tlv_update_drams(struct iwl_fw_runtime *fwrt) +{ + int ret, i, dram_alloc = 0; + struct iwl_dram_info dram_info; + struct iwl_dram_data *frags = + &fwrt->trans->dbg.fw_mon_ini[IWL_FW_INI_ALLOCATION_ID_DBGC1].frags[0]; + + if (!fw_has_capa(&fwrt->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT)) + return; + + dram_info.first_word = cpu_to_le32(DRAM_INFO_FIRST_MAGIC_WORD); + dram_info.second_word = cpu_to_le32(DRAM_INFO_SECOND_MAGIC_WORD); + + for (i = IWL_FW_INI_ALLOCATION_ID_DBGC1; + i <= IWL_FW_INI_ALLOCATION_ID_DBGC3; i++) { + ret = iwl_dbg_tlv_update_dram(fwrt, i, &dram_info); + if (!ret) + dram_alloc++; + else + IWL_WARN(fwrt, + "WRT: Failed to set DRAM buffer for alloc id %d, ret=%d\n", + i, ret); + } + if (dram_alloc) { + memcpy(frags->block, &dram_info, sizeof(dram_info)); + IWL_DEBUG_FW(fwrt, "block data after %016x\n", + *((int *)fwrt->trans->dbg.fw_mon_ini[1].frags[0].block)); + } +} + static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt, struct list_head *hcmd_list) { @@ -677,6 +805,31 @@ static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt, } } +static void iwl_dbg_tlv_apply_config(struct iwl_fw_runtime *fwrt, + struct list_head *config_list) +{ + struct iwl_dbg_tlv_node *node; + + list_for_each_entry(node, config_list, list) { + struct iwl_fw_ini_conf_set_tlv *config_list = (void *)node->tlv.data; + u32 type = le32_to_cpu(config_list->set_type); + + switch (type) { + case IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: { + u32 debug_token_config = + le32_to_cpu(config_list->addr_val[0].value); + + IWL_DEBUG_FW(fwrt, "WRT: Setting HWM debug token config: %u\n", + debug_token_config); + fwrt->trans->dbg.ucode_preset = debug_token_config; + break; + } + default: + break; + } + } +} + static void iwl_dbg_tlv_periodic_trig_handler(struct timer_list *t) { struct iwl_dbg_tlv_timer_node *timer_node = @@ -1051,7 +1204,7 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt, union iwl_dbg_tlv_tp_data *tp_data, bool sync) { - struct list_head *hcmd_list, *trig_list; + struct list_head *hcmd_list, *trig_list, *conf_list; if (!iwl_trans_dbg_ini_valid(fwrt->trans) || tp_id == IWL_FW_INI_TIME_POINT_INVALID || @@ -1060,10 +1213,13 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt, hcmd_list = &fwrt->trans->dbg.time_point[tp_id].hcmd_list; trig_list = &fwrt->trans->dbg.time_point[tp_id].active_trig_list; + conf_list = &fwrt->trans->dbg.time_point[tp_id].config_list; switch (tp_id) { case IWL_FW_INI_TIME_POINT_EARLY: iwl_dbg_tlv_init_cfg(fwrt); + iwl_dbg_tlv_apply_config(fwrt, conf_list); + iwl_dbg_tlv_update_drams(fwrt); iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL); break; case IWL_FW_INI_TIME_POINT_AFTER_ALIVE: diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index c12b1fd3f4792..79287708bd6e6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -33,11 +33,13 @@ union iwl_dbg_tlv_tp_data { * @trig_list: list of triggers * @active_trig_list: list of active triggers * @hcmd_list: list of host commands + * @config_list: list of configuration */ struct iwl_dbg_tlv_time_point_data { struct list_head trig_list; struct list_head active_trig_list; struct list_head hcmd_list; + struct list_head config_list; }; struct iwl_trans; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 8296b71aa76fc..36196e07b1a04 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1169,6 +1169,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, case IWL_UCODE_TLV_TYPE_HCMD: case IWL_UCODE_TLV_TYPE_REGIONS: case IWL_UCODE_TLV_TYPE_TRIGGERS: + case IWL_UCODE_TLV_TYPE_CONF_SET: if (iwlwifi_mod_params.enable_ini) iwl_dbg_tlv_alloc(drv->trans, tlv, false); break; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 32d228d7e1fe6..4ebb1871bd1fb 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -739,8 +739,8 @@ struct iwl_self_init_dram { * @debug_info_tlv_list: list of debug info TLVs * @time_point: array of debug time points * @periodic_trig_list: periodic triggers list - * @domains_bitmap: bitmap of active domains other than - * &IWL_FW_INI_DOMAIN_ALWAYS_ON + * @domains_bitmap: bitmap of active domains other than &IWL_FW_INI_DOMAIN_ALWAYS_ON + * @ucode_preset: preset based on ucode */ struct iwl_trans_debug { u8 n_dest_reg; @@ -774,6 +774,7 @@ struct iwl_trans_debug { struct list_head periodic_trig_list; u32 domains_bitmap; + u32 ucode_preset; }; struct iwl_dma_ptr { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 239a722cd79d8..85a6da70ca787 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -57,6 +57,10 @@ iwl_pcie_ctxt_info_dbg_enable(struct iwl_trans *trans, dbg_flags |= IWL_PRPH_SCRATCH_EDBG_DEST_DRAM; dbg_cfg->hwm_base_addr = cpu_to_le64(frag->physical); dbg_cfg->hwm_size = cpu_to_le32(frag->size); + dbg_cfg->debug_token_config = cpu_to_le32(trans->dbg.ucode_preset); + IWL_DEBUG_FW(trans, + "WRT: Applying DRAM destination (debug_token_config=%u)\n", + dbg_cfg->debug_token_config); IWL_DEBUG_FW(trans, "WRT: Applying DRAM destination (alloc_id=%u, num_frags=%u)\n", alloc_id, From 44b2dd4098be856579a6f7c48e0ee3d0c01c7c0e Mon Sep 17 00:00:00 2001 From: Roee Goldfiner Date: Sun, 17 Oct 2021 16:25:53 +0300 Subject: [PATCH 026/114] iwlwifi: BZ Family BUS_MASTER_DISABLE_REQ code duplication Remove redundant code which occurs anyway in a later stage and add msleep(100) which is required after disable request. Signed-off-by: Roee Goldfiner Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.46183bcd6549.Ie05161496810d3f28fb9d1fecb5f8593889ed2c6@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 16 ++-------------- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 1 + 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 53bc5b7d8d5c8..a4aad24abb90e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -131,21 +131,9 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) if (trans_pcie->is_down) return; - if (trans->state >= IWL_TRANS_FW_STARTED) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { - iwl_set_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_REQ); - iwl_poll_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS, - CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS, - 5000); - msleep(100); - iwl_set_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_SW_RESET); - } else if (trans_pcie->fw_reset_handshake) { + if (trans->state >= IWL_TRANS_FW_STARTED) + if (trans_pcie->fw_reset_handshake) iwl_trans_pcie_fw_reset_handshake(trans); - } - } trans_pcie->is_down = true; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 9e462633af552..22393b724e985 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -458,6 +458,7 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans) CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS, CSR_GP_CNTRL_REG_FLAG_BUS_MASTER_DISABLE_STATUS, 100); + msleep(100); } else { iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); From 1b6598c3dc35c631aa16279bb17f293c1b5c4ce8 Mon Sep 17 00:00:00 2001 From: Roee Goldfiner Date: Sun, 17 Oct 2021 16:25:54 +0300 Subject: [PATCH 027/114] iwlwifi: BZ Family SW reset support Previously added BZ reset wasn't taking into account the call to iwl_trans_pcie_sw_reset which used a pre-BZ logic to reset the device - enabling iwl_trans_pcie_sw_reset to support BZ family made this reset redundant. MAC_ACCESS clear shouldn't be called here but only when calling _iwl_trans_pcie_stop_device which now support also BZ family. Signed-off-by: Roee Goldfiner Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.648931fe07e2.Ibf30f9b8e70536da93c4a574ace33d325d3f8da4@changeid Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 12 ---------- .../net/wireless/intel/iwlwifi/pcie/trans.c | 24 ++++++++++++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index a4aad24abb90e..d7e11cf8627ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -163,18 +163,6 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) else iwl_pcie_ctxt_info_free(trans); - /* Make sure (redundant) we've released our request to stay awake */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) - iwl_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); - else - iwl_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) { - iwl_set_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_SW_RESET); - } /* Stop the device, and put it in low power state */ iwl_pcie_gen2_apm_stop(trans, false); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 22393b724e985..12a402be2e06e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -129,7 +129,12 @@ void iwl_trans_pcie_dump_regs(struct iwl_trans *trans) static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans) { /* Reset entire device - do controller reset (results in SHRD_HW_RST) */ - iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + iwl_set_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_SW_RESET); + else + iwl_set_bit(trans, CSR_RESET, + CSR_RESET_REG_FLAG_SW_RESET); usleep_range(5000, 6000); } @@ -1209,8 +1214,12 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) } /* Make sure (redundant) we've released our request to stay awake */ - iwl_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); + else + iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ iwl_pcie_apm_stop(trans, false); @@ -2141,9 +2150,12 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans) if (trans_pcie->cmd_hold_nic_awake) goto out; - - __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_BZ_MAC_ACCESS_REQ); + else + __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* * Above we read the CSR_GP_CNTRL register, which will flush * any previous writes, but we need the write that clears the From d35d95ce8b0a548f3c7059cc0978819bcf2b4536 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 16:25:55 +0300 Subject: [PATCH 028/114] iwlwifi: mvm: Add support for new rate_n_flags in tx_cmd. As part of the new rate_n_flags, tx_cmd API has changed. Add support for these changes. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.26efa51624b1.Ic96ae4d81b3ff07fb514df2b5f6a8e470e4d3778@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/tx.h | 6 ++++-- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 5 +++-- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 14 +++++++++++--- drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 12 ++++++++++-- 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index c0caf9dca545f..25af74d13d4b0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -267,7 +267,8 @@ struct iwl_tx_cmd_gen2 { struct iwl_dram_sec_info dram_info; __le32 rate_n_flags; struct ieee80211_hdr hdr[]; -} __packed; /* TX_CMD_API_S_VER_7 */ +} __packed; /* TX_CMD_API_S_VER_7, + TX_CMD_API_S_VER_9 */ /** * struct iwl_tx_cmd_gen3 - TX command struct to FW for AX210+ devices @@ -290,7 +291,8 @@ struct iwl_tx_cmd_gen3 { __le32 rate_n_flags; __le64 ttl; struct ieee80211_hdr hdr[]; -} __packed; /* TX_CMD_API_S_VER_8 */ +} __packed; /* TX_CMD_API_S_VER_8, + TX_CMD_API_S_VER_10 */ /* * TX response related data diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 1fba6b421d311..307d57ec7f7c9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1240,7 +1240,7 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len) mvmvif = iwl_mvm_vif_from_mac80211(vif); info = IEEE80211_SKB_CB(beacon); rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); - flags = iwl_mvm_mac80211_idx_to_hwrate(rate); + flags = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate); if (rate == IWL_FIRST_CCK_RATE) flags |= IWL_MAC_BEACON_CCK; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 0065cc76a2a04..89c260e1c3f4a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -844,7 +844,8 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm, rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); - tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate)); + tx->rate_n_flags |= + cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate)); if (rate == IWL_FIRST_CCK_RATE) tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK_V1); @@ -930,7 +931,7 @@ static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm, struct ieee80211_chanctx_conf *ctx; int channel; - flags = iwl_mvm_mac80211_idx_to_hwrate(rate); + flags = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate); if (rate == IWL_FIRST_CCK_RATE) flags |= IWL_MAC_BEACON_CCK; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 50a11a595db1e..12b22545e9d04 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1448,7 +1448,7 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, enum nl80211_band band, struct ieee80211_tx_rate *r); -u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx); +u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx); u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac); static inline void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index ff29c4b140dc1..aa1797139f7c8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -268,6 +268,7 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, int rate_idx = -1; u8 rate_plcp; u32 rate_flags = 0; + bool is_cck; struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); /* info->control is only relevant for non HW rate control */ @@ -299,11 +300,18 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0); /* Get PLCP rate for tx_cmd->rate_n_flags */ - rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); + rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate_idx); + is_cck = (rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE); - /* Set CCK flag as needed */ - if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) + /* Set CCK or OFDM flag */ + if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 8) { + if (!is_cck) + rate_flags |= RATE_MCS_LEGACY_OFDM_MSK; + else + rate_flags |= RATE_MCS_CCK_MSK; + } else if (is_cck) { rate_flags |= RATE_MCS_CCK_MSK_V1; + } return (u32)rate_plcp | rate_flags; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index dc1727280248b..11f51a421a3d3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -152,9 +152,17 @@ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, return -1; } -u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx) +u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx) { - /* Get PLCP rate for tx_cmd->rate_n_flags */ + if (iwl_fw_lookup_cmd_ver(fw, LONG_GROUP, + TX_CMD, 0) > 8) + /* In the new rate legacy rates are indexed: + * 0 - 3 for CCK and 0 - 7 for OFDM. + */ + return (rate_idx >= IWL_FIRST_OFDM_RATE ? + rate_idx - IWL_FIRST_OFDM_RATE : + rate_idx); + return iwl_fw_rate_idx_to_plcp(rate_idx); } From cd2c46a7eb5967e390f31938eca3b22571db986e Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 16:25:56 +0300 Subject: [PATCH 029/114] iwlwifi: mvm: Support new version of BEACON_TEMPLATE_CMD. As part of the new rate_n_flags, a new version of BEACON_TEMPLATE_CMD was added in FW in order to support the new rate_n_flags. Add support for the new version. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.b42e67f14293.Ic3f1ed8cb3a31cfaa51174497dd993936b00d398@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/tx.h | 21 +++++++++++---- .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 8 ++---- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 27 ++++++++++++++----- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 ++ 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index 25af74d13d4b0..fd7f577c525b9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -757,11 +757,20 @@ struct iwl_mac_beacon_cmd_v7 { struct ieee80211_hdr frame[]; } __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */ +/* Bit flags for BEACON_TEMPLATE_CMD_API until version 10 */ +enum iwl_mac_beacon_flags_v1 { + IWL_MAC_BEACON_CCK_V1 = BIT(8), + IWL_MAC_BEACON_ANT_A_V1 = BIT(9), + IWL_MAC_BEACON_ANT_B_V1 = BIT(10), + IWL_MAC_BEACON_FILS_V1 = BIT(12), +}; + +/* Bit flags for BEACON_TEMPLATE_CMD_API version 11 and above */ enum iwl_mac_beacon_flags { - IWL_MAC_BEACON_CCK = BIT(8), - IWL_MAC_BEACON_ANT_A = BIT(9), - IWL_MAC_BEACON_ANT_B = BIT(10), - IWL_MAC_BEACON_FILS = BIT(12), + IWL_MAC_BEACON_CCK = BIT(5), + IWL_MAC_BEACON_ANT_A = BIT(6), + IWL_MAC_BEACON_ANT_B = BIT(7), + IWL_MAC_BEACON_FILS = BIT(8), }; /** @@ -789,7 +798,9 @@ struct iwl_mac_beacon_cmd { __le32 ecsa_offset; __le32 csa_offset; struct ieee80211_hdr frame[]; -} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10 */ +} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10, + BEACON_TEMPLATE_CMD_API_S_VER_11, + BEACON_TEMPLATE_CMD_API_S_VER_12 */ struct iwl_beacon_notif { struct iwl_mvm_tx_resp beacon_notify_hdr; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 307d57ec7f7c9..ff66001d507ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1193,7 +1193,6 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len) struct ieee80211_tx_info *info; struct iwl_mac_beacon_cmd beacon_cmd = {}; u8 rate; - u16 flags; int i; len /= 2; @@ -1240,12 +1239,9 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len) mvmvif = iwl_mvm_vif_from_mac80211(vif); info = IEEE80211_SKB_CB(beacon); rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); - flags = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate); - if (rate == IWL_FIRST_CCK_RATE) - flags |= IWL_MAC_BEACON_CCK; - - beacon_cmd.flags = cpu_to_le16(flags); + beacon_cmd.flags = + cpu_to_le16(iwl_mvm_mac_ctxt_get_beacon_flags(mvm->fw, rate)); beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len); beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 89c260e1c3f4a..e31d81a403399 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -812,6 +812,21 @@ u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, return rate; } +u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx) +{ + u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); + bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, + LONG_GROUP, + BEACON_TEMPLATE_CMD, + 0) > 10; + + if (rate_idx <= IWL_FIRST_CCK_RATE) + flags |= is_new_rate ? IWL_MAC_BEACON_CCK + : IWL_MAC_BEACON_CCK_V1; + + return flags; +} + static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct sk_buff *beacon, @@ -930,11 +945,7 @@ static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm, u16 flags; struct ieee80211_chanctx_conf *ctx; int channel; - - flags = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate); - - if (rate == IWL_FIRST_CCK_RATE) - flags |= IWL_MAC_BEACON_CCK; + flags = iwl_mvm_mac_ctxt_get_beacon_flags(mvm->fw, rate); /* Enable FILS on PSC channels only */ rcu_read_lock(); @@ -943,7 +954,11 @@ static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm, WARN_ON(channel == 0); if (cfg80211_channel_is_psc(ctx->def.chan) && !IWL_MVM_DISABLE_AP_FILS) { - flags |= IWL_MAC_BEACON_FILS; + flags |= iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, + BEACON_TEMPLATE_CMD, + 0) > 10 ? + IWL_MAC_BEACON_FILS : + IWL_MAC_BEACON_FILS_V1; beacon_cmd.short_ssid = cpu_to_le32(~crc32_le(~0, vif->bss_conf.ssid, vif->bss_conf.ssid_len)); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 12b22545e9d04..eea6de5f56c82 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1629,6 +1629,8 @@ int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm, void *data, int len); u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, struct ieee80211_vif *vif); +u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, + u8 rate_idx); void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm, __le32 *tim_index, __le32 *tim_size, u8 *beacon, u32 frame_size); From dc52fac37c874cfb909caf6bef34edf69503b979 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 16:25:57 +0300 Subject: [PATCH 030/114] iwlwifi: mvm: Support new TX_RSP and COMPRESSED_BA_RES versions As part of the new rate_n_flags, a new version of this structures was added in the FW. Add support for this new version and for the new rate_n_flags in this API. Both these APIs were updated in one patch since they are using the same functions. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.a28e7a92f558.I19f72735c674f815c6e7c11cecfad6230b4510ef@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/tx.h | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 ++ drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 8 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 89 +++++++++++++++---- .../net/wireless/intel/iwlwifi/mvm/utils.c | 15 ++++ 5 files changed, 99 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index fd7f577c525b9..b7090ae95cfb7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -593,7 +593,8 @@ struct iwl_mvm_tx_resp { __le16 tx_queue; __le16 reserved2; struct agg_tx_status status; -} __packed; /* TX_RSP_API_S_VER_6 */ +} __packed; /* TX_RSP_API_S_VER_6, + TX_RSP_API_S_VER_7 */ /** * struct iwl_mvm_ba_notif - notifies about reception of BA @@ -717,7 +718,8 @@ struct iwl_mvm_compressed_ba_notif { __le16 ra_tid_cnt; struct iwl_mvm_compressed_ba_ratid ra_tid[0]; struct iwl_mvm_compressed_ba_tfd tfd[]; -} __packed; /* COMPRESSED_BA_RES_API_S_VER_4 */ +} __packed; /* COMPRESSED_BA_RES_API_S_VER_4, + COMPRESSED_BA_RES_API_S_VER_5 */ /** * struct iwl_mac_beacon_cmd_v6 - beacon template command diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index eea6de5f56c82..cc11961b0d83f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1443,11 +1443,16 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm); int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm); /* Utils */ +int iwl_mvm_legacy_hw_idx_to_mac80211_idx(u32 rate_n_flags, + enum nl80211_band band); int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, enum nl80211_band band); void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, enum nl80211_band band, struct ieee80211_tx_rate *r); +void iwl_mvm_hwrate_to_tx_rate_v1(u32 rate_n_flags, + enum nl80211_band band, + struct ieee80211_tx_rate *r); u8 iwl_mvm_mac80211_idx_to_hwrate(const struct iwl_fw *fw, int rate_idx); u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 88b5969d7b51c..f4d02f9fe16d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -2692,8 +2692,8 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, return; lq_sta = mvm_sta; - iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags, - info->band, &info->control.rates[0]); + iwl_mvm_hwrate_to_tx_rate_v1(lq_sta->last_rate_n_flags, + info->band, &info->control.rates[0]); info->control.rates[0].count = 1; /* Report the optimal rate based on rssi and STA caps if we haven't @@ -2703,8 +2703,8 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, optimal_rate = rs_get_optimal_rate(mvm, lq_sta); last_ucode_rate = ucode_rate_from_rs_rate(mvm, optimal_rate); - iwl_mvm_hwrate_to_tx_rate(last_ucode_rate, info->band, - &txrc->reported_rate); + iwl_mvm_hwrate_to_tx_rate_v1(last_ucode_rate, info->band, + &txrc->reported_rate); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index aa1797139f7c8..4cc543fb95963 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1292,25 +1292,66 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status) } #endif /* CONFIG_IWLWIFI_DEBUG */ -void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, - enum nl80211_band band, - struct ieee80211_tx_rate *r) +static int iwl_mvm_get_hwrate_chan_width(u32 chan_width) { - if (rate_n_flags & RATE_HT_MCS_GF_MSK) - r->flags |= IEEE80211_TX_RC_GREEN_FIELD; - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { + switch (chan_width) { case RATE_MCS_CHAN_WIDTH_20: - break; + return 0; case RATE_MCS_CHAN_WIDTH_40: - r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; - break; + return IEEE80211_TX_RC_40_MHZ_WIDTH; case RATE_MCS_CHAN_WIDTH_80: - r->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; - break; + return IEEE80211_TX_RC_80_MHZ_WIDTH; case RATE_MCS_CHAN_WIDTH_160: - r->flags |= IEEE80211_TX_RC_160_MHZ_WIDTH; - break; + return IEEE80211_TX_RC_160_MHZ_WIDTH; + default: + return 0; + } +} + +void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, + enum nl80211_band band, + struct ieee80211_tx_rate *r) +{ + u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; + u32 rate = format == RATE_MCS_HT_MSK ? + RATE_HT_MCS_INDEX(rate_n_flags) : + rate_n_flags & RATE_MCS_CODE_MSK; + + r->flags |= + iwl_mvm_get_hwrate_chan_width(rate_n_flags & + RATE_MCS_CHAN_WIDTH_MSK); + + if (rate_n_flags & RATE_MCS_SGI_MSK) + r->flags |= IEEE80211_TX_RC_SHORT_GI; + if (format == RATE_MCS_HT_MSK) { + r->flags |= IEEE80211_TX_RC_MCS; + r->idx = rate; + } else if (format == RATE_MCS_VHT_MSK) { + ieee80211_rate_set_vht(r, rate, + ((rate_n_flags & RATE_MCS_NSS_MSK) >> + RATE_MCS_NSS_POS) + 1); + r->flags |= IEEE80211_TX_RC_VHT_MCS; + } else if (format == RATE_MCS_HE_MSK) { + /* mac80211 cannot do this without ieee80211_tx_status_ext() + * but it only matters for radiotap */ + r->idx = 0; + } else { + r->idx = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags, + band); } +} + +void iwl_mvm_hwrate_to_tx_rate_v1(u32 rate_n_flags, + enum nl80211_band band, + struct ieee80211_tx_rate *r) +{ + if (rate_n_flags & RATE_HT_MCS_GF_MSK) + r->flags |= IEEE80211_TX_RC_GREEN_FIELD; + + r->flags |= + iwl_mvm_get_hwrate_chan_width(rate_n_flags & + RATE_MCS_CHAN_WIDTH_MSK_V1); + if (rate_n_flags & RATE_MCS_SGI_MSK_V1) r->flags |= IEEE80211_TX_RC_SHORT_GI; if (rate_n_flags & RATE_MCS_HT_MSK_V1) { @@ -1331,14 +1372,20 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, /* * translate ucode response to mac80211 tx status control values */ -static void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags, +static void iwl_mvm_hwrate_to_tx_status(const struct iwl_fw *fw, + u32 rate_n_flags, struct ieee80211_tx_info *info) { struct ieee80211_tx_rate *r = &info->status.rates[0]; + if (iwl_fw_lookup_notif_ver(fw, LONG_GROUP, + TX_CMD, 0) > 6) + rate_n_flags = iwl_new_rate_from_v1(rate_n_flags); + info->status.antenna = ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS); - iwl_mvm_hwrate_to_tx_rate(rate_n_flags, info->band, r); + iwl_mvm_hwrate_to_tx_rate(rate_n_flags, + info->band, r); } static void iwl_mvm_tx_status_check_trigger(struct iwl_mvm *mvm, @@ -1480,8 +1527,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, iwl_mvm_tx_status_check_trigger(mvm, status, hdr->frame_control); info->status.rates[0].count = tx_resp->failure_frame + 1; - iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate), + + iwl_mvm_hwrate_to_tx_status(mvm->fw, + le32_to_cpu(tx_resp->initial_rate), info); + + /* Don't assign the converted initial_rate, because driver + * TLC uses this and doesn't support the new FW rate + */ info->status.status_driver_data[1] = (void *)(uintptr_t)le32_to_cpu(tx_resp->initial_rate); @@ -1843,7 +1896,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, info->flags |= IEEE80211_TX_STAT_AMPDU; memcpy(&info->status, &tx_info->status, sizeof(tx_info->status)); - iwl_mvm_hwrate_to_tx_status(rate, info); + iwl_mvm_hwrate_to_tx_status(mvm->fw, rate, info); } } @@ -1864,7 +1917,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, goto out; tx_info->band = chanctx_conf->def.chan->band; - iwl_mvm_hwrate_to_tx_status(rate, tx_info); + iwl_mvm_hwrate_to_tx_status(mvm->fw, rate, tx_info); if (!iwl_mvm_has_tlc_offload(mvm)) { IWL_DEBUG_TX_REPLY(mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 11f51a421a3d3..caf1dcf488886 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -135,6 +135,21 @@ int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len, return iwl_mvm_send_cmd_status(mvm, &cmd, status); } +int iwl_mvm_legacy_hw_idx_to_mac80211_idx(u32 rate_n_flags, + enum nl80211_band band) +{ + int format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; + int rate = rate_n_flags & RATE_LEGACY_RATE_MSK; + bool is_LB = band == NL80211_BAND_2GHZ; + + if (format == RATE_MCS_LEGACY_OFDM_MSK) + return is_LB ? rate + IWL_FIRST_OFDM_RATE : + rate; + + /* CCK is not allowed in HB */ + return is_LB ? rate : -1; +} + int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, enum nl80211_band band) { From ce712478a458fc9ae7488b511088d43d311ccd2e Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sun, 17 Oct 2021 16:25:58 +0300 Subject: [PATCH 031/114] iwlwifi: mvm: Support new rate_n_flags for REPLY_RX_MPDU_CMD and RX_NO_DATA_NOTIF As part of the new rate_n_flags this two APIs may use the new rate. Add support for the new rate. These two APIs were updated in one patch because both of them are using the same functions which were changed. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.7eb6240b8079.I1e804e70a8ebd23840a9431fc5d2a56ad8d5d1a2@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rx.h | 12 +- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 132 +++++++++++------- 2 files changed, 86 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index aa43ef67a2b5f..1989b270862b0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -445,7 +445,7 @@ struct iwl_rx_mpdu_desc_v1 { __le32 phy_data1; }; }; -} __packed; +} __packed; /* RX_MPDU_RES_START_API_S_VER_4 */ /** * struct iwl_rx_mpdu_desc_v3 - RX MPDU descriptor @@ -545,7 +545,8 @@ struct iwl_rx_mpdu_desc_v3 { * @reserved: reserved */ __le32 reserved[2]; -} __packed; /* RX_MPDU_RES_START_API_S_VER_3 */ +} __packed; /* RX_MPDU_RES_START_API_S_VER_3, + RX_MPDU_RES_START_API_S_VER_5 */ /** * struct iwl_rx_mpdu_desc - RX MPDU descriptor @@ -610,7 +611,9 @@ struct iwl_rx_mpdu_desc { struct iwl_rx_mpdu_desc_v1 v1; struct iwl_rx_mpdu_desc_v3 v3; }; -} __packed; /* RX_MPDU_RES_START_API_S_VER_3 */ +} __packed; /* RX_MPDU_RES_START_API_S_VER_3, + RX_MPDU_RES_START_API_S_VER_4, + RX_MPDU_RES_START_API_S_VER_5 */ #define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1) @@ -664,7 +667,8 @@ struct iwl_rx_no_data { __le32 rate; __le32 phy_info[2]; __le32 rx_vec[2]; -} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1 */ +} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1, + TX_NO_DATA_NTFY_API_S_VER_2 */ struct iwl_frame_release { u8 baid; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 8cfec733756bd..0f2ff94d5dfb4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1440,7 +1440,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); struct ieee80211_radiotap_he *he = NULL; struct ieee80211_radiotap_he_mu *he_mu = NULL; - u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1; + u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; u8 stbc, ltf; static const struct ieee80211_radiotap_he known = { .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | @@ -1493,23 +1493,23 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, } } - if (he_type == RATE_MCS_HE_TYPE_EXT_SU_V1 && - rate_n_flags & RATE_MCS_HE_106T_MSK_V1) { + if (he_type == RATE_MCS_HE_TYPE_EXT_SU && + rate_n_flags & RATE_MCS_HE_106T_MSK) { rx_status->bw = RATE_INFO_BW_HE_RU; rx_status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; } /* actually data is filled in mac80211 */ - if (he_type == RATE_MCS_HE_TYPE_SU_V1 || - he_type == RATE_MCS_HE_TYPE_EXT_SU_V1) + if (he_type == RATE_MCS_HE_TYPE_SU || + he_type == RATE_MCS_HE_TYPE_EXT_SU) he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN); stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->nss = - ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> - RATE_VHT_MCS_NSS_POS) + 1; - rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; + ((rate_n_flags & RATE_MCS_NSS_MSK) >> + RATE_MCS_NSS_POS) + 1; + rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK; rx_status->encoding = RX_ENC_HE; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; if (rate_n_flags & RATE_MCS_BF_MSK) @@ -1520,39 +1520,39 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, #define CHECK_TYPE(F) \ BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ - (RATE_MCS_HE_TYPE_ ## F ##_V1 >> RATE_MCS_HE_TYPE_POS_V1)) + (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS)) CHECK_TYPE(SU); CHECK_TYPE(EXT_SU); CHECK_TYPE(MU); CHECK_TYPE(TRIG); - he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS_V1); + he->data1 |= cpu_to_le16(he_type >> RATE_MCS_HE_TYPE_POS); if (rate_n_flags & RATE_MCS_BF_MSK) he->data5 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA5_TXBF); - switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK_V1) >> + switch ((rate_n_flags & RATE_MCS_HE_GI_LTF_MSK) >> RATE_MCS_HE_GI_LTF_POS) { case 0: - if (he_type == RATE_MCS_HE_TYPE_TRIG_V1) + if (he_type == RATE_MCS_HE_TYPE_TRIG) rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; else rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; - if (he_type == RATE_MCS_HE_TYPE_MU_V1) + if (he_type == RATE_MCS_HE_TYPE_MU) ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; else ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X; break; case 1: - if (he_type == RATE_MCS_HE_TYPE_TRIG_V1) + if (he_type == RATE_MCS_HE_TYPE_TRIG) rx_status->he_gi = NL80211_RATE_INFO_HE_GI_1_6; else rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; break; case 2: - if (he_type == RATE_MCS_HE_TYPE_TRIG_V1) { + if (he_type == RATE_MCS_HE_TYPE_TRIG) { rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; } else { @@ -1561,14 +1561,15 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, } break; case 3: - if ((he_type == RATE_MCS_HE_TYPE_SU_V1 || - he_type == RATE_MCS_HE_TYPE_EXT_SU_V1) && - rate_n_flags & RATE_MCS_SGI_MSK_V1) - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; - else - rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_3_2; ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; break; + case 4: + rx_status->he_gi = NL80211_RATE_INFO_HE_GI_0_8; + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; + break; + default: + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN; } he->data5 |= le16_encode_bits(ltf, @@ -1653,6 +1654,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, .info_type = IWL_RX_PHY_INFO_TYPE_NONE, }; bool csi = false; + u32 format; + bool is_sgi; if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; @@ -1690,6 +1693,13 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, phy_data.d2 = desc->v1.phy_data2; phy_data.d3 = desc->v1.phy_data3; } + if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, + REPLY_RX_MPDU_CMD, 0) < 4) { + rate_n_flags = iwl_new_rate_from_v1(rate_n_flags); + IWL_DEBUG_DROP(mvm, "Got old format rate, converting. New rate: 0x%x\n", + rate_n_flags); + } + format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; len = le16_to_cpu(desc->mpdu_len); @@ -1729,7 +1739,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status = IEEE80211_SKB_RXCB(skb); /* This may be overridden by iwl_mvm_rx_he() to HE_RU */ - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { case RATE_MCS_CHAN_WIDTH_20: break; case RATE_MCS_CHAN_WIDTH_40: @@ -1743,7 +1753,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, break; } - if (rate_n_flags & RATE_MCS_HE_MSK_V1) + if (format == RATE_MCS_HE_MSK) iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags, phy_info, queue); @@ -1760,7 +1770,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; } /* set the preamble flag if appropriate */ - if (rate_n_flags & RATE_MCS_CCK_MSK_V1 && + if (format == RATE_MCS_CCK_MSK && phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE; @@ -1936,33 +1946,34 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } } - if (!(rate_n_flags & RATE_MCS_CCK_MSK_V1) && - rate_n_flags & RATE_MCS_SGI_MSK_V1) + is_sgi = format == RATE_MCS_HE_MSK ? + iwl_he_is_sgi(rate_n_flags) : + rate_n_flags & RATE_MCS_SGI_MSK; + + if (!(format == RATE_MCS_CCK_MSK) && is_sgi) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - if (rate_n_flags & RATE_HT_MCS_GF_MSK) - rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; - if (rate_n_flags & RATE_MCS_LDPC_MSK_V1) + if (rate_n_flags & RATE_MCS_LDPC_MSK) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; - if (rate_n_flags & RATE_MCS_HT_MSK_V1) { + if (format == RATE_MCS_HT_MSK) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> - RATE_MCS_STBC_POS; + RATE_MCS_STBC_POS; rx_status->encoding = RX_ENC_HT; - rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1; + rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags); rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { + } else if (format == RATE_MCS_VHT_MSK) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> - RATE_MCS_STBC_POS; - rx_status->nss = - ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> - RATE_VHT_MCS_NSS_POS) + 1; - rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; + RATE_MCS_STBC_POS; + rx_status->nss = + ((rate_n_flags & RATE_MCS_NSS_MSK) >> + RATE_MCS_NSS_POS) + 1; + rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK; rx_status->encoding = RX_ENC_VHT; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; if (rate_n_flags & RATE_MCS_BF_MSK) rx_status->enc_flags |= RX_ENC_FLAG_BF; - } else if (!(rate_n_flags & RATE_MCS_HE_MSK_V1)) { - int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, - rx_status->band); + } else if (!(format == RATE_MCS_HE_MSK)) { + int rate = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags, + rx_status->band); if (WARN(rate < 0 || rate > 0xFF, "Invalid rate flags 0x%x, band %d,\n", @@ -2012,12 +2023,24 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, struct ieee80211_sta *sta = NULL; struct sk_buff *skb; u8 channel, energy_a, energy_b; + u32 format; struct iwl_mvm_rx_phy_data phy_data = { .info_type = le32_get_bits(desc->phy_info[1], IWL_RX_PHY_DATA1_INFO_TYPE_MASK), .d0 = desc->phy_info[0], .d1 = desc->phy_info[1], }; + bool is_sgi; + + if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, + RX_NO_DATA_NOTIF, 0) < 2) { + IWL_DEBUG_DROP(mvm, "Got an old rate format. Old rate: 0x%x\n", + rate_n_flags); + rate_n_flags = iwl_new_rate_from_v1(rate_n_flags); + IWL_DEBUG_DROP(mvm, " Rate after conversion to the new format: 0x%x\n", + rate_n_flags); + } + format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; if (unlikely(iwl_rx_packet_payload_len(pkt) < sizeof(*desc))) return; @@ -2060,7 +2083,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, } /* This may be overridden by iwl_mvm_rx_he() to HE_RU */ - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) { + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { case RATE_MCS_CHAN_WIDTH_20: break; case RATE_MCS_CHAN_WIDTH_40: @@ -2074,7 +2097,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, break; } - if (rate_n_flags & RATE_MCS_HE_MSK_V1) + if (format == RATE_MCS_HE_MSK) iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags, phy_info, queue); @@ -2090,23 +2113,24 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, rcu_read_lock(); - if (!(rate_n_flags & RATE_MCS_CCK_MSK_V1) && - rate_n_flags & RATE_MCS_SGI_MSK_V1) + is_sgi = format == RATE_MCS_HE_MSK ? + iwl_he_is_sgi(rate_n_flags) : + rate_n_flags & RATE_MCS_SGI_MSK; + + if (!(format == RATE_MCS_CCK_MSK) && is_sgi) rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - if (rate_n_flags & RATE_HT_MCS_GF_MSK) - rx_status->enc_flags |= RX_ENC_FLAG_HT_GF; - if (rate_n_flags & RATE_MCS_LDPC_MSK_V1) + if (rate_n_flags & RATE_MCS_LDPC_MSK) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; - if (rate_n_flags & RATE_MCS_HT_MSK_V1) { + if (format == RATE_MCS_HT_MSK) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; rx_status->encoding = RX_ENC_HT; - rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK_V1; + rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags); rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { + } else if (format == RATE_MCS_VHT_MSK) { u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> RATE_MCS_STBC_POS; - rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; + rx_status->rate_idx = rate_n_flags & RATE_MCS_CODE_MSK; rx_status->encoding = RX_ENC_VHT; rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; if (rate_n_flags & RATE_MCS_BF_MSK) @@ -2119,12 +2143,12 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK) + 1; - } else if (rate_n_flags & RATE_MCS_HE_MSK_V1) { + } else if (format == RATE_MCS_HE_MSK) { rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_HE_NSTS_MSK) + 1; } else { - int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, + int rate = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags, rx_status->band); if (WARN(rate < 0 || rate > 0xFF, From 544ab2a9a875d83d35e977a31a7ce41c56ec3bb8 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sun, 17 Oct 2021 16:25:59 +0300 Subject: [PATCH 032/114] iwlwifi: mvm: remove csi from iwl_mvm_pass_packet_to_mac80211() Remove the unused csi parameter from iwl_mvm_pass_packet_to_mac80211(). It is not used anymore, but was accidentally left in. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/20211017132604.480251-2-luca@coelho.fi Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 0f2ff94d5dfb4..e0601f802628c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -240,8 +240,7 @@ static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm, static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, struct napi_struct *napi, struct sk_buff *skb, int queue, - struct ieee80211_sta *sta, - bool csi) + struct ieee80211_sta *sta) { if (iwl_mvm_check_pn(mvm, skb, queue, sta)) kfree_skb(skb); @@ -619,7 +618,7 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm, while ((skb = __skb_dequeue(skb_list))) { iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, reorder_buf->queue, - sta, false); + sta); reorder_buf->num_stored--; } } @@ -1653,7 +1652,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, struct iwl_mvm_rx_phy_data phy_data = { .info_type = IWL_RX_PHY_INFO_TYPE_NONE, }; - bool csi = false; u32 format; bool is_sgi; @@ -2004,7 +2002,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc)) iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, - sta, csi); + sta); out: rcu_read_unlock(); } From ebd935987800690cb72fae22e55ac594fdbbb592 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 16:26:00 +0300 Subject: [PATCH 033/114] iwlwifi: mvm: Add RTS and CTS flags to iwl_tx_cmd_flags. As part of the new rate_n_flags, the RTS and CTS flags are being removed from it. Instead, we have these flags in the flags field in the TX command. Add to new flags to the iwl_tx_cmd_flags enum. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.b5aaabb04432.I999f86ed6a9d9b99e63a33f724963f83f85fbb44@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/tx.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index b7090ae95cfb7..9b3bce83efb60 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -81,6 +81,10 @@ enum iwl_tx_cmd_flags { IWL_TX_FLAGS_CMD_RATE = BIT(0), IWL_TX_FLAGS_ENCRYPT_DIS = BIT(1), IWL_TX_FLAGS_HIGH_PRI = BIT(2), + /* Use these flags only from + * TX_FLAGS_BITS_API_S_VER_4 and above */ + IWL_TX_FLAGS_RTS = BIT(3), + IWL_TX_FLAGS_CTS = BIT(4), }; /* TX_FLAGS_BITS_API_S_VER_3 */ /** From 425d66d8ddfc4aaf692030aea67932dc59f69abf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 16:26:01 +0300 Subject: [PATCH 034/114] iwlwifi: remove redundant iwl_finish_nic_init() argument We don't need this argument, since in all cases where the function is called, trans->trans_cfg is already set (it's in fact set during allocation). Remove it to avoid any confusion about it. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.cb04580b8521.I7129d4ba3dc689af839761d5807a10f99718893e@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dump.c | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/iwl-io.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/iwl-io.h | 5 ++--- drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 ++++---- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index 1f9cf4e405475..016b3a4c5f513 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c @@ -214,7 +214,7 @@ static void iwl_fwrt_dump_lmac_error_log(struct iwl_fw_runtime *fwrt, u8 lmac_nu /* reset the device */ iwl_trans_sw_reset(trans); - err = iwl_finish_nic_init(trans, trans->trans_cfg); + err = iwl_finish_nic_init(trans); if (err) return; } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c index dbab2f10d7505..b9e86bf972e56 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2014, 2018-2019 Intel Corporation + * Copyright (C) 2005-2014, 2018-2019, 2021 Intel Corporation */ #include #include @@ -139,7 +139,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans) { int ret; - ret = iwl_finish_nic_init(trans, trans->trans_cfg); + ret = iwl_finish_nic_init(trans); if (ret) return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index 2517c4ae07ab3..6e96ee5bc261f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -398,9 +398,9 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf) return 0; } -int iwl_finish_nic_init(struct iwl_trans *trans, - const struct iwl_cfg_trans_params *cfg_trans) +int iwl_finish_nic_init(struct iwl_trans *trans) { + const struct iwl_cfg_trans_params *cfg_trans = trans->trans_cfg; u32 poll_ready; int err; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h index 3c21c0e081f8e..37b3bd62897e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2021 Intel Corporation */ #ifndef __iwl_io_h__ #define __iwl_io_h__ @@ -52,8 +52,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); void iwl_force_nmi(struct iwl_trans *trans); -int iwl_finish_nic_init(struct iwl_trans *trans, - const struct iwl_cfg_trans_params *cfg_trans); +int iwl_finish_nic_init(struct iwl_trans *trans); /* Error handling */ int iwl_dump_fh(struct iwl_trans *trans, char **buf); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index d7e11cf8627ac..645cb4dd4e5a3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -47,7 +47,7 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); - ret = iwl_finish_nic_init(trans, trans->trans_cfg); + ret = iwl_finish_nic_init(trans); if (ret) return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 12a402be2e06e..262795368bfe3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -311,7 +311,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) if (trans->trans_cfg->base_params->pll_cfg) iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); - ret = iwl_finish_nic_init(trans, trans->trans_cfg); + ret = iwl_finish_nic_init(trans); if (ret) return ret; @@ -383,7 +383,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) iwl_trans_pcie_sw_reset(trans); - ret = iwl_finish_nic_init(trans, trans->trans_cfg); + ret = iwl_finish_nic_init(trans); if (WARN_ON(ret)) { /* Release XTAL ON request */ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, @@ -1511,7 +1511,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - ret = iwl_finish_nic_init(trans, trans->trans_cfg); + ret = iwl_finish_nic_init(trans); if (ret) return ret; @@ -1744,7 +1744,7 @@ static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans) { int ret; - ret = iwl_finish_nic_init(trans, trans->trans_cfg); + ret = iwl_finish_nic_init(trans); if (ret < 0) return ret; From 6b1259d1046ce068dc5448b65c26534fb22e37ac Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 16:26:02 +0300 Subject: [PATCH 035/114] iwlwifi: mvm: remove session protection after auth/assoc When auth/assoc completes, we should remove session protection, except when association is successful, where we need it until a beacon is received from the AP. In particular, in the case of assoc comeback, currently the session protection event just times out, leading to confusing messages: wlan0: 42:00:00:00:00:00 rejected association temporarily; comeback duration 1000 TU (1024 ms) iwlwifi 0000:00:00.0: Not associated and the session protection is over already... wlan0: Connection to AP 42:00:00:00:00:00 lost wlan0: associate with 42:00:00:00:00:00 (try 2/3) mac80211 never does anything on the "Connection ... lost" as it's not even connected. Removing the session protection when it's no longer needed removes those confusing messages and lets the device do other things in the allocated time. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.95e4bebb069b.I635280e5d26c70414ac6eb5d62b46fe4bd942818@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 4660f21c4e79a..adca7c78b815c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3347,6 +3347,21 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, mutex_unlock(&mvm->mutex); } +static void iwl_mvm_mac_mgd_complete_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_prep_tx_info *info) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + + /* for successful cases (auth/assoc), don't cancel session protection */ + if (info->success) + return; + + mutex_lock(&mvm->mutex); + iwl_mvm_stop_session_protection(mvm, vif); + mutex_unlock(&mvm->mutex); +} + static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, @@ -5347,6 +5362,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .sta_rc_update = iwl_mvm_sta_rc_update, .conf_tx = iwl_mvm_mac_conf_tx, .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, + .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, .flush = iwl_mvm_mac_flush, .sched_scan_start = iwl_mvm_mac_sched_scan_start, From e5f1cc98cc1bd07bc6d4f75e34d89db06a2f8bdb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 16:26:03 +0300 Subject: [PATCH 036/114] iwlwifi: allow rate-limited error messages Sometimes we might want to have an error message for something related to TX/RX, but if that somehow happens frequently it'll overwhelm the logs. Add IWL_ERR_LIMIT() to alleviate that by rate-limiting those messages. To do this, rework __iwl_err() a bit to have a mode argument instead of passing yet another (bool) argument to it. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.2cb1e6b75672.Iec5b1c1bcc6ebc87c586921a6c5c2a937f49e83c@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/dvm/agn.h | 11 +++++---- .../net/wireless/intel/iwlwifi/iwl-debug.c | 24 +++++++++++++------ .../net/wireless/intel/iwlwifi/iwl-debug.h | 21 ++++++++++++---- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h index 1276df1c7a55b..abb8696ba294a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2014 Intel Corporation + * Copyright (C) 2005-2014, 2021 Intel Corporation */ #ifndef __iwl_agn_h__ #define __iwl_agn_h__ @@ -398,8 +398,10 @@ do { \ if (!iwl_is_rfkill((m))) \ IWL_ERR(m, fmt, ##args); \ else \ - __iwl_err((m)->dev, true, \ - !iwl_have_debug_level(IWL_DL_RADIO), \ + __iwl_err((m)->dev, \ + iwl_have_debug_level(IWL_DL_RADIO) ? \ + IWL_ERR_MODE_RFKILL : \ + IWL_ERR_MODE_TRACE_ONLY, \ fmt, ##args); \ } while (0) #else @@ -408,7 +410,8 @@ do { \ if (!iwl_is_rfkill((m))) \ IWL_ERR(m, fmt, ##args); \ else \ - __iwl_err((m)->dev, true, true, fmt, ##args); \ + __iwl_err((m)->dev, IWL_ERR_MODE_TRACE_ONLY, \ + fmt, ##args); \ } while (0) #endif /* CONFIG_IWLWIFI_DEBUG */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c index f6ca2fc37c407..ae4c2a3d63d5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2005-2011 Intel Corporation + * Copyright (C) 2005-2011, 2021 Intel Corporation */ #include #include @@ -31,21 +31,31 @@ IWL_EXPORT_SYMBOL(__iwl_info); __iwl_fn(crit) IWL_EXPORT_SYMBOL(__iwl_crit); -void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, - const char *fmt, ...) +void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...) { struct va_format vaf = { .fmt = fmt, }; - va_list args; + va_list args, args2; va_start(args, fmt); - vaf.va = &args; - if (!trace_only) { - if (rfkill_prefix) + switch (mode) { + case IWL_ERR_MODE_RATELIMIT: + if (net_ratelimit()) + break; + fallthrough; + case IWL_ERR_MODE_REGULAR: + case IWL_ERR_MODE_RFKILL: + va_copy(args2, args); + vaf.va = &args2; + if (mode == IWL_ERR_MODE_RFKILL) dev_err(dev, "(RFKILL) %pV", &vaf); else dev_err(dev, "%pV", &vaf); + va_end(args2); + break; + default: + break; } trace_iwlwifi_err(&vaf); va_end(args); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h index 8db7aeddfd057..1b9f16a31b546 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 - 2020 Intel Corporation + * Copyright(c) 2018 - 2021 Intel Corporation * * Portions of this file are derived from the ipw3945 project. *****************************************************************************/ @@ -22,9 +22,16 @@ static inline bool iwl_have_debug_level(u32 level) #endif } +enum iwl_err_mode { + IWL_ERR_MODE_REGULAR, + IWL_ERR_MODE_RFKILL, + IWL_ERR_MODE_TRACE_ONLY, + IWL_ERR_MODE_RATELIMIT, +}; + struct device; -void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace, - const char *fmt, ...) __printf(4, 5); +void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...) + __printf(3, 4); void __iwl_warn(struct device *dev, const char *fmt, ...) __printf(2, 3); void __iwl_info(struct device *dev, const char *fmt, ...) __printf(2, 3); void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3); @@ -33,13 +40,17 @@ void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3); #define CHECK_FOR_NEWLINE(f) BUILD_BUG_ON(f[sizeof(f) - 2] != '\n') /* No matter what is m (priv, bus, trans), this will work */ -#define IWL_ERR_DEV(d, f, a...) \ +#define __IWL_ERR_DEV(d, mode, f, a...) \ do { \ CHECK_FOR_NEWLINE(f); \ - __iwl_err((d), false, false, f, ## a); \ + __iwl_err((d), mode, f, ## a); \ } while (0) +#define IWL_ERR_DEV(d, f, a...) \ + __IWL_ERR_DEV(d, IWL_ERR_MODE_REGULAR, f, ## a) #define IWL_ERR(m, f, a...) \ IWL_ERR_DEV((m)->dev, f, ## a) +#define IWL_ERR_LIMIT(m, f, a...) \ + __IWL_ERR_DEV((m)->dev, IWL_ERR_MODE_RATELIMIT, f, ## a) #define IWL_WARN(m, f, a...) \ do { \ CHECK_FOR_NEWLINE(f); \ From 75da590ffae71db4567adffff0288bea70a41219 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 16:26:04 +0300 Subject: [PATCH 037/114] iwlwifi: mvm: reduce WARN_ON() in TX status path Evidently, it's possible to hit this issue, so reduce the noise from it by just having it print a (rate-limited) message instead. We don't really know yet why we hit it, but there's no value in having a WARN_ON() here. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017162352.8d503387b523.Id2c82d023df5128e553b28c935d30df4d9411917@changeid 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 4cc543fb95963..bdd4ee4325483 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1505,7 +1505,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, /* the FW should have stopped the queue and not * return this status */ - WARN_ON(1); + IWL_ERR_LIMIT(mvm, + "FW reported TX filtered, status=0x%x, FC=0x%x\n", + status, le16_to_cpu(hdr->frame_control)); info->flags |= IEEE80211_TX_STAT_TX_FILTERED; break; default: From 2fd8aaaeb87441e2577e8e55373e9b3b221dc4b0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 16:59:45 +0300 Subject: [PATCH 038/114] iwlwifi: pcie: try to grab NIC access early Sometimes some NICs may fail to initialize, but if we have such a scenario we may only see an alive timeout (i.e. the firmware doesn't send us the alive message), and that will only cause us to fail the interface up. Try to once grab NIC access during device probe to ensure we can properly talk to the hardware at all, and to do all the potential workarounds in that function. Since we now finish NIC init here, we can remove it from the later potential read of the RF ID. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.604dfc8f43bd.I07b58a5c9238f75413a91198452ba1268ee79425@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index d1b9f85c00cf2..1b19413f6ceb8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1322,6 +1322,24 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); + /* + * Let's try to grab NIC access early here. Sometimes, NICs may + * fail to initialize, and if that happens it's better if we see + * issues early on (and can reprobe, per the logic inside), than + * first trying to load the firmware etc. and potentially only + * detecting any problems when the first interface is brought up. + */ + ret = iwl_finish_nic_init(iwl_trans); + if (ret) + goto out_free_trans; + if (iwl_trans_grab_nic_access(iwl_trans)) { + /* all good */ + iwl_trans_release_nic_access(iwl_trans); + } else { + ret = -EIO; + goto out_free_trans; + } + iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); /* From c0ad5c49252133975b97afd4e2536d21fd38829b Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Sun, 17 Oct 2021 16:59:46 +0300 Subject: [PATCH 039/114] iwlwifi: mvm: set inactivity timeouts also for PS-poll Code tried to avoid setting ACs for PS-poll by an early return. However as a result the timeouts weren't set as well. Inactivity timeout of zero means we will always try to go back to sleep immediately after moving to AM, which doesn't make much sense, and isn't supported by FW. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.dda7f6ba0b22.Ia107bfe496b84e8a2edb33d9f39a5d2b56ed63f7@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/power.c | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c index f2b090be38980..b2ea2fca5376f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2019 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -128,6 +128,19 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm, enum ieee80211_ac_numbers ac; bool tid_found = false; + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) || + cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { + cmd->rx_data_timeout_uapsd = + cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); + cmd->tx_data_timeout_uapsd = + cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); + } else { + cmd->rx_data_timeout_uapsd = + cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT); + cmd->tx_data_timeout_uapsd = + cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT); + } + #ifdef CONFIG_IWLWIFI_DEBUGFS /* set advanced pm flag with no uapsd ACs to enable ps-poll */ if (mvmvif->dbgfs_pm.use_ps_poll) { @@ -182,19 +195,6 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm, cmd->uapsd_max_sp = mvm->hw->uapsd_max_sp_len; - if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) || - cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { - cmd->rx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); - cmd->tx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); - } else { - cmd->rx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT); - cmd->tx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT); - } - if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { cmd->heavy_tx_thld_packets = IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS; From 33c99471b0863bbbf0912ad8a78aab3a7e52cfd6 Mon Sep 17 00:00:00 2001 From: Yaara Baruch Date: Sun, 17 Oct 2021 16:59:47 +0300 Subject: [PATCH 040/114] iwlwifi: add new killer devices to the driver Add 1550, 1675 and 1690 killer devices to the driver. Signed-off-by: Yaara Baruch Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.9a3d01b8c4e9.I9720afa0a6ea72f94ed4a3f3cf88294174ab905b@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 8 ++++++++ .../net/wireless/intel/iwlwifi/iwl-config.h | 4 ++++ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 20 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 0b8a897a18532..0f18ff990a9c1 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -476,6 +476,14 @@ const char iwl_ax210_killer_1675w_name[] = "Killer(R) Wi-Fi 6E AX1675w 160MHz Wireless Network Adapter (210D2W)"; const char iwl_ax210_killer_1675x_name[] = "Killer(R) Wi-Fi 6E AX1675x 160MHz Wireless Network Adapter (210NGW)"; +const char iwl_ax211_killer_1675s_name[] = + "Killer(R) Wi-Fi 6E AX1675s 160MHz Wireless Network Adapter (211NGW)"; +const char iwl_ax211_killer_1675i_name[] = + "Killer(R) Wi-Fi 6E AX1675i 160MHz Wireless Network Adapter (211NGW)"; +const char iwl_ax411_killer_1690s_name[] = + "Killer(R) Wi-Fi 6E AX1690s 160MHz Wireless Network Adapter (411D2W)"; +const char iwl_ax411_killer_1690i_name[] = + "Killer(R) Wi-Fi 6E AX1690i 160MHz Wireless Network Adapter (411NGW)"; const struct iwl_cfg iwl_qu_b0_hr1_b0 = { .fw_name_pre = IWL_QU_B_HR_B_FW_PRE, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index e06994610e77d..665167a223f61 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -511,6 +511,10 @@ extern const char iwl_ax210_killer_1675w_name[]; extern const char iwl_ax210_killer_1675x_name[]; extern const char iwl9560_killer_1550i_160_name[]; extern const char iwl9560_killer_1550s_160_name[]; +extern const char iwl_ax211_killer_1675s_name[]; +extern const char iwl_ax211_killer_1675i_name[]; +extern const char iwl_ax411_killer_1690s_name[]; +extern const char iwl_ax411_killer_1690i_name[]; extern const char iwl_ax211_name[]; extern const char iwl_ax221_name[]; extern const char iwl_ax231_name[]; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 1b19413f6ceb8..7bd24144fff2c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -532,10 +532,20 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x31DC, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), IWL_DEV_INFO(0xA370, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_name), IWL_DEV_INFO(0xA370, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), + IWL_DEV_INFO(0x54F0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), + IWL_DEV_INFO(0x54F0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_name), IWL_DEV_INFO(0x51F0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), IWL_DEV_INFO(0x51F0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name), + IWL_DEV_INFO(0x51F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x51F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x54F0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x54F0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x7A70, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x7A70, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), + IWL_DEV_INFO(0x7E40, 0x1691, iwl_cfg_ma_a0_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x7E40, 0x1692, iwl_cfg_ma_a0_gf4_a0, iwl_ax411_killer_1690i_name), /* AX200 */ IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), @@ -639,6 +649,12 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x7AF0, 0x0510, iwlax211_2ax_cfg_so_gf_a0, NULL), IWL_DEV_INFO(0x7AF0, 0x0A10, iwlax211_2ax_cfg_so_gf_a0, NULL), + /* So with JF */ + IWL_DEV_INFO(0x7A70, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), + IWL_DEV_INFO(0x7A70, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name), + IWL_DEV_INFO(0x7AF0, 0x1551, iwl9560_2ac_cfg_soc, iwl9560_killer_1550s_160_name), + IWL_DEV_INFO(0x7AF0, 0x1552, iwl9560_2ac_cfg_soc, iwl9560_killer_1550i_160_name), + /* SnJ with HR */ IWL_DEV_INFO(0x2725, 0x00B0, iwlax411_2ax_cfg_sosnj_gf4_a0, NULL), IWL_DEV_INFO(0x2726, 0x0090, iwlax211_cfg_snj_gf_a0, NULL), @@ -648,6 +664,10 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x2726, 0x0510, iwlax211_cfg_snj_gf_a0, NULL), IWL_DEV_INFO(0x2726, 0x1651, iwl_cfg_snj_hr_b0, iwl_ax201_killer_1650s_name), IWL_DEV_INFO(0x2726, 0x1652, iwl_cfg_snj_hr_b0, iwl_ax201_killer_1650i_name), + IWL_DEV_INFO(0x2726, 0x1671, iwlax211_cfg_snj_gf_a0, iwl_ax211_killer_1675s_name), + IWL_DEV_INFO(0x2726, 0x1672, iwlax211_cfg_snj_gf_a0, iwl_ax211_killer_1675i_name), + IWL_DEV_INFO(0x2726, 0x1691, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x2726, 0x1692, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690i_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, From d41cdbcd71185884c3bacc97c42dabd82a058d7e Mon Sep 17 00:00:00 2001 From: Rotem Saado Date: Sun, 17 Oct 2021 16:59:48 +0300 Subject: [PATCH 041/114] iwlwifi: dbg: treat dbgc allocation failure when tlv is missing in case allocation tlv is missing for specific dbgc id, treat it as allocation failure. with this behavior we removing later the unsupported regions relating to the failed dbgc allocation. this saves operational driver memory and run time at collecting debug data. Signed-off-by: Rotem Saado Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.4cd241abf1de.I8f6cf00a7266675dfebdc01a73c1ac6e001855b9@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 8692700207638..75d5ed0c32048 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -1149,8 +1149,10 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt) &fwrt->trans->dbg.fw_mon_cfg[i]; u32 dest = le32_to_cpu(fw_mon_cfg->buf_location); - if (dest == IWL_FW_INI_LOCATION_INVALID) + if (dest == IWL_FW_INI_LOCATION_INVALID) { + failed_alloc |= BIT(i); continue; + } if (*ini_dest == IWL_FW_INI_LOCATION_INVALID) *ini_dest = dest; From 8b75858c2e218570a61bb7ee21b17bdd19c49485 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 16:59:49 +0300 Subject: [PATCH 042/114] iwlwifi: mvm: set BT-coex high priority for 802.1X/4-way-HS Set BT coex high priority during the 802.1X handshake to avoid issues where BT is active enough to kill all the big negotiation frames that we may need to send (e.g. with a large certificate), leading to the connection not being established correctly. Give WiFi priority over BT during this short but critical phase. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.a1825bbba397.I10315577fb41dfcec15c92e8f6785d9655f74c6a@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/mac.h | 3 +++ drivers/net/wireless/intel/iwlwifi/fw/file.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 6 ++++++ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 8 ++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 ++ 5 files changed, 20 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h index 7be7715b431df..11f0bd283e499 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h @@ -138,6 +138,8 @@ struct iwl_mac_data_ibss { * @FLEXIBLE_TWT_SUPPORTED: AP supports flexible TWT schedule * @PROTECTED_TWT_SUPPORTED: AP supports protected TWT frames (with 11w) * @BROADCAST_TWT_SUPPORTED: AP and STA support broadcast TWT + * @COEX_HIGH_PRIORITY_ENABLE: high priority mode for BT coex, to be used + * during 802.1X negotiation (and allowed during 4-way-HS) */ enum iwl_mac_data_policy { TWT_SUPPORTED = BIT(0), @@ -145,6 +147,7 @@ enum iwl_mac_data_policy { FLEXIBLE_TWT_SUPPORTED = BIT(2), PROTECTED_TWT_SUPPORTED = BIT(3), BROADCAST_TWT_SUPPORTED = BIT(4), + COEX_HIGH_PRIORITY_ENABLE = BIT(5), }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index c65196daf55b3..565918054ed19 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -420,6 +420,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)58, IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)59, IWL_UCODE_TLV_CAPA_BROADCAST_TWT = (__force iwl_ucode_tlv_capa_t)60, + IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO = (__force iwl_ucode_tlv_capa_t)61, /* set 2 */ IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index e31d81a403399..cfb69e49a687a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -604,6 +604,12 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, ctxt_sta->is_assoc = cpu_to_le32(1); + if (!mvmvif->authorized && + fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO)) + ctxt_sta->data_policy |= + cpu_to_le32(COEX_HIGH_PRIORITY_ENABLE); + /* * allow multicast data frames only as long as the station is * authorized, i.e., GTK keys are already installed (if needed) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index adca7c78b815c..5277f63dac3d2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3201,6 +3201,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, /* enable beacon filtering */ WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); + mvmvif->authorized = 1; + /* * Now that the station is authorized, i.e., keys were already * installed, need to indicate to the FW that @@ -3217,6 +3219,12 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, /* Multicast data frames are no longer allowed */ iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); + /* + * Set this after the above iwl_mvm_mac_ctxt_changed() + * to avoid sending high prio again for a little time. + */ + mvmvif->authorized = 0; + /* disable beacon filtering */ ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); WARN_ON(ret && diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index cc11961b0d83f..4277536e31c3a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -297,6 +297,7 @@ struct iwl_probe_resp_data { * see enum &iwl_mvm_low_latency_cause for causes. * @low_latency_actual: boolean, indicates low latency is set, * as a result from low_latency bit flags and takes force into account. + * @authorized: indicates the AP station was set to authorized * @ps_disabled: indicates that this interface requires PS to be disabled * @queue_params: QoS params for this MAC * @bcast_sta: station used for broadcast packets. Used by the following @@ -330,6 +331,7 @@ struct iwl_mvm_vif { bool monitor_active; u8 low_latency: 6; u8 low_latency_actual: 1; + u8 authorized:1; bool ps_disabled; struct iwl_mvm_vif_bf_data bf_data; From c3eae059fcab3f10c1204d2b297172d734a34ba6 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Sun, 17 Oct 2021 16:59:50 +0300 Subject: [PATCH 043/114] iwlwifi: mvm: improve log when processing CSA Sometimes driver fails to detect misbehaving AP since we may miss a few beacons (AP is declared misbehaving only after the second time CSA counter has a wrong jump). Move the print to the start of the function to avoid doubts when analysing this kind of issues. Signed-off-by: Gregory Greenman Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.8e6b1eb8a436.I5fd6caee968007e91d03b93d6ea84b670ce047e9@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 5277f63dac3d2..2645dd8fef83e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4732,6 +4732,9 @@ static void iwl_mvm_channel_switch_rx_beacon(struct ieee80211_hw *hw, if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CS_MODIFY)) return; + IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d count = %d (old %d) mode = %d\n", + mvmvif->id, chsw->count, mvmvif->csa_count, chsw->block_tx); + if (chsw->count >= mvmvif->csa_count && chsw->block_tx) { if (mvmvif->csa_misbehave) { /* Second time, give up on this AP*/ @@ -4748,8 +4751,6 @@ static void iwl_mvm_channel_switch_rx_beacon(struct ieee80211_hw *hw, if (mvmvif->csa_failed) goto out_unlock; - IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d count = %d mode = %d\n", - mvmvif->id, chsw->count, chsw->block_tx); WARN_ON(iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, CHANNEL_SWITCH_TIME_EVENT_CMD), From 66198ac53195f004c40325d55aa1e35494feb856 Mon Sep 17 00:00:00 2001 From: Yaara Baruch Date: Sun, 17 Oct 2021 16:59:51 +0300 Subject: [PATCH 044/114] iwlwifi: add new device id 7F70 Add new 7F70 device to cards id struct. Add new 7F70 DID killers devices. Signed-off-by: Yaara Baruch Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.d931a48ad8bd.I9b027837cba3478c9bb74c3f07df48eaef70a197@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 7bd24144fff2c..37a1ef868e6fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -499,6 +499,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { /* Ma devices */ {IWL_PCI_DEVICE(0x2729, PCI_ANY_ID, iwl_ma_trans_cfg)}, {IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_trans_cfg)}, + {IWL_PCI_DEVICE(0x7F70, PCI_ANY_ID, iwl_ma_trans_cfg)}, /* Bz devices */ {IWL_PCI_DEVICE(0x2727, PCI_ANY_ID, iwl_bz_trans_cfg)}, @@ -668,6 +669,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x2726, 0x1672, iwlax211_cfg_snj_gf_a0, iwl_ax211_killer_1675i_name), IWL_DEV_INFO(0x2726, 0x1691, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690s_name), IWL_DEV_INFO(0x2726, 0x1692, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x7F70, 0x1691, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x7F70, 0x1692, iwlax411_2ax_cfg_sosnj_gf4_a0, iwl_ax411_killer_1690i_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_PU, IWL_CFG_ANY, From 1f578d4f2d52f64133c4b53346451b1116242e3d Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Sun, 17 Oct 2021 16:59:52 +0300 Subject: [PATCH 045/114] iwlwifi: mvm: Read acpi dsm to get channel activation bitmap Read the bitmap from the ACPI and pass it to he FW through LARI_CONFIG_CHANGE_CMD. This allows OEMs to override channel state to active as per Geo Location bitmap. Signed-off-by: Miri Korenblit Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.23d4f2d182c0.I39ac5ff74ac6f2223f393657205eddc1c8e48890@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 3 ++- .../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 23 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 18 +++++++++++---- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 16ed0995b51e7..0822c6b15c43e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -116,7 +116,8 @@ enum iwl_dsm_funcs_rev_0 { DSM_FUNC_DISABLE_SRD = 1, DSM_FUNC_ENABLE_INDONESIA_5G2 = 2, DSM_FUNC_11AX_ENABLEMENT = 6, - DSM_FUNC_ENABLE_UNII4_CHAN = 7 + DSM_FUNC_ENABLE_UNII4_CHAN = 7, + DSM_FUNC_ACTIVATE_CHANNEL = 8 }; enum iwl_dsm_values_srd { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index cf48c6fa8f655..3551a3f1c1aab 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -471,6 +471,29 @@ struct iwl_lari_config_change_cmd_v4 { __le32 oem_unii4_allow_bitmap; } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_4 */ +/** + * struct iwl_lari_config_change_cmd_v5 - change LARI configuration + * @config_bitmap: Bitmap of the config commands. Each bit will trigger a + * different predefined FW config operation. + * @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets. + * @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits + * per country, one to indicate whether to override and the other to + * indicate the value to use. + * @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits + * per country, one to indicate whether to override and the other to + * indicate allow/disallow unii4 channels. + * @chan_state_active_bitmap: Bitmap for overriding channel state to active. + * Each bit represents a country or region to activate, according to the BIOS + * definitions. + */ +struct iwl_lari_config_change_cmd_v5 { + __le32 config_bitmap; + __le32 oem_uhb_allow_bitmap; + __le32 oem_11ax_allow_bitmap; + __le32 oem_unii4_allow_bitmap; + __le32 chan_state_active_bitmap; +} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_5 */ + /** * struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete * @status: PNVM image loading status diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 660860b8d02f0..410a8d20d56e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1139,7 +1139,7 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) { int ret; u32 value; - struct iwl_lari_config_change_cmd_v4 cmd = {}; + struct iwl_lari_config_change_cmd_v5 cmd = {}; cmd.config_bitmap = iwl_acpi_get_lari_config_bitmap(&mvm->fwrt); @@ -1155,14 +1155,23 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) if (!ret) cmd.oem_unii4_allow_bitmap = cpu_to_le32(value); + ret = iwl_acpi_get_dsm_u32((&mvm->fwrt)->dev, 0, + DSM_FUNC_ACTIVATE_CHANNEL, + &iwl_guid, &value); + if (!ret) + cmd.chan_state_active_bitmap = cpu_to_le32(value); + if (cmd.config_bitmap || cmd.oem_11ax_allow_bitmap || - cmd.oem_unii4_allow_bitmap) { + cmd.oem_unii4_allow_bitmap || + cmd.chan_state_active_bitmap) { size_t cmd_size; u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, REGULATORY_AND_NVM_GROUP, LARI_CONFIG_CHANGE, 1); - if (cmd_ver == 4) + if (cmd_ver == 5) + cmd_size = sizeof(struct iwl_lari_config_change_cmd_v5); + else if (cmd_ver == 4) cmd_size = sizeof(struct iwl_lari_config_change_cmd_v4); else if (cmd_ver == 3) cmd_size = sizeof(struct iwl_lari_config_change_cmd_v3); @@ -1176,8 +1185,9 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) le32_to_cpu(cmd.config_bitmap), le32_to_cpu(cmd.oem_11ax_allow_bitmap)); IWL_DEBUG_RADIO(mvm, - "sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, cmd_ver=%d\n", + "sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, chan_state_active_bitmap=0x%x, cmd_ver=%d\n", le32_to_cpu(cmd.oem_unii4_allow_bitmap), + le32_to_cpu(cmd.chan_state_active_bitmap), cmd_ver); ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP, From 72c43f7d6562cec138536e7e6d0939692ff74482 Mon Sep 17 00:00:00 2001 From: Rotem Saado Date: Sun, 17 Oct 2021 16:59:53 +0300 Subject: [PATCH 046/114] iwlwifi: dbg: treat non active regions as unsupported regions If a region is not active, it means that it was not defined as a region TLV in the FW image. We should treat them as unsupported in that case. This saves operational driver memory and run time when collecting debug data by skipping unsupported regions. Signed-off-by: Rotem Saado Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.8025bd29d86a.I3ecb4e273bf714e426d82217e0590264cb763419@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 75d5ed0c32048..f487cc8b9fe0b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -1179,8 +1179,10 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt) &fwrt->trans->dbg.active_regions[i]; u32 reg_type; - if (!*active_reg) + if (!*active_reg) { + fwrt->trans->dbg.unsupported_region_msk |= BIT(i); continue; + } reg = (void *)(*active_reg)->data; reg_type = le32_to_cpu(reg->type); From 2c5769e358b7b436f4e848f134d2bbac6010a490 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 17 Oct 2021 16:59:54 +0300 Subject: [PATCH 047/114] iwlwifi: pnvm: print out the version properly The version really is a git sha1, not a hex number, so we need to print it out with leading zeroes (8 digits) and without 0x prefix. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211017165728.83422182774a.I40703fd517534133eb67d644ee16532ba8a67e35@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index 069fcbc46d2ba..7d4aa398729a1 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -162,7 +162,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data, goto out; } - IWL_INFO(trans, "loaded PNVM version 0x%0x\n", sha1); + IWL_INFO(trans, "loaded PNVM version %08x\n", sha1); ret = iwl_trans_set_pnvm(trans, pnvm_data, size); out: From 03a25c01de3367e6380fd98a9cbb3452b221d50f Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Wed, 20 Oct 2021 23:24:35 +0800 Subject: [PATCH 048/114] mt76: mt7615: apply cached RF data for DBDC Band0 and band1 share the same hardware, so band0 will stop Tx/Rx when band1 performs Rx calibration. cal_cache is introduced to solve such corner cases by moving necessary datas from channel_switch to bootup. Co-developed-by: Peter Chiu Signed-off-by: Peter Chiu Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7615/mcu.c | 22 +++++++++++++++++-- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index 2cb3969e6432b..25f9cbe2cd610 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -1698,6 +1698,19 @@ int mt7615_mcu_fw_log_2_host(struct mt7615_dev *dev, u8 ctrl) sizeof(data), true); } +static int mt7615_mcu_cal_cache_apply(struct mt7615_dev *dev) +{ + struct { + bool cache_enable; + u8 pad[3]; + } data = { + .cache_enable = true + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_CAL_CACHE, &data, + sizeof(data), false); +} + static int mt7663_load_n9(struct mt7615_dev *dev, const char *name) { u32 offset = 0, override_addr = 0, flag = FW_START_DLYCAL; @@ -1906,9 +1919,14 @@ int mt7615_mcu_init(struct mt7615_dev *dev) mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false); dev_dbg(dev->mt76.dev, "Firmware init done\n"); set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); - mt7615_mcu_fw_log_2_host(dev, 0); - return 0; + if (dev->dbdc_support) { + ret = mt7615_mcu_cal_cache_apply(dev); + if (ret) + return ret; + } + + return mt7615_mcu_fw_log_2_host(dev, 0); } EXPORT_SYMBOL_GPL(mt7615_mcu_init); diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index b89faab049960..4e2c9dafd7765 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -531,6 +531,7 @@ enum { MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58, MCU_EXT_CMD_RXDCOC_CAL = 0x59, MCU_EXT_CMD_TXDPD_CAL = 0x60, + MCU_EXT_CMD_CAL_CACHE = 0x67, MCU_EXT_CMD_SET_RDD_TH = 0x7c, MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d, }; From 2eec60dc9fae51953b823bff21df27f78cbd0c08 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Thu, 21 Oct 2021 04:57:54 +0800 Subject: [PATCH 049/114] mt76: mt7915: remove mt7915_mcu_add_he() Make mt7915_mcu_sta_he_tlv() as a part of mt7915_mcu_add_rate_ctrl() as firmware rate control should get HE rate information from sta_rec_he, and reduce a global function accordingly. Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7915/mac.c | 6 ++-- .../net/wireless/mediatek/mt76/mt7915/main.c | 2 +- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 36 ++++++------------- .../wireless/mediatek/mt76/mt7915/mt7915.h | 4 +-- 4 files changed, 14 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 21e6ef07814c6..6fc12e45a0129 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -2077,10 +2077,8 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED | IEEE80211_RC_NSS_CHANGED | - IEEE80211_RC_BW_CHANGED)) { - mt7915_mcu_add_he(dev, vif, sta); - mt7915_mcu_add_rate_ctrl(dev, vif, sta); - } + IEEE80211_RC_BW_CHANGED)) + mt7915_mcu_add_rate_ctrl(dev, vif, sta, true); if (changed & IEEE80211_RC_SMPS_CHANGED) mt7915_mcu_add_smps(dev, vif, sta); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 8be78917dee9a..ca44f68c54343 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -663,7 +663,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, if (ret) return ret; - return mt7915_mcu_add_rate_ctrl(dev, vif, sta); + return mt7915_mcu_add_rate_ctrl(dev, vif, sta, false); } void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index b4cc4cb35762b..27b741e38920c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2149,41 +2149,25 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, } int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct ieee80211_sta *sta, bool changed) { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct sk_buff *skb; - int len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_ra); - skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len); + skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, + MT7915_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); - mt7915_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta); - - return mt76_mcu_skb_send_msg(&dev->mt76, skb, - MCU_EXT_CMD(STA_REC_UPDATE), true); -} - -int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; - struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; - struct sk_buff *skb; - int len; - - if (!sta->he_cap.has_he) - return 0; - - len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_he); - - skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len); - if (IS_ERR(skb)) - return PTR_ERR(skb); + /* firmware rc algorithm refers to sta_rec_he for HE control. + * once dev->rc_work changes the settings driver should also + * update sta_rec_he here. + */ + if (sta->he_cap.has_he && changed) + mt7915_mcu_sta_he_tlv(skb, sta, vif); - mt7915_mcu_sta_he_tlv(skb, sta, vif); + mt7915_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta); return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD(STA_REC_UPDATE), true); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index fff15f6b9cad3..79a33afc5920a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -409,9 +409,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif, bool enable); int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); + struct ieee80211_sta *sta, bool changed); int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt7915_set_channel(struct mt7915_phy *phy); From 70fd1333cd32f530bc825f36ce2d705ac43106c2 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Thu, 21 Oct 2021 04:57:55 +0800 Subject: [PATCH 050/114] mt76: mt7915: rework .set_bitrate_mask() to support more options With this patch, driver can support single rate, (HE)GI and HE_LTF configuration through .set_bitrate_mask(). Tested-by: MeiChia Chiu Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- .../net/wireless/mediatek/mt76/mt7915/main.c | 32 ++-- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 147 +++++++++++++++++- .../net/wireless/mediatek/mt76/mt7915/mcu.h | 16 +- .../wireless/mediatek/mt76/mt7915/mt7915.h | 5 + 5 files changed, 175 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 6fc12e45a0129..5fcf35f2d9fbe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -89,7 +89,7 @@ bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask) 0, 5000); } -static u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw) +u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw) { mt76_wr(dev, MT_WTBLON_TOP_WDUCR, FIELD_PREP(MT_WTBLON_TOP_WDUCR_GROUP, (wcid >> 7))); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index ca44f68c54343..057ab27b70832 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -172,6 +172,9 @@ static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif) int i; for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) { + mvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI; + mvif->bitrate_mask.control[i].he_gi = GENMASK(7, 0); + mvif->bitrate_mask.control[i].he_ltf = GENMASK(7, 0); mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0); memset(mvif->bitrate_mask.control[i].ht_mcs, GENMASK(7, 0), sizeof(mvif->bitrate_mask.control[i].ht_mcs)); @@ -994,7 +997,6 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta) { struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct mt7915_dev *dev = msta->vif->phy->dev; - struct ieee80211_hw *hw = msta->vif->phy->mt76->hw; u32 *changed = data; spin_lock_bh(&dev->sta_poll_lock); @@ -1002,8 +1004,6 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta) if (list_empty(&msta->rc_list)) list_add_tail(&msta->rc_list, &dev->sta_rc_list); spin_unlock_bh(&dev->sta_poll_lock); - - ieee80211_queue_work(hw, &dev->rc_work); } static void mt7915_sta_rc_update(struct ieee80211_hw *hw, @@ -1011,7 +1011,11 @@ static void mt7915_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u32 changed) { + struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct mt7915_dev *dev = phy->dev; + mt7915_sta_rc_work(&changed, sta); + ieee80211_queue_work(hw, &dev->rc_work); } static int @@ -1019,22 +1023,22 @@ mt7915_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; - enum nl80211_band band = mvif->phy->mt76->chandef.chan->band; - u32 changed; - - if (mask->control[band].gi == NL80211_TXRATE_FORCE_LGI) - return -EINVAL; + struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct mt7915_dev *dev = phy->dev; + u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; - changed = IEEE80211_RC_SUPP_RATES_CHANGED; mvif->bitrate_mask = *mask; - /* Update firmware rate control to add a boundary on top of table - * to limit the rate selection for each peer, so when set bitrates - * vht-mcs-5 1:9, which actually means nss = 1 mcs = 0~9. This only - * applies to data frames as for the other mgmt, mcast, bcast still - * use legacy rates as it is. + /* if multiple rates across different preambles are given we can + * reconfigure this info with all peers using sta_rec command with + * the below exception cases. + * - single rate : if a rate is passed along with different preambles, + * we select the highest one as fixed rate. i.e VHT MCS for VHT peers. + * - multiple rates: if it's not in range format i.e 0-{7,8,9} for VHT + * then multiple MCS setting (MCS 4,5,6) is not supported. */ ieee80211_iterate_stations_atomic(hw, mt7915_sta_rc_work, &changed); + ieee80211_queue_work(hw, &dev->rc_work); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 27b741e38920c..aa7964788a1c4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2050,6 +2050,128 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2); } +int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + void *data, u32 field) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct sta_phy *phy = data; + struct sta_rec_ra_fixed *ra; + struct sk_buff *skb; + struct tlv *tlv; + int len = sizeof(struct sta_req_hdr) + sizeof(*ra); + + skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + tlv = mt7915_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra)); + ra = (struct sta_rec_ra_fixed *)tlv; + + switch (field) { + case RATE_PARAM_AUTO: + break; + case RATE_PARAM_FIXED_MCS: + case RATE_PARAM_FIXED_GI: + case RATE_PARAM_FIXED_HE_LTF: + ra->phy = *phy; + break; + default: + break; + } + ra->field = cpu_to_le32(field); + + return mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_EXT_CMD(STA_REC_UPDATE), true); +} + +static int +mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; + struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask; + enum nl80211_band band = chandef->chan->band; + struct sta_phy phy = {}; + int ret, nrates = 0; + +#define __sta_phy_bitrate_mask_check(_mcs, _gi, _he) \ + do { \ + u8 i, gi = mask->control[band]._gi; \ + gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \ + for (i = 0; i <= sta->bandwidth; i++) { \ + phy.sgi |= gi << (i << (_he)); \ + phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\ + } \ + for (i = 0; i < ARRAY_SIZE(mask->control[band]._mcs); i++) \ + nrates += hweight16(mask->control[band]._mcs[i]); \ + phy.mcs = ffs(mask->control[band]._mcs[0]) - 1; \ + } while (0) + + if (sta->he_cap.has_he) { + __sta_phy_bitrate_mask_check(he_mcs, he_gi, 1); + } else if (sta->vht_cap.vht_supported) { + __sta_phy_bitrate_mask_check(vht_mcs, gi, 0); + } else if (sta->ht_cap.ht_supported) { + __sta_phy_bitrate_mask_check(ht_mcs, gi, 0); + } else { + nrates = hweight32(mask->control[band].legacy); + phy.mcs = ffs(mask->control[band].legacy) - 1; + } +#undef __sta_phy_bitrate_mask_check + + /* fall back to auto rate control */ + if (mask->control[band].gi == NL80211_TXRATE_DEFAULT_GI && + mask->control[band].he_gi == GENMASK(7, 0) && + mask->control[band].he_ltf == GENMASK(7, 0) && + nrates != 1) + return 0; + + /* fixed single rate */ + if (nrates == 1) { + ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy, + RATE_PARAM_FIXED_MCS); + if (ret) + return ret; + } + + /* fixed GI */ + if (mask->control[band].gi != NL80211_TXRATE_DEFAULT_GI || + mask->control[band].he_gi != GENMASK(7, 0)) { + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + u32 addr; + + /* firmware updates only TXCMD but doesn't take WTBL into + * account, so driver should update here to reflect the + * actual txrate hardware sends out. + */ + addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7); + if (sta->he_cap.has_he) + mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi); + else + mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi); + + ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy, + RATE_PARAM_FIXED_GI); + if (ret) + return ret; + } + + /* fixed HE_LTF */ + if (mask->control[band].he_ltf != GENMASK(7, 0)) { + ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy, + RATE_PARAM_FIXED_HE_LTF); + if (ret) + return ret; + } + + return 0; +} + static void mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) @@ -2092,8 +2214,6 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, } if (sta->ht_cap.ht_supported) { - const u8 *mcs_mask = mask->control[band].ht_mcs; - ra->supp_mode |= MODE_HT; ra->af = sta->ht_cap.ampdu_factor; ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); @@ -2111,12 +2231,12 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)) cap |= STA_CAP_LDPC; - mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs, mcs_mask); + mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs, + mask->control[band].ht_mcs); ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; } if (sta->vht_cap.vht_supported) { - const u16 *mcs_mask = mask->control[band].vht_mcs; u8 af; ra->supp_mode |= MODE_VHT; @@ -2137,7 +2257,8 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)) cap |= STA_CAP_VHT_LDPC; - mt7915_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs, mcs_mask); + mt7915_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs, + mask->control[band].vht_mcs); } if (sta->he_cap.has_he) { @@ -2154,6 +2275,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct sk_buff *skb; + int ret; skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, MT7915_STA_UPDATE_MAX_SIZE); @@ -2167,10 +2289,21 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, if (sta->he_cap.has_he && changed) mt7915_mcu_sta_he_tlv(skb, sta, vif); + /* sta_rec_ra accommodates BW, NSS and only MCS range format + * i.e 0-{7,8,9} for VHT. + */ mt7915_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta); - return mt76_mcu_skb_send_msg(&dev->mt76, skb, - MCU_EXT_CMD(STA_REC_UPDATE), true); + ret = mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_EXT_CMD(STA_REC_UPDATE), true); + if (ret) + return ret; + + /* sta_rec_ra_fixed accommodates single rate, (HE)GI and HE_LTE, + * and updates as peer fixed rate parameters, which overrides + * sta_rec_ra and firmware rate control algorithm. + */ + return mt7915_mcu_add_rate_ctrl_fixed(dev, vif, sta); } static int diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index d66918d914da1..4821adb793d14 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -886,7 +886,7 @@ struct sta_rec_sec { struct sec_key key[2]; } __packed; -struct ra_phy { +struct sta_phy { u8 type; u8 flag; u8 stbc; @@ -930,7 +930,7 @@ struct sta_rec_ra { __le32 sta_cap; - struct ra_phy phy; + struct sta_phy phy; } __packed; struct sta_rec_ra_fixed { @@ -943,7 +943,7 @@ struct sta_rec_ra_fixed { u8 op_vht_rx_nss; u8 op_vht_rx_nss_type; - struct ra_phy phy; + struct sta_phy phy; u8 spe_en; u8 short_preamble; @@ -951,8 +951,14 @@ struct sta_rec_ra_fixed { u8 mmps_mode; } __packed; -#define RATE_PARAM_FIXED 3 -#define RATE_PARAM_AUTO 20 +enum { + RATE_PARAM_FIXED = 3, + RATE_PARAM_FIXED_HE_LTF = 7, + RATE_PARAM_FIXED_MCS, + RATE_PARAM_FIXED_GI = 11, + RATE_PARAM_AUTO = 20, +}; + #define RATE_CFG_MCS GENMASK(3, 0) #define RATE_CFG_NSS GENMASK(7, 4) #define RATE_CFG_GI GENMASK(11, 8) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 79a33afc5920a..7a328fc774a78 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -418,6 +418,10 @@ int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif); int mt7915_mcu_update_edca(struct mt7915_dev *dev, void *req); int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev, struct ieee80211_sta *sta, u32 rate); +int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + void *data, u32 field); int mt7915_mcu_set_eeprom(struct mt7915_dev *dev); int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset); int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, @@ -478,6 +482,7 @@ static inline void mt7915_irq_disable(struct mt7915_dev *dev, u32 mask) mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0); } +u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw); bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask); void mt7915_mac_reset_counters(struct mt7915_phy *phy); void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy); From 9a93364d6595358a11d07e7f4261ae263ae2a02a Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Thu, 21 Oct 2021 04:57:56 +0800 Subject: [PATCH 051/114] mt76: mt7915: rework debugfs fixed-rate knob Switch to use new mt7915_mcu_set_fixed_rate_ctrl(). Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt7915/debugfs.c | 68 ++++++++++++++++--- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 1 + .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 - 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index 4b7f38fcbe64e..4bd2a5c7f72d6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -481,19 +481,71 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) #ifdef CONFIG_MAC80211_DEBUGFS /** per-station debugfs **/ -static int mt7915_sta_fixed_rate_set(void *data, u64 rate) +static ssize_t mt7915_sta_fixed_rate_set(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { - struct ieee80211_sta *sta = data; + struct ieee80211_sta *sta = file->private_data; struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; - - /* usage: - * : see enum mt76_phy_type + struct mt7915_dev *dev = msta->vif->phy->dev; + struct ieee80211_vif *vif; + struct sta_phy phy = {}; + char buf[100]; + int ret; + u32 field; + u8 i, gi, he_ltf; + + if (count >= sizeof(buf)) + return -EINVAL; + + if (copy_from_user(buf, user_buf, count)) + return -EFAULT; + + if (count && buf[count - 1] == '\n') + buf[count - 1] = '\0'; + else + buf[count] = '\0'; + + /* mode - cck: 0, ofdm: 1, ht: 2, gf: 3, vht: 4, he_su: 8, he_er: 9 + * bw - bw20: 0, bw40: 1, bw80: 2, bw160: 3 + * nss - vht: 1~4, he: 1~4, others: ignore + * mcs - cck: 0~4, ofdm: 0~7, ht: 0~32, vht: 0~9, he_su: 0~11, he_er: 0~2 + * gi - (ht/vht) lgi: 0, sgi: 1; (he) 0.8us: 0, 1.6us: 1, 3.2us: 2 + * ldpc - off: 0, on: 1 + * stbc - off: 0, on: 1 + * he_ltf - 1xltf: 0, 2xltf: 1, 4xltf: 2 */ - return mt7915_mcu_set_fixed_rate(msta->vif->phy->dev, sta, rate); + if (sscanf(buf, "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu", + &phy.type, &phy.bw, &phy.nss, &phy.mcs, &gi, + &phy.ldpc, &phy.stbc, &he_ltf) != 8) { + dev_warn(dev->mt76.dev, + "format: Mode BW NSS MCS (HE)GI LDPC STBC HE_LTF\n"); + field = RATE_PARAM_AUTO; + goto out; + } + + phy.ldpc = (phy.bw || phy.ldpc) * GENMASK(2, 0); + for (i = 0; i <= phy.bw; i++) { + phy.sgi |= gi << (i << sta->he_cap.has_he); + phy.he_ltf |= he_ltf << (i << sta->he_cap.has_he); + } + field = RATE_PARAM_FIXED; + +out: + vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); + ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy, field); + if (ret) + return -EFAULT; + + return count; } -DEFINE_DEBUGFS_ATTRIBUTE(fops_fixed_rate, NULL, - mt7915_sta_fixed_rate_set, "%llx\n"); +static const struct file_operations fops_fixed_rate = { + .write = mt7915_sta_fixed_rate_set, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; static int mt7915_queues_show(struct seq_file *s, void *data) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index aa7964788a1c4..6c93ca24307fc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2073,6 +2073,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, switch (field) { case RATE_PARAM_AUTO: break; + case RATE_PARAM_FIXED: case RATE_PARAM_FIXED_MCS: case RATE_PARAM_FIXED_GI: case RATE_PARAM_FIXED_HE_LTF: diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 7a328fc774a78..d11b87d47ca1e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -416,8 +416,6 @@ int mt7915_set_channel(struct mt7915_phy *phy); int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd); int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif); int mt7915_mcu_update_edca(struct mt7915_dev *dev, void *req); -int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev, - struct ieee80211_sta *sta, u32 rate); int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, From 2be10a9744956673b0ddbf89976e32c75eeb2992 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 21 Oct 2021 01:09:32 +0200 Subject: [PATCH 052/114] mt76: mt7915: fix endiannes warning mt7915_mcu_beacon_check_caps Fix the following sparse warning mt7915_mcu_beacon_check_caps routine: warning: cast to restricted __le32 warning: cast from restricted __le16 Fixes: 22dffbddf0167 ("mt76: mt7915: introduce mt7915_mcu_beacon_check_caps()") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 6c93ca24307fc..79990a420fc6a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2561,9 +2561,8 @@ mt7915_mcu_beacon_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif, len); if (ie && ie[1] >= sizeof(*ht)) { ht = (void *)(ie + 2); - bc = le32_to_cpu(ht->cap_info); - - vc->ldpc |= !!(bc & IEEE80211_HT_CAP_LDPC_CODING); + vc->ldpc |= !!(le16_to_cpu(ht->cap_info) & + IEEE80211_HT_CAP_LDPC_CODING); } ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, mgmt->u.beacon.variable, From 9b121acd4e853c9cfb8b11c014435e6cbb3e25f6 Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Fri, 22 Oct 2021 01:38:39 +0800 Subject: [PATCH 053/114] mt76: mt7915: add WA firmware log support Support to turn on/off WA firmware log from debugfs. Signed-off-by: Shayne Chen Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt7915/debugfs.c | 50 +++++++++++++++---- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 12 ++++- .../net/wireless/mediatek/mt76/mt7915/mcu.h | 5 ++ .../wireless/mediatek/mt76/mt7915/mt7915.h | 5 +- 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index 4bd2a5c7f72d6..182cc6cf095e8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -82,7 +82,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL, mt7915_radar_trigger, "%lld\n"); static int -mt7915_fw_debug_set(void *data, u64 val) +mt7915_fw_debug_wm_set(void *data, u64 val) { struct mt7915_dev *dev = data; enum { @@ -92,29 +92,58 @@ mt7915_fw_debug_set(void *data, u64 val) DEBUG_SPL, DEBUG_RPT_RX, } debug; + int ret; - dev->fw_debug = !!val; + dev->fw_debug_wm = val ? MCU_FW_LOG_TO_HOST : 0; - mt7915_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0); + ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, dev->fw_debug_wm); + if (ret) + return ret; - for (debug = DEBUG_TXCMD; debug <= DEBUG_RPT_RX; debug++) - mt7915_mcu_fw_dbg_ctrl(dev, debug, dev->fw_debug); + for (debug = DEBUG_TXCMD; debug <= DEBUG_RPT_RX; debug++) { + ret = mt7915_mcu_fw_dbg_ctrl(dev, debug, !!dev->fw_debug_wm); + if (ret) + return ret; + } return 0; } static int -mt7915_fw_debug_get(void *data, u64 *val) +mt7915_fw_debug_wm_get(void *data, u64 *val) +{ + struct mt7915_dev *dev = data; + + *val = dev->fw_debug_wm; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wm, mt7915_fw_debug_wm_get, + mt7915_fw_debug_wm_set, "%lld\n"); + +static int +mt7915_fw_debug_wa_set(void *data, u64 val) +{ + struct mt7915_dev *dev = data; + + dev->fw_debug_wa = val ? MCU_FW_LOG_TO_HOST : 0; + + return mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw_debug_wa); +} + +static int +mt7915_fw_debug_wa_get(void *data, u64 *val) { struct mt7915_dev *dev = data; - *val = dev->fw_debug; + *val = dev->fw_debug_wa; return 0; } -DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7915_fw_debug_get, - mt7915_fw_debug_set, "%lld\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wa, mt7915_fw_debug_wa_get, + mt7915_fw_debug_wa_set, "%lld\n"); static void mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, @@ -460,7 +489,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) debugfs_create_file("xmit-queues", 0400, dir, phy, &mt7915_xmit_queues_fops); debugfs_create_file("tx_stats", 0400, dir, phy, &mt7915_tx_stats_fops); - debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug); + debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm); + debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa); debugfs_create_file("implicit_txbf", 0600, dir, dev, &fops_implicit_txbf); debugfs_create_file("txpower_sku", 0400, dir, phy, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 79990a420fc6a..13d5d7e544a33 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2980,7 +2980,7 @@ static int mt7915_load_firmware(struct mt7915_dev *dev) return 0; } -int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 ctrl) +int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl) { struct { u8 ctrl_val; @@ -2989,6 +2989,10 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 ctrl) .ctrl_val = ctrl }; + if (type == MCU_FW_LOG_WA) + return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(FW_LOG_2_HOST), + &data, sizeof(data), true); + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(FW_LOG_2_HOST), &data, sizeof(data), true); } @@ -3101,7 +3105,11 @@ int mt7915_mcu_init(struct mt7915_dev *dev) return ret; set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); - ret = mt7915_mcu_fw_log_2_host(dev, 0); + ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0); + if (ret) + return ret; + + ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, 0); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index 4821adb793d14..83dc39ac719d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -229,6 +229,11 @@ enum { MCU_S2D_H2CN }; +enum { + MCU_FW_LOG_WM, + MCU_FW_LOG_WA, + MCU_FW_LOG_TO_HOST, +}; #define __MCU_CMD_FIELD_ID GENMASK(7, 0) #define __MCU_CMD_FIELD_EXT_ID GENMASK(15, 8) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index d11b87d47ca1e..5fd74173c7eac 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -270,8 +270,9 @@ struct mt7915_dev { bool dbdc_support; bool flash_mode; - bool fw_debug; bool ibf; + u8 fw_debug_wm; + u8 fw_debug_wa; void *cal; @@ -449,7 +450,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct rate_info *rate); int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev, enum mt7915_rdd_cmd cmd, u8 index, u8 rx_sel, u8 val); -int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 ctrl); +int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb); void mt7915_mcu_exit(struct mt7915_dev *dev); From 90f5daea758abcc4722f4304ed5fccbbc80a59c2 Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Fri, 22 Oct 2021 01:38:40 +0800 Subject: [PATCH 054/114] mt76: mt7915: add debugfs knobs for MCU utilization Add debugfs knobs to read MCU utilization, which helps user know firmware status more easily to narrow down CPU bottleneck issues. Co-developed-by: Ryder Lee Signed-off-by: Ryder Lee Signed-off-by: Shayne Chen Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt7915/debugfs.c | 51 ++++++++++++++++++- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 5 +- .../net/wireless/mediatek/mt76/mt7915/mcu.h | 2 + .../net/wireless/mediatek/mt76/mt7915/mmio.c | 3 ++ .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 + .../net/wireless/mediatek/mt76/mt7915/regs.h | 17 +++++++ 6 files changed, 75 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index 182cc6cf095e8..a15aa256d0cfd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -106,6 +106,12 @@ mt7915_fw_debug_wm_set(void *data, u64 val) return ret; } + /* WM CPU info record control */ + mt76_clear(dev, MT_CPU_UTIL_CTRL, BIT(0)); + mt76_wr(dev, MT_DIC_CMD_REG_CMD, BIT(2) | BIT(13) | !dev->fw_debug_wm); + mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR, BIT(5)); + mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR, BIT(5)); + return 0; } @@ -126,10 +132,16 @@ static int mt7915_fw_debug_wa_set(void *data, u64 val) { struct mt7915_dev *dev = data; + int ret; dev->fw_debug_wa = val ? MCU_FW_LOG_TO_HOST : 0; - return mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw_debug_wa); + ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw_debug_wa); + if (ret) + return ret; + + return mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), MCU_WA_PARAM_PDMA_RX, + !!dev->fw_debug_wa, 0); } static int @@ -145,6 +157,39 @@ mt7915_fw_debug_wa_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wa, mt7915_fw_debug_wa_get, mt7915_fw_debug_wa_set, "%lld\n"); +static int +mt7915_fw_util_wm_show(struct seq_file *file, void *data) +{ + struct mt7915_dev *dev = file->private; + + if (dev->fw_debug_wm) { + seq_printf(file, "Busy: %u%% Peak busy: %u%%\n", + mt76_rr(dev, MT_CPU_UTIL_BUSY_PCT), + mt76_rr(dev, MT_CPU_UTIL_PEAK_BUSY_PCT)); + seq_printf(file, "Idle count: %u Peak idle count: %u\n", + mt76_rr(dev, MT_CPU_UTIL_IDLE_CNT), + mt76_rr(dev, MT_CPU_UTIL_PEAK_IDLE_CNT)); + } + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wm); + +static int +mt7915_fw_util_wa_show(struct seq_file *file, void *data) +{ + struct mt7915_dev *dev = file->private; + + if (dev->fw_debug_wa) + return mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(QUERY), + MCU_WA_PARAM_CPU_UTIL, 0, 0); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa); + static void mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, struct seq_file *file) @@ -491,6 +536,10 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) debugfs_create_file("tx_stats", 0400, dir, phy, &mt7915_tx_stats_fops); debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm); debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa); + debugfs_create_file("fw_util_wm", 0400, dir, dev, + &mt7915_fw_util_wm_fops); + debugfs_create_file("fw_util_wa", 0400, dir, dev, + &mt7915_fw_util_wa_fops); debugfs_create_file("implicit_txbf", 0600, dir, dev, &fops_implicit_txbf); debugfs_create_file("txpower_sku", 0400, dir, phy, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 13d5d7e544a33..899957b9d0f19 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -416,8 +416,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0); } -static int -mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3) +int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3) { struct { __le32 args[3]; @@ -429,7 +428,7 @@ mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3) }, }; - return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true); + return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), false); } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index 83dc39ac719d8..1f5a64ba9b59d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -309,6 +309,8 @@ enum { }; enum { + MCU_WA_PARAM_PDMA_RX = 0x04, + MCU_WA_PARAM_CPU_UTIL = 0x0b, MCU_WA_PARAM_RED = 0x0e, }; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 7bbb38e7116af..1f6ba306c8509 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -34,6 +34,9 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr) u32 mapped; u32 size; } fixed_map[] = { + { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ + { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure regs) */ + { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 5fd74173c7eac..e69b4c8974ee7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -450,6 +450,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct rate_info *rate); int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev, enum mt7915_rdd_cmd cmd, u8 index, u8 rx_sel, u8 val); +int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3); int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index a2e98788f421d..59693535b098c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -528,6 +528,18 @@ #define MT_HIF_REMAP_L2_BASE GENMASK(31, 12) #define MT_HIF_REMAP_BASE_L2 0x00000 +#define MT_DIC_CMD_REG_BASE 0x41f000 +#define MT_DIC_CMD_REG(ofs) (MT_DIC_CMD_REG_BASE + (ofs)) +#define MT_DIC_CMD_REG_CMD MT_DIC_CMD_REG(0x10) + +#define MT_CPU_UTIL_BASE 0x41f030 +#define MT_CPU_UTIL(ofs) (MT_CPU_UTIL_BASE + (ofs)) +#define MT_CPU_UTIL_BUSY_PCT MT_CPU_UTIL(0x00) +#define MT_CPU_UTIL_PEAK_BUSY_PCT MT_CPU_UTIL(0x04) +#define MT_CPU_UTIL_IDLE_CNT MT_CPU_UTIL(0x08) +#define MT_CPU_UTIL_PEAK_IDLE_CNT MT_CPU_UTIL(0x0c) +#define MT_CPU_UTIL_CTRL MT_CPU_UTIL(0x1c) + #define MT_SWDEF_BASE 0x41f200 #define MT_SWDEF(ofs) (MT_SWDEF_BASE + (ofs)) #define MT_SWDEF_MODE MT_SWDEF(0x3c) @@ -590,4 +602,9 @@ #define MT_WF_PHY_RXTD12_IRPI_SW_CLR_ONLY BIT(18) #define MT_WF_PHY_RXTD12_IRPI_SW_CLR BIT(29) +#define MT_MCU_WM_CIRQ_BASE 0x89010000 +#define MT_MCU_WM_CIRQ(ofs) (MT_MCU_WM_CIRQ_BASE + (ofs)) +#define MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR MT_MCU_WM_CIRQ(0x80) +#define MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR MT_MCU_WM_CIRQ(0xc0) + #endif From 565ddaaab9a15424a9037f929bce685aa34ffd0b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 21 Oct 2021 20:08:41 +0200 Subject: [PATCH 055/114] mt76: mt7921: disable 4addr capability 4addr is not supported by the driver/firmware yet Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index 87265045e2dd5..210998f086ab3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -62,7 +62,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) hw->vif_data_size = sizeof(struct mt7921_vif); wiphy->iface_combinations = if_comb; - wiphy->flags &= ~WIPHY_FLAG_IBSS_RSN; + wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP | + WIPHY_FLAG_4ADDR_STATION); wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN; From 2c4766fd5d3d390cbdd1f71eacee13a756d8ef0e Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Fri, 22 Oct 2021 23:41:40 +0200 Subject: [PATCH 056/114] mt76: Print error message when reading EEPROM from mtd failed When the EEPROM data is stored on a MTD partition print an error message when reading this MTD partition failed. This is currently happening often in OpenWrt because the initial data was written with using a flash driver which ignores the error detection data and now OpenWrt uses a driver which checks it. With this patch a better error message is shown: [ 8.986988] mt7915e 0000:01:00.0: WA Firmware Version: DEV_000000, Build Time: 20201105222323 [ 9.100508] mt7915e 0000:01:00.0: reading EEPROM from mtd factory failed: -117 [ 9.144289] mt7915e: probe of 0000:01:00.0 failed with error -22 mt7915 does not work without an EEPROM, MT7922 still works. Signed-off-by: Hauke Mehrtens Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/eeprom.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c index e65b2262e6927..2d58aa31db934 100644 --- a/drivers/net/wireless/mediatek/mt76/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -65,8 +65,11 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len) offset = be32_to_cpup(list); ret = mtd_read(mtd, offset, len, &retlen, eep); put_mtd_device(mtd); - if (ret) + if (ret) { + dev_err(dev->dev, "reading EEPROM from mtd %s failed: %i\n", + part, ret); goto out_put_node; + } if (retlen < len) { ret = -EINVAL; From f31a577ae7365bcdaaedbb2064be78e2c4f2946f Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Thu, 21 Oct 2021 16:41:49 +0800 Subject: [PATCH 057/114] mt76: Make use of the helper macro kthread_run() Repalce kthread_create/wake_up_process() with kthread_run() to simplify the code. Signed-off-by: Cai Huoqing Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/util.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/util.h b/drivers/net/wireless/mediatek/mt76/util.h index 1c363ea9ab9cd..49c52d781f40f 100644 --- a/drivers/net/wireless/mediatek/mt76/util.h +++ b/drivers/net/wireless/mediatek/mt76/util.h @@ -70,17 +70,15 @@ mt76_worker_setup(struct ieee80211_hw *hw, struct mt76_worker *w, if (fn) w->fn = fn; - w->task = kthread_create(__mt76_worker_fn, w, "mt76-%s %s", - name, dev_name); + w->task = kthread_run(__mt76_worker_fn, w, + "mt76-%s %s", name, dev_name); - ret = PTR_ERR_OR_ZERO(w->task); - if (ret) { + if (IS_ERR(w->task)) { + ret = PTR_ERR(w->task); w->task = NULL; return ret; } - wake_up_process(w->task); - return 0; } From 52a99a13cb880845cd77f1da7136d689347489ef Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 23 Oct 2021 13:22:53 +0200 Subject: [PATCH 058/114] mt76: connac: fix unresolved symbols when CONFIG_PM is unset mt76_connac_mcu_reg_* functions are always needed by connac based drivers Fixes: 87f9bf24ea84 ("mt76: connac: move mcu reg access utility routines in mt76_connac_lib module") Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index 32e25180fc1e2..26b4b875dcc02 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -2477,6 +2477,7 @@ void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac, mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan); } EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter); +#endif /* CONFIG_PM */ u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset) { @@ -2505,7 +2506,6 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val) mt76_mcu_send_msg(dev, MCU_CMD_REG_WRITE, &req, sizeof(req), false); } EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr); -#endif /* CONFIG_PM */ MODULE_AUTHOR("Lorenzo Bianconi "); MODULE_LICENSE("Dual BSD/GPL"); From 734223d78428de3c7c7d7bc04daf258085780d90 Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Wed, 20 Oct 2021 11:59:06 +0300 Subject: [PATCH 059/114] ath11k: change return buffer manager for QCA6390 QCA6390 firmware uses HAL_RX_BUF_RBM_SW1_BM, not HAL_RX_BUF_RBM_SW3_BM. This is needed to fix a case where an A-MSDU has an unexpected LLC/SNAP header in the first subframe (CVE-2020-24588). Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Baochen Qiang Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20210914163726.38604-2-jouni@codeaurora.org --- drivers/net/wireless/ath/ath11k/core.c | 5 ++++ drivers/net/wireless/ath/ath11k/dp.c | 4 +++- drivers/net/wireless/ath/ath11k/dp_rx.c | 29 +++++++++++++++--------- drivers/net/wireless/ath/ath11k/hal_rx.c | 6 +++-- drivers/net/wireless/ath/ath11k/hw.c | 11 ++++++++- drivers/net/wireless/ath/ath11k/hw.h | 9 ++++++++ 6 files changed, 49 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index b0d6922802edf..b5a2af3ffc3e1 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, .max_tx_ring = DP_TCL_NUM_RING_MAX, + .hal_params = &ath11k_hw_hal_params_ipq8074, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -129,6 +130,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, .max_tx_ring = DP_TCL_NUM_RING_MAX, + .hal_params = &ath11k_hw_hal_params_ipq8074, }, { .name = "qca6390 hw2.0", @@ -176,6 +178,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .fix_l1ss = true, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .hal_params = &ath11k_hw_hal_params_qca6390, }, { .name = "qcn9074 hw1.0", @@ -223,6 +226,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), .fix_l1ss = true, .max_tx_ring = DP_TCL_NUM_RING_MAX, + .hal_params = &ath11k_hw_hal_params_ipq8074, }, { .name = "wcn6855 hw2.0", @@ -270,6 +274,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), .fix_l1ss = false, .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .hal_params = &ath11k_hw_hal_params_qca6390, }, }; diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index c52d49cb8a048..8baaeeb8cf821 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -739,6 +739,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, int budget) { struct napi_struct *napi = &irq_grp->napi; + const struct ath11k_hw_hal_params *hal_params; int grp_id = irq_grp->grp_id; int work_done = 0; int i = 0, j; @@ -821,8 +822,9 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, struct ath11k_pdev_dp *dp = &ar->dp; struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; + hal_params = ab->hw_params.hal_params; ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); } } } diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 1232bbea4b65e..c5320847b80a7 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -499,7 +499,7 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar, rx_ring->bufs_max = num_entries; ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries, - HAL_RX_BUF_RBM_SW3_BM); + ar->ab->hw_params.hal_params->rx_buf_rbm); return 0; } @@ -2756,7 +2756,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); } ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list, @@ -2949,6 +2949,7 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, int *budget, struct sk_buff_head *skb_list) { struct ath11k *ar; + const struct ath11k_hw_hal_params *hal_params; struct ath11k_pdev_dp *dp; struct dp_rxdma_ring *rx_ring; struct hal_srng *srng; @@ -3019,8 +3020,9 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, &buf_id); if (!skb) { + hal_params = ab->hw_params.hal_params; ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); num_buffs_reaped++; break; } @@ -3030,7 +3032,8 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr, - cookie, HAL_RX_BUF_RBM_SW3_BM); + cookie, + ab->hw_params.hal_params->rx_buf_rbm); ath11k_hal_srng_src_get_next_entry(ab, srng); num_buffs_reaped++; } @@ -3419,7 +3422,8 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) | FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id); - ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, HAL_RX_BUF_RBM_SW3_BM); + ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, + ab->hw_params.hal_params->rx_buf_rbm); /* Fill mpdu details into reo entrace ring */ srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id]; @@ -3796,7 +3800,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies, &rbm); if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST && - rbm != HAL_RX_BUF_RBM_SW3_BM) { + rbm != ab->hw_params.hal_params->rx_buf_rbm) { ab->soc_stats.invalid_rbm++; ath11k_warn(ab, "invalid return buffer manager %d\n", rbm); ath11k_dp_rx_link_desc_return(ab, desc, @@ -3852,7 +3856,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi, rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i], - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); } return tot_n_bufs_reaped; @@ -4148,7 +4152,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab, rx_ring = &ar->dp.rx_refill_buf_ring; ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); } rcu_read_lock(); @@ -4257,7 +4261,7 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget) if (num_buf_freed) ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed, - HAL_RX_BUF_RBM_SW3_BM); + ab->hw_params.hal_params->rx_buf_rbm); return budget - quota; } @@ -4976,6 +4980,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, { struct ath11k_pdev_dp *dp = &ar->dp; struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; + const struct ath11k_hw_hal_params *hal_params; void *ring_entry; void *mon_dst_srng; u32 ppdu_id; @@ -5039,16 +5044,18 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id, if (rx_bufs_used) { rx_mon_stats->dest_ppdu_done++; + hal_params = ar->ab->hw_params.hal_params; + if (ar->ab->hw_params.rxdma1_enable) ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, &dp->rxdma_mon_buf_ring, rx_bufs_used, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); else ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, &dp->rx_refill_buf_ring, rx_bufs_used, - HAL_RX_BUF_RBM_SW3_BM); + hal_params->rx_buf_rbm); } } diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index 325055ca41abd..329c404cfa80d 100644 --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -356,6 +356,7 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, struct hal_wbm_release_ring *wbm_desc = desc; enum hal_wbm_rel_desc_type type; enum hal_wbm_rel_src_module rel_src; + enum hal_rx_buf_return_buf_manager ret_buf_mgr; type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE, wbm_desc->info0); @@ -371,8 +372,9 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, rel_src != HAL_WBM_REL_SRC_MODULE_REO) return -EINVAL; - if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, - wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) { + ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, + wbm_desc->buf_addr_info.info1); + if (ret_buf_mgr != ab->hw_params.hal_params->rx_buf_rbm) { ab->soc_stats.invalid_rbm++; return -EINVAL; } diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index 7a343db1dde88..da35fcf5bc560 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -7,10 +7,11 @@ #include #include -#include "hw.h" #include "core.h" #include "ce.h" #include "hif.h" +#include "hal.h" +#include "hw.h" /* Map from pdev index to hw mac index */ static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx) @@ -2124,3 +2125,11 @@ const struct ath11k_hw_regs wcn6855_regs = { .pcie_qserdes_sysclk_en_sel = 0x01e0c0ac, .pcie_pcs_osc_dtct_config_base = 0x01e0c628, }; + +const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM, +}; + +const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = { + .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, +}; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 8f92210edc8ff..19223d36846e8 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -6,6 +6,7 @@ #ifndef ATH11K_HW_H #define ATH11K_HW_H +#include "hal.h" #include "wmi.h" /* Target configuration defines */ @@ -119,6 +120,10 @@ struct ath11k_hw_ring_mask { u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX]; }; +struct ath11k_hw_hal_params { + enum hal_rx_buf_return_buf_manager rx_buf_rbm; +}; + struct ath11k_hw_params { const char *name; u16 hw_rev; @@ -170,6 +175,7 @@ struct ath11k_hw_params { u32 hal_desc_sz; bool fix_l1ss; u8 max_tx_ring; + const struct ath11k_hw_hal_params *hal_params; }; struct ath11k_hw_ops { @@ -223,6 +229,9 @@ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; +extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074; +extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390; + static inline int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw, int pdev_idx) From 937e79c67740d1d84736730d679f3cb2552f990e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 20 Oct 2021 11:59:07 +0300 Subject: [PATCH 060/114] ath10k: fix invalid dma_addr_t token assignment Using a kernel pointer in place of a dma_addr_t token can lead to undefined behavior if that makes it into cache management functions. The compiler caught one such attempt in a cast: drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_add_interface': drivers/net/wireless/ath/ath10k/mac.c:5586:47: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast] 5586 | arvif->beacon_paddr = (dma_addr_t)arvif->beacon_buf; | ^ Looking through how this gets used down the way, I'm fairly sure that beacon_paddr is never accessed again for ATH10K_DEV_TYPE_HL devices, and if it was accessed, that would be a bug. Change the assignment to use a known-invalid address token instead, which avoids the warning and makes it easier to catch bugs if it does end up getting used. Fixes: e263bdab9c0e ("ath10k: high latency fixes for beacon buffer") Signed-off-by: Arnd Bergmann Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211014075153.3655910-1-arnd@kernel.org --- drivers/net/wireless/ath/ath10k/mac.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 5ec19d91cf372..1f73fbfee0c06 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -5583,7 +5583,15 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) { arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN, GFP_KERNEL); - arvif->beacon_paddr = (dma_addr_t)arvif->beacon_buf; + + /* Using a kernel pointer in place of a dma_addr_t + * token can lead to undefined behavior if that + * makes it into cache management functions. Use a + * known-invalid address token instead, which + * avoids the warning and makes it easier to catch + * bugs if it does end up getting used. + */ + arvif->beacon_paddr = DMA_MAPPING_ERROR; } else { arvif->beacon_buf = dma_alloc_coherent(ar->dev, From 6f8c8bf4c7c9be1c42088689fd4370e06b46608a Mon Sep 17 00:00:00 2001 From: Abinaya Kalaiselvan Date: Wed, 20 Oct 2021 11:59:07 +0300 Subject: [PATCH 061/114] ath10k: fix module load regression with iram-recovery feature Commit 9af7c32ceca8 ("ath10k: add target IRAM recovery feature support") introduced a new firmware feature flag ATH10K_FW_FEATURE_IRAM_RECOVERY. But this caused ath10k_pci module load to fail if ATH10K_FW_CRASH_DUMP_RAM_DATA bit was not enabled in the ath10k coredump_mask module parameter: [ 2209.328190] ath10k_pci 0000:02:00.0: qca9984/qca9994 hw1.0 target 0x01000000 chip_id 0x00000000 sub 168c:cafe [ 2209.434414] ath10k_pci 0000:02:00.0: kconfig debug 1 debugfs 1 tracing 1 dfs 1 testmode 1 [ 2209.547191] ath10k_pci 0000:02:00.0: firmware ver 10.4-3.9.0.2-00099 api 5 features no-p2p,mfp,peer-flow-ctrl,btcoex-param,allows-mesh-bcast,no-ps,peer-fixed-rate,iram-recovery crc32 cbade90a [ 2210.896485] ath10k_pci 0000:02:00.0: board_file api 1 bmi_id 0:1 crc32 a040efc2 [ 2213.603339] ath10k_pci 0000:02:00.0: failed to copy target iram contents: -12 [ 2213.839027] ath10k_pci 0000:02:00.0: could not init core (-12) [ 2213.933910] ath10k_pci 0000:02:00.0: could not probe fw (-12) And by default coredump_mask does not have ATH10K_FW_CRASH_DUMP_RAM_DATA enabled so anyone using a firmware with iram-recovery feature would fail. To my knowledge only QCA9984 firmwares starting from release 10.4-3.9.0.2-00099 enabled the feature. The reason for regression was that ath10k_core_copy_target_iram() used ath10k_coredump_get_mem_layout() to get the memory layout, but when ATH10K_FW_CRASH_DUMP_RAM_DATA was disabled it would get just NULL and bail out with an error. While looking at all this I noticed another bug: if CONFIG_DEV_COREDUMP is disabled but the firmware has iram-recovery enabled the module load fails with similar error messages. I fixed that by returning 0 from ath10k_core_copy_target_iram() when _ath10k_coredump_get_mem_layout() returns NULL. Tested-on: QCA9984 hw2.0 PCI 10.4-3.9.0.2-00139 Fixes: 9af7c32ceca8 ("ath10k: add target IRAM recovery feature support") Signed-off-by: Abinaya Kalaiselvan Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211020075054.23061-1-kvalo@codeaurora.org --- drivers/net/wireless/ath/ath10k/core.c | 11 +++++++++-- drivers/net/wireless/ath/ath10k/coredump.c | 11 ++++++++--- drivers/net/wireless/ath/ath10k/coredump.h | 7 +++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 112e04bb0e57b..5935e0973d146 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -2690,9 +2690,16 @@ static int ath10k_core_copy_target_iram(struct ath10k *ar) int i, ret; u32 len, remaining_len; - hw_mem = ath10k_coredump_get_mem_layout(ar); + /* copy target iram feature must work also when + * ATH10K_FW_CRASH_DUMP_RAM_DATA is disabled, so + * _ath10k_coredump_get_mem_layout() to accomplist that + */ + hw_mem = _ath10k_coredump_get_mem_layout(ar); if (!hw_mem) - return -ENOMEM; + /* if CONFIG_DEV_COREDUMP is disabled we get NULL, then + * just silently disable the feature by doing nothing + */ + return 0; for (i = 0; i < hw_mem->region_table.size; i++) { tmp = &hw_mem->region_table.regions[i]; diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c index 7eb72290a925c..55e7e11d06d94 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.c +++ b/drivers/net/wireless/ath/ath10k/coredump.c @@ -1447,11 +1447,17 @@ static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar) const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar) { - int i; - if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) return NULL; + return _ath10k_coredump_get_mem_layout(ar); +} +EXPORT_SYMBOL(ath10k_coredump_get_mem_layout); + +const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar) +{ + int i; + if (WARN_ON(ar->target_version == 0)) return NULL; @@ -1464,7 +1470,6 @@ const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k return NULL; } -EXPORT_SYMBOL(ath10k_coredump_get_mem_layout); struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) { diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h index 42404e246e0e9..240d705150888 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.h +++ b/drivers/net/wireless/ath/ath10k/coredump.h @@ -176,6 +176,7 @@ int ath10k_coredump_register(struct ath10k *ar); void ath10k_coredump_unregister(struct ath10k *ar); void ath10k_coredump_destroy(struct ath10k *ar); +const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar); const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar); #else /* CONFIG_DEV_COREDUMP */ @@ -214,6 +215,12 @@ ath10k_coredump_get_mem_layout(struct ath10k *ar) return NULL; } +static inline const struct ath10k_hw_mem_layout * +_ath10k_coredump_get_mem_layout(struct ath10k *ar) +{ + return NULL; +} + #endif /* CONFIG_DEV_COREDUMP */ #endif /* _COREDUMP_H_ */ From d3fd2c95c1c13ec217d43ebef3c61cfa00a6cd37 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 25 Oct 2021 16:12:18 +0300 Subject: [PATCH 062/114] wcn36xx: Fix (QoS) null data frame bitrate/modulation We observe unexpected connection drops with some APs due to non-acked mac80211 generated null data frames (keep-alive). After debugging and capture, we noticed that null frames are submitted at standard data bitrate and that the given APs are in trouble with that. After setting the null frame bitrate to control bitrate, all null frames are acked as expected and connection is maintained. Not sure if it's a requirement of the specification, but it seems the right thing to do anyway, null frames are mostly used for control purpose (power-saving, keep-alive...), and submitting them with a slower/simpler bitrate/modulation is more robust. Cc: stable@vger.kernel.org Fixes: 512b191d9652 ("wcn36xx: Fix TX data path") Signed-off-by: Loic Poulain Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1634560399-15290-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/txrx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index cab196bb38cd4..e2d09d5291460 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -429,6 +429,7 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, if (ieee80211_is_any_nullfunc(hdr->frame_control)) { /* Don't use a regular queue for null packet (no ampdu) */ bd->queue_id = WCN36XX_TX_U_WQ_ID; + bd->bd_rate = WCN36XX_BD_RATE_CTRL; } if (bcast) { From a9e79b116cc4d0057e912be8f40b2c2e5bdc7c43 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 25 Oct 2021 16:12:18 +0300 Subject: [PATCH 063/114] wcn36xx: Fix tx_status mechanism This change fix the TX ack mechanism in various ways: - For NO_ACK tagged packets, we don't need to wait for TX_ACK indication and so are not subject to the single packet ack limitation. So we don't have to stop the tx queue, and can call the tx status callback as soon as DMA transfer has completed. - Fix skb ownership/reference. Only start status indication timeout once the DMA transfer has been completed. This avoids the skb to be both referenced in the DMA tx ring and by the tx_ack_skb pointer, preventing any use-after-free or double-free. - This adds a sanity (paranoia?) check on the skb tx ack pointer. - Resume TX queue if TX status tagged packet TX fails. Cc: stable@vger.kernel.org Fixes: fdf21cc37149 ("wcn36xx: Add TX ack support") Signed-off-by: Loic Poulain Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1634567281-28997-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/dxe.c | 37 ++++++++++--------------- drivers/net/wireless/ath/wcn36xx/txrx.c | 31 ++++----------------- 2 files changed, 21 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index 8e1dbfda65386..0e0bbcd11300b 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -403,8 +403,21 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, ctl->skb->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(ctl->skb); - if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { - /* Keep frame until TX status comes */ + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if (info->flags & IEEE80211_TX_CTL_NO_ACK) { + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + ieee80211_tx_status_irqsafe(wcn->hw, ctl->skb); + } else { + /* Wait for the TX ack indication or timeout... */ + spin_lock(&wcn->dxe_lock); + if (WARN_ON(wcn->tx_ack_skb)) + ieee80211_free_txskb(wcn->hw, wcn->tx_ack_skb); + wcn->tx_ack_skb = ctl->skb; /* Tracking ref */ + mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10); + spin_unlock(&wcn->dxe_lock); + } + /* do not free, ownership transferred to mac80211 status cb */ + } else { ieee80211_free_txskb(wcn->hw, ctl->skb); } @@ -426,7 +439,6 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) { struct wcn36xx *wcn = (struct wcn36xx *)dev; int int_src, int_reason; - bool transmitted = false; wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src); @@ -466,7 +478,6 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK | WCN36XX_CH_STAT_INT_ED_MASK)) { reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); - transmitted = true; } } @@ -479,7 +490,6 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) WCN36XX_DXE_0_INT_CLR, WCN36XX_INT_MASK_CHAN_TX_L); - if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) { wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ERR_CLR, @@ -507,25 +517,8 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK | WCN36XX_CH_STAT_INT_ED_MASK)) { reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); - transmitted = true; - } - } - - spin_lock(&wcn->dxe_lock); - if (wcn->tx_ack_skb && transmitted) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(wcn->tx_ack_skb); - - /* TX complete, no need to wait for 802.11 ack indication */ - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS && - info->flags & IEEE80211_TX_CTL_NO_ACK) { - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; - del_timer(&wcn->tx_ack_timer); - ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb); - wcn->tx_ack_skb = NULL; - ieee80211_wake_queues(wcn->hw); } } - spin_unlock(&wcn->dxe_lock); return IRQ_HANDLED; } diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index e2d09d5291460..eaf2410e39647 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -503,10 +503,11 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct wcn36xx_vif *vif_priv = NULL; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned long flags; bool is_low = ieee80211_is_data(hdr->frame_control); bool bcast = is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1); + bool ack_ind = (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && + !(info->flags & IEEE80211_TX_CTL_NO_ACK); struct wcn36xx_tx_bd bd; int ret; @@ -522,30 +523,16 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, bd.dpu_rf = WCN36XX_BMU_WQ_TX; - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if (unlikely(ack_ind)) { wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); - spin_lock_irqsave(&wcn->dxe_lock, flags); - if (wcn->tx_ack_skb) { - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - wcn36xx_warn("tx_ack_skb already set\n"); - return -EINVAL; - } - - wcn->tx_ack_skb = skb; - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - /* Only one at a time is supported by fw. Stop the TX queues * until the ack status gets back. */ ieee80211_stop_queues(wcn->hw); - /* TX watchdog if no TX irq or ack indication received */ - mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10); - /* Request ack indication from the firmware */ - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - bd.tx_comp = 1; + bd.tx_comp = 1; } /* Data frames served first*/ @@ -559,14 +546,8 @@ int wcn36xx_start_tx(struct wcn36xx *wcn, bd.tx_bd_sign = 0xbdbdbdbd; ret = wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low); - if (ret && (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { - /* If the skb has not been transmitted, - * don't keep a reference to it. - */ - spin_lock_irqsave(&wcn->dxe_lock, flags); - wcn->tx_ack_skb = NULL; - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - + if (unlikely(ret && ack_ind)) { + /* If the skb has not been transmitted, resume TX queue */ ieee80211_wake_queues(wcn->hw); } From 1aa3367ca78ce6c1b06726587da1a6d8aa387797 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 19 Oct 2021 14:48:41 +0200 Subject: [PATCH 064/114] wlcore: spi: Use dev_err_probe() Use the existing dev_err_probe() helper instead of open-coding the same operation. Signed-off-by: Geert Uytterhoeven Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/465e76901b801ac0755088998249928fd546c08a.1634647460.git.geert+renesas@glider.be --- drivers/net/wireless/ti/wlcore/spi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c index f26fc150ecd01..354a7e1c3315c 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c @@ -488,12 +488,9 @@ static int wl1271_probe(struct spi_device *spi) spi->bits_per_word = 32; glue->reg = devm_regulator_get(&spi->dev, "vwlan"); - if (PTR_ERR(glue->reg) == -EPROBE_DEFER) - return -EPROBE_DEFER; - if (IS_ERR(glue->reg)) { - dev_err(glue->dev, "can't get regulator\n"); - return PTR_ERR(glue->reg); - } + if (IS_ERR(glue->reg)) + return dev_err_probe(glue->dev, PTR_ERR(glue->reg), + "can't get regulator\n"); ret = wlcore_probe_of(spi, glue, pdev_data); if (ret) { From d549107305b4634c81223a853701c06bcf657bc3 Mon Sep 17 00:00:00 2001 From: Wang Hai Date: Wed, 20 Oct 2021 20:03:44 +0800 Subject: [PATCH 065/114] libertas_tf: Fix possible memory leak in probe and disconnect I got memory leak as follows when doing fault injection test: unreferenced object 0xffff88810a2ddc00 (size 512): comm "kworker/6:1", pid 176, jiffies 4295009893 (age 757.220s) hex dump (first 32 bytes): 00 50 05 18 81 88 ff ff 00 00 00 00 00 00 00 00 .P.............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] slab_post_alloc_hook+0x9c/0x490 [] kmem_cache_alloc_trace+0x1f7/0x470 [] if_usb_probe+0x60/0x37c [libertas_tf_usb] [] usb_probe_interface+0x1aa/0x3c0 [usbcore] [] really_probe+0x190/0x480 [] __driver_probe_device+0xf9/0x180 [] driver_probe_device+0x53/0x130 [] __device_attach_driver+0x105/0x130 [] bus_for_each_drv+0x129/0x190 [] __device_attach+0x1c9/0x270 [] device_initial_probe+0x20/0x30 [] bus_probe_device+0x142/0x160 [] device_add+0x829/0x1300 [] usb_set_configuration+0xb01/0xcc0 [usbcore] [] usb_generic_driver_probe+0x6e/0x90 [usbcore] [] usb_probe_device+0x6f/0x130 [usbcore] cardp is missing being freed in the error handling path of the probe and the path of the disconnect, which will cause memory leak. This patch adds the missing kfree(). Fixes: c305a19a0d0a ("libertas_tf: usb specific functions") Reported-by: Hulk Robot Signed-off-by: Wang Hai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211020120345.2016045-2-wanghai38@huawei.com --- drivers/net/wireless/marvell/libertas_tf/if_usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c index fe0a69e804d8c..75b5319d033f3 100644 --- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c +++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c @@ -230,6 +230,7 @@ static int if_usb_probe(struct usb_interface *intf, dealloc: if_usb_free(cardp); + kfree(cardp); error: lbtf_deb_leave(LBTF_DEB_MAIN); return -ENOMEM; @@ -254,6 +255,7 @@ static void if_usb_disconnect(struct usb_interface *intf) /* Unlink and free urb */ if_usb_free(cardp); + kfree(cardp); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); From 9692151e2fe7a326bafe99836fd1f20a2cc3a049 Mon Sep 17 00:00:00 2001 From: Wang Hai Date: Wed, 20 Oct 2021 20:03:45 +0800 Subject: [PATCH 066/114] libertas: Fix possible memory leak in probe and disconnect I got memory leak as follows when doing fault injection test: unreferenced object 0xffff88812c7d7400 (size 512): comm "kworker/6:1", pid 176, jiffies 4295003332 (age 822.830s) hex dump (first 32 bytes): 00 68 1e 04 81 88 ff ff 01 00 00 00 00 00 00 00 .h.............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] slab_post_alloc_hook+0x9c/0x490 [] kmem_cache_alloc_trace+0x1f7/0x470 [] if_usb_probe+0x63/0x446 [usb8xxx] [] usb_probe_interface+0x1aa/0x3c0 [usbcore] [] really_probe+0x190/0x480 [] __driver_probe_device+0xf9/0x180 [] driver_probe_device+0x53/0x130 [] __device_attach_driver+0x105/0x130 [] bus_for_each_drv+0x129/0x190 [] __device_attach+0x1c9/0x270 [] device_initial_probe+0x20/0x30 [] bus_probe_device+0x142/0x160 [] device_add+0x829/0x1300 [] usb_set_configuration+0xb01/0xcc0 [usbcore] [] usb_generic_driver_probe+0x6e/0x90 [usbcore] [] usb_probe_device+0x6f/0x130 [usbcore] cardp is missing being freed in the error handling path of the probe and the path of the disconnect, which will cause memory leak. This patch adds the missing kfree(). Fixes: 876c9d3aeb98 ("[PATCH] Marvell Libertas 8388 802.11b/g USB driver") Reported-by: Hulk Robot Signed-off-by: Wang Hai Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211020120345.2016045-3-wanghai38@huawei.com --- drivers/net/wireless/marvell/libertas/if_usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c index 20436a289d5cd..5d6dc1dd050d4 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -292,6 +292,7 @@ static int if_usb_probe(struct usb_interface *intf, if_usb_reset_device(cardp); dealloc: if_usb_free(cardp); + kfree(cardp); error: return r; @@ -316,6 +317,7 @@ static void if_usb_disconnect(struct usb_interface *intf) /* Unlink and free urb */ if_usb_free(cardp); + kfree(cardp); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); From dea857700a75943017488b1d47f6687cfc037642 Mon Sep 17 00:00:00 2001 From: Lv Ruyi Date: Thu, 21 Oct 2021 04:20:35 +0000 Subject: [PATCH 067/114] rtw89: fix error function parameter This patch fixes the following Coccinelle warning: drivers/net/wireless/realtek/rtw89/rtw8852a.c:753: WARNING possible condition with no effect (if == else) Reported-by: Zeal Robot Signed-off-by: Lv Ruyi Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211021042035.1042463-1-lv.ruyi@zte.com.cn --- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index b1b87f0aadbb0..5c6ffca3a324e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -757,7 +757,7 @@ static void rtw8852a_ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch, else rtw89_phy_write32_idx(rtwdev, R_P1_MODE, B_P1_MODE_SEL, - 1, phy_idx); + 0, phy_idx); /* SCO compensate FC setting */ sco_comp = rtw8852a_sco_mapping(central_ch); rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_FC0_BW_INV, From 090f8a2f7b38f3a1dcf202437e5307761e8e4625 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Thu, 21 Oct 2021 13:44:08 +0800 Subject: [PATCH 068/114] rtw89: remove duplicate register definitions Remove duplicate register definitions. Signed-off-by: Kevin Lo Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/YXD+KL+xzFsnGShb@ns.kevlo.org --- drivers/net/wireless/realtek/rtw89/pci.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.h b/drivers/net/wireless/realtek/rtw89/pci.h index 34333c441aea0..20e6767ea5c4b 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.h +++ b/drivers/net/wireless/realtek/rtw89/pci.h @@ -276,11 +276,6 @@ #define B_AX_CH10_BUSY BIT(0) /* Configure */ -#define R_AX_PCIE_INIT_CFG1 0x1000 -#define B_AX_PCIE_RXRST_KEEP_REG BIT(23) -#define B_AX_PCIE_TXRST_KEEP_REG BIT(22) -#define B_AX_DIS_RXDMA_PRE BIT(2) - #define R_AX_PCIE_INIT_CFG2 0x1004 #define B_AX_WD_ITVL_IDLE GENMASK(27, 24) #define B_AX_WD_ITVL_ACT GENMASK(19, 16) From c6477cb237048725922f6a786f68b5232abb418f Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Thu, 21 Oct 2021 14:32:27 +0800 Subject: [PATCH 069/114] rtw89: fix return value in hfc_pub_cfg_chk It seems to me when pub_cfg->grp0 + pub_cfg->grp1 != pub_cfg->pub_max is true, it should return -EFAULT rather than 0. Otherwise, the function doesn't need to exist. Signed-off-by: Kevin Lo Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/YXEJey8lKksAZif4@ns.kevlo.org --- drivers/net/wireless/realtek/rtw89/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 69384c43c0461..afcd07ab1de79 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -560,7 +560,7 @@ static int hfc_pub_cfg_chk(struct rtw89_dev *rtwdev) const struct rtw89_hfc_pub_cfg *pub_cfg = ¶m->pub_cfg; if (pub_cfg->grp0 + pub_cfg->grp1 != pub_cfg->pub_max) - return 0; + return -EFAULT; return 0; } From 5d44f0672319c19a41ff0e0e4f0d64164cf9752b Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Fri, 22 Oct 2021 14:12:42 +0800 Subject: [PATCH 070/114] rtw89: Fix variable dereferenced before check 'sta' The pointer rtwsta is dereferencing pointer sta before sta is being null checked. Fix this by assigning sta->drv_priv to rtwsta only if sta is not NULL, otherwise just NULL. Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver") Reported-by: Colin Ian King Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211022061242.8383-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 06fb6e5b1b37a..d02ec5a735cb1 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1412,7 +1412,7 @@ static void rtw89_core_ba_work(struct work_struct *work) list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->ba_list, list) { struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; u8 tid = txq->tid; if (!sta) { @@ -1462,7 +1462,7 @@ static void rtw89_core_txq_check_agg(struct rtw89_dev *rtwdev, struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_txq *txq = rtw89_txq_to_txq(rtwtxq); struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; if (unlikely(skb_get_queue_mapping(skb) == IEEE80211_AC_VO)) return; @@ -1534,7 +1534,7 @@ static bool rtw89_core_txq_agg_wait(struct rtw89_dev *rtwdev, { struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv; struct ieee80211_sta *sta = txq->sta; - struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_sta *rtwsta = sta ? (struct rtw89_sta *)sta->drv_priv : NULL; if (!sta || rtwsta->max_agg_wait <= 0) return false; From d3c6daa174ff53b61215d8e67c85d466adf57cad Mon Sep 17 00:00:00 2001 From: Ye Guojin Date: Fri, 22 Oct 2021 09:04:38 +0000 Subject: [PATCH 071/114] libertas: replace snprintf in show functions with sysfs_emit coccicheck complains about the use of snprintf() in sysfs show functions: WARNING use scnprintf or sprintf Use sysfs_emit instead of scnprintf or sprintf makes more sense. Reported-by: Zeal Robot Signed-off-by: Ye Guojin Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211022090438.1065286-1-ye.guojin@zte.com.cn --- drivers/net/wireless/marvell/libertas/mesh.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/marvell/libertas/mesh.c b/drivers/net/wireless/marvell/libertas/mesh.c index 6cbba84989b8a..a58c1e141f2ca 100644 --- a/drivers/net/wireless/marvell/libertas/mesh.c +++ b/drivers/net/wireless/marvell/libertas/mesh.c @@ -169,7 +169,7 @@ static ssize_t anycast_mask_show(struct device *dev, if (ret) return ret; - return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0])); + return sysfs_emit(buf, "0x%X\n", le32_to_cpu(mesh_access.data[0])); } /** @@ -222,7 +222,7 @@ static ssize_t prb_rsp_limit_show(struct device *dev, return ret; retry_limit = le32_to_cpu(mesh_access.data[1]); - return snprintf(buf, 10, "%d\n", retry_limit); + return sysfs_emit(buf, "%d\n", retry_limit); } /** @@ -270,7 +270,7 @@ static ssize_t lbs_mesh_show(struct device *dev, struct device_attribute *attr, char *buf) { struct lbs_private *priv = to_net_dev(dev)->ml_priv; - return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev); + return sysfs_emit(buf, "0x%X\n", !!priv->mesh_dev); } /** @@ -369,7 +369,7 @@ static ssize_t bootflag_show(struct device *dev, if (ret) return ret; - return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag)); + return sysfs_emit(buf, "%d\n", le32_to_cpu(defs.bootflag)); } /** @@ -419,7 +419,7 @@ static ssize_t boottime_show(struct device *dev, if (ret) return ret; - return snprintf(buf, 12, "%d\n", defs.boottime); + return sysfs_emit(buf, "%d\n", defs.boottime); } /** @@ -479,7 +479,7 @@ static ssize_t channel_show(struct device *dev, if (ret) return ret; - return snprintf(buf, 12, "%d\n", le16_to_cpu(defs.channel)); + return sysfs_emit(buf, "%d\n", le16_to_cpu(defs.channel)); } /** @@ -605,7 +605,7 @@ static ssize_t protocol_id_show(struct device *dev, if (ret) return ret; - return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id); + return sysfs_emit(buf, "%d\n", defs.meshie.val.active_protocol_id); } /** @@ -667,7 +667,7 @@ static ssize_t metric_id_show(struct device *dev, if (ret) return ret; - return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id); + return sysfs_emit(buf, "%d\n", defs.meshie.val.active_metric_id); } /** @@ -729,7 +729,7 @@ static ssize_t capability_show(struct device *dev, if (ret) return ret; - return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability); + return sysfs_emit(buf, "%d\n", defs.meshie.val.mesh_capability); } /** From 8a27ca39478270e07baf9c09aa0c99709769ba03 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 18 Oct 2021 12:57:57 +0200 Subject: [PATCH 072/114] wcn36xx: Correct band/freq reporting on RX For packets originating from hardware scan, the channel and band is included in the buffer descriptor (bd->rf_band & bd->rx_ch). For 2Ghz band the channel value is directly reported in the 4-bit rx_ch field. For 5Ghz band, the rx_ch field contains a mapping index (given the 4-bit limitation). The reserved0 value field is also used to extend 4-bit mapping to 5-bit mapping to support more than 16 5Ghz channels. This change adds correct reporting of the frequency/band, that is used in scan mechanism. And is required for 5Ghz hardware scan support. Signed-off-by: Loic Poulain Tested-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1634554678-7993-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/txrx.c | 23 +++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/txrx.h | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index eaf2410e39647..c0f51fa13dfa1 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -31,6 +31,13 @@ struct wcn36xx_rate { enum rate_info_bw bw; }; +/* Buffer descriptor rx_ch field is limited to 5-bit (4+1), a mapping is used + * for 11A Channels. + */ +static const u8 ab_rx_ch_map[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, + 108, 112, 116, 120, 124, 128, 132, 136, 140, + 149, 153, 157, 161, 165, 144 }; + static const struct wcn36xx_rate wcn36xx_rate_table[] = { /* 11b rates */ { 10, 0, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, @@ -291,6 +298,22 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) ieee80211_is_probe_resp(hdr->frame_control)) status.boottime_ns = ktime_get_boottime_ns(); + if (bd->scan_learn) { + /* If packet originates from hardware scanning, extract the + * band/channel from bd descriptor. + */ + u8 hwch = (bd->reserved0 << 4) + bd->rx_ch; + + if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) { + status.band = NL80211_BAND_5GHZ; + status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1], + status.band); + } else { + status.band = NL80211_BAND_2GHZ; + status.freq = ieee80211_channel_to_frequency(hwch, status.band); + } + } + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); if (ieee80211_is_beacon(hdr->frame_control)) { diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.h b/drivers/net/wireless/ath/wcn36xx/txrx.h index 032216e82b2be..b54311ffde9c5 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.h +++ b/drivers/net/wireless/ath/wcn36xx/txrx.h @@ -110,7 +110,8 @@ struct wcn36xx_rx_bd { /* 0x44 */ u32 exp_seq_num:12; u32 cur_seq_num:12; - u32 fr_type_subtype:8; + u32 rf_band:2; + u32 fr_type_subtype:6; /* 0x48 */ u32 msdu_size:16; From 2371b15f8eeb5fb2c5f323ad4d4ea221277ac21e Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 18 Oct 2021 12:57:58 +0200 Subject: [PATCH 073/114] wcn36xx: Enable hardware scan offload for 5Ghz band Until now, offload scanning for 5Ghz channels was considered broken. However it was mostly a driver issue, caused by bad reporting of the beacons/probe-resp bands and frequencies, which has been fixed. We can now allow offload scan for 5GHz band, this reduces the scanning time comparing to software driven scanning. Note that offloaded scan is limited to 48 channels, check for this. Signed-off-by: Loic Poulain Tested-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1634554678-7993-2-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 263af65a889ab..2ac8efa6fb12b 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -659,19 +659,19 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_scan_request *hw_req) { struct wcn36xx *wcn = hw->priv; - int i; if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { /* fallback to mac80211 software scan */ return 1; } - /* For unknown reason, the hardware offloaded scan only works with - * 2.4Ghz channels, fallback to software scan in other cases. + /* Firmware scan offload is limited to 48 channels, fallback to + * software driven scanning otherwise. */ - for (i = 0; i < hw_req->req.n_channels; i++) { - if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ) - return 1; + if (hw_req->req.n_channels > 48) { + wcn36xx_warn("Offload scan aborted, n_channels=%u", + hw_req->req.n_channels); + return 1; } mutex_lock(&wcn->scan_lock); From a224b47ab36d7db5fb5d410622777fd10794f4cd Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 25 Oct 2021 16:26:10 +0300 Subject: [PATCH 074/114] wcn36xx: Add chained transfer support for AMSDU WCNSS RX DMA transfer support is limited to 3872 bytes, which is enough for simple MPDUs (single MSDU), but not enough for cases with A-MSDU (depending on max AMSDU size or max MPDU size). In that case the MPDU is spread over multiple transfers, with the first transfer containing the MPDU header and (at least) the first A-MSDU subframe and additional transfer(s) containing the following A-MSDUs. This can be handled with a series of flags to tagging the first and last A-MSDU transfers. In that case we have to bufferize and re-linearize the A-MSDU buffers into a proper MPDU skb before forwarding to mac80211 (in the same way as it is done in ath10k). This change also includes sanity check of the buffer descriptor to prevent skb overflow. Signed-off-by: Loic Poulain Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1634557705-11120-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/main.c | 3 + drivers/net/wireless/ath/wcn36xx/smd.c | 3 +- drivers/net/wireless/ath/wcn36xx/txrx.c | 83 ++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 4 +- 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 2ac8efa6fb12b..80d818c5a64e9 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1499,6 +1499,7 @@ static int wcn36xx_probe(struct platform_device *pdev) mutex_init(&wcn->conf_mutex); mutex_init(&wcn->hal_mutex); mutex_init(&wcn->scan_lock); + __skb_queue_head_init(&wcn->amsdu); wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); if (!wcn->hal_buf) { @@ -1576,6 +1577,8 @@ static int wcn36xx_remove(struct platform_device *pdev) iounmap(wcn->dxe_base); iounmap(wcn->ccu_base); + __skb_queue_purge(&wcn->amsdu); + mutex_destroy(&wcn->hal_mutex); ieee80211_free_hw(hw); diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 3979171c92dd2..3cecc8f9c9647 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -266,7 +266,8 @@ static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta, sta_params->max_ampdu_size = sta->ht_cap.ampdu_factor; sta_params->max_ampdu_density = sta->ht_cap.ampdu_density; - sta_params->max_amsdu_size = is_cap_supported(caps, + /* max_amsdu_size: 1 : 3839 bytes, 0 : 7935 bytes (max) */ + sta_params->max_amsdu_size = !is_cap_supported(caps, IEEE80211_HT_CAP_MAX_AMSDU); sta_params->sgi_20Mhz = is_cap_supported(caps, IEEE80211_HT_CAP_SGI_20); diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index c0f51fa13dfa1..81db90f8e3c38 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -231,6 +231,41 @@ static const struct wcn36xx_rate wcn36xx_rate_table[] = { { 4333, 9, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 }, }; +static struct sk_buff *wcn36xx_unchain_msdu(struct sk_buff_head *amsdu) +{ + struct sk_buff *skb, *first; + int total_len = 0; + int space; + + first = __skb_dequeue(amsdu); + + skb_queue_walk(amsdu, skb) + total_len += skb->len; + + space = total_len - skb_tailroom(first); + if (space > 0 && pskb_expand_head(first, 0, space, GFP_ATOMIC) < 0) { + __skb_queue_head(amsdu, first); + return NULL; + } + + /* Walk list again, copying contents into msdu_head */ + while ((skb = __skb_dequeue(amsdu))) { + skb_copy_from_linear_data(skb, skb_put(first, skb->len), + skb->len); + dev_kfree_skb_irq(skb); + } + + return first; +} + +static void __skb_queue_purge_irq(struct sk_buff_head *list) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(list)) != NULL) + dev_kfree_skb_irq(skb); +} + int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) { struct ieee80211_rx_status status; @@ -252,6 +287,26 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) "BD <<< ", (char *)bd, sizeof(struct wcn36xx_rx_bd)); + if (bd->pdu.mpdu_data_off <= bd->pdu.mpdu_header_off || + bd->pdu.mpdu_len < bd->pdu.mpdu_header_len) + goto drop; + + if (bd->asf && !bd->esf) { /* chained A-MSDU chunks */ + /* Sanity check */ + if (bd->pdu.mpdu_data_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE) + goto drop; + + skb_put(skb, bd->pdu.mpdu_data_off + bd->pdu.mpdu_len); + skb_pull(skb, bd->pdu.mpdu_data_off); + + /* Only set status for first chained BD (with mac header) */ + goto done; + } + + if (bd->pdu.mpdu_header_off < sizeof(*bd) || + bd->pdu.mpdu_header_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE) + goto drop; + skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len); skb_pull(skb, bd->pdu.mpdu_header_off); @@ -328,9 +383,37 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) (char *)skb->data, skb->len); } +done: + /* Chained AMSDU ? slow path */ + if (unlikely(bd->asf && !(bd->lsf && bd->esf))) { + if (bd->esf && !skb_queue_empty(&wcn->amsdu)) { + wcn36xx_err("Discarding non complete chain"); + __skb_queue_purge_irq(&wcn->amsdu); + } + + __skb_queue_tail(&wcn->amsdu, skb); + + if (!bd->lsf) + return 0; /* Not the last AMSDU, wait for more */ + + skb = wcn36xx_unchain_msdu(&wcn->amsdu); + if (!skb) + goto drop; + } + ieee80211_rx_irqsafe(wcn->hw, skb); return 0; + +drop: /* drop everything */ + wcn36xx_err("Drop frame! skb:%p len:%u hoff:%u doff:%u asf=%u esf=%u lsf=%u\n", + skb, bd->pdu.mpdu_len, bd->pdu.mpdu_header_off, + bd->pdu.mpdu_data_off, bd->asf, bd->esf, bd->lsf); + + dev_kfree_skb_irq(skb); + __skb_queue_purge_irq(&wcn->amsdu); + + return -EINVAL; } static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd, diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index add6e527e8330..ae63bc6916d66 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h @@ -269,6 +269,9 @@ struct wcn36xx { struct sk_buff *tx_ack_skb; struct timer_list tx_ack_timer; + /* For A-MSDU re-aggregation */ + struct sk_buff_head amsdu; + /* RF module */ unsigned rf_id; @@ -276,7 +279,6 @@ struct wcn36xx { /* Debug file system entry */ struct wcn36xx_dfs_entry dfs; #endif /* CONFIG_WCN36XX_DEBUGFS */ - }; static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, From 2f1ae32f736ddafa3b3c7a62b8e943ef53b3230f Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 22 Oct 2021 15:04:46 +0100 Subject: [PATCH 075/114] wcn36xx: Treat repeated BMPS entry fail as connection loss On an open AP when you pull the plug on the AP, if we are not already in BMPS mode then the firmware will not generate a disconnection event. Instead we need to monitor for failure to enter BMPS and treat a string of failures as connection loss. Secure AP connections don't appear to demonstrate this behavior so the work-around is limited to open APs only. Signed-off-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211022140447.2846248-2-bryan.odonoghue@linaro.org --- drivers/net/wireless/ath/wcn36xx/pmc.c | 8 ++++++++ drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.c b/drivers/net/wireless/ath/wcn36xx/pmc.c index 2d0780fefd477..6a9cfeabd7419 100644 --- a/drivers/net/wireless/ath/wcn36xx/pmc.c +++ b/drivers/net/wireless/ath/wcn36xx/pmc.c @@ -18,6 +18,8 @@ #include "wcn36xx.h" +#define WCN36XX_BMPS_FAIL_THREHOLD 3 + int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, struct ieee80211_vif *vif) { @@ -31,6 +33,7 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, if (!ret) { wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n"); vif_priv->pw_state = WCN36XX_BMPS; + vif_priv->bmps_fail_ct = 0; vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; } else { /* @@ -39,6 +42,11 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, * received just after auth complete */ wcn36xx_err("Can not enter BMPS!\n"); + + if (vif_priv->bmps_fail_ct++ == WCN36XX_BMPS_FAIL_THREHOLD) { + ieee80211_connection_loss(vif); + vif_priv->bmps_fail_ct = 0; + } } return ret; } diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index ae63bc6916d66..7a064f8f16351 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h @@ -151,6 +151,8 @@ struct wcn36xx_vif { } rekey_data; struct list_head sta_list; + + int bmps_fail_ct; }; /** From 285bb1738e196507bf985574d0bc1e9dd72d46b1 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Fri, 22 Oct 2021 15:04:47 +0100 Subject: [PATCH 076/114] Revert "wcn36xx: Disable bmps when encryption is disabled" This reverts commit c6522a5076e1a65877c51cfee313a74ef61cabf8. Testing on tip-of-tree shows that this is working now. Revert this and re-enable BMPS for Open APs. Signed-off-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211022140447.2846248-3-bryan.odonoghue@linaro.org --- drivers/net/wireless/ath/wcn36xx/main.c | 10 ---------- drivers/net/wireless/ath/wcn36xx/pmc.c | 5 +---- drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 - 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 80d818c5a64e9..644b8523df689 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -613,15 +613,6 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } } } - /* FIXME: Only enable bmps support when encryption is enabled. - * For any reasons, when connected to open/no-security BSS, - * the wcn36xx controller in bmps mode does not forward - * 'wake-up' beacons despite AP sends DTIM with station AID. - * It could be due to a firmware issue or to the way driver - * configure the station. - */ - if (vif->type == NL80211_IFTYPE_STATION) - vif_priv->allow_bmps = true; break; case DISABLE_KEY: if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { @@ -922,7 +913,6 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, vif->addr, bss_conf->aid); vif_priv->sta_assoc = false; - vif_priv->allow_bmps = false; wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr, diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.c b/drivers/net/wireless/ath/wcn36xx/pmc.c index 6a9cfeabd7419..2c660458b3830 100644 --- a/drivers/net/wireless/ath/wcn36xx/pmc.c +++ b/drivers/net/wireless/ath/wcn36xx/pmc.c @@ -25,10 +25,7 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, { int ret = 0; struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif); - - if (!vif_priv->allow_bmps) - return -ENOTSUPP; - + /* TODO: Make sure the TX chain clean */ ret = wcn36xx_smd_enter_bmps(wcn, vif); if (!ret) { wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n"); diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index 7a064f8f16351..1c8d918137da2 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h @@ -128,7 +128,6 @@ struct wcn36xx_vif { enum wcn36xx_hal_bss_type bss_type; /* Power management */ - bool allow_bmps; enum wcn36xx_power_state pw_state; u8 bss_index; From 960ae77f25631bbe4e3aafefe209b52e044baf31 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Wed, 20 Oct 2021 15:38:53 +0200 Subject: [PATCH 077/114] wcn36xx: Fix HT40 capability for 2Ghz band All wcn36xx controllers are supposed to support HT40 (and SGI40), This doubles the maximum bitrate/throughput with compatible APs. Tested with wcn3620 & wcn3680B. Cc: stable@vger.kernel.org Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware") Signed-off-by: Loic Poulain Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1634737133-22336-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 644b8523df689..1cddb78aa00e9 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -135,7 +135,9 @@ static struct ieee80211_supported_band wcn_band_2ghz = { .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 | - IEEE80211_HT_CAP_LSIG_TXOP_PROT, + IEEE80211_HT_CAP_LSIG_TXOP_PROT | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_SUP_WIDTH_20_40, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, From 9bfe38e064af5decba2ffce66a2958ab8b10eaa4 Mon Sep 17 00:00:00 2001 From: Benjamin Li Date: Fri, 22 Oct 2021 17:15:28 -0700 Subject: [PATCH 078/114] wcn36xx: add proper DMA memory barriers in rx path This is essentially exactly following the dma_wmb()/dma_rmb() usage instructions in Documentation/memory-barriers.txt. The theoretical races here are: 1. DXE (the DMA Transfer Engine in the Wi-Fi subsystem) seeing the dxe->ctrl & WCN36xx_DXE_CTRL_VLD write before the dxe->dst_addr_l write, thus performing DMA into the wrong address. 2. CPU reading dxe->dst_addr_l before DXE unsets dxe->ctrl & WCN36xx_DXE_CTRL_VLD. This should generally be harmless since DXE doesn't write dxe->dst_addr_l (no risk of freeing the wrong skb). Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware") Signed-off-by: Benjamin Li Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211023001528.3077822-1-benl@squareup.com --- drivers/net/wireless/ath/wcn36xx/dxe.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index 0e0bbcd11300b..aff04ef662663 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -606,6 +606,10 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, dxe = ctl->desc; while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) { + /* do not read until we own DMA descriptor */ + dma_rmb(); + + /* read/modify DMA descriptor */ skb = ctl->skb; dma_addr = dxe->dst_addr_l; ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC); @@ -616,9 +620,15 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE, DMA_FROM_DEVICE); wcn36xx_rx_skb(wcn, skb); - } /* else keep old skb not submitted and use it for rx DMA */ + } + /* else keep old skb not submitted and reuse it for rx DMA + * (dropping the packet that it contained) + */ + /* flush descriptor changes before re-marking as valid */ + dma_wmb(); dxe->ctrl = ctrl; + ctl = ctl->next; dxe = ctl->desc; } From 113f304dbc1627c6ec9d5329d839964095768980 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 25 Oct 2021 10:25:36 +0200 Subject: [PATCH 079/114] wcn36xx: Fix discarded frames due to wrong sequence number The firmware is offering features such as ARP offload, for which firmware crafts its own (QoS)packets without waking up the host. Point is that the sequence numbers generated by the firmware are not in sync with the host mac80211 layer and can cause packets such as firmware ARP reponses to be dropped by the AP (too old SN). To fix this we need to let the firmware manages the sequence numbers by its own (except for QoS null frames). There is a SN counter for each QoS queue and one global/baseline counter for Non-QoS. Fixes: 84aff52e4f57 ("wcn36xx: Use sequence number allocated by mac80211") Signed-off-by: Loic Poulain Tested-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1635150336-18736-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/txrx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index 81db90f8e3c38..75951ccbc840e 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -427,8 +427,6 @@ static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd, bd->pdu.mpdu_header_off; bd->pdu.mpdu_len = len; bd->pdu.tid = tid; - /* Use seq number generated by mac80211 */ - bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST; } static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn, @@ -525,6 +523,9 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, tid = ieee80211_get_tid(hdr); /* TID->QID is one-to-one mapping */ bd->queue_id = tid; + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_QOS; + } else { + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; } if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT || @@ -536,6 +537,8 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, /* Don't use a regular queue for null packet (no ampdu) */ bd->queue_id = WCN36XX_TX_U_WQ_ID; bd->bd_rate = WCN36XX_BD_RATE_CTRL; + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST; } if (bcast) { @@ -595,6 +598,8 @@ static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd, bd->queue_id = WCN36XX_TX_U_WQ_ID; *vif_priv = __vif_priv; + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; + wcn36xx_set_tx_pdu(bd, ieee80211_is_data_qos(hdr->frame_control) ? sizeof(struct ieee80211_qos_hdr) : From df0697801d8aa2eebfe7f0b7388879639f8fe7cc Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 25 Oct 2021 10:28:16 +0200 Subject: [PATCH 080/114] wcn36xx: Fix packet drop on resume If the system is resumed because of an incoming packet, the wcn36xx RX interrupts is fired before actual resuming of the wireless/mac80211 stack, causing any received packets to be simply dropped. E.g. a ping request causes a system resume, but is dropped and so never forwarded to the IP stack. This change fixes that, disabling DMA interrupts on suspend to no pass packets until mac80211 is resumed and ready to handle them. Note that it's not incompatible with RX irq wake. Signed-off-by: Loic Poulain Reviewed-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1635150496-19290-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 1cddb78aa00e9..fadacb309c471 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1124,6 +1124,13 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow) goto out; ret = wcn36xx_smd_wlan_host_suspend_ind(wcn); } + + /* Disable IRQ, we don't want to handle any packet before mac80211 is + * resumed and ready to receive packets. + */ + disable_irq(wcn->tx_irq); + disable_irq(wcn->rx_irq); + out: mutex_unlock(&wcn->conf_mutex); return ret; @@ -1146,6 +1153,10 @@ static int wcn36xx_resume(struct ieee80211_hw *hw) wcn36xx_smd_ipv6_ns_offload(wcn, vif, false); wcn36xx_smd_arp_offload(wcn, vif, false); } + + enable_irq(wcn->tx_irq); + enable_irq(wcn->rx_irq); + mutex_unlock(&wcn->conf_mutex); return 0; From 43ea9bd84f27d06482cc823d9749cc9dd2993bc8 Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Mon, 25 Oct 2021 10:30:37 +0100 Subject: [PATCH 081/114] Revert "wcn36xx: Enable firmware link monitoring" Firmware link offload monitoring can be made to work in 3/4 cases by switching on firmware feature bit WLANACTIVE_OFFLOAD - Secure power-save on - Secure power-save off - Open power-save on However, with an open AP if we switch off power-saving - thus never entering Beacon Mode Power Save - BMPS, firmware never forwards loss of beacon upwards. We had hoped that WLANACTIVE_OFFLOAD and some fixes for sequence numbers would unblock this but, it hasn't and further investigation is required. Its possible to have a complete set of Secure power-save on/off and Open power-save on/off provided we use Linux' link monitoring mechanism. While we debug the Open AP failure we need to fix upstream. This reverts commit c973fdad79f6eaf247d48b5fc77733e989eb01e1. Signed-off-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211025093037.3966022-2-bryan.odonoghue@linaro.org --- drivers/net/wireless/ath/wcn36xx/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index fadacb309c471..42153305f6d84 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1350,7 +1350,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL); ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS); ieee80211_hw_set(wcn->hw, REPORTS_TX_ACK_STATUS); - ieee80211_hw_set(wcn->hw, CONNECTION_MONITOR); wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | From d707f812bb0513ea0030d0c9fe2a456bae5a4583 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Mon, 25 Oct 2021 17:22:08 +0200 Subject: [PATCH 082/114] wcn36xx: Channel list update before hardware scan The channel scan list must be updated before triggering a hardware scan so that firmware takes into account the regulatory info for each single channel such as active/passive config, power, DFS, etc... Without this the firmware uses its own internal default channel configuration, which is not aligned with mac80211 regulatory rules, and misses several channels (e.g. 144). Fixes: 2f3bef4b247e ("wcn36xx: Add hardware scan offload support") Signed-off-by: Loic Poulain Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1635175328-25642-1-git-send-email-loic.poulain@linaro.org --- drivers/net/wireless/ath/wcn36xx/hal.h | 32 ++++++++++ drivers/net/wireless/ath/wcn36xx/main.c | 1 + drivers/net/wireless/ath/wcn36xx/smd.c | 82 +++++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/smd.h | 1 + 4 files changed, 116 insertions(+) diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 5f1f2480459a7..9bea2b01f9aab 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -359,6 +359,8 @@ enum wcn36xx_hal_host_msg_type { WCN36XX_HAL_START_SCAN_OFFLOAD_RSP = 205, WCN36XX_HAL_STOP_SCAN_OFFLOAD_REQ = 206, WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP = 207, + WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ = 208, + WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP = 209, WCN36XX_HAL_SCAN_OFFLOAD_IND = 210, WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233, @@ -1353,6 +1355,36 @@ struct wcn36xx_hal_stop_scan_offload_rsp_msg { u32 status; } __packed; +#define WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK 0x000000ff +#define WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK 0x0000ff00 +#define WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK 0x00ff0000 +#define WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK 0xff000000 +#define WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK 0x000000ff +#define WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE BIT(7) +#define WCN36XX_HAL_CHAN_INFO_FLAG_DFS BIT(10) +#define WCN36XX_HAL_CHAN_INFO_FLAG_HT BIT(11) +#define WCN36XX_HAL_CHAN_INFO_FLAG_VHT BIT(12) +#define WCN36XX_HAL_CHAN_INFO_PHY_11A 0 +#define WCN36XX_HAL_CHAN_INFO_PHY_11BG 1 +#define WCN36XX_HAL_DEFAULT_ANT_GAIN 6 +#define WCN36XX_HAL_DEFAULT_MIN_POWER 6 + +struct wcn36xx_hal_channel_param { + u32 mhz; + u32 band_center_freq1; + u32 band_center_freq2; + u32 channel_info; + u32 reg_info_1; + u32 reg_info_2; +} __packed; + +struct wcn36xx_hal_update_channel_list_req_msg { + struct wcn36xx_hal_msg_header header; + + u8 num_channel; + struct wcn36xx_hal_channel_param channels[80]; +} __packed; + enum wcn36xx_hal_rate_index { HW_RATE_INDEX_1MBPS = 0x82, HW_RATE_INDEX_2MBPS = 0x84, diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 42153305f6d84..158ac17f5f564 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -678,6 +678,7 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw, mutex_unlock(&wcn->scan_lock); + wcn36xx_smd_update_channel_list(wcn, &hw_req->req); return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req); } diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 3cecc8f9c9647..e1f4a5d79af77 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -16,6 +16,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -928,6 +929,86 @@ int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn) return ret; } +int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req) +{ + struct wcn36xx_hal_update_channel_list_req_msg *msg_body; + int ret, i; + + msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL); + if (!msg_body) + return -ENOMEM; + + INIT_HAL_MSG((*msg_body), WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ); + + msg_body->num_channel = min_t(u8, req->n_channels, sizeof(msg_body->channels)); + for (i = 0; i < msg_body->num_channel; i++) { + struct wcn36xx_hal_channel_param *param = &msg_body->channels[i]; + u32 min_power = WCN36XX_HAL_DEFAULT_MIN_POWER; + u32 ant_gain = WCN36XX_HAL_DEFAULT_ANT_GAIN; + + param->mhz = req->channels[i]->center_freq; + param->band_center_freq1 = req->channels[i]->center_freq; + param->band_center_freq2 = 0; + + if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE; + + if (req->channels[i]->flags & IEEE80211_CHAN_RADAR) + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_DFS; + + if (req->channels[i]->band == NL80211_BAND_5GHZ) { + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_HT; + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_VHT; + param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11A; + } else { + param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11BG; + } + + if (min_power > req->channels[i]->max_power) + min_power = req->channels[i]->max_power; + + if (req->channels[i]->max_antenna_gain) + ant_gain = req->channels[i]->max_antenna_gain; + + u32p_replace_bits(¶m->reg_info_1, min_power, + WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK); + u32p_replace_bits(¶m->reg_info_1, req->channels[i]->max_power, + WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK); + u32p_replace_bits(¶m->reg_info_1, req->channels[i]->max_reg_power, + WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK); + u32p_replace_bits(¶m->reg_info_1, 0, + WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK); + u32p_replace_bits(¶m->reg_info_2, ant_gain, + WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK); + + wcn36xx_dbg(WCN36XX_DBG_HAL, + "%s: freq=%u, channel_info=%08x, reg_info1=%08x, reg_info2=%08x\n", + __func__, param->mhz, param->channel_info, param->reg_info_1, + param->reg_info_2); + } + + mutex_lock(&wcn->hal_mutex); + + PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body)); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len); + if (ret) { + wcn36xx_err("Sending hal_update_channel_list failed\n"); + goto out; + } + + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_update_channel_list response failed err=%d\n", ret); + goto out; + } + +out: + kfree(msg_body); + mutex_unlock(&wcn->hal_mutex); + return ret; +} + static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len) { struct wcn36xx_hal_switch_channel_rsp_msg *rsp; @@ -3138,6 +3219,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_HOST_RESUME_RSP: case WCN36XX_HAL_ENTER_IMPS_RSP: case WCN36XX_HAL_EXIT_IMPS_RSP: + case WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP: memcpy(wcn->hal_buf, buf, len); wcn->hal_rsp_len = len; complete(&wcn->hal_rsp_compl); diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index 5f98c1d01ae4c..88e045dad8f3a 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -70,6 +70,7 @@ int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t cha int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn); +int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req); int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index); From d8e12f315f81871d12356f1723fd9b5e1c3fcb9a Mon Sep 17 00:00:00 2001 From: Benjamin Li Date: Mon, 25 Oct 2021 10:53:57 -0700 Subject: [PATCH 083/114] wcn36xx: switch on antenna diversity feature bit The official feature-complete WCN3680B driver (known as prima, open source but not upstream) sends this feature bit. As we wish to support the antenna diversity feature in upstream, we need to set this bit as well. Signed-off-by: Benjamin Li Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211025175359.3591048-2-benl@squareup.com --- drivers/net/wireless/ath/wcn36xx/smd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index e1f4a5d79af77..b18ab216d5cdc 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -2476,8 +2476,10 @@ int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn) INIT_HAL_MSG(msg_body, WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ); set_feat_caps(msg_body.feat_caps, STA_POWERSAVE); - if (wcn->rf_id == RF_IRIS_WCN3680) + if (wcn->rf_id == RF_IRIS_WCN3680) { set_feat_caps(msg_body.feat_caps, DOT11AC); + set_feat_caps(msg_body.feat_caps, ANTENNA_DIVERSITY_SELECTION); + } PREPARE_HAL_BUF(wcn->hal_buf, msg_body); From c9a4f2dd4cb2c6a40a2c8823832cc37e829ba4fb Mon Sep 17 00:00:00 2001 From: Benjamin Li Date: Mon, 25 Oct 2021 10:53:58 -0700 Subject: [PATCH 084/114] wcn36xx: add missing 5GHz channels 136 and 144 The official feature-complete WCN3680B driver (known as prima, open source but not upstream) supports channels 136 and 144. However, these channels are missing in upstream. Add them here to get closer to feature parity with prima. Signed-off-by: Benjamin Li Reviewed-by: Bryan O'Donoghue Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211025175359.3591048-3-benl@squareup.com --- drivers/net/wireless/ath/wcn36xx/main.c | 2 ++ drivers/net/wireless/ath/wcn36xx/smd.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 158ac17f5f564..b04533bbc3a45 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -85,7 +85,9 @@ static struct ieee80211_channel wcn_5ghz_channels[] = { CHAN5G(5620, 124, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), CHAN5G(5640, 128, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), CHAN5G(5660, 132, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), + CHAN5G(5680, 136, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), CHAN5G(5700, 140, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), + CHAN5G(5720, 144, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH), CHAN5G(5745, 149, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW), CHAN5G(5765, 153, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW), CHAN5G(5785, 157, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH), diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index b18ab216d5cdc..ed45e2cf039be 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -2478,6 +2478,7 @@ int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn) set_feat_caps(msg_body.feat_caps, STA_POWERSAVE); if (wcn->rf_id == RF_IRIS_WCN3680) { set_feat_caps(msg_body.feat_caps, DOT11AC); + set_feat_caps(msg_body.feat_caps, WLAN_CH144); set_feat_caps(msg_body.feat_caps, ANTENNA_DIVERSITY_SELECTION); } From 5286132324230168d3fab6ffc16bfd7de85bdfb4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 25 Oct 2021 14:05:19 +0200 Subject: [PATCH 085/114] ath10k: fix control-message timeout USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ. Fixes: 4db66499df91 ("ath10k: add initial USB support") Cc: stable@vger.kernel.org # 4.14 Cc: Erik Stromdahl Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211025120522.6045-2-johan@kernel.org --- drivers/net/wireless/ath/ath10k/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c index 19b9c27e30e20..6d831b098cbb6 100644 --- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -525,7 +525,7 @@ static int ath10k_usb_submit_ctrl_in(struct ath10k *ar, req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, buf, - size, 2 * HZ); + size, 2000); if (ret < 0) { ath10k_warn(ar, "Failed to read usb control message: %d\n", From a066d28a7e729f808a3e6eff22e70c003091544e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 25 Oct 2021 14:05:20 +0200 Subject: [PATCH 086/114] ath6kl: fix control-message timeout USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ. Fixes: 241b128b6b69 ("ath6kl: add back beginnings of USB support") Cc: stable@vger.kernel.org # 3.4 Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211025120522.6045-3-johan@kernel.org --- drivers/net/wireless/ath/ath6kl/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index 5372e948e761d..bd367b79a4d30 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -907,7 +907,7 @@ static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb, req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, buf, - size, 2 * HZ); + size, 2000); if (ret < 0) { ath6kl_warn("Failed to read usb control message: %d\n", ret); From a006acb931317aad3a8dd41333ebb0453caf49b8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 27 Oct 2021 10:08:17 +0200 Subject: [PATCH 087/114] ath10k: fix division by zero in send path Add the missing endpoint max-packet sanity check to probe() to avoid division by zero in ath10k_usb_hif_tx_sg() in case a malicious device has broken descriptors (or when doing descriptor fuzz testing). Note that USB core will reject URBs submitted for endpoints with zero wMaxPacketSize but that drivers doing packet-size calculations still need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip endpoint descriptors with maxpacket=0")). Fixes: 4db66499df91 ("ath10k: add initial USB support") Cc: stable@vger.kernel.org # 4.14 Cc: Erik Stromdahl Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211027080819.6675-2-johan@kernel.org --- drivers/net/wireless/ath/ath10k/usb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c index 6d831b098cbb6..3d98f19c6ec8a 100644 --- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -853,6 +853,11 @@ static int ath10k_usb_setup_pipe_resources(struct ath10k *ar, le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval); } + + /* Ignore broken descriptors. */ + if (usb_endpoint_maxp(endpoint) == 0) + continue; + urbcount = 0; pipe_num = From c1b9ca365deae667192be9fe24db244919971234 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 27 Oct 2021 10:08:18 +0200 Subject: [PATCH 088/114] ath6kl: fix division by zero in send path Add the missing endpoint max-packet sanity check to probe() to avoid division by zero in ath10k_usb_hif_tx_sg() in case a malicious device has broken descriptors (or when doing descriptor fuzz testing). Note that USB core will reject URBs submitted for endpoints with zero wMaxPacketSize but that drivers doing packet-size calculations still need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip endpoint descriptors with maxpacket=0")). Fixes: 9cbee358687e ("ath6kl: add full USB support") Cc: stable@vger.kernel.org # 3.5 Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211027080819.6675-3-johan@kernel.org --- drivers/net/wireless/ath/ath6kl/usb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index bd367b79a4d30..aba70f35e574b 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -340,6 +340,11 @@ static int ath6kl_usb_setup_pipe_resources(struct ath6kl_usb *ar_usb) le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval); } + + /* Ignore broken descriptors. */ + if (usb_endpoint_maxp(endpoint) == 0) + continue; + urbcount = 0; pipe_num = From 479b878a95951c618e6c881f9cf00fe98dd069f9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 24 Oct 2021 16:54:56 +0300 Subject: [PATCH 089/114] iwlwifi: mvm: fix some kerneldoc issues A few fields were missing their kerneldoc in the station capabilities. Signed-off-by: Emmanuel Grumbach Fixes: c8a2e7a29702 ("iwlwifi: sta: set max HE max A-MPDU according to HE capa") Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.fecbcd7c2fcc.I7419f102b798ba0cecd93c80f345b241670e0683@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/sta.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h index f1a3e14880e7a..5edbe27c09227 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h @@ -28,6 +28,8 @@ * @STA_FLG_MAX_AGG_SIZE_256K: maximal size for A-MPDU (256k supported) * @STA_FLG_MAX_AGG_SIZE_512K: maximal size for A-MPDU (512k supported) * @STA_FLG_MAX_AGG_SIZE_1024K: maximal size for A-MPDU (1024k supported) + * @STA_FLG_MAX_AGG_SIZE_2M: maximal size for A-MPDU (2M supported) + * @STA_FLG_MAX_AGG_SIZE_4M: maximal size for A-MPDU (4M supported) * @STA_FLG_AGG_MPDU_DENS_MSK: maximal MPDU density for Tx aggregation * @STA_FLG_FAT_EN_MSK: support for channel width (for Tx). This flag is * initialised by driver and can be updated by fw upon reception of From c7d3db99047c4901c96f0140fa2707d4fe72f0cc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 16:54:57 +0300 Subject: [PATCH 090/114] iwlwifi: pcie: fix killer name matching for AX200 The "Killer(R) Wi-Fi 6 AX1650w 160MHz Wireless Network Adapter (200D2W)" and "Killer(R) Wi-Fi 6 AX1650x 160MHz Wireless Network Adapter (200NGW)" names couldn't match properly because the most generic entry needs to be specified last. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.86a430e5b2ff.I7a9e89df7ddfc939690d3718d41afc934a4d4ea0@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 37a1ef868e6fd..aeac1b3997ab5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -549,9 +549,9 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_DEV_INFO(0x7E40, 0x1692, iwl_cfg_ma_a0_gf4_a0, iwl_ax411_killer_1690i_name), /* AX200 */ + IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), IWL_DEV_INFO(0x2723, 0x1653, iwl_ax200_cfg_cc, iwl_ax200_killer_1650w_name), IWL_DEV_INFO(0x2723, 0x1654, iwl_ax200_cfg_cc, iwl_ax200_killer_1650x_name), - IWL_DEV_INFO(0x2723, IWL_CFG_ANY, iwl_ax200_cfg_cc, iwl_ax200_name), /* Qu with Hr */ IWL_DEV_INFO(0x43F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), From 636cc16582e28f5c395a4c8d0e13bd70816922d1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 16:54:58 +0300 Subject: [PATCH 091/114] iwlwifi: pcie: remove duplicate entry This entry is literally duplicated, remove one of them. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.239f82fc3737.I5fef3a20fbce77e201dc35d45be0ee526bcd3cd3@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index aeac1b3997ab5..fec1620bd5932 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1074,11 +1074,6 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_so_a0_hr_a0, iwl_ax203_name), - _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, - IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, - iwl_cfg_so_a0_hr_a0, iwl_ax203_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_SO, IWL_CFG_ANY, IWL_CFG_RF_TYPE_HR1, IWL_CFG_ANY, From 0a1f96d571c841b31d12d3697f149ae1ea3087ea Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 16:54:59 +0300 Subject: [PATCH 092/114] iwlwifi: pcie: refactor dev_info lookup The large condition here is not very clear, refactor the code to a separate function where we can more easily just check each of the pieces separately. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.ef06ed58a26e.Ie9664a94b157c5781c481118d900ae428c26fdb3@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 99 +++++++++++++------ 1 file changed, 68 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index fec1620bd5932..adb3ad26b712e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -519,7 +519,7 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); #define IWL_DEV_INFO(_device, _subdevice, _cfg, _name) \ _IWL_DEV_INFO(_device, _subdevice, IWL_CFG_ANY, IWL_CFG_ANY, \ IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, \ - IWL_CFG_NO_CDB, _cfg, _name) + IWL_CFG_ANY, _cfg, _name) static const struct iwl_dev_info iwl_dev_info_table[] = { #if IS_ENABLED(CONFIG_IWLMVM) @@ -1312,13 +1312,67 @@ static int get_crf_id(struct iwl_trans *iwl_trans) /* PCI registers */ #define PCI_CFG_RETRY_TIMEOUT 0x041 +static const struct iwl_dev_info * +iwl_pci_find_dev_info(u16 device, u16 subsystem_device, + u16 mac_type, u8 mac_step, + u16 rf_type, u8 cdb, u8 rf_id, u8 no_160, u8 cores) +{ + const struct iwl_dev_info *ret = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(iwl_dev_info_table); i++) { + const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; + + if (dev_info->device != (u16)IWL_CFG_ANY && + dev_info->device != device) + continue; + + if (dev_info->subdevice != (u16)IWL_CFG_ANY && + dev_info->subdevice != subsystem_device) + continue; + + if (dev_info->mac_type != (u16)IWL_CFG_ANY && + dev_info->mac_type != mac_type) + continue; + + if (dev_info->mac_step != (u8)IWL_CFG_ANY && + dev_info->mac_step != mac_step) + continue; + + if (dev_info->rf_type != (u16)IWL_CFG_ANY && + dev_info->rf_type != rf_type) + continue; + + if (dev_info->cdb != (u8)IWL_CFG_ANY && + dev_info->cdb != cdb) + continue; + + if (dev_info->rf_id != (u8)IWL_CFG_ANY && + dev_info->rf_id != rf_id) + continue; + + if (dev_info->no_160 != (u8)IWL_CFG_ANY && + dev_info->no_160 != no_160) + continue; + + if (dev_info->cores != (u8)IWL_CFG_ANY && + dev_info->cores != cores) + continue; + + ret = dev_info; + } + + return ret; +} + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { const struct iwl_cfg_trans_params *trans; const struct iwl_cfg *cfg_7265d __maybe_unused = NULL; + const struct iwl_dev_info *dev_info; struct iwl_trans *iwl_trans; struct iwl_trans_pcie *trans_pcie; - int i, ret; + int ret; const struct iwl_cfg *cfg; trans = (void *)(ent->driver_data & ~TRANS_CFG_MARKER); @@ -1370,35 +1424,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) !CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans)) goto out_free_trans; - for (i = 0; i < ARRAY_SIZE(iwl_dev_info_table); i++) { - const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; - if ((dev_info->device == (u16)IWL_CFG_ANY || - dev_info->device == pdev->device) && - (dev_info->subdevice == (u16)IWL_CFG_ANY || - dev_info->subdevice == pdev->subsystem_device) && - (dev_info->mac_type == (u16)IWL_CFG_ANY || - dev_info->mac_type == - CSR_HW_REV_TYPE(iwl_trans->hw_rev)) && - (dev_info->mac_step == (u8)IWL_CFG_ANY || - dev_info->mac_step == - CSR_HW_REV_STEP(iwl_trans->hw_rev)) && - (dev_info->rf_type == (u16)IWL_CFG_ANY || - dev_info->rf_type == - CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id)) && - (dev_info->cdb == IWL_CFG_NO_CDB || - CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id)) && - (dev_info->rf_id == (u8)IWL_CFG_ANY || - dev_info->rf_id == - IWL_SUBDEVICE_RF_ID(pdev->subsystem_device)) && - (dev_info->no_160 == (u8)IWL_CFG_ANY || - dev_info->no_160 == - IWL_SUBDEVICE_NO_160(pdev->subsystem_device)) && - (dev_info->cores == (u8)IWL_CFG_ANY || - dev_info->cores == - IWL_SUBDEVICE_CORES(pdev->subsystem_device))) { - iwl_trans->cfg = dev_info->cfg; - iwl_trans->name = dev_info->name; - } + dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device, + CSR_HW_REV_TYPE(iwl_trans->hw_rev), + CSR_HW_REV_STEP(iwl_trans->hw_rev), + CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id), + CSR_HW_RFID_IS_CDB(iwl_trans->hw_rf_id), + IWL_SUBDEVICE_RF_ID(pdev->subsystem_device), + IWL_SUBDEVICE_NO_160(pdev->subsystem_device), + IWL_SUBDEVICE_CORES(pdev->subsystem_device)); + + if (dev_info) { + iwl_trans->cfg = dev_info->cfg; + iwl_trans->name = dev_info->name; } #if IS_ENABLED(CONFIG_IWLMVM) From 2270bb685c913ac076aff835ff8ba53ee36ae70d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 16:55:00 +0300 Subject: [PATCH 093/114] iwlwifi: pcie: remove two duplicate PNJ device entries Since PNJ and TH have the same ID (0x32), there are duplicate entries. Remove the duplicates with PNJ since PNJ is only the test device in the first place. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.0ca7c9322e69.Id2f32427795d0713fd7d2722567e604808b219dd@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index adb3ad26b712e..ab7a1a090b363 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -725,17 +725,6 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, iwl9260_2ac_cfg, iwl9462_name), - _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, - IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9560_160_name), - _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_PNJ, IWL_CFG_ANY, - IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, - IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, - iwl9260_2ac_cfg, iwl9560_name), - _IWL_DEV_INFO(0x2526, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_TH, IWL_CFG_ANY, IWL_CFG_RF_TYPE_TH, IWL_CFG_ANY, From e699bdea24104cb1add30ae019347d2a5ebe1f63 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Sun, 24 Oct 2021 16:55:01 +0300 Subject: [PATCH 094/114] iwlwifi: mvm: Use all Rx chains for roaming scan To improve chances of hearing beacons and probe responses during a scan which (based on the scan request parameters) looks like a roaming scan, enable reception on all chains. Signed-off-by: Ilan Peer Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.f115ad455aca.I5de854fe8ce58c85c21a7adf43526acb29156a08@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index ce8bdbc70b7e3..a138b5c4cce84 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1995,8 +1995,16 @@ static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm, { u16 flags = 0; + /* + * If no direct SSIDs are provided perform a passive scan. Otherwise, + * if there is a single SSID which is not the broadcast SSID, assume + * that the scan is intended for roaming purposes and thus enable Rx on + * all chains to improve chances of hearing the beacons/probe responses. + */ if (params->n_ssids == 0) flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE; + else if (params->n_ssids == 1 && params->ssids[0].ssid_len) + flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_USE_ALL_RX_CHAINS; if (iwl_mvm_is_scan_fragmented(params->type)) flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1; From f06bc8afa2a82a1d615b4bfeb5bb6835b3326f26 Mon Sep 17 00:00:00 2001 From: Yaara Baruch Date: Sun, 24 Oct 2021 16:55:02 +0300 Subject: [PATCH 095/114] iwlwifi: add new pci SoF with JF add new SoF JF device to the driver. Signed-off-by: Yaara Baruch Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.50e62c8ef85b.I3498879d8c184e42b1578a64aa7b7c99a18b75fb@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index ab7a1a090b363..3276f04cfd607 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1130,6 +1130,39 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_cfg_gl_a0_fm_a0, iwl_bz_name), +/* SoF with JF2 */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + iwlax210_2ax_cfg_so_jf_b0, iwl9560_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF2, IWL_CFG_RF_ID_JF, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + iwlax210_2ax_cfg_so_jf_b0, iwl9560_name), + +/* SoF with JF */ + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + iwlax210_2ax_cfg_so_jf_b0, iwl9461_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + iwlax210_2ax_cfg_so_jf_b0, iwl9462_160_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + iwlax210_2ax_cfg_so_jf_b0, iwl9461_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_SOF, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_JF1, IWL_CFG_RF_ID_JF1_DIV, + IWL_CFG_NO_160, IWL_CFG_CORES_BT, IWL_CFG_NO_CDB, + iwlax210_2ax_cfg_so_jf_b0, iwl9462_name), /* SoF with JF2 */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, From 571836a02c7b6197bab4328fc9ceaa262873e85c Mon Sep 17 00:00:00 2001 From: Mike Golant Date: Sun, 24 Oct 2021 16:55:03 +0300 Subject: [PATCH 096/114] iwlwifi: pcie: update sw error interrupt for BZ family The cause for sw error in BZ device family was changed Signed-off-by: Mike Golant Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.f674cd409b8e.I519f554d0a22d4711077785ec2bd7c564997241f@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 9 +++- .../net/wireless/intel/iwlwifi/pcie/trans.c | 45 ++++++++++++++----- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index 2c4d70fb32fa8..ff79a2ecb2422 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -605,6 +605,7 @@ enum msix_hw_int_causes { MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1), MSIX_HW_INT_CAUSES_REG_IML = BIT(1), MSIX_HW_INT_CAUSES_REG_RESET_DONE = BIT(2), + MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ = BIT(5), MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6), MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7), MSIX_HW_INT_CAUSES_REG_PERIODIC = BIT(8), diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 8e45eb38304b2..14602d6d6699f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -2149,6 +2149,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) u32 inta_fh_msk = ~MSIX_FH_INT_CAUSES_DATA_QUEUE; u32 inta_fh, inta_hw; bool polling = false; + bool sw_err; if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX) inta_fh_msk |= MSIX_FH_INT_CAUSES_Q0; @@ -2221,9 +2222,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) wake_up(&trans_pcie->ucode_write_waitq); } + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ; + else + sw_err = inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR; + /* Error detected by uCode */ - if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) || - (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR)) { + if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) || sw_err) { IWL_ERR(trans, "Microcode SW error detected. Restarting 0x%X.\n", inta_fh); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 262795368bfe3..1efb53f78a62f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1062,7 +1062,7 @@ struct iwl_causes_list { u8 addr; }; -static struct iwl_causes_list causes_list[] = { +static const struct iwl_causes_list causes_list_common[] = { {MSIX_FH_INT_CAUSES_D2S_CH0_NUM, CSR_MSIX_FH_INT_MASK_AD, 0}, {MSIX_FH_INT_CAUSES_D2S_CH1_NUM, CSR_MSIX_FH_INT_MASK_AD, 0x1}, {MSIX_FH_INT_CAUSES_S2D, CSR_MSIX_FH_INT_MASK_AD, 0x3}, @@ -1073,30 +1073,50 @@ static struct iwl_causes_list causes_list[] = { {MSIX_HW_INT_CAUSES_REG_CT_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x16}, {MSIX_HW_INT_CAUSES_REG_RF_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x17}, {MSIX_HW_INT_CAUSES_REG_PERIODIC, CSR_MSIX_HW_INT_MASK_AD, 0x18}, - {MSIX_HW_INT_CAUSES_REG_SW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x29}, {MSIX_HW_INT_CAUSES_REG_SCD, CSR_MSIX_HW_INT_MASK_AD, 0x2A}, {MSIX_HW_INT_CAUSES_REG_FH_TX, CSR_MSIX_HW_INT_MASK_AD, 0x2B}, {MSIX_HW_INT_CAUSES_REG_HW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x2D}, {MSIX_HW_INT_CAUSES_REG_HAP, CSR_MSIX_HW_INT_MASK_AD, 0x2E}, }; +static const struct iwl_causes_list causes_list_pre_bz[] = { + {MSIX_HW_INT_CAUSES_REG_SW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x29}, +}; + +static const struct iwl_causes_list causes_list_bz[] = { + {MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ, CSR_MSIX_HW_INT_MASK_AD, 0x29}, +}; + +static void iwl_pcie_map_list(struct iwl_trans *trans, + const struct iwl_causes_list *causes, + int arr_size, int val) +{ + int i; + + for (i = 0; i < arr_size; i++) { + iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val); + iwl_clear_bit(trans, causes[i].mask_reg, + causes[i].cause_num); + } +} + static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE; - int i, arr_size = ARRAY_SIZE(causes_list); - struct iwl_causes_list *causes = causes_list; - /* * Access all non RX causes and map them to the default irq. * In case we are missing at least one interrupt vector, * the first interrupt vector will serve non-RX and FBQ causes. */ - for (i = 0; i < arr_size; i++) { - iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val); - iwl_clear_bit(trans, causes[i].mask_reg, - causes[i].cause_num); - } + iwl_pcie_map_list(trans, causes_list_common, + ARRAY_SIZE(causes_list_common), val); + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + iwl_pcie_map_list(trans, causes_list_bz, + ARRAY_SIZE(causes_list_bz), val); + else + iwl_pcie_map_list(trans, causes_list_pre_bz, + ARRAY_SIZE(causes_list_pre_bz), val); } static void iwl_pcie_map_rx_causes(struct iwl_trans *trans) @@ -3384,7 +3404,10 @@ static void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans) if (trans_pcie->msix_enabled) { inta_addr = CSR_MSIX_HW_INT_CAUSES_AD; - sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR; + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) + sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ; + else + sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR; } else { inta_addr = CSR_INT; sw_err_bit = CSR_INT_BIT_SW_ERR; From 97f8a3d1610b1f50013de1e632b007cbfd7459d8 Mon Sep 17 00:00:00 2001 From: Ayala Barazani Date: Sun, 24 Oct 2021 16:55:04 +0300 Subject: [PATCH 097/114] iwlwifi: ACPI: support revision 3 WGDS tables There's a new revision of the WGDS table with more data, and corresponding firmware API to pass it through. Add support for both. Since we now support 4 different versions, make a table to load them instead of hard-coding it all. Signed-off-by: Ayala Barazani Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.2f9b8e304f25.If88d2d1309270e659d4845c5b5c22d5e8d8e2caf@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 142 +++++++++++++----- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 39 +++-- .../net/wireless/intel/iwlwifi/fw/api/power.h | 35 ++++- .../net/wireless/intel/iwlwifi/fw/runtime.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 44 +++++- 5 files changed, 193 insertions(+), 69 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 1efac0b2a94d7..4602e74d176da 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -184,9 +184,11 @@ int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func, } IWL_EXPORT_SYMBOL(iwl_acpi_get_dsm_u32); -union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, - union acpi_object *data, - int data_size, int *tbl_rev) +union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev, + union acpi_object *data, + int min_data_size, + int max_data_size, + int *tbl_rev) { int i; union acpi_object *wifi_pkg; @@ -196,7 +198,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, * describes the domain, and one more entry, otherwise there's * no point in reading it. */ - if (WARN_ON_ONCE(data_size < 2)) + if (WARN_ON_ONCE(min_data_size < 2 || min_data_size > max_data_size)) return ERR_PTR(-EINVAL); /* @@ -222,7 +224,8 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, /* skip entries that are not a package with the right size */ if (wifi_pkg->type != ACPI_TYPE_PACKAGE || - wifi_pkg->package.count != data_size) + wifi_pkg->package.count < min_data_size || + wifi_pkg->package.count > max_data_size) continue; domain = &wifi_pkg->package.elements[0]; @@ -236,7 +239,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, found: return wifi_pkg; } -IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg); +IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg_range); int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 *block_list_array, @@ -707,49 +710,103 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt) { union acpi_object *wifi_pkg, *data; int i, j, k, ret, tbl_rev; - int idx = 1; /* start from one to skip the domain */ - u8 num_bands; + u8 num_bands, num_profiles; + static const struct { + u8 revisions; + u8 bands; + u8 profiles; + u8 min_profiles; + } rev_data[] = { + { + .revisions = BIT(3), + .bands = ACPI_GEO_NUM_BANDS_REV2, + .profiles = ACPI_NUM_GEO_PROFILES_REV3, + .min_profiles = 3, + }, + { + .revisions = BIT(2), + .bands = ACPI_GEO_NUM_BANDS_REV2, + .profiles = ACPI_NUM_GEO_PROFILES, + }, + { + .revisions = BIT(0) | BIT(1), + .bands = ACPI_GEO_NUM_BANDS_REV0, + .profiles = ACPI_NUM_GEO_PROFILES, + }, + }; + int idx; + /* start from one to skip the domain */ + int entry_idx = 1; + + BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES_REV3 != IWL_NUM_GEO_PROFILES_V3); + BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES != IWL_NUM_GEO_PROFILES); data = iwl_acpi_get_object(fwrt->dev, ACPI_WGDS_METHOD); if (IS_ERR(data)) return PTR_ERR(data); - /* start by trying to read revision 2 */ - wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, - ACPI_WGDS_WIFI_DATA_SIZE_REV2, - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 2) { - ret = PTR_ERR(wifi_pkg); - goto out_free; - } - - num_bands = ACPI_GEO_NUM_BANDS_REV2; - - goto read_table; - } - - /* then try revision 0 (which is the same as 1) */ - wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, - ACPI_WGDS_WIFI_DATA_SIZE_REV0, - &tbl_rev); - if (!IS_ERR(wifi_pkg)) { - if (tbl_rev != 0 && tbl_rev != 1) { - ret = PTR_ERR(wifi_pkg); - goto out_free; + /* read the highest revision we understand first */ + for (idx = 0; idx < ARRAY_SIZE(rev_data); idx++) { + /* min_profiles != 0 requires num_profiles header */ + u32 hdr_size = 1 + !!rev_data[idx].min_profiles; + u32 profile_size = ACPI_GEO_PER_CHAIN_SIZE * + rev_data[idx].bands; + u32 max_size = hdr_size + profile_size * rev_data[idx].profiles; + u32 min_size; + + if (!rev_data[idx].min_profiles) + min_size = max_size; + else + min_size = hdr_size + + profile_size * rev_data[idx].min_profiles; + + wifi_pkg = iwl_acpi_get_wifi_pkg_range(fwrt->dev, data, + min_size, max_size, + &tbl_rev); + if (!IS_ERR(wifi_pkg)) { + if (!(BIT(tbl_rev) & rev_data[idx].revisions)) + continue; + + num_bands = rev_data[idx].bands; + num_profiles = rev_data[idx].profiles; + + if (rev_data[idx].min_profiles) { + /* read header that says # of profiles */ + union acpi_object *entry; + + entry = &wifi_pkg->package.elements[entry_idx]; + entry_idx++; + if (entry->type != ACPI_TYPE_INTEGER || + entry->integer.value > num_profiles) { + ret = -EINVAL; + goto out_free; + } + num_profiles = entry->integer.value; + + /* + * this also validates >= min_profiles since we + * otherwise wouldn't have gotten the data when + * looking up in ACPI + */ + if (wifi_pkg->package.count != + min_size + profile_size * num_profiles) { + ret = -EINVAL; + goto out_free; + } + } + goto read_table; } - - num_bands = ACPI_GEO_NUM_BANDS_REV0; - - goto read_table; } - ret = PTR_ERR(wifi_pkg); + if (idx < ARRAY_SIZE(rev_data)) + ret = PTR_ERR(wifi_pkg); + else + ret = -ENOENT; goto out_free; read_table: fwrt->geo_rev = tbl_rev; - for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) { + for (i = 0; i < num_profiles; i++) { for (j = 0; j < ACPI_GEO_NUM_BANDS_REV2; j++) { union acpi_object *entry; @@ -762,7 +819,8 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt) fwrt->geo_profiles[i].bands[j].max = fwrt->geo_profiles[i].bands[1].max; } else { - entry = &wifi_pkg->package.elements[idx++]; + entry = &wifi_pkg->package.elements[entry_idx]; + entry_idx++; if (entry->type != ACPI_TYPE_INTEGER || entry->integer.value > U8_MAX) { ret = -EINVAL; @@ -779,7 +837,8 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt) fwrt->geo_profiles[i].bands[j].chains[k] = fwrt->geo_profiles[i].bands[1].chains[k]; } else { - entry = &wifi_pkg->package.elements[idx++]; + entry = &wifi_pkg->package.elements[entry_idx]; + entry_idx++; if (entry->type != ACPI_TYPE_INTEGER || entry->integer.value > U8_MAX) { ret = -EINVAL; @@ -822,14 +881,15 @@ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt) IWL_EXPORT_SYMBOL(iwl_sar_geo_support); int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, - struct iwl_per_chain_offset *table, u32 n_bands) + struct iwl_per_chain_offset *table, + u32 n_bands, u32 n_profiles) { int i, j; if (!iwl_sar_geo_support(fwrt)) return -EOPNOTSUPP; - for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) { + for (i = 0; i < n_profiles; i++) { for (j = 0; j < n_bands; j++) { struct iwl_per_chain_offset *chain = &table[i * n_bands + j]; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 0822c6b15c43e..a30b95a011440 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -29,6 +29,7 @@ #define ACPI_SAR_PROFILE_NUM 4 #define ACPI_NUM_GEO_PROFILES 3 +#define ACPI_NUM_GEO_PROFILES_REV3 8 #define ACPI_GEO_PER_CHAIN_SIZE 3 #define ACPI_SAR_NUM_CHAINS_REV0 2 @@ -59,13 +60,6 @@ #define ACPI_GEO_NUM_BANDS_REV2 3 #define ACPI_GEO_NUM_CHAINS 2 -#define ACPI_WGDS_WIFI_DATA_SIZE_REV0 (ACPI_NUM_GEO_PROFILES * \ - ACPI_GEO_NUM_BANDS_REV0 * \ - ACPI_GEO_PER_CHAIN_SIZE + 1) -#define ACPI_WGDS_WIFI_DATA_SIZE_REV2 (ACPI_NUM_GEO_PROFILES * \ - ACPI_GEO_NUM_BANDS_REV2 * \ - ACPI_GEO_PER_CHAIN_SIZE + 1) - #define ACPI_WRDD_WIFI_DATA_SIZE 2 #define ACPI_SPLC_WIFI_DATA_SIZE 2 #define ACPI_ECKV_WIFI_DATA_SIZE 2 @@ -159,10 +153,11 @@ int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func, int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func, const guid_t *guid, u32 *value); -union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, - union acpi_object *data, - int data_size, int *tbl_rev); - +union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev, + union acpi_object *data, + int min_data_size, + int max_data_size, + int *tbl_rev); /** * iwl_acpi_get_mcc - read MCC from ACPI, if available * @@ -199,7 +194,8 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt); bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt); int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, - struct iwl_per_chain_offset *table, u32 n_bands); + struct iwl_per_chain_offset *table, + u32 n_bands, u32 n_profiles); int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 *block_list_array, int *block_list_size); @@ -231,10 +227,11 @@ static inline int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func, return -ENOENT; } -static inline union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev, - union acpi_object *data, - int data_size, - int *tbl_rev) +static inline union acpi_object * +iwl_acpi_get_wifi_pkg_range(struct device *dev, + union acpi_object *data, + int min_data_size, int max_data_size, + int *tbl_rev) { return ERR_PTR(-ENOENT); } @@ -294,4 +291,14 @@ static inline __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt } #endif /* CONFIG_ACPI */ + +static inline union acpi_object * +iwl_acpi_get_wifi_pkg(struct device *dev, + union acpi_object *data, + int data_size, int *tbl_rev) +{ + return iwl_acpi_get_wifi_pkg_range(dev, data, data_size, data_size, + tbl_rev); +} + #endif /* __iwl_fw_acpi__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index 86445385f072c..44dd64e78a2cc 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2020 Intel Corporation + * Copyright (C) 2012-2014, 2018-2021 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -378,9 +378,10 @@ struct iwl_dev_tx_power_cmd { }; }; -#define IWL_NUM_GEO_PROFILES 3 -#define IWL_NUM_BANDS_PER_CHAIN_V1 2 -#define IWL_NUM_BANDS_PER_CHAIN_V2 3 +#define IWL_NUM_GEO_PROFILES 3 +#define IWL_NUM_GEO_PROFILES_V3 8 +#define IWL_NUM_BANDS_PER_CHAIN_V1 2 +#define IWL_NUM_BANDS_PER_CHAIN_V2 3 /** * enum iwl_geo_per_chain_offset_operation - type of operation @@ -438,10 +439,36 @@ struct iwl_geo_tx_power_profiles_cmd_v3 { __le32 table_revision; } __packed; /* GEO_TX_POWER_LIMIT_VER_3 */ +/** + * struct iwl_geo_tx_power_profile_cmd_v4 - struct for GEO_TX_POWER_LIMIT cmd. + * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation + * @table: offset profile per band. + * @table_revision: BIOS table revision. + */ +struct iwl_geo_tx_power_profiles_cmd_v4 { + __le32 ops; + struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V1]; + __le32 table_revision; +} __packed; /* GEO_TX_POWER_LIMIT_VER_4 */ + +/** + * struct iwl_geo_tx_power_profile_cmd_v5 - struct for GEO_TX_POWER_LIMIT cmd. + * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation + * @table: offset profile per band. + * @table_revision: BIOS table revision. + */ +struct iwl_geo_tx_power_profiles_cmd_v5 { + __le32 ops; + struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V2]; + __le32 table_revision; +} __packed; /* GEO_TX_POWER_LIMIT_VER_5 */ + union iwl_geo_tx_power_profiles_cmd { struct iwl_geo_tx_power_profiles_cmd_v1 v1; struct iwl_geo_tx_power_profiles_cmd_v2 v2; struct iwl_geo_tx_power_profiles_cmd_v3 v3; + struct iwl_geo_tx_power_profiles_cmd_v4 v4; + struct iwl_geo_tx_power_profiles_cmd_v5 v5; }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index a569ce3c5e961..69799f1ed2c4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -154,7 +154,7 @@ struct iwl_fw_runtime { struct iwl_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM]; u8 sar_chain_a_profile; u8 sar_chain_b_profile; - struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES]; + struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES_REV3]; u32 geo_rev; union iwl_ppag_table_cmd ppag_table; u32 ppag_ver; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 410a8d20d56e2..e64b6468d1a11 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -776,7 +776,11 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) geo_tx_cmd.v1.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_GET_CURRENT_TABLE); - if (cmd_ver == 3) + if (cmd_ver == 5) + len = sizeof(geo_tx_cmd.v5); + else if (cmd_ver == 4) + len = sizeof(geo_tx_cmd.v4); + else if (cmd_ver == 3) len = sizeof(geo_tx_cmd.v3); else if (fw_has_api(&mvm->fwrt.fw->ucode_capa, IWL_UCODE_TLV_API_SAR_TABLE_VER)) @@ -803,7 +807,7 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) resp = (void *)cmd.resp_pkt->data; ret = le32_to_cpu(resp->profile_idx); - if (WARN_ON(ret > ACPI_NUM_GEO_PROFILES)) + if (WARN_ON(ret > ACPI_NUM_GEO_PROFILES_REV3)) ret = -EIO; iwl_free_resp(&cmd); @@ -815,6 +819,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) union iwl_geo_tx_power_profiles_cmd cmd; u16 len; u32 n_bands; + u32 n_profiles; int ret; u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP, GEO_TX_POWER_LIMIT, @@ -823,28 +828,49 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, ops) != offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) || offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) != - offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops)); + offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops) || + offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops) != + offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, ops) || + offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, ops) != + offsetof(struct iwl_geo_tx_power_profiles_cmd_v5, ops)); + /* the ops field is at the same spot for all versions, so set in v1 */ cmd.v1.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES); - if (cmd_ver == 3) { + if (cmd_ver == 5) { + len = sizeof(cmd.v5); + n_bands = ARRAY_SIZE(cmd.v5.table[0]); + n_profiles = ACPI_NUM_GEO_PROFILES_REV3; + } else if (cmd_ver == 4) { + len = sizeof(cmd.v4); + n_bands = ARRAY_SIZE(cmd.v4.table[0]); + n_profiles = ACPI_NUM_GEO_PROFILES_REV3; + } else if (cmd_ver == 3) { len = sizeof(cmd.v3); n_bands = ARRAY_SIZE(cmd.v3.table[0]); + n_profiles = ACPI_NUM_GEO_PROFILES; } else if (fw_has_api(&mvm->fwrt.fw->ucode_capa, IWL_UCODE_TLV_API_SAR_TABLE_VER)) { len = sizeof(cmd.v2); n_bands = ARRAY_SIZE(cmd.v2.table[0]); + n_profiles = ACPI_NUM_GEO_PROFILES; } else { len = sizeof(cmd.v1); n_bands = ARRAY_SIZE(cmd.v1.table[0]); + n_profiles = ACPI_NUM_GEO_PROFILES; } BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, table) != offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) || offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) != - offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table)); + offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table) || + offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table) != + offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, table) || + offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, table) != + offsetof(struct iwl_geo_tx_power_profiles_cmd_v5, table)); /* the table is at the same position for all versions, so set use v1 */ - ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0], n_bands); + ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0], + n_bands, n_profiles); /* * It is a valid scenario to not support SAR, or miss wgds table, @@ -857,7 +883,11 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) * Set the revision on versions that contain it. * This must be done after calling iwl_sar_geo_init(). */ - if (cmd_ver == 3) + if (cmd_ver == 5) + cmd.v5.table_revision = cpu_to_le32(mvm->fwrt.geo_rev); + else if (cmd_ver == 4) + cmd.v4.table_revision = cpu_to_le32(mvm->fwrt.geo_rev); + else if (cmd_ver == 3) cmd.v3.table_revision = cpu_to_le32(mvm->fwrt.geo_rev); else if (fw_has_api(&mvm->fwrt.fw->ucode_capa, IWL_UCODE_TLV_API_SAR_TABLE_VER)) From 3f7320428fa41a4c8be9c6f3d0cc06beeb0b3df8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 16:55:05 +0300 Subject: [PATCH 098/114] iwlwifi: pcie: simplify iwl_pci_find_dev_info() We currently match the list of devices from the start to the end, but then find the *last* match, so we need to look at each and every entry. We don't want to change the semantics ("most generic entry must come first"), so just change the order of matching to be back-to-front, then we can break out once we find a match. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.abd85e1391cb.I7681fe90735044cc1c59f120e8591b7ac125535d@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 3276f04cfd607..c574f041f0969 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1339,10 +1339,9 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device, u16 mac_type, u8 mac_step, u16 rf_type, u8 cdb, u8 rf_id, u8 no_160, u8 cores) { - const struct iwl_dev_info *ret = NULL; int i; - for (i = 0; i < ARRAY_SIZE(iwl_dev_info_table); i++) { + for (i = ARRAY_SIZE(iwl_dev_info_table) - 1; i >= 0; i--) { const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; if (dev_info->device != (u16)IWL_CFG_ANY && @@ -1381,10 +1380,10 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device, dev_info->cores != cores) continue; - ret = dev_info; + return dev_info; } - return ret; + return NULL; } static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) From c66ab56ad90355f20364794d1c6201831a5ceea9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 16:55:06 +0300 Subject: [PATCH 099/114] iwlwifi: dump host monitor data when NIC doesn't init If the NIC cannot be initialized, dump host monitor data so we can analyze properly why it didn't initialize. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024165252.21c90ba4fa5f.I2a30f62aa4685dc7623d3c69838909833c3f435c@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-io.c | 46 ++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index 6e96ee5bc261f..46917b4216b30 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -398,6 +398,47 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf) return 0; } +#define IWL_HOST_MON_BLOCK_PEMON 0x00 +#define IWL_HOST_MON_BLOCK_HIPM 0x22 + +#define IWL_HOST_MON_BLOCK_PEMON_VEC0 0x00 +#define IWL_HOST_MON_BLOCK_PEMON_VEC1 0x01 +#define IWL_HOST_MON_BLOCK_PEMON_WFPM 0x06 + +static void iwl_dump_host_monitor_block(struct iwl_trans *trans, + u32 block, u32 vec, u32 iter) +{ + int i; + + IWL_ERR(trans, "Host monitor block 0x%x vector 0x%x\n", block, vec); + iwl_write32(trans, CSR_MONITOR_CFG_REG, (block << 8) | vec); + for (i = 0; i < iter; i++) + IWL_ERR(trans, " value [iter %d]: 0x%08x\n", + i, iwl_read32(trans, CSR_MONITOR_STATUS_REG)); +} + +static void iwl_dump_host_monitor(struct iwl_trans *trans) +{ + switch (trans->trans_cfg->device_family) { + case IWL_DEVICE_FAMILY_22000: + case IWL_DEVICE_FAMILY_AX210: + IWL_ERR(trans, "CSR_RESET = 0x%x\n", + iwl_read32(trans, CSR_RESET)); + iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON, + IWL_HOST_MON_BLOCK_PEMON_VEC0, 15); + iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON, + IWL_HOST_MON_BLOCK_PEMON_VEC1, 15); + iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON, + IWL_HOST_MON_BLOCK_PEMON_WFPM, 15); + iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_HIPM, + IWL_HOST_MON_BLOCK_PEMON_VEC0, 1); + break; + default: + /* not supported yet */ + return; + } +} + int iwl_finish_nic_init(struct iwl_trans *trans) { const struct iwl_cfg_trans_params *cfg_trans = trans->trans_cfg; @@ -433,9 +474,12 @@ int iwl_finish_nic_init(struct iwl_trans *trans) * and accesses to uCode SRAM. */ err = iwl_poll_bit(trans, CSR_GP_CNTRL, poll_ready, poll_ready, 25000); - if (err < 0) + if (err < 0) { IWL_DEBUG_INFO(trans, "Failed to wake NIC\n"); + iwl_dump_host_monitor(trans); + } + if (cfg_trans->bisr_workaround) { /* ensure BISR shift has finished */ udelay(200); From 91000fdf82195b66350b4f88413c2e8b5f94d994 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 18:20:26 +0300 Subject: [PATCH 100/114] iwlwifi: fw: uefi: add missing include guards We still don't use #pragma once in the kernel, but even if we did it'd be missing. Add the missing include guards. Signed-off-by: Johannes Berg Fixes: 84c3c9952afb ("iwlwifi: move UEFI code to a separate file") Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.7fc9988ed49b.I87e300fab664047581e51fb9b02744c75320d08c@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/uefi.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index 45d0b36d79b5a..d552c656ac9fe 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -2,7 +2,8 @@ /* * Copyright(c) 2021 Intel Corporation */ - +#ifndef __iwl_fw_uefi__ +#define __iwl_fw_uefi__ #define IWL_UEFI_OEM_PNVM_NAME L"UefiCnvWlanOemSignedPnvm" #define IWL_UEFI_REDUCED_POWER_NAME L"UefiCnvWlanReducedPower" @@ -40,3 +41,5 @@ void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len) return ERR_PTR(-EOPNOTSUPP); } #endif /* CONFIG_EFI */ + +#endif /* __iwl_fw_uefi__ */ From 1a5daead217c4b2243e6ab061e19a1190e4325ac Mon Sep 17 00:00:00 2001 From: Mukesh Sisodiya Date: Sun, 24 Oct 2021 18:20:27 +0300 Subject: [PATCH 101/114] iwlwifi: yoyo: support for ROM usniffer Add handling of config set TLV for ROM usniffer support. Signed-off-by: Mukesh Sisodiya Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.507212be427a.I36acb6ca84095963614be70dc944ba0d98ee770c@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/debug.h | 17 ++++ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 92 ++++++++++++++++--- 2 files changed, 94 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index 0abed12df2cb9..029ae64bf2b21 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -379,6 +379,23 @@ struct iwl_dram_info { struct iwl_buf_alloc_cmd dram_frags[IWL_FW_INI_ALLOCATION_NUM - 1]; } __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */ +/** + * struct iwl_dbgc1_info - DBGC1 address and size + * + * Driver will fill the dbcg1 address and size at address based on config TLV. + * + * @first_word: all 0 set as identifier + * @dbgc1_add_lsb: LSB bits of DBGC1 physical address + * @dbgc1_add_msb: MSB bits of DBGC1 physical address + * @dbgc1_size: DBGC1 size +*/ +struct iwl_dbgc1_info { + __le32 first_word; + __le32 dbgc1_add_lsb; + __le32 dbgc1_add_msb; + __le32 dbgc1_size; +} __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */ + /** * struct iwl_dbg_host_event_cfg_cmd * @enabled_severities: enabled severities diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index f487cc8b9fe0b..7ab98b419cc1f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -284,13 +284,6 @@ static int iwl_dbg_tlv_config_set(struct iwl_trans *trans, return -EINVAL; } - if (type != IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM || - trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { - IWL_DEBUG_FW(trans, - "WRT: Config set type %u is not supported\n", type); - return -EINVAL; - } - return iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].config_list); } @@ -812,18 +805,84 @@ static void iwl_dbg_tlv_apply_config(struct iwl_fw_runtime *fwrt, list_for_each_entry(node, config_list, list) { struct iwl_fw_ini_conf_set_tlv *config_list = (void *)node->tlv.data; + u32 count, address, value; + u32 len = (le32_to_cpu(node->tlv.length) - sizeof(*config_list)) / 8; u32 type = le32_to_cpu(config_list->set_type); + u32 offset = le32_to_cpu(config_list->addr_offset); switch (type) { - case IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: { - u32 debug_token_config = - le32_to_cpu(config_list->addr_val[0].value); - - IWL_DEBUG_FW(fwrt, "WRT: Setting HWM debug token config: %u\n", - debug_token_config); - fwrt->trans->dbg.ucode_preset = debug_token_config; - break; + case IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: { + if (!iwl_trans_grab_nic_access(fwrt->trans)) { + IWL_DEBUG_FW(fwrt, "WRT: failed to get nic access\n"); + IWL_DEBUG_FW(fwrt, "WRT: skipping MAC PERIPHERY config\n"); + continue; + } + IWL_DEBUG_FW(fwrt, "WRT: MAC PERIPHERY config len: len %u\n", len); + for (count = 0; count < len; count++) { + address = le32_to_cpu(config_list->addr_val[count].address); + value = le32_to_cpu(config_list->addr_val[count].value); + iwl_trans_write_prph(fwrt->trans, address + offset, value); + } + iwl_trans_release_nic_access(fwrt->trans); + break; + } + case IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY: { + for (count = 0; count < len; count++) { + address = le32_to_cpu(config_list->addr_val[count].address); + value = le32_to_cpu(config_list->addr_val[count].value); + iwl_trans_write_mem32(fwrt->trans, address + offset, value); + IWL_DEBUG_FW(fwrt, "WRT: DEV_MEM: count %u, add: %u val: %u\n", + count, address, value); + } + break; + } + case IWL_FW_INI_CONFIG_SET_TYPE_CSR: { + for (count = 0; count < len; count++) { + address = le32_to_cpu(config_list->addr_val[count].address); + value = le32_to_cpu(config_list->addr_val[count].value); + iwl_write32(fwrt->trans, address + offset, value); + IWL_DEBUG_FW(fwrt, "WRT: CSR: count %u, add: %u val: %u\n", + count, address, value); + } + break; + } + case IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR: { + struct iwl_dbgc1_info dram_info = {}; + struct iwl_dram_data *frags = &fwrt->trans->dbg.fw_mon_ini[1].frags[0]; + __le64 dram_base_addr = cpu_to_le64(frags->physical); + __le32 dram_size = cpu_to_le32(frags->size); + u64 dram_addr = le64_to_cpu(dram_base_addr); + u32 ret; + + IWL_DEBUG_FW(fwrt, "WRT: dram_base_addr 0x%016llx, dram_size 0x%x\n", + dram_base_addr, dram_size); + IWL_DEBUG_FW(fwrt, "WRT: config_list->addr_offset: %u\n", + le32_to_cpu(config_list->addr_offset)); + for (count = 0; count < len; count++) { + address = le32_to_cpu(config_list->addr_val[count].address); + dram_info.dbgc1_add_lsb = + cpu_to_le32((dram_addr & 0x00000000FFFFFFFFULL) + 0x400); + dram_info.dbgc1_add_msb = + cpu_to_le32((dram_addr & 0xFFFFFFFF00000000ULL) >> 32); + dram_info.dbgc1_size = cpu_to_le32(le32_to_cpu(dram_size) - 0x400); + ret = iwl_trans_write_mem(fwrt->trans, + address + offset, &dram_info, 4); + if (ret) { + IWL_ERR(fwrt, "Failed to write dram_info to HW_SMEM\n"); + break; + } } + break; + } + case IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: { + u32 debug_token_config = + le32_to_cpu(config_list->addr_val[0].value); + + IWL_DEBUG_FW(fwrt, "WRT: Setting HWM debug token config: %u\n", + debug_token_config); + fwrt->trans->dbg.ucode_preset = debug_token_config; + break; + } default: break; } @@ -1229,6 +1288,7 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt, case IWL_FW_INI_TIME_POINT_AFTER_ALIVE: iwl_dbg_tlv_apply_buffers(fwrt); iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list); + iwl_dbg_tlv_apply_config(fwrt, conf_list); iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL); break; case IWL_FW_INI_TIME_POINT_PERIODIC: @@ -1239,11 +1299,13 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt, case IWL_FW_INI_TIME_POINT_MISSED_BEACONS: case IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFICATION: iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list); + iwl_dbg_tlv_apply_config(fwrt, conf_list); iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, iwl_dbg_tlv_check_fw_pkt); break; default: iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list); + iwl_dbg_tlv_apply_config(fwrt, conf_list); iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL); break; } From 698b166ed3464e1604a0e6a3e23cc1b529a5adc1 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sun, 24 Oct 2021 18:20:28 +0300 Subject: [PATCH 102/114] iwlwifi: mvm: read 6E enablement flags from DSM and pass to FW We need to call a new DSM function and pass the values to the firmware in order to allow enablement of 6E support by the OEMs via ACPI. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.2fa34d31383c.I6504005c60882c94e6e58f64cab4e42e6481ce08@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index a30b95a011440..4aaa8a6b071ba 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -109,6 +109,7 @@ enum iwl_dsm_funcs_rev_0 { DSM_FUNC_QUERY = 0, DSM_FUNC_DISABLE_SRD = 1, DSM_FUNC_ENABLE_INDONESIA_5G2 = 2, + DSM_FUNC_ENABLE_6E = 3, DSM_FUNC_11AX_ENABLEMENT = 6, DSM_FUNC_ENABLE_UNII4_CHAN = 7, DSM_FUNC_ACTIVATE_CHANNEL = 8 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index e64b6468d1a11..6063b2ffe2665 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1177,7 +1177,6 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) &iwl_guid, &value); if (!ret) cmd.oem_11ax_allow_bitmap = cpu_to_le32(value); - /* apply more config masks here */ ret = iwl_acpi_get_dsm_u32((&mvm->fwrt)->dev, 0, DSM_FUNC_ENABLE_UNII4_CHAN, @@ -1191,7 +1190,14 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) if (!ret) cmd.chan_state_active_bitmap = cpu_to_le32(value); + ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0, + DSM_FUNC_ENABLE_6E, + &iwl_guid, &value); + if (!ret) + cmd.oem_uhb_allow_bitmap = cpu_to_le32(value); + if (cmd.config_bitmap || + cmd.oem_uhb_allow_bitmap || cmd.oem_11ax_allow_bitmap || cmd.oem_unii4_allow_bitmap || cmd.chan_state_active_bitmap) { @@ -1219,6 +1225,9 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) le32_to_cpu(cmd.oem_unii4_allow_bitmap), le32_to_cpu(cmd.chan_state_active_bitmap), cmd_ver); + IWL_DEBUG_RADIO(mvm, + "sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x\n", + le32_to_cpu(cmd.oem_uhb_allow_bitmap)); ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP, LARI_CONFIG_CHANGE), From 45fe1b6b6c999f76975581fe6d4888dad3bbbfd8 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sun, 24 Oct 2021 18:20:29 +0300 Subject: [PATCH 103/114] iwlwifi: mvm: don't get address of mvm->fwrt just to dereference as a pointer The mvm->fwrt element is not a pointer, but an instance of the structure, so we should access its elements with a dot-notation instead of getting the address and dereferencing it as a pointer. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.ce6841093681.I09634a0aa845a0256e79c7895154d9ac35bc26be@changeid 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 6063b2ffe2665..8b96b885658f1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1144,7 +1144,7 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm) static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm) { u8 value; - int ret = iwl_acpi_get_dsm_u8((&mvm->fwrt)->dev, 0, DSM_RFI_FUNC_ENABLE, + int ret = iwl_acpi_get_dsm_u8(mvm->fwrt.dev, 0, DSM_RFI_FUNC_ENABLE, &iwl_rfi_guid, &value); if (ret < 0) { @@ -1173,18 +1173,18 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) cmd.config_bitmap = iwl_acpi_get_lari_config_bitmap(&mvm->fwrt); - ret = iwl_acpi_get_dsm_u32((&mvm->fwrt)->dev, 0, DSM_FUNC_11AX_ENABLEMENT, + ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0, DSM_FUNC_11AX_ENABLEMENT, &iwl_guid, &value); if (!ret) cmd.oem_11ax_allow_bitmap = cpu_to_le32(value); - ret = iwl_acpi_get_dsm_u32((&mvm->fwrt)->dev, 0, + ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0, DSM_FUNC_ENABLE_UNII4_CHAN, &iwl_guid, &value); if (!ret) cmd.oem_unii4_allow_bitmap = cpu_to_le32(value); - ret = iwl_acpi_get_dsm_u32((&mvm->fwrt)->dev, 0, + ret = iwl_acpi_get_dsm_u32(mvm->fwrt.dev, 0, DSM_FUNC_ACTIVATE_CHANNEL, &iwl_guid, &value); if (!ret) From 9da090cdbcfa1ef864bfcbad9ad7e18691395867 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Sun, 24 Oct 2021 18:20:30 +0300 Subject: [PATCH 104/114] iwlwifi: mvm: update RFI TLV RFI TLV was moved in FW from set3 to set1 due to FW internal dependency. Adjust driver to this change. Signed-off-by: Gregory Greenman Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.90e42cd8cb37.I89ac9910e38006a2e5c9e87d371a8507f475572d@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 565918054ed19..3d572f5024bbc 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -421,6 +421,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)59, IWL_UCODE_TLV_CAPA_BROADCAST_TWT = (__force iwl_ucode_tlv_capa_t)60, IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO = (__force iwl_ucode_tlv_capa_t)61, + IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)62, /* set 2 */ IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, @@ -454,7 +455,6 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)98, IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT = (__force iwl_ucode_tlv_capa_t)100, - IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)102, IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT = (__force iwl_ucode_tlv_capa_t)104, #ifdef __CHECKER__ From 4d4cbb9b8e56394d18ec3be3744ae84e9797a865 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 18:20:31 +0300 Subject: [PATCH 105/114] iwlwifi: mvm: d3: use internal data representation Trying to convert from one firmware data representation to the next version is getting tedious and error-prone, and doesn't lend itself well to new APIs being added. Additionally, the version 11 of the API as defined in the driver doesn't even exist in the firmware. Instead of converting to a newer firmware version of the data, convert to an internal representation. This takes a bit more space because the TKIP/AES counters etc. must be kept twice, their representation is different and we don't know which of the ones it is until later, but this is just a temporary use of memory, and the code is clearer this way. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.9e71630627f3.Iad975e15338844ca068683f62a51eb1fcb69e608@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/d3.h | 43 --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 357 +++++++++++------- 2 files changed, 212 insertions(+), 188 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index e199d1813a613..1503119ea910a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -693,49 +693,6 @@ struct iwl_wowlan_status_v9 { u8 wake_packet[]; /* can be truncated from _length to _bufsize */ } __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_9 */ -/** - * struct iwl_wowlan_status - WoWLAN status - * @gtk: GTK data - * @igtk: IGTK data - * @bigtk: BIGTK data - * @replay_ctr: GTK rekey replay counter - * @pattern_number: number of the matched pattern - * @non_qos_seq_ctr: non-QoS sequence counter to use next - * @qos_seq_ctr: QoS sequence counters to use next - * @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason - * @num_of_gtk_rekeys: number of GTK rekeys - * @tid_tear_down: bitmap of TIDs torn down - * @reserved: reserved - * @received_beacons: number of received beacons - * @wake_packet_length: wakeup packet length - * @wake_packet_bufsize: wakeup packet buffer size - * @tid_tear_down: bit mask of tids whose BA sessions were closed - * in suspend state - * @wake_packet: wakeup packet - */ -struct iwl_wowlan_status { - struct iwl_wowlan_gtk_status gtk[1]; - struct iwl_wowlan_igtk_status igtk[1]; - struct iwl_wowlan_igtk_status bigtk[WOWLAN_IGTK_KEYS_NUM]; - __le64 replay_ctr; - __le16 pattern_number; - __le16 non_qos_seq_ctr; - __le16 qos_seq_ctr[8]; - __le32 wakeup_reasons; - __le32 num_of_gtk_rekeys; - u8 tid_tear_down; - u8 reserved[3]; - __le32 received_beacons; - __le32 wake_packet_length; - __le32 wake_packet_bufsize; - u8 wake_packet[]; /* can be truncated from _length to _bufsize */ -} __packed; /* WOWLAN_STATUSES_API_S_VER_11 */ - -static inline u8 iwlmvm_wowlan_gtk_idx(struct iwl_wowlan_gtk_status *gtk) -{ - return gtk->key_flags & IWL_WOWLAN_GTK_IDX_MASK; -} - /* TODO: NetDetect API */ #endif /* __iwl_fw_api_d3_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index d3013a51a5096..a19f646a324f4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1379,12 +1379,49 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* converted data from the different status responses */ struct iwl_wowlan_status_data { - u16 pattern_number; - u16 qos_seq_ctr[8]; + u64 replay_ctr; + u32 num_of_gtk_rekeys; + u32 received_beacons; u32 wakeup_reasons; u32 wake_packet_length; u32 wake_packet_bufsize; - const u8 *wake_packet; + u16 pattern_number; + u16 non_qos_seq_ctr; + u16 qos_seq_ctr[8]; + u8 tid_tear_down; + + struct { + /* + * We store both the TKIP and AES representations + * coming from the firmware because we decode the + * data from there before we iterate the keys and + * know which one we need. + */ + struct { + struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT]; + } tkip, aes; + /* including RX MIC key for TKIP */ + u8 key[WOWLAN_KEY_MAX_SIZE]; + u8 len; + u8 flags; + } gtk; + + struct { + /* Same as above */ + struct { + struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT]; + u64 tx_pn; + } tkip, aes; + } ptk; + + struct { + u64 ipn; + u8 key[WOWLAN_KEY_MAX_SIZE]; + u8 len; + u8 flags; + } igtk; + + u8 wake_packet[]; }; static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, @@ -1540,77 +1577,90 @@ static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc, seq->tkip.iv16 = le16_to_cpu(sc->iv16); } -static void iwl_mvm_set_aes_rx_seq(struct iwl_mvm *mvm, struct aes_sc *scs, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) +static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq) { int tid; - BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS); + for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) + ieee80211_set_key_rx_seq(key, tid, &seq[tid]); +} - if (sta && iwl_mvm_has_new_rx_api(mvm)) { - struct iwl_mvm_sta *mvmsta; - struct iwl_mvm_key_pn *ptk_pn; +static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm, + struct iwl_wowlan_status_data *status, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + struct iwl_mvm_key_pn *ptk_pn; + int tid; - mvmsta = iwl_mvm_sta_from_mac80211(sta); + iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq); - rcu_read_lock(); - ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]); - if (WARN_ON(!ptk_pn)) { - rcu_read_unlock(); - return; - } + if (!iwl_mvm_has_new_rx_api(mvm)) + return; - for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { - struct ieee80211_key_seq seq = {}; - int i; - iwl_mvm_aes_sc_to_seq(&scs[tid], &seq); - ieee80211_set_key_rx_seq(key, tid, &seq); - for (i = 1; i < mvm->trans->num_rx_queues; i++) - memcpy(ptk_pn->q[i].pn[tid], - seq.ccmp.pn, IEEE80211_CCMP_PN_LEN); - } + rcu_read_lock(); + ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]); + if (WARN_ON(!ptk_pn)) { rcu_read_unlock(); - } else { - for (tid = 0; tid < IWL_NUM_RSC; tid++) { - struct ieee80211_key_seq seq = {}; + return; + } - iwl_mvm_aes_sc_to_seq(&scs[tid], &seq); - ieee80211_set_key_rx_seq(key, tid, &seq); - } + for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { + int i; + + for (i = 1; i < mvm->trans->num_rx_queues; i++) + memcpy(ptk_pn->q[i].pn[tid], + status->ptk.aes.seq[tid].ccmp.pn, + IEEE80211_CCMP_PN_LEN); } + rcu_read_unlock(); } -static void iwl_mvm_set_tkip_rx_seq(struct tkip_sc *scs, - struct ieee80211_key_conf *key) +static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status, + union iwl_all_tsc_rsc *sc) { - int tid; + int i; - BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS); + BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT); + BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC); - for (tid = 0; tid < IWL_NUM_RSC; tid++) { - struct ieee80211_key_seq seq = {}; + /* GTK RX counters */ + for (i = 0; i < IWL_MAX_TID_COUNT; i++) { + iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i], + &status->gtk.tkip.seq[i]); + iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i], + &status->gtk.aes.seq[i]); + } - iwl_mvm_tkip_sc_to_seq(&scs[tid], &seq); - ieee80211_set_key_rx_seq(key, tid, &seq); + /* PTK TX counter */ + status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) | + ((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16); + status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn); + + /* PTK RX counters */ + for (i = 0; i < IWL_MAX_TID_COUNT; i++) { + iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i], + &status->ptk.tkip.seq[i]); + iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i], + &status->ptk.aes.seq[i]); } } static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm, struct ieee80211_key_conf *key, - struct iwl_wowlan_status *status) + struct iwl_wowlan_status_data *status) { - union iwl_all_tsc_rsc *rsc = &status->gtk[0].rsc.all_tsc_rsc; - switch (key->cipher) { case WLAN_CIPHER_SUITE_CCMP: case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP_256: - iwl_mvm_set_aes_rx_seq(mvm, rsc->aes.multicast_rsc, NULL, key); + iwl_mvm_set_key_rx_seq_tids(key, status->gtk.aes.seq); break; case WLAN_CIPHER_SUITE_TKIP: - iwl_mvm_set_tkip_rx_seq(rsc->tkip.multicast_rsc, key); + iwl_mvm_set_key_rx_seq_tids(key, status->gtk.tkip.seq); break; default: WARN_ON(1); @@ -1619,7 +1669,7 @@ static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm, struct iwl_mvm_d3_gtk_iter_data { struct iwl_mvm *mvm; - struct iwl_wowlan_status *status; + struct iwl_wowlan_status_data *status; void *last_gtk; u32 cipher; bool find_phase, unhandled_cipher; @@ -1633,6 +1683,7 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw, void *_data) { struct iwl_mvm_d3_gtk_iter_data *data = _data; + struct iwl_wowlan_status_data *status = data->status; if (data->unhandled_cipher) return; @@ -1661,10 +1712,6 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw, * note that this assumes no TDLS sessions are active */ if (sta) { - struct ieee80211_key_seq seq = {}; - union iwl_all_tsc_rsc *sc = - &data->status->gtk[0].rsc.all_tsc_rsc; - if (data->find_phase) return; @@ -1672,16 +1719,12 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw, case WLAN_CIPHER_SUITE_CCMP: case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP_256: - iwl_mvm_set_aes_rx_seq(data->mvm, sc->aes.unicast_rsc, - sta, key); - atomic64_set(&key->tx_pn, le64_to_cpu(sc->aes.tsc.pn)); + atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn); + iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key); break; case WLAN_CIPHER_SUITE_TKIP: - iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq); - iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key); - atomic64_set(&key->tx_pn, - (u64)seq.tkip.iv16 | - ((u64)seq.tkip.iv32 << 16)); + atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn); + iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq); break; } @@ -1703,7 +1746,7 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw, static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_wowlan_status *status) + struct iwl_wowlan_status_data *status) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_d3_gtk_iter_data gtkdata = { @@ -1717,7 +1760,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, if (!status || !vif->bss_conf.bssid) return false; - if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons) + if (status->wakeup_reasons & disconnection_reasons) return false; /* find last GTK that we used initially, if any */ @@ -1741,7 +1784,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, iwl_mvm_d3_update_keys, >kdata); IWL_DEBUG_WOWLAN(mvm, "num of GTK rekeying %d\n", - le32_to_cpu(status->num_of_gtk_rekeys)); + status->num_of_gtk_rekeys); if (status->num_of_gtk_rekeys) { struct ieee80211_key_conf *key; struct { @@ -1750,36 +1793,32 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, } conf = { .conf.cipher = gtkdata.cipher, .conf.keyidx = - iwlmvm_wowlan_gtk_idx(&status->gtk[0]), + status->gtk.flags & IWL_WOWLAN_GTK_IDX_MASK, }; __be64 replay_ctr; IWL_DEBUG_WOWLAN(mvm, "Received from FW GTK cipher %d, key index %d\n", conf.conf.cipher, conf.conf.keyidx); + + BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP); + BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP); + BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256); + BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP); + BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk.key)); + + memcpy(conf.conf.key, status->gtk.key, sizeof(status->gtk.key)); + switch (gtkdata.cipher) { case WLAN_CIPHER_SUITE_CCMP: case WLAN_CIPHER_SUITE_GCMP: - BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP); - BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP); conf.conf.keylen = WLAN_KEY_LEN_CCMP; - memcpy(conf.conf.key, status->gtk[0].key, - WLAN_KEY_LEN_CCMP); break; case WLAN_CIPHER_SUITE_GCMP_256: - BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256); conf.conf.keylen = WLAN_KEY_LEN_GCMP_256; - memcpy(conf.conf.key, status->gtk[0].key, - WLAN_KEY_LEN_GCMP_256); break; case WLAN_CIPHER_SUITE_TKIP: - BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP); conf.conf.keylen = WLAN_KEY_LEN_TKIP; - memcpy(conf.conf.key, status->gtk[0].key, 16); - /* leave TX MIC key zeroed, we don't use it anyway */ - memcpy(conf.conf.key + - NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, - status->gtk[0].tkip_mic_key, 8); break; } @@ -1788,8 +1827,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, return false; iwl_mvm_set_key_rx_seq(mvm, key, status); - replay_ctr = - cpu_to_be64(le64_to_cpu(status->replay_ctr)); + replay_ctr = cpu_to_be64(status->replay_ctr); ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, (void *)&replay_ctr, GFP_KERNEL); @@ -1800,7 +1838,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, WOWLAN_GET_STATUSES, 0) < 10) { mvmvif->seqno_valid = true; /* +0x10 because the set API expects next-to-use, not last-used */ - mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10; + mvmvif->seqno = status->non_qos_seq_ctr + 0x10; } return true; @@ -1808,13 +1846,13 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, /* Occasionally, templates would be nice. This is one of those times ... */ #define iwl_mvm_parse_wowlan_status_common(_ver) \ -static struct iwl_wowlan_status * \ +static struct iwl_wowlan_status_data * \ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \ - void *_data, int len) \ + struct iwl_wowlan_status_ ##_ver *data,\ + int len) \ { \ - struct iwl_wowlan_status *status; \ - struct iwl_wowlan_status_ ##_ver *data = _data; \ - int data_size; \ + struct iwl_wowlan_status_data *status; \ + int data_size, i; \ \ if (len < sizeof(*data)) { \ IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); \ @@ -1832,18 +1870,22 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \ return ERR_PTR(-ENOMEM); \ \ /* copy all the common fields */ \ - status->replay_ctr = data->replay_ctr; \ - status->pattern_number = data->pattern_number; \ - status->non_qos_seq_ctr = data->non_qos_seq_ctr; \ - memcpy(status->qos_seq_ctr, data->qos_seq_ctr, \ - sizeof(status->qos_seq_ctr)); \ - status->wakeup_reasons = data->wakeup_reasons; \ - status->num_of_gtk_rekeys = data->num_of_gtk_rekeys; \ - status->received_beacons = data->received_beacons; \ - status->wake_packet_length = data->wake_packet_length; \ - status->wake_packet_bufsize = data->wake_packet_bufsize; \ + status->replay_ctr = le64_to_cpu(data->replay_ctr); \ + status->pattern_number = le16_to_cpu(data->pattern_number); \ + status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr); \ + for (i = 0; i < 8; i++) \ + status->qos_seq_ctr[i] = \ + le16_to_cpu(data->qos_seq_ctr[i]); \ + status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); \ + status->num_of_gtk_rekeys = \ + le32_to_cpu(data->num_of_gtk_rekeys); \ + status->received_beacons = le32_to_cpu(data->received_beacons); \ + status->wake_packet_length = \ + le32_to_cpu(data->wake_packet_length); \ + status->wake_packet_bufsize = \ + le32_to_cpu(data->wake_packet_bufsize); \ memcpy(status->wake_packet, data->wake_packet, \ - le32_to_cpu(status->wake_packet_bufsize)); \ + status->wake_packet_bufsize); \ \ return status; \ } @@ -1852,10 +1894,49 @@ iwl_mvm_parse_wowlan_status_common(v6) iwl_mvm_parse_wowlan_status_common(v7) iwl_mvm_parse_wowlan_status_common(v9) -static struct iwl_wowlan_status * +static void iwl_mvm_convert_gtk(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_gtk_status *data) +{ + BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key)); + BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY + + sizeof(data->tkip_mic_key) > + sizeof(status->gtk.key)); + + status->gtk.len = data->key_len; + status->gtk.flags = data->key_flags; + + memcpy(status->gtk.key, data->key, sizeof(data->key)); + + /* if it's as long as the TKIP encryption key, copy MIC key */ + if (status->gtk.len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) + memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, + data->tkip_mic_key, sizeof(data->tkip_mic_key)); +} + +static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_igtk_status *data) +{ + const u8 *ipn = data->ipn; + + BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key)); + + status->igtk.len = data->key_len; + status->igtk.flags = data->key_flags; + + memcpy(status->igtk.key, data->key, sizeof(data->key)); + + status->igtk.ipn = ((u64)ipn[5] << 0) | + ((u64)ipn[4] << 8) | + ((u64)ipn[3] << 16) | + ((u64)ipn[2] << 24) | + ((u64)ipn[1] << 32) | + ((u64)ipn[0] << 40); +} + +static struct iwl_wowlan_status_data * iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id) { - struct iwl_wowlan_status *status; + struct iwl_wowlan_status_data *status; struct iwl_wowlan_get_status_cmd get_status_cmd = { .sta_id = cpu_to_le32(sta_id), }; @@ -1895,59 +1976,57 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id) IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) { struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data; - status = iwl_mvm_parse_wowlan_status_common_v6(mvm, - cmd.resp_pkt->data, - len); + status = iwl_mvm_parse_wowlan_status_common_v6(mvm, v6, len); if (IS_ERR(status)) goto out_free_resp; BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) > - sizeof(status->gtk[0].key)); - BUILD_BUG_ON(sizeof(v6->gtk.tkip_mic_key) > - sizeof(status->gtk[0].tkip_mic_key)); + sizeof(status->gtk.key)); + BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY + + sizeof(v6->gtk.tkip_mic_key) > + sizeof(status->gtk.key)); /* copy GTK info to the right place */ - memcpy(status->gtk[0].key, v6->gtk.decrypt_key, + memcpy(status->gtk.key, v6->gtk.decrypt_key, sizeof(v6->gtk.decrypt_key)); - memcpy(status->gtk[0].tkip_mic_key, v6->gtk.tkip_mic_key, + memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, + v6->gtk.tkip_mic_key, sizeof(v6->gtk.tkip_mic_key)); - memcpy(&status->gtk[0].rsc, &v6->gtk.rsc, - sizeof(status->gtk[0].rsc)); + + iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc); /* hardcode the key length to 16 since v6 only supports 16 */ - status->gtk[0].key_len = 16; + status->gtk.len = 16; /* * The key index only uses 2 bits (values 0 to 3) and * we always set bit 7 which means this is the * currently used key. */ - status->gtk[0].key_flags = v6->gtk.key_index | BIT(7); + status->gtk.flags = v6->gtk.key_index | BIT(7); } else if (notif_ver == 7) { struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data; - status = iwl_mvm_parse_wowlan_status_common_v7(mvm, - cmd.resp_pkt->data, - len); + status = iwl_mvm_parse_wowlan_status_common_v7(mvm, v7, len); if (IS_ERR(status)) goto out_free_resp; - status->gtk[0] = v7->gtk[0]; - status->igtk[0] = v7->igtk[0]; + iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc); + iwl_mvm_convert_gtk(status, &v7->gtk[0]); + iwl_mvm_convert_igtk(status, &v7->igtk[0]); } else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) { struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data; /* these three command versions have same layout and size, the * difference is only in a few not used (reserved) fields. */ - status = iwl_mvm_parse_wowlan_status_common_v9(mvm, - cmd.resp_pkt->data, - len); + status = iwl_mvm_parse_wowlan_status_common_v9(mvm, v9, len); if (IS_ERR(status)) goto out_free_resp; - status->gtk[0] = v9->gtk[0]; - status->igtk[0] = v9->igtk[0]; + iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc); + iwl_mvm_convert_gtk(status, &v9->gtk[0]); + iwl_mvm_convert_igtk(status, &v9->igtk[0]); status->tid_tear_down = v9->tid_tear_down; } else { @@ -1962,7 +2041,7 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id) return status; } -static struct iwl_wowlan_status * +static struct iwl_wowlan_status_data * iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, u8 sta_id) { u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, @@ -1987,29 +2066,17 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_wowlan_status_data status; - struct iwl_wowlan_status *fw_status; + struct iwl_wowlan_status_data *status; int i; bool keep; struct iwl_mvm_sta *mvm_ap_sta; - fw_status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id); - if (IS_ERR_OR_NULL(fw_status)) + status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id); + if (IS_ERR(status)) goto out_unlock; IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n", - le32_to_cpu(fw_status->wakeup_reasons)); - - status.pattern_number = le16_to_cpu(fw_status->pattern_number); - for (i = 0; i < 8; i++) - status.qos_seq_ctr[i] = - le16_to_cpu(fw_status->qos_seq_ctr[i]); - status.wakeup_reasons = le32_to_cpu(fw_status->wakeup_reasons); - status.wake_packet_length = - le32_to_cpu(fw_status->wake_packet_length); - status.wake_packet_bufsize = - le32_to_cpu(fw_status->wake_packet_bufsize); - status.wake_packet = fw_status->wake_packet; + status->wakeup_reasons); /* still at hard-coded place 0 for D3 image */ mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0); @@ -2017,7 +2084,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, goto out_free; for (i = 0; i < IWL_MAX_TID_COUNT; i++) { - u16 seq = status.qos_seq_ctr[i]; + u16 seq = status->qos_seq_ctr[i]; /* firmware stores last-used value, we store next value */ seq += 0x10; mvm_ap_sta->tid_data[i].seq_number = seq; @@ -2033,15 +2100,15 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, /* now we have all the data we need, unlock to avoid mac80211 issues */ mutex_unlock(&mvm->mutex); - iwl_mvm_report_wakeup_reasons(mvm, vif, &status); + iwl_mvm_report_wakeup_reasons(mvm, vif, status); - keep = iwl_mvm_setup_connection_keep(mvm, vif, fw_status); + keep = iwl_mvm_setup_connection_keep(mvm, vif, status); - kfree(fw_status); + kfree(status); return keep; out_free: - kfree(fw_status); + kfree(status); out_unlock: mutex_unlock(&mvm->mutex); return false; @@ -2165,16 +2232,16 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, .pattern_idx = -1, }; struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; + struct iwl_wowlan_status_data *status; struct iwl_mvm_nd_query_results query; - struct iwl_wowlan_status *fw_status; unsigned long matched_profiles; u32 reasons = 0; int i, n_matches, ret; - fw_status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA); - if (!IS_ERR_OR_NULL(fw_status)) { - reasons = le32_to_cpu(fw_status->wakeup_reasons); - kfree(fw_status); + status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA); + if (!IS_ERR(status)) { + reasons = status->wakeup_reasons; + kfree(status); } if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) From 523de6c872ca89e2a636f5c03ab48fc0769e132b Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sun, 24 Oct 2021 18:20:32 +0300 Subject: [PATCH 106/114] iwlwifi: rename GEO_TX_POWER_LIMIT to PER_CHAIN_LIMIT_OFFSET_CMD When this code was implemented, there was no official FW API description yet, so a placeholder name was used (GEO_TX_POWER_LIMIT). But then the command became actually called PER_CHAIN_LIMIT_OFFSET_CMD. Rename the command (and change related comments) to PER_CHAIN_LIMIT_OFFSET_CMD to avoid confusion. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.672fa727ef75.I6572df5d1e3441a0214993a59985da9a9431f3e5@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 8 +++--- .../net/wireless/intel/iwlwifi/fw/api/phy.h | 6 ++-- .../net/wireless/intel/iwlwifi/fw/api/power.h | 28 +++++++++---------- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 9 +++--- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 4602e74d176da..bf431fa4fe81f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -862,10 +862,10 @@ IWL_EXPORT_SYMBOL(iwl_sar_get_wgds_table); bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt) { /* - * The GEO_TX_POWER_LIMIT command is not supported on earlier - * firmware versions. Unfortunately, we don't have a TLV API - * flag to rely on, so rely on the major version which is in - * the first byte of ucode_ver. This was implemented + * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on + * earlier firmware versions. Unfortunately, we don't have a + * TLV API flag to rely on, so rely on the major version which + * is in the first byte of ucode_ver. This was implemented * initially on version 38 and then backported to 17. It was * also backported to 29, but only for 7265D devices. The * intention was to have it in 36 as well, but not all 8000 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h index d07a632f1af7c..c04f2521fcb3b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2019-2020 Intel Corporation + * Copyright (C) 2012-2014, 2019-2021 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -29,9 +29,9 @@ enum iwl_phy_ops_subcmd_ids { TEMP_REPORTING_THRESHOLDS_CMD = 0x04, /** - * @GEO_TX_POWER_LIMIT: &struct iwl_geo_tx_power_profiles_cmd + * @PER_CHAIN_LIMIT_OFFSET_CMD: &struct iwl_geo_tx_power_profiles_cmd */ - GEO_TX_POWER_LIMIT = 0x05, + PER_CHAIN_LIMIT_OFFSET_CMD = 0x05, /** * @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index 44dd64e78a2cc..4d671c878bb7a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -391,10 +391,10 @@ struct iwl_dev_tx_power_cmd { enum iwl_geo_per_chain_offset_operation { IWL_PER_CHAIN_OFFSET_SET_TABLES, IWL_PER_CHAIN_OFFSET_GET_CURRENT_TABLE, -}; /* GEO_TX_POWER_LIMIT FLAGS TYPE */ +}; /* PER_CHAIN_OFFSET_OPERATION_E */ /** - * struct iwl_per_chain_offset - embedded struct for GEO_TX_POWER_LIMIT. + * struct iwl_per_chain_offset - embedded struct for PER_CHAIN_LIMIT_OFFSET_CMD. * @max_tx_power: maximum allowed tx power. * @chain_a: tx power offset for chain a. * @chain_b: tx power offset for chain b. @@ -406,17 +406,17 @@ struct iwl_per_chain_offset { } __packed; /* PER_CHAIN_LIMIT_OFFSET_PER_CHAIN_S_VER_1 */ /** - * struct iwl_geo_tx_power_profile_cmd_v1 - struct for GEO_TX_POWER_LIMIT cmd. + * struct iwl_geo_tx_power_profile_cmd_v1 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd. * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation * @table: offset profile per band. */ struct iwl_geo_tx_power_profiles_cmd_v1 { __le32 ops; struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V1]; -} __packed; /* GEO_TX_POWER_LIMIT_VER_1 */ +} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_1 */ /** - * struct iwl_geo_tx_power_profile_cmd_v2 - struct for GEO_TX_POWER_LIMIT cmd. + * struct iwl_geo_tx_power_profile_cmd_v2 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd. * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation * @table: offset profile per band. * @table_revision: BIOS table revision. @@ -425,10 +425,10 @@ struct iwl_geo_tx_power_profiles_cmd_v2 { __le32 ops; struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V1]; __le32 table_revision; -} __packed; /* GEO_TX_POWER_LIMIT_VER_2 */ +} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_2 */ /** - * struct iwl_geo_tx_power_profile_cmd_v3 - struct for GEO_TX_POWER_LIMIT cmd. + * struct iwl_geo_tx_power_profile_cmd_v3 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd. * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation * @table: offset profile per band. * @table_revision: BIOS table revision. @@ -437,10 +437,10 @@ struct iwl_geo_tx_power_profiles_cmd_v3 { __le32 ops; struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V2]; __le32 table_revision; -} __packed; /* GEO_TX_POWER_LIMIT_VER_3 */ +} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_3 */ /** - * struct iwl_geo_tx_power_profile_cmd_v4 - struct for GEO_TX_POWER_LIMIT cmd. + * struct iwl_geo_tx_power_profile_cmd_v4 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd. * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation * @table: offset profile per band. * @table_revision: BIOS table revision. @@ -449,10 +449,10 @@ struct iwl_geo_tx_power_profiles_cmd_v4 { __le32 ops; struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V1]; __le32 table_revision; -} __packed; /* GEO_TX_POWER_LIMIT_VER_4 */ +} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_4 */ /** - * struct iwl_geo_tx_power_profile_cmd_v5 - struct for GEO_TX_POWER_LIMIT cmd. + * struct iwl_geo_tx_power_profile_cmd_v5 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd. * @ops: operations, value from &enum iwl_geo_per_chain_offset_operation * @table: offset profile per band. * @table_revision: BIOS table revision. @@ -461,7 +461,7 @@ struct iwl_geo_tx_power_profiles_cmd_v5 { __le32 ops; struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V2]; __le32 table_revision; -} __packed; /* GEO_TX_POWER_LIMIT_VER_5 */ +} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_5 */ union iwl_geo_tx_power_profiles_cmd { struct iwl_geo_tx_power_profiles_cmd_v1 v1; @@ -472,12 +472,12 @@ union iwl_geo_tx_power_profiles_cmd { }; /** - * struct iwl_geo_tx_power_profiles_resp - response to GEO_TX_POWER_LIMIT cmd + * struct iwl_geo_tx_power_profiles_resp - response to PER_CHAIN_LIMIT_OFFSET_CMD cmd * @profile_idx: current geo profile in use */ struct iwl_geo_tx_power_profiles_resp { __le32 profile_idx; -} __packed; /* GEO_TX_POWER_LIMIT_RESP */ +} __packed; /* PER_CHAIN_LIMIT_OFFSET_RSP */ /** * union iwl_ppag_table_cmd - union for all versions of PPAG command diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 8b96b885658f1..863fec150e536 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -769,7 +769,7 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) int ret; struct iwl_host_cmd cmd; u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP, - GEO_TX_POWER_LIMIT, + PER_CHAIN_LIMIT_OFFSET_CMD, IWL_FW_CMD_VER_UNKNOWN); /* the ops field is at the same spot for all versions, so set in v1 */ @@ -792,7 +792,7 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) return -EOPNOTSUPP; cmd = (struct iwl_host_cmd){ - .id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT), + .id = WIDE_ID(PHY_OPS_GROUP, PER_CHAIN_LIMIT_OFFSET_CMD), .len = { len, }, .flags = CMD_WANT_SKB, .data = { &geo_tx_cmd }, @@ -822,7 +822,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) u32 n_profiles; int ret; u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP, - GEO_TX_POWER_LIMIT, + PER_CHAIN_LIMIT_OFFSET_CMD, IWL_FW_CMD_VER_UNKNOWN); BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, ops) != @@ -894,7 +894,8 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) cmd.v2.table_revision = cpu_to_le32(mvm->fwrt.geo_rev); return iwl_mvm_send_cmd_pdu(mvm, - WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT), + WIDE_ID(PHY_OPS_GROUP, + PER_CHAIN_LIMIT_OFFSET_CMD), 0, len, &cmd); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index e331e18b9ab18..0ad45d11c9e06 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -521,7 +521,7 @@ static const struct iwl_hcmd_names iwl_mvm_phy_names[] = { HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE), HCMD_NAME(CTDP_CONFIG_CMD), HCMD_NAME(TEMP_REPORTING_THRESHOLDS_CMD), - HCMD_NAME(GEO_TX_POWER_LIMIT), + HCMD_NAME(PER_CHAIN_LIMIT_OFFSET_CMD), HCMD_NAME(CT_KILL_NOTIFICATION), HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE), }; From a6175a85ba339bb2a019abbfd21e0a9c2942bea1 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sun, 24 Oct 2021 18:20:33 +0300 Subject: [PATCH 107/114] iwlwifi: mvm: fix WGDS table print in iwl_mvm_chub_update_mcc() WGDS table index 0 means disabled, but we were erroneously checking for < 0 to print that it is disabled. Fix that and make the print more readable by mentioning that it's either disabled or there was an error. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.98a5572bf0f8.I6c112ca80cf427f12b2c752899d293cb6437ba5f@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index da705fcaf0fcc..6d18a1fd649b9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -583,8 +583,9 @@ void iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm, return; wgds_tbl_idx = iwl_mvm_get_sar_geo_profile(mvm); - if (wgds_tbl_idx < 0) - IWL_DEBUG_INFO(mvm, "SAR WGDS is disabled (%d)\n", + if (wgds_tbl_idx < 1) + IWL_DEBUG_INFO(mvm, + "SAR WGDS is disabled or error received (%d)\n", wgds_tbl_idx); else IWL_DEBUG_INFO(mvm, "SAR WGDS: geo profile %d is configured\n", From cf7a7457a362aa868c7d66b1ccbd20b9872a2ff9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 18:20:34 +0300 Subject: [PATCH 108/114] iwlwifi: mvm: remove session protection on disassoc If we somehow get disassociated while still waiting for a beacon during connection, we can end up printing the No beacon heard and the session protection is over already... message even if we aren't really quite waiting for it anymore. Remove the time event, if it's running, when we get disassociated and don't need to wait for beacons anymore. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.6192e2363784.Ie9c2bfdc30dcfff2c4dd7c393c79e3ac182840a9@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 2645dd8fef83e..d7d7d8a85c6d8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3237,6 +3237,9 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP) { mvmvif->ap_assoc_sta_count--; iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); + } else if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) { + /* remove session protection if still running */ + iwl_mvm_stop_session_protection(mvm, vif); } ret = 0; } else if (old_state == IEEE80211_STA_AUTH && From 6905eb1c3b9ee4580f5d2c7fd9f2bbcc74ec26eb Mon Sep 17 00:00:00 2001 From: Nathan Errera Date: Sun, 24 Oct 2021 18:20:35 +0300 Subject: [PATCH 109/114] iwlwifi: rename CHANNEL_SWITCH_NOA_NOTIF to CHANNEL_SWITCH_START_NOTIF There is no relation between the name and the purpose of the notification. This notification is sent from FW when the channel switch starts. Signed-off-by: Nathan Errera Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.24b71b0cb741.I97deb70e18f259de51395a1e7c7e58c7b006c317@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h | 10 +++++----- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 6 +++--- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h index 6610d1234f74d..d088c820b1a91 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2019 Intel Corporation + * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -39,9 +39,9 @@ enum iwl_mac_conf_subcmd_ids { PROBE_RESPONSE_DATA_NOTIF = 0xFC, /** - * @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif + * @CHANNEL_SWITCH_START_NOTIF: &struct iwl_channel_switch_start_notif */ - CHANNEL_SWITCH_NOA_NOTIF = 0xFF, + CHANNEL_SWITCH_START_NOTIF = 0xFF, }; #define IWL_P2P_NOA_DESC_COUNT (2) @@ -102,11 +102,11 @@ struct iwl_missed_vap_notif { } __packed; /* MISSED_VAP_NTFY_API_S_VER_1 */ /** - * struct iwl_channel_switch_noa_notif - Channel switch NOA notification + * struct iwl_channel_switch_start_notif - Channel switch start notification * * @id_and_color: ID and color of the MAC */ -struct iwl_channel_switch_noa_notif { +struct iwl_channel_switch_start_notif { __le32 id_and_color; } __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index cfb69e49a687a..fd7d4abfb454b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1557,11 +1557,11 @@ void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm, ieee80211_beacon_set_cntdwn(vif, notif->csa_counter); } -void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb) +void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_channel_switch_noa_notif *notif = (void *)pkt->data; + struct iwl_channel_switch_start_notif *notif = (void *)pkt->data; struct ieee80211_vif *csa_vif, *vif; struct iwl_mvm_vif *mvmvif; u32 id_n_color, csa_id, mac_id; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 4277536e31c3a..2b1dcd60e00f6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1658,8 +1658,8 @@ void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); void iwl_mvm_rx_missed_vap_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); -void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb); +void iwl_mvm_channel_switch_start_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb); /* Bindings */ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 0ad45d11c9e06..232ad531d612a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -383,9 +383,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { iwl_mvm_probe_resp_data_notif, RX_HANDLER_ASYNC_LOCKED, struct iwl_probe_resp_data_notif), - RX_HANDLER_GRP(MAC_CONF_GROUP, CHANNEL_SWITCH_NOA_NOTIF, - iwl_mvm_channel_switch_noa_notif, - RX_HANDLER_SYNC, struct iwl_channel_switch_noa_notif), + RX_HANDLER_GRP(MAC_CONF_GROUP, CHANNEL_SWITCH_START_NOTIF, + iwl_mvm_channel_switch_start_notif, + RX_HANDLER_SYNC, struct iwl_channel_switch_start_notif), RX_HANDLER_GRP(DATA_PATH_GROUP, MONITOR_NOTIF, iwl_mvm_rx_monitor_notif, RX_HANDLER_ASYNC_LOCKED, struct iwl_datapath_monitor_notif), @@ -511,7 +511,7 @@ static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = { HCMD_NAME(CHANNEL_SWITCH_TIME_EVENT_CMD), HCMD_NAME(SESSION_PROTECTION_CMD), HCMD_NAME(SESSION_PROTECTION_NOTIF), - HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF), + HCMD_NAME(CHANNEL_SWITCH_START_NOTIF), }; /* Please keep this array *SORTED* by hex value. From af84ac579c66869a30bf2ca61c3bf63117c060ce Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 24 Oct 2021 18:20:36 +0300 Subject: [PATCH 110/114] iwlwifi: mvm: extend session protection on association When we receive an association response, a significant amount of time might have passed since we sent the corresponding association request (mac80211 will wait up to 500ms for the TX and then 100ms for the response after ACK was received). But the time event is touched only when we send the assoc request, so it might not have much time remaining, more easily causing the (dreaded) No beacon heard and the session protection is over already... message. Refactor iwl_mvm_mac_mgd_prepare_tx() and split out a new function iwl_mvm_protect_assoc(), and call it on successful association to extend the time event to the minimum time if necessary. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.411c174d9e5e.I03c701c2e9e6788f34546e538264763db0ab30ef@changeid Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index d7d7d8a85c6d8..9fb9c7dad314f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2236,6 +2236,34 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, IWL_ERR(mvm, "Failed to config FW to work HE!\n"); } +static void iwl_mvm_protect_assoc(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + u32 duration_override) +{ + u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS; + u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS; + + if (duration_override > duration) + duration = duration_override; + + /* Try really hard to protect the session and hear a beacon + * The new session protection command allows us to protect the + * session for a much longer time since the firmware will internally + * create two events: a 300TU one with a very high priority that + * won't be fragmented which should be enough for 99% of the cases, + * and another one (which we configure here to be 900TU long) which + * will have a slightly lower priority, but more importantly, can be + * fragmented so that it'll allow other activities to run. + */ + if (fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) + iwl_mvm_schedule_session_protection(mvm, vif, 900, + min_duration, false); + else + iwl_mvm_protect_session(mvm, vif, duration, + min_duration, 500, false); +} + static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, @@ -2319,6 +2347,20 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, u32 dur = (11 * vif->bss_conf.beacon_int) / 10; iwl_mvm_protect_session(mvm, vif, dur, dur, 5 * dur, false); + } else if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, + &mvm->status) && + !vif->bss_conf.dtim_period) { + /* + * If we're not restarting and still haven't + * heard a beacon (dtim period unknown) then + * make sure we still have enough minimum time + * remaining in the time event, since the auth + * might actually have taken quite a while + * (especially for SAE) and so the remaining + * time could be small without us having heard + * a beacon yet. + */ + iwl_mvm_protect_assoc(mvm, vif, 0); } iwl_mvm_sf_update(mvm, vif, false); @@ -3332,29 +3374,9 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, struct ieee80211_prep_tx_info *info) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS; - u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS; - - if (info->duration > duration) - duration = info->duration; mutex_lock(&mvm->mutex); - /* Try really hard to protect the session and hear a beacon - * The new session protection command allows us to protect the - * session for a much longer time since the firmware will internally - * create two events: a 300TU one with a very high priority that - * won't be fragmented which should be enough for 99% of the cases, - * and another one (which we configure here to be 900TU long) which - * will have a slightly lower priority, but more importantly, can be - * fragmented so that it'll allow other activities to run. - */ - if (fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) - iwl_mvm_schedule_session_protection(mvm, vif, 900, - min_duration, false); - else - iwl_mvm_protect_session(mvm, vif, duration, - min_duration, 500, false); + iwl_mvm_protect_assoc(mvm, vif, info->duration); mutex_unlock(&mvm->mutex); } From cbaa6aeedee5f92dafa5982eceea2a1f98ce4f7d Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sun, 24 Oct 2021 18:20:37 +0300 Subject: [PATCH 111/114] iwlwifi: bump FW API to 67 for AX devices Start supporting API version 67 for AX devices. Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20211024181719.3c0af5832d23.I7c18858604b72bc15cf2047a91531e4aa7c0527a@changeid Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 0f18ff990a9c1..1572097bccf17 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -9,7 +9,7 @@ #include "iwl-prph.h" /* Highest firmware API version supported */ -#define IWL_22000_UCODE_API_MAX 66 +#define IWL_22000_UCODE_API_MAX 67 /* Lowest firmware API version supported */ #define IWL_22000_UCODE_API_MIN 39 From 2e9be536a213e838daed6ba42024dd68954ac061 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 25 Oct 2021 14:05:21 +0200 Subject: [PATCH 112/114] rtl8187: fix control-message timeouts USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ. Fixes: 605bebe23bf6 ("[PATCH] Add rtl8187 wireless driver") Cc: stable@vger.kernel.org # 2.6.23 Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211025120522.6045-4-johan@kernel.org --- .../net/wireless/realtek/rtl818x/rtl8187/rtl8225.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c index 585784258c665..4efab907a3ac6 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c @@ -28,7 +28,7 @@ u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits8, sizeof(val), 500); val = priv->io_dmabuf->bits8; mutex_unlock(&priv->io_mutex); @@ -45,7 +45,7 @@ u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits16, sizeof(val), 500); val = priv->io_dmabuf->bits16; mutex_unlock(&priv->io_mutex); @@ -62,7 +62,7 @@ u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits32, sizeof(val), 500); val = priv->io_dmabuf->bits32; mutex_unlock(&priv->io_mutex); @@ -79,7 +79,7 @@ void rtl818x_iowrite8_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits8, sizeof(val), 500); mutex_unlock(&priv->io_mutex); } @@ -93,7 +93,7 @@ void rtl818x_iowrite16_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits16, sizeof(val), 500); mutex_unlock(&priv->io_mutex); } @@ -107,7 +107,7 @@ void rtl818x_iowrite32_idx(struct rtl8187_priv *priv, usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits32, sizeof(val), 500); mutex_unlock(&priv->io_mutex); } @@ -183,7 +183,7 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data) usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), - HZ / 2); + 500); mutex_unlock(&priv->io_mutex); From 541fd20c3ce5b0bc39f0c6a52414b6b92416831c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 25 Oct 2021 14:05:22 +0200 Subject: [PATCH 113/114] rsi: fix control-message timeout USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ. Use the common control-message timeout define for the five-second timeout. Fixes: dad0d04fa7ba ("rsi: Add RS9113 wireless driver") Cc: stable@vger.kernel.org # 3.15 Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211025120522.6045-5-johan@kernel.org --- drivers/net/wireless/rsi/rsi_91x_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index 6a120211800db..6821ea9918956 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -58,7 +58,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter, (void *)seg, (int)len, &transfer, - HZ * 5); + USB_CTRL_SET_TIMEOUT); if (status < 0) { rsi_dbg(ERR_ZONE, From 89f8765a11d8df49296d92c404067f9b5c58ee26 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 27 Oct 2021 10:08:19 +0200 Subject: [PATCH 114/114] mwifiex: fix division by zero in fw download path Add the missing endpoint sanity checks to probe() to avoid division by zero in mwifiex_write_data_sync() in case a malicious device has broken descriptors (or when doing descriptor fuzz testing). Only add checks for the firmware-download boot stage, which require both command endpoints, for now. The driver looks like it will handle a missing endpoint during normal operation without oopsing, albeit not very gracefully as it will try to submit URBs to the default pipe and fail. Note that USB core will reject URBs submitted for endpoints with zero wMaxPacketSize but that drivers doing packet-size calculations still need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip endpoint descriptors with maxpacket=0")). Fixes: 4daffe354366 ("mwifiex: add support for Marvell USB8797 chipset") Cc: stable@vger.kernel.org # 3.5 Cc: Amitkumar Karwar Signed-off-by: Johan Hovold Reviewed-by: Brian Norris Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20211027080819.6675-4-johan@kernel.org --- drivers/net/wireless/marvell/mwifiex/usb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c index 426e39d4ccf0f..9736aa0ab7fd4 100644 --- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -505,6 +505,22 @@ static int mwifiex_usb_probe(struct usb_interface *intf, } } + switch (card->usb_boot_state) { + case USB8XXX_FW_DNLD: + /* Reject broken descriptors. */ + if (!card->rx_cmd_ep || !card->tx_cmd_ep) + return -ENODEV; + if (card->bulk_out_maxpktsize == 0) + return -ENODEV; + break; + case USB8XXX_FW_READY: + /* Assume the driver can handle missing endpoints for now. */ + break; + default: + WARN_ON(1); + return -ENODEV; + } + usb_set_intfdata(intf, card); ret = mwifiex_add_card(card, &card->fw_done, &usb_ops,