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