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