// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright (C) 2023 Intel Corporation
 */
#include <linux/dmi.h>
#include "iwl-drv.h"
#include "iwl-debug.h"
#include "regulatory.h"
#include "fw/runtime.h"
#include "fw/uefi.h"

#define GET_BIOS_TABLE(__name, ...)					\
do {									\
	int ret = -ENOENT;						\
	if (fwrt->uefi_tables_lock_status > UEFI_WIFI_GUID_UNLOCKED)	\
		ret = iwl_uefi_get_ ## __name(__VA_ARGS__);		\
	if (ret < 0)							\
		ret = iwl_acpi_get_ ## __name(__VA_ARGS__);		\
	return ret;							\
} while (0)

#define IWL_BIOS_TABLE_LOADER(__name)					\
int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt)		\
{GET_BIOS_TABLE(__name, fwrt); }					\
IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)

#define IWL_BIOS_TABLE_LOADER_DATA(__name, data_type)			\
int iwl_bios_get_ ## __name(struct iwl_fw_runtime *fwrt,		\
			    data_type * data)				\
{GET_BIOS_TABLE(__name, fwrt, data); }					\
IWL_EXPORT_SYMBOL(iwl_bios_get_ ## __name)

IWL_BIOS_TABLE_LOADER(wrds_table);
IWL_BIOS_TABLE_LOADER(ewrd_table);
IWL_BIOS_TABLE_LOADER(wgds_table);
IWL_BIOS_TABLE_LOADER(ppag_table);
IWL_BIOS_TABLE_LOADER_DATA(tas_table, struct iwl_tas_data);
IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64);
IWL_BIOS_TABLE_LOADER_DATA(mcc, char);
IWL_BIOS_TABLE_LOADER_DATA(eckv, u32);


static const struct dmi_system_id dmi_ppag_approved_list[] = {
	{ .ident = "HP",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
		},
	},
	{ .ident = "SAMSUNG",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
		},
	},
	{ .ident = "MSFT",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
		},
	},
	{ .ident = "ASUS",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
		},
	},
	{ .ident = "GOOGLE-HP",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
		},
	},
	{ .ident = "GOOGLE-ASUS",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."),
		},
	},
	{ .ident = "GOOGLE-SAMSUNG",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
			DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
		},
	},
	{ .ident = "DELL",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
		},
	},
	{ .ident = "DELL",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
		},
	},
	{ .ident = "RAZER",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
		},
	},
	{ .ident = "Honor",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
		},
	},
	{}
};

static const struct dmi_system_id dmi_tas_approved_list[] = {
	{ .ident = "HP",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
		},
	},
	{ .ident = "SAMSUNG",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
		},
	},
		{ .ident = "LENOVO",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
		},
	},
	{ .ident = "DELL",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
		},
	},
	{ .ident = "MSFT",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
		},
	},
	{ .ident = "Acer",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
		},
	},
	{ .ident = "ASUS",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
		},
	},
	{ .ident = "GOOGLE-HP",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
			DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
		},
	},
	{ .ident = "MSI",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
		},
	},
	{ .ident = "Honor",
	  .matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
		},
	},
	/* keep last */
	{}
};

bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
{
	/*
	 * The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on
	 * earlier firmware versions.  Unfortunately, we don't have a
	 * TLV API flag to rely on, so rely on the major version which
	 * is in the first byte of ucode_ver.  This was implemented
	 * initially on version 38 and then backported to 17.  It was
	 * also backported to 29, but only for 7265D devices.  The
	 * intention was to have it in 36 as well, but not all 8000
	 * family got this feature enabled.  The 8000 family is the
	 * only one using version 36, so skip this version entirely.
	 */
	return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 ||
		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 &&
		 fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) ||
		(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 &&
		 ((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
		  CSR_HW_REV_TYPE_7265D));
}
IWL_EXPORT_SYMBOL(iwl_sar_geo_support);

int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
			   struct iwl_per_chain_offset *table,
			   u32 n_bands, u32 n_profiles)
{
	int i, j;

	if (!fwrt->geo_enabled)
		return -ENODATA;

	if (!iwl_sar_geo_support(fwrt))
		return -EOPNOTSUPP;

	for (i = 0; i < n_profiles; i++) {
		for (j = 0; j < n_bands; j++) {
			struct iwl_per_chain_offset *chain =
				&table[i * n_bands + j];

			chain->max_tx_power =
				cpu_to_le16(fwrt->geo_profiles[i].bands[j].max);
			chain->chain_a =
				fwrt->geo_profiles[i].bands[j].chains[0];
			chain->chain_b =
				fwrt->geo_profiles[i].bands[j].chains[1];
			IWL_DEBUG_RADIO(fwrt,
					"SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n",
					i, j,
					fwrt->geo_profiles[i].bands[j].chains[0],
					fwrt->geo_profiles[i].bands[j].chains[1],
					fwrt->geo_profiles[i].bands[j].max);
		}
	}

	return 0;
}
IWL_EXPORT_SYMBOL(iwl_sar_geo_fill_table);

static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt,
			      __le16 *per_chain, u32 n_subbands,
			      int prof_a, int prof_b)
{
	int profs[BIOS_SAR_NUM_CHAINS] = { prof_a, prof_b };
	int i, j;

	for (i = 0; i < BIOS_SAR_NUM_CHAINS; i++) {
		struct iwl_sar_profile *prof;

		/* don't allow SAR to be disabled (profile 0 means disable) */
		if (profs[i] == 0)
			return -EPERM;

		/* we are off by one, so allow up to BIOS_SAR_MAX_PROFILE_NUM */
		if (profs[i] > BIOS_SAR_MAX_PROFILE_NUM)
			return -EINVAL;

		/* profiles go from 1 to 4, so decrement to access the array */
		prof = &fwrt->sar_profiles[profs[i] - 1];

		/* if the profile is disabled, do nothing */
		if (!prof->enabled) {
			IWL_DEBUG_RADIO(fwrt, "SAR profile %d is disabled.\n",
					profs[i]);
			/*
			 * if one of the profiles is disabled, we
			 * ignore all of them and return 1 to
			 * differentiate disabled from other failures.
			 */
			return 1;
		}

		IWL_DEBUG_INFO(fwrt,
			       "SAR EWRD: chain %d profile index %d\n",
			       i, profs[i]);
		IWL_DEBUG_RADIO(fwrt, "  Chain[%d]:\n", i);
		for (j = 0; j < n_subbands; j++) {
			per_chain[i * n_subbands + j] =
				cpu_to_le16(prof->chains[i].subbands[j]);
			IWL_DEBUG_RADIO(fwrt, "    Band[%d] = %d * .125dBm\n",
					j, prof->chains[i].subbands[j]);
		}
	}

	return 0;
}

int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
			 __le16 *per_chain, u32 n_tables, u32 n_subbands,
			 int prof_a, int prof_b)
{
	int i, ret = 0;

	for (i = 0; i < n_tables; i++) {
		ret = iwl_sar_fill_table(fwrt,
			&per_chain[i * n_subbands * BIOS_SAR_NUM_CHAINS],
			n_subbands, prof_a, prof_b);
		if (ret)
			break;
	}

	return ret;
}
IWL_EXPORT_SYMBOL(iwl_sar_fill_profile);

static bool iwl_ppag_value_valid(struct iwl_fw_runtime *fwrt, int chain,
				 int subband)
{
	s8 ppag_val = fwrt->ppag_chains[chain].subbands[subband];

	if ((subband == 0 &&
	     (ppag_val > IWL_PPAG_MAX_LB || ppag_val < IWL_PPAG_MIN_LB)) ||
	    (subband != 0 &&
	     (ppag_val > IWL_PPAG_MAX_HB || ppag_val < IWL_PPAG_MIN_HB))) {
		IWL_DEBUG_RADIO(fwrt, "Invalid PPAG value: %d\n", ppag_val);
		return false;
	}
	return true;
}

int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
			union iwl_ppag_table_cmd *cmd, int *cmd_size)
{
	u8 cmd_ver;
	int i, j, num_sub_bands;
	s8 *gain;
	bool send_ppag_always;

	/* many firmware images for JF lie about this */
	if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) ==
	    CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))
		return -EOPNOTSUPP;

	if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
		IWL_DEBUG_RADIO(fwrt,
				"PPAG capability not supported by FW, command not sent.\n");
		return -EINVAL;
	}

	cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
					WIDE_ID(PHY_OPS_GROUP,
						PER_PLATFORM_ANT_GAIN_CMD), 1);
	/*
	 * Starting from ver 4, driver needs to send the PPAG CMD regardless
	 * if PPAG is enabled/disabled or valid/invalid.
	 */
	send_ppag_always = cmd_ver > 3;

	/* Don't send PPAG if it is disabled */
	if (!send_ppag_always && !fwrt->ppag_flags) {
		IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n");
		return -EINVAL;
	}

	/* The 'flags' field is the same in v1 and in v2 so we can just
	 * use v1 to access it.
	 */
	cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags);

	IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver);
	if (cmd_ver == 1) {
		num_sub_bands = IWL_NUM_SUB_BANDS_V1;
		gain = cmd->v1.gain[0];
		*cmd_size = sizeof(cmd->v1);
		if (fwrt->ppag_ver >= 1) {
			/* in this case FW supports revision 0 */
			IWL_DEBUG_RADIO(fwrt,
					"PPAG table rev is %d, send truncated table\n",
					fwrt->ppag_ver);
		}
	} else if (cmd_ver >= 2 && cmd_ver <= 5) {
		num_sub_bands = IWL_NUM_SUB_BANDS_V2;
		gain = cmd->v2.gain[0];
		*cmd_size = sizeof(cmd->v2);
		if (fwrt->ppag_ver == 0) {
			/* in this case FW supports revisions 1,2 or 3 */
			IWL_DEBUG_RADIO(fwrt,
					"PPAG table rev is 0, send padded table\n");
		}
	} else {
		IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n");
		return -EINVAL;
	}

	/* ppag mode */
	IWL_DEBUG_RADIO(fwrt,
			"PPAG MODE bits were read from bios: %d\n",
			le32_to_cpu(cmd->v1.flags));

	if (cmd_ver == 5)
		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK);
	else if (cmd_ver < 5)
		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK);

	if ((cmd_ver == 1 &&
	     !fw_has_capa(&fwrt->fw->ucode_capa,
			  IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
	    (cmd_ver == 2 && fwrt->ppag_ver >= 2)) {
		cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
		IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
	} else {
		IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n");
	}

	IWL_DEBUG_RADIO(fwrt,
			"PPAG MODE bits going to be sent: %d\n",
			le32_to_cpu(cmd->v1.flags));

	for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
		for (j = 0; j < num_sub_bands; j++) {
			if (!send_ppag_always &&
			    !iwl_ppag_value_valid(fwrt, i, j))
				return -EINVAL;

			gain[i * num_sub_bands + j] =
				fwrt->ppag_chains[i].subbands[j];
			IWL_DEBUG_RADIO(fwrt,
					"PPAG table: chain[%d] band[%d]: gain = %d\n",
					i, j, gain[i * num_sub_bands + j]);
		}
	}

	return 0;
}
IWL_EXPORT_SYMBOL(iwl_fill_ppag_table);

bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt)
{
	if (!dmi_check_system(dmi_ppag_approved_list)) {
		IWL_DEBUG_RADIO(fwrt,
				"System vendor '%s' is not in the approved list, disabling PPAG.\n",
				dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>");
		fwrt->ppag_flags = 0;
		return false;
	}

	return true;
}
IWL_EXPORT_SYMBOL(iwl_is_ppag_approved);

bool iwl_is_tas_approved(void)
{
	return dmi_check_system(dmi_tas_approved_list);
}
IWL_EXPORT_SYMBOL(iwl_is_tas_approved);

int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
			    struct iwl_tas_data *tas_data,
			    const u32 tas_selection)
{
	u8 override_iec = u32_get_bits(tas_selection,
				       IWL_WTAS_OVERRIDE_IEC_MSK);
	u8 enabled_iec = u32_get_bits(tas_selection, IWL_WTAS_ENABLE_IEC_MSK);
	u8 usa_tas_uhb = u32_get_bits(tas_selection, IWL_WTAS_USA_UHB_MSK);
	int enabled = tas_selection & IWL_WTAS_ENABLED_MSK;

	IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
			tas_selection);

	tas_data->usa_tas_uhb_allowed = usa_tas_uhb;
	tas_data->override_tas_iec = override_iec;
	tas_data->enable_tas_iec = enabled_iec;

	return enabled;
}

__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
{
	int ret;
	u32 val;
	__le32 config_bitmap = 0;

	switch (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id)) {
	case IWL_CFG_RF_TYPE_HR1:
	case IWL_CFG_RF_TYPE_HR2:
	case IWL_CFG_RF_TYPE_JF1:
	case IWL_CFG_RF_TYPE_JF2:
		ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2,
				       &val);

		if (!ret && val == DSM_VALUE_INDONESIA_ENABLE)
			config_bitmap |=
			    cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK);
		break;
	default:
		break;
	}

	ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val);
	if (!ret) {
		if (val == DSM_VALUE_SRD_PASSIVE)
			config_bitmap |=
				cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK);
		else if (val == DSM_VALUE_SRD_DISABLE)
			config_bitmap |=
				cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK);
	}

	if (fw_has_capa(&fwrt->fw->ucode_capa,
			IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) {
		ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG,
				       &val);
		/*
		 * China 2022 enable if the BIOS object does not exist or
		 * if it is enabled in BIOS.
		 */
		if (ret < 0 || val & DSM_MASK_CHINA_22_REG)
			config_bitmap |=
				cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK);
	}

	return config_bitmap;
}
IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap);

int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
		     u32 *value)
{
	GET_BIOS_TABLE(dsm, fwrt, func, value);
}
IWL_EXPORT_SYMBOL(iwl_bios_get_dsm);
