xref: /linux/drivers/net/wireless/realtek/rtw89/phy.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2020  Realtek Corporation
3  */
4 
5 #include "acpi.h"
6 #include "chan.h"
7 #include "coex.h"
8 #include "debug.h"
9 #include "fw.h"
10 #include "mac.h"
11 #include "phy.h"
12 #include "ps.h"
13 #include "reg.h"
14 #include "sar.h"
15 #include "txrx.h"
16 #include "util.h"
17 
rtw89_phy0_phy1_offset(struct rtw89_dev * rtwdev,u32 addr)18 static u32 rtw89_phy0_phy1_offset(struct rtw89_dev *rtwdev, u32 addr)
19 {
20 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
21 
22 	return phy->phy0_phy1_offset(rtwdev, addr);
23 }
24 
get_max_amsdu_len(struct rtw89_dev * rtwdev,const struct rtw89_ra_report * report)25 static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev,
26 			     const struct rtw89_ra_report *report)
27 {
28 	u32 bit_rate = report->bit_rate;
29 
30 	/* lower than ofdm, do not aggregate */
31 	if (bit_rate < 550)
32 		return 1;
33 
34 	/* avoid AMSDU for legacy rate */
35 	if (report->might_fallback_legacy)
36 		return 1;
37 
38 	/* lower than 20M vht 2ss mcs8, make it small */
39 	if (bit_rate < 1800)
40 		return 1200;
41 
42 	/* lower than 40M vht 2ss mcs9, make it medium */
43 	if (bit_rate < 4000)
44 		return 2600;
45 
46 	/* not yet 80M vht 2ss mcs8/9, make it twice regular packet size */
47 	if (bit_rate < 7000)
48 		return 3500;
49 
50 	return rtwdev->chip->max_amsdu_limit;
51 }
52 
get_mcs_ra_mask(u16 mcs_map,u8 highest_mcs,u8 gap)53 static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap)
54 {
55 	u64 ra_mask = 0;
56 	u8 mcs_cap;
57 	int i, nss;
58 
59 	for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 12) {
60 		mcs_cap = mcs_map & 0x3;
61 		switch (mcs_cap) {
62 		case 2:
63 			ra_mask |= GENMASK_ULL(highest_mcs, 0) << nss;
64 			break;
65 		case 1:
66 			ra_mask |= GENMASK_ULL(highest_mcs - gap, 0) << nss;
67 			break;
68 		case 0:
69 			ra_mask |= GENMASK_ULL(highest_mcs - gap * 2, 0) << nss;
70 			break;
71 		default:
72 			break;
73 		}
74 	}
75 
76 	return ra_mask;
77 }
78 
get_he_ra_mask(struct ieee80211_link_sta * link_sta)79 static u64 get_he_ra_mask(struct ieee80211_link_sta *link_sta)
80 {
81 	struct ieee80211_sta_he_cap cap = link_sta->he_cap;
82 	u16 mcs_map;
83 
84 	switch (link_sta->bandwidth) {
85 	case IEEE80211_STA_RX_BW_160:
86 		if (cap.he_cap_elem.phy_cap_info[0] &
87 		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
88 			mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80p80);
89 		else
90 			mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_160);
91 		break;
92 	default:
93 		mcs_map = le16_to_cpu(cap.he_mcs_nss_supp.rx_mcs_80);
94 	}
95 
96 	/* MCS11, MCS9, MCS7 */
97 	return get_mcs_ra_mask(mcs_map, 11, 2);
98 }
99 
get_eht_mcs_ra_mask(u8 * max_nss,u8 start_mcs,u8 n_nss)100 static u64 get_eht_mcs_ra_mask(u8 *max_nss, u8 start_mcs, u8 n_nss)
101 {
102 	u64 nss_mcs_shift;
103 	u64 nss_mcs_val;
104 	u64 mask = 0;
105 	int i, j;
106 	u8 nss;
107 
108 	for (i = 0; i < n_nss; i++) {
109 		nss = u8_get_bits(max_nss[i], IEEE80211_EHT_MCS_NSS_RX);
110 		if (!nss)
111 			continue;
112 
113 		nss_mcs_val = GENMASK_ULL(start_mcs + i * 2, 0);
114 
115 		for (j = 0, nss_mcs_shift = 12; j < nss; j++, nss_mcs_shift += 16)
116 			mask |= nss_mcs_val << nss_mcs_shift;
117 	}
118 
119 	return mask;
120 }
121 
get_eht_ra_mask(struct rtw89_vif_link * rtwvif_link,struct ieee80211_link_sta * link_sta)122 static u64 get_eht_ra_mask(struct rtw89_vif_link *rtwvif_link,
123 			   struct ieee80211_link_sta *link_sta)
124 {
125 	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
126 	struct ieee80211_eht_mcs_nss_supp_20mhz_only *mcs_nss_20mhz;
127 	struct ieee80211_sta_eht_cap *eht_cap = &link_sta->eht_cap;
128 	struct ieee80211_eht_mcs_nss_supp_bw *mcs_nss;
129 	u8 *he_phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
130 
131 	switch (link_sta->bandwidth) {
132 	case IEEE80211_STA_RX_BW_320:
133 		mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._320;
134 		/* MCS 9, 11, 13 */
135 		return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
136 	case IEEE80211_STA_RX_BW_160:
137 		mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._160;
138 		/* MCS 9, 11, 13 */
139 		return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
140 	case IEEE80211_STA_RX_BW_20:
141 		if (vif->type == NL80211_IFTYPE_AP &&
142 		    !(he_phy_cap[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_MASK_ALL)) {
143 			mcs_nss_20mhz = &eht_cap->eht_mcs_nss_supp.only_20mhz;
144 			/* MCS 7, 9, 11, 13 */
145 			return get_eht_mcs_ra_mask(mcs_nss_20mhz->rx_tx_max_nss, 7, 4);
146 		}
147 		fallthrough;
148 	case IEEE80211_STA_RX_BW_80:
149 	default:
150 		mcs_nss = &eht_cap->eht_mcs_nss_supp.bw._80;
151 		/* MCS 9, 11, 13 */
152 		return get_eht_mcs_ra_mask(mcs_nss->rx_tx_max_nss, 9, 3);
153 	}
154 }
155 
156 #define RA_FLOOR_TABLE_SIZE	7
157 #define RA_FLOOR_UP_GAP		3
rtw89_phy_ra_mask_rssi(struct rtw89_dev * rtwdev,u8 rssi,u8 ratr_state)158 static u64 rtw89_phy_ra_mask_rssi(struct rtw89_dev *rtwdev, u8 rssi,
159 				  u8 ratr_state)
160 {
161 	u8 rssi_lv_t[RA_FLOOR_TABLE_SIZE] = {30, 44, 48, 52, 56, 60, 100};
162 	u8 rssi_lv = 0;
163 	u8 i;
164 
165 	rssi >>= 1;
166 	for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
167 		if (i >= ratr_state)
168 			rssi_lv_t[i] += RA_FLOOR_UP_GAP;
169 		if (rssi < rssi_lv_t[i]) {
170 			rssi_lv = i;
171 			break;
172 		}
173 	}
174 	if (rssi_lv == 0)
175 		return 0xffffffffffffffffULL;
176 	else if (rssi_lv == 1)
177 		return 0xfffffffffffffff0ULL;
178 	else if (rssi_lv == 2)
179 		return 0xffffffffffffefe0ULL;
180 	else if (rssi_lv == 3)
181 		return 0xffffffffffffcfc0ULL;
182 	else if (rssi_lv == 4)
183 		return 0xffffffffffff8f80ULL;
184 	else if (rssi_lv >= 5)
185 		return 0xffffffffffff0f00ULL;
186 
187 	return 0xffffffffffffffffULL;
188 }
189 
rtw89_phy_ra_mask_recover(u64 ra_mask,u64 ra_mask_bak)190 static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak)
191 {
192 	if ((ra_mask & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES)) == 0)
193 		ra_mask |= (ra_mask_bak & ~(RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES));
194 
195 	if (ra_mask == 0)
196 		ra_mask |= (ra_mask_bak & (RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES));
197 
198 	return ra_mask;
199 }
200 
rtw89_phy_ra_mask_cfg(struct rtw89_dev * rtwdev,struct rtw89_sta_link * rtwsta_link,struct ieee80211_link_sta * link_sta,const struct rtw89_chan * chan)201 static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev,
202 				 struct rtw89_sta_link *rtwsta_link,
203 				 struct ieee80211_link_sta *link_sta,
204 				 const struct rtw89_chan *chan)
205 {
206 	struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask;
207 	enum nl80211_band band;
208 	u64 cfg_mask;
209 
210 	if (!rtwsta_link->use_cfg_mask)
211 		return -1;
212 
213 	switch (chan->band_type) {
214 	case RTW89_BAND_2G:
215 		band = NL80211_BAND_2GHZ;
216 		cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_2GHZ].legacy,
217 					   RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES);
218 		break;
219 	case RTW89_BAND_5G:
220 		band = NL80211_BAND_5GHZ;
221 		cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_5GHZ].legacy,
222 					   RA_MASK_OFDM_RATES);
223 		break;
224 	case RTW89_BAND_6G:
225 		band = NL80211_BAND_6GHZ;
226 		cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_6GHZ].legacy,
227 					   RA_MASK_OFDM_RATES);
228 		break;
229 	default:
230 		rtw89_warn(rtwdev, "unhandled band type %d\n", chan->band_type);
231 		return -1;
232 	}
233 
234 	if (link_sta->eht_cap.has_eht) {
235 		cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[0],
236 					    RA_MASK_EHT_1SS_RATES);
237 		cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[1],
238 					    RA_MASK_EHT_2SS_RATES);
239 	} else if (link_sta->he_cap.has_he) {
240 		cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0],
241 					    RA_MASK_HE_1SS_RATES);
242 		cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1],
243 					    RA_MASK_HE_2SS_RATES);
244 	} else if (link_sta->vht_cap.vht_supported) {
245 		cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0],
246 					    RA_MASK_VHT_1SS_RATES);
247 		cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1],
248 					    RA_MASK_VHT_2SS_RATES);
249 	} else if (link_sta->ht_cap.ht_supported) {
250 		cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0],
251 					    RA_MASK_HT_1SS_RATES);
252 		cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1],
253 					    RA_MASK_HT_2SS_RATES);
254 	}
255 
256 	return cfg_mask;
257 }
258 
259 static const u64
260 rtw89_ra_mask_ht_rates[4] = {RA_MASK_HT_1SS_RATES, RA_MASK_HT_2SS_RATES,
261 			     RA_MASK_HT_3SS_RATES, RA_MASK_HT_4SS_RATES};
262 static const u64
263 rtw89_ra_mask_vht_rates[4] = {RA_MASK_VHT_1SS_RATES, RA_MASK_VHT_2SS_RATES,
264 			      RA_MASK_VHT_3SS_RATES, RA_MASK_VHT_4SS_RATES};
265 static const u64
266 rtw89_ra_mask_he_rates[4] = {RA_MASK_HE_1SS_RATES, RA_MASK_HE_2SS_RATES,
267 			     RA_MASK_HE_3SS_RATES, RA_MASK_HE_4SS_RATES};
268 static const u64
269 rtw89_ra_mask_eht_rates[4] = {RA_MASK_EHT_1SS_RATES, RA_MASK_EHT_2SS_RATES,
270 			      RA_MASK_EHT_3SS_RATES, RA_MASK_EHT_4SS_RATES};
271 static const u64
272 rtw89_ra_mask_eht_mcs0_11[4] = {RA_MASK_EHT_1SS_MCS0_11, RA_MASK_EHT_2SS_MCS0_11,
273 				RA_MASK_EHT_3SS_MCS0_11, RA_MASK_EHT_4SS_MCS0_11};
274 
rtw89_phy_ra_gi_ltf(struct rtw89_dev * rtwdev,struct rtw89_sta_link * rtwsta_link,struct ieee80211_link_sta * link_sta,const struct rtw89_chan * chan,bool * fix_giltf_en,u8 * fix_giltf)275 static void rtw89_phy_ra_gi_ltf(struct rtw89_dev *rtwdev,
276 				struct rtw89_sta_link *rtwsta_link,
277 				struct ieee80211_link_sta *link_sta,
278 				const struct rtw89_chan *chan,
279 				bool *fix_giltf_en, u8 *fix_giltf)
280 {
281 	struct cfg80211_bitrate_mask *mask = &rtwsta_link->mask;
282 	u8 band = chan->band_type;
283 	enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
284 	u8 ltf, gi;
285 
286 	*fix_giltf_en = true;
287 
288 	if (rtwdev->chip->chip_id == RTL8852C &&
289 	    chan->band_width == RTW89_CHANNEL_WIDTH_160 &&
290 	    rtw89_sta_link_has_su_mu_4xhe08(link_sta))
291 		*fix_giltf = RTW89_GILTF_SGI_4XHE08;
292 	else
293 		*fix_giltf = RTW89_GILTF_2XHE08;
294 
295 	if (!rtwsta_link->use_cfg_mask)
296 		return;
297 
298 	if (link_sta->eht_cap.has_eht) {
299 		ltf = mask->control[nl_band].eht_ltf;
300 		gi = mask->control[nl_band].eht_gi;
301 	} else if (link_sta->he_cap.has_he) {
302 		ltf = mask->control[nl_band].he_ltf;
303 		gi = mask->control[nl_band].he_gi;
304 	} else {
305 		return;
306 	}
307 
308 	if (ltf == 2 && gi == 2)
309 		*fix_giltf = RTW89_GILTF_LGI_4XHE32;
310 	else if (ltf == 2 && gi == 0)
311 		*fix_giltf = RTW89_GILTF_SGI_4XHE08;
312 	else if (ltf == 1 && gi == 1)
313 		*fix_giltf = RTW89_GILTF_2XHE16;
314 	else if (ltf == 1 && gi == 0)
315 		*fix_giltf = RTW89_GILTF_2XHE08;
316 	else if (ltf == 0 && gi == 1)
317 		*fix_giltf = RTW89_GILTF_1XHE16;
318 	else if (ltf == 0 && gi == 0)
319 		*fix_giltf = RTW89_GILTF_1XHE08;
320 }
321 
rtw89_phy_ra_sta_update(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,struct rtw89_sta_link * rtwsta_link,struct ieee80211_link_sta * link_sta,bool p2p,bool csi)322 static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
323 				    struct rtw89_vif_link *rtwvif_link,
324 				    struct rtw89_sta_link *rtwsta_link,
325 				    struct ieee80211_link_sta *link_sta,
326 				    bool p2p, bool csi)
327 {
328 	struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif_link->rate_pattern;
329 	struct rtw89_ra_info *ra = &rtwsta_link->ra;
330 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
331 						       rtwvif_link->chanctx_idx);
332 	const u64 *high_rate_masks = rtw89_ra_mask_ht_rates;
333 	u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi);
334 	u64 ra_mask = 0;
335 	u64 ra_mask_bak;
336 	u8 mode = 0;
337 	u8 csi_mode = RTW89_RA_RPT_MODE_LEGACY;
338 	u8 bw_mode = 0;
339 	u8 stbc_en = 0;
340 	u8 ldpc_en = 0;
341 	u8 fix_giltf = 0;
342 	u8 i;
343 	bool sgi = false;
344 	bool fix_giltf_en = false;
345 
346 	memset(ra, 0, sizeof(*ra));
347 	/* Set the ra mask from sta's capability */
348 	if (link_sta->eht_cap.has_eht) {
349 		mode |= RTW89_RA_MODE_EHT;
350 		ra_mask |= get_eht_ra_mask(rtwvif_link, link_sta);
351 
352 		if (rtwdev->hal.no_mcs_12_13)
353 			high_rate_masks = rtw89_ra_mask_eht_mcs0_11;
354 		else
355 			high_rate_masks = rtw89_ra_mask_eht_rates;
356 
357 		rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, link_sta,
358 				    chan, &fix_giltf_en, &fix_giltf);
359 	} else if (link_sta->he_cap.has_he) {
360 		mode |= RTW89_RA_MODE_HE;
361 		csi_mode = RTW89_RA_RPT_MODE_HE;
362 		ra_mask |= get_he_ra_mask(link_sta);
363 		high_rate_masks = rtw89_ra_mask_he_rates;
364 		if (link_sta->he_cap.he_cap_elem.phy_cap_info[2] &
365 		    IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
366 			stbc_en = 1;
367 		if (link_sta->he_cap.he_cap_elem.phy_cap_info[1] &
368 		    IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
369 			ldpc_en = 1;
370 		rtw89_phy_ra_gi_ltf(rtwdev, rtwsta_link, link_sta,
371 				    chan, &fix_giltf_en, &fix_giltf);
372 	} else if (link_sta->vht_cap.vht_supported) {
373 		u16 mcs_map = le16_to_cpu(link_sta->vht_cap.vht_mcs.rx_mcs_map);
374 
375 		mode |= RTW89_RA_MODE_VHT;
376 		csi_mode = RTW89_RA_RPT_MODE_VHT;
377 		/* MCS9 (non-20MHz), MCS8, MCS7 */
378 		if (link_sta->bandwidth == IEEE80211_STA_RX_BW_20)
379 			ra_mask |= get_mcs_ra_mask(mcs_map, 8, 1);
380 		else
381 			ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1);
382 		high_rate_masks = rtw89_ra_mask_vht_rates;
383 		if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
384 			stbc_en = 1;
385 		if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
386 			ldpc_en = 1;
387 	} else if (link_sta->ht_cap.ht_supported) {
388 		mode |= RTW89_RA_MODE_HT;
389 		csi_mode = RTW89_RA_RPT_MODE_HT;
390 		ra_mask |= ((u64)link_sta->ht_cap.mcs.rx_mask[3] << 48) |
391 			   ((u64)link_sta->ht_cap.mcs.rx_mask[2] << 36) |
392 			   ((u64)link_sta->ht_cap.mcs.rx_mask[1] << 24) |
393 			   ((u64)link_sta->ht_cap.mcs.rx_mask[0] << 12);
394 		high_rate_masks = rtw89_ra_mask_ht_rates;
395 		if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
396 			stbc_en = 1;
397 		if (link_sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
398 			ldpc_en = 1;
399 	}
400 
401 	switch (chan->band_type) {
402 	case RTW89_BAND_2G:
403 		ra_mask |= link_sta->supp_rates[NL80211_BAND_2GHZ];
404 		if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xf)
405 			mode |= RTW89_RA_MODE_CCK;
406 		if (link_sta->supp_rates[NL80211_BAND_2GHZ] & 0xff0)
407 			mode |= RTW89_RA_MODE_OFDM;
408 		break;
409 	case RTW89_BAND_5G:
410 		ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_5GHZ] << 4;
411 		mode |= RTW89_RA_MODE_OFDM;
412 		break;
413 	case RTW89_BAND_6G:
414 		ra_mask |= (u64)link_sta->supp_rates[NL80211_BAND_6GHZ] << 4;
415 		mode |= RTW89_RA_MODE_OFDM;
416 		break;
417 	default:
418 		rtw89_err(rtwdev, "Unknown band type\n");
419 		break;
420 	}
421 
422 	ra_mask_bak = ra_mask;
423 
424 	if (mode >= RTW89_RA_MODE_HT) {
425 		u64 mask = 0;
426 		for (i = 0; i < rtwdev->hal.tx_nss; i++)
427 			mask |= high_rate_masks[i];
428 		if (mode & RTW89_RA_MODE_OFDM)
429 			mask |= RA_MASK_SUBOFDM_RATES;
430 		if (mode & RTW89_RA_MODE_CCK)
431 			mask |= RA_MASK_SUBCCK_RATES;
432 		ra_mask &= mask;
433 	} else if (mode & RTW89_RA_MODE_OFDM) {
434 		ra_mask &= (RA_MASK_OFDM_RATES | RA_MASK_SUBCCK_RATES);
435 	}
436 
437 	if (mode != RTW89_RA_MODE_CCK)
438 		ra_mask &= rtw89_phy_ra_mask_rssi(rtwdev, rssi, 0);
439 
440 	ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak);
441 	ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan);
442 
443 	switch (link_sta->bandwidth) {
444 	case IEEE80211_STA_RX_BW_160:
445 		bw_mode = RTW89_CHANNEL_WIDTH_160;
446 		sgi = link_sta->vht_cap.vht_supported &&
447 		      (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160);
448 		break;
449 	case IEEE80211_STA_RX_BW_80:
450 		bw_mode = RTW89_CHANNEL_WIDTH_80;
451 		sgi = link_sta->vht_cap.vht_supported &&
452 		      (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
453 		break;
454 	case IEEE80211_STA_RX_BW_40:
455 		bw_mode = RTW89_CHANNEL_WIDTH_40;
456 		sgi = link_sta->ht_cap.ht_supported &&
457 		      (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
458 		break;
459 	default:
460 		bw_mode = RTW89_CHANNEL_WIDTH_20;
461 		sgi = link_sta->ht_cap.ht_supported &&
462 		      (link_sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
463 		break;
464 	}
465 
466 	if (link_sta->he_cap.he_cap_elem.phy_cap_info[3] &
467 	    IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM)
468 		ra->dcm_cap = 1;
469 
470 	if (rate_pattern->enable && !p2p) {
471 		ra_mask = rtw89_phy_ra_mask_cfg(rtwdev, rtwsta_link, link_sta, chan);
472 		ra_mask &= rate_pattern->ra_mask;
473 		mode = rate_pattern->ra_mode;
474 	}
475 
476 	ra->bw_cap = bw_mode;
477 	ra->er_cap = rtwsta_link->er_cap;
478 	ra->mode_ctrl = mode;
479 	ra->macid = rtwsta_link->mac_id;
480 	ra->stbc_cap = stbc_en;
481 	ra->ldpc_cap = ldpc_en;
482 	ra->ss_num = min(link_sta->rx_nss, rtwdev->hal.tx_nss) - 1;
483 	ra->en_sgi = sgi;
484 	ra->ra_mask = ra_mask;
485 	ra->fix_giltf_en = fix_giltf_en;
486 	ra->fix_giltf = fix_giltf;
487 	ra->partial_bw_er = link_sta->he_cap.has_he ?
488 			    !!(link_sta->he_cap.he_cap_elem.phy_cap_info[6] &
489 			       IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE) : 0;
490 	ra->band = chan->band_type;
491 
492 	if (!csi)
493 		return;
494 
495 	ra->fixed_csi_rate_en = false;
496 	ra->ra_csi_rate_en = true;
497 	ra->cr_tbl_sel = false;
498 	ra->band_num = rtwvif_link->phy_idx;
499 	ra->csi_bw = bw_mode;
500 	ra->csi_gi_ltf = RTW89_GILTF_LGI_4XHE32;
501 	ra->csi_mcs_ss_idx = 5;
502 	ra->csi_mode = csi_mode;
503 }
504 
rtw89_phy_ra_update_sta_link(struct rtw89_dev * rtwdev,struct rtw89_sta_link * rtwsta_link,u32 changed)505 void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev,
506 				  struct rtw89_sta_link *rtwsta_link,
507 				  u32 changed)
508 {
509 	struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
510 	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
511 	struct rtw89_ra_info *ra = &rtwsta_link->ra;
512 	struct ieee80211_link_sta *link_sta;
513 
514 	rcu_read_lock();
515 
516 	link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
517 	rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link,
518 				link_sta, vif->p2p, false);
519 
520 	rcu_read_unlock();
521 
522 	if (changed & IEEE80211_RC_SUPP_RATES_CHANGED)
523 		ra->upd_mask = 1;
524 	if (changed & (IEEE80211_RC_BW_CHANGED | IEEE80211_RC_NSS_CHANGED))
525 		ra->upd_bw_nss_mask = 1;
526 
527 	rtw89_debug(rtwdev, RTW89_DBG_RA,
528 		    "ra updat: macid = %d, bw = %d, nss = %d, gi = %d %d",
529 		    ra->macid,
530 		    ra->bw_cap,
531 		    ra->ss_num,
532 		    ra->en_sgi,
533 		    ra->giltf);
534 
535 	rtw89_fw_h2c_ra(rtwdev, ra, false);
536 }
537 
rtw89_phy_ra_update_sta(struct rtw89_dev * rtwdev,struct ieee80211_sta * sta,u32 changed)538 void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
539 			     u32 changed)
540 {
541 	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
542 	struct rtw89_sta_link *rtwsta_link;
543 	unsigned int link_id;
544 
545 	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
546 		rtw89_phy_ra_update_sta_link(rtwdev, rtwsta_link, changed);
547 }
548 
__check_rate_pattern(struct rtw89_phy_rate_pattern * next,u16 rate_base,u64 ra_mask,u8 ra_mode,u32 rate_ctrl,u32 ctrl_skip,bool force)549 static bool __check_rate_pattern(struct rtw89_phy_rate_pattern *next,
550 				 u16 rate_base, u64 ra_mask, u8 ra_mode,
551 				 u32 rate_ctrl, u32 ctrl_skip, bool force)
552 {
553 	u8 n, c;
554 
555 	if (rate_ctrl == ctrl_skip)
556 		return true;
557 
558 	n = hweight32(rate_ctrl);
559 	if (n == 0)
560 		return true;
561 
562 	if (force && n != 1)
563 		return false;
564 
565 	if (next->enable)
566 		return false;
567 
568 	c = __fls(rate_ctrl);
569 	next->rate = rate_base + c;
570 	next->ra_mode = ra_mode;
571 	next->ra_mask = ra_mask;
572 	next->enable = true;
573 
574 	return true;
575 }
576 
577 enum __rtw89_hw_rate_invalid_bases {
578 	/* no EHT rate for ax chip */
579 	RTW89_HW_RATE_EHT_NSS1_MCS0 = RTW89_HW_RATE_INVAL,
580 	RTW89_HW_RATE_EHT_NSS2_MCS0 = RTW89_HW_RATE_INVAL,
581 	RTW89_HW_RATE_EHT_NSS3_MCS0 = RTW89_HW_RATE_INVAL,
582 	RTW89_HW_RATE_EHT_NSS4_MCS0 = RTW89_HW_RATE_INVAL,
583 };
584 
585 #define RTW89_HW_RATE_BY_CHIP_GEN(rate) \
586 	{ \
587 		[RTW89_CHIP_AX] = RTW89_HW_RATE_ ## rate, \
588 		[RTW89_CHIP_BE] = RTW89_HW_RATE_V1_ ## rate, \
589 	}
590 
591 static
__rtw89_phy_rate_pattern_vif(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,const struct cfg80211_bitrate_mask * mask)592 void __rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
593 				  struct rtw89_vif_link *rtwvif_link,
594 				  const struct cfg80211_bitrate_mask *mask)
595 {
596 	struct ieee80211_supported_band *sband;
597 	struct rtw89_phy_rate_pattern next_pattern = {0};
598 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
599 						       rtwvif_link->chanctx_idx);
600 	static const u16 hw_rate_eht[][RTW89_CHIP_GEN_NUM] = {
601 		RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS1_MCS0),
602 		RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS2_MCS0),
603 		RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS3_MCS0),
604 		RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS4_MCS0),
605 	};
606 	static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = {
607 		RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0),
608 		RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0),
609 		RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS3_MCS0),
610 		RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS4_MCS0),
611 	};
612 	static const u16 hw_rate_vht[][RTW89_CHIP_GEN_NUM] = {
613 		RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS1_MCS0),
614 		RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS2_MCS0),
615 		RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS3_MCS0),
616 		RTW89_HW_RATE_BY_CHIP_GEN(VHT_NSS4_MCS0),
617 	};
618 	static const u16 hw_rate_ht[][RTW89_CHIP_GEN_NUM] = {
619 		RTW89_HW_RATE_BY_CHIP_GEN(MCS0),
620 		RTW89_HW_RATE_BY_CHIP_GEN(MCS8),
621 		RTW89_HW_RATE_BY_CHIP_GEN(MCS16),
622 		RTW89_HW_RATE_BY_CHIP_GEN(MCS24),
623 	};
624 	u8 band = chan->band_type;
625 	enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
626 	enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
627 	u8 tx_nss = rtwdev->hal.tx_nss;
628 	u8 i;
629 
630 	if (chip_gen == RTW89_CHIP_AX)
631 		goto rs_11ax;
632 
633 	for (i = 0; i < tx_nss; i++)
634 		if (!__check_rate_pattern(&next_pattern, hw_rate_eht[i][chip_gen],
635 					  RA_MASK_EHT_RATES, RTW89_RA_MODE_EHT,
636 					  mask->control[nl_band].eht_mcs[i],
637 					  0, true))
638 			goto out;
639 
640 rs_11ax:
641 	for (i = 0; i < tx_nss; i++)
642 		if (!__check_rate_pattern(&next_pattern, hw_rate_he[i][chip_gen],
643 					  RA_MASK_HE_RATES, RTW89_RA_MODE_HE,
644 					  mask->control[nl_band].he_mcs[i],
645 					  0, true))
646 			goto out;
647 
648 	for (i = 0; i < tx_nss; i++)
649 		if (!__check_rate_pattern(&next_pattern, hw_rate_vht[i][chip_gen],
650 					  RA_MASK_VHT_RATES, RTW89_RA_MODE_VHT,
651 					  mask->control[nl_band].vht_mcs[i],
652 					  0, true))
653 			goto out;
654 
655 	for (i = 0; i < tx_nss; i++)
656 		if (!__check_rate_pattern(&next_pattern, hw_rate_ht[i][chip_gen],
657 					  RA_MASK_HT_RATES, RTW89_RA_MODE_HT,
658 					  mask->control[nl_band].ht_mcs[i],
659 					  0, true))
660 			goto out;
661 
662 	/* lagacy cannot be empty for nl80211_parse_tx_bitrate_mask, and
663 	 * require at least one basic rate for ieee80211_set_bitrate_mask,
664 	 * so the decision just depends on if all bitrates are set or not.
665 	 */
666 	sband = rtwdev->hw->wiphy->bands[nl_band];
667 	if (band == RTW89_BAND_2G) {
668 		if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_CCK1,
669 					  RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES,
670 					  RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM,
671 					  mask->control[nl_band].legacy,
672 					  BIT(sband->n_bitrates) - 1, false))
673 			goto out;
674 	} else {
675 		if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_OFDM6,
676 					  RA_MASK_OFDM_RATES, RTW89_RA_MODE_OFDM,
677 					  mask->control[nl_band].legacy,
678 					  BIT(sband->n_bitrates) - 1, false))
679 			goto out;
680 	}
681 
682 	if (!next_pattern.enable)
683 		goto out;
684 
685 	if (unlikely(next_pattern.rate >= RTW89_HW_RATE_INVAL)) {
686 		rtw89_debug(rtwdev, RTW89_DBG_RA,
687 			    "pattern invalid target: chip_gen %d, mode 0x%x\n",
688 			    chip_gen, next_pattern.ra_mode);
689 		goto out;
690 	}
691 
692 	rtwvif_link->rate_pattern = next_pattern;
693 	rtw89_debug(rtwdev, RTW89_DBG_RA,
694 		    "configure pattern: rate 0x%x, mask 0x%llx, mode 0x%x\n",
695 		    next_pattern.rate,
696 		    next_pattern.ra_mask,
697 		    next_pattern.ra_mode);
698 	return;
699 
700 out:
701 	rtwvif_link->rate_pattern.enable = false;
702 	rtw89_debug(rtwdev, RTW89_DBG_RA, "unset rate pattern\n");
703 }
704 
rtw89_phy_rate_pattern_vif(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,const struct cfg80211_bitrate_mask * mask)705 void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
706 				struct ieee80211_vif *vif,
707 				const struct cfg80211_bitrate_mask *mask)
708 {
709 	struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
710 	struct rtw89_vif_link *rtwvif_link;
711 	unsigned int link_id;
712 
713 	rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
714 		__rtw89_phy_rate_pattern_vif(rtwdev, rtwvif_link, mask);
715 }
716 
rtw89_phy_ra_update_sta_iter(void * data,struct ieee80211_sta * sta)717 static void rtw89_phy_ra_update_sta_iter(void *data, struct ieee80211_sta *sta)
718 {
719 	struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
720 
721 	rtw89_phy_ra_update_sta(rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
722 }
723 
rtw89_phy_ra_update(struct rtw89_dev * rtwdev)724 void rtw89_phy_ra_update(struct rtw89_dev *rtwdev)
725 {
726 	ieee80211_iterate_stations_atomic(rtwdev->hw,
727 					  rtw89_phy_ra_update_sta_iter,
728 					  rtwdev);
729 }
730 
rtw89_phy_ra_assoc(struct rtw89_dev * rtwdev,struct rtw89_sta_link * rtwsta_link)731 void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link)
732 {
733 	struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
734 	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
735 	struct rtw89_ra_info *ra = &rtwsta_link->ra;
736 	u8 rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
737 	struct ieee80211_link_sta *link_sta;
738 	bool csi;
739 
740 	rcu_read_lock();
741 
742 	link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
743 	csi = rtw89_sta_has_beamformer_cap(link_sta);
744 
745 	rtw89_phy_ra_sta_update(rtwdev, rtwvif_link, rtwsta_link,
746 				link_sta, vif->p2p, csi);
747 
748 	rcu_read_unlock();
749 
750 	if (rssi > 40)
751 		ra->init_rate_lv = 1;
752 	else if (rssi > 20)
753 		ra->init_rate_lv = 2;
754 	else if (rssi > 1)
755 		ra->init_rate_lv = 3;
756 	else
757 		ra->init_rate_lv = 0;
758 	ra->upd_all = 1;
759 	rtw89_debug(rtwdev, RTW89_DBG_RA,
760 		    "ra assoc: macid = %d, mode = %d, bw = %d, nss = %d, lv = %d",
761 		    ra->macid,
762 		    ra->mode_ctrl,
763 		    ra->bw_cap,
764 		    ra->ss_num,
765 		    ra->init_rate_lv);
766 	rtw89_debug(rtwdev, RTW89_DBG_RA,
767 		    "ra assoc: dcm = %d, er = %d, ldpc = %d, stbc = %d, gi = %d %d",
768 		    ra->dcm_cap,
769 		    ra->er_cap,
770 		    ra->ldpc_cap,
771 		    ra->stbc_cap,
772 		    ra->en_sgi,
773 		    ra->giltf);
774 
775 	rtw89_fw_h2c_ra(rtwdev, ra, csi);
776 }
777 
rtw89_phy_ra_recalc_agg_limit(struct rtw89_dev * rtwdev)778 void rtw89_phy_ra_recalc_agg_limit(struct rtw89_dev *rtwdev)
779 {
780 	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
781 	const struct rtw89_reg_def *ra_limit = &mac->ra_agg_limit;
782 	struct ieee80211_sta *sta;
783 	struct rtw89_sta *rtwsta;
784 	u16 agg_num = U16_MAX;
785 	u8 tid;
786 
787 	for_each_station(sta, rtwdev->hw) {
788 		rtwsta = sta_to_rtwsta(sta);
789 
790 		for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS)
791 			agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num);
792 	}
793 
794 	if (agg_num == U16_MAX)
795 		agg_num = 0x3F;
796 	else
797 		agg_num = clamp(agg_num, 1, 256) - 1;
798 
799 	rtw89_write32_idx(rtwdev, ra_limit->addr, ra_limit->mask, agg_num, RTW89_MAC_0);
800 	if (!rtwdev->dbcc_en)
801 		return;
802 	rtw89_write32_idx(rtwdev, ra_limit->addr, ra_limit->mask, agg_num, RTW89_MAC_1);
803 }
804 
rtw89_phy_get_txsc(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,enum rtw89_bandwidth dbw)805 u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev,
806 		      const struct rtw89_chan *chan,
807 		      enum rtw89_bandwidth dbw)
808 {
809 	enum rtw89_bandwidth cbw = chan->band_width;
810 	u8 pri_ch = chan->primary_channel;
811 	u8 central_ch = chan->channel;
812 	u8 txsc_idx = 0;
813 	u8 tmp = 0;
814 
815 	if (cbw == dbw || cbw == RTW89_CHANNEL_WIDTH_20)
816 		return txsc_idx;
817 
818 	switch (cbw) {
819 	case RTW89_CHANNEL_WIDTH_40:
820 		txsc_idx = pri_ch > central_ch ? 1 : 2;
821 		break;
822 	case RTW89_CHANNEL_WIDTH_80:
823 		if (dbw == RTW89_CHANNEL_WIDTH_20) {
824 			if (pri_ch > central_ch)
825 				txsc_idx = (pri_ch - central_ch) >> 1;
826 			else
827 				txsc_idx = ((central_ch - pri_ch) >> 1) + 1;
828 		} else {
829 			txsc_idx = pri_ch > central_ch ? 9 : 10;
830 		}
831 		break;
832 	case RTW89_CHANNEL_WIDTH_160:
833 		if (pri_ch > central_ch)
834 			tmp = (pri_ch - central_ch) >> 1;
835 		else
836 			tmp = ((central_ch - pri_ch) >> 1) + 1;
837 
838 		if (dbw == RTW89_CHANNEL_WIDTH_20) {
839 			txsc_idx = tmp;
840 		} else if (dbw == RTW89_CHANNEL_WIDTH_40) {
841 			if (tmp == 1 || tmp == 3)
842 				txsc_idx = 9;
843 			else if (tmp == 5 || tmp == 7)
844 				txsc_idx = 11;
845 			else if (tmp == 2 || tmp == 4)
846 				txsc_idx = 10;
847 			else if (tmp == 6 || tmp == 8)
848 				txsc_idx = 12;
849 			else
850 				return 0xff;
851 		} else {
852 			txsc_idx = pri_ch > central_ch ? 13 : 14;
853 		}
854 		break;
855 	case RTW89_CHANNEL_WIDTH_80_80:
856 		if (dbw == RTW89_CHANNEL_WIDTH_20) {
857 			if (pri_ch > central_ch)
858 				txsc_idx = (10 - (pri_ch - central_ch)) >> 1;
859 			else
860 				txsc_idx = ((central_ch - pri_ch) >> 1) + 5;
861 		} else if (dbw == RTW89_CHANNEL_WIDTH_40) {
862 			txsc_idx = pri_ch > central_ch ? 10 : 12;
863 		} else {
864 			txsc_idx = 14;
865 		}
866 		break;
867 	default:
868 		break;
869 	}
870 
871 	return txsc_idx;
872 }
873 EXPORT_SYMBOL(rtw89_phy_get_txsc);
874 
rtw89_phy_get_txsb(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,enum rtw89_bandwidth dbw)875 u8 rtw89_phy_get_txsb(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan,
876 		      enum rtw89_bandwidth dbw)
877 {
878 	enum rtw89_bandwidth cbw = chan->band_width;
879 	u8 pri_ch = chan->primary_channel;
880 	u8 central_ch = chan->channel;
881 	u8 txsb_idx = 0;
882 
883 	if (cbw == dbw || cbw == RTW89_CHANNEL_WIDTH_20)
884 		return txsb_idx;
885 
886 	switch (cbw) {
887 	case RTW89_CHANNEL_WIDTH_40:
888 		txsb_idx = pri_ch > central_ch ? 1 : 0;
889 		break;
890 	case RTW89_CHANNEL_WIDTH_80:
891 		if (dbw == RTW89_CHANNEL_WIDTH_20)
892 			txsb_idx = (pri_ch - central_ch + 6) / 4;
893 		else
894 			txsb_idx = pri_ch > central_ch ? 1 : 0;
895 		break;
896 	case RTW89_CHANNEL_WIDTH_160:
897 		if (dbw == RTW89_CHANNEL_WIDTH_20)
898 			txsb_idx = (pri_ch - central_ch + 14) / 4;
899 		else if (dbw == RTW89_CHANNEL_WIDTH_40)
900 			txsb_idx = (pri_ch - central_ch + 12) / 8;
901 		else
902 			txsb_idx = pri_ch > central_ch ? 1 : 0;
903 		break;
904 	case RTW89_CHANNEL_WIDTH_320:
905 		if (dbw == RTW89_CHANNEL_WIDTH_20)
906 			txsb_idx = (pri_ch - central_ch + 30) / 4;
907 		else if (dbw == RTW89_CHANNEL_WIDTH_40)
908 			txsb_idx = (pri_ch - central_ch + 28) / 8;
909 		else if (dbw == RTW89_CHANNEL_WIDTH_80)
910 			txsb_idx = (pri_ch - central_ch + 24) / 16;
911 		else
912 			txsb_idx = pri_ch > central_ch ? 1 : 0;
913 		break;
914 	default:
915 		break;
916 	}
917 
918 	return txsb_idx;
919 }
920 EXPORT_SYMBOL(rtw89_phy_get_txsb);
921 
rtw89_phy_check_swsi_busy(struct rtw89_dev * rtwdev)922 static bool rtw89_phy_check_swsi_busy(struct rtw89_dev *rtwdev)
923 {
924 	return !!rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, B_SWSI_W_BUSY_V1) ||
925 	       !!rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, B_SWSI_R_BUSY_V1);
926 }
927 
rtw89_phy_read_rf(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask)928 u32 rtw89_phy_read_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
929 		      u32 addr, u32 mask)
930 {
931 	const struct rtw89_chip_info *chip = rtwdev->chip;
932 	const u32 *base_addr = chip->rf_base_addr;
933 	u32 val, direct_addr;
934 
935 	if (rf_path >= rtwdev->chip->rf_path_num) {
936 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
937 		return INV_RF_DATA;
938 	}
939 
940 	addr &= 0xff;
941 	direct_addr = base_addr[rf_path] + (addr << 2);
942 	mask &= RFREG_MASK;
943 
944 	val = rtw89_phy_read32_mask(rtwdev, direct_addr, mask);
945 
946 	return val;
947 }
948 EXPORT_SYMBOL(rtw89_phy_read_rf);
949 
rtw89_phy_read_rf_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask)950 static u32 rtw89_phy_read_rf_a(struct rtw89_dev *rtwdev,
951 			       enum rtw89_rf_path rf_path, u32 addr, u32 mask)
952 {
953 	bool busy;
954 	bool done;
955 	u32 val;
956 	int ret;
957 
958 	ret = read_poll_timeout_atomic(rtw89_phy_check_swsi_busy, busy, !busy,
959 				       1, 30, false, rtwdev);
960 	if (ret) {
961 		rtw89_err(rtwdev, "read rf busy swsi\n");
962 		return INV_RF_DATA;
963 	}
964 
965 	mask &= RFREG_MASK;
966 
967 	val = FIELD_PREP(B_SWSI_READ_ADDR_PATH_V1, rf_path) |
968 	      FIELD_PREP(B_SWSI_READ_ADDR_ADDR_V1, addr);
969 	rtw89_phy_write32_mask(rtwdev, R_SWSI_READ_ADDR_V1, B_SWSI_READ_ADDR_V1, val);
970 	udelay(2);
971 
972 	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done, 1,
973 				       30, false, rtwdev, R_SWSI_V1,
974 				       B_SWSI_R_DATA_DONE_V1);
975 	if (ret) {
976 		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
977 			rtw89_err(rtwdev, "read swsi busy\n");
978 		return INV_RF_DATA;
979 	}
980 
981 	return rtw89_phy_read32_mask(rtwdev, R_SWSI_V1, mask);
982 }
983 
rtw89_phy_read_rf_v1(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask)984 u32 rtw89_phy_read_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
985 			 u32 addr, u32 mask)
986 {
987 	bool ad_sel = FIELD_GET(RTW89_RF_ADDR_ADSEL_MASK, addr);
988 
989 	if (rf_path >= rtwdev->chip->rf_path_num) {
990 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
991 		return INV_RF_DATA;
992 	}
993 
994 	if (ad_sel)
995 		return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask);
996 	else
997 		return rtw89_phy_read_rf_a(rtwdev, rf_path, addr, mask);
998 }
999 EXPORT_SYMBOL(rtw89_phy_read_rf_v1);
1000 
rtw89_phy_read_full_rf_v2_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr)1001 static u32 rtw89_phy_read_full_rf_v2_a(struct rtw89_dev *rtwdev,
1002 				       enum rtw89_rf_path rf_path, u32 addr)
1003 {
1004 	static const u16 r_addr_ofst[2] = {0x2C24, 0x2D24};
1005 	static const u16 addr_ofst[2] = {0x2ADC, 0x2BDC};
1006 	bool busy, done;
1007 	int ret;
1008 	u32 val;
1009 
1010 	rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_CTL_MASK, 0x1);
1011 	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1012 				       1, 3800, false,
1013 				       rtwdev, r_addr_ofst[rf_path], B_HWSI_VAL_BUSY);
1014 	if (ret) {
1015 		rtw89_warn(rtwdev, "poll HWSI is busy\n");
1016 		return INV_RF_DATA;
1017 	}
1018 
1019 	rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_MASK, addr);
1020 	rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_RD, 0x1);
1021 	udelay(2);
1022 
1023 	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done,
1024 				       1, 3800, false,
1025 				       rtwdev, r_addr_ofst[rf_path], B_HWSI_VAL_RDONE);
1026 	if (ret) {
1027 		rtw89_warn(rtwdev, "read HWSI is busy\n");
1028 		val = INV_RF_DATA;
1029 		goto out;
1030 	}
1031 
1032 	val = rtw89_phy_read32_mask(rtwdev, r_addr_ofst[rf_path], RFREG_MASK);
1033 out:
1034 	rtw89_phy_write32_mask(rtwdev, addr_ofst[rf_path], B_HWSI_ADD_POLL_MASK, 0);
1035 
1036 	return val;
1037 }
1038 
rtw89_phy_read_rf_v2_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask)1039 static u32 rtw89_phy_read_rf_v2_a(struct rtw89_dev *rtwdev,
1040 				  enum rtw89_rf_path rf_path, u32 addr, u32 mask)
1041 {
1042 	u32 val;
1043 
1044 	val = rtw89_phy_read_full_rf_v2_a(rtwdev, rf_path, addr);
1045 
1046 	return (val & mask) >> __ffs(mask);
1047 }
1048 
rtw89_phy_read_rf_v2(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask)1049 u32 rtw89_phy_read_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1050 			 u32 addr, u32 mask)
1051 {
1052 	bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK);
1053 
1054 	if (rf_path >= rtwdev->chip->rf_path_num) {
1055 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
1056 		return INV_RF_DATA;
1057 	}
1058 
1059 	if (ad_sel)
1060 		return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask);
1061 	else
1062 		return rtw89_phy_read_rf_v2_a(rtwdev, rf_path, addr, mask);
1063 }
1064 EXPORT_SYMBOL(rtw89_phy_read_rf_v2);
1065 
rtw89_phy_read_full_rf_v3_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr)1066 static u32 rtw89_phy_read_full_rf_v3_a(struct rtw89_dev *rtwdev,
1067 				       enum rtw89_rf_path rf_path, u32 addr)
1068 {
1069 	bool done;
1070 	u32 busy;
1071 	int ret;
1072 	u32 val;
1073 
1074 	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1075 				       1, 30, false,
1076 				       rtwdev, R_SW_SI_DATA_BE4,
1077 				       B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4);
1078 	if (ret) {
1079 		rtw89_warn(rtwdev, "poll HWSI is busy\n");
1080 		return INV_RF_DATA;
1081 	}
1082 
1083 	val = u32_encode_bits(rf_path, GENMASK(10, 8)) |
1084 	      u32_encode_bits(addr, GENMASK(7, 0));
1085 
1086 	rtw89_phy_write32_mask(rtwdev, R_SW_SI_READ_ADDR_BE4, B_SW_SI_READ_ADDR_BE4, val);
1087 
1088 	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, done, done,
1089 				       1, 30, false,
1090 				       rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_DONE_BE4);
1091 	if (ret) {
1092 		rtw89_warn(rtwdev, "read HWSI is busy\n");
1093 		return INV_RF_DATA;
1094 	}
1095 
1096 	val = rtw89_phy_read32_mask(rtwdev, R_SW_SI_DATA_BE4, B_SW_SI_READ_DATA_BE4);
1097 
1098 	return val;
1099 }
1100 
rtw89_phy_read_rf_v3_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask)1101 static u32 rtw89_phy_read_rf_v3_a(struct rtw89_dev *rtwdev,
1102 				  enum rtw89_rf_path rf_path, u32 addr, u32 mask)
1103 {
1104 	u32 val;
1105 
1106 	val = rtw89_phy_read_full_rf_v3_a(rtwdev, rf_path, addr);
1107 
1108 	return (val & mask) >> __ffs(mask);
1109 }
1110 
rtw89_phy_read_rf_v3(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask)1111 u32 rtw89_phy_read_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1112 			 u32 addr, u32 mask)
1113 {
1114 	bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK);
1115 
1116 	if (rf_path >= rtwdev->chip->rf_path_num) {
1117 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
1118 		return INV_RF_DATA;
1119 	}
1120 
1121 	if (ad_sel)
1122 		return rtw89_phy_read_rf(rtwdev, rf_path, addr, mask);
1123 	else
1124 		return rtw89_phy_read_rf_v3_a(rtwdev, rf_path, addr, mask);
1125 }
1126 EXPORT_SYMBOL(rtw89_phy_read_rf_v3);
1127 
rtw89_phy_write_rf(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask,u32 data)1128 bool rtw89_phy_write_rf(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1129 			u32 addr, u32 mask, u32 data)
1130 {
1131 	const struct rtw89_chip_info *chip = rtwdev->chip;
1132 	const u32 *base_addr = chip->rf_base_addr;
1133 	u32 direct_addr;
1134 
1135 	if (rf_path >= rtwdev->chip->rf_path_num) {
1136 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
1137 		return false;
1138 	}
1139 
1140 	addr &= 0xff;
1141 	direct_addr = base_addr[rf_path] + (addr << 2);
1142 	mask &= RFREG_MASK;
1143 
1144 	rtw89_phy_write32_mask(rtwdev, direct_addr, mask, data);
1145 
1146 	/* delay to ensure writing properly */
1147 	udelay(1);
1148 
1149 	return true;
1150 }
1151 EXPORT_SYMBOL(rtw89_phy_write_rf);
1152 
rtw89_phy_write_rf_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask,u32 data)1153 static bool rtw89_phy_write_rf_a(struct rtw89_dev *rtwdev,
1154 				 enum rtw89_rf_path rf_path, u32 addr, u32 mask,
1155 				 u32 data)
1156 {
1157 	u8 bit_shift;
1158 	u32 val;
1159 	bool busy, b_msk_en = false;
1160 	int ret;
1161 
1162 	ret = read_poll_timeout_atomic(rtw89_phy_check_swsi_busy, busy, !busy,
1163 				       1, 30, false, rtwdev);
1164 	if (ret) {
1165 		rtw89_err(rtwdev, "write rf busy swsi\n");
1166 		return false;
1167 	}
1168 
1169 	data &= RFREG_MASK;
1170 	mask &= RFREG_MASK;
1171 
1172 	if (mask != RFREG_MASK) {
1173 		b_msk_en = true;
1174 		rtw89_phy_write32_mask(rtwdev, R_SWSI_BIT_MASK_V1, RFREG_MASK,
1175 				       mask);
1176 		bit_shift = __ffs(mask);
1177 		data = (data << bit_shift) & RFREG_MASK;
1178 	}
1179 
1180 	val = FIELD_PREP(B_SWSI_DATA_BIT_MASK_EN_V1, b_msk_en) |
1181 	      FIELD_PREP(B_SWSI_DATA_PATH_V1, rf_path) |
1182 	      FIELD_PREP(B_SWSI_DATA_ADDR_V1, addr) |
1183 	      FIELD_PREP(B_SWSI_DATA_VAL_V1, data);
1184 
1185 	rtw89_phy_write32_mask(rtwdev, R_SWSI_DATA_V1, MASKDWORD, val);
1186 
1187 	return true;
1188 }
1189 
rtw89_phy_write_rf_v1(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask,u32 data)1190 bool rtw89_phy_write_rf_v1(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1191 			   u32 addr, u32 mask, u32 data)
1192 {
1193 	bool ad_sel = FIELD_GET(RTW89_RF_ADDR_ADSEL_MASK, addr);
1194 
1195 	if (rf_path >= rtwdev->chip->rf_path_num) {
1196 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
1197 		return false;
1198 	}
1199 
1200 	if (ad_sel)
1201 		return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data);
1202 	else
1203 		return rtw89_phy_write_rf_a(rtwdev, rf_path, addr, mask, data);
1204 }
1205 EXPORT_SYMBOL(rtw89_phy_write_rf_v1);
1206 
1207 static
rtw89_phy_write_full_rf_v2_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 data)1208 bool rtw89_phy_write_full_rf_v2_a(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1209 				  u32 addr, u32 data)
1210 {
1211 	static const u32 addr_is_idle[2] = {0x2C24, 0x2D24};
1212 	static const u32 addr_ofst[2] = {0x2AE0, 0x2BE0};
1213 	bool busy;
1214 	u32 val;
1215 	int ret;
1216 
1217 	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1218 				       1, 3800, false,
1219 				       rtwdev, addr_is_idle[rf_path], BIT(29));
1220 	if (ret) {
1221 		rtw89_warn(rtwdev, "[%s] HWSI is busy\n", __func__);
1222 		return false;
1223 	}
1224 
1225 	val = u32_encode_bits(addr, B_HWSI_DATA_ADDR) |
1226 	      u32_encode_bits(data, B_HWSI_DATA_VAL);
1227 
1228 	rtw89_phy_write32(rtwdev, addr_ofst[rf_path], val);
1229 
1230 	return true;
1231 }
1232 
1233 static
rtw89_phy_write_rf_a_v2(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask,u32 data)1234 bool rtw89_phy_write_rf_a_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1235 			     u32 addr, u32 mask, u32 data)
1236 {
1237 	u32 val;
1238 
1239 	if (mask == RFREG_MASK) {
1240 		val = data;
1241 	} else {
1242 		val = rtw89_phy_read_full_rf_v2_a(rtwdev, rf_path, addr);
1243 		val &= ~mask;
1244 		val |= (data << __ffs(mask)) & mask;
1245 	}
1246 
1247 	return rtw89_phy_write_full_rf_v2_a(rtwdev, rf_path, addr, val);
1248 }
1249 
rtw89_phy_write_rf_v2(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask,u32 data)1250 bool rtw89_phy_write_rf_v2(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1251 			   u32 addr, u32 mask, u32 data)
1252 {
1253 	bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK);
1254 
1255 	if (rf_path >= rtwdev->chip->rf_path_num) {
1256 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
1257 		return INV_RF_DATA;
1258 	}
1259 
1260 	if (ad_sel)
1261 		return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data);
1262 	else
1263 		return rtw89_phy_write_rf_a_v2(rtwdev, rf_path, addr, mask, data);
1264 }
1265 EXPORT_SYMBOL(rtw89_phy_write_rf_v2);
1266 
1267 static
rtw89_phy_write_full_rf_v3_a(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 data)1268 bool rtw89_phy_write_full_rf_v3_a(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1269 				  u32 addr, u32 data)
1270 {
1271 	u32 busy;
1272 	u32 val;
1273 	int ret;
1274 
1275 	ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, busy, !busy,
1276 				       1, 30, false,
1277 				       rtwdev, R_SW_SI_DATA_BE4,
1278 				       B_SW_SI_W_BUSY_BE4 | B_SW_SI_R_BUSY_BE4);
1279 	if (ret) {
1280 		rtw89_warn(rtwdev, "[%s] HWSI is busy\n", __func__);
1281 		return false;
1282 	}
1283 
1284 	val = u32_encode_bits(rf_path, B_SW_SI_DATA_PATH_BE4) |
1285 	      u32_encode_bits(addr, B_SW_SI_DATA_ADR_BE4) |
1286 	      u32_encode_bits(data, B_SW_SI_DATA_DAT_BE4);
1287 
1288 	rtw89_phy_write32(rtwdev, R_SW_SI_WDATA_BE4, val);
1289 
1290 	return true;
1291 }
1292 
1293 static
rtw89_phy_write_rf_a_v3(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask,u32 data)1294 bool rtw89_phy_write_rf_a_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1295 			     u32 addr, u32 mask, u32 data)
1296 {
1297 	u32 val;
1298 
1299 	if (mask == RFREG_MASK) {
1300 		val = data;
1301 	} else {
1302 		val = rtw89_phy_read_full_rf_v3_a(rtwdev, rf_path, addr);
1303 		val &= ~mask;
1304 		val |= (data << __ffs(mask)) & mask;
1305 	}
1306 
1307 	return rtw89_phy_write_full_rf_v3_a(rtwdev, rf_path, addr, val);
1308 }
1309 
rtw89_phy_write_rf_v3(struct rtw89_dev * rtwdev,enum rtw89_rf_path rf_path,u32 addr,u32 mask,u32 data)1310 bool rtw89_phy_write_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path,
1311 			   u32 addr, u32 mask, u32 data)
1312 {
1313 	bool ad_sel = u32_get_bits(addr, RTW89_RF_ADDR_ADSEL_MASK);
1314 
1315 	if (rf_path >= rtwdev->chip->rf_path_num) {
1316 		rtw89_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
1317 		return INV_RF_DATA;
1318 	}
1319 
1320 	if (ad_sel)
1321 		return rtw89_phy_write_rf(rtwdev, rf_path, addr, mask, data);
1322 	else
1323 		return rtw89_phy_write_rf_a_v3(rtwdev, rf_path, addr, mask, data);
1324 }
1325 EXPORT_SYMBOL(rtw89_phy_write_rf_v3);
1326 
rtw89_chip_rf_v1(struct rtw89_dev * rtwdev)1327 static bool rtw89_chip_rf_v1(struct rtw89_dev *rtwdev)
1328 {
1329 	return rtwdev->chip->ops->write_rf == rtw89_phy_write_rf_v1;
1330 }
1331 
__rtw89_phy_bb_reset(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)1332 static void __rtw89_phy_bb_reset(struct rtw89_dev *rtwdev,
1333 				 enum rtw89_phy_idx phy_idx)
1334 {
1335 	const struct rtw89_chip_info *chip = rtwdev->chip;
1336 
1337 	chip->ops->bb_reset(rtwdev, phy_idx);
1338 }
1339 
rtw89_phy_bb_reset(struct rtw89_dev * rtwdev)1340 static void rtw89_phy_bb_reset(struct rtw89_dev *rtwdev)
1341 {
1342 	__rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0);
1343 	if (rtwdev->dbcc_en)
1344 		__rtw89_phy_bb_reset(rtwdev, RTW89_PHY_1);
1345 }
1346 
rtw89_phy_config_bb_reg(struct rtw89_dev * rtwdev,const struct rtw89_reg2_def * reg,enum rtw89_rf_path rf_path,void * extra_data)1347 static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev,
1348 				    const struct rtw89_reg2_def *reg,
1349 				    enum rtw89_rf_path rf_path,
1350 				    void *extra_data)
1351 {
1352 	u32 addr;
1353 
1354 	if (reg->addr == 0xfe) {
1355 		rtw89_io_mdelay(rtwdev, 50);
1356 	} else if (reg->addr == 0xfd) {
1357 		rtw89_io_mdelay(rtwdev, 5);
1358 	} else if (reg->addr == 0xfc) {
1359 		rtw89_io_mdelay(rtwdev, 1);
1360 	} else if (reg->addr == 0xfb) {
1361 		rtw89_io_udelay(rtwdev, 50);
1362 	} else if (reg->addr == 0xfa) {
1363 		rtw89_io_udelay(rtwdev, 5);
1364 	} else if (reg->addr == 0xf9) {
1365 		rtw89_io_udelay(rtwdev, 1);
1366 	} else if (reg->data == BYPASS_CR_DATA) {
1367 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Bypass CR 0x%x\n", reg->addr);
1368 	} else {
1369 		addr = reg->addr;
1370 
1371 		if ((uintptr_t)extra_data == RTW89_PHY_1)
1372 			addr += rtw89_phy0_phy1_offset(rtwdev, reg->addr);
1373 
1374 		rtw89_phy_write32(rtwdev, addr, reg->data);
1375 	}
1376 }
1377 
1378 union rtw89_phy_bb_gain_arg {
1379 	u32 addr;
1380 	struct {
1381 		union {
1382 			u8 type;
1383 			struct {
1384 				u8 rxsc_start:4;
1385 				u8 bw:4;
1386 			};
1387 		};
1388 		u8 path;
1389 		u8 gain_band;
1390 		u8 cfg_type;
1391 	};
1392 } __packed;
1393 
1394 static void
rtw89_phy_cfg_bb_gain_error(struct rtw89_dev * rtwdev,union rtw89_phy_bb_gain_arg arg,u32 data)1395 rtw89_phy_cfg_bb_gain_error(struct rtw89_dev *rtwdev,
1396 			    union rtw89_phy_bb_gain_arg arg, u32 data)
1397 {
1398 	struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
1399 	u8 type = arg.type;
1400 	u8 path = arg.path;
1401 	u8 gband = arg.gain_band;
1402 	int i;
1403 
1404 	switch (type) {
1405 	case 0:
1406 		for (i = 0; i < 4; i++, data >>= 8)
1407 			gain->lna_gain[gband][path][i] = data & 0xff;
1408 		break;
1409 	case 1:
1410 		for (i = 4; i < 7; i++, data >>= 8)
1411 			gain->lna_gain[gband][path][i] = data & 0xff;
1412 		break;
1413 	case 2:
1414 		for (i = 0; i < 2; i++, data >>= 8)
1415 			gain->tia_gain[gband][path][i] = data & 0xff;
1416 		break;
1417 	default:
1418 		rtw89_warn(rtwdev,
1419 			   "bb gain error {0x%x:0x%x} with unknown type: %d\n",
1420 			   arg.addr, data, type);
1421 		break;
1422 	}
1423 }
1424 
1425 enum rtw89_phy_bb_rxsc_start_idx {
1426 	RTW89_BB_RXSC_START_IDX_FULL = 0,
1427 	RTW89_BB_RXSC_START_IDX_20 = 1,
1428 	RTW89_BB_RXSC_START_IDX_20_1 = 5,
1429 	RTW89_BB_RXSC_START_IDX_40 = 9,
1430 	RTW89_BB_RXSC_START_IDX_80 = 13,
1431 };
1432 
1433 static void
rtw89_phy_cfg_bb_rpl_ofst(struct rtw89_dev * rtwdev,union rtw89_phy_bb_gain_arg arg,u32 data)1434 rtw89_phy_cfg_bb_rpl_ofst(struct rtw89_dev *rtwdev,
1435 			  union rtw89_phy_bb_gain_arg arg, u32 data)
1436 {
1437 	struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
1438 	u8 rxsc_start = arg.rxsc_start;
1439 	u8 bw = arg.bw;
1440 	u8 path = arg.path;
1441 	u8 gband = arg.gain_band;
1442 	u8 rxsc;
1443 	s8 ofst;
1444 	int i;
1445 
1446 	switch (bw) {
1447 	case RTW89_CHANNEL_WIDTH_20:
1448 		gain->rpl_ofst_20[gband][path] = (s8)data;
1449 		break;
1450 	case RTW89_CHANNEL_WIDTH_40:
1451 		if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) {
1452 			gain->rpl_ofst_40[gband][path][0] = (s8)data;
1453 		} else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) {
1454 			for (i = 0; i < 2; i++, data >>= 8) {
1455 				rxsc = RTW89_BB_RXSC_START_IDX_20 + i;
1456 				ofst = (s8)(data & 0xff);
1457 				gain->rpl_ofst_40[gband][path][rxsc] = ofst;
1458 			}
1459 		}
1460 		break;
1461 	case RTW89_CHANNEL_WIDTH_80:
1462 		if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) {
1463 			gain->rpl_ofst_80[gband][path][0] = (s8)data;
1464 		} else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) {
1465 			for (i = 0; i < 4; i++, data >>= 8) {
1466 				rxsc = RTW89_BB_RXSC_START_IDX_20 + i;
1467 				ofst = (s8)(data & 0xff);
1468 				gain->rpl_ofst_80[gband][path][rxsc] = ofst;
1469 			}
1470 		} else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) {
1471 			for (i = 0; i < 2; i++, data >>= 8) {
1472 				rxsc = RTW89_BB_RXSC_START_IDX_40 + i;
1473 				ofst = (s8)(data & 0xff);
1474 				gain->rpl_ofst_80[gband][path][rxsc] = ofst;
1475 			}
1476 		}
1477 		break;
1478 	case RTW89_CHANNEL_WIDTH_160:
1479 		if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) {
1480 			gain->rpl_ofst_160[gband][path][0] = (s8)data;
1481 		} else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) {
1482 			for (i = 0; i < 4; i++, data >>= 8) {
1483 				rxsc = RTW89_BB_RXSC_START_IDX_20 + i;
1484 				ofst = (s8)(data & 0xff);
1485 				gain->rpl_ofst_160[gband][path][rxsc] = ofst;
1486 			}
1487 		} else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20_1) {
1488 			for (i = 0; i < 4; i++, data >>= 8) {
1489 				rxsc = RTW89_BB_RXSC_START_IDX_20_1 + i;
1490 				ofst = (s8)(data & 0xff);
1491 				gain->rpl_ofst_160[gband][path][rxsc] = ofst;
1492 			}
1493 		} else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) {
1494 			for (i = 0; i < 4; i++, data >>= 8) {
1495 				rxsc = RTW89_BB_RXSC_START_IDX_40 + i;
1496 				ofst = (s8)(data & 0xff);
1497 				gain->rpl_ofst_160[gband][path][rxsc] = ofst;
1498 			}
1499 		} else if (rxsc_start == RTW89_BB_RXSC_START_IDX_80) {
1500 			for (i = 0; i < 2; i++, data >>= 8) {
1501 				rxsc = RTW89_BB_RXSC_START_IDX_80 + i;
1502 				ofst = (s8)(data & 0xff);
1503 				gain->rpl_ofst_160[gband][path][rxsc] = ofst;
1504 			}
1505 		}
1506 		break;
1507 	default:
1508 		rtw89_warn(rtwdev,
1509 			   "bb rpl ofst {0x%x:0x%x} with unknown bw: %d\n",
1510 			   arg.addr, data, bw);
1511 		break;
1512 	}
1513 }
1514 
1515 static void
rtw89_phy_cfg_bb_gain_bypass(struct rtw89_dev * rtwdev,union rtw89_phy_bb_gain_arg arg,u32 data)1516 rtw89_phy_cfg_bb_gain_bypass(struct rtw89_dev *rtwdev,
1517 			     union rtw89_phy_bb_gain_arg arg, u32 data)
1518 {
1519 	struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
1520 	u8 type = arg.type;
1521 	u8 path = arg.path;
1522 	u8 gband = arg.gain_band;
1523 	int i;
1524 
1525 	switch (type) {
1526 	case 0:
1527 		for (i = 0; i < 4; i++, data >>= 8)
1528 			gain->lna_gain_bypass[gband][path][i] = data & 0xff;
1529 		break;
1530 	case 1:
1531 		for (i = 4; i < 7; i++, data >>= 8)
1532 			gain->lna_gain_bypass[gband][path][i] = data & 0xff;
1533 		break;
1534 	default:
1535 		rtw89_warn(rtwdev,
1536 			   "bb gain bypass {0x%x:0x%x} with unknown type: %d\n",
1537 			   arg.addr, data, type);
1538 		break;
1539 	}
1540 }
1541 
1542 static void
rtw89_phy_cfg_bb_gain_op1db(struct rtw89_dev * rtwdev,union rtw89_phy_bb_gain_arg arg,u32 data)1543 rtw89_phy_cfg_bb_gain_op1db(struct rtw89_dev *rtwdev,
1544 			    union rtw89_phy_bb_gain_arg arg, u32 data)
1545 {
1546 	struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain.ax;
1547 	u8 type = arg.type;
1548 	u8 path = arg.path;
1549 	u8 gband = arg.gain_band;
1550 	int i;
1551 
1552 	switch (type) {
1553 	case 0:
1554 		for (i = 0; i < 4; i++, data >>= 8)
1555 			gain->lna_op1db[gband][path][i] = data & 0xff;
1556 		break;
1557 	case 1:
1558 		for (i = 4; i < 7; i++, data >>= 8)
1559 			gain->lna_op1db[gband][path][i] = data & 0xff;
1560 		break;
1561 	case 2:
1562 		for (i = 0; i < 4; i++, data >>= 8)
1563 			gain->tia_lna_op1db[gband][path][i] = data & 0xff;
1564 		break;
1565 	case 3:
1566 		for (i = 4; i < 8; i++, data >>= 8)
1567 			gain->tia_lna_op1db[gband][path][i] = data & 0xff;
1568 		break;
1569 	default:
1570 		rtw89_warn(rtwdev,
1571 			   "bb gain op1db {0x%x:0x%x} with unknown type: %d\n",
1572 			   arg.addr, data, type);
1573 		break;
1574 	}
1575 }
1576 
rtw89_phy_config_bb_gain_ax(struct rtw89_dev * rtwdev,const struct rtw89_reg2_def * reg,enum rtw89_rf_path rf_path,void * extra_data)1577 static void rtw89_phy_config_bb_gain_ax(struct rtw89_dev *rtwdev,
1578 					const struct rtw89_reg2_def *reg,
1579 					enum rtw89_rf_path rf_path,
1580 					void *extra_data)
1581 {
1582 	const struct rtw89_chip_info *chip = rtwdev->chip;
1583 	union rtw89_phy_bb_gain_arg arg = { .addr = reg->addr };
1584 	struct rtw89_efuse *efuse = &rtwdev->efuse;
1585 
1586 	if (arg.gain_band >= RTW89_BB_GAIN_BAND_NR)
1587 		return;
1588 
1589 	if (arg.path >= chip->rf_path_num)
1590 		return;
1591 
1592 	if (arg.addr >= 0xf9 && arg.addr <= 0xfe) {
1593 		rtw89_warn(rtwdev, "bb gain table with flow ctrl\n");
1594 		return;
1595 	}
1596 
1597 	switch (arg.cfg_type) {
1598 	case 0:
1599 		rtw89_phy_cfg_bb_gain_error(rtwdev, arg, reg->data);
1600 		break;
1601 	case 1:
1602 		rtw89_phy_cfg_bb_rpl_ofst(rtwdev, arg, reg->data);
1603 		break;
1604 	case 2:
1605 		rtw89_phy_cfg_bb_gain_bypass(rtwdev, arg, reg->data);
1606 		break;
1607 	case 3:
1608 		rtw89_phy_cfg_bb_gain_op1db(rtwdev, arg, reg->data);
1609 		break;
1610 	case 4:
1611 		/* This cfg_type is only used by rfe_type >= 50 with eFEM */
1612 		if (efuse->rfe_type < 50)
1613 			break;
1614 		fallthrough;
1615 	default:
1616 		rtw89_warn(rtwdev,
1617 			   "bb gain {0x%x:0x%x} with unknown cfg type: %d\n",
1618 			   arg.addr, reg->data, arg.cfg_type);
1619 		break;
1620 	}
1621 }
1622 
1623 static void
rtw89_phy_cofig_rf_reg_store(struct rtw89_dev * rtwdev,const struct rtw89_reg2_def * reg,enum rtw89_rf_path rf_path,struct rtw89_fw_h2c_rf_reg_info * info)1624 rtw89_phy_cofig_rf_reg_store(struct rtw89_dev *rtwdev,
1625 			     const struct rtw89_reg2_def *reg,
1626 			     enum rtw89_rf_path rf_path,
1627 			     struct rtw89_fw_h2c_rf_reg_info *info)
1628 {
1629 	u16 idx = info->curr_idx % RTW89_H2C_RF_PAGE_SIZE;
1630 	u8 page = info->curr_idx / RTW89_H2C_RF_PAGE_SIZE;
1631 
1632 	if (page >= RTW89_H2C_RF_PAGE_NUM) {
1633 		rtw89_warn(rtwdev, "RF parameters exceed size. path=%d, idx=%d",
1634 			   rf_path, info->curr_idx);
1635 		return;
1636 	}
1637 
1638 	info->rtw89_phy_config_rf_h2c[page][idx] =
1639 		cpu_to_le32((reg->addr << 20) | reg->data);
1640 	info->curr_idx++;
1641 }
1642 
rtw89_phy_config_rf_reg_fw(struct rtw89_dev * rtwdev,struct rtw89_fw_h2c_rf_reg_info * info)1643 static int rtw89_phy_config_rf_reg_fw(struct rtw89_dev *rtwdev,
1644 				      struct rtw89_fw_h2c_rf_reg_info *info)
1645 {
1646 	u16 remain = info->curr_idx;
1647 	u16 len = 0;
1648 	u8 i;
1649 	int ret = 0;
1650 
1651 	if (remain > RTW89_H2C_RF_PAGE_NUM * RTW89_H2C_RF_PAGE_SIZE) {
1652 		rtw89_warn(rtwdev,
1653 			   "rf reg h2c total len %d larger than %d\n",
1654 			   remain, RTW89_H2C_RF_PAGE_NUM * RTW89_H2C_RF_PAGE_SIZE);
1655 		ret = -EINVAL;
1656 		goto out;
1657 	}
1658 
1659 	for (i = 0; i < RTW89_H2C_RF_PAGE_NUM && remain; i++, remain -= len) {
1660 		len = remain > RTW89_H2C_RF_PAGE_SIZE ? RTW89_H2C_RF_PAGE_SIZE : remain;
1661 		ret = rtw89_fw_h2c_rf_reg(rtwdev, info, len * 4, i);
1662 		if (ret)
1663 			goto out;
1664 	}
1665 out:
1666 	info->curr_idx = 0;
1667 
1668 	return ret;
1669 }
1670 
rtw89_phy_config_rf_reg_noio(struct rtw89_dev * rtwdev,const struct rtw89_reg2_def * reg,enum rtw89_rf_path rf_path,void * extra_data)1671 static void rtw89_phy_config_rf_reg_noio(struct rtw89_dev *rtwdev,
1672 					 const struct rtw89_reg2_def *reg,
1673 					 enum rtw89_rf_path rf_path,
1674 					 void *extra_data)
1675 {
1676 	u32 addr = reg->addr;
1677 
1678 	if (addr == 0xfe || addr == 0xfd || addr == 0xfc || addr == 0xfb ||
1679 	    addr == 0xfa || addr == 0xf9)
1680 		return;
1681 
1682 	if (rtw89_chip_rf_v1(rtwdev) && addr < 0x100)
1683 		return;
1684 
1685 	rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path,
1686 				     (struct rtw89_fw_h2c_rf_reg_info *)extra_data);
1687 }
1688 
rtw89_phy_config_rf_reg(struct rtw89_dev * rtwdev,const struct rtw89_reg2_def * reg,enum rtw89_rf_path rf_path,void * extra_data)1689 void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev,
1690 			     const struct rtw89_reg2_def *reg,
1691 			     enum rtw89_rf_path rf_path,
1692 			     void *extra_data)
1693 {
1694 	if (reg->addr == 0xfe) {
1695 		rtw89_io_mdelay(rtwdev, 50);
1696 	} else if (reg->addr == 0xfd) {
1697 		rtw89_io_mdelay(rtwdev, 5);
1698 	} else if (reg->addr == 0xfc) {
1699 		rtw89_io_mdelay(rtwdev, 1);
1700 	} else if (reg->addr == 0xfb) {
1701 		rtw89_io_udelay(rtwdev, 50);
1702 	} else if (reg->addr == 0xfa) {
1703 		rtw89_io_udelay(rtwdev, 5);
1704 	} else if (reg->addr == 0xf9) {
1705 		rtw89_io_udelay(rtwdev, 1);
1706 	} else {
1707 		rtw89_write_rf(rtwdev, rf_path, reg->addr, 0xfffff, reg->data);
1708 		rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path,
1709 					     (struct rtw89_fw_h2c_rf_reg_info *)extra_data);
1710 	}
1711 }
1712 
rtw89_phy_config_rf_reg_v1(struct rtw89_dev * rtwdev,const struct rtw89_reg2_def * reg,enum rtw89_rf_path rf_path,void * extra_data)1713 void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
1714 				const struct rtw89_reg2_def *reg,
1715 				enum rtw89_rf_path rf_path,
1716 				void *extra_data)
1717 {
1718 	if (reg->addr == 0xfe) {
1719 		rtw89_io_mdelay(rtwdev, 50);
1720 		return;
1721 	}
1722 
1723 	rtw89_write_rf(rtwdev, rf_path, reg->addr, RFREG_MASK, reg->data);
1724 
1725 	if (reg->addr < 0x100)
1726 		return;
1727 
1728 	rtw89_phy_cofig_rf_reg_store(rtwdev, reg, rf_path,
1729 				     (struct rtw89_fw_h2c_rf_reg_info *)extra_data);
1730 }
1731 EXPORT_SYMBOL(rtw89_phy_config_rf_reg_v1);
1732 
rtw89_phy_sel_headline(struct rtw89_dev * rtwdev,const struct rtw89_phy_table * table,u32 * headline_size,u32 * headline_idx,u8 rfe,u8 cv)1733 static int rtw89_phy_sel_headline(struct rtw89_dev *rtwdev,
1734 				  const struct rtw89_phy_table *table,
1735 				  u32 *headline_size, u32 *headline_idx,
1736 				  u8 rfe, u8 cv)
1737 {
1738 	const struct rtw89_reg2_def *reg;
1739 	u32 headline;
1740 	u32 compare, target;
1741 	u8 rfe_para, cv_para;
1742 	u8 cv_max = 0;
1743 	bool case_matched = false;
1744 	u32 i;
1745 
1746 	for (i = 0; i < table->n_regs; i++) {
1747 		reg = &table->regs[i];
1748 		headline = get_phy_headline(reg->addr);
1749 		if (headline != PHY_HEADLINE_VALID)
1750 			break;
1751 	}
1752 	*headline_size = i;
1753 	if (*headline_size == 0)
1754 		return 0;
1755 
1756 	/* case 1: RFE match, CV match */
1757 	compare = get_phy_compare(rfe, cv);
1758 	for (i = 0; i < *headline_size; i++) {
1759 		reg = &table->regs[i];
1760 		target = get_phy_target(reg->addr);
1761 		if (target == compare) {
1762 			*headline_idx = i;
1763 			return 0;
1764 		}
1765 	}
1766 
1767 	/* case 2: RFE match, CV don't care */
1768 	compare = get_phy_compare(rfe, PHY_COND_DONT_CARE);
1769 	for (i = 0; i < *headline_size; i++) {
1770 		reg = &table->regs[i];
1771 		target = get_phy_target(reg->addr);
1772 		if (target == compare) {
1773 			*headline_idx = i;
1774 			return 0;
1775 		}
1776 	}
1777 
1778 	/* case 3: RFE match, CV max in table */
1779 	for (i = 0; i < *headline_size; i++) {
1780 		reg = &table->regs[i];
1781 		rfe_para = get_phy_cond_rfe(reg->addr);
1782 		cv_para = get_phy_cond_cv(reg->addr);
1783 		if (rfe_para == rfe) {
1784 			if (cv_para >= cv_max) {
1785 				cv_max = cv_para;
1786 				*headline_idx = i;
1787 				case_matched = true;
1788 			}
1789 		}
1790 	}
1791 
1792 	if (case_matched)
1793 		return 0;
1794 
1795 	/* case 4: RFE don't care, CV max in table */
1796 	for (i = 0; i < *headline_size; i++) {
1797 		reg = &table->regs[i];
1798 		rfe_para = get_phy_cond_rfe(reg->addr);
1799 		cv_para = get_phy_cond_cv(reg->addr);
1800 		if (rfe_para == PHY_COND_DONT_CARE) {
1801 			if (cv_para >= cv_max) {
1802 				cv_max = cv_para;
1803 				*headline_idx = i;
1804 				case_matched = true;
1805 			}
1806 		}
1807 	}
1808 
1809 	if (case_matched)
1810 		return 0;
1811 
1812 	return -EINVAL;
1813 }
1814 
rtw89_phy_init_reg(struct rtw89_dev * rtwdev,const struct rtw89_phy_table * table,bool by_acv,void (* config)(struct rtw89_dev * rtwdev,const struct rtw89_reg2_def * reg,enum rtw89_rf_path rf_path,void * data),void * extra_data)1815 static void rtw89_phy_init_reg(struct rtw89_dev *rtwdev,
1816 			       const struct rtw89_phy_table *table, bool by_acv,
1817 			       void (*config)(struct rtw89_dev *rtwdev,
1818 					      const struct rtw89_reg2_def *reg,
1819 					      enum rtw89_rf_path rf_path,
1820 					      void *data),
1821 			       void *extra_data)
1822 {
1823 	const struct rtw89_reg2_def *reg;
1824 	enum rtw89_rf_path rf_path = table->rf_path;
1825 	u8 cv = by_acv ? rtwdev->hal.acv : rtwdev->hal.cv;
1826 	u8 rfe = rtwdev->efuse.rfe_type;
1827 	u32 i;
1828 	u32 headline_size = 0, headline_idx = 0;
1829 	u32 target = 0, cfg_target;
1830 	u8 cond;
1831 	bool is_matched = true;
1832 	bool target_found = false;
1833 	int ret;
1834 
1835 	ret = rtw89_phy_sel_headline(rtwdev, table, &headline_size,
1836 				     &headline_idx, rfe, cv);
1837 	if (ret) {
1838 		rtw89_err(rtwdev, "invalid PHY package: %d/%d\n", rfe, cv);
1839 		return;
1840 	}
1841 
1842 	cfg_target = get_phy_target(table->regs[headline_idx].addr);
1843 	for (i = headline_size; i < table->n_regs; i++) {
1844 		reg = &table->regs[i];
1845 		cond = get_phy_cond(reg->addr);
1846 		switch (cond) {
1847 		case PHY_COND_BRANCH_IF:
1848 		case PHY_COND_BRANCH_ELIF:
1849 			target = get_phy_target(reg->addr);
1850 			break;
1851 		case PHY_COND_BRANCH_ELSE:
1852 			is_matched = false;
1853 			if (!target_found) {
1854 				rtw89_warn(rtwdev, "failed to load CR %x/%x\n",
1855 					   reg->addr, reg->data);
1856 				return;
1857 			}
1858 			break;
1859 		case PHY_COND_BRANCH_END:
1860 			is_matched = true;
1861 			target_found = false;
1862 			break;
1863 		case PHY_COND_CHECK:
1864 			if (target_found) {
1865 				is_matched = false;
1866 				break;
1867 			}
1868 
1869 			if (target == cfg_target) {
1870 				is_matched = true;
1871 				target_found = true;
1872 			} else {
1873 				is_matched = false;
1874 				target_found = false;
1875 			}
1876 			break;
1877 		default:
1878 			if (is_matched)
1879 				config(rtwdev, reg, rf_path, extra_data);
1880 			break;
1881 		}
1882 	}
1883 }
1884 
rtw89_phy_init_bb_reg(struct rtw89_dev * rtwdev)1885 void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev)
1886 {
1887 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1888 	const struct rtw89_chip_info *chip = rtwdev->chip;
1889 	const struct rtw89_phy_table *bb_table;
1890 	const struct rtw89_phy_table *bb_gain_table;
1891 
1892 	bb_table = elm_info->bb_tbl ? elm_info->bb_tbl : chip->bb_table;
1893 
1894 	rtw89_io_pack(rtwdev);
1895 
1896 	rtw89_phy_init_reg(rtwdev, bb_table, false, rtw89_phy_config_bb_reg, NULL);
1897 	if (rtwdev->dbcc_en)
1898 		rtw89_phy_init_reg(rtwdev, bb_table, false, rtw89_phy_config_bb_reg,
1899 				   (void *)RTW89_PHY_1);
1900 
1901 	rtw89_io_unpack(rtwdev);
1902 
1903 	rtw89_chip_init_txpwr_unit(rtwdev);
1904 
1905 	bb_gain_table = elm_info->bb_gain ? elm_info->bb_gain : chip->bb_gain_table;
1906 	if (bb_gain_table)
1907 		rtw89_phy_init_reg(rtwdev, bb_gain_table, false,
1908 				   chip->phy_def->config_bb_gain, NULL);
1909 
1910 	rtw89_phy_bb_reset(rtwdev);
1911 }
1912 
rtw89_phy_init_bb_afe(struct rtw89_dev * rtwdev)1913 void rtw89_phy_init_bb_afe(struct rtw89_dev *rtwdev)
1914 {
1915 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
1916 	const struct rtw89_fw_element_hdr *afe_elm = elm_info->afe;
1917 	const struct rtw89_phy_afe_info *info;
1918 	u32 action, cat, class;
1919 	u32 addr, mask, val;
1920 	u32 poll, rpt;
1921 	u32 n, i;
1922 
1923 	if (!afe_elm)
1924 		return;
1925 
1926 	n = le32_to_cpu(afe_elm->size) / sizeof(*info);
1927 
1928 	for (i = 0; i < n; i++) {
1929 		info = &afe_elm->u.afe.infos[i];
1930 
1931 		class = le32_to_cpu(info->class);
1932 		switch (class) {
1933 		case RTW89_FW_AFE_CLASS_P0:
1934 		case RTW89_FW_AFE_CLASS_P1:
1935 		case RTW89_FW_AFE_CLASS_CMN:
1936 			/* Currently support two paths */
1937 			break;
1938 		case RTW89_FW_AFE_CLASS_P2:
1939 		case RTW89_FW_AFE_CLASS_P3:
1940 		case RTW89_FW_AFE_CLASS_P4:
1941 		default:
1942 			rtw89_warn(rtwdev, "unexpected AFE class %u\n", class);
1943 			continue;
1944 		}
1945 
1946 		addr = le32_to_cpu(info->addr);
1947 		mask = le32_to_cpu(info->mask);
1948 		val = le32_to_cpu(info->val);
1949 		cat = le32_to_cpu(info->cat);
1950 		action = le32_to_cpu(info->action);
1951 
1952 		switch (action) {
1953 		case RTW89_FW_AFE_ACTION_WRITE:
1954 			switch (cat) {
1955 			case RTW89_FW_AFE_CAT_MAC:
1956 			case RTW89_FW_AFE_CAT_MAC1:
1957 				rtw89_write32_mask(rtwdev, addr, mask, val);
1958 				break;
1959 			case RTW89_FW_AFE_CAT_AFEDIG:
1960 			case RTW89_FW_AFE_CAT_AFEDIG1:
1961 				rtw89_write32_mask(rtwdev, addr, mask, val);
1962 				break;
1963 			case RTW89_FW_AFE_CAT_BB:
1964 				rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_0);
1965 				break;
1966 			case RTW89_FW_AFE_CAT_BB1:
1967 				rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_1);
1968 				break;
1969 			default:
1970 				rtw89_warn(rtwdev,
1971 					   "unexpected AFE writing action %u\n", action);
1972 				break;
1973 			}
1974 			break;
1975 		case RTW89_FW_AFE_ACTION_POLL:
1976 			for (poll = 0; poll <= 10; poll++) {
1977 				/*
1978 				 * For CAT_BB, AFE reads register with mcu_offset 0,
1979 				 * so both CAT_MAC and CAT_BB use the same method.
1980 				 */
1981 				rpt = rtw89_read32_mask(rtwdev, addr, mask);
1982 				if (rpt == val)
1983 					goto poll_done;
1984 
1985 				fsleep(1);
1986 			}
1987 			rtw89_warn(rtwdev, "failed to poll AFE cat=%u addr=0x%x mask=0x%x\n",
1988 				   cat, addr, mask);
1989 poll_done:
1990 			break;
1991 		case RTW89_FW_AFE_ACTION_DELAY:
1992 			fsleep(addr);
1993 			break;
1994 		}
1995 	}
1996 }
1997 
rtw89_phy_nctl_poll(struct rtw89_dev * rtwdev)1998 static u32 rtw89_phy_nctl_poll(struct rtw89_dev *rtwdev)
1999 {
2000 	rtw89_phy_write32(rtwdev, 0x8080, 0x4);
2001 	udelay(1);
2002 	return rtw89_phy_read32(rtwdev, 0x8080);
2003 }
2004 
rtw89_phy_init_rf_reg(struct rtw89_dev * rtwdev,bool noio)2005 void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio)
2006 {
2007 	void (*config)(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg,
2008 		       enum rtw89_rf_path rf_path, void *data);
2009 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
2010 	const struct rtw89_chip_info *chip = rtwdev->chip;
2011 	const struct rtw89_phy_table *rf_table;
2012 	struct rtw89_fw_h2c_rf_reg_info *rf_reg_info;
2013 	bool by_acv = chip->chip_id == RTL8922D;
2014 	u8 path;
2015 
2016 	rf_reg_info = kzalloc_obj(*rf_reg_info);
2017 	if (!rf_reg_info)
2018 		return;
2019 
2020 	for (path = RF_PATH_A; path < chip->rf_path_num; path++) {
2021 		rf_table = elm_info->rf_radio[path] ?
2022 			   elm_info->rf_radio[path] : chip->rf_table[path];
2023 		rf_reg_info->rf_path = rf_table->rf_path;
2024 		if (noio)
2025 			config = rtw89_phy_config_rf_reg_noio;
2026 		else
2027 			config = rf_table->config ? rf_table->config :
2028 				 rtw89_phy_config_rf_reg;
2029 
2030 		rtw89_io_pack(rtwdev);
2031 		rtw89_phy_init_reg(rtwdev, rf_table, by_acv, config, (void *)rf_reg_info);
2032 		rtw89_io_unpack(rtwdev);
2033 
2034 		if (rtw89_phy_config_rf_reg_fw(rtwdev, rf_reg_info))
2035 			rtw89_warn(rtwdev, "rf path %d reg h2c config failed\n",
2036 				   rf_reg_info->rf_path);
2037 	}
2038 	kfree(rf_reg_info);
2039 }
2040 
rtw89_phy_preinit_rf_nctl_ax(struct rtw89_dev * rtwdev)2041 static void rtw89_phy_preinit_rf_nctl_ax(struct rtw89_dev *rtwdev)
2042 {
2043 	const struct rtw89_chip_info *chip = rtwdev->chip;
2044 	u32 val;
2045 	int ret;
2046 
2047 	/* IQK/DPK clock & reset */
2048 	rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x3);
2049 	rtw89_phy_write32_set(rtwdev, R_GNT_BT_WGT_EN, 0x1);
2050 	rtw89_phy_write32_set(rtwdev, R_P0_PATH_RST, 0x8000000);
2051 	if (chip->chip_id != RTL8851B)
2052 		rtw89_phy_write32_set(rtwdev, R_P1_PATH_RST, 0x8000000);
2053 	if (chip->chip_id == RTL8852B || chip->chip_id == RTL8852BT)
2054 		rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, 0x2);
2055 
2056 	/* check 0x8080 */
2057 	rtw89_phy_write32(rtwdev, R_NCTL_CFG, 0x8);
2058 
2059 	ret = read_poll_timeout(rtw89_phy_nctl_poll, val, val == 0x4, 10,
2060 				1000, false, rtwdev);
2061 	if (ret)
2062 		rtw89_err(rtwdev, "failed to poll nctl block\n");
2063 }
2064 
rtw89_phy_init_rf_nctl(struct rtw89_dev * rtwdev)2065 static void rtw89_phy_init_rf_nctl(struct rtw89_dev *rtwdev)
2066 {
2067 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
2068 	const struct rtw89_chip_info *chip = rtwdev->chip;
2069 	const struct rtw89_phy_table *nctl_table;
2070 
2071 	rtw89_phy_preinit_rf_nctl(rtwdev);
2072 
2073 	nctl_table = elm_info->rf_nctl ? elm_info->rf_nctl : chip->nctl_table;
2074 	rtw89_phy_init_reg(rtwdev, nctl_table, false, rtw89_phy_config_bb_reg, NULL);
2075 
2076 	if (chip->nctl_post_table)
2077 		rtw89_rfk_parser(rtwdev, chip->nctl_post_table);
2078 }
2079 
rtw89_phy0_phy1_offset_ax(struct rtw89_dev * rtwdev,u32 addr)2080 static u32 rtw89_phy0_phy1_offset_ax(struct rtw89_dev *rtwdev, u32 addr)
2081 {
2082 	u32 phy_page = addr >> 8;
2083 	u32 ofst = 0;
2084 
2085 	switch (phy_page) {
2086 	case 0x6:
2087 	case 0x7:
2088 	case 0x8:
2089 	case 0x9:
2090 	case 0xa:
2091 	case 0xb:
2092 	case 0xc:
2093 	case 0xd:
2094 	case 0x19:
2095 	case 0x1a:
2096 	case 0x1b:
2097 		ofst = 0x2000;
2098 		break;
2099 	default:
2100 		/* warning case */
2101 		ofst = 0;
2102 		break;
2103 	}
2104 
2105 	if (phy_page >= 0x40 && phy_page <= 0x4f)
2106 		ofst = 0x2000;
2107 
2108 	return ofst;
2109 }
2110 
rtw89_phy_write32_idx(struct rtw89_dev * rtwdev,u32 addr,u32 mask,u32 data,enum rtw89_phy_idx phy_idx)2111 void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
2112 			   u32 data, enum rtw89_phy_idx phy_idx)
2113 {
2114 	if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
2115 		addr += rtw89_phy0_phy1_offset(rtwdev, addr);
2116 	rtw89_phy_write32_mask(rtwdev, addr, mask, data);
2117 }
2118 EXPORT_SYMBOL(rtw89_phy_write32_idx);
2119 
rtw89_phy_write32_idx_set(struct rtw89_dev * rtwdev,u32 addr,u32 bits,enum rtw89_phy_idx phy_idx)2120 void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
2121 			       enum rtw89_phy_idx phy_idx)
2122 {
2123 	if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
2124 		addr += rtw89_phy0_phy1_offset(rtwdev, addr);
2125 	rtw89_phy_write32_set(rtwdev, addr, bits);
2126 }
2127 EXPORT_SYMBOL(rtw89_phy_write32_idx_set);
2128 
rtw89_phy_write32_idx_clr(struct rtw89_dev * rtwdev,u32 addr,u32 bits,enum rtw89_phy_idx phy_idx)2129 void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
2130 			       enum rtw89_phy_idx phy_idx)
2131 {
2132 	if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
2133 		addr += rtw89_phy0_phy1_offset(rtwdev, addr);
2134 	rtw89_phy_write32_clr(rtwdev, addr, bits);
2135 }
2136 EXPORT_SYMBOL(rtw89_phy_write32_idx_clr);
2137 
rtw89_phy_read32_idx(struct rtw89_dev * rtwdev,u32 addr,u32 mask,enum rtw89_phy_idx phy_idx)2138 u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
2139 			 enum rtw89_phy_idx phy_idx)
2140 {
2141 	if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
2142 		addr += rtw89_phy0_phy1_offset(rtwdev, addr);
2143 	return rtw89_phy_read32_mask(rtwdev, addr, mask);
2144 }
2145 EXPORT_SYMBOL(rtw89_phy_read32_idx);
2146 
rtw89_phy_set_phy_regs(struct rtw89_dev * rtwdev,u32 addr,u32 mask,u32 val)2147 void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
2148 			    u32 val)
2149 {
2150 	rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_0);
2151 
2152 	if (!rtwdev->dbcc_en)
2153 		return;
2154 
2155 	rtw89_phy_write32_idx(rtwdev, addr, mask, val, RTW89_PHY_1);
2156 }
2157 EXPORT_SYMBOL(rtw89_phy_set_phy_regs);
2158 
rtw89_phy_write_reg3_tbl(struct rtw89_dev * rtwdev,const struct rtw89_phy_reg3_tbl * tbl)2159 void rtw89_phy_write_reg3_tbl(struct rtw89_dev *rtwdev,
2160 			      const struct rtw89_phy_reg3_tbl *tbl)
2161 {
2162 	const struct rtw89_reg3_def *reg3;
2163 	int i;
2164 
2165 	for (i = 0; i < tbl->size; i++) {
2166 		reg3 = &tbl->reg3[i];
2167 		rtw89_phy_write32_mask(rtwdev, reg3->addr, reg3->mask, reg3->data);
2168 	}
2169 }
2170 EXPORT_SYMBOL(rtw89_phy_write_reg3_tbl);
2171 
rtw89_phy_ant_gain_domain_to_regd(struct rtw89_dev * rtwdev,u8 ant_gain_regd)2172 static u8 rtw89_phy_ant_gain_domain_to_regd(struct rtw89_dev *rtwdev, u8 ant_gain_regd)
2173 {
2174 	switch (ant_gain_regd) {
2175 	case RTW89_ANT_GAIN_ETSI:
2176 		return RTW89_ETSI;
2177 	default:
2178 		rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
2179 			    "unknown antenna gain domain: %d\n",
2180 			    ant_gain_regd);
2181 		return RTW89_REGD_NUM;
2182 	}
2183 }
2184 
2185 /* antenna gain in unit of 0.25 dbm */
2186 #define RTW89_ANT_GAIN_2GHZ_MIN -8
2187 #define RTW89_ANT_GAIN_2GHZ_MAX 14
2188 #define RTW89_ANT_GAIN_5GHZ_MIN -8
2189 #define RTW89_ANT_GAIN_5GHZ_MAX 20
2190 #define RTW89_ANT_GAIN_6GHZ_MIN -8
2191 #define RTW89_ANT_GAIN_6GHZ_MAX 20
2192 
2193 #define RTW89_ANT_GAIN_REF_2GHZ 14
2194 #define RTW89_ANT_GAIN_REF_5GHZ 20
2195 #define RTW89_ANT_GAIN_REF_6GHZ 20
2196 
rtw89_phy_ant_gain_init(struct rtw89_dev * rtwdev)2197 void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev)
2198 {
2199 	struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
2200 	const struct rtw89_chip_info *chip = rtwdev->chip;
2201 	struct rtw89_acpi_rtag_result res = {};
2202 	u32 domain;
2203 	int ret;
2204 	u8 i, j;
2205 	u8 regd;
2206 	u8 val;
2207 
2208 	if (!chip->support_ant_gain)
2209 		return;
2210 
2211 	ret = rtw89_acpi_evaluate_rtag(rtwdev, &res);
2212 	if (ret) {
2213 		rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
2214 			    "acpi: cannot eval rtag: %d\n", ret);
2215 		return;
2216 	}
2217 
2218 	if (res.revision != 0) {
2219 		rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
2220 			    "unknown rtag revision: %d\n", res.revision);
2221 		return;
2222 	}
2223 
2224 	domain = get_unaligned_le32(&res.domain);
2225 
2226 	for (i = 0; i < RTW89_ANT_GAIN_DOMAIN_NUM; i++) {
2227 		if (!(domain & BIT(i)))
2228 			continue;
2229 
2230 		regd = rtw89_phy_ant_gain_domain_to_regd(rtwdev, i);
2231 		if (regd >= RTW89_REGD_NUM)
2232 			continue;
2233 		ant_gain->regd_enabled |= BIT(regd);
2234 	}
2235 
2236 	for (i = 0; i < RTW89_ANT_GAIN_CHAIN_NUM; i++) {
2237 		for (j = 0; j < RTW89_ANT_GAIN_SUBBAND_NR; j++) {
2238 			val = res.ant_gain_table[i][j];
2239 			switch (j) {
2240 			default:
2241 			case RTW89_ANT_GAIN_2GHZ_SUBBAND:
2242 				val = RTW89_ANT_GAIN_REF_2GHZ -
2243 				      clamp_t(s8, val,
2244 					      RTW89_ANT_GAIN_2GHZ_MIN,
2245 					      RTW89_ANT_GAIN_2GHZ_MAX);
2246 				break;
2247 			case RTW89_ANT_GAIN_5GHZ_SUBBAND_1:
2248 			case RTW89_ANT_GAIN_5GHZ_SUBBAND_2:
2249 			case RTW89_ANT_GAIN_5GHZ_SUBBAND_2E:
2250 			case RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4:
2251 				val = RTW89_ANT_GAIN_REF_5GHZ -
2252 				      clamp_t(s8, val,
2253 					      RTW89_ANT_GAIN_5GHZ_MIN,
2254 					      RTW89_ANT_GAIN_5GHZ_MAX);
2255 				break;
2256 			case RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L:
2257 			case RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H:
2258 			case RTW89_ANT_GAIN_6GHZ_SUBBAND_6:
2259 			case RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L:
2260 			case RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H:
2261 			case RTW89_ANT_GAIN_6GHZ_SUBBAND_8:
2262 				val = RTW89_ANT_GAIN_REF_6GHZ -
2263 				      clamp_t(s8, val,
2264 					      RTW89_ANT_GAIN_6GHZ_MIN,
2265 					      RTW89_ANT_GAIN_6GHZ_MAX);
2266 			}
2267 			ant_gain->offset[i][j] = val;
2268 		}
2269 	}
2270 }
2271 
2272 static
rtw89_phy_ant_gain_get_subband(struct rtw89_dev * rtwdev,u32 center_freq)2273 enum rtw89_ant_gain_subband rtw89_phy_ant_gain_get_subband(struct rtw89_dev *rtwdev,
2274 							   u32 center_freq)
2275 {
2276 	switch (center_freq) {
2277 	default:
2278 		rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
2279 			    "center freq: %u to antenna gain subband is unhandled\n",
2280 			    center_freq);
2281 		fallthrough;
2282 	case 2412 ... 2484:
2283 		return RTW89_ANT_GAIN_2GHZ_SUBBAND;
2284 	case 5180 ... 5240:
2285 		return RTW89_ANT_GAIN_5GHZ_SUBBAND_1;
2286 	case 5250 ... 5320:
2287 		return RTW89_ANT_GAIN_5GHZ_SUBBAND_2;
2288 	case 5500 ... 5720:
2289 		return RTW89_ANT_GAIN_5GHZ_SUBBAND_2E;
2290 	case 5745 ... 5885:
2291 		return RTW89_ANT_GAIN_5GHZ_SUBBAND_3_4;
2292 	case 5955 ... 6155:
2293 		return RTW89_ANT_GAIN_6GHZ_SUBBAND_5_L;
2294 	case 6175 ... 6415:
2295 		return RTW89_ANT_GAIN_6GHZ_SUBBAND_5_H;
2296 	case 6435 ... 6515:
2297 		return RTW89_ANT_GAIN_6GHZ_SUBBAND_6;
2298 	case 6535 ... 6695:
2299 		return RTW89_ANT_GAIN_6GHZ_SUBBAND_7_L;
2300 	case 6715 ... 6855:
2301 		return RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H;
2302 
2303 	/* freq 6875 (ch 185, 20MHz) spans RTW89_ANT_GAIN_6GHZ_SUBBAND_7_H
2304 	 * and RTW89_ANT_GAIN_6GHZ_SUBBAND_8, so directly describe it with
2305 	 * struct rtw89_6ghz_span.
2306 	 */
2307 
2308 	case 6895 ... 7115:
2309 		return RTW89_ANT_GAIN_6GHZ_SUBBAND_8;
2310 	}
2311 }
2312 
rtw89_phy_ant_gain_query(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,u32 center_freq)2313 static s8 rtw89_phy_ant_gain_query(struct rtw89_dev *rtwdev,
2314 				   enum rtw89_rf_path path, u32 center_freq)
2315 {
2316 	struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
2317 	enum rtw89_ant_gain_subband subband_l, subband_h;
2318 	const struct rtw89_6ghz_span *span;
2319 
2320 	span = rtw89_get_6ghz_span(rtwdev, center_freq);
2321 
2322 	if (span && RTW89_ANT_GAIN_SPAN_VALID(span)) {
2323 		subband_l = span->ant_gain_subband_low;
2324 		subband_h = span->ant_gain_subband_high;
2325 	} else {
2326 		subband_l = rtw89_phy_ant_gain_get_subband(rtwdev, center_freq);
2327 		subband_h = subband_l;
2328 	}
2329 
2330 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
2331 		    "center_freq %u: antenna gain subband {%u, %u}\n",
2332 		    center_freq, subband_l, subband_h);
2333 
2334 	return min(ant_gain->offset[path][subband_l],
2335 		   ant_gain->offset[path][subband_h]);
2336 }
2337 
rtw89_phy_ant_gain_offset(struct rtw89_dev * rtwdev,u32 center_freq)2338 static s8 rtw89_phy_ant_gain_offset(struct rtw89_dev *rtwdev, u32 center_freq)
2339 {
2340 	s8 offset_patha, offset_pathb;
2341 
2342 	offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, center_freq);
2343 	offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, center_freq);
2344 
2345 	if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw))
2346 		return min(offset_patha, offset_pathb);
2347 
2348 	return max(offset_patha, offset_pathb);
2349 }
2350 
rtw89_can_apply_ant_gain(struct rtw89_dev * rtwdev,u8 band)2351 static bool rtw89_can_apply_ant_gain(struct rtw89_dev *rtwdev, u8 band)
2352 {
2353 	const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
2354 	struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain;
2355 	const struct rtw89_chip_info *chip = rtwdev->chip;
2356 	u8 regd = rtw89_regd_get(rtwdev, band);
2357 
2358 	if (!chip->support_ant_gain)
2359 		return false;
2360 
2361 	if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd)))
2362 		return false;
2363 
2364 	if (!rfe_parms->has_da)
2365 		return false;
2366 
2367 	return true;
2368 }
2369 
rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan)2370 s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev,
2371 				  const struct rtw89_chan *chan)
2372 {
2373 	s8 offset_patha, offset_pathb;
2374 
2375 	if (!rtw89_can_apply_ant_gain(rtwdev, chan->band_type))
2376 		return 0;
2377 
2378 	if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw))
2379 		return 0;
2380 
2381 	offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq);
2382 	offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq);
2383 
2384 	return rtw89_phy_txpwr_rf_to_bb(rtwdev, offset_patha - offset_pathb);
2385 }
2386 EXPORT_SYMBOL(rtw89_phy_ant_gain_pwr_offset);
2387 
rtw89_print_ant_gain(struct rtw89_dev * rtwdev,char * buf,size_t bufsz,const struct rtw89_chan * chan)2388 int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
2389 			 const struct rtw89_chan *chan)
2390 {
2391 	char *p = buf, *end = buf + bufsz;
2392 	s8 offset_patha, offset_pathb;
2393 
2394 	if (!rtw89_can_apply_ant_gain(rtwdev, chan->band_type)) {
2395 		p += scnprintf(p, end - p, "no DAG is applied\n");
2396 		goto out;
2397 	}
2398 
2399 	offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq);
2400 	offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq);
2401 
2402 	p += scnprintf(p, end - p, "ChainA offset: %d dBm\n", offset_patha);
2403 	p += scnprintf(p, end - p, "ChainB offset: %d dBm\n", offset_pathb);
2404 
2405 out:
2406 	return p - buf;
2407 }
2408 
2409 static const u8 rtw89_rs_idx_num_ax[] = {
2410 	[RTW89_RS_CCK] = RTW89_RATE_CCK_NUM,
2411 	[RTW89_RS_OFDM] = RTW89_RATE_OFDM_NUM,
2412 	[RTW89_RS_MCS] = RTW89_RATE_MCS_NUM_AX,
2413 	[RTW89_RS_HEDCM] = RTW89_RATE_HEDCM_NUM,
2414 	[RTW89_RS_OFFSET] = RTW89_RATE_OFFSET_NUM_AX,
2415 };
2416 
2417 static const u8 rtw89_rs_nss_num_ax[] = {
2418 	[RTW89_RS_CCK] = 1,
2419 	[RTW89_RS_OFDM] = 1,
2420 	[RTW89_RS_MCS] = RTW89_NSS_NUM,
2421 	[RTW89_RS_HEDCM] = RTW89_NSS_HEDCM_NUM,
2422 	[RTW89_RS_OFFSET] = 1,
2423 };
2424 
rtw89_phy_raw_byr_seek(struct rtw89_dev * rtwdev,struct rtw89_txpwr_byrate * head,const struct rtw89_rate_desc * desc)2425 s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev,
2426 			   struct rtw89_txpwr_byrate *head,
2427 			   const struct rtw89_rate_desc *desc)
2428 {
2429 	switch (desc->rs) {
2430 	case RTW89_RS_CCK:
2431 		return &head->cck[desc->idx];
2432 	case RTW89_RS_OFDM:
2433 		return &head->ofdm[desc->idx];
2434 	case RTW89_RS_MCS:
2435 		return &head->mcs[desc->ofdma][desc->nss][desc->idx];
2436 	case RTW89_RS_HEDCM:
2437 		return &head->hedcm[desc->ofdma][desc->nss][desc->idx];
2438 	case RTW89_RS_OFFSET:
2439 		return &head->offset[desc->idx];
2440 	default:
2441 		rtw89_warn(rtwdev, "unrecognized byr rs: %d\n", desc->rs);
2442 		return &head->trap;
2443 	}
2444 }
2445 
rtw89_phy_load_txpwr_byrate(struct rtw89_dev * rtwdev,const struct rtw89_txpwr_table * tbl)2446 void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
2447 				 const struct rtw89_txpwr_table *tbl)
2448 {
2449 	const struct rtw89_txpwr_byrate_cfg *cfg = tbl->data;
2450 	const struct rtw89_txpwr_byrate_cfg *end = cfg + tbl->size;
2451 	struct rtw89_txpwr_byrate *byr_head;
2452 	struct rtw89_rate_desc desc = {};
2453 	s8 *byr;
2454 	u32 data;
2455 	u8 i;
2456 
2457 	for (; cfg < end; cfg++) {
2458 		byr_head = &rtwdev->byr[cfg->band][0];
2459 		desc.rs = cfg->rs;
2460 		desc.nss = cfg->nss;
2461 		data = cfg->data;
2462 
2463 		for (i = 0; i < cfg->len; i++, data >>= 8) {
2464 			desc.idx = cfg->shf + i;
2465 			byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, &desc);
2466 			*byr = data & 0xff;
2467 		}
2468 	}
2469 }
2470 EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate);
2471 
rtw89_phy_txpwr_dbm_without_tolerance(s8 dbm)2472 static s8 rtw89_phy_txpwr_dbm_without_tolerance(s8 dbm)
2473 {
2474 	const u8 tssi_deviation_point = 0;
2475 	const u8 tssi_max_deviation = 2;
2476 
2477 	if (dbm <= tssi_deviation_point)
2478 		dbm -= tssi_max_deviation;
2479 
2480 	return dbm;
2481 }
2482 
rtw89_phy_get_tpe_constraint(struct rtw89_dev * rtwdev,u8 band)2483 static s8 rtw89_phy_get_tpe_constraint(struct rtw89_dev *rtwdev, u8 band)
2484 {
2485 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
2486 	const struct rtw89_reg_6ghz_tpe *tpe = &regulatory->reg_6ghz_tpe;
2487 	s8 cstr = S8_MAX;
2488 
2489 	if (band == RTW89_BAND_6G && tpe->valid)
2490 		cstr = rtw89_phy_txpwr_dbm_without_tolerance(tpe->constraint);
2491 
2492 	return rtw89_phy_txpwr_dbm_to_mac(rtwdev, cstr);
2493 }
2494 
rtw89_phy_read_txpwr_byrate(struct rtw89_dev * rtwdev,u8 band,u8 bw,const struct rtw89_rate_desc * rate_desc)2495 s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw,
2496 			       const struct rtw89_rate_desc *rate_desc)
2497 {
2498 	struct rtw89_txpwr_byrate *byr_head;
2499 	s8 *byr;
2500 
2501 	if (rate_desc->rs == RTW89_RS_CCK)
2502 		band = RTW89_BAND_2G;
2503 
2504 	byr_head = &rtwdev->byr[band][bw];
2505 	byr = rtw89_phy_raw_byr_seek(rtwdev, byr_head, rate_desc);
2506 
2507 	return rtw89_phy_txpwr_rf_to_mac(rtwdev, *byr);
2508 }
2509 
rtw89_channel_6g_to_idx(struct rtw89_dev * rtwdev,u8 channel_6g)2510 static u8 rtw89_channel_6g_to_idx(struct rtw89_dev *rtwdev, u8 channel_6g)
2511 {
2512 	switch (channel_6g) {
2513 	case 1 ... 29:
2514 		return (channel_6g - 1) / 2;
2515 	case 33 ... 61:
2516 		return (channel_6g - 3) / 2;
2517 	case 65 ... 93:
2518 		return (channel_6g - 5) / 2;
2519 	case 97 ... 125:
2520 		return (channel_6g - 7) / 2;
2521 	case 129 ... 157:
2522 		return (channel_6g - 9) / 2;
2523 	case 161 ... 189:
2524 		return (channel_6g - 11) / 2;
2525 	case 193 ... 221:
2526 		return (channel_6g - 13) / 2;
2527 	case 225 ... 253:
2528 		return (channel_6g - 15) / 2;
2529 	default:
2530 		rtw89_warn(rtwdev, "unknown 6g channel: %d\n", channel_6g);
2531 		return 0;
2532 	}
2533 }
2534 
rtw89_channel_to_idx(struct rtw89_dev * rtwdev,u8 band,u8 channel)2535 static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 band, u8 channel)
2536 {
2537 	if (band == RTW89_BAND_6G)
2538 		return rtw89_channel_6g_to_idx(rtwdev, channel);
2539 
2540 	switch (channel) {
2541 	case 1 ... 14:
2542 		return channel - 1;
2543 	case 36 ... 64:
2544 		return (channel - 36) / 2;
2545 	case 100 ... 144:
2546 		return ((channel - 100) / 2) + 15;
2547 	case 149 ... 177:
2548 		return ((channel - 149) / 2) + 38;
2549 	default:
2550 		rtw89_warn(rtwdev, "unknown channel: %d\n", channel);
2551 		return 0;
2552 	}
2553 }
2554 
rtw89_phy_validate_txpwr_limit_bw(struct rtw89_dev * rtwdev,u8 band,u8 bw)2555 static bool rtw89_phy_validate_txpwr_limit_bw(struct rtw89_dev *rtwdev,
2556 					      u8 band, u8 bw)
2557 {
2558 	switch (band) {
2559 	case RTW89_BAND_2G:
2560 		return bw < RTW89_2G_BW_NUM;
2561 	case RTW89_BAND_5G:
2562 		return bw < RTW89_5G_BW_NUM;
2563 	case RTW89_BAND_6G:
2564 		return bw < RTW89_6G_BW_NUM;
2565 	default:
2566 		return false;
2567 	}
2568 }
2569 
rtw89_phy_read_txpwr_limit(struct rtw89_dev * rtwdev,u8 band,u8 bw,u8 ntx,u8 rs,u8 bf,u8 ch)2570 s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
2571 			      u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch)
2572 {
2573 	const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
2574 	const struct rtw89_txpwr_rule_2ghz *rule_da_2ghz = &rfe_parms->rule_da_2ghz;
2575 	const struct rtw89_txpwr_rule_5ghz *rule_da_5ghz = &rfe_parms->rule_da_5ghz;
2576 	const struct rtw89_txpwr_rule_6ghz *rule_da_6ghz = &rfe_parms->rule_da_6ghz;
2577 	const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz;
2578 	const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz;
2579 	const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz;
2580 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
2581 	enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
2582 	bool has_ant_gain = rtw89_can_apply_ant_gain(rtwdev, band);
2583 	u32 freq = ieee80211_channel_to_frequency(ch, nl_band);
2584 	u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
2585 	s8 lmt = 0, da_lmt = S8_MAX, sar, offset = 0;
2586 	u8 regd = rtw89_regd_get(rtwdev, band);
2587 	u8 reg6 = regulatory->reg_6ghz_power;
2588 	struct rtw89_sar_parm sar_parm = {
2589 		.center_freq = freq,
2590 		.ntx = ntx,
2591 	};
2592 	s8 cstr;
2593 
2594 	if (!rtw89_phy_validate_txpwr_limit_bw(rtwdev, band, bw)) {
2595 		rtw89_warn(rtwdev, "invalid band %u bandwidth %u\n", band, bw);
2596 		return 0;
2597 	}
2598 
2599 	switch (band) {
2600 	case RTW89_BAND_2G:
2601 		if (has_ant_gain)
2602 			da_lmt = (*rule_da_2ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
2603 
2604 		lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
2605 		if (lmt)
2606 			break;
2607 
2608 		lmt = (*rule_2ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx];
2609 		break;
2610 	case RTW89_BAND_5G:
2611 		if (has_ant_gain)
2612 			da_lmt = (*rule_da_5ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
2613 
2614 		lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][regd][ch_idx];
2615 		if (lmt)
2616 			break;
2617 
2618 		lmt = (*rule_5ghz->lmt)[bw][ntx][rs][bf][RTW89_WW][ch_idx];
2619 		break;
2620 	case RTW89_BAND_6G:
2621 		if (has_ant_gain)
2622 			da_lmt = (*rule_da_6ghz->lmt)[bw][ntx][rs][bf][regd][reg6][ch_idx];
2623 
2624 		lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][regd][reg6][ch_idx];
2625 		if (lmt)
2626 			break;
2627 
2628 		lmt = (*rule_6ghz->lmt)[bw][ntx][rs][bf][RTW89_WW]
2629 				       [RTW89_REG_6GHZ_POWER_DFLT]
2630 				       [ch_idx];
2631 		break;
2632 	default:
2633 		rtw89_warn(rtwdev, "unknown band type: %d\n", band);
2634 		return 0;
2635 	}
2636 
2637 	da_lmt = da_lmt ?: S8_MAX;
2638 	if (da_lmt != S8_MAX)
2639 		offset = rtw89_phy_ant_gain_offset(rtwdev, freq);
2640 
2641 	lmt = rtw89_phy_txpwr_rf_to_mac(rtwdev, min(lmt + offset, da_lmt));
2642 	sar = rtw89_query_sar(rtwdev, &sar_parm);
2643 	cstr = rtw89_phy_get_tpe_constraint(rtwdev, band);
2644 
2645 	return min3(lmt, sar, cstr);
2646 }
2647 EXPORT_SYMBOL(rtw89_phy_read_txpwr_limit);
2648 
2649 #define __fill_txpwr_limit_nonbf_bf(ptr, band, bw, ntx, rs, ch)		\
2650 	do {								\
2651 		u8 __i;							\
2652 		for (__i = 0; __i < RTW89_BF_NUM; __i++)		\
2653 			ptr[__i] = rtw89_phy_read_txpwr_limit(rtwdev,	\
2654 							      band,	\
2655 							      bw, ntx,	\
2656 							      rs, __i,	\
2657 							      (ch));	\
2658 	} while (0)
2659 
rtw89_phy_fill_txpwr_limit_20m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ax * lmt,u8 band,u8 ntx,u8 ch)2660 static void rtw89_phy_fill_txpwr_limit_20m_ax(struct rtw89_dev *rtwdev,
2661 					      struct rtw89_txpwr_limit_ax *lmt,
2662 					      u8 band, u8 ntx, u8 ch)
2663 {
2664 	__fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20,
2665 				    ntx, RTW89_RS_CCK, ch);
2666 	__fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40,
2667 				    ntx, RTW89_RS_CCK, ch);
2668 	__fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
2669 				    ntx, RTW89_RS_OFDM, ch);
2670 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
2671 				    RTW89_CHANNEL_WIDTH_20,
2672 				    ntx, RTW89_RS_MCS, ch);
2673 }
2674 
rtw89_phy_fill_txpwr_limit_40m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ax * lmt,u8 band,u8 ntx,u8 ch,u8 pri_ch)2675 static void rtw89_phy_fill_txpwr_limit_40m_ax(struct rtw89_dev *rtwdev,
2676 					      struct rtw89_txpwr_limit_ax *lmt,
2677 					      u8 band, u8 ntx, u8 ch, u8 pri_ch)
2678 {
2679 	__fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20,
2680 				    ntx, RTW89_RS_CCK, ch - 2);
2681 	__fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40,
2682 				    ntx, RTW89_RS_CCK, ch);
2683 	__fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
2684 				    ntx, RTW89_RS_OFDM, pri_ch);
2685 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
2686 				    RTW89_CHANNEL_WIDTH_20,
2687 				    ntx, RTW89_RS_MCS, ch - 2);
2688 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band,
2689 				    RTW89_CHANNEL_WIDTH_20,
2690 				    ntx, RTW89_RS_MCS, ch + 2);
2691 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band,
2692 				    RTW89_CHANNEL_WIDTH_40,
2693 				    ntx, RTW89_RS_MCS, ch);
2694 }
2695 
rtw89_phy_fill_txpwr_limit_80m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ax * lmt,u8 band,u8 ntx,u8 ch,u8 pri_ch)2696 static void rtw89_phy_fill_txpwr_limit_80m_ax(struct rtw89_dev *rtwdev,
2697 					      struct rtw89_txpwr_limit_ax *lmt,
2698 					      u8 band, u8 ntx, u8 ch, u8 pri_ch)
2699 {
2700 	s8 val_0p5_n[RTW89_BF_NUM];
2701 	s8 val_0p5_p[RTW89_BF_NUM];
2702 	u8 i;
2703 
2704 	__fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
2705 				    ntx, RTW89_RS_OFDM, pri_ch);
2706 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
2707 				    RTW89_CHANNEL_WIDTH_20,
2708 				    ntx, RTW89_RS_MCS, ch - 6);
2709 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band,
2710 				    RTW89_CHANNEL_WIDTH_20,
2711 				    ntx, RTW89_RS_MCS, ch - 2);
2712 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band,
2713 				    RTW89_CHANNEL_WIDTH_20,
2714 				    ntx, RTW89_RS_MCS, ch + 2);
2715 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band,
2716 				    RTW89_CHANNEL_WIDTH_20,
2717 				    ntx, RTW89_RS_MCS, ch + 6);
2718 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band,
2719 				    RTW89_CHANNEL_WIDTH_40,
2720 				    ntx, RTW89_RS_MCS, ch - 4);
2721 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band,
2722 				    RTW89_CHANNEL_WIDTH_40,
2723 				    ntx, RTW89_RS_MCS, ch + 4);
2724 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band,
2725 				    RTW89_CHANNEL_WIDTH_80,
2726 				    ntx, RTW89_RS_MCS, ch);
2727 
2728 	__fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40,
2729 				    ntx, RTW89_RS_MCS, ch - 4);
2730 	__fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40,
2731 				    ntx, RTW89_RS_MCS, ch + 4);
2732 
2733 	for (i = 0; i < RTW89_BF_NUM; i++)
2734 		lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]);
2735 }
2736 
rtw89_phy_fill_txpwr_limit_160m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ax * lmt,u8 band,u8 ntx,u8 ch,u8 pri_ch)2737 static void rtw89_phy_fill_txpwr_limit_160m_ax(struct rtw89_dev *rtwdev,
2738 					       struct rtw89_txpwr_limit_ax *lmt,
2739 					       u8 band, u8 ntx, u8 ch, u8 pri_ch)
2740 {
2741 	s8 val_0p5_n[RTW89_BF_NUM];
2742 	s8 val_0p5_p[RTW89_BF_NUM];
2743 	s8 val_2p5_n[RTW89_BF_NUM];
2744 	s8 val_2p5_p[RTW89_BF_NUM];
2745 	u8 i;
2746 
2747 	/* fill ofdm section */
2748 	__fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20,
2749 				    ntx, RTW89_RS_OFDM, pri_ch);
2750 
2751 	/* fill mcs 20m section */
2752 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band,
2753 				    RTW89_CHANNEL_WIDTH_20,
2754 				    ntx, RTW89_RS_MCS, ch - 14);
2755 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band,
2756 				    RTW89_CHANNEL_WIDTH_20,
2757 				    ntx, RTW89_RS_MCS, ch - 10);
2758 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band,
2759 				    RTW89_CHANNEL_WIDTH_20,
2760 				    ntx, RTW89_RS_MCS, ch - 6);
2761 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band,
2762 				    RTW89_CHANNEL_WIDTH_20,
2763 				    ntx, RTW89_RS_MCS, ch - 2);
2764 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[4], band,
2765 				    RTW89_CHANNEL_WIDTH_20,
2766 				    ntx, RTW89_RS_MCS, ch + 2);
2767 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[5], band,
2768 				    RTW89_CHANNEL_WIDTH_20,
2769 				    ntx, RTW89_RS_MCS, ch + 6);
2770 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[6], band,
2771 				    RTW89_CHANNEL_WIDTH_20,
2772 				    ntx, RTW89_RS_MCS, ch + 10);
2773 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[7], band,
2774 				    RTW89_CHANNEL_WIDTH_20,
2775 				    ntx, RTW89_RS_MCS, ch + 14);
2776 
2777 	/* fill mcs 40m section */
2778 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band,
2779 				    RTW89_CHANNEL_WIDTH_40,
2780 				    ntx, RTW89_RS_MCS, ch - 12);
2781 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band,
2782 				    RTW89_CHANNEL_WIDTH_40,
2783 				    ntx, RTW89_RS_MCS, ch - 4);
2784 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[2], band,
2785 				    RTW89_CHANNEL_WIDTH_40,
2786 				    ntx, RTW89_RS_MCS, ch + 4);
2787 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[3], band,
2788 				    RTW89_CHANNEL_WIDTH_40,
2789 				    ntx, RTW89_RS_MCS, ch + 12);
2790 
2791 	/* fill mcs 80m section */
2792 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band,
2793 				    RTW89_CHANNEL_WIDTH_80,
2794 				    ntx, RTW89_RS_MCS, ch - 8);
2795 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[1], band,
2796 				    RTW89_CHANNEL_WIDTH_80,
2797 				    ntx, RTW89_RS_MCS, ch + 8);
2798 
2799 	/* fill mcs 160m section */
2800 	__fill_txpwr_limit_nonbf_bf(lmt->mcs_160m, band,
2801 				    RTW89_CHANNEL_WIDTH_160,
2802 				    ntx, RTW89_RS_MCS, ch);
2803 
2804 	/* fill mcs 40m 0p5 section */
2805 	__fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40,
2806 				    ntx, RTW89_RS_MCS, ch - 4);
2807 	__fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40,
2808 				    ntx, RTW89_RS_MCS, ch + 4);
2809 
2810 	for (i = 0; i < RTW89_BF_NUM; i++)
2811 		lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]);
2812 
2813 	/* fill mcs 40m 2p5 section */
2814 	__fill_txpwr_limit_nonbf_bf(val_2p5_n, band, RTW89_CHANNEL_WIDTH_40,
2815 				    ntx, RTW89_RS_MCS, ch - 8);
2816 	__fill_txpwr_limit_nonbf_bf(val_2p5_p, band, RTW89_CHANNEL_WIDTH_40,
2817 				    ntx, RTW89_RS_MCS, ch + 8);
2818 
2819 	for (i = 0; i < RTW89_BF_NUM; i++)
2820 		lmt->mcs_40m_2p5[i] = min_t(s8, val_2p5_n[i], val_2p5_p[i]);
2821 }
2822 
2823 static
rtw89_phy_fill_txpwr_limit_ax(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,struct rtw89_txpwr_limit_ax * lmt,u8 ntx)2824 void rtw89_phy_fill_txpwr_limit_ax(struct rtw89_dev *rtwdev,
2825 				   const struct rtw89_chan *chan,
2826 				   struct rtw89_txpwr_limit_ax *lmt,
2827 				   u8 ntx)
2828 {
2829 	u8 band = chan->band_type;
2830 	u8 pri_ch = chan->primary_channel;
2831 	u8 ch = chan->channel;
2832 	u8 bw = chan->band_width;
2833 
2834 	memset(lmt, 0, sizeof(*lmt));
2835 
2836 	switch (bw) {
2837 	case RTW89_CHANNEL_WIDTH_20:
2838 		rtw89_phy_fill_txpwr_limit_20m_ax(rtwdev, lmt, band, ntx, ch);
2839 		break;
2840 	case RTW89_CHANNEL_WIDTH_40:
2841 		rtw89_phy_fill_txpwr_limit_40m_ax(rtwdev, lmt, band, ntx, ch,
2842 						  pri_ch);
2843 		break;
2844 	case RTW89_CHANNEL_WIDTH_80:
2845 		rtw89_phy_fill_txpwr_limit_80m_ax(rtwdev, lmt, band, ntx, ch,
2846 						  pri_ch);
2847 		break;
2848 	case RTW89_CHANNEL_WIDTH_160:
2849 		rtw89_phy_fill_txpwr_limit_160m_ax(rtwdev, lmt, band, ntx, ch,
2850 						   pri_ch);
2851 		break;
2852 	}
2853 }
2854 
rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev * rtwdev,u8 band,u8 ru,u8 ntx,u8 ch)2855 s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band,
2856 				 u8 ru, u8 ntx, u8 ch)
2857 {
2858 	const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
2859 	const struct rtw89_txpwr_rule_2ghz *rule_da_2ghz = &rfe_parms->rule_da_2ghz;
2860 	const struct rtw89_txpwr_rule_5ghz *rule_da_5ghz = &rfe_parms->rule_da_5ghz;
2861 	const struct rtw89_txpwr_rule_6ghz *rule_da_6ghz = &rfe_parms->rule_da_6ghz;
2862 	const struct rtw89_txpwr_rule_2ghz *rule_2ghz = &rfe_parms->rule_2ghz;
2863 	const struct rtw89_txpwr_rule_5ghz *rule_5ghz = &rfe_parms->rule_5ghz;
2864 	const struct rtw89_txpwr_rule_6ghz *rule_6ghz = &rfe_parms->rule_6ghz;
2865 	struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
2866 	enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
2867 	bool has_ant_gain = rtw89_can_apply_ant_gain(rtwdev, band);
2868 	u32 freq = ieee80211_channel_to_frequency(ch, nl_band);
2869 	u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
2870 	s8 lmt_ru = 0, da_lmt_ru = S8_MAX, sar, offset = 0;
2871 	u8 regd = rtw89_regd_get(rtwdev, band);
2872 	u8 reg6 = regulatory->reg_6ghz_power;
2873 	struct rtw89_sar_parm sar_parm = {
2874 		.center_freq = freq,
2875 		.ntx = ntx,
2876 	};
2877 	s8 cstr;
2878 
2879 	switch (band) {
2880 	case RTW89_BAND_2G:
2881 		if (has_ant_gain)
2882 			da_lmt_ru = (*rule_da_2ghz->lmt_ru)[ru][ntx][regd][ch_idx];
2883 
2884 		lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][regd][ch_idx];
2885 		if (lmt_ru)
2886 			break;
2887 
2888 		lmt_ru = (*rule_2ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx];
2889 		break;
2890 	case RTW89_BAND_5G:
2891 		if (has_ant_gain)
2892 			da_lmt_ru = (*rule_da_5ghz->lmt_ru)[ru][ntx][regd][ch_idx];
2893 
2894 		lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][regd][ch_idx];
2895 		if (lmt_ru)
2896 			break;
2897 
2898 		lmt_ru = (*rule_5ghz->lmt_ru)[ru][ntx][RTW89_WW][ch_idx];
2899 		break;
2900 	case RTW89_BAND_6G:
2901 		if (has_ant_gain)
2902 			da_lmt_ru = (*rule_da_6ghz->lmt_ru)[ru][ntx][regd][reg6][ch_idx];
2903 
2904 		lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][regd][reg6][ch_idx];
2905 		if (lmt_ru)
2906 			break;
2907 
2908 		lmt_ru = (*rule_6ghz->lmt_ru)[ru][ntx][RTW89_WW]
2909 					     [RTW89_REG_6GHZ_POWER_DFLT]
2910 					     [ch_idx];
2911 		break;
2912 	default:
2913 		rtw89_warn(rtwdev, "unknown band type: %d\n", band);
2914 		return 0;
2915 	}
2916 
2917 	da_lmt_ru = da_lmt_ru ?: S8_MAX;
2918 	if (da_lmt_ru != S8_MAX)
2919 		offset = rtw89_phy_ant_gain_offset(rtwdev, freq);
2920 
2921 	lmt_ru = rtw89_phy_txpwr_rf_to_mac(rtwdev, min(lmt_ru + offset, da_lmt_ru));
2922 	sar = rtw89_query_sar(rtwdev, &sar_parm);
2923 	cstr = rtw89_phy_get_tpe_constraint(rtwdev, band);
2924 
2925 	return min3(lmt_ru, sar, cstr);
2926 }
2927 
2928 static void
rtw89_phy_fill_txpwr_limit_ru_20m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ru_ax * lmt_ru,u8 band,u8 ntx,u8 ch)2929 rtw89_phy_fill_txpwr_limit_ru_20m_ax(struct rtw89_dev *rtwdev,
2930 				     struct rtw89_txpwr_limit_ru_ax *lmt_ru,
2931 				     u8 band, u8 ntx, u8 ch)
2932 {
2933 	lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2934 							RTW89_RU26,
2935 							ntx, ch);
2936 	lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2937 							RTW89_RU52,
2938 							ntx, ch);
2939 	lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2940 							 RTW89_RU106,
2941 							 ntx, ch);
2942 }
2943 
2944 static void
rtw89_phy_fill_txpwr_limit_ru_40m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ru_ax * lmt_ru,u8 band,u8 ntx,u8 ch)2945 rtw89_phy_fill_txpwr_limit_ru_40m_ax(struct rtw89_dev *rtwdev,
2946 				     struct rtw89_txpwr_limit_ru_ax *lmt_ru,
2947 				     u8 band, u8 ntx, u8 ch)
2948 {
2949 	lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2950 							RTW89_RU26,
2951 							ntx, ch - 2);
2952 	lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2953 							RTW89_RU26,
2954 							ntx, ch + 2);
2955 	lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2956 							RTW89_RU52,
2957 							ntx, ch - 2);
2958 	lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2959 							RTW89_RU52,
2960 							ntx, ch + 2);
2961 	lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2962 							 RTW89_RU106,
2963 							 ntx, ch - 2);
2964 	lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2965 							 RTW89_RU106,
2966 							 ntx, ch + 2);
2967 }
2968 
2969 static void
rtw89_phy_fill_txpwr_limit_ru_80m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ru_ax * lmt_ru,u8 band,u8 ntx,u8 ch)2970 rtw89_phy_fill_txpwr_limit_ru_80m_ax(struct rtw89_dev *rtwdev,
2971 				     struct rtw89_txpwr_limit_ru_ax *lmt_ru,
2972 				     u8 band, u8 ntx, u8 ch)
2973 {
2974 	lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2975 							RTW89_RU26,
2976 							ntx, ch - 6);
2977 	lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2978 							RTW89_RU26,
2979 							ntx, ch - 2);
2980 	lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2981 							RTW89_RU26,
2982 							ntx, ch + 2);
2983 	lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2984 							RTW89_RU26,
2985 							ntx, ch + 6);
2986 	lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2987 							RTW89_RU52,
2988 							ntx, ch - 6);
2989 	lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2990 							RTW89_RU52,
2991 							ntx, ch - 2);
2992 	lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2993 							RTW89_RU52,
2994 							ntx, ch + 2);
2995 	lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2996 							RTW89_RU52,
2997 							ntx, ch + 6);
2998 	lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
2999 							 RTW89_RU106,
3000 							 ntx, ch - 6);
3001 	lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
3002 							 RTW89_RU106,
3003 							 ntx, ch - 2);
3004 	lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
3005 							 RTW89_RU106,
3006 							 ntx, ch + 2);
3007 	lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
3008 							 RTW89_RU106,
3009 							 ntx, ch + 6);
3010 }
3011 
3012 static void
rtw89_phy_fill_txpwr_limit_ru_160m_ax(struct rtw89_dev * rtwdev,struct rtw89_txpwr_limit_ru_ax * lmt_ru,u8 band,u8 ntx,u8 ch)3013 rtw89_phy_fill_txpwr_limit_ru_160m_ax(struct rtw89_dev *rtwdev,
3014 				      struct rtw89_txpwr_limit_ru_ax *lmt_ru,
3015 				      u8 band, u8 ntx, u8 ch)
3016 {
3017 	static const int ofst[] = { -14, -10, -6, -2, 2, 6, 10, 14 };
3018 	int i;
3019 
3020 	static_assert(ARRAY_SIZE(ofst) == RTW89_RU_SEC_NUM_AX);
3021 	for (i = 0; i < RTW89_RU_SEC_NUM_AX; i++) {
3022 		lmt_ru->ru26[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
3023 								RTW89_RU26,
3024 								ntx,
3025 								ch + ofst[i]);
3026 		lmt_ru->ru52[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
3027 								RTW89_RU52,
3028 								ntx,
3029 								ch + ofst[i]);
3030 		lmt_ru->ru106[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band,
3031 								 RTW89_RU106,
3032 								 ntx,
3033 								 ch + ofst[i]);
3034 	}
3035 }
3036 
3037 static
rtw89_phy_fill_txpwr_limit_ru_ax(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,struct rtw89_txpwr_limit_ru_ax * lmt_ru,u8 ntx)3038 void rtw89_phy_fill_txpwr_limit_ru_ax(struct rtw89_dev *rtwdev,
3039 				      const struct rtw89_chan *chan,
3040 				      struct rtw89_txpwr_limit_ru_ax *lmt_ru,
3041 				      u8 ntx)
3042 {
3043 	u8 band = chan->band_type;
3044 	u8 ch = chan->channel;
3045 	u8 bw = chan->band_width;
3046 
3047 	memset(lmt_ru, 0, sizeof(*lmt_ru));
3048 
3049 	switch (bw) {
3050 	case RTW89_CHANNEL_WIDTH_20:
3051 		rtw89_phy_fill_txpwr_limit_ru_20m_ax(rtwdev, lmt_ru, band, ntx,
3052 						     ch);
3053 		break;
3054 	case RTW89_CHANNEL_WIDTH_40:
3055 		rtw89_phy_fill_txpwr_limit_ru_40m_ax(rtwdev, lmt_ru, band, ntx,
3056 						     ch);
3057 		break;
3058 	case RTW89_CHANNEL_WIDTH_80:
3059 		rtw89_phy_fill_txpwr_limit_ru_80m_ax(rtwdev, lmt_ru, band, ntx,
3060 						     ch);
3061 		break;
3062 	case RTW89_CHANNEL_WIDTH_160:
3063 		rtw89_phy_fill_txpwr_limit_ru_160m_ax(rtwdev, lmt_ru, band, ntx,
3064 						      ch);
3065 		break;
3066 	}
3067 }
3068 
rtw89_phy_set_txpwr_byrate_ax(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,enum rtw89_phy_idx phy_idx)3069 static void rtw89_phy_set_txpwr_byrate_ax(struct rtw89_dev *rtwdev,
3070 					  const struct rtw89_chan *chan,
3071 					  enum rtw89_phy_idx phy_idx)
3072 {
3073 	u8 max_nss_num = rtwdev->chip->rf_path_num;
3074 	static const u8 rs[] = {
3075 		RTW89_RS_CCK,
3076 		RTW89_RS_OFDM,
3077 		RTW89_RS_MCS,
3078 		RTW89_RS_HEDCM,
3079 	};
3080 	struct rtw89_rate_desc cur = {};
3081 	u8 band = chan->band_type;
3082 	u8 ch = chan->channel;
3083 	u32 addr, val;
3084 	s8 v[4] = {};
3085 	u8 i;
3086 
3087 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
3088 		    "[TXPWR] set txpwr byrate with ch=%d\n", ch);
3089 
3090 	BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_CCK] % 4);
3091 	BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_OFDM] % 4);
3092 	BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_MCS] % 4);
3093 	BUILD_BUG_ON(rtw89_rs_idx_num_ax[RTW89_RS_HEDCM] % 4);
3094 
3095 	addr = R_AX_PWR_BY_RATE;
3096 	for (cur.nss = 0; cur.nss < max_nss_num; cur.nss++) {
3097 		for (i = 0; i < ARRAY_SIZE(rs); i++) {
3098 			if (cur.nss >= rtw89_rs_nss_num_ax[rs[i]])
3099 				continue;
3100 
3101 			cur.rs = rs[i];
3102 			for (cur.idx = 0; cur.idx < rtw89_rs_idx_num_ax[rs[i]];
3103 			     cur.idx++) {
3104 				v[cur.idx % 4] =
3105 					rtw89_phy_read_txpwr_byrate(rtwdev,
3106 								    band, 0,
3107 								    &cur);
3108 
3109 				if ((cur.idx + 1) % 4)
3110 					continue;
3111 
3112 				val = FIELD_PREP(GENMASK(7, 0), v[0]) |
3113 				      FIELD_PREP(GENMASK(15, 8), v[1]) |
3114 				      FIELD_PREP(GENMASK(23, 16), v[2]) |
3115 				      FIELD_PREP(GENMASK(31, 24), v[3]);
3116 
3117 				rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr,
3118 							val);
3119 				addr += 4;
3120 			}
3121 		}
3122 	}
3123 }
3124 
3125 static
rtw89_phy_set_txpwr_offset_ax(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,enum rtw89_phy_idx phy_idx)3126 void rtw89_phy_set_txpwr_offset_ax(struct rtw89_dev *rtwdev,
3127 				   const struct rtw89_chan *chan,
3128 				   enum rtw89_phy_idx phy_idx)
3129 {
3130 	struct rtw89_rate_desc desc = {
3131 		.nss = RTW89_NSS_1,
3132 		.rs = RTW89_RS_OFFSET,
3133 	};
3134 	u8 band = chan->band_type;
3135 	s8 v[RTW89_RATE_OFFSET_NUM_AX] = {};
3136 	u32 val;
3137 
3138 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[TXPWR] set txpwr offset\n");
3139 
3140 	for (desc.idx = 0; desc.idx < RTW89_RATE_OFFSET_NUM_AX; desc.idx++)
3141 		v[desc.idx] = rtw89_phy_read_txpwr_byrate(rtwdev, band, 0, &desc);
3142 
3143 	BUILD_BUG_ON(RTW89_RATE_OFFSET_NUM_AX != 5);
3144 	val = FIELD_PREP(GENMASK(3, 0), v[0]) |
3145 	      FIELD_PREP(GENMASK(7, 4), v[1]) |
3146 	      FIELD_PREP(GENMASK(11, 8), v[2]) |
3147 	      FIELD_PREP(GENMASK(15, 12), v[3]) |
3148 	      FIELD_PREP(GENMASK(19, 16), v[4]);
3149 
3150 	rtw89_mac_txpwr_write32_mask(rtwdev, phy_idx, R_AX_PWR_RATE_OFST_CTRL,
3151 				     GENMASK(19, 0), val);
3152 }
3153 
rtw89_phy_set_txpwr_limit_ax(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,enum rtw89_phy_idx phy_idx)3154 static void rtw89_phy_set_txpwr_limit_ax(struct rtw89_dev *rtwdev,
3155 					 const struct rtw89_chan *chan,
3156 					 enum rtw89_phy_idx phy_idx)
3157 {
3158 	u8 max_ntx_num = rtwdev->chip->rf_path_num;
3159 	struct rtw89_txpwr_limit_ax lmt;
3160 	u8 ch = chan->channel;
3161 	u8 bw = chan->band_width;
3162 	const s8 *ptr;
3163 	u32 addr, val;
3164 	u8 i, j;
3165 
3166 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
3167 		    "[TXPWR] set txpwr limit with ch=%d bw=%d\n", ch, bw);
3168 
3169 	BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit_ax) !=
3170 		     RTW89_TXPWR_LMT_PAGE_SIZE_AX);
3171 
3172 	addr = R_AX_PWR_LMT;
3173 	for (i = 0; i < max_ntx_num; i++) {
3174 		rtw89_phy_fill_txpwr_limit_ax(rtwdev, chan, &lmt, i);
3175 
3176 		ptr = (s8 *)&lmt;
3177 		for (j = 0; j < RTW89_TXPWR_LMT_PAGE_SIZE_AX;
3178 		     j += 4, addr += 4, ptr += 4) {
3179 			val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
3180 			      FIELD_PREP(GENMASK(15, 8), ptr[1]) |
3181 			      FIELD_PREP(GENMASK(23, 16), ptr[2]) |
3182 			      FIELD_PREP(GENMASK(31, 24), ptr[3]);
3183 
3184 			rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
3185 		}
3186 	}
3187 }
3188 
rtw89_phy_set_txpwr_limit_ru_ax(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,enum rtw89_phy_idx phy_idx)3189 static void rtw89_phy_set_txpwr_limit_ru_ax(struct rtw89_dev *rtwdev,
3190 					    const struct rtw89_chan *chan,
3191 					    enum rtw89_phy_idx phy_idx)
3192 {
3193 	u8 max_ntx_num = rtwdev->chip->rf_path_num;
3194 	struct rtw89_txpwr_limit_ru_ax lmt_ru;
3195 	u8 ch = chan->channel;
3196 	u8 bw = chan->band_width;
3197 	const s8 *ptr;
3198 	u32 addr, val;
3199 	u8 i, j;
3200 
3201 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR,
3202 		    "[TXPWR] set txpwr limit ru with ch=%d bw=%d\n", ch, bw);
3203 
3204 	BUILD_BUG_ON(sizeof(struct rtw89_txpwr_limit_ru_ax) !=
3205 		     RTW89_TXPWR_LMT_RU_PAGE_SIZE_AX);
3206 
3207 	addr = R_AX_PWR_RU_LMT;
3208 	for (i = 0; i < max_ntx_num; i++) {
3209 		rtw89_phy_fill_txpwr_limit_ru_ax(rtwdev, chan, &lmt_ru, i);
3210 
3211 		ptr = (s8 *)&lmt_ru;
3212 		for (j = 0; j < RTW89_TXPWR_LMT_RU_PAGE_SIZE_AX;
3213 		     j += 4, addr += 4, ptr += 4) {
3214 			val = FIELD_PREP(GENMASK(7, 0), ptr[0]) |
3215 			      FIELD_PREP(GENMASK(15, 8), ptr[1]) |
3216 			      FIELD_PREP(GENMASK(23, 16), ptr[2]) |
3217 			      FIELD_PREP(GENMASK(31, 24), ptr[3]);
3218 
3219 			rtw89_mac_txpwr_write32(rtwdev, phy_idx, addr, val);
3220 		}
3221 	}
3222 }
3223 
3224 struct rtw89_phy_iter_ra_data {
3225 	struct rtw89_dev *rtwdev;
3226 	struct sk_buff *c2h;
3227 };
3228 
__rtw89_phy_c2h_ra_rpt_iter(struct rtw89_sta_link * rtwsta_link,struct ieee80211_link_sta * link_sta,struct rtw89_phy_iter_ra_data * ra_data,bool * changed)3229 static void __rtw89_phy_c2h_ra_rpt_iter(struct rtw89_sta_link *rtwsta_link,
3230 					struct ieee80211_link_sta *link_sta,
3231 					struct rtw89_phy_iter_ra_data *ra_data,
3232 					bool *changed)
3233 {
3234 	struct rtw89_dev *rtwdev = ra_data->rtwdev;
3235 	const struct rtw89_c2h_ra_rpt *c2h =
3236 		(const struct rtw89_c2h_ra_rpt *)ra_data->c2h->data;
3237 	struct rtw89_ra_report *ra_report = &rtwsta_link->ra_report;
3238 	const struct rtw89_chip_info *chip = rtwdev->chip;
3239 	bool format_v1 = chip->chip_gen == RTW89_CHIP_BE;
3240 	u8 mode, rate, bw, giltf, mac_id;
3241 	u16 legacy_bitrate, amsdu_len;
3242 	u8 retry_ratio = 0;
3243 	bool valid;
3244 	u8 mcs = 0;
3245 	u8 t;
3246 
3247 	mac_id = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MACID);
3248 	if (mac_id != rtwsta_link->mac_id)
3249 		return;
3250 
3251 	rate = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MCSNSS);
3252 	bw = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_BW);
3253 	giltf = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_GILTF);
3254 	mode = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MD_SEL);
3255 
3256 	if (format_v1) {
3257 		t = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_MCSNSS_B7);
3258 		rate |= u8_encode_bits(t, BIT(7));
3259 		t = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_BW_B2);
3260 		bw |= u8_encode_bits(t, BIT(2));
3261 		t = le32_get_bits(c2h->w3, RTW89_C2H_RA_RPT_W3_MD_SEL_B2);
3262 		mode |= u8_encode_bits(t, BIT(2));
3263 		retry_ratio = le32_get_bits(c2h->w2, RTW89_C2H_RA_RPT_W2_RETRY_RATIO);
3264 	}
3265 
3266 	if (mode == RTW89_RA_RPT_MODE_LEGACY) {
3267 		valid = rtw89_legacy_rate_to_bitrate(rtwdev, rate, &legacy_bitrate);
3268 		if (!valid)
3269 			return;
3270 	}
3271 
3272 	memset(&ra_report->txrate, 0, sizeof(ra_report->txrate));
3273 
3274 	switch (mode) {
3275 	case RTW89_RA_RPT_MODE_LEGACY:
3276 		ra_report->txrate.legacy = legacy_bitrate;
3277 		break;
3278 	case RTW89_RA_RPT_MODE_HT:
3279 		ra_report->txrate.flags |= RATE_INFO_FLAGS_MCS;
3280 		if (RTW89_CHK_FW_FEATURE(OLD_HT_RA_FORMAT, &rtwdev->fw))
3281 			rate = RTW89_MK_HT_RATE(FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate),
3282 						FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate));
3283 		else
3284 			rate = FIELD_GET(RTW89_RA_RATE_MASK_HT_MCS, rate);
3285 		ra_report->txrate.mcs = rate;
3286 		if (giltf)
3287 			ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
3288 		mcs = ra_report->txrate.mcs & 0x07;
3289 		break;
3290 	case RTW89_RA_RPT_MODE_VHT:
3291 		ra_report->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
3292 		ra_report->txrate.mcs = format_v1 ?
3293 			u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1) :
3294 			u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS);
3295 		ra_report->txrate.nss = format_v1 ?
3296 			u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1 :
3297 			u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS) + 1;
3298 		if (giltf)
3299 			ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
3300 		mcs = ra_report->txrate.mcs;
3301 		break;
3302 	case RTW89_RA_RPT_MODE_HE:
3303 		ra_report->txrate.flags |= RATE_INFO_FLAGS_HE_MCS;
3304 		ra_report->txrate.mcs = format_v1 ?
3305 			u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1) :
3306 			u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS);
3307 		ra_report->txrate.nss  = format_v1 ?
3308 			u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1 :
3309 			u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS) + 1;
3310 		if (giltf == RTW89_GILTF_2XHE08 || giltf == RTW89_GILTF_1XHE08)
3311 			ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_0_8;
3312 		else if (giltf == RTW89_GILTF_2XHE16 || giltf == RTW89_GILTF_1XHE16)
3313 			ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_1_6;
3314 		else
3315 			ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_3_2;
3316 		mcs = ra_report->txrate.mcs;
3317 		break;
3318 	case RTW89_RA_RPT_MODE_EHT:
3319 		ra_report->txrate.flags |= RATE_INFO_FLAGS_EHT_MCS;
3320 		ra_report->txrate.mcs = u8_get_bits(rate, RTW89_RA_RATE_MASK_MCS_V1);
3321 		ra_report->txrate.nss = u8_get_bits(rate, RTW89_RA_RATE_MASK_NSS_V1) + 1;
3322 		if (giltf == RTW89_GILTF_2XHE08 || giltf == RTW89_GILTF_1XHE08)
3323 			ra_report->txrate.eht_gi = NL80211_RATE_INFO_EHT_GI_0_8;
3324 		else if (giltf == RTW89_GILTF_2XHE16 || giltf == RTW89_GILTF_1XHE16)
3325 			ra_report->txrate.eht_gi = NL80211_RATE_INFO_EHT_GI_1_6;
3326 		else
3327 			ra_report->txrate.eht_gi = NL80211_RATE_INFO_EHT_GI_3_2;
3328 		mcs = ra_report->txrate.mcs;
3329 		break;
3330 	}
3331 
3332 	ra_report->txrate.bw = rtw89_hw_to_rate_info_bw(bw);
3333 	ra_report->bit_rate = cfg80211_calculate_bitrate(&ra_report->txrate);
3334 	ra_report->hw_rate = format_v1 ?
3335 			     u16_encode_bits(mode, RTW89_HW_RATE_V1_MASK_MOD) |
3336 			     u16_encode_bits(rate, RTW89_HW_RATE_V1_MASK_VAL) :
3337 			     u16_encode_bits(mode, RTW89_HW_RATE_MASK_MOD) |
3338 			     u16_encode_bits(rate, RTW89_HW_RATE_MASK_VAL);
3339 	ra_report->retry_ratio = retry_ratio;
3340 	ra_report->might_fallback_legacy = mcs <= 2;
3341 
3342 	amsdu_len = get_max_amsdu_len(rtwdev, ra_report);
3343 	if (link_sta->agg.max_rc_amsdu_len != amsdu_len) {
3344 		link_sta->agg.max_rc_amsdu_len = amsdu_len;
3345 		*changed = true;
3346 	}
3347 
3348 	rtwsta_link->max_agg_wait = link_sta->agg.max_rc_amsdu_len / 1500 - 1;
3349 }
3350 
rtw89_phy_c2h_ra_rpt_iter(void * data,struct ieee80211_sta * sta)3351 static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
3352 {
3353 	struct rtw89_phy_iter_ra_data *ra_data = (struct rtw89_phy_iter_ra_data *)data;
3354 	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
3355 	struct rtw89_sta_link *rtwsta_link;
3356 	struct ieee80211_link_sta *link_sta;
3357 	unsigned int link_id;
3358 	bool changed = false;
3359 
3360 	rcu_read_lock();
3361 
3362 	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
3363 		link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
3364 		__rtw89_phy_c2h_ra_rpt_iter(rtwsta_link, link_sta, ra_data, &changed);
3365 	}
3366 
3367 	if (changed)
3368 		ieee80211_sta_recalc_aggregates(sta);
3369 
3370 	rcu_read_unlock();
3371 }
3372 
3373 static void
rtw89_phy_c2h_ra_rpt(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3374 rtw89_phy_c2h_ra_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3375 {
3376 	struct rtw89_phy_iter_ra_data ra_data;
3377 
3378 	ra_data.rtwdev = rtwdev;
3379 	ra_data.c2h = c2h;
3380 	ieee80211_iterate_stations_atomic(rtwdev->hw,
3381 					  rtw89_phy_c2h_ra_rpt_iter,
3382 					  &ra_data);
3383 }
3384 
3385 static void
rtw89_phy_c2h_tx_history(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3386 rtw89_phy_c2h_tx_history(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3387 {
3388 	const struct rtw89_c2h_ra_tx_history *history = (const void *)c2h->data;
3389 	u32 *tx_rate_cnt = rtwdev->phystat.tx_rate_cnt;
3390 	u32 i;
3391 
3392 	for (i = 0; i < RTW89_TX_RATE_NR; i++)
3393 		tx_rate_cnt[i] = le32_to_cpu(history->tx_rate_tot_cnt_hist[i]);
3394 }
3395 
3396 static
3397 void (* const rtw89_phy_c2h_ra_handler[])(struct rtw89_dev *rtwdev,
3398 					  struct sk_buff *c2h, u32 len) = {
3399 	[RTW89_PHY_C2H_FUNC_STS_RPT] = rtw89_phy_c2h_ra_rpt,
3400 	[RTW89_PHY_C2H_FUNC_MU_GPTBL_RPT] = NULL,
3401 	[RTW89_PHY_C2H_FUNC_TXSTS] = NULL,
3402 	[RTW89_PHY_C2H_FUNC_TX_HISTORY] = rtw89_phy_c2h_tx_history,
3403 	[RTW89_PHY_C2H_FUNC_ACCELERATE_EN] = rtw89_fw_c2h_dummy_handler,
3404 };
3405 
3406 static void
rtw89_phy_c2h_lowrt_rty(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3407 rtw89_phy_c2h_lowrt_rty(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3408 {
3409 }
3410 
3411 static void
rtw89_phy_c2h_lps_rpt(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3412 rtw89_phy_c2h_lps_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3413 {
3414 	const struct rtw89_c2h_lps_rpt *c2h_rpt = (const void *)c2h->data;
3415 	const __le32 *data_a, *data_b;
3416 	u16 len_info, cr_len, idx;
3417 	const __le16 *addr;
3418 	const u8 *info;
3419 
3420 	/* elements size of BBCR/BBMCUCR/RFCR are 6/6/10 bytes respectively */
3421 	cr_len = c2h_rpt->cnt_bbcr * 6 +
3422 		 c2h_rpt->cnt_bbmcucr * 6 +
3423 		 c2h_rpt->cnt_rfcr * 10;
3424 	len_info = len - (sizeof(*c2h_rpt) + cr_len);
3425 
3426 	if (len < sizeof(*c2h_rpt) + cr_len || len_info % 4 != 0) {
3427 		rtw89_debug(rtwdev, RTW89_DBG_PS,
3428 			    "Invalid LPS RPT len(%d) TYPE(%d) CRCNT: BB(%d) MCU(%d) RF(%d)\n",
3429 			    len, c2h_rpt->type, c2h_rpt->cnt_bbcr,
3430 			    c2h_rpt->cnt_bbmcucr, c2h_rpt->cnt_rfcr);
3431 		return;
3432 	}
3433 
3434 	rtw89_debug(rtwdev, RTW89_DBG_PS,
3435 		    "LPS RPT TYPE(%d), CRCNT: BB(%d) MCU(%d) RF(%d)\n",
3436 		    c2h_rpt->type, c2h_rpt->cnt_bbcr,
3437 		    c2h_rpt->cnt_bbmcucr, c2h_rpt->cnt_rfcr);
3438 
3439 	info = &c2h_rpt->data[0];
3440 	for (idx = 0; idx < len_info; idx += 4, info += 4)
3441 		rtw89_debug(rtwdev, RTW89_DBG_PS,
3442 			    "BB LPS INFO (%02d) - 0x%02x,0x%02x,0x%02x,0x%02x\n",
3443 			    idx, info[3], info[2], info[1], info[0]);
3444 
3445 	addr = (const void *)(info);
3446 	data_a = (const void *)(addr + c2h_rpt->cnt_bbcr);
3447 	for (idx = 0; idx < c2h_rpt->cnt_bbcr; idx++, addr++, data_a++)
3448 		rtw89_debug(rtwdev, RTW89_DBG_PS,
3449 			    "LPS BB CR - 0x%04x=0x%08x\n",
3450 			    le16_to_cpu(*addr), le32_to_cpu(*data_a));
3451 
3452 	addr = (const void *)data_a;
3453 	data_a = (const void *)(addr + c2h_rpt->cnt_bbmcucr);
3454 	for (idx = 0; idx < c2h_rpt->cnt_bbmcucr; idx++, addr++, data_a++)
3455 		rtw89_debug(rtwdev, RTW89_DBG_PS,
3456 			    "LPS BBMCU - 0x%04x=0x%08x\n",
3457 			    le16_to_cpu(*addr), le32_to_cpu(*data_a));
3458 
3459 	addr = (const void *)data_a;
3460 	data_a = (const void *)(addr + c2h_rpt->cnt_rfcr);
3461 	data_b = (const void *)(data_a + c2h_rpt->cnt_rfcr);
3462 	for (idx = 0; idx < c2h_rpt->cnt_rfcr; idx++, addr++, data_a++, data_b++)
3463 		rtw89_debug(rtwdev, RTW89_DBG_PS,
3464 			    "LPS RFCR - 0x%04x=0x%05x,0x%05x\n",
3465 			    le16_to_cpu(*addr), le32_to_cpu(*data_a),
3466 			    le32_to_cpu(*data_b));
3467 }
3468 
3469 static void
rtw89_phy_c2h_fw_scan_rpt(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3470 rtw89_phy_c2h_fw_scan_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3471 {
3472 	const struct rtw89_c2h_fw_scan_rpt *c2h_rpt =
3473 		(const struct rtw89_c2h_fw_scan_rpt *)c2h->data;
3474 
3475 	rtw89_debug(rtwdev, RTW89_DBG_DIG,
3476 		    "%s: band: %u, op_chan: %u, PD_low_bd(ofdm, cck): (-%d, %d), phy_idx: %u\n",
3477 		    __func__, c2h_rpt->band, c2h_rpt->center_ch,
3478 		    PD_LOWER_BOUND_BASE - (c2h_rpt->ofdm_pd_idx << 1),
3479 		    c2h_rpt->cck_pd_idx, c2h_rpt->phy_idx);
3480 }
3481 
3482 static
3483 void (* const rtw89_phy_c2h_dm_handler[])(struct rtw89_dev *rtwdev,
3484 					  struct sk_buff *c2h, u32 len) = {
3485 	[RTW89_PHY_C2H_DM_FUNC_FW_TEST] = NULL,
3486 	[RTW89_PHY_C2H_DM_FUNC_FW_TRIG_TX_RPT] = NULL,
3487 	[RTW89_PHY_C2H_DM_FUNC_SIGB] = NULL,
3488 	[RTW89_PHY_C2H_DM_FUNC_LOWRT_RTY] = rtw89_phy_c2h_lowrt_rty,
3489 	[RTW89_PHY_C2H_DM_FUNC_MCC_DIG] = NULL,
3490 	[RTW89_PHY_C2H_DM_FUNC_LPS] = rtw89_phy_c2h_lps_rpt,
3491 	[RTW89_PHY_C2H_DM_FUNC_ENV_MNTR] = rtw89_fw_c2h_dummy_handler,
3492 	[RTW89_PHY_C2H_DM_FUNC_FW_SCAN] = rtw89_phy_c2h_fw_scan_rpt,
3493 };
3494 
3495 static
rtw89_phy_c2h_rfk_tas_pwr(struct rtw89_dev * rtwdev,const struct rtw89_c2h_rf_tas_rpt_log * content)3496 void rtw89_phy_c2h_rfk_tas_pwr(struct rtw89_dev *rtwdev,
3497 			       const struct rtw89_c2h_rf_tas_rpt_log *content)
3498 {
3499 	const enum rtw89_sar_sources src = rtwdev->sar.src;
3500 	struct rtw89_tas_info *tas = &rtwdev->tas;
3501 	u64 linear = 0;
3502 	u32 i, cur_idx;
3503 	s16 txpwr;
3504 
3505 	if (!tas->enable || src == RTW89_SAR_SOURCE_NONE)
3506 		return;
3507 
3508 	cur_idx = le32_to_cpu(content->cur_idx);
3509 	for (i = 0; i < cur_idx; i++) {
3510 		txpwr = le16_to_cpu(content->txpwr_history[i]);
3511 		linear += rtw89_db_quarter_to_linear(txpwr);
3512 
3513 		rtw89_debug(rtwdev, RTW89_DBG_SAR,
3514 			    "tas: index: %u, txpwr: %d\n", i, txpwr);
3515 	}
3516 
3517 	if (cur_idx == 0)
3518 		tas->instant_txpwr = rtw89_db_to_linear(0);
3519 	else
3520 		tas->instant_txpwr = DIV_ROUND_DOWN_ULL(linear, cur_idx);
3521 }
3522 
rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev * rtwdev,enum rtw89_phy_c2h_rfk_log_func func,void * content,u16 len)3523 static void rtw89_phy_c2h_rfk_rpt_log(struct rtw89_dev *rtwdev,
3524 				      enum rtw89_phy_c2h_rfk_log_func func,
3525 				      void *content, u16 len)
3526 {
3527 	struct rtw89_c2h_rf_txgapk_rpt_log *txgapk;
3528 	struct rtw89_c2h_rf_rxdck_rpt_log *rxdck;
3529 	struct rtw89_c2h_rf_txiqk_rpt_log *txiqk;
3530 	struct rtw89_c2h_rf_cim3k_rpt_log *cim3k;
3531 	struct rtw89_c2h_rf_dack_rpt_log *dack;
3532 	struct rtw89_c2h_rf_tssi_rpt_log *tssi;
3533 	struct rtw89_c2h_rf_dpk_rpt_log *dpk;
3534 	struct rtw89_c2h_rf_iqk_rpt_log *iqk;
3535 	int i, j, k;
3536 
3537 	switch (func) {
3538 	case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK:
3539 		if (len != sizeof(*iqk))
3540 			goto out;
3541 
3542 		iqk = content;
3543 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3544 			    "[IQK] iqk->is_iqk_init = %x\n", iqk->is_iqk_init);
3545 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3546 			    "[IQK] iqk->is_reload = %x\n", iqk->is_reload);
3547 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3548 			    "[IQK] iqk->is_nbiqk = %x\n", iqk->is_nbiqk);
3549 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3550 			    "[IQK] iqk->txiqk_en = %x\n", iqk->txiqk_en);
3551 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3552 			    "[IQK] iqk->rxiqk_en = %x\n", iqk->rxiqk_en);
3553 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3554 			    "[IQK] iqk->lok_en = %x\n", iqk->lok_en);
3555 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3556 			    "[IQK] iqk->iqk_xym_en = %x\n", iqk->iqk_xym_en);
3557 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3558 			    "[IQK] iqk->iqk_sram_en = %x\n", iqk->iqk_sram_en);
3559 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3560 			    "[IQK] iqk->iqk_fft_en = %x\n", iqk->iqk_fft_en);
3561 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3562 			    "[IQK] iqk->is_fw_iqk = %x\n", iqk->is_fw_iqk);
3563 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3564 			    "[IQK] iqk->is_iqk_enable = %x\n", iqk->is_iqk_enable);
3565 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3566 			    "[IQK] iqk->iqk_cfir_en = %x\n", iqk->iqk_cfir_en);
3567 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3568 			    "[IQK] iqk->thermal_rek_en = %x\n", iqk->thermal_rek_en);
3569 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3570 			    "[IQK] iqk->version = %x\n", iqk->version);
3571 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3572 			    "[IQK] iqk->phy = %x\n", iqk->phy);
3573 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3574 			    "[IQK] iqk->fwk_status = %x\n", iqk->fwk_status);
3575 
3576 		for (i = 0; i < 2; i++) {
3577 			rtw89_debug(rtwdev, RTW89_DBG_RFK,
3578 				    "[IQK] ======== Path %x  ========\n", i);
3579 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_band[%d] = %x\n",
3580 				    i, iqk->iqk_band[i]);
3581 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_ch[%d] = %x\n",
3582 				    i, iqk->iqk_ch[i]);
3583 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_bw[%d] = %x\n",
3584 				    i, iqk->iqk_bw[i]);
3585 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->rf_0x18[%d] = %x\n",
3586 				    i, le32_to_cpu(iqk->rf_0x18[i]));
3587 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_idac[%d] = %x\n",
3588 				    i, le32_to_cpu(iqk->lok_idac[i]));
3589 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->lok_vbuf[%d] = %x\n",
3590 				    i, le32_to_cpu(iqk->lok_vbuf[i]));
3591 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_tx_fail[%d] = %x\n",
3592 				    i, iqk->iqk_tx_fail[i]);
3593 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] iqk->iqk_rx_fail[%d] = %x\n",
3594 				    i, iqk->iqk_rx_fail[i]);
3595 			for (j = 0; j < 6; j++)
3596 				rtw89_debug(rtwdev, RTW89_DBG_RFK,
3597 					    "[IQK] iqk->rftxgain[%d][%d] = %x\n",
3598 					    i, j, le32_to_cpu(iqk->rftxgain[i][j]));
3599 			for (j = 0; j < 6; j++)
3600 				rtw89_debug(rtwdev, RTW89_DBG_RFK,
3601 					    "[IQK] iqk->tx_xym[%d][%d] = %x\n",
3602 					    i, j, le32_to_cpu(iqk->tx_xym[i][j]));
3603 			for (j = 0; j < 6; j++)
3604 				rtw89_debug(rtwdev, RTW89_DBG_RFK,
3605 					    "[IQK] iqk->rfrxgain[%d][%d] = %x\n",
3606 					    i, j, le32_to_cpu(iqk->rfrxgain[i][j]));
3607 			for (j = 0; j < 6; j++)
3608 				rtw89_debug(rtwdev, RTW89_DBG_RFK,
3609 					    "[IQK] iqk->rx_xym[%d][%d] = %x\n",
3610 					    i, j, le32_to_cpu(iqk->rx_xym[i][j]));
3611 
3612 			if (!iqk->iqk_xym_en)
3613 				continue;
3614 
3615 			for (j = 0; j < 32; j++)
3616 				rtw89_debug(rtwdev, RTW89_DBG_RFK,
3617 					    "[IQK] iqk->rx_wb_xym[%d][%d] = %x\n",
3618 					    i, j, iqk->rx_wb_xym[i][j]);
3619 		}
3620 		return;
3621 	case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
3622 		if (len != sizeof(*dpk))
3623 			goto out;
3624 
3625 		dpk = content;
3626 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3627 			    "DPK ver:%d idx:%2ph band:%2ph bw:%2ph ch:%2ph path:%2ph\n",
3628 			    dpk->ver, dpk->idx, dpk->band, dpk->bw, dpk->ch, dpk->path_ok);
3629 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3630 			    "DPK txagc:%2ph ther:%2ph gs:%2ph dc_i:%4ph dc_q:%4ph\n",
3631 			    dpk->txagc, dpk->ther, dpk->gs, dpk->dc_i, dpk->dc_q);
3632 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3633 			    "DPK corr_v:%2ph corr_i:%2ph to:%2ph ov:%2ph\n",
3634 			    dpk->corr_val, dpk->corr_idx, dpk->is_timeout, dpk->rxbb_ov);
3635 		return;
3636 	case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK:
3637 		if (len != sizeof(*dack))
3638 			goto out;
3639 
3640 		dack = content;
3641 
3642 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]FWDACK SUMMARY!!!!!\n");
3643 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3644 			    "[DACK]FWDACK ver = 0x%x, FWDACK rpt_ver = 0x%x, driver rpt_ver = 0x%x\n",
3645 			    dack->fwdack_ver, dack->fwdack_info_ver, 0x2);
3646 
3647 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3648 			    "[DACK]timeout code = [0x%x 0x%x 0x%x 0x%x 0x%x]\n",
3649 			    dack->addck_timeout, dack->cdack_timeout, dack->dadck_timeout,
3650 			    dack->adgaink_timeout, dack->msbk_timeout);
3651 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3652 			    "[DACK]DACK fail = 0x%x\n", dack->dack_fail);
3653 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3654 			    "[DACK]S0 WBADCK = [0x%x]\n", dack->wbdck_d[0]);
3655 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3656 			    "[DACK]S1 WBADCK = [0x%x]\n", dack->wbdck_d[1]);
3657 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3658 			    "[DACK]DRCK = [0x%x]\n", dack->rck_d);
3659 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK ic = [0x%x, 0x%x]\n",
3660 			    dack->cdack_d[0][0][0], dack->cdack_d[0][0][1]);
3661 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 CDACK qc = [0x%x, 0x%x]\n",
3662 			    dack->cdack_d[0][1][0], dack->cdack_d[0][1][1]);
3663 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK ic = [0x%x, 0x%x]\n",
3664 			    dack->cdack_d[1][0][0], dack->cdack_d[1][0][1]);
3665 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 CDACK qc = [0x%x, 0x%x]\n",
3666 			    dack->cdack_d[1][1][0], dack->cdack_d[1][1][1]);
3667 
3668 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = [0x%x, 0x%x]\n",
3669 			    ((u32)dack->addck2_hd[0][0][0] << 8) | dack->addck2_ld[0][0][0],
3670 			    ((u32)dack->addck2_hd[0][0][1] << 8) | dack->addck2_ld[0][0][1]);
3671 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK qc = [0x%x, 0x%x]\n",
3672 			    ((u32)dack->addck2_hd[0][1][0] << 8) | dack->addck2_ld[0][1][0],
3673 			    ((u32)dack->addck2_hd[0][1][1] << 8) | dack->addck2_ld[0][1][1]);
3674 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK ic = [0x%x, 0x%x]\n",
3675 			    ((u32)dack->addck2_hd[1][0][0] << 8) | dack->addck2_ld[1][0][0],
3676 			    ((u32)dack->addck2_hd[1][0][1] << 8) | dack->addck2_ld[1][0][1]);
3677 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_DCK qc = [0x%x, 0x%x]\n",
3678 			    ((u32)dack->addck2_hd[1][1][0] << 8) | dack->addck2_ld[1][1][0],
3679 			    ((u32)dack->addck2_hd[1][1][1] << 8) | dack->addck2_ld[1][1][1]);
3680 
3681 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
3682 			    dack->adgaink_d[0][0], dack->adgaink_d[0][1]);
3683 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADC_GAINK ic = 0x%x, qc = 0x%x\n",
3684 			    dack->adgaink_d[1][0], dack->adgaink_d[1][1]);
3685 
3686 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n",
3687 			    dack->dadck_d[0][0], dack->dadck_d[0][1]);
3688 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n",
3689 			    dack->dadck_d[1][0], dack->dadck_d[1][1]);
3690 
3691 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask iqc = 0x%x\n",
3692 			    ((u32)dack->biask_hd[0][0] << 8) | dack->biask_ld[0][0]);
3693 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 biask iqc = 0x%x\n",
3694 			    ((u32)dack->biask_hd[1][0] << 8) | dack->biask_ld[1][0]);
3695 
3696 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n");
3697 		for (i = 0; i < 0x10; i++)
3698 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
3699 				    dack->msbk_d[0][0][i]);
3700 
3701 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n");
3702 		for (i = 0; i < 0x10; i++)
3703 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
3704 				    dack->msbk_d[0][1][i]);
3705 
3706 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n");
3707 		for (i = 0; i < 0x10; i++)
3708 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
3709 				    dack->msbk_d[1][0][i]);
3710 
3711 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n");
3712 		for (i = 0; i < 0x10; i++)
3713 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n",
3714 				    dack->msbk_d[1][1][i]);
3715 		return;
3716 	case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
3717 		if (len != sizeof(*rxdck))
3718 			goto out;
3719 
3720 		rxdck = content;
3721 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3722 			    "RXDCK ver:%d band:%2ph bw:%2ph ch:%2ph to:%2ph\n",
3723 			    rxdck->ver, rxdck->band, rxdck->bw, rxdck->ch,
3724 			    rxdck->timeout);
3725 		return;
3726 	case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI:
3727 		if (len != sizeof(*tssi))
3728 			goto out;
3729 
3730 		tssi = content;
3731 		for (i = 0; i < 2; i++) {
3732 			for (j = 0; j < 2; j++) {
3733 				for (k = 0; k < 4; k++) {
3734 					rtw89_debug(rtwdev, RTW89_DBG_RFK,
3735 						    "[TSSI] alignment_power_cw_h[%d][%d][%d]=%d\n",
3736 						    i, j, k, tssi->alignment_power_cw_h[i][j][k]);
3737 					rtw89_debug(rtwdev, RTW89_DBG_RFK,
3738 						    "[TSSI] alignment_power_cw_l[%d][%d][%d]=%d\n",
3739 						    i, j, k, tssi->alignment_power_cw_l[i][j][k]);
3740 					rtw89_debug(rtwdev, RTW89_DBG_RFK,
3741 						    "[TSSI] alignment_power[%d][%d][%d]=%d\n",
3742 						    i, j, k, tssi->alignment_power[i][j][k]);
3743 					rtw89_debug(rtwdev, RTW89_DBG_RFK,
3744 						    "[TSSI] alignment_power_cw[%d][%d][%d]=%d\n",
3745 						    i, j, k,
3746 						    (tssi->alignment_power_cw_h[i][j][k] << 8) +
3747 						     tssi->alignment_power_cw_l[i][j][k]);
3748 				}
3749 
3750 				rtw89_debug(rtwdev, RTW89_DBG_RFK,
3751 					    "[TSSI] tssi_alimk_state[%d][%d]=%d\n",
3752 					    i, j, tssi->tssi_alimk_state[i][j]);
3753 				rtw89_debug(rtwdev, RTW89_DBG_RFK,
3754 					    "[TSSI] default_txagc_offset[%d]=%d\n",
3755 					    j, tssi->default_txagc_offset[0][j]);
3756 			}
3757 		}
3758 		return;
3759 	case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
3760 		if (len != sizeof(*txgapk))
3761 			goto out;
3762 
3763 		txgapk = content;
3764 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
3765 			    "[TXGAPK]rpt r0x8010[0]=0x%x, r0x8010[1]=0x%x\n",
3766 			    le32_to_cpu(txgapk->r0x8010[0]),
3767 			    le32_to_cpu(txgapk->r0x8010[1]));
3768 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_id = %d\n",
3769 			    txgapk->chk_id);
3770 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt chk_cnt = %d\n",
3771 			    le32_to_cpu(txgapk->chk_cnt));
3772 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt ver = 0x%x\n",
3773 			    txgapk->ver);
3774 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt d_bnd_ok = %d\n",
3775 			    txgapk->d_bnd_ok);
3776 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt stage[0] = 0x%x\n",
3777 			    le32_to_cpu(txgapk->stage[0]));
3778 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt stage[1] = 0x%x\n",
3779 			    le32_to_cpu(txgapk->stage[1]));
3780 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]failcode[0] = 0x%x\n",
3781 			    le16_to_cpu(txgapk->failcode[0]));
3782 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]failcode[1] = 0x%x\n",
3783 			    le16_to_cpu(txgapk->failcode[1]));
3784 
3785 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[0] = %*ph\n",
3786 			    (int)sizeof(txgapk->track_d[0]), txgapk->track_d[0]);
3787 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[0] = %*ph\n",
3788 			    (int)sizeof(txgapk->power_d[0]), txgapk->power_d[0]);
3789 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt track_d[1] = %*ph\n",
3790 			    (int)sizeof(txgapk->track_d[1]), txgapk->track_d[1]);
3791 		rtw89_debug(rtwdev, RTW89_DBG_RFK, "[TXGAPK]rpt power_d[1] = %*ph\n",
3792 			    (int)sizeof(txgapk->power_d[1]), txgapk->power_d[1]);
3793 		return;
3794 	case RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR:
3795 		if (len != sizeof(struct rtw89_c2h_rf_tas_rpt_log))
3796 			goto out;
3797 
3798 		rtw89_phy_c2h_rfk_tas_pwr(rtwdev, content);
3799 		return;
3800 	case RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK:
3801 		if (len != sizeof(*txiqk))
3802 			goto out;
3803 		return;
3804 	case RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K:
3805 		if (len != sizeof(*cim3k))
3806 			goto out;
3807 		return;
3808 	default:
3809 		break;
3810 	}
3811 
3812 out:
3813 	rtw89_debug(rtwdev, RTW89_DBG_RFK,
3814 		    "unexpected RFK func %d report log with length %d\n", func, len);
3815 }
3816 
rtw89_phy_c2h_rfk_run_log(struct rtw89_dev * rtwdev,enum rtw89_phy_c2h_rfk_log_func func,void * content,u16 len)3817 static bool rtw89_phy_c2h_rfk_run_log(struct rtw89_dev *rtwdev,
3818 				      enum rtw89_phy_c2h_rfk_log_func func,
3819 				      void *content, u16 len)
3820 {
3821 	struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
3822 	const struct rtw89_c2h_rf_run_log *log = content;
3823 	const struct rtw89_fw_element_hdr *elm;
3824 	u32 fmt_idx;
3825 	u16 offset;
3826 
3827 	if (sizeof(*log) != len)
3828 		return false;
3829 
3830 	if (!elm_info->rfk_log_fmt)
3831 		return false;
3832 
3833 	elm = elm_info->rfk_log_fmt->elm[func];
3834 	fmt_idx = le32_to_cpu(log->fmt_idx);
3835 	if (!elm || fmt_idx >= elm->u.rfk_log_fmt.nr)
3836 		return false;
3837 
3838 	offset = le16_to_cpu(elm->u.rfk_log_fmt.offset[fmt_idx]);
3839 	if (offset == 0)
3840 		return false;
3841 
3842 	rtw89_debug(rtwdev, RTW89_DBG_RFK, &elm->u.common.contents[offset],
3843 		    le32_to_cpu(log->arg[0]), le32_to_cpu(log->arg[1]),
3844 		    le32_to_cpu(log->arg[2]), le32_to_cpu(log->arg[3]));
3845 
3846 	return true;
3847 }
3848 
rtw89_phy_c2h_rfk_log(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len,enum rtw89_phy_c2h_rfk_log_func func,const char * rfk_name)3849 static void rtw89_phy_c2h_rfk_log(struct rtw89_dev *rtwdev, struct sk_buff *c2h,
3850 				  u32 len, enum rtw89_phy_c2h_rfk_log_func func,
3851 				  const char *rfk_name)
3852 {
3853 	struct rtw89_c2h_hdr *c2h_hdr = (struct rtw89_c2h_hdr *)c2h->data;
3854 	struct rtw89_c2h_rf_log_hdr *log_hdr;
3855 	void *log_ptr = c2h_hdr;
3856 	u16 content_len;
3857 	u16 chunk_len;
3858 	bool handled;
3859 
3860 	log_ptr += sizeof(*c2h_hdr);
3861 	len -= sizeof(*c2h_hdr);
3862 
3863 	while (len > sizeof(*log_hdr)) {
3864 		log_hdr = log_ptr;
3865 		content_len = le16_to_cpu(log_hdr->len);
3866 		chunk_len = content_len + sizeof(*log_hdr);
3867 
3868 		if (chunk_len > len)
3869 			break;
3870 
3871 		switch (log_hdr->type) {
3872 		case RTW89_RF_RUN_LOG:
3873 			handled = rtw89_phy_c2h_rfk_run_log(rtwdev, func,
3874 							    log_hdr->content, content_len);
3875 			if (handled)
3876 				break;
3877 
3878 			rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s run: %*ph\n",
3879 				    rfk_name, content_len, log_hdr->content);
3880 			break;
3881 		case RTW89_RF_RPT_LOG:
3882 			rtw89_phy_c2h_rfk_rpt_log(rtwdev, func,
3883 						  log_hdr->content, content_len);
3884 			break;
3885 		default:
3886 			return;
3887 		}
3888 
3889 		log_ptr += chunk_len;
3890 		len -= chunk_len;
3891 	}
3892 }
3893 
3894 static void
rtw89_phy_c2h_rfk_log_iqk(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3895 rtw89_phy_c2h_rfk_log_iqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3896 {
3897 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3898 			      RTW89_PHY_C2H_RFK_LOG_FUNC_IQK, "IQK");
3899 }
3900 
3901 static void
rtw89_phy_c2h_rfk_log_dpk(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3902 rtw89_phy_c2h_rfk_log_dpk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3903 {
3904 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3905 			      RTW89_PHY_C2H_RFK_LOG_FUNC_DPK, "DPK");
3906 }
3907 
3908 static void
rtw89_phy_c2h_rfk_log_dack(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3909 rtw89_phy_c2h_rfk_log_dack(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3910 {
3911 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3912 			      RTW89_PHY_C2H_RFK_LOG_FUNC_DACK, "DACK");
3913 }
3914 
3915 static void
rtw89_phy_c2h_rfk_log_rxdck(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3916 rtw89_phy_c2h_rfk_log_rxdck(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3917 {
3918 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3919 			      RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK, "RX_DCK");
3920 }
3921 
3922 static void
rtw89_phy_c2h_rfk_log_tssi(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3923 rtw89_phy_c2h_rfk_log_tssi(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3924 {
3925 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3926 			      RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI, "TSSI");
3927 }
3928 
3929 static void
rtw89_phy_c2h_rfk_log_txgapk(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3930 rtw89_phy_c2h_rfk_log_txgapk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3931 {
3932 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3933 			      RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK, "TXGAPK");
3934 }
3935 
3936 static void
rtw89_phy_c2h_rfk_log_tas_pwr(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3937 rtw89_phy_c2h_rfk_log_tas_pwr(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3938 {
3939 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3940 			      RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR, "TAS");
3941 }
3942 
3943 static void
rtw89_phy_c2h_rfk_log_txiqk(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3944 rtw89_phy_c2h_rfk_log_txiqk(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3945 {
3946 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3947 			      RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK, "TXIQK");
3948 }
3949 
3950 static void
rtw89_phy_c2h_rfk_log_cim3k(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)3951 rtw89_phy_c2h_rfk_log_cim3k(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
3952 {
3953 	rtw89_phy_c2h_rfk_log(rtwdev, c2h, len,
3954 			      RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K, "CIM3K");
3955 }
3956 
3957 static
3958 void (* const rtw89_phy_c2h_rfk_log_handler[])(struct rtw89_dev *rtwdev,
3959 					       struct sk_buff *c2h, u32 len) = {
3960 	[RTW89_PHY_C2H_RFK_LOG_FUNC_IQK] = rtw89_phy_c2h_rfk_log_iqk,
3961 	[RTW89_PHY_C2H_RFK_LOG_FUNC_DPK] = rtw89_phy_c2h_rfk_log_dpk,
3962 	[RTW89_PHY_C2H_RFK_LOG_FUNC_DACK] = rtw89_phy_c2h_rfk_log_dack,
3963 	[RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK] = rtw89_phy_c2h_rfk_log_rxdck,
3964 	[RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI] = rtw89_phy_c2h_rfk_log_tssi,
3965 	[RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK] = rtw89_phy_c2h_rfk_log_txgapk,
3966 	[RTW89_PHY_C2H_RFK_LOG_FUNC_TAS_PWR] = rtw89_phy_c2h_rfk_log_tas_pwr,
3967 	[RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK] = rtw89_phy_c2h_rfk_log_txiqk,
3968 	[RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K] = rtw89_phy_c2h_rfk_log_cim3k,
3969 };
3970 
3971 #define NAME_RTW89_RFK_REPORT(type) \
3972 	[RTW89_RFK_REPORT_ ## type] = #type
3973 
3974 const char * const rtw89_rfk_report_names[] = {
3975 	NAME_RTW89_RFK_REPORT(PRE_NTFY),
3976 	NAME_RTW89_RFK_REPORT(TSSI),
3977 	NAME_RTW89_RFK_REPORT(IQK),
3978 	NAME_RTW89_RFK_REPORT(DPK),
3979 	NAME_RTW89_RFK_REPORT(TXGAPK),
3980 	NAME_RTW89_RFK_REPORT(DACK),
3981 	NAME_RTW89_RFK_REPORT(RX_DCK),
3982 	NAME_RTW89_RFK_REPORT(TX_IQK),
3983 	NAME_RTW89_RFK_REPORT(CIM3k),
3984 };
3985 
3986 static_assert(ARRAY_SIZE(rtw89_rfk_report_names) == NUM_OF_RTW89_RFK_REPORT_TYPES);
3987 
3988 static
rtw89_phy_rfk_report_prep(struct rtw89_dev * rtwdev)3989 void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev)
3990 {
3991 	struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait;
3992 
3993 	wait->state = RTW89_RFK_STATE_START;
3994 	wait->start_time = ktime_get();
3995 	reinit_completion(&wait->completion);
3996 }
3997 
3998 static
____rtw89_phy_rfk_report_wait(struct rtw89_dev * rtwdev,const char * rfk_name,unsigned int ms)3999 int ____rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
4000 				  unsigned int ms)
4001 {
4002 	struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait;
4003 	unsigned long time_left;
4004 
4005 	/*
4006 	 * USB transport adds latency to H2C/C2H round-trips, so RF
4007 	 * calibrations take longer than on PCIe. Apply a 4x multiplier
4008 	 * to avoid spurious timeouts.
4009 	 */
4010 	if (rtwdev->hci.type == RTW89_HCI_TYPE_USB)
4011 		ms *= 4;
4012 
4013 	/* Since we can't receive C2H event during SER, use a fixed delay. */
4014 	if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags)) {
4015 		fsleep(1000 * ms / 2);
4016 		goto out;
4017 	}
4018 
4019 	time_left = wait_for_completion_timeout(&wait->completion,
4020 						msecs_to_jiffies(ms));
4021 	if (time_left == 0) {
4022 		rtw89_warn(rtwdev, "failed to wait RF %s\n", rfk_name);
4023 		return -ETIMEDOUT;
4024 	} else if (wait->state != RTW89_RFK_STATE_OK) {
4025 		rtw89_warn(rtwdev, "failed to do RF %s result from state %d\n",
4026 			   rfk_name, wait->state);
4027 		return -EFAULT;
4028 	}
4029 
4030 out:
4031 	rtw89_debug(rtwdev, RTW89_DBG_RFK, "RF %s takes %lld ms to complete\n",
4032 		    rfk_name, ktime_ms_delta(ktime_get(), wait->start_time));
4033 
4034 	return 0;
4035 }
4036 
4037 static
__rtw89_phy_rfk_report_wait(struct rtw89_dev * rtwdev,enum rtw89_rfk_report_types rfk_type,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,unsigned int ms)4038 int __rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev,
4039 				enum rtw89_rfk_report_types rfk_type,
4040 				enum rtw89_phy_idx phy_idx,
4041 				const struct rtw89_chan *chan,
4042 				unsigned int ms)
4043 {
4044 	const char *rfk_name = rtw89_rfk_report_names[rfk_type];
4045 	struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait;
4046 	struct rtw89_rfk_record *record = wait->record_ptr;
4047 	int ret;
4048 
4049 	ret = ____rtw89_phy_rfk_report_wait(rtwdev, rfk_name, ms);
4050 
4051 	if (record)
4052 		record->states[rfk_type] = wait->state;
4053 
4054 	return ret;
4055 }
4056 
4057 #define rtw89_phy_rfk_report_wait(rtwdev, type, phy_idx, chan, ms) \
4058 	__rtw89_phy_rfk_report_wait(rtwdev, RTW89_RFK_REPORT_ ## type, phy_idx, chan, ms)
4059 
4060 static void
rtw89_phy_c2h_rfk_report_state(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)4061 rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4062 {
4063 	const struct rtw89_c2h_rfk_report *report =
4064 		(const struct rtw89_c2h_rfk_report *)c2h->data;
4065 	struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait;
4066 
4067 	wait->state = report->state;
4068 	wait->version = report->version;
4069 
4070 	complete(&wait->completion);
4071 
4072 	rtw89_debug(rtwdev, RTW89_DBG_RFK,
4073 		    "RFK report state %d with version %d (%*ph)\n",
4074 		    wait->state, wait->version,
4075 		    (int)(len - sizeof(report->hdr)), &report->state);
4076 }
4077 
4078 static void
rtw89_phy_c2h_rfk_report_tas_pwr(struct rtw89_dev * rtwdev,struct sk_buff * c2h,u32 len)4079 rtw89_phy_c2h_rfk_report_tas_pwr(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
4080 {
4081 	const struct rtw89_c2h_rf_tas_info *report =
4082 		(const struct rtw89_c2h_rf_tas_info *)c2h->data;
4083 
4084 	rtw89_phy_c2h_rfk_tas_pwr(rtwdev, &report->content);
4085 }
4086 
4087 static
4088 void (* const rtw89_phy_c2h_rfk_report_handler[])(struct rtw89_dev *rtwdev,
4089 						  struct sk_buff *c2h, u32 len) = {
4090 	[RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE] = rtw89_phy_c2h_rfk_report_state,
4091 	[RTW89_PHY_C2H_RFK_REPORT_FUNC_TAS_PWR] = rtw89_phy_c2h_rfk_report_tas_pwr,
4092 };
4093 
rtw89_phy_c2h_chk_atomic(struct rtw89_dev * rtwdev,u8 class,u8 func)4094 bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func)
4095 {
4096 	switch (class) {
4097 	case RTW89_PHY_C2H_RFK_LOG:
4098 		switch (func) {
4099 		case RTW89_PHY_C2H_RFK_LOG_FUNC_IQK:
4100 		case RTW89_PHY_C2H_RFK_LOG_FUNC_DPK:
4101 		case RTW89_PHY_C2H_RFK_LOG_FUNC_DACK:
4102 		case RTW89_PHY_C2H_RFK_LOG_FUNC_RXDCK:
4103 		case RTW89_PHY_C2H_RFK_LOG_FUNC_TSSI:
4104 		case RTW89_PHY_C2H_RFK_LOG_FUNC_TXGAPK:
4105 		case RTW89_PHY_C2H_RFK_LOG_FUNC_TXIQK:
4106 			return true;
4107 		default:
4108 			return false;
4109 		}
4110 	case RTW89_PHY_C2H_RFK_REPORT:
4111 		switch (func) {
4112 		case RTW89_PHY_C2H_RFK_REPORT_FUNC_STATE:
4113 			return true;
4114 		default:
4115 			return false;
4116 		}
4117 	default:
4118 		return false;
4119 	}
4120 }
4121 
rtw89_phy_c2h_handle(struct rtw89_dev * rtwdev,struct sk_buff * skb,u32 len,u8 class,u8 func)4122 void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
4123 			  u32 len, u8 class, u8 func)
4124 {
4125 	void (*handler)(struct rtw89_dev *rtwdev,
4126 			struct sk_buff *c2h, u32 len) = NULL;
4127 
4128 	switch (class) {
4129 	case RTW89_PHY_C2H_CLASS_RA:
4130 		if (func < ARRAY_SIZE(rtw89_phy_c2h_ra_handler))
4131 			handler = rtw89_phy_c2h_ra_handler[func];
4132 		break;
4133 	case RTW89_PHY_C2H_RFK_LOG:
4134 		if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_log_handler))
4135 			handler = rtw89_phy_c2h_rfk_log_handler[func];
4136 		break;
4137 	case RTW89_PHY_C2H_RFK_REPORT:
4138 		if (func < ARRAY_SIZE(rtw89_phy_c2h_rfk_report_handler))
4139 			handler = rtw89_phy_c2h_rfk_report_handler[func];
4140 		break;
4141 	case RTW89_PHY_C2H_CLASS_DM:
4142 		if (func < ARRAY_SIZE(rtw89_phy_c2h_dm_handler))
4143 			handler = rtw89_phy_c2h_dm_handler[func];
4144 		break;
4145 	default:
4146 		break;
4147 	}
4148 	if (!handler) {
4149 		rtw89_info_once(rtwdev, "PHY c2h class %d func %d not support\n",
4150 				class, func);
4151 		return;
4152 	}
4153 	handler(rtwdev, skb, len);
4154 }
4155 
rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,unsigned int ms)4156 int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
4157 				    enum rtw89_phy_idx phy_idx,
4158 				    unsigned int ms)
4159 {
4160 	int ret;
4161 
4162 	if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) {
4163 		rtw89_phy_rfk_report_prep(rtwdev);
4164 		rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx);
4165 		ret = rtw89_phy_rfk_report_wait(rtwdev, PRE_NTFY, phy_idx, NULL, ms);
4166 		if (ret)
4167 			return ret;
4168 	}
4169 
4170 	if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY_MCC, &rtwdev->fw)) {
4171 		ret = rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx);
4172 		if (ret)
4173 			return ret;
4174 	}
4175 
4176 	return 0;
4177 
4178 }
4179 EXPORT_SYMBOL(rtw89_phy_rfk_pre_ntfy_and_wait);
4180 
rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,enum rtw89_tssi_mode tssi_mode,unsigned int ms)4181 int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
4182 				enum rtw89_phy_idx phy_idx,
4183 				const struct rtw89_chan *chan,
4184 				enum rtw89_tssi_mode tssi_mode,
4185 				unsigned int ms)
4186 {
4187 	int ret;
4188 
4189 	rtw89_phy_rfk_report_prep(rtwdev);
4190 
4191 	ret = rtw89_fw_h2c_rf_tssi(rtwdev, phy_idx, chan, tssi_mode);
4192 	if (ret)
4193 		return ret;
4194 
4195 	return rtw89_phy_rfk_report_wait(rtwdev, TSSI, phy_idx, chan, ms);
4196 }
4197 EXPORT_SYMBOL(rtw89_phy_rfk_tssi_and_wait);
4198 
rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,unsigned int ms)4199 int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev,
4200 			       enum rtw89_phy_idx phy_idx,
4201 			       const struct rtw89_chan *chan,
4202 			       unsigned int ms)
4203 {
4204 	int ret;
4205 
4206 	rtw89_phy_rfk_report_prep(rtwdev);
4207 
4208 	ret = rtw89_fw_h2c_rf_iqk(rtwdev, phy_idx, chan);
4209 	if (ret)
4210 		return ret;
4211 
4212 	return rtw89_phy_rfk_report_wait(rtwdev, IQK, phy_idx, chan, ms);
4213 }
4214 EXPORT_SYMBOL(rtw89_phy_rfk_iqk_and_wait);
4215 
rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,unsigned int ms)4216 int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev,
4217 			       enum rtw89_phy_idx phy_idx,
4218 			       const struct rtw89_chan *chan,
4219 			       unsigned int ms)
4220 {
4221 	int ret;
4222 
4223 	rtw89_phy_rfk_report_prep(rtwdev);
4224 
4225 	ret = rtw89_fw_h2c_rf_dpk(rtwdev, phy_idx, chan);
4226 	if (ret)
4227 		return ret;
4228 
4229 	return rtw89_phy_rfk_report_wait(rtwdev, DPK, phy_idx, chan, ms);
4230 }
4231 EXPORT_SYMBOL(rtw89_phy_rfk_dpk_and_wait);
4232 
rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,unsigned int ms)4233 int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev,
4234 				  enum rtw89_phy_idx phy_idx,
4235 				  const struct rtw89_chan *chan,
4236 				  unsigned int ms)
4237 {
4238 	int ret;
4239 
4240 	rtw89_phy_rfk_report_prep(rtwdev);
4241 
4242 	ret = rtw89_fw_h2c_rf_txgapk(rtwdev, phy_idx, chan);
4243 	if (ret)
4244 		return ret;
4245 
4246 	return rtw89_phy_rfk_report_wait(rtwdev, TXGAPK, phy_idx, chan, ms);
4247 }
4248 EXPORT_SYMBOL(rtw89_phy_rfk_txgapk_and_wait);
4249 
rtw89_phy_rfk_dack_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,unsigned int ms)4250 int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
4251 				enum rtw89_phy_idx phy_idx,
4252 				const struct rtw89_chan *chan,
4253 				unsigned int ms)
4254 {
4255 	int ret;
4256 
4257 	rtw89_phy_rfk_report_prep(rtwdev);
4258 
4259 	ret = rtw89_fw_h2c_rf_dack(rtwdev, phy_idx, chan);
4260 	if (ret)
4261 		return ret;
4262 
4263 	return rtw89_phy_rfk_report_wait(rtwdev, DACK, phy_idx, chan, ms);
4264 }
4265 EXPORT_SYMBOL(rtw89_phy_rfk_dack_and_wait);
4266 
rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,bool is_chl_k,unsigned int ms)4267 int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
4268 				 enum rtw89_phy_idx phy_idx,
4269 				 const struct rtw89_chan *chan,
4270 				 bool is_chl_k, unsigned int ms)
4271 {
4272 	int ret;
4273 
4274 	rtw89_phy_rfk_report_prep(rtwdev);
4275 
4276 	ret = rtw89_fw_h2c_rf_rxdck(rtwdev, phy_idx, chan, is_chl_k);
4277 	if (ret)
4278 		return ret;
4279 
4280 	return rtw89_phy_rfk_report_wait(rtwdev, RX_DCK, phy_idx, chan, ms);
4281 }
4282 EXPORT_SYMBOL(rtw89_phy_rfk_rxdck_and_wait);
4283 
rtw89_phy_rfk_txiqk_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,unsigned int ms)4284 int rtw89_phy_rfk_txiqk_and_wait(struct rtw89_dev *rtwdev,
4285 				 enum rtw89_phy_idx phy_idx,
4286 				 const struct rtw89_chan *chan,
4287 				 unsigned int ms)
4288 {
4289 	int ret;
4290 
4291 	rtw89_phy_rfk_report_prep(rtwdev);
4292 
4293 	ret = rtw89_fw_h2c_rf_txiqk(rtwdev, phy_idx, chan);
4294 	if (ret)
4295 		return ret;
4296 
4297 	return rtw89_phy_rfk_report_wait(rtwdev, TX_IQK, phy_idx, chan, ms);
4298 }
4299 EXPORT_SYMBOL(rtw89_phy_rfk_txiqk_and_wait);
4300 
rtw89_phy_rfk_cim3k_and_wait(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,const struct rtw89_chan * chan,unsigned int ms)4301 int rtw89_phy_rfk_cim3k_and_wait(struct rtw89_dev *rtwdev,
4302 				 enum rtw89_phy_idx phy_idx,
4303 				 const struct rtw89_chan *chan,
4304 				 unsigned int ms)
4305 {
4306 	int ret;
4307 
4308 	rtw89_phy_rfk_report_prep(rtwdev);
4309 
4310 	ret = rtw89_fw_h2c_rf_cim3k(rtwdev, phy_idx, chan);
4311 	if (ret)
4312 		return ret;
4313 
4314 	return rtw89_phy_rfk_report_wait(rtwdev, CIM3k, phy_idx, chan, ms);
4315 }
4316 EXPORT_SYMBOL(rtw89_phy_rfk_cim3k_and_wait);
4317 
phy_tssi_get_cck_group(u8 ch)4318 static u32 phy_tssi_get_cck_group(u8 ch)
4319 {
4320 	switch (ch) {
4321 	case 1 ... 2:
4322 		return 0;
4323 	case 3 ... 5:
4324 		return 1;
4325 	case 6 ... 8:
4326 		return 2;
4327 	case 9 ... 11:
4328 		return 3;
4329 	case 12 ... 13:
4330 		return 4;
4331 	case 14:
4332 		return 5;
4333 	}
4334 
4335 	return 0;
4336 }
4337 
4338 #define PHY_TSSI_EXTRA_GROUP_BIT BIT(31)
4339 #define PHY_TSSI_EXTRA_GROUP(idx) (PHY_TSSI_EXTRA_GROUP_BIT | (idx))
4340 #define PHY_IS_TSSI_EXTRA_GROUP(group) ((group) & PHY_TSSI_EXTRA_GROUP_BIT)
4341 #define PHY_TSSI_EXTRA_GET_GROUP_IDX1(group) \
4342 	((group) & ~PHY_TSSI_EXTRA_GROUP_BIT)
4343 #define PHY_TSSI_EXTRA_GET_GROUP_IDX2(group) \
4344 	(PHY_TSSI_EXTRA_GET_GROUP_IDX1(group) + 1)
4345 
phy_tssi_get_ofdm_group(u8 ch)4346 static u32 phy_tssi_get_ofdm_group(u8 ch)
4347 {
4348 	switch (ch) {
4349 	case 1 ... 2:
4350 		return 0;
4351 	case 3 ... 5:
4352 		return 1;
4353 	case 6 ... 8:
4354 		return 2;
4355 	case 9 ... 11:
4356 		return 3;
4357 	case 12 ... 14:
4358 		return 4;
4359 	case 36 ... 40:
4360 		return 5;
4361 	case 41 ... 43:
4362 		return PHY_TSSI_EXTRA_GROUP(5);
4363 	case 44 ... 48:
4364 		return 6;
4365 	case 49 ... 51:
4366 		return PHY_TSSI_EXTRA_GROUP(6);
4367 	case 52 ... 56:
4368 		return 7;
4369 	case 57 ... 59:
4370 		return PHY_TSSI_EXTRA_GROUP(7);
4371 	case 60 ... 64:
4372 		return 8;
4373 	case 100 ... 104:
4374 		return 9;
4375 	case 105 ... 107:
4376 		return PHY_TSSI_EXTRA_GROUP(9);
4377 	case 108 ... 112:
4378 		return 10;
4379 	case 113 ... 115:
4380 		return PHY_TSSI_EXTRA_GROUP(10);
4381 	case 116 ... 120:
4382 		return 11;
4383 	case 121 ... 123:
4384 		return PHY_TSSI_EXTRA_GROUP(11);
4385 	case 124 ... 128:
4386 		return 12;
4387 	case 129 ... 131:
4388 		return PHY_TSSI_EXTRA_GROUP(12);
4389 	case 132 ... 136:
4390 		return 13;
4391 	case 137 ... 139:
4392 		return PHY_TSSI_EXTRA_GROUP(13);
4393 	case 140 ... 144:
4394 		return 14;
4395 	case 149 ... 153:
4396 		return 15;
4397 	case 154 ... 156:
4398 		return PHY_TSSI_EXTRA_GROUP(15);
4399 	case 157 ... 161:
4400 		return 16;
4401 	case 162 ... 164:
4402 		return PHY_TSSI_EXTRA_GROUP(16);
4403 	case 165 ... 169:
4404 		return 17;
4405 	case 170 ... 172:
4406 		return PHY_TSSI_EXTRA_GROUP(17);
4407 	case 173 ... 177:
4408 		return 18;
4409 	}
4410 
4411 	return 0;
4412 }
4413 
phy_tssi_get_6g_ofdm_group(u8 ch)4414 static u32 phy_tssi_get_6g_ofdm_group(u8 ch)
4415 {
4416 	switch (ch) {
4417 	case 1 ... 5:
4418 		return 0;
4419 	case 6 ... 8:
4420 		return PHY_TSSI_EXTRA_GROUP(0);
4421 	case 9 ... 13:
4422 		return 1;
4423 	case 14 ... 16:
4424 		return PHY_TSSI_EXTRA_GROUP(1);
4425 	case 17 ... 21:
4426 		return 2;
4427 	case 22 ... 24:
4428 		return PHY_TSSI_EXTRA_GROUP(2);
4429 	case 25 ... 29:
4430 		return 3;
4431 	case 33 ... 37:
4432 		return 4;
4433 	case 38 ... 40:
4434 		return PHY_TSSI_EXTRA_GROUP(4);
4435 	case 41 ... 45:
4436 		return 5;
4437 	case 46 ... 48:
4438 		return PHY_TSSI_EXTRA_GROUP(5);
4439 	case 49 ... 53:
4440 		return 6;
4441 	case 54 ... 56:
4442 		return PHY_TSSI_EXTRA_GROUP(6);
4443 	case 57 ... 61:
4444 		return 7;
4445 	case 65 ... 69:
4446 		return 8;
4447 	case 70 ... 72:
4448 		return PHY_TSSI_EXTRA_GROUP(8);
4449 	case 73 ... 77:
4450 		return 9;
4451 	case 78 ... 80:
4452 		return PHY_TSSI_EXTRA_GROUP(9);
4453 	case 81 ... 85:
4454 		return 10;
4455 	case 86 ... 88:
4456 		return PHY_TSSI_EXTRA_GROUP(10);
4457 	case 89 ... 93:
4458 		return 11;
4459 	case 97 ... 101:
4460 		return 12;
4461 	case 102 ... 104:
4462 		return PHY_TSSI_EXTRA_GROUP(12);
4463 	case 105 ... 109:
4464 		return 13;
4465 	case 110 ... 112:
4466 		return PHY_TSSI_EXTRA_GROUP(13);
4467 	case 113 ... 117:
4468 		return 14;
4469 	case 118 ... 120:
4470 		return PHY_TSSI_EXTRA_GROUP(14);
4471 	case 121 ... 125:
4472 		return 15;
4473 	case 129 ... 133:
4474 		return 16;
4475 	case 134 ... 136:
4476 		return PHY_TSSI_EXTRA_GROUP(16);
4477 	case 137 ... 141:
4478 		return 17;
4479 	case 142 ... 144:
4480 		return PHY_TSSI_EXTRA_GROUP(17);
4481 	case 145 ... 149:
4482 		return 18;
4483 	case 150 ... 152:
4484 		return PHY_TSSI_EXTRA_GROUP(18);
4485 	case 153 ... 157:
4486 		return 19;
4487 	case 161 ... 165:
4488 		return 20;
4489 	case 166 ... 168:
4490 		return PHY_TSSI_EXTRA_GROUP(20);
4491 	case 169 ... 173:
4492 		return 21;
4493 	case 174 ... 176:
4494 		return PHY_TSSI_EXTRA_GROUP(21);
4495 	case 177 ... 181:
4496 		return 22;
4497 	case 182 ... 184:
4498 		return PHY_TSSI_EXTRA_GROUP(22);
4499 	case 185 ... 189:
4500 		return 23;
4501 	case 193 ... 197:
4502 		return 24;
4503 	case 198 ... 200:
4504 		return PHY_TSSI_EXTRA_GROUP(24);
4505 	case 201 ... 205:
4506 		return 25;
4507 	case 206 ... 208:
4508 		return PHY_TSSI_EXTRA_GROUP(25);
4509 	case 209 ... 213:
4510 		return 26;
4511 	case 214 ... 216:
4512 		return PHY_TSSI_EXTRA_GROUP(26);
4513 	case 217 ... 221:
4514 		return 27;
4515 	case 225 ... 229:
4516 		return 28;
4517 	case 230 ... 232:
4518 		return PHY_TSSI_EXTRA_GROUP(28);
4519 	case 233 ... 237:
4520 		return 29;
4521 	case 238 ... 240:
4522 		return PHY_TSSI_EXTRA_GROUP(29);
4523 	case 241 ... 245:
4524 		return 30;
4525 	case 246 ... 248:
4526 		return PHY_TSSI_EXTRA_GROUP(30);
4527 	case 249 ... 253:
4528 		return 31;
4529 	}
4530 
4531 	return 0;
4532 }
4533 
phy_tssi_get_trim_group(u8 ch)4534 static u32 phy_tssi_get_trim_group(u8 ch)
4535 {
4536 	switch (ch) {
4537 	case 1 ... 8:
4538 		return 0;
4539 	case 9 ... 14:
4540 		return 1;
4541 	case 36 ... 48:
4542 		return 2;
4543 	case 49 ... 51:
4544 		return PHY_TSSI_EXTRA_GROUP(2);
4545 	case 52 ... 64:
4546 		return 3;
4547 	case 100 ... 112:
4548 		return 4;
4549 	case 113 ... 115:
4550 		return PHY_TSSI_EXTRA_GROUP(4);
4551 	case 116 ... 128:
4552 		return 5;
4553 	case 132 ... 144:
4554 		return 6;
4555 	case 149 ... 177:
4556 		return 7;
4557 	}
4558 
4559 	return 0;
4560 }
4561 
phy_tssi_get_6g_trim_group(u8 ch)4562 static u32 phy_tssi_get_6g_trim_group(u8 ch)
4563 {
4564 	switch (ch) {
4565 	case 1 ... 13:
4566 		return 0;
4567 	case 14 ... 16:
4568 		return PHY_TSSI_EXTRA_GROUP(0);
4569 	case 17 ... 29:
4570 		return 1;
4571 	case 33 ... 45:
4572 		return 2;
4573 	case 46 ... 48:
4574 		return PHY_TSSI_EXTRA_GROUP(2);
4575 	case 49 ... 61:
4576 		return 3;
4577 	case 65 ... 77:
4578 		return 4;
4579 	case 78 ... 80:
4580 		return PHY_TSSI_EXTRA_GROUP(4);
4581 	case 81 ... 93:
4582 		return 5;
4583 	case 97 ... 109:
4584 		return 6;
4585 	case 110 ... 112:
4586 		return PHY_TSSI_EXTRA_GROUP(6);
4587 	case 113 ... 125:
4588 		return 7;
4589 	case 129 ... 141:
4590 		return 8;
4591 	case 142 ... 144:
4592 		return PHY_TSSI_EXTRA_GROUP(8);
4593 	case 145 ... 157:
4594 		return 9;
4595 	case 161 ... 173:
4596 		return 10;
4597 	case 174 ... 176:
4598 		return PHY_TSSI_EXTRA_GROUP(10);
4599 	case 177 ... 189:
4600 		return 11;
4601 	case 193 ... 205:
4602 		return 12;
4603 	case 206 ... 208:
4604 		return PHY_TSSI_EXTRA_GROUP(12);
4605 	case 209 ... 221:
4606 		return 13;
4607 	case 225 ... 237:
4608 		return 14;
4609 	case 238 ... 240:
4610 		return PHY_TSSI_EXTRA_GROUP(14);
4611 	case 241 ... 253:
4612 		return 15;
4613 	}
4614 
4615 	return 0;
4616 }
4617 
phy_tssi_get_ofdm_de(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,const struct rtw89_chan * chan,enum rtw89_rf_path path)4618 static s8 phy_tssi_get_ofdm_de(struct rtw89_dev *rtwdev,
4619 			       enum rtw89_phy_idx phy,
4620 			       const struct rtw89_chan *chan,
4621 			       enum rtw89_rf_path path)
4622 {
4623 	struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
4624 	enum rtw89_band band = chan->band_type;
4625 	u8 ch = chan->channel;
4626 	u32 gidx_1st;
4627 	u32 gidx_2nd;
4628 	s8 de_1st;
4629 	s8 de_2nd;
4630 	u32 gidx;
4631 	s8 val;
4632 
4633 	if (band == RTW89_BAND_6G)
4634 		goto calc_6g;
4635 
4636 	gidx = phy_tssi_get_ofdm_group(ch);
4637 
4638 	rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4639 		    "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n",
4640 		    path, gidx);
4641 
4642 	if (PHY_IS_TSSI_EXTRA_GROUP(gidx)) {
4643 		gidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(gidx);
4644 		gidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(gidx);
4645 		de_1st = tssi_info->tssi_mcs[path][gidx_1st];
4646 		de_2nd = tssi_info->tssi_mcs[path][gidx_2nd];
4647 		val = (de_1st + de_2nd) / 2;
4648 
4649 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4650 			    "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n",
4651 			    path, val, de_1st, de_2nd);
4652 	} else {
4653 		val = tssi_info->tssi_mcs[path][gidx];
4654 
4655 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4656 			    "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val);
4657 	}
4658 
4659 	return val;
4660 
4661 calc_6g:
4662 	gidx = phy_tssi_get_6g_ofdm_group(ch);
4663 
4664 	rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4665 		    "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n",
4666 		    path, gidx);
4667 
4668 	if (PHY_IS_TSSI_EXTRA_GROUP(gidx)) {
4669 		gidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(gidx);
4670 		gidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(gidx);
4671 		de_1st = tssi_info->tssi_6g_mcs[path][gidx_1st];
4672 		de_2nd = tssi_info->tssi_6g_mcs[path][gidx_2nd];
4673 		val = (de_1st + de_2nd) / 2;
4674 
4675 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4676 			    "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n",
4677 			    path, val, de_1st, de_2nd);
4678 	} else {
4679 		val = tssi_info->tssi_6g_mcs[path][gidx];
4680 
4681 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4682 			    "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val);
4683 	}
4684 
4685 	return val;
4686 }
4687 
phy_tssi_get_ofdm_trim_de(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,const struct rtw89_chan * chan,enum rtw89_rf_path path)4688 static s8 phy_tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev,
4689 				    enum rtw89_phy_idx phy,
4690 				    const struct rtw89_chan *chan,
4691 				    enum rtw89_rf_path path)
4692 {
4693 	struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
4694 	enum rtw89_band band = chan->band_type;
4695 	u8 ch = chan->channel;
4696 	u32 tgidx_1st;
4697 	u32 tgidx_2nd;
4698 	s8 tde_1st;
4699 	s8 tde_2nd;
4700 	u32 tgidx;
4701 	s8 val;
4702 
4703 	if (band == RTW89_BAND_6G)
4704 		goto calc_6g;
4705 
4706 	tgidx = phy_tssi_get_trim_group(ch);
4707 
4708 	rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4709 		    "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n",
4710 		    path, tgidx);
4711 
4712 	if (PHY_IS_TSSI_EXTRA_GROUP(tgidx)) {
4713 		tgidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(tgidx);
4714 		tgidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(tgidx);
4715 		tde_1st = tssi_info->tssi_trim[path][tgidx_1st];
4716 		tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd];
4717 		val = (tde_1st + tde_2nd) / 2;
4718 
4719 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4720 			    "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n",
4721 			    path, val, tde_1st, tde_2nd);
4722 	} else {
4723 		val = tssi_info->tssi_trim[path][tgidx];
4724 
4725 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4726 			    "[TSSI][TRIM]: path=%d mcs trim_de=%d\n",
4727 			    path, val);
4728 	}
4729 
4730 	return val;
4731 
4732 calc_6g:
4733 	tgidx = phy_tssi_get_6g_trim_group(ch);
4734 
4735 	rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4736 		    "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n",
4737 		    path, tgidx);
4738 
4739 	if (PHY_IS_TSSI_EXTRA_GROUP(tgidx)) {
4740 		tgidx_1st = PHY_TSSI_EXTRA_GET_GROUP_IDX1(tgidx);
4741 		tgidx_2nd = PHY_TSSI_EXTRA_GET_GROUP_IDX2(tgidx);
4742 		tde_1st = tssi_info->tssi_trim_6g[path][tgidx_1st];
4743 		tde_2nd = tssi_info->tssi_trim_6g[path][tgidx_2nd];
4744 		val = (tde_1st + tde_2nd) / 2;
4745 
4746 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4747 			    "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n",
4748 			    path, val, tde_1st, tde_2nd);
4749 	} else {
4750 		val = tssi_info->tssi_trim_6g[path][tgidx];
4751 
4752 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4753 			    "[TSSI][TRIM]: path=%d mcs trim_de=%d\n",
4754 			    path, val);
4755 	}
4756 
4757 	return val;
4758 }
4759 
rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,const struct rtw89_chan * chan,struct rtw89_h2c_rf_tssi * h2c)4760 void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev,
4761 					       enum rtw89_phy_idx phy,
4762 					       const struct rtw89_chan *chan,
4763 					       struct rtw89_h2c_rf_tssi *h2c)
4764 {
4765 	const struct rtw89_chip_info *chip = rtwdev->chip;
4766 	struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
4767 	u8 ch = chan->channel;
4768 	s8 trim_de;
4769 	s8 ofdm_de;
4770 	s8 cck_de;
4771 	u8 gidx;
4772 	s8 val;
4773 	int i;
4774 
4775 	rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n",
4776 		    phy, ch);
4777 
4778 	for (i = RF_PATH_A; i <= RF_PATH_B; i++) {
4779 		trim_de = phy_tssi_get_ofdm_trim_de(rtwdev, phy, chan, i);
4780 		h2c->curr_tssi_trim_de[i] = trim_de;
4781 
4782 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4783 			    "[TSSI][TRIM]: path=%d trim_de=0x%x\n", i, trim_de);
4784 
4785 		gidx = phy_tssi_get_cck_group(ch);
4786 		cck_de = tssi_info->tssi_cck[i][gidx];
4787 		val = u32_get_bits(cck_de + trim_de, 0xff);
4788 
4789 		if (chip->chip_id == RTL8922A) {
4790 			h2c->curr_tssi_cck_de[i] = 0x0;
4791 			h2c->curr_tssi_cck_de_20m[i] = val;
4792 			h2c->curr_tssi_cck_de_40m[i] = val;
4793 		} else {
4794 			h2c->curr_tssi_cck_de[i] = val;
4795 		}
4796 
4797 		h2c->curr_tssi_efuse_cck_de[i] = cck_de;
4798 
4799 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4800 			    "[TSSI][TRIM]: path=%d cck_de=0x%x\n", i, cck_de);
4801 
4802 		ofdm_de = phy_tssi_get_ofdm_de(rtwdev, phy, chan, i);
4803 		val = u32_get_bits(ofdm_de + trim_de, 0xff);
4804 
4805 		if (chip->chip_id == RTL8922A) {
4806 			h2c->curr_tssi_ofdm_de[i] = 0x0;
4807 			h2c->curr_tssi_ofdm_de_20m[i] = val;
4808 			h2c->curr_tssi_ofdm_de_40m[i] = val;
4809 			h2c->curr_tssi_ofdm_de_80m[i] = val;
4810 			h2c->curr_tssi_ofdm_de_160m[i] = val;
4811 			h2c->curr_tssi_ofdm_de_320m[i] = val;
4812 		} else {
4813 			h2c->curr_tssi_ofdm_de[i] = val;
4814 		}
4815 
4816 		h2c->curr_tssi_efuse_ofdm_de[i] = ofdm_de;
4817 
4818 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4819 			    "[TSSI][TRIM]: path=%d ofdm_de=0x%x\n", i, ofdm_de);
4820 	}
4821 }
4822 
rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,const struct rtw89_chan * chan,struct rtw89_h2c_rf_tssi * h2c)4823 void rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev *rtwdev,
4824 					      enum rtw89_phy_idx phy,
4825 					      const struct rtw89_chan *chan,
4826 					      struct rtw89_h2c_rf_tssi *h2c)
4827 {
4828 	struct rtw89_fw_txpwr_track_cfg *trk = rtwdev->fw.elm_info.txpwr_trk;
4829 	struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
4830 	const struct rtw89_chip_info *chip = rtwdev->chip;
4831 	const s8 *thm_up[RF_PATH_B + 1] = {};
4832 	const s8 *thm_down[RF_PATH_B + 1] = {};
4833 	u8 subband = chan->subband_type;
4834 	s8 thm_ofst[128] = {};
4835 	int multiplier;
4836 	u8 thermal;
4837 	u8 path;
4838 	u8 i, j;
4839 
4840 	switch (subband) {
4841 	default:
4842 	case RTW89_CH_2G:
4843 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_P][0];
4844 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GA_N][0];
4845 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_P][0];
4846 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_2GB_N][0];
4847 		break;
4848 	case RTW89_CH_5G_BAND_1:
4849 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][0];
4850 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][0];
4851 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][0];
4852 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][0];
4853 		break;
4854 	case RTW89_CH_5G_BAND_3:
4855 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][1];
4856 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][1];
4857 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][1];
4858 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][1];
4859 		break;
4860 	case RTW89_CH_5G_BAND_4:
4861 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_P][2];
4862 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GA_N][2];
4863 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_P][2];
4864 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_5GB_N][2];
4865 		break;
4866 	case RTW89_CH_6G_BAND_IDX0:
4867 	case RTW89_CH_6G_BAND_IDX1:
4868 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][0];
4869 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][0];
4870 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][0];
4871 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][0];
4872 		break;
4873 	case RTW89_CH_6G_BAND_IDX2:
4874 	case RTW89_CH_6G_BAND_IDX3:
4875 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][1];
4876 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][1];
4877 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][1];
4878 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][1];
4879 		break;
4880 	case RTW89_CH_6G_BAND_IDX4:
4881 	case RTW89_CH_6G_BAND_IDX5:
4882 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][2];
4883 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][2];
4884 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][2];
4885 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][2];
4886 		break;
4887 	case RTW89_CH_6G_BAND_IDX6:
4888 	case RTW89_CH_6G_BAND_IDX7:
4889 		thm_up[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_P][3];
4890 		thm_down[RF_PATH_A] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GA_N][3];
4891 		thm_up[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_P][3];
4892 		thm_down[RF_PATH_B] = trk->delta[RTW89_FW_TXPWR_TRK_TYPE_6GB_N][3];
4893 		break;
4894 	}
4895 
4896 	rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4897 		    "[TSSI] tmeter tbl on subband: %u\n", subband);
4898 
4899 	if (chip->chip_id == RTL8922A)
4900 		multiplier = 1;
4901 	else
4902 		multiplier = -1;
4903 
4904 	for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
4905 		thermal = tssi_info->thermal[path];
4906 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4907 			    "path: %u, pg thermal: 0x%x\n", path, thermal);
4908 
4909 		if (thermal == 0xff) {
4910 			h2c->pg_thermal[path] = 0x38;
4911 			memset(h2c->ftable[path], 0, sizeof(h2c->ftable[path]));
4912 			continue;
4913 		}
4914 
4915 		h2c->pg_thermal[path] = thermal;
4916 
4917 		i = 0;
4918 		for (j = 0; j < 64; j++) {
4919 			thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
4920 				      thm_up[path][i++] :
4921 				      thm_up[path][DELTA_SWINGIDX_SIZE - 1];
4922 			thm_ofst[j] *= multiplier;
4923 		}
4924 
4925 		i = 1;
4926 		for (j = 127; j >= 64; j--) {
4927 			thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
4928 				      -thm_down[path][i++] :
4929 				      -thm_down[path][DELTA_SWINGIDX_SIZE - 1];
4930 			thm_ofst[j] *= multiplier;
4931 		}
4932 
4933 		for (i = 0; i < 128; i += 4) {
4934 			h2c->ftable[path][i + 0] = thm_ofst[i + 3];
4935 			h2c->ftable[path][i + 1] = thm_ofst[i + 2];
4936 			h2c->ftable[path][i + 2] = thm_ofst[i + 1];
4937 			h2c->ftable[path][i + 3] = thm_ofst[i + 0];
4938 
4939 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
4940 				    "thm ofst [%x]: %02x %02x %02x %02x\n",
4941 				    i, thm_ofst[i], thm_ofst[i + 1],
4942 				    thm_ofst[i + 2], thm_ofst[i + 3]);
4943 		}
4944 	}
4945 }
4946 
rtw89_phy_cfo_get_xcap_reg(struct rtw89_dev * rtwdev,bool sc_xo)4947 static u8 rtw89_phy_cfo_get_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo)
4948 {
4949 	const struct rtw89_xtal_info *xtal = rtwdev->chip->xtal_info;
4950 	u32 reg_mask;
4951 
4952 	if (sc_xo)
4953 		reg_mask = xtal->sc_xo_mask;
4954 	else
4955 		reg_mask = xtal->sc_xi_mask;
4956 
4957 	return (u8)rtw89_read32_mask(rtwdev, xtal->xcap_reg, reg_mask);
4958 }
4959 
rtw89_phy_cfo_set_xcap_reg(struct rtw89_dev * rtwdev,bool sc_xo,u8 val)4960 static void rtw89_phy_cfo_set_xcap_reg(struct rtw89_dev *rtwdev, bool sc_xo,
4961 				       u8 val)
4962 {
4963 	const struct rtw89_xtal_info *xtal = rtwdev->chip->xtal_info;
4964 	u32 reg_mask;
4965 
4966 	if (sc_xo)
4967 		reg_mask = xtal->sc_xo_mask;
4968 	else
4969 		reg_mask = xtal->sc_xi_mask;
4970 
4971 	rtw89_write32_mask(rtwdev, xtal->xcap_reg, reg_mask, val);
4972 }
4973 
rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev * rtwdev,u8 crystal_cap,bool force)4974 static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev,
4975 					  u8 crystal_cap, bool force)
4976 {
4977 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
4978 	const struct rtw89_chip_info *chip = rtwdev->chip;
4979 	u8 sc_xi_val = 0, sc_xo_val = 0;
4980 
4981 	if (!force && cfo->crystal_cap == crystal_cap)
4982 		return;
4983 	if (chip->chip_id == RTL8852A || chip->chip_id == RTL8851B) {
4984 		rtw89_phy_cfo_set_xcap_reg(rtwdev, true, crystal_cap);
4985 		rtw89_phy_cfo_set_xcap_reg(rtwdev, false, crystal_cap);
4986 		sc_xo_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, true);
4987 		sc_xi_val = rtw89_phy_cfo_get_xcap_reg(rtwdev, false);
4988 	} else {
4989 		rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XO,
4990 					crystal_cap, XTAL_SC_XO_MASK);
4991 		rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XI,
4992 					crystal_cap, XTAL_SC_XI_MASK);
4993 		rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XO, &sc_xo_val);
4994 		rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_SC_XI, &sc_xi_val);
4995 	}
4996 	cfo->crystal_cap = sc_xi_val;
4997 	cfo->x_cap_ofst = (s8)((int)cfo->crystal_cap - cfo->def_x_cap);
4998 
4999 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xi=0x%x\n", sc_xi_val);
5000 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set sc_xo=0x%x\n", sc_xo_val);
5001 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Get xcap_ofst=%d\n",
5002 		    cfo->x_cap_ofst);
5003 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Set xcap OK\n");
5004 }
5005 
rtw89_phy_cfo_reset(struct rtw89_dev * rtwdev)5006 static void rtw89_phy_cfo_reset(struct rtw89_dev *rtwdev)
5007 {
5008 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5009 	u8 cap;
5010 
5011 	cfo->def_x_cap = cfo->crystal_cap_default & B_AX_XTAL_SC_MASK;
5012 	cfo->is_adjust = false;
5013 	if (cfo->crystal_cap == cfo->def_x_cap)
5014 		return;
5015 	cap = cfo->crystal_cap;
5016 	cap += (cap > cfo->def_x_cap ? -1 : 1);
5017 	rtw89_phy_cfo_set_crystal_cap(rtwdev, cap, false);
5018 	rtw89_debug(rtwdev, RTW89_DBG_CFO,
5019 		    "(0x%x) approach to dflt_val=(0x%x)\n", cfo->crystal_cap,
5020 		    cfo->def_x_cap);
5021 }
5022 
rtw89_dcfo_comp(struct rtw89_dev * rtwdev,s32 curr_cfo)5023 static void rtw89_dcfo_comp(struct rtw89_dev *rtwdev, s32 curr_cfo)
5024 {
5025 	const struct rtw89_reg_def *dcfo_comp = rtwdev->chip->dcfo_comp;
5026 	bool is_linked = rtwdev->total_sta_assoc > 0;
5027 	s32 cfo_avg_312;
5028 	s32 dcfo_comp_val;
5029 	int sign;
5030 
5031 	if (!dcfo_comp)
5032 		return;
5033 
5034 	if (!is_linked) {
5035 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: is_linked=%d\n",
5036 			    is_linked);
5037 		return;
5038 	}
5039 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "DCFO: curr_cfo=%d\n", curr_cfo);
5040 	if (curr_cfo == 0)
5041 		return;
5042 	dcfo_comp_val = rtw89_phy_read32_mask(rtwdev, R_DCFO, B_DCFO);
5043 	sign = curr_cfo > 0 ? 1 : -1;
5044 	cfo_avg_312 = curr_cfo / 625 + sign * dcfo_comp_val;
5045 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "avg_cfo_312=%d step\n", cfo_avg_312);
5046 	if (rtwdev->chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV)
5047 		cfo_avg_312 = -cfo_avg_312;
5048 	rtw89_phy_set_phy_regs(rtwdev, dcfo_comp->addr, dcfo_comp->mask,
5049 			       cfo_avg_312);
5050 }
5051 
rtw89_dcfo_comp_init(struct rtw89_dev * rtwdev)5052 static void rtw89_dcfo_comp_init(struct rtw89_dev *rtwdev)
5053 {
5054 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
5055 	const struct rtw89_chip_info *chip = rtwdev->chip;
5056 	const struct rtw89_cfo_regs *cfo = phy->cfo;
5057 
5058 	rtw89_phy_set_phy_regs(rtwdev, cfo->comp_seg0, cfo->valid_0_mask, 1);
5059 	rtw89_phy_set_phy_regs(rtwdev, cfo->comp, cfo->weighting_mask, 8);
5060 
5061 	if (chip->chip_gen == RTW89_CHIP_AX) {
5062 		if (chip->cfo_hw_comp) {
5063 			rtw89_write32_mask(rtwdev, R_AX_PWR_UL_CTRL2,
5064 					   B_AX_PWR_UL_CFO_MASK, 0x6);
5065 		} else {
5066 			rtw89_phy_set_phy_regs(rtwdev, R_DCFO, B_DCFO, 1);
5067 			rtw89_write32_clr(rtwdev, R_AX_PWR_UL_CTRL2,
5068 					  B_AX_PWR_UL_CFO_MASK);
5069 		}
5070 	}
5071 }
5072 
rtw89_phy_cfo_init(struct rtw89_dev * rtwdev)5073 static void rtw89_phy_cfo_init(struct rtw89_dev *rtwdev)
5074 {
5075 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5076 	struct rtw89_efuse *efuse = &rtwdev->efuse;
5077 
5078 	cfo->crystal_cap_default = efuse->xtal_cap & B_AX_XTAL_SC_MASK;
5079 	cfo->crystal_cap = cfo->crystal_cap_default;
5080 	cfo->def_x_cap = cfo->crystal_cap;
5081 	cfo->x_cap_ub = min_t(int, cfo->def_x_cap + CFO_BOUND, 0x7f);
5082 	cfo->x_cap_lb = max_t(int, cfo->def_x_cap - CFO_BOUND, 0x1);
5083 	cfo->is_adjust = false;
5084 	cfo->divergence_lock_en = false;
5085 	cfo->x_cap_ofst = 0;
5086 	cfo->lock_cnt = 0;
5087 	cfo->rtw89_multi_cfo_mode = RTW89_TP_BASED_AVG_MODE;
5088 	cfo->apply_compensation = false;
5089 	cfo->residual_cfo_acc = 0;
5090 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Default xcap=%0x\n",
5091 		    cfo->crystal_cap_default);
5092 	rtw89_phy_cfo_set_crystal_cap(rtwdev, cfo->crystal_cap_default, true);
5093 	rtw89_dcfo_comp_init(rtwdev);
5094 	cfo->cfo_timer_ms = 2000;
5095 	cfo->cfo_trig_by_timer_en = false;
5096 	cfo->phy_cfo_trk_cnt = 0;
5097 	cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL;
5098 	cfo->cfo_ul_ofdma_acc_mode = RTW89_CFO_UL_OFDMA_ACC_ENABLE;
5099 }
5100 
rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev * rtwdev,s32 curr_cfo)5101 static void rtw89_phy_cfo_crystal_cap_adjust(struct rtw89_dev *rtwdev,
5102 					     s32 curr_cfo)
5103 {
5104 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5105 	int crystal_cap = cfo->crystal_cap;
5106 	s32 cfo_abs = abs(curr_cfo);
5107 	int sign;
5108 
5109 	if (curr_cfo == 0) {
5110 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "curr_cfo=0\n");
5111 		return;
5112 	}
5113 	if (!cfo->is_adjust) {
5114 		if (cfo_abs > CFO_TRK_ENABLE_TH)
5115 			cfo->is_adjust = true;
5116 	} else {
5117 		if (cfo_abs <= CFO_TRK_STOP_TH)
5118 			cfo->is_adjust = false;
5119 	}
5120 	if (!cfo->is_adjust) {
5121 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "Stop CFO tracking\n");
5122 		return;
5123 	}
5124 	sign = curr_cfo > 0 ? 1 : -1;
5125 	if (cfo_abs > CFO_TRK_STOP_TH_4)
5126 		crystal_cap += 3 * sign;
5127 	else if (cfo_abs > CFO_TRK_STOP_TH_3)
5128 		crystal_cap += 3 * sign;
5129 	else if (cfo_abs > CFO_TRK_STOP_TH_2)
5130 		crystal_cap += 1 * sign;
5131 	else if (cfo_abs > CFO_TRK_STOP_TH_1)
5132 		crystal_cap += 1 * sign;
5133 	else
5134 		return;
5135 
5136 	crystal_cap = clamp(crystal_cap, 0, 127);
5137 	rtw89_phy_cfo_set_crystal_cap(rtwdev, (u8)crystal_cap, false);
5138 	rtw89_debug(rtwdev, RTW89_DBG_CFO,
5139 		    "X_cap{Curr,Default}={0x%x,0x%x}\n",
5140 		    cfo->crystal_cap, cfo->def_x_cap);
5141 }
5142 
rtw89_phy_average_cfo_calc(struct rtw89_dev * rtwdev)5143 static s32 rtw89_phy_average_cfo_calc(struct rtw89_dev *rtwdev)
5144 {
5145 	const struct rtw89_chip_info *chip = rtwdev->chip;
5146 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5147 	s32 cfo_khz_all = 0;
5148 	s32 cfo_cnt_all = 0;
5149 	s32 cfo_all_avg = 0;
5150 	u8 i;
5151 
5152 	if (rtwdev->total_sta_assoc != 1)
5153 		return 0;
5154 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "one_entry_only\n");
5155 	for (i = 0; i < CFO_TRACK_MAX_USER; i++) {
5156 		if (cfo->cfo_cnt[i] == 0)
5157 			continue;
5158 		cfo_khz_all += cfo->cfo_tail[i];
5159 		cfo_cnt_all += cfo->cfo_cnt[i];
5160 		cfo_all_avg = phy_div(cfo_khz_all, cfo_cnt_all);
5161 		cfo->pre_cfo_avg[i] = cfo->cfo_avg[i];
5162 		cfo->dcfo_avg = phy_div(cfo_khz_all << chip->dcfo_comp_sft,
5163 					cfo_cnt_all);
5164 	}
5165 	rtw89_debug(rtwdev, RTW89_DBG_CFO,
5166 		    "CFO track for macid = %d\n", i);
5167 	rtw89_debug(rtwdev, RTW89_DBG_CFO,
5168 		    "Total cfo=%dK, pkt_cnt=%d, avg_cfo=%dK\n",
5169 		    cfo_khz_all, cfo_cnt_all, cfo_all_avg);
5170 	return cfo_all_avg;
5171 }
5172 
rtw89_phy_multi_sta_cfo_calc(struct rtw89_dev * rtwdev)5173 static s32 rtw89_phy_multi_sta_cfo_calc(struct rtw89_dev *rtwdev)
5174 {
5175 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5176 	struct rtw89_traffic_stats *stats = &rtwdev->stats;
5177 	s32 target_cfo = 0;
5178 	s32 cfo_khz_all = 0;
5179 	s32 cfo_khz_all_tp_wgt = 0;
5180 	s32 cfo_avg = 0;
5181 	s32 max_cfo_lb = BIT(31);
5182 	s32 min_cfo_ub = GENMASK(30, 0);
5183 	u16 cfo_cnt_all = 0;
5184 	u8 active_entry_cnt = 0;
5185 	u8 sta_cnt = 0;
5186 	u32 tp_all = 0;
5187 	u8 i;
5188 	u8 cfo_tol = 0;
5189 
5190 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Multi entry cfo_trk\n");
5191 	if (cfo->rtw89_multi_cfo_mode == RTW89_PKT_BASED_AVG_MODE) {
5192 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt based avg mode\n");
5193 		for (i = 0; i < CFO_TRACK_MAX_USER; i++) {
5194 			if (cfo->cfo_cnt[i] == 0)
5195 				continue;
5196 			cfo_khz_all += cfo->cfo_tail[i];
5197 			cfo_cnt_all += cfo->cfo_cnt[i];
5198 			cfo_avg = phy_div(cfo_khz_all, (s32)cfo_cnt_all);
5199 			rtw89_debug(rtwdev, RTW89_DBG_CFO,
5200 				    "Msta cfo=%d, pkt_cnt=%d, avg_cfo=%d\n",
5201 				    cfo_khz_all, cfo_cnt_all, cfo_avg);
5202 			target_cfo = cfo_avg;
5203 		}
5204 	} else if (cfo->rtw89_multi_cfo_mode == RTW89_ENTRY_BASED_AVG_MODE) {
5205 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "Entry based avg mode\n");
5206 		for (i = 0; i < CFO_TRACK_MAX_USER; i++) {
5207 			if (cfo->cfo_cnt[i] == 0)
5208 				continue;
5209 			cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i],
5210 						  (s32)cfo->cfo_cnt[i]);
5211 			cfo_khz_all += cfo->cfo_avg[i];
5212 			rtw89_debug(rtwdev, RTW89_DBG_CFO,
5213 				    "Macid=%d, cfo_avg=%d\n", i,
5214 				    cfo->cfo_avg[i]);
5215 		}
5216 		sta_cnt = rtwdev->total_sta_assoc;
5217 		cfo_avg = phy_div(cfo_khz_all, (s32)sta_cnt);
5218 		rtw89_debug(rtwdev, RTW89_DBG_CFO,
5219 			    "Msta cfo_acc=%d, ent_cnt=%d, avg_cfo=%d\n",
5220 			    cfo_khz_all, sta_cnt, cfo_avg);
5221 		target_cfo = cfo_avg;
5222 	} else if (cfo->rtw89_multi_cfo_mode == RTW89_TP_BASED_AVG_MODE) {
5223 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "TP based avg mode\n");
5224 		cfo_tol = cfo->sta_cfo_tolerance;
5225 		for (i = 0; i < CFO_TRACK_MAX_USER; i++) {
5226 			sta_cnt++;
5227 			if (cfo->cfo_cnt[i] != 0) {
5228 				cfo->cfo_avg[i] = phy_div(cfo->cfo_tail[i],
5229 							  (s32)cfo->cfo_cnt[i]);
5230 				active_entry_cnt++;
5231 			} else {
5232 				cfo->cfo_avg[i] = cfo->pre_cfo_avg[i];
5233 			}
5234 			max_cfo_lb = max(cfo->cfo_avg[i] - cfo_tol, max_cfo_lb);
5235 			min_cfo_ub = min(cfo->cfo_avg[i] + cfo_tol, min_cfo_ub);
5236 			cfo_khz_all += cfo->cfo_avg[i];
5237 			/* need tp for each entry */
5238 			rtw89_debug(rtwdev, RTW89_DBG_CFO,
5239 				    "[%d] cfo_avg=%d, tp=tbd\n",
5240 				    i, cfo->cfo_avg[i]);
5241 			if (sta_cnt >= rtwdev->total_sta_assoc)
5242 				break;
5243 		}
5244 		tp_all = stats->rx_throughput; /* need tp for each entry */
5245 		cfo_avg =  phy_div(cfo_khz_all_tp_wgt, (s32)tp_all);
5246 
5247 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "Assoc sta cnt=%d\n",
5248 			    sta_cnt);
5249 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "Active sta cnt=%d\n",
5250 			    active_entry_cnt);
5251 		rtw89_debug(rtwdev, RTW89_DBG_CFO,
5252 			    "Msta cfo with tp_wgt=%d, avg_cfo=%d\n",
5253 			    cfo_khz_all_tp_wgt, cfo_avg);
5254 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "cfo_lb=%d,cfo_ub=%d\n",
5255 			    max_cfo_lb, min_cfo_ub);
5256 		if (max_cfo_lb <= min_cfo_ub) {
5257 			rtw89_debug(rtwdev, RTW89_DBG_CFO,
5258 				    "cfo win_size=%d\n",
5259 				    min_cfo_ub - max_cfo_lb);
5260 			target_cfo = clamp(cfo_avg, max_cfo_lb, min_cfo_ub);
5261 		} else {
5262 			rtw89_debug(rtwdev, RTW89_DBG_CFO,
5263 				    "No intersection of cfo tolerance windows\n");
5264 			target_cfo = phy_div(cfo_khz_all, (s32)sta_cnt);
5265 		}
5266 		for (i = 0; i < CFO_TRACK_MAX_USER; i++)
5267 			cfo->pre_cfo_avg[i] = cfo->cfo_avg[i];
5268 	}
5269 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Target cfo=%d\n", target_cfo);
5270 	return target_cfo;
5271 }
5272 
rtw89_phy_cfo_statistics_reset(struct rtw89_dev * rtwdev)5273 static void rtw89_phy_cfo_statistics_reset(struct rtw89_dev *rtwdev)
5274 {
5275 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5276 
5277 	memset(&cfo->cfo_tail, 0, sizeof(cfo->cfo_tail));
5278 	memset(&cfo->cfo_cnt, 0, sizeof(cfo->cfo_cnt));
5279 	cfo->packet_count = 0;
5280 	cfo->packet_count_pre = 0;
5281 	cfo->cfo_avg_pre = 0;
5282 }
5283 
rtw89_phy_cfo_dm(struct rtw89_dev * rtwdev)5284 static void rtw89_phy_cfo_dm(struct rtw89_dev *rtwdev)
5285 {
5286 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5287 	s32 new_cfo = 0;
5288 	bool x_cap_update = false;
5289 	u8 pre_x_cap = cfo->crystal_cap;
5290 	u8 dcfo_comp_sft = rtwdev->chip->dcfo_comp_sft;
5291 
5292 	cfo->dcfo_avg = 0;
5293 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "CFO:total_sta_assoc=%d\n",
5294 		    rtwdev->total_sta_assoc);
5295 	if (rtwdev->total_sta_assoc == 0 || rtw89_is_mlo_1_1(rtwdev)) {
5296 		rtw89_phy_cfo_reset(rtwdev);
5297 		return;
5298 	}
5299 	if (cfo->packet_count == 0) {
5300 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt = 0\n");
5301 		return;
5302 	}
5303 	if (cfo->packet_count == cfo->packet_count_pre) {
5304 		rtw89_debug(rtwdev, RTW89_DBG_CFO, "Pkt cnt doesn't change\n");
5305 		return;
5306 	}
5307 	if (rtwdev->total_sta_assoc == 1)
5308 		new_cfo = rtw89_phy_average_cfo_calc(rtwdev);
5309 	else
5310 		new_cfo = rtw89_phy_multi_sta_cfo_calc(rtwdev);
5311 	if (cfo->divergence_lock_en) {
5312 		cfo->lock_cnt++;
5313 		if (cfo->lock_cnt > CFO_PERIOD_CNT) {
5314 			cfo->divergence_lock_en = false;
5315 			cfo->lock_cnt = 0;
5316 		} else {
5317 			rtw89_phy_cfo_reset(rtwdev);
5318 		}
5319 		return;
5320 	}
5321 	if (cfo->crystal_cap >= cfo->x_cap_ub ||
5322 	    cfo->crystal_cap <= cfo->x_cap_lb) {
5323 		cfo->divergence_lock_en = true;
5324 		rtw89_phy_cfo_reset(rtwdev);
5325 		return;
5326 	}
5327 
5328 	rtw89_phy_cfo_crystal_cap_adjust(rtwdev, new_cfo);
5329 	cfo->cfo_avg_pre = new_cfo;
5330 	cfo->dcfo_avg_pre = cfo->dcfo_avg;
5331 	x_cap_update =  cfo->crystal_cap != pre_x_cap;
5332 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap_up=%d\n", x_cap_update);
5333 	rtw89_debug(rtwdev, RTW89_DBG_CFO, "Xcap: D:%x C:%x->%x, ofst=%d\n",
5334 		    cfo->def_x_cap, pre_x_cap, cfo->crystal_cap,
5335 		    cfo->x_cap_ofst);
5336 	if (x_cap_update) {
5337 		if (cfo->dcfo_avg > 0)
5338 			cfo->dcfo_avg -= CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft;
5339 		else
5340 			cfo->dcfo_avg += CFO_SW_COMP_FINE_TUNE << dcfo_comp_sft;
5341 	}
5342 	rtw89_dcfo_comp(rtwdev, cfo->dcfo_avg);
5343 	rtw89_phy_cfo_statistics_reset(rtwdev);
5344 }
5345 
rtw89_phy_cfo_track_work(struct wiphy * wiphy,struct wiphy_work * work)5346 void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work)
5347 {
5348 	struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
5349 						cfo_track_work.work);
5350 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5351 
5352 	lockdep_assert_wiphy(wiphy);
5353 
5354 	if (!cfo->cfo_trig_by_timer_en)
5355 		return;
5356 	rtw89_leave_ps_mode(rtwdev);
5357 	rtw89_phy_cfo_dm(rtwdev);
5358 	wiphy_delayed_work_queue(wiphy, &rtwdev->cfo_track_work,
5359 				 msecs_to_jiffies(cfo->cfo_timer_ms));
5360 }
5361 
rtw89_phy_cfo_start_work(struct rtw89_dev * rtwdev)5362 static void rtw89_phy_cfo_start_work(struct rtw89_dev *rtwdev)
5363 {
5364 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5365 
5366 	wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->cfo_track_work,
5367 				 msecs_to_jiffies(cfo->cfo_timer_ms));
5368 }
5369 
rtw89_phy_cfo_track(struct rtw89_dev * rtwdev)5370 void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev)
5371 {
5372 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5373 	struct rtw89_traffic_stats *stats = &rtwdev->stats;
5374 	bool is_ul_ofdma = false, ofdma_acc_en = false;
5375 
5376 	if (stats->rx_tf_periodic > CFO_TF_CNT_TH)
5377 		is_ul_ofdma = true;
5378 	if (cfo->cfo_ul_ofdma_acc_mode == RTW89_CFO_UL_OFDMA_ACC_ENABLE &&
5379 	    is_ul_ofdma)
5380 		ofdma_acc_en = true;
5381 
5382 	switch (cfo->phy_cfo_status) {
5383 	case RTW89_PHY_DCFO_STATE_NORMAL:
5384 		if (stats->tx_throughput >= CFO_TP_UPPER) {
5385 			cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_ENHANCE;
5386 			cfo->cfo_trig_by_timer_en = true;
5387 			cfo->cfo_timer_ms = CFO_COMP_PERIOD;
5388 			rtw89_phy_cfo_start_work(rtwdev);
5389 		}
5390 		break;
5391 	case RTW89_PHY_DCFO_STATE_ENHANCE:
5392 		if (stats->tx_throughput <= CFO_TP_LOWER)
5393 			cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL;
5394 		else if (ofdma_acc_en &&
5395 			 cfo->phy_cfo_trk_cnt >= CFO_PERIOD_CNT)
5396 			cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_HOLD;
5397 		else
5398 			cfo->phy_cfo_trk_cnt++;
5399 
5400 		if (cfo->phy_cfo_status == RTW89_PHY_DCFO_STATE_NORMAL) {
5401 			cfo->phy_cfo_trk_cnt = 0;
5402 			cfo->cfo_trig_by_timer_en = false;
5403 		}
5404 		break;
5405 	case RTW89_PHY_DCFO_STATE_HOLD:
5406 		if (stats->tx_throughput <= CFO_TP_LOWER) {
5407 			cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL;
5408 			cfo->phy_cfo_trk_cnt = 0;
5409 			cfo->cfo_trig_by_timer_en = false;
5410 		} else {
5411 			cfo->phy_cfo_trk_cnt++;
5412 		}
5413 		break;
5414 	default:
5415 		cfo->phy_cfo_status = RTW89_PHY_DCFO_STATE_NORMAL;
5416 		cfo->phy_cfo_trk_cnt = 0;
5417 		break;
5418 	}
5419 	rtw89_debug(rtwdev, RTW89_DBG_CFO,
5420 		    "[CFO]WatchDog tp=%d,state=%d,timer_en=%d,trk_cnt=%d,thermal=%ld\n",
5421 		    stats->tx_throughput, cfo->phy_cfo_status,
5422 		    cfo->cfo_trig_by_timer_en, cfo->phy_cfo_trk_cnt,
5423 		    ewma_thermal_read(&rtwdev->phystat.avg_thermal[0]));
5424 	if (cfo->cfo_trig_by_timer_en)
5425 		return;
5426 	rtw89_phy_cfo_dm(rtwdev);
5427 }
5428 
rtw89_phy_cfo_parse(struct rtw89_dev * rtwdev,s16 cfo_val,struct rtw89_rx_phy_ppdu * phy_ppdu)5429 void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
5430 			 struct rtw89_rx_phy_ppdu *phy_ppdu)
5431 {
5432 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
5433 	u8 macid = phy_ppdu->mac_id;
5434 
5435 	if (macid >= CFO_TRACK_MAX_USER) {
5436 		rtw89_warn(rtwdev, "mac_id %d is out of range\n", macid);
5437 		return;
5438 	}
5439 
5440 	cfo->cfo_tail[macid] += cfo_val;
5441 	cfo->cfo_cnt[macid]++;
5442 	cfo->packet_count++;
5443 }
5444 
rtw89_phy_ul_tb_assoc(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link)5445 void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
5446 {
5447 	const struct rtw89_chip_info *chip = rtwdev->chip;
5448 	const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
5449 						       rtwvif_link->chanctx_idx);
5450 	struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info;
5451 
5452 	if (!chip->ul_tb_waveform_ctrl)
5453 		return;
5454 
5455 	rtwvif_link->def_tri_idx =
5456 		rtw89_phy_read32_mask(rtwdev, R_DCFO_OPT, B_TXSHAPE_TRIANGULAR_CFG);
5457 
5458 	if (chip->chip_id == RTL8852B && rtwdev->hal.cv > CHIP_CBV)
5459 		rtwvif_link->dyn_tb_bedge_en = false;
5460 	else if (chan->band_type >= RTW89_BAND_5G &&
5461 		 chan->band_width >= RTW89_CHANNEL_WIDTH_40)
5462 		rtwvif_link->dyn_tb_bedge_en = true;
5463 	else
5464 		rtwvif_link->dyn_tb_bedge_en = false;
5465 
5466 	rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
5467 		    "[ULTB] def_if_bandedge=%d, def_tri_idx=%d\n",
5468 		    ul_tb_info->def_if_bandedge, rtwvif_link->def_tri_idx);
5469 	rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
5470 		    "[ULTB] dyn_tb_begde_en=%d, dyn_tb_tri_en=%d\n",
5471 		    rtwvif_link->dyn_tb_bedge_en, ul_tb_info->dyn_tb_tri_en);
5472 }
5473 
5474 struct rtw89_phy_ul_tb_check_data {
5475 	bool valid;
5476 	bool high_tf_client;
5477 	bool low_tf_client;
5478 	bool dyn_tb_bedge_en;
5479 	u8 def_tri_idx;
5480 };
5481 
5482 struct rtw89_phy_power_diff {
5483 	u32 q_00;
5484 	u32 q_11;
5485 	u32 q_matrix_en;
5486 	u32 ultb_1t_norm_160;
5487 	u32 ultb_2t_norm_160;
5488 	u32 com1_norm_1sts;
5489 	u32 com2_resp_1sts_path;
5490 };
5491 
rtw89_phy_ofdma_power_diff(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link)5492 static void rtw89_phy_ofdma_power_diff(struct rtw89_dev *rtwdev,
5493 				       struct rtw89_vif_link *rtwvif_link)
5494 {
5495 	static const struct rtw89_phy_power_diff table[2] = {
5496 		{0x0, 0x0, 0x0, 0x0, 0xf4, 0x3, 0x3},
5497 		{0xb50, 0xb50, 0x1, 0xc, 0x0, 0x1, 0x1},
5498 	};
5499 	const struct rtw89_phy_power_diff *param;
5500 	u32 reg;
5501 
5502 	if (!rtwdev->chip->ul_tb_pwr_diff)
5503 		return;
5504 
5505 	if (rtwvif_link->pwr_diff_en == rtwvif_link->pre_pwr_diff_en) {
5506 		rtwvif_link->pwr_diff_en = false;
5507 		return;
5508 	}
5509 
5510 	rtwvif_link->pre_pwr_diff_en = rtwvif_link->pwr_diff_en;
5511 	param = &table[rtwvif_link->pwr_diff_en];
5512 
5513 	rtw89_phy_write32_mask(rtwdev, R_Q_MATRIX_00, B_Q_MATRIX_00_REAL,
5514 			       param->q_00);
5515 	rtw89_phy_write32_mask(rtwdev, R_Q_MATRIX_11, B_Q_MATRIX_11_REAL,
5516 			       param->q_11);
5517 	rtw89_phy_write32_mask(rtwdev, R_CUSTOMIZE_Q_MATRIX,
5518 			       B_CUSTOMIZE_Q_MATRIX_EN, param->q_matrix_en);
5519 
5520 	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_1T, rtwvif_link->mac_idx);
5521 	rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_1T_NORM_BW160,
5522 			   param->ultb_1t_norm_160);
5523 
5524 	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PWR_UL_TB_2T, rtwvif_link->mac_idx);
5525 	rtw89_write32_mask(rtwdev, reg, B_AX_PWR_UL_TB_2T_NORM_BW160,
5526 			   param->ultb_2t_norm_160);
5527 
5528 	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM1, rtwvif_link->mac_idx);
5529 	rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM1_NORM_1STS,
5530 			   param->com1_norm_1sts);
5531 
5532 	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_PATH_COM2, rtwvif_link->mac_idx);
5533 	rtw89_write32_mask(rtwdev, reg, B_AX_PATH_COM2_RESP_1STS_PATH,
5534 			   param->com2_resp_1sts_path);
5535 }
5536 
5537 static
rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,struct rtw89_phy_ul_tb_check_data * ul_tb_data)5538 void rtw89_phy_ul_tb_ctrl_check(struct rtw89_dev *rtwdev,
5539 				struct rtw89_vif_link *rtwvif_link,
5540 				struct rtw89_phy_ul_tb_check_data *ul_tb_data)
5541 {
5542 	struct rtw89_traffic_stats *stats = &rtwdev->stats;
5543 	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
5544 
5545 	if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
5546 		return;
5547 
5548 	if (!vif->cfg.assoc)
5549 		return;
5550 
5551 	if (rtwdev->chip->ul_tb_waveform_ctrl) {
5552 		if (stats->rx_tf_periodic > UL_TB_TF_CNT_L2H_TH)
5553 			ul_tb_data->high_tf_client = true;
5554 		else if (stats->rx_tf_periodic < UL_TB_TF_CNT_H2L_TH)
5555 			ul_tb_data->low_tf_client = true;
5556 
5557 		ul_tb_data->valid = true;
5558 		ul_tb_data->def_tri_idx = rtwvif_link->def_tri_idx;
5559 		ul_tb_data->dyn_tb_bedge_en = rtwvif_link->dyn_tb_bedge_en;
5560 	}
5561 
5562 	rtw89_phy_ofdma_power_diff(rtwdev, rtwvif_link);
5563 }
5564 
rtw89_phy_ul_tb_waveform_ctrl(struct rtw89_dev * rtwdev,struct rtw89_phy_ul_tb_check_data * ul_tb_data)5565 static void rtw89_phy_ul_tb_waveform_ctrl(struct rtw89_dev *rtwdev,
5566 					  struct rtw89_phy_ul_tb_check_data *ul_tb_data)
5567 {
5568 	struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info;
5569 
5570 	if (!rtwdev->chip->ul_tb_waveform_ctrl)
5571 		return;
5572 
5573 	if (ul_tb_data->dyn_tb_bedge_en) {
5574 		if (ul_tb_data->high_tf_client) {
5575 			rtw89_phy_write32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN, 0);
5576 			rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
5577 				    "[ULTB] Turn off if_bandedge\n");
5578 		} else if (ul_tb_data->low_tf_client) {
5579 			rtw89_phy_write32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN,
5580 					       ul_tb_info->def_if_bandedge);
5581 			rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
5582 				    "[ULTB] Set to default if_bandedge = %d\n",
5583 				    ul_tb_info->def_if_bandedge);
5584 		}
5585 	}
5586 
5587 	if (ul_tb_info->dyn_tb_tri_en) {
5588 		if (ul_tb_data->high_tf_client) {
5589 			rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT,
5590 					       B_TXSHAPE_TRIANGULAR_CFG, 0);
5591 			rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
5592 				    "[ULTB] Turn off Tx triangle\n");
5593 		} else if (ul_tb_data->low_tf_client) {
5594 			rtw89_phy_write32_mask(rtwdev, R_DCFO_OPT,
5595 					       B_TXSHAPE_TRIANGULAR_CFG,
5596 					       ul_tb_data->def_tri_idx);
5597 			rtw89_debug(rtwdev, RTW89_DBG_UL_TB,
5598 				    "[ULTB] Set to default tx_shap_idx = %d\n",
5599 				    ul_tb_data->def_tri_idx);
5600 		}
5601 	}
5602 }
5603 
rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev * rtwdev)5604 void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev)
5605 {
5606 	const struct rtw89_chip_info *chip = rtwdev->chip;
5607 	struct rtw89_phy_ul_tb_check_data ul_tb_data = {};
5608 	struct rtw89_vif_link *rtwvif_link;
5609 	struct rtw89_vif *rtwvif;
5610 	unsigned int link_id;
5611 
5612 	if (!chip->ul_tb_waveform_ctrl && !chip->ul_tb_pwr_diff)
5613 		return;
5614 
5615 	if (rtwdev->total_sta_assoc != 1)
5616 		return;
5617 
5618 	rtw89_for_each_rtwvif(rtwdev, rtwvif)
5619 		rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
5620 			rtw89_phy_ul_tb_ctrl_check(rtwdev, rtwvif_link, &ul_tb_data);
5621 
5622 	if (!ul_tb_data.valid)
5623 		return;
5624 
5625 	rtw89_phy_ul_tb_waveform_ctrl(rtwdev, &ul_tb_data);
5626 }
5627 
rtw89_phy_ul_tb_info_init(struct rtw89_dev * rtwdev)5628 static void rtw89_phy_ul_tb_info_init(struct rtw89_dev *rtwdev)
5629 {
5630 	const struct rtw89_chip_info *chip = rtwdev->chip;
5631 	struct rtw89_phy_ul_tb_info *ul_tb_info = &rtwdev->ul_tb_info;
5632 
5633 	if (!chip->ul_tb_waveform_ctrl)
5634 		return;
5635 
5636 	ul_tb_info->dyn_tb_tri_en = true;
5637 	ul_tb_info->def_if_bandedge =
5638 		rtw89_phy_read32_mask(rtwdev, R_BANDEDGE, B_BANDEDGE_EN);
5639 }
5640 
5641 static
rtw89_phy_antdiv_sts_instance_reset(struct rtw89_antdiv_stats * antdiv_sts)5642 void rtw89_phy_antdiv_sts_instance_reset(struct rtw89_antdiv_stats *antdiv_sts)
5643 {
5644 	ewma_rssi_init(&antdiv_sts->cck_rssi_avg);
5645 	ewma_rssi_init(&antdiv_sts->ofdm_rssi_avg);
5646 	ewma_rssi_init(&antdiv_sts->non_legacy_rssi_avg);
5647 	antdiv_sts->pkt_cnt_cck = 0;
5648 	antdiv_sts->pkt_cnt_ofdm = 0;
5649 	antdiv_sts->pkt_cnt_non_legacy = 0;
5650 	antdiv_sts->evm = 0;
5651 }
5652 
rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev * rtwdev,struct rtw89_rx_phy_ppdu * phy_ppdu,struct rtw89_antdiv_stats * stats)5653 static void rtw89_phy_antdiv_sts_instance_add(struct rtw89_dev *rtwdev,
5654 					      struct rtw89_rx_phy_ppdu *phy_ppdu,
5655 					      struct rtw89_antdiv_stats *stats)
5656 {
5657 	if (rtw89_get_data_rate_mode(rtwdev, phy_ppdu->rate) == DATA_RATE_MODE_NON_HT) {
5658 		if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) {
5659 			ewma_rssi_add(&stats->cck_rssi_avg, phy_ppdu->rssi_avg);
5660 			stats->pkt_cnt_cck++;
5661 		} else {
5662 			ewma_rssi_add(&stats->ofdm_rssi_avg, phy_ppdu->rssi_avg);
5663 			stats->pkt_cnt_ofdm++;
5664 			stats->evm += phy_ppdu->ofdm.evm_min;
5665 		}
5666 	} else {
5667 		ewma_rssi_add(&stats->non_legacy_rssi_avg, phy_ppdu->rssi_avg);
5668 		stats->pkt_cnt_non_legacy++;
5669 		stats->evm += phy_ppdu->ofdm.evm_min;
5670 	}
5671 }
5672 
rtw89_phy_antdiv_sts_instance_get_rssi(struct rtw89_antdiv_stats * stats)5673 static u8 rtw89_phy_antdiv_sts_instance_get_rssi(struct rtw89_antdiv_stats *stats)
5674 {
5675 	if (stats->pkt_cnt_non_legacy >= stats->pkt_cnt_cck &&
5676 	    stats->pkt_cnt_non_legacy >= stats->pkt_cnt_ofdm)
5677 		return ewma_rssi_read(&stats->non_legacy_rssi_avg);
5678 	else if (stats->pkt_cnt_ofdm >= stats->pkt_cnt_cck &&
5679 		 stats->pkt_cnt_ofdm >= stats->pkt_cnt_non_legacy)
5680 		return ewma_rssi_read(&stats->ofdm_rssi_avg);
5681 	else
5682 		return ewma_rssi_read(&stats->cck_rssi_avg);
5683 }
5684 
rtw89_phy_antdiv_sts_instance_get_evm(struct rtw89_antdiv_stats * stats)5685 static u8 rtw89_phy_antdiv_sts_instance_get_evm(struct rtw89_antdiv_stats *stats)
5686 {
5687 	return phy_div(stats->evm, stats->pkt_cnt_non_legacy + stats->pkt_cnt_ofdm);
5688 }
5689 
rtw89_phy_antdiv_parse(struct rtw89_dev * rtwdev,struct rtw89_rx_phy_ppdu * phy_ppdu)5690 void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
5691 			    struct rtw89_rx_phy_ppdu *phy_ppdu)
5692 {
5693 	struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
5694 	struct rtw89_hal *hal = &rtwdev->hal;
5695 
5696 	if (!hal->ant_diversity || hal->ant_diversity_fixed)
5697 		return;
5698 
5699 	rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->target_stats);
5700 
5701 	if (!antdiv->get_stats)
5702 		return;
5703 
5704 	if (hal->antenna_rx == RF_A)
5705 		rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->main_stats);
5706 	else if (hal->antenna_rx == RF_B)
5707 		rtw89_phy_antdiv_sts_instance_add(rtwdev, phy_ppdu, &antdiv->aux_stats);
5708 }
5709 
rtw89_phy_antdiv_reg_init(struct rtw89_dev * rtwdev)5710 static void rtw89_phy_antdiv_reg_init(struct rtw89_dev *rtwdev)
5711 {
5712 	rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_ANT_TRAIN_EN,
5713 			      0x0, RTW89_PHY_0);
5714 	rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_TX_ANT_SEL,
5715 			      0x0, RTW89_PHY_0);
5716 
5717 	rtw89_phy_write32_idx(rtwdev, R_P0_ANT_SW, B_P0_TRSW_TX_EXTEND,
5718 			      0x0, RTW89_PHY_0);
5719 	rtw89_phy_write32_idx(rtwdev, R_P0_ANT_SW, B_P0_HW_ANTSW_DIS_BY_GNT_BT,
5720 			      0x0, RTW89_PHY_0);
5721 
5722 	rtw89_phy_write32_idx(rtwdev, R_P0_TRSW, B_P0_BT_FORCE_ANTIDX_EN,
5723 			      0x0, RTW89_PHY_0);
5724 
5725 	rtw89_phy_write32_idx(rtwdev, R_RFSW_CTRL_ANT0_BASE, B_RFSW_CTRL_ANT_MAPPING,
5726 			      0x0100, RTW89_PHY_0);
5727 
5728 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_BTG_TRX,
5729 			      0x1, RTW89_PHY_0);
5730 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_HW_CTRL,
5731 			      0x0, RTW89_PHY_0);
5732 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_SW_2G,
5733 			      0x0, RTW89_PHY_0);
5734 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_SW_5G,
5735 			      0x0, RTW89_PHY_0);
5736 }
5737 
rtw89_phy_antdiv_sts_reset(struct rtw89_dev * rtwdev)5738 static void rtw89_phy_antdiv_sts_reset(struct rtw89_dev *rtwdev)
5739 {
5740 	struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
5741 
5742 	rtw89_phy_antdiv_sts_instance_reset(&antdiv->target_stats);
5743 	rtw89_phy_antdiv_sts_instance_reset(&antdiv->main_stats);
5744 	rtw89_phy_antdiv_sts_instance_reset(&antdiv->aux_stats);
5745 }
5746 
rtw89_phy_antdiv_init(struct rtw89_dev * rtwdev)5747 static void rtw89_phy_antdiv_init(struct rtw89_dev *rtwdev)
5748 {
5749 	struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
5750 	struct rtw89_hal *hal = &rtwdev->hal;
5751 
5752 	if (!hal->ant_diversity)
5753 		return;
5754 
5755 	antdiv->get_stats = false;
5756 	antdiv->rssi_pre = 0;
5757 	rtw89_phy_antdiv_sts_reset(rtwdev);
5758 	rtw89_phy_antdiv_reg_init(rtwdev);
5759 }
5760 
rtw89_phy_thermal_protect_vcore(struct rtw89_dev * rtwdev)5761 static void rtw89_phy_thermal_protect_vcore(struct rtw89_dev *rtwdev)
5762 {
5763 	struct rtw89_phy_stat *phystat = &rtwdev->phystat;
5764 	struct rtw89_hal *hal = &rtwdev->hal;
5765 	bool vcore_enabled = !!hal->thermal_prot_vmax;
5766 	u8 th_max = phystat->last_thermal_max;
5767 	u8 vlv = hal->thermal_prot_vlv;
5768 	u8 prot_th;
5769 
5770 	if (!vcore_enabled || (hal->disabled_dm_bitmap & BIT(RTW89_DM_VCORE)))
5771 		return;
5772 
5773 	prot_th = hal->thermal_prot_th - RTW89_THERMAL_PROT_VLV_TH_OFFSET;
5774 	if (th_max > prot_th && vlv < RTW89_THERMAL_PROT_VLV_MAX)
5775 		vlv++;
5776 	else if (th_max < prot_th - 2 && vlv > 0)
5777 		vlv--;
5778 	else
5779 		return;
5780 
5781 	rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "thermal protection vlv=%d\n", vlv);
5782 
5783 	hal->thermal_prot_vlv = vlv;
5784 	rtw89_mac_set_vcore_cfg(rtwdev, vlv);
5785 }
5786 
rtw89_phy_thermal_protect(struct rtw89_dev * rtwdev)5787 static void rtw89_phy_thermal_protect(struct rtw89_dev *rtwdev)
5788 {
5789 	struct rtw89_phy_stat *phystat = &rtwdev->phystat;
5790 	struct rtw89_hal *hal = &rtwdev->hal;
5791 	u8 th_max = phystat->last_thermal_max;
5792 	u8 lv = hal->thermal_prot_lv;
5793 
5794 	if (!hal->thermal_prot_th ||
5795 	    (hal->disabled_dm_bitmap & BIT(RTW89_DM_THERMAL_PROTECT)))
5796 		return;
5797 
5798 	if (th_max > hal->thermal_prot_th && lv < RTW89_THERMAL_PROT_LV_MAX)
5799 		lv++;
5800 	else if (th_max < hal->thermal_prot_th - 2 && lv > 0)
5801 		lv--;
5802 	else
5803 		return;
5804 
5805 	hal->thermal_prot_lv = lv;
5806 
5807 	rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, "thermal protection lv=%d\n", lv);
5808 
5809 	rtw89_fw_h2c_tx_duty(rtwdev, hal->thermal_prot_lv);
5810 }
5811 
rtw89_phy_stat_thermal_update(struct rtw89_dev * rtwdev)5812 static void rtw89_phy_stat_thermal_update(struct rtw89_dev *rtwdev)
5813 {
5814 	struct rtw89_phy_stat *phystat = &rtwdev->phystat;
5815 	u8 th, th_max = 0;
5816 	int i;
5817 
5818 	for (i = 0; i < rtwdev->chip->rf_path_num; i++) {
5819 		th = rtw89_chip_get_thermal(rtwdev, i);
5820 		if (th)
5821 			ewma_thermal_add(&phystat->avg_thermal[i], th);
5822 
5823 		rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
5824 			    "path(%d) thermal cur=%u avg=%ld", i, th,
5825 			    ewma_thermal_read(&phystat->avg_thermal[i]));
5826 
5827 		th_max = max(th_max, th);
5828 	}
5829 
5830 	phystat->last_thermal_max = th_max;
5831 }
5832 
5833 struct rtw89_phy_iter_rssi_data {
5834 	struct rtw89_dev *rtwdev;
5835 	bool rssi_changed;
5836 };
5837 
5838 static
__rtw89_phy_stat_rssi_update_iter(struct rtw89_sta_link * rtwsta_link,struct rtw89_phy_iter_rssi_data * rssi_data)5839 void __rtw89_phy_stat_rssi_update_iter(struct rtw89_sta_link *rtwsta_link,
5840 				       struct rtw89_phy_iter_rssi_data *rssi_data)
5841 {
5842 	struct rtw89_vif_link *rtwvif_link = rtwsta_link->rtwvif_link;
5843 	struct rtw89_dev *rtwdev = rssi_data->rtwdev;
5844 	struct rtw89_phy_ch_info *ch_info;
5845 	struct rtw89_bb_ctx *bb;
5846 	unsigned long rssi_curr;
5847 
5848 	rssi_curr = ewma_rssi_read(&rtwsta_link->avg_rssi);
5849 	bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
5850 	ch_info = &bb->ch_info;
5851 
5852 	if (rssi_curr < ch_info->rssi_min) {
5853 		ch_info->rssi_min = rssi_curr;
5854 		ch_info->rssi_min_macid = rtwsta_link->mac_id;
5855 	}
5856 
5857 	if (rtwsta_link->prev_rssi == 0) {
5858 		rtwsta_link->prev_rssi = rssi_curr;
5859 	} else if (abs((int)rtwsta_link->prev_rssi - (int)rssi_curr) >
5860 		   (3 << RSSI_FACTOR)) {
5861 		rtwsta_link->prev_rssi = rssi_curr;
5862 		rssi_data->rssi_changed = true;
5863 	}
5864 }
5865 
rtw89_phy_stat_rssi_update_iter(void * data,struct ieee80211_sta * sta)5866 static void rtw89_phy_stat_rssi_update_iter(void *data,
5867 					    struct ieee80211_sta *sta)
5868 {
5869 	struct rtw89_phy_iter_rssi_data *rssi_data =
5870 					(struct rtw89_phy_iter_rssi_data *)data;
5871 	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
5872 	struct rtw89_sta_link *rtwsta_link;
5873 	unsigned int link_id;
5874 
5875 	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
5876 		__rtw89_phy_stat_rssi_update_iter(rtwsta_link, rssi_data);
5877 }
5878 
rtw89_phy_stat_rssi_update(struct rtw89_dev * rtwdev)5879 static void rtw89_phy_stat_rssi_update(struct rtw89_dev *rtwdev)
5880 {
5881 	struct rtw89_phy_iter_rssi_data rssi_data = {};
5882 	struct rtw89_bb_ctx *bb;
5883 
5884 	rssi_data.rtwdev = rtwdev;
5885 	rtw89_for_each_active_bb(rtwdev, bb)
5886 		bb->ch_info.rssi_min = U8_MAX;
5887 
5888 	ieee80211_iterate_stations_atomic(rtwdev->hw,
5889 					  rtw89_phy_stat_rssi_update_iter,
5890 					  &rssi_data);
5891 	if (rssi_data.rssi_changed)
5892 		rtw89_btc_ntfy_wl_sta(rtwdev);
5893 }
5894 
rtw89_phy_stat_init(struct rtw89_dev * rtwdev)5895 static void rtw89_phy_stat_init(struct rtw89_dev *rtwdev)
5896 {
5897 	struct rtw89_phy_stat *phystat = &rtwdev->phystat;
5898 	struct rtw89_bb_ctx *bb;
5899 	int i;
5900 
5901 	for (i = 0; i < rtwdev->chip->rf_path_num; i++)
5902 		ewma_thermal_init(&phystat->avg_thermal[i]);
5903 
5904 	rtw89_phy_stat_thermal_update(rtwdev);
5905 
5906 	rtw89_for_each_capab_bb(rtwdev, bb) {
5907 		memset(&bb->cur_pkt_stat, 0, sizeof(bb->cur_pkt_stat));
5908 		memset(&bb->last_pkt_stat, 0, sizeof(bb->last_pkt_stat));
5909 
5910 		ewma_rssi_init(&bb->bcn_rssi);
5911 		bb->path_diff.raw = 0;
5912 		ewma_path_diff_init(&bb->path_diff.avg);
5913 		bb->path_diff.bf_smo_en = false;
5914 	}
5915 
5916 	rtwdev->hal.thermal_prot_lv = 0;
5917 }
5918 
rtw89_phy_pmac_diag(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)5919 static void rtw89_phy_pmac_diag(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
5920 {
5921 #define RTW89_DIAG_BB_FA_RATIO_TH 80
5922 #define RTW89_DIAG_BB_NO_RX_TH 5
5923 #define RTW89_DIAG_BB_HANG_TH 30
5924 	struct rtw89_pmac_stat_info *pmac_stat = &bb->pmac_stat;
5925 	bool is_linked = rtwdev->total_sta_assoc > 0;
5926 	struct rtw89_diag_bb *diag = &bb->diag;
5927 	u8 fa_ratio = 0;
5928 
5929 	if (!(pmac_stat->cck_mac_txen || pmac_stat->ofdm_mac_txen))
5930 		diag->consecutive_no_tx_cnt++;
5931 	else
5932 		diag->consecutive_no_tx_cnt = 0;
5933 
5934 	if (!pmac_stat->cnt_cca_all)
5935 		diag->consecutive_no_rx_cnt++;
5936 	else
5937 		diag->consecutive_no_rx_cnt = 0;
5938 
5939 	if (pmac_stat->cnt_cca_all)
5940 		fa_ratio = pmac_stat->cnt_fail_all * PERCENT / pmac_stat->cnt_cca_all;
5941 
5942 	diag->diag_bb_bitmap &= ~(BIT(RTW89_DIAG_BB_NO_RX) |
5943 				  BIT(RTW89_DIAG_BB_HANG) |
5944 				  BIT(RTW89_DIAG_BB_FA));
5945 
5946 	if (diag->consecutive_no_rx_cnt >= RTW89_DIAG_BB_NO_RX_TH && is_linked) {
5947 		diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_NO_RX);
5948 		diag->diag_bb_cnt[RTW89_DIAG_BB_NO_RX]++;
5949 	}
5950 
5951 	if (fa_ratio >= RTW89_DIAG_BB_FA_RATIO_TH && is_linked) {
5952 		diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_FA);
5953 		diag->diag_bb_cnt[RTW89_DIAG_BB_FA]++;
5954 	}
5955 
5956 	if (diag->consecutive_no_tx_cnt > RTW89_DIAG_BB_HANG_TH &&
5957 	    diag->consecutive_no_rx_cnt > RTW89_DIAG_BB_HANG_TH) {
5958 		diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_HANG);
5959 		diag->diag_bb_cnt[RTW89_DIAG_BB_HANG]++;
5960 	}
5961 }
5962 
rtw89_phy_pmac_stat_reset(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,bool cck)5963 static void rtw89_phy_pmac_stat_reset(struct rtw89_dev *rtwdev,
5964 				      struct rtw89_bb_ctx *bb, bool cck)
5965 {
5966 	const struct rtw89_pmac_regs *regs = rtwdev->chip->pmac_regs;
5967 
5968 	if (cck) {
5969 		rtw89_phy_write32_clr(rtwdev, regs->r1b_rx_rpt_rst.addr,
5970 				      regs->r1b_rx_rpt_rst.mask);
5971 		rtw89_phy_write32_set(rtwdev, regs->r1b_rx_rpt_rst.addr,
5972 				      regs->r1b_rx_rpt_rst.mask);
5973 	}
5974 
5975 	rtw89_phy_write32_idx_set(rtwdev, regs->enable_all_cnt.addr,
5976 				  regs->enable_all_cnt.mask, bb->phy_idx);
5977 	rtw89_phy_write32_idx_set(rtwdev, regs->rst_all_cnt.addr,
5978 				  regs->rst_all_cnt.mask, bb->phy_idx);
5979 	rtw89_phy_write32_idx_clr(rtwdev, regs->rst_all_cnt.addr,
5980 				  regs->rst_all_cnt.mask, bb->phy_idx);
5981 }
5982 
rtw89_phy_pmac_stat_cck(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)5983 static void rtw89_phy_pmac_stat_cck(struct rtw89_dev *rtwdev,
5984 				    struct rtw89_bb_ctx *bb)
5985 {
5986 	const struct rtw89_pmac_regs *regs = rtwdev->chip->pmac_regs;
5987 	struct rtw89_pmac_stat_info *pmac = &bb->pmac_stat;
5988 	const struct rtw89_chip_info *chip = rtwdev->chip;
5989 	u32 val;
5990 
5991 	pmac->cck_phy_txon =
5992 		rtw89_phy_read32_mask(rtwdev, regs->cck_txon.addr, regs->cck_txon.mask);
5993 	pmac->cck_mac_txen =
5994 		rtw89_phy_read32_mask(rtwdev, regs->cck_txen.addr, regs->cck_txen.mask);
5995 
5996 	if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
5997 		rtw89_phy_write32_mask(rtwdev, regs->r1b_rr_sel.addr,
5998 				       regs->r1b_rr_sel.mask, 0x2);
5999 
6000 	if (bb->phy_idx == RTW89_PHY_1)
6001 		pmac->cnt_cck_cca =
6002 			rtw89_phy_read32_mask(rtwdev, regs->cck_cca.addr + 8,
6003 					      regs->cck_cca.mask);
6004 	else
6005 		pmac->cnt_cck_cca =
6006 			rtw89_phy_read32_mask(rtwdev, regs->cck_cca.addr,
6007 					      regs->cck_cca.mask);
6008 
6009 	if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
6010 		rtw89_phy_write32_mask(rtwdev, regs->r1b_rr_sel.addr,
6011 				       regs->r1b_rr_sel.mask, 0x1);
6012 
6013 	if (bb->phy_idx == RTW89_PHY_1)
6014 		val = rtw89_phy_read32(rtwdev, regs->cck_crc32 + 8);
6015 	else
6016 		val = rtw89_phy_read32(rtwdev, regs->cck_crc32);
6017 	pmac->cnt_cck_crc32_ok = field_get(regs->cck_crc32_ok_mask, val);
6018 	pmac->cnt_cck_crc32_error = field_get(regs->cck_crc32_fail_mask, val);
6019 
6020 	pmac->cnt_sfd_gg =
6021 		rtw89_phy_read32_idx(rtwdev, regs->cck_sfd_gg.addr,
6022 				     regs->cck_sfd_gg.mask, bb->phy_idx);
6023 	pmac->cnt_sig_gg =
6024 		rtw89_phy_read32_idx(rtwdev, regs->cck_sig_gg.addr,
6025 				     regs->cck_sig_gg.mask, bb->phy_idx);
6026 	pmac->cnt_cck_spoofing =
6027 		rtw89_phy_read32_idx(rtwdev, regs->cck_spoofing.addr,
6028 				     regs->cck_spoofing.mask, bb->phy_idx);
6029 
6030 	if (chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev))
6031 		pmac->cnt_cck_fail =
6032 			pmac->cnt_cck_cca - pmac->cnt_cck_crc32_ok -
6033 			pmac->cnt_cck_crc32_error - pmac->cnt_cck_spoofing;
6034 	else
6035 		pmac->cnt_cck_fail =
6036 			rtw89_phy_read32_idx(rtwdev, regs->cck_brk.addr,
6037 					     regs->cck_brk.mask, bb->phy_idx);
6038 }
6039 
rtw89_phy_pmac_stat_ofdm(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6040 static void rtw89_phy_pmac_stat_ofdm(struct rtw89_dev *rtwdev,
6041 				     struct rtw89_bb_ctx *bb)
6042 {
6043 	const struct rtw89_pmac_regs *regs = rtwdev->chip->pmac_regs;
6044 	struct rtw89_pmac_stat_info *pmac = &bb->pmac_stat;
6045 	const struct rtw89_chip_info *chip = rtwdev->chip;
6046 	u32 val;
6047 
6048 	val = rtw89_phy_read32_idx(rtwdev, regs->ofdm_txon, MASKDWORD, bb->phy_idx);
6049 	pmac->ofdm_phy_txon = field_get(regs->ofdm_txon_mask, val);
6050 	pmac->ofdm_mac_txen = field_get(regs->ofdm_txen_mask, val);
6051 
6052 	val = rtw89_phy_read32_idx(rtwdev, regs->l_crc, MASKDWORD, bb->phy_idx);
6053 	pmac->cnt_ofdm_crc32_ok = field_get(regs->l_crc_ok_mask, val);
6054 	pmac->cnt_ofdm_crc32_error = field_get(regs->l_crc_err_mask, val);
6055 
6056 	val = rtw89_phy_read32_idx(rtwdev, regs->ht_crc, MASKDWORD, bb->phy_idx);
6057 	pmac->cnt_ht_crc32_ok = field_get(regs->ht_crc_ok_mask, val);
6058 	pmac->cnt_ht_crc32_error = field_get(regs->ht_crc_err_mask, val);
6059 
6060 	val = rtw89_phy_read32_idx(rtwdev, regs->vht_crc, MASKDWORD, bb->phy_idx);
6061 	pmac->cnt_vht_crc32_ok = field_get(regs->vht_crc_ok_mask, val);
6062 	pmac->cnt_vht_crc32_error = field_get(regs->vht_crc_err_mask, val);
6063 
6064 	val = rtw89_phy_read32_idx(rtwdev, regs->he_crc, MASKDWORD, bb->phy_idx);
6065 	pmac->cnt_he_crc32_ok = field_get(regs->he_crc_ok_mask, val);
6066 	pmac->cnt_he_crc32_error = field_get(regs->he_crc_err_mask, val);
6067 
6068 	if (chip->chip_gen == RTW89_CHIP_BE) {
6069 		val = rtw89_phy_read32_idx(rtwdev, regs->eht_crc,
6070 					   MASKDWORD, bb->phy_idx);
6071 		pmac->cnt_eht_crc32_ok = field_get(regs->eht_crc_ok_mask, val);
6072 		pmac->cnt_eht_crc32_error = field_get(regs->eht_crc_err_mask, val);
6073 	}
6074 
6075 	val = rtw89_phy_read32_idx(rtwdev, regs->ampdu_crc, MASKDWORD, bb->phy_idx);
6076 	pmac->cnt_ampdu_crc_ok = field_get(regs->ampdu_crc_ok_mask, val);
6077 	pmac->cnt_ampdu_crc_error = field_get(regs->ampdu_crc_err_mask, val);
6078 
6079 	val = rtw89_phy_read32_idx(rtwdev, regs->brk.addr, regs->brk.mask, bb->phy_idx);
6080 	if (chip->chip_id == RTL8852C &&
6081 	    rtw89_phy_read32_idx(rtwdev, regs->brk_option.addr,
6082 				 regs->brk_option.mask, bb->phy_idx) == 1) {
6083 		u32 tmp = pmac->ofdm_phy_txon + pmac->cck_phy_txon;
6084 
6085 		val = (val > tmp) ? (val - tmp) : 0;
6086 	}
6087 	pmac->cnt_ofdm_fail = val;
6088 
6089 	pmac->cnt_sb_search_fail =
6090 		rtw89_phy_read32_idx(rtwdev, regs->search_fail.addr,
6091 				     regs->search_fail.mask, bb->phy_idx);
6092 	pmac->cnt_lsig_brk_s_th =
6093 		rtw89_phy_read32_idx(rtwdev, regs->lsig_brk_s_th.addr,
6094 				     regs->lsig_brk_s_th.mask, bb->phy_idx);
6095 	pmac->cnt_lsig_brk_l_th =
6096 		rtw89_phy_read32_idx(rtwdev, regs->lsig_brk_l_th.addr,
6097 				     regs->lsig_brk_l_th.mask, bb->phy_idx);
6098 	pmac->cnt_parity_fail =
6099 		rtw89_phy_read32_idx(rtwdev, regs->rxl_err_parity.addr,
6100 				     regs->rxl_err_parity.mask, bb->phy_idx);
6101 	pmac->cnt_rate_illegal =
6102 		rtw89_phy_read32_idx(rtwdev, regs->rxl_err_rate.addr,
6103 				     regs->rxl_err_rate.mask, bb->phy_idx);
6104 	pmac->cnt_ofdm_cca =
6105 		rtw89_phy_read32_idx(rtwdev, regs->ofdm_cca.addr,
6106 				     regs->ofdm_cca.mask, bb->phy_idx);
6107 	pmac->cnt_ofdm_spoofing =
6108 		rtw89_phy_read32_idx(rtwdev, regs->cca_spoofing.addr,
6109 				     regs->cca_spoofing.mask, bb->phy_idx);
6110 	pmac->cnt_ampdu_miss =
6111 		rtw89_phy_read32_idx(rtwdev, regs->ampdu_miss.addr,
6112 				     regs->ampdu_miss.mask, bb->phy_idx);
6113 }
6114 
rtw89_phy_pmac_stat_update(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6115 static void rtw89_phy_pmac_stat_update(struct rtw89_dev *rtwdev,
6116 				       struct rtw89_bb_ctx *bb)
6117 {
6118 	struct rtw89_pmac_stat_info *pmac = &bb->pmac_stat;
6119 	const struct rtw89_chip_info *chip = rtwdev->chip;
6120 	struct rtw89_entity_conf conf;
6121 	const struct rtw89_chan *chan;
6122 	bool cck;
6123 
6124 	rtw89_entity_get_conf(rtwdev, &conf);
6125 	chan = conf.chans[bb->phy_idx];
6126 	cck = chan->band_type == RTW89_BAND_2G;
6127 
6128 	if (cck)
6129 		rtw89_phy_pmac_stat_cck(rtwdev, bb);
6130 
6131 	rtw89_phy_pmac_stat_ofdm(rtwdev, bb);
6132 
6133 	pmac->cnt_fail_all = pmac->cnt_ofdm_fail;
6134 	pmac->cnt_cca_all = pmac->cnt_ofdm_cca;
6135 
6136 	if (cck) {
6137 		pmac->cnt_fail_all += pmac->cnt_cck_fail;
6138 		pmac->cnt_cca_all += pmac->cnt_cck_cca;
6139 	}
6140 
6141 	pmac->cnt_crc32_error_all = pmac->cnt_he_crc32_error +
6142 				    pmac->cnt_vht_crc32_error +
6143 				    pmac->cnt_ht_crc32_error +
6144 				    pmac->cnt_ofdm_crc32_error +
6145 				    pmac->cnt_cck_crc32_error;
6146 
6147 	pmac->cnt_crc32_ok_all = pmac->cnt_he_crc32_ok +
6148 				 pmac->cnt_vht_crc32_ok +
6149 				 pmac->cnt_ht_crc32_ok +
6150 				 pmac->cnt_ofdm_crc32_ok +
6151 				 pmac->cnt_cck_crc32_ok;
6152 
6153 	if (chip->chip_gen == RTW89_CHIP_BE) {
6154 		pmac->cnt_crc32_error_all += pmac->cnt_eht_crc32_error;
6155 		pmac->cnt_crc32_ok_all += pmac->cnt_eht_crc32_ok;
6156 	}
6157 
6158 	rtw89_phy_pmac_diag(rtwdev, bb);
6159 	rtw89_phy_pmac_stat_reset(rtwdev, bb, cck);
6160 }
6161 
rtw89_phy_tx_stat_update(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6162 static void rtw89_phy_tx_stat_update(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
6163 {
6164 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6165 	const struct rtw89_physts_regs *physts = phy->physts;
6166 	struct rtw89_tx_stat_info *tx_stat = &bb->tx_stat;
6167 	const struct rtw89_chip_info *chip = rtwdev->chip;
6168 	u32 reg_nr;
6169 	u32 val;
6170 	u32 i;
6171 
6172 	if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF &&
6173 	    bb->phy_idx != RTW89_PHY_0)
6174 		val = 1;
6175 	else
6176 		val = 0;
6177 
6178 	rtw89_phy_write32_mask(rtwdev, physts->mac_phy_intf_sel.addr,
6179 			       physts->mac_phy_intf_sel.mask, val);
6180 
6181 	reg_nr = min(physts->tx_info.reg_nr, ARRAY_SIZE(tx_stat->info));
6182 	for (i = 0; i < reg_nr; i++)
6183 		tx_stat->info[i] = rtw89_phy_read32(rtwdev, physts->tx_info.regs[i]);
6184 
6185 	reg_nr = min(physts->tx_common_ctrl.reg_nr, ARRAY_SIZE(tx_stat->common_ctrl));
6186 	for (i = 0; i < reg_nr; i++)
6187 		tx_stat->common_ctrl[i] =
6188 			rtw89_phy_read32(rtwdev, physts->tx_common_ctrl.regs[i]);
6189 
6190 	reg_nr = min(chip->rf_path_num, ARRAY_SIZE(tx_stat->txpwr));
6191 	for (i = 0; i < reg_nr; i++)
6192 		tx_stat->txpwr[i] = rtw89_phy_read32_mask(rtwdev, physts->txpwr[i].addr,
6193 							  physts->txpwr[i].mask);
6194 
6195 	tx_stat->type = u32_get_bits(tx_stat->info[0], TX_STATUS_TYPE);
6196 
6197 	if (chip->chip_gen == RTW89_CHIP_AX) {
6198 		tx_stat->tx_path_en = u32_get_bits(tx_stat->info[0], TX_STATUS_TX_PATH_EN);
6199 		tx_stat->path_map = u32_get_bits(tx_stat->info[0], TX_STATUS_PATH_MAP);
6200 		tx_stat->txcmd = u32_get_bits(tx_stat->info[0], TX_STATUS_TXCMD);
6201 		tx_stat->txsc = u32_get_bits(tx_stat->info[1], TX_STATUS_TXSC);
6202 		tx_stat->bw = u32_get_bits(tx_stat->info[1], TX_STATUS_BW);
6203 		tx_stat->tmac_txpwr = u32_get_bits(tx_stat->info[1], TX_STATUS_TMAC_TXPWR);
6204 
6205 		if (!(chip->chip_id == RTL8852A || rtw89_is_rtl885xb(rtwdev)))
6206 			tx_stat->max_mcs = u32_get_bits(tx_stat->info[3], TX_STATUS_MAX_MCS);
6207 	} else {
6208 		tx_stat->type = u32_get_bits(tx_stat->info[0], TX_STATUS_TYPE);
6209 		tx_stat->subtype = u32_get_bits(tx_stat->info[0], TX_STATUS_SUBTYPE);
6210 
6211 		if (chip->chip_id == RTL8922A)
6212 			tx_stat->txcmd = u32_get_bits(tx_stat->info[0], TX_STATUS_TXCMD_V1);
6213 		else
6214 			tx_stat->txcmd = u32_get_bits(tx_stat->info[0], TX_STATUS_TXCMD_V2);
6215 
6216 		tx_stat->txsc = u32_get_bits(tx_stat->info[0], TX_STATUS_TXSC_V1);
6217 		tx_stat->bw = u32_get_bits(tx_stat->info[1], TX_STATUS_BW_V1);
6218 		tx_stat->tmac_txpwr = u32_get_bits(tx_stat->info[1], TX_STATUS_TMAC_TXPWR_V1);
6219 		tx_stat->tx_path_en = u32_get_bits(tx_stat->info[2], TX_STATUS_TX_PATH_EN_V1);
6220 		tx_stat->path_map = u32_get_bits(tx_stat->info[2], TX_STATUS_PATH_MAP_V1);
6221 		tx_stat->max_mcs = u32_get_bits(tx_stat->info[4], TX_STATUS_MAX_MCS_V1);
6222 	}
6223 
6224 	tx_stat->stbc = !!(tx_stat->common_ctrl[0] & TX_STATUS_STBC);
6225 }
6226 
rtw89_phy_trigger_tx_count(struct rtw89_dev * rtwdev)6227 static void rtw89_phy_trigger_tx_count(struct rtw89_dev *rtwdev)
6228 {
6229 	if (RTW89_CHK_FW_FEATURE(TX_HISTORY_V1, &rtwdev->fw))
6230 		rtw89_fw_h2c_phy_ch_rpt(rtwdev);
6231 	else
6232 		rtw89_fw_h2c_drv_ctrl_fw(rtwdev);
6233 }
6234 
rtw89_phy_stat_update(struct rtw89_dev * rtwdev)6235 static void rtw89_phy_stat_update(struct rtw89_dev *rtwdev)
6236 {
6237 	struct rtw89_bb_ctx *bb;
6238 
6239 	if (!rtwdev->phy_info.bb_stat_cfg.enable)
6240 		return;
6241 
6242 	rtw89_phy_trigger_tx_count(rtwdev);
6243 
6244 	rtw89_for_each_active_bb(rtwdev, bb) {
6245 		rtw89_phy_pmac_stat_update(rtwdev, bb);
6246 		rtw89_phy_tx_stat_update(rtwdev, bb);
6247 	}
6248 }
6249 
rtw89_phy_stat_track(struct rtw89_dev * rtwdev)6250 void rtw89_phy_stat_track(struct rtw89_dev *rtwdev)
6251 {
6252 	struct rtw89_bb_ctx *bb;
6253 
6254 	rtw89_phy_stat_thermal_update(rtwdev);
6255 	rtw89_phy_thermal_protect_vcore(rtwdev);
6256 	rtw89_phy_thermal_protect(rtwdev);
6257 	rtw89_phy_stat_rssi_update(rtwdev);
6258 	rtw89_phy_stat_update(rtwdev);
6259 
6260 	rtw89_for_each_active_bb(rtwdev, bb) {
6261 		bb->last_pkt_stat = bb->cur_pkt_stat;
6262 		memset(&bb->cur_pkt_stat, 0, sizeof(bb->cur_pkt_stat));
6263 
6264 		rtw89_chip_path_diff_update(rtwdev, bb);
6265 	}
6266 }
6267 
rtw89_phy_ccx_us_to_idx(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u32 time_us)6268 static u16 rtw89_phy_ccx_us_to_idx(struct rtw89_dev *rtwdev,
6269 				   struct rtw89_bb_ctx *bb, u32 time_us)
6270 {
6271 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6272 
6273 	return time_us >> (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx);
6274 }
6275 
rtw89_phy_ccx_idx_to_us(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u16 idx)6276 static u32 rtw89_phy_ccx_idx_to_us(struct rtw89_dev *rtwdev,
6277 				   struct rtw89_bb_ctx *bb, u16 idx)
6278 {
6279 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6280 
6281 	return idx << (ilog2(CCX_US_BASE_RATIO) + env->ccx_unit_idx);
6282 }
6283 
rtw89_phy_ccx_top_setting_init(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6284 static void rtw89_phy_ccx_top_setting_init(struct rtw89_dev *rtwdev,
6285 					   struct rtw89_bb_ctx *bb)
6286 {
6287 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6288 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6289 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6290 
6291 	env->ccx_manual_ctrl = false;
6292 	env->ccx_ongoing = false;
6293 	env->ccx_rac_lv = RTW89_RAC_RELEASE;
6294 	env->ccx_period = 0;
6295 	env->ccx_unit_idx = RTW89_CCX_32_US;
6296 
6297 	rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->en_mask, 1, bb->phy_idx);
6298 	rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->trig_opt_mask, 1,
6299 			      bb->phy_idx);
6300 	rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1,
6301 			      bb->phy_idx);
6302 	rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->edcca_opt_mask,
6303 			      RTW89_CCX_EDCCA_BW20_0, bb->phy_idx);
6304 }
6305 
rtw89_phy_ccx_get_report(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u16 report,u16 score)6306 static u16 rtw89_phy_ccx_get_report(struct rtw89_dev *rtwdev,
6307 				    struct rtw89_bb_ctx *bb,
6308 				    u16 report, u16 score)
6309 {
6310 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6311 	u32 numer = 0;
6312 	u16 ret = 0;
6313 
6314 	numer = report * score + (env->ccx_period >> 1);
6315 	if (env->ccx_period)
6316 		ret = numer / env->ccx_period;
6317 
6318 	return ret >= score ? score - 1 : ret;
6319 }
6320 
rtw89_phy_ccx_ms_to_period_unit(struct rtw89_dev * rtwdev,u16 time_ms,u32 * period,u32 * unit_idx)6321 static void rtw89_phy_ccx_ms_to_period_unit(struct rtw89_dev *rtwdev,
6322 					    u16 time_ms, u32 *period,
6323 					    u32 *unit_idx)
6324 {
6325 	u32 idx;
6326 	u8 quotient;
6327 
6328 	if (time_ms >= CCX_MAX_PERIOD)
6329 		time_ms = CCX_MAX_PERIOD;
6330 
6331 	quotient = CCX_MAX_PERIOD_UNIT * time_ms / CCX_MAX_PERIOD;
6332 
6333 	if (quotient < 4)
6334 		idx = RTW89_CCX_4_US;
6335 	else if (quotient < 8)
6336 		idx = RTW89_CCX_8_US;
6337 	else if (quotient < 16)
6338 		idx = RTW89_CCX_16_US;
6339 	else
6340 		idx = RTW89_CCX_32_US;
6341 
6342 	*unit_idx = idx;
6343 	*period = (time_ms * MS_TO_4US_RATIO) >> idx;
6344 
6345 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6346 		    "[Trigger Time] period:%d, unit_idx:%d\n",
6347 		    *period, *unit_idx);
6348 }
6349 
rtw89_phy_ccx_racing_release(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6350 static void rtw89_phy_ccx_racing_release(struct rtw89_dev *rtwdev,
6351 					 struct rtw89_bb_ctx *bb)
6352 {
6353 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6354 
6355 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6356 		    "lv:(%d)->(0)\n", env->ccx_rac_lv);
6357 
6358 	env->ccx_ongoing = false;
6359 	env->ccx_rac_lv = RTW89_RAC_RELEASE;
6360 	env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND;
6361 }
6362 
rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,struct rtw89_ccx_para_info * para)6363 static bool rtw89_phy_ifs_clm_th_update_check(struct rtw89_dev *rtwdev,
6364 					      struct rtw89_bb_ctx *bb,
6365 					      struct rtw89_ccx_para_info *para)
6366 {
6367 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6368 	bool is_update = env->ifs_clm_app != para->ifs_clm_app;
6369 	u8 i = 0;
6370 	u16 *ifs_th_l = env->ifs_clm_th_l;
6371 	u16 *ifs_th_h = env->ifs_clm_th_h;
6372 	u32 ifs_th0_us = 0, ifs_th_times = 0;
6373 	u32 ifs_th_h_us[RTW89_IFS_CLM_NUM] = {0};
6374 
6375 	if (!is_update)
6376 		goto ifs_update_finished;
6377 
6378 	switch (para->ifs_clm_app) {
6379 	case RTW89_IFS_CLM_INIT:
6380 	case RTW89_IFS_CLM_BACKGROUND:
6381 	case RTW89_IFS_CLM_ACS:
6382 	case RTW89_IFS_CLM_DBG:
6383 	case RTW89_IFS_CLM_DIG:
6384 	case RTW89_IFS_CLM_TDMA_DIG:
6385 		ifs_th0_us = IFS_CLM_TH0_UPPER;
6386 		ifs_th_times = IFS_CLM_TH_MUL;
6387 		break;
6388 	case RTW89_IFS_CLM_DBG_MANUAL:
6389 		ifs_th0_us = para->ifs_clm_manual_th0;
6390 		ifs_th_times = para->ifs_clm_manual_th_times;
6391 		break;
6392 	default:
6393 		break;
6394 	}
6395 
6396 	/* Set sampling threshold for 4 different regions, unit in idx_cnt.
6397 	 * low[i] = high[i-1] + 1
6398 	 * high[i] = high[i-1] * ifs_th_times
6399 	 */
6400 	ifs_th_l[IFS_CLM_TH_START_IDX] = 0;
6401 	ifs_th_h_us[IFS_CLM_TH_START_IDX] = ifs_th0_us;
6402 	ifs_th_h[IFS_CLM_TH_START_IDX] = rtw89_phy_ccx_us_to_idx(rtwdev, bb,
6403 								 ifs_th0_us);
6404 	for (i = 1; i < RTW89_IFS_CLM_NUM; i++) {
6405 		ifs_th_l[i] = ifs_th_h[i - 1] + 1;
6406 		ifs_th_h_us[i] = ifs_th_h_us[i - 1] * ifs_th_times;
6407 		ifs_th_h[i] = rtw89_phy_ccx_us_to_idx(rtwdev, bb, ifs_th_h_us[i]);
6408 	}
6409 
6410 ifs_update_finished:
6411 	if (!is_update)
6412 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6413 			    "No need to update IFS_TH\n");
6414 
6415 	return is_update;
6416 }
6417 
rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6418 static void rtw89_phy_ifs_clm_set_th_reg(struct rtw89_dev *rtwdev,
6419 					 struct rtw89_bb_ctx *bb)
6420 {
6421 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6422 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6423 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6424 	u8 i = 0;
6425 
6426 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_l_mask,
6427 			      env->ifs_clm_th_l[0], bb->phy_idx);
6428 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_l_mask,
6429 			      env->ifs_clm_th_l[1], bb->phy_idx);
6430 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_l_mask,
6431 			      env->ifs_clm_th_l[2], bb->phy_idx);
6432 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_l_mask,
6433 			      env->ifs_clm_th_l[3], bb->phy_idx);
6434 
6435 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_th_h_mask,
6436 			      env->ifs_clm_th_h[0], bb->phy_idx);
6437 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_th_h_mask,
6438 			      env->ifs_clm_th_h[1], bb->phy_idx);
6439 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_th_h_mask,
6440 			      env->ifs_clm_th_h[2], bb->phy_idx);
6441 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_th_h_mask,
6442 			      env->ifs_clm_th_h[3], bb->phy_idx);
6443 
6444 	for (i = 0; i < RTW89_IFS_CLM_NUM; i++)
6445 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6446 			    "Update IFS_T%d_th{low, high} : {%d, %d}\n",
6447 			    i + 1, env->ifs_clm_th_l[i], env->ifs_clm_th_h[i]);
6448 }
6449 
__rtw89_phy_nhm_setting_init(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6450 static void __rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev,
6451 					 struct rtw89_bb_ctx *bb)
6452 {
6453 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6454 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6455 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6456 
6457 	env->nhm_include_cca = false;
6458 	env->nhm_mntr_time = 0;
6459 	env->nhm_sum = 0;
6460 
6461 	rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_config, ccx->nhm_en_mask, bb->phy_idx);
6462 	rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_method, ccx->nhm_pwr_method_msk,
6463 				  bb->phy_idx);
6464 }
6465 
rtw89_phy_nhm_setting_init(struct rtw89_dev * rtwdev)6466 void rtw89_phy_nhm_setting_init(struct rtw89_dev *rtwdev)
6467 {
6468 	const struct rtw89_chip_info *chip = rtwdev->chip;
6469 	struct rtw89_bb_ctx *bb;
6470 
6471 	if (!chip->support_noise)
6472 		return;
6473 
6474 	rtw89_for_each_active_bb(rtwdev, bb)
6475 		__rtw89_phy_nhm_setting_init(rtwdev, bb);
6476 }
6477 
rtw89_phy_ifs_clm_setting_init(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6478 static void rtw89_phy_ifs_clm_setting_init(struct rtw89_dev *rtwdev,
6479 					   struct rtw89_bb_ctx *bb)
6480 {
6481 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6482 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6483 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6484 	struct rtw89_ccx_para_info para = {};
6485 
6486 	env->ifs_clm_app = RTW89_IFS_CLM_BACKGROUND;
6487 	env->ifs_clm_mntr_time = 0;
6488 
6489 	para.ifs_clm_app = RTW89_IFS_CLM_INIT;
6490 	if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, &para))
6491 		rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb);
6492 
6493 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_collect_en_mask, true,
6494 			      bb->phy_idx);
6495 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t1_addr, ccx->ifs_t1_en_mask, true,
6496 			      bb->phy_idx);
6497 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t2_addr, ccx->ifs_t2_en_mask, true,
6498 			      bb->phy_idx);
6499 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t3_addr, ccx->ifs_t3_en_mask, true,
6500 			      bb->phy_idx);
6501 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_t4_addr, ccx->ifs_t4_en_mask, true,
6502 			      bb->phy_idx);
6503 }
6504 
rtw89_phy_ccx_racing_ctrl(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,enum rtw89_env_racing_lv level)6505 static int rtw89_phy_ccx_racing_ctrl(struct rtw89_dev *rtwdev,
6506 				     struct rtw89_bb_ctx *bb,
6507 				     enum rtw89_env_racing_lv level)
6508 {
6509 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6510 	int ret = 0;
6511 
6512 	if (level >= RTW89_RAC_MAX_NUM) {
6513 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6514 			    "[WARNING] Wrong LV=%d\n", level);
6515 		return -EINVAL;
6516 	}
6517 
6518 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6519 		    "ccx_ongoing=%d, level:(%d)->(%d)\n", env->ccx_ongoing,
6520 		    env->ccx_rac_lv, level);
6521 
6522 	if (env->ccx_ongoing) {
6523 		if (level <= env->ccx_rac_lv)
6524 			ret = -EINVAL;
6525 		else
6526 			env->ccx_ongoing = false;
6527 	}
6528 
6529 	if (ret == 0)
6530 		env->ccx_rac_lv = level;
6531 
6532 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "ccx racing success=%d\n",
6533 		    !ret);
6534 
6535 	return ret;
6536 }
6537 
rtw89_phy_ccx_trigger(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 sel)6538 static void rtw89_phy_ccx_trigger(struct rtw89_dev *rtwdev,
6539 				  struct rtw89_bb_ctx *bb, u8 sel)
6540 {
6541 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6542 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6543 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6544 
6545 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 0,
6546 			      bb->phy_idx);
6547 	rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 0,
6548 			      bb->phy_idx);
6549 	if (sel & RTW89_PHY_ENV_MON_NHM)
6550 		rtw89_phy_write32_idx_clr(rtwdev, ccx->nhm_config,
6551 					  ccx->nhm_en_mask, bb->phy_idx);
6552 
6553 	rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr, ccx->ifs_clm_cnt_clear_mask, 1,
6554 			      bb->phy_idx);
6555 	rtw89_phy_write32_idx(rtwdev, ccx->setting_addr, ccx->measurement_trig_mask, 1,
6556 			      bb->phy_idx);
6557 	if (sel & RTW89_PHY_ENV_MON_NHM)
6558 		rtw89_phy_write32_idx_set(rtwdev, ccx->nhm_config,
6559 					  ccx->nhm_en_mask, bb->phy_idx);
6560 
6561 	env->ccx_ongoing = true;
6562 }
6563 
rtw89_phy_ifs_clm_get_utility(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6564 static void rtw89_phy_ifs_clm_get_utility(struct rtw89_dev *rtwdev,
6565 					  struct rtw89_bb_ctx *bb)
6566 {
6567 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6568 	u8 i = 0;
6569 	u32 res = 0;
6570 
6571 	env->ifs_clm_tx_ratio =
6572 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_tx, PERCENT);
6573 	env->ifs_clm_edcca_excl_cca_ratio =
6574 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_edcca_excl_cca,
6575 					 PERCENT);
6576 	env->ifs_clm_cck_fa_ratio =
6577 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERCENT);
6578 	env->ifs_clm_ofdm_fa_ratio =
6579 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERCENT);
6580 	env->ifs_clm_cck_cca_excl_fa_ratio =
6581 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckcca_excl_fa,
6582 					 PERCENT);
6583 	env->ifs_clm_ofdm_cca_excl_fa_ratio =
6584 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmcca_excl_fa,
6585 					 PERCENT);
6586 	env->ifs_clm_cck_fa_permil =
6587 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_cckfa, PERMIL);
6588 	env->ifs_clm_ofdm_fa_permil =
6589 		rtw89_phy_ccx_get_report(rtwdev, bb, env->ifs_clm_ofdmfa, PERMIL);
6590 
6591 	for (i = 0; i < RTW89_IFS_CLM_NUM; i++) {
6592 		if (env->ifs_clm_his[i] > ENV_MNTR_IFSCLM_HIS_MAX) {
6593 			env->ifs_clm_ifs_avg[i] = ENV_MNTR_FAIL_DWORD;
6594 		} else {
6595 			env->ifs_clm_ifs_avg[i] =
6596 				rtw89_phy_ccx_idx_to_us(rtwdev, bb,
6597 							env->ifs_clm_avg[i]);
6598 		}
6599 
6600 		res = rtw89_phy_ccx_idx_to_us(rtwdev, bb, env->ifs_clm_cca[i]);
6601 		res += env->ifs_clm_his[i] >> 1;
6602 		if (env->ifs_clm_his[i])
6603 			res /= env->ifs_clm_his[i];
6604 		else
6605 			res = 0;
6606 		env->ifs_clm_cca_avg[i] = res;
6607 	}
6608 
6609 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6610 		    "IFS-CLM ratio {Tx, EDCCA_exclu_cca} = {%d, %d}\n",
6611 		    env->ifs_clm_tx_ratio, env->ifs_clm_edcca_excl_cca_ratio);
6612 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6613 		    "IFS-CLM FA ratio {CCK, OFDM} = {%d, %d}\n",
6614 		    env->ifs_clm_cck_fa_ratio, env->ifs_clm_ofdm_fa_ratio);
6615 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6616 		    "IFS-CLM FA permil {CCK, OFDM} = {%d, %d}\n",
6617 		    env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil);
6618 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6619 		    "IFS-CLM CCA_exclu_FA ratio {CCK, OFDM} = {%d, %d}\n",
6620 		    env->ifs_clm_cck_cca_excl_fa_ratio,
6621 		    env->ifs_clm_ofdm_cca_excl_fa_ratio);
6622 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6623 		    "Time:[his, ifs_avg(us), cca_avg(us)]\n");
6624 	for (i = 0; i < RTW89_IFS_CLM_NUM; i++)
6625 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "T%d:[%d, %d, %d]\n",
6626 			    i + 1, env->ifs_clm_his[i], env->ifs_clm_ifs_avg[i],
6627 			    env->ifs_clm_cca_avg[i]);
6628 }
6629 
rtw89_nhm_weighted_avg(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6630 static u8 rtw89_nhm_weighted_avg(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
6631 {
6632 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6633 	u8 nhm_weight[RTW89_NHM_RPT_NUM];
6634 	u32 nhm_weighted_sum = 0;
6635 	u8 weight_zero;
6636 	u8 i;
6637 
6638 	if (env->nhm_sum == 0)
6639 		return 0;
6640 
6641 	weight_zero = clamp_t(u16, env->nhm_th[0] - RTW89_NHM_WEIGHT_OFFSET, 0, U8_MAX);
6642 
6643 	for (i = 0; i < RTW89_NHM_RPT_NUM; i++) {
6644 		if (i == 0)
6645 			nhm_weight[i] = weight_zero;
6646 		else if (i == (RTW89_NHM_RPT_NUM - 1))
6647 			nhm_weight[i] = env->nhm_th[i - 1] + RTW89_NHM_WEIGHT_OFFSET;
6648 		else
6649 			nhm_weight[i] = (env->nhm_th[i - 1] + env->nhm_th[i]) / 2;
6650 	}
6651 
6652 	if (rtwdev->chip->chip_id == RTL8852A || rtwdev->chip->chip_id == RTL8852B ||
6653 	    rtwdev->chip->chip_id == RTL8852C) {
6654 		if (env->nhm_th[RTW89_NHM_TH_NUM - 1] == RTW89_NHM_WA_TH) {
6655 			nhm_weight[RTW89_NHM_RPT_NUM - 1] =
6656 				env->nhm_th[RTW89_NHM_TH_NUM - 2] +
6657 				RTW89_NHM_WEIGHT_OFFSET;
6658 			nhm_weight[RTW89_NHM_RPT_NUM - 2] =
6659 				nhm_weight[RTW89_NHM_RPT_NUM - 1];
6660 		}
6661 
6662 		env->nhm_result[0] += env->nhm_result[RTW89_NHM_RPT_NUM - 1];
6663 		env->nhm_result[RTW89_NHM_RPT_NUM - 1] = 0;
6664 	}
6665 
6666 	for (i = 0; i < RTW89_NHM_RPT_NUM; i++)
6667 		nhm_weighted_sum += env->nhm_result[i] * nhm_weight[i];
6668 
6669 	return (nhm_weighted_sum / env->nhm_sum) >> RTW89_NHM_TH_FACTOR;
6670 }
6671 
__rtw89_phy_nhm_get_result(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,enum rtw89_band hw_band,u16 ch_hw_value)6672 static void __rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev,
6673 				       struct rtw89_bb_ctx *bb, enum rtw89_band hw_band,
6674 				       u16 ch_hw_value)
6675 {
6676 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6677 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6678 	const struct rtw89_chip_info *chip = rtwdev->chip;
6679 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6680 	struct ieee80211_supported_band *sband;
6681 	const struct rtw89_reg_def *nhm_rpt;
6682 	enum nl80211_band band;
6683 	u32 sum = 0;
6684 	u8 chan_idx;
6685 	u8 nhm_pwr;
6686 	u8 i;
6687 
6688 	if (!rtw89_phy_read32_idx(rtwdev, ccx->nhm, ccx->nhm_ready, bb->phy_idx)) {
6689 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,  "[NHM] Get NHM report Fail\n");
6690 		return;
6691 	}
6692 
6693 	for (i = 0; i < RTW89_NHM_RPT_NUM; i++) {
6694 		nhm_rpt = &(*chip->nhm_report)[i];
6695 
6696 		env->nhm_result[i] =
6697 			rtw89_phy_read32_idx(rtwdev, nhm_rpt->addr,
6698 					     nhm_rpt->mask, bb->phy_idx);
6699 		sum += env->nhm_result[i];
6700 	}
6701 	env->nhm_sum = sum;
6702 	nhm_pwr = rtw89_nhm_weighted_avg(rtwdev, bb);
6703 
6704 	if (!ch_hw_value)
6705 		return;
6706 
6707 	band = rtw89_hw_to_nl80211_band(hw_band);
6708 	sband = rtwdev->hw->wiphy->bands[band];
6709 	if (!sband)
6710 		return;
6711 
6712 	for (chan_idx = 0; chan_idx < sband->n_channels; chan_idx++) {
6713 		struct ieee80211_channel *channel;
6714 		struct rtw89_nhm_report *rpt;
6715 		struct list_head *nhm_list;
6716 
6717 		channel = &sband->channels[chan_idx];
6718 		if (channel->hw_value != ch_hw_value)
6719 			continue;
6720 
6721 		rpt = &env->nhm_his[hw_band][chan_idx];
6722 		nhm_list = &env->nhm_rpt_list;
6723 
6724 		rpt->channel = channel;
6725 		rpt->noise = nhm_pwr;
6726 
6727 		if (list_empty(&rpt->list))
6728 			list_add_tail(&rpt->list, nhm_list);
6729 
6730 		return;
6731 	}
6732 
6733 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "[NHM] channel not found\n");
6734 }
6735 
rtw89_phy_nhm_get_result(struct rtw89_dev * rtwdev,enum rtw89_band hw_band,u16 ch_hw_value)6736 void rtw89_phy_nhm_get_result(struct rtw89_dev *rtwdev, enum rtw89_band hw_band,
6737 			      u16 ch_hw_value)
6738 {
6739 	const struct rtw89_chip_info *chip = rtwdev->chip;
6740 	struct rtw89_bb_ctx *bb;
6741 
6742 	if (!chip->support_noise)
6743 		return;
6744 
6745 	rtw89_for_each_active_bb(rtwdev, bb)
6746 		__rtw89_phy_nhm_get_result(rtwdev, bb, hw_band, ch_hw_value);
6747 }
6748 
rtw89_phy_ifs_clm_get_result(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6749 static bool rtw89_phy_ifs_clm_get_result(struct rtw89_dev *rtwdev,
6750 					 struct rtw89_bb_ctx *bb)
6751 {
6752 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6753 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6754 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6755 	u8 i = 0;
6756 
6757 	if (rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr,
6758 				 ccx->ifs_cnt_done_mask, bb->phy_idx) == 0) {
6759 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6760 			    "Get IFS_CLM report Fail\n");
6761 		return false;
6762 	}
6763 
6764 	env->ifs_clm_tx =
6765 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr,
6766 				     ccx->ifs_clm_tx_cnt_msk, bb->phy_idx);
6767 	env->ifs_clm_edcca_excl_cca =
6768 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_tx_cnt_addr,
6769 				     ccx->ifs_clm_edcca_excl_cca_fa_mask, bb->phy_idx);
6770 	env->ifs_clm_cckcca_excl_fa =
6771 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr,
6772 				     ccx->ifs_clm_cckcca_excl_fa_mask, bb->phy_idx);
6773 	env->ifs_clm_ofdmcca_excl_fa =
6774 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_cca_addr,
6775 				     ccx->ifs_clm_ofdmcca_excl_fa_mask, bb->phy_idx);
6776 	env->ifs_clm_cckfa =
6777 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr,
6778 				     ccx->ifs_clm_cck_fa_mask, bb->phy_idx);
6779 	env->ifs_clm_ofdmfa =
6780 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_clm_fa_addr,
6781 				     ccx->ifs_clm_ofdm_fa_mask, bb->phy_idx);
6782 
6783 	env->ifs_clm_his[0] =
6784 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr,
6785 				     ccx->ifs_t1_his_mask, bb->phy_idx);
6786 	env->ifs_clm_his[1] =
6787 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr,
6788 				     ccx->ifs_t2_his_mask, bb->phy_idx);
6789 
6790 	env->ifs_clm_his[2] =
6791 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr2,
6792 				     ccx->ifs_t3_his_mask, bb->phy_idx);
6793 	env->ifs_clm_his[3] =
6794 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_his_addr2,
6795 				     ccx->ifs_t4_his_mask, bb->phy_idx);
6796 
6797 	env->ifs_clm_avg[0] =
6798 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr,
6799 				     ccx->ifs_t1_avg_mask, bb->phy_idx);
6800 	env->ifs_clm_avg[1] =
6801 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_l_addr,
6802 				     ccx->ifs_t2_avg_mask, bb->phy_idx);
6803 	env->ifs_clm_avg[2] =
6804 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr,
6805 				     ccx->ifs_t3_avg_mask, bb->phy_idx);
6806 	env->ifs_clm_avg[3] =
6807 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_avg_h_addr,
6808 				     ccx->ifs_t4_avg_mask, bb->phy_idx);
6809 
6810 	env->ifs_clm_cca[0] =
6811 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr,
6812 				     ccx->ifs_t1_cca_mask, bb->phy_idx);
6813 	env->ifs_clm_cca[1] =
6814 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_l_addr,
6815 				     ccx->ifs_t2_cca_mask, bb->phy_idx);
6816 	env->ifs_clm_cca[2] =
6817 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr,
6818 				     ccx->ifs_t3_cca_mask, bb->phy_idx);
6819 	env->ifs_clm_cca[3] =
6820 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_cca_h_addr,
6821 				     ccx->ifs_t4_cca_mask, bb->phy_idx);
6822 
6823 	env->ifs_clm_total_ifs =
6824 		rtw89_phy_read32_idx(rtwdev, ccx->ifs_total_addr,
6825 				     ccx->ifs_total_mask, bb->phy_idx);
6826 
6827 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "IFS-CLM total_ifs = %d\n",
6828 		    env->ifs_clm_total_ifs);
6829 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6830 		    "{Tx, EDCCA_exclu_cca} = {%d, %d}\n",
6831 		    env->ifs_clm_tx, env->ifs_clm_edcca_excl_cca);
6832 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6833 		    "IFS-CLM FA{CCK, OFDM} = {%d, %d}\n",
6834 		    env->ifs_clm_cckfa, env->ifs_clm_ofdmfa);
6835 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6836 		    "IFS-CLM CCA_exclu_FA{CCK, OFDM} = {%d, %d}\n",
6837 		    env->ifs_clm_cckcca_excl_fa, env->ifs_clm_ofdmcca_excl_fa);
6838 
6839 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK, "Time:[his, avg, cca]\n");
6840 	for (i = 0; i < RTW89_IFS_CLM_NUM; i++)
6841 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6842 			    "T%d:[%d, %d, %d]\n", i + 1, env->ifs_clm_his[i],
6843 			    env->ifs_clm_avg[i], env->ifs_clm_cca[i]);
6844 
6845 	rtw89_phy_ifs_clm_get_utility(rtwdev, bb);
6846 
6847 	return true;
6848 }
6849 
rtw89_phy_edcca_clm_get_result(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6850 static bool rtw89_phy_edcca_clm_get_result(struct rtw89_dev *rtwdev,
6851 					   struct rtw89_bb_ctx *bb)
6852 {
6853 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6854 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6855 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6856 	u32 val;
6857 
6858 	val = rtw89_phy_read32_idx(rtwdev, ccx->edcca_clm_rdy,
6859 				   ccx->edcca_clm_rdy_mask, bb->phy_idx);
6860 	if (!val) {
6861 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6862 			    "Get EDCCA_CLM report Fail\n");
6863 		return false;
6864 	}
6865 
6866 	val = rtw89_phy_read32_idx(rtwdev, ccx->edcca_clm_cnt,
6867 				   ccx->edcca_clm_cnt_mask, bb->phy_idx);
6868 	env->edcca_clm_ratio = rtw89_phy_ccx_get_report(rtwdev, bb, val, PERCENT);
6869 
6870 	return true;
6871 }
6872 
rtw89_phy_nhm_th_update(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6873 static void rtw89_phy_nhm_th_update(struct rtw89_dev *rtwdev,
6874 				    struct rtw89_bb_ctx *bb)
6875 {
6876 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6877 	static const u8 nhm_th_11k[RTW89_NHM_RPT_NUM] = {
6878 		18, 21, 24, 27, 30, 35, 40, 45, 50, 55, 60, 0
6879 	};
6880 	const struct rtw89_chip_info *chip = rtwdev->chip;
6881 	const struct rtw89_reg_def *nhm_th;
6882 	u8 i;
6883 
6884 	for (i = 0; i < RTW89_NHM_RPT_NUM; i++)
6885 		env->nhm_th[i] = nhm_th_11k[i] << RTW89_NHM_TH_FACTOR;
6886 
6887 	if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B ||
6888 	    chip->chip_id == RTL8852C)
6889 		env->nhm_th[RTW89_NHM_TH_NUM - 1] = RTW89_NHM_WA_TH;
6890 
6891 	for (i = 0; i < RTW89_NHM_TH_NUM; i++) {
6892 		nhm_th = &(*chip->nhm_th)[i];
6893 
6894 		rtw89_phy_write32_idx(rtwdev, nhm_th->addr, nhm_th->mask,
6895 				      env->nhm_th[i], bb->phy_idx);
6896 	}
6897 }
6898 
rtw89_phy_nhm_set(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,struct rtw89_ccx_para_info * para)6899 static int rtw89_phy_nhm_set(struct rtw89_dev *rtwdev,
6900 			     struct rtw89_bb_ctx *bb,
6901 			     struct rtw89_ccx_para_info *para)
6902 {
6903 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6904 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6905 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6906 	u32 unit_idx = 0;
6907 	u32 period = 0;
6908 
6909 	if (para->mntr_time == 0) {
6910 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6911 			    "[NHM] MNTR_TIME is 0\n");
6912 		return -EINVAL;
6913 	}
6914 
6915 	if (rtw89_phy_ccx_racing_ctrl(rtwdev, bb, para->rac_lv))
6916 		return -EINVAL;
6917 
6918 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6919 		    "[NHM]nhm_incld_cca=%d, mntr_time=%d ms\n",
6920 		    para->nhm_incld_cca, para->mntr_time);
6921 
6922 	if (para->mntr_time != env->nhm_mntr_time) {
6923 		rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time,
6924 						&period, &unit_idx);
6925 		rtw89_phy_write32_idx(rtwdev, ccx->nhm_config,
6926 				      ccx->nhm_period_mask, period, bb->phy_idx);
6927 		rtw89_phy_write32_idx(rtwdev, ccx->nhm_config,
6928 				      ccx->nhm_unit_mask, period, bb->phy_idx);
6929 
6930 		env->nhm_mntr_time = para->mntr_time;
6931 		env->ccx_period = period;
6932 		env->ccx_unit_idx = unit_idx;
6933 	}
6934 
6935 	if (para->nhm_incld_cca != env->nhm_include_cca) {
6936 		rtw89_phy_write32_idx(rtwdev, ccx->nhm_config,
6937 				      ccx->nhm_include_cca_mask, para->nhm_incld_cca,
6938 				      bb->phy_idx);
6939 
6940 		env->nhm_include_cca = para->nhm_incld_cca;
6941 	}
6942 
6943 	rtw89_phy_nhm_th_update(rtwdev, bb);
6944 
6945 	return 0;
6946 }
6947 
__rtw89_phy_nhm_trigger(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)6948 static void __rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
6949 {
6950 	struct rtw89_ccx_para_info para = {
6951 		.mntr_time = RTW89_NHM_MNTR_TIME,
6952 		.rac_lv = RTW89_RAC_LV_1,
6953 		.nhm_incld_cca = true,
6954 	};
6955 
6956 	rtw89_phy_ccx_racing_release(rtwdev, bb);
6957 
6958 	rtw89_phy_nhm_set(rtwdev, bb, &para);
6959 	rtw89_phy_ccx_trigger(rtwdev, bb, RTW89_PHY_ENV_MON_NHM);
6960 }
6961 
rtw89_phy_nhm_trigger(struct rtw89_dev * rtwdev)6962 void rtw89_phy_nhm_trigger(struct rtw89_dev *rtwdev)
6963 {
6964 	const struct rtw89_chip_info *chip = rtwdev->chip;
6965 	struct rtw89_bb_ctx *bb;
6966 
6967 	if (!chip->support_noise)
6968 		return;
6969 
6970 	rtw89_for_each_active_bb(rtwdev, bb)
6971 		__rtw89_phy_nhm_trigger(rtwdev, bb);
6972 }
6973 
rtw89_phy_ifs_clm_set(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,struct rtw89_ccx_para_info * para)6974 static int rtw89_phy_ifs_clm_set(struct rtw89_dev *rtwdev,
6975 				 struct rtw89_bb_ctx *bb,
6976 				 struct rtw89_ccx_para_info *para)
6977 {
6978 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
6979 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
6980 	const struct rtw89_ccx_regs *ccx = phy->ccx;
6981 	u32 period = 0;
6982 	u32 unit_idx = 0;
6983 
6984 	if (para->mntr_time == 0) {
6985 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
6986 			    "[WARN] MNTR_TIME is 0\n");
6987 		return -EINVAL;
6988 	}
6989 
6990 	if (rtw89_phy_ccx_racing_ctrl(rtwdev, bb, para->rac_lv))
6991 		return -EINVAL;
6992 
6993 	if (para->mntr_time != env->ifs_clm_mntr_time) {
6994 		rtw89_phy_ccx_ms_to_period_unit(rtwdev, para->mntr_time,
6995 						&period, &unit_idx);
6996 		rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr,
6997 				      ccx->ifs_clm_period_mask, period, bb->phy_idx);
6998 		rtw89_phy_write32_idx(rtwdev, ccx->ifs_cnt_addr,
6999 				      ccx->ifs_clm_cnt_unit_mask,
7000 				      unit_idx, bb->phy_idx);
7001 
7002 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
7003 			    "Update IFS-CLM time ((%d)) -> ((%d))\n",
7004 			    env->ifs_clm_mntr_time, para->mntr_time);
7005 
7006 		env->ifs_clm_mntr_time = para->mntr_time;
7007 		env->ccx_period = (u16)period;
7008 		env->ccx_unit_idx = (u8)unit_idx;
7009 	}
7010 
7011 	if (rtw89_phy_ifs_clm_th_update_check(rtwdev, bb, para)) {
7012 		env->ifs_clm_app = para->ifs_clm_app;
7013 		rtw89_phy_ifs_clm_set_th_reg(rtwdev, bb);
7014 	}
7015 
7016 	return 0;
7017 }
7018 
__rtw89_phy_env_monitor_track(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7019 static void __rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev,
7020 					  struct rtw89_bb_ctx *bb)
7021 {
7022 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
7023 	struct rtw89_ccx_para_info para = {};
7024 	u8 chk_result = RTW89_PHY_ENV_MON_CCX_FAIL;
7025 
7026 	env->ccx_watchdog_result = RTW89_PHY_ENV_MON_CCX_FAIL;
7027 	if (env->ccx_manual_ctrl) {
7028 		rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
7029 			    "CCX in manual ctrl\n");
7030 		return;
7031 	}
7032 
7033 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
7034 		    "BB-%d env_monitor track\n", bb->phy_idx);
7035 
7036 	/* only ifs_clm for now */
7037 	if (rtw89_phy_ifs_clm_get_result(rtwdev, bb))
7038 		env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_IFS_CLM;
7039 
7040 	if (rtw89_phy_edcca_clm_get_result(rtwdev, bb))
7041 		env->ccx_watchdog_result |= RTW89_PHY_ENV_MON_EDCCA_CLM;
7042 
7043 	rtw89_phy_ccx_racing_release(rtwdev, bb);
7044 	para.mntr_time = 1900;
7045 	para.rac_lv = RTW89_RAC_LV_1;
7046 	para.ifs_clm_app = RTW89_IFS_CLM_BACKGROUND;
7047 
7048 	if (rtw89_phy_ifs_clm_set(rtwdev, bb, &para) == 0)
7049 		chk_result |= RTW89_PHY_ENV_MON_IFS_CLM;
7050 	if (chk_result)
7051 		rtw89_phy_ccx_trigger(rtwdev, bb, chk_result);
7052 
7053 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
7054 		    "get_result=0x%x, chk_result:0x%x\n",
7055 		    env->ccx_watchdog_result, chk_result);
7056 }
7057 
rtw89_phy_env_monitor_track(struct rtw89_dev * rtwdev)7058 void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
7059 {
7060 	struct rtw89_bb_ctx *bb;
7061 
7062 	rtw89_for_each_active_bb(rtwdev, bb)
7063 		__rtw89_phy_env_monitor_track(rtwdev, bb);
7064 }
7065 
rtw89_physts_ie_page_valid(struct rtw89_dev * rtwdev,enum rtw89_phy_status_bitmap * ie_page)7066 static bool rtw89_physts_ie_page_valid(struct rtw89_dev *rtwdev,
7067 				       enum rtw89_phy_status_bitmap *ie_page)
7068 {
7069 	const struct rtw89_chip_info *chip = rtwdev->chip;
7070 
7071 	if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM ||
7072 	    *ie_page == RTW89_RSVD_9)
7073 		return false;
7074 	else if (*ie_page > RTW89_RSVD_9 && *ie_page < RTW89_EHT_PKT)
7075 		*ie_page -= 1;
7076 
7077 	if (*ie_page == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX)
7078 		return false;
7079 
7080 	return true;
7081 }
7082 
rtw89_phy_get_ie_bitmap_addr(struct rtw89_dev * rtwdev,enum rtw89_phy_status_bitmap ie_page)7083 static u32 rtw89_phy_get_ie_bitmap_addr(struct rtw89_dev *rtwdev,
7084 					enum rtw89_phy_status_bitmap ie_page)
7085 {
7086 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
7087 	static const u8 ie_page_shift = 2;
7088 
7089 	if (ie_page == RTW89_EHT_PKT)
7090 		return phy->physt_bmp_eht;
7091 
7092 	return phy->physt_bmp_start + (ie_page << ie_page_shift);
7093 }
7094 
rtw89_physts_get_ie_bitmap(struct rtw89_dev * rtwdev,enum rtw89_phy_status_bitmap ie_page,enum rtw89_phy_idx phy_idx)7095 static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev,
7096 				      enum rtw89_phy_status_bitmap ie_page,
7097 				      enum rtw89_phy_idx phy_idx)
7098 {
7099 	u32 addr;
7100 
7101 	if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page))
7102 		return 0;
7103 
7104 	addr = rtw89_phy_get_ie_bitmap_addr(rtwdev, ie_page);
7105 
7106 	return rtw89_phy_read32_idx(rtwdev, addr, MASKDWORD, phy_idx);
7107 }
7108 
rtw89_physts_set_ie_bitmap(struct rtw89_dev * rtwdev,enum rtw89_phy_status_bitmap ie_page,u32 val,enum rtw89_phy_idx phy_idx)7109 static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
7110 				       enum rtw89_phy_status_bitmap ie_page,
7111 				       u32 val, enum rtw89_phy_idx phy_idx)
7112 {
7113 	const struct rtw89_chip_info *chip = rtwdev->chip;
7114 	u32 addr;
7115 
7116 	if (!rtw89_physts_ie_page_valid(rtwdev, &ie_page))
7117 		return;
7118 
7119 	if (chip->chip_id == RTL8852A)
7120 		val &= B_PHY_STS_BITMAP_MSK_52A;
7121 
7122 	addr = rtw89_phy_get_ie_bitmap_addr(rtwdev, ie_page);
7123 	rtw89_phy_write32_idx(rtwdev, addr, MASKDWORD, val, phy_idx);
7124 }
7125 
rtw89_physts_enable_fail_report(struct rtw89_dev * rtwdev,bool enable,enum rtw89_phy_idx phy_idx)7126 static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
7127 					    bool enable,
7128 					    enum rtw89_phy_idx phy_idx)
7129 {
7130 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
7131 	const struct rtw89_physts_regs *physts = phy->physts;
7132 
7133 	if (enable) {
7134 		rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr,
7135 					  physts->dis_trigger_fail_mask, phy_idx);
7136 		rtw89_phy_write32_idx_clr(rtwdev, physts->setting_addr,
7137 					  physts->dis_trigger_brk_mask, phy_idx);
7138 	} else {
7139 		rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr,
7140 					  physts->dis_trigger_fail_mask, phy_idx);
7141 		rtw89_phy_write32_idx_set(rtwdev, physts->setting_addr,
7142 					  physts->dis_trigger_brk_mask, phy_idx);
7143 	}
7144 }
7145 
rtw89_physts_enable_hdr_2(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)7146 static void rtw89_physts_enable_hdr_2(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
7147 {
7148 	const struct rtw89_chip_info *chip = rtwdev->chip;
7149 
7150 	if (chip->chip_gen == RTW89_CHIP_AX || chip->chip_id == RTL8922A)
7151 		return;
7152 
7153 	rtw89_phy_write32_idx_set(rtwdev, R_STS_HDR2_PARSING_BE4,
7154 				  B_STS_HDR2_PARSING_BE4, phy_idx);
7155 }
7156 
__rtw89_physts_parsing_init(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)7157 static void __rtw89_physts_parsing_init(struct rtw89_dev *rtwdev,
7158 					enum rtw89_phy_idx phy_idx)
7159 {
7160 	const struct rtw89_phy_gen_def *phy = rtwdev->chip->phy_def;
7161 	const struct rtw89_chip_info *chip = rtwdev->chip;
7162 	u32 monitor_mode_mu_ies = 0;
7163 	u32 monitor_mode_su_ies = 0;
7164 	u32 val;
7165 	u8 i;
7166 
7167 	if (rtwdev->hw->conf.flags & IEEE80211_CONF_MONITOR) {
7168 		monitor_mode_mu_ies = BIT(RTW89_PHYSTS_IE09_FTR_0);
7169 		if (phy->physt_gen < 2)
7170 			monitor_mode_mu_ies |= BIT(RTW89_PHYSTS_IE10_FTR_PLCP_EXT);
7171 
7172 		monitor_mode_su_ies = BIT(RTW89_PHYSTS_IE09_FTR_0);
7173 	}
7174 
7175 	rtw89_physts_enable_fail_report(rtwdev, false, phy_idx);
7176 
7177 	/* enable hdr_2 for 8922D (PHYSTS_BE_GEN2 above) */
7178 	rtw89_physts_enable_hdr_2(rtwdev, phy_idx);
7179 
7180 	for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) {
7181 		if (i == RTW89_RSVD_9 ||
7182 		    (i == RTW89_EHT_PKT && chip->chip_gen == RTW89_CHIP_AX))
7183 			continue;
7184 
7185 		val = rtw89_physts_get_ie_bitmap(rtwdev, i, phy_idx);
7186 		if (i == RTW89_HE_MU || i == RTW89_VHT_MU) {
7187 			val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF);
7188 			val |= monitor_mode_mu_ies;
7189 		} else if (i == RTW89_TRIG_BASE_PPDU) {
7190 			val |= BIT(RTW89_PHYSTS_IE13_DL_MU_DEF) |
7191 			       BIT(RTW89_PHYSTS_IE01_CMN_OFDM);
7192 		} else if (i >= RTW89_CCK_PKT) {
7193 			val &= ~(GENMASK(RTW89_PHYSTS_IE07_CMN_EXT_PATH_D,
7194 					 RTW89_PHYSTS_IE04_CMN_EXT_PATH_A));
7195 
7196 			if (i == RTW89_CCK_PKT)
7197 				val |= BIT(RTW89_PHYSTS_IE01_CMN_OFDM);
7198 			else if (i >= RTW89_HT_PKT)
7199 				val |= BIT(RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0);
7200 		}
7201 
7202 		if (i == RTW89_HE_PKT || i == RTW89_VHT_PKT)
7203 			val |= monitor_mode_su_ies;
7204 
7205 		rtw89_physts_set_ie_bitmap(rtwdev, i, val, phy_idx);
7206 	}
7207 }
7208 
rtw89_physts_parsing_init(struct rtw89_dev * rtwdev)7209 void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
7210 {
7211 	__rtw89_physts_parsing_init(rtwdev, RTW89_PHY_0);
7212 	if (rtwdev->dbcc_en)
7213 		__rtw89_physts_parsing_init(rtwdev, RTW89_PHY_1);
7214 }
7215 
rtw89_phy_dig_read_gain_table(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,int type)7216 static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev,
7217 					  struct rtw89_bb_ctx *bb, int type)
7218 {
7219 	const struct rtw89_chip_info *chip = rtwdev->chip;
7220 	const struct rtw89_phy_dig_gain_cfg *cfg;
7221 	struct rtw89_dig_info *dig = &bb->dig;
7222 	const char *msg;
7223 	u8 i;
7224 	s8 gain_base;
7225 	s8 *gain_arr;
7226 	u32 tmp;
7227 
7228 	switch (type) {
7229 	case RTW89_DIG_GAIN_LNA_G:
7230 		gain_arr = dig->lna_gain_g;
7231 		gain_base = LNA0_GAIN;
7232 		cfg = chip->dig_table->cfg_lna_g;
7233 		msg = "lna_gain_g";
7234 		break;
7235 	case RTW89_DIG_GAIN_TIA_G:
7236 		gain_arr = dig->tia_gain_g;
7237 		gain_base = TIA0_GAIN_G;
7238 		cfg = chip->dig_table->cfg_tia_g;
7239 		msg = "tia_gain_g";
7240 		break;
7241 	case RTW89_DIG_GAIN_LNA_A:
7242 		gain_arr = dig->lna_gain_a;
7243 		gain_base = LNA0_GAIN;
7244 		cfg = chip->dig_table->cfg_lna_a;
7245 		msg = "lna_gain_a";
7246 		break;
7247 	case RTW89_DIG_GAIN_TIA_A:
7248 		gain_arr = dig->tia_gain_a;
7249 		gain_base = TIA0_GAIN_A;
7250 		cfg = chip->dig_table->cfg_tia_a;
7251 		msg = "tia_gain_a";
7252 		break;
7253 	default:
7254 		return;
7255 	}
7256 
7257 	for (i = 0; i < cfg->size; i++) {
7258 		tmp = rtw89_phy_read32_idx(rtwdev, cfg->table[i].addr,
7259 					   cfg->table[i].mask, bb->phy_idx);
7260 		tmp >>= DIG_GAIN_SHIFT;
7261 		gain_arr[i] = sign_extend32(tmp, U4_MAX_BIT) + gain_base;
7262 		gain_base += DIG_GAIN;
7263 
7264 		rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s[%d]=%d\n",
7265 			    msg, i, gain_arr[i]);
7266 	}
7267 }
7268 
rtw89_phy_dig_update_gain_para(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7269 static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev,
7270 					   struct rtw89_bb_ctx *bb)
7271 {
7272 	struct rtw89_dig_info *dig = &bb->dig;
7273 	u32 tmp;
7274 	u8 i;
7275 
7276 	if (!rtwdev->hal.support_igi)
7277 		return;
7278 
7279 	tmp = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PKPW,
7280 				   B_PATH0_IB_PKPW_MSK, bb->phy_idx);
7281 	dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT);
7282 	dig->ib_pbk = rtw89_phy_read32_idx(rtwdev, R_PATH0_IB_PBK,
7283 					   B_PATH0_IB_PBK_MSK, bb->phy_idx);
7284 	rtw89_debug(rtwdev, RTW89_DBG_DIG, "ib_pkpwr=%d, ib_pbk=%d\n",
7285 		    dig->ib_pkpwr, dig->ib_pbk);
7286 
7287 	for (i = RTW89_DIG_GAIN_LNA_G; i < RTW89_DIG_GAIN_MAX; i++)
7288 		rtw89_phy_dig_read_gain_table(rtwdev, bb, i);
7289 }
7290 
7291 static const u8 rssi_nolink = 22;
7292 static const u8 igi_rssi_th[IGI_RSSI_TH_NUM] = {68, 84, 90, 98, 104};
7293 static const u16 fa_th_2g[FA_TH_NUM] = {22, 44, 66, 88};
7294 static const u16 fa_th_5g[FA_TH_NUM] = {4, 8, 12, 16};
7295 static const u16 fa_th_nolink[FA_TH_NUM] = {196, 352, 440, 528};
7296 
rtw89_phy_dig_update_rssi_info(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7297 static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev,
7298 					   struct rtw89_bb_ctx *bb)
7299 {
7300 	struct rtw89_phy_ch_info *ch_info = &bb->ch_info;
7301 	struct rtw89_dig_info *dig = &bb->dig;
7302 	bool is_linked = rtwdev->total_sta_assoc > 0;
7303 
7304 	if (is_linked) {
7305 		dig->igi_rssi = ch_info->rssi_min >> 1;
7306 	} else {
7307 		rtw89_debug(rtwdev, RTW89_DBG_DIG, "RSSI update : NO Link\n");
7308 		dig->igi_rssi = rssi_nolink;
7309 	}
7310 }
7311 
rtw89_phy_dig_update_para(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7312 static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev,
7313 				      struct rtw89_bb_ctx *bb)
7314 {
7315 	struct rtw89_dig_info *dig = &bb->dig;
7316 	bool is_linked = rtwdev->total_sta_assoc > 0;
7317 	struct rtw89_entity_conf conf;
7318 	const struct rtw89_chan *chan;
7319 	const u16 *fa_th_src = NULL;
7320 
7321 	rtw89_entity_get_conf(rtwdev, &conf);
7322 	chan = conf.chans[bb->phy_idx];
7323 
7324 	switch (chan->band_type) {
7325 	case RTW89_BAND_2G:
7326 		dig->lna_gain = dig->lna_gain_g;
7327 		dig->tia_gain = dig->tia_gain_g;
7328 		fa_th_src = is_linked ? fa_th_2g : fa_th_nolink;
7329 		dig->force_gaincode_idx_en = false;
7330 		dig->dyn_pd_th_en = true;
7331 		break;
7332 	case RTW89_BAND_5G:
7333 	default:
7334 		dig->lna_gain = dig->lna_gain_a;
7335 		dig->tia_gain = dig->tia_gain_a;
7336 		fa_th_src = is_linked ? fa_th_5g : fa_th_nolink;
7337 		dig->force_gaincode_idx_en = true;
7338 		dig->dyn_pd_th_en = true;
7339 		break;
7340 	}
7341 	memcpy(dig->fa_th, fa_th_src, sizeof(dig->fa_th));
7342 	memcpy(dig->igi_rssi_th, igi_rssi_th, sizeof(dig->igi_rssi_th));
7343 }
7344 
7345 static const u8 pd_low_th_offset = 16, dynamic_igi_min = 0x20;
7346 static const u8 igi_max_performance_mode = 0x5a;
7347 static const u8 dynamic_pd_threshold_max;
7348 
rtw89_phy_dig_para_reset(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7349 static void rtw89_phy_dig_para_reset(struct rtw89_dev *rtwdev,
7350 				     struct rtw89_bb_ctx *bb)
7351 {
7352 	struct rtw89_dig_info *dig = &bb->dig;
7353 
7354 	dig->cur_gaincode.lna_idx = LNA_IDX_MAX;
7355 	dig->cur_gaincode.tia_idx = TIA_IDX_MAX;
7356 	dig->cur_gaincode.rxb_idx = RXB_IDX_MAX;
7357 	dig->force_gaincode.lna_idx = LNA_IDX_MAX;
7358 	dig->force_gaincode.tia_idx = TIA_IDX_MAX;
7359 	dig->force_gaincode.rxb_idx = RXB_IDX_MAX;
7360 
7361 	dig->dyn_igi_max = igi_max_performance_mode;
7362 	dig->dyn_igi_min = dynamic_igi_min;
7363 	dig->dyn_pd_th_max = dynamic_pd_threshold_max;
7364 	dig->dyn_pd_max_cnt = 0;
7365 	dig->pd_low_th_ofst = pd_low_th_offset;
7366 	dig->is_linked_pre = false;
7367 }
7368 
__rtw89_phy_dig_init(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7369 static void __rtw89_phy_dig_init(struct rtw89_dev *rtwdev,
7370 				 struct rtw89_bb_ctx *bb)
7371 {
7372 	rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig_init\n", bb->phy_idx);
7373 
7374 	rtw89_phy_dig_update_gain_para(rtwdev, bb);
7375 	rtw89_phy_dig_reset(rtwdev, bb);
7376 }
7377 
rtw89_phy_dig_init(struct rtw89_dev * rtwdev)7378 static void rtw89_phy_dig_init(struct rtw89_dev *rtwdev)
7379 {
7380 	struct rtw89_bb_ctx *bb;
7381 
7382 	rtw89_for_each_capab_bb(rtwdev, bb)
7383 		__rtw89_phy_dig_init(rtwdev, bb);
7384 }
7385 
rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 rssi)7386 static u8 rtw89_phy_dig_lna_idx_by_rssi(struct rtw89_dev *rtwdev,
7387 					struct rtw89_bb_ctx *bb, u8 rssi)
7388 {
7389 	struct rtw89_dig_info *dig = &bb->dig;
7390 	u8 lna_idx;
7391 
7392 	if (rssi < dig->igi_rssi_th[0])
7393 		lna_idx = RTW89_DIG_GAIN_LNA_IDX6;
7394 	else if (rssi < dig->igi_rssi_th[1])
7395 		lna_idx = RTW89_DIG_GAIN_LNA_IDX5;
7396 	else if (rssi < dig->igi_rssi_th[2])
7397 		lna_idx = RTW89_DIG_GAIN_LNA_IDX4;
7398 	else if (rssi < dig->igi_rssi_th[3])
7399 		lna_idx = RTW89_DIG_GAIN_LNA_IDX3;
7400 	else if (rssi < dig->igi_rssi_th[4])
7401 		lna_idx = RTW89_DIG_GAIN_LNA_IDX2;
7402 	else
7403 		lna_idx = RTW89_DIG_GAIN_LNA_IDX1;
7404 
7405 	return lna_idx;
7406 }
7407 
rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 rssi)7408 static u8 rtw89_phy_dig_tia_idx_by_rssi(struct rtw89_dev *rtwdev,
7409 					struct rtw89_bb_ctx *bb, u8 rssi)
7410 {
7411 	struct rtw89_dig_info *dig = &bb->dig;
7412 	u8 tia_idx;
7413 
7414 	if (rssi < dig->igi_rssi_th[0])
7415 		tia_idx = RTW89_DIG_GAIN_TIA_IDX1;
7416 	else
7417 		tia_idx = RTW89_DIG_GAIN_TIA_IDX0;
7418 
7419 	return tia_idx;
7420 }
7421 
7422 #define IB_PBK_BASE 110
7423 #define WB_RSSI_BASE 10
rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 rssi,struct rtw89_agc_gaincode_set * set)7424 static u8 rtw89_phy_dig_rxb_idx_by_rssi(struct rtw89_dev *rtwdev,
7425 					struct rtw89_bb_ctx *bb, u8 rssi,
7426 					struct rtw89_agc_gaincode_set *set)
7427 {
7428 	struct rtw89_dig_info *dig = &bb->dig;
7429 	s8 lna_gain = dig->lna_gain[set->lna_idx];
7430 	s8 tia_gain = dig->tia_gain[set->tia_idx];
7431 	s32 wb_rssi = rssi + lna_gain + tia_gain;
7432 	s32 rxb_idx_tmp = IB_PBK_BASE + WB_RSSI_BASE;
7433 	u8 rxb_idx;
7434 
7435 	rxb_idx_tmp += dig->ib_pkpwr - dig->ib_pbk - wb_rssi;
7436 	rxb_idx = clamp_t(s32, rxb_idx_tmp, RXB_IDX_MIN, RXB_IDX_MAX);
7437 
7438 	rtw89_debug(rtwdev, RTW89_DBG_DIG, "wb_rssi=%03d, rxb_idx_tmp=%03d\n",
7439 		    wb_rssi, rxb_idx_tmp);
7440 
7441 	return rxb_idx;
7442 }
7443 
rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 rssi,struct rtw89_agc_gaincode_set * set)7444 static void rtw89_phy_dig_gaincode_by_rssi(struct rtw89_dev *rtwdev,
7445 					   struct rtw89_bb_ctx *bb, u8 rssi,
7446 					   struct rtw89_agc_gaincode_set *set)
7447 {
7448 	set->lna_idx = rtw89_phy_dig_lna_idx_by_rssi(rtwdev, bb, rssi);
7449 	set->tia_idx = rtw89_phy_dig_tia_idx_by_rssi(rtwdev, bb, rssi);
7450 	set->rxb_idx = rtw89_phy_dig_rxb_idx_by_rssi(rtwdev, bb, rssi, set);
7451 
7452 	rtw89_debug(rtwdev, RTW89_DBG_DIG,
7453 		    "final_rssi=%03d, (lna,tia,rab)=(%d,%d,%02d)\n",
7454 		    rssi, set->lna_idx, set->tia_idx, set->rxb_idx);
7455 }
7456 
7457 #define IGI_OFFSET_MAX 25
7458 #define IGI_OFFSET_MUL 2
rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7459 static void rtw89_phy_dig_igi_offset_by_env(struct rtw89_dev *rtwdev,
7460 					    struct rtw89_bb_ctx *bb)
7461 {
7462 	struct rtw89_dig_info *dig = &bb->dig;
7463 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
7464 	enum rtw89_dig_noisy_level noisy_lv;
7465 	u8 igi_offset = dig->fa_rssi_ofst;
7466 	u16 fa_ratio = 0;
7467 
7468 	fa_ratio = env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil;
7469 
7470 	if (fa_ratio < dig->fa_th[0])
7471 		noisy_lv = RTW89_DIG_NOISY_LEVEL0;
7472 	else if (fa_ratio < dig->fa_th[1])
7473 		noisy_lv = RTW89_DIG_NOISY_LEVEL1;
7474 	else if (fa_ratio < dig->fa_th[2])
7475 		noisy_lv = RTW89_DIG_NOISY_LEVEL2;
7476 	else if (fa_ratio < dig->fa_th[3])
7477 		noisy_lv = RTW89_DIG_NOISY_LEVEL3;
7478 	else
7479 		noisy_lv = RTW89_DIG_NOISY_LEVEL_MAX;
7480 
7481 	if (noisy_lv == RTW89_DIG_NOISY_LEVEL0 && igi_offset < 2)
7482 		igi_offset = 0;
7483 	else
7484 		igi_offset += noisy_lv * IGI_OFFSET_MUL;
7485 
7486 	igi_offset = min_t(u8, igi_offset, IGI_OFFSET_MAX);
7487 	dig->fa_rssi_ofst = igi_offset;
7488 	dig->noisy_lv = noisy_lv;
7489 
7490 	rtw89_debug(rtwdev, RTW89_DBG_DIG,
7491 		    "fa_th: [+6 (%d) +4 (%d) +2 (%d) 0 (%d) -2 ]\n",
7492 		    dig->fa_th[3], dig->fa_th[2], dig->fa_th[1], dig->fa_th[0]);
7493 
7494 	rtw89_debug(rtwdev, RTW89_DBG_DIG,
7495 		    "fa(CCK,OFDM,ALL)=(%d,%d,%d)%%, noisy_lv=%d, ofst=%d\n",
7496 		    env->ifs_clm_cck_fa_permil, env->ifs_clm_ofdm_fa_permil,
7497 		    env->ifs_clm_cck_fa_permil + env->ifs_clm_ofdm_fa_permil,
7498 		    noisy_lv, igi_offset);
7499 }
7500 
rtw89_phy_dig_set_lna_idx(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 lna_idx)7501 static void rtw89_phy_dig_set_lna_idx(struct rtw89_dev *rtwdev,
7502 				      struct rtw89_bb_ctx *bb, u8 lna_idx)
7503 {
7504 	const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
7505 
7506 	rtw89_phy_write32_idx(rtwdev, dig_regs->p0_lna_init.addr,
7507 			      dig_regs->p0_lna_init.mask, lna_idx, bb->phy_idx);
7508 	rtw89_phy_write32_idx(rtwdev, dig_regs->p1_lna_init.addr,
7509 			      dig_regs->p1_lna_init.mask, lna_idx, bb->phy_idx);
7510 }
7511 
rtw89_phy_dig_set_tia_idx(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 tia_idx)7512 static void rtw89_phy_dig_set_tia_idx(struct rtw89_dev *rtwdev,
7513 				      struct rtw89_bb_ctx *bb, u8 tia_idx)
7514 {
7515 	const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
7516 
7517 	rtw89_phy_write32_idx(rtwdev, dig_regs->p0_tia_init.addr,
7518 			      dig_regs->p0_tia_init.mask, tia_idx, bb->phy_idx);
7519 	rtw89_phy_write32_idx(rtwdev, dig_regs->p1_tia_init.addr,
7520 			      dig_regs->p1_tia_init.mask, tia_idx, bb->phy_idx);
7521 }
7522 
rtw89_phy_dig_set_rxb_idx(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 rxb_idx)7523 static void rtw89_phy_dig_set_rxb_idx(struct rtw89_dev *rtwdev,
7524 				      struct rtw89_bb_ctx *bb, u8 rxb_idx)
7525 {
7526 	const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
7527 
7528 	rtw89_phy_write32_idx(rtwdev, dig_regs->p0_rxb_init.addr,
7529 			      dig_regs->p0_rxb_init.mask, rxb_idx, bb->phy_idx);
7530 	rtw89_phy_write32_idx(rtwdev, dig_regs->p1_rxb_init.addr,
7531 			      dig_regs->p1_rxb_init.mask, rxb_idx, bb->phy_idx);
7532 }
7533 
rtw89_phy_dig_set_igi_cr(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,const struct rtw89_agc_gaincode_set set)7534 static void rtw89_phy_dig_set_igi_cr(struct rtw89_dev *rtwdev,
7535 				     struct rtw89_bb_ctx *bb,
7536 				     const struct rtw89_agc_gaincode_set set)
7537 {
7538 	if (!rtwdev->hal.support_igi)
7539 		return;
7540 
7541 	rtw89_phy_dig_set_lna_idx(rtwdev, bb, set.lna_idx);
7542 	rtw89_phy_dig_set_tia_idx(rtwdev, bb, set.tia_idx);
7543 	rtw89_phy_dig_set_rxb_idx(rtwdev, bb, set.rxb_idx);
7544 
7545 	rtw89_debug(rtwdev, RTW89_DBG_DIG, "Set (lna,tia,rxb)=((%d,%d,%02d))\n",
7546 		    set.lna_idx, set.tia_idx, set.rxb_idx);
7547 }
7548 
rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,bool enable)7549 static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev,
7550 						   struct rtw89_bb_ctx *bb,
7551 						   bool enable)
7552 {
7553 	const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
7554 
7555 	if (rtwdev->chip->chip_gen != RTW89_CHIP_AX)
7556 		return;
7557 
7558 	rtw89_phy_write32_idx(rtwdev, dig_regs->p0_p20_pagcugc_en.addr,
7559 			      dig_regs->p0_p20_pagcugc_en.mask, enable, bb->phy_idx);
7560 	rtw89_phy_write32_idx(rtwdev, dig_regs->p0_s20_pagcugc_en.addr,
7561 			      dig_regs->p0_s20_pagcugc_en.mask, enable, bb->phy_idx);
7562 	rtw89_phy_write32_idx(rtwdev, dig_regs->p1_p20_pagcugc_en.addr,
7563 			      dig_regs->p1_p20_pagcugc_en.mask, enable, bb->phy_idx);
7564 	rtw89_phy_write32_idx(rtwdev, dig_regs->p1_s20_pagcugc_en.addr,
7565 			      dig_regs->p1_s20_pagcugc_en.mask, enable, bb->phy_idx);
7566 
7567 	rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable);
7568 }
7569 
rtw89_phy_dig_config_igi(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7570 static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev,
7571 				     struct rtw89_bb_ctx *bb)
7572 {
7573 	struct rtw89_dig_info *dig = &bb->dig;
7574 
7575 	if (!rtwdev->hal.support_igi)
7576 		return;
7577 
7578 	if (dig->force_gaincode_idx_en) {
7579 		rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode);
7580 		rtw89_debug(rtwdev, RTW89_DBG_DIG,
7581 			    "Force gaincode index enabled.\n");
7582 	} else {
7583 		rtw89_phy_dig_gaincode_by_rssi(rtwdev, bb, dig->igi_fa_rssi,
7584 					       &dig->cur_gaincode);
7585 		rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->cur_gaincode);
7586 	}
7587 }
7588 
rtw89_phy_dig_cal_under_region(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,const struct rtw89_chan * chan)7589 static u8 rtw89_phy_dig_cal_under_region(struct rtw89_dev *rtwdev,
7590 					 struct rtw89_bb_ctx *bb,
7591 					 const struct rtw89_chan *chan)
7592 {
7593 	enum rtw89_bandwidth cbw = chan->band_width;
7594 	struct rtw89_dig_info *dig = &bb->dig;
7595 	u8 under_region = dig->pd_low_th_ofst;
7596 
7597 	if (rtwdev->chip->chip_gen == RTW89_CHIP_AX)
7598 		under_region += PD_TH_SB_FLTR_CMP_VAL;
7599 
7600 	switch (cbw) {
7601 	case RTW89_CHANNEL_WIDTH_40:
7602 		under_region += PD_TH_BW40_CMP_VAL;
7603 		break;
7604 	case RTW89_CHANNEL_WIDTH_80:
7605 		under_region += PD_TH_BW80_CMP_VAL;
7606 		break;
7607 	case RTW89_CHANNEL_WIDTH_160:
7608 		under_region += PD_TH_BW160_CMP_VAL;
7609 		break;
7610 	case RTW89_CHANNEL_WIDTH_20:
7611 		fallthrough;
7612 	default:
7613 		under_region += PD_TH_BW20_CMP_VAL;
7614 		break;
7615 	}
7616 
7617 	return under_region;
7618 }
7619 
__rtw89_phy_dig_dyn_pd_th(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 rssi,bool enable,const struct rtw89_chan * chan)7620 static u32 __rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
7621 				     struct rtw89_bb_ctx *bb,
7622 				     u8 rssi, bool enable,
7623 				     const struct rtw89_chan *chan)
7624 {
7625 	struct rtw89_dig_info *dig = &bb->dig;
7626 	u8 ofdm_cca_th, under_region;
7627 	u8 final_rssi;
7628 	u32 pd_val;
7629 
7630 	under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan);
7631 	dig->dyn_pd_th_max = dig->igi_rssi;
7632 
7633 	final_rssi = min_t(u8, rssi, dig->igi_rssi);
7634 	ofdm_cca_th = clamp_t(u8, final_rssi, PD_TH_MIN_RSSI + under_region,
7635 			      PD_TH_MAX_RSSI + under_region);
7636 
7637 	if (enable) {
7638 		pd_val = (ofdm_cca_th - under_region - PD_TH_MIN_RSSI) >> 1;
7639 		rtw89_debug(rtwdev, RTW89_DBG_DIG,
7640 			    "igi=%d, ofdm_ccaTH=%d, backoff=%d, PD_low=%d\n",
7641 			    final_rssi, ofdm_cca_th, under_region, pd_val);
7642 	} else {
7643 		pd_val = 0;
7644 		rtw89_debug(rtwdev, RTW89_DBG_DIG,
7645 			    "Dynamic PD th disabled, Set PD_low_bd=0\n");
7646 	}
7647 
7648 	return pd_val;
7649 }
7650 
rtw89_phy_dig_dyn_pd_th(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,u8 rssi,bool enable)7651 static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev,
7652 				    struct rtw89_bb_ctx *bb,
7653 				    u8 rssi, bool enable)
7654 {
7655 	const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
7656 	struct rtw89_dig_info *dig = &bb->dig;
7657 	struct rtw89_hal *hal = &rtwdev->hal;
7658 	u8 final_rssi, under_region = dig->pd_low_th_ofst;
7659 	struct rtw89_entity_conf conf;
7660 	const struct rtw89_chan *chan;
7661 	s8 cck_cca_th;
7662 	u32 pd_val;
7663 
7664 	rtw89_entity_get_conf(rtwdev, &conf);
7665 	chan = conf.chans[bb->phy_idx];
7666 
7667 	if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) {
7668 		pd_val = hal->fixed_dig_pd_th;
7669 
7670 		rtw89_debug(rtwdev, RTW89_DBG_DIG,
7671 			    "Fixed DIG: PD_low=%d\n", pd_val);
7672 	} else {
7673 		pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi, enable, chan);
7674 	}
7675 	dig->bak_dig = pd_val;
7676 
7677 	rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
7678 			      dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx);
7679 	rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
7680 			      dig_regs->pd_spatial_reuse_en, enable, bb->phy_idx);
7681 
7682 	if (!hal->support_cckpd)
7683 		return;
7684 
7685 	if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) {
7686 		pd_val = hal->fixed_dig_cck_pd_th;
7687 
7688 		rtw89_debug(rtwdev, RTW89_DBG_DIG,
7689 			    "Fixed DIG: cck_PD_low=((%d))dB\n", pd_val);
7690 	} else {
7691 		final_rssi = min_t(u8, rssi, dig->igi_rssi);
7692 		under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan);
7693 		cck_cca_th = max_t(s8, final_rssi - under_region, CCKPD_TH_MIN_RSSI);
7694 		pd_val = (u32)(cck_cca_th - IGI_RSSI_MAX);
7695 
7696 		rtw89_debug(rtwdev, RTW89_DBG_DIG,
7697 			    "igi=%d, cck_ccaTH=%d, backoff=%d, cck_PD_low=((%d))dB\n",
7698 			    final_rssi, cck_cca_th, under_region, pd_val);
7699 	}
7700 
7701 	rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_reg,
7702 			      dig_regs->bmode_cca_rssi_limit_en, enable, bb->phy_idx);
7703 	rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_lower_bound_reg,
7704 			      dig_regs->bmode_rssi_nocca_low_th_mask, pd_val, bb->phy_idx);
7705 }
7706 
rtw89_phy_dig_reset(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7707 void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
7708 {
7709 	struct rtw89_dig_info *dig = &bb->dig;
7710 
7711 	dig->bypass_dig = false;
7712 	rtw89_phy_dig_para_reset(rtwdev, bb);
7713 	rtw89_phy_dig_set_igi_cr(rtwdev, bb, dig->force_gaincode);
7714 	rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi_nolink, false);
7715 	rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false);
7716 	rtw89_phy_dig_update_para(rtwdev, bb);
7717 }
7718 
rtw89_phy_dig_diag(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,bool is_linked)7719 static void rtw89_phy_dig_diag(struct rtw89_dev *rtwdev,
7720 			       struct rtw89_bb_ctx *bb, bool is_linked)
7721 {
7722 #define RTW89_DIAG_BB_PD_MAX_PERIOD 5
7723 	struct rtw89_diag_bb *diag = &bb->diag;
7724 	struct rtw89_dig_info *dig = &bb->dig;
7725 
7726 	diag->diag_bb_bitmap &= ~BIT(RTW89_DIAG_BB_PD);
7727 
7728 	if (dig->dyn_igi_max != dig->igi_fa_rssi ||
7729 	    dig->noisy_lv < RTW89_DIG_NOISY_LEVEL_MAX) {
7730 		dig->dyn_pd_max_cnt = 0;
7731 		return;
7732 	}
7733 
7734 	if (++dig->dyn_pd_max_cnt < RTW89_DIAG_BB_PD_MAX_PERIOD || !is_linked)
7735 		return;
7736 
7737 	diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_PD);
7738 	diag->diag_bb_cnt[RTW89_DIAG_BB_PD]++;
7739 }
7740 
7741 #define IGI_RSSI_MIN 10
7742 #define ABS_IGI_MIN 0xc
7743 static
rtw89_phy_cal_igi_fa_rssi(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,bool is_linked)7744 void rtw89_phy_cal_igi_fa_rssi(struct rtw89_dev *rtwdev,
7745 			       struct rtw89_bb_ctx *bb, bool is_linked)
7746 {
7747 	struct rtw89_dig_info *dig = &bb->dig;
7748 	u8 igi_min;
7749 
7750 	rtw89_phy_dig_igi_offset_by_env(rtwdev, bb);
7751 
7752 	igi_min = max_t(int, dig->igi_rssi - IGI_RSSI_MIN, 0);
7753 	dig->dyn_igi_max = min(igi_min + IGI_OFFSET_MAX, igi_max_performance_mode);
7754 	dig->dyn_igi_min = max(igi_min, ABS_IGI_MIN);
7755 
7756 	if (dig->dyn_igi_max >= dig->dyn_igi_min) {
7757 		dig->igi_fa_rssi += dig->fa_rssi_ofst;
7758 		dig->igi_fa_rssi = clamp(dig->igi_fa_rssi, dig->dyn_igi_min,
7759 					 dig->dyn_igi_max);
7760 	} else {
7761 		dig->igi_fa_rssi = dig->dyn_igi_max;
7762 	}
7763 
7764 	rtw89_phy_dig_diag(rtwdev, bb, is_linked);
7765 }
7766 
7767 struct rtw89_phy_iter_mcc_dig {
7768 	struct rtw89_vif_link *rtwvif_link;
7769 	bool has_sta;
7770 	u8 rssi_min;
7771 };
7772 
rtw89_phy_set_mcc_dig(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link,struct rtw89_bb_ctx * bb,u8 rssi_min,u8 mcc_role_idx,bool is_linked)7773 static void rtw89_phy_set_mcc_dig(struct rtw89_dev *rtwdev,
7774 				  struct rtw89_vif_link *rtwvif_link,
7775 				  struct rtw89_bb_ctx *bb,
7776 				  u8 rssi_min, u8 mcc_role_idx,
7777 				  bool is_linked)
7778 {
7779 	struct rtw89_dig_info *dig = &bb->dig;
7780 	const struct rtw89_chan *chan;
7781 	u8 pd_val;
7782 
7783 	if (is_linked) {
7784 		dig->igi_rssi = rssi_min >> 1;
7785 		dig->igi_fa_rssi = dig->igi_rssi;
7786 	} else {
7787 		rtw89_debug(rtwdev, RTW89_DBG_DIG, "RSSI update : NO Link\n");
7788 		dig->igi_rssi = rssi_nolink;
7789 		dig->igi_fa_rssi = dig->igi_rssi;
7790 	}
7791 
7792 	chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
7793 	rtw89_phy_cal_igi_fa_rssi(rtwdev, bb, is_linked);
7794 	pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, dig->igi_fa_rssi,
7795 					   is_linked, chan);
7796 	rtw89_fw_h2c_mcc_dig(rtwdev, rtwvif_link->chanctx_idx,
7797 			     mcc_role_idx, pd_val, true);
7798 
7799 	rtw89_debug(rtwdev, RTW89_DBG_DIG,
7800 		    "MCC chanctx_idx %d chan %d rssi %d pd_val %d",
7801 		    rtwvif_link->chanctx_idx, chan->primary_channel,
7802 		    dig->igi_rssi, pd_val);
7803 }
7804 
rtw89_phy_set_mcc_dig_iter(void * data,struct ieee80211_sta * sta)7805 static void rtw89_phy_set_mcc_dig_iter(void *data, struct ieee80211_sta *sta)
7806 {
7807 	struct rtw89_phy_iter_mcc_dig *mcc_dig = (struct rtw89_phy_iter_mcc_dig *)data;
7808 	unsigned int link_id = mcc_dig->rtwvif_link->link_id;
7809 	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
7810 	struct rtw89_sta_link *rtwsta_link;
7811 
7812 	if (rtwsta->rtwvif != mcc_dig->rtwvif_link->rtwvif)
7813 		return;
7814 
7815 	rtwsta_link = rtwsta->links[link_id];
7816 	if (!rtwsta_link)
7817 		return;
7818 
7819 	mcc_dig->has_sta = true;
7820 	if (ewma_rssi_read(&rtwsta_link->avg_rssi) < mcc_dig->rssi_min)
7821 		mcc_dig->rssi_min = ewma_rssi_read(&rtwsta_link->avg_rssi);
7822 }
7823 
rtw89_phy_dig_mcc(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7824 static void rtw89_phy_dig_mcc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
7825 {
7826 	struct rtw89_phy_iter_mcc_dig mcc_dig;
7827 	struct rtw89_vif_link *rtwvif_link;
7828 	struct rtw89_mcc_links_info info;
7829 	int i;
7830 
7831 	rtw89_mcc_get_links(rtwdev, &info);
7832 	for (i = 0; i < ARRAY_SIZE(info.links); i++) {
7833 		rtwvif_link = info.links[i];
7834 		if (!rtwvif_link)
7835 			continue;
7836 
7837 		memset(&mcc_dig, 0, sizeof(mcc_dig));
7838 		mcc_dig.rtwvif_link = rtwvif_link;
7839 		mcc_dig.has_sta = false;
7840 		mcc_dig.rssi_min = U8_MAX;
7841 		ieee80211_iterate_stations_atomic(rtwdev->hw,
7842 						  rtw89_phy_set_mcc_dig_iter,
7843 						  &mcc_dig);
7844 
7845 		rtw89_phy_set_mcc_dig(rtwdev, rtwvif_link, bb,
7846 				      mcc_dig.rssi_min, i, mcc_dig.has_sta);
7847 	}
7848 }
7849 
rtw89_phy_dig_ctrl(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,bool pause_dig,bool restore)7850 static void rtw89_phy_dig_ctrl(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb,
7851 			       bool pause_dig, bool restore)
7852 {
7853 	const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
7854 	struct rtw89_dig_info *dig = &bb->dig;
7855 	struct rtw89_hal *hal = &rtwdev->hal;
7856 	bool en_dig;
7857 	u32 pd_val;
7858 
7859 	if (dig->pause_dig == pause_dig)
7860 		return;
7861 
7862 	if (pause_dig) {
7863 		en_dig = false;
7864 		if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD))
7865 			pd_val = hal->fixed_dig_pd_th;
7866 		else
7867 			pd_val = 0;
7868 	} else {
7869 		en_dig = rtwdev->total_sta_assoc > 0;
7870 		if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD))
7871 			pd_val = hal->fixed_dig_pd_th;
7872 		else
7873 			pd_val = restore ? dig->bak_dig : 0;
7874 	}
7875 
7876 	rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s <%s> PD_low=%d", __func__,
7877 		    pause_dig ? "suspend" : "resume", pd_val);
7878 
7879 	rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
7880 			      dig_regs->pd_lower_bound_mask, pd_val, bb->phy_idx);
7881 	rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
7882 			      dig_regs->pd_spatial_reuse_en, en_dig, bb->phy_idx);
7883 
7884 	dig->pause_dig = pause_dig;
7885 }
7886 
rtw89_phy_dig_suspend(struct rtw89_dev * rtwdev)7887 void rtw89_phy_dig_suspend(struct rtw89_dev *rtwdev)
7888 {
7889 	struct rtw89_bb_ctx *bb;
7890 
7891 	rtw89_for_each_active_bb(rtwdev, bb)
7892 		rtw89_phy_dig_ctrl(rtwdev, bb, true, false);
7893 }
7894 
rtw89_phy_dig_resume(struct rtw89_dev * rtwdev,bool restore)7895 void rtw89_phy_dig_resume(struct rtw89_dev *rtwdev, bool restore)
7896 {
7897 	struct rtw89_bb_ctx *bb;
7898 
7899 	rtw89_for_each_active_bb(rtwdev, bb)
7900 		rtw89_phy_dig_ctrl(rtwdev, bb, false, restore);
7901 }
7902 
__rtw89_phy_dig(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)7903 static void __rtw89_phy_dig(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
7904 {
7905 	struct rtw89_dig_info *dig = &bb->dig;
7906 	bool is_linked = rtwdev->total_sta_assoc > 0;
7907 	enum rtw89_entity_mode mode;
7908 
7909 	if (unlikely(dig->bypass_dig)) {
7910 		dig->bypass_dig = false;
7911 		return;
7912 	}
7913 
7914 	rtw89_debug(rtwdev, RTW89_DBG_DIG, "BB-%d dig track\n", bb->phy_idx);
7915 
7916 	rtw89_phy_dig_update_rssi_info(rtwdev, bb);
7917 
7918 	mode = rtw89_get_entity_mode(rtwdev);
7919 	if (mode == RTW89_ENTITY_MODE_MCC) {
7920 		rtw89_phy_dig_mcc(rtwdev, bb);
7921 		return;
7922 	}
7923 
7924 	if (unlikely(dig->pause_dig))
7925 		return;
7926 
7927 	if (!dig->is_linked_pre && is_linked) {
7928 		rtw89_debug(rtwdev, RTW89_DBG_DIG, "First connected\n");
7929 		rtw89_phy_dig_update_para(rtwdev, bb);
7930 		dig->igi_fa_rssi = dig->igi_rssi;
7931 	} else if (dig->is_linked_pre && !is_linked) {
7932 		rtw89_debug(rtwdev, RTW89_DBG_DIG, "First disconnected\n");
7933 		rtw89_phy_dig_update_para(rtwdev, bb);
7934 		dig->igi_fa_rssi = dig->igi_rssi;
7935 	}
7936 	dig->is_linked_pre = is_linked;
7937 
7938 	rtw89_phy_cal_igi_fa_rssi(rtwdev, bb, is_linked);
7939 
7940 	rtw89_debug(rtwdev, RTW89_DBG_DIG,
7941 		    "rssi=%03d, dyn_joint(max,min)=(%d,%d), final_rssi=%d\n",
7942 		    dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min,
7943 		    dig->igi_fa_rssi);
7944 
7945 	rtw89_phy_dig_config_igi(rtwdev, bb);
7946 
7947 	rtw89_phy_dig_dyn_pd_th(rtwdev, bb, dig->igi_fa_rssi, dig->dyn_pd_th_en);
7948 
7949 	if (dig->dyn_pd_th_en && dig->igi_fa_rssi > dig->dyn_pd_th_max)
7950 		rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, true);
7951 	else
7952 		rtw89_phy_dig_sdagc_follow_pagc_config(rtwdev, bb, false);
7953 }
7954 
rtw89_phy_dig(struct rtw89_dev * rtwdev)7955 void rtw89_phy_dig(struct rtw89_dev *rtwdev)
7956 {
7957 	struct rtw89_bb_ctx *bb;
7958 
7959 	rtw89_for_each_active_bb(rtwdev, bb)
7960 		__rtw89_phy_dig(rtwdev, bb);
7961 }
7962 
__rtw89_phy_tx_path_div_sta_iter(struct rtw89_dev * rtwdev,struct rtw89_sta_link * rtwsta_link)7963 static void __rtw89_phy_tx_path_div_sta_iter(struct rtw89_dev *rtwdev,
7964 					     struct rtw89_sta_link *rtwsta_link)
7965 {
7966 	struct rtw89_hal *hal = &rtwdev->hal;
7967 	u8 rssi_a, rssi_b;
7968 	u32 candidate;
7969 
7970 	rssi_a = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_A]);
7971 	rssi_b = ewma_rssi_read(&rtwsta_link->rssi[RF_PATH_B]);
7972 
7973 	if (rssi_a > rssi_b + RTW89_TX_DIV_RSSI_RAW_TH)
7974 		candidate = RF_A;
7975 	else if (rssi_b > rssi_a + RTW89_TX_DIV_RSSI_RAW_TH)
7976 		candidate = RF_B;
7977 	else
7978 		return;
7979 
7980 	if (hal->antenna_tx == candidate)
7981 		return;
7982 
7983 	hal->antenna_tx = candidate;
7984 	rtw89_fw_h2c_txpath_cmac_tbl(rtwdev, rtwsta_link);
7985 
7986 	if (hal->antenna_tx == RF_A) {
7987 		rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, B_P0_RFMODE_MUX, 0x12);
7988 		rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, B_P1_RFMODE_MUX, 0x11);
7989 	} else if (hal->antenna_tx == RF_B) {
7990 		rtw89_phy_write32_mask(rtwdev, R_P0_RFMODE, B_P0_RFMODE_MUX, 0x11);
7991 		rtw89_phy_write32_mask(rtwdev, R_P1_RFMODE, B_P1_RFMODE_MUX, 0x12);
7992 	}
7993 }
7994 
rtw89_phy_tx_path_div_sta_iter(void * data,struct ieee80211_sta * sta)7995 static void rtw89_phy_tx_path_div_sta_iter(void *data, struct ieee80211_sta *sta)
7996 {
7997 	struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
7998 	struct rtw89_dev *rtwdev = rtwsta->rtwdev;
7999 	struct rtw89_vif *rtwvif = rtwsta->rtwvif;
8000 	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
8001 	struct rtw89_vif_link *rtwvif_link;
8002 	struct rtw89_sta_link *rtwsta_link;
8003 	unsigned int link_id;
8004 	bool *done = data;
8005 
8006 	if (WARN(ieee80211_vif_is_mld(vif), "MLD mix path_div\n"))
8007 		return;
8008 
8009 	if (sta->tdls)
8010 		return;
8011 
8012 	if (*done)
8013 		return;
8014 
8015 	rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
8016 		rtwvif_link = rtwsta_link->rtwvif_link;
8017 		if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION)
8018 			continue;
8019 
8020 		*done = true;
8021 		__rtw89_phy_tx_path_div_sta_iter(rtwdev, rtwsta_link);
8022 		return;
8023 	}
8024 }
8025 
rtw89_phy_tx_path_div_track(struct rtw89_dev * rtwdev)8026 void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev)
8027 {
8028 	struct rtw89_hal *hal = &rtwdev->hal;
8029 	bool done = false;
8030 
8031 	if (!hal->tx_path_diversity)
8032 		return;
8033 
8034 	ieee80211_iterate_stations_atomic(rtwdev->hw,
8035 					  rtw89_phy_tx_path_div_sta_iter,
8036 					  &done);
8037 }
8038 
8039 #define ANTDIV_MAIN 0
8040 #define ANTDIV_AUX 1
8041 
rtw89_phy_antdiv_set_ant(struct rtw89_dev * rtwdev)8042 static void rtw89_phy_antdiv_set_ant(struct rtw89_dev *rtwdev)
8043 {
8044 	struct rtw89_hal *hal = &rtwdev->hal;
8045 	u8 default_ant, optional_ant;
8046 
8047 	if (!hal->ant_diversity || hal->antenna_tx == 0)
8048 		return;
8049 
8050 	if (hal->antenna_tx == RF_B) {
8051 		default_ant = ANTDIV_AUX;
8052 		optional_ant = ANTDIV_MAIN;
8053 	} else {
8054 		default_ant = ANTDIV_MAIN;
8055 		optional_ant = ANTDIV_AUX;
8056 	}
8057 
8058 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_CGCS_CTRL,
8059 			      default_ant, RTW89_PHY_0);
8060 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_RX_ORI,
8061 			      default_ant, RTW89_PHY_0);
8062 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_RX_ALT,
8063 			      optional_ant, RTW89_PHY_0);
8064 	rtw89_phy_write32_idx(rtwdev, R_P0_ANTSEL, B_P0_ANTSEL_TX_ORI,
8065 			      default_ant, RTW89_PHY_0);
8066 }
8067 
rtw89_phy_swap_hal_antenna(struct rtw89_dev * rtwdev)8068 static void rtw89_phy_swap_hal_antenna(struct rtw89_dev *rtwdev)
8069 {
8070 	struct rtw89_hal *hal = &rtwdev->hal;
8071 
8072 	hal->antenna_rx = hal->antenna_rx == RF_A ? RF_B : RF_A;
8073 	hal->antenna_tx = hal->antenna_rx;
8074 }
8075 
rtw89_phy_antdiv_decision_state(struct rtw89_dev * rtwdev)8076 static void rtw89_phy_antdiv_decision_state(struct rtw89_dev *rtwdev)
8077 {
8078 	struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
8079 	struct rtw89_hal *hal = &rtwdev->hal;
8080 	bool no_change = false;
8081 	u8 main_rssi, aux_rssi;
8082 	u8 main_evm, aux_evm;
8083 	u32 candidate;
8084 
8085 	antdiv->get_stats = false;
8086 	antdiv->training_count = 0;
8087 
8088 	main_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->main_stats);
8089 	main_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->main_stats);
8090 	aux_rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->aux_stats);
8091 	aux_evm = rtw89_phy_antdiv_sts_instance_get_evm(&antdiv->aux_stats);
8092 
8093 	if (main_evm > aux_evm + ANTDIV_EVM_DIFF_TH)
8094 		candidate = RF_A;
8095 	else if (aux_evm > main_evm + ANTDIV_EVM_DIFF_TH)
8096 		candidate = RF_B;
8097 	else if (main_rssi > aux_rssi + RTW89_TX_DIV_RSSI_RAW_TH)
8098 		candidate = RF_A;
8099 	else if (aux_rssi > main_rssi + RTW89_TX_DIV_RSSI_RAW_TH)
8100 		candidate = RF_B;
8101 	else
8102 		no_change = true;
8103 
8104 	if (no_change) {
8105 		/* swap back from training antenna to original */
8106 		rtw89_phy_swap_hal_antenna(rtwdev);
8107 		return;
8108 	}
8109 
8110 	hal->antenna_tx = candidate;
8111 	hal->antenna_rx = candidate;
8112 }
8113 
rtw89_phy_antdiv_training_state(struct rtw89_dev * rtwdev)8114 static void rtw89_phy_antdiv_training_state(struct rtw89_dev *rtwdev)
8115 {
8116 	struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
8117 	u64 state_period;
8118 
8119 	if (antdiv->training_count % 2 == 0) {
8120 		if (antdiv->training_count == 0)
8121 			rtw89_phy_antdiv_sts_reset(rtwdev);
8122 
8123 		antdiv->get_stats = true;
8124 		state_period = msecs_to_jiffies(ANTDIV_TRAINNING_INTVL);
8125 	} else {
8126 		antdiv->get_stats = false;
8127 		state_period = msecs_to_jiffies(ANTDIV_DELAY);
8128 
8129 		rtw89_phy_swap_hal_antenna(rtwdev);
8130 		rtw89_phy_antdiv_set_ant(rtwdev);
8131 	}
8132 
8133 	antdiv->training_count++;
8134 	wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work,
8135 				 state_period);
8136 }
8137 
rtw89_phy_antdiv_work(struct wiphy * wiphy,struct wiphy_work * work)8138 void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work)
8139 {
8140 	struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
8141 						antdiv_work.work);
8142 	struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
8143 
8144 	lockdep_assert_wiphy(wiphy);
8145 
8146 	if (antdiv->training_count <= ANTDIV_TRAINNING_CNT) {
8147 		rtw89_phy_antdiv_training_state(rtwdev);
8148 	} else {
8149 		rtw89_phy_antdiv_decision_state(rtwdev);
8150 		rtw89_phy_antdiv_set_ant(rtwdev);
8151 	}
8152 }
8153 
rtw89_phy_antdiv_track(struct rtw89_dev * rtwdev)8154 void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev)
8155 {
8156 	struct rtw89_antdiv_info *antdiv = &rtwdev->antdiv;
8157 	struct rtw89_hal *hal = &rtwdev->hal;
8158 	u8 rssi, rssi_pre;
8159 
8160 	if (!hal->ant_diversity || hal->ant_diversity_fixed)
8161 		return;
8162 
8163 	rssi = rtw89_phy_antdiv_sts_instance_get_rssi(&antdiv->target_stats);
8164 	rssi_pre = antdiv->rssi_pre;
8165 	antdiv->rssi_pre = rssi;
8166 	rtw89_phy_antdiv_sts_instance_reset(&antdiv->target_stats);
8167 
8168 	if (abs((int)rssi - (int)rssi_pre) < ANTDIV_RSSI_DIFF_TH)
8169 		return;
8170 
8171 	antdiv->training_count = 0;
8172 	wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->antdiv_work, 0);
8173 }
8174 
__rtw89_phy_env_monitor_init(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8175 static void __rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev,
8176 					 struct rtw89_bb_ctx *bb)
8177 {
8178 	rtw89_debug(rtwdev, RTW89_DBG_PHY_TRACK,
8179 		    "BB-%d env_monitor init\n", bb->phy_idx);
8180 
8181 	rtw89_phy_ccx_top_setting_init(rtwdev, bb);
8182 	rtw89_phy_ifs_clm_setting_init(rtwdev, bb);
8183 }
8184 
rtw89_phy_env_monitor_init(struct rtw89_dev * rtwdev)8185 static void rtw89_phy_env_monitor_init(struct rtw89_dev *rtwdev)
8186 {
8187 	struct rtw89_bb_ctx *bb;
8188 
8189 	rtw89_for_each_capab_bb(rtwdev, bb)
8190 		__rtw89_phy_env_monitor_init(rtwdev, bb);
8191 }
8192 
rtw89_phy_diag_init(struct rtw89_dev * rtwdev)8193 static void rtw89_phy_diag_init(struct rtw89_dev *rtwdev)
8194 {
8195 	struct rtw89_bb_ctx *bb;
8196 
8197 	rtw89_for_each_capab_bb(rtwdev, bb)
8198 		memset(&bb->diag, 0, sizeof(bb->diag));
8199 }
8200 
__rtw89_phy_edcca_init(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8201 static void __rtw89_phy_edcca_init(struct rtw89_dev *rtwdev,
8202 				   struct rtw89_bb_ctx *bb)
8203 {
8204 	const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
8205 	struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak;
8206 
8207 	rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca init\n", bb->phy_idx);
8208 
8209 	memset(edcca_bak, 0, sizeof(*edcca_bak));
8210 
8211 	if (rtwdev->chip->chip_id == RTL8922A && rtwdev->hal.cv == CHIP_CAV) {
8212 		rtw89_phy_set_phy_regs(rtwdev, R_TXGATING, B_TXGATING_EN, 0);
8213 		rtw89_phy_set_phy_regs(rtwdev, R_CTLTOP, B_CTLTOP_VAL, 2);
8214 		rtw89_phy_set_phy_regs(rtwdev, R_CTLTOP, B_CTLTOP_ON, 1);
8215 		rtw89_phy_set_phy_regs(rtwdev, R_SPOOF_CG, B_SPOOF_CG_EN, 0);
8216 		rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_CG_EN, 0);
8217 		rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 0);
8218 		rtw89_phy_set_phy_regs(rtwdev, R_SEGSND, B_SEGSND_EN, 0);
8219 		rtw89_phy_set_phy_regs(rtwdev, R_SEGSND, B_SEGSND_EN, 1);
8220 		rtw89_phy_set_phy_regs(rtwdev, R_DFS_FFT_CG, B_DFS_FFT_EN, 1);
8221 	}
8222 
8223 	rtw89_phy_write32_idx(rtwdev, edcca_regs->tx_collision_t2r_st,
8224 			      edcca_regs->tx_collision_t2r_st_mask, 0x29, bb->phy_idx);
8225 }
8226 
rtw89_phy_edcca_init(struct rtw89_dev * rtwdev)8227 static void rtw89_phy_edcca_init(struct rtw89_dev *rtwdev)
8228 {
8229 	struct rtw89_bb_ctx *bb;
8230 
8231 	rtw89_for_each_capab_bb(rtwdev, bb)
8232 		__rtw89_phy_edcca_init(rtwdev, bb);
8233 }
8234 
rtw89_phy_dm_init(struct rtw89_dev * rtwdev)8235 void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
8236 {
8237 	rtw89_phy_stat_init(rtwdev);
8238 
8239 	rtw89_chip_bb_sethw(rtwdev);
8240 
8241 	rtw89_phy_diag_init(rtwdev);
8242 	rtw89_phy_env_monitor_init(rtwdev);
8243 	rtw89_phy_nhm_setting_init(rtwdev);
8244 	rtw89_physts_parsing_init(rtwdev);
8245 	rtw89_phy_dig_init(rtwdev);
8246 	rtw89_phy_cfo_init(rtwdev);
8247 	rtw89_phy_bb_wrap_init(rtwdev);
8248 	rtw89_phy_edcca_init(rtwdev);
8249 	rtw89_phy_ch_info_init(rtwdev);
8250 	rtw89_phy_ul_tb_info_init(rtwdev);
8251 	rtw89_phy_antdiv_init(rtwdev);
8252 	rtw89_chip_rfe_gpio(rtwdev);
8253 	rtw89_phy_antdiv_set_ant(rtwdev);
8254 
8255 	rtw89_chip_rfk_hw_init(rtwdev);
8256 	rtw89_phy_init_rf_nctl(rtwdev);
8257 	rtw89_chip_rfk_init(rtwdev);
8258 	rtw89_chip_set_txpwr_ctrl(rtwdev);
8259 	rtw89_chip_power_trim(rtwdev);
8260 	rtw89_chip_cfg_txrx_path(rtwdev);
8261 }
8262 
rtw89_phy_dm_reinit(struct rtw89_dev * rtwdev)8263 void rtw89_phy_dm_reinit(struct rtw89_dev *rtwdev)
8264 {
8265 	rtw89_phy_env_monitor_init(rtwdev);
8266 	rtw89_physts_parsing_init(rtwdev);
8267 }
8268 
__rtw89_phy_dm_init_data(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8269 static void __rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
8270 {
8271 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
8272 	const struct rtw89_chip_info *chip = rtwdev->chip;
8273 	struct ieee80211_supported_band *sband;
8274 	enum rtw89_band hw_band;
8275 	enum nl80211_band band;
8276 	u8 idx;
8277 
8278 	if (!chip->support_noise)
8279 		return;
8280 
8281 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
8282 		sband = rtwdev->hw->wiphy->bands[band];
8283 		if (!sband)
8284 			continue;
8285 
8286 		hw_band = rtw89_nl80211_to_hw_band(band);
8287 		env->nhm_his[hw_band] =
8288 			devm_kcalloc(rtwdev->dev, sband->n_channels,
8289 				     sizeof(*env->nhm_his[0]), GFP_KERNEL);
8290 
8291 		for (idx = 0; idx < sband->n_channels; idx++)
8292 			INIT_LIST_HEAD(&env->nhm_his[hw_band][idx].list);
8293 
8294 		INIT_LIST_HEAD(&env->nhm_rpt_list);
8295 	}
8296 }
8297 
rtw89_phy_dm_init_data(struct rtw89_dev * rtwdev)8298 void rtw89_phy_dm_init_data(struct rtw89_dev *rtwdev)
8299 {
8300 	struct rtw89_bb_ctx *bb;
8301 
8302 	rtw89_for_each_capab_bb(rtwdev, bb)
8303 		__rtw89_phy_dm_init_data(rtwdev, bb);
8304 }
8305 
__rtw89_phy_set_bss_color(struct rtw89_dev * rtwdev,u8 bss_color,u16 aid,enum rtw89_phy_idx phy_idx)8306 void __rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, u8 bss_color, u16 aid,
8307 			       enum rtw89_phy_idx phy_idx)
8308 {
8309 	const struct rtw89_chip_info *chip = rtwdev->chip;
8310 	const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld;
8311 
8312 	rtw89_phy_write32_idx(rtwdev, bss_clr_vld->addr, bss_clr_vld->mask, 0x1,
8313 			      phy_idx);
8314 	rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_TGT,
8315 			      bss_color, phy_idx);
8316 	rtw89_phy_write32_idx(rtwdev, chip->bss_clr_map_reg, B_BSS_CLR_MAP_STAID,
8317 			      aid, phy_idx);
8318 }
8319 
rtw89_phy_set_bss_color(struct rtw89_dev * rtwdev,struct rtw89_vif_link * rtwvif_link)8320 void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev,
8321 			     struct rtw89_vif_link *rtwvif_link)
8322 {
8323 	struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
8324 	enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
8325 	struct ieee80211_bss_conf *bss_conf;
8326 	u8 bss_color;
8327 
8328 	rcu_read_lock();
8329 
8330 	bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
8331 	if (!bss_conf->he_support || !vif->cfg.assoc) {
8332 		rcu_read_unlock();
8333 		return;
8334 	}
8335 
8336 	bss_color = bss_conf->he_bss_color.color;
8337 
8338 	rcu_read_unlock();
8339 
8340 	__rtw89_phy_set_bss_color(rtwdev, bss_color, vif->cfg.aid, phy_idx);
8341 }
8342 
rfk_chan_validate_desc(const struct rtw89_rfk_chan_desc * desc)8343 static bool rfk_chan_validate_desc(const struct rtw89_rfk_chan_desc *desc)
8344 {
8345 	return desc->ch != 0;
8346 }
8347 
rfk_chan_is_equivalent(const struct rtw89_rfk_chan_desc * desc,const struct rtw89_chan * chan)8348 static bool rfk_chan_is_equivalent(const struct rtw89_rfk_chan_desc *desc,
8349 				   const struct rtw89_chan *chan)
8350 {
8351 	if (!rfk_chan_validate_desc(desc))
8352 		return false;
8353 
8354 	if (desc->ch != chan->channel)
8355 		return false;
8356 
8357 	if (desc->has_band && desc->band != chan->band_type)
8358 		return false;
8359 
8360 	if (desc->has_bw && desc->bw != chan->band_width)
8361 		return false;
8362 
8363 	return true;
8364 }
8365 
8366 struct rfk_chan_iter_data {
8367 	const struct rtw89_rfk_chan_desc desc;
8368 	unsigned int found;
8369 };
8370 
rfk_chan_iter_search(const struct rtw89_chan * chan,void * data)8371 static int rfk_chan_iter_search(const struct rtw89_chan *chan, void *data)
8372 {
8373 	struct rfk_chan_iter_data *iter_data = data;
8374 
8375 	if (rfk_chan_is_equivalent(&iter_data->desc, chan))
8376 		iter_data->found++;
8377 
8378 	return 0;
8379 }
8380 
rtw89_rfk_chan_lookup(struct rtw89_dev * rtwdev,const struct rtw89_rfk_chan_desc * desc,u8 desc_nr,const struct rtw89_chan * target_chan)8381 u8 rtw89_rfk_chan_lookup(struct rtw89_dev *rtwdev,
8382 			 const struct rtw89_rfk_chan_desc *desc, u8 desc_nr,
8383 			 const struct rtw89_chan *target_chan)
8384 {
8385 	int sel = -1;
8386 	u8 i;
8387 
8388 	for (i = 0; i < desc_nr; i++) {
8389 		struct rfk_chan_iter_data iter_data = {
8390 			.desc = desc[i],
8391 		};
8392 
8393 		if (rfk_chan_is_equivalent(&desc[i], target_chan))
8394 			return i;
8395 
8396 		rtw89_iterate_entity_chan(rtwdev, rfk_chan_iter_search, &iter_data);
8397 		if (!iter_data.found && sel == -1)
8398 			sel = i;
8399 	}
8400 
8401 	if (sel == -1) {
8402 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
8403 			    "no idle rfk entry; force replace the first\n");
8404 		sel = 0;
8405 	}
8406 
8407 	return sel;
8408 }
8409 EXPORT_SYMBOL(rtw89_rfk_chan_lookup);
8410 
8411 static void
_rfk_write_rf(struct rtw89_dev * rtwdev,const struct rtw89_reg5_def * def)8412 _rfk_write_rf(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def)
8413 {
8414 	rtw89_write_rf(rtwdev, def->path, def->addr, def->mask, def->data);
8415 }
8416 
8417 static void
_rfk_write32_mask(struct rtw89_dev * rtwdev,const struct rtw89_reg5_def * def)8418 _rfk_write32_mask(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def)
8419 {
8420 	rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data);
8421 }
8422 
8423 static void
_rfk_write32_set(struct rtw89_dev * rtwdev,const struct rtw89_reg5_def * def)8424 _rfk_write32_set(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def)
8425 {
8426 	rtw89_phy_write32_set(rtwdev, def->addr, def->mask);
8427 }
8428 
8429 static void
_rfk_write32_clr(struct rtw89_dev * rtwdev,const struct rtw89_reg5_def * def)8430 _rfk_write32_clr(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def)
8431 {
8432 	rtw89_phy_write32_clr(rtwdev, def->addr, def->mask);
8433 }
8434 
8435 static void
_rfk_delay(struct rtw89_dev * rtwdev,const struct rtw89_reg5_def * def)8436 _rfk_delay(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def)
8437 {
8438 	udelay(def->data);
8439 }
8440 
8441 static void
8442 (*_rfk_handler[])(struct rtw89_dev *rtwdev, const struct rtw89_reg5_def *def) = {
8443 	[RTW89_RFK_F_WRF] = _rfk_write_rf,
8444 	[RTW89_RFK_F_WM] = _rfk_write32_mask,
8445 	[RTW89_RFK_F_WS] = _rfk_write32_set,
8446 	[RTW89_RFK_F_WC] = _rfk_write32_clr,
8447 	[RTW89_RFK_F_DELAY] = _rfk_delay,
8448 };
8449 
8450 static_assert(ARRAY_SIZE(_rfk_handler) == RTW89_RFK_F_NUM);
8451 
8452 void
rtw89_rfk_parser(struct rtw89_dev * rtwdev,const struct rtw89_rfk_tbl * tbl)8453 rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl)
8454 {
8455 	const struct rtw89_reg5_def *p = tbl->defs;
8456 	const struct rtw89_reg5_def *end = tbl->defs + tbl->size;
8457 
8458 	for (; p < end; p++)
8459 		_rfk_handler[p->flag](rtwdev, p);
8460 }
8461 EXPORT_SYMBOL(rtw89_rfk_parser);
8462 
8463 #define RTW89_TSSI_FAST_MODE_NUM 4
8464 
8465 static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_flat[RTW89_TSSI_FAST_MODE_NUM] = {
8466 	{0xD934, 0xff0000},
8467 	{0xD934, 0xff000000},
8468 	{0xD938, 0xff},
8469 	{0xD934, 0xff00},
8470 };
8471 
8472 static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_level[RTW89_TSSI_FAST_MODE_NUM] = {
8473 	{0xD930, 0xff0000},
8474 	{0xD930, 0xff000000},
8475 	{0xD934, 0xff},
8476 	{0xD930, 0xff00},
8477 };
8478 
8479 static
rtw89_phy_tssi_ctrl_set_fast_mode_cfg(struct rtw89_dev * rtwdev,enum rtw89_mac_idx mac_idx,enum rtw89_tssi_bandedge_cfg bandedge_cfg,u32 val)8480 void rtw89_phy_tssi_ctrl_set_fast_mode_cfg(struct rtw89_dev *rtwdev,
8481 					   enum rtw89_mac_idx mac_idx,
8482 					   enum rtw89_tssi_bandedge_cfg bandedge_cfg,
8483 					   u32 val)
8484 {
8485 	const struct rtw89_reg_def *regs;
8486 	u32 reg;
8487 	int i;
8488 
8489 	if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT)
8490 		regs = rtw89_tssi_fastmode_regs_flat;
8491 	else
8492 		regs = rtw89_tssi_fastmode_regs_level;
8493 
8494 	for (i = 0; i < RTW89_TSSI_FAST_MODE_NUM; i++) {
8495 		reg = rtw89_mac_reg_by_idx(rtwdev, regs[i].addr, mac_idx);
8496 		rtw89_write32_mask(rtwdev, reg, regs[i].mask, val);
8497 	}
8498 }
8499 
8500 static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_flat[RTW89_TSSI_SBW_NUM] = {
8501 	{0xD91C, 0xff000000},
8502 	{0xD920, 0xff},
8503 	{0xD920, 0xff00},
8504 	{0xD920, 0xff0000},
8505 	{0xD920, 0xff000000},
8506 	{0xD924, 0xff},
8507 	{0xD924, 0xff00},
8508 	{0xD914, 0xff000000},
8509 	{0xD918, 0xff},
8510 	{0xD918, 0xff00},
8511 	{0xD918, 0xff0000},
8512 	{0xD918, 0xff000000},
8513 	{0xD91C, 0xff},
8514 	{0xD91C, 0xff00},
8515 	{0xD91C, 0xff0000},
8516 };
8517 
8518 static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_level[RTW89_TSSI_SBW_NUM] = {
8519 	{0xD910, 0xff},
8520 	{0xD910, 0xff00},
8521 	{0xD910, 0xff0000},
8522 	{0xD910, 0xff000000},
8523 	{0xD914, 0xff},
8524 	{0xD914, 0xff00},
8525 	{0xD914, 0xff0000},
8526 	{0xD908, 0xff},
8527 	{0xD908, 0xff00},
8528 	{0xD908, 0xff0000},
8529 	{0xD908, 0xff000000},
8530 	{0xD90C, 0xff},
8531 	{0xD90C, 0xff00},
8532 	{0xD90C, 0xff0000},
8533 	{0xD90C, 0xff000000},
8534 };
8535 
rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev * rtwdev,enum rtw89_mac_idx mac_idx,enum rtw89_tssi_bandedge_cfg bandedge_cfg)8536 void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev,
8537 					  enum rtw89_mac_idx mac_idx,
8538 					  enum rtw89_tssi_bandedge_cfg bandedge_cfg)
8539 {
8540 	const struct rtw89_chip_info *chip = rtwdev->chip;
8541 	const struct rtw89_reg_def *regs;
8542 	const u32 *data;
8543 	u32 reg;
8544 	int i;
8545 
8546 	if (bandedge_cfg >= RTW89_TSSI_CFG_NUM)
8547 		return;
8548 
8549 	if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT)
8550 		regs = rtw89_tssi_bandedge_regs_flat;
8551 	else
8552 		regs = rtw89_tssi_bandedge_regs_level;
8553 
8554 	data = chip->tssi_dbw_table->data[bandedge_cfg];
8555 
8556 	for (i = 0; i < RTW89_TSSI_SBW_NUM; i++) {
8557 		reg = rtw89_mac_reg_by_idx(rtwdev, regs[i].addr, mac_idx);
8558 		rtw89_write32_mask(rtwdev, reg, regs[i].mask, data[i]);
8559 	}
8560 
8561 	reg = rtw89_mac_reg_by_idx(rtwdev, R_AX_BANDEDGE_CFG, mac_idx);
8562 	rtw89_write32_mask(rtwdev, reg, B_AX_BANDEDGE_CFG_IDX_MASK, bandedge_cfg);
8563 
8564 	rtw89_phy_tssi_ctrl_set_fast_mode_cfg(rtwdev, mac_idx, bandedge_cfg,
8565 					      data[RTW89_TSSI_SBW20]);
8566 }
8567 EXPORT_SYMBOL(rtw89_phy_tssi_ctrl_set_bandedge_cfg);
8568 
8569 static
8570 const u8 rtw89_ch_base_table[16] = {1, 0xff,
8571 				    36, 100, 132, 149, 0xff,
8572 				    1, 33, 65, 97, 129, 161, 193, 225, 0xff};
8573 #define RTW89_CH_BASE_IDX_2G		0
8574 #define RTW89_CH_BASE_IDX_5G_FIRST	2
8575 #define RTW89_CH_BASE_IDX_5G_LAST	5
8576 #define RTW89_CH_BASE_IDX_6G_FIRST	7
8577 #define RTW89_CH_BASE_IDX_6G_LAST	14
8578 
8579 #define RTW89_CH_BASE_IDX_MASK		GENMASK(7, 4)
8580 #define RTW89_CH_OFFSET_MASK		GENMASK(3, 0)
8581 
rtw89_encode_chan_idx(struct rtw89_dev * rtwdev,u8 central_ch,u8 band)8582 u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band)
8583 {
8584 	u8 chan_idx;
8585 	u8 last, first;
8586 	u8 idx;
8587 
8588 	switch (band) {
8589 	case RTW89_BAND_2G:
8590 		chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, RTW89_CH_BASE_IDX_2G) |
8591 			   FIELD_PREP(RTW89_CH_OFFSET_MASK, central_ch);
8592 		return chan_idx;
8593 	case RTW89_BAND_5G:
8594 		first = RTW89_CH_BASE_IDX_5G_FIRST;
8595 		last = RTW89_CH_BASE_IDX_5G_LAST;
8596 		break;
8597 	case RTW89_BAND_6G:
8598 		first = RTW89_CH_BASE_IDX_6G_FIRST;
8599 		last = RTW89_CH_BASE_IDX_6G_LAST;
8600 		break;
8601 	default:
8602 		rtw89_warn(rtwdev, "Unsupported band %d\n", band);
8603 		return 0;
8604 	}
8605 
8606 	for (idx = last; idx >= first; idx--)
8607 		if (central_ch >= rtw89_ch_base_table[idx])
8608 			break;
8609 
8610 	if (idx < first) {
8611 		rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch);
8612 		return 0;
8613 	}
8614 
8615 	chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, idx) |
8616 		   FIELD_PREP(RTW89_CH_OFFSET_MASK,
8617 			      (central_ch - rtw89_ch_base_table[idx]) >> 1);
8618 	return chan_idx;
8619 }
8620 EXPORT_SYMBOL(rtw89_encode_chan_idx);
8621 
rtw89_decode_chan_idx(struct rtw89_dev * rtwdev,u8 chan_idx,u8 * ch,enum nl80211_band * band)8622 void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
8623 			   u8 *ch, enum nl80211_band *band)
8624 {
8625 	u8 idx, offset;
8626 
8627 	idx = FIELD_GET(RTW89_CH_BASE_IDX_MASK, chan_idx);
8628 	offset = FIELD_GET(RTW89_CH_OFFSET_MASK, chan_idx);
8629 
8630 	if (idx == RTW89_CH_BASE_IDX_2G) {
8631 		*band = NL80211_BAND_2GHZ;
8632 		*ch = offset;
8633 		return;
8634 	}
8635 
8636 	*band = idx <= RTW89_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ;
8637 	*ch = rtw89_ch_base_table[idx] + (offset << 1);
8638 }
8639 EXPORT_SYMBOL(rtw89_decode_chan_idx);
8640 
rtw89_phy_config_edcca(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb,bool scan)8641 void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev,
8642 			    struct rtw89_bb_ctx *bb, bool scan)
8643 {
8644 	const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
8645 	struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak;
8646 
8647 	if (scan) {
8648 		edcca_bak->a =
8649 			rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level,
8650 					     edcca_regs->edcca_mask, bb->phy_idx);
8651 		edcca_bak->p =
8652 			rtw89_phy_read32_idx(rtwdev, edcca_regs->edcca_level,
8653 					     edcca_regs->edcca_p_mask, bb->phy_idx);
8654 		edcca_bak->ppdu =
8655 			rtw89_phy_read32_idx(rtwdev, edcca_regs->ppdu_level,
8656 					     edcca_regs->ppdu_mask, bb->phy_idx);
8657 
8658 		rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
8659 				      edcca_regs->edcca_mask, EDCCA_MAX, bb->phy_idx);
8660 		rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
8661 				      edcca_regs->edcca_p_mask, EDCCA_MAX, bb->phy_idx);
8662 		rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level,
8663 				      edcca_regs->ppdu_mask, EDCCA_MAX, bb->phy_idx);
8664 	} else {
8665 		rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
8666 				      edcca_regs->edcca_mask,
8667 				      edcca_bak->a, bb->phy_idx);
8668 		rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
8669 				      edcca_regs->edcca_p_mask,
8670 				      edcca_bak->p, bb->phy_idx);
8671 		rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level,
8672 				      edcca_regs->ppdu_mask,
8673 				      edcca_bak->ppdu, bb->phy_idx);
8674 	}
8675 }
8676 
rtw89_phy_edcca_log(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8677 static void rtw89_phy_edcca_log(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
8678 {
8679 	const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
8680 	const struct rtw89_edcca_p_regs *edcca_p_regs;
8681 	bool flag_fb, flag_p20, flag_s20, flag_s40, flag_s80;
8682 	s8 pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80;
8683 	u8 path, per20_bitmap = 0;
8684 	u8 pwdb_sel = 5;
8685 	u8 pwdb[8];
8686 	u32 tmp;
8687 
8688 	if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_EDCCA))
8689 		return;
8690 
8691 	if (bb->phy_idx == RTW89_PHY_1)
8692 		edcca_p_regs = &edcca_regs->p[RTW89_PHY_1];
8693 	else
8694 		edcca_p_regs = &edcca_regs->p[RTW89_PHY_0];
8695 
8696 	rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
8697 			       edcca_p_regs->rpt_sel_mask, 0);
8698 	if (rtwdev->chip->chip_id == RTL8922A || rtwdev->chip->chip_id == RTL8922D) {
8699 		rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
8700 				       edcca_regs->rpt_sel_be_mask, 0);
8701 		per20_bitmap = rtw89_phy_read32_mask(rtwdev, edcca_p_regs->rpt_a,
8702 						     MASKBYTE0);
8703 	}
8704 	tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
8705 	path = u32_get_bits(tmp, B_EDCCA_RPT_B_PATH_MASK);
8706 	flag_s80 = u32_get_bits(tmp, B_EDCCA_RPT_B_S80);
8707 	flag_s40 = u32_get_bits(tmp, B_EDCCA_RPT_B_S40);
8708 	flag_s20 = u32_get_bits(tmp, B_EDCCA_RPT_B_S20);
8709 	flag_p20 = u32_get_bits(tmp, B_EDCCA_RPT_B_P20);
8710 	flag_fb = u32_get_bits(tmp, B_EDCCA_RPT_B_FB);
8711 	pwdb_s20 = u32_get_bits(tmp, MASKBYTE1);
8712 	pwdb_p20 = u32_get_bits(tmp, MASKBYTE2);
8713 	pwdb_fb = u32_get_bits(tmp, MASKBYTE3);
8714 
8715 	if (rtwdev->chip->chip_id == RTL8922D)
8716 		pwdb_sel = 2;
8717 
8718 	rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
8719 			       edcca_p_regs->rpt_sel_mask, pwdb_sel);
8720 	tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
8721 	pwdb_s80 = u32_get_bits(tmp, MASKBYTE1);
8722 	pwdb_s40 = u32_get_bits(tmp, MASKBYTE2);
8723 
8724 	if (rtwdev->chip->chip_id == RTL8922A || rtwdev->chip->chip_id == RTL8922D) {
8725 		rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
8726 				       edcca_regs->rpt_sel_be_mask, 4);
8727 		tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
8728 		pwdb[0] = u32_get_bits(tmp, MASKBYTE3);
8729 		pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
8730 		pwdb[2] = u32_get_bits(tmp, MASKBYTE1);
8731 		pwdb[3] = u32_get_bits(tmp, MASKBYTE0);
8732 
8733 		rtw89_phy_write32_mask(rtwdev, edcca_regs->rpt_sel_be,
8734 				       edcca_regs->rpt_sel_be_mask, 5);
8735 		tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_b);
8736 		pwdb[4] = u32_get_bits(tmp, MASKBYTE3);
8737 		pwdb[5] = u32_get_bits(tmp, MASKBYTE2);
8738 		pwdb[6] = u32_get_bits(tmp, MASKBYTE1);
8739 		pwdb[7] = u32_get_bits(tmp, MASKBYTE0);
8740 	} else {
8741 		rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
8742 				       edcca_p_regs->rpt_sel_mask, 0);
8743 		tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
8744 		pwdb[0] = u32_get_bits(tmp, MASKBYTE3);
8745 		pwdb[1] = u32_get_bits(tmp, MASKBYTE2);
8746 
8747 		rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
8748 				       edcca_p_regs->rpt_sel_mask, 5);
8749 		tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
8750 		pwdb[2] = u32_get_bits(tmp, MASKBYTE3);
8751 		pwdb[3] = u32_get_bits(tmp, MASKBYTE2);
8752 
8753 		rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
8754 				       edcca_p_regs->rpt_sel_mask, 2);
8755 		tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
8756 		pwdb[4] = u32_get_bits(tmp, MASKBYTE3);
8757 		pwdb[5] = u32_get_bits(tmp, MASKBYTE2);
8758 
8759 		rtw89_phy_write32_mask(rtwdev, edcca_p_regs->rpt_sel,
8760 				       edcca_p_regs->rpt_sel_mask, 3);
8761 		tmp = rtw89_phy_read32(rtwdev, edcca_p_regs->rpt_a);
8762 		pwdb[6] = u32_get_bits(tmp, MASKBYTE3);
8763 		pwdb[7] = u32_get_bits(tmp, MASKBYTE2);
8764 	}
8765 
8766 	rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
8767 		    "[EDCCA]: edcca_bitmap = %04x\n", per20_bitmap);
8768 
8769 	rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
8770 		    "[EDCCA]: pwdb per20{0,1,2,3,4,5,6,7} = {%d,%d,%d,%d,%d,%d,%d,%d}(dBm)\n",
8771 		    pwdb[0], pwdb[1], pwdb[2], pwdb[3], pwdb[4], pwdb[5],
8772 		    pwdb[6], pwdb[7]);
8773 
8774 	rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
8775 		    "[EDCCA]: path=%d, flag {FB,p20,s20,s40,s80} = {%d,%d,%d,%d,%d}\n",
8776 		    path, flag_fb, flag_p20, flag_s20, flag_s40, flag_s80);
8777 
8778 	rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
8779 		    "[EDCCA]: pwdb {FB,p20,s20,s40,s80} = {%d,%d,%d,%d,%d}(dBm)\n",
8780 		    pwdb_fb, pwdb_p20, pwdb_s20, pwdb_s40, pwdb_s80);
8781 }
8782 
rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8783 static u8 rtw89_phy_edcca_get_thre_by_rssi(struct rtw89_dev *rtwdev,
8784 					   struct rtw89_bb_ctx *bb)
8785 {
8786 	struct rtw89_phy_ch_info *ch_info = &bb->ch_info;
8787 	bool is_linked = rtwdev->total_sta_assoc > 0;
8788 	u8 rssi_min = ch_info->rssi_min >> 1;
8789 	u8 edcca_thre;
8790 
8791 	if (!is_linked) {
8792 		edcca_thre = EDCCA_MAX;
8793 	} else {
8794 		edcca_thre = rssi_min - RSSI_UNIT_CONVER + EDCCA_UNIT_CONVER -
8795 			     EDCCA_TH_REF;
8796 		edcca_thre = max_t(u8, edcca_thre, EDCCA_TH_L2H_LB);
8797 	}
8798 
8799 	return edcca_thre;
8800 }
8801 
rtw89_phy_edcca_thre_calc(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8802 void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
8803 {
8804 	const struct rtw89_edcca_regs *edcca_regs = rtwdev->chip->edcca_regs;
8805 	struct rtw89_edcca_bak *edcca_bak = &bb->edcca_bak;
8806 	u8 th;
8807 
8808 	th = rtw89_phy_edcca_get_thre_by_rssi(rtwdev, bb);
8809 	if (th == edcca_bak->th_old)
8810 		return;
8811 
8812 	edcca_bak->th_old = th;
8813 
8814 	rtw89_debug(rtwdev, RTW89_DBG_EDCCA,
8815 		    "[EDCCA]: Normal Mode, EDCCA_th = %d\n", th);
8816 
8817 	rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
8818 			      edcca_regs->edcca_mask, th, bb->phy_idx);
8819 	rtw89_phy_write32_idx(rtwdev, edcca_regs->edcca_level,
8820 			      edcca_regs->edcca_p_mask, th, bb->phy_idx);
8821 	rtw89_phy_write32_idx(rtwdev, edcca_regs->ppdu_level,
8822 			      edcca_regs->ppdu_mask, th, bb->phy_idx);
8823 }
8824 
rtw89_phy_edcca_diag(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8825 static void rtw89_phy_edcca_diag(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
8826 {
8827 #define RTW89_DIAG_BB_EDCCA_RATIO_TH 50
8828 #define RTW89_DIAG_BB_EDCCA_TX_TH 10
8829 	struct rtw89_env_monitor_info *env = &bb->env_monitor;
8830 	struct rtw89_traffic_stats *stats = &rtwdev->stats;
8831 	struct rtw89_diag_bb *diag = &bb->diag;
8832 
8833 	diag->diag_bb_bitmap &= ~BIT(RTW89_DIAG_BB_EDCCA);
8834 
8835 	if (stats->tx_throughput <= RTW89_DIAG_BB_EDCCA_TX_TH ||
8836 	    env->edcca_clm_ratio <= RTW89_DIAG_BB_EDCCA_RATIO_TH)
8837 		return;
8838 
8839 	diag->diag_bb_bitmap |= BIT(RTW89_DIAG_BB_EDCCA);
8840 	diag->diag_bb_cnt[RTW89_DIAG_BB_EDCCA]++;
8841 }
8842 
8843 static
__rtw89_phy_edcca_track(struct rtw89_dev * rtwdev,struct rtw89_bb_ctx * bb)8844 void __rtw89_phy_edcca_track(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb)
8845 {
8846 	rtw89_debug(rtwdev, RTW89_DBG_EDCCA, "BB-%d edcca track\n", bb->phy_idx);
8847 
8848 	rtw89_phy_edcca_thre_calc(rtwdev, bb);
8849 	rtw89_phy_edcca_log(rtwdev, bb);
8850 	rtw89_phy_edcca_diag(rtwdev, bb);
8851 }
8852 
rtw89_phy_edcca_track(struct rtw89_dev * rtwdev)8853 void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev)
8854 {
8855 	struct rtw89_hal *hal = &rtwdev->hal;
8856 	struct rtw89_bb_ctx *bb;
8857 
8858 	if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DYNAMIC_EDCCA))
8859 		return;
8860 
8861 	rtw89_for_each_active_bb(rtwdev, bb)
8862 		__rtw89_phy_edcca_track(rtwdev, bb);
8863 }
8864 
rtw89_phy_get_kpath(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)8865 enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev,
8866 					   enum rtw89_phy_idx phy_idx)
8867 {
8868 	rtw89_debug(rtwdev, RTW89_DBG_RFK,
8869 		    "[RFK] kpath dbcc_en: 0x%x, mode=0x%x, PHY%d\n",
8870 		    rtwdev->dbcc_en, rtwdev->mlo_dbcc_mode, phy_idx);
8871 
8872 	switch (rtwdev->mlo_dbcc_mode) {
8873 	case MLO_1_PLUS_1_1RF:
8874 		if (phy_idx == RTW89_PHY_0)
8875 			return RF_A;
8876 		else
8877 			return RF_B;
8878 	case MLO_1_PLUS_1_2RF:
8879 		if (phy_idx == RTW89_PHY_0)
8880 			return RF_A;
8881 		else
8882 			return RF_D;
8883 	case MLO_0_PLUS_2_1RF:
8884 	case MLO_2_PLUS_0_1RF:
8885 		/* for both PHY 0/1 */
8886 		return RF_AB;
8887 	case MLO_0_PLUS_2_2RF:
8888 	case MLO_2_PLUS_0_2RF:
8889 	case MLO_2_PLUS_2_2RF:
8890 	default:
8891 		if (phy_idx == RTW89_PHY_0)
8892 			return RF_AB;
8893 		else
8894 			return RF_CD;
8895 	}
8896 }
8897 EXPORT_SYMBOL(rtw89_phy_get_kpath);
8898 
rtw89_phy_get_syn_sel(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)8899 enum rtw89_rf_path rtw89_phy_get_syn_sel(struct rtw89_dev *rtwdev,
8900 					 enum rtw89_phy_idx phy_idx)
8901 {
8902 	rtw89_debug(rtwdev, RTW89_DBG_RFK,
8903 		    "[RFK] kpath dbcc_en: 0x%x, mode=0x%x, PHY%d\n",
8904 		    rtwdev->dbcc_en, rtwdev->mlo_dbcc_mode, phy_idx);
8905 
8906 	switch (rtwdev->mlo_dbcc_mode) {
8907 	case MLO_1_PLUS_1_1RF:
8908 		if (phy_idx == RTW89_PHY_0)
8909 			return RF_PATH_A;
8910 		else
8911 			return RF_PATH_B;
8912 	case MLO_1_PLUS_1_2RF:
8913 		if (phy_idx == RTW89_PHY_0)
8914 			return RF_PATH_A;
8915 		else
8916 			return RF_PATH_D;
8917 	case MLO_0_PLUS_2_1RF:
8918 	case MLO_2_PLUS_0_1RF:
8919 		if (phy_idx == RTW89_PHY_0)
8920 			return RF_PATH_A;
8921 		else
8922 			return RF_PATH_B;
8923 	case MLO_0_PLUS_2_2RF:
8924 	case MLO_2_PLUS_0_2RF:
8925 	case MLO_2_PLUS_2_2RF:
8926 	default:
8927 		if (phy_idx == RTW89_PHY_0)
8928 			return RF_PATH_A;
8929 		else
8930 			return RF_PATH_C;
8931 	}
8932 }
8933 EXPORT_SYMBOL(rtw89_phy_get_syn_sel);
8934 
8935 static const struct rtw89_ccx_regs rtw89_ccx_regs_ax = {
8936 	.setting_addr = R_CCX,
8937 	.edcca_opt_mask = B_CCX_EDCCA_OPT_MSK,
8938 	.measurement_trig_mask = B_MEASUREMENT_TRIG_MSK,
8939 	.trig_opt_mask = B_CCX_TRIG_OPT_MSK,
8940 	.en_mask = B_CCX_EN_MSK,
8941 	.ifs_cnt_addr = R_IFS_COUNTER,
8942 	.ifs_clm_period_mask = B_IFS_CLM_PERIOD_MSK,
8943 	.ifs_clm_cnt_unit_mask = B_IFS_CLM_COUNTER_UNIT_MSK,
8944 	.ifs_clm_cnt_clear_mask = B_IFS_COUNTER_CLR_MSK,
8945 	.ifs_collect_en_mask = B_IFS_COLLECT_EN,
8946 	.ifs_t1_addr = R_IFS_T1,
8947 	.ifs_t1_th_h_mask = B_IFS_T1_TH_HIGH_MSK,
8948 	.ifs_t1_en_mask = B_IFS_T1_EN_MSK,
8949 	.ifs_t1_th_l_mask = B_IFS_T1_TH_LOW_MSK,
8950 	.ifs_t2_addr = R_IFS_T2,
8951 	.ifs_t2_th_h_mask = B_IFS_T2_TH_HIGH_MSK,
8952 	.ifs_t2_en_mask = B_IFS_T2_EN_MSK,
8953 	.ifs_t2_th_l_mask = B_IFS_T2_TH_LOW_MSK,
8954 	.ifs_t3_addr = R_IFS_T3,
8955 	.ifs_t3_th_h_mask = B_IFS_T3_TH_HIGH_MSK,
8956 	.ifs_t3_en_mask = B_IFS_T3_EN_MSK,
8957 	.ifs_t3_th_l_mask = B_IFS_T3_TH_LOW_MSK,
8958 	.ifs_t4_addr = R_IFS_T4,
8959 	.ifs_t4_th_h_mask = B_IFS_T4_TH_HIGH_MSK,
8960 	.ifs_t4_en_mask = B_IFS_T4_EN_MSK,
8961 	.ifs_t4_th_l_mask = B_IFS_T4_TH_LOW_MSK,
8962 	.ifs_clm_tx_cnt_addr = R_IFS_CLM_TX_CNT,
8963 	.ifs_clm_edcca_excl_cca_fa_mask = B_IFS_CLM_EDCCA_EXCLUDE_CCA_FA_MSK,
8964 	.ifs_clm_tx_cnt_msk = B_IFS_CLM_TX_CNT_MSK,
8965 	.ifs_clm_cca_addr = R_IFS_CLM_CCA,
8966 	.ifs_clm_ofdmcca_excl_fa_mask = B_IFS_CLM_OFDMCCA_EXCLUDE_FA_MSK,
8967 	.ifs_clm_cckcca_excl_fa_mask = B_IFS_CLM_CCKCCA_EXCLUDE_FA_MSK,
8968 	.ifs_clm_fa_addr = R_IFS_CLM_FA,
8969 	.ifs_clm_ofdm_fa_mask = B_IFS_CLM_OFDM_FA_MSK,
8970 	.ifs_clm_cck_fa_mask = B_IFS_CLM_CCK_FA_MSK,
8971 	.ifs_his_addr = R_IFS_HIS,
8972 	.ifs_his_addr2 = R_IFS_HIS,
8973 	.ifs_t4_his_mask = B_IFS_T4_HIS_MSK,
8974 	.ifs_t3_his_mask = B_IFS_T3_HIS_MSK,
8975 	.ifs_t2_his_mask = B_IFS_T2_HIS_MSK,
8976 	.ifs_t1_his_mask = B_IFS_T1_HIS_MSK,
8977 	.ifs_avg_l_addr = R_IFS_AVG_L,
8978 	.ifs_t2_avg_mask = B_IFS_T2_AVG_MSK,
8979 	.ifs_t1_avg_mask = B_IFS_T1_AVG_MSK,
8980 	.ifs_avg_h_addr = R_IFS_AVG_H,
8981 	.ifs_t4_avg_mask = B_IFS_T4_AVG_MSK,
8982 	.ifs_t3_avg_mask = B_IFS_T3_AVG_MSK,
8983 	.ifs_cca_l_addr = R_IFS_CCA_L,
8984 	.ifs_t2_cca_mask = B_IFS_T2_CCA_MSK,
8985 	.ifs_t1_cca_mask = B_IFS_T1_CCA_MSK,
8986 	.ifs_cca_h_addr = R_IFS_CCA_H,
8987 	.ifs_t4_cca_mask = B_IFS_T4_CCA_MSK,
8988 	.ifs_t3_cca_mask = B_IFS_T3_CCA_MSK,
8989 	.ifs_total_addr = R_IFSCNT,
8990 	.ifs_cnt_done_mask = B_IFSCNT_DONE_MSK,
8991 	.ifs_total_mask = B_IFSCNT_TOTAL_CNT_MSK,
8992 	.nhm = R_NHM_AX,
8993 	.nhm_ready = B_NHM_READY_MSK,
8994 	.nhm_config = R_NHM_CFG,
8995 	.nhm_period_mask = B_NHM_PERIOD_MSK,
8996 	.nhm_unit_mask = B_NHM_COUNTER_MSK,
8997 	.nhm_include_cca_mask = B_NHM_INCLUDE_CCA_MSK,
8998 	.nhm_en_mask = B_NHM_EN_MSK,
8999 	.nhm_method = R_NHM_TH9,
9000 	.nhm_pwr_method_msk = B_NHM_PWDB_METHOD_MSK,
9001 	.edcca_clm_rdy = R_CLM_EDCCA_RDY,
9002 	.edcca_clm_rdy_mask = B_CLM_EDCCA_RDY,
9003 	.edcca_clm_cnt = R_CLM_EDCCA_RESULT,
9004 	.edcca_clm_cnt_mask = B_CLM_EDCCA_RESULT,
9005 };
9006 
9007 static const u32 rtw89_txinfo_reg_ax[] = {
9008 	R_TX_INFO_0_0_COMB,
9009 	R_TX_INFO_0_1_COMB,
9010 	R_TX_INFO_1_0_COMB,
9011 	R_TX_INFO_1_1_COMB
9012 };
9013 
9014 static const u32 rtw89_tx_common_ctrl_reg_ax[] = {
9015 	R_TX_COMMON_CTRL_0_0_COMB,
9016 	R_TX_COMMON_CTRL_0_1_COMB
9017 };
9018 
9019 static const struct rtw89_reg_def rtw89_txpwr_ax[] = {
9020 	{.addr = R_PATH0_TXPWR, .mask = B_PATH0_TXPWR},
9021 	{.addr = R_PATH1_TXPWR, .mask = B_PATH1_TXPWR}
9022 };
9023 
9024 static const struct rtw89_physts_regs rtw89_physts_regs_ax = {
9025 	.setting_addr = R_PLCP_HISTOGRAM,
9026 	.dis_trigger_fail_mask = B_STS_DIS_TRIG_BY_FAIL,
9027 	.dis_trigger_brk_mask = B_STS_DIS_TRIG_BY_BRK,
9028 	.mac_phy_intf_sel = {R_INTF_R_INTF_RPT_SEL, B_INTF_R_INTF_RPT_SEL},
9029 	.txpwr = rtw89_txpwr_ax,
9030 	.tx_info = RTW89_REGS_DEF(rtw89_txinfo_reg_ax),
9031 	.tx_common_ctrl = RTW89_REGS_DEF(rtw89_tx_common_ctrl_reg_ax),
9032 };
9033 
9034 static const struct rtw89_cfo_regs rtw89_cfo_regs_ax = {
9035 	.comp = R_DCFO_WEIGHT,
9036 	.weighting_mask = B_DCFO_WEIGHT_MSK,
9037 	.comp_seg0 = R_DCFO_OPT,
9038 	.valid_0_mask = B_DCFO_OPT_EN,
9039 };
9040 
9041 const struct rtw89_phy_gen_def rtw89_phy_gen_ax = {
9042 	.cr_base = 0x10000,
9043 	.physt_bmp_start = R_PHY_STS_BITMAP_ADDR_START,
9044 	.physt_bmp_eht = 0xfc,
9045 	.physt_ie_len = {16, 32, 24, 24, 8, 8, 8, 8, VAR_LEN, 8, VAR_LEN, 176, VAR_LEN,
9046 			 VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, VAR_LEN, 16, 24, VAR_LEN,
9047 			 VAR_LEN, VAR_LEN, 0, 24, 24, 24, 24, 32, 32, 32, 32},
9048 	.physt_gen = 0,
9049 	.ccx = &rtw89_ccx_regs_ax,
9050 	.physts = &rtw89_physts_regs_ax,
9051 	.cfo = &rtw89_cfo_regs_ax,
9052 	.bb_wrap = NULL,
9053 	.nctl = NULL,
9054 	.phy0_phy1_offset = rtw89_phy0_phy1_offset_ax,
9055 	.config_bb_gain = rtw89_phy_config_bb_gain_ax,
9056 	.preinit_rf_nctl = rtw89_phy_preinit_rf_nctl_ax,
9057 	.bb_wrap_init = NULL,
9058 	.ch_info_init = NULL,
9059 
9060 	.set_txpwr_byrate = rtw89_phy_set_txpwr_byrate_ax,
9061 	.set_txpwr_offset = rtw89_phy_set_txpwr_offset_ax,
9062 	.set_txpwr_limit = rtw89_phy_set_txpwr_limit_ax,
9063 	.set_txpwr_limit_ru = rtw89_phy_set_txpwr_limit_ru_ax,
9064 };
9065 EXPORT_SYMBOL(rtw89_phy_gen_ax);
9066