summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89/phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/phy.c')
-rw-r--r--drivers/net/wireless/realtek/rtw89/phy.c481
1 files changed, 428 insertions, 53 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index ac211d8973118..762cdba9d3cfd 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -76,10 +76,10 @@ static u64 get_mcs_ra_mask(u16 mcs_map, u8 highest_mcs, u8 gap)
static u64 get_he_ra_mask(struct ieee80211_sta *sta)
{
- struct ieee80211_sta_he_cap cap = sta->he_cap;
+ struct ieee80211_sta_he_cap cap = sta->deflink.he_cap;
u16 mcs_map;
- switch (sta->bandwidth) {
+ switch (sta->deflink.bandwidth) {
case IEEE80211_STA_RX_BW_160:
if (cap.he_cap_elem.phy_cap_info[0] &
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
@@ -172,17 +172,17 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw
return -1;
}
- if (sta->he_cap.has_he) {
+ if (sta->deflink.he_cap.has_he) {
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0],
RA_MASK_HE_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1],
RA_MASK_HE_2SS_RATES);
- } else if (sta->vht_cap.vht_supported) {
+ } else if (sta->deflink.vht_cap.vht_supported) {
cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0],
RA_MASK_VHT_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1],
RA_MASK_VHT_2SS_RATES);
- } else if (sta->ht_cap.ht_supported) {
+ } else if (sta->deflink.ht_cap.ht_supported) {
cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0],
RA_MASK_HT_1SS_RATES);
cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1],
@@ -223,57 +223,57 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
memset(ra, 0, sizeof(*ra));
/* Set the ra mask from sta's capability */
- if (sta->he_cap.has_he) {
+ if (sta->deflink.he_cap.has_he) {
mode |= RTW89_RA_MODE_HE;
csi_mode = RTW89_RA_RPT_MODE_HE;
ra_mask |= get_he_ra_mask(sta);
high_rate_masks = rtw89_ra_mask_he_rates;
- if (sta->he_cap.he_cap_elem.phy_cap_info[2] &
+ if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[2] &
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
stbc_en = 1;
- if (sta->he_cap.he_cap_elem.phy_cap_info[1] &
+ if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[1] &
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
ldpc_en = 1;
- } else if (sta->vht_cap.vht_supported) {
- u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map);
+ } else if (sta->deflink.vht_cap.vht_supported) {
+ u16 mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);
mode |= RTW89_RA_MODE_VHT;
csi_mode = RTW89_RA_RPT_MODE_VHT;
/* MCS9, MCS8, MCS7 */
ra_mask |= get_mcs_ra_mask(mcs_map, 9, 1);
high_rate_masks = rtw89_ra_mask_vht_rates;
- if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
+ if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
stbc_en = 1;
- if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
+ if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
ldpc_en = 1;
- } else if (sta->ht_cap.ht_supported) {
+ } else if (sta->deflink.ht_cap.ht_supported) {
mode |= RTW89_RA_MODE_HT;
csi_mode = RTW89_RA_RPT_MODE_HT;
- ra_mask |= ((u64)sta->ht_cap.mcs.rx_mask[3] << 48) |
- ((u64)sta->ht_cap.mcs.rx_mask[2] << 36) |
- (sta->ht_cap.mcs.rx_mask[1] << 24) |
- (sta->ht_cap.mcs.rx_mask[0] << 12);
+ ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 48) |
+ ((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 36) |
+ (sta->deflink.ht_cap.mcs.rx_mask[1] << 24) |
+ (sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
high_rate_masks = rtw89_ra_mask_ht_rates;
- if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
+ if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
stbc_en = 1;
- if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
+ if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
ldpc_en = 1;
}
switch (rtwdev->hal.current_band_type) {
case RTW89_BAND_2G:
- ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ];
- if (sta->supp_rates[NL80211_BAND_2GHZ] <= 0xf)
+ ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ];
+ if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] <= 0xf)
mode |= RTW89_RA_MODE_CCK;
else
mode |= RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM;
break;
case RTW89_BAND_5G:
- ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4;
+ ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4;
mode |= RTW89_RA_MODE_OFDM;
break;
case RTW89_BAND_6G:
- ra_mask |= (u64)sta->supp_rates[NL80211_BAND_6GHZ] << 4;
+ ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_6GHZ] << 4;
mode |= RTW89_RA_MODE_OFDM;
break;
default:
@@ -302,30 +302,30 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra_mask = rtw89_phy_ra_mask_recover(ra_mask, ra_mask_bak);
ra_mask &= rtw89_phy_ra_mask_cfg(rtwdev, rtwsta);
- switch (sta->bandwidth) {
+ switch (sta->deflink.bandwidth) {
case IEEE80211_STA_RX_BW_160:
bw_mode = RTW89_CHANNEL_WIDTH_160;
- sgi = sta->vht_cap.vht_supported &&
- (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160);
+ sgi = sta->deflink.vht_cap.vht_supported &&
+ (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160);
break;
case IEEE80211_STA_RX_BW_80:
bw_mode = RTW89_CHANNEL_WIDTH_80;
- sgi = sta->vht_cap.vht_supported &&
- (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
+ sgi = sta->deflink.vht_cap.vht_supported &&
+ (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80);
break;
case IEEE80211_STA_RX_BW_40:
bw_mode = RTW89_CHANNEL_WIDTH_40;
- sgi = sta->ht_cap.ht_supported &&
- (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
+ sgi = sta->deflink.ht_cap.ht_supported &&
+ (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40);
break;
default:
bw_mode = RTW89_CHANNEL_WIDTH_20;
- sgi = sta->ht_cap.ht_supported &&
- (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
+ sgi = sta->deflink.ht_cap.ht_supported &&
+ (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20);
break;
}
- if (sta->he_cap.he_cap_elem.phy_cap_info[3] &
+ if (sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM)
ra->dcm_cap = 1;
@@ -340,7 +340,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->macid = rtwsta->mac_id;
ra->stbc_cap = stbc_en;
ra->ldpc_cap = ldpc_en;
- ra->ss_num = min(sta->rx_nss, rtwdev->hal.tx_nss) - 1;
+ ra->ss_num = min(sta->deflink.rx_nss, rtwdev->hal.tx_nss) - 1;
ra->en_sgi = sgi;
ra->ra_mask = ra_mask;
@@ -357,13 +357,19 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev,
ra->csi_mode = csi_mode;
}
-void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta)
+void rtw89_phy_ra_updata_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
+ u32 changed)
{
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_ra_info *ra = &rtwsta->ra;
rtw89_phy_ra_sta_update(rtwdev, sta, false);
- ra->upd_mask = 1;
+
+ if (changed & IEEE80211_RC_SUPP_RATES_CHANGED)
+ ra->upd_mask = 1;
+ if (changed & (IEEE80211_RC_BW_CHANGED | IEEE80211_RC_NSS_CHANGED))
+ ra->upd_bw_nss_mask = 1;
+
rtw89_debug(rtwdev, RTW89_DBG_RA,
"ra updat: macid = %d, bw = %d, nss = %d, gi = %d %d",
ra->macid,
@@ -423,27 +429,28 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
RTW89_HW_RATE_MCS16,
RTW89_HW_RATE_MCS24};
u8 band = rtwdev->hal.current_band_type;
+ enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
u8 tx_nss = rtwdev->hal.tx_nss;
u8 i;
for (i = 0; i < tx_nss; i++)
if (!__check_rate_pattern(&next_pattern, hw_rate_he[i],
RA_MASK_HE_RATES, RTW89_RA_MODE_HE,
- mask->control[band].he_mcs[i],
+ mask->control[nl_band].he_mcs[i],
0, true))
goto out;
for (i = 0; i < tx_nss; i++)
if (!__check_rate_pattern(&next_pattern, hw_rate_vht[i],
RA_MASK_VHT_RATES, RTW89_RA_MODE_VHT,
- mask->control[band].vht_mcs[i],
+ mask->control[nl_band].vht_mcs[i],
0, true))
goto out;
for (i = 0; i < tx_nss; i++)
if (!__check_rate_pattern(&next_pattern, hw_rate_ht[i],
RA_MASK_HT_RATES, RTW89_RA_MODE_HT,
- mask->control[band].ht_mcs[i],
+ mask->control[nl_band].ht_mcs[i],
0, true))
goto out;
@@ -451,18 +458,18 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
* require at least one basic rate for ieee80211_set_bitrate_mask,
* so the decision just depends on if all bitrates are set or not.
*/
- sband = rtwdev->hw->wiphy->bands[band];
+ sband = rtwdev->hw->wiphy->bands[nl_band];
if (band == RTW89_BAND_2G) {
if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_CCK1,
RA_MASK_CCK_RATES | RA_MASK_OFDM_RATES,
RTW89_RA_MODE_CCK | RTW89_RA_MODE_OFDM,
- mask->control[band].legacy,
+ mask->control[nl_band].legacy,
BIT(sband->n_bitrates) - 1, false))
goto out;
} else {
if (!__check_rate_pattern(&next_pattern, RTW89_HW_RATE_OFDM6,
RA_MASK_OFDM_RATES, RTW89_RA_MODE_OFDM,
- mask->control[band].legacy,
+ mask->control[nl_band].legacy,
BIT(sband->n_bitrates) - 1, false))
goto out;
}
@@ -487,7 +494,7 @@ static void rtw89_phy_ra_updata_sta_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
- rtw89_phy_ra_updata_sta(rtwdev, sta);
+ rtw89_phy_ra_updata_sta(rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
}
void rtw89_phy_ra_update(struct rtw89_dev *rtwdev)
@@ -790,6 +797,245 @@ static void rtw89_phy_config_bb_reg(struct rtw89_dev *rtwdev,
rtw89_phy_write32(rtwdev, reg->addr, reg->data);
}
+union rtw89_phy_bb_gain_arg {
+ u32 addr;
+ struct {
+ union {
+ u8 type;
+ struct {
+ u8 rxsc_start:4;
+ u8 bw:4;
+ };
+ };
+ u8 path;
+ u8 gain_band;
+ u8 cfg_type;
+ };
+} __packed;
+
+static void
+rtw89_phy_cfg_bb_gain_error(struct rtw89_dev *rtwdev,
+ union rtw89_phy_bb_gain_arg arg, u32 data)
+{
+ struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain;
+ u8 type = arg.type;
+ u8 path = arg.path;
+ u8 gband = arg.gain_band;
+ int i;
+
+ switch (type) {
+ case 0:
+ for (i = 0; i < 4; i++, data >>= 8)
+ gain->lna_gain[gband][path][i] = data & 0xff;
+ break;
+ case 1:
+ for (i = 4; i < 7; i++, data >>= 8)
+ gain->lna_gain[gband][path][i] = data & 0xff;
+ break;
+ case 2:
+ for (i = 0; i < 2; i++, data >>= 8)
+ gain->tia_gain[gband][path][i] = data & 0xff;
+ break;
+ default:
+ rtw89_warn(rtwdev,
+ "bb gain error {0x%x:0x%x} with unknown type: %d\n",
+ arg.addr, data, type);
+ break;
+ }
+}
+
+enum rtw89_phy_bb_rxsc_start_idx {
+ RTW89_BB_RXSC_START_IDX_FULL = 0,
+ RTW89_BB_RXSC_START_IDX_20 = 1,
+ RTW89_BB_RXSC_START_IDX_20_1 = 5,
+ RTW89_BB_RXSC_START_IDX_40 = 9,
+ RTW89_BB_RXSC_START_IDX_80 = 13,
+};
+
+static void
+rtw89_phy_cfg_bb_rpl_ofst(struct rtw89_dev *rtwdev,
+ union rtw89_phy_bb_gain_arg arg, u32 data)
+{
+ struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain;
+ u8 rxsc_start = arg.rxsc_start;
+ u8 bw = arg.bw;
+ u8 path = arg.path;
+ u8 gband = arg.gain_band;
+ u8 rxsc;
+ s8 ofst;
+ int i;
+
+ switch (bw) {
+ case RTW89_CHANNEL_WIDTH_20:
+ gain->rpl_ofst_20[gband][path] = (s8)data;
+ break;
+ case RTW89_CHANNEL_WIDTH_40:
+ if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) {
+ gain->rpl_ofst_40[gband][path][0] = (s8)data;
+ } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) {
+ for (i = 0; i < 2; i++, data >>= 8) {
+ rxsc = RTW89_BB_RXSC_START_IDX_20 + i;
+ ofst = (s8)(data & 0xff);
+ gain->rpl_ofst_40[gband][path][rxsc] = ofst;
+ }
+ }
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) {
+ gain->rpl_ofst_80[gband][path][0] = (s8)data;
+ } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) {
+ for (i = 0; i < 4; i++, data >>= 8) {
+ rxsc = RTW89_BB_RXSC_START_IDX_20 + i;
+ ofst = (s8)(data & 0xff);
+ gain->rpl_ofst_80[gband][path][rxsc] = ofst;
+ }
+ } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) {
+ for (i = 0; i < 2; i++, data >>= 8) {
+ rxsc = RTW89_BB_RXSC_START_IDX_40 + i;
+ ofst = (s8)(data & 0xff);
+ gain->rpl_ofst_80[gband][path][rxsc] = ofst;
+ }
+ }
+ break;
+ case RTW89_CHANNEL_WIDTH_160:
+ if (rxsc_start == RTW89_BB_RXSC_START_IDX_FULL) {
+ gain->rpl_ofst_160[gband][path][0] = (s8)data;
+ } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20) {
+ for (i = 0; i < 4; i++, data >>= 8) {
+ rxsc = RTW89_BB_RXSC_START_IDX_20 + i;
+ ofst = (s8)(data & 0xff);
+ gain->rpl_ofst_160[gband][path][rxsc] = ofst;
+ }
+ } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_20_1) {
+ for (i = 0; i < 4; i++, data >>= 8) {
+ rxsc = RTW89_BB_RXSC_START_IDX_20_1 + i;
+ ofst = (s8)(data & 0xff);
+ gain->rpl_ofst_160[gband][path][rxsc] = ofst;
+ }
+ } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_40) {
+ for (i = 0; i < 4; i++, data >>= 8) {
+ rxsc = RTW89_BB_RXSC_START_IDX_40 + i;
+ ofst = (s8)(data & 0xff);
+ gain->rpl_ofst_160[gband][path][rxsc] = ofst;
+ }
+ } else if (rxsc_start == RTW89_BB_RXSC_START_IDX_80) {
+ for (i = 0; i < 2; i++, data >>= 8) {
+ rxsc = RTW89_BB_RXSC_START_IDX_80 + i;
+ ofst = (s8)(data & 0xff);
+ gain->rpl_ofst_160[gband][path][rxsc] = ofst;
+ }
+ }
+ break;
+ default:
+ rtw89_warn(rtwdev,
+ "bb rpl ofst {0x%x:0x%x} with unknown bw: %d\n",
+ arg.addr, data, bw);
+ break;
+ }
+}
+
+static void
+rtw89_phy_cfg_bb_gain_bypass(struct rtw89_dev *rtwdev,
+ union rtw89_phy_bb_gain_arg arg, u32 data)
+{
+ struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain;
+ u8 type = arg.type;
+ u8 path = arg.path;
+ u8 gband = arg.gain_band;
+ int i;
+
+ switch (type) {
+ case 0:
+ for (i = 0; i < 4; i++, data >>= 8)
+ gain->lna_gain_bypass[gband][path][i] = data & 0xff;
+ break;
+ case 1:
+ for (i = 4; i < 7; i++, data >>= 8)
+ gain->lna_gain_bypass[gband][path][i] = data & 0xff;
+ break;
+ default:
+ rtw89_warn(rtwdev,
+ "bb gain bypass {0x%x:0x%x} with unknown type: %d\n",
+ arg.addr, data, type);
+ break;
+ }
+}
+
+static void
+rtw89_phy_cfg_bb_gain_op1db(struct rtw89_dev *rtwdev,
+ union rtw89_phy_bb_gain_arg arg, u32 data)
+{
+ struct rtw89_phy_bb_gain_info *gain = &rtwdev->bb_gain;
+ u8 type = arg.type;
+ u8 path = arg.path;
+ u8 gband = arg.gain_band;
+ int i;
+
+ switch (type) {
+ case 0:
+ for (i = 0; i < 4; i++, data >>= 8)
+ gain->lna_op1db[gband][path][i] = data & 0xff;
+ break;
+ case 1:
+ for (i = 4; i < 7; i++, data >>= 8)
+ gain->lna_op1db[gband][path][i] = data & 0xff;
+ break;
+ case 2:
+ for (i = 0; i < 4; i++, data >>= 8)
+ gain->tia_lna_op1db[gband][path][i] = data & 0xff;
+ break;
+ case 3:
+ for (i = 4; i < 8; i++, data >>= 8)
+ gain->tia_lna_op1db[gband][path][i] = data & 0xff;
+ break;
+ default:
+ rtw89_warn(rtwdev,
+ "bb gain op1db {0x%x:0x%x} with unknown type: %d\n",
+ arg.addr, data, type);
+ break;
+ }
+}
+
+static void rtw89_phy_config_bb_gain(struct rtw89_dev *rtwdev,
+ const struct rtw89_reg2_def *reg,
+ enum rtw89_rf_path rf_path,
+ void *extra_data)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ union rtw89_phy_bb_gain_arg arg = { .addr = reg->addr };
+
+ if (arg.gain_band >= RTW89_BB_GAIN_BAND_NR)
+ return;
+
+ if (arg.path >= chip->rf_path_num)
+ return;
+
+ if (arg.addr >= 0xf9 && arg.addr <= 0xfe) {
+ rtw89_warn(rtwdev, "bb gain table with flow ctrl\n");
+ return;
+ }
+
+ switch (arg.cfg_type) {
+ case 0:
+ rtw89_phy_cfg_bb_gain_error(rtwdev, arg, reg->data);
+ break;
+ case 1:
+ rtw89_phy_cfg_bb_rpl_ofst(rtwdev, arg, reg->data);
+ break;
+ case 2:
+ rtw89_phy_cfg_bb_gain_bypass(rtwdev, arg, reg->data);
+ break;
+ case 3:
+ rtw89_phy_cfg_bb_gain_op1db(rtwdev, arg, reg->data);
+ break;
+ default:
+ rtw89_warn(rtwdev,
+ "bb gain {0x%x:0x%x} with unknown cfg type: %d\n",
+ arg.addr, reg->data, arg.cfg_type);
+ break;
+ }
+}
+
static void
rtw89_phy_cofig_rf_reg_store(struct rtw89_dev *rtwdev,
const struct rtw89_reg2_def *reg,
@@ -1033,9 +1279,13 @@ void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_phy_table *bb_table = chip->bb_table;
+ const struct rtw89_phy_table *bb_gain_table = chip->bb_gain_table;
rtw89_phy_init_reg(rtwdev, bb_table, rtw89_phy_config_bb_reg, NULL);
rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0);
+ if (bb_gain_table)
+ rtw89_phy_init_reg(rtwdev, bb_gain_table,
+ rtw89_phy_config_bb_gain, NULL);
rtw89_phy_bb_reset(rtwdev, RTW89_PHY_0);
}
@@ -1686,7 +1936,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta)
break;
case RTW89_RA_RPT_MODE_HT:
ra_report->txrate.flags |= RATE_INFO_FLAGS_MCS;
- if (rtwdev->fw.old_ht_ra_format)
+ if (RTW89_CHK_FW_FEATURE(OLD_HT_RA_FORMAT, &rtwdev->fw))
rate = RTW89_MK_HT_RATE(FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate),
FIELD_GET(RTW89_RA_RATE_MASK_MCS, rate));
else
@@ -2213,6 +2463,11 @@ void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
u8 macid = phy_ppdu->mac_id;
+ if (macid >= CFO_TRACK_MAX_USER) {
+ rtw89_warn(rtwdev, "mac_id %d is out of range\n", macid);
+ return;
+ }
+
cfo->cfo_tail[macid] += cfo_val;
cfo->cfo_cnt[macid]++;
cfo->packet_count++;
@@ -2930,6 +3185,9 @@ static void rtw89_phy_dig_update_gain_para(struct rtw89_dev *rtwdev)
u32 tmp;
u8 i;
+ if (!rtwdev->hal.support_igi)
+ return;
+
tmp = rtw89_phy_read32_mask(rtwdev, R_PATH0_IB_PKPW,
B_PATH0_IB_PKPW_MSK);
dig->ib_pkpwr = sign_extend32(tmp >> DIG_GAIN_SHIFT, U8_MAX_BIT);
@@ -3180,6 +3438,24 @@ static void rtw89_phy_dig_sdagc_follow_pagc_config(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_DIG, "sdagc_follow_pagc=%d\n", enable);
}
+static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_dig_info *dig = &rtwdev->dig;
+
+ if (!rtwdev->hal.support_igi)
+ return;
+
+ if (dig->force_gaincode_idx_en) {
+ rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode);
+ rtw89_debug(rtwdev, RTW89_DBG_DIG,
+ "Force gaincode index enabled.\n");
+ } else {
+ rtw89_phy_dig_gaincode_by_rssi(rtwdev, dig->igi_fa_rssi,
+ &dig->cur_gaincode);
+ rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode);
+ }
+}
+
static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi,
bool enable)
{
@@ -3294,15 +3570,7 @@ void rtw89_phy_dig(struct rtw89_dev *rtwdev)
dig->igi_rssi, dig->dyn_igi_max, dig->dyn_igi_min,
dig->igi_fa_rssi);
- if (dig->force_gaincode_idx_en) {
- rtw89_phy_dig_set_igi_cr(rtwdev, dig->force_gaincode);
- rtw89_debug(rtwdev, RTW89_DBG_DIG,
- "Force gaincode index enabled.\n");
- } else {
- rtw89_phy_dig_gaincode_by_rssi(rtwdev, dig->igi_fa_rssi,
- &dig->cur_gaincode);
- rtw89_phy_dig_set_igi_cr(rtwdev, dig->cur_gaincode);
- }
+ rtw89_phy_dig_config_igi(rtwdev);
rtw89_phy_dig_dyn_pd_th(rtwdev, dig->igi_fa_rssi, dig->dyn_pd_th_en);
@@ -3336,6 +3604,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
rtw89_load_txpwr_table(rtwdev, chip->byr_table);
rtw89_chip_set_txpwr_ctrl(rtwdev);
rtw89_chip_power_trim(rtwdev);
+ rtw89_chip_cfg_txrx_path(rtwdev);
}
void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
@@ -3407,3 +3676,109 @@ rtw89_rfk_parser(struct rtw89_dev *rtwdev, const struct rtw89_rfk_tbl *tbl)
_rfk_handler[p->flag](rtwdev, p);
}
EXPORT_SYMBOL(rtw89_rfk_parser);
+
+#define RTW89_TSSI_FAST_MODE_NUM 4
+
+static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_flat[RTW89_TSSI_FAST_MODE_NUM] = {
+ {0xD934, 0xff0000},
+ {0xD934, 0xff000000},
+ {0xD938, 0xff},
+ {0xD934, 0xff00},
+};
+
+static const struct rtw89_reg_def rtw89_tssi_fastmode_regs_level[RTW89_TSSI_FAST_MODE_NUM] = {
+ {0xD930, 0xff0000},
+ {0xD930, 0xff000000},
+ {0xD934, 0xff},
+ {0xD930, 0xff00},
+};
+
+static
+void rtw89_phy_tssi_ctrl_set_fast_mode_cfg(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_idx mac_idx,
+ enum rtw89_tssi_bandedge_cfg bandedge_cfg,
+ u32 val)
+{
+ const struct rtw89_reg_def *regs;
+ u32 reg;
+ int i;
+
+ if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT)
+ regs = rtw89_tssi_fastmode_regs_flat;
+ else
+ regs = rtw89_tssi_fastmode_regs_level;
+
+ for (i = 0; i < RTW89_TSSI_FAST_MODE_NUM; i++) {
+ reg = rtw89_mac_reg_by_idx(regs[i].addr, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, regs[i].mask, val);
+ }
+}
+
+static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_flat[RTW89_TSSI_SBW_NUM] = {
+ {0xD91C, 0xff000000},
+ {0xD920, 0xff},
+ {0xD920, 0xff00},
+ {0xD920, 0xff0000},
+ {0xD920, 0xff000000},
+ {0xD924, 0xff},
+ {0xD924, 0xff00},
+ {0xD914, 0xff000000},
+ {0xD918, 0xff},
+ {0xD918, 0xff00},
+ {0xD918, 0xff0000},
+ {0xD918, 0xff000000},
+ {0xD91C, 0xff},
+ {0xD91C, 0xff00},
+ {0xD91C, 0xff0000},
+};
+
+static const struct rtw89_reg_def rtw89_tssi_bandedge_regs_level[RTW89_TSSI_SBW_NUM] = {
+ {0xD910, 0xff},
+ {0xD910, 0xff00},
+ {0xD910, 0xff0000},
+ {0xD910, 0xff000000},
+ {0xD914, 0xff},
+ {0xD914, 0xff00},
+ {0xD914, 0xff0000},
+ {0xD908, 0xff},
+ {0xD908, 0xff00},
+ {0xD908, 0xff0000},
+ {0xD908, 0xff000000},
+ {0xD90C, 0xff},
+ {0xD90C, 0xff00},
+ {0xD90C, 0xff0000},
+ {0xD90C, 0xff000000},
+};
+
+void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev,
+ enum rtw89_mac_idx mac_idx,
+ enum rtw89_tssi_bandedge_cfg bandedge_cfg)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_reg_def *regs;
+ const u32 *data;
+ u32 reg;
+ int i;
+
+ if (bandedge_cfg >= RTW89_TSSI_CFG_NUM)
+ return;
+
+ if (bandedge_cfg == RTW89_TSSI_BANDEDGE_FLAT)
+ regs = rtw89_tssi_bandedge_regs_flat;
+ else
+ regs = rtw89_tssi_bandedge_regs_level;
+
+ data = chip->tssi_dbw_table->data[bandedge_cfg];
+
+ for (i = 0; i < RTW89_TSSI_SBW_NUM; i++) {
+ reg = rtw89_mac_reg_by_idx(regs[i].addr, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, regs[i].mask, data[i]);
+ }
+
+ reg = rtw89_mac_reg_by_idx(R_AX_BANDEDGE_CFG, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_AX_BANDEDGE_CFG_IDX_MASK, bandedge_cfg);
+
+ rtw89_phy_tssi_ctrl_set_fast_mode_cfg(rtwdev, mac_idx, bandedge_cfg,
+ data[RTW89_TSSI_SBW20]);
+}
+EXPORT_SYMBOL(rtw89_phy_tssi_ctrl_set_bandedge_cfg);