Merge remote-tracking branch 'net-next/master' into mac80211-next
authorJohannes Berg <johannes.berg@intel.com>
Tue, 4 Oct 2016 07:22:19 +0000 (09:22 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 4 Oct 2016 07:46:44 +0000 (09:46 +0200)
Resolve the merge conflict between Felix's/my and Toke's patches
coming into the tree through net and mac80211-next respectively.
Most of Felix's changes go away due to Toke's new infrastructure
work, my patch changes to "goto begin" (the label wasn't there
before) instead of returning NULL so flow control towards drivers
is preserved better.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1  2 
net/mac80211/ieee80211_i.h
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/tx.c
net/wireless/nl80211.c

Simple merge
Simple merge
@@@ -1647,7 -1638,10 +1636,8 @@@ ieee80211_sta_ps_deliver_response(struc
                        return;
  
                for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
-                       if (!(tids & BIT(tid)) || txq_has_queue(sta->sta.txq[tid]))
 -                      struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
 -
+                       if (!(driver_release_tids & BIT(tid)) ||
 -                          txqi->tin.backlog_packets)
++                          txq_has_queue(sta->sta.txq[tid]))
                                continue;
  
                        sta_info_recalc_tim(sta);
@@@ -3374,90 -3316,6 +3374,94 @@@ static bool ieee80211_xmit_fast(struct 
        return true;
  }
  
-       if (skb && skb_has_frag_list(skb) &&
-           !ieee80211_hw_check(&local->hw, TX_FRAG_LIST))
-               skb_linearize(skb);
 +struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
 +                                   struct ieee80211_txq *txq)
 +{
 +      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;
 +      struct ieee80211_tx_data tx;
 +      ieee80211_tx_result r;
 +
 +      spin_lock_bh(&fq->lock);
 +
 +      if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags))
 +              goto out;
 +
 +      /* Make sure fragments stay together. */
 +      skb = __skb_dequeue(&txqi->frags);
 +      if (skb)
 +              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;
 +      info = IEEE80211_SKB_CB(skb);
 +
 +      memset(&tx, 0, sizeof(tx));
 +      __skb_queue_head_init(&tx.skbs);
 +      tx.local = local;
 +      tx.skb = skb;
 +      tx.sdata = vif_to_sdata(info->control.vif);
 +
 +      if (txq->sta)
 +              tx.sta = container_of(txq->sta, struct sta_info, sta);
 +
 +      /*
 +       * The key can be removed while the packet was queued, so need to call
 +       * this here to get the current key.
 +       */
 +      r = ieee80211_tx_h_select_key(&tx);
 +      if (r != TX_CONTINUE) {
 +              ieee80211_free_txskb(&local->hw, skb);
 +              goto begin;
 +      }
 +
 +      if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
 +              struct sta_info *sta = container_of(txq->sta, struct sta_info,
 +                                                  sta);
 +              u8 pn_offs = 0;
 +
 +              if (tx.key &&
 +                  (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
 +                      pn_offs = ieee80211_hdrlen(hdr->frame_control);
 +
 +              ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
 +                                         tx.key, skb);
 +      } else {
 +              if (invoke_tx_handlers_late(&tx))
 +                      goto begin;
 +
 +              skb = __skb_dequeue(&tx.skbs);
 +
 +              if (!skb_queue_empty(&tx.skbs))
 +                      skb_queue_splice_tail(&tx.skbs, &txqi->frags);
 +      }
 +
++      if (skb && skb_has_frag_list(skb) &&
++          !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) {
++              if (skb_linearize(skb)) {
++                      ieee80211_free_txskb(&local->hw, skb);
++                      goto begin;
++              }
++      }
++
 +out:
 +      spin_unlock_bh(&fq->lock);
 +
 +      return skb;
 +}
 +EXPORT_SYMBOL(ieee80211_tx_dequeue);
 +
  void __ieee80211_subif_start_xmit(struct sk_buff *skb,
                                  struct net_device *dev,
                                  u32 info_flags)
Simple merge