Inter-revision diff: patch 5

Comparing v1 (message) to v3 (message)

--- v1
+++ v3
@@ -1,415 +1,22 @@
-From: Havard Skinnemoen <havard@skinnemoen.net>
+On some revision of GEM, TSR status register has more information.
 
-Instead of masking head and tail every time we increment them, just let them
-wrap through UINT_MAX and mask them when subscripting. Add simple accessor
-functions to do the subscripting properly to minimize the chances of messing
-this up.
-
-This makes the code slightly smaller, and hopefully faster as well.  Also,
-doing the ring buffer management this way will simplify things a lot when
-making the ring sizes configurable in the future.
-
-Signed-off-by: Havard Skinnemoen <havard@skinnemoen.net>
-[nicolas.ferre@atmel.com: split patch in topics, adapt to newer kernel]
 Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
 ---
- drivers/net/ethernet/cadence/macb.c |  170 ++++++++++++++++++++++-------------
- drivers/net/ethernet/cadence/macb.h |   22 +++--
- 2 files changed, 123 insertions(+), 69 deletions(-)
+ drivers/net/ethernet/cadence/macb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
-index f4b8adf..3d3a077 100644
+index 4db52f3..cd6d431 100644
 --- a/drivers/net/ethernet/cadence/macb.c
 +++ b/drivers/net/ethernet/cadence/macb.c
-@@ -31,24 +31,13 @@
+@@ -314,7 +314,7 @@ static void macb_tx(struct macb *bp)
+ 	status = macb_readl(bp, TSR);
+ 	macb_writel(bp, TSR, status);
  
- #define RX_BUFFER_SIZE		128
- #define RX_RING_SIZE		512
--#define RX_RING_BYTES		(sizeof(struct dma_desc) * RX_RING_SIZE)
-+#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+-	netdev_vdbg(bp->dev, "macb_tx status = %02lx\n", (unsigned long)status);
++	netdev_vdbg(bp->dev, "macb_tx status = 0x%03lx\n", (unsigned long)status);
  
- /* Make the IP header word-aligned (the ethernet header is 14 bytes) */
- #define RX_OFFSET		2
- 
- #define TX_RING_SIZE		128
--#define DEF_TX_RING_PENDING	(TX_RING_SIZE - 1)
--#define TX_RING_BYTES		(sizeof(struct dma_desc) * TX_RING_SIZE)
--
--#define TX_RING_GAP(bp)						\
--	(TX_RING_SIZE - (bp)->tx_pending)
--#define TX_BUFFS_AVAIL(bp)					\
--	(((bp)->tx_tail <= (bp)->tx_head) ?			\
--	 (bp)->tx_tail + (bp)->tx_pending - (bp)->tx_head :	\
--	 (bp)->tx_tail - (bp)->tx_head - TX_RING_GAP(bp))
--#define NEXT_TX(n)		(((n) + 1) & (TX_RING_SIZE - 1))
--
--#define NEXT_RX(n)		(((n) + 1) & (RX_RING_SIZE - 1))
-+#define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
- 
- /* minimum number of free TX descriptors before waking up TX process */
- #define MACB_TX_WAKEUP_THRESH	(TX_RING_SIZE / 4)
-@@ -56,6 +45,51 @@
- #define MACB_RX_INT_FLAGS	(MACB_BIT(RCOMP) | MACB_BIT(RXUBR)	\
- 				 | MACB_BIT(ISR_ROVR))
- 
-+/* Ring buffer accessors */
-+static unsigned int macb_tx_ring_wrap(unsigned int index)
-+{
-+	return index & (TX_RING_SIZE - 1);
-+}
-+
-+static unsigned int macb_tx_ring_avail(struct macb *bp)
-+{
-+	return TX_RING_SIZE - (bp->tx_head - bp->tx_tail);
-+}
-+
-+static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
-+{
-+	return &bp->tx_ring[macb_tx_ring_wrap(index)];
-+}
-+
-+static struct macb_tx_skb *macb_tx_skb(struct macb *bp, unsigned int index)
-+{
-+	return &bp->tx_skb[macb_tx_ring_wrap(index)];
-+}
-+
-+static dma_addr_t macb_tx_dma(struct macb *bp, unsigned int index)
-+{
-+	dma_addr_t offset;
-+
-+	offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc);
-+
-+	return bp->tx_ring_dma + offset;
-+}
-+
-+static unsigned int macb_rx_ring_wrap(unsigned int index)
-+{
-+	return index & (RX_RING_SIZE - 1);
-+}
-+
-+static struct macb_dma_desc *macb_rx_desc(struct macb *bp, unsigned int index)
-+{
-+	return &bp->rx_ring[macb_rx_ring_wrap(index)];
-+}
-+
-+static void *macb_rx_buffer(struct macb *bp, unsigned int index)
-+{
-+	return bp->rx_buffers + RX_BUFFER_SIZE * macb_rx_ring_wrap(index);
-+}
-+
- static void __macb_set_hwaddr(struct macb *bp)
- {
- 	u32 bottom;
-@@ -335,17 +369,18 @@ static void macb_tx(struct macb *bp)
- 		bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
- 
- 		/* free transmit buffer in upper layer*/
--		for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
--			struct ring_info *rp = &bp->tx_skb[tail];
--			struct sk_buff *skb = rp->skb;
--
--			BUG_ON(skb == NULL);
-+		for (tail = bp->tx_tail; tail != head; tail++) {
-+			struct macb_tx_skb	*tx_skb;
-+			struct sk_buff		*skb;
- 
- 			rmb();
- 
--			dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
--							 DMA_TO_DEVICE);
--			rp->skb = NULL;
-+			tx_skb = macb_tx_skb(bp, tail);
-+			skb = tx_skb->skb;
-+
-+			dma_unmap_single(&bp->pdev->dev, tx_skb->mapping,
-+						skb->len, DMA_TO_DEVICE);
-+			tx_skb->skb = NULL;
- 			dev_kfree_skb_irq(skb);
- 		}
- 
-@@ -365,28 +400,32 @@ static void macb_tx(struct macb *bp)
- 		return;
- 
- 	head = bp->tx_head;
--	for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
--		struct ring_info *rp = &bp->tx_skb[tail];
--		struct sk_buff *skb = rp->skb;
--		u32 bufstat;
-+	for (tail = bp->tx_tail; tail != head; tail++) {
-+		struct macb_tx_skb	*tx_skb;
-+		struct sk_buff		*skb;
-+		struct macb_dma_desc	*desc;
-+		u32			ctrl;
- 
--		BUG_ON(skb == NULL);
-+		desc = macb_tx_desc(bp, tail);
- 
- 		/* Make hw descriptor updates visible to CPU */
- 		rmb();
- 
--		bufstat = bp->tx_ring[tail].ctrl;
-+		ctrl = desc->ctrl;
- 
--		if (!(bufstat & MACB_BIT(TX_USED)))
-+		if (!(ctrl & MACB_BIT(TX_USED)))
- 			break;
- 
-+		tx_skb = macb_tx_skb(bp, tail);
-+		skb = tx_skb->skb;
-+
- 		netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
--			   tail, skb->data);
--		dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
-+			macb_tx_ring_wrap(tail), skb->data);
-+		dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len,
- 				 DMA_TO_DEVICE);
- 		bp->stats.tx_packets++;
- 		bp->stats.tx_bytes += skb->len;
--		rp->skb = NULL;
-+		tx_skb->skb = NULL;
- 		dev_kfree_skb_irq(skb);
- 	}
- 
-@@ -398,8 +437,8 @@ static void macb_tx(struct macb *bp)
- 		macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
- 
- 	bp->tx_tail = tail;
--	if (netif_queue_stopped(bp->dev) &&
--	    TX_BUFFS_AVAIL(bp) > MACB_TX_WAKEUP_THRESH)
-+	if (netif_queue_stopped(bp->dev)
-+			&& macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH)
- 		netif_wake_queue(bp->dev);
- }
- 
-@@ -410,17 +449,21 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
- 	unsigned int frag;
- 	unsigned int offset = 0;
- 	struct sk_buff *skb;
-+	struct macb_dma_desc *desc;
- 
--	len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl);
-+	desc = macb_rx_desc(bp, last_frag);
-+	len = MACB_BFEXT(RX_FRMLEN, desc->ctrl);
- 
- 	netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
--		   first_frag, last_frag, len);
-+		macb_rx_ring_wrap(first_frag),
-+		macb_rx_ring_wrap(last_frag), len);
- 
- 	skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET);
- 	if (!skb) {
- 		bp->stats.rx_dropped++;
--		for (frag = first_frag; ; frag = NEXT_RX(frag)) {
--			bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
-+		for (frag = first_frag; ; frag++) {
-+			desc = macb_rx_desc(bp, frag);
-+			desc->addr &= ~MACB_BIT(RX_USED);
- 			if (frag == last_frag)
- 				break;
- 		}
-@@ -435,7 +478,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
- 	skb_checksum_none_assert(skb);
- 	skb_put(skb, len);
- 
--	for (frag = first_frag; ; frag = NEXT_RX(frag)) {
-+	for (frag = first_frag; ; frag++) {
- 		unsigned int frag_len = RX_BUFFER_SIZE;
- 
- 		if (offset + frag_len > len) {
-@@ -443,11 +486,10 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
- 			frag_len = len - offset;
- 		}
- 		skb_copy_to_linear_data_offset(skb, offset,
--					       (bp->rx_buffers +
--					        (RX_BUFFER_SIZE * frag)),
--					       frag_len);
-+				macb_rx_buffer(bp, frag), frag_len);
- 		offset += RX_BUFFER_SIZE;
--		bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
-+		desc = macb_rx_desc(bp, frag);
-+		desc->addr &= ~MACB_BIT(RX_USED);
- 
- 		if (frag == last_frag)
- 			break;
-@@ -473,8 +515,10 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
- {
- 	unsigned int frag;
- 
--	for (frag = begin; frag != end; frag = NEXT_RX(frag))
--		bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
-+	for (frag = begin; frag != end; frag++) {
-+		struct macb_dma_desc *desc = macb_rx_desc(bp, frag);
-+		desc->addr &= ~MACB_BIT(RX_USED);
-+	}
- 
- 	/* Make descriptor updates visible to hardware */
- 	wmb();
-@@ -489,17 +533,18 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
- static int macb_rx(struct macb *bp, int budget)
- {
- 	int received = 0;
--	unsigned int tail = bp->rx_tail;
-+	unsigned int tail;
- 	int first_frag = -1;
- 
--	for (; budget > 0; tail = NEXT_RX(tail)) {
-+	for (tail = bp->rx_tail; budget > 0; tail++) {
-+		struct macb_dma_desc *desc = macb_rx_desc(bp, tail);
- 		u32 addr, ctrl;
- 
- 		/* Make hw descriptor updates visible to CPU */
- 		rmb();
- 
--		addr = bp->rx_ring[tail].addr;
--		ctrl = bp->rx_ring[tail].ctrl;
-+		addr = desc->addr;
-+		ctrl = desc->ctrl;
- 
- 		if (!(addr & MACB_BIT(RX_USED)))
- 			break;
-@@ -653,6 +698,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 	struct macb *bp = netdev_priv(dev);
- 	dma_addr_t mapping;
- 	unsigned int len, entry;
-+	struct macb_dma_desc *desc;
-+	struct macb_tx_skb *tx_skb;
- 	u32 ctrl;
- 	unsigned long flags;
- 
-@@ -669,7 +716,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 	spin_lock_irqsave(&bp->lock, flags);
- 
- 	/* This is a hard error, log it. */
--	if (TX_BUFFS_AVAIL(bp) < 1) {
-+	if (macb_tx_ring_avail(bp) < 1) {
- 		netif_stop_queue(dev);
- 		spin_unlock_irqrestore(&bp->lock, flags);
- 		netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
-@@ -678,12 +725,15 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 		return NETDEV_TX_BUSY;
- 	}
- 
--	entry = bp->tx_head;
-+	entry = macb_tx_ring_wrap(bp->tx_head);
-+	bp->tx_head++;
- 	netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry);
- 	mapping = dma_map_single(&bp->pdev->dev, skb->data,
- 				 len, DMA_TO_DEVICE);
--	bp->tx_skb[entry].skb = skb;
--	bp->tx_skb[entry].mapping = mapping;
-+
-+	tx_skb = &bp->tx_skb[entry];
-+	tx_skb->skb = skb;
-+	tx_skb->mapping = mapping;
- 	netdev_vdbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n",
- 		   skb->data, (unsigned long)mapping);
- 
-@@ -692,15 +742,13 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 	if (entry == (TX_RING_SIZE - 1))
- 		ctrl |= MACB_BIT(TX_WRAP);
- 
--	bp->tx_ring[entry].addr = mapping;
--	bp->tx_ring[entry].ctrl = ctrl;
-+	desc = &bp->tx_ring[entry];
-+	desc->addr = mapping;
-+	desc->ctrl = ctrl;
- 
- 	/* Make newly initialized descriptor visible to hardware */
- 	wmb();
- 
--	entry = NEXT_TX(entry);
--	bp->tx_head = entry;
--
- 	skb_tx_timestamp(skb);
- 
- 	/*
-@@ -713,10 +761,10 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 	 * re-enable interrupts, and the interrupt handler will make
- 	 * sure the controler is started.
- 	 */
--	if (NEXT_TX(bp->tx_tail) == bp->tx_head)
-+	if (bp->tx_tail == bp->tx_head - 1)
- 		macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
- 
--	if (TX_BUFFS_AVAIL(bp) < 1)
-+	if (macb_tx_ring_avail(bp) < 1)
- 		netif_stop_queue(dev);
- 
- 	spin_unlock_irqrestore(&bp->lock, flags);
-@@ -752,7 +800,7 @@ static int macb_alloc_consistent(struct macb *bp)
- {
- 	int size;
- 
--	size = TX_RING_SIZE * sizeof(struct ring_info);
-+	size = TX_RING_SIZE * sizeof(struct macb_tx_skb);
- 	bp->tx_skb = kmalloc(size, GFP_KERNEL);
- 	if (!bp->tx_skb)
- 		goto out_err;
-@@ -1437,8 +1485,6 @@ static int __init macb_probe(struct platform_device *pdev)
- 		macb_or_gem_writel(bp, USRIO, MACB_BIT(MII));
- #endif
- 
--	bp->tx_pending = DEF_TX_RING_PENDING;
--
- 	err = register_netdev(dev);
- 	if (err) {
- 		dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
-diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
-index f69ceef..8a4ee2f 100644
---- a/drivers/net/ethernet/cadence/macb.h
-+++ b/drivers/net/ethernet/cadence/macb.h
-@@ -356,7 +356,12 @@
- 		__v; \
- 	})
- 
--struct dma_desc {
-+/**
-+ * struct macb_dma_desc - Hardware DMA descriptor
-+ * @addr: DMA address of data buffer
-+ * @ctrl: Control and status bits
-+ */
-+struct macb_dma_desc {
- 	u32	addr;
- 	u32	ctrl;
- };
-@@ -421,7 +426,12 @@ struct dma_desc {
- #define MACB_TX_USED_OFFSET			31
- #define MACB_TX_USED_SIZE			1
- 
--struct ring_info {
-+/**
-+ * struct macb_tx_skb - data about an skb which is being transmitted
-+ * @skb: skb currently being transmitted
-+ * @mapping: DMA address of the skb's data buffer
-+ */
-+struct macb_tx_skb {
- 	struct sk_buff		*skb;
- 	dma_addr_t		mapping;
- };
-@@ -506,12 +516,12 @@ struct macb {
- 	void __iomem		*regs;
- 
- 	unsigned int		rx_tail;
--	struct dma_desc		*rx_ring;
-+	struct macb_dma_desc	*rx_ring;
- 	void			*rx_buffers;
- 
- 	unsigned int		tx_head, tx_tail;
--	struct dma_desc		*tx_ring;
--	struct ring_info	*tx_skb;
-+	struct macb_dma_desc	*tx_ring;
-+	struct macb_tx_skb	*tx_skb;
- 
- 	spinlock_t		lock;
- 	struct platform_device	*pdev;
-@@ -529,8 +539,6 @@ struct macb {
- 	dma_addr_t		tx_ring_dma;
- 	dma_addr_t		rx_buffers_dma;
- 
--	unsigned int		rx_pending, tx_pending;
--
- 	struct mii_bus		*mii_bus;
- 	struct phy_device	*phy_dev;
- 	unsigned int 		link;
+ 	if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
+ 		int i;
 -- 
-1.7.10
+1.8.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help