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