1 /* 2 * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "opt_ah.h" 18 19 #include "ah.h" 20 #include "ah_desc.h" 21 #include "ah_internal.h" 22 23 #include "ar9300/ar9300.h" 24 #include "ar9300/ar9300reg.h" 25 #include "ar9300/ar9300desc.h" 26 27 /* 28 * Get the RXDP. 29 */ 30 u_int32_t 31 ar9300_get_rx_dp(struct ath_hal *ath, HAL_RX_QUEUE qtype) 32 { 33 if (qtype == HAL_RX_QUEUE_HP) { 34 return OS_REG_READ(ath, AR_HP_RXDP); 35 } else { 36 return OS_REG_READ(ath, AR_LP_RXDP); 37 } 38 } 39 40 /* 41 * Set the rx_dp. 42 */ 43 void 44 ar9300_set_rx_dp(struct ath_hal *ah, u_int32_t rxdp, HAL_RX_QUEUE qtype) 45 { 46 HALASSERT((qtype == HAL_RX_QUEUE_HP) || (qtype == HAL_RX_QUEUE_LP)); 47 48 if (qtype == HAL_RX_QUEUE_HP) { 49 OS_REG_WRITE(ah, AR_HP_RXDP, rxdp); 50 } else { 51 OS_REG_WRITE(ah, AR_LP_RXDP, rxdp); 52 } 53 } 54 55 /* 56 * Set Receive Enable bits. 57 */ 58 void 59 ar9300_enable_receive(struct ath_hal *ah) 60 { 61 OS_REG_WRITE(ah, AR_CR, 0); 62 } 63 64 /* 65 * Set the RX abort bit. 66 */ 67 HAL_BOOL 68 ar9300_set_rx_abort(struct ath_hal *ah, HAL_BOOL set) 69 { 70 if (set) { 71 /* Set the force_rx_abort bit */ 72 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 73 74 if ( AH9300(ah)->ah_reset_reason == HAL_RESET_BBPANIC ){ 75 /* depending upon the BB panic status, rx state may not return to 0, 76 * so skipping the wait for BB panic reset */ 77 OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 78 return AH_FALSE; 79 } else { 80 HAL_BOOL okay; 81 okay = ath_hal_wait( 82 ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0); 83 /* Wait for Rx state to return to 0 */ 84 if (!okay) { 85 /* abort: chip rx failed to go idle in 10 ms */ 86 OS_REG_CLR_BIT(ah, AR_DIAG_SW, 87 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 88 89 HALDEBUG(ah, HAL_DEBUG_RX, 90 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n", 91 __func__, OS_REG_READ(ah, AR_OBS_BUS_1)); 92 93 return AH_FALSE; /* failure */ 94 } 95 } 96 } else { 97 OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 98 } 99 100 return AH_TRUE; /* success */ 101 } 102 103 /* 104 * Stop Receive at the DMA engine 105 */ 106 HAL_BOOL 107 ar9300_stop_dma_receive(struct ath_hal *ah, u_int timeout) 108 { 109 int wait; 110 HAL_BOOL status, okay; 111 u_int32_t org_value; 112 113 #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ 114 #define AH_TIME_QUANTUM 100 /* usec */ 115 116 OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP); 117 118 if (timeout == 0) { 119 timeout = AH_RX_STOP_DMA_TIMEOUT; 120 } 121 122 org_value = OS_REG_READ(ah, AR_MACMISC); 123 124 OS_REG_WRITE(ah, AR_MACMISC, 125 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | 126 (AR_MACMISC_MISC_OBS_BUS_1 << AR_MACMISC_MISC_OBS_BUS_MSB_S))); 127 128 okay = ath_hal_wait( 129 ah, AR_DMADBG_7, AR_DMADBG_RX_STATE, 0); 130 /* wait for Rx DMA state machine to become idle */ 131 if (!okay) { 132 HALDEBUG(ah, HAL_DEBUG_RX, 133 "reg AR_DMADBG_7 is not 0, instead 0x%08x\n", 134 OS_REG_READ(ah, AR_DMADBG_7)); 135 } 136 137 /* Set receive disable bit */ 138 OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); 139 140 /* Wait for rx enable bit to go low */ 141 for (wait = timeout / AH_TIME_QUANTUM; wait != 0; wait--) { 142 if ((OS_REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) { 143 break; 144 } 145 OS_DELAY(AH_TIME_QUANTUM); 146 } 147 148 if (wait == 0) { 149 HALDEBUG(ah, HAL_DEBUG_RX, "%s: dma failed to stop in %d ms\n" 150 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", 151 __func__, 152 timeout / 1000, 153 OS_REG_READ(ah, AR_CR), 154 OS_REG_READ(ah, AR_DIAG_SW)); 155 status = AH_FALSE; 156 } else { 157 status = AH_TRUE; 158 } 159 160 OS_REG_WRITE(ah, AR_MACMISC, org_value); 161 162 OS_MARK(ah, AH_MARK_RX_CTL, 163 status ? AH_MARK_RX_CTL_DMA_STOP_OK : AH_MARK_RX_CTL_DMA_STOP_ERR); 164 165 return status; 166 #undef AH_RX_STOP_DMA_TIMEOUT 167 #undef AH_TIME_QUANTUM 168 } 169 170 /* 171 * Start Transmit at the PCU engine (unpause receive) 172 */ 173 void 174 ar9300_start_pcu_receive(struct ath_hal *ah, HAL_BOOL is_scanning) 175 { 176 ar9300_enable_mib_counters(ah); 177 ar9300_ani_reset(ah, is_scanning); 178 /* Clear RX_DIS and RX_ABORT after enabling phy errors in ani_reset */ 179 OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 180 } 181 182 /* 183 * Stop Transmit at the PCU engine (pause receive) 184 */ 185 void 186 ar9300_stop_pcu_receive(struct ath_hal *ah) 187 { 188 OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); 189 ar9300_disable_mib_counters(ah); 190 } 191 192 /* 193 * Set multicast filter 0 (lower 32-bits) 194 * filter 1 (upper 32-bits) 195 */ 196 void 197 ar9300_set_multicast_filter( 198 struct ath_hal *ah, 199 u_int32_t filter0, 200 u_int32_t filter1) 201 { 202 OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0); 203 OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1); 204 } 205 206 /* 207 * Get the receive filter. 208 */ 209 u_int32_t 210 ar9300_get_rx_filter(struct ath_hal *ah) 211 { 212 u_int32_t bits = OS_REG_READ(ah, AR_RX_FILTER); 213 u_int32_t phybits = OS_REG_READ(ah, AR_PHY_ERR); 214 if (phybits & AR_PHY_ERR_RADAR) { 215 bits |= HAL_RX_FILTER_PHYRADAR; 216 } 217 if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING)) { 218 bits |= HAL_RX_FILTER_PHYERR; 219 } 220 return bits; 221 } 222 223 /* 224 * Set the receive filter. 225 */ 226 void 227 ar9300_set_rx_filter(struct ath_hal *ah, u_int32_t bits) 228 { 229 u_int32_t phybits; 230 231 if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) { 232 /* Enable Rx for 4 address frames */ 233 bits |= AR_RX_4ADDRESS; 234 } 235 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 236 /* HW fix for rx hang and corruption. */ 237 bits |= AR_RX_CONTROL_WRAPPER; 238 } 239 OS_REG_WRITE(ah, AR_RX_FILTER, 240 bits | AR_RX_UNCOM_BA_BAR | AR_RX_COMPR_BAR); 241 phybits = 0; 242 if (bits & HAL_RX_FILTER_PHYRADAR) { 243 phybits |= AR_PHY_ERR_RADAR; 244 } 245 if (bits & HAL_RX_FILTER_PHYERR) { 246 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING; 247 } 248 OS_REG_WRITE(ah, AR_PHY_ERR, phybits); 249 if (phybits) { 250 OS_REG_WRITE(ah, AR_RXCFG, 251 OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA); 252 } else { 253 OS_REG_WRITE(ah, AR_RXCFG, 254 OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA); 255 } 256 } 257 258 /* 259 * Select to pass PLCP headr or EVM data. 260 */ 261 HAL_BOOL 262 ar9300_set_rx_sel_evm(struct ath_hal *ah, HAL_BOOL sel_evm, HAL_BOOL just_query) 263 { 264 struct ath_hal_9300 *ahp = AH9300(ah); 265 HAL_BOOL old_value = ahp->ah_get_plcp_hdr == 0; 266 267 if (just_query) { 268 return old_value; 269 } 270 if (sel_evm) { 271 OS_REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM); 272 } else { 273 OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM); 274 } 275 276 ahp->ah_get_plcp_hdr = !sel_evm; 277 278 return old_value; 279 } 280 281 void ar9300_promisc_mode(struct ath_hal *ah, HAL_BOOL enable) 282 { 283 u_int32_t reg_val = 0; 284 reg_val = OS_REG_READ(ah, AR_RX_FILTER); 285 if (enable){ 286 reg_val |= AR_RX_PROM; 287 } else{ /*Disable promisc mode */ 288 reg_val &= ~AR_RX_PROM; 289 } 290 OS_REG_WRITE(ah, AR_RX_FILTER, reg_val); 291 } 292 293 void 294 ar9300_read_pktlog_reg( 295 struct ath_hal *ah, 296 u_int32_t *rxfilter_val, 297 u_int32_t *rxcfg_val, 298 u_int32_t *phy_err_mask_val, 299 u_int32_t *mac_pcu_phy_err_regval) 300 { 301 *rxfilter_val = OS_REG_READ(ah, AR_RX_FILTER); 302 *rxcfg_val = OS_REG_READ(ah, AR_RXCFG); 303 *phy_err_mask_val = OS_REG_READ(ah, AR_PHY_ERR); 304 *mac_pcu_phy_err_regval = OS_REG_READ(ah, 0x8338); 305 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 306 "%s[%d] rxfilter_val 0x%08x , rxcfg_val 0x%08x, " 307 "phy_err_mask_val 0x%08x mac_pcu_phy_err_regval 0x%08x\n", 308 __func__, __LINE__, 309 *rxfilter_val, *rxcfg_val, *phy_err_mask_val, *mac_pcu_phy_err_regval); 310 } 311 312 void 313 ar9300_write_pktlog_reg( 314 struct ath_hal *ah, 315 HAL_BOOL enable, 316 u_int32_t rxfilter_val, 317 u_int32_t rxcfg_val, 318 u_int32_t phy_err_mask_val, 319 u_int32_t mac_pcu_phy_err_reg_val) 320 { 321 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 322 /* HW fix for rx hang and corruption. */ 323 rxfilter_val |= AR_RX_CONTROL_WRAPPER; 324 } 325 if (enable) { /* Enable pktlog phyerr setting */ 326 OS_REG_WRITE(ah, AR_RX_FILTER, 0xffff | AR_RX_COMPR_BAR | rxfilter_val); 327 OS_REG_WRITE(ah, AR_PHY_ERR, 0xFFFFFFFF); 328 OS_REG_WRITE(ah, AR_RXCFG, rxcfg_val | AR_RXCFG_ZLFDMA); 329 OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, mac_pcu_phy_err_reg_val | 0xFF); 330 } else { /* Disable phyerr and Restore regs */ 331 OS_REG_WRITE(ah, AR_RX_FILTER, rxfilter_val); 332 OS_REG_WRITE(ah, AR_PHY_ERR, phy_err_mask_val); 333 OS_REG_WRITE(ah, AR_RXCFG, rxcfg_val); 334 OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, mac_pcu_phy_err_reg_val); 335 } 336 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 337 "%s[%d] ena %d rxfilter_val 0x%08x , rxcfg_val 0x%08x, " 338 "phy_err_mask_val 0x%08x mac_pcu_phy_err_regval 0x%08x\n", 339 __func__, __LINE__, 340 enable, rxfilter_val, rxcfg_val, 341 phy_err_mask_val, mac_pcu_phy_err_reg_val); 342 } 343