Bring the following change from OpenBSD:
Keep track of the average RSSI using an Exponential Moving Average (EMA). Use it to dynamically tune radio receive sensitivity. The idea is simple: - increase sensitivity when the RSSI is bad to optimize throughput on long distance to the AP, and - decrease sensitivity when the RSSI is good to reduce noise level and optimize throughput on short distance to the AP The EMA allows to smooth RSSI variations so we don't end up changing the sensitivity too frequently. We check if it would be worth updating the sensitivity every one second. RSSI thresholds were taken from the Ralink Tech. Linux driver.
This commit is contained in:
parent
d8c7f94e0e
commit
69ae4b1781
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rt2661.c,v 1.5 2006/06/08 13:00:35 rpaulo Exp $ */
|
||||
/* $NetBSD: rt2661.c,v 1.6 2006/06/08 20:56:41 rpaulo Exp $ */
|
||||
/* $OpenBSD: rt2661.c,v 1.17 2006/05/01 08:41:11 damien Exp $ */
|
||||
/* $FreeBSD: rt2560.c,v 1.5 2006/06/02 19:59:31 csjp Exp $ */
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rt2661.c,v 1.5 2006/06/08 13:00:35 rpaulo Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rt2661.c,v 1.6 2006/06/08 20:56:41 rpaulo Exp $");
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
@ -99,7 +99,7 @@ static struct ieee80211_node *
|
||||
static int rt2661_media_change(struct ifnet *);
|
||||
static void rt2661_next_scan(void *);
|
||||
static void rt2661_iter_func(void *, struct ieee80211_node *);
|
||||
static void rt2661_rssadapt_updatestats(void *);
|
||||
static void rt2661_updatestats(void *);
|
||||
static int rt2661_newstate(struct ieee80211com *, enum ieee80211_state,
|
||||
int);
|
||||
static uint16_t rt2661_eeprom_read(struct rt2661_softc *, uint8_t);
|
||||
@ -158,8 +158,8 @@ static int rt2661_init(struct ifnet *);
|
||||
static void rt2661_stop(struct ifnet *, int);
|
||||
static int rt2661_load_microcode(struct rt2661_softc *, const uint8_t *,
|
||||
int);
|
||||
#ifdef notyet
|
||||
static void rt2661_rx_tune(struct rt2661_softc *);
|
||||
#ifdef notyet
|
||||
static void rt2661_radar_start(struct rt2661_softc *);
|
||||
static int rt2661_radar_stop(struct rt2661_softc *);
|
||||
#endif
|
||||
@ -894,18 +894,26 @@ rt2661_iter_func(void *arg, struct ieee80211_node *ni)
|
||||
|
||||
/*
|
||||
* This function is called periodically (every 100ms) in RUN state to update
|
||||
* the rate adaptation statistics.
|
||||
* various settings like rate control statistics or Rx sensitivity.
|
||||
*/
|
||||
static void
|
||||
rt2661_rssadapt_updatestats(void *arg)
|
||||
rt2661_updatestats(void *arg)
|
||||
{
|
||||
struct rt2661_softc *sc = arg;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg);
|
||||
if (ic->ic_opmode == IEEE80211_M_STA)
|
||||
rt2661_iter_func(sc, ic->ic_bss);
|
||||
else
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg);
|
||||
|
||||
callout_reset(&sc->rssadapt_ch, hz / 10, rt2661_rssadapt_updatestats,
|
||||
sc);
|
||||
/* update rx sensitivity every 1 sec */
|
||||
if (++sc->ncalls == 10) {
|
||||
rt2661_rx_tune(sc);
|
||||
sc->ncalls = 0;
|
||||
}
|
||||
|
||||
callout_reset(&sc->rssadapt_ch, hz / 10, rt2661_updatestats, sc);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -960,8 +968,10 @@ rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
}
|
||||
|
||||
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
|
||||
sc->ncalls = 0;
|
||||
sc->avg_rssi = -95; /* reset EMA */
|
||||
callout_reset(&sc->rssadapt_ch, hz / 10,
|
||||
rt2661_rssadapt_updatestats, sc);
|
||||
rt2661_updatestats, sc);
|
||||
rt2661_enable_tsf_sync(sc);
|
||||
}
|
||||
break;
|
||||
@ -1151,7 +1161,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
|
||||
struct ieee80211_frame *wh;
|
||||
struct ieee80211_node *ni;
|
||||
struct mbuf *mnew, *m;
|
||||
int error;
|
||||
int error, rssi;
|
||||
|
||||
for (;;) {
|
||||
desc = &sc->rxq.desc[sc->rxq.cur];
|
||||
@ -1267,8 +1277,15 @@ rt2661_rx_intr(struct rt2661_softc *sc)
|
||||
|
||||
/* give rssi to the rate adatation algorithm */
|
||||
rn = (struct rt2661_node *)ni;
|
||||
ieee80211_rssadapt_input(ic, ni, &rn->rssadapt,
|
||||
rt2661_get_rssi(sc, desc->rssi));
|
||||
rssi = rt2661_get_rssi(sc, desc->rssi);
|
||||
ieee80211_rssadapt_input(ic, ni, &rn->rssadapt, rssi);
|
||||
|
||||
/*-
|
||||
* Keep track of the average RSSI using an Exponential Moving
|
||||
* Average (EMA) of 8 Wilder's days:
|
||||
* avg = (1 / N) x rssi + ((N - 1) / N) x avg
|
||||
*/
|
||||
sc->avg_rssi = (rssi + 7 * sc->avg_rssi) / 8;
|
||||
|
||||
/* node is no longer needed */
|
||||
ieee80211_free_node(ni);
|
||||
@ -1724,7 +1741,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
|
||||
* than the length threshold indicated by [...]" ic_rtsthreshold.
|
||||
*/
|
||||
if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
|
||||
m0->m_pkthdr.len > ic->ic_rtsthreshold) {
|
||||
m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
|
||||
struct mbuf *m;
|
||||
int rtsrate, ackrate;
|
||||
|
||||
@ -1845,7 +1862,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
|
||||
data->m = m0;
|
||||
data->ni = ni;
|
||||
|
||||
/* remember link conditions for rate adaptation algorithm */
|
||||
/* remember link conditions for rate control algorithm */
|
||||
if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
|
||||
data->id.id_len = m0->m_pkthdr.len;
|
||||
data->id.id_rateidx = ni->ni_txrate;
|
||||
@ -2286,6 +2303,7 @@ rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
|
||||
bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
|
||||
}
|
||||
|
||||
sc->bbp17 = bbp17;
|
||||
rt2661_bbp_write(sc, 17, bbp17);
|
||||
rt2661_bbp_write(sc, 96, bbp96);
|
||||
rt2661_bbp_write(sc, 104, bbp104);
|
||||
@ -2894,7 +2912,6 @@ rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode, int size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Dynamically tune Rx sensitivity (BBP register 17) based on average RSSI and
|
||||
* false CCA count. This function is called periodically (every seconds) when
|
||||
@ -2919,44 +2936,43 @@ rt2661_rx_tune(struct rt2661_softc *sc)
|
||||
lo += 0x10;
|
||||
hi = lo + 0x20;
|
||||
|
||||
dbm = sc->avg_rssi;
|
||||
/* retrieve false CCA count since last call (clear on read) */
|
||||
cca = RAL_READ(sc, RT2661_STA_CSR1) & 0xffff;
|
||||
|
||||
if (dbm >= -35) {
|
||||
bbp17 = 0x60;
|
||||
} else if (dbm >= -58) {
|
||||
bbp17 = hi;
|
||||
} else if (dbm >= -66) {
|
||||
bbp17 = lo + 0x10;
|
||||
} else if (dbm >= -74) {
|
||||
bbp17 = lo + 0x08;
|
||||
} else {
|
||||
/* RSSI < -74dBm, tune using false CCA count */
|
||||
|
||||
DPRINTFN(2, ("RSSI=%ddBm false CCA=%d\n", dbm, cca));
|
||||
if (dbm < -74) {
|
||||
/* very bad RSSI, tune using false CCA count */
|
||||
bbp17 = sc->bbp17; /* current value */
|
||||
|
||||
hi -= 2 * (-74 - dbm);
|
||||
if (hi < lo)
|
||||
hi = lo;
|
||||
|
||||
if (bbp17 > hi) {
|
||||
if (bbp17 > hi)
|
||||
bbp17 = hi;
|
||||
|
||||
} else if (cca > 512) {
|
||||
if (++bbp17 > hi)
|
||||
bbp17 = hi;
|
||||
} else if (cca < 100) {
|
||||
if (--bbp17 < lo)
|
||||
bbp17 = lo;
|
||||
}
|
||||
else if (cca > 512)
|
||||
bbp17 = min(bbp17 + 1, hi);
|
||||
else if (cca < 100)
|
||||
bbp17 = max(bbp17 - 1, lo);
|
||||
} else if (dbm < -66) {
|
||||
bbp17 = lo + 0x08;
|
||||
} else if (dbm < -58) {
|
||||
bbp17 = lo + 0x10;
|
||||
} else if (dbm < -35) {
|
||||
bbp17 = hi;
|
||||
} else { /* very good RSSI >= -35dBm */
|
||||
bbp17 = 0x60; /* very low sensitivity */
|
||||
}
|
||||
|
||||
if (bbp17 != sc->bbp17) {
|
||||
DPRINTF(("BBP17 %x->%x\n", sc->bbp17, bbp17));
|
||||
rt2661_bbp_write(sc, 17, bbp17);
|
||||
sc->bbp17 = bbp17;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Enter/Leave radar detection mode.
|
||||
* This is for 802.11h additional regulatory domains.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rt2661var.h,v 1.2 2006/06/06 20:48:27 rpaulo Exp $ */
|
||||
/* $NetBSD: rt2661var.h,v 1.3 2006/06/08 20:56:41 rpaulo Exp $ */
|
||||
/* $OpenBSD: rt2661var.h,v 1.4 2006/02/25 12:56:47 damien Exp $ */
|
||||
|
||||
/*-
|
||||
@ -145,6 +145,9 @@ struct rt2661_softc {
|
||||
int rssi_2ghz_corr;
|
||||
int rssi_5ghz_corr;
|
||||
|
||||
int ncalls;
|
||||
int avg_rssi;
|
||||
|
||||
uint8_t bbp18;
|
||||
uint8_t bbp21;
|
||||
uint8_t bbp22;
|
||||
|
Loading…
Reference in New Issue
Block a user