aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2009-08-17 20:15:55 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-20 11:36:02 -0400
commitbfc32e6a9559d3e30925929cd9a9df7498f325db (patch)
treef0e5f1bdf902fe463fa994d44cafcab39b357380 /net/mac80211
parent92ed48e5230e8f5906dda0cc31715b3b7e3fe303 (diff)
mac80211: Decouple fail_avg stats used by mesh from rate control algorithm.
Mesh uses the tx failure average to compute the (m)path metric. This used to be done inside the rate control module. This patch breaks the dependency between the mesh stack and the rate control algorithm. Mesh will now work independently of the chosen rate control algorithm. The mesh stack keeps a moving average of the average transmission losses for each mesh peer station. If the fail average exceeds a certain threshold, the peer link is marked as broken. Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_hwmp.c18
-rw-r--r--net/mac80211/rc80211_minstrel.c16
-rw-r--r--net/mac80211/rc80211_pid_algo.c15
5 files changed, 24 insertions, 29 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 3302df96f8d4..f80efd7ff5ec 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -482,6 +482,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
482 } 482 }
483 483
484 rate_control_tx_status(local, sband, sta, skb); 484 rate_control_tx_status(local, sband, sta, skb);
485 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
486 ieee80211s_update_metric(local, sta, skb);
485 } 487 }
486 488
487 rcu_read_unlock(); 489 rcu_read_unlock();
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index eb23fc639b2b..dd1c19319f0a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -226,6 +226,8 @@ void mesh_mgmt_ies_add(struct sk_buff *skb,
226void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 226void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
227int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 227int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
228void ieee80211s_init(void); 228void ieee80211s_init(void);
229void ieee80211s_update_metric(struct ieee80211_local *local,
230 struct sta_info *stainfo, struct sk_buff *skb);
229void ieee80211s_stop(void); 231void ieee80211s_stop(void);
230void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 232void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
231ieee80211_rx_result 233ieee80211_rx_result
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index ef1efd362691..7aeba00ac502 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -201,6 +201,24 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
201 return 0; 201 return 0;
202} 202}
203 203
204void ieee80211s_update_metric(struct ieee80211_local *local,
205 struct sta_info *stainfo, struct sk_buff *skb)
206{
207 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
208 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
209 int failed;
210
211 if (!ieee80211_is_data(hdr->frame_control))
212 return;
213
214 failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
215
216 /* moving average, scaled to 100 */
217 stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed);
218 if (stainfo->fail_avg > 95)
219 mesh_plink_broken(stainfo);
220}
221
204static u32 airtime_link_metric_get(struct ieee80211_local *local, 222static u32 airtime_link_metric_get(struct ieee80211_local *local,
205 struct sta_info *sta) 223 struct sta_info *sta)
206{ 224{
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 007164919e02..7c5142988bbb 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -51,7 +51,6 @@
51#include <linux/random.h> 51#include <linux/random.h>
52#include <linux/ieee80211.h> 52#include <linux/ieee80211.h>
53#include <net/mac80211.h> 53#include <net/mac80211.h>
54#include "mesh.h"
55#include "rate.h" 54#include "rate.h"
56#include "rc80211_minstrel.h" 55#include "rc80211_minstrel.h"
57 56
@@ -156,16 +155,12 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
156 struct sk_buff *skb) 155 struct sk_buff *skb)
157{ 156{
158 struct minstrel_sta_info *mi = priv_sta; 157 struct minstrel_sta_info *mi = priv_sta;
159 struct minstrel_priv *mp = (struct minstrel_priv *)priv;
160 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 158 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
161 struct ieee80211_tx_rate *ar = info->status.rates; 159 struct ieee80211_tx_rate *ar = info->status.rates;
162 struct ieee80211_local *local = hw_to_local(mp->hw);
163 struct sta_info *si;
164 int i, ndx; 160 int i, ndx;
165 int success; 161 int success;
166 162
167 success = !!(info->flags & IEEE80211_TX_STAT_ACK); 163 success = !!(info->flags & IEEE80211_TX_STAT_ACK);
168 si = sta_info_get(local, sta->addr);
169 164
170 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 165 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
171 if (ar[i].idx < 0) 166 if (ar[i].idx < 0)
@@ -177,17 +172,8 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
177 172
178 mi->r[ndx].attempts += ar[i].count; 173 mi->r[ndx].attempts += ar[i].count;
179 174
180 if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) { 175 if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
181 mi->r[ndx].success += success; 176 mi->r[ndx].success += success;
182 if (si) {
183 si->fail_avg = (18050 - mi->r[ndx].probability)
184 / 180;
185 WARN_ON(si->fail_avg > 100);
186 if (si->fail_avg == 100 &&
187 ieee80211_vif_is_mesh(&si->sdata->vif))
188 mesh_plink_broken(si);
189 }
190 }
191 } 177 }
192 178
193 if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0)) 179 if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 8c053be9dc24..f6e25d7d957c 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -169,19 +169,9 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
169 * still a good measurement and copy it. */ 169 * still a good measurement and copy it. */
170 if (unlikely(spinfo->tx_num_xmit == 0)) 170 if (unlikely(spinfo->tx_num_xmit == 0))
171 pf = spinfo->last_pf; 171 pf = spinfo->last_pf;
172 else { 172 else
173 /* XXX: BAD HACK!!! */
174 struct sta_info *si = container_of(sta, struct sta_info, sta);
175
176 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; 173 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
177 174
178 if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100)
179 mesh_plink_broken(si);
180 pf <<= RC_PID_ARITH_SHIFT;
181 si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
182 >> RC_PID_ARITH_SHIFT;
183 }
184
185 spinfo->tx_num_xmit = 0; 175 spinfo->tx_num_xmit = 0;
186 spinfo->tx_num_failed = 0; 176 spinfo->tx_num_failed = 0;
187 177
@@ -348,9 +338,6 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
348 } 338 }
349 339
350 spinfo->txrate_idx = rate_lowest_index(sband, sta); 340 spinfo->txrate_idx = rate_lowest_index(sband, sta);
351 /* HACK */
352 si = container_of(sta, struct sta_info, sta);
353 si->fail_avg = 0;
354} 341}
355 342
356static void *rate_control_pid_alloc(struct ieee80211_hw *hw, 343static void *rate_control_pid_alloc(struct ieee80211_hw *hw,