From be4f96a6b7ff02315471a3d5544c7a37d59e12cf Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 20 Jul 2012 02:17:48 +0000 Subject: [PATCH] Introduce a rate table TLV so rate table statistics consumers know how to map rix -> rate code. --- sys/dev/ath/ath_rate/sample/sample.c | 64 +++++++++++++++++----------- sys/dev/ath/if_athioctl.h | 12 ++++++ 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c index b1003be2a2a9..cccf0e539396 100644 --- a/sys/dev/ath/ath_rate/sample/sample.c +++ b/sys/dev/ath/ath_rate/sample/sample.c @@ -1207,8 +1207,9 @@ ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an, 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; + struct ath_rateioctl_rt *tv; int y; + int o = 0; ATH_NODE_LOCK_ASSERT(an); @@ -1217,48 +1218,61 @@ ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an, */ if (rs->len < sizeof(struct ath_rateioctl_tlv) + - sizeof(struct sample_node)) + sizeof(struct ath_rateioctl_rt) + + sizeof(struct ath_rateioctl_tlv) + + sizeof(struct sample_node)) { + device_printf(sc->sc_dev, "%s: len=%d, too short\n", + __func__, + rs->len); 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) + tv = malloc(sizeof(struct ath_rateioctl_rt), M_TEMP, + M_NOWAIT | M_ZERO); + if (tv == 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. + * Populate the rate table mapping TLV. + */ + tv->nentries = rt->rateCount; + for (y = 0; y < rt->rateCount; y++) { + tv->ratecode[y] = rt->info[y].dot11Rate & IEEE80211_RATE_VAL; + if (rt->info[y].phy == IEEE80211_T_HT) + tv->ratecode[y] |= IEEE80211_RATE_MCS; + } + + o = 0; + /* + * First TLV - rate code mapping + */ + av.tlv_id = ATH_RATE_TLV_RATETABLE; + av.tlv_len = sizeof(struct ath_rateioctl_rt); + copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv)); + o += sizeof(struct ath_rateioctl_tlv); + copyout(tv, rs->buf + o, sizeof(struct ath_rateioctl_rt)); + o += sizeof(struct ath_rateioctl_rt); + + /* + * Second TLV - sample node statistics */ av.tlv_id = ATH_RATE_TLV_SAMPLENODE; av.tlv_len = sizeof(struct sample_node); - copyout(&av, rs->buf, sizeof(struct ath_rateioctl_tlv)); + copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv)); + o += 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)); + copyout(sn, rs->buf + o, sizeof(struct sample_node)); + o += sizeof(struct sample_node); - free(ts, M_TEMP); + free(tv, M_TEMP); return (0); } diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h index b8199cd25a02..7f6b735a6229 100644 --- a/sys/dev/ath/if_athioctl.h +++ b/sys/dev/ath/if_athioctl.h @@ -203,6 +203,18 @@ struct ath_rateioctl_tlv { */ #define ATH_RATE_TLV_MACADDR 0xaab0 +/* + * The rate control modules may decide to push a mapping table + * of rix -> net80211 ratecode as part of the update. + */ +#define ATH_RATE_TLV_RATETABLE_NENTRIES 64 +struct ath_rateioctl_rt { + uint16_t nentries; + uint16_t pad[1]; + uint8_t ratecode[ATH_RATE_TLV_RATETABLE_NENTRIES]; +}; +#define ATH_RATE_TLV_RATETABLE 0xaab1 + /* * This is the sample node statistics structure. * More in ath_rate/sample/sample.h.