From 4028af95f863f05837308523fd27d49eafd82bc6 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Thu, 8 Apr 2010 13:25:32 +0100 Subject: [PATCH] Sync with latest net80211 changes from FreeBSD, therby removing DFly's ratectl code. --- sys/conf/files | 5 +- sys/netproto/802_11/Makefile | 2 +- sys/netproto/802_11/ieee80211_amrr.h | 42 +- sys/netproto/802_11/ieee80211_dragonfly.h | 13 +- sys/netproto/802_11/ieee80211_node.h | 10 +- sys/netproto/802_11/ieee80211_ratectl.h | 246 +++-- sys/netproto/802_11/ieee80211_rssadapt.h | 35 +- sys/netproto/802_11/ieee80211_var.h | 30 +- sys/netproto/802_11/wlan/Makefile | 2 +- sys/netproto/802_11/wlan/ieee80211.c | 4 +- sys/netproto/802_11/wlan/ieee80211_amrr.c | 145 ++- sys/netproto/802_11/wlan/ieee80211_input.c | 16 +- sys/netproto/802_11/wlan/ieee80211_node.c | 4 +- sys/netproto/802_11/wlan/ieee80211_ratectl.c | 249 +---- sys/netproto/802_11/wlan/ieee80211_rssadapt.c | 132 ++- sys/netproto/802_11/wlan_ratectl/Makefile | 5 - .../802_11/wlan_ratectl/amrr/Makefile | 6 - .../wlan_ratectl/amrr/ieee80211_amrr_param.h | 66 -- .../amrr/ieee80211_ratectl_amrr.c | 597 ----------- .../802_11/wlan_ratectl/onoe/Makefile | 6 - .../wlan_ratectl/onoe/ieee80211_onoe_param.h | 65 -- .../onoe/ieee80211_ratectl_onoe.c | 586 ----------- .../802_11/wlan_ratectl/sample/Makefile | 6 - .../sample/ieee80211_ratectl_sample.c | 939 ------------------ .../sample/ieee80211_sample_param.h | 61 -- 25 files changed, 416 insertions(+), 2856 deletions(-) delete mode 100644 sys/netproto/802_11/wlan_ratectl/Makefile delete mode 100644 sys/netproto/802_11/wlan_ratectl/amrr/Makefile delete mode 100644 sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_amrr_param.h delete mode 100644 sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c delete mode 100644 sys/netproto/802_11/wlan_ratectl/onoe/Makefile delete mode 100644 sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h delete mode 100644 sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c delete mode 100644 sys/netproto/802_11/wlan_ratectl/sample/Makefile delete mode 100644 sys/netproto/802_11/wlan_ratectl/sample/ieee80211_ratectl_sample.c delete mode 100644 sys/netproto/802_11/wlan_ratectl/sample/ieee80211_sample_param.h diff --git a/sys/conf/files b/sys/conf/files index 7845befbb3..bfb1725e82 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -915,7 +915,7 @@ netproto/802_11/wlan/ieee80211_power.c optional wlan netproto/802_11/wlan/ieee80211_proto.c optional wlan netproto/802_11/wlan/ieee80211_radiotap.c optional wlan netproto/802_11/wlan/ieee80211_ratectl.c optional wlan -netproto/802_11/wlan/ieee80211_ratectl_none.c optional wlan +netproto/802_11/wlan/ieee80211_ratectl.c optional wlan netproto/802_11/wlan/ieee80211_regdomain.c optional wlan netproto/802_11/wlan/ieee80211_rssadapt.c optional wlan_rssadapt netproto/802_11/wlan/ieee80211_scan.c optional wlan @@ -925,9 +925,6 @@ netproto/802_11/wlan/ieee80211_superg.c optional wlan ieee80211_support_supe netproto/802_11/wlan/ieee80211_tdma.c optional wlan ieee80211_support_tdma netproto/802_11/wlan/ieee80211_wds.c optional wlan netproto/802_11/wlan_xauth/ieee80211_xauth.c optional wlan_xauth -netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c optional wlan_ratectl_onoe -netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c optional wlan_ratectl_amrr -netproto/802_11/wlan_ratectl/sample/ieee80211_ratectl_sample.c optional wlan_ratectl_sample netproto/atalk/aarp.c optional netatalk netproto/atalk/at_control.c optional netatalk netproto/atalk/at_proto.c optional netatalk diff --git a/sys/netproto/802_11/Makefile b/sys/netproto/802_11/Makefile index 89992156bb..d77d42a0b1 100644 --- a/sys/netproto/802_11/Makefile +++ b/sys/netproto/802_11/Makefile @@ -1,5 +1,5 @@ # $DragonFly: src/sys/netproto/802_11/Makefile,v 1.6 2006/09/01 15:12:11 sephe Exp $ -SUBDIR= wlan wlan_acl wlan_ccmp wlan_tkip wlan_wep wlan_xauth wlan_ratectl +SUBDIR= wlan wlan_acl wlan_ccmp wlan_tkip wlan_wep wlan_xauth .include diff --git a/sys/netproto/802_11/ieee80211_amrr.h b/sys/netproto/802_11/ieee80211_amrr.h index 4d8df07e65..61e999729e 100644 --- a/sys/netproto/802_11/ieee80211_amrr.h +++ b/sys/netproto/802_11/ieee80211_amrr.h @@ -1,4 +1,4 @@ -/* $FreeBSD: head/sys/net80211/ieee80211_amrr.h 178354 2008-04-20 20:35:46Z sam $ */ +/* $FreeBSD: head/sys/net80211/ieee80211_amrr.h 206358 2010-04-07 15:29:13Z rpaulo $ */ /* $OpenBSD: ieee80211_amrr.h,v 1.3 2006/06/17 19:34:31 damien Exp $ */ /*- @@ -58,44 +58,4 @@ struct ieee80211_amrr_node { u_int amn_retrycnt; }; -void ieee80211_amrr_init(struct ieee80211_amrr *, struct ieee80211vap *, - int, int, int); -void ieee80211_amrr_cleanup(struct ieee80211_amrr *); -void ieee80211_amrr_setinterval(struct ieee80211_amrr *, int); -void ieee80211_amrr_node_init(struct ieee80211_amrr *, - struct ieee80211_amrr_node *, struct ieee80211_node *); -int ieee80211_amrr_choose(struct ieee80211_node *, - struct ieee80211_amrr_node *); - -#define IEEE80211_AMRR_SUCCESS 1 -#define IEEE80211_AMRR_FAILURE 0 - -/* - * Update statistics with tx complete status. Ok is non-zero - * if the packet is known to be ACK'd. Retries has the number - * retransmissions (i.e. xmit attempts - 1). - */ -static __inline void -ieee80211_amrr_tx_complete(struct ieee80211_amrr_node *amn, - int ok, int retries) -{ - amn->amn_txcnt++; - if (ok) - amn->amn_success++; - amn->amn_retrycnt += retries; -} - -/* - * Set tx count/retry statistics explicitly. Intended for - * drivers that poll the device for statistics maintained - * in the device. - */ -static __inline void -ieee80211_amrr_tx_update(struct ieee80211_amrr_node *amn, - int txcnt, int success, int retrycnt) -{ - amn->amn_txcnt = txcnt; - amn->amn_success = success; - amn->amn_retrycnt = retrycnt; -} #endif /* _NET80211_IEEE80211_AMRR_H_ */ diff --git a/sys/netproto/802_11/ieee80211_dragonfly.h b/sys/netproto/802_11/ieee80211_dragonfly.h index a8f9fedacd..03a5eac4e7 100644 --- a/sys/netproto/802_11/ieee80211_dragonfly.h +++ b/sys/netproto/802_11/ieee80211_dragonfly.h @@ -392,14 +392,19 @@ TEXT_SET(auth_set, name##_modevent) /* * Rate control modules provide tx rate control support. */ -#define IEEE80211_RATE_MODULE(alg, version) \ -_IEEE80211_POLICY_MODULE(rate, alg, version); \ +#define IEEE80211_RATECTL_MODULE(alg, version) \ + _IEEE80211_POLICY_MODULE(ratectl, alg, version); \ + +#define IEEE80211_RATECTL_ALG(name, alg, v) \ static void \ alg##_modevent(int type) \ { \ - /* XXX nothing to do until the rate control framework arrives */\ + if (type == MOD_LOAD) \ + ieee80211_ratectl_register(alg, &v); \ + else \ + ieee80211_ratectl_unregister(alg); \ } \ -TEXT_SET(rate##_set, alg##_modevent) +TEXT_SET(ratectl##_set, alg##_modevent) struct ieee80211req; typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *, diff --git a/sys/netproto/802_11/ieee80211_node.h b/sys/netproto/802_11/ieee80211_node.h index 6e67b81068..aa0ba13e9a 100644 --- a/sys/netproto/802_11/ieee80211_node.h +++ b/sys/netproto/802_11/ieee80211_node.h @@ -23,14 +23,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: head/sys/net80211/ieee80211_node.h 195618 2009-07-11 15:02:45Z rpaulo $ + * $FreeBSD: head/sys/net80211/ieee80211_node.h 206358 2010-04-07 15:29:13Z rpaulo $ * $DragonFly$ */ #ifndef _NET80211_IEEE80211_NODE_H_ #define _NET80211_IEEE80211_NODE_H_ -#include /* for ieee80211_nodestats */ -#include /* for aggregation state */ +#include /* for ieee80211_nodestats */ +#include /* for aggregation state */ /* * Each ieee80211com instance has a single timer that fires every @@ -181,7 +181,6 @@ struct ieee80211_node { uint8_t ni_esslen; uint8_t ni_essid[IEEE80211_NWID_LEN]; struct ieee80211_rateset ni_rates; /* negotiated rate set */ - void *ni_rate_data; struct ieee80211_channel *ni_chan; uint16_t ni_fhdwell; /* FH only */ uint8_t ni_fhindex; /* FH only */ @@ -220,7 +219,8 @@ struct ieee80211_node { struct ieee80211_nodestats ni_stats; /* per-node statistics */ struct ieee80211vap *ni_wdsvap; /* associated WDS vap */ - uint64_t ni_spare[4]; + void *ni_rctls; /* private ratectl state */ + uint64_t ni_spare[3]; }; MALLOC_DECLARE(M_80211_NODE); MALLOC_DECLARE(M_80211_NODE_IE); diff --git a/sys/netproto/802_11/ieee80211_ratectl.h b/sys/netproto/802_11/ieee80211_ratectl.h index 3e72662f09..9ea8c31acf 100644 --- a/sys/netproto/802_11/ieee80211_ratectl.h +++ b/sys/netproto/802_11/ieee80211_ratectl.h @@ -1,142 +1,132 @@ -/* - * Copyright (c) 2006 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Sepherosa Ziehau - * +/*- + * Copyright (c) 2010 Rui Paulo + * All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/sys/netproto/802_11/ieee80211_ratectl.h,v 1.7 2008/01/15 09:01:13 sephe Exp $ + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: head/sys/net80211/ieee80211_ratectl.h 206367 2010-04-07 17:31:56Z rpaulo $ + * $DragonFly$ */ -#ifndef _NET80211_IEEE80211_RATECTL_H -#define _NET80211_IEEE80211_RATECTL_H - -#ifdef _KERNEL - -struct ieee80211_ratectl_stats; - -struct ieee80211_ratectl_state { - void *rc_st_ctx; - uint32_t rc_st_flags; /* see IEEE80211_RATECTL_F_ */ - u_int rc_st_ratectl; /* see IEEE80211_RATECTL_ */ - uint32_t rc_st_ratectl_cap; /* see IEEE80211_RATECTL_CAP_ */ - void *(*rc_st_attach)(struct ieee80211vap *, u_int); - void (*rc_st_stats)(struct ieee80211vap *, - struct ieee80211_node *, - struct ieee80211_ratectl_stats *); -}; - -#define IEEE80211_RATECTL_F_RSDESC 0x1 /* Rate set must be descendant. */ -#define IEEE80211_RATECTL_F_MRR 0x2 /* Support multi-rate-retry. */ - -struct ieee80211_ratectl_res { - int rc_res_rateidx; - int rc_res_tries; +enum ieee80211_ratealgs { + IEEE80211_RATECTL_AMRR = 0, + IEEE80211_RATECTL_RSSADAPT = 1, + IEEE80211_RATECTL_ONOE = 2, + IEEE80211_RATECTL_SAMPLE = 3, + IEEE80211_RATECTL_MAX }; -#define IEEE80211_RATEIDX_MAX 5 - -struct ieee80211_ratectl_stats { - int stats_pkt_noretry; - int stats_pkt_ok; - int stats_pkt_err; - int stats_retries; -}; +#define IEEE80211_RATECTL_TX_SUCCESS 0 +#define IEEE80211_RATECTL_TX_FAILURE 1 struct ieee80211_ratectl { - const char *rc_name; - u_int rc_ratectl; /* see IEEE80211_RATECTL_ */ - - void *(*rc_attach)(struct ieee80211vap *); - void (*rc_detach)(void *); - - void (*rc_data_alloc)(struct ieee80211_node *); - void (*rc_data_free)(struct ieee80211_node *); - void (*rc_data_dup)(const struct ieee80211_node *, - struct ieee80211_node *); - - void (*rc_newstate)(void *, enum ieee80211_state); - void (*rc_tx_complete)(void *, struct ieee80211_node *, int, - const struct ieee80211_ratectl_res[], - int, int, int, int); - void (*rc_newassoc)(void *, struct ieee80211_node *, int); - int (*rc_findrate)(void *, struct ieee80211_node *, int, - int[], int); + const char *ir_name; + int (*ir_attach)(const struct ieee80211vap *); + void (*ir_detach)(const struct ieee80211vap *); + void (*ir_init)(struct ieee80211vap *); + void (*ir_deinit)(struct ieee80211vap *); + void (*ir_node_init)(struct ieee80211_node *); + void (*ir_node_deinit)(struct ieee80211_node *); + int (*ir_rate)(struct ieee80211_node *, void *, uint32_t); + void (*ir_tx_complete)(const struct ieee80211vap *, + const struct ieee80211_node *, int, + void *, void *); + void (*ir_tx_update)(const struct ieee80211vap *, + const struct ieee80211_node *, + void *, void *, void *); + void (*ir_setinterval)(const struct ieee80211vap *, int); }; -#endif /* _KERNEL */ - -#define IEEE80211_RATECTL_NONE 0 -#define IEEE80211_RATECTL_ONOE 1 -#define IEEE80211_RATECTL_AMRR 2 -#define IEEE80211_RATECTL_SAMPLE 3 -#define IEEE80211_RATECTL_MAX 4 - -#ifdef _KERNEL - -#define IEEE80211_RATECTL_CAP(v) (1 << (v)) - -#define _IEEE80211_RATECTL_CAP(n) \ - IEEE80211_RATECTL_CAP(IEEE80211_RATECTL_##n) - -#define IEEE80211_RATECTL_CAP_NONE _IEEE80211_RATECTL_CAP(NONE) -#define IEEE80211_RATECTL_CAP_ONOE _IEEE80211_RATECTL_CAP(ONOE) -#define IEEE80211_RATECTL_CAP_AMRR _IEEE80211_RATECTL_CAP(AMRR) -#define IEEE80211_RATECTL_CAP_SAMPLE _IEEE80211_RATECTL_CAP(SAMPLE) - -#define IEEE80211_RS_RATE(rs, idx) \ - ((rs)->rs_rates[idx] & IEEE80211_RATE_VAL) - -extern const struct ieee80211_ratectl ieee80211_ratectl_none; - -void ieee80211_ratectl_attach(struct ieee80211vap *); -void ieee80211_ratectl_detach(struct ieee80211vap *); - -void ieee80211_ratectl_register(const struct ieee80211_ratectl *); -void ieee80211_ratectl_unregister(const struct ieee80211_ratectl *); - -int ieee80211_ratectl_change(struct ieee80211vap *, u_int); - -void ieee80211_ratectl_data_alloc(struct ieee80211_node *); -void ieee80211_ratectl_data_dup(const struct ieee80211_node *, - struct ieee80211_node *); -void ieee80211_ratectl_data_free(struct ieee80211_node *); - -void ieee80211_ratectl_newstate(struct ieee80211vap *, - enum ieee80211_state); -void ieee80211_ratectl_tx_complete(struct ieee80211_node *, int, - const struct ieee80211_ratectl_res[], - int, int, int, int); -void ieee80211_ratectl_newassoc(struct ieee80211_node *, int); -int ieee80211_ratectl_findrate(struct ieee80211_node *, int, int[], int); - -#endif /* _KERNEL */ - -#endif /* !_NET80211_IEEE80211_RATECTL_H */ - +void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *); +void ieee80211_ratectl_unregister(int); +void ieee80211_ratectl_set(struct ieee80211vap *, int); + +MALLOC_DECLARE(M_80211_RATECTL); + +static void __inline +ieee80211_ratectl_init(struct ieee80211vap *vap) +{ + vap->iv_rate->ir_init(vap); +} + +static void __inline +ieee80211_ratectl_deinit(struct ieee80211vap *vap) +{ + vap->iv_rate->ir_deinit(vap); +} + +static void __inline +ieee80211_ratectl_node_init(struct ieee80211_node *ni) +{ + const struct ieee80211vap *vap = ni->ni_vap; + + if (ni->ni_rctls == NULL) /* ratectl not setup */ + return; + vap->iv_rate->ir_node_init(ni); +} + +static void __inline +ieee80211_ratectl_node_deinit(struct ieee80211_node *ni) +{ + const struct ieee80211vap *vap = ni->ni_vap; + + if (ni->ni_rctls == NULL) /* ratectl not setup */ + return; + vap->iv_rate->ir_node_deinit(ni); +} + +static int __inline +ieee80211_ratectl_rate(struct ieee80211_node *ni, void *arg, uint32_t iarg) +{ + const struct ieee80211vap *vap = ni->ni_vap; + + if (ni->ni_rctls == NULL) /* ratectl not setup */ + return 0; + return vap->iv_rate->ir_rate(ni, arg, iarg); +} + +static void __inline +ieee80211_ratectl_tx_complete(const struct ieee80211vap *vap, + const struct ieee80211_node *ni, int status, void *arg1, void *arg2) +{ + if (ni->ni_rctls == NULL) /* ratectl not setup */ + return; + vap->iv_rate->ir_tx_complete(vap, ni, status, arg1, arg2); +} + +static void __inline +ieee80211_ratectl_tx_update(const struct ieee80211vap *vap, + const struct ieee80211_node *ni, void *arg1, void *arg2, void *arg3) +{ + if (vap->iv_rate->ir_tx_update == NULL) + return; + if (ni->ni_rctls == NULL) /* ratectl not setup */ + return; + vap->iv_rate->ir_tx_update(vap, ni, arg1, arg2, arg3); +} + +static void __inline +ieee80211_ratectl_setinterval(const struct ieee80211vap *vap, int msecs) +{ + if (vap->iv_rate->ir_setinterval == NULL) + return; + vap->iv_rate->ir_setinterval(vap, msecs); +} diff --git a/sys/netproto/802_11/ieee80211_rssadapt.h b/sys/netproto/802_11/ieee80211_rssadapt.h index 7424cd014f..44f6b50aac 100644 --- a/sys/netproto/802_11/ieee80211_rssadapt.h +++ b/sys/netproto/802_11/ieee80211_rssadapt.h @@ -1,5 +1,4 @@ -/* $DragonFly$ */ -/* $FreeBSD: head/sys/net80211/ieee80211_rssadapt.h 178354 2008-04-20 20:35:46Z sam $ */ +/* $FreeBSD: head/sys/net80211/ieee80211_rssadapt.h 206358 2010-04-07 15:29:13Z rpaulo $ */ /* $NetBSD: ieee80211_rssadapt.h,v 1.4 2005/02/26 22:45:09 perry Exp $ */ /*- * Copyright (c) 2003, 2004 David Young. All rights reserved. @@ -44,7 +43,7 @@ #define IEEE80211_RSSADAPT_BKTPOWER 3 /* 2**_BKTPOWER */ struct ieee80211_rssadapt { - struct ieee80211vap *vap; + const struct ieee80211vap *vap; int interval; /* update interval (ticks) */ }; @@ -67,36 +66,6 @@ struct ieee80211_rssadapt_node { [IEEE80211_RATE_SIZE]; }; -void ieee80211_rssadapt_init(struct ieee80211_rssadapt *, - struct ieee80211vap *, int); -void ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *); -void ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *, int); -void ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *, - struct ieee80211_rssadapt_node *, struct ieee80211_node *); -int ieee80211_rssadapt_choose(struct ieee80211_node *, - struct ieee80211_rssadapt_node *, u_int); - -/* NB: these are public only for the inline below */ -void ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *, - int pktlen, int rssi); -void ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *, - int pktlen, int rssi); - #define IEEE80211_RSSADAPT_SUCCESS 1 #define IEEE80211_RSSADAPT_FAILURE 0 - -static __inline void -ieee80211_rssadapt_tx_complete(struct ieee80211_rssadapt_node *ra, - int success, int pktlen, int rssi) -{ - if (success) { - ra->ra_nok++; - if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates && - (ticks - ra->ra_last_raise) >= ra->ra_raise_interval) - ieee80211_rssadapt_raise_rate(ra, pktlen, rssi); - } else { - ra->ra_nfail++; - ieee80211_rssadapt_lower_rate(ra, pktlen, rssi); - } -} #endif /* _NET80211_IEEE80211_RSSADAPT_H_ */ diff --git a/sys/netproto/802_11/ieee80211_var.h b/sys/netproto/802_11/ieee80211_var.h index b28843f127..c609cab62c 100644 --- a/sys/netproto/802_11/ieee80211_var.h +++ b/sys/netproto/802_11/ieee80211_var.h @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: head/sys/net80211/ieee80211_var.h 202612 2010-01-19 05:00:57Z thompsa $ + * $FreeBSD: head/sys/net80211/ieee80211_var.h 206358 2010-04-07 15:29:13Z rpaulo $ * $DragonFly$ */ #ifndef _NET80211_IEEE80211_VAR_H_ @@ -50,16 +50,13 @@ #include #include #include -#include /* for ieee80211_stats */ +#include /* for ieee80211_stats */ #include #include #include #include #include #include -#if defined(__DragonFly__) -#include -#endif #define IEEE80211_TXPOWER_MAX 100 /* .5 dbM (XXX units?) */ #define IEEE80211_TXPOWER_MIN 0 /* kill radio */ @@ -143,6 +140,7 @@ struct ieee80211com { uint32_t ic_flags_ven; /* vendor state flags */ uint32_t ic_caps; /* capabilities */ uint32_t ic_htcaps; /* HT capabilities */ + uint32_t ic_htextcaps; /* HT extended capabilities */ uint32_t ic_cryptocaps; /* crypto capabilities */ uint8_t ic_modecaps[2]; /* set of mode capabilities */ uint8_t ic_promisc; /* vap's needing promisc mode */ @@ -319,7 +317,8 @@ struct ieee80211com { int batimeout, int baseqctl); void (*ic_ampdu_rx_stop)(struct ieee80211_node *, struct ieee80211_rx_ampdu *); - uint64_t ic_spare[8]; + uint64_t ic_spare[7]; + uint32_t ic_spare2; }; struct ieee80211_aclator; @@ -346,6 +345,7 @@ struct ieee80211vap { uint32_t iv_flags_ven; /* vendor state flags */ uint32_t iv_caps; /* capabilities */ uint32_t iv_htcaps; /* HT capabilities */ + uint32_t iv_htextcaps; /* HT extended capabilities */ enum ieee80211_opmode iv_opmode; /* operation mode */ enum ieee80211_state iv_state; /* state machine state */ enum ieee80211_state iv_nstate; /* pending state */ @@ -439,6 +439,9 @@ struct ieee80211vap { const struct ieee80211_aclator *iv_acl; /* acl glue */ void *iv_as; /* private aclator state */ + const struct ieee80211_ratectl *iv_rate; + void *iv_rs; /* private ratectl state */ + struct ieee80211_tdma_state *iv_tdma; /* tdma state */ struct ieee80211_mesh_state *iv_mesh; /* MBSS state */ struct ieee80211_hwmp_state *iv_hwmp; /* HWMP state */ @@ -474,8 +477,7 @@ struct ieee80211vap { /* 802.3 output method for raw frame xmit */ int (*iv_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); - struct ieee80211_ratectl_state iv_ratectl; - uint64_t iv_spare[8]; + uint64_t iv_spare[6]; }; MALLOC_DECLARE(M_80211_VAP); @@ -856,10 +858,10 @@ ieee80211_htchanflags(const struct ieee80211_channel *c) if (ieee80211_msg(_vap, _m)) \ ieee80211_note_frame(_vap, _wh, _fmt, __VA_ARGS__); \ } while (0) -void ieee80211_note(struct ieee80211vap *, const char *, ...); -void ieee80211_note_mac(struct ieee80211vap *, +void ieee80211_note(const struct ieee80211vap *, const char *, ...); +void ieee80211_note_mac(const struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN], const char *, ...); -void ieee80211_note_frame(struct ieee80211vap *, +void ieee80211_note_frame(const struct ieee80211vap *, const struct ieee80211_frame *, const char *, ...); #define ieee80211_msg_debug(_vap) \ ((_vap)->iv_debug & IEEE80211_MSG_DEBUG) @@ -897,11 +899,11 @@ void ieee80211_note_frame(struct ieee80211vap *, ieee80211_discard_mac(_vap, _mac, _type, _fmt, __VA_ARGS__);\ } while (0) -void ieee80211_discard_frame(struct ieee80211vap *, +void ieee80211_discard_frame(const struct ieee80211vap *, const struct ieee80211_frame *, const char *type, const char *fmt, ...); -void ieee80211_discard_ie(struct ieee80211vap *, +void ieee80211_discard_ie(const struct ieee80211vap *, const struct ieee80211_frame *, const char *type, const char *fmt, ...); -void ieee80211_discard_mac(struct ieee80211vap *, +void ieee80211_discard_mac(const struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN], const char *type, const char *fmt, ...); #else diff --git a/sys/netproto/802_11/wlan/Makefile b/sys/netproto/802_11/wlan/Makefile index 04f4834d17..b6428f1d50 100644 --- a/sys/netproto/802_11/wlan/Makefile +++ b/sys/netproto/802_11/wlan/Makefile @@ -9,7 +9,7 @@ SRCS += ieee80211_ht.c ieee80211_hwmp.c ieee80211_input.c ieee80211_ioctl.c SRCS += ieee80211_mesh.c ieee80211_monitor.c ieee80211_node.c SRCS += ieee80211_output.c ieee80211_phy.c ieee80211_power.c SRCS += ieee80211_proto.c ieee80211_radiotap.c -SRCS += ieee80211_ratectl.c ieee80211_ratectl_none.c +SRCS += ieee80211_ratectl.c SRCS += ieee80211_regdomain.c ieee80211_rssadapt.c SRCS += ieee80211_scan.c ieee80211_scan_sta.c ieee80211_sta.c SRCS += ieee80211_superg.c ieee80211_tdma.c ieee80211_wds.c diff --git a/sys/netproto/802_11/wlan/ieee80211.c b/sys/netproto/802_11/wlan/ieee80211.c index 97f9c2bfdc..e98f5b9972 100644 --- a/sys/netproto/802_11/wlan/ieee80211.c +++ b/sys/netproto/802_11/wlan/ieee80211.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: head/sys/net80211/ieee80211.c 202612 2010-01-19 05:00:57Z thompsa $ + * $FreeBSD: head/sys/net80211/ieee80211.c 206358 2010-04-07 15:29:13Z rpaulo $ * $DragonFly$ */ @@ -51,6 +51,7 @@ #ifdef IEEE80211_SUPPORT_SUPERG #include #endif +#include #include @@ -485,6 +486,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, ieee80211_scan_vattach(vap); ieee80211_regdomain_vattach(vap); ieee80211_radiotap_vattach(vap); + ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR); return 0; } diff --git a/sys/netproto/802_11/wlan/ieee80211_amrr.c b/sys/netproto/802_11/wlan/ieee80211_amrr.c index 94ade514d2..2f4283a638 100644 --- a/sys/netproto/802_11/wlan/ieee80211_amrr.c +++ b/sys/netproto/802_11/wlan/ieee80211_amrr.c @@ -1,6 +1,7 @@ /* $OpenBSD: ieee80211_amrr.c,v 1.1 2006/06/17 19:07:19 damien Exp $ */ /*- + * Copyright (c) 2010 Rui Paulo * Copyright (c) 2006 * Damien Bergamini * @@ -16,10 +17,11 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $FreeBSD: head/sys/net80211/ieee80211_amrr.c 178354 2008-04-20 20:35:46Z sam $ + * $FreeBSD: head/sys/net80211/ieee80211_amrr.c 206358 2010-04-07 15:29:13Z rpaulo $ * $DragonFly$ */ + /*- * Naive implementation of the Adaptive Multi Rate Retry algorithm: * @@ -46,6 +48,7 @@ #include #include +#include #define is_success(amn) \ ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10) @@ -54,15 +57,45 @@ #define is_enough(amn) \ ((amn)->amn_txcnt > 10) -static void amrr_sysctlattach(struct ieee80211_amrr *amrr, - struct sysctl_ctx_list *ctx, struct sysctl_oid *tree); +static void amrr_setinterval(const struct ieee80211vap *, int); +static void amrr_init(struct ieee80211vap *); +static void amrr_deinit(struct ieee80211vap *); +static void amrr_node_init(struct ieee80211_node *); +static void amrr_node_deinit(struct ieee80211_node *); +static int amrr_update(struct ieee80211_amrr *, + struct ieee80211_amrr_node *, struct ieee80211_node *); +static int amrr_rate(struct ieee80211_node *, void *, uint32_t); +static void amrr_tx_complete(const struct ieee80211vap *, + const struct ieee80211_node *, int, + void *, void *); +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 *); /* number of references from net80211 layer */ static int nrefs = 0; -void -ieee80211_amrr_setinterval(struct ieee80211_amrr *amrr, int msecs) +static const struct ieee80211_ratectl amrr = { + .ir_name = "amrr", + .ir_attach = NULL, + .ir_detach = NULL, + .ir_init = amrr_init, + .ir_deinit = amrr_deinit, + .ir_node_init = amrr_node_init, + .ir_node_deinit = amrr_node_deinit, + .ir_rate = amrr_rate, + .ir_tx_complete = amrr_tx_complete, + .ir_tx_update = amrr_tx_update, + .ir_setinterval = amrr_setinterval, +}; +IEEE80211_RATECTL_MODULE(amrr, 1); +IEEE80211_RATECTL_ALG(amrr, IEEE80211_RATECTL_AMRR, amrr); + +static void +amrr_setinterval(const struct ieee80211vap *vap, int msecs) { + struct ieee80211_amrr *amrr = vap->iv_rs; int t; if (msecs < 100) @@ -71,29 +104,42 @@ ieee80211_amrr_setinterval(struct ieee80211_amrr *amrr, int msecs) amrr->amrr_interval = (t < 1) ? 1 : t; } -void -ieee80211_amrr_init(struct ieee80211_amrr *amrr, - struct ieee80211vap *vap, int amin, int amax, int interval) +static void +amrr_init(struct ieee80211vap *vap) { - /* XXX bounds check? */ - amrr->amrr_min_success_threshold = amin; - amrr->amrr_max_success_threshold = amax; - ieee80211_amrr_setinterval(amrr, interval); + struct ieee80211_amrr *amrr; - amrr_sysctlattach(amrr, vap->iv_sysctl, vap->iv_oid); + KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__)); + + vap->iv_rs = kmalloc(sizeof(struct ieee80211_amrr), M_80211_RATECTL, + M_WAITOK|M_ZERO); + amrr = vap->iv_rs; + amrr->amrr_min_success_threshold = IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD; + amrr->amrr_max_success_threshold = IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD; + amrr_setinterval(vap, 500 /* ms */); + amrr_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid); } -void -ieee80211_amrr_cleanup(struct ieee80211_amrr *amrr) +static void +amrr_deinit(struct ieee80211vap *vap) { + kfree(vap->iv_rs, M_80211_RATECTL); } -void -ieee80211_amrr_node_init(struct ieee80211_amrr *amrr, - struct ieee80211_amrr_node *amn, struct ieee80211_node *ni) +static void +amrr_node_init(struct ieee80211_node *ni) { const struct ieee80211_rateset *rs = &ni->ni_rates; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211_amrr *amrr = vap->iv_rs; + struct ieee80211_amrr_node *amn; + + KASSERT(ni->ni_rctls == NULL, ("%s: ni_rctls already initialized", + __func__)); + ni->ni_rctls = kmalloc(sizeof(struct ieee80211_amrr_node), + M_80211_RATECTL, M_WAITOK|M_ZERO); + amn = ni->ni_rctls; amn->amn_amrr = amrr; amn->amn_success = 0; amn->amn_recovery = 0; @@ -112,6 +158,12 @@ ieee80211_amrr_node_init(struct ieee80211_amrr *amrr, "AMRR initial rate %d", ni->ni_txrate); } +static void +amrr_node_deinit(struct ieee80211_node *ni) +{ + kfree(ni->ni_rctls, M_80211_RATECTL); +} + static int amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn, struct ieee80211_node *ni) @@ -168,10 +220,10 @@ amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn, * Update our internal state if it's been long enough. * If the rate changes we also update ni_txrate to match. */ -int -ieee80211_amrr_choose(struct ieee80211_node *ni, - struct ieee80211_amrr_node *amn) +static int +amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused) { + struct ieee80211_amrr_node *amn = ni->ni_rctls; struct ieee80211_amrr *amrr = amn->amn_amrr; int rix; @@ -189,27 +241,65 @@ ieee80211_amrr_choose(struct ieee80211_node *ni, return rix; } +/* + * Update statistics with tx complete status. Ok is non-zero + * if the packet is known to be ACK'd. Retries has the number + * retransmissions (i.e. xmit attempts - 1). + */ +static void +amrr_tx_complete(const struct ieee80211vap *vap, + const struct ieee80211_node *ni, int ok, + void *arg1, void *arg2 __unused) +{ + struct ieee80211_amrr_node *amn = ni->ni_rctls; + int retries = *(int *)arg1; + + amn->amn_txcnt++; + if (ok) + amn->amn_success++; + amn->amn_retrycnt += retries; +} + +/* + * Set tx count/retry statistics explicitly. Intended for + * drivers that poll the device for statistics maintained + * in the device. + */ +static void +amrr_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni, + void *arg1, void *arg2, void *arg3) +{ + struct ieee80211_amrr_node *amn = ni->ni_rctls; + int txcnt = *(int *)arg1, success = *(int *)arg2, retrycnt = *(int *)arg3; + + amn->amn_txcnt = txcnt; + amn->amn_success = success; + amn->amn_retrycnt = retrycnt; +} + static int amrr_sysctl_interval(SYSCTL_HANDLER_ARGS) { - struct ieee80211_amrr *amrr = arg1; + struct ieee80211vap *vap = arg1; + struct ieee80211_amrr *amrr = vap->iv_rs; int msecs = ticks_to_msecs(amrr->amrr_interval); int error; error = sysctl_handle_int(oidp, &msecs, 0, req); if (error || !req->newptr) return error; - ieee80211_amrr_setinterval(amrr, msecs); + amrr_setinterval(vap, msecs); return 0; } static void -amrr_sysctlattach(struct ieee80211_amrr *amrr, +amrr_sysctlattach(struct ieee80211vap *vap, struct sysctl_ctx_list *ctx, struct sysctl_oid *tree) { + struct ieee80211_amrr *amrr = vap->iv_rs; SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, amrr, + "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap, 0, amrr_sysctl_interval, "I", "amrr operation interval (ms)"); /* XXX bounds check values */ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, @@ -219,8 +309,3 @@ amrr_sysctlattach(struct ieee80211_amrr *amrr, "amrr_min_sucess_threshold", CTLFLAG_RW, &amrr->amrr_min_success_threshold, 0, ""); } - -/* - * Module glue. - */ -IEEE80211_RATE_MODULE(amrr, 1); diff --git a/sys/netproto/802_11/wlan/ieee80211_input.c b/sys/netproto/802_11/wlan/ieee80211_input.c index cd1f897583..1043159a75 100644 --- a/sys/netproto/802_11/wlan/ieee80211_input.c +++ b/sys/netproto/802_11/wlan/ieee80211_input.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: head/sys/net80211/ieee80211_input.c 196316 2009-08-17 12:57:57Z rpaulo $ + * $FreeBSD: head/sys/net80211/ieee80211_input.c 205986 2010-03-31 16:07:36Z rpaulo $ * $DragonFly$ */ @@ -734,7 +734,7 @@ ieee80211_ssid_mismatch(struct ieee80211vap *vap, const char *tag, * Return the bssid of a frame. */ static const uint8_t * -ieee80211_getbssid(struct ieee80211vap *vap, const struct ieee80211_frame *wh) +ieee80211_getbssid(const struct ieee80211vap *vap, const struct ieee80211_frame *wh) { if (vap->iv_opmode == IEEE80211_M_STA) return wh->i_addr2; @@ -748,7 +748,7 @@ ieee80211_getbssid(struct ieee80211vap *vap, const struct ieee80211_frame *wh) #include void -ieee80211_note(struct ieee80211vap *vap, const char *fmt, ...) +ieee80211_note(const struct ieee80211vap *vap, const char *fmt, ...) { char buf[128]; /* XXX */ __va_list ap; @@ -761,7 +761,7 @@ ieee80211_note(struct ieee80211vap *vap, const char *fmt, ...) } void -ieee80211_note_frame(struct ieee80211vap *vap, +ieee80211_note_frame(const struct ieee80211vap *vap, const struct ieee80211_frame *wh, const char *fmt, ...) { @@ -776,7 +776,7 @@ ieee80211_note_frame(struct ieee80211vap *vap, } void -ieee80211_note_mac(struct ieee80211vap *vap, +ieee80211_note_mac(const struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], const char *fmt, ...) { @@ -790,7 +790,7 @@ ieee80211_note_mac(struct ieee80211vap *vap, } void -ieee80211_discard_frame(struct ieee80211vap *vap, +ieee80211_discard_frame(const struct ieee80211vap *vap, const struct ieee80211_frame *wh, const char *type, const char *fmt, ...) { @@ -811,7 +811,7 @@ ieee80211_discard_frame(struct ieee80211vap *vap, } void -ieee80211_discard_ie(struct ieee80211vap *vap, +ieee80211_discard_ie(const struct ieee80211vap *vap, const struct ieee80211_frame *wh, const char *type, const char *fmt, ...) { @@ -830,7 +830,7 @@ ieee80211_discard_ie(struct ieee80211vap *vap, } void -ieee80211_discard_mac(struct ieee80211vap *vap, +ieee80211_discard_mac(const struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], const char *type, const char *fmt, ...) { diff --git a/sys/netproto/802_11/wlan/ieee80211_node.c b/sys/netproto/802_11/wlan/ieee80211_node.c index 792c6e42f0..2058d882b3 100644 --- a/sys/netproto/802_11/wlan/ieee80211_node.c +++ b/sys/netproto/802_11/wlan/ieee80211_node.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: head/sys/net80211/ieee80211_node.c 201758 2010-01-07 21:01:37Z mbr $ + * $FreeBSD: head/sys/net80211/ieee80211_node.c 206358 2010-04-07 15:29:13Z rpaulo $ * $DragonFly$ */ @@ -52,6 +52,7 @@ #endif #include #include +#include #include @@ -1036,6 +1037,7 @@ node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; + ieee80211_ratectl_node_deinit(ni); ic->ic_node_cleanup(ni); ieee80211_ies_cleanup(&ni->ni_ies); ieee80211_psq_cleanup(&ni->ni_psq); diff --git a/sys/netproto/802_11/wlan/ieee80211_ratectl.c b/sys/netproto/802_11/wlan/ieee80211_ratectl.c index 66f7f83e96..e1e829b6f7 100644 --- a/sys/netproto/802_11/wlan/ieee80211_ratectl.c +++ b/sys/netproto/802_11/wlan/ieee80211_ratectl.c @@ -1,243 +1,66 @@ -/* - * Copyright (c) 2006 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Sepherosa Ziehau - * +/*- + * Copyright (c) 2010 Rui Paulo + * All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ratectl.c,v 1.5 2008/01/15 09:01:13 sephe Exp $ + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: head/sys/net80211/ieee80211_ratectl.c 206358 2010-04-07 15:29:13Z rpaulo $ + * $DragonFly$ */ #include #include - +#include +#include + #include #include -#include -#include #include +#include -static const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX] = { - [IEEE80211_RATECTL_NONE] = &ieee80211_ratectl_none -}; - -static const char *ratectl_modname[IEEE80211_RATECTL_MAX] = { - [IEEE80211_RATECTL_ONOE] = "wlan_ratectl_onoe", - [IEEE80211_RATECTL_AMRR] = "wlan_ratectl_amrr", - [IEEE80211_RATECTL_SAMPLE] = "wlan_ratectl_sample" -}; - -void -ieee80211_ratectl_attach(struct ieee80211vap *vap) -{ - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - u_int cur_ratectl = rc_st->rc_st_ratectl; - - rc_st->rc_st_ratectl_cap |= IEEE80211_RATECTL_CAP_NONE; - rc_st->rc_st_ratectl = IEEE80211_RATECTL_NONE; +static const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX]; - ieee80211_ratectl_change(vap, cur_ratectl); -} +MALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control"); void -ieee80211_ratectl_detach(struct ieee80211vap *vap) +ieee80211_ratectl_register(int type, const struct ieee80211_ratectl *ratectl) { - ieee80211_ratectl_change(vap, IEEE80211_RATECTL_NONE); -} - -void -ieee80211_ratectl_register(const struct ieee80211_ratectl *rc) -{ - /* - * Sanity checks - */ - if (rc->rc_ratectl >= IEEE80211_RATECTL_MAX) { - kprintf("%s: rate control %s has an invalid index %d\n", - __func__, rc->rc_name, rc->rc_ratectl); - return; - } - if (ratectls[rc->rc_ratectl] != NULL && - ratectls[rc->rc_ratectl] != rc) { - kprintf("%s: rate control index %d is registered by %s\n", - __func__, rc->rc_ratectl, - ratectls[rc->rc_ratectl]->rc_name); + if (type >= IEEE80211_RATECTL_MAX) return; - } - - ratectls[rc->rc_ratectl] = rc; + ratectls[type] = ratectl; } void -ieee80211_ratectl_unregister(const struct ieee80211_ratectl *rc) +ieee80211_ratectl_unregister(int type) { - /* - * Sanity checks - */ - if (rc->rc_ratectl >= IEEE80211_RATECTL_MAX) { - kprintf("%s: rate control %s has an invalid index %d\n", - __func__, rc->rc_name, rc->rc_ratectl); - return; - } - if (ratectls[rc->rc_ratectl] != NULL && - ratectls[rc->rc_ratectl] != rc) { - kprintf("%s: rate control index %d is registered by %s\n", - __func__, rc->rc_ratectl, - ratectls[rc->rc_ratectl]->rc_name); + if (type >= IEEE80211_RATECTL_MAX) return; - } - - /* - * Indiviual rate control module MUST maintain reference count itself. - */ - ratectls[rc->rc_ratectl] = NULL; -} - -int -ieee80211_ratectl_change(struct ieee80211vap *vap, u_int rc_idx) -{ - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc, *rc_old; - - if (rc_idx == rc_st->rc_st_ratectl) { - /* Nothing need to be changed */ - return 0; - } - - if ((IEEE80211_RATECTL_CAP(rc_idx) & rc_st->rc_st_ratectl_cap) == 0) { - /* We are not capable to do requested rate control */ - return EOPNOTSUPP; - } - - rc = ratectls[rc_idx]; - if (rc == NULL) { - /* Try load the rate control module */ - ieee80211_load_module(ratectl_modname[rc_idx]); - - /* - * If rate control module loaded it should immediately - * call ieee80211_ratectl_register() which will fill in - * the entry in the 'ratectls' array. - */ - rc = ratectls[rc_idx]; - if (rc == NULL) { - kprintf("%s: can't load requested rate control module", - __func__); - return EOPNOTSUPP; - } - } - - /* Detach old rate control */ - rc_old = ratectls[rc_st->rc_st_ratectl]; - rc_old->rc_detach(rc_st->rc_st_ctx); - - /* Attach new rate control */ - rc_st->rc_st_ratectl = rc_idx; - rc_st->rc_st_ctx = rc->rc_attach(vap); - - return 0; + ratectls[type] = NULL; } void -ieee80211_ratectl_data_alloc(struct ieee80211_node *ni) +ieee80211_ratectl_set(struct ieee80211vap *vap, int type) { - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl]; - - rc->rc_data_alloc(ni); -} - -void -ieee80211_ratectl_data_dup(const struct ieee80211_node *oni, - struct ieee80211_node *nni) -{ - struct ieee80211vap *vap = oni->ni_vap; - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl]; - - rc->rc_data_dup(oni, nni); -} - -void -ieee80211_ratectl_data_free(struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl]; - - rc->rc_data_free(ni); -} - -void -ieee80211_ratectl_newstate(struct ieee80211vap *vap, enum ieee80211_state state) -{ - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl]; - - rc->rc_newstate(rc_st->rc_st_ctx, state); -} - -void -ieee80211_ratectl_tx_complete(struct ieee80211_node *ni, int frame_len, - const struct ieee80211_ratectl_res res[], - int res_len, int data_retries, int rts_retries, - int is_fail) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl]; - - rc->rc_tx_complete(rc_st->rc_st_ctx, ni, frame_len, res, res_len, - data_retries, rts_retries, is_fail); -} - -void -ieee80211_ratectl_newassoc(struct ieee80211_node *ni, int is_new) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl]; - - rc->rc_newassoc(rc_st->rc_st_ctx, ni, is_new); -} - -int -ieee80211_ratectl_findrate(struct ieee80211_node *ni, int frame_len, - int rateidx[], int rateidx_len) -{ - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - const struct ieee80211_ratectl *rc = ratectls[rc_st->rc_st_ratectl]; - - KKASSERT(rateidx_len > 0); - - return rc->rc_findrate(rc_st->rc_st_ctx, ni, frame_len, - rateidx, rateidx_len); + if (type >= IEEE80211_RATECTL_MAX) + return; + vap->iv_rate = ratectls[type]; } diff --git a/sys/netproto/802_11/wlan/ieee80211_rssadapt.c b/sys/netproto/802_11/wlan/ieee80211_rssadapt.c index 45a264beda..74dcc49f81 100644 --- a/sys/netproto/802_11/wlan/ieee80211_rssadapt.c +++ b/sys/netproto/802_11/wlan/ieee80211_rssadapt.c @@ -1,7 +1,7 @@ -/* $DragonFly$ */ -/* $FreeBSD: head/sys/net80211/ieee80211_rssadapt.c 178354 2008-04-20 20:35:46Z sam $ */ +/* $FreeBSD: head/sys/net80211/ieee80211_rssadapt.c 206358 2010-04-07 15:29:13Z rpaulo $ */ /* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */ /*- + * Copyright (c) 2010 Rui Paulo * Copyright (c) 2003, 2004 David Young. All rights reserved. * * Redistribution and use in source and binary forms, with or @@ -40,10 +40,10 @@ #include #include -#include #include #include +#include struct rssadapt_expavgctl { /* RSS threshold decay. */ @@ -73,15 +73,45 @@ static struct rssadapt_expavgctl master_expavgctl = { (parm##_denom - parm##_old) * (new)) / \ parm##_denom) -static void rssadapt_sysctlattach(struct ieee80211_rssadapt *rs, - struct sysctl_ctx_list *ctx, struct sysctl_oid *tree); +static void rssadapt_setinterval(const struct ieee80211vap *, int); +static void rssadapt_init(struct ieee80211vap *); +static void rssadapt_deinit(struct ieee80211vap *); +static void rssadapt_updatestats(struct ieee80211_rssadapt_node *); +static void rssadapt_node_init(struct ieee80211_node *); +static void rssadapt_node_deinit(struct ieee80211_node *); +static int rssadapt_rate(struct ieee80211_node *, void *, uint32_t); +static void rssadapt_lower_rate(struct ieee80211_rssadapt_node *, int, int); +static void rssadapt_raise_rate(struct ieee80211_rssadapt_node *, + int, int); +static void rssadapt_tx_complete(const struct ieee80211vap *, + const struct ieee80211_node *, int, + void *, void *); +static void rssadapt_sysctlattach(struct ieee80211vap *, + struct sysctl_ctx_list *, struct sysctl_oid *); /* number of references from net80211 layer */ static int nrefs = 0; -void -ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *rs, int msecs) +static const struct ieee80211_ratectl rssadapt = { + .ir_name = "rssadapt", + .ir_attach = NULL, + .ir_detach = NULL, + .ir_init = rssadapt_init, + .ir_deinit = rssadapt_deinit, + .ir_node_init = rssadapt_node_init, + .ir_node_deinit = rssadapt_node_deinit, + .ir_rate = rssadapt_rate, + .ir_tx_complete = rssadapt_tx_complete, + .ir_tx_update = NULL, + .ir_setinterval = rssadapt_setinterval, +}; +IEEE80211_RATECTL_MODULE(rssadapt, 1); +IEEE80211_RATECTL_ALG(rssadapt, IEEE80211_RATECTL_RSSADAPT, rssadapt); + +static void +rssadapt_setinterval(const struct ieee80211vap *vap, int msecs) { + struct ieee80211_rssadapt *rs = vap->iv_rs; int t; if (msecs < 100) @@ -90,18 +120,26 @@ ieee80211_rssadapt_setinterval(struct ieee80211_rssadapt *rs, int msecs) rs->interval = (t < 1) ? 1 : t; } -void -ieee80211_rssadapt_init(struct ieee80211_rssadapt *rs, struct ieee80211vap *vap, int interval) +static void +rssadapt_init(struct ieee80211vap *vap) { + struct ieee80211_rssadapt *rs; + + KASSERT(vap->iv_rs == NULL, ("%s: iv_rs already initialized", + __func__)); + + rs = kmalloc(sizeof(struct ieee80211_rssadapt), M_80211_RATECTL, + M_WAITOK|M_ZERO); + vap->iv_rs = rs; rs->vap = vap; - ieee80211_rssadapt_setinterval(rs, interval); - - rssadapt_sysctlattach(rs, vap->iv_sysctl, vap->iv_oid); + rssadapt_setinterval(vap, 500 /* msecs */); + rssadapt_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid); } -void -ieee80211_rssadapt_cleanup(struct ieee80211_rssadapt *rs) +static void +rssadapt_deinit(struct ieee80211vap *vap) { + kfree(vap->iv_rs, M_80211_RATECTL); } static void @@ -120,12 +158,16 @@ rssadapt_updatestats(struct ieee80211_rssadapt_node *ra) ra->ra_raise_interval = msecs_to_ticks(interval); } -void -ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rsa, - struct ieee80211_rssadapt_node *ra, struct ieee80211_node *ni) +static void +rssadapt_node_init(struct ieee80211_node *ni) { + struct ieee80211_rssadapt_node *ra; + struct ieee80211_rssadapt *rsa = ni->ni_vap->iv_rs; const struct ieee80211_rateset *rs = &ni->ni_rates; + ra = kmalloc(sizeof(struct ieee80211_rssadapt_node), M_80211_RATECTL, + M_WAITOK|M_ZERO); + ni->ni_rctls = ra; ra->ra_rs = rsa; ra->ra_rates = *rs; rssadapt_updatestats(ra); @@ -142,6 +184,13 @@ ieee80211_rssadapt_node_init(struct ieee80211_rssadapt *rsa, "RSSADAPT initial rate %d", ni->ni_txrate); } +static void +rssadapt_node_deinit(struct ieee80211_node *ni) +{ + + kfree(ni->ni_rctls, M_80211_RATECTL); +} + static __inline int bucket(int pktlen) { @@ -157,10 +206,11 @@ bucket(int pktlen) return thridx; } -int -ieee80211_rssadapt_choose(struct ieee80211_node *ni, - struct ieee80211_rssadapt_node *ra, u_int pktlen) +static int +rssadapt_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg) { + struct ieee80211_rssadapt_node *ra = ni->ni_rctls; + u_int pktlen = iarg; const struct ieee80211_rateset *rs = &ra->ra_rates; uint16_t (*thrs)[IEEE80211_RATE_SIZE]; int rix, rssi; @@ -195,9 +245,8 @@ ieee80211_rssadapt_choose(struct ieee80211_node *ni, * raise the RSS threshold for transmitting packets of similar length at * the same data rate. */ -void -ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, - int pktlen, int rssi) +static void +rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) { uint16_t last_thr; uint16_t (*thrs)[IEEE80211_RATE_SIZE]; @@ -216,9 +265,8 @@ ieee80211_rssadapt_lower_rate(struct ieee80211_rssadapt_node *ra, last_thr, (*thrs)[rix], rssi); } -void -ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, - int pktlen, int rssi) +static void +rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, int pktlen, int rssi) { uint16_t (*thrs)[IEEE80211_RATE_SIZE]; uint16_t newthr, oldthr; @@ -245,31 +293,45 @@ ieee80211_rssadapt_raise_rate(struct ieee80211_rssadapt_node *ra, } } +static void +rssadapt_tx_complete(const struct ieee80211vap *vap, + const struct ieee80211_node *ni, int success, void *arg1, void *arg2) +{ + struct ieee80211_rssadapt_node *ra = ni->ni_rctls; + int pktlen = *(int *)arg1, rssi = *(int *)arg2; + + if (success) { + ra->ra_nok++; + if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates && + (ticks - ra->ra_last_raise) >= ra->ra_raise_interval) + rssadapt_raise_rate(ra, pktlen, rssi); + } else { + ra->ra_nfail++; + rssadapt_lower_rate(ra, pktlen, rssi); + } +} + static int rssadapt_sysctl_interval(SYSCTL_HANDLER_ARGS) { - struct ieee80211_rssadapt *rs = arg1; + struct ieee80211vap *vap = arg1; + struct ieee80211_rssadapt *rs = vap->iv_rs; int msecs = ticks_to_msecs(rs->interval); int error; error = sysctl_handle_int(oidp, &msecs, 0, req); if (error || !req->newptr) return error; - ieee80211_rssadapt_setinterval(rs, msecs); + rssadapt_setinterval(vap, msecs); return 0; } static void -rssadapt_sysctlattach(struct ieee80211_rssadapt *rs, +rssadapt_sysctlattach(struct ieee80211vap *vap, struct sysctl_ctx_list *ctx, struct sysctl_oid *tree) { SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, rs, + "rssadapt_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap, 0, rssadapt_sysctl_interval, "I", "rssadapt operation interval (ms)"); } - -/* - * Module glue. - */ -IEEE80211_RATE_MODULE(rssadapt, 1); diff --git a/sys/netproto/802_11/wlan_ratectl/Makefile b/sys/netproto/802_11/wlan_ratectl/Makefile deleted file mode 100644 index 5637a653cf..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $DragonFly: src/sys/netproto/802_11/wlan_ratectl/Makefile,v 1.2 2007/04/01 13:59:41 sephe Exp $ - -SUBDIR= onoe amrr sample - -.include diff --git a/sys/netproto/802_11/wlan_ratectl/amrr/Makefile b/sys/netproto/802_11/wlan_ratectl/amrr/Makefile deleted file mode 100644 index 4f8fc51598..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/amrr/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $DragonFly: src/sys/netproto/802_11/wlan_ratectl/amrr/Makefile,v 1.1 2006/09/01 15:12:12 sephe Exp $ - -KMOD = wlan_ratectl_amrr -SRCS = ieee80211_ratectl_amrr.c - -.include diff --git a/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_amrr_param.h b/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_amrr_param.h deleted file mode 100644 index acadee5567..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_amrr_param.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2004 INRIA - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD: src/sys/dev/ath/ath_rate/amrr/amrr.h,v 1.2 2004/12/31 22:41:45 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_amrr_param.h,v 1.2 2008/01/15 09:01:13 sephe Exp $ - */ - -#ifndef _IEEE80211_AMRR_PARAM_H -#define _IEEE80211_AMRR_PARAM_H - -struct ieee80211_amrr_param { - int amrr_interval; /* unit: millisecond */ - int amrr_max_success_threshold; - int amrr_min_success_threshold; - int amrr_debug; -}; - -#define IEEE80211_AMRR_INTERVAL 1000 /* 1 second */ -#define IEEE80211_AMRR_MAX_SUCCESS_THR 10 -#define IEEE80211_AMRR_MIN_SUCCESS_THR 1 - -#define IEEE80211_AMRR_PARAM_SETUP(param) \ -do { \ - (param)->amrr_interval = \ - IEEE80211_AMRR_INTERVAL; \ - (param)->amrr_max_success_threshold = \ - IEEE80211_AMRR_MAX_SUCCESS_THR; \ - (param)->amrr_min_success_threshold = \ - IEEE80211_AMRR_MIN_SUCCESS_THR; \ - (param)->amrr_debug = 0; \ -} while (0) - -#endif /* !_IEEE80211_AMRR_PARAM_H */ diff --git a/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c b/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c deleted file mode 100644 index 5f53eb22bd..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * Copyright (c) 2004 INRIA - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD: src/sys/dev/ath/ath_rate/amrr/amrr.c,v 1.8.2.3 2006/02/24 19:51:11 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/amrr/ieee80211_ratectl_amrr.c,v 1.11 2008/01/15 09:01:13 sephe Exp $ - */ - -/* - * AMRR rate control. See: - * http://www-sop.inria.fr/rapports/sophia/RR-5208.html - * "IEEE 802.11 Rate Adaptation: A Practical Approach" by - * Mathieu Lacage, Hossein Manshaei, Thierry Turletti - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#define AMRR_DEBUG -#ifdef AMRR_DEBUG -#define DPRINTF(asc, lv, fmt, ...) do { \ - if ((asc)->param->amrr_debug >= lv) \ - kprintf(fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(asc, lv, fmt, ...) -#endif - -struct amrr_softc { - struct ieee80211vap *vap; - struct callout timer; /* periodic timer */ - struct sysctl_ctx_list sysctl_ctx; - struct sysctl_oid *sysctl_oid; - - struct ieee80211_amrr_param *param; -#define max_success_threshold param->amrr_max_success_threshold -#define min_success_threshold param->amrr_min_success_threshold -}; - -struct amrr_data { - /* AMRR statistics for this node */ - u_int ad_tx_cnt; - u_int ad_tx_failure_cnt; - - /* AMRR algorithm state for this node */ - u_int ad_success_threshold; - u_int ad_success; - u_int ad_recovery; -}; - -static void *amrr_attach(struct ieee80211vap *); -static void amrr_detach(void *); -static void amrr_data_alloc(struct ieee80211_node *); -static void amrr_data_free(struct ieee80211_node *); -static void amrr_data_dup(const struct ieee80211_node *, - struct ieee80211_node *); -static void amrr_newstate(void *, enum ieee80211_state); -static void amrr_tx_complete(void *, struct ieee80211_node *, int, - const struct ieee80211_ratectl_res[], - int, int, int, int); -static void amrr_newassoc(void *, struct ieee80211_node *, int); -static int amrr_findrate(void *, struct ieee80211_node *, int, - int[], int); - -static void amrr_sysctl_attach(struct amrr_softc *); -static void amrr_update(struct amrr_softc *, struct ieee80211_node *, int); -static void amrr_start(struct amrr_softc *, struct ieee80211_node *); -static void amrr_tick(void *); -static void amrr_ratectl(void *, struct ieee80211_node *); -static void amrr_gather_stats(struct amrr_softc *, struct ieee80211_node *); - -static const struct ieee80211_ratectl amrr = { - .rc_name = "amrr", - .rc_ratectl = IEEE80211_RATECTL_AMRR, - .rc_attach = amrr_attach, - .rc_detach = amrr_detach, - .rc_data_alloc = amrr_data_alloc, - .rc_data_free = amrr_data_free, - .rc_data_dup = amrr_data_dup, - .rc_newstate = amrr_newstate, - .rc_tx_complete = amrr_tx_complete, - .rc_newassoc = amrr_newassoc, - .rc_findrate = amrr_findrate -}; - -static u_int amrr_nrefs; - -MALLOC_DEFINE(M_AMRR_RATECTL_DATA, "amrr_ratectl_data", - "amrr rate control data"); - -static int -amrr_findrate(void *arg, struct ieee80211_node *ni, - int frame_len __unused, int rateidx[], int rateidx_len) -{ - struct amrr_softc *asc = arg; - int i, rate_idx; - - if (ni->ni_txrate >= ni->ni_rates.rs_nrates) { - DPRINTF(asc, 5, "%s: number of rates changed, restart\n", - __func__); - amrr_start(asc, ni); - } - rate_idx = ni->ni_txrate; - - for (i = 0; i < rateidx_len; ++i) { - if (rate_idx < 0) - break; - rateidx[i] = rate_idx--; - } - if (rateidx_len > 1) - rateidx[rateidx_len - 1] = 0; - return i; -} - -static void -amrr_tx_complete(void *arg __unused, struct ieee80211_node *ni, - int frame_len __unused, - const struct ieee80211_ratectl_res res[], - int res_len, int data_retries __unused, - int rts_retries __unused, int is_fail) -{ - struct amrr_data *ad = ni->ni_rate_data; - u_int total_tries; - int i; - - if (ad == NULL) - return; - - total_tries = 0; - for (i = 0; i < res_len; ++i) - total_tries += res[i].rc_res_tries; - ad->ad_tx_cnt += total_tries; - - ad->ad_tx_failure_cnt += total_tries; - if (res_len == 1 && !is_fail) { - KKASSERT(ad->ad_tx_failure_cnt != 0); - /* One packet is successfully transmitted at desired rate */ - ad->ad_tx_failure_cnt--; - } -} - -static void -amrr_newassoc(void *arg, struct ieee80211_node *ni, int isnew) -{ - if (isnew) - amrr_start(arg, ni); -} - -/* - * The code below assumes that we are dealing with hardware multi rate retry - * I have no idea what will happen if you try to use this module with another - * type of hardware. Your machine might catch fire or it might work with - * horrible performance... - */ -static void -amrr_update(struct amrr_softc *asc, struct ieee80211_node *ni, int rate) -{ - struct amrr_data *ad = ni->ni_rate_data; - - DPRINTF(asc, 5, "%s: set xmit rate for %6D to %dM\n", - __func__, ni->ni_macaddr, ":", - ni->ni_rates.rs_nrates > 0 ? - IEEE80211_RS_RATE(&ni->ni_rates, rate) / 2 : 0); - - ni->ni_txrate = rate; - - if (ad == NULL) { - amrr_data_alloc(ni); - ad = ni->ni_rate_data; - if (ad == NULL) - return; - } - - ad->ad_tx_cnt = 0; - ad->ad_tx_failure_cnt = 0; - ad->ad_success = 0; - ad->ad_recovery = 0; - ad->ad_success_threshold = asc->min_success_threshold; -} - -/* - * Set the starting transmit rate for a node. - */ -static void -amrr_start(struct amrr_softc *asc, struct ieee80211_node *ni) -{ -#define RATE(_ix) IEEE80211_RS_RATE(&ni->ni_rates, (_ix)) - struct ieee80211vap *vap = asc->vap; - int srate; - const struct ieee80211_txparam *tp = ni->ni_txparms; - enum ieee80211_phymode mode = - ieee80211_chan2mode(vap->iv_ic->ic_curchan); - - KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); - - if (tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { - /* - * For adhoc or ibss mode, start from the lowest rate. - */ - if (vap->iv_opmode == IEEE80211_M_AHDEMO || - vap->iv_opmode == IEEE80211_M_IBSS) { - amrr_update(asc, ni, 0); - return; - } - - /* - * No fixed rate is requested. For 11b start with - * the highest negotiated rate; otherwise, for 11g - * and 11a, we start "in the middle" at 24Mb or 36Mb. - */ - srate = ni->ni_rates.rs_nrates - 1; - if (mode != IEEE80211_MODE_11B) { - /* - * Scan the negotiated rate set to find the - * closest rate. - */ - /* NB: the rate set is assumed sorted */ - for (; srate >= 0 && RATE(srate) > 72; srate--) - ; - KASSERT(srate >= 0, ("bogus rate set")); - } - } else { - /* - * A fixed rate is to be used; ucastrate is an - * index into the supported rate set. Convert this - * to the index into the negotiated rate set for - * the node. We know the rate is there because the - * rate set is checked when the station associates. - */ - const struct ieee80211_rateset *rs = - &vap->iv_ic->ic_sup_rates[vap->iv_ic->ic_curmode]; - int r = IEEE80211_RS_RATE(rs, vap->iv_txparms[mode].ucastrate); - - /* NB: the rate set is assumed sorted */ - srate = ni->ni_rates.rs_nrates - 1; - for (; srate >= 0 && RATE(srate) != r; srate--) - ; - KASSERT(srate >= 0, - ("fixed rate %d not in rate set", tp->ucastrate)); - } - amrr_update(asc, ni, srate); -#undef RATE -} - -static void -amrr_rate_cb(void *arg, struct ieee80211_node *ni) -{ - amrr_update(arg, ni, 0); -} - -/* - * Reset the rate control state for each 802.11 state transition. - */ -static void -amrr_newstate(void *arg, enum ieee80211_state state) -{ - struct amrr_softc *asc = arg; - struct ieee80211vap *vap = asc->vap; - struct ieee80211_node *ni; - const struct ieee80211_txparam *tp = NULL; - - if (state == IEEE80211_S_INIT) { - callout_stop(&asc->timer); - return; - } - - if (vap->iv_opmode == IEEE80211_M_STA) { - /* - * Reset local xmit state; this is really only - * meaningful when operating in station mode. - */ - ni = vap->iv_bss; - tp = ni->ni_txparms; - if (state == IEEE80211_S_RUN) - amrr_start(asc, ni); - else - amrr_update(asc, ni, 0); - } else { - /* - * When operating as a station the node table holds - * the AP's that were discovered during scanning. - * For any other operating mode we want to reset the - * tx rate state of each node. - */ - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, amrr_rate_cb, asc); - amrr_update(asc, vap->iv_bss, 0); - } - if ((tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) && - state == IEEE80211_S_RUN) { - int interval; - - /* - * Start the background rate control thread if we - * are not configured to use a fixed xmit rate. - */ - interval = asc->param->amrr_interval; - if (vap->iv_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&asc->timer, (interval * hz) / 1000, - amrr_tick, asc); - } -} - -static void -amrr_gather_stats(struct amrr_softc *asc, struct ieee80211_node *ni) -{ - struct ieee80211vap *vap = asc->vap; - const struct ieee80211_ratectl_state *st = &vap->iv_ratectl; - struct amrr_data *ad = ni->ni_rate_data; - struct ieee80211_ratectl_stats stats; - u_int total_tries = 0; - - st->rc_st_stats(vap, ni, &stats); - - total_tries = stats.stats_pkt_ok + - stats.stats_pkt_err + - stats.stats_retries; - - ad->ad_tx_cnt += total_tries; - ad->ad_tx_failure_cnt += (total_tries - stats.stats_pkt_noretry); -} - -/* - * Examine and potentially adjust the transmit rate. - */ -static void -amrr_ratectl(void *arg, struct ieee80211_node *ni) -{ - struct amrr_softc *asc = arg; - const struct ieee80211_ratectl_state *st = &asc->vap->iv_ratectl; - struct amrr_data *ad = ni->ni_rate_data; - int old_rate; - - if (ad == NULL) { - /* We are not ready to go, set TX rate to lowest one */ - ni->ni_txrate = 0; - return; - } - -#define is_success(ad) (ad->ad_tx_failure_cnt < (ad->ad_tx_cnt / 10)) -#define is_enough(ad) (ad->ad_tx_cnt > 10) -#define is_failure(ad) (ad->ad_tx_failure_cnt > (ad->ad_tx_cnt / 3)) -#define is_max_rate(ni) ((ni->ni_txrate + 1) >= ni->ni_rates.rs_nrates) -#define is_min_rate(ni) (ni->ni_txrate == 0) - - old_rate = ni->ni_txrate; - - if (st->rc_st_stats != NULL) - amrr_gather_stats(asc, ni); - - DPRINTF(asc, 10, "tx_cnt: %u tx_failure_cnt: %u -- " - "threshold: %d\n", - ad->ad_tx_cnt, ad->ad_tx_failure_cnt, - ad->ad_success_threshold); - - if (is_success(ad) && is_enough(ad)) { - ad->ad_success++; - if (ad->ad_success == ad->ad_success_threshold && - !is_max_rate(ni)) { - ad->ad_recovery = 1; - ad->ad_success = 0; - ni->ni_txrate++; - DPRINTF(asc, 5, "increase rate to %d\n", ni->ni_txrate); - } else { - ad->ad_recovery = 0; - } - } else if (is_failure(ad)) { - ad->ad_success = 0; - if (!is_min_rate(ni)) { - if (ad->ad_recovery) { - /* recovery failure. */ - ad->ad_success_threshold *= 2; - ad->ad_success_threshold = - min(ad->ad_success_threshold, - (u_int)asc->max_success_threshold); - DPRINTF(asc, 5, "decrease rate recovery thr: " - "%d\n", ad->ad_success_threshold); - } else { - /* simple failure. */ - ad->ad_success_threshold = - asc->min_success_threshold; - DPRINTF(asc, 5, "decrease rate normal thr: " - "%d\n", ad->ad_success_threshold); - } - ad->ad_recovery = 0; - ni->ni_txrate--; - } else { - ad->ad_recovery = 0; - } - } - if (is_enough(ad) || old_rate != ni->ni_txrate) { - /* reset counters. */ - ad->ad_tx_cnt = 0; - ad->ad_tx_failure_cnt = 0; - } - if (old_rate != ni->ni_txrate) - amrr_update(asc, ni, ni->ni_txrate); -} - -static void -amrr_tick(void *arg) -{ - struct amrr_softc *asc = arg; - struct ieee80211vap *vap = asc->vap; - struct ifnet *ifp = vap->iv_ifp; - int interval; - - ifnet_serialize_all(ifp); - - if (ifp->if_flags & IFF_RUNNING) { - if (vap->iv_opmode == IEEE80211_M_STA) - amrr_ratectl(asc, vap->iv_bss); /* NB: no reference */ - else - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, - amrr_ratectl, asc); - } - interval = asc->param->amrr_interval; - if (vap->iv_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&asc->timer, (interval * hz) / 1000, amrr_tick, asc); - - ifnet_deserialize_all(ifp); -} - -static void -amrr_sysctl_attach(struct amrr_softc *asc) -{ - sysctl_ctx_init(&asc->sysctl_ctx); - asc->sysctl_oid = SYSCTL_ADD_NODE(&asc->sysctl_ctx, - SYSCTL_CHILDREN(asc->vap->iv_oid), - OID_AUTO, "amrr_ratectl", CTLFLAG_RD, 0, ""); - if (asc->sysctl_oid == NULL) { - kprintf("wlan_ratectl_amrr: create sysctl tree failed\n"); - return; - } - - SYSCTL_ADD_INT(&asc->sysctl_ctx, SYSCTL_CHILDREN(asc->sysctl_oid), - OID_AUTO, "interval", CTLFLAG_RW, - &asc->param->amrr_interval, 0, - "rate control: operation interval (ms)"); - - /* XXX bounds check values */ - SYSCTL_ADD_INT(&asc->sysctl_ctx, SYSCTL_CHILDREN(asc->sysctl_oid), - OID_AUTO, "max_sucess_threshold", CTLFLAG_RW, - &asc->param->amrr_max_success_threshold, 0, ""); - - SYSCTL_ADD_INT(&asc->sysctl_ctx, SYSCTL_CHILDREN(asc->sysctl_oid), - OID_AUTO, "min_sucess_threshold", CTLFLAG_RW, - &asc->param->amrr_min_success_threshold, 0, ""); - - SYSCTL_ADD_INT(&asc->sysctl_ctx, SYSCTL_CHILDREN(asc->sysctl_oid), - OID_AUTO, "debug", CTLFLAG_RW, - &asc->param->amrr_debug, 0, "debug level"); -} - -static void * -amrr_attach(struct ieee80211vap *vap) -{ - struct amrr_softc *asc; - - amrr_nrefs++; - - asc = kmalloc(sizeof(struct amrr_softc), M_DEVBUF, M_WAITOK | M_ZERO); - - asc->vap = vap; - callout_init(&asc->timer); - asc->param = vap->iv_ratectl.rc_st_attach(vap, IEEE80211_RATECTL_AMRR); - - amrr_sysctl_attach(asc); - - amrr_newstate(asc, vap->iv_state); - - return asc; -} - -static void -_amrr_data_free(void *arg __unused, struct ieee80211_node *ni) -{ - amrr_data_free(ni); -} - -void -amrr_detach(void *arg) -{ - struct amrr_softc *asc = arg; - struct ieee80211vap *vap = asc->vap; - - amrr_newstate(asc, IEEE80211_S_INIT); - - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, _amrr_data_free, NULL); - - if (asc->sysctl_oid != NULL) - sysctl_ctx_free(&asc->sysctl_ctx); - kfree(asc, M_DEVBUF); - - amrr_nrefs--; -} - -static void -amrr_data_free(struct ieee80211_node *ni) -{ - if (ni->ni_rate_data != NULL) { - kfree(ni->ni_rate_data, M_AMRR_RATECTL_DATA); - ni->ni_rate_data = NULL; - } -} - -static void -amrr_data_alloc(struct ieee80211_node *ni) -{ - KKASSERT(ni->ni_rate_data == NULL); - ni->ni_rate_data = kmalloc(sizeof(struct amrr_data), - M_AMRR_RATECTL_DATA, M_NOWAIT | M_ZERO); -} - -static void -amrr_data_dup(const struct ieee80211_node *oni, struct ieee80211_node *nni) -{ - if (oni->ni_rate_data == NULL || nni->ni_rate_data == NULL) - return; - - bcopy(oni->ni_rate_data, nni->ni_rate_data, sizeof(struct amrr_data)); -} - -/* - * Module glue. - */ -static int -amrr_modevent(module_t mod, int type, void *unused) -{ - switch (type) { - case MOD_LOAD: - ieee80211_ratectl_register(&amrr); - return 0; - case MOD_UNLOAD: - if (amrr_nrefs) { - kprintf("wlan_ratectl_amrr: still in use " - "(%u dynamic refs)\n", amrr_nrefs); - return EBUSY; - } - ieee80211_ratectl_unregister(&amrr); - return 0; - } - return EINVAL; -} - -static moduledata_t amrr_mod = { - "wlan_ratectl_amrr", - amrr_modevent, - 0 -}; -DECLARE_MODULE(wlan_ratectl_amrr, amrr_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); -MODULE_VERSION(wlan_ratectl_amrr, 1); -MODULE_DEPEND(wlan_ratectl_amrr, wlan, 1, 1, 1); diff --git a/sys/netproto/802_11/wlan_ratectl/onoe/Makefile b/sys/netproto/802_11/wlan_ratectl/onoe/Makefile deleted file mode 100644 index aa0b6e9e9d..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/onoe/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $DragonFly: src/sys/netproto/802_11/wlan_ratectl/onoe/Makefile,v 1.1 2006/09/01 15:12:12 sephe Exp $ - -KMOD = wlan_ratectl_onoe -SRCS = ieee80211_ratectl_onoe.c - -.include diff --git a/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h b/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h deleted file mode 100644 index e5566695d4..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.h,v 1.2 2004/12/31 22:41:45 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_onoe_param.h,v 1.2 2008/01/15 09:01:13 sephe Exp $ - */ - -#ifndef _IEEE80211_ONOE_PARAM_H -#define _IEEE80211_ONOE_PARAM_H - -struct ieee80211_onoe_param { - int onoe_interval; /* rate ctl interval (millisecond) */ - int onoe_raise; /* add credit threshold */ - int onoe_raise_threshold; /* rate ctl raise threshold */ - int onoe_debug; -}; - -#define IEEE80211_ONOE_INTERVAL 1000 /* 1 second */ -#define IEEE80211_ONOE_RAISE 10 -#define IEEE80211_ONOE_RAISE_THR 10 - -#define IEEE80211_ONOE_PARAM_SETUP(param) \ -do { \ - (param)->onoe_interval = \ - IEEE80211_ONOE_INTERVAL; \ - (param)->onoe_raise = \ - IEEE80211_ONOE_RAISE; \ - (param)->onoe_raise_threshold = \ - IEEE80211_ONOE_RAISE_THR; \ - (param)->onoe_debug = 0; \ -} while (0) - -#endif /* !_IEEE80211_ONOE_PARAM_H */ diff --git a/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c b/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c deleted file mode 100644 index 14941742e6..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.c,v 1.8.2.3 2006/02/24 19:51:11 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/onoe/ieee80211_ratectl_onoe.c,v 1.10 2008/01/15 09:01:13 sephe Exp $ - */ - -/* - * Atsushi Onoe's rate control algorithm. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#define ONOE_DEBUG - -#ifdef ONOE_DEBUG -#define DPRINTF(osc, lv, fmt, ...) do { \ - if ((osc)->param->onoe_debug >= lv) \ - kprintf(fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(osc, lv, fmt, ...) -#endif - -struct onoe_softc { - struct ieee80211vap *vap; - struct callout timer; /* periodic timer */ - - struct sysctl_ctx_list sysctl_ctx; - struct sysctl_oid *sysctl_oid; - - struct ieee80211_onoe_param *param; -#define raise param->onoe_raise -#define raise_threshold param->onoe_raise_threshold -}; - -struct onoe_data { - u_int od_tx_ok; /* tx ok pkt */ - u_int od_tx_err; /* tx !ok pkt */ - u_int od_tx_retr; /* tx retry count */ - int od_tx_upper; /* tx upper rate req cnt */ -}; - -/* - * Default parameters for the rate control algorithm. These are - * all tunable with sysctls. The rate controller runs periodically - * (each ath_rateinterval ms) analyzing transmit statistics for each - * neighbor/station (when operating in station mode this is only the AP). - * If transmits look to be working well over a sampling period then - * it gives a "raise rate credit". If transmits look to not be working - * well than it deducts a credit. If the credits cross a threshold then - * the transmit rate is raised. Various error conditions force the - * the transmit rate to be dropped. - * - * The decision to issue/deduct a credit is based on the errors and - * retries accumulated over the sampling period. ath_rate_raise defines - * the percent of retransmits for which a credit is issued/deducted. - * ath_rate_raise_threshold defines the threshold on credits at which - * the transmit rate is increased. - * - * XXX this algorithm is flawed. - */ - -static void *onoe_attach(struct ieee80211vap *); -static void onoe_detach(void *); -static void onoe_data_free(struct ieee80211_node *); -static void onoe_data_alloc(struct ieee80211_node *); -static void onoe_data_dup(const struct ieee80211_node *, - struct ieee80211_node *); -static void onoe_newstate(void *, enum ieee80211_state); -static void onoe_tx_complete(void *, struct ieee80211_node *, int, - const struct ieee80211_ratectl_res[], - int, int, int, int); -static void onoe_newassoc(void *, struct ieee80211_node *, int); -static int onoe_findrate(void *, struct ieee80211_node *, int, - int[], int); - -static void onoe_sysctl_attach(struct onoe_softc *); -static void onoe_update(struct onoe_softc *, struct ieee80211_node *, int); -static void onoe_start(struct onoe_softc *, struct ieee80211_node *); -static void onoe_tick(void *); -static void onoe_ratectl(void *, struct ieee80211_node *); -static void onoe_gather_stats(struct onoe_softc *, struct ieee80211_node *); - -static const struct ieee80211_ratectl onoe = { - .rc_name = "onoe", - .rc_ratectl = IEEE80211_RATECTL_ONOE, - .rc_attach = onoe_attach, - .rc_detach = onoe_detach, - .rc_data_alloc = onoe_data_alloc, - .rc_data_free = onoe_data_free, - .rc_data_dup = onoe_data_dup, - .rc_newstate = onoe_newstate, - .rc_tx_complete = onoe_tx_complete, - .rc_newassoc = onoe_newassoc, - .rc_findrate = onoe_findrate -}; - -static u_int onoe_nrefs; - -MALLOC_DEFINE(M_ONOE_RATECTL_DATA, "onoe_ratectl_data", - "onoe rate control data"); - -static void -onoe_tx_complete(void *arg __unused, struct ieee80211_node *ni, - int frame_len __unused, - const struct ieee80211_ratectl_res res[] __unused, - int res_len __unused, - int data_retries, int rts_retries __unused, int is_fail) -{ - struct onoe_data *od = ni->ni_rate_data; - - if (od == NULL) - return; - - if (is_fail) - od->od_tx_err++; - else - od->od_tx_ok++; - - od->od_tx_retr += data_retries; -} - -static void -onoe_newassoc(void *arg, struct ieee80211_node *ni, int is_new) -{ - if (is_new) - onoe_start(arg, ni); -} - -static int -onoe_findrate(void *arg, struct ieee80211_node *ni, - int frame_len __unused, int rateidx[], int rateidx_len) -{ - struct onoe_softc *osc = arg; - int i, rate_idx; - - if (ni->ni_txrate >= ni->ni_rates.rs_nrates) { - DPRINTF(osc, 5, "%s: number of rates changed, restart\n", - __func__); - onoe_start(osc, ni); - } - rate_idx = ni->ni_txrate; - - for (i = 0; i < rateidx_len; ++i) { - if (rate_idx < 0) - break; - rateidx[i] = rate_idx--; - } - if (rateidx_len > 1) - rateidx[rateidx_len - 1] = 0; - return i; -} - -static void -onoe_update(struct onoe_softc *osc, struct ieee80211_node *ni, int nrate) -{ - struct onoe_data *od = ni->ni_rate_data; - - DPRINTF(osc, 1, "%s: set xmit rate for %6D to %dM\n", __func__, - ni->ni_macaddr, ":", - ni->ni_rates.rs_nrates > 0 ? - IEEE80211_RS_RATE(&ni->ni_rates, nrate) / 2 : 0); - - ni->ni_txrate = nrate; - - if (od == NULL) { - onoe_data_alloc(ni); - } else { - od->od_tx_ok = 0; - od->od_tx_err = 0; - od->od_tx_retr = 0; - od->od_tx_upper = 0; - } -} - -/* - * Set the starting transmit rate for a node. - */ -static void -onoe_start(struct onoe_softc *osc, struct ieee80211_node *ni) -{ -#define RATE(_ix) IEEE80211_RS_RATE(&ni->ni_rates, (_ix)) - struct ieee80211vap *vap = osc->vap; - int srate; - const struct ieee80211_txparam *tp = ni->ni_txparms; - enum ieee80211_phymode mode = - ieee80211_chan2mode(vap->iv_ic->ic_curchan); - - KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); - if (tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { - /* - * For adhoc or ibss mode, start from the lowest rate. - */ - if (vap->iv_opmode == IEEE80211_M_AHDEMO || - vap->iv_opmode == IEEE80211_M_IBSS) { - onoe_update(osc, ni, 0); - return; - } - - /* - * No fixed rate is requested. For 11b start with - * the highest negotiated rate; otherwise, for 11g - * and 11a, we start "in the middle" at 24Mb or 36Mb. - */ - srate = ni->ni_rates.rs_nrates - 1; - if (mode != IEEE80211_MODE_11B) { - /* - * Scan the negotiated rate set to find the - * closest rate. - */ - /* NB: the rate set is assumed sorted */ - for (; srate >= 0 && RATE(srate) > 72; srate--) - ; - KASSERT(srate >= 0, ("bogus rate set")); - } - } else { - /* - * A fixed rate is to be used; ucastrate is an - * index into the supported rate set. Convert this - * to the index into the negotiated rate set for - * the node. We know the rate is there because the - * rate set is checked when the station associates. - */ - const struct ieee80211_rateset *rs = - &vap->iv_ic->ic_sup_rates[vap->iv_ic->ic_curmode]; - int r = IEEE80211_RS_RATE(rs, vap->iv_txparms[mode].ucastrate); - - /* NB: the rate set is assumed sorted */ - srate = ni->ni_rates.rs_nrates - 1; - for (; srate >= 0 && RATE(srate) != r; srate--) - ; - KASSERT(srate >= 0, - ("fixed rate %d not in rate set", tp->ucastrate)); - } - onoe_update(osc, ni, srate); -#undef RATE -} - -static void -onoe_rate_cb(void *arg, struct ieee80211_node *ni) -{ - onoe_update(arg, ni, 0); -} - -static void -onoe_newstate(void *arg, enum ieee80211_state state) -{ - struct onoe_softc *osc = arg; - struct ieee80211vap *vap = osc->vap; - struct ieee80211_node *ni; - const struct ieee80211_txparam *tp = NULL; - - if (state == IEEE80211_S_INIT) { - callout_stop(&osc->timer); - return; - } - - if (vap->iv_opmode == IEEE80211_M_STA) { - /* - * Reset local xmit state; this is really only - * meaningful when operating in station mode. - */ - ni = vap->iv_bss; - tp = ni->ni_txparms; - if (state == IEEE80211_S_RUN) - onoe_start(osc, ni); - else - onoe_update(osc, ni, 0); - } else { - /* - * When operating as a station the node table holds - * the AP's that were discovered during scanning. - * For any other operating mode we want to reset the - * tx rate state of each node. - */ - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, onoe_rate_cb, osc); - onoe_update(osc, vap->iv_bss, 0); - } - - if ((tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) && - state == IEEE80211_S_RUN) { - int interval; - - /* - * Start the background rate control thread if we - * are not configured to use a fixed xmit rate. - */ - interval = osc->param->onoe_interval; - if (vap->iv_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&osc->timer, (interval * hz) / 1000, - onoe_tick, osc); - } -} - -static void -onoe_gather_stats(struct onoe_softc *osc, struct ieee80211_node *ni) -{ - struct onoe_data *od = ni->ni_rate_data; - struct ieee80211vap *vap = osc->vap; - const struct ieee80211_ratectl_state *st = &vap->iv_ratectl; - struct ieee80211_ratectl_stats stats; - - st->rc_st_stats(vap, ni, &stats); - - od->od_tx_ok += stats.stats_pkt_ok; - od->od_tx_err += stats.stats_pkt_err; - od->od_tx_retr += stats.stats_retries; -} - -static void -onoe_ratectl(void *arg, struct ieee80211_node *ni) -{ - struct onoe_softc *osc = arg; - struct onoe_data *od = ni->ni_rate_data; - const struct ieee80211_ratectl_state *st = &osc->vap->iv_ratectl; - struct ieee80211_rateset *rs = &ni->ni_rates; - int dir = 0, nrate, enough; - - if (od == NULL) { - /* We are no ready to go, set TX rate to lowest one */ - ni->ni_txrate = 0; - return; - } - - if (st->rc_st_stats != NULL) - onoe_gather_stats(osc, ni); - - /* - * Rate control - * XXX: very primitive version. - */ - enough = (od->od_tx_ok + od->od_tx_err >= 10); - - /* no packet reached -> down */ - if (od->od_tx_err > 0 && od->od_tx_ok == 0) - dir = -1; - - /* all packets needs retry in average -> down */ - if (enough && od->od_tx_ok < od->od_tx_retr) - dir = -1; - - /* no error and less than rate_raise% of packets need retry -> up */ - if (enough && od->od_tx_err == 0 && - od->od_tx_retr < (od->od_tx_ok * osc->raise) / 100) - dir = 1; - - DPRINTF(osc, 10, "%6D: ok %d err %d retr %d upper %d dir %d\n", - ni->ni_macaddr, ":", - od->od_tx_ok, od->od_tx_err, od->od_tx_retr, - od->od_tx_upper, dir); - - nrate = ni->ni_txrate; - switch (dir) { - case 0: - if (enough && od->od_tx_upper > 0) - od->od_tx_upper--; - break; - case -1: - if (nrate > 0) - nrate--; - od->od_tx_upper = 0; - break; - case 1: - /* raise rate if we hit rate_raise_threshold */ - if (++od->od_tx_upper < osc->raise_threshold) - break; - od->od_tx_upper = 0; - if (nrate + 1 < rs->rs_nrates) - nrate++; - break; - } - - if (nrate != ni->ni_txrate) { - DPRINTF(osc, 5, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n", - __func__, - IEEE80211_RS_RATE(rs, ni->ni_txrate) / 2, - IEEE80211_RS_RATE(rs, nrate) / 2, - od->od_tx_ok, od->od_tx_err, od->od_tx_retr); - onoe_update(osc, ni, nrate); - } else if (enough) { - od->od_tx_ok = od->od_tx_err = od->od_tx_retr = 0; - } -} - -static void -onoe_tick(void *arg) -{ - struct onoe_softc *osc = arg; - struct ieee80211vap *vap = osc->vap; - struct ifnet *ifp = vap->iv_ifp; - int interval; - - ifnet_serialize_all(ifp); - - if (ifp->if_flags & IFF_RUNNING) { - if (vap->iv_opmode == IEEE80211_M_STA) - onoe_ratectl(osc, vap->iv_bss); /* NB: no reference */ - else - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, onoe_ratectl, osc); - } - - interval = osc->param->onoe_interval; - if (vap->iv_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&osc->timer, (interval * hz) / 1000, onoe_tick, osc); - - ifnet_deserialize_all(ifp); -} - -static void -onoe_sysctl_attach(struct onoe_softc *osc) -{ - sysctl_ctx_init(&osc->sysctl_ctx); - osc->sysctl_oid = SYSCTL_ADD_NODE(&osc->sysctl_ctx, - SYSCTL_CHILDREN(osc->vap->iv_oid), - OID_AUTO, "onoe_ratectl", CTLFLAG_RD, 0, ""); - if (osc->sysctl_oid == NULL) { - kprintf("wlan_ratectl_onoe: create sysctl tree failed\n"); - return; - } - - SYSCTL_ADD_INT(&osc->sysctl_ctx, SYSCTL_CHILDREN(osc->sysctl_oid), - OID_AUTO, "interval", CTLFLAG_RW, - &osc->param->onoe_interval, 0, - "rate control: operation interval (ms)"); - - /* XXX bounds check values */ - SYSCTL_ADD_INT(&osc->sysctl_ctx, SYSCTL_CHILDREN(osc->sysctl_oid), - OID_AUTO, "raise", CTLFLAG_RW, - &osc->param->onoe_raise, 0, - "rate control: " - "retry threshold to credit rate raise (%%)"); - - SYSCTL_ADD_INT(&osc->sysctl_ctx, SYSCTL_CHILDREN(osc->sysctl_oid), - OID_AUTO, "raise_threshold", CTLFLAG_RW, - &osc->param->onoe_raise_threshold, 0, - "rate control: # good periods before raising rate"); - - SYSCTL_ADD_INT(&osc->sysctl_ctx, SYSCTL_CHILDREN(osc->sysctl_oid), - OID_AUTO, "debug", CTLFLAG_RW, - &osc->param->onoe_debug, 0, - "rate control: debug level"); -} - -static void * -onoe_attach(struct ieee80211vap *vap) -{ - struct onoe_softc *osc; - - onoe_nrefs++; - - osc = kmalloc(sizeof(struct onoe_softc), M_DEVBUF, M_WAITOK | M_ZERO); - - osc->vap = vap; - callout_init(&osc->timer); - osc->param = vap->iv_ratectl.rc_st_attach(vap, IEEE80211_RATECTL_ONOE); - - onoe_sysctl_attach(osc); - - onoe_newstate(osc, vap->iv_state); - - return osc; -} - -static void -_onoe_data_free(void *arg __unused, struct ieee80211_node *ni) -{ - onoe_data_free(ni); -} - -static void -onoe_detach(void *arg) -{ - struct onoe_softc *osc = arg; - struct ieee80211vap *vap = osc->vap; - - onoe_newstate(osc, IEEE80211_S_INIT); - - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, _onoe_data_free, NULL); - - if (osc->sysctl_oid != NULL) - sysctl_ctx_free(&osc->sysctl_ctx); - kfree(osc, M_DEVBUF); - - onoe_nrefs--; -} - -static void -onoe_data_free(struct ieee80211_node *ni) -{ - if (ni->ni_rate_data != NULL) { - kfree(ni->ni_rate_data, M_ONOE_RATECTL_DATA); - ni->ni_rate_data = NULL; - } -} - -static void -onoe_data_alloc(struct ieee80211_node *ni) -{ - KKASSERT(ni->ni_rate_data == NULL); - ni->ni_rate_data = kmalloc(sizeof(struct onoe_data), - M_ONOE_RATECTL_DATA, M_NOWAIT | M_ZERO); -} - -static void -onoe_data_dup(const struct ieee80211_node *oni, struct ieee80211_node *nni) -{ - if (oni->ni_rate_data == NULL || nni->ni_rate_data == NULL) - return; - - bcopy(oni->ni_rate_data, nni->ni_rate_data, sizeof(struct onoe_data)); -} - -static int -onoe_modevent(module_t mod, int type, void *unused) -{ - switch (type) { - case MOD_LOAD: - ieee80211_ratectl_register(&onoe); - return 0; - case MOD_UNLOAD: - if (onoe_nrefs) { - kprintf("wlan_ratectl_onoe: still in use " - "(%u dynamic refs)\n", onoe_nrefs); - return EBUSY; - } - ieee80211_ratectl_unregister(&onoe); - return 0; - } - return EINVAL; -} - -static moduledata_t onoe_mod = { - "wlan_ratectl_onoe", - onoe_modevent, - 0 -}; -DECLARE_MODULE(wlan_ratectl_onoe, onoe_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); -MODULE_VERSION(wlan_ratectl_onoe, 1); -MODULE_DEPEND(wlan_ratectl_onoe, wlan, 1, 1, 1); diff --git a/sys/netproto/802_11/wlan_ratectl/sample/Makefile b/sys/netproto/802_11/wlan_ratectl/sample/Makefile deleted file mode 100644 index ece32a05cd..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/sample/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $DragonFly: src/sys/netproto/802_11/wlan_ratectl/sample/Makefile,v 1.1 2007/04/01 13:59:41 sephe Exp $ - -KMOD = wlan_ratectl_sample -SRCS = ieee80211_ratectl_sample.c - -.include diff --git a/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_ratectl_sample.c b/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_ratectl_sample.c deleted file mode 100644 index 79b3bbc683..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_ratectl_sample.c +++ /dev/null @@ -1,939 +0,0 @@ -/* - * Copyright (c) 2005 John Bicket - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD: src/sys/dev/ath/ath_rate/sample/sample.c,v 1.8.2.3 2006/03/14 23:22:27 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_ratectl_sample.c,v 1.4 2008/01/15 09:01:13 sephe Exp $ - */ - -/* - * John Bicket's SampleRate control algorithm. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#define SAMPLE_DEBUG - -#ifdef SAMPLE_DEBUG -#define DPRINTF(ssc, lv, fmt, ...) do { \ - if (ssc->param->sample_debug >= lv) \ - kprintf(fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(ssc, lv, fmt, ...) -#endif - -struct sample_softc { - struct ieee80211vap *vap; - - struct sysctl_ctx_list sysctl_ctx; - struct sysctl_oid *sysctl_oid; - - struct ieee80211_sample_param *param; -#define smoothing_rate param->sample_smoothing_rate -}; - -struct rate_stats { - unsigned average_tx_time; - int successive_failures; - int tries; - int total_packets; - int packets_acked; - unsigned perfect_tx_time; /* transmit time for 0 retries */ - int last_tx; -}; - -#define NUM_PACKET_SIZE_BINS 3 - -struct sample_data { - int started; - int static_rate_ndx; - - struct rate_stats stats[NUM_PACKET_SIZE_BINS][IEEE80211_RATE_MAXSIZE]; - int last_sample_ndx[NUM_PACKET_SIZE_BINS]; - - int current_sample_ndx[NUM_PACKET_SIZE_BINS]; - int packets_sent[NUM_PACKET_SIZE_BINS]; - - int current_rate[NUM_PACKET_SIZE_BINS]; - int packets_since_switch[NUM_PACKET_SIZE_BINS]; - unsigned ticks_since_switch[NUM_PACKET_SIZE_BINS]; - - int packets_since_sample[NUM_PACKET_SIZE_BINS]; - unsigned sample_tt[NUM_PACKET_SIZE_BINS]; -}; - -/* - * This file is an implementation of the SampleRate algorithm - * in "Bit-rate Selection in Wireless Networks" - * (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps) - * - * SampleRate chooses the bit-rate it predicts will provide the most - * throughput based on estimates of the expected per-packet - * transmission time for each bit-rate. SampleRate periodically sends - * packets at bit-rates other than the current one to estimate when - * another bit-rate will provide better performance. SampleRate - * switches to another bit-rate when its estimated per-packet - * transmission time becomes smaller than the current bit-rate's. - * SampleRate reduces the number of bit-rates it must sample by - * eliminating those that could not perform better than the one - * currently being used. SampleRate also stops probing at a bit-rate - * if it experiences several successive losses. - * - * The difference between the algorithm in the thesis and the one in this - * file is that the one in this file uses a ewma instead of a window. - * - * Also, this implementation tracks the average transmission time for - * a few different packet sizes independently for each link. - */ - -#define STALE_FAILURE_TIMEOUT_MS 10000 -#define MIN_SWITCH_MS 1000 - -static void *sample_attach(struct ieee80211vap *); -static void sample_detach(void *); -static void sample_data_alloc(struct ieee80211_node *); -static void sample_data_free(struct ieee80211_node *); -static void sample_data_dup(const struct ieee80211_node *, - struct ieee80211_node *); -static void sample_newstate(void *, enum ieee80211_state); -static void sample_tx_complete(void *, struct ieee80211_node *, int, - const struct ieee80211_ratectl_res[], - int, int, int, int); -static void sample_newassoc(void *, struct ieee80211_node *, int); -static int sample_findrate(void *, struct ieee80211_node *, int, - int[], int); - -static void sample_sysctl_attach(struct sample_softc *); -static void sample_start(struct sample_softc *, struct ieee80211_node *); -static void sample_update_stats(struct sample_softc *, - struct ieee80211_node *, int, int, - const struct ieee80211_ratectl_res [], int, - int, int); - -static const struct ieee80211_ratectl sample = { - .rc_name = "sample", - .rc_ratectl = IEEE80211_RATECTL_SAMPLE, - .rc_attach = sample_attach, - .rc_detach = sample_detach, - .rc_data_alloc = sample_data_alloc, - .rc_data_free = sample_data_free, - .rc_data_dup = sample_data_dup, - .rc_newstate = sample_newstate, - .rc_tx_complete = sample_tx_complete, - .rc_newassoc = sample_newassoc, - .rc_findrate = sample_findrate -}; - -static u_int sample_nrefs; - -/* - * for now, we track performance for three different packet - * size buckets - */ -static int packet_size_bins[NUM_PACKET_SIZE_BINS] = { 250, 1600, 3000 }; - -MALLOC_DEFINE(M_SAMPLE_RATECTL_DATA, "sample_ratectl_data", - "sample rate control data"); - -static __inline int -size_to_bin(int size) -{ - int x; - - for (x = 0; x < NUM_PACKET_SIZE_BINS; x++) { - if (size <= packet_size_bins[x]) - return x; - } - return NUM_PACKET_SIZE_BINS - 1; -} - -static __inline int -bin_to_size(int index) -{ - return packet_size_bins[index]; -} - -static __inline int -rate_to_ndx(struct ieee80211_node *ni, int rate) -{ - int x = 0; - - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { - if (IEEE80211_RS_RATE(&ni->ni_rates, x) == rate) - return x; - } - return -1; -} - -static __inline int -unicast_pkt_time(struct sample_softc *ssc, struct ieee80211_node *ni, - int rate, int len, int data_tries, int rts_tries, - int *cw0) -{ - struct ieee80211vap *vap = ssc->vap; - int sifs, difs, slot; - int ack_dur, data_dur, cw; - int tt = 0; - int i; - - ack_dur = ieee80211_txtime(ni, - sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN, - ieee80211_ack_rate(vap->iv_ic->ic_rt, rate), - vap->iv_flags); - data_dur = ieee80211_txtime(ni, len, rate, vap->iv_flags); - - if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) { - cw = IEEE80211_CW_MIN_1; - sifs = IEEE80211_DUR_OFDM_SIFS; - slot = IEEE80211_DUR_OFDM_SLOT; - } else { - /* XXX should base on characteristic rate set */ - cw = IEEE80211_CW_MIN_0; - sifs = IEEE80211_DUR_SIFS; - slot = (vap->iv_flags & IEEE80211_F_SHSLOT) - ? IEEE80211_DUR_SHSLOT - : IEEE80211_DUR_SLOT; - } - if (cw0 != NULL && *cw0 != 0) - cw = *cw0; - difs = IEEE80211_DUR_DIFS(sifs, slot); - - if (rts_tries > 0 && (vap->iv_flags & IEEE80211_F_USEPROT) && - vap->iv_ic->ic_phytype == IEEE80211_T_OFDM) { - if (vap->iv_ic->ic_protmode == IEEE80211_PROT_RTSCTS) { - uint8_t rts_rate; - int rts_dur, cts_dur; - - /* Assume RTS is sent at 2Mbits/s */ - rts_rate = 4; - - rts_dur = ieee80211_txtime(ni, - sizeof(struct ieee80211_frame_rts) + - IEEE80211_CRC_LEN, - rts_rate, vap->iv_flags); - cts_dur = ieee80211_txtime(ni, - sizeof(struct ieee80211_frame_cts) + - IEEE80211_CRC_LEN, - ieee80211_ack_rate(vap->iv_ic->ic_rt, - rts_rate), - vap->iv_flags); - - tt += rts_tries * (rts_dur + sifs + cts_dur); - - /* - * Immediate data transmission does not perform backoff - * procedure. - * - * XXX not correct, if RTS retries (short retry count) - * reaches dot11ShortRetryLimit, which should be rare. - */ - tt += sifs; - --rts_tries; - } else if (vap->iv_ic->ic_protmode == IEEE80211_PROT_CTSONLY) { - /* Assume CTS is sent at 2Mbits/s */ - tt += ieee80211_txtime(ni, - sizeof(struct ieee80211_frame_cts) + - IEEE80211_CRC_LEN, - 4, vap->iv_flags); - tt += sifs; - rts_tries = 0; - } - } else { - rts_tries = 0; - } - - tt += data_tries * (data_dur + sifs + ack_dur); - - /* Average time consumed by backoff procedure */ - for (i = 0; i < (data_tries + rts_tries); ++i) { - tt += difs + (slot * cw / 2); - cw = MIN(IEEE80211_CW_MAX + 1, (cw + 1) * 2) - 1; - } - if (cw0 != NULL) - *cw0 = cw; - return tt; -} - -/* - * returns the ndx with the lowest average_tx_time, - * or -1 if all the average_tx_times are 0. - */ -static __inline int -best_rate_ndx(struct ieee80211_node *ni, int size_bin, - int require_acked_before) -{ - int x, best_rate_ndx = 0, best_rate_tt = 0; - struct sample_data *sd = ni->ni_rate_data; - - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { - int tt = sd->stats[size_bin][x].average_tx_time; - - if (tt <= 0 || - (require_acked_before && - !sd->stats[size_bin][x].packets_acked)) - continue; - - /* 9 megabits never works better than 12 */ - if (IEEE80211_RS_RATE(&ni->ni_rates, x) == 18) - continue; - - /* don't use a bit-rate that has been failing */ - if (sd->stats[size_bin][x].successive_failures > 3) - continue; - - if (!best_rate_tt || best_rate_tt > tt) { - best_rate_tt = tt; - best_rate_ndx = x; - } - } - return (best_rate_tt) ? best_rate_ndx : -1; -} - -/* - * pick a good "random" bit-rate to sample other than the current one - */ -static __inline int -pick_sample_ndx(struct ieee80211_node *ni, int size_bin) -{ - int x = 0; - int current_ndx = 0; - unsigned current_tt = 0; - struct sample_data *sd = ni->ni_rate_data; - - current_ndx = sd->current_rate[size_bin]; - if (current_ndx < 0) { - /* no successes yet, send at the lowest bit-rate */ - return 0; - } - - current_tt = sd->stats[size_bin][current_ndx].average_tx_time; - - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { - int ndx = (sd->last_sample_ndx[size_bin] + 1 + x) % - ni->ni_rates.rs_nrates; - - /* don't sample the current bit-rate */ - if (ndx == current_ndx) - continue; - - /* this bit-rate is always worse than the current one */ - if (sd->stats[size_bin][ndx].perfect_tx_time > current_tt) - continue; - - /* rarely sample bit-rates that fail a lot */ - if (ticks - sd->stats[size_bin][ndx].last_tx < ((hz * STALE_FAILURE_TIMEOUT_MS) / 1000) && - sd->stats[size_bin][ndx].successive_failures > 3) - continue; - - /* - * don't sample more than 2 indexes higher - * for rates higher than 11 megabits - */ - if (IEEE80211_RS_RATE(&ni->ni_rates, ndx) > 22 && - ndx > current_ndx + 2) - continue; - - /* 9 megabits never works better than 12 */ - if (IEEE80211_RS_RATE(&ni->ni_rates, ndx) == 18) - continue; - - /* - * if we're using 11 megabits, only sample up to 12 megabits - */ - if (IEEE80211_RS_RATE(&ni->ni_rates, current_ndx) == 22 && - ndx > current_ndx + 1) - continue; - - sd->last_sample_ndx[size_bin] = ndx; - return ndx; - } - return current_ndx; -} - -static int -sample_findrate(void *arg, struct ieee80211_node *ni, int frame_len, - int rateidx[], int rateidx_len) -{ - struct sample_softc *ssc = arg; - struct sample_data *sd = ni->ni_rate_data; - struct ieee80211vap *vap = ssc->vap; - struct ieee80211_ratectl_state *rc_st = &vap->iv_ratectl; - int ndx, size_bin, best_ndx, change_rates, ack_before, cur_ndx, i; - unsigned average_tx_time; - - if (sd == NULL) { - /* - * XXX - * This could happen on a "reclaimed" node, which will - * vanish soon, so don't bother to call sample_start() - * here. - */ - rateidx[0] = 0; - return 1; - } else { - for (i = 0; i < NUM_PACKET_SIZE_BINS; ++i) { - if (sd->current_rate[i] >= ni->ni_rates.rs_nrates) { - DPRINTF(ssc, 5, "%s: number of rates changed, " - "restart\n", __func__); - sample_start(ssc, ni); - break; - } - } - } - - KKASSERT(frame_len > 0); - size_bin = size_to_bin(frame_len); - - ack_before = (!(rc_st->rc_st_flags & IEEE80211_RATECTL_F_MRR) || - (vap->iv_flags & IEEE80211_F_USEPROT)); - best_ndx = best_rate_ndx(ni, size_bin, ack_before); - if (best_ndx >= 0) - average_tx_time = sd->stats[size_bin][best_ndx].average_tx_time; - else - average_tx_time = 0; - - if (sd->static_rate_ndx != -1) { - ndx = sd->static_rate_ndx; - } else { - if (sd->sample_tt[size_bin] < - average_tx_time * (sd->packets_since_sample[size_bin] * ssc->param->sample_rate / 100)) { - /* - * We want to limit the time measuring the - * performance of other bit-rates to sample_rate% - * of the total transmission time. - */ - ndx = pick_sample_ndx(ni, size_bin); - if (ndx != sd->current_rate[size_bin]) - sd->current_sample_ndx[size_bin] = ndx; - else - sd->current_sample_ndx[size_bin] = -1; - sd->packets_since_sample[size_bin] = 0; - } else { - change_rates = 0; - if (!sd->packets_sent[size_bin] || best_ndx == -1) { - /* no packet has been sent successfully yet */ - for (ndx = ni->ni_rates.rs_nrates - 1; ndx > 0; ndx--) { - /* - * pick the highest rate <= 36 Mbps - * that hasn't failed. - */ - if (IEEE80211_RS_RATE(&ni->ni_rates, ndx) <= 72 && - sd->stats[size_bin][ndx].successive_failures == 0) - break; - } - change_rates = 1; - best_ndx = ndx; - } else if (sd->packets_sent[size_bin] < 20) { - /* let the bit-rate switch quickly during the first few packets */ - change_rates = 1; - } else if (ticks - ((hz * MIN_SWITCH_MS) / 1000) > sd->ticks_since_switch[size_bin]) { - /* 2 seconds have gone by */ - change_rates = 1; - } else if (average_tx_time * 2 < sd->stats[size_bin][sd->current_rate[size_bin]].average_tx_time) { - /* the current bit-rate is twice as slow as the best one */ - change_rates = 1; - } - - sd->packets_since_sample[size_bin]++; - - if (change_rates) { - if (best_ndx != sd->current_rate[size_bin]) { - DPRINTF(ssc, 5, "%s: %6D size %d " - "switch rate " - "%d (%d/%d) -> %d (%d/%d) " - "after %d packets\n", - __func__, - ni->ni_macaddr, ":", - packet_size_bins[size_bin], - IEEE80211_RS_RATE(&ni->ni_rates, sd->current_rate[size_bin]), - sd->stats[size_bin][sd->current_rate[size_bin]].average_tx_time, - sd->stats[size_bin][sd->current_rate[size_bin]].perfect_tx_time, - IEEE80211_RS_RATE(&ni->ni_rates, best_ndx), - sd->stats[size_bin][best_ndx].average_tx_time, - sd->stats[size_bin][best_ndx].perfect_tx_time, - sd->packets_since_switch[size_bin]); - } - sd->packets_since_switch[size_bin] = 0; - sd->current_rate[size_bin] = best_ndx; - sd->ticks_since_switch[size_bin] = ticks; - } - ndx = sd->current_rate[size_bin]; - sd->packets_since_switch[size_bin]++; - if (size_bin == 0) { - /* - * set the visible txrate for this node - * to the rate of small packets - */ - ni->ni_txrate = ndx; - } - } - } - - KASSERT(ndx >= 0 && ndx < ni->ni_rates.rs_nrates, ("ndx is %d", ndx)); - - sd->packets_sent[size_bin]++; - - cur_ndx = sd->current_rate[size_bin]; - if (sd->stats[size_bin][cur_ndx].packets_acked == 0) - cur_ndx = 0; - - rateidx[0] = ndx; - i = 1; - if (rateidx_len > 2) { - if ((rc_st->rc_st_flags & IEEE80211_RATECTL_F_RSDESC) == 0 || - cur_ndx < ndx) - rateidx[i++] = cur_ndx; - else if (ndx > 0) - rateidx[i++] = ndx - 1; - } - if (i < rateidx_len && rateidx[i] != 0) - rateidx[i++] = 0; - return i; -} - -static void -sample_update_stats(struct sample_softc *ssc, struct ieee80211_node *ni, - int size, int size_bin, - const struct ieee80211_ratectl_res res[], int res_len, - int rts_tries, int is_fail) -{ - struct sample_data *sd = ni->ni_rate_data; - int tt, rate, i, ndx, cw = 0, data_tries; - - cw = 0; - ndx = res[0].rc_res_rateidx; - - rate = IEEE80211_RS_RATE(&ni->ni_rates, ndx); - tt = unicast_pkt_time(ssc, ni, rate, size, - res[0].rc_res_tries, rts_tries, &cw); - data_tries = res[0].rc_res_tries; - - for (i = 1; i < res_len; ++i) { - rate = IEEE80211_RS_RATE(&ni->ni_rates, res[i].rc_res_rateidx); - tt += unicast_pkt_time(ssc, ni, rate, size, - res[i].rc_res_tries, 0, &cw); - data_tries += res[i].rc_res_tries; - } - - if (sd->stats[size_bin][ndx].total_packets < (100 / (100 - ssc->smoothing_rate))) { - int avg_tx = sd->stats[size_bin][ndx].average_tx_time; - int packets = sd->stats[size_bin][ndx].total_packets; - - /* Average the first few packets. */ - sd->stats[size_bin][ndx].average_tx_time = - (tt + (avg_tx * packets)) / (packets + 1); - } else { - /* Use EWMA */ - sd->stats[size_bin][ndx].average_tx_time = - ((sd->stats[size_bin][ndx].average_tx_time * ssc->smoothing_rate) + - (tt * (100 - ssc->smoothing_rate))) / 100; - } - - if (is_fail) { - int y; - - sd->stats[size_bin][ndx].successive_failures++; - for (y = size_bin + 1; y < NUM_PACKET_SIZE_BINS; y++) { - /* - * also say larger packets failed since we - * assume if a small packet fails at a lower - * bit-rate then a larger one will also. - */ - sd->stats[y][ndx].successive_failures++; - sd->stats[y][ndx].last_tx = ticks; - sd->stats[y][ndx].tries += data_tries; - sd->stats[y][ndx].total_packets++; - } - } else { - sd->stats[size_bin][ndx].packets_acked++; - sd->stats[size_bin][ndx].successive_failures = 0; - } - sd->stats[size_bin][ndx].last_tx = ticks; - sd->stats[size_bin][ndx].tries += data_tries; - sd->stats[size_bin][ndx].total_packets++; - - if (ndx == sd->current_sample_ndx[size_bin]) { - DPRINTF(ssc, 10, "%s: %6D size %d sample rate %d " - "tries (d%d/r%d) tt %d avg_tt (%d/%d)%s\n", - __func__, ni->ni_macaddr, ":", - size, IEEE80211_RS_RATE(&ni->ni_rates, ndx), - data_tries, rts_tries, tt, - sd->stats[size_bin][ndx].average_tx_time, - sd->stats[size_bin][ndx].perfect_tx_time, - is_fail ? " fail" : ""); - sd->sample_tt[size_bin] = tt; - sd->current_sample_ndx[size_bin] = -1; - } -} - -static void -sample_tx_complete(void *arg, struct ieee80211_node *ni, int frame_len, - const struct ieee80211_ratectl_res res[], int res_len, - int data_retry, int rts_retry, int is_fail0) -{ - struct sample_softc *ssc = arg; - struct sample_data *sd = ni->ni_rate_data; - int i, size_bin, size; - - KKASSERT(frame_len > 0); - size_bin = size_to_bin(frame_len); - size = bin_to_size(size_bin); - - if (sd == NULL || !sd->started) { - DPRINTF(ssc, 10, "%s: %6D size %d retries (d%d/r%d) " - "no rates yet\n", __func__, - ni->ni_macaddr, ":", - size, data_retry, rts_retry); - return; - } - - for (i = 0; i < res_len; ++i) { - if (res[i].rc_res_rateidx >= ni->ni_rates.rs_nrates) { - DPRINTF(ssc, 5, "%s: number of rates changed, " - "restart\n", __func__); - sample_start(ssc, ni); - return; - } - } - - DPRINTF(ssc, 20, "%s: %6D size %d retries (d%d/r%d)\n", - __func__, ni->ni_macaddr, ":", - size, data_retry, rts_retry); - for (i = 0; i < res_len; ++i) { - int is_fail = is_fail0; - - if (i == 0 && (data_retry + 1) > res[0].rc_res_tries && - res[0].rc_res_rateidx == sd->current_sample_ndx[size_bin]) - is_fail = 1; - - sample_update_stats(ssc, ni, size, size_bin, - &res[i], res_len - i, - rts_retry + 1, is_fail); - } -} - -static void -sample_newassoc(void *arg, struct ieee80211_node *ni, int isnew) -{ - struct sample_softc *ssc = arg; - - DPRINTF(ssc, 5, "%s: %6D isnew %d\n", __func__, - ni->ni_macaddr, ":", isnew); - - if (isnew) - sample_start(ssc, ni); -} - -/* - * Initialize the tables for a node. - */ -static void -sample_start(struct sample_softc *ssc, struct ieee80211_node *ni) -{ -#define RATE(_ix) IEEE80211_RS_RATE(&ni->ni_rates, (_ix)) - struct ieee80211vap *vap = ssc->vap; - struct sample_data *sd = ni->ni_rate_data; - const struct ieee80211_txparam *tp = ni->ni_txparms; - enum ieee80211_phymode mode = - ieee80211_chan2mode(vap->iv_ic->ic_curchan); - int x, y, srate; - - if (sd == NULL) { - sample_data_alloc(ni); - - sd = ni->ni_rate_data; - if (sd == NULL) - return; - } - - sd->static_rate_ndx = -1; - if (tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { - /* - * A fixed rate is to be used; ucastrate is an - * index into the supported rate set. Convert this - * to the index into the negotiated rate set for - * the node. - */ - const struct ieee80211_rateset *rs = - &vap->iv_ic->ic_sup_rates[vap->iv_ic->ic_curmode]; - int r = IEEE80211_RS_RATE(rs, vap->iv_txparms[mode].ucastrate); - - /* NB: the rate set is assumed sorted */ - srate = ni->ni_rates.rs_nrates - 1; - for (; srate >= 0 && RATE(srate) != r; srate--) - ; - KASSERT(srate >= 0, - ("fixed rate %d not in rate set", tp->ucastrate)); - sd->static_rate_ndx = srate; - } - -#ifdef SAMPLE_DEBUG - DPRINTF(ssc, 1, "%s: %6D size 1600 rate/tt", __func__, - ni->ni_macaddr, ":"); - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { - DPRINTF(ssc, 1, " %d/%d", RATE(x), - unicast_pkt_time(ssc, ni, RATE(x), 1600, 1, 1, NULL)); - } - DPRINTF(ssc, 1, "%s\n", ""); -#endif - - /* Set the visible bit-rate to the lowest one available */ - ni->ni_txrate = 0; - - for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { - int size = bin_to_size(y); - int ndx = 0; - - sd->packets_sent[y] = 0; - sd->current_sample_ndx[y] = -1; - sd->last_sample_ndx[y] = 0; - - DPRINTF(ssc, 1, "%s: %6D size %d rate/tt", __func__, - ni->ni_macaddr, ":", size); - for (x = 0; x < ni->ni_rates.rs_nrates; x++) { - sd->stats[y][x].successive_failures = 0; - sd->stats[y][x].tries = 0; - sd->stats[y][x].total_packets = 0; - sd->stats[y][x].packets_acked = 0; - sd->stats[y][x].last_tx = 0; - - sd->stats[y][x].perfect_tx_time = - unicast_pkt_time(ssc, ni, RATE(x), size, - 1, 1, NULL); - - DPRINTF(ssc, 1, " %d/%d", RATE(x), - sd->stats[y][x].perfect_tx_time); - - sd->stats[y][x].average_tx_time = - sd->stats[y][x].perfect_tx_time; - } - DPRINTF(ssc, 1, "%s\n", ""); - - /* Set the initial rate */ - for (ndx = ni->ni_rates.rs_nrates - 1; ndx > 0; ndx--) { - if (RATE(ndx) <= 72) - break; - } - sd->current_rate[y] = ndx; - } - - DPRINTF(ssc, 1, "%s: %6D %d rates %d%sMbps (%dus)- %d%sMbps (%dus)\n", - __func__, ni->ni_macaddr, ":", - ni->ni_rates.rs_nrates, - RATE(0) / 2, RATE(0) % 2 ? ".5" : "", - sd->stats[1][0].perfect_tx_time, - RATE(ni->ni_rates.rs_nrates - 1) / 2, - RATE(ni->ni_rates.rs_nrates - 1) % 2 ? ".5" : "", - sd->stats[1][ni->ni_rates.rs_nrates - 1].perfect_tx_time); - - if (sd->static_rate_ndx != -1) - ni->ni_txrate = sd->static_rate_ndx; - else - ni->ni_txrate = sd->current_rate[0]; -#undef RATE - - sd->started = 1; -} - -static void -sample_rate_cb(void *arg, struct ieee80211_node *ni) -{ - sample_newassoc(arg, ni, 1); -} - -/* - * Reset the rate control state for each 802.11 state transition. - */ -static void -sample_newstate(void *arg, enum ieee80211_state state) -{ - struct sample_softc *ssc = arg; - - if (state == IEEE80211_S_RUN) { - struct ieee80211vap *vap = ssc->vap; - - if (vap->iv_opmode != IEEE80211_M_STA) { - /* - * Sync rates for associated stations and neighbors. - */ - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, - sample_rate_cb, ssc); - } - sample_newassoc(ssc, vap->iv_bss, 1); - } -} - -static void -sample_sysctl_attach(struct sample_softc *ssc) -{ - sysctl_ctx_init(&ssc->sysctl_ctx); - ssc->sysctl_oid = SYSCTL_ADD_NODE(&ssc->sysctl_ctx, - SYSCTL_CHILDREN(ssc->vap->iv_oid), - OID_AUTO, "sample_ratectl", CTLFLAG_RD, 0, ""); - if (ssc->sysctl_oid == NULL) { - kprintf("wlan_ratectl_sample: create sysctl tree failed\n"); - return; - } - - /* XXX bounds check [0..100] */ - SYSCTL_ADD_INT(&ssc->sysctl_ctx, SYSCTL_CHILDREN(ssc->sysctl_oid), - OID_AUTO, "smoothing_rate", CTLFLAG_RW, - &ssc->param->sample_smoothing_rate, 0, - "rate control: " - "retry threshold to credit rate raise (%%)"); - - /* XXX bounds check [2..100] */ - SYSCTL_ADD_INT(&ssc->sysctl_ctx, SYSCTL_CHILDREN(ssc->sysctl_oid), - OID_AUTO, "sample_rate", CTLFLAG_RW, - &ssc->param->sample_rate, 0, - "rate control: " - "# good periods before raising rate"); - - SYSCTL_ADD_INT(&ssc->sysctl_ctx, SYSCTL_CHILDREN(ssc->sysctl_oid), - OID_AUTO, "debug", CTLFLAG_RW, - &ssc->param->sample_debug, 0, - "rate control: debug level"); -} - -static void * -sample_attach(struct ieee80211vap *vap) -{ - struct sample_softc *ssc; - - sample_nrefs++; - - ssc = kmalloc(sizeof(struct sample_softc), M_DEVBUF, M_WAITOK | M_ZERO); - - ssc->vap = vap; - ssc->param = vap->iv_ratectl.rc_st_attach(vap, IEEE80211_RATECTL_SAMPLE); - - sample_sysctl_attach(ssc); - - sample_newstate(ssc, vap->iv_state); - - return ssc; -} - -static void -_sample_data_free(void *arg __unused, struct ieee80211_node *ni) -{ - sample_data_free(ni); -} - -static void -sample_detach(void *arg) -{ - struct sample_softc *ssc = arg; - struct ieee80211vap *vap = ssc->vap; - - sample_newstate(ssc, IEEE80211_S_INIT); - - ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, _sample_data_free, NULL); - - if (ssc->sysctl_oid != NULL) - sysctl_ctx_free(&ssc->sysctl_ctx); - kfree(ssc, M_DEVBUF); - - sample_nrefs--; -} - -static void -sample_data_alloc(struct ieee80211_node *ni) -{ - KKASSERT(ni->ni_rate_data == NULL); - ni->ni_rate_data = kmalloc(sizeof(struct sample_data), - M_SAMPLE_RATECTL_DATA, M_NOWAIT | M_ZERO); -} - -static void -sample_data_free(struct ieee80211_node *ni) -{ - if (ni->ni_rate_data != NULL) { - kfree(ni->ni_rate_data, M_SAMPLE_RATECTL_DATA); - ni->ni_rate_data = NULL; - } -} - -static void -sample_data_dup(const struct ieee80211_node *oni, struct ieee80211_node *nni) -{ - if (oni->ni_rate_data == NULL || nni->ni_rate_data == NULL) - return; - - bcopy(oni->ni_rate_data, nni->ni_rate_data, - sizeof(struct sample_data)); -} - -/* - * Module glue. - */ -static int -sample_modevent(module_t mod, int type, void *unused) -{ - switch (type) { - case MOD_LOAD: - ieee80211_ratectl_register(&sample); - return 0; - case MOD_UNLOAD: - if (sample_nrefs) { - kprintf("wlan_ratectl_sample: still in use " - "(%u dynamic refs)\n", sample_nrefs); - return EBUSY; - } - ieee80211_ratectl_unregister(&sample); - return 0; - } - return EINVAL; -} - -static moduledata_t sample_mod = { - "wlan_ratectl_sample", - sample_modevent, - 0 -}; -DECLARE_MODULE(wlan_ratectl_sample, sample_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); -MODULE_VERSION(wlan_ratectl_sample, 1); -MODULE_DEPEND(wlan_ratectl_sample, wlan, 1, 1, 1); diff --git a/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_sample_param.h b/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_sample_param.h deleted file mode 100644 index cae5d4e2a1..0000000000 --- a/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_sample_param.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2005 John Bicket - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - * - * $FreeBSD: src/sys/dev/ath/ath_rate/sample/sample.h,v 1.3.2.1 2006/02/24 19:51:11 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan_ratectl/sample/ieee80211_sample_param.h,v 1.1 2008/01/15 09:01:13 sephe Exp $ - */ - -#ifndef _IEEE80211_SAMPLE_PARAM_H -#define _IEEE80211_SAMPLE_PARAM_H - -struct ieee80211_sample_param { - int sample_smoothing_rate; /* ewma percentage (out of 100) */ - int sample_rate; /* send a different bit-rate 1/X pkts */ - int sample_debug; -}; - -#define IEEE80211_SAMPLE_SMOOTHING_RATE 95 -#define IEEE80211_SAMPLE_RATE 10 - -#define IEEE80211_SAMPLE_PARAM_SETUP(param) \ -do { \ - (param)->sample_smoothing_rate = \ - IEEE80211_SAMPLE_SMOOTHING_RATE;\ - (param)->sample_rate = \ - IEEE80211_SAMPLE_RATE; \ - (param)->sample_debug = 0; \ -} while (0) - -#endif /* !_IEEE80211_SAMPLE_PARAM_H */ -- 2.41.0