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