LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath9k - ar5008_phy.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 311 659 47.2 %
Date: 2022-03-28 13:20:08 Functions: 19 27 70.4 %
Branches: 92 346 26.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2008-2011 Atheros Communications 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
       9                 :            :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      10                 :            :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      11                 :            :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      12                 :            :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      13                 :            :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      14                 :            :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include "hw.h"
      18                 :            : #include "hw-ops.h"
      19                 :            : #include "../regd.h"
      20                 :            : #include "ar9002_phy.h"
      21                 :            : #include "ar5008_initvals.h"
      22                 :            : 
      23                 :            : /* All code below is for AR5008, AR9001, AR9002 */
      24                 :            : 
      25                 :            : #define AR5008_OFDM_RATES               8
      26                 :            : #define AR5008_HT_SS_RATES              8
      27                 :            : #define AR5008_HT_DS_RATES              8
      28                 :            : 
      29                 :            : #define AR5008_HT20_SHIFT               16
      30                 :            : #define AR5008_HT40_SHIFT               24
      31                 :            : 
      32                 :            : #define AR5008_11NA_OFDM_SHIFT          0
      33                 :            : #define AR5008_11NA_HT_SS_SHIFT         8
      34                 :            : #define AR5008_11NA_HT_DS_SHIFT         16
      35                 :            : 
      36                 :            : #define AR5008_11NG_OFDM_SHIFT          4
      37                 :            : #define AR5008_11NG_HT_SS_SHIFT         12
      38                 :            : #define AR5008_11NG_HT_DS_SHIFT         20
      39                 :            : 
      40                 :            : /*
      41                 :            :  * register values to turn OFDM weak signal detection OFF
      42                 :            :  */
      43                 :            : static const int m1ThreshLow_off = 127;
      44                 :            : static const int m2ThreshLow_off = 127;
      45                 :            : static const int m1Thresh_off = 127;
      46                 :            : static const int m2Thresh_off = 127;
      47                 :            : static const int m2CountThr_off =  31;
      48                 :            : static const int m2CountThrLow_off =  63;
      49                 :            : static const int m1ThreshLowExt_off = 127;
      50                 :            : static const int m2ThreshLowExt_off = 127;
      51                 :            : static const int m1ThreshExt_off = 127;
      52                 :            : static const int m2ThreshExt_off = 127;
      53                 :            : 
      54                 :            : static const struct ar5416IniArray bank0 = STATIC_INI_ARRAY(ar5416Bank0);
      55                 :            : static const struct ar5416IniArray bank1 = STATIC_INI_ARRAY(ar5416Bank1);
      56                 :            : static const struct ar5416IniArray bank2 = STATIC_INI_ARRAY(ar5416Bank2);
      57                 :            : static const struct ar5416IniArray bank3 = STATIC_INI_ARRAY(ar5416Bank3);
      58                 :            : static const struct ar5416IniArray bank7 = STATIC_INI_ARRAY(ar5416Bank7);
      59                 :            : 
      60                 :         40 : static void ar5008_write_bank6(struct ath_hw *ah, unsigned int *writecnt)
      61                 :            : {
      62                 :         40 :         struct ar5416IniArray *array = &ah->iniBank6;
      63                 :         40 :         u32 *data = ah->analogBank6Data;
      64                 :         40 :         int r;
      65                 :            : 
      66         [ -  + ]:         40 :         ENABLE_REGWRITE_BUFFER(ah);
      67                 :            : 
      68         [ +  + ]:       1360 :         for (r = 0; r < array->ia_rows; r++) {
      69                 :       1320 :                 REG_WRITE(ah, INI_RA(array, r, 0), data[r]);
      70   [ -  +  -  - ]:       1320 :                 DO_DELAY(*writecnt);
      71                 :            :         }
      72                 :            : 
      73         [ -  + ]:         40 :         REGWRITE_BUFFER_FLUSH(ah);
      74                 :         40 : }
      75                 :            : 
      76                 :            : /**
      77                 :            :  * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
      78                 :            :  * @rfbuf:
      79                 :            :  * @reg32:
      80                 :            :  * @numBits:
      81                 :            :  * @firstBit:
      82                 :            :  * @column:
      83                 :            :  *
      84                 :            :  * Performs analog "swizzling" of parameters into their location.
      85                 :            :  * Used on external AR2133/AR5133 radios.
      86                 :            :  */
      87                 :         60 : static void ar5008_hw_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
      88                 :            :                                            u32 numBits, u32 firstBit,
      89                 :            :                                            u32 column)
      90                 :            : {
      91                 :         60 :         u32 tmp32, mask, arrayEntry, lastBit;
      92                 :         60 :         int32_t bitPosition, bitsLeft;
      93                 :            : 
      94                 :         60 :         tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
      95                 :         60 :         arrayEntry = (firstBit - 1) / 8;
      96                 :         60 :         bitPosition = (firstBit - 1) % 8;
      97                 :         60 :         bitsLeft = numBits;
      98         [ +  + ]:        120 :         while (bitsLeft > 0) {
      99                 :         60 :                 lastBit = (bitPosition + bitsLeft > 8) ?
     100                 :         60 :                     8 : bitPosition + bitsLeft;
     101                 :         60 :                 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
     102                 :         60 :                     (column * 8);
     103                 :         60 :                 rfBuf[arrayEntry] &= ~mask;
     104                 :         60 :                 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
     105                 :         60 :                                       (column * 8)) & mask;
     106                 :         60 :                 bitsLeft -= 8 - bitPosition;
     107                 :         60 :                 tmp32 = tmp32 >> (8 - bitPosition);
     108                 :         60 :                 bitPosition = 0;
     109                 :         60 :                 arrayEntry++;
     110                 :            :         }
     111                 :         60 : }
     112                 :            : 
     113                 :            : /*
     114                 :            :  * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
     115                 :            :  * rf_pwd_icsyndiv.
     116                 :            :  *
     117                 :            :  * Theoretical Rules:
     118                 :            :  *   if 2 GHz band
     119                 :            :  *      if forceBiasAuto
     120                 :            :  *         if synth_freq < 2412
     121                 :            :  *            bias = 0
     122                 :            :  *         else if 2412 <= synth_freq <= 2422
     123                 :            :  *            bias = 1
     124                 :            :  *         else // synth_freq > 2422
     125                 :            :  *            bias = 2
     126                 :            :  *      else if forceBias > 0
     127                 :            :  *         bias = forceBias & 7
     128                 :            :  *      else
     129                 :            :  *         no change, use value from ini file
     130                 :            :  *   else
     131                 :            :  *      no change, invalid band
     132                 :            :  *
     133                 :            :  *  1st Mod:
     134                 :            :  *    2422 also uses value of 2
     135                 :            :  *    <approved>
     136                 :            :  *
     137                 :            :  *  2nd Mod:
     138                 :            :  *    Less than 2412 uses value of 0, 2412 and above uses value of 2
     139                 :            :  */
     140                 :         20 : static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
     141                 :            : {
     142         [ +  - ]:         20 :         struct ath_common *common = ath9k_hw_common(ah);
     143                 :         20 :         u32 tmp_reg;
     144                 :         20 :         int reg_writes = 0;
     145                 :         20 :         u32 new_bias = 0;
     146                 :            : 
     147   [ +  -  -  + ]:         20 :         if (!AR_SREV_5416(ah) || synth_freq >= 3000)
     148                 :          0 :                 return;
     149                 :            : 
     150                 :         20 :         BUG_ON(AR_SREV_9280_20_OR_LATER(ah));
     151                 :            : 
     152         [ +  - ]:         20 :         if (synth_freq < 2412)
     153                 :            :                 new_bias = 0;
     154         [ -  + ]:         20 :         else if (synth_freq < 2422)
     155                 :            :                 new_bias = 1;
     156                 :            :         else
     157                 :          0 :                 new_bias = 2;
     158                 :            : 
     159                 :            :         /* pre-reverse this field */
     160                 :         20 :         tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
     161                 :            : 
     162         [ -  + ]:         20 :         ath_dbg(common, CONFIG, "Force rf_pwd_icsyndiv to %1d on %4d\n",
     163                 :            :                 new_bias, synth_freq);
     164                 :            : 
     165                 :            :         /* swizzle rf_pwd_icsyndiv */
     166                 :         20 :         ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
     167                 :            : 
     168                 :            :         /* write Bank 6 with new params */
     169                 :         20 :         ar5008_write_bank6(ah, &reg_writes);
     170                 :            : }
     171                 :            : 
     172                 :            : /**
     173                 :            :  * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
     174                 :            :  * @ah: atheros hardware structure
     175                 :            :  * @chan:
     176                 :            :  *
     177                 :            :  * For the external AR2133/AR5133 radios, takes the MHz channel value and set
     178                 :            :  * the channel value. Assumes writes enabled to analog bus and bank6 register
     179                 :            :  * cache in ah->analogBank6Data.
     180                 :            :  */
     181                 :         20 : static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
     182                 :            : {
     183                 :         20 :         struct ath_common *common = ath9k_hw_common(ah);
     184                 :         20 :         u32 channelSel = 0;
     185                 :         20 :         u32 bModeSynth = 0;
     186                 :         20 :         u32 aModeRefSel = 0;
     187                 :         20 :         u32 reg32 = 0;
     188                 :         20 :         u16 freq;
     189                 :         20 :         struct chan_centers centers;
     190                 :            : 
     191                 :         20 :         ath9k_hw_get_channel_centers(ah, chan, &centers);
     192                 :         20 :         freq = centers.synth_center;
     193                 :            : 
     194         [ +  - ]:         20 :         if (freq < 4800) {
     195                 :         20 :                 u32 txctl;
     196                 :            : 
     197         [ +  - ]:         20 :                 if (((freq - 2192) % 5) == 0) {
     198                 :         20 :                         channelSel = ((freq - 672) * 2 - 3040) / 10;
     199                 :         20 :                         bModeSynth = 0;
     200         [ #  # ]:          0 :                 } else if (((freq - 2224) % 5) == 0) {
     201                 :          0 :                         channelSel = ((freq - 704) * 2 - 3040) / 10;
     202                 :          0 :                         bModeSynth = 1;
     203                 :            :                 } else {
     204                 :          0 :                         ath_err(common, "Invalid channel %u MHz\n", freq);
     205                 :          0 :                         return -EINVAL;
     206                 :            :                 }
     207                 :            : 
     208                 :         20 :                 channelSel = (channelSel << 2) & 0xff;
     209                 :         20 :                 channelSel = ath9k_hw_reverse_bits(channelSel, 8);
     210                 :            : 
     211                 :         20 :                 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
     212         [ -  + ]:         20 :                 if (freq == 2484) {
     213                 :            : 
     214                 :          0 :                         REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
     215                 :            :                                   txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
     216                 :            :                 } else {
     217                 :         20 :                         REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
     218                 :            :                                   txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
     219                 :            :                 }
     220                 :            : 
     221   [ #  #  #  # ]:          0 :         } else if ((freq % 20) == 0 && freq >= 5120) {
     222                 :          0 :                 channelSel =
     223                 :          0 :                     ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
     224                 :          0 :                 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
     225         [ #  # ]:          0 :         } else if ((freq % 10) == 0) {
     226                 :          0 :                 channelSel =
     227                 :          0 :                     ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
     228   [ #  #  #  # ]:          0 :                 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
     229                 :          0 :                         aModeRefSel = ath9k_hw_reverse_bits(2, 2);
     230                 :            :                 else
     231                 :          0 :                         aModeRefSel = ath9k_hw_reverse_bits(1, 2);
     232         [ #  # ]:          0 :         } else if ((freq % 5) == 0) {
     233                 :          0 :                 channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
     234                 :          0 :                 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
     235                 :            :         } else {
     236                 :          0 :                 ath_err(common, "Invalid channel %u MHz\n", freq);
     237                 :          0 :                 return -EINVAL;
     238                 :            :         }
     239                 :            : 
     240                 :         20 :         ar5008_hw_force_bias(ah, freq);
     241                 :            : 
     242                 :         20 :         reg32 =
     243                 :         20 :             (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
     244                 :            :             (1 << 5) | 0x1;
     245                 :            : 
     246                 :         20 :         REG_WRITE(ah, AR_PHY(0x37), reg32);
     247                 :            : 
     248                 :         20 :         ah->curchan = chan;
     249                 :            : 
     250                 :         20 :         return 0;
     251                 :            : }
     252                 :            : 
     253                 :          0 : void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,
     254                 :            :                           struct ath9k_channel *chan, int bin)
     255                 :            : {
     256                 :          0 :         int cur_bin;
     257                 :          0 :         int upper, lower, cur_vit_mask;
     258                 :          0 :         int i;
     259                 :          0 :         int8_t mask_m[123] = {0};
     260                 :          0 :         int8_t mask_p[123] = {0};
     261                 :          0 :         int8_t mask_amt;
     262                 :          0 :         int tmp_mask;
     263                 :          0 :         static const int pilot_mask_reg[4] = {
     264                 :            :                 AR_PHY_TIMING7, AR_PHY_TIMING8,
     265                 :            :                 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
     266                 :            :         };
     267                 :          0 :         static const int chan_mask_reg[4] = {
     268                 :            :                 AR_PHY_TIMING9, AR_PHY_TIMING10,
     269                 :            :                 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
     270                 :            :         };
     271                 :          0 :         static const int inc[4] = { 0, 100, 0, 0 };
     272                 :            : 
     273                 :          0 :         cur_bin = -6000;
     274                 :          0 :         upper = bin + 100;
     275                 :          0 :         lower = bin - 100;
     276                 :            : 
     277         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
     278                 :            :                 int pilot_mask = 0;
     279                 :            :                 int chan_mask = 0;
     280                 :            :                 int bp = 0;
     281                 :            : 
     282         [ #  # ]:          0 :                 for (bp = 0; bp < 30; bp++) {
     283   [ #  #  #  # ]:          0 :                         if ((cur_bin > lower) && (cur_bin < upper)) {
     284                 :          0 :                                 pilot_mask = pilot_mask | 0x1 << bp;
     285                 :          0 :                                 chan_mask = chan_mask | 0x1 << bp;
     286                 :            :                         }
     287                 :          0 :                         cur_bin += 100;
     288                 :            :                 }
     289                 :          0 :                 cur_bin += inc[i];
     290                 :          0 :                 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
     291                 :          0 :                 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
     292                 :            :         }
     293                 :            : 
     294                 :          0 :         cur_vit_mask = 6100;
     295                 :          0 :         upper = bin + 120;
     296                 :          0 :         lower = bin - 120;
     297                 :            : 
     298         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(mask_m); i++) {
     299   [ #  #  #  # ]:          0 :                 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
     300                 :            :                         /* workaround for gcc bug #37014 */
     301                 :          0 :                         volatile int tmp_v = abs(cur_vit_mask - bin);
     302                 :            : 
     303         [ #  # ]:          0 :                         if (tmp_v < 75)
     304                 :            :                                 mask_amt = 1;
     305                 :            :                         else
     306                 :          0 :                                 mask_amt = 0;
     307         [ #  # ]:          0 :                         if (cur_vit_mask < 0)
     308                 :          0 :                                 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
     309                 :            :                         else
     310                 :          0 :                                 mask_p[cur_vit_mask / 100] = mask_amt;
     311                 :            :                 }
     312                 :          0 :                 cur_vit_mask -= 100;
     313                 :            :         }
     314                 :            : 
     315                 :          0 :         tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
     316                 :          0 :                 | (mask_m[48] << 26) | (mask_m[49] << 24)
     317                 :          0 :                 | (mask_m[50] << 22) | (mask_m[51] << 20)
     318                 :          0 :                 | (mask_m[52] << 18) | (mask_m[53] << 16)
     319                 :          0 :                 | (mask_m[54] << 14) | (mask_m[55] << 12)
     320                 :          0 :                 | (mask_m[56] << 10) | (mask_m[57] << 8)
     321                 :          0 :                 | (mask_m[58] << 6) | (mask_m[59] << 4)
     322                 :          0 :                 | (mask_m[60] << 2) | (mask_m[61] << 0);
     323                 :          0 :         REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
     324                 :          0 :         REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
     325                 :            : 
     326                 :          0 :         tmp_mask = (mask_m[31] << 28)
     327                 :          0 :                 | (mask_m[32] << 26) | (mask_m[33] << 24)
     328                 :          0 :                 | (mask_m[34] << 22) | (mask_m[35] << 20)
     329                 :          0 :                 | (mask_m[36] << 18) | (mask_m[37] << 16)
     330                 :          0 :                 | (mask_m[48] << 14) | (mask_m[39] << 12)
     331                 :          0 :                 | (mask_m[40] << 10) | (mask_m[41] << 8)
     332                 :          0 :                 | (mask_m[42] << 6) | (mask_m[43] << 4)
     333                 :          0 :                 | (mask_m[44] << 2) | (mask_m[45] << 0);
     334                 :          0 :         REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
     335                 :          0 :         REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
     336                 :            : 
     337                 :          0 :         tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
     338                 :          0 :                 | (mask_m[18] << 26) | (mask_m[18] << 24)
     339                 :          0 :                 | (mask_m[20] << 22) | (mask_m[20] << 20)
     340                 :          0 :                 | (mask_m[22] << 18) | (mask_m[22] << 16)
     341                 :          0 :                 | (mask_m[24] << 14) | (mask_m[24] << 12)
     342                 :          0 :                 | (mask_m[25] << 10) | (mask_m[26] << 8)
     343                 :          0 :                 | (mask_m[27] << 6) | (mask_m[28] << 4)
     344                 :          0 :                 | (mask_m[29] << 2) | (mask_m[30] << 0);
     345                 :          0 :         REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
     346                 :          0 :         REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
     347                 :            : 
     348                 :          0 :         tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
     349                 :          0 :                 | (mask_m[2] << 26) | (mask_m[3] << 24)
     350                 :          0 :                 | (mask_m[4] << 22) | (mask_m[5] << 20)
     351                 :          0 :                 | (mask_m[6] << 18) | (mask_m[7] << 16)
     352                 :          0 :                 | (mask_m[8] << 14) | (mask_m[9] << 12)
     353                 :          0 :                 | (mask_m[10] << 10) | (mask_m[11] << 8)
     354                 :          0 :                 | (mask_m[12] << 6) | (mask_m[13] << 4)
     355                 :          0 :                 | (mask_m[14] << 2) | (mask_m[15] << 0);
     356                 :          0 :         REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
     357                 :          0 :         REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
     358                 :            : 
     359                 :          0 :         tmp_mask = (mask_p[15] << 28)
     360                 :          0 :                 | (mask_p[14] << 26) | (mask_p[13] << 24)
     361                 :          0 :                 | (mask_p[12] << 22) | (mask_p[11] << 20)
     362                 :          0 :                 | (mask_p[10] << 18) | (mask_p[9] << 16)
     363                 :          0 :                 | (mask_p[8] << 14) | (mask_p[7] << 12)
     364                 :          0 :                 | (mask_p[6] << 10) | (mask_p[5] << 8)
     365                 :          0 :                 | (mask_p[4] << 6) | (mask_p[3] << 4)
     366                 :          0 :                 | (mask_p[2] << 2) | (mask_p[1] << 0);
     367                 :          0 :         REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
     368                 :          0 :         REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
     369                 :            : 
     370                 :          0 :         tmp_mask = (mask_p[30] << 28)
     371                 :          0 :                 | (mask_p[29] << 26) | (mask_p[28] << 24)
     372                 :          0 :                 | (mask_p[27] << 22) | (mask_p[26] << 20)
     373                 :          0 :                 | (mask_p[25] << 18) | (mask_p[24] << 16)
     374                 :          0 :                 | (mask_p[23] << 14) | (mask_p[22] << 12)
     375                 :          0 :                 | (mask_p[21] << 10) | (mask_p[20] << 8)
     376                 :          0 :                 | (mask_p[19] << 6) | (mask_p[18] << 4)
     377                 :          0 :                 | (mask_p[17] << 2) | (mask_p[16] << 0);
     378                 :          0 :         REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
     379                 :          0 :         REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
     380                 :            : 
     381                 :          0 :         tmp_mask = (mask_p[45] << 28)
     382                 :          0 :                 | (mask_p[44] << 26) | (mask_p[43] << 24)
     383                 :          0 :                 | (mask_p[42] << 22) | (mask_p[41] << 20)
     384                 :          0 :                 | (mask_p[40] << 18) | (mask_p[39] << 16)
     385                 :          0 :                 | (mask_p[38] << 14) | (mask_p[37] << 12)
     386                 :          0 :                 | (mask_p[36] << 10) | (mask_p[35] << 8)
     387                 :          0 :                 | (mask_p[34] << 6) | (mask_p[33] << 4)
     388                 :          0 :                 | (mask_p[32] << 2) | (mask_p[31] << 0);
     389                 :          0 :         REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
     390                 :          0 :         REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
     391                 :            : 
     392                 :          0 :         tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
     393                 :          0 :                 | (mask_p[59] << 26) | (mask_p[58] << 24)
     394                 :          0 :                 | (mask_p[57] << 22) | (mask_p[56] << 20)
     395                 :          0 :                 | (mask_p[55] << 18) | (mask_p[54] << 16)
     396                 :          0 :                 | (mask_p[53] << 14) | (mask_p[52] << 12)
     397                 :          0 :                 | (mask_p[51] << 10) | (mask_p[50] << 8)
     398                 :          0 :                 | (mask_p[49] << 6) | (mask_p[48] << 4)
     399                 :          0 :                 | (mask_p[47] << 2) | (mask_p[46] << 0);
     400                 :          0 :         REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
     401                 :          0 :         REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
     402                 :          0 : }
     403                 :            : 
     404                 :            : /**
     405                 :            :  * ar5008_hw_spur_mitigate - convert baseband spur frequency for external radios
     406                 :            :  * @ah: atheros hardware structure
     407                 :            :  * @chan:
     408                 :            :  *
     409                 :            :  * For non single-chip solutions. Converts to baseband spur frequency given the
     410                 :            :  * input channel frequency and compute register settings below.
     411                 :            :  */
     412                 :         20 : static void ar5008_hw_spur_mitigate(struct ath_hw *ah,
     413                 :            :                                     struct ath9k_channel *chan)
     414                 :            : {
     415                 :         20 :         int bb_spur = AR_NO_SPUR;
     416                 :         20 :         int bin;
     417                 :         20 :         int spur_freq_sd;
     418                 :         20 :         int spur_delta_phase;
     419                 :         20 :         int denominator;
     420                 :         20 :         int tmp, new;
     421                 :         20 :         int i;
     422                 :            : 
     423                 :         20 :         int cur_bb_spur;
     424                 :         20 :         bool is2GHz = IS_CHAN_2GHZ(chan);
     425                 :            : 
     426         [ +  + ]:        120 :         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
     427                 :        100 :                 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
     428         [ +  - ]:        100 :                 if (AR_NO_SPUR == cur_bb_spur)
     429                 :            :                         break;
     430                 :        100 :                 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
     431         [ +  - ]:        100 :                 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
     432                 :            :                         bb_spur = cur_bb_spur;
     433                 :            :                         break;
     434                 :            :                 }
     435                 :            :         }
     436                 :            : 
     437         [ -  + ]:         20 :         if (AR_NO_SPUR == bb_spur)
     438                 :            :                 return;
     439                 :            : 
     440                 :          0 :         bin = bb_spur * 32;
     441                 :            : 
     442                 :          0 :         tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
     443                 :          0 :         new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
     444                 :            :                      AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
     445                 :            :                      AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
     446                 :            :                      AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
     447                 :            : 
     448                 :          0 :         REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
     449                 :            : 
     450                 :          0 :         new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
     451                 :            :                AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
     452                 :            :                AR_PHY_SPUR_REG_MASK_RATE_SELECT |
     453                 :            :                AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
     454                 :            :                SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
     455                 :          0 :         REG_WRITE(ah, AR_PHY_SPUR_REG, new);
     456                 :            : 
     457                 :          0 :         spur_delta_phase = ((bb_spur * 524288) / 100) &
     458                 :            :                 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
     459                 :            : 
     460         [ #  # ]:          0 :         denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
     461                 :          0 :         spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
     462                 :            : 
     463                 :          0 :         new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
     464                 :          0 :                SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
     465                 :            :                SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
     466                 :          0 :         REG_WRITE(ah, AR_PHY_TIMING11, new);
     467                 :            : 
     468                 :          0 :         ar5008_hw_cmn_spur_mitigate(ah, chan, bin);
     469                 :            : }
     470                 :            : 
     471                 :            : /**
     472                 :            :  * ar5008_hw_rf_alloc_ext_banks - allocates banks for external radio programming
     473                 :            :  * @ah: atheros hardware structure
     474                 :            :  *
     475                 :            :  * Only required for older devices with external AR2133/AR5133 radios.
     476                 :            :  */
     477                 :         22 : static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
     478                 :            : {
     479                 :         22 :         int size = ah->iniBank6.ia_rows * sizeof(u32);
     480                 :            : 
     481         [ +  - ]:         22 :         if (AR_SREV_9280_20_OR_LATER(ah))
     482                 :            :             return 0;
     483                 :            : 
     484                 :         22 :         ah->analogBank6Data = devm_kzalloc(ah->dev, size, GFP_KERNEL);
     485         [ -  + ]:         22 :         if (!ah->analogBank6Data)
     486                 :          0 :                 return -ENOMEM;
     487                 :            : 
     488                 :            :         return 0;
     489                 :            : }
     490                 :            : 
     491                 :            : 
     492                 :            : /* *
     493                 :            :  * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM
     494                 :            :  * @ah: atheros hardware structure
     495                 :            :  * @chan:
     496                 :            :  * @modesIndex:
     497                 :            :  *
     498                 :            :  * Used for the external AR2133/AR5133 radios.
     499                 :            :  *
     500                 :            :  * Reads the EEPROM header info from the device structure and programs
     501                 :            :  * all rf registers. This routine requires access to the analog
     502                 :            :  * rf device. This is not required for single-chip devices.
     503                 :            :  */
     504                 :         20 : static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
     505                 :            :                                   struct ath9k_channel *chan,
     506                 :            :                                   u16 modesIndex)
     507                 :            : {
     508                 :         20 :         u32 eepMinorRev;
     509                 :         20 :         u32 ob5GHz = 0, db5GHz = 0;
     510                 :         20 :         u32 ob2GHz = 0, db2GHz = 0;
     511                 :         20 :         int regWrites = 0;
     512                 :         20 :         int i;
     513                 :            : 
     514                 :            :         /*
     515                 :            :          * Software does not need to program bank data
     516                 :            :          * for single chip devices, that is AR9280 or anything
     517                 :            :          * after that.
     518                 :            :          */
     519         [ +  - ]:         20 :         if (AR_SREV_9280_20_OR_LATER(ah))
     520                 :            :                 return true;
     521                 :            : 
     522                 :            :         /* Setup rf parameters */
     523                 :         20 :         eepMinorRev = ah->eep_ops->get_eeprom_rev(ah);
     524                 :            : 
     525         [ +  + ]:        680 :         for (i = 0; i < ah->iniBank6.ia_rows; i++)
     526                 :        660 :                 ah->analogBank6Data[i] = INI_RA(&ah->iniBank6, i, modesIndex);
     527                 :            : 
     528                 :            :         /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
     529         [ +  - ]:         20 :         if (eepMinorRev >= 2) {
     530         [ +  - ]:         20 :                 if (IS_CHAN_2GHZ(chan)) {
     531                 :         20 :                         ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
     532                 :         20 :                         db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
     533                 :         20 :                         ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
     534                 :            :                                                        ob2GHz, 3, 197, 0);
     535                 :         20 :                         ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
     536                 :            :                                                        db2GHz, 3, 194, 0);
     537                 :            :                 } else {
     538                 :          0 :                         ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
     539                 :          0 :                         db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
     540                 :          0 :                         ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
     541                 :            :                                                        ob5GHz, 3, 203, 0);
     542                 :          0 :                         ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,
     543                 :            :                                                        db5GHz, 3, 200, 0);
     544                 :            :                 }
     545                 :            :         }
     546                 :            : 
     547                 :            :         /* Write Analog registers */
     548                 :         20 :         REG_WRITE_ARRAY(&bank0, 1, regWrites);
     549                 :         20 :         REG_WRITE_ARRAY(&bank1, 1, regWrites);
     550                 :         20 :         REG_WRITE_ARRAY(&bank2, 1, regWrites);
     551                 :         20 :         REG_WRITE_ARRAY(&bank3, modesIndex, regWrites);
     552                 :         20 :         ar5008_write_bank6(ah, &regWrites);
     553                 :         20 :         REG_WRITE_ARRAY(&bank7, 1, regWrites);
     554                 :            : 
     555                 :         20 :         return true;
     556                 :            : }
     557                 :            : 
     558                 :         20 : static void ar5008_hw_init_bb(struct ath_hw *ah,
     559                 :            :                               struct ath9k_channel *chan)
     560                 :            : {
     561                 :         20 :         u32 synthDelay;
     562                 :            : 
     563                 :         20 :         synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
     564                 :            : 
     565                 :         20 :         REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
     566                 :            : 
     567                 :         20 :         ath9k_hw_synth_delay(ah, chan, synthDelay);
     568                 :         20 : }
     569                 :            : 
     570                 :         20 : static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
     571                 :            : {
     572                 :         20 :         int rx_chainmask, tx_chainmask;
     573                 :            : 
     574                 :         20 :         rx_chainmask = ah->rxchainmask;
     575                 :         20 :         tx_chainmask = ah->txchainmask;
     576                 :            : 
     577                 :            : 
     578   [ -  -  +  - ]:         20 :         switch (rx_chainmask) {
     579                 :          0 :         case 0x5:
     580                 :          0 :                 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
     581                 :            :                             AR_PHY_SWAP_ALT_CHAIN);
     582                 :            :                 /* fall through */
     583                 :          0 :         case 0x3:
     584         [ #  # ]:          0 :                 if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
     585                 :          0 :                         REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
     586                 :          0 :                         REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
     587                 :          0 :                         break;
     588                 :            :                 }
     589                 :            :                 /* fall through */
     590                 :            :         case 0x1:
     591                 :            :         case 0x2:
     592                 :            :         case 0x7:
     593         [ -  + ]:         20 :                 ENABLE_REGWRITE_BUFFER(ah);
     594                 :         20 :                 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
     595                 :         20 :                 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
     596                 :         20 :                 break;
     597                 :          0 :         default:
     598         [ #  # ]:          0 :                 ENABLE_REGWRITE_BUFFER(ah);
     599                 :            :                 break;
     600                 :            :         }
     601                 :            : 
     602                 :         20 :         REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
     603                 :            : 
     604         [ -  + ]:         20 :         REGWRITE_BUFFER_FLUSH(ah);
     605                 :            : 
     606         [ -  + ]:         20 :         if (tx_chainmask == 0x5) {
     607                 :          0 :                 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
     608                 :            :                             AR_PHY_SWAP_ALT_CHAIN);
     609                 :            :         }
     610         [ -  + ]:         20 :         if (AR_SREV_9100(ah))
     611                 :          0 :                 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
     612                 :            :                           REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
     613                 :         20 : }
     614                 :            : 
     615                 :            : static void ar5008_hw_override_ini(struct ath_hw *ah,
     616                 :            :                                    struct ath9k_channel *chan)
     617                 :            : {
     618                 :            :         u32 val;
     619                 :            : 
     620                 :            :         /*
     621                 :            :          * Set the RX_ABORT and RX_DIS and clear if off only after
     622                 :            :          * RXE is set for MAC. This prevents frames with corrupted
     623                 :            :          * descriptor status.
     624                 :            :          */
     625                 :            :         REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
     626                 :            : 
     627                 :            :         if (AR_SREV_9280_20_OR_LATER(ah)) {
     628                 :            :                 /*
     629                 :            :                  * For AR9280 and above, there is a new feature that allows
     630                 :            :                  * Multicast search based on both MAC Address and Key ID.
     631                 :            :                  * By default, this feature is enabled. But since the driver
     632                 :            :                  * is not using this feature, we switch it off; otherwise
     633                 :            :                  * multicast search based on MAC addr only will fail.
     634                 :            :                  */
     635                 :            :                 val = REG_READ(ah, AR_PCU_MISC_MODE2) &
     636                 :            :                         (~AR_ADHOC_MCAST_KEYID_ENABLE);
     637                 :            : 
     638                 :            :                 if (!AR_SREV_9271(ah))
     639                 :            :                         val &= ~AR_PCU_MISC_MODE2_HWWAR1;
     640                 :            : 
     641                 :            :                 if (AR_SREV_9287_11_OR_LATER(ah))
     642                 :            :                         val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
     643                 :            : 
     644                 :            :                 val |= AR_PCU_MISC_MODE2_CFP_IGNORE;
     645                 :            : 
     646                 :            :                 REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
     647                 :            :         }
     648                 :            : 
     649                 :            :         if (AR_SREV_9280_20_OR_LATER(ah))
     650                 :            :                 return;
     651                 :            :         /*
     652                 :            :          * Disable BB clock gating
     653                 :            :          * Necessary to avoid issues on AR5416 2.0
     654                 :            :          */
     655                 :            :         REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
     656                 :            : 
     657                 :            :         /*
     658                 :            :          * Disable RIFS search on some chips to avoid baseband
     659                 :            :          * hang issues.
     660                 :            :          */
     661                 :            :         if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {
     662                 :            :                 val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
     663                 :            :                 val &= ~AR_PHY_RIFS_INIT_DELAY;
     664                 :            :                 REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
     665                 :            :         }
     666                 :            : }
     667                 :            : 
     668                 :         20 : static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
     669                 :            :                                        struct ath9k_channel *chan)
     670                 :            : {
     671                 :         20 :         u32 phymode;
     672                 :         20 :         u32 enableDacFifo = 0;
     673                 :            : 
     674         [ -  + ]:         20 :         if (AR_SREV_9285_12_OR_LATER(ah))
     675                 :          0 :                 enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
     676                 :            :                                          AR_PHY_FC_ENABLE_DAC_FIFO);
     677                 :            : 
     678                 :         20 :         phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
     679                 :            :                 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
     680                 :            : 
     681         [ -  + ]:         20 :         if (IS_CHAN_HT40(chan)) {
     682                 :          0 :                 phymode |= AR_PHY_FC_DYN2040_EN;
     683                 :            : 
     684         [ #  # ]:          0 :                 if (IS_CHAN_HT40PLUS(chan))
     685                 :          0 :                         phymode |= AR_PHY_FC_DYN2040_PRI_CH;
     686                 :            : 
     687                 :            :         }
     688         [ -  + ]:         20 :         ENABLE_REGWRITE_BUFFER(ah);
     689                 :         20 :         REG_WRITE(ah, AR_PHY_TURBO, phymode);
     690                 :            : 
     691                 :            :         /* This function do only REG_WRITE, so
     692                 :            :          * we can include it to REGWRITE_BUFFER. */
     693                 :         20 :         ath9k_hw_set11nmac2040(ah, chan);
     694                 :            : 
     695                 :         20 :         REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
     696                 :         20 :         REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
     697                 :            : 
     698         [ -  + ]:         20 :         REGWRITE_BUFFER_FLUSH(ah);
     699                 :         20 : }
     700                 :            : 
     701                 :            : 
     702                 :         20 : static int ar5008_hw_process_ini(struct ath_hw *ah,
     703                 :            :                                  struct ath9k_channel *chan)
     704                 :            : {
     705         [ -  + ]:         20 :         struct ath_common *common = ath9k_hw_common(ah);
     706                 :         20 :         int i, regWrites = 0;
     707                 :         20 :         u32 modesIndex, freqIndex;
     708                 :            : 
     709         [ -  + ]:         20 :         if (IS_CHAN_5GHZ(chan)) {
     710                 :          0 :                 freqIndex = 1;
     711         [ #  # ]:          0 :                 modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
     712                 :            :         } else {
     713                 :         20 :                 freqIndex = 2;
     714         [ +  - ]:         20 :                 modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
     715                 :            :         }
     716                 :            : 
     717                 :            :         /*
     718                 :            :          * Set correct baseband to analog shift setting to
     719                 :            :          * access analog chips.
     720                 :            :          */
     721                 :         20 :         REG_WRITE(ah, AR_PHY(0), 0x00000007);
     722                 :            : 
     723                 :            :         /* Write ADDAC shifts */
     724                 :         20 :         REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
     725         [ +  - ]:         20 :         if (ah->eep_ops->set_addac)
     726                 :         20 :                 ah->eep_ops->set_addac(ah, chan);
     727                 :            : 
     728                 :         20 :         REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
     729                 :         20 :         REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
     730                 :            : 
     731         [ -  + ]:         20 :         ENABLE_REGWRITE_BUFFER(ah);
     732                 :            : 
     733         [ +  + ]:       1280 :         for (i = 0; i < ah->iniModes.ia_rows; i++) {
     734                 :       1260 :                 u32 reg = INI_RA(&ah->iniModes, i, 0);
     735                 :       1260 :                 u32 val = INI_RA(&ah->iniModes, i, modesIndex);
     736                 :            : 
     737   [ -  +  -  - ]:       1260 :                 if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup)
     738                 :          0 :                         val &= ~AR_AN_TOP2_PWDCLKIND;
     739                 :            : 
     740                 :       1260 :                 REG_WRITE(ah, reg, val);
     741                 :            : 
     742         [ -  + ]:       1260 :                 if (reg >= 0x7800 && reg < 0x78a0
     743         [ #  # ]:          0 :                     && ah->config.analog_shiftreg
     744         [ #  # ]:          0 :                     && (common->bus_ops->ath_bus_type != ATH_USB)) {
     745                 :          0 :                         udelay(100);
     746                 :            :                 }
     747                 :            : 
     748   [ +  +  +  - ]:       1260 :                 DO_DELAY(regWrites);
     749                 :            :         }
     750                 :            : 
     751         [ -  + ]:         20 :         REGWRITE_BUFFER_FLUSH(ah);
     752                 :            : 
     753   [ +  -  -  + ]:         20 :         if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))
     754                 :          0 :                 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
     755                 :            : 
     756   [ +  -  -  + ]:         20 :         if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
     757                 :            :             AR_SREV_9287_11_OR_LATER(ah))
     758                 :          0 :                 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
     759                 :            : 
     760         [ -  + ]:         20 :         if (AR_SREV_9271_10(ah)) {
     761                 :          0 :                 REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA);
     762                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa);
     763                 :            :         }
     764                 :            : 
     765         [ -  + ]:         20 :         ENABLE_REGWRITE_BUFFER(ah);
     766                 :            : 
     767                 :            :         /* Write common array parameters */
     768         [ +  + ]:       7500 :         for (i = 0; i < ah->iniCommon.ia_rows; i++) {
     769                 :       7480 :                 u32 reg = INI_RA(&ah->iniCommon, i, 0);
     770                 :       7480 :                 u32 val = INI_RA(&ah->iniCommon, i, 1);
     771                 :            : 
     772                 :       7480 :                 REG_WRITE(ah, reg, val);
     773                 :            : 
     774         [ -  + ]:       7480 :                 if (reg >= 0x7800 && reg < 0x78a0
     775         [ #  # ]:          0 :                     && ah->config.analog_shiftreg
     776         [ #  # ]:          0 :                     && (common->bus_ops->ath_bus_type != ATH_USB)) {
     777                 :          0 :                         udelay(100);
     778                 :            :                 }
     779                 :            : 
     780   [ +  +  +  - ]:       7480 :                 DO_DELAY(regWrites);
     781                 :            :         }
     782                 :            : 
     783         [ -  + ]:         20 :         REGWRITE_BUFFER_FLUSH(ah);
     784                 :            : 
     785                 :         20 :         REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
     786                 :            : 
     787   [ -  +  -  - ]:         20 :         if (IS_CHAN_A_FAST_CLOCK(ah, chan))
     788                 :          0 :                 REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex,
     789                 :            :                                 regWrites);
     790                 :            : 
     791                 :         20 :         ar5008_hw_override_ini(ah, chan);
     792                 :         20 :         ar5008_hw_set_channel_regs(ah, chan);
     793                 :         20 :         ar5008_hw_init_chain_masks(ah);
     794         [ -  + ]:         20 :         ath9k_olc_init(ah);
     795                 :         20 :         ath9k_hw_apply_txpower(ah, chan, false);
     796                 :            : 
     797                 :            :         /* Write analog registers */
     798   [ +  -  -  + ]:         40 :         if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
     799                 :          0 :                 ath_err(ath9k_hw_common(ah), "ar5416SetRfRegs failed\n");
     800                 :          0 :                 return -EIO;
     801                 :            :         }
     802                 :            : 
     803                 :            :         return 0;
     804                 :            : }
     805                 :            : 
     806                 :         20 : static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
     807                 :            : {
     808                 :         20 :         u32 rfMode = 0;
     809                 :            : 
     810         [ +  - ]:         20 :         if (chan == NULL)
     811                 :            :                 return;
     812                 :            : 
     813         [ -  + ]:         20 :         if (IS_CHAN_2GHZ(chan))
     814                 :            :                 rfMode |= AR_PHY_MODE_DYNAMIC;
     815                 :            :         else
     816                 :          0 :                 rfMode |= AR_PHY_MODE_OFDM;
     817                 :            : 
     818         [ +  - ]:         20 :         if (!AR_SREV_9280_20_OR_LATER(ah))
     819                 :         20 :                 rfMode |= (IS_CHAN_5GHZ(chan)) ?
     820         [ +  - ]:         20 :                         AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
     821                 :            : 
     822   [ -  +  -  - ]:         20 :         if (IS_CHAN_A_FAST_CLOCK(ah, chan))
     823                 :          0 :                 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
     824                 :            : 
     825                 :         20 :         REG_WRITE(ah, AR_PHY_MODE, rfMode);
     826                 :            : }
     827                 :            : 
     828                 :         20 : static void ar5008_hw_mark_phy_inactive(struct ath_hw *ah)
     829                 :            : {
     830                 :         20 :         REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
     831                 :         20 : }
     832                 :            : 
     833                 :         20 : static void ar5008_hw_set_delta_slope(struct ath_hw *ah,
     834                 :            :                                       struct ath9k_channel *chan)
     835                 :            : {
     836                 :         20 :         u32 coef_scaled, ds_coef_exp, ds_coef_man;
     837                 :         20 :         u32 clockMhzScaled = 0x64000000;
     838                 :         20 :         struct chan_centers centers;
     839                 :            : 
     840         [ +  - ]:         20 :         if (IS_CHAN_HALF_RATE(chan))
     841                 :            :                 clockMhzScaled = clockMhzScaled >> 1;
     842         [ -  + ]:         20 :         else if (IS_CHAN_QUARTER_RATE(chan))
     843                 :          0 :                 clockMhzScaled = clockMhzScaled >> 2;
     844                 :            : 
     845                 :         20 :         ath9k_hw_get_channel_centers(ah, chan, &centers);
     846                 :         20 :         coef_scaled = clockMhzScaled / centers.synth_center;
     847                 :            : 
     848                 :         20 :         ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
     849                 :            :                                       &ds_coef_exp);
     850                 :            : 
     851                 :         20 :         REG_RMW_FIELD(ah, AR_PHY_TIMING3,
     852                 :            :                       AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
     853                 :         20 :         REG_RMW_FIELD(ah, AR_PHY_TIMING3,
     854                 :            :                       AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
     855                 :            : 
     856                 :         20 :         coef_scaled = (9 * coef_scaled) / 10;
     857                 :            : 
     858                 :         20 :         ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
     859                 :            :                                       &ds_coef_exp);
     860                 :            : 
     861                 :         20 :         REG_RMW_FIELD(ah, AR_PHY_HALFGI,
     862                 :            :                       AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
     863                 :         20 :         REG_RMW_FIELD(ah, AR_PHY_HALFGI,
     864                 :            :                       AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
     865                 :         20 : }
     866                 :            : 
     867                 :          0 : static bool ar5008_hw_rfbus_req(struct ath_hw *ah)
     868                 :            : {
     869                 :          0 :         REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
     870                 :          0 :         return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
     871                 :            :                            AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
     872                 :            : }
     873                 :            : 
     874                 :          0 : static void ar5008_hw_rfbus_done(struct ath_hw *ah)
     875                 :            : {
     876                 :          0 :         u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
     877                 :            : 
     878                 :          0 :         ath9k_hw_synth_delay(ah, ah->curchan, synthDelay);
     879                 :            : 
     880                 :          0 :         REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
     881                 :          0 : }
     882                 :            : 
     883                 :         20 : static void ar5008_restore_chainmask(struct ath_hw *ah)
     884                 :            : {
     885                 :         20 :         int rx_chainmask = ah->rxchainmask;
     886                 :            : 
     887   [ +  -  -  + ]:         20 :         if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
     888                 :          0 :                 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
     889                 :          0 :                 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
     890                 :            :         }
     891                 :         20 : }
     892                 :            : 
     893                 :          0 : static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,
     894                 :            :                                          struct ath9k_channel *chan)
     895                 :            : {
     896                 :          0 :         u32 pll;
     897                 :            : 
     898                 :          0 :         pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
     899                 :            : 
     900   [ #  #  #  # ]:          0 :         if (chan && IS_CHAN_HALF_RATE(chan))
     901                 :            :                 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
     902   [ #  #  #  # ]:          0 :         else if (chan && IS_CHAN_QUARTER_RATE(chan))
     903                 :          0 :                 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
     904                 :            : 
     905   [ #  #  #  # ]:          0 :         if (chan && IS_CHAN_5GHZ(chan))
     906                 :          0 :                 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
     907                 :            :         else
     908                 :          0 :                 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
     909                 :            : 
     910                 :          0 :         return pll;
     911                 :            : }
     912                 :            : 
     913                 :         21 : static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
     914                 :            :                                          struct ath9k_channel *chan)
     915                 :            : {
     916                 :         21 :         u32 pll;
     917                 :            : 
     918                 :         21 :         pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
     919                 :            : 
     920   [ +  +  +  - ]:         21 :         if (chan && IS_CHAN_HALF_RATE(chan))
     921                 :            :                 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
     922   [ +  +  -  + ]:         21 :         else if (chan && IS_CHAN_QUARTER_RATE(chan))
     923                 :          0 :                 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
     924                 :            : 
     925   [ +  +  -  + ]:         21 :         if (chan && IS_CHAN_5GHZ(chan))
     926                 :          0 :                 pll |= SM(0xa, AR_RTC_PLL_DIV);
     927                 :            :         else
     928                 :         21 :                 pll |= SM(0xb, AR_RTC_PLL_DIV);
     929                 :            : 
     930                 :         21 :         return pll;
     931                 :            : }
     932                 :            : 
     933                 :          0 : static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
     934                 :            :                                       enum ath9k_ani_cmd cmd,
     935                 :            :                                       int param)
     936                 :            : {
     937   [ #  #  #  #  :          0 :         struct ath_common *common = ath9k_hw_common(ah);
                      # ]
     938                 :          0 :         struct ath9k_channel *chan = ah->curchan;
     939                 :          0 :         struct ar5416AniState *aniState = &ah->ani;
     940                 :          0 :         s32 value;
     941                 :            : 
     942   [ #  #  #  #  :          0 :         switch (cmd & ah->ani_function) {
                      # ]
     943                 :          0 :         case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
     944                 :            :                 /*
     945                 :            :                  * on == 1 means ofdm weak signal detection is ON
     946                 :            :                  * on == 1 is the default, for less noise immunity
     947                 :            :                  *
     948                 :            :                  * on == 0 means ofdm weak signal detection is OFF
     949                 :            :                  * on == 0 means more noise imm
     950                 :            :                  */
     951                 :          0 :                 u32 on = param ? 1 : 0;
     952                 :            :                 /*
     953                 :            :                  * make register setting for default
     954                 :            :                  * (weak sig detect ON) come from INI file
     955                 :            :                  */
     956                 :          0 :                 int m1ThreshLow = on ?
     957         [ #  # ]:          0 :                         aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
     958                 :          0 :                 int m2ThreshLow = on ?
     959         [ #  # ]:          0 :                         aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
     960                 :          0 :                 int m1Thresh = on ?
     961         [ #  # ]:          0 :                         aniState->iniDef.m1Thresh : m1Thresh_off;
     962                 :          0 :                 int m2Thresh = on ?
     963         [ #  # ]:          0 :                         aniState->iniDef.m2Thresh : m2Thresh_off;
     964                 :          0 :                 int m2CountThr = on ?
     965         [ #  # ]:          0 :                         aniState->iniDef.m2CountThr : m2CountThr_off;
     966                 :          0 :                 int m2CountThrLow = on ?
     967         [ #  # ]:          0 :                         aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
     968                 :          0 :                 int m1ThreshLowExt = on ?
     969         [ #  # ]:          0 :                         aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
     970                 :          0 :                 int m2ThreshLowExt = on ?
     971         [ #  # ]:          0 :                         aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
     972                 :          0 :                 int m1ThreshExt = on ?
     973         [ #  # ]:          0 :                         aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
     974                 :          0 :                 int m2ThreshExt = on ?
     975         [ #  # ]:          0 :                         aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
     976                 :            : 
     977                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
     978                 :            :                               AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
     979                 :            :                               m1ThreshLow);
     980                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
     981                 :            :                               AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
     982                 :            :                               m2ThreshLow);
     983                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
     984                 :            :                               AR_PHY_SFCORR_M1_THRESH, m1Thresh);
     985                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
     986                 :            :                               AR_PHY_SFCORR_M2_THRESH, m2Thresh);
     987                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
     988                 :            :                               AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
     989                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
     990                 :            :                               AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
     991                 :            :                               m2CountThrLow);
     992                 :            : 
     993                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
     994                 :            :                               AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
     995                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
     996                 :            :                               AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
     997                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
     998                 :            :                               AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
     999                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
    1000                 :            :                               AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
    1001                 :            : 
    1002         [ #  # ]:          0 :                 if (on)
    1003                 :          0 :                         REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
    1004                 :            :                                     AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
    1005                 :            :                 else
    1006                 :          0 :                         REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
    1007                 :            :                                     AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
    1008                 :            : 
    1009         [ #  # ]:          0 :                 if (on != aniState->ofdmWeakSigDetect) {
    1010   [ #  #  #  #  :          0 :                         ath_dbg(common, ANI,
                   #  # ]
    1011                 :            :                                 "** ch %d: ofdm weak signal: %s=>%s\n",
    1012                 :            :                                 chan->channel,
    1013                 :            :                                 aniState->ofdmWeakSigDetect ?
    1014                 :            :                                 "on" : "off",
    1015                 :            :                                 on ? "on" : "off");
    1016         [ #  # ]:          0 :                         if (on)
    1017                 :          0 :                                 ah->stats.ast_ani_ofdmon++;
    1018                 :            :                         else
    1019                 :          0 :                                 ah->stats.ast_ani_ofdmoff++;
    1020                 :          0 :                         aniState->ofdmWeakSigDetect = on;
    1021                 :            :                 }
    1022                 :            :                 break;
    1023                 :            :         }
    1024                 :          0 :         case ATH9K_ANI_FIRSTEP_LEVEL:{
    1025                 :          0 :                 u32 level = param;
    1026                 :            : 
    1027                 :          0 :                 value = level * 2;
    1028                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
    1029                 :            :                               AR_PHY_FIND_SIG_FIRSTEP, value);
    1030                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
    1031                 :            :                               AR_PHY_FIND_SIG_FIRSTEP_LOW, value);
    1032                 :            : 
    1033         [ #  # ]:          0 :                 if (level != aniState->firstepLevel) {
    1034         [ #  # ]:          0 :                         ath_dbg(common, ANI,
    1035                 :            :                                 "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
    1036                 :            :                                 chan->channel,
    1037                 :            :                                 aniState->firstepLevel,
    1038                 :            :                                 level,
    1039                 :            :                                 ATH9K_ANI_FIRSTEP_LVL,
    1040                 :            :                                 value,
    1041                 :            :                                 aniState->iniDef.firstep);
    1042         [ #  # ]:          0 :                         ath_dbg(common, ANI,
    1043                 :            :                                 "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",
    1044                 :            :                                 chan->channel,
    1045                 :            :                                 aniState->firstepLevel,
    1046                 :            :                                 level,
    1047                 :            :                                 ATH9K_ANI_FIRSTEP_LVL,
    1048                 :            :                                 value,
    1049                 :            :                                 aniState->iniDef.firstepLow);
    1050         [ #  # ]:          0 :                         if (level > aniState->firstepLevel)
    1051                 :          0 :                                 ah->stats.ast_ani_stepup++;
    1052         [ #  # ]:          0 :                         else if (level < aniState->firstepLevel)
    1053                 :          0 :                                 ah->stats.ast_ani_stepdown++;
    1054                 :          0 :                         aniState->firstepLevel = level;
    1055                 :            :                 }
    1056                 :            :                 break;
    1057                 :            :         }
    1058                 :          0 :         case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
    1059                 :          0 :                 u32 level = param;
    1060                 :            : 
    1061                 :          0 :                 value = (level + 1) * 2;
    1062                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
    1063                 :            :                               AR_PHY_TIMING5_CYCPWR_THR1, value);
    1064                 :            : 
    1065                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
    1066                 :            :                                   AR_PHY_EXT_TIMING5_CYCPWR_THR1, value - 1);
    1067                 :            : 
    1068         [ #  # ]:          0 :                 if (level != aniState->spurImmunityLevel) {
    1069         [ #  # ]:          0 :                         ath_dbg(common, ANI,
    1070                 :            :                                 "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",
    1071                 :            :                                 chan->channel,
    1072                 :            :                                 aniState->spurImmunityLevel,
    1073                 :            :                                 level,
    1074                 :            :                                 ATH9K_ANI_SPUR_IMMUNE_LVL,
    1075                 :            :                                 value,
    1076                 :            :                                 aniState->iniDef.cycpwrThr1);
    1077         [ #  # ]:          0 :                         ath_dbg(common, ANI,
    1078                 :            :                                 "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",
    1079                 :            :                                 chan->channel,
    1080                 :            :                                 aniState->spurImmunityLevel,
    1081                 :            :                                 level,
    1082                 :            :                                 ATH9K_ANI_SPUR_IMMUNE_LVL,
    1083                 :            :                                 value,
    1084                 :            :                                 aniState->iniDef.cycpwrThr1Ext);
    1085         [ #  # ]:          0 :                         if (level > aniState->spurImmunityLevel)
    1086                 :          0 :                                 ah->stats.ast_ani_spurup++;
    1087         [ #  # ]:          0 :                         else if (level < aniState->spurImmunityLevel)
    1088                 :          0 :                                 ah->stats.ast_ani_spurdown++;
    1089                 :          0 :                         aniState->spurImmunityLevel = level;
    1090                 :            :                 }
    1091                 :            :                 break;
    1092                 :            :         }
    1093                 :            :         case ATH9K_ANI_MRC_CCK:
    1094                 :            :                 /*
    1095                 :            :                  * You should not see this as AR5008, AR9001, AR9002
    1096                 :            :                  * does not have hardware support for MRC CCK.
    1097                 :            :                  */
    1098                 :          0 :                 WARN_ON(1);
    1099                 :          0 :                 break;
    1100                 :          0 :         default:
    1101         [ #  # ]:          0 :                 ath_dbg(common, ANI, "invalid cmd %u\n", cmd);
    1102                 :            :                 return false;
    1103                 :            :         }
    1104                 :            : 
    1105   [ #  #  #  #  :          0 :         ath_dbg(common, ANI,
                   #  # ]
    1106                 :            :                 "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
    1107                 :            :                 aniState->spurImmunityLevel,
    1108                 :            :                 aniState->ofdmWeakSigDetect ? "on" : "off",
    1109                 :            :                 aniState->firstepLevel,
    1110                 :            :                 aniState->mrcCCK ? "on" : "off",
    1111                 :            :                 aniState->listenTime,
    1112                 :            :                 aniState->ofdmPhyErrCount,
    1113                 :            :                 aniState->cckPhyErrCount);
    1114                 :            :         return true;
    1115                 :            : }
    1116                 :            : 
    1117                 :         10 : static void ar5008_hw_do_getnf(struct ath_hw *ah,
    1118                 :            :                               int16_t nfarray[NUM_NF_READINGS])
    1119                 :            : {
    1120                 :         10 :         int16_t nf;
    1121                 :            : 
    1122                 :         10 :         nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
    1123                 :         10 :         nfarray[0] = sign_extend32(nf, 8);
    1124                 :            : 
    1125                 :         10 :         nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);
    1126                 :         10 :         nfarray[1] = sign_extend32(nf, 8);
    1127                 :            : 
    1128                 :         10 :         nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
    1129         [ -  + ]:         10 :         nfarray[2] = sign_extend32(nf, 8);
    1130                 :            : 
    1131         [ -  + ]:         10 :         if (!IS_CHAN_HT40(ah->curchan))
    1132                 :            :                 return;
    1133                 :            : 
    1134                 :          0 :         nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
    1135                 :          0 :         nfarray[3] = sign_extend32(nf, 8);
    1136                 :            : 
    1137                 :          0 :         nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);
    1138                 :          0 :         nfarray[4] = sign_extend32(nf, 8);
    1139                 :            : 
    1140                 :          0 :         nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);
    1141                 :          0 :         nfarray[5] = sign_extend32(nf, 8);
    1142                 :            : }
    1143                 :            : 
    1144                 :            : /*
    1145                 :            :  * Initialize the ANI register values with default (ini) values.
    1146                 :            :  * This routine is called during a (full) hardware reset after
    1147                 :            :  * all the registers are initialised from the INI.
    1148                 :            :  */
    1149                 :         20 : static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
    1150                 :            : {
    1151         [ -  + ]:         20 :         struct ath_common *common = ath9k_hw_common(ah);
    1152                 :         20 :         struct ath9k_channel *chan = ah->curchan;
    1153                 :         20 :         struct ar5416AniState *aniState = &ah->ani;
    1154                 :         20 :         struct ath9k_ani_default *iniDef;
    1155                 :         20 :         u32 val;
    1156                 :            : 
    1157                 :         20 :         iniDef = &aniState->iniDef;
    1158                 :            : 
    1159         [ -  + ]:         20 :         ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n",
    1160                 :            :                 ah->hw_version.macVersion,
    1161                 :            :                 ah->hw_version.macRev,
    1162                 :            :                 ah->opmode,
    1163                 :            :                 chan->channel);
    1164                 :            : 
    1165                 :         20 :         val = REG_READ(ah, AR_PHY_SFCORR);
    1166                 :         20 :         iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
    1167                 :         20 :         iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
    1168                 :         20 :         iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
    1169                 :            : 
    1170                 :         20 :         val = REG_READ(ah, AR_PHY_SFCORR_LOW);
    1171                 :         20 :         iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
    1172                 :         20 :         iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
    1173                 :         20 :         iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
    1174                 :            : 
    1175                 :         20 :         val = REG_READ(ah, AR_PHY_SFCORR_EXT);
    1176                 :         20 :         iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
    1177                 :         20 :         iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
    1178                 :         20 :         iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
    1179                 :         20 :         iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
    1180                 :         20 :         iniDef->firstep = REG_READ_FIELD(ah,
    1181                 :            :                                          AR_PHY_FIND_SIG,
    1182                 :            :                                          AR_PHY_FIND_SIG_FIRSTEP);
    1183                 :         20 :         iniDef->firstepLow = REG_READ_FIELD(ah,
    1184                 :            :                                             AR_PHY_FIND_SIG_LOW,
    1185                 :            :                                             AR_PHY_FIND_SIG_FIRSTEP_LOW);
    1186                 :         20 :         iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
    1187                 :            :                                             AR_PHY_TIMING5,
    1188                 :            :                                             AR_PHY_TIMING5_CYCPWR_THR1);
    1189                 :         20 :         iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
    1190                 :            :                                                AR_PHY_EXT_CCA,
    1191                 :            :                                                AR_PHY_EXT_TIMING5_CYCPWR_THR1);
    1192                 :            : 
    1193                 :            :         /* these levels just got reset to defaults by the INI */
    1194                 :         20 :         aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
    1195                 :         20 :         aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
    1196                 :         20 :         aniState->ofdmWeakSigDetect = true;
    1197                 :         20 :         aniState->mrcCCK = false; /* not available on pre AR9003 */
    1198                 :         20 : }
    1199                 :            : 
    1200                 :         22 : static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
    1201                 :            : {
    1202                 :         22 :         ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
    1203                 :         22 :         ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
    1204                 :         22 :         ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
    1205                 :         22 :         ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
    1206                 :         22 :         ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
    1207                 :         22 :         ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
    1208                 :            : }
    1209                 :            : 
    1210                 :          0 : static void ar5008_hw_set_radar_params(struct ath_hw *ah,
    1211                 :            :                                        struct ath_hw_radar_conf *conf)
    1212                 :            : {
    1213                 :          0 :         u32 radar_0 = 0, radar_1;
    1214                 :            : 
    1215         [ #  # ]:          0 :         if (!conf) {
    1216                 :          0 :                 REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);
    1217                 :          0 :                 return;
    1218                 :            :         }
    1219                 :            : 
    1220                 :          0 :         radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;
    1221                 :          0 :         radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);
    1222                 :          0 :         radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);
    1223                 :          0 :         radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);
    1224                 :          0 :         radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);
    1225                 :          0 :         radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);
    1226                 :            : 
    1227                 :          0 :         radar_1 = REG_READ(ah, AR_PHY_RADAR_1);
    1228                 :          0 :         radar_1 &= ~(AR_PHY_RADAR_1_MAXLEN | AR_PHY_RADAR_1_RELSTEP_THRESH |
    1229                 :            :                      AR_PHY_RADAR_1_RELPWR_THRESH);
    1230                 :          0 :         radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;
    1231                 :          0 :         radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;
    1232                 :          0 :         radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);
    1233                 :          0 :         radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);
    1234                 :          0 :         radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);
    1235                 :            : 
    1236                 :          0 :         REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);
    1237                 :          0 :         REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);
    1238         [ #  # ]:          0 :         if (conf->ext_channel)
    1239                 :          0 :                 REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
    1240                 :            :         else
    1241                 :          0 :                 REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);
    1242                 :            : }
    1243                 :            : 
    1244                 :         22 : static void ar5008_hw_set_radar_conf(struct ath_hw *ah)
    1245                 :            : {
    1246                 :         22 :         struct ath_hw_radar_conf *conf = &ah->radar_conf;
    1247                 :            : 
    1248                 :         22 :         conf->fir_power = -33;
    1249                 :         22 :         conf->radar_rssi = 20;
    1250                 :         22 :         conf->pulse_height = 10;
    1251                 :         22 :         conf->pulse_rssi = 15;
    1252                 :         22 :         conf->pulse_inband = 15;
    1253                 :         22 :         conf->pulse_maxlen = 255;
    1254                 :         22 :         conf->pulse_inband_step = 12;
    1255                 :         22 :         conf->radar_inband = 8;
    1256                 :            : }
    1257                 :            : 
    1258                 :          0 : static void ar5008_hw_init_txpower_cck(struct ath_hw *ah, int16_t *rate_array)
    1259                 :            : {
    1260                 :            : #define CCK_DELTA(x) ((OLC_FOR_AR9280_20_LATER) ? max((x) - 2, 0) : (x))
    1261   [ #  #  #  # ]:          0 :         ah->tx_power[0] = CCK_DELTA(rate_array[rate1l]);
    1262   [ #  #  #  # ]:          0 :         ah->tx_power[1] = CCK_DELTA(min(rate_array[rate2l],
    1263                 :            :                                         rate_array[rate2s]));
    1264   [ #  #  #  # ]:          0 :         ah->tx_power[2] = CCK_DELTA(min(rate_array[rate5_5l],
    1265                 :            :                                         rate_array[rate5_5s]));
    1266   [ #  #  #  # ]:          0 :         ah->tx_power[3] = CCK_DELTA(min(rate_array[rate11l],
    1267                 :            :                                         rate_array[rate11s]));
    1268                 :            : #undef CCK_DELTA
    1269                 :          0 : }
    1270                 :            : 
    1271                 :          0 : static void ar5008_hw_init_txpower_ofdm(struct ath_hw *ah, int16_t *rate_array,
    1272                 :            :                                         int offset)
    1273                 :            : {
    1274                 :          0 :         int i, idx = 0;
    1275                 :            : 
    1276   [ #  #  #  # ]:          0 :         for (i = offset; i < offset + AR5008_OFDM_RATES; i++) {
    1277                 :          0 :                 ah->tx_power[i] = rate_array[idx];
    1278                 :          0 :                 idx++;
    1279                 :            :         }
    1280                 :            : }
    1281                 :            : 
    1282                 :          0 : static void ar5008_hw_init_txpower_ht(struct ath_hw *ah, int16_t *rate_array,
    1283                 :            :                                       int ss_offset, int ds_offset,
    1284                 :            :                                       bool is_40, int ht40_delta)
    1285                 :            : {
    1286                 :          0 :         int i, mcs_idx = (is_40) ? AR5008_HT40_SHIFT : AR5008_HT20_SHIFT;
    1287                 :            : 
    1288   [ #  #  #  # ]:          0 :         for (i = ss_offset; i < ss_offset + AR5008_HT_SS_RATES; i++) {
    1289                 :          0 :                 ah->tx_power[i] = rate_array[mcs_idx] + ht40_delta;
    1290                 :          0 :                 mcs_idx++;
    1291                 :            :         }
    1292                 :          0 :         memcpy(&ah->tx_power[ds_offset], &ah->tx_power[ss_offset],
    1293                 :            :                AR5008_HT_SS_RATES);
    1294                 :          0 : }
    1295                 :            : 
    1296                 :          0 : void ar5008_hw_init_rate_txpower(struct ath_hw *ah, int16_t *rate_array,
    1297                 :            :                                  struct ath9k_channel *chan, int ht40_delta)
    1298                 :            : {
    1299         [ #  # ]:          0 :         if (IS_CHAN_5GHZ(chan)) {
    1300                 :            :                 ar5008_hw_init_txpower_ofdm(ah, rate_array,
    1301                 :            :                                             AR5008_11NA_OFDM_SHIFT);
    1302   [ #  #  #  # ]:          0 :                 if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {
    1303         [ #  # ]:          0 :                         ar5008_hw_init_txpower_ht(ah, rate_array,
    1304                 :            :                                                   AR5008_11NA_HT_SS_SHIFT,
    1305                 :            :                                                   AR5008_11NA_HT_DS_SHIFT,
    1306                 :            :                                                   IS_CHAN_HT40(chan),
    1307                 :            :                                                   ht40_delta);
    1308                 :            :                 }
    1309                 :            :         } else {
    1310                 :          0 :                 ar5008_hw_init_txpower_cck(ah, rate_array);
    1311                 :          0 :                 ar5008_hw_init_txpower_ofdm(ah, rate_array,
    1312                 :            :                                             AR5008_11NG_OFDM_SHIFT);
    1313   [ #  #  #  # ]:          0 :                 if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {
    1314         [ #  # ]:          0 :                         ar5008_hw_init_txpower_ht(ah, rate_array,
    1315                 :            :                                                   AR5008_11NG_HT_SS_SHIFT,
    1316                 :            :                                                   AR5008_11NG_HT_DS_SHIFT,
    1317                 :            :                                                   IS_CHAN_HT40(chan),
    1318                 :            :                                                   ht40_delta);
    1319                 :            :                 }
    1320                 :            :         }
    1321                 :          0 : }
    1322                 :            : 
    1323                 :         22 : int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
    1324                 :            : {
    1325                 :         22 :         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
    1326                 :         22 :         static const u32 ar5416_cca_regs[6] = {
    1327                 :            :                 AR_PHY_CCA,
    1328                 :            :                 AR_PHY_CH1_CCA,
    1329                 :            :                 AR_PHY_CH2_CCA,
    1330                 :            :                 AR_PHY_EXT_CCA,
    1331                 :            :                 AR_PHY_CH1_EXT_CCA,
    1332                 :            :                 AR_PHY_CH2_EXT_CCA
    1333                 :            :         };
    1334                 :         22 :         int ret;
    1335                 :            : 
    1336                 :         22 :         ret = ar5008_hw_rf_alloc_ext_banks(ah);
    1337         [ +  - ]:         22 :         if (ret)
    1338                 :            :             return ret;
    1339                 :            : 
    1340                 :         22 :         priv_ops->rf_set_freq = ar5008_hw_set_channel;
    1341                 :         22 :         priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
    1342                 :            : 
    1343                 :         22 :         priv_ops->set_rf_regs = ar5008_hw_set_rf_regs;
    1344                 :         22 :         priv_ops->set_channel_regs = ar5008_hw_set_channel_regs;
    1345                 :         22 :         priv_ops->init_bb = ar5008_hw_init_bb;
    1346                 :         22 :         priv_ops->process_ini = ar5008_hw_process_ini;
    1347                 :         22 :         priv_ops->set_rfmode = ar5008_hw_set_rfmode;
    1348                 :         22 :         priv_ops->mark_phy_inactive = ar5008_hw_mark_phy_inactive;
    1349                 :         22 :         priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
    1350                 :         22 :         priv_ops->rfbus_req = ar5008_hw_rfbus_req;
    1351                 :         22 :         priv_ops->rfbus_done = ar5008_hw_rfbus_done;
    1352                 :         22 :         priv_ops->restore_chainmask = ar5008_restore_chainmask;
    1353                 :         22 :         priv_ops->do_getnf = ar5008_hw_do_getnf;
    1354                 :         22 :         priv_ops->set_radar_params = ar5008_hw_set_radar_params;
    1355                 :            : 
    1356                 :         22 :         priv_ops->ani_control = ar5008_hw_ani_control_new;
    1357                 :         22 :         priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
    1358                 :            : 
    1359   [ +  -  -  + ]:         22 :         if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
    1360                 :          0 :                 priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
    1361                 :            :         else
    1362                 :         22 :                 priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
    1363                 :            : 
    1364                 :         22 :         ar5008_hw_set_nf_limits(ah);
    1365                 :         22 :         ar5008_hw_set_radar_conf(ah);
    1366                 :         22 :         memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
    1367                 :         22 :         return 0;
    1368                 :            : }

Generated by: LCOV version 1.14