LCOV - code coverage report
Current view: top level - net80211 - ieee80211_amrr.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 53 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ieee80211_amrr.c,v 1.11 2016/01/05 18:41:16 stsp Exp $        */
       2             : 
       3             : /*-
       4             :  * Copyright (c) 2006
       5             :  *      Damien Bergamini <damien.bergamini@free.fr>
       6             :  *
       7             :  * Permission to use, copy, modify, and distribute this software for any
       8             :  * purpose with or without fee is hereby granted, provided that the above
       9             :  * copyright notice and this permission notice appear in all copies.
      10             :  *
      11             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      12             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      13             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      14             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      15             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      16             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      17             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      18             :  */
      19             : 
      20             : #include <sys/param.h>
      21             : #include <sys/systm.h>
      22             : #include <sys/kernel.h>
      23             : #include <sys/socket.h>
      24             : 
      25             : #include <net/if.h>
      26             : #include <net/if_media.h>
      27             : 
      28             : #include <netinet/in.h>
      29             : #include <netinet/if_ether.h>
      30             : 
      31             : #include <net80211/ieee80211_var.h>
      32             : #include <net80211/ieee80211_priv.h>
      33             : #include <net80211/ieee80211_amrr.h>
      34             : 
      35             : #define is_success(amn) \
      36             :         ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10)
      37             : #define is_failure(amn) \
      38             :         ((amn)->amn_retrycnt > (amn)->amn_txcnt / 3)
      39             : #define is_enough(amn)          \
      40             :         ((amn)->amn_txcnt > 10)
      41             : #define reset_cnt(amn)          \
      42             :         do { (amn)->amn_txcnt = (amn)->amn_retrycnt = 0; } while (0)
      43             : 
      44             : /* 
      45             :  * XXX In HT mode we only support MCS 0-7, for now.
      46             :  * Beyond MCS 7, incrementing the MCS index does not imply a
      47             :  * higher data rate, so this simple implementation will need
      48             :  * to be enhanced.
      49             :  */
      50             : 
      51             : static inline int
      52           0 : is_min_rate(struct ieee80211_node *ni)
      53             : {
      54           0 :         if (ni->ni_flags & IEEE80211_NODE_HT)
      55           0 :                 return (ni->ni_txmcs == 0);
      56           0 :         return (ni->ni_txrate == 0);
      57           0 : }
      58             : 
      59             : static inline int
      60           0 : is_max_rate(struct ieee80211_node *ni)
      61             : {
      62           0 :         if (ni->ni_flags & IEEE80211_NODE_HT)
      63           0 :                 return (ni->ni_txmcs == 7); /* XXX up to MCS 7 only */
      64           0 :         return (ni->ni_txrate == ni->ni_rates.rs_nrates - 1);
      65           0 : }
      66             : 
      67             : static inline void
      68           0 : increase_rate(struct ieee80211_node *ni)
      69             : {
      70           0 :         if (ni->ni_flags & IEEE80211_NODE_HT)
      71           0 :                 ni->ni_txmcs++;
      72             :         else
      73           0 :                 ni->ni_txrate++;
      74           0 : }
      75             : 
      76             : static inline void
      77           0 : decrease_rate(struct ieee80211_node *ni)
      78             : {
      79           0 :         if (ni->ni_flags & IEEE80211_NODE_HT)
      80           0 :                 ni->ni_txmcs--;
      81             :         else
      82           0 :                 ni->ni_txrate--;
      83           0 : }
      84             : 
      85             : void
      86           0 : ieee80211_amrr_node_init(const struct ieee80211_amrr *amrr,
      87             :     struct ieee80211_amrr_node *amn)
      88             : {
      89           0 :         amn->amn_success = 0;
      90           0 :         amn->amn_recovery = 0;
      91           0 :         amn->amn_txcnt = amn->amn_retrycnt = 0;
      92           0 :         amn->amn_success_threshold = amrr->amrr_min_success_threshold;
      93           0 : }
      94             : 
      95             : /*
      96             :  * Update ni->ni_txrate.
      97             :  */
      98             : void
      99           0 : ieee80211_amrr_choose(struct ieee80211_amrr *amrr, struct ieee80211_node *ni,
     100             :     struct ieee80211_amrr_node *amn)
     101             : {
     102             : #define RV(rate)        ((rate) & IEEE80211_RATE_VAL)
     103             :         int need_change = 0;
     104             : 
     105           0 :         if (is_success(amn) && is_enough(amn)) {
     106           0 :                 amn->amn_success++;
     107           0 :                 if (amn->amn_success >= amn->amn_success_threshold &&
     108           0 :                     !is_max_rate(ni)) {
     109           0 :                         amn->amn_recovery = 1;
     110           0 :                         amn->amn_success = 0;
     111           0 :                         increase_rate(ni);
     112             :                         DPRINTF(("increase rate=%d,#tx=%d,#retries=%d\n",
     113             :                             (ni->ni_flags & IEEE80211_NODE_HT) ? ni->ni_txmcs :
     114             :                             RV(ni->ni_rates.rs_rates[ni->ni_txrate]),
     115             :                             amn->amn_txcnt, amn->amn_retrycnt));
     116             :                         need_change = 1;
     117           0 :                 } else {
     118           0 :                         amn->amn_recovery = 0;
     119             :                 }
     120           0 :         } else if (is_failure(amn)) {
     121           0 :                 amn->amn_success = 0;
     122           0 :                 if (!is_min_rate(ni)) {
     123           0 :                         if (amn->amn_recovery) {
     124           0 :                                 amn->amn_success_threshold *= 2;
     125           0 :                                 if (amn->amn_success_threshold >
     126           0 :                                     amrr->amrr_max_success_threshold)
     127           0 :                                         amn->amn_success_threshold =
     128             :                                             amrr->amrr_max_success_threshold;
     129             :                         } else {
     130           0 :                                 amn->amn_success_threshold =
     131           0 :                                     amrr->amrr_min_success_threshold;
     132             :                         }
     133           0 :                         decrease_rate(ni);
     134             :                         DPRINTF(("decrease rate=%d,#tx=%d,#retries=%d\n",
     135             :                             (ni->ni_flags & IEEE80211_NODE_HT) ? ni->ni_txmcs :
     136             :                             RV(ni->ni_rates.rs_rates[ni->ni_txrate]),
     137             :                             amn->amn_txcnt, amn->amn_retrycnt));
     138             :                         need_change = 1;
     139           0 :                 }
     140           0 :                 amn->amn_recovery = 0;
     141           0 :         }
     142             : 
     143           0 :         if (is_enough(amn) || need_change)
     144           0 :                 reset_cnt(amn);
     145             : #undef RV
     146           0 : }

Generated by: LCOV version 1.13