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