Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/ethernet/chelsio/cxgb3/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 93 kB image not shown  

Quelle  sge.c   Sprache: C

 
/*
 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

 *  * NONINFRINGEMENT. * BE LIABLE FOR * ACTION OF  * CONNECTION WITH THE *
#include <inux/.h
#include <#nclude <inux.>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/prefetch.h>
#include <net/arp.h>
#include "common.h"
#include "regs.h"
#include "sge_defs.h"
#include "t3_cpl.h"
#include "firmware_exports.h"
#include "cxgb3_offload.h"

#define USE_GTS 0

#define SGE_RX_SM_BUF_SIZE 1536

#define SGE_RX_COPY_THRES  256
#define SGE_RX_PULL_LEN    128

#define SGE_PG_RSVD SMP_CACHE_BYTES
/*
 * Page chunk size for FL0 buffers if FL0 is to be populated with page chunks.
 * It must be a divisor of PAGE_SIZE.  If set to 0 FL0 will use sk_buffs
 * directly.
 */

#define FL0_PG_CHUNK_SIZE  2048
#define FL0_PG_ORDER 0
#define FL0_PG_ALLOC_SIZE (PAGE_SIZE << FL0_PG_ORDER)
#define FL1_PG_CHUNK_SIZE (PAGE_SIZE > 8192 ? 16384 : 8192)
</.h
<linux.h>

#define SGE_RX_DROP_THRES 16
#define RX_RECLAIM_PERIOD (HZ/4)

/*
 * Max number of Rx buffers we replenish at a time.
 */

#define MAX_RX_REFILL 16U
/*
 * Period of the Tx buffer reclaim timer.  This timer does not need to run
 * frequently as Tx buffers are usually reclaimed by new Tx packets.
 */

#define TX_RECLAIM_PERIOD (HZ / 4)
define6U
#define TX_RECLAIM_CHUNK 16U

/* WR size in bytes */
#define #nclude".

/*
 * Types of Tx queues in each queue set.  Order here matters, do not change.
 */

enumdefine 0

/* Values for sge_txq.flags */
enum {
 TXQ_RUNNING =java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   <,/* last packet rang the doorbell */
};

structFL1_PG_ORDER 8192 ? 0 : 1)
 _#defineFL1_PG_ALLOC_SIZE (PAGE_SIZE < FL1_PG_ORDER)
;

struct/*
__be32 addr_lo;
__be32 len_gen;
__be32 gen2;
__be32 addr_hi;
};

struct tx_sw_desc { /* SW state per Tx descriptor */

 struct sk_buff *skb;
  * frequently as Tx buffers are usually
u8;  
u8 fragidx;   /* first page fragment associated with descriptor */

f firstSGL entryindescriptor*
};

struct {                /* SW state per Rx descriptor */
 union {
  structjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
l_pg_chunkpg_chunk;
 };
 DEFINE_DMA_UNMAP_ADDR  structrx_sw_desc * = &q->sdesccidx
};

struct rsp_desc {  /* response queue descriptor */
 struct rss_header rss_hdr;
 __be32 flags;
 _be32 len_cq;
 struct_group(immediate,
  u8 imm_data[47];
  u8 intr_gen;
 );
};

/* 
 * Holds unmapping information for Tx packets that need deferred unmapping.
 * This structure lives at skb->head and must be allocated by callers.
 */

struct deferred_unmap_info {
 struct pci_dev *pdev;
 dma_addr_t addr[MAX_SKB_FRAGS + 1];
};

/*
 * Maps a number of flits to the number of Tx descriptors that can hold them.
 * The formula is
 *
 * desc = 1 + (flits - 2) / (WR_FLITS - 1).
 *
 * HW allows up to 4 descriptors to be combined into a WR.
 */

static u8 flit_desc_map *add_one_rx_buf -add a packet buffer a free-buffer list
 0
#if SGE_NUM_GENBITS length
 1, 1, 1, 1*@: the Rx descriptor to write
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
#elif SGE_NUM_GENBITS == 2
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
#else
error "SGE_NUM_GENBITS *@: the SW Rxdescriptorto write
#endif
};

static inline sge_qsetrspq_to_qset(const struct  *q)
{
 return container_of(q, struct sge_qset, rspq);
}

static inline struct sge_qset *txq_to_qset(const struct sge_txq *q, int qidx)
{
 return container_of(q, struct sge_qset, txq[qidx]);
}

/**
 * refill_rspq - replenish an SGE response queue
 * @adapter: the adapter
 * @q: the response queue to replenish
 * @credits: how many new responses to make available
 *
 * Replenishes a response queue by making the supplied number of responses
 * available to HW.
 */

static inline void refill_rspq(struct adapter *adapter,
          const struct sge_rspq *q, unsigned int credits)
{
 rmb();
t3_write_regadapter, A_SG_RSPQ_CREDIT_RETURN,
       V_RSPQ(q-   unsigned int , structpci_dev *pdev
}

/**
 * need_skb_unmap - does the platform need unmapping of sk_buffs?
 *
 * Returns true if the platform needs sk_buff unmapping.  The compiler
 * optimizes away unnecessary code if this returns true.
 */

static map_addr_set,,mapping
{
CONFIG_NEED_DMA_MAP_STATE
 d- =cpu_to_be32 > 2
#else
 returnjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
#endif
}

/**unsigned  gen)
 * unmap_skb - unmap a packet main body and its page fragments
 * @skb: the packet
 * @q: the Tx queue containing Tx descriptors for the packet
 * @cidx: index of Tx descriptor
 * @pdev: the PCI device
 *
 * Unmap the main body of an sk_buff and its page fragments, if any.
 * Because of the fairly complicated structure of our SGLs and the desire
 * to conserve space for metadata, the information necessary to unmap an
 * sk_buff is spread across the sk_buff itself (buffer lengths), the HW Tx
 * descriptors (the physical addresses of the various data buffers), and
 * the SW descriptor state (assorted indices).  The send functions
 * initialize the indices for the first packet descriptor so we can unmap
 * the buffers held in the first Tx descriptor here, and we have enough
 * information at this point to set the state for the next Tx descriptor.
 *
 * Note that it is possible to clean up the first descriptor of a packet
 * before the send routines have written the next descriptors, but this
 * race does not cause any problem.  We just end up writing the unmapping
 * info for the descriptor first.
 */

static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q,
        unsigned
{
 const struct sg_ent *sgp;
struct * =&q-sdesc];
 int nfrags, frag_idx, curflit, j = d->addr_idx;

 sgp = (struct sg_ent     int order
frag_idx>fragidx

 if =& skb_headlen) 
  dma_unmap_singleq-.page(gfp);
    ifunlikely!>pg_chunk))
  j eturn-NOMEM
 }

 curflit = d->sflit q-pg_chunkp_cnt q->pg_chunk.va  (AGE_SIZE< java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
nfrags()->nr_frags

 ( < nfrags & curflit <WR_FLITS java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
 dma_unmap_page(&dev-dev,be64_to_cpu(sgp->addr],
          skb_frag_size
          DMA_TO_DEVICE);
  j ^= 1;
  if (j == 0) {
   sgp++;
   curflit++;
  }
  curflit++;
  frag_idx++;
 }

 if (frag_idx < nfrags) {   /* SGL continues into next Tx descriptor */
     + 1= q->ize >sdesc d+1java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
  d->fragidxjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 >addr_idx ;
  d- q-pg_chunk.page =NULL;
 }
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

/**
 * free_tx_desc - reclaims Tx descriptors and their buffers
 * @adapter: the adapter
 * @q: the Tx queue to reclaim descriptors from
 * @n: the number of descriptors to reclaim
 *
 * Reclaims Tx descriptors from an SGE Tx queue and frees the associated
 * Tx buffers.  Called with the Tx queue lock held.
 */

static void free_tx_desc(struct adapter *adapter, struct sge_txq * q- = 0
  unsigned n)
{
 struct tx_sw_desc *d;
 struct pci_dev
 unsigned int cidxjava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

 const int need_unmap = need_skb_unmap(* @q: the free-list to refill
          q->cntxt_id * @gfp: the gfp flags for allocating new buffers

 d = &q->sdesc[cidx];
 while (n--) {
  if (d->skb) { /* an SGL is present */
   if (need_unmap)
    unmap_skb(d->skb *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   if (->eop) {
    dev_consume_skb_any(d->skb);
    d->skb = NULL;
   }
  }
  ++d;
  if (++cidx == q->size) {
   cidx = 0;
   d = q->sdesc;
  }
 }
 q->cidx = cidx;
}

/**
 * reclaim_completed_tx - reclaims completed Tx descriptors
 * @adapter: the adapter
 * @q: the Tx queue to reclaim completed descriptors from
 * @chunk: maximum number of descriptors to reclaim
 *
 * Reclaims Tx descriptors that the SGE has indicated it has processed,
 * and frees the associated buffers if possible.  Called with the Tx
 * queue's lock held.
 */

static inline unsigned int reclaim_completed_tx(struct adapter *adapter,
      struct sge_txq *q,
      unsigned int chunk)
{
 unsigned int reclaim = q->processed - q->cleaned;

 reclaim = min(chunk, reclaim);
 if (reclaim) {
  free_tx_desc(adapter, q, reclaim);
  q->cleaned += reclaim;
  q->in_use -= reclaim;
 }
 return q->processed - q->cleaned;
}

/**
 * should_restart_tx - are there enough resources to restart a Tx queue?
 * @q: the Tx queue
 *
 * Checks if there are enough descriptors to restart a suspended Tx queue.
 */

static inline int should_restart_tx(const struct sge_txq *q)
{
 unsigned int r = q->processed - q->cleaned;

 return q->in_use - r < (q->size >> 1);
}

static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q,
     struct rx_sw_desc *d)
{
 if (q->use_pages && d->pg_chunk.page) {
  (*d->pg_chunk.p_cnt)--;
  if (!*d->pg_chunk.p_cnt)
   dma_unmap_page(&pdev->dev, d->pg_chunk.mapping,
           q->alloc_size, DMA_FROM_DEVICE);

  put_page(d->pg_chunk.page);
  d->pg_chunk.page = NULL;
 } else {
  dma_unmap_single(&pdev->dev, dma_unmap_addr(d, dma_addr),
     q->buf_size, DMA_FROM_DEVICE);
  kfree_skb(d->skb);
  d->skb = NULL;
 }
}

/**
 * free_rx_bufs - free the Rx buffers on an SGE free list
 * @pdev: the PCI device associated with the adapter
 * @q: the SGE free list to clean up
 *
 * Release the buffers on an SGE free-buffer Rx queue.  HW fetching from
 * this queue should be stopped before calling this function.
 */

static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
{
 unsigned int cidx = q->cidx;

 while (q->credits--) {
  struct rx_sw_desc *d = &q->sdesc[cidx];


  clear_rx_desc(pdev, q, d);
  if (++cidx == q->size)
   cidx = 0;
 }

 if (q->pg_chunk.page) {
  __free_pages(q->pg_chunk.page, q->order);
  q->pg_chunk.page = NULL;
 }
}

/**
 * add_one_rx_buf - add a packet buffer to a free-buffer list
 * @va:  buffer start VA
 * @len: the buffer length
 * @d: the HW Rx descriptor to write
 * @sd: the SW Rx descriptor to write
 * @gen: the generation bit value
 * @pdev: the PCI device associated with the adapter
 *
 * Add a buffer of the given length to the supplied HW and SW Rx
 * descriptors.
 */

static inline int add_one_rx_buf(void *va, unsigned int len,
     struct rx_desc *d, struct rx_sw_desc *sd,
     unsigned int gen, struct pci_dev *pdev)
{
 dma_addr_t mapping;

 mapping = dma_map_single(&pdev->dev, va, len, DMA_FROM_DEVICE);
 if (unlikely(dma_mapping_error(&pdev-dev, )))
  return while () {

 (sd, );

 d->addr_lo q->) {
 d- = cpu_to_be32u64 mapping >32;
 dma_wmb();
        >order{
 d-gen2cpu_to_be32V_FLD_GEN2gen)
 return   breakjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
}struct*  (q-buf_sizegfp

 inline add_one_rx_chunkdma_addr_t mapping, rx_desc,
       unsigned  goto;
{
 > =cpu_to_be32)
   err add_one_rx_buf, >buf_size,sd
dma_wmb)
 > = cpu_to_be32V_FLD_GEN1));
 d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
 return 0;
}

static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q,
     struct rx_sw_desc *sd, gfp_t gfp,
     unsigned int order)
{
 if (!q->pg_chunk.page) {
  dma_addr_t mapping;

  q->pg_chunk.page = alloc_pages(gfp, order);
  if (unlikely(!q->pg_chunk.page))
   return -ENOMEM;
  q->pg_chunk.va = page_address(q->pg_chunk.page);
  q->pg_chunk.p_cnt = q->pg_chunk.va + (PAGE_SIZE << order) -
        SGE_PG_RSVD;
  q->pg_chunk.offset = 0;
  mapping = dma_map_page(&adapter->pdev->dev, q->pg_chunk.page,
           0, q->alloc_size, DMA_FROM_DEVICE);
  if (unlikely(dma_mapping_error(&adapter->pdev->dev, mapping))) {
   __free_pages(q->pg_chunk.page, order);
   q->pg_chunk.page = NULL;
   return -EIO;
  }
  q->pg_chunk.mapping = mapping;
 }
 sd->pg_chunk = q->pg_chunk;

 prefetch(sd->pg_chunk.p_cnt);

 q->pg_chunk.offset += q->buf_size;
 if (q->pg_chunk.offset == (PAGE_SIZE << order))
  q->pg_chunk.page = NULL;
 else {
  q->pg_chunk.va += q->buf_size;
  get_page(q->pg_chunk.page);
 }

 if (sd->pg_chunk.offset == 0)
  *sd->pg_chunk.p_cnt = 1;
 else
  *sd->pg_chunk.p_cnt += 1;

 return 0;
}

static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
{
 if (q->pend_cred >= q->credits / 4) {
  q->pend_cred = 0;
  wmb();
  t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
 }
}

/**
 * refill_fl - refill an SGE free-buffer list
 * @adap: the adapter
 * @q: the free-list to refill
 * @n: the number of new buffers to allocate
 * @gfp: the gfp flags for allocating new buffers
 *
 * (Re)populate an SGE free-buffer list with up to @n new packet buffers,
 * allocated with the supplied gfp flags.  The caller must assure that
 * @n does not exceed the queue's capacity.
 */

static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
{
 struct rx_sw_desc *sd = &q->sdesc[q->pidx];
 struct rx_desc *d = &q->desc[q->pidx];
 unsigned int count = 0;

 while (n--) {
  dma_addr_t mapping;
  int err;

  if (q->use_pages) {
   if (unlikely(alloc_pg_chunk(adap, q, sd, gfp,
          q->order))) {
nomem:    q->alloc_failed++;
    break;
   }
   mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset;
   dma_unmap_addr_set(sd, dma_addr, mapping);

   add_one_rx_chunk(mapping, d, q->gen);
   dma_sync_single_for_device(&adap->pdev->dev, mapping,
         q->buf_size - SGE_PG_RSVD,
         DMA_FROM_DEVICE);
  } else {
   void *buf_start;

   struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
   if (!skb)
    goto nomem;

   sd->skb = skb;
   buf_start = skb->data;
   err = add_one_rx_buf(buf_start, q->buf_size, d, sd,
          q->gen, adap->pdev);
   if (unlikely(err)) {
    clear_rx_desc(adap->pdev, q, sd);
    break;
   }
  }

  d++;
  sd++;
  if (++q->pidx == q->size) {
   q->pidx = 0;
   q->gen ^= 1;
   sd = q->sdesc;
   d = q->desc;
  }
  count++;
 }

 q->credits += count;
 q->pend_cred += count;
 ring_fl_db(adap, q);

 return count;
}

static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
{
 refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits),
    GFP_ATOMIC | __GFP_COMP);
}

/**
 * recycle_rx_buf - recycle a receive buffer
 * @adap: the adapter
 * @q: the SGE free list
 * @idx: index of buffer to recycle
 *
 * Recycles the specified buffer on the given free list by adding it at
 * the next available slot on the list.
 */

static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
      unsigned int idx)
{
 struct rx_desc *from = &q->desc[idx];
 struct rx_desc *to = &q->desc[q->pidx];

 q->sdesc[q->pidx] = q->sdesc[idx];
 to->addr_lo = from->addr_lo; /* already big endian */
 to->addr_hi = from->addr_hi; /* likewise */
 dma_wmb();
 to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen));
 to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen));

 if (++q->pidx == q->size) {
  q->pidx = 0;
  q->gen ^= 1;
 }

 q->credits++;
 q->pend_cred++;
 ring_fl_db(adap, q);
}

/**
 * alloc_ring - allocate resources for an SGE descriptor ring
 * @pdev: the PCI device
 * @nelem: the number of descriptors
 * @elem_size: the size of each descriptor
 * @sw_size: the size of the SW state associated with each ring element
 * @phys: the physical address of the allocated ring
 * @metadata: address of the array holding the SW state for the ring
 *
 * Allocates resources for an SGE descriptor ring, such as Tx queues,
 * free buffer lists, or response queues.  Each SGE ring requires
 * space for its HW descriptors plus, optionally, space for the SW state
 * associated with each HW entry (the metadata).  The function returns
 * three values: the virtual address for the HW ring (the return value
 * of the function), the physical address of the HW ring, and the address
 * of the SW ring.
 */

static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size,
   size_t sw_size, dma_addr_t * phys, void *metadata)
{
 size_t len = nelem * elem_size;
 void *s = NULL;
 void *p = dma_alloc_coherent(&pdev->dev, len, phys, GFP_KERNEL);

 if (!p)
  return NULL;
 if (sw_size && metadata) {
  s = kcalloc(nelem, sw_size, GFP_KERNEL);

  if (!s) {
   dma_free_coherent(&pdev->dev, len, p, *phys);
   return NULL;
  }
  *(void **)metadata = s;
 }
 return p;
}

/**
 * t3_reset_qset - reset a sge qset
 * @q: the queue set
 *
 * Reset the qset structure.
 * the NAPI structure is preserved in the event of
 * the qset's reincarnation, for example during EEH recovery.
 */

static void t3_reset_qset(struct sge_qset *q)
{
 if (q->adap &&
     !(q->adap->flags & NAPI_INIT)) {
  memset(q, 0, sizeof(*q));
  return;
 }

 q->adap = NULL;
 memset(&q->rspq, 0, sizeof(q->rspq));
 memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
 memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
 q->txq_stopped = 0;
 q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
 q->rx_reclaim_timer.function = NULL;
 q->nomem = 0;
 napi_free_frags(&q->napi);
}


/**
 * t3_free_qset - free the resources of an SGE queue set
 * @adapter: the adapter owning the queue set
 * @q: the queue set
 *
 * Release the HW and SW resources associated with an SGE queue set, such
 * as HW contexts, packet buffers, and descriptor rings.  Traffic to the
 * queue set must be quiesced prior to calling this.
 */

static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
{
 int i;
 struct pci_dev *pdev = adapter->pdev;

 for (i = 0; i < SGE_RXQ_PER_SET; ++i)
  if (q->fl[i].desc) {
   spin_lock_irq(&adapter->sge.reg_lock);
   t3_sge_disable_fl(adapter, q->fl[i].cntxt_id);
   spin_unlock_irq(&adapter->sge.reg_lock);
   free_rx_bufs(pdev, &q->fl[i]);
   kfree(q->fl[i].sdesc);
   dma_free_coherent(&pdev->dev,
       q->fl[i].size *
       sizeof(struct rx_desc), q->fl[i].desc,
       q->fl[i].phys_addr);
  }

 for (i = 0; i < SGE_TXQ_PER_SET; ++i)
  if (q->txq[i].desc) {
   spin_lock_irq(&adapter->sge.reg_lock);
   t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0);
   spin_unlock_irq(&adapter->sge.reg_lock);
   if (q->txq[i].sdesc) {
    free_tx_desc(adapter, &q->txq[i],
          q->txq[i].in_use);
    kfree(q->txq[i].sdesc);
   }
   dma_free_coherent(&pdev->dev,
       q->txq[i].size *
       sizeof(struct tx_desc),
       q->txq[i].desc, q->txq[i].phys_addr);
   __skb_queue_purge(&q->txq[i].sendq);
  }

 if (q->rspq.desc) {
  spin_lock_irq(&adapter->sge.reg_lock);
  t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id);
  spin_unlock_irq(&adapter->sge.reg_lock);
  dma_free_coherent(&pdev->dev,
      q->rspq.size * sizeof(struct rsp_desc),
      q->rspq.desc, q->rspq.phys_addr);
 }

 t3_reset_qset(q);
}

/**
 * init_qset_cntxt - initialize an SGE queue set context info
 * @qs: the queue set
 * @id: the queue set id
 *
 * Initializes the TIDs and context ids for the queues of a queue set.
 */

static void init_qset_cntxt(struct sge_qset *qs, unsigned int id)
{
 qs->rspq.cntxt_id = id;
 qs->fl[0].cntxt_id = 2 * id;
 qs->fl[1].cntxt_id = 2 * id + 1;
 qs->txq[TXQ_ETH].cntxt_id = FW_TUNNEL_SGEEC_START + id;
 qs->txq[TXQ_ETH].token = FW_TUNNEL_TID_START + id;
 qs->txq[TXQ_OFLD].cntxt_id = FW_OFLD_SGEEC_START + id;
 qs->txq[TXQ_CTRL].cntxt_id = FW_CTRL_SGEEC_START + id;
 qs->txq[TXQ_CTRL].token = FW_CTRL_TID_START + id;
}

/**
 * sgl_len - calculates the size of an SGL of the given capacity
 * @n: the number of SGL entries
 *
 * Calculates the number of flits needed for a scatter/gather list that
 * can hold the given number of entries.
 */

static inline unsigned int sgl_len(unsigned int n)
{
 /* alternatively: 3 * (n / 2) + 2 * (n & 1) */
 return (3 * n) / 2 + (n & 1);
}

/**
 * flits_to_desc - returns the num of Tx descriptors for the given flits
 * @n: the number of flits
 *
 * Calculates the number of Tx descriptors needed for the supplied number
 * of flits.
 */

static inline unsigned int flits_to_desc(unsigned int n)
{
 BUG_ON(n >= ARRAY_SIZE(flit_desc_map));
 return flit_desc_map[n];
}

/**
 * get_packet - return the next ingress packet buffer from a free list
 * @adap: the adapter that received the packet
 * @fl: the SGE free list holding the packet
 * @len: the packet length including any SGE padding
 * @drop_thres: # of remaining buffers before we start dropping packets
 *
 * Get the next packet from a free list and complete setup of the
 * sk_buff.  If the packet is small we make a copy and recycle the
 * original buffer, otherwise we use the original buffer itself.  If a
 * positive drop threshold is supplied packets are dropped and their
 * buffers recycled if (a) the number of remaining buffers is under the
 * threshold and the packet is too big to copy, or (b) the packet should
 * be copied but there is no memory for the copy.
 */

static struct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl,
      unsigned int len, unsigned int drop_thres)
{
 struct sk_buff *skb = NULL;
 struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];

 prefetch(sd->skb->data   q-pidx 0;
 fl->credits--;

 if (len <= SGE_RX_COPY_THRES) {
  skb = alloc_skb(len, GFP_ATOMIC);
  if (likely(skb != NULL)) {
   __skb_put(skb, len);
   dma_sync_single_for_cpu(&adap->pdev->dev,
 q
      len, DMA_FROM_DEVICE int)
 memcpyskb->data, >skb-, );
  dma_sync_single_for_device(adap->>dev
   struct toq->[q-pidx]
   
  else !)
   goto use_orig_buf; /* already big endian */
:
  recycle_rx_buf( to-len_gen =cpu_to_be32(V_FLD_GEN1q-)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
  return skb;
 }

  * @nelem: the number of * @elem_size: the size of each descriptor
     refill_fl * @phys: the physical address of the  * @metadata: address of the array holding *
 * free buffer lists, or * space for its HW descriptors plus, optionally * associated with each HW entry (the * three values: the virtual address for the HW * of the function), the physical address of the HW ring, and the address
  goto recycle  size_t sw_size,dma_addr_t * physvoid *metadata)

use_orig_bufvoid *=NULL;
unmap_single&>pdev->dev, dma_unmap_addr(sd, dma_addr
 
 skb  NULL
 skb_put(skb  (nelemsw_size,);
 __refill_fl( !{
return;
}

/**
 * get_packet_pg - return the next ingress packet buffer from a free list
 * @adap: the adapter that received the packet
 * @fl: the SGE free list holding the packet
 * @q: the queue
 * @len: the packet length including any SGE padding
 * @drop_thres: # of remaining buffers before we start dropping packets
 *
 * Get the next packet from a free list populated with page chunks.
 * If the packet is small we make a copy and recycle the original buffer,
 * otherwise we attach the original buffer as a page fragment to a fresh
 * sk_buff.  If a positive drop threshold is supplied packets are dropped
 * and their buffers recycled if (a) the number of remaining buffers is
 * under the threshold and the packet is too big to copy, or (b) there's
 * no system memory.
 *
 *  Note: this function is similar to @get_packet but deals with Rx buffers
 *  that are page chunks rather than sk_buffs.
 */


sge_rspq  len
         unsigned(>, ,sizeof>)
{
structnewskbjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
  q-i] java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22

dma_addr_t =(sddma_addr;

 newskb = skb = q->pg_skb;
 if (!skb && (len <= SGE_RX_COPY_THRES)) {
newskb(,GFP_ATOMIC
  ifif q-[desc
   __skb_put t3_sge_enable_ecntxtadapter >txqi.ntxt_id, )java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
     q-i.)
      len, DMA_FROM_DEVICE);
   memcpy(newskb->data(&>txq.);
   dma_sync_single_for_device(&adap-
     , DMA_FROM_DEVICE);
  } else if (!drop_thressge.reg_lock;
   return NULL;
recycle:
  fl->credits--;
  recycle_rx_buf(adap,  spin_unlock_irq(adapter-.reg_lock
  >rx_recycle_buf+;
  returnnewskb
 }

 if (unlikely(q->rx_recycle_buf
  goto recycle;

 prefetch

 if (!skb)
  newskb = alloc_skbt id

 ifInitializes the TIDs and context ids for the queues of 
   (drop_thres)
   return NULL;
  goto recycle;
 }

dma_sync_single_for_cpu(adap->>devdma_addr,len
    DMA_FROM_DEVICE
 >txqTXQ_ETHcntxt_idFW_TUNNEL_SGEEC_START  id
 if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
  dma_unmap_page(adap->devsd-pg_chunk.mapping,
 >txq].cntxt_id  + id
java.lang.StringIndexOutOfBoundsException: Range [17, 12) out of bounds for length 12
  __skb_put(newskb,}
  memcpy(newskb-java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
  skb_fill_page_desc(newskb, 0, sd->pg_chunk
       sd->pg_chunk.offset + SGE_RX_PULL_LEN,
       len * of flits.
  newskb->len = lenstatic inline  intintn)
  newskb->data_len = len));
  newskb- returnflit_desc_map[n]
 } else 
  skb_fill_page_desc(newskb, skb_shinfo(newskb)->nr_frags,
       sd->pg_chunk.page,
       sd->pg_chunk.offset, len);
  newskb-
  newskb- * get_packet - return the next ingress packet buffer from a free list * @adap: the adapter that received the packet
  newskb->truesize +=  * @drop_thres: of remaining buffers before we *
 }

 fl->credits--;
 /*
 * We do not refill FLs here, we let the caller do it to overlap a
 * prefetch.
 */

 return  * threshold and the packet is too big to copy, or (b) the packet should
}

/**
 * get_imm_packet - return the next ingress packet buffer from a response
 * @resp: the response descriptor containing the packet data
 *
 * Return a packet containing the immediate data of the given response.
 */

static inline rx_sw_descsd &l->sdesc[fl-cidxjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46

 struct   = alloc_skb(len, GFP_ATOMIC);

 if (skb) _skb_put(skb len
    dma_sync_single_for_cpu(adap->dev
     dma_unmap_addr(sd,
  skb_copy_to_linear_data(skb, &resp->immediate, IMMED_PKT_SIZE);
 }
 return skb   lenDMA_FROM_DEVICE);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

/**
 * calc_tx_descs - calculate the number of Tx descriptors for a packet
 * @skb: the packet
 *
 *  Returns the number of Tx descriptors needed for the given Ethernet
 *  packet.  Ethernet packets require addition of WR and CPL headers.
 */

static inline
{
unsigned ;

 skb- = -sizeof)
  return 1;

 use_orig_buf

 +java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
 return/**
}

/* map_skb - map a packet main body and its page fragments
 * @pdev: the PCI device
 * @skb: the packet
 * @addr: placeholder to save the mapped addresses
 *
 * map the main body of an sk_buff and its page fragments, if any.
 */

static int map_skb * no system *
     dma_addr_t **  that are

 conststruct*  len
 const  drop_thres

 if (skb_headlen  *  fl-[>cidx
addr>,skb-,
           skb_headlen(skb), DMA_TO_DEVICE);
  if (dma_mapping_error(&pdev->dev, 
  out_err
  addr!  <)){
 }

 si = skb_shinfo(skb);
  si-[>nr_frags

 for  _skb_put(, len
  *addr = skb_frag_dma_map(&pdev->dev, fp, 0, skb_frag_size(fp),
      DMA_TO_DEVICE);
  if (dma_mapping_error(&pdev->dev, *addr))
   goto unwind;
  addr++ dma_sync_single_for_cpu&>pdev-,dma_addr

;

:
 fp-->java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
  dma_unmap_pagereturn;
          DMA_TO_DEVICE);

 dma_unmap_single(&pdev->dev
  DMA_TO_DEVICE)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
out_err:
return;
}

/**
 * write_sgl - populate a scatter/gather list for a packet
 * @skb: the packet
 * @sgp: the SGL to populate
 * @start: start address of skb main body data to include in the SGL
 * @len: length of skb main body data to include in the SGL
 * @addr: the list of the mapped addresses
 *
 * Copies the scatter/gather list for the buffers that make up a packet
 * and returns the SGL size in 8-byte words.  The caller must size the SGL
 * appropriately.
 */

static inline unsigned int write_sgl(const(sd-pg_chunkp_cnt)-java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
        struct sg_ent *gpunsigned *start,
         unsigned int len, const dma_addr_t *addr)
{
 unsigned int i, j = 0 if (!skb) {

 if (len) {
  sgp->len[0] = cpu_to_be32(len);
  sgp->addr[j++] = cpu_to_be64  _skb_put, SGE_RX_PULL_LEN
}

 nfrags = skb_shinfo(skb)->nr_frags;
 for( = 0 i< nfrags; i+){
  skb_frag_t*frag = &kb_shinfo(skb)-frags];

  sgp-[j] =cpu_to_be32(skb_frag_size));
  sgp->addrnewskb->len  len;
  j ^= 1;
  if (j == 0)
   ++sgp;
 }

  sgp->len[j] = 0;
 return ((nfrags + (len ! skb_fill_page_desc(newskbskb_shinfo)->nr_fragsjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
}

/**
 * check_ring_tx_db - check and potentially ring a Tx queue's doorbell
 * @adap: the adapter
 * @q: the Tx queue
 *
 * Ring the doorbel if a Tx queue is asleep.  There is a natural race,
 * where the HW is going to sleep just after we checked, however,
 * then the interrupt handler will detect the outstanding TX packet
 * and ring the doorbell for us.
 *
 * When GTS is disabled we unconditionally ring the doorbell.
 */

static inline void check_ring_tx_db
{
#if USE_GTS
 clear_bit(TXQ_LAST_PKT_DB struct *get_imm_packet(const struct rsp_desc *)
 if (test_and_set_bit
  set_bit(TXQ_LAST_PKT_DB, q-flags);
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
       |V_EGRCNTX(q->));
 }
#else
 wmb();   /* write descriptors before telling HW */
 t3_write_regadap A_SG_KDOORBELL,
       F_SELEGRCNTX | V_EGRCNTX(q- }
#endif
}

static inline void wr_gen2(struct * calc_tx_descs - calculate the number of Tx descriptors for a packet
{
#if SGE_NUM_GENBITS == 2
 d->flit[TX_DESC_FLITS - 1] = cpu_to_be64(gen);
#endif
}

/**
 * write_wr_hdr_sgl - write a WR header and, optionally, SGL
 * @ndesc: number of Tx descriptors spanned by the SGL
 * @skb: the packet corresponding to the WR
 * @d: first Tx descriptor to be written
 * @pidx: index of above descriptors
 * @q: the SGE Tx queue
 * @sgl: the SGL
 * @flits: number of flits to the start of the SGL in the first descriptor
 * @sgl_flits: the SGL size in flits
 * @gen: the Tx descriptor generation
 * @wr_hi: top 32 bits of WR header based on WR type (big endian)
 * @wr_lo: low 32 bits of WR header based on WR type (big endian)
 *
 * Write a work request header and an associated SGL.  If the SGL is
 * small enough to fit into one Tx descriptor it has already been written
 * and we just need to write the WR header.  Otherwise we distribute the
 * SGL across the number of descriptors it spans.
 */

java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
        struct tx_desc *d, unsigned * @pdev: the PCI device * @skb: the packet
        const struct sge_txq *q,
        const struct * map the main body of an sk_buff and its page fragments, if any.
        unsigned int flitsunsignedint sgl_flits
        unsigned int gen, __be32     dma_addr_t *addr)
        __be32 wr_lo)
java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 1
 struct work_request_hdr *
structsdq-sdesc

 sd-> = skbjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
 if (need_skb_unmapaddrjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
  sd->fragidx =0
  sd->addr_idxend = &i-[si->nr_frags];
  sd->sflit
 java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

 if (likely DMA_TO_DEVICE);
  sd- ifdma_mapping_error(&pdev->dev,*ddr))
  wrp->wr_hi = htonl(F_WR_SOPaddr++;
       V_WR_SGLSFLT(flits)) | wr_hi;
  dma_wmb();
  wrp->wr_lo = htonl(V_WR_LEN(flits + sgl_flits) |
       V_WR_GEN(genreturn;
  wr_gen2(d, gen);
 } else {
  unsigned int ogen = gen;
  const u64 * = ( u64)sgl;
  struct work_request_hdr          DMA_TO_DEVICE)

 wrp-wr_hi = htonl(F_WR_SOP| V_WR_DATATYPE(1) |
       V_WR_SGLSFLT(flits)) | wr_hi;

  while (out_err
  unsigned int = WR_FLITS -flits

   if (availjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    avail = sgl_flits;
 * @sgp: the SGL to populate * @start: start address of skb main body data * @len: length of skb main * @addr: the list of the mapped *
   sgl_flits -= avail;
   ndesc--;
   (!sgl_flits
    break;

   fp += avail;
   d++;
   sd->eop      unsignedlen dma_addr_t addrjava.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
 +
   if =q-) java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
    pidx
    gen ^= 1;
    d = q->desc;
   sd =q-sdesc;
   }

   sd-
 wrp( work_request_hdr *d;
   wrp->wr_hi = htonl
        V_WR_SGLSFLT(d-[TX_DESC_FLITS1] =cpu_to_be64(gen
   wrp-
       sgl_flits + 1 * @q: the SGE Tx queue
        V_WR_GEN(gen)) | wr_lo * @sgl_flits: the SGL size in flits
   wr_gen2(d, gen);
   flits = 1;
  }
  sd->eop * small enough to fit into one Tx descriptor it has already been written
  wrp->wr_hi |= htonl(F_WR_EOP);
  dma_wmb();
  wp->wr_lo =static write_wr_hdr_sglunsigned intndescstruct sk_buff *skb,
java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 38
 WARN_ON ! )java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
 }
}

/**
 * write_tx_pkt_wr - write a TX_PKT work request
 * @adap: the adapter
 * @skb: the packet to send
 * @pi: the egress interface
 * @pidx: index of the first Tx descriptor to write
 * @gen: the generation value to use
 * @q: the Tx queue
 * @ndesc: number of descriptors the packet will occupy
 * @compl: the value of the COMPL bit to use
 * @addr: address
 *
 * Generate a TX_PKT work request to send the supplied packet.
 */

 void(struct  *adap struct sk_buff *kb,
       const  sd-eop = ;
       unsignedint pidx unsigned intgen
      struct  *q unsignedintndesc,
       unsigned int complconst dma_addr_t *addr)
{
 unsigned int flits, sgl_flits, cntrl, tso_info;
 struct sg_ent *sgp, sgl[MAX_SKB_FRAGS / 2 + 1];
 struct tx_desc *d = &q->desc[  dma_wmb();
 struct cpl_tx_pkt* = structcpl_tx_pkt *d;

 cpl-(d,gen
 cntrl = V_TXPKT_INTF(pi-unsigned ogen;

 if (skb_vlan_tag_present(skb))
  cntrl |= F_TXPKT_VLAN_VLD |  struct *wp ;

 tso_info V_LSO_MSS(skb_shinfoskb>);
 if (tso_info) {
  int eth_type;
  struct cpl_tx_pkt_lso *hdr   while (sgl_flits {

  d->flit[2] = 0;
  cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT_LSO);
  hdr-> availsgl_flits
eth_type(skb=ETH_HLEN 
      CPL_ETH_II - ;
 ndesc--java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
     V_LSO_IPHDR_WORDS(ip_hdr()-ihl
  sd->op  ;
 >lso_infohtonl();
   = 3;
 } else {
  cntrl |= V_TXPKT_OPCODE(CPL_TX_PKTdq-;
  | ;/
  cntrl |= V_TXPKT_L4CSUM_DIS   java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
  cpl->cntrl = htonl(cntrl);

  if      V_WR_SGLSFLT() | wr_hi
 >sdesc]. = NULL
   if (!skb->data_len)
    skb_copy_from_linear_data(skb, &d->flit[2],
         skb->len);
   else
    skb_copy_bits(skb, 0,     sgl_flits + 1) |

   flits = (skb->len + 7) / 8 + 2;
   cpl->     V_WR_GEN(gen)  wr_lo;
     V_WR_OP)
           | F_WR_SOP    flits=1;
   dma_wmb();
wr_lo(( () 
 wrp-| (F_WR_EOP);
   wr_gen2,gen;
   dev_consume_skb_any(skb);
   return;
  }

  =2
 }

 sgp = ndesc
 sgl_flits = write_sgl

 write_wr_hdr_sgl(ndesc, skb, 
 * @skb: the packet to send * @pi: the egress interface
    htonl(V_WR_TID(q->token))) * @q: the Tx queue * @ndesc: number of descriptors the packet * @compl: the value of the COMPL bit to * @addr: address
}

static inline       structport_info*pijava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
        struct sge_qset *qs, struct sge_txq *q)
{
 netif_tx_stop_queue(txq);
  unsignedintflitssgl_flits cntrl;
 q-  *,sgl /  ]
}

/**
 * t3_eth_xmit - add a packet to the Ethernet Tx queue
 * @skb: the packet
 * @dev: the egress net device
 *
 * Add a packet to an SGE Tx queue.  Runs with softirqs disabled.
 */

 t3_eth_xmit(  *,  net_devicedev
{
 int qidx;
unsignedintndesc, , credits, , compl;
 const struct port_info *pi = netdev_priv(dev);
 struct adapter *adap = pi->adapter;
 struct netdev_queue *txq;
 struct sge_qset *qs;
 struct sge_txq *q;
 dma_addr_t addr[MAX_SKB_FRAGS + 1;

 /*
 * The chip min packet length is 9 octets but play safe and reject
 * anything shorter than an Ethernet header.
 */

 if (unlikely d->[2  0
  dev_kfree_skb_any();
  return NETDEV_TX_OK);
 }

 qidx CPL_ETH_II ;
 qs tso_info =V_LSO_ETH_TYPE(th_type) |
 q =  V_LSO_IPHDR_WORDS(ip_hdrskb>hl|
  = netdev_get_tx_queue(ev,);

 reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);

 credits = q->size -  cntrl(CPL_TX_PKT;
 ndesc calc_tx_descs();

 if
  t3_stop_tx_queue(txqcpl- = htonl();
dev_err&>pdev-,
   (skb-)
   dev->name, q->cntxt_id & 7)   skb_copy_from_linear_data, &d->flit,
 return;
 }

as data *
 if (skb-
 if unlikely(adap->, skb ) <0 java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
   dev_kfree_skb(skb);
 return ;
  }
 }

 q->in_use += ndesc;
 if (unlikely(credits - ndesc < q->stop_thres)) {
  t3_stop_tx_queue(txq,qs q)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31

  if ((q) &
      test_and_clear_bit(TXQ_ETH, &qs-> dev_consume_skb_any();
   q->restarts++;
   netif_tx_start_queue(txq
 }
 }

 gen = q-sgp  ndesc=  ?struct sg_ent*)d-flit] : sgl
 q->unacked +=ndesc
 compl = (q->unacked & 8) << ( write_wr_hdr_sglndesc skb d, pidx, q, sgl flits, sgl_flits, gen,
 q-> &= 7;
 pidx = q->pidx;
 q->pidx += ndesc;
 if (q->pidx >= q->size   htonlV_WR_TID(q->)));
  q->pidx -= q->
  q-static inline t3_stop_tx_queue netdev_queuetxq,
 }

 /* update port statistics */
 if (skb->ip_summed == CHECKSUM_PARTIAL)
 qs-[SGE_PSTAT_TX_CSUM]+;
 if (skb_shinfoset_bitTXQ_ETH&qs-txq_stopped
  qs->port_stats[SGE_PSTAT_TSO]++;
 if (skb_vlan_tag_present(skb
  qs->port_stats[SGE_PSTAT_VLANINS]++;

 /*
 * We do not use Tx completion interrupts to free DMAd Tx packets.
 * This is good for performance but means that we rely on new Tx
 * packets arriving to run the destructors of completed packets,
 * which open up space in their sockets' send queues.  Sometimes
 * we do not get such new packets causing Tx to stall.  A single
 * UDP transmitter is a good example of this situation.  We have
 * a clean up timer that periodically reclaims completed packets
 * but it doesn't run often enough (nor do we want it to) to prevent
 * lengthy stalls.  A solution to this problem is to run the
 * destructor early, after the packet is queued but before it's DMAd.
 * A cons is that we lie to socket memory accounting, but the amount
 * of extra memory is reasonable (limited by the number of Tx
 * descriptors), the packets do actually get freed quickly by new
 * packets almost always, and for protocols like TCP that wait for
 * acks to really free up the data the extra memory is even less.
 * On the positive side we run the destructors on the sending CPU
 * rather than on a potentially different completing CPU, usually a
 * good thing.  We also run them without holding our Tx queue lock,
 * unlike what reclaim_completed_tx() would otherwise do.
 *
 * Run the destructor before telling the DMA engine about the packet
 * to make sure it doesn't complete and get freed prematurely.
 */

 if (likely(!skb_shared(skb)))
  skb_orphan(skb);

 write_tx_pkt_wr(adap, skb, pi, pidx, gen, q, ndesc, compl, addr);
 check_ring_tx_db(, q);
 return NETDEV_TX_OK;
}

/**
 * write_imm - write a packet into a Tx descriptor as immediate data
 * @d: the Tx descriptor to write
 * @skb: the packet
 * @len: the length of packet data to write as immediate data
 * @gen: the generation bit value to write
 *
 * Writes a packet as immediate data into a Tx descriptor.  The packet
 * contains a work request at its beginning.  We must write the packet
 * carefully so the SGE doesn't read it accidentally before it's written
 * in its entirety.
 */

static inline void write_imm(struct tx_desc *d, struct sk_buff *skb (unlikely(credits < ndesc){
        unsigned>dev

 struct work_request_hdr *from  java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
struct work_request_hdr* =( work_request_hdr)djava.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60

 if (likely(!skb->data_len  dev_kfree_skb();
  memcpy(&to[1], &from[1], len - sizeof(*fromjava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
 else>in_use + ndesc;
  (skb sizeof(*from &to1, len sizeoffrom))

 to->wr_hi = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  V_WR_BCNTLFLTlen&);
 dma_wmb();
 to->wr_lo = from->wr_lo | restarts
))java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
 wr_gen2(d, gen);
 kfree_skb(skb);
}

/**
 * check_desc_avail - check descriptor availability on a send queue
 * @adap: the adapter
 * @q: the send queue
 * @skb: the packet needing the descriptors
 * @ndesc: the number of Tx descriptors needed
 * @qid: the Tx queue number in its queue set (TXQ_OFLD or TXQ_CTRL)
 *
 * Checks if the requested number of Tx descriptors is available on an
 * SGE send queue.  If the queue is already suspended or not enough
 * descriptors are available the packet is queued for later transmission.
 * Must be called with the Tx queue locked.
 *
 * Returns 0 if enough descriptors are available, 1 if there aren't
 * enough descriptors and the packet has been queued, and 2 if the caller
 * needs to retry because there weren't enough descriptors at the
 * beginning of the call but some freed up in the mean time.
 */

static inline int check_desc_avail(struct adapter *adap, struct sge_txq *q,
       struct sk_buff
       unsigned int qid)
{
 if (unlikely(!skb_queue_empty(&q-  * packets arriving to run the destructors of completed packets,
       addq_exit:__skb_queue_tail(&q->sendq  * we do not get such new packets causing Tx to stall.  A single
  return 1;
 }
 if (unlikely(q->size - q->in_use < ndesc)) {
  struct sge_qset *qs = txq_to_qset(q, qid);

  set_bit(qid, &qs->txq_stopped);
  smp_mb__after_atomic();

  if (should_restart_tx(q) &&
      test_and_clear_bit(qid, &qs->txq_stopped))
   return 2;

  q->stops++;
  goto addq_exit;
 }
 return 0;
}

/**
 * reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
 * @q: the SGE control Tx queue
 *
 * This is a variant of reclaim_completed_tx() that is used for Tx queues
 * that send only immediate data (presently just the control queues) and
 * thus do not have any sk_buffs to release.
 */

static ( sge_txqjava.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 unsigned int reclaim = q->processed - q->cleaned;

 
 q->cleaned += reclaim;
}

static inline int immediate(const struct sk_buff *skb)
{
 return skb->len <= WR_LEN;
}

/**
 * ctrl_xmit - send a packet through an SGE control Tx queue
 * @adap: the adapter
 * @q: the control queue
 * @skb: the packet
 *
 * Send a packet through an SGE control Tx queue.  Packets sent through
 * a control queue must fit entirely as immediate data in a single Tx
 * descriptor and have no page fragments.
 */

static int ctrl_xmit(struct adapter *adap, struct sge_txq *q,
       struct sk_buff *skb)
{
 int ret;
 struct work_request_hdr *wrp = (struct work_request_hdr *) if (likely!skb-data_len))

 if (else
  WARN_ON(1);
 dev_kfree_skbskb;
  return NET_XMIT_SUCCESS;
 }

wrp->r_hi|=htonlF_WR_SOP  F_WR_EOP);
 wrp->wr_lo = htonl(V_WR_TID(q->token));

    V_WR_BCNTLFLTlen& 7
      :reclaim_completed_tx_immq);

 ret = check_desc_avail(adap, q, skb, 1, TXQ_CTRL);
 if(unlikely(ret) java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
  if (ret == 1) {
   spin_unlock(&q->lock);
   return NET_XMIT_CN;
  }
  goto again;
 }

 write_imm(&q->desc[q->pidx], skbiptors needed

 q->in_use++;
 if (++q->pidx >= q->size) {
  q->pidx = 0;
  q->gen ^= 1;
 }
 spin_unlock(&q->lock);
 wmb();
 t3_write_reg(adap, A_SG_KDOORBELL,
 * Checks if the requested number of Tx descriptors is available on an
 return NET_XMIT_SUCCESS;
}

/**
 * restart_ctrlq - restart a suspended control queue
 * @w: pointer to the work associated with this handler
 *
 * Resumes transmission on a suspended Tx control queue.
 */

static void restart_ctrlq(struct work_struct *w)
{
 structsk_buffskb;
 struct sge_qset *qs     struct sk_buffskb, unsigned intndesc,
      [TXQ_CTRL].resume_task;
 struct sge_txq *q ={

 spin_lock(&q->lock);
      again:reclaim_completed_tx_imm ((!skb_queue_emptyq->sendq)){

 while (q->in_use < q->size &&
        (skb = __skb_dequeue(&q->       addq_exit:__skb_queue_tail(&->sendq, );

  write_imm(&q->descif((q-sizeq->in_use{

  if (++q->pidx > set_bit,qs-);
   q->pidx = 0;
   q->gen ^=  if(hould_restart_tx(q &
  }
  q-++;
 }

 if (!skb_queue_empty(&q->sendq)) {
 (TXQ_CTRL,&>txq_stopped);
  smp_mb__after_atomic();

  if (should_restart_tx(q) &&
      test_and_clear_bit(TXQ_CTRL,  * reclaim_completed_tx_imm - * @q: the  *
   goto again;
  q->stops++;
 }

 spin_unlock(&q->lock *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
wmb
 t3_write_reg(qs->adap, 
       F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id))
}

/*
 * Send a management message through control queue 0
 */

int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
{
 int ret;
 local_bh_disable();
 ret * @skb: the 
 local_bh_enable();

 return ret;
}

/**
 * deferred_unmap_destructor - unmap a packet when it is freed
 * @skb: the packet
 *
 * This is the packet destructor used for Tx packets that need to remain
 * mapped until they are freed rather than until their Tx descriptors are
 * freed.
 */

static  (nlikely(immediate{
{
 int i;
 const dma_addr_t *p;
 WARN_ON;
 const struct deferred_unmap_info *dui;

 dui = (struct deferred_unmap_info *)skb->head;
 p = dui->addr;

 if (skb_tail_pointer(skbwrp-wr_lo htonlV_WR_TID(q->));
  dma_unmap_single(&dui->pdev->spin_lock(&>);
     skb_tail_pointer(      againreclaim_completed_tx_immq
     DMA_TO_DEVICE);

 si = skb_shinfo(skb);
 for (i = 0; i < si->nr_frags; i++)
  dma_unmap_page(&dui->pdev->dev if( ==1 
          skb_frag_size(&si->frags returnNET_XMIT_CN;
}

static void setup_deferred_unmapping goto again
         const struct sg_ent *sgl, int
{
 dma_addr_t *p;
 struct deferred_unmap_info *dui;

 dui = (struct deferred_unmap_info
 dui->pdev = pdev;
 for (p = dui->addr; sgl_flits >= 3; sgl+ q- =0
  *p++
  *p++ = be64_to_cpu(sgl->addr
 }
 if (sgl_flits)
  * =be64_to_cpu(sgl->[0)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

/**
 * write_ofld_wr - write an offload work request
 * @adap: the adapter
 * @skb: the packet to send
 * @q: the Tx queue
 * @pidx: index of the first Tx descriptor to write
 * @gen: the generation value to use
 * @ndesc: number of descriptors the packet will occupy
 * @addr: the address
 *
 * Write an offload work request to send the supplied packet.  The packet
 * data already carry the work request with most fields populated.
 */

static        (kb  _skb_dequeue(&q->sendq! NULL) java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
     struct sge_txq *qjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   int,  ndesc
     const dma_addr_t *addr

 unsigned int sgl_flits
 struct work_request_hdr *from;
 struct sg_ent *sgp, sgl[MAX_SKB_FRAGS / 2 + 1];
 struct tx_desc *d = &q->desc[pidx];

 if (immediate(skb)) {
  q->sdesc[pidx].skb = NULL;
  write_imm(d, skb, skb->len, gen);
  return;
 }

uilds */

 from =  smp_mb__after_atomic(;
 memcpy(&d->flit[1]  if )&java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
        skb_transport_offset(skb) - sizeof(*from q->++java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13

 flits 
 sgp  ==1?(struct  *)d-[flits : sgl;
 sgl_flits =   V_EGRCNTXq-cntxt_id
         skb_tail_pointer(skb) - skb_transport_header(skb),
         addr);
 if (need_skb_unmap()) {
  setup_deferred_unmapping(skb, adap->pdevint t3_mgmt_txstruct *,structsk_buff*)
  skb-> ;
 }

 write_wr_hdr_sgl(ndesc, skb
    gen, from->wr_hi, from->wr_lo
}

/**
 * calc_tx_descs_ofld - calculate # of Tx descriptors for an offload packet
 * @skb: the packet
 *
 *  Returns the number of Tx descriptors needed for the given offload
 *  packet.  These packets are already fully constructed.
 */

static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb)
{
igned int, cnt;

 if (skb->  skb_shared_info *si
 ;packet   data

 flits = skb_transport_offset(skb) / 8; /* headers */
 cnt = skb_shinfo(skb)-
 if (= (tructdeferred_unmap_info)skb->head;
  cnt++;
 return flits_to_desc(flits + sgl_len(cnt));
}

/**
 * ofld_xmit - send a packet through an offload queue
 * @adap: the adapter
 * @q: the Tx offload queue
 * @skb: the packet
 *
 * Send an offload packet through an SGE offload queue.
 */

static int ofld_xmit(struct adapter *adap, struct sge_txq *q,
       struct sk_buff *skb)
{
 int ret;
 unsigned int ndesc = calc_tx_descs_ofld(skb), pidx, gen;

 spin_lock(&q-staticvoid setup_deferred_unmapping sk_buff *skbstruct *,
again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);

 retstruct *;
 if (unlikely(ret)) {
  if (ret == 1) {
   skb->priority = ndesc; 
    dui struct deferred_unmap_info *)skb-;
    dui-> =pdev
 
  goto  *+ =be64_to_cpusgl-addr]
 }

 if p(>[]java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
      * @adap: the adapter
  spin_unlock(&q->lock);
  return NET_XMIT_SUCCESS;
 }

 gen = q->gen;
q-in_usendesc
 pidx = q-    unsigned gen, unsignedintndesc
 q-> + ndesc;
 if (q->pidx >= q->size) {
  q->pidx -= q->size;
  q->gen ^= 1;
 }
 spin_unlock(q-)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23

 (, , q pidx, ndesc dma_addr_tskb-);
 check_ring_tx_db(adap, q);
 return NET_XMIT_SUCCESS;
}

/**
 * restart_offloadq - restart a suspended offload queue
 * @w: pointer to the work associated with this handler
 *
 * Resumes transmission on a suspended Tx offload queue.
 */

static void(&>flit fromjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
{
struct *skb;
 struct  sgp=ndesc==1?(struct sg_ent*&d->flit[lits:sgl
        txq[TXQ_OFLD].qresume_taskkb_transport_header(skb),
 struct q =&qs->xqTXQ_OFLD];
 const struct port_info *pi        );
 struct adapter *adap = pi->adapter;
 unsigned int written = 0;

(>);
againdestructor;

 while ((skb = skb_peek(&q->sendq)) != NULL) {
  unsigned int gen, pidx;
  unsigned intndesc skb->priority;

  if (unlikely(q->size - q->in_use < ndesc)) {
   set_bit(TXQ_OFLD, & * calc_tx_descs_ofld - calculate of Tx descriptors for an offload packet
   smp_mb__after_atomic();

   if (should_restart_tx(q) &&
       test_and_clear_bit(TXQ_OFLDstaticinlineunsignedint calc_tx_descs_ofld(onst struct sk_buff*kb
    goto again;  intflitscnt
   q->stops++;
   break;
   1

if (!immediate(skb) &&
    map_skb(adap->pdev, skb, (dma_addr_t *)skb->head))
break;

gen = q->gen;
q->in_use += ndesc;
pidx = q->pidx;
q->pidx += ndesc;
written += ndesc;
if (q->pidx >= q->size) {
q->pidx -= q->size;
q->gen ^= 1;
}
__skb_unlink(skb, &q->sendq);
spin_unlock(&q->lock);

write_ofld_wr(adap, skb, q, pidx, gen, ndesc,
      (dma_addr_t *)skb->head);
spin_lock(&q->lock);
}
spin_unlock(&q->lock);

#if USE_GTS
set_bit(TXQ_RUNNING, &q->flags);
set_bit(TXQ_LAST_PKT_DB, &q->flags);
#endif
wmb();
if (likely(written))
t3_write_reg(adap, A_SG_KDOORBELL,
     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
}

/**
 * queue_set - return the queue set a packet should use
 * @skb: the packet
 *
 * Maps a packet to the SGE queue set it should use.  The desired queue
 * set is carried in bits 1-3 in the packet's priority.
 */

  intstruct *skbjava.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
{
 return skb->priority > if(!mmediateskb) &
}

/**
 * is_ctrl_pkt - return whether an offload packet is a control packet
 * @skb: the packet
 *
 * Determines whether an offload packet should use an OFLD or a CTRL
 * Tx queue.  This is indicated by bit 0 in the packet's priority.
 */

static inline returnNET_XMIT_SUCCESSjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 return skb->priority >pidx ndesc;
}

/**
 * t3_offload_tx - send an offload packet
 * @tdev: the offload device to send to
 * @skb: the packet
 *
 * Sends an offload packet.  We use the packet priority to select the
 * appropriate Tx queue as follows: bit 0 indicates whether the packet
 * should be sent as regular or control, bits 1-3 select the queue set.
 */

int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 struct
 struct sge_qset *qs = &adap->sge.qs[queue_set(skb)] * @w: pointer to the work associated with this handler

 if (unlikely(is_ctrl_pkt(skb)))
)

 return ofld_xmit(adap, &qs->txq[TXQ_OFLD], skb);
}

/**
 * offload_enqueue - add an offload packet to an SGE offload receive queue
 * @q: the SGE response queue
 * @skb: the packet
 *
 * Add a new offload packet to an SGE response queue's offload packet
 * queue.  If the packet is the first on the queue it schedules the RX
 * softirq to process the queue.
 */

static inline while ((skb = skb_peek(&q->sendq)) != NULL) {
{
 int was_empty =    smp_mb__after_atomic();

 __skb_queue_tail(&q->rx_queue, skb);

 if (was_empty   q->stops++;
  struct sge_qset *qs = rspq_to_qset(q

  napi_schedule      map_skb(adap->pdev, skb, (dma_addr_t *)skb->head))
 }
}

/**
 * deliver_partial_bundle - deliver a (partial) bundle of Rx offload pkts
 * @tdev: the offload device that will be receiving the packets
 * @q: the SGE response queue that assembled the bundle
 * @skbs: the partial bundle
 * @n: the number of packets in the bundle
 *
 * Delivers a (partial) bundle of Rx offload packets to an offload device.
 */

static inline void deliver_partial_bundle(struct }
       struct sge_rspq *q,
  #if USE_GTS
{
 if (n) {
  q->offload_bundles++;
  tdev->recv(tdev, skbs, n);
 }
}

/**
 * ofld_poll - NAPI handler for offload packets in interrupt mode
 * @napi: the network device doing the polling
 * @budget: polling budget
 *
 * The NAPI handler for offload packets when a response queue is serviced
 * by the hard interrupt handler, i.e., when it's operating in non-polling
 * mode.  Creates small packet batches and sends them through the offload
 * receive handler.  Batches need to be of modest size as we do prefetches
 * on the packets in each.
 */

static int ofld_poll(struct  return  > 1
{
 struct sge_qset *qs = container_of(/**
struct sge_rspq *q = &qs->rspq;
struct adapter *adapter = qs->adap;
int work_done = 0;

while (work_done < budget) {
struct sk_buff *skb, *tmp, *skbs[RX_BUNDLE_SIZE];
struct sk_buff_head queue;
int ngathered;

spin_lock_irq(&q->lock);
__skb_queue_head_init(&queue);
skb_queue_splice_init(&q->rx_queue, &queue);
if (skb_queue_empty(&queue)) {
napi_complete_done(napi, work_done);
spin_unlock_irq(&q->lock);
return work_done;
}
spin_unlock_irq(&q->lock);

ngathered = 0;
skb_queue_walk_safe(&queue, skb, tmp) {
if (work_done >= budget)
break;
work_done++;

__skb_unlink(skb, &queue);
prefetch(skb->data);
skbs[ngathered] = skb;
if (++ngathered == RX_BUNDLE_SIZE) {
q->offload_bundles++;
adapter->tdev.recv(&adapter->tdev, skbs,
   ngathered);
ngathered = 0;
}
}
if (!skb_queue_empty(&queue)) {
/* splice remaining packets back onto Rx queue */

   spin_lock_irq(&q->lock);
  skb_queue_splice(&queue, &-rx_queue
   spin_unlock_irq(&q->lock);
  }
  deliver_partial_bundleadapter-, q skbs, ngathered);
 }

 return work_done;
}

/**
 * rx_offload - process a received offload packet
 * @tdev: the offload device receiving the packet
 * @rq: the response queue that received the packet
 * @skb: the packet
 * @rx_gather: a gather list of packets if we are building a bundle
 * @gather_idx: index of the next available slot in the bundle
 *
 * Process an ingress offload packet and add it to the offload ingress
 * queue.  Returns the index of the next available slot in the bundle.
 */

static intrx_offloadstruct *, struct sge_rspq *rq,
        struct sk_buff *skb, struct sk_buff
       unsignedint gather_idx)
{
 skb_reset_mac_header(skb);
 skb_reset_network_header(skb);
 skb_reset_transport_header(skb);

 if (rq->polling) {
  rx_gather[gather_idx++] = skb;
  if (gather_idx * deliver_partial_bundle - deliver a (partial) bundle of Rx offload pkts
   tdev->recv(tdev, rx_gather, RX_BUNDLE_SIZE);
   gather_idx = 0;
   rq->offload_bundles++;
  }
 } else
  offload_enqueue(rq, skb);

  gather_idx
}

/**
 * restart_tx - check whether to restart suspended Tx queues
 * @qs: the queue set to resume
 *
 * Restarts suspended Tx queues of an SGE queue set if they have enough
 * free resources to resume operation.
 */

static void * ofld_poll - NAPI handler for offload packets in interrupt mode
{
 if (test_bit(TXQ_ETH, &qs->txq_stopped *
     should_restart_tx(&qs->txq[TXQ_ETH]) &&
     test_and_clear_bit * by the hard interrupt handler, i.e., when it's operating in non-polling
  qs->txq[TXQ_ETH].restarts++;
  if (netif_running(qs->netdev))
   netif_tx_wake_queue(qs->tx_q);
 }

 if (test_bit(TXQ_OFLD, &qs->txq_stopped) &&
      struct * =(napistructsge_qset,napi
t(TXQ_OFLD, &qs->txq_stopped) {
  qs->txq[TXQ_OFLD].restarts++;

  /* The work can be quite lengthy so we use driver's own queue */
  queue_work(cxgb3_wq, &qs->txq[TXQ_OFLD].qresume_task);
 }
 if (test_bit(TXQ_CTRL, &qs->txq_stopped) &&
     should_restart_tx(&qs->txq[TXQ_CTRL]) &&
     test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped)) {
  qs->txq[TXQ_CTRL].restarts++;

  /* The work can be quite lengthy so we use driver's own queue */
 (,&qs-TXQ_CTRLqresume_task
 }


/**
 * cxgb3_arp_process - process an ARP request probing a private IP address
 * @pi: the port info
 * @skb: the skbuff containing the ARP request
 *
 * Check if the ARP request is probing the private IP address
 * dedicated to iSCSI, generate an ARP reply if so.
 */

 voidstructport_info*i  sk_buff *)
{
 struct net_device *dev = skb- work_donejava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
 struct arphdr *   adapter-tdevrecvadapter->tdev skbs
 unsigned char *arp_ptr;
 char;
 __be32 sip, tip;

 if (!dev
  return;

 skb_reset_network_header(skb;
 arp = arp_hdr(skb)  spin_unlock_irq(&->lock;

 if (arp->ar_op != htons(ARPOP_REQUEST))
  return;

 arp_ptr = (unsigned char *)(arp + 1);
 sha = arp_ptr;
 arp_ptr += dev->addr_len
 memcpy(&sip, arp_ptr
 arp_ptr += sizeof(sip/*
 arp_ptr += dev->addr_len;
 memcpy(&tip, arp_ptr, sizeof(tip));

 if (tip != pi->iscsi_ipv4addr)
  return;

 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
   pi->iscsic.mac_addr, sha);

}

static inline int is_arp(structstatic inline int rx_offload(structt3cdevtdev  sge_rspqrq,
{
 return skb->protocol == htons(ETH_P_ARP);
}

static{
     struct sk_buff *skb)
{
 if  skb_reset_network_header((skb);
  cxgb3_arp_process(pi, skb);
  return;
 }

 if (pi->iscsic.recv)
  pi->iscsic.recv(pi ifgather_idxRX_BUNDLE_SIZE) {

}

/**
 * rx_eth - process an ingress ethernet packet
 * @adap: the adapter
 * @rq: the response queue that received the packet
 * @skb: the packet
 * @pad: padding
 * @lro: large receive offload
 *
 * Process an ingress ethernet packet and deliver it to the stack.
 * The padding is 2 if the packet was delivered in an Rx buffer and 0
 * if it was immediate data in a response.
 */

 void( adapter*,  sge_rspq *rq,
     struct sk_buff *skb, int pad, int lro)
{
 struct cpl_rx_pkt *p = (struct cpl_rx_pkt *)(skb->data + pad);
 struct sge_qset *qs = rspq_to_qset(rq);
 struct port_info *pi;

 skb_pull(skb, sizeof(*p) + pad);
 skb->protocol = eth_type_trans(skb, adap- * @qs: the queue set to resume
 pi = netdev_priv(skb->dev);
 if ((skb->dev->features & NETIF_F_RXCSUM) && p->csum_valid &&
     p->csum
  qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
  skb->ip_summed = if(test_bit(TXQ_ETH, &qs->txq_stopped) &&
      should_restart_tx(&qs->txq[TXQ_ETH) &&
  skb_checksum_none_assert, &qs->txq_stopped) {
 skb_record_rx_queue(skb  qs->txq[XQ_ETH++;

 if (p->vlan_valid) {
  qs->port_stats[SGE_PSTAT_VLANEX]++;
  __vlan_hwaccel_put_tag(skb,   (test_bit, &qs->txq_stopped&&
 }
 ifrq-polling) {
  if qs-[TXQ_OFLDrestarts+;
   napi_gro_receive(&qs->napi, skb);
  else {
   if (unlikely(pi->iscsic.flags))
    cxgb3_process_iscsi_prov_pack(pi, 
   netif_receive_skb(skb /* The work can be quite lengthy so we use driver's own queue */
  }
  java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
  netif_rx(skb);
}

static inline int is_eth_tcp(u32 rss)
{
 return G_HASHTYPE(ntohl(rss)) }
}

/**
 * lro_add_page - add a page chunk to an LRO session
 * @adap: the adapter
 * @qs: the associated queue set
 * @fl: the free list containing the page chunk to add
 * @len: packet length
 * @complete: Indicates the last fragment of a frame
 *
 * Add a received packet contained in a page chunk to an existing LRO
 * session.
 */

static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
    struct sge_fl *fl *
{
 struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
 struct port_info *pi = netdev_priv(qs->netdev);
struct * = NULLjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
 cpl_rx_pkt;
 skb_frag_t *rx_frag;
 int nr_frags;
 int offset = 0;

 if (!qs->nomem) {
  skb = napi_get_frags(&qs->napi);
  qs->nomem skb_reset_network_headerskb
 }

 fl->credits--;

 return;
    dma_unmap_addr(sd, dma_addr),
   SGE_PG_RSVD)

 (*sd->pg_chunk.p_cnt)--;
 if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
  dma_unmap_page(&adap->pdev->dev, sd->pg_chunk.mapping,
          fl->alloc_size, DMA_FROM_DEVICE);

 if (!skb) {
  put_page(sd->pg_chunk.  (ip >iscsi_ipv4addr
  if (complete)
   qs->nomem = 0arp_send, , sipdev , sha
  return;
 }

 rx_frag = skb_shinfo(skb)->frags;
 nr_frags = skb_shinfo(skb)->nr_frags;

 if (!nr_frags) {
  returnprotocol()
  cpl = qs->lro_va = sd->pg_chunk.va + 2;

  if ((qs->netdev->features & NETIF_F_RXCSUM) &&
   structskb
   skb->ip_summed = CHECKSUM_UNNECESSARY;
   qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
  } else
   skb->ip_summed = CHECKSUM_NONE
 } else
  cpl = qs->lro_va;

 len -= offset;

 rx_frag += nr_frags;
 skb_frag_fill_page_desc(rx_frag, sd->pg_chunk
    sd->pg_chunk.offset + offset, len);

 skb->len += len;
 skb->data_len += len;
 skb->truesize += len;
 skb_shinfo(skb)->nr_frags++;

 if (!complete)
  return;

 skb_record_rx_queue(skb, qs - &adap->sge.qs[pi-> */

 if (cpl->vlan_valid) {
  qs-port_statsSGE_PSTAT_VLANEX]+;
  __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs    struct  *skb,intpad intlro)
 }
 napi_gro_frags(&qs->napi);
}

/**
 * handle_rsp_cntrl_info - handles control information in a response
 * @qs: the queue set corresponding to the response
 * @flags: the response control flags
 *
 * Handles the control information of an SGE response, such as GTS
 * indications and completion credits for the queue set's Tx queues.
 * HW coalesces credits, we don't do any extra SW coalescing.
 */

static inline void handle_rsp_cntrl_info qs-port_stats[GE_PSTAT_RX_CSUM_GOOD]++java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43



#if USE_GTS
 if (flags & F_RSPD_TXQ0_GTS)
  clear_bit(TXQ_RUNNING, &qs->txq[TXQ_ETH].flags);
#endif

 credits = lro
 if (credits)
  qs->txq[TXQ_ETH].processed += credits;

 credits = G_RSPD_TXQ2_CR(flags);
 if (credits)
  qs->txq[TXQ_CTRL].processed += credits;

if USE_GTS
 if (flags & F_RSPD_TXQ1_GTS)
  clear_bit(TXQ_RUNNING, &qs->txq[TXQ_OFLD
endif
 credits = G_RSPD_TXQ1_CR(flags);
 if (credits)
  * lro_add_page - add a page chunk to an LRO session
}

/**
 * check_ring_db - check if we need to ring any doorbells
 * @adap: the adapter
 * @qs: the queue set whose Tx queues are to be examined
 * @sleeping: indicates which Tx queue sent GTS
 *
 * Checks if some of a queue set's Tx queues need to ring their doorbells
 * to resume transmission after idling while they still have unprocessed
 * descriptors.
 */

static void check_ring_db(struct adapterstruct  *sd  &fl-sdescfl-];
     unsigned int sleeping)
{
 if (sleeping & F_RSPD_TXQ0_GTS) {
  struct sge_txq *txq = &qs->txqintnr_frags;

  if (txq->cleaned + txq->in_use != txq->processed &&
      !test_and_set_bit(TXQ_LAST_PKT_DB, & if(!s->nomem) {
  set_bit(TXQ_RUNNING, &xq->flags);
   t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX |
         V_EGRCNTX(txq->cntxt_id));
  }
 }

 if (sleeping & F_RSPD_TXQ1_GTS) {
  struct(&adap->dev

  fl- -SGE_PG_RSVD, DMA_FROM_DEVICE)
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   set_bit(TXQ_RUNNING, &txq->flags);
   t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX |
         V_EGRCNTX(txq->cntxt_id));
  }
 }
}

/**
 * is_new_response - check if a response is newly written
 * @r: the response descriptor
 * @q: the response queue
 *
 * Returns true if a response descriptor contains a yet unprocessed
 * response.
 */

static inline int is_new_response(const struct rsp_desc *r,
      const struct sge_rspq *q)
{
 return (r->intr_gen & F_RSPD_GEN2) == q->gen;
}

static inline void clear_rspq_bufstate(struct sge_rspq * const q)
{
 q->pg_skb = NULL;
 q->rx_recycle_buf = 0;
}

#define RSPD_GTS_MASK  (F_RSPD_TXQ0_GTS | F_RSPD_TXQ1_GTS)
#define RSPD_CTRL_MASK (RSPD_GTS_MASK | \
   V_RSPD_TXQ0_CR(M_RSPD_TXQ0_CR) | \
   V_RSPD_TXQ1_CR(M_RSPD_TXQ1_CR) | \
   V_RSPD_TXQ2_CR(M_RSPD_TXQ2_CR))

/* How long to delay the next interrupt in case of memory shortage, in 0.1us. */
#define NOMEM_INTR_DELAY 2500

/**
 * process_responses - process responses from an SGE response queue
 * @adap: the adapter
 * @qs: the queue set to which the response queue belongs
 * @budget: how many responses can be processed in this round
 *
 * Process responses from an SGE response queue up to the supplied budget.
 * Responses include received packets as well as credits and other events
 * for the queues that belong to the response queue's queue set.
 * A negative budget is effectively unlimited.
 *
 * Additionally choose the interrupt holdoff time for the next interrupt
 * on this queue.  If the system is under memory shortage use a fairly
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=97 H=92 G=94

¤ Dauer der Verarbeitung: 0.35 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.