summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-07-16 10:15:09 -0700
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:14 -0400
commitb770b43e95a66587fbd8c1841de83da87fbf23ea (patch)
tree8b91a3936e0964192e4f59a98e157606cbe932ac
parentfe643414dbf330d6d910e01edd48dd93dc6f2942 (diff)
downloadlinux-3.10-b770b43e95a66587fbd8c1841de83da87fbf23ea.tar.gz
linux-3.10-b770b43e95a66587fbd8c1841de83da87fbf23ea.tar.bz2
linux-3.10-b770b43e95a66587fbd8c1841de83da87fbf23ea.zip
mac80211: drop frames for sta with no valid rate
When we're associated we should be able to send data to target sta. If we cannot we may be trying to use the incorrect band to talk to the sta. Lets catch any such cases, warn, and drop the frames to not invalidate assumptions being made on rate control algorithms when they have a valid sta to communicate with. Any such cases should be handled and fixed. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/net/mac80211.h11
-rw-r--r--net/mac80211/tx.c20
2 files changed, 31 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ce7cb1b5d45..d98fac54577 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2110,6 +2110,17 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
return 0;
}
+static inline
+bool rate_usable_index_exists(struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta)
+{
+ unsigned int i;
+
+ for (i = 0; i < sband->n_bitrates; i++)
+ if (rate_supported(sta, sband->band, i))
+ return true;
+ return false;
+}
int ieee80211_rate_control_register(struct rate_control_ops *ops);
void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 60ae086995b..f3efd4f16e9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -512,6 +512,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
int i, len;
bool inval = false, rts = false, short_preamble = false;
struct ieee80211_tx_rate_control txrc;
+ u32 sta_flags;
memset(&txrc, 0, sizeof(txrc));
@@ -544,7 +545,26 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
(tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
txrc.short_preamble = short_preamble = true;
+ sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
+
+ /*
+ * Lets not bother rate control if we're associated and cannot
+ * talk to the sta. This should not happen.
+ */
+ if (WARN((tx->local->sw_scanning) &&
+ (sta_flags & WLAN_STA_ASSOC) &&
+ !rate_usable_index_exists(sband, &tx->sta->sta),
+ "%s: Dropped data frame as no usable bitrate found while "
+ "scanning and associated. Target station: "
+ "%pM on %d GHz band\n",
+ tx->dev->name, hdr->addr1,
+ tx->channel->band ? 5 : 2))
+ return TX_DROP;
+ /*
+ * If we're associated with the sta at this point we know we can at
+ * least send the frame at the lowest bit rate.
+ */
rate_control_get_rate(tx->sdata, tx->sta, &txrc);
if (unlikely(info->control.rates[0].idx < 0))