summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2018-09-04 16:41:07 +0200
committerFelix Fietkau <nbd@nbd.name>2018-09-19 12:29:16 +0200
commit5327b5ea13910df072772219e303a3d6cc5f992e (patch)
tree7cf9d77a072c443104a63e4f7b83afc9a61d72a7 /drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
parent212926eb449309489b55ae46e433d26808337bcf (diff)
mt76: unify sta_rate_tbl_update and related helpers
Use common sta_rate_tbl_update on mt76x0 and mt76x2. mt76x0 do not have support TPC (transmision power control) implmented, msta->wcid.max_txpwr_adj is only set for mt76x2. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt76x02_mac.c')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x02_mac.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 67c53089229e..d67e12bd23a7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -155,3 +155,64 @@ void mt76x02_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq)
mt76_txq_init(dev, txq);
}
EXPORT_SYMBOL_GPL(mt76x02_txq_init);
+
+__le16
+mt76x02_mac_tx_rate_val(struct mt76_dev *dev,
+ const struct ieee80211_tx_rate *rate, u8 *nss_val)
+{
+ u16 rateval;
+ u8 phy, rate_idx;
+ u8 nss = 1;
+ u8 bw = 0;
+
+ if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
+ rate_idx = rate->idx;
+ nss = 1 + (rate->idx >> 4);
+ phy = MT_PHY_TYPE_VHT;
+ if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+ bw = 2;
+ else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ bw = 1;
+ } else if (rate->flags & IEEE80211_TX_RC_MCS) {
+ rate_idx = rate->idx;
+ nss = 1 + (rate->idx >> 3);
+ phy = MT_PHY_TYPE_HT;
+ if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+ phy = MT_PHY_TYPE_HT_GF;
+ if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ bw = 1;
+ } else {
+ const struct ieee80211_rate *r;
+ int band = dev->chandef.chan->band;
+ u16 val;
+
+ r = &dev->hw->wiphy->bands[band]->bitrates[rate->idx];
+ if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ val = r->hw_value_short;
+ else
+ val = r->hw_value;
+
+ phy = val >> 8;
+ rate_idx = val & 0xff;
+ bw = 0;
+ }
+
+ rateval = FIELD_PREP(MT_RXWI_RATE_INDEX, rate_idx);
+ rateval |= FIELD_PREP(MT_RXWI_RATE_PHY, phy);
+ rateval |= FIELD_PREP(MT_RXWI_RATE_BW, bw);
+ if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+ rateval |= MT_RXWI_RATE_SGI;
+
+ *nss_val = nss;
+ return cpu_to_le16(rateval);
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_tx_rate_val);
+
+void mt76x02_mac_wcid_set_rate(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ const struct ieee80211_tx_rate *rate)
+{
+ spin_lock_bh(&dev->lock);
+ wcid->tx_rate = mt76x02_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss);
+ wcid->tx_rate_set = true;
+ spin_unlock_bh(&dev->lock);
+}