All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Fleming <afleming@freescale.com>
To: jeff@garzik.org
Cc: galak@kernel.crashing.org, netdev@vger.kernel.org,
	Andy Fleming <afleming@freescale.com>
Subject: [PATCH v2.6.29 09/14] gianfar: Add macros for stepping through BDs
Date: Tue, 16 Dec 2008 17:21:02 -0600	[thread overview]
Message-ID: <1229469667-25002-10-git-send-email-afleming@freescale.com> (raw)
In-Reply-To: <1229469667-25002-9-git-send-email-afleming@freescale.com>

This code is based strongly on code from Dai Haruki <Dai.Haruki@freescale.com>.

The gianfar Buffer Descriptors are arranged in a circular array, the end of
which is denoted by setting the "WRAP" bit in the descriptor.  However, the
software knows the end of the ring because it knows how many descriptors are
there.  Rather than check each descriptor for whether the WRAP bit is set,
use pointer math to determine where the next BD is.  This is also useful for
when we want to look at BDs other than the very next one (for Scatter-Gather).

Signed-off-by: Andy Fleming <afleming@freescale.com>
---
 drivers/net/gianfar.c |   27 +++++++++------------------
 drivers/net/gianfar.h |    6 ++++++
 2 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6c0e0a3..2c88701 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1215,7 +1215,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	struct txfcb *fcb = NULL;
-	struct txbd8 *txbdp;
+	struct txbd8 *txbdp, *base;
 	u16 status;
 	unsigned long flags;
 
@@ -1227,6 +1227,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* Point at the first free tx descriptor */
 	txbdp = priv->cur_tx;
+	base = priv->tx_bd_base;
 
 	/* Clear all but the WRAP status flags */
 	status = txbdp->status & TXBD_WRAP;
@@ -1279,12 +1280,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	eieio();
 	txbdp->status = status;
 
-	/* If this was the last BD in the ring, the next one */
-	/* is at the beginning of the ring */
-	if (txbdp->status & TXBD_WRAP)
-		txbdp = priv->tx_bd_base;
-	else
-		txbdp++;
+	txbdp = next_bd(txbdp, base, priv->tx_ring_size);
 
 	/* If the next BD still needs to be cleaned up, then the bds
 	   are full.  We need to tell the kernel to stop sending us stuff. */
@@ -1470,11 +1466,12 @@ static void gfar_timeout(struct net_device *dev)
 /* Interrupt Handler for Transmit complete */
 static int gfar_clean_tx_ring(struct net_device *dev)
 {
-	struct txbd8 *bdp;
+	struct txbd8 *bdp, *base;
 	struct gfar_private *priv = netdev_priv(dev);
 	int howmany = 0;
 
 	bdp = priv->dirty_tx;
+	base = priv->tx_bd_base;
 	while ((bdp->status & TXBD_READY) == 0) {
 		/* If dirty_tx and cur_tx are the same, then either the */
 		/* ring is empty or full now (it could only be full in the beginning, */
@@ -1500,11 +1497,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
 		/* Clean BD length for empty detection */
 		bdp->length = 0;
 
-		/* update bdp to point at next bd in the ring (wrapping if necessary) */
-		if (bdp->status & TXBD_WRAP)
-			bdp = priv->tx_bd_base;
-		else
-			bdp++;
+		bdp = next_bd(bdp, base, priv->tx_ring_size);
 
 		/* Move dirty_tx to be the next bd */
 		priv->dirty_tx = bdp;
@@ -1708,7 +1701,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
  */
 int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 {
-	struct rxbd8 *bdp;
+	struct rxbd8 *bdp, *base;
 	struct sk_buff *skb;
 	int pkt_len;
 	int amount_pull;
@@ -1717,6 +1710,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 
 	/* Get the first full descriptor */
 	bdp = priv->cur_rx;
+	base = priv->rx_bd_base;
 
 	amount_pull = (gfar_uses_fcb(priv) ? GMAC_FCB_LEN : 0) +
 		priv->padding;
@@ -1774,10 +1768,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 		gfar_new_rxbdp(dev, bdp, newskb);
 
 		/* Update to the next pointer */
-		if (bdp->status & RXBD_WRAP)
-			bdp = priv->rx_bd_base;
-		else
-			bdp++;
+		bdp = next_bd(bdp, base, priv->rx_ring_size);
 
 		/* update to point at the next skb */
 		priv->skb_currx =
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 1bdb50c..1ebf7ac 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -196,6 +196,12 @@ extern const char gfar_driver_version[];
 #define DEFAULT_TXIC mk_ic_value(DEFAULT_TXCOUNT, DEFAULT_TXTIME)
 #define DEFAULT_RXIC mk_ic_value(DEFAULT_RXCOUNT, DEFAULT_RXTIME)
 
+#define skip_bd(bdp, stride, base, ring_size) ({ \
+	typeof(bdp) new_bd = (bdp) + (stride); \
+	(new_bd >= (base) + (ring_size)) ? (new_bd - (ring_size)) : new_bd; })
+
+#define next_bd(bdp, base, ring_size) skip_bd(bdp, 1, base, ring_size)
+
 #define RCTRL_PAL_MASK		0x001f0000
 #define RCTRL_VLEX		0x00002000
 #define RCTRL_FILREN		0x00001000
-- 
1.5.4.GIT


  reply	other threads:[~2008-12-16 23:21 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-16 23:20 [PATCH 0/14] gianfar improvements Andy Fleming
2008-12-16 23:20 ` [PATCH v2.6.29 01/14] gianfar: Use gfar_halt to stop DMA in gfar_probe Andy Fleming
2008-12-16 23:20   ` [PATCH v2.6.29 02/14] gianfar: Fix skb allocation error Andy Fleming
2008-12-16 23:20     ` [PATCH v2.6.29 03/14] gianfar: Convert gianfar to an of_platform_driver Andy Fleming
2008-12-16 23:20       ` [PATCH v2.6.29 04/14] gianfar: Optimize interrupt coalescing configuration Andy Fleming
2008-12-16 23:20         ` [PATCH v2.6.29 05/14] gianfar: Fix eTSEC configuration procedure Andy Fleming
2008-12-16 23:20           ` [PATCH v2.6.29 06/14] gianfar: Fix VLAN HW feature related frame/buffer size calculation Andy Fleming
2008-12-16 23:21             ` [PATCH v2.6.29 07/14] gianfar: Enable padding and Optimize the frame prepended bytes handling Andy Fleming
2008-12-16 23:21               ` [PATCH v2.6.29 08/14] gianfar: Remove unused gfar_add_fcb() function parameter Andy Fleming
2008-12-16 23:21                 ` Andy Fleming [this message]
2008-12-16 23:21                   ` [PATCH v2.6.29 10/14] gianfar: Make all BD status writes 32-bit Andy Fleming
2008-12-16 23:21                     ` [PATCH v2.6.29 11/14] gianfar: Add Scatter Gather support Andy Fleming
2008-12-16 23:21                       ` [PATCH v2.6.29 12/14] gianfar: Use interface name in interrupt name to distinguish the source Andy Fleming
2008-12-16 23:21                         ` [PATCH v2.6.29 13/14] gianfar: Merge Tx and Rx interrupt for scheduling clean up ring Andy Fleming
2008-12-16 23:21                           ` [PATCH v2.6.29 14/14] gianfar: Continue polling until both tx and rx are empty Andy Fleming
2008-12-16 23:36                       ` [PATCH v2.6.29 11/14] gianfar: Add Scatter Gather support David Miller
2008-12-16 23:35                     ` [PATCH v2.6.29 10/14] gianfar: Make all BD status writes 32-bit David Miller
2008-12-16 23:33                   ` [PATCH v2.6.29 09/14] gianfar: Add macros for stepping through BDs David Miller
2008-12-16 23:33                 ` [PATCH v2.6.29 08/14] gianfar: Remove unused gfar_add_fcb() function parameter David Miller
2008-12-16 23:31               ` [PATCH v2.6.29 07/14] gianfar: Enable padding and Optimize the frame prepended bytes handling David Miller
2008-12-16 23:30             ` [PATCH v2.6.29 06/14] gianfar: Fix VLAN HW feature related frame/buffer size calculation David Miller
2008-12-16 23:30           ` [PATCH v2.6.29 05/14] gianfar: Fix eTSEC configuration procedure David Miller
2008-12-16 23:30         ` [PATCH v2.6.29 04/14] gianfar: Optimize interrupt coalescing configuration David Miller
2008-12-16 23:29       ` [PATCH v2.6.29 03/14] gianfar: Convert gianfar to an of_platform_driver David Miller
2008-12-16 23:28     ` [PATCH v2.6.29 02/14] gianfar: Fix skb allocation error David Miller
2008-12-16 23:25   ` [PATCH v2.6.29 01/14] gianfar: Use gfar_halt to stop DMA in gfar_probe David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1229469667-25002-10-git-send-email-afleming@freescale.com \
    --to=afleming@freescale.com \
    --cc=galak@kernel.crashing.org \
    --cc=jeff@garzik.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.