linux/drivers/net/ethernet/chelsio/cxgb4/sge.c

/*
 * This file is part of the Chelsio T4 Ethernet driver for Linux.
 *
 * Copyright (c) 2003-2014 Chelsio Communications, 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.
 */

#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/dma-mapping.h>
#include <linux/jiffies.h>
#include <linux/prefetch.h>
#include <linux/export.h>
#include <net/xfrm.h>
#include <net/ipv6.h>
#include <net/tcp.h>
#include <net/busy_poll.h>
#ifdef CONFIG_CHELSIO_T4_FCOE
#include <scsi/fc/fc_fcoe.h>
#endif /* CONFIG_CHELSIO_T4_FCOE */
#include "cxgb4.h"
#include "t4_regs.h"
#include "t4_values.h"
#include "t4_msg.h"
#include "t4fw_api.h"
#include "cxgb4_ptp.h"
#include "cxgb4_uld.h"
#include "cxgb4_tc_mqprio.h"
#include "sched.h"

/*
 * Rx buffer size.  We use largish buffers if possible but settle for single
 * pages under memory shortage.
 */
#if PAGE_SHIFT >= 16
#define FL_PG_ORDER
#else
#define FL_PG_ORDER
#endif

/* RX_PULL_LEN should be <= RX_COPY_THRES */
#define RX_COPY_THRES
#define RX_PULL_LEN

/*
 * Main body length for sk_buffs used for Rx Ethernet packets with fragments.
 * Should be >= RX_PULL_LEN but possibly bigger to give pskb_may_pull some room.
 */
#define RX_PKT_SKB_LEN

/*
 * Max number of Tx descriptors we clean up at a time.  Should be modest as
 * freeing skbs isn't cheap and it happens while holding locks.  We just need
 * to free packets faster than they arrive, we eventually catch up and keep
 * the amortized cost reasonable.  Must be >= 2 * TXQ_STOP_THRES.  It should
 * also match the CIDX Flush Threshold.
 */
#define MAX_TX_RECLAIM

/*
 * Max number of Rx buffers we replenish at a time.  Again keep this modest,
 * allocating buffers isn't cheap either.
 */
#define MAX_RX_REFILL

/*
 * Period of the Rx queue check timer.  This timer is infrequent as it has
 * something to do only when the system experiences severe memory shortage.
 */
#define RX_QCHECK_PERIOD

/*
 * Period of the Tx queue check timer.
 */
#define TX_QCHECK_PERIOD

/*
 * Max number of Tx descriptors to be reclaimed by the Tx timer.
 */
#define MAX_TIMER_TX_RECLAIM

/*
 * Timer index used when backing off due to memory shortage.
 */
#define NOMEM_TMR_IDX

/*
 * Suspension threshold for non-Ethernet Tx queues.  We require enough room
 * for a full sized WR.
 */
#define TXQ_STOP_THRES

/*
 * Max Tx descriptor space we allow for an Ethernet packet to be inlined
 * into a WR.
 */
#define MAX_IMM_TX_PKT_LEN

/*
 * Max size of a WR sent through a control Tx queue.
 */
#define MAX_CTRL_WR_LEN

struct rx_sw_desc {};

/*
 * Rx buffer sizes for "useskbs" Free List buffers (one ingress packet pe skb
 * buffer).  We currently only support two sizes for 1500- and 9000-byte MTUs.
 * We could easily support more but there doesn't seem to be much need for
 * that ...
 */
#define FL_MTU_SMALL
#define FL_MTU_LARGE

static inline unsigned int fl_mtu_bufsize(struct adapter *adapter,
					  unsigned int mtu)
{}

#define FL_MTU_SMALL_BUFSIZE(adapter)
#define FL_MTU_LARGE_BUFSIZE(adapter)

/*
 * Bits 0..3 of rx_sw_desc.dma_addr have special meaning.  The hardware uses
 * these to specify the buffer size as an index into the SGE Free List Buffer
 * Size register array.  We also use bit 4, when the buffer has been unmapped
 * for DMA, but this is of course never sent to the hardware and is only used
 * to prevent double unmappings.  All of the above requires that the Free List
 * Buffers which we allocate have the bottom 5 bits free (0) -- i.e. are
 * 32-byte or or a power of 2 greater in alignment.  Since the SGE's minimal
 * Free List Buffer alignment is 32 bytes, this works out for us ...
 */
enum {};

static int timer_pkt_quota[] =;
#define MIN_NAPI_WORK

static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *d)
{}

static inline bool is_buf_mapped(const struct rx_sw_desc *d)
{}

/**
 *	txq_avail - return the number of available slots in a Tx queue
 *	@q: the Tx queue
 *
 *	Returns the number of descriptors in a Tx queue available to write new
 *	packets.
 */
static inline unsigned int txq_avail(const struct sge_txq *q)
{}

/**
 *	fl_cap - return the capacity of a free-buffer list
 *	@fl: the FL
 *
 *	Returns the capacity of a free-buffer list.  The capacity is less than
 *	the size because one descriptor needs to be left unpopulated, otherwise
 *	HW will think the FL is empty.
 */
static inline unsigned int fl_cap(const struct sge_fl *fl)
{}

/**
 *	fl_starving - return whether a Free List is starving.
 *	@adapter: pointer to the adapter
 *	@fl: the Free List
 *
 *	Tests specified Free List to see whether the number of buffers
 *	available to the hardware has falled below our "starvation"
 *	threshold.
 */
static inline bool fl_starving(const struct adapter *adapter,
			       const struct sge_fl *fl)
{}

int cxgb4_map_skb(struct device *dev, const struct sk_buff *skb,
		  dma_addr_t *addr)
{}
EXPORT_SYMBOL();

static void unmap_skb(struct device *dev, const struct sk_buff *skb,
		      const dma_addr_t *addr)
{}

#ifdef CONFIG_NEED_DMA_MAP_STATE
/**
 *	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 void deferred_unmap_destructor(struct sk_buff *skb)
{}
#endif

/**
 *	free_tx_desc - reclaims Tx descriptors and their buffers
 *	@adap: the adapter
 *	@q: the Tx queue to reclaim descriptors from
 *	@n: the number of descriptors to reclaim
 *	@unmap: whether the buffers should be unmapped for DMA
 *
 *	Reclaims Tx descriptors from an SGE Tx queue and frees the associated
 *	Tx buffers.  Called with the Tx queue lock held.
 */
void free_tx_desc(struct adapter *adap, struct sge_txq *q,
		  unsigned int n, bool unmap)
{}

/*
 * Return the number of reclaimable descriptors in a Tx queue.
 */
static inline int reclaimable(const struct sge_txq *q)
{}

/**
 *	reclaim_completed_tx - reclaims completed TX Descriptors
 *	@adap: the adapter
 *	@q: the Tx queue to reclaim completed descriptors from
 *	@maxreclaim: the maximum number of TX Descriptors to reclaim or -1
 *	@unmap: whether the buffers should be unmapped for DMA
 *
 *	Reclaims Tx Descriptors that the SGE has indicated it has processed,
 *	and frees the associated buffers if possible.  If @max == -1, then
 *	we'll use a defaiult maximum.  Called with the TX Queue locked.
 */
static inline int reclaim_completed_tx(struct adapter *adap, struct sge_txq *q,
				       int maxreclaim, bool unmap)
{}

/**
 *	cxgb4_reclaim_completed_tx - reclaims completed Tx descriptors
 *	@adap: the adapter
 *	@q: the Tx queue to reclaim completed descriptors from
 *	@unmap: whether the buffers should be unmapped for DMA
 *
 *	Reclaims Tx descriptors that the SGE has indicated it has processed,
 *	and frees the associated buffers if possible.  Called with the Tx
 *	queue locked.
 */
void cxgb4_reclaim_completed_tx(struct adapter *adap, struct sge_txq *q,
				bool unmap)
{}
EXPORT_SYMBOL();

static inline int get_buf_size(struct adapter *adapter,
			       const struct rx_sw_desc *d)
{}

/**
 *	free_rx_bufs - free the Rx buffers on an SGE free list
 *	@adap: the adapter
 *	@q: the SGE free list to free buffers from
 *	@n: how many buffers to free
 *
 *	Release the next @n buffers on an SGE free-buffer Rx queue.   The
 *	buffers must be made inaccessible to HW before calling this function.
 */
static void free_rx_bufs(struct adapter *adap, struct sge_fl *q, int n)
{}

/**
 *	unmap_rx_buf - unmap the current Rx buffer on an SGE free list
 *	@adap: the adapter
 *	@q: the SGE free list
 *
 *	Unmap the current buffer on an SGE free-buffer Rx queue.   The
 *	buffer must be made inaccessible to HW before calling this function.
 *
 *	This is similar to @free_rx_bufs above but does not free the buffer.
 *	Do note that the FL still loses any further access to the buffer.
 */
static void unmap_rx_buf(struct adapter *adap, struct sge_fl *q)
{}

static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
{}

static inline void set_rx_sw_desc(struct rx_sw_desc *sd, struct page *pg,
				  dma_addr_t mapping)
{}

/**
 *	refill_fl - refill an SGE Rx buffer ring
 *	@adap: the adapter
 *	@q: the ring to refill
 *	@n: the number of new buffers to allocate
 *	@gfp: the gfp flags for the allocations
 *
 *	(Re)populate an SGE free-buffer queue 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.  If afterwards the queue is
 *	found critically low mark it as starving in the bitmap of starving FLs.
 *
 *	Returns the number of buffers allocated.
 */
static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n,
			      gfp_t gfp)
{}

static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
{}

/**
 *	alloc_ring - allocate resources for an SGE descriptor ring
 *	@dev: the PCI device's core 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
 *	@stat_size: extra space in HW ring for status information
 *	@node: preferred node for memory allocations
 *
 *	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 bus address of the HW ring, and the address
 *	of the SW ring.
 */
static void *alloc_ring(struct device *dev, size_t nelem, size_t elem_size,
			size_t sw_size, dma_addr_t *phys, void *metadata,
			size_t stat_size, int node)
{}

/**
 *	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)
{}

/**
 *	flits_to_desc - returns the num of Tx descriptors for the given flits
 *	@n: the number of flits
 *
 *	Returns the number of Tx descriptors needed for the supplied number
 *	of flits.
 */
static inline unsigned int flits_to_desc(unsigned int n)
{}

/**
 *	is_eth_imm - can an Ethernet packet be sent as immediate data?
 *	@skb: the packet
 *	@chip_ver: chip version
 *
 *	Returns whether an Ethernet packet is small enough to fit as
 *	immediate data. Return value corresponds to headroom required.
 */
static inline int is_eth_imm(const struct sk_buff *skb, unsigned int chip_ver)
{}

/**
 *	calc_tx_flits - calculate the number of flits for a packet Tx WR
 *	@skb: the packet
 *	@chip_ver: chip version
 *
 *	Returns the number of flits needed for a Tx WR for the given Ethernet
 *	packet, including the needed WR and CPL headers.
 */
static inline unsigned int calc_tx_flits(const struct sk_buff *skb,
					 unsigned int chip_ver)
{}

/**
 *	cxgb4_write_sgl - populate a scatter/gather list for a packet
 *	@skb: the packet
 *	@q: the Tx queue we are writing into
 *	@sgl: starting location for writing the SGL
 *	@end: points right after the end of the SGL
 *	@start: start offset into skb main-body data to include in the SGL
 *	@addr: the list of bus addresses for the SGL elements
 *
 *	Generates a gather list for the buffers that make up a packet.
 *	The caller must provide adequate space for the SGL that will be written.
 *	The SGL includes all of the packet's page fragments and the data in its
 *	main body except for the first @start bytes.  @sgl must be 16-byte
 *	aligned and within a Tx descriptor with available space.  @end points
 *	right after the end of the SGL but does not account for any potential
 *	wrap around, i.e., @end > @sgl.
 */
void cxgb4_write_sgl(const struct sk_buff *skb, struct sge_txq *q,
		     struct ulptx_sgl *sgl, u64 *end, unsigned int start,
		     const dma_addr_t *addr)
{}
EXPORT_SYMBOL();

/*	cxgb4_write_partial_sgl - populate SGL for partial packet
 *	@skb: the packet
 *	@q: the Tx queue we are writing into
 *	@sgl: starting location for writing the SGL
 *	@end: points right after the end of the SGL
 *	@addr: the list of bus addresses for the SGL elements
 *	@start: start offset in the SKB where partial data starts
 *	@len: length of data from @start to send out
 *
 *	This API will handle sending out partial data of a skb if required.
 *	Unlike cxgb4_write_sgl, @start can be any offset into the skb data,
 *	and @len will decide how much data after @start offset to send out.
 */
void cxgb4_write_partial_sgl(const struct sk_buff *skb, struct sge_txq *q,
			     struct ulptx_sgl *sgl, u64 *end,
			     const dma_addr_t *addr, u32 start, u32 len)
{}
EXPORT_SYMBOL();

/* This function copies 64 byte coalesced work request to
 * memory mapped BAR2 space. For coalesced WR SGE fetches
 * data from the FIFO instead of from Host.
 */
static void cxgb_pio_copy(u64 __iomem *dst, u64 *src)
{}

/**
 *	cxgb4_ring_tx_db - check and potentially ring a Tx queue's doorbell
 *	@adap: the adapter
 *	@q: the Tx queue
 *	@n: number of new descriptors to give to HW
 *
 *	Ring the doorbel for a Tx queue.
 */
inline void cxgb4_ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
{}
EXPORT_SYMBOL();

/**
 *	cxgb4_inline_tx_skb - inline a packet's data into Tx descriptors
 *	@skb: the packet
 *	@q: the Tx queue where the packet will be inlined
 *	@pos: starting position in the Tx queue where to inline the packet
 *
 *	Inline a packet's contents directly into Tx descriptors, starting at
 *	the given position within the Tx DMA ring.
 *	Most of the complexity of this operation is dealing with wrap arounds
 *	in the middle of the packet we want to inline.
 */
void cxgb4_inline_tx_skb(const struct sk_buff *skb,
			 const struct sge_txq *q, void *pos)
{}
EXPORT_SYMBOL();

static void *inline_tx_skb_header(const struct sk_buff *skb,
				  const struct sge_txq *q,  void *pos,
				  int length)
{}

/*
 * Figure out what HW csum a packet wants and return the appropriate control
 * bits.
 */
static u64 hwcsum(enum chip_type chip, const struct sk_buff *skb)
{}

static void eth_txq_stop(struct sge_eth_txq *q)
{}

static inline void txq_advance(struct sge_txq *q, unsigned int n)
{}

#ifdef CONFIG_CHELSIO_T4_FCOE
static inline int
cxgb_fcoe_offload(struct sk_buff *skb, struct adapter *adap,
		  const struct port_info *pi, u64 *cntrl)
{}
#endif /* CONFIG_CHELSIO_T4_FCOE */

/* Returns tunnel type if hardware supports offloading of the same.
 * It is called only for T5 and onwards.
 */
enum cpl_tx_tnl_lso_type cxgb_encap_offload_supported(struct sk_buff *skb)
{}

static inline void t6_fill_tnl_lso(struct sk_buff *skb,
				   struct cpl_tx_tnl_lso *tnl_lso,
				   enum cpl_tx_tnl_lso_type tnl_type)
{}

static inline void *write_tso_wr(struct adapter *adap, struct sk_buff *skb,
				 struct cpl_tx_pkt_lso_core *lso)
{}

/**
 *	t4_sge_eth_txq_egress_update - handle Ethernet TX Queue update
 *	@adap: the adapter
 *	@eq: the Ethernet TX Queue
 *	@maxreclaim: the maximum number of TX Descriptors to reclaim or -1
 *
 *	We're typically called here to update the state of an Ethernet TX
 *	Queue with respect to the hardware's progress in consuming the TX
 *	Work Requests that we've put on that Egress Queue.  This happens
 *	when we get Egress Queue Update messages and also prophylactically
 *	in regular timer-based Ethernet TX Queue maintenance.
 */
int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq,
				 int maxreclaim)
{}

static inline int cxgb4_validate_skb(struct sk_buff *skb,
				     struct net_device *dev,
				     u32 min_pkt_len)
{}

static void *write_eo_udp_wr(struct sk_buff *skb, struct fw_eth_tx_eo_wr *wr,
			     u32 hdr_len)
{}

/**
 *	cxgb4_eth_xmit - add a packet to an Ethernet Tx queue
 *	@skb: the packet
 *	@dev: the egress net device
 *
 *	Add a packet to an SGE Ethernet Tx queue.  Runs with softirqs disabled.
 */
static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
{}

/* Constants ... */
enum {};

/**
 *	t4vf_is_eth_imm - can an Ethernet packet be sent as immediate data?
 *	@skb: the packet
 *
 *	Returns whether an Ethernet packet is small enough to fit completely as
 *	immediate data.
 */
static inline int t4vf_is_eth_imm(const struct sk_buff *skb)
{}

/**
 *	t4vf_calc_tx_flits - calculate the number of flits for a packet TX WR
 *	@skb: the packet
 *
 *	Returns the number of flits needed for a TX Work Request for the
 *	given Ethernet packet, including the needed WR and CPL headers.
 */
static inline unsigned int t4vf_calc_tx_flits(const struct sk_buff *skb)
{}

/**
 *	cxgb4_vf_eth_xmit - add a packet to an Ethernet TX queue
 *	@skb: the packet
 *	@dev: the egress net device
 *
 *	Add a packet to an SGE Ethernet TX queue.  Runs with softirqs disabled.
 */
static netdev_tx_t cxgb4_vf_eth_xmit(struct sk_buff *skb,
				     struct net_device *dev)
{}

/**
 * reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
 * @q: the SGE control Tx queue
 *
 * This is a variant of cxgb4_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 inline void reclaim_completed_tx_imm(struct sge_txq *q)
{}

static inline void eosw_txq_advance_index(u32 *idx, u32 n, u32 max)
{}

void cxgb4_eosw_txq_free_desc(struct adapter *adap,
			      struct sge_eosw_txq *eosw_txq, u32 ndesc)
{}

static inline void eosw_txq_advance(struct sge_eosw_txq *eosw_txq, u32 n)
{}

static inline int eosw_txq_enqueue(struct sge_eosw_txq *eosw_txq,
				   struct sk_buff *skb)
{}

static inline struct sk_buff *eosw_txq_peek(struct sge_eosw_txq *eosw_txq)
{}

static inline u8 ethofld_calc_tx_flits(struct adapter *adap,
				       struct sk_buff *skb, u32 hdr_len)
{}

static void *write_eo_wr(struct adapter *adap, struct sge_eosw_txq *eosw_txq,
			 struct sk_buff *skb, struct fw_eth_tx_eo_wr *wr,
			 u32 hdr_len, u32 wrlen)
{}

static int ethofld_hard_xmit(struct net_device *dev,
			     struct sge_eosw_txq *eosw_txq)
{}

static void ethofld_xmit(struct net_device *dev, struct sge_eosw_txq *eosw_txq)
{}

static netdev_tx_t cxgb4_ethofld_xmit(struct sk_buff *skb,
				      struct net_device *dev)
{}

netdev_tx_t t4_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static void eosw_txq_flush_pending_skbs(struct sge_eosw_txq *eosw_txq)
{}

/**
 * cxgb4_ethofld_send_flowc - Send ETHOFLD flowc request to bind eotid to tc.
 * @dev: netdevice
 * @eotid: ETHOFLD tid to bind/unbind
 * @tc: traffic class. If set to FW_SCHED_CLS_NONE, then unbinds the @eotid
 *
 * Send a FLOWC work request to bind an ETHOFLD TID to a traffic class.
 * If @tc is set to FW_SCHED_CLS_NONE, then the @eotid is unbound from
 * a traffic class.
 */
int cxgb4_ethofld_send_flowc(struct net_device *dev, u32 eotid, u32 tc)
{}

/**
 *	is_imm - check whether a packet can be sent as immediate data
 *	@skb: the packet
 *
 *	Returns true if a packet can be sent as a WR with immediate data.
 */
static inline int is_imm(const struct sk_buff *skb)
{}

/**
 *	ctrlq_check_stop - check if a control queue is full and should stop
 *	@q: the queue
 *	@wr: most recent WR written to the queue
 *
 *	Check if a control queue has become full and should be stopped.
 *	We clean up control queue descriptors very lazily, only when we are out.
 *	If the queue is still full after reclaiming any completed descriptors
 *	we suspend it and have the last WR wake it up.
 */
static void ctrlq_check_stop(struct sge_ctrl_txq *q, struct fw_wr_hdr *wr)
{}

#define CXGB4_SELFTEST_LB_STR

int cxgb4_selftest_lb_pkt(struct net_device *netdev)
{}

/**
 *	ctrl_xmit - send a packet through an SGE control Tx queue
 *	@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.
 */
static int ctrl_xmit(struct sge_ctrl_txq *q, struct sk_buff *skb)
{}

/**
 *	restart_ctrlq - restart a suspended control queue
 *	@t: pointer to the tasklet associated with this handler
 *
 *	Resumes transmission on a suspended Tx control queue.
 */
static void restart_ctrlq(struct tasklet_struct *t)
{}

/**
 *	t4_mgmt_tx - send a management message
 *	@adap: the adapter
 *	@skb: the packet containing the management message
 *
 *	Send a management message through control queue 0.
 */
int t4_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
{}

/**
 *	is_ofld_imm - check whether a packet can be sent as immediate data
 *	@skb: the packet
 *
 *	Returns true if a packet can be sent as an offload WR with immediate
 *	data.
 *	FW_OFLD_TX_DATA_WR limits the payload to 255 bytes due to 8-bit field.
 *      However, FW_ULPTX_WR commands have a 256 byte immediate only
 *      payload limit.
 */
static inline int is_ofld_imm(const struct sk_buff *skb)
{}

/**
 *	calc_tx_flits_ofld - calculate # of flits for an offload packet
 *	@skb: the packet
 *
 *	Returns the number of flits needed for the given offload packet.
 *	These packets are already fully constructed and no additional headers
 *	will be added.
 */
static inline unsigned int calc_tx_flits_ofld(const struct sk_buff *skb)
{}

/**
 *	txq_stop_maperr - stop a Tx queue due to I/O MMU exhaustion
 *	@q: the queue to stop
 *
 *	Mark a Tx queue stopped due to I/O MMU exhaustion and resulting
 *	inability to map packets.  A periodic timer attempts to restart
 *	queues so marked.
 */
static void txq_stop_maperr(struct sge_uld_txq *q)
{}

/**
 *	ofldtxq_stop - stop an offload Tx queue that has become full
 *	@q: the queue to stop
 *	@wr: the Work Request causing the queue to become full
 *
 *	Stops an offload Tx queue that has become full and modifies the packet
 *	being written to request a wakeup.
 */
static void ofldtxq_stop(struct sge_uld_txq *q, struct fw_wr_hdr *wr)
{}

/**
 *	service_ofldq - service/restart a suspended offload queue
 *	@q: the offload queue
 *
 *	Services an offload Tx queue by moving packets from its Pending Send
 *	Queue to the Hardware TX ring.  The function starts and ends with the
 *	Send Queue locked, but drops the lock while putting the skb at the
 *	head of the Send Queue onto the Hardware TX Ring.  Dropping the lock
 *	allows more skbs to be added to the Send Queue by other threads.
 *	The packet being processed at the head of the Pending Send Queue is
 *	left on the queue in case we experience DMA Mapping errors, etc.
 *	and need to give up and restart later.
 *
 *	service_ofldq() can be thought of as a task which opportunistically
 *	uses other threads execution contexts.  We use the Offload Queue
 *	boolean "service_ofldq_running" to make sure that only one instance
 *	is ever running at a time ...
 */
static void service_ofldq(struct sge_uld_txq *q)
	__must_hold(&q->sendq.lock)
{}

/**
 *	ofld_xmit - send a packet through an offload queue
 *	@q: the Tx offload queue
 *	@skb: the packet
 *
 *	Send an offload packet through an SGE offload queue.
 */
static int ofld_xmit(struct sge_uld_txq *q, struct sk_buff *skb)
{}

/**
 *	restart_ofldq - restart a suspended offload queue
 *	@t: pointer to the tasklet associated with this handler
 *
 *	Resumes transmission on a suspended Tx offload queue.
 */
static void restart_ofldq(struct tasklet_struct *t)
{}

/**
 *	skb_txq - return the Tx queue an offload packet should use
 *	@skb: the packet
 *
 *	Returns the Tx queue an offload packet should use as indicated by bits
 *	1-15 in the packet's queue_mapping.
 */
static inline unsigned int skb_txq(const struct sk_buff *skb)
{}

/**
 *	is_ctrl_pkt - return whether an offload packet is a control packet
 *	@skb: the packet
 *
 *	Returns whether an offload packet should use an OFLD or a CTRL
 *	Tx queue as indicated by bit 0 in the packet's queue_mapping.
 */
static inline unsigned int is_ctrl_pkt(const struct sk_buff *skb)
{}

static inline int uld_send(struct adapter *adap, struct sk_buff *skb,
			   unsigned int tx_uld_type)
{}

/**
 *	t4_ofld_send - send an offload packet
 *	@adap: the adapter
 *	@skb: the packet
 *
 *	Sends an offload packet.  We use the packet queue_mapping to select the
 *	appropriate Tx queue as follows: bit 0 indicates whether the packet
 *	should be sent as regular or control, bits 1-15 select the queue.
 */
int t4_ofld_send(struct adapter *adap, struct sk_buff *skb)
{}

/**
 *	cxgb4_ofld_send - send an offload packet
 *	@dev: the net device
 *	@skb: the packet
 *
 *	Sends an offload packet.  This is an exported version of @t4_ofld_send,
 *	intended for ULDs.
 */
int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb)
{}
EXPORT_SYMBOL();

static void *inline_tx_header(const void *src,
			      const struct sge_txq *q,
			      void *pos, int length)
{}

/**
 *      ofld_xmit_direct - copy a WR into offload queue
 *      @q: the Tx offload queue
 *      @src: location of WR
 *      @len: WR length
 *
 *      Copy an immediate WR into an uncontended SGE offload queue.
 */
static int ofld_xmit_direct(struct sge_uld_txq *q, const void *src,
			    unsigned int len)
{}

int cxgb4_immdata_send(struct net_device *dev, unsigned int idx,
		       const void *src, unsigned int len)
{}
EXPORT_SYMBOL();

/**
 *	t4_crypto_send - send crypto packet
 *	@adap: the adapter
 *	@skb: the packet
 *
 *	Sends crypto packet.  We use the packet queue_mapping to select the
 *	appropriate Tx queue as follows: bit 0 indicates whether the packet
 *	should be sent as regular or control, bits 1-15 select the queue.
 */
static int t4_crypto_send(struct adapter *adap, struct sk_buff *skb)
{}

/**
 *	cxgb4_crypto_send - send crypto packet
 *	@dev: the net device
 *	@skb: the packet
 *
 *	Sends crypto packet.  This is an exported version of @t4_crypto_send,
 *	intended for ULDs.
 */
int cxgb4_crypto_send(struct net_device *dev, struct sk_buff *skb)
{}
EXPORT_SYMBOL();

static inline void copy_frags(struct sk_buff *skb,
			      const struct pkt_gl *gl, unsigned int offset)
{}

/**
 *	cxgb4_pktgl_to_skb - build an sk_buff from a packet gather list
 *	@gl: the gather list
 *	@skb_len: size of sk_buff main body if it carries fragments
 *	@pull_len: amount of data to move to the sk_buff's main body
 *
 *	Builds an sk_buff from the given packet gather list.  Returns the
 *	sk_buff or %NULL if sk_buff allocation failed.
 */
struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
				   unsigned int skb_len, unsigned int pull_len)
{}
EXPORT_SYMBOL();

/**
 *	t4_pktgl_free - free a packet gather list
 *	@gl: the gather list
 *
 *	Releases the pages of a packet gather list.  We do not own the last
 *	page on the list and do not free it.
 */
static void t4_pktgl_free(const struct pkt_gl *gl)
{}

/*
 * Process an MPS trace packet.  Give it an unused protocol number so it won't
 * be delivered to anyone and send it to the stack for capture.
 */
static noinline int handle_trace_pkt(struct adapter *adap,
				     const struct pkt_gl *gl)
{}

/**
 * cxgb4_sgetim_to_hwtstamp - convert sge time stamp to hw time stamp
 * @adap: the adapter
 * @hwtstamps: time stamp structure to update
 * @sgetstamp: 60bit iqe timestamp
 *
 * Every ingress queue entry has the 60-bit timestamp, convert that timestamp
 * which is in Core Clock ticks into ktime_t and assign it
 **/
static void cxgb4_sgetim_to_hwtstamp(struct adapter *adap,
				     struct skb_shared_hwtstamps *hwtstamps,
				     u64 sgetstamp)
{}

static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
		   const struct cpl_rx_pkt *pkt, unsigned long tnl_hdr_len)
{}

enum {};

/**
 *     t4_systim_to_hwstamp - read hardware time stamp
 *     @adapter: the adapter
 *     @skb: the packet
 *
 *     Read Time Stamp from MPS packet and insert in skb which
 *     is forwarded to PTP application
 */
static noinline int t4_systim_to_hwstamp(struct adapter *adapter,
					 struct sk_buff *skb)
{}

/**
 *     t4_rx_hststamp - Recv PTP Event Message
 *     @adapter: the adapter
 *     @rsp: the response queue descriptor holding the RX_PKT message
 *     @rxq: the response queue holding the RX_PKT message
 *     @skb: the packet
 *
 *     PTP enabled and MPS packet, read HW timestamp
 */
static int t4_rx_hststamp(struct adapter *adapter, const __be64 *rsp,
			  struct sge_eth_rxq *rxq, struct sk_buff *skb)
{}

/**
 *      t4_tx_hststamp - Loopback PTP Transmit Event Message
 *      @adapter: the adapter
 *      @skb: the packet
 *      @dev: the ingress net device
 *
 *      Read hardware timestamp for the loopback PTP Tx event message
 */
static int t4_tx_hststamp(struct adapter *adapter, struct sk_buff *skb,
			  struct net_device *dev)
{}

/**
 *	t4_tx_completion_handler - handle CPL_SGE_EGR_UPDATE messages
 *	@rspq: Ethernet RX Response Queue associated with Ethernet TX Queue
 *	@rsp: Response Entry pointer into Response Queue
 *	@gl: Gather List pointer
 *
 *	For adapters which support the SGE Doorbell Queue Timer facility,
 *	we configure the Ethernet TX Queues to send CIDX Updates to the
 *	Associated Ethernet RX Response Queue with CPL_SGE_EGR_UPDATE
 *	messages.  This adds a small load to PCIe Link RX bandwidth and,
 *	potentially, higher CPU Interrupt load, but allows us to respond
 *	much more quickly to the CIDX Updates.  This is important for
 *	Upper Layer Software which isn't willing to have a large amount
 *	of TX Data outstanding before receiving DMA Completions.
 */
static void t4_tx_completion_handler(struct sge_rspq *rspq,
				     const __be64 *rsp,
				     const struct pkt_gl *gl)
{}

static int cxgb4_validate_lb_pkt(struct port_info *pi, const struct pkt_gl *si)
{}

/**
 *	t4_ethrx_handler - process an ingress ethernet packet
 *	@q: the response queue that received the packet
 *	@rsp: the response queue descriptor holding the RX_PKT message
 *	@si: the gather list of packet fragments
 *
 *	Process an ingress ethernet packet and deliver it to the stack.
 */
int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
		     const struct pkt_gl *si)
{}

/**
 *	restore_rx_bufs - put back a packet's Rx buffers
 *	@si: the packet gather list
 *	@q: the SGE free list
 *	@frags: number of FL buffers to restore
 *
 *	Puts back on an FL the Rx buffers associated with @si.  The buffers
 *	have already been unmapped and are left unmapped, we mark them so to
 *	prevent further unmapping attempts.
 *
 *	This function undoes a series of @unmap_rx_buf calls when we find out
 *	that the current packet can't be processed right away afterall and we
 *	need to come back to it later.  This is a very rare event and there's
 *	no effort to make this particularly efficient.
 */
static void restore_rx_bufs(const struct pkt_gl *si, struct sge_fl *q,
			    int frags)
{}

/**
 *	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 bool is_new_response(const struct rsp_ctrl *r,
				   const struct sge_rspq *q)
{}

/**
 *	rspq_next - advance to the next entry in a response queue
 *	@q: the queue
 *
 *	Updates the state of a response queue to advance it to the next entry.
 */
static inline void rspq_next(struct sge_rspq *q)
{}

/**
 *	process_responses - process responses from an SGE response queue
 *	@q: the ingress queue to process
 *	@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 control messages from FW
 *	or HW.
 *
 *	Additionally choose the interrupt holdoff time for the next interrupt
 *	on this queue.  If the system is under memory shortage use a fairly
 *	long delay to help recovery.
 */
static int process_responses(struct sge_rspq *q, int budget)
{}

/**
 *	napi_rx_handler - the NAPI handler for Rx processing
 *	@napi: the napi instance
 *	@budget: how many packets we can process in this round
 *
 *	Handler for new data events when using NAPI.  This does not need any
 *	locking or protection from interrupts as data interrupts are off at
 *	this point and other adapter interrupts do not interfere (the latter
 *	in not a concern at all with MSI-X as non-data interrupts then have
 *	a separate handler).
 */
static int napi_rx_handler(struct napi_struct *napi, int budget)
{}

void cxgb4_ethofld_restart(struct tasklet_struct *t)
{}

/* cxgb4_ethofld_rx_handler - Process ETHOFLD Tx completions
 * @q: the response queue that received the packet
 * @rsp: the response queue descriptor holding the CPL message
 * @si: the gather list of packet fragments
 *
 * Process a ETHOFLD Tx completion. Increment the cidx here, but
 * free up the descriptors in a tasklet later.
 */
int cxgb4_ethofld_rx_handler(struct sge_rspq *q, const __be64 *rsp,
			     const struct pkt_gl *si)
{}

/*
 * The MSI-X interrupt handler for an SGE response queue.
 */
irqreturn_t t4_sge_intr_msix(int irq, void *cookie)
{}

/*
 * Process the indirect interrupt entries in the interrupt queue and kick off
 * NAPI for each queue that has generated an entry.
 */
static unsigned int process_intrq(struct adapter *adap)
{}

/*
 * The MSI interrupt handler, which handles data events from SGE response queues
 * as well as error and other async events as they all use the same MSI vector.
 */
static irqreturn_t t4_intr_msi(int irq, void *cookie)
{}

/*
 * Interrupt handler for legacy INTx interrupts.
 * Handles data events from SGE response queues as well as error and other
 * async events as they all use the same interrupt line.
 */
static irqreturn_t t4_intr_intx(int irq, void *cookie)
{}

/**
 *	t4_intr_handler - select the top-level interrupt handler
 *	@adap: the adapter
 *
 *	Selects the top-level interrupt handler based on the type of interrupts
 *	(MSI-X, MSI, or INTx).
 */
irq_handler_t t4_intr_handler(struct adapter *adap)
{}

static void sge_rx_timer_cb(struct timer_list *t)
{}

static void sge_tx_timer_cb(struct timer_list *t)
{}

/**
 *	bar2_address - return the BAR2 address for an SGE Queue's Registers
 *	@adapter: the adapter
 *	@qid: the SGE Queue ID
 *	@qtype: the SGE Queue Type (Egress or Ingress)
 *	@pbar2_qid: BAR2 Queue ID or 0 for Queue ID inferred SGE Queues
 *
 *	Returns the BAR2 address for the SGE Queue Registers associated with
 *	@qid.  If BAR2 SGE Registers aren't available, returns NULL.  Also
 *	returns the BAR2 Queue ID to be used with writes to the BAR2 SGE
 *	Queue Registers.  If the BAR2 Queue ID is 0, then "Inferred Queue ID"
 *	Registers are supported (e.g. the Write Combining Doorbell Buffer).
 */
static void __iomem *bar2_address(struct adapter *adapter,
				  unsigned int qid,
				  enum t4_bar2_qtype qtype,
				  unsigned int *pbar2_qid)
{}

/* @intr_idx: MSI/MSI-X vector if >=0, -(absolute qid + 1) if < 0
 * @cong: < 0 -> no congestion feedback, >= 0 -> congestion channel map
 */
int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
		     struct net_device *dev, int intr_idx,
		     struct sge_fl *fl, rspq_handler_t hnd,
		     rspq_flush_handler_t flush_hnd, int cong)
{}

static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
{}

/**
 *	t4_sge_alloc_eth_txq - allocate an Ethernet TX Queue
 *	@adap: the adapter
 *	@txq: the SGE Ethernet TX Queue to initialize
 *	@dev: the Linux Network Device
 *	@netdevq: the corresponding Linux TX Queue
 *	@iqid: the Ingress Queue to which to deliver CIDX Update messages
 *	@dbqt: whether this TX Queue will use the SGE Doorbell Queue Timers
 */
int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
			 struct net_device *dev, struct netdev_queue *netdevq,
			 unsigned int iqid, u8 dbqt)
{}

int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
			  struct net_device *dev, unsigned int iqid,
			  unsigned int cmplqid)
{}

int t4_sge_mod_ctrl_txq(struct adapter *adap, unsigned int eqid,
			unsigned int cmplqid)
{}

static int t4_sge_alloc_ofld_txq(struct adapter *adap, struct sge_txq *q,
				 struct net_device *dev, u32 cmd, u32 iqid)
{}

int t4_sge_alloc_uld_txq(struct adapter *adap, struct sge_uld_txq *txq,
			 struct net_device *dev, unsigned int iqid,
			 unsigned int uld_type)
{}

int t4_sge_alloc_ethofld_txq(struct adapter *adap, struct sge_eohw_txq *txq,
			     struct net_device *dev, u32 iqid)
{}

void free_txq(struct adapter *adap, struct sge_txq *q)
{}

void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
		  struct sge_fl *fl)
{}

/**
 *      t4_free_ofld_rxqs - free a block of consecutive Rx queues
 *      @adap: the adapter
 *      @n: number of queues
 *      @q: pointer to first queue
 *
 *      Release the resources of a consecutive block of offload Rx queues.
 */
void t4_free_ofld_rxqs(struct adapter *adap, int n, struct sge_ofld_rxq *q)
{}

void t4_sge_free_ethofld_txq(struct adapter *adap, struct sge_eohw_txq *txq)
{}

/**
 *	t4_free_sge_resources - free SGE resources
 *	@adap: the adapter
 *
 *	Frees resources used by the SGE queue sets.
 */
void t4_free_sge_resources(struct adapter *adap)
{}

void t4_sge_start(struct adapter *adap)
{}

/**
 *	t4_sge_stop - disable SGE operation
 *	@adap: the adapter
 *
 *	Stop tasklets and timers associated with the DMA engine.  Note that
 *	this is effective only if measures have been taken to disable any HW
 *	events that may restart them.
 */
void t4_sge_stop(struct adapter *adap)
{}

/**
 *	t4_sge_init_soft - grab core SGE values needed by SGE code
 *	@adap: the adapter
 *
 *	We need to grab the SGE operating parameters that we need to have
 *	in order to do our job and make sure we can live with them.
 */

static int t4_sge_init_soft(struct adapter *adap)
{}

/**
 *     t4_sge_init - initialize SGE
 *     @adap: the adapter
 *
 *     Perform low-level SGE code initialization needed every time after a
 *     chip reset.
 */
int t4_sge_init(struct adapter *adap)
{}