| @@ -69,14 +69,31 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix) · 68 unmodified lines |
| 69 | return i; | 69 | return i; |
| 70 | } | 70 | } |
| 71 | | 71 | |
| | 72 | /* find & sort topmost throughput rates */ |
| | 73 | static inline void |
| | 74 | minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) |
| | 75 | { |
| | 76 | int j = MAX_THR_RATES; |
| | 77 | |
| | 78 | while (j > 0 && mi->r[i].cur_tp > mi->r[tp_list[j - 1]].cur_tp) |
| | 79 | j--; |
| | 80 | if (j < MAX_THR_RATES - 1) |
| | 81 | memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1)); |
| | 82 | if (j < MAX_THR_RATES) |
| | 83 | tp_list[j] = i; |
| | 84 | } |
| | 85 | |
| 72 | static void | 86 | static void |
| 73 | minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | 87 | minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) |
| 74 | { | 88 | { |
| 75 | u32 max_tp = 0, index_max_tp = 0, index_max_tp2 = 0; | 89 | u8 tmp_tp_rate[MAX_THR_RATES]; |
| 76 | u32 max_prob = 0, index_max_prob = 0; | 90 | u8 tmp_prob_rate = 0; |
| 77 | u32 usecs; | 91 | u32 usecs; |
| 78 | int i; | 92 | int i; |
| 79 | | 93 | |
| | 94 | for (i=0; i < MAX_THR_RATES; i++) |
| | 95 | tmp_tp_rate[i] = 0; |
| | 96 | |
| 80 | for (i = 0; i < mi->n_rates; i++) { | 97 | for (i = 0; i < mi->n_rates; i++) { |
| 81 | struct minstrel_rate *mr = &mi->r[i]; | 98 | struct minstrel_rate *mr = &mi->r[i]; |
| 82 | | 99 | |
| @@ -120,35 +137,27 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) · 37 unmodified lines |
| 120 | } | 137 | } |
| 121 | if (!mr->adjusted_retry_count) | 138 | if (!mr->adjusted_retry_count) |
| 122 | mr->adjusted_retry_count = 2; | 139 | mr->adjusted_retry_count = 2; |
| 123 | } | | |
| 124 | | 140 | |
| 125 | for (i = 0; i < mi->n_rates; i++) { | 141 | minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate); |
| 126 | struct minstrel_rate *mr = &mi->r[i]; | 142 | |
| 127 | if (max_tp < mr->cur_tp) { | 143 | /* To determine the most robust rate (max_prob_rate) used at |
| 128 | index_max_tp = i; | 144 | * 3rd mmr stage we distinct between two cases: |
| 129 | max_tp = mr->cur_tp; | 145 | * (1) if any success probabilitiy >= 95%, out of those rates |
| 130 | } | 146 | * choose the maximum throughput rate as max_prob_rate |
| 131 | if (max_prob < mr->probability) { | 147 | * (2) if all success probabilities < 95%, the rate with |
| 132 | index_max_prob = i; | 148 | * highest success probability is choosen as max_prob_rate */ |
| 133 | max_prob = mr->probability; | 149 | if (mr->probability >= MINSTREL_FRAC(95,100)) { |
| | 150 | if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp) |
| | 151 | tmp_prob_rate = i; |
| | 152 | } else { |
| | 153 | if (mr->probability >= mi->r[tmp_prob_rate].probability) |
| | 154 | tmp_prob_rate = i; |
| 134 | } | 155 | } |
| 135 | } | 156 | } |
| 136 | | 157 | |
| 137 | max_tp = 0; | 158 | /* Assign the new rate set */ |
| 138 | for (i = 0; i < mi->n_rates; i++) { | 159 | memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate)); |
| 139 | struct minstrel_rate *mr = &mi->r[i]; | 160 | mi->max_prob_rate = tmp_prob_rate; |
| 140 | | | |
| 141 | if (i == index_max_tp) | | |
| 142 | continue; | | |
| 143 | | | |
| 144 | if (max_tp < mr->cur_tp) { | | |
| 145 | index_max_tp2 = i; | | |
| 146 | max_tp = mr->cur_tp; | | |
| 147 | } | | |
| 148 | } | | |
| 149 | mi->max_tp_rate = index_max_tp; | | |
| 150 | mi->max_tp_rate2 = index_max_tp2; | | |
| 151 | mi->max_prob_rate = index_max_prob; | | |
| 152 | | 161 | |
| 153 | /* Reset update timer */ | 162 | /* Reset update timer */ |
| 154 | mi->stats_update = jiffies; | 163 | mi->stats_update = jiffies; |
| @@ -254,7 +263,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 99 unmodified lines |
| 254 | sampling_ratio = mp->lookaround_rate; | 263 | sampling_ratio = mp->lookaround_rate; |
| 255 | | 264 | |
| 256 | /* init rateindex [ndx] with max throughput rate */ | 265 | /* init rateindex [ndx] with max throughput rate */ |
| 257 | ndx = mi->max_tp_rate; | 266 | ndx = mi->max_tp_rate[0]; |
| 258 | | 267 | |
| 259 | /* increase sum packet counter */ | 268 | /* increase sum packet counter */ |
| 260 | mi->packet_count++; | 269 | mi->packet_count++; |
| @@ -322,7 +331,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 61 unmodified lines |
| 322 | * to use it, as this only wastes precious airtime */ | 331 | * to use it, as this only wastes precious airtime */ |
| 323 | if (!mrr_capable && rate_sampling && | 332 | if (!mrr_capable && rate_sampling && |
| 324 | (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) | 333 | (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) |
| 325 | ndx = mi->max_tp_rate; | 334 | ndx = mi->max_tp_rate[0]; |
| 326 | | 335 | |
| 327 | /* mrr setup for 1st stage */ | 336 | /* mrr setup for 1st stage */ |
| 328 | ar[0].idx = mi->r[ndx].rix; | 337 | ar[0].idx = mi->r[ndx].rix; |
| @@ -342,9 +351,9 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 13 unmodified lines |
| 342 | if (indirect_rate_sampling) | 351 | if (indirect_rate_sampling) |
| 343 | mrr_ndx[0] = sample_ndx; | 352 | mrr_ndx[0] = sample_ndx; |
| 344 | else | 353 | else |
| 345 | mrr_ndx[0] = mi->max_tp_rate; | 354 | mrr_ndx[0] = mi->max_tp_rate[0]; |
| 346 | } else { | 355 | } else { |
| 347 | mrr_ndx[0] = mi->max_tp_rate2; | 356 | mrr_ndx[0] = mi->max_tp_rate[1]; |
| 348 | } | 357 | } |
| 349 | | 358 | |
| 350 | /* mrr setup for 3rd & 4th stage */ | 359 | /* mrr setup for 3rd & 4th stage */ |