2  * Copyright (c) 2008 Atheros Communications Inc.
 
   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.
 
   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.
 
  22 static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
 
  23                                         struct ath9k_tx_queue_info *qi)
 
  25         struct ath_hal_5416 *ahp = AH5416(ah);
 
  27         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
 
  28                 "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
 
  29                 ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
 
  30                 ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
 
  31                 ahp->ah_txUrnInterruptMask);
 
  33         REG_WRITE(ah, AR_IMR_S0,
 
  34                   SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
 
  35                   | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
 
  36         REG_WRITE(ah, AR_IMR_S1,
 
  37                   SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
 
  38                   | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
 
  39         REG_RMW_FIELD(ah, AR_IMR_S2,
 
  40                       AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
 
  43 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
 
  45         return REG_READ(ah, AR_QTXDP(q));
 
  48 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp)
 
  50         REG_WRITE(ah, AR_QTXDP(q), txdp);
 
  55 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
 
  57         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
 
  59         REG_WRITE(ah, AR_Q_TXE, 1 << q);
 
  64 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
 
  68         npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
 
  71                 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
 
  78 bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
 
  80         struct ath_hal_5416 *ahp = AH5416(ah);
 
  81         u32 txcfg, curLevel, newLevel;
 
  84         if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
 
  87         omask = ath9k_hw_set_interrupts(ah, ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
 
  89         txcfg = REG_READ(ah, AR_TXCFG);
 
  90         curLevel = MS(txcfg, AR_FTRIG);
 
  93                 if (curLevel < MAX_TX_FIFO_THRESHOLD)
 
  95         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
 
  97         if (newLevel != curLevel)
 
  98                 REG_WRITE(ah, AR_TXCFG,
 
  99                           (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
 
 101         ath9k_hw_set_interrupts(ah, omask);
 
 103         ah->ah_txTrigLevel = newLevel;
 
 105         return newLevel != curLevel;
 
 108 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
 
 112         REG_WRITE(ah, AR_Q_TXD, 1 << q);
 
 114         for (wait = 1000; wait != 0; wait--) {
 
 115                 if (ath9k_hw_numtxpending(ah, q) == 0)
 
 120         if (ath9k_hw_numtxpending(ah, q)) {
 
 121                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
 
 122                         "%s: Num of pending TX Frames %d on Q %d\n",
 
 123                         __func__, ath9k_hw_numtxpending(ah, q), q);
 
 125                 for (j = 0; j < 2; j++) {
 
 126                         tsfLow = REG_READ(ah, AR_TSF_L32);
 
 127                         REG_WRITE(ah, AR_QUIET2,
 
 128                                   SM(10, AR_QUIET2_QUIET_DUR));
 
 129                         REG_WRITE(ah, AR_QUIET_PERIOD, 100);
 
 130                         REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
 
 131                         REG_SET_BIT(ah, AR_TIMER_MODE,
 
 134                         if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
 
 137                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
 
 138                                 "TSF have moved while trying to set "
 
 139                                 "quiet time TSF: 0x%08x\n", tsfLow);
 
 142                 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
 
 145                 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
 
 149                 while (ath9k_hw_numtxpending(ah, q)) {
 
 151                                 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
 
 152                                         "Failed to stop Tx DMA in 100 "
 
 153                                         "msec after killing last frame\n");
 
 159                 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
 
 162         REG_WRITE(ah, AR_Q_TXD, 0);
 
 167 bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
 
 168                          u32 segLen, bool firstSeg,
 
 169                          bool lastSeg, const struct ath_desc *ds0)
 
 171         struct ar5416_desc *ads = AR5416DESC(ds);
 
 174                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
 
 175         } else if (lastSeg) {
 
 177                 ads->ds_ctl1 = segLen;
 
 178                 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
 
 179                 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
 
 182                 ads->ds_ctl1 = segLen | AR_TxMore;
 
 186         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
 
 187         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
 
 188         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
 
 189         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
 
 190         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 
 195 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
 
 197         struct ar5416_desc *ads = AR5416DESC(ds);
 
 199         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
 
 200         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
 
 201         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
 
 202         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
 
 203         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 
 206 int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
 
 208         struct ar5416_desc *ads = AR5416DESC(ds);
 
 210         if ((ads->ds_txstatus9 & AR_TxDone) == 0)
 
 213         ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
 
 214         ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
 
 215         ds->ds_txstat.ts_status = 0;
 
 216         ds->ds_txstat.ts_flags = 0;
 
 218         if (ads->ds_txstatus1 & AR_ExcessiveRetries)
 
 219                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
 
 220         if (ads->ds_txstatus1 & AR_Filtered)
 
 221                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
 
 222         if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
 
 223                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
 
 224                 ath9k_hw_updatetxtriglevel(ah, true);
 
 226         if (ads->ds_txstatus9 & AR_TxOpExceeded)
 
 227                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
 
 228         if (ads->ds_txstatus1 & AR_TxTimerExpired)
 
 229                 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
 
 231         if (ads->ds_txstatus1 & AR_DescCfgErr)
 
 232                 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
 
 233         if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
 
 234                 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
 
 235                 ath9k_hw_updatetxtriglevel(ah, true);
 
 237         if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
 
 238                 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
 
 239                 ath9k_hw_updatetxtriglevel(ah, true);
 
 241         if (ads->ds_txstatus0 & AR_TxBaStatus) {
 
 242                 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
 
 243                 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
 
 244                 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
 
 247         ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
 
 248         switch (ds->ds_txstat.ts_rateindex) {
 
 250                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
 
 253                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
 
 256                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
 
 259                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
 
 263         ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
 
 264         ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
 
 265         ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
 
 266         ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
 
 267         ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
 
 268         ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
 
 269         ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
 
 270         ds->ds_txstat.evm0 = ads->AR_TxEVM0;
 
 271         ds->ds_txstat.evm1 = ads->AR_TxEVM1;
 
 272         ds->ds_txstat.evm2 = ads->AR_TxEVM2;
 
 273         ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
 
 274         ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
 
 275         ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
 
 276         ds->ds_txstat.ts_antenna = 1;
 
 281 void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
 
 282                             u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
 
 283                             u32 keyIx, enum ath9k_key_type keyType, u32 flags)
 
 285         struct ar5416_desc *ads = AR5416DESC(ds);
 
 286         struct ath_hal_5416 *ahp = AH5416(ah);
 
 288         txPower += ahp->ah_txPowerIndexOffset;
 
 292         ads->ds_ctl0 = (pktLen & AR_FrameLen)
 
 293                 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
 
 294                 | SM(txPower, AR_XmitPower)
 
 295                 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
 
 296                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
 
 297                 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
 
 298                 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
 
 301                 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
 
 302                 | SM(type, AR_FrameType)
 
 303                 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
 
 304                 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
 
 305                 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
 
 307         ads->ds_ctl6 = SM(keyType, AR_EncrType);
 
 309         if (AR_SREV_9285(ah)) {
 
 317 void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
 
 318                                   struct ath_desc *lastds,
 
 319                                   u32 durUpdateEn, u32 rtsctsRate,
 
 321                                   struct ath9k_11n_rate_series series[],
 
 322                                   u32 nseries, u32 flags)
 
 324         struct ar5416_desc *ads = AR5416DESC(ds);
 
 325         struct ar5416_desc *last_ads = AR5416DESC(lastds);
 
 329         (void) rtsctsDuration;
 
 331         if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
 
 332                 ds_ctl0 = ads->ds_ctl0;
 
 334                 if (flags & ATH9K_TXDESC_RTSENA) {
 
 335                         ds_ctl0 &= ~AR_CTSEnable;
 
 336                         ds_ctl0 |= AR_RTSEnable;
 
 338                         ds_ctl0 &= ~AR_RTSEnable;
 
 339                         ds_ctl0 |= AR_CTSEnable;
 
 342                 ads->ds_ctl0 = ds_ctl0;
 
 345                         (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
 
 348         ads->ds_ctl2 = set11nTries(series, 0)
 
 349                 | set11nTries(series, 1)
 
 350                 | set11nTries(series, 2)
 
 351                 | set11nTries(series, 3)
 
 352                 | (durUpdateEn ? AR_DurUpdateEna : 0)
 
 353                 | SM(0, AR_BurstDur);
 
 355         ads->ds_ctl3 = set11nRate(series, 0)
 
 356                 | set11nRate(series, 1)
 
 357                 | set11nRate(series, 2)
 
 358                 | set11nRate(series, 3);
 
 360         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
 
 361                 | set11nPktDurRTSCTS(series, 1);
 
 363         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
 
 364                 | set11nPktDurRTSCTS(series, 3);
 
 366         ads->ds_ctl7 = set11nRateFlags(series, 0)
 
 367                 | set11nRateFlags(series, 1)
 
 368                 | set11nRateFlags(series, 2)
 
 369                 | set11nRateFlags(series, 3)
 
 370                 | SM(rtsctsRate, AR_RTSCTSRate);
 
 371         last_ads->ds_ctl2 = ads->ds_ctl2;
 
 372         last_ads->ds_ctl3 = ads->ds_ctl3;
 
 375 void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
 
 378         struct ar5416_desc *ads = AR5416DESC(ds);
 
 380         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
 
 381         ads->ds_ctl6 &= ~AR_AggrLen;
 
 382         ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
 
 385 void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
 
 388         struct ar5416_desc *ads = AR5416DESC(ds);
 
 391         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
 
 394         ctl6 &= ~AR_PadDelim;
 
 395         ctl6 |= SM(numDelims, AR_PadDelim);
 
 399 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
 
 401         struct ar5416_desc *ads = AR5416DESC(ds);
 
 403         ads->ds_ctl1 |= AR_IsAggr;
 
 404         ads->ds_ctl1 &= ~AR_MoreAggr;
 
 405         ads->ds_ctl6 &= ~AR_PadDelim;
 
 408 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
 
 410         struct ar5416_desc *ads = AR5416DESC(ds);
 
 412         ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
 
 415 void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
 
 418         struct ar5416_desc *ads = AR5416DESC(ds);
 
 420         ads->ds_ctl2 &= ~AR_BurstDur;
 
 421         ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
 
 424 void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
 
 427         struct ar5416_desc *ads = AR5416DESC(ds);
 
 430                 ads->ds_ctl0 |= AR_VirtMoreFrag;
 
 432                 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
 
 435 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
 
 437         struct ath_hal_5416 *ahp = AH5416(ah);
 
 439         *txqs &= ahp->ah_intrTxqs;
 
 440         ahp->ah_intrTxqs &= ~(*txqs);
 
 443 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
 
 444                             const struct ath9k_tx_queue_info *qinfo)
 
 447         struct ath_hal_5416 *ahp = AH5416(ah);
 
 448         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
 449         struct ath9k_tx_queue_info *qi;
 
 451         if (q >= pCap->total_queues) {
 
 452                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
 
 456         qi = &ahp->ah_txq[q];
 
 457         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 
 458                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
 
 462         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi);
 
 464         qi->tqi_ver = qinfo->tqi_ver;
 
 465         qi->tqi_subtype = qinfo->tqi_subtype;
 
 466         qi->tqi_qflags = qinfo->tqi_qflags;
 
 467         qi->tqi_priority = qinfo->tqi_priority;
 
 468         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
 
 469                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
 
 471                 qi->tqi_aifs = INIT_AIFS;
 
 472         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
 
 473                 cw = min(qinfo->tqi_cwmin, 1024U);
 
 475                 while (qi->tqi_cwmin < cw)
 
 476                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
 
 478                 qi->tqi_cwmin = qinfo->tqi_cwmin;
 
 479         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
 
 480                 cw = min(qinfo->tqi_cwmax, 1024U);
 
 482                 while (qi->tqi_cwmax < cw)
 
 483                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
 
 485                 qi->tqi_cwmax = INIT_CWMAX;
 
 487         if (qinfo->tqi_shretry != 0)
 
 488                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
 
 490                 qi->tqi_shretry = INIT_SH_RETRY;
 
 491         if (qinfo->tqi_lgretry != 0)
 
 492                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
 
 494                 qi->tqi_lgretry = INIT_LG_RETRY;
 
 495         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
 
 496         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
 
 497         qi->tqi_burstTime = qinfo->tqi_burstTime;
 
 498         qi->tqi_readyTime = qinfo->tqi_readyTime;
 
 500         switch (qinfo->tqi_subtype) {
 
 502                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
 
 503                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
 
 512 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
 
 513                             struct ath9k_tx_queue_info *qinfo)
 
 515         struct ath_hal_5416 *ahp = AH5416(ah);
 
 516         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
 517         struct ath9k_tx_queue_info *qi;
 
 519         if (q >= pCap->total_queues) {
 
 520                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
 
 524         qi = &ahp->ah_txq[q];
 
 525         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 
 526                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
 
 530         qinfo->tqi_qflags = qi->tqi_qflags;
 
 531         qinfo->tqi_ver = qi->tqi_ver;
 
 532         qinfo->tqi_subtype = qi->tqi_subtype;
 
 533         qinfo->tqi_qflags = qi->tqi_qflags;
 
 534         qinfo->tqi_priority = qi->tqi_priority;
 
 535         qinfo->tqi_aifs = qi->tqi_aifs;
 
 536         qinfo->tqi_cwmin = qi->tqi_cwmin;
 
 537         qinfo->tqi_cwmax = qi->tqi_cwmax;
 
 538         qinfo->tqi_shretry = qi->tqi_shretry;
 
 539         qinfo->tqi_lgretry = qi->tqi_lgretry;
 
 540         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
 
 541         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
 
 542         qinfo->tqi_burstTime = qi->tqi_burstTime;
 
 543         qinfo->tqi_readyTime = qi->tqi_readyTime;
 
 548 int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
 
 549                           const struct ath9k_tx_queue_info *qinfo)
 
 551         struct ath_hal_5416 *ahp = AH5416(ah);
 
 552         struct ath9k_tx_queue_info *qi;
 
 553         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
 557         case ATH9K_TX_QUEUE_BEACON:
 
 558                 q = pCap->total_queues - 1;
 
 560         case ATH9K_TX_QUEUE_CAB:
 
 561                 q = pCap->total_queues - 2;
 
 563         case ATH9K_TX_QUEUE_PSPOLL:
 
 566         case ATH9K_TX_QUEUE_UAPSD:
 
 567                 q = pCap->total_queues - 3;
 
 569         case ATH9K_TX_QUEUE_DATA:
 
 570                 for (q = 0; q < pCap->total_queues; q++)
 
 571                         if (ahp->ah_txq[q].tqi_type ==
 
 572                             ATH9K_TX_QUEUE_INACTIVE)
 
 574                 if (q == pCap->total_queues) {
 
 575                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
 
 576                                 "no available tx queue\n");
 
 581                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type);
 
 585         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
 
 587         qi = &ahp->ah_txq[q];
 
 588         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
 
 589                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
 
 590                         "tx queue %u already active\n", q);
 
 593         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
 
 597                         TXQ_FLAG_TXOKINT_ENABLE
 
 598                         | TXQ_FLAG_TXERRINT_ENABLE
 
 599                         | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
 
 600                 qi->tqi_aifs = INIT_AIFS;
 
 601                 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
 
 602                 qi->tqi_cwmax = INIT_CWMAX;
 
 603                 qi->tqi_shretry = INIT_SH_RETRY;
 
 604                 qi->tqi_lgretry = INIT_LG_RETRY;
 
 605                 qi->tqi_physCompBuf = 0;
 
 607                 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
 
 608                 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
 
 614 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
 
 616         struct ath_hal_5416 *ahp = AH5416(ah);
 
 617         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
 618         struct ath9k_tx_queue_info *qi;
 
 620         if (q >= pCap->total_queues) {
 
 621                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
 
 624         qi = &ahp->ah_txq[q];
 
 625         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 
 626                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
 
 630         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
 
 632         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
 
 633         ahp->ah_txOkInterruptMask &= ~(1 << q);
 
 634         ahp->ah_txErrInterruptMask &= ~(1 << q);
 
 635         ahp->ah_txDescInterruptMask &= ~(1 << q);
 
 636         ahp->ah_txEolInterruptMask &= ~(1 << q);
 
 637         ahp->ah_txUrnInterruptMask &= ~(1 << q);
 
 638         ath9k_hw_set_txq_interrupts(ah, qi);
 
 643 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
 
 645         struct ath_hal_5416 *ahp = AH5416(ah);
 
 646         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
 647         struct ath9k_channel *chan = ah->ah_curchan;
 
 648         struct ath9k_tx_queue_info *qi;
 
 649         u32 cwMin, chanCwMin, value;
 
 651         if (q >= pCap->total_queues) {
 
 652                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
 
 656         qi = &ahp->ah_txq[q];
 
 657         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 
 658                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
 
 662         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q);
 
 664         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
 
 665                 if (chan && IS_CHAN_B(chan))
 
 666                         chanCwMin = INIT_CWMIN_11B;
 
 668                         chanCwMin = INIT_CWMIN;
 
 670                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
 
 672                 cwMin = qi->tqi_cwmin;
 
 674         REG_WRITE(ah, AR_DLCL_IFS(q),
 
 675                   SM(cwMin, AR_D_LCL_IFS_CWMIN) |
 
 676                   SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
 
 677                   SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
 
 679         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
 
 680                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
 
 681                   SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
 
 682                   SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
 
 684         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
 
 685         REG_WRITE(ah, AR_DMISC(q),
 
 686                   AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
 
 688         if (qi->tqi_cbrPeriod) {
 
 689                 REG_WRITE(ah, AR_QCBRCFG(q),
 
 690                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
 
 691                           SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
 
 692                 REG_WRITE(ah, AR_QMISC(q),
 
 693                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
 
 694                           (qi->tqi_cbrOverflowLimit ?
 
 695                            AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
 
 697         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
 
 698                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
 
 699                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
 
 703         REG_WRITE(ah, AR_DCHNTIME(q),
 
 704                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
 
 705                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
 
 707         if (qi->tqi_burstTime
 
 708             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
 
 709                 REG_WRITE(ah, AR_QMISC(q),
 
 710                           REG_READ(ah, AR_QMISC(q)) |
 
 711                           AR_Q_MISC_RDYTIME_EXP_POLICY);
 
 715         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
 
 716                 REG_WRITE(ah, AR_DMISC(q),
 
 717                           REG_READ(ah, AR_DMISC(q)) |
 
 718                           AR_D_MISC_POST_FR_BKOFF_DIS);
 
 720         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
 
 721                 REG_WRITE(ah, AR_DMISC(q),
 
 722                           REG_READ(ah, AR_DMISC(q)) |
 
 723                           AR_D_MISC_FRAG_BKOFF_EN);
 
 725         switch (qi->tqi_type) {
 
 726         case ATH9K_TX_QUEUE_BEACON:
 
 727                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
 
 728                           | AR_Q_MISC_FSP_DBA_GATED
 
 729                           | AR_Q_MISC_BEACON_USE
 
 730                           | AR_Q_MISC_CBR_INCR_DIS1);
 
 732                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
 
 733                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
 
 734                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
 
 735                           | AR_D_MISC_BEACON_USE
 
 736                           | AR_D_MISC_POST_FR_BKOFF_DIS);
 
 738         case ATH9K_TX_QUEUE_CAB:
 
 739                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
 
 740                           | AR_Q_MISC_FSP_DBA_GATED
 
 741                           | AR_Q_MISC_CBR_INCR_DIS1
 
 742                           | AR_Q_MISC_CBR_INCR_DIS0);
 
 743                 value = (qi->tqi_readyTime -
 
 744                          (ah->ah_config.sw_beacon_response_time -
 
 745                           ah->ah_config.dma_beacon_response_time) -
 
 746                          ah->ah_config.additional_swba_backoff) * 1024;
 
 747                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
 
 748                           value | AR_Q_RDYTIMECFG_EN);
 
 749                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
 
 750                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
 
 751                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
 
 753         case ATH9K_TX_QUEUE_PSPOLL:
 
 754                 REG_WRITE(ah, AR_QMISC(q),
 
 755                           REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
 
 757         case ATH9K_TX_QUEUE_UAPSD:
 
 758                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
 
 759                           AR_D_MISC_POST_FR_BKOFF_DIS);
 
 765         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
 
 766                 REG_WRITE(ah, AR_DMISC(q),
 
 767                           REG_READ(ah, AR_DMISC(q)) |
 
 768                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
 
 769                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
 
 770                           AR_D_MISC_POST_FR_BKOFF_DIS);
 
 773         if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
 
 774                 ahp->ah_txOkInterruptMask |= 1 << q;
 
 776                 ahp->ah_txOkInterruptMask &= ~(1 << q);
 
 777         if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
 
 778                 ahp->ah_txErrInterruptMask |= 1 << q;
 
 780                 ahp->ah_txErrInterruptMask &= ~(1 << q);
 
 781         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
 
 782                 ahp->ah_txDescInterruptMask |= 1 << q;
 
 784                 ahp->ah_txDescInterruptMask &= ~(1 << q);
 
 785         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
 
 786                 ahp->ah_txEolInterruptMask |= 1 << q;
 
 788                 ahp->ah_txEolInterruptMask &= ~(1 << q);
 
 789         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
 
 790                 ahp->ah_txUrnInterruptMask |= 1 << q;
 
 792                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
 
 793         ath9k_hw_set_txq_interrupts(ah, qi);
 
 798 int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
 
 799                         u32 pa, struct ath_desc *nds, u64 tsf)
 
 801         struct ar5416_desc ads;
 
 802         struct ar5416_desc *adsp = AR5416DESC(ds);
 
 805         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
 
 808         ads.u.rx = adsp->u.rx;
 
 810         ds->ds_rxstat.rs_status = 0;
 
 811         ds->ds_rxstat.rs_flags = 0;
 
 813         ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
 
 814         ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
 
 816         ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
 
 817         ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
 
 818         ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
 
 819         ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
 
 820         ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
 
 821         ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
 
 822         ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
 
 823         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
 
 824                 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
 
 826                 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
 
 828         ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
 
 829         ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
 
 831         ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
 
 832         ds->ds_rxstat.rs_moreaggr =
 
 833                 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
 
 834         ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
 
 835         ds->ds_rxstat.rs_flags =
 
 836                 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
 
 837         ds->ds_rxstat.rs_flags |=
 
 838                 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
 
 840         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
 
 841                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
 
 842         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
 
 843                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
 
 844         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
 
 845                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
 
 847         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
 
 848                 if (ads.ds_rxstatus8 & AR_CRCErr)
 
 849                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
 
 850                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
 
 851                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
 
 852                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
 
 853                         ds->ds_rxstat.rs_phyerr = phyerr;
 
 854                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
 
 855                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
 
 856                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
 
 857                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
 
 863 bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
 
 866         struct ar5416_desc *ads = AR5416DESC(ds);
 
 867         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
 869         ads->ds_ctl1 = size & AR_BufLen;
 
 870         if (flags & ATH9K_RXDESC_INTREQ)
 
 871                 ads->ds_ctl1 |= AR_RxIntrReq;
 
 873         ads->ds_rxstatus8 &= ~AR_RxDone;
 
 874         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
 
 875                 memset(&(ads->u), 0, sizeof(ads->u));
 
 880 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
 
 885                 REG_SET_BIT(ah, AR_DIAG_SW,
 
 886                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
 888                 if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
 
 889                         REG_CLR_BIT(ah, AR_DIAG_SW,
 
 893                         reg = REG_READ(ah, AR_OBS_BUS_1);
 
 894                         DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
 
 895                                 "rx failed to go idle in 10 ms RXSM=0x%x\n", reg);
 
 900                 REG_CLR_BIT(ah, AR_DIAG_SW,
 
 901                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
 907 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
 
 909         REG_WRITE(ah, AR_RXDP, rxdp);
 
 912 void ath9k_hw_rxena(struct ath_hal *ah)
 
 914         REG_WRITE(ah, AR_CR, AR_CR_RXE);
 
 917 void ath9k_hw_startpcureceive(struct ath_hal *ah)
 
 919         ath9k_enable_mib_counters(ah);
 
 923         REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
 926 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
 
 928         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
 
 930         ath9k_hw_disable_mib_counters(ah);
 
 933 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
 
 935         REG_WRITE(ah, AR_CR, AR_CR_RXD);
 
 937         if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
 
 938                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
 
 939                         "dma failed to stop in 10ms\n"
 
 940                         "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
 
 941                         REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));