Index: compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel_ht.c
===================================================================
--- compat-wireless-2014-09-26.orig/net/mac80211/rc80211_minstrel_ht.c
+++ compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel_ht.c
@@ -16,11 +16,11 @@
 #include "rc80211_minstrel.h"
 #include "rc80211_minstrel_ht.h"
 
-#define AVG_PKT_SIZE	1200
-
 /* Spatial stream error threshold in [%] */
 #define STREAM_ERROR_THRES 50
 
+#define AVG_PKT_SIZE 1200
+
 /* Number of bits for an average sized packet */
 #define MCS_NBITS (AVG_PKT_SIZE << 3)
 
@@ -35,7 +35,8 @@
 	)
 
 /* Transmit duration for the raw data part of an average sized packet */
-#define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))
+#define MCS_DURATION(streams, sgi, bps) 				\
+	MCS_SYMBOL_TIME(sgi,MCS_NSYMS((streams) * (bps)))
 
 /*
  * Define group sort order: HT40 -> SGI -> #streams
@@ -88,12 +89,11 @@
 		}						\
 	}
 
+
 /*
  * To enable sufficiently targeted rate sampling, MCS rates are divided into
  * groups, based on the number of streams and flags (HT40, SGI) that they
- * use. The groups are sorted by robustnes in order to enable stepwise
- * increase in robustness by downgrading group index per stream to find
- * best mix between spatial multiplexing and diversity.
+ * use.
  *
  * Sortorder has to be fixed for GROUP_IDX macro to be applicable:
  * HT40 -> SGI -> #streams
@@ -122,6 +122,11 @@ const struct mcs_group minstrel_mcs_grou
 
 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
 
+int size_of_cck_group(void)
+{
+	return (ARRAY_SIZE(minstrel_mcs_groups) - 1);
+}
+
 static void
 minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
 
@@ -162,33 +167,8 @@ minstrel_ht_get_stats(struct minstrel_pr
 static inline struct minstrel_rate_stats *
 minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index)
 {
-	return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
-}
-
-
-/*
- * Recalculate success probabilities and counters for a rate using EWMA
- */
-static void
-minstrel_calc_rate_ewma(struct minstrel_rate_stats *mr)
-{
-	if (unlikely(mr->attempts > 0)) {
-		mr->sample_skipped = 0;
-		mr->cur_prob = MINSTREL_FRAC(mr->success, mr->attempts);
-		if (!mr->att_hist)
-			mr->probability = mr->cur_prob;
-		else
-			mr->probability = minstrel_ewma(mr->probability,
-				mr->cur_prob, EWMA_LEVEL);
-		mr->att_hist += mr->attempts;
-		mr->succ_hist += mr->success;
-	} else {
-		mr->sample_skipped++;
-	}
-	mr->last_success = mr->success;
-	mr->last_attempts = mr->attempts;
-	mr->success = 0;
-	mr->attempts = 0;
+	return &mi->groups[index / MCS_GROUP_RATES].rates[index %
+		MCS_GROUP_RATES];
 }
 
 /*
@@ -206,26 +186,29 @@ minstrel_ht_calc_tp(struct minstrel_ht_s
 	mr = &mi->groups[group].rates[rate];
 	prob = mr->probability;
 
-	if (prob < MINSTREL_FRAC(1, 10)) {
-		mr->cur_tp = 0;
-		return;
-	}
+//	if (prob < MINSTREL_FRAC(1, 10)) {
+//		mr->cur_tp = 0;
+//		return;
+//	}
 
 	/*
-	 * For the throughput calculation, limit the probability value to 90% to
-	 * account for collision related packet error rate fluctuation
+	 * For the throughput calculation, limit the probability value to 90%
+	 * to account for collision related packet error rate fluctuation
 	 */
-	if (prob > MINSTREL_FRAC(9, 10))
-		prob = MINSTREL_FRAC(9, 10);
+//	if (prob > MINSTREL_FRAC(9, 10))
+//		prob = MINSTREL_FRAC(9, 10);
 
 	if (group != MINSTREL_CCK_GROUP)
-		nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len);
+		nsecs = 1000 * mi->overhead /
+		MINSTREL_TRUNC(mi->avg_ampdu_len);
 
 	nsecs += minstrel_mcs_groups[group].duration[rate];
 
 	/* prob is scaled - see MINSTREL_FRAC above */
 	tp = 1000000 * ((prob * 1000) / nsecs);
 	mr->cur_tp = MINSTREL_TRUNC(tp);
+//	mr->cur_tp = tp;
+	mr->max_potential_tp = MINSTREL_TRUNC(1000000 * ((MINSTREL_FRAC(100, 100) * 1000) / nsecs));
 }
 
 /*
@@ -340,39 +323,58 @@ minstrel_ht_assign_best_tp_rates(struct 
 
 }
 
-/*
- * Try to increase robustness of max_prob rate by decrease number of
- * streams if possible.
- */
-static inline void
-minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
+static inline int
+minstrel_get_duration(int index)
 {
-	struct minstrel_mcs_group_data *mg;
-	struct minstrel_rate_stats *mr;
-	int tmp_max_streams, group;
-	int tmp_tp = 0;
+	const struct mcs_group *group = &minstrel_mcs_groups[index /
+		MCS_GROUP_RATES];
+	return group->duration[index % MCS_GROUP_RATES];
+}
 
-	tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] /
-			  MCS_GROUP_RATES].streams;
-	for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
-		mg = &mi->groups[group];
-		if (!mg->supported || group == MINSTREL_CCK_GROUP)
-			continue;
-		mr = minstrel_get_ratestats(mi, mg->max_group_prob_rate);
-		if (tmp_tp < mr->cur_tp &&
-		   (minstrel_mcs_groups[group].streams < tmp_max_streams)) {
-				mi->max_prob_rate = mg->max_group_prob_rate;
-				tmp_tp = mr->cur_tp;
+/* Determine max and min durations of current rate set */
+static void
+minstrel_ht_find_cur_tp_extremum(struct minstrel_ht_sta *mi)
+{
+	unsigned int tmp_rate, tmp_group, tmp_idx;
+	unsigned int max_cur_tp, min_cur_tp, max_rate_dur;
+	int i;
+
+	max_cur_tp = 0;
+	min_cur_tp = ~0;
+	max_rate_dur = 0;
+
+	for (i = 0; i < 2; i++) {
+		if (i != 2) {
+			tmp_rate = mi->max_tp_rate[i];
+			tmp_group = tmp_rate / MCS_GROUP_RATES;
+			tmp_idx = tmp_rate % MCS_GROUP_RATES;
+		} else {
+			tmp_rate = mi->max_prob_rate;
+			tmp_group = tmp_rate / MCS_GROUP_RATES;
+			tmp_idx = tmp_rate % MCS_GROUP_RATES;
 		}
+
+		/* calculate max potential bandwidth of current rate set */
+
+		if (max_cur_tp < mi->groups[tmp_group].rates[tmp_rate].cur_tp)
+			max_cur_tp = mi->groups[tmp_group].rates[tmp_rate].cur_tp;
+
+		if (min_cur_tp > mi->groups[tmp_group].rates[tmp_rate].cur_tp)
+			min_cur_tp = mi->groups[tmp_group].rates[tmp_rate].cur_tp;
+
+		if (max_rate_dur < minstrel_get_duration(tmp_rate))
+			max_rate_dur = minstrel_get_duration(tmp_rate);
 	}
+
+	mi->max_cur_tp = max_cur_tp;
+	mi->min_cur_tp = min_cur_tp;
+	mi->max_rate_dur = max_rate_dur;
 }
 
 /*
  * Update rate statistics and select new primary rates
  *
  * Rules for rate selection:
- *  - max_prob_rate must use only one stream, as a tradeoff between delivery
- *    probability and throughput during strong fluctuations
  *  - as long as the max prob rate has a probability of more than 75%, pick
  *    higher throughput rates, even if the probablity is a bit lower
  */
@@ -392,9 +394,6 @@ minstrel_ht_update_stats(struct minstrel
 		mi->ampdu_packets = 0;
 	}
 
-	mi->sample_slow = 0;
-	mi->sample_count = 0;
-
 	/* Initialize global rate indexes */
 	for(j = 0; j < MAX_THR_RATES; j++){
 		tmp_mcs_tp_rate[j] = 0;
@@ -408,8 +407,6 @@ minstrel_ht_update_stats(struct minstrel
 		if (!mg->supported)
 			continue;
 
-		mi->sample_count++;
-
 		for (i = 0; i < MCS_GROUP_RATES; i++) {
 			if (!(mg->supported & BIT(i)))
 				continue;
@@ -418,7 +415,7 @@ minstrel_ht_update_stats(struct minstrel
 
 			mr = &mg->rates[i];
 			mr->retry_updated = false;
-			minstrel_calc_rate_ewma(mr);
+			minstrel_calc_rate_ewma(mp, mr);
 			minstrel_ht_calc_tp(mi, group, i);
 
 			if (!mr->cur_tp)
@@ -433,7 +430,7 @@ minstrel_ht_update_stats(struct minstrel
 							       tmp_cck_tp_rate);
 			}
 
-			/* Find max probability rate per group and global */
+			/* Find max probability rate */
 			minstrel_ht_set_best_prob_rate(mi, index);
 		}
 	}
@@ -442,11 +439,8 @@ minstrel_ht_update_stats(struct minstrel
 	minstrel_ht_assign_best_tp_rates(mi, tmp_mcs_tp_rate, tmp_cck_tp_rate);
 	memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate));
 
-	/* Try to increase robustness of max_prob_rate*/
-	minstrel_ht_prob_rate_reduce_streams(mi);
-
-	/* try to sample all available rates during each interval */
-	mi->sample_count *= 8;
+	/* Find max and min durations of current rate set */
+	minstrel_ht_find_cur_tp_extremum(mi);
 
 #ifdef CPTCFG_MAC80211_DEBUGFS
 	/* use fixed index if set */
@@ -458,11 +452,12 @@ minstrel_ht_update_stats(struct minstrel
 #endif
 
 	/* Reset update timer */
-	mi->stats_update = jiffies;
+	mi->last_stats_update = jiffies;
 }
 
 static bool
-minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rate)
+minstrel_ht_txstat_valid(struct minstrel_priv *mp,
+	struct ieee80211_tx_rate *rate)
 {
 	if (rate->idx < 0)
 		return false;
@@ -480,7 +475,7 @@ minstrel_ht_txstat_valid(struct minstrel
 }
 
 static void
-minstrel_next_sample_idx(struct minstrel_ht_sta *mi)
+minstrel_set_next_sample_idx(struct minstrel_ht_sta *mi)
 {
 	struct minstrel_mcs_group_data *mg;
 
@@ -517,10 +512,16 @@ minstrel_ht_downgrade_rate(struct minstr
       if (mp->fixed_rate_idx != -1)
 	                return;
 #endif
+	/* search among max_tp_rate[x] & max_prob_rate */
+	for (i = MAX_THR_RATES; i != 0; i--) {
+		if (i < MAX_THR_RATES) {
+			tmp_group = cur_group = mi->max_tp_rate[i] / MCS_GROUP_RATES;
+			cur_idx = mi->max_tp_rate[i] % MCS_GROUP_RATES;
+		} else {
+			tmp_group = cur_group = mi->max_prob_rate / MCS_GROUP_RATES;
+			cur_idx = mi->max_prob_rate % MCS_GROUP_RATES;
+		}
 
-	for (i = 0; i < MAX_THR_RATES; i++) {
-		tmp_group = cur_group = mi->max_tp_rate[i] / MCS_GROUP_RATES;
-		cur_idx = mi->max_tp_rate[i] % MCS_GROUP_RATES;
 		cur_flags = minstrel_mcs_groups[cur_group].flags;
 		cur_streams = minstrel_mcs_groups[cur_group].streams;
 
@@ -542,10 +543,12 @@ minstrel_ht_downgrade_rate(struct minstr
 			/* if possible switch SGI to LGI */
 			if ((cur_flags & IEEE80211_TX_RC_SHORT_GI) &&
 			    !(tmp_flags & IEEE80211_TX_RC_SHORT_GI) &&
-			    ((cur_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) == (tmp_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) &&
+			    ((cur_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+			     (tmp_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) &&
 			    (cur_streams == tmp_streams)) {
 				printk(KERN_ERR "Downgrade rate tp_max_rate[%i] from SGI rate %i -> to LGI rate %i\n", i, mi->max_tp_rate[i], tmp_group * MCS_GROUP_RATES + cur_idx);
-				mi->max_tp_rate[i] = tmp_group * MCS_GROUP_RATES + cur_idx;
+				mi->max_tp_rate[i] = tmp_group * MCS_GROUP_RATES
+								      + cur_idx;
 				break;
 			}
 
@@ -554,7 +557,8 @@ minstrel_ht_downgrade_rate(struct minstr
 			    !(tmp_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
 			    (cur_streams == tmp_streams)) {
 				printk(KERN_ERR "Downgrade rate tp_max_rate[%i] from HT40 rate %i -> to HT20 rate %i\n", i, mi->max_tp_rate[i], tmp_group * MCS_GROUP_RATES + cur_idx);
-				mi->max_tp_rate[i] = tmp_group * MCS_GROUP_RATES + cur_idx;
+				mi->max_tp_rate[i] = tmp_group * MCS_GROUP_RATES
+								      + cur_idx;
 				break;
 			}
 
@@ -563,7 +567,8 @@ minstrel_ht_downgrade_rate(struct minstr
 			   !(tmp_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
 			   !(tmp_flags & IEEE80211_TX_RC_SHORT_GI)) {
 				printk(KERN_ERR "Downgrade rate tp_max_rate[%i] by STREAMS %i from index %i to new index %i \n", i, cur_streams, mi->max_tp_rate[i], tmp_group * MCS_GROUP_RATES + cur_idx);
-				mi->max_tp_rate[i] = tmp_group * MCS_GROUP_RATES + cur_idx;
+				mi->max_tp_rate[i] = tmp_group * MCS_GROUP_RATES
+								      + cur_idx;
 				break;
 			}
 		}
@@ -608,7 +613,8 @@ minstrel_ht_tx_status(void *priv, struct
 	int i;
 
 	if (!msp->is_ht)
-		return mac80211_minstrel.tx_status(priv, sband, sta, &msp->legacy, skb);
+		return mac80211_minstrel.tx_status(priv, sband, sta,
+			&msp->legacy, skb);
 
 	/* This packet was aggregated but doesn't carry status info */
 	if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -624,12 +630,6 @@ minstrel_ht_tx_status(void *priv, struct
 	mi->ampdu_packets++;
 	mi->ampdu_len += info->status.ampdu_len;
 
-	if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
-		mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len);
-		mi->sample_tries = 1;
-		mi->sample_count--;
-	}
-
 	if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
 		mi->sample_packets += info->status.ampdu_len;
 
@@ -657,7 +657,8 @@ minstrel_ht_tx_status(void *priv, struct
 	    (MINSTREL_FRAC(info->status.ampdu_ack_len, info->status.ampdu_len) <
 	    MINSTREL_FRAC(STREAM_ERROR_THRES, 100))) {
 		mi->stream_errors++;
-		if (mi->stream_errors > 3) {
+		/* check stream errors at one-tenth of channel coherence */
+		if (mi->stream_errors >= 3) {
 
 #ifdef CONFIG_MAC80211_DEBUGFS
 			if (mp->simlple_downgrade != 1) {
@@ -676,7 +677,9 @@ minstrel_ht_tx_status(void *priv, struct
 		}
 	} else
 		mi->stream_errors = 0;
-	if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) {
+
+	if (time_after(jiffies, mi->last_stats_update +
+				(WIFI_COHERENCE_TIME * 2 * HZ) / 1000)) {
 		update = true;
 		minstrel_ht_update_stats(mp, mi);
 		if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -713,7 +716,8 @@ minstrel_calc_retransmit(struct minstrel
 	mr->retry_updated = true;
 
 	group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
-	tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000;
+	tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len /
+		1000;
 
 	/* Contention time for first 2 tries */
 	ctime = (t_slot * cw) >> 1;
@@ -749,9 +753,10 @@ minstrel_calc_retransmit(struct minstrel
 
 static void
 minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
-                     struct ieee80211_sta_rates *ratetbl, int offset, int index)
+		     struct ieee80211_sta_rates *ratetbl, int offset, int index)
 {
-	const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
+	const struct mcs_group *group = &minstrel_mcs_groups[index /
+		MCS_GROUP_RATES];
 	struct minstrel_rate_stats *mr;
 	u8 idx;
 	u16 flags;
@@ -815,78 +820,28 @@ minstrel_ht_update_rates(struct minstrel
 	rate_control_set_rates(mp->hw, mi->sta, rates);
 }
 
-static inline int
-minstrel_get_duration(int index)
-{
-	const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
-	return group->duration[index % MCS_GROUP_RATES];
-}
-
 static int
-minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
+minstrel_ht_get_next_sample(struct minstrel_ht_sta *mi)
 {
-	struct minstrel_rate_stats *mr;
 	struct minstrel_mcs_group_data *mg;
-	unsigned int sample_dur, sample_group, cur_max_tp_streams;
-	int sample_idx = 0;
-
-	if (mi->sample_wait > 0) {
-		mi->sample_wait--;
-		return -1;
-	}
-
-	if (!mi->sample_tries)
-		return -1;
+	unsigned int sample_group;
+	unsigned int sample_idx = 0;
+	unsigned int sample_rate = 0;
 
 	sample_group = mi->sample_group;
 	mg = &mi->groups[sample_group];
 	sample_idx = sample_table[mg->column][mg->index];
-	minstrel_next_sample_idx(mi);
-
-	if (!(mg->supported & BIT(sample_idx)))
-		return -1;
-
-	mr = &mg->rates[sample_idx];
-	sample_idx += sample_group * MCS_GROUP_RATES;
-
-	/*
-	 * Sampling might add some overhead (RTS, no aggregation)
-	 * to the frame. Hence, don't use sampling for the currently
-	 * used rates.
-	 */
-	if (sample_idx == mi->max_tp_rate[0] ||
-	    sample_idx == mi->max_tp_rate[1] ||
-	    sample_idx == mi->max_prob_rate)
-		return -1;
-
-	/*
-	 * Do not sample if the probability is already higher than 95%
-	 * to avoid wasting airtime.
-	 */
-	if (mr->probability > MINSTREL_FRAC(95, 100))
-		return -1;
+	minstrel_set_next_sample_idx(mi);
 
-	/*
-	 * Make sure that lower rates get sampled only occasionally,
-	 * if the link is working perfectly.
-	 */
-
-	cur_max_tp_streams = minstrel_mcs_groups[mi->max_tp_rate[0] /
-		MCS_GROUP_RATES].streams;
-	sample_dur = minstrel_get_duration(sample_idx);
-	if (sample_dur >= minstrel_get_duration(mi->max_tp_rate[1]) &&
-	    (cur_max_tp_streams - 1 <
-	     minstrel_mcs_groups[sample_group].streams ||
-	     sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {
-		if (mr->sample_skipped < 20)
-			return -1;
-
-		if (mi->sample_slow++ > 2)
-			return -1;
+	while (!(mg->supported & BIT(sample_idx))) {
+		sample_group = mi->sample_group;
+		mg = &mi->groups[sample_group];
+		sample_idx = sample_table[mg->column][mg->index];
+		minstrel_set_next_sample_idx(mi);
 	}
-	mi->sample_tries--;
+	sample_rate = sample_group * MCS_GROUP_RATES + sample_idx;
 
-	return sample_idx;
+	return sample_rate;
 }
 
 static void
@@ -905,27 +860,61 @@ minstrel_ht_check_cck_shortpreamble(stru
 	mi->groups[MINSTREL_CCK_GROUP].supported = supported;
 }
 
+/* Check whether rate sampling is required */
+static inline bool
+minstrel_ht_requires_sampling(struct minstrel_ht_sta *mi,
+	struct minstrel_priv *mp, unsigned int rate_sampling_interval)
+{
+      if (mi->cur_intersample_spacing >= MIN_INTERSAMPLE_SPACING &&
+	 (time_after(jiffies, mi->last_rate_update +
+	 (rate_sampling_interval * HZ) / 1000))) {
+			mi->cur_intersample_spacing = 0;
+			mi->last_rate_update = jiffies;
+			return true;
+	} else {
+		mi->cur_intersample_spacing++;
+		return false;
+	}
+}
+
 static void
 minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
                      struct ieee80211_tx_rate_control *txrc)
 {
-	const struct mcs_group *sample_group;
+	const struct mcs_group *sample_rate_group;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
-	struct ieee80211_tx_rate *rate = &info->status.rates[0];
+	struct ieee80211_tx_rate *sampling_setup = NULL;
 	struct minstrel_ht_sta_priv *msp = priv_sta;
 	struct minstrel_ht_sta *mi = &msp->ht;
 	struct minstrel_priv *mp = priv;
-	int sample_idx;
+	unsigned int rate_sampling_int = 0;
+	unsigned int s_prob, s_group, s_idx, s_dur, s_skipped, s_thr;
+	unsigned int sample_rate;
+	int i, max_r, random_skipp;
+	bool rate_sampling = false;
+	bool mrr_capable = false;
 
+	/* management/no-ack frames do not use rate control */
 	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
 
+	/* legacy packets (non 802.11n) are handled by minstrel rate control */
 	if (!msp->is_ht)
-		return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
+		return mac80211_minstrel.get_rate(priv, sta, &msp->legacy,
+			txrc);
 
 	info->flags |= mi->tx_flags;
 	minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);
 
+	/* increase sum packet counter */
+	mi->total_packets++;
+
+	/* wraparound */
+	if (mi->total_packets == ~0) {
+		mi->total_packets = 0;
+		mi->sample_packets = 0;
+	}
+
 #ifdef CPTCFG_MAC80211_DEBUGFS
 	if (mp->fixed_rate_idx != -1)
 		return;
@@ -934,35 +923,118 @@ minstrel_ht_get_rate(void *priv, struct 
 	/* Don't use EAPOL frames for sampling on non-mrr hw */
 	if (mp->hw->max_rates == 1 &&
 	    (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
-		sample_idx = -1;
+		return;
+
+	/* Check multi-rate-retry capabilities & adjust sampling interval */
+	mrr_capable = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
+	if (mrr_capable)
+		rate_sampling_int = WIFI_COHERENCE_TIME / 2;
 	else
-		sample_idx = minstrel_get_sample_rate(mp, mi);
+		rate_sampling_int = WIFI_COHERENCE_TIME;
 
-	mi->total_packets++;
+	rate_sampling = minstrel_ht_requires_sampling(mi, mp, rate_sampling_int);
 
-	/* wraparound */
-	if (mi->total_packets == ~0) {
-		mi->total_packets = 0;
-		mi->sample_packets = 0;
-	}
+	if (unlikely(rate_sampling)) {
+		/* Only consider rates with a probability of < 80% as we
+		 * we would waste airtime otherwise */
+		max_r = MCS_GROUP_RATES * ARRAY_SIZE(minstrel_mcs_groups) + 1;
+
+		for (i = max_r; i != 0; i--) {
+			/* get next random rate sample */
+			sample_rate = minstrel_ht_get_next_sample(mi);
+
+// TRY REAL RANDOM FUNCTION prandom_u32_max()
+
+			s_idx = sample_rate % MCS_GROUP_RATES;
+			s_group = sample_rate / MCS_GROUP_RATES;
+			s_dur = minstrel_get_duration(sample_rate);
+			s_skipped = mi->groups[s_group].rates[s_idx].sample_skipped;
+			s_prob = mi->groups[s_group].rates[s_idx].probability;
+
+			/* if no sample attempts happend, do initial sampling */
+			if (mi->groups[s_group].rates[s_idx].att_hist < 3)
+				break;
+
+			/* max potential throughput of sample_rate */
+			s_thr = mi->groups[s_group].rates[s_idx].max_potential_tp;
 
-	if (sample_idx < 0)
+
+			//test random packet skip interval
+			random_skipp = (u32)(((u64) prandom_u32() * WIFI_COHERENCE_TIME) >> 32);
+
+			if ((s_skipped < random_skipp) &&
+			    (s_thr > mi->max_cur_tp * 2)) {
+//				printk(KERN_ERR "rate: %u 2 fast ( s_thr: %u >= 2x max_cur_tp: %u ) -> rand skip: %i\n", sample_rate, s_thr, mi->max_cur_tp, random_skipp);
+				continue;
+			}
+			if ((s_skipped < random_skipp + WIFI_COHERENCE_TIME) &&
+			    (s_thr <  mi->min_cur_tp)) {
+//				printk(KERN_ERR "rate: %u too SLOW ( s_thr: %u <= min_cur_tp: %u ) -> rand skip: %i \n", sample_rate, s_thr, mi->min_cur_tp, random_skipp);
+				continue;
+			}
+
+			/* Reduce sampling of rates potentially slower and
+			 * 2-times faster than current rate set to avoid
+			 * unnecessary sampling hence wasting scars airtime*/
+/*			if (s_skipped < WIFI_COHERENCE_TIME) {
+				if (s_dur >= mi->max_rate_dur)
+					continue;
+				else if (s_dur <  mi->min_rate_dur / 2)
+					continue;
+			}
+*/
+
+			/* do not sample current max tp rates */
+			if ((sample_rate == mi->max_tp_rate[0]) ||
+			    (sample_rate == mi->max_tp_rate[1]))
+				continue;
+
+			if (s_prob < MINSTREL_FRAC(75, 100)) {
+				break;
+			}
+		}
+
+		/* if no rate for sampling is found, skipp sampling*/
+		if (i == 0) {
+//			printk(KERN_ERR "keine passende sampling rate gefunden -> kein sampling -> RETURN\n");
+			return;
+		}
+
+		/* Decide if direct (1st mrr stage) or indirect (2nd mrr stage)
+		 * method should be used. Respect such rates that are not
+		 * sampled for 4 * WIFI_COHERENCE_TIME iterations. */
+		if (s_dur > mi->max_rate_dur) {
+//		    &&
+//		    (s_skipped > WIFI_COHERENCE_TIME)) {
+//		    (random_skipp > 6 + WIFI_COHERENCE_TIME / 5)) {  //balance 50% of slow rates between indirect & direct
+			sampling_setup = &info->control.rates[1];
+//			printk(KERN_ERR " INDIRECT sampling of rate %u mit test dur: %u > mi->max_rate_dur: %u \n", sample_rate, s_dur, mi->max_rate_dur);
+		} else {
+			sampling_setup = &info->control.rates[0];
+			mi->sample_packets++;
+		}
+
+		/* Annotate rate sampling packets to avoid aggregation */
+		info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+	} else {
+		/* no sampling required */
 		return;
+	}
 
-	sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
-	info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-	rate->count = 1;
-
-	if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
-		int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
-		rate->idx = mp->cck_rates[idx];
-		rate->flags = 0;
+	/* If CCK sampling assign parameter */
+	if (s_group == MINSTREL_CCK_GROUP) {
+		int idx = sample_rate % ARRAY_SIZE(mp->cck_rates);
+		sampling_setup->idx = mp->cck_rates[idx];
+		sampling_setup->count = 1;
+		sampling_setup->flags = 0;
 		return;
 	}
 
-	rate->idx = sample_idx % MCS_GROUP_RATES +
-		    (sample_group->streams - 1) * 8;
-	rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
+	/* Assign MCS sampling parameter */
+	sample_rate_group = &minstrel_mcs_groups[s_group];
+	sampling_setup->idx = s_idx + (sample_rate_group->streams - 1) * 8;
+	sampling_setup->count = 1;
+	sampling_setup->flags = IEEE80211_TX_RC_MCS | sample_rate_group->flags;
 }
 
 static void
@@ -1018,7 +1090,7 @@ minstrel_ht_update_caps(void *priv, stru
 	memset(mi, 0, sizeof(*mi));
 
 	mi->sta = sta;
-	mi->stats_update = jiffies;
+	mi->last_stats_update = jiffies;
 
 	ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1, 0);
 	mi->overhead = ieee80211_frame_duration(sband->band, 0, 60, 1, 1, 0);
@@ -1027,16 +1099,6 @@ minstrel_ht_update_caps(void *priv, stru
 
 	mi->avg_ampdu_len = MINSTREL_FRAC(1, 1);
 
-	/* When using MRR, sample more on the first attempt, without delay */
-	if (mp->has_mrr) {
-		mi->sample_count = 16;
-		mi->sample_wait = 0;
-	} else {
-		mi->sample_count = 8;
-		mi->sample_wait = 8;
-	}
-	mi->sample_tries = 4;
-
 	stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
 		IEEE80211_HT_CAP_RX_STBC_SHIFT;
 	mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
@@ -1052,7 +1114,8 @@ minstrel_ht_update_caps(void *priv, stru
 		}
 
 		if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) {
-			if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+			if (minstrel_mcs_groups[i].flags &
+				IEEE80211_TX_RC_40_MHZ_WIDTH) {
 				if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
 					continue;
 			} else {
@@ -1061,14 +1124,15 @@ minstrel_ht_update_caps(void *priv, stru
 			}
 		}
 
-		if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH &&
-		    sta->bandwidth < IEEE80211_STA_RX_BW_40)
-			continue;
+		if (minstrel_mcs_groups[i].flags &
+			IEEE80211_TX_RC_40_MHZ_WIDTH &&
+			sta->bandwidth < IEEE80211_STA_RX_BW_40)
+				continue;
 
 		/* Mark MCS > 7 as unsupported if STA is in static SMPS mode */
 		if (sta->smps_mode == IEEE80211_SMPS_STATIC &&
-		    minstrel_mcs_groups[i].streams > 1)
-			continue;
+			minstrel_mcs_groups[i].streams > 1)
+				continue;
 
 		mi->groups[i].supported =
 			mcs->rx_mask[minstrel_mcs_groups[i].streams - 1];
@@ -1092,7 +1156,7 @@ use_legacy:
 	msp->legacy.r = msp->ratelist;
 	msp->legacy.sample_table = msp->sample_table;
 	return mac80211_minstrel.rate_init(priv, sband, chandef, sta,
-					   &msp->legacy);
+					&msp->legacy);
 }
 
 static void
@@ -1100,7 +1164,9 @@ minstrel_ht_rate_init(void *priv, struct
 		      struct cfg80211_chan_def *chandef,
                       struct ieee80211_sta *sta, void *priv_sta)
 {
+	struct minstrel_ht_sta_priv *msp = priv_sta;
 	minstrel_ht_update_caps(priv, sband, chandef, sta, priv_sta);
+	msp->ht.last_rate_update = jiffies;
 }
 
 static void
Index: compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel_ht.h
===================================================================
--- compat-wireless-2014-09-26.orig/net/mac80211/rc80211_minstrel_ht.h
+++ compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel_ht.h
@@ -26,6 +26,8 @@ struct mcs_group {
 
 extern const struct mcs_group minstrel_mcs_groups[];
 
+int size_of_cck_group(void);
+
 struct minstrel_mcs_group_data {
 	u8 index;
 	u8 column;
@@ -54,8 +56,19 @@ struct minstrel_ht_sta {
 	u8 max_tp_rate[MAX_THR_RATES];
 	u8 max_prob_rate;
 
+	/* max and min durations of current rate set*/
+	unsigned int max_cur_tp;
+	unsigned int min_cur_tp;
+	unsigned int max_rate_dur;
+
 	/* time of last status update */
-	unsigned long stats_update;
+	unsigned long last_stats_update;
+
+	/* time of last rate sampling update */
+	unsigned long last_rate_update;
+
+	/* min # of packets between sample attempts */
+	u8 cur_intersample_spacing;
 
 	/* overhead time in usec for each frame */
 	unsigned int overhead;
@@ -68,11 +81,6 @@ struct minstrel_ht_sta {
 	u32 tx_flags;
 	u8 stream_errors;
 
-	u8 sample_wait;
-	u8 sample_tries;
-	u8 sample_count;
-	u8 sample_slow;
-
 	/* current MCS group to be sampled */
 	u8 sample_group;
 
@@ -80,7 +88,8 @@ struct minstrel_ht_sta {
 	u8 cck_supported_short;
 
 	/* MCS rate group info and statistics */
-	struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1];
+	struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS *
+		MINSTREL_STREAM_GROUPS + 1];
 };
 
 struct minstrel_ht_sta_priv {
Index: compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel_ht_debugfs.c
===================================================================
--- compat-wireless-2014-09-26.orig/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -20,7 +20,7 @@ minstrel_ht_stats_dump(struct minstrel_h
 {
 	unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS;
 	const struct mcs_group *mg;
-	unsigned int j, tp, prob, eprob;
+	unsigned int j, tp, prob, eprob, max_tp;
 	char htmode = '2';
 	char gimode = 'L';
 
@@ -59,12 +59,17 @@ minstrel_ht_stats_dump(struct minstrel_h
 			p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j);
 		}
 
+		 p += sprintf(p, "   %-3u", idx);
+
+		max_tp = mr->max_potential_tp /10;
 		tp = mr->cur_tp / 10;
+//		tp = MINSTREL_TRUNC(mr->cur_tp) / 10;
 		prob = MINSTREL_TRUNC(mr->cur_prob * 1000);
 		eprob = MINSTREL_TRUNC(mr->probability * 1000);
 
-		p += sprintf(p, "      %6u.%1u   %6u.%1u    %6u.%1u    "
+		p += sprintf(p, " %6u.%1u  %6u.%1u   %6u.%1u    %6u.%1u    "
 				"%3u            %3u(%3u)  %8llu    %8llu\n",
+				max_tp /10, max_tp % 10,
 				tp / 10, tp % 10,
 				eprob / 10, eprob % 10,
 				prob / 10, prob % 10,
@@ -102,7 +107,7 @@ minstrel_ht_stats_open(struct inode *ino
 
 	file->private_data = ms;
 	p = ms->buf;
-	p += sprintf(p, "type           rate     throughput  ewma prob   "
+	p += sprintf(p, "type           rate   idx    max_tp    cur_tp  ewma prob   "
 		     "this prob  retry   this succ/attempt   success    attempts\n");
 
 	p = minstrel_ht_stats_dump(mi, max_mcs, p);
Index: compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel.c
===================================================================
--- compat-wireless-2014-09-26.orig/net/mac80211/rc80211_minstrel.c
+++ compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel.c
@@ -153,20 +153,21 @@ minstrel_calc_rate_ewma(struct minstrel_
 {
 	int target_attempts, aging_factor;
 
-	target_attempts = 2;
+	target_attempts = 3;
 
 	/* Dynamic weigthting factor for EWMA calculation. The number of
-	* attempts to send a packet at a certain rate within an statistic
-	* update interval respresents the timeliness of success probability. */
-	if (mr->attempts > 10 * target_attempts)
-		aging_factor = 768; /* ~75% */
-	else if (mr->attempts > target_attempts)
-		aging_factor = 820; /* ~80% */
+	 * attempts to send a packet at a certain rate within an statistic
+	 * update interval respresents the timeliness of success probability.
+	 */
+	if (mr->attempts >= 4 * target_attempts)
+		aging_factor = 1638; /* ~80% */
+	else if (mr->attempts >= target_attempts)
+		aging_factor = 1536; /* ~75% */
 	else if (mr->attempts > 0)
-		aging_factor = 920; /* ~90% */
+		aging_factor = 1434; /* ~70% */
 	else {
-		/* = ~99% to age prob. of non-sampled rates by 10% in 10sec */
-		aging_factor = 1023;
+		/* age prob. of unsampled rates as it gets out-of-date */
+		aging_factor = 2047;
 	}
 
 	if (unlikely(mr->attempts > 0)) {
Index: compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel.h
===================================================================
--- compat-wireless-2014-09-26.orig/net/mac80211/rc80211_minstrel.h
+++ compat-wireless-2014-09-26/net/mac80211/rc80211_minstrel.h
@@ -9,8 +9,8 @@
 #ifndef __RC_MINSTREL_H
 #define __RC_MINSTREL_H
 
-#define EWMA_DIV	1024
-#define EWMA_LEVEL	 768	/* ewma weighting factor of 75% [/EWMA_DIV] */
+#define EWMA_DIV	2048
+#define EWMA_LEVEL	1536	/* ewma weighting factor of 75% [/EWMA_DIV] */
 #define SAMPLE_COLUMNS	10	/* number of columns in sample table */
 
 
