mac80211: fix multi-use timer
[safe/jmp/linux-2.6] / net / mac80211 / rc80211_pid_algo.c
index 86eb374..a0bef76 100644 (file)
@@ -241,7 +241,7 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
 
        /* Ignore all frames that were sent with a different rate than the rate
         * we currently advise mac80211 to use. */
-       if (info->tx_rate_idx != spinfo->txrate_idx)
+       if (info->status.rates[0].idx != spinfo->txrate_idx)
                return;
 
        spinfo->tx_num_xmit++;
@@ -253,10 +253,10 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
        /* We count frames that totally failed to be transmitted as two bad
         * frames, those that made it out but had some retries as one good and
         * one bad frame. */
-       if (info->status.excessive_retries) {
+       if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
                spinfo->tx_num_failed += 2;
                spinfo->tx_num_xmit++;
-       } else if (info->status.retry_count) {
+       } else if (info->status.rates[0].count > 1) {
                spinfo->tx_num_failed++;
                spinfo->tx_num_xmit++;
        }
@@ -270,23 +270,34 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
 }
 
 static void
-rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband,
-                         struct ieee80211_sta *sta, void *priv_sta,
-                         struct sk_buff *skb,
-                         struct rate_selection *sel)
+rate_control_pid_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_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct rc_pid_sta_info *spinfo = priv_sta;
        int rateidx;
        u16 fc;
 
-       /* Send management frames and broadcast/multicast data using lowest
-        * rate. */
+       if (txrc->rts)
+               info->control.rates[0].count =
+                       txrc->hw->conf.long_frame_max_tx_count;
+       else
+               info->control.rates[0].count =
+                       txrc->hw->conf.short_frame_max_tx_count;
+
+       /* Send management frames and NO_ACK data using lowest rate. */
        fc = le16_to_cpu(hdr->frame_control);
        if (!sta || !spinfo ||
            (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-           is_multicast_ether_addr(hdr->addr1)) {
-               sel->rate_idx = rate_lowest_index(sband, sta);
+           info->flags & IEEE80211_TX_CTL_NO_ACK) {
+               info->control.rates[0].idx = rate_lowest_index(sband, sta);
+               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+                       info->control.rates[0].count = 1;
+
                return;
        }
 
@@ -295,7 +306,7 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband,
        if (rateidx >= sband->n_bitrates)
                rateidx = sband->n_bitrates - 1;
 
-       sel->rate_idx = rateidx;
+       info->control.rates[0].idx = rateidx;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        rate_control_pid_event_tx_rate(&spinfo->events,
@@ -308,13 +319,44 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
                           struct ieee80211_sta *sta, void *priv_sta)
 {
        struct rc_pid_sta_info *spinfo = priv_sta;
+       struct rc_pid_info *pinfo = priv;
+       struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
        struct sta_info *si;
+       int i, j, tmp;
+       bool s;
 
        /* TODO: This routine should consider using RSSI from previous packets
         * as we need to have IEEE 802.1X auth succeed immediately after assoc..
         * Until that method is implemented, we will use the lowest supported
         * rate as a workaround. */
 
+       /* Sort the rates. This is optimized for the most common case (i.e.
+        * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
+        * mapping too. */
+       for (i = 0; i < sband->n_bitrates; i++) {
+               rinfo[i].index = i;
+               rinfo[i].rev_index = i;
+               if (RC_PID_FAST_START)
+                       rinfo[i].diff = 0;
+               else
+                       rinfo[i].diff = i * pinfo->norm_offset;
+       }
+       for (i = 1; i < sband->n_bitrates; i++) {
+               s = 0;
+               for (j = 0; j < sband->n_bitrates - i; j++)
+                       if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
+                                    sband->bitrates[rinfo[j + 1].index].bitrate)) {
+                               tmp = rinfo[j].index;
+                               rinfo[j].index = rinfo[j + 1].index;
+                               rinfo[j + 1].index = tmp;
+                               rinfo[rinfo[j].index].rev_index = j;
+                               rinfo[rinfo[j + 1].index].rev_index = j + 1;
+                               s = 1;
+                       }
+               if (!s)
+                       break;
+       }
+
        spinfo->txrate_idx = rate_lowest_index(sband, sta);
        /* HACK */
        si = container_of(sta, struct sta_info, sta);
@@ -327,21 +369,22 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
        struct rc_pid_info *pinfo;
        struct rc_pid_rateinfo *rinfo;
        struct ieee80211_supported_band *sband;
-       int i, j, tmp;
-       bool s;
+       int i, max_rates = 0;
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct rc_pid_debugfs_entries *de;
 #endif
 
-       sband = hw->wiphy->bands[hw->conf.channel->band];
-
        pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
        if (!pinfo)
                return NULL;
 
-       /* We can safely assume that sband won't change unless we get
-        * reinitialized. */
-       rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC);
+       for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
+               sband = hw->wiphy->bands[i];
+               if (sband && sband->n_bitrates > max_rates)
+                       max_rates = sband->n_bitrates;
+       }
+
+       rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC);
        if (!rinfo) {
                kfree(pinfo);
                return NULL;
@@ -359,33 +402,6 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
        pinfo->rinfo = rinfo;
        pinfo->oldrate = 0;
 
-       /* Sort the rates. This is optimized for the most common case (i.e.
-        * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
-        * mapping too. */
-       for (i = 0; i < sband->n_bitrates; i++) {
-               rinfo[i].index = i;
-               rinfo[i].rev_index = i;
-               if (RC_PID_FAST_START)
-                       rinfo[i].diff = 0;
-               else
-                       rinfo[i].diff = i * pinfo->norm_offset;
-       }
-       for (i = 1; i < sband->n_bitrates; i++) {
-               s = 0;
-               for (j = 0; j < sband->n_bitrates - i; j++)
-                       if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
-                                    sband->bitrates[rinfo[j + 1].index].bitrate)) {
-                               tmp = rinfo[j].index;
-                               rinfo[j].index = rinfo[j + 1].index;
-                               rinfo[j + 1].index = tmp;
-                               rinfo[rinfo[j].index].rev_index = j;
-                               rinfo[rinfo[j + 1].index].rev_index = j + 1;
-                               s = 1;
-                       }
-               if (!s)
-                       break;
-       }
-
 #ifdef CONFIG_MAC80211_DEBUGFS
        de = &pinfo->dentries;
        de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
@@ -394,11 +410,11 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
                                                 S_IRUSR | S_IWUSR, debugfsdir,
                                                 &pinfo->sampling_period);
        de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
-                                        debugfsdir, &pinfo->coeff_p);
+                                        debugfsdir, (u32 *)&pinfo->coeff_p);
        de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
-                                        debugfsdir, &pinfo->coeff_i);
+                                        debugfsdir, (u32 *)&pinfo->coeff_i);
        de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
-                                        debugfsdir, &pinfo->coeff_d);
+                                        debugfsdir, (u32 *)&pinfo->coeff_d);
        de->smoothing_shift = debugfs_create_u32("smoothing_shift",
                                                 S_IRUSR | S_IWUSR, debugfsdir,
                                                 &pinfo->smoothing_shift);
@@ -437,10 +453,6 @@ static void rate_control_pid_free(void *priv)
        kfree(pinfo);
 }
 
-static void rate_control_pid_clear(void *priv)
-{
-}
-
 static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
                                        gfp_t gfp)
 {
@@ -471,7 +483,6 @@ static struct rate_control_ops mac80211_rcpid = {
        .tx_status = rate_control_pid_tx_status,
        .get_rate = rate_control_pid_get_rate,
        .rate_init = rate_control_pid_rate_init,
-       .clear = rate_control_pid_clear,
        .alloc = rate_control_pid_alloc,
        .free = rate_control_pid_free,
        .alloc_sta = rate_control_pid_alloc_sta,