drivers/net/ethernet/chelsio/cxgb4vf/sge.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/chelsio/cxgb4vf/sge.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/chelsio/cxgb4vf/sge.c
Extension
.c
Size
82250 bytes
Lines
2707
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tx_sw_desc {
	struct sk_buff *skb;		/* socket buffer of TX data source */
	struct ulptx_sgl *sgl;		/* scatter/gather list in TX Queue */
};

/*
 * Software state per RX Free List descriptor.  We keep track of the allocated
 * FL page, its size, and its PCI DMA address (if the page is mapped).  The FL
 * page size and its PCI DMA mapped state are stored in the low bits of the
 * PCI DMA address as per below.
 */
struct rx_sw_desc {
	struct page *page;		/* Free List page buffer */
	dma_addr_t dma_addr;		/* PCI DMA address (if mapped) */
					/*   and flags (see below) */
};

/*
 * The low bits of rx_sw_desc.dma_addr have special meaning.  Note that the
 * SGE also uses the low 4 bits to determine the size of the buffer.  It uses
 * those bits to index into the SGE_FL_BUFFER_SIZE[index] register array.
 * Since we only use SGE_FL_BUFFER_SIZE0 and SGE_FL_BUFFER_SIZE1, these low 4
 * bits can only contain a 0 or a 1 to indicate which size buffer we're giving
 * to the SGE.  Thus, our software state of "is the buffer mapped for DMA" is
 * maintained in an inverse sense so the hardware never sees that bit high.
 */
enum {
	RX_LARGE_BUF    = 1 << 0,	/* buffer is SGE_FL_BUFFER_SIZE[1] */
	RX_UNMAPPED_BUF = 1 << 1,	/* buffer is not mapped */
};

/**
 *	get_buf_addr - return DMA buffer address of software descriptor
 *	@sdesc: pointer to the software buffer descriptor
 *
 *	Return the DMA buffer address of a software descriptor (stripping out
 *	our low-order flag bits).
 */
static inline dma_addr_t get_buf_addr(const struct rx_sw_desc *sdesc)
{
	return sdesc->dma_addr & ~(dma_addr_t)(RX_LARGE_BUF | RX_UNMAPPED_BUF);
}

/**
 *	is_buf_mapped - is buffer mapped for DMA?
 *	@sdesc: pointer to the software buffer descriptor
 *
 *	Determine whether the buffer associated with a software descriptor in
 *	mapped for DMA or not.
 */
static inline bool is_buf_mapped(const struct rx_sw_desc *sdesc)
{
	return !(sdesc->dma_addr & RX_UNMAPPED_BUF);
}

/**
 *	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 inline int need_skb_unmap(void)
{
#ifdef CONFIG_NEED_DMA_MAP_STATE
	return 1;
#else
	return 0;
#endif
}

/**
 *	txq_avail - return the number of available slots in a TX queue
 *	@tq: the TX queue
 *
 *	Returns the number of available descriptors in a TX queue.
 */
static inline unsigned int txq_avail(const struct sge_txq *tq)
{
	return tq->size - 1 - tq->in_use;
}

/**
 *	fl_cap - return the capacity of a Free List
 *	@fl: the Free List
 *
 *	Returns the capacity of a Free List.  The capacity is less than the
 *	size because an Egress Queue Index Unit worth of descriptors needs to
 *	be left unpopulated, otherwise the Producer and Consumer indices PIDX
 *	and CIDX will match and the hardware will think the FL is empty.
 */

Annotation

Implementation Notes