1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * $FreeBSD: releng/12.0/sys/net80211/ieee80211_ratectl.h 326272 2017-11-27 15:23:17Z pfg $ 28 */ 29 30enum ieee80211_ratealgs { 31 IEEE80211_RATECTL_AMRR = 0, 32 IEEE80211_RATECTL_RSSADAPT = 1, 33 IEEE80211_RATECTL_ONOE = 2, 34 IEEE80211_RATECTL_SAMPLE = 3, 35 IEEE80211_RATECTL_NONE = 4, 36 IEEE80211_RATECTL_MAX 37}; 38 39/* used fields for tx_complete() events */ 40#define IEEE80211_RATECTL_STATUS_PKTLEN 0x00000001 41#define IEEE80211_RATECTL_STATUS_FINAL_RATE 0x00000002 42#define IEEE80211_RATECTL_STATUS_SHORT_RETRY 0x00000004 43#define IEEE80211_RATECTL_STATUS_LONG_RETRY 0x00000008 44#define IEEE80211_RATECTL_STATUS_RSSI 0x00000010 45 46/* failure reason */ 47enum ieee80211_ratectl_tx_fail_reason { 48 IEEE80211_RATECTL_TX_SUCCESS = 0, 49 IEEE80211_RATECTL_TX_FAIL_SHORT = 1, /* too many RTS retries */ 50 IEEE80211_RATECTL_TX_FAIL_LONG = 2, /* too many retries */ 51 IEEE80211_RATECTL_TX_FAIL_EXPIRED = 3, /* lifetime expired */ 52 IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED = 4, /* another reason */ 53}; 54#define IEEE80211_RATECTL_TX_FAIL_MAX \ 55 (IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED + 1) 56 57struct ieee80211_ratectl_tx_status { 58 uint32_t flags; /* mark used fields */ 59 enum ieee80211_ratectl_tx_fail_reason status; /* Tx status */ 60 61 int pktlen; /* frame length */ 62 int final_rate; /* transmission rate */ 63 uint_fast8_t short_retries; /* RTS/CTS retries */ 64 uint_fast8_t long_retries; /* ACK retries */ 65 int8_t rssi; /* ACK RSSI */ 66 67 uint8_t spare[15]; /* for future use */ 68}; 69 70/* used fields for tx_update() events */ 71#define IEEE80211_RATECTL_TX_STATS_NODE 0x00000001 72#define IEEE80211_RATECTL_TX_STATS_RETRIES 0x00000002 73 74struct ieee80211_ratectl_tx_stats { 75 uint32_t flags; /* mark used fields */ 76 77 struct ieee80211_node *ni; /* receiver */ 78 int nframes; /* transmitted frames */ 79 int nsuccess; /* ACKed frames */ 80 int nretries; /* number of retries */ 81}; 82 83struct ieee80211_ratectl { 84 const char *ir_name; 85 int (*ir_attach)(const struct ieee80211vap *); 86 void (*ir_detach)(const struct ieee80211vap *); 87 void (*ir_init)(struct ieee80211vap *); 88 void (*ir_deinit)(struct ieee80211vap *); 89 void (*ir_node_init)(struct ieee80211_node *); 90 void (*ir_node_deinit)(struct ieee80211_node *); 91 int (*ir_rate)(struct ieee80211_node *, void *, uint32_t); 92 void (*ir_tx_complete)(const struct ieee80211_node *, 93 const struct ieee80211_ratectl_tx_status *); 94 void (*ir_tx_update)(struct ieee80211vap *, 95 struct ieee80211_ratectl_tx_stats *); 96 void (*ir_setinterval)(const struct ieee80211vap *, int); 97 void (*ir_node_stats)(struct ieee80211_node *ni, struct sbuf *s); 98}; 99 100void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *); 101void ieee80211_ratectl_unregister(int); 102void ieee80211_ratectl_init(struct ieee80211vap *); 103void ieee80211_ratectl_set(struct ieee80211vap *, int); 104 105MALLOC_DECLARE(M_80211_RATECTL); 106 107static __inline void 108ieee80211_ratectl_deinit(struct ieee80211vap *vap) 109{ 110 vap->iv_rate->ir_deinit(vap); 111} 112 113static __inline void 114ieee80211_ratectl_node_init(struct ieee80211_node *ni) 115{ 116 const struct ieee80211vap *vap = ni->ni_vap; 117 118 vap->iv_rate->ir_node_init(ni); 119} 120 121static __inline void 122ieee80211_ratectl_node_deinit(struct ieee80211_node *ni) 123{ 124 const struct ieee80211vap *vap = ni->ni_vap; 125 126 vap->iv_rate->ir_node_deinit(ni); 127} 128 129static int __inline 130ieee80211_ratectl_rate(struct ieee80211_node *ni, void *arg, uint32_t iarg) 131{ 132 const struct ieee80211vap *vap = ni->ni_vap; 133 134 return vap->iv_rate->ir_rate(ni, arg, iarg); 135} 136 137static __inline void 138ieee80211_ratectl_tx_complete(const struct ieee80211_node *ni, 139 const struct ieee80211_ratectl_tx_status *status) 140{ 141 const struct ieee80211vap *vap = ni->ni_vap; 142 143 vap->iv_rate->ir_tx_complete(ni, status); 144} 145 146static __inline void 147ieee80211_ratectl_tx_update(struct ieee80211vap *vap, 148 struct ieee80211_ratectl_tx_stats *stats) 149{ 150 if (vap->iv_rate->ir_tx_update == NULL) 151 return; 152 vap->iv_rate->ir_tx_update(vap, stats); 153} 154 155static __inline void 156ieee80211_ratectl_setinterval(const struct ieee80211vap *vap, int msecs) 157{ 158 if (vap->iv_rate->ir_setinterval == NULL) 159 return; 160 vap->iv_rate->ir_setinterval(vap, msecs); 161} 162 163static __inline void 164ieee80211_ratectl_node_stats(struct ieee80211_node *ni, struct sbuf *s) 165{ 166 const struct ieee80211vap *vap = ni->ni_vap; 167 168 if (vap->iv_rate->ir_node_stats == NULL) 169 return; 170 vap->iv_rate->ir_node_stats(ni, s); 171} 172