diff options
-rw-r--r-- | include/net/mac80211.h | 11 | ||||
-rw-r--r-- | net/mac80211/tx.c | 20 |
2 files changed, 31 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ce7cb1b5d453..d98fac54577b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -2110,6 +2110,17 @@ rate_lowest_index(struct ieee80211_supported_band *sband, | |||
2110 | return 0; | 2110 | return 0; |
2111 | } | 2111 | } |
2112 | 2112 | ||
2113 | static inline | ||
2114 | bool rate_usable_index_exists(struct ieee80211_supported_band *sband, | ||
2115 | struct ieee80211_sta *sta) | ||
2116 | { | ||
2117 | unsigned int i; | ||
2118 | |||
2119 | for (i = 0; i < sband->n_bitrates; i++) | ||
2120 | if (rate_supported(sta, sband->band, i)) | ||
2121 | return true; | ||
2122 | return false; | ||
2123 | } | ||
2113 | 2124 | ||
2114 | int ieee80211_rate_control_register(struct rate_control_ops *ops); | 2125 | int ieee80211_rate_control_register(struct rate_control_ops *ops); |
2115 | void ieee80211_rate_control_unregister(struct rate_control_ops *ops); | 2126 | void ieee80211_rate_control_unregister(struct rate_control_ops *ops); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 60ae086995b1..f3efd4f16e91 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) | |||
512 | int i, len; | 512 | int i, len; |
513 | bool inval = false, rts = false, short_preamble = false; | 513 | bool inval = false, rts = false, short_preamble = false; |
514 | struct ieee80211_tx_rate_control txrc; | 514 | struct ieee80211_tx_rate_control txrc; |
515 | u32 sta_flags; | ||
515 | 516 | ||
516 | memset(&txrc, 0, sizeof(txrc)); | 517 | memset(&txrc, 0, sizeof(txrc)); |
517 | 518 | ||
@@ -544,7 +545,26 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
544 | (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) | 545 | (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) |
545 | txrc.short_preamble = short_preamble = true; | 546 | txrc.short_preamble = short_preamble = true; |
546 | 547 | ||
548 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; | ||
549 | |||
550 | /* | ||
551 | * Lets not bother rate control if we're associated and cannot | ||
552 | * talk to the sta. This should not happen. | ||
553 | */ | ||
554 | if (WARN((tx->local->sw_scanning) && | ||
555 | (sta_flags & WLAN_STA_ASSOC) && | ||
556 | !rate_usable_index_exists(sband, &tx->sta->sta), | ||
557 | "%s: Dropped data frame as no usable bitrate found while " | ||
558 | "scanning and associated. Target station: " | ||
559 | "%pM on %d GHz band\n", | ||
560 | tx->dev->name, hdr->addr1, | ||
561 | tx->channel->band ? 5 : 2)) | ||
562 | return TX_DROP; | ||
547 | 563 | ||
564 | /* | ||
565 | * If we're associated with the sta at this point we know we can at | ||
566 | * least send the frame at the lowest bit rate. | ||
567 | */ | ||
548 | rate_control_get_rate(tx->sdata, tx->sta, &txrc); | 568 | rate_control_get_rate(tx->sdata, tx->sta, &txrc); |
549 | 569 | ||
550 | if (unlikely(info->control.rates[0].idx < 0)) | 570 | if (unlikely(info->control.rates[0].idx < 0)) |