From patchwork Tue Sep 6 13:42:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967559 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01F3EECAAA1 for ; Tue, 6 Sep 2022 14:08:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240859AbiIFOIH (ORCPT ); Tue, 6 Sep 2022 10:08:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240842AbiIFOGx (ORCPT ); Tue, 6 Sep 2022 10:06:53 -0400 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6954F857DA for ; Tue, 6 Sep 2022 06:45:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471928; x=1694007928; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vHFIX1L8XM12D+ambrd2H4ssx8FrLeFZ/hcHLEnNtZM=; b=NslKcJW5JHlwWeIHgleLwAZ//XHHgpSZFfVPx77NTNhuK6lnpUL+aJpF 7+7YbdjEStbb5CyJxn0zxzg1kBlkdYMKkw0an+CWLLApMm2sZGCHZsgqg HS7deoi3DUDpFKB+/Fi6xiU6UweFmp94mIwFUbLq/xLsfKpmArYzAqmYL ypt8tyf5XadpXlqWMWTRvOUc/uC37wfnjwAgf1JDM0IWY8DSNvPlEEmAM xJsSr97hnIGRRnL5VztlsGbQWHyPlQixAGEXGa29bZ57WY4zOZeVuwWXA m4RZtnMcSg2bhvvF44Azcdz8xG9ForzIQeMWcmu/yGmVenTdgjpD9TqSv w==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="297906960" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="297906960" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:12 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459562" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:10 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Yaara Baruch , Gregory Greenman Subject: [PATCH 01/15] wifi: iwlwifi: pcie: add support for BZ devices Date: Tue, 6 Sep 2022 16:42:05 +0300 Message-Id: <20220906161827.0b7fc8487039.I984dcb58272e2f38c835e7aaa7e1ac646bc2f65e@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Yaara Baruch Add support in BZ-FM and BZ-GL devices. Adjust current structs steps to differ between the new devices. Signed-off-by: Yaara Baruch Signed-off-by: Gregory Greenman --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 33 +++++++++++++++++++ .../net/wireless/intel/iwlwifi/iwl-config.h | 3 ++ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 19 +++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 8ff967edc8f0..c949675ca2ed 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -56,13 +56,16 @@ #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_BZ_A_FM4_A_FW_PRE "iwlwifi-bz-a0-fm4-a0-" #define IWL_GL_A_FM_A_FW_PRE "iwlwifi-gl-a0-fm-a0-" +#define IWL_GL_B_FM_B_FW_PRE "iwlwifi-gl-b0-fm-b0-" #define IWL_BZ_Z_GF_A_FW_PRE "iwlwifi-bz-z0-gf-a0-" #define IWL_BNJ_A_FM_A_FW_PRE "iwlwifi-BzBnj-a0-fm-a0-" #define IWL_BNJ_A_FM4_A_FW_PRE "iwlwifi-BzBnj-a0-fm4-a0-" #define IWL_BNJ_A_GF_A_FW_PRE "iwlwifi-BzBnj-a0-gf-a0-" #define IWL_BNJ_A_GF4_A_FW_PRE "iwlwifi-BzBnj-a0-gf4-a0-" #define IWL_BNJ_A_HR_B_FW_PRE "iwlwifi-BzBnj-a0-hr-b0-" +#define IWL_BNJ_B_FM_B_FW_PRE "iwlwifi-BzBnj-b0-fm-b0-" #define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \ @@ -119,8 +122,12 @@ 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_BZ_A_FM4_A_MODULE_FIRMWARE(api) \ + IWL_BZ_A_FM4_A_FW_PRE __stringify(api) ".ucode" #define IWL_GL_A_FM_A_MODULE_FIRMWARE(api) \ IWL_GL_A_FM_A_FW_PRE __stringify(api) ".ucode" +#define IWL_GL_B_FM_B_MODULE_FIRMWARE(api) \ + IWL_GL_B_FM_B_FW_PRE __stringify(api) ".ucode" #define IWL_BNJ_A_FM_A_MODULE_FIRMWARE(api) \ IWL_BNJ_A_FM_A_FW_PRE __stringify(api) ".ucode" #define IWL_BNJ_A_FM4_A_MODULE_FIRMWARE(api) \ @@ -131,6 +138,8 @@ IWL_BNJ_A_GF4_A_FW_PRE __stringify(api) ".ucode" #define IWL_BNJ_A_HR_B_MODULE_FIRMWARE(api) \ IWL_BNJ_A_HR_B_FW_PRE __stringify(api) ".ucode" +#define IWL_BNJ_B_FM_B_MODULE_FIRMWARE(api) \ + IWL_BNJ_B_FM_B_FW_PRE __stringify(api) ".ucode" static const struct iwl_base_params iwl_22000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, @@ -926,6 +935,13 @@ const struct iwl_cfg iwl_cfg_bz_a0_fm_a0 = { .num_rbds = IWL_NUM_RBDS_AX210_HE, }; +const struct iwl_cfg iwl_cfg_bz_a0_fm4_a0 = { + .fw_name_pre = IWL_BZ_A_FM4_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, @@ -933,6 +949,13 @@ const struct iwl_cfg iwl_cfg_gl_a0_fm_a0 = { .num_rbds = IWL_NUM_RBDS_AX210_HE, }; +const struct iwl_cfg iwl_cfg_gl_b0_fm_b0 = { + .fw_name_pre = IWL_GL_B_FM_B_FW_PRE, + .uhb_supported = true, + IWL_DEVICE_BZ, + .num_rbds = IWL_NUM_RBDS_AX210_HE, +}; + const struct iwl_cfg iwl_cfg_bz_z0_gf_a0 = { .fw_name_pre = IWL_BZ_Z_GF_A_FW_PRE, .uhb_supported = true, @@ -974,6 +997,13 @@ const struct iwl_cfg iwl_cfg_bnj_a0_hr_b0 = { IWL_DEVICE_BZ, .num_rbds = IWL_NUM_RBDS_AX210_HE, }; + +const struct iwl_cfg iwl_cfg_bnj_b0_fm_b0 = { + .fw_name_pre = IWL_BNJ_B_FM_B_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)); @@ -1007,3 +1037,6 @@ MODULE_FIRMWARE(IWL_BNJ_A_FM4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_BNJ_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_BNJ_A_GF4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_BNJ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_BZ_A_FM4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_GL_B_FM_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_BNJ_B_FM_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index f5b556a103e8..cfa5e1b3c3f6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -649,13 +649,16 @@ 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_bz_a0_fm4_a0; extern const struct iwl_cfg iwl_cfg_gl_a0_fm_a0; +extern const struct iwl_cfg iwl_cfg_gl_b0_fm_b0; extern const struct iwl_cfg iwl_cfg_bz_z0_gf_a0; extern const struct iwl_cfg iwl_cfg_bnj_a0_fm_a0; extern const struct iwl_cfg iwl_cfg_bnj_a0_fm4_a0; extern const struct iwl_cfg iwl_cfg_bnj_a0_gf_a0; extern const struct iwl_cfg iwl_cfg_bnj_a0_gf4_a0; extern const struct iwl_cfg iwl_cfg_bnj_a0_hr_b0; +extern const struct iwl_cfg iwl_cfg_bnj_b0_fm_b0; #endif /* CONFIG_IWLMVM */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index b16d4ae182d1..4f699862e7f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1155,10 +1155,20 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, IWL_CFG_ANY, 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_MAC_TYPE_BZ, IWL_CFG_ANY, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_CDB, IWL_CFG_NO_JACKET, + iwl_cfg_bz_a0_fm4_a0, iwl_bz_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_GL, SILICON_A_STEP, IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, IWL_CFG_NO_JACKET, iwl_cfg_gl_a0_fm_a0, iwl_bz_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_GL, SILICON_B_STEP, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, IWL_CFG_NO_JACKET, + iwl_cfg_gl_b0_fm_b0, iwl_bz_name), /* BZ Z step */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, @@ -1169,10 +1179,15 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { /* BNJ */ _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_GL, SILICON_A_STEP, IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, IWL_CFG_IS_JACKET, iwl_cfg_bnj_a0_fm_a0, iwl_bz_name), + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, + IWL_CFG_MAC_TYPE_GL, SILICON_B_STEP, + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, IWL_CFG_IS_JACKET, + iwl_cfg_bnj_b0_fm_b0, 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, From patchwork Tue Sep 6 13:42:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967545 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71FC3ECAAD5 for ; Tue, 6 Sep 2022 14:02:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239920AbiIFOCZ (ORCPT ); Tue, 6 Sep 2022 10:02:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239694AbiIFOAU (ORCPT ); Tue, 6 Sep 2022 10:00:20 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB81C83F2E for ; Tue, 6 Sep 2022 06:44:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471860; x=1694007860; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Qw4/LQBfMM8AzS7rwZHBIi2flgUOzLeoUR4QNprbkeo=; b=jdIm1OhJCQCw1Y/SIXctjqzHQeDKq5sM1GyHmP9WJhPqc9FxZkZrq881 UKw7BYGH4dP379KDnYPjc9+BfCNxnlCChdjiwjogzMifVaWNWj4I5LJpj Rfl4CDE0kcDtmkgq09Yg3FckwRP6L45So9WUsvLaLAPqdgfcwwg9iRy1P AeZk5UTUGliXvsp1zUHbsh8M+zDPy1NuM3YyJRuroeR53LEOUz8ictUo8 2jnw/f+F4u+04tpZ5j9X3JhxqNJ7Lb793vKBhVDFNpYL3SbH5IZhVYF7g QsAWmE3aUg85zxDx7LofV48vWAWThOg2yEkxjdtNl4Y+yBKGWXYGDT8ls Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276332678" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276332678" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:17 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459600" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:16 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg , Gregory Greenman Subject: [PATCH 02/15] wifi: iwlwifi: mvm: fix typo in struct iwl_rx_no_data API Date: Tue, 6 Sep 2022 16:42:06 +0300 Message-Id: <20220906161827.80f7eda56163.Ib783512104f0c135695b4d59b637f3eef3e8f537@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg The version 2 is also for RX, of course, that's just a typo. Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/fw/api/rx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 1989b270862b..74a01888715b 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-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -668,7 +668,7 @@ struct iwl_rx_no_data { __le32 phy_info[2]; __le32 rx_vec[2]; } __packed; /* RX_NO_DATA_NTFY_API_S_VER_1, - TX_NO_DATA_NTFY_API_S_VER_2 */ + RX_NO_DATA_NTFY_API_S_VER_2 */ struct iwl_frame_release { u8 baid; From patchwork Tue Sep 6 13:42:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967548 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EDE19ECAAD5 for ; Tue, 6 Sep 2022 14:05:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240449AbiIFOFc (ORCPT ); Tue, 6 Sep 2022 10:05:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240944AbiIFOC6 (ORCPT ); Tue, 6 Sep 2022 10:02:58 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D509F60 for ; Tue, 6 Sep 2022 06:44:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471864; x=1694007864; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tw6NVEHDYAGo0abkaSwnxvNQhQfiJL/krdoUGnD0sTk=; b=l1+Yl9V9lfhyeHdtEa90xws/AMk1TF3L1rtthw4Vao4YuktirHZ9Bx0x z0BH8WhoXebhuYysmxWtONPxxmlZ1NgsPoW6xImojySfZh/R2PK7koRTn KNWRtXR6hI2xZy4fqTQ0Mp4xoji1A1cj83XNmpM9qLFLcaSVIZVwwvPXH cgA6ce3vSP1B+JSE8zBEPsyhn8bAOxGvj2m7q3olpP1CBIYXclx5D8xbs sK+cC3tKgP7iJT+jg5bt3GT2q0zRLebqOVjmY0UKHmRVHZWtvi/D1kUgQ Yi7z++ScPspUoEU16kQta8CYoVTbrjmQnYya14IFFRxJvUNHvzb7JUHeS Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276332692" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276332692" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:21 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459621" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:19 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg , Gregory Greenman Subject: [PATCH 03/15] wifi: iwlwifi: mvm: rxmq: refactor mac80211 rx_status setting Date: Tue, 6 Sep 2022 16:42:07 +0300 Message-Id: <20220906161827.a81580d5e769.I3ee7a1fe1adf8684c48713dbbdc2cbc60bd24cd1@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg There's a bunch of duplicated code in the normal data RX and the no-data RX paths, refactor that. Note that we're evidently not implementing the 6 GHz band in the no-data path correctly, need to fix that in firmware first. Also, we were setting the NSS differently, keep doing that, but just override the previous values. Note also that we used to drop frames with bad rate data, to simplify that just report rate 0 and continue. Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 356 ++++++++---------- 1 file changed, 165 insertions(+), 191 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 2c43a9989783..c0a779867938 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -1191,16 +1191,22 @@ struct iwl_mvm_rx_phy_data { enum iwl_rx_phy_info_type info_type; __le32 d0, d1, d2, d3; __le16 d4; + + u32 rate_n_flags; + u32 gp2_on_air_rise; + u16 phy_info; + u8 energy_a, energy_b; + u8 channel; }; static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm, struct iwl_mvm_rx_phy_data *phy_data, - u32 rate_n_flags, struct ieee80211_radiotap_he_mu *he_mu) { u32 phy_data2 = le32_to_cpu(phy_data->d2); u32 phy_data3 = le32_to_cpu(phy_data->d3); u16 phy_data4 = le16_to_cpu(phy_data->d4); + u32 rate_n_flags = phy_data->rate_n_flags; if (FIELD_GET(IWL_RX_PHY_DATA4_HE_MU_EXT_CH1_CRC_OK, phy_data4)) { he_mu->flags1 |= @@ -1246,7 +1252,6 @@ static void iwl_mvm_decode_he_mu_ext(struct iwl_mvm *mvm, static void iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data, - u32 rate_n_flags, struct ieee80211_radiotap_he *he, struct ieee80211_radiotap_he_mu *he_mu, struct ieee80211_rx_status *rx_status) @@ -1260,6 +1265,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 rate_n_flags = phy_data->rate_n_flags; u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1; u8 offs = 0; @@ -1331,7 +1337,7 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm, struct ieee80211_radiotap_he *he, struct ieee80211_radiotap_he_mu *he_mu, struct ieee80211_rx_status *rx_status, - u32 rate_n_flags, int queue) + int queue) { switch (phy_data->info_type) { case IWL_RX_PHY_INFO_TYPE_NONE: @@ -1430,7 +1436,7 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm, le16_encode_bits(le16_get_bits(phy_data->d4, IWL_RX_PHY_DATA4_HE_MU_EXT_PREAMBLE_PUNC_TYPE_MASK), IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW); - iwl_mvm_decode_he_mu_ext(mvm, phy_data, rate_n_flags, he_mu); + iwl_mvm_decode_he_mu_ext(mvm, phy_data, he_mu); fallthrough; case IWL_RX_PHY_INFO_TYPE_HE_MU: he_mu->flags2 |= @@ -1444,8 +1450,7 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm, fallthrough; case IWL_RX_PHY_INFO_TYPE_HE_TB: case IWL_RX_PHY_INFO_TYPE_HE_TB_EXT: - iwl_mvm_decode_he_phy_ru_alloc(phy_data, rate_n_flags, - he, he_mu, rx_status); + iwl_mvm_decode_he_phy_ru_alloc(phy_data, he, he_mu, rx_status); break; case IWL_RX_PHY_INFO_TYPE_HE_SU: he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN); @@ -1461,11 +1466,12 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm, static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, struct iwl_mvm_rx_phy_data *phy_data, - u32 rate_n_flags, u16 phy_info, int queue) + int queue) { 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 rate_n_flags = phy_data->rate_n_flags; u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; u8 stbc, ltf; static const struct ieee80211_radiotap_he known = { @@ -1484,6 +1490,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN | IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), }; + u16 phy_info = phy_data->phy_info; he = skb_put_data(skb, &known, sizeof(known)); rx_status->flag |= RX_FLAG_RADIOTAP_HE; @@ -1504,7 +1511,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) iwl_mvm_decode_he_phy_data(mvm, phy_data, he, he_mu, rx_status, - rate_n_flags, queue); + queue); /* update aggregation data for monitor sake on default queue */ if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) && @@ -1661,6 +1668,102 @@ static void iwl_mvm_rx_get_sta_block_tx(void *data, struct ieee80211_sta *sta) rx_sta_csa->all_sta_unblocked = false; } +/* + * Note: requires also rx_status->band to be prefilled, as well + * as phy_data (apart from phy_data->info_type) + */ +static void iwl_mvm_rx_fill_status(struct iwl_mvm *mvm, + struct sk_buff *skb, + struct iwl_mvm_rx_phy_data *phy_data, + int queue) +{ + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); + u32 rate_n_flags = phy_data->rate_n_flags; + u8 stbc = u32_get_bits(rate_n_flags, RATE_MCS_STBC_MSK); + u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; + bool is_sgi; + + phy_data->info_type = IWL_RX_PHY_INFO_TYPE_NONE; + + if (phy_data->phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) + phy_data->info_type = + le32_get_bits(phy_data->d1, + IWL_RX_PHY_DATA1_INFO_TYPE_MASK); + + /* This may be overridden by iwl_mvm_rx_he() to HE_RU */ + switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { + case RATE_MCS_CHAN_WIDTH_20: + break; + case RATE_MCS_CHAN_WIDTH_40: + rx_status->bw = RATE_INFO_BW_40; + break; + case RATE_MCS_CHAN_WIDTH_80: + rx_status->bw = RATE_INFO_BW_80; + break; + case RATE_MCS_CHAN_WIDTH_160: + rx_status->bw = RATE_INFO_BW_160; + break; + } + + /* must be before L-SIG data */ + if (format == RATE_MCS_HE_MSK) + iwl_mvm_rx_he(mvm, skb, phy_data, queue); + + iwl_mvm_decode_lsig(skb, phy_data); + + rx_status->device_timestamp = phy_data->gp2_on_air_rise; + rx_status->freq = ieee80211_channel_to_frequency(phy_data->channel, + rx_status->band); + iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, + phy_data->energy_a, phy_data->energy_b); + + if (unlikely(mvm->monitor_on)) + iwl_mvm_add_rtap_sniffer_config(mvm, skb); + + 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_MCS_LDPC_MSK) + rx_status->enc_flags |= RX_ENC_FLAG_LDPC; + + switch (format) { + case RATE_MCS_HT_MSK: + rx_status->encoding = RX_ENC_HT; + rx_status->rate_idx = RATE_HT_MCS_INDEX(rate_n_flags); + rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; + break; + case RATE_MCS_VHT_MSK: + 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; + break; + case RATE_MCS_HE_MSK: + /* handled above */ + break; + default: { + int rate = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags, + rx_status->band); + + rx_status->rate_idx = rate; + + if (WARN_ONCE(rate < 0 || rate > 0xFF, + "Invalid rate flags 0x%x, band %d,\n", + rate_n_flags, rx_status->band)) + rx_status->rate_idx = 0; + break; + } + } +} + void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, struct iwl_rx_cmd_buffer *rxb, int queue) { @@ -1670,17 +1773,12 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, struct ieee80211_hdr *hdr; u32 len; u32 pkt_len = iwl_rx_packet_payload_len(pkt); - u32 rate_n_flags, gp2_on_air_rise; - u16 phy_info; struct ieee80211_sta *sta = NULL; struct sk_buff *skb; - u8 crypt_len = 0, channel, energy_a, energy_b; + u8 crypt_len = 0; size_t desc_size; - struct iwl_mvm_rx_phy_data phy_data = { - .info_type = IWL_RX_PHY_INFO_TYPE_NONE, - }; + struct iwl_mvm_rx_phy_data phy_data = {}; u32 format; - bool is_sgi; if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; @@ -1696,35 +1794,37 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { - rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags); - channel = desc->v3.channel; - gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); - energy_a = desc->v3.energy_a; - energy_b = desc->v3.energy_b; + phy_data.rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags); + phy_data.channel = desc->v3.channel; + phy_data.gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); + phy_data.energy_a = desc->v3.energy_a; + phy_data.energy_b = desc->v3.energy_b; phy_data.d0 = desc->v3.phy_data0; phy_data.d1 = desc->v3.phy_data1; phy_data.d2 = desc->v3.phy_data2; phy_data.d3 = desc->v3.phy_data3; } else { - rate_n_flags = le32_to_cpu(desc->v1.rate_n_flags); - channel = desc->v1.channel; - gp2_on_air_rise = le32_to_cpu(desc->v1.gp2_on_air_rise); - energy_a = desc->v1.energy_a; - energy_b = desc->v1.energy_b; + phy_data.rate_n_flags = le32_to_cpu(desc->v1.rate_n_flags); + phy_data.channel = desc->v1.channel; + phy_data.gp2_on_air_rise = le32_to_cpu(desc->v1.gp2_on_air_rise); + phy_data.energy_a = desc->v1.energy_a; + phy_data.energy_b = desc->v1.energy_b; phy_data.d0 = desc->v1.phy_data0; phy_data.d1 = desc->v1.phy_data1; 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); + phy_data.rate_n_flags = iwl_new_rate_from_v1(phy_data.rate_n_flags); IWL_DEBUG_DROP(mvm, "Got old format rate, converting. New rate: 0x%x\n", - rate_n_flags); + phy_data.rate_n_flags); } - format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; + + format = phy_data.rate_n_flags & RATE_MCS_MOD_TYPE_MSK; len = le16_to_cpu(desc->mpdu_len); @@ -1733,14 +1833,9 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, return; } - phy_info = le16_to_cpu(desc->phy_info); + phy_data.phy_info = le16_to_cpu(desc->phy_info); phy_data.d4 = desc->phy_data4; - if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) - phy_data.info_type = - le32_get_bits(phy_data.d1, - IWL_RX_PHY_DATA1_INFO_TYPE_MASK); - hdr = (void *)(pkt->data + desc_size); /* Dont use dev_alloc_skb(), we'll have enough headroom once * ieee80211_hdr pulled. @@ -1763,27 +1858,6 @@ 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) { - case RATE_MCS_CHAN_WIDTH_20: - break; - case RATE_MCS_CHAN_WIDTH_40: - rx_status->bw = RATE_INFO_BW_40; - break; - case RATE_MCS_CHAN_WIDTH_80: - rx_status->bw = RATE_INFO_BW_80; - break; - case RATE_MCS_CHAN_WIDTH_160: - rx_status->bw = RATE_INFO_BW_160; - break; - } - - if (format == RATE_MCS_HE_MSK) - iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags, - phy_info, queue); - - iwl_mvm_decode_lsig(skb, &phy_data); - /* * Keep packets with CRC errors (and with overrun) for monitor mode * (otherwise the firmware discards them) but mark them as bad. @@ -1794,12 +1868,13 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, le32_to_cpu(desc->status)); rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; } + /* set the preamble flag if appropriate */ if (format == RATE_MCS_CCK_MSK && - phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) + phy_data.phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE) rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE; - if (likely(!(phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) { + if (likely(!(phy_data.phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) { u64 tsf_on_air_rise; if (mvm->trans->trans_cfg->device_family >= @@ -1813,24 +1888,20 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->flag |= RX_FLAG_MACTIME_PLCP_START; } - rx_status->device_timestamp = gp2_on_air_rise; if (iwl_mvm_is_band_in_rx_supported(mvm)) { u8 band = BAND_IN_RX_STATUS(desc->mac_phy_idx); rx_status->band = iwl_mvm_nl80211_band_from_rx_msdu(band); } else { - rx_status->band = channel > 14 ? NL80211_BAND_5GHZ : + rx_status->band = phy_data.channel > 14 ? NL80211_BAND_5GHZ : NL80211_BAND_2GHZ; } - rx_status->freq = ieee80211_channel_to_frequency(channel, - rx_status->band); - iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, energy_a, - energy_b); /* update aggregation data for monitor sake on default queue */ - if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) { - bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE; + if (!queue && (phy_data.phy_info & IWL_RX_MPDU_PHY_AMPDU)) { + bool toggle_bit; + toggle_bit = phy_data.phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE; rx_status->flag |= RX_FLAG_AMPDU_DETAILS; /* * Toggle is switched whenever new aggregation starts. Make @@ -1846,9 +1917,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->ampdu_reference = mvm->ampdu_ref; } - if (unlikely(mvm->monitor_on)) - iwl_mvm_add_rtap_sniffer_config(mvm, skb); - rcu_read_lock(); if (desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_SRC_STA_FOUND)) { @@ -1867,13 +1935,15 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, sta = ieee80211_find_sta_by_ifaddr(mvm->hw, hdr->addr2, NULL); } - if (iwl_mvm_rx_crypto(mvm, sta, hdr, rx_status, phy_info, desc, + if (iwl_mvm_rx_crypto(mvm, sta, hdr, rx_status, phy_data.phy_info, desc, le32_to_cpu(pkt->len_n_flags), queue, &crypt_len)) { kfree_skb(skb); goto out; } + iwl_mvm_rx_fill_status(mvm, skb, &phy_data, queue); + if (sta) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct ieee80211_vif *tx_blocked_vif = @@ -1971,43 +2041,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } } - 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_MCS_LDPC_MSK) - rx_status->enc_flags |= RX_ENC_FLAG_LDPC; - 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_HT_MCS_INDEX(rate_n_flags); - rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - } 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_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 (!(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", - rate_n_flags, rx_status->band)) { - kfree_skb(skb); - goto out; - } - rx_status->rate_idx = rate; - } - /* management stuff on default queue */ if (!queue) { if (unlikely((ieee80211_is_beacon(hdr->frame_control) || @@ -2039,32 +2072,32 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, struct ieee80211_rx_status *rx_status; struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_no_data *desc = (void *)pkt->data; - u32 rate_n_flags = le32_to_cpu(desc->rate); - u32 gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time); u32 rssi = le32_to_cpu(desc->rssi); u32 info_type = le32_to_cpu(desc->info) & RX_NO_DATA_INFO_TYPE_MSK; - u16 phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD; 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], + .phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD, + .gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time), + .rate_n_flags = le32_to_cpu(desc->rate), + .energy_a = u32_get_bits(rssi, RX_NO_DATA_CHAIN_A_MSK), + .energy_b = u32_get_bits(rssi, RX_NO_DATA_CHAIN_B_MSK), + .channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK), }; - bool is_sgi; + u32 format; 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); + phy_data.rate_n_flags); + phy_data.rate_n_flags = iwl_new_rate_from_v1(phy_data.rate_n_flags); IWL_DEBUG_DROP(mvm, " Rate after conversion to the new format: 0x%x\n", - rate_n_flags); + phy_data.rate_n_flags); } - format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; + + format = phy_data.rate_n_flags & RATE_MCS_MOD_TYPE_MSK; if (unlikely(iwl_rx_packet_payload_len(pkt) < sizeof(*desc))) return; @@ -2072,10 +2105,6 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; - energy_a = (rssi & RX_NO_DATA_CHAIN_A_MSK) >> RX_NO_DATA_CHAIN_A_POS; - energy_b = (rssi & RX_NO_DATA_CHAIN_B_MSK) >> RX_NO_DATA_CHAIN_B_POS; - channel = (rssi & RX_NO_DATA_CHANNEL_MSK) >> RX_NO_DATA_CHANNEL_POS; - /* Dont use dev_alloc_skb(), we'll have enough headroom once * ieee80211_hdr pulled. */ @@ -2106,86 +2135,31 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, break; } - /* This may be overridden by iwl_mvm_rx_he() to HE_RU */ - switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { - case RATE_MCS_CHAN_WIDTH_20: - break; - case RATE_MCS_CHAN_WIDTH_40: - rx_status->bw = RATE_INFO_BW_40; - break; - case RATE_MCS_CHAN_WIDTH_80: - rx_status->bw = RATE_INFO_BW_80; - break; - case RATE_MCS_CHAN_WIDTH_160: - rx_status->bw = RATE_INFO_BW_160; - break; - } - - if (format == RATE_MCS_HE_MSK) - iwl_mvm_rx_he(mvm, skb, &phy_data, rate_n_flags, - phy_info, queue); - - iwl_mvm_decode_lsig(skb, &phy_data); - - rx_status->device_timestamp = gp2_on_air_rise; - rx_status->band = channel > 14 ? NL80211_BAND_5GHZ : + rx_status->band = phy_data.channel > 14 ? NL80211_BAND_5GHZ : NL80211_BAND_2GHZ; - rx_status->freq = ieee80211_channel_to_frequency(channel, - rx_status->band); - iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, energy_a, - energy_b); - - rcu_read_lock(); - is_sgi = format == RATE_MCS_HE_MSK ? - iwl_he_is_sgi(rate_n_flags) : - rate_n_flags & RATE_MCS_SGI_MSK; + iwl_mvm_rx_fill_status(mvm, skb, &phy_data, queue); - if (!(format == RATE_MCS_CCK_MSK) && is_sgi) - rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - if (rate_n_flags & RATE_MCS_LDPC_MSK) - rx_status->enc_flags |= RX_ENC_FLAG_LDPC; - 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_HT_MCS_INDEX(rate_n_flags); - rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; - } 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_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; - /* - * take the nss from the rx_vec since the rate_n_flags has - * only 2 bits for the nss which gives a max of 4 ss but - * there may be up to 8 spatial streams - */ + /* + * Override the nss from the rx_vec since the rate_n_flags has + * only 2 bits for the nss which gives a max of 4 ss but there + * may be up to 8 spatial streams. + */ + switch (format) { + case RATE_MCS_VHT_MSK: rx_status->nss = le32_get_bits(desc->rx_vec[0], RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK) + 1; - } else if (format == RATE_MCS_HE_MSK) { + break; + case 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_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", - rate_n_flags, rx_status->band)) { - kfree_skb(skb); - goto out; - } - rx_status->rate_idx = rate; + break; } + rcu_read_lock(); ieee80211_rx_napi(mvm->hw, sta, skb, napi); -out: rcu_read_unlock(); } From patchwork Tue Sep 6 13:42:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967546 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E4B5ECAAA1 for ; Tue, 6 Sep 2022 14:05:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239513AbiIFOFR (ORCPT ); Tue, 6 Sep 2022 10:05:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241283AbiIFODz (ORCPT ); Tue, 6 Sep 2022 10:03:55 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6C5316580 for ; Tue, 6 Sep 2022 06:44:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471885; x=1694007885; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eLTKNs2xRpBl+HRdpQSAS6NVnjHB428wqLA1/yU+acc=; b=fuLFCHWwKA/UPjilqRBicRu8JR2udHIMbAHUaBMhVyx7sBWmfbiSg2Nz GAKLjavDT6HY2bS0ly1jjr2gPFXXQ109fJTAsTYa4ul0eHGJ2YMXhZMA6 JSUX32TGw1nn7pzMhNzODmqpikQO1qIFqnhlKU0S2px5bj0UJhkG7CtmB tpCCrgmatvm4nJw54H7nbZ3jSHWGIxP3yf3JL04dKVuJBSGyRfdmP1wjJ aDnqC41M/IS76PK9Wrte1zPDHQ3W8AF+ZrsFuVr+vYij23uOQVG7T2glx //2kuGHLlsa3Alqb0X2riFyiZnLGdykxDa9Tpg3qqxJs5fxWqAAEN8o5G A==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276332703" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276332703" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:23 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459640" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:22 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg , Gregory Greenman Subject: [PATCH 04/15] wifi: iwlwifi: mvm: rxmq: further unify some VHT/HE code Date: Tue, 6 Sep 2022 16:42:08 +0300 Message-Id: <20220906161827.d1e8673b9443.I6d81fc9dd0856d75e3a799c23f0f8d212b077fca@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg There's some duplication here, unify it so that adding EHT becomes easier. Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index c0a779867938..1aadccd8841f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -1473,7 +1473,7 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_radiotap_he_mu *he_mu = NULL; u32 rate_n_flags = phy_data->rate_n_flags; u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; - u8 stbc, ltf; + u8 ltf; static const struct ieee80211_radiotap_he known = { .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN | @@ -1538,19 +1538,6 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, 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_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) - rx_status->enc_flags |= RX_ENC_FLAG_BF; - - rx_status->he_dcm = - !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); - #define CHECK_TYPE(F) \ BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS)) @@ -1730,6 +1717,17 @@ static void iwl_mvm_rx_fill_status(struct iwl_mvm *mvm, if (rate_n_flags & RATE_MCS_LDPC_MSK) rx_status->enc_flags |= RX_ENC_FLAG_LDPC; + switch (format) { + case RATE_MCS_VHT_MSK: + rx_status->encoding = RX_ENC_VHT; + break; + case RATE_MCS_HE_MSK: + rx_status->encoding = RX_ENC_HE; + rx_status->he_dcm = + !!(rate_n_flags & RATE_HE_DUAL_CARRIER_MODE_MSK); + break; + } + switch (format) { case RATE_MCS_HT_MSK: rx_status->encoding = RX_ENC_HT; @@ -1737,17 +1735,11 @@ static void iwl_mvm_rx_fill_status(struct iwl_mvm *mvm, rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT; break; case RATE_MCS_VHT_MSK: + case RATE_MCS_HE_MSK: rx_status->nss = - ((rate_n_flags & RATE_MCS_NSS_MSK) >> - RATE_MCS_NSS_POS) + 1; + u32_get_bits(rate_n_flags, RATE_MCS_NSS_MSK) + 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; - break; - case RATE_MCS_HE_MSK: - /* handled above */ break; default: { int rate = iwl_mvm_legacy_hw_idx_to_mac80211_idx(rate_n_flags, From patchwork Tue Sep 6 13:42:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967547 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C8F5ECAAD5 for ; Tue, 6 Sep 2022 14:05:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238560AbiIFOFP (ORCPT ); Tue, 6 Sep 2022 10:05:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241414AbiIFOER (ORCPT ); Tue, 6 Sep 2022 10:04:17 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCA0222BE5 for ; Tue, 6 Sep 2022 06:44:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471897; x=1694007897; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=52D2F/yHOk+iTcQqICjsrT1eKWDPzyaGsuGa54hUkHQ=; b=irBfpWYkeWVspkYfQGwqYprOZFEfIo3V3l2uZEqdYARgqJtEPjJ7cf3V bis8ceO9o38+RNThXZnCjKZyt6pyAPVYFU4wm16s47pYv6YpyLhLb0zXh SxqqhntCCLLpZaNpKMZB7xhmuih5FB2tvdtRgn4V3lmDew3440Z20sx6e OtoNqXHqbGk7uHaBCXpTNROakbqdn3D6PY2BYgfZjUZebr9hcALILtWui mrQ1+tsDhK81NcEYOdnYDke5HE4CGXGRTHapUEHWi4DVzk0gEF3P78Q06 rq0fu30N7lYcUIbtHP4Ftr1D+qpZSK6P9CDesAN7GY3j6QuAliD8DCK96 Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276332709" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276332709" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:26 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459646" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:24 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg , Gregory Greenman Subject: [PATCH 05/15] wifi: iwlwifi: mvm: refactor iwl_mvm_set_sta_rate() a bit Date: Tue, 6 Sep 2022 16:42:09 +0300 Message-Id: <20220906161827.623e32931b67.Id743a7879e84ae37a849179e536c58b1bf55380f@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg Use a switch statement over the rate type instead of the if chain, to simplify. Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 5eb28f8ee87e..735d5ed412d1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4949,6 +4949,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) { u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK; + u32 gi_ltf; switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { case RATE_MCS_CHAN_WIDTH_20: @@ -5019,9 +5020,12 @@ static void iwl_mvm_set_sta_rate(u32 rate_n_flags, struct rate_info *rinfo) 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); + if (rate_n_flags & RATE_MCS_SGI_MSK) + rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; + + switch (format) { + case RATE_MCS_HE_MSK: + gi_ltf = u32_get_bits(rate_n_flags, RATE_MCS_HE_GI_LTF_MSK); rinfo->flags |= RATE_INFO_FLAGS_HE_MCS; @@ -5060,19 +5064,14 @@ 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; - return; - } - - if (rate_n_flags & RATE_MCS_SGI_MSK) - rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; - - if (format == RATE_MCS_HT_MSK) { + break; + case RATE_MCS_HT_MSK: rinfo->flags |= RATE_INFO_FLAGS_MCS; - - } else if (format == RATE_MCS_VHT_MSK) { + break; + case RATE_MCS_VHT_MSK: rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS; + break; } - } static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, From patchwork Tue Sep 6 13:42:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967558 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32AE0ECAAD5 for ; Tue, 6 Sep 2022 14:08:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240528AbiIFOH7 (ORCPT ); Tue, 6 Sep 2022 10:07:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59682 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240617AbiIFOGM (ORCPT ); Tue, 6 Sep 2022 10:06:12 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3FC6585AB4 for ; Tue, 6 Sep 2022 06:45:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471938; x=1694007938; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=57EsCeN96aU/GbsBp91aR4FkeJbmOE9aupl6NB4s5J4=; b=BanHxC/Z//y8QOPAJQ8rqjeg0BdJYEskkT7ByObnvMIt0ImOGw6AAhNK jKqIDlgs+s7vWxxsA82PWIuSeTz1z1s/TeGwQFhBdoG9X+aIy3lv1RQCD q1/+ofLYCFFofukaUHv1FPdbFXAQiApvJM6O58+V0QbgzLEPuFwamaMA/ uChvYPXqm5mT5ryGUB0V1BQA2asCqM+VDSxvnqykSTbJeKI6UVfUigqiK p8cyZlB9KHVpCC6IeJUNOEU6S7nHecdISgc9LVq3vir02LiBZDd6t5I/Y FSU4dbEjmK3LcTIzunHA1sf3QLc4hWvdJow7uyFOoYl9a0wISWD8SYUow A==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="279608704" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="279608704" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:33 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459692" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:43:32 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Johannes Berg , Gregory Greenman Subject: [PATCH 06/15] wifi: iwlwifi: cfg: remove IWL_DEVICE_BZ_COMMON macro Date: Tue, 6 Sep 2022 16:42:10 +0300 Message-Id: <20220906161827.23d6c92e9a11.I4a11928a6d698079dc742e3ba3d3ce6fd7a878d1@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg We only have a single use of this inside the IWL_DEVICE_BZ macro, so just combine the contents here. Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index c949675ca2ed..110fda65bd21 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -249,7 +249,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = { }, \ } -#define IWL_DEVICE_BZ_COMMON \ +#define IWL_DEVICE_BZ \ .ucode_api_max = IWL_22000_UCODE_API_MAX, \ .ucode_api_min = IWL_22000_UCODE_API_MIN, \ .led_mode = IWL_LED_RF_STATE, \ @@ -285,16 +285,13 @@ static const struct iwl_ht_params iwl_22000_ht_params = { .addr = LDBG_M2S_BUF_WRAP_CNT, \ .mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \ }, \ - } - -#define IWL_DEVICE_BZ \ - IWL_DEVICE_BZ_COMMON, \ + }, \ .trans.umac_prph_offset = 0x300000, \ .trans.device_family = IWL_DEVICE_FAMILY_BZ, \ .trans.base_params = &iwl_ax210_base_params, \ .min_txq_size = 128, \ .gp2_reg_addr = 0xd02c68, \ - .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \ + .min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \ .mon_dram_regs = { \ .write_ptr = { \ .addr = DBGC_CUR_DBGBUF_STATUS, \ From patchwork Tue Sep 6 13:42:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967560 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B098FECAAA1 for ; Tue, 6 Sep 2022 14:10:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233696AbiIFOKq (ORCPT ); Tue, 6 Sep 2022 10:10:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241104AbiIFOIv (ORCPT ); Tue, 6 Sep 2022 10:08:51 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54B5186739 for ; Tue, 6 Sep 2022 06:46:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471979; x=1694007979; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tznXWQ5RkAZHwQ+4mEODzDh0CdtCjKkHrQBezVMonSw=; b=WsRPAkxtXfRrb8oIhvmtTw1GaxXKuX4TKtYqRRQru/jaxgrRVLf+7XOZ juKbn/0Kymtefv5udXaH92nZIRcKHU0edhJzMgK+Lu34ubKfuG8pYzgjb UsTf2oI4EUOMH+H4K80eA2bU8znqJqnzu6Jrtqs0gVcOQNyy7a63w8D/c 4a6e44S4A2JxxEX8Kj9+0clNGHPEwi/B8bIpixX80O6MpRfWZ2SJnjPAr fltk74v2RPIXmShz06Jgm7zKc1vOkHas5sLia15sBIQgIQJ9vA5yIgbO5 1KzfMosbOXCIfZmcSRCDruGvBJPlyMer1lkNAE4iGGzyykYj39FE4GTiD g==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276988996" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276988996" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:41 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459883" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:40 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Haim Dreyfuss , Gregory Greenman Subject: [PATCH 07/15] wifi: iwlwifi: mvm: don't check D0I3 version Date: Tue, 6 Sep 2022 16:42:11 +0300 Message-Id: <20220906161827.87c82482229a.I70456c38ed8f7beb7d62dd618f58e7dc0a7d33b2@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Haim Dreyfuss This code is dead, even old FW versions don't use it. The IWL_D0I3_RESET_REQUIRE flag will be sent by the FW via a notification, instead of command, the notification handler will be introduced later in the series. Signed-off-by: Haim Dreyfuss Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 22 -------------------- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 7 ------- 3 files changed, 30 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index aeb0015b73d2..518755b756b4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2551,7 +2551,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) .id = D0I3_END_CMD, .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, }; - int len; ret = iwl_mvm_send_cmd(mvm, &cmd); if (ret < 0) { @@ -2559,27 +2558,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) ret); goto err; } - switch (mvm->cmd_ver.d0i3_resp) { - case 0: - break; - case 1: - len = iwl_rx_packet_payload_len(cmd.resp_pkt); - if (len != sizeof(u32)) { - IWL_ERR(mvm, - "Error with D0I3_END_CMD response size (%d)\n", - len); - goto err; - } - if (IWL_D0I3_RESET_REQUIRE & - le32_to_cpu(*(__le32 *)cmd.resp_pkt->data)) { - iwl_write32(mvm->trans, CSR_RESET, - CSR_RESET_REG_FLAG_FORCE_NMI); - iwl_free_resp(&cmd); - } - break; - default: - WARN_ON(1); - } } /* after the successful handshake, we're out of D3 */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index bf35e130c876..ea128066eea6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1079,7 +1079,6 @@ struct iwl_mvm { struct list_head resp_pasn_list; struct { - u8 d0i3_resp; u8 range_resp; } cmd_ver; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index db43c8a83a31..7ed4f5a0abc3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1188,13 +1188,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, INIT_DELAYED_WORK(&mvm->cs_tx_unblock_dwork, iwl_mvm_tx_unblock_dwork); - mvm->cmd_ver.d0i3_resp = - iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, D0I3_END_CMD, - 0); - /* we only support version 1 */ - if (WARN_ON_ONCE(mvm->cmd_ver.d0i3_resp > 1)) - goto out_free; - mvm->cmd_ver.range_resp = iwl_fw_lookup_notif_ver(mvm->fw, LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF, 5); From patchwork Tue Sep 6 13:42:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967562 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0437AC6FA86 for ; Tue, 6 Sep 2022 14:10:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240583AbiIFOKw (ORCPT ); Tue, 6 Sep 2022 10:10:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241176AbiIFOI6 (ORCPT ); Tue, 6 Sep 2022 10:08:58 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F7AE85F8C for ; Tue, 6 Sep 2022 06:46:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471981; x=1694007981; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nDrSV8tX9zQNNnNIQiyGZucgO8HMjlnExUc5+3dy1l4=; b=UEXBg8dMRPJKCsVBjL6js06mR3sLp7KIAT9Vzfe9EilQ2lrWPWFtCm/G Utvc77BmpVPB+d+YfDA0rDV8SqkwQAqP672GdI0d7cOca24S5HgfcUi7O KWKykOy0B3JNpt9BCVaadX9yCEuputx57/IiiC5oFrOEvBodnba5PYQct 9pJAZ5CJDhIEr59tI1Tf4oLbYqqK+05qD6sstDsVnJPDIpyvkjulRZuUK dXgUv2qEg30f9ATqVv5jAGtFg5P1Qm1ehpAZKOWe0q29wes2xtyMLVx8e fdQUVUsIOz/fXBPtneQIi8Adn+PvBxi0HzGV7zL16JKSUGDBABphry/d4 w==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989012" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989012" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:44 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459889" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:42 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Haim Dreyfuss , Yedidya Benshimol , Gregory Greenman Subject: [PATCH 08/15] wifi: iwlwifi: mvm: Add support for wowlan info notification Date: Tue, 6 Sep 2022 16:42:12 +0300 Message-Id: <20220906161827.3ce8deefd929.Ieba8610e8bb4bec788076371ae38becb4a3d20d5@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Haim Dreyfuss IMR (Isolated Memory Regions) is a mechanism to protect memory regions from unwarranted access by agents in the system that should not have access to that memory. When IMR is enabled, pages in the DRAM will be located within the IMR memory space, accessible only by the device. As a side effect, during S4 (a.k.a hibernate) the IMR memory space is not retained. While the DRAM is saved to the disk and restored by the OS upon resume, the IMR, which is hidden from the OS neither saved upon suspend nor restored upon resume. As a consequence of the above, it turned out that commands cannot be sent as part of the resume flow, and so after ending d3 the FW needs to use notifications instead of cmd-resp. The resume flow becomes asynchronous, with a series of notifications, starting with wowlan_info_notif, through wowlan_pkt_notif and complete the resume flow by d3_end_notif. This patch adds the support for wowlan info notification. The wake packet has been removed from the wowlan info struct and will be handled in a dedicated notification. Signed-off-by: Yedidya Benshimol Signed-off-by: Haim Dreyfuss Signed-off-by: Gregory Greenman --- .../net/wireless/intel/iwlwifi/fw/api/d3.h | 39 ++- .../wireless/intel/iwlwifi/fw/api/offload.h | 7 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 227 ++++++++++++++---- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 4 files changed, 230 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index 4cd9ab23954e..7b2501fe50e6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -766,6 +766,43 @@ struct iwl_wowlan_status_v12 { u8 wake_packet[]; /* can be truncated from _length to _bufsize */ } __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_12 */ +/** + * struct iwl_wowlan_info_notif - WoWLAN information notification + * @gtk: GTK data + * @igtk: IGTK data + * @replay_ctr: GTK rekey replay counter + * @pattern_number: number of the matched patterns + * @reserved1: reserved + * @qos_seq_ctr: QoS sequence counters to use next + * @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason + * @num_of_gtk_rekeys: number of GTK rekeys + * @transmitted_ndps: number of transmitted neighbor discovery packets + * @received_beacons: number of received beacons + * @wake_packet_length: wakeup packet length + * @wake_packet_bufsize: wakeup packet buffer size + * @tid_tear_down: bit mask of tids whose BA sessions were closed + * in suspend state + * @station_id: station id + * @reserved2: reserved + */ +struct iwl_wowlan_info_notif { + struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM]; + struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM]; + __le64 replay_ctr; + __le16 pattern_number; + __le16 reserved1; + __le16 qos_seq_ctr[8]; + __le32 wakeup_reasons; + __le32 num_of_gtk_rekeys; + __le32 transmitted_ndps; + __le32 received_beacons; + __le32 wake_packet_length; + __le32 wake_packet_bufsize; + u8 tid_tear_down; + u8 station_id; + u8 reserved2[2]; +} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_1 */ + /* TODO: NetDetect API */ #endif /* __iwl_fw_api_d3_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h index 5204aa94e72a..ae2263e2e293 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h @@ -3,7 +3,7 @@ * Copyright (C) 2012-2014 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2021 Intel Corporation + * Copyright (C) 2021-2022 Intel Corporation */ #ifndef __iwl_fw_api_offload_h__ #define __iwl_fw_api_offload_h__ @@ -12,6 +12,11 @@ * enum iwl_prot_offload_subcmd_ids - protocol offload commands */ enum iwl_prot_offload_subcmd_ids { + /** + * @WOWLAN_INFO_NOTIFICATION: Notification in &struct iwl_wowlan_info_notif + */ + WOWLAN_INFO_NOTIFICATION = 0xFD, + /** * @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 518755b756b4..f522cc105b53 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1995,6 +1995,30 @@ iwl_mvm_parse_wowlan_status_common(v7) iwl_mvm_parse_wowlan_status_common(v9) iwl_mvm_parse_wowlan_status_common(v12) +static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm, + struct iwl_wowlan_info_notif *data, + struct iwl_wowlan_status_data *status, + u32 len) +{ + u32 i; + + if (len < sizeof(*data)) { + IWL_ERR(mvm, "Invalid WoWLAN info notification!\n"); + status = NULL; + return; + } + + status->replay_ctr = le64_to_cpu(data->replay_ctr); + status->pattern_number = le16_to_cpu(data->pattern_number); + for (i = 0; i < IWL_MAX_TID_COUNT; 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); +} + static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status, struct iwl_wowlan_gtk_status_v2 *data) { @@ -2194,15 +2218,13 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, u8 sta_id) /* releases the MVM mutex */ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) + struct ieee80211_vif *vif, + struct iwl_wowlan_status_data *status) { - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_wowlan_status_data *status; int i; bool keep; struct iwl_mvm_sta *mvm_ap_sta; - status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id); if (!status) goto out_unlock; @@ -2212,7 +2234,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, /* still at hard-coded place 0 for D3 image */ mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0); if (!mvm_ap_sta) - goto out_free; + goto out_unlock; for (i = 0; i < IWL_MAX_TID_COUNT; i++) { u16 seq = status->qos_seq_ctr[i]; @@ -2235,11 +2257,8 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, keep = iwl_mvm_setup_connection_keep(mvm, vif, status); - kfree(status); return keep; -out_free: - kfree(status); out_unlock: mutex_unlock(&mvm->mutex); return false; @@ -2356,24 +2375,23 @@ static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm, } static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) + struct ieee80211_vif *vif, + struct iwl_wowlan_status_data *status) { struct cfg80211_wowlan_nd_info *net_detect = NULL; struct cfg80211_wowlan_wakeup wakeup = { .pattern_idx = -1, }; struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; - struct iwl_wowlan_status_data *status; struct iwl_mvm_nd_query_results query; unsigned long matched_profiles; u32 reasons = 0; int i, n_matches, ret; - status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA); - if (status) { - reasons = status->wakeup_reasons; - kfree(status); - } + if (WARN_ON(!status)) + return; + + reasons = status->wakeup_reasons; if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) wakeup.rfkill_release = true; @@ -2504,16 +2522,142 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm, return false; } +/** + * enum iwl_d3_notif - d3 notifications + * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF was received + */ +enum iwl_d3_notif { + IWL_D3_NOTIF_WOWLAN_INFO = BIT(0), +}; + +/* manage d3 resume data */ +struct iwl_d3_data { + struct iwl_wowlan_status_data *status; + bool test; + u32 notif_expected; /* bitmap - see &enum iwl_d3_notif */ + u32 notif_received; /* bitmap - see &enum iwl_d3_notif */ +}; + +/* + * This function assumes: + * 1. The mutex is already held. + * 2. The callee functions unlock the mutex. + */ +static void iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct iwl_d3_data *d3_data, + bool test) +{ + lockdep_assert_held(&mvm->mutex); + + /* if FW uses status notification, status shouldn't be NULL here */ + if (!d3_data->status) { + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + d3_data->status = iwl_mvm_get_wakeup_status(mvm, mvm->net_detect ? + IWL_MVM_INVALID_STA : + mvmvif->ap_sta_id); + } + + if (mvm->net_detect) { + iwl_mvm_query_netdetect_reasons(mvm, vif, d3_data->status); + } else { + bool keep = iwl_mvm_query_wakeup_reasons(mvm, vif, + d3_data->status); + +#ifdef CONFIG_IWLWIFI_DEBUGFS + if (keep) + mvm->keep_vif = vif; +#endif + + if (!test) + ieee80211_iterate_active_interfaces_mtx(mvm->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_d3_disconnect_iter, + keep ? vif : NULL); + } +} + +static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt, void *data) +{ + struct iwl_mvm *mvm = + container_of(notif_wait, struct iwl_mvm, notif_wait); + struct iwl_d3_data *d3_data = data; + u32 len; + + switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) { + case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION): { + struct iwl_wowlan_info_notif *notif = (void *)pkt->data; + + if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_INFO) { + /* We might get two notifications due to dual bss */ + IWL_DEBUG_WOWLAN(mvm, + "Got additional wowlan info notification\n"); + break; + } + + d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_INFO; + len = iwl_rx_packet_payload_len(pkt); + iwl_mvm_parse_wowlan_info_notif(mvm, notif, d3_data->status, + len); + break; + } + default: + WARN_ON(1); + } + + return d3_data->notif_received == d3_data->notif_expected; +} + +#define IWL_MVM_D3_NOTIF_TIMEOUT (HZ / 5) + +static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, + struct iwl_d3_data *d3_data, + enum iwl_d3_status *d3_status, + bool test) +{ + static const u16 d3_resume_notif[] = { + WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION) + }; + struct iwl_notification_wait wait_d3_notif; + int ret; + + iwl_init_notification_wait(&mvm->notif_wait, &wait_d3_notif, + d3_resume_notif, ARRAY_SIZE(d3_resume_notif), + iwl_mvm_wait_d3_notif, d3_data); + + ret = iwl_trans_d3_resume(mvm->trans, d3_status, test, false); + if (ret) { + iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif); + return ret; + } + + if (*d3_status != IWL_D3_STATUS_ALIVE) { + IWL_INFO(mvm, "Device was reset during suspend\n"); + iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif); + return -ENOENT; + } + + return iwl_wait_notification(&mvm->notif_wait, &wait_d3_notif, + IWL_MVM_D3_NOTIF_TIMEOUT); +} + static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) { struct ieee80211_vif *vif = NULL; int ret = 1; enum iwl_d3_status d3_status; - bool keep = false; + struct iwl_d3_data d3_data = { + .test = test, + .notif_expected = IWL_D3_NOTIF_WOWLAN_INFO, + }; bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST); + /* currently disabled */ + bool resume_notif_based = false; mutex_lock(&mvm->mutex); @@ -2537,7 +2681,20 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) goto err; } - ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image); + if (resume_notif_based) { + d3_data.status = kzalloc(sizeof(*d3_data.status), GFP_KERNEL); + if (!d3_data.status) { + IWL_ERR(mvm, "Failed to allocate wowlan status\n"); + ret = -ENOMEM; + goto err; + } + + ret = iwl_mvm_d3_notif_wait(mvm, &d3_data, &d3_status, test); + } else { + ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, + !unified_image); + } + if (ret) goto err; @@ -2546,7 +2703,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) goto err; } - if (d0i3_first) { + if (d0i3_first && mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_22000) { struct iwl_host_cmd cmd = { .id = D0I3_END_CMD, .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, @@ -2576,41 +2733,27 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) /* Re-configure default SAR profile */ iwl_mvm_sar_select_profile(mvm, 1, 1); - if (mvm->net_detect) { + if (mvm->net_detect && unified_image) { /* If this is a non-unified image, we restart the FW, * so no need to stop the netdetect scan. If that * fails, continue and try to get the wake-up reasons, * but trigger a HW restart by keeping a failure code * in ret. */ - if (unified_image) - ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT, - false); - - iwl_mvm_query_netdetect_reasons(mvm, vif); - /* has unlocked the mutex, so skip that */ - goto out; - } else { - keep = iwl_mvm_query_wakeup_reasons(mvm, vif); -#ifdef CONFIG_IWLWIFI_DEBUGFS - if (keep) - mvm->keep_vif = vif; -#endif - /* has unlocked the mutex, so skip that */ - goto out_iterate; + ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT, + false); } + iwl_mvm_choose_query_wakeup_reasons(mvm, vif, &d3_data, d3_data.test); + /* has unlocked the mutex, so skip that */ + goto out; + err: - iwl_mvm_free_nd(mvm); mutex_unlock(&mvm->mutex); - -out_iterate: - if (!test) - ieee80211_iterate_active_interfaces_mtx(mvm->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_d3_disconnect_iter, keep ? vif : NULL); - out: + kfree(d3_data.status); + iwl_mvm_free_nd(mvm); + clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); /* no need to reset the device in unified images, if successful */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 7ed4f5a0abc3..e380ee841773 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -574,6 +574,7 @@ static const struct iwl_hcmd_names iwl_mvm_location_names[] = { * Access is done through binary search */ static const struct iwl_hcmd_names iwl_mvm_prot_offload_names[] = { + HCMD_NAME(WOWLAN_INFO_NOTIFICATION), HCMD_NAME(STORED_BEACON_NTF), }; From patchwork Tue Sep 6 13:42:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967566 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94294C6FA89 for ; Tue, 6 Sep 2022 14:11:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240917AbiIFOK6 (ORCPT ); Tue, 6 Sep 2022 10:10:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59682 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241188AbiIFOJA (ORCPT ); Tue, 6 Sep 2022 10:09:00 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71DF585FEF for ; Tue, 6 Sep 2022 06:46:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471983; x=1694007983; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rzUuYUq9kN2DENwdg3HU7YC/J3bpJPa14+nt1QjC20I=; b=lsWHVsfXrahvQRaMlJfDpDfWXTueqLsGup7vAgsnwlITCHimJd+buHRY PlGhQoII17LARIfkbrao+dm3qFN0rEvnSs09BZT1pNCKTR86wew1ha+hu XQxp3IpOzBmxgjqLizRyhFsLet9Dm7hrFAeBJcwFW0F1NEoMu7VkMkCIU PNlrjNxwqc7TLkmyXAQnTAs4HRzPKLSTVi8vjFexaCPY1H9fY8JBtYJTW 0JvN7Whh+zqTLw0pMw91pfrKQB4PUhwr95PasaW/tTHPqm72Y4Rf+HHab kmvuvn/kC/UTqz1FbmL3HxjTBzLkYBqroY6FPDN77xaqk/UDxLV3xsM4D g==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989026" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989026" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:47 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459895" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:45 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Haim Dreyfuss , Yedidya Benshimol , Gregory Greenman Subject: [PATCH 09/15] wifi: iwlwifi: mvm: Add support for wowlan wake packet notification Date: Tue, 6 Sep 2022 16:42:13 +0300 Message-Id: <20220906161827.06d1e6aecf10.Ib3d6a46ffe71d10cbc69bdb5654e6b14c28df245@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Haim Dreyfuss The wowlan info notification is quite big. (~750 bytes without the wake packet itself). The max FW notification size is ~2K. There might be cases where the wake packet gets truncated because of this limit. Separating the wake packet from the wowlan info notification allows us to get more data without trimming it. Note: we currently limit the wake packet to 1600 bytes. Signed-off-by: Yedidya Benshimol Signed-off-by: Haim Dreyfuss Signed-off-by: Gregory Greenman --- .../net/wireless/intel/iwlwifi/fw/api/d3.h | 14 ++ .../wireless/intel/iwlwifi/fw/api/offload.h | 5 + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 126 ++++++++++++++---- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 4 files changed, 118 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index 7b2501fe50e6..5588f6d65813 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -803,6 +803,20 @@ struct iwl_wowlan_info_notif { u8 reserved2[2]; } __packed; /* WOWLAN_INFO_NTFY_API_S_VER_1 */ +/** + * struct iwl_wowlan_wake_pkt_notif - WoWLAN wake packet notification + * @wake_packet_length: wakeup packet length + * @station_id: station id + * @reserved: unused + * @wake_packet: wakeup packet + */ +struct iwl_wowlan_wake_pkt_notif { + __le32 wake_packet_length; + u8 station_id; + u8 reserved[3]; + u8 wake_packet[1]; +} __packed; /* WOWLAN_WAKE_PKT_NTFY_API_S_VER_1 */ + /* TODO: NetDetect API */ #endif /* __iwl_fw_api_d3_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h index ae2263e2e293..1a1b7ac78309 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h @@ -12,6 +12,11 @@ * enum iwl_prot_offload_subcmd_ids - protocol offload commands */ enum iwl_prot_offload_subcmd_ids { + /** + * @WOWLAN_WAKE_PKT_NOTIFICATION: Notification in &struct iwl_wowlan_wake_pkt_notif + */ + WOWLAN_WAKE_PKT_NOTIFICATION = 0xFC, + /** * @WOWLAN_INFO_NOTIFICATION: Notification in &struct iwl_wowlan_info_notif */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index f522cc105b53..77e70899c46e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1427,7 +1427,7 @@ struct iwl_wowlan_status_data { u8 flags; } igtk; - u8 wake_packet[]; + u8 *wake_packet; }; static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, @@ -1480,7 +1480,7 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET) wakeup.tcp_match = true; - if (status->wake_packet_bufsize) { + if (status->wake_packet) { int pktsize = status->wake_packet_bufsize; int pktlen = status->wake_packet_length; const u8 *pktdata = status->wake_packet; @@ -1965,7 +1965,7 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \ return NULL; \ } \ \ - status = kzalloc(sizeof(*status) + data_size, GFP_KERNEL); \ + status = kzalloc(sizeof(*status), GFP_KERNEL); \ if (!status) \ return NULL; \ \ @@ -1984,8 +1984,18 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \ 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, \ - status->wake_packet_bufsize); \ + if (status->wake_packet_bufsize) { \ + status->wake_packet = \ + kmemdup(data->wake_packet, \ + status->wake_packet_bufsize, \ + GFP_KERNEL); \ + if (!status->wake_packet) { \ + kfree(status); \ + return NULL; \ + } \ + } else { \ + status->wake_packet = NULL; \ + } \ \ return status; \ } @@ -2197,25 +2207,6 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id) return 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, OFFLOADS_QUERY_CMD, - IWL_FW_CMD_VER_UNKNOWN); - __le32 station_id = cpu_to_le32(sta_id); - u32 cmd_size = cmd_ver != IWL_FW_CMD_VER_UNKNOWN ? sizeof(station_id) : 0; - - if (!mvm->net_detect) { - /* only for tracing for now */ - int ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0, - cmd_size, &station_id); - if (ret) - IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret); - } - - return iwl_mvm_send_wowlan_get_status(mvm, sta_id); -} - /* releases the MVM mutex */ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, struct ieee80211_vif *vif, @@ -2525,9 +2516,11 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm, /** * enum iwl_d3_notif - d3 notifications * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF was received + * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF was received */ enum iwl_d3_notif { IWL_D3_NOTIF_WOWLAN_INFO = BIT(0), + IWL_D3_NOTIF_WOWLAN_WAKE_PKT = BIT(1), }; /* manage d3 resume data */ @@ -2553,10 +2546,9 @@ static void iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, /* if FW uses status notification, status shouldn't be NULL here */ if (!d3_data->status) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + u8 sta_id = mvm->net_detect ? IWL_MVM_INVALID_STA : mvmvif->ap_sta_id; - d3_data->status = iwl_mvm_get_wakeup_status(mvm, mvm->net_detect ? - IWL_MVM_INVALID_STA : - mvmvif->ap_sta_id); + d3_data->status = iwl_mvm_send_wowlan_get_status(mvm, sta_id); } if (mvm->net_detect) { @@ -2578,6 +2570,55 @@ static void iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, } } +#define IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT (IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET | \ + IWL_WOWLAN_WAKEUP_BY_PATTERN | \ + IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN |\ + IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN_WILDCARD |\ + IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN |\ + IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN_WILDCARD) + +static int iwl_mvm_wowlan_store_wake_pkt(struct iwl_mvm *mvm, + struct iwl_wowlan_wake_pkt_notif *notif, + struct iwl_wowlan_status_data *status, + u32 len) +{ + u32 data_size, packet_len = le32_to_cpu(notif->wake_packet_length); + + if (len < sizeof(*notif)) { + IWL_ERR(mvm, "Invalid WoWLAN wake packet notification!\n"); + return -EIO; + } + + if (WARN_ON(!status)) { + IWL_ERR(mvm, "Got wake packet notification but wowlan status data is NULL\n"); + return -EIO; + } + + if (WARN_ON(!(status->wakeup_reasons & + IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT))) { + IWL_ERR(mvm, "Got wakeup packet but wakeup reason is %x\n", + status->wakeup_reasons); + return -EIO; + } + + data_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif, wake_packet); + + /* data_size got the padding from the notification, remove it. */ + if (packet_len < data_size) + data_size = packet_len; + + status->wake_packet = kmemdup(notif->wake_packet, data_size, + GFP_ATOMIC); + + if (!status->wake_packet) + return -ENOMEM; + + status->wake_packet_length = packet_len; + status->wake_packet_bufsize = data_size; + + return 0; +} + static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt, void *data) { @@ -2585,6 +2626,7 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, container_of(notif_wait, struct iwl_mvm, notif_wait); struct iwl_d3_data *d3_data = data; u32 len; + int ret; switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) { case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION): { @@ -2601,6 +2643,31 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, len = iwl_rx_packet_payload_len(pkt); iwl_mvm_parse_wowlan_info_notif(mvm, notif, d3_data->status, len); + if (d3_data->status && + d3_data->status->wakeup_reasons & IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT) + /* We are supposed to get also wake packet notif */ + d3_data->notif_expected |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT; + + break; + } + case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION): { + struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data; + + if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_WAKE_PKT) { + /* We shouldn't get two wake packet notifications */ + IWL_ERR(mvm, + "Got additional wowlan wake packet notification\n"); + } else { + d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT; + len = iwl_rx_packet_payload_len(pkt); + ret = iwl_mvm_wowlan_store_wake_pkt(mvm, notif, + d3_data->status, + len); + if (ret) + IWL_ERR(mvm, + "Can't parse WOWLAN_WAKE_PKT_NOTIFICATION\n"); + } + break; } default: @@ -2618,7 +2685,8 @@ static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, bool test) { static const u16 d3_resume_notif[] = { - WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION) + WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION), + WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION) }; struct iwl_notification_wait wait_d3_notif; int ret; @@ -2751,6 +2819,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) err: mutex_unlock(&mvm->mutex); out: + if (d3_data.status) + kfree(d3_data.status->wake_packet); kfree(d3_data.status); iwl_mvm_free_nd(mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index e380ee841773..9c8adb0c2acf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -574,6 +574,7 @@ static const struct iwl_hcmd_names iwl_mvm_location_names[] = { * Access is done through binary search */ static const struct iwl_hcmd_names iwl_mvm_prot_offload_names[] = { + HCMD_NAME(WOWLAN_WAKE_PKT_NOTIFICATION), HCMD_NAME(WOWLAN_INFO_NOTIFICATION), HCMD_NAME(STORED_BEACON_NTF), }; From patchwork Tue Sep 6 13:42:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967561 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C941ECAAD5 for ; Tue, 6 Sep 2022 14:10:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240471AbiIFOKt (ORCPT ); Tue, 6 Sep 2022 10:10:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59466 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241168AbiIFOI5 (ORCPT ); Tue, 6 Sep 2022 10:08:57 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4793F868AF for ; Tue, 6 Sep 2022 06:46:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471987; x=1694007987; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=W7CK7F+9fxRc3H7WEk1L1dHFbjNCtwDCqmw5x07uFyo=; b=agFqV1/19DpAGFlM+y+2bG0PqZGalSGXdQ2AVwDv3iH9UUrUwoW530R9 iZ17lTAIzRtpwyweiJWOGy1FQbVAhrNcbbwBe2LEsQw3kHLqwRGBFFVKJ vBkrtyFRR8g0It+CH53qByDTPSziNNmx+lGlm4rfFzrRaLww5FfUpzGfN k2Ux976zL24AuyvlQDiSfqYTp5uL7yHZMtAi/Z3GmM6N1z4zb5R+EOwMC Zjk0k8DiKFD21HSQnFdJ1w+A5dIDwywJWZK8gnqKTFl/C1wH1oj5zQfPM gzuzJjras1cGOrWpBI/FXwPaBubujg6CJhAWY/p8tzwLWqPGDFPSfk455 A==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989040" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989040" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:50 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459907" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:48 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Haim Dreyfuss , Yedidya Benshimol , Gregory Greenman Subject: [PATCH 10/15] wifi: iwlwifi: mvm: Add support for d3 end notification Date: Tue, 6 Sep 2022 16:42:14 +0300 Message-Id: <20220906161827.898ecba881b2.I13eb69bb5af08b9ac33043647eaed6b8d50e8659@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Haim Dreyfuss Due to IMR, when host returns from hibernate, commands cannot be sent as part of the resume flow, and so after ending d3 the FW needs to send notifications instead of responses. This notification indicates whether a fw reset is required. Signed-off-by: Yedidya Benshimol Signed-off-by: Haim Dreyfuss Signed-off-by: Gregory Greenman --- .../net/wireless/intel/iwlwifi/fw/api/d3.h | 8 +++++ .../wireless/intel/iwlwifi/fw/api/offload.h | 5 +++ drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 34 ++++++++++++++++--- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index 5588f6d65813..df0833890e55 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -817,6 +817,14 @@ struct iwl_wowlan_wake_pkt_notif { u8 wake_packet[1]; } __packed; /* WOWLAN_WAKE_PKT_NTFY_API_S_VER_1 */ +/** + * struct iwl_mvm_d3_end_notif - d3 end notification + * @flags: See &enum iwl_d0i3_flags + */ +struct iwl_mvm_d3_end_notif { + __le32 flags; +} __packed; + /* TODO: NetDetect API */ #endif /* __iwl_fw_api_d3_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h index 1a1b7ac78309..a0123f81f5d8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h @@ -22,6 +22,11 @@ enum iwl_prot_offload_subcmd_ids { */ WOWLAN_INFO_NOTIFICATION = 0xFD, + /** + * @D3_END_NOTIFICATION: End D3 state notification + */ + D3_END_NOTIFICATION = 0xFE, + /** * @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 77e70899c46e..3a593f6175fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2517,16 +2517,21 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm, * enum iwl_d3_notif - d3 notifications * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF was received * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF was received + * @IWL_D3_NOTIF_PROT_OFFLOAD: PROT_OFFLOAD_NOTIF was received + * @IWL_D3_NOTIF_D3_END_NOTIF: D3_END_NOTIF was received */ enum iwl_d3_notif { IWL_D3_NOTIF_WOWLAN_INFO = BIT(0), IWL_D3_NOTIF_WOWLAN_WAKE_PKT = BIT(1), + IWL_D3_NOTIF_PROT_OFFLOAD = BIT(2), + IWL_D3_NOTIF_D3_END_NOTIF = BIT(3) }; /* manage d3 resume data */ struct iwl_d3_data { struct iwl_wowlan_status_data *status; bool test; + u32 d3_end_flags; u32 notif_expected; /* bitmap - see &enum iwl_d3_notif */ u32 notif_received; /* bitmap - see &enum iwl_d3_notif */ }; @@ -2670,6 +2675,14 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, break; } + case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): { + struct iwl_mvm_d3_end_notif *notif = (void *)pkt->data; + + d3_data->d3_end_flags = __le32_to_cpu(notif->flags); + d3_data->notif_received |= IWL_D3_NOTIF_D3_END_NOTIF; + + break; + } default: WARN_ON(1); } @@ -2686,7 +2699,8 @@ static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, { static const u16 d3_resume_notif[] = { WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION), - WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION) + WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION), + WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION) }; struct iwl_notification_wait wait_d3_notif; int ret; @@ -2718,7 +2732,9 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) enum iwl_d3_status d3_status; struct iwl_d3_data d3_data = { .test = test, - .notif_expected = IWL_D3_NOTIF_WOWLAN_INFO, + .notif_expected = + IWL_D3_NOTIF_WOWLAN_INFO | + IWL_D3_NOTIF_D3_END_NOTIF, }; bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); @@ -2788,6 +2804,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) /* after the successful handshake, we're out of D3 */ mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; + /* when reset is required we can't send these following commands */ + if (d3_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE) + goto query_wakeup_reasons; + /* * Query the current location and source from the D3 firmware so we * can play it back when we re-intiailize the D0 firmware @@ -2812,6 +2832,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) false); } +query_wakeup_reasons: iwl_mvm_choose_query_wakeup_reasons(mvm, vif, &d3_data, d3_data.test); /* has unlocked the mutex, so skip that */ goto out; @@ -2832,9 +2853,14 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) if (d0i3_first) return 0; - ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL); - if (!ret) + if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, + D3_END_NOTIFICATION, 0)) { + ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL); + if (!ret) + return 0; + } else if (!(d3_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE)) { return 0; + } } /* diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 9c8adb0c2acf..3eb59b958801 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -576,6 +576,7 @@ static const struct iwl_hcmd_names iwl_mvm_location_names[] = { static const struct iwl_hcmd_names iwl_mvm_prot_offload_names[] = { HCMD_NAME(WOWLAN_WAKE_PKT_NOTIFICATION), HCMD_NAME(WOWLAN_INFO_NOTIFICATION), + HCMD_NAME(D3_END_NOTIFICATION), HCMD_NAME(STORED_BEACON_NTF), }; From patchwork Tue Sep 6 13:42:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967565 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 089C4ECAAD5 for ; Tue, 6 Sep 2022 14:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240861AbiIFOK4 (ORCPT ); Tue, 6 Sep 2022 10:10:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241273AbiIFOJV (ORCPT ); Tue, 6 Sep 2022 10:09:21 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8C1D7E321 for ; Tue, 6 Sep 2022 06:46:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471989; x=1694007989; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Bmt+8Xkm4Lsqx2EPIpivvCH7Yqisx486Dbb78u3vDcI=; b=mYmtu2+BZJqWPLSf+empyNPe3WL5Ntw2qtaE9ZYjKc0k0ccpehqep63m nxtZIiaaiYGMA6Ej52w1Jk0d9IB36isUf7oSfEG+ke1+p/x114qsK/iPA 0yqO+4qEy2lcB4I/Ye9/dhiFNt9r0wmi4rYUyrggmlqh3AMLulRtU9m0g JSIAQM2XJElNpsU5SG1XYQL4Ew6aMpypKR7XbtvBeOrZRgwMqpg5V9YWY wETvxlpXv+vGUFRju9xQVQE8tCa9KD1xOqckHAHLH5xXt92QgLbWyk1Oh E5DIqPCOSx2uXIz5WH5NDAF7qJaDmr9VUAQe/4cc5qZ2LB9NLABSwT+i7 Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989048" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989048" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:52 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459919" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:51 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Haim Dreyfuss , Gregory Greenman Subject: [PATCH 11/15] wifi: iwlwifi: mvm: enable resume based on notifications Date: Tue, 6 Sep 2022 16:42:15 +0300 Message-Id: <20220906161827.a6344ba23df5.I09fce8cf5aac1d46b40ae81b1abcf7a0e54af196@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Haim Dreyfuss We have recently added support for resume based on notifications. Enable it. Signed-off-by: Haim Dreyfuss Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 3a593f6175fd..90871f3603de 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2725,6 +2725,16 @@ static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, IWL_MVM_D3_NOTIF_TIMEOUT); } +static inline bool iwl_mvm_d3_resume_notif_based(struct iwl_mvm *mvm) +{ + return iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, + WOWLAN_INFO_NOTIFICATION, 0) && + iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, + WOWLAN_WAKE_PKT_NOTIFICATION, 0) && + iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, + D3_END_NOTIFICATION, 0); +} + static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) { struct ieee80211_vif *vif = NULL; @@ -2740,8 +2750,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST); - /* currently disabled */ - bool resume_notif_based = false; + bool resume_notif_based = iwl_mvm_d3_resume_notif_based(mvm); mutex_lock(&mvm->mutex); From patchwork Tue Sep 6 13:42:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967563 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB3FFECAAA1 for ; Tue, 6 Sep 2022 14:10:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238465AbiIFOKx (ORCPT ); Tue, 6 Sep 2022 10:10:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34414 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241280AbiIFOJV (ORCPT ); Tue, 6 Sep 2022 10:09:21 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E0A67F10A for ; Tue, 6 Sep 2022 06:46:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471991; x=1694007991; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iLXyuL7AdCBwAh8iyyXHea0uwWiE2gay49lCti7pe4o=; b=AfNaJ8DHu7NKp5EtvpnfCnLDUWcDaRYecmOykeUNL2qFt5sJqYMt+li4 6mk5/4Ti8zvK/swe+gCpPlGJBOokfZ3AUajjBl18udPZGALrgVoS6z0UD 1CEH/ANTN6yU0s8S29fND7uAVq5rfff7KhPG8U+Pl8FgPIhKPD06FwPpU fL2sa+C3haMtk8gkNDLTkSTxpTY9kJFVgU1cRwpQPwvYMb0Xi/ZnRSzRH zRlJfzL9lxffhAGkx9+0+BeHCwHVXK/ySSAm2FQkEy312cQigJaSp20o1 dM96eaztSyHTTX5wtlVsbYoEKYzUJtir03XDaQUU24wVeTTtGVCEEd0bq g==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989064" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989064" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:55 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459942" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:53 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Ilan Peer , Gregory Greenman Subject: [PATCH 12/15] wifi: iwlwifi: mvm: Add handling for scan offload match info notification Date: Tue, 6 Sep 2022 16:42:16 +0300 Message-Id: <20220906161827.bbc5602d0b6f.I1329c231f82e7bf18f7dba0ccbd9f2d4080cbfc1@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ilan Peer To support FW versions that send the scan match information as an asynchronous notification. Signed-off-by: Ilan Peer Signed-off-by: Gregory Greenman --- .../wireless/intel/iwlwifi/fw/api/commands.h | 5 +- .../net/wireless/intel/iwlwifi/fw/api/scan.h | 20 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 192 +++++++++++++----- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 8 + 4 files changed, 166 insertions(+), 59 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index c78d2f1c722c..0b052c2e563a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2020 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation */ #ifndef __iwl_fw_api_commands_h__ #define __iwl_fw_api_commands_h__ @@ -20,6 +20,8 @@ * &enum iwl_phy_ops_subcmd_ids * @DATA_PATH_GROUP: data path group, uses command IDs from * &enum iwl_data_path_subcmd_ids + * @SCAN_GROUP: scan group, uses command IDs from + * &enum iwl_scan_subcmd_ids * @NAN_GROUP: NAN group, uses command IDs from &enum iwl_nan_subcmd_ids * @LOCATION_GROUP: location group, uses command IDs from * &enum iwl_location_subcmd_ids @@ -36,6 +38,7 @@ enum iwl_mvm_command_groups { MAC_CONF_GROUP = 0x3, PHY_OPS_GROUP = 0x4, DATA_PATH_GROUP = 0x5, + SCAN_GROUP = 0x6, NAN_GROUP = 0x7, LOCATION_GROUP = 0x8, PROT_OFFLOAD_GROUP = 0xb, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 5543d9cb74c8..7ba0e3409199 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2021 Intel Corporation + * Copyright (C) 2012-2014, 2018-2022 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -9,6 +9,16 @@ /* Scan Commands, Responses, Notifications */ +/** + * enum iwl_scan_subcmd_ids - scan commands + */ +enum iwl_scan_subcmd_ids { + /** + * @OFFLOAD_MATCH_INFO_NOTIF: &struct iwl_scan_offload_match_info + */ + OFFLOAD_MATCH_INFO_NOTIF = 0xFC, +}; + /* Max number of IEs for direct SSID scans in a command */ #define PROBE_OPTION_MAX 20 @@ -1188,7 +1198,7 @@ struct iwl_scan_offload_profile_match { } __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_2 */ /** - * struct iwl_scan_offload_profiles_query - match results query response + * struct iwl_scan_offload_match_info - match results information * @matched_profiles: bitmap of matched profiles, referencing the * matches passed in the scan offload request * @last_scan_age: age of the last offloaded scan @@ -1200,7 +1210,7 @@ struct iwl_scan_offload_profile_match { * @reserved: reserved * @matches: array of match information, one for each match */ -struct iwl_scan_offload_profiles_query { +struct iwl_scan_offload_match_info { __le32 matched_profiles; __le32 last_scan_age; __le32 n_scans_done; @@ -1210,7 +1220,9 @@ struct iwl_scan_offload_profiles_query { u8 self_recovery; __le16 reserved; struct iwl_scan_offload_profile_match matches[]; -} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 */ +} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 and + * SCAN_OFFLOAD_MATCH_INFO_NOTIFICATION_S_VER_1 + */ /** * struct iwl_umac_scan_iter_complete_notif - notifies end of scanning iteration diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 90871f3603de..8c38e96ae608 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2258,16 +2258,16 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, #define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \ IWL_SCAN_MAX_PROFILES) -struct iwl_mvm_nd_query_results { +struct iwl_mvm_nd_results { u32 matched_profiles; u8 matches[ND_QUERY_BUF_LEN]; }; static int iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, - struct iwl_mvm_nd_query_results *results) + struct iwl_mvm_nd_results *results) { - struct iwl_scan_offload_profiles_query *query; + struct iwl_scan_offload_match_info *query; struct iwl_host_cmd cmd = { .id = SCAN_OFFLOAD_PROFILES_QUERY_CMD, .flags = CMD_WANT_SKB, @@ -2284,7 +2284,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) { - query_len = sizeof(struct iwl_scan_offload_profiles_query); + query_len = sizeof(struct iwl_scan_offload_match_info); matches_len = sizeof(struct iwl_scan_offload_profile_match) * max_profiles; } else { @@ -2315,7 +2315,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, } static int iwl_mvm_query_num_match_chans(struct iwl_mvm *mvm, - struct iwl_mvm_nd_query_results *query, + struct iwl_mvm_nd_results *results, int idx) { int n_chans = 0, i; @@ -2323,13 +2323,13 @@ static int iwl_mvm_query_num_match_chans(struct iwl_mvm *mvm, if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) { struct iwl_scan_offload_profile_match *matches = - (struct iwl_scan_offload_profile_match *)query->matches; + (void *)results->matches; for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; i++) n_chans += hweight8(matches[idx].matching_channels[i]); } else { struct iwl_scan_offload_profile_match_v1 *matches = - (struct iwl_scan_offload_profile_match_v1 *)query->matches; + (void *)results->matches; for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1; i++) n_chans += hweight8(matches[idx].matching_channels[i]); @@ -2339,7 +2339,7 @@ static int iwl_mvm_query_num_match_chans(struct iwl_mvm *mvm, } static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm, - struct iwl_mvm_nd_query_results *query, + struct iwl_mvm_nd_results *results, struct cfg80211_wowlan_nd_match *match, int idx) { @@ -2348,7 +2348,7 @@ static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm, if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) { struct iwl_scan_offload_profile_match *matches = - (struct iwl_scan_offload_profile_match *)query->matches; + (void *)results->matches; for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; i++) if (matches[idx].matching_channels[i / 8] & (BIT(i % 8))) @@ -2356,7 +2356,7 @@ static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm, mvm->nd_channels[i]->center_freq; } else { struct iwl_scan_offload_profile_match_v1 *matches = - (struct iwl_scan_offload_profile_match_v1 *)query->matches; + (void *)results->matches; for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1 * 8; i++) if (matches[idx].matching_channels[i / 8] & (BIT(i % 8))) @@ -2365,24 +2365,50 @@ static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm, } } +/** + * enum iwl_d3_notif - d3 notifications + * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF was received + * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF was received + * @IWL_D3_NOTIF_PROT_OFFLOAD: PROT_OFFLOAD_NOTIF was received + * @IWL_D3_ND_MATCH_INFO: OFFLOAD_MATCH_INFO_NOTIF was received + * @IWL_D3_NOTIF_D3_END_NOTIF: D3_END_NOTIF was received + */ +enum iwl_d3_notif { + IWL_D3_NOTIF_WOWLAN_INFO = BIT(0), + IWL_D3_NOTIF_WOWLAN_WAKE_PKT = BIT(1), + IWL_D3_NOTIF_PROT_OFFLOAD = BIT(2), + IWL_D3_ND_MATCH_INFO = BIT(3), + IWL_D3_NOTIF_D3_END_NOTIF = BIT(4) +}; + +/* manage d3 resume data */ +struct iwl_d3_data { + struct iwl_wowlan_status_data *status; + bool test; + u32 d3_end_flags; + u32 notif_expected; /* bitmap - see &enum iwl_d3_notif */ + u32 notif_received; /* bitmap - see &enum iwl_d3_notif */ + struct iwl_mvm_nd_results *nd_results; + bool nd_results_valid; +}; + static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_wowlan_status_data *status) + struct iwl_d3_data *d3_data) { struct cfg80211_wowlan_nd_info *net_detect = NULL; struct cfg80211_wowlan_wakeup wakeup = { .pattern_idx = -1, }; struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; - struct iwl_mvm_nd_query_results query; unsigned long matched_profiles; u32 reasons = 0; int i, n_matches, ret; - if (WARN_ON(!status)) - return; + if (WARN_ON(!d3_data || !d3_data->status)) + goto out; - reasons = status->wakeup_reasons; + reasons = d3_data->status->wakeup_reasons; if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) wakeup.rfkill_release = true; @@ -2390,13 +2416,22 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) goto out; - ret = iwl_mvm_netdetect_query_results(mvm, &query); - if (ret || !query.matched_profiles) { + if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, + WOWLAN_INFO_NOTIFICATION, 0)) { + IWL_INFO(mvm, "Query FW for ND results\n"); + ret = iwl_mvm_netdetect_query_results(mvm, d3_data->nd_results); + + } else { + IWL_INFO(mvm, "Notification based ND results\n"); + ret = d3_data->nd_results_valid ? 0 : -1; + } + + if (ret || !d3_data->nd_results->matched_profiles) { wakeup_report = NULL; goto out; } - matched_profiles = query.matched_profiles; + matched_profiles = d3_data->nd_results->matched_profiles; if (mvm->n_nd_match_sets) { n_matches = hweight_long(matched_profiles); } else { @@ -2413,7 +2448,9 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, struct cfg80211_wowlan_nd_match *match; int idx, n_channels = 0; - n_channels = iwl_mvm_query_num_match_chans(mvm, &query, i); + n_channels = iwl_mvm_query_num_match_chans(mvm, + d3_data->nd_results, + i); match = kzalloc(struct_size(match, channels, n_channels), GFP_KERNEL); @@ -2433,7 +2470,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, if (mvm->n_nd_channels < n_channels) continue; - iwl_mvm_query_set_freqs(mvm, &query, match, i); + iwl_mvm_query_set_freqs(mvm, d3_data->nd_results, match, i); } out_report_nd: @@ -2513,38 +2550,15 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm, return false; } -/** - * enum iwl_d3_notif - d3 notifications - * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF was received - * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF was received - * @IWL_D3_NOTIF_PROT_OFFLOAD: PROT_OFFLOAD_NOTIF was received - * @IWL_D3_NOTIF_D3_END_NOTIF: D3_END_NOTIF was received - */ -enum iwl_d3_notif { - IWL_D3_NOTIF_WOWLAN_INFO = BIT(0), - IWL_D3_NOTIF_WOWLAN_WAKE_PKT = BIT(1), - IWL_D3_NOTIF_PROT_OFFLOAD = BIT(2), - IWL_D3_NOTIF_D3_END_NOTIF = BIT(3) -}; - -/* manage d3 resume data */ -struct iwl_d3_data { - struct iwl_wowlan_status_data *status; - bool test; - u32 d3_end_flags; - u32 notif_expected; /* bitmap - see &enum iwl_d3_notif */ - u32 notif_received; /* bitmap - see &enum iwl_d3_notif */ -}; - /* * This function assumes: * 1. The mutex is already held. * 2. The callee functions unlock the mutex. */ -static void iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct iwl_d3_data *d3_data, - bool test) +static void +iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct iwl_d3_data *d3_data) { lockdep_assert_held(&mvm->mutex); @@ -2557,7 +2571,7 @@ static void iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, } if (mvm->net_detect) { - iwl_mvm_query_netdetect_reasons(mvm, vif, d3_data->status); + iwl_mvm_query_netdetect_reasons(mvm, vif, d3_data); } else { bool keep = iwl_mvm_query_wakeup_reasons(mvm, vif, d3_data->status); @@ -2567,7 +2581,7 @@ static void iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, mvm->keep_vif = vif; #endif - if (!test) + if (!d3_data->test) ieee80211_iterate_active_interfaces_mtx(mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_d3_disconnect_iter, @@ -2624,6 +2638,55 @@ static int iwl_mvm_wowlan_store_wake_pkt(struct iwl_mvm *mvm, return 0; } +static void iwl_mvm_nd_match_info_handler(struct iwl_mvm *mvm, + struct iwl_d3_data *d3_data, + struct iwl_scan_offload_match_info *notif, + u32 len) +{ + struct iwl_wowlan_status_data *status = d3_data->status; + struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm); + struct iwl_mvm_nd_results *results = d3_data->nd_results; + size_t i, matches_len = sizeof(struct iwl_scan_offload_profile_match) * + iwl_umac_scan_get_max_profiles(mvm->fw); + + if (IS_ERR_OR_NULL(vif)) + return; + + if (len < sizeof(struct iwl_scan_offload_match_info)) { + IWL_ERR(mvm, "Invalid scan match info notification\n"); + return; + } + + if (!mvm->net_detect) { + IWL_ERR(mvm, "Unexpected scan match info notification\n"); + return; + } + + if (!status || status->wakeup_reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { + IWL_ERR(mvm, + "Ignore scan match info notification: no reason\n"); + return; + } + +#ifdef CONFIG_IWLWIFI_DEBUGFS + mvm->last_netdetect_scans = le32_to_cpu(notif->n_scans_done); +#endif + + results->matched_profiles = le32_to_cpu(notif->matched_profiles); + IWL_INFO(mvm, "number of matched profiles=%u\n", + results->matched_profiles); + + if (results->matched_profiles) { + memcpy(results->matches, notif->matches, matches_len); + d3_data->nd_results_valid = TRUE; + } + + /* no scan should be active at this point */ + mvm->scan_status = 0; + for (i = 0; i < mvm->max_scans; i++) + mvm->scan_uid_status[i] = 0; +} + static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt, void *data) { @@ -2675,6 +2738,24 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, break; } + case WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF): { + struct iwl_scan_offload_match_info *notif = (void *)pkt->data; + + if (d3_data->notif_received & IWL_D3_ND_MATCH_INFO) { + IWL_ERR(mvm, + "Got additional netdetect match info\n"); + break; + } + + d3_data->notif_received |= IWL_D3_ND_MATCH_INFO; + + /* explicitly set this in the 'expected' as well */ + d3_data->notif_expected |= IWL_D3_ND_MATCH_INFO; + + len = iwl_rx_packet_payload_len(pkt); + iwl_mvm_nd_match_info_handler(mvm, d3_data, notif, len); + break; + } case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): { struct iwl_mvm_d3_end_notif *notif = (void *)pkt->data; @@ -2694,12 +2775,12 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, struct iwl_d3_data *d3_data, - enum iwl_d3_status *d3_status, - bool test) + enum iwl_d3_status *d3_status) { static const u16 d3_resume_notif[] = { WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION), WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION), + WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF), WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION) }; struct iwl_notification_wait wait_d3_notif; @@ -2709,7 +2790,7 @@ static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, d3_resume_notif, ARRAY_SIZE(d3_resume_notif), iwl_mvm_wait_d3_notif, d3_data); - ret = iwl_trans_d3_resume(mvm->trans, d3_status, test, false); + ret = iwl_trans_d3_resume(mvm->trans, d3_status, d3_data->test, false); if (ret) { iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif); return ret; @@ -2740,11 +2821,14 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) struct ieee80211_vif *vif = NULL; int ret = 1; enum iwl_d3_status d3_status; + struct iwl_mvm_nd_results results = {}; struct iwl_d3_data d3_data = { .test = test, .notif_expected = IWL_D3_NOTIF_WOWLAN_INFO | IWL_D3_NOTIF_D3_END_NOTIF, + .nd_results_valid = false, + .nd_results = &results, }; bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); @@ -2782,7 +2866,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) goto err; } - ret = iwl_mvm_d3_notif_wait(mvm, &d3_data, &d3_status, test); + ret = iwl_mvm_d3_notif_wait(mvm, &d3_data, &d3_status); } else { ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image); @@ -2842,7 +2926,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) } query_wakeup_reasons: - iwl_mvm_choose_query_wakeup_reasons(mvm, vif, &d3_data, d3_data.test); + iwl_mvm_choose_query_wakeup_reasons(mvm, vif, &d3_data); /* has unlocked the mutex, so skip that */ goto out; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 3eb59b958801..429963cd8ee1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -554,6 +554,13 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = { HCMD_NAME(RX_QUEUES_NOTIFICATION), }; +/* Please keep this array *SORTED* by hex value. + * Access is done through binary search + */ +static const struct iwl_hcmd_names iwl_mvm_scan_names[] = { + HCMD_NAME(OFFLOAD_MATCH_INFO_NOTIF), +}; + /* Please keep this array *SORTED* by hex value. * Access is done through binary search */ @@ -596,6 +603,7 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = { [MAC_CONF_GROUP] = HCMD_ARR(iwl_mvm_mac_conf_names), [PHY_OPS_GROUP] = HCMD_ARR(iwl_mvm_phy_names), [DATA_PATH_GROUP] = HCMD_ARR(iwl_mvm_data_path_names), + [SCAN_GROUP] = HCMD_ARR(iwl_mvm_scan_names), [LOCATION_GROUP] = HCMD_ARR(iwl_mvm_location_names), [PROT_OFFLOAD_GROUP] = HCMD_ARR(iwl_mvm_prot_offload_names), [REGULATORY_AND_NVM_GROUP] = From patchwork Tue Sep 6 13:42:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967564 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB593C6FA89 for ; Tue, 6 Sep 2022 14:10:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240834AbiIFOKz (ORCPT ); Tue, 6 Sep 2022 10:10:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241303AbiIFOJY (ORCPT ); Tue, 6 Sep 2022 10:09:24 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E26B79A41 for ; Tue, 6 Sep 2022 06:46:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471993; x=1694007993; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=93ISQq+irzOavLdLd3bn6WLgY29G1/toWR4cJd/N8RY=; b=I6W9RXQw1nhV6nt2N2Bydq9XnFPfIoatjARND3dNpsKPs6zPsFEHtJQs zIdR7GuRLeM2kPlbkozTy/KvNqqCan15it7azhuFRsysDdxBJqsgD7rem 4YXVdlrpu4/4v36hY64qsmOoGBsut/IwBishESOAIHzTRWc1nYZgM/iA8 9rC6dDHhKLqO1WWdSJ8aOIzvoEYiJDzLhGWYX6DQ/y4XxhLCAPKv9un+V dkdgtzrdqkgQaYTdm1793m2jMuPJCpIssXyLHJG45ouV5XbGojKANLy1/ VLYh5OaAkn7tOIiYpqmPe85YvdU3TlMvP/om22wK4QrwdPAxlb9J2nkEZ g==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989075" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989075" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:58 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459950" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:56 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, "Haim, Dreyfuss" , Haim@vger.kernel.org, Gregory Greenman Subject: [PATCH 13/15] wifi: iwlwifi: mvm: trigger resume flow before wait for notifications Date: Tue, 6 Sep 2022 16:42:17 +0300 Message-Id: <20220906161827.5f0f251edf9c.Ia49ab73105af6f52aa7d318f4984edecd3b0671a@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: "Haim, Dreyfuss" We have recently enabled resume flow based on notifications. These notifications are sent by the FW when completing the resume flow. From IWL_DEVICE_FAMILY_AX210 the resume flow is triggered by the transport layer on iwl_trans_d3_resume. On IWL_DEVICE_FAMILY_22000 and earlier we trigger the resume flow by sending the D0I3 command. Currently, we are waiting for the notifications before sending the command, the notifications won't be sent by the FW since there is no resume trigger to piggyback on. Send the command before starting the wait flow to fix it. Signed-off-by: Haim, Dreyfuss Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 77 ++++++++++++--------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 8c38e96ae608..012fe872d9aa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2771,11 +2771,46 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait, return d3_data->notif_received == d3_data->notif_expected; } +static int iwl_mvm_resume_firmware(struct iwl_mvm *mvm, bool test) +{ + int ret; + enum iwl_d3_status d3_status; + struct iwl_host_cmd cmd = { + .id = D0I3_END_CMD, + .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, + }; + bool reset = fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); + + ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !reset); + if (ret) + return ret; + + if (d3_status != IWL_D3_STATUS_ALIVE) { + IWL_INFO(mvm, "Device was reset during suspend\n"); + return -ENOENT; + } + + /* + * We should trigger resume flow using command only for 22000 family + * AX210 and above don't need the command since they have + * the doorbell interrupt. + */ + if (mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_22000 && + fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST)) { + ret = iwl_mvm_send_cmd(mvm, &cmd); + if (ret < 0) + IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n", + ret); + } + + return ret; +} + #define IWL_MVM_D3_NOTIF_TIMEOUT (HZ / 5) static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, - struct iwl_d3_data *d3_data, - enum iwl_d3_status *d3_status) + struct iwl_d3_data *d3_data) { static const u16 d3_resume_notif[] = { WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION), @@ -2790,18 +2825,12 @@ static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm, d3_resume_notif, ARRAY_SIZE(d3_resume_notif), iwl_mvm_wait_d3_notif, d3_data); - ret = iwl_trans_d3_resume(mvm->trans, d3_status, d3_data->test, false); + ret = iwl_mvm_resume_firmware(mvm, d3_data->test); if (ret) { iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif); return ret; } - if (*d3_status != IWL_D3_STATUS_ALIVE) { - IWL_INFO(mvm, "Device was reset during suspend\n"); - iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif); - return -ENOENT; - } - return iwl_wait_notification(&mvm->notif_wait, &wait_d3_notif, IWL_MVM_D3_NOTIF_TIMEOUT); } @@ -2820,7 +2849,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) { struct ieee80211_vif *vif = NULL; int ret = 1; - enum iwl_d3_status d3_status; struct iwl_mvm_nd_results results = {}; struct iwl_d3_data d3_data = { .test = test, @@ -2866,32 +2894,13 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) goto err; } - ret = iwl_mvm_d3_notif_wait(mvm, &d3_data, &d3_status); + ret = iwl_mvm_d3_notif_wait(mvm, &d3_data); + if (ret) + goto err; } else { - ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, - !unified_image); - } - - if (ret) - goto err; - - if (d3_status != IWL_D3_STATUS_ALIVE) { - IWL_INFO(mvm, "Device was reset during suspend\n"); - goto err; - } - - if (d0i3_first && mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_22000) { - struct iwl_host_cmd cmd = { - .id = D0I3_END_CMD, - .flags = CMD_WANT_SKB | CMD_SEND_IN_D3, - }; - - ret = iwl_mvm_send_cmd(mvm, &cmd); - if (ret < 0) { - IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n", - ret); + ret = iwl_mvm_resume_firmware(mvm, test); + if (ret < 0) goto err; - } } /* after the successful handshake, we're out of D3 */ From patchwork Tue Sep 6 13:42:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967567 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29DD7C6FA8B for ; Tue, 6 Sep 2022 14:11:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240950AbiIFOLB (ORCPT ); Tue, 6 Sep 2022 10:11:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241304AbiIFOJY (ORCPT ); Tue, 6 Sep 2022 10:09:24 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CBAD8673E for ; Tue, 6 Sep 2022 06:46:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662471993; x=1694007993; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=62X+ntw2Zl4eAMvqexhE4PG72DyERaXLa7R+np6oI5o=; b=Y6ewPprlFW/3sxHtJAdhSqMu+cagpzrA/fBetW6g0OejwYHNIsjDvKid zW1zbx9klqfprVmwnaojgSLKprcSppHmrdsJPPA874BQGZJ26W5g3tZLY X4Ff5L0vLp/KD6RL1zHd2gTPqK0Bt28BlpmaGjVuIJHTyCnx6f84fI8bp MxugHlX29v2U+QUHxFzKZB3KayPUCcCM4AhwP+ybugVwU88Q5ANP3Wv9O SCOMvDVlKdEHsVz0b8JRsXPJlQ0qrQWf/dtsa7WkZER+9Vi22yhDd0PWG AfdBo+tdXaKRWSoVMEA5e3ciJQJdM/g/iG4JDuwzdEmWNsq/x9jvkhXAx w==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989078" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989078" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:45:00 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459965" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:44:58 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Yedidya Benshimol , Gregory Greenman Subject: [PATCH 14/15] wifi: iwlwifi: mvm: iterate over interfaces after an assert in d3 Date: Tue, 6 Sep 2022 16:42:18 +0300 Message-Id: <20220906161827.ad888cc6cd91.Ib56e416fce17df089edf76d22896430df5ebe080@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Yedidya Benshimol In recent patches notifications based d3 resume flow was added, and the resume flow was changed. Currently, when resuming from d3 during which an assert was thrown, the resume flow skips the iteration over active interfaces preventing the sta to reconnect to the ap. Perform the iteration in case an assert was thrown to fix it. Signed-off-by: Yedidya Benshimol Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 012fe872d9aa..d8a67f391ab9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2555,7 +2555,7 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm, * 1. The mutex is already held. * 2. The callee functions unlock the mutex. */ -static void +static bool iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_d3_data *d3_data) @@ -2581,12 +2581,9 @@ iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm, mvm->keep_vif = vif; #endif - if (!d3_data->test) - ieee80211_iterate_active_interfaces_mtx(mvm->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_d3_disconnect_iter, - keep ? vif : NULL); + return keep; } + return false; } #define IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT (IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET | \ @@ -2863,6 +2860,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST); bool resume_notif_based = iwl_mvm_d3_resume_notif_based(mvm); + bool keep = false; mutex_lock(&mvm->mutex); @@ -2935,7 +2933,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) } query_wakeup_reasons: - iwl_mvm_choose_query_wakeup_reasons(mvm, vif, &d3_data); + keep = iwl_mvm_choose_query_wakeup_reasons(mvm, vif, &d3_data); /* has unlocked the mutex, so skip that */ goto out; @@ -2947,6 +2945,12 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) kfree(d3_data.status); iwl_mvm_free_nd(mvm); + if (!d3_data.test && !mvm->net_detect) + ieee80211_iterate_active_interfaces_mtx(mvm->hw, + IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_d3_disconnect_iter, + keep ? vif : NULL); + clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); /* no need to reset the device in unified images, if successful */ From patchwork Tue Sep 6 13:42:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Greenman, Gregory" X-Patchwork-Id: 12967568 X-Patchwork-Delegate: gregory.greenman@intel.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B748CECAAD5 for ; Tue, 6 Sep 2022 14:11:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240966AbiIFOLE (ORCPT ); Tue, 6 Sep 2022 10:11:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241360AbiIFOJc (ORCPT ); Tue, 6 Sep 2022 10:09:32 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EFB312018B for ; Tue, 6 Sep 2022 06:46:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1662472001; x=1694008001; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hoTdyMPRK8mYLBSLeWumzqGvsYvug2vZg1+TRcG7k6E=; b=ZEjby89k3jVu1/jgxTKyjTztf17hsqs2l/N2SOHyHiDVVNWS58MToh3U qlE+pNCNvayMRIFNWCm0ZQhURQVLckM2Q469EFitZjFAP/ea4kaqXhxij fTl4Fqdi7IGrY98C9ajobsEKxxW9584lIgSIAEIu8B4ixB7K7o2Wy6PlJ snYt9bdDqAcQI+LxWekv1Np0GR+PwsOhnF3ztKAPJg1vwOETwsvsyjoiu Aj6t8AoBE1+IbzUjmV44rrW5g3AGR/0pXG+OHkL/dLI18DR970hcfsB+1 5FBTvoXU1+c4gWHo/5ug1lFR+BxeRmSFXV07tUrK4vko6FeDqH0ELOngO w==; X-IronPort-AV: E=McAfee;i="6500,9779,10462"; a="276989089" X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="276989089" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:45:03 -0700 X-IronPort-AV: E=Sophos;i="5.93,294,1654585200"; d="scan'208";a="942459999" Received: from ygueta-mobl2.ger.corp.intel.com (HELO ggreenma-mobl2.lan) ([10.249.82.178]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Sep 2022 06:45:01 -0700 From: gregory.greenman@intel.com To: kvalo@kernel.org, johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Naftali Goldstein , Gregory Greenman Subject: [PATCH 15/15] wifi: iwlwifi: mvm: d3: parse keys from wowlan info notification Date: Tue, 6 Sep 2022 16:42:19 +0300 Message-Id: <20220906161827.ca3fb23cab81.I0a9fe7729af4567b98813bc51bad13ee5512a0ae@changeid> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220906134219.365090-1-gregory.greenman@intel.com> References: <20220906134219.365090-1-gregory.greenman@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Naftali Goldstein This notification replaces the WOWLAN_GET_STATUSES command-and-response, so it's required to parse all the keys in the notification just like what happened when that command was used. Move around a few required static functions in order to avoid forward declarations. Signed-off-by: Naftali Goldstein Signed-off-by: Gregory Greenman --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 171 ++++++++++---------- 1 file changed, 88 insertions(+), 83 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index d8a67f391ab9..919b1f478b4c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1944,6 +1944,94 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, return true; } +static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_gtk_status_v2 *data) +{ + BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key)); + BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY + + 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_gtk_v3(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_gtk_status_v3 *data) +{ + /* The parts we need are identical in v2 and v3 */ +#define CHECK(_f) do { \ + BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) != \ + offsetof(struct iwl_wowlan_gtk_status_v3, _f)); \ + BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\ + offsetofend(struct iwl_wowlan_gtk_status_v3, _f)); \ +} while (0) + + CHECK(key); + CHECK(key_len); + CHECK(key_flags); + CHECK(tkip_mic_key); +#undef CHECK + + iwl_mvm_convert_gtk_v2(status, (void *)data); +} + +static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status, + struct iwl_wowlan_igtk_status *data) +{ + 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 void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm, + struct iwl_wowlan_info_notif *data, + struct iwl_wowlan_status_data *status, + u32 len) +{ + u32 i; + + if (len < sizeof(*data)) { + IWL_ERR(mvm, "Invalid WoWLAN info notification!\n"); + status = NULL; + return; + } + + iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc); + iwl_mvm_convert_gtk_v3(status, &data->gtk[0]); + iwl_mvm_convert_igtk(status, &data->igtk[0]); + + status->replay_ctr = le64_to_cpu(data->replay_ctr); + status->pattern_number = le16_to_cpu(data->pattern_number); + for (i = 0; i < IWL_MAX_TID_COUNT; 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->tid_tear_down = data->tid_tear_down; +} + /* Occasionally, templates would be nice. This is one of those times ... */ #define iwl_mvm_parse_wowlan_status_common(_ver) \ static struct iwl_wowlan_status_data * \ @@ -2005,89 +2093,6 @@ iwl_mvm_parse_wowlan_status_common(v7) iwl_mvm_parse_wowlan_status_common(v9) iwl_mvm_parse_wowlan_status_common(v12) -static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm, - struct iwl_wowlan_info_notif *data, - struct iwl_wowlan_status_data *status, - u32 len) -{ - u32 i; - - if (len < sizeof(*data)) { - IWL_ERR(mvm, "Invalid WoWLAN info notification!\n"); - status = NULL; - return; - } - - status->replay_ctr = le64_to_cpu(data->replay_ctr); - status->pattern_number = le16_to_cpu(data->pattern_number); - for (i = 0; i < IWL_MAX_TID_COUNT; 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); -} - -static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status, - struct iwl_wowlan_gtk_status_v2 *data) -{ - BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key)); - BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY + - 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_gtk_v3(struct iwl_wowlan_status_data *status, - struct iwl_wowlan_gtk_status_v3 *data) -{ - /* The parts we need are identical in v2 and v3 */ -#define CHECK(_f) do { \ - BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) != \ - offsetof(struct iwl_wowlan_gtk_status_v3, _f)); \ - BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\ - offsetofend(struct iwl_wowlan_gtk_status_v3, _f)); \ -} while (0) - - CHECK(key); - CHECK(key_len); - CHECK(key_flags); - CHECK(tkip_mic_key); -#undef CHECK - - iwl_mvm_convert_gtk_v2(status, (void *)data); -} - -static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status, - struct iwl_wowlan_igtk_status *data) -{ - 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) {