Commit 6b583201 authored by Petr Štetiar's avatar Petr Štetiar Committed by Kalle Valo

mwl8k: Fix rate_idx underflow

It was reported on OpenWrt bug tracking system[1], that several users
are affected by the endless reboot of their routers if they configure
5GHz interface with channel 44 or 48.

The reboot loop is caused by the following excessive number of WARN_ON
messages:

 WARNING: CPU: 0 PID: 0 at backports-4.19.23-1/net/mac80211/rx.c:4516
                             ieee80211_rx_napi+0x1fc/0xa54 [mac80211]

as the messages are being correctly emitted by the following guard:

 case RX_ENC_LEGACY:
      if (WARN_ON(status->rate_idx >= sband->n_bitrates))

as the rate_idx is in this case erroneously set to 251 (0xfb). This fix
simply converts previously used magic number to proper constant and
guards against substraction which is leading to the currently observed
underflow.

1. https://bugs.openwrt.org/index.php?do=details&task_id=2218

Fixes: 85478344 ("mwl8k: properly set receive status rate index on 5 GHz receive")
Cc: <stable@vger.kernel.org>
Tested-by: default avatarEubert Bao <bunnier@gmail.com>
Reported-by: default avatarEubert Bao <bunnier@gmail.com>
Signed-off-by: default avatarPetr Štetiar <ynezz@true.cz>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 09ac2694
...@@ -441,6 +441,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { ...@@ -441,6 +441,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
#define MWL8K_CMD_UPDATE_STADB 0x1123 #define MWL8K_CMD_UPDATE_STADB 0x1123
#define MWL8K_CMD_BASTREAM 0x1125 #define MWL8K_CMD_BASTREAM 0x1125
#define MWL8K_LEGACY_5G_RATE_OFFSET \
(ARRAY_SIZE(mwl8k_rates_24) - ARRAY_SIZE(mwl8k_rates_50))
static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
{ {
u16 command = le16_to_cpu(cmd); u16 command = le16_to_cpu(cmd);
...@@ -1016,8 +1019,9 @@ mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status, ...@@ -1016,8 +1019,9 @@ mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status,
if (rxd->channel > 14) { if (rxd->channel > 14) {
status->band = NL80211_BAND_5GHZ; status->band = NL80211_BAND_5GHZ;
if (!(status->encoding == RX_ENC_HT)) if (!(status->encoding == RX_ENC_HT) &&
status->rate_idx -= 5; status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET)
status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET;
} else { } else {
status->band = NL80211_BAND_2GHZ; status->band = NL80211_BAND_2GHZ;
} }
...@@ -1124,8 +1128,9 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, ...@@ -1124,8 +1128,9 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
if (rxd->channel > 14) { if (rxd->channel > 14) {
status->band = NL80211_BAND_5GHZ; status->band = NL80211_BAND_5GHZ;
if (!(status->encoding == RX_ENC_HT)) if (!(status->encoding == RX_ENC_HT) &&
status->rate_idx -= 5; status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET)
status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET;
} else { } else {
status->band = NL80211_BAND_2GHZ; status->band = NL80211_BAND_2GHZ;
} }
......
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