On Thu, Sep 1, 2016 at 12:03 PM, Toke Høiland-Jørgensen <toke@xxxxxxx> wrote: > @@ -1481,33 +1506,57 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, > { > struct ieee80211_local *local = hw_to_local(hw); > struct txq_info *txqi = container_of(txq, struct txq_info, txq); > - struct ieee80211_hdr *hdr; > struct sk_buff *skb = NULL; > struct fq *fq = &local->fq; > struct fq_tin *tin = &txqi->tin; > + struct ieee80211_tx_info *info; > > spin_lock_bh(&fq->lock); > > if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags)) > goto out; > > +begin: > skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func); > if (!skb) > goto out; > > ieee80211_set_skb_vif(skb, txqi); > > - hdr = (struct ieee80211_hdr *)skb->data; > - if (txq->sta && ieee80211_is_data_qos(hdr->frame_control)) { > + info = IEEE80211_SKB_CB(skb); > + if (txq->sta && info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) { > struct sta_info *sta = container_of(txq->sta, struct sta_info, > sta); > - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); > + struct ieee80211_fast_tx *fast_tx; > > - hdr->seq_ctrl = ieee80211_tx_next_seq(sta, txq->tid); > - if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags)) > - info->flags |= IEEE80211_TX_CTL_AMPDU; > - else > - info->flags &= ~IEEE80211_TX_CTL_AMPDU; > + fast_tx = rcu_dereference(sta->fast_tx); > + if (WARN_ON(!fast_tx)) { > + /* lost the fast_tx pointer while the packet was queued */ > + ieee80211_free_txskb(hw, skb); > + goto begin; > + } > + ieee80211_xmit_fast_finish(sta->sdata, sta, fast_tx, skb, false); > + } else { > + struct ieee80211_tx_data tx = { }; > + > + __skb_queue_head_init(&tx.skbs); > + tx.local = local; > + if (txq->sta) { > + struct sta_info *sta = container_of(txq->sta, > + struct sta_info, > + sta); sta is unneeded give the assignment below? Regards, Jason > + tx.sta = container_of(txq->sta, struct sta_info, sta); > + tx.sdata = sta->sdata; > + } else { > + tx.sdata = vif_to_sdata(info->control.vif); > + } > + > + __skb_queue_tail(&tx.skbs, skb); > + > + if (invoke_tx_handlers_late(&tx)) > + goto begin; > + > + __skb_unlink(skb, &tx.skbs); > }