diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/phy.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/phy.c | 286 |
1 files changed, 171 insertions, 115 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 1532c0a6bbc4..4dfeedeb0d90 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -14,23 +14,14 @@ static u16 get_max_amsdu_len(struct rtw89_dev *rtwdev, const struct rtw89_ra_report *report) { - const struct rate_info *txrate = &report->txrate; u32 bit_rate = report->bit_rate; - u8 mcs; /* lower than ofdm, do not aggregate */ if (bit_rate < 550) return 1; - /* prevent hardware rate fallback to G mode rate */ - if (txrate->flags & RATE_INFO_FLAGS_MCS) - mcs = txrate->mcs & 0x07; - else if (txrate->flags & (RATE_INFO_FLAGS_VHT_MCS | RATE_INFO_FLAGS_HE_MCS)) - mcs = txrate->mcs; - else - mcs = 0; - - if (mcs <= 2) + /* avoid AMSDU for legacy rate */ + if (report->might_fallback_legacy) return 1; /* lower than 20M vht 2ss mcs8, make it small */ @@ -142,8 +133,8 @@ static u64 rtw89_phy_ra_mask_recover(u64 ra_mask, u64 ra_mask_bak) static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta) { - struct rtw89_hal *hal = &rtwdev->hal; struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta); + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); struct cfg80211_bitrate_mask *mask = &rtwsta->mask; enum nl80211_band band; u64 cfg_mask; @@ -151,7 +142,7 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw if (!rtwsta->use_cfg_mask) return -1; - switch (hal->current_band_type) { + switch (chan->band_type) { case RTW89_BAND_2G: band = NL80211_BAND_2GHZ; cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_2GHZ].legacy, @@ -168,7 +159,7 @@ static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtw RA_MASK_OFDM_RATES); break; default: - rtw89_warn(rtwdev, "unhandled band type %d\n", hal->current_band_type); + rtw89_warn(rtwdev, "unhandled band type %d\n", chan->band_type); return -1; } @@ -209,6 +200,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif = rtwsta->rtwvif; struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; struct rtw89_ra_info *ra = &rtwsta->ra; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); const u64 *high_rate_masks = rtw89_ra_mask_ht_rates; u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi); u64 ra_mask = 0; @@ -260,7 +252,7 @@ static void rtw89_phy_ra_sta_update(struct rtw89_dev *rtwdev, ldpc_en = 1; } - switch (rtwdev->hal.current_band_type) { + switch (chan->band_type) { case RTW89_BAND_2G: ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ]; if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] <= 0xf) @@ -416,6 +408,7 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, struct ieee80211_supported_band *sband; struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; struct rtw89_phy_rate_pattern next_pattern = {0}; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); static const u16 hw_rate_he[] = {RTW89_HW_RATE_HE_NSS1_MCS0, RTW89_HW_RATE_HE_NSS2_MCS0, RTW89_HW_RATE_HE_NSS3_MCS0, @@ -428,7 +421,7 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev, RTW89_HW_RATE_MCS8, RTW89_HW_RATE_MCS16, RTW89_HW_RATE_MCS24}; - u8 band = rtwdev->hal.current_band_type; + u8 band = chan->band_type; enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band); u8 tx_nss = rtwdev->hal.tx_nss; u8 i; @@ -542,12 +535,12 @@ void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta) } u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev, - struct rtw89_channel_params *param, + const struct rtw89_chan *chan, enum rtw89_bandwidth dbw) { - enum rtw89_bandwidth cbw = param->bandwidth; - u8 pri_ch = param->primary_chan; - u8 central_ch = param->center_chan; + enum rtw89_bandwidth cbw = chan->band_width; + u8 pri_ch = chan->primary_channel; + u8 central_ch = chan->channel; u8 txsc_idx = 0; u8 tmp = 0; @@ -1468,10 +1461,9 @@ EXPORT_SYMBOL(rtw89_phy_load_txpwr_byrate); (txpwr_rf) >> (__c->txpwr_factor_rf - __c->txpwr_factor_mac); \ }) -s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, +s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, const struct rtw89_rate_desc *rate_desc) { - enum rtw89_band band = rtwdev->hal.current_band_type; s8 *byr; u8 idx; @@ -1538,11 +1530,10 @@ static u8 rtw89_channel_to_idx(struct rtw89_dev *rtwdev, u8 band, u8 channel) } } -s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, +s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch) { const struct rtw89_chip_info *chip = rtwdev->chip; - u8 band = rtwdev->hal.current_band_type; u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); u8 regd = rtw89_regd_get(rtwdev, band); s8 lmt = 0, sar; @@ -1578,11 +1569,12 @@ s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, } EXPORT_SYMBOL(rtw89_phy_read_txpwr_limit); -#define __fill_txpwr_limit_nonbf_bf(ptr, bw, ntx, rs, ch) \ +#define __fill_txpwr_limit_nonbf_bf(ptr, band, bw, ntx, rs, ch) \ do { \ u8 __i; \ for (__i = 0; __i < RTW89_BF_NUM; __i++) \ ptr[__i] = rtw89_phy_read_txpwr_limit(rtwdev, \ + band, \ bw, ntx, \ rs, __i, \ (ch)); \ @@ -1590,64 +1582,75 @@ EXPORT_SYMBOL(rtw89_phy_read_txpwr_limit); static void rtw89_phy_fill_txpwr_limit_20m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit *lmt, - u8 ntx, u8 ch) + u8 band, u8 ntx, u8 ch) { - __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_CCK, ch); - __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_CCK, ch); - __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, ch); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch); } static void rtw89_phy_fill_txpwr_limit_40m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit *lmt, - u8 ntx, u8 ch, u8 pri_ch) + u8 band, u8 ntx, u8 ch, u8 pri_ch) { - __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->cck_20m, band, RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_CCK, ch - 2); - __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->cck_40m, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_CCK, ch); - __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, pri_ch); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 2); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 2); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch); } static void rtw89_phy_fill_txpwr_limit_80m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit *lmt, - u8 ntx, u8 ch, u8 pri_ch) + u8 band, u8 ntx, u8 ch, u8 pri_ch) { s8 val_0p5_n[RTW89_BF_NUM]; s8 val_0p5_p[RTW89_BF_NUM]; u8 i; - __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, pri_ch); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 6); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 2); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 2); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 6); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 4); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 4); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], RTW89_CHANNEL_WIDTH_80, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch); - __fill_txpwr_limit_nonbf_bf(val_0p5_n, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 4); - __fill_txpwr_limit_nonbf_bf(val_0p5_p, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 4); for (i = 0; i < RTW89_BF_NUM; i++) @@ -1656,7 +1659,7 @@ static void rtw89_phy_fill_txpwr_limit_80m(struct rtw89_dev *rtwdev, static void rtw89_phy_fill_txpwr_limit_160m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit *lmt, - u8 ntx, u8 ch, u8 pri_ch) + u8 band, u8 ntx, u8 ch, u8 pri_ch) { s8 val_0p5_n[RTW89_BF_NUM]; s8 val_0p5_p[RTW89_BF_NUM]; @@ -1665,60 +1668,75 @@ static void rtw89_phy_fill_txpwr_limit_160m(struct rtw89_dev *rtwdev, u8 i; /* fill ofdm section */ - __fill_txpwr_limit_nonbf_bf(lmt->ofdm, RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->ofdm, band, RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_OFDM, pri_ch); /* fill mcs 20m section */ - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[0], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 14); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[1], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 10); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[2], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 6); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[3], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch - 2); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[4], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[4], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 2); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[5], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[5], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 6); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[6], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[6], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 10); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[7], RTW89_CHANNEL_WIDTH_20, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_20m[7], band, + RTW89_CHANNEL_WIDTH_20, ntx, RTW89_RS_MCS, ch + 14); /* fill mcs 40m section */ - __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[0], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 12); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[1], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 4); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[2], RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[2], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 4); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[3], RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_40m[3], band, + RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 12); /* fill mcs 80m section */ - __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], RTW89_CHANNEL_WIDTH_80, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[0], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch - 8); - __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[1], RTW89_CHANNEL_WIDTH_80, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_80m[1], band, + RTW89_CHANNEL_WIDTH_80, ntx, RTW89_RS_MCS, ch + 8); /* fill mcs 160m section */ - __fill_txpwr_limit_nonbf_bf(lmt->mcs_160m, RTW89_CHANNEL_WIDTH_160, + __fill_txpwr_limit_nonbf_bf(lmt->mcs_160m, band, + RTW89_CHANNEL_WIDTH_160, ntx, RTW89_RS_MCS, ch); /* fill mcs 40m 0p5 section */ - __fill_txpwr_limit_nonbf_bf(val_0p5_n, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(val_0p5_n, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 4); - __fill_txpwr_limit_nonbf_bf(val_0p5_p, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(val_0p5_p, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 4); for (i = 0; i < RTW89_BF_NUM; i++) lmt->mcs_40m_0p5[i] = min_t(s8, val_0p5_n[i], val_0p5_p[i]); /* fill mcs 40m 2p5 section */ - __fill_txpwr_limit_nonbf_bf(val_2p5_n, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(val_2p5_n, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch - 8); - __fill_txpwr_limit_nonbf_bf(val_2p5_p, RTW89_CHANNEL_WIDTH_40, + __fill_txpwr_limit_nonbf_bf(val_2p5_p, band, RTW89_CHANNEL_WIDTH_40, ntx, RTW89_RS_MCS, ch + 8); for (i = 0; i < RTW89_BF_NUM; i++) @@ -1726,37 +1744,41 @@ static void rtw89_phy_fill_txpwr_limit_160m(struct rtw89_dev *rtwdev, } void rtw89_phy_fill_txpwr_limit(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, struct rtw89_txpwr_limit *lmt, u8 ntx) { - u8 pri_ch = rtwdev->hal.current_primary_channel; - u8 ch = rtwdev->hal.current_channel; - u8 bw = rtwdev->hal.current_band_width; + u8 band = chan->band_type; + u8 pri_ch = chan->primary_channel; + u8 ch = chan->channel; + u8 bw = chan->band_width; memset(lmt, 0, sizeof(*lmt)); switch (bw) { case RTW89_CHANNEL_WIDTH_20: - rtw89_phy_fill_txpwr_limit_20m(rtwdev, lmt, ntx, ch); + rtw89_phy_fill_txpwr_limit_20m(rtwdev, lmt, band, ntx, ch); break; case RTW89_CHANNEL_WIDTH_40: - rtw89_phy_fill_txpwr_limit_40m(rtwdev, lmt, ntx, ch, pri_ch); + rtw89_phy_fill_txpwr_limit_40m(rtwdev, lmt, band, ntx, ch, + pri_ch); break; case RTW89_CHANNEL_WIDTH_80: - rtw89_phy_fill_txpwr_limit_80m(rtwdev, lmt, ntx, ch, pri_ch); + rtw89_phy_fill_txpwr_limit_80m(rtwdev, lmt, band, ntx, ch, + pri_ch); break; case RTW89_CHANNEL_WIDTH_160: - rtw89_phy_fill_txpwr_limit_160m(rtwdev, lmt, ntx, ch, pri_ch); + rtw89_phy_fill_txpwr_limit_160m(rtwdev, lmt, band, ntx, ch, + pri_ch); break; } } EXPORT_SYMBOL(rtw89_phy_fill_txpwr_limit); -static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, +static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, u8 band, u8 ru, u8 ntx, u8 ch) { const struct rtw89_chip_info *chip = rtwdev->chip; - u8 band = rtwdev->hal.current_band_type; u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch); u8 regd = rtw89_regd_get(rtwdev, band); s8 lmt_ru = 0, sar; @@ -1794,85 +1816,106 @@ static s8 rtw89_phy_read_txpwr_limit_ru(struct rtw89_dev *rtwdev, static void rtw89_phy_fill_txpwr_limit_ru_20m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit_ru *lmt_ru, - u8 ntx, u8 ch) + u8 band, u8 ntx, u8 ch) { - lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, + lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, ntx, ch); - lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, + lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, ntx, ch); - lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, + lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, ntx, ch); } static void rtw89_phy_fill_txpwr_limit_ru_40m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit_ru *lmt_ru, - u8 ntx, u8 ch) + u8 band, u8 ntx, u8 ch) { - lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, + lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, ntx, ch - 2); - lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, + lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, ntx, ch + 2); - lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, + lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, ntx, ch - 2); - lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, + lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, ntx, ch + 2); - lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, + lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, ntx, ch - 2); - lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, + lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, ntx, ch + 2); } static void rtw89_phy_fill_txpwr_limit_ru_80m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit_ru *lmt_ru, - u8 ntx, u8 ch) + u8 band, u8 ntx, u8 ch) { - lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, + lmt_ru->ru26[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, ntx, ch - 6); - lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, + lmt_ru->ru26[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, ntx, ch - 2); - lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, + lmt_ru->ru26[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, ntx, ch + 2); - lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU26, + lmt_ru->ru26[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU26, ntx, ch + 6); - lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, + lmt_ru->ru52[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, ntx, ch - 6); - lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, + lmt_ru->ru52[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, ntx, ch - 2); - lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, + lmt_ru->ru52[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, ntx, ch + 2); - lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU52, + lmt_ru->ru52[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU52, ntx, ch + 6); - lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, + lmt_ru->ru106[0] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, ntx, ch - 6); - lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, + lmt_ru->ru106[1] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, ntx, ch - 2); - lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, + lmt_ru->ru106[2] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, ntx, ch + 2); - lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, RTW89_RU106, + lmt_ru->ru106[3] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, + RTW89_RU106, ntx, ch + 6); } static void rtw89_phy_fill_txpwr_limit_ru_160m(struct rtw89_dev *rtwdev, struct rtw89_txpwr_limit_ru *lmt_ru, - u8 ntx, u8 ch) + u8 band, u8 ntx, u8 ch) { static const int ofst[] = { -14, -10, -6, -2, 2, 6, 10, 14 }; int i; static_assert(ARRAY_SIZE(ofst) == RTW89_RU_SEC_NUM); for (i = 0; i < RTW89_RU_SEC_NUM; i++) { - lmt_ru->ru26[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, + lmt_ru->ru26[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU26, ntx, ch + ofst[i]); - lmt_ru->ru52[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, + lmt_ru->ru52[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU52, ntx, ch + ofst[i]); - lmt_ru->ru106[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, + lmt_ru->ru106[i] = rtw89_phy_read_txpwr_limit_ru(rtwdev, band, RTW89_RU106, ntx, ch + ofst[i]); @@ -1880,26 +1923,32 @@ rtw89_phy_fill_txpwr_limit_ru_160m(struct rtw89_dev *rtwdev, } void rtw89_phy_fill_txpwr_limit_ru(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, struct rtw89_txpwr_limit_ru *lmt_ru, u8 ntx) { - u8 ch = rtwdev->hal.current_channel; - u8 bw = rtwdev->hal.current_band_width; + u8 band = chan->band_type; + u8 ch = chan->channel; + u8 bw = chan->band_width; memset(lmt_ru, 0, sizeof(*lmt_ru)); switch (bw) { case RTW89_CHANNEL_WIDTH_20: - rtw89_phy_fill_txpwr_limit_ru_20m(rtwdev, lmt_ru, ntx, ch); + rtw89_phy_fill_txpwr_limit_ru_20m(rtwdev, lmt_ru, band, ntx, + ch); break; case RTW89_CHANNEL_WIDTH_40: - rtw89_phy_fill_txpwr_limit_ru_40m(rtwdev, lmt_ru, ntx, ch); + rtw89_phy_fill_txpwr_limit_ru_40m(rtwdev, lmt_ru, band, ntx, + ch); break; case RTW89_CHANNEL_WIDTH_80: - rtw89_phy_fill_txpwr_limit_ru_80m(rtwdev, lmt_ru, ntx, ch); + rtw89_phy_fill_txpwr_limit_ru_80m(rtwdev, lmt_ru, band, ntx, + ch); break; case RTW89_CHANNEL_WIDTH_160: - rtw89_phy_fill_txpwr_limit_ru_160m(rtwdev, lmt_ru, ntx, ch); + rtw89_phy_fill_txpwr_limit_ru_160m(rtwdev, lmt_ru, band, ntx, + ch); break; } } @@ -1920,6 +1969,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) u8 mode, rate, bw, giltf, mac_id; u16 legacy_bitrate; bool valid; + u8 mcs = 0; mac_id = RTW89_GET_PHY_C2H_RA_RPT_MACID(c2h->data); if (mac_id != rtwsta->mac_id) @@ -1936,7 +1986,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) return; } - memset(ra_report, 0, sizeof(*ra_report)); + memset(&ra_report->txrate, 0, sizeof(ra_report->txrate)); switch (mode) { case RTW89_RA_RPT_MODE_LEGACY: @@ -1952,6 +2002,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) ra_report->txrate.mcs = rate; if (giltf) ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + mcs = ra_report->txrate.mcs & 0x07; break; case RTW89_RA_RPT_MODE_VHT: ra_report->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; @@ -1959,6 +2010,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) ra_report->txrate.nss = FIELD_GET(RTW89_RA_RATE_MASK_NSS, rate) + 1; if (giltf) ra_report->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + mcs = ra_report->txrate.mcs; break; case RTW89_RA_RPT_MODE_HE: ra_report->txrate.flags |= RATE_INFO_FLAGS_HE_MCS; @@ -1970,6 +2022,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_1_6; else ra_report->txrate.he_gi = NL80211_RATE_INFO_HE_GI_3_2; + mcs = ra_report->txrate.mcs; break; } @@ -1977,6 +2030,7 @@ static void rtw89_phy_c2h_ra_rpt_iter(void *data, struct ieee80211_sta *sta) ra_report->bit_rate = cfg80211_calculate_bitrate(&ra_report->txrate); ra_report->hw_rate = FIELD_PREP(RTW89_HW_RATE_MASK_MOD, mode) | FIELD_PREP(RTW89_HW_RATE_MASK_VAL, rate); + ra_report->might_fallback_legacy = mcs <= 2; sta->max_rc_amsdu_len = get_max_amsdu_len(rtwdev, ra_report); rtwsta->max_agg_wait = sta->max_rc_amsdu_len / 1500 - 1; } @@ -3247,10 +3301,11 @@ static void rtw89_phy_dig_update_rssi_info(struct rtw89_dev *rtwdev) static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev) { struct rtw89_dig_info *dig = &rtwdev->dig; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); bool is_linked = rtwdev->total_sta_assoc > 0; const u16 *fa_th_src = NULL; - switch (rtwdev->hal.current_band_type) { + switch (chan->band_type) { case RTW89_BAND_2G: dig->lna_gain = dig->lna_gain_g; dig->tia_gain = dig->tia_gain_g; @@ -3483,7 +3538,8 @@ static void rtw89_phy_dig_config_igi(struct rtw89_dev *rtwdev) static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi, bool enable) { - enum rtw89_bandwidth cbw = rtwdev->hal.current_band_width; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); + enum rtw89_bandwidth cbw = chan->band_width; struct rtw89_dig_info *dig = &rtwdev->dig; u8 final_rssi = 0, under_region = dig->pd_low_th_ofst; u8 ofdm_cca_th; |