Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / mac80211 / tx.c
index 83e3261..8410bb3 100644 (file)
 
 /* misc utils */
 
+static inline void ieee80211_tx_stats(struct net_device *dev, u32 len)
+{
+       struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
+
+       u64_stats_update_begin(&tstats->syncp);
+       tstats->tx_packets++;
+       tstats->tx_bytes += len;
+       u64_stats_update_end(&tstats->syncp);
+}
+
 static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
                                 struct sk_buff *skb, int group_addr,
                                 int next_frag_len)
@@ -201,11 +211,11 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
        struct ieee80211_if_managed *ifmgd;
 
        /* driver doesn't support power save */
-       if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
+       if (!ieee80211_hw_check(&local->hw, SUPPORTS_PS))
                return TX_CONTINUE;
 
        /* hardware does dynamic power save */
-       if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
+       if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
                return TX_CONTINUE;
 
        /* dynamic power save disabled */
@@ -421,7 +431,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
        if (ieee80211_is_probe_req(hdr->frame_control))
                return TX_CONTINUE;
 
-       if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
+       if (ieee80211_hw_check(&tx->local->hw, QUEUE_CONTROL))
                info->hw_queue = tx->sdata->vif.cab_queue;
 
        /* no stations in PS mode */
@@ -431,7 +441,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
        info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
 
        /* device releases frame after DTIM beacon */
-       if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
+       if (!ieee80211_hw_check(&tx->local->hw, HOST_BROADCAST_PS_BUFFERING))
                return TX_CONTINUE;
 
        /* buffered in mac80211 */
@@ -987,7 +997,6 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
 
        skb_queue_walk(&tx->skbs, skb) {
                ac = skb_get_queue_mapping(skb);
-               tx->sta->tx_fragments++;
                tx->sta->tx_bytes[ac] += skb->len;
        }
        if (ac >= 0)
@@ -1176,8 +1185,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
 
        if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
            !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
-           (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) &&
-           !(local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) {
+           ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) &&
+           !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) {
                struct tid_ampdu_tx *tid_tx;
 
                qc = ieee80211_get_qos_ctl(hdr);
@@ -1420,7 +1429,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
                        vif = &sdata->vif;
                        info->hw_queue =
                                vif->hw_queue[skb_get_queue_mapping(skb)];
-               } else if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
+               } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
                        dev_kfree_skb(skb);
                        return true;
                } else
@@ -1466,7 +1475,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
        CALL_TXH(ieee80211_tx_h_ps_buf);
        CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
        CALL_TXH(ieee80211_tx_h_select_key);
-       if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
+       if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
                CALL_TXH(ieee80211_tx_h_rate_ctrl);
 
        if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
@@ -1481,7 +1490,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
        /* handlers after fragment must be aware of tx info fragmentation! */
        CALL_TXH(ieee80211_tx_h_stats);
        CALL_TXH(ieee80211_tx_h_encrypt);
-       if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL))
+       if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
                CALL_TXH(ieee80211_tx_h_calculate_duration);
 #undef CALL_TXH
 
@@ -1571,7 +1580,7 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
 
        /* set up hw_queue value early */
        if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) ||
-           !(local->hw.flags & IEEE80211_HW_QUEUE_CONTROL))
+           !ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
                info->hw_queue =
                        sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
 
@@ -1598,7 +1607,7 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
        }
 
        if (skb_cloned(skb) &&
-           (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CLONED_SKBS) ||
+           (!ieee80211_hw_check(&local->hw, SUPPORTS_CLONED_SKBS) ||
             !skb_clone_writable(skb, ETH_HLEN) ||
             (may_encrypt && sdata->crypto_tx_tailroom_needed_cnt)))
                I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
@@ -2417,7 +2426,7 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
        struct ieee80211_chanctx_conf *chanctx_conf;
        __le16 fc;
 
-       if (!(local->hw.flags & IEEE80211_HW_SUPPORT_FAST_XMIT))
+       if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
                return;
 
        /* Locking here protects both the pointer itself, and against concurrent
@@ -2433,8 +2442,8 @@ void ieee80211_check_fast_xmit(struct sta_info *sta)
         * cleared/changed already.
         */
        spin_lock_bh(&sta->lock);
-       if (local->hw.flags & IEEE80211_HW_SUPPORTS_PS &&
-           !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) &&
+       if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
+           !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS) &&
            sdata->vif.type == NL80211_IFTYPE_STATION)
                goto out;
 
@@ -2710,9 +2719,12 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
        if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
                tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
                tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
-               if (tid_tx &&
-                   !test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
-                       return false;
+               if (tid_tx) {
+                       if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
+                               return false;
+                       if (tid_tx->timeout)
+                               tid_tx->last_tx = jiffies;
+               }
        }
 
        /* after this point (skb is modified) we cannot return false */
@@ -2727,8 +2739,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
                        return true;
        }
 
-       dev->stats.tx_packets++;
-       dev->stats.tx_bytes += skb->len + extra_head;
+       ieee80211_tx_stats(dev, skb->len + extra_head);
 
        /* will not be crypto-handled beyond what we do here, so use false
         * as the may-encrypt argument for the resize to not account for
@@ -2779,7 +2790,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
        if (fast_tx->key)
                info->control.hw_key = &fast_tx->key->conf;
 
-       if (!(local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) {
+       if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
                tx.skb = skb;
                r = ieee80211_tx_h_rate_ctrl(&tx);
                skb = tx.skb;
@@ -2795,7 +2806,6 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
        /* statistics normally done by ieee80211_tx_h_stats (but that
         * has to consider fragmentation, so is more complex)
         */
-       sta->tx_fragments++;
        sta->tx_bytes[skb_get_queue_mapping(skb)] += skb->len;
        sta->tx_packets[skb_get_queue_mapping(skb)]++;
 
@@ -2806,17 +2816,9 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
                switch (fast_tx->key->conf.cipher) {
                case WLAN_CIPHER_SUITE_CCMP:
                case WLAN_CIPHER_SUITE_CCMP_256:
-                       pn = atomic64_inc_return(&fast_tx->key->u.ccmp.tx_pn);
-                       crypto_hdr[0] = pn;
-                       crypto_hdr[1] = pn >> 8;
-                       crypto_hdr[4] = pn >> 16;
-                       crypto_hdr[5] = pn >> 24;
-                       crypto_hdr[6] = pn >> 32;
-                       crypto_hdr[7] = pn >> 40;
-                       break;
                case WLAN_CIPHER_SUITE_GCMP:
                case WLAN_CIPHER_SUITE_GCMP_256:
-                       pn = atomic64_inc_return(&fast_tx->key->u.gcmp.tx_pn);
+                       pn = atomic64_inc_return(&fast_tx->key->conf.tx_pn);
                        crypto_hdr[0] = pn;
                        crypto_hdr[1] = pn >> 8;
                        crypto_hdr[4] = pn >> 16;
@@ -2886,12 +2888,8 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
                 * fix it up in software before we handle anything else.
                 */
                if (skb->ip_summed == CHECKSUM_PARTIAL) {
-                       if (skb->encapsulation)
-                               skb_set_inner_transport_header(skb,
-                                                              skb_checksum_start_offset(skb));
-                       else
-                               skb_set_transport_header(skb,
-                                                        skb_checksum_start_offset(skb));
+                       skb_set_transport_header(skb,
+                                                skb_checksum_start_offset(skb));
                        if (skb_checksum_help(skb))
                                goto out_free;
                }
@@ -2909,8 +2907,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
                if (IS_ERR(skb))
                        goto out;
 
-               dev->stats.tx_packets++;
-               dev->stats.tx_bytes += skb->len;
+               ieee80211_tx_stats(dev, skb->len);
 
                ieee80211_xmit(sdata, sta, skb);
        }
@@ -3810,7 +3807,7 @@ int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
        synchronize_net();
 
        /* Tear down BA sessions so we stop aggregating on this TID */
-       if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) {
+       if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION)) {
                set_sta_flag(sta, WLAN_STA_BLOCK_BA);
                __ieee80211_stop_tx_ba_session(sta, tid,
                                               AGG_STOP_LOCAL_REQUEST);
@@ -3824,7 +3821,7 @@ int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
        ieee80211_wake_vif_queues(local, sdata,
                                  IEEE80211_QUEUE_STOP_REASON_RESERVE_TID);
 
-       if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)
+       if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION))
                clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
 
        ret = 0;