Commit f43b941f authored by Ryder Lee's avatar Ryder Lee Committed by Felix Fietkau

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: e57b7901 ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Fixes: e4c5ead6 ("mt76: mt7915: rename mt7915_mcu_get_rate_info to mt7915_mcu_get_tx_rate")
Reported-by: default avatarEvelyn Tsai <evelyn.tsai@mediatek.com>
Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 7883906d
...@@ -364,54 +364,62 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb) ...@@ -364,54 +364,62 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb)
dev->hw_pattern++; dev->hw_pattern++;
} }
static void static int
mt7915_mcu_tx_rate_parse(struct mt76_phy *mphy, struct mt7915_mcu_ra_info *ra, mt7915_mcu_tx_rate_parse(struct mt76_phy *mphy, struct mt7915_mcu_ra_info *ra,
struct rate_info *rate, u16 r) struct rate_info *rate, u16 r)
{ {
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
u16 ru_idx = le16_to_cpu(ra->ru_idx); 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->mcs = FIELD_GET(MT_RA_RATE_MCS, r);
rate->nss = FIELD_GET(MT_RA_RATE_NSS, r) + 1; rate->nss = FIELD_GET(MT_RA_RATE_NSS, r) + 1;
switch (FIELD_GET(MT_RA_RATE_TX_MODE, r)) { switch (FIELD_GET(MT_RA_RATE_TX_MODE, r)) {
case MT_PHY_TYPE_CCK: case MT_PHY_TYPE_CCK:
cck = true;
fallthrough;
case MT_PHY_TYPE_OFDM: case MT_PHY_TYPE_OFDM:
if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
sband = &mphy->sband_5g.sband; sband = &mphy->sband_5g.sband;
else else
sband = &mphy->sband_2g.sband; sband = &mphy->sband_2g.sband;
rate->mcs = mt76_get_rate(mphy->dev, sband, rate->mcs, cck);
rate->legacy = sband->bitrates[rate->mcs].bitrate; rate->legacy = sband->bitrates[rate->mcs].bitrate;
break; break;
case MT_PHY_TYPE_HT: case MT_PHY_TYPE_HT:
case MT_PHY_TYPE_HT_GF: case MT_PHY_TYPE_HT_GF:
rate->mcs += (rate->nss - 1) * 8; 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) if (ra->gi)
flags |= RATE_INFO_FLAGS_SHORT_GI; rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
break; break;
case MT_PHY_TYPE_VHT: 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) if (ra->gi)
flags |= RATE_INFO_FLAGS_SHORT_GI; rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
break; break;
case MT_PHY_TYPE_HE_SU: case MT_PHY_TYPE_HE_SU:
case MT_PHY_TYPE_HE_EXT_SU: case MT_PHY_TYPE_HE_EXT_SU:
case MT_PHY_TYPE_HE_TB: case MT_PHY_TYPE_HE_TB:
case MT_PHY_TYPE_HE_MU: 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_gi = ra->gi;
rate->he_dcm = FIELD_GET(MT_RA_RATE_DCM_EN, r); rate->he_dcm = FIELD_GET(MT_RA_RATE_DCM_EN, r);
rate->flags = RATE_INFO_FLAGS_HE_MCS;
flags |= RATE_INFO_FLAGS_HE_MCS;
break; break;
default: default:
break; return -EINVAL;
} }
rate->flags = flags;
if (ru_idx) { if (ru_idx) {
switch (ru_idx) { switch (ru_idx) {
...@@ -448,6 +456,8 @@ mt7915_mcu_tx_rate_parse(struct mt76_phy *mphy, struct mt7915_mcu_ra_info *ra, ...@@ -448,6 +456,8 @@ mt7915_mcu_tx_rate_parse(struct mt76_phy *mphy, struct mt7915_mcu_ra_info *ra,
break; break;
} }
} }
return 0;
} }
static void static void
...@@ -478,11 +488,11 @@ mt7915_mcu_tx_rate_report(struct mt7915_dev *dev, struct sk_buff *skb) ...@@ -478,11 +488,11 @@ mt7915_mcu_tx_rate_report(struct mt7915_dev *dev, struct sk_buff *skb)
mphy = dev->mt76.phy2; mphy = dev->mt76.phy2;
/* current rate */ /* current rate */
mt7915_mcu_tx_rate_parse(mphy, ra, &rate, curr); if (!mt7915_mcu_tx_rate_parse(mphy, ra, &rate, curr))
stats->tx_rate = rate; stats->tx_rate = rate;
/* probing rate */ /* probing rate */
mt7915_mcu_tx_rate_parse(mphy, ra, &prob_rate, probe); if (!mt7915_mcu_tx_rate_parse(mphy, ra, &prob_rate, probe))
stats->prob_rate = prob_rate; stats->prob_rate = prob_rate;
if (attempts) { if (attempts) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment