|
@@ -326,22 +326,33 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
|
|
u32 tx_time, estimated_retx;
|
|
|
u64 result;
|
|
|
|
|
|
- if (sta->mesh->fail_avg >= 100)
|
|
|
- return MAX_METRIC;
|
|
|
+ /* Try to get rate based on HW/SW RC algorithm.
|
|
|
+ * Rate is returned in units of Kbps, correct this
|
|
|
+ * to comply with airtime calculation units
|
|
|
+ * Round up in case we get rate < 100Kbps
|
|
|
+ */
|
|
|
+ rate = DIV_ROUND_UP(sta_get_expected_throughput(sta), 100);
|
|
|
|
|
|
- sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
|
|
|
- rate = cfg80211_calculate_bitrate(&rinfo);
|
|
|
- if (WARN_ON(!rate))
|
|
|
- return MAX_METRIC;
|
|
|
+ if (rate) {
|
|
|
+ err = 0;
|
|
|
+ } else {
|
|
|
+ if (sta->mesh->fail_avg >= 100)
|
|
|
+ return MAX_METRIC;
|
|
|
|
|
|
- err = (sta->mesh->fail_avg << ARITH_SHIFT) / 100;
|
|
|
+ sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
|
|
|
+ rate = cfg80211_calculate_bitrate(&rinfo);
|
|
|
+ if (WARN_ON(!rate))
|
|
|
+ return MAX_METRIC;
|
|
|
+
|
|
|
+ err = (sta->mesh->fail_avg << ARITH_SHIFT) / 100;
|
|
|
+ }
|
|
|
|
|
|
/* bitrate is in units of 100 Kbps, while we need rate in units of
|
|
|
* 1Mbps. This will be corrected on tx_time computation.
|
|
|
*/
|
|
|
tx_time = (device_constant + 10 * test_frame_len / rate);
|
|
|
estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
|
|
|
- result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
|
|
|
+ result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT);
|
|
|
return (u32)result;
|
|
|
}
|
|
|
|