Commit 3d801a75 authored by Anjaneyulu's avatar Anjaneyulu Committed by Johannes Berg

wifi: iwlwifi: Add support for PPAG cmd v5 and PPAG revision 3

Add support for
- PPAG revision 3 in BIOS to enable PPAG in UHB
- PPAG command version 5, this command allows OEM to control
  enablement of PPAG for LPI for UHB mode in USA and ETSI countries.
Signed-off-by: default avatarAnjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240204235836.d17425824b11.If2c1b29e3c579f4135383681af2d625cfe2cffcd@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a20ac99b
...@@ -817,15 +817,15 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) ...@@ -817,15 +817,15 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
if (IS_ERR(data)) if (IS_ERR(data))
return PTR_ERR(data); return PTR_ERR(data);
/* try to read ppag table rev 2 or 1 (both have the same data size) */ /* try to read ppag table rev 3, 2 or 1 (all have the same data size) */
wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data, wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev); ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev);
if (!IS_ERR(wifi_pkg)) { if (!IS_ERR(wifi_pkg)) {
if (tbl_rev == 1 || tbl_rev == 2) { if (tbl_rev >= 1 && tbl_rev <= 3) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2; num_sub_bands = IWL_NUM_SUB_BANDS_V2;
IWL_DEBUG_RADIO(fwrt, IWL_DEBUG_RADIO(fwrt,
"Reading PPAG table v2 (tbl_rev=%d)\n", "Reading PPAG table (tbl_rev=%d)\n",
tbl_rev); tbl_rev);
goto read_table; goto read_table;
} else { } else {
...@@ -857,7 +857,8 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt) ...@@ -857,7 +857,8 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
goto out_free; goto out_free;
} }
fwrt->ppag_flags = flags->integer.value & IWL_PPAG_ETSI_CHINA_MASK; fwrt->ppag_flags = iwl_bios_get_ppag_flags(flags->integer.value,
fwrt->ppag_ver);
/* /*
* read, verify gain values and save them into the PPAG table. * read, verify gain values and save them into the PPAG table.
......
...@@ -505,14 +505,41 @@ struct iwl_geo_tx_power_profiles_resp { ...@@ -505,14 +505,41 @@ struct iwl_geo_tx_power_profiles_resp {
__le32 profile_idx; __le32 profile_idx;
} __packed; /* PER_CHAIN_LIMIT_OFFSET_RSP */ } __packed; /* PER_CHAIN_LIMIT_OFFSET_RSP */
/**
* enum iwl_ppag_flags - PPAG enable masks
* @IWL_PPAG_ETSI_MASK: enable PPAG in ETSI
* @IWL_PPAG_CHINA_MASK: enable PPAG in China
* @IWL_PPAG_ETSI_LPI_UHB_MASK: enable LPI in ETSI for UHB
* @IWL_PPAG_ETSI_VLP_UHB_MASK: enable VLP in ETSI for UHB
* @IWL_PPAG_ETSI_SP_UHB_MASK: enable SP in ETSI for UHB
* @IWL_PPAG_USA_LPI_UHB_MASK: enable LPI in USA for UHB
* @IWL_PPAG_USA_VLP_UHB_MASK: enable VLP in USA for UHB
* @IWL_PPAG_USA_SP_UHB_MASK: enable SP in USA for UHB
* @IWL_PPAG_CANADA_LPI_UHB_MASK: enable LPI in CANADA for UHB
* @IWL_PPAG_CANADA_VLP_UHB_MASK: enable VLP in CANADA for UHB
* @IWL_PPAG_CANADA_SP_UHB_MASK: enable SP in CANADA for UHB
*/
enum iwl_ppag_flags {
IWL_PPAG_ETSI_MASK = BIT(0),
IWL_PPAG_CHINA_MASK = BIT(1),
IWL_PPAG_ETSI_LPI_UHB_MASK = BIT(2),
IWL_PPAG_ETSI_VLP_UHB_MASK = BIT(3),
IWL_PPAG_ETSI_SP_UHB_MASK = BIT(4),
IWL_PPAG_USA_LPI_UHB_MASK = BIT(5),
IWL_PPAG_USA_VLP_UHB_MASK = BIT(6),
IWL_PPAG_USA_SP_UHB_MASK = BIT(7),
IWL_PPAG_CANADA_LPI_UHB_MASK = BIT(8),
IWL_PPAG_CANADA_VLP_UHB_MASK = BIT(9),
IWL_PPAG_CANADA_SP_UHB_MASK = BIT(10),
};
/** /**
* union iwl_ppag_table_cmd - union for all versions of PPAG command * union iwl_ppag_table_cmd - union for all versions of PPAG command
* @v1: version 1 * @v1: version 1
* @v2: version 2 * @v2: version 2
* * version 3, 4 and 5 are the same structure as v2,
* @flags: bit 0 - indicates enablement of PPAG for ETSI * but has a different format of the flags bitmap
* bit 1 - indicates enablement of PPAG for CHINA BIOS * @flags: values from &enum iwl_ppag_flags
* bit 1 can be used only in v3 (identical to v2)
* @gain: table of antenna gain values per chain and sub-band * @gain: table of antenna gain values per chain and sub-band
* @reserved: reserved * @reserved: reserved
*/ */
...@@ -529,6 +556,11 @@ union iwl_ppag_table_cmd { ...@@ -529,6 +556,11 @@ union iwl_ppag_table_cmd {
} v2; } v2;
} __packed; } __packed;
#define IWL_PPAG_CMD_V4_MASK (IWL_PPAG_ETSI_MASK | IWL_PPAG_CHINA_MASK)
#define IWL_PPAG_CMD_V5_MASK (IWL_PPAG_CMD_V4_MASK | \
IWL_PPAG_ETSI_LPI_UHB_MASK | \
IWL_PPAG_USA_LPI_UHB_MASK)
#define MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE 26 #define MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE 26
#define MCC_TO_SAR_OFFSET_TABLE_COL_SIZE 13 #define MCC_TO_SAR_OFFSET_TABLE_COL_SIZE 13
......
...@@ -320,7 +320,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, ...@@ -320,7 +320,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
WIDE_ID(PHY_OPS_GROUP, WIDE_ID(PHY_OPS_GROUP,
PER_PLATFORM_ANT_GAIN_CMD), 1); PER_PLATFORM_ANT_GAIN_CMD), 1);
/* /*
* Starting from ver 4, driver needs to send the PPAG CMD regradless * Starting from ver 4, driver needs to send the PPAG CMD regardless
* if PPAG is enabled/disabled or valid/invalid. * if PPAG is enabled/disabled or valid/invalid.
*/ */
send_ppag_always = cmd_ver > 3; send_ppag_always = cmd_ver > 3;
...@@ -341,18 +341,18 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, ...@@ -341,18 +341,18 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
num_sub_bands = IWL_NUM_SUB_BANDS_V1; num_sub_bands = IWL_NUM_SUB_BANDS_V1;
gain = cmd->v1.gain[0]; gain = cmd->v1.gain[0];
*cmd_size = sizeof(cmd->v1); *cmd_size = sizeof(cmd->v1);
if (fwrt->ppag_ver == 1 || fwrt->ppag_ver == 2) { if (fwrt->ppag_ver >= 1) {
/* in this case FW supports revision 0 */ /* in this case FW supports revision 0 */
IWL_DEBUG_RADIO(fwrt, IWL_DEBUG_RADIO(fwrt,
"PPAG table rev is %d, send truncated table\n", "PPAG table rev is %d, send truncated table\n",
fwrt->ppag_ver); fwrt->ppag_ver);
} }
} else if (cmd_ver >= 2 && cmd_ver <= 4) { } else if (cmd_ver >= 2 && cmd_ver <= 5) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2; num_sub_bands = IWL_NUM_SUB_BANDS_V2;
gain = cmd->v2.gain[0]; gain = cmd->v2.gain[0];
*cmd_size = sizeof(cmd->v2); *cmd_size = sizeof(cmd->v2);
if (fwrt->ppag_ver == 0) { if (fwrt->ppag_ver == 0) {
/* in this case FW supports revisions 1 or 2 */ /* in this case FW supports revisions 1,2 or 3 */
IWL_DEBUG_RADIO(fwrt, IWL_DEBUG_RADIO(fwrt,
"PPAG table rev is 0, send padded table\n"); "PPAG table rev is 0, send padded table\n");
} }
...@@ -364,11 +364,17 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, ...@@ -364,11 +364,17 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
/* ppag mode */ /* ppag mode */
IWL_DEBUG_RADIO(fwrt, IWL_DEBUG_RADIO(fwrt,
"PPAG MODE bits were read from bios: %d\n", "PPAG MODE bits were read from bios: %d\n",
cmd->v1.flags); 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 && if ((cmd_ver == 1 &&
!fw_has_capa(&fwrt->fw->ucode_capa, !fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) || IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
(cmd_ver == 2 && fwrt->ppag_ver == 2)) { (cmd_ver == 2 && fwrt->ppag_ver >= 2)) {
cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK); cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n"); IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
} else { } else {
...@@ -377,7 +383,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, ...@@ -377,7 +383,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
IWL_DEBUG_RADIO(fwrt, IWL_DEBUG_RADIO(fwrt,
"PPAG MODE bits going to be sent: %d\n", "PPAG MODE bits going to be sent: %d\n",
cmd->v1.flags); le32_to_cpu(cmd->v1.flags));
for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) { for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
for (j = 0; j < num_sub_bands; j++) { for (j = 0; j < num_sub_bands; j++) {
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#define IWL_PPAG_MAX_HB 40 #define IWL_PPAG_MAX_HB 40
#define IWL_PPAG_ETSI_CHINA_MASK 3 #define IWL_PPAG_ETSI_CHINA_MASK 3
#define IWL_PPAG_ETSI_MASK BIT(0) #define IWL_PPAG_REV3_MASK 0x7FF
#define IWL_WTAS_BLACK_LIST_MAX 16 #define IWL_WTAS_BLACK_LIST_MAX 16
#define IWL_WTAS_ENABLED_MSK 0x1 #define IWL_WTAS_ENABLED_MSK 0x1
...@@ -189,4 +189,11 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt); ...@@ -189,4 +189,11 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);
int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
u32 *value); u32 *value);
static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes,
const u8 ppag_ver)
{
return ppag_modes & (ppag_ver < 3 ? IWL_PPAG_ETSI_CHINA_MASK :
IWL_PPAG_REV3_MASK);
}
#endif /* __fw_regulatory_h__ */ #endif /* __fw_regulatory_h__ */
...@@ -174,7 +174,7 @@ struct iwl_fw_runtime { ...@@ -174,7 +174,7 @@ struct iwl_fw_runtime {
bool geo_enabled; bool geo_enabled;
struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS]; struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS];
u32 ppag_flags; u32 ppag_flags;
u32 ppag_ver; u8 ppag_ver;
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
struct iwl_sar_offset_mapping_cmd sgom_table; struct iwl_sar_offset_mapping_cmd sgom_table;
bool sgom_enabled; bool sgom_enabled;
......
...@@ -541,7 +541,8 @@ int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt) ...@@ -541,7 +541,8 @@ int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt)
} }
fwrt->ppag_ver = data->revision; fwrt->ppag_ver = data->revision;
fwrt->ppag_flags = data->ppag_modes & IWL_PPAG_ETSI_CHINA_MASK; fwrt->ppag_flags = iwl_bios_get_ppag_flags(data->ppag_modes,
fwrt->ppag_ver);
BUILD_BUG_ON(sizeof(fwrt->ppag_chains) != sizeof(data->ppag_chains)); BUILD_BUG_ON(sizeof(fwrt->ppag_chains) != sizeof(data->ppag_chains));
memcpy(&fwrt->ppag_chains, &data->ppag_chains, memcpy(&fwrt->ppag_chains, &data->ppag_chains,
......
...@@ -116,8 +116,7 @@ struct uefi_cnv_var_wgds { ...@@ -116,8 +116,7 @@ struct uefi_cnv_var_wgds {
/* /*
* struct uefi_cnv_var_ppag - PPAG table as defined in UEFI * struct uefi_cnv_var_ppag - PPAG table as defined in UEFI
* @revision: the revision of the table * @revision: the revision of the table
* @ppag_modes: bit 0 - PPAG is enabled/disabled in ETSI, * @ppag_modes: values from &enum iwl_ppag_flags
* bit 1 - PPAG is enabled/disabled in China
* @ppag_chains: the PPAG values per chain and band * @ppag_chains: the PPAG values per chain and band
*/ */
struct uefi_cnv_var_ppag { struct uefi_cnv_var_ppag {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment