LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath9k - mac.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 394 526 74.9 %
Date: 2022-03-28 13:20:08 Functions: 20 27 74.1 %
Branches: 213 397 53.7 %

           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 <linux/export.h>
      20                 :            : 
      21                 :            : static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
      22                 :            :                                         struct ath9k_tx_queue_info *qi)
      23                 :            : {
      24                 :            :         ath_dbg(ath9k_hw_common(ah), INTERRUPT,
      25                 :            :                 "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
      26                 :            :                 ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
      27                 :            :                 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
      28                 :            :                 ah->txurn_interrupt_mask);
      29                 :            : 
      30                 :            :         ENABLE_REGWRITE_BUFFER(ah);
      31                 :            : 
      32                 :            :         REG_WRITE(ah, AR_IMR_S0,
      33                 :            :                   SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
      34                 :            :                   | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
      35                 :            :         REG_WRITE(ah, AR_IMR_S1,
      36                 :            :                   SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
      37                 :            :                   | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
      38                 :            : 
      39                 :            :         ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
      40                 :            :         ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
      41                 :            :         REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
      42                 :            : 
      43                 :            :         REGWRITE_BUFFER_FLUSH(ah);
      44                 :            : }
      45                 :            : 
      46                 :          0 : u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
      47                 :            : {
      48                 :          0 :         return REG_READ(ah, AR_QTXDP(q));
      49                 :            : }
      50                 :            : EXPORT_SYMBOL(ath9k_hw_gettxbuf);
      51                 :            : 
      52                 :          0 : void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
      53                 :            : {
      54                 :          0 :         REG_WRITE(ah, AR_QTXDP(q), txdp);
      55                 :          0 : }
      56                 :            : EXPORT_SYMBOL(ath9k_hw_puttxbuf);
      57                 :            : 
      58                 :          0 : void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
      59                 :            : {
      60         [ #  # ]:          0 :         ath_dbg(ath9k_hw_common(ah), QUEUE, "Enable TXE on queue: %u\n", q);
      61                 :          0 :         REG_WRITE(ah, AR_Q_TXE, 1 << q);
      62                 :          0 : }
      63                 :            : EXPORT_SYMBOL(ath9k_hw_txstart);
      64                 :            : 
      65                 :       5854 : u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
      66                 :            : {
      67                 :       5854 :         u32 npend;
      68                 :            : 
      69                 :       5854 :         npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
      70         [ +  + ]:       5854 :         if (npend == 0) {
      71                 :            : 
      72         [ +  + ]:       1339 :                 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
      73                 :        799 :                         npend = 1;
      74                 :            :         }
      75                 :            : 
      76                 :       5854 :         return npend;
      77                 :            : }
      78                 :            : EXPORT_SYMBOL(ath9k_hw_numtxpending);
      79                 :            : 
      80                 :            : /**
      81                 :            :  * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
      82                 :            :  *
      83                 :            :  * @ah: atheros hardware struct
      84                 :            :  * @bIncTrigLevel: whether or not the frame trigger level should be updated
      85                 :            :  *
      86                 :            :  * The frame trigger level specifies the minimum number of bytes,
      87                 :            :  * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
      88                 :            :  * before the PCU will initiate sending the frame on the air. This can
      89                 :            :  * mean we initiate transmit before a full frame is on the PCU TX FIFO.
      90                 :            :  * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
      91                 :            :  * first)
      92                 :            :  *
      93                 :            :  * Caution must be taken to ensure to set the frame trigger level based
      94                 :            :  * on the DMA request size. For example if the DMA request size is set to
      95                 :            :  * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
      96                 :            :  * there need to be enough space in the tx FIFO for the requested transfer
      97                 :            :  * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
      98                 :            :  * the threshold to a value beyond 6, then the transmit will hang.
      99                 :            :  *
     100                 :            :  * Current dual   stream devices have a PCU TX FIFO size of 8 KB.
     101                 :            :  * Current single stream devices have a PCU TX FIFO size of 4 KB, however,
     102                 :            :  * there is a hardware issue which forces us to use 2 KB instead so the
     103                 :            :  * frame trigger level must not exceed 2 KB for these chipsets.
     104                 :            :  */
     105                 :          0 : bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
     106                 :            : {
     107                 :          0 :         u32 txcfg, curLevel, newLevel;
     108                 :            : 
     109         [ #  # ]:          0 :         if (ah->tx_trig_level >= ah->config.max_txtrig_level)
     110                 :            :                 return false;
     111                 :            : 
     112                 :          0 :         ath9k_hw_disable_interrupts(ah);
     113                 :            : 
     114                 :          0 :         txcfg = REG_READ(ah, AR_TXCFG);
     115                 :          0 :         curLevel = MS(txcfg, AR_FTRIG);
     116                 :          0 :         newLevel = curLevel;
     117         [ #  # ]:          0 :         if (bIncTrigLevel) {
     118         [ #  # ]:          0 :                 if (curLevel < ah->config.max_txtrig_level)
     119                 :          0 :                         newLevel++;
     120         [ #  # ]:          0 :         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
     121                 :          0 :                 newLevel--;
     122         [ #  # ]:          0 :         if (newLevel != curLevel)
     123                 :          0 :                 REG_WRITE(ah, AR_TXCFG,
     124                 :            :                           (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
     125                 :            : 
     126                 :          0 :         ath9k_hw_enable_interrupts(ah);
     127                 :            : 
     128                 :          0 :         ah->tx_trig_level = newLevel;
     129                 :            : 
     130                 :          0 :         return newLevel != curLevel;
     131                 :            : }
     132                 :            : EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
     133                 :            : 
     134                 :         54 : void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
     135                 :            : {
     136                 :         54 :         int maxdelay = 1000;
     137                 :         54 :         int i, q;
     138                 :            : 
     139         [ +  - ]:         54 :         if (ah->curchan) {
     140         [ +  - ]:         54 :                 if (IS_CHAN_HALF_RATE(ah->curchan))
     141                 :            :                         maxdelay *= 2;
     142         [ -  + ]:         54 :                 else if (IS_CHAN_QUARTER_RATE(ah->curchan))
     143                 :          0 :                         maxdelay *= 4;
     144                 :            :         }
     145                 :            : 
     146                 :         54 :         REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
     147                 :            : 
     148                 :         54 :         REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
     149                 :         54 :         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
     150                 :         54 :         REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
     151                 :            : 
     152         [ +  + ]:        648 :         for (q = 0; q < AR_NUM_QCU; q++) {
     153         [ +  - ]:       5853 :                 for (i = 0; i < maxdelay; i++) {
     154         [ +  + ]:       5853 :                         if (i)
     155                 :       5313 :                                 udelay(5);
     156                 :            : 
     157         [ +  + ]:       5853 :                         if (!ath9k_hw_numtxpending(ah, q))
     158                 :            :                                 break;
     159                 :            :                 }
     160                 :            :         }
     161                 :            : 
     162                 :         54 :         REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
     163                 :         54 :         REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
     164                 :         54 :         REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
     165                 :            : 
     166                 :         54 :         REG_WRITE(ah, AR_Q_TXD, 0);
     167                 :         54 : }
     168                 :            : EXPORT_SYMBOL(ath9k_hw_abort_tx_dma);
     169                 :            : 
     170                 :          0 : bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q)
     171                 :            : {
     172                 :            : #define ATH9K_TX_STOP_DMA_TIMEOUT       1000    /* usec */
     173                 :            : #define ATH9K_TIME_QUANTUM              100     /* usec */
     174                 :          0 :         int wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
     175                 :          0 :         int wait;
     176                 :            : 
     177                 :          0 :         REG_WRITE(ah, AR_Q_TXD, 1 << q);
     178                 :            : 
     179         [ #  # ]:          0 :         for (wait = wait_time; wait != 0; wait--) {
     180         [ #  # ]:          0 :                 if (wait != wait_time)
     181                 :          0 :                         udelay(ATH9K_TIME_QUANTUM);
     182                 :            : 
     183         [ #  # ]:          0 :                 if (ath9k_hw_numtxpending(ah, q) == 0)
     184                 :            :                         break;
     185                 :            :         }
     186                 :            : 
     187                 :          0 :         REG_WRITE(ah, AR_Q_TXD, 0);
     188                 :            : 
     189                 :          0 :         return wait != 0;
     190                 :            : 
     191                 :            : #undef ATH9K_TX_STOP_DMA_TIMEOUT
     192                 :            : #undef ATH9K_TIME_QUANTUM
     193                 :            : }
     194                 :            : EXPORT_SYMBOL(ath9k_hw_stop_dma_queue);
     195                 :            : 
     196                 :         72 : bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
     197                 :            :                             const struct ath9k_tx_queue_info *qinfo)
     198                 :            : {
     199                 :         72 :         u32 cw;
     200         [ -  + ]:         72 :         struct ath_common *common = ath9k_hw_common(ah);
     201                 :         72 :         struct ath9k_tx_queue_info *qi;
     202                 :            : 
     203                 :         72 :         qi = &ah->txq[q];
     204         [ -  + ]:         72 :         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
     205         [ #  # ]:          0 :                 ath_dbg(common, QUEUE,
     206                 :            :                         "Set TXQ properties, inactive queue: %u\n", q);
     207                 :          0 :                 return false;
     208                 :            :         }
     209                 :            : 
     210         [ -  + ]:         72 :         ath_dbg(common, QUEUE, "Set queue properties for: %u\n", q);
     211                 :            : 
     212                 :         72 :         qi->tqi_ver = qinfo->tqi_ver;
     213                 :         72 :         qi->tqi_subtype = qinfo->tqi_subtype;
     214                 :         72 :         qi->tqi_qflags = qinfo->tqi_qflags;
     215                 :         72 :         qi->tqi_priority = qinfo->tqi_priority;
     216         [ +  + ]:         72 :         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
     217                 :         36 :                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
     218                 :            :         else
     219                 :         36 :                 qi->tqi_aifs = INIT_AIFS;
     220         [ +  + ]:         72 :         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
     221                 :         30 :                 cw = min(qinfo->tqi_cwmin, 1024U);
     222                 :         30 :                 qi->tqi_cwmin = 1;
     223         [ +  + ]:        102 :                 while (qi->tqi_cwmin < cw)
     224                 :         72 :                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
     225                 :            :         } else
     226                 :         42 :                 qi->tqi_cwmin = qinfo->tqi_cwmin;
     227         [ +  + ]:         72 :         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
     228                 :         36 :                 cw = min(qinfo->tqi_cwmax, 1024U);
     229                 :         36 :                 qi->tqi_cwmax = 1;
     230         [ +  + ]:        306 :                 while (qi->tqi_cwmax < cw)
     231                 :        270 :                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
     232                 :            :         } else
     233                 :         36 :                 qi->tqi_cwmax = INIT_CWMAX;
     234                 :            : 
     235         [ +  + ]:         72 :         if (qinfo->tqi_shretry != 0)
     236                 :         30 :                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
     237                 :            :         else
     238                 :         42 :                 qi->tqi_shretry = INIT_SH_RETRY;
     239         [ +  + ]:         72 :         if (qinfo->tqi_lgretry != 0)
     240                 :         30 :                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
     241                 :            :         else
     242                 :         42 :                 qi->tqi_lgretry = INIT_LG_RETRY;
     243                 :         72 :         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
     244                 :         72 :         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
     245                 :         72 :         qi->tqi_burstTime = qinfo->tqi_burstTime;
     246                 :         72 :         qi->tqi_readyTime = qinfo->tqi_readyTime;
     247                 :            : 
     248         [ -  + ]:         72 :         switch (qinfo->tqi_subtype) {
     249                 :          0 :         case ATH9K_WME_UPSD:
     250         [ #  # ]:          0 :                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
     251                 :          0 :                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
     252                 :            :                 break;
     253                 :            :         default:
     254                 :            :                 break;
     255                 :            :         }
     256                 :            : 
     257                 :            :         return true;
     258                 :            : }
     259                 :            : EXPORT_SYMBOL(ath9k_hw_set_txq_props);
     260                 :            : 
     261                 :         36 : bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
     262                 :            :                             struct ath9k_tx_queue_info *qinfo)
     263                 :            : {
     264         [ -  + ]:         36 :         struct ath_common *common = ath9k_hw_common(ah);
     265                 :         36 :         struct ath9k_tx_queue_info *qi;
     266                 :            : 
     267                 :         36 :         qi = &ah->txq[q];
     268         [ -  + ]:         36 :         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
     269         [ #  # ]:          0 :                 ath_dbg(common, QUEUE,
     270                 :            :                         "Get TXQ properties, inactive queue: %u\n", q);
     271                 :          0 :                 return false;
     272                 :            :         }
     273                 :            : 
     274                 :         36 :         qinfo->tqi_qflags = qi->tqi_qflags;
     275                 :         36 :         qinfo->tqi_ver = qi->tqi_ver;
     276                 :         36 :         qinfo->tqi_subtype = qi->tqi_subtype;
     277                 :         36 :         qinfo->tqi_qflags = qi->tqi_qflags;
     278                 :         36 :         qinfo->tqi_priority = qi->tqi_priority;
     279                 :         36 :         qinfo->tqi_aifs = qi->tqi_aifs;
     280                 :         36 :         qinfo->tqi_cwmin = qi->tqi_cwmin;
     281                 :         36 :         qinfo->tqi_cwmax = qi->tqi_cwmax;
     282                 :         36 :         qinfo->tqi_shretry = qi->tqi_shretry;
     283                 :         36 :         qinfo->tqi_lgretry = qi->tqi_lgretry;
     284                 :         36 :         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
     285                 :         36 :         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
     286                 :         36 :         qinfo->tqi_burstTime = qi->tqi_burstTime;
     287                 :         36 :         qinfo->tqi_readyTime = qi->tqi_readyTime;
     288                 :            : 
     289                 :         36 :         return true;
     290                 :            : }
     291                 :            : EXPORT_SYMBOL(ath9k_hw_get_txq_props);
     292                 :            : 
     293                 :         42 : int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
     294                 :            :                           const struct ath9k_tx_queue_info *qinfo)
     295                 :            : {
     296   [ +  -  +  +  :         42 :         struct ath_common *common = ath9k_hw_common(ah);
                   -  + ]
     297                 :         42 :         struct ath9k_tx_queue_info *qi;
     298                 :         42 :         int q;
     299                 :            : 
     300   [ +  -  +  +  :         42 :         switch (type) {
                   -  + ]
     301                 :            :         case ATH9K_TX_QUEUE_BEACON:
     302                 :            :                 q = ATH9K_NUM_TX_QUEUES - 1;
     303                 :            :                 break;
     304                 :          6 :         case ATH9K_TX_QUEUE_CAB:
     305                 :          6 :                 q = ATH9K_NUM_TX_QUEUES - 2;
     306                 :          6 :                 break;
     307                 :          0 :         case ATH9K_TX_QUEUE_PSPOLL:
     308                 :          0 :                 q = 1;
     309                 :          0 :                 break;
     310                 :          6 :         case ATH9K_TX_QUEUE_UAPSD:
     311                 :          6 :                 q = ATH9K_NUM_TX_QUEUES - 3;
     312                 :          6 :                 break;
     313                 :         24 :         case ATH9K_TX_QUEUE_DATA:
     314                 :         24 :                 q = qinfo->tqi_subtype;
     315                 :         24 :                 break;
     316                 :          0 :         default:
     317                 :          0 :                 ath_err(common, "Invalid TX queue type: %u\n", type);
     318                 :          0 :                 return -1;
     319                 :            :         }
     320                 :            : 
     321         [ -  + ]:         42 :         ath_dbg(common, QUEUE, "Setup TX queue: %u\n", q);
     322                 :            : 
     323                 :         42 :         qi = &ah->txq[q];
     324         [ -  + ]:         42 :         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
     325                 :          0 :                 ath_err(common, "TX queue: %u already active\n", q);
     326                 :          0 :                 return -1;
     327                 :            :         }
     328                 :         42 :         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
     329                 :         42 :         qi->tqi_type = type;
     330                 :         42 :         qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
     331                 :         42 :         (void) ath9k_hw_set_txq_props(ah, q, qinfo);
     332                 :            : 
     333                 :         42 :         return q;
     334                 :            : }
     335                 :            : EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
     336                 :            : 
     337                 :        450 : static void ath9k_hw_clear_queue_interrupts(struct ath_hw *ah, u32 q)
     338                 :            : {
     339                 :        450 :         ah->txok_interrupt_mask &= ~(1 << q);
     340                 :        450 :         ah->txerr_interrupt_mask &= ~(1 << q);
     341                 :        450 :         ah->txdesc_interrupt_mask &= ~(1 << q);
     342                 :        450 :         ah->txeol_interrupt_mask &= ~(1 << q);
     343                 :        450 :         ah->txurn_interrupt_mask &= ~(1 << q);
     344                 :            : }
     345                 :            : 
     346                 :          0 : bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
     347                 :            : {
     348         [ #  # ]:          0 :         struct ath_common *common = ath9k_hw_common(ah);
     349                 :          0 :         struct ath9k_tx_queue_info *qi;
     350                 :            : 
     351                 :          0 :         qi = &ah->txq[q];
     352         [ #  # ]:          0 :         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
     353         [ #  # ]:          0 :                 ath_dbg(common, QUEUE, "Release TXQ, inactive queue: %u\n", q);
     354                 :          0 :                 return false;
     355                 :            :         }
     356                 :            : 
     357         [ #  # ]:          0 :         ath_dbg(common, QUEUE, "Release TX queue: %u\n", q);
     358                 :            : 
     359                 :          0 :         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
     360                 :          0 :         ath9k_hw_clear_queue_interrupts(ah, q);
     361                 :          0 :         ath9k_hw_set_txq_interrupts(ah, qi);
     362                 :            : 
     363                 :          0 :         return true;
     364                 :            : }
     365                 :            : EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
     366                 :            : 
     367                 :        630 : bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
     368                 :            : {
     369         [ +  + ]:        630 :         struct ath_common *common = ath9k_hw_common(ah);
     370                 :        630 :         struct ath9k_tx_queue_info *qi;
     371                 :        630 :         u32 cwMin, chanCwMin, value;
     372                 :            : 
     373                 :        630 :         qi = &ah->txq[q];
     374         [ +  + ]:        630 :         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
     375         [ -  + ]:        180 :                 ath_dbg(common, QUEUE, "Reset TXQ, inactive queue: %u\n", q);
     376                 :        180 :                 return true;
     377                 :            :         }
     378                 :            : 
     379         [ -  + ]:        450 :         ath_dbg(common, QUEUE, "Reset TX queue: %u\n", q);
     380                 :            : 
     381         [ +  + ]:        450 :         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
     382                 :            :                 chanCwMin = INIT_CWMIN;
     383                 :            : 
     384         [ +  + ]:        680 :                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
     385                 :            :         } else
     386                 :            :                 cwMin = qi->tqi_cwmin;
     387                 :            : 
     388         [ -  + ]:        450 :         ENABLE_REGWRITE_BUFFER(ah);
     389                 :            : 
     390                 :        450 :         REG_WRITE(ah, AR_DLCL_IFS(q),
     391                 :            :                   SM(cwMin, AR_D_LCL_IFS_CWMIN) |
     392                 :            :                   SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
     393                 :            :                   SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
     394                 :            : 
     395                 :        450 :         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
     396                 :            :                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
     397                 :            :                   SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
     398                 :            :                   SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
     399                 :            : 
     400                 :        450 :         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
     401                 :            : 
     402   [ -  +  -  - ]:        450 :         if (AR_SREV_9340(ah) && !AR_SREV_9340_13_OR_LATER(ah))
     403                 :          0 :                 REG_WRITE(ah, AR_DMISC(q),
     404                 :            :                           AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
     405                 :            :         else
     406                 :        450 :                 REG_WRITE(ah, AR_DMISC(q),
     407                 :            :                           AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
     408                 :            : 
     409         [ -  + ]:        450 :         if (qi->tqi_cbrPeriod) {
     410                 :          0 :                 REG_WRITE(ah, AR_QCBRCFG(q),
     411                 :            :                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
     412                 :            :                           SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
     413         [ #  # ]:          0 :                 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
     414                 :            :                             (qi->tqi_cbrOverflowLimit ?
     415                 :            :                              AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
     416                 :            :         }
     417   [ -  +  -  - ]:        450 :         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
     418                 :          0 :                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
     419                 :            :                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
     420                 :            :                           AR_Q_RDYTIMECFG_EN);
     421                 :            :         }
     422                 :            : 
     423         [ +  - ]:        900 :         REG_WRITE(ah, AR_DCHNTIME(q),
     424                 :            :                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
     425                 :            :                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
     426                 :            : 
     427         [ -  + ]:        450 :         if (qi->tqi_burstTime
     428         [ #  # ]:          0 :             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE))
     429                 :          0 :                 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY);
     430                 :            : 
     431         [ -  + ]:        450 :         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE)
     432                 :          0 :                 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
     433                 :            : 
     434         [ -  + ]:        450 :         REGWRITE_BUFFER_FLUSH(ah);
     435                 :            : 
     436         [ -  + ]:        450 :         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
     437                 :          0 :                 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN);
     438                 :            : 
     439   [ +  +  -  +  :        450 :         switch (qi->tqi_type) {
                      + ]
     440                 :         60 :         case ATH9K_TX_QUEUE_BEACON:
     441         [ -  + ]:         60 :                 ENABLE_REGWRITE_BUFFER(ah);
     442                 :            : 
     443                 :         60 :                 REG_SET_BIT(ah, AR_QMISC(q),
     444                 :            :                             AR_Q_MISC_FSP_DBA_GATED
     445                 :            :                             | AR_Q_MISC_BEACON_USE
     446                 :            :                             | AR_Q_MISC_CBR_INCR_DIS1);
     447                 :            : 
     448                 :         60 :                 REG_SET_BIT(ah, AR_DMISC(q),
     449                 :            :                             (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
     450                 :            :                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
     451                 :            :                             | AR_D_MISC_BEACON_USE
     452                 :            :                             | AR_D_MISC_POST_FR_BKOFF_DIS);
     453                 :            : 
     454         [ -  + ]:         60 :                 REGWRITE_BUFFER_FLUSH(ah);
     455                 :            : 
     456                 :            :                 /*
     457                 :            :                  * cwmin and cwmax should be 0 for beacon queue
     458                 :            :                  * but not for IBSS as we would create an imbalance
     459                 :            :                  * on beaconing fairness for participating nodes.
     460                 :            :                  */
     461         [ +  + ]:         60 :                 if (AR_SREV_9300_20_OR_LATER(ah) &&
     462         [ +  - ]:         40 :                     ah->opmode != NL80211_IFTYPE_ADHOC) {
     463                 :         40 :                         REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
     464                 :            :                                   | SM(0, AR_D_LCL_IFS_CWMAX)
     465                 :            :                                   | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
     466                 :            :                 }
     467                 :            :                 break;
     468                 :         66 :         case ATH9K_TX_QUEUE_CAB:
     469         [ -  + ]:         66 :                 ENABLE_REGWRITE_BUFFER(ah);
     470                 :            : 
     471                 :         66 :                 REG_SET_BIT(ah, AR_QMISC(q),
     472                 :            :                             AR_Q_MISC_FSP_DBA_GATED
     473                 :            :                             | AR_Q_MISC_CBR_INCR_DIS1
     474                 :            :                             | AR_Q_MISC_CBR_INCR_DIS0);
     475                 :         66 :                 value = (qi->tqi_readyTime -
     476                 :         66 :                          (ah->config.sw_beacon_response_time -
     477                 :         66 :                           ah->config.dma_beacon_response_time)) * 1024;
     478                 :         66 :                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
     479                 :            :                           value | AR_Q_RDYTIMECFG_EN);
     480                 :         66 :                 REG_SET_BIT(ah, AR_DMISC(q),
     481                 :            :                             (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
     482                 :            :                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
     483                 :            : 
     484         [ -  + ]:         66 :                 REGWRITE_BUFFER_FLUSH(ah);
     485                 :            : 
     486                 :            :                 break;
     487                 :          0 :         case ATH9K_TX_QUEUE_PSPOLL:
     488                 :          0 :                 REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1);
     489                 :          0 :                 break;
     490                 :         60 :         case ATH9K_TX_QUEUE_UAPSD:
     491                 :         60 :                 REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
     492                 :         60 :                 break;
     493                 :            :         default:
     494                 :            :                 break;
     495                 :            :         }
     496                 :            : 
     497         [ -  + ]:        450 :         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
     498                 :          0 :                 REG_SET_BIT(ah, AR_DMISC(q),
     499                 :            :                             SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
     500                 :            :                                AR_D_MISC_ARB_LOCKOUT_CNTRL) |
     501                 :            :                             AR_D_MISC_POST_FR_BKOFF_DIS);
     502                 :            :         }
     503                 :            : 
     504         [ +  + ]:        450 :         if (AR_SREV_9300_20_OR_LATER(ah))
     505                 :        300 :                 REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
     506                 :            : 
     507                 :        450 :         ath9k_hw_clear_queue_interrupts(ah, q);
     508         [ +  + ]:        450 :         if (qi->tqi_qflags & TXQ_FLAG_TXINT_ENABLE) {
     509                 :        300 :                 ah->txok_interrupt_mask |= 1 << q;
     510                 :        300 :                 ah->txerr_interrupt_mask |= 1 << q;
     511                 :            :         }
     512         [ +  + ]:        450 :         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
     513                 :        130 :                 ah->txdesc_interrupt_mask |= 1 << q;
     514         [ +  + ]:        450 :         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
     515                 :        110 :                 ah->txeol_interrupt_mask |= 1 << q;
     516         [ -  + ]:        450 :         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
     517                 :          0 :                 ah->txurn_interrupt_mask |= 1 << q;
     518                 :        450 :         ath9k_hw_set_txq_interrupts(ah, qi);
     519                 :            : 
     520                 :        450 :         return true;
     521                 :            : }
     522                 :            : EXPORT_SYMBOL(ath9k_hw_resettxqueue);
     523                 :            : 
     524                 :        260 : int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
     525                 :            :                         struct ath_rx_status *rs)
     526                 :            : {
     527                 :        260 :         struct ar5416_desc ads;
     528                 :        260 :         struct ar5416_desc *adsp = AR5416DESC(ds);
     529                 :        260 :         u32 phyerr;
     530                 :            : 
     531         [ +  + ]:        260 :         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
     532                 :            :                 return -EINPROGRESS;
     533                 :            : 
     534                 :        188 :         ads.u.rx = adsp->u.rx;
     535                 :            : 
     536                 :        188 :         rs->rs_status = 0;
     537                 :        188 :         rs->rs_flags = 0;
     538                 :        188 :         rs->enc_flags = 0;
     539                 :        188 :         rs->bw = RATE_INFO_BW_20;
     540                 :            : 
     541                 :        188 :         rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
     542                 :        188 :         rs->rs_tstamp = ads.AR_RcvTimestamp;
     543                 :            : 
     544         [ +  + ]:        188 :         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
     545                 :        104 :                 rs->rs_rssi = ATH9K_RSSI_BAD;
     546                 :        104 :                 rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
     547                 :        104 :                 rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
     548                 :        104 :                 rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
     549                 :        104 :                 rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
     550                 :        104 :                 rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
     551                 :        104 :                 rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
     552                 :            :         } else {
     553                 :         84 :                 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
     554                 :         84 :                 rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
     555                 :            :                                                 AR_RxRSSIAnt00);
     556                 :         84 :                 rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
     557                 :            :                                                 AR_RxRSSIAnt01);
     558                 :         84 :                 rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
     559                 :            :                                                 AR_RxRSSIAnt02);
     560                 :         84 :                 rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
     561                 :            :                                                 AR_RxRSSIAnt10);
     562                 :         84 :                 rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
     563                 :            :                                                 AR_RxRSSIAnt11);
     564                 :         84 :                 rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
     565                 :            :                                                 AR_RxRSSIAnt12);
     566                 :            :         }
     567         [ +  + ]:        188 :         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
     568                 :         36 :                 rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
     569                 :            :         else
     570                 :        152 :                 rs->rs_keyix = ATH9K_RXKEYIX_INVALID;
     571                 :            : 
     572                 :        188 :         rs->rs_rate = MS(ads.ds_rxstatus0, AR_RxRate);
     573                 :        188 :         rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
     574                 :            : 
     575                 :        188 :         rs->rs_firstaggr = (ads.ds_rxstatus8 & AR_RxFirstAggr) ? 1 : 0;
     576                 :        188 :         rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
     577                 :        188 :         rs->rs_moreaggr = (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
     578                 :        188 :         rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
     579                 :            : 
     580                 :            :         /* directly mapped flags for ieee80211_rx_status */
     581                 :        188 :         rs->enc_flags |=
     582                 :        188 :                 (ads.ds_rxstatus3 & AR_GI) ? RX_ENC_FLAG_SHORT_GI : 0;
     583         [ +  + ]:        188 :         rs->bw = (ads.ds_rxstatus3 & AR_2040) ? RATE_INFO_BW_40 :
     584                 :            :                                                 RATE_INFO_BW_20;
     585         [ -  + ]:        188 :         if (AR_SREV_9280_20_OR_LATER(ah))
     586                 :          0 :                 rs->enc_flags |=
     587                 :            :                         (ads.ds_rxstatus3 & AR_STBC) ?
     588                 :            :                                 /* we can only Nss=1 STBC */
     589                 :          0 :                                 (1 << RX_ENC_FLAG_STBC_SHIFT) : 0;
     590                 :            : 
     591         [ +  + ]:        188 :         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
     592                 :         68 :                 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
     593         [ +  + ]:        188 :         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
     594                 :        104 :                 rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
     595         [ +  + ]:        188 :         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
     596                 :         28 :                 rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
     597                 :            : 
     598         [ +  + ]:        188 :         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
     599                 :            :                 /*
     600                 :            :                  * Treat these errors as mutually exclusive to avoid spurious
     601                 :            :                  * extra error reports from the hardware. If a CRC error is
     602                 :            :                  * reported, then decryption and MIC errors are irrelevant,
     603                 :            :                  * the frame is going to be dropped either way
     604                 :            :                  */
     605         [ +  + ]:        128 :                 if (ads.ds_rxstatus8 & AR_PHYErr) {
     606                 :         36 :                         rs->rs_status |= ATH9K_RXERR_PHY;
     607                 :         36 :                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
     608                 :         36 :                         rs->rs_phyerr = phyerr;
     609         [ +  + ]:         92 :                 } else if (ads.ds_rxstatus8 & AR_CRCErr)
     610                 :         20 :                         rs->rs_status |= ATH9K_RXERR_CRC;
     611         [ +  + ]:         72 :                 else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
     612                 :         10 :                         rs->rs_status |= ATH9K_RXERR_DECRYPT;
     613         [ +  + ]:         62 :                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
     614                 :          2 :                         rs->rs_status |= ATH9K_RXERR_MIC;
     615                 :            :         } else {
     616         [ +  + ]:         60 :                 if (ads.ds_rxstatus8 &
     617                 :            :                     (AR_CRCErr | AR_PHYErr | AR_DecryptCRCErr | AR_MichaelErr))
     618                 :         58 :                         rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC;
     619                 :            : 
     620                 :            :                 /* Only up to MCS16 supported, everything above is invalid */
     621         [ +  + ]:         60 :                 if (rs->rs_rate >= 0x90)
     622                 :          8 :                         rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC;
     623                 :            :         }
     624                 :            : 
     625         [ +  + ]:        188 :         if (ads.ds_rxstatus8 & AR_KeyMiss)
     626                 :         46 :                 rs->rs_status |= ATH9K_RXERR_KEYMISS;
     627                 :            : 
     628                 :            :         return 0;
     629                 :            : }
     630                 :            : EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
     631                 :            : 
     632                 :            : /*
     633                 :            :  * This can stop or re-enables RX.
     634                 :            :  *
     635                 :            :  * If bool is set this will kill any frame which is currently being
     636                 :            :  * transferred between the MAC and baseband and also prevent any new
     637                 :            :  * frames from getting started.
     638                 :            :  */
     639                 :         33 : bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
     640                 :            : {
     641                 :         33 :         u32 reg;
     642                 :            : 
     643         [ +  + ]:         33 :         if (set) {
     644                 :         31 :                 REG_SET_BIT(ah, AR_DIAG_SW,
     645                 :            :                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
     646                 :            : 
     647         [ -  + ]:         31 :                 if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
     648                 :            :                                    0, AH_WAIT_TIMEOUT)) {
     649                 :          0 :                         REG_CLR_BIT(ah, AR_DIAG_SW,
     650                 :            :                                     (AR_DIAG_RX_DIS |
     651                 :            :                                      AR_DIAG_RX_ABORT));
     652                 :            : 
     653                 :          0 :                         reg = REG_READ(ah, AR_OBS_BUS_1);
     654                 :          0 :                         ath_err(ath9k_hw_common(ah),
     655                 :            :                                 "RX failed to go idle in 10 ms RXSM=0x%x\n",
     656                 :            :                                 reg);
     657                 :            : 
     658                 :          0 :                         return false;
     659                 :            :                 }
     660                 :            :         } else {
     661                 :          2 :                 REG_CLR_BIT(ah, AR_DIAG_SW,
     662                 :            :                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
     663                 :            :         }
     664                 :            : 
     665                 :            :         return true;
     666                 :            : }
     667                 :            : EXPORT_SYMBOL(ath9k_hw_setrxabort);
     668                 :            : 
     669                 :         40 : void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
     670                 :            : {
     671                 :         40 :         REG_WRITE(ah, AR_RXDP, rxdp);
     672                 :         40 : }
     673                 :            : EXPORT_SYMBOL(ath9k_hw_putrxbuf);
     674                 :            : 
     675                 :         60 : void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning)
     676                 :            : {
     677                 :         60 :         ath9k_enable_mib_counters(ah);
     678                 :            : 
     679                 :         60 :         ath9k_ani_reset(ah, is_scanning);
     680                 :            : 
     681                 :         60 :         REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
     682                 :         60 : }
     683                 :            : EXPORT_SYMBOL(ath9k_hw_startpcureceive);
     684                 :            : 
     685                 :         54 : void ath9k_hw_abortpcurecv(struct ath_hw *ah)
     686                 :            : {
     687                 :         54 :         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
     688                 :            : 
     689                 :         54 :         ath9k_hw_disable_mib_counters(ah);
     690                 :         54 : }
     691                 :            : EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
     692                 :            : 
     693                 :         85 : bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)
     694                 :            : {
     695                 :            : #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
     696                 :         85 :         struct ath_common *common = ath9k_hw_common(ah);
     697                 :         85 :         u32 mac_status, last_mac_status = 0;
     698                 :         85 :         int i;
     699                 :            : 
     700                 :            :         /* Enable access to the DMA observation bus */
     701                 :         85 :         REG_WRITE(ah, AR_MACMISC,
     702                 :            :                   ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
     703                 :            :                    (AR_MACMISC_MISC_OBS_BUS_1 <<
     704                 :            :                     AR_MACMISC_MISC_OBS_BUS_MSB_S)));
     705                 :            : 
     706                 :         85 :         REG_WRITE(ah, AR_CR, AR_CR_RXD);
     707                 :            : 
     708                 :            :         /* Wait for rx enable bit to go low */
     709         [ +  - ]:        226 :         for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
     710   [ +  +  +  + ]:        179 :                 if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
     711                 :            :                         break;
     712                 :            : 
     713         [ +  + ]:         56 :                 if (!AR_SREV_9300_20_OR_LATER(ah)) {
     714                 :         10 :                         mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0;
     715   [ -  +  -  - ]:         10 :                         if (mac_status == 0x1c0 && mac_status == last_mac_status) {
     716                 :          0 :                                 *reset = true;
     717                 :          0 :                                 break;
     718                 :            :                         }
     719                 :            : 
     720                 :            :                         last_mac_status = mac_status;
     721                 :            :                 }
     722                 :            : 
     723                 :         56 :                 udelay(AH_TIME_QUANTUM);
     724                 :            :         }
     725                 :            : 
     726         [ -  + ]:         85 :         if (i == 0) {
     727                 :          0 :                 ath_err(common,
     728                 :            :                         "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
     729                 :            :                         AH_RX_STOP_DMA_TIMEOUT / 1000,
     730                 :            :                         REG_READ(ah, AR_CR),
     731                 :            :                         REG_READ(ah, AR_DIAG_SW),
     732                 :            :                         REG_READ(ah, AR_DMADBG_7));
     733                 :          0 :                 return false;
     734                 :            :         } else {
     735                 :            :                 return true;
     736                 :            :         }
     737                 :            : 
     738                 :            : #undef AH_RX_STOP_DMA_TIMEOUT
     739                 :            : }
     740                 :            : EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
     741                 :            : 
     742                 :          6 : int ath9k_hw_beaconq_setup(struct ath_hw *ah)
     743                 :            : {
     744                 :          6 :         struct ath9k_tx_queue_info qi;
     745                 :            : 
     746                 :          6 :         memset(&qi, 0, sizeof(qi));
     747                 :          6 :         qi.tqi_aifs = 1;
     748                 :          6 :         qi.tqi_cwmin = 0;
     749                 :          6 :         qi.tqi_cwmax = 0;
     750                 :            : 
     751         [ +  + ]:          6 :         if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
     752                 :          4 :                 qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE;
     753                 :            : 
     754                 :          6 :         return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
     755                 :            : }
     756                 :            : EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
     757                 :            : 
     758                 :        181 : bool ath9k_hw_intrpend(struct ath_hw *ah)
     759                 :            : {
     760                 :        181 :         u32 host_isr;
     761                 :            : 
     762         [ +  - ]:        181 :         if (AR_SREV_9100(ah))
     763                 :            :                 return true;
     764                 :            : 
     765         [ +  - ]:        362 :         host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
     766                 :            : 
     767         [ +  + ]:        181 :         if (((host_isr & AR_INTR_MAC_IRQ) ||
     768         [ -  + ]:         29 :              (host_isr & AR_INTR_ASYNC_MASK_MCI)) &&
     769                 :            :             (host_isr != AR_INTR_SPURIOUS))
     770                 :            :                 return true;
     771                 :            : 
     772         [ +  - ]:        304 :         host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
     773         [ +  + ]:        152 :         if ((host_isr & AR_INTR_SYNC_DEFAULT)
     774         [ +  - ]:        107 :             && (host_isr != AR_INTR_SPURIOUS))
     775                 :        107 :                 return true;
     776                 :            : 
     777                 :            :         return false;
     778                 :            : }
     779                 :            : EXPORT_SYMBOL(ath9k_hw_intrpend);
     780                 :            : 
     781                 :        223 : void ath9k_hw_kill_interrupts(struct ath_hw *ah)
     782                 :            : {
     783         [ -  + ]:        223 :         struct ath_common *common = ath9k_hw_common(ah);
     784                 :            : 
     785         [ -  + ]:        223 :         ath_dbg(common, INTERRUPT, "disable IER\n");
     786                 :        223 :         REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
     787                 :        223 :         (void) REG_READ(ah, AR_IER);
     788         [ +  - ]:        223 :         if (!AR_SREV_9100(ah)) {
     789         [ +  - ]:        446 :                 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
     790         [ +  - ]:        446 :                 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
     791                 :            : 
     792         [ +  - ]:        446 :                 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
     793         [ +  - ]:        446 :                 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
     794                 :            :         }
     795                 :        223 : }
     796                 :            : EXPORT_SYMBOL(ath9k_hw_kill_interrupts);
     797                 :            : 
     798                 :        120 : void ath9k_hw_disable_interrupts(struct ath_hw *ah)
     799                 :            : {
     800         [ -  + ]:        120 :         if (!(ah->imask & ATH9K_INT_GLOBAL))
     801                 :          0 :                 atomic_set(&ah->intr_ref_cnt, -1);
     802                 :            :         else
     803                 :        120 :                 atomic_dec(&ah->intr_ref_cnt);
     804                 :            : 
     805                 :        120 :         ath9k_hw_kill_interrupts(ah);
     806                 :        120 : }
     807                 :            : EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
     808                 :            : 
     809                 :         67 : static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
     810                 :            : {
     811         [ +  - ]:         67 :         struct ath_common *common = ath9k_hw_common(ah);
     812                 :         67 :         u32 sync_default = AR_INTR_SYNC_DEFAULT;
     813                 :         67 :         u32 async_mask;
     814                 :            : 
     815   [ +  -  +  -  :         67 :         if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
             +  +  +  + ]
     816                 :            :             AR_SREV_9561(ah))
     817                 :         21 :                 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
     818                 :            : 
     819                 :         67 :         async_mask = AR_INTR_MAC_IRQ;
     820                 :            : 
     821         [ -  + ]:         67 :         if (ah->imask & ATH9K_INT_MCI)
     822                 :          0 :                 async_mask |= AR_INTR_ASYNC_MASK_MCI;
     823                 :            : 
     824         [ -  + ]:         67 :         ath_dbg(common, INTERRUPT, "enable IER\n");
     825                 :         67 :         REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
     826         [ +  - ]:         67 :         if (!AR_SREV_9100(ah)) {
     827         [ +  - ]:        134 :                 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, async_mask);
     828         [ +  - ]:        134 :                 REG_WRITE(ah, AR_INTR_ASYNC_MASK, async_mask);
     829                 :            : 
     830         [ +  - ]:        134 :                 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
     831         [ +  - ]:        134 :                 REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
     832                 :            :         }
     833         [ -  + ]:         67 :         ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
     834                 :            :                 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
     835                 :            : 
     836         [ -  + ]:         67 :         if (ah->msi_enabled) {
     837                 :          0 :                 u32 _msi_reg = 0;
     838                 :          0 :                 u32 i = 0;
     839                 :          0 :                 u32 msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
     840                 :            : 
     841         [ #  # ]:          0 :                 ath_dbg(ath9k_hw_common(ah), INTERRUPT,
     842                 :            :                         "Enabling MSI, msi_mask=0x%X\n", ah->msi_mask);
     843                 :            : 
     844         [ #  # ]:          0 :                 REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, ah->msi_mask);
     845         [ #  # ]:          0 :                 REG_WRITE(ah, AR_INTR_PRIO_ASYNC_MASK, ah->msi_mask);
     846   [ #  #  #  #  :          0 :                 ath_dbg(ath9k_hw_common(ah), INTERRUPT,
                   #  # ]
     847                 :            :                         "AR_INTR_PRIO_ASYNC_ENABLE=0x%X, AR_INTR_PRIO_ASYNC_MASK=0x%X\n",
     848                 :            :                         REG_READ(ah, AR_INTR_PRIO_ASYNC_ENABLE),
     849                 :            :                         REG_READ(ah, AR_INTR_PRIO_ASYNC_MASK));
     850                 :            : 
     851         [ #  # ]:          0 :                 if (ah->msi_reg == 0)
     852   [ #  #  #  # ]:          0 :                         ah->msi_reg = REG_READ(ah, AR_PCIE_MSI);
     853                 :            : 
     854   [ #  #  #  #  :          0 :                 ath_dbg(ath9k_hw_common(ah), INTERRUPT,
                   #  # ]
     855                 :            :                         "AR_PCIE_MSI=0x%X, ah->msi_reg = 0x%X\n",
     856                 :            :                         AR_PCIE_MSI, ah->msi_reg);
     857                 :            : 
     858                 :            :                 i = 0;
     859                 :          0 :                 do {
     860   [ #  #  #  # ]:          0 :                         REG_WRITE(ah, AR_PCIE_MSI,
     861                 :            :                                   (ah->msi_reg | AR_PCIE_MSI_ENABLE)
     862                 :            :                                   & msi_pend_addr_mask);
     863   [ #  #  #  # ]:          0 :                         _msi_reg = REG_READ(ah, AR_PCIE_MSI);
     864                 :          0 :                         i++;
     865   [ #  #  #  # ]:          0 :                 } while ((_msi_reg & AR_PCIE_MSI_ENABLE) == 0 && i < 200);
     866                 :            : 
     867         [ #  # ]:          0 :                 if (i >= 200)
     868                 :          0 :                         ath_err(ath9k_hw_common(ah),
     869                 :            :                                 "%s: _msi_reg = 0x%X\n",
     870                 :            :                                 __func__, _msi_reg);
     871                 :            :         }
     872                 :         67 : }
     873                 :            : 
     874                 :          1 : void ath9k_hw_resume_interrupts(struct ath_hw *ah)
     875                 :            : {
     876         [ +  - ]:          1 :         struct ath_common *common = ath9k_hw_common(ah);
     877                 :            : 
     878         [ +  - ]:          1 :         if (!(ah->imask & ATH9K_INT_GLOBAL))
     879                 :            :                 return;
     880                 :            : 
     881         [ -  + ]:          1 :         if (atomic_read(&ah->intr_ref_cnt) != 0) {
     882         [ #  # ]:          0 :                 ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
     883                 :            :                         atomic_read(&ah->intr_ref_cnt));
     884                 :          0 :                 return;
     885                 :            :         }
     886                 :            : 
     887                 :          1 :         __ath9k_hw_enable_interrupts(ah);
     888                 :            : }
     889                 :            : EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
     890                 :            : 
     891                 :        126 : void ath9k_hw_enable_interrupts(struct ath_hw *ah)
     892                 :            : {
     893         [ +  - ]:        126 :         struct ath_common *common = ath9k_hw_common(ah);
     894                 :            : 
     895         [ +  - ]:        126 :         if (!(ah->imask & ATH9K_INT_GLOBAL))
     896                 :            :                 return;
     897                 :            : 
     898         [ +  + ]:        126 :         if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
     899         [ -  + ]:         60 :                 ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
     900                 :            :                         atomic_read(&ah->intr_ref_cnt));
     901                 :         60 :                 return;
     902                 :            :         }
     903                 :            : 
     904                 :         66 :         __ath9k_hw_enable_interrupts(ah);
     905                 :            : }
     906                 :            : EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
     907                 :            : 
     908                 :        194 : void ath9k_hw_set_interrupts(struct ath_hw *ah)
     909                 :            : {
     910                 :        194 :         enum ath9k_int ints = ah->imask;
     911                 :        194 :         u32 mask, mask2;
     912                 :        194 :         struct ath9k_hw_capabilities *pCap = &ah->caps;
     913         [ -  + ]:        194 :         struct ath_common *common = ath9k_hw_common(ah);
     914                 :            : 
     915         [ -  + ]:        194 :         if (!(ints & ATH9K_INT_GLOBAL))
     916                 :          0 :                 ath9k_hw_disable_interrupts(ah);
     917                 :            : 
     918         [ -  + ]:        194 :         if (ah->msi_enabled) {
     919         [ #  # ]:          0 :                 ath_dbg(common, INTERRUPT, "Clearing AR_INTR_PRIO_ASYNC_ENABLE\n");
     920                 :            : 
     921         [ #  # ]:          0 :                 REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
     922         [ #  # ]:          0 :                 REG_READ(ah, AR_INTR_PRIO_ASYNC_ENABLE);
     923                 :            :         }
     924                 :            : 
     925         [ -  + ]:        194 :         ath_dbg(common, INTERRUPT, "New interrupt mask 0x%x\n", ints);
     926                 :            : 
     927                 :        194 :         mask = ints & ATH9K_INT_COMMON;
     928                 :        194 :         mask2 = 0;
     929                 :            : 
     930                 :        194 :         ah->msi_mask = 0;
     931         [ +  - ]:        194 :         if (ints & ATH9K_INT_TX) {
     932                 :        194 :                 ah->msi_mask |= AR_INTR_PRIO_TX;
     933         [ -  + ]:        194 :                 if (ah->config.tx_intr_mitigation)
     934                 :          0 :                         mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
     935                 :            :                 else {
     936         [ +  + ]:        194 :                         if (ah->txok_interrupt_mask)
     937                 :        130 :                                 mask |= AR_IMR_TXOK;
     938         [ +  + ]:        194 :                         if (ah->txdesc_interrupt_mask)
     939                 :         64 :                                 mask |= AR_IMR_TXDESC;
     940                 :            :                 }
     941         [ +  + ]:        194 :                 if (ah->txerr_interrupt_mask)
     942                 :        130 :                         mask |= AR_IMR_TXERR;
     943         [ +  + ]:        194 :                 if (ah->txeol_interrupt_mask)
     944                 :         64 :                         mask |= AR_IMR_TXEOL;
     945                 :            :         }
     946         [ +  - ]:        194 :         if (ints & ATH9K_INT_RX) {
     947                 :        194 :                 ah->msi_mask |= AR_INTR_PRIO_RXLP | AR_INTR_PRIO_RXHP;
     948         [ +  + ]:        194 :                 if (AR_SREV_9300_20_OR_LATER(ah)) {
     949                 :        130 :                         mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
     950         [ +  - ]:        130 :                         if (ah->config.rx_intr_mitigation) {
     951                 :        130 :                                 mask &= ~AR_IMR_RXOK_LP;
     952                 :        130 :                                 mask |=  AR_IMR_RXMINTR | AR_IMR_RXINTM;
     953                 :            :                         } else {
     954                 :          0 :                                 mask |= AR_IMR_RXOK_LP;
     955                 :            :                         }
     956                 :            :                 } else {
     957         [ +  - ]:         64 :                         if (ah->config.rx_intr_mitigation)
     958                 :         64 :                                 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
     959                 :            :                         else
     960                 :          0 :                                 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
     961                 :            :                 }
     962         [ +  + ]:        194 :                 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
     963                 :         64 :                         mask |= AR_IMR_GENTMR;
     964                 :            :         }
     965                 :            : 
     966         [ -  + ]:        194 :         if (ints & ATH9K_INT_GENTIMER)
     967                 :          0 :                 mask |= AR_IMR_GENTMR;
     968                 :            : 
     969         [ +  + ]:        194 :         if (ints & (ATH9K_INT_BMISC)) {
     970                 :        161 :                 mask |= AR_IMR_BCNMISC;
     971         [ -  + ]:        161 :                 if (ints & ATH9K_INT_TIM)
     972                 :          0 :                         mask2 |= AR_IMR_S2_TIM;
     973         [ -  + ]:        161 :                 if (ints & ATH9K_INT_DTIM)
     974                 :          0 :                         mask2 |= AR_IMR_S2_DTIM;
     975         [ -  + ]:        161 :                 if (ints & ATH9K_INT_DTIMSYNC)
     976                 :          0 :                         mask2 |= AR_IMR_S2_DTIMSYNC;
     977         [ -  + ]:        161 :                 if (ints & ATH9K_INT_CABEND)
     978                 :          0 :                         mask2 |= AR_IMR_S2_CABEND;
     979         [ +  - ]:        161 :                 if (ints & ATH9K_INT_TSFOOR)
     980                 :        161 :                         mask2 |= AR_IMR_S2_TSFOOR;
     981                 :            :         }
     982                 :            : 
     983         [ +  - ]:        194 :         if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
     984                 :        194 :                 mask |= AR_IMR_BCNMISC;
     985         [ +  + ]:        194 :                 if (ints & ATH9K_INT_GTT)
     986                 :        130 :                         mask2 |= AR_IMR_S2_GTT;
     987         [ +  - ]:        194 :                 if (ints & ATH9K_INT_CST)
     988                 :        194 :                         mask2 |= AR_IMR_S2_CST;
     989                 :            :         }
     990                 :            : 
     991         [ +  + ]:        194 :         if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) {
     992         [ +  - ]:        130 :                 if (ints & ATH9K_INT_BB_WATCHDOG) {
     993                 :        130 :                         mask |= AR_IMR_BCNMISC;
     994                 :        130 :                         mask2 |= AR_IMR_S2_BB_WATCHDOG;
     995                 :            :                 }
     996                 :            :         }
     997                 :            : 
     998         [ -  + ]:        194 :         ath_dbg(common, INTERRUPT, "new IMR 0x%x\n", mask);
     999                 :        194 :         REG_WRITE(ah, AR_IMR, mask);
    1000                 :        194 :         ah->imrs2_reg &= ~(AR_IMR_S2_TIM |
    1001                 :            :                            AR_IMR_S2_DTIM |
    1002                 :            :                            AR_IMR_S2_DTIMSYNC |
    1003                 :            :                            AR_IMR_S2_CABEND |
    1004                 :            :                            AR_IMR_S2_CABTO |
    1005                 :            :                            AR_IMR_S2_TSFOOR |
    1006                 :            :                            AR_IMR_S2_GTT |
    1007                 :            :                            AR_IMR_S2_CST);
    1008                 :            : 
    1009         [ +  + ]:        194 :         if (ah->config.hw_hang_checks & HW_BB_WATCHDOG) {
    1010         [ +  - ]:        130 :                 if (ints & ATH9K_INT_BB_WATCHDOG)
    1011                 :        130 :                         ah->imrs2_reg &= ~AR_IMR_S2_BB_WATCHDOG;
    1012                 :            :         }
    1013                 :            : 
    1014                 :        194 :         ah->imrs2_reg |= mask2;
    1015                 :        194 :         REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
    1016                 :            : 
    1017         [ +  + ]:        194 :         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
    1018         [ -  + ]:         64 :                 if (ints & ATH9K_INT_TIM_TIMER)
    1019                 :          0 :                         REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
    1020                 :            :                 else
    1021                 :         64 :                         REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
    1022                 :            :         }
    1023                 :            : 
    1024                 :        194 :         return;
    1025                 :            : }
    1026                 :            : EXPORT_SYMBOL(ath9k_hw_set_interrupts);
    1027                 :            : 
    1028                 :            : #define ATH9K_HW_MAX_DCU       10
    1029                 :            : #define ATH9K_HW_SLICE_PER_DCU 16
    1030                 :            : #define ATH9K_HW_BIT_IN_SLICE  16
    1031                 :          0 : void ath9k_hw_set_tx_filter(struct ath_hw *ah, u8 destidx, bool set)
    1032                 :            : {
    1033                 :          0 :         int dcu_idx;
    1034                 :          0 :         u32 filter;
    1035                 :            : 
    1036         [ #  # ]:          0 :         for (dcu_idx = 0; dcu_idx < 10; dcu_idx++) {
    1037                 :          0 :                 filter = SM(set, AR_D_TXBLK_WRITE_COMMAND);
    1038                 :          0 :                 filter |= SM(dcu_idx, AR_D_TXBLK_WRITE_DCU);
    1039                 :          0 :                 filter |= SM((destidx / ATH9K_HW_SLICE_PER_DCU),
    1040                 :            :                              AR_D_TXBLK_WRITE_SLICE);
    1041                 :          0 :                 filter |= BIT(destidx % ATH9K_HW_BIT_IN_SLICE);
    1042         [ #  # ]:          0 :                 ath_dbg(ath9k_hw_common(ah), PS,
    1043                 :            :                         "DCU%d staid %d set %d txfilter %08x\n",
    1044                 :            :                         dcu_idx, destidx, set, filter);
    1045                 :          0 :                 REG_WRITE(ah, AR_D_TXBLK_BASE, filter);
    1046                 :            :         }
    1047                 :          0 : }
    1048                 :            : EXPORT_SYMBOL(ath9k_hw_set_tx_filter);

Generated by: LCOV version 1.14