bd572555c47fa7296550f5390b6f1caadcbc318c
[dragonfly.git] / sys / dev / netif / ath / hal / ath_hal / ar5416 / ar5416_recv.c
1 /*
2  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3  * Copyright (c) 2002-2008 Atheros Communications, Inc.
4  *
5  * Permission to use, copy, modify, and/or 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.
8  *
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.
16  *
17  * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c 203158 2010-01-29 10:07:17Z rpaulo $
18  * $DragonFly$
19  */
20 #include "opt_ah.h"
21
22 #include "ah.h"
23 #include "ah_desc.h"
24 #include "ah_internal.h"
25
26 #include "ar5416/ar5416.h"
27 #include "ar5416/ar5416reg.h"
28 #include "ar5416/ar5416desc.h"
29
30 /*
31  * Start receive at the PCU engine
32  */
33 void
34 ar5416StartPcuReceive(struct ath_hal *ah)
35 {
36         struct ath_hal_private *ahp = AH_PRIVATE(ah);
37
38         HALDEBUG(ah, HAL_DEBUG_RX, "%s: Start PCU Receive \n", __func__);
39         ar5212EnableMibCounters(ah);
40         /* NB: restore current settings */
41         ar5416AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE);
42         /*
43          * NB: must do after enabling phy errors to avoid rx
44          *     frames w/ corrupted descriptor status.
45          */
46         OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
47 }
48
49 /*
50  * Stop receive at the PCU engine
51  * and abort current frame in PCU
52  */
53 void
54 ar5416StopPcuReceive(struct ath_hal *ah)
55 {
56         OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT);
57     
58         HALDEBUG(ah, HAL_DEBUG_RX, "%s: Stop PCU Receive \n", __func__);
59         ar5212DisableMibCounters(ah);
60 }
61
62 /*
63  * Initialize RX descriptor, by clearing the status and setting
64  * the size (and any other flags).
65  */
66 HAL_BOOL
67 ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
68     uint32_t size, u_int flags)
69 {
70         struct ar5416_desc *ads = AR5416DESC(ds);
71
72         HALASSERT((size &~ AR_BufLen) == 0);
73
74         ads->ds_ctl1 = size & AR_BufLen;
75         if (flags & HAL_RXDESC_INTREQ)
76                 ads->ds_ctl1 |= AR_RxIntrReq;
77
78         /* this should be enough */
79         ads->ds_rxstatus8 &= ~AR_RxDone;
80
81         return AH_TRUE;
82 }
83
84 /*
85  * Process an RX descriptor, and return the status to the caller.
86  * Copy some hardware specific items into the software portion
87  * of the descriptor.
88  *
89  * NB: the caller is responsible for validating the memory contents
90  *     of the descriptor (e.g. flushing any cached copy).
91  */
92 HAL_STATUS
93 ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
94     uint32_t pa, struct ath_desc *nds, uint64_t tsf,
95     struct ath_rx_status *rs)
96 {
97         struct ar5416_desc *ads = AR5416DESC(ds);
98         struct ar5416_desc *ands = AR5416DESC(nds);
99
100         if ((ads->ds_rxstatus8 & AR_RxDone) == 0)
101                 return HAL_EINPROGRESS;
102         /*
103          * Given the use of a self-linked tail be very sure that the hw is
104          * done with this descriptor; the hw may have done this descriptor
105          * once and picked it up again...make sure the hw has moved on.
106          */
107         if ((ands->ds_rxstatus8 & AR_RxDone) == 0
108             && OS_REG_READ(ah, AR_RXDP) == pa)
109                 return HAL_EINPROGRESS;
110
111         rs->rs_status = 0;
112         rs->rs_flags = 0;
113
114         rs->rs_datalen = ads->ds_rxstatus1 & AR_DataLen;
115         rs->rs_tstamp =  ads->AR_RcvTimestamp;
116
117         /* XXX what about KeyCacheMiss? */
118
119         rs->rs_rssi = MS(ads->ds_rxstatus4, AR_RxRSSICombined);
120         rs->rs_rssi_ctl[0] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt00);
121         rs->rs_rssi_ctl[1] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt01);
122         rs->rs_rssi_ctl[2] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt02);
123         rs->rs_rssi_ext[0] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt10);
124         rs->rs_rssi_ext[1] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt11);
125         rs->rs_rssi_ext[2] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt12);
126
127         if (ads->ds_rxstatus8 & AR_RxKeyIdxValid)
128                 rs->rs_keyix = MS(ads->ds_rxstatus8, AR_KeyIdx);
129         else
130                 rs->rs_keyix = HAL_RXKEYIX_INVALID;
131
132         /* NB: caller expected to do rate table mapping */
133         rs->rs_rate = RXSTATUS_RATE(ah, ads);
134         rs->rs_more = (ads->ds_rxstatus1 & AR_RxMore) ? 1 : 0;
135
136         rs->rs_isaggr = (ads->ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
137         rs->rs_moreaggr = (ads->ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
138         rs->rs_antenna = MS(ads->ds_rxstatus3, AR_RxAntenna);
139
140         if (ads->ds_rxstatus3 & AR_GI)
141                 rs->rs_flags |= HAL_RX_GI;
142         if (ads->ds_rxstatus3 & AR_2040)
143                 rs->rs_flags |= HAL_RX_2040;
144
145         if (ads->ds_rxstatus8 & AR_PreDelimCRCErr)
146                 rs->rs_flags |= HAL_RX_DELIM_CRC_PRE;
147         if (ads->ds_rxstatus8 & AR_PostDelimCRCErr)
148                 rs->rs_flags |= HAL_RX_DELIM_CRC_POST;
149         if (ads->ds_rxstatus8 & AR_DecryptBusyErr)
150                 rs->rs_flags |= HAL_RX_DECRYPT_BUSY;
151         if (ads->ds_rxstatus8 & AR_HiRxChain)
152                 rs->rs_flags |= HAL_RX_HI_RX_CHAIN;
153
154         if ((ads->ds_rxstatus8 & AR_RxFrameOK) == 0) {
155                 /*
156                  * These four bits should not be set together.  The
157                  * 5416 spec states a Michael error can only occur if
158                  * DecryptCRCErr not set (and TKIP is used).  Experience
159                  * indicates however that you can also get Michael errors
160                  * when a CRC error is detected, but these are specious.
161                  * Consequently we filter them out here so we don't
162                  * confuse and/or complicate drivers.
163                  */
164                 if (ads->ds_rxstatus8 & AR_CRCErr)
165                         rs->rs_status |= HAL_RXERR_CRC;
166                 else if (ads->ds_rxstatus8 & AR_PHYErr) {
167                         u_int phyerr;
168
169                         rs->rs_status |= HAL_RXERR_PHY;
170                         phyerr = MS(ads->ds_rxstatus8, AR_PHYErrCode);
171                         rs->rs_phyerr = phyerr;
172                 } else if (ads->ds_rxstatus8 & AR_DecryptCRCErr)
173                         rs->rs_status |= HAL_RXERR_DECRYPT;
174                 else if (ads->ds_rxstatus8 & AR_MichaelErr)
175                         rs->rs_status |= HAL_RXERR_MIC;
176         }
177
178         return HAL_OK;
179 }