LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath9k - ar9003_rtt.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 103 110 93.6 %
Date: 2022-03-28 13:20:08 Functions: 11 11 100.0 %
Branches: 50 60 83.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2010-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 "ar9003_phy.h"
      20                 :            : #include "ar9003_rtt.h"
      21                 :            : 
      22                 :            : #define RTT_RESTORE_TIMEOUT          1000
      23                 :            : #define RTT_ACCESS_TIMEOUT           100
      24                 :            : #define RTT_BAD_VALUE                0x0bad0bad
      25                 :            : 
      26                 :            : /*
      27                 :            :  * RTT (Radio Retention Table) hardware implementation information
      28                 :            :  *
      29                 :            :  * There is an internal table (i.e. the rtt) for each chain (or bank).
      30                 :            :  * Each table contains 6 entries and each entry is corresponding to
      31                 :            :  * a specific calibration parameter as depicted below.
      32                 :            :  *  0~2 - DC offset DAC calibration: loop, low, high (offsetI/Q_...)
      33                 :            :  *  3   - Filter cal (filterfc)
      34                 :            :  *  4   - RX gain settings
      35                 :            :  *  5   - Peak detector offset calibration (agc_caldac)
      36                 :            :  */
      37                 :            : 
      38                 :         12 : void ar9003_hw_rtt_enable(struct ath_hw *ah)
      39                 :            : {
      40                 :          3 :         REG_WRITE(ah, AR_PHY_RTT_CTRL, 1);
      41                 :          3 : }
      42                 :            : 
      43                 :         11 : void ar9003_hw_rtt_disable(struct ath_hw *ah)
      44                 :            : {
      45                 :          2 :         REG_WRITE(ah, AR_PHY_RTT_CTRL, 0);
      46                 :          2 : }
      47                 :            : 
      48                 :         12 : void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask)
      49                 :            : {
      50                 :          3 :         REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
      51                 :            :                       AR_PHY_RTT_CTRL_RESTORE_MASK, rtt_mask);
      52                 :          9 : }
      53                 :            : 
      54                 :          9 : bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
      55                 :            : {
      56         [ +  - ]:          9 :         if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
      57                 :            :                            AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
      58                 :            :                            0, RTT_RESTORE_TIMEOUT))
      59                 :            :                 return false;
      60                 :            : 
      61                 :          9 :         REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
      62                 :            :                       AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE, 1);
      63                 :            : 
      64         [ -  + ]:          9 :         if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
      65                 :            :                            AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
      66                 :            :                            0, RTT_RESTORE_TIMEOUT))
      67                 :          0 :                 return false;
      68                 :            : 
      69                 :            :         return true;
      70                 :            : }
      71                 :            : 
      72                 :        168 : static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
      73                 :            :                                           u32 index, u32 data28)
      74                 :            : {
      75                 :        168 :         u32 val;
      76                 :            : 
      77                 :        168 :         val = SM(data28, AR_PHY_RTT_SW_RTT_TABLE_DATA);
      78         [ +  + ]:        252 :         REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain), val);
      79                 :            : 
      80                 :        168 :         val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
      81                 :            :               SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
      82                 :        168 :               SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
      83         [ +  + ]:        252 :         REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
      84                 :        168 :         udelay(1);
      85                 :            : 
      86                 :        168 :         val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
      87                 :        168 :         REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
      88                 :        168 :         udelay(1);
      89                 :            : 
      90         [ +  + ]:        168 :         if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
      91                 :            :                            AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
      92                 :            :                            RTT_ACCESS_TIMEOUT))
      93                 :            :                 return;
      94                 :            : 
      95                 :        164 :         val &= ~SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE);
      96                 :        164 :         REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
      97                 :        164 :         udelay(1);
      98                 :            : 
      99                 :        164 :         ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
     100                 :            :                       AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
     101                 :            :                       RTT_ACCESS_TIMEOUT);
     102                 :            : }
     103                 :            : 
     104                 :         11 : void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
     105                 :            : {
     106                 :         11 :         int chain, i;
     107                 :            : 
     108         [ +  + ]:         44 :         for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
     109         [ +  + ]:         33 :                 if (!(ah->caps.rx_chainmask & (1 << chain)))
     110                 :         11 :                         continue;
     111         [ +  + ]:        154 :                 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
     112                 :        132 :                         ar9003_hw_rtt_load_hist_entry(ah, chain, i,
     113                 :        132 :                                               ah->caldata->rtt_table[chain][i]);
     114         [ -  + ]:        132 :                         ath_dbg(ath9k_hw_common(ah), CALIBRATE,
     115                 :            :                                 "Load RTT value at idx %d, chain %d: 0x%x\n",
     116                 :            :                                 i, chain, ah->caldata->rtt_table[chain][i]);
     117                 :            :                 }
     118                 :            :         }
     119                 :         11 : }
     120                 :            : 
     121                 :         24 : static void ar9003_hw_patch_rtt(struct ath_hw *ah, int index, int chain)
     122                 :            : {
     123                 :         24 :         int agc, caldac;
     124                 :            : 
     125         [ +  - ]:         24 :         if (!test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags))
     126                 :            :                 return;
     127                 :            : 
     128   [ +  +  +  - ]:         24 :         if ((index != 5) || (chain >= 2))
     129                 :            :                 return;
     130                 :            : 
     131                 :          4 :         agc = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
     132                 :            :                              AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE);
     133         [ +  + ]:          4 :         if (!agc)
     134                 :            :                 return;
     135                 :            : 
     136                 :          1 :         caldac = ah->caldata->caldac[chain];
     137                 :          1 :         ah->caldata->rtt_table[chain][index] &= 0xFFFF05FF;
     138                 :          1 :         caldac = (caldac & 0x20) | ((caldac & 0x1F) << 7);
     139                 :          1 :         ah->caldata->rtt_table[chain][index] |= (caldac << 4);
     140                 :            : }
     141                 :            : 
     142                 :         24 : static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
     143                 :            : {
     144                 :         24 :         u32 val;
     145                 :            : 
     146                 :         24 :         val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
     147                 :            :               SM(0, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
     148                 :         24 :               SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
     149                 :            : 
     150         [ +  + ]:         36 :         REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
     151                 :         24 :         udelay(1);
     152                 :            : 
     153                 :         24 :         val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
     154                 :         24 :         REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
     155                 :         24 :         udelay(1);
     156                 :            : 
     157         [ +  - ]:         24 :         if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
     158                 :            :                            AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
     159                 :            :                            RTT_ACCESS_TIMEOUT))
     160                 :            :                 return RTT_BAD_VALUE;
     161                 :            : 
     162         [ +  + ]:         36 :         val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)),
     163                 :            :                  AR_PHY_RTT_SW_RTT_TABLE_DATA);
     164                 :            : 
     165                 :            : 
     166                 :         24 :         return val;
     167                 :            : }
     168                 :            : 
     169                 :          2 : void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
     170                 :            : {
     171                 :          2 :         int chain, i;
     172                 :            : 
     173         [ +  + ]:          8 :         for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
     174         [ +  + ]:          6 :                 if (!(ah->caps.rx_chainmask & (1 << chain)))
     175                 :          2 :                         continue;
     176         [ +  + ]:         28 :                 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
     177                 :         48 :                         ah->caldata->rtt_table[chain][i] =
     178                 :         24 :                                 ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
     179                 :            : 
     180                 :         24 :                         ar9003_hw_patch_rtt(ah, i, chain);
     181                 :            : 
     182         [ -  + ]:         24 :                         ath_dbg(ath9k_hw_common(ah), CALIBRATE,
     183                 :            :                                 "RTT value at idx %d, chain %d is: 0x%x\n",
     184                 :            :                                 i, chain, ah->caldata->rtt_table[chain][i]);
     185                 :            :                 }
     186                 :            :         }
     187                 :            : 
     188                 :          2 :         set_bit(RTT_DONE, &ah->caldata->cal_flags);
     189                 :          2 : }
     190                 :            : 
     191                 :          3 : void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
     192                 :            : {
     193                 :          3 :         int chain, i;
     194                 :            : 
     195         [ +  + ]:         12 :         for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
     196         [ +  + ]:          9 :                 if (!(ah->caps.rx_chainmask & (1 << chain)))
     197                 :          3 :                         continue;
     198         [ +  + ]:         42 :                 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
     199                 :         36 :                         ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
     200                 :            :         }
     201                 :            : 
     202         [ +  + ]:          3 :         if (ah->caldata)
     203                 :          2 :                 clear_bit(RTT_DONE, &ah->caldata->cal_flags);
     204                 :          3 : }
     205                 :            : 
     206                 :         12 : bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
     207                 :            : {
     208                 :         12 :         bool restore;
     209                 :            : 
     210         [ +  + ]:         12 :         if (!ah->caldata)
     211                 :            :                 return false;
     212                 :            : 
     213         [ +  + ]:         11 :         if (test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags)) {
     214         [ +  - ]:          9 :                 if (IS_CHAN_2GHZ(chan)){
     215                 :          9 :                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0),
     216                 :            :                                       AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
     217                 :            :                                       ah->caldata->caldac[0]);
     218                 :          9 :                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1),
     219                 :            :                                       AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
     220                 :            :                                       ah->caldata->caldac[1]);
     221                 :            :                 } else {
     222                 :          0 :                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0),
     223                 :            :                                       AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
     224                 :            :                                       ah->caldata->caldac[0]);
     225                 :          0 :                         REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1),
     226                 :            :                                       AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
     227                 :            :                                       ah->caldata->caldac[1]);
     228                 :            :                 }
     229                 :          9 :                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1),
     230                 :            :                               AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
     231                 :          9 :                 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0),
     232                 :            :                               AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
     233                 :            :         }
     234                 :            : 
     235         [ +  + ]:         11 :         if (!test_bit(RTT_DONE, &ah->caldata->cal_flags))
     236                 :            :                 return false;
     237                 :            : 
     238                 :          9 :         ar9003_hw_rtt_enable(ah);
     239                 :            : 
     240         [ +  - ]:          9 :         if (test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags))
     241                 :          9 :                 ar9003_hw_rtt_set_mask(ah, 0x30);
     242                 :            :         else
     243                 :          0 :                 ar9003_hw_rtt_set_mask(ah, 0x10);
     244                 :            : 
     245         [ -  + ]:          9 :         if (!ath9k_hw_rfbus_req(ah)) {
     246                 :          0 :                 ath_err(ath9k_hw_common(ah), "Could not stop baseband\n");
     247                 :          0 :                 restore = false;
     248                 :          0 :                 goto fail;
     249                 :            :         }
     250                 :            : 
     251                 :          9 :         ar9003_hw_rtt_load_hist(ah);
     252                 :          9 :         restore = ar9003_hw_rtt_force_restore(ah);
     253                 :            : 
     254                 :          9 : fail:
     255                 :          9 :         ath9k_hw_rfbus_done(ah);
     256                 :          9 :         ar9003_hw_rtt_disable(ah);
     257                 :          9 :         return restore;
     258                 :            : }

Generated by: LCOV version 1.14