/* * 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 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>
/* * 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 */
};
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
};
/* * 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
};
/** * 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.
*/ staticinlinevoid refill_rspq(struct adapter *adapter, conststruct sge_rspq *q, unsignedint credits)
{
rmb();
t3_write_regadapter, A_SG_RSPQ_CREDIT_RETURN,
V_RSPQ(q- unsignedint , 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.
*/ staticinlinevoid unmap_skb(struct sk_buff *skb, struct sge_txq *q, unsigned
{ conststruct 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.
*/ staticvoid free_tx_desc(struct adapter *adapter, struct sge_txq * q- = 0 unsigned n)
{ struct tx_sw_desc *d; struct pci_dev unsignedint cidxjava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
constint 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.
*/ staticinlineunsignedint reclaim_completed_tx(struct adapter *adapter, struct sge_txq *q, unsignedint chunk)
{ unsignedint reclaim = 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.
*/ staticinlineint should_restart_tx(conststruct sge_txq *q)
{ unsignedint r = q->processed - q->cleaned;
/** * 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.
*/ staticvoid free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
{ unsignedint 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.
*/ staticinlineint add_one_rx_buf(void *va, unsignedint len, struct rx_desc *d, struct rx_sw_desc *sd, unsignedint 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, ))) returnwhile () {
(sd, );
d->addr_lo q->) {
d- = cpu_to_be32u64 mapping >32;
dma_wmb();
>order{
d-gen2cpu_to_be32V_FLD_GEN2gen) returnbreakjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
}struct* (q-buf_sizegfp
/** * 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.
*/ staticint 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]; unsignedint 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);
/** * 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.
*/ staticvoid recycle_rx_buf(struct adapter *adap, struct sge_fl *q, unsignedint idx)
{ struct rx_desc *from = &q->desc[idx]; struct rx_desc *to = &q->desc[q->pidx];
/** * 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.
*/ staticvoid *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);
/** * 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.
*/ staticvoid t3_reset_qset(struct sge_qset *q)
{ if (q->adap &&
!(q->adap->flags & NAPI_INIT)) {
memset(q, 0, sizeof(*q)); return;
}
/** * 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.
*/ staticvoid 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);
}
/** * 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.
*/ staticvoid init_qset_cntxt(struct sge_qset *qs, unsignedint 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.
*/ staticinlineunsignedint sgl_len(unsignedint 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.
*/ staticinlineunsignedint flits_to_desc(unsignedint 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.
*/ staticstruct sk_buff *get_packet(struct adapter *adap, struct sge_fl *fl, unsignedint len, unsignedint drop_thres)
{ struct sk_buff *skb = NULL; struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
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)
/** * 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);
} elseif (!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 = lenstaticinlineint( intn)
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.
*/ staticinline 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.
*/ staticinline
{ 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.
*/ staticint 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.
*/ staticinlineunsignedint write_sgl(const(sd-pg_chunkp_cnt)-java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25 struct sg_ent *gpunsigned *start, unsignedint len, const dma_addr_t *addr)
{ unsignedint i, j = 0 if (!skb) {
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.
*/ staticinlinevoid check_ring_tx_db
{ #if USE_GTS
clear_bit(TXQ_LAST_PKT_DB struct *get_imm_packet(conststruct 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
}
staticinlinevoid 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 conststruct sge_txq *q, conststruct * map the main body of an sk_buff and its page fragments, if any. unsignedint flitsunsignedint sgl_flits unsignedint 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 (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_sglunsignedintndescstruct 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 unsignedintgen struct *q unsignedintndesc, unsignedintcompl, const dma_addr_t *addr)
{ unsignedint 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) |
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
}
staticinlinestructport_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; conststruct 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);
}
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
}
}
/* 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_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.
*/ staticinlinevoid 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.
*/ staticinlineint check_desc_avail(struct adapter *adap, struct sge_txq *q, struct sk_buff unsignedint qid)
{ if (unlikely(!skb_queue_empty(&q- * packets arriving to run the destructors of completed packets,
addq_exit:__skb_queue_tail(&q->sendq * we donot 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);
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 unsignedint reclaim = q->processed - q->cleaned;
/** * 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.
*/ staticint 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;
}
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.
*/ staticvoid restart_ctrlq(struct work_struct *w)
{ structsk_buffskb; struct sge_qset *qs struct sk_buffskb, unsignedintndesc,
[TXQ_CTRL].resume_task; struct sge_txq *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; conststruct 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;
}
staticvoid setup_deferred_unmapping goto again conststruct 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
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
/** * 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.
*/ staticinlineunsignedint calc_tx_descs_ofld(conststruct sk_buff *skb)
{
igned int, 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.
*/ staticint ofld_xmit(struct adapter *adap, struct sge_txq *q, struct sk_buff *skb)
{ int ret; unsignedint 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
/** * restart_offloadq - restart a suspended offload queue * @w: pointer to the work associated with this handler * * Resumes transmission on a suspended Tx offload queue.
*/ staticvoid(&>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]; conststruct port_info *pi ); struct adapter *adap = pi->adapter; unsignedint written = 0;
/** * 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.
*/ int( struct *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.
*/ staticinlinereturnNET_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
/** * 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.
*/ staticinlinewhile ((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
/** * 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.
*/ staticinlinevoid 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.
*/ staticint ofld_poll(structreturn > 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;
/** * 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.
*/ staticintrx_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.
*/ staticvoid * 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);
}
/* 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 unsignedchar *arp_ptr; char;
__be32 sip, tip;
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);
}
/** * 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.
*/ staticvoid 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
}
/** * 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.
*/ staticinlinevoid 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.
*/ staticvoid check_ring_db(struct adapterstruct *sd &fl-sdescfl-]; unsignedint sleeping)
{ if (sleeping & F_RSPD_TXQ0_GTS) { struct sge_txq *txq = &qs->txqintnr_frags;
/* 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
¤ Dauer der Verarbeitung: 0.40 Sekunden
(vorverarbeitet)
¤
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.