| 1 | /* $NetBSD: athrate-sample.h,v 1.4 2012/11/08 20:43:55 dyoung Exp $ */ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 2005 John Bicket |
| 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 | * without modification. |
| 13 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
| 14 | * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any |
| 15 | * redistribution must be conditioned upon including a substantially |
| 16 | * similar Disclaimer requirement for further binary redistribution. |
| 17 | * 3. Neither the names of the above-listed copyright holders nor the names |
| 18 | * of any contributors may be used to endorse or promote products derived |
| 19 | * from this software without specific prior written permission. |
| 20 | * |
| 21 | * Alternatively, this software may be distributed under the terms of the |
| 22 | * GNU General Public License ("GPL") version 2 as published by the Free |
| 23 | * Software Foundation. |
| 24 | * |
| 25 | * NO WARRANTY |
| 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 27 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 28 | * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY |
| 29 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
| 30 | * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, |
| 31 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 33 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
| 34 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 36 | * THE POSSIBILITY OF SUCH DAMAGES. |
| 37 | * |
| 38 | * $FreeBSD: src/sys/dev/ath/ath_rate/sample/sample.h,v 1.3 2005/03/20 01:27:33 sam Exp $ |
| 39 | */ |
| 40 | |
| 41 | /* |
| 42 | * Defintions for the Atheros Wireless LAN controller driver. |
| 43 | */ |
| 44 | #ifndef _DEV_ATH_RATE_SAMPLE_H |
| 45 | #define _DEV_ATH_RATE_SAMPLE_H |
| 46 | |
| 47 | /* per-device state */ |
| 48 | struct sample_softc { |
| 49 | struct ath_ratectrl arc; /* base state */ |
| 50 | int ath_smoothing_rate; /* ewma percentage (out of 100) */ |
| 51 | int ath_sample_rate; /* send a different bit-rate 1/X packets */ |
| 52 | }; |
| 53 | #define ATH_SOFTC_SAMPLE(sc) ((struct sample_softc *)sc->sc_rc) |
| 54 | |
| 55 | struct rate_info { |
| 56 | int rate; |
| 57 | int rix; |
| 58 | int rateCode; |
| 59 | int shortPreambleRateCode; |
| 60 | }; |
| 61 | |
| 62 | |
| 63 | struct rate_stats { |
| 64 | unsigned average_tx_time; |
| 65 | int successive_failures; |
| 66 | int tries; |
| 67 | int total_packets; |
| 68 | int packets_acked; |
| 69 | unsigned perfect_tx_time; /* transmit time for 0 retries */ |
| 70 | int last_tx; |
| 71 | }; |
| 72 | |
| 73 | /* |
| 74 | * for now, we track performance for three different packet |
| 75 | * size buckets |
| 76 | */ |
| 77 | #define NUM_PACKET_SIZE_BINS 3 |
| 78 | static int packet_size_bins[NUM_PACKET_SIZE_BINS] = {250, 1600, 3000}; |
| 79 | |
| 80 | /* per-node state */ |
| 81 | struct sample_node { |
| 82 | int static_rate_ndx; |
| 83 | int num_rates; |
| 84 | |
| 85 | struct rate_info rates[IEEE80211_RATE_MAXSIZE]; |
| 86 | |
| 87 | struct rate_stats stats[NUM_PACKET_SIZE_BINS][IEEE80211_RATE_MAXSIZE]; |
| 88 | int last_sample_ndx[NUM_PACKET_SIZE_BINS]; |
| 89 | |
| 90 | int current_sample_ndx[NUM_PACKET_SIZE_BINS]; |
| 91 | int packets_sent[NUM_PACKET_SIZE_BINS]; |
| 92 | |
| 93 | int current_rate[NUM_PACKET_SIZE_BINS]; |
| 94 | int packets_since_switch[NUM_PACKET_SIZE_BINS]; |
| 95 | unsigned ticks_since_switch[NUM_PACKET_SIZE_BINS]; |
| 96 | |
| 97 | int packets_since_sample[NUM_PACKET_SIZE_BINS]; |
| 98 | unsigned sample_tt[NUM_PACKET_SIZE_BINS]; |
| 99 | }; |
| 100 | #define ATH_NODE_SAMPLE(an) ((struct sample_node *)&an[1]) |
| 101 | |
| 102 | #ifndef MIN |
| 103 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
| 104 | #endif |
| 105 | #ifndef MAX |
| 106 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
| 107 | #endif |
| 108 | |
| 109 | #define WIFI_CW_MIN 31 |
| 110 | #define WIFI_CW_MAX 1023 |
| 111 | |
| 112 | struct ar5212_desc { |
| 113 | /* |
| 114 | * tx_control_0 |
| 115 | */ |
| 116 | u_int32_t frame_len:12; |
| 117 | u_int32_t reserved_12_15:4; |
| 118 | u_int32_t xmit_power:6; |
| 119 | u_int32_t rts_cts_enable:1; |
| 120 | u_int32_t veol:1; |
| 121 | u_int32_t clear_dest_mask:1; |
| 122 | u_int32_t ant_mode_xmit:4; |
| 123 | u_int32_t inter_req:1; |
| 124 | u_int32_t encrypt_key_valid:1; |
| 125 | u_int32_t cts_enable:1; |
| 126 | |
| 127 | /* |
| 128 | * tx_control_1 |
| 129 | */ |
| 130 | u_int32_t buf_len:12; |
| 131 | u_int32_t more:1; |
| 132 | u_int32_t encrypt_key_index:7; |
| 133 | u_int32_t frame_type:4; |
| 134 | u_int32_t no_ack:1; |
| 135 | u_int32_t comp_proc:2; |
| 136 | u_int32_t comp_iv_len:2; |
| 137 | u_int32_t comp_icv_len:2; |
| 138 | u_int32_t reserved_31:1; |
| 139 | |
| 140 | /* |
| 141 | * tx_control_2 |
| 142 | */ |
| 143 | u_int32_t rts_duration:15; |
| 144 | u_int32_t duration_update_enable:1; |
| 145 | u_int32_t xmit_tries0:4; |
| 146 | u_int32_t xmit_tries1:4; |
| 147 | u_int32_t xmit_tries2:4; |
| 148 | u_int32_t xmit_tries3:4; |
| 149 | |
| 150 | /* |
| 151 | * tx_control_3 |
| 152 | */ |
| 153 | u_int32_t xmit_rate0:5; |
| 154 | u_int32_t xmit_rate1:5; |
| 155 | u_int32_t xmit_rate2:5; |
| 156 | u_int32_t xmit_rate3:5; |
| 157 | u_int32_t rts_cts_rate:5; |
| 158 | u_int32_t reserved_25_31:7; |
| 159 | |
| 160 | /* |
| 161 | * tx_status_0 |
| 162 | */ |
| 163 | u_int32_t frame_xmit_ok:1; |
| 164 | u_int32_t excessive_retries:1; |
| 165 | u_int32_t fifo_underrun:1; |
| 166 | u_int32_t filtered:1; |
| 167 | u_int32_t rts_fail_count:4; |
| 168 | u_int32_t data_fail_count:4; |
| 169 | u_int32_t virt_coll_count:4; |
| 170 | u_int32_t send_timestamp:16; |
| 171 | |
| 172 | /* |
| 173 | * tx_status_1 |
| 174 | */ |
| 175 | u_int32_t done:1; |
| 176 | u_int32_t seq_num:12; |
| 177 | u_int32_t ack_sig_strength:8; |
| 178 | u_int32_t final_ts_index:2; |
| 179 | u_int32_t comp_success:1; |
| 180 | u_int32_t xmit_antenna:1; |
| 181 | u_int32_t reserved_25_31_x:7; |
| 182 | } __packed; |
| 183 | |
| 184 | /* |
| 185 | * Calculate the transmit duration of a frame. |
| 186 | */ |
| 187 | static unsigned calc_usecs_unicast_packet(struct ath_softc *sc, |
| 188 | int length, |
| 189 | int rix, int short_retries, int long_retries) { |
| 190 | const HAL_RATE_TABLE *rt = sc->sc_currates; |
| 191 | int rts, cts; |
| 192 | |
| 193 | unsigned t_slot = 20; |
| 194 | unsigned t_difs = 50; |
| 195 | unsigned t_sifs = 10; |
| 196 | struct ieee80211com *ic = &sc->sc_ic; |
| 197 | int tt = 0; |
| 198 | int x = 0; |
| 199 | int cw = WIFI_CW_MIN; |
| 200 | int cix = rt->info[rix].controlRate; |
| 201 | |
| 202 | KASSERTMSG(rt != NULL, "no rate table, mode %u" , sc->sc_curmode); |
| 203 | |
| 204 | if (!rt->info[rix].rateKbps) { |
| 205 | printf("rix %d (%d) bad ratekbps %d mode %u" , |
| 206 | rix, rt->info[rix].dot11Rate, |
| 207 | rt->info[rix].rateKbps, |
| 208 | sc->sc_curmode); |
| 209 | |
| 210 | return 0; |
| 211 | } |
| 212 | /* |
| 213 | * XXX getting mac/phy level timings should be fixed for turbo |
| 214 | * rates, and there is probably a way to get this from the |
| 215 | * hal... |
| 216 | */ |
| 217 | switch (rt->info[rix].phy) { |
| 218 | case IEEE80211_T_OFDM: |
| 219 | t_slot = 9; |
| 220 | t_sifs = 16; |
| 221 | t_difs = 28; |
| 222 | /* fall through */ |
| 223 | case IEEE80211_T_TURBO: |
| 224 | t_slot = 9; |
| 225 | t_sifs = 8; |
| 226 | t_difs = 28; |
| 227 | break; |
| 228 | case IEEE80211_T_DS: |
| 229 | /* fall through to default */ |
| 230 | default: |
| 231 | /* pg 205 ieee.802.11.pdf */ |
| 232 | t_slot = 20; |
| 233 | t_difs = 50; |
| 234 | t_sifs = 10; |
| 235 | } |
| 236 | |
| 237 | rts = cts = 0; |
| 238 | |
| 239 | if ((ic->ic_flags & IEEE80211_F_USEPROT) && |
| 240 | rt->info[rix].phy == IEEE80211_T_OFDM) { |
| 241 | if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) |
| 242 | rts = 1; |
| 243 | else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) |
| 244 | cts = 1; |
| 245 | |
| 246 | cix = rt->info[sc->sc_protrix].controlRate; |
| 247 | |
| 248 | } |
| 249 | |
| 250 | if (0 /*length > ic->ic_rtsthreshold */) { |
| 251 | rts = 1; |
| 252 | } |
| 253 | |
| 254 | if (rts || cts) { |
| 255 | int ctsrate = rt->info[cix].rateCode; |
| 256 | int ctsduration = 0; |
| 257 | |
| 258 | if (!rt->info[cix].rateKbps) { |
| 259 | printf("cix %d (%d) bad ratekbps %d mode %u" , |
| 260 | cix, rt->info[cix].dot11Rate, |
| 261 | rt->info[cix].rateKbps, |
| 262 | sc->sc_curmode); |
| 263 | return 0; |
| 264 | } |
| 265 | |
| 266 | ctsrate |= rt->info[cix].shortPreamble; |
| 267 | if (rts) /* SIFS + CTS */ |
| 268 | ctsduration += rt->info[cix].spAckDuration; |
| 269 | |
| 270 | ctsduration += ath_hal_computetxtime(sc->sc_ah, |
| 271 | rt, length, rix, AH_TRUE); |
| 272 | |
| 273 | if (cts) /* SIFS + ACK */ |
| 274 | ctsduration += rt->info[cix].spAckDuration; |
| 275 | |
| 276 | tt += (short_retries + 1) * ctsduration; |
| 277 | } |
| 278 | tt += t_difs; |
| 279 | tt += (long_retries+1)*(t_sifs + rt->info[rix].spAckDuration); |
| 280 | tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length, |
| 281 | rix, AH_TRUE); |
| 282 | for (x = 0; x <= short_retries + long_retries; x++) { |
| 283 | cw = MIN(WIFI_CW_MAX, (cw + 1) * 2); |
| 284 | tt += (t_slot * cw/2); |
| 285 | } |
| 286 | return tt; |
| 287 | } |
| 288 | #endif /* _DEV_ATH_RATE_SAMPLE_H */ |
| 289 | |