diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4e3b97c3d7c2de5a7b0cdb096af5e370a44426ac..b3c7241a62a5b9cebf6dc757e806448bc983c8c5 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2654,6 +2654,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
 							bool skip_pcu)
 {
 	struct ath5k_hw *ah = sc->ah;
+	struct ath_common *common = ath5k_hw_common(ah);
 	int ret, ani_mode;
 
 	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
@@ -2696,6 +2697,14 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
 	ah->ah_cal_next_nf = jiffies;
 	ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
 
+	/* clear survey data and cycle counters */
+	memset(&sc->survey, 0, sizeof(sc->survey));
+	spin_lock(&common->cc_lock);
+	ath_hw_cycle_counters_update(common);
+	memset(&common->cc_survey, 0, sizeof(common->cc_survey));
+	memset(&common->cc_ani, 0, sizeof(common->cc_ani));
+	spin_unlock(&common->cc_lock);
+
 	/*
 	 * Change channels and update the h/w rate map if we're switching;
 	 * e.g. 11a to 11b/g.
@@ -3362,25 +3371,27 @@ static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
 	if (idx != 0)
 		return -ENOENT;
 
-	survey->channel = conf->channel;
-	survey->filled = SURVEY_INFO_NOISE_DBM;
-	survey->noise = sc->ah->ah_noise_floor;
-
 	spin_lock_bh(&common->cc_lock);
 	ath_hw_cycle_counters_update(common);
 	if (cc->cycles > 0) {
-		survey->filled |= SURVEY_INFO_CHANNEL_TIME |
-			SURVEY_INFO_CHANNEL_TIME_BUSY |
-			SURVEY_INFO_CHANNEL_TIME_RX |
-			SURVEY_INFO_CHANNEL_TIME_TX;
-		survey->channel_time += cc->cycles / div;
-		survey->channel_time_busy += cc->rx_busy / div;
-		survey->channel_time_rx += cc->rx_frame / div;
-		survey->channel_time_tx += cc->tx_frame / div;
+		sc->survey.channel_time += cc->cycles / div;
+		sc->survey.channel_time_busy += cc->rx_busy / div;
+		sc->survey.channel_time_rx += cc->rx_frame / div;
+		sc->survey.channel_time_tx += cc->tx_frame / div;
 	}
 	memset(cc, 0, sizeof(*cc));
 	spin_unlock_bh(&common->cc_lock);
 
+	memcpy(survey, &sc->survey, sizeof(*survey));
+
+	survey->channel = conf->channel;
+	survey->noise = sc->ah->ah_noise_floor;
+	survey->filled = SURVEY_INFO_NOISE_DBM |
+			SURVEY_INFO_CHANNEL_TIME |
+			SURVEY_INFO_CHANNEL_TIME_BUSY |
+			SURVEY_INFO_CHANNEL_TIME_RX |
+			SURVEY_INFO_CHANNEL_TIME_TX;
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index aa6c32aafb5927102160c0aba6f6dd77074800b5..6d511476e4d2695c1b0a8edb1eac552620cd06eb 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -258,6 +258,8 @@ struct ath5k_softc {
 	struct tasklet_struct	ani_tasklet;	/* ANI calibration */
 
 	struct delayed_work	tx_complete_work;
+
+	struct survey_info	survey;		/* collected survey info */
 };
 
 #define ath5k_hw_hasbssidmask(_ah) \