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