#include <linux/skbuff.h>
#include <linux/debugfs.h>
#include <net/mac80211.h>
-#include "ieee80211_rate.h"
-
+#include "rate.h"
+#include "mesh.h"
#include "rc80211_pid.h"
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;
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;
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;
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++;
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,
int rateidx;
u16 fc;
+ rcu_read_lock();
+
sta = sta_info_get(local, hdr->addr1);
/* Send management frames and broadcast/multicast data using lowest
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;
}
sta->last_txrate_idx = rateidx;
- sta_info_put(sta);
+ rcu_read_unlock();
sel->rate = &sband->bitrates[rateidx];
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)