bool ar9300_handle_radar_bb_panic(struct ath_hal *ah) { u_int32_t status; u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; status = AH_PRIVATE(ah)->ah_bb_panic_last_status; if ( status == 0x04000539 ) { if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } /* recover from this BB panic without reset*/ /* set AR9300_DFS_FIRPWR to -1 */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= (~AR_PHY_RADAR_0_FIRPWR); val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); OS_DELAY(1); /* set AR9300_DFS_FIRPWR to its default value */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } return true; } else if (status == 0x0400000a) { /* EV 92527 : reset required if we see this signature */ HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__); return false; } else if (status == 0x1300000a) { /* EV92527: we do not need a reset if we see this signature */ HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__); return true; } else if ((AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) && (status == 0x04000409)) { return true; } else { if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK && (status & 0xff00000f) == 0x04000009 && status != 0x04000409 && status != 0x04000b09 && status != 0x04000e09 && (status & 0x0000ff00)) { /* disable RIFS Rx */ #ifdef AH_DEBUG HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n", __func__, status, ahp->ah_rifs_enabled); #endif ar9300_set_rifs_delay(ah, false); } return false; } }
/* * Clear the specified key cache entry and any associated MIC entry. */ HAL_BOOL ar9300_reset_key_cache_entry(struct ath_hal *ah, u_int16_t entry) { u_int32_t key_type; struct ath_hal_9300 *ahp = AH9300(ah); if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: entry %u out of range\n", __func__, entry); return AH_FALSE; } ahp->ah_keytype[entry] = keyType[HAL_CIPHER_CLR]; key_type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); /* XXX why not clear key type/valid bit first? */ OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); if (key_type == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */ HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize); OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); /* NB: key type and MAC are known to be ok */ } if (AH_PRIVATE(ah)->ah_curchan == AH_NULL) { return AH_TRUE; } if (ar9300_get_capability(ah, HAL_CAP_BB_RIFS_HANG, 0, AH_NULL) == HAL_OK) { if (key_type == AR_KEYTABLE_TYPE_TKIP || key_type == AR_KEYTABLE_TYPE_40 || key_type == AR_KEYTABLE_TYPE_104 || key_type == AR_KEYTABLE_TYPE_128) { /* SW WAR for Bug 31602 */ if (--ahp->ah_rifs_sec_cnt == 0) { HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: Count = %d, enabling RIFS\n", __func__, ahp->ah_rifs_sec_cnt); ar9300_set_rifs_delay(ah, AH_TRUE); } } } return AH_TRUE; }
HAL_BOOL ar9300_handle_radar_bb_panic(struct ath_hal *ah) { u_int32_t status; u_int32_t val; #ifdef AH_DEBUG struct ath_hal_9300 *ahp = AH9300(ah); #endif status = AH_PRIVATE(ah)->ah_bb_panic_last_status; if ( status == 0x04000539 ) { /* recover from this BB panic without reset*/ /* set AR9300_DFS_FIRPWR to -1 */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= (~AR_PHY_RADAR_0_FIRPWR); val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); OS_DELAY(1); /* set AR9300_DFS_FIRPWR to its default value */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); return AH_TRUE; } else if (status == 0x0400000a) { /* EV 92527 : reset required if we see this signature */ HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__); return AH_FALSE; } else if (status == 0x1300000a) { /* EV92527: we do not need a reset if we see this signature */ HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__); return AH_TRUE; } else if (AR_SREV_WASP(ah) && (status == 0x04000409)) { return AH_TRUE; } else { if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK && (status & 0xff00000f) == 0x04000009 && status != 0x04000409 && status != 0x04000b09 && status != 0x04000e09 && (status & 0x0000ff00)) { /* disable RIFS Rx */ #ifdef AH_DEBUG HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n", __func__, status, ahp->ah_rifs_enabled); #endif ar9300_set_rifs_delay(ah, AH_FALSE); } return AH_FALSE; } }