drivers/net/ethernet/intel/ice/ice_txrx.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ice/ice_txrx.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ice/ice_txrx.c
Extension
.c
Size
65057 bytes
Lines
2405
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

while (tx_desc != eop_desc) {
			ice_trace(clean_tx_irq_unmap, tx_ring, tx_desc, tx_buf);
			tx_buf++;
			tx_desc++;
			i++;
			if (unlikely(!i)) {
				i -= tx_ring->count;
				tx_buf = tx_ring->tx_buf;
				tx_desc = ICE_TX_DESC(tx_ring, 0);
			}

			/* unmap any remaining paged data */
			if (dma_unmap_len(tx_buf, len)) {
				dma_unmap_page(tx_ring->dev,
					       dma_unmap_addr(tx_buf, dma),
					       dma_unmap_len(tx_buf, len),
					       DMA_TO_DEVICE);
				dma_unmap_len_set(tx_buf, len, 0);
			}
		}
		ice_trace(clean_tx_irq_unmap_eop, tx_ring, tx_desc, tx_buf);

		/* move us one more past the eop_desc for start of next pkt */
		tx_buf++;
		tx_desc++;
		i++;
		if (unlikely(!i)) {
			i -= tx_ring->count;
			tx_buf = tx_ring->tx_buf;
			tx_desc = ICE_TX_DESC(tx_ring, 0);
		}

		prefetch(tx_desc);

		/* update budget accounting */
		budget--;
	} while (likely(budget));

	i += tx_ring->count;
	tx_ring->next_to_clean = i;

	ice_update_tx_ring_stats(tx_ring, total_pkts, total_bytes);
	netdev_tx_completed_queue(txring_txq(tx_ring), total_pkts, total_bytes);

#define TX_WAKE_THRESHOLD ((s16)(DESC_NEEDED * 2))
	if (unlikely(total_pkts && netif_carrier_ok(tx_ring->netdev) &&
		     (ICE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) {
		/* Make sure that anybody stopping the queue after this
		 * sees the new next_to_clean.
		 */
		smp_mb();
		if (netif_tx_queue_stopped(txring_txq(tx_ring)) &&
		    !test_bit(ICE_VSI_DOWN, vsi->state)) {
			netif_tx_wake_queue(txring_txq(tx_ring));
			ice_stats_inc(tx_ring->ring_stats, tx_restart_q);
		}
	}

	return !!budget;
}

/**
 * ice_alloc_tstamp_ring - allocate the Time Stamp ring
 * @tx_ring: Tx ring to allocate the Time Stamp ring for
 *
 * Return: 0 on success, negative on error
 */
static int ice_alloc_tstamp_ring(struct ice_tx_ring *tx_ring)
{
	struct ice_tstamp_ring *tstamp_ring;

	/* allocate with kzalloc(), free with kfree_rcu() */
	tstamp_ring = kzalloc_obj(*tstamp_ring);
	if (!tstamp_ring)
		return -ENOMEM;

	tstamp_ring->tx_ring = tx_ring;
	tx_ring->tstamp_ring = tstamp_ring;
	tstamp_ring->desc = NULL;
	tstamp_ring->count = ice_calc_ts_ring_count(tx_ring);
	set_bit(ICE_TX_RING_FLAGS_TXTIME, tx_ring->flags);
	return 0;
}

/**
 * ice_setup_tstamp_ring - allocate the Time Stamp ring
 * @tx_ring: Tx ring to set up the Time Stamp ring for
 *
 * Return: 0 on success, negative on error
 */

Annotation

Implementation Notes