1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 /* 3 * Copyright (C) 2023-2026 Intel Corporation 4 */ 5 6 #ifndef __fw_regulatory_h__ 7 #define __fw_regulatory_h__ 8 9 #include "fw/img.h" 10 #include "fw/api/commands.h" 11 #include "fw/api/power.h" 12 #include "fw/api/phy.h" 13 #include "fw/api/config.h" 14 #include "fw/api/nvm-reg.h" 15 #include "iwl-trans.h" 16 17 #define BIOS_SAR_MAX_PROFILE_NUM 4 18 /* 19 * Each SAR profile has (up to, depends on the table revision) 4 chains: 20 * chain A, chain B, chain A when in CDB, chain B when in CDB 21 */ 22 #define BIOS_SAR_MAX_CHAINS_PER_PROFILE 4 23 #define BIOS_SAR_NUM_CHAINS 2 24 #define BIOS_SAR_MAX_SUB_BANDS_NUM 12 25 #define BIOS_PPAG_MAX_SUB_BANDS_NUM 12 26 27 #define BIOS_GEO_NUM_CHAINS 2 28 #define BIOS_GEO_MAX_NUM_BANDS 4 29 #define BIOS_GEO_MAX_PROFILE_NUM 8 30 #define BIOS_GEO_MIN_PROFILE_NUM 3 31 32 #define IWL_SAR_ENABLE_MSK BIT(0) 33 #define IWL_REDUCE_POWER_FLAGS_POS 1 34 #define IWL_BIOS_REVISION_UNSET 0xFF 35 36 /* PPAG gain value bounds in 1/8 dBm */ 37 #define IWL_PPAG_MIN_LB -16 38 #define IWL_PPAG_MAX_LB 24 39 #define IWL_PPAG_MIN_HB -16 40 #define IWL_PPAG_MAX_HB 40 41 42 #define IWL_PPAG_ETSI_CHINA_MASK 3 43 #define IWL_PPAG_REV3_MASK 0x7FF 44 45 #define IWL_WTAS_ENABLED_MSK BIT(0) 46 #define IWL_WTAS_OVERRIDE_IEC_MSK BIT(1) 47 #define IWL_WTAS_ENABLE_IEC_MSK BIT(2) 48 #define IWL_WTAS_CANADA_UHB_MSK BIT(15) 49 #define IWL_WTAS_USA_UHB_MSK BIT(16) 50 51 /** 52 * enum iwl_uefi_cnv_guid_status - lock status of the connectivity 53 * UEFI tables 54 * @UEFI_CNV_GUID_UNLOCKED: the tables are unlocked 55 * @UEFI_CNV_GUID_LOCKED: the tables are locked 56 * @UEFI_CNV_GUID_TEST_MODE: the tables are locked in test mode 57 * @UEFI_CNV_GUID_UNKNOWN: the lock status could not be determined. 58 * This value is a driver internal, not a possible BIOS reported one 59 */ 60 enum iwl_uefi_cnv_guid_status { 61 UEFI_CNV_GUID_UNLOCKED = 0, 62 UEFI_CNV_GUID_LOCKED = 1, 63 UEFI_CNV_GUID_TEST_MODE = 2, 64 UEFI_CNV_GUID_UNKNOWN = 3, 65 }; 66 67 struct iwl_tas_selection_data { 68 u8 override_tas_iec:1, 69 enable_tas_iec:1, 70 usa_tas_uhb_allowed:1, 71 canada_tas_uhb_allowed:1; 72 }; 73 74 #define BIOS_MCC_CHINA 0x434e 75 76 /* 77 * The profile for revision 2 is a superset of revision 1, which is in 78 * turn a superset of revision 0. So we can store all revisions 79 * inside revision 2, which is what we represent here. 80 */ 81 82 /* 83 * struct iwl_sar_profile_chain - per-chain values of a SAR profile 84 * @subbands: the SAR value for each subband 85 */ 86 struct iwl_sar_profile_chain { 87 u8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM]; 88 }; 89 90 /* 91 * struct iwl_sar_profile - SAR profile from SAR tables 92 * @enabled: whether the profile is enabled or not 93 * @chains: per-chain SAR values 94 */ 95 struct iwl_sar_profile { 96 bool enabled; 97 struct iwl_sar_profile_chain chains[BIOS_SAR_MAX_CHAINS_PER_PROFILE]; 98 }; 99 100 /* Same thing as with SAR, all revisions fit in revision 2 */ 101 102 /* 103 * struct iwl_geo_profile_band - per-band geo SAR offsets 104 * @max: the max tx power allowed for the band 105 * @chains: SAR offsets values for each chain 106 */ 107 struct iwl_geo_profile_band { 108 u8 max; 109 u8 chains[BIOS_GEO_NUM_CHAINS]; 110 }; 111 112 /* 113 * struct iwl_geo_profile - geo profile 114 * @bands: per-band table of the SAR offsets 115 */ 116 struct iwl_geo_profile { 117 struct iwl_geo_profile_band bands[BIOS_GEO_MAX_NUM_BANDS]; 118 }; 119 120 /* Same thing as with SAR, all revisions fit in revision 2 */ 121 struct iwl_ppag_chain { 122 s8 subbands[BIOS_PPAG_MAX_SUB_BANDS_NUM]; 123 }; 124 125 struct iwl_tas_data { 126 u8 block_list_size; 127 u16 block_list_array[IWL_WTAS_BLACK_LIST_MAX]; 128 u8 table_source; 129 u8 table_revision; 130 u32 tas_selection; 131 }; 132 133 /* For DSM revision 0 and 4 */ 134 enum iwl_dsm_funcs { 135 DSM_FUNC_QUERY = 0, 136 DSM_FUNC_DISABLE_SRD = 1, 137 DSM_FUNC_ENABLE_INDONESIA_5G2 = 2, 138 DSM_FUNC_ENABLE_6E = 3, 139 DSM_FUNC_REGULATORY_CONFIG = 4, 140 DSM_FUNC_11AX_ENABLEMENT = 6, 141 DSM_FUNC_ENABLE_UNII4_CHAN = 7, 142 DSM_FUNC_ACTIVATE_CHANNEL = 8, 143 DSM_FUNC_FORCE_DISABLE_CHANNELS = 9, 144 DSM_FUNC_ENERGY_DETECTION_THRESHOLD = 10, 145 DSM_FUNC_RFI_CONFIG = 11, 146 DSM_FUNC_ENABLE_11BE = 12, 147 DSM_FUNC_ENABLE_11BN = 13, 148 DSM_FUNC_ENABLE_UNII_9 = 14, 149 DSM_FUNC_NUM_FUNCS, 150 }; 151 152 enum iwl_dsm_values_srd { 153 DSM_VALUE_SRD_ACTIVE, 154 DSM_VALUE_SRD_PASSIVE, 155 DSM_VALUE_SRD_DISABLE, 156 DSM_VALUE_SRD_MAX 157 }; 158 159 enum iwl_dsm_values_indonesia { 160 DSM_VALUE_INDONESIA_DISABLE, 161 DSM_VALUE_INDONESIA_ENABLE, 162 DSM_VALUE_INDONESIA_RESERVED, 163 DSM_VALUE_INDONESIA_MAX 164 }; 165 166 enum iwl_dsm_unii4_bitmap { 167 DSM_VALUE_UNII4_US_OVERRIDE_MSK = BIT(0), 168 DSM_VALUE_UNII4_US_EN_MSK = BIT(1), 169 DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK = BIT(2), 170 DSM_VALUE_UNII4_ETSI_EN_MSK = BIT(3), 171 DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK = BIT(4), 172 DSM_VALUE_UNII4_CANADA_EN_MSK = BIT(5), 173 }; 174 175 #define DSM_UNII4_ALLOW_BITMAP (DSM_VALUE_UNII4_US_OVERRIDE_MSK |\ 176 DSM_VALUE_UNII4_US_EN_MSK |\ 177 DSM_VALUE_UNII4_ETSI_OVERRIDE_MSK |\ 178 DSM_VALUE_UNII4_ETSI_EN_MSK |\ 179 DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK |\ 180 DSM_VALUE_UNII4_CANADA_EN_MSK) 181 182 #define DSM_11AX_ALLOW_BITMAP 0xF 183 #define DSM_EDT_ALLOWED_BITMAP 0x7ffff0 184 #define DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP 0x7FF 185 186 enum iwl_dsm_values_rfi { 187 DSM_VALUE_RFI_DLVR_DISABLE = BIT(0), 188 DSM_VALUE_RFI_DDR_DISABLE = BIT(1), 189 }; 190 191 #define DSM_VALUE_RFI_DISABLE (DSM_VALUE_RFI_DLVR_DISABLE |\ 192 DSM_VALUE_RFI_DDR_DISABLE) 193 194 bool iwl_rfi_is_enabled_in_bios(struct iwl_fw_runtime *fwrt); 195 196 enum iwl_dsm_masks_reg { 197 DSM_MASK_CHINA_22_REG = BIT(2) 198 }; 199 200 struct iwl_fw_runtime; 201 202 /* Print the PPAG table as read from BIOS */ 203 void iwl_bios_print_ppag(struct iwl_fw_runtime *fwrt, int n_subbands); 204 205 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt); 206 207 int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt, 208 struct iwl_per_chain_offset *table, 209 u32 n_bands, u32 n_profiles); 210 211 int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt, 212 __le16 *per_chain, u32 n_tables, u32 n_subbands, 213 int prof_a, int prof_b, 214 const struct iwl_sar_profile *profiles, 215 bool is_standalone); 216 217 bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt); 218 219 bool iwl_is_tas_approved(void); 220 bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc); 221 222 struct iwl_tas_selection_data 223 iwl_parse_tas_selection(const u32 tas_selection, const u8 tbl_rev); 224 225 int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt); 226 227 int iwl_bios_get_ewrd_table(struct iwl_fw_runtime *fwrt); 228 229 int iwl_bios_get_wsss_table(struct iwl_fw_runtime *fwrt); 230 231 int iwl_bios_get_ewss_table(struct iwl_fw_runtime *fwrt); 232 233 int iwl_bios_get_wgds_table(struct iwl_fw_runtime *fwrt); 234 235 int iwl_bios_get_ppag_table(struct iwl_fw_runtime *fwrt); 236 237 int iwl_bios_get_tas_table(struct iwl_fw_runtime *fwrt, 238 struct iwl_tas_data *data); 239 240 int iwl_bios_get_pwr_limit(struct iwl_fw_runtime *fwrt, 241 u64 *dflt_pwr_limit); 242 243 int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc); 244 int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk); 245 int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value); 246 247 int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, 248 u32 *value); 249 250 static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes, 251 const u8 ppag_bios_rev) 252 { 253 /* For revision 4 and above driver is pipe */ 254 if (ppag_bios_rev >= 4) 255 return ppag_modes; 256 257 return ppag_modes & (ppag_bios_rev < 3 ? IWL_PPAG_ETSI_CHINA_MASK : 258 IWL_PPAG_REV3_MASK); 259 } 260 261 bool iwl_puncturing_is_allowed_in_bios(u32 puncturing, u16 mcc); 262 263 #define IWL_DSBR_FW_MODIFIED_URM_MASK BIT(8) 264 #define IWL_DSBR_PERMANENT_URM_MASK BIT(9) 265 266 int iwl_bios_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value); 267 int iwl_bios_get_phy_filters(struct iwl_fw_runtime *fwrt); 268 void iwl_bios_get_guid_lock_status(struct iwl_fw_runtime *fwrt); 269 270 static inline void iwl_bios_setup_step(struct iwl_trans *trans, 271 struct iwl_fw_runtime *fwrt) 272 { 273 u32 dsbr; 274 275 if (!trans->mac_cfg->integrated) 276 return; 277 278 if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_BZ) 279 return; 280 281 if (iwl_bios_get_dsbr(fwrt, &dsbr)) 282 dsbr = 0; 283 284 trans->conf.dsbr_urm_fw_dependent = 285 !!(dsbr & IWL_DSBR_FW_MODIFIED_URM_MASK); 286 trans->conf.dsbr_urm_permanent = 287 !!(dsbr & IWL_DSBR_PERMANENT_URM_MASK); 288 } 289 #endif /* __fw_regulatory_h__ */ 290