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_paprd.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 #include "ah.h"
   19 #include "ar9300.h"
   20 #include "ah_internal.h"
   21 #include "ar9300paprd.h"
   22 #include "ar9300reg.h"
   23 
   24 
   25 #if ATH_SUPPORT_PAPRD
   26 
   27 static struct ar9300_paprd_pwr_adjust ar9300_paprd_pwr_adj_array[] = {
   28 /*   rate index     ,   register offset   ,  mask of register               , */
   29   {ALL_TARGET_HT20_5, AR_PHY_POWERTX_RATE5, AR_PHY_POWERTX_RATE5_POWERTXHT20_3,
   30 /* mask offset of register             ,  offset  dB*/
   31    AR_PHY_POWERTX_RATE5_POWERTXHT20_3_S,      1},
   32   {ALL_TARGET_HT20_6, AR_PHY_POWERTX_RATE6, AR_PHY_POWERTX_RATE6_POWERTXHT20_4,
   33    AR_PHY_POWERTX_RATE6_POWERTXHT20_4_S,      2},
   34   {ALL_TARGET_HT20_7, AR_PHY_POWERTX_RATE6, AR_PHY_POWERTX_RATE6_POWERTXHT20_5,
   35    AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S,      2},
   36   {ALL_TARGET_HT40_5, AR_PHY_POWERTX_RATE7, AR_PHY_POWERTX_RATE7_POWERTXHT40_3,
   37    AR_PHY_POWERTX_RATE7_POWERTXHT40_3_S,      1},
   38   {ALL_TARGET_HT40_6, AR_PHY_POWERTX_RATE8, AR_PHY_POWERTX_RATE8_POWERTXHT40_4,
   39    AR_PHY_POWERTX_RATE8_POWERTXHT40_4_S,      2},
   40   {ALL_TARGET_HT40_7, AR_PHY_POWERTX_RATE8, AR_PHY_POWERTX_RATE8_POWERTXHT40_5,
   41    AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S,      2},
   42  {ALL_TARGET_LEGACY_54, AR_PHY_POWERTX_RATE2, AR_PHY_POWERTX_RATE2_POWERTX54M_7,
   43    AR_PHY_POWERTX_RATE2_POWERTX54M_7_S,       2},
   44 };
   45 
   46 HAL_BOOL create_pa_curve(u_int32_t * paprd_train_data_l,
   47     u_int32_t *paprd_train_data_u, u_int32_t *pa_table, u_int32_t *g_fxp_ext,
   48     int * pa_in);
   49 
   50 static int
   51 ar9300_paprd_setup_single_table(struct ath_hal *ah, struct ieee80211_channel * chan)
   52 {
   53     int is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
   54     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
   55     struct ath_hal_9300 *ahp = AH9300(ah);
   56     int is_ht40 = 0;
   57     u_int32_t am_mask = 0;
   58     u_int32_t val = OS_REG_READ(ah, AR_2040_MODE);
   59     u_int8_t target_power_val_t2[ar9300_rate_size];
   60     int      power_tblindex = 0, power_delta = 0;
   61     int      paprd_scale_factor = 5;  
   62 
   63     const u_int8_t mask2num[8] = {
   64         0 /* 000 */,
   65         1 /* 001 */,
   66         1 /* 010 */,
   67         2 /* 011 */,
   68         1 /* 100 */,
   69         2 /* 101 */,
   70         2 /* 110 */,
   71         3 /* 111 */
   72     };
   73 
   74     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
   75 
   76 #define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x)
   77 
   78     ar9300_set_target_power_from_eeprom(ah, ichan->channel, target_power_val_t2);
   79     if (val & HAL_HT_MACMODE_2040) {
   80         is_ht40 = 1;
   81     }
   82 
   83     /*
   84      * Note on paprd_scale_factor
   85      * This factor is saved in eeprom as 3 bit fields in following fashion. 
   86      * In 5G there are 3 scale factors -- upper, mid and lower band.
   87      * Upper band scale factor is coded in bits 25-27 of
   88      * modal_header_5g.paprd_rate_mask_ht20.
   89      * Mid band scale factor is coded in bits 28-30 of
   90      * modal_header_5g.paprd_rate_mask_ht40.
   91      * Lower band scale factor is coded in bits 25-27 of
   92      * modal_header_5g.paprd_rate_mask_ht40.
   93      * For 2G there is only one scale factor. It is saved in bits 25-27 of
   94      * modal_header_2g.paprd_rate_mask_ht20.
   95      */
   96     AH_PAPRD_GET_SCALE_FACTOR(paprd_scale_factor, eep, is_2g, ichan->channel);
   97     if (is_2g) {
   98         if (is_ht40) {
   99             am_mask = ahp->ah_2g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
  100             power_tblindex = ALL_TARGET_HT40_0_8_16;
  101         } else {
  102             am_mask = ahp->ah_2g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
  103             power_tblindex = ALL_TARGET_HT20_0_8_16;
  104         }
  105         if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
  106             if (is_ht40) {
  107                 ahp->paprd_training_power = 
  108                     target_power_val_t2[ALL_TARGET_HT40_7] + 2;
  109             } else {
  110                 ahp->paprd_training_power = 
  111                     target_power_val_t2[ALL_TARGET_HT20_7] + 2;
  112             }
  113                 } else if (AR_SREV_POSEIDON(ah)) {
  114             ahp->paprd_training_power = 25;
  115         } else {
  116             ahp->paprd_training_power =
  117                 OS_REG_READ_FIELD_ALT(ah, AR_PHY_POWERTX_RATE5,
  118                 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
  119             if (ABS(target_power_val_t2[power_tblindex], 
  120                 ahp->paprd_training_power) >  paprd_scale_factor)
  121             {
  122                 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
  123                     "%s[%d]: Chan %d paprd failing EEP PWR 0x%08x" 
  124                     "TGT PWR 0x%08x\n", __func__, __LINE__, ichan->channel,
  125                     target_power_val_t2[power_tblindex], 
  126                     ahp->paprd_training_power);
  127                 goto FAILED;
  128             }
  129             
  130             power_delta =
  131                 ABS(ahp->paprd_training_power, 
  132                     target_power_val_t2[power_tblindex]);
  133 
  134             power_delta = power_delta > 4 ? 0 : 4 - power_delta;
  135             ahp->paprd_training_power = 
  136                 ahp->paprd_training_power - power_delta;
  137         }
  138 
  139 
  140     } else {
  141         if (is_ht40) {
  142             ahp->paprd_training_power =
  143                             OS_REG_READ_FIELD_ALT(ah, AR_PHY_POWERTX_RATE8,
  144                                 AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
  145             am_mask = ahp->ah_5g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
  146             switch (mask2num[ahp->ah_tx_chainmask])
  147             {
  148             case 1:
  149                 power_delta = 6;
  150                 break;
  151             case 2:
  152                 power_delta = 4;
  153                 break;
  154             case 3:
  155                 power_delta = 2;
  156                 break;
  157             default:
  158                 goto FAILED;
  159                 break;
  160             }
  161             power_tblindex = ALL_TARGET_HT40_7;
  162         } else {
  163             ahp->paprd_training_power =
  164                             OS_REG_READ_FIELD_ALT(ah, AR_PHY_POWERTX_RATE6,
  165                                 AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
  166             am_mask = ahp->ah_5g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
  167             switch (mask2num[ahp->ah_tx_chainmask])
  168             {
  169             case 1:
  170                 power_delta = 6;
  171                 break;
  172             case 2:
  173                 power_delta = 4;
  174                 break;
  175             case 3:
  176                 power_delta = 2;
  177                 break;
  178             default:
  179                 goto FAILED;
  180                 break;
  181             }
  182             power_tblindex = ALL_TARGET_HT20_7;
  183         }
  184         /* Adjust for scale factor */
  185         ahp->paprd_training_power += paprd_scale_factor;
  186         /*
  187         ath_hal_printf(ah, "%s[%d] paprd_scale_factor %d power_delta %d\n",
  188             __func__, __LINE__, paprd_scale_factor, power_delta);
  189          */
  190         if (ABS(target_power_val_t2[power_tblindex], ahp->paprd_training_power)
  191             >  paprd_scale_factor)
  192         {
  193             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
  194                 "%s[%d]: Chan %d paprd failing EEP PWR 0x%08x TGT PWR 0x%08x\n",
  195                 __func__, __LINE__, ichan->channel,
  196                 target_power_val_t2[power_tblindex], ahp->paprd_training_power);
  197             goto FAILED;
  198         }
  199         ahp->paprd_training_power = ahp->paprd_training_power + power_delta;
  200     }
  201 
  202     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s 2G %d HT40 %d am_mask 0x%08x\n",
  203         __func__, is_2g, is_ht40, am_mask);
  204     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
  205         am_mask);
  206     if (AR_SREV_HORNET(ah)) {
  207         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
  208             0);
  209     }
  210     else {
  211         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
  212             am_mask);
  213     }
  214 
  215     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
  216         AR_PHY_PAPRD_HT40_MASK);
  217     /* chain0 */
  218     if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
  219         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
  220             AR_PHY_PAPRD_CTRL0_B0_USE_SINGLE_TABLE_MASK, 1);
  221         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  222             AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2PM_ENABLE_0, 1);
  223         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  224             AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2AM_ENABLE_0, 1);
  225         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  226             AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
  227         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  228             AR_PHY_PAPRD_CTRL1_B0_PA_GAIN_SCALE_FACT_0_MASK, 181);
  229         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  230             AR_PHY_PAPRD_CTRL1_B0_PAPRD_MAG_SCALE_FACT_0, 361);
  231         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  232             AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
  233         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
  234             AR_PHY_PAPRD_CTRL0_B0_PAPRD_MAG_THRSH_0, 3);
  235     }
  236 
  237     /* chain1 */
  238     if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
  239         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
  240             AR_PHY_PAPRD_CTRL0_B1_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_1, 1);
  241         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  242             AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2PM_ENABLE_1, 1);
  243         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  244             AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2AM_ENABLE_1, 1);
  245         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  246             AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
  247         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  248             AR_PHY_PAPRD_CTRL1_B1_PA_GAIN_SCALE_FACT_1_MASK, 181);
  249         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  250             AR_PHY_PAPRD_CTRL1_B1_PAPRD_MAG_SCALE_FACT_1, 361);
  251         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  252             AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
  253         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
  254             AR_PHY_PAPRD_CTRL0_B1_PAPRD_MAG_THRSH_1, 3);
  255     }
  256 
  257     /* chain2 */
  258     if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
  259         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
  260             AR_PHY_PAPRD_CTRL0_B2_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_2, 1);
  261         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  262             AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2PM_ENABLE_2, 1);
  263         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  264             AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2AM_ENABLE_2, 1);
  265         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  266             AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
  267         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  268             AR_PHY_PAPRD_CTRL1_B2_PA_GAIN_SCALE_FACT_2_MASK, 181);
  269         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  270             AR_PHY_PAPRD_CTRL1_B2_PAPRD_MAG_SCALE_FACT_2, 361);
  271         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  272             AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
  273         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
  274             AR_PHY_PAPRD_CTRL0_B2_PAPRD_MAG_THRSH_2, 3);
  275     }
  276 
  277     ar9300_enable_paprd(ah, AH_FALSE, chan);
  278     if (AR_SREV_POSEIDON(ah)) {
  279         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  280             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30);
  281         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  282             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1);
  283         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  284             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1);
  285         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  286             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0);
  287         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  288             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0);
  289         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  290             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
  291         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  292             AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
  293         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2_POSEIDON,
  294             AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 148);
  295         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  296             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4);
  297         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  298             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4);
  299         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  300             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
  301         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  302             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
  303         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  304                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -3);
  305         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  306             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -15);
  307         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  308             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1);
  309         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
  310             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0);
  311         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
  312             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400);
  313         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
  314             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES, 100);
  315     } else {
  316         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
  317             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30);
  318         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
  319             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1);
  320         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
  321             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1);
  322         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
  323             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0);
  324         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
  325             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0);
  326         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
  327             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
  328         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
  329             AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
  330         if (is_2g) {
  331                  if(AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)){ 
  332              OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
  333                  AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 0x91);
  334            }else{
  335              OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
  336                  AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147);             
  337            }
  338         }
  339                 else if (AR_SREV_WASP(ah) && !is_2g) {
  340             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
  341                     AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 137);
  342                 } else {
  343             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
  344                     AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147);
  345         }
  346         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  347             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4);
  348         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  349             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4);
  350         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  351             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
  352         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  353             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
  354         if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
  355             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  356                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -3);
  357         } else {
  358             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  359                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
  360         }
  361         if (is_2g) {
  362             if(AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)){           
  363                 OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  364                     AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -10);
  365             }else{
  366                 OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  367                     AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -15);                            
  368             }
  369         }
  370         else {
  371              OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  372                  AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -10);
  373         }
  374         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
  375             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1);
  376         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
  377             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0);
  378         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
  379             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400);
  380         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
  381             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES, 100);
  382     }
  383 
  384     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0,
  385         AR_PHY_PAPRD_PRE_POST_SCALE_0_B0_PAPRD_PRE_POST_SCALING_0_0, 261376);
  386     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0,
  387         AR_PHY_PAPRD_PRE_POST_SCALE_1_B0_PAPRD_PRE_POST_SCALING_1_0, 248079);
  388     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0,
  389         AR_PHY_PAPRD_PRE_POST_SCALE_2_B0_PAPRD_PRE_POST_SCALING_2_0, 233759);
  390     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0,
  391         AR_PHY_PAPRD_PRE_POST_SCALE_3_B0_PAPRD_PRE_POST_SCALING_3_0, 220464);
  392     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0,
  393         AR_PHY_PAPRD_PRE_POST_SCALE_4_B0_PAPRD_PRE_POST_SCALING_4_0, 208194);
  394     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0,
  395         AR_PHY_PAPRD_PRE_POST_SCALE_5_B0_PAPRD_PRE_POST_SCALING_5_0, 196949);
  396     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0,
  397         AR_PHY_PAPRD_PRE_POST_SCALE_6_B0_PAPRD_PRE_POST_SCALING_6_0, 185706);
  398     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
  399         AR_PHY_PAPRD_PRE_POST_SCALE_7_B0_PAPRD_PRE_POST_SCALING_7_0, 175487);
  400     return 0;
  401     
  402 FAILED:
  403     return -1;
  404 #undef ABS    
  405 }
  406 
  407 /*
  408  * XXX There's another copy of this in ar9300_reset.c, use that!
  409  */
  410 #if 0
  411 static inline HAL_CHANNEL_INTERNAL*
  412 ar9300_check_chan(struct ath_hal *ah, HAL_CHANNEL *chan)
  413 {
  414     if ((AR9300_IS_CHAN(chan, CHANNEL_2GHZ) ^
  415          AR9300_IS_CHAN(chan, CHANNEL_5GHZ)) == 0)
  416     {
  417         HALDEBUG(ah, HAL_DEBUG_CHANNEL,
  418             "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
  419             __func__, chan->channel, chan->channel_flags);
  420         return AH_NULL;
  421     }
  422 
  423     if ((AR9300_IS_CHAN(chan, CHANNEL_OFDM)     ^
  424          AR9300_IS_CHAN(chan, CHANNEL_CCK)      ^
  425          AR9300_IS_CHAN(chan, CHANNEL_HT20)     ^
  426          AR9300_IS_CHAN(chan, CHANNEL_HT40PLUS) ^
  427          AR9300_IS_CHAN(chan, CHANNEL_HT40MINUS)) == 0)
  428     {
  429         HALDEBUG(ah, HAL_DEBUG_CHANNEL,
  430             "%s: invalid channel %u/0x%x; not marked as "
  431             "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n", __func__,
  432             chan->channel, chan->channel_flags);
  433         return AH_NULL;
  434     }
  435 
  436     return (ath_hal_checkchannel(ah, chan));
  437 }
  438 #endif
  439 
  440 void ar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag,
  441     struct ieee80211_channel * chan)
  442 {
  443     HAL_BOOL enable = enable_flag;
  444     u_int32_t am_mask = 0;
  445     u_int32_t val = OS_REG_READ(ah, AR_2040_MODE);
  446     int is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
  447     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
  448     int is_ht40 = 0;
  449     struct ath_hal_9300 *ahp = AH9300(ah);
  450 
  451     if (val & HAL_HT_MACMODE_2040) {
  452         is_ht40 = 1;
  453     }
  454     if (enable_flag == AH_TRUE) {
  455         ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
  456 
  457         if (!is_2g) {
  458             /*
  459              * 3 bits for modal_header_5g.paprd_rate_mask_ht20
  460              * is used for sub band disabling of paprd.
  461              * 5G band is divided into 3 sub bands -- upper, mid, lower.
  462              * If bit 30 of modal_header_5g.paprd_rate_mask_ht20 is set
  463              * to one -- disable paprd for upper 5G
  464              * If bit 29 of modal_header_5g.paprd_rate_mask_ht20 is set
  465              * to one -- disable paprd for mid 5G
  466              * If bit 28 of modal_header_5g.paprd_rate_mask_ht20 is set
  467              * to one -- disable paprd for lower 5G
  468              * u_int32_t am_mask = eep->modal_header_5g.paprd_rate_mask_ht20;
  469              */
  470             if (ichan->channel >= UPPER_5G_SUB_BANDSTART) {
  471                 if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 30)) {
  472                     enable = AH_FALSE;
  473                 }
  474             } else if (ichan->channel >= MID_5G_SUB_BANDSTART) {
  475                 if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 29)) {
  476                     enable = AH_FALSE;
  477                 }
  478             } else { /* must be in the lower 5G subband */
  479                 if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 28)) {
  480                     enable = AH_FALSE;
  481                 }
  482             }
  483         }
  484 
  485         if (ahp->ah_paprd_broken) {
  486             ahp->ah_paprd_broken = AH_FALSE;
  487             enable = AH_FALSE;
  488 
  489             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 
  490                      "%s: PAPRD is in bad state. Don't enable PAPRD\n",
  491                      __func__);
  492         }
  493     }
  494     if (enable) {
  495         HAL_CHANNEL_INTERNAL *ichan;
  496         if (is_2g) {
  497             if (is_ht40) {
  498                 am_mask = ahp->ah_2g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
  499             } else {
  500                 am_mask = ahp->ah_2g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
  501             }
  502         } else {
  503             if (is_ht40) {
  504                 am_mask = ahp->ah_5g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
  505             } else {
  506                 am_mask = ahp->ah_5g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
  507             }
  508         }
  509         /* Earlier we promgrammed TGT Power with Scaled down value, since
  510          * PAPRD CAL was not done.
  511          * Now we finish PAPRD CAL, so bump up the TGT PWR to original
  512          * EEPROM Power. CTLs calc and Maverickd in
  513          * "ar9300_eeprom_set_transmit_power"
  514          */
  515         ichan = ar9300_check_chan(ah, chan);
  516         ichan->paprd_table_write_done = 1;
  517 //        chan->paprd_table_write_done = 1;
  518         /*
  519         ath_hal_printf(ah, "%s[%d] eeprom_set_transmit_power PAPRD\n",
  520             __func__, __LINE__);
  521          */
  522         if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
  523             ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
  524             ath_hal_get_twice_max_regpower(AH_PRIVATE(ah), ichan, chan),
  525             AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit)) != HAL_OK) {
  526             ichan->paprd_table_write_done = 0;
  527 //            chan->paprd_table_write_done = 0;
  528             /* Intentional print */
  529             ath_hal_printf(ah,
  530                 "%s[%d] eeprom_set_transmit_power failed ABORT PAPRD\n",
  531                 __func__, __LINE__);
  532             
  533             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
  534                 AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0, 0);
  535             if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah)) {
  536                 OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
  537                     AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1, 0);
  538                 if (!AR_SREV_JUPITER(ah) || (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK)) {
  539                     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
  540                         AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2, 0);
  541 
  542                 }
  543             }
  544             return;
  545         }
  546 
  547         HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s 2G %d HT40 %d am_mask 0x%08x\n",
  548             __func__, is_2g, is_ht40, am_mask);
  549         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
  550             am_mask);
  551         if (AR_SREV_HORNET(ah)) {
  552             OS_REG_RMW_FIELD_ALT(ah,
  553                 AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, 0);
  554         } else {
  555             OS_REG_RMW_FIELD_ALT(ah,
  556                 AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
  557         }
  558 
  559         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
  560             AR_PHY_PAPRD_HT40_MASK);
  561         /* chain0 */
  562         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
  563             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
  564                 AR_PHY_PAPRD_CTRL0_B0_USE_SINGLE_TABLE_MASK, 1);
  565             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  566                 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2PM_ENABLE_0, 1);
  567             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  568                 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2AM_ENABLE_0, 1);
  569             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  570                 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
  571             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  572                 AR_PHY_PAPRD_CTRL1_B0_PA_GAIN_SCALE_FACT_0_MASK, 181);
  573             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  574                 AR_PHY_PAPRD_CTRL1_B0_PAPRD_MAG_SCALE_FACT_0, 361);
  575             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
  576                 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
  577             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
  578                 AR_PHY_PAPRD_CTRL0_B0_PAPRD_MAG_THRSH_0, 3);
  579         }
  580         /* chain1 */
  581         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
  582             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
  583                 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_1, 1);
  584             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  585                 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2PM_ENABLE_1, 1);
  586             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  587                 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2AM_ENABLE_1, 1);
  588             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  589                 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
  590             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  591                 AR_PHY_PAPRD_CTRL1_B1_PA_GAIN_SCALE_FACT_1_MASK, 181);
  592             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  593                 AR_PHY_PAPRD_CTRL1_B1_PAPRD_MAG_SCALE_FACT_1, 361);
  594             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
  595                 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
  596             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
  597                 AR_PHY_PAPRD_CTRL0_B1_PAPRD_MAG_THRSH_1, 3);
  598         }
  599         /* chain2 */
  600         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
  601             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
  602                 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_2, 1);
  603             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  604                 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2PM_ENABLE_2, 1);
  605             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  606                 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2AM_ENABLE_2, 1);
  607             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  608                 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
  609             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  610                 AR_PHY_PAPRD_CTRL1_B2_PA_GAIN_SCALE_FACT_2_MASK, 181);
  611             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  612                 AR_PHY_PAPRD_CTRL1_B2_PAPRD_MAG_SCALE_FACT_2, 361);
  613             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
  614                 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
  615             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
  616                 AR_PHY_PAPRD_CTRL0_B2_PAPRD_MAG_THRSH_2, 3);
  617         }
  618         
  619         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
  620             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
  621                 AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0, 1);
  622         }
  623         
  624         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
  625             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
  626                 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1, 1);
  627         }
  628 
  629         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
  630             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
  631                 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2, 1);
  632         }
  633         
  634     } else {
  635         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
  636             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
  637                 AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0, 0);
  638         }
  639         
  640         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
  641             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
  642                 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1, 0);
  643         }
  644         
  645         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
  646             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
  647                 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2, 0);
  648         }
  649     }
  650 }
  651 
  652 static void ar9300_gain_table_entries(struct ath_hal *ah)
  653 {
  654     int i;
  655     u_int32_t reg;
  656     u_int32_t *gain_table_entries = AH9300(ah)->paprd_gain_table_entries;
  657     u_int32_t *gain_vs_table_index = AH9300(ah)->paprd_gain_table_index;
  658 
  659     reg = AR_PHY_TXGAIN_TAB(1);
  660 
  661     for (i = 0; i < 32; i++) {
  662         gain_table_entries[i] = OS_REG_READ(ah, reg);
  663         gain_vs_table_index[i] = (gain_table_entries[i] >> 24) & 0xff;
  664         /*
  665          * ath_hal_printf(
  666          *     ah, "+++reg 0x%08x gain_table_entries[%d] = 0x%08x \n", 
  667          *     reg, i, gain_table_entries[i]);
  668          */
  669         reg = reg + 4;
  670     }
  671 }
  672 
  673 /* Get gain index for Target power */
  674 static unsigned int ar9300_get_desired_gain_for_chain(struct ath_hal *ah,
  675     int chain_num, int target_power)
  676 {
  677     int olpc_gain_delta = 0;
  678     int alpha_therm = 0, alpha_volt = 0;
  679     int therm_cal_value = 0, volt_cal_value = 0;
  680     int latest_therm_value = 0, latest_volt_value = 0, olpc_gain_delta_tmp = 0;
  681     int thermal_gain_corr = 0, voltage_gain_corr = 0, desired_scale = 0;
  682     int desired_gain = 0;
  683     int cl_gain_mod = 0;
  684 
  685     /* Clear the training done bit */
  686     if (AR_SREV_POSEIDON(ah)) {
  687         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
  688             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
  689     } else {
  690         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
  691             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
  692     }
  693     /*field_read("BB_tpc_12.desired_scale_ht40_5", &desired_scale);*/
  694     desired_scale =
  695         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_12,
  696         AR_PHY_TPC_12_DESIRED_SCALE_HT40_5);
  697     /*field_read("BB_tpc_19.alpha_therm", &alpha_therm);*/
  698     alpha_therm =
  699         OS_REG_READ_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM);
  700     /*field_read("BB_tpc_19.alpha_volt", &alpha_volt);*/
  701     alpha_volt =
  702         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALT_ALPHA_VOLT);
  703 
  704     /*field_read("BB_tpc_18.therm_cal_value", &therm_cal_value);*/
  705     therm_cal_value =
  706         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_18,
  707         AR_PHY_TPC_18_ALT_THERM_CAL_VALUE);
  708     /*field_read("BB_tpc_18.volt_cal_value", &volt_cal_value);*/
  709     volt_cal_value =
  710         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_18,
  711         AR_PHY_TPC_18_ALT_VOLT_CAL_VALUE);
  712 
  713     /*field_read("BB_therm_adc_4.latest_therm_value", &latest_therm_value);*/
  714     latest_therm_value =
  715         OS_REG_READ_FIELD_ALT(ah, AR_PHY_THERM_ADC_4,
  716         AR_PHY_THERM_ADC_4_LATEST_THERM_VALUE);
  717     /*field_read("BB_therm_adc_4.latest_volt_value", &latest_volt_value);*/
  718     latest_volt_value =
  719         OS_REG_READ_FIELD_ALT(ah, AR_PHY_THERM_ADC_4,
  720         AR_PHY_THERM_ADC_4_LATEST_VOLT_VALUE);
  721 
  722     /*
  723      * sprintf(
  724      *     field_name, "%s%d%s%d\0", "BB_tpc_11_b", 
  725      *     chain_num, ".olpc_gain_delta_", chain_num);
  726      */
  727     /*field_read(field_name, &olpc_gain_delta_tmp);*/
  728 
  729 
  730     if (chain_num == 0) {
  731         olpc_gain_delta_tmp =
  732             OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_11_B0,
  733             AR_PHY_TPC_11_B0_OLPC_GAIN_DELTA_0);
  734         cl_gain_mod = OS_REG_READ_FIELD_ALT(ah, AR_PHY_CL_TAB_0, 
  735             AR_PHY_CL_TAB_0_CL_GAIN_MOD);
  736     } else if (chain_num == 1) {
  737         if (!AR_SREV_POSEIDON(ah)) {
  738             olpc_gain_delta_tmp =
  739                 OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_11_B1,
  740                 AR_PHY_TPC_11_B1_OLPC_GAIN_DELTA_1);
  741             cl_gain_mod = OS_REG_READ_FIELD_ALT(ah, AR_PHY_CL_TAB_1, 
  742                 AR_PHY_CL_TAB_1_CL_GAIN_MOD);
  743         }
  744     } else if (chain_num == 2) {
  745         if (!AR_SREV_POSEIDON(ah)) {
  746             olpc_gain_delta_tmp =
  747                 OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_11_B2,
  748                 AR_PHY_TPC_11_B2_OLPC_GAIN_DELTA_2);
  749             cl_gain_mod = OS_REG_READ_FIELD_ALT(ah, AR_PHY_CL_TAB_2, 
  750                 AR_PHY_CL_TAB_2_CL_GAIN_MOD);
  751         }
  752     } else {
  753         /* invalid chain_num */
  754     }
  755 
  756     if (olpc_gain_delta_tmp < 128) {
  757         olpc_gain_delta = olpc_gain_delta_tmp;
  758     } else {
  759         olpc_gain_delta = olpc_gain_delta_tmp - 256;
  760     }
  761 
  762     thermal_gain_corr =
  763         (int) (alpha_therm * (latest_therm_value - therm_cal_value) +
  764         128) >> 8;
  765     voltage_gain_corr =
  766         (int) (alpha_volt * (latest_volt_value - volt_cal_value) + 64) >> 7;
  767     desired_gain =
  768         target_power - olpc_gain_delta - thermal_gain_corr -
  769         voltage_gain_corr + desired_scale + cl_gain_mod;
  770     /*
  771      * printf(
  772      *     "olpc_gain_delta %d, desired_gain %d\n", 
  773      *     olpc_gain_delta, desired_gain);
  774      */
  775 #if 0
  776     ath_hal_printf(ah,
  777         "+++ target_power %d olpc_gain_delta %d, cl_gain_mod %d,"
  778         "thermal_gain_corr %d  voltage_gain_corr %d desired_scale %d"
  779         "desired_gain %d\n",
  780         target_power, olpc_gain_delta, cl_gain_mod, thermal_gain_corr,
  781         voltage_gain_corr,
  782         desired_scale, desired_gain);
  783 #endif
  784     return (unsigned int) desired_gain;
  785 }
  786 
  787 static void ar9300_tx_force_gain(struct ath_hal *ah, unsigned int gain_index)
  788 {
  789     int selected_gain_entry, txbb1dbgain, txbb6dbgain, txmxrgain;
  790     int padrvgn_a, padrvgn_b, padrvgn_c, padrvgn_d;
  791     u_int32_t *gain_table_entries = AH9300(ah)->paprd_gain_table_entries;
  792 
  793     /*u_int32_t *gain_vs_table_index = ah->paprd_gain_table_index;*/
  794     selected_gain_entry = gain_table_entries[gain_index];
  795     txbb1dbgain = selected_gain_entry & 0x7;
  796     txbb6dbgain = (selected_gain_entry >> 3) & 0x3;
  797     txmxrgain = (selected_gain_entry >> 5) & 0xf;
  798     padrvgn_a = (selected_gain_entry >> 9) & 0xf;
  799     padrvgn_b = (selected_gain_entry >> 13) & 0xf;
  800     padrvgn_c = (selected_gain_entry >> 17) & 0xf;
  801     padrvgn_d = (selected_gain_entry >> 21) & 0x3;
  802 
  803     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  804         AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN, txbb1dbgain);
  805     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  806         AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN, txbb6dbgain);
  807     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  808         AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN, txmxrgain);
  809     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  810         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA, padrvgn_a);
  811     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  812         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB, padrvgn_b);
  813     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  814         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC, padrvgn_c);
  815     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  816         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND, padrvgn_d);
  817     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  818         AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL, 0);
  819     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
  820         AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN, 0);
  821 
  822     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0);
  823     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN, 0);
  824 }
  825 
  826 #define HAL_DEBUG_PAPRD HAL_DEBUG_CALIBRATE  /* driver: conditionally print */
  827 
  828 #if defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG)
  829 static void ar9300_paprd_debug_print(struct ath_hal *ah)
  830 {
  831     int temp;
  832     int txbb1dbgain, txbb6dbgain, txmxrgain;
  833     int padrvgn_a, padrvgn_b, padrvgn_c, padrvgn_d;
  834 
  835     if (AR_SREV_POSEIDON(ah)) {
  836         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
  837         temp =
  838             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  839             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP);
  840         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  841             "BB_paprd_trainer_cntl1.cf_paprd_lb_skip=0x%x\n", temp);
  842         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_enable", &temp);*/
  843         temp =
  844             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  845             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE);
  846         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  847             "BB_paprd_trainer_cntl1.cf_paprd_lb_enable=0x%x\n", temp);
  848         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force", &temp);*/
  849         temp =
  850             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  851             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE);
  852         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  853             "BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force=0x%x\n", temp);
  854         /*
  855          * field_read(
  856          *     "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
  857          */
  858         temp =
  859             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  860             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE);
  861         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  862             "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force=0x%x\n", temp);
  863         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable", &temp);*/
  864         temp =
  865             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  866             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE);
  867         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  868             "BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable=0x%x\n", temp);
  869         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_agc2_settling", &temp);*/
  870         temp =
  871             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  872             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING);
  873         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  874             "BB_paprd_trainer_cntl1.cf_paprd_agc2_settling=0x%x\n", temp);
  875         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_train_enable", &temp);*/
  876         temp =
  877             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
  878             AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE);
  879         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  880             "BB_paprd_trainer_cntl1.cf_paprd_train_enable=0x%x\n", temp);
  881         /*
  882          * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
  883          */
  884         temp =
  885             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2_POSEIDON,
  886             AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN);
  887         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  888             "BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain=0x%x\n", temp);
  889         /*field_read("BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len", &temp);*/
  890         temp =
  891             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  892             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN);
  893         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  894             "BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len=0x%x\n", temp);
  895         /*
  896          * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
  897          */
  898         temp =
  899             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  900             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN);
  901         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  902             "BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len=0x%x\n", temp);
  903         /*
  904          * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
  905          */
  906         temp =
  907             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  908             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES);
  909         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  910             "BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages=0x%x\n", temp);
  911         /*
  912          * field_read(
  913          *     "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
  914          */
  915         temp =
  916             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  917             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL);
  918         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  919             "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del=0x%x\n", temp);
  920         /*field_read("BB_paprd_trainer_cntl3.cf_paprd_quick_drop", &temp);*/
  921         temp =
  922             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  923             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
  924         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  925             "BB_paprd_trainer_cntl3.cf_paprd_quick_drop=0x%x\n", temp);
  926         /*
  927          * field_read(
  928          *     "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
  929          */
  930         temp =
  931             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  932             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE);
  933         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  934             "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size=0x%x\n", temp);
  935         /*
  936          * field_read("BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
  937          */
  938         temp =
  939             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
  940             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE);
  941         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  942             "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable=0x%x\n", temp);
  943         /*field_read("BB_paprd_trainer_cntl4.cf_paprd_safety_delta", &temp);*/
  944         temp =
  945             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
  946             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA);
  947         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  948             "BB_paprd_trainer_cntl4.cf_paprd_safety_delta=0x%x\n", temp);
  949         /*field_read("BB_paprd_trainer_cntl4.cf_paprd_min_corr", &temp);*/
  950         temp =
  951             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
  952             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR);
  953         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  954             "BB_paprd_trainer_cntl4.cf_paprd_min_corr=0x%x\n", temp);
  955         /*field_read("BB_paprd_trainer_stat1.paprd_agc2_pwr", &temp);*/
  956         temp =
  957             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
  958             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
  959         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  960             "    paprd_agc2_pwr              = 0x%02x\n", temp);
  961         /*field_read("BB_paprd_trainer_stat1.paprd_rx_gain_idx", &temp);*/
  962         temp =
  963             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
  964             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX);
  965         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  966             "    paprd_rx_gain_idx           = 0x%02x\n", temp);
  967         /*field_read("BB_paprd_trainer_stat1.paprd_train_active", &temp);*/
  968         temp =
  969             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
  970             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE);
  971         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  972             "    paprd_train_active          = 0x%08x\n", temp);
  973         /*field_read("BB_paprd_trainer_stat1.paprd_corr_err", &temp);*/
  974         temp =
  975             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
  976             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR);
  977         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  978             "    paprd_corr_err              = 0x%08x\n", temp);
  979         /*field_read("BB_paprd_trainer_stat1.paprd_train_incomplete", &temp);*/
  980         temp =
  981             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
  982             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE);
  983         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  984             "    paprd_train_incomplete      = 0x%08x\n", temp);
  985         /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
  986         temp =
  987             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
  988             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
  989         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  990             "    paprd_train_done            = 0x%08x\n", temp);
  991         /*field_read("BB_paprd_trainer_stat2.paprd_fine_idx", &temp);*/
  992         temp =
  993             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON,
  994             AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX);
  995         HALDEBUG(ah, HAL_DEBUG_PAPRD,
  996             "    paprd_fine_idx              = 0x%08x\n", temp);
  997         /*field_read("BB_paprd_trainer_stat2.paprd_coarse_idx", &temp);*/
  998         temp =
  999             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON,
 1000             AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX);
 1001         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1002             "    paprd_coarse_idx            = 0x%08x\n", temp);
 1003         /*field_read("BB_paprd_trainer_stat2.paprd_fine_val", &temp);*/
 1004         temp =
 1005             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON,
 1006             AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL);
 1007         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1008             "    paprd_fine_val              = 0x%08x\n", temp);
 1009         /*field_read("BB_paprd_trainer_stat3.paprd_train_samples_cnt", &temp);*/
 1010         temp =
 1011             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT3_POSEIDON,
 1012             AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT);
 1013         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1014             "    paprd_train_samples_cnt     = 0x%08x\n", temp);
 1015     } else {
 1016         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
 1017         temp =
 1018             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
 1019             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP);
 1020         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1021             "BB_paprd_trainer_cntl1.cf_paprd_lb_skip=0x%x\n", temp);
 1022         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_enable", &temp);*/
 1023         temp =
 1024             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
 1025             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE);
 1026         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1027             "BB_paprd_trainer_cntl1.cf_paprd_lb_enable=0x%x\n", temp);
 1028         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force", &temp);*/
 1029         temp =
 1030             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
 1031             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE);
 1032         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1033             "BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force=0x%x\n", temp);
 1034         /*
 1035          * field_read(
 1036          *     "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
 1037          */
 1038         temp =
 1039             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
 1040             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE);
 1041         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1042             "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force=0x%x\n", temp);
 1043         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable", &temp);*/
 1044         temp =
 1045             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
 1046             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE);
 1047         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1048             "BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable=0x%x\n", temp);
 1049         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_agc2_settling", &temp);*/
 1050         temp =
 1051             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
 1052             AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING);
 1053         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1054             "BB_paprd_trainer_cntl1.cf_paprd_agc2_settling=0x%x\n", temp);
 1055         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_train_enable", &temp);*/
 1056         temp =
 1057             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
 1058             AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE);
 1059         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1060             "BB_paprd_trainer_cntl1.cf_paprd_train_enable=0x%x\n", temp);
 1061         /*
 1062          * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
 1063          */
 1064         temp =
 1065             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
 1066             AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN);
 1067         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1068             "BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain=0x%x\n", temp);
 1069         /*field_read("BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len", &temp);*/
 1070         temp =
 1071             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 1072             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN);
 1073         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1074             "BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len=0x%x\n", temp);
 1075         /*
 1076          * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
 1077          */
 1078         temp =
 1079             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 1080             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN);
 1081         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1082             "BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len=0x%x\n", temp);
 1083         /*
 1084          * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
 1085          */
 1086         temp =
 1087             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 1088             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES);
 1089         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1090             "BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages=0x%x\n", temp);
 1091         /*
 1092          * field_read(
 1093          *     "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
 1094          */
 1095         temp =
 1096             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 1097             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL);
 1098         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1099             "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del=0x%x\n", temp);
 1100         /*field_read("BB_paprd_trainer_cntl3.cf_paprd_quick_drop", &temp);*/
 1101         temp =
 1102             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 1103             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
 1104         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1105             "BB_paprd_trainer_cntl3.cf_paprd_quick_drop=0x%x\n", temp);
 1106         /*
 1107          * field_read(
 1108          *     "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
 1109          */
 1110         temp =
 1111             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 1112             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE);
 1113         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1114             "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size=0x%x\n", temp);
 1115         /*
 1116          * field_read(
 1117          *     "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
 1118          */
 1119         temp =
 1120             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 1121             AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE);
 1122         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1123             "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable=0x%x\n", temp);
 1124         /*field_read("BB_paprd_trainer_cntl4.cf_paprd_safety_delta", &temp);*/
 1125         temp =
 1126             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
 1127             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA);
 1128         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1129             "BB_paprd_trainer_cntl4.cf_paprd_safety_delta=0x%x\n", temp);
 1130         /*field_read("BB_paprd_trainer_cntl4.cf_paprd_min_corr", &temp);*/
 1131         temp =
 1132             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
 1133             AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR);
 1134         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1135             "BB_paprd_trainer_cntl4.cf_paprd_min_corr=0x%x\n", temp);
 1136         /*field_read("BB_paprd_trainer_stat1.paprd_agc2_pwr", &temp);*/
 1137         temp =
 1138             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 1139             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
 1140         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1141             "    paprd_agc2_pwr              = 0x%02x\n", temp);
 1142         /*field_read("BB_paprd_trainer_stat1.paprd_rx_gain_idx", &temp);*/
 1143         temp =
 1144             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 1145             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX);
 1146         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1147             "    paprd_rx_gain_idx           = 0x%02x\n", temp);
 1148         /*field_read("BB_paprd_trainer_stat1.paprd_train_active", &temp);*/
 1149         temp =
 1150             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 1151             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE);
 1152         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1153             "    paprd_train_active          = 0x%08x\n", temp);
 1154         /*field_read("BB_paprd_trainer_stat1.paprd_corr_err", &temp);*/
 1155         temp =
 1156             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 1157             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR);
 1158         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1159             "    paprd_corr_err              = 0x%08x\n", temp);
 1160         /*field_read("BB_paprd_trainer_stat1.paprd_train_incomplete", &temp);*/
 1161         temp =
 1162             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 1163             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE);
 1164         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1165             "    paprd_train_incomplete      = 0x%08x\n", temp);
 1166         /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
 1167         temp =
 1168             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 1169             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
 1170         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1171             "    paprd_train_done            = 0x%08x\n", temp);
 1172         /*field_read("BB_paprd_trainer_stat2.paprd_fine_idx", &temp);*/
 1173         temp =
 1174             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2,
 1175             AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX);
 1176         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1177             "    paprd_fine_idx              = 0x%08x\n", temp);
 1178         /*field_read("BB_paprd_trainer_stat2.paprd_coarse_idx", &temp);*/
 1179         temp =
 1180             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2,
 1181             AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX);
 1182         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1183             "    paprd_coarse_idx            = 0x%08x\n", temp);
 1184         /*field_read("BB_paprd_trainer_stat2.paprd_fine_val", &temp);*/
 1185         temp =
 1186             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2,
 1187             AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL);
 1188         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1189             "    paprd_fine_val              = 0x%08x\n", temp);
 1190         /*field_read("BB_paprd_trainer_stat3.paprd_train_samples_cnt", &temp);*/
 1191         temp =
 1192             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT3,
 1193             AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT);
 1194         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1195             "    paprd_train_samples_cnt     = 0x%08x\n", temp);
 1196     }
 1197 
 1198     /*field_read("BB_tpc_1.force_dac_gain", &temp);*/
 1199     temp =
 1200         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN);
 1201     HALDEBUG(ah, HAL_DEBUG_PAPRD, "    dac_gain_forced     = 0x%08x\n",
 1202         temp);
 1203     /*field_read("BB_tpc_1.forced_dac_gain", &temp);*/
 1204     temp =
 1205         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN);
 1206     HALDEBUG(ah, HAL_DEBUG_PAPRD, "    forced_dac_gain     = 0x%08x\n",
 1207         temp);
 1208 
 1209     /*field_read("BB_paprd_ctrl0_b0.paprd_enable_0", &temp);*/
 1210     temp =
 1211         OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
 1212         AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0);
 1213     HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1214         "    BB_paprd_ctrl0_b0.paprd_enable_0     = 0x%08x\n", temp);
 1215     if (!AR_SREV_POSEIDON(ah)) {
 1216         /*field_read("BB_paprd_ctrl0_b1.paprd_enable_1", &temp);*/
 1217         temp =
 1218             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
 1219             AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1);
 1220         HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1221             "    BB_paprd_ctrl0_b1.paprd_enable_1     = 0x%08x\n", temp);
 1222         if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
 1223             /*field_read("BB_paprd_ctrl0_b2.paprd_enable_2", &temp);*/
 1224             temp =
 1225                 OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
 1226                 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2);
 1227             HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1228                 "    BB_paprd_ctrl0_b2.paprd_enable_2     = 0x%08x\n", temp);
 1229         }
 1230     }
 1231 
 1232     /*field_read("BB_tx_forced_gain.forced_txbb1dbgain", &txbb1dbgain);*/
 1233     txbb1dbgain =
 1234         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
 1235         AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN);
 1236     /*field_read("BB_tx_forced_gain.forced_txbb6dbgain", &txbb6dbgain);*/
 1237     txbb6dbgain =
 1238         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
 1239         AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN);
 1240     /*field_read("BB_tx_forced_gain.forced_txmxrgain", &txmxrgain);*/
 1241     txmxrgain =
 1242         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
 1243         AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN);
 1244     /*field_read("BB_tx_forced_gain.forced_padrvgn_a", &padrvgn_a);*/
 1245     padrvgn_a =
 1246         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
 1247         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA);
 1248     /*field_read("BB_tx_forced_gain.forced_padrvgn_b", &padrvgn_b);*/
 1249     padrvgn_b =
 1250         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
 1251         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB);
 1252     /*field_read("BB_tx_forced_gain.forced_padrvgn_c", &padrvgn_c);*/
 1253     padrvgn_c =
 1254         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
 1255         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC);
 1256     /*field_read("BB_tx_forced_gain.forced_padrvgn_d", &padrvgn_d);*/
 1257     padrvgn_d =
 1258         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
 1259         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND);
 1260 
 1261     HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1262         "txbb1dbgain=0x%x, txbb6dbgain=0x%x, txmxrgain=0x%x\n",
 1263         txbb1dbgain, txbb6dbgain, txmxrgain);
 1264     HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1265         "padrvgn_a=0x%x, padrvgn_b=0x%x\n", padrvgn_a, padrvgn_b);
 1266     HALDEBUG(ah, HAL_DEBUG_PAPRD,
 1267         "padrvgn_c=0x%x, padrvgn_d=0x%x\n", padrvgn_c, padrvgn_d);
 1268 }
 1269 #else
 1270 #define ar9300_paprd_debug_print(ah) /* dummy macro */
 1271 #endif /* defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG) */
 1272 
 1273 static int ar9300_create_pa_curve(struct ath_hal *ah, u_int32_t * pa_table,
 1274     u_int32_t * small_signal_gain, int * pa_in)
 1275 {
 1276     int i;
 1277     int status;
 1278     /*char field_name[100];*/
 1279     u_int32_t paprd_train_data_l[48], paprd_train_data_u[48];
 1280     u_int32_t reg;
 1281 
 1282     ar9300_paprd_debug_print(ah);
 1283     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_CHAN_INFO_MEMORY,
 1284         AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ, 0);
 1285     reg = AR_PHY_CHAN_INFO_TAB_0;
 1286 
 1287     for (i = 0; i < 48; i++) {
 1288         /*
 1289          * sprintf(
 1290          *     field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[", 
 1291          *     i, "].chaninfo_word");
 1292          */
 1293         /*field_read(field_name, &paprd_train_data_l[i]);*/
 1294         paprd_train_data_l[i] = OS_REG_READ(ah, reg);
 1295         reg = reg + 4;
 1296     }
 1297 
 1298     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_CHAN_INFO_MEMORY,
 1299         AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ, 1);
 1300     reg = AR_PHY_CHAN_INFO_TAB_0;
 1301 
 1302     for (i = 0; i < 48; i++) {
 1303         /*
 1304          * sprintf(
 1305          *     field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[", 
 1306          *     i, "].chaninfo_word");
 1307          */
 1308         /*field_read(field_name, &paprd_train_data_u[i]);*/
 1309         paprd_train_data_u[i] = OS_REG_READ(ah, reg);
 1310         reg = reg + 4;
 1311     }
 1312 
 1313     /*
 1314      * for(i=0; i<48; i++)
 1315      *     ath_hal_printf(
 1316      *         ah, "%08x%08x\n", paprd_train_data_u[i], paprd_train_data_l[i]);
 1317      */
 1318     status = 0;
 1319     if (create_pa_curve(
 1320             paprd_train_data_l, paprd_train_data_u, 
 1321             pa_table, small_signal_gain, pa_in) ==
 1322             AH_FALSE)
 1323     {
 1324         status = -2;
 1325     }
 1326     /* Clear the training done bit */
 1327     if (AR_SREV_POSEIDON(ah)) {
 1328         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
 1329             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
 1330     } else {
 1331         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 1332             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
 1333     }
 1334     return status;
 1335 }
 1336 
 1337 static int find_expn(int num)
 1338 {
 1339     int tmp, exp;
 1340 
 1341     exp = 0;
 1342     tmp = num >> 1;
 1343 
 1344     while (tmp != 0) {
 1345         tmp = tmp >> 1;
 1346         exp++;
 1347     }
 1348 
 1349     return exp;
 1350 }
 1351 
 1352 static int find_proper_scale(int expn, int n)
 1353 {
 1354     int q_pw;
 1355 
 1356     q_pw = (expn > n) ? expn - 10 : 0;
 1357     return q_pw;
 1358 }
 1359 
 1360 static int find_max(int *array, int length)
 1361 {
 1362     int i, loc_max;
 1363 
 1364     loc_max = 0;
 1365 
 1366     for (i = 0; i < length; i++) {
 1367         if (array[i] > loc_max) {
 1368             loc_max = array[i];
 1369         }
 1370     }
 1371 
 1372     return loc_max;
 1373 }
 1374 
 1375 static int paprd_abs(int num)
 1376 {
 1377     if (num < 0) {
 1378         return -num;
 1379     }
 1380     return num;
 1381 }
 1382 
 1383 #define NUM_BIN 23
 1384 
 1385 HAL_BOOL create_pa_curve(u_int32_t * paprd_train_data_l,
 1386     u_int32_t * paprd_train_data_u, u_int32_t * pa_table, 
 1387     u_int32_t * g_fxp_ext, int *pa_in)
 1388 {
 1389     unsigned int accum_cnt[NUM_BIN + 1];
 1390     unsigned int accum_tx[NUM_BIN + 1];
 1391     unsigned int accum_rx[NUM_BIN + 1];
 1392     unsigned int accum_ang[NUM_BIN + 1];
 1393     unsigned int thresh_accum_cnt;
 1394 
 1395     int max_index;
 1396     int scale_factor;
 1397 
 1398     int x_est[NUM_BIN + 1];
 1399     int y[NUM_BIN + 1];
 1400     int theta[NUM_BIN + 1];
 1401     int y_sqr[NUM_BIN + 1];
 1402     int y_quad[NUM_BIN + 1];
 1403     int theta_tilde[NUM_BIN + 1];
 1404     int pa_angle[NUM_BIN + 1];
 1405 
 1406     int b1_tmp[NUM_BIN + 1];
 1407     int b2_tmp[NUM_BIN + 1];
 1408     int b1_abs[NUM_BIN + 1];
 1409     int b2_abs[NUM_BIN + 1];
 1410 
 1411     int y_lin[NUM_BIN + 1];
 1412     int y_est[NUM_BIN + 1];
 1413     int x_est_fxp1_nonlin[NUM_BIN + 1];
 1414     int x_tilde[NUM_BIN + 1];
 1415     int x_tilde_abs[NUM_BIN + 1];
 1416 
 1417     int g_fxp;
 1418     int y_intercept;
 1419     int order_x_by_y;
 1420     int m, half_lo, half_hi;
 1421     int sum_y_sqr;
 1422     int sum_y_quad;
 1423     int q_x, q_b1, q_b2;
 1424     int beta_raw, alpha_raw, scale_b;
 1425     int q_scale_b, q_beta, q_alpha;
 1426     int alpha, beta;
 1427     int order_1, order_2;
 1428     int order1_5x, order2_3x;
 1429     int order1_5x_rem, order2_3x_rem;
 1430     int y5, y3, tmp;
 1431     int bin, idx;
 1432     int theta_low_bin = 0;
 1433 
 1434     /*
 1435      * [15:00] u16, accum_cnt[15:00]: number of samples in the bin
 1436      * [42:16] u27, accum_tx[26:00]: sum(tx amplitude) of the bin
 1437      * [63:43] u21, accum_rx[20:00]: 
 1438      *     sum(rx amplitude distance to lower bin edge) of the bin
 1439      * [90:64] s27, accum_ang[26:00]: sum(angles) of the bin
 1440      */
 1441     max_index = 0;
 1442     /*
 1443      * Disregard any bin that contains less than 
 1444      * or equal to 16 counts of samples
 1445      */
 1446     thresh_accum_cnt = 16;      
 1447     scale_factor = 5;
 1448 
 1449     for (bin = 0; bin < NUM_BIN; bin++) {
 1450         accum_cnt[bin] = paprd_train_data_l[bin] & 0xffff;
 1451         /* lower 16 bit OR-ed  upper 11 bits */
 1452         accum_tx[bin] = 
 1453             ((paprd_train_data_l[bin] >> 16) & 0xffff) | 
 1454             ((paprd_train_data_u[bin] & 0x7ff) << 16);
 1455         accum_rx[bin] =
 1456             ((paprd_train_data_u[bin] >> 11) & 0x1f) |
 1457              ((paprd_train_data_l[bin + 23] & 0xffff) << 5);
 1458         accum_ang[bin] =
 1459             ((paprd_train_data_l[bin + 23] >> 16) & 0xffff) |
 1460              ((paprd_train_data_u[bin + 23] & 0x7ff) << 16);
 1461         /*
 1462          * printf(
 1463          *     "%d\t%d\t%d\t%d\n", accum_cnt[bin], accum_tx[bin],
 1464          *     accum_rx[bin], accum_ang[bin]);
 1465          */
 1466         if (accum_cnt[bin] > thresh_accum_cnt) {
 1467             /* accum_cnt[i] will be non-zero at this point */
 1468             x_est[bin + 1] =
 1469                 ((((accum_tx[bin] << scale_factor) +
 1470                     accum_cnt[bin]) / accum_cnt[bin]) + 32) >> scale_factor;
 1471             y[bin + 1] =
 1472                 (((((accum_rx[bin] << scale_factor) +
 1473                      accum_cnt[bin]) / accum_cnt[bin]) + 32) >> scale_factor) +
 1474                 (1 << scale_factor) * max_index + 16;
 1475             if (accum_ang[bin] >= (1 << 26)) {
 1476                 theta[bin + 1] =
 1477                     ((accum_ang[bin] - (1 << 27)) * (1 << scale_factor) +
 1478                     accum_cnt[bin]);
 1479                 theta[bin + 1] = theta[bin + 1] / (int) accum_cnt[bin];
 1480                 /*
 1481                  *  theta[i+1] = 
 1482                  *      ((accum_ang[i] - (1 << 27)) * 
 1483                  *      (1 << scale_factor) + zz) / zz;
 1484                  */
 1485             } else {
 1486                 theta[bin + 1] =
 1487                     ((accum_ang[bin] * (1 << scale_factor)) +
 1488                     accum_cnt[bin]) / accum_cnt[bin];
 1489             }
 1490             max_index++;
 1491         }
 1492         /*
 1493          * printf(
 1494          *     "i=%d, theta[i+1]=%d\t%d\t%d\t%d\t%d\n", 
 1495          *     i, theta[i+1], accum_cnt[i], 
 1496          *     accum_tx[i], accum_rx[i], accum_ang[i]);
 1497          */
 1498     }
 1499 
 1500     /*
 1501      * Find average theta of first 5 bin and all of those to same value. 
 1502      * Curve is linear at that range.
 1503      */
 1504     for (bin = 1; bin < 6; bin++) {
 1505         theta_low_bin += theta[bin];
 1506     }
 1507     theta_low_bin = theta_low_bin / 5;
 1508     for (bin = 1; bin < 6; bin++) {
 1509         theta[bin] = theta_low_bin;
 1510     }
 1511 
 1512     /* Set values at origin */
 1513     theta[0] = theta_low_bin;
 1514 
 1515     for (bin = 0; bin <= max_index; bin++) {
 1516         theta[bin] = theta[bin] - theta_low_bin;
 1517         /*printf("bin=%d, theta[bin] = %d\n", bin, theta[bin]);*/
 1518     }
 1519 
 1520     x_est[0] = 0;
 1521     y[0] = 0;
 1522     scale_factor = 8;
 1523     /* low signal gain */
 1524     if (x_est[6] == x_est[3]) {
 1525         return AH_FALSE;
 1526     }
 1527     g_fxp =
 1528         (((y[6] - y[3]) * 1 << scale_factor) + (x_est[6] - x_est[3])) /
 1529         (x_est[6] - x_est[3]);
 1530     if (g_fxp == 0) {
 1531         /*
 1532          * ath_hal_printf(
 1533          *     NULL, "%s[%d] Potential divide by zero error\n",
 1534          *     __func__, __LINE__);
 1535          */
 1536         return AH_FALSE;
 1537     }
 1538 
 1539     for (bin = 0; bin <= max_index; bin++) {
 1540         y_lin[bin] =
 1541             (g_fxp * (x_est[bin] - x_est[3]) + (1 << scale_factor)) /
 1542             (1 << scale_factor) + y[3];
 1543     }
 1544     y_intercept = y_lin[0];
 1545 
 1546     for (bin = 0; bin <= max_index; bin++) {
 1547         y_est[bin] = y[bin] - y_intercept;
 1548         y_lin[bin] = y_lin[bin] - y_intercept;
 1549     }
 1550 
 1551     for (bin = 0; bin <= 3; bin++) {
 1552         y_est[bin] = bin * 32;
 1553         /* g_fxp was checked for zero already */
 1554         x_est[bin] = ((y_est[bin] * 1 << scale_factor) + g_fxp) / g_fxp;
 1555     }
 1556 
 1557     /*
 1558      *  for (bin = 0; bin <= max_index; bin++) {
 1559      *      printf("y_est[%d] = %d, x_est[%d]=%d\n",
 1560      *          bin, y_est[bin], bin, x_est[bin]);
 1561      *  }
 1562      */
 1563     for (bin = 0; bin <= max_index; bin++) {
 1564         x_est_fxp1_nonlin[bin] =
 1565             x_est[bin] - ((1 << scale_factor) * y_est[bin] + g_fxp) / g_fxp;
 1566         /*printf("x_est_fxp1_nonlin[%d] = %d\n", bin, x_est_fxp1_nonlin[bin]);*/
 1567     }
 1568 
 1569     /* Check for divide by 0 */
 1570     if (y_est[max_index] == 0) {
 1571         return AH_FALSE;
 1572     }
 1573     order_x_by_y =
 1574         (x_est_fxp1_nonlin[max_index] + y_est[max_index]) / y_est[max_index];
 1575     if (order_x_by_y == 0) {
 1576         m = 10;
 1577     } else if (order_x_by_y == 1) {
 1578         m = 9;
 1579     } else {
 1580         m = 8;
 1581     }
 1582 
 1583     half_lo = (max_index > 15) ? 7 : max_index >> 1;
 1584     half_hi = max_index - half_lo;
 1585     scale_factor = 8;
 1586     sum_y_sqr = 0;
 1587     sum_y_quad = 0;
 1588 
 1589     for (bin = 0; bin <= half_hi; bin++) {
 1590         if (y_est[bin + half_lo] == 0) {
 1591             /*
 1592              * ath_hal_printf(
 1593              *     NULL, "%s Potential divide by zero error\n", __func__);
 1594              */
 1595             return AH_FALSE;
 1596         }
 1597 
 1598         x_tilde[bin] =
 1599             (x_est_fxp1_nonlin[bin + half_lo] * (1 << m) +
 1600              y_est[bin + half_lo]) / y_est[bin + half_lo];
 1601         x_tilde[bin] = (x_tilde[bin] * (1 << m) + y_est[bin + half_lo]) /
 1602             y_est[bin + half_lo];
 1603         x_tilde[bin] = (x_tilde[bin] * (1 << m) + y_est[bin + half_lo]) /
 1604             y_est[bin + half_lo];
 1605 
 1606         y_sqr[bin] =
 1607             (y_est[bin + half_lo] * y_est[bin + half_lo] +
 1608              (scale_factor * scale_factor)) / (scale_factor * scale_factor);
 1609         x_tilde_abs[bin] = paprd_abs(x_tilde[bin]);
 1610         y_quad[bin] = y_sqr[bin] * y_sqr[bin];
 1611         sum_y_sqr = sum_y_sqr + y_sqr[bin];
 1612         sum_y_quad = sum_y_quad + y_quad[bin];
 1613     }
 1614 
 1615     /*printf("sum_y_sqr = %d, sum_y_quad=%d\n", sum_y_sqr, sum_y_quad);*/
 1616 
 1617     for (bin = 0; bin <= half_hi; bin++) {
 1618         b1_tmp[bin] = y_sqr[bin] * (half_hi + 1) - sum_y_sqr;
 1619         b2_tmp[bin] = sum_y_quad - sum_y_sqr * y_sqr[bin];
 1620         b1_abs[bin] = paprd_abs(b1_tmp[bin]);
 1621         b2_abs[bin] = paprd_abs(b2_tmp[bin]);
 1622 
 1623         /*
 1624          * printf(
 1625          *     "bin=%d, b1_tmp[bin] = %d, b2_tmp[bin] = %d\n", 
 1626          *     bin, b1_tmp[bin], b2_tmp[bin]);
 1627          */
 1628     }
 1629 
 1630     q_x = find_proper_scale(find_expn(find_max(x_tilde_abs, half_hi + 1)), 10);
 1631     q_b1 = find_proper_scale(find_expn(find_max(b1_abs, half_hi + 1)), 10);
 1632     q_b2 = find_proper_scale(find_expn(find_max(b2_abs, half_hi + 1)), 10);
 1633 
 1634     beta_raw = 0;
 1635     alpha_raw = 0;
 1636 
 1637     for (bin = 0; bin <= half_hi; bin++) {
 1638         x_tilde[bin] = x_tilde[bin] / (1 << q_x);
 1639         b1_tmp[bin] = b1_tmp[bin] / (1 << q_b1);
 1640         b2_tmp[bin] = b2_tmp[bin] / (1 << q_b2);
 1641 
 1642         /*
 1643          * printf(
 1644          *     "bin=%d, b1_tmp[bin]=%d b2_tmp[bin]=%d x_tilde[bin] = %d\n", 
 1645          *     bin, b1_tmp[bin], b2_tmp[bin], x_tilde[bin]);
 1646          */
 1647         beta_raw = beta_raw + b1_tmp[bin] * x_tilde[bin];
 1648         alpha_raw = alpha_raw + b2_tmp[bin] * x_tilde[bin];
 1649     }
 1650 
 1651     scale_b =
 1652         ((sum_y_quad / scale_factor) * (half_hi + 1) -
 1653         (sum_y_sqr / scale_factor) * sum_y_sqr) * scale_factor;
 1654     q_scale_b = find_proper_scale(find_expn(paprd_abs(scale_b)), 10);
 1655     scale_b = scale_b / (1 << q_scale_b);
 1656     /* Check for divide by 0 */
 1657     if (scale_b == 0) {
 1658         return AH_FALSE;
 1659     }
 1660     q_beta = find_proper_scale(find_expn(paprd_abs(beta_raw)), 10);
 1661     q_alpha = find_proper_scale(find_expn(paprd_abs(alpha_raw)), 10);
 1662 
 1663     beta_raw = beta_raw / (1 << q_beta);
 1664     alpha_raw = alpha_raw / (1 << q_alpha);
 1665     alpha = (alpha_raw << 10) / scale_b;
 1666     beta = (beta_raw << 10) / scale_b;
 1667     order_1 = 3 * m - q_x - q_b1 - q_beta + 10 + q_scale_b;
 1668     order_2 = 3 * m - q_x - q_b2 - q_alpha + 10 + q_scale_b;
 1669 
 1670     order1_5x = order_1 / 5;
 1671     order2_3x = order_2 / 3;
 1672 
 1673     order1_5x_rem = order_1 - 5 * order1_5x;
 1674     order2_3x_rem = order_2 - 3 * order2_3x;
 1675 
 1676     for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
 1677         tmp = idx * 32;
 1678         y5 = ((beta * tmp) >> 6) >> order1_5x;
 1679         y5 = (y5 * tmp) >> order1_5x;
 1680         y5 = (y5 * tmp) >> order1_5x;
 1681         y5 = (y5 * tmp) >> order1_5x;
 1682         y5 = (y5 * tmp) >> order1_5x;
 1683 
 1684         y5 = y5 >> order1_5x_rem;
 1685         y3 = (alpha * tmp) >> order2_3x;
 1686         y3 = (y3 * tmp) >> order2_3x;
 1687         y3 = (y3 * tmp) >> order2_3x;
 1688 
 1689         y3 = y3 >> order2_3x_rem;
 1690         /* g_fxp was checked for zero already */
 1691         pa_in[idx] = y5 + y3 + (256 * tmp) / g_fxp;
 1692     }
 1693 
 1694     for (idx = 1; idx < 23; idx++) {
 1695         tmp = pa_in[idx + 1] - pa_in[idx];
 1696         if (tmp < 0) {
 1697             pa_in[idx + 1] = pa_in[idx] + (pa_in[idx] - pa_in[idx - 1]);
 1698         }
 1699     }
 1700 
 1701     for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
 1702         pa_in[idx] = (pa_in[idx] < 1400) ? pa_in[idx] : 1400;
 1703         /*printf("idx=%d, pa_in[idx]=%d\n", i, pa_in[idx]);*/
 1704     }
 1705 
 1706     beta_raw = 0;
 1707     alpha_raw = 0;
 1708 
 1709     for (bin = 0; bin <= half_hi; bin++) {
 1710         /*
 1711          *  printf(
 1712          *      "bin=%d half_lo=%d m=%d theta[bin+half_lo]=%d "
 1713          *      "y_est[bin+half_lo]=%d\n", 
 1714          *      bin, half_lo, m, theta[bin+half_lo], y_est[bin+half_lo]);
 1715          */
 1716         /* y_est[] was already checked for zero */
 1717         theta_tilde[bin] =
 1718             ((theta[bin + half_lo] << m) + y_est[bin + half_lo]) /
 1719             y_est[bin + half_lo];
 1720         theta_tilde[bin] = ((theta_tilde[bin] << m) + y_est[bin + half_lo]) /
 1721             y_est[bin + half_lo];
 1722         theta_tilde[bin] = ((theta_tilde[bin] << m) + y_est[bin + half_lo]) /
 1723             y_est[bin + half_lo];
 1724 
 1725         /*printf("bin=%d theta_tilde[bin]=%d\n", bin, theta_tilde[bin]);*/
 1726         beta_raw = beta_raw + b1_tmp[bin] * theta_tilde[bin];
 1727         alpha_raw = alpha_raw + b2_tmp[bin] * theta_tilde[bin];
 1728 
 1729         /*
 1730         printf("bin=%d, alpha_raw=%d, beta_raw=%d\n", bin, alpha_raw, beta_raw);
 1731          */
 1732     }
 1733 
 1734     q_beta = find_proper_scale(find_expn(paprd_abs(beta_raw)), 10);
 1735     q_alpha = find_proper_scale(find_expn(paprd_abs(alpha_raw)), 10);
 1736 
 1737     beta_raw = beta_raw / (1 << q_beta);
 1738     alpha_raw = alpha_raw / (1 << q_alpha);
 1739     /* scale_b checked for zero previously */
 1740     alpha = (alpha_raw << 10) / scale_b;
 1741     beta = (beta_raw << 10) / scale_b;
 1742     order_1 = 3 * m - q_x - q_b1 - q_beta + 10 + q_scale_b + 5;
 1743     order_2 = 3 * m - q_x - q_b2 - q_alpha + 10 + q_scale_b + 5;
 1744 
 1745     order1_5x = order_1 / 5;
 1746     order2_3x = order_2 / 3;
 1747 
 1748     order1_5x_rem = order_1 - 5 * order1_5x;
 1749     order2_3x_rem = order_2 - 3 * order2_3x;
 1750 
 1751     for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
 1752         tmp = idx * 32;
 1753 
 1754         if (beta > 0) {
 1755             y5 = (((beta * tmp - 64) >> 6) -
 1756                 (1 << order1_5x)) / (1 << order1_5x);
 1757         } else {
 1758             y5 = ((((beta * tmp - 64) >> 6) +
 1759                     (1 << order1_5x)) / (1 << order1_5x));
 1760         }
 1761 
 1762         y5 = (y5 * tmp) / (1 << order1_5x);
 1763         y5 = (y5 * tmp) / (1 << order1_5x);
 1764         y5 = (y5 * tmp) / (1 << order1_5x);
 1765         y5 = (y5 * tmp) / (1 << order1_5x);
 1766 
 1767         y5 = y5 / (1 << order1_5x_rem);
 1768 
 1769         if (beta > 0) {
 1770             y3 = (alpha * tmp - (1 << order2_3x)) / (1 << order2_3x);
 1771         } else {
 1772             y3 = (alpha * tmp + (1 << order2_3x)) / (1 << order2_3x);
 1773         }
 1774 
 1775         y3 = (y3 * tmp) / (1 << order2_3x);
 1776         y3 = (y3 * tmp) / (1 << order2_3x);
 1777 
 1778         y3 = y3 / (1 << order2_3x_rem);
 1779         pa_angle[idx] = y5 + y3;
 1780         /*printf("idx=%d, y5 = %d, y3=%d\n", idx, y5, y3);*/
 1781         pa_angle[idx] =
 1782             (pa_angle[idx] < -150) ? -150 : ((pa_angle[idx] >
 1783                 150) ? 150 : pa_angle[idx]);
 1784     }
 1785 
 1786     pa_angle[0] = 0;
 1787     pa_angle[1] = 0;
 1788     pa_angle[2] = 0;
 1789     pa_angle[3] = 0;
 1790 
 1791     pa_angle[4] = (pa_angle[5] + 2) >> 1;
 1792 
 1793     for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
 1794         pa_table[idx] = ((pa_in[idx] & 0x7ff) << 11) + (pa_angle[idx] & 0x7ff);
 1795         /*
 1796          * HALDEBUG(
 1797          *     NULL, HAL_DEBUG_UNMASKABLE,"%d\t%d\t0x%x\n", 
 1798          *     pa_in[idx], pa_angle[idx], pa_table[idx]);
 1799          */
 1800     }
 1801 
 1802     /*HALDEBUG(NULL, HAL_DEBUG_UNMASKABLE, "g_fxp = %d\n", g_fxp);*/
 1803     *g_fxp_ext = g_fxp;
 1804     return AH_TRUE;
 1805 }
 1806 
 1807 // Due to a hardware bug, when transmitting with just one chain the papd
 1808 // data for chain 0 is always used. So when using chain 2 or 4, the 
 1809 // corresponding data must be copied into the chain 0 area.
 1810 void ar9300_swizzle_paprd_entries(struct ath_hal *ah, unsigned int txchain)
 1811 {
 1812     int i;
 1813     u_int32_t *paprd_table_val = NULL;
 1814     u_int32_t small_signal_gain = 0;
 1815     u_int32_t reg = 0;
 1816 
 1817     reg = AR_PHY_PAPRD_MEM_TAB_B0;
 1818     switch (txchain) {
 1819     case 0x1: 
 1820     case 0x3:
 1821     case 0x7:
 1822         paprd_table_val = &AH9300(ah)->pa_table[0][0];
 1823         small_signal_gain = AH9300(ah)->small_signal_gain[0];
 1824         break;
 1825     case 0x2:
 1826         paprd_table_val = &AH9300(ah)->pa_table[1][0];
 1827         small_signal_gain = AH9300(ah)->small_signal_gain[1];
 1828         break;
 1829     case 0x4:
 1830         paprd_table_val = &AH9300(ah)->pa_table[2][0];
 1831         small_signal_gain = AH9300(ah)->small_signal_gain[2];
 1832         break;
 1833     default:
 1834         // Error out.
 1835         ath_hal_printf(ah, "YAK! Bad chain mask %x\n", txchain);
 1836         return;
 1837     }
 1838     for (i = 0; i < AR9300_PAPRD_TABLE_SZ; i++) { 
 1839         OS_REG_WRITE(ah, reg, paprd_table_val[i]);
 1840         HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
 1841                  __LINE__, reg, paprd_table_val[i]);
 1842         
 1843         reg = reg + 4;
 1844     }
 1845     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B0,AR_PHY_PA_GAIN123_B0_PA_GAIN1_0, small_signal_gain);
 1846     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x small_signal_gain 0x%08x\n", __func__, __LINE__,
 1847              (unsigned) AR_PHY_PA_GAIN123_B0, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
 1848 
 1849     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0, AR_PHY_PAPRD_CTRL1_B0_PAPRD_POWER_AT_AM2AM_CAL_0,
 1850                          AH9300(ah)->paprd_training_power);
 1851     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__, 
 1852              (unsigned) AR_PHY_PAPRD_CTRL1_B0, OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B0));
 1853 
 1854 }
 1855 
 1856 void ar9300_populate_paprd_single_table(struct ath_hal *ah,
 1857     struct ieee80211_channel *chan, int chain_num)
 1858 {
 1859     int i, j, bad_read = 0;
 1860 #ifdef  AH_DEBUG
 1861     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
 1862 #endif
 1863     u_int32_t *paprd_table_val = &AH9300(ah)->pa_table[chain_num][0];
 1864     u_int32_t small_signal_gain = AH9300(ah)->small_signal_gain[chain_num];
 1865     u_int32_t reg = 0;
 1866 
 1867     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
 1868         "%s[%d]: channel %d paprd_done %d write %d\n", __func__, __LINE__,
 1869         ichan->channel, ichan->paprd_done, ichan->paprd_table_write_done);
 1870 
 1871     if (chain_num == 0) {
 1872         reg = AR_PHY_PAPRD_MEM_TAB_B0;
 1873     } else if (chain_num == 1) {
 1874         reg = AR_PHY_PAPRD_MEM_TAB_B1;
 1875     } else if (chain_num == 2) {
 1876         reg = AR_PHY_PAPRD_MEM_TAB_B2;
 1877     }
 1878 
 1879     for (i = 0; i < AR9300_PAPRD_TABLE_SZ; i++) {
 1880         if (AR_SREV_POSEIDON(ah)) {
 1881             HALASSERT(chain_num == 0x1);
 1882             if ((reg == AR_PHY_PAPRD_MEM_TAB_B1) || 
 1883                 (reg == AR_PHY_PAPRD_MEM_TAB_B2)) {
 1884                 continue;
 1885             }
 1886         }
 1887         /*
 1888          * sprintf(
 1889          *     field_name, "%s%d[%d]%s\0", "BB_paprd_mem_tab_b", 
 1890          *     chain_num, i, ".paprd_mem");
 1891          */
 1892         OS_REG_WRITE(ah, reg, paprd_table_val[i]);
 1893         HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
 1894             __LINE__, reg, paprd_table_val[i]);
 1895         /*
 1896          * printf(
 1897          *     "%s[%d] reg %08x = 0x%08x\n", 
 1898          *     __func__, __LINE__, reg, paprd_table_val[i]);
 1899          */
 1900          if (OS_REG_READ(ah, reg) == 0xdeadbeef) {
 1901             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 
 1902                      "%s: Reg0x%x = 0xdeadbeef\n", __func__, reg);
 1903             bad_read++;
 1904             for (j = AR_PHY_PAPRD_MEM_TAB_B0; j < (AR_PHY_PAPRD_MEM_TAB_B0 + 0x10); j+=4)
 1905             {
 1906                 if (OS_REG_READ(ah, j) == 0xdeadbeef) {
 1907                     HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 
 1908                              "%s: Reg0x%x = 0xdeadbeef\n", __func__, j);
 1909                     bad_read++;
 1910                 }
 1911             }
 1912             for (j = AR_PHY_PAPRD_MEM_TAB_B1; j < (AR_PHY_PAPRD_MEM_TAB_B1 + 0x10); j+=4)
 1913             {
 1914                 if (OS_REG_READ(ah, j) == 0xdeadbeef) {
 1915                     HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 
 1916                              "%s: Reg0x%x = 0xdeadbeef\n", __func__, j);
 1917                     bad_read++;
 1918                 }
 1919             }
 1920          }
 1921          
 1922         reg = reg + 4;
 1923     }
 1924 
 1925     if (bad_read > 4) {
 1926         HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 
 1927                  "%s: Get %d 0xdeadbeef. Mark PAPRD as broken.\n", 
 1928                  __func__, bad_read);
 1929         AH9300(ah)->ah_paprd_broken = AH_TRUE;
 1930     }
 1931 
 1932     if (chain_num == 0) {
 1933         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B0,
 1934             AR_PHY_PA_GAIN123_B0_PA_GAIN1_0, small_signal_gain);
 1935         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
 1936             "%s[%d] reg %08x small_signal_gain 0x%08x\n", __func__, __LINE__,
 1937             (unsigned) AR_PHY_PA_GAIN123_B0,
 1938             OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
 1939     } else if (chain_num == 1) {
 1940         if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah) && !AR_SREV_APHRODITE(ah)) {
 1941             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B1,
 1942                 AR_PHY_PA_GAIN123_B1_PA_GAIN1_1, small_signal_gain);
 1943             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
 1944                 "%s[%d] reg %08x small_signal_gain 0x%08x\n",
 1945                 __func__, __LINE__,
 1946                 (unsigned) AR_PHY_PA_GAIN123_B1,
 1947                 OS_REG_READ(ah, AR_PHY_PA_GAIN123_B1));
 1948         }
 1949     } else if (chain_num == 2) {
 1950         if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah) && !AR_SREV_APHRODITE(ah)) {
 1951             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B2,
 1952                 AR_PHY_PA_GAIN123_B2_PA_GAIN1_2, small_signal_gain);
 1953             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
 1954                 "%s[%d] reg %08x small_signal_gain 0x%08x\n",
 1955                 __func__, __LINE__,
 1956                 (unsigned) AR_PHY_PA_GAIN123_B2,
 1957                 OS_REG_READ(ah, AR_PHY_PA_GAIN123_B2));
 1958         }
 1959     } else {
 1960         /* invalid channel number */
 1961     }
 1962 
 1963     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
 1964         AR_PHY_PAPRD_CTRL1_B0_PAPRD_POWER_AT_AM2AM_CAL_0,
 1965         AH9300(ah)->paprd_training_power);
 1966     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
 1967         __LINE__, (unsigned) AR_PHY_PAPRD_CTRL1_B0,
 1968         OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B0));
 1969     if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah) && !AR_SREV_APHRODITE(ah)) {
 1970         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
 1971             AR_PHY_PAPRD_CTRL1_B1_PAPRD_POWER_AT_AM2AM_CAL_1,
 1972             AH9300(ah)->paprd_training_power);
 1973         HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
 1974             __LINE__, (unsigned) AR_PHY_PAPRD_CTRL1_B1,
 1975             OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B1));
 1976         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
 1977             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
 1978                 AR_PHY_PAPRD_CTRL1_B2_PAPRD_POWER_AT_AM2AM_CAL_2,
 1979                 AH9300(ah)->paprd_training_power);
 1980             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
 1981                 "%s[%d] reg %08x = 0x%08x\n", __func__,
 1982                 __LINE__, (unsigned) AR_PHY_PAPRD_CTRL1_B2,
 1983                 OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B2));
 1984         }
 1985     }
 1986     /*ar9300_enable_paprd(ah, AH_TRUE);*/
 1987 }
 1988 
 1989 HAL_STATUS ar9300_paprd_setup_gain_table(struct ath_hal *ah, int chain_num)
 1990 {
 1991     unsigned int i, desired_gain, gain_index;
 1992     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
 1993         "Run papredistortion single table algorithm:: Training power = %d\n",
 1994         AH9300(ah)->paprd_training_power / 2);
 1995 
 1996     if (AH9300(ah)->ah_tx_chainmask & (1 << chain_num)) {
 1997         /* this is an active chain */
 1998         desired_gain = ar9300_get_desired_gain_for_chain(
 1999             ah, chain_num, AH9300(ah)->paprd_training_power);
 2000         /* find out gain index */
 2001         gain_index = 0;
 2002 
 2003         for (i = 0; i < 32; i++) {
 2004             if (AH9300(ah)->paprd_gain_table_index[i] < desired_gain) {
 2005                 gain_index = gain_index + 1;
 2006             } else {
 2007                 break;
 2008             }
 2009         }
 2010 
 2011         /*printf("gain_index = %d\n", gain_index);*/
 2012         /*ath_hal_printf(ah, "++++ gain_index = %d\n", gain_index);*/
 2013         ar9300_tx_force_gain(ah, gain_index);
 2014         if (AR_SREV_POSEIDON(ah)) {
 2015             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
 2016                 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
 2017         } else {
 2018             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 2019                 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
 2020         }
 2021     }
 2022 
 2023     return HAL_OK;
 2024 }
 2025 
 2026 static HAL_BOOL ar9300_paprd_retrain_pain(struct ath_hal * ah, int * pa_in)
 2027 {
 2028     int count = 0, i;
 2029     int capdiv_offset = 0, quick_drop_offset;
 2030     int capdiv2g, quick_drop;
 2031 
 2032     capdiv2g = (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF3) >> 1) & 0xF;
 2033     if (!AR_SREV_POSEIDON(ah)) {
 2034         quick_drop = 
 2035             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
 2036                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
 2037     } else {
 2038         quick_drop = 
 2039             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
 2040                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
 2041     }
 2042 
 2043     if ( quick_drop != 0 ) {
 2044         quick_drop -= 0x40; 
 2045     }
 2046     for (i = 0; i < (NUM_BIN + 1); i++) {
 2047         if (pa_in[i] == 1400) {
 2048             count++;
 2049         }            
 2050     }
 2051 
 2052     if (AR_SREV_POSEIDON(ah)) {
 2053         if ((pa_in[23] < 800) || (pa_in[23] == 1400)) {
 2054             if (pa_in[23] < 800) {
 2055                 capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150);
 2056                 capdiv2g = capdiv2g + capdiv_offset;
 2057                 if (capdiv2g > 7) {
 2058                     capdiv2g = 7;
 2059                     if (pa_in[23] < 600) {
 2060                         quick_drop = quick_drop + 1;
 2061                         if (quick_drop > 0) {
 2062                             quick_drop = 0;
 2063                         }
 2064                     }
 2065                 }
 2066                 
 2067                 OS_REG_RMW_FIELD(ah, 
 2068                     AR_PHY_65NM_CH0_TXRF3, 
 2069                             AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, 
 2070                             capdiv2g);
 2071 
 2072                 OS_REG_RMW_FIELD_ALT(ah, 
 2073                     AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON, 
 2074                     AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, 
 2075                     quick_drop);
 2076                 
 2077                 return AH_TRUE;
 2078             } /* end of if (pa_in[23] < 800) */
 2079             else if (pa_in[23] == 1400) {
 2080                 quick_drop_offset = (int)(count / 3);
 2081                 if (quick_drop_offset > 2) {
 2082                     quick_drop_offset = 2;
 2083                 }
 2084                 quick_drop = quick_drop + quick_drop_offset;
 2085                 capdiv2g = capdiv2g + (int)(quick_drop_offset / 2); 
 2086                 if (capdiv2g > 7) {
 2087                     capdiv2g = 7;
 2088                 }
 2089                 if (quick_drop > 0) {
 2090                     quick_drop = 0;
 2091                     capdiv2g = capdiv2g - (int)(quick_drop_offset / 1);
 2092                                 if (capdiv2g < 0) {
 2093                         capdiv2g = 0;
 2094                                 }
 2095                 }
 2096                 OS_REG_RMW_FIELD(ah, 
 2097                         AR_PHY_65NM_CH0_TXRF3, 
 2098                                 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, 
 2099                                 capdiv2g);
 2100 
 2101                 OS_REG_RMW_FIELD_ALT(ah, 
 2102                         AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON, 
 2103                                     AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, 
 2104                         quick_drop);
 2105                 
 2106                 return AH_TRUE;
 2107                 /* sleep(1); */            
 2108             } /* end of if (pa_in[23] == 1400)*/
 2109         } /* end of if ((pa_in[23] < 800) || (pa_in[23] == 1400)) */
 2110     }else if (AR_SREV_HORNET(ah)) {
 2111         if ((pa_in[23] < 1000) || (pa_in[23] == 1400)) {
 2112             if (pa_in[23] < 1000) {
 2113                 capdiv_offset = ((1000 - pa_in[23]) / 100);   
 2114                 capdiv2g = capdiv2g + capdiv_offset;
 2115                 if (capdiv_offset > 3) {
 2116                     quick_drop_offset = 1;
 2117                     quick_drop = quick_drop - quick_drop_offset;
 2118                     capdiv2g = capdiv2g + 1;
 2119                     if (capdiv2g > 6) {
 2120                         capdiv2g = 6;
 2121                     }
 2122                     if (quick_drop < -4) {
 2123                         quick_drop = -4;
 2124                     }
 2125                     OS_REG_RMW_FIELD(ah, 
 2126                         AR_PHY_65NM_CH0_TXRF3, 
 2127                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, 
 2128                         capdiv2g);
 2129                     OS_REG_RMW_FIELD_ALT(ah, 
 2130                         AR_PHY_PAPRD_TRAINER_CNTL3, 
 2131                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, 
 2132                         quick_drop);
 2133                     return AH_TRUE;
 2134                 } else {
 2135                     capdiv2g = capdiv2g + capdiv_offset;
 2136                     if (capdiv2g > 6) {
 2137                         capdiv2g = 6;
 2138                     }
 2139                     if (quick_drop < -4) {
 2140                         quick_drop = -4;
 2141                     }
 2142                     OS_REG_RMW_FIELD(ah, 
 2143                         AR_PHY_65NM_CH0_TXRF3, 
 2144                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, 
 2145                         capdiv2g);
 2146                     OS_REG_RMW_FIELD_ALT(ah, 
 2147                         AR_PHY_PAPRD_TRAINER_CNTL3, 
 2148                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, 
 2149                         quick_drop);
 2150                     return AH_TRUE;
 2151                 }
 2152             } /* end of if (PA_in[23] < 1000) */
 2153             else if (pa_in[23] == 1400) {
 2154                 if (count > 3) {
 2155                     quick_drop_offset = 1;
 2156                     quick_drop = quick_drop + quick_drop_offset;
 2157                     capdiv2g = capdiv2g - (count / 4);  
 2158                     if (capdiv2g < 0) {
 2159                         capdiv2g = 0;
 2160                     }
 2161                     if (quick_drop > -2) {
 2162                         quick_drop = -2;
 2163                     }
 2164                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, 
 2165                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, 
 2166                         capdiv2g);
 2167                     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3, 
 2168                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
 2169                         quick_drop);
 2170                     return AH_TRUE;
 2171                 } else {
 2172                     capdiv2g = capdiv2g - 1;  
 2173                     if (capdiv2g < 0) {
 2174                         capdiv2g = 0;
 2175                     }
 2176                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, 
 2177                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, 
 2178                         capdiv2g);
 2179                     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3, 
 2180                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, 
 2181                         quick_drop);
 2182                     return AH_TRUE; 
 2183                 }
 2184             } /* end of if (PA_in[23] == 1400)*/
 2185         } /* end of if ((PA_in[23] < 1000) || (PA_in[23] == 1400)) */
 2186     }
 2187 
 2188     return AH_FALSE;
 2189 }
 2190 
 2191 HAL_STATUS ar9300_paprd_create_curve(struct ath_hal * ah,
 2192   struct ieee80211_channel * chan, int chain_num)
 2193 {
 2194     int status = 0;
 2195     u_int32_t *pa_table, small_signal_gain;
 2196     int pa_in[NUM_BIN + 1];
 2197 
 2198     if (AH9300(ah)->ah_tx_chainmask & (1 << chain_num)) {
 2199         pa_table = &AH9300(ah)->pa_table[chain_num][0];
 2200         /* Compute PA table and gain index */
 2201         status = ar9300_create_pa_curve(ah, &pa_table[0], &small_signal_gain, 
 2202                     &pa_in[0]);
 2203 
 2204                 if (AR_SREV_WASP(ah)) {
 2205                         OS_DELAY(1000);
 2206                 }
 2207 
 2208         if (status != 0) {
 2209             ath_hal_printf(ah, "ERROR:: paprd failed with error code = %d\n",
 2210                 status);
 2211             return -1;
 2212         }
 2213         AH9300(ah)->small_signal_gain[chain_num] = small_signal_gain;
 2214 
 2215         if (AR_SREV_POSEIDON(ah) || AR_SREV_HORNET(ah)) {
 2216             if (ar9300_paprd_retrain_pain(ah, pa_in)) {
 2217                 /* need re-train PAPRD */
 2218                 return HAL_EINPROGRESS;
 2219                     }
 2220         }
 2221     }
 2222     return HAL_OK;
 2223 }
 2224 
 2225 int ar9300_paprd_init_table(struct ath_hal *ah, struct ieee80211_channel * chan)
 2226 {
 2227     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
 2228 
 2229     if ((AR_SREV_WASP(ah) && IS_CHAN_5GHZ(ichan)) ||
 2230          ar9300_paprd_setup_single_table(ah, chan)) {
 2231         goto FAIL;
 2232     }
 2233     OS_MEMZERO(AH9300(ah)->paprd_gain_table_entries,
 2234         sizeof(AH9300(ah)->paprd_gain_table_entries));
 2235     OS_MEMZERO(AH9300(ah)->paprd_gain_table_index,
 2236         sizeof(AH9300(ah)->paprd_gain_table_index));
 2237 
 2238     ar9300_gain_table_entries(ah);
 2239     return 0;
 2240 FAIL:
 2241     return -1;
 2242 }
 2243 
 2244 int ar9300_paprd_is_done(struct ath_hal *ah)
 2245 {
 2246     int temp, agc2_pwr;
 2247 
 2248     /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
 2249     if (!AR_SREV_POSEIDON(ah)) {
 2250         temp =
 2251             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 2252                 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
 2253 
 2254         if (temp == 0x1) {
 2255             agc2_pwr =
 2256                 OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
 2257                    AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
 2258 
 2259             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
 2260                    "%s AGC2_PWR=0x%2x Training done=0x%2x\n",
 2261                    __func__, agc2_pwr, temp);
 2262 
 2263             /* Retrain if agc2_pwr is not in ideal range */
 2264             if (agc2_pwr <= AH_PAPRD_IDEAL_AGC2_PWR_RANGE) {
 2265                 temp = 0;
 2266             }
 2267                 }
 2268     } else {
 2269         temp =
 2270             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
 2271                 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
 2272     }
 2273     if (!temp) {
 2274         /*ath_hal_printf(ah, "%s[%d] PAPRD TEMp Error\n", __func__, __LINE__);*/
 2275     }
 2276 
 2277     return temp;
 2278 }
 2279 
 2280 /*
 2281  * ar9300_paprd_dec_tx_pwr
 2282  *
 2283  * This function do decrease tx power if Paprd is off or train failed.
 2284  */
 2285 void 
 2286 ar9300_paprd_dec_tx_pwr(struct ath_hal *ah)
 2287 {
 2288     u_int32_t   pwr_temp, pwr_reg;
 2289     int         i, loop_cnt;
 2290     struct ar9300_paprd_pwr_adjust  *p_item;
 2291     struct ath_hal_9300 *ahp = AH9300(ah);
 2292 
 2293     if (AR_SREV_POSEIDON(ah)) {
 2294         loop_cnt = 
 2295         (sizeof(ar9300_paprd_pwr_adj_array) / 
 2296             sizeof(struct ar9300_paprd_pwr_adjust));
 2297         for (i = 0; i < loop_cnt; i++ )
 2298         {
 2299             p_item = &ar9300_paprd_pwr_adj_array[i];
 2300             pwr_reg = OS_REG_READ(ah, p_item->reg_addr);
 2301             pwr_temp = ahp->ah_default_tx_power[p_item->target_rate];
 2302             pwr_temp -= (p_item->sub_db * 2);
 2303             pwr_temp = pwr_temp << p_item->reg_mask_offset;
 2304             pwr_temp |= (pwr_reg&~(p_item->reg_mask <<p_item->reg_mask_offset));
 2305 
 2306             if (pwr_temp != pwr_reg) 
 2307             {
 2308                 OS_REG_WRITE(ah, p_item->reg_addr, pwr_temp);
 2309             }
 2310         }
 2311     }
 2312     return;
 2313 }
 2314 
 2315 int ar9300_paprd_thermal_send(struct ath_hal *ah)
 2316 {
 2317     if (AR_SREV_HORNET(ah)) {
 2318         return OS_REG_READ(ah, AR_TFCNT);
 2319     } else {
 2320         return 1;
 2321     }
 2322 }
 2323 
 2324 #if 0
 2325 void ar9300_paprd_test_prints(struct ath_hal *ah)
 2326 {
 2327     u_int32_t i, reg = 0;
 2328 
 2329     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "=====ar9300_paprd_test_prints=======\n");
 2330     /*printf("=====ar9300_paprd_test_prints=======\n");*/
 2331     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b0 = 0x%08x\n",
 2332         OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B0));
 2333     /*
 2334      * printf(
 2335      *     "BB_paprd_ctrl0_b0 = 0x%08x\n", 
 2336      *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B0));
 2337      */
 2338     if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah)) {
 2339         HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b1 = 0x%08x\n",
 2340             OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B1));
 2341         /*
 2342          * printf(
 2343          *     "BB_paprd_ctrl0_b1 = 0x%08x\n", 
 2344          *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B1));
 2345          */
 2346         HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b2 = 0x%08x\n",
 2347             OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B2));
 2348         /*
 2349          * printf(
 2350          *     "BB_paprd_ctrl0_b2 = 0x%08x\n", 
 2351          *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B2));
 2352          */
 2353     }
 2354 
 2355     reg = AR_PHY_PAPRD_MEM_TAB_B0;
 2356     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE,
 2357         "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n", __func__, __LINE__,
 2358         AR_PHY_PA_GAIN123_B0, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
 2359     /*
 2360      * printf(
 2361      *     "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n",
 2362      *     __func__,  __LINE__, AR_PHY_PA_GAIN123_B0, 
 2363      *     OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
 2364      */
 2365 
 2366     for (i = 0; i < 24; i++) {
 2367         HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n",
 2368             __func__, __LINE__, reg, OS_REG_READ(ah, reg));
 2369         /*
 2370          * printf(
 2371          *     "%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__,
 2372          *     reg, OS_REG_READ(ah, reg));
 2373          */
 2374         reg = reg + 4;
 2375     }
 2376 
 2377     ar9300_paprd_debug_print(ah);
 2378     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE,
 2379         "=====ar9300_paprd_test_prints end=======\n");
 2380     /*printf("=====ar9300_paprd_test_prints end=======\n");*/
 2381 
 2382     if (!AR_SREV_POSEIDON(ah)) {
 2383         reg = AR_PHY_PAPRD_MEM_TAB_B1;
 2384         printf("%s[%d] reg %08lx small_signal_gain ch1 0x%08x\n",
 2385             __func__, __LINE__,
 2386             AR_PHY_PA_GAIN123_B1, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B1));
 2387         for (i = 0; i < 24; i++) {
 2388             OS_REG_WRITE(ah, reg, paprd_table_val[i]);
 2389             HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n",
 2390                 __func__, __LINE__, reg, OS_REG_READ(ah, reg));
 2391             printf("%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__, reg,
 2392                 OS_REG_READ(ah, reg));
 2393             reg = reg + 4;
 2394         }
 2395     
 2396         reg = AR_PHY_PAPRD_MEM_TAB_B2;
 2397         printf("%s[%d] reg %08lx small_signal_gain ch2 0x%08x\n",
 2398             __func__, __LINE__,
 2399             AR_PHY_PA_GAIN123_B2, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B2));
 2400     }
 2401 }
 2402 #endif
 2403 
 2404 #else
 2405 int
 2406 ar9300_paprd_init_table(struct ath_hal *ah, HAL_CHANNEL * chan)
 2407 {
 2408     return 0;
 2409 }
 2410 
 2411 HAL_STATUS
 2412 ar9300_paprd_setup_gain_table(struct ath_hal * ah, int chain_num)
 2413 {
 2414     return HAL_OK;
 2415 }
 2416 
 2417 HAL_STATUS
 2418 ar9300_paprd_create_curve(struct ath_hal * ah, HAL_CHANNEL * chan,
 2419     int chain_num)
 2420 {
 2421     return HAL_OK;
 2422 }
 2423 
 2424 int
 2425 ar9300_paprd_is_done(struct ath_hal *ah)
 2426 {
 2427     return 0;
 2428 }
 2429 
 2430 void
 2431 ar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag, HAL_CHANNEL * chan)
 2432 {
 2433     return;
 2434 }
 2435 
 2436 void
 2437 ar9300_populate_paprd_single_table(struct ath_hal *ah, HAL_CHANNEL * chan,
 2438     int chain_num)
 2439 {
 2440     return;
 2441 }
 2442 
 2443 void 
 2444 ar9300_paprd_dec_tx_pwr(struct ath_hal *ah)
 2445 {
 2446     return;
 2447 }
 2448 
 2449 int ar9300_paprd_thermal_send(struct ath_hal *ah)
 2450 {
 2451     return 1;
 2452 }
 2453 #endif                          /* ATH_SUPPORT_PAPRD */

Cache object: 5a0ec17273d04f20055022b618298f98


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