1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 /* Copyright(c) 2021-2023 Realtek Corporation 3 */ 4 5 #ifndef __RTW89_ACPI_H__ 6 #define __RTW89_ACPI_H__ 7 8 #include "core.h" 9 10 struct rtw89_acpi_data { 11 u32 len; 12 u8 buf[] __counted_by(len); 13 }; 14 15 enum rtw89_acpi_dsm_func { 16 RTW89_ACPI_DSM_FUNC_IDN_BAND_SUP = 2, 17 RTW89_ACPI_DSM_FUNC_6G_DIS = 3, 18 RTW89_ACPI_DSM_FUNC_6G_BP = 4, 19 RTW89_ACPI_DSM_FUNC_TAS_EN = 5, 20 RTW89_ACPI_DSM_FUNC_UNII4_SUP = 6, 21 RTW89_ACPI_DSM_FUNC_6GHZ_SP_SUP = 7, 22 RTW89_ACPI_DSM_FUNC_REG_RULES_EN = 10, 23 RTW89_ACPI_DSM_FUNC_6GHZ_VLP_SUP = 11, 24 }; 25 26 enum rtw89_acpi_conf_unii4 { 27 RTW89_ACPI_CONF_UNII4_US = BIT(0), 28 RTW89_ACPI_CONF_UNII4_CA = BIT(1), 29 }; 30 31 enum rtw89_acpi_policy_mode { 32 RTW89_ACPI_POLICY_BLOCK = 0, 33 RTW89_ACPI_POLICY_ALLOW = 1, 34 }; 35 36 enum rtw89_acpi_conf_tas { 37 RTW89_ACPI_CONF_TAS_US = BIT(0), 38 RTW89_ACPI_CONF_TAS_CA = BIT(1), 39 RTW89_ACPI_CONF_TAS_KR = BIT(2), 40 RTW89_ACPI_CONF_TAS_OTHERS = BIT(7), 41 }; 42 43 struct rtw89_acpi_country_code { 44 /* below are allowed: 45 * * ISO alpha2 country code 46 * * EU for countries in Europe 47 */ 48 char alpha2[2]; 49 } __packed; 50 51 struct rtw89_acpi_policy_6ghz { 52 u8 signature[3]; 53 u8 rsvd; 54 u8 policy_mode; 55 u8 country_count; 56 struct rtw89_acpi_country_code country_list[] __counted_by(country_count); 57 } __packed; 58 59 enum rtw89_acpi_conf_6ghz_sp { 60 RTW89_ACPI_CONF_6GHZ_SP_US = BIT(0), 61 RTW89_ACPI_CONF_6GHZ_SP_CA = BIT(1), 62 }; 63 64 struct rtw89_acpi_policy_6ghz_sp { 65 u8 signature[4]; 66 u8 revision; 67 u8 override; 68 u8 conf; 69 u8 rsvd; 70 } __packed; 71 72 enum rtw89_acpi_conf_6ghz_vlp { 73 RTW89_ACPI_CONF_6GHZ_VLP_US = BIT(0), 74 RTW89_ACPI_CONF_6GHZ_VLP_CA = BIT(1), 75 }; 76 77 struct rtw89_acpi_policy_6ghz_vlp { 78 u8 signature[4]; 79 u8 revision; 80 u8 override; 81 u8 conf; 82 u8 rsvd; 83 } __packed; 84 85 struct rtw89_acpi_policy_tas { 86 u8 signature[4]; 87 u8 revision; 88 u8 enable; 89 u8 enabled_countries; 90 u8 rsvd[3]; 91 } __packed; 92 93 enum rtw89_acpi_conf_reg_rules { 94 RTW89_ACPI_CONF_REG_RULE_REGD_UK = BIT(0), 95 }; 96 97 struct rtw89_acpi_policy_reg_rules { 98 u8 signature[4]; 99 u8 revision; 100 u8 conf; 101 u8 rsvd[3]; 102 } __packed; 103 104 struct rtw89_acpi_dsm_result { 105 union { 106 u8 value; 107 /* caller needs to free it after using */ 108 struct rtw89_acpi_policy_6ghz *policy_6ghz; 109 struct rtw89_acpi_policy_6ghz_sp *policy_6ghz_sp; 110 struct rtw89_acpi_policy_6ghz_vlp *policy_6ghz_vlp; 111 struct rtw89_acpi_policy_tas *policy_tas; 112 struct rtw89_acpi_policy_reg_rules *policy_reg_rules; 113 } u; 114 }; 115 116 struct rtw89_acpi_rtag_result { 117 u8 tag[4]; 118 u8 revision; 119 __le32 domain; 120 u8 ant_gain_table[RTW89_ANT_GAIN_CHAIN_NUM][RTW89_ANT_GAIN_SUBBAND_NR]; 121 } __packed; 122 123 enum rtw89_acpi_sar_cid { 124 RTW89_ACPI_SAR_CID_HP = 0x5048, 125 RTW89_ACPI_SAR_CID_RT = 0x5452, 126 }; 127 128 enum rtw89_acpi_sar_rev { 129 RTW89_ACPI_SAR_REV_LEGACY = 1, 130 RTW89_ACPI_SAR_REV_HAS_6GHZ = 2, 131 }; 132 133 #define RTW89_ACPI_SAR_ANT_NR_STD 4 134 #define RTW89_ACPI_SAR_ANT_NR_SML 2 135 136 #define RTW89_ACPI_METHOD_STATIC_SAR "WRDS" 137 #define RTW89_ACPI_METHOD_DYNAMIC_SAR "RWRD" 138 #define RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR "RWSI" 139 #define RTW89_ACPI_METHOD_GEO_SAR "RWGS" 140 141 struct rtw89_acpi_sar_std_legacy { 142 u8 v[RTW89_ACPI_SAR_ANT_NR_STD][RTW89_ACPI_SAR_SUBBAND_NR_LEGACY]; 143 } __packed; 144 145 struct rtw89_acpi_sar_std_has_6ghz { 146 u8 v[RTW89_ACPI_SAR_ANT_NR_STD][RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ]; 147 } __packed; 148 149 struct rtw89_acpi_sar_sml_legacy { 150 u8 v[RTW89_ACPI_SAR_ANT_NR_SML][RTW89_ACPI_SAR_SUBBAND_NR_LEGACY]; 151 } __packed; 152 153 struct rtw89_acpi_sar_sml_has_6ghz { 154 u8 v[RTW89_ACPI_SAR_ANT_NR_SML][RTW89_ACPI_SAR_SUBBAND_NR_HAS_6GHZ]; 155 } __packed; 156 157 struct rtw89_acpi_static_sar_hdr { 158 __le16 cid; 159 u8 rev; 160 u8 content[]; 161 } __packed; 162 163 struct rtw89_acpi_dynamic_sar_hdr { 164 __le16 cid; 165 u8 rev; 166 u8 cnt; 167 u8 content[]; 168 } __packed; 169 170 struct rtw89_acpi_sar_identifier { 171 enum rtw89_acpi_sar_cid cid; 172 enum rtw89_acpi_sar_rev rev; 173 u8 size; 174 }; 175 176 /* for rtw89_acpi_sar_identifier::size */ 177 #define RTW89_ACPI_SAR_SIZE_MAX U8_MAX 178 #define RTW89_ACPI_SAR_SIZE_OF(type) \ 179 (BUILD_BUG_ON_ZERO(sizeof(struct rtw89_acpi_sar_ ## type) > \ 180 RTW89_ACPI_SAR_SIZE_MAX) + \ 181 sizeof(struct rtw89_acpi_sar_ ## type)) 182 183 struct rtw89_acpi_sar_recognition { 184 struct rtw89_acpi_sar_identifier id; 185 const struct rtw89_acpi_geo_sar_handler *geo; 186 187 u8 (*rfpath_to_antidx)(enum rtw89_rf_path rfpath); 188 s16 (*normalize)(u8 v); 189 void (*load)(struct rtw89_dev *rtwdev, 190 const struct rtw89_acpi_sar_recognition *rec, 191 const void *content, 192 struct rtw89_sar_entry_from_acpi *ent); 193 }; 194 195 struct rtw89_acpi_geo_sar_hp_val { 196 u8 max; 197 s8 delta[RTW89_ACPI_SAR_ANT_NR_STD]; 198 } __packed; 199 200 struct rtw89_acpi_geo_sar_hp_legacy_entry { 201 struct rtw89_acpi_geo_sar_hp_val val_2ghz; 202 struct rtw89_acpi_geo_sar_hp_val val_5ghz; 203 } __packed; 204 205 struct rtw89_acpi_geo_sar_hp_has_6ghz_entry { 206 struct rtw89_acpi_geo_sar_hp_val val_2ghz; 207 struct rtw89_acpi_geo_sar_hp_val val_5ghz; 208 struct rtw89_acpi_geo_sar_hp_val val_6ghz; 209 } __packed; 210 211 enum rtw89_acpi_geo_sar_regd_hp { 212 RTW89_ACPI_GEO_SAR_REGD_HP_FCC = 0, 213 RTW89_ACPI_GEO_SAR_REGD_HP_ETSI = 1, 214 RTW89_ACPI_GEO_SAR_REGD_HP_WW = 2, 215 216 RTW89_ACPI_GEO_SAR_REGD_NR_HP, 217 }; 218 219 struct rtw89_acpi_geo_sar_hp_legacy { 220 struct rtw89_acpi_geo_sar_hp_legacy_entry 221 entries[RTW89_ACPI_GEO_SAR_REGD_NR_HP]; 222 } __packed; 223 224 struct rtw89_acpi_geo_sar_hp_has_6ghz { 225 struct rtw89_acpi_geo_sar_hp_has_6ghz_entry 226 entries[RTW89_ACPI_GEO_SAR_REGD_NR_HP]; 227 } __packed; 228 229 struct rtw89_acpi_geo_sar_rt_val { 230 u8 max; 231 s8 delta; 232 } __packed; 233 234 struct rtw89_acpi_geo_sar_rt_legacy_entry { 235 struct rtw89_acpi_geo_sar_rt_val val_2ghz; 236 struct rtw89_acpi_geo_sar_rt_val val_5ghz; 237 } __packed; 238 239 struct rtw89_acpi_geo_sar_rt_has_6ghz_entry { 240 struct rtw89_acpi_geo_sar_rt_val val_2ghz; 241 struct rtw89_acpi_geo_sar_rt_val val_5ghz; 242 struct rtw89_acpi_geo_sar_rt_val val_6ghz; 243 } __packed; 244 245 enum rtw89_acpi_geo_sar_regd_rt { 246 RTW89_ACPI_GEO_SAR_REGD_RT_FCC = 0, 247 RTW89_ACPI_GEO_SAR_REGD_RT_ETSI = 1, 248 RTW89_ACPI_GEO_SAR_REGD_RT_MKK = 2, 249 RTW89_ACPI_GEO_SAR_REGD_RT_IC = 3, 250 RTW89_ACPI_GEO_SAR_REGD_RT_KCC = 4, 251 RTW89_ACPI_GEO_SAR_REGD_RT_WW = 5, 252 253 RTW89_ACPI_GEO_SAR_REGD_NR_RT, 254 }; 255 256 struct rtw89_acpi_geo_sar_rt_legacy { 257 struct rtw89_acpi_geo_sar_rt_legacy_entry 258 entries[RTW89_ACPI_GEO_SAR_REGD_NR_RT]; 259 } __packed; 260 261 struct rtw89_acpi_geo_sar_rt_has_6ghz { 262 struct rtw89_acpi_geo_sar_rt_has_6ghz_entry 263 entries[RTW89_ACPI_GEO_SAR_REGD_NR_RT]; 264 } __packed; 265 266 struct rtw89_acpi_geo_sar_handler { 267 u8 data_size; 268 269 void (*load)(struct rtw89_dev *rtwdev, 270 const void *content, 271 enum rtw89_regulation_type regd, 272 struct rtw89_sar_entry_from_acpi *ent); 273 }; 274 275 /* for rtw89_acpi_geo_sar_handler::data_size */ 276 #define RTW89_ACPI_GEO_SAR_SIZE_MAX U8_MAX 277 #define RTW89_ACPI_GEO_SAR_SIZE_OF(type) \ 278 (BUILD_BUG_ON_ZERO(sizeof(struct rtw89_acpi_geo_sar_ ## type) > \ 279 RTW89_ACPI_GEO_SAR_SIZE_MAX) + \ 280 sizeof(struct rtw89_acpi_geo_sar_ ## type)) 281 282 enum rtw89_acpi_sar_subband rtw89_acpi_sar_get_subband(struct rtw89_dev *rtwdev, 283 u32 center_freq); 284 enum rtw89_band rtw89_acpi_sar_subband_to_band(struct rtw89_dev *rtwdev, 285 enum rtw89_acpi_sar_subband subband); 286 287 int rtw89_acpi_evaluate_dsm(struct rtw89_dev *rtwdev, 288 enum rtw89_acpi_dsm_func func, 289 struct rtw89_acpi_dsm_result *res); 290 int rtw89_acpi_evaluate_rtag(struct rtw89_dev *rtwdev, 291 struct rtw89_acpi_rtag_result *res); 292 int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev, 293 struct rtw89_sar_cfg_acpi *cfg); 294 int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev, 295 struct rtw89_sar_cfg_acpi *cfg, 296 bool *changed); 297 298 #endif 299