#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)
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->info.hw_rev != CSR_HW_REV_TYPE_3160) ||
(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 &&
((fwrt->trans->info.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];
staticint 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;
}
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;
}
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->info.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;
}
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);
cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags); if (fwrt->ppag_bios_rev >= 1) { /* in this case FW supports revision 0 */
IWL_DEBUG_RADIO(fwrt, "PPAG table rev is %d, send truncated table\n",
fwrt->ppag_bios_rev);
}
} elseif (cmd_ver >= 2 && cmd_ver <= 6) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
gain = cmd->v2.gain[0];
*cmd_size = sizeof(cmd->v2);
cmd->v2.flags = cpu_to_le32(fwrt->ppag_flags); if (fwrt->ppag_bios_rev == 0) { /* in this case FW supports revisions 1,2 or 3 */
IWL_DEBUG_RADIO(fwrt, "PPAG table rev is 0, send padded table\n");
}
} elseif (cmd_ver == 7) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
gain = cmd->v3.gain[0];
*cmd_size = sizeof(cmd->v3);
cmd->v3.ppag_config_info.table_source = fwrt->ppag_bios_source;
cmd->v3.ppag_config_info.table_revision = fwrt->ppag_bios_rev;
cmd->v3.ppag_config_info.value = cpu_to_le32(fwrt->ppag_flags);
} 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",
fwrt->ppag_flags);
/* The 'flags' field is the same in v1 and v2 so we can just * use v1 to access it.
*/
IWL_DEBUG_RADIO(fwrt, "PPAG MODE bits going to be sent: %d\n",
(cmd_ver < 7) ? le32_to_cpu(cmd->v1.flags) :
le32_to_cpu(cmd->v3.ppag_config_info.value));
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;
bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc)
{ for (int i = 0; i < *size; i++) { if (list[i] == mcc) returntrue;
}
/* Verify that there is room for another country * If *size == IWL_WTAS_BLACK_LIST_MAX, then the table is full.
*/ if (*size >= IWL_WTAS_BLACK_LIST_MAX) returnfalse;
switch (CSR_HW_RFID_TYPE(fwrt->trans->info.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); elseif (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);
}
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value); if (!ret) { if (!has_raw_dsm_capa)
value &= DSM_11AX_ALLOW_BITMAP;
cmd->oem_11ax_allow_bitmap = cpu_to_le32(value);
}
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value); if (!ret) { if (!has_raw_dsm_capa)
value &= DSM_UNII4_ALLOW_BITMAP;
/* Since version 9, bits 4 and 5 are supported * regardless of this capability, By pass this masking * if firmware has capability of accepting raw DSM table.
*/ if (!has_raw_dsm_capa && cmd_ver < 9 &&
!fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA))
value &= ~(DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK |
DSM_VALUE_UNII4_CANADA_EN_MSK);
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value); if (!ret) { if (!has_raw_dsm_capa)
value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V12;
if (!has_raw_dsm_capa && cmd_ver < 8)
value &= ~ACTIVATE_5G2_IN_WW_MASK;
/* Since version 12, bits 5 and 6 are supported * regardless of this capability, By pass this masking * if firmware has capability of accepting raw DSM table.
*/ if (!has_raw_dsm_capa && cmd_ver < 12 &&
!fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA))
value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V11;
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_6E, &value); if (!ret)
cmd->oem_uhb_allow_bitmap = cpu_to_le32(value);
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value); if (!ret) { if (!has_raw_dsm_capa)
value &= DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP;
cmd->force_disable_channels_bitmap = cpu_to_le32(value);
}
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
&value); if (!ret) { if (!has_raw_dsm_capa)
value &= DSM_EDT_ALLOWED_BITMAP;
cmd->edt_bitmap = cpu_to_le32(value);
}
ret = iwl_bios_get_wbem(fwrt, &value); if (!ret)
cmd->oem_320mhz_allow_bitmap = cpu_to_le32(value);
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_11BE, &value); if (!ret)
cmd->oem_11be_allow_bitmap = cpu_to_le32(value);
bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc)
{ /* Some kind of regulatory mess means we need to currently disallow * puncturing in the US and Canada unless enabled in BIOS.
*/ switch (mcc) { case IWL_MCC_US: return puncturing & IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK; case IWL_MCC_CANADA: return puncturing & IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK; default: returntrue;
}
}
IWL_EXPORT_SYMBOL(iwl_puncturing_is_allowed_in_bios);
bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt)
{ /* default behaviour is disabled */
u32 value = 0; int ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_RFI_CONFIG, &value);
if (ret < 0) {
IWL_DEBUG_RADIO(fwrt, "Failed to get DSM RFI, ret=%d\n", ret); returnfalse;
}
value &= DSM_VALUE_RFI_DISABLE; /* RFI BIOS CONFIG value can be 0 or 3 only. * i.e 0 means DDR and DLVR enabled. 3 means DDR and DLVR disabled. * 1 and 2 are invalid BIOS configurations, So, it's not possible to * disable ddr/dlvr separately.
*/ if (!value) {
IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to enable\n"); returntrue;
} elseif (value == DSM_VALUE_RFI_DISABLE) {
IWL_DEBUG_RADIO(fwrt, "DSM RFI is evaluated to disable\n");
} else {
IWL_DEBUG_RADIO(fwrt, "DSM RFI got invalid value, value=%d\n", value);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.