summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
diff options
context:
space:
mode:
authorRyder Lee <ryder.lee@mediatek.com>2021-03-03 13:38:00 +0300
committerFelix Fietkau <nbd@nbd.name>2021-04-12 01:01:24 +0300
commitf43b941fd61003659a3f0e039595e5e525917aa8 (patch)
tree7d76ba7283d7e766e4a764b28fa58d55df27f3aa /drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
parent7883906d22c1e73f1f316bd84fc4a7ff8edd12aa (diff)
downloadlinux-f43b941fd61003659a3f0e039595e5e525917aa8.tar.xz
mt76: mt7915: fix txrate reporting
Properly check rate_info to fix unexpected reporting. [ 1215.161863] Call trace: [ 1215.164307] cfg80211_calculate_bitrate+0x124/0x200 [cfg80211] [ 1215.170139] ieee80211s_update_metric+0x80/0xc0 [mac80211] [ 1215.175624] ieee80211_tx_status_ext+0x508/0x838 [mac80211] [ 1215.181190] mt7915_mcu_get_rx_rate+0x28c/0x8d0 [mt7915e] [ 1215.186580] mt7915_mac_tx_free+0x324/0x7c0 [mt7915e] [ 1215.191623] mt7915_queue_rx_skb+0xa8/0xd0 [mt7915e] [ 1215.196582] mt76_dma_cleanup+0x7b0/0x11d0 [mt76] [ 1215.201276] __napi_poll+0x38/0xf8 [ 1215.204668] napi_workfn+0x40/0x80 [ 1215.208062] process_one_work+0x1fc/0x390 [ 1215.212062] worker_thread+0x48/0x4d0 [ 1215.215715] kthread+0x120/0x128 [ 1215.218935] ret_from_fork+0x10/0x1c Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets") Fixes: e4c5ead632ff ("mt76: mt7915: rename mt7915_mcu_get_rate_info to mt7915_mcu_get_tx_rate") Reported-by: Evelyn Tsai <evelyn.tsai@mediatek.com> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7915/mcu.c')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index b204c5dd7914..29b5039cc286 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -364,54 +364,62 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
dev->hw_pattern++;
}
-static void
+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);
- u16 flags = 0;
+ 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;
- flags |= RATE_INFO_FLAGS_MCS;
+ if (rate->mcs > 31)
+ return -EINVAL;
+ rate->flags = RATE_INFO_FLAGS_MCS;
if (ra->gi)
- flags |= RATE_INFO_FLAGS_SHORT_GI;
+ rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
break;
case MT_PHY_TYPE_VHT:
- flags |= RATE_INFO_FLAGS_VHT_MCS;
+ if (rate->mcs > 9)
+ return -EINVAL;
+ rate->flags = RATE_INFO_FLAGS_VHT_MCS;
if (ra->gi)
- flags |= RATE_INFO_FLAGS_SHORT_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);
-
- flags |= RATE_INFO_FLAGS_HE_MCS;
+ rate->flags = RATE_INFO_FLAGS_HE_MCS;
break;
default:
- break;
+ return -EINVAL;
}
- rate->flags = flags;
if (ru_idx) {
switch (ru_idx) {
@@ -448,6 +456,8 @@ mt7915_mcu_tx_rate_parse(struct mt76_phy *mphy, struct mt7915_mcu_ra_info *ra,
break;
}
}
+
+ return 0;
}
static void
@@ -478,12 +488,12 @@ mt7915_mcu_tx_rate_report(struct mt7915_dev *dev, struct sk_buff *skb)
mphy = dev->mt76.phy2;
/* current rate */
- mt7915_mcu_tx_rate_parse(mphy, ra, &rate, curr);
- stats->tx_rate = rate;
+ if (!mt7915_mcu_tx_rate_parse(mphy, ra, &rate, curr))
+ stats->tx_rate = rate;
/* probing rate */
- mt7915_mcu_tx_rate_parse(mphy, ra, &prob_rate, probe);
- stats->prob_rate = prob_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);