LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath9k - ar9002_phy.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 284 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 14 0.0 %
Branches: 0 104 0.0 %

           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                 :            : /**
      18                 :            :  * DOC: Programming Atheros 802.11n analog front end radios
      19                 :            :  *
      20                 :            :  * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
      21                 :            :  * devices have either an external AR2133 analog front end radio for single
      22                 :            :  * band 2.4 GHz communication or an AR5133 analog front end radio for dual
      23                 :            :  * band 2.4 GHz / 5 GHz communication.
      24                 :            :  *
      25                 :            :  * All devices after the AR5416 and AR5418 family starting with the AR9280
      26                 :            :  * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
      27                 :            :  * into a single-chip and require less programming.
      28                 :            :  *
      29                 :            :  * The following single-chips exist with a respective embedded radio:
      30                 :            :  *
      31                 :            :  * AR9280 - 11n dual-band 2x2 MIMO for PCIe
      32                 :            :  * AR9281 - 11n single-band 1x2 MIMO for PCIe
      33                 :            :  * AR9285 - 11n single-band 1x1 for PCIe
      34                 :            :  * AR9287 - 11n single-band 2x2 MIMO for PCIe
      35                 :            :  *
      36                 :            :  * AR9220 - 11n dual-band 2x2 MIMO for PCI
      37                 :            :  * AR9223 - 11n single-band 2x2 MIMO for PCI
      38                 :            :  *
      39                 :            :  * AR9287 - 11n single-band 1x1 MIMO for USB
      40                 :            :  */
      41                 :            : 
      42                 :            : #include "hw.h"
      43                 :            : #include "ar9002_phy.h"
      44                 :            : 
      45                 :            : /**
      46                 :            :  * ar9002_hw_set_channel - set channel on single-chip device
      47                 :            :  * @ah: atheros hardware structure
      48                 :            :  * @chan:
      49                 :            :  *
      50                 :            :  * This is the function to change channel on single-chip devices, that is
      51                 :            :  * all devices after ar9280.
      52                 :            :  *
      53                 :            :  * This function takes the channel value in MHz and sets
      54                 :            :  * hardware channel value. Assumes writes have been enabled to analog bus.
      55                 :            :  *
      56                 :            :  * Actual Expression,
      57                 :            :  *
      58                 :            :  * For 2GHz channel,
      59                 :            :  * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
      60                 :            :  * (freq_ref = 40MHz)
      61                 :            :  *
      62                 :            :  * For 5GHz channel,
      63                 :            :  * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
      64                 :            :  * (freq_ref = 40MHz/(24>>amodeRefSel))
      65                 :            :  */
      66                 :          0 : static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
      67                 :            : {
      68                 :          0 :         u16 bMode, fracMode, aModeRefSel = 0;
      69                 :          0 :         u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
      70                 :          0 :         struct chan_centers centers;
      71                 :          0 :         u32 refDivA = 24;
      72                 :            : 
      73                 :          0 :         ath9k_hw_get_channel_centers(ah, chan, &centers);
      74                 :          0 :         freq = centers.synth_center;
      75                 :            : 
      76                 :          0 :         reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
      77                 :          0 :         reg32 &= 0xc0000000;
      78                 :            : 
      79         [ #  # ]:          0 :         if (freq < 4800) { /* 2 GHz, fractional mode */
      80                 :          0 :                 u32 txctl;
      81                 :          0 :                 int regWrites = 0;
      82                 :            : 
      83                 :          0 :                 bMode = 1;
      84                 :          0 :                 fracMode = 1;
      85                 :          0 :                 aModeRefSel = 0;
      86                 :          0 :                 channelSel = CHANSEL_2G(freq);
      87                 :            : 
      88         [ #  # ]:          0 :                 if (AR_SREV_9287_11_OR_LATER(ah)) {
      89         [ #  # ]:          0 :                         if (freq == 2484) {
      90                 :            :                                 /* Enable channel spreading for channel 14 */
      91                 :          0 :                                 REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
      92                 :            :                                                 1, regWrites);
      93                 :            :                         } else {
      94                 :          0 :                                 REG_WRITE_ARRAY(&ah->iniCckfirNormal,
      95                 :            :                                                 1, regWrites);
      96                 :            :                         }
      97                 :            :                 } else {
      98                 :          0 :                         txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
      99         [ #  # ]:          0 :                         if (freq == 2484) {
     100                 :            :                                 /* Enable channel spreading for channel 14 */
     101                 :          0 :                                 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
     102                 :            :                                           txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
     103                 :            :                         } else {
     104                 :          0 :                                 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
     105                 :            :                                           txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
     106                 :            :                         }
     107                 :            :                 }
     108                 :            :         } else {
     109                 :          0 :                 bMode = 0;
     110                 :          0 :                 fracMode = 0;
     111                 :            : 
     112         [ #  # ]:          0 :                 switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
     113                 :          0 :                 case 0:
     114         [ #  # ]:          0 :                         if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
     115                 :            :                                 aModeRefSel = 0;
     116         [ #  # ]:          0 :                         else if ((freq % 20) == 0)
     117                 :            :                                 aModeRefSel = 3;
     118         [ #  # ]:          0 :                         else if ((freq % 10) == 0)
     119                 :            :                                 aModeRefSel = 2;
     120                 :            :                         if (aModeRefSel)
     121                 :            :                                 break;
     122                 :            :                         /* fall through */
     123                 :            :                 case 1:
     124                 :            :                 default:
     125                 :          0 :                         aModeRefSel = 0;
     126                 :            :                         /*
     127                 :            :                          * Enable 2G (fractional) mode for channels
     128                 :            :                          * which are 5MHz spaced.
     129                 :            :                          */
     130                 :          0 :                         fracMode = 1;
     131                 :          0 :                         refDivA = 1;
     132                 :          0 :                         channelSel = CHANSEL_5G(freq);
     133                 :            : 
     134                 :            :                         /* RefDivA setting */
     135                 :          0 :                         ath9k_hw_analog_shift_rmw(ah, AR_AN_SYNTH9,
     136                 :            :                                       AR_AN_SYNTH9_REFDIVA,
     137                 :            :                                       AR_AN_SYNTH9_REFDIVA_S, refDivA);
     138                 :            : 
     139                 :            :                 }
     140                 :            : 
     141         [ #  # ]:          0 :                 if (!fracMode) {
     142                 :          0 :                         ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
     143                 :          0 :                         channelSel = ndiv & 0x1ff;
     144                 :          0 :                         channelFrac = (ndiv & 0xfffffe00) * 2;
     145                 :          0 :                         channelSel = (channelSel << 17) | channelFrac;
     146                 :            :                 }
     147                 :            :         }
     148                 :            : 
     149                 :          0 :         reg32 = reg32 |
     150                 :          0 :             (bMode << 29) |
     151                 :          0 :             (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
     152                 :            : 
     153                 :          0 :         REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
     154                 :            : 
     155                 :          0 :         ah->curchan = chan;
     156                 :            : 
     157                 :          0 :         return 0;
     158                 :            : }
     159                 :            : 
     160                 :            : /**
     161                 :            :  * ar9002_hw_spur_mitigate - convert baseband spur frequency
     162                 :            :  * @ah: atheros hardware structure
     163                 :            :  * @chan:
     164                 :            :  *
     165                 :            :  * For single-chip solutions. Converts to baseband spur frequency given the
     166                 :            :  * input channel frequency and compute register settings below.
     167                 :            :  */
     168                 :          0 : static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
     169                 :            :                                     struct ath9k_channel *chan)
     170                 :            : {
     171                 :          0 :         int bb_spur = AR_NO_SPUR;
     172                 :          0 :         int freq;
     173                 :          0 :         int bin;
     174                 :          0 :         int bb_spur_off, spur_subchannel_sd;
     175                 :          0 :         int spur_freq_sd;
     176                 :          0 :         int spur_delta_phase;
     177                 :          0 :         int denominator;
     178                 :          0 :         int tmp, newVal;
     179                 :          0 :         int i;
     180                 :          0 :         struct chan_centers centers;
     181                 :            : 
     182                 :          0 :         int cur_bb_spur;
     183                 :          0 :         bool is2GHz = IS_CHAN_2GHZ(chan);
     184                 :            : 
     185                 :          0 :         ath9k_hw_get_channel_centers(ah, chan, &centers);
     186                 :          0 :         freq = centers.synth_center;
     187                 :            : 
     188         [ #  # ]:          0 :         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
     189                 :          0 :                 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
     190                 :            : 
     191         [ #  # ]:          0 :                 if (AR_NO_SPUR == cur_bb_spur)
     192                 :            :                         break;
     193                 :            : 
     194         [ #  # ]:          0 :                 if (is2GHz)
     195                 :          0 :                         cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
     196                 :            :                 else
     197                 :          0 :                         cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
     198                 :            : 
     199                 :          0 :                 cur_bb_spur = cur_bb_spur - freq;
     200                 :            : 
     201         [ #  # ]:          0 :                 if (IS_CHAN_HT40(chan)) {
     202         [ #  # ]:          0 :                         if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
     203                 :            :                             (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
     204                 :            :                                 bb_spur = cur_bb_spur;
     205                 :            :                                 break;
     206                 :            :                         }
     207         [ #  # ]:          0 :                 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
     208                 :            :                            (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
     209                 :            :                         bb_spur = cur_bb_spur;
     210                 :            :                         break;
     211                 :            :                 }
     212                 :            :         }
     213                 :            : 
     214         [ #  # ]:          0 :         if (AR_NO_SPUR == bb_spur) {
     215                 :          0 :                 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
     216                 :            :                             AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
     217                 :          0 :                 return;
     218                 :            :         } else {
     219                 :          0 :                 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
     220                 :            :                             AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
     221                 :            :         }
     222                 :            : 
     223                 :          0 :         bin = bb_spur * 320;
     224                 :            : 
     225                 :          0 :         tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
     226                 :            : 
     227         [ #  # ]:          0 :         ENABLE_REGWRITE_BUFFER(ah);
     228                 :            : 
     229                 :          0 :         newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
     230                 :            :                         AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
     231                 :            :                         AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
     232                 :            :                         AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
     233                 :          0 :         REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
     234                 :            : 
     235                 :          0 :         newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
     236                 :            :                   AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
     237                 :            :                   AR_PHY_SPUR_REG_MASK_RATE_SELECT |
     238                 :            :                   AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
     239                 :            :                   SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
     240                 :          0 :         REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
     241                 :            : 
     242         [ #  # ]:          0 :         if (IS_CHAN_HT40(chan)) {
     243         [ #  # ]:          0 :                 if (bb_spur < 0) {
     244                 :          0 :                         spur_subchannel_sd = 1;
     245                 :          0 :                         bb_spur_off = bb_spur + 10;
     246                 :            :                 } else {
     247                 :          0 :                         spur_subchannel_sd = 0;
     248                 :          0 :                         bb_spur_off = bb_spur - 10;
     249                 :            :                 }
     250                 :            :         } else {
     251                 :            :                 spur_subchannel_sd = 0;
     252                 :            :                 bb_spur_off = bb_spur;
     253                 :            :         }
     254                 :            : 
     255         [ #  # ]:          0 :         if (IS_CHAN_HT40(chan))
     256                 :          0 :                 spur_delta_phase =
     257                 :          0 :                         ((bb_spur * 262144) /
     258                 :            :                          10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
     259                 :            :         else
     260                 :          0 :                 spur_delta_phase =
     261                 :          0 :                         ((bb_spur * 524288) /
     262                 :            :                          10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
     263                 :            : 
     264         [ #  # ]:          0 :         denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
     265                 :          0 :         spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
     266                 :            : 
     267                 :          0 :         newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
     268                 :          0 :                   SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
     269                 :            :                   SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
     270                 :          0 :         REG_WRITE(ah, AR_PHY_TIMING11, newVal);
     271                 :            : 
     272                 :          0 :         newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
     273                 :          0 :         REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
     274                 :            : 
     275                 :          0 :         ar5008_hw_cmn_spur_mitigate(ah, chan, bin);
     276                 :            : 
     277         [ #  # ]:          0 :         REGWRITE_BUFFER_FLUSH(ah);
     278                 :            : }
     279                 :            : 
     280                 :          0 : static void ar9002_olc_init(struct ath_hw *ah)
     281                 :            : {
     282                 :          0 :         u32 i;
     283                 :            : 
     284   [ #  #  #  # ]:          0 :         if (!OLC_FOR_AR9280_20_LATER)
     285                 :          0 :                 return;
     286                 :            : 
     287   [ #  #  #  # ]:          0 :         if (OLC_FOR_AR9287_10_LATER) {
     288                 :          0 :                 REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
     289                 :            :                                 AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
     290                 :          0 :                 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
     291                 :            :                                 AR9287_AN_TXPC0_TXPCMODE,
     292                 :            :                                 AR9287_AN_TXPC0_TXPCMODE_S,
     293                 :            :                                 AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
     294                 :          0 :                 udelay(100);
     295                 :            :         } else {
     296         [ #  # ]:          0 :                 for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
     297                 :          0 :                         ah->originalGain[i] =
     298                 :          0 :                                 MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
     299                 :            :                                                 AR_PHY_TX_GAIN);
     300                 :          0 :                 ah->PDADCdelta = 0;
     301                 :            :         }
     302                 :            : }
     303                 :            : 
     304                 :          0 : static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
     305                 :            :                                          struct ath9k_channel *chan)
     306                 :            : {
     307                 :          0 :         int ref_div = 5;
     308                 :          0 :         int pll_div = 0x2c;
     309                 :          0 :         u32 pll;
     310                 :            : 
     311   [ #  #  #  #  :          0 :         if (chan && IS_CHAN_5GHZ(chan) && !IS_CHAN_A_FAST_CLOCK(ah, chan)) {
                   #  # ]
     312         [ #  # ]:          0 :                 if (AR_SREV_9280_20(ah)) {
     313                 :            :                         ref_div = 10;
     314                 :            :                         pll_div = 0x50;
     315                 :            :                 } else {
     316                 :          0 :                         pll_div = 0x28;
     317                 :            :                 }
     318                 :            :         }
     319                 :            : 
     320                 :          0 :         pll = SM(ref_div, AR_RTC_9160_PLL_REFDIV);
     321                 :          0 :         pll |= SM(pll_div, AR_RTC_9160_PLL_DIV);
     322                 :            : 
     323   [ #  #  #  # ]:          0 :         if (chan && IS_CHAN_HALF_RATE(chan))
     324                 :          0 :                 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
     325   [ #  #  #  # ]:          0 :         else if (chan && IS_CHAN_QUARTER_RATE(chan))
     326                 :          0 :                 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
     327                 :            : 
     328                 :          0 :         return pll;
     329                 :            : }
     330                 :            : 
     331                 :          0 : static void ar9002_hw_do_getnf(struct ath_hw *ah,
     332                 :            :                               int16_t nfarray[NUM_NF_READINGS])
     333                 :            : {
     334                 :          0 :         int16_t nf;
     335                 :            : 
     336                 :          0 :         nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
     337                 :          0 :         nfarray[0] = sign_extend32(nf, 8);
     338                 :            : 
     339                 :          0 :         nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
     340         [ #  # ]:          0 :         if (IS_CHAN_HT40(ah->curchan))
     341                 :          0 :                 nfarray[3] = sign_extend32(nf, 8);
     342                 :            : 
     343         [ #  # ]:          0 :         if (!(ah->rxchainmask & BIT(1)))
     344                 :            :                 return;
     345                 :            : 
     346                 :          0 :         nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
     347                 :          0 :         nfarray[1] = sign_extend32(nf, 8);
     348                 :            : 
     349                 :          0 :         nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
     350         [ #  # ]:          0 :         if (IS_CHAN_HT40(ah->curchan))
     351                 :          0 :                 nfarray[4] = sign_extend32(nf, 8);
     352                 :            : }
     353                 :            : 
     354                 :          0 : static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
     355                 :            : {
     356                 :          0 :         if (AR_SREV_9285(ah)) {
     357                 :          0 :                 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ;
     358                 :          0 :                 ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ;
     359                 :          0 :                 ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ;
     360         [ #  # ]:          0 :         } else if (AR_SREV_9287(ah)) {
     361                 :          0 :                 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
     362                 :          0 :                 ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
     363                 :          0 :                 ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
     364         [ #  # ]:          0 :         } else if (AR_SREV_9271(ah)) {
     365                 :          0 :                 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ;
     366                 :          0 :                 ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ;
     367                 :          0 :                 ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9271_2GHZ;
     368                 :            :         } else {
     369                 :          0 :                 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
     370                 :          0 :                 ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
     371                 :          0 :                 ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
     372                 :          0 :                 ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
     373                 :          0 :                 ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
     374                 :          0 :                 ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
     375                 :            :         }
     376                 :            : }
     377                 :            : 
     378                 :          0 : static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah,
     379                 :            :                                    struct ath_hw_antcomb_conf *antconf)
     380                 :            : {
     381                 :          0 :         u32 regval;
     382                 :            : 
     383                 :          0 :         regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
     384                 :          0 :         antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >>
     385                 :            :                                   AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S;
     386                 :          0 :         antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >>
     387                 :            :                                  AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
     388                 :          0 :         antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
     389                 :            :                                   AR_PHY_9285_FAST_DIV_BIAS_S;
     390                 :          0 :         antconf->lna1_lna2_switch_delta = -1;
     391                 :          0 :         antconf->lna1_lna2_delta = -3;
     392                 :          0 :         antconf->div_group = 0;
     393                 :          0 : }
     394                 :            : 
     395                 :          0 : static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
     396                 :            :                                    struct ath_hw_antcomb_conf *antconf)
     397                 :            : {
     398                 :          0 :         u32 regval;
     399                 :            : 
     400                 :          0 :         regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
     401                 :          0 :         regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
     402                 :            :                     AR_PHY_9285_ANT_DIV_ALT_LNACONF |
     403                 :            :                     AR_PHY_9285_FAST_DIV_BIAS);
     404                 :          0 :         regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S)
     405                 :          0 :                    & AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
     406                 :          0 :         regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S)
     407                 :          0 :                    & AR_PHY_9285_ANT_DIV_ALT_LNACONF);
     408                 :          0 :         regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S)
     409                 :          0 :                    & AR_PHY_9285_FAST_DIV_BIAS);
     410                 :            : 
     411                 :          0 :         REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
     412                 :          0 : }
     413                 :            : 
     414                 :            : #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
     415                 :            : 
     416                 :          0 : static void ar9002_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
     417                 :            : {
     418                 :          0 :         struct ath_btcoex_hw *btcoex = &ah->btcoex_hw;
     419                 :          0 :         u8 antdiv_ctrl1, antdiv_ctrl2;
     420                 :          0 :         u32 regval;
     421                 :            : 
     422         [ #  # ]:          0 :         if (enable) {
     423                 :          0 :                 antdiv_ctrl1 = ATH_BT_COEX_ANTDIV_CONTROL1_ENABLE;
     424                 :          0 :                 antdiv_ctrl2 = ATH_BT_COEX_ANTDIV_CONTROL2_ENABLE;
     425                 :            : 
     426                 :            :                 /*
     427                 :            :                  * Don't disable BT ant to allow BB to control SWCOM.
     428                 :            :                  */
     429                 :          0 :                 btcoex->bt_coex_mode2 &= (~(AR_BT_DISABLE_BT_ANT));
     430                 :          0 :                 REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2);
     431                 :            : 
     432                 :          0 :                 REG_WRITE(ah, AR_PHY_SWITCH_COM, ATH_BT_COEX_ANT_DIV_SWITCH_COM);
     433                 :          0 :                 REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
     434                 :            :         } else {
     435                 :            :                 /*
     436                 :            :                  * Disable antenna diversity, use LNA1 only.
     437                 :            :                  */
     438                 :          0 :                 antdiv_ctrl1 = ATH_BT_COEX_ANTDIV_CONTROL1_FIXED_A;
     439                 :          0 :                 antdiv_ctrl2 = ATH_BT_COEX_ANTDIV_CONTROL2_FIXED_A;
     440                 :            : 
     441                 :            :                 /*
     442                 :            :                  * Disable BT Ant. to allow concurrent BT and WLAN receive.
     443                 :            :                  */
     444                 :          0 :                 btcoex->bt_coex_mode2 |= AR_BT_DISABLE_BT_ANT;
     445                 :          0 :                 REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2);
     446                 :            : 
     447                 :            :                 /*
     448                 :            :                  * Program SWCOM table to make sure RF switch always parks
     449                 :            :                  * at BT side.
     450                 :            :                  */
     451                 :          0 :                 REG_WRITE(ah, AR_PHY_SWITCH_COM, 0);
     452                 :          0 :                 REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
     453                 :            :         }
     454                 :            : 
     455                 :          0 :         regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
     456                 :          0 :         regval &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
     457                 :            :         /*
     458                 :            :          * Clear ant_fast_div_bias [14:9] since for WB195,
     459                 :            :          * the main LNA is always LNA1.
     460                 :            :          */
     461                 :          0 :         regval &= (~(AR_PHY_9285_FAST_DIV_BIAS));
     462                 :          0 :         regval |= SM(antdiv_ctrl1, AR_PHY_9285_ANT_DIV_CTL);
     463                 :          0 :         regval |= SM(antdiv_ctrl2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
     464                 :          0 :         regval |= SM((antdiv_ctrl2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
     465                 :          0 :         regval |= SM((antdiv_ctrl1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);
     466                 :          0 :         regval |= SM((antdiv_ctrl1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
     467                 :          0 :         REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
     468                 :            : 
     469                 :          0 :         regval = REG_READ(ah, AR_PHY_CCK_DETECT);
     470                 :          0 :         regval &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
     471                 :          0 :         regval |= SM((antdiv_ctrl1 >> 3), AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
     472                 :          0 :         REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
     473                 :          0 : }
     474                 :            : 
     475                 :            : #endif
     476                 :            : 
     477                 :          0 : static void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
     478                 :            :                                     struct ath_spec_scan *param)
     479                 :            : {
     480                 :          0 :         u32 repeat_bit;
     481                 :          0 :         u8 count;
     482                 :            : 
     483         [ #  # ]:          0 :         if (!param->enabled) {
     484                 :          0 :                 REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
     485                 :            :                             AR_PHY_SPECTRAL_SCAN_ENABLE);
     486                 :          0 :                 return;
     487                 :            :         }
     488                 :          0 :         REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
     489                 :          0 :         REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
     490                 :            : 
     491         [ #  # ]:          0 :         if (AR_SREV_9280(ah))
     492                 :            :                 repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
     493                 :            :         else
     494                 :          0 :                 repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
     495                 :            : 
     496         [ #  # ]:          0 :         if (param->short_repeat)
     497                 :          0 :                 REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit);
     498                 :            :         else
     499                 :          0 :                 REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit);
     500                 :            : 
     501                 :            :         /* on AR92xx, the highest bit of count will make the the chip send
     502                 :            :          * spectral samples endlessly. Check if this really was intended,
     503                 :            :          * and fix otherwise.
     504                 :            :          */
     505                 :          0 :         count = param->count;
     506         [ #  # ]:          0 :         if (param->endless) {
     507         [ #  # ]:          0 :                 if (AR_SREV_9280(ah))
     508                 :            :                         count = 0x80;
     509                 :            :                 else
     510                 :          0 :                         count = 0;
     511         [ #  # ]:          0 :         } else if (count & 0x80)
     512                 :            :                 count = 0x7f;
     513                 :          0 :         else if (!count)
     514                 :            :                 count = 1;
     515                 :            : 
     516         [ #  # ]:          0 :         if (AR_SREV_9280(ah)) {
     517                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
     518                 :            :                               AR_PHY_SPECTRAL_SCAN_COUNT, count);
     519                 :            :         } else {
     520                 :          0 :                 REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
     521                 :            :                               AR_PHY_SPECTRAL_SCAN_COUNT_KIWI, count);
     522                 :          0 :                 REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
     523                 :            :                             AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT);
     524                 :            :         }
     525                 :            : 
     526                 :          0 :         REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
     527                 :            :                       AR_PHY_SPECTRAL_SCAN_PERIOD, param->period);
     528                 :          0 :         REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
     529                 :            :                       AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, param->fft_period);
     530                 :            : 
     531                 :          0 :         return;
     532                 :            : }
     533                 :            : 
     534                 :          0 : static void ar9002_hw_spectral_scan_trigger(struct ath_hw *ah)
     535                 :            : {
     536                 :          0 :         REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
     537                 :            :         /* Activate spectral scan */
     538                 :          0 :         REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
     539                 :            :                     AR_PHY_SPECTRAL_SCAN_ACTIVE);
     540                 :          0 : }
     541                 :            : 
     542                 :          0 : static void ar9002_hw_spectral_scan_wait(struct ath_hw *ah)
     543                 :            : {
     544                 :          0 :         struct ath_common *common = ath9k_hw_common(ah);
     545                 :            : 
     546                 :            :         /* Poll for spectral scan complete */
     547         [ #  # ]:          0 :         if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
     548                 :            :                            AR_PHY_SPECTRAL_SCAN_ACTIVE,
     549                 :            :                            0, AH_WAIT_TIMEOUT)) {
     550                 :          0 :                 ath_err(common, "spectral scan wait failed\n");
     551                 :          0 :                 return;
     552                 :            :         }
     553                 :            : }
     554                 :            : 
     555                 :          0 : static void ar9002_hw_tx99_start(struct ath_hw *ah, u32 qnum)
     556                 :            : {
     557                 :          0 :         REG_SET_BIT(ah, 0x9864, 0x7f000);
     558                 :          0 :         REG_SET_BIT(ah, 0x9924, 0x7f00fe);
     559                 :          0 :         REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
     560                 :          0 :         REG_WRITE(ah, AR_CR, AR_CR_RXD);
     561                 :          0 :         REG_WRITE(ah, AR_DLCL_IFS(qnum), 0);
     562                 :          0 :         REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 20);
     563                 :          0 :         REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 20);
     564                 :          0 :         REG_WRITE(ah, AR_D_FPCTL, 0x10|qnum);
     565                 :          0 :         REG_WRITE(ah, AR_TIME_OUT, 0x00000400);
     566                 :          0 :         REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff);
     567                 :          0 :         REG_SET_BIT(ah, AR_QMISC(qnum), AR_Q_MISC_DCU_EARLY_TERM_REQ);
     568                 :          0 : }
     569                 :            : 
     570                 :          0 : static void ar9002_hw_tx99_stop(struct ath_hw *ah)
     571                 :            : {
     572                 :          0 :         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
     573                 :          0 : }
     574                 :            : 
     575                 :          0 : void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
     576                 :            : {
     577         [ #  # ]:          0 :         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
     578         [ #  # ]:          0 :         struct ath_hw_ops *ops = ath9k_hw_ops(ah);
     579                 :            : 
     580                 :          0 :         priv_ops->set_rf_regs = NULL;
     581                 :          0 :         priv_ops->rf_set_freq = ar9002_hw_set_channel;
     582                 :          0 :         priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
     583                 :          0 :         priv_ops->olc_init = ar9002_olc_init;
     584                 :          0 :         priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
     585                 :          0 :         priv_ops->do_getnf = ar9002_hw_do_getnf;
     586                 :            : 
     587                 :          0 :         ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
     588                 :          0 :         ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
     589                 :          0 :         ops->spectral_scan_config = ar9002_hw_spectral_scan_config;
     590                 :          0 :         ops->spectral_scan_trigger = ar9002_hw_spectral_scan_trigger;
     591                 :          0 :         ops->spectral_scan_wait = ar9002_hw_spectral_scan_wait;
     592                 :            : 
     593                 :            : #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
     594                 :          0 :         ops->set_bt_ant_diversity = ar9002_hw_set_bt_ant_diversity;
     595                 :            : #endif
     596                 :          0 :         ops->tx99_start = ar9002_hw_tx99_start;
     597                 :          0 :         ops->tx99_stop = ar9002_hw_tx99_stop;
     598                 :            : 
     599         [ #  # ]:          0 :         ar9002_hw_set_nf_limits(ah);
     600                 :          0 : }

Generated by: LCOV version 1.14