mac80211: Assign a default mesh beaconing interval.
[pandora-kernel.git] / net / mac80211 / rc80211_minstrel.c
index 37771ab..0071649 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/random.h>
 #include <linux/ieee80211.h>
 #include <net/mac80211.h>
+#include "mesh.h"
 #include "rate.h"
 #include "rc80211_minstrel.h"
 
@@ -70,20 +71,6 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
        return i;
 }
 
-static inline bool
-use_low_rate(struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       u16 fc;
-
-       fc = le16_to_cpu(hdr->frame_control);
-
-       return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
-               (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA);
-}
-
-
 static void
 minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
 {
@@ -169,12 +156,16 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
                   struct sk_buff *skb)
 {
        struct minstrel_sta_info *mi = priv_sta;
+       struct minstrel_priv *mp = (struct minstrel_priv *)priv;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_tx_rate *ar = info->status.rates;
+       struct ieee80211_local *local = hw_to_local(mp->hw);
+       struct sta_info *si;
        int i, ndx;
        int success;
 
        success = !!(info->flags & IEEE80211_TX_STAT_ACK);
+       si = sta_info_get(local, sta->addr);
 
        for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
                if (ar[i].idx < 0)
@@ -186,8 +177,17 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 
                mi->r[ndx].attempts += ar[i].count;
 
-               if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
+               if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) {
                        mi->r[ndx].success += success;
+                       if (si) {
+                               si->fail_avg = (18050 - mi->r[ndx].probability)
+                                       / 180;
+                               WARN_ON(si->fail_avg > 100);
+                               if (si->fail_avg == 100 &&
+                                       ieee80211_vif_is_mesh(&si->sdata->vif))
+                                       mesh_plink_broken(si);
+                       }
+               }
        }
 
        if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
@@ -232,7 +232,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
                  void *priv_sta, struct ieee80211_tx_rate_control *txrc)
 {
        struct sk_buff *skb = txrc->skb;
-       struct ieee80211_supported_band *sband = txrc->sband;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct minstrel_sta_info *mi = priv_sta;
        struct minstrel_priv *mp = priv;
@@ -245,14 +244,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
        int mrr_ndx[3];
        int sample_rate;
 
-       if (!sta || !mi || use_low_rate(skb)) {
-               ar[0].idx = rate_lowest_index(sband, sta);
-               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-                       ar[0].count = 1;
-               else
-                       ar[0].count = mp->max_retry;
+       if (rate_control_send_low(sta, priv_sta, txrc))
                return;
-       }
 
        mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;