343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. From: Felix Fietkau <[email protected]>
  2. Date: Sat, 26 Dec 2020 19:09:08 +0100
  3. Subject: [PATCH] mac80211: minstrel_ht: fix max probability rate selection
  4. - do not select rates faster than the max throughput rate if probability is lower
  5. - reset previous rate before sorting again
  6. This ensures that the max prob rate gets set to a more reliable rate
  7. Signed-off-by: Felix Fietkau <[email protected]>
  8. ---
  9. --- a/net/mac80211/rc80211_minstrel_ht.c
  10. +++ b/net/mac80211/rc80211_minstrel_ht.c
  11. @@ -495,12 +495,13 @@ minstrel_ht_sort_best_tp_rates(struct mi
  12. * Find and set the topmost probability rate per sta and per group
  13. */
  14. static void
  15. -minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
  16. +minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
  17. {
  18. struct minstrel_mcs_group_data *mg;
  19. struct minstrel_rate_stats *mrs;
  20. int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
  21. - int max_tp_group, cur_tp_avg, cur_group, cur_idx;
  22. + int max_tp_group, max_tp_idx, max_tp_prob;
  23. + int cur_tp_avg, cur_group, cur_idx;
  24. int max_gpr_group, max_gpr_idx;
  25. int max_gpr_tp_avg, max_gpr_prob;
  26. @@ -509,18 +510,26 @@ minstrel_ht_set_best_prob_rate(struct mi
  27. mg = &mi->groups[index / MCS_GROUP_RATES];
  28. mrs = &mg->rates[index % MCS_GROUP_RATES];
  29. - tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
  30. - tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
  31. + tmp_group = *dest / MCS_GROUP_RATES;
  32. + tmp_idx = *dest % MCS_GROUP_RATES;
  33. tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
  34. tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
  35. /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
  36. * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */
  37. max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES;
  38. + max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
  39. + max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg;
  40. +
  41. if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) &&
  42. !minstrel_ht_is_legacy_group(max_tp_group))
  43. return;
  44. + /* skip rates faster than max tp rate with lower prob */
  45. + if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) &&
  46. + mrs->prob_avg < max_tp_prob)
  47. + return;
  48. +
  49. max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
  50. max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
  51. max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
  52. @@ -538,7 +547,7 @@ minstrel_ht_set_best_prob_rate(struct mi
  53. mg->max_group_prob_rate = index;
  54. } else {
  55. if (mrs->prob_avg > tmp_prob)
  56. - mi->max_prob_rate = index;
  57. + *dest = index;
  58. if (mrs->prob_avg > max_gpr_prob)
  59. mg->max_group_prob_rate = index;
  60. }
  61. @@ -816,7 +825,8 @@ minstrel_ht_update_stats(struct minstrel
  62. struct minstrel_rate_stats *mrs;
  63. int group, i, j, cur_prob;
  64. u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES];
  65. - u16 tmp_legacy_tp_rate[MAX_THR_RATES], index;
  66. + u16 tmp_legacy_tp_rate[MAX_THR_RATES], tmp_max_prob_rate;
  67. + u16 index;
  68. bool ht_supported = mi->sta->ht_cap.ht_supported;
  69. mi->sample_mode = MINSTREL_SAMPLE_IDLE;
  70. @@ -863,6 +873,7 @@ minstrel_ht_update_stats(struct minstrel
  71. else
  72. index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES;
  73. + tmp_max_prob_rate = index;
  74. for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++)
  75. tmp_mcs_tp_rate[j] = index;
  76. @@ -903,9 +914,6 @@ minstrel_ht_update_stats(struct minstrel
  77. /* Find max throughput rate set within a group */
  78. minstrel_ht_sort_best_tp_rates(mi, index,
  79. tmp_group_tp_rate);
  80. -
  81. - /* Find max probability rate per group and global */
  82. - minstrel_ht_set_best_prob_rate(mi, index);
  83. }
  84. memcpy(mg->max_group_tp_rate, tmp_group_tp_rate,
  85. @@ -917,6 +925,27 @@ minstrel_ht_update_stats(struct minstrel
  86. tmp_legacy_tp_rate);
  87. memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate));
  88. + for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
  89. + if (!mi->supported[group])
  90. + continue;
  91. +
  92. + mg = &mi->groups[group];
  93. + mg->max_group_prob_rate = MCS_GROUP_RATES * group;
  94. +
  95. + for (i = 0; i < MCS_GROUP_RATES; i++) {
  96. + if (!(mi->supported[group] & BIT(i)))
  97. + continue;
  98. +
  99. + index = MCS_GROUP_RATES * group + i;
  100. +
  101. + /* Find max probability rate per group and global */
  102. + minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate,
  103. + index);
  104. + }
  105. + }
  106. +
  107. + mi->max_prob_rate = tmp_max_prob_rate;
  108. +
  109. /* Try to increase robustness of max_prob_rate*/
  110. minstrel_ht_prob_rate_reduce_streams(mi);