summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/xilinx
diff options
context:
space:
mode:
authorEsben Haabendal <esben@geanix.com>2019-04-30 09:17:58 +0200
committerDavid S. Miller <davem@davemloft.net>2019-05-01 20:33:30 +0200
commit7e97a194aca03c6ff86f84e46e196f5c9ed5c32c (patch)
treedfed285b7a785eca6bed68eb41fb9563d7de859e /drivers/net/ethernet/xilinx
parentnet: ll_temac: Replace bad usage of msleep() with usleep_range() (diff)
downloadlinux-7e97a194aca03c6ff86f84e46e196f5c9ed5c32c.tar.xz
linux-7e97a194aca03c6ff86f84e46e196f5c9ed5c32c.zip
net: ll_temac: Allow configuration of IRQ coalescing
This allows custom setup of IRQ coalescing for platforms using legacy platform_device. The irq timeout and count parameters can be used for tuning cpu load vs. latency. I have maintained the 0x00000400 bit in TX_CHNL_CTRL. It is specified as unused in the documentation I have available. It does not make any difference in the hardware I have available, so it is left in to not risk breaking other platforms where it might be used. Signed-off-by: Esben Haabendal <esben@geanix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/xilinx')
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac.h4
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_main.c40
2 files changed, 32 insertions, 12 deletions
diff --git a/drivers/net/ethernet/xilinx/ll_temac.h b/drivers/net/ethernet/xilinx/ll_temac.h
index 990f9ed151b2..1aeda084b8f1 100644
--- a/drivers/net/ethernet/xilinx/ll_temac.h
+++ b/drivers/net/ethernet/xilinx/ll_temac.h
@@ -375,6 +375,10 @@ struct temac_local {
int tx_bd_next;
int tx_bd_tail;
int rx_bd_ci;
+
+ /* DMA channel control setup */
+ u32 tx_chnl_ctrl;
+ u32 rx_chnl_ctrl;
};
/* Wrappers for temac_ior()/temac_iow() function pointers above */
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index fec8e4c22944..bccef30bf64e 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -304,18 +304,15 @@ static int temac_dma_bd_init(struct net_device *ndev)
lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND);
}
- lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 |
- CHNL_CTRL_IRQ_EN |
- CHNL_CTRL_IRQ_DLY_EN |
- CHNL_CTRL_IRQ_COAL_EN);
- /* 0x10220483 */
- /* 0x00100483 */
- lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 |
- CHNL_CTRL_IRQ_EN |
- CHNL_CTRL_IRQ_DLY_EN |
- CHNL_CTRL_IRQ_COAL_EN |
- CHNL_CTRL_IRQ_IOE);
- /* 0xff010283 */
+ /* Configure DMA channel (irq setup) */
+ lp->dma_out(lp, TX_CHNL_CTRL, lp->tx_chnl_ctrl |
+ 0x00000400 | // Use 1 Bit Wide Counters. Currently Not Used!
+ CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_ERR_EN |
+ CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN);
+ lp->dma_out(lp, RX_CHNL_CTRL, lp->rx_chnl_ctrl |
+ CHNL_CTRL_IRQ_IOE |
+ CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_ERR_EN |
+ CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN);
lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p);
lp->dma_out(lp, RX_TAILDESC_PTR,
@@ -1191,6 +1188,13 @@ static int temac_probe(struct platform_device *pdev)
lp->rx_irq = irq_of_parse_and_map(dma_np, 0);
lp->tx_irq = irq_of_parse_and_map(dma_np, 1);
+ /* Use defaults for IRQ delay/coalescing setup. These
+ * are configuration values, so does not belong in
+ * device-tree.
+ */
+ lp->tx_chnl_ctrl = 0x10220000;
+ lp->rx_chnl_ctrl = 0xff070000;
+
/* Finished with the DMA node; drop the reference */
of_node_put(dma_np);
} else if (pdata) {
@@ -1214,6 +1218,18 @@ static int temac_probe(struct platform_device *pdev)
/* Get DMA RX and TX interrupts */
lp->rx_irq = platform_get_irq(pdev, 0);
lp->tx_irq = platform_get_irq(pdev, 1);
+
+ /* IRQ delay/coalescing setup */
+ if (pdata->tx_irq_timeout || pdata->tx_irq_count)
+ lp->tx_chnl_ctrl = (pdata->tx_irq_timeout << 24) |
+ (pdata->tx_irq_count << 16);
+ else
+ lp->tx_chnl_ctrl = 0x10220000;
+ if (pdata->rx_irq_timeout || pdata->rx_irq_count)
+ lp->rx_chnl_ctrl = (pdata->rx_irq_timeout << 24) |
+ (pdata->rx_irq_count << 16);
+ else
+ lp->rx_chnl_ctrl = 0xff070000;
}
/* Error handle returned DMA RX and TX interrupts */