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