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