1 1.1 alc /* 2 1.1 alc * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 1.1 alc * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 1.1 alc * 5 1.1 alc * Permission to use, copy, modify, and/or distribute this software for any 6 1.1 alc * purpose with or without fee is hereby granted, provided that the above 7 1.1 alc * copyright notice and this permission notice appear in all copies. 8 1.1 alc * 9 1.1 alc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 1.1 alc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 1.1 alc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 1.1 alc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 1.1 alc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 1.1 alc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 1.1 alc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 1.1 alc * 17 1.2 cegger * $Id: ar5212_recv.c,v 1.2 2011/03/07 11:25:43 cegger Exp $ 18 1.1 alc */ 19 1.1 alc #include "opt_ah.h" 20 1.1 alc 21 1.1 alc #include "ah.h" 22 1.1 alc #include "ah_internal.h" 23 1.1 alc 24 1.1 alc #include "ar5212/ar5212.h" 25 1.1 alc #include "ar5212/ar5212reg.h" 26 1.1 alc #include "ar5212/ar5212desc.h" 27 1.1 alc 28 1.1 alc /* 29 1.1 alc * Get the RXDP. 30 1.1 alc */ 31 1.1 alc uint32_t 32 1.1 alc ar5212GetRxDP(struct ath_hal *ath) 33 1.1 alc { 34 1.1 alc return OS_REG_READ(ath, AR_RXDP); 35 1.1 alc } 36 1.1 alc 37 1.1 alc /* 38 1.1 alc * Set the RxDP. 39 1.1 alc */ 40 1.1 alc void 41 1.1 alc ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp) 42 1.1 alc { 43 1.1 alc OS_REG_WRITE(ah, AR_RXDP, rxdp); 44 1.1 alc HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp); 45 1.1 alc } 46 1.1 alc 47 1.1 alc /* 48 1.1 alc * Set Receive Enable bits. 49 1.1 alc */ 50 1.1 alc void 51 1.1 alc ar5212EnableReceive(struct ath_hal *ah) 52 1.1 alc { 53 1.1 alc OS_REG_WRITE(ah, AR_CR, AR_CR_RXE); 54 1.1 alc } 55 1.1 alc 56 1.1 alc /* 57 1.1 alc * Stop Receive at the DMA engine 58 1.1 alc */ 59 1.1 alc HAL_BOOL 60 1.1 alc ar5212StopDmaReceive(struct ath_hal *ah) 61 1.1 alc { 62 1.1 alc OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */ 63 1.1 alc if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) { 64 1.1 alc #ifdef AH_DEBUG 65 1.1 alc ath_hal_printf(ah, "%s: dma failed to stop in 10ms\n" 66 1.1 alc "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", 67 1.1 alc __func__, 68 1.1 alc OS_REG_READ(ah, AR_CR), 69 1.1 alc OS_REG_READ(ah, AR_DIAG_SW)); 70 1.1 alc #endif 71 1.1 alc return AH_FALSE; 72 1.1 alc } else { 73 1.1 alc return AH_TRUE; 74 1.1 alc } 75 1.1 alc } 76 1.1 alc 77 1.1 alc /* 78 1.1 alc * Start Transmit at the PCU engine (unpause receive) 79 1.1 alc */ 80 1.1 alc void 81 1.1 alc ar5212StartPcuReceive(struct ath_hal *ah) 82 1.1 alc { 83 1.1 alc struct ath_hal_private *ahp = AH_PRIVATE(ah); 84 1.1 alc 85 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, 86 1.1 alc OS_REG_READ(ah, AR_DIAG_SW) &~ AR_DIAG_RX_DIS); 87 1.1 alc ar5212EnableMibCounters(ah); 88 1.1 alc /* NB: restore current settings */ 89 1.1 alc ar5212AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE); 90 1.1 alc } 91 1.1 alc 92 1.1 alc /* 93 1.1 alc * Stop Transmit at the PCU engine (pause receive) 94 1.1 alc */ 95 1.1 alc void 96 1.1 alc ar5212StopPcuReceive(struct ath_hal *ah) 97 1.1 alc { 98 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, 99 1.1 alc OS_REG_READ(ah, AR_DIAG_SW) | AR_DIAG_RX_DIS); 100 1.1 alc ar5212DisableMibCounters(ah); 101 1.1 alc } 102 1.1 alc 103 1.1 alc /* 104 1.1 alc * Set multicast filter 0 (lower 32-bits) 105 1.1 alc * filter 1 (upper 32-bits) 106 1.1 alc */ 107 1.1 alc void 108 1.1 alc ar5212SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1) 109 1.1 alc { 110 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0); 111 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1); 112 1.1 alc } 113 1.1 alc 114 1.1 alc /* 115 1.1 alc * Clear multicast filter by index 116 1.1 alc */ 117 1.1 alc HAL_BOOL 118 1.1 alc ar5212ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) 119 1.1 alc { 120 1.1 alc uint32_t val; 121 1.1 alc 122 1.1 alc if (ix >= 64) 123 1.1 alc return AH_FALSE; 124 1.1 alc if (ix >= 32) { 125 1.1 alc val = OS_REG_READ(ah, AR_MCAST_FIL1); 126 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32)))); 127 1.1 alc } else { 128 1.1 alc val = OS_REG_READ(ah, AR_MCAST_FIL0); 129 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<<ix))); 130 1.1 alc } 131 1.1 alc return AH_TRUE; 132 1.1 alc } 133 1.1 alc 134 1.1 alc /* 135 1.1 alc * Set multicast filter by index 136 1.1 alc */ 137 1.1 alc HAL_BOOL 138 1.1 alc ar5212SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) 139 1.1 alc { 140 1.1 alc uint32_t val; 141 1.1 alc 142 1.1 alc if (ix >= 64) 143 1.1 alc return AH_FALSE; 144 1.1 alc if (ix >= 32) { 145 1.1 alc val = OS_REG_READ(ah, AR_MCAST_FIL1); 146 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32)))); 147 1.1 alc } else { 148 1.1 alc val = OS_REG_READ(ah, AR_MCAST_FIL0); 149 1.1 alc OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<<ix))); 150 1.1 alc } 151 1.1 alc return AH_TRUE; 152 1.1 alc } 153 1.1 alc 154 1.1 alc /* 155 1.1 alc * Get the receive filter. 156 1.1 alc */ 157 1.1 alc uint32_t 158 1.1 alc ar5212GetRxFilter(struct ath_hal *ah) 159 1.1 alc { 160 1.1 alc uint32_t bits = OS_REG_READ(ah, AR_RX_FILTER); 161 1.1 alc uint32_t phybits = OS_REG_READ(ah, AR_PHY_ERR); 162 1.1 alc if (phybits & AR_PHY_ERR_RADAR) 163 1.1 alc bits |= HAL_RX_FILTER_PHYRADAR; 164 1.1 alc if (phybits & (AR_PHY_ERR_OFDM_TIMING|AR_PHY_ERR_CCK_TIMING)) 165 1.1 alc bits |= HAL_RX_FILTER_PHYERR; 166 1.2 cegger if (AH_PRIVATE(ah)->ah_caps.halBssidMatchSupport && 167 1.2 cegger (AH5212(ah)->ah_miscMode & AR_MISC_MODE_BSSID_MATCH_FORCE)) 168 1.2 cegger bits |= HAL_RX_FILTER_BSSID; 169 1.1 alc return bits; 170 1.1 alc } 171 1.1 alc 172 1.1 alc /* 173 1.1 alc * Set the receive filter. 174 1.1 alc */ 175 1.1 alc void 176 1.1 alc ar5212SetRxFilter(struct ath_hal *ah, uint32_t bits) 177 1.1 alc { 178 1.2 cegger struct ath_hal_5212 *ahp = AH5212(ah); 179 1.1 alc uint32_t phybits; 180 1.1 alc 181 1.1 alc OS_REG_WRITE(ah, AR_RX_FILTER, 182 1.2 cegger bits &~ (HAL_RX_FILTER_PHYRADAR|HAL_RX_FILTER_PHYERR| 183 1.2 cegger HAL_RX_FILTER_BSSID)); 184 1.1 alc phybits = 0; 185 1.1 alc if (bits & HAL_RX_FILTER_PHYRADAR) 186 1.1 alc phybits |= AR_PHY_ERR_RADAR; 187 1.1 alc if (bits & HAL_RX_FILTER_PHYERR) 188 1.1 alc phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING; 189 1.1 alc OS_REG_WRITE(ah, AR_PHY_ERR, phybits); 190 1.1 alc if (phybits) { 191 1.1 alc OS_REG_WRITE(ah, AR_RXCFG, 192 1.1 alc OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA); 193 1.1 alc } else { 194 1.1 alc OS_REG_WRITE(ah, AR_RXCFG, 195 1.1 alc OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA); 196 1.1 alc } 197 1.2 cegger if (AH_PRIVATE(ah)->ah_caps.halBssidMatchSupport) { 198 1.2 cegger if (bits & HAL_RX_FILTER_BSSID) 199 1.2 cegger ahp->ah_miscMode |= AR_MISC_MODE_BSSID_MATCH_FORCE; 200 1.2 cegger else 201 1.2 cegger ahp->ah_miscMode &= ~AR_MISC_MODE_BSSID_MATCH_FORCE; 202 1.2 cegger OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 203 1.2 cegger } 204 1.1 alc } 205 1.1 alc 206 1.1 alc /* 207 1.1 alc * Initialize RX descriptor, by clearing the status and setting 208 1.1 alc * the size (and any other flags). 209 1.1 alc */ 210 1.1 alc HAL_BOOL 211 1.1 alc ar5212SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds, 212 1.1 alc uint32_t size, u_int flags) 213 1.1 alc { 214 1.1 alc struct ar5212_desc *ads = AR5212DESC(ds); 215 1.1 alc 216 1.1 alc HALASSERT((size &~ AR_BufLen) == 0); 217 1.1 alc 218 1.1 alc ads->ds_ctl0 = 0; 219 1.1 alc ads->ds_ctl1 = size & AR_BufLen; 220 1.1 alc 221 1.1 alc if (flags & HAL_RXDESC_INTREQ) 222 1.1 alc ads->ds_ctl1 |= AR_RxInterReq; 223 1.1 alc ads->ds_rxstatus0 = ads->ds_rxstatus1 = 0; 224 1.1 alc 225 1.1 alc return AH_TRUE; 226 1.1 alc } 227 1.1 alc 228 1.1 alc /* 229 1.1 alc * Process an RX descriptor, and return the status to the caller. 230 1.1 alc * Copy some hardware specific items into the software portion 231 1.1 alc * of the descriptor. 232 1.1 alc * 233 1.1 alc * NB: the caller is responsible for validating the memory contents 234 1.1 alc * of the descriptor (e.g. flushing any cached copy). 235 1.1 alc */ 236 1.1 alc HAL_STATUS 237 1.1 alc ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds, 238 1.1 alc uint32_t pa, struct ath_desc *nds, uint64_t tsf, 239 1.1 alc struct ath_rx_status *rs) 240 1.1 alc { 241 1.1 alc struct ar5212_desc *ads = AR5212DESC(ds); 242 1.1 alc struct ar5212_desc *ands = AR5212DESC(nds); 243 1.1 alc 244 1.1 alc if ((ads->ds_rxstatus1 & AR_Done) == 0) 245 1.1 alc return HAL_EINPROGRESS; 246 1.1 alc /* 247 1.1 alc * Given the use of a self-linked tail be very sure that the hw is 248 1.1 alc * done with this descriptor; the hw may have done this descriptor 249 1.1 alc * once and picked it up again...make sure the hw has moved on. 250 1.1 alc */ 251 1.1 alc if ((ands->ds_rxstatus1&AR_Done) == 0 && OS_REG_READ(ah, AR_RXDP) == pa) 252 1.1 alc return HAL_EINPROGRESS; 253 1.1 alc 254 1.1 alc rs->rs_datalen = ads->ds_rxstatus0 & AR_DataLen; 255 1.1 alc rs->rs_tstamp = MS(ads->ds_rxstatus1, AR_RcvTimestamp); 256 1.1 alc rs->rs_status = 0; 257 1.1 alc /* XXX what about KeyCacheMiss? */ 258 1.1 alc rs->rs_rssi = MS(ads->ds_rxstatus0, AR_RcvSigStrength); 259 1.1 alc /* discard invalid h/w rssi data */ 260 1.1 alc if (rs->rs_rssi == -128) 261 1.1 alc rs->rs_rssi = 0; 262 1.1 alc if (ads->ds_rxstatus1 & AR_KeyIdxValid) 263 1.1 alc rs->rs_keyix = MS(ads->ds_rxstatus1, AR_KeyIdx); 264 1.1 alc else 265 1.1 alc rs->rs_keyix = HAL_RXKEYIX_INVALID; 266 1.1 alc /* NB: caller expected to do rate table mapping */ 267 1.1 alc rs->rs_rate = MS(ads->ds_rxstatus0, AR_RcvRate); 268 1.1 alc rs->rs_antenna = MS(ads->ds_rxstatus0, AR_RcvAntenna); 269 1.1 alc rs->rs_more = (ads->ds_rxstatus0 & AR_More) ? 1 : 0; 270 1.1 alc 271 1.1 alc if ((ads->ds_rxstatus1 & AR_FrmRcvOK) == 0) { 272 1.1 alc /* 273 1.1 alc * These four bits should not be set together. The 274 1.1 alc * 5212 spec states a Michael error can only occur if 275 1.1 alc * DecryptCRCErr not set (and TKIP is used). Experience 276 1.1 alc * indicates however that you can also get Michael errors 277 1.1 alc * when a CRC error is detected, but these are specious. 278 1.1 alc * Consequently we filter them out here so we don't 279 1.1 alc * confuse and/or complicate drivers. 280 1.1 alc */ 281 1.1 alc if (ads->ds_rxstatus1 & AR_CRCErr) 282 1.1 alc rs->rs_status |= HAL_RXERR_CRC; 283 1.1 alc else if (ads->ds_rxstatus1 & AR_PHYErr) { 284 1.1 alc u_int phyerr; 285 1.1 alc 286 1.1 alc rs->rs_status |= HAL_RXERR_PHY; 287 1.1 alc phyerr = MS(ads->ds_rxstatus1, AR_PHYErrCode); 288 1.1 alc rs->rs_phyerr = phyerr; 289 1.1 alc if (!AH5212(ah)->ah_hasHwPhyCounters && 290 1.1 alc phyerr != HAL_PHYERR_RADAR) 291 1.1 alc ar5212AniPhyErrReport(ah, rs); 292 1.1 alc } else if (ads->ds_rxstatus1 & AR_DecryptCRCErr) 293 1.1 alc rs->rs_status |= HAL_RXERR_DECRYPT; 294 1.1 alc else if (ads->ds_rxstatus1 & AR_MichaelErr) 295 1.1 alc rs->rs_status |= HAL_RXERR_MIC; 296 1.1 alc } 297 1.1 alc return HAL_OK; 298 1.1 alc } 299