FreeBSD kernel ATH device code
ar5416_recv.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: ISC
3 *
4 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
5 * Copyright (c) 2002-2008 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_desc.h"
25#include "ah_internal.h"
26
27#include "ar5416/ar5416.h"
28#include "ar5416/ar5416reg.h"
29#include "ar5416/ar5416desc.h"
30
31/*
32 * Get the receive filter.
33 */
34uint32_t
36{
37 uint32_t bits = OS_REG_READ(ah, AR_RX_FILTER);
38 uint32_t phybits = OS_REG_READ(ah, AR_PHY_ERR);
39
40 if (phybits & AR_PHY_ERR_RADAR)
44 return bits;
45}
46
47/*
48 * Set the receive filter.
49 */
50void
51ar5416SetRxFilter(struct ath_hal *ah, u_int32_t bits)
52{
53 uint32_t phybits;
54
55 OS_REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff));
56 phybits = 0;
57 if (bits & HAL_RX_FILTER_PHYRADAR)
58 phybits |= AR_PHY_ERR_RADAR;
59 if (bits & HAL_RX_FILTER_PHYERR)
61 OS_REG_WRITE(ah, AR_PHY_ERR, phybits);
62 if (phybits) {
65 } else {
68 }
69}
70
71/*
72 * Stop Receive at the DMA engine
73 */
76{
77 HAL_BOOL status;
78
80 OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */
81 if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) {
83#ifdef AH_DEBUG
84 ath_hal_printf(ah, "%s: dma failed to stop in 10ms\n"
85 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
86 __func__,
87 OS_REG_READ(ah, AR_CR),
89#endif
90 status = AH_FALSE;
91 } else {
92 status = AH_TRUE;
93 }
94
95 /*
96 * XXX Is this to flush whatever is in a FIFO somewhere?
97 * XXX If so, what should the correct behaviour should be?
98 */
99 if (AR_SREV_9100(ah))
100 OS_DELAY(3000);
101
102 return (status);
103}
104
105/*
106 * Start receive at the PCU engine
107 */
108void
109ar5416StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
110{
111 struct ath_hal_private *ahp = AH_PRIVATE(ah);
112
113 HALDEBUG(ah, HAL_DEBUG_RX, "%s: Start PCU Receive \n", __func__);
115 /* NB: restore current settings if we're not scanning */
116 ar5416AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, ! is_scanning);
117 /*
118 * NB: must do after enabling phy errors to avoid rx
119 * frames w/ corrupted descriptor status.
120 */
122}
123
124/*
125 * Stop receive at the PCU engine
126 * and abort current frame in PCU
127 */
128void
130{
132
133 HALDEBUG(ah, HAL_DEBUG_RX, "%s: Stop PCU Receive \n", __func__);
135}
136
137/*
138 * Initialize RX descriptor, by clearing the status and setting
139 * the size (and any other flags).
140 */
142ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
143 uint32_t size, u_int flags)
144{
145 struct ar5416_desc *ads = AR5416DESC(ds);
146
147 HALASSERT((size &~ AR_BufLen) == 0);
148
149 ads->ds_ctl1 = size & AR_BufLen;
150 if (flags & HAL_RXDESC_INTREQ)
151 ads->ds_ctl1 |= AR_RxIntrReq;
152
153 /* this should be enough */
154 ads->ds_rxstatus8 &= ~AR_RxDone;
155
156 /* clear the rest of the status fields */
157 OS_MEMZERO(&(ads->u), sizeof(ads->u));
158
159 return AH_TRUE;
160}
161
162/*
163 * Process an RX descriptor, and return the status to the caller.
164 * Copy some hardware specific items into the software portion
165 * of the descriptor.
166 *
167 * NB: the caller is responsible for validating the memory contents
168 * of the descriptor (e.g. flushing any cached copy).
169 */
171ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
172 uint32_t pa, struct ath_desc *nds, uint64_t tsf,
173 struct ath_rx_status *rs)
174{
175 struct ar5416_desc *ads = AR5416DESC(ds);
176
177 if ((ads->ds_rxstatus8 & AR_RxDone) == 0)
178 return HAL_EINPROGRESS;
179
180 rs->rs_status = 0;
181 rs->rs_flags = 0;
182
183 rs->rs_datalen = ads->ds_rxstatus1 & AR_DataLen;
184 rs->rs_tstamp = ads->AR_RcvTimestamp;
185
186 rs->rs_rssi = MS(ads->ds_rxstatus4, AR_RxRSSICombined);
187 rs->rs_rssi_ctl[0] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt00);
188 rs->rs_rssi_ctl[1] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt01);
189 rs->rs_rssi_ctl[2] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt02);
190 rs->rs_rssi_ext[0] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt10);
191 rs->rs_rssi_ext[1] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt11);
192 rs->rs_rssi_ext[2] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt12);
193
194 if (ads->ds_rxstatus8 & AR_RxKeyIdxValid)
195 rs->rs_keyix = MS(ads->ds_rxstatus8, AR_KeyIdx);
196 else
198
199 /* NB: caller expected to do rate table mapping */
200 rs->rs_rate = RXSTATUS_RATE(ah, ads);
201 rs->rs_more = (ads->ds_rxstatus1 & AR_RxMore) ? 1 : 0;
202
203 rs->rs_isaggr = (ads->ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
204 rs->rs_moreaggr = (ads->ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
205 rs->rs_antenna = MS(ads->ds_rxstatus3, AR_RxAntenna);
206
207 if (ads->ds_rxstatus3 & AR_GI)
208 rs->rs_flags |= HAL_RX_GI;
209 if (ads->ds_rxstatus3 & AR_2040)
210 rs->rs_flags |= HAL_RX_2040;
211
212 /*
213 * Only the AR9280 and later chips support STBC RX, so
214 * ensure we only set this bit for those chips.
215 */
217 && ads->ds_rxstatus3 & AR_STBCFrame)
218 rs->rs_flags |= HAL_RX_STBC;
219
220 if (ads->ds_rxstatus8 & AR_PreDelimCRCErr)
222 if (ads->ds_rxstatus8 & AR_PostDelimCRCErr)
224 if (ads->ds_rxstatus8 & AR_DecryptBusyErr)
226 if (ads->ds_rxstatus8 & AR_HiRxChain)
228
229 if ((ads->ds_rxstatus8 & AR_RxFrameOK) == 0) {
230 /*
231 * These four bits should not be set together. The
232 * 5416 spec states a Michael error can only occur if
233 * DecryptCRCErr not set (and TKIP is used). Experience
234 * indicates however that you can also get Michael errors
235 * when a CRC error is detected, but these are specious.
236 * Consequently we filter them out here so we don't
237 * confuse and/or complicate drivers.
238 */
239
240 /*
241 * The AR5416 sometimes sets both AR_CRCErr and AR_PHYErr
242 * when reporting radar pulses. In this instance
243 * set HAL_RXERR_PHY as well as HAL_RXERR_CRC and
244 * let the driver layer figure out what to do.
245 *
246 * See PR kern/169362.
247 */
248 if (ads->ds_rxstatus8 & AR_PHYErr) {
249 u_int phyerr;
250
251 /*
252 * Packets with OFDM_RESTART on post delimiter are CRC OK and
253 * usable and MAC ACKs them.
254 * To avoid packet from being lost, we remove the PHY Err flag
255 * so that driver layer does not drop them.
256 */
257 phyerr = MS(ads->ds_rxstatus8, AR_PHYErrCode);
258
259 if ((phyerr == HAL_PHYERR_OFDM_RESTART) &&
260 (ads->ds_rxstatus8 & AR_PostDelimCRCErr)) {
262 "%s: OFDM_RESTART on post-delim CRC error\n",
263 __func__);
264 rs->rs_phyerr = 0;
265 } else {
267 rs->rs_phyerr = phyerr;
268 }
269 }
270 if (ads->ds_rxstatus8 & AR_CRCErr)
272 else if (ads->ds_rxstatus8 & AR_DecryptCRCErr)
274 else if (ads->ds_rxstatus8 & AR_MichaelErr)
276 }
277
278 if (ads->ds_rxstatus8 & AR_KeyMiss)
280
281 return HAL_OK;
282}
HAL_BOOL ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
Definition: ah.c:305
HAL_STATUS
Definition: ah.h:71
@ HAL_OK
Definition: ah.h:72
@ HAL_EINPROGRESS
Definition: ah.h:87
@ HAL_RX_FILTER_PHYERR
Definition: ah.h:422
@ HAL_RX_FILTER_PHYRADAR
Definition: ah.h:426
HAL_BOOL
Definition: ah.h:93
@ AH_FALSE
Definition: ah.h:94
@ AH_TRUE
Definition: ah.h:95
@ HAL_DEBUG_RX
Definition: ah_debug.h:41
@ AH_MARK_RX_CTL
Definition: ah_decode.h:57
@ AH_MARK_RX_CTL_DMA_STOP
Definition: ah_decode.h:66
@ AH_MARK_RX_CTL_DMA_STOP_ERR
Definition: ah_decode.h:67
#define HAL_RXDESC_INTREQ
Definition: ah_desc.h:277
#define HAL_RX_HI_RX_CHAIN
Definition: ah_desc.h:144
#define HAL_RXERR_KEYMISS
Definition: ah_desc.h:134
#define HAL_RX_DELIM_CRC_PRE
Definition: ah_desc.h:141
#define HAL_RXERR_DECRYPT
Definition: ah_desc.h:131
#define HAL_RX_DECRYPT_BUSY
Definition: ah_desc.h:143
#define HAL_RX_DELIM_CRC_POST
Definition: ah_desc.h:142
#define HAL_RXERR_PHY
Definition: ah_desc.h:129
#define HAL_RX_GI
Definition: ah_desc.h:139
#define HAL_RXKEYIX_INVALID
Definition: ah_desc.h:213
#define HAL_RX_STBC
Definition: ah_desc.h:146
#define HAL_RXERR_CRC
Definition: ah_desc.h:128
@ HAL_PHYERR_OFDM_RESTART
Definition: ah_desc.h:195
#define HAL_RX_2040
Definition: ah_desc.h:140
#define HAL_RXERR_MIC
Definition: ah_desc.h:132
#define OS_REG_SET_BIT(_a, _r, _f)
Definition: ah_internal.h:594
#define MS(_v, _f)
Definition: ah_internal.h:588
#define OS_REG_CLR_BIT(_a, _r, _f)
Definition: ah_internal.h:596
#define AH_PRIVATE(_ah)
Definition: ah_internal.h:442
#define HALASSERT(_x)
Definition: ah_internal.h:683
#define HALDEBUG(_ah, __m,...)
Definition: ah_internal.h:658
void ath_hal_printf(struct ath_hal *, const char *,...)
Definition: ah_osdep.c:80
#define OS_DELAY(_n)
Definition: ah_osdep.h:69
#define OS_MEMZERO(_a, _n)
Definition: ah_osdep.h:72
#define OS_REG_WRITE(_ah, _reg, _val)
Definition: ah_osdep.h:139
#define OS_MARK(_ah, _id, _v)
Definition: ah_osdep.h:148
#define OS_REG_READ(_ah, _reg)
Definition: ah_osdep.h:140
#define AR_KeyIdx
Definition: ar5210desc.h:126
#define AR_PHYErr
Definition: ar5210desc.h:115
#define AR_CRCErr
Definition: ar5210desc.h:112
#define AR_DecryptCRCErr
Definition: ar5210desc.h:114
#define AR_DataLen
Definition: ar5210desc.h:95
#define AR_BufLen
Definition: ar5210desc.h:70
#define AR_RXCFG
Definition: ar5210reg.h:47
#define AR_RXCFG_ZLFDMA
Definition: ar5210reg.h:218
#define AR_CR_RXD
Definition: ar5210reg.h:115
#define AR_CR
Definition: ar5210reg.h:38
#define AR_RX_FILTER
Definition: ar5210reg.h:88
#define AR_CR_RXE
Definition: ar5210reg.h:112
#define AR_DIAG_SW
Definition: ar5210reg.h:95
void ar5212EnableMibCounters(struct ath_hal *)
Definition: ar5212_misc.c:366
void ar5212DisableMibCounters(struct ath_hal *)
Definition: ar5212_misc.c:374
#define AR_MichaelErr
Definition: ar5212desc.h:165
#define AR_PHYErrCode
Definition: ar5212desc.h:175
#define AR_PHY_ERR
Definition: ar5212reg.h:317
#define AR_PHY_ERR_CCK_TIMING
Definition: ar5212reg.h:950
#define AR_PHY_ERR_RADAR
Definition: ar5212reg.h:948
#define AR_PHY_ERR_OFDM_TIMING
Definition: ar5212reg.h:949
#define AR_DIAG_RX_DIS
Definition: ar5212reg.h:908
void ar5416AniReset(struct ath_hal *, const struct ieee80211_channel *, HAL_OPMODE, int)
Definition: ar5416_ani.c:544
HAL_BOOL ar5416StopDmaReceive(struct ath_hal *ah)
Definition: ar5416_recv.c:75
void ar5416StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning)
Definition: ar5416_recv.c:109
HAL_BOOL ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t size, u_int flags)
Definition: ar5416_recv.c:142
void ar5416StopPcuReceive(struct ath_hal *ah)
Definition: ar5416_recv.c:129
HAL_STATUS ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t pa, struct ath_desc *nds, uint64_t tsf, struct ath_rx_status *rs)
Definition: ar5416_recv.c:171
void ar5416SetRxFilter(struct ath_hal *ah, u_int32_t bits)
Definition: ar5416_recv.c:51
uint32_t ar5416GetRxFilter(struct ath_hal *ah)
Definition: ar5416_recv.c:35
#define AR_RxKeyIdxValid
Definition: ar5416desc.h:393
#define AR_RxAntenna
Definition: ar5416desc.h:362
#define AR_RxRSSIAnt10
Definition: ar5416desc.h:366
#define AR_RxMore
Definition: ar5416desc.h:342
#define AR_DecryptBusyErr
Definition: ar5416desc.h:403
#define AR_2040
Definition: ar5416desc.h:352
#define AR_RxMoreAggr
Definition: ar5416desc.h:398
#define AR_RxRSSIAnt01
Definition: ar5416desc.h:329
#define AR_RxRSSICombined
Definition: ar5416desc.h:372
#define AR_KeyMiss
Definition: ar5416desc.h:404
#define AR_RxAggr
Definition: ar5416desc.h:399
#define AR_RxRSSIAnt12
Definition: ar5416desc.h:370
#define AR_GI
Definition: ar5416desc.h:351
#define AR5416DESC(_ds)
Definition: ar5416desc.h:77
#define AR_RxRSSIAnt02
Definition: ar5416desc.h:331
#define RXSTATUS_RATE(ah, ads)
Definition: ar5416desc.h:415
#define AR_RxRSSIAnt11
Definition: ar5416desc.h:368
#define AR_PostDelimCRCErr
Definition: ar5416desc.h:400
#define AR_STBCFrame
Definition: ar5416desc.h:361
#define AR_HiRxChain
Definition: ar5416desc.h:402
#define AR_RxIntrReq
Definition: ar5416desc.h:319
#define AR_RxDone
Definition: ar5416desc.h:385
#define AR_RxRSSIAnt00
Definition: ar5416desc.h:327
#define AR_RxFrameOK
Definition: ar5416desc.h:386
#define AR_PreDelimCRCErr
Definition: ar5416desc.h:391
#define AR_DIAG_RX_ABORT
Definition: ar5416reg.h:299
#define AR_SREV_9100(_ah)
Definition: ar5416reg.h:721
#define AR_SREV_MERLIN_10_OR_LATER(_ah)
Definition: ar5416reg.h:740
uint32_t ds_ctl1
Definition: ar5416desc.h:71
union ar5416_desc::@27 u
const struct ieee80211_channel * ah_curchan
Definition: ah_internal.h:401
HAL_OPMODE ah_opmode
Definition: ah_internal.h:400
Definition: ah.h:1219
uint8_t rs_isaggr
Definition: ah_desc.h:112
uint16_t rs_flags
Definition: ah_desc.h:114
uint8_t rs_keyix
Definition: ah_desc.h:104
uint8_t rs_rate
Definition: ah_desc.h:105
int8_t rs_rssi_ext[3]
Definition: ah_desc.h:111
uint8_t rs_status
Definition: ah_desc.h:101
uint16_t rs_datalen
Definition: ah_desc.h:100
uint8_t rs_more
Definition: ah_desc.h:106
uint8_t rs_phyerr
Definition: ah_desc.h:102
uint32_t rs_antenna
Definition: ah_desc.h:108
int8_t rs_rssi_ctl[3]
Definition: ah_desc.h:110
uint8_t rs_moreaggr
Definition: ah_desc.h:113
int8_t rs_rssi
Definition: ah_desc.h:103
uint32_t rs_tstamp
Definition: ah_desc.h:107