[net80211] Begin implementing rate control module stats.
* Implement a new ratectl method, which defaults to returning nothing; * Add a top level sysctl (net.wlan.X.rate_stats) to extract it; * Add ratectl info for the 'amrr' module. Tested: * urtwn(4), STA mode Differential Revision: https://reviews.freebsd.org/D5630
This commit is contained in:
parent
d775d23ac5
commit
73931706e7
@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
@ -75,6 +76,7 @@ static void amrr_tx_update(const struct ieee80211vap *vap,
|
||||
const struct ieee80211_node *, void *, void *, void *);
|
||||
static void amrr_sysctlattach(struct ieee80211vap *,
|
||||
struct sysctl_ctx_list *, struct sysctl_oid *);
|
||||
static void amrr_node_stats(struct ieee80211_node *ni, struct sbuf *s);
|
||||
|
||||
/* number of references from net80211 layer */
|
||||
static int nrefs = 0;
|
||||
@ -91,6 +93,7 @@ static const struct ieee80211_ratectl amrr = {
|
||||
.ir_tx_complete = amrr_tx_complete,
|
||||
.ir_tx_update = amrr_tx_update,
|
||||
.ir_setinterval = amrr_setinterval,
|
||||
.ir_node_stats = amrr_node_stats,
|
||||
};
|
||||
IEEE80211_RATECTL_MODULE(amrr, 1);
|
||||
IEEE80211_RATECTL_ALG(amrr, IEEE80211_RATECTL_AMRR, amrr);
|
||||
@ -410,3 +413,31 @@ amrr_sysctlattach(struct ieee80211vap *vap,
|
||||
"amrr_min_sucess_threshold", CTLFLAG_RW,
|
||||
&amrr->amrr_min_success_threshold, 0, "");
|
||||
}
|
||||
|
||||
static void
|
||||
amrr_node_stats(struct ieee80211_node *ni, struct sbuf *s)
|
||||
{
|
||||
int rate;
|
||||
struct ieee80211_amrr_node *amn = ni->ni_rctls;
|
||||
struct ieee80211_rateset *rs;
|
||||
|
||||
/* XXX TODO: check locking? */
|
||||
|
||||
/* XXX TODO: this should be a method */
|
||||
if (amrr_node_is_11n(ni)) {
|
||||
rs = (struct ieee80211_rateset *) &ni->ni_htrates;
|
||||
rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
|
||||
sbuf_printf(s, "rate: MCS %d\n", rate);
|
||||
} else {
|
||||
rs = &ni->ni_rates;
|
||||
rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
|
||||
sbuf_printf(s, "rate: %d Mbit\n", rate / 2);
|
||||
}
|
||||
|
||||
sbuf_printf(s, "ticks: %d\n", amn->amn_ticks);
|
||||
sbuf_printf(s, "txcnt: %u\n", amn->amn_txcnt);
|
||||
sbuf_printf(s, "success: %u\n", amn->amn_success);
|
||||
sbuf_printf(s, "success_threshold: %u\n", amn->amn_success_threshold);
|
||||
sbuf_printf(s, "recovery: %u\n", amn->amn_recovery);
|
||||
sbuf_printf(s, "retry_cnt: %u\n", amn->amn_retrycnt);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -68,12 +69,52 @@ ieee80211_ratectl_unregister(int type)
|
||||
ratectls[type] = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211_ratectl_sysctl_stats_node_iter(void *arg, struct ieee80211_node *ni)
|
||||
{
|
||||
|
||||
struct sbuf *sb = (struct sbuf *) arg;
|
||||
sbuf_printf(sb, "MAC: %6D\n", ni->ni_macaddr, ":");
|
||||
ieee80211_ratectl_node_stats(ni, sb);
|
||||
sbuf_printf(sb, "\n");
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_ratectl_sysctl_stats(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct ieee80211vap *vap = arg1;
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
struct sbuf sb;
|
||||
int error;
|
||||
|
||||
error = sysctl_wire_old_buffer(req, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
sbuf_new_for_sysctl(&sb, NULL, 8, req);
|
||||
sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
|
||||
|
||||
IEEE80211_LOCK(ic);
|
||||
ieee80211_iterate_nodes(&ic->ic_sta,
|
||||
ieee80211_ratectl_sysctl_stats_node_iter,
|
||||
&sb);
|
||||
IEEE80211_UNLOCK(ic);
|
||||
|
||||
error = sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
ieee80211_ratectl_init(struct ieee80211vap *vap)
|
||||
{
|
||||
if (vap->iv_rate == ratectls[IEEE80211_RATECTL_NONE])
|
||||
ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR);
|
||||
vap->iv_rate->ir_init(vap);
|
||||
|
||||
/* Attach generic stats sysctl */
|
||||
SYSCTL_ADD_PROC(vap->iv_sysctl, SYSCTL_CHILDREN(vap->iv_oid), OID_AUTO,
|
||||
"rate_stats", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, vap,
|
||||
0, ieee80211_ratectl_sysctl_stats, "A", "ratectl node stats");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -53,6 +53,7 @@ struct ieee80211_ratectl {
|
||||
const struct ieee80211_node *,
|
||||
void *, void *, void *);
|
||||
void (*ir_setinterval)(const struct ieee80211vap *, int);
|
||||
void (*ir_node_stats)(struct ieee80211_node *ni, struct sbuf *s);
|
||||
};
|
||||
|
||||
void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *);
|
||||
@ -115,3 +116,13 @@ ieee80211_ratectl_setinterval(const struct ieee80211vap *vap, int msecs)
|
||||
return;
|
||||
vap->iv_rate->ir_setinterval(vap, msecs);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
ieee80211_ratectl_node_stats(struct ieee80211_node *ni, struct sbuf *s)
|
||||
{
|
||||
const struct ieee80211vap *vap = ni->ni_vap;
|
||||
|
||||
if (vap->iv_rate->ir_node_stats == NULL)
|
||||
return;
|
||||
vap->iv_rate->ir_node_stats(ni, s);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user