Maintain a history of data associated with received frames and use this to
calculate smoothed signal quality data for each node. o add a 16-deep history buffer to each driver-private node storage that holds rssi and antenna info for received frames o override the default per-node "get rssi" method to return an average rssi value based on samples collected over the last second o enable beacon reception so even idle systems maintain a running history of signal quality This data may also be useful for improving the rate control algorithm. Based on work by Tom Marshall <tommy@home.tig-grr.com> for MADWIFI.
This commit is contained in:
parent
d1e61976a0
commit
de5af70460
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=120105
@ -114,6 +114,8 @@ static struct ieee80211_node *ath_node_alloc(struct ieee80211com *);
|
||||
static void ath_node_free(struct ieee80211com *, struct ieee80211_node *);
|
||||
static void ath_node_copy(struct ieee80211com *,
|
||||
struct ieee80211_node *, const struct ieee80211_node *);
|
||||
static u_int8_t ath_node_getrssi(struct ieee80211com *,
|
||||
struct ieee80211_node *);
|
||||
static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
|
||||
static void ath_rx_proc(void *, int);
|
||||
static int ath_tx_start(struct ath_softc *, struct ieee80211_node *,
|
||||
@ -290,6 +292,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
||||
ic->ic_node_alloc = ath_node_alloc;
|
||||
ic->ic_node_free = ath_node_free;
|
||||
ic->ic_node_copy = ath_node_copy;
|
||||
ic->ic_node_getrssi = ath_node_getrssi;
|
||||
sc->sc_newstate = ic->ic_newstate;
|
||||
ic->ic_newstate = ath_newstate;
|
||||
/* complete initialization */
|
||||
@ -922,7 +925,8 @@ ath_mode_init(struct ath_softc *sc)
|
||||
if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
|
||||
(ifp->if_flags & IFF_PROMISC))
|
||||
rfilt |= HAL_RX_FILTER_PROM;
|
||||
if (ic->ic_state == IEEE80211_S_SCAN)
|
||||
if (ic->ic_opmode == IEEE80211_M_STA ||
|
||||
ic->ic_state == IEEE80211_S_SCAN)
|
||||
rfilt |= HAL_RX_FILTER_BEACON;
|
||||
ath_hal_setrxfilter(ah, rfilt);
|
||||
|
||||
@ -1387,7 +1391,14 @@ ath_node_alloc(struct ieee80211com *ic)
|
||||
{
|
||||
struct ath_node *an =
|
||||
malloc(sizeof(struct ath_node), M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
return an ? &an->an_node : NULL;
|
||||
if (an) {
|
||||
int i;
|
||||
for (i = 0; i < ATH_RHIST_SIZE; i++)
|
||||
an->an_rx_hist[i].arh_ticks = ATH_RHIST_NOTIME;
|
||||
an->an_rx_hist_next = ATH_RHIST_SIZE-1;
|
||||
return &an->an_node;
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1410,6 +1421,41 @@ ath_node_copy(struct ieee80211com *ic,
|
||||
*(struct ath_node *)dst = *(const struct ath_node *)src;
|
||||
}
|
||||
|
||||
|
||||
static u_int8_t
|
||||
ath_node_getrssi(struct ieee80211com *ic, struct ieee80211_node *ni)
|
||||
{
|
||||
struct ath_node *an = ATH_NODE(ni);
|
||||
int i, now, nsamples, rssi;
|
||||
|
||||
/*
|
||||
* Calculate the average over the last second of sampled data.
|
||||
*/
|
||||
now = ticks;
|
||||
nsamples = 0;
|
||||
rssi = 0;
|
||||
i = an->an_rx_hist_next;
|
||||
do {
|
||||
struct ath_recv_hist *rh = &an->an_rx_hist[i];
|
||||
if (rh->arh_ticks == ATH_RHIST_NOTIME)
|
||||
goto done;
|
||||
if (now - rh->arh_ticks > hz)
|
||||
goto done;
|
||||
rssi += rh->arh_rssi;
|
||||
nsamples++;
|
||||
if (i == 0)
|
||||
i = ATH_RHIST_SIZE-1;
|
||||
else
|
||||
i--;
|
||||
} while (i != an->an_rx_hist_next);
|
||||
done:
|
||||
/*
|
||||
* Return either the average or the last known
|
||||
* value if there is no recent data.
|
||||
*/
|
||||
return (nsamples ? rssi / nsamples : an->an_rx_hist[i].arh_rssi);
|
||||
}
|
||||
|
||||
static int
|
||||
ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
|
||||
{
|
||||
@ -1478,6 +1524,8 @@ ath_rx_proc(void *arg, int npending)
|
||||
struct mbuf *m;
|
||||
struct ieee80211_frame *wh, whbuf;
|
||||
struct ieee80211_node *ni;
|
||||
struct ath_node *an;
|
||||
struct ath_recv_hist *rh;
|
||||
int len;
|
||||
u_int phyerr;
|
||||
HAL_STATUS status;
|
||||
@ -1588,12 +1636,24 @@ ath_rx_proc(void *arg, int npending)
|
||||
ni = ieee80211_ref_node(ic->ic_bss);
|
||||
} else
|
||||
ni = ieee80211_ref_node(ic->ic_bss);
|
||||
ATH_NODE(ni)->an_rx_antenna = ds->ds_rxstat.rs_antenna;
|
||||
|
||||
/*
|
||||
* Record driver-specific state.
|
||||
*/
|
||||
an = ATH_NODE(ni);
|
||||
if (++(an->an_rx_hist_next) == ATH_RHIST_SIZE)
|
||||
an->an_rx_hist_next = 0;
|
||||
rh = &an->an_rx_hist[an->an_rx_hist_next];
|
||||
rh->arh_ticks = ticks;
|
||||
rh->arh_rssi = ds->ds_rxstat.rs_rssi;
|
||||
rh->arh_antenna = ds->ds_rxstat.rs_antenna;
|
||||
|
||||
/*
|
||||
* Send frame up for processing.
|
||||
*/
|
||||
ieee80211_input(ifp, m, ni,
|
||||
ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
|
||||
|
||||
/*
|
||||
* The frame may have caused the node to be marked for
|
||||
* reclamation (e.g. in response to a DEAUTH message)
|
||||
@ -1859,7 +1919,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
|
||||
if (an->an_tx_antenna)
|
||||
antenna = an->an_tx_antenna;
|
||||
else
|
||||
antenna = an->an_rx_antenna;
|
||||
antenna = an->an_rx_hist[an->an_rx_hist_next].arh_antenna;
|
||||
|
||||
/*
|
||||
* Formulate first tx descriptor with tx controls.
|
||||
@ -2288,11 +2348,13 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
|
||||
(ifp->if_flags & IFF_PROMISC))
|
||||
rfilt |= HAL_RX_FILTER_PROM;
|
||||
if (ic->ic_opmode == IEEE80211_M_STA ||
|
||||
ic->ic_state == IEEE80211_S_SCAN)
|
||||
rfilt |= HAL_RX_FILTER_BEACON;
|
||||
if (nstate == IEEE80211_S_SCAN) {
|
||||
callout_reset(&sc->sc_scan_ch, (hz * ath_dwelltime) / 1000,
|
||||
ath_next_scan, sc);
|
||||
bssid = ifp->if_broadcastaddr;
|
||||
rfilt |= HAL_RX_FILTER_BEACON;
|
||||
} else {
|
||||
callout_stop(&sc->sc_scan_ch);
|
||||
bssid = ni->ni_bssid;
|
||||
|
@ -54,6 +54,14 @@
|
||||
#define ATH_TXBUF 60 /* number of TX buffers */
|
||||
#define ATH_TXDESC 8 /* number of descriptors per buffer */
|
||||
|
||||
struct ath_recv_hist {
|
||||
int arh_ticks; /* sample time by system clock */
|
||||
u_int8_t arh_rssi; /* rssi */
|
||||
u_int8_t arh_antenna; /* antenna */
|
||||
};
|
||||
#define ATH_RHIST_SIZE 16 /* number of samples */
|
||||
#define ATH_RHIST_NOTIME (~0)
|
||||
|
||||
/* driver-specific node */
|
||||
struct ath_node {
|
||||
struct ieee80211_node an_node; /* base class */
|
||||
@ -63,6 +71,8 @@ struct ath_node {
|
||||
int an_tx_upper; /* tx upper rate req cnt */
|
||||
u_int an_tx_antenna; /* antenna for last good frame */
|
||||
u_int an_rx_antenna; /* antenna for last rcvd frame */
|
||||
struct ath_recv_hist an_rx_hist[ATH_RHIST_SIZE];
|
||||
u_int an_rx_hist_next;/* index of next ``free entry'' */
|
||||
};
|
||||
#define ATH_NODE(_n) ((struct ath_node *)(_n))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user