From fd2d3ce742a2bd4ec6b3a1c7b1fe3c8a80c05a39 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 31 Jan 2016 22:40:25 +0100 Subject: [PATCH] mt7603: fill sta rate table Signed-off-by: Felix Fietkau --- mt7603.h | 3 +++ mt7603_mac.c | 36 ++++++++++++++++++++++++++++++++++-- mt7603_main.c | 15 +++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/mt7603.h b/mt7603.h index db4562c1..249a3e89 100644 --- a/mt7603.h +++ b/mt7603.h @@ -125,6 +125,9 @@ void mt7603_mac_start(struct mt7603_dev *dev); void mt7603_mac_stop(struct mt7603_dev *dev); int mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb); void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data); +void mt7603_mac_wtbl_set_rates(struct mt7603_dev *dev, int wcid, + struct ieee80211_tx_rate *rates, + int n_rates); int mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def); int mt7603_mcu_set_channel(struct mt7603_dev *dev); diff --git a/mt7603_mac.c b/mt7603_mac.c index a9e2305a..a55df5cf 100644 --- a/mt7603_mac.c +++ b/mt7603_mac.c @@ -50,6 +50,13 @@ mt7603_wtbl_update(struct mt7603_dev *dev, int idx, u32 mask) mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000); } +static u32 +mt7603_wtbl2_addr(int idx) +{ + /* Mapped to WTBL2 */ + return MT_PCIE_REMAP_BASE_1 + idx * MT_WTBL2_SIZE; +} + void mt7603_wtbl_init(struct mt7603_dev *dev, int idx, const u8 *mac_addr) { const void *_mac = mac_addr; @@ -92,8 +99,7 @@ void mt7603_wtbl_clear(struct mt7603_dev *dev, int idx) mt76_clear(dev, MT_WTBL1_OR, MT_WTBL1_OR_PSM_WRITE); - /* Mapped to WTBL2 */ - addr = MT_PCIE_REMAP_BASE_1 + idx * MT_WTBL2_SIZE; + addr = mt7603_wtbl2_addr(idx); /* Clear BA information */ mt76_wr(dev, addr + (15 * 4), 0); @@ -269,6 +275,32 @@ mt7603_mac_tx_rate_val(struct mt7603_dev *dev, MT76_SET(MT_TX_RATE_MODE, phy)); } +void mt7603_mac_wtbl_set_rates(struct mt7603_dev *dev, int wcid, + struct ieee80211_tx_rate *rates, + int n_rates) +{ + u32 addr = mt7603_wtbl2_addr(wcid); + u8 nss, bw; + u16 val; + int i; + + for (i = n_rates; i < 4; i++) + rates[i] = rates[n_rates - 1]; + + val = mt7603_mac_tx_rate_val(dev, &rates[0], &nss, &bw); + mt76_rmw_field(dev, addr + 10 * 4, MT_WTBL2_W10_RATE1, val); + + val = mt7603_mac_tx_rate_val(dev, &rates[1], &nss, &bw); + mt76_rmw_field(dev, addr + 10 * 4, MT_WTBL2_W10_RATE2, val); + + val = mt7603_mac_tx_rate_val(dev, &rates[2], &nss, &bw); + mt76_rmw_field(dev, addr + 10 * 4, MT_WTBL2_W10_RATE3_LO, val); + mt76_rmw_field(dev, addr + 11 * 4, MT_WTBL2_W11_RATE3_HI, val >> 4); + + val = mt7603_mac_tx_rate_val(dev, &rates[3], &nss, &bw); + mt76_rmw_field(dev, addr + 11 * 4, MT_WTBL2_W11_RATE4, val); +} + int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta) diff --git a/mt7603_main.c b/mt7603_main.c index 09955164..8d597e4f 100644 --- a/mt7603_main.c +++ b/mt7603_main.c @@ -222,6 +222,21 @@ static void mt7603_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { + struct mt7603_dev *dev = hw->priv; + struct mt7603_sta *msta = (struct mt7603_sta *) sta->drv_priv; + struct ieee80211_sta_rates *sta_rates = rcu_dereference(sta->rates); + struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES] = {}; + int i; + + for (i = 0; i < ARRAY_SIZE(rates); i++) { + rates[i].idx = sta_rates->rate[i].idx; + rates[i].count = sta_rates->rate[i].count; + rates[i].flags = sta_rates->rate[i].flags; + if (rates[i].idx < 0 || !rates[i].count) + break; + } + + mt7603_mac_wtbl_set_rates(dev, msta->wcid.idx, rates, i); } static void mt7603_set_coverage_class(struct ieee80211_hw *hw,