| @@ -69,14 +69,31 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix) · 68 unmodified lines |
| 69 | 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 | 86 | static void |
| 73 | 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; |
| 76 | | − u32 max_prob = 0, index_max_prob = 0; |
| 89 | + u8 tmp_tp_rate[MAX_THR_RATES]; |
| 90 | + u8 tmp_prob_rate = 0; |
| 77 | 91 | u32 usecs; |
| 78 | 92 | int i; |
| 79 | 93 | |
| 94 | + for (i=0; i < MAX_THR_RATES; i++) |
| 95 | + tmp_tp_rate[i] = 0; |
| 96 | + |
| 80 | 97 | for (i = 0; i < mi->n_rates; i++) { |
| 81 | 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 | 138 | if (!mr->adjusted_retry_count) |
| 122 | 139 | mr->adjusted_retry_count = 2; |
| 123 | | − } |
| 124 | 140 | |
| 125 | | − for (i = 0; i < mi->n_rates; i++) { |
| 126 | | − struct minstrel_rate *mr = &mi->r[i]; |
| 127 | | − if (max_tp < mr->cur_tp) { |
| 128 | | − index_max_tp = i; |
| 129 | | − max_tp = mr->cur_tp; |
| 130 | | − } |
| 131 | | − if (max_prob < mr->probability) { |
| 132 | | − index_max_prob = i; |
| 133 | | − max_prob = mr->probability; |
| 141 | + minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate); |
| 142 | + |
| 143 | + /* To determine the most robust rate (max_prob_rate) used at |
| 144 | + * 3rd mmr stage we distinct between two cases: |
| 145 | + * (1) if any success probabilitiy >= 95%, out of those rates |
| 146 | + * choose the maximum throughput rate as max_prob_rate |
| 147 | + * (2) if all success probabilities < 95%, the rate with |
| 148 | + * highest success probability is choosen as max_prob_rate */ |
| 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; |
| 138 | | − for (i = 0; i < mi->n_rates; i++) { |
| 139 | | − struct minstrel_rate *mr = &mi->r[i]; |
| 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; |
| 158 | + /* Assign the new rate set */ |
| 159 | + memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate)); |
| 160 | + mi->max_prob_rate = tmp_prob_rate; |
| 152 | 161 | |
| 153 | 162 | /* Reset update timer */ |
| 154 | 163 | mi->stats_update = jiffies; |
| @@ -254,7 +263,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 99 unmodified lines |
| 254 | 263 | sampling_ratio = mp->lookaround_rate; |
| 255 | 264 | |
| 256 | 265 | /* init rateindex [ndx] with max throughput rate */ |
| 257 | | − ndx = mi->max_tp_rate; |
| 266 | + ndx = mi->max_tp_rate[0]; |
| 258 | 267 | |
| 259 | 268 | /* increase sum packet counter */ |
| 260 | 269 | mi->packet_count++; |
| @@ -322,7 +331,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, · 61 unmodified lines |
| 322 | 331 | * to use it, as this only wastes precious airtime */ |
| 323 | 332 | if (!mrr_capable && rate_sampling && |
| 324 | 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 | 336 | /* mrr setup for 1st stage */ |
| 328 | 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 | 351 | if (indirect_rate_sampling) |
| 343 | 352 | mrr_ndx[0] = sample_ndx; |
| 344 | 353 | else |
| 345 | | − mrr_ndx[0] = mi->max_tp_rate; |
| 354 | + mrr_ndx[0] = mi->max_tp_rate[0]; |
| 346 | 355 | } else { |
| 347 | | − mrr_ndx[0] = mi->max_tp_rate2; |
| 356 | + mrr_ndx[0] = mi->max_tp_rate[1]; |
| 348 | 357 | } |
| 349 | 358 | |
| 350 | 359 | /* mrr setup for 3rd & 4th stage */ |