All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ucc_geth: Rework the TX logic.
@ 2009-03-26 17:44 Joakim Tjernlund
  2009-03-26 18:03 ` Anton Vorontsov
  2009-03-27  9:45   ` Li Yang
  0 siblings, 2 replies; 27+ messages in thread
From: Joakim Tjernlund @ 2009-03-26 17:44 UTC (permalink / raw)
  To: avorontsov, leoli, linuxppc-dev, netdev; +Cc: Joakim Tjernlund

The line:
 if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
       break;
in ucc_geth_tx() didn not make sense to me. Rework & cleanup
this logic to something understandable.
---

Reworked the patch according to Antons comments.

 drivers/net/ucc_geth.c |   66 +++++++++++++++++++++++++++--------------------
 1 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 7fc91aa..465de3a 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -161,6 +161,17 @@ static struct ucc_geth_info ugeth_primary_info = {
 
 static struct ucc_geth_info ugeth_info[8];
 
+
+static inline u32 __iomem *bd2buf(u8 __iomem *bd)
+{
+	return (u32 __iomem *)(bd+4);
+}
+
+static inline u32 __iomem *bd2status(u8 __iomem *bd)
+{
+	return (u32 __iomem *)bd;
+}
+
 #ifdef DEBUG
 static void mem_disp(u8 *addr, int size)
 {
@@ -3048,6 +3059,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	u8 __iomem *bd;			/* BD pointer */
 	u32 bd_status;
 	u8 txQ = 0;
+	int tx_ind;
 
 	ugeth_vdbg("%s: IN", __func__);
 
@@ -3057,21 +3069,19 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* Start from the next BD that should be filled */
 	bd = ugeth->txBd[txQ];
-	bd_status = in_be32((u32 __iomem *)bd);
+	bd_status = in_be32(bd2status(bd));
 	/* Save the skb pointer so we can free it later */
-	ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb;
+	tx_ind = ugeth->skb_curtx[txQ];
+	ugeth->tx_skbuff[txQ][tx_ind] = skb;
 
 	/* Update the current skb pointer (wrapping if this was the last) */
-	ugeth->skb_curtx[txQ] =
-	    (ugeth->skb_curtx[txQ] +
-	     1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
+	tx_ind = (tx_ind + 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
+	ugeth->skb_curtx[txQ] = tx_ind;
 
 	/* set up the buffer descriptor */
-	out_be32(&((struct qe_bd __iomem *)bd)->buf,
-		      dma_map_single(&ugeth->dev->dev, skb->data,
-			      skb->len, DMA_TO_DEVICE));
-
-	/* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
+	out_be32(bd2buf(bd),
+		 dma_map_single(&ugeth->dev->dev, skb->data,
+				skb->len, DMA_TO_DEVICE));
 
 	bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len;
 
@@ -3088,9 +3098,9 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* 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. */
-	if (bd == ugeth->confBd[txQ]) {
-		if (!netif_queue_stopped(dev))
-			netif_stop_queue(dev);
+
+	if (!in_be32(bd2buf(bd))) {
+		netif_stop_queue(dev);
 	}
 
 	ugeth->txBd[txQ] = bd;
@@ -3198,41 +3208,41 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 	struct ucc_geth_private *ugeth = netdev_priv(dev);
 	u8 __iomem *bd;		/* BD pointer */
 	u32 bd_status;
+	int tx_ind, num_freed;
 
 	bd = ugeth->confBd[txQ];
-	bd_status = in_be32((u32 __iomem *)bd);
-
+	bd_status = in_be32(bd2status(bd));
+	tx_ind = ugeth->skb_dirtytx[txQ];
+	num_freed = 0;
 	/* Normal processing. */
 	while ((bd_status & T_R) == 0) {
 		/* BD contains already transmitted buffer.   */
 		/* Handle the transmitted buffer and release */
 		/* the BD to be used with the current frame  */
 
-		if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
-			break;
+		if (bd == ugeth->txBd[txQ])
+			break; /* Queue is empty */
 
 		dev->stats.tx_packets++;
 
 		/* Free the sk buffer associated with this TxBD */
-		dev_kfree_skb(ugeth->
-				  tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
-		ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
-		ugeth->skb_dirtytx[txQ] =
-		    (ugeth->skb_dirtytx[txQ] +
-		     1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
-
-		/* We freed a buffer, so now we can restart transmission */
-		if (netif_queue_stopped(dev))
-			netif_wake_queue(dev);
+		dev_kfree_skb(ugeth->tx_skbuff[txQ][tx_ind]);
+		ugeth->tx_skbuff[txQ][tx_ind] = NULL;
+		out_be32(bd2buf(bd), 0); /* Mark it free */
+		num_freed++;
+		tx_ind = (tx_ind + 1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
 
 		/* Advance the confirmation BD pointer */
 		if (!(bd_status & T_W))
 			bd += sizeof(struct qe_bd);
 		else
 			bd = ugeth->p_tx_bd_ring[txQ];
-		bd_status = in_be32((u32 __iomem *)bd);
+		bd_status = in_be32(bd2status(bd));
 	}
 	ugeth->confBd[txQ] = bd;
+	ugeth->skb_dirtytx[txQ] = tx_ind;
+	if (num_freed)
+		netif_wake_queue(dev); /* We freed some buffers, so restart transmission */
 	return 0;
 }
 
-- 
1.6.1.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2009-03-31 14:37 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-26 17:44 [PATCH] ucc_geth: Rework the TX logic Joakim Tjernlund
2009-03-26 18:03 ` Anton Vorontsov
2009-03-26 18:26   ` Joakim Tjernlund
2009-03-27  9:45 ` Li Yang
2009-03-27  9:45   ` Li Yang
2009-03-27 10:23   ` Joakim Tjernlund
2009-03-27 10:23     ` Joakim Tjernlund
2009-03-27 10:39     ` Li Yang
2009-03-27 10:39       ` Li Yang
2009-03-27 11:39       ` Joakim Tjernlund
2009-03-27 13:26     ` Scott Wood
2009-03-30 16:38       ` Joakim Tjernlund
2009-03-30 16:38         ` Joakim Tjernlund
2009-03-30 17:22         ` Scott Wood
2009-03-30 17:34           ` Joakim Tjernlund
2009-03-30 17:34             ` Joakim Tjernlund
2009-03-30 17:45             ` Scott Wood
2009-03-30 18:42               ` Joakim Tjernlund
2009-03-30 19:32                 ` Scott Wood
2009-03-30 19:32                   ` Scott Wood
2009-03-31  9:07                   ` Joakim Tjernlund
2009-03-31  9:07                     ` Joakim Tjernlund
2009-03-31 10:58                     ` Li Yang
2009-03-31 10:58                       ` Li Yang
2009-03-31 14:37                     ` Scott Wood
2009-03-31  8:16           ` Li Yang
2009-03-31  8:16             ` Li Yang

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.