From: "Edgar E. Iglesias" <[email protected]>
Currently, we only use the first receive queue and leave the
remaining DMA descriptor pointers pointing at 0.
Disable unused queues by connecting them to a looped descriptor
chain without free slots.
Signed-off-by: Edgar E. Iglesias <[email protected]>
Signed-off-by: Harini Katakam <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
---
drivers/net/ethernet/cadence/macb.h | 2 ++
drivers/net/ethernet/cadence/macb_main.c | 42 ++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index acb6578..974c801 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -994,6 +994,7 @@ struct macb {
unsigned int rx_tail;
unsigned int rx_prepared_head;
struct macb_dma_desc *rx_ring;
+ struct macb_dma_desc *rx_ring_tieoff;
struct sk_buff **rx_skbuff;
void *rx_buffers;
size_t rx_buffer_size;
@@ -1019,6 +1020,7 @@ struct macb {
} hw_stats;
dma_addr_t rx_ring_dma;
+ dma_addr_t rx_ring_tieoff_dma;
dma_addr_t rx_buffers_dma;
struct macb_or_gem_ops macbgem_ops;
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 623ae9c..b14a04d 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1755,6 +1755,12 @@ static void macb_free_consistent(struct macb *bp)
bp->rx_ring = NULL;
}
+ if (bp->rx_ring_tieoff) {
+ dma_free_coherent(&bp->pdev->dev, sizeof(bp->rx_ring_tieoff[0]),
+ bp->rx_ring_tieoff, bp->rx_ring_tieoff_dma);
+ bp->rx_ring_tieoff = NULL;
+ }
+
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
kfree(queue->tx_skb);
queue->tx_skb = NULL;
@@ -1826,6 +1832,19 @@ static int macb_alloc_consistent(struct macb *bp)
&bp->rx_ring_dma, GFP_KERNEL);
if (!bp->rx_ring)
goto out_err;
+
+ /* If we have more than one queue, allocate a tie off descriptor
+ * that will be used to disable unused RX queues.
+ */
+ if (bp->num_queues > 1) {
+ bp->rx_ring_tieoff = dma_alloc_coherent(&bp->pdev->dev,
+ sizeof(bp->rx_ring_tieoff[0]),
+ &bp->rx_ring_tieoff_dma,
+ GFP_KERNEL);
+ if (!bp->rx_ring_tieoff)
+ goto out_err;
+ }
+
netdev_dbg(bp->dev,
"Allocated RX ring of %d bytes at %08lx (mapped %p)\n",
size, (unsigned long)bp->rx_ring_dma, bp->rx_ring);
@@ -1840,6 +1859,19 @@ static int macb_alloc_consistent(struct macb *bp)
return -ENOMEM;
}
+static void macb_init_tieoff(struct macb *bp)
+{
+ struct macb_dma_desc *d = bp->rx_ring_tieoff;
+
+ if (bp->num_queues > 1) {
+ /* Setup a wrapping descriptor with no free slots
+ * (WRAP and USED) to tie off/disable unused RX queues.
+ */
+ d->addr = MACB_BIT(RX_WRAP) | MACB_BIT(RX_USED);
+ d->ctrl = 0;
+ }
+}
+
static void gem_init_rings(struct macb *bp)
{
struct macb_queue *queue;
@@ -1862,6 +1894,7 @@ static void gem_init_rings(struct macb *bp)
bp->rx_prepared_head = 0;
gem_rx_refill(bp);
+ macb_init_tieoff(bp);
}
static void macb_init_rings(struct macb *bp)
@@ -1879,6 +1912,7 @@ static void macb_init_rings(struct macb *bp)
bp->queues[0].tx_head = 0;
bp->queues[0].tx_tail = 0;
desc->ctrl |= MACB_BIT(TX_WRAP);
+ macb_init_tieoff(bp);
}
static void macb_reset_hw(struct macb *bp)
@@ -2063,6 +2097,14 @@ static void macb_init_hw(struct macb *bp)
queue_writel(queue, TBQPH, upper_32_bits(queue->tx_ring_dma));
#endif
+ /* We only use the first queue at the moment. Remaining
+ * queues must be tied-off before we enable the receiver.
+ *
+ * See the documentation for receive_q1_ptr for more info.
+ */
+ if (q)
+ queue_writel(queue, RBQP, bp->rx_ring_tieoff_dma);
+
/* Enable interrupts */
queue_writel(queue, IER,
MACB_RX_INT_FLAGS |
--
2.7.4
From 1586382173253971996@xxx Sun Dec 10 07:45:34 +0000 2017
X-GM-THRID: 1585818026281513739
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread