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$ 28 */ 29 30 enum 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 */ 47 enum 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 57 struct 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 74 struct 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 83 struct 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 100 void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *); 101 void ieee80211_ratectl_unregister(int); 102 void ieee80211_ratectl_init(struct ieee80211vap *); 103 void ieee80211_ratectl_set(struct ieee80211vap *, int); 104 105 MALLOC_DECLARE(M_80211_RATECTL); 106 107 static __inline void 108 ieee80211_ratectl_deinit(struct ieee80211vap *vap) 109 { 110 vap->iv_rate->ir_deinit(vap); 111 } 112 113 static __inline void 114 ieee80211_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 121 static __inline void 122 ieee80211_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 129 static int __inline 130 ieee80211_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 137 static __inline void 138 ieee80211_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 146 static __inline void 147 ieee80211_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 155 static __inline void 156 ieee80211_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 163 static __inline void 164 ieee80211_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