2  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
 
   3  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
 
   5  * Permission to use, copy, modify, and distribute this software for any
 
   6  * purpose with or without fee is hereby granted, provided that the above
 
   7  * copyright notice and this permission notice appear in all copies.
 
   9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 
  10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 
  11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 
  12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
  13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 
  14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 
  15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
  19 /********************************************\
 
  20 Queue Control Unit, DFS Control Unit Functions
 
  21 \********************************************/
 
  29  * Get properties for a transmit queue
 
  31 int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
 
  32                 struct ath5k_txq_info *queue_info)
 
  34         ATH5K_TRACE(ah->ah_sc);
 
  35         memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
 
  40  * Set properties for a transmit queue
 
  42 int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
 
  43                                 const struct ath5k_txq_info *queue_info)
 
  45         ATH5K_TRACE(ah->ah_sc);
 
  46         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
 
  48         if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
 
  51         memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
 
  53         /*XXX: Is this supported on 5210 ?*/
 
  54         if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
 
  55                         ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
 
  56                         (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
 
  57                         queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
 
  58                 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
 
  64  * Initialize a transmit queue
 
  66 int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
 
  67                 struct ath5k_txq_info *queue_info)
 
  72         ATH5K_TRACE(ah->ah_sc);
 
  77         /*5210 only has 2 queues*/
 
  78         if (ah->ah_version == AR5K_AR5210) {
 
  80                 case AR5K_TX_QUEUE_DATA:
 
  81                         queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
 
  83                 case AR5K_TX_QUEUE_BEACON:
 
  84                 case AR5K_TX_QUEUE_CAB:
 
  85                         queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
 
  92                 case AR5K_TX_QUEUE_DATA:
 
  93                         for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
 
  94                                 ah->ah_txq[queue].tqi_type !=
 
  95                                 AR5K_TX_QUEUE_INACTIVE; queue++) {
 
  97                                 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
 
 101                 case AR5K_TX_QUEUE_UAPSD:
 
 102                         queue = AR5K_TX_QUEUE_ID_UAPSD;
 
 104                 case AR5K_TX_QUEUE_BEACON:
 
 105                         queue = AR5K_TX_QUEUE_ID_BEACON;
 
 107                 case AR5K_TX_QUEUE_CAB:
 
 108                         queue = AR5K_TX_QUEUE_ID_CAB;
 
 110                 case AR5K_TX_QUEUE_XR_DATA:
 
 111                         if (ah->ah_version != AR5K_AR5212)
 
 113                                         "XR data queues only supported in"
 
 115                         queue = AR5K_TX_QUEUE_ID_XR_DATA;
 
 123          * Setup internal queue structure
 
 125         memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
 
 126         ah->ah_txq[queue].tqi_type = queue_type;
 
 128         if (queue_info != NULL) {
 
 129                 queue_info->tqi_type = queue_type;
 
 130                 ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
 
 136          * We use ah_txq_status to hold a temp value for
 
 137          * the Secondary interrupt mask registers on 5211+
 
 138          * check out ath5k_hw_reset_tx_queue
 
 140         AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
 
 146  * Get number of pending frames
 
 147  * for a specific queue [5211+]
 
 149 u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
 
 151         ATH5K_TRACE(ah->ah_sc);
 
 152         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
 
 154         /* Return if queue is declared inactive */
 
 155         if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
 
 158         /* XXX: How about AR5K_CFG_TXCNT ? */
 
 159         if (ah->ah_version == AR5K_AR5210)
 
 162         return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
 
 166  * Set a transmit queue inactive
 
 168 void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 
 170         ATH5K_TRACE(ah->ah_sc);
 
 171         if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
 
 174         /* This queue will be skipped in further operations */
 
 175         ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
 
 177         AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
 
 181  * Set DFS properties for a transmit queue on DCU
 
 183 int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 
 185         u32 cw_min, cw_max, retry_lg, retry_sh;
 
 186         struct ath5k_txq_info *tq = &ah->ah_txq[queue];
 
 188         ATH5K_TRACE(ah->ah_sc);
 
 189         AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
 
 191         tq = &ah->ah_txq[queue];
 
 193         if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
 
 196         if (ah->ah_version == AR5K_AR5210) {
 
 197                 /* Only handle data queues, others will be ignored */
 
 198                 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
 
 202                 ath5k_hw_reg_write(ah, ah->ah_turbo ?
 
 203                         AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
 
 205                 /* Set ACK_CTS timeout */
 
 206                 ath5k_hw_reg_write(ah, ah->ah_turbo ?
 
 207                         AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
 
 208                         AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
 
 209                 /* Set Transmit Latency */
 
 210                 ath5k_hw_reg_write(ah, ah->ah_turbo ?
 
 211                         AR5K_INIT_TRANSMIT_LATENCY_TURBO :
 
 212                         AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
 
 216                          ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
 
 217                                 (ah->ah_aifs + tq->tqi_aifs) *
 
 218                                 AR5K_INIT_SLOT_TIME_TURBO) <<
 
 219                                 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
 
 222                         ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
 
 223                                 (ah->ah_aifs + tq->tqi_aifs) *
 
 224                                 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
 
 225                                 AR5K_INIT_SIFS, AR5K_IFS0);
 
 229                 ath5k_hw_reg_write(ah, ah->ah_turbo ?
 
 230                         AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
 
 231                         AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
 
 232                 /* Set AR5K_PHY_SETTLING */
 
 233                 ath5k_hw_reg_write(ah, ah->ah_turbo ?
 
 234                         (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
 
 236                         (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
 
 239                 /* Set Frame Control Register */
 
 240                 ath5k_hw_reg_write(ah, ah->ah_turbo ?
 
 241                         (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
 
 242                         AR5K_PHY_TURBO_SHORT | 0x2020) :
 
 243                         (AR5K_PHY_FRAME_CTL_INI | 0x1020),
 
 244                         AR5K_PHY_FRAME_CTL_5210);
 
 248          * Calculate cwmin/max by channel mode
 
 250         cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
 
 251         cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
 
 252         ah->ah_aifs = AR5K_TUNE_AIFS;
 
 253         /*XR is only supported on 5212*/
 
 254         if (IS_CHAN_XR(ah->ah_current_channel) &&
 
 255                         ah->ah_version == AR5K_AR5212) {
 
 256                 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
 
 257                 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
 
 258                 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
 
 259         /*B mode is not supported on 5210*/
 
 260         } else if (IS_CHAN_B(ah->ah_current_channel) &&
 
 261                         ah->ah_version != AR5K_AR5210) {
 
 262                 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
 
 263                 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
 
 264                 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
 
 268         while (cw_min < ah->ah_cw_min)
 
 269                 cw_min = (cw_min << 1) | 1;
 
 271         cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
 
 272                 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
 
 273         cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
 
 274                 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
 
 277          * Calculate and set retry limits
 
 279         if (ah->ah_software_retry) {
 
 280                 /* XXX Need to test this */
 
 281                 retry_lg = ah->ah_limit_tx_retries;
 
 282                 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
 
 283                         AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
 
 285                 retry_lg = AR5K_INIT_LG_RETRY;
 
 286                 retry_sh = AR5K_INIT_SH_RETRY;
 
 289         /*No QCU/DCU [5210]*/
 
 290         if (ah->ah_version == AR5K_AR5210) {
 
 291                 ath5k_hw_reg_write(ah,
 
 292                         (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
 
 293                         | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
 
 294                                 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
 
 295                         | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
 
 296                                 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
 
 297                         | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
 
 298                         | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
 
 299                         AR5K_NODCU_RETRY_LMT);
 
 302                 ath5k_hw_reg_write(ah,
 
 303                         AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
 
 304                                 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
 
 305                         AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
 
 306                                 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
 
 307                         AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
 
 308                         AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
 
 309                         AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
 
 311         /*===Rest is also for QCU/DCU only [5211+]===*/
 
 314                  * Set initial content window (cw_min/cw_max)
 
 315                  * and arbitrated interframe space (aifs)...
 
 317                 ath5k_hw_reg_write(ah,
 
 318                         AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
 
 319                         AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
 
 320                         AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
 
 321                                 AR5K_DCU_LCL_IFS_AIFS),
 
 322                         AR5K_QUEUE_DFS_LOCAL_IFS(queue));
 
 327                 ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
 
 328                         AR5K_QUEUE_MISC(queue));
 
 330                 if (tq->tqi_cbr_period) {
 
 331                         ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
 
 332                                 AR5K_QCU_CBRCFG_INTVAL) |
 
 333                                 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
 
 334                                 AR5K_QCU_CBRCFG_ORN_THRES),
 
 335                                 AR5K_QUEUE_CBRCFG(queue));
 
 336                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
 
 337                                 AR5K_QCU_MISC_FRSHED_CBR);
 
 338                         if (tq->tqi_cbr_overflow_limit)
 
 339                                 AR5K_REG_ENABLE_BITS(ah,
 
 340                                         AR5K_QUEUE_MISC(queue),
 
 341                                         AR5K_QCU_MISC_CBR_THRES_ENABLE);
 
 344                 if (tq->tqi_ready_time)
 
 345                         ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
 
 346                                 AR5K_QCU_RDYTIMECFG_INTVAL) |
 
 347                                 AR5K_QCU_RDYTIMECFG_ENABLE,
 
 348                                 AR5K_QUEUE_RDYTIMECFG(queue));
 
 350                 if (tq->tqi_burst_time) {
 
 351                         ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
 
 352                                 AR5K_DCU_CHAN_TIME_DUR) |
 
 353                                 AR5K_DCU_CHAN_TIME_ENABLE,
 
 354                                 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
 
 357                         & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
 
 358                                 AR5K_REG_ENABLE_BITS(ah,
 
 359                                         AR5K_QUEUE_MISC(queue),
 
 360                                         AR5K_QCU_MISC_RDY_VEOL_POLICY);
 
 363                 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
 
 364                         ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
 
 365                                 AR5K_QUEUE_DFS_MISC(queue));
 
 367                 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
 
 368                         ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
 
 369                                 AR5K_QUEUE_DFS_MISC(queue));
 
 372                  * Set registers by queue type
 
 374                 switch (tq->tqi_type) {
 
 375                 case AR5K_TX_QUEUE_BEACON:
 
 376                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
 
 377                                 AR5K_QCU_MISC_FRSHED_DBA_GT |
 
 378                                 AR5K_QCU_MISC_CBREXP_BCN_DIS |
 
 379                                 AR5K_QCU_MISC_BCN_ENABLE);
 
 381                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
 
 382                                 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
 
 383                                 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
 
 384                                 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
 
 385                                 AR5K_DCU_MISC_BCN_ENABLE);
 
 387                         ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
 
 388                                 (AR5K_TUNE_SW_BEACON_RESP -
 
 389                                 AR5K_TUNE_DMA_BEACON_RESP) -
 
 390                                 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
 
 391                                 AR5K_QCU_RDYTIMECFG_ENABLE,
 
 392                                 AR5K_QUEUE_RDYTIMECFG(queue));
 
 395                 case AR5K_TX_QUEUE_CAB:
 
 396                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
 
 397                                 AR5K_QCU_MISC_FRSHED_DBA_GT |
 
 398                                 AR5K_QCU_MISC_CBREXP_DIS |
 
 399                                 AR5K_QCU_MISC_CBREXP_BCN_DIS);
 
 401                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
 
 402                                 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
 
 403                                 AR5K_DCU_MISC_ARBLOCK_CTL_S));
 
 406                 case AR5K_TX_QUEUE_UAPSD:
 
 407                         AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
 
 408                                 AR5K_QCU_MISC_CBREXP_DIS);
 
 411                 case AR5K_TX_QUEUE_DATA:
 
 417                  * Enable interrupts for this tx queue
 
 418                  * in the secondary interrupt mask registers
 
 420                 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
 
 421                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
 
 423                 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
 
 424                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
 
 426                 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
 
 427                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
 
 429                 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
 
 430                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
 
 432                 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
 
 433                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
 
 435                 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
 
 436                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
 
 438                 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
 
 439                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
 
 441                 if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
 
 442                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
 
 444                 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
 
 445                         AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
 
 447                 /* Update secondary interrupt mask registers */
 
 449                 /* Filter out inactive queues */
 
 450                 ah->ah_txq_imr_txok &= ah->ah_txq_status;
 
 451                 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
 
 452                 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
 
 453                 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
 
 454                 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
 
 455                 ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
 
 456                 ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
 
 457                 ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
 
 458                 ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
 
 460                 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
 
 461                         AR5K_SIMR0_QCU_TXOK) |
 
 462                         AR5K_REG_SM(ah->ah_txq_imr_txdesc,
 
 463                         AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
 
 464                 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
 
 465                         AR5K_SIMR1_QCU_TXERR) |
 
 466                         AR5K_REG_SM(ah->ah_txq_imr_txeol,
 
 467                         AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
 
 468                 /* Update simr2 but don't overwrite rest simr2 settings */
 
 469                 AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
 
 470                 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
 
 471                         AR5K_REG_SM(ah->ah_txq_imr_txurn,
 
 472                         AR5K_SIMR2_QCU_TXURN));
 
 473                 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
 
 474                         AR5K_SIMR3_QCBRORN) |
 
 475                         AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
 
 476                         AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
 
 477                 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
 
 478                         AR5K_SIMR4_QTRIG), AR5K_SIMR4);
 
 479                 /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
 
 480                 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
 
 481                         AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
 
 482                 /* No queue has TXNOFRM enabled, disable the interrupt
 
 483                  * by setting AR5K_TXNOFRM to zero */
 
 484                 if (ah->ah_txq_imr_nofrm == 0)
 
 485                         ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
 
 492  * Get slot time from DCU
 
 494 unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
 
 496         ATH5K_TRACE(ah->ah_sc);
 
 497         if (ah->ah_version == AR5K_AR5210)
 
 498                 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
 
 499                                 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
 
 501                 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
 
 505  * Set slot time on DCU
 
 507 int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
 
 509         ATH5K_TRACE(ah->ah_sc);
 
 510         if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
 
 513         if (ah->ah_version == AR5K_AR5210)
 
 514                 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
 
 515                                 ah->ah_turbo), AR5K_SLOT_TIME);
 
 517                 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);