drivers/staging/octeon/ethernet-tx.c

Source file repositories/reference/linux-study-clean/drivers/staging/octeon/ethernet-tx.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/octeon/ethernet-tx.c
Extension
.c
Size
19278 bytes
Lines
672
Domain
Driver Families
Bucket
drivers/staging
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

if (skb_to_free > 0) {
			struct sk_buff *to_free_list = NULL;

			spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
			while (skb_to_free > 0) {
				struct sk_buff *t;

				t = __skb_dequeue(&priv->tx_free_list[qos]);
				t->next = to_free_list;
				to_free_list = t;
				skb_to_free--;
			}
			spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
					       flags);
			/* Do the actual freeing outside of the lock. */
			while (to_free_list) {
				struct sk_buff *t = to_free_list;

				to_free_list = to_free_list->next;
				dev_kfree_skb_any(t);
			}
		}
		total_remaining += skb_queue_len(&priv->tx_free_list[qos]);
	}
	if (total_remaining < MAX_OUT_QUEUE_DEPTH && netif_queue_stopped(dev))
		netif_wake_queue(dev);
	if (total_remaining)
		cvm_oct_kick_tx_poll_watchdog();
}

/**
 * cvm_oct_xmit - transmit a packet
 * @skb:    Packet to send
 * @dev:    Device info structure
 *
 * Returns Always returns NETDEV_TX_OK
 */
netdev_tx_t cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
{
	union cvmx_pko_command_word0 pko_command;
	union cvmx_buf_ptr hw_buffer;
	u64 old_scratch;
	u64 old_scratch2;
	int qos;
	int i;
	enum {QUEUE_CORE, QUEUE_HW, QUEUE_DROP} queue_type;
	struct octeon_ethernet *priv = netdev_priv(dev);
	struct sk_buff *to_free_list;
	int skb_to_free;
	int buffers_to_free;
	u32 total_to_clean;
	unsigned long flags;
#if REUSE_SKBUFFS_WITHOUT_FREE
	unsigned char *fpa_head;
#endif

	/*
	 * Prefetch the private data structure.  It is larger than the
	 * one cache line.
	 */
	prefetch(priv);

	/*
	 * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
	 * completely remove "qos" in the event neither interface
	 * supports multiple queues per port.
	 */
	if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
	    (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
		qos = GET_SKBUFF_QOS(skb);
		if (qos <= 0)
			qos = 0;
		else if (qos >= cvmx_pko_get_num_queues(priv->port))
			qos = 0;
	} else {
		qos = 0;
	}

	if (USE_ASYNC_IOBDMA) {
		/* Save scratch in case userspace is using it */
		CVMX_SYNCIOBDMA;
		old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
		old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);

		/*
		 * Fetch and increment the number of packets to be
		 * freed.
		 */
		cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
					       FAU_NUM_PACKET_BUFFERS_TO_FREE,

Annotation

Implementation Notes