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/ar5211/ar5211_recv.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-2008 Sam Leffler, Errno Consulting
    5  * Copyright (c) 2002-2006 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 "ar5211/ar5211.h"
   28 #include "ar5211/ar5211reg.h"
   29 #include "ar5211/ar5211desc.h"
   30 
   31 /*
   32  * Get the RXDP.
   33  */
   34 uint32_t
   35 ar5211GetRxDP(struct ath_hal *ah, HAL_RX_QUEUE qtype)
   36 {
   37 
   38         HALASSERT(qtype == HAL_RX_QUEUE_HP);
   39         return OS_REG_READ(ah, AR_RXDP);
   40 }
   41 
   42 /*
   43  * Set the RxDP.
   44  */
   45 void
   46 ar5211SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype)
   47 {
   48 
   49         HALASSERT(qtype == HAL_RX_QUEUE_HP);
   50         OS_REG_WRITE(ah, AR_RXDP, rxdp);
   51         HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp);
   52 }
   53 
   54 /*
   55  * Set Receive Enable bits.
   56  */
   57 void
   58 ar5211EnableReceive(struct ath_hal *ah)
   59 {
   60         OS_REG_WRITE(ah, AR_CR, AR_CR_RXE);
   61 }
   62 
   63 /*
   64  * Stop Receive at the DMA engine
   65  */
   66 HAL_BOOL
   67 ar5211StopDmaReceive(struct ath_hal *ah)
   68 {
   69         OS_REG_WRITE(ah, AR_CR, AR_CR_RXD);     /* Set receive disable bit */
   70         if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) {
   71 #ifdef AH_DEBUG
   72                 ath_hal_printf(ah, "%s failed to stop in 10ms\n"
   73                                    "AR_CR=0x%08X\nAR_DIAG_SW=0x%08X\n"
   74                                    , __func__
   75                                    , OS_REG_READ(ah, AR_CR)
   76                                    , OS_REG_READ(ah, AR_DIAG_SW)
   77                 );
   78 #endif
   79                 return AH_FALSE;
   80         } else {
   81                 return AH_TRUE;
   82         }
   83 }
   84 
   85 /*
   86  * Start Transmit at the PCU engine (unpause receive)
   87  */
   88 void
   89 ar5211StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
   90 {
   91         OS_REG_WRITE(ah, AR_DIAG_SW,
   92                 OS_REG_READ(ah, AR_DIAG_SW) & ~(AR_DIAG_SW_DIS_RX));
   93 }
   94 
   95 /*
   96  * Stop Transmit at the PCU engine (pause receive)
   97  */
   98 void
   99 ar5211StopPcuReceive(struct ath_hal *ah)
  100 {
  101         OS_REG_WRITE(ah, AR_DIAG_SW,
  102                 OS_REG_READ(ah, AR_DIAG_SW) | AR_DIAG_SW_DIS_RX);
  103 }
  104 
  105 /*
  106  * Set multicast filter 0 (lower 32-bits)
  107  *                         filter 1 (upper 32-bits)
  108  */
  109 void
  110 ar5211SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1)
  111 {
  112         OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0);
  113         OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1);
  114 }
  115 
  116 /*
  117  * Clear multicast filter by index
  118  */
  119 HAL_BOOL
  120 ar5211ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
  121 {
  122         uint32_t val;
  123 
  124         if (ix >= 64)
  125                 return AH_FALSE;
  126         if (ix >= 32) {
  127                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
  128                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32))));
  129         } else {
  130                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
  131                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<<ix)));
  132         }
  133         return AH_TRUE;
  134 }
  135 
  136 /*
  137  * Set multicast filter by index
  138  */
  139 HAL_BOOL
  140 ar5211SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix)
  141 {
  142         uint32_t val;
  143 
  144         if (ix >= 64)
  145                 return AH_FALSE;
  146         if (ix >= 32) {
  147                 val = OS_REG_READ(ah, AR_MCAST_FIL1);
  148                 OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32))));
  149         } else {
  150                 val = OS_REG_READ(ah, AR_MCAST_FIL0);
  151                 OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<<ix)));
  152         }
  153         return AH_TRUE;
  154 }
  155 
  156 /*
  157  * Get receive filter.
  158  */
  159 uint32_t
  160 ar5211GetRxFilter(struct ath_hal *ah)
  161 {
  162         return OS_REG_READ(ah, AR_RX_FILTER);
  163 }
  164 
  165 /*
  166  * Set receive filter.
  167  */
  168 void
  169 ar5211SetRxFilter(struct ath_hal *ah, uint32_t bits)
  170 {
  171         OS_REG_WRITE(ah, AR_RX_FILTER, bits);
  172 }
  173 
  174 /*
  175  * Initialize RX descriptor, by clearing the status and clearing
  176  * the size.  This is not strictly HW dependent, but we want the
  177  * control and status words to be opaque above the hal.
  178  */
  179 HAL_BOOL
  180 ar5211SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
  181         uint32_t size, u_int flags)
  182 {
  183         struct ar5211_desc *ads = AR5211DESC(ds);
  184 
  185         ads->ds_ctl0 = 0;
  186         ads->ds_ctl1 = size & AR_BufLen;
  187         if (ads->ds_ctl1 != size) {
  188                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: buffer size %u too large\n",
  189                     __func__, size);
  190                 return AH_FALSE;
  191         }
  192         if (flags & HAL_RXDESC_INTREQ)
  193                 ads->ds_ctl1 |= AR_RxInterReq;
  194         ads->ds_status0 = ads->ds_status1 = 0;
  195 
  196         return AH_TRUE;
  197 }
  198 
  199 /*
  200  * Process an RX descriptor, and return the status to the caller.
  201  * Copy some hardware specific items into the software portion
  202  * of the descriptor.
  203  *
  204  * NB: the caller is responsible for validating the memory contents
  205  *     of the descriptor (e.g. flushing any cached copy).
  206  */
  207 HAL_STATUS
  208 ar5211ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
  209         uint32_t pa, struct ath_desc *nds, uint64_t tsf,
  210         struct ath_rx_status *rs)
  211 {
  212         struct ar5211_desc *ads = AR5211DESC(ds);
  213         struct ar5211_desc *ands = AR5211DESC(nds);
  214 
  215         if ((ads->ds_status1 & AR_Done) == 0)
  216                 return HAL_EINPROGRESS;
  217         /*
  218          * Given the use of a self-linked tail be very sure that the hw is
  219          * done with this descriptor; the hw may have done this descriptor
  220          * once and picked it up again...make sure the hw has moved on.
  221          */
  222         if ((ands->ds_status1 & AR_Done) == 0 && OS_REG_READ(ah, AR_RXDP) == pa)
  223                 return HAL_EINPROGRESS;
  224 
  225         rs->rs_datalen = ads->ds_status0 & AR_DataLen;
  226         rs->rs_tstamp = MS(ads->ds_status1, AR_RcvTimestamp);
  227         rs->rs_status = 0;
  228         if ((ads->ds_status1 & AR_FrmRcvOK) == 0) {
  229                 if (ads->ds_status1 & AR_CRCErr)
  230                         rs->rs_status |= HAL_RXERR_CRC;
  231                 else if (ads->ds_status1 & AR_DecryptCRCErr)
  232                         rs->rs_status |= HAL_RXERR_DECRYPT;
  233                 else {
  234                         rs->rs_status |= HAL_RXERR_PHY;
  235                         rs->rs_phyerr = MS(ads->ds_status1, AR_PHYErr);
  236                 }
  237         }
  238         /* XXX what about KeyCacheMiss? */
  239         rs->rs_rssi = MS(ads->ds_status0, AR_RcvSigStrength);
  240         if (ads->ds_status1 & AR_KeyIdxValid)
  241                 rs->rs_keyix = MS(ads->ds_status1, AR_KeyIdx);
  242         else
  243                 rs->rs_keyix = HAL_RXKEYIX_INVALID;
  244         /* NB: caller expected to do rate table mapping */
  245         rs->rs_rate = MS(ads->ds_status0, AR_RcvRate);
  246         rs->rs_antenna  = MS(ads->ds_status0, AR_RcvAntenna);
  247         rs->rs_more = (ads->ds_status0 & AR_More) ? 1 : 0;
  248 
  249         return HAL_OK;
  250 }

Cache object: e4addd18abf7f6e424ac4d3467889228


[ 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.