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/contrib/dev/ath/ath_hal/ar9300/ar9300_ani.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  * Copyright (c) 2013 Qualcomm Atheros, Inc.
    3  *
    4  * Permission to use, copy, modify, and/or distribute this software for any
    5  * purpose with or without fee is hereby granted, provided that the above
    6  * copyright notice and this permission notice appear in all copies.
    7  *
    8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
   10  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
   11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
   12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
   13  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
   14  * PERFORMANCE OF THIS SOFTWARE.
   15  */
   16 
   17 #include "opt_ah.h"
   18 
   19 #include "ah.h"
   20 #include "ah_internal.h"
   21 #include "ah_desc.h"
   22 //#include "ah_pktlog.h"
   23 
   24 #include "ar9300/ar9300.h"
   25 #include "ar9300/ar9300reg.h"
   26 #include "ar9300/ar9300phy.h"
   27 
   28 extern  void ar9300_set_rx_filter(struct ath_hal *ah, u_int32_t bits);
   29 extern  u_int32_t ar9300_get_rx_filter(struct ath_hal *ah);
   30 
   31 #define HAL_ANI_DEBUG 1
   32 
   33 /*
   34  * Anti noise immunity support.  We track phy errors and react
   35  * to excessive errors by adjusting the noise immunity parameters.
   36  */
   37 
   38 /******************************************************************************
   39  *
   40  * New Ani Algorithm for Station side only
   41  *
   42  *****************************************************************************/
   43 
   44 #define HAL_ANI_OFDM_TRIG_HIGH     1000 /* units are errors per second */
   45 #define HAL_ANI_OFDM_TRIG_LOW       400 /* units are errors per second */
   46 #define HAL_ANI_CCK_TRIG_HIGH       600 /* units are errors per second */
   47 #define HAL_ANI_CCK_TRIG_LOW        300 /* units are errors per second */
   48 #define HAL_ANI_USE_OFDM_WEAK_SIG  AH_TRUE
   49 #define HAL_ANI_ENABLE_MRC_CCK     AH_TRUE /* default is enabled */
   50 #define HAL_ANI_DEF_SPUR_IMMUNE_LVL   3
   51 #define HAL_ANI_DEF_FIRSTEP_LVL       2
   52 #define HAL_ANI_RSSI_THR_HIGH        40
   53 #define HAL_ANI_RSSI_THR_LOW          7
   54 #define HAL_ANI_PERIOD             1000
   55 
   56 #define HAL_NOISE_DETECT_PERIOD     100
   57 #define HAL_NOISE_RECOVER_PERIOD    5000
   58 
   59 #define HAL_SIG_FIRSTEP_SETTING_MIN   0
   60 #define HAL_SIG_FIRSTEP_SETTING_MAX  20
   61 #define HAL_SIG_SPUR_IMM_SETTING_MIN  0
   62 #define HAL_SIG_SPUR_IMM_SETTING_MAX 22
   63 
   64 #define HAL_EP_RND(x, mul) \
   65     ((((x) % (mul)) >= ((mul) / 2)) ? ((x) + ((mul) - 1)) / (mul) : (x) / (mul))
   66 #define BEACON_RSSI(ahp) \
   67     HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
   68         HAL_RSSI_EP_MULTIPLIER)
   69 
   70 typedef int TABLE[];
   71 /*
   72  *                            level:    0   1   2   3   4   5   6   7   8
   73  * firstep_table:    lvl 0-8, default 2
   74  */
   75 static const TABLE firstep_table    = { -4, -2,  0,  2,  4,  6,  8, 10, 12};
   76 /* cycpwr_thr1_table: lvl 0-7, default 3 */
   77 static const TABLE cycpwr_thr1_table = { -6, -4, -2,  0,  2,  4,  6,  8 };
   78 /* values here are relative to the INI */
   79 
   80 typedef struct _HAL_ANI_OFDM_LEVEL_ENTRY {
   81     int spur_immunity_level;
   82     int fir_step_level;
   83     int ofdm_weak_signal_on;
   84 } HAL_ANI_OFDM_LEVEL_ENTRY;
   85 static const HAL_ANI_OFDM_LEVEL_ENTRY ofdm_level_table[] = {
   86 /*     SI  FS  WS */
   87      {  0,  0,  1  }, /* lvl 0 */
   88      {  1,  1,  1  }, /* lvl 1 */
   89      {  2,  2,  1  }, /* lvl 2 */
   90      {  3,  2,  1  }, /* lvl 3  (default) */
   91      {  4,  3,  1  }, /* lvl 4 */
   92      {  5,  4,  1  }, /* lvl 5 */
   93      {  6,  5,  1  }, /* lvl 6 */
   94      {  7,  6,  1  }, /* lvl 7 */
   95      {  7,  7,  1  }, /* lvl 8 */
   96      {  7,  8,  0  }  /* lvl 9 */
   97 };
   98 #define HAL_ANI_OFDM_NUM_LEVEL \
   99     (sizeof(ofdm_level_table) / sizeof(ofdm_level_table[0]))
  100 #define HAL_ANI_OFDM_MAX_LEVEL (HAL_ANI_OFDM_NUM_LEVEL - 1)
  101 #define HAL_ANI_OFDM_DEF_LEVEL 3 /* default level - matches the INI settings */
  102 
  103 typedef struct _HAL_ANI_CCK_LEVEL_ENTRY {
  104     int fir_step_level;
  105     int mrc_cck_on;
  106 } HAL_ANI_CCK_LEVEL_ENTRY;
  107 
  108 static const HAL_ANI_CCK_LEVEL_ENTRY cck_level_table[] = {
  109 /*     FS  MRC-CCK */
  110      {  0,  1  },  /* lvl 0 */
  111      {  1,  1  },  /* lvl 1 */
  112      {  2,  1  },  /* lvl 2  (default) */
  113      {  3,  1  },  /* lvl 3 */
  114      {  4,  0  },  /* lvl 4 */
  115      {  5,  0  },  /* lvl 5 */
  116      {  6,  0  },  /* lvl 6 */
  117      {  7,  0  },  /* lvl 7 (only for high rssi) */
  118      {  8,  0  }   /* lvl 8 (only for high rssi) */
  119 };
  120 #define HAL_ANI_CCK_NUM_LEVEL \
  121     (sizeof(cck_level_table) / sizeof(cck_level_table[0]))
  122 #define HAL_ANI_CCK_MAX_LEVEL           (HAL_ANI_CCK_NUM_LEVEL - 1)
  123 #define HAL_ANI_CCK_MAX_LEVEL_LOW_RSSI  (HAL_ANI_CCK_NUM_LEVEL - 3)
  124 #define HAL_ANI_CCK_DEF_LEVEL 2 /* default level - matches the INI settings */
  125 
  126 /*
  127  * register values to turn OFDM weak signal detection OFF
  128  */
  129 static const int m1_thresh_low_off     = 127;
  130 static const int m2_thresh_low_off     = 127;
  131 static const int m1_thresh_off         = 127;
  132 static const int m2_thresh_off         = 127;
  133 static const int m2_count_thr_off      =  31;
  134 static const int m2_count_thr_low_off  =  63;
  135 static const int m1_thresh_low_ext_off = 127;
  136 static const int m2_thresh_low_ext_off = 127;
  137 static const int m1_thresh_ext_off     = 127;
  138 static const int m2_thresh_ext_off     = 127;
  139 
  140 void
  141 ar9300_enable_mib_counters(struct ath_hal *ah)
  142 {
  143     HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Enable MIB counters\n", __func__);
  144     /* Clear the mib counters and save them in the stats */
  145     ar9300_update_mib_mac_stats(ah);
  146 
  147     OS_REG_WRITE(ah, AR_FILT_OFDM, 0);
  148     OS_REG_WRITE(ah, AR_FILT_CCK, 0);
  149     OS_REG_WRITE(ah, AR_MIBC,
  150         ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f);
  151     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
  152     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
  153 
  154 }
  155 
  156 void
  157 ar9300_disable_mib_counters(struct ath_hal *ah)
  158 {
  159     HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Disabling MIB counters\n", __func__);
  160 
  161     OS_REG_WRITE(ah, AR_MIBC,  AR_MIBC_FMC | AR_MIBC_CMC);
  162 
  163     /* Clear the mib counters and save them in the stats */
  164     ar9300_update_mib_mac_stats(ah);
  165 
  166     OS_REG_WRITE(ah, AR_FILT_OFDM, 0);
  167     OS_REG_WRITE(ah, AR_FILT_CCK, 0);
  168 }
  169 
  170 /*
  171  * This routine returns the index into the ani_state array that
  172  * corresponds to the channel in *chan.  If no match is found and the
  173  * array is still not fully utilized, a new entry is created for the
  174  * channel.  We assume the attach function has already initialized the
  175  * ah_ani values and only the channel field needs to be set.
  176  */
  177 static int
  178 ar9300_get_ani_channel_index(struct ath_hal *ah,
  179   const struct ieee80211_channel *chan)
  180 {
  181     struct ath_hal_9300 *ahp = AH9300(ah);
  182     int i;
  183 
  184     for (i = 0; i < ARRAY_LENGTH(ahp->ah_ani); i++) {
  185         /* XXX this doesn't distinguish between 20/40 channels */
  186         if (ahp->ah_ani[i].c.ic_freq == chan->ic_freq) {
  187             return i;
  188         }
  189         if (ahp->ah_ani[i].c.ic_freq == 0) {
  190             ahp->ah_ani[i].c.ic_freq = chan->ic_freq;
  191             ahp->ah_ani[i].c.ic_flags = chan->ic_flags;
  192             return i;
  193         }
  194     }
  195     /* XXX statistic */
  196     HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
  197         "%s: No more channel states left. Using channel 0\n", __func__);
  198     return 0;        /* XXX gotta return something valid */
  199 }
  200 
  201 /*
  202  * Return the current ANI state of the channel we're on
  203  */
  204 struct ar9300_ani_state *
  205 ar9300_ani_get_current_state(struct ath_hal *ah)
  206 {
  207     return AH9300(ah)->ah_curani;
  208 }
  209 
  210 /*
  211  * Return the current statistics.
  212  */
  213 HAL_ANI_STATS *
  214 ar9300_ani_get_current_stats(struct ath_hal *ah)
  215 {
  216     return &AH9300(ah)->ah_stats;
  217 }
  218 
  219 /*
  220  * Setup ANI handling.  Sets all thresholds and levels to default level AND
  221  * resets the channel statistics
  222  */
  223 
  224 void
  225 ar9300_ani_attach(struct ath_hal *ah)
  226 {
  227     struct ath_hal_9300 *ahp = AH9300(ah);
  228     int i;
  229 
  230     OS_MEMZERO(ahp->ah_ani, sizeof(ahp->ah_ani));
  231     for (i = 0; i < ARRAY_LENGTH(ahp->ah_ani); i++) {
  232         ahp->ah_ani[i].ofdm_trig_high = HAL_ANI_OFDM_TRIG_HIGH;
  233         ahp->ah_ani[i].ofdm_trig_low = HAL_ANI_OFDM_TRIG_LOW;
  234         ahp->ah_ani[i].cck_trig_high = HAL_ANI_CCK_TRIG_HIGH;
  235         ahp->ah_ani[i].cck_trig_low = HAL_ANI_CCK_TRIG_LOW;
  236         ahp->ah_ani[i].rssi_thr_high = HAL_ANI_RSSI_THR_HIGH;
  237         ahp->ah_ani[i].rssi_thr_low = HAL_ANI_RSSI_THR_LOW;
  238         ahp->ah_ani[i].ofdm_noise_immunity_level = HAL_ANI_OFDM_DEF_LEVEL;
  239         ahp->ah_ani[i].cck_noise_immunity_level = HAL_ANI_CCK_DEF_LEVEL;
  240         ahp->ah_ani[i].ofdm_weak_sig_detect_off = !HAL_ANI_USE_OFDM_WEAK_SIG;
  241         ahp->ah_ani[i].spur_immunity_level = HAL_ANI_DEF_SPUR_IMMUNE_LVL;
  242         ahp->ah_ani[i].firstep_level = HAL_ANI_DEF_FIRSTEP_LVL;
  243         ahp->ah_ani[i].mrc_cck_off = !HAL_ANI_ENABLE_MRC_CCK;
  244         ahp->ah_ani[i].ofdms_turn = AH_TRUE;
  245         ahp->ah_ani[i].must_restore = AH_FALSE;
  246     }
  247 
  248     /*
  249      * Since we expect some ongoing maintenance on the tables,
  250      * let's sanity check here.
  251      * The default level should not modify INI setting.
  252      */
  253     HALASSERT(firstep_table[HAL_ANI_DEF_FIRSTEP_LVL] == 0);
  254     HALASSERT(cycpwr_thr1_table[HAL_ANI_DEF_SPUR_IMMUNE_LVL] == 0);
  255     HALASSERT(
  256         ofdm_level_table[HAL_ANI_OFDM_DEF_LEVEL].fir_step_level ==
  257         HAL_ANI_DEF_FIRSTEP_LVL);
  258     HALASSERT(
  259         ofdm_level_table[HAL_ANI_OFDM_DEF_LEVEL].spur_immunity_level ==
  260         HAL_ANI_DEF_SPUR_IMMUNE_LVL);
  261     HALASSERT(
  262         cck_level_table[HAL_ANI_CCK_DEF_LEVEL].fir_step_level ==
  263         HAL_ANI_DEF_FIRSTEP_LVL);
  264 
  265     /* Initialize and enable MIB Counters */
  266     OS_REG_WRITE(ah, AR_PHY_ERR_1, 0);
  267     OS_REG_WRITE(ah, AR_PHY_ERR_2, 0);
  268     ar9300_enable_mib_counters(ah);
  269 
  270     ahp->ah_ani_period = HAL_ANI_PERIOD;
  271     if (ah->ah_config.ath_hal_enable_ani) {
  272         ahp->ah_proc_phy_err |= HAL_PROCESS_ANI;
  273     }
  274 }
  275 
  276 /*
  277  * Cleanup any ANI state setup.
  278  */
  279 void
  280 ar9300_ani_detach(struct ath_hal *ah)
  281 {
  282     HALDEBUG(ah, HAL_DEBUG_ANI, "%s: Detaching Ani\n", __func__);
  283     ar9300_disable_mib_counters(ah);
  284     OS_REG_WRITE(ah, AR_PHY_ERR_1, 0);
  285     OS_REG_WRITE(ah, AR_PHY_ERR_2, 0);
  286 }
  287 
  288 /*
  289  * Initialize the ANI register values with default (ini) values.
  290  * This routine is called during a (full) hardware reset after
  291  * all the registers are initialised from the INI.
  292  */
  293 void
  294 ar9300_ani_init_defaults(struct ath_hal *ah, HAL_HT_MACMODE macmode)
  295 {
  296     struct ath_hal_9300 *ahp = AH9300(ah);
  297     struct ar9300_ani_state *ani_state;
  298     const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
  299     int index;
  300     u_int32_t val;
  301 
  302     HALASSERT(chan != AH_NULL);
  303     index = ar9300_get_ani_channel_index(ah, chan);
  304     ani_state = &ahp->ah_ani[index];
  305     ahp->ah_curani = ani_state;
  306 
  307     HALDEBUG(ah, HAL_DEBUG_ANI,
  308         "%s: ver %d.%d opmode %u chan %d Mhz/0x%x macmode %d\n",
  309         __func__, AH_PRIVATE(ah)->ah_macVersion, AH_PRIVATE(ah)->ah_macRev,
  310         AH_PRIVATE(ah)->ah_opmode, chan->ic_freq, chan->ic_flags, macmode);
  311 
  312     val = OS_REG_READ(ah, AR_PHY_SFCORR);
  313     ani_state->ini_def.m1_thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
  314     ani_state->ini_def.m2_thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
  315     ani_state->ini_def.m2_count_thr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
  316 
  317     val = OS_REG_READ(ah, AR_PHY_SFCORR_LOW);
  318     ani_state->ini_def.m1_thresh_low =
  319         MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
  320     ani_state->ini_def.m2_thresh_low =
  321         MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
  322     ani_state->ini_def.m2_count_thr_low =
  323         MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
  324 
  325     val = OS_REG_READ(ah, AR_PHY_SFCORR_EXT);
  326     ani_state->ini_def.m1_thresh_ext = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
  327     ani_state->ini_def.m2_thresh_ext = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
  328     ani_state->ini_def.m1_thresh_low_ext =
  329         MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
  330     ani_state->ini_def.m2_thresh_low_ext =
  331         MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
  332 
  333     ani_state->ini_def.firstep =
  334         OS_REG_READ_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP);
  335     ani_state->ini_def.firstep_low =
  336         OS_REG_READ_FIELD(
  337             ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW);
  338     ani_state->ini_def.cycpwr_thr1 =
  339         OS_REG_READ_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1);
  340     ani_state->ini_def.cycpwr_thr1_ext =
  341         OS_REG_READ_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CYCPWR_THR1);
  342 
  343     /* these levels just got reset to defaults by the INI */
  344     ani_state->spur_immunity_level = HAL_ANI_DEF_SPUR_IMMUNE_LVL;
  345     ani_state->firstep_level = HAL_ANI_DEF_FIRSTEP_LVL;
  346     ani_state->ofdm_weak_sig_detect_off = !HAL_ANI_USE_OFDM_WEAK_SIG;
  347     ani_state->mrc_cck_off = !HAL_ANI_ENABLE_MRC_CCK;
  348 
  349     ani_state->cycle_count = 0;
  350 }
  351 
  352 /*
  353  * Set the ANI settings to match an OFDM level.
  354  */
  355 static void
  356 ar9300_ani_set_odfm_noise_immunity_level(struct ath_hal *ah,
  357                                    u_int8_t ofdm_noise_immunity_level)
  358 {
  359     struct ath_hal_9300 *ahp = AH9300(ah);
  360     struct ar9300_ani_state *ani_state = ahp->ah_curani;
  361 
  362     ani_state->rssi = BEACON_RSSI(ahp);
  363     HALDEBUG(ah, HAL_DEBUG_ANI,
  364         "**** %s: ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", __func__,
  365         ani_state->ofdm_noise_immunity_level, ofdm_noise_immunity_level,
  366         ani_state->rssi, ani_state->rssi_thr_low, ani_state->rssi_thr_high);
  367 
  368     ani_state->ofdm_noise_immunity_level = ofdm_noise_immunity_level;
  369 
  370     if (ani_state->spur_immunity_level !=
  371         ofdm_level_table[ofdm_noise_immunity_level].spur_immunity_level)
  372     {
  373         ar9300_ani_control(
  374             ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
  375             ofdm_level_table[ofdm_noise_immunity_level].spur_immunity_level);
  376     }
  377 
  378     if (ani_state->firstep_level !=
  379             ofdm_level_table[ofdm_noise_immunity_level].fir_step_level &&
  380         ofdm_level_table[ofdm_noise_immunity_level].fir_step_level >=
  381             cck_level_table[ani_state->cck_noise_immunity_level].fir_step_level)
  382     {
  383         ar9300_ani_control(
  384             ah, HAL_ANI_FIRSTEP_LEVEL,
  385             ofdm_level_table[ofdm_noise_immunity_level].fir_step_level);
  386     }
  387 
  388     if ((AH_PRIVATE(ah)->ah_opmode != HAL_M_STA ||
  389         ani_state->rssi <= ani_state->rssi_thr_high))
  390     {
  391         if (ani_state->ofdm_weak_sig_detect_off) {
  392             /*
  393              * force on ofdm weak sig detect.
  394              */
  395             ar9300_ani_control(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, AH_TRUE);
  396         }
  397     } else if (ani_state->ofdm_weak_sig_detect_off ==
  398                ofdm_level_table[ofdm_noise_immunity_level].ofdm_weak_signal_on)
  399     {
  400         ar9300_ani_control(
  401             ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  402             ofdm_level_table[ofdm_noise_immunity_level].ofdm_weak_signal_on);
  403     }
  404 }
  405 
  406 /*
  407  * Set the ANI settings to match a CCK level.
  408  */
  409 static void
  410 ar9300_ani_set_cck_noise_immunity_level(struct ath_hal *ah,
  411                                   u_int8_t cck_noise_immunity_level)
  412 {
  413     struct ath_hal_9300 *ahp = AH9300(ah);
  414     struct ar9300_ani_state *ani_state = ahp->ah_curani;
  415     int level;
  416 
  417     ani_state->rssi = BEACON_RSSI(ahp);
  418     HALDEBUG(ah, HAL_DEBUG_ANI,
  419         "**** %s: ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
  420         __func__, ani_state->cck_noise_immunity_level, cck_noise_immunity_level,
  421         ani_state->rssi, ani_state->rssi_thr_low, ani_state->rssi_thr_high);
  422 
  423     if (AH_PRIVATE(ah)->ah_opmode == HAL_M_STA &&
  424         ani_state->rssi <= ani_state->rssi_thr_low &&
  425         cck_noise_immunity_level > HAL_ANI_CCK_MAX_LEVEL_LOW_RSSI)
  426     {
  427         cck_noise_immunity_level = HAL_ANI_CCK_MAX_LEVEL_LOW_RSSI;
  428     }
  429 
  430     ani_state->cck_noise_immunity_level = cck_noise_immunity_level;
  431 
  432     level = ani_state->ofdm_noise_immunity_level;
  433     if (ani_state->firstep_level !=
  434             cck_level_table[cck_noise_immunity_level].fir_step_level &&
  435         cck_level_table[cck_noise_immunity_level].fir_step_level >=
  436             ofdm_level_table[level].fir_step_level)
  437     {
  438         ar9300_ani_control(
  439             ah, HAL_ANI_FIRSTEP_LEVEL,
  440             cck_level_table[cck_noise_immunity_level].fir_step_level);
  441     }
  442 
  443     if (ani_state->mrc_cck_off ==
  444         cck_level_table[cck_noise_immunity_level].mrc_cck_on)
  445     {
  446         ar9300_ani_control(
  447             ah, HAL_ANI_MRC_CCK,
  448             cck_level_table[cck_noise_immunity_level].mrc_cck_on);
  449     }
  450 }
  451 
  452 /*
  453  * Control Adaptive Noise Immunity Parameters
  454  */
  455 HAL_BOOL
  456 ar9300_ani_control(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
  457 {
  458     struct ath_hal_9300 *ahp = AH9300(ah);
  459     struct ar9300_ani_state *ani_state = ahp->ah_curani;
  460     const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
  461     int32_t value, value2;
  462     u_int level = param;
  463     u_int is_on;
  464 
  465     HALDEBUG(ah, HAL_DEBUG_ANI, "%s: cmd=%d, param=%d, chan=%p, funcmask=0x%08x\n",
  466       __func__,
  467       cmd,
  468       param,
  469       chan,
  470       ahp->ah_ani_function);
  471 
  472 
  473     if (chan == NULL && cmd != HAL_ANI_MODE) {
  474         HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
  475             "%s: ignoring cmd 0x%02x - no channel\n", __func__, cmd);
  476         return AH_FALSE;
  477     }
  478 
  479     /*
  480      * These two control the top-level cck/ofdm immunity levels and will
  481      * program the rest of the values.
  482      */
  483     if (cmd == HAL_ANI_NOISE_IMMUNITY_LEVEL) {
  484         if (param > HAL_ANI_OFDM_NUM_LEVEL)
  485           return AH_FALSE;
  486         ar9300_ani_set_odfm_noise_immunity_level(ah, param);
  487         return AH_TRUE;
  488     }
  489 
  490     if (cmd == HAL_ANI_CCK_NOISE_IMMUNITY_LEVEL) {
  491         if (param > HAL_ANI_CCK_NUM_LEVEL)
  492           return AH_FALSE;
  493         ar9300_ani_set_cck_noise_immunity_level(ah, param);
  494         return AH_TRUE;
  495     }
  496 
  497     /*
  498      * Check to see if this command is available in the
  499      * current operating mode.
  500      */
  501     if (((1 << cmd) & ahp->ah_ani_function) == 0) {
  502         HALDEBUG(ah, HAL_DEBUG_ANI,
  503             "%s: early check: invalid cmd 0x%02x (allowed=0x%02x)\n",
  504             __func__, cmd, ahp->ah_ani_function);
  505         return AH_FALSE;
  506     }
  507 
  508     /*
  509      * The rest of these program in the requested parameter values
  510      * into the PHY.
  511      */
  512     switch (cmd) {
  513 
  514     case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: 
  515         {
  516             int m1_thresh_low, m2_thresh_low;
  517             int m1_thresh, m2_thresh;
  518             int m2_count_thr, m2_count_thr_low;
  519             int m1_thresh_low_ext, m2_thresh_low_ext;
  520             int m1_thresh_ext, m2_thresh_ext;
  521             /*
  522              * is_on == 1 means ofdm weak signal detection is ON
  523              * (default, less noise imm)
  524              * is_on == 0 means ofdm weak signal detection is OFF
  525              * (more noise imm)
  526              */
  527             is_on = param ? 1 : 0;
  528 
  529             if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah))
  530                 goto skip_ws_det;
  531 
  532             /*
  533              * make register setting for default (weak sig detect ON)
  534              * come from INI file
  535              */
  536             m1_thresh_low    = is_on ?
  537                 ani_state->ini_def.m1_thresh_low    : m1_thresh_low_off;
  538             m2_thresh_low    = is_on ?
  539                 ani_state->ini_def.m2_thresh_low    : m2_thresh_low_off;
  540             m1_thresh       = is_on ?
  541                 ani_state->ini_def.m1_thresh       : m1_thresh_off;
  542             m2_thresh       = is_on ?
  543                 ani_state->ini_def.m2_thresh       : m2_thresh_off;
  544             m2_count_thr     = is_on ?
  545                 ani_state->ini_def.m2_count_thr     : m2_count_thr_off;
  546             m2_count_thr_low  = is_on ?
  547                 ani_state->ini_def.m2_count_thr_low  : m2_count_thr_low_off;
  548             m1_thresh_low_ext = is_on ?
  549                 ani_state->ini_def.m1_thresh_low_ext : m1_thresh_low_ext_off;
  550             m2_thresh_low_ext = is_on ?
  551                 ani_state->ini_def.m2_thresh_low_ext : m2_thresh_low_ext_off;
  552             m1_thresh_ext    = is_on ?
  553                 ani_state->ini_def.m1_thresh_ext    : m1_thresh_ext_off;
  554             m2_thresh_ext    = is_on ?
  555                 ani_state->ini_def.m2_thresh_ext    : m2_thresh_ext_off;
  556             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
  557                 AR_PHY_SFCORR_LOW_M1_THRESH_LOW, m1_thresh_low);
  558             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
  559                 AR_PHY_SFCORR_LOW_M2_THRESH_LOW, m2_thresh_low);
  560             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M1_THRESH,
  561                 m1_thresh);
  562             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2_THRESH,
  563                 m2_thresh);
  564             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2COUNT_THR,
  565                 m2_count_thr);
  566             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
  567                 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, m2_count_thr_low);
  568             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
  569                 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1_thresh_low_ext);
  570             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
  571                 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2_thresh_low_ext);
  572             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M1_THRESH,
  573                 m1_thresh_ext);
  574             OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M2_THRESH,
  575                 m2_thresh_ext);
  576 skip_ws_det:
  577             if (is_on) {
  578                 OS_REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
  579                     AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
  580             } else {
  581                 OS_REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
  582                     AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
  583             }
  584             if ((!is_on) != ani_state->ofdm_weak_sig_detect_off) {
  585                 HALDEBUG(ah, HAL_DEBUG_ANI,
  586                     "%s: ** ch %d: ofdm weak signal: %s=>%s\n",
  587                     __func__, chan->ic_freq,
  588                     !ani_state->ofdm_weak_sig_detect_off ? "on" : "off",
  589                     is_on ? "on" : "off");
  590                 if (is_on) {
  591                     ahp->ah_stats.ast_ani_ofdmon++;
  592                 } else {
  593                     ahp->ah_stats.ast_ani_ofdmoff++;
  594                 }
  595                 ani_state->ofdm_weak_sig_detect_off = !is_on;
  596             }
  597             break;
  598         }
  599     case HAL_ANI_FIRSTEP_LEVEL:
  600         if (level >= ARRAY_LENGTH(firstep_table)) {
  601             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
  602                 "%s: HAL_ANI_FIRSTEP_LEVEL level out of range (%u > %u)\n",
  603                 __func__, level, (unsigned) ARRAY_LENGTH(firstep_table));
  604             return AH_FALSE;
  605         }
  606         /*
  607          * make register setting relative to default
  608          * from INI file & cap value
  609          */
  610         value =
  611             firstep_table[level] -
  612             firstep_table[HAL_ANI_DEF_FIRSTEP_LVL] +
  613             ani_state->ini_def.firstep;
  614         if (value < HAL_SIG_FIRSTEP_SETTING_MIN) {
  615             value = HAL_SIG_FIRSTEP_SETTING_MIN;
  616         }
  617         if (value > HAL_SIG_FIRSTEP_SETTING_MAX) {
  618             value = HAL_SIG_FIRSTEP_SETTING_MAX;
  619         }
  620         OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, value);
  621         /*
  622          * we need to set first step low register too
  623          * make register setting relative to default from INI file & cap value
  624          */
  625         value2 =
  626             firstep_table[level] -
  627             firstep_table[HAL_ANI_DEF_FIRSTEP_LVL] +
  628             ani_state->ini_def.firstep_low;
  629         if (value2 < HAL_SIG_FIRSTEP_SETTING_MIN) {
  630             value2 = HAL_SIG_FIRSTEP_SETTING_MIN;
  631         }
  632         if (value2 > HAL_SIG_FIRSTEP_SETTING_MAX) {
  633             value2 = HAL_SIG_FIRSTEP_SETTING_MAX;
  634         }
  635         OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
  636             AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
  637 
  638         if (level != ani_state->firstep_level) {
  639             HALDEBUG(ah, HAL_DEBUG_ANI,
  640                 "%s: ** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
  641                 __func__, chan->ic_freq, ani_state->firstep_level, level,
  642                 HAL_ANI_DEF_FIRSTEP_LVL, value, ani_state->ini_def.firstep);
  643             HALDEBUG(ah, HAL_DEBUG_ANI,
  644                 "%s: ** ch %d: level %d=>%d[def:%d] "
  645                 "firstep_low[level]=%d ini=%d\n",
  646                 __func__, chan->ic_freq, ani_state->firstep_level, level,
  647                 HAL_ANI_DEF_FIRSTEP_LVL, value2,
  648                 ani_state->ini_def.firstep_low);
  649             if (level > ani_state->firstep_level) {
  650                 ahp->ah_stats.ast_ani_stepup++;
  651             } else if (level < ani_state->firstep_level) {
  652                 ahp->ah_stats.ast_ani_stepdown++;
  653             }
  654             ani_state->firstep_level = level;
  655         }
  656         break;
  657     case HAL_ANI_SPUR_IMMUNITY_LEVEL:
  658         if (level >= ARRAY_LENGTH(cycpwr_thr1_table)) {
  659             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
  660                 "%s: HAL_ANI_SPUR_IMMUNITY_LEVEL level "
  661                 "out of range (%u > %u)\n",
  662                 __func__, level, (unsigned) ARRAY_LENGTH(cycpwr_thr1_table));
  663             return AH_FALSE;
  664         }
  665         /*
  666          * make register setting relative to default from INI file & cap value
  667          */
  668         value =
  669             cycpwr_thr1_table[level] -
  670             cycpwr_thr1_table[HAL_ANI_DEF_SPUR_IMMUNE_LVL] +
  671             ani_state->ini_def.cycpwr_thr1;
  672         if (value < HAL_SIG_SPUR_IMM_SETTING_MIN) {
  673             value = HAL_SIG_SPUR_IMM_SETTING_MIN;
  674         }
  675         if (value > HAL_SIG_SPUR_IMM_SETTING_MAX) {
  676             value = HAL_SIG_SPUR_IMM_SETTING_MAX;
  677         }
  678         OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1, value);
  679 
  680         /*
  681          * set AR_PHY_EXT_CCA for extension channel
  682          * make register setting relative to default from INI file & cap value
  683          */
  684         value2 =
  685             cycpwr_thr1_table[level] -
  686             cycpwr_thr1_table[HAL_ANI_DEF_SPUR_IMMUNE_LVL] +
  687             ani_state->ini_def.cycpwr_thr1_ext;
  688         if (value2 < HAL_SIG_SPUR_IMM_SETTING_MIN) {
  689             value2 = HAL_SIG_SPUR_IMM_SETTING_MIN;
  690         }
  691         if (value2 > HAL_SIG_SPUR_IMM_SETTING_MAX) {
  692             value2 = HAL_SIG_SPUR_IMM_SETTING_MAX;
  693         }
  694         OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CYCPWR_THR1, value2);
  695 
  696         if (level != ani_state->spur_immunity_level) {
  697             HALDEBUG(ah, HAL_DEBUG_ANI,
  698                 "%s: ** ch %d: level %d=>%d[def:%d] "
  699                 "cycpwr_thr1[level]=%d ini=%d\n",
  700                 __func__, chan->ic_freq, ani_state->spur_immunity_level, level,
  701                 HAL_ANI_DEF_SPUR_IMMUNE_LVL, value,
  702                 ani_state->ini_def.cycpwr_thr1);
  703             HALDEBUG(ah, HAL_DEBUG_ANI,
  704                 "%s: ** ch %d: level %d=>%d[def:%d] "
  705                 "cycpwr_thr1_ext[level]=%d ini=%d\n",
  706                 __func__, chan->ic_freq, ani_state->spur_immunity_level, level,
  707                 HAL_ANI_DEF_SPUR_IMMUNE_LVL, value2,
  708                 ani_state->ini_def.cycpwr_thr1_ext);
  709             if (level > ani_state->spur_immunity_level) {
  710                 ahp->ah_stats.ast_ani_spurup++;
  711             } else if (level < ani_state->spur_immunity_level) {
  712                 ahp->ah_stats.ast_ani_spurdown++;
  713             }
  714             ani_state->spur_immunity_level = level;
  715         }
  716         break;
  717     case HAL_ANI_MRC_CCK:
  718         /*
  719          * is_on == 1 means MRC CCK ON (default, less noise imm)
  720          * is_on == 0 means MRC CCK is OFF (more noise imm)
  721          */
  722         is_on = param ? 1 : 0;
  723         if (!AR_SREV_POSEIDON(ah)) {
  724             OS_REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
  725                 AR_PHY_MRC_CCK_ENABLE, is_on);
  726             OS_REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
  727                 AR_PHY_MRC_CCK_MUX_REG, is_on);
  728         }
  729         if ((!is_on) != ani_state->mrc_cck_off) {
  730             HALDEBUG(ah, HAL_DEBUG_ANI,
  731                 "%s: ** ch %d: MRC CCK: %s=>%s\n", __func__, chan->ic_freq,
  732                 !ani_state->mrc_cck_off ? "on" : "off", is_on ? "on" : "off");
  733             if (is_on) {
  734                 ahp->ah_stats.ast_ani_ccklow++;
  735             } else {
  736                 ahp->ah_stats.ast_ani_cckhigh++;
  737             }
  738             ani_state->mrc_cck_off = !is_on;
  739         }
  740         break;
  741     case HAL_ANI_PRESENT:
  742         break;
  743 #ifdef AH_PRIVATE_DIAG
  744     case HAL_ANI_MODE:
  745         if (param == 0) {
  746             ahp->ah_proc_phy_err &= ~HAL_PROCESS_ANI;
  747             /* Turn off HW counters if we have them */
  748             ar9300_ani_detach(ah);
  749             if (AH_PRIVATE(ah)->ah_curchan == NULL) {
  750                 return AH_TRUE;
  751             }
  752             /* if we're turning off ANI, reset regs back to INI settings */
  753             if (ah->ah_config.ath_hal_enable_ani) {
  754                 HAL_ANI_CMD savefunc = ahp->ah_ani_function;
  755                 /* temporarly allow all functions so we can reset */
  756                 ahp->ah_ani_function = HAL_ANI_ALL;
  757                 HALDEBUG(ah, HAL_DEBUG_ANI,
  758                     "%s: disable all ANI functions\n", __func__);
  759                 ar9300_ani_set_odfm_noise_immunity_level(
  760                     ah, HAL_ANI_OFDM_DEF_LEVEL);
  761                 ar9300_ani_set_cck_noise_immunity_level(
  762                     ah, HAL_ANI_CCK_DEF_LEVEL);
  763                 ahp->ah_ani_function = savefunc;
  764             }
  765         } else {            /* normal/auto mode */
  766             HALDEBUG(ah, HAL_DEBUG_ANI, "%s: enabled\n", __func__);
  767             ahp->ah_proc_phy_err |= HAL_PROCESS_ANI;
  768             if (AH_PRIVATE(ah)->ah_curchan == NULL) {
  769                 return AH_TRUE;
  770             }
  771             ar9300_enable_mib_counters(ah);
  772             ar9300_ani_reset(ah, AH_FALSE);
  773             ani_state = ahp->ah_curani;
  774         }
  775         HALDEBUG(ah, HAL_DEBUG_ANI, "5 ANC: ahp->ah_proc_phy_err %x \n",
  776                  ahp->ah_proc_phy_err);
  777         break;
  778     case HAL_ANI_PHYERR_RESET:
  779         ahp->ah_stats.ast_ani_ofdmerrs = 0;
  780         ahp->ah_stats.ast_ani_cckerrs = 0;
  781         break;
  782 #endif /* AH_PRIVATE_DIAG */
  783     default:
  784 #if HAL_ANI_DEBUG
  785         HALDEBUG(ah, HAL_DEBUG_ANI,
  786             "%s: invalid cmd 0x%02x (allowed=0x%02x)\n",
  787             __func__, cmd, ahp->ah_ani_function);
  788 #endif
  789         return AH_FALSE;
  790     }
  791 
  792 #if HAL_ANI_DEBUG
  793     HALDEBUG(ah, HAL_DEBUG_ANI,
  794         "%s: ANI parameters: SI=%d, ofdm_ws=%s FS=%d MRCcck=%s listen_time=%d "
  795         "CC=%d listen=%d ofdm_errs=%d cck_errs=%d\n",
  796         __func__, ani_state->spur_immunity_level,
  797         !ani_state->ofdm_weak_sig_detect_off ? "on" : "off",
  798         ani_state->firstep_level, !ani_state->mrc_cck_off ? "on" : "off",
  799         ani_state->listen_time, ani_state->cycle_count,
  800         ani_state->listen_time, ani_state->ofdm_phy_err_count,
  801         ani_state->cck_phy_err_count);
  802 #endif
  803 
  804 #ifndef REMOVE_PKT_LOG
  805     /* do pktlog */
  806     {
  807         struct log_ani log_data;
  808 
  809         /* Populate the ani log record */
  810         log_data.phy_stats_disable = DO_ANI(ah);
  811         log_data.noise_immun_lvl = ani_state->ofdm_noise_immunity_level;
  812         log_data.spur_immun_lvl = ani_state->spur_immunity_level;
  813         log_data.ofdm_weak_det = ani_state->ofdm_weak_sig_detect_off;
  814         log_data.cck_weak_thr = ani_state->cck_noise_immunity_level;
  815         log_data.fir_lvl = ani_state->firstep_level;
  816         log_data.listen_time = ani_state->listen_time;
  817         log_data.cycle_count = ani_state->cycle_count;
  818         /* express ofdm_phy_err_count as errors/second */
  819         log_data.ofdm_phy_err_count = ani_state->listen_time ?
  820             ani_state->ofdm_phy_err_count * 1000 / ani_state->listen_time : 0;
  821         /* express cck_phy_err_count as errors/second */
  822         log_data.cck_phy_err_count =  ani_state->listen_time ?
  823             ani_state->cck_phy_err_count * 1000 / ani_state->listen_time  : 0;
  824         log_data.rssi = ani_state->rssi;
  825 
  826         /* clear interrupt context flag */
  827         ath_hal_log_ani(AH_PRIVATE(ah)->ah_sc, &log_data, 0);
  828     }
  829 #endif
  830 
  831     return AH_TRUE;
  832 }
  833 
  834 static void
  835 ar9300_ani_restart(struct ath_hal *ah)
  836 {
  837     struct ath_hal_9300 *ahp = AH9300(ah);
  838     struct ar9300_ani_state *ani_state;
  839 
  840     if (!DO_ANI(ah)) {
  841         return;
  842     }
  843 
  844     ani_state = ahp->ah_curani;
  845 
  846     ani_state->listen_time = 0;
  847 
  848     OS_REG_WRITE(ah, AR_PHY_ERR_1, 0);
  849     OS_REG_WRITE(ah, AR_PHY_ERR_2, 0);
  850     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
  851     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
  852 
  853     /* Clear the mib counters and save them in the stats */
  854     ar9300_update_mib_mac_stats(ah);
  855 
  856     ani_state->ofdm_phy_err_count = 0;
  857     ani_state->cck_phy_err_count = 0;
  858 }
  859 
  860 static void
  861 ar9300_ani_ofdm_err_trigger(struct ath_hal *ah)
  862 {
  863     struct ath_hal_9300 *ahp = AH9300(ah);
  864     struct ar9300_ani_state *ani_state;
  865 
  866     if (!DO_ANI(ah)) {
  867         return;
  868     }
  869 
  870     ani_state = ahp->ah_curani;
  871 
  872     if (ani_state->ofdm_noise_immunity_level < HAL_ANI_OFDM_MAX_LEVEL) {
  873         ar9300_ani_set_odfm_noise_immunity_level(
  874             ah, ani_state->ofdm_noise_immunity_level + 1);
  875     }
  876 }
  877 
  878 static void
  879 ar9300_ani_cck_err_trigger(struct ath_hal *ah)
  880 {
  881     struct ath_hal_9300 *ahp = AH9300(ah);
  882     struct ar9300_ani_state *ani_state;
  883 
  884     if (!DO_ANI(ah)) {
  885         return;
  886     }
  887 
  888     ani_state = ahp->ah_curani;
  889 
  890     if (ani_state->cck_noise_immunity_level < HAL_ANI_CCK_MAX_LEVEL) {
  891         ar9300_ani_set_cck_noise_immunity_level(
  892             ah, ani_state->cck_noise_immunity_level + 1);
  893     }
  894 }
  895 
  896 /*
  897  * Restore the ANI parameters in the HAL and reset the statistics.
  898  * This routine should be called for every hardware reset and for
  899  * every channel change.
  900  */
  901 void
  902 ar9300_ani_reset(struct ath_hal *ah, HAL_BOOL is_scanning)
  903 {
  904     struct ath_hal_9300 *ahp = AH9300(ah);
  905     struct ar9300_ani_state *ani_state;
  906     const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
  907     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
  908     int index;
  909 
  910     HALASSERT(chan != AH_NULL);
  911 
  912     if (!DO_ANI(ah)) {
  913         return;
  914     }
  915 
  916     /*
  917      * we need to re-point to the correct ANI state since the channel
  918      * may have changed due to a fast channel change
  919     */
  920     index = ar9300_get_ani_channel_index(ah, chan);
  921     ani_state = &ahp->ah_ani[index];
  922     HALASSERT(ani_state != AH_NULL);
  923     ahp->ah_curani = ani_state;
  924 
  925     ahp->ah_stats.ast_ani_reset++;
  926 
  927     ani_state->phy_noise_spur = 0;
  928 
  929     /* only allow a subset of functions in AP mode */
  930     if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
  931         if (IS_CHAN_2GHZ(ichan)) {
  932             ahp->ah_ani_function = (1 << HAL_ANI_SPUR_IMMUNITY_LEVEL) |
  933                                    (1 << HAL_ANI_FIRSTEP_LEVEL) |
  934                                    (1 << HAL_ANI_MRC_CCK);
  935         } else {
  936             ahp->ah_ani_function = 0;
  937         }
  938     } else {
  939       ahp->ah_ani_function = HAL_ANI_ALL;
  940     }
  941 
  942     /* always allow mode (on/off) to be controlled */
  943     ahp->ah_ani_function |= HAL_ANI_MODE;
  944 
  945     if (is_scanning ||
  946         (AH_PRIVATE(ah)->ah_opmode != HAL_M_STA &&
  947          AH_PRIVATE(ah)->ah_opmode != HAL_M_IBSS))
  948     {
  949         /*
  950          * If we're scanning or in AP mode, the defaults (ini) should be
  951          * in place.
  952          * For an AP we assume the historical levels for this channel are
  953          * probably outdated so start from defaults instead.
  954          */
  955         if (ani_state->ofdm_noise_immunity_level != HAL_ANI_OFDM_DEF_LEVEL ||
  956             ani_state->cck_noise_immunity_level != HAL_ANI_CCK_DEF_LEVEL)
  957         {
  958             HALDEBUG(ah, HAL_DEBUG_ANI,
  959                 "%s: Restore defaults: opmode %u chan %d Mhz/0x%x "
  960                 "is_scanning=%d restore=%d ofdm:%d cck:%d\n",
  961                 __func__, AH_PRIVATE(ah)->ah_opmode, chan->ic_freq,
  962                 chan->ic_flags, is_scanning, ani_state->must_restore,
  963                 ani_state->ofdm_noise_immunity_level,
  964                 ani_state->cck_noise_immunity_level);
  965             /*
  966              * for STA/IBSS, we want to restore the historical values later
  967              * (when we're not scanning)
  968              */
  969             if (AH_PRIVATE(ah)->ah_opmode == HAL_M_STA ||
  970                 AH_PRIVATE(ah)->ah_opmode == HAL_M_IBSS)
  971             {
  972                 ar9300_ani_control(ah, HAL_ANI_SPUR_IMMUNITY_LEVEL,
  973                     HAL_ANI_DEF_SPUR_IMMUNE_LVL);
  974                 ar9300_ani_control(
  975                     ah, HAL_ANI_FIRSTEP_LEVEL, HAL_ANI_DEF_FIRSTEP_LVL);
  976                 ar9300_ani_control(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  977                     HAL_ANI_USE_OFDM_WEAK_SIG);
  978                 ar9300_ani_control(ah, HAL_ANI_MRC_CCK, HAL_ANI_ENABLE_MRC_CCK);
  979                 ani_state->must_restore = AH_TRUE;
  980             } else {
  981                 ar9300_ani_set_odfm_noise_immunity_level(
  982                     ah, HAL_ANI_OFDM_DEF_LEVEL);
  983                 ar9300_ani_set_cck_noise_immunity_level(
  984                     ah, HAL_ANI_CCK_DEF_LEVEL);
  985             }
  986         }
  987     } else {
  988         /*
  989          * restore historical levels for this channel
  990          */
  991         HALDEBUG(ah, HAL_DEBUG_ANI,
  992             "%s: Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d "
  993             "restore=%d ofdm:%d cck:%d\n",
  994             __func__, AH_PRIVATE(ah)->ah_opmode, chan->ic_freq,
  995             chan->ic_flags, is_scanning, ani_state->must_restore,
  996             ani_state->ofdm_noise_immunity_level,
  997             ani_state->cck_noise_immunity_level);
  998         ar9300_ani_set_odfm_noise_immunity_level(
  999             ah, ani_state->ofdm_noise_immunity_level);
 1000         ar9300_ani_set_cck_noise_immunity_level(
 1001             ah, ani_state->cck_noise_immunity_level);
 1002         ani_state->must_restore = AH_FALSE;
 1003     }
 1004 
 1005     /* enable phy counters */
 1006     ar9300_ani_restart(ah);
 1007     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
 1008     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 1009 }
 1010 
 1011 /*
 1012  * Process a MIB interrupt.  We may potentially be invoked because
 1013  * any of the MIB counters overflow/trigger so don't assume we're
 1014  * here because a PHY error counter triggered.
 1015  */
 1016 void
 1017 ar9300_process_mib_intr(struct ath_hal *ah, const HAL_NODE_STATS *stats)
 1018 {
 1019     struct ath_hal_9300 *ahp = AH9300(ah);
 1020     u_int32_t phy_cnt1, phy_cnt2;
 1021 
 1022 #if 0
 1023     HALDEBUG(ah, HAL_DEBUG_ANI, "%s: Processing Mib Intr\n", __func__);
 1024 #endif
 1025 
 1026     /* Reset these counters regardless */
 1027     OS_REG_WRITE(ah, AR_FILT_OFDM, 0);
 1028     OS_REG_WRITE(ah, AR_FILT_CCK, 0);
 1029     if (!(OS_REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) {
 1030         OS_REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
 1031     }
 1032 
 1033     /* Clear the mib counters and save them in the stats */
 1034     ar9300_update_mib_mac_stats(ah);
 1035     ahp->ah_stats.ast_nodestats = *stats;
 1036 
 1037     if (!DO_ANI(ah)) {
 1038         /*
 1039          * We must always clear the interrupt cause by resetting
 1040          * the phy error regs.
 1041          */
 1042         OS_REG_WRITE(ah, AR_PHY_ERR_1, 0);
 1043         OS_REG_WRITE(ah, AR_PHY_ERR_2, 0);
 1044         return;
 1045     }
 1046 
 1047     /* NB: these are not reset-on-read */
 1048     phy_cnt1 = OS_REG_READ(ah, AR_PHY_ERR_1);
 1049     phy_cnt2 = OS_REG_READ(ah, AR_PHY_ERR_2);
 1050 #if HAL_ANI_DEBUG
 1051     HALDEBUG(ah, HAL_DEBUG_ANI,
 1052         "%s: Errors: OFDM=0x%08x-0x0=%d   CCK=0x%08x-0x0=%d\n",
 1053         __func__, phy_cnt1, phy_cnt1, phy_cnt2, phy_cnt2);
 1054 #endif
 1055     if (((phy_cnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
 1056         ((phy_cnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
 1057         /* NB: always restart to insure the h/w counters are reset */
 1058         ar9300_ani_restart(ah);
 1059     }
 1060 }
 1061 
 1062 
 1063 static void
 1064 ar9300_ani_lower_immunity(struct ath_hal *ah)
 1065 {
 1066     struct ath_hal_9300 *ahp = AH9300(ah);
 1067     struct ar9300_ani_state *ani_state = ahp->ah_curani;
 1068 
 1069     if (ani_state->ofdm_noise_immunity_level > 0 &&
 1070         (ani_state->ofdms_turn || ani_state->cck_noise_immunity_level == 0)) {
 1071         /*
 1072          * lower OFDM noise immunity
 1073          */
 1074         ar9300_ani_set_odfm_noise_immunity_level(
 1075             ah, ani_state->ofdm_noise_immunity_level - 1);
 1076 
 1077         /*
 1078          * only lower either OFDM or CCK errors per turn
 1079          * we lower the other one next time
 1080          */
 1081         return;
 1082     }
 1083 
 1084     if (ani_state->cck_noise_immunity_level > 0) {
 1085         /*
 1086          * lower CCK noise immunity
 1087          */
 1088         ar9300_ani_set_cck_noise_immunity_level(
 1089             ah, ani_state->cck_noise_immunity_level - 1);
 1090     }
 1091 }
 1092 
 1093 /* convert HW counter values to ms using mode specifix clock rate */
 1094 //#define CLOCK_RATE(_ah)  (ath_hal_chan_2_clock_rate_mhz(_ah) * 1000)
 1095 #define CLOCK_RATE(_ah)  (ath_hal_mac_clks(ah, 1000))
 1096 
 1097 /*
 1098  * Return an approximation of the time spent ``listening'' by
 1099  * deducting the cycles spent tx'ing and rx'ing from the total
 1100  * cycle count since our last call.  A return value <0 indicates
 1101  * an invalid/inconsistent time.
 1102  */
 1103 static int32_t
 1104 ar9300_ani_get_listen_time(struct ath_hal *ah, HAL_ANISTATS *ani_stats)
 1105 {
 1106     struct ath_hal_9300 *ahp = AH9300(ah);
 1107     struct ar9300_ani_state *ani_state;
 1108     u_int32_t tx_frame_count, rx_frame_count, cycle_count;
 1109     u_int32_t rx_busy_count, rx_ext_busy_count;
 1110     int32_t listen_time;
 1111 
 1112     tx_frame_count = OS_REG_READ(ah, AR_TFCNT);
 1113     rx_frame_count = OS_REG_READ(ah, AR_RFCNT);
 1114     rx_busy_count = OS_REG_READ(ah, AR_RCCNT);
 1115     rx_ext_busy_count = OS_REG_READ(ah, AR_EXTRCCNT);
 1116     cycle_count = OS_REG_READ(ah, AR_CCCNT);
 1117 
 1118     ani_state = ahp->ah_curani;
 1119     if (ani_state->cycle_count == 0 || ani_state->cycle_count > cycle_count) {
 1120         /*
 1121          * Cycle counter wrap (or initial call); it's not possible
 1122          * to accurately calculate a value because the registers
 1123          * right shift rather than wrap--so punt and return 0.
 1124          */
 1125         listen_time = 0;
 1126         ahp->ah_stats.ast_ani_lzero++;
 1127 #if HAL_ANI_DEBUG
 1128         HALDEBUG(ah, HAL_DEBUG_ANI,
 1129             "%s: 1st call: ani_state->cycle_count=%d\n",
 1130             __func__, ani_state->cycle_count);
 1131 #endif
 1132     } else {
 1133         int32_t ccdelta = cycle_count - ani_state->cycle_count;
 1134         int32_t rfdelta = rx_frame_count - ani_state->rx_frame_count;
 1135         int32_t tfdelta = tx_frame_count - ani_state->tx_frame_count;
 1136         int32_t rcdelta = rx_busy_count - ani_state->rx_busy_count;
 1137         int32_t extrcdelta = rx_ext_busy_count - ani_state->rx_ext_busy_count;
 1138         listen_time = (ccdelta - rfdelta - tfdelta) / CLOCK_RATE(ah);
 1139 //#if HAL_ANI_DEBUG
 1140         HALDEBUG(ah, HAL_DEBUG_ANI,
 1141             "%s: cyclecount=%d, rfcount=%d, tfcount=%d, rcdelta=%d, extrcdelta=%d, listen_time=%d "
 1142             "CLOCK_RATE=%d\n",
 1143             __func__, ccdelta, rfdelta, tfdelta, rcdelta, extrcdelta,
 1144             listen_time, CLOCK_RATE(ah));
 1145 //#endif
 1146             /* Populate as appropriate */
 1147             ani_stats->cyclecnt_diff = ccdelta;
 1148             ani_stats->rxclr_cnt = rcdelta;
 1149             ani_stats->txframecnt_diff = tfdelta;
 1150             ani_stats->rxframecnt_diff = rfdelta;
 1151             ani_stats->extrxclr_cnt = extrcdelta;
 1152             ani_stats->listen_time = listen_time;
 1153             ani_stats->valid = AH_TRUE;
 1154     }
 1155     ani_state->cycle_count = cycle_count;
 1156     ani_state->tx_frame_count = tx_frame_count;
 1157     ani_state->rx_frame_count = rx_frame_count;
 1158     ani_state->rx_busy_count = rx_busy_count;
 1159     ani_state->rx_ext_busy_count = rx_ext_busy_count;
 1160     return listen_time;
 1161 }
 1162 
 1163 /*
 1164  * Do periodic processing.  This routine is called from a timer
 1165  */
 1166 void
 1167 ar9300_ani_ar_poll(struct ath_hal *ah, const HAL_NODE_STATS *stats,
 1168                 const struct ieee80211_channel *chan, HAL_ANISTATS *ani_stats)
 1169 {
 1170     struct ath_hal_9300 *ahp = AH9300(ah);
 1171     struct ar9300_ani_state *ani_state;
 1172     int32_t listen_time;
 1173     u_int32_t ofdm_phy_err_rate, cck_phy_err_rate;
 1174     u_int32_t ofdm_phy_err_cnt, cck_phy_err_cnt;
 1175     HAL_BOOL old_phy_noise_spur;
 1176 
 1177     ani_state = ahp->ah_curani;
 1178     ahp->ah_stats.ast_nodestats = *stats;        /* XXX optimize? */
 1179 
 1180     if (ani_state == NULL) {
 1181         /* should not happen */
 1182         HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
 1183             "%s: can't poll - no ANI not initialized for this channel\n",
 1184             __func__);
 1185         return;
 1186     }
 1187 
 1188     /*
 1189      * ar9300_ani_ar_poll is never called while scanning but we may have been
 1190      * scanning and now just restarted polling.  In this case we need to
 1191      * restore historical values.
 1192      */
 1193     if (ani_state->must_restore) {
 1194         HALDEBUG(ah, HAL_DEBUG_ANI,
 1195             "%s: must restore - calling ar9300_ani_restart\n", __func__);
 1196         ar9300_ani_reset(ah, AH_FALSE);
 1197         return;
 1198     }
 1199 
 1200     listen_time = ar9300_ani_get_listen_time(ah, ani_stats);
 1201     if (listen_time <= 0) {
 1202         ahp->ah_stats.ast_ani_lneg++;
 1203         /* restart ANI period if listen_time is invalid */
 1204         HALDEBUG(ah, HAL_DEBUG_ANI,
 1205             "%s: listen_time=%d - calling ar9300_ani_restart\n",
 1206             __func__, listen_time);
 1207         ar9300_ani_restart(ah);
 1208         return;
 1209     }
 1210     /* XXX beware of overflow? */
 1211     ani_state->listen_time += listen_time;
 1212 
 1213     /* Clear the mib counters and save them in the stats */
 1214     ar9300_update_mib_mac_stats(ah);
 1215     /* NB: these are not reset-on-read */
 1216     ofdm_phy_err_cnt = OS_REG_READ(ah, AR_PHY_ERR_1);
 1217     cck_phy_err_cnt = OS_REG_READ(ah, AR_PHY_ERR_2);
 1218 
 1219     /* Populate HAL_ANISTATS */
 1220     /* XXX TODO: are these correct? */
 1221     if (ani_stats) {
 1222             ani_stats->cckphyerr_cnt =
 1223                cck_phy_err_cnt - ani_state->cck_phy_err_count;
 1224             ani_stats->ofdmphyerrcnt_diff =
 1225               ofdm_phy_err_cnt - ani_state->ofdm_phy_err_count;
 1226     }
 1227 
 1228     /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
 1229     ahp->ah_stats.ast_ani_ofdmerrs +=
 1230         ofdm_phy_err_cnt - ani_state->ofdm_phy_err_count;
 1231     ani_state->ofdm_phy_err_count = ofdm_phy_err_cnt;
 1232 
 1233     ahp->ah_stats.ast_ani_cckerrs +=
 1234         cck_phy_err_cnt - ani_state->cck_phy_err_count;
 1235     ani_state->cck_phy_err_count = cck_phy_err_cnt;
 1236 
 1237     /*
 1238      * Note - the ANI code is using the aggregate listen time.
 1239      * The AR_PHY_CNT1/AR_PHY_CNT2 registers here are also
 1240      * free running, not clear-on-read and are free-running.
 1241      *
 1242      * So, ofdm_phy_err_rate / cck_phy_err_rate are accumulating
 1243      * the same as listenTime is accumulating.
 1244      */
 1245 
 1246 #if HAL_ANI_DEBUG
 1247     HALDEBUG(ah, HAL_DEBUG_ANI,
 1248         "%s: Errors: OFDM=0x%08x-0x0=%d   CCK=0x%08x-0x0=%d\n",
 1249         __func__, ofdm_phy_err_cnt, ofdm_phy_err_cnt,
 1250         cck_phy_err_cnt, cck_phy_err_cnt);
 1251 #endif
 1252 
 1253     /*
 1254      * If ani is not enabled, return after we've collected
 1255      * statistics
 1256      */
 1257     if (!DO_ANI(ah)) {
 1258         return;
 1259     }
 1260 
 1261     /*
 1262      * Calculate the OFDM/CCK phy error rate over the listen time interval.
 1263      * This is used in subsequent math to see if the OFDM/CCK phy error rate
 1264      * is above or below the threshold checks.
 1265      */
 1266 
 1267     ofdm_phy_err_rate =
 1268         ani_state->ofdm_phy_err_count * 1000 / ani_state->listen_time;
 1269     cck_phy_err_rate =
 1270         ani_state->cck_phy_err_count * 1000 / ani_state->listen_time;
 1271 
 1272     HALDEBUG(ah, HAL_DEBUG_ANI,
 1273         "%s: listen_time=%d (total: %d) OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
 1274         __func__, listen_time,
 1275         ani_state->listen_time,
 1276         ani_state->ofdm_noise_immunity_level, ofdm_phy_err_rate,
 1277         ani_state->cck_noise_immunity_level, cck_phy_err_rate,
 1278         ani_state->ofdms_turn);
 1279 
 1280     /*
 1281      * Check for temporary noise spurs.  This is intended to be used by
 1282      * rate control to check if we should try higher packet rates or not.
 1283      * If the noise period is short enough then we shouldn't avoid trying
 1284      * higher rates but if the noise is high/sustained then it's likely
 1285      * not a great idea to try the higher MCS rates.
 1286      */
 1287     if (ani_state->listen_time >= HAL_NOISE_DETECT_PERIOD) {
 1288         old_phy_noise_spur = ani_state->phy_noise_spur;
 1289         if (ofdm_phy_err_rate <= ani_state->ofdm_trig_low &&
 1290             cck_phy_err_rate <= ani_state->cck_trig_low) {
 1291             if (ani_state->listen_time >= HAL_NOISE_RECOVER_PERIOD) {
 1292                 ani_state->phy_noise_spur = 0;
 1293             }
 1294         } else {
 1295             ani_state->phy_noise_spur = 1;
 1296         }
 1297         if (old_phy_noise_spur != ani_state->phy_noise_spur) {
 1298             HALDEBUG(ah, HAL_DEBUG_ANI,
 1299                      "%s: environment change from %d to %d\n",
 1300                      __func__, old_phy_noise_spur, ani_state->phy_noise_spur);
 1301         }
 1302     }
 1303 
 1304     if (ani_state->listen_time > 5 * ahp->ah_ani_period) {
 1305         /*
 1306          * Check to see if need to lower immunity if
 1307          * 5 ani_periods have passed
 1308          */
 1309         if (ofdm_phy_err_rate <= ani_state->ofdm_trig_low &&
 1310             cck_phy_err_rate <= ani_state->cck_trig_low)
 1311         {
 1312             HALDEBUG(ah, HAL_DEBUG_ANI,
 1313                 "%s: 1. listen_time=%d OFDM:%d errs=%d/s(<%d)  "
 1314                 "CCK:%d errs=%d/s(<%d) -> ar9300_ani_lower_immunity\n",
 1315                 __func__, ani_state->listen_time,
 1316                 ani_state->ofdm_noise_immunity_level, ofdm_phy_err_rate,
 1317                 ani_state->ofdm_trig_low, ani_state->cck_noise_immunity_level,
 1318                 cck_phy_err_rate, ani_state->cck_trig_low);
 1319             ar9300_ani_lower_immunity(ah);
 1320             ani_state->ofdms_turn = !ani_state->ofdms_turn;
 1321         }
 1322         /*
 1323          * Force an ANI restart regardless of whether the lower immunity
 1324          * level was met.
 1325          */
 1326         HALDEBUG(ah, HAL_DEBUG_ANI,
 1327             "%s: 1 listen_time=%d ofdm=%d/s cck=%d/s - "
 1328             "calling ar9300_ani_restart\n",
 1329             __func__, ani_state->listen_time,
 1330             ofdm_phy_err_rate, cck_phy_err_rate);
 1331         ar9300_ani_restart(ah);
 1332      } else if (ani_state->listen_time > ahp->ah_ani_period) {
 1333         /* check to see if need to raise immunity */
 1334         if (ofdm_phy_err_rate > ani_state->ofdm_trig_high &&
 1335             (cck_phy_err_rate <= ani_state->cck_trig_high ||
 1336              ani_state->ofdms_turn))
 1337         {
 1338             HALDEBUG(ah, HAL_DEBUG_ANI,
 1339                 "%s: 2 listen_time=%d OFDM:%d errs=%d/s(>%d) -> "
 1340                 "ar9300_ani_ofdm_err_trigger\n",
 1341                 __func__, ani_state->listen_time,
 1342                 ani_state->ofdm_noise_immunity_level, ofdm_phy_err_rate,
 1343                 ani_state->ofdm_trig_high);
 1344             ar9300_ani_ofdm_err_trigger(ah);
 1345             ar9300_ani_restart(ah);
 1346             ani_state->ofdms_turn = AH_FALSE;
 1347         } else if (cck_phy_err_rate > ani_state->cck_trig_high) {
 1348             HALDEBUG(ah, HAL_DEBUG_ANI,
 1349                 "%s: 3 listen_time=%d CCK:%d errs=%d/s(>%d) -> "
 1350                 "ar9300_ani_cck_err_trigger\n",
 1351                 __func__, ani_state->listen_time,
 1352                 ani_state->cck_noise_immunity_level, cck_phy_err_rate,
 1353                 ani_state->cck_trig_high);
 1354             ar9300_ani_cck_err_trigger(ah);
 1355             ar9300_ani_restart(ah);
 1356             ani_state->ofdms_turn = AH_TRUE;
 1357         }
 1358     }
 1359 
 1360     /*
 1361      * Note that currently this poll function doesn't reset the listen
 1362      * time after it accumulates a second worth of error samples.
 1363      * It will continue to accumulate samples until a counter overflows,
 1364      * or a raise threshold is met, or 5 seconds passes.
 1365      */
 1366 }
 1367 
 1368 /*
 1369  * The poll function above calculates short noise spurs, caused by non-80211
 1370  * devices, based on OFDM/CCK Phy errs.
 1371  * If the noise is short enough, we don't want our ratectrl Algo to stop probing
 1372  * higher rates, due to bad PER.
 1373  */
 1374 HAL_BOOL
 1375 ar9300_is_ani_noise_spur(struct ath_hal *ah)
 1376 {
 1377     struct ath_hal_9300 *ahp = AH9300(ah);
 1378     struct ar9300_ani_state *ani_state;
 1379 
 1380     ani_state = ahp->ah_curani;
 1381 
 1382     return ani_state->phy_noise_spur;
 1383 }
 1384 

Cache object: fddf1fd738231c6b0cf85343e0014252


[ 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.