Changeset View
Changeset View
Standalone View
Standalone View
sys/net80211/ieee80211_rssadapt.c
Show First 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | rssadapt_updatestats(struct ieee80211_rssadapt_node *ra) | ||||
*/ | */ | ||||
interval = MAX(10*1000, 10*1000 / MAX(1, 10 * ra->ra_pktrate)); | interval = MAX(10*1000, 10*1000 / MAX(1, 10 * ra->ra_pktrate)); | ||||
ra->ra_raise_interval = msecs_to_ticks(interval); | ra->ra_raise_interval = msecs_to_ticks(interval); | ||||
} | } | ||||
static void | static void | ||||
rssadapt_node_init(struct ieee80211_node *ni) | rssadapt_node_init(struct ieee80211_node *ni) | ||||
{ | { | ||||
const struct ieee80211_rate_t *rate; | |||||
struct ieee80211_rssadapt_node *ra; | struct ieee80211_rssadapt_node *ra; | ||||
struct ieee80211vap *vap = ni->ni_vap; | struct ieee80211vap *vap = ni->ni_vap; | ||||
struct ieee80211_rssadapt *rsa = vap->iv_rs; | struct ieee80211_rssadapt *rsa = vap->iv_rs; | ||||
const struct ieee80211_rateset *rs = &ni->ni_rates; | const struct ieee80211_rateset *rs = &ni->ni_rates; | ||||
uint16_t rate_index; | |||||
int rix; | |||||
if (ni->ni_rctls == NULL) { | if (ni->ni_rctls == NULL) { | ||||
ni->ni_rctls = ra = | ni->ni_rctls = ra = | ||||
IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt_node), | IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt_node), | ||||
M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); | M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); | ||||
if (ra == NULL) { | if (ra == NULL) { | ||||
if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl " | if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl " | ||||
"structure\n"); | "structure\n"); | ||||
return; | return; | ||||
} | } | ||||
} else | } else | ||||
ra = ni->ni_rctls; | ra = ni->ni_rctls; | ||||
ra->ra_rs = rsa; | ra->ra_rs = rsa; | ||||
ra->ra_rates = *rs; | ra->ra_rates = *rs; | ||||
rssadapt_updatestats(ra); | rssadapt_updatestats(ra); | ||||
if (__predict_false(rs->rs_nrates == 0)) { | |||||
if_printf(vap->iv_ifp, "%s: no rates available!\n", __func__); | |||||
return; | |||||
} | |||||
/* pick initial rate */ | /* pick initial rate */ | ||||
for (ra->ra_rix = rs->rs_nrates - 1; | for (rix = rs->rs_nrates - 1; rix > 0; rix--) { | ||||
ra->ra_rix > 0 && (rs->rs_rates[ra->ra_rix] & IEEE80211_RATE_VAL) > 72; | rate_index = rs->rates[rix].rs_index; | ||||
ra->ra_rix--) | rate = ieee80211_get_rate(rate_index); | ||||
; | |||||
ni->ni_txrate = rs->rs_rates[ra->ra_rix] & IEEE80211_RATE_VAL; | if (rate->value <= 72) | ||||
break; | |||||
} | |||||
ni->ni_txrate = rs->rates[rix].rs_index; | |||||
ra->ra_ticks = ticks; | ra->ra_ticks = ticks; | ||||
ra->ra_rix = rix; | |||||
rate = ieee80211_get_rate(ni->ni_txrate); | |||||
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, | IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, | ||||
"RSSADAPT initial rate %d", ni->ni_txrate); | "RSSADAPT initial rate %u/%u", rate->type, rate->value); | ||||
} | } | ||||
static void | static void | ||||
rssadapt_node_deinit(struct ieee80211_node *ni) | rssadapt_node_deinit(struct ieee80211_node *ni) | ||||
{ | { | ||||
IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL); | IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL); | ||||
} | } | ||||
Show All 11 Lines | if (pktlen <= top) | ||||
break; | break; | ||||
} | } | ||||
return thridx; | return thridx; | ||||
} | } | ||||
static int | static int | ||||
rssadapt_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg) | rssadapt_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg) | ||||
{ | { | ||||
const struct ieee80211_rate_t *rate; | |||||
struct ieee80211_rssadapt_node *ra = ni->ni_rctls; | struct ieee80211_rssadapt_node *ra = ni->ni_rctls; | ||||
u_int pktlen = iarg; | u_int pktlen = iarg; | ||||
const struct ieee80211_rateset *rs = &ra->ra_rates; | const struct ieee80211_rateset *rs = &ra->ra_rates; | ||||
uint16_t (*thrs)[IEEE80211_RATE_SIZE]; | uint16_t (*thrs)[IEEE80211_RATE_SIZE]; | ||||
int rix, rssi; | int rix, rssi; | ||||
if ((ticks - ra->ra_ticks) > ra->ra_rs->interval) { | if ((ticks - ra->ra_ticks) > ra->ra_rs->interval) { | ||||
rssadapt_updatestats(ra); | rssadapt_updatestats(ra); | ||||
ra->ra_ticks = ticks; | ra->ra_ticks = ticks; | ||||
} | } | ||||
thrs = &ra->ra_rate_thresh[bucket(pktlen)]; | thrs = &ra->ra_rate_thresh[bucket(pktlen)]; | ||||
/* XXX this is average rssi, should be using last value */ | /* XXX this is average rssi, should be using last value */ | ||||
rssi = ni->ni_ic->ic_node_getrssi(ni); | rssi = ni->ni_ic->ic_node_getrssi(ni); | ||||
for (rix = rs->rs_nrates-1; rix >= 0; rix--) | for (rix = rs->rs_nrates - 1; rix >= 0; rix--) | ||||
if ((*thrs)[rix] < (rssi << 8)) | if ((*thrs)[rix] < (rssi << 8)) | ||||
break; | break; | ||||
if (rix != ra->ra_rix) { | if (rix != ra->ra_rix) { | ||||
/* update public rate */ | /* update public rate */ | ||||
ni->ni_txrate = ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL; | ni->ni_txrate = ni->ni_rates.rates[rix].rs_index; | ||||
ra->ra_rix = rix; | ra->ra_rix = rix; | ||||
rate = ieee80211_get_rate(ni->ni_txrate); | |||||
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, | IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, | ||||
"RSSADAPT new rate %d (pktlen %d rssi %d)", | "RSSADAPT new rate %u/%u (pktlen %d rssi %d)", | ||||
ni->ni_txrate, pktlen, rssi); | rate->type, rate->value, pktlen, rssi); | ||||
} | } | ||||
return rix; | return rix; | ||||
} | } | ||||
/* | /* | ||||
* Adapt the data rate to suit the conditions. When a transmitted | * Adapt the data rate to suit the conditions. When a transmitted | ||||
* packet is dropped after RAL_RSSADAPT_RETRY_LIMIT retransmissions, | * packet is dropped after RAL_RSSADAPT_RETRY_LIMIT retransmissions, | ||||
* raise the RSS threshold for transmitting packets of similar length at | * raise the RSS threshold for transmitting packets of similar length at | ||||
* the same data rate. | * the same data rate. | ||||
*/ | */ | ||||
static void | static void | ||||
rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) | rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) | ||||
{ | { | ||||
const struct ieee80211_rate_t *rate; | |||||
uint16_t last_thr; | uint16_t last_thr; | ||||
uint16_t (*thrs)[IEEE80211_RATE_SIZE]; | uint16_t (*thrs)[IEEE80211_RATE_SIZE]; | ||||
u_int rix; | u_int rix; | ||||
thrs = &ra->ra_rate_thresh[bucket(pktlen)]; | thrs = &ra->ra_rate_thresh[bucket(pktlen)]; | ||||
rix = ra->ra_rix; | rix = ra->ra_rix; | ||||
last_thr = (*thrs)[rix]; | last_thr = (*thrs)[rix]; | ||||
(*thrs)[rix] = interpolate(master_expavgctl.rc_thresh, | (*thrs)[rix] = interpolate(master_expavgctl.rc_thresh, | ||||
last_thr, (rssi << 8)); | last_thr, (rssi << 8)); | ||||
rate = ieee80211_get_rate(ra->ra_rates.rates[rix + 1].rs_index); | |||||
IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, | IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, | ||||
"RSSADAPT lower threshold for rate %d (last_thr %d new thr %d rssi %d)\n", | "RSSADAPT lower threshold for rate %u/%u " | ||||
ra->ra_rates.rs_rates[rix + 1] & IEEE80211_RATE_VAL, | "(last_thr %d new thr %d rssi %d)\n", | ||||
last_thr, (*thrs)[rix], rssi); | rate->type, rate->value, last_thr, (*thrs)[rix], rssi); | ||||
} | } | ||||
static void | static void | ||||
rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) | rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) | ||||
{ | { | ||||
const struct ieee80211_rate_t *rate; | |||||
uint16_t (*thrs)[IEEE80211_RATE_SIZE]; | uint16_t (*thrs)[IEEE80211_RATE_SIZE]; | ||||
uint16_t newthr, oldthr; | uint16_t newthr, oldthr; | ||||
int rix; | int rix; | ||||
thrs = &ra->ra_rate_thresh[bucket(pktlen)]; | thrs = &ra->ra_rate_thresh[bucket(pktlen)]; | ||||
rix = ra->ra_rix; | rix = ra->ra_rix; | ||||
if ((*thrs)[rix + 1] > (*thrs)[rix]) { | if ((*thrs)[rix + 1] > (*thrs)[rix]) { | ||||
oldthr = (*thrs)[rix + 1]; | oldthr = (*thrs)[rix + 1]; | ||||
if ((*thrs)[rix] == 0) | if ((*thrs)[rix] == 0) | ||||
newthr = (rssi << 8); | newthr = (rssi << 8); | ||||
else | else | ||||
newthr = (*thrs)[rix]; | newthr = (*thrs)[rix]; | ||||
(*thrs)[rix + 1] = interpolate(master_expavgctl.rc_decay, | (*thrs)[rix + 1] = interpolate(master_expavgctl.rc_decay, | ||||
oldthr, newthr); | oldthr, newthr); | ||||
rate = | |||||
ieee80211_get_rate(ra->ra_rates.rates[rix + 1].rs_index); | |||||
IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, | IEEE80211_DPRINTF(ra->ra_rs->vap, IEEE80211_MSG_RATECTL, | ||||
"RSSADAPT raise threshold for rate %d (oldthr %d newthr %d rssi %d)\n", | "RSSADAPT raise threshold for rate %u/%u " | ||||
ra->ra_rates.rs_rates[rix + 1] & IEEE80211_RATE_VAL, | "(oldthr %d newthr %d rssi %d)\n", | ||||
oldthr, newthr, rssi); | rate->type, rate->value, oldthr, newthr, rssi); | ||||
ra->ra_last_raise = ticks; | ra->ra_last_raise = ticks; | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
rssadapt_tx_complete(const struct ieee80211_node *ni, | rssadapt_tx_complete(const struct ieee80211_node *ni, | ||||
const struct ieee80211_ratectl_tx_status *status) | const struct ieee80211_ratectl_tx_status *status) | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |