mac80211: fix mesh airtime link metric estimating
Airtime link metric estimation was broken in HT mesh, use cfg80211_calculate_bitrate to get the right rate value. Also factor out tx rate copying from sta_set_sinfo(). Signed-off-by: Thomas Pedersen <thomas@cozybit.com> Reviewed-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
8097e14944
commit
6b62bf3263
|
@ -336,6 +336,20 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
|
||||||
rate->mcs = idx;
|
rate->mcs = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sta_set_rate_info_tx(struct sta_info *sta,
|
||||||
|
const struct ieee80211_tx_rate *rate,
|
||||||
|
struct rate_info *rinfo)
|
||||||
|
{
|
||||||
|
rinfo->flags = 0;
|
||||||
|
if (rate->flags & IEEE80211_TX_RC_MCS)
|
||||||
|
rinfo->flags |= RATE_INFO_FLAGS_MCS;
|
||||||
|
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||||
|
rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
|
||||||
|
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
|
||||||
|
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||||
|
rate_idx_to_bitrate(rinfo, sta, rate->idx);
|
||||||
|
}
|
||||||
|
|
||||||
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
||||||
{
|
{
|
||||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||||
|
@ -378,14 +392,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
||||||
sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
|
sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
sinfo->txrate.flags = 0;
|
sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
|
||||||
if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
|
|
||||||
sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
|
|
||||||
if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
|
||||||
sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
|
|
||||||
if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
|
|
||||||
sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
|
||||||
rate_idx_to_bitrate(&sinfo->txrate, sta, sta->last_tx_rate.idx);
|
|
||||||
|
|
||||||
sinfo->rxrate.flags = 0;
|
sinfo->rxrate.flags = 0;
|
||||||
if (sta->last_rx_rate_flag & RX_FLAG_HT)
|
if (sta->last_rx_rate_flag & RX_FLAG_HT)
|
||||||
|
|
|
@ -324,6 +324,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||||
struct sta_info *sta)
|
struct sta_info *sta)
|
||||||
{
|
{
|
||||||
struct ieee80211_supported_band *sband;
|
struct ieee80211_supported_band *sband;
|
||||||
|
struct rate_info rinfo;
|
||||||
/* This should be adjusted for each device */
|
/* This should be adjusted for each device */
|
||||||
int device_constant = 1 << ARITH_SHIFT;
|
int device_constant = 1 << ARITH_SHIFT;
|
||||||
int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT;
|
int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT;
|
||||||
|
@ -337,7 +338,9 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||||
if (sta->fail_avg >= 100)
|
if (sta->fail_avg >= 100)
|
||||||
return MAX_METRIC;
|
return MAX_METRIC;
|
||||||
|
|
||||||
if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
|
sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo);
|
||||||
|
rate = cfg80211_calculate_bitrate(&rinfo);
|
||||||
|
if (WARN_ON(!rate))
|
||||||
return MAX_METRIC;
|
return MAX_METRIC;
|
||||||
|
|
||||||
err = (sta->fail_avg << ARITH_SHIFT) / 100;
|
err = (sta->fail_avg << ARITH_SHIFT) / 100;
|
||||||
|
@ -345,7 +348,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||||
/* bitrate is in units of 100 Kbps, while we need rate in units of
|
/* bitrate is in units of 100 Kbps, while we need rate in units of
|
||||||
* 1Mbps. This will be corrected on tx_time computation.
|
* 1Mbps. This will be corrected on tx_time computation.
|
||||||
*/
|
*/
|
||||||
rate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
|
|
||||||
tx_time = (device_constant + 10 * test_frame_len / rate);
|
tx_time = (device_constant + 10 * test_frame_len / rate);
|
||||||
estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
|
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) ;
|
||||||
|
|
|
@ -529,6 +529,9 @@ void sta_info_init(struct ieee80211_local *local);
|
||||||
void sta_info_stop(struct ieee80211_local *local);
|
void sta_info_stop(struct ieee80211_local *local);
|
||||||
int sta_info_flush(struct ieee80211_local *local,
|
int sta_info_flush(struct ieee80211_local *local,
|
||||||
struct ieee80211_sub_if_data *sdata);
|
struct ieee80211_sub_if_data *sdata);
|
||||||
|
void sta_set_rate_info_tx(struct sta_info *sta,
|
||||||
|
const struct ieee80211_tx_rate *rate,
|
||||||
|
struct rate_info *rinfo);
|
||||||
void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
|
||||||
unsigned long exp_time);
|
unsigned long exp_time);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue