Index: compat-wireless-2014-10-08/net/mac80211/rc80211_minstrel_ht.c
===================================================================
--- compat-wireless-2014-10-08.orig/net/mac80211/rc80211_minstrel_ht.c	2014-10-19 10:15:38.559682049 +0200
+++ compat-wireless-2014-10-08/net/mac80211/rc80211_minstrel_ht.c	2014-10-19 10:17:44.178221521 +0200
@@ -186,17 +186,12 @@
 	mr = &mi->groups[group].rates[rate];
 	prob = mr->probability;
 
-//	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
 	 */
-//	if (prob > MINSTREL_FRAC(9, 10))
-//		prob = MINSTREL_FRAC(9, 10);
+	if (prob > MINSTREL_FRAC(90, 100))
+		prob = MINSTREL_FRAC(90, 100);
 
 	if (group != MINSTREL_CCK_GROUP)
 		nsecs = 1000 * mi->overhead /
@@ -204,11 +199,16 @@
 
 	nsecs += minstrel_mcs_groups[group].duration[rate];
 
+	mr->max_potential_tp = MINSTREL_TRUNC(1000000 * ((MINSTREL_FRAC(100, 100) * 1000) / nsecs));
+
+	if (prob < MINSTREL_FRAC(10, 100)) {
+		mr->cur_tp = 0;
+		return;
+	}
+
 	/* 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));
 }
 
 /*
@@ -335,40 +335,25 @@
 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 */
+	unsigned int tmp_group, tmp_idx;
 
-		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;
+	tmp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES;
+	tmp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
+	mi->max_cur_tp = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
+
+	tmp_group = mi->max_tp_rate[1] / MCS_GROUP_RATES;
+	tmp_idx = mi->max_tp_rate[1] % MCS_GROUP_RATES;
+	mi->min_cur_tp = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
+	mi->max_rate_dur = minstrel_get_duration(mi->max_tp_rate[1]);
 
-		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);
+	tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
+	tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
+	if (mi->min_cur_tp < mi->groups[tmp_group].rates[tmp_idx].cur_tp) {
+		tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
+		tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
+		mi->min_cur_tp = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
+		mi->max_rate_dur = minstrel_get_duration(mi->max_prob_rate);
 	}
-
-	mi->max_cur_tp = max_cur_tp;
-	mi->min_cur_tp = min_cur_tp;
-	mi->max_rate_dur = max_rate_dur;
 }
 
 /*
@@ -497,80 +482,67 @@
 }
 
 /*
- * Downgrading is done by lowering group index as group index is sorted
- * in ascending order of robustness. When possible it first switches
+ * Downgrading is done for the max_prob rate. When possible it first switches
  * from SGI to LGI, second lowers HT40 to HT20 and then reduces the
  * number of streams.
  */
 static void
 minstrel_ht_downgrade_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
 {
-	int i, cur_group, cur_idx, cur_flags, cur_streams;
+	int cur_group, cur_idx, cur_flags, cur_streams;
 	int tmp_group, tmp_flags, tmp_streams;
 
 #ifdef CPTCFG_MAC80211_DEBUGFS
       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;
-		}
+	tmp_group = cur_group = mi->max_prob_rate / MCS_GROUP_RATES;
+	cur_idx = mi->max_prob_rate % MCS_GROUP_RATES;
 
-		cur_flags = minstrel_mcs_groups[cur_group].flags;
-		cur_streams = minstrel_mcs_groups[cur_group].streams;
+	cur_flags = minstrel_mcs_groups[cur_group].flags;
+	cur_streams = minstrel_mcs_groups[cur_group].streams;
 
-		/* Ignore CCK group and lowest single stream rate */
-		if ((cur_group == MINSTREL_CCK_GROUP) ||
-		    (cur_idx == 0 && cur_streams == 1)) {
-			continue;
-		}
-
-		while (tmp_group > 0) {
-			tmp_group--;
-
-			tmp_flags = minstrel_mcs_groups[tmp_group].flags;
-			tmp_streams = minstrel_mcs_groups[tmp_group].streams;
+	/* Ignore CCK group and lowest single stream rate */
+	if ((cur_group == MINSTREL_CCK_GROUP) ||
+	    (cur_idx == 0 && cur_streams == 1))
+		return;
 
-			if (!mi->groups[tmp_group].supported)
-				continue;
+	while (tmp_group > 0) {
+		tmp_group--;
 
-			/* 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_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;
-				break;
-			}
+		tmp_flags = minstrel_mcs_groups[tmp_group].flags;
+		tmp_streams = minstrel_mcs_groups[tmp_group].streams;
 
-			/* if possible switch HT40 to HT20 */
-			if ((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 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;
-				break;
-			}
+		if (!mi->groups[tmp_group].supported)
+			continue;
 
-			/* if possible reduce streams by 1 */
-			if ((cur_streams > 1) &&
-			   !(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;
-				break;
-			}
+		/* 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_streams == tmp_streams)) {
+//			printk(KERN_ERR "Downgrade max_tp_rate from SGI rate %i -> to LGI rate %i\n", mi->max_prob_rate, tmp_group * MCS_GROUP_RATES + cur_idx);
+			mi->max_prob_rate = tmp_group * MCS_GROUP_RATES + cur_idx;
+			break;
+		}
+
+		/* if possible switch HT40 to HT20 */
+		if ((cur_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+		    !(tmp_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+		    (cur_streams == tmp_streams)) {
+//			printk(KERN_ERR "Downgrade max_tp_rate from HT40 rate %i -> to HT20 rate %i\n", mi->max_prob_rate, tmp_group * MCS_GROUP_RATES + cur_idx);
+			mi->max_prob_rate = tmp_group * MCS_GROUP_RATES + cur_idx;
+			break;
+		}
+
+		/* if possible reduce streams by 1 */
+		if ((cur_streams > 1) &&
+		   !(tmp_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+		   !(tmp_flags & IEEE80211_TX_RC_SHORT_GI)) {
+//			printk(KERN_ERR "Downgrade max_tp_rate by STREAMS %i from index %i to new index %i \n", cur_streams, mi->max_prob_rate, tmp_group * MCS_GROUP_RATES + cur_idx);
+			mi->max_prob_rate = tmp_group * MCS_GROUP_RATES + cur_idx;
+			break;
 		}
 	}
 }
@@ -662,11 +634,11 @@
 
 #ifdef CONFIG_MAC80211_DEBUGFS
 			if (mp->simlple_downgrade != 1) {
-				minstrel_ht_downgrade_rate(mo, mi);
+				minstrel_ht_downgrade_rate(mp, mi);
 			} else {
 				/* simplified downgrade version */
-				mi->tp_max_rate[0] = mi->mac_tp_rate[2];
-				mi->tp_max_rate[1] = mi->mac_tp_rate[3];
+				mi->max_tp_rate[0] = mi->max_tp_rate[2];
+				mi->max_tp_rate[1] = mi->max_tp_rate[3];
 			}
 #else
 			minstrel_ht_downgrade_rate(mp, mi);
@@ -942,54 +914,42 @@
 		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;
+			s_thr = mi->groups[s_group].rates[s_idx].max_potential_tp;
 
 			/* 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;
-
-
-			//test random packet skip interval
+			/* generate random packet skip interval */
 			random_skipp = (u32)(((u64) prandom_u32() * WIFI_COHERENCE_TIME) >> 32);
 
+			/* 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 < 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);
+//				printk(KERN_ERR "rate: %u 2 fast ( s_thr: %u >= 2x max_cur_tp: %u ) -> rand skip: %i & s_skipped: %i \n", sample_rate, s_thr, mi->max_cur_tp, random_skipp, s_skipped);
+				mi->groups[s_group].rates[s_idx].sample_skipped++;
 				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);
+			if ((s_skipped < random_skipp) &&
+			    (s_thr * 2 <  mi->min_cur_tp)) {
+//				printk(KERN_ERR "rate: %u too SLOW ( s_thr: %u <= min_cur_tp: %u ) -> rand skip: %i & s_skipped: %i \n", sample_rate, s_thr, mi->min_cur_tp, random_skipp, s_skipped);
+				mi->groups[s_group].rates[s_idx].sample_skipped++;
 				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]))
+			/* do not sample current max tp rate */
+			if (sample_rate == mi->max_tp_rate[0])
 				continue;
 
-			if (s_prob < MINSTREL_FRAC(75, 100)) {
+			/* sample this rate if it is not allready perfect */
+			if (s_prob < MINSTREL_FRAC(95, 100)) {
 				break;
 			}
 		}
@@ -1001,23 +961,21 @@
 		}
 
 		/* 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
+		 * method should be used. */
+		if (s_dur > mi->max_rate_dur * 2) {
 			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++;
+//printk(KERN_ERR "direct rate sampling is performed with sample rate %i\n", sample_rate);
 		}
 
 		/* Annotate rate sampling packets to avoid aggregation */
 		info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
 	} else {
 		/* no sampling required */
+//printk(KERN_ERR "no rate sampling required");
 		return;
 	}
 
