]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/mac80211/status.c
mac80211: make TX aggregation start/stop request async
[mv-sheeva.git] / net / mac80211 / status.c
index 56d5b9a6ec5b7fcfd433d2da9280bd24d27d1fda..34da67995d94ae91c8982776fd3e9104c161079f 100644 (file)
@@ -47,7 +47,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
        /*
         * This skb 'survived' a round-trip through the driver, and
         * hopefully the driver didn't mangle it too badly. However,
-        * we can definitely not rely on the the control information
+        * we can definitely not rely on the control information
         * being correct. Clear it so we don't get junk there, and
         * indicate that it needs new processing, but must not be
         * modified/encrypted again.
@@ -171,13 +171,16 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct net_device *prev_dev = NULL;
        struct sta_info *sta, *tmp;
        int retry_count = -1, i;
-       bool injected;
+       int rates_idx = -1;
+       bool send_to_cooked;
 
        for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
                /* the HW cannot have attempted that rate */
                if (i >= hw->max_rates) {
                        info->status.rates[i].idx = -1;
                        info->status.rates[i].count = 0;
+               } else if (info->status.rates[i].idx >= 0) {
+                       rates_idx = i;
                }
 
                retry_count += info->status.rates[i].count;
@@ -206,6 +209,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                        return;
                }
 
+               if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
+                   (rates_idx != -1))
+                       sta->last_tx_rate = info->status.rates[rates_idx];
+
                if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
                    (ieee80211_is_data_qos(fc))) {
                        u16 tid, ssn;
@@ -296,11 +303,15 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        /* this was a transmitted frame, but now we want to reuse it */
        skb_orphan(skb);
 
+       /* Need to make a copy before skb->cb gets cleared */
+       send_to_cooked = !!(info->flags & IEEE80211_TX_CTL_INJECTED) ||
+                       (type != IEEE80211_FTYPE_DATA);
+
        /*
         * This is a bit racy but we can avoid a lot of work
         * with this test...
         */
-       if (!local->monitors && !local->cooked_mntrs) {
+       if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
                dev_kfree_skb(skb);
                return;
        }
@@ -345,9 +356,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        /* for now report the total retry_count */
        rthdr->data_retries = retry_count;
 
-       /* Need to make a copy before skb->cb gets cleared */
-       injected = !!(info->flags & IEEE80211_TX_CTL_INJECTED);
-
        /* XXX: is this sufficient for BPF? */
        skb_set_mac_header(skb, 0);
        skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -362,8 +370,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                                continue;
 
                        if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
-                           !injected &&
-                           (type == IEEE80211_FTYPE_DATA))
+                           !send_to_cooked)
                                continue;
 
                        if (prev_dev) {