mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 14:48:57 +00:00
Add a per-node rate control routine for each rate control module.
For now, the only module implement is 'sample', and that's only partially implemented. The main issue here with reusing this structure in userland is that it uses 'rix' everywhere, which requires the userland code to have access to the current HAL rate table. For now, this is a very large work in progress. Specific details: * The rate control information is per-node at the moment and wrapped in a TLV, to ease parsing and backwards compatibility. * .. but so I can be slack for now, the userland statistics are just a copy of the kernel-land sample node state. * However, for now use a temporary copy and change the rix entries to dot11rate entries to make it slightly easier to eyeball. Problems: * The actual rate information table is unfortunately indexed by rix and it doesn't contain a rate code. So the userland side of this currently has no way to extract out a mapping. TODO: * Add a TLV payload to dump out the rate control table mapping so 'rix' can be turned into a dot11 / MCS rate. * .. then remove the temporary copy.
This commit is contained in:
parent
9e38f70840
commit
2d20d6559d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=238633
@ -421,6 +421,14 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an,
|
||||
struct ath_rateioctl *re)
|
||||
{
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
ath_rate_sysctlattach(struct ath_softc *sc)
|
||||
{
|
||||
|
@ -407,6 +407,14 @@ ath_rate_sysctlattach(struct ath_softc *sc)
|
||||
"rate control: # good periods before raising rate");
|
||||
}
|
||||
|
||||
static int
|
||||
ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an,
|
||||
struct ath_rateioctl *re)
|
||||
{
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
struct ath_ratectrl *
|
||||
ath_rate_attach(struct ath_softc *sc)
|
||||
{
|
||||
|
@ -105,8 +105,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *);
|
||||
|
||||
static const int packet_size_bins[NUM_PACKET_SIZE_BINS] = { 250, 1600 };
|
||||
|
||||
static __inline int
|
||||
size_to_bin(int size)
|
||||
{
|
||||
@ -128,12 +126,6 @@ size_to_bin(int size)
|
||||
return NUM_PACKET_SIZE_BINS-1;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bin_to_size(int index)
|
||||
{
|
||||
return packet_size_bins[index];
|
||||
}
|
||||
|
||||
void
|
||||
ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
|
||||
{
|
||||
@ -1198,6 +1190,79 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
|
||||
#undef DOT11RATE
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the statistics for the given node.
|
||||
*
|
||||
* The ieee80211 node must be referenced and unlocked, however the ath_node
|
||||
* must be locked.
|
||||
*
|
||||
* The main difference here is that we convert the rate indexes
|
||||
* to 802.11 rates, or the userland output won't make much sense
|
||||
* as it has no access to the rix table.
|
||||
*/
|
||||
int
|
||||
ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an,
|
||||
struct ath_rateioctl *rs)
|
||||
{
|
||||
struct sample_node *sn = ATH_NODE_SAMPLE(an);
|
||||
const HAL_RATE_TABLE *rt = sc->sc_currates;
|
||||
struct ath_rateioctl_tlv av;
|
||||
struct sample_node *ts;
|
||||
int y;
|
||||
|
||||
ATH_NODE_LOCK_ASSERT(an);
|
||||
|
||||
/*
|
||||
* Ensure there's enough space for the statistics.
|
||||
*/
|
||||
if (rs->len <
|
||||
sizeof(struct ath_rateioctl_tlv) +
|
||||
sizeof(struct sample_node))
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* Take a temporary copy of the sample node state so we can
|
||||
* modify it before we copy it.
|
||||
*/
|
||||
ts = malloc(sizeof(struct sample_node), M_TEMP, M_WAITOK | M_ZERO);
|
||||
if (ts == NULL)
|
||||
return (ENOMEM);
|
||||
memcpy(ts, sn, sizeof(struct sample_node));
|
||||
|
||||
/* Convert rix -> 802.11 rate codes */
|
||||
ts->static_rix = dot11rate(rt, sn->static_rix);
|
||||
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
|
||||
/*
|
||||
* For non-11n rates, clear the high bit - that
|
||||
* means "basic rate" and will confuse things.
|
||||
*
|
||||
* For 11n rates, set the high bit.
|
||||
*/
|
||||
ts->current_rix[y] = dot11rate(rt, sn->current_rix[y]);
|
||||
ts->current_sample_rix[y] =
|
||||
dot11rate(rt, sn->current_sample_rix[y]);
|
||||
ts->last_sample_rix[y] =
|
||||
dot11rate(rt, sn->last_sample_rix[y]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assemble the TLV.
|
||||
*/
|
||||
av.tlv_id = ATH_RATE_TLV_SAMPLENODE;
|
||||
av.tlv_len = sizeof(struct sample_node);
|
||||
copyout(&av, rs->buf, sizeof(struct ath_rateioctl_tlv));
|
||||
|
||||
/*
|
||||
* Copy the statistics over to the provided buffer.
|
||||
*/
|
||||
copyout(ts, rs->buf + sizeof(struct ath_rateioctl_tlv),
|
||||
sizeof(struct sample_node));
|
||||
|
||||
free(ts, M_TEMP);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
sample_stats(void *arg, struct ieee80211_node *ni)
|
||||
{
|
||||
|
@ -79,6 +79,14 @@ struct txschedule {
|
||||
*/
|
||||
#define NUM_PACKET_SIZE_BINS 2
|
||||
|
||||
static const int packet_size_bins[NUM_PACKET_SIZE_BINS] = { 250, 1600 };
|
||||
|
||||
static inline int
|
||||
bin_to_size(int index)
|
||||
{
|
||||
return packet_size_bins[index];
|
||||
}
|
||||
|
||||
/* per-node state */
|
||||
struct sample_node {
|
||||
int static_rix; /* rate index of fixed tx rate */
|
||||
|
Loading…
Reference in New Issue
Block a user