Rewrite handling of the fixed rates

Make srate signed, or checks for it being less than 0 don't work.
Consistently use IEEE80211_FIXED_RATE_NONE.  Fix misleading comments.

Survive the case when the fixed rate is not in the rate table.  It can
happen e.g. a CCK rate is used with an 802.11a channel, or in the STA
mode when an OFDM rate is used with 802.11b.  The driver should catch
it, but it doesn't.  In any case, it's not a reason for an oops.

Remove the debugging message if everything is fine.  In case of an
error, specify the VAP name.


git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@4095 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
proski 2009-09-03 21:08:13 +00:00
parent 0c1df90920
commit 922778b6ef
4 changed files with 104 additions and 106 deletions

View File

@ -80,6 +80,12 @@
#define DPRINTF(sc, _fmt, ...)
#endif
#include "release.h"
#if 0
static char *version = "0.1 (" RELEASE_VERSION ")";
#endif
static char *dev_info = "ath_rate_amrr";
static int ath_rateinterval = 1000; /* rate ctl interval (ms) */
static int ath_rate_max_success_threshold = 10;
static int ath_rate_min_success_threshold = 1;
@ -270,35 +276,41 @@ ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni)
int srate;
KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
if (vap->iv_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
* and 11a, we start "in the middle" at 24Mb or 36Mb.
* A fixed rate is to be used. Find the corresponding
* index in the rate table.
*/
srate = ni->ni_rates.rs_nrates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
/*
* Scan the negotiated rate set to find the
* closest rate.
*/
/* NB: the rate set is assumed sorted */
for (; srate >= 0 && RATE(srate) > 72; srate--);
KASSERT(srate >= 0, ("bogus rate set"));
}
} else {
/*
* A fixed rate is to be used; ic_fixed_rate is an
* index into the supported rate set. Convert this
* to the index into the negotiated rate set for
* the node. We know the rate is there because the
* rate set is checked when the station associates.
*/
srate = ni->ni_rates.rs_nrates - 1;
for (; srate >= 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
KASSERT(srate >= 0,
("fixed rate %d not in rate set", vap->iv_fixed_rate));
for (srate = 0; srate < ni->ni_rates.rs_nrates; srate++)
if (vap->iv_fixed_rate ==
(ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL)) {
ath_rate_update(sc, ni, srate);
return;
}
printk(KERN_WARNING "%s: %s: fixed rate %u%sMbps is not "
"available and will be ignored\n", vap->iv_dev->name,
dev_info, vap->iv_fixed_rate / 2,
(vap->iv_fixed_rate & 1) ? ".5" : "");
}
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
* and 11a, we start "in the middle" at 24Mb or 36Mb.
*/
srate = ni->ni_rates.rs_nrates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
/*
* Scan the negotiated rate set to find the
* closest rate.
*/
/* NB: the rate set is assumed sorted */
for (; srate >= 0 && RATE(srate) > 72; srate--);
KASSERT(srate >= 0, ("bogus rate set"));
}
ath_rate_update(sc, ni, srate);
#undef RATE
}
@ -554,12 +566,6 @@ static struct ieee80211_rate_ops ath_rate_ops = {
.detach = ath_rate_detach,
};
#include "release.h"
#if 0
static char *version = "0.1 (" RELEASE_VERSION ")";
static char *dev_info = "ath_rate_amrr";
#endif
MODULE_AUTHOR("INRIA, Mathieu Lacage");
MODULE_DESCRIPTION("AMRR Rate control algorithm");
#ifdef MODULE_VERSION

View File

@ -634,7 +634,6 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
const HAL_RATE_TABLE *rt = sc->sc_currates;
unsigned int x;
int retry_index, tx_time;
int srate;
int ndx = 0;
sn->num_rates = 0;
@ -689,30 +688,24 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
}
if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
srate = sn->num_rates - 1;
int srate;
/* A fixed rate is to be used; ic_fixed_rate is an
* index into the supported rate set. Convert this
* to the index into the negotiated rate set for
* the node. We know the rate is there because the
* rate set is checked when the station associates. */
/* NB: the rate set is assumed to be sorted. */
for (;
(srate >= 0) &&
(ni->ni_rates.rs_rates[srate] &
IEEE80211_RATE_VAL) != vap->iv_fixed_rate;
srate--);
/*
* A fixed rate is to be used. Find the corresponding
* index in the rate table.
*/
for (srate = 0; srate < sn->num_rates; srate++)
if (vap->iv_fixed_rate ==
(ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL)) {
sn->static_rate_ndx = srate;
ni->ni_txrate = srate;
return;
}
KASSERT(srate >= 0,
("fixed rate %d not in rate set", vap->iv_fixed_rate));
sn->static_rate_ndx = srate;
ni->ni_txrate = srate;
DPRINTF(sc, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n",
dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
sn->rates[srate].rate / 2,
(sn->rates[srate].rate % 2) ? ".5 " : " ");
return;
printk(KERN_WARNING "%s: %s: fixed rate %u%sMbps is not "
"available and will be ignored\n", vap->iv_dev->name,
dev_info, vap->iv_fixed_rate / 2,
(vap->iv_fixed_rate & 1) ? ".5" : "");
}
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {

View File

@ -79,6 +79,12 @@ enum {
#define DPRINTF(sc, _fmt, ...)
#endif
#include "release.h"
#if 0
static char *version = "1.0 (" RELEASE_VERSION ")";
#endif
static char *dev_info = "ath_rate_onoe";
/*
* Default parameters for the rate control algorithm. These are
* all tunable with sysctls. The rate controller runs periodically
@ -255,36 +261,41 @@ ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni)
int srate;
KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
if (vap->iv_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
* and 11a, we start "in the middle" at 24Mb or 36Mb.
* A fixed rate is to be used. Find the corresponding
* index in the rate table.
*/
srate = ni->ni_rates.rs_nrates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
/*
* Scan the negotiated rate set to find the
* closest rate.
*/
/* NB: the rate set is assumed sorted */
for (; srate >= 0 && RATE(srate) > 72; srate--);
KASSERT(srate >= 0, ("bogus rate set"));
}
} else {
for (srate = 0; srate < ni->ni_rates.rs_nrates; srate++)
if (vap->iv_fixed_rate ==
(ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL)) {
ath_rate_update(sc, ni, srate);
return;
}
printk(KERN_WARNING "%s: %s: fixed rate %u%sMbps is not "
"available and will be ignored\n", vap->iv_dev->name,
dev_info, vap->iv_fixed_rate / 2,
(vap->iv_fixed_rate & 1) ? ".5" : "");
}
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
* and 11a, we start "in the middle" at 24Mb or 36Mb.
*/
srate = ni->ni_rates.rs_nrates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
/*
* A fixed rate is to be used; iv_fixed_rate is the
* 802.11 rate code. Convert this to the index into
* the negotiated rate set for the node. We know the
* rate is there because the rate set is checked when
* the station associates.
* Scan the negotiated rate set to find the
* closest rate.
*/
/* NB: the rate set is assumed sorted */
srate = ni->ni_rates.rs_nrates - 1;
for (; srate >= 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
KASSERT(srate >= 0,
("fixed rate %d not in rate set", vap->iv_fixed_rate));
for (; srate >= 0 && RATE(srate) > 72; srate--);
KASSERT(srate >= 0, ("bogus rate set"));
}
ath_rate_update(sc, ni, srate);
#undef RATE
}
@ -501,12 +512,6 @@ static struct ieee80211_rate_ops ath_rate_ops = {
.detach = ath_rate_detach,
};
#include "release.h"
#if 0
static char *version = "1.0 (" RELEASE_VERSION ")";
static char *dev_info = "ath_rate_onoe";
#endif
MODULE_AUTHOR("Errno Consulting, Sam Leffler");
MODULE_DESCRIPTION("Atsushi Onoe's rate control algorithm for Atheros devices");
#ifdef MODULE_VERSION

View File

@ -816,7 +816,6 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
struct ieee80211vap *vap = ni->ni_vap;
const HAL_RATE_TABLE *rt = sc->sc_currates;
unsigned int x, y;
unsigned int srate;
sn->num_rates = 0;
@ -853,31 +852,26 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
}
if (vap->iv_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
int srate;
/*
* A fixed rate is to be used; ic_fixed_rate is an
* index into the supported rate set. Convert this
* to the index into the negotiated rate set for
* the node. We know the rate is there because the
* rate set is checked when the station associates.
* A fixed rate is to be used. Find the corresponding
* index in the rate table.
*/
/* NB: the rate set is assumed sorted */
for (x = 0, srate = 0; x < sn->num_rates; x++)
if ((ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL) == vap->iv_fixed_rate)
srate = x;
for (srate = 0; srate < sn->num_rates; srate++)
if (vap->iv_fixed_rate ==
(ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL)) {
sn->static_rate_ndx = srate;
ni->ni_txrate = srate;
return;
}
KASSERT(((ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) == vap->iv_fixed_rate),
("fixed rate %u not in rate set", vap->iv_fixed_rate));
sn->static_rate_ndx = srate;
ni->ni_txrate = srate;
DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " fixed rate %u%sMbps\n",
dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
sn->rates[srate].rate / 2,
(sn->rates[srate].rate % 0x1) ? ".5" : " ");
return;
printk(KERN_WARNING "%s: %s: fixed rate %u%sMbps is not "
"available and will be ignored\n", vap->iv_dev->name,
dev_info, vap->iv_fixed_rate / 2,
(vap->iv_fixed_rate & 1) ? ".5" : "");
}
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
unsigned int size = bin_to_size(y);
int ndx = 0;