mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
mt76x2: add TPC support
add per-packet tx power adjustment support Signed-off-by: Lorenzo Bianconi <[email protected]>
This commit is contained in:
committed by
Felix Fietkau
parent
3d36d4b649
commit
aa77eadf0e
@@ -126,6 +126,7 @@ struct mt76_wcid {
|
||||
__le16 tx_rate;
|
||||
bool tx_rate_set;
|
||||
u8 tx_rate_nss;
|
||||
s8 max_txpwr_adj;
|
||||
};
|
||||
|
||||
struct mt76_txq {
|
||||
|
||||
@@ -210,4 +210,8 @@ void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
||||
|
||||
void mt76x2_update_channel(struct mt76_dev *dev);
|
||||
|
||||
s8 mt76x3_tx_get_max_txpwr_adj(struct mt76x2_dev *dev,
|
||||
const struct ieee80211_tx_rate *rate);
|
||||
s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -163,6 +163,7 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi,
|
||||
u16 rate_ht_mask = MT76_SET(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
|
||||
u16 txwi_flags = 0;
|
||||
u8 nss;
|
||||
s8 txpwr_adj, max_txpwr_adj;
|
||||
|
||||
memset(txwi, 0, sizeof(*txwi));
|
||||
|
||||
@@ -176,12 +177,18 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi,
|
||||
spin_lock_bh(&dev->mt76.lock);
|
||||
if (rate->idx < 0 || !rate->count) {
|
||||
txwi->rate = wcid->tx_rate;
|
||||
max_txpwr_adj = wcid->max_txpwr_adj;
|
||||
nss = wcid->tx_rate_nss;
|
||||
} else {
|
||||
txwi->rate = mt76x2_mac_tx_rate_val(dev, rate, &nss);
|
||||
max_txpwr_adj = mt76x3_tx_get_max_txpwr_adj(dev, rate);
|
||||
}
|
||||
spin_unlock_bh(&dev->mt76.lock);
|
||||
|
||||
txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, dev->txpower_conf,
|
||||
max_txpwr_adj);
|
||||
txwi->ctl2 = MT76_SET(MT_TX_PWR_ADJ, txpwr_adj);
|
||||
|
||||
if (mt76xx_rev(dev) >= MT76XX_REV_E4)
|
||||
txwi->txstream = 0x13;
|
||||
else if (mt76xx_rev(dev) >= MT76XX_REV_E3 &&
|
||||
|
||||
@@ -108,6 +108,8 @@ struct mt76x2_rxwi {
|
||||
#define MT_RATE_INDEX_VHT_IDX GENMASK(3, 0)
|
||||
#define MT_RATE_INDEX_VHT_NSS GENMASK(5, 4)
|
||||
|
||||
#define MT_TX_PWR_ADJ GENMASK(3, 0)
|
||||
|
||||
enum mt76x2_phy_bandwith {
|
||||
MT_PHY_BW_20,
|
||||
MT_PHY_BW_40,
|
||||
|
||||
@@ -478,6 +478,7 @@ mt76x2_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
rate.idx = rates->rate[0].idx;
|
||||
rate.flags = rates->rate[0].flags;
|
||||
mt76x2_mac_wcid_set_rate(dev, &msta->wcid, &rate);
|
||||
msta->wcid.max_txpwr_adj = mt76x3_tx_get_max_txpwr_adj(dev, &rate);
|
||||
}
|
||||
|
||||
static void mt76x2_set_coverage_class(struct ieee80211_hw *hw,
|
||||
|
||||
+52
@@ -58,6 +58,58 @@ void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
s8 mt76x3_tx_get_max_txpwr_adj(struct mt76x2_dev *dev,
|
||||
const struct ieee80211_tx_rate *rate)
|
||||
{
|
||||
s8 max_txpwr;
|
||||
|
||||
if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
u8 mcs = ieee80211_rate_get_vht_mcs(rate);
|
||||
|
||||
if (mcs == 8 || mcs == 9) {
|
||||
max_txpwr = dev->rate_power.vht[8];
|
||||
} else {
|
||||
u8 nss, idx;
|
||||
|
||||
nss = ieee80211_rate_get_vht_nss(rate);
|
||||
idx = ((nss - 1) << 3) + mcs;
|
||||
max_txpwr = dev->rate_power.ht[idx & 0xf];
|
||||
}
|
||||
} else if (rate->flags & IEEE80211_TX_RC_MCS) {
|
||||
max_txpwr = dev->rate_power.ht[rate->idx & 0xf];
|
||||
} else {
|
||||
enum nl80211_band band = dev->mt76.chandef.chan->band;
|
||||
|
||||
if (band == NL80211_BAND_2GHZ) {
|
||||
const struct ieee80211_rate *r;
|
||||
struct wiphy *wiphy = mt76_hw(dev)->wiphy;
|
||||
struct mt76_rate_power *rp = &dev->rate_power;
|
||||
|
||||
r = &wiphy->bands[band]->bitrates[rate->idx];
|
||||
if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE)
|
||||
max_txpwr = rp->cck[r->hw_value & 0x3];
|
||||
else
|
||||
max_txpwr = rp->ofdm[r->hw_value & 0x7];
|
||||
} else {
|
||||
max_txpwr = dev->rate_power.ofdm[rate->idx & 0x7];
|
||||
}
|
||||
}
|
||||
|
||||
return max_txpwr;
|
||||
}
|
||||
|
||||
s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj)
|
||||
{
|
||||
txpwr = min_t(s8, txpwr, dev->txpower_conf);
|
||||
txpwr -= (dev->target_power + dev->target_power_delta[0]);
|
||||
txpwr = min_t(s8, txpwr, max_txpwr_adj);
|
||||
|
||||
if (txpwr >= 0)
|
||||
return min_t(s8, txpwr, 7);
|
||||
else
|
||||
return (txpwr < -16) ? 8 : (txpwr + 32) / 2;
|
||||
}
|
||||
|
||||
int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
|
||||
struct sk_buff *skb, struct mt76_queue *q,
|
||||
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
|
||||
|
||||
Reference in New Issue
Block a user