The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ath/ath_rate/sample/sample.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-3-Clause
    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  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD$");
   42 
   43 /*
   44  * John Bicket's SampleRate control algorithm.
   45  */
   46 #include "opt_ath.h"
   47 #include "opt_inet.h"
   48 #include "opt_wlan.h"
   49 #include "opt_ah.h"
   50 
   51 #include <sys/param.h>
   52 #include <sys/systm.h> 
   53 #include <sys/sysctl.h>
   54 #include <sys/kernel.h>
   55 #include <sys/lock.h>
   56 #include <sys/malloc.h>
   57 #include <sys/mutex.h>
   58 #include <sys/errno.h>
   59 
   60 #include <machine/bus.h>
   61 #include <machine/resource.h>
   62 #include <sys/bus.h>
   63 
   64 #include <sys/socket.h>
   65 
   66 #include <net/if.h>
   67 #include <net/if_var.h>
   68 #include <net/if_media.h>
   69 #include <net/if_arp.h>
   70 #include <net/ethernet.h>               /* XXX for ether_sprintf */
   71 
   72 #include <net80211/ieee80211_var.h>
   73 
   74 #include <net/bpf.h>
   75 
   76 #ifdef INET
   77 #include <netinet/in.h> 
   78 #include <netinet/if_ether.h>
   79 #endif
   80 
   81 #include <dev/ath/if_athvar.h>
   82 #include <dev/ath/ath_rate/sample/sample.h>
   83 #include <dev/ath/ath_hal/ah_desc.h>
   84 #include <dev/ath/ath_rate/sample/tx_schedules.h>
   85 
   86 /*
   87  * This file is an implementation of the SampleRate algorithm
   88  * in "Bit-rate Selection in Wireless Networks"
   89  * (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps)
   90  *
   91  * SampleRate chooses the bit-rate it predicts will provide the most
   92  * throughput based on estimates of the expected per-packet
   93  * transmission time for each bit-rate.  SampleRate periodically sends
   94  * packets at bit-rates other than the current one to estimate when
   95  * another bit-rate will provide better performance. SampleRate
   96  * switches to another bit-rate when its estimated per-packet
   97  * transmission time becomes smaller than the current bit-rate's.
   98  * SampleRate reduces the number of bit-rates it must sample by
   99  * eliminating those that could not perform better than the one
  100  * currently being used.  SampleRate also stops probing at a bit-rate
  101  * if it experiences several successive losses.
  102  *
  103  * The difference between the algorithm in the thesis and the one in this
  104  * file is that the one in this file uses a ewma instead of a window.
  105  *
  106  * Also, this implementation tracks the average transmission time for
  107  * a few different packet sizes independently for each link.
  108  */
  109 
  110 /* XXX TODO: move this into ath_hal/net80211 so it can be shared */
  111 
  112 #define MCS_HT20        0
  113 #define MCS_HT20_SGI    1
  114 #define MCS_HT40        2
  115 #define MCS_HT40_SGI    3
  116 
  117 /*
  118  * This is currently a copy/paste from the 11n tx code.
  119  *
  120  * It's used to determine the maximum frame length allowed for the
  121  * given rate.  For now this ignores SGI/LGI and will assume long-GI.
  122  * This only matters for lower rates that can't fill a full 64k A-MPDU.
  123  *
  124  * (But it's also important because right now rate control doesn't set
  125  * flags like SGI/LGI, STBC, LDPC, TX power, etc.)
  126  *
  127  * When selecting a set of rates the rate control code will iterate
  128  * over the HT20/HT40 max frame length and tell the caller the maximum
  129  * length (@ LGI.)  It will also choose a bucket that's the minimum
  130  * of this value and the provided aggregate length.  That way the
  131  * rate selection will closely match what the eventual formed aggregate
  132  * will be rather than "not at all".
  133  */
  134 
  135 static int ath_rate_sample_max_4ms_framelen[4][32] = {
  136         [MCS_HT20] = {
  137                 3212,  6432,  9648,  12864,  19300,  25736,  28952,  32172,
  138                 6424,  12852, 19280, 25708,  38568,  51424,  57852,  64280,
  139                 9628,  19260, 28896, 38528,  57792,  65532,  65532,  65532,
  140                 12828, 25656, 38488, 51320,  65532,  65532,  65532,  65532,
  141         },
  142         [MCS_HT20_SGI] = {
  143                 3572,  7144,  10720,  14296,  21444,  28596,  32172,  35744,
  144                 7140,  14284, 21428,  28568,  42856,  57144,  64288,  65532,
  145                 10700, 21408, 32112,  42816,  64228,  65532,  65532,  65532,
  146                 14256, 28516, 42780,  57040,  65532,  65532,  65532,  65532,
  147         },
  148         [MCS_HT40] = {
  149                 6680,  13360,  20044,  26724,  40092,  53456,  60140,  65532,
  150                 13348, 26700,  40052,  53400,  65532,  65532,  65532,  65532,
  151                 20004, 40008,  60016,  65532,  65532,  65532,  65532,  65532,
  152                 26644, 53292,  65532,  65532,  65532,  65532,  65532,  65532,
  153         },
  154         [MCS_HT40_SGI] = {
  155                 7420,  14844,  22272,  29696,  44544,  59396,  65532,  65532,
  156                 14832, 29668,  44504,  59340,  65532,  65532,  65532,  65532,
  157                 22232, 44464,  65532,  65532,  65532,  65532,  65532,  65532,
  158                 29616, 59232,  65532,  65532,  65532,  65532,  65532,  65532,
  159         }
  160 };
  161 
  162 /*
  163  * Given the (potentially MRR) transmit schedule, calculate the maximum
  164  * allowed packet size for forming aggregates based on the lowest
  165  * MCS rate in the transmit schedule.
  166  *
  167  * Returns -1 if it's a legacy rate or no MRR.
  168  *
  169  * XXX TODO: this needs to be limited by the RTS/CTS AR5416 8KB bug limit!
  170  * (by checking rts/cts flags and applying sc_rts_aggr_limit)
  171  *
  172  * XXX TODO: apply per-node max-ampdu size and driver ampdu size limits too.
  173  */
  174 static int
  175 ath_rate_sample_find_min_pktlength(struct ath_softc *sc,
  176     struct ath_node *an, uint8_t rix0, int is_aggr)
  177 {
  178 #define MCS_IDX(ix)             (rt->info[ix].dot11Rate)
  179         const HAL_RATE_TABLE *rt = sc->sc_currates;
  180         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  181         const struct txschedule *sched = &sn->sched[rix0];
  182         int max_pkt_length = 65530; // ATH_AGGR_MAXSIZE
  183         // Note: this may not be true in all cases; need to check?
  184         int is_ht40 = (an->an_node.ni_chw == 40);
  185         // Note: not great, but good enough..
  186         int idx = is_ht40 ? MCS_HT40 : MCS_HT20;
  187 
  188         if (rt->info[rix0].phy != IEEE80211_T_HT) {
  189                 return -1;
  190         }
  191 
  192         if (! sc->sc_mrretry) {
  193                 return -1;
  194         }
  195 
  196         KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
  197             rix0, sched->r0));
  198 
  199         /*
  200          * Update based on sched->r{0,1,2,3} if sched->t{0,1,2,3}
  201          * is not zero.
  202          *
  203          * Note: assuming all four PHYs are HT!
  204          *
  205          * XXX TODO: right now I hardcode here and in getxtxrates() that
  206          * rates 2 and 3 in the tx schedule are ignored.  This is important
  207          * for forming larger aggregates because right now (a) the tx schedule
  208          * per rate is fixed, and (b) reliable packet transmission at those
  209          * higher rates kinda needs a lower MCS rate in there somewhere.
  210          * However, this means we can only form shorter aggregates.
  211          * If we've negotiated aggregation then we can actually just
  212          * rely on software retransmit rather than having things fall
  213          * back to like MCS0/1 in hardware, and rate control will hopefully
  214          * do the right thing.
  215          *
  216          * Once the whole rate schedule is passed into ath_rate_findrate(),
  217          * the ath_rc_series is populated ,the fixed tx schedule stuff
  218          * is removed AND getxtxrates() is removed then we can remove this
  219          * check as it can just NOT populate t2/t3.  It also means
  220          * probing can actually use rix0 for probeing and rix1 for the
  221          * current best rate..
  222          */
  223         if (sched->t0 != 0) {
  224                 max_pkt_length = MIN(max_pkt_length,
  225                     ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r0)]);
  226         }
  227         if (sched->t1 != 0) {
  228                 max_pkt_length = MIN(max_pkt_length,
  229                     ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r1)]);
  230         }
  231         if (sched->t2 != 0 && (! is_aggr)) {
  232                 max_pkt_length = MIN(max_pkt_length,
  233                     ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r2)]);
  234         }
  235         if (sched->t3 != 0 && (! is_aggr)) {
  236                 max_pkt_length = MIN(max_pkt_length,
  237                     ath_rate_sample_max_4ms_framelen[idx][MCS_IDX(sched->r3)]);
  238         }
  239 
  240         return max_pkt_length;
  241 #undef  MCS
  242 }
  243 
  244 static void     ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *);
  245 
  246 static __inline int
  247 size_to_bin(int size) 
  248 {
  249 #if NUM_PACKET_SIZE_BINS > 1
  250         if (size <= packet_size_bins[0])
  251                 return 0;
  252 #endif
  253 #if NUM_PACKET_SIZE_BINS > 2
  254         if (size <= packet_size_bins[1])
  255                 return 1;
  256 #endif
  257 #if NUM_PACKET_SIZE_BINS > 3
  258         if (size <= packet_size_bins[2])
  259                 return 2;
  260 #endif
  261 #if NUM_PACKET_SIZE_BINS > 4
  262         if (size <= packet_size_bins[3])
  263                 return 3;
  264 #endif
  265 #if NUM_PACKET_SIZE_BINS > 5
  266         if (size <= packet_size_bins[4])
  267                 return 4;
  268 #endif
  269 #if NUM_PACKET_SIZE_BINS > 6
  270         if (size <= packet_size_bins[5])
  271                 return 5;
  272 #endif
  273 #if NUM_PACKET_SIZE_BINS > 7
  274         if (size <= packet_size_bins[6])
  275                 return 6;
  276 #endif
  277 #if NUM_PACKET_SIZE_BINS > 8
  278 #error "add support for more packet sizes"
  279 #endif
  280         return NUM_PACKET_SIZE_BINS-1;
  281 }
  282 
  283 void
  284 ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
  285 {
  286         /* NB: assumed to be zero'd by caller */
  287 }
  288 
  289 void
  290 ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
  291 {
  292 }
  293 
  294 static int
  295 dot11rate(const HAL_RATE_TABLE *rt, int rix)
  296 {
  297         if (rix < 0)
  298                 return -1;
  299         return rt->info[rix].phy == IEEE80211_T_HT ?
  300             rt->info[rix].dot11Rate : (rt->info[rix].dot11Rate & IEEE80211_RATE_VAL) / 2;
  301 }
  302 
  303 static const char *
  304 dot11rate_label(const HAL_RATE_TABLE *rt, int rix)
  305 {
  306         if (rix < 0)
  307                 return "";
  308         return rt->info[rix].phy == IEEE80211_T_HT ? "MCS" : "Mb ";
  309 }
  310 
  311 /*
  312  * Return the rix with the lowest average_tx_time,
  313  * or -1 if all the average_tx_times are 0.
  314  */
  315 static __inline int
  316 pick_best_rate(struct ath_node *an, const HAL_RATE_TABLE *rt,
  317     int size_bin, int require_acked_before)
  318 {
  319         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  320         int best_rate_rix, best_rate_tt, best_rate_pct;
  321         uint64_t mask;
  322         int rix, tt, pct;
  323 
  324         best_rate_rix = 0;
  325         best_rate_tt = 0;
  326         best_rate_pct = 0;
  327         for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
  328                 if ((mask & 1) == 0)            /* not a supported rate */
  329                         continue;
  330 
  331                 /* Don't pick a non-HT rate for a HT node */
  332                 if ((an->an_node.ni_flags & IEEE80211_NODE_HT) &&
  333                     (rt->info[rix].phy != IEEE80211_T_HT)) {
  334                         continue;
  335                 }
  336 
  337                 tt = sn->stats[size_bin][rix].average_tx_time;
  338                 if (tt <= 0 ||
  339                     (require_acked_before &&
  340                      !sn->stats[size_bin][rix].packets_acked))
  341                         continue;
  342 
  343                 /* Calculate percentage if possible */
  344                 if (sn->stats[size_bin][rix].total_packets > 0) {
  345                         pct = sn->stats[size_bin][rix].ewma_pct;
  346                 } else {
  347                         pct = -1; /* No percent yet to compare against! */
  348                 }
  349 
  350                 /* don't use a bit-rate that has been failing */
  351                 if (sn->stats[size_bin][rix].successive_failures > 3)
  352                         continue;
  353 
  354                 /*
  355                  * For HT, Don't use a bit rate that is more
  356                  * lossy than the best.  Give a bit of leeway.
  357                  *
  358                  * Don't consider best rates that we haven't seen
  359                  * packets for yet; let sampling start inflence that.
  360                  */
  361                 if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
  362                         if (pct == -1)
  363                                 continue;
  364 #if 0
  365                         IEEE80211_NOTE(an->an_node.ni_vap,
  366                             IEEE80211_MSG_RATECTL,
  367                             &an->an_node,
  368                             "%s: size %d comparing best rate 0x%x pkts/ewma/tt (%ju/%d/%d) "
  369                             "to 0x%x pkts/ewma/tt (%ju/%d/%d)",
  370                             __func__,
  371                             bin_to_size(size_bin),
  372                             rt->info[best_rate_rix].dot11Rate,
  373                             sn->stats[size_bin][best_rate_rix].total_packets,
  374                             best_rate_pct,
  375                             best_rate_tt,
  376                             rt->info[rix].dot11Rate,
  377                             sn->stats[size_bin][rix].total_packets,
  378                             pct,
  379                             tt);
  380 #endif
  381                         if (best_rate_pct > (pct + 50))
  382                                 continue;
  383                 }
  384                 /*
  385                  * For non-MCS rates, use the current average txtime for
  386                  * comparison.
  387                  */
  388                 if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) {
  389                         if (best_rate_tt == 0 || tt <= best_rate_tt) {
  390                                 best_rate_tt = tt;
  391                                 best_rate_rix = rix;
  392                                 best_rate_pct = pct;
  393                         }
  394                 }
  395 
  396                 /*
  397                  * Since 2 and 3 stream rates have slightly higher TX times,
  398                  * allow a little bit of leeway. This should later
  399                  * be abstracted out and properly handled.
  400                  */
  401                 if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
  402                         if (best_rate_tt == 0 || ((tt * 10) <= (best_rate_tt * 10))) {
  403                                 best_rate_tt = tt;
  404                                 best_rate_rix = rix;
  405                                 best_rate_pct = pct;
  406                         }
  407                 }
  408         }
  409         return (best_rate_tt ? best_rate_rix : -1);
  410 }
  411 
  412 /*
  413  * Pick a good "random" bit-rate to sample other than the current one.
  414  */
  415 static __inline int
  416 pick_sample_rate(struct sample_softc *ssc , struct ath_node *an,
  417     const HAL_RATE_TABLE *rt, int size_bin)
  418 {
  419 #define DOT11RATE(ix)   (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
  420 #define MCS(ix)         (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
  421         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  422         int current_rix, rix;
  423         unsigned current_tt;
  424         uint64_t mask;
  425 
  426         current_rix = sn->current_rix[size_bin];
  427         if (current_rix < 0) {
  428                 /* no successes yet, send at the lowest bit-rate */
  429                 /* XXX TODO should return MCS0 if HT */
  430                 return 0;
  431         }
  432 
  433         current_tt = sn->stats[size_bin][current_rix].average_tx_time;
  434 
  435         rix = sn->last_sample_rix[size_bin]+1;  /* next sample rate */
  436         mask = sn->ratemask &~ ((uint64_t) 1<<current_rix);/* don't sample current rate */
  437         while (mask != 0) {
  438                 if ((mask & ((uint64_t) 1<<rix)) == 0) {        /* not a supported rate */
  439         nextrate:
  440                         if (++rix >= rt->rateCount)
  441                                 rix = 0;
  442                         continue;
  443                 }
  444 
  445                 /*
  446                  * The following code stops trying to sample
  447                  * non-MCS rates when speaking to an MCS node.
  448                  * However, at least for CCK rates in 2.4GHz mode,
  449                  * the non-MCS rates MAY actually provide better
  450                  * PER at the very far edge of reception.
  451                  *
  452                  * However! Until ath_rate_form_aggr() grows
  453                  * some logic to not form aggregates if the
  454                  * selected rate is non-MCS, this won't work.
  455                  *
  456                  * So don't disable this code until you've taught
  457                  * ath_rate_form_aggr() to drop out if any of
  458                  * the selected rates are non-MCS.
  459                  */
  460 #if 1
  461                 /* if the node is HT and the rate isn't HT, don't bother sample */
  462                 if ((an->an_node.ni_flags & IEEE80211_NODE_HT) &&
  463                     (rt->info[rix].phy != IEEE80211_T_HT)) {
  464                         mask &= ~((uint64_t) 1<<rix);
  465                         goto nextrate;
  466                 }
  467 #endif
  468 
  469                 /* this bit-rate is always worse than the current one */
  470                 if (sn->stats[size_bin][rix].perfect_tx_time > current_tt) {
  471                         mask &= ~((uint64_t) 1<<rix);
  472                         goto nextrate;
  473                 }
  474 
  475                 /* rarely sample bit-rates that fail a lot */
  476                 if (sn->stats[size_bin][rix].successive_failures > ssc->max_successive_failures &&
  477                     ticks - sn->stats[size_bin][rix].last_tx < ssc->stale_failure_timeout) {
  478                         mask &= ~((uint64_t) 1<<rix);
  479                         goto nextrate;
  480                 }
  481 
  482                 /*
  483                  * For HT, only sample a few rates on either side of the
  484                  * current rix; there's quite likely a lot of them.
  485                  *
  486                  * This is limited to testing rate indexes on either side of
  487                  * this MCS, but for all spatial streams.
  488                  *
  489                  * Otherwise we'll (a) never really sample higher MCS
  490                  * rates if we're stuck low, and we'll make weird moves
  491                  * like sample MCS8 if we're using MCS7.
  492                  */
  493                 if (an->an_node.ni_flags & IEEE80211_NODE_HT) {
  494                         uint8_t current_mcs, rix_mcs;
  495 
  496                         current_mcs = MCS(current_rix) & 0x7;
  497                         rix_mcs = MCS(rix) & 0x7;
  498 
  499                         if (rix_mcs < (current_mcs - 2) ||
  500                             rix_mcs > (current_mcs + 2)) {
  501                                 mask &= ~((uint64_t) 1<<rix);
  502                                 goto nextrate;
  503                         }
  504                 }
  505 
  506                 /* Don't sample more than 2 rates higher for rates > 11M for non-HT rates */
  507                 if (! (an->an_node.ni_flags & IEEE80211_NODE_HT)) {
  508                         if (DOT11RATE(rix) > 2*11 && rix > current_rix + 2) {
  509                                 mask &= ~((uint64_t) 1<<rix);
  510                                 goto nextrate;
  511                         }
  512                 }
  513 
  514                 sn->last_sample_rix[size_bin] = rix;
  515                 return rix;
  516         }
  517         return current_rix;
  518 #undef DOT11RATE
  519 #undef  MCS
  520 }
  521 
  522 static int
  523 ath_rate_get_static_rix(struct ath_softc *sc, const struct ieee80211_node *ni)
  524 {
  525 #define RATE(_ix)       (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
  526 #define DOT11RATE(_ix)  (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL)
  527 #define MCS(_ix)        (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS)
  528         const struct ieee80211_txparam *tp = ni->ni_txparms;
  529         int srate;
  530 
  531         /* Check MCS rates */
  532         for (srate = ni->ni_htrates.rs_nrates - 1; srate >= 0; srate--) {
  533                 if (MCS(srate) == tp->ucastrate)
  534                         return sc->sc_rixmap[tp->ucastrate];
  535         }
  536 
  537         /* Check legacy rates */
  538         for (srate = ni->ni_rates.rs_nrates - 1; srate >= 0; srate--) {
  539                 if (RATE(srate) == tp->ucastrate)
  540                         return sc->sc_rixmap[tp->ucastrate];
  541         }
  542         return -1;
  543 #undef  RATE
  544 #undef  DOT11RATE
  545 #undef  MCS
  546 }
  547 
  548 static void
  549 ath_rate_update_static_rix(struct ath_softc *sc, struct ieee80211_node *ni)
  550 {
  551         struct ath_node *an = ATH_NODE(ni);
  552         const struct ieee80211_txparam *tp = ni->ni_txparms;
  553         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  554 
  555         if (tp != NULL && tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
  556                 /*
  557                  * A fixed rate is to be used; ucastrate is the IEEE code
  558                  * for this rate (sans basic bit).  Check this against the
  559                  * negotiated rate set for the node.  Note the fixed rate
  560                  * may not be available for various reasons so we only
  561                  * setup the static rate index if the lookup is successful.
  562                  */
  563                 sn->static_rix = ath_rate_get_static_rix(sc, ni);
  564         } else {
  565                 sn->static_rix = -1;
  566         }
  567 }
  568 
  569 /*
  570  * Pick a non-HT rate to begin using.
  571  */
  572 static int
  573 ath_rate_pick_seed_rate_legacy(struct ath_softc *sc, struct ath_node *an,
  574     int frameLen)
  575 {
  576 #define DOT11RATE(ix)   (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
  577 #define MCS(ix)         (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
  578 #define RATE(ix)        (DOT11RATE(ix) / 2)
  579         int rix = -1;
  580         const HAL_RATE_TABLE *rt = sc->sc_currates;
  581         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  582         const int size_bin = size_to_bin(frameLen);
  583 
  584         /* no packet has been sent successfully yet */
  585         for (rix = rt->rateCount-1; rix > 0; rix--) {
  586                 if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
  587                         continue;
  588 
  589                 /* Skip HT rates */
  590                 if (rt->info[rix].phy == IEEE80211_T_HT)
  591                         continue;
  592 
  593                 /*
  594                  * Pick the highest rate <= 36 Mbps
  595                  * that hasn't failed.
  596                  */
  597                 if (DOT11RATE(rix) <= 72 &&
  598                     sn->stats[size_bin][rix].successive_failures == 0) {
  599                         break;
  600                 }
  601         }
  602         return rix;
  603 #undef  RATE
  604 #undef  MCS
  605 #undef  DOT11RATE
  606 }
  607 
  608 /*
  609  * Pick a HT rate to begin using.
  610  *
  611  * Don't use any non-HT rates; only consider HT rates.
  612  */
  613 static int
  614 ath_rate_pick_seed_rate_ht(struct ath_softc *sc, struct ath_node *an,
  615     int frameLen)
  616 {
  617 #define DOT11RATE(ix)   (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
  618 #define MCS(ix)         (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
  619 #define RATE(ix)        (DOT11RATE(ix) / 2)
  620         int rix = -1, ht_rix = -1;
  621         const HAL_RATE_TABLE *rt = sc->sc_currates;
  622         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  623         const int size_bin = size_to_bin(frameLen);
  624 
  625         /* no packet has been sent successfully yet */
  626         for (rix = rt->rateCount-1; rix > 0; rix--) {
  627                 /* Skip rates we can't use */
  628                 if ((sn->ratemask & ((uint64_t) 1<<rix)) == 0)
  629                         continue;
  630 
  631                 /* Keep a copy of the last seen HT rate index */
  632                 if (rt->info[rix].phy == IEEE80211_T_HT)
  633                         ht_rix = rix;
  634 
  635                 /* Skip non-HT rates */
  636                 if (rt->info[rix].phy != IEEE80211_T_HT)
  637                         continue;
  638 
  639                 /*
  640                  * Pick a medium-speed rate at 1 spatial stream
  641                  * which has not seen any failures.
  642                  * Higher rates may fail; we'll try them later.
  643                  */
  644                 if (((MCS(rix)& 0x7f) <= 4) &&
  645                     sn->stats[size_bin][rix].successive_failures == 0) {
  646                         break;
  647                 }
  648         }
  649 
  650         /*
  651          * If all the MCS rates have successive failures, rix should be
  652          * > 0; otherwise use the lowest MCS rix (hopefully MCS 0.)
  653          */
  654         return MAX(rix, ht_rix);
  655 #undef  RATE
  656 #undef  MCS
  657 #undef  DOT11RATE
  658 }
  659 
  660 void
  661 ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
  662                   int shortPreamble, size_t frameLen, int tid,
  663                   int is_aggr, u_int8_t *rix0, int *try0,
  664                   u_int8_t *txrate, int *maxdur, int *maxpktlen)
  665 {
  666 #define DOT11RATE(ix)   (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL)
  667 #define MCS(ix)         (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS)
  668 #define RATE(ix)        (DOT11RATE(ix) / 2)
  669         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  670         struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
  671         struct ieee80211com *ic = &sc->sc_ic;
  672         const HAL_RATE_TABLE *rt = sc->sc_currates;
  673         int size_bin = size_to_bin(frameLen);
  674         int rix, mrr, best_rix, change_rates;
  675         unsigned average_tx_time;
  676         int max_pkt_len;
  677 
  678         ath_rate_update_static_rix(sc, &an->an_node);
  679 
  680         /* For now don't take TID, is_aggr into account */
  681         /* Also for now don't calculate a max duration; that'll come later */
  682         *maxdur = -1;
  683 
  684         /*
  685          * For now just set it to the frame length; we'll optimise it later.
  686          */
  687         *maxpktlen = frameLen;
  688 
  689         if (sn->currates != sc->sc_currates) {
  690                 device_printf(sc->sc_dev, "%s: currates != sc_currates!\n",
  691                     __func__);
  692                 rix = 0;
  693                 *try0 = ATH_TXMAXTRY;
  694                 goto done;
  695         }
  696 
  697         if (sn->static_rix != -1) {
  698                 rix = sn->static_rix;
  699                 *try0 = ATH_TXMAXTRY;
  700 
  701                 /*
  702                  * Ensure we limit max packet length here too!
  703                  */
  704                 max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an,
  705                     sn->static_rix,
  706                     is_aggr);
  707                 if (max_pkt_len > 0) {
  708                         *maxpktlen = frameLen = MIN(frameLen, max_pkt_len);
  709                         size_bin = size_to_bin(frameLen);
  710                 }
  711                 goto done;
  712         }
  713 
  714         mrr = sc->sc_mrretry;
  715         /* XXX check HT protmode too */
  716         /* XXX turn into a cap; 11n MACs support MRR+RTSCTS */
  717         if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot))
  718                 mrr = 0;
  719 
  720         best_rix = pick_best_rate(an, rt, size_bin, !mrr);
  721 
  722         /*
  723          * At this point we've chosen the best rix, so now we
  724          * need to potentially update our maximum packet length
  725          * and size_bin if we're doing 11n rates.
  726          */
  727         max_pkt_len = ath_rate_sample_find_min_pktlength(sc, an, best_rix,
  728             is_aggr);
  729         if (max_pkt_len > 0) {
  730 #if 0
  731                 device_printf(sc->sc_dev,
  732                     "Limiting maxpktlen from %d to %d bytes\n",
  733                     (int) frameLen, max_pkt_len);
  734 #endif
  735                 *maxpktlen = frameLen = MIN(frameLen, max_pkt_len);
  736                 size_bin = size_to_bin(frameLen);
  737         }
  738 
  739         if (best_rix >= 0) {
  740                 average_tx_time = sn->stats[size_bin][best_rix].average_tx_time;
  741         } else {
  742                 average_tx_time = 0;
  743         }
  744 
  745         /*
  746          * Limit the time measuring the performance of other tx
  747          * rates to sample_rate% of the total transmission time.
  748          */
  749         if (sn->sample_tt[size_bin] <
  750             average_tx_time *
  751             (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) {
  752                 rix = pick_sample_rate(ssc, an, rt, size_bin);
  753                 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
  754                      &an->an_node, "att %d sample_tt %d size %u "
  755                      "sample rate %d %s current rate %d %s",
  756                      average_tx_time,
  757                      sn->sample_tt[size_bin],
  758                      bin_to_size(size_bin),
  759                      dot11rate(rt, rix),
  760                      dot11rate_label(rt, rix),
  761                      dot11rate(rt, sn->current_rix[size_bin]),
  762                      dot11rate_label(rt, sn->current_rix[size_bin]));
  763                 if (rix != sn->current_rix[size_bin]) {
  764                         sn->current_sample_rix[size_bin] = rix;
  765                 } else {
  766                         sn->current_sample_rix[size_bin] = -1;
  767                 }
  768                 sn->packets_since_sample[size_bin] = 0;
  769         } else {
  770                 change_rates = 0;
  771                 if (!sn->packets_sent[size_bin] || best_rix == -1) {
  772                         /* no packet has been sent successfully yet */
  773                         change_rates = 1;
  774                         if (an->an_node.ni_flags & IEEE80211_NODE_HT)
  775                                 best_rix =
  776                                     ath_rate_pick_seed_rate_ht(sc, an, frameLen);
  777                         else
  778                                 best_rix =
  779                                     ath_rate_pick_seed_rate_legacy(sc, an, frameLen);
  780                 } else if (sn->packets_sent[size_bin] < 20) {
  781                         /* let the bit-rate switch quickly during the first few packets */
  782                         IEEE80211_NOTE(an->an_node.ni_vap,
  783                             IEEE80211_MSG_RATECTL, &an->an_node,
  784                             "%s: switching quickly..", __func__);
  785                         change_rates = 1;
  786                 } else if (ticks - ssc->min_switch > sn->ticks_since_switch[size_bin]) {
  787                         /* min_switch seconds have gone by */
  788                         IEEE80211_NOTE(an->an_node.ni_vap,
  789                             IEEE80211_MSG_RATECTL, &an->an_node,
  790                             "%s: min_switch %d > ticks_since_switch %d..",
  791                             __func__, ticks - ssc->min_switch, sn->ticks_since_switch[size_bin]);
  792                         change_rates = 1;
  793                 } else if ((! (an->an_node.ni_flags & IEEE80211_NODE_HT)) &&
  794                     (2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time)) {
  795                         /* the current bit-rate is twice as slow as the best one */
  796                         IEEE80211_NOTE(an->an_node.ni_vap,
  797                             IEEE80211_MSG_RATECTL, &an->an_node,
  798                             "%s: 2x att (= %d) < cur_rix att %d",
  799                             __func__,
  800                             2 * average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time);
  801                         change_rates = 1;
  802                 } else if ((an->an_node.ni_flags & IEEE80211_NODE_HT)) {
  803                         int cur_rix = sn->current_rix[size_bin];
  804                         int cur_att = sn->stats[size_bin][cur_rix].average_tx_time;
  805                         /*
  806                          * If the node is HT, it if the rate isn't the
  807                          * same and the average tx time is within 10%
  808                          * of the current rate. It can fail a little.
  809                          *
  810                          * This is likely not optimal!
  811                          */
  812 #if 0
  813                         printf("cur rix/att %x/%d, best rix/att %x/%d\n",
  814                             MCS(cur_rix), cur_att, MCS(best_rix), average_tx_time);
  815 #endif
  816                         if ((best_rix != cur_rix) &&
  817                             (average_tx_time * 9) <= (cur_att * 10)) {
  818                                 IEEE80211_NOTE(an->an_node.ni_vap,
  819                                     IEEE80211_MSG_RATECTL, &an->an_node,
  820                                     "%s: HT: size %d best_rix 0x%x > "
  821                                     " cur_rix 0x%x, average_tx_time %d,"
  822                                     " cur_att %d",
  823                                     __func__, bin_to_size(size_bin),
  824                                     MCS(best_rix), MCS(cur_rix),
  825                                     average_tx_time, cur_att);
  826                                 change_rates = 1;
  827                         }
  828                 }
  829 
  830                 sn->packets_since_sample[size_bin]++;
  831                 
  832                 if (change_rates) {
  833                         if (best_rix != sn->current_rix[size_bin]) {
  834                                 IEEE80211_NOTE(an->an_node.ni_vap,
  835                                     IEEE80211_MSG_RATECTL,
  836                                     &an->an_node,
  837 "%s: size %d switch rate %d %s (%d/%d) EWMA %d -> %d %s (%d/%d) EWMA %d after %d packets mrr %d",
  838                                     __func__,
  839                                     bin_to_size(size_bin),
  840                                     dot11rate(rt, sn->current_rix[size_bin]),
  841                                     dot11rate_label(rt, sn->current_rix[size_bin]),
  842                                     sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time,
  843                                     sn->stats[size_bin][sn->current_rix[size_bin]].perfect_tx_time,
  844                                     sn->stats[size_bin][sn->current_rix[size_bin]].ewma_pct,
  845                                     dot11rate(rt, best_rix),
  846                                     dot11rate_label(rt, best_rix),
  847                                     sn->stats[size_bin][best_rix].average_tx_time,
  848                                     sn->stats[size_bin][best_rix].perfect_tx_time,
  849                                     sn->stats[size_bin][best_rix].ewma_pct,
  850                                     sn->packets_since_switch[size_bin],
  851                                     mrr);
  852                         }
  853                         sn->packets_since_switch[size_bin] = 0;
  854                         sn->current_rix[size_bin] = best_rix;
  855                         sn->ticks_since_switch[size_bin] = ticks;
  856                         /* 
  857                          * Set the visible txrate for this node.
  858                          */
  859                         an->an_node.ni_txrate =
  860                             (rt->info[best_rix].phy == IEEE80211_T_HT) ?
  861                              MCS(best_rix) : DOT11RATE(best_rix);
  862                 }
  863                 rix = sn->current_rix[size_bin];
  864                 sn->packets_since_switch[size_bin]++;
  865         }
  866         *try0 = mrr ? sn->sched[rix].t0 : ATH_TXMAXTRY;
  867 done:
  868 
  869         /*
  870          * This bug totally sucks and should be fixed.
  871          *
  872          * For now though, let's not panic, so we can start to figure
  873          * out how to better reproduce it.
  874          */
  875         if (rix < 0 || rix >= rt->rateCount) {
  876                 printf("%s: ERROR: rix %d out of bounds (rateCount=%d)\n",
  877                     __func__,
  878                     rix,
  879                     rt->rateCount);
  880                     rix = 0;    /* XXX just default for now */
  881         }
  882         KASSERT(rix >= 0 && rix < rt->rateCount, ("rix is %d", rix));
  883 
  884         *rix0 = rix;
  885         *txrate = rt->info[rix].rateCode
  886                 | (shortPreamble ? rt->info[rix].shortPreamble : 0);
  887         sn->packets_sent[size_bin]++;
  888 
  889 #undef DOT11RATE
  890 #undef MCS
  891 #undef RATE
  892 }
  893 
  894 /*
  895  * Get the TX rates. Don't fiddle with short preamble flags for them;
  896  * the caller can do that.
  897  */
  898 void
  899 ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
  900     uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
  901 {
  902         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  903         const struct txschedule *sched = &sn->sched[rix0];
  904 
  905         KASSERT(rix0 == sched->r0, ("rix0 (%x) != sched->r0 (%x)!\n",
  906             rix0, sched->r0));
  907 
  908         rc[0].flags = rc[1].flags = rc[2].flags = rc[3].flags = 0;
  909 
  910         rc[0].rix = sched->r0;
  911         rc[1].rix = sched->r1;
  912         rc[2].rix = sched->r2;
  913         rc[3].rix = sched->r3;
  914 
  915         rc[0].tries = sched->t0;
  916         rc[1].tries = sched->t1;
  917 
  918         if (is_aggr) {
  919                 rc[2].tries = rc[3].tries = 0;
  920         } else {
  921                 rc[2].tries = sched->t2;
  922                 rc[3].tries = sched->t3;
  923         }
  924 }
  925 
  926 void
  927 ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
  928                       struct ath_desc *ds, int shortPreamble, u_int8_t rix)
  929 {
  930         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  931         const struct txschedule *sched = &sn->sched[rix];
  932         const HAL_RATE_TABLE *rt = sc->sc_currates;
  933         uint8_t rix1, s1code, rix2, s2code, rix3, s3code;
  934 
  935         /* XXX precalculate short preamble tables */
  936         rix1 = sched->r1;
  937         s1code = rt->info[rix1].rateCode
  938                | (shortPreamble ? rt->info[rix1].shortPreamble : 0);
  939         rix2 = sched->r2;
  940         s2code = rt->info[rix2].rateCode
  941                | (shortPreamble ? rt->info[rix2].shortPreamble : 0);
  942         rix3 = sched->r3;
  943         s3code = rt->info[rix3].rateCode
  944                | (shortPreamble ? rt->info[rix3].shortPreamble : 0);
  945         ath_hal_setupxtxdesc(sc->sc_ah, ds,
  946             s1code, sched->t1,          /* series 1 */
  947             s2code, sched->t2,          /* series 2 */
  948             s3code, sched->t3);         /* series 3 */
  949 }
  950 
  951 /*
  952  * Update the current statistics.
  953  *
  954  * Note that status is for the FINAL transmit status, not this
  955  * particular attempt.  So, check if tries > tries0 and if so
  956  * assume this status failed.
  957  *
  958  * This is important because some failures are due to both
  959  * short AND long retries; if the final issue was a short
  960  * retry failure then we still want to account for the
  961  * bad long retry attempts.
  962  */
  963 static void
  964 update_stats(struct ath_softc *sc, struct ath_node *an, 
  965                   int frame_size,
  966                   int rix0, int tries0,
  967                   int short_tries, int tries, int status,
  968                   int nframes, int nbad)
  969 {
  970         struct sample_node *sn = ATH_NODE_SAMPLE(an);
  971         struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
  972 #ifdef IEEE80211_DEBUG
  973         const HAL_RATE_TABLE *rt = sc->sc_currates;
  974 #endif
  975         const int size_bin = size_to_bin(frame_size);
  976         const int size = bin_to_size(size_bin);
  977         int tt;
  978         int is_ht40 = (an->an_node.ni_chw == 40);
  979         int pct;
  980 
  981         if (!IS_RATE_DEFINED(sn, rix0))
  982                 return;
  983 
  984         /*
  985          * Treat long retries as us exceeding retries, even
  986          * if the eventual attempt at some other MRR schedule
  987          * succeeded.
  988          */
  989         if (tries > tries0) {
  990                 status = HAL_TXERR_XRETRY;
  991         }
  992 
  993         /*
  994          * If status is FAIL then we treat all frames as bad.
  995          * This better accurately tracks EWMA and average TX time
  996          * because even if the eventual transmission succeeded,
  997          * transmission at this rate did not.
  998          */
  999         if (status != 0)
 1000                 nbad = nframes;
 1001 
 1002         /*
 1003          * Ignore short tries count as contributing to failure.
 1004          * Right now there's no way to know if it's part of any
 1005          * given rate attempt, and outside of the RTS/CTS management
 1006          * rate, it doesn't /really/ help.
 1007          */
 1008         tt = calc_usecs_unicast_packet(sc, size, rix0,
 1009             0 /* short_tries */, MIN(tries0, tries) - 1, is_ht40);
 1010 
 1011         if (sn->stats[size_bin][rix0].total_packets < ssc->smoothing_minpackets) {
 1012                 /* just average the first few packets */
 1013                 int avg_tx = sn->stats[size_bin][rix0].average_tx_time;
 1014                 int packets = sn->stats[size_bin][rix0].total_packets;
 1015                 sn->stats[size_bin][rix0].average_tx_time = (tt+(avg_tx*packets))/(packets+nframes);
 1016         } else {
 1017                 /* use a ewma */
 1018                 sn->stats[size_bin][rix0].average_tx_time = 
 1019                         ((sn->stats[size_bin][rix0].average_tx_time * ssc->smoothing_rate) + 
 1020                          (tt * (100 - ssc->smoothing_rate))) / 100;
 1021         }
 1022 
 1023         if (nframes == nbad) {
 1024                 sn->stats[size_bin][rix0].successive_failures += nbad;
 1025         } else {
 1026                 sn->stats[size_bin][rix0].packets_acked += (nframes - nbad);
 1027                 sn->stats[size_bin][rix0].successive_failures = 0;
 1028         }
 1029         sn->stats[size_bin][rix0].tries += tries;
 1030         sn->stats[size_bin][rix0].last_tx = ticks;
 1031         sn->stats[size_bin][rix0].total_packets += nframes;
 1032 
 1033         /* update EWMA for this rix */
 1034 
 1035         /* Calculate percentage based on current rate */
 1036         if (nframes == 0)
 1037                 nframes = nbad = 1;
 1038         pct = ((nframes - nbad) * 1000) / nframes;
 1039 
 1040         if (sn->stats[size_bin][rix0].total_packets <
 1041             ssc->smoothing_minpackets) {
 1042                 /* just average the first few packets */
 1043                 int a_pct = (sn->stats[size_bin][rix0].packets_acked * 1000) /
 1044                     (sn->stats[size_bin][rix0].total_packets);
 1045                 sn->stats[size_bin][rix0].ewma_pct = a_pct;
 1046         } else {
 1047                 /* use a ewma */
 1048                 sn->stats[size_bin][rix0].ewma_pct =
 1049                         ((sn->stats[size_bin][rix0].ewma_pct * ssc->smoothing_rate) +
 1050                          (pct * (100 - ssc->smoothing_rate))) / 100;
 1051         }
 1052 
 1053         /*
 1054          * Only update the sample time for the initial sample rix.
 1055          * We've updated the statistics on each of the other retries
 1056          * fine, but we should only update the sample_tt with what
 1057          * was actually sampled.
 1058          *
 1059          * However, to aide in debugging, log all the failures for
 1060          * each of the buckets
 1061          */
 1062         IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
 1063            &an->an_node,
 1064             "%s: size %d %s %s rate %d %s tries (%d/%d) tt %d "
 1065             "avg_tt (%d/%d) nfrm %d nbad %d",
 1066             __func__,
 1067             size,
 1068             status ? "FAIL" : "OK",
 1069             rix0 == sn->current_sample_rix[size_bin] ? "sample" : "mrr",
 1070             dot11rate(rt, rix0),
 1071             dot11rate_label(rt, rix0),
 1072             short_tries, tries, tt, 
 1073             sn->stats[size_bin][rix0].average_tx_time,
 1074             sn->stats[size_bin][rix0].perfect_tx_time,
 1075             nframes, nbad);
 1076 
 1077         if (rix0 == sn->current_sample_rix[size_bin]) {
 1078                 sn->sample_tt[size_bin] = tt;
 1079                 sn->current_sample_rix[size_bin] = -1;
 1080         }
 1081 }
 1082 
 1083 static void
 1084 badrate(struct ath_softc *sc, int series, int hwrate, int tries, int status)
 1085 {
 1086 
 1087         device_printf(sc->sc_dev,
 1088             "bad series%d hwrate 0x%x, tries %u ts_status 0x%x\n",
 1089             series, hwrate, tries, status);
 1090 }
 1091 
 1092 void
 1093 ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
 1094         const struct ath_rc_series *rc, const struct ath_tx_status *ts,
 1095         int frame_size, int rc_framesize, int nframes, int nbad)
 1096 {
 1097         struct ieee80211com *ic = &sc->sc_ic;
 1098         struct sample_node *sn = ATH_NODE_SAMPLE(an);
 1099         int final_rix, short_tries, long_tries;
 1100         const HAL_RATE_TABLE *rt = sc->sc_currates;
 1101         int status = ts->ts_status;
 1102         int mrr;
 1103 
 1104         final_rix = rt->rateCodeToIndex[ts->ts_rate];
 1105         short_tries = ts->ts_shortretry;
 1106         long_tries = ts->ts_longretry + 1;
 1107 
 1108         if (nframes == 0) {
 1109                 device_printf(sc->sc_dev, "%s: nframes=0?\n", __func__);
 1110                 return;
 1111         }
 1112 
 1113         if (frame_size == 0)                /* NB: should not happen */
 1114                 frame_size = 1500;
 1115         if (rc_framesize == 0)              /* NB: should not happen */
 1116                 rc_framesize = 1500;
 1117 
 1118         /*
 1119          * There are still some places where what rate control set as
 1120          * a limit but the hardware decided, for some reason, to transmit
 1121          * at a smaller size that fell into a different bucket.
 1122          *
 1123          * The eternal question here is - which size_bin should it go in?
 1124          * The one that was requested, or the one that was transmitted?
 1125          *
 1126          * Here's the problem - if we use the one that was transmitted,
 1127          * we may continue to hit corner cases where we make a rate
 1128          * selection using a higher bin but only update the smaller bin;
 1129          * thus never really "adapting".
 1130          *
 1131          * If however we update the larger bin, we're not accurately
 1132          * representing the channel state at that frame/aggregate size.
 1133          * However if we keep hitting the larger request but completing
 1134          * a smaller size, we at least updates based on what the
 1135          * request was /for/.
 1136          *
 1137          * I'm going to err on the side of caution and choose the
 1138          * latter.
 1139          */
 1140         if (size_to_bin(frame_size) != size_to_bin(rc_framesize)) {
 1141 #if 0
 1142                 device_printf(sc->sc_dev,
 1143                     "%s: completed but frame size buckets mismatch "
 1144                     "(completed %d tx'ed %d)\n",
 1145                     __func__, frame_size, rc_framesize);
 1146 #endif
 1147                 frame_size = rc_framesize;
 1148         }
 1149 
 1150         if (sn->ratemask == 0) {
 1151                 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
 1152                     &an->an_node,
 1153                     "%s: size %d %s rate/try %d/%d no rates yet", 
 1154                     __func__,
 1155                     bin_to_size(size_to_bin(frame_size)),
 1156                     status ? "FAIL" : "OK",
 1157                     short_tries, long_tries);
 1158                 return;
 1159         }
 1160         mrr = sc->sc_mrretry;
 1161         /* XXX check HT protmode too */
 1162         if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot))
 1163                 mrr = 0;
 1164 
 1165         if (!mrr || ts->ts_finaltsi == 0) {
 1166                 if (!IS_RATE_DEFINED(sn, final_rix)) {
 1167                         device_printf(sc->sc_dev,
 1168                             "%s: ts_rate=%d ts_finaltsi=%d, final_rix=%d\n",
 1169                             __func__, ts->ts_rate, ts->ts_finaltsi, final_rix);
 1170                         badrate(sc, 0, ts->ts_rate, long_tries, status);
 1171                         return;
 1172                 }
 1173                 /*
 1174                  * Only one rate was used; optimize work.
 1175                  */
 1176                 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
 1177                      &an->an_node, "%s: size %d (%d bytes) %s rate/short/long %d %s/%d/%d nframes/nbad [%d/%d]",
 1178                      __func__,
 1179                      bin_to_size(size_to_bin(frame_size)),
 1180                      frame_size,
 1181                      status ? "FAIL" : "OK",
 1182                      dot11rate(rt, final_rix), dot11rate_label(rt, final_rix),
 1183                      short_tries, long_tries, nframes, nbad);
 1184                 update_stats(sc, an, frame_size, 
 1185                              final_rix, long_tries,
 1186                              short_tries, long_tries, status,
 1187                              nframes, nbad);
 1188 
 1189         } else {
 1190                 int finalTSIdx = ts->ts_finaltsi;
 1191                 int i;
 1192 
 1193                 /*
 1194                  * Process intermediate rates that failed.
 1195                  */
 1196 
 1197                 IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL,
 1198                     &an->an_node,
 1199 "%s: size %d (%d bytes) finaltsidx %d short %d long %d %s rate/try [%d %s/%d %d %s/%d %d %s/%d %d %s/%d] nframes/nbad [%d/%d]", 
 1200                      __func__,
 1201                      bin_to_size(size_to_bin(frame_size)),
 1202                      frame_size,
 1203                      finalTSIdx,
 1204                      short_tries,
 1205                      long_tries,
 1206                      status ? "FAIL" : "OK",
 1207                      dot11rate(rt, rc[0].rix),
 1208                       dot11rate_label(rt, rc[0].rix), rc[0].tries,
 1209                      dot11rate(rt, rc[1].rix),
 1210                       dot11rate_label(rt, rc[1].rix), rc[1].tries,
 1211                      dot11rate(rt, rc[2].rix),
 1212                       dot11rate_label(rt, rc[2].rix), rc[2].tries,
 1213                      dot11rate(rt, rc[3].rix),
 1214                       dot11rate_label(rt, rc[3].rix), rc[3].tries,
 1215                      nframes, nbad);
 1216 
 1217                 for (i = 0; i < 4; i++) {
 1218                         if (rc[i].tries && !IS_RATE_DEFINED(sn, rc[i].rix))
 1219                                 badrate(sc, 0, rc[i].ratecode, rc[i].tries,
 1220                                     status);
 1221                 }
 1222 
 1223                 /*
 1224                  * This used to not penalise other tries because loss
 1225                  * can be bursty, but it's then not accurately keeping
 1226                  * the avg TX time and EWMA updated.
 1227                  */
 1228                 if (rc[0].tries) {
 1229                         update_stats(sc, an, frame_size,
 1230                                      rc[0].rix, rc[0].tries,
 1231                                      short_tries, long_tries,
 1232                                      status,
 1233                                      nframes, nbad);
 1234                         long_tries -= rc[0].tries;
 1235                 }
 1236                 
 1237                 if (rc[1].tries && finalTSIdx > 0) {
 1238                         update_stats(sc, an, frame_size,
 1239                                      rc[1].rix, rc[1].tries,
 1240                                      short_tries, long_tries,
 1241                                      status,
 1242                                      nframes, nbad);
 1243                         long_tries -= rc[1].tries;
 1244                 }
 1245 
 1246                 if (rc[2].tries && finalTSIdx > 1) {
 1247                         update_stats(sc, an, frame_size,
 1248                                      rc[2].rix, rc[2].tries,
 1249                                      short_tries, long_tries,
 1250                                      status,
 1251                                      nframes, nbad);
 1252                         long_tries -= rc[2].tries;
 1253                 }
 1254 
 1255                 if (rc[3].tries && finalTSIdx > 2) {
 1256                         update_stats(sc, an, frame_size,
 1257                                      rc[3].rix, rc[3].tries,
 1258                                      short_tries, long_tries,
 1259                                      status,
 1260                                      nframes, nbad);
 1261                 }
 1262         }
 1263 }
 1264 
 1265 void
 1266 ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
 1267 {
 1268         if (isnew)
 1269                 ath_rate_ctl_reset(sc, &an->an_node);
 1270 }
 1271 
 1272 void
 1273 ath_rate_update_rx_rssi(struct ath_softc *sc, struct ath_node *an, int rssi)
 1274 {
 1275 }
 1276 
 1277 static const struct txschedule *mrr_schedules[IEEE80211_MODE_MAX+2] = {
 1278         NULL,           /* IEEE80211_MODE_AUTO */
 1279         series_11a,     /* IEEE80211_MODE_11A */
 1280         series_11g,     /* IEEE80211_MODE_11B */
 1281         series_11g,     /* IEEE80211_MODE_11G */
 1282         NULL,           /* IEEE80211_MODE_FH */
 1283         series_11a,     /* IEEE80211_MODE_TURBO_A */
 1284         series_11g,     /* IEEE80211_MODE_TURBO_G */
 1285         series_11a,     /* IEEE80211_MODE_STURBO_A */
 1286         series_11na,    /* IEEE80211_MODE_11NA */
 1287         series_11ng,    /* IEEE80211_MODE_11NG */
 1288         series_half,    /* IEEE80211_MODE_HALF */
 1289         series_quarter, /* IEEE80211_MODE_QUARTER */
 1290 };
 1291 
 1292 /*
 1293  * Initialize the tables for a node.
 1294  */
 1295 static void
 1296 ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
 1297 {
 1298 #define RATE(_ix)       (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
 1299 #define DOT11RATE(_ix)  (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL)
 1300 #define MCS(_ix)        (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS)
 1301         struct ath_node *an = ATH_NODE(ni);
 1302         struct sample_node *sn = ATH_NODE_SAMPLE(an);
 1303         const HAL_RATE_TABLE *rt = sc->sc_currates;
 1304         int x, y, rix;
 1305 
 1306         KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
 1307 
 1308         KASSERT(sc->sc_curmode < IEEE80211_MODE_MAX+2,
 1309             ("curmode %u", sc->sc_curmode));
 1310 
 1311         sn->sched = mrr_schedules[sc->sc_curmode];
 1312         KASSERT(sn->sched != NULL,
 1313             ("no mrr schedule for mode %u", sc->sc_curmode));
 1314 
 1315         sn->static_rix = -1;
 1316         ath_rate_update_static_rix(sc, ni);
 1317 
 1318         sn->currates = sc->sc_currates;
 1319 
 1320         /*
 1321          * Construct a bitmask of usable rates.  This has all
 1322          * negotiated rates minus those marked by the hal as
 1323          * to be ignored for doing rate control.
 1324          */
 1325         sn->ratemask = 0;
 1326         /* MCS rates */
 1327         if (ni->ni_flags & IEEE80211_NODE_HT) {
 1328                 for (x = 0; x < ni->ni_htrates.rs_nrates; x++) {
 1329                         rix = sc->sc_rixmap[MCS(x)];
 1330                         if (rix == 0xff)
 1331                                 continue;
 1332                         /* skip rates marked broken by hal */
 1333                         if (!rt->info[rix].valid)
 1334                                 continue;
 1335                         KASSERT(rix < SAMPLE_MAXRATES,
 1336                             ("mcs %u has rix %d", MCS(x), rix));
 1337                         sn->ratemask |= (uint64_t) 1<<rix;
 1338                 }
 1339         }
 1340 
 1341         /* Legacy rates */
 1342         for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
 1343                 rix = sc->sc_rixmap[RATE(x)];
 1344                 if (rix == 0xff)
 1345                         continue;
 1346                 /* skip rates marked broken by hal */
 1347                 if (!rt->info[rix].valid)
 1348                         continue;
 1349                 KASSERT(rix < SAMPLE_MAXRATES,
 1350                     ("rate %u has rix %d", RATE(x), rix));
 1351                 sn->ratemask |= (uint64_t) 1<<rix;
 1352         }
 1353 #ifdef IEEE80211_DEBUG
 1354         if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) {
 1355                 uint64_t mask;
 1356 
 1357                 ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt",
 1358                     ni->ni_macaddr, ":", __func__);
 1359                 for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
 1360                         if ((mask & 1) == 0)
 1361                                 continue;
 1362                         printf(" %d %s/%d", dot11rate(rt, rix), dot11rate_label(rt, rix),
 1363                             calc_usecs_unicast_packet(sc, 1600, rix, 0,0,
 1364                                 (ni->ni_chw == 40)));
 1365                 }
 1366                 printf("\n");
 1367         }
 1368 #endif
 1369         for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
 1370                 int size = bin_to_size(y);
 1371                 uint64_t mask;
 1372 
 1373                 sn->packets_sent[y] = 0;
 1374                 sn->current_sample_rix[y] = -1;
 1375                 sn->last_sample_rix[y] = 0;
 1376                 /* XXX start with first valid rate */
 1377                 sn->current_rix[y] = ffs(sn->ratemask)-1;
 1378                 
 1379                 /*
 1380                  * Initialize the statistics buckets; these are
 1381                  * indexed by the rate code index.
 1382                  */
 1383                 for (rix = 0, mask = sn->ratemask; mask != 0; rix++, mask >>= 1) {
 1384                         if ((mask & 1) == 0)            /* not a valid rate */
 1385                                 continue;
 1386                         sn->stats[y][rix].successive_failures = 0;
 1387                         sn->stats[y][rix].tries = 0;
 1388                         sn->stats[y][rix].total_packets = 0;
 1389                         sn->stats[y][rix].packets_acked = 0;
 1390                         sn->stats[y][rix].last_tx = 0;
 1391                         sn->stats[y][rix].ewma_pct = 0;
 1392                         
 1393                         sn->stats[y][rix].perfect_tx_time =
 1394                             calc_usecs_unicast_packet(sc, size, rix, 0, 0,
 1395                             (ni->ni_chw == 40));
 1396                         sn->stats[y][rix].average_tx_time =
 1397                             sn->stats[y][rix].perfect_tx_time;
 1398                 }
 1399         }
 1400 #if 0
 1401         /* XXX 0, num_rates-1 are wrong */
 1402         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
 1403             "%s: %d rates %d%sMbps (%dus)- %d%sMbps (%dus)", __func__, 
 1404             sn->num_rates,
 1405             DOT11RATE(0)/2, DOT11RATE(0) % 1 ? ".5" : "",
 1406             sn->stats[1][0].perfect_tx_time,
 1407             DOT11RATE(sn->num_rates-1)/2, DOT11RATE(sn->num_rates-1) % 1 ? ".5" : "",
 1408             sn->stats[1][sn->num_rates-1].perfect_tx_time
 1409         );
 1410 #endif
 1411         /* set the visible bit-rate */
 1412         if (sn->static_rix != -1)
 1413                 ni->ni_txrate = DOT11RATE(sn->static_rix);
 1414         else
 1415                 ni->ni_txrate = RATE(0);
 1416 #undef RATE
 1417 #undef DOT11RATE
 1418 }
 1419 
 1420 /*
 1421  * Fetch the statistics for the given node.
 1422  *
 1423  * The ieee80211 node must be referenced and unlocked, however the ath_node
 1424  * must be locked.
 1425  *
 1426  * The main difference here is that we convert the rate indexes
 1427  * to 802.11 rates, or the userland output won't make much sense
 1428  * as it has no access to the rix table.
 1429  */
 1430 int
 1431 ath_rate_fetch_node_stats(struct ath_softc *sc, struct ath_node *an,
 1432     struct ath_rateioctl *rs)
 1433 {
 1434         struct sample_node *sn = ATH_NODE_SAMPLE(an);
 1435         const HAL_RATE_TABLE *rt = sc->sc_currates;
 1436         struct ath_rateioctl_tlv av;
 1437         struct ath_rateioctl_rt *tv;
 1438         int y;
 1439         int o = 0;
 1440 
 1441         ATH_NODE_LOCK_ASSERT(an);
 1442 
 1443         /*
 1444          * Ensure there's enough space for the statistics.
 1445          */
 1446         if (rs->len <
 1447             sizeof(struct ath_rateioctl_tlv) +
 1448             sizeof(struct ath_rateioctl_rt) +
 1449             sizeof(struct ath_rateioctl_tlv) +
 1450             sizeof(struct sample_node)) {
 1451                 device_printf(sc->sc_dev, "%s: len=%d, too short\n",
 1452                     __func__,
 1453                     rs->len);
 1454                 return (EINVAL);
 1455         }
 1456 
 1457         /*
 1458          * Take a temporary copy of the sample node state so we can
 1459          * modify it before we copy it.
 1460          */
 1461         tv = malloc(sizeof(struct ath_rateioctl_rt), M_TEMP,
 1462             M_NOWAIT | M_ZERO);
 1463         if (tv == NULL) {
 1464                 return (ENOMEM);
 1465         }
 1466 
 1467         /*
 1468          * Populate the rate table mapping TLV.
 1469          */
 1470         tv->nentries = rt->rateCount;
 1471         for (y = 0; y < rt->rateCount; y++) {
 1472                 tv->ratecode[y] = rt->info[y].dot11Rate & IEEE80211_RATE_VAL;
 1473                 if (rt->info[y].phy == IEEE80211_T_HT)
 1474                         tv->ratecode[y] |= IEEE80211_RATE_MCS;
 1475         }
 1476 
 1477         o = 0;
 1478         /*
 1479          * First TLV - rate code mapping
 1480          */
 1481         av.tlv_id = ATH_RATE_TLV_RATETABLE;
 1482         av.tlv_len = sizeof(struct ath_rateioctl_rt);
 1483         copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv));
 1484         o += sizeof(struct ath_rateioctl_tlv);
 1485         copyout(tv, rs->buf + o, sizeof(struct ath_rateioctl_rt));
 1486         o += sizeof(struct ath_rateioctl_rt);
 1487 
 1488         /*
 1489          * Second TLV - sample node statistics
 1490          */
 1491         av.tlv_id = ATH_RATE_TLV_SAMPLENODE;
 1492         av.tlv_len = sizeof(struct sample_node);
 1493         copyout(&av, rs->buf + o, sizeof(struct ath_rateioctl_tlv));
 1494         o += sizeof(struct ath_rateioctl_tlv);
 1495 
 1496         /*
 1497          * Copy the statistics over to the provided buffer.
 1498          */
 1499         copyout(sn, rs->buf + o, sizeof(struct sample_node));
 1500         o += sizeof(struct sample_node);
 1501 
 1502         free(tv, M_TEMP);
 1503 
 1504         return (0);
 1505 }
 1506 
 1507 static void
 1508 sample_stats(void *arg, struct ieee80211_node *ni)
 1509 {
 1510         struct ath_softc *sc = arg;
 1511         const HAL_RATE_TABLE *rt = sc->sc_currates;
 1512         struct sample_node *sn = ATH_NODE_SAMPLE(ATH_NODE(ni));
 1513         uint64_t mask;
 1514         int rix, y;
 1515 
 1516         printf("\n[%s] refcnt %d static_rix (%d %s) ratemask 0x%jx\n",
 1517             ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni),
 1518             dot11rate(rt, sn->static_rix),
 1519             dot11rate_label(rt, sn->static_rix),
 1520             (uintmax_t)sn->ratemask);
 1521         for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
 1522                 printf("[%4u] cur rix %d (%d %s) since switch: packets %d ticks %u\n",
 1523                     bin_to_size(y), sn->current_rix[y],
 1524                     dot11rate(rt, sn->current_rix[y]),
 1525                     dot11rate_label(rt, sn->current_rix[y]),
 1526                     sn->packets_since_switch[y], sn->ticks_since_switch[y]);
 1527                 printf("[%4u] last sample (%d %s) cur sample (%d %s) packets sent %d\n",
 1528                     bin_to_size(y),
 1529                     dot11rate(rt, sn->last_sample_rix[y]),
 1530                     dot11rate_label(rt, sn->last_sample_rix[y]),
 1531                     dot11rate(rt, sn->current_sample_rix[y]),
 1532                     dot11rate_label(rt, sn->current_sample_rix[y]),
 1533                     sn->packets_sent[y]);
 1534                 printf("[%4u] packets since sample %d sample tt %u\n",
 1535                     bin_to_size(y), sn->packets_since_sample[y],
 1536                     sn->sample_tt[y]);
 1537         }
 1538         for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) {
 1539                 if ((mask & 1) == 0)
 1540                                 continue;
 1541                 for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
 1542                         if (sn->stats[y][rix].total_packets == 0)
 1543                                 continue;
 1544                         printf("[%2u %s:%4u] %8ju:%-8ju (%3d%%) (EWMA %3d.%1d%%) T %8ju F %4d avg %5u last %u\n",
 1545                             dot11rate(rt, rix), dot11rate_label(rt, rix),
 1546                             bin_to_size(y),
 1547                             (uintmax_t) sn->stats[y][rix].total_packets,
 1548                             (uintmax_t) sn->stats[y][rix].packets_acked,
 1549                             (int) ((sn->stats[y][rix].packets_acked * 100ULL) /
 1550                              sn->stats[y][rix].total_packets),
 1551                             sn->stats[y][rix].ewma_pct / 10,
 1552                             sn->stats[y][rix].ewma_pct % 10,
 1553                             (uintmax_t) sn->stats[y][rix].tries,
 1554                             sn->stats[y][rix].successive_failures,
 1555                             sn->stats[y][rix].average_tx_time,
 1556                             ticks - sn->stats[y][rix].last_tx);
 1557                 }
 1558         }
 1559 }
 1560 
 1561 static int
 1562 ath_rate_sysctl_stats(SYSCTL_HANDLER_ARGS)
 1563 {
 1564         struct ath_softc *sc = arg1;
 1565         struct ieee80211com *ic = &sc->sc_ic;
 1566         int error, v;
 1567 
 1568         v = 0;
 1569         error = sysctl_handle_int(oidp, &v, 0, req);
 1570         if (error || !req->newptr)
 1571                 return error;
 1572         ieee80211_iterate_nodes(&ic->ic_sta, sample_stats, sc);
 1573         return 0;
 1574 }
 1575 
 1576 static int
 1577 ath_rate_sysctl_smoothing_rate(SYSCTL_HANDLER_ARGS)
 1578 {
 1579         struct sample_softc *ssc = arg1;
 1580         int rate, error;
 1581 
 1582         rate = ssc->smoothing_rate;
 1583         error = sysctl_handle_int(oidp, &rate, 0, req);
 1584         if (error || !req->newptr)
 1585                 return error;
 1586         if (!(0 <= rate && rate < 100))
 1587                 return EINVAL;
 1588         ssc->smoothing_rate = rate;
 1589         ssc->smoothing_minpackets = 100 / (100 - rate);
 1590         return 0;
 1591 }
 1592 
 1593 static int
 1594 ath_rate_sysctl_sample_rate(SYSCTL_HANDLER_ARGS)
 1595 {
 1596         struct sample_softc *ssc = arg1;
 1597         int rate, error;
 1598 
 1599         rate = ssc->sample_rate;
 1600         error = sysctl_handle_int(oidp, &rate, 0, req);
 1601         if (error || !req->newptr)
 1602                 return error;
 1603         if (!(2 <= rate && rate <= 100))
 1604                 return EINVAL;
 1605         ssc->sample_rate = rate;
 1606         return 0;
 1607 }
 1608 
 1609 static void
 1610 ath_rate_sysctlattach(struct ath_softc *sc, struct sample_softc *ssc)
 1611 {
 1612         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
 1613         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
 1614 
 1615         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 1616             "smoothing_rate", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
 1617             ssc, 0, ath_rate_sysctl_smoothing_rate, "I",
 1618             "sample: smoothing rate for avg tx time (%%)");
 1619         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 1620             "sample_rate", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
 1621             ssc, 0, ath_rate_sysctl_sample_rate, "I",
 1622             "sample: percent air time devoted to sampling new rates (%%)");
 1623         /* XXX max_successive_failures, stale_failure_timeout, min_switch */
 1624         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 1625             "sample_stats", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
 1626             sc, 0, ath_rate_sysctl_stats, "I", "sample: print statistics");
 1627 }
 1628 
 1629 struct ath_ratectrl *
 1630 ath_rate_attach(struct ath_softc *sc)
 1631 {
 1632         struct sample_softc *ssc;
 1633 
 1634         ssc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
 1635         if (ssc == NULL)
 1636                 return NULL;
 1637         ssc->arc.arc_space = sizeof(struct sample_node);
 1638         ssc->smoothing_rate = 75;               /* ewma percentage ([0..99]) */
 1639         ssc->smoothing_minpackets = 100 / (100 - ssc->smoothing_rate);
 1640         ssc->sample_rate = 10;                  /* %time to try diff tx rates */
 1641         ssc->max_successive_failures = 3;       /* threshold for rate sampling*/
 1642         ssc->stale_failure_timeout = 10 * hz;   /* 10 seconds */
 1643         ssc->min_switch = hz;                   /* 1 second */
 1644         ath_rate_sysctlattach(sc, ssc);
 1645         return &ssc->arc;
 1646 }
 1647 
 1648 void
 1649 ath_rate_detach(struct ath_ratectrl *arc)
 1650 {
 1651         struct sample_softc *ssc = (struct sample_softc *) arc;
 1652 
 1653         free(ssc, M_DEVBUF);
 1654 }

Cache object: b93e032c78bb0e680f2287867d1209dc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.