summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw/regulatory.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/regulatory.c116
1 files changed, 97 insertions, 19 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
index 4d9a1f83ef8c..6adcfa6e214a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
@@ -39,6 +39,7 @@ IWL_BIOS_TABLE_LOADER_DATA(pwr_limit, u64);
IWL_BIOS_TABLE_LOADER_DATA(mcc, char);
IWL_BIOS_TABLE_LOADER_DATA(eckv, u32);
IWL_BIOS_TABLE_LOADER_DATA(wbem, u32);
+IWL_BIOS_TABLE_LOADER_DATA(dsbr, u32);
static const struct dmi_system_id dmi_ppag_approved_list[] = {
@@ -100,6 +101,11 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
},
},
+ { .ident = "WIKO",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "WIKO"),
+ },
+ },
{}
};
@@ -424,27 +430,51 @@ bool iwl_is_tas_approved(void)
}
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)
+struct iwl_tas_selection_data
+iwl_parse_tas_selection(const u32 tas_selection_in, const u8 tbl_rev)
{
- u8 override_iec = u32_get_bits(tas_selection,
+ struct iwl_tas_selection_data tas_selection_out = {};
+ u8 override_iec = u32_get_bits(tas_selection_in,
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;
+ u8 canada_tas_uhb = u32_get_bits(tas_selection_in,
+ IWL_WTAS_CANADA_UHB_MSK);
+ u8 enabled_iec = u32_get_bits(tas_selection_in,
+ IWL_WTAS_ENABLE_IEC_MSK);
+ u8 usa_tas_uhb = u32_get_bits(tas_selection_in,
+ IWL_WTAS_USA_UHB_MSK);
+
+ if (tbl_rev > 0) {
+ tas_selection_out.usa_tas_uhb_allowed = usa_tas_uhb;
+ tas_selection_out.override_tas_iec = override_iec;
+ tas_selection_out.enable_tas_iec = enabled_iec;
+ }
- IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
- tas_selection);
+ if (tbl_rev > 1)
+ tas_selection_out.canada_tas_uhb_allowed = canada_tas_uhb;
+
+ return tas_selection_out;
+}
+IWL_EXPORT_SYMBOL(iwl_parse_tas_selection);
+
+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)
+ return true;
+ }
- tas_data->usa_tas_uhb_allowed = usa_tas_uhb;
- tas_data->override_tas_iec = override_iec;
- tas_data->enable_tas_iec = enabled_iec;
+ /* 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)
+ return false;
- return enabled;
+ list[*size++] = mcc;
+ return true;
}
+IWL_EXPORT_SYMBOL(iwl_add_mcc_to_tas_block_list);
-static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
+__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
{
int ret;
u32 val;
@@ -491,6 +521,7 @@ static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
return config_bitmap;
}
+IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap);
static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver)
{
@@ -541,6 +572,10 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
WIDE_ID(REGULATORY_AND_NVM_GROUP,
LARI_CONFIG_CHANGE), 1);
+ if (WARN_ONCE(cmd_ver > 12,
+ "Don't add newer versions to this function\n"))
+ return -EINVAL;
+
memset(cmd, 0, sizeof(*cmd));
*cmd_size = iwl_get_lari_config_cmd_size(cmd_ver);
@@ -552,10 +587,16 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);
if (!ret) {
- if (cmd_ver < 9)
- value &= DSM_UNII4_ALLOW_BITMAP_CMD_V8;
- else
- value &= DSM_UNII4_ALLOW_BITMAP;
+ value &= DSM_UNII4_ALLOW_BITMAP;
+
+ /* Since version 9, bits 4 and 5 are supported
+ * regardless of this capability.
+ */
+ if (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);
cmd->oem_unii4_allow_bitmap = cpu_to_le32(value);
}
@@ -564,7 +605,13 @@ int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt,
if (!ret) {
if (cmd_ver < 8)
value &= ~ACTIVATE_5G2_IN_WW_MASK;
- if (cmd_ver < 12)
+
+ /* Since version 12, bits 5 and 6 are supported
+ * regardless of this capability.
+ */
+ if (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;
cmd->chan_state_active_bitmap = cpu_to_le32(value);
@@ -650,3 +697,34 @@ bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc)
}
}
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);
+ return false;
+ }
+
+ 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");
+ return true;
+ } else if (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);
+ }
+
+ return false;
+}
+IWL_EXPORT_SYMBOL(iwl_rfi_is_enabled_in_bios);