The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ath/ath_hal/ar5210/ar5210_xmit.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: ISC
    3  *
    4  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
    5  * Copyright (c) 2002-2004 Atheros Communications, Inc.
    6  *
    7  * Permission to use, copy, modify, and/or distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  *
   19  * $FreeBSD$
   20  */
   21 #include "opt_ah.h"
   22 
   23 #include "ah.h"
   24 #include "ah_internal.h"
   25 #include "ah_desc.h"
   26 
   27 #include "ar5210/ar5210.h"
   28 #include "ar5210/ar5210reg.h"
   29 #include "ar5210/ar5210phy.h"
   30 #include "ar5210/ar5210desc.h"
   31 
   32 /*
   33  * Set the properties of the tx queue with the parameters
   34  * from qInfo.  The queue must previously have been setup
   35  * with a call to ar5210SetupTxQueue.
   36  */
   37 HAL_BOOL
   38 ar5210SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo)
   39 {
   40         struct ath_hal_5210 *ahp = AH5210(ah);
   41 
   42         if (q >= HAL_NUM_TX_QUEUES) {
   43                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
   44                     __func__, q);
   45                 return AH_FALSE;
   46         }
   47         return ath_hal_setTxQProps(ah, &ahp->ah_txq[q], qInfo);
   48 }
   49 
   50 /*
   51  * Return the properties for the specified tx queue.
   52  */
   53 HAL_BOOL
   54 ar5210GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo)
   55 {
   56         struct ath_hal_5210 *ahp = AH5210(ah);
   57 
   58         if (q >= HAL_NUM_TX_QUEUES) {
   59                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
   60                     __func__, q);
   61                 return AH_FALSE;
   62         }
   63         return ath_hal_getTxQProps(ah, qInfo, &ahp->ah_txq[q]);
   64 }
   65 
   66 /*
   67  * Allocate and initialize a tx DCU/QCU combination.
   68  */
   69 int
   70 ar5210SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type,
   71         const HAL_TXQ_INFO *qInfo)
   72 {
   73         struct ath_hal_5210 *ahp = AH5210(ah);
   74         HAL_TX_QUEUE_INFO *qi;
   75         int q;
   76 
   77         switch (type) {
   78         case HAL_TX_QUEUE_BEACON:
   79                 q = 2;
   80                 break;
   81         case HAL_TX_QUEUE_CAB:
   82                 q = 1;
   83                 break;
   84         case HAL_TX_QUEUE_DATA:
   85                 q = 0;
   86                 break;
   87         default:
   88                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad tx queue type %u\n",
   89                     __func__, type);
   90                 return -1;
   91         }
   92 
   93         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
   94 
   95         qi = &ahp->ah_txq[q];
   96         if (qi->tqi_type != HAL_TX_QUEUE_INACTIVE) {
   97                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: tx queue %u already active\n",
   98                     __func__, q);
   99                 return -1;
  100         }
  101         OS_MEMZERO(qi, sizeof(HAL_TX_QUEUE_INFO));
  102         qi->tqi_type = type;
  103         if (qInfo == AH_NULL) {
  104                 /* by default enable OK+ERR+DESC+URN interrupts */
  105                 qi->tqi_qflags =
  106                           HAL_TXQ_TXOKINT_ENABLE
  107                         | HAL_TXQ_TXERRINT_ENABLE
  108                         | HAL_TXQ_TXDESCINT_ENABLE
  109                         | HAL_TXQ_TXURNINT_ENABLE
  110                         ;
  111                 qi->tqi_aifs = INIT_AIFS;
  112                 qi->tqi_cwmin = HAL_TXQ_USEDEFAULT;     /* NB: do at reset */
  113                 qi->tqi_shretry = INIT_SH_RETRY;
  114                 qi->tqi_lgretry = INIT_LG_RETRY;
  115         } else
  116                 (void) ar5210SetTxQueueProps(ah, q, qInfo);
  117         /* NB: must be followed by ar5210ResetTxQueue */
  118         return q;
  119 }
  120 
  121 /*
  122  * Free a tx DCU/QCU combination.
  123  */
  124 HAL_BOOL
  125 ar5210ReleaseTxQueue(struct ath_hal *ah, u_int q)
  126 {
  127         struct ath_hal_5210 *ahp = AH5210(ah);
  128         HAL_TX_QUEUE_INFO *qi;
  129 
  130         if (q >= HAL_NUM_TX_QUEUES) {
  131                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
  132                     __func__, q);
  133                 return AH_FALSE;
  134         }
  135         qi = &ahp->ah_txq[q];
  136         if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
  137                 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
  138                     __func__, q);
  139                 return AH_FALSE;
  140         }
  141 
  142         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: release queue %u\n", __func__, q);
  143 
  144         qi->tqi_type = HAL_TX_QUEUE_INACTIVE;
  145         ahp->ah_txOkInterruptMask &= ~(1 << q);
  146         ahp->ah_txErrInterruptMask &= ~(1 << q);
  147         ahp->ah_txDescInterruptMask &= ~(1 << q);
  148         ahp->ah_txEolInterruptMask &= ~(1 << q);
  149         ahp->ah_txUrnInterruptMask &= ~(1 << q);
  150 
  151         return AH_TRUE;
  152 #undef N
  153 }
  154 
  155 HAL_BOOL
  156 ar5210ResetTxQueue(struct ath_hal *ah, u_int q)
  157 {
  158         struct ath_hal_5210 *ahp = AH5210(ah);
  159         const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
  160         HAL_TX_QUEUE_INFO *qi;
  161         uint32_t cwMin;
  162 
  163         if (q >= HAL_NUM_TX_QUEUES) {
  164                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
  165                     __func__, q);
  166                 return AH_FALSE;
  167         }
  168         qi = &ahp->ah_txq[q];
  169         if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
  170                 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
  171                     __func__, q);
  172                 return AH_FALSE;
  173         }
  174 
  175         /*
  176          * Ignore any non-data queue(s).
  177          */
  178         if (qi->tqi_type != HAL_TX_QUEUE_DATA)
  179                 return AH_TRUE;
  180 
  181         /* Set turbo mode / base mode parameters on or off */
  182         if (IEEE80211_IS_CHAN_TURBO(chan)) {
  183                 OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME_TURBO);
  184                 OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT_TURBO);
  185                 OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY_TURBO);
  186                 OS_REG_WRITE(ah, AR_IFS0, 
  187                         ((INIT_SIFS_TURBO + qi->tqi_aifs * INIT_SLOT_TIME_TURBO)
  188                                 << AR_IFS0_DIFS_S)
  189                         | INIT_SIFS_TURBO);
  190                 OS_REG_WRITE(ah, AR_IFS1, INIT_PROTO_TIME_CNTRL_TURBO);
  191                 OS_REG_WRITE(ah, AR_PHY(17),
  192                         (OS_REG_READ(ah, AR_PHY(17)) & ~0x7F) | 0x38);
  193                 OS_REG_WRITE(ah, AR_PHY_FRCTL,
  194                         AR_PHY_SERVICE_ERR | AR_PHY_TXURN_ERR |
  195                         AR_PHY_ILLLEN_ERR | AR_PHY_ILLRATE_ERR |
  196                         AR_PHY_PARITY_ERR | AR_PHY_TIMING_ERR |
  197                         0x2020 |
  198                         AR_PHY_TURBO_MODE | AR_PHY_TURBO_SHORT);
  199         } else {
  200                 OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME);
  201                 OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT);
  202                 OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY);
  203                 OS_REG_WRITE(ah, AR_IFS0, 
  204                         ((INIT_SIFS + qi->tqi_aifs * INIT_SLOT_TIME)
  205                                 << AR_IFS0_DIFS_S)
  206                         | INIT_SIFS);
  207                 OS_REG_WRITE(ah, AR_IFS1, INIT_PROTO_TIME_CNTRL);
  208                 OS_REG_WRITE(ah, AR_PHY(17),
  209                         (OS_REG_READ(ah, AR_PHY(17)) & ~0x7F) | 0x1C);
  210                 OS_REG_WRITE(ah, AR_PHY_FRCTL,
  211                         AR_PHY_SERVICE_ERR | AR_PHY_TXURN_ERR |
  212                         AR_PHY_ILLLEN_ERR | AR_PHY_ILLRATE_ERR |
  213                         AR_PHY_PARITY_ERR | AR_PHY_TIMING_ERR | 0x1020);
  214         }
  215 
  216         if (qi->tqi_cwmin == HAL_TXQ_USEDEFAULT)
  217                 cwMin = INIT_CWMIN;
  218         else
  219                 cwMin = qi->tqi_cwmin;
  220 
  221         /* Set cwmin and retry limit values */
  222         OS_REG_WRITE(ah, AR_RETRY_LMT, 
  223                   (cwMin << AR_RETRY_LMT_CW_MIN_S)
  224                  | SM(INIT_SLG_RETRY, AR_RETRY_LMT_SLG_RETRY)
  225                  | SM(INIT_SSH_RETRY, AR_RETRY_LMT_SSH_RETRY)
  226                  | SM(qi->tqi_lgretry, AR_RETRY_LMT_LG_RETRY)
  227                  | SM(qi->tqi_shretry, AR_RETRY_LMT_SH_RETRY)
  228         );
  229 
  230         if (qi->tqi_qflags & HAL_TXQ_TXOKINT_ENABLE)
  231                 ahp->ah_txOkInterruptMask |= 1 << q;
  232         else
  233                 ahp->ah_txOkInterruptMask &= ~(1 << q);
  234         if (qi->tqi_qflags & HAL_TXQ_TXERRINT_ENABLE)
  235                 ahp->ah_txErrInterruptMask |= 1 << q;
  236         else
  237                 ahp->ah_txErrInterruptMask &= ~(1 << q);
  238         if (qi->tqi_qflags & HAL_TXQ_TXDESCINT_ENABLE)
  239                 ahp->ah_txDescInterruptMask |= 1 << q;
  240         else
  241                 ahp->ah_txDescInterruptMask &= ~(1 << q);
  242         if (qi->tqi_qflags & HAL_TXQ_TXEOLINT_ENABLE)
  243                 ahp->ah_txEolInterruptMask |= 1 << q;
  244         else
  245                 ahp->ah_txEolInterruptMask &= ~(1 << q);
  246         if (qi->tqi_qflags & HAL_TXQ_TXURNINT_ENABLE)
  247                 ahp->ah_txUrnInterruptMask |= 1 << q;
  248         else
  249                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
  250 
  251         return AH_TRUE;
  252 }
  253 
  254 /*
  255  * Get the TXDP for the "main" data queue.  Needs to be extended
  256  * for multiple Q functionality
  257  */
  258 uint32_t
  259 ar5210GetTxDP(struct ath_hal *ah, u_int q)
  260 {
  261         struct ath_hal_5210 *ahp = AH5210(ah);
  262         HAL_TX_QUEUE_INFO *qi;
  263 
  264         HALASSERT(q < HAL_NUM_TX_QUEUES);
  265 
  266         qi = &ahp->ah_txq[q];
  267         switch (qi->tqi_type) {
  268         case HAL_TX_QUEUE_DATA:
  269                 return OS_REG_READ(ah, AR_TXDP0);
  270         case HAL_TX_QUEUE_INACTIVE:
  271                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: inactive queue %u\n",
  272                     __func__, q);
  273                 /* fall thru... */
  274         default:
  275                 break;
  276         }
  277         return 0xffffffff;
  278 }
  279 
  280 /*
  281  * Set the TxDP for the "main" data queue.
  282  */
  283 HAL_BOOL
  284 ar5210SetTxDP(struct ath_hal *ah, u_int q, uint32_t txdp)
  285 {
  286         struct ath_hal_5210 *ahp = AH5210(ah);
  287         HAL_TX_QUEUE_INFO *qi;
  288 
  289         HALASSERT(q < HAL_NUM_TX_QUEUES);
  290 
  291         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u 0x%x\n",
  292             __func__, q, txdp);
  293         qi = &ahp->ah_txq[q];
  294         switch (qi->tqi_type) {
  295         case HAL_TX_QUEUE_DATA:
  296 #ifdef AH_DEBUG
  297                 /*
  298                  * Make sure that TXE is deasserted before setting the
  299                  * TXDP.  If TXE is still asserted, setting TXDP will
  300                  * have no effect.
  301                  */
  302                 if (OS_REG_READ(ah, AR_CR) & AR_CR_TXE0)
  303                         ath_hal_printf(ah, "%s: TXE asserted; AR_CR=0x%x\n",
  304                                 __func__, OS_REG_READ(ah, AR_CR));
  305 #endif
  306                 OS_REG_WRITE(ah, AR_TXDP0, txdp);
  307                 break;
  308         case HAL_TX_QUEUE_BEACON:
  309         case HAL_TX_QUEUE_CAB:
  310                 OS_REG_WRITE(ah, AR_TXDP1, txdp);
  311                 break;
  312         case HAL_TX_QUEUE_INACTIVE:
  313                 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
  314                     __func__, q);
  315                 /* fall thru... */
  316         default:
  317                 return AH_FALSE;
  318         }
  319         return AH_TRUE;
  320 }
  321 
  322 /*
  323  * Update Tx FIFO trigger level.
  324  *
  325  * Set bIncTrigLevel to TRUE to increase the trigger level.
  326  * Set bIncTrigLevel to FALSE to decrease the trigger level.
  327  *
  328  * Returns TRUE if the trigger level was updated
  329  */
  330 HAL_BOOL
  331 ar5210UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
  332 {
  333         uint32_t curTrigLevel;
  334         HAL_INT ints = ar5210GetInterrupts(ah);
  335 
  336         /*
  337          * Disable chip interrupts. This is because halUpdateTxTrigLevel
  338          * is called from both ISR and non-ISR contexts.
  339          */
  340         (void) ar5210SetInterrupts(ah, ints &~ HAL_INT_GLOBAL);
  341         curTrigLevel = OS_REG_READ(ah, AR_TRIG_LEV);
  342         if (bIncTrigLevel){
  343                 /* increase the trigger level */
  344                 curTrigLevel = curTrigLevel +
  345                         ((MAX_TX_FIFO_THRESHOLD - curTrigLevel) / 2);
  346         } else {
  347                 /* decrease the trigger level if not already at the minimum */
  348                 if (curTrigLevel > MIN_TX_FIFO_THRESHOLD) {
  349                         /* decrease the trigger level */
  350                         curTrigLevel--;
  351                 } else {
  352                         /* no update to the trigger level */
  353                         /* re-enable chip interrupts */
  354                         ar5210SetInterrupts(ah, ints);
  355                         return AH_FALSE;
  356                 }
  357         }
  358         /* Update the trigger level */
  359         OS_REG_WRITE(ah, AR_TRIG_LEV, curTrigLevel);
  360         /* re-enable chip interrupts */
  361         ar5210SetInterrupts(ah, ints);
  362         return AH_TRUE;
  363 }
  364 
  365 /*
  366  * Set Transmit Enable bits for the specified queues.
  367  */
  368 HAL_BOOL
  369 ar5210StartTxDma(struct ath_hal *ah, u_int q)
  370 {
  371         struct ath_hal_5210 *ahp = AH5210(ah);
  372         HAL_TX_QUEUE_INFO *qi;
  373 
  374         HALASSERT(q < HAL_NUM_TX_QUEUES);
  375 
  376         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
  377         qi = &ahp->ah_txq[q];
  378         switch (qi->tqi_type) {
  379         case HAL_TX_QUEUE_DATA:
  380                 OS_REG_WRITE(ah, AR_CR, AR_CR_TXE0);
  381                 break;
  382         case HAL_TX_QUEUE_CAB:
  383                 OS_REG_WRITE(ah, AR_CR, AR_CR_TXE1);    /* enable altq xmit */
  384                 OS_REG_WRITE(ah, AR_BCR,
  385                         AR_BCR_TQ1V | AR_BCR_BDMAE | AR_BCR_TQ1FV);
  386                 break;
  387         case HAL_TX_QUEUE_BEACON:
  388                 /* XXX add CR_BCR_BCMD if IBSS mode */
  389                 OS_REG_WRITE(ah, AR_BCR, AR_BCR_TQ1V | AR_BCR_BDMAE);
  390                 break;
  391         case HAL_TX_QUEUE_INACTIVE:
  392                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: inactive queue %u\n",
  393                     __func__, q);
  394                 /* fal thru... */
  395         default:
  396                 return AH_FALSE;
  397         }
  398         return AH_TRUE;
  399 }
  400 
  401 uint32_t
  402 ar5210NumTxPending(struct ath_hal *ah, u_int q)
  403 {
  404         struct ath_hal_5210 *ahp = AH5210(ah);
  405         HAL_TX_QUEUE_INFO *qi;
  406         uint32_t v;
  407 
  408         HALASSERT(q < HAL_NUM_TX_QUEUES);
  409 
  410         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
  411         qi = &ahp->ah_txq[q];
  412         switch (qi->tqi_type) {
  413         case HAL_TX_QUEUE_DATA:
  414                 v = OS_REG_READ(ah, AR_CFG);
  415                 return MS(v, AR_CFG_TXCNT);
  416         case HAL_TX_QUEUE_INACTIVE:
  417                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: inactive queue %u\n",
  418                     __func__, q);
  419                 /* fall thru... */
  420         default:
  421                 break;
  422         }
  423         return 0;
  424 }
  425 
  426 /*
  427  * Stop transmit on the specified queue
  428  */
  429 HAL_BOOL
  430 ar5210StopTxDma(struct ath_hal *ah, u_int q)
  431 {
  432         struct ath_hal_5210 *ahp = AH5210(ah);
  433         HAL_TX_QUEUE_INFO *qi;
  434 
  435         HALASSERT(q < HAL_NUM_TX_QUEUES);
  436 
  437         HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
  438         qi = &ahp->ah_txq[q];
  439         switch (qi->tqi_type) {
  440         case HAL_TX_QUEUE_DATA: {
  441                 int i;
  442                 OS_REG_WRITE(ah, AR_CR, AR_CR_TXD0);
  443                 for (i = 0; i < 1000; i++) {
  444                         if ((OS_REG_READ(ah, AR_CFG) & AR_CFG_TXCNT) == 0)
  445                                 break;
  446                         OS_DELAY(10);
  447                 }
  448                 OS_REG_WRITE(ah, AR_CR, 0);
  449                 return (i < 1000);
  450         }
  451         case HAL_TX_QUEUE_BEACON:
  452                 return ath_hal_wait(ah, AR_BSR, AR_BSR_TXQ1F, 0);
  453         case HAL_TX_QUEUE_INACTIVE:
  454                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: inactive queue %u\n",
  455                     __func__, q);
  456                 /* fall thru... */
  457         default:
  458                 break;
  459         }
  460         return AH_FALSE;
  461 }
  462 
  463 /*
  464  * Descriptor Access Functions
  465  */
  466 
  467 #define VALID_PKT_TYPES \
  468         ((1<<HAL_PKT_TYPE_NORMAL)|(1<<HAL_PKT_TYPE_ATIM)|\
  469          (1<<HAL_PKT_TYPE_PSPOLL)|(1<<HAL_PKT_TYPE_PROBE_RESP)|\
  470          (1<<HAL_PKT_TYPE_BEACON))
  471 #define isValidPktType(_t)      ((1<<(_t)) & VALID_PKT_TYPES)
  472 #define VALID_TX_RATES \
  473         ((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\
  474          (1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\
  475          (1<<0x1d)|(1<<0x18)|(1<<0x1c))
  476 #define isValidTxRate(_r)       ((1<<(_r)) & VALID_TX_RATES)
  477 
  478 HAL_BOOL
  479 ar5210SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
  480         u_int pktLen,
  481         u_int hdrLen,
  482         HAL_PKT_TYPE type,
  483         u_int txPower,
  484         u_int txRate0, u_int txTries0,
  485         u_int keyIx,
  486         u_int antMode,
  487         u_int flags,
  488         u_int rtsctsRate,
  489         u_int rtsctsDuration,
  490         u_int compicvLen,
  491         u_int compivLen,
  492         u_int comp)
  493 {
  494         struct ar5210_desc *ads = AR5210DESC(ds);
  495         uint32_t frtype;
  496 
  497         (void) txPower;
  498         (void) rtsctsDuration;
  499 
  500         HALASSERT(txTries0 != 0);
  501         HALASSERT(isValidPktType(type));
  502         HALASSERT(isValidTxRate(txRate0));
  503 
  504         if (type == HAL_PKT_TYPE_BEACON || type == HAL_PKT_TYPE_PROBE_RESP)
  505                 frtype = AR_Frm_NoDelay;
  506         else
  507                 frtype = type << 26;
  508         ads->ds_ctl0 = (pktLen & AR_FrameLen)
  509                      | (txRate0 << AR_XmitRate_S)
  510                      | ((hdrLen << AR_HdrLen_S) & AR_HdrLen)
  511                      | frtype
  512                      | (flags & HAL_TXDESC_CLRDMASK ? AR_ClearDestMask : 0)
  513                      | (flags & HAL_TXDESC_INTREQ ? AR_TxInterReq : 0)
  514                      | (antMode ? AR_AntModeXmit : 0)
  515                      ;
  516         if (keyIx != HAL_TXKEYIX_INVALID) {
  517                 ads->ds_ctl1 = (keyIx << AR_EncryptKeyIdx_S) & AR_EncryptKeyIdx;
  518                 ads->ds_ctl0 |= AR_EncryptKeyValid;
  519         } else
  520                 ads->ds_ctl1 = 0;
  521         if (flags & HAL_TXDESC_RTSENA) {
  522                 ads->ds_ctl0 |= AR_RTSCTSEnable;
  523                 ads->ds_ctl1 |= (rtsctsDuration << AR_RTSDuration_S)
  524                     & AR_RTSDuration;
  525         }
  526         return AH_TRUE;
  527 }
  528 
  529 HAL_BOOL
  530 ar5210SetupXTxDesc(struct ath_hal *ah, struct ath_desc *ds,
  531         u_int txRate1, u_int txTries1,
  532         u_int txRate2, u_int txTries2,
  533         u_int txRate3, u_int txTries3)
  534 {
  535         (void) ah; (void) ds;
  536         (void) txRate1; (void) txTries1;
  537         (void) txRate2; (void) txTries2;
  538         (void) txRate3; (void) txTries3;
  539         return AH_FALSE;
  540 }
  541 
  542 void
  543 ar5210IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *ds)
  544 {
  545         struct ar5210_desc *ads = AR5210DESC(ds);
  546 
  547         ads->ds_ctl0 |= AR_TxInterReq;
  548 }
  549 
  550 HAL_BOOL
  551 ar5210FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
  552         HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId,
  553         u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg,
  554         const struct ath_desc *ds0)
  555 {
  556         struct ar5210_desc *ads = AR5210DESC(ds);
  557         uint32_t segLen = segLenList[0];
  558 
  559         HALASSERT((segLen &~ AR_BufLen) == 0);
  560 
  561         ds->ds_data = bufAddrList[0];
  562 
  563         if (firstSeg) {
  564                 /*
  565                  * First descriptor, don't clobber xmit control data
  566                  * setup by ar5210SetupTxDesc.
  567                  */
  568                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_More);
  569         } else if (lastSeg) {           /* !firstSeg && lastSeg */
  570                 /*
  571                  * Last descriptor in a multi-descriptor frame,
  572                  * copy the transmit parameters from the first
  573                  * frame for processing on completion. 
  574                  */
  575                 ads->ds_ctl0 = AR5210DESC_CONST(ds0)->ds_ctl0;
  576                 ads->ds_ctl1 = segLen;
  577         } else {                        /* !firstSeg && !lastSeg */
  578                 /*
  579                  * Intermediate descriptor in a multi-descriptor frame.
  580                  */
  581                 ads->ds_ctl0 = 0;
  582                 ads->ds_ctl1 = segLen | AR_More;
  583         }
  584         ads->ds_status0 = ads->ds_status1 = 0;
  585         return AH_TRUE;
  586 }
  587 
  588 /*
  589  * Processing of HW TX descriptor.
  590  */
  591 HAL_STATUS
  592 ar5210ProcTxDesc(struct ath_hal *ah,
  593         struct ath_desc *ds, struct ath_tx_status *ts)
  594 {
  595         struct ar5210_desc *ads = AR5210DESC(ds);
  596 
  597         if ((ads->ds_status1 & AR_Done) == 0)
  598                 return HAL_EINPROGRESS;
  599 
  600         /* Update software copies of the HW status */
  601         ts->ts_seqnum = ads->ds_status1 & AR_SeqNum;
  602         ts->ts_tstamp = MS(ads->ds_status0, AR_SendTimestamp);
  603         ts->ts_status = 0;
  604         if ((ads->ds_status0 & AR_FrmXmitOK) == 0) {
  605                 if (ads->ds_status0 & AR_ExcessiveRetries)
  606                         ts->ts_status |= HAL_TXERR_XRETRY;
  607                 if (ads->ds_status0 & AR_Filtered)
  608                         ts->ts_status |= HAL_TXERR_FILT;
  609                 if (ads->ds_status0  & AR_FIFOUnderrun)
  610                         ts->ts_status |= HAL_TXERR_FIFO;
  611         }
  612         ts->ts_rate = MS(ads->ds_ctl0, AR_XmitRate);
  613         ts->ts_rssi = MS(ads->ds_status1, AR_AckSigStrength);
  614         ts->ts_shortretry = MS(ads->ds_status0, AR_ShortRetryCnt);
  615         ts->ts_longretry = MS(ads->ds_status0, AR_LongRetryCnt);
  616         ts->ts_antenna = 0;             /* NB: don't know */
  617         ts->ts_finaltsi = 0;
  618 
  619         return HAL_OK;
  620 }
  621 
  622 /*
  623  * Determine which tx queues need interrupt servicing.
  624  * STUB.
  625  */
  626 void
  627 ar5210GetTxIntrQueue(struct ath_hal *ah, uint32_t *txqs)
  628 {
  629         return;
  630 }
  631 
  632 /*
  633  * Retrieve the rate table from the given TX completion descriptor
  634  */
  635 HAL_BOOL
  636 ar5210GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
  637 {
  638         return AH_FALSE;
  639 }
  640 
  641 /*
  642  * Set the TX descriptor link pointer
  643  */
  644 void
  645 ar5210SetTxDescLink(struct ath_hal *ah, void *ds, uint32_t link)
  646 {
  647         struct ar5210_desc *ads = AR5210DESC(ds);
  648 
  649         ads->ds_link = link;
  650 }
  651 
  652 /*
  653  * Get the TX descriptor link pointer
  654  */
  655 void
  656 ar5210GetTxDescLink(struct ath_hal *ah, void *ds, uint32_t *link)
  657 {
  658         struct ar5210_desc *ads = AR5210DESC(ds);
  659 
  660         *link = ads->ds_link;
  661 }
  662 
  663 /*
  664  * Get a pointer to the TX descriptor link pointer
  665  */
  666 void
  667 ar5210GetTxDescLinkPtr(struct ath_hal *ah, void *ds, uint32_t **linkptr)
  668 {
  669         struct ar5210_desc *ads = AR5210DESC(ds);
  670 
  671         *linkptr = &ads->ds_link;
  672 }

Cache object: d7f68de85b2d568f3d248ae914f214fd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.