Commit e76d1ea8 authored by Sean Anderson's avatar Sean Anderson Committed by Jakub Kicinski
Browse files

net: xilinx: axienet: Combine CR calculation



Combine the common parts of the CR calculations for better code reuse.
While we're at it, simplify the code a bit.

Signed-off-by: default avatarSean Anderson <sean.anderson@linux.dev>
Reviewed-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Link: https://patch.msgid.link/20250206201036.1516800-2-sean.anderson@linux.dev


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 848b09d5
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -112,9 +112,6 @@
#define XAXIDMA_DELAY_MASK		0xFF000000 /* Delay timeout counter */
#define XAXIDMA_COALESCE_MASK		0x00FF0000 /* Coalesce counter */

#define XAXIDMA_DELAY_SHIFT		24
#define XAXIDMA_COALESCE_SHIFT		16

#define XAXIDMA_IRQ_IOC_MASK		0x00001000 /* Completion intr */
#define XAXIDMA_IRQ_DELAY_MASK		0x00002000 /* Delay interrupt */
#define XAXIDMA_IRQ_ERROR_MASK		0x00004000 /* Error interrupt */
+34 −30
Original line number Diff line number Diff line
@@ -224,22 +224,40 @@ static void axienet_dma_bd_release(struct net_device *ndev)
}

/**
 * axienet_usec_to_timer - Calculate IRQ delay timer value
 * @lp:		Pointer to the axienet_local structure
 * @coalesce_usec: Microseconds to convert into timer value
 * axienet_calc_cr() - Calculate control register value
 * @lp: Device private data
 * @count: Number of completions before an interrupt
 * @usec: Microseconds after the last completion before an interrupt
 *
 * Calculate a control register value based on the coalescing settings. The
 * run/stop bit is not set.
 */
static u32 axienet_usec_to_timer(struct axienet_local *lp, u32 coalesce_usec)
static u32 axienet_calc_cr(struct axienet_local *lp, u32 count, u32 usec)
{
	u32 result;
	u32 cr;

	cr = FIELD_PREP(XAXIDMA_COALESCE_MASK, count) | XAXIDMA_IRQ_IOC_MASK |
	     XAXIDMA_IRQ_ERROR_MASK;
	/* Only set interrupt delay timer if not generating an interrupt on
	 * the first packet. Otherwise leave at 0 to disable delay interrupt.
	 */
	if (count > 1) {
		u64 clk_rate = 125000000; /* arbitrary guess if no clock rate set */
		u32 timer;

		if (lp->axi_clk)
			clk_rate = clk_get_rate(lp->axi_clk);

		/* 1 Timeout Interval = 125 * (clock period of SG clock) */
	result = DIV64_U64_ROUND_CLOSEST((u64)coalesce_usec * clk_rate,
		timer = DIV64_U64_ROUND_CLOSEST((u64)usec * clk_rate,
						XAXIDMA_DELAY_SCALE);
	return min(result, FIELD_MAX(XAXIDMA_DELAY_MASK));

		timer = min(timer, FIELD_MAX(XAXIDMA_DELAY_MASK));
		cr |= FIELD_PREP(XAXIDMA_DELAY_MASK, timer) |
		      XAXIDMA_IRQ_DELAY_MASK;
	}

	return cr;
}

/**
@@ -249,27 +267,13 @@ static u32 axienet_usec_to_timer(struct axienet_local *lp, u32 coalesce_usec)
static void axienet_dma_start(struct axienet_local *lp)
{
	/* Start updating the Rx channel control register */
	lp->rx_dma_cr = (lp->coalesce_count_rx << XAXIDMA_COALESCE_SHIFT) |
			XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
	/* Only set interrupt delay timer if not generating an interrupt on
	 * the first RX packet. Otherwise leave at 0 to disable delay interrupt.
	 */
	if (lp->coalesce_count_rx > 1)
		lp->rx_dma_cr |= (axienet_usec_to_timer(lp, lp->coalesce_usec_rx)
					<< XAXIDMA_DELAY_SHIFT) |
				 XAXIDMA_IRQ_DELAY_MASK;
	lp->rx_dma_cr = axienet_calc_cr(lp, lp->coalesce_count_rx,
					lp->coalesce_usec_rx);
	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, lp->rx_dma_cr);

	/* Start updating the Tx channel control register */
	lp->tx_dma_cr = (lp->coalesce_count_tx << XAXIDMA_COALESCE_SHIFT) |
			XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
	/* Only set interrupt delay timer if not generating an interrupt on
	 * the first TX packet. Otherwise leave at 0 to disable delay interrupt.
	 */
	if (lp->coalesce_count_tx > 1)
		lp->tx_dma_cr |= (axienet_usec_to_timer(lp, lp->coalesce_usec_tx)
					<< XAXIDMA_DELAY_SHIFT) |
				 XAXIDMA_IRQ_DELAY_MASK;
	lp->tx_dma_cr = axienet_calc_cr(lp, lp->coalesce_count_tx,
					lp->coalesce_usec_tx);
	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, lp->tx_dma_cr);

	/* Populate the tail pointer and bring the Rx Axi DMA engine out of