summaryrefslogtreecommitdiffstats
path: root/net/mac80211/rc80211_pid_algo.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
-rw-r--r--net/mac80211/rc80211_pid_algo.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 9762803..a199316 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -15,7 +15,7 @@
#include <linux/debugfs.h>
#include <net/mac80211.h>
#include "ieee80211_rate.h"
-
+#include "mesh.h"
#include "rc80211_pid.h"
@@ -77,7 +77,7 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
int cur = sta->txrate_idx;
- sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+ sdata = sta->sdata;
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
band = sband->band;
n_bitrates = sband->n_bitrates;
@@ -148,6 +148,9 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
struct ieee80211_local *local,
struct sta_info *sta)
{
+#ifdef CONFIG_MAC80211_MESH
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
+#endif
struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;
struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
struct ieee80211_supported_band *sband;
@@ -178,7 +181,14 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
pf = spinfo->last_pf;
else {
pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
+#ifdef CONFIG_MAC80211_MESH
+ if (pf == 100 &&
+ sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT)
+ mesh_plink_broken(sta);
+#endif
pf <<= RC_PID_ARITH_SHIFT;
+ sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
+ >> RC_PID_ARITH_SHIFT;
}
spinfo->tx_num_xmit = 0;
@@ -239,23 +249,25 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
unsigned long period;
struct ieee80211_supported_band *sband;
+ rcu_read_lock();
+
sta = sta_info_get(local, hdr->addr1);
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
if (!sta)
- return;
+ goto unlock;
/* Don't update the state if we're not controlling the rate. */
- sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+ sdata = sta->sdata;
if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
sta->txrate_idx = sdata->bss->max_ratectrl_rateidx;
- return;
+ goto unlock;
}
/* Ignore all frames that were sent with a different rate than the rate
* we currently advise mac80211 to use. */
if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx])
- goto ignore;
+ goto unlock;
spinfo = sta->rate_ctrl_priv;
spinfo->tx_num_xmit++;
@@ -293,8 +305,8 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
if (time_after(jiffies, spinfo->last_sample + period))
rate_control_pid_sample(pinfo, local, sta);
-ignore:
- sta_info_put(sta);
+ unlock:
+ rcu_read_unlock();
}
static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
@@ -309,6 +321,8 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
int rateidx;
u16 fc;
+ rcu_read_lock();
+
sta = sta_info_get(local, hdr->addr1);
/* Send management frames and broadcast/multicast data using lowest
@@ -317,8 +331,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
is_multicast_ether_addr(hdr->addr1) || !sta) {
sel->rate = rate_lowest(local, sband, sta);
- if (sta)
- sta_info_put(sta);
+ rcu_read_unlock();
return;
}
@@ -334,7 +347,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
sta->last_txrate_idx = rateidx;
- sta_info_put(sta);
+ rcu_read_unlock();
sel->rate = &sband->bitrates[rateidx];
@@ -357,6 +370,7 @@ static void rate_control_pid_rate_init(void *priv, void *priv_sta,
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
sta->txrate_idx = rate_lowest_index(local, sband, sta);
+ sta->fail_avg = 0;
}
static void *rate_control_pid_alloc(struct ieee80211_local *local)
OpenPOWER on IntegriCloud