Commit c4c95454 authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: iwlwifi: implement WPFC ACPI table loading



We skipped this in the past, but now we will need it for some
platforms. Implement loading the PHY filter configuration IDs
from the WPFC ACPI table. Note that the firmware must also be
aware of the right filter configuration IDs (they're just the
IDs of a filter configuration, not the actual configuration).

Remove the useless hardcoded zeroes while at it.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230614123447.035026ea3169.I3a1fc1fe644fefa0d818ee1926c5fc331d68e8a3@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 1902f195
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -1248,3 +1248,40 @@ bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt)
	return true;
}
IWL_EXPORT_SYMBOL(iwl_acpi_is_ppag_approved);

void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
			      struct iwl_phy_specific_cfg *filters)
{
	struct iwl_phy_specific_cfg tmp = {};
	union acpi_object *wifi_pkg, *data;
	int tbl_rev, i;

	data = iwl_acpi_get_object(fwrt->dev, ACPI_WPFC_METHOD);
	if (IS_ERR(data))
		return;

	/* try to read wtas table revision 1 or revision 0*/
	wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
					 ACPI_WPFC_WIFI_DATA_SIZE,
					 &tbl_rev);
	if (IS_ERR(wifi_pkg))
		goto out_free;

	if (tbl_rev != 0)
		goto out_free;

	BUILD_BUG_ON(ARRAY_SIZE(filters->filter_cfg_chains) != ACPI_WPFC_WIFI_DATA_SIZE);

	for (i = 0; i < ARRAY_SIZE(filters->filter_cfg_chains); i++) {
		if (wifi_pkg->package.elements[i].type != ACPI_TYPE_INTEGER)
			return;
		tmp.filter_cfg_chains[i] =
			cpu_to_le32(wifi_pkg->package.elements[i].integer.value);
	}

	IWL_DEBUG_RADIO(fwrt, "Loaded WPFC filter config from ACPI\n");
	*filters = tmp;
out_free:
	kfree(data);
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_phy_filters);
+11 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "fw/api/power.h"
#include "fw/api/phy.h"
#include "fw/api/nvm-reg.h"
#include "fw/api/config.h"
#include "fw/img.h"
#include "iwl-trans.h"

@@ -23,6 +24,7 @@
#define ACPI_ECKV_METHOD	"ECKV"
#define ACPI_PPAG_METHOD	"PPAG"
#define ACPI_WTAS_METHOD	"WTAS"
#define ACPI_WPFC_METHOD	"WPFC"

#define ACPI_WIFI_DOMAIN	(0x07)

@@ -54,6 +56,7 @@
#define ACPI_EWRD_WIFI_DATA_SIZE_REV2	((ACPI_SAR_PROFILE_NUM - 1) * \
					 ACPI_SAR_NUM_CHAINS_REV2 * \
					 ACPI_SAR_NUM_SUB_BANDS_REV2 + 3)
#define ACPI_WPFC_WIFI_DATA_SIZE	4 /* 4 filter config words */

/* revision 0 and 1 are identical, except for the semantics in the FW */
#define ACPI_GEO_NUM_BANDS_REV0		2
@@ -225,6 +228,9 @@ int iwl_read_ppag_table(struct iwl_fw_runtime *fwrt, union iwl_ppag_table_cmd *c

bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt);

void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
			      struct iwl_phy_specific_cfg *filters);

#else /* CONFIG_ACPI */

static inline void *iwl_acpi_get_dsm_object(struct device *dev, int rev,
@@ -314,6 +320,11 @@ static inline bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt)
	return false;
}

static inline void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
					    struct iwl_phy_specific_cfg *filters)
{
}

#endif /* CONFIG_ACPI */

#endif /* __iwl_fw_acpi__ */
+5 −10
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
 * Copyright (C) 2012-2014, 2018-2019 Intel Corporation
 * Copyright (C) 2012-2014, 2018-2019, 2023 Intel Corporation
 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
 * Copyright (C) 2016-2017 Intel Deutschland GmbH
 */
@@ -67,17 +67,12 @@ enum iwl_calib_cfg {
 * Sent as part of the phy configuration command (v3) to configure specific FW
 * defined PHY filters that can be applied to each antenna.
 *
 * @filter_cfg_chain_a: filter config id for LMAC1 chain A
 * @filter_cfg_chain_b: filter config id for LMAC1 chain B
 * @filter_cfg_chain_c: filter config id for LMAC2 chain A
 * @filter_cfg_chain_d: filter config id for LMAC2 chain B
 * values: 0 - no filter; 0xffffffff - reserved; otherwise - filter id
 * @filter_cfg_chains: filter config id for LMAC1 chain A, LMAC1 chain B,
 *	LMAC2 chain A, LMAC2 chain B (in that order)
 *	values: 0: no filter; 0xffffffff: reserved; otherwise: filter id
 */
struct iwl_phy_specific_cfg {
	__le32 filter_cfg_chain_a;
	__le32 filter_cfg_chain_b;
	__le32 filter_cfg_chain_c;
	__le32 filter_cfg_chain_d;
	__le32 filter_cfg_chains[4];
} __packed; /* PHY_SPECIFIC_CONFIGURATION_API_VER_1*/

/**
+1 −5
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
 * Copyright (C) 2013-2014, 2018-2021 Intel Corporation
 * Copyright (C) 2013-2014, 2018-2023 Intel Corporation
 * Copyright (C) 2015 Intel Deutschland GmbH
 */
#ifndef __MVM_CONSTANTS_H
@@ -109,10 +109,6 @@
#define IWL_MVM_USE_TWT				true
#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA	20
#define IWL_MVM_USE_NSSN_SYNC			0
#define IWL_MVM_PHY_FILTER_CHAIN_A		0
#define IWL_MVM_PHY_FILTER_CHAIN_B		0
#define IWL_MVM_PHY_FILTER_CHAIN_C		0
#define IWL_MVM_PHY_FILTER_CHAIN_D		0
#define IWL_MVM_FTM_INITIATOR_ENABLE_SMOOTH     false
#define IWL_MVM_FTM_INITIATOR_SMOOTH_ALPHA      40
/*  20016 pSec is 6 meter RTT, meaning 3 meter range */
+7 −36
Original line number Diff line number Diff line
@@ -478,40 +478,13 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
	return 0;
}

#ifdef CONFIG_ACPI
static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
				    struct iwl_phy_specific_cfg *phy_filters)
{
	/*
	 * TODO: read specific phy config from BIOS
	 * ACPI table for this feature has not been defined yet,
	 * so for now we use hardcoded values.
	 */

	if (IWL_MVM_PHY_FILTER_CHAIN_A) {
		phy_filters->filter_cfg_chain_a =
			cpu_to_le32(IWL_MVM_PHY_FILTER_CHAIN_A);
	}
	if (IWL_MVM_PHY_FILTER_CHAIN_B) {
		phy_filters->filter_cfg_chain_b =
			cpu_to_le32(IWL_MVM_PHY_FILTER_CHAIN_B);
	}
	if (IWL_MVM_PHY_FILTER_CHAIN_C) {
		phy_filters->filter_cfg_chain_c =
			cpu_to_le32(IWL_MVM_PHY_FILTER_CHAIN_C);
	}
	if (IWL_MVM_PHY_FILTER_CHAIN_D) {
		phy_filters->filter_cfg_chain_d =
			cpu_to_le32(IWL_MVM_PHY_FILTER_CHAIN_D);
	}
}
#else /* CONFIG_ACPI */

static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
				    struct iwl_phy_specific_cfg *phy_filters)
{
}
#ifdef CONFIG_ACPI
	*phy_filters = mvm->phy_filters;
#endif /* CONFIG_ACPI */
}

#if defined(CONFIG_ACPI) && defined(CONFIG_EFI)
static int iwl_mvm_sgom_init(struct iwl_mvm *mvm)
@@ -560,7 +533,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
	u32 cmd_id = PHY_CONFIGURATION_CMD;
	struct iwl_phy_cfg_cmd_v3 phy_cfg_cmd;
	enum iwl_ucode_type ucode_type = mvm->fwrt.cur_fw_img;
	struct iwl_phy_specific_cfg phy_filters = {};
	u8 cmd_ver;
	size_t cmd_size;

@@ -591,11 +563,8 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)

	cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id,
					IWL_FW_CMD_VER_UNKNOWN);
	if (cmd_ver == 3) {
		iwl_mvm_phy_filter_init(mvm, &phy_filters);
		memcpy(&phy_cfg_cmd.phy_specific_cfg, &phy_filters,
		       sizeof(struct iwl_phy_specific_cfg));
	}
	if (cmd_ver >= 3)
		iwl_mvm_phy_filter_init(mvm, &phy_cfg_cmd.phy_specific_cfg);

	IWL_DEBUG_INFO(mvm, "Sending Phy CFG command: 0x%x\n",
		       phy_cfg_cmd.phy_cfg);
@@ -1380,6 +1349,8 @@ void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
				/* we don't fail if the table is not available */
		}
	}

	iwl_acpi_get_phy_filters(&mvm->fwrt, &mvm->phy_filters);
}
#else /* CONFIG_ACPI */

Loading