914 lines · c
1/*2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>4 *5 * Permission to use, copy, modify, and distribute this software for any6 * purpose with or without fee is hereby granted, provided that the above7 * copyright notice and this permission notice appear in all copies.8 *9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16 *17 */18 19/*************************************\20* DMA and interrupt masking functions *21\*************************************/22 23/**24 * DOC: DMA and interrupt masking functions25 *26 * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and27 * handle queue setup for 5210 chipset (rest are handled on qcu.c).28 * Also we setup interrupt mask register (IMR) and read the various interrupt29 * status registers (ISR).30 */31 32#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt33 34#include "ath5k.h"35#include "reg.h"36#include "debug.h"37 38 39/*********\40* Receive *41\*********/42 43/**44 * ath5k_hw_start_rx_dma() - Start DMA receive45 * @ah: The &struct ath5k_hw46 */47void48ath5k_hw_start_rx_dma(struct ath5k_hw *ah)49{50 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);51 ath5k_hw_reg_read(ah, AR5K_CR);52}53 54/**55 * ath5k_hw_stop_rx_dma() - Stop DMA receive56 * @ah: The &struct ath5k_hw57 */58static int59ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)60{61 unsigned int i;62 63 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);64 65 /*66 * It may take some time to disable the DMA receive unit67 */68 for (i = 1000; i > 0 &&69 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;70 i--)71 udelay(100);72 73 if (!i)74 ATH5K_DBG(ah, ATH5K_DEBUG_DMA,75 "failed to stop RX DMA !\n");76 77 return i ? 0 : -EBUSY;78}79 80/**81 * ath5k_hw_get_rxdp() - Get RX Descriptor's address82 * @ah: The &struct ath5k_hw83 */84u3285ath5k_hw_get_rxdp(struct ath5k_hw *ah)86{87 return ath5k_hw_reg_read(ah, AR5K_RXDP);88}89 90/**91 * ath5k_hw_set_rxdp() - Set RX Descriptor's address92 * @ah: The &struct ath5k_hw93 * @phys_addr: RX descriptor address94 *95 * Returns -EIO if rx is active96 */97int98ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)99{100 if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) {101 ATH5K_DBG(ah, ATH5K_DEBUG_DMA,102 "tried to set RXDP while rx was active !\n");103 return -EIO;104 }105 106 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);107 return 0;108}109 110 111/**********\112* Transmit *113\**********/114 115/**116 * ath5k_hw_start_tx_dma() - Start DMA transmit for a specific queue117 * @ah: The &struct ath5k_hw118 * @queue: The hw queue number119 *120 * Start DMA transmit for a specific queue and since 5210 doesn't have121 * QCU/DCU, set up queue parameters for 5210 here based on queue type (one122 * queue for normal data and one queue for beacons). For queue setup123 * on newer chips check out qcu.c. Returns -EINVAL if queue number is out124 * of range or if queue is already disabled.125 *126 * NOTE: Must be called after setting up tx control descriptor for that127 * queue (see below).128 */129int130ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)131{132 u32 tx_queue;133 134 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);135 136 /* Return if queue is declared inactive */137 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)138 return -EINVAL;139 140 if (ah->ah_version == AR5K_AR5210) {141 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);142 143 /*144 * Set the queue by type on 5210145 */146 switch (ah->ah_txq[queue].tqi_type) {147 case AR5K_TX_QUEUE_DATA:148 tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;149 break;150 case AR5K_TX_QUEUE_BEACON:151 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;152 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,153 AR5K_BSR);154 break;155 case AR5K_TX_QUEUE_CAB:156 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;157 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |158 AR5K_BCR_BDMAE, AR5K_BSR);159 break;160 default:161 return -EINVAL;162 }163 /* Start queue */164 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);165 ath5k_hw_reg_read(ah, AR5K_CR);166 } else {167 /* Return if queue is disabled */168 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))169 return -EIO;170 171 /* Start queue */172 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);173 }174 175 return 0;176}177 178/**179 * ath5k_hw_stop_tx_dma() - Stop DMA transmit on a specific queue180 * @ah: The &struct ath5k_hw181 * @queue: The hw queue number182 *183 * Stop DMA transmit on a specific hw queue and drain queue so we don't184 * have any pending frames. Returns -EBUSY if we still have pending frames,185 * -EINVAL if queue number is out of range or inactive.186 */187static int188ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)189{190 unsigned int i = 40;191 u32 tx_queue, pending;192 193 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);194 195 /* Return if queue is declared inactive */196 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)197 return -EINVAL;198 199 if (ah->ah_version == AR5K_AR5210) {200 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);201 202 /*203 * Set by queue type204 */205 switch (ah->ah_txq[queue].tqi_type) {206 case AR5K_TX_QUEUE_DATA:207 tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;208 break;209 case AR5K_TX_QUEUE_BEACON:210 case AR5K_TX_QUEUE_CAB:211 /* XXX Fix me... */212 tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;213 ath5k_hw_reg_write(ah, 0, AR5K_BSR);214 break;215 default:216 return -EINVAL;217 }218 219 /* Stop queue */220 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);221 ath5k_hw_reg_read(ah, AR5K_CR);222 } else {223 224 /*225 * Enable DCU early termination to quickly226 * flush any pending frames from QCU227 */228 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),229 AR5K_QCU_MISC_DCU_EARLY);230 231 /*232 * Schedule TX disable and wait until queue is empty233 */234 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);235 236 /* Wait for queue to stop */237 for (i = 1000; i > 0 &&238 (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0);239 i--)240 udelay(100);241 242 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))243 ATH5K_DBG(ah, ATH5K_DEBUG_DMA,244 "queue %i didn't stop !\n", queue);245 246 /* Check for pending frames */247 i = 1000;248 do {249 pending = ath5k_hw_reg_read(ah,250 AR5K_QUEUE_STATUS(queue)) &251 AR5K_QCU_STS_FRMPENDCNT;252 udelay(100);253 } while (--i && pending);254 255 /* For 2413+ order PCU to drop packets using256 * QUIET mechanism */257 if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&258 pending) {259 /* Set periodicity and duration */260 ath5k_hw_reg_write(ah,261 AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|262 AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),263 AR5K_QUIET_CTL2);264 265 /* Enable quiet period for current TSF */266 ath5k_hw_reg_write(ah,267 AR5K_QUIET_CTL1_QT_EN |268 AR5K_REG_SM(ath5k_hw_reg_read(ah,269 AR5K_TSF_L32_5211) >> 10,270 AR5K_QUIET_CTL1_NEXT_QT_TSF),271 AR5K_QUIET_CTL1);272 273 /* Force channel idle high */274 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,275 AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);276 277 /* Wait a while and disable mechanism */278 udelay(400);279 AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,280 AR5K_QUIET_CTL1_QT_EN);281 282 /* Re-check for pending frames */283 i = 100;284 do {285 pending = ath5k_hw_reg_read(ah,286 AR5K_QUEUE_STATUS(queue)) &287 AR5K_QCU_STS_FRMPENDCNT;288 udelay(100);289 } while (--i && pending);290 291 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,292 AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);293 294 if (pending)295 ATH5K_DBG(ah, ATH5K_DEBUG_DMA,296 "quiet mechanism didn't work q:%i !\n",297 queue);298 }299 300 /*301 * Disable DCU early termination302 */303 AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue),304 AR5K_QCU_MISC_DCU_EARLY);305 306 /* Clear register */307 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);308 if (pending) {309 ATH5K_DBG(ah, ATH5K_DEBUG_DMA,310 "tx dma didn't stop (q:%i, frm:%i) !\n",311 queue, pending);312 return -EBUSY;313 }314 }315 316 /* TODO: Check for success on 5210 else return error */317 return 0;318}319 320/**321 * ath5k_hw_stop_beacon_queue() - Stop beacon queue322 * @ah: The &struct ath5k_hw323 * @queue: The queue number324 *325 * Returns -EIO if queue didn't stop326 */327int328ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue)329{330 int ret;331 ret = ath5k_hw_stop_tx_dma(ah, queue);332 if (ret) {333 ATH5K_DBG(ah, ATH5K_DEBUG_DMA,334 "beacon queue didn't stop !\n");335 return -EIO;336 }337 return 0;338}339 340/**341 * ath5k_hw_get_txdp() - Get TX Descriptor's address for a specific queue342 * @ah: The &struct ath5k_hw343 * @queue: The hw queue number344 *345 * Get TX descriptor's address for a specific queue. For 5210 we ignore346 * the queue number and use tx queue type since we only have 2 queues.347 * We use TXDP0 for normal data queue and TXDP1 for beacon queue.348 * For newer chips with QCU/DCU we just read the corresponding TXDP register.349 *350 * XXX: Is TXDP read and clear ?351 */352u32353ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)354{355 u16 tx_reg;356 357 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);358 359 /*360 * Get the transmit queue descriptor pointer from the selected queue361 */362 /*5210 doesn't have QCU*/363 if (ah->ah_version == AR5K_AR5210) {364 switch (ah->ah_txq[queue].tqi_type) {365 case AR5K_TX_QUEUE_DATA:366 tx_reg = AR5K_NOQCU_TXDP0;367 break;368 case AR5K_TX_QUEUE_BEACON:369 case AR5K_TX_QUEUE_CAB:370 tx_reg = AR5K_NOQCU_TXDP1;371 break;372 default:373 return 0xffffffff;374 }375 } else {376 tx_reg = AR5K_QUEUE_TXDP(queue);377 }378 379 return ath5k_hw_reg_read(ah, tx_reg);380}381 382/**383 * ath5k_hw_set_txdp() - Set TX Descriptor's address for a specific queue384 * @ah: The &struct ath5k_hw385 * @queue: The hw queue number386 * @phys_addr: The physical address387 *388 * Set TX descriptor's address for a specific queue. For 5210 we ignore389 * the queue number and we use tx queue type since we only have 2 queues390 * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue.391 * For newer chips with QCU/DCU we just set the corresponding TXDP register.392 * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still393 * active.394 */395int396ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)397{398 u16 tx_reg;399 400 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);401 402 /*403 * Set the transmit queue descriptor pointer register by type404 * on 5210405 */406 if (ah->ah_version == AR5K_AR5210) {407 switch (ah->ah_txq[queue].tqi_type) {408 case AR5K_TX_QUEUE_DATA:409 tx_reg = AR5K_NOQCU_TXDP0;410 break;411 case AR5K_TX_QUEUE_BEACON:412 case AR5K_TX_QUEUE_CAB:413 tx_reg = AR5K_NOQCU_TXDP1;414 break;415 default:416 return -EINVAL;417 }418 } else {419 /*420 * Set the transmit queue descriptor pointer for421 * the selected queue on QCU for 5211+422 * (this won't work if the queue is still active)423 */424 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))425 return -EIO;426 427 tx_reg = AR5K_QUEUE_TXDP(queue);428 }429 430 /* Set descriptor pointer */431 ath5k_hw_reg_write(ah, phys_addr, tx_reg);432 433 return 0;434}435 436/**437 * ath5k_hw_update_tx_triglevel() - Update tx trigger level438 * @ah: The &struct ath5k_hw439 * @increase: Flag to force increase of trigger level440 *441 * This function increases/decreases the tx trigger level for the tx fifo442 * buffer (aka FIFO threshold) that is used to indicate when PCU flushes443 * the buffer and transmits its data. Lowering this results sending small444 * frames more quickly but can lead to tx underruns, raising it a lot can445 * result other problems. Right now we start with the lowest possible446 * (64Bytes) and if we get tx underrun we increase it using the increase447 * flag. Returns -EIO if we have reached maximum/minimum.448 *449 * XXX: Link this with tx DMA size ?450 * XXX2: Use it to save interrupts ?451 */452int453ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)454{455 u32 trigger_level, imr;456 int ret = -EIO;457 458 /*459 * Disable interrupts by setting the mask460 */461 imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);462 463 trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),464 AR5K_TXCFG_TXFULL);465 466 if (!increase) {467 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)468 goto done;469 } else470 trigger_level +=471 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);472 473 /*474 * Update trigger level on success475 */476 if (ah->ah_version == AR5K_AR5210)477 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);478 else479 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,480 AR5K_TXCFG_TXFULL, trigger_level);481 482 ret = 0;483 484done:485 /*486 * Restore interrupt mask487 */488 ath5k_hw_set_imr(ah, imr);489 490 return ret;491}492 493 494/*******************\495* Interrupt masking *496\*******************/497 498/**499 * ath5k_hw_is_intr_pending() - Check if we have pending interrupts500 * @ah: The &struct ath5k_hw501 *502 * Check if we have pending interrupts to process. Returns 1 if we503 * have pending interrupts and 0 if we haven't.504 */505bool506ath5k_hw_is_intr_pending(struct ath5k_hw *ah)507{508 return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;509}510 511/**512 * ath5k_hw_get_isr() - Get interrupt status513 * @ah: The @struct ath5k_hw514 * @interrupt_mask: Driver's interrupt mask used to filter out515 * interrupts in sw.516 *517 * This function is used inside our interrupt handler to determine the reason518 * for the interrupt by reading Primary Interrupt Status Register. Returns an519 * abstract interrupt status mask which is mostly ISR with some uncommon bits520 * being mapped on some standard non hw-specific positions521 * (check out &ath5k_int).522 *523 * NOTE: We do write-to-clear, so the active PISR/SISR bits at the time this524 * function gets called are cleared on return.525 */526int527ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)528{529 u32 data = 0;530 531 /*532 * Read interrupt status from Primary Interrupt533 * Register.534 *535 * Note: PISR/SISR Not available on 5210536 */537 if (ah->ah_version == AR5K_AR5210) {538 u32 isr = 0;539 isr = ath5k_hw_reg_read(ah, AR5K_ISR);540 if (unlikely(isr == AR5K_INT_NOCARD)) {541 *interrupt_mask = isr;542 return -ENODEV;543 }544 545 /*546 * Filter out the non-common bits from the interrupt547 * status.548 */549 *interrupt_mask = (isr & AR5K_INT_COMMON) & ah->ah_imr;550 551 /* Hanlde INT_FATAL */552 if (unlikely(isr & (AR5K_ISR_SSERR | AR5K_ISR_MCABT553 | AR5K_ISR_DPERR)))554 *interrupt_mask |= AR5K_INT_FATAL;555 556 /*557 * XXX: BMISS interrupts may occur after association.558 * I found this on 5210 code but it needs testing. If this is559 * true we should disable them before assoc and re-enable them560 * after a successful assoc + some jiffies.561 interrupt_mask &= ~AR5K_INT_BMISS;562 */563 564 data = isr;565 } else {566 u32 pisr = 0;567 u32 pisr_clear = 0;568 u32 sisr0 = 0;569 u32 sisr1 = 0;570 u32 sisr2 = 0;571 u32 sisr3 = 0;572 u32 sisr4 = 0;573 574 /* Read PISR and SISRs... */575 pisr = ath5k_hw_reg_read(ah, AR5K_PISR);576 if (unlikely(pisr == AR5K_INT_NOCARD)) {577 *interrupt_mask = pisr;578 return -ENODEV;579 }580 581 sisr0 = ath5k_hw_reg_read(ah, AR5K_SISR0);582 sisr1 = ath5k_hw_reg_read(ah, AR5K_SISR1);583 sisr2 = ath5k_hw_reg_read(ah, AR5K_SISR2);584 sisr3 = ath5k_hw_reg_read(ah, AR5K_SISR3);585 sisr4 = ath5k_hw_reg_read(ah, AR5K_SISR4);586 587 /*588 * PISR holds the logical OR of interrupt bits589 * from SISR registers:590 *591 * TXOK and TXDESC -> Logical OR of TXOK and TXDESC592 * per-queue bits on SISR0593 *594 * TXERR and TXEOL -> Logical OR of TXERR and TXEOL595 * per-queue bits on SISR1596 *597 * TXURN -> Logical OR of TXURN per-queue bits on SISR2598 *599 * HIUERR -> Logical OR of MCABT, SSERR and DPER bits on SISR2600 *601 * BCNMISC -> Logical OR of TIM, CAB_END, DTIM_SYNC602 * BCN_TIMEOUT, CAB_TIMEOUT and DTIM603 * (and TSFOOR ?) bits on SISR2604 *605 * QCBRORN and QCBRURN -> Logical OR of QCBRORN and606 * QCBRURN per-queue bits on SISR3607 * QTRIG -> Logical OR of QTRIG per-queue bits on SISR4608 *609 * If we clean these bits on PISR we 'll also clear all610 * related bits from SISRs, e.g. if we write the TXOK bit on611 * PISR we 'll clean all TXOK bits from SISR0 so if a new TXOK612 * interrupt got fired for another queue while we were reading613 * the interrupt registers and we write back the TXOK bit on614 * PISR we 'll lose it. So make sure that we don't write back615 * on PISR any bits that come from SISRs. Clearing them from616 * SISRs will also clear PISR so no need to worry here.617 */618 619 /* XXX: There seems to be an issue on some cards620 * with tx interrupt flags not being updated621 * on PISR despite that all Tx interrupt bits622 * are cleared on SISRs. Since we handle all623 * Tx queues all together it shouldn't be an624 * issue if we clear Tx interrupt flags also625 * on PISR to avoid that.626 */627 pisr_clear = (pisr & ~AR5K_ISR_BITS_FROM_SISRS) |628 (pisr & AR5K_INT_TX_ALL);629 630 /*631 * Write to clear them...632 * Note: This means that each bit we write back633 * to the registers will get cleared, leaving the634 * rest unaffected. So this won't affect new interrupts635 * we didn't catch while reading/processing, we 'll get636 * them next time get_isr gets called.637 */638 ath5k_hw_reg_write(ah, sisr0, AR5K_SISR0);639 ath5k_hw_reg_write(ah, sisr1, AR5K_SISR1);640 ath5k_hw_reg_write(ah, sisr2, AR5K_SISR2);641 ath5k_hw_reg_write(ah, sisr3, AR5K_SISR3);642 ath5k_hw_reg_write(ah, sisr4, AR5K_SISR4);643 ath5k_hw_reg_write(ah, pisr_clear, AR5K_PISR);644 /* Flush previous write */645 ath5k_hw_reg_read(ah, AR5K_PISR);646 647 /*648 * Filter out the non-common bits from the interrupt649 * status.650 */651 *interrupt_mask = (pisr & AR5K_INT_COMMON) & ah->ah_imr;652 653 ah->ah_txq_isr_txok_all = 0;654 655 /* We treat TXOK,TXDESC, TXERR and TXEOL656 * the same way (schedule the tx tasklet)657 * so we track them all together per queue */658 if (pisr & AR5K_ISR_TXOK)659 ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr0,660 AR5K_SISR0_QCU_TXOK);661 662 if (pisr & AR5K_ISR_TXDESC)663 ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr0,664 AR5K_SISR0_QCU_TXDESC);665 666 if (pisr & AR5K_ISR_TXERR)667 ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr1,668 AR5K_SISR1_QCU_TXERR);669 670 if (pisr & AR5K_ISR_TXEOL)671 ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr1,672 AR5K_SISR1_QCU_TXEOL);673 674 /* Misc Beacon related interrupts */675 676 /* For AR5211 */677 if (pisr & AR5K_ISR_TIM)678 *interrupt_mask |= AR5K_INT_TIM;679 680 /* For AR5212+ */681 if (pisr & AR5K_ISR_BCNMISC) {682 if (sisr2 & AR5K_SISR2_TIM)683 *interrupt_mask |= AR5K_INT_TIM;684 if (sisr2 & AR5K_SISR2_DTIM)685 *interrupt_mask |= AR5K_INT_DTIM;686 if (sisr2 & AR5K_SISR2_DTIM_SYNC)687 *interrupt_mask |= AR5K_INT_DTIM_SYNC;688 if (sisr2 & AR5K_SISR2_BCN_TIMEOUT)689 *interrupt_mask |= AR5K_INT_BCN_TIMEOUT;690 if (sisr2 & AR5K_SISR2_CAB_TIMEOUT)691 *interrupt_mask |= AR5K_INT_CAB_TIMEOUT;692 }693 694 /* Below interrupts are unlikely to happen */695 696 /* HIU = Host Interface Unit (PCI etc)697 * Can be one of MCABT, SSERR, DPERR from SISR2 */698 if (unlikely(pisr & (AR5K_ISR_HIUERR)))699 *interrupt_mask |= AR5K_INT_FATAL;700 701 /*Beacon Not Ready*/702 if (unlikely(pisr & (AR5K_ISR_BNR)))703 *interrupt_mask |= AR5K_INT_BNR;704 705 /* A queue got CBR overrun */706 if (unlikely(pisr & (AR5K_ISR_QCBRORN)))707 *interrupt_mask |= AR5K_INT_QCBRORN;708 709 /* A queue got CBR underrun */710 if (unlikely(pisr & (AR5K_ISR_QCBRURN)))711 *interrupt_mask |= AR5K_INT_QCBRURN;712 713 /* A queue got triggered */714 if (unlikely(pisr & (AR5K_ISR_QTRIG)))715 *interrupt_mask |= AR5K_INT_QTRIG;716 717 data = pisr;718 }719 720 /*721 * In case we didn't handle anything,722 * print the register value.723 */724 if (unlikely(*interrupt_mask == 0 && net_ratelimit()))725 ATH5K_PRINTF("ISR: 0x%08x IMR: 0x%08x\n", data, ah->ah_imr);726 727 return 0;728}729 730/**731 * ath5k_hw_set_imr() - Set interrupt mask732 * @ah: The &struct ath5k_hw733 * @new_mask: The new interrupt mask to be set734 *735 * Set the interrupt mask in hw to save interrupts. We do that by mapping736 * ath5k_int bits to hw-specific bits to remove abstraction and writing737 * Interrupt Mask Register.738 */739enum ath5k_int740ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)741{742 enum ath5k_int old_mask, int_mask;743 744 old_mask = ah->ah_imr;745 746 /*747 * Disable card interrupts to prevent any race conditions748 * (they will be re-enabled afterwards if AR5K_INT GLOBAL749 * is set again on the new mask).750 */751 if (old_mask & AR5K_INT_GLOBAL) {752 ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);753 ath5k_hw_reg_read(ah, AR5K_IER);754 }755 756 /*757 * Add additional, chipset-dependent interrupt mask flags758 * and write them to the IMR (interrupt mask register).759 */760 int_mask = new_mask & AR5K_INT_COMMON;761 762 if (ah->ah_version != AR5K_AR5210) {763 /* Preserve per queue TXURN interrupt mask */764 u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2)765 & AR5K_SIMR2_QCU_TXURN;766 767 /* Fatal interrupt abstraction for 5211+ */768 if (new_mask & AR5K_INT_FATAL) {769 int_mask |= AR5K_IMR_HIUERR;770 simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR771 | AR5K_SIMR2_DPERR);772 }773 774 /* Misc beacon related interrupts */775 if (new_mask & AR5K_INT_TIM)776 int_mask |= AR5K_IMR_TIM;777 778 if (new_mask & AR5K_INT_TIM)779 simr2 |= AR5K_SISR2_TIM;780 if (new_mask & AR5K_INT_DTIM)781 simr2 |= AR5K_SISR2_DTIM;782 if (new_mask & AR5K_INT_DTIM_SYNC)783 simr2 |= AR5K_SISR2_DTIM_SYNC;784 if (new_mask & AR5K_INT_BCN_TIMEOUT)785 simr2 |= AR5K_SISR2_BCN_TIMEOUT;786 if (new_mask & AR5K_INT_CAB_TIMEOUT)787 simr2 |= AR5K_SISR2_CAB_TIMEOUT;788 789 /*Beacon Not Ready*/790 if (new_mask & AR5K_INT_BNR)791 int_mask |= AR5K_INT_BNR;792 793 /* Note: Per queue interrupt masks794 * are set via ath5k_hw_reset_tx_queue() (qcu.c) */795 ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);796 ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);797 798 } else {799 /* Fatal interrupt abstraction for 5210 */800 if (new_mask & AR5K_INT_FATAL)801 int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT802 | AR5K_IMR_HIUERR | AR5K_IMR_DPERR);803 804 /* Only common interrupts left for 5210 (no SIMRs) */805 ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);806 }807 808 /* If RXNOFRM interrupt is masked disable it809 * by setting AR5K_RXNOFRM to zero */810 if (!(new_mask & AR5K_INT_RXNOFRM))811 ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM);812 813 /* Store new interrupt mask */814 ah->ah_imr = new_mask;815 816 /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */817 if (new_mask & AR5K_INT_GLOBAL) {818 ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);819 ath5k_hw_reg_read(ah, AR5K_IER);820 }821 822 return old_mask;823}824 825 826/********************\827 Init/Stop functions828\********************/829 830/**831 * ath5k_hw_dma_init() - Initialize DMA unit832 * @ah: The &struct ath5k_hw833 *834 * Set DMA size and pre-enable interrupts835 * (driver handles tx/rx buffer setup and836 * dma start/stop)837 *838 * XXX: Save/restore RXDP/TXDP registers ?839 */840void841ath5k_hw_dma_init(struct ath5k_hw *ah)842{843 /*844 * Set Rx/Tx DMA Configuration845 *846 * Set standard DMA size (128). Note that847 * a DMA size of 512 causes rx overruns and tx errors848 * on pci-e cards (tested on 5424 but since rx overruns849 * also occur on 5416/5418 with madwifi we set 128850 * for all PCI-E cards to be safe).851 *852 * XXX: need to check 5210 for this853 * TODO: Check out tx trigger level, it's always 64 on dumps but I854 * guess we can tweak it and see how it goes ;-)855 */856 if (ah->ah_version != AR5K_AR5210) {857 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,858 AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);859 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,860 AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);861 }862 863 /* Pre-enable interrupts on 5211/5212*/864 if (ah->ah_version != AR5K_AR5210)865 ath5k_hw_set_imr(ah, ah->ah_imr);866 867}868 869/**870 * ath5k_hw_dma_stop() - stop DMA unit871 * @ah: The &struct ath5k_hw872 *873 * Stop tx/rx DMA and interrupts. Returns874 * -EBUSY if tx or rx dma failed to stop.875 *876 * XXX: Sometimes DMA unit hangs and we have877 * stuck frames on tx queues, only a reset878 * can fix that.879 */880int881ath5k_hw_dma_stop(struct ath5k_hw *ah)882{883 int i, qmax, err;884 err = 0;885 886 /* Disable interrupts */887 ath5k_hw_set_imr(ah, 0);888 889 /* Stop rx dma */890 err = ath5k_hw_stop_rx_dma(ah);891 if (err)892 return err;893 894 /* Clear any pending interrupts895 * and disable tx dma */896 if (ah->ah_version != AR5K_AR5210) {897 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);898 qmax = AR5K_NUM_TX_QUEUES;899 } else {900 /* PISR/SISR Not available on 5210 */901 ath5k_hw_reg_read(ah, AR5K_ISR);902 qmax = AR5K_NUM_TX_QUEUES_NOQCU;903 }904 905 for (i = 0; i < qmax; i++) {906 err = ath5k_hw_stop_tx_dma(ah, i);907 /* -EINVAL -> queue inactive */908 if (err && err != -EINVAL)909 return err;910 }911 912 return 0;913}914