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