Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / mac80211 / tx.c
index 1d0746d..1ff08be 100644 (file)
@@ -796,6 +796,36 @@ static __le16 ieee80211_tx_next_seq(struct sta_info *sta, int tid)
        return ret;
 }
 
+static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
+                                         struct ieee80211_vif *vif,
+                                         struct ieee80211_sta *pubsta,
+                                         struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_txq *txq = NULL;
+
+       if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
+           (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
+               return NULL;
+
+       if (!ieee80211_is_data(hdr->frame_control))
+               return NULL;
+
+       if (pubsta) {
+               u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+
+               txq = pubsta->txq[tid];
+       } else if (vif) {
+               txq = vif->txq;
+       }
+
+       if (!txq)
+               return NULL;
+
+       return to_txq_info(txq);
+}
+
 static ieee80211_tx_result debug_noinline
 ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
 {
@@ -853,7 +883,8 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
        tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
        tx->sta->tx_stats.msdu[tid]++;
 
-       if (!tx->sta->sta.txq[0])
+       if (!ieee80211_get_txq(tx->local, info->control.vif, &tx->sta->sta,
+                              tx->skb))
                hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
 
        return TX_CONTINUE;
@@ -1243,36 +1274,6 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
        return TX_CONTINUE;
 }
 
-static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
-                                         struct ieee80211_vif *vif,
-                                         struct ieee80211_sta *pubsta,
-                                         struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_txq *txq = NULL;
-
-       if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
-           (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
-               return NULL;
-
-       if (!ieee80211_is_data(hdr->frame_control))
-               return NULL;
-
-       if (pubsta) {
-               u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
-
-               txq = pubsta->txq[tid];
-       } else if (vif) {
-               txq = vif->txq;
-       }
-
-       if (!txq)
-               return NULL;
-
-       return to_txq_info(txq);
-}
-
 static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
 {
        IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
@@ -1343,7 +1344,7 @@ static struct sk_buff *fq_tin_dequeue_func(struct fq *fq,
        local = container_of(fq, struct ieee80211_local, fq);
        txqi = container_of(tin, struct txq_info, tin);
        cparams = &local->cparams;
-       cstats = &local->cstats;
+       cstats = &txqi->cstats;
 
        if (flow == &txqi->def_flow)
                cvars = &txqi->def_cvars;
@@ -1403,6 +1404,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
        fq_tin_init(&txqi->tin);
        fq_flow_init(&txqi->def_flow);
        codel_vars_init(&txqi->def_cvars);
+       codel_stats_init(&txqi->cstats);
 
        txqi->txq.vif = &sdata->vif;
 
@@ -1441,7 +1443,6 @@ int ieee80211_txq_setup_flows(struct ieee80211_local *local)
                return ret;
 
        codel_params_init(&local->cparams);
-       codel_stats_init(&local->cstats);
        local->cparams.interval = MS2TIME(100);
        local->cparams.target = MS2TIME(20);
        local->cparams.ecn = true;
@@ -1514,8 +1515,12 @@ out:
        spin_unlock_bh(&fq->lock);
 
        if (skb && skb_has_frag_list(skb) &&
-           !ieee80211_hw_check(&local->hw, TX_FRAG_LIST))
-               skb_linearize(skb);
+           !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) {
+               if (skb_linearize(skb)) {
+                       ieee80211_free_txskb(&local->hw, skb);
+                       return NULL;
+               }
+       }
 
        return skb;
 }
@@ -1643,7 +1648,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
 
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_MONITOR:
-               if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
+               if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
                        vif = &sdata->vif;
                        break;
                }
@@ -2263,15 +2268,9 @@ static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
        case NL80211_IFTYPE_STATION:
                if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
                        sta = sta_info_get(sdata, skb->data);
-                       if (sta) {
-                               bool tdls_peer, tdls_auth;
-
-                               tdls_peer = test_sta_flag(sta,
-                                                         WLAN_STA_TDLS_PEER);
-                               tdls_auth = test_sta_flag(sta,
-                                               WLAN_STA_TDLS_PEER_AUTH);
-
-                               if (tdls_peer && tdls_auth) {
+                       if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
+                               if (test_sta_flag(sta,
+                                                 WLAN_STA_TDLS_PEER_AUTH)) {
                                        *sta_out = sta;
                                        return 0;
                                }
@@ -2283,8 +2282,7 @@ static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
                                 * after a TDLS sta is removed due to being
                                 * unreachable.
                                 */
-                               if (tdls_peer && !tdls_auth &&
-                                   !ieee80211_is_tdls_setup(skb))
+                               if (!ieee80211_is_tdls_setup(skb))
                                        return -EINVAL;
                        }
 
@@ -3243,7 +3241,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
 
        if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
                *ieee80211_get_qos_ctl(hdr) = tid;
-               if (!sta->sta.txq[0])
+               if (!ieee80211_get_txq(local, &sdata->vif, &sta->sta, skb))
                        hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
        } else {
                info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;