2021-07-14 05:37:42

by Ryder Lee

[permalink] [raw]
Subject: [PATCH 1/3] mt76 mt7915: take RCU read lock when calling ieee80211_bss_get_elem()

As ieee80211_bss_get_elem() derefences an RCU to return ssid_ie, both
the call to this function and any operation on this variable need
protection by the RCU read lock.

Signed-off-by: Ryder Lee <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 863aa18b3024..4d2e5b5e6389 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -923,12 +923,15 @@ static void mt7915_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
struct mt7915_he_obss_narrow_bw_ru_data *data = _data;
const struct element *elem;

+ rcu_read_lock();
elem = ieee80211_bss_get_elem(bss, WLAN_EID_EXT_CAPABILITY);

if (!elem || elem->datalen < 10 ||
!(elem->data[10] &
WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT))
data->tolerated = false;
+
+ rcu_read_unlock();
}

static bool mt7915_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
--
2.29.2


2021-07-14 05:37:42

by Ryder Lee

[permalink] [raw]
Subject: [PATCH 3/3] mt76: mt7915: remove mt7915_sta_stats

mt7915_sta_stats is no longer needed after tx rate reworking.

Signed-off-by: Ryder Lee <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 8 ++++----
drivers/net/wireless/mediatek/mt76/mt7915/main.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h | 9 ++-------
3 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 6962446c9d3c..16d60cf4b1e3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1058,9 +1058,9 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,

msta = (struct mt7915_sta *)sta->drv_priv;

- if (time_after(jiffies, msta->stats.jiffies + HZ / 4)) {
+ if (time_after(jiffies, msta->jiffies + HZ / 4)) {
info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
- msta->stats.jiffies = jiffies;
+ msta->jiffies = jiffies;
}
}

@@ -1879,8 +1879,8 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
while (!list_empty(&list)) {
msta = list_first_entry(&list, struct mt7915_sta, rc_list);
list_del_init(&msta->rc_list);
- changed = msta->stats.changed;
- msta->stats.changed = 0;
+ changed = msta->changed;
+ msta->changed = 0;
spin_unlock_bh(&dev->sta_poll_lock);

sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 953d5caae5c2..825cb44c9107 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -623,7 +623,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
msta->wcid.idx = idx;
msta->wcid.ext_phy = mvif->band_idx;
msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
- msta->stats.jiffies = jiffies;
+ msta->jiffies = jiffies;

mt7915_mac_wtbl_update(dev, idx,
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
@@ -955,7 +955,7 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
u32 *changed = data;

spin_lock_bh(&dev->sta_poll_lock);
- msta->stats.changed |= *changed;
+ msta->changed |= *changed;
if (list_empty(&msta->rc_list))
list_add_tail(&msta->rc_list, &dev->sta_rc_list);
spin_unlock_bh(&dev->sta_poll_lock);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index a9c36b515aa6..33be449309e0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -64,11 +64,6 @@ enum mt7915_rxq_id {
MT7915_RXQ_MCU_WA_EXT,
};

-struct mt7915_sta_stats {
- unsigned long changed;
- unsigned long jiffies;
-};
-
struct mt7915_sta_key_conf {
s8 keyidx;
u8 key[16];
@@ -83,8 +78,8 @@ struct mt7915_sta {
struct list_head rc_list;
u32 airtime_ac[8];

- struct mt7915_sta_stats stats;
-
+ unsigned long changed;
+ unsigned long jiffies;
unsigned long ampdu_state;

struct mt7915_sta_key_conf bip;
--
2.29.2

2021-07-14 05:37:42

by Ryder Lee

[permalink] [raw]
Subject: [PATCH 2/3] mt76: mt7915: report tx rate directly from tx status

Report tx rate from tx status packets instead of receving periodic mcu
event. This improves flexibility, accuracy and AQL performance, and
simplifies code flow for better readability.

Signed-off-by: Ryder Lee <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 +
.../wireless/mediatek/mt76/mt7915/debugfs.c | 47 -----
.../net/wireless/mediatek/mt76/mt7915/init.c | 2 -
.../net/wireless/mediatek/mt76/mt7915/mac.c | 174 ++++++++++++++----
.../net/wireless/mediatek/mt76/mt7915/main.c | 26 ++-
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 168 -----------------
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 43 -----
.../wireless/mediatek/mt76/mt7915/mt7915.h | 17 --
drivers/net/wireless/mediatek/mt76/tx.c | 6 +-
9 files changed, 154 insertions(+), 331 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 25c5ceef5257..b41faedee001 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -244,6 +244,8 @@ struct mt76_wcid {
struct ewma_signal rssi;
int inactive_count;

+ struct rate_info rate;
+
u16 idx;
u8 hw_key_idx;
u8 hw_key_idx2;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index 64048243e34b..1a48b09d0cb7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -377,56 +377,9 @@ static int mt7915_sta_fixed_rate_set(void *data, u64 rate)
DEFINE_DEBUGFS_ATTRIBUTE(fops_fixed_rate, NULL,
mt7915_sta_fixed_rate_set, "%llx\n");

-static int
-mt7915_sta_stats_show(struct seq_file *s, void *data)
-{
- struct ieee80211_sta *sta = s->private;
- struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
- struct mt7915_sta_stats *stats = &msta->stats;
- struct rate_info *rate = &stats->prob_rate;
- static const char * const bw[] = {
- "BW20", "BW5", "BW10", "BW40",
- "BW80", "BW160", "BW_HE_RU"
- };
-
- if (!rate->legacy && !rate->flags)
- return 0;
-
- seq_puts(s, "Probing rate - ");
- if (rate->flags & RATE_INFO_FLAGS_MCS)
- seq_puts(s, "HT ");
- else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
- seq_puts(s, "VHT ");
- else if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
- seq_puts(s, "HE ");
- else
- seq_printf(s, "Bitrate %d\n", rate->legacy);
-
- if (rate->flags) {
- seq_printf(s, "%s NSS%d MCS%d ",
- bw[rate->bw], rate->nss, rate->mcs);
-
- if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
- seq_puts(s, "SGI ");
- else if (rate->he_gi)
- seq_puts(s, "HE GI ");
-
- if (rate->he_dcm)
- seq_puts(s, "DCM ");
- }
-
- seq_printf(s, "\nPPDU PER: %ld.%1ld%%\n",
- stats->per / 10, stats->per % 10);
-
- return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(mt7915_sta_stats);
-
void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct dentry *dir)
{
debugfs_create_file("fixed_rate", 0600, dir, sta, &fops_fixed_rate);
- debugfs_create_file("stats", 0400, dir, sta, &mt7915_sta_stats_fops);
}
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 4798d6344305..eb4c4991d020 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -350,7 +350,6 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev)
mphy->chainmask = dev->chainmask & ~dev->mphy.chainmask;
mphy->antenna_mask = BIT(hweight8(mphy->chainmask)) - 1;

- INIT_LIST_HEAD(&phy->stats_list);
INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work);

mt7915_eeprom_parse_band_config(phy);
@@ -787,7 +786,6 @@ int mt7915_register_device(struct mt7915_dev *dev)
dev->phy.dev = dev;
dev->phy.mt76 = &dev->mt76.phy;
dev->mt76.phy.priv = &dev->phy;
- INIT_LIST_HEAD(&dev->phy.stats_list);
INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work);
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
INIT_LIST_HEAD(&dev->sta_rc_list);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 2462704094b0..6962446c9d3c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -88,15 +88,14 @@ bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask)
0, 5000);
}

-static u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid)
+static u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw)
{
mt76_wr(dev, MT_WTBLON_TOP_WDUCR,
FIELD_PREP(MT_WTBLON_TOP_WDUCR_GROUP, (wcid >> 7)));

- return MT_WTBL_LMAC_OFFS(wcid, 0);
+ return MT_WTBL_LMAC_OFFS(wcid, dw);
}

-/* TODO: use txfree airtime info to avoid runtime accessing in the long run */
static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
{
static const u8 ac_to_tid[] = {
@@ -107,6 +106,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
};
struct ieee80211_sta *sta;
struct mt7915_sta *msta;
+ struct rate_info *rate;
u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
LIST_HEAD(sta_poll_list);
int i;
@@ -119,8 +119,9 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)

while (true) {
bool clear = false;
- u32 addr;
+ u32 addr, val;
u16 idx;
+ u8 bw;

spin_lock_bh(&dev->sta_poll_lock);
if (list_empty(&sta_poll_list)) {
@@ -133,7 +134,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
spin_unlock_bh(&dev->sta_poll_lock);

idx = msta->wcid.idx;
- addr = mt7915_mac_wtbl_lmac_addr(dev, idx) + 20 * 4;
+ addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 20);

for (i = 0; i < IEEE80211_NUM_ACS; i++) {
u32 tx_last = msta->airtime_ac[i];
@@ -174,6 +175,42 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
ieee80211_sta_register_airtime(sta, tid, tx_cur,
rx_cur);
}
+
+ /*
+ * We don't support reading GI info from txs packets.
+ * For accurate tx status reporting and AQL improvement,
+ * we need to make sure that flags match so polling GI
+ * from per-sta counters directly.
+ */
+ rate = &msta->wcid.rate;
+ addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 7);
+ val = mt76_rr(dev, addr);
+
+ switch (rate->bw) {
+ case RATE_INFO_BW_160:
+ bw = IEEE80211_STA_RX_BW_160;
+ break;
+ case RATE_INFO_BW_80:
+ bw = IEEE80211_STA_RX_BW_80;
+ break;
+ case RATE_INFO_BW_40:
+ bw = IEEE80211_STA_RX_BW_40;
+ break;
+ default:
+ bw = IEEE80211_STA_RX_BW_20;
+ break;
+ }
+
+ if (rate->flags & RATE_INFO_FLAGS_HE_MCS) {
+ u8 offs = 24 + 2 * bw;
+
+ rate->he_gi = (val & (0x3 << offs)) >> offs;
+ } else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS) {
+ if (val & BIT(12 + bw))
+ rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
+ else
+ rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;
+ }
}

rcu_read_unlock();
@@ -1016,6 +1053,17 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
if (!wcid)
wcid = &dev->mt76.global_wcid;

+ if (sta) {
+ struct mt7915_sta *msta;
+
+ msta = (struct mt7915_sta *)sta->drv_priv;
+
+ if (time_after(jiffies, msta->stats.jiffies + HZ / 4)) {
+ info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
+ msta->stats.jiffies = jiffies;
+ }
+ }
+
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);

mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key,
@@ -1184,8 +1232,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
msta = container_of(wcid, struct mt7915_sta, wcid);
phy = msta->vif->phy;
spin_lock_bh(&dev->sta_poll_lock);
- if (list_empty(&msta->stats_list))
- list_add_tail(&msta->stats_list, &phy->stats_list);
if (list_empty(&msta->poll_list))
list_add_tail(&msta->poll_list, &dev->sta_poll_list);
spin_unlock_bh(&dev->sta_poll_lock);
@@ -1221,18 +1267,26 @@ static bool
mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
__le32 *txs_data)
{
+ struct ieee80211_supported_band *sband;
+ struct mt7915_sta *msta;
struct mt76_dev *mdev = &dev->mt76;
+ struct mt76_phy *mphy;
struct ieee80211_tx_info *info;
struct sk_buff_head list;
+ struct rate_info rate = {};
struct sk_buff *skb;
+ bool cck = false;
+ u32 txrate, txs;

mt76_tx_status_lock(mdev, &list);
skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
if (!skb)
goto out;

+ txs = le32_to_cpu(txs_data[0]);
+
info = IEEE80211_SKB_CB(skb);
- if (!(txs_data[0] & le32_to_cpu(MT_TXS0_ACK_ERROR_MASK)))
+ if (!(txs & MT_TXS0_ACK_ERROR_MASK))
info->flags |= IEEE80211_TX_STAT_ACK;

info->status.ampdu_len = 1;
@@ -1240,9 +1294,82 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
IEEE80211_TX_STAT_ACK);

info->status.rates[0].idx = -1;
- mt76_tx_status_skb_done(mdev, skb, &list);
+
+ if (!wcid->sta)
+ goto out;
+
+ msta = container_of(wcid, struct mt7915_sta, wcid);
+ txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
+
+ rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
+ rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;
+
+ switch (FIELD_GET(MT_TX_RATE_MODE, txrate)) {
+ case MT_PHY_TYPE_CCK:
+ cck = true;
+ fallthrough;
+ case MT_PHY_TYPE_OFDM:
+ mphy = &dev->mphy;
+ if (wcid->ext_phy && dev->mt76.phy2)
+ mphy = dev->mt76.phy2;
+
+ if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
+ sband = &mphy->sband_5g.sband;
+ else
+ sband = &mphy->sband_2g.sband;
+
+ rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs, cck);
+ rate.legacy = sband->bitrates[rate.mcs].bitrate;
+ break;
+ case MT_PHY_TYPE_HT:
+ case MT_PHY_TYPE_HT_GF:
+ rate.mcs += (rate.nss - 1) * 8;
+ if (rate.mcs > 31)
+ goto out;
+
+ rate.flags = RATE_INFO_FLAGS_MCS;
+ if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
+ rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ break;
+ case MT_PHY_TYPE_VHT:
+ if (rate.mcs > 9)
+ goto out;
+
+ rate.flags = RATE_INFO_FLAGS_VHT_MCS;
+ break;
+ case MT_PHY_TYPE_HE_SU:
+ case MT_PHY_TYPE_HE_EXT_SU:
+ case MT_PHY_TYPE_HE_TB:
+ case MT_PHY_TYPE_HE_MU:
+ if (rate.mcs > 11)
+ goto out;
+
+ rate.he_gi = wcid->rate.he_gi;
+ rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
+ rate.flags = RATE_INFO_FLAGS_HE_MCS;
+ break;
+ default:
+ goto out;
+ }
+
+ switch (FIELD_GET(MT_TXS0_BW, txs)) {
+ case IEEE80211_STA_RX_BW_160:
+ rate.bw = RATE_INFO_BW_160;
+ break;
+ case IEEE80211_STA_RX_BW_80:
+ rate.bw = RATE_INFO_BW_80;
+ break;
+ case IEEE80211_STA_RX_BW_40:
+ rate.bw = RATE_INFO_BW_40;
+ break;
+ default:
+ rate.bw = RATE_INFO_BW_20;
+ break;
+ }
+ wcid->rate = rate;

out:
+ mt76_tx_status_skb_done(mdev, skb, &list);
mt76_tx_status_unlock(mdev, &list);

return !!skb;
@@ -1737,30 +1864,6 @@ mt7915_mac_update_stats(struct mt7915_phy *phy)
}
}

-static void
-mt7915_mac_sta_stats_work(struct mt7915_phy *phy)
-{
- struct mt7915_dev *dev = phy->dev;
- struct mt7915_sta *msta;
- LIST_HEAD(list);
-
- spin_lock_bh(&dev->sta_poll_lock);
- list_splice_init(&phy->stats_list, &list);
-
- while (!list_empty(&list)) {
- msta = list_first_entry(&list, struct mt7915_sta, stats_list);
- list_del_init(&msta->stats_list);
- spin_unlock_bh(&dev->sta_poll_lock);
-
- /* use MT_TX_FREE_RATE to report Tx rate for further devices */
- mt7915_mcu_get_tx_rate(dev, RATE_CTRL_RU_INFO, msta->wcid.idx);
-
- spin_lock_bh(&dev->sta_poll_lock);
- }
-
- spin_unlock_bh(&dev->sta_poll_lock);
-}
-
void mt7915_mac_sta_rc_work(struct work_struct *work)
{
struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
@@ -1817,11 +1920,6 @@ void mt7915_mac_work(struct work_struct *work)
mt7915_mac_update_stats(phy);
}

- if (++phy->sta_work_count == 10) {
- phy->sta_work_count = 0;
- mt7915_mac_sta_stats_work(phy);
- }
-
mutex_unlock(&mphy->dev->mutex);

mt76_tx_status_check(mphy->dev, NULL, false);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index c25f8da590dd..953d5caae5c2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -231,7 +231,6 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
idx = MT7915_WTBL_RESERVED - mvif->idx;

INIT_LIST_HEAD(&mvif->sta.rc_list);
- INIT_LIST_HEAD(&mvif->sta.stats_list);
INIT_LIST_HEAD(&mvif->sta.poll_list);
mvif->sta.wcid.idx = idx;
mvif->sta.wcid.ext_phy = mvif->band_idx;
@@ -618,7 +617,6 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
return -ENOSPC;

INIT_LIST_HEAD(&msta->rc_list);
- INIT_LIST_HEAD(&msta->stats_list);
INIT_LIST_HEAD(&msta->poll_list);
msta->vif = mvif;
msta->wcid.sta = 1;
@@ -652,8 +650,6 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
spin_lock_bh(&dev->sta_poll_lock);
if (!list_empty(&msta->poll_list))
list_del_init(&msta->poll_list);
- if (!list_empty(&msta->stats_list))
- list_del_init(&msta->stats_list);
if (!list_empty(&msta->rc_list))
list_del_init(&msta->rc_list);
spin_unlock_bh(&dev->sta_poll_lock);
@@ -926,7 +922,7 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
{
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
- struct mt7915_sta_stats *stats = &msta->stats;
+ struct rate_info *txrate = &msta->wcid.rate;
struct rate_info rxrate = {};

if (!mt7915_mcu_get_rx_rate(phy, vif, sta, &rxrate)) {
@@ -934,20 +930,20 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw,
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
}

- if (!stats->tx_rate.legacy && !stats->tx_rate.flags)
+ if (!txrate->legacy && !txrate->flags)
return;

- if (stats->tx_rate.legacy) {
- sinfo->txrate.legacy = stats->tx_rate.legacy;
+ if (txrate->legacy) {
+ sinfo->txrate.legacy = txrate->legacy;
} else {
- sinfo->txrate.mcs = stats->tx_rate.mcs;
- sinfo->txrate.nss = stats->tx_rate.nss;
- sinfo->txrate.bw = stats->tx_rate.bw;
- sinfo->txrate.he_gi = stats->tx_rate.he_gi;
- sinfo->txrate.he_dcm = stats->tx_rate.he_dcm;
- sinfo->txrate.he_ru_alloc = stats->tx_rate.he_ru_alloc;
+ sinfo->txrate.mcs = txrate->mcs;
+ sinfo->txrate.nss = txrate->nss;
+ sinfo->txrate.bw = txrate->bw;
+ sinfo->txrate.he_gi = txrate->he_gi;
+ sinfo->txrate.he_dcm = txrate->he_dcm;
+ sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;
}
- sinfo->txrate.flags = stats->tx_rate.flags;
+ sinfo->txrate.flags = txrate->flags;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 4d2e5b5e6389..8d646aa3d084 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -488,152 +488,6 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
dev->hw_pattern++;
}

-static int
-mt7915_mcu_tx_rate_parse(struct mt76_phy *mphy, struct mt7915_mcu_ra_info *ra,
- struct rate_info *rate, u16 r)
-{
- struct ieee80211_supported_band *sband;
- u16 ru_idx = le16_to_cpu(ra->ru_idx);
- bool cck = false;
-
- rate->mcs = FIELD_GET(MT_RA_RATE_MCS, r);
- rate->nss = FIELD_GET(MT_RA_RATE_NSS, r) + 1;
-
- switch (FIELD_GET(MT_RA_RATE_TX_MODE, r)) {
- case MT_PHY_TYPE_CCK:
- cck = true;
- fallthrough;
- case MT_PHY_TYPE_OFDM:
- if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
- sband = &mphy->sband_5g.sband;
- else
- sband = &mphy->sband_2g.sband;
-
- rate->mcs = mt76_get_rate(mphy->dev, sband, rate->mcs, cck);
- rate->legacy = sband->bitrates[rate->mcs].bitrate;
- break;
- case MT_PHY_TYPE_HT:
- case MT_PHY_TYPE_HT_GF:
- rate->mcs += (rate->nss - 1) * 8;
- if (rate->mcs > 31)
- return -EINVAL;
-
- rate->flags = RATE_INFO_FLAGS_MCS;
- if (ra->gi)
- rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
- break;
- case MT_PHY_TYPE_VHT:
- if (rate->mcs > 9)
- return -EINVAL;
-
- rate->flags = RATE_INFO_FLAGS_VHT_MCS;
- if (ra->gi)
- rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
- break;
- case MT_PHY_TYPE_HE_SU:
- case MT_PHY_TYPE_HE_EXT_SU:
- case MT_PHY_TYPE_HE_TB:
- case MT_PHY_TYPE_HE_MU:
- if (ra->gi > NL80211_RATE_INFO_HE_GI_3_2 || rate->mcs > 11)
- return -EINVAL;
-
- rate->he_gi = ra->gi;
- rate->he_dcm = FIELD_GET(MT_RA_RATE_DCM_EN, r);
- rate->flags = RATE_INFO_FLAGS_HE_MCS;
- break;
- default:
- return -EINVAL;
- }
-
- if (ru_idx) {
- switch (ru_idx) {
- case 1 ... 2:
- rate->he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_996;
- break;
- case 3 ... 6:
- rate->he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_484;
- break;
- case 7 ... 14:
- rate->he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_242;
- break;
- default:
- rate->he_ru_alloc = NL80211_RATE_INFO_HE_RU_ALLOC_106;
- break;
- }
- rate->bw = RATE_INFO_BW_HE_RU;
- } else {
- u8 bw = mt7915_mcu_chan_bw(&mphy->chandef) -
- FIELD_GET(MT_RA_RATE_BW, r);
-
- switch (bw) {
- case IEEE80211_STA_RX_BW_160:
- rate->bw = RATE_INFO_BW_160;
- break;
- case IEEE80211_STA_RX_BW_80:
- rate->bw = RATE_INFO_BW_80;
- break;
- case IEEE80211_STA_RX_BW_40:
- rate->bw = RATE_INFO_BW_40;
- break;
- default:
- rate->bw = RATE_INFO_BW_20;
- break;
- }
- }
-
- return 0;
-}
-
-static void
-mt7915_mcu_tx_rate_report(struct mt7915_dev *dev, struct sk_buff *skb)
-{
- struct mt7915_mcu_ra_info *ra = (struct mt7915_mcu_ra_info *)skb->data;
- struct rate_info rate = {}, prob_rate = {};
- u16 probe = le16_to_cpu(ra->prob_up_rate);
- u16 attempts = le16_to_cpu(ra->attempts);
- u16 curr = le16_to_cpu(ra->curr_rate);
- u16 wcidx = le16_to_cpu(ra->wlan_idx);
- struct ieee80211_tx_status status = {};
- struct mt76_phy *mphy = &dev->mphy;
- struct mt7915_sta_stats *stats;
- struct mt7915_sta *msta;
- struct mt76_wcid *wcid;
-
- if (wcidx >= MT76_N_WCIDS)
- return;
-
- wcid = rcu_dereference(dev->mt76.wcid[wcidx]);
- if (!wcid)
- return;
-
- msta = container_of(wcid, struct mt7915_sta, wcid);
- stats = &msta->stats;
-
- if (msta->wcid.ext_phy && dev->mt76.phy2)
- mphy = dev->mt76.phy2;
-
- /* current rate */
- if (!mt7915_mcu_tx_rate_parse(mphy, ra, &rate, curr))
- stats->tx_rate = rate;
-
- /* probing rate */
- if (!mt7915_mcu_tx_rate_parse(mphy, ra, &prob_rate, probe))
- stats->prob_rate = prob_rate;
-
- if (attempts) {
- u16 success = le16_to_cpu(ra->success);
-
- stats->per = 1000 * (attempts - success) / attempts;
- }
-
- status.sta = wcid_to_sta(wcid);
- if (!status.sta)
- return;
-
- status.rate = &stats->tx_rate;
- ieee80211_tx_status_ext(mphy->hw, &status);
-}
-
static void
mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb)
{
@@ -672,9 +526,6 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
case MCU_EXT_EVENT_CSA_NOTIFY:
mt7915_mcu_rx_csa_notify(dev, skb);
break;
- case MCU_EXT_EVENT_RATE_REPORT:
- mt7915_mcu_tx_rate_report(dev, skb);
- break;
case MCU_EXT_EVENT_FW_LOG_2_HOST:
mt7915_mcu_rx_log_message(dev, skb);
break;
@@ -706,7 +557,6 @@ void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb)
rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
- rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT ||
!rxd->seq)
mt7915_mcu_rx_unsolicited_event(dev, skb);
else
@@ -3736,24 +3586,6 @@ int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state)
&req, sizeof(req), false);
}

-int mt7915_mcu_get_tx_rate(struct mt7915_dev *dev, u32 cmd, u16 wlan_idx)
-{
- struct {
- __le32 cmd;
- __le16 wlan_idx;
- __le16 ru_idx;
- __le16 direction;
- __le16 dump_group;
- } req = {
- .cmd = cpu_to_le32(cmd),
- .wlan_idx = cpu_to_le16(wlan_idx),
- .dump_group = cpu_to_le16(1),
- };
-
- return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RATE_CTRL), &req,
- sizeof(req), false);
-}
-
int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index edd3ba3a0c2d..31c31a2a532b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -43,7 +43,6 @@ enum {
MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
MCU_EXT_EVENT_RDD_REPORT = 0x3a,
MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
- MCU_EXT_EVENT_RATE_REPORT = 0x87,
};

enum {
@@ -164,41 +163,6 @@ struct mt7915_mcu_eeprom_info {
u8 data[16];
} __packed;

-struct mt7915_mcu_ra_info {
- struct mt7915_mcu_rxd rxd;
-
- __le32 event_id;
- __le16 wlan_idx;
- __le16 ru_idx;
- __le16 direction;
- __le16 dump_group;
-
- __le32 suggest_rate;
- __le32 min_rate; /* for dynamic sounding */
- __le32 max_rate; /* for dynamic sounding */
- __le32 init_rate_down_rate;
-
- __le16 curr_rate;
- __le16 init_rate_down_total;
- __le16 init_rate_down_succ;
- __le16 success;
- __le16 attempts;
-
- __le16 prev_rate;
- __le16 prob_up_rate;
- u8 no_rate_up_cnt;
- u8 ppdu_cnt;
- u8 gi;
-
- u8 try_up_fail;
- u8 try_up_total;
- u8 suggest_wf;
- u8 try_up_check;
- u8 prob_up_period;
- u8 prob_down_pending;
-} __packed;
-
-
struct mt7915_mcu_phy_rx_info {
u8 category;
u8 rate;
@@ -210,12 +174,6 @@ struct mt7915_mcu_phy_rx_info {
u8 bw;
};

-#define MT_RA_RATE_NSS GENMASK(8, 6)
-#define MT_RA_RATE_MCS GENMASK(3, 0)
-#define MT_RA_RATE_TX_MODE GENMASK(12, 9)
-#define MT_RA_RATE_DCM_EN BIT(4)
-#define MT_RA_RATE_BW GENMASK(14, 13)
-
struct mt7915_mcu_mib {
__le32 band;
__le32 offs;
@@ -318,7 +276,6 @@ enum {
MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
MCU_EXT_CMD_SCS_CTRL = 0x82,
- MCU_EXT_CMD_RATE_CTRL = 0x87,
MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
MCU_EXT_CMD_SET_RDD_TH = 0x9d,
MCU_EXT_CMD_SET_SPR = 0xa8,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 3f613fae6218..a9c36b515aa6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -65,10 +65,6 @@ enum mt7915_rxq_id {
};

struct mt7915_sta_stats {
- struct rate_info prob_rate;
- struct rate_info tx_rate;
-
- unsigned long per;
unsigned long changed;
unsigned long jiffies;
};
@@ -83,7 +79,6 @@ struct mt7915_sta {

struct mt7915_vif *vif;

- struct list_head stats_list;
struct list_head poll_list;
struct list_head rc_list;
u32 airtime_ac[8];
@@ -94,7 +89,6 @@ struct mt7915_sta {

struct mt7915_sta_key_conf bip;
};
-
struct mt7915_vif {
u16 idx;
u8 omac_idx;
@@ -151,9 +145,6 @@ struct mt7915_phy {

struct mib_stats mib;
struct mt76_channel_state state_ts;
- struct list_head stats_list;
-
- u8 sta_work_count;

#ifdef CONFIG_NL80211_TESTMODE
struct {
@@ -250,13 +241,6 @@ enum mt7915_rdd_cmd {
RDD_IRQ_OFF,
};

-enum {
- RATE_CTRL_RU_INFO,
- RATE_CTRL_FIXED_RATE_INFO,
- RATE_CTRL_DUMP_INFO,
- RATE_CTRL_MU_INFO,
-};
-
static inline struct mt7915_phy *
mt7915_hw_phy(struct ieee80211_hw *hw)
{
@@ -367,7 +351,6 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy);
int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
int mt7915_mcu_get_temperature(struct mt7915_phy *phy);
int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state);
-int mt7915_mcu_get_tx_rate(struct mt7915_dev *dev, u32 cmd, u16 wlan_idx);
int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct rate_info *rate);
int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev, enum mt7915_rdd_cmd cmd,
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index f0f7a913eaab..6f302acb6e69 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -64,9 +64,13 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
struct mt76_wcid *wcid;

wcid = rcu_dereference(dev->wcid[cb->wcid]);
- if (wcid)
+ if (wcid) {
status.sta = wcid_to_sta(wcid);

+ if (status.sta)
+ status.rate = &wcid->rate;
+ }
+
hw = mt76_tx_status_get_hw(dev, skb);
ieee80211_tx_status_ext(hw, &status);
}
--
2.29.2

2021-07-14 07:36:00

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/3] mt76 mt7915: take RCU read lock when calling ieee80211_bss_get_elem()

On Wed, 2021-07-14 at 13:36 +0800, Ryder Lee wrote:
>
>   if (!elem || elem->datalen < 10 ||
>   !(elem->data[10] &
>   WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT))
>   data->tolerated = false;

Unrelated to this patch, but that looks like an off-by-one?

If datalen == 10, then you can only access data[0] through data[9], not
data[10]?

johannes

2021-07-14 08:04:10

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 2/3] mt76: mt7915: report tx rate directly from tx status

Hi Ryder,

I love your patch! Perhaps something to improve:

[auto build test WARNING on wireless-drivers-next/master]
[also build test WARNING on v5.14-rc1 next-20210714]
[cannot apply to wireless-drivers/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Ryder-Lee/mt76-mt7915-take-RCU-read-lock-when-calling-ieee80211_bss_get_elem/20210714-133745
base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/787e54058191f647390d63f0f608de62a3d3a3e8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Ryder-Lee/mt76-mt7915-take-RCU-read-lock-when-calling-ieee80211_bss_get_elem/20210714-133745
git checkout 787e54058191f647390d63f0f608de62a3d3a3e8
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

drivers/net/wireless/mediatek/mt76/mt7915/mac.c: In function 'mt7915_mac_tx_free':
>> drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1221:23: warning: variable 'phy' set but not used [-Wunused-but-set-variable]
1221 | struct mt7915_phy *phy;
| ^~~
drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1213:6: warning: variable 'stat' set but not used [-Wunused-but-set-variable]
1213 | u8 stat;
| ^~~~
drivers/net/wireless/mediatek/mt76/mt7915/mac.c: In function 'mt7915_mac_add_txs_skb':
>> drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1271:21: warning: variable 'msta' set but not used [-Wunused-but-set-variable]
1271 | struct mt7915_sta *msta;
| ^~~~
drivers/net/wireless/mediatek/mt76/mt7915/mac.c: In function 'mt7915_tx_complete_skb':
drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1463:21: warning: variable 'dev' set but not used [-Wunused-but-set-variable]
1463 | struct mt7915_dev *dev;
| ^~~


vim +/phy +1221 drivers/net/wireless/mediatek/mt76/mt7915/mac.c

e57b7901469fc0 Ryder Lee 2020-04-25 1183
338330bd26b1fe Felix Fietkau 2021-05-07 1184 static void
338330bd26b1fe Felix Fietkau 2021-05-07 1185 mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
e57b7901469fc0 Ryder Lee 2020-04-25 1186 {
e57b7901469fc0 Ryder Lee 2020-04-25 1187 struct mt7915_tx_free *free = (struct mt7915_tx_free *)skb->data;
e57b7901469fc0 Ryder Lee 2020-04-25 1188 struct mt76_dev *mdev = &dev->mt76;
4c430774e01b06 Lorenzo Bianconi 2020-11-13 1189 struct mt76_phy *mphy_ext = mdev->phy2;
e57b7901469fc0 Ryder Lee 2020-04-25 1190 struct mt76_txwi_cache *txwi;
e57b7901469fc0 Ryder Lee 2020-04-25 1191 struct ieee80211_sta *sta = NULL;
660915d052c606 Felix Fietkau 2020-09-01 1192 LIST_HEAD(free_list);
660915d052c606 Felix Fietkau 2020-09-01 1193 struct sk_buff *tmp;
e57b7901469fc0 Ryder Lee 2020-04-25 1194 u8 i, count;
5342758d5522db Felix Fietkau 2020-11-21 1195 bool wake = false;
e57b7901469fc0 Ryder Lee 2020-04-25 1196
f8a667a9af9198 Felix Fietkau 2020-08-22 1197 /* clean DMA queues and unmap buffers first */
91990519298e23 Lorenzo Bianconi 2020-11-11 1198 mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_PSD], false);
91990519298e23 Lorenzo Bianconi 2020-11-11 1199 mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BE], false);
4c430774e01b06 Lorenzo Bianconi 2020-11-13 1200 if (mphy_ext) {
4c430774e01b06 Lorenzo Bianconi 2020-11-13 1201 mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[MT_TXQ_PSD], false);
4c430774e01b06 Lorenzo Bianconi 2020-11-13 1202 mt76_queue_tx_cleanup(dev, mphy_ext->q_tx[MT_TXQ_BE], false);
4c430774e01b06 Lorenzo Bianconi 2020-11-13 1203 }
f8a667a9af9198 Felix Fietkau 2020-08-22 1204
e57b7901469fc0 Ryder Lee 2020-04-25 1205 /*
e57b7901469fc0 Ryder Lee 2020-04-25 1206 * TODO: MT_TX_FREE_LATENCY is msdu time from the TXD is queued into PLE,
e57b7901469fc0 Ryder Lee 2020-04-25 1207 * to the time ack is received or dropped by hw (air + hw queue time).
e57b7901469fc0 Ryder Lee 2020-04-25 1208 * Should avoid accessing WTBL to get Tx airtime, and use it instead.
e57b7901469fc0 Ryder Lee 2020-04-25 1209 */
e57b7901469fc0 Ryder Lee 2020-04-25 1210 count = FIELD_GET(MT_TX_FREE_MSDU_CNT, le16_to_cpu(free->ctrl));
e57b7901469fc0 Ryder Lee 2020-04-25 1211 for (i = 0; i < count; i++) {
e57b7901469fc0 Ryder Lee 2020-04-25 1212 u32 msdu, info = le32_to_cpu(free->info[i]);
e57b7901469fc0 Ryder Lee 2020-04-25 1213 u8 stat;
e57b7901469fc0 Ryder Lee 2020-04-25 1214
e57b7901469fc0 Ryder Lee 2020-04-25 1215 /*
e57b7901469fc0 Ryder Lee 2020-04-25 1216 * 1'b1: new wcid pair.
e57b7901469fc0 Ryder Lee 2020-04-25 1217 * 1'b0: msdu_id with the same 'wcid pair' as above.
e57b7901469fc0 Ryder Lee 2020-04-25 1218 */
e57b7901469fc0 Ryder Lee 2020-04-25 1219 if (info & MT_TX_FREE_PAIR) {
e57b7901469fc0 Ryder Lee 2020-04-25 1220 struct mt7915_sta *msta;
1daf2522fa1604 Felix Fietkau 2020-07-26 @1221 struct mt7915_phy *phy;
e57b7901469fc0 Ryder Lee 2020-04-25 1222 struct mt76_wcid *wcid;
e57b7901469fc0 Ryder Lee 2020-04-25 1223 u16 idx;
e57b7901469fc0 Ryder Lee 2020-04-25 1224
e57b7901469fc0 Ryder Lee 2020-04-25 1225 count++;
e57b7901469fc0 Ryder Lee 2020-04-25 1226 idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
e57b7901469fc0 Ryder Lee 2020-04-25 1227 wcid = rcu_dereference(dev->mt76.wcid[idx]);
e57b7901469fc0 Ryder Lee 2020-04-25 1228 sta = wcid_to_sta(wcid);
e57b7901469fc0 Ryder Lee 2020-04-25 1229 if (!sta)
e57b7901469fc0 Ryder Lee 2020-04-25 1230 continue;
e57b7901469fc0 Ryder Lee 2020-04-25 1231
e57b7901469fc0 Ryder Lee 2020-04-25 1232 msta = container_of(wcid, struct mt7915_sta, wcid);
1daf2522fa1604 Felix Fietkau 2020-07-26 1233 phy = msta->vif->phy;
1daf2522fa1604 Felix Fietkau 2020-07-26 1234 spin_lock_bh(&dev->sta_poll_lock);
1daf2522fa1604 Felix Fietkau 2020-07-26 1235 if (list_empty(&msta->poll_list))
1daf2522fa1604 Felix Fietkau 2020-07-26 1236 list_add_tail(&msta->poll_list, &dev->sta_poll_list);
1daf2522fa1604 Felix Fietkau 2020-07-26 1237 spin_unlock_bh(&dev->sta_poll_lock);
6425791d350301 Felix Fietkau 2020-09-27 1238 continue;
e57b7901469fc0 Ryder Lee 2020-04-25 1239 }
e57b7901469fc0 Ryder Lee 2020-04-25 1240
e57b7901469fc0 Ryder Lee 2020-04-25 1241 msdu = FIELD_GET(MT_TX_FREE_MSDU_ID, info);
e57b7901469fc0 Ryder Lee 2020-04-25 1242 stat = FIELD_GET(MT_TX_FREE_STATUS, info);
e57b7901469fc0 Ryder Lee 2020-04-25 1243
d089692bc7938a Lorenzo Bianconi 2021-04-20 1244 txwi = mt76_token_release(mdev, msdu, &wake);
e57b7901469fc0 Ryder Lee 2020-04-25 1245 if (!txwi)
e57b7901469fc0 Ryder Lee 2020-04-25 1246 continue;
e57b7901469fc0 Ryder Lee 2020-04-25 1247
223fd4f8430810 Felix Fietkau 2021-05-07 1248 mt7915_txwi_free(dev, txwi, sta, &free_list);
e57b7901469fc0 Ryder Lee 2020-04-25 1249 }
0f1c443ca9cfa0 Felix Fietkau 2020-08-20 1250
0f1c443ca9cfa0 Felix Fietkau 2020-08-20 1251 mt7915_mac_sta_poll(dev);
5342758d5522db Felix Fietkau 2020-11-21 1252
d089692bc7938a Lorenzo Bianconi 2021-04-20 1253 if (wake)
d089692bc7938a Lorenzo Bianconi 2021-04-20 1254 mt76_set_tx_blocked(&dev->mt76, false);
5342758d5522db Felix Fietkau 2020-11-21 1255
781eef5b34c57d Felix Fietkau 2020-07-24 1256 mt76_worker_schedule(&dev->mt76.tx_worker);
660915d052c606 Felix Fietkau 2020-09-01 1257
660915d052c606 Felix Fietkau 2020-09-01 1258 napi_consume_skb(skb, 1);
660915d052c606 Felix Fietkau 2020-09-01 1259
660915d052c606 Felix Fietkau 2020-09-01 1260 list_for_each_entry_safe(skb, tmp, &free_list, list) {
660915d052c606 Felix Fietkau 2020-09-01 1261 skb_list_del_init(skb);
660915d052c606 Felix Fietkau 2020-09-01 1262 napi_consume_skb(skb, 1);
660915d052c606 Felix Fietkau 2020-09-01 1263 }
e57b7901469fc0 Ryder Lee 2020-04-25 1264 }
e57b7901469fc0 Ryder Lee 2020-04-25 1265
3de4cb1756565a Felix Fietkau 2021-05-07 1266 static bool
3de4cb1756565a Felix Fietkau 2021-05-07 1267 mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid,
3de4cb1756565a Felix Fietkau 2021-05-07 1268 __le32 *txs_data)
3de4cb1756565a Felix Fietkau 2021-05-07 1269 {
787e54058191f6 Ryder Lee 2021-07-14 1270 struct ieee80211_supported_band *sband;
787e54058191f6 Ryder Lee 2021-07-14 @1271 struct mt7915_sta *msta;
3de4cb1756565a Felix Fietkau 2021-05-07 1272 struct mt76_dev *mdev = &dev->mt76;
787e54058191f6 Ryder Lee 2021-07-14 1273 struct mt76_phy *mphy;
3de4cb1756565a Felix Fietkau 2021-05-07 1274 struct ieee80211_tx_info *info;
3de4cb1756565a Felix Fietkau 2021-05-07 1275 struct sk_buff_head list;
787e54058191f6 Ryder Lee 2021-07-14 1276 struct rate_info rate = {};
3de4cb1756565a Felix Fietkau 2021-05-07 1277 struct sk_buff *skb;
787e54058191f6 Ryder Lee 2021-07-14 1278 bool cck = false;
787e54058191f6 Ryder Lee 2021-07-14 1279 u32 txrate, txs;
3de4cb1756565a Felix Fietkau 2021-05-07 1280
3de4cb1756565a Felix Fietkau 2021-05-07 1281 mt76_tx_status_lock(mdev, &list);
3de4cb1756565a Felix Fietkau 2021-05-07 1282 skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list);
3de4cb1756565a Felix Fietkau 2021-05-07 1283 if (!skb)
3de4cb1756565a Felix Fietkau 2021-05-07 1284 goto out;
3de4cb1756565a Felix Fietkau 2021-05-07 1285
787e54058191f6 Ryder Lee 2021-07-14 1286 txs = le32_to_cpu(txs_data[0]);
787e54058191f6 Ryder Lee 2021-07-14 1287
3de4cb1756565a Felix Fietkau 2021-05-07 1288 info = IEEE80211_SKB_CB(skb);
787e54058191f6 Ryder Lee 2021-07-14 1289 if (!(txs & MT_TXS0_ACK_ERROR_MASK))
3de4cb1756565a Felix Fietkau 2021-05-07 1290 info->flags |= IEEE80211_TX_STAT_ACK;
3de4cb1756565a Felix Fietkau 2021-05-07 1291
3de4cb1756565a Felix Fietkau 2021-05-07 1292 info->status.ampdu_len = 1;
3de4cb1756565a Felix Fietkau 2021-05-07 1293 info->status.ampdu_ack_len = !!(info->flags &
3de4cb1756565a Felix Fietkau 2021-05-07 1294 IEEE80211_TX_STAT_ACK);
3de4cb1756565a Felix Fietkau 2021-05-07 1295
3de4cb1756565a Felix Fietkau 2021-05-07 1296 info->status.rates[0].idx = -1;
787e54058191f6 Ryder Lee 2021-07-14 1297
787e54058191f6 Ryder Lee 2021-07-14 1298 if (!wcid->sta)
787e54058191f6 Ryder Lee 2021-07-14 1299 goto out;
787e54058191f6 Ryder Lee 2021-07-14 1300
787e54058191f6 Ryder Lee 2021-07-14 1301 msta = container_of(wcid, struct mt7915_sta, wcid);
787e54058191f6 Ryder Lee 2021-07-14 1302 txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
787e54058191f6 Ryder Lee 2021-07-14 1303
787e54058191f6 Ryder Lee 2021-07-14 1304 rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
787e54058191f6 Ryder Lee 2021-07-14 1305 rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;
787e54058191f6 Ryder Lee 2021-07-14 1306
787e54058191f6 Ryder Lee 2021-07-14 1307 switch (FIELD_GET(MT_TX_RATE_MODE, txrate)) {
787e54058191f6 Ryder Lee 2021-07-14 1308 case MT_PHY_TYPE_CCK:
787e54058191f6 Ryder Lee 2021-07-14 1309 cck = true;
787e54058191f6 Ryder Lee 2021-07-14 1310 fallthrough;
787e54058191f6 Ryder Lee 2021-07-14 1311 case MT_PHY_TYPE_OFDM:
787e54058191f6 Ryder Lee 2021-07-14 1312 mphy = &dev->mphy;
787e54058191f6 Ryder Lee 2021-07-14 1313 if (wcid->ext_phy && dev->mt76.phy2)
787e54058191f6 Ryder Lee 2021-07-14 1314 mphy = dev->mt76.phy2;
787e54058191f6 Ryder Lee 2021-07-14 1315
787e54058191f6 Ryder Lee 2021-07-14 1316 if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
787e54058191f6 Ryder Lee 2021-07-14 1317 sband = &mphy->sband_5g.sband;
787e54058191f6 Ryder Lee 2021-07-14 1318 else
787e54058191f6 Ryder Lee 2021-07-14 1319 sband = &mphy->sband_2g.sband;
787e54058191f6 Ryder Lee 2021-07-14 1320
787e54058191f6 Ryder Lee 2021-07-14 1321 rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs, cck);
787e54058191f6 Ryder Lee 2021-07-14 1322 rate.legacy = sband->bitrates[rate.mcs].bitrate;
787e54058191f6 Ryder Lee 2021-07-14 1323 break;
787e54058191f6 Ryder Lee 2021-07-14 1324 case MT_PHY_TYPE_HT:
787e54058191f6 Ryder Lee 2021-07-14 1325 case MT_PHY_TYPE_HT_GF:
787e54058191f6 Ryder Lee 2021-07-14 1326 rate.mcs += (rate.nss - 1) * 8;
787e54058191f6 Ryder Lee 2021-07-14 1327 if (rate.mcs > 31)
787e54058191f6 Ryder Lee 2021-07-14 1328 goto out;
787e54058191f6 Ryder Lee 2021-07-14 1329
787e54058191f6 Ryder Lee 2021-07-14 1330 rate.flags = RATE_INFO_FLAGS_MCS;
787e54058191f6 Ryder Lee 2021-07-14 1331 if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
787e54058191f6 Ryder Lee 2021-07-14 1332 rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
787e54058191f6 Ryder Lee 2021-07-14 1333 break;
787e54058191f6 Ryder Lee 2021-07-14 1334 case MT_PHY_TYPE_VHT:
787e54058191f6 Ryder Lee 2021-07-14 1335 if (rate.mcs > 9)
787e54058191f6 Ryder Lee 2021-07-14 1336 goto out;
787e54058191f6 Ryder Lee 2021-07-14 1337
787e54058191f6 Ryder Lee 2021-07-14 1338 rate.flags = RATE_INFO_FLAGS_VHT_MCS;
787e54058191f6 Ryder Lee 2021-07-14 1339 break;
787e54058191f6 Ryder Lee 2021-07-14 1340 case MT_PHY_TYPE_HE_SU:
787e54058191f6 Ryder Lee 2021-07-14 1341 case MT_PHY_TYPE_HE_EXT_SU:
787e54058191f6 Ryder Lee 2021-07-14 1342 case MT_PHY_TYPE_HE_TB:
787e54058191f6 Ryder Lee 2021-07-14 1343 case MT_PHY_TYPE_HE_MU:
787e54058191f6 Ryder Lee 2021-07-14 1344 if (rate.mcs > 11)
787e54058191f6 Ryder Lee 2021-07-14 1345 goto out;
787e54058191f6 Ryder Lee 2021-07-14 1346
787e54058191f6 Ryder Lee 2021-07-14 1347 rate.he_gi = wcid->rate.he_gi;
787e54058191f6 Ryder Lee 2021-07-14 1348 rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
787e54058191f6 Ryder Lee 2021-07-14 1349 rate.flags = RATE_INFO_FLAGS_HE_MCS;
787e54058191f6 Ryder Lee 2021-07-14 1350 break;
787e54058191f6 Ryder Lee 2021-07-14 1351 default:
787e54058191f6 Ryder Lee 2021-07-14 1352 goto out;
787e54058191f6 Ryder Lee 2021-07-14 1353 }
787e54058191f6 Ryder Lee 2021-07-14 1354
787e54058191f6 Ryder Lee 2021-07-14 1355 switch (FIELD_GET(MT_TXS0_BW, txs)) {
787e54058191f6 Ryder Lee 2021-07-14 1356 case IEEE80211_STA_RX_BW_160:
787e54058191f6 Ryder Lee 2021-07-14 1357 rate.bw = RATE_INFO_BW_160;
787e54058191f6 Ryder Lee 2021-07-14 1358 break;
787e54058191f6 Ryder Lee 2021-07-14 1359 case IEEE80211_STA_RX_BW_80:
787e54058191f6 Ryder Lee 2021-07-14 1360 rate.bw = RATE_INFO_BW_80;
787e54058191f6 Ryder Lee 2021-07-14 1361 break;
787e54058191f6 Ryder Lee 2021-07-14 1362 case IEEE80211_STA_RX_BW_40:
787e54058191f6 Ryder Lee 2021-07-14 1363 rate.bw = RATE_INFO_BW_40;
787e54058191f6 Ryder Lee 2021-07-14 1364 break;
787e54058191f6 Ryder Lee 2021-07-14 1365 default:
787e54058191f6 Ryder Lee 2021-07-14 1366 rate.bw = RATE_INFO_BW_20;
787e54058191f6 Ryder Lee 2021-07-14 1367 break;
787e54058191f6 Ryder Lee 2021-07-14 1368 }
787e54058191f6 Ryder Lee 2021-07-14 1369 wcid->rate = rate;
3de4cb1756565a Felix Fietkau 2021-05-07 1370
3de4cb1756565a Felix Fietkau 2021-05-07 1371 out:
787e54058191f6 Ryder Lee 2021-07-14 1372 mt76_tx_status_skb_done(mdev, skb, &list);
3de4cb1756565a Felix Fietkau 2021-05-07 1373 mt76_tx_status_unlock(mdev, &list);
3de4cb1756565a Felix Fietkau 2021-05-07 1374
3de4cb1756565a Felix Fietkau 2021-05-07 1375 return !!skb;
3de4cb1756565a Felix Fietkau 2021-05-07 1376 }
3de4cb1756565a Felix Fietkau 2021-05-07 1377

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (17.14 kB)
.config.gz (66.41 kB)
Download all attachments