linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [patch 0/6] pasemi_mac updates for 2.6.26
@ 2008-02-21  2:57 Olof Johansson
  2008-02-21  2:57 ` [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib Olof Johansson
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

Here's a set of updates for pasemi_mac for 2.6.26. Some of them touch
the dma_lib in the platform code as well, but it's easier if it's all
merged through netdev to avoid dependencies.

Major highlights are jumbo frame support and ethtool basics, the rest
is mostly minor plumbing around it.

-- 

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

* [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib
  2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
@ 2008-02-21  2:57 ` Olof Johansson
  2008-02-26 11:46   ` Michael Ellerman
  2008-02-21  2:57 ` [patch 2/6] [POWERPC] pasemi: Add flag management functions " Olof Johansson
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

Also stop both rx and tx sections before changing the configuration of
the dma device during init.

Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/dma_lib.c
+++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -478,6 +478,30 @@ int pasemi_dma_init(void)
 	for (i = 0; i < MAX_RXCH; i++)
 		__set_bit(i, rxch_free);
 
+	i = 1000;
+	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
+	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1))
+		i--;
+	if (i < 0)
+		printk(KERN_INFO "Warning: Could not disable RX section\n");
+
+	i = 1000;
+	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
+	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1))
+		i--;
+	if (i < 0)
+		printk(KERN_INFO "Warning: Could not disable TX section\n");
+
+	/* setup resource allocations for the different DMA sections */
+	tmp = pasemi_read_dma_reg(PAS_DMA_COM_CFG);
+	pasemi_write_dma_reg(PAS_DMA_COM_CFG, tmp | 0x18000000);
+
+	/* enable tx section */
+	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
+
+	/* enable rx section */
+	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
+
 	printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
 		"(%d tx, %d rx channels)\n", num_txch, num_rxch);
 
Index: k.org/drivers/net/pasemi_mac.c
===================================================================
--- k.org.orig/drivers/net/pasemi_mac.c
+++ k.org/drivers/net/pasemi_mac.c
@@ -1043,12 +1043,6 @@ static int pasemi_mac_open(struct net_de
 	unsigned int flags;
 	int ret;
 
-	/* enable rx section */
-	write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
-
-	/* enable tx section */
-	write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
-
 	flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
 		PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
 		PAS_MAC_CFG_TXP_TIFT(8) | PAS_MAC_CFG_TXP_TIFG(12);
Index: k.org/include/asm-powerpc/pasemi_dma.h
===================================================================
--- k.org.orig/include/asm-powerpc/pasemi_dma.h
+++ k.org/include/asm-powerpc/pasemi_dma.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 PA Semi, Inc
+ * Copyright (C) 2006-2008 PA Semi, Inc
  *
  * Hardware register layout and descriptor formats for the on-board
  * DMA engine on PA Semi PWRficient. Used by ethernet, function and security
@@ -40,6 +40,11 @@ enum {
 	PAS_DMA_COM_TXSTA = 0x104,	/* Transmit Status Register   */
 	PAS_DMA_COM_RXCMD = 0x108,	/* Receive Command Register   */
 	PAS_DMA_COM_RXSTA = 0x10c,	/* Receive Status Register    */
+	PAS_DMA_COM_CFG   = 0x114,	/* Common config reg	      */
+	PAS_DMA_TXF_SFLG0 = 0x140,	/* Set flags                  */
+	PAS_DMA_TXF_SFLG1 = 0x144,	/* Set flags                  */
+	PAS_DMA_TXF_CFLG0 = 0x148,	/* Set flags                  */
+	PAS_DMA_TXF_CFLG1 = 0x14c,	/* Set flags                  */
 };
 
 

-- 

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

* [patch 2/6] [POWERPC] pasemi: Add flag management functions to dma_lib
  2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
  2008-02-21  2:57 ` [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib Olof Johansson
@ 2008-02-21  2:57 ` Olof Johansson
  2008-02-21  2:57 ` [patch 3/6] [POWERPC] pasemi: Add function engine " Olof Johansson
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

Add functions to manage the channel syncronization flags to dma_lib
    
Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/dma_lib.c
+++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -26,6 +26,7 @@
 
 #define MAX_TXCH 64
 #define MAX_RXCH 64
+#define MAX_FLAGS 64
 
 static struct pasdma_status *dma_status;
 
@@ -43,6 +44,7 @@ static struct pci_dev *dma_pdev;
 
 static DECLARE_BITMAP(txch_free, MAX_TXCH);
 static DECLARE_BITMAP(rxch_free, MAX_RXCH);
+static DECLARE_BITMAP(flags_free, MAX_FLAGS);
 
 /* pasemi_read_iob_reg - read IOB register
  * @reg: Register to read (offset into PCI CFG space)
@@ -373,6 +375,71 @@ void pasemi_dma_free_buf(struct pasemi_d
 }
 EXPORT_SYMBOL(pasemi_dma_free_buf);
 
+/* pasemi_dma_alloc_flag - Allocate a flag (event) for channel syncronization
+ *
+ * Allocates a flag for use with channel syncronization (event descriptors).
+ * Returns allocated flag (0-63), < 0 on error.
+ */
+int pasemi_dma_alloc_flag(void)
+{
+	int bit;
+
+retry:
+	bit = find_next_bit(flags_free, MAX_FLAGS, 0);
+	if (bit >= MAX_FLAGS)
+		return -ENOSPC;
+	if (!test_and_clear_bit(bit, flags_free))
+		goto retry;
+
+	return bit;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_flag);
+
+
+/* pasemi_dma_free_flag - Deallocates a flag (event)
+ * @flag: Flag number to deallocate
+ *
+ * Frees up a flag so it can be reused for other purposes.
+ */
+void pasemi_dma_free_flag(int flag)
+{
+	BUG_ON(test_bit(flag, flags_free));
+	BUG_ON(flag >= MAX_FLAGS);
+	set_bit(flag, flags_free);
+}
+EXPORT_SYMBOL(pasemi_dma_free_flag);
+
+
+/* pasemi_dma_set_flag - Sets a flag (event) to 1
+ * @flag: Flag number to set active
+ *
+ * Sets the flag provided to 1.
+ */
+void pasemi_dma_set_flag(int flag)
+{
+	BUG_ON(flag >= MAX_FLAGS);
+	if (flag < 32)
+		pasemi_write_dma_reg(PAS_DMA_TXF_SFLG0, 1 << flag);
+	else
+		pasemi_write_dma_reg(PAS_DMA_TXF_SFLG1, 1 << flag);
+}
+EXPORT_SYMBOL(pasemi_dma_set_flag);
+
+/* pasemi_dma_clear_flag - Sets a flag (event) to 0
+ * @flag: Flag number to set inactive
+ *
+ * Sets the flag provided to 0.
+ */
+void pasemi_dma_clear_flag(int flag)
+{
+	BUG_ON(flag >= MAX_FLAGS);
+	if (flag < 32)
+		pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 1 << flag);
+	else
+		pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 1 << flag);
+}
+EXPORT_SYMBOL(pasemi_dma_clear_flag);
+
 static void *map_onedev(struct pci_dev *p, int index)
 {
 	struct device_node *dn;
@@ -502,6 +569,13 @@ int pasemi_dma_init(void)
 	/* enable rx section */
 	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
 
+	for (i = 0; i < MAX_FLAGS; i++)
+		__set_bit(i, flags_free);
+
+	/* clear all status flags */
+	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff);
+	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff);
+
 	printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
 		"(%d tx, %d rx channels)\n", num_txch, num_rxch);
 
Index: k.org/include/asm-powerpc/pasemi_dma.h
===================================================================
--- k.org.orig/include/asm-powerpc/pasemi_dma.h
+++ k.org/include/asm-powerpc/pasemi_dma.h
@@ -466,6 +466,12 @@ extern void *pasemi_dma_alloc_buf(struct
 extern void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
 				dma_addr_t *handle);
 
+/* Routines to allocate flags (events) for channel syncronization */
+extern int  pasemi_dma_alloc_flag(void);
+extern void pasemi_dma_free_flag(int flag);
+extern void pasemi_dma_set_flag(int flag);
+extern void pasemi_dma_clear_flag(int flag);
+
 /* Initialize the library, must be called before any other functions */
 extern int pasemi_dma_init(void);
 

-- 

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

* [patch 3/6] [POWERPC] pasemi: Add function engine management functions to dma_lib
  2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
  2008-02-21  2:57 ` [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib Olof Johansson
  2008-02-21  2:57 ` [patch 2/6] [POWERPC] pasemi: Add flag management functions " Olof Johansson
@ 2008-02-21  2:57 ` Olof Johansson
  2008-02-21  2:57 ` [patch 4/6] pasemi_mac: jumbo frame support Olof Johansson
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

Used to allocate functions for crypto/checksum offload.
    
Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/dma_lib.c
+++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -27,6 +27,7 @@
 #define MAX_TXCH 64
 #define MAX_RXCH 64
 #define MAX_FLAGS 64
+#define MAX_FUN 8
 
 static struct pasdma_status *dma_status;
 
@@ -45,6 +46,7 @@ static struct pci_dev *dma_pdev;
 static DECLARE_BITMAP(txch_free, MAX_TXCH);
 static DECLARE_BITMAP(rxch_free, MAX_RXCH);
 static DECLARE_BITMAP(flags_free, MAX_FLAGS);
+static DECLARE_BITMAP(fun_free, MAX_FUN);
 
 /* pasemi_read_iob_reg - read IOB register
  * @reg: Register to read (offset into PCI CFG space)
@@ -440,6 +442,41 @@ void pasemi_dma_clear_flag(int flag)
 }
 EXPORT_SYMBOL(pasemi_dma_clear_flag);
 
+/* pasemi_dma_alloc_fun - Allocate a function engine
+ *
+ * Allocates a function engine to use for crypto/checksum offload
+ * Returns allocated engine (0-8), < 0 on error.
+ */
+int pasemi_dma_alloc_fun(void)
+{
+	int bit;
+
+retry:
+	bit = find_next_bit(fun_free, MAX_FLAGS, 0);
+	if (bit >= MAX_FLAGS)
+		return -ENOSPC;
+	if (!test_and_clear_bit(bit, fun_free))
+		goto retry;
+
+	return bit;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_fun);
+
+
+/* pasemi_dma_free_fun - Deallocates a function engine
+ * @flag: Engine number to deallocate
+ *
+ * Frees up a function engine so it can be used for other purposes.
+ */
+void pasemi_dma_free_fun(int fun)
+{
+	BUG_ON(test_bit(fun, fun_free));
+	BUG_ON(fun >= MAX_FLAGS);
+	set_bit(fun, fun_free);
+}
+EXPORT_SYMBOL(pasemi_dma_free_fun);
+
+
 static void *map_onedev(struct pci_dev *p, int index)
 {
 	struct device_node *dn;
@@ -572,6 +609,9 @@ int pasemi_dma_init(void)
 	for (i = 0; i < MAX_FLAGS; i++)
 		__set_bit(i, flags_free);
 
+	for (i = 0; i < MAX_FUN; i++)
+		__set_bit(i, fun_free);
+
 	/* clear all status flags */
 	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff);
 	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff);
Index: k.org/include/asm-powerpc/pasemi_dma.h
===================================================================
--- k.org.orig/include/asm-powerpc/pasemi_dma.h
+++ k.org/include/asm-powerpc/pasemi_dma.h
@@ -472,6 +472,10 @@ extern void pasemi_dma_free_flag(int fla
 extern void pasemi_dma_set_flag(int flag);
 extern void pasemi_dma_clear_flag(int flag);
 
+/* Routines to allocate function engines */
+extern int  pasemi_dma_alloc_fun(void);
+extern void pasemi_dma_free_fun(int fun);
+
 /* Initialize the library, must be called before any other functions */
 extern int pasemi_dma_init(void);
 

-- 

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

* [patch 4/6] pasemi_mac: jumbo frame support
  2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
                   ` (2 preceding siblings ...)
  2008-02-21  2:57 ` [patch 3/6] [POWERPC] pasemi: Add function engine " Olof Johansson
@ 2008-02-21  2:57 ` Olof Johansson
  2008-02-21  2:57 ` [patch 5/6] pasemi_mac: Enable GSO by default Olof Johansson
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

First cut at jumbo frame support. To support large MTU, one or several
separate channels must be allocated to calculate the TCP/UDP checksum
separately, since the mac lacks enough buffers to hold a whole packet
while it's being calculated.

Furthermore, it seems that a single function channel is not quite
enough to feed one of the 10Gig links, so allocate two channels for
XAUI interfaces.

Signed-off-by: Olof Johansson <olof@lixom.net>

Index: 2.6.25/drivers/net/pasemi_mac.c
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.c
+++ 2.6.25/drivers/net/pasemi_mac.c
@@ -59,11 +59,12 @@
 /* Must be a power of two */
 #define RX_RING_SIZE 2048
 #define TX_RING_SIZE 4096
+#define CS_RING_SIZE (TX_RING_SIZE*2)
 
 #define LRO_MAX_AGGR 64
 
 #define PE_MIN_MTU	64
-#define PE_MAX_MTU	1500
+#define PE_MAX_MTU	9000
 #define PE_DEF_MTU	ETH_DATA_LEN
 
 #define DEFAULT_MSG_ENABLE	  \
@@ -81,6 +82,7 @@
 #define RX_DESC(rx, num)	((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
 #define RX_DESC_INFO(rx, num)	((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
 #define RX_BUFF(rx, num)	((rx)->buffers[(num) & (RX_RING_SIZE-1)])
+#define CS_DESC(cs, num)	((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)])
 
 #define RING_USED(ring)		(((ring)->next_to_fill - (ring)->next_to_clean) \
 				 & ((ring)->size - 1))
@@ -322,6 +324,103 @@ static int pasemi_mac_unmap_tx_skb(struc
 	return (nfrags + 3) & ~1;
 }
 
+static struct pasemi_mac_csring *pasemi_mac_setup_csring(struct pasemi_mac *mac)
+{
+	struct pasemi_mac_csring *ring;
+	u32 val;
+	unsigned int cfg;
+	int chno;
+
+	ring = pasemi_dma_alloc_chan(TXCHAN, sizeof(struct pasemi_mac_csring),
+				       offsetof(struct pasemi_mac_csring, chan));
+
+	if (!ring) {
+		dev_err(&mac->pdev->dev, "Can't allocate checksum channel\n");
+		goto out_chan;
+	}
+
+	chno = ring->chan.chno;
+
+	ring->size = CS_RING_SIZE;
+	ring->next_to_fill = 0;
+
+	/* Allocate descriptors */
+	if (pasemi_dma_alloc_ring(&ring->chan, CS_RING_SIZE))
+		goto out_ring_desc;
+
+	write_dma_reg(PAS_DMA_TXCHAN_BASEL(chno),
+		      PAS_DMA_TXCHAN_BASEL_BRBL(ring->chan.ring_dma));
+	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32);
+	val |= PAS_DMA_TXCHAN_BASEU_SIZ(CS_RING_SIZE >> 3);
+
+	write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val);
+
+	ring->events[0] = pasemi_dma_alloc_flag();
+	ring->events[1] = pasemi_dma_alloc_flag();
+	if (ring->events[0] < 0 || ring->events[1] < 0)
+		goto out_flags;
+
+	pasemi_dma_clear_flag(ring->events[0]);
+	pasemi_dma_clear_flag(ring->events[1]);
+
+	ring->fun = pasemi_dma_alloc_fun();
+	if (ring->fun < 0)
+		goto out_fun;
+
+	cfg = PAS_DMA_TXCHAN_CFG_TY_FUNC | PAS_DMA_TXCHAN_CFG_UP |
+	      PAS_DMA_TXCHAN_CFG_TATTR(ring->fun) |
+	      PAS_DMA_TXCHAN_CFG_LPSQ | PAS_DMA_TXCHAN_CFG_LPDQ;
+
+	if (translation_enabled())
+		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
+
+	write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg);
+
+	/* enable channel */
+	pasemi_dma_start_chan(&ring->chan, PAS_DMA_TXCHAN_TCMDSTA_SZ |
+					   PAS_DMA_TXCHAN_TCMDSTA_DB |
+					   PAS_DMA_TXCHAN_TCMDSTA_DE |
+					   PAS_DMA_TXCHAN_TCMDSTA_DA);
+
+	return ring;
+
+out_fun:
+out_flags:
+	if (ring->events[0] >= 0)
+		pasemi_dma_free_flag(ring->events[0]);
+	if (ring->events[1] >= 0)
+		pasemi_dma_free_flag(ring->events[1]);
+	pasemi_dma_free_ring(&ring->chan);
+out_ring_desc:
+	pasemi_dma_free_chan(&ring->chan);
+out_chan:
+
+	return NULL;
+}
+
+static void pasemi_mac_setup_csrings(struct pasemi_mac *mac)
+{
+	int i;
+	mac->cs[0] = pasemi_mac_setup_csring(mac);
+	if (mac->type == MAC_TYPE_XAUI)
+		mac->cs[1] = pasemi_mac_setup_csring(mac);
+	else
+		mac->cs[1] = 0;
+
+	for (i = 0; i < MAX_CS; i++)
+		if (mac->cs[i])
+			mac->num_cs++;
+}
+
+static void pasemi_mac_free_csring(struct pasemi_mac_csring *csring)
+{
+	pasemi_dma_stop_chan(&csring->chan);
+	pasemi_dma_free_flag(csring->events[0]);
+	pasemi_dma_free_flag(csring->events[1]);
+	pasemi_dma_free_ring(&csring->chan);
+	pasemi_dma_free_chan(&csring->chan);
+}
+
 static int pasemi_mac_setup_rx_resources(const struct net_device *dev)
 {
 	struct pasemi_mac_rxring *ring;
@@ -445,7 +544,7 @@ pasemi_mac_setup_tx_resources(const stru
 	cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
 	      PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
 	      PAS_DMA_TXCHAN_CFG_UP |
-	      PAS_DMA_TXCHAN_CFG_WT(2);
+	      PAS_DMA_TXCHAN_CFG_WT(4);
 
 	if (translation_enabled())
 		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
@@ -810,13 +909,21 @@ restart:
 		u64 mactx = TX_DESC(txring, i);
 		struct sk_buff *skb;
 
-		skb = TX_DESC_INFO(txring, i+1).skb;
-		nr_frags = TX_DESC_INFO(txring, i).dma;
-
 		if ((mactx  & XCT_MACTX_E) ||
 		    (*chan->status & PAS_STATUS_ERROR))
 			pasemi_mac_tx_error(mac, mactx);
 
+		/* Skip over control descriptors */
+		if (!(mactx & XCT_MACTX_LLEN_M)) {
+			TX_DESC(txring, i) = 0;
+			TX_DESC(txring, i+1) = 0;
+			buf_count = 2;
+			continue;
+		}
+
+		skb = TX_DESC_INFO(txring, i+1).skb;
+		nr_frags = TX_DESC_INFO(txring, i).dma;
+
 		if (unlikely(mactx & XCT_MACTX_O))
 			/* Not yet transmitted */
 			break;
@@ -1058,6 +1165,12 @@ static int pasemi_mac_open(struct net_de
 	if (!mac->tx)
 		goto out_tx_ring;
 
+	if (dev->mtu > 1500) {
+		pasemi_mac_setup_csrings(mac);
+		if (!mac->num_cs)
+			goto out_tx_ring;
+	}
+
 	/* 0x3ff with 33MHz clock is about 31us */
 	write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
 		      PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));
@@ -1241,7 +1354,7 @@ static int pasemi_mac_close(struct net_d
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int sta;
-	int rxch, txch;
+	int rxch, txch, i;
 
 	rxch = rx_ring(mac)->chan.chno;
 	txch = tx_ring(mac)->chan.chno;
@@ -1286,6 +1399,9 @@ static int pasemi_mac_close(struct net_d
 	free_irq(mac->tx->chan.irq, mac->tx);
 	free_irq(mac->rx->chan.irq, mac->rx);
 
+	for (i = 0; i < mac->num_cs; i++)
+		pasemi_mac_free_csring(mac->cs[i]);
+
 	/* Free resources */
 	pasemi_mac_free_rx_resources(mac);
 	pasemi_mac_free_tx_resources(mac);
@@ -1293,35 +1409,113 @@ static int pasemi_mac_close(struct net_d
 	return 0;
 }
 
+static void pasemi_mac_queue_csdesc(const struct sk_buff *skb,
+				    const dma_addr_t *map,
+				    const unsigned int *map_size,
+				    struct pasemi_mac_txring *txring,
+				    struct pasemi_mac_csring *csring)
+{
+	u64 fund;
+	dma_addr_t cs_dest;
+	const int nh_off = skb_network_offset(skb);
+	const int nh_len = skb_network_header_len(skb);
+	const int nfrags = skb_shinfo(skb)->nr_frags;
+	int cs_size, i, fill, hdr, cpyhdr, evt;
+	dma_addr_t csdma;
+
+	fund = XCT_FUN_ST | XCT_FUN_RR_8BRES |
+	       XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
+	       XCT_FUN_CRM_SIG | XCT_FUN_LLEN(skb->len - nh_off) |
+	       XCT_FUN_SHL(nh_len >> 2) | XCT_FUN_SE;
+
+	switch (ip_hdr(skb)->protocol) {
+	case IPPROTO_TCP:
+		fund |= XCT_FUN_SIG_TCP4;
+		/* TCP checksum is 16 bytes into the header */
+		cs_dest = map[0] + skb_transport_offset(skb) + 16;
+		break;
+	case IPPROTO_UDP:
+		fund |= XCT_FUN_SIG_UDP4;
+		/* UDP checksum is 6 bytes into the header */
+		cs_dest = map[0] + skb_transport_offset(skb) + 6;
+		break;
+	default:
+		WARN_ON(1);
+	}
+
+	/* Do the checksum offloaded */
+	fill = csring->next_to_fill;
+	hdr = fill;
+
+	CS_DESC(csring, fill++) = fund;
+	/* Room for 8BRES. Checksum result is really 2 bytes into it */
+	csdma = csring->chan.ring_dma + (fill & (CS_RING_SIZE-1)) * 8 + 2;
+	CS_DESC(csring, fill++) = 0;
+
+	CS_DESC(csring, fill) = XCT_PTR_LEN(map_size[0]-nh_off) | XCT_PTR_ADDR(map[0]+nh_off);
+	for (i = 1; i <= nfrags; i++)
+		CS_DESC(csring, fill+i) = XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
+
+	fill += i;
+	if (fill & 1)
+		fill++;
+
+	/* Copy the result into the TCP packet */
+	cpyhdr = fill;
+	CS_DESC(csring, fill++) = XCT_FUN_O | XCT_FUN_FUN(csring->fun) |
+				  XCT_FUN_LLEN(2) | XCT_FUN_SE;
+	CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(cs_dest) | XCT_PTR_T;
+	CS_DESC(csring, fill++) = XCT_PTR_LEN(2) | XCT_PTR_ADDR(csdma);
+	fill++;
+
+	evt = !csring->last_event;
+	csring->last_event = evt;
+
+	/* Event handshaking with MAC TX */
+	CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_SET | CTRL_CMD_REG(csring->events[evt]);
+	CS_DESC(csring, fill++) = 0;
+	CS_DESC(csring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_WCLR | CTRL_CMD_REG(csring->events[!evt]);
+	CS_DESC(csring, fill++) = 0;
+	csring->next_to_fill = fill & (CS_RING_SIZE-1);
+
+	cs_size = fill - hdr;
+	write_dma_reg(PAS_DMA_TXCHAN_INCR(csring->chan.chno), (cs_size) >> 1);
+
+	/* TX-side event handshaking */
+	fill = txring->next_to_fill;
+	TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_WSET | CTRL_CMD_REG(csring->events[evt]);
+	TX_DESC(txring, fill++) = 0;
+	TX_DESC(txring, fill++) = CTRL_CMD_T | CTRL_CMD_META_EVT | CTRL_CMD_O |
+				  CTRL_CMD_ETYPE_CLR | CTRL_CMD_REG(csring->events[!evt]);
+	TX_DESC(txring, fill++) = 0;
+	txring->next_to_fill = fill;
+
+	write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2);
+
+	return;
+}
+
 static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct pasemi_mac *mac = netdev_priv(dev);
-	struct pasemi_mac_txring *txring;
-	u64 dflags, mactx;
+	struct pasemi_mac * const mac = netdev_priv(dev);
+	struct pasemi_mac_txring * const txring = tx_ring(mac);
+	struct pasemi_mac_csring *csring;
+	u64 dflags = 0;
+	u64 mactx;
 	dma_addr_t map[MAX_SKB_FRAGS+1];
 	unsigned int map_size[MAX_SKB_FRAGS+1];
 	unsigned long flags;
 	int i, nfrags;
 	int fill;
+	const int nh_off = skb_network_offset(skb);
+	const int nh_len = skb_network_header_len(skb);
 
-	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
-
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		const unsigned char *nh = skb_network_header(skb);
+	prefetch(&txring->ring_info);
 
-		switch (ip_hdr(skb)->protocol) {
-		case IPPROTO_TCP:
-			dflags |= XCT_MACTX_CSUM_TCP;
-			dflags |= XCT_MACTX_IPH(skb_network_header_len(skb) >> 2);
-			dflags |= XCT_MACTX_IPO(nh - skb->data);
-			break;
-		case IPPROTO_UDP:
-			dflags |= XCT_MACTX_CSUM_UDP;
-			dflags |= XCT_MACTX_IPH(skb_network_header_len(skb) >> 2);
-			dflags |= XCT_MACTX_IPO(nh - skb->data);
-			break;
-		}
-	}
+	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
 
 	nfrags = skb_shinfo(skb)->nr_frags;
 
@@ -1344,24 +1538,46 @@ static int pasemi_mac_start_tx(struct sk
 		}
 	}
 
-	mactx = dflags | XCT_MACTX_LLEN(skb->len);
+	if (skb->ip_summed == CHECKSUM_PARTIAL && skb->len <= 1540) {
+		switch (ip_hdr(skb)->protocol) {
+		case IPPROTO_TCP:
+			dflags |= XCT_MACTX_CSUM_TCP;
+			dflags |= XCT_MACTX_IPH(nh_len >> 2);
+			dflags |= XCT_MACTX_IPO(nh_off);
+			break;
+		case IPPROTO_UDP:
+			dflags |= XCT_MACTX_CSUM_UDP;
+			dflags |= XCT_MACTX_IPH(nh_len >> 2);
+			dflags |= XCT_MACTX_IPO(nh_off);
+			break;
+		default:
+			WARN_ON(1);
+		}
+	}
 
-	txring = tx_ring(mac);
+	mactx = dflags | XCT_MACTX_LLEN(skb->len);
 
 	spin_lock_irqsave(&txring->lock, flags);
 
-	fill = txring->next_to_fill;
-
 	/* Avoid stepping on the same cache line that the DMA controller
 	 * is currently about to send, so leave at least 8 words available.
 	 * Total free space needed is mactx + fragments + 8
 	 */
-	if (RING_AVAIL(txring) < nfrags + 10) {
+	if (RING_AVAIL(txring) < nfrags + 14) {
 		/* no room -- stop the queue and wait for tx intr */
 		netif_stop_queue(dev);
 		goto out_err;
 	}
 
+	if (mac->num_cs && skb->len > 1540) {
+		csring = mac->cs[mac->last_cs];
+		mac->last_cs = (mac->last_cs+1) % mac->num_cs;
+
+		/* Queue up checksum + event descriptors, if needed */
+		pasemi_mac_queue_csdesc(skb, map, map_size, txring, csring);
+	}
+
+	fill = txring->next_to_fill;
 	TX_DESC(txring, fill) = mactx;
 	TX_DESC_INFO(txring, fill).dma = nfrags;
 	fill++;
@@ -1441,6 +1657,7 @@ static int pasemi_mac_change_mtu(struct 
 	unsigned int reg;
 	unsigned int rcmdsta;
 	int running;
+	int ret = 0;
 
 	if (new_mtu < PE_MIN_MTU || new_mtu > PE_MAX_MTU)
 		return -EINVAL;
@@ -1462,6 +1679,16 @@ static int pasemi_mac_change_mtu(struct 
 		pasemi_mac_pause_rxint(mac);
 		pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
 		pasemi_mac_free_rx_buffers(mac);
+
+	}
+
+	/* Setup checksum channels if large MTU and none already allocated */
+	if (new_mtu > 1500 && !mac->num_cs) {
+		pasemi_mac_setup_csrings(mac);
+		if (!mac->num_cs) {
+			ret = -ENOMEM;
+			goto out;
+		}
 	}
 
 	/* Change maxf, i.e. what size frames are accepted.
@@ -1476,6 +1703,7 @@ static int pasemi_mac_change_mtu(struct 
 	/* MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
 	mac->bufsz = new_mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
 
+out:
 	if (running) {
 		write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
 			      rcmdsta | PAS_DMA_RXINT_RCMDSTA_EN);
@@ -1488,7 +1716,7 @@ static int pasemi_mac_change_mtu(struct 
 		pasemi_mac_intf_enable(mac);
 	}
 
-	return 0;
+	return ret;
 }
 
 static int __devinit
Index: 2.6.25/drivers/net/pasemi_mac.h
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.h
+++ 2.6.25/drivers/net/pasemi_mac.h
@@ -27,6 +27,7 @@
 #include <linux/phy.h>
 
 #define MAX_LRO_DESCRIPTORS 8
+#define MAX_CS	2
 
 struct pasemi_mac_txring {
 	struct pasemi_dmachan chan; /* Must be first */
@@ -51,6 +52,15 @@ struct pasemi_mac_rxring {
 	struct pasemi_mac *mac;	/* Needed in intr handler */
 };
 
+struct pasemi_mac_csring {
+	struct pasemi_dmachan chan;
+	unsigned int	size;
+	unsigned int	next_to_fill;
+	int		events[2];
+	int		last_event;
+	int		fun;
+};
+
 struct pasemi_mac {
 	struct net_device *netdev;
 	struct pci_dev *pdev;
@@ -60,10 +70,12 @@ struct pasemi_mac {
 	struct napi_struct napi;
 
 	int		bufsz; /* RX ring buffer size */
+	int		last_cs;
+	int		num_cs;
+	u32		dma_if;
 	u8		type;
 #define MAC_TYPE_GMAC	1
 #define MAC_TYPE_XAUI	2
-	u32	dma_if;
 
 	u8		mac_addr[6];
 
@@ -74,6 +86,7 @@ struct pasemi_mac {
 
 	struct pasemi_mac_txring *tx;
 	struct pasemi_mac_rxring *rx;
+	struct pasemi_mac_csring *cs[MAX_CS];
 	char		tx_irq_name[10];		/* "eth%d tx" */
 	char		rx_irq_name[10];		/* "eth%d rx" */
 	int	link;
Index: 2.6.25/include/asm-powerpc/pasemi_dma.h
===================================================================
--- 2.6.25.orig/include/asm-powerpc/pasemi_dma.h
+++ 2.6.25/include/asm-powerpc/pasemi_dma.h
@@ -128,11 +128,16 @@ enum {
 #define    PAS_DMA_TXCHAN_TCMDSTA_DA	0x00000100
 #define PAS_DMA_TXCHAN_CFG(c)     (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
 #define    PAS_DMA_TXCHAN_CFG_TY_IFACE	0x00000000	/* Type = interface */
+#define    PAS_DMA_TXCHAN_CFG_TY_COPY	0x00000001	/* Type = copy only */
+#define    PAS_DMA_TXCHAN_CFG_TY_FUNC	0x00000002	/* Type = function */
+#define    PAS_DMA_TXCHAN_CFG_TY_XOR	0x00000003	/* Type = xor only */
 #define    PAS_DMA_TXCHAN_CFG_TATTR_M	0x0000003c
 #define    PAS_DMA_TXCHAN_CFG_TATTR_S	2
 #define    PAS_DMA_TXCHAN_CFG_TATTR(x)	(((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
 					 PAS_DMA_TXCHAN_CFG_TATTR_M)
-#define    PAS_DMA_TXCHAN_CFG_WT_M	0x000001c0
+#define    PAS_DMA_TXCHAN_CFG_LPDQ	0x00000800
+#define    PAS_DMA_TXCHAN_CFG_LPSQ	0x00000400
+#define    PAS_DMA_TXCHAN_CFG_WT_M	0x000003c0
 #define    PAS_DMA_TXCHAN_CFG_WT_S	6
 #define    PAS_DMA_TXCHAN_CFG_WT(x)	(((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
 					 PAS_DMA_TXCHAN_CFG_WT_M)
@@ -399,11 +404,62 @@ enum {
 				 XCT_COPY_LLEN_M)
 #define XCT_COPY_SE		0x0000000000000001ull
 
+/* Function descriptor fields */
+#define XCT_FUN_T		0x8000000000000000ull
+#define XCT_FUN_ST		0x4000000000000000ull
+#define XCT_FUN_RR_M		0x3000000000000000ull
+#define XCT_FUN_RR_NORES	0x0000000000000000ull
+#define XCT_FUN_RR_8BRES	0x1000000000000000ull
+#define XCT_FUN_RR_24BRES	0x2000000000000000ull
+#define XCT_FUN_RR_40BRES	0x3000000000000000ull
+#define XCT_FUN_I		0x0800000000000000ull
+#define XCT_FUN_O		0x0400000000000000ull
+#define XCT_FUN_E		0x0200000000000000ull
+#define XCT_FUN_FUN_M		0x01c0000000000000ull
+#define XCT_FUN_FUN_S		54
+#define XCT_FUN_FUN(x)		((((long)(x)) << XCT_FUN_FUN_S) & XCT_FUN_FUN_M)
+#define XCT_FUN_CRM_M		0x0038000000000000ull
+#define XCT_FUN_CRM_NOP		0x0000000000000000ull
+#define XCT_FUN_CRM_SIG		0x0008000000000000ull
+#define XCT_FUN_LLEN_M		0x0007ffff00000000ull
+#define XCT_FUN_LLEN_S		32
+#define XCT_FUN_LLEN(x)		((((long)(x)) << XCT_FUN_LLEN_S) & XCT_FUN_LLEN_M)
+#define XCT_FUN_SHL_M		0x00000000f8000000ull
+#define XCT_FUN_SHL_S		27
+#define XCT_FUN_SHL(x)		((((long)(x)) << XCT_FUN_SHL_S) & XCT_FUN_SHL_M)
+#define XCT_FUN_CHL_M		0x0000000007c00000ull
+#define XCT_FUN_HSZ_M		0x00000000003c0000ull
+#define XCT_FUN_ALG_M		0x0000000000038000ull
+#define XCT_FUN_HP		0x0000000000004000ull
+#define XCT_FUN_BCM_M		0x0000000000003800ull
+#define XCT_FUN_BCP_M		0x0000000000000600ull
+#define XCT_FUN_SIG_M		0x00000000000001f0ull
+#define XCT_FUN_SIG_TCP4	0x0000000000000140ull
+#define XCT_FUN_SIG_TCP6	0x0000000000000150ull
+#define XCT_FUN_SIG_UDP4	0x0000000000000160ull
+#define XCT_FUN_SIG_UDP6	0x0000000000000170ull
+#define XCT_FUN_A		0x0000000000000008ull
+#define XCT_FUN_C		0x0000000000000004ull
+#define XCT_FUN_AL2		0x0000000000000002ull
+#define XCT_FUN_SE		0x0000000000000001ull
+
+/* Function descriptor 8byte result fields */
+#define XCT_FUNRES_8B_CS_M	0x0000ffff00000000ull
+#define XCT_FUNRES_8B_CS_S	32
+#define XCT_FUNRES_8B_CRC_M	0x00000000ffffffffull
+#define XCT_FUNRES_8B_CRC_S	0
+
 /* Control descriptor fields */
 #define CTRL_CMD_T		0x8000000000000000ull
 #define CTRL_CMD_META_EVT	0x2000000000000000ull
 #define CTRL_CMD_O		0x0400000000000000ull
-#define CTRL_CMD_REG_M		0x000000000000000full
+#define CTRL_CMD_ETYPE_M	0x0038000000000000ull
+#define CTRL_CMD_ETYPE_EXT	0x0000000000000000ull
+#define CTRL_CMD_ETYPE_WSET	0x0020000000000000ull
+#define CTRL_CMD_ETYPE_WCLR	0x0028000000000000ull
+#define CTRL_CMD_ETYPE_SET	0x0030000000000000ull
+#define CTRL_CMD_ETYPE_CLR	0x0038000000000000ull
+#define CTRL_CMD_REG_M		0x000000000000007full
 #define CTRL_CMD_REG_S		0
 #define CTRL_CMD_REG(x)		((((long)(x)) << CTRL_CMD_REG_S) & \
 				 CTRL_CMD_REG_M)

-- 

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

* [patch 5/6] pasemi_mac: Enable GSO by default
  2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
                   ` (3 preceding siblings ...)
  2008-02-21  2:57 ` [patch 4/6] pasemi_mac: jumbo frame support Olof Johansson
@ 2008-02-21  2:57 ` Olof Johansson
  2008-02-21  2:57 ` [patch 6/6] pasemi_mac: basic ethtool support Olof Johansson
  2008-02-26  9:49 ` [patch 0/6] pasemi_mac updates for 2.6.26 Paul Mackerras
  6 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

Ethtool support will handle the runtime toggling, but we do quite a bit
better with it on by default so just leave it on for now.


Signed-off-by: Olof Johansson <olof@lixom.net>

Index: k.org/drivers/net/pasemi_mac.c
===================================================================
--- k.org.orig/drivers/net/pasemi_mac.c
+++ k.org/drivers/net/pasemi_mac.c
@@ -1750,7 +1750,7 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 	netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
 
 	dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG |
-			NETIF_F_HIGHDMA;
+			NETIF_F_HIGHDMA | NETIF_F_GSO;
 
 	mac->lro_mgr.max_aggr = LRO_MAX_AGGR;
 	mac->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;

-- 

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

* [patch 6/6] pasemi_mac: basic ethtool support
  2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
                   ` (4 preceding siblings ...)
  2008-02-21  2:57 ` [patch 5/6] pasemi_mac: Enable GSO by default Olof Johansson
@ 2008-02-21  2:57 ` Olof Johansson
  2008-02-26  9:49 ` [patch 0/6] pasemi_mac updates for 2.6.26 Paul Mackerras
  6 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2008-02-21  2:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, pasemi-linux, linuxppc-dev

First cut at ethtool support, to be completed over time.


Signed-off-by: Olof Johansson <olof@lixom.net>

Index: 2.6.25/drivers/net/Makefile
===================================================================
--- 2.6.25.orig/drivers/net/Makefile
+++ 2.6.25/drivers/net/Makefile
@@ -218,7 +218,8 @@ obj-$(CONFIG_SMC911X) += smc911x.o
 obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
 obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
-obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
+obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
+pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
 obj-$(CONFIG_ENC28J60) += enc28j60.o
 
Index: 2.6.25/drivers/net/pasemi_mac.c
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.c
+++ 2.6.25/drivers/net/pasemi_mac.c
@@ -55,12 +55,6 @@
  * - Multiqueue RX/TX
  */
 
-
-/* Must be a power of two */
-#define RX_RING_SIZE 2048
-#define TX_RING_SIZE 4096
-#define CS_RING_SIZE (TX_RING_SIZE*2)
-
 #define LRO_MAX_AGGR 64
 
 #define PE_MIN_MTU	64
@@ -77,17 +71,6 @@
 	 NETIF_MSG_RX_ERR	| \
 	 NETIF_MSG_TX_ERR)
 
-#define TX_DESC(tx, num)	((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)])
-#define TX_DESC_INFO(tx, num)	((tx)->ring_info[(num) & (TX_RING_SIZE-1)])
-#define RX_DESC(rx, num)	((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
-#define RX_DESC_INFO(rx, num)	((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
-#define RX_BUFF(rx, num)	((rx)->buffers[(num) & (RX_RING_SIZE-1)])
-#define CS_DESC(cs, num)	((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)])
-
-#define RING_USED(ring)		(((ring)->next_to_fill - (ring)->next_to_clean) \
-				 & ((ring)->size - 1))
-#define RING_AVAIL(ring)	((ring->size) - RING_USED(ring))
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
 MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
@@ -96,6 +79,8 @@ static int debug = -1;	/* -1 == use DEFA
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
 
+extern const struct ethtool_ops pasemi_mac_ethtool_ops;
+
 static int translation_enabled(void)
 {
 #if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
@@ -1148,7 +1133,7 @@ static int pasemi_mac_open(struct net_de
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int flags;
-	int ret;
+	int i, ret;
 
 	flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
 		PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
@@ -1171,6 +1156,10 @@ static int pasemi_mac_open(struct net_de
 			goto out_tx_ring;
 	}
 
+	/* Zero out rmon counters */
+	for (i = 0; i < 32; i++)
+		write_mac_reg(mac, PAS_MAC_RMON(i), 0);
+
 	/* 0x3ff with 33MHz clock is about 31us */
 	write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
 		      PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));
@@ -1812,6 +1801,7 @@ pasemi_mac_probe(struct pci_dev *pdev, c
 	mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
 
 	dev->change_mtu = pasemi_mac_change_mtu;
+	dev->ethtool_ops = &pasemi_mac_ethtool_ops;
 
 	if (err)
 		goto out;
Index: 2.6.25/drivers/net/pasemi_mac.h
===================================================================
--- 2.6.25.orig/drivers/net/pasemi_mac.h
+++ 2.6.25/drivers/net/pasemi_mac.h
@@ -26,6 +26,12 @@
 #include <linux/spinlock.h>
 #include <linux/phy.h>
 
+/* Must be a power of two */
+#define RX_RING_SIZE 2048
+#define TX_RING_SIZE 4096
+#define CS_RING_SIZE (TX_RING_SIZE*2)
+
+
 #define MAX_LRO_DESCRIPTORS 8
 #define MAX_CS	2
 
@@ -103,6 +109,16 @@ struct pasemi_mac_buffer {
 	dma_addr_t	dma;
 };
 
+#define TX_DESC(tx, num)	((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)])
+#define TX_DESC_INFO(tx, num)	((tx)->ring_info[(num) & (TX_RING_SIZE-1)])
+#define RX_DESC(rx, num)	((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
+#define RX_DESC_INFO(rx, num)	((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
+#define RX_BUFF(rx, num)	((rx)->buffers[(num) & (RX_RING_SIZE-1)])
+#define CS_DESC(cs, num)	((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)])
+
+#define RING_USED(ring)	(((ring)->next_to_fill - (ring)->next_to_clean) \
+				& ((ring)->size - 1))
+#define RING_AVAIL(ring)	((ring->size) - RING_USED(ring))
 
 /* PCI register offsets and formats */
 
@@ -114,6 +130,7 @@ enum {
 	PAS_MAC_CFG_ADR0 = 0x8c,
 	PAS_MAC_CFG_ADR1 = 0x90,
 	PAS_MAC_CFG_TXP = 0x98,
+	PAS_MAC_CFG_RMON = 0x100,
 	PAS_MAC_IPC_CHNL = 0x208,
 };
 
@@ -185,6 +202,8 @@ enum {
 #define PAS_MAC_CFG_TXP_TIFG(x)		(((x) << PAS_MAC_CFG_TXP_TIFG_S) & \
 					 PAS_MAC_CFG_TXP_TIFG_M)
 
+#define PAS_MAC_RMON(r)			(0x100+(r)*4)
+
 #define PAS_MAC_IPC_CHNL_DCHNO_M	0x003f0000
 #define PAS_MAC_IPC_CHNL_DCHNO_S	16
 #define PAS_MAC_IPC_CHNL_DCHNO(x)	(((x) << PAS_MAC_IPC_CHNL_DCHNO_S) & \
@@ -194,4 +213,5 @@ enum {
 #define PAS_MAC_IPC_CHNL_BCH(x)		(((x) << PAS_MAC_IPC_CHNL_BCH_S) & \
 					 PAS_MAC_IPC_CHNL_BCH_M)
 
+
 #endif /* PASEMI_MAC_H */
Index: 2.6.25/drivers/net/pasemi_mac_ethtool.c
===================================================================
--- /dev/null
+++ 2.6.25/drivers/net/pasemi_mac_ethtool.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2006-2008 PA Semi, Inc
+ *
+ * Ethtool hooks for the PA Semi PWRficient onchip 1G/10G Ethernet MACs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/inet_lro.h>
+
+#include <asm/pasemi_dma.h>
+#include "pasemi_mac.h"
+
+static struct {
+	const char str[ETH_GSTRING_LEN];
+} ethtool_stats_keys[] = {
+	{ "rx-drops" },
+	{ "rx-bytes" },
+	{ "rx-packets" },
+	{ "rx-broadcast-packets" },
+	{ "rx-multicast-packets" },
+	{ "rx-crc-errors" },
+	{ "rx-undersize-errors" },
+	{ "rx-oversize-errors" },
+	{ "rx-short-fragment-errors" },
+	{ "rx-jabber-errors" },
+	{ "rx-64-byte-packets" },
+	{ "rx-65-127-byte-packets" },
+	{ "rx-128-255-byte-packets" },
+	{ "rx-256-511-byte-packets" },
+	{ "rx-512-1023-byte-packets" },
+	{ "rx-1024-1518-byte-packets" },
+	{ "rx-pause-frames" },
+	{ "tx-bytes" },
+	{ "tx-packets" },
+	{ "tx-broadcast-packets" },
+	{ "tx-multicast-packets" },
+	{ "tx-collisions" },
+	{ "tx-late-collisions" },
+	{ "tx-excessive-collisions" },
+	{ "tx-crc-errors" },
+	{ "tx-undersize-errors" },
+	{ "tx-oversize-errors" },
+	{ "tx-64-byte-packets" },
+	{ "tx-65-127-byte-packets" },
+	{ "tx-128-255-byte-packets" },
+	{ "tx-256-511-byte-packets" },
+	{ "tx-512-1023-byte-packets" },
+	{ "tx-1024-1518-byte-packets" },
+};
+
+static int
+pasemi_mac_ethtool_get_settings(struct net_device *netdev,
+			       struct ethtool_cmd *cmd)
+{
+	struct pasemi_mac *mac = netdev_priv(netdev);
+	struct phy_device *phydev = mac->phydev;
+
+	return phy_ethtool_gset(phydev, cmd);
+}
+
+static void
+pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev,
+			       struct ethtool_drvinfo *drvinfo)
+{
+	struct pasemi_mac *mac;
+	mac = netdev_priv(netdev);
+
+	/* clear and fill out info */
+	memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
+	strncpy(drvinfo->driver, "pasemi_mac", 12);
+	strcpy(drvinfo->version, "N/A");
+	strcpy(drvinfo->fw_version, "N/A");
+	strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32);
+}
+
+static u32
+pasemi_mac_ethtool_get_msglevel(struct net_device *netdev)
+{
+	struct pasemi_mac *mac = netdev_priv(netdev);
+	return mac->msg_enable;
+}
+
+static void
+pasemi_mac_ethtool_set_msglevel(struct net_device *netdev,
+				u32 level)
+{
+	struct pasemi_mac *mac = netdev_priv(netdev);
+	mac->msg_enable = level;
+}
+
+
+static void
+pasemi_mac_ethtool_get_ringparam(struct net_device *netdev,
+				 struct ethtool_ringparam *ering)
+{
+	struct pasemi_mac *mac = netdev->priv;
+
+	ering->tx_max_pending = TX_RING_SIZE/2;
+	ering->tx_pending = RING_USED(mac->tx)/2;
+	ering->rx_max_pending = RX_RING_SIZE/4;
+	ering->rx_pending = RING_USED(mac->rx)/4;
+}
+
+static int pasemi_mac_get_sset_count(struct net_device *netdev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(ethtool_stats_keys);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void pasemi_mac_get_ethtool_stats(struct net_device *netdev,
+		struct ethtool_stats *stats, u64 *data)
+{
+	struct pasemi_mac *mac = netdev->priv;
+	int i;
+
+	data[0] = pasemi_read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if))
+			>> PAS_DMA_RXINT_RCMDSTA_DROPS_S;
+	for (i = 0; i < 32; i++)
+		data[1+i] = pasemi_read_mac_reg(mac->dma_if, PAS_MAC_RMON(i));
+}
+
+static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset,
+				   u8 *data)
+{
+	memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
+}
+
+const struct ethtool_ops pasemi_mac_ethtool_ops = {
+	.get_settings		= pasemi_mac_ethtool_get_settings,
+	.get_drvinfo		= pasemi_mac_ethtool_get_drvinfo,
+	.get_msglevel		= pasemi_mac_ethtool_get_msglevel,
+	.set_msglevel		= pasemi_mac_ethtool_set_msglevel,
+	.get_link		= ethtool_op_get_link,
+	.get_ringparam          = pasemi_mac_ethtool_get_ringparam,
+	.get_strings		= pasemi_mac_get_strings,
+	.get_sset_count		= pasemi_mac_get_sset_count,
+	.get_ethtool_stats	= pasemi_mac_get_ethtool_stats,
+};
+

-- 

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

* Re: [patch 0/6] pasemi_mac updates for 2.6.26
  2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
                   ` (5 preceding siblings ...)
  2008-02-21  2:57 ` [patch 6/6] pasemi_mac: basic ethtool support Olof Johansson
@ 2008-02-26  9:49 ` Paul Mackerras
  2008-02-26 14:16   ` Olof Johansson
  6 siblings, 1 reply; 15+ messages in thread
From: Paul Mackerras @ 2008-02-26  9:49 UTC (permalink / raw)
  To: Olof Johansson; +Cc: netdev, pasemi-linux, jgarzik, linuxppc-dev

Olof Johansson writes:

> Here's a set of updates for pasemi_mac for 2.6.26. Some of them touch
> the dma_lib in the platform code as well, but it's easier if it's all
> merged through netdev to avoid dependencies.
> 
> Major highlights are jumbo frame support and ethtool basics, the rest
> is mostly minor plumbing around it.

What route do you think these should take upstream?  I'm happy to take
them if Jeff is OK with that.

Paul.

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

* Re: [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib
  2008-02-21  2:57 ` [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib Olof Johansson
@ 2008-02-26 11:46   ` Michael Ellerman
  2008-02-26 14:14     ` Olof Johansson
  0 siblings, 1 reply; 15+ messages in thread
From: Michael Ellerman @ 2008-02-26 11:46 UTC (permalink / raw)
  To: Olof Johansson; +Cc: netdev, pasemi-linux, jgarzik, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1361 bytes --]

On Wed, 2008-02-20 at 20:57 -0600, Olof Johansson wrote:
> plain text document attachment (in-progress)
> Also stop both rx and tx sections before changing the configuration of
> the dma device during init.
> 
> Signed-off-by: Olof Johansson <olof@lixom.net>
> 
> Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
> ===================================================================
> --- k.org.orig/arch/powerpc/platforms/pasemi/dma_lib.c
> +++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
> @@ -478,6 +478,30 @@ int pasemi_dma_init(void)
>  	for (i = 0; i < MAX_RXCH; i++)
>  		__set_bit(i, rxch_free);
>  
> +	i = 1000;
> +	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
> +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1))
> +		i--;
> +	if (i < 0)
> +		printk(KERN_INFO "Warning: Could not disable RX section\n");
> +
> +	i = 1000;
> +	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
> +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1))
> +		i--;

This kind of caught my eye, is it still going to work when the next core
is twice as fast?

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib
  2008-02-26 11:46   ` Michael Ellerman
@ 2008-02-26 14:14     ` Olof Johansson
  2008-03-05 18:21       ` [Pasemi-linux] " Olof Johansson
  0 siblings, 1 reply; 15+ messages in thread
From: Olof Johansson @ 2008-02-26 14:14 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: netdev, pasemi-linux, jgarzik, linuxppc-dev

Hi,

On Tue, Feb 26, 2008 at 10:46:06PM +1100, Michael Ellerman wrote:
> On Wed, 2008-02-20 at 20:57 -0600, Olof Johansson wrote:
> > +	i = 1000;
> > +	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
> > +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1))
> > +		i--;
> > +	if (i < 0)
> > +		printk(KERN_INFO "Warning: Could not disable RX section\n");
> > +
> > +	i = 1000;
> > +	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
> > +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1))
> > +		i--;
> 
> This kind of caught my eye, is it still going to work when the next core
> is twice as fast?

Actually, I added the variable right before posting, I used to have an
infinite loop there while testing the patch. I've never seen it do more
than a few rounds, so I'm not that worried.

We already have a similar loop in the channel shutdown code, but it runs
a bit longer. I might bring that over instead. Thanks for pointing it
out.


-Olof

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

* Re: [patch 0/6] pasemi_mac updates for 2.6.26
  2008-02-26  9:49 ` [patch 0/6] pasemi_mac updates for 2.6.26 Paul Mackerras
@ 2008-02-26 14:16   ` Olof Johansson
  2008-02-26 18:21     ` Jeff Garzik
  0 siblings, 1 reply; 15+ messages in thread
From: Olof Johansson @ 2008-02-26 14:16 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: netdev, pasemi-linux, jgarzik, linuxppc-dev

On Tue, Feb 26, 2008 at 08:49:58PM +1100, Paul Mackerras wrote:
> Olof Johansson writes:
> 
> > Here's a set of updates for pasemi_mac for 2.6.26. Some of them touch
> > the dma_lib in the platform code as well, but it's easier if it's all
> > merged through netdev to avoid dependencies.
> > 
> > Major highlights are jumbo frame support and ethtool basics, the rest
> > is mostly minor plumbing around it.
> 
> What route do you think these should take upstream?  I'm happy to take
> them if Jeff is OK with that.

I've sent them through Jeff in the past, that's been convenient when
there's been churn in the network APIs. I'm not sure if there's much of
that for .26 though.

If Jeff prefers to ACK, I'll just add it to my git and ask you to pull
that. But I was originally planning to just feed it through him.

(Note: I'll repost the patch set later today or tomorrow with a couple
of tweaks).


-Olof

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

* Re: [patch 0/6] pasemi_mac updates for 2.6.26
  2008-02-26 14:16   ` Olof Johansson
@ 2008-02-26 18:21     ` Jeff Garzik
  2008-02-26 18:33       ` Olof Johansson
  0 siblings, 1 reply; 15+ messages in thread
From: Jeff Garzik @ 2008-02-26 18:21 UTC (permalink / raw)
  To: Olof Johansson; +Cc: netdev, pasemi-linux, Paul Mackerras, linuxppc-dev

Olof Johansson wrote:
> On Tue, Feb 26, 2008 at 08:49:58PM +1100, Paul Mackerras wrote:
>> Olof Johansson writes:
>>
>>> Here's a set of updates for pasemi_mac for 2.6.26. Some of them touch
>>> the dma_lib in the platform code as well, but it's easier if it's all
>>> merged through netdev to avoid dependencies.
>>>
>>> Major highlights are jumbo frame support and ethtool basics, the rest
>>> is mostly minor plumbing around it.
>> What route do you think these should take upstream?  I'm happy to take
>> them if Jeff is OK with that.
> 
> I've sent them through Jeff in the past, that's been convenient when
> there's been churn in the network APIs. I'm not sure if there's much of
> that for .26 though.
> 
> If Jeff prefers to ACK, I'll just add it to my git and ask you to pull
> that. But I was originally planning to just feed it through him.
> 
> (Note: I'll repost the patch set later today or tomorrow with a couple
> of tweaks).

Not much networking churn for 2.6.26, and IMO this patchset have 
above-average ppc changes/dependencies, so....   ACK

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

* Re: [patch 0/6] pasemi_mac updates for 2.6.26
  2008-02-26 18:21     ` Jeff Garzik
@ 2008-02-26 18:33       ` Olof Johansson
  0 siblings, 0 replies; 15+ messages in thread
From: Olof Johansson @ 2008-02-26 18:33 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, pasemi-linux, Paul Mackerras, linuxppc-dev

On Tue, Feb 26, 2008 at 01:21:00PM -0500, Jeff Garzik wrote:
> Olof Johansson wrote:
> > On Tue, Feb 26, 2008 at 08:49:58PM +1100, Paul Mackerras wrote:

> >> What route do you think these should take upstream?  I'm happy to take
> >> them if Jeff is OK with that.
> > 
> > I've sent them through Jeff in the past, that's been convenient when
> > there's been churn in the network APIs. I'm not sure if there's much of
> > that for .26 though.
> > 
> > If Jeff prefers to ACK, I'll just add it to my git and ask you to pull
> > that. But I was originally planning to just feed it through him.
> > 
> > (Note: I'll repost the patch set later today or tomorrow with a couple
> > of tweaks).
> 
> Not much networking churn for 2.6.26, and IMO this patchset have 
> above-average ppc changes/dependencies, so....   ACK

Ok, thanks Jeff.

Paul: I'll commit to my tree and ask you to pull later.


-Olof

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

* Re: [Pasemi-linux] [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib
  2008-02-26 14:14     ` Olof Johansson
@ 2008-03-05 18:21       ` Olof Johansson
  2008-03-06  0:47         ` Michael Ellerman
  0 siblings, 1 reply; 15+ messages in thread
From: Olof Johansson @ 2008-03-05 18:21 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: netdev, pasemi-linux, jgarzik, linuxppc-dev

On Tue, Feb 26, 2008 at 08:14:20AM -0600, Olof Johansson wrote:
> Hi,
> 
> On Tue, Feb 26, 2008 at 10:46:06PM +1100, Michael Ellerman wrote:
> > On Wed, 2008-02-20 at 20:57 -0600, Olof Johansson wrote:
> > > +	i = 1000;
> > > +	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
> > > +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1))
> > > +		i--;
> > > +	if (i < 0)
> > > +		printk(KERN_INFO "Warning: Could not disable RX section\n");
> > > +
> > > +	i = 1000;
> > > +	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
> > > +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1))
> > > +		i--;
> > 
> > This kind of caught my eye, is it still going to work when the next core
> > is twice as fast?
> 
> Actually, I added the variable right before posting, I used to have an
> infinite loop there while testing the patch. I've never seen it do more
> than a few rounds, so I'm not that worried.
> 
> We already have a similar loop in the channel shutdown code, but it runs
> a bit longer. I might bring that over instead. Thanks for pointing it
> out.

FYI; I've commited in this change, rest of the patch is identical.

diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c
index c529d8d..48cb7c9 100644
--- a/arch/powerpc/platforms/pasemi/dma_lib.c
+++ b/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -17,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -410,6 +411,7 @@ int pasemi_dma_init(void)
 	struct resource res;
 	struct device_node *dn;
 	int i, intf, err = 0;
+	unsigned long timeout;
 	u32 tmp;
 
 	if (!machine_is(pasemi))
@@ -478,6 +480,34 @@ int pasemi_dma_init(void)
 	for (i = 0; i < MAX_RXCH; i++)
 		__set_bit(i, rxch_free);
 
+	timeout = jiffies + HZ;
+	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
+	while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) {
+		if (time_after(jiffies, timeout)) {
+			pr_warning("Warning: Could not disable RX section\n");
+			break;
+		}
+	}
+
+	timeout = jiffies + HZ;
+	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
+	while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) {
+		if (time_after(jiffies, timeout)) {
+			pr_warning("Warning: Could not disable TX section\n");
+			break;
+		}
+	}

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

* Re: [Pasemi-linux] [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib
  2008-03-05 18:21       ` [Pasemi-linux] " Olof Johansson
@ 2008-03-06  0:47         ` Michael Ellerman
  0 siblings, 0 replies; 15+ messages in thread
From: Michael Ellerman @ 2008-03-06  0:47 UTC (permalink / raw)
  To: Olof Johansson; +Cc: netdev, pasemi-linux, jgarzik, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 2586 bytes --]

On Wed, 2008-03-05 at 12:21 -0600, Olof Johansson wrote:
> On Tue, Feb 26, 2008 at 08:14:20AM -0600, Olof Johansson wrote:
> > Hi,
> > 
> > On Tue, Feb 26, 2008 at 10:46:06PM +1100, Michael Ellerman wrote:
> > > On Wed, 2008-02-20 at 20:57 -0600, Olof Johansson wrote:
> > > > +	i = 1000;
> > > > +	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
> > > > +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1))
> > > > +		i--;
> > > > +	if (i < 0)
> > > > +		printk(KERN_INFO "Warning: Could not disable RX section\n");
> > > > +
> > > > +	i = 1000;
> > > > +	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
> > > > +	while ((i > 0) && (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1))
> > > > +		i--;
> > > 
> > > This kind of caught my eye, is it still going to work when the next core
> > > is twice as fast?
> 
> FYI; I've commited in this change, rest of the patch is identical.
> 
> diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c
> index c529d8d..48cb7c9 100644
> --- a/arch/powerpc/platforms/pasemi/dma_lib.c
> +++ b/arch/powerpc/platforms/pasemi/dma_lib.c
> @@ -17,6 +17,7 @@
>   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
>   */
>  
> +#include <linux/kernel.h>
>  #include <linux/init.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> @@ -410,6 +411,7 @@ int pasemi_dma_init(void)
>  	struct resource res;
>  	struct device_node *dn;
>  	int i, intf, err = 0;
> +	unsigned long timeout;
>  	u32 tmp;
>  
>  	if (!machine_is(pasemi))
> @@ -478,6 +480,34 @@ int pasemi_dma_init(void)
>  	for (i = 0; i < MAX_RXCH; i++)
>  		__set_bit(i, rxch_free);
>  
> +	timeout = jiffies + HZ;
> +	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
> +	while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) {
> +		if (time_after(jiffies, timeout)) {
> +			pr_warning("Warning: Could not disable RX section\n");
> +			break;
> +		}
> +	}
> +
> +	timeout = jiffies + HZ;
> +	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
> +	while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) {
> +		if (time_after(jiffies, timeout)) {
> +			pr_warning("Warning: Could not disable TX section\n");
> +			break;
> +		}
> +	}

I like that a lot better :)

Ooo, someone beat me to adding pr_warning() - nice.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

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

end of thread, other threads:[~2008-03-06  0:47 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-21  2:57 [patch 0/6] pasemi_mac updates for 2.6.26 Olof Johansson
2008-02-21  2:57 ` [patch 1/6] pasemi_mac: Move RX/TX section enablement to dma_lib Olof Johansson
2008-02-26 11:46   ` Michael Ellerman
2008-02-26 14:14     ` Olof Johansson
2008-03-05 18:21       ` [Pasemi-linux] " Olof Johansson
2008-03-06  0:47         ` Michael Ellerman
2008-02-21  2:57 ` [patch 2/6] [POWERPC] pasemi: Add flag management functions " Olof Johansson
2008-02-21  2:57 ` [patch 3/6] [POWERPC] pasemi: Add function engine " Olof Johansson
2008-02-21  2:57 ` [patch 4/6] pasemi_mac: jumbo frame support Olof Johansson
2008-02-21  2:57 ` [patch 5/6] pasemi_mac: Enable GSO by default Olof Johansson
2008-02-21  2:57 ` [patch 6/6] pasemi_mac: basic ethtool support Olof Johansson
2008-02-26  9:49 ` [patch 0/6] pasemi_mac updates for 2.6.26 Paul Mackerras
2008-02-26 14:16   ` Olof Johansson
2008-02-26 18:21     ` Jeff Garzik
2008-02-26 18:33       ` Olof Johansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).