diff --git a/ath/if_ath.c b/ath/if_ath.c index 039f40c..3bd7ab8 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -7520,6 +7520,17 @@ ath_tx_start(struct net_device *dev, struct ieee80211_node *ni, } else antenna = sc->sc_txantenna; + /* should be ok, but just to be sure */ + if (txrate == 0) + return -EIO; + + DPRINTF(sc, ATH_DEBUG_XMIT, "%s: set up txdesc: pktlen %d hdrlen %d " + "atype %d txpower %d txrate %d try0 %d keyix %d ant %d flags %x " + "ctsrate %d ctsdur %d icvlen %d ivlen %d comp %d\n", + __func__, pktlen, hdrlen, atype, MIN(ni->ni_txpower, 60), txrate, + try0, keyix, antenna, flags, ctsrate, ctsduration, icvlen, ivlen, + comp); + /* * Formulate first tx descriptor with tx controls. */ @@ -7551,6 +7562,20 @@ ath_tx_start(struct net_device *dev, struct ieee80211_node *ni, if (try0 != ATH_TXMAXTRY) { sc->sc_rc->ops->get_mrr(sc, an, shortPreamble, skb->len, rix, &mrr); + /* + * if rate module fucks up and gives us 0 rates we disable the + * multi rate retries. this is important since 0 rates can lead + * to a card continously sending noise (in A band at least) + */ + if (!mrr.rate1) mrr.retries1 = 0; + if (!mrr.rate2) mrr.retries2 = 0; + if (!mrr.rate3) mrr.retries3 = 0; + + DPRINTF(sc, ATH_DEBUG_XMIT, "%s: set up multi rate/retry " + "1:%d/%d 2:%d/%d 3:%d/%d\n", __func__, + mrr.rate1, mrr.retries1, mrr.rate2, mrr.retries2, + mrr.rate3, mrr.retries3); + ath_hal_setupxtxdesc(sc->sc_ah, ds, mrr.rate1, mrr.retries1, mrr.rate2, mrr.retries2, mrr.rate3, mrr.retries3); diff --git a/net80211/ieee80211_input.c b/net80211/ieee80211_input.c index 5b6074f..ecf7650 100644 --- a/net80211/ieee80211_input.c +++ b/net80211/ieee80211_input.c @@ -2765,6 +2765,7 @@ ieee80211_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, if (frm > efrm) return; IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE); + IEEE80211_VERIFY_ELEMENT(scan.xrates, IEEE80211_RATE_MAXSIZE); IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN); #if IEEE80211_CHAN_MAX < 255 if (scan.chan > IEEE80211_CHAN_MAX) { diff --git a/net80211/ieee80211_proto.c b/net80211/ieee80211_proto.c index 292906a..106166e 100644 --- a/net80211/ieee80211_proto.c +++ b/net80211/ieee80211_proto.c @@ -425,6 +425,20 @@ ieee80211_fix_rate(struct ieee80211_node *ni, int flags) } r = nrs->rs_rates[i] & IEEE80211_RATE_VAL; badrate = r; + + /* + * remove 0 rates + * they don't make sense and can lead to trouble later + */ + if (r == 0) { + nrs->rs_nrates--; + nrs->rs_nrates--; + for (j = i; j < nrs->rs_nrates; j++) + nrs->rs_rates[j] = nrs->rs_rates[j + 1]; + nrs->rs_rates[j] = 0; + continue; + } + /* * Check for fixed rate. */